UNPKG

@usercentrics/cmp-web-sdk

Version:

Please visit our official [https://usercentrics.com/docs/web/implementation/sdk/][docs] (alpha version, not to be used in production).

1,247 lines (1,144 loc) 233 kB
import {UCConsole as $jDAan$UCConsole, convertCookieMaxAge as $jDAan$convertCookieMaxAge, convertDomain as $jDAan$convertDomain, mergeDeep as $jDAan$mergeDeep} from "@usercentrics/cmp-web-shared"; import {v4 as $jDAan$v4} from "uuid"; import $jDAan$cryptojssha256 from "crypto-js/sha256"; import {API_VERSION as $jDAan$API_VERSION, getCategoriesWithServicesConsent as $jDAan$getCategoriesWithServicesConsent, ucCmpTheme as $jDAan$ucCmpTheme, ucPrivacyButtonTheme as $jDAan$ucPrivacyButtonTheme, ucEmbeddingsTheme as $jDAan$ucEmbeddingsTheme, applyVendorRestrictions as $jDAan$applyVendorRestrictions, CONSENT_DATA_VERSION as $jDAan$CONSENT_DATA_VERSION} from "@usercentrics/cmp-web-api-cmp-server"; import {CmpApi as $jDAan$CmpApi, CmpApiModel as $jDAan$CmpApiModel} from "@iabtechlabtcf/cmpapi"; import {RestrictionType as $jDAan$RestrictionType, PurposeRestriction as $jDAan$PurposeRestriction, GVL as $jDAan$GVL, TCModel as $jDAan$TCModel, TCString as $jDAan$TCString, Segment as $jDAan$Segment} from "@iabtechlabtcf/core"; function $parcel$export(e, n, v, s) { Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true}); } function $parcel$exportWildcard(dest, source) { Object.keys(source).forEach(function(key) { if (key === 'default' || key === '__esModule' || Object.prototype.hasOwnProperty.call(dest, key)) { return; } Object.defineProperty(dest, key, { enumerable: true, get: function get() { return source[key]; } }); }); return dest; } var $parcel$global = globalThis; var $parcel$modules = {}; var $parcel$inits = {}; var parcelRequire = $parcel$global["parcelRequire94c2"]; if (parcelRequire == null) { parcelRequire = function(id) { if (id in $parcel$modules) { return $parcel$modules[id].exports; } if (id in $parcel$inits) { var init = $parcel$inits[id]; delete $parcel$inits[id]; var module = {id: id, exports: {}}; $parcel$modules[id] = module; init.call(module.exports, module, module.exports); return module.exports; } var err = new Error("Cannot find module '" + id + "'"); err.code = 'MODULE_NOT_FOUND'; throw err; }; parcelRequire.register = function register(id, init) { $parcel$inits[id] = init; }; $parcel$global["parcelRequire94c2"] = parcelRequire; } var parcelRegister = parcelRequire.register; parcelRegister("2SngV", function(module, exports) { module.exports = import("./GppService.db796dba.js").then(()=>parcelRequire('lzCWz')); }); parcelRegister("gQm4g", function(module, exports) { $parcel$export(module.exports, "UsCmpController", () => $758554fa4ca8b982$export$b8d5d7cd0ae3a47a); var $8qIH8 = parcelRequire("8qIH8"); var $loxzk = parcelRequire("loxzk"); var $ddbu5 = parcelRequire("ddbu5"); var $fTk4U = parcelRequire("fTk4U"); class $758554fa4ca8b982$export$b8d5d7cd0ae3a47a extends (0, $fTk4U.CmpController) { isOptedOut() { return this.consent.getHasOptedOut(); } constructor(ccpaCmpData, services, options){ if (!ccpaCmpData.consent.ccpaString && options?.consentData?.ccpaString) ccpaCmpData.consent.ccpaString = options.consentData.ccpaString; super(ccpaCmpData, services, options); this.consent = new (0, $loxzk.UsConsentModel)(ccpaCmpData.consent, { initialView: ccpaCmpData.ui.initialView, uiVersion: options?.uiVersion }); this.i18n = new (0, $ddbu5.UsI18nModel)(ccpaCmpData.i18n); window.__uspapi = (command, version, callback)=>{ switch(command){ case 'getUSPData': callback({ version: (0, $8qIH8.CCPA_VERSION), uspString: this.consent.getCcpaString() }, true); break; default: (0, $jDAan$UCConsole).warn('UsCmpController - constructor', '(__uspapi) Invalid command:', command); callback(null, false); break; } }; } } }); parcelRegister("8qIH8", function(module, exports) { $parcel$export(module.exports, "CCPA_VERSION", () => $3afdb0c87ffbd89f$export$68beac7206e2f1e7); const $3afdb0c87ffbd89f$export$68beac7206e2f1e7 = 1; const $3afdb0c87ffbd89f$export$2f1c055c758626f6 = '__uspapiLocator'; const $3afdb0c87ffbd89f$export$a123c78691e1ae11 = /^[1][nNyY-][nNyY-][nNyY-]$/; const $3afdb0c87ffbd89f$export$207ddf74c950b98d = '__uspapi'; var $3afdb0c87ffbd89f$export$cd9441e9c0d2a8d1 = /*#__PURE__*/ function(CCPA_STRING_CHARACTER) { CCPA_STRING_CHARACTER["ACCEPT"] = "Y"; CCPA_STRING_CHARACTER["DENY"] = "N"; CCPA_STRING_CHARACTER["UNKNOWN"] = "-"; return CCPA_STRING_CHARACTER; }({}); }); parcelRegister("loxzk", function(module, exports) { $parcel$export(module.exports, "UsConsentModel", () => $3d9681ddc5b118b1$export$3b6609671a9e0620); var $8qIH8 = parcelRequire("8qIH8"); var $3CyAA = parcelRequire("3CyAA"); class $3d9681ddc5b118b1$export$3b6609671a9e0620 extends (0, $3CyAA.GdprConsentModel) { constructor(usConsentData, options){ super(usConsentData, { uiVersion: options?.uiVersion }); const { ccpaString: ccpaString } = usConsentData; this.legislation = usConsentData.legislation; this.ccpaString = ccpaString; this.gpcSignal = usConsentData.gpcSignal; this._hasBeenNotified = options?.initialView === 'first' || options?.initialView === 'second' ? 'Y' : ccpaString.charAt(1); this._hasOptedOut = ccpaString.charAt(2); this._iabAgreementExists = ccpaString.charAt(3); } /** * Get US string * @returns {string} - The US consent string. */ getCcpaString() { return this.ccpaString; } emitCcpaString() { this.ccpaString = `${0, $8qIH8.CCPA_VERSION}${this._hasBeenNotified}${this._hasOptedOut}${this._iabAgreementExists}`; } setHasOptedOut(hasOptedOut) { this._hasOptedOut = hasOptedOut ? 'Y' : 'N'; this.setUpdatedBy(hasOptedOut ? 'onDenyAllServices' : 'onAcceptAllServices'); } getHasOptedOut() { return this._hasOptedOut === 'Y'; } /** * Set that the user has been notified about the opportunity to opt out * @returns {void} */ setHasBeenNotified() { this._hasBeenNotified = 'Y'; } } }); parcelRegister("3CyAA", function(module, exports) { $parcel$export(module.exports, "GdprConsentModel", () => $37757c32508376ef$export$743198fc6aa02c43); var $evKBX = parcelRequire("evKBX"); class $37757c32508376ef$export$743198fc6aa02c43 extends (0, $evKBX.ConsentModel) { constructor(gdprConsentData, options){ super(gdprConsentData, options); this.serviceIds = gdprConsentData.serviceIds; } /** * Set list of services ids * @param {string[]} ids - Services ids list. * @returns {void} */ setServiceIds(ids) { this.serviceIds = ids; } } }); parcelRegister("evKBX", function(module, exports) { $parcel$export(module.exports, "ConsentModel", () => $af3bb98f3cc73716$export$6220cc9b14234074); var $27GXH = parcelRequire("27GXH"); class $af3bb98f3cc73716$export$6220cc9b14234074 { constructor({ language: language, setting: setting, updatedAt: updatedAt, updatedBy: updatedBy, createdAt: createdAt, controllerId: controllerId, version: version, uiVersion: uiVersion, required: required, status: status, type: type, hash: hash, isBot: isBot, _domains: _domains }, options){ const now = Date.now(); this.version = version; this.uiVersion = uiVersion || options?.uiVersion; this._latestUiVersion = options?.uiVersion; this.controllerId = controllerId || (0, $27GXH.sha256)((0, $jDAan$v4)()).toString(); this.language = language; this.setting = setting; this.updatedAt = updatedAt || now; this.updatedBy = updatedBy || 'onInitialPageLoad'; this.createdAt = createdAt || now; this.required = required; this.status = status; this.type = type; this.hash = hash; this.isBot = isBot; this._domains = _domains; } /** * Set setting's data * @param {SettingData} setting - New setting's data. * @returns {void} */ setSetting(setting) { this.setting = setting; } getDomains() { return this._domains || []; } /** * Set language * @param {string} language - New language. * @returns {void} */ setLanguage(language) { this.language = language; } setUiVersion(uiVersion) { this.uiVersion = uiVersion || this._latestUiVersion; } /** * Set updatedAt * @param {number} number - New timestamp. * @returns {void} */ setUpdatedAt(updatedAt) { this.updatedAt = updatedAt; } /** * Set updatedBy * @param {ConsentActionType} updatedBy - New consent action. * @returns {void} */ setUpdatedBy(updatedBy) { this.updatedBy = updatedBy; } /** * Set hash * @param {string} hash - New hash string. * @returns {void} */ setHash(hash) { this.hash = hash; } /** * Set required * @param {boolean} isRequired - Is consent required. * @returns {void} */ setRequired(isRequired) { this.required = isRequired; } /** * Set status * @param {string} status - New consent status. * @returns {void} */ setStatus(status) { this.status = status; } /** * Set type * @param {ConsentType} type - New consent type. * @returns {void} */ setType(type) { this.type = type; } } }); parcelRegister("27GXH", function(module, exports) { $parcel$export(module.exports, "sha256", () => $5dc41e93bd754c39$export$bced8d2aada2d1c9); const $5dc41e93bd754c39$export$bced8d2aada2d1c9 = (v)=>{ return (0, $jDAan$cryptojssha256)(v).toString(); }; }); parcelRegister("ddbu5", function(module, exports) { $parcel$export(module.exports, "UsI18nModel", () => $a66ccd87e9eeae00$export$b0ba528e2cd8bbc1); $parcel$export(module.exports, "isCcpaI18nData", () => $a66ccd87e9eeae00$export$1fc5dcfc5efc8505); var $3JnnS = parcelRequire("3JnnS"); class $a66ccd87e9eeae00$export$b0ba528e2cd8bbc1 extends (0, $3JnnS.I18nModel) { constructor(ccpaI18nData){ super(ccpaI18nData); this.ccpa = ccpaI18nData.ccpa; } } const $a66ccd87e9eeae00$export$1fc5dcfc5efc8505 = (data)=>{ return 'ccpa' in data; }; }); parcelRegister("3JnnS", function(module, exports) { $parcel$export(module.exports, "I18nModel", () => $d032784b0e48b4ad$export$a8593aa1fad6625d); class $d032784b0e48b4ad$export$a8593aa1fad6625d { constructor({ base: base, firstLayer: firstLayer, secondLayer: secondLayer, services: services, categories: categories }){ this.base = base; this.categories = categories; this.services = services; this.firstLayer = firstLayer; this.secondLayer = secondLayer; } /** * Get i18n service data by id * @param {string} serviceId - Service id. * @returns {ServiceI18n} - The i18n service data */ getService(serviceId) { return this.services[serviceId]; } /** * Determines wether or not a service already has details available * @param {string} serviceId - Service id. * @returns {boolean} - True if service details are available. */ getServiceHasDetails(serviceId) { const service = this.getService(serviceId); return service && typeof service.details !== 'undefined'; } } }); parcelRegister("fTk4U", function(module, exports) { $parcel$export(module.exports, "CmpController", () => $d41e196d399204b8$export$937cbbe093a3d900); parcelRequire("evIjB"); var $22ugm = parcelRequire("22ugm"); var $6KjkM = parcelRequire("6KjkM"); var $1uDf8 = parcelRequire("1uDf8"); parcelRequire("9ICfj"); var $bllKQ = parcelRequire("bllKQ"); var $gTa9l = parcelRequire("gTa9l"); var $f7OmZ = parcelRequire("f7OmZ"); var $gAUrd = parcelRequire("gAUrd"); var $4PEVa = parcelRequire("4PEVa"); var $g7fcG = parcelRequire("g7fcG"); var $dxyXd = parcelRequire("dxyXd"); var $czsx7 = parcelRequire("czsx7"); var $ddbu5 = parcelRequire("ddbu5"); var $j9WI1 = parcelRequire("j9WI1"); var $evYVd = parcelRequire("evYVd"); var $gKkFX = parcelRequire("gKkFX"); var $8zGgn = parcelRequire("8zGgn"); var $9AFzU = parcelRequire("9AFzU"); var $2hccy = parcelRequire("2hccy"); var $iXjyA = parcelRequire("iXjyA"); var $27GXH = parcelRequire("27GXH"); class $d41e196d399204b8$export$937cbbe093a3d900 { constructor(cmpData, { apiService: apiService, consentService: consentService, localStorageService: localStorageService, analyticsService: analyticsService, crossDeviceService: crossDeviceService, gppService: gppService }, options){ const combinedCmpData = (0, $iXjyA.getCombinedCmpData)(cmpData, options); (0, $2hccy.webSdkEvents).emit('CMP_DATA_COMBINED', combinedCmpData); const { dps: dps, gcm: gcm, uet: uet, core: core, integrations: integrations, setting: setting, ui: ui, languages: languages, theme: theme, template: template } = combinedCmpData; this.coreData = options?.settingsCoreData; this.apiService = apiService; this.analyticsService = analyticsService; this.consentService = consentService; this.crossDeviceService = crossDeviceService; this.customEventService = new (0, $22ugm.default)(core.customEvents || []); this.gppService = gppService; this.localStorageService = localStorageService; this.scriptService = new (0, $1uDf8.default)(); if (core.dataLayers) this.dataLayerService = new (0, $6KjkM.default)(core.dataLayers); this.ui = new (0, $g7fcG.UiModel)(ui); this.languages = new (0, $gTa9l.LanguagesModel)(languages); this.setting = new (0, $f7OmZ.SettingModel)(setting); this.dps = new (0, $bllKQ.DpsModel)(dps); this.theme = new (0, $4PEVa.ThemeModel)(theme || {}); if (template) this.template = new (0, $gAUrd.TemplateModel)(template); if (integrations) this.integrations = new (0, $gKkFX.IntegrationsModel)(integrations); if (gcm) this.gcm = new (0, $evYVd.GoogleConsentModeModel)(gcm, localStorageService, this.customEventService); if (uet) this.uet = new (0, $8zGgn.UetModel)(this.customEventService); } /** * Get the consent details * @returns {Promise<ConsentDetails | undefined>} - The consent data used inside our UCstring. */ async getConsentDetails() { if (!this.consent) return; // In order to avoid overwriting previous consent details saved on the DataLayer // we need to destruct the object to make a copy by value const consentDetails = { consent: { ...this.consent }, services: { ...this.dps.services }, categories: { ...this.dps.categories } }; return consentDetails; } /** * Fetch the translated data from the API and created the respective variant i18n models * @returns {Promise<void>} */ async initI18nData() { const i18nData = await this.apiService.fetchI18nData({ settingsId: this.setting.id, settingsType: this.setting.type, settingsVersion: this.setting.version, language: this.ui.language, activeTcfVendorsListVersion: this.coreData?.tcf?.vendorsListVersion, previousTcfVendorsListVersion: this.consent && this.consent?.vendorsList?.version || this.coreData?.tcf?.vendorsListVersion, previousTcfPolicyVersion: this.consent && this.consent?.vendorsList?.policyVersion || this.coreData?.tcf?.policyVersion }); if (!i18nData) return; if ((0, $dxyXd.isGdprI18nData)(i18nData)) this.i18n = new (0, $dxyXd.GdprI18nModel)(i18nData); else if ((0, $czsx7.isTcfI18nData)(i18nData)) { this.i18n = new (0, $czsx7.TcfI18nModel)(i18nData); if (this.tcf?.acm?.vendors) this.tcf.updateAcmVendorsPurposes(this.i18n.tcf.acm.vendorsPurposes); } else if ((0, $ddbu5.isCcpaI18nData)(i18nData)) this.i18n = new (0, $ddbu5.UsI18nModel)(i18nData); } /** * Clears the Local Storage including Cross Domain * @returns {Promise<void>} */ async clearStorage() { return this.consentService.clearConsentsLocally(); } /** * Unblock the scripts which need consent to be run * @returns {Promise<string[]>} - A list with the services names which were unblocked. */ async unblockScriptsWithConsent() { const acceptedDps = this.dps.getAcceptedServices('name'); return this.scriptService.unblockScripts(acceptedDps); } /** * Get the Controller Id * @returns {string | undefined} - The controller id value. */ getControllerId() { return this.consent?.controllerId; } /** * Get the current selected language * @returns {string} the selected language */ getLanguage() { return this.ui.getLanguage(); } /** * Get consent required * @returns {boolean | undefined} - True if consent is required from user. */ getIsConsentRequired() { return this.consent?.required; } /** * Sets the CMP language to the new given language * @param {string} language - New language * @returns {Promise<void>} */ async changeLanguage(language) { if (!this.languages.getHasLanguage(language)) return; this.ui.setLanguage(language); this.localStorageService.setUiData({ language: language }); await this.initI18nData(); } /** * Will set the analytics pixel via network call and will fire the custom events defined on the AI * @param {CMP_EVENT_TYPE} cmpEventType - The type of event which trigered the analytics call. * @param {CmpEventSource} source - The source from where the event was fired originally. * @returns {void} */ setAnalyticsPixel(cmpEventType, source) { this.analyticsService?.setAnalyticsPixel(cmpEventType, source); } /** * Will dispatch an event (UC_UI_VIEW_CHANGED) signaling that the view has changed * @param {UiView | undefined} previousView - The previous view that was displayed. * @param {UiView} view - The current view being displayed. * @returns {void} */ dispatchViewChanged(previousView, view) { (0, $9AFzU.V2BridgeCustomEvents).dispatchUcUiViewChangedEvent({ previousView: previousView, view: view }); if (this.gppService) { if (view === 'first' || view === 'second') this.gppService.setCmpDisplayVisible(); else this.gppService.setCmpDisplayHidden(); this.gppService.setCmpSignalReady(); this.gppService.setCmpStatusLoaded(); } if (this.tcf) { if (view === 'first' || view === 'second') this.tcf.setUIOpen(); else if (previousView !== 'none') this.tcf.setUIClosed(); } } /** * Accepts all consents inside the CMP * @returns {Promise<void>} */ async acceptAllConsents() { if (this.tcf) this.tcf.acceptAll(); this.dps.acceptAll(); } /** * Denys all consents inside the CMP * @returns {Promise<void>} */ async denyAllConsents() { if (this.tcf) this.tcf.denyAll(); this.dps.denyAll(); } /** * Updates a list of consents with the respective state * @param {ServicesConsents} consents - List of (serviceId, consentState) pair. * @returns {Promise<void>} */ async updateServicesConsents(consents) { this.dps.updateSome(consents); } /** * Updates a specific consent with the respective state * @param {ServiceConsent} consent - The service to be updated (serviceId, consentState) pair. * @returns {Promise<void>} */ async updateServiceConsent(consent) { this.dps.updateSome([ consent ]); } /** * Updates a list of categories with the respective state * @param {CategoriesConsents} categoriesConsents - List of (categoryId, consentState) pair. * @returns {Promise<void>} */ async updateCategoriesConsents(categoriesConsents) { this.dps.updateCategoriesConsents(categoriesConsents); } /** * Updates a specific category with the respective state * @param {CategoriesConsents} categoriesConsents - The category to be updated (categoryId, consentState) pair. * @returns {Promise<void>} */ async updateCategoryConsent(categoryConsent) { this.dps.updateCategoriesConsents([ categoryConsent ]); } /** * Save the consents * @param {ConsentType} consentType - Type of consent (Implicit/Explicit). * @param {boolean | undefined} fromEmbeddings - Wether or not the save was called from the embeddings view. * @returns {Promise<void>} */ async saveConsents(consentType = 'EXPLICIT', fromEmbeddings) { if (this.consent) { /* GENERAL */ this.consent.setUiVersion(); this.consent.setRequired(false); this.consent.setSetting(this.setting); this.consent.setLanguage(this.ui.getLanguage()); this.consent.setUpdatedAt(Date.now()); const previousConsentHash = this.consent.hash; this.consent.setHash((0, $27GXH.sha256)(this.consent.updatedAt.toString())); if (this.setting.type === 'US') { // TODO US this needs to be flexible based on US legislation // First we check if the user has opted out (meaning all denied in US) const hasOptedOut = this.dps.getConsentStatus() === 'ALL_DENIED'; const ccpaConsentModel = this.consent; ccpaConsentModel.setHasOptedOut(hasOptedOut); ccpaConsentModel.emitCcpaString(); } else if (fromEmbeddings) this.consent.setUpdatedBy('onUpdateServices'); else this.consent.setUpdatedBy(this.dps.updatedBy || this.tcf?.updatedBy || 'onUpdateServices'); // reset updated by reason after it has been applied this.dps.updatedBy = undefined; if (this.tcf) this.tcf.updatedBy = undefined; /* GDPR/US */ this.consent.setStatus(this.dps.getConsentStatus()); this.consent.setServiceIds(this.dps.getConsentServiceIds()); this.consent.setType(consentType); /* TCF */ if (this.tcf) { const consent = this.consent; consent.setTcString(this.tcf.getTcString()); if (this.tcf.acm) { const updatedACString = this.tcf.getACString(); consent.setAcString(updatedACString); this.tcf.setAddtlConsent(updatedACString); } this.tcf.refreshTimestamp(); this.tcf.emitTcString(); } /* PROCESS */ await this.applyConsents(previousConsentHash, fromEmbeddings); } } /** * Save the consents remotely on API * @returns {Promise<void>} */ async saveConsentRemotely() { if (this.consent && !this.consent.isBot) { const vendors = this.tcf && Object.entries(this.tcf.vendors).map(([id, { legIntPurposes: legIntPurposes, purposes: purposes, specialPurposes: specialPurposes }])=>{ return [ +id, legIntPurposes, purposes, specialPurposes ]; }); const apiSaveConsentData = { consent: this.consent, services: this.dps.services, settingsType: this.setting.type, ucString: this.localStorageService.getConsentString(), crossDeviceEnabled: this.crossDeviceService, analyticsEnabled: typeof this.analyticsService !== 'undefined', ...vendors && { vendors: vendors } }; await this.consentService.saveConsentRemotely(apiSaveConsentData); } } /** * Check if all consents are granted * @returns {boolean} - True if all consents accepted. */ areAllConsentsAccepted() { return this.dps.getConsentStatus() === 'ALL_ACCEPTED'; } /** * Check if all consents are denied * @returns {boolean} - True if all consents denied. */ areAllConsentsDenied() { return this.dps.getConsentStatus() === 'ALL_DENIED'; } /** * Gets the detailed information of a service * @param {string} serviceId - Service id. * @param {boolean} includeDetails - Determine wether service details should be included on the result or not. * @returns {Promise<{service: ServiceData; i18n: ServiceI18n;} | undefined>} - The service detailed information. */ async getServiceInfo(serviceId, includeDetails = false) { const service = this.dps.getService(serviceId); if (!service) return; if (!this.i18n || includeDetails && !this.i18n.getServiceHasDetails(serviceId)) await this.initI18nData(); if (this.i18n) return { service: service, i18n: this.i18n.getService(serviceId) }; return; } /** * Get Stored Information via URL * @param {string} url - URL for Stored Info. * @returns {Promise<{disclosures?: StoredInfoItem[] | undefined; domains?: StoredInfoItem[] | undefined;}>} - The service's stored information. */ async getStoredInfoByUrl(url) { const storedInfoContent = {}; const deviceStorage = await this.apiService.fetchStoredInfoData(url); const isTCF = this.setting.getType() === 'TCF'; if (this.i18n === undefined) await this.initI18nData(); else { const { anyDomain: anyDomain, cookieRefresh: cookieRefreshLabel, domain: domainLabel, multipleDomains: multipleDomains, duration: duration = 'duration', no: no, type: typeLabel = 'type', yes: yes } = this.i18n.base.cookieInformation; const { purposes: purposesLabel, day: day, days: days, hour: hour, hours: hours, minute: minute, minutes: minutes, month: month, months: months, second: second, seconds: seconds, session: session, year: year, years: years } = this.i18n.base; if (deviceStorage) { const { disclosures: disclosures, domains: domains } = deviceStorage; const disclosuresData = []; const domainsData = []; // Disclosures disclosures.map((disclosure)=>{ const { cookieRefresh: cookieRefresh, description: description, domain: domain, identifier: identifier, maxAgeSeconds: maxAgeSeconds, name: name, type: type, purposes: purposes } = disclosure; let purposesValue = ''; if (isTCF) { if (purposes && purposes?.length > 0) { const purposesInfo = []; purposes.forEach((purpose)=>{ if (this.tcf?.purposes[purpose]) purposesInfo.push(this.tcf.purposes[purpose].name); }); purposesValue = `${purposesInfo.join('; ')}`; } } const bodyData = []; // Type bodyData.push({ label: typeLabel, value: `${type}` }); // Duration if (type.toString() === 'cookie') bodyData.push({ label: duration, value: (0, $jDAan$convertCookieMaxAge)(maxAgeSeconds, { day: day, days: days, hour: hour, hours: hours, minute: minute, minutes: minutes, month: month, months: months, second: second, seconds: seconds, session: session, year: year, years: years }) }); // Cookie refresh if (cookieRefresh !== null) bodyData.push({ label: cookieRefreshLabel, value: cookieRefresh ? yes : no }); // Domain if (domain) bodyData.push({ label: domainLabel, value: (0, $jDAan$convertDomain)(domain, anyDomain, multipleDomains) }); // Purposes -> only for TCF if (isTCF && purposesValue !== '') bodyData.push({ label: purposesLabel || 'Purposes', value: purposesValue }); disclosuresData.push({ id: name ?? identifier, name: name ?? identifier, ...description && { description: description }, body: bodyData }); }); // Domains -> only for TCF if (isTCF) domains?.map((domainsEntry)=>{ const { domain: domain, use: use } = domainsEntry; domainsData.push({ id: domain, name: domain, body: [ ...use ? [ { label: purposesLabel || 'Purposes', value: use } ] : [] ] }); }); if (disclosuresData.length > 0) storedInfoContent.disclosures = disclosuresData; if (domainsData.length > 0) storedInfoContent.domains = domainsData; } } return storedInfoContent; } /** * Save consents locally and remotely * @param {string} consentHash - Consent hash string. * @returns {Promise<void>} */ async applyConsents(consentHash, fromEmbeddings) { if (!this.consent) throw new Error('No consents'); const requiresSaving = this.consent.hash !== consentHash; /* Google Consent Mode */ if (this.gcm) this.gcm.apply(this.dps.services, this.consent.type); // Microsoft Consent Mode if (this.uet) this.uet.apply(this.dps.services, this.consent.type); if (requiresSaving) { await this.consentService.saveConsentLocally(this.consent, this.dps); if (this.gppService) { let consentString = ''; let legislation; if ((0, $j9WI1.isUsConsentModel)(this.consent)) { consentString = this.consent.ccpaString; legislation = this.consent.legislation; } if ((0, $j9WI1.isTcfConsentModel)(this.consent)) consentString = this.consent.tcString; this.gppService?.setSectionString(consentString, this.setting.type, legislation); } } setTimeout(()=>{ this.unblockScriptsWithConsent(); }, 0); // put this possibly expensive process to another thread if (this.customEventService || this.dataLayerService) { const consentDetails = await this.getConsentDetails(); if (consentDetails) { this.customEventService.dispatchConsentDetails(consentDetails); this.dataLayerService?.push((0, $9AFzU.V2BridgeCustomEvents).getConsentDetailsV2(consentDetails)); } } if (requiresSaving) { this.saveConsentRemotely().catch(()=>{ (0, $jDAan$UCConsole).error('CmpController - saveConsentRemotely', 'Could not save consents'); }); this.customEventService.dispatch('UC_CONSENT_CHANGED', await this.getConsentDetails()); } else { // Re-init ucData.consent in the case that consent does not require saving, // but ucData.consent does not exist [CTS-937]/[EUD-3033] const ucData = this.localStorageService.getUcData(); if (!ucData?.consent) { const servicesData = this.consentService.mapServicesData(this.dps.services); this.localStorageService.setConsentData({ services: servicesData }); } } (0, $2hccy.webSdkEvents).emit('CONSENTS_APPLIED', { fromEmbeddings: fromEmbeddings }); } getPrivacyButtonTheme(custom) { const direction = this.languages.getLanguageScreenDirection(this.ui.getLanguage()); return this.theme.getPrivacyButtonTheme({ custom: custom, direction: direction }); } getEmbeddingTheme(custom) { const direction = this.languages.getLanguageScreenDirection(this.ui.getLanguage()); return this.theme.getEmbeddingsTheme({ custom: custom, direction: direction }); } getCmpTheme(layer, custom) { const direction = this.languages.getLanguageScreenDirection(this.ui.getLanguage()); return this.theme.getCmpTheme(layer, { custom: custom, direction: direction }); } getThemeDefaults() { this.theme.getThemeDefaults(); } /** * Update theme model * @param {ThemeData} themeData - Theme model data. * @returns {void} */ updateTheme(themeData) { if (themeData) this.theme = new (0, $4PEVa.ThemeModel)(themeData); } /** * Get the CMP config * @return Promise<Record<string, object>> */ async getCmpConfig() { return { i18n: { ...this.i18n?.base.poweredBy.isEnabled && { poweredBy: this.i18n?.base.poweredBy } } }; } /** * Get the services * @return Promise<[serviceId: string, data: ServiceData][]> */ async getServices() { return Object.entries(this.dps.services); } /** * Get the categories * @return Promise<[categoryId: string, data: CategoryData][]> */ async getCategories() { return Object.entries(this.dps.categories); } /** * Get the categories * @return Promise<[language: string, data: LanguageData][]> */ async getLanguages() { return Object.entries(this.languages.languages); } } }); parcelRegister("evIjB", function(module, exports) { $parcel$export(module.exports, "ApiService", () => (parcelRequire("elIWk")).default); $parcel$export(module.exports, "ConsentService", () => (parcelRequire("1uAEQ")).default); $parcel$export(module.exports, "CrossDomainService", () => (parcelRequire("5PUMf")).default); $parcel$export(module.exports, "CustomEventService", () => (parcelRequire("22ugm")).default); $parcel$export(module.exports, "DataLayerService", () => (parcelRequire("6KjkM")).default); $parcel$export(module.exports, "LocalStorageService", () => (parcelRequire("69Lqy")).default); $parcel$export(module.exports, "ScriptService", () => (parcelRequire("1uDf8")).default); var $4AkFz = parcelRequire("4AkFz"); var $22ugm = parcelRequire("22ugm"); var $6KjkM = parcelRequire("6KjkM"); var $elIWk = parcelRequire("elIWk"); var $1uAEQ = parcelRequire("1uAEQ"); var $5PUMf = parcelRequire("5PUMf"); var $69Lqy = parcelRequire("69Lqy"); var $1uDf8 = parcelRequire("1uDf8"); }); parcelRegister("4AkFz", function(module, exports) { $parcel$export(module.exports, "default", () => $8a561ec7a49bb827$export$2e2bcd8739ae039); var $ikG7g = parcelRequire("ikG7g"); var $j0vu9 = parcelRequire("j0vu9"); var $dtBZI = parcelRequire("dtBZI"); var $9AFzU = parcelRequire("9AFzU"); class $8a561ec7a49bb827$export$2e2bcd8739ae039 { constructor({ settingsId: settingsId, abTestVariant: abTestVariant, euMode: euMode = false, sandbox: sandbox = false }){ this.version = 2 // set version to 2 to identify rather request is coming from v2 or boost ; /** * Set analytics pixel (via network call) and dispatch custom events * @param {CMP_EVENT_TYPE} cmpEventType - The event type. * @param {CmpEventSource | undefined} source - The event source. * @returns {void} */ this.setAnalyticsPixel = (cmpEventType, source)=>{ if (!this.getIsValidEventType(cmpEventType)) return; const cacheBuster = Date.now(); const referrer = encodeURIComponent(document.location.href); const actionType = this.getActionType(cmpEventType, source); const queryString = `v=${this.version}&sid=${this.settingsId}&t=${actionType}&abv=${this.abTestVariant || ''}&r=${referrer}&cb=${cacheBuster}`; const src = `${this.domains.analytics}/uct?${queryString}`; const pixel = new Image(); pixel.src = src; // DEPRECATED V2 CUSTOM EVENT UC_UI_CMP_EVENT (0, $9AFzU.V2BridgeCustomEvents).dispatchUcUiCmpEvent(cmpEventType, source, this.abTestVariant); }; this.domains = { analytics: (0, $dtBZI.TRACK_EVENT_DOMAINS)[sandbox ? 'SANDBOX' : 'PROD'][euMode ? 'EU_URI' : 'URI'], ...window.ucCmpConfig?.proxy?.analytics && { analytics: window.ucCmpConfig.proxy.analytics } }; this.settingsId = settingsId; this.abTestVariant = abTestVariant; } getIsValidEventType(cmpEventType) { if (Object.values((0, $j0vu9.CMP_EVENT_TYPE)).includes(cmpEventType)) return true; return false; } getActionType(cmpEventType, source) { switch(cmpEventType){ case (0, $j0vu9.CMP_EVENT_TYPE).CMP_SHOWN: return (0, $ikG7g.UI_ACTION_TYPE).CMP_SHOWN; case (0, $j0vu9.CMP_EVENT_TYPE).ACCEPT_ALL: if (source) switch(source){ case 'first': return (0, $ikG7g.UI_ACTION_TYPE).ACCEPT_ALL_L1; case 'second': return (0, $ikG7g.UI_ACTION_TYPE).ACCEPT_ALL_L2; default: break; } return (0, $ikG7g.UI_ACTION_TYPE).ACCEPT_ALL; case (0, $j0vu9.CMP_EVENT_TYPE).DENY_ALL: if (source) switch(source){ case 'first': return (0, $ikG7g.UI_ACTION_TYPE).DENY_ALL_L1; case 'second': return (0, $ikG7g.UI_ACTION_TYPE).DENY_ALL_L2; default: break; } return (0, $ikG7g.UI_ACTION_TYPE).DENY_ALL; case (0, $j0vu9.CMP_EVENT_TYPE).SAVE: if (source) switch(source){ case 'first': return (0, $ikG7g.UI_ACTION_TYPE).SAVE_L1; case 'second': return (0, $ikG7g.UI_ACTION_TYPE).SAVE_L2; default: break; } return (0, $ikG7g.UI_ACTION_TYPE).SAVE; case (0, $j0vu9.CMP_EVENT_TYPE).CCPA_TOGGLES_ON: return (0, $ikG7g.UI_ACTION_TYPE).CCPA_TOGGLES_ON; case (0, $j0vu9.CMP_EVENT_TYPE).CCPA_TOGGLES_OFF: return (0, $ikG7g.UI_ACTION_TYPE).CCPA_TOGGLES_OFF; case (0, $j0vu9.CMP_EVENT_TYPE).COOKIE_POLICY_LINK: return (0, $ikG7g.UI_ACTION_TYPE).COOKIE_POLICY_LINK; case (0, $j0vu9.CMP_EVENT_TYPE).IMPRINT_LINK: return (0, $ikG7g.UI_ACTION_TYPE).IMPRINT_LINK; case (0, $j0vu9.CMP_EVENT_TYPE).MORE_INFORMATION_LINK: return (0, $ikG7g.UI_ACTION_TYPE).MORE_INFORMATION_LINK; case (0, $j0vu9.CMP_EVENT_TYPE).PRIVACY_POLICY_LINK: return (0, $ikG7g.UI_ACTION_TYPE).PRIVACY_POLICY_LINK; case (0, $j0vu9.CMP_EVENT_TYPE).SAY_MINE_LINK: return (0, $ikG7g.UI_ACTION_TYPE).SAY_MINE_LINK; default: return (0, $ikG7g.UI_ACTION_TYPE).UNDEFINED; } } } }); parcelRegister("ikG7g", function(module, exports) { $parcel$export(module.exports, "UI_ACTION_TYPE", () => $28da986583d9d04e$export$ee8035c8cdbc680c); var $28da986583d9d04e$export$ee8035c8cdbc680c = /*#__PURE__*/ function(UI_ACTION_TYPE) { UI_ACTION_TYPE[UI_ACTION_TYPE["UNDEFINED"] = 0] = "UNDEFINED"; UI_ACTION_TYPE[UI_ACTION_TYPE["CMP_SHOWN"] = 1] = "CMP_SHOWN"; UI_ACTION_TYPE[UI_ACTION_TYPE["ACCEPT_ALL"] = 2] = "ACCEPT_ALL"; UI_ACTION_TYPE[UI_ACTION_TYPE["DENY_ALL"] = 3] = "DENY_ALL"; UI_ACTION_TYPE[UI_ACTION_TYPE["SAVE"] = 4] = "SAVE"; UI_ACTION_TYPE[UI_ACTION_TYPE["ACCEPT_ALL_L1"] = 5] = "ACCEPT_ALL_L1"; UI_ACTION_TYPE[UI_ACTION_TYPE["DENY_ALL_L1"] = 6] = "DENY_ALL_L1"; UI_ACTION_TYPE[UI_ACTION_TYPE["SAVE_L1"] = 7] = "SAVE_L1"; UI_ACTION_TYPE[UI_ACTION_TYPE["ACCEPT_ALL_L2"] = 8] = "ACCEPT_ALL_L2"; UI_ACTION_TYPE[UI_ACTION_TYPE["DENY_ALL_L2"] = 9] = "DENY_ALL_L2"; UI_ACTION_TYPE[UI_ACTION_TYPE["SAVE_L2"] = 10] = "SAVE_L2"; UI_ACTION_TYPE[UI_ACTION_TYPE["COOKIE_POLICY_LINK"] = 11] = "COOKIE_POLICY_LINK"; UI_ACTION_TYPE[UI_ACTION_TYPE["IMPRINT_LINK"] = 12] = "IMPRINT_LINK"; UI_ACTION_TYPE[UI_ACTION_TYPE["MORE_INFORMATION_LINK"] = 13] = "MORE_INFORMATION_LINK"; UI_ACTION_TYPE[UI_ACTION_TYPE["PRIVACY_POLICY_LINK"] = 14] = "PRIVACY_POLICY_LINK"; UI_ACTION_TYPE[UI_ACTION_TYPE["CCPA_TOGGLES_ON"] = 15] = "CCPA_TOGGLES_ON"; UI_ACTION_TYPE[UI_ACTION_TYPE["CCPA_TOGGLES_OFF"] = 16] = "CCPA_TOGGLES_OFF"; UI_ACTION_TYPE[UI_ACTION_TYPE["SAY_MINE_LINK"] = 17] = "SAY_MINE_LINK"; UI_ACTION_TYPE[UI_ACTION_TYPE["FIRST_LAYER_SHOWN"] = 18] = "FIRST_LAYER_SHOWN"; UI_ACTION_TYPE[UI_ACTION_TYPE["SECOND_LAYER_SHOWN"] = 19] = "SECOND_LAYER_SHOWN"; UI_ACTION_TYPE[UI_ACTION_TYPE["PRIVACY_BUTTON_SHOWN"] = 20] = "PRIVACY_BUTTON_SHOWN"; UI_ACTION_TYPE[UI_ACTION_TYPE["NONE_SHOWN"] = 21] = "NONE_SHOWN"; return UI_ACTION_TYPE; }({}); }); parcelRegister("j0vu9", function(module, exports) { $parcel$export(module.exports, "CMP_EVENT_TYPE", () => $d8f2ea8e2fd18208$export$86d70409c0ac3e02); var $d8f2ea8e2fd18208$export$86d70409c0ac3e02 = /*#__PURE__*/ function(CMP_EVENT_TYPE) { CMP_EVENT_TYPE["CMP_SHOWN"] = "CMP_SHOWN"; CMP_EVENT_TYPE["ACCEPT_ALL"] = "ACCEPT_ALL"; CMP_EVENT_TYPE["DENY_ALL"] = "DENY_ALL"; CMP_EVENT_TYPE["SAVE"] = "SAVE"; CMP_EVENT_TYPE["COOKIE_POLICY_LINK"] = "COOKIE_POLICY_LINK"; CMP_EVENT_TYPE["IMPRINT_LINK"] = "IMPRINT_LINK"; CMP_EVENT_TYPE["MORE_INFORMATION_LINK"] = "MORE_INFORMATION_LINK"; CMP_EVENT_TYPE["PRIVACY_POLICY_LINK"] = "PRIVACY_POLICY_LINK"; CMP_EVENT_TYPE["CCPA_TOGGLES_ON"] = "CCPA_TOGGLES_ON"; CMP_EVENT_TYPE["CCPA_TOGGLES_OFF"] = "CCPA_TOGGLES_OFF"; CMP_EVENT_TYPE["SAY_MINE_LINK"] = "SAY_MINE_LINK"; return CMP_EVENT_TYPE; }({}); }); parcelRegister("dtBZI", function(module, exports) { $parcel$export(module.exports, "TRACK_EVENT_DOMAINS", () => $b0693f0319f01624$export$569886486a26c95f); // import { ACTION_TYPE } from './interfaces'; // // export const CONSENT_ACTIONS = [ // ACTION_TYPE.ACCEPT_ALL, // ACTION_TYPE.ACCEPT_ALL_L1, // ACTION_TYPE.ACCEPT_ALL_L2, // ACTION_TYPE.DENY_ALL, // ACTION_TYPE.DENY_ALL_L1, // ACTION_TYPE.DENY_ALL_L2, // ACTION_TYPE.SAVE, // ACTION_TYPE.SAVE_L1, // ACTION_TYPE.SAVE_L2, // ]; // // export const CCPA_CONSENT_ACTIONS = [ACTION_TYPE.CCPA_TOGGLES_OFF, ACTION_TYPE.CCPA_TOGGLES_ON]; // export const VIEW_ACTIONS = [ // ACTION_TYPE.FIRST_LAYER_SHOWN, // ACTION_TYPE.SECOND_LAYER_SHOWN, // ACTION_TYPE.NONE_SHOWN, // ACTION_TYPE.PRIVACY_BUTTON_SHOWN, // ]; // // export const VIEW_EVENTS_MAP = { // [ACTION_TYPE.FIRST_LAYER_SHOWN]: 'FIRST_LAYER', // [ACTION_TYPE.SECOND_LAYER_SHOWN]: 'SECOND_LAYER', // [ACTION_TYPE.PRIVACY_BUTTON_SHOWN]: 'PRIVACY_BUTTON', // [ACTION_TYPE.NONE_SHOWN]: 'NONE', // }; const $b0693f0319f01624$export$569886486a26c95f = { PROD: { URI: 'https://uct.service.usercentrics.eu', EU_URI: 'https://uct.eu.usercentrics.eu' }, SANDBOX: { URI: 'https://uct.service.usercentrics.eu', EU_URI: 'https://uct.eu.usercentrics.eu' } }; }); parcelRegister("9AFzU", function(module, exports) { $parcel$export(module.exports, "V2BridgeCustomEvents", () => $7531446f1585bb9f$export$4fe773a5245e2464); class $7531446f1585bb9f$export$4fe773a5245e2464 { static getConsentDetailsV2(consentDetails) { const newCategoriesObject = {}; Object.entries(consentDetails.categories).map(([key, categoryData])=>{ if (categoryData.state === 'SOME_ACCEPTED') newCategoriesObject[key] = null; else newCategoriesObject[key] = categoryData.state === 'ALL_ACCEPTED'; }); const newServicesObject = {}; Object.entries(consentDetails.services).map(([, serviceData])=>{ newServicesObject[serviceData.name] = !!serviceData.consent?.given; }); let consentStatusObject = { action: consentDetails.consent.updatedBy, event: 'consent_status', type: consentDetails.consent.type, ucCategory: newCategoriesObject }; consentStatusObject = { ...consentStatusObject, ...newServicesObject }; return consentStatusObject; } static dispatchUcUiCmpEvent(cmpEventType, source, abTestVariant) { const detail = { abTestVariant: abTestVariant, source: source, type: cmpEventType }; this.dispatch('UC_UI_CMP_EVENT', detail); } static dispatchUcUiViewChangedEvent(detail) { const viewDictionary = { none: 'NONE', first: 'FIRST_LAYER', second: 'SECOND_LAYER', button: 'PRIVACY_BUTTON' }; const event = new window.CustomEvent('UC_UI_VIEW_CHANGED', { detail: { // This will ensure retrocompatibility with V2 previousView: detail.previousView ? viewDictionary[detail.previousView] : undefined, view: viewDictionary[detail.view] } }); window.dispatchEvent(event); } static dispatch(eventName, detail) { const event = new window.CustomEvent(eventName, { detail: detail }); window.dispatchEvent(event); } } }); parcelRegister("22ugm", function(module, exports) { $parcel$export(module.exports, "default", () => $216104ce5d14f76e$export$2e2bcd8739ae039); var $9AFzU = parcelRequire("9AFzU"); class $216104ce5d14f76e$export$2e2bcd8739ae039 { constructor(eventNames){ this.eventNames = eventNames; } /** * Dispatches UC_CONSENT and custom events with consent details * @param {ConsentDetails} consentDetails - The consent details data. * @returns {void} */ dispatchConsentDetails(consentDetails) { this.dispatch('UC_CONSENT', consentDetails); const v2ConsentDetails = (0, $9AFzU.V2BridgeCustomEvents).getConsentDetailsV2(consentDetails); this.eventNames.forEach((eventName)=>{ this.dispatch(eventName, v2ConsentDetails); }); } dispatchUcGcmUpdateEvent(detail) { this.dispatch('UC_GCM_UPDATE', detail); } dispatchUcUetUpdateEvent(detail) { this.dispatch('UC_UET_UPDATE', detail); } /** * Dispatches events to the window * @param {string} name - The event name. * @param {unknown} data - The event data. * @returns {void} */ dispatch(name, data) { const event = new window.CustomEvent(name, { detail: data }); window.dispatchEvent(event); } } }); parcelRegister("6KjkM", function(module, exports) { $parcel$export(module.exports, "default", () => $82043bd3cb346f1b$export$2e2bcd8739ae039); class $82043bd3cb346f1b$export$2e2bcd8739ae039 { constructor(dataLayers){ this.windowDataLayers = window; this.dataLayers = dataLayers; dataLayers.forEach((key)=>{ if (!this.windowDataLayers[key]) this.windowDataLayers[key] = []; }); } /** * Pushes information into the dataLayer window object * @param {unknown} data - The data to be pushed. * @returns {void} */ push(data) { this.dataLayers.forEach((key)=>{ try { this.windowDataLayers[key].push(data); } catch (e) { (0, $jDAan$UCConsole).warn('dataLayer', `Could not push to dataLayer ${key}`, e); } }); } } }); parcelRegister("elIWk", function(module, exports) { $parcel$export(module.exports, "default", () => $c85908aa7c06fb4d$export$2e2bcd8739ae039); var $j38U1 = parcelRequire("j38U1"); class $c85908aa7c06fb4d$export$2e2bcd8739ae039 { constructor(options){ this.cache = {}; this.sandbox = options.sandbox === true; this.cacheVersion = options.cacheVersion; this.euMode = options.euMode === true; this.domains = this.getDomains(); this.paths = this.getPaths(); } getDomains() { // EU Mode for dynamic environments (PRs) const API_ROOT = this.euMode && "https://v1.api.service.eu1.cmp.usercentrics-staging.eu" ? "https://v1.api.service.eu1.cmp.usercentrics-staging.eu" : "https://v1.api.service.cmp.usercentrics-staging.eu"; retur