From e63b2004eec685f17b514f200a54d19602aac0f1 Mon Sep 17 00:00:00 2001 From: kyle-ssg Date: Tue, 22 Jul 2025 11:34:07 +0100 Subject: [PATCH 01/10] Remove heap and mixpanel --- api/app/settings/common.py | 1 - api/app/views.py | 1 - .../deployment/hosting/locally-frontend.md | 1 - frontend/.eslintrc.js | 1 - frontend/api/index.js | 2 - .../components/pages/GettingStartedPage.tsx | 5 +- frontend/web/project/api.js | 163 +++--------------- frontend/web/project/libs.js | 25 --- 8 files changed, 22 insertions(+), 177 deletions(-) diff --git a/api/app/settings/common.py b/api/app/settings/common.py index 43f2ac5497b5..bdb696f1ffa3 100644 --- a/api/app/settings/common.py +++ b/api/app/settings/common.py @@ -1026,7 +1026,6 @@ GOOGLE_ANALYTICS_API_KEY = env("GOOGLE_ANALYTICS_API_KEY", default=None) HEADWAY_API_KEY = env("HEADWAY_API_KEY", default=None) CRISP_CHAT_API_KEY = env("CRISP_CHAT_API_KEY", default=None) -MIXPANEL_API_KEY = env("MIXPANEL_API_KEY", default=None) SENTRY_API_KEY = env("SENTRY_API_KEY", default=None) AMPLITUDE_API_KEY = env("AMPLITUDE_API_KEY", default=None) REO_API_KEY = env("REO_API_KEY", default=None) diff --git a/api/app/views.py b/api/app/views.py index 0d40372d8f96..ec4a7b33e1f1 100644 --- a/api/app/views.py +++ b/api/app/views.py @@ -46,7 +46,6 @@ def project_overrides(request: Request) -> HttpResponse: "hideInviteLinks": "DISABLE_INVITE_LINKS", "linkedinPartnerTracking": "LINKEDIN_PARTNER_TRACKING", "maintenance": "MAINTENANCE_MODE", - "mixpanel": "MIXPANEL_API_KEY", "preventEmailPassword": "PREVENT_EMAIL_PASSWORD", "preventSignup": "PREVENT_SIGNUP", "reo": "REO_API_KEY", diff --git a/docs/docs/deployment/hosting/locally-frontend.md b/docs/docs/deployment/hosting/locally-frontend.md index 0c9f4b061659..6edfb3896860 100644 --- a/docs/docs/deployment/hosting/locally-frontend.md +++ b/docs/docs/deployment/hosting/locally-frontend.md @@ -90,7 +90,6 @@ Current variables used between 'frontend/environment.js' and 'frontend/common/pr - `ENABLE_MAINTENANCE_MODE`: Puts the site into maintenance mode. Set it to any value to enable maintenance. - `AMPLITUDE_API_KEY`: The Amplitude key to use for behaviour tracking. - `REO_API_KEY`: The Reo key to use for behaviour tracking. -- `MIXPANEL_API_KEY`: Mixpanel analytics key to use for behaviour tracking. - `SENTRY_API_KEY`: Sentry key for error reporting. - `ALBACROSS_CLIENT_ID`: Albacross client ID key for behaviour tracking. - `BASE_URL`: Used for specifying a base url path that's ignored during routing if serving from a subdirectory. diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 00de9863478a..76ee117464ef 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -83,7 +83,6 @@ module.exports = { 'hljs': true, 'hot': true, 'isMobile': true, - 'mixpanel': true, 'moment': true, 'oneOfType': true, 'openConfirm': true, diff --git a/frontend/api/index.js b/frontend/api/index.js index 6302af8af8b6..a445eb15d661 100755 --- a/frontend/api/index.js +++ b/frontend/api/index.js @@ -63,11 +63,9 @@ app.get('/config/project-overrides', (req, res) => { value: envToBool('ONLY_SUPERUSERS_CAN_CREATE_ORGANISATIONS', false), }, { name: 'flagsmith', value: process.env.FLAGSMITH_ON_FLAGSMITH_API_KEY }, - { name: 'heap', value: process.env.HEAP_API_KEY }, { name: 'headway', value: process.env.HEADWAY_API_KEY }, { name: 'ga', value: process.env.GOOGLE_ANALYTICS_API_KEY }, { name: 'sha', value: sha }, - { name: 'mixpanel', value: process.env.MIXPANEL_API_KEY }, { name: 'crispChat', value: process.env.CRISP_WEBSITE_ID }, { name: 'fpr', value: process.env.FIRST_PROMOTER_ID }, { name: 'zendesk', value: process.env.ZENDESK_WIDGET_ID }, diff --git a/frontend/web/components/pages/GettingStartedPage.tsx b/frontend/web/components/pages/GettingStartedPage.tsx index a9489e441439..aa3308a97228 100644 --- a/frontend/web/components/pages/GettingStartedPage.tsx +++ b/frontend/web/components/pages/GettingStartedPage.tsx @@ -139,10 +139,7 @@ const GettingStartedPage: FC = () => { ) } - if ( - !hasSubmittedIntegrations && - Utils.getFlagsmithHasFeature('integration_onboarding') - ) { + if (true) { return ( setCompletedIntegrations(true)} /> ) diff --git a/frontend/web/project/api.js b/frontend/web/project/api.js index 11a1b308052d..84da83bbca42 100644 --- a/frontend/web/project/api.js +++ b/frontend/web/project/api.js @@ -4,10 +4,9 @@ import isFreeEmailDomain from 'common/utils/isFreeEmailDomain' const enableDynatrace = !!window.enableDynatrace && typeof dtrum !== 'undefined' import { loadReoScript } from 'reodotdev' - -import freeEmailDomains from 'free-email-domains' import { groupBy } from 'lodash' import getUserDisplayName from 'common/utils/getUserDisplayName' + global.API = { ajaxHandler(store, res) { switch (res.status) { @@ -62,42 +61,11 @@ global.API = { }, alias(id, user = {}) { if (Project.excludeAnalytics?.includes(id)) return - if (Project.mixpanel) { - mixpanel.alias(id) - } if (enableDynatrace && user?.id) { dtrum.identifyUser(`${user.id}`) } Utils.setupCrisp() - if (Project.heap) { - heap.identify(id) - const user = AccountStore.model - const orgs = - (user && - user.organisations && - _.map( - user.organisations, - (o) => `${o.name} #${o.id}(${o.role})[${o.num_seats}]`, - ).join(',')) || - '' - const plans = AccountStore.getPlans() - heap.addUserProperties({ - // use human-readable names - '$first_name': user.first_name, - - '$last_name': user.last_name, - 'USER_ID': id, - email: id, - 'isCompanyEmail': - !user.email.includes('@gmail') && - !user.email.includes('@yahoo') && - !user.email.includes('@hotmail') && - !user.email.includes('@icloud'), - orgs, - 'plan': plans && plans.join(','), - }) - } if (Project.reo) { const reoPromise = loadReoScript({ clientID: Project.reo }) reoPromise.then((Reo) => { @@ -128,8 +96,9 @@ global.API = { } if (Project.amplitude) { amplitude.setUserId(id) - const identify = new amplitude.Identify().set('email', id) - amplitude.identify(identify) + API.trackTraits({ + email: id, + }) if (typeof window.engagement !== 'undefined') { window.engagement.boot({ integrations: [ @@ -218,36 +187,6 @@ global.API = { identify(id, user = {}) { if (Project.excludeAnalytics?.includes(id)) return try { - const orgs = - (user && - user.organisations && - _.map( - user.organisations, - (o) => `${o.name} #${o.id}(${o.role})[${o.num_seats}]`, - ).join(',')) || - '' - if (Project.mixpanel) { - mixpanel.identify(id) - const plans = AccountStore.getPlans() - - mixpanel.people.set({ - '$email': id, - // use human-readable names - '$first_name': user.first_name, - - '$last_name': user.last_name, - // only reserved properties need the $ - 'USER_ID': id, - 'isCompanyEmail': - !user.email.includes('@gmail') && - !user.email.includes('@yahoo') && - !user.email.includes('@hotmail') && - !user.email.includes('@icloud'), - orgs, - 'plan': plans && plans.join(','), - }) - } - if (enableDynatrace && user?.id) { dtrum.identifyUser(`${user.id}`) } @@ -297,41 +236,16 @@ global.API = { ) const selectedRole = selectedOrg?.role //ADMIN | USER const selectedOrgName = selectedOrg?.name - if (Project.heap) { - const plans = AccountStore.getPlans() - heap.identify(id) - heap.addUserProperties({ - // use human-readable names - '$first_name': user.first_name, - '$last_name': user.last_name, - 'USER_ID': id, - email: id, - 'isCompanyEmail': - !user.email.includes('@gmail') && - !user.email.includes('@yahoo') && - !user.email.includes('@hotmail') && - !user.email.includes('@icloud'), - orgs, - 'plan': plans && plans.join(','), - }) - } - - if (Project.amplitude) { - amplitude.setUserId(id) - const identify = new amplitude.Identify() - .set('email', id) - .set('name', { 'first': user.first_name, 'last': user.last_name }) - .set('organisation', selectedOrgName) - .set('role', selectedRole) - .set('plan', selectedPlanName) - .set( - 'tasks', - (user.onboarding?.tasks || [])?.map((v) => v.name), - ) - .set('integrations', user.onboarding?.tools?.integrations || []) - amplitude.identify(identify) - } + API.trackTraits({ + email: id, + integrations: user.onboarding?.tools?.integrations || [], + name: { 'first': user.first_name, 'last': user.last_name }, + organisation: selectedOrgName, + plan: selectedPlanName, + role: selectedRole, + tasks: (user.onboarding?.tasks || [])?.map((v) => v.name), + }) API.flagsmithIdentify() } catch (e) { console.error('Error identifying', e) @@ -352,20 +266,7 @@ global.API = { tag, }) }, - register(email, firstName, lastName) { - if (Project.excludeAnalytics?.includes(email)) return - if (Project.mixpanel) { - mixpanel.register({ - 'Email': email, - 'First Name': firstName, - 'Last Name': lastName, - }) - } - }, reset() { - if (Project.mixpanel) { - mixpanel.reset() - } return flagsmith.logout() }, setCookie(key, v) { @@ -432,11 +333,6 @@ global.API = { }) } - if (Project.heap) { - heap.track(data.event, { - category: data.category, - }) - } if (Project.amplitude) { const eventData = { category: data.category, @@ -445,18 +341,6 @@ global.API = { amplitude.track(data.event, eventData) } - if (Project.mixpanel) { - if (!data) { - console.error('Passed null event data') - } - console.info('track', data) - if (!data || !data.category || !data.event) { - console.error('Invalid event provided', data) - } - mixpanel.track(data.event, { - category: data.category, - }) - } }, trackPage(title) { if (Project.ga) { @@ -467,19 +351,14 @@ global.API = { title, }) } - if (Project.heap) { - heap.track(`Page View - ${title}`, { - location: document.location.href, - page: document.location.pathname, - title, - }) - } - if (Project.mixpanel) { - mixpanel.track(`Page View - ${title}`, { - location: document.location.href, - page: document.location.pathname, - title, - }) + }, + trackTraits(traits) { + if (Project.amplitude && traits) { + const identifyObj = new amplitude.Identify() + for (const [key, value] of Object.entries(traits)) { + identifyObj.set(key, value) + } + amplitude.identify(identifyObj) } }, } diff --git a/frontend/web/project/libs.js b/frontend/web/project/libs.js index 484f42f530ed..2bfd98872258 100644 --- a/frontend/web/project/libs.js +++ b/frontend/web/project/libs.js @@ -56,10 +56,6 @@ window.RequiredElement = propTypes.node.isRequired; window.Link = require('react-router-dom').Link; window.NavLink = require('react-router-dom').NavLink; -if (Project.heap) { - window.heap = window.heap || [], heap.load = function (e, t) { window.heap.appid = e, window.heap.config = t = t || {}; const r = document.createElement('script'); r.type = 'text/javascript', r.async = !0, r.src = `https://cdn.heapanalytics.com/js/heap-${e}.js`; const a = document.getElementsByTagName('script')[0]; a.parentNode.insertBefore(r, a); for (let n = function (e) { return function () { heap.push([e].concat(Array.prototype.slice.call(arguments, 0))); }; }, p = ['addEventProperties', 'addUserProperties', 'clearEventProperties', 'identify', 'resetIdentity', 'removeEventProperty', 'setEventProperties', 'track', 'unsetEventProperty'], o = 0; o Date: Tue, 22 Jul 2025 11:35:58 +0100 Subject: [PATCH 02/10] Revert getting started page --- frontend/web/components/pages/GettingStartedPage.tsx | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/frontend/web/components/pages/GettingStartedPage.tsx b/frontend/web/components/pages/GettingStartedPage.tsx index aa3308a97228..a9489e441439 100644 --- a/frontend/web/components/pages/GettingStartedPage.tsx +++ b/frontend/web/components/pages/GettingStartedPage.tsx @@ -139,7 +139,10 @@ const GettingStartedPage: FC = () => { ) } - if (true) { + if ( + !hasSubmittedIntegrations && + Utils.getFlagsmithHasFeature('integration_onboarding') + ) { return ( setCompletedIntegrations(true)} /> ) From 55d6aaacbcb568fb017af6810341bb21b7283996 Mon Sep 17 00:00:00 2001 From: kyle-ssg Date: Tue, 22 Jul 2025 13:41:56 +0100 Subject: [PATCH 03/10] Remove zendesk and dynatrace --- frontend/.eslintrc.js | 1 - frontend/api/index.js | 71 ------------------------------------- frontend/web/main.js | 9 ----- frontend/webpack/plugins.js | 1 - 4 files changed, 82 deletions(-) diff --git a/frontend/.eslintrc.js b/frontend/.eslintrc.js index 76ee117464ef..efcd8d9262d3 100644 --- a/frontend/.eslintrc.js +++ b/frontend/.eslintrc.js @@ -29,7 +29,6 @@ module.exports = { 'CodeHelp': true, 'Column': true, 'Cookies': true, - 'DYNATRACE_URL': true, 'Dispatcher': true, 'E2E': true, 'ES6Component': true, diff --git a/frontend/api/index.js b/frontend/api/index.js index a445eb15d661..fe179c3fea9e 100755 --- a/frontend/api/index.js +++ b/frontend/api/index.js @@ -68,7 +68,6 @@ app.get('/config/project-overrides', (req, res) => { { name: 'sha', value: sha }, { name: 'crispChat', value: process.env.CRISP_WEBSITE_ID }, { name: 'fpr', value: process.env.FIRST_PROMOTER_ID }, - { name: 'zendesk', value: process.env.ZENDESK_WIDGET_ID }, { name: 'sentry', value: process.env.SENTRY_API_KEY }, { name: 'api', @@ -120,76 +119,6 @@ app.get('/config/project-overrides', (req, res) => { ] let output = values.map(getVariable).join('') let dynatrace = '' - if (process.env.DYNATRACE_URL) { - dynatrace = ` -window.enableDynatrace = true; -(function(){function va(){document.cookie="".concat("__dTCookie","=").concat("1",";SameSite=Lax");var ua=-1!==document.cookie.indexOf("__dTCookie");document.cookie="".concat("__dTCookie","=").concat("1","; expires=Thu, 01-Jan-1970 00:00:01 GMT");return ua}function Sa(){return void 0===eb.dialogArguments?navigator.cookieEnabled||va():va()}function fb(){var ua;if(Sa()&&!window.dT_){var kb=(ua={},ua.cfg="app=8e35f25923c61ac7|cors=1|featureHash=A2NVfqru|vcv=2|reportUrl=${process.env.DYNATRACE_URL}/bf|rdnt=1|uxrgce=1|bp=3|cuc=2zmvahr4|mel=100000|dpvc=1|ssv=4|lastModification=1688993944019|tp=500,50,0,1|featureHash=A2NVfqru|agentUri=https://js-cdn.dynatrace.com/jstag/17b5f18726d/ruxitagent_A2NVfqru_10269230615181503.js|auto=|domain=|rid=RID_|rpid=|app=8e35f25923c61ac7",ua.iCE= - Sa,ua);window.dT_=kb}}this.dT_&&dT_.prm&&dT_.prm();var eb="undefined"!==typeof window?window:self,La;eb.dT_?(null===(La=eb.console)||void 0===La?void 0:La.log("Duplicate agent injection detected, turning off redundant initConfig."),eb.dT_.di=1):fb()})(); - (function(){function va(f,n,G){if(G||2===arguments.length)for(var F=0,Z=n.length,Da;Ff)return"";for(;0<=f;){if(0===f||" "===n.charAt(f- - 1)||";"===n.charAt(f-1))return G=f+G.length,f=Sa(n,";",f),0<=f?n.substring(G,f):n.substring(G);f=Sa(n,G,f+G.length)}return""}function La(f){return eb(f,document.cookie)}function ua(){}function kb(){var f=0;try{f=Math.round(Wa.performance.timeOrigin)}catch(n){}if(0>=f||isNaN(f)||!isFinite(f)){Ha(Qd,{severity:"Warning",type:"ptoi",text:"performance.timeOrigin is invalid, with a value of [".concat(f,"]. Falling back to performance.timing.navigationStart")});f=0;try{f=Wa.performance.timing.navigationStart}catch(n){}f= - 0>=f||isNaN(f)||!isFinite(f)?Jd:f}ag=f;Bd=na;return ag}function na(){return ag}function Ta(){return Bd()}function Oa(){var f,n=0;if(null===(f=null===Wa||void 0===Wa?void 0:Wa.performance)||void 0===f?0:f.now)try{n=Math.round(Wa.performance.now())}catch(G){}return 0>=n||isNaN(n)||!isFinite(n)?(new Date).getTime()-Bd():n}function Za(f,n){void 0===n&&(n=document.cookie);return eb(f,n)}function Aa(){}function ja(f,n){return function(){f.apply(n,arguments)}}function ta(f){if(!(this instanceof ta))throw new TypeError("Promises must be constructed via new"); - if("function"!==typeof f)throw new TypeError("not a function");this.ka=0;this.ic=!1;this.qa=void 0;this.Fa=[];ra(f,this)}function Ia(f,n){for(;3===f.ka;)f=f.qa;0===f.ka?f.Fa.push(n):(f.ic=!0,ta.Fb(function(){var G=1===f.ka?n.Be:n.Ce;if(null===G)(1===f.ka?Ma:Ba)(n.promise,f.qa);else{try{var F=G(f.qa)}catch(Z){Ba(n.promise,Z);return}Ma(n.promise,F)}}))}function Ma(f,n){try{if(n===f)throw new TypeError("A promise cannot be resolved with itself.");if(n&&("object"===typeof n||"function"===typeof n)){var G= - n.then;if(n instanceof ta){f.ka=3;f.qa=n;N(f);return}if("function"===typeof G){ra(ja(G,n),f);return}}f.ka=1;f.qa=n;N(f)}catch(F){Ba(f,F)}}function Ba(f,n){f.ka=2;f.qa=n;N(f)}function N(f){2===f.ka&&0===f.Fa.length&&ta.Fb(function(){f.ic||ta.qc(f.qa)});for(var n=0,G=f.Fa.length;n"),f=f.split("^lb").join("<"),f=f.split("^p").join("|"),f=f.split("^e").join("="),f=f.split("^s").join(";"),f=f.split("^c").join(","),f=f.split("^bs").join("\\\\"));return f}function P(f,n){if(!f||!f.length)return-1;if(f.indexOf)return f.indexOf(n);for(var G=f.length;G--;)if(f[G]===n)return G;return-1}function Va(f,n){var G;void 0===n&&(n=[]);if(!f||"object"!==typeof f&& - "function"!==typeof f)return!1;var F="number"!==typeof n?n:[],Z=null,Da=[];switch("number"===typeof n?n:5){case 1:Z="Boolean";break;case 2:Z="Number";break;case 3:Z="String";break;case 4:Z="Function";break;case 5:Z="Object";break;case 6:Z="Date";Da.push("getTime");break;case 7:Z="Error";Da.push("name","message");break;case 8:Z="Element";break;case 9:Z="HTMLElement";break;case 10:Z="HTMLImageElement";Da.push("complete");break;case 11:Z="PerformanceEntry";break;case 12:Z="PerformanceTiming";break;case 13:Z= - "PerformanceResourceTiming";break;case 14:Z="PerformanceNavigationTiming";break;case 15:Z="CSSRule";Da.push("cssText","parentStyleSheet");break;case 16:Z="CSSStyleSheet";Da.push("cssRules","insertRule");break;case 17:Z="Request";Da.push("url");break;case 18:Z="Response";Da.push("ok","status","statusText");break;case 19:Z="Set";Da.push("add","entries","forEach");break;case 20:Z="Map";Da.push("set","entries","forEach");break;case 21:Z="Worker";Da.push("addEventListener","postMessage","terminate");break; - case 22:Z="XMLHttpRequest";Da.push("open","send","setRequestHeader");break;case 23:Z="SVGScriptElement";Da.push("ownerSVGElement","type");break;case 24:Z="HTMLMetaElement";Da.push("httpEquiv","content","name");break;case 25:Z="HTMLHeadElement";break;case 26:Z="ArrayBuffer";break;case 27:Z="ShadowRoot",Da.push("host","mode")}n=Z;if(!n)return!1;Da=Da.length?Da:F;if(!F.length)try{if(Wa[n]&&f instanceof Wa[n]||Object.prototype.toString.call(f)==="[object "+n+"]")return!0;if(f&&f.nodeType&&1===f.nodeType){var Gb= - null===(G=f.ownerDocument.defaultView)||void 0===G?void 0:G[n];if("function"===typeof Gb&&f instanceof Gb)return!0}}catch(Qb){}for(G=0;GZ)}function Vb(){if(Wa.MobileAgent||Wa.dynatraceMobile){var f=La("dtAdkSettings");return Lb(f).privacyState||null}return null}function jb(f,n){return!Ob()||Wa.dT_.overloadPrevention&&!K()?null:f.apply(this,n||[])}function Ob(){var f=Vb();return 2===f||1===f?!1:!W("coo")||W("cooO")||K()}function Ab(f,n){try{Wa.sessionStorage.setItem(f,n)}catch(G){}}function xb(f,n){jb(Ab,[f,n])}function lc(f){try{return Wa.sessionStorage.getItem(f)}catch(n){}return null}function Tb(f){try{Wa.sessionStorage.removeItem(f)}catch(n){}} - function vb(f){document.cookie=f+'="";path=/'+(Ga("domain")?";domain="+Ga("domain"):"")+"; expires=Thu, 01 Jan 1970 00:00:01 GMT;"}function Ec(f,n,G,F){n||0===n?(n=(n+"").replace(/[;\\n\\r]/g,"_"),f=f+"="+n+";path=/"+(Ga("domain")?";domain="+Ga("domain"):""),G&&(f+=";expires="+G.toUTCString()),f+=Jb(Ga("cssm")),F&&"https:"===location.protocol&&(f+=";Secure"),document.cookie=f):vb(f)}function cc(f,n,G,F){jb(Ec,[f,n,G,F])}function mc(f){return-1===Sa(f,"v_4")?!1:!0}function sb(f){f=Za("dtCookie",f);f|| - ((f=lc("dtCookie"))&&mc(f)?C(f):f="");return mc(f)?f:""}function C(f){cc("dtCookie",f,void 0,W("ssc"))}function r(f){return(f=f||sb())?Lb(f):{sessionId:"",serverId:"",overloadState:0,appState:{}}}function z(f){return r(f).serverId}function D(f){return r(f).sessionId}function K(){return 0<=Sa(navigator.userAgent,"RuxitSynthetic")}function E(f){var n={},G=0;for(f=f.split("|");GSa(Db[f],"#"+f.toUpperCase())?Db[f]:""}function yc(f){var n=f.agentUri;n&&-1=Da)F="";else{for(var Gb=Z[0],Qb="",hc=1;hc<=Da;hc++)if(Za("dTValidationCookie")){Qb=Gb;break}else{Z[hc]&&(Gb="".concat(Z[hc],".").concat(Gb));var xc="".concat("dTValidationCookie","=dTValidationCookieValue;path=/;domain=").concat(Gb);xc+=Jb(F);document.cookie=xc}cb("dTValidationCookie",Qb,"/");F= - Qb}}else F="";F&&(f.domain=F);G||Ha(Qd,{type:"dpi",severity:"Warning",text:'Configured domain "'.concat(n,'" is invalid for current location "').concat(location.hostname,'". Agent will use "').concat(f.domain,'" instead.')})}}function zc(f,n){tc(f);var G=Db.pVO;G&&(f.pVO=G);n||(f.bp=(f.bp||Xc.bp)+"")}function ud(){return Db}function md(f){return Xc[f]===ma(f)}function Lb(f){var n,G={},F={sessionId:"",serverId:"",overloadState:0,appState:G},Z=f.split("_");if(2f)return F;f={};for(var Da=2;Da=Z.length?Z:""):Z="hybrid";F.sessionId=Z;if(f.srv){a:{Z=f.srv.replace("-2D","-");if(!isNaN(+Z)&&(Da=ab(Z),-99<=Da&&99>=Da))break a;Z=""}F.serverId=Z}Z=+f.ol;1===Z&&Rb(K());0<=Z&&2>=Z&&(F.overloadState=Z);f=+f.prv;isNaN(f)||(F.privacyState=1>f||4=Kc()||!isFinite(Kc()))Kc=function(){return(new Date).getTime()}}function Ka(){De&&(Wa.clearTimeout=Cd,Wa.clearInterval=vd,De=!1)}function ib(f,n){try{Wa.localStorage.setItem(f,n)}catch(G){}}function $a(f){try{Wa.localStorage.removeItem(f)}catch(n){}}function nb(f){try{return Wa.localStorage.getItem(f)}catch(n){}return null}function pc(){$a("rxvisitid");$a("rxvt")}function Wb(f){Ob()?f():(Ee||(Ee=[]),Ha(Ee,f))}function Nb(f){return jb(f)} - function dc(){if(W("coo")&&!Ob()){for(var f=0,n=Ee;fGb&&1=F?48:55)))}return f.join("")}function bd(){return Fe}function gd(f){void 0===f&&(f=!0);Qe=f}function Cc(f,n,G){var F=oa("pcl");F=f.length-F;0xc);Qb&&(Da={frameId:F,D:"-"=== - hc?"-":ab(hc),visitId:""});F=Gb;(hc=Da)&&n.push(hc)}for(f=0;fdocument.documentMode)){var G=0>(null===(f=navigator.userAgent)||void 0===f?void 0:f.indexOf("RuxitSynthetic"));if(!Wa.dT_||!Wa.dT_.cfg||"string"!==typeof Wa.dT_.cfg||"initialized"in Wa.dT_&&Wa.dT_.initialized)null===(n=Wa.console)||void 0===n?void 0:n.log("InitConfig not found or agent already initialized! This is an injection issue."), - Wa.dT_&&(Wa.dT_.di=3);else if(G)try{Pf();var F;Xc=(F={},F.ade="",F.aew=!0,F.apn="",F.agentLocation="",F.agentUri="",F.app="",F.async=!1,F.ase=!1,F.auto=!1,F.bp=3,F.bisaoi=!1,F.bisCmE="",F.bs=!1,F.buildNumber=0,F.csprv=!0,F.cepl=16E3,F.cls=!0,F.ccNcss=!1,F.coo=!1,F.cooO=!1,F.cssm="0",F.cwt="",F.cwtUrl="27pd8x1igg",F.cors=!1,F.csu="",F.cuc="",F.cce=!1,F.cux=!1,F.dataDtConfig="",F.debugName="",F.dvl=500,F.dASXH=!1,F.disableCookieManager=!1,F.dKAH=!1,F.disableLogging=!1,F.dmo=!1,F.doel=!1,F.dpch=!1,F.dpvc= - !1,F.disableXhrFailures=!1,F.domain="",F.domainOverride="",F.domainOriginal="",F.doNotDetect="",F.ds=!0,F.dsndb=!1,F.dsa=!1,F.dsss=!1,F.dssv=!0,F.earxa=!0,F.exp=!1,F.eni=!0,F.expw=!1,F.instr="",F.evl="",F.fa=!1,F.fvdi=!1,F.featureHash="",F.hvt=216E5,F.imm=!1,F.ign="",F.iub="",F.iqvn=!1,F.initializedModules="",F.lastModification=0,F.lupr=!0,F.lab=!1,F.legacy=!1,F.lt=!0,F.mb="",F.md="",F.mdp="",F.mdl="",F.mcepsl=100,F.mdn=5E3,F.mhl=4E3,F.mpl=1024,F.mmds=2E4,F.msl=3E4,F.bismepl=2E3,F.mel=200,F.mepp= - 10,F.moa=30,F.mrt=3,F.ntd=!1,F.nsfnv=!1,F.ncw=!1,F.oat=180,F.ote=!1,F.owasp=!1,F.pcl=20,F.pt=!0,F.perfbv=1,F.prfSmpl=0,F.pVO=!1,F.peti=!1,F.raxeh=!0,F.rdnt=0,F.nosr=!0,F.reportUrl="dynaTraceMonitor",F.rid="",F.ridPath="",F.rpid="",F.rcdec=12096E5,F.rtl=0,F.rtp=2,F.rtt=1E3,F.rtu=200,F.rvcl=24,F.sl=100,F.ssc=!1,F.svNB=!1,F.srad=!0,F.srbbv=1,F.srbw=!0,F.srdinitrec=!0,F.srmr=100,F.srms="1,1,,,",F.srsr=1E5,F.srtbv=3,F.srtd=1,F.srtr=500,F.srvr="",F.srvi=0,F.srwo=!1,F.srre="",F.srxcss=!0,F.srxicss=!0,F.srif= - !1,F.srmrc=!1,F.srsdom=!0,F.srcss=!0,F.srmcrl=1,F.srmcrv=10,F.st=3E3,F.spc="",F.syntheticConfig=!1,F.tal=0,F.tt=100,F.tvc=3E3,F.uxdce=!1,F.uxdcw=1500,F.uxrgce=!0,F.uxrgcm="100,25,300,3;100,25,300,3",F.uam=!1,F.uana="data-dtname,data-dtName",F.uanpi=0,F.pui=!1,F.usrvd=!0,F.vrt=!1,F.vcfi=!0,F.vcsb=!1,F.vcit=1E3,F.vct=50,F.vcx=50,F.vscl=0,F.vncm=1,F.xb="",F.chw="",F.xt=0,F.xhb="",F);var Z;bb();var Da;Ac=Wa.XMLHttpRequest;var Gb=null===(Da=Wa.XMLHttpRequest)||void 0===Da?void 0:Da.prototype;if(Gb)for(Hc= - {},f=0,n=Qc;fbh?Ud.substring(bh):"Default%20Application"}else if(Ud){var sg=se.exec(Ud);sg&&(Ld.app=sg[1])}gf=Bf}else gf=ke}if(gf)for(var Rf in gf)Object.prototype.hasOwnProperty.call(gf,Rf)&&(ee=Rf,Db[ee]=gf[ee]);var Sf=ba();try{var fe=(gf=de)&&gf.getItem(Sf);if(fe){var Tf=E(fe),Te=R(Tf.config||""),qh=Db.lastModification||"0",Nh=ab((Te.lastModification||Tf.lastModification||"0").substring(0,13)),Ni="string"=== - typeof qh?ab(qh.substring(0,13)):qh;if(!qh||Nh>=Ni)if(Te.csu=Tf.name||Ga("csu"),Te.featureHash=Tf.featureHash||Ga("featureHash"),Te.agentUri&&yc(Te),zc(Te,!0),wb(Te),zb(Te),Nh>(+Db.lastModification||0)){var rh=W("auto"),hd=W("legacy");Db=Eb(Te);Db.auto=rh?"1":"0";Db.legacy=hd?"1":"0"}}}catch(Mh){}zc(Db);try{var tg=Db.ign;if(tg&&(new RegExp(tg)).test(Wa.location.href)){document.dT_=Wa.dT_=void 0;var He=!1;break a}}catch(Mh){}if(K()){var Df=navigator.userAgent,Ue=Df.lastIndexOf("RuxitSynthetic");if(-1=== - Ue)var fg={};else{var Ve=Df.substring(Ue+14);if(-1===Sa(Ve," c"))fg={};else{Sf={};fe=0;for(var te=Ve.split(" ");feje.indexOf("dbg")&&(je=Ga("debugName")||je+"dbg");if(!W("auto")&&!W("legacy")&& - !Lg){var Ef=Ga("agentUri")||ad(Ga("featureHash"));if(W("async")||"complete"===document.readyState)Zc(Ef,W("async"),void 0,void 0,"dtjsagent");else{var Oi="".concat("dtjsagent","dw");document.write('