(()=>{ let dermObj = dml_fmc; let initialized = false; dermObj.tmDt.mainScriptExec = Date.now() - dermObj.stTmStmp; dermObj.urlObj = new URL(window.location.href); dermObj.urlObj.searchParams.delete('cnst'); dermObj.urlObj.searchParams.delete('imupld'); dermObj.newUrl = dermObj.urlObj.toString(); history.replaceState({}, '', dermObj.newUrl); dermObj.config = { chat: { enabled: false, key: 'none', depId: '' }, forcedPage: '', forcedCountry: '', forcedLanguage: '', histFmcObj: true, percMatchFolder: '', useDioxideStaging: false, maxConcerns: 6, showQniConsentButton: true, qniChoiceFromLanding: false, quizNoImage: false, quizAfterImage: false, useNewUserKits: false, userImgOnly: false, useFaceAi: true, crm: { enabled: false, country: '' }, badges: {}, pageDict:{ 'loading' : 'fmc_loading_page_default', 'landing' : 'fmc_landing_page_default', 'onboarding' : 'fmc_onboarding_page_default', 'capture' : 'fmc_capture_page_default', "quiz_after_image" : 'fmc_qai_page_default', 'waiting' : 'fmc_waiting_page_default', 'results' : 'fmc_results_prep_treat_glow' }, useTreatmentBanners : false, blogs_file : '', useShopify: false, useCustomShopifyFunction: false, use2FA: false, requestEmailForResults : false, showSaveEmailMobile: false, hideEmailButtons: false, emailDoubleCheckbox : false, emailSubjectOverride: '', hideContactBanners: false, langForBackends: '', skipMasks : false, shopButton : { textOverride : "", showPrices : false, hide: false }, storeLocator: { extraParameters: "", regexFilter: "", showStores: false }, brandingLogoUrl : '', brandingLogoUrlGrey : '', brandingLogoScale : 1 , useAgGeFaceApiFeature : false, useLightening: true, sentrySampleRate: 0.01, useSentry: true } if (dermObj.isPercMatchMiniPage == undefined){ dermObj.isPercMatchMiniPage = false; } // adding url parameter for face model or age bucket question const fmAgGeVer = window.localStorage.getItem('fmAgGeVer'); if (fmAgGeVer == '0'){ dermObj.config.useAgGeFaceApiFeature = false; }else if (fmAgGeVer == '1'){ dermObj.config.useAgGeFaceApiFeature = true; }else{ dermObj.config.useAgGeFaceApiFeature = Math.random() < 0.5; } if (dermObj.isPercMatchMiniPage == true){ dermObj.config.useAgGeFaceApiFeature = false; } (async ()=>{ let consInt = setInterval(async ()=>{ if (typeof dermObj.checkCookieConsent == 'function'){ clearInterval(consInt); await dermObj.checkCookieConsent() if (dermObj.config.allowCookies){ if (dermObj.config.useAgGeFaceApiFeature){ window.localStorage.setItem('fmAgGeVer','1'); }else{ window.localStorage.setItem('fmAgGeVer','0'); } } } },500) })(); dermObj.addUrlParameter = (key, value) => { let urlObject = new URL(window.location.href); let params = urlObject.searchParams; params.set(key, value); // This will automatically handle existing parameters return urlObject.toString(); } if (dermObj.isPercMatchMiniPage != true){ let newUrl; if (dermObj.config.useAgGeFaceApiFeature){ newUrl = dermObj.addUrlParameter('4gD3v',1) }else{ newUrl = dermObj.addUrlParameter('4gD3v',0) } window.history.replaceState({}, '', newUrl); } dermObj.referrer = window.location.href.split('?')[0] if (window.location.search.indexOf('forced_page=') > -1){ try{ dermObj.config.forcedPage = decodeURIComponent(window.location.search.split('forced_page=')[1].split('&')[0]); }catch(err){console.error(err)} } if (window.location.search.indexOf('forced_country=') > -1){ dermObj.config.forcedCountry = window.location.search.split('forced_country=')[1].split('&')[0]; } if (window.location.search.indexOf("forced_lang=") >-1 ){ dermObj.config.forcedLanguage = window.location.search.split("forced_lang=")[1].split("&")[0]; } if (window.location.search.indexOf("rspg=") >-1 ){ try{ const forcedResultsPage = window.location.search.split("rspg=")[1].split("&")[0]; if (dermObj.body.querySelectorAll('.fmc_page').map((fmcPage) => {return fmcPage.id}).includes(forcedResultsPage)){ dermObj.config.pageDict.results = forcedResultsPage; } }catch(err){} } if (window.location.search.indexOf("qni=1") >-1 ){ dermObj.config.quizNoImage = true; } if (window.location.search.indexOf('force_qai=1') > -1){ localStorage.removeItem('fmc_qai'); dermObj.config.quizAfterImage = true; } if (window.location.search.indexOf('force_qai=0') > -1){ localStorage.removeItem('fmc_qai'); dermObj.config.quizAfterImage = false; } dermObj.getGDPR = ()=>{ return new Promise(async (resolve, reject)=>{ const backends = { us_v2 : "https://global.facemapping.me", stg_v2 : "https://staging.facemapping.me", eu_v2 : "https://eu.facemapping.me", ca_v2 : "https://ca.facemapping.me", us : "https://fmc-backend-production.herokuapp.com", eu : "https://imb-backend-eu.herokuapp.com", ca : "https://imb-backend-ca.herokuapp.com", stg : "https://fmc-backend-staging.herokuapp.com" } const countriesUsingBackendEU = ["BE", "EL", "LT", "PT", "BG", "ES", "LU", "RO", "CZ", "FR", "HU", "SI", "DK", "HR", "MT", "SK", "DE", "IT", "NL", "FI", "EE", "CY", "AT", "SE", "IE", "LV", "PL", "IS", "NO", "LI", "CH", "GB"]; let gdprRes = await fetchGDPRRes(); dermObj.gdprLegalCopy = gdprRes.legal_copy; if (dermObj.config.forcedCountry){ dermObj.countryCode = dermObj.config.forcedCountry; }else{ dermObj.countryCode = gdprRes.country_code; } if (dermObj.countryCode == 'IT'){ dermObj.body.querySelector('#fmc_legal_scroll_container_italy').style.display = 'block'; dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'none'; } let be_code="us"; if (dermObj.countryCode == 'US'){ dermObj.config.use2FA = true; dermObj.body.querySelector("#fmc_legal_copy_US_addition").style.display = "block"; //console.log(gdprRes) if (gdprRes.state == 'IL'){ //be_code="us"; } if (gdprRes.state == 'OR' && gdprRes.city == 'Portland'){ dermObj.config.quizNoImage = true; } if (gdprRes.state == 'MD' && gdprRes.city == 'Baltimore'){ dermObj.config.quizNoImage = true; } if (gdprRes.state == 'WA' || gdprRes.state == 'NV'){ dermObj.config.consentWaNv = true; dermObj.config.qniChoiceFromLanding = false; dermObj.body.querySelectorAll('.fmc_landing_default_flow').forEach((defFlowEl) => defFlowEl.style.display ="flex"); dermObj.body.querySelectorAll('.fmc_landing_ai_qni_flow').forEach((choiceFlowEl) => choiceFlowEl.style.display ="none"); } } if (window.location.search.indexOf("forced_be=") > -1){ be_code = window.location.search.split("forced_be=")[1].split("&")[0]; }else{ if (countriesUsingBackendEU.includes(dermObj.countryCode)) be_code = "eu"; if (dermObj.countryCode == "CA") be_code="ca"; } if (countriesUsingBackendEU.includes(dermObj.countryCode)){ dermObj.body.querySelector('#fmc_manageCookiebotLink').style.opacity = 1; dermObj.body.querySelector('#fmc_manageCookiebotLink').style.pointerEvents = 'all'; } if (["eu", "ca"].includes(be_code)){ try{ dermObj.body.querySelectorAll('.fmc_subscribe_checkbox_label').forEach((checkBox)=>{ checkBox.checked=false; }) }catch(err){ console.warn(err) } }else{ dermObj.body.querySelectorAll('.fmc_subscribe_checkbox_label').forEach((checkBox)=>{ checkBox.checked=true; }) } if (dermObj.config.useLightening === true) { be_code += '_v2'; //dermObj.config.sendAlsoToNewEmailEndpoint = false; } if ('https://fmc-backend-production.herokuapp.com'=='https://staging.facemapping.me'){ be_code = 'stg_v2' } if ('https://fmc-backend-production.herokuapp.com'=='https://fmc-backend-staging.herokuapp.com'){ be_code = 'stg' } if (window.location.search.indexOf('be=') > -1 && window.location.search.indexOf('forced_be=') < 0){ be_code = window.location.search.split("be=")[1].split("&")[0]; } if (be_code.indexOf('_v2') > -1){ dermObj.config.sendAlsoToNewEmailEndpoint = false; dermObj.config.useLightening = true; } dermObj.backend = backends[be_code] || backends["us"]; dermObj.sendGA360("main flow",`backend used - ${dermObj.backend}`); dermObj.sendGAFlowEvent(`backend used - ${dermObj.backend}`); resolve(); }) } dermObj.applyLegalText = ()=>{ const legalTextFields = ["legal_text_top", "legal_text_consent", "legal_text_bottom", "legal_text_extra_statement"]; legalTextFields.forEach((legalTextField)=>{ document.querySelectorAll(`[data-widget-legal-term=${legalTextField}]`).forEach((htmlEl)=>{ try{ htmlEl.innerHTML = dermObj.gdprLegalCopy[legalTextField]; }catch(e){ console.error(e); } }); }); setTimeout(()=>{ const extraToggleButton = document.getElementById("dml_fmc_privacy_statment"); if (extraToggleButton != null){ extraToggleButton.addEventListener('click',dermObj.toggleLegalExtraText); } },200) } dermObj.toggleLegalExtraText = ()=>{ document.querySelector('#fmc_legal_overlay .fmc_legal_content_collapsable').classList.toggle('fmc_legal_content_hidden'); document.querySelector('#fmc_legal_overlay .fmc_legal_content_collapsable').scrollIntoView({'behavior':'smooth'}); document.querySelector('#fmc_legal_overlay .fmc_legal_scroll_container').classList.toggle('fmc_show_scrollbar'); } dermObj.showConsent = ()=>{ if (dermObj.tmDt.firstShowCons == undefined){ dermObj.tmDt.firstShowCons = Date.now() - dermObj.stTmStmp; } if (dermObj.config.consentWaNv == true){ dermObj.body.querySelectorAll('#fmc_consent_quiz_button').forEach((btn) => {btn.style.display="none"}) } document.getElementById('fmc_legal_overlay').style.display = "flex"; dermObj.sendGA360("main flow","open consent with CTA"); dermObj.sendGAFlowEvent("open consent with CTA"); } dermObj.consentClickPending = false; dermObj.consentClicked = ()=>{ if (dermObj.consentClickPending == true) return; dermObj.consentClickPending = true; if (dermObj.config.consentWaNv == true && dermObj.config.consentWaNvFirstConsented != true){ dermObj.body.querySelectorAll('.fmc_legal_scroll_wrapper').forEach((scrollEl)=>{scrollEl.style.opacity = 0;}) setTimeout(()=>{ dermObj.body.querySelector('#fmc_legal_scroll_container_default').style.display="none"; dermObj.body.querySelector('#fmc_legal_wa_nv_page_2').style.display="block"; dermObj.body.querySelector('#fmc_consent_reject_button').style.display="flex"; dermObj.config.consentWaNvFirstConsented = true; dermObj.body.querySelectorAll('.fmc_legal_scroll_wrapper').forEach((scrollEl)=>{scrollEl.style.opacity = 1;}) dermObj.consentClickPending = false; },500) return; } if (dermObj.config.consentWaNv == true){ dermObj.body.querySelector('#fmc_legal_scroll_container_default').style.display="block"; dermObj.body.querySelector('#fmc_legal_wa_nv_page_2').style.display="none"; dermObj.body.querySelector('#fmc_consent_reject_button').style.display="none"; dermObj.config.consentWaNvFirstConsented = false; } document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow","consent clicked"); dermObj.sendGAFlowEvent("consent clicked"); if (dermObj.permissionBeforeFormerResults){ dermObj.loadingFormerResultAfterPermission(); }else{ dermObj.gotoPage("capture"); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('cnst')) { urlObj.searchParams.set('cnst', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } } dermObj.consentClickPending = false; } dml_fmc.rejectClicked = ()=>{ dermObj.consentClickPending = true; window.open("https://dermalogica.com", "_self"); } dermObj.consentCanceled = ()=>{ document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow","consent canceled"); dermObj.sendGAFlowEvent("consent canceled"); } dermObj.checkLegalCheckboxesIT = async ()=>{ const italyCheckboxes = Array.from(dermObj.body.querySelectorAll('#fmc_legal_scroll_container_italy input[type=checkbox]')); let activateConsentButton = true; italyCheckboxes.forEach((checkBox) => { activateConsentButton = activateConsentButton && checkBox.checked; }) if (activateConsentButton){ dermObj.body.querySelector('#fmc_consent_accept_button_italy').classList.remove('fmc_inactive'); }else{ dermObj.body.querySelector('#fmc_consent_accept_button_italy').classList.add('fmc_inactive'); } } dermObj.isValidGdrpRes = (gdprObj) => { try{ gdprKeysToCheck = [ "legal_copy", "country_code", "state", "city" ]; gdprKeyArray = Object.keys(gdprObj) const gdprValid = gdprKeysToCheck.every( gdprKey => gdprKeyArray.includes(gdprKey)); return gdprValid; }catch(err){ return false; } } async function fetchGDPRRes(){ return new Promise((resolve,reject) => { if (dermObj.isPercMatchMiniPage == true){ if (window.dsrp != undefined){ if (dermObj.isValidGdrpRes(window.dsrp.gdpr)){ resolve({...window.dsrp.gdpr}) return; } } } const lang_code = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; const gdprUrl = `https://gdpr.facemapping.me/get_country_gdpr/?lang_code=${lang_code}`; fetch(gdprUrl, { method: 'GET', headers: { 'Content-Type' : 'application/x-www-form-urlencoded' } }) .then(response => { if (!response.ok) { reject(new Error('Error in reaching the GDPR endpoint')); } return response.json(); }) .then(gdprRes => { dermObj.debug("success GDPR call", gdprRes); resolve(gdprRes) }) .catch(error => { reject(); }) }) } dermObj.sendGAFlowEvent = (actionString) => { const eventParameters = { action : actionString, page_location: window.location.hostname, page_path: window.location.pathname, page_title: dermObj.currentPage } dermObj.sendGA4("user_flow",eventParameters); } dermObj.sendGAUserClickEvent = (actionString) => { const eventParameters = { action : actionString, page_location: window.location.hostname, page_path: window.location.pathname, page_title: dermObj.currentPage } dermObj.sendGA4("user_click",eventParameters); } dermObj.sentry = {} dermObj.sentry.loaded = false dermObj.sentry.pending = false; dermObj.sentry.sentryBtsClient dermObj.sentry.sentryBtsHub dermObj.sentry.loadScript = function() { dermObj.sentry.pending = true; let script = document.createElement('script'); script.defer = 1; script.crossorigin = "anonymous"; let sampleRate = dermObj.config.sentrySampleRate; script.onload = function(evt) { //console.log('sentry script loaded - ', evt); const defaultIntegrations = Sentry.defaultIntegrations; const integrationsToRemove = ['GlobalHandlers', 'Breadcrumbs', 'TryCatch']; const filteredIntegrations = defaultIntegrations.filter(integration => !integrationsToRemove.includes(integration.name)); dermObj.sentry.sentryBtsClient = new Sentry.BrowserClient({ dsn: "https://bb80ec4e4a764eed95a8d8582c57f6d6@o220176.ingest.sentry.io/1771446", tracesSampleRate: sampleRate, autoSessionTracking: false, transport: Sentry.makeFetchTransport, integrations: filteredIntegrations, beforeSend(event) { // Check if the error has a custom tag 'manualReport' if (event.tags && event.tags.customManualReport) { // If the tag is present, allow the error to be reported return event; } // If the tag is not present, ignore the error return null; } }); dermObj.sentry.sentryBtsHub = new Sentry.Hub(dermObj.sentry.sentryBtsClient); dermObj.sentry.loaded = true; dermObj.sentry.pending = false; }; script.onerror = function(err){ console.error(err) } script.setAttribute('type','text/javascript'); //script.integrity="sha384-5Zu44WQLIjQtAmHoeW6zq6diH9kymV7kGUaYAV1PK5LPCSGURU7y840OHlpaU8NQ" script.src = "https://browser.sentry-cdn.com/7.60.0/bundle.min.js" // error bundle only dermObj.widget_wrapper.appendChild(script); } dermObj.sentry.triggerTestError = ()=>{ try{ triggerTestDueUndefinedFunction(); }catch(err){ const extraContext = { 'function_info':{ 'file':'sentry.ejs', 'function':'triggerTestError', 'context': 'test error to manual trigger a test message' } } dermObj.sentry.errorWrapper(err, extraContext); } }; dermObj.sentry.errorWrapper = function(err, extraContext = {}){ if (dermObj.sentry.loaded === false && dermObj.sentry.pending === false) { console.error(err); return; }; if (dermObj.sentry.loaded === false && dermObj.sentry.pending === true){ setTimeout(()=>{ dermObj.sentry.errorWrapper(err,extraContext); },500) return; } console.error(err); try{ dermObj.sentry.sentryBtsHub.withScope((scope)=>{ scope.setTag('customManualReport',true); scope.setContext("browser_data", { userAgent: navigator.userAgent, url: window.location.href, }); try{ if ( Object.keys(extraContext).length > 0 ){ Object.keys(extraContext).forEach((contextName)=>{ scope.setContext(contextName, extraContext[contextName]); }) } }catch(err){} dermObj.sentry.sentryBtsHub.captureException(err); }) }catch(err){} } dermObj.processImage = async (base64image) => { return new Promise( async (resolve , reject)=>{ if (dermObj.imageUploadPending){ reject({status: 'failure', message: 'image upload pending'}) return; } dermObj.imageUploadPending = true; try{ const analyzeRes = await dermObj.uploadImage(base64image); dermObj.imageUploadPending = false; resolve(analyzeRes); }catch(err){ dermObj.imageUploadPending = false; reject(err); } }) } dermObj.uploadImage = async (base64image) => { return new Promise( async (resolve, reject) => { dermObj.analyzeRequestStatus = 'pending'; const xhr = new XMLHttpRequest(); dermObj.sendGA360("main flow","upload image submit"); dermObj.sendGAFlowEvent("upload image submit"); xhr.upload.onload = () => { console.log(`Upload completed - ${xhr.status} - ${xhr.response}`); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('imupld')) { urlObj.searchParams.set('imupld', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } //resolve(xhr.response); } xhr.upload.onerror = () => { console.error('Upload failed - ',xhr); dermObj.analyzeRequestStatus = 'failed'; //reject("error") resolve({status: 'failed'}) } xhr.upload.onabort = () => { console.error('Upload aborted - ',xhr); dermObj.analyzeRequestStatus = 'failed'; reject("abort") } xhr.upload.onprogress = (event) => { console.log(`Uploaded ${event.loaded} of ${event.total} bytes`); } xhr.onload = async () => { //console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); dermObj.analyzeRequestStatus = 'finished'; const parsedResponse = JSON.parse(xhr.response); dermObj.debug('Backend Response: ', parsedResponse); if (parsedResponse.revieve_response == undefined || parsedResponse.revieve_response == null){ if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } dermObj.dioxide_data= null; resolve(parsedResponse); } xhr.onerror = () => { console.error('Upload failed - ',xhr); dermObj.analyzeRequestStatus = 'failed'; reject("error") } const payload = {}; payload.imageBase64 = base64image; try{ payload.ldTms = {...dermObj.ldTms}; }catch(err){ console.warn(err); } let referrerUrl = dermObj.referrer if (dermObj.config.useAgGeFaceApiFeature === true){ try{ dermObj.pageControls.capture.ed6d4 = dermObj.capture.ed6d4; dermObj.pageControls.capture.b83d2 = dermObj.capture.b83d2; }catch(err){ console.log(error) } } try{ payload.ed6d4 = dermObj.pageControls.capture.ed6d4; payload.b83d2 = dermObj.pageControls.capture.b83d2; }catch(err){ console.log(error) } payload.referrer = referrerUrl; payload.browser = navigator.userAgent.slice(0,30); const langCodeToSend = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; payload.lang_code = langCodeToSend; payload.auto_capture = true; payload.os = 'os dummy value'; payload.dark_circles_score = dermObj.masks.darkCirclesScore; payload.dehydration_score = 2; if (dermObj.klaviyo.id != ''){ payload.learnq_id = dermObj.klaviyo.id; } if (dermObj.config.userImgOnly){ payload.s_i = false; } await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ if (window.localStorage.getItem("dmlcid") != null){ try{ dermObj.customUID = Number(window.localStorage.getItem("dmlcid")); }catch(err){ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); } payload.custom_uid = dermObj.customUID; xhr.open('POST', `${dermObj.backend}/fmc/analyze-v3?new_json=1&lang_code=${langCodeToSend}&custom_uid=${dermObj.customUID}`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }) } dermObj.sendNoImageQuizResults = async (quizResults, revVals = {})=>{ return new Promise( async (resolve, reject) => { const xhr = new XMLHttpRequest(); dermObj.sendGA360("main flow","send no image quiz results"); dermObj.sendGAFlowEvent("send no image quiz results"); xhr.onload = async () => { //console.log(xhr.response) console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); const parsedResponse = JSON.parse(xhr.response); dermObj.debug('Backend Response: ', parsedResponse); resolve(parsedResponse); } xhr.onerror = () => { console.error('Upload failed - ',xhr); reject("error") } const payload = {}; let referrerUrl= dermObj.referrer; payload.host_site = referrerUrl; payload.browser = navigator.userAgent.slice(0,30); payload.lang_code = dermObj.lang_code; payload.quiz_results = dml_dmlqz.surveyResults; payload.mapped_revieve_vals = revVals; await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ if (window.localStorage.getItem("dmlcid") != null){ try{ dermObj.customUID = Number(window.localStorage.getItem("dmlcid")); }catch(err){ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); window.localStorage.setItem("dmlcid",dermObj.customUID); } }else{ dermObj.customUID = Date.now() + Math.round(Math.random()*100000); } payload.custom_uid = dermObj.customUID; xhr.open('POST', `${dermObj.backend}/fmc/fmc_quiz_products`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }) } dermObj.getFormerfmcResult = async(hashId, useLegacyBe = false)=>{ return new Promise( async(resolve, reject)=>{ if (dermObj.config.use2FA && dermObj.twofa.code == ''){ await dermObj.twofa.prompt(); } let backendLabel = "us"; if (window.location.search.indexOf("be=") > - 1){ backendLabel = window.location.search.split("be=")[1].split("&")[0]; }else{ backendLabel = dermObj.getBackendLabel(); } let urlParamString = ''; if (dermObj.twofa.code != ''){ urlParamString = `?access_code=${dermObj.twofa.code}`; } dermObj.twofa.code != ''; const xhr = new XMLHttpRequest(); xhr.open('GET', `${dermObj.backend}/fmc/get-skin-io/${hashId}${urlParamString}`,true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.onload = async () => { //console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); let rawResponseData; try{ rawResponseData = JSON.parse(xhr.response); delete rawResponseData.concerns; delete rawResponseData.cropped_image; delete rawResponseData.skin_io_response; delete rawResponseData.skin_io_response_time; delete rawResponseData.recommendedProducts; delete rawResponseData.product_ids; }catch(err){ console.error(err); reject(err); return } if (rawResponseData.status == '400' || rawResponseData.status == 400 || rawResponseData.status == '404' || rawResponseData.status == 404){ if (rawResponseData.message.indexOf('Please supply the correct access code') > -1){ console.error(rawResponseData.message); reject(rawResponseData.message); } } if (rawResponseData.status == '500' || rawResponseData.status == 500 ){ console.error(rawResponseData.message); reject(rawResponseData.message); } if (rawResponseData.success == false){ if (!useLegacyBe){ rawResponseData = await dermObj.getFormerfmcResult(hashId, true); if (rawResponseData.status == 'failure'){ reject(rawResponseData); } }else{ resolve({status:'failure',reason:'id not found'}); } } let refinedResponseData; try{ refinedResponseData = await dermObj.refineData(rawResponseData); }catch(err){ console.error(err); reject(err); } if (refinedResponseData.dioxide_data != undefined && refinedResponseData.dioxide_data != null && window.location.search.indexOf('qni=1') < 0 ){ try{ const refinedDioxideData = await dermObj.refineAndCleanDioxideData(refinedResponseData.dioxide_data) refinedResponseData.dioxide_data = refinedDioxideData; }catch(err){ console.error('error in refining backend dioxide data - ',err); } } resolve(refinedResponseData); } xhr.onerror = (err) =>{ console.error(err); reject(err); } xhr.send(); }) } dermObj.refineData = async (rawData)=>{ const refinedData = {... rawData}; dermObj.rawData = rawData; //console.log(rawData) try{ refinedData.azure_age = Number(refinedData.azure_age); }catch(err){ refinedData.azure_age = null; } if (typeof refinedData.azure_response == 'string'){ refinedData.azure_response = JSON.parse(refinedData.azure_response.replace(/\'/g,'"').replace(/True/g,'true').replace(/False/g,'false')) } if (typeof refinedData.revieve_response == 'string'){ refinedData.revieve_response = JSON.parse(refinedData.revieve_response.replace(/w\'s/g,'w_s').replace(/\'/g,'"').replace(/True/g,'true').replace(/False/g,'false').replace(/None/g,'null')) } Object.keys(refinedData).forEach((key)=>{ if (key.indexOf('revieve_') > -1 && key.indexOf('_value') > -1){ refinedData[key] = refinedData[key] === null ? null : Number(refinedData[key]); } }); return refinedData; } dermObj.submitEmail = async ()=>{ if (dermObj.submitEmailPending){ return; } dermObj.submitEmailPending = true; setTimeout(()=>{ dermObj.submitEmailPending = false; },500) const usrEmail = document.getElementById('fmc_email_popup_input').value; const emailValid = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/.test(usrEmail) if (emailValid){ dermObj.submitEmailToBackend(); document.getElementById("fmc_email_popup_hint").style.opacity = 0; document.getElementById("fmc_email_popup").style.display = 'none'; try{ const fmcSnapShot = await dermObj.getRevSnapShot(dermObj.backendData); dermObj.addUrlParameters(fmcSnapShot); await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ dermObj.updateLocalStorage(fmcSnapShot); } }catch(err){ console.error(err) } dermObj.gotoPage('results'); }else{ document.getElementById("fmc_email_popup_hint").style.opacity = 1; } } dermObj.submitEmailToBackend = async () => { let subscribeChecked = false; if (dermObj.config.emailDoubleCheckbox == true){ subscribeChecked = dermObj.body.querySelector('#fmc_email_checkbox_gdpr1').checked; }else{ subscribeChecked = document.getElementById("fmc_email_checkbox").checked; } //if (dermObj.lang_code == 'en-US' || dermObj.lang_code == 'en-GB' || dermObj.lang_code == 'en-NZ' || dermObj.countryCode == 'US'){ //if ( ['en-US', 'en-GB', 'en-NZ', 'fr', 'ja-np'].includes(dermObj.lang_code) || dermObj.countryCode == 'US'){ if (dermObj.config.pageDict.results == 'fmc_results_prep_treat_glow'){ dermObj.debug('SEND PREP TREAT GLOW EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "prep_treat_glow" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "prep_treat_glow", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_estimated_results'){ dermObj.debug('SEND ESTIMATED RESULTS WITH PREP TREAT GLOW EMAIL TEMPLATE'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "estimated_results" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "estimated_results", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_results_brand_campaign'){ dermObj.debug('BRAND CAMPAIGN EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "brand_campaign" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "brand_campaign", true ); }catch(err){ console.warn(err); } } }else if (dermObj.config.pageDict.results == 'fmc_results_quiz_no_image'){ dermObj.debug('QUIZ NO IMAGE EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "quiz_no_image" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "quiz_no_image", true ); }catch(err){ console.warn(err); } } }else{ dermObj.debug('DEFAULT EMAIL'); try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "results_default" ); }catch(err){ console.warn(err); } if (dermObj.config.sendAlsoToNewEmailEndpoint === true){ try{ dermObj.email.send(document.getElementById('fmc_email_input').value, subscribeChecked, "results_default", true ); }catch(err){ console.warn(err); } } } } dermObj.getBackendLabel = ()=>{ let backendLabel; switch(dermObj.backend){ case "https://global.facemapping.me": backendLabel = "us_v2"; break; case "https://staging.facemapping.me": backendLabel = "stg_v2"; break; case "https://eu.facemapping.me": backendLabel = "eu_v2"; break; case "https://ca.facemapping.me": backendLabel = "ca_v2"; break; case "https://fmc-backend-staging.herokuapp.com": backendLabel = "stg"; break; case "https://imb-backend-eu.herokuapp.com": backendLabel = "eu"; break; case "https://imb-backend-ca.herokuapp.com": backendLabel = "ca"; break; default: backendLabel = "us" } return backendLabel; } dermObj.backendUrlFromLabel = (backendLabel)=>{ let backendUrl; switch(backendLabel){ case "us_v2": backendUrl = "https://global.facemapping.me"; break; case "stg_v2": backendUrl = "https://staging.facemapping.me"; break; case "eu_v2": backendUrl = "https://eu.facemapping.me"; break; case "ca_v2": backendUrl = "https://ca.facemapping.me"; break; case "stg": backendUrl = "https://fmc-backend-staging.herokuapp.com"; break; case "eu": backendUrl = "https://imb-backend-eu.herokuapp.com"; break; case "ca": backendUrl = "https://imb-backend-ca.herokuapp.com"; break; default: backendUrl = "https://fmc-backend-production.herokuapp.com" } return backendUrl; } dermObj.email = {}; dermObj.email.send = async (email, emailConsent, emailType = "results_default", useNewEndpoint = false) => { return new Promise( async (resolve, reject) => { let createdKlavPro = false; if (emailConsent == true && dermObj.config.klavyioId != '' && dermObj.config.klavyioId != undefined && dermObj.config.klavyioListId != '' && dermObj.config.klavyioListId != undefined ){ try{ let prep_prod; let treat_prod; let glow_prod; try{ prep_prod = dermObj.dioxideData.prep_treat_glow.prep.name_original }catch(errInner){} try{ treat_prod = dermObj.dioxideData.prep_treat_glow.treat.name_original }catch(errInner){} try{ glow_prod = dermObj.dioxideData.prep_treat_glow.glow.name_original }catch(errInner){} await fetch(`https://a.klaviyo.com/client/profiles/?company_id=${dermObj.config.klavyioId}`,{ method: 'POST', headers: {revision: '2023-08-15', 'content-type': 'application/json'}, body: JSON.stringify({ data: { type: 'profile', attributes: { email: email, properties: { FMC: "yes", FMC_created_at: Date.now(), FMC_uid: dermObj.backendData.hashid, FMC_prep: prep_prod, FMC_treat: treat_prod, FMC_glow: glow_prod } } } }) }) await fetch(`https://a.klaviyo.com/client/subscriptions/?company_id=${dermObj.config.klavyioId}`,{ method: 'POST', headers: {revision: '2023-08-15', 'content-type': 'application/json'}, body: JSON.stringify({ data: { type: 'subscription', attributes: { custom_source: 'FMC email form', profile: { data: { type: 'profile', attributes: { email: email } } } }, relationships: {list: {data: {type: 'list', id: dermObj.config.klavyioListId}}} } }) }) createdKlavPro = true; }catch(err){ console.error(err) } } const xhr = new XMLHttpRequest(); xhr.upload.onload = () => { console.log(`Upload completed - ${xhr.status} - ${xhr.response}`); //resolve(xhr.response); } xhr.upload.onerror = () => { console.error('Upload failed - ',xhr); reject("error") } xhr.upload.onabort = () => { console.error('Upload aborted - ',xhr); reject("abort") } xhr.upload.onprogress = (event) => { console.log(`Uploaded ${event.loaded} of ${event.total} bytes`); } xhr.onload = () => { console.log(`Request completed - ${xhr.status} - ${JSON.parse(xhr.response)}`); resolve(JSON.parse(xhr.response)); if (emailConsent && dermObj.config.crm.enabled == true) { dermObj.crm.send(emailType, email); } } const payload = { ed6d4: null, b83d2: null }; payload.upo = createdKlavPro; let fmcResultsUrl; const connectionChar = window.location.search == '' ? '?' : '&' if (window.location.search.indexOf('fmhid') == -1){ let backendLabel = dermObj.getBackendLabel(); fmcResultsUrl = `${window.location.href}${connectionChar}fmhid=${dml_fmc.backendData.hashid}&be=${backendLabel}`; }else{ fmcResultsUrl = `${window.location.href}`; } payload.email = email; payload.email_consent = emailConsent; payload.hashid = dermObj.backendData.hashid; try{ if (dermObj.backendData.ed6d4 != undefined && dermObj.backendData.ed6d4 != null){ payload.ed6d4 = dermObj.backendData.ed6d4; }else if(dermObj.pageControls.capture.ed6d4 != undefined && dermObj.pageControls.capture.ed6d4 != null){ payload.ed6d4 = dermObj.pageControls.capture.ed6d4; }else if(location.search.indexOf('ed6d4=') > -1){ const agIdx = Number(location.search.split('ed6d4=')[1].split('&')[0]); payload.ed6d4 = [17, 22,30,40,50, 60, 70][agIdx]; } }catch(err){ console.warn('error in adding ag to payload',err); } try{ if (dermObj.backendData.b83d2 != undefined && dermObj.backendData.b83d2 != null){ payload.b83d2 = dermObj.backendData.b83d2; }else if(dermObj.pageControls.capture.b83d2 != undefined && dermObj.pageControls.capture.b83d2 != null){ payload.b83d2 = dermObj.pageControls.capture.b83d2; }else if(location.search.indexOf('b83d2=') > -1){ payload.b83d2 = Number(location.search.split('b83d2=')[1].split('&')[0]); } }catch(err){ console.warn('error in adding ge to payload',err); } try{ payload.referrer = dermObj.referrer; }catch(err){console.error(err)} try{ payload.maxmind_country = dml_fmc.backendData.maxmind_country; }catch(err){console.error(err)} const subscribeValue = emailConsent ? "1" : "0"; payload.subscribe = subscribeValue; try{ payload.revieveData = Object.keys(dermObj.backendData) .filter(key => {return key.startsWith('revieve_') && key != 'revieve_response'}) .reduce((obj, key) => { return { ...obj, [key]: dermObj.backendData[key] }; }, {}); }catch(err){ console.error('error in extracting revieve values - ',err) } delete payload.revieveData.revieve_response_time; if (dermObj.config.use2FA){ if(dermObj.backendData.access_code != null && dermObj.backendData.access_code != undefined){ payload.access_code = { code: dermObj.backendData.access_code, copy: dermObj.textData['2fa'].email_code_copy } } } if (emailType == "prep_treat_glow"){ if (dermObj.backendData.dioxide_data.prep_treat_glow == null || dermObj.backendData.dioxide_data.prep_treat_glow == undefined){ emailType = "results_default"; } } if (emailType == "brand_campaign"){ if (dermObj.backendData.dioxide_data.brand_campaign == null || dermObj.backendData.dioxide_data.brand_campaign == undefined){ emailType = "results_default"; } } if (emailType == "estimated_results"){ try{ const estimatedDioxRes = await dermObj.getEstimatedDioxideRecommendations(); dermObj.dioxideData.prep_treat_glow = estimatedDioxRes.prep_treat_glow; }catch(err){ console.error('error in sending email at estr - ',err); return; } } if (emailType == "results_default"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-94218a74bc19433ea9ba731a56bf9399"; const shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; payload.intro = { "title": dermObj.textData['email_results_default'].email_results_default_intro_title, "content": dermObj.textData['email_results_default'].email_results_default_intro_content } let switchFirstTwoProducts = false; let highestConcern = dml_fmc.dioxideData.sortedConcerns[0].concern_key; if (highestConcern == "dehydration"){ switchFirstTwoProducts = true; highestConcern = dml_fmc.dioxideData.sortedConcerns[1].concern_key; } payload.concern = { "intro": dermObj.textData['email_results_default'].email_results_default_intro_concern_intro, "name": dermObj.textData['concerns'][highestConcern], "image": dermObj.backendData.cropped_image, "analysisLink": fmcResultsUrl, "analysisLinkCaption": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta } payload.treatments = { "title": dermObj.textData['email_results_default'].email_results_default_treatments_title, "products": [] } let concernProdsToDisplay; if (switchFirstTwoProducts){ concernProdsToDisplay = [dermObj.dioxideData.sortedConcerns[1],dermObj.dioxideData.sortedConcerns[0],dermObj.dioxideData.sortedConcerns[2]]; }else{ concernProdsToDisplay = [dermObj.dioxideData.sortedConcerns[0],dermObj.dioxideData.sortedConcerns[1],dermObj.dioxideData.sortedConcerns[2]]; } concernProdsToDisplay.forEach((concern,index)=>{ if (concern.recommended_product.productUrl.indexOf('fmc_formPostRequest') > -1){ concern.recommended_product.productUrl = concern.recommended_product.productEmailURL; } payload.treatments.products.push({ "concern": dermObj.textData['concerns'][concern.concern_key], "productImage": concern.recommended_product.imageUrl, "productName": concern.recommended_product.name, "productTagline": concern.recommended_product.tagline, "shopLink": concern.recommended_product.productUrl, "shopLinkCaption": shopButtonText, }) }) if (dermObj.dioxideData.recommendedProducts.length == 6){ payload.regimen = { "title": dermObj.textData['email_results_default'].email_results_default_regimen_title, } dermObj.dioxideData.recommendedProducts.forEach((product,index)=>{ if (product.productUrl.indexOf('fmc_formPostRequest') > -1){ product.productUrl = product.productEmailURL; } payload.regimen[`p${product.regimen_index}`]={ "label": `0${product.regimen_index}`, "productImage": product.imageUrl, "productName": product.name, "shopLink": product.productUrl, "shopLinkCaption": shopButtonText } }) } const emailFooter = []; if (dermObj.siteLinks.contact_us_url != undefined && dermObj.siteLinks.contact_us_url != null && dermObj.siteLinks.contact_us_url != ''){ if (dermObj.config.hideContactBanners != true){ payload.chat = { "lead": dermObj.textData['email_results_default'].email_results_default_PST_footer_header, "title": dermObj.textData['email_results_default'].email_results_default_PST_footer_tagline, "chatLink": dermObj.siteLinks.contact_us_url, "chatLinkCaption": dermObj.textData['email_results_default'].email_results_default_PST_footer_cta } emailFooter.push({ "footerLink": dermObj.siteLinks.contact_us_url, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_contact }) } } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ emailFooter.push({ "footerLink": dermObj.siteLinks.privacy_policy, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ emailFooter.push({ "footerLink": typeof dermObj.siteLinks.copyright, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_copyright }) } if (emailFooter.length > 0){ payload.footer = emailFooter; } } if (emailType == "prep_treat_glow" || emailType == "estimated_results" || emailType == "quiz_no_image"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-94218a74bc19433ea9ba731a56bf9399"; let onlyNewUserKit = false; if (dermObj.config.useNewUserKits == true && dermObj.dioxideData.prep_treat_glow.kit_nu != undefined){ onlyNewUserKit = true; } let shopButtonText; if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].add_to_bag; }else{ shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; } payload.intro = { "title": dermObj.textData['email_results_default'].email_results_default_intro_title, "content": dermObj.textData['email_results_default'].email_results_default_intro_content } let switchFirstTwoProducts = false; let highestConcern = ''; try{ if (dermObj.pageControls.prep_treat_glow.concernOrder.length == 0){ let concernOrder = dermObj.dioxideData.sortedConcerns.map((concern) => {return concern.concern_key}); highestConcern = concernOrder[0]; if (highestConcern == 'dehydration'){ highestConcern = concernOrder[1]; } }else{ highestConcern = dermObj.pageControls.prep_treat_glow.concernOrder[0]; } }catch(err){} payload.concern = { "intro": dermObj.textData['email_results_default'].email_results_default_intro_concern_intro, "name": dermObj.textData['concerns'][highestConcern], "image": dermObj.backendData.original_image, "analysisLink": fmcResultsUrl, "analysisLinkCaption": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta } if (emailType == "prep_treat_glow"){ if (payload.concern.analysisLink.indexOf('rspg=prep_treat_glow') < 0){ payload.concern.analysisLink += '&rspg=prep_treat_glow'; } } if (emailType == "quiz_no_image"){ payload.concern = null; } if (emailType == "estimated_results"){ payload.concern.image = 'http://facemapping.me/img/landing/fmc_landing_page_desktop.jpg'; payload.concern.intro= ''; payload.concern.name=''; if (payload.concern.analysisLink.indexOf('rspg=estr') < 0){ payload.concern.analysisLink += '&rspg=estr'; } } payload.treatments = { "title": dermObj.textData['exact_phrases'].we_recommend, "products": [] } const prepProd = dml_fmc.dioxideData.prep_treat_glow.prep; const treatProd = dml_fmc.dioxideData.prep_treat_glow.treat; const glowProd = dml_fmc.dioxideData.prep_treat_glow.glow; if (prepProd.productUrl.indexOf('fmc_formPostRequest') > -1){ prepProd.productUrl = prepProd.productEmailURL; } if (treatProd.productUrl.indexOf('fmc_formPostRequest') > -1){ treatProd.productUrl = treatProd.productEmailURL; } if (glowProd.productUrl.indexOf('fmc_formPostRequest') > -1){ glowProd.productUrl = glowProd.productEmailURL; } if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ try{ let urlObj = new URL(prepProd.productUrl); let cartUrl = urlObj.protocol + "//" + urlObj.hostname + '/cart/add'; try{ prepProd.productUrl = `${cartUrl}?id=${prepProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } try{ treatProd.productUrl = `${cartUrl}?id=${treatProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } try{ glowProd.productUrl = `${cartUrl}?id=${glowProd.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } }catch(errInUrl){ console.log(`Error in new URL() - ${prepProd.productUrl}`, errInUrl) } } payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].prep, "productImage": prepProd.imageUrl, "productName": prepProd.name, "productTagline": prepProd.tagline, "shopLink": prepProd.productUrl, "shopLinkCaption": shopButtonText, }) payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].treat, "productImage": treatProd.imageUrl, "productName": treatProd.name, "productTagline": treatProd.tagline, "shopLink": treatProd.productUrl, "shopLinkCaption": shopButtonText, }) payload.treatments.products.push({ "concern": dermObj.textData['exact_phrases'].glow, "productImage": glowProd.imageUrl, "productName": glowProd.name, "productTagline": glowProd.tagline, "shopLink": glowProd.productUrl, "shopLinkCaption": shopButtonText, }) if (emailType == "quiz_no_image" && dermObj.pageControls.quiz_no_image_results.isUnsureSkin == true){ const discoverSkinKit = dml_fmc.productData['22900']; if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ try{ let urlObj = new URL(discoverSkinKit.productUrl); let cartUrl = urlObj.protocol + "//" + urlObj.hostname + '/cart/add'; try{ discoverSkinKit.productUrl = `${cartUrl}?id=${discoverSkinKit.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } }catch(errInUrl){ console.log(`Error in new URL() - ${discoverSkinKit.productUrl}`, errInUrl) } } payload.treatments.products =[{ "productImage": discoverSkinKit.imageUrl, "productName": discoverSkinKit.name, "productTagline": discoverSkinKit.tagline, "shopLink": discoverSkinKit.productUrl, "shopLinkCaption": shopButtonText }] } if (onlyNewUserKit == true){ payload.concern = null; const newUserKit = dermObj.dioxideData.prep_treat_glow.kit_nu; if ("TRUE" == 'TRUE' && dermObj.config.useShopify == true){ try{ let urlObj = new URL(newUserKit.productUrl); let cartUrl = urlObj.protocol + "//" + urlObj.hostname + '/cart/add'; try{ newUserKit.productUrl = `${cartUrl}?id=${newUserKit.variants.filter((varobj)=>{return varobj.default})[0].shopify_variant_id}&quantity=1`; }catch(err){ console.error(err) } }catch(errInUrl){ console.log(`Error in new URL() - ${newUserKit.productUrl}`, errInUrl) } } payload.treatments.products =[{ "productImage": newUserKit.imageUrl, "productName": newUserKit.name, "productTagline": newUserKit.tagline, "shopLink": newUserKit.productUrl, "shopLinkCaption": shopButtonText }] } if (dermObj.config.useTreatmentBanners == true && dermObj.countryCode == 'US' ){ try{ let skin_service_list; if (dermObj.dioxideData.skin_services == undefined){ dermObj.dioxideData.skin_services = [ {...dermObj.dioxideData.skin_service}] } skin_service_list = dermObj.dioxideData.skin_services; let skin_service_payload = { "header": dermObj.textData.email_skin_service.email_skin_service_header, "subtitle": dermObj.textData.email_skin_service.email_skin_service_subtitle, "services": [] }; skin_service_list.forEach(skin_service => { if (skin_service.name != undefined && skin_service.name != '' && skin_service.image2_url != undefined && skin_service.image2_url != '' && skin_service.booking_id != undefined && skin_service.booking_id != '' ){ skin_service_payload.services.push({ "name": skin_service.name, "image_url": skin_service.image2_url, "description": skin_service.description != undefined ? skin_service.description : '' , "link": `${dermObj.treatments.bookNowUrl}?code=${skin_service.booking_id}&fmc_eml=1`, //"link": "https://www.dermalogica.com/pages/store-locator", "cta": dermObj.textData.exact_phrases.book_now }) } }) if (skin_service_payload.services.length > 1){ skin_service_payload.subtitle = dermObj.textData.email_skin_service.email_skin_services_subtitle } if (skin_service_payload.services.length > 0) { payload.skin_services = {...skin_service_payload} } }catch(err){ console.error(err) } } const emailFooter = []; if (typeof dermObj.siteLinks.contact_us_url != 'undefined' && dermObj.siteLinks.contact_us_url != ''){ if (dermObj.config.hideContactBanners != true){ payload.chat = { "lead": dermObj.textData['email_results_default'].email_results_default_PST_footer_header, "title": dermObj.textData['email_results_default'].email_results_default_PST_footer_tagline, "chatLink": dermObj.siteLinks.contact_us_url, "chatLinkCaption": dermObj.textData['email_results_default'].email_results_default_PST_footer_cta } emailFooter.push({ "footerLink": dermObj.siteLinks.contact_us_url, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_contact }) } } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ emailFooter.push({ "footerLink": dermObj.siteLinks.privacy_policy, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ emailFooter.push({ "footerLink": typeof dermObj.siteLinks.copyright, "footerLinkCaption": dermObj.textData["email_footer_links"].email_footer_copyright }) } if (emailFooter.length > 0){ payload.footer = emailFooter; } } if (emailType == "brand_campaign"){ if (dermObj.config.emailSubjectOverride != ''){ payload.subject = dermObj.config.emailSubjectOverride; }else{ payload.subject = dermObj.textData['email_results_default'].email_results_default_subject; } payload.template_id = "d-582ee0c9b4a24f27b81ac80077fc9570"; const shopButtonText = dermObj.config.shopButton.textOverride != '' ? dermObj.config.shopButton.textOverride : dermObj.textData["product_buttons_labels"].shop; let switchFirstTwoProducts = false; let highestConcern; if (dermObj.pageControls.brand_campaign.concernOrder.length == 0 || true){ const unsortedBrandConcerns = []; const brand_concerns = dermObj.backendData.dioxide_data.brand_campaign; dermObj.backendData.dioxide_data.brand_campaign Object.keys(brand_concerns).forEach((concernKey)=> { brand_concerns[concernKey].name = concernKey; brand_concerns[concernKey].concern_key = concernKey; switch(concernKey){ case "acne": brand_concerns[concernKey].score = dermObj.backendData.revieve_acne_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_circles": brand_concerns[concernKey].score = dermObj.backendData.revieve_eyes_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_spots": brand_concerns[concernKey].score = dermObj.backendData.revieve_dark_spots_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dehydration": brand_concerns[concernKey].score = 0.25; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dull_skin": brand_concerns[concernKey].score = dermObj.backendData.revieve_dull_skin_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "redness": brand_concerns[concernKey].score = dermObj.backendData.revieve_redness_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "wrinkles": brand_concerns[concernKey].score = dermObj.backendData.revieve_wrinkles_value; unsortedBrandConcerns.push(brand_concerns[concernKey]) break; } }) let concernOrder = unsortedBrandConcerns.sort((a,b) => {return b.score - a.score}); highestConcern = concernOrder[0].concern_key; if (highestConcern == 'dehydration'){ highestConcern = concernOrder[1]; } }else{ highestConcern = dermObj.pageControls.brand_campaign.concernOrder[0]; } const product = dermObj.backendData.dioxide_data.brand_campaign[highestConcern].one_product ; let kit = dermObj.backendData.dioxide_data.brand_campaign[highestConcern].kit; if (Array.isArray(kit)){ kit = kit[0]; } if (window.location.search.indexOf('rspg=brand_campaign') < 0){ fmcResultsUrl += '&rspg=brand_campaign'; } payload.concern = { "top_concern_header": dermObj.textData['email_results_default'].brand_campaign_my_top_concern_is, "top_concern_title": dermObj.textData['concerns'][highestConcern], "view_result_button": dermObj.textData['email_results_default'].email_results_default_intro_concern_cta, "view_result_url": fmcResultsUrl }; if (dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area == '' || dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area === undefined){ dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area; } if (dermObj.pageControls.brand_campaign.raw_concern_header == '' || dermObj.pageControls.brand_campaign.raw_concern_header === undefined){ dermObj.pageControls.brand_campaign.raw_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header; } if (highestConcern == 'dark_circles'){ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area.replace('__CONCERN__', `${dermObj.textData.concerns.dark_circles}`); payload.concern.top_concern_info += ` ${dermObj.textData.brand_campaign.brand_campaign_results_concern_info_dark_circles}`; }else if (highestConcern == 'acne'){ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns.acne_alternative}`); payload.concern.top_concern_info += ` ${dermObj.textData.brand_campaign.brand_campaign_results_concern_info_breakouts}`; }else{ payload.concern.top_concern_info = dermObj.pageControls.brand_campaign.raw_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns[highestConcern]}`); const infoCopy = dermObj.textData.brand_campaign[`brand_campaign_results_concern_info_${highestConcern}`]; payload.concern.top_concern_info += ` ${infoCopy}`; } payload.product_card = { "product_header": dermObj.textData.brand_campaign.brand_campaign_single_product_header, "product_name" : product.name, "product_info": product.mediumDescription, "product_image_url": product.imageUrl, "product_button": dml_fmc.textData.product_buttons_labels.shop } if (product.productUrl.indexOf('fmc_formPostRequest') > -1){ payload.product_card.product_url = product.productEmailURL }else{ payload.product_card.product_url = product.productUrl; } payload.kit_card = { "kit_header": dermObj.textData.brand_campaign.brand_campaign_kit_product_header, "kit_name": kit.name, "kit_info": kit.mediumDescription, "kit_image_url": kit.imageUrl, "kit_button": dml_fmc.textData.product_buttons_labels.shop } if (kit.productUrl.indexOf('fmc_formPostRequest') > -1){ payload.kit_card.product_url = kit.productEmailURL }else{ payload.kit_card.product_url = kit.productUrl; } if (dermObj.pageControls.brand_campaign.proBrightLink != ''){ payload.treatments = { "treatment_header": dermObj.textData.brand_campaign.brand_campaign_treatment_header, "treatment_title": dermObj.textData.treatments.treatment_probright_title, "treatment_image": "https://cdn.mcauto-images-production.sendgrid.net/8c98fb67ef549c42/5e100a03-21f0-471e-bd6e-07a8040c9e45/1200x1112.jpg", "treatment_url": dermObj.pageControls.brand_campaign.proBrightLink, "treatment_info": dermObj.textData.treatments.treatment_probright_desc, "treatment_button": dermObj.textData.exact_phrases.book_now } } const emailFooter = []; payload.footer = { logo_url : window.location.hostname, logo_image_url : "https://cdn.mcauto-images-production.sendgrid.net/8c98fb67ef549c42/f3d3320b-bde9-4a85-93e9-522f0d33b7e2/320x44.png" , links: [] } if (typeof dermObj.siteLinks.contact_us_url != 'undefined' && dermObj.siteLinks.contact_us_url != ''){ if (dermObj.config.hideContactBanners != true){ payload.contact = { "contact_header": `${dermObj.textData.exact_phrases.need_skin_care_advice}?`, "contact_title": `${dermObj.textData.exact_phrases.chat_with_an_expert}`, "contact_button": `${dermObj.textData.exact_phrases.chat_now}`, "contact_link": dermObj.siteLinks.contact_us_url } if (dermObj.contactOpenHours){ payload.contact.contact_open_hour = dermObj.contactOpenHours; // "contact_open_hour": "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)" } payload.footer.links.push({ "link_url": dermObj.siteLinks.contact_us_url, "link_text": dermObj.textData["email_footer_links"].email_footer_contact }) } } if (typeof dermObj.siteLinks.privacy_policy != 'undefined' && dermObj.siteLinks.privacy_policy != ''){ payload.footer.links.push({ "link_url": dermObj.siteLinks.privacy_policy, "link_text": dermObj.textData["email_footer_links"].email_footer_privacy_policy }) } if (typeof dermObj.siteLinks.copyright != 'undefined' && dermObj.siteLinks.copyright != ''){ payload.footer.links.push({ "link_url": typeof dermObj.siteLinks.copyright, "link_text": dermObj.textData["email_footer_links"].email_footer_copyright }) } } if (useNewEndpoint === true){ if ("https://global.facemapping.me" != ''){ try{ xhr.open('POST', "https://global.facemapping.me/fmc/send-sendgrid-crm",true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); }catch(err){ console.error(err); } }else{ reject('no NEW_EMAIL_URL'); } }else{ xhr.open('POST', `${dermObj.backend}/fmc/send-sendgrid-email`,true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.send(JSON.stringify(payload)); } }) } dermObj.getDioxideRecommendations = async (payloadObject)=>{ //dermObj.debug("PAYLOAD OBJECT:", payloadObject); return new Promise((resolve,reject)=>{ let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxideEndpoint + "/recommendations/get_recommended_products/", true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.onload = async () => { //dermObj.debug(xhr.responseText) try{ if (String(xhr.status) == "200"){ let parsedResponse; try{ parsedResponse = JSON.parse(xhr.responseText) }catch(err){ console.error(err) parsedResponse = xhr.responseText; } try{ const refinedDioxData = await dermObj.refineAndCleanDioxideData(parsedResponse, payloadObject); resolve(refinedDioxData); }catch(err){ console.error(err); reject('failed to refine and clean dioxide data'); } }else{ if (String(xhr.status) == "500"){ /* reportDioxError({ "title": "ERROR - DIOXIDE STATUS - 500", "value": "Dioxide Payload: "+JSON.stringify(payloadObject), "targetChannel": "dioxide-500-errors" }); */ } reject("Error in dioxide call - status code: " + xhr.status); } }catch(err){ reject(err); } } xhr.send(JSON.stringify(payloadObject)); }) } dermObj.getEstimatedDioxideRecommendations = async ()=>{ return new Promise((resolve,reject)=>{ let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxideEndpoint + "/recommendations/get_estimated_results/", true); xhr.setRequestHeader('Content-Type', 'application/json') //xhr.responseType = 'json'; xhr.onload = async () => { try{ const response = JSON.parse(xhr.responseText) dermObj.debug(response) resolve({prep_treat_glow: response.prep_treat_glow_obj}) }catch(err){ console.error(err); reject(); } } const payload = { country_code : dermObj.countryCode, lang_code : dermObj.lang_code, host_site : dermObj.referrer } xhr.send(JSON.stringify(payload)); }) } dermObj.refineAndCleanDioxideData = async (rawDioxideData, payloadObj = {}) => { return new Promise(async (resolve, reject) => { try{ if (Array.isArray(rawDioxideData.concerns)){ rawDioxideData.concerns.forEach((concern,index)=>{ rawDioxideData.concerns[index].name = concern.concern_key; if (concern.recommended_product != undefined){ if (Array.isArray(concern.recommended_product.priceCurrency)){ rawDioxideData.concerns[index].recommended_product.priceCurrency = concern.recommended_product.priceCurrency[0] } if (Array.isArray(concern.recommended_product.price)){ rawDioxideData.concerns[index].recommended_product.price = concern.recommended_product.price[0] } if (Array.isArray(concern.recommended_product.productUrl)){ rawDioxideData.concerns[index].recommended_product.productUrl = concern.recommended_product.productUrl[0] } let formatedPriceObj = dermObj.priceFormating(rawDioxideData.concerns[index].recommended_product.price,rawDioxideData.concerns[index].recommended_product.priceCurrency); rawDioxideData.concerns[index].recommended_product.priceCurrency = formatedPriceObj.priceCurrency; rawDioxideData.concerns[index].recommended_product.price = formatedPriceObj.price; if (concern.recommended_product.productUrl && concern.recommended_product.productUrl.indexOf('fmc_formPostRequest') > -1){ rawDioxideData.concerns[index].recommended_product.productUrl = concern.recommended_product.productEmailURL; } } }) } if (Array.isArray(rawDioxideData.recommendedProducts)){ rawDioxideData.recommendedProducts.forEach((product,index)=>{ if (Array.isArray(product.priceCurrency)){ rawDioxideData.recommendedProducts[index].priceCurrency = product.priceCurrency[0] } if (Array.isArray(product.price)){ rawDioxideData.recommendedProducts[index].price = product.price[0] } if (Array.isArray(product.productUrl)){ rawDioxideData.recommendedProducts[index].productUrl = product.productUrl[0] } let formatedPriceObj = dermObj.priceFormating(rawDioxideData.recommendedProducts[index].price,rawDioxideData.recommendedProducts[index].priceCurrency); rawDioxideData.recommendedProducts[index].priceCurrency = formatedPriceObj.priceCurrency; rawDioxideData.recommendedProducts[index].price = formatedPriceObj.price; if (product.productUrl && product.productUrl.indexOf('fmc_formPostRequest') > -1){ rawDioxideData.recommendedProducts[index].productUrl = product.productEmailURL; } }) } }catch(err){ reject(err); } dermObj.debug("DIOXIDE before cleaning - ", rawDioxideData) try{ const cleanedResponse = await dermObj.checkDioxideResponse(rawDioxideData, payloadObj) if (rawDioxideData.concerns != undefined){ cleanedResponse.sortedConcerns = []; let curScore = 5; while (curScore > 0){ cleanedResponse.concerns.forEach((concern)=>{ if (concern.score == curScore){ cleanedResponse.sortedConcerns.push(concern); } }) curScore--; } dermObj.debug("DIOXIDE after cleaning - ", cleanedResponse) } resolve(cleanedResponse); }catch(err){ console.error("Error in cleaning dioxide response - ",err); } }) } dermObj.prepareDioxidePayload = (facemapObj, languageCode) => { return new Promise((resolve,reject)=>{ try{ let dioxPayload = { "dehydration_score" : 2, "dark_circles_score" : 1, "redness_score" : 1, "oiliness_score" : 1, "wrinkles_score" : 1, "acne_score" : 1, "azure_age" : 25, "country_code" : "US", "host_site" : "www.dermalogica.com", "lang_code" : "en", "breezometer_air_quality_index" : null, "breezometer_humidity" : null, "revieve_acne_value": 0.2, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_dark_spots_value": null, "revieve_dull_skin_value": null, "revieve_eyes_value": null, "revieve_freckles_value": null, "revieve_hyperpigmentation_value": null, "revieve_makeup_value": null, "revieve_melasma_value": null, "revieve_radiance_value": null, "revieve_redness_value": 0.25, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_skin_shine_value": null, "revieve_smoothness_value": null, "revieve_texture_value": 0.25, // TODO - REMOVE TEMPORARY FALLBACK ONCE HANDLED IN DIOXIDE "revieve_uneven_skin_tone_value": null, "revieve_wrinkles_value": null, } //console.log(dioxPayload, facemapObj) try{ if (dermObj.masks.darkCirclesScore != undefined && dermObj.masks.darkCirclesScore != null ) dioxPayload.dark_circles_score = dermObj.masks.darkCirclesScore; }catch(err){ } // REVIEVE PARAMETERS START if (facemapObj.revieve_acne_value != undefined){ dioxPayload.revieve_acne_value = Number(facemapObj.revieve_acne_value); } if (facemapObj.revieve_dark_spots_value != undefined){ dioxPayload.revieve_dark_spots_value = Number(facemapObj.revieve_dark_spots_value); } if (facemapObj.revieve_dull_skin_value != undefined){ dioxPayload.revieve_dull_skin_value = Number(facemapObj.revieve_dull_skin_value); } if (facemapObj.revieve_eyes_value != undefined){ dioxPayload.revieve_eyes_value = Number(facemapObj.revieve_eyes_value); } if (facemapObj.revieve_freckles_value != undefined){ dioxPayload.revieve_freckles_value = Number(facemapObj.revieve_freckles_value); } if (facemapObj.revieve_hyperpigmentation_value != undefined){ dioxPayload.revieve_hyperpigmentation_value = Number(facemapObj.revieve_hyperpigmentation_value); } if (facemapObj.revieve_makeup_value != undefined){ dioxPayload.revieve_makeup_value = Number(facemapObj.revieve_makeup_value); } if (facemapObj.revieve_melasma_value != undefined){ dioxPayload.revieve_melasma_value = Number(facemapObj.revieve_melasma_value); } if (facemapObj.revieve_radiance_value != undefined){ dioxPayload.revieve_radiance_value = Number(facemapObj.revieve_radiance_value); } if (facemapObj.revieve_redness_value != undefined){ dioxPayload.revieve_redness_value = Number(facemapObj.revieve_redness_value); } if (facemapObj.revieve_skin_shine_value != undefined){ dioxPayload.revieve_skin_shine_value = Number(facemapObj.revieve_skin_shine_value); } if (facemapObj.revieve_smoothness_value != undefined){ dioxPayload.revieve_smoothness_value = Number(facemapObj.revieve_smoothness_value); } if (facemapObj.revieve_texture_value != undefined){ dioxPayload.revieve_texture_value = Number(facemapObj.revieve_texture_value); } if (facemapObj.revieve_uneven_skin_tone_value != undefined){ dioxPayload.revieve_uneven_skin_tone_value = Number(facemapObj.revieve_uneven_skin_tone_value); } if (facemapObj.revieve_wrinkles_value != undefined){ dioxPayload.revieve_wrinkles_value = Number(facemapObj.revieve_wrinkles_value); } // REVIEVE PARAMETERS END try{ dioxPayload.azure_age = Number(dermObj.backendData.ed6d4); }catch(err){ console.error(err); } if (facemapObj.country != undefined){ dioxPayload.country_code = facemapObj.country; }else if (facemapObj.maxmind_country != undefined){ dioxPayload.country_code = facemapObj.maxmind_country; } dioxPayload.host_site = dermObj.referrer; if (dermObj.referrer.indexOf("dermalogica-us-staging.myshopify.com") > -1){ dioxPayload.host_site = "www.dermalogica.com/"; } if (dermObj.config.forcedCountry != ""){ dioxPayload.country_code = dermObj.config.forcedCountry; } if (dml_fmc.lang_code != undefined){ dioxPayload.lang_code = dml_fmc.lang_code; if (dioxPayload.lang_code.indexOf('-') > 1){ let langParts = dioxPayload.lang_code.split('-'); try{ dioxPayload.lang_code = `${langParts[0]}-${langParts[1].toUpperCase()}`; }catch(err){} } if (dml_fmc.lang_code == "en"){ if (dioxPayload.country_code != "AU"){ dioxPayload.lang_code += "-US"; } } if (dioxPayload.lang_code.toLowerCase() == 'ja-np'){ dioxPayload.lang_code = 'ja'; } } if (facemapObj.breezometer_air_quality_index != undefined){ dioxPayload.breezometer_air_quality_index = facemapObj.breezometer_air_quality_index; } if (facemapObj.breezometer_humidity != undefined){ dioxPayload.breezometer_humidity = facemapObj.breezometer_humidity; } let isfourfivecluster = false; try{ isfourfivecluster = facemapObj.dioxide_data.prep_treat_glow.ptg_id == 45 }catch(err){ isfourfivecluster = false console.error('ERROR CLUSTER 45 - ', err) } if (dermObj.config.quizAfterImage == true && isfourfivecluster == false){ let quizAnswers = {}; try{ quizAnswers = dermObj.pageControls.qai.answerObj[dermObj.config.pageDict.quiz_after_image]; }catch(err){} try{ if (quizAnswers.looking_for != undefined && quizAnswers.looking_for != null){ dioxPayload.quiz_looking_for = quizAnswers.looking_for; } }catch(err){} try{ if (quizAnswers.dermalogica_familiar != undefined && quizAnswers.dermalogica_familiar != null){ dioxPayload.quiz_dermalogica_familiar = quizAnswers.dermalogica_familiar; } }catch(err){} try{ if (quizAnswers.skin_concern != undefined && quizAnswers.skin_concern != null && quizAnswers.skin_concern != ''){ dioxPayload.quiz_skin_concerns = quizAnswers.skin_concern.split(','); } }catch(err){} } let qaiUrlParam = (new URLSearchParams(window.location.search)).get('qai_an'); if (qaiUrlParam != undefined && qaiUrlParam != null && qaiUrlParam != '' && isfourfivecluster == false){ try{ let lfAns = /QlfA([a-z])/g.exec(qaiUrlParam); if (lfAns != null){ let lfAnswer; switch(lfAns[1]){ case 'b': lfAnswer = 'basic'; break; case 'a': lfAnswer = 'advanced'; break; case 's': lfAnswer = 'skin_concerns'; break; default: lfAnswer = ''; } if (lfAnswer != ''){ dioxPayload.quiz_looking_for = lfAnswer; } } }catch(err){} try{ let dfAns = /QdfA([a-z])/g.exec(qaiUrlParam); if (dfAns != null){ let dfAnswer; switch(dfAns[1]){ case 'n': dfAnswer = 'new_user'; break; case 'u': dfAnswer = 'user_before'; break; case 'g': dfAnswer = 'guru'; break; default: dfAnswer = ''; } if (dfAnswer != ''){ dioxPayload.quiz_dermalogica_familiar = dfAnswer; } } }catch(err){} try{ let scAns = /Qsc([Aa-z]+)/g.exec(qaiUrlParam); if (scAns != null){ let concernSuffixArray = scAns[1].split(/A/g); let concernArray = []; if (concernSuffixArray.includes('br')) concernArray.push('breakouts'); if (concernSuffixArray.includes('dc')) concernArray.push('dark_circles'); if (concernSuffixArray.includes('ust')) concernArray.push('uneven_skin_tone'); if (concernSuffixArray.includes('el')) concernArray.push('elasticity'); if (concernSuffixArray.includes('se')) concernArray.push('sensitivity'); if (concernSuffixArray.includes('de')) concernArray.push('dehydration'); if (concernSuffixArray.includes('wr')) concernArray.push('wrinkles'); dioxPayload.quiz_skin_concerns = String(concernArray); }else{} }catch(err){} if (dioxPayload.quiz_looking_for == 'skin_concerns' && (dioxPayload.quiz_skin_concerns == undefined || dioxPayload.quiz_skin_concerns == null)){ dioxPayload.quiz_looking_for = ''; } } if (dermObj.config.pageDict.results == 'fmc_results_prep_treat_glow'){ dioxPayload.response_details = ["prep_treat_glow","debug"]; } if (dermObj.config.pageDict.results == 'fmc_results_ai_steps'){ dioxPayload.response_details = ["prep_treat_glow","ai_steps", "debug"]; } resolve(dioxPayload); }catch(err){ console.error(err); reject(err); } }) } dermObj.checkDioxideResponse = async (dioxObj, payloadObj) => { return new Promise((resolve,reject)=>{ let outObj = {...dioxObj}; let reducedPayload = { oiliness: payloadObj.oiliness_score, dehydation: payloadObj.dehydration_score, wrinkles: payloadObj.wrinkles_score, acne: payloadObj.acne_score, redness: payloadObj.redness_score, dark_circles: payloadObj.dark_circles_score, age: payloadObj.azure_age, country_code: payloadObj.country_code, host_site: payloadObj.host_site, lang: payloadObj.lang_code } //dermObj.debug("CHECK RESPONSE OBJECT: ",dioxObj); //dermObj.debug("WITH PAYLOAD: ",JSON.stringify(reducedPayload)); let dioxPayloadString = JSON.stringify(reducedPayload).replace(/,/g,"\n").replace("{","").replace("}",""); let missingConcerns = ""; let missingRegimenIndex = ""; if (outObj.concerns == undefined){ dermObj.reportDioxideProblem("MISSING 'concerns' FIELD", dioxPayloadString); }else{ let concernIndicesToRemove = []; let concernList = ["dehydration", "acne", "wrinkles","dark_circles","redness","oiliness"]; outObj.concerns.forEach((concern,index)=>{ concernList = concernList.filter( concernName => concernName != concern.name); let productIsGood = dermObj.checkDioxProductFields(concern,"concern",dioxPayloadString); if (!productIsGood){ concernIndicesToRemove.push(index); } }) if (concernIndicesToRemove.length > 0){ for(let ii = concernIndicesToRemove.length -1; ii > -1; ii--){ outObj.concerns.splice(concernIndicesToRemove[ii],1); } } } if (outObj.recommendedProducts == undefined){ dermObj.reportDioxideProblem("MISSING 'recommendedProducts' FIELD",dioxPayloadString); }else{ let regimenIndexList = [1,2,3,4,5,6]; let regimenIsGood = true; outObj.recommendedProducts.forEach((regimenProduct)=>{ regimenIndexList = regimenIndexList.filter( regimenIndex => regimenIndex != regimenProduct.regimen_index); //dermObj.debug("regimen product before checking - ", regimenProduct); let productIsGood = dermObj.checkDioxProductFields(regimenProduct, "regimen",dioxPayloadString) //dermObj.debug("regimen product is good: ", productIsGood); regimenIsGood = regimenIsGood && productIsGood; }) if (regimenIndexList.length > 0){ missingRegimenIndex = String(regimenIndexList); dermObj.reportDioxideProblem("MISSING REGIMEN INDEX/INDICES: " + missingRegimenIndex,dioxPayloadString); regimenIsGood = false; } if (!regimenIsGood){ outObj.recommendedProducts = []; } } resolve(outObj); }) } dermObj.checkDioxProductFields = (inObj, type, dioxPayloadString)=>{ let productIsGood = true; try{ let recommendedProd; if (type == "concern"){ recommendedProd = inObj.recommended_product; }else{ recommendedProd = inObj; } if (recommendedProd == undefined){ productIsGood = false; if (type=="concern"){ dermObj.reportDioxideProblem("MISSING PRODUCT FOR CONCERN: " + inObj.name,dioxPayloadString); } }else{ if (recommendedProd.pimcore_id == undefined){ dermObj.reportDioxideProblem("PIMCORE ID FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.pimcore_id == 0){ dermObj.reportDioxideProblem("PIMCORE ID IS 0 FOR" + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.name == undefined){ dermObj.reportDioxideProblem("NAME FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; }else if (recommendedProd.name == ""){ dermObj.reportDioxideProblem("NAME IS MISSING EMPTY FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } if (recommendedProd.tagline == undefined){ dermObj.reportDioxideProblem("TAGLINE FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.tagline == ""){ dermObj.reportDioxideProblem("TAGLINE IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.mediumDescription == undefined){ dermObj.reportDioxideProblem("MEDIUM DESCRIPTION FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.mediumDescription == ""){ dermObj.reportDioxideProblem("MEDIUM DESCRIPTION IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.imageUrl == undefined){ dermObj.reportDioxideProblem("IMAGE URL FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.imageUrl == ""){ dermObj.reportDioxideProblem("IMAGE URL IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.productUrl == undefined){ dermObj.reportDioxideProblem("PRODUCT URL FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; }else if (recommendedProd.productUrl == ""){ dermObj.reportDioxideProblem("PRODUCT URL IS MISSING EMPTY FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.price == undefined && dermObj.config.shopButton.showPrices){ dermObj.reportDioxideProblem("PRICE FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (recommendedProd.priceCurrency == undefined && dermObj.config.shopButton.showPrices){ dermObj.reportDioxideProblem("CURRENCY FIELD IS MISSING FOR " + recommendedProd.name,dioxPayloadString); productIsGood = false; } if (type == "regimen"){ if (recommendedProd.regimen_index == undefined){ dermObj.reportDioxideProblem("REGIMEN INDEX FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } if (recommendedProd.regimen_step == undefined){ dermObj.reportDioxideProblem("REGIMEN STEP FIELD IS MISSING FOR " + JSON.stringify(recommendedProd),dioxPayloadString); productIsGood = false; } } } }catch(err){ console.error("Error in checking dioxide product fields" ,err); productIsGood = false; } return productIsGood; } dermObj.reportDioxideProblem = (message,payloadString) => { return; // disabled completely console.warn(message); try{ /* reportDioxError({ "title": "WARN - DIOXIDE RESPONSE ERROR", "value": message + "\n"+payloadString, "color" : "warning" }); */ }catch(err){ console.error(err) } } dermObj.priceFormating = (inPrice,currency)=>{ let formatedPrice; formatedPrice = Number(String(inPrice).replace(/,/g,"")).toFixed(2); let outputFormated = { price: formatedPrice, priceCurrency: currency } if (currency == "¥"){ //dermObj.debug("price conversion yen - A: ",formatedPrice) formatedPrice = String(Number(formatedPrice)); // remove commas //dermObj.debug("price conversion yen - B: ",formatedPrice) let numDots = Math.floor(formatedPrice.length / 3) let curDotPos = (formatedPrice.length) % 3; if (curDotPos == 0){ curDotPos = 3; numDots -= 1; } let outString = ""; let dotCounter =0; for (let ii=0; ii < formatedPrice.length; ii++){ outString += formatedPrice[ii]; if (ii+1 == curDotPos && dotCounter < numDots){ curDotPos += 3; outString += ","; dotCounter++; } } formatedPrice = outString; outputFormated.price = outString; } if (currency == "$MXN"){ outputFormated.priceCurrency = "$"; outputFormated.price = formatedPrice + " MXN"; } return outputFormated; } dermObj.getDioxideLinkData = async (forcedCountryCode = "")=> { return new Promise(async (resolve, reject)=>{ let dioxLinkUrl = `${dermObj.dioxide}/recommendations/get_site_links/`; let payload = { 'country_code' : dermObj.countryCode, 'host_site' : dermObj.config.forcedPage == '' ? window.location.href : dermObj.config.forcedPage } if (forcedCountryCode != ""){ payload.country_code = forcedCountryCode; } let xhr = new XMLHttpRequest(); xhr.open("POST", dioxLinkUrl, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.responseType = 'json'; xhr.onload = async () => { if (xhr.status === 200){ if (xhr.response.status === 200){ resolve(xhr.response.data); }else{ reject({status: xhr.status, response_status: xhr.response.status}); } }else{ reject({status: xhr.status}); } } xhr.onerror =(err)=>{ console.error("dioxide call error - ",err) reject(err); } xhr.onabort = (err)=>{ console.error("dioxide call aborted - ",err) reject(err); } try{ xhr.send(JSON.stringify(payload)); }catch(err){ console.error(err); } }) } dermObj.getAllDioxideProducts = async ()=>{ return new Promise(async (resolve,reject)=>{ try{ const fullCall = await dermObj.dioxideGetAllProducts(); if (fullCall.all_products.length === 0 ){ const countryCall = await dermObj.dioxideGetAllProducts('countryOnly'); if (countryCall.all_products.length === 0 ){ const defaultCall = await dermObj.dioxideGetAllProducts('useDefaultUS'); dermObj.dioxideAllProducts = [...defaultCall.all_products]; resolve(); }else{ dermObj.dioxideAllProducts = [...countryCall.all_products]; resolve(); } }else{ dermObj.dioxideAllProducts = [...fullCall.all_products]; resolve(); } }catch(err){ console.error(err); } }) } dermObj.dioxideGetAllProducts = async (callType = "") => { return new Promise((resolve, reject) => { let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } const country_code = dermObj.countryCode; const host_site = dermObj.referrer; let lang_code = dermObj.config.langForBackends == '' ? dermObj.lang_code : dermObj.config.langForBackends; if (lang_code.toLowerCase() == 'ja-np'){ lang_code='ja'; } const dioxProductsUrl = `${dioxideEndpoint}/recommendations/get_all_products/`; const payload = { country_code, host_site, lang_code } payload.host_site = dermObj.referrer; if (dermObj.referrer.indexOf("dermalogica-us-staging.myshopify.com") > -1){ payload.host_site = "www.dermalogica.com/"; } if (dermObj.config.forcedCountry != ""){ payload.country_code = dermObj.config.forcedCountry; } if (callType == "countryOnly"){ payload.host_site = "facemapping.me" } if (callType == "useDefaultUS"){ payload.host_site = "facemapping.me" payload.country_code = "US" } //dermObj.debug("Dioxide payload: ", payload) let xhr = new XMLHttpRequest(); xhr.open("POST", dioxProductsUrl, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.onload = async () => { if (xhr.status === 200){ resolve(JSON.parse(xhr.response)); }else{ reject({status: xhr.status}); } } xhr.onerror =(err)=>{ console.error("dioxide call error - ",err) reject(err); } xhr.onabort = (err)=>{ console.error("dioxide call aborted - ",err) reject(err); } xhr.send(JSON.stringify(payload)); }) } dermObj.getAllDioxideTranslations = async () => { dermObj.dioxideAllProductTranslations = {} let dioxideEndpoint = dermObj.dioxide; if (dermObj.config.useDioxideStaging){ dioxideEndpoint = "https://dioxide-staging.herokuapp.com"; } let enUsProdTranslations = []; let langSpecTranslations = []; try { const enUsProdTranslationsRequest = await fetch(`${dioxideEndpoint}/product/get_product_translations/en-US`); if (!enUsProdTranslationsRequest.ok) { throw new Error(`HTTP error! Status: ${enUsProdTranslationsRequest.status}`); } enUsProdTranslations = await enUsProdTranslationsRequest.json(); if (dermObj.lang_code != 'en-us'){ let requestLangCode = dermObj.lang_code; const requestLangCodeArr = requestLangCode.split('-'); if (requestLangCodeArr.length > 1){ requestLangCode = `${requestLangCodeArr[0]}-${requestLangCodeArr[1].toUpperCase()}`; } if (requestLangCode.toLowerCase == 'ja-np'){ requestLangCode='ja'; } try { const langProdTranslationsRequest = await fetch(`${dioxideEndpoint}/product/get_product_translations/${requestLangCode}`); if (!langProdTranslationsRequest.ok) { throw new Error(`HTTP error! Status: ${langProdTranslationsRequest.status}`); } langSpecTranslations = await langProdTranslationsRequest.json(); }catch(errInner){ console.error('Fetch error: ', errInner); } } enUsProdTranslations.forEach((prodTrans) => { if (prodTrans.pimcore_id == undefined || prodTrans.pimcore_id == null || prodTrans.pimcore_id == 0) return; dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] = prodTrans; }) langSpecTranslations.forEach((prodTrans) => { if (prodTrans.pimcore_id == undefined || prodTrans.pimcore_id == null || prodTrans.pimcore_id == 0) return; if (dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] != undefined){ Object.keys(prodTrans).forEach((objKey) => { if (prodTrans[objKey] == '') return; dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id][objKey] = prodTrans[objKey]; }) }else{ dermObj.dioxideAllProductTranslations[prodTrans.pimcore_id] = prodTrans; } }) } catch (error) { console.error('Fetch error: ', error); } } dermObj.mergeDioxideAllProdAndTranslations = () => { const missingTranslations = []; const descriptionIsTagline = []; dermObj.dioxideAllProducts.forEach((productData, index) => { const prodPimcoreId = productData.pimcoreId; if (dermObj.dioxideAllProductTranslations[prodPimcoreId] != undefined){ const prodTranslationData = dermObj.dioxideAllProductTranslations[prodPimcoreId]; dermObj.dioxideAllProducts[index].tagline = prodTranslationData.tagline; dermObj.dioxideAllProducts[index].mediumDescription = prodTranslationData.medium_description; /* if (prodTranslationData.tagline == prodTranslationData.medium_description){ dermObj.debug('TAGLINE IS DESCRIPTION') dermObj.debug(prodTranslationData.medium_description, prodTranslationData.tagline) descriptionIsTagline.push({pimcore_id: prodPimcoreId, name: productData.name}); } */ }else{ missingTranslations.push({pimcore_id: prodPimcoreId, name: productData.name}); } }) /* - this is just for debugging and finding not complete products if (missingTranslations.length > 0){ dermObj.debug('TRANSLATIONS MISSING - ',missingTranslations ); } if (descriptionIsTagline.length > 0){ dermObj.debug('Tdescription is tagline - ',descriptionIsTagline ); } */ } dermObj.getDioxideQuizNoImageRecommendation = async (quizResults) => { return new Promise(async (resolve, reject) => { const payload = { "country_code": dermObj.countryCode, "host_site": dermObj.referrer, "lang_code": dermObj.lang_code, "quiz_results": quizResults } try { const xhr = new XMLHttpRequest(); xhr.open('POST',`${dermObj.dioxide}/recommendations/get_fmc_quiz_products/`); xhr.setRequestHeader('Content-type','application/json; charset=utf-8') xhr.responseType = 'json'; xhr.onload = ()=>{ if (xhr.status >= 200 && xhr.status < 300) { dermObj.debug('DIOX QUIZ NO IMAGE RESPONSE - ', xhr.response); resolve(xhr.response) } else { console.error(`HTTP request failed with status ${xhr.status}`); reject(`HTTP request failed with status ${xhr.status}`); } } xhr.send(JSON.stringify(payload)); }catch(err){ console.log(err); reject(err) } }) } dermObj.productData = {}; dermObj.dispProdArr = []; dermObj.recomProdArr = []; dermObj.collectProductData = async ()=>{ const concernProducts = dermObj.dioxideData.sortedConcerns.map((concernObj)=>{return concernObj.recommended_product}); const regimenProducts = [...dermObj.dioxideData.recommendedProducts]; concernProducts.forEach((prod)=>{ dermObj.productData[prod.pimcore_id] = {...prod}; }) regimenProducts.forEach((prod)=>{R if (!dermObj.productData[prod.pimcore_id]){ dermObj.productData[prod.pimcore_id] = {...prod}; } }) return; } dermObj.applyProductData = async (productData) => { Object.keys(productData).forEach((productId)=>{ try{ if (productData[productId].productUrl.indexOf('fmc_formPostRequest') > -1){ productData[productId].productUrl = productData[productId].productEmailURL; } }catch(err){ console.error(err); } }) const productKeys = Object.keys(productData); document.querySelectorAll(`[data-widget-product-exists]`).forEach((productToDisplayElement)=>{ if (!productKeys.includes(productToDisplayElement.dataset.widgetProductExists)){ productToDisplayElement.style.pointerEvents = "none"; productToDisplayElement.style.cursor = "default"; productToDisplayElement.querySelectorAll('*').forEach((childEl)=>{ childEl.style.pointerEvents = "none"; childEl.style.cursor = "default"; childEl.style.opacity = 0; }) } }) document.querySelectorAll(`[data-widget-product-link]`).forEach((productLink)=>{ if (productData[productLink.dataset?.widgetProductLink]?.productUrl){ let variantParameterString = ''; // use default variant price data if variants exist if (productObj.variants != undefined){ const defVariantArray = productObj.variants.filter((variant) => variant.default == true); if (defVariantArray.length > 0){ const defVariant = defVariantArray[0]; try{ if (defVariant.price != undefined && defVariant.price != '' && Number(defVariant.price) != 0 ){ variantParameterString = `?variant=${defVariant.shopify_variant_id}`; } }catch(err){console.error(err)} } } productLink.onclick = ()=>{window.open(productData[productLink.dataset.widgetProductLink].productUrl + variantParameterString,'_blank');} } }) document.querySelectorAll(`[data-widget-product-image]`).forEach((productImage)=>{ if (productData[productImage.dataset?.widgetProductImage]?.imageUrl){ productImage.src = productData[productImage.dataset.widgetProductImage].imageUrl; } }) document.querySelectorAll(`[data-widget-product-background]`).forEach((productImage)=>{ if (productData[productImage.dataset?.widgetProductBackground]?.imageUrl){ productImage.style.backgroundImage = `url('${productData[productImage.dataset.widgetProductBackground].imageUrl}')`; } }) document.querySelectorAll(`[data-widget-product-name]`).forEach((productName)=>{ if (productData[productName.dataset?.widgetProductName]?.name){ productName.innerHTML = productData[productName.dataset.widgetProductName].name; if (dermObj.lang_code == 'ja'){ productName.style.textTransform = 'uppercase'; } } }) document.querySelectorAll(`[data-widget-product-price]`).forEach((productPrice)=>{ if (productData[productPrice.dataset?.widgetProductPrice]?.price){ let prodData = productData[productPrice.dataset.widgetProductPrice]; try{ let prodPrice = Number(prodData.price); if (!Number.isNaN(prodPrice) && prodPrice != 0){ productPrice.innerHTML = dermObj.makePriceString(prodData); } }catch(err){ console.error(err); } } }) document.querySelectorAll(`[data-widget-variant-price]`).forEach((variantPriceEl)=>{ if (productData[variantPriceEl.dataset?.widgetVariantPrice]?.variants){ try{ let prodData = productData[variantPriceEl.dataset.widgetVariantPrice]; //console.log(prodData, prodData.variants); let selectedVariantArray = prodData.variants.filter((variantObj ) => {return variantObj.selected == true}); if (selectedVariantArray.length == 0){ selectedVariantArray = prodData.variants.filter((variantObj ) => {return variantObj.default == true}); } if (selectedVariantArray.length == 0){ console.error('cannot find selected or default variant for ',prodData.name); return; } let selectedVariant = selectedVariantArray[0]; selectedVariant.priceCurrency = prodData.priceCurrency; let prodPrice = Number(selectedVariant.price); if (!Number.isNaN(prodPrice) && prodPrice != 0){ variantPriceEl.innerHTML = dermObj.makePriceString(selectedVariant); } }catch(err){ console.error(err); } } }) document.querySelectorAll(`[data-widget-product-tagline]`).forEach((productTagline)=>{ if (productData[productTagline.dataset?.widgetProductTagline]?.tagline){ productTagline.innerHTML = productData[productTagline.dataset.widgetProductTagline].tagline; } }) document.querySelectorAll(`[data-widget-product-description]`).forEach((productDescription)=>{ if (productData[productDescription.dataset?.widgetProductDescription]?.tagline){ productDescription.innerHTML = productData[productDescription.dataset.widgetProductDescription].mediumDescription; } }) const obsOptions = { root: null, rootMargin: '0px', threshold: 1.0 } dermObj.itemViewObserver = new IntersectionObserver((entries)=>{ entries.forEach((itemView) => { if (itemView.isIntersecting){ //console.log('Item in View - ', itemView); dermObj.itemViewObserver.unobserve(itemView.target) const pimcoreId = itemView.target.dataset.viewItemObserver; //console.log('product data:', dermObj.productData[pimcoreId]); dermObj.pimcoreIdToViewItemEvent(pimcoreId); dermObj.prodDisplayed(pimcoreId); } }); }, obsOptions); document.querySelectorAll(`[data-view-item-observer]`).forEach((observeEl)=>{ dermObj.itemViewObserver.observe(observeEl); }) document.querySelectorAll(`[data-widget-product-buy]`).forEach((productBuyButton)=>{ const pimcoreId = productBuyButton.dataset?.widgetProductBuy; if (pimcoreId){ productBuyButton.addEventListener("click",()=>{ dermObj.sendGA360("main flow",'shop button clicked - pimcore_id - '+ pimcoreId ); dermObj.sendGAFlowEvent('shop button clicked - pimcore_id - '+ pimcoreId ); dermObj.sendGA360("main flow",'shop button clicked'); dermObj.sendGAFlowEvent('shop button clicked'); }) if (!(dermObj.productData[pimcoreId]?.productUrl && dermObj.productData[pimcoreId]?.productUrl.indexOf('https://') > -1)){ console.log("COMING SOON PRODUCT - ", pimcoreId, dermObj.productData[pimcoreId]) productBuyButton.classList.add('dml_is_coming_soon_button'); return; } if (dermObj.config.useShopify){ if (dermObj.productData[pimcoreId].variants && dermObj.productData[pimcoreId].variants.length > 0){ productBuyButton.classList.add('dml_is_add_to_bag_button'); const addToBagClickHandler = async ()=>{ if (!productBuyButton.isPending){ productBuyButton.isPending = true; setTimeout(()=>{ productBuyButton.isPending = false; },500) productBuyButton.classList.add('dml_is_pending') try{ await dermObj.addToBagShopify(productBuyButton); productBuyButton.classList.add('dml_added_to_bag_button'); productBuyButton.classList.remove('dml_is_add_to_bag_button'); productBuyButton.classList.remove('dml_is_pending'); }catch(err){ console.warn(err); productBuyButton.classList.remove('dml_is_add_to_bag_button'); productBuyButton.classList.remove('dml_is_pending'); dermObj.shopButtonClick(productBuyButton); } } } productBuyButton.removeEventListener('click', addToBagClickHandler) productBuyButton.addEventListener('click', addToBagClickHandler) return; }else{ const shopClickHandler = async()=>{ if (!productBuyButton.isPending){ productBuyButton.isPending = true; setTimeout(()=>{ productBuyButton.isPending = false; },500) dermObj.shopButtonClick(productBuyButton); } } productBuyButton.removeEventListener('click',shopClickHandler) productBuyButton.addEventListener('click',shopClickHandler) } }else{ const shopClickHandler = async()=>{ if (!productBuyButton.isPending){ productBuyButton.isPending = true; setTimeout(()=>{ productBuyButton.isPending = false; },500) dermObj.shopButtonClick(productBuyButton); } } productBuyButton.removeEventListener('click',shopClickHandler) productBuyButton.addEventListener('click',shopClickHandler) } } }) try{ if (dermObj.isPercMatchMiniPage == true) return; dermObj.sendDispProds(); }catch(err){ console.error(err); } } dermObj.updateVariantData = async (productData) => { dermObj.body.querySelectorAll(`[data-widget-variant-price]`).forEach((variantPriceEl)=>{ if (productData[variantPriceEl.dataset?.widgetVariantPrice]?.variants){ try{ let prodData = productData[variantPriceEl.dataset.widgetVariantPrice]; //console.log(prodData, prodData.variants); let selectedVariantArray = prodData.variants.filter((variantObj ) => {return variantObj.selected == true}); if (selectedVariantArray.length == 0){ selectedVariantArray = prodData.variants.filter((variantObj ) => {return variantObj.default == true}); } if (selectedVariantArray.length == 0){ console.error('cannot find selected or default variant for ',prodData.name); return; } let selectedVariant = selectedVariantArray[0]; selectedVariant.priceCurrency = prodData.priceCurrency; let prodPrice = Number(selectedVariant.price); if (!Number.isNaN(prodPrice) && prodPrice != 0){ variantPriceEl.innerHTML = dermObj.makePriceString(selectedVariant); } }catch(err){ console.error(err); } } }) } dermObj.shopButtonClick = async (productBuyButton) => { const pimcoreId = productBuyButton.dataset.widgetProductBuy; const productObj = dermObj.productData[pimcoreId]; let variantParameterString = ''; let isValidVariantArray = productObj.variants != undefined; if (isValidVariantArray){ isValidVariantArray = productObj.variants.length > 0; } // use default variant price data if variants exist if (isValidVariantArray){ const defaultVariantObj = productObj.variants.filter((variantData) => {return variantData.default}); const selectedVariantObj = productObj.variants.filter((variantData) => {return variantData.selected}); let variantId; if (selectedVariantObj.length == 1){ variantId = selectedVariantObj[0].shopify_variant_id; }else if (defaultVariantObj.length > 0){ variantId = defaultVariantObj[0].shopify_variant_id; }else{ variantId = dermObj.productData[pimcoreId].variants[0].shopify_variant_id; } try{ variantParameterString = `?variant=${variantId}`; }catch(err){console.error(err)} } window.open(productObj.productUrl + variantParameterString,'_blank'); } dermObj.pimcoreIdToViewItemEvent = (pimcoreId) => { if (typeof dataLayer === 'undefined') return; try{ let currencyCode = ''; try{ currencyCode = Shopify.currency.active; }catch(err){} const prodData = dermObj.productData[pimcoreId]; if (prodData.shopify_id == undefined) return; let variantId, variantSize; try{ const defVariant = prodData.variants.filter((variant) => variant.default)[0]; variantId = defVariant.shopify_variant_id; variantSize = defVariant.size; }catch(errVar){ console.warn(errVar); variantId = undefined; variantSize = undefined; } const dataLayerPayload = { event : 'dl_view_item', from_fmc: true, ecommerce : { currencyCode: currencyCode, detail: { products: [ { product_id : prodData.shopify_id, price: Number(prodData.price), name: prodData.name, variant_id : variantId, item_variant: variantSize } ] } } } dataLayer.push(dataLayerPayload); }catch(err){ console.error(err); return; } } dermObj.prodDisplayed = (pimcoreId) => { try{ const prodObj = dermObj.productData[pimcoreId]; dermObj.dispProdArr.push({ name: prodObj.name, shopify_id: prodObj.shopify_id, variant_id: prodObj.variant_id }); // Debounce the send to backend clearTimeout(dermObj.sendDispProdsTimeout); dermObj.sendDispProdsTimeout = setTimeout(dermObj.sendDispProds, 1000); }catch(err){ console.log(err); } } dermObj.sendDispProds = () =>{ if (dermObj.backendData == undefined) return; if (dermObj.backendData.hashid == undefined || dermObj.backendData.hashid == '') return; const payload = { hashid : dermObj.backendData.hashid, displayed_products: [...dermObj.dispProdArr] } if (dermObj.recomProdSent != true){ if (dermObj.productData != undefined){ payload.recommended_products = [] try{ Object.values(dermObj.productData).forEach((prodData) => { const reducedProdData = { name : prodData.name, shopify_id : prodData.shopify_id } if (Array.isArray(prodData.variants)){ let variantIdArr = prodData.variants.filter((variantObj) => variantObj.default); if (variantIdArr.length > 0 ){ reducedProdData.variant_id = variantIdArr[0].shopify_variant_id; } payload.recommended_products.push(reducedProdData); } }) }catch(errProdData){ console.error(errProdData); } } try{ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg != undefined && rspg != ''){ payload.rspg = rspg; } }catch(errRspg){ console.error(errRspg); } dermObj.recomProdSent = true; } fetch(`${dermObj.backend}/fmc/update_user_products`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => { console.log('Data sent successfully:', data); }) .catch(error => { console.error('Error sending data:', error); }); } dermObj.addToBagShopify = async (productBuyButton) => { return new Promise( async (resolve,reject)=>{ const pimcoreId = productBuyButton.dataset.widgetProductBuy; const defaultVariantObj = dermObj.productData[pimcoreId].variants.filter((variantData) => {return variantData.default}); const selectedVariantObj = dermObj.productData[pimcoreId].variants.filter((variantData) => {return variantData.selected}); let variantId; if (selectedVariantObj.length == 1){ variantId = selectedVariantObj[0].shopify_variant_id; }else if (defaultVariantObj.length > 0){ variantId = defaultVariantObj[0].shopify_variant_id; }else{ variantId = dermObj.productData[pimcoreId].variants[0].shopify_variant_id; } let useShopifyFunction = false; if ((window.Shopify != undefined && window.Shopify != null) && dermObj.config.useCustomShopifyFunction == true){ if (Shopify.derm_custom != undefined && Shopify.derm_custom != null){ if (Shopify.derm_custom.addToBagShopify != undefined && Shopify.derm_custom.addToBagShopify != null){ useShopifyFunction = true; } } } if (useShopifyFunction == true){ // TO BE REMOVED ONCE ECOM FIXES SHOPIFY FUNCTION let dummyEvent = {} try{ if (dermObj.config.useShopifyDummyBtn == true){ let dummy_el = document.createElement('button'); dummy_el.innerHTML = ""; dummyEvent = { target: dummy_el } } }catch(err){ dummyEvent = {} } // ALSO REMOVE DUMMY EVENT AGAIN ONCE THE ABOVE CODE WILL BE REMOVED Shopify.derm_custom.addToBagShopify(dummyEvent,variantId).then((res)=>{ dermObj.sendGA360("main flow","add to bag - variant id="+variantId); dermObj.sendGAFlowEvent("add to bag - variant id="+variantId); dermObj.sendGA360("main flow","add to bag"); dermObj.sendGAFlowEvent("add to bag"); resolve("product added successfully"); }) .catch((err)=>{ reject("error in adding product do cart"); }); }else{ try{ const xhr = new XMLHttpRequest(); xhr.open('POST','/cart/add.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'text'; xhr.onerror = ()=>{ console.error('Upload failed - ',xhr); reject("error") } xhr.onload = ()=>{ if(xhr.status == 200){ setTimeout(()=>{ dermObj.updateShopifyCart(); },1000) dermObj.sendGA360("main flow","add to bag - variant id="+variantId); dermObj.sendGAFlowEvent("add to bag - variant id="+variantId); dermObj.sendGA360("main flow","add to bag"); dermObj.sendGAFlowEvent("add to bag"); resolve("product added successfully"); }else{ reject("error in adding product to cart"); } } const payload = { id:variantId, ...(dermObj.config.shopifyExtraPayload || {}) }; xhr.send(JSON.stringify(payload)); }catch(err){ reject(err); } } }) } dermObj.updateShopifyCartDawn = async function(){ try{ fetch(window.location.pathname + "?sections=cart-drawer,cart-icon-bubble") .then(cartRes => cartRes.json()) .then(cartData => { try{ const bubbleLink = document.getElementById('cart-icon-bubble'); const bubbleDom = (new DOMParser).parseFromString(cartData['cart-icon-bubble'],'text/html'); const newBubbleSvg = bubbleDom.getElementById('shopify-section-cart-icon-bubble').innerHTML; bubbleLink.innerHTML = newBubbleSvg; }catch(bubbleErr){ console.error(bubbleErr) } try{ const cartDrawer = document.querySelector('cart-drawer'); const drawerDom = (new DOMParser).parseFromString(cartData['cart-drawer'],'text/html'); const newCartDrawerInner = drawerDom.querySelector('cart-drawer').innerHTML; cartDrawer.classList.remove('is-empty'); cartDrawer.innerHTML = newCartDrawerInner; try{ cartDrawer.querySelector('#CartDrawer-Overlay').addEventListener('click',()=>{ cartDrawer.classList.remove('active'); document.body.classList.remove('overflow-hidden', 'ed-overflow-hidden', 'ed-drawer-open'); }) }catch(overlayErr){ console.error(overlayErr) } }catch(drawerErr){ console.error(drawerErr) } }) }catch(outerErr){ console.error(outerErr); } } dermObj.updateShopifyCart = async () => { if (dermObj.customization?.updateShopifyCart){ const xhr = new XMLHttpRequest(); xhr.open('GET','/cart.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = () => { const cart = xhr.response dermObj.customization.updateShopifyCart(cart); }; xhr.send(); }else{ try{ dermObj.updateShopifyCartDawn(); }catch(err){console.error(err)} } } dermObj.addMultipleToBagShopify = async ( variantIdArray) => { let useShopifyFunction = false; if (Shopify != undefined && Shopify != null){ if (Shopify.derm_custom != undefined && Shopify.derm_custom != null){ if (Shopify.derm_custom.discts == undefined || Shopify.derm_custom.discts == null) Shopify.derm_custom.discts = {}; if (Shopify.derm_custom.addToBagShopifyArray != undefined && Shopify.derm_custom.addToBagShopifyArray != null){ useShopifyFunction = true; } } } return new Promise( async (resolve,reject)=>{ if (useShopifyFunction){ Shopify.derm_custom.addToBagShopifyArray(variantIdArray).then((res)=>{ dermObj.sendGA360("main flow",`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGAFlowEvent(`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGA360("main flow","add all to bag"); dermObj.sendGAFlowEvent("add all to bag"); resolve("product array added successfully"); }) .catch((err)=>{ reject("error in adding product array to cart"); }); }else{ try{ const payload = { items: [] } variantIdArray.forEach((variantId) => { payload.items.push({ id: variantId, quantity: 1 }) }) const xhr = new XMLHttpRequest(); xhr.open('POST','/cart/add.js',true) xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onerror = ()=>{ console.error('Upload failed - ',xhr); reject("error") } xhr.onload = ()=>{ dermObj.updateShopifyCart(); dermObj.sendGA360("main flow",`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGAFlowEvent(`add multiple products to bag - variant ids=${variantIdArray}`); dermObj.sendGA360("main flow","add all to bag"); dermObj.sendGAFlowEvent("add all to bag"); resolve("product added successfully"); } xhr.send(JSON.stringify(payload)); }catch(err){ reject(err); } } }) } if (typeof dermObj.afterTextRendering == 'undefined'){ dermObj.afterTextRendering = ()=>{}; } dermObj.getLanguageData = async()=>{ return new Promise(async (resolve, reject)=>{ if (dml_fmc.config.forcedLanguage){ dermObj.lang_code = dml_fmc.config.forcedLanguage; }else{ dermObj.lang_code = navigator.language; } if (dermObj.lang_code != 'en-US'){ await dermObj.getLanguageDataEnUs(); } let xhr = new XMLHttpRequest(); xhr.open('GET',`https://facemapping.me/lang/${dermObj.lang_code}`, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = async (successEvent)=>{ console.log("success lang call", xhr.response); dermObj.lang_code=xhr.response.lang_code; if (dermObj.textData){ await dermObj.mergeIntoTextData(xhr.response.data); }else{ dermObj.textData = xhr.response.data; } resolve(xhr.response.data); } xhr.onerror = (errorEvent)=>{ console.error("error lang call", errorEvent); reject(); } xhr.abort = (abortEvent)=>{ console.error("abort lang call",abortEvent); reject(); } xhr.ontimeout = (timeoutEvent)=>{ console.error("timeout lang call",timeoutEvent); reject(); } xhr.send(null); }) } dermObj.getLanguageDataEnUs = async()=>{ return new Promise((resolve, reject)=>{ let xhr = new XMLHttpRequest(); xhr.open('GET',`https://facemapping.me/lang/en-US`, true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.responseType = 'json'; xhr.onload = (successEvent)=>{ console.log("success lang call", xhr.response); dermObj.textData = xhr.response.data; resolve(xhr.response.data); } xhr.onerror = (errorEvent)=>{ console.error("error lang call", errorEvent); reject(); } xhr.abort = (abortEvent)=>{ console.error("abort lang call",abortEvent); reject(); } xhr.ontimeout = (timeoutEvent)=>{ console.error("timeout lang call",timeoutEvent); reject(); } xhr.send(null); }) } dermObj.renderTextData = async (textData) => { return new Promise((resolve, reject) => { const render_jsonTextObject = (textObj)=>{ Object.keys(textObj).forEach((item,index)=>{ if (typeof textObj[item] == "object"){ render_jsonTextObject(textObj[item]); }else{ try{ if (textObj[item] != ""){ document.querySelectorAll(`[data-widget-text-term=${item}]`).forEach((htmlEl)=>{ htmlEl.innerHTML = textObj[item]; }) document.querySelectorAll(`[data-widget-attribute-text-term=${item}]`).forEach((htmlEl)=>{ if (htmlEl.dataset.widgetAttributeType && htmlEl.dataset.widgetAttributeType != ""){ htmlEl.setAttribute(htmlEl.dataset.widgetAttributeType , textObj[item]); } }) } }catch(err){ dermObj.debug('INFO - Element with id '+item+' not found - err: ',err); } } }) } render_jsonTextObject(textData); dermObj.afterTextRendering(); resolve(); }) } dermObj.mergeIntoTextData = async (updatedTextData) => { let tmpObj = {...updatedTextData}; async function scanThroughJson(currentObj, currentKeyArray){ let compareMainObj = tmpObj; currentKeyArray.forEach((pastKey)=>{ compareMainObj = compareMainObj[pastKey]; }) Object.keys(currentObj).forEach((currentKey)=>{ if ( Object.keys(compareMainObj).includes(currentKey)){ if (typeof currentObj[currentKey] == "object"){ let updatedKeyArray = [...currentKeyArray] updatedKeyArray.push(currentKey); scanThroughJson(currentObj[currentKey], updatedKeyArray); }else if(typeof currentObj[currentKey] == "string"){ if (compareMainObj[currentKey] == ""){ compareMainObj[currentKey] = currentObj[currentKey]; if (currentKey.indexOf('consent_privacy_statement_') > -1 && dermObj.lang_code.split('-')[0] != 'en'){ dermObj.uselegacyLegalCopy = true; } } } }else{ compareMainObj[currentKey] = currentObj[currentKey]; if (currentKey.indexOf('consent_privacy_statement_') > -1 && dermObj.lang_code.split('-')[0] != 'en'){ dermObj.uselegacyLegalCopy = true; } } }) } await scanThroughJson(dermObj.textData,[]); dermObj.textData = {...tmpObj} return tmpObj; } dermObj.pageControls = {} dermObj.initClassesDueWidth = async()=>{ return new Promise(async (resolve, reject)=>{ const bodyWidthCheck = setInterval(async ()=>{ if (dermObj.body.offsetWidth > 0){ clearInterval(bodyWidthCheck); await dermObj.updateClassesDueWith(); window.addEventListener('resize', dermObj.updateClassesDueWith); } resolve(); },50) const isMacLike = /(Mac|iPhone|iPod|iPad)/i.test(navigator.platform); if (isMacLike){ dermObj.body.classList.add('dml_is_os'); } }) } dermObj.updateClassesDueWith = async ()=>{ return new Promise(async (resolve, reject)=>{ if (dermObj.body.offsetWidth > 768){ dermObj.widget_wrapper.classList.remove("dml_mobile"); dermObj.body.classList.remove("dml_mobile"); }else{ dermObj.widget_wrapper.classList.add("dml_mobile"); dermObj.body.classList.add("dml_mobile"); } resolve(); }); } dermObj.pageControls.permissionsPage = {} let skipToResultsCounter = 0; dermObj.pageControls.permissionsPage.skptres = async () => { skipToResultsCounter++; if (skipToResultsCounter > 10){ dermObj.gotoPage('blmr_results_page'); } } dermObj.pageControls.landing_brand_campaign = {} dermObj.pageControls.landing_brand_campaign.runConcernCycle = () => { const textKeyArray = [ "acne_alternative", "redness_alternative", "dark_circles_alternative", "wrinkles_alternative", "dehydration_alternative", "dull_skin", "dark_spots"]; const concernCycleField = dermObj.body.querySelector('#fmc_brand_campaign_app_title_concern'); const intervalTimer = 3000; const blendTimer = 500; concernCycleField.style.transition = `${blendTimer/1000}s opacity`; let concernCurIndex = 0; let maxLength = { desktop: 0, mobile: 0 }; textKeyArray.forEach((textKey) => { maxLength.desktop = Math.max(maxLength.desktop, dermObj.textData.concerns[textKey].length * 30 + 30); maxLength.mobile = Math.max(maxLength.mobile, dermObj.textData.concerns[textKey].length * 18 + 20); }) if (dermObj.body.offsetWidth > 768){ concernCycleField.style.width = `${maxLength.desktop}px`; }else{ concernCycleField.style.width = `${maxLength.mobile}px`; } window.addEventListener('resize',()=>{ if (dermObj.body.offsetWidth > 768){ concernCycleField.style.width = `${maxLength.desktop}px`; }else{ concernCycleField.style.width = `${maxLength.mobile}px`; } }) const cicleInterval = setInterval(()=>{ if (concernCycleField.getBoundingClientRect().height > 0){ concernCurIndex++; concernCurIndex = concernCurIndex < textKeyArray.length ? concernCurIndex: 0; concernCycleField.innerHTML = dermObj.textData.concerns[textKeyArray[concernCurIndex]]; concernCycleField.style.opacity = 1; setTimeout(()=>{ concernCycleField.style.opacity = 0; },intervalTimer - blendTimer) }else{ clearInterval(cicleInterval) } },intervalTimer) concernCycleField.innerHTML = dermObj.textData.concerns[textKeyArray[concernCurIndex]]; setTimeout(()=>{ concernCycleField.style.opacity = 0; },intervalTimer - blendTimer) } dermObj.pageControls.onboarding_default = {} dermObj.pageControls.onboarding_default.currentSlideIndex = 0 let fmcOnboardingSlider = document.getElementById("fmc_onboarding_slider_container"); dermObj.pageControls.onboarding_default.nextSlide = ()=>{ dermObj.sendGA360("main flow", "onboarding next clicked"); dermObj.sendGAFlowEvent( "onboarding next clicked"); if (dermObj.pageControls.onboarding_default.currentSlideIndex < 2 ){ dermObj.pageControls.onboarding_default.currentSlideIndex++; let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; document.getElementById("fmc_onboarding_prev_button_icon").classList.remove('fmc_inactive'); document.querySelectorAll(".fmc_onboarding_bullet").forEach((bullet)=>{ bullet.classList.remove('fmc_selected'); }) document.getElementById(`fmc_onboarding_bullet_${dermObj.pageControls.onboarding_default.currentSlideIndex + 1}`).classList.add('fmc_selected'); }else{ dermObj.pageControls.onboarding_default.skipIntro(); } } dermObj.pageControls.onboarding_default.prevSlide = ()=>{ dermObj.sendGA360("main flow", "onboarding back clicked"); dermObj.sendGAFlowEvent( "onboarding back clicked"); if (dermObj.pageControls.onboarding_default.currentSlideIndex > 0 ){ dermObj.pageControls.onboarding_default.currentSlideIndex--; let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; if (dermObj.pageControls.onboarding_default.currentSlideIndex == 0){ document.getElementById("fmc_onboarding_prev_button_icon").classList.add('fmc_inactive'); } document.querySelectorAll(".fmc_onboarding_bullet").forEach((bullet)=>{ bullet.classList.remove('fmc_selected'); }) document.getElementById(`fmc_onboarding_bullet_${dermObj.pageControls.onboarding_default.currentSlideIndex + 1}`).classList.add('fmc_selected'); } } dermObj.pageControls.onboarding_default.skipToResultsCounter = 0; dermObj.pageControls.onboarding_default.skipIntro = async () => { if (dermObj.pageControls.onboarding_default.skipToResultsCounter > 5){ dermObj.gotoPage('results'); let skipHash; let be; if (dermObj.backend == "https://fmc-backend-staging.herokuapp.com"){ skipHash = "a0ef6d0190214fce992e877e2a518b36"; be = "stg"; }else if(dermObj.backend == "https://imb-backend-eu.herokuapp.com"){ skipHash = "8b139fac4f0549309feb263750c2effd"; be = "eu"; }else if(dermObj.backend == "https://imb-backend-ca.herokuapp.com"){ skipHash = "24b16e9ebf56472288eb4ee1e4a8a6f4"; be = "ca"; }else{ skipHash = "5fe15fcbbc5b403ebedd7a46b479a5ab"; be = "us"; } let urlParamString = '' if (window.location.search.indexOf('?') > - 1){ urlParamString = `&fmhid=${skipHash}&be=${be}`; }else{ urlParamString = `?fmhid=${skipHash}&be=${be}`; } window.history.pushState('fmc_results_page', '', `${window.location.href}${urlParamString}`); const analyzeData = await dermObj.getFormerfmcResult(skipHash); dermObj.debug("fmc data: ",analyzeData); dermObj.backendData = {...analyzeData} dermObj.pageControls.results_default.build(); }else{ if (dermObj.pageControls.onboarding_default.currentSlideIndex == 2){ dermObj.sendGA360("main flow","onboarding analyze clicked"); dermObj.sendGAFlowEvent("onboarding analyze clicked"); }else{ dermObj.sendGA360("main flow","skip intro clicked"); dermObj.sendGAFlowEvent("skip intro clicked"); } dml_fmc.showConsent() } } dermObj.pageControls.onboarding_default.skipToResults = () => { dermObj.pageControls.onboarding_default.skipToResultsCounter++ } dermObj.pageControls.onboarding_default.resizeSlides = ()=>{ let newPos = `-${fmcOnboardingSlider.parentElement.offsetWidth * (dermObj.pageControls.onboarding_default.currentSlideIndex)}px`; fmcOnboardingSlider.style.left = newPos; } window.addEventListener('resize',dermObj.pageControls.onboarding_default.resizeSlides) dermObj.pageControls.onboarding_quiz_no_image = {} dermObj.pageControls.onboarding_quiz_no_image.loadQuiz = async ()=>{ console.log('loading quiz') //clear potential old quiz: const quizWrapper = dermObj.body.querySelector('#fmc_quiz_no_image_page #dml_dmlqz_wrapper') const loadingSpinner = dermObj.body.querySelector('#fmc_quiz_no_image_page .fmc_quiz_loading_spinner') quizWrapper.innerHTML = ''; quizWrapper.style.display = "none"; loadingSpinner.style.display = "block"; window.dml_dmlqz = {}; dml_dmlqz.customCssUrl = 'https://facemapping.me/css/quiz_styles.min.css'; dml_dmlqz.surveyResults = {}; dml_dmlqz.surveyId = '6a5c9571-20e6-4efa-a8fc-26edb24024ef'; dml_dmlqz.postId = '7bb43cf4-8cbb-46ab-b52c-95183ae37b80'; if (typeof window.dml_dmlqz.surveyId == 'undefined') { console.error("cannot load survey data - ",err); return; } const qzembedUrl = "https://dml-quiz-production.herokuapp.com/embed.js?"+(new Date()).getTime(); const qzembedScript = document.createElement("script"); qzembedScript.src = qzembedUrl; document.getElementById("dml_dmlqz_wrapper").appendChild(qzembedScript); const surveyLoadedInterval = setInterval(()=>{ if (dml_dmlqz.surveyLoaded){ clearInterval(surveyLoadedInterval); dermObj.renderTextData(dermObj.textData); //dermObj.addClickEventsToButtons(); //dml_dmlqz.body.querySelectorAll('#dmlqz_submit_button').forEach((submitButton) => { //submitButton.innerHTML = dermObj.textData["exact phrases"].next; //}) dml_dmlqz.surveyJs.submitButton = async()=>{ dml_dmlqz.evaluateCurrentQuestion(); try{ dermObj.pageControls.onboarding_quiz_no_image.submitSurveyResults(); }catch(err){ console.error(err) } } quizWrapper.style.display = "flex"; loadingSpinner.style.display = "none"; if (dermObj.isIOS || dermObj.isMacLike ){ dml_dmlqz.body.querySelectorAll('.dml_horizontally_centered_text').forEach((centerEl) => { centerEl.style.paddingTop = '0.2em'; }) } // FIX FOR POLISH LANGUAGE - ISSUES WITH HELVETICA NEUE STD - SECOND TIME AFTER QUIZ LOADED if (['pl','cs','ro'].includes(dermObj.lang_code)){ dermObj.body.querySelectorAll('p,span,a,h1,h2,h3').forEach((textEl) => { textEl.style.fontFamily = '"Helvetica Neue", "Arial"' }); } } },100) } dermObj.pageControls.onboarding_quiz_no_image.submitSurveyResults = async ()=>{ console.log('submit survey results'); dermObj.gotoPage('waiting'); try{ let revVals = {}; try{ revVals = await dermObj.pageControls.onboarding_quiz_no_image.quizToRevieveMapping(dml_dmlqz.surveyResults); }catch(err){ revVals = {}; console.error(err); } dermObj.backendData = await dermObj.sendNoImageQuizResults(dml_dmlqz.surveyResults, revVals); //dermObj.gotoPage('results'); }catch(err){ console.error(err); } } dermObj.pageControls.onboarding_quiz_no_image.quizToRevieveMapping = async (surveyResults) => { return new Promise ((resolve,reject)=>{ try{ const revVals = {}; const survRes = {...dml_dmlqz.surveyResults}; // Q1 Mapping let q1skinShineAnswerCounter = 0; let q1isNotSure = false; let q1isSensitive = false; let q1skinShineString = ''; const q1skinShineVals = { 'normal' : 0.2, 'oily' : 0.8, 'dry' : 0, 'combination' : 0.5 } survRes.q1.forEach((answer) => { switch(answer){ case 'normal': case 'oily': case 'combination': case 'dry': q1skinShineAnswerCounter++; q1skinShineString = answer; break; case 'sensitive': q1isSensitive = true; break; case 'not_sure': q1isNotSure = true; break; } }) if (!q1isNotSure){ if (q1isSensitive){ revVals.revieve_redness_value = 0.8; } if (q1skinShineAnswerCounter > 1){ revVals.revieve_skin_shin_value = 0.5; }else if(q1skinShineAnswerCounter == 1){ try{ revVals.revieve_skin_shine_value = q1skinShineVals[ q1skinShineString ]; }catch(errInner){console.error(errInner)} } } // Q2 Mapping const q2revieveVals = { fine_lines : { key: 'revieve_wrinkles_value', val: 0.5 }, deep_lines : { key: 'revieve_wrinkles_value', val: 0.8 }, breakouts : { key: 'revieve_acne_value', val: 0.8 }, dark_circles : { key: 'revieve_eyes_value', val: 0.8 }, uneven_tone : { key: 'revieve_uneven_skin_tone_value', val: 0.8 }, elasticity : { key: 'revieve_dummy_elasticity_value', // TO BE REPLACED val: 0.33 }, sensitivity : { key: 'revieve_redness_value', val: 0.8 }, blackheads : { key: 'revieve_dummy_blackheads_value', val: 0.33 }, dehydration : { key: 'revieve_dummy_dehydration_value', val: 0.33 } } survRes.q2.forEach((answer) => { let curKey = ''; let curVal = 0.1; switch(answer){ case 'fine_lines': case 'deep_lines': if (survRes.q2.includes('deep_lines')){ curKey = q2revieveVals.deep_lines.key; curVal = q2revieveVals.deep_lines.val; }else{ curKey = q2revieveVals.fine_lines.key; curVal = q2revieveVals.deep_lines.val; } break; default: curKey = q2revieveVals[answer].key; curVal = q2revieveVals[answer].val; } revVals[curKey] = curVal; }); resolve(revVals); }catch(err){reject(err)} }); } dermObj.pageControls.capture = {}; dermObj.pageControls.capture.start = async () => { //dermObj.pageControls.waiting.isAnalyzing = false; dermObj.backendData = null; dermObj.fmcResultsUrl = ''; dermObj.masks.clearImages(); if (dermObj.config.useFaceAi != false){ await dermObj.capture.checkFaceApi(); if (dermObj.config.useAgGeFaceApiFeature !== true){ dermObj.sendGA360("main flow","capture page - age bucket question"); dermObj.sendGAFlowEvent("capture page - age bucket question"); try{ dermObj.pageControls.capture.ed6d4 = -1; dermObj.pageControls.capture.b83d2 = -1; dermObj.pageControls.capture.getAgeBucketQuestionAnswered = false; await dermObj.pageControls.capture.getAgeBucketQuestion(); }catch(err){console.log(err)} }else{ dermObj.sendGA360("main flow","capture page - use extra face model"); dermObj.sendGAFlowEvent("capture page - use extra face model"); } }else{ dermObj.pageControls.capture.ed6d4 = -1; dermObj.pageControls.capture.b83d2 = -1; dermObj.pageControls.capture.getAgeBucketQuestionAnswered = false; await dermObj.pageControls.capture.getAgeBucketQuestion(); } try{ await dermObj.capture.startStream(); }catch(err){ console.warn("camera stream not working - ", err); } try{ dermObj.pageControls.waiting.reset(); }catch(err){console.error(err)} dermObj.emailRequestedForResults = false; try{ const capturedImage = await dermObj.capture.getImage(); await dermObj.capture.stopStream(); //console.log(capturedImage) if (dermObj.config.quizAfterImage === true){ dermObj.gotoPage('quiz_after_image'); }else{ dermObj.gotoPage('waiting'); let urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_ds')) { urlObj.searchParams.set('qai_ds', 0); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } } dermObj.masks.capturedImage = capturedImage; await dermObj.masks.calcDarkCirclesScore(); try{ const startTime = Date.now(); const analyzeData = await dermObj.processImage(capturedImage) const endTime = Date.now(); dermObj.debug('analyze call time [s]: ', (endTime-startTime)/1000); dermObj.masks.obscurifyEyesFlag = false; dermObj.debug("ANALYZE DATA - ",analyzeData) // catch fmc mini collection page and route through if (dermObj.isPercMatchMiniPage == true && dermObj.pageControls.perc_match_coll.percMatchFailed == true){ dermObj.backendData = {}; dermObj.gotoPage('results'); return; } if (analyzeData.success === false || analyzeData.statusCode === 500){ if (analyzeData.code === 5002){ document.getElementById("fmc_waiting_page_default").classList.add("no_face_error"); dermObj.sendGA360("main flow","analyze image - error_no_face"); dermObj.sendGAFlowEvent("analyze image - error_no_face"); return; } if (analyzeData.code === 5003 || analyzeData.code === 202){ //document.getElementById("fmc_waiting_page_default").classList.add("multi_face_error"); //dermObj.sendGA360("main flow","analyze image - error_multi_faces"); dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } // general handling of old revieve errors if (analyzeData.code < 999 ){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } if (analyzeData.code === 4000 || analyzeData.code === 5001 || analyzeData.code === 5000 || analyzeData.statusCode === 500){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; /* document.getElementById("fmc_waiting_page_default").classList.add("general_error"); dermObj.sendGA360("main flow","analyze image - error_general"); dermObj.sendGAFlowEvent("analyze image - error_general"); return; */ }else{ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } } if (!dermObj.config.userImgOnly){ if (!analyzeData.revieve_response){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; dermObj.gotoPage('results'); return; } if (analyzeData.revieve_response?.results === null){ dermObj.sendGA360("main flow","analyze image - show estimated results"); dermObj.sendGAFlowEvent("analyze image - show estimated results"); dermObj.config.pageDict.results = 'fmc_estimated_results'; if (dermObj.config.quizAfterImage !== true){ dermObj.gotoPage('results'); } return; } } dermObj.sendGA360("main flow","analyze image - success"); dermObj.sendGAFlowEvent("analyze image - success"); dermObj.backendData = {...analyzeData}; if (dermObj.config.userImgOnly){ /*dermObj.backendData.concerns.forEach((concern)=>{ Object.keys(concern).forEach((key)=>{ if (key.indexOf('image') > -1){ concern[key] = capturedImage; } }) })*/ dermObj.backendData.original_image = capturedImage; } }catch(err){ document.getElementById("fmc_waiting_page_default").classList.add("general_error"); dermObj.sendGA360("main flow","analyze image - general_error"); dermObj.sendGAFlowEvent("analyze image - general_error"); console.error("error in uploading image - ",err) dermObj.gotoPage('waiting'); } }catch(err){ console.error("error in capturing an image - ",err) let waitingPageEl = document.getElementById("fmc_waiting_page_default"); if (err.error === 'multi_face'){ waitingPageEl.classList.add('multi_face_error') dermObj.sendGA360("main flow","analyze image - error_multi_faces"); dermObj.sendGAFlowEvent("analyze image - error_multi_faces"); }else{ waitingPageEl.classList.add('general_error') dermObj.sendGA360("main flow","analyze image - general_error"); dermObj.sendGAFlowEvent("analyze image - general_error"); } dermObj.gotoPage('waiting'); } } dermObj.pageControls.capture.getAgeBucketQuestion = async () => { return new Promise((resolve,reject) => { let intervalStep = 500; let pendingTime = 0; let intervalTimeout = 30000; dermObj.body.querySelector('#fmc_capture_question_overlay').style.display = 'flex'; const ageBucketInterval = setInterval(()=>{ if (dermObj.pageControls.capture.getAgeBucketQuestionAnswered === true){ clearInterval(ageBucketInterval); resolve(); return; } pendingTime += intervalStep; if (pendingTime > intervalTimeout) { clearInterval(ageBucketInterval); dermObj.pageControls.capture.ed6d4 = -1; reject('timeout in age bucket question'); } },intervalStep) }) } dermObj.pageControls.capture.selectAgeBucket = async (bucketIndex) => { dermObj.body.querySelector('#fmc_capture_question_overlay').style.display = 'none'; const ageArray = [17, 22,30,40,50, 60, 70]; try{ dermObj.pageControls.capture.ed6d4 = ageArray[bucketIndex]; }catch(err){ dermObj.pageControls.capture.ed6d4 = -1 console.error(err); } dermObj.pageControls.capture.getAgeBucketQuestionAnswered = true; } dermObj.pageControls.qai = {}; dermObj.pageControls.qai.curIndex = 0; dermObj.pageControls.qai.urlParamAnswerArr = []; dermObj.pageControls.qai.answerObj = {} dermObj.pageControls.qai.init = ()=>{ dermObj.pageControls.qai.ingredientsList = [...dermObj.pageControls.qai.keyIngredientsList]; dermObj.pageControls.qai.quizPage = dermObj.body.querySelector(`#${dermObj.config.pageDict.quiz_after_image}`); dermObj.pageControls.qai.answerObj[dermObj.pageControls.qai.quizPage.id] = {}; dermObj.pageControls.qai.slider = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_slider'); dermObj.pageControls.qai.curIndex = 0; dermObj.pageControls.qai.quizPage.querySelectorAll('button.fmc_qai_answer_button').forEach((answerBtn) => { answerBtn.removeEventListener('click', dermObj.pageControls.qai.evaluateButtonClick); answerBtn.addEventListener('click', dermObj.pageControls.qai.evaluateButtonClick); answerBtn.classList.remove('is_selected'); }); dermObj.pageControls.qai.quizPage.querySelectorAll('button.fmc_qai_answer_list_item').forEach((listItem)=>{ listItem.remove(); }); dermObj.pageControls.qai.quizPage.querySelectorAll('input.fmc_qai_input').forEach((autoCompInput) => { autoCompInput.removeEventListener('input', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.addEventListener('input', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.removeEventListener('focus', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.addEventListener('focus', dermObj.pageControls.qai.triggerAutoComplete); autoCompInput.removeEventListener('blur', dermObj.pageControls.qai.closeAutoCompleteBox); autoCompInput.addEventListener('blur', dermObj.pageControls.qai.closeAutoCompleteBox); }) dermObj.pageControls.qai.nextButton = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_next_button'); dermObj.pageControls.qai.backButton = dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_back_button'); dermObj.pageControls.qai.update(); const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_ds')) { urlObj.searchParams.set('qai_ds', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } }; dermObj.pageControls.qai.update = () => { const slidesVisibleCount = Math.max(1,dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length); dermObj.pageControls.qai.slider.style.width = `${slidesVisibleCount}00%`; dermObj.pageControls.qai.slider.style.left = `-${dermObj.pageControls.qai.curIndex}00%`; dermObj.pageControls.qai.quizPage.querySelector('.fmc_qai_progress_bar').style.width = `${100*(dermObj.pageControls.qai.curIndex+1)/slidesVisibleCount}%`; dermObj.pageControls.qai.updateNavButtons(); } dermObj.pageControls.qai.nextSlide = () => { const currentSlide = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible')[dermObj.pageControls.qai.curIndex]; currentSlide.querySelectorAll('button.fmc_qai_answer_button:not(.is_selected)').forEach((selectedBtn)=>{ if (selectedBtn.dataset.qaiFollowUpSlide != undefined){ const followUpSlidesLabels = selectedBtn.dataset.qaiFollowUpSlide.split(','); followUpSlidesLabels.forEach((followUpSlideLabel)=>{ const followUpSlide = dermObj.pageControls.qai.slider.querySelector(`[data-qai-slide-label="${followUpSlideLabel}"]`); if (followUpSlide == undefined || followUpSlide == null) return; followUpSlide.classList.remove('slide_visible'); }) } }) currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').forEach((selectedBtn)=>{ if (selectedBtn.dataset.qaiFollowUpSlide != undefined){ const followUpSlidesLabels = selectedBtn.dataset.qaiFollowUpSlide.split(','); followUpSlidesLabels.forEach((followUpSlideLabel)=>{ const followUpSlide = dermObj.pageControls.qai.slider.querySelector(`[data-qai-slide-label="${followUpSlideLabel}"]`); if (followUpSlide == undefined || followUpSlide == null) return; followUpSlide.classList.add('slide_visible'); }) } }) const visibleSlides = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible') const slidesVisibleCount = Math.max(1,visibleSlides.length); dermObj.pageControls.qai.evaluateSlide(visibleSlides[dermObj.pageControls.qai.curIndex]); if (dermObj.pageControls.qai.nextButton.classList.contains('is_done_button')){ try{ dermObj.pageControls.qai.sendAnswers(); }catch(err){ console.log(err) } const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_fn')) { urlObj.searchParams.set('qai_fn', 1); try{ urlObj.searchParams.set('qai_an', dermObj.pageControls.qai.urlParamAnswerArr.join('_')); }catch(err){console.error(err)} const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } dermObj.debug('QUIZ ANSWERS - ', JSON.stringify(dermObj.pageControls.qai.answerObj)); dermObj.gotoPage('waiting'); return; } dermObj.pageControls.qai.curIndex++; dermObj.pageControls.qai.curIndex = Math.min(dermObj.pageControls.qai.curIndex, slidesVisibleCount - 1 ); dermObj.pageControls.qai.update(); } dermObj.pageControls.qai.prevSlide = () => { dermObj.pageControls.qai.urlParamAnswerArr.pop(); const slidesVisibleCount = Math.max(1,dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length); dermObj.pageControls.qai.curIndex--; dermObj.pageControls.qai.curIndex = Math.max(dermObj.pageControls.qai.curIndex,0 ); dermObj.pageControls.qai.update(); } dermObj.pageControls.qai.evaluateButtonClick = (evt)=>{ const currentBtn = evt.target; let currentSlide = currentBtn.parentElement; let generationCounter = 0; while (!currentSlide.classList.contains('fmc_qai_slide') && generationCounter < 5){ currentSlide = currentSlide.parentElement; generationCounter++; } if (generationCounter >= 5){ console.error('SLIDE NOT FOUND'); return; } const slideType = currentSlide.dataset.qaiSlideType; switch (slideType){ case "single": currentSlide.querySelectorAll('.fmc_qai_answer_button').forEach((btn)=>{ btn.classList.remove('is_selected'); }) currentBtn.classList.add('is_selected'); dermObj.pageControls.qai.updateNavButtons(); break; case "multiple": currentBtn.classList.toggle('is_selected'); dermObj.pageControls.qai.updateNavButtons(); break; case "list": dermObj.pageControls.qai.nextSlide(); break; default: console.error('TYPE NOT RECOGNIZED'); } } dermObj.pageControls.qai.updateNavButtons = ()=>{ const currentSlide = dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible')[dermObj.pageControls.qai.curIndex]; const slideType = currentSlide.dataset.qaiSlideType; const slideOptional = currentSlide.dataset.qaiSlideOptional; if (dermObj.pageControls.qai.slider.querySelectorAll('.slide_visible').length - 1 == dermObj.pageControls.qai.curIndex){ dermObj.pageControls.qai.nextButton.classList.add('is_done_button'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_done_button'); } if (dermObj.pageControls.qai.curIndex > 0){ dermObj.pageControls.qai.backButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.backButton.classList.remove('is_active'); } if (slideOptional == 'true'){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); return; } let selectedAnswers; let minAnswers; switch (slideType){ case 'single': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; if (selectedAnswers > 0){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; case 'multiple': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; try{ minAnswers = Number(currentSlide.dataset.qaiAnswersMin) || 1; }catch(err){ minAnswers = 1; } if (selectedAnswers >= minAnswers){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; case 'list': selectedAnswers = currentSlide.querySelectorAll('button.fmc_qai_answer_button.is_selected').length; try{ minAnswers = Number(currentSlide.dataset.qaiAnswersMin) || 1; }catch(err){ minAnswers = 1; } if (selectedAnswers >= minAnswers){ dermObj.pageControls.qai.nextButton.classList.add('is_active'); }else{ dermObj.pageControls.qai.nextButton.classList.remove('is_active'); } break; default: console.error('TYPE NOT RECOGNIZED'); } } dermObj.pageControls.qai.evaluateSlide = (slideToEval) => { let valueString = ''; let urlParamString = ''; try{ urlParamString ='Q' + slideToEval.dataset.qaiSlidePrefix; }catch(err){ console.error(err); } slideToEval.querySelectorAll('button.fmc_qai_answer_button.is_selected').forEach((selectedBtn)=>{ valueString += selectedBtn.dataset.qaiAnswerValue + ','; if (selectedBtn.dataset.qaiAnswerSuffix != undefined){ try{ urlParamString += 'A' + selectedBtn.dataset.qaiAnswerSuffix; }catch(err){ console.error(err); } } }) valueString = valueString.replace(/,$/g, ''); const slideLabel = slideToEval.dataset.qaiSlideLabel; dermObj.pageControls.qai.answerObj[dermObj.pageControls.qai.quizPage.id][slideLabel] = valueString; dermObj.pageControls.qai.urlParamAnswerArr.push(urlParamString); } dermObj.pageControls.qai.closeAutoCompleteBox = (evt) => { try{ if (evt.relatedTarget != undefined && evt.relatedTarget.classList.contains('fmc_qai_autocomplete_match')){ return; } let autoCompleteBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_auto_complete_box').innerHTML = ""; }catch(err){ console.log(err); } } dermObj.pageControls.qai.triggerAutoComplete = (evt) => { dermObj.pageControls.qai.currentSlide = evt.target.parentElement.parentElement; let autoCompleteBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_auto_complete_box'); let inputValue = event.target.value.toLowerCase(); let inputEl = event.target; // Filter the ingredientsList to only those which have a word that starts with the input value let matches = dermObj.pageControls.qai.ingredientsList.filter(item => { let words = item.toLowerCase().split(' '); return words.some(word => word.startsWith(inputValue)); }).slice(0, 12); // Generate buttons with the matching items function generateButtons(matches) { // Clear the autocomplete box autoCompleteBox.innerHTML = ''; if (matches.length > 0){ for (let i = 0; i < matches.length; i++) { // Create a new button element let btn = document.createElement('button'); btn.innerHTML = `${matches[i]}`; btn.classList.add('fmc_qai_autocomplete_match'); const ingredientName = matches[i]; btn.onclick = () => { inputEl.value = ''; autoCompleteBox.innerHTML = ''; dermObj.pageControls.qai.addIngredient(ingredientName); }; // Append the button to the auto complete box autoCompleteBox.appendChild(btn); } }else{ let btn = document.createElement('button'); btn.innerHTML = `no matching ingredient found`; btn.classList.add('fmc_qai_autocomplete_match'); autoCompleteBox.appendChild(btn); } } generateButtons(matches); } dermObj.pageControls.qai.addIngredient = (ingredientName)=>{ const answerBox = dermObj.pageControls.qai.currentSlide.querySelector('.fmc_qai_answer_container.fmc_qai_answers_list'); const btn = document.createElement('button'); const listIndex = dermObj.pageControls.qai.ingredientsList.indexOf(ingredientName); if (listIndex !== -1) { dermObj.pageControls.qai.ingredientsList.splice(listIndex, 1); } btn.classList.add('fmc_qai_answer_button','is_selected','fmc_qai_answer_list_item'); btn.dataset.qaiAnswerValue=ingredientName; btn.innerHTML = `${ingredientName}`; answerBox.appendChild(btn); if (answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != undefined && answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != null){ answerBox.querySelector('.fmc_qai_display_on_emtpy_list').style.display = 'none'; } btn.onclick = ()=>{ dermObj.pageControls.qai.ingredientsList.push(ingredientName); dermObj.pageControls.qai.ingredientsList = dermObj.pageControls.qai.ingredientsList.sort(); btn.remove(); const listItemsLength = answerBox.querySelectorAll('.fmc_qai_answer_list_item').length; if (listItemsLength == 0){ if (answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != undefined && answerBox.querySelector('.fmc_qai_display_on_emtpy_list') != null){ answerBox.querySelector('.fmc_qai_display_on_emtpy_list').style.display = 'flex'; } } dermObj.pageControls.qai.updateNavButtons(); } dermObj.pageControls.qai.updateNavButtons(); //data-qai-answer-value } dermObj.pageControls.qai.sendAnswers = () =>{ dermObj.debug('SENDING QUIZ RESULTS CALL') if (dml_fmc.pageControls.qai == undefined) return; if (dml_fmc.pageControls.qai.answerObj == undefined) return; const beInterval = setInterval(()=>{ dermObj.debug('SENDING QUIZ RESULTS - INSIDE INTERVAL') if (dermObj.backendData == undefined || dermObj.backendData == null) return; if (dermObj.backendData.hashid == undefined || dermObj.backendData.hashid == null) return; dermObj.debug('SENDING QUIZ RESULTS FINAL') clearInterval(beInterval); const payload = { hashid : dermObj.backendData.hashid, quiz_after_image_responses: dermObj.pageControls.qai.answerObj } fetch(`${dermObj.backend}/fmc/quiz_after_image`, { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(payload) }) .then(response => response.json()) .then(data => { console.log('Data sent successfully:', data); }) .catch(error => { console.error('Error sending data:', error); }); },100) } dermObj.pageControls.qai.skipToResult = ()=>{ const urlObj = new URL(window.location.href); if (!urlObj.searchParams.has('qai_sk')) { urlObj.searchParams.set('qai_sk', 1); const newUrl = urlObj.toString(); history.pushState({}, '', newUrl); } dermObj.gotoPage('waiting'); } dermObj.pageControls.qai.keyIngredientsList = [ "Alpha Hydroxy Acids (AHAs)", "Antioxidants", "Ceramides", "Collagen", "Hyaluronic Acid", "Niacinamide", "Peptides", "Plant Extracts", "Retinol", "SPF", "Squalane", "Vitamin C" ]; dermObj.pageControls.waiting = {}; dermObj.pageControls.waiting.reset = ()=>{ let waitingPage = document.getElementById("fmc_waiting_page_default"); waitingPage.classList.remove("no_face_error", "multi_face_error", "resolution_error", "general_error", "too_dark_error", "overexposed_error" , "tilt_side_error", "tilt_up_down_error"); } dermObj.pageControls.waiting.buildLoadingText = async ()=>{ const loadingEl = document.getElementById("fmc_loading_results_text"); let loadingString; if (dermObj.lang_code.split('-')[0] != 'en'){ if (dermObj.textData['exact_phrases'].loading_results == 'loading results'){ loadingString = dermObj.textData.waiting_default.fmc_loading_analyze_text; }else{ loadingString = dermObj.textData['exact_phrases'].loading_results; } }else{ loadingString = dermObj.textData['exact_phrases'].loading_results; } // try with preset wave time const waveDuration = 1.5; const resetDelay = 0.5; const blueTime = (waveDuration - resetDelay) / loadingString.length; loadingEl.innerHTML = ''; for (let ii = 0; ii < loadingString.length; ii++){ const spanEl = document.createElement('span'); spanEl.innerHTML = loadingString[ii]; spanEl.style.animation = `fmcLetterBlink ${waveDuration}s ${blueTime * ii}s linear infinite`; loadingEl.appendChild(spanEl); } const bluePerc = (100*blueTime / waveDuration); const blinkStyle = document.createElement('style'); blinkStyle.innerHTML = `@keyframes fmcLetterBlink{\ 0%{color :#6BAAFF}\ ${bluePerc}%{color: #6BAAFF}\ ${bluePerc + 2}%{color: #5b6670}\ 98%{color: #5b6670}\ 100%{color :#6BAAFF}\ }` dermObj.widget_wrapper.appendChild(blinkStyle); } dermObj.pageControls.results_default = {}; dermObj.pageControls.results_default.concernIndex = 0; dermObj.pageControls.results_default.build = async ()=>{ try{ dermObj.storeLocator.updateStoreLocations().catch((err)=>{ console.warn(err); }) }catch(err){ console.warn(err); } try{ dermObj.pageControls.results_default.storeLocator.updateCarousel(); window.addEventListener('resize',dermObj.pageControls.results_default.storeLocator.updateCarousel); dermObj.swipeHandling.addSwiper(dermObj.pageControls.results_default.storeLocator.slider, dermObj.pageControls.results_default.storeLocator.nextStore, dermObj.pageControls.results_default.storeLocator.prevStore ); }catch(err){console.error("error in adding touch move events to store slider", err)} /* if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ dermObj.debug('using Dioxide Data from Backend'); dermObj.dioxideData = dermObj.backendData.dioxide_data; }else{ dermObj.debug('calling Dioxide for recommendations'); const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) const dioxRes = await dermObj.getDioxideRecommendations(dioxPayload) dermObj.dioxideData = dioxRes; } */ if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } try{ dermObj.swipeHandling.addSwiper(document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides"), dermObj.pageControls.results_default.nextProduct, dermObj.pageControls.results_default.prevProduct ); }catch(err){console.error("error in adding touch move events to concern slider", err)} try{ dermObj.swipeHandling.addSwiper(document.querySelector("#fmc_results_page_default .fmc_regimen_product_slider"), dermObj.pageControls.results_default.regimen.next, dermObj.pageControls.results_default.regimen.back ); }catch(err){console.error("error in adding touch move events to regimen slider", err)} (async ()=>{ dermObj.masks.images = {}; try{ await dermObj.masks.getObscEyeRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.getCropRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.makeOriginalImages(); }catch(err){ console.error('error in making original mask images - ',err) } try{ await dermObj.masks.buildMasks(); }catch(err){ console.error('error in building masks - ',err) } dermObj.masks.applyImageData(); try{ document.querySelectorAll('.fmc_results_concerns_section.fmc_desktop_only .fmc_results_images_shift').forEach((shiftEl)=>{ const checkElementInterval = setInterval(()=>{ if (shiftEl.parentElement.offsetWidth > 0){ clearInterval(checkElementInterval); const containerWidth = shiftEl.parentElement.offsetWidth; const containerHeight = shiftEl.parentElement.offsetHeight; const scale = containerHeight / dermObj.masks.cropRect.originalImageHeight; try{ const faceCenter = scale * (dermObj.masks.cropRect.left + 0.5 * dermObj.masks.cropRect.width); shiftEl.style.left = `${Math.round(0.5*containerWidth - faceCenter)}px`; shiftEl.style.opacity = 1; }catch(err){ shiftEl.style.opacity = 1; } } },100) }) }catch(err){ console.error(err); } })(); await dermObj.pageControls.results_default.makeConcernsList(); if (dermObj.isIOS || dermObj.isMacLike){ dermObj.body.querySelectorAll('.dml_horizontally_centered_text').forEach((centerEl) => { centerEl.style.paddingTop = '0.2em'; }) } await dermObj.pageControls.results_default.regimen.build(); await dermObj.collectProductData(); await dermObj.applyProductData(dermObj.productData); dermObj.renderTextData(dermObj.textData); //dermObj.pageControls.results_default.concern.addSwipeDetection(); //dermObj.pageControls.results_default.regimen.addSwipeDetection(); window.addEventListener('resize',dermObj.pageControls.results_default.resizeElements, false); return; } dermObj.pageControls.results_default.makeConcernsList = async () => { await new Promise(async (resolve,reject)=>{ try{ await dermObj.pageControls.results_default.clearConcernLists(); }catch(err){console.error("error clearing concern lists - ",err)} try{ dermObj.dioxideData.sortedConcerns.forEach(async (concern,index)=>{ if (index < dermObj.config.maxConcerns){ await dermObj.pageControls.results_default.addConcernToConcernList(concern,index); await dermObj.pageControls.results_default.addProductToConcernProducts(concern,index); await dermObj.pageControls.results_default.addMobileConcernCard(concern,index); await dermObj.pageControls.results_default.addMobileConcernProduct(concern,index); } if ( index + 1 >= dermObj.dioxideData.sortedConcerns.length) resolve(); }) }catch(err){ console.error(err) resolve(); } }) document.querySelector("#fmc_results_concerns_products_carousel_desktop .fmc_results_products_slides").style.width = `${dermObj.dioxideData.sortedConcerns.length * 100}%`; document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides").style.width = `${dermObj.dioxideData.sortedConcerns.length * 100}%`; document.querySelectorAll("#fmc_results_concerns_products_carousel_desktop .fmc_results_products_slides .fmc_results_product_slide").forEach((slide)=>{ slide.style.width = `${1/dermObj.dioxideData.sortedConcerns.length * 100}%`; }) dermObj.renderTextData(dermObj.textData) const highestConcern = dermObj.dioxideData.sortedConcerns[0].name; document.querySelectorAll(`[data-widget-concern-img="${highestConcern}"]`).forEach((concernImg)=>{ concernImg.classList.add('fmc_displayed'); }) document.querySelectorAll("#fmc_results_page_default .fmc_concern_name_placeholder").forEach((placeholderEl)=>{ placeholderEl.innerHTML = ` ${dermObj.textData.results_default["fmc_concern_title_" + highestConcern]}`; }) dermObj.pageControls.results_default.focusSelectedConcern(); } dermObj.pageControls.results_default.clearConcernLists = async ()=>{ return new Promise (async (resolve, reject)=>{ document.getElementById("fmc_results_concerns_list").innerHTML = ""; document.querySelector("#fmc_results_page_default .fmc_results_products_slides").innerHTML = ""; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_products').innerHTML = ""; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_slides').innerHTML = ""; resolve(); }) } dermObj.pageControls.results_default.addConcernToConcernList = async (concernObj, concernIndex) => { const listContainer = document.getElementById("fmc_results_concerns_list"); let barColor = '#4caf50'; let barWidth = '30%'; const concernItem = document.createElement("div"); concernItem.classList.add(`fmc_concern_item_${concernObj.name}`, 'fmc_concern_info_item'); concernItem.dataset.widgetConcernIndex = concernIndex; try{ document.querySelector(`#fmc_results_page_default [data-widget-concern-img="${concernObj.name}"]`).dataset.widgetConcernIndex = concernIndex; }catch(err){ console.error(err) } let concernInnerHTMLString = `
`+ `

`; barWidth = `${concernObj.score * 20 - 10}%`; if (concernObj.score > 3){ barColor = '#da806e'; concernInnerHTMLString += '

'; }else if (concernObj.score > 1){ barColor = '#e9c353'; concernInnerHTMLString += '

'; } concernInnerHTMLString += '
'; concernInnerHTMLString += `

`; concernInnerHTMLString += `
`; concernItem.innerHTML = concernInnerHTMLString; listContainer.appendChild(concernItem); concernItem.addEventListener('click',dermObj.pageControls.results_default.selectThisConcern); return; } dermObj.pageControls.results_default.addProductToConcernProducts = async (concernObj, concernIndex) => { const slidesContainer = document.querySelector("#fmc_results_page_default .fmc_results_products_slides"); const pimcoreId = concernObj.recommended_product.pimcore_id; const prodImage = concernObj.recommended_product.imageUrl; const prodName = concernObj.recommended_product.name; const prodLink = concernObj.recommended_product.productUrl; const prodTagline = concernObj.recommended_product.tagline; const priceString = dermObj.makePriceString(concernObj.recommended_product); const prodCard = document.createElement("div") prodCard.classList.add("fmc_results_product_slide"); prodCard.dataset.widgetConcernIndex = concernIndex; prodCard.dataset.viewItemObserver = pimcoreId; prodCard.dataset.itemViewed = false; let cardHTMLString = ""; cardHTMLString += ``; /* if (dermObj.lang_code == 'ja'){ cardHTMLString += `

${prodName.toUpperCase()}

`; }else{ cardHTMLString += `

${prodName}

`; } */ cardHTMLString += `

`; cardHTMLString += `

`; cardHTMLString += ``; prodCard.innerHTML = cardHTMLString; slidesContainer.appendChild(prodCard); } dermObj.pageControls.results_default.addMobileConcernCard = async (concern,index) => { const slidesContainer = document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_slides'); const concernSlide = document.createElement('div'); concernSlide.classList.add('fmc_mobile_concern_slide'); concernSlide.dataset.widgetConcernIndex = index; concernSlide.style.width = `${1/dermObj.dioxideData.sortedConcerns.length * 100}%`; let slideHTMLString = ""; slideHTMLString += `
`; let indicatorColor; const concernTitle = dermObj.textData.results_default[`fmc_concern_title_${concern.name}`]; const polygonString = `polygon(100% 100%, 100% 0%, ${(concern.score - 1)* 15 + 30}% 0%, ${(concern.score - 1)* 15 + 30}% 100%)`; if (concern.score > 3){ indicatorColor = '#e21f26'; }else if (concern.score > 1){ indicatorColor = '#ff9635'; }else{ indicatorColor = '#6ea95f'; } slideHTMLString += `

${concernTitle}

`; slideHTMLString += `
`; slideHTMLString += `
`; slideHTMLString += `${dermObj.textData.product_buttons_labels.moderate}${dermObj.textData.product_buttons_labels.critical}`; slideHTMLString += `
`; slideHTMLString += `${dermObj.textData.product_buttons_labels.moderate}${dermObj.textData.product_buttons_labels.critical}`; slideHTMLString += `
`; slideHTMLString += `

`; slideHTMLString += `
`; concernSlide.innerHTML = slideHTMLString; slidesContainer.appendChild(concernSlide); } dermObj.pageControls.results_default.addMobileConcernProduct = async (concern,index) => { const productContainer = document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_products'); const productCard = document.createElement('div'); productCard.classList.add('fmc_mobile_product_card'); productCard.dataset.viewItemObserver = concern.recommended_product.pimcore_id; productCard.dataset.itemViewed = false; const pimcoreId = concern.recommended_product.pimcore_id; const prodImage = concern.recommended_product.imageUrl; const prodName = concern.recommended_product.name; const prodLink = concern.recommended_product.productUrl; const prodTagline = concern.recommended_product.tagline; const priceString = dermObj.makePriceString(concern.recommended_product); let indicatorColor; if (concern.score > 3){ indicatorColor = '#e21f26'; }else if (concern.score > 1){ indicatorColor = '#ff9635'; }else{ indicatorColor = '#6ea95f'; } let cardHTMLString = ``; /*if (dermObj.lang_code == 'ja'){ cardHTMLString += `

${prodName.toUpperCase()}

`; }else{ cardHTMLString += `

${prodName}

`; }*/ cardHTMLString += `

`; cardHTMLString += `

`; cardHTMLString += ``; cardHTMLString += `

`; productCard.innerHTML = cardHTMLString; productContainer.appendChild(productCard); } dermObj.pageControls.results_default.nextProduct = ()=>{ if (dermObj.pageControls.results_default.concernIndex < Math.min(dermObj.dioxideData.sortedConcerns.length -1,dermObj.config.maxConcerns - 1) ){ dermObj.pageControls.results_default.concernIndex++; dermObj.pageControls.results_default.focusSelectedConcern(); } } dermObj.pageControls.results_default.prevProduct = ()=>{ if (dermObj.pageControls.results_default.concernIndex > 0 ){ dermObj.pageControls.results_default.concernIndex--; dermObj.pageControls.results_default.focusSelectedConcern(); } } dermObj.pageControls.results_default.focusSelectedConcern = async ()=>{ if (dermObj.pageControls.results_default.concernIndex == 0){ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_back_button').forEach((backButton)=>{ backButton.classList.add("fmc_inactive"); }) }else{ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_back_button').forEach((backButton)=>{ backButton.classList.remove("fmc_inactive"); }) } if (dermObj.pageControls.results_default.concernIndex == Math.min(dermObj.dioxideData.sortedConcerns.length -1,dermObj.config.maxConcerns - 1) ){ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_next_button').forEach((nextButton)=>{ nextButton.classList.add("fmc_inactive"); }) }else{ document.querySelectorAll('#fmc_results_page_default .fmc_carousel_next_button').forEach((nextButton)=>{ nextButton.classList.remove("fmc_inactive"); }) } const slidesContainerDesktop = document.querySelector("#fmc_results_page_default .fmc_results_products_slides"); slidesContainerDesktop.style.left = `-${dermObj.pageControls.results_default.concernIndex * 100}%`; const slidesContainerMobile = document.querySelector("#fmc_results_page_default .fmc_results_mobile_concern_slides"); slidesContainerMobile.style.left = `-${dermObj.pageControls.results_default.concernIndex * 100}%`; document.querySelectorAll('#fmc_results_concerns_list .fmc_concern_info_item').forEach((concernItem)=>{ if (concernItem.dataset.widgetConcernIndex == dermObj.pageControls.results_default.concernIndex){ concernItem.classList.add('fmc_selected'); concernItem.parentElement.scrollTop = concernItem.offsetTop; }else{ concernItem.classList.remove('fmc_selected'); } }) document.querySelectorAll('#fmc_results_page_default .fmc_result_concern_image[data-widget-concern-index]').forEach((concernImage)=>{ if (concernImage.dataset.widgetConcernIndex == dermObj.pageControls.results_default.concernIndex){ concernImage.classList.add('fmc_displayed'); }else{ concernImage.classList.remove('fmc_displayed'); } }) dermObj.pageControls.results_default.resizeElements(); return; } dermObj.pageControls.results_default.toggleInfoCollapse = (evt)=>{ const isCollapsed = evt.target.parentElement.classList.toggle('fmc_collapsed'); } dermObj.pageControls.results_default.toggleInfoCollapseMobileCarousel = (evt)=>{ const isCollapsed = evt.target.parentElement.classList.contains('fmc_collapsed'); document.querySelectorAll('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_concern_info_wrapper').forEach((concernInfo)=>{ if (isCollapsed){ concernInfo.classList.remove('fmc_collapsed'); }else{ concernInfo.classList.add('fmc_collapsed'); } }) dermObj.pageControls.results_default.resizeElements(); } dermObj.pageControls.results_default.selectThisConcern = (evt)=>{ let cardItem; if (evt.target.classList.contains('fmc_concern_info_item')){ cardItem = evt.target; }else{ cardItem = evt.target.parentElement.parentElement; } dermObj.pageControls.results_default.concernIndex = cardItem.dataset.widgetConcernIndex; dermObj.pageControls.results_default.focusSelectedConcern(); } dermObj.pageControls.results_default.resizeElements = ()=>{ let maxHeight = Math.min(0.8*dermObj.body.offsetWidth, 400) + 160; document.querySelectorAll('#fmc_results_page_default .fmc_mobile_concern_card').forEach((concernCard)=>{ maxHeight = Math.max(maxHeight, concernCard.offsetHeight + 40); }) document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images').style.height = `${maxHeight}px`; document.querySelectorAll('#fmc_results_page_default .fmc_result_mobile_concern_image').forEach((concernImage)=>{ concernImage.style.height = `${Math.min(0.8*dermObj.body.offsetWidth, 400)}px`; }) const nextBackArrowLeftRight = Math.max(5, 0.5*(dermObj.body.offsetWidth - Math.min(0.8*dermObj.body.offsetWidth, 400)) - 40); document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_carousel_next_button').style.right = `${nextBackArrowLeftRight}px`; document.querySelector('#fmc_results_page_default .fmc_results_mobile_concern_images .fmc_carousel_back_button').style.left = `${nextBackArrowLeftRight}px`; let cardWidth = 0.48*(Math.min(500,dermObj.body.offsetWidth) - 20); document.querySelectorAll('#fmc_results_page_default .fmc_results_mobile_concern_products .fmc_mobile_product_card').forEach((prodCard)=>{ prodCard.style.height = `${cardWidth * 1.4}px`; }) dermObj.pageControls.results_default.regimen.focusStep(); } dml_fmc.pageControls.results_default.restart = ()=>{ dermObj.sendGA360("main flow",'fashionplace restart button pressed'); dermObj.sendGAFlowEvent('fashionplace restart button pressed'); const urlParamsToRemove = ['ed6d4','b83d2','fmhid','be','r_ac','r_ds','r_du','r_ey','r_fr','r_hy','r_me','r_ra','r_re','r_sk','r_sm','r_te','r_un','r_wr', 'cnst','imupld', 'qni', 'qfc', 'qfl', 'fmc_shpr','qai_ds','qai_sk','qai_fn','qai_an','fmc_mnpg_d','fmc_mnpg_sc'] const urlParameters = window.location.search.replace('?','').split('&'); let urlString = '' urlParameters.forEach((parameterString)=>{ const urlParameterKey = parameterString.split('=')[0]; if (urlParamsToRemove.includes(urlParameterKey)){ // do nothing }else{ if (urlString == ''){ urlString += `?${parameterString}`; }else{ urlString += `&${parameterString}`; } } }) const baseUrl = window.location.href.split('?')[0]; window.history.replaceState('fmc_landing_page', '', `${baseUrl}${urlString}`); dermObj.backendData = undefined; dermObj.masks.images = {}; dermObj.pageControls.results_default.clearConcernLists(); dermObj.applyState(); //window.location.reload(); } dermObj.pageControls.results_default.regimen = {} dermObj.pageControls.results_default.regimen.currentIndex = 0; dermObj.pageControls.results_default.regimen.build = async ()=>{ if (dermObj.dioxideData.recommendedProducts.length == 6){ for (let regimenStep = 1; regimenStep < 7; regimenStep++){ try{ product = dermObj.dioxideData.recommendedProducts.filter((product) => {return product.regimen_index == regimenStep})[0]; productCard = document.querySelector(`#fmc_results_page_default .fmc_regimen_product_card[data-widget-regimen-index="${regimenStep-1}"]`); productCard.dataset.viewItemObserver = product.pimcore_id; productCard.dataset.itemViewed = false; productCard.querySelector('.fmc_regimen_title').dataset.widgetTextTerm = `regimen_step_${product.regimen_step}`; if (product.pimcore_id == 9211){ document.querySelector('#fmc_results_page_default .fmc_regimen_title').dataset.widgetTextTerm = `regimen_step_soothe`; } productCard.querySelector('.fmc_product_image').dataset.widgetProductImage = product.pimcore_id; productCard.querySelector('.fmc_product_name').dataset.widgetProductName = product.pimcore_id; productCard.querySelector('.fmc_product_tagline').dataset.widgetProductTagline = product.pimcore_id; productCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; const priceString = dermObj.makePriceString(product); productCard.querySelectorAll('.fmc_price_string').forEach((priceEl)=>{ priceEl.innerHTML = ` | ${priceString}`; }) productCard.querySelectorAll('.fmc_regimen_price_only').forEach((priceOnly)=>{ priceOnly.innerHTML = `${priceString}`; }) }catch(err){ console.log(`error in building regimen at step ${regimenStep} - `,err); document.querySelector('#fmc_results_page_default .fmc_results_regimen_section').style.display ="none"; } } }else{ document.querySelector('#fmc_results_page_default .fmc_results_regimen_section').style.display ="none"; } } dermObj.pageControls.results_default.regimen.back = async ()=>{ if (dermObj.pageControls.results_default.regimen.currentIndex > 0){ dermObj.pageControls.results_default.regimen.currentIndex--; dermObj.pageControls.results_default.regimen.focusStep() } } dermObj.pageControls.results_default.regimen.next = async ()=>{ if (dermObj.pageControls.results_default.regimen.currentIndex < 5){ dermObj.pageControls.results_default.regimen.currentIndex++; dermObj.pageControls.results_default.regimen.focusStep() } } dermObj.pageControls.results_default.regimen.gotoRegimenStep = async (regimenStep) => { dermObj.pageControls.results_default.regimen.currentIndex = regimenStep; dermObj.pageControls.results_default.regimen.focusStep(); } dermObj.pageControls.results_default.regimen.focusStep = async () => { await dermObj.pageControls.results_default.regimen.resize(); document.querySelectorAll('.fmc_regimen_product_slider').forEach( async (regimenSlider)=>{ regimenSlider.querySelectorAll('.fmc_regimen_product_card').forEach((prodCard)=>{ if (prodCard.dataset.widgetRegimenIndex == dermObj.pageControls.results_default.regimen.currentIndex){ prodCard.classList.add('fmc_selected'); }else{ prodCard.classList.remove('fmc_selected'); } }) }) document.querySelectorAll('#fmc_results_page_default .fmc_regimen_carousel_container .fmc_regimen_back_button').forEach((backButton)=>{ if (dermObj.pageControls.results_default.regimen.currentIndex == 0){ backButton.classList.add('fmc_inactive'); }else{ backButton.classList.remove('fmc_inactive'); } }) document.querySelectorAll('#fmc_results_page_default .fmc_regimen_carousel_container .fmc_regimen_next_button').forEach((nextButton)=>{ if (dermObj.pageControls.results_default.regimen.currentIndex == 5){ nextButton.classList.add('fmc_inactive'); }else{ nextButton.classList.remove('fmc_inactive'); } }) } dermObj.pageControls.results_default.regimen.resize = async () => { document.querySelectorAll('.fmc_regimen_product_slider').forEach( async (regimenSlider)=>{ if (dermObj.body.classList.contains('dml_mobile')){ const cardSpace = Math.min(dermObj.body.offsetWidth * 0.85,300); const sliderWidth = cardSpace * 6; const sliderOffset = 0.5*(dermObj.body.offsetWidth - cardSpace); regimenSlider.style.width = `${sliderWidth}px`; regimenSlider.style.left = `${-dermObj.pageControls.results_default.regimen.currentIndex * cardSpace + sliderOffset }px`; }else{ regimenSlider.style.width = `200%`; regimenSlider.style.left = `${-(dermObj.pageControls.results_default.regimen.currentIndex-1) * 100 / 3 }%`; } }) return; } dermObj.pageControls.results_default.regimen.swipeHandling = { touchStartX : 0, touchCurrentX : 0, allowTouchEvent : true } dermObj.pageControls.results_default.regimen.addSwipeDetection = async ()=>{ document.querySelectorAll('.fmc_regimen_product_card').forEach((prodCard) => { prodCard.addEventListener('touchstart',(evt)=>{ try{ dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX = evt.targetTouches[0].clientX; dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX = evt.targetTouches[0].clientX; }catch(e){console.error(e)} }) prodCard.addEventListener('touchmove',(evt)=>{ try{ dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX = evt.targetTouches[0].clientX; }catch(e){console.error(e)} }) prodCard.addEventListener('touchend',(evt)=>{ if (dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent && dermObj.body.classList.contains('dml_mobile')){ if (dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX - dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX > 30){ dermObj.pageControls.results_default.regimen.back(); dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = false; setTimeout(()=>{ dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = true; },500) } if (dermObj.pageControls.results_default.regimen.swipeHandling.touchCurrentX - dermObj.pageControls.results_default.regimen.swipeHandling.touchStartX < - 30){ dermObj.pageControls.results_default.regimen.next(); dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = false; setTimeout(()=>{ dermObj.pageControls.results_default.regimen.swipeHandling.allowTouchEvent = true; },500) } } }) }) } dermObj.pageControls.results_default.storeLocator = { storeIndex : 0, storeIndexLimit : 2, slider : dermObj.body.querySelector('#fmc_results_page_default #fmc_skin_center_container') } dermObj.pageControls.results_default.storeLocator.updateCarousel = async () => { if (dermObj.body.classList.contains('dml_mobile')){ const sliderWidth = Math.min(dermObj.body.offsetWidth*2.4, 800); const cardWidth = sliderWidth * 0.31; dermObj.pageControls.results_default.storeLocator.slider.style.left = `${-dermObj.pageControls.results_default.storeLocator.storeIndex * 0.345*sliderWidth + 0.5* (0.95*dermObj.body.offsetWidth - cardWidth)}px`; }else{ dermObj.pageControls.results_default.storeLocator.slider.style.left = "0px"; } } dermObj.pageControls.results_default.storeLocator.nextStore = async () => { if (!dermObj.body.classList.contains('dml_mobile')) return; if (dermObj.pageControls.results_default.storeLocator.storeIndex >= dermObj.pageControls.results_default.storeLocator.storeIndexLimit) return; dermObj.pageControls.results_default.storeLocator.storeIndex++; dermObj.pageControls.results_default.storeLocator.updateCarousel(); } dermObj.pageControls.results_default.storeLocator.prevStore = async () => { if (!dermObj.body.classList.contains('dml_mobile')) return; if (dermObj.pageControls.results_default.storeLocator.storeIndex < 1) return; dermObj.pageControls.results_default.storeLocator.storeIndex--; dermObj.pageControls.results_default.storeLocator.updateCarousel(); } dermObj.pageControls.prep_treat_glow = {}; dermObj.pageControls.prep_treat_glow.curConcernIndex = 0; dermObj.pageControls.prep_treat_glow.concernOrder = [] dermObj.pageControls.prep_treat_glow.build = async ()=>{ if (dermObj.dioxideData.prep_treat_glow == null || typeof dermObj.dioxideData.prep_treat_glow == 'undefined'){ dermObj.config.pageDict.results = 'fmc_estimated_results'; dermObj.gotoPage('results'); return; } dermObj.body.querySelector('#fmc_results_prep_treat_glow').style.opacity = 1; if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } const ptgPage = dermObj.body.querySelector('#fmc_results_prep_treat_glow'); if (dermObj.config.useNewUserKits == true && dermObj.dioxideData.prep_treat_glow.kit_nu != undefined){ try{ const kitData = dermObj.dioxideData.prep_treat_glow.kit_nu; const kitPimcoreId = kitData.pimcore_id; dermObj.productData[kitPimcoreId] = {...kitData}; ptgPage.classList.add('show-skin-kit') const kitProdCard = ptgPage.querySelector('#fmc_ptg_skin_kit') kitProdCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.dataset.widgetProductName = kitPimcoreId}); kitProdCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.dataset.widgetProductPrice = kitPimcoreId}); kitProdCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = kitPimcoreId; kitProdCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = kitPimcoreId; kitProdCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = kitPimcoreId; kitProdCard.dataset.viewItemObserver = kitPimcoreId kitProdCard.dataset.itemViewed = false; dermObj.applyProductData(dermObj.productData); }catch(err){ console.warn('error in PTG results build function in building kit data',err); } }else{ dermObj.pageControls.prep_treat_glow.updateProducts(); } try{ dermObj.pageControls.prep_treat_glow.concernOrder = await dermObj.pageControls.prep_treat_glow.getConcernOrder(); /* dermObj.pageControls.prep_treat_glow.concernOrder = dermObj.dioxideData.sortedConcerns.map((concern) => {return concern.concern_key}); if (dermObj.pageControls.prep_treat_glow.concernOrder[0] == 'dehydration'){ dermObj.pageControls.prep_treat_glow.concernOrder[0] = dermObj.pageControls.prep_treat_glow.concernOrder[1]; dermObj.pageControls.prep_treat_glow.concernOrder[1] = 'dehydration'; } */ }catch(err){ console.error(err) } const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; try{ const topConcern = dermObj.pageControls.prep_treat_glow.concernOrder[0]; dermObj.body.querySelectorAll('#fmc_results_prep_treat_glow .fmc_top_concern_only').forEach((el)=>{el.style.display = 'none'}); dermObj.body.querySelectorAll(`#fmc_results_prep_treat_glow .fmc_prep_treat_glow_slider_label_text.fmc_concern_${topConcern} .fmc_top_concern_only`).forEach((el)=>{el.style.display = 'inline-block'}); dermObj.pageControls.prep_treat_glow.selectConcern(topConcern); if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').style.display = 'flex'; //dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'inline-block'; } }catch(err){ console.error(err) } if (dermObj.masks.pending == false){ dermObj.masks.images = {}; try{ await dermObj.masks.getObscEyeRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.getCropRect(); }catch(err){ console.error(err); } try{ await dermObj.masks.makeOriginalImages(); }catch(err){ console.error('error in making original mask images - ',err) } if (dermObj.config.skipMasks){ dermObj.debug('SKIP MASKS PREP TREAT GLOW'); dermObj.masks.images.acne = dermObj.masks.images.original; dermObj.masks.images.acne_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.darkCircles = dermObj.masks.images.original; dermObj.masks.images.darkCircles_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.dehydration = dermObj.masks.images.original; dermObj.masks.images.dehydration_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.oiliness = dermObj.masks.images.original; dermObj.masks.images.oiliness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.redness = dermObj.masks.images.original; dermObj.masks.images.redness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.wrinkles = dermObj.masks.images.original; dermObj.masks.images.wrinkles_cropped = dermObj.masks.images.original_cropped; }else{ (async ()=>{ dermObj.masks.buildMasks(); })(); } dermObj.masks.applyImageData() } } dermObj.pageControls.prep_treat_glow.updateProducts = async (concernName)=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_results_prep_treat_glow #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.dataset.widgetProductName = product.pimcore_id}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.dataset.widgetProductPrice = product.pimcore_id}); prodCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = product.pimcore_id; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ if (dermObj.dioxideData.prep_treat_glow.ptg_id == 45 && dermObj.config.replacePTGcopy == true){ await replaceProductCopy(); } dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.prep_treat_glow.selectConcern = (concernIdIn)=>{ const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; const resultsPage = dermObj.body.querySelector('#fmc_results_prep_treat_glow'); const otherScoreLabel = resultsPage.querySelector('.fmc_other_users_label'); const yourScoreLabel = resultsPage.querySelector('.fmc_your_score_label'); const indBarGreyBlend = resultsPage.querySelector('.fmc_prep_treat_glow_indicator_bar_grey_blend'); resultsPage.classList.remove('fmc_concern_breakouts','fmc_concern_dark_circles','fmc_concern_wrinkles','fmc_concern_oiliness','fmc_concern_redness','fmc_concern_dehydration') switch (concernId){ case 'breakouts': resultsPage.classList.add('fmc_concern_breakouts'); otherScoreLabel.style.left = '18%'; if (dermObj.backendData.revieve_acne_value == 0 || dermObj.backendData.revieve_acne_value == null){ dermObj.backendData.revieve_acne_value = 0.18 } yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_acne_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_acne_value )}%`; break; case 'dark_circles': resultsPage.classList.add('fmc_concern_dark_circles'); otherScoreLabel.style.left = '45%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_eyes_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_eyes_value )}%`; break; case 'wrinkles': resultsPage.classList.add('fmc_concern_wrinkles'); otherScoreLabel.style.left = '27%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_wrinkles_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_wrinkles_value )}%`; break; case 'redness': resultsPage.classList.add('fmc_concern_redness'); otherScoreLabel.style.left = '23%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_redness_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_redness_value )}%`; break; case 'dehydration': resultsPage.classList.add('fmc_concern_dehydration'); otherScoreLabel.style.left = '30%'; yourScoreLabel.style.left = `35%`; indBarGreyBlend.style.width = `65%`; break; case 'oiliness': resultsPage.classList.add('fmc_concern_oiliness'); otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_skin_shine_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_skin_shine_value )}%`; break; default: resultsPage.classList.add('fmc_concern_oiliness'); otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * dermObj.backendData.revieve_skin_shine_value}%`; indBarGreyBlend.style.width = `${100 * ( 1 - dermObj.backendData.revieve_skin_shine_value )}%`; } } dermObj.pageControls.prep_treat_glow.redoAnalysis = () => { dermObj.debug('REDO ANALYSIS'); dermObj.sendGA360("main flow","redo analysis - prep treat glow"); dermObj.sendGAFlowEvent("redo analysis - prep treat glow"); dermObj.pageControls.waiting.reset(); dermObj.dioxideData = undefined; try{ dermObj.pageControls.qai.answerObj[dermObj.config.pageDict.quiz_after_image] = null; dermObj.pageControls.qai.urlParamAnswerArr = []; }catch(err){} dermObj.body.querySelector('#fmc_results_prep_treat_glow').classList.remove('show-skin-kit'); dermObj.removeUrlParameters('capture',['rspg','be']); dermObj.gotoPage('capture'); } dermObj.pageControls.prep_treat_glow.nextConcern = ()=>{ dermObj.pageControls.prep_treat_glow.curConcernIndex++; if (dermObj.pageControls.prep_treat_glow.curConcernIndex > dermObj.pageControls.prep_treat_glow.concernOrder.length - 1 ){ dermObj.pageControls.prep_treat_glow.curConcernIndex = 0; } const nextConcern = dermObj.pageControls.prep_treat_glow.concernOrder[dermObj.pageControls.prep_treat_glow.curConcernIndex]; dermObj.pageControls.prep_treat_glow.selectConcern(nextConcern); } dermObj.pageControls.prep_treat_glow.prevConcern = ()=>{ dermObj.pageControls.prep_treat_glow.curConcernIndex--; if (dermObj.pageControls.prep_treat_glow.curConcernIndex < 0 ){ dermObj.pageControls.prep_treat_glow.curConcernIndex = dermObj.pageControls.prep_treat_glow.concernOrder.length - 1; } const prevConcern = dermObj.pageControls.prep_treat_glow.concernOrder[dermObj.pageControls.prep_treat_glow.curConcernIndex]; dermObj.pageControls.prep_treat_glow.selectConcern(prevConcern); } dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = true; dermObj.pageControls.prep_treat_glow.addAllToCart = async ()=>{ if (dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag === true){ dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.prep_treat_glow.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_results_prep_treat_glow button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'none'; dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_results_prep_treat_glow button.fmc_add_all_to_cart').style.display = 'none'; dermObj.body.querySelector('#fmc_results_prep_treat_glow #fmc_prep_treat_glow_add_all_in_info').style.display = 'none'; } } } dermObj.pageControls.prep_treat_glow.getConcernOrder = async () => { return new Promise((resolve,reject) => { concernDeltas = {} if (dermObj.backendData.revieve_acne_value == 0 || dermObj.backendData.revieve_acne_value == null){ dermObj.backendData.revieve_acne_value = 0.18 } concernDeltas.breakouts = dermObj.backendData.revieve_acne_value - 0.18; concernDeltas.dark_circles = dermObj.backendData.revieve_eyes_value - 0.45; concernDeltas.wrinkles = dermObj.backendData.revieve_wrinkles_value - 0.27; concernDeltas.redness = dermObj.backendData.revieve_redness_value - 0.23; concernDeltas.oiliness = dermObj.backendData.revieve_skin_shine_value - 0.48; concernDeltas.dehydration = -0.2; const entries = Object.entries(concernDeltas); entries.sort((a, b) => b[1] - a[1]); const sortedKeys = entries.map(entry => entry[0]); //console.log('SORTED CONCERN LIST: ', sortedKeys); resolve(sortedKeys) }) } async function replaceProductCopy(){ return new Promise((resolve,reject) => { fetch('https://facemapping.me/ptg_cluster_copy/45.json') .then(response => { if (!response.ok) { throw new Error('Network response was not ok'); } return response.json(); }) .then(copyReplacementData => { let rvBreakoutsVal; if (dermObj.backendData.revieve_acne_value == 0 || dermObj.backendData.revieve_acne_value == null){ rvBreakoutsVal = 0.05; }else{ rvBreakoutsVal = dermObj.backendData.revieve_acne_value; } const rvHyperpigmentationVal = dermObj.backendData.revieve_hyperpigmentation_value; const rvRednessVal = dermObj.backendData.revieve_redness_value; let clusterAreaString = '' if (rvBreakoutsVal < 0.0293){ clusterAreaString='acne_low' }else if(rvBreakoutsVal < 0.0686){ clusterAreaString='acne_moderate' }else{ clusterAreaString='acne_high' } if (rvHyperpigmentationVal < 0.117){ clusterAreaString += '__hyperpigmentation_low'; }else if(rvBreakoutsVal < 0.301){ clusterAreaString += '__hyperpigmentation_moderate'; }else{ clusterAreaString += '__hyperpigmentation_high'; } if (rvRednessVal < 0.1619){ clusterAreaString += '__redness_low'; }else if(rvRednessVal < 0.2591){ clusterAreaString += '__redness_moderate'; }else{ clusterAreaString += '__redness_high'; } try{ Object.entries(copyReplacementData[clusterAreaString]).forEach(([pimcoreId, description]) => { try{ dermObj.productData[pimcoreId].mediumDescription = description; }catch(errInner){ console.error(errInner) } }) }catch(err){ console.error(err) } resolve(); }) .catch(error => { console.error('There was a problem with the fetch operation:', error); rejecT(error) }); }); } dermObj.pageControls.aiSteps = {}; const aiStepsPage = dermObj.body.querySelector('#fmc_results_ai_steps'); const concernRevMap = { breakouts: { revieve_key : "revieve_acne_value", fallback : 0.18 }, dark_circles: { revieve_key : "revieve_eyes_value", fallback : 0.45 }, redness: { revieve_key : "revieve_redness_value", fallback : 0.23 }, wrinkles: { revieve_key : "revieve_wrinkles_value", fallback : 0.27 }, dehydration :{ revieve_key : "revieve_dehydration", fallback : 0.35 }, oiliness :{ revieve_key : "revieve_skin_shine_value", fallback : 0.48 } } dermObj.pageControls.aiSteps.build = async () => { if (dermObj.dioxideData.ai_steps_data == null || typeof dermObj.dioxideData.ai_steps_data == 'undefined'){ dermObj.config.pageDict.results = 'fmc_estimated_results'; dermObj.gotoPage('results'); return; } Object.values(dermObj.dioxideData.ai_steps_data.am).forEach((stepData)=>{ const prodData = stepData.product; dermObj.productData[prodData.pimcore_id] = prodData; }) Object.values(dermObj.dioxideData.ai_steps_data.pm).forEach((stepData)=>{ const prodData = stepData.product; if (!Object.keys(dermObj.productData).includes(prodData.pimcore_id)){ dermObj.productData[prodData.pimcore_id] = prodData; } }) aiStepsPage.querySelector('#ai_steps_select_am_routine_btn').addEventListener('click',()=>{dermObj.pageControls.aiSteps.selectTab('am_routine');}); aiStepsPage.querySelector('#ai_steps_select_pm_routine_btn').addEventListener('click',()=>{dermObj.pageControls.aiSteps.selectTab('pm_routine');}); try{ if (dermObj.config.useTreatmentBanners == false || dermObj.dioxideData.skin_services == undefined || dermObj.dioxideData.skin_services.length < 1){ aiStepsPage.querySelector('#ai_steps_select_treatments_btn').style.pointerEvents = 'none'; aiStepsPage.querySelector('#ai_steps_select_treatments_btn').style.opacity = 0.1; }else{ aiStepsPage.querySelector('#ai_steps_select_treatments_btn').addEventListener('click',()=>{dermObj.pageControls.aiSteps.selectTab('treatments');}); } }catch(err){ console.error('error in setting up treatment banners - ',err) aiStepsPage.querySelector('#ai_steps_select_treatments_btn').style.pointerEvents = 'none'; aiStepsPage.querySelector('#ai_steps_select_treatments_btn').style.opacity = 0.1; } await dermObj.pageControls.aiSteps.addProducts(); await dermObj.applyProductData(dermObj.productData); await dermObj.renderTextData(dermObj.textData); if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } await dermObj.masks.getCropRect(); await dermObj.masks.makeOriginalImages(); if (dermObj.masks.images.original_cropped != undefined){ aiStepsPage.querySelectorAll('img.ai_steps_concern_user_image').forEach((faceImg)=> faceImg.src = dermObj.masks.images.original_cropped) } } dermObj.pageControls.aiSteps.selectTab = async function(tabName) { aiStepsPage.querySelector('#fmc_ai_steps_tabs_section').className = `fmc_tabs_display_${tabName}`; }; dermObj.pageControls.aiSteps.addProducts = async () => { const aiStepsAmData = dermObj.dioxideData.ai_steps_data.am; const aiStepsPmData = dermObj.dioxideData.ai_steps_data.pm; const amContainer = aiStepsPage.querySelector('#fmc_tabs_am_routine'); const pmContainer = aiStepsPage.querySelector('#fmc_tabs_pm_routine'); const productCardTemplate = aiStepsPage.querySelector('#ai_steps_product_template').content; function addProductCard(stepLabel, stepData, containerEl){ const prodData = stepData.product; const pimcoreId = prodData.pimcore_id; const prodCard = document.importNode(productCardTemplate, true); const mainConcern = stepData.concerns[0]; let userScore; try{ userScore = dermObj.backendData[concernRevMap[mainConcern].revieve_key] if (userScore == undefined || userScore == null){ dermObj.debug(`USING FALLBACK REVEIVE SCORE FOR ${mainConcern} with revieve key ${concernRevMap[mainConcern].revieve_key}`) userScore = concernRevMap[mainConcern].fallback } }catch(err){ dermObj.debug(`ERROR - USING FALLBACK REVEIVE SCORE FOR ${mainConcern} with revieve key ${concernRevMap[mainConcern].revieve_key}`) userScore = concernRevMap[mainConcern].fallback } prodCard.querySelector('.ai_steps_step_label').innerHTML = dermObj.textData.exact_phrases[stepLabel]; prodCard.querySelector('.ai_steps_plot_image').src = "https://facemapping.me/img/results/dummy_scatter_plot.png"; prodCard.querySelector('.ai_steps_prod_image').dataset.widgetProductImage = pimcoreId; prodCard.querySelector('.ai_steps_prod_name').dataset.widgetProductName = pimcoreId; prodCard.querySelector('.ai_steps_prod_price').dataset.widgetVariantPrice = pimcoreId; prodCard.querySelector('.ai_steps_prod_description').dataset.widgetProductDescription = pimcoreId; prodCard.querySelector('img.ai_steps_concern_user_image').style.left = `${10 + userScore * 80 - 10}%`; prodCard.querySelector('button.fmc_product_button').dataset.widgetProductBuy = pimcoreId; dermObj.pageControls.aiSteps.addVariantSelectorsToElement(prodCard, prodData.variants, pimcoreId); dermObj.pageControls.aiSteps.addConcernLabels(prodCard, stepData.concerns); containerEl.appendChild(prodCard); } for (let [stepLabel, stepData] of Object.entries(aiStepsAmData)){ addProductCard(stepLabel, stepData, amContainer) } for (let [stepLabel, stepData] of Object.entries(aiStepsPmData)){ addProductCard(stepLabel, stepData, pmContainer) } return; } dermObj.pageControls.aiSteps.addVariantSelectorsToElement = (prodCard, variantArray, pimcoreId)=>{ const containerEl = prodCard.querySelector('.ai_steps_variants'); containerEl.innerHTML = ''; //console.log('ADDING VARIANTS TO CONTAINER - ',containerEl) variantArray.forEach((variantObj)=>{ //console.log('ADDING VARIANT - ',variantObj.size); try{ const variantSelector = document.createElement('div'); variantSelector.className = 'ai_steps_variant_radio_wrapper' const variantRadioButton = document.createElement('div'); variantRadioButton.className = 'ai_steps_variant_radio_button'; variantRadioButton.innerHTML = '
'; if (variantObj.default == true){ variantRadioButton.classList.add('selected'); } variantRadioButton.dataset.pimId = pimcoreId; variantRadioButton.dataset.variantId = variantObj.shopify_variant_id; variantRadioButton.onclick = (evt)=>{ const radioButton = evt.target; if (radioButton.classList.contains('selected') == true) return; //console.log('CHANGE IN VARIANT SELECTION') containerEl.querySelector('.selected').classList.remove('selected'); radioButton.classList.add('selected'); const pimcoreId = radioButton.dataset.pimId; const variantId = radioButton.dataset.variantId; let newPrice; dermObj.productData[pimcoreId].variants = dermObj.productData[pimcoreId].variants.map((variantData) => { if (variantData.shopify_variant_id == variantId) { newPrice = variantData.price; return { ...variantData, selected: true }; } else { return { ...variantData, selected: false }; } }); dermObj.updateVariantData(dermObj.productData); } const variantRadioButtonLabel = document.createElement('span'); variantRadioButtonLabel.className = 'ai_steps_variant_radio_button_label'; variantRadioButtonLabel.innerHTML = variantObj.size; variantSelector.appendChild(variantRadioButton); variantSelector.appendChild(variantRadioButtonLabel); containerEl.appendChild(variantSelector); }catch(err){ console.log(err) } }) } dermObj.pageControls.aiSteps.addConcernLabels = (prodCard, concerns) => { const concernLabelContainer = prodCard.querySelector('.ai_steps_concern_labels_wrapper'); concerns.forEach((concern,index) => { const concernDiv = document.createElement('div'); concernDiv.classList.add('fmc_ai_steps_concern_label'); if (index == 0) concernDiv.classList.add('fmc_ai_steps_primary_concern'); let concernCopy; try{ concernCopy = dml_fmc.textData.concerns[concern]; if (concernCopy == undefined || concernCopy == ''){ concernCopy = concern; } }catch(err){ concernCopy = concern; } concernDiv.innerHTML = `${concernCopy}`; concernLabelContainer.appendChild(concernDiv); }) } dermObj.pageControls.brand_campaign = {}; dermObj.pageControls.brand_campaign.curConcernIndex = 0; dermObj.pageControls.brand_campaign.concernOrder = [] dermObj.pageControls.brand_campaign.proBrightLink = ''; dermObj.pageControls.brand_campaign.bookNowLink = ''; dermObj.pageControls.brand_campaign.cardTitleScaleFact = 1; dermObj.pageControls.brand_campaign.build = async () => { //dermObj.debug('BUILD BRAND CAMPAIGN') if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ dermObj.debug('using Dioxide Data from Backend'); dermObj.dioxideData ={... dermObj.backendData.dioxide_data}; } else { dermObj.debug('calling Dioxide for recommendations'); const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) const dioxRes = await dermObj.getDioxideRecommendations(dioxPayload) dermObj.dioxideData = dioxRes; } if (dermObj.dioxideData.brand_campaign == null || typeof dermObj.dioxideData.brand_campaign == 'undefined') { dermObj.config.pageDict.results = 'fmc_results_page_default'; dermObj.gotoPage('results'); return; } dermObj.pageControls.brand_campaign.adjustDropDownWidth(); window.addEventListener('resize',dermObj.pageControls.brand_campaign.adjustDropDownWidth) window.addEventListener('resize',dermObj.pageControls.brand_campaign.resizeCardImages) window.addEventListener('resize',dermObj.pageControls.brand_campaign.resizeCardTitles) const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (chatEnabled){ document.querySelector('#fmc_results_brand_campaign .fmc_contact_section').style.display = 'flex'; } dermObj.body.querySelector('#fmc_results_brand_campaign').style.opacity = 1; await dermObj.pageControls.brand_campaign.sortConcernsForBrandCampaign(); dermObj.pageControls.brand_campaign.concernOrder = dermObj.dioxideData.sortedBrandConcerns.map((concern) => {return concern.concern_key}); dermObj.debug(dermObj.pageControls.brand_campaign.concernOrder) if (dermObj.pageControls.brand_campaign.concernOrder[0] == "dehydration") { dermObj.pageControls.brand_campaign.concernOrder[0] = dermObj.pageControls.brand_campaign.concernOrder[1]; dermObj.pageControls.brand_campaign.concernOrder[1] = "dehydration"; } const topConcern = dermObj.pageControls.brand_campaign.concernOrder[0]; dermObj.dioxideData.brand_campaign.topConcern = topConcern; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_top_concern_only').forEach((el)=>{el.style.display = 'none'}); dermObj.body.querySelectorAll(`#fmc_results_brand_campaign .fmc_brand_campaign_slider_label_text.fmc_concern_${topConcern} .fmc_top_concern_only`).forEach((el)=>{el.style.display = 'inline-block'}); dermObj.pageControls.brand_campaign.raw_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header; dermObj.pageControls.brand_campaign.raw_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area; dermObj.textData.brand_campaign.brand_campaign_results_concern_header = dermObj.textData.brand_campaign.brand_campaign_results_concern_header.replace('__CONCERN__', `${dermObj.textData.concerns[topConcern]}`); dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area = dermObj.textData.brand_campaign.brand_campaign_results_concern_header_under_eye_area.replace('__CONCERN__', `${dermObj.textData.concerns.dark_circles}`); dermObj.textData.brand_campaign.brand_campaign_survey_question_one_new = dermObj.textData.brand_campaign.brand_campaign_survey_question_one_new.replace('__CONCERN__', dermObj.textData.concerns[topConcern]); dermObj.renderTextData(dermObj.textData); dermObj.pageControls.brand_campaign.selectTopConcern(topConcern, true); dermObj.masks.images = {}; try { await dermObj.masks.getObscEyeRect(); } catch(err){ console.error(err); } try { await dermObj.masks.getCropRect(); } catch(err){ console.error(err); } try { await dermObj.masks.makeOriginalImages(); } catch(err){ console.error('error in making original mask images - ',err) } if (dermObj.config.skipMasks) { dermObj.debug('SKIP MASKS BRAND CAMPAIGN'); dermObj.masks.images.acne = dermObj.masks.images.original; dermObj.masks.images.acne_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.darkCircles = dermObj.masks.images.original; dermObj.masks.images.darkCircles_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.dehydration = dermObj.masks.images.original; dermObj.masks.images.dehydration_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.oiliness = dermObj.masks.images.original; dermObj.masks.images.oiliness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.redness = dermObj.masks.images.original; dermObj.masks.images.redness_cropped = dermObj.masks.images.original_cropped; dermObj.masks.images.wrinkles = dermObj.masks.images.original; dermObj.masks.images.wrinkles_cropped = dermObj.masks.images.original_cropped; } else { (async ()=>{ dermObj.masks.buildMasks(); })(); } dermObj.masks.applyImageData(); if (dermObj.config.useTreatmentBanners && dermObj.dioxideData.skin_service != null && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } } dermObj.pageControls.brand_campaign.selectTopConcern = (concernIdIn, isAnalyzedTopConcern = false) => { const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; if (concernId == 'dark_circles'){ dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern_under_eye_area').style.display = 'inline'; dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern').style.display = 'none'; }else{ dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern_under_eye_area').style.display = 'none'; dermObj.body.querySelector('#fmc_brand_campaign_concerns_results_desc span.fmc_desc_beginning_top_concern').style.display = 'inline'; } dermObj.body.querySelector('#fmc_brand_campaign_top_concern_selected_text').innerHTML = dermObj.textData.concerns[concernIdIn]; dermObj.pageControls.brand_campaign.recomendationControls(concernIdIn) dermObj.pageControls.brand_campaign.selectConcernImage(concernIdIn); dermObj.pageControls.brand_campaign.curConcernIndex = dermObj.pageControls.brand_campaign.concernOrder.indexOf(concernIdIn); if (isAnalyzedTopConcern){ dermObj.sendGA360("main flow",`brand_campaign top concern - analysis - ${concernId}`); dermObj.sendGAFlowEvent(`brand_campaign top concern - analysis - ${concernId}`); }else{ dermObj.sendGA360("main flow",`brand_campaign top concern - userSelect - ${concernId}`); dermObj.sendGAFlowEvent(`brand_campaign top concern - userSelect - ${concernId}`); } dermObj.body.querySelectorAll('#fmc_results_brand_campaign button.fmc_product_button').forEach((prodBtn) => { if (prodBtn.classList.contains('dml_added_to_bag_button')){ prodBtn.classList.remove('dml_added_to_bag_button'); prodBtn.classList.add('dml_is_add_to_bag_button'); } }) //console.log("top concern: " + concernId) } dermObj.pageControls.brand_campaign.selectConcernImage = (concernIdIn)=>{ const concernId = concernIdIn == 'acne' ? 'breakouts' : concernIdIn; const resultsPage = dermObj.body.querySelector('#fmc_results_brand_campaign'); const otherScoreLabel = resultsPage.querySelector('.fmc_other_users_label'); const yourScoreLabel = resultsPage.querySelector('.fmc_your_score_label'); const indBarGreyBlend = resultsPage.querySelector('.fmc_brand_campaign_indicator_bar_grey_blend'); resultsPage.querySelectorAll('img[data-widget-concern-img-cropped]').forEach((concernImage) => { if (concernImage.dataset.widgetConcernImgCropped == concernIdIn){ concernImage.style.display = 'block'; }else{ concernImage.style.display = 'none'; } }) const brandCampaignData = dermObj.dioxideData.brand_campaign; resultsPage.querySelector('#fmc_brand_campaign_concern_image_label').innerHTML = dermObj.textData.concerns[concernIdIn]; switch (concernId){ case 'breakouts': otherScoreLabel.style.left = '18%'; if (brandCampaignData.acne.score == 0 || brandCampaignData.acne.score == null) { brandCampaignData.acne.score = 0.18; } yourScoreLabel.style.left = `${100 * brandCampaignData.acne.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.acne.score )}%`; break; case 'dark_circles': otherScoreLabel.style.left = '25%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dark_circles.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dark_circles.score )}%`; break; case 'wrinkles': otherScoreLabel.style.left = '27%'; yourScoreLabel.style.left = `${100 * brandCampaignData.wrinkles.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.wrinkles.score )}%`; break; case 'redness': otherScoreLabel.style.left = '23%'; yourScoreLabel.style.left = `${100 * brandCampaignData.redness.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.redness.score )}%`; break; case 'dehydration': otherScoreLabel.style.left = '20%'; yourScoreLabel.style.left = `25%`; indBarGreyBlend.style.width = `75%`; break; case 'dull_skin': otherScoreLabel.style.left = '34%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dull_skin.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dull_skin.score )}%`; break; case 'dark_spots': otherScoreLabel.style.left = '17%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dark_spots.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dark_spots.score )}%`; break; default: otherScoreLabel.style.left = '48%'; yourScoreLabel.style.left = `${100 * brandCampaignData.dull_skin.score}%`; indBarGreyBlend.style.width = `${100 * ( 1 - brandCampaignData.dull_skin.score )}%`; } } dermObj.pageControls.brand_campaign.nextConcern = ()=>{ dermObj.pageControls.brand_campaign.curConcernIndex++; if (dermObj.pageControls.brand_campaign.curConcernIndex > dermObj.pageControls.brand_campaign.concernOrder.length - 1 ){ dermObj.pageControls.brand_campaign.curConcernIndex = 0; } const nextConcern = dermObj.pageControls.brand_campaign.concernOrder[dermObj.pageControls.brand_campaign.curConcernIndex]; dermObj.pageControls.brand_campaign.selectConcernImage(nextConcern); } dermObj.pageControls.brand_campaign.prevConcern = ()=>{ dermObj.pageControls.brand_campaign.curConcernIndex--; if (dermObj.pageControls.brand_campaign.curConcernIndex < 0 ){ dermObj.pageControls.brand_campaign.curConcernIndex = dermObj.pageControls.brand_campaign.concernOrder.length - 1; } const prevConcern = dermObj.pageControls.brand_campaign.concernOrder[dermObj.pageControls.brand_campaign.curConcernIndex]; dermObj.pageControls.brand_campaign.selectConcernImage(prevConcern); } dermObj.pageControls.brand_campaign.ingredientsToggle = (evt) => { const toggleButton = evt.target; const dropDownContent = toggleButton.parentElement.parentElement.querySelector('.fmc_ingredients_dropdown_content'); const concernContainer = toggleButton.parentElement.parentElement.parentElement; if (toggleButton.innerText == "-") { dropDownContent.style.ight = `0px`; toggleButton.innerText = "+"; } else { concernContainer.querySelectorAll('.fmc_ingredients_dropdown').forEach( (ingredientItem) => { const itemDropDownContent = ingredientItem.querySelector('.fmc_ingredients_dropdown_content'); const itemToggleButton = ingredientItem.querySelector('.fmc_ingredients_btn'); if (itemDropDownContent == dropDownContent) { const maxHeightString = `${itemDropDownContent.querySelector('p').getBoundingClientRect().height}px`; itemDropDownContent.style.maxHeight = maxHeightString; itemToggleButton.innerText = "-"; } else { itemDropDownContent.style.maxHeight = `0px`; itemToggleButton.innerText = "+"; } }); } concernContainer.querySelectorAll('.fmc_ingredients_dropdown').forEach((ingredientItem) => { const itemToggleButton = ingredientItem.querySelector('.fmc_ingredients_btn'); if (itemToggleButton.innerText == "-") { itemToggleButton.style.transform = 'scaleX(1.5)'; } else { itemToggleButton.style.transform = 'scaleX(1)'; } }) } dermObj.pageControls.brand_campaign.ingredients_OLD = (ingredient) => { const content = dermObj.body.querySelectorAll(".fmc_ingredients_dropdown_content"); const toggleBtns = dermObj.body.querySelectorAll(".fmc_ingredients_btn"); let toggle; for (let i = 0; i < content.length; i++) { if (content[i].classList.contains(ingredient)) toggle = i; } if (toggleBtns[toggle].innerText == "-") { content[toggle].style.maxHeight = `0px`; toggleBtns[toggle].innerText = "+"; } else { content.forEach( (el, index) => { if (index == toggle) { const maxHeightString = `${content[toggle].querySelector('p').getBoundingClientRect().height}px`; el.style.maxHeight = maxHeightString; toggleBtns[index].innerText = "-"; } else { el.style.maxHeight = `0px`; toggleBtns[index].innerText = "+"; } }); } } //called on load and on toggle dermObj.pageControls.brand_campaign.recomendationControls = (concern, onLoad) => { const concernDesc = document.querySelector('#fmc_brand_campaign_concerns_results_desc'); const topConcernOptions = document.querySelectorAll('.fmc_brand_campaign_top_concern_value'); const concernInfo = concernDesc.querySelectorAll('.fmc_brand_campaign_concern'); if (dml_fmc.pageControls.brand_campaign.concernOrder[0] == concern) { dermObj.body.querySelector('.brand_campaign_our_analysis_wrapper').style.display = 'inline'; dermObj.body.querySelector('.fmc_desc_beginning_user_choice').style.display = 'none'; //let concernText = document.querySelector('.fmc_desc_beginning_top_concern').innerText; //document.querySelector('.fmc_desc_beginning_top_concern').innerHTML = concernText.replace('__CONCERN__', `${concern}`); } else { document.querySelector('.fmc_desc_beginning_top_concern').style.display = 'none'; document.querySelector('.fmc_desc_beginning_user_choice').style.display = 'inline'; } concernInfo.forEach((desc) => { if (!desc.classList.contains(`fmc_concern_${concern}`)) { desc.style.display = 'none'; } else { desc.style.display = 'inline'; } }) for (let ii=0; ii < 2; ii++){ const stepLabel = ii == 0 ? 'one_product': 'kit'; const prodCard = dermObj.body.querySelector(`#fmc_results_brand_campaign #fmc_brand_campaign_card_${stepLabel}`); let product = dermObj.dioxideData.brand_campaign[concern][stepLabel]; if (Array.isArray(product) ) product = product[0]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelector('.fmc_product_name').dataset.widgetProductName = product.pimcore_id; prodCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = product.pimcore_id; prodCard.querySelectorAll('.fmc_product_price').forEach((priceEl)=>{ priceEl.innerHTML = ` | ${dermObj.makePriceString(product)}`; }) prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 1){ dermObj.applyProductData(dermObj.productData); setTimeout(()=>{ dermObj.pageControls.brand_campaign.resizeCardImages(); dermObj.pageControls.brand_campaign.resizeCardTitles(); },50) } } const ingredientDropdowns = document.querySelectorAll(".fmc_ingredients_dropdown_list"); ingredientDropdowns.forEach(list => { if (list.classList.contains(`fmc_ingredients_dropdown_${concern}`)) { list.classList.add('fmc_active'); } else { list.classList.remove('fmc_active'); } }); if (Object.keys(dermObj.blogs.concernBlogs).indexOf(concern) > -1){ const blogCards = document.querySelectorAll('.fmc_blog_card'); blogCards.forEach((card, index) => { card.querySelector('.fmc_blog_img').style.backgroundImage = `url('${dermObj.blogs.concernBlogs[concern][index].image_url}')`; card.dataset.blogUrl = dermObj.blogs.concernBlogs[concern][index].url; card.querySelector('.fmc_blog_title').innerText = dermObj.blogs.concernBlogs[concern][index].title; }); dermObj.body.querySelector('#fmc_brand_campaign_blog_section').style.display = "flex"; }else{ dermObj.body.querySelector('#fmc_brand_campaign_blog_section').style.display = "none"; } const surveySelectConcerns = document.querySelectorAll('.brand_campaign_survey_concern'); //if (onLoad) { // surveySelectConcerns.forEach((option) => { // console.log(concern) // if (option.value == concern) { // option.selected = 'selected'; // } // }); // } } dermObj.pageControls.brand_campaign.surveyControls = async (evt) => { dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_brand_campaign_survey_submit').classList.remove('fmc_disabled'); const questionTwoAns = dermObj.body.querySelectorAll('#fmc_survey_container .fmc_survey_response_btn'); const pressedButton = evt.target; questionTwoAns.forEach( (btn) => { if(btn == pressedButton) { btn.classList.add('fmc_survey_response_selected'); } else { btn.classList.remove('fmc_survey_response_selected'); } }); } dermObj.pageControls.brand_campaign.sendSurvey = async (evt) => { const questionOneVal = dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_survey_container #fmc_survey_answers').value; const questionTwoVal = dermObj.body.querySelector('#fmc_results_brand_campaign .fmc_survey_response_btn.fmc_survey_response_selected').dataset.value; const xhr = new XMLHttpRequest(); let payload = { "hashid": dermObj.backendData.hashid, "feedback_data": { "surveyQuestionOne": { "question": `Our analysis highlighted ${dermObj.pageControls.brand_campaign.concernOrder[0]} as your main skin concern. What would you have said?`, // TODO questions should be replaced with keyword "response": questionOneVal }, "surveyQuestionTwo": { "question": "Did your results feel personalized and helpful?", // TODO questions should be replaced with keyword "response": questionTwoVal } } } xhr.onreadystatechange = () => { if (xhr.readyState === 4) { dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_brand_campaign_survey_submit').classList.add('fmc_done'); dermObj.body.querySelector('#fmc_results_brand_campaign #fmc_survey_container #fmc_survey_answers').style.pointerEvents = 'none'; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_survey_response_btn').forEach((btn)=> {btn.style.pointerEvents = 'none';}) dermObj.debug(xhr.response); } } xhr.open('POST', 'https://fmc-backend-staging.herokuapp.com/fmc/add_fmc_feedback',true); xhr.send(JSON.stringify(payload)); //document.querySelector('#fmc_brand_campaign_survey_notice').style.display = "none"; //submitBtns[0].style.display = "none"; //submitBtns[1].style.display = "block"; dermObj.pageControls.brand_campaign.hideSurveyOnSubmit(evt); } dermObj.pageControls.brand_campaign.hideSurveyOnSubmit = () => { //document.querySelector('#fmc_brand_campaign_survey_section').classList.add("fmc_brand_campaign_survey_section_closed"); document.querySelector('#fmc_brand_campaign_survey_section').style.display = 'none'; } dermObj.pageControls.brand_campaign.openConcernsDropdown = () => { function closeDropDown(){ const dropdownMenu = document.querySelector('#fmc_brand_campaign_top_concern'); const dropdownBtn = document.querySelector('#fmc_concerns_expand_arrow'); dropdownMenu.style.maxHeight = "0"; //dropdownMenu.style.transition = "max-height 0.15s ease-out;"; dropdownBtn.style.transform = "rotate(-90deg)"; dropdownMenu.style.overflow = "hidden"; window.removeEventListener('click', closeDropDown ) setTimeout(()=>{ dropdownMenu.style.border = "none"; },250) } const dropdownMenu = document.querySelector('#fmc_brand_campaign_top_concern'); const dropdownBtn = document.querySelector('#fmc_concerns_expand_arrow'); if (dropdownBtn.style.transform == "rotate(-90deg)") { dropdownMenu.style.maxHeight = `${(dermObj.pageControls.brand_campaign.concernOrder.length + 1) * 60 + document.getElementById("brand_campaign_results_dropdown_text").offsetHeight }px`; dropdownMenu.style.transition = "max-height 0.25s ease-in-out"; dropdownBtn.style.transform = "rotate(90deg)" dropdownMenu.style.border = "1px solid #5e93db"; dropdownMenu.style.borderTop = "none"; dropdownMenu.style.overflow = "scroll"; setTimeout(()=> { window.addEventListener('click', closeDropDown ) },100) } } dermObj.pageControls.brand_campaign.sortConcernsForBrandCampaign = async () => { return new Promise((resolve, reject)=>{ dermObj.dioxideData.unsortedBrandConcerns = []; const brand_concerns = dermObj.dioxideData.brand_campaign; Object.keys(brand_concerns).forEach((concernKey)=> { brand_concerns[concernKey].name = concernKey; brand_concerns[concernKey].concern_key = concernKey; switch(concernKey){ case "acne": brand_concerns[concernKey].score = dermObj.backendData.revieve_acne_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_circles": brand_concerns[concernKey].score = dermObj.backendData.revieve_eyes_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dark_spots": brand_concerns[concernKey].score = dermObj.backendData.revieve_dark_spots_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dehydration": brand_concerns[concernKey].score = 0.25; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "dull_skin": brand_concerns[concernKey].score = dermObj.backendData.revieve_dull_skin_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "redness": brand_concerns[concernKey].score = dermObj.backendData.revieve_redness_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; case "wrinkles": brand_concerns[concernKey].score = dermObj.backendData.revieve_wrinkles_value; dermObj.dioxideData.unsortedBrandConcerns.push(brand_concerns[concernKey]) break; } }) dermObj.dioxideData.sortedBrandConcerns = dermObj.dioxideData.unsortedBrandConcerns.sort((a,b) => {return b.score - a.score}); resolve(); }) } dermObj.pageControls.brand_campaign.openBlog = (evt) => { let blogCard = evt.target; let stopCounter = 0; while (!blogCard.classList.contains('fmc_blog_card') && stopCounter < 5){ blogCard = blogCard.parentElement; stopCounter++; } const blogUrl = blogCard.dataset.blogUrl; window.open(blogUrl, '_blank'); } dermObj.pageControls.brand_campaign.openBookNow = () => { window.open(dermObj.pageControls.brand_campaign.bookNowLink, '_blank'); } dermObj.pageControls.brand_campaign.adjustDropDownWidth = ()=>{ const headerTextEl = dermObj.body.querySelector('#fmc_results_brand_campaign_subtitle'); const dropDownEl = dermObj.body.querySelector('#fmc_brand_campaign_top_concern_dropdown'); if (headerTextEl.offsetWidth > 0){ dropDownEl.style.maxWidth = `${headerTextEl.offsetWidth}px`; }else{ let counter = 0; const widthInterval = setInterval(()=>{ if (headerTextEl.offsetWidth > 0){ clearInterval(widthInterval); dropDownEl.style.maxWidth = `${headerTextEl.offsetWidth}px`; } if (counter > 50){ clearInterval(widthInterval); } counter++; },100) } } dermObj.pageControls.brand_campaign.resizeCardImages = () =>{ dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_img').forEach((imgDiv) => { if (dermObj.body.offsetWidth > 768){ imgDiv.style.maxHeight = `${dermObj.body.offsetWidth * 0.2}px`; }else{ imgDiv.style.maxHeight = `${dermObj.body.offsetWidth * 0.5}px`; } }) } dermObj.pageControls.brand_campaign.resizeCardTitles = () =>{ let maxTitleWidth = 0; let cardWidth = 0; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_title').forEach((cardTitle) => { cardWidth = cardTitle.parentElement.offsetWidth; maxTitleWidth = Math.max(maxTitleWidth / dermObj.pageControls.brand_campaign.cardTitleScaleFact, cardTitle.offsetWidth) }) dermObj.pageControls.brand_campaign.cardTitleScaleFact = cardWidth/maxTitleWidth; dermObj.body.querySelectorAll('#fmc_results_brand_campaign .fmc_brand_campaign_product_card_title').forEach((cardTitle) => { cardTitle.style.transform = `scale(${dermObj.pageControls.brand_campaign.cardTitleScaleFact})`; }) } dermObj.pageControls.quiz_no_image_results = {}; dermObj.pageControls.quiz_no_image_results.build = async ()=>{ dermObj.dioxideData = dermObj.backendData.dioxide_data; if (window.dml_dmlqz != undefined && dermObj.dioxideAllProducts != undefined){ try{ dermObj.pageControls.quiz_no_image_results.isUnsureSkin = dml_dmlqz.surveyResults.q1.includes('not_sure') // DISABLED CHECK IF UNSURE IS THE ONLY ANSWER && dml_dmlqz.surveyResults.q1.length == 1; if (dermObj.pageControls.quiz_no_image_results.isUnsureSkin){ const notSureProduct = 22900; const notSureProdDataArr = dermObj.dioxideAllProducts.filter((prod) => {return prod.pimcoreId == notSureProduct}); if (notSureProdDataArr.length == 1){ notSureProdData=notSureProdDataArr[0]; dermObj.productData[notSureProduct] = {...notSureProdData}; dermObj.body.querySelector('#fmc_results_quiz_no_image .fmc_results_product_section').classList.add('is_discover_kit') const kitProdCard = dermObj.body.querySelector('#fmc_results_quiz_no_image #fmc_qni_discover_skin_kit') kitProdCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.dataset.widgetProductName = notSureProduct}); kitProdCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.dataset.widgetProductPrice = notSureProduct}); kitProdCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = notSureProduct; kitProdCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = notSureProduct; kitProdCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = notSureProduct; kitProdCard.dataset.viewItemObserver = notSureProduct kitProdCard.dataset.itemViewed = false; dermObj.applyProductData(dermObj.productData); dermObj.body.querySelector('#fmc_results_quiz_no_image').style.opacity = 1; if (dermObj.config.useTreatmentBanners === true && dermObj.dioxideData.skin_services != undefined && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } return; } } }catch(err){ console.warn('error in QNI results build function in checking for quiz results',err); } } /* if (dermObj.dioxide == 'http://127.0.0.1:8000' || dermObj.dioxide == 'https://dioxide-staging.herokuapp.com'){ try{ const quizRecommendations = await dermObj.getDioxideQuizNoImageRecommendation(dml_dmlqz.surveyResults); dermObj.debug('quizRecommendations: ',quizRecommendations) dermObj.dioxideData.prep_treat_glow = {...quizRecommendations.prep_treat_glow}; }catch(err){ console.error(err); } } */ dermObj.body.querySelector('#fmc_results_quiz_no_image').style.opacity = 1; dermObj.pageControls.quiz_no_image_results.updateProducts(); const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; dermObj.productData[dermObj.dioxideData.prep_treat_glow.prep.pimcore_id] = dermObj.dioxideData.prep_treat_glow.prep; dermObj.productData[dermObj.dioxideData.prep_treat_glow.treat.pimcore_id] = dermObj.dioxideData.prep_treat_glow.treat; dermObj.productData[dermObj.dioxideData.prep_treat_glow.glow.pimcore_id] = dermObj.dioxideData.prep_treat_glow.glow; if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').style.display = 'flex'; } if (dermObj.config.useTreatmentBanners === true && dermObj.dioxideData.skin_services != undefined && dermObj.countryCode == 'US' ){ dermObj.treatments.updateBanners(); } } dermObj.pageControls.quiz_no_image_results.updateProducts = async ()=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_results_quiz_no_image #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.dataset.widgetProductName = product.pimcore_id}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.dataset.widgetProductPrice = product.pimcore_id}); prodCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = product.pimcore_id; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = true; dermObj.pageControls.quiz_no_image_results.addAllToCart = async ()=>{ if (dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag === true){ dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.quiz_no_image_results.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_results_quiz_no_image button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_results_quiz_no_image button.fmc_add_all_to_cart').style.display = 'none'; } } } dermObj.pageControls.estimatedResults = {}; dermObj.pageControls.estimatedResults.build = async ()=>{ const dioxRes = await dermObj.getEstimatedDioxideRecommendations(); dermObj.dioxideData = dioxRes; dermObj.body.querySelector('#fmc_estimated_results').style.opacity = 1; dermObj.pageControls.estimatedResults.updateProducts(); const prepProdName = dermObj.dioxideData.prep_treat_glow.prep.name; const treatProdName = dermObj.dioxideData.prep_treat_glow.treat.name; const glowProdName = dermObj.dioxideData.prep_treat_glow.glow.name; dermObj.productData[dermObj.dioxideData.prep_treat_glow.prep.pimcore_id] = dermObj.dioxideData.prep_treat_glow.prep; dermObj.productData[dermObj.dioxideData.prep_treat_glow.treat.pimcore_id] = dermObj.dioxideData.prep_treat_glow.treat; dermObj.productData[dermObj.dioxideData.prep_treat_glow.glow.pimcore_id] = dermObj.dioxideData.prep_treat_glow.glow; if (dermObj.config.useShopify === true){ dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').style.display = 'flex'; } if (window.location.search == ''){ window.history.pushState('fmc_estimated_results', '', `${window.location.href}?estr=1`); }else{ if (window.location.search.indexOf('estr=') == -1 && window.location.search.indexOf('rspg=estr') == -1){ window.history.pushState('fmc_results_quiz_no_image', '', `${window.location.href}&estr=1`); } } } dermObj.pageControls.estimatedResults.updateProducts = async ()=>{ let selectedProdIndices = [] for (let ii=0; ii < 3; ii++){ let stepLabel; switch (ii){ case 0: stepLabel='prep'; break; case 1: stepLabel='treat'; break; case 2: stepLabel='glow'; break; } const prodCard = document.querySelector(`#fmc_estimated_results #fmc_prep_treat_glow_card_${stepLabel}`); const product = dermObj.dioxideData.prep_treat_glow[stepLabel]; dermObj.productData[product.pimcore_id] = product; prodCard.querySelectorAll('.fmc_product_name').forEach((prodNameEl) => {prodNameEl.dataset.widgetProductName = product.pimcore_id}); prodCard.querySelectorAll('.fmc_product_price').forEach((prodPriceEl) => {prodPriceEl.dataset.widgetProductPrice = product.pimcore_id}); prodCard.querySelector('.fmc_product_description').dataset.widgetProductDescription = product.pimcore_id; prodCard.querySelector('.fmc_product_button').dataset.widgetProductBuy = product.pimcore_id; prodCard.querySelector('.fmc_product_image').dataset.widgetProductBackground = product.pimcore_id; prodCard.dataset.viewItemObserver = product.pimcore_id; prodCard.dataset.itemViewed = false; if (ii == 2){ dermObj.applyProductData(dermObj.productData); } } } dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = true; dermObj.pageControls.estimatedResults.addAllToCart = async ()=>{ if (dermObj.pageControls.estimatedResults.allowAddAllToCartFlag === true){ dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = false; setTimeout(()=>{ dermObj.pageControls.estimatedResults.allowAddAllToCartFlag = true; },500) dermObj.sendGA360("main flow",'add all to cart button clicked'); dermObj.sendGAFlowEvent('add all to cart button clicked'); const variantIdArray = []; dermObj.body.querySelectorAll('#fmc_estimated_results button.fmc_product_button').forEach(async (buyButton, index)=>{ const variantId = dermObj.productData[buyButton.dataset.widgetProductBuy].variants.filter((variantObj) => variantObj.default === true)[0].shopify_variant_id; variantIdArray.push(variantId) }) try{ await dermObj.addMultipleToBagShopify( variantIdArray); dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').classList.add('fmc_added_to_cart'); }catch(err){ console.error(err); dermObj.debug('hiding add all to cart buttons'); dermObj.body.querySelector('#fmc_estimated_results button.fmc_add_all_to_cart').style.display = 'none'; } } } dermObj.pageControls.perc_match_coll = {}; dermObj.pageControls.perc_match_coll.percMatchFailed = false; dermObj.pageControls.perc_match_coll.estProdsDefault = { "cleanser" : 9125, "exfoliant" : 9137, "moisturizer" : 9142, "masque" : 13136, "toner" : 9131, "spf" : 9178, "facial_oil_or_serum" : 9297, "eye_treatment": 11322 } dermObj.pageControls.perc_match_coll.estProds= {} dermObj.pageControls.perc_match_coll.build = async () => { window.fmc_collections_complete = true; try{ if (dermObj.miniPageSettings.estProds != undefined && dermObj.miniPageSettings.estProds != null){ dermObj.pageControls.perc_match_coll.estProds = JSON.parse(dermObj.miniPageSettings.estProds); } }catch(err){} if (dermObj.miniPageSettings.oncePerCollPage == true){ try{ dermObj.setLocalStorageWithExp(`dml_fmc_coll_${dermObj.miniPageSettings.collectionType}`,1); }catch(err){} } let prodTypeCopyElArr = dermObj.body.querySelectorAll('#fmc_perc_match_coll_prod_type'); let prodTypeCopy = ''; if (dermObj.miniPageSettings.collectionType != undefined){ if (dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != undefined && dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != null && dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] != ''){ prodTypeCopy = dermObj.textData.exact_phrases[dermObj.miniPageSettings.collectionType] }else{ prodTypeCopy = dermObj.textData.exact_phrases.product; } }else{ prodTypeCopy = dermObj.textData.exact_phrases.product; } prodTypeCopyElArr.forEach((copyEl) => { copyEl.innerHTML = prodTypeCopy; }) const pimcoreId = await dermObj.pageControls.perc_match_coll.getPimcoreIdToDisplay(); let miniPage = dermObj.body.querySelector('#fmc_results_page_perc_match_coll') miniPage.querySelector('.fmc_product_card').dataset.viewItemObserver = pimcoreId; miniPage.querySelector('.fmc_product_image').dataset.widgetProductBackground = pimcoreId; miniPage.querySelector('.fmc_product_name').dataset.widgetProductName = pimcoreId; miniPage.querySelector('.fmc_product_tagline').dataset.widgetProductTagline = pimcoreId; miniPage.querySelector('.fmc_product_description').dataset.widgetProductDescription = pimcoreId; miniPage.querySelector('button.fmc_product_button').dataset.widgetProductBuy = pimcoreId; if (dermObj.miniPageSettings.headerCopyToUse != undefined){ miniPage.querySelector('p.fmc_results_section_title').innerHTML = dermObj.miniPageSettings.headerCopyToUse; } let infoCopy = dermObj.textData.results_collection_mini_page.collection_mini_page_info_copy; if (dermObj.miniPageSettings.infoCopyToUse != undefined){ infoCopy = dermObj.miniPageSettings.infoCopyToUse; } infoCopy = infoCopy.replace(/__PRODUCTNAME__/g,``).replace(/__PRODUCTCATEGORY__/g, prodTypeCopy); dermObj.body.querySelector('#fmc_coll_page_info_hint').innerHTML = infoCopy; let checkFmcLinkInterval = setInterval(()=>{ if (dermObj.fmcResultsUrl != ''){ clearInterval(checkFmcLinkInterval); dermObj.body.querySelectorAll('.fmc_coll_page_fmc_link').forEach((fmcLink)=>{ fmcLink.setAttribute('href',dermObj.fmcResultsUrl); }) } },100) dermObj.productData = {} dermObj.dioxideAllProducts.forEach((dioxProd) => { if (dioxProd.pimcoreId == pimcoreId){ dermObj.productData[pimcoreId] = {...dioxProd} } }); try{ if (dermObj.productData[pimcoreId].mediumDescription == undefined || dermObj.productData[pimcoreId].mediumDescription == null || dermObj.productData[pimcoreId].mediumDescription == ''){ miniPage.querySelector('.fmc_product_description').style.display="none"; }else{ miniPage.querySelector('.fmc_product_description').style.display="block"; } }catch(err){console.error(err)} dermObj.applyProductData(dermObj.productData); try{ dermObj.queueUrlParameters({ptg_id:dermObj.dioxideData.prep_treat_glow.ptg_id}); }catch(err){ console.error(err) } try{ if (dermObj.pageControls.perc_match_coll.percMatchFailed == true){ miniPage.querySelector('a.fmc_coll_page_fmc_link').style.display = 'none'; dermObj.queueUrlParameters({fmc_mnpg_sc:0}); window.fmc_collections_df = true; }else{ dermObj.queueUrlParameters({fmc_mnpg_sc:1}); } }catch(err){} try{ // observe add to bag button const buyButton = miniPage.querySelector('button.fmc_product_button'); const classObserver = new MutationObserver((mutationsList, observer) => { for(var mutation of mutationsList) { if (mutation.type === 'attributes' && mutation.attributeName === 'class') { if (buyButton.classList.contains('dml_added_to_bag_button')) { try{ if (window.dsrp != undefined && window.dsrp.miniFmc != undefined && window.dsrp.miniFmc.doubleGridContainer != undefined){ window.dsrp.miniFmc.doubleGridContainer.remove(); } document.querySelectorAll('#dml_widget_wrapper').forEach((wrapperEl)=> { wrapperEl.style.transition = 'opacity 1s'; wrapperEl.style.opacity = 1; setTimeout(()=>{ wrapperEl.style.opacity = 0; },1000) setTimeout(()=>{ wrapperEl.remove(); },2500) }); }catch(err){} observer.disconnect(); } } } }) classObserver.observe(buyButton, { attributes: true, attributeOldValue: true }); //dml_added_to_bag_button ///dml_is_pending }catch(err){ console.error(err) } } dermObj.pageControls.perc_match_coll.checkForPercMatchData = () => { return new Promise((resolve,reject) => { let checkInterval = setInterval(()=>{ if (dermObj.percMatchData == undefined || dermObj.percMatchData == null) return; if (Object.keys(dermObj.percMatchData).length < 1) return; clearInterval(checkInterval); resolve(); },50); }); } dermObj.pageControls.perc_match_coll.getPimcoreIdToDisplay = async ()=> { return new Promise(async (resolve,reject)=>{ if (dermObj.pageControls.perc_match_coll.percMatchFailed == true){ try{ let pimcoreId; if (dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != undefined && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != null && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != 0){ pimcoreId = dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType]; }else{ pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; } resolve(pimcoreId); }catch(err){ let pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; resolve(pimcoreId); } }else{ let shopIdsOnPage; try{ shopIdsOnPage = JSON.parse(dermObj.miniPageSettings.productsOnPage); }catch(err){ console.error(err) } try{ await dermObj.pageControls.perc_match_coll.checkForPercMatchData(); }catch(err){console.error(err)} let matchingProducts = {}; shopIdsOnPage.forEach((prodId)=>{ if (dermObj.percMatchData.hasOwnProperty(prodId)){ const inDioxide = dermObj.dioxideAllProducts.some((prod) => prod.shopify_id == prodId) if (inDioxide == true){ matchingProducts[prodId] = dermObj.percMatchData[prodId]; } } }) let matchingProductsSorted = {}; if (Object.keys(matchingProducts).length > 0){ matchingProductsSorted = Object.fromEntries( Object.entries(matchingProducts).sort(([, a], [, b]) => b - a) ); } if (Object.keys(matchingProductsSorted).length > 0){ let bestFitId = Object.keys(matchingProductsSorted)[0]; let dioxideMatches = dermObj.dioxideAllProducts.filter((obj) => obj.shopify_id == bestFitId); let pimcoreId; if (dioxideMatches.length > 0){ pimcoreId = dioxideMatches[0].pimcoreId; }else{ pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; console.warn(`WARNING - shopify id not found in dioxide all products for ${bestFitId}`); } resolve(pimcoreId); }else{ try{ let pimcoreId; if (dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != undefined && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != null && dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType] != 0){ pimcoreId = dermObj.pageControls.perc_match_coll.estProds[dermObj.miniPageSettings.collectionType]; }else{ pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; } resolve(pimcoreId); }catch(err){ let pimcoreId = dermObj.pageControls.perc_match_coll.estProdsDefault[dermObj.miniPageSettings.collectionType]; resolve(pimcoreId); } } } }) } dermObj.gotoPage = async (pageIdKey)=>{ if (dermObj.tmDt.firstPageCall == undefined){ dermObj.tmDt.firstPageCall = Date.now() - dermObj.stTmStmp; } if (pageIdKey == 'waiting'){ if (dermObj.dioxideData != null && dermObj.dioxideData != undefined){ if (dermObj.config.quizNoImage != true){ try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) //dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); //dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ console.error('error in refining backend dioxide data - ',err); if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } }else{ dermObj.dioxideData = {...dermObj.backendData.dioxide_data}; } dermObj.gotoPage('results'); return; }else{ let resultsFinishTimeout = 40000; let intervalStep = 500; let intervalTotalTime = 0; let resultsFinishedInterval = setInterval(async ()=>{ if ((dermObj.backendData != null && dermObj.backendData != undefined)){ clearInterval(resultsFinishedInterval); if (dermObj.config.quizNoImage != true){ try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ console.error('error in refining backend dioxide data - ',err); if (dermObj.isPercMatchMiniPage != true){ dermObj.config.pageDict.results = 'fmc_estimated_results'; }else{ dermObj.pageControls.perc_match_coll.percMatchFailed = true; } } }else{ dermObj.dioxideData = {...dermObj.backendData.dioxide_data}; } dermObj.gotoPage('results'); return; } if (dermObj.analyzeRequestStatus == 'failed' ){ clearInterval(resultsFinishedInterval); } if (intervalTotalTime >= resultsFinishTimeout ){ clearInterval(resultsFinishedInterval); } intervalTotalTime += intervalStep; },intervalStep) } } if (pageIdKey == 'results' && window.location.search.indexOf('fmhid=') == -1 && !(dermObj.isPercMatchMiniPage == true && dermObj.pageControls.perc_match_coll.percMatchFailed == true)){ dermObj.showEmailRequestPopupFlag = await dermObj.checkEmailRequirement(); //dermObj.showEmailRequestPopupFlag = true; if (dermObj.showEmailRequestPopupFlag && dermObj.emailRequestedForResults !== true){ dermObj.sendGA360("main flow","show email capture form before results") dermObj.sendGA4("show email capture form before results") dermObj.emailRequestedForResults = true; //document.getElementById("fmc_email_popup").style.display = 'flex'; dermObj.showEmailPopup(); return; } try{ if (!dermObj.config.userImgOnly){ const fmcSnapShot = await dermObj.getRevSnapShot(dermObj.backendData); dermObj.addUrlParameters(fmcSnapShot); await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ dermObj.updateLocalStorage(fmcSnapShot); } } }catch(err){ console.error(err) } } if (dermObj.config.quizNoImage == true && dermObj.quizNoImageInitFlag != true){ dermObj.quizNoImageInitFlag = true; dermObj.config.pageDict.onboarding_orig = dermObj.config.pageDict.onboarding; dermObj.config.pageDict.onboarding = 'fmc_quiz_no_image_page'; dermObj.config.pageDict.results_orig = dermObj.config.pageDict.results; dermObj.config.pageDict.results = 'fmc_results_quiz_no_image'; dermObj.config.requestEmailForResults_orig = dermObj.config.requestEmailForResults; //dermObj.config.requestEmailForResults = false; } let pageId = dermObj.config.pageDict[pageIdKey]; if (pageIdKey == 'onboarding' && dermObj.quizFromConsent == true){ pageId = 'fmc_quiz_no_image_page'; } if (pageIdKey == 'quiz_after_image' || pageId == 'fmc_qai_page_default'){ dermObj.pageControls.qai.init(); } let curPage = document.getElementById(pageId) || document.getElementById('fmc_landing_page_default'); document.querySelectorAll(".fmc_page").forEach((pageEl)=>{ pageEl.classList.remove("fmc_visible"); }) if (curPage.id != pageId) { console.warn("page id not found - ", pageId); } if (pageId == 'fmc_landing_page_brand_campaign'){ dermObj.pageControls.landing_brand_campaign.runConcernCycle(); } curPage.classList.add("fmc_visible"); if (dermObj.tmDt.firstPageView == undefined){ dermObj.tmDt.firstPageView = Date.now() - dermObj.stTmStmp; } dermObj.currentPage = pageId; if (pageIdKey == "landing" && pageId == 'fmc_loading_page_default'){ dermObj.showConsent(); } if (pageIdKey == "onboarding"){ if (pageId == 'fmc_onbording_default'){ try{ dermObj.pageControls.onboarding_default.skipToResultsCounter = 0; }catch(err){} } if (pageId == 'fmc_quiz_no_image_page'){ dermObj.pageControls.onboarding_quiz_no_image.loadQuiz(); } if (pageId == 'fmc_loading_page_default'){ dermObj.showConsent(); } if (window.dataLayer != undefined){ try{ dataLayer.push({'event':'visited_face_mapping'}) }catch(err){} } } if (pageIdKey == "capture") { if (!dermObj.capture.initDone){ await dermObj.capture.init({ captureContainerId : 'fmc_video_container', videoConstrains : { video: { facingMode: { ideal: 'user' }, width: { min: 720, ideal: 1080, max: 1920 }, height: {min: 720, ideal: 1080, max: 1920 } }, audio: false } }); } dermObj.pageControls.capture.start(); } if (pageId == "fmc_waiting_page_default"){ dermObj.pageControls.waiting.buildLoadingText() } if (pageIdKey == "results"){ dermObj.body.style.height = "auto"; dermObj.widget_wrapper.style.height = "auto"; setTimeout(()=>{ dermObj.resizeWrapper(); },1000) }else{ if (dermObj.widgetMaxHeight != undefined){ dermObj.body.style.height = dermObj.widgetMaxHeight; dermObj.widget_wrapper.style.height = dermObj.widgetMaxHeight; }else{ dermObj.body.style.height = `${window.innerHeight}px`; dermObj.widget_wrapper.style.height = `${window.innerHeight}px`; } } if (pageIdKey == "results"){ switch (dermObj.config.pageDict.results){ case 'fmc_results_quiz_no_image': dermObj.pageControls.quiz_no_image_results.build(); break; case 'fmc_results_prep_treat_glow': dermObj.pageControls.prep_treat_glow.build(); break; case 'fmc_results_ai_steps': dermObj.pageControls.aiSteps.build(); break; case 'fmc_estimated_results': dermObj.pageControls.estimatedResults.build(); break; case 'fmc_results_brand_campaign': dermObj.pageControls.brand_campaign.build(); break; case 'fmc_results_page_perc_match_coll': dermObj.pageControls.perc_match_coll.build(); break; default: dermObj.pageControls.results_default.build(); } if (window.dataLayer != undefined){ try{ dataLayer.push({'event':'completed_face_mapping'}); }catch(err){} } if (dermObj.config.ga4dst !== undefined && dermObj.config.ga4dst !== null ){ try{ gtag('event','fmc_results_complete_ga4',{send_to: dermObj.config.ga4dst}) }catch(err){ console.error(err) } } if (dermObj.config.gtmDLArray !== undefined && dermObj.config.gtmDLArray !== null ){ try{ if (window[dermObj.config.gtmDLArray] !== undefined && window[dermObj.config.gtmDLArray] !== null){ window[dermObj.config.gtmDLArray].push({event: 'fmc_results_complete_gtm'}); } }catch(err){ console.error(err) } }; if (dermObj.config.fmcCheckoutCookie === true){ (async()=>{ await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies === true){ try{ sessionStorage.setItem('fmccmpl',1); }catch(err){} } })(); } } // badges logic if (dermObj.config.badges != {}){ if (dermObj.config.badges[pageId] != undefined && typeof dermObj.config.badges[pageId] == 'string'){ dermObj.badges.showVariation(dermObj.config.badges[pageId], false) } } dermObj.sendGA360("main flow",`show page - ${pageId}`); dermObj.sendGAFlowEvent(`show page - ${pageId}`); }; dermObj.requestPermissionBeforeLoadingFormerResult = async ()=>{ dermObj.permissionBeforeFormerResults = true; dermObj.gotoPage('loading'); dermObj.body.style.opacity = 1; let mpData; try{ mpData = JSON.parse(localStorage.getItem('derm_mp')) || {}; }catch(err){ mpData = {}; } let smac = mpData.smac; if (smac != '' && smac != undefined && mpData.fh != undefined){ let fhid = location.search.split('fmhid=')[1].split('&')[0]; if (fhid == mpData.fh){ dermObj.twofa.code = dermObj.clearCd(smac, fhid); } } if (dermObj.config.quizNoImage || dermObj.twofa.code != ''){ dermObj.loadingFormerResultAfterPermission(); }else{ dermObj.showConsent(); } } dermObj.loadingFormerResultAfterPermission = async ()=>{ dermObj.permissionBeforeFormerResults = false; try{ const analyzeData = await dermObj.getFormerfmcResult(dermObj.formerHash); dermObj.debug("fmc data: ",analyzeData); dermObj.backendData = analyzeData; //console.log('BACKEND DATA - ',dermObj.backendData) //dermObj.dioxideData = {...dermObj.backendData} try{ const dioxPayload = await dermObj.prepareDioxidePayload(dermObj.backendData, dermObj.lang_code) //dermObj.debug("DIOX PAYLOAD - ",dioxPayload); const dioxRefineRecomResponse = await dermObj.getDioxideRecommendations(dioxPayload); //dermObj.debug("DIOX RECOM RESPONSE - ",dioxRefineRecomResponse); dermObj.dioxideData = {...dioxRefineRecomResponse}; }catch(err){ } if (window.location.search.indexOf("dbe6412ad=1") > -1){ dermObj.masks.obscurifyEyesFlag = false; }else{ dermObj.masks.obscurifyEyesFlag = true; } await dermObj.loadExtraLibraries(); try{ await dermObj.capture.initFaceLandmarkModel(false); }catch(err){ console.error(err) } dermObj.gotoPage('results'); }catch(err){ if (err.indexOf('Please supply the correct access code') > -1 ){ dermObj.twofa.inputEl.value = ''; dermObj.gotoPage('loading'); dermObj.loadingFormerResultAfterPermission(); window.alert("Access Code wrong"); }else{ dermObj.gotoPage('landing'); } } } dermObj.openChatOrContactPage = async () => { const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (chatEnabled){ dermObj.sendGA360("main flow", `chat available - trying to open a chat with message`); dermObj.sendGAFlowEvent( `chat available - trying to open a chat with message`); dermObj.chat.openChat(); }else{ dermObj.sendGA360("main flow",`no chat available - go to contact page`); dermObj.sendGAFlowEvent(`no chat available - go to contact page`); dermObj.gotoContactPage() } } dermObj.gotoContactPage = async () => { window.open(dermObj.siteLinks.contact_us_url, '_blank'); } dermObj.gotoQuizFromConsent = async () => { document.getElementById('fmc_legal_overlay').style.display = "none"; dermObj.sendGA360("main flow",`quiz from consent`); dermObj.sendGAFlowEvent(`quiz from consent`); dermObj.quizFromConsent = true; dermObj.config.quizNoImage = true; dermObj.gotoPage('onboarding'); } dermObj.gotoQuizFromLanding = async () => { dermObj.sendGA360("main flow",`quiz from landing`); dermObj.sendGAFlowEvent(`quiz from landing`); dermObj.quizFromLanding = true; dermObj.config.quizNoImage = true; dermObj.queueUrlParameters({qfl:1}); dermObj.gotoPage('onboarding'); } dermObj.exitQuizNoImage = async () => { dermObj.sendGA360("main flow",`exit quiz no image`); dermObj.sendGAFlowEvent(`exit quiz no image`); dermObj.config.quizNoImage = false; dermObj.quizFromConsent = false; dermObj.quizFromLanding = false; dermObj.quizNoImageInitFlag = false; dermObj.config.pageDict.onboarding = dermObj.config.pageDict.onboarding_orig; dermObj.config.pageDict.results = dermObj.config.pageDict.results_orig; dermObj.config.requestEmailForResults = dermObj.config.requestEmailForResults_orig; dermObj.gotoPage('landing'); } dermObj.masks = {} dermObj.masks.images = {} dermObj.masks.pending = false; dermObj.masks.getObscEyeRect = async ()=>{ if (dermObj.config.quizNoImage === true) { dermObj.masks.fillWithPlaceholderImage(); return; } if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ dermObj.masks.fillWithPlaceholderImage(); return; } if (dermObj.backendData.azure_response != undefined){ const azureRes = dermObj.backendData.azure_response; dermObj.masks.eyeRect = {}; dermObj.masks.eyeRect.left = azureRes.face_rectangle.left; dermObj.masks.eyeRect.width = azureRes.face_rectangle.width; const eyeTop = Math.min(azureRes.face_landmarks.eyeLeftTop.y, azureRes.face_landmarks.eyeRightTop.y ) const eyeBottom = Math.min(azureRes.face_landmarks.eyeLeftBottom.y, azureRes.face_landmarks.eyeRightBottom.y ) const eyeHeight = eyeBottom - eyeTop; dermObj.masks.eyeRect.top = eyeTop - 2* eyeHeight; dermObj.masks.eyeRect.height = 5* eyeHeight; return; }else{ dermObj.masks.eyeRect = { left: dermObj.capture.faceBox._x, width: dermObj.capture.faceBox._width, top: dermObj.capture.faceBox._y + 0.2*dermObj.capture.faceBox._height, height: 0.2*dermObj.capture.faceBox._height } return; } } dermObj.masks.fillWithPlaceholderImage = async () => { if (dermObj.masks.pending == true) return; dermObj.masks.images = { original : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, original_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, darkCircles : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, darkCircles_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, redness : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, redness_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, dehydration : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, dehydration_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, oiliness : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, oiliness_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, acne : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, acne_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, wrinkles : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg`, wrinkles_cropped : `https://facemapping.me/img/landing/fmc_landing_page_desktop.jpg` } } dermObj.masks.fillWithOriginalImage = async () => { dermObj.masks.images = { original : dermObj.backendData.original_image, original_cropped : dermObj.backendData.original_image, darkCircles : dermObj.backendData.original_image, darkCircles_cropped : dermObj.backendData.original_image, redness : dermObj.backendData.original_image, redness_cropped : dermObj.backendData.original_image, dehydration : dermObj.backendData.original_image, dehydration_cropped : dermObj.backendData.original_image, oiliness : dermObj.backendData.original_image, oiliness_cropped : dermObj.backendData.original_image, acne : dermObj.backendData.original_image, acne_cropped : dermObj.backendData.original_image, wrinkles : dermObj.backendData.original_image, wrinkles_cropped : dermObj.backendData.original_image } return; } dermObj.masks.getCropRect = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true || dermObj.masks.pending == true) { resolve() return; }; if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ reject('azure_response undefined') return; } const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ let faceWidth; let faceHeight; let faceLeft; let faceTop; if (dermObj.backendData.azure_response != undefined){ const azureRes = dermObj.backendData.azure_response; faceWidth = azureRes.face_rectangle.width; faceHeight = azureRes.face_rectangle.height; faceLeft = azureRes.face_rectangle.left; faceTop = azureRes.face_rectangle.top; }else if (dermObj.capture.faceBox != undefined){ faceWidth = Math.round(dermObj.capture.faceBox._width); faceHeight = Math.round(dermObj.capture.faceBox._height); faceLeft = Math.round(dermObj.capture.faceBox._x); faceTop = Math.round(dermObj.capture.faceBox._y); }else{ reject('no face data'); return; } dermObj.masks.cropRect = {}; dermObj.masks.cropRect.originalImageWidth = img.naturalWidth; dermObj.masks.cropRect.originalImageHeight = img.naturalHeight; const cropLimitX = img.naturalWidth - 1; const cropLimitY = img.naturalHeight - 1; const cropMax = Math.max(faceWidth * 1.2, faceHeight * 1.6); let cropSize = Math.max(faceWidth, faceHeight); const cropStep = Math.round((cropMax - cropSize)/5); function evalCropAndImageSize(){ let withinImage = true; if (dermObj.masks.cropRect.left < 0){ withinImage = false; } if (dermObj.masks.cropRect.top < 0){ withinImage = false; } if (dermObj.masks.cropRect.left + dermObj.masks.cropRect.width > cropLimitX){ withinImage = false; } if (dermObj.masks.cropRect.top + dermObj.masks.cropRect.height > cropLimitY){ withinImage = false; } return withinImage; } let cropWithinImage = true; while (cropWithinImage && cropSize < cropMax){ dermObj.masks.cropRect.left = faceLeft + 0.5 * faceWidth - 0.5 * cropSize; dermObj.masks.cropRect.width = cropSize; dermObj.masks.cropRect.top = faceTop + 0.5 * faceHeight - 0.5 * cropSize; dermObj.masks.cropRect.height = cropSize; cropWithinImage = evalCropAndImageSize(); if (cropWithinImage){ cropSize += cropStep; }else{ cropSize -= cropStep; dermObj.masks.cropRect.left = faceLeft + 0.5 * faceWidth - 0.5 * cropSize; dermObj.masks.cropRect.width = cropSize; dermObj.masks.cropRect.top = faceTop + 0.5 * faceHeight - 0.5 * cropSize; dermObj.masks.cropRect.height = cropSize; } } resolve(); } img.src = dermObj.backendData.original_image; }) } dermObj.masks.makeOriginalImages = async ()=>{ return new Promise(async (resolve, reject)=>{ if (dermObj.config.quizNoImage === true || dermObj.masks.pending == true) { resolve() return; }; if (dermObj.backendData.azure_response == undefined && dermObj.capture.faceBox == undefined){ await dermObj.masks.fillWithPlaceholderImage(); reject('azure_response undefined - using original image'); return; } const canvas = document.createElement("canvas"); canvas.id="fmc_original_img_obscured_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) if (dermObj.masks.obscurifyEyesFlag && dermObj.masks.eyeRect != undefined){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } dermObj.masks.images.original= canvas.toDataURL("image/jpeg") let cropOriginalCanvas = document.getElementById('fmc_original_canvas'); if (!cropOriginalCanvas){ cropOriginalCanvas= document.createElement('canvas'); cropOriginalCanvas.id = 'fmc_original_canvas'; cropOriginalCanvas.classList.add('fmc_hidden_canvas') document.getElementById("fmc_mask_canvas_container").appendChild(cropOriginalCanvas); } const ctxOriginalCanvas = cropOriginalCanvas.getContext('2d'); const originalImg = new Image(); originalImg.crossOrigin = "Anonymous"; originalImg.onload = async ()=>{ cropOriginalCanvas.width = dermObj.masks.cropRect.width; cropOriginalCanvas.height = dermObj.masks.cropRect.height; ctxOriginalCanvas.drawImage(originalImg,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.original_cropped = cropOriginalCanvas.toDataURL("image/jpeg") resolve(); } originalImg.src = dermObj.masks.images.original; } img.src = dermObj.backendData.original_image; }) } dermObj.masks.buildMasks = async ()=>{ if (dermObj.masks.pending == true) return; dermObj.masks.pending = true; setTimeout(()=>{ dermObj.masks.pending = false; },10000); let finishedMaskCounter = 0; (async ()=>{ await dermObj.masks.darkCircles(); finishedMaskCounter++; })(); (async ()=>{ await dermObj.masks.dehydrationAndRedness(); finishedMaskCounter++; })(); (async ()=>{ await dermObj.masks.acne(); finishedMaskCounter++; })(); (async ()=>{ await dermObj.masks.wrinkles(); finishedMaskCounter++; })(); (async ()=>{ await dermObj.masks.oiliness(); finishedMaskCounter++; })(); let maskCounterInt = setInterval(()=>{ if (finishedMaskCounter >= 5 || dermObj.masks.pending == false){ clearInterval(maskCounterInt); dermObj.masks.pending = false; } },100) } dermObj.masks.applyImageData = () => { document.querySelectorAll(`[data-widget-concern-img]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.original; }) document.querySelectorAll(`[data-widget-concern-img-cropped]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.original_cropped; }) const darkCirclesInterval = setInterval (()=>{ if (typeof dermObj.masks.images.darkCircles_cropped != 'undefined' ){ clearInterval(darkCirclesInterval); document.querySelectorAll(`[data-widget-concern-img=dark_circles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.darkCircles; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dark_circles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.darkCircles_cropped; }) } },200); const rednessInterval = setInterval (()=>{ if (typeof dermObj.masks.images.redness_cropped != 'undefined' ){ clearInterval(rednessInterval); document.querySelectorAll(`[data-widget-concern-img=redness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.redness; }) document.querySelectorAll(`[data-widget-concern-img-cropped=redness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.redness_cropped; }) } },200); const dehydrInterval = setInterval (()=>{ if (typeof dermObj.masks.images.dehydration_cropped != 'undefined' ){ clearInterval(dehydrInterval); document.querySelectorAll(`[data-widget-concern-img=dehydration]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.dehydration; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dehydration]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.dehydration_cropped; }) } },200); const oilinessInterval = setInterval (()=>{ if (typeof dermObj.masks.images.oiliness_cropped != 'undefined' ){ clearInterval(oilinessInterval); document.querySelectorAll(`[data-widget-concern-img=oiliness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.oiliness; }) document.querySelectorAll(`[data-widget-concern-img-cropped=oiliness]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.oiliness_cropped; }) } },200); const acneInterval = setInterval (()=>{ if (typeof dermObj.masks.images.acne_cropped != 'undefined' ){ clearInterval(acneInterval); document.querySelectorAll(`[data-widget-concern-img=acne]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.acne; }) document.querySelectorAll(`[data-widget-concern-img-cropped=acne]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.acne_cropped; }) } },200); const wrinklesInterval = setInterval (()=>{ if (typeof dermObj.masks.images.wrinkles_cropped != 'undefined' ){ clearInterval(wrinklesInterval); document.querySelectorAll(`[data-widget-concern-img=wrinkles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.wrinkles; }) document.querySelectorAll(`[data-widget-concern-img-cropped=wrinkles]`).forEach((imgEl)=>{ imgEl.src = dermObj.masks.images.wrinkles_cropped; }) } },200); } dermObj.masks.clearImages = () => { document.querySelectorAll(`[data-widget-concern-img]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=dark_circles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dark_circles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=redness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=redness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=dehydration]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=dehydration]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=oiliness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=oiliness]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=acne]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=acne]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img=wrinkles]`).forEach((imgEl)=>{ imgEl.src = ''; }) document.querySelectorAll(`[data-widget-concern-img-cropped=wrinkles]`).forEach((imgEl)=>{ imgEl.src = ''; }) } dermObj.masks.calcDarkCirclesScore = async ()=>{ return new Promise((resolve,reject) => { if (dermObj.capture.faceApiIsLoaded){ const canvas = document.createElement('canvas'); canvas.id="fmc_dark_circles_canvas"; canvas.classList.add("fmc_hidden_canvas"); const ctx = canvas.getContext('2d'); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async () => { canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) faceapi.detectAllFaces(canvas, dermObj.capture.modelOptions).withFaceLandmarks().then((landmarkDataArray)=>{ dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); } } let leftEyeBoxWidth = leftEye[3]._x - leftEye[0]._x; let rightEyeBoxWidth = rightEye[3]._x - rightEye[0]._x; let leftEyeBoxHeight = Math.max(leftEye[4]._y, leftEye[5]._y) - Math.min(leftEye[1]._y, leftEye[2]._y); let rightEyeBoxHeight = Math.max(rightEye[4]._y, rightEye[5]._y) - Math.min(rightEye[1]._y, rightEye[2]._y); let calcBoxWidth = Math.max(1.2*leftEyeBoxWidth,1.2*rightEyeBoxWidth); let calcBoxHeight = Math.max(1.2*leftEyeBoxHeight,1.2*rightEyeBoxHeight); let leftDarkCircleBox = {x : leftEye[0]._x - leftEyeBoxWidth*0.1,y : Math.max(leftEye[4]._y,leftEye[5]._y) + 0.6*leftEyeBoxHeight, w : calcBoxWidth, h : calcBoxHeight}; let rightDarkCircleBox = {x : rightEye[0]._x - rightEyeBoxWidth*0.1 ,y : Math.max(rightEye[4]._y,rightEye[5]._y)+ 0.6*rightEyeBoxHeight, w : calcBoxWidth, h : calcBoxHeight}; let leftCompareBox = { x: leftDarkCircleBox.x - 0.3*leftDarkCircleBox.w, y: leftDarkCircleBox.y + leftDarkCircleBox.h, w: leftDarkCircleBox.w, h: leftDarkCircleBox.h } let rightCompareBox = { x: rightDarkCircleBox.x + 0.3*leftDarkCircleBox.w, y: rightDarkCircleBox.y + rightDarkCircleBox.h, w: rightDarkCircleBox.w, h: rightDarkCircleBox.h } let darkCircleImgDataLeft = ctx.getImageData(leftDarkCircleBox.x, leftDarkCircleBox.y, leftDarkCircleBox.w , leftDarkCircleBox.h); let compareImgDataLeft = ctx.getImageData(leftCompareBox.x, leftCompareBox.y, leftCompareBox.w , leftCompareBox.h); let darkCircleImgDataRight = ctx.getImageData(rightDarkCircleBox.x, rightDarkCircleBox.y, rightDarkCircleBox.w , rightDarkCircleBox.h); let compareImgDataRight = ctx.getImageData(rightCompareBox.x, rightCompareBox.y, rightCompareBox.w , rightCompareBox.h); let darkCircleR = 0; let darkCircleG = 0; let darkCircleB = 0; let compareR = 0; let compareG = 0; let compareB = 0; for (let ii = 0; ii < darkCircleImgDataLeft.data.length/4; ii++){ darkCircleR += darkCircleImgDataLeft.data[4*ii]/255 + darkCircleImgDataRight.data[4*ii]/255 ; darkCircleG += darkCircleImgDataLeft.data[4*ii+1]/255 + darkCircleImgDataRight.data[4*ii+1]/255 ; darkCircleB += darkCircleImgDataLeft.data[4*ii+2]/255 + darkCircleImgDataRight.data[4*ii+2]/255 ; compareR += compareImgDataLeft.data[4*ii]/255 + compareImgDataRight.data[4*ii]/255 ; compareG += compareImgDataLeft.data[4*ii+1]/255 + compareImgDataRight.data[4*ii+1]/255 ; compareB += compareImgDataLeft.data[4*ii+2]/255 + compareImgDataRight.data[4*ii+2]/255 ; } let darkCircleLight = 0.2126 * darkCircleR + 0.7152 * darkCircleG + 0.0722 * darkCircleB; let compareLight = 0.2126 * compareR + 0.7152 * compareG + 0.0722 * compareB; dermObj.masks.darkCirclesScore = Math.max(1,Math.min(5,Math.floor(-50/3 * darkCircleLight/compareLight + 52/3))); if (isNaN(dermObj.masks.darkCirclesScore)){ dermObj.masks.darkCirclesScore =2; } }else{ dermObj.masks.darkCirclesImage = dermObj.masks.capturedImage; dermObj.masks.darkCirclesScore = 2; } resolve(); }); } img.src = dermObj.masks.capturedImage; }else{ dermObj.masks.images.darkCircles = dermObj.masks.capturedImage; dermObj.masks.darkCirclesScore = 2; resolve(); } }) } dermObj.masks.darkCircles = async ()=>{ dermObj.debug('darkCircles call'); return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_dark_circles_canvas")){ canvas = document.getElementById("fmc_dark_circles_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_dark_circles_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) faceapi.detectAllFaces(canvas, dermObj.capture.modelOptions).withFaceLandmarks().then( async (landmarkDataArray)=>{ //dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); } } let leftEyeBoxWidth = leftEye[3]._x - leftEye[0]._x; let rightEyeBoxWidth = rightEye[3]._x - rightEye[0]._x; let leftEyeBoxHeight = Math.max(leftEye[4]._y, leftEye[5]._y) - Math.min(leftEye[1]._y, leftEye[2]._y); let rightEyeBoxHeight = Math.max(rightEye[4]._y, rightEye[5]._y) - Math.min(rightEye[1]._y, rightEye[2]._y); let leftDarkCircleBox = {x : leftEye[0]._x - leftEyeBoxWidth*0.1,y : Math.max(leftEye[4]._y,leftEye[5]._y) + 0.6*leftEyeBoxHeight, w : 1.2*leftEyeBoxWidth, h : 1.2*leftEyeBoxHeight}; let rightDarkCircleBox = {x : rightEye[0]._x - rightEyeBoxWidth*0.1 ,y : Math.max(rightEye[4]._y,rightEye[5]._y)+ 0.6*rightEyeBoxHeight, w : 1.2*rightEyeBoxWidth, h : 1.2*rightEyeBoxHeight}; await dermObj.masks.drawWhiteEllipseInRect(leftDarkCircleBox.x,leftDarkCircleBox.y,leftDarkCircleBox.w,leftDarkCircleBox.h, ctx); await dermObj.masks.drawWhiteEllipseInRect (rightDarkCircleBox.x,rightDarkCircleBox.y,rightDarkCircleBox.w,rightDarkCircleBox.h, ctx); if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } dermObj.masks.images.darkCircles = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.darkCircles_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.darkCircles } }) } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawWhiteEllipseInRect = async (coordsX,coordsY,width,height,ctx) => { let scaleFact = 1.2; let scaledWidth = width*1.2; let scaledHeight = height*1.2; let centerX = coordsX + 0.5*width; let centerY = coordsY + 0.5*height; ctx.beginPath(); ctx.moveTo(centerX - scaledWidth/2, centerY); // A1 ctx.bezierCurveTo( centerX - scaledWidth/2, centerY - scaledHeight/2, // C1 centerX + scaledWidth/2, centerY - scaledHeight/2, // C2 centerX + scaledWidth/2, centerY); // A2 ctx.bezierCurveTo( centerX + scaledWidth/2, centerY + scaledHeight/2, // C3 centerX - scaledWidth/2, centerY + scaledHeight/2, // C4 centerX - scaledWidth/2, centerY); // A1 let lineWidth; try{ lineWidth = Math.max(2, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); }catch(err){ lineWidth = 2; } //dermObj.debug('LINE WIDTH: ', lineWidth) ctx.lineWidth = lineWidth; ctx.strokeStyle = "white"; ctx.stroke(); ctx.closePath(); return; } dermObj.masks.dehydrationAndRedness = async ()=>{ return new Promise(async (resolve, reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let imgScaleFactor = 1; const canvasDehydr = document.createElement("canvas"); canvasDehydr.id="fmc_dehydration_canvas"; canvasDehydr.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvasDehydr); const ctxDehydr = canvasDehydr.getContext('2d'); const canvasRed = document.createElement("canvas"); canvasRed.id="fmc_redness_canvas"; canvasRed.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvasRed); const ctxRed = canvasRed.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ const maxFaceDim = Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height); if (maxFaceDim > 500 ){ imgScaleFactor = 500 / maxFaceDim; } //dermObj.debug('Dehydration mask Scale Factor: ', imgScaleFactor); const imgUsedWidth = Math.ceil(img.naturalWidth * imgScaleFactor); const imgUsedHeight = Math.ceil(img.naturalHeight * imgScaleFactor); canvasDehydr.width = imgUsedWidth; canvasDehydr.height = imgUsedHeight; ctxDehydr.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,imgUsedWidth,imgUsedHeight) canvasRed.width = imgUsedWidth; canvasRed.height = imgUsedHeight; ctxRed.drawImage(img,0,0,img.naturalWidth,img.naturalHeight,0,0,imgUsedWidth,imgUsedHeight) faceapi.detectAllFaces(canvasDehydr, dermObj.capture.modelOptions).withFaceLandmarks().then( async (landmarkDataArray)=>{ //dermObj.debug("LANDMARK DATA ARRAY", landmarkDataArray); if (landmarkDataArray.length > 0){ const landmarkData = landmarkDataArray[0]; let leftEye = []; let rightEye = []; let leftEyeBrow = []; let rightEyeBrow = []; let jaw = []; let mouth = []; let nose = []; if (landmarkData.landmarks._shift._x >= 0 && landmarkData.landmarks._shift._y >= 0){ leftEye =landmarkData.landmarks.getLeftEye(); rightEye =landmarkData.landmarks.getRightEye(); leftEyeBrow = landmarkData.landmarks.getLeftEyeBrow(); rightEyeBrow = landmarkData.landmarks.getRightEyeBrow(); jaw = landmarkData.landmarks.getJawOutline(); mouth = landmarkData.landmarks.getMouth(); nose = landmarkData.landmarks.getNose(); }else if (landmarkData.landmarks._shift._x < 0 && landmarkData.landmarks._shift._y < 0){ leftEye =landmarkData.unshiftedLandmarks.getLeftEye(); rightEye =landmarkData.unshiftedLandmarks.getRightEye(); leftEyeBrow = landmarkData.unshiftedLandmarks.getLeftEyeBrow(); rightEyeBrow = landmarkData.unshiftedLandmarks.getRightEyeBrow(); jaw = landmarkData.unshiftedLandmarks.getJawOutline(); mouth = landmarkData.unshiftedLandmarks.getMouth(); nose = landmarkData.unshiftedLandmarks.getNose(); }else{ let unshiftedLeftEye = landmarkData.unshiftedLandmarks.getLeftEye(); let unshiftedRightEye = landmarkData.unshiftedLandmarks.getRightEye(); let shiftedLeftEye = landmarkData.landmarks.getLeftEye(); let shiftedRightEye = landmarkData.landmarks.getRightEye(); let unshiftedLeftEyeBrow = landmarkData.unshiftedLandmarks.getLeftEyeBrow(); let unshiftedRightEyeBrow = landmarkData.unshiftedLandmarks.getRightEyeBrow(); let shiftedLeftEyeBrow = landmarkData.landmarks.getLeftEyeBrow(); let shiftedRightEyeBrow = landmarkData.landmarks.getRightEyeBrow(); let shiftedJaw = landmarkData.landmarks.getJawOutline(); let unshiftedJaw = landmarkData.unshiftedLandmarks.getJawOutline(); let shiftedMouth = landmarkData.landmarks.getMouth(); let unshiftedMouth = landmarkData.unshiftedLandmarks.getMouth(); let shiftedNose = landmarkData.landmarks.getMouth(); let unshiftedNose = landmarkData.unshiftedLandmarks.getNose(); if (landmarkData.landmarks._shift._x >= 0){ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: shiftedLeftEye[index]._x , _y : unshiftedLeftEye[index]._y}); rightEye.push({_x: shiftedRightEye[index]._x , _y : unshiftedRightEye[index]._y}) }); shiftedLeftEyeBrow.forEach((eyeBrowPoint,index)=>{ leftEyeBrow.push({_x: shiftedLeftEyeBrow[index]._x , _y : unshiftedLeftEyeBrow[index]._y}); rightEyeBrow.push({_x: shiftedRightEyeBrow[index]._x , _y : unshiftedRightEyeBrow[index]._y}) }); shiftedJaw.forEach((jawPoint,index)=>{ jaw.push({_x: shiftedJaw[index]._x , _y : unshiftedJaw[index]._y}); }); shiftedMouth.forEach((mouthPoint,index)=>{ mouth.push({_x: shiftedMouth[index]._x , _y : unshiftedMouth[index]._y}); }); shiftedNose.forEach((nosePoint,index)=>{ try{ nose.push({_x: shiftedNose[index]._x , _y : unshiftedNose[index]._y}); }catch(err){ nose.push({_x: shiftedNose[index]._x , _y : shiftedNose[index]._y}); } }); }else{ shiftedLeftEye.forEach((eyePoint,index)=>{ leftEye.push({_x: unshiftedLeftEye[index]._x , _y : shiftedLeftEye[index]._y}); rightEye.push({_x: unshiftedRightEye[index]._x , _y : shiftedRightEye[index]._y}) }); shiftedLeftEyeBrow.forEach((eyeBrowPoint,index)=>{ leftEyeBrow.push({_x: unshiftedLeftEyeBrow[index]._x , _y : shiftedLeftEyeBrow[index]._y}); rightEyeBrow.push({_x: unshiftedRightEyeBrow[index]._x , _y : shiftedRightEyeBrow[index]._y}) }); shiftedJaw.forEach((jawPoint,index)=>{ jaw.push({_x: unshiftedJaw[index]._x , _y : shiftedJaw[index]._y}); }); shiftedMouth.forEach((mouthPoint,index)=>{ mouth.push({_x: unshiftedMouth[index]._x , _y : shiftedMouth[index]._y}); }); shiftedNose.forEach((nosePoint,index)=>{ try{ nose.push({_x: unshiftedNose[index]._x , _y : shiftedNose[index]._y}); }catch(err){ nose.push({_x: shiftedNose[index]._x , _y : shiftedNose[index]._y}); } }); } } let topLeftEyeBrowY = leftEyeBrow[2]._y; let topRightEyeBrowY = rightEyeBrow[2]._y; let lowLeftEyeY = Math.max(leftEye[4]._y,leftEye[5]._y); let lowRightEyeY = Math.max(rightEye[4]._y,rightEye[5]._y); let faceRectToScan = { x: Math.round(jaw[2]._x) + 0.0*(jaw[14]._x - jaw[2]._x) , y: Math.round(2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) - 1.0*Math.min(lowLeftEyeY,lowRightEyeY) - 0.05*(jaw[8]._y - 2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) + 1.0*Math.min(lowLeftEyeY,lowRightEyeY))), w: Math.round(1.0*(jaw[14]._x - jaw[2]._x)), //w: Math.round(1.0*(rightEyeBrow[4]._x - leftEyeBrow[0]._x)), h: Math.round(1.1*(jaw[8]._y - 2.0 * Math.min(topLeftEyeBrowY,topRightEyeBrowY) + 1.0*Math.min(lowLeftEyeY,lowRightEyeY))) } let leftEyeBlankRect = { x: Math.round(jaw[0]._x), y: Math.round(topLeftEyeBrowY - 0.2*(lowLeftEyeY - topLeftEyeBrowY)), w: Math.round( 0.5*leftEye[3]._x + 0.5*rightEye[0]._x -jaw[0]._x ), h: Math.round(1.7*(lowLeftEyeY - topLeftEyeBrowY)) } let rightEyeBlankRect = { x: Math.round( leftEye[3]._x + 0.5*(rightEye[0]._x - leftEye[3]._x )), y: Math.round(topRightEyeBrowY - 0.2*(lowRightEyeY - topRightEyeBrowY)), w: Math.round( jaw[16]._x - leftEye[3]._x - 0.5*(rightEye[0]._x - leftEye[3]._x ) ), h: Math.round(1.7*(lowRightEyeY - topRightEyeBrowY)) } let mouthBlankRect = { x: Math.round( mouth[0]._x - 0.2 * (mouth[6]._x - mouth[0]._x)), y: Math.round(mouth[2]._y - 0.2* (mouth[9]._y - mouth[2]._y)), w: Math.round( 1.4*(mouth[6]._x - mouth[0]._x) ), h: Math.round( 1.4* (mouth[9]._y - mouth[2]._y)) } let noseBlankRect = { x: Math.round( nose[4]._x - 0.5*(nose[8]._x - nose[4]._x)), y: Math.round( nose[3]._y - 0.7*(nose[6]._y - nose[3]._y)), w: Math.round( 2*(nose[8]._x - nose[4]._x) ), h: Math.round( 2* (nose[6]._y - nose[3]._y)) } let imageData = ctxDehydr.getImageData(faceRectToScan.x ,faceRectToScan.y , faceRectToScan.w, faceRectToScan.h ); let dehydrationImgData = ctxDehydr.createImageData(imageData.width, imageData.height) let rednessImgData = ctxDehydr.createImageData(imageData.width, imageData.height) let y=0; let x=0; const modTarget = Math.ceil(imageData.height / 100) //dermObj.debug(`estimated pixels per block: ${modTarget * imageData.width}`); //dermObj.debug(`image width: ${imageData.width}`); //dermObj.debug(`image height: ${imageData.height}`); //dermObj.debug(`modTarget: ${modTarget}`); //const dehydrationStartTime = (new Date).getTime(); async function processImageBlocks(){ return new Promise( async (imgRes,imgRej)=>{ //logOnLocalHostFrontEnd("processing image block - cur y = ",y); let initBlockCall = true; while( y< imageData.height && ( y % modTarget != 0) || initBlockCall){ initBlockCall = false; while( x< imageData.width ){ let ii = y* imageData.width + x; let minBlue = 255; let maxBlue = 0; let avRed = 0; let avCounter = 0; const calcLimit = 10; for (var scan_x = - calcLimit; scan_x < calcLimit + 1; scan_x++ ){ for (var scan_y = - calcLimit; scan_y < calcLimit + 1; scan_y++ ){ let idx = (ii-scan_x + scan_y*imageData.width ); while (idx < 0){ idx += imageData.data.length/4; } while (idx >= imageData.data.length/4){ idx -= imageData.data.length/4; } minBlue = Math.min(minBlue, imageData.data[idx*4+2]); maxBlue = Math.max(maxBlue, imageData.data[idx*4+2]); avRed += imageData.data[idx*4+0] / (imageData.data[idx*4+0]+imageData.data[idx*4+1]+imageData.data[idx*4+2]); avCounter++; } } let curColorObj = dermObj.masks.getColorFromGradient(Math.min(Math.max(Math.round((imageData.data[ii*4+2]-minBlue)/(maxBlue - minBlue)*255),0),255)); dehydrationImgData.data[ii*4+0] = curColorObj.r; dehydrationImgData.data[ii*4+1] = curColorObj.g; dehydrationImgData.data[ii*4+2] = curColorObj.b; let faceAlpha = dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:0,y:0,w:imageData.width,h:imageData.height}, 0.2 ); let leftEyeAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(leftEyeBlankRect.x-faceRectToScan.x),y:Math.round(leftEyeBlankRect.y-faceRectToScan.y),w:leftEyeBlankRect.w,h:leftEyeBlankRect.h}, 0.4 ); let rightEyeAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(rightEyeBlankRect.x-faceRectToScan.x),y:Math.round(rightEyeBlankRect.y-faceRectToScan.y),w:rightEyeBlankRect.w,h:rightEyeBlankRect.h}, 0.4 ); let mouthAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(mouthBlankRect.x-faceRectToScan.x),y:Math.round(mouthBlankRect.y-faceRectToScan.y),w:mouthBlankRect.w,h:mouthBlankRect.h}, 0.4 ); let noseAlpha = 255-dermObj.masks.calcOpacityEllipse(ii % imageData.width,Math.floor(ii/imageData.width), {x:Math.round(noseBlankRect.x-faceRectToScan.x),y:Math.round(noseBlankRect.y-faceRectToScan.y),w:noseBlankRect.w,h:noseBlankRect.h}, 0.4 ); let maskAlpha = 1*Math.min(faceAlpha,leftEyeAlpha,rightEyeAlpha,mouthAlpha,noseAlpha)/255; dehydrationImgData.data[ii*4+0] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+0] + (1-maskAlpha) * imageData.data[ii*4+0]); dehydrationImgData.data[ii*4+1] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+1] + (1-maskAlpha) * imageData.data[ii*4+1]); dehydrationImgData.data[ii*4+2] = Math.round(maskAlpha * dehydrationImgData.data[ii*4+2] + (1-maskAlpha) * imageData.data[ii*4+2]); dehydrationImgData.data[ii*4+3] = 255; avRed /= avCounter; let curRedRatio = imageData.data[ii*4+0] / (imageData.data[ii*4+0]+imageData.data[ii*4+1]+imageData.data[ii*4+2]); if ( curRedRatio + 0.005 > avRed){ rednessImgData.data[ii*4+0] = imageData.data[ii*4+0]; rednessImgData.data[ii*4+1] = Math.round(imageData.data[ii*4+1] * (1 - 10*(curRedRatio + 0.005 - avRed))); rednessImgData.data[ii*4+2] = Math.round(imageData.data[ii*4+2] * (1 - 10*(curRedRatio + 0.005 - avRed))); }else{ rednessImgData.data[ii*4+0] = imageData.data[ii*4+0]; rednessImgData.data[ii*4+1] = imageData.data[ii*4+1]; rednessImgData.data[ii*4+2] = imageData.data[ii*4+2]; } rednessImgData.data[ii*4+0] = Math.round(maskAlpha * rednessImgData.data[ii*4+0] + (1-maskAlpha) * imageData.data[ii*4+0]); rednessImgData.data[ii*4+1] = Math.round(maskAlpha * rednessImgData.data[ii*4+1] + (1-maskAlpha) * imageData.data[ii*4+1]); rednessImgData.data[ii*4+2] = Math.round(maskAlpha * rednessImgData.data[ii*4+2] + (1-maskAlpha) * imageData.data[ii*4+2]); rednessImgData.data[ii*4+3] = 255; x++; } x=0; y++; } ctxDehydr.putImageData(dehydrationImgData,faceRectToScan.x, faceRectToScan.y); ctxRed.putImageData(rednessImgData,faceRectToScan.x, faceRectToScan.y); if (y < imageData.height){ setTimeout(async ()=>{ processImageBlocks() },10) }else{ //const dehydrationEndTime = (new Date).getTime(); //dermObj.debug('total pixels: ', imageData.data.length/4) //dermObj.debug('total process time [s]: ', (dehydrationEndTime - dehydrationStartTime)/1000); //dermObj.debug('block pixels: ', imageData.width * modTarget) //dermObj.debug('av block process time [ms]: ', (dehydrationEndTime - dehydrationStartTime)/Math.ceil(imageData.height / modTarget)); if (dermObj.masks.obscurifyEyesFlag){ ctxDehydr.fillStyle = 'black'; ctxDehydr.fillRect(dermObj.masks.eyeRect.left * imgScaleFactor, dermObj.masks.eyeRect.top * imgScaleFactor, dermObj.masks.eyeRect.width * imgScaleFactor, dermObj.masks.eyeRect.height * imgScaleFactor); ctxRed.fillStyle = 'black'; ctxRed.fillRect(dermObj.masks.eyeRect.left * imgScaleFactor, dermObj.masks.eyeRect.top * imgScaleFactor, dermObj.masks.eyeRect.width * imgScaleFactor, dermObj.masks.eyeRect.height * imgScaleFactor); } dermObj.masks.images.dehydration = canvasDehydr.toDataURL("image/jpeg"); dermObj.masks.images.redness = canvasRed.toDataURL("image/jpeg"); imageData = null; dehydrationImgData = null; rednessImgData = null; const cropDehyPromise = new Promise((resCrop,rejCrop)=>{ const croppedImageDehy = new Image(); croppedImageDehy.crossOrigin = "Anonymous"; croppedImageDehy.onload = async ()=>{ canvasDehydr.width = dermObj.masks.cropRect.width; canvasDehydr.height = dermObj.masks.cropRect.height; ctxDehydr.drawImage(croppedImageDehy,dermObj.masks.cropRect.left * imgScaleFactor,dermObj.masks.cropRect.top * imgScaleFactor,dermObj.masks.cropRect.width * imgScaleFactor,dermObj.masks.cropRect.height * imgScaleFactor, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height); dermObj.masks.images.dehydration_cropped = canvasDehydr.toDataURL("image/jpeg") resCrop(); } croppedImageDehy.src = dermObj.masks.images.dehydration }) const cropRedPromise = new Promise((resCrop,rejCrop)=>{ const croppedImageRed = new Image(); croppedImageRed.crossOrigin = "Anonymous"; croppedImageRed.onload = async ()=>{ canvasRed.width = dermObj.masks.cropRect.width; canvasRed.height = dermObj.masks.cropRect.height; ctxRed.drawImage(croppedImageRed,dermObj.masks.cropRect.left * imgScaleFactor,dermObj.masks.cropRect.top * imgScaleFactor,dermObj.masks.cropRect.width * imgScaleFactor,dermObj.masks.cropRect.height * imgScaleFactor, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height); dermObj.masks.images.redness_cropped = canvasRed.toDataURL("image/jpeg") resCrop(); } croppedImageRed.src = dermObj.masks.images.redness }) Promise.all([cropDehyPromise,cropRedPromise]).then(()=>{ resolve(); }); } }) } processImageBlocks() } }); } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.getColorFromGradient = (gradientPoint) => { let colorObj = {r:0,g:0,b:0} if (gradientPoint > 210){ colorObj.r = 225 + Math.round(30 * ( (gradientPoint - 210 )/ 45)); colorObj.g = 141 - Math.round(141 * ( (gradientPoint - 210 )/ 45)); colorObj.b = 0; } else if (gradientPoint > 160){ colorObj.r = 242 - Math.round(13 * ( (gradientPoint - 160 )/ 50)); colorObj.g = 226 - Math.round(85 * ( (gradientPoint - 160 )/ 50)); colorObj.b = 0; }else{ colorObj.r = 55 - Math.round(44 * (gradientPoint / 160)); colorObj.g = 192 - Math.round(50 * (gradientPoint / 160)) ; colorObj.b = 176 + Math.round(16 * (gradientPoint / 160)); } return colorObj; } dermObj.masks.calcOpacityEllipse = (point_x, point_y, ellRectObj, fullAlphaFact = 0.05 ) => { let scaleDimensions = 0.9; let aSqu = (ellRectObj.w/2*scaleDimensions)*(ellRectObj.w/2*scaleDimensions); let bSqu = (ellRectObj.h/2*scaleDimensions)*(ellRectObj.h/2*scaleDimensions); let centX = ellRectObj.x + 0.5*ellRectObj.w; let centY = ellRectObj.y + 0.5*ellRectObj.h; let ellVal = (point_x-centX)*(point_x-centX)/aSqu + (point_y - centY)*(point_y-centY)/bSqu - 1; let alpha255 = Math.round(Math.min(1,Math.max(0,-ellVal/fullAlphaFact))*255); return alpha255; } dermObj.masks.acne = async ()=>{ //console.log('- ACNE MASK -') return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_acne_canvas")){ canvas = document.getElementById("fmc_acne_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_acne_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let acneData; try{ acneData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'acne')[0]; }catch(err){ console.error('error in getting acne data - ',err); } //console.log(' ACNE DATA: ',acneData) acneData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { const radius = Math.max(5,Math.min(detailLocation.length_weighted_intensity/15,30)); const opacity = Math.max(0.05,Math.min(detailLocation.length_weighted_intensity/300,0.5)); /* console.log('INTENSITY Length Weightened: ', detailLocation.length_weighted_intensity); console.log(radius, opacity) console.log('---------------'); */ if (detailLocation.length_weighted_intensity > 5){ await dermObj.masks.drawAcneCircle(detailLocation.x,detailLocation.y,radius,opacity,ctx); } }) } }) if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH ACNE IMAGE') dermObj.masks.images.acne = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.acne_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.acne } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawAcneCircle = async (coordsX,coordsY,radius,opacity,ctx) => { let scaleFact = 1.2; let lineWidth; try{ lineWidth = Math.max(2, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); }catch(err){ lineWidth = 2; } //dermObj.debug('LINE WIDTH: ', lineWidth) ctx.beginPath(); ctx.lineWidth = lineWidth; ctx.arc(coordsX,coordsY,radius, 0, 2*Math.PI); ctx.strokeStyle = `rgba(255,255,255,${opacity})`; ctx.fillStyle = `rgba(200,55,55,${opacity/5})`; ctx.fill(); ctx.stroke(); ctx.closePath(); return; } dermObj.masks.wrinkles = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_wrinkles_canvas")){ canvas = document.getElementById("fmc_wrinkles_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_wrinkles_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let wrinklesData; try{ wrinklesData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'wrinkles')[0]; //console.log(' wrinkles DATA: ',wrinklesData) wrinklesData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { //console.log(detailLocation.length_weighted_intensity, detailLocation.x.length) if (detailLocation.length_weighted_intensity > 0.2 && detailLocation.x.length > 15){ const scaleFact = Math.max(1, Math.ceil(Math.max(dermObj.masks.cropRect.width, dermObj.masks.cropRect.height)/400) ); detailLocation.x.forEach((xCoord, coordIndex) => { const radius = scaleFact * Math.max(1,detailLocation.intensity[coordIndex]*2); dermObj.masks.drawWrinkle(xCoord,detailLocation.y[coordIndex],radius,Math.max(0.05,0.5*detailLocation.intensity[coordIndex]),ctx) }) } }) } }) }catch(err){ console.error('error in getting wrinkles data - ',err); } if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH wrinkles IMAGE') dermObj.masks.images.wrinkles = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.wrinkles_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.wrinkles } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawWrinkle = async (coordsX,coordsY,radius,opacity,ctx) => { ctx.beginPath(); ctx.arc(coordsX,coordsY,radius, 0, 2*Math.PI); ctx.fillStyle = `rgba(255, 0, 0,${opacity})`; ctx.fill(); ctx.closePath(); return; } dermObj.masks.oiliness = async ()=>{ return new Promise(async (resolve,reject) => { if (dermObj.config.quizNoImage === true) { resolve() return; }; let canvas; if (document.getElementById("fmc_oiliness_canvas")){ canvas = document.getElementById("fmc_oiliness_canvas"); }else{ canvas = document.createElement("canvas"); canvas.id="fmc_oiliness_canvas"; canvas.classList.add("fmc_hidden_canvas"); document.getElementById("fmc_mask_canvas_container").appendChild(canvas); } const ctx = canvas.getContext('2d'); const img = new Image(); img.crossOrigin = "Anonymous"; img.onload = async ()=>{ canvas.width = img.naturalWidth; canvas.height = img.naturalHeight; ctx.drawImage(img,0,0) let oilinessData; try{ oilinessData = dermObj.backendData.revieve_response.results.filter(item => item.description == 'Skin shine')[0]; //console.log(' oiliness DATA: ',oilinessData) oilinessData.measurement_locations.forEach(async (faceLocation) => { if (faceLocation.visualization_data != null && faceLocation.visualization_data != undefined){ faceLocation.visualization_data.forEach(async (detailLocation) => { if (detailLocation.length_weighted_intensity > 0.1 && detailLocation.x.length > 1){ dermObj.masks.drawOiliness(detailLocation,ctx) } }) } }) }catch(err){ console.error('error in getting oiliness data - ',err); } if (dermObj.masks.obscurifyEyesFlag){ ctx.fillStyle = 'black'; ctx.fillRect(dermObj.masks.eyeRect.left, dermObj.masks.eyeRect.top, dermObj.masks.eyeRect.width, dermObj.masks.eyeRect.height); } //console.log('FINISH oiliness IMAGE') dermObj.masks.images.oiliness = await canvas.toDataURL("image/jpeg") const croppedImage = new Image(); croppedImage.crossOrigin = "Anonymous"; croppedImage.onload = async ()=>{ canvas.width = dermObj.masks.cropRect.width; canvas.height = dermObj.masks.cropRect.height; ctx.drawImage(croppedImage,dermObj.masks.cropRect.left,dermObj.masks.cropRect.top,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height, 0, 0,dermObj.masks.cropRect.width,dermObj.masks.cropRect.height ) dermObj.masks.images.oiliness_cropped = canvas.toDataURL("image/jpeg") resolve(); } croppedImage.src = dermObj.masks.images.oiliness } img.src = dml_fmc.backendData.original_image; }) } dermObj.masks.drawOiliness = async (visData,ctx) => { const opacity = 0.15; //visData.length_weighted_intensity * 0.1; ctx.beginPath(); visData.x.forEach((xCoord, index) => { if (index == 0){ ctx.moveTo(xCoord,visData.y[index]); }else{ ctx.lineTo(xCoord,visData.y[index]); } }) //ctx.lineTo(xCoord,visData.y[index]); ctx.fillStyle = `rgba(255, 0, 0,${Math.min(1,4*opacity)})`; ctx.closePath(); ctx.fill(); return; } dermObj.makePriceString =(productObj) => { let price = productObj.price; // use default variant price data if variants exist if (productObj.variants != undefined){ const defVariantArray = productObj.variants.filter((variant) => variant.default == true); if (defVariantArray.length > 0){ const defVariant = defVariantArray[0]; try{ if (defVariant.price != undefined && defVariant.price != '' && Number(defVariant.price) != 0 ){ price = defVariant.price; } }catch(err){console.error(err)} } } const currency = productObj.priceCurrency; let priceString = `${currency} ${price}`; //default if (currency == "¥"){ try{ let yenFormatter = new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }) priceString = `${yenFormatter.format(Number(price))}`; }catch(err){} } if (currency == "$MXN"){ //priceString = `${price} MXN`; try{ let mxnFormatter = new Intl.NumberFormat('es-MX', { style: 'currency', currency: 'MXN' }) priceString = `${mxnFormatter.format(Number(price))} MXN`; }catch(err){} } return priceString; } dermObj.storeLocator = {} dermObj.storeLocator.updateStoreLocations = async() => { return new Promise(async (resolve, reject)=>{ if (dermObj.config.storeLocator.showStores){ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "none"; }); try{ const storesArr = await dermObj.storeLocator.getStoreLocations() if (storesArr.length < 2){ resolve(); }else{ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "flex"; }); dermObj.debug("STORES: ", storesArr); storesArr.pop(); while(storesArr.length > 3){ storesArr.pop(); } dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeSection)=>{ storeSection.querySelectorAll('.fmc_skin_center_card').forEach((storeCard,index)=>{ if (storesArr.length > index){ storeCard.querySelector('.fmc_skin_center_name').innerHTML = storesArr[index].LocationName; storeCard.querySelector('.fmc_skin_center_distance').innerHTML = `${Number(storesArr[index].Distance.trim())} miles`; storeCard.querySelector('.fmc_skin_center_address_street').innerHTML = storesArr[index].AddressLine.trim(); storeCard.querySelector('.fmc_skin_center_address_zip_city').innerHTML = `${storesArr[index].PrimaryCity.trim()}, ${storesArr[index].SubDivision.trim()} ${storesArr[index].PostalCode.trim()}`; storeCard.querySelector('.fmc_skin_center_address_phone').innerHTML = storesArr[index].Phone.trim().replace(")",") ").replace(" "," "); storeCard.querySelector('.fmc_skin_center_call_button').setAttribute('href', `tel:${storesArr[index].Phone.trim().replace(")","").replace("(","").replace(" ","-")}`) storeCard.querySelector('.fmc_skin_center_directions_button').setAttribute('href', `https://www.google.com/maps?daddr=${storesArr[index].AddressLine.trim().replace(" ","+")}+${storesArr[index].PostalCode.trim()}+${storesArr[index].PrimaryCity.trim().replace(" ","+")}`) }else{ storeCard.style.display = "none"; } }); }) resolve(); } }catch(err){ reject(err); } }else{ dermObj.body.querySelectorAll('.fmc_results_store_location_section').forEach((storeLocationSection)=>{ storeLocationSection.style.display = "none"; }); resolve(); } }) } dermObj.storeLocator.getStoreLocations = async ()=>{ return new Promise(async(resolve,reject)=>{ const navigatorOptions = { enableHighAccuracy: true, timeout: 60000, maximumAge: 10*60*1000 // 10 mins ... 10 * 60s * 1000ms } try{ navigator.geolocation.getCurrentPosition((position)=>{ dermObj.storeLocator.lat = position.coords.latitude; dermObj.storeLocator.lng = position.coords.longitude; dermObj.debug("geolocation coords: ",{lat:dermObj.storeLocator.lat,lng:dermObj.storeLocator.lng}) let xhr = new XMLHttpRequest(); xhr.open("GET", `https://facemapping.me/getStoreLocations?lat=${dermObj.storeLocator.lat}&lng=${dermObj.storeLocator.lng}${dermObj.config.storeLocator.extraParameters}`,true); xhr.onload = async()=>{ try{ let response = xhr.responseText; if (typeof response == "string"){ response = JSON.parse(response); } if (dermObj.config.storeLocator.regexFilter != ""){ if (typeof response == "object"){ let storesToDisplay = []; response.forEach((store)=>{ console.log(store.LocationName) if (dermObj.config.storeLocator.regexFilter.test(store.LocationName)){ storesToDisplay.push(store); } }); storesToDisplay.push({"TotalCount" : String(storesToDisplay.length)}); resolve(storesToDisplay) } }else{ resolve(response); } }catch(err){ reject('error in store locator call'); } } xhr.onerror = ()=>{ reject('error in store locator call') } xhr.ontimeout = ()=>{ reject('timeout in store locator call') } xhr.send(); }); }catch(err){ console.log(err); reject(err); } }) } dermObj.twofa = {} dermObj.twofa.promptFinished = false; dermObj.twofa.code = ''; dermObj.twofa.inputEl = dermObj.body.querySelector('#fmc_2fa_input'); dermObj.twofa.popupEl = dermObj.body.querySelector('#fmc_2fa_prompt') dermObj.twofa.buttonEl = dermObj.body.querySelector('#fmc_2fa_submit') dermObj.twofa.prompt = async ()=>{ return new Promise(async (resolve, reject)=>{ dermObj.twofa.promptFinished = false; dermObj.twofa.code = ''; dermObj.twofa.showCodePrompt(); const promptInterval = setInterval(()=>{ if (dermObj.twofa.promptFinished){ clearInterval(promptInterval) resolve(); } },100) }) } dermObj.twofa.showCodePrompt = async () => { dermObj.twofa.popupEl.style.display = 'flex'; } dermObj.twofa.submit = async ()=>{ dermObj.twofa.code = dermObj.twofa.inputEl.value; dermObj.twofa.promptFinished = true; dermObj.twofa.popupEl.style.display = 'none'; } dermObj.twofa.checkInput = async ()=>{ if (dermObj.twofa.inputEl.value.length > 6){ dermObj.twofa.inputEl.value = dermObj.twofa.inputEl.value.substring(0,6); } if (dermObj.twofa.inputEl.value.length == 6){ dermObj.twofa.buttonEl.classList.remove('fmc_inactive'); }else{ dermObj.twofa.buttonEl.classList.add('fmc_inactive'); } } dermObj.swipeHandling = {}; dermObj.swipeHandling.swiperCollection = {}; dermObj.swipeHandling.addSwiper = async (swiperElement,leftSwipeFunction, rightSwipeFunction)=>{ let swiperId = swiperElement.id; if (swiperId == ''){ swiperId = `swiper_${Object.keys(dermObj.swipeHandling.swiperCollection).length + 1}`; swiperElement.id = swiperId; } swiperElement.style.pointerEvents = 'all'; swiperElement.addEventListener('touchstart', dermObj.swipeHandling.touchStart, false) swiperElement.addEventListener('mousedown', dermObj.swipeHandling.mouseStart, false) swiperElement.addEventListener('mouseup', (evt)=>{ swiperElement.style.cursor = 'grab' }, false) dermObj.swipeHandling.swiperCollection[swiperId] = { swiperElement : swiperElement, startX : 0, moveX : 0, swipePending : false, leftSwipeFunction: ()=>{leftSwipeFunction()}, rightSwipeFunction: ()=>{rightSwipeFunction()} }; dermObj.swipeHandling.swiperCollection[swiperId].swiperElement.style.cursor = 'grab' } dermObj.swipeHandling.touchStart = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.swiperElement.addEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.swipePending = true; swiperObj.startX = evt.touches[0].clientX; } dermObj.swipeHandling.mouseStart = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.swiperElement.addEventListener('mousemove', dermObj.swipeHandling.mouseMove, false); swiperObj.swipePending = true; swiperObj.startX = evt.clientX; dermObj.swipeHandling.swiperCollection[evt.target.id].swiperElement.style.cursor = 'grabbing' } dermObj.swipeHandling.touchMove = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.moveX = evt.touches[0].clientX - swiperObj.startX; if (swiperObj.moveX < -50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.leftSwipeFunction(); } if (swiperObj.moveX > 50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('touchmove', dermObj.swipeHandling.touchMove, false); swiperObj.rightSwipeFunction(); } } dermObj.swipeHandling.mouseMove = async (evt)=>{ const swiperObj = dermObj.swipeHandling.swiperCollection[evt.target.id]; swiperObj.moveX = evt.clientX - swiperObj.startX; if (swiperObj.moveX < -50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('mousemove', dermObj.swipeHandling.touchMove, false); swiperObj.leftSwipeFunction(); } if (swiperObj.moveX > 50 && swiperObj.swipePending){ swiperObj.swipePending = false; swiperObj.swiperElement.removeEventListener('mousemove', dermObj.swipeHandling.touchMove, false); swiperObj.rightSwipeFunction(); } } dermObj.checkEmailRequirement = async () => { if (!dermObj.config.requestEmailForResults){ return false; } if (window.localStorage.getItem('fmc_emsbflg') == 1){ return false; } if (dermObj.klaviyo.id != ''){ return false; } return true; } dermObj.emailDoubleCheckboxChanged = (evt) => { dermObj.checkEmailInput(); if (evt.target.checked == false) return; if (evt.target.id == 'fmc_email_checkbox_gdpr1' ){ evt.target.parentElement.parentElement.querySelector('#fmc_email_checkbox_gdpr2').checked = false; }else{ evt.target.parentElement.parentElement.querySelector('#fmc_email_checkbox_gdpr1').checked = false; } } dermObj.checkEmailInput = async ()=>{ clearTimeout(dermObj.checkEmailTimeout); dermObj.checkEmailTimeout = setTimeout(()=>{ let sendButton = document.getElementById("fmc_email_submit_button"); if (/^\w+([\.-]?\w+)*(\+[^@]+)?@\w+([\.-]?\w+)*(\.\w{2,})+$/.test(document.getElementById("fmc_email_input").value)){ dermObj.debug("activating send button"); document.getElementById("fmc_email_hint").style.opacity=0; if (dermObj.config.emailDoubleCheckbox == true){ let oneCheckboxChecked = false; sendButton.parentElement.querySelectorAll('#fmc_email_checkbox_gdpr1, #fmc_email_checkbox_gdpr2').forEach((checkbox)=>{ oneCheckboxChecked = oneCheckboxChecked || checkbox.checked; }) if (oneCheckboxChecked){ document.getElementById("fmc_email_submit_button").classList.remove("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.remove("fmc_disabled"); }else{ console.log("deactivating send button"); document.getElementById("fmc_email_submit_button").classList.add("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.add("fmc_disabled"); } }else{ document.getElementById("fmc_email_submit_button").classList.remove("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.remove("fmc_disabled"); } }else{ console.log("deactivating send button"); document.getElementById("fmc_email_submit_button").classList.add("fmc_inactive"); document.getElementById("fmc_email_submit_button").classList.add("fmc_disabled"); document.getElementById("fmc_email_hint").style.opacity=1; } },100) } dermObj.submitEmailForResults = async ()=>{ dermObj.submitEmailToBackend(); dermObj.hideEmailPopup(); if (dermObj.config.requestEmailForResults){ if (dermObj.showEmailRequestPopupFlag){ dermObj.sendGA360("main flow","request email for results - email submited") dermObj.sendGAFlowEvent("request email for results - email submited"); }else{ dermObj.sendGA360("main flow","send results - email submited"); dermObj.sendGAFlowEvent("send results - email submited"); } document.getElementById('fmc_email_input').value = ''; await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies){ window.localStorage.setItem("fmc_emsbflg",1); } if (dermObj.resultsBuilt) return; dermObj.gotoPage('results'); } } dermObj.skipEmailToResults = async () => { dermObj.sendGA360("main flow","skip email to results"); dermObj.sendGAFlowEvent("skip email to results"); dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'none'; dermObj.hideEmailPopup(); dermObj.gotoPage('waiting'); } dermObj.showClosableEmailPopup = () => { dermObj.resultsBuilt = true; const emailPopup = document.getElementById("fmc_email_popup"); const contentCard = emailPopup.querySelector('#fmc_email_content_card'); emailPopup.style.pointerEvents = "all"; emailPopup.style.display = "flex"; dermObj.sendGA360("main flow","save results clicked") dermObj.sendGAFlowEvent("save results clicked"); if (dermObj.body.offsetHeight > window.innerHeight * 1.1){ emailPopup.style.alignItems = "flex-start"; contentCard.style.marginTop = `${Math.round((window.innerHeight - contentCard.offsetHeight))*0.5}px`; }else{ emailPopup.style.alignItems = "center"; contentCard.style.marginTop = "unset"; } } dermObj.showEmailPopup = () => { dermObj.resultsBuilt = false; const emailPopup = document.getElementById("fmc_email_popup"); const contentCard = emailPopup.querySelector('#fmc_email_content_card'); emailPopup.style.display = "flex"; if (dermObj.currentPage.indexOf('fmc_results_') < 0){ dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'block'; }else{ dermObj.body.querySelector('#fmc_email_skip_button').style.display = 'none'; } if (dermObj.body.offsetHeight > window.innerHeight * 1.1){ emailPopup.style.alignItems = "flex-start"; contentCard.style.marginTop = `${Math.round((window.innerHeight - contentCard.offsetHeight))*0.5}px`; }else{ emailPopup.style.alignItems = "center"; contentCard.style.marginTop = "unset"; } } dermObj.clickOutEmailPopup = (evt)=>{ if (evt.target.id == "fmc_email_popup"){ dermObj.hideEmailPopup(); } } dermObj.hideEmailPopup = () => { document.getElementById("fmc_email_popup").style.display = "none"; } //window.dermObj = window.dermObj || {}; dermObj.loadedLibs = dermObj.loadedLibs || []; dermObj.loadExtraLibraries = async () =>{ return new Promise((resolve, reject)=>{ const libsToLoad = ['exif.js' , 'derm_capture.js'] if (dermObj.config.useFaceAi != false){ libsToLoad.push('face-api.js'); } if (!dermObj.loadedLibs.includes('face-api.js') && dermObj.config.useFaceAi != false){ const loadStartTimeFaceApi = Date.now(); dermObj.getScript('https://facemapping.me/face-api.js',function(){ dermObj.sendGA4Time('face_api_js' , Date.now() - loadStartTimeFaceApi); dermObj.loadedLibs.push('face-api.js'); }); } if (!dermObj.loadedLibs.includes('exif.js')){ const loadStartTimeExif = Date.now(); dermObj.getScript('https://facemapping.me/vendor/exif.js',function(){ dermObj.sendGA4Time('exif' , Date.now() - loadStartTimeExif); dermObj.loadedLibs.push('exif.js'); }); } if (!dermObj.loadedLibs.includes('derm_capture.js')){ const loadStartTimeDermCapture = Date.now(); dermObj.getScript('https://facemapping.me/derm_capture.js',function(){ dermObj.sendGA4Time('derm_capture' , Date.now() - loadStartTimeDermCapture); dermObj.loadedLibs.push('derm_capture.js'); }); } let extraLibsCheck = setInterval(async ()=>{ let extraLibsLoaded = true; libsToLoad.forEach((libToLoad ) => { extraLibsLoaded = extraLibsLoaded && dermObj.loadedLibs.includes(libToLoad); }) if (extraLibsLoaded){ clearInterval(extraLibsCheck); resolve({status : "success", message:"extra libraries loaded"}); } },50) }) } dermObj.chat = {} dermObj.chat.chatEnabledCheck = async () => { return new Promise(async (resolve,reject)=>{ if (!dermObj.config.chat.enabled || dermObj.config.chat.depId=='') { resolve(false); return; } if (typeof window.zE != 'function'){ resolve(false); return; } const skinCareChatDeps = zE('webWidget:get', 'chat:departments').filter((department) => {return department.id==dermObj.config.chat.depId}) if (skinCareChatDeps.length == 0){ resolve(false); return; }else{ if (skinCareChatDeps[0].status != 'online'){ resolve(false); return; } } if (dermObj.lang_code.split('-')[0] != 'en'){ resolve(false); return; } resolve(true); }) } dermObj.chat.openChat = async ()=>{ const chatEnabled = await dermObj.chat.chatEnabledCheck(); if (!chatEnabled){ return; } if (zE('webWidget:get', 'chat:isChatting')){ return; } window.zE('webWidget','show'); window.$zopim.livechat.window.show(); window.zE('webWidget','open'); zE('webWidget:on', 'chat:connected', function() { dermObj.sendGA360("main flow", `chat opened`); dermObj.sendGAFlowEvent( `chat opened`); console.log('successfully connected to Zendesk Chat!'); }); let currentlyChatting = zE('webWidget:get', 'chat:isChatting'); if (typeof dermObj.backendData != 'undefined'){ if (!currentlyChatting){ zE('webWidget', 'chat:send', dermObj.textData.chat_copy.withResult + ": " + window.location.href); } }else{ if (!currentlyChatting){ zE('webWidget', 'chat:send', dermObj.textData.chat_copy.withoutResult); } } } dermObj.urlParameterQueue = []; dermObj.urlParameterQueuePending = false; dermObj.addUrlParameters = async(fmcSnapshot) => { if (dermObj.isPercMatchMiniPage) return; //dermObj.debug(window.location.search, fmcSnapshot); let urlParamString=""; Object.keys(fmcSnapshot).forEach((key,index)=>{ if ( key == "fh"){ urlParamString += `&fmhid=${fmcSnapshot[key]}`; return; } if ( ['ts','fmc'].includes(key)){ return; } if (urlParamString.indexOf(key) == -1 && window.location.search.indexOf(key) == -1){ urlParamString += `&${key}=${fmcSnapshot[key]}`; } }) if (window.location.search == ""){ urlParamString = "?" + urlParamString.substring(1); } if (window.location.hostname.indexOf('dermalogica.com.au') > -1){ try{ urlParamString += `&fmc_hid=${fmcSnapshot['fh']}`; }catch(err){} } if (dermObj.config.shopButton.showPrices == true){ urlParamString += '&fmc_shpr=1'; }else{ urlParamString += '&fmc_shpr=0'; } window.history.pushState(dermObj.config.pageDict.results, '', `${window.location.href}${urlParamString}`); return; }; dermObj.checkCookieConsent = async () =>{ if (dermObj.config.allowCookies === true) return; if (dermObj.backend == "https://imb-backend-eu.herokuapp.com" || dermObj.backend == "https://eu.facemapping.me"){ if (typeof CookieConsent != 'undefined'){ dermObj.config.allowCookies = CookieConsent.consented; }else if (typeof Cookiebot != 'undefined'){ dermObj.config.allowCookies = Cookiebot.consented; }else if (typeof __axeptioSDK != 'undefined'){ try{ dermObj.config.allowCookies = __axeptioSDK.userPreferencesManager.choices.google_analytics; }catch(err){ dermObj.config.allowCookies = false; } }else{ dermObj.config.allowCookies = false; } }else{ dermObj.config.allowCookies = true; } return; }; dermObj.removeUrlParameters = async(targetPage = 'landing', remainingParameters = []) => { const parametersToRemove = [ 'ed6d4', 'b83d2', 'fmhid', 'ptg_id', 'be', 'r_ac', 'r_ds', 'r_du', 'r_ey', 'r_fr', 'r_hy', 'r_me', 'r_ra', 'r_re', 'r_sk', 'r_sm', 'r_te', 'r_un', 'r_wr', 'cnst', 'imupld', 'qni', 'qfc', 'qfl', 'fmc_shpr','qai_ds','qai_sk','qai_fn','qai_an', 'fmc_mnpg_d', 'fmc_mnpg_sc', 'bdge_var'] let url = new URL(window.location.href); let qniOnStart = url.searchParams.has('qni') && !url.searchParams.has('fmhid'); parametersToRemove.forEach(param => { if (qniOnStart && param == 'qni') return; if (remainingParameters.includes(param)) return; url.searchParams.delete(param); }); // Use history.replaceState() to update the URL without adding a new history entry history.replaceState(dermObj.config.pageDict[targetPage], '', url); /* old code if (window.location.search != ''){ const urlParameterArray = window.location.search.replace('?','').split('&'); let remainingParameterString = ''; urlParameterArray.forEach((parameterString)=>{ const paramKey = parameterString.split('=')[0]; if (!parametersToRemove.includes(paramKey)){ if (remainingParameterString == ''){ remainingParameterString = `?${parameterString}`; }else{ remainingParameterString += `&${parameterString}`; } } }) window.history.pushState(dermObj.config.pageDict[targetPage], '', `${window.location.href.split('?')[0]}${remainingParameterString}`); } */ } const mapRevieveToNumber = (revValue) => { if (typeof revValue != "number") return -1; let revNum; if (revValue < 0.3){ revNum = 0; }else if (revValue <= 0.7 ){ revNum = 1; }else{ revNum = 2; } return revNum; } dermObj.getRevSnapShot = async(facemap) => { return new Promise(async(resolve, reject) => { try{ let backendLabel = dermObj.getBackendLabel(); let genNum = dermObj.pageControls.capture.b83d2; let aNum; if (dermObj.pageControls.capture.ed6d4 < 18){ aNum = 0; }else if (dermObj.pageControls.capture.ed6d4 < 25){ aNum = 1; }else if (dermObj.pageControls.capture.ed6d4 < 35){ aNum = 2; }else if (dermObj.pageControls.capture.ed6d4 < 45){ aNum = 3; }else if (dermObj.pageControls.capture.ed6d4 < 55){ aNum = 4; }else if (dermObj.pageControls.capture.ed6d4 < 65){ aNum = 5; }else{ aNum = 6; } const fmcSnapshot = { ed6d4: aNum, b83d2 : genNum, fh : facemap.hashid, be: backendLabel, ts: Date.now(), r_ac : mapRevieveToNumber(facemap.revieve_acne_value), r_ds : mapRevieveToNumber(facemap.revieve_dark_spots_value), r_du : mapRevieveToNumber(facemap.revieve_dull_skin_value), r_ey : mapRevieveToNumber(facemap.revieve_eyes_value), r_fr : mapRevieveToNumber(facemap.revieve_freckles_value), r_hy : mapRevieveToNumber(facemap.revieve_hyperpigmentation_value), r_me : mapRevieveToNumber(facemap.revieve_melasma_value), r_ra : mapRevieveToNumber(facemap.revieve_radiance_value), r_re : mapRevieveToNumber(facemap.revieve_redness_value), r_sk : mapRevieveToNumber(facemap.revieve_skin_shine_value), r_sm : mapRevieveToNumber(facemap.revieve_smoothness_value), r_te : mapRevieveToNumber(facemap.revieve_texture_value), r_un : mapRevieveToNumber(facemap.revieve_uneven_skin_tone_value), r_wr : mapRevieveToNumber(facemap.revieve_wrinkles_value), fmc : 1 } fmcSnapshot.rspg = 'default'; try{ if (facemap.dioxide_data == undefined || facemap.dioxide_data == null){ facemap.dioxide_data = {...dermObj.dioxideData}; } }catch(errInner){} try{ if (dermObj.config.pageDict.results == 'fmc_results_prep_treat_glow' && facemap.dioxide_data.prep_treat_glow != null){ fmcSnapshot.rspg = 'prep_treat_glow'; } if (dermObj.config.pageDict.results == 'fmc_results_brand_campaign' && facemap.dioxide_data.brand_campaign != null){ fmcSnapshot.rspg = 'brand_campaign'; } }catch(errInner){} if (dermObj.config.pageDict.results == 'fmc_results_ai_steps'){ fmcSnapshot.rspg = 'ai_steps'; } if (dermObj.config.pageDict.results == 'fmc_results_quiz_no_image'){ fmcSnapshot.rspg = 'quiz_no_image'; if (dml_fmc.config.quizNoImage == true){ fmcSnapshot.qni = 1; } if (dermObj.quizFromConsent == true){ fmcSnapshot.qfc = 1; } } if (dermObj.config.qniChoiceFromLanding == true){ if (dermObj.quizFromLanding == true){ fmcSnapshot.qfl = 1; }else{ fmcSnapshot.qfl = 0; } } if (dermObj.config.pageDict.results == 'fmc_estimated_results'){ fmcSnapshot.rspg = 'estr'; } if (dermObj.backendData.dioxide_data != undefined && dermObj.backendData.dioxide_data != null){ try{ fmcSnapshot.ptg_id = dermObj.backendData.dioxide_data.prep_treat_glow.ptg_id; }catch(err){ console.warn(err) } } resolve(fmcSnapshot); }catch(err){ reject(err); } }) } dermObj.updateLocalStorage = async (fmcSnapshot)=>{ //dermObj.debug('UPDATE LOCAL STORAGE CALL') if (dermObj.config.histFmcObj !== true) return; try{ let rSum = 0; Object.keys(fmcSnapshot).forEach((snapKey) => { if (snapKey.indexOf("r_")>-1){ if (typeof fmcSnapshot[snapKey] == "number"){ rSum += fmcSnapshot[snapKey] } } }); if (rSum > 0){ let localFmcData = window.localStorage.getItem("derm_fmh1"); if (!localFmcData){ localFmcData = []; }else{ localFmcData = JSON.parse(localFmcData); } localFmcData.push(fmcSnapshot) if (localFmcData.length > 10){ localFmcData.shift(); } window.localStorage.setItem("derm_fmh1",JSON.stringify(localFmcData)); } }catch(e){ console.error(e); } // match percentage storage object try{ if (fmcSnapshot.ptg_id != undefined && fmcSnapshot.ptg_id != null && dermObj.config.percMatchFolder != ''){ const date = new Date(fmcSnapshot.ts); const months = ['january', 'february', 'march', 'april', 'may', 'june', 'july', 'august', 'september','october', 'november' , 'december']; const day = date.getDate(); const month = dermObj.textData.perc_match[months[date.getMonth()]]; const fullYeah = date.getFullYear(); const dateString = `${month} ${day}, ${fullYeah}`; let clusterId; if (fmcSnapshot.ptg_id < 59){ clusterId = Math.ceil(fmcSnapshot.ptg_id / 2 - 0.1); }else{ switch(String(fmcSnapshot.ptg_id)){ case '59': case '60': clusterId = 11; break; case '61': case '62': clusterId = 16; break; case '63': case '64': clusterId = 23; break; case '65': case '66': clusterId = 25; break; default: clusterId = -1; console.error(`no cluster found for ptg_id ${fmcSnapshot.ptg_id}`) } } //dermObj.debug('fmc SNAPSHOT: ',fmcSnapshot); if (clusterId > 0){ fetch(`https://facemapping.me/clstr/${dermObj.config.percMatchFolder}/${clusterId}.json`) .then(async (res)=>{ try{ const percMatchDict = await res.json(); dermObj.percMatchData = percMatchDict; //dermObj.debug('percMatchDict: ',percMatchDict);; let fmcLink; if (dermObj.isPercMatchMiniPage){ let urlParams = `?fmhid=${fmcSnapshot.fh}&rspg=prep_treat_glow&be=${dml_fmc.getBackendLabel()}`; if (dermObj.miniPageSettings.fmcPageUrl != undefined && dermObj.miniPageSettings.fmcPageUrl != ''){ fmcLink = dermObj.miniPageSettings.fmcPageUrl + urlParams; }else{ fmcLink = 'https://facemapping.me' + urlParams; } }else{ fmcLink = window.location.href; } dermObj.fmcResultsUrl = fmcLink; let smac = dermObj.smearCd(dermObj.backendData.access_code, fmcSnapshot.fh); window.localStorage.setItem('derm_mp',JSON.stringify({percent_matches : percMatchDict, ttcopy: dermObj.textData.perc_match.based_on_copy.replace('__DATE__',dateString), ctacopy: dermObj.textData.perc_match.view_results_cta, fmc_link: fmcLink, fh: fmcSnapshot.fh, ts: fmcSnapshot.ts, date_string:dateString, smac: smac})); try{ if (dermObj.isPercMatchMiniPage == true && window.dsrp && window.dsrp.showPercMatches != undefined){ window.dsrp.showPercMatches(); } }catch(badgeErr){console.error(badgeErr)} }catch(parseErr){ console.error(parseErr) } }) .catch((err) => { console.error(err); }); } }else{ return; } }catch(err){ console.error(err); } } dermObj.queueUrlParameters = (paramObj)=>{ clearTimeout(dermObj.urlParameterQueueTimeout); dermObj.urlParameterQueue.push(paramObj); dermObj.urlParameterQueueTimeout = setTimeout(()=>{ dermObj.workUrlParameterQueue() },200) } dermObj.workUrlParameterQueue = ()=> { if (dermObj.urlParameterQueuePending == true) return; try{ dermObj.urlParameterQueuePending = true; const curUrl = new URL(window.location.href); const params = new URLSearchParams(curUrl.search); // Add new parameters while (dermObj.urlParameterQueue.length > 0){ let curParamPairs = dermObj.urlParameterQueue.pop(); for (const [parKey, parVal] of Object.entries(curParamPairs)){ params.set(parKey, parVal); } } // Update URL with new parameters const newUrl = `${curUrl.protocol}//${curUrl.host}${curUrl.pathname}?${params.toString()}`; // Push new URL to history history.pushState({}, '', newUrl); }catch(err){ console.log(err) }finally{ dermObj.urlParameterQueuePending = false; } } dml_fmc.smearCd = (num, pattern)=>{ let newStr = ''; let patUsed = [...new Set(pattern.split(''))]; if (patUsed.length < 10){ patUsed.push(...['!','%','&','#','=','?','$','+','€','µ']).slice(0,10-patUsed.length); } try{ String(num).split('').forEach((digit) => { newStr += patUsed[Number(digit)]; }) return newStr; }catch(err){ console.error(err); return num; } } dml_fmc.clearCd = (smearedCd, pattern)=>{ let newStr = ''; let patUsed = [...new Set(pattern.split(''))]; if (patUsed.length < 10){ patUsed.push(...['!','%','&','#','=','?','$','+','€','µ']).slice(0,10-patUsed.length); } try{ String(smearedCd).split('').forEach((char) => { newStr += String(patUsed.indexOf(char)); }) return newStr; }catch(err){ console.error(err); } } dermObj.setLocalStorageWithExp = async (itemName, itemValue, timeValid='7d')=>{ try{ await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies != true){ return 0; } localStorage.setItem(itemName, `${itemValue}_${Date.now() + timeToMilliseconds(timeValid)}`) }catch(err){ console.error(err); } return 0; } dermObj.getLocalStorageWithExp = (localStorageName) => { const myVal = localStorage.getItem(localStorageName); if (!myVal) { return [null, false]; } const expDateMatch = myVal.match(/_(\d+)$/); const expDate = expDateMatch ? parseInt(expDateMatch[1], 10) : null; const valueWithoutExpDate = expDateMatch ? myVal.replace(/_\d+$/, '') : myVal; const now = Date.now(); const isValid = expDate ? now < expDate : false; return [valueWithoutExpDate, isValid]; } function timeToMilliseconds(timeStr) { const timeUnits = { s: 1000, min: 60 * 1000, h: 60 * 60 * 1000, d: 24 * 60 * 60 * 1000, m: 30 * 24 * 60 * 60 * 1000 }; let match = timeStr.match(/^(\d+)(s|min|h|d|m)$/); if (!match) { console.warn("Invalid time format - using default"); match = '7d'.match(/^(\d+)(s|min|h|d|m)$/); } const value = parseInt(match[1], 10); const unit = match[2]; return value * timeUnits[unit]; } dermObj.badges = {} dermObj.badges.overlayEl = document.getElementById('fmc_badge_page_overlay'); [savedBadgeConfig, savedBadgeConfigValid] = dermObj.getLocalStorageWithExp('fmc_bdg_cfg'); if (savedBadgeConfigValid){ try{ dermObj.config.badges = JSON.parse(savedBadgeConfig); }catch(err){ console.error(err); } } dermObj.badges.variations = { 'fc-var-l-blank' : { handle: 'blank', class: '', pageId: 'fmc_landing_page_default' }, 'fc-var-l-rd': { handle: 'fc-var-l-rd', class: 'fastcompany-variation-round-dark-bg', pageId: 'fmc_landing_page_default' }, 'fc-var-l-rw': { handle: 'fc-var-l-rw', class: 'fastcompany-variation-round-white-bg', pageId: 'fmc_landing_page_default' }, 'fc-var-l-sd': { handle: 'fc-var-l-sd', class: 'fastcompany-variation-stamp-dark', pageId: 'fmc_landing_page_default' }, 'fc-var-l-bd': { handle: 'fc-var-l-bd', class: 'fastcompany-variation-banner-dark', pageId: 'fmc_landing_page_default' } } dermObj.badges.showVariation = (variationHandle, updateLocSt = true)=>{ try{ dermObj.badges.overlayEl.classList.remove(...dermObj.badges.overlayEl.classList); }catch(err){console.error(err)} if (!Object.keys(dermObj.badges.variations).includes(variationHandle)) return 'badge handle unknown'; try{ dermObj.config.badges[dermObj.badges.variations[variationHandle].pageId] = variationHandle; (async ()=>{ try{ if (updateLocSt != true) return; await dermObj.checkCookieConsent(); if (dermObj.config.allowCookies == false) return; dermObj.setLocalStorageWithExp('fmc_bdg_cfg',JSON.stringify(dermObj.config.badges), '1h'); }catch(errJSON){ console.error(errJSON) } })() if (dermObj.badges.variations[variationHandle].pageId == dermObj.currentPage){ dermObj.badges.overlayEl.className = `badge-for-landing-default ${dermObj.badges.variations[variationHandle].class}` dermObj.queueUrlParameters({'bdge_var':variationHandle}); } }catch(err){ console.error(err); dermObj.badges.overlayEl.classList.remove(...badgeOverlay.classList); } } /* //badges - to enable we also need to change the landing page to the default one const fastCompanyBadgeVariations = ['fastcompany-variation-round-dark-bg','fastcompany-variation-round-white-bg', 'fastcompany-variation-stamp-dark' ,'fastcompany-variation-banner-dark']; const urlParamShort = ['fc-var-l-rd','fc-var-l-rw', 'fc-var-l-sd' ,'fc-var-l-bd']; const fastCompanyBadgeIndex = Math.min(Math.floor(Math.random()*fastCompanyBadgeVariations.length + 1),fastCompanyBadgeVariations.length ); if (fastCompanyBadgeIndex <= fastCompanyBadgeVariations.length - 1){ dermObj.config.badges.fmc_landing_page_default = `badge-for-landing-default ${fastCompanyBadgeVariations[fastCompanyBadgeIndex]}`; dermObj.queueUrlParameters({'bdge_var':urlParamShort[fastCompanyBadgeIndex]}); }else{ dermObj.queueUrlParameters({'bdge_var':'blank'}) } */ dermObj.crm = {}; dermObj.crm.send = (emailType, email) => { const revieveData = {} Object.keys(dermObj.backendData).forEach((key)=>{ if (/revieve_.+_value$/.test(key) ){ revieveData[key] = dermObj.backendData[key]; } }) let payload = { "dioxideData": dermObj.dioxideData, "revieveData": revieveData, "emailType": emailType, "email": email, //"topConcern": topConcern, "countryCode": dermObj.config.crm.country } delete payload.dioxideData.email_html; delete payload.dioxideData.email_subject; let xhr = new XMLHttpRequest(); xhr.open("POST", "https://facemapping.me/handleCrmRequest", true); xhr.setRequestHeader('Content-Type', 'application/json'); xhr.send(JSON.stringify(payload)); //console.log(payload) } dermObj.klaviyo = {} dermObj.klaviyo.id = ''; dermObj.klaviyo.getId = async () => { return new Promise((resolve,reject)=>{ dermObj.klaviyo.id = '' let intervalCounter = 0; let klaviyoInterval = setInterval(()=>{ if (typeof window._learnq == 'undefined'){ if (intervalCounter > 10){ clearInterval(klaviyoInterval); resolve('no klaviyo object'); } }else{ clearInterval(klaviyoInterval); try{ if (_learnq.isIdentified()){ dermObj.klaviyo.id = _learnq.push(['_getIdentifiers']).$exchange_id; resolve(dermObj.klaviyo.id); } }catch(err){ console.log(err); dermObj.klaviyo.id = ''; reject(err); } } intervalCounter++; },500); }) } dermObj.blogs = {} dermObj.blogs.loaded = false; dermObj.blogs.concernBlogs = {}; dermObj.blogs.load = ()=>{ if (dermObj.config.blogs_file == '') { dermObj.blogs.concernBlogs = {}; dermObj.blogs.loaded = true; return; } const xhr = new XMLHttpRequest(); xhr.open('GET', `https://facemapping.me/blogs/${dermObj.config.blogs_file}`, true); xhr.responseType = 'json'; xhr.onload = () => { if (xhr.status == 200){ dermObj.debug('blog request response: ', xhr.response); dermObj.blogs.concernBlogs = xhr.response; }else{ dermObj.blogs.concernBlogs = {}; console.error(`Could not load blogfile ${dermObj.config.blogs_file} - Status: ${xhr.status} - ${xhr.statusText}`); } dermObj.blogs.loaded = true; }; xhr.send(); } dermObj.treatments = {} dermObj.treatments.bookNowDict = {} dermObj.treatments.updateBanners = ()=>{ try{ const skinServices = [...dermObj.dioxideData.skin_services] const skinServSections = dermObj.body.querySelectorAll('.fmc_results_treatment_section'); skinServSections.forEach((skinServSection) => { let cardElements = skinServSection.querySelectorAll('.fmc_treatment_card'); if (cardElements.length > skinServices.length){ const indexToRemoveStart = skinServices.length for (let i = indexToRemoveStart; i < cardElements.length; i++) { cardElements[i].remove(); } } if (cardElements.length < skinServices.length){ for (let i = 0; i < skinServices.length - cardElements.length; i++) { let clone = cardElements[0].cloneNode(true); skinServSection.insertBefore(clone, cardElements[0].nextSibling); } } cardElements = skinServSection.querySelectorAll('.fmc_treatment_card'); // re-select all card Elements cardElements.forEach((cardElement, index) => { let skinServ = skinServices[index]; cardElement.className = 'fmc_treatment_card' cardElement.classList.add(`fmc_${skinServ.name.replace(/&/g,'').replace(/\s/g, '_')}`); cardElement.querySelector('.fmc_treatment_name_type').innerHTML = skinServ.name.replace('pro ', ''); cardElement.querySelector('.fmc_treatment_description').innerHTML = skinServ.description; try{ if (skinServ.name.indexOf('clear start') > -1){ cardElement.querySelector('.fmc_treatment_name_pro').style.display = "none"; }else{ cardElement.querySelector('.fmc_treatment_name_pro').style.display = "block"; } }catch(err){console.error(err)} cardElement.querySelector('button#fmc_treatment_cta').onclick = () => { dermObj.sendGA360("main flow",`treatment cta clicked - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment cta clicked - ${skinServ.name}`); // CHANGE BACK AFTER LINKS ARE FIXED //window.open('https://www.dermalogica.com/pages/store-locator','_blank'); window.open(skinServ.url,'_blank'); } if (dermObj.treatments.bookNowUrl != '' && dermObj.treatments.bookNowUrl != undefined && skinServ.booking_id != '' && skinServ.booking_id != undefined){ const treatKey = skinServ.name; cardElement.querySelector('button#fmc_treatment_cta').style.display = "none"; cardElement.querySelector('button#fmc_treatment_cta_book_now').style.display = "flex"; cardElement.querySelector('button#fmc_treatment_cta_book_now').onclick = () => { dermObj.sendGA360("main flow",`treatment cta book now clicked - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment cta book now clicked - ${skinServ.name}`); // CHANGE BACK AFTER LINKS ARE FIXED //window.open('https://www.dermalogica.com/pages/store-locator','_blank'); window.open(`${dermObj.treatments.bookNowUrl}?code=${skinServ.booking_id}&fmc_emb=1`,'_blank'); } } skinServSection.style.display = 'flex' dermObj.sendGA360("main flow",`treatment displayed - ${skinServ.name}`); dermObj.sendGAFlowEvent(`treatment displayed - ${skinServ.name}`); }) }) }catch(err){ try{ dermObj.body.querySelectorAll('.fmc_results_treatment_section').forEach((treatmentSection)=> treatmentSection.style.display = 'none'); }catch(err2){ console.err(err2) } console.warn(err) } } dermObj.customizationCheck = (domainToCheck, microPagePath) => { const regex = new RegExp(`${domainToCheck}(:|$)`,'g') if (dermObj.config.forcedPage != ''){ try{ let forcedHostName = dermObj.config.forcedPage.replace('https://','').replace('http://','').split('/')[0] if (regex.test(forcedHostName) || dermObj.config.forcedPage.indexOf(`/${microPagePath}`) > -1){ return true; }else{ return false; } }catch(err){ console.error(err); return false; } } if (regex.test(window.location.hostname)){ return true; } if (window.location.pathname.indexOf(`/${microPagePath}`) > -1){ return true; } return false; } dermObj.customization = {} // GENERAL DERMALOGICA AND FACEMAPPING.ME RULES if ( /dermalogica\./g.test(window.location.hostname) || /dermalogica./g.test(dermObj.config.forcedPage) || ( /facemapping.me/g.test(window.location.hostname) && window.location.pathname == '/' ) || /facemapping.me[^\/]?/g.test(dermObj.config.forcedPage)){ if (dermObj.config.forcedPage == '' || /dermalogica./g.test(dermObj.config.forcedPage) || /facemapping.me[^\/]?/g.test(dermObj.config.forcedPage)){ dermObj.debug("CUSTOMIZE FOR dermalogica pages and facemapping.me without 3rd parties"); dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; } } //for facemapping.me and localhost only if (/facemapping.me/g.test(window.location.hostname) || /facemapping.me/g.test(dermObj.config.forcedPage) || /localhost/g.test(window.location.hostname)){ try{ document.getElementById("fmc_manageCookiebotLink").style.display="block"; }catch(err){ console.warn(err); } if ( (/facemapping.me/g.test(window.location.hostname) || /facemapping.me/g.test(dermObj.config.forcedPage)) && window.location.pathname == '/'){ dermObj.config.useTreatmentBanners = true; } } dermObj.applyCustomizations = async ()=>{ if (dermObj.isPercMatchMiniPage){ dermObj.body.classList.add('is-fmc-mini-coll'); try{ const outsideFMCExitBtn = document.querySelector('#dml_widget_wrapper > #dml_widget_exit'); if (outsideFMCExitBtn != undefined){ outsideFMCExitBtn.style.display = "none" } }catch(err){} dermObj.config.pageDict.landing = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_page_perc_match_coll'; dermObj.config.quizAfterImage = false; dermObj.config.showQniConsentButton = false; dermObj.config.requestEmailForResults = false; dermObj.config.allowCookies = true; dermObj.config.percMatchFolder = dermObj.miniPageSettings.percMatchFolder; dermObj.config.useShopify = true; if (dermObj.miniPageSettings.forcedCountry != undefined){ dermObj.config.forcedCountry = dermObj.miniPageSettings.forcedCountry; } } if (dermObj.config.shopButton.showPrices){ dermObj.body.classList.add('dml_show_prices'); } if (dermObj.config.hideEmailButtons){ dermObj.config.requestEmailForResults = false; dermObj.body.classList.add('dml_no_email_buttons') } if (dermObj.config.shopButton.hide){ dermObj.body.classList.add('dml_hide_store_buttons') } if (dermObj.config.shopButton.textOverride != ''){ dermObj.afterTextRendering = ()=>{ document.querySelectorAll(`[data-widget-text-term=shop]`).forEach((htmlEl)=>{ htmlEl.innerHTML = dermObj.config.shopButton.textOverride; }) } } if (dermObj.config.showQniConsentButton && window.location.search.indexOf('only_upload=1') < 0){ if (window.location.search.indexOf('fmhid=') < 0){ dermObj.body.querySelector('#fmc_consent_quiz_button').style.display = 'block'; } } if (dermObj.config.showSaveEmailMobile){ document.querySelector('#fmc_results_page_default #fmc_save_email_results.fmc_email_button_tag').classList.add('fmc_display_mobile'); document.querySelector('#fmc_results_page_default .fmc_branding_logo_white').classList.add('fmc_hide_mobile'); } if (dermObj.config.ga4dst !== undefined && dermObj.config.ga4dst !== null ){ try{ gtag('config',dermObj.config.ga4dst); }catch(err){console.error()}; } if (dermObj.config.brandingLogoUrl != ''){ dermObj.body.querySelectorAll('.fmc_branding_logo_white').forEach((brandingLogoDiv)=>{ brandingLogoDiv.style.backgroundImage = `url('${dermObj.config.brandingLogoUrl}')`; if (dermObj.config.brandingLogoScale != 1){ brandingLogoDiv.style.transform = `scale(${dermObj.config.brandingLogoScale})`; } }) dermObj.body.querySelectorAll('.fmc_branding_logo_grey').forEach((brandingLogoDiv)=>{ brandingLogoDiv.style.backgroundImage = `url('${dermObj.config.brandingLogoUrlGrey}')`; if (dermObj.config.brandingLogoScale != 1){ brandingLogoDiv.style.transform = `scale(${dermObj.config.brandingLogoScale})`; } }) } if (window.location.search.indexOf('qni=1') < 0 && window.location.search.indexOf('rspg') > -1){ dermObj.config.quizNoImage = false; } if (dermObj.config.qniChoiceFromLanding == true && window.location.search.indexOf('qni=1') < 0){ dermObj.body.querySelectorAll('.fmc_landing_default_flow').forEach((defEl) => {defEl.style.display='none'}); dermObj.body.querySelectorAll('.fmc_landing_ai_qni_flow').forEach((aiQniEl) => {aiQniEl.style.display='flex'}); }else{ dermObj.body.querySelectorAll('.fmc_landing_default_flow').forEach((defEl) => {defEl.style.display='flex'}); dermObj.body.querySelectorAll('.fmc_landing_ai_qni_flow').forEach((aiQniEl) => {aiQniEl.style.display='none'}); } if (dermObj.config.forcedLang != undefined && dermObj.config.forcedLang != ''){ dermObj.lang_code = dermObj.config.forcedLang; } try{ dermObj.referrer = dermObj.config.forcedPage != '' ? dermObj.config.forcedPage : dermObj.referrer; }catch(err){console.log(err)} await dermObj.checkCookieConsent() if (dermObj.config.allowCookies){ if (dermObj.isPercMatchMiniPage != true){ let qaiFlagStItem = window.localStorage.getItem("fmc_qai"); if (window.location.search.indexOf('force_qai=1') > -1){ qaiFlagStItem = '1_'+Date.now(); }else{ qaiFlagStItem = '0_'+Date.now(); } if (qaiFlagStItem != null && qaiFlagStItem != undefined){ try{ let qaiFlagVal = qaiFlagStItem.split('_')[0]; let qaiFlagExp = qaiFlagStItem.split('_')[1]; if (qaiFlagExp - Date.now() > 0 ){ if (qaiFlagVal == 1){ dermObj.config.quizAfterImage = true; }else if (qaiFlagVal == 0){ dermObj.config.quizAfterImage = false; } } }catch(qaierr){console.log(qaierr)}; } let qaiFlagNewExp = Date.now() + 2 * 3600 * 1000; // 2 hours valid let qaiFlagNewVal = dermObj.config.quizAfterImage == true ? 1 : 0; window.localStorage.setItem("fmc_qai",`${qaiFlagNewVal}_${qaiFlagNewExp}`); } if ("TRUE"=='TRUE' && dermObj.config.useSentry === true){ dermObj.sentry.loadScript(); } if (window.location.search.indexOf('only_upload=1') > -1){ dermObj.config.pageDict.landing = 'fmc_capture_page_default'; dermObj.showConsent(); } } } // single pages if (dermObj.customizationCheck('arcstore.co.za')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/arcstore.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/arcstore_grey.png"; dermObj.config.brandingLogoScale = 2; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautyboxpangbourne.co.uk') || dermObj.customizationCheck('www-beautyboxpangbourne-co-uk.filesusr.com')){ dermObj.config.forcedPage = "https://www-beautyboxpangbourne-co-uk.filesusr.com/"; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautybrands.com', 'beautybrands')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/beautybrands.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/beautybrands_grey.png"; dermObj.config.brandingLogoScale = 5; dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('beautyfeatures.ie')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } // // uses default settings // // uses default settings if (dermObj.customizationCheck('bluemercury.com','bluemercury')){ dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/derm_bluemercury_logo.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/derm_bluemercury_logo_grey.png"; dermObj.config.brandingLogoScale = 3; } // // uses default settings // uses default settings // // NOT EMBED ANYMORE? https://www.cosmania.nl/nl/blog/artikel/doe-de-dermalogica-face-mapping/ if (dermObj.customizationCheck('dermalogica.ae')){ dermObj.config.sendAlsoToNewEmailEndpoint = true; try{ dermObj.config.klavyioId = "Vm3bBM"; dermObj.config.klavyioListId = "U5gh2B"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.ca')){ try{ if (window.location.pathname.indexOf('/fr/') == 0 || dermObj.config.forcedPage.indexOf('/fr/') > 0){ dermObj.config.forcedLanguage = 'fr' } }catch(err){} dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.quizAfterImage = true; try{ dermObj.config.klavyioId = "WQ7Ua9"; dermObj.config.klavyioListId = "WbV7jf"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } const dermCaResultsInt = setInterval(()=>{ if (dermObj.currentPage == 'fmc_results_prep_treat_glow'){ clearInterval(dermCaResultsInt); dermObj.pageControls.prep_treat_glow.build(); } },1000) } if (dermObj.customizationCheck('dermalogica.co.kr')){ dermObj.config.requestEmailForResults = false; dermObj.config.shopButton.showPrices = false; dermObj.config.qniChoiceFromLanding = true; dermObj.config.forcedCountry = "KR"; } if (dermObj.customizationCheck('dermalogica.co.nz')){ dermObj.config.shopButton.showPrices = false; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'derm_nz'; dermObj.config.sendAlsoToNewEmailEndpoint = true; dermObj.config.qniChoiceFromLanding = true; try{ dermObj.config.klavyioId = "PcLf2F"; dermObj.config.klavyioListId = "MyH4aY"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.co.uk')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.emailDoubleCheckbox = true; dermObj.config.requestEmailForResults = false; dermObj.config.percMatchFolder = 'GB'; /* if (window.location.search.indexOf('force_qai=') == -1){ dermObj.config.quizAfterImage = Math.random() < 0.5; } */ dermObj.config.quizAfterImage = true; try{ dermObj.widget_wrapper.parentElement.parentElement.style.padding=0 }catch(err){} try{ // remove anouncementbar for FMC pages to have more space document.getElementById('splide_slide-announcement-bar').style.zIndex = "-100"; document.getElementById('splide_slide-announcement-bar').style.pointerEvents = "none"; document.getElementById('splide_slide-announcement-bar').style.opacity = "0"; document.getElementById('splide_slide-announcement-bar').style.position = "fixed"; }catch(err){} try{ // overwrite resize wrapper window.removeEventListener('resize', dermObj.resizeWrapper); dermObj.resizeWrapper = function (){ if (dermObj.widget_wrapper.style.height != "auto"){ let heightReduction; try{ heightReduction = document.querySelector('sticky-header.header-wrapper').offsetHeight; }catch(errInner){ heightReduction = 0; } dermObj.widget_wrapper.style.height = (window.innerHeight-heightReduction) + "px"; dermObj.body.style.height = (window.innerHeight-heightReduction) + "px"; } } window.addEventListener('resize', dermObj.resizeWrapper); dermObj.resizeWrapper(); setTimeout(()=>{ dermObj.resizeWrapper(); },1000) }catch(err){} try{ dermObj.config.klavyioId = "WcNx8p"; dermObj.config.klavyioListId = "Xkj7Rc"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } dermObj.config.chat.enabled = false; dermObj.config.chat.key = 'gb_and_ie'; dermObj.config.chat.depId = ''; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; /* const abcTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); dermObj.config.pageDict.results = abcTestResultsPageArray[resultsPageIndex]; */ //dermObj.pageControls.brand_campaign.proBrightLink = 'https://www.dermalogica.co.uk/pages/our-dermalogica-stores-uk'; dermObj.config.blogs_file = 'blogs_GB.json'; dml_fmc.customization.updateShopifyCart = (cart) => { const itemBubble = document.getElementById('cart-icon-bubble'); if (!itemBubble.querySelector('div.cart-count-bubble')){ const bubbleBadge = document.createElement('div'); bubbleBadge.classList.add('cart-count-bubble'); const hiddenItemString = cart.item_count > 1 ? `${cart.item_count} items` : '1 item'; bubbleBadge.innerHTML = `${hiddenItemString}`; itemBubble.appendChild(bubbleBadge); }else{ itemBubble.querySelector('div.cart-count-bubble span[aria-hidden="true"]').innerHTML = cart.item_count; } } dermObj.config.gtmDLArray = "dataLayer"; dermObj.config.ga4dst = "G-DJ1Q2Q6JW0"; } if (dermObj.customizationCheck('dermalogica.co.za')){ dermObj.config.crm.enabled = true; dermObj.config.crm.country = 'ZA'; } if (dermObj.customizationCheck('dermalogica.com.au')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.showQniConsentButton = true; dermObj.config.qniChoiceFromLanding = true; dermObj.config.quizAfterImage = true; try{ dermObj.config.klavyioId = "VhhRMj"; dermObj.config.klavyioListId = "WdX2Xm"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.com')){ dermObj.config.useShopifyDummyBtn = true; // REMOVE AFTER ECOM TEAM FIXED THE BROKEN SHOPIFY ADD TO CART FUNCTION dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.useCustomShopifyFunction = true; dermObj.config.chat.enabled = true; dermObj.config.chat.depId = 2148428841; dermObj.config.chat.key = 'en'; dermObj.config.forcedCountry = "US"; dermObj.config.useTreatmentBanners = true; dermObj.config.replacePTGcopy = true; dermObj.config.useNewUserKits = true; dermObj.config.showQniConsentButton = true; /* if (window.location.search.indexOf('force_qai=') == -1){ dermObj.config.quizAfterImage = Math.random() < 0.5; } */ dermObj.config.quizAfterImage = true; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; try{ dermObj.config.klavyioId = "JvUywn"; dermObj.config.klavyioListId = "VfNfk3"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } /* const abTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); try{ dermObj.config.pageDict.results = abTestResultsPageArray[resultsPageIndex]; }catch(err){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } */ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; // ptg - legacy AB test for organic traffic 50% split /* DISABLED try{ if (document.referrer.indexOf('google.com') > -1 ){ if (window.location.search.indexOf('rspg=') < 0 ){ if (Math.random() < 0.5){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; }else{ dermObj.config.pageDict.results = 'fmc_results_page_default'; } } } }catch(err){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } */ dermObj.treatments.bookNowUrl = 'https://booking.dermalogica.com/'; dermObj.config.blogs_file = 'blogs_US.json'; dermObj.contactOpenHours = "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)"; dermObj.config.gtmDLArray = "dataLayer"; dermObj.config.ga4dst = "G-7BHWEMK9Q3"; dermObj.config.fmcCheckoutCookie = true; //dermObj.config.crm.enabled = true; dermObj.config.crm.country = 'US'; dermObj.config.percMatchFolder = 'US'; dermObj.config.allowCookies = true; } if (dermObj.customizationCheck('dermalogica.de')){ dermObj.config.requestEmailForResults = false; try{ dermObj.body.querySelectorAll('#fmc_save_email_results').forEach((emBut)=>emBut.style.display= 'flex'); }catch(err){console.log(err)} /* if (window.location.search.indexOf('force_qai=') == -1){ dermObj.config.quizAfterImage = Math.random() < 0.5; } */ dermObj.config.quizAfterImage=true; dermObj.config.forcedLanguage = 'de'; dermObj.config.qniChoiceFromLanding = true; dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; // button text to "more info" dermObj.config.shopButton.textOverride = "Mehr Infos"; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow' //dermObj.config.shopifyExtraPayload = {sections: 'cart-drawer,cart-icon-bubble'}; // DISABLED - WAS NOT THE SOLUTION try{ dermObj.config.klavyioId = "SPekEq"; dermObj.config.klavyioListId = "RcLs2N"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } //const abTestResultsPageArray = ['fmc_results_page_default','fmc_results_prep_treat_glow'] //const resultsPageIndex = Math.max(0,Math.min(1,Math.floor(Math.random()*2))); //full width on desktop try{ const pageWidthEl = dermObj.widget_wrapper.parentElement.parentElement; pageWidthEl.style.maxWidth = "100%"; pageWidthEl.style.paddingLeft = 0; pageWidthEl.style.paddingRight = 0; pageWidthEl.style.marginLeft = 0; pageWidthEl.style.marginRight = 0; }catch(err){ console.log(err) } // show coupon on results page - disabled, was not working in old version if (window.location.search.indexOf("dekp=") == 1 && false ){ let couponCont = document.getElementById("fmc_coupon_container"); let couponText = document.getElementById("fmc_coupon_text"); couponText.innerHTML = "20% Face Mapping Rabatt mit Code FM20 auf dermalogica.de" couponCont.style.display = "block"; } // DISABLED - LINK IS NOT WORKING ANYMORE if (window.location.search.indexOf("dekp=1") > -1 && false){ window.fmcCustomizations.afterBuildResultsPageCall = ()=>{ if (window.facemap.germany_samples){ try{ let bannerCont = document.getElementById("fmc_extra_banner_container"); bannerCont.style.display = "block"; bannerCont.style.cursor = "pointer"; bannerCont.style.backgroundPosition = "center"; bannerCont.style.backgroundRepeat = "no-repeat"; bannerCont.style.backgroundImage = "url('https://facemapping.me/img/fmc_germany_samples_banner.jpg')"; bannerCont.style.boxShadow = "0px 0px 30px rgba(55,143,219,0.2)"; bannerCont.style.marginBottom = "50px"; bannerCont.style.backgroundColor = "white"; let textPadTop; if (document.getElementById("fmcBody").offsetWidth > 768){ bannerCont.style.height = "250px"; bannerCont.style.backgroundSize = "contain"; textPadTop = "80px"; }else{ bannerCont.style.height = "300px"; bannerCont.style.backgroundSize = "cover"; textPadTop = "100px"; } bannerCont.innerHTML = "

Jetzt passende Gratis-Proben aussuchen

"; bannerCont.innerHTML += "

Kostenlos bestellen

"; let sampleLink = "https://fmderma.rheinmail.de/?" window.facemap.germany_samples.forEach((prodId,index)=>{ if (index > 0){ sampleLink += "&"; } sampleLink += "products[]="+prodId; }) bannerCont.onclick = ()=>{ window.open(sampleLink,'_blank'); } }catch(err){ console.error("error in germany's sample kit preparation - ",err); document.getElementById("fmc_extra_banner_container").style.display = "none"; } } } } } dermObj.afterGDPRCall = ()=>{ if (dermObj.countryCode == "DE" && (/facemapping.me($|:)/g.test(window.location.hostname) || /facemappingconsumer-staging.herokuapp.com($|:)/g.test(window.location.hostname) || /localhost($|:)/g.test(window.location.hostname) ) ){ let pathElements = window.location.pathname.split("/"); try{ if ((pathElements[1] == "" || pathElements[1] == "results" ) && dermObj.config.forcedPage == ""){ dermObj.config.chat.enabled = true; dermObj.config.requestEmailForResults = false; // button text to "more info" if (dermObj.lang_code == "de"){ dermObj.config.shopButton.textOverride = "Mehr Infos"; } dermObj.applyCustomizations(); //console.log("APPLY GERMAN CUSTOMIZATIONS") } }catch(err){ console.error("Error in getting facemapping.me path elements - ",err) } } } // TODO - needs more work - coupons and DE facemapping.me requirements if (dermObj.customizationCheck('dermalogica.dk')){ dermObj.config.forcedCountry = "DK"; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; } if (dermObj.customizationCheck('dermalogica.ee')){ // show a different background image on landing page try{ dermObj.body.querySelector("#fmc_landing_page_default").classList.add("fmc-background-estonia"); }catch(err){} } if (dermObj.customizationCheck('dermalogica.es')){ dermObj.config.forcedCountry = "ES"; dermObj.config.shopButton.showPrices = false; } if (dermObj.customizationCheck('dermalogica.fi')){ dermObj.config.sendAlsoToNewEmailEndpoint = true; try{ dermObj.config.klavyioId = "VjVjYj"; dermObj.config.klavyioListId = "Tpnpdf"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.fr')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; //dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.qniChoiceFromLanding = true; try{ dermObj.config.klavyioId = "VHKS5B"; dermObj.config.klavyioListId = "XR4ab5"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } dermObj.config.quizAfterImage = true; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; try{ dermObj.body.querySelectorAll('.fmc_brand_campaign_cta').forEach((brandCTA) =>{ brandCTA.classList.add('smaller-mobile-font'); }) }catch(err){} try{ document.querySelector('[data-widget-regimen-index="5"]').style.display = "none"; }catch(err){console.error(err)} } if (dermObj.customizationCheck('dermalogica.ie')){ dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'gb_and_ie'; dermObj.config.qniChoiceFromLanding = true; dermObj.config.quizAfterImage = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; try{ dermObj.config.klavyioId = "Vm3bBM"; dermObj.config.klavyioListId = "TtCxDX"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.in')){ dermObj.config.forcedPage = "https://dermalogica.in" dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; dermObj.config.quizAfterImage = true; dermObj.config.qniChoiceFromLanding = true; // only display the top 3 concerns dermObj.config.maxConcerns = 3; // show a different background image on landing page dermObj.body.querySelector("#fmc_landing_page_default").classList.add("fmc-background-ind"); } if (dermObj.customizationCheck('dermalogica.it')){ dermObj.config.forcedCountry = "IT"; dermObj.config.chat.enabled = true; dermObj.config.chat.key = 'it'; dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.hideContactBanners = true; try{ dermObj.config.klavyioId = "Xie7pk"; dermObj.config.klavyioListId = "WTub4C"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.jp')){ dermObj.config.forcedLanguage = 'ja-np'; dermObj.config.langForBackends = 'ja'; try{ dermObj.config.klavyioId = "SfJVhQ"; dermObj.config.klavyioListId = "TKnxu9"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica.nl')){ dermObj.config.requestEmailForResults = false; dermObj.config.showSaveEmailMobile = true; } if (dermObj.customizationCheck('dermalogica-ru.ru')){ dermObj.config.requestEmailForResults = true; dermObj.config.histFmcObj = true; dermObj.config.storeLocator.showStores = true; } if (dermObj.customizationCheck('dermalogica.ro') || dermObj.customizationCheck('demo.voitin.com')){ dermObj.config.forcedLanguage='ro'; } if (dermObj.customizationCheck('dermalogica.se')){ //dermObj.config.crm.enabled = true; //dermObj.config.crm.country = 'SE'; try{ dermObj.config.klavyioId = "YmZuN7"; dermObj.config.klavyioListId = "TBw7rn"; }catch(err){ dermObj.config.klavyioId = ""; dermObj.config.klavyioListId = ""; console.error(err); } } if (dermObj.customizationCheck('dermalogica-us-staging.myshopify.com')){ dermObj.config.requestEmailForResults = true; dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.chat.enabled = true; dermObj.config.storeLocator.showStores = true; dermObj.config.histFmcObj = true; dermObj.config.useDioxideStaging = true; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.useTreatmentBanners = true; dermObj.config.usePrepTreatGlowTreatmentBanners = false; dermObj.config.skipMasks = true; //dermObj.body.querySelector('#fmc_treatment_cta').style.display = "none"; //dermObj.body.querySelector('#fmc_treatment_cta_demo').style.display = "flex"; } if (dermObj.customizationCheck('douglas.es')){ dermObj.config.hideEmailButtons = true; } if (dermObj.customizationCheck('dpharmacy.ie')){ try{ document.getElementById("fmc_submit_form").style.marginBottom = "30px"; document.querySelectorAll(".fmc-main-button").forEach((buttonEl)=>{ buttonEl.style.cssText = "color: white !important; font-size: 1em !important; text-transform: uppercase !important; border-radius: 1px !important; font-weight: 400 !important; padding: 10px 40px; !important" }); let fontBlock = " font-family: 'Helvetica Neue',Helvetica, Arial !important;" let fontBlockCaslon = " font-family: 'BigCaslon !important;" document.getElementById("fmc_app_title").style.cssText = "color: white !important; font-size: 5em !important;" + fontBlockCaslon; document.getElementById("fmc_app_tagline").style.cssText = "color: white !important; font-weight: 400 !important; font-size: 1.1em !important; text-transform:uppercase !important;" + fontBlock; let legalContainer = document.querySelector(".fmc-legaltext-container"); legalContainer.querySelector("#legal_text_top").style.cssText = "font-weight: 300 !important; line-height: 1.2 !important; color: #ddd !important;" + fontBlock; legalContainer.querySelector("#legal_text_consent").style.cssText = "font-weight: 300 !important; line-height: 1.2 !important; color: #ddd !important;" + fontBlock; legalContainer.querySelector("#legal_text_bottom").style.cssText = "font-size: 10px !important; color: #ccc !important;" + fontBlock; legalContainer.querySelector("#fmc_consent_accept_button").style.cssText = "font-size: 12px !important; color: white !important; text-transform: uppercase !important; font-weight: 500 !important; letter-spacing: 0.2em !important; padding: 0 !important; margin: 0 !important;" + fontBlock; document.querySelectorAll(".fmc_onboarding_slide_title").forEach((slideTitle)=>{ slideTitle.style.cssText = 'color: #5B6670 !important; font-family: "BigCaslon" !important; font-size: 32px !important; margin: 0 !important; line-height: 1 !important;'; }); document.querySelectorAll("#fmcBody #fmc_screen3 p, #fmcBody #fmc_screen3 span,#fmcBody #fmc_screen4 p, #fmcBody #fmc_screen4 span").forEach((elem)=>{ elem.style.cssText = "color: white !important;"+fontBlock; }) document.getElementById("fmc_frozen_glass_text_bar").style.display = "none"; fmcCustomizations.afterBuildResultsPageCall = ()=>{ document.querySelectorAll(".fmc-ind-word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; color: white !important;"+fontBlock; }) document.querySelectorAll(".fmc-product-image img").forEach((elem)=>{ elem.style.cssText = "height: 100% !important;" }) document.querySelectorAll(".fmc-product-name").forEach((elem)=>{ elem.style.cssText = "font-weight: bold !important; font-size: 1.2em !important; color: #999 !important;"+fontBlock; }) document.querySelectorAll(".fmc-product-subtitle").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 1em !important; color: #999 !important;"+fontBlock; }) document.querySelectorAll(".fmc_price_separator").forEach((elem)=>{ elem.style.cssText = "font-weight: 500 !important; font-size: 1.3em !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) if (document.getElementById("fmcBody").classList.contains("fmc_768")){ document.querySelectorAll(".fmc-product-price").forEach((elem)=>{ elem.style.cssText = "font-weight: 500 !important; font-size: 11px !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) }else{ document.querySelectorAll(".fmc-product-price").forEach((elem)=>{ elem.style.cssText = "font-weight: bold !important; font-size: 1.3em !important; color: white !important; text-transform: uppercase !important;"+fontBlock; }) } document.querySelectorAll(".fmc_mobile_results_indicator_bar .fmc_mobile_indicator_word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 11px !important; color: white !important; text-transform: uppercase !important; "+fontBlock; }) document.querySelectorAll(".fmc_mobile_results_indicator_background .fmc_mobile_indicator_word").forEach((elem)=>{ elem.style.cssText = "font-weight: 300 !important; font-size: 11px !important; color: grey !important; text-transform: uppercase !important; "+fontBlock; }) document.querySelectorAll(".fmc_carousel_mobile_results_text").forEach((elem)=>{ elem.style.cssText ="font-weight: 300 !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_indicator ").forEach((elem)=>{ elem.style.cssText ="font-size: 10px !important; color: white !important; text-transform: lowercase !important; font-weight: 300 !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_title ").forEach((elem)=>{ elem.style.cssText ="font-size: 10px !important; color: #999 !important; font-weight: bold !important;"+fontBlock; }) document.querySelectorAll(".fmc_prod_cont_tagline ").forEach((elem)=>{ elem.style.cssText ="font-size: 9px !important; color: #999 !important; font-weight: 300 !important;"+fontBlock; }) } }catch(err){ console.error("Error in overwriting faulty host css - ",err) } } // WILL NOT WORK - NEEDS TO BE DONE ONCE FMC IS RELAUNCHED if (dermObj.customizationCheck('fashionplace.com','fashionplace')){ dermObj.config.shopButton.hide = true; dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/fashionplace.svg"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/fashionplace_grey.svg"; dermObj.config.brandingLogoScale = 2; const couponSection = dermObj.body.querySelector('#fmc_results_page_default .fmc_results_coupon_section'); couponSection.innerHTML = '

' couponSection.style.display = "flex"; const redoButton = document.createElement('button'); redoButton.id="fmc_fashionplace_redo"; redoButton.classList.add('fmc_centered_text_box','fmc_fashonplace_redo_button'); redoButton.setAttribute('data-widget-text-term','fashionplace_restart_analysis'); redoButton.setAttribute('onclick',"dml_fmc.pageControls.results_default.restart()"); dermObj.body.querySelector('#fmc_results_page_default .fmc_results_head_section').appendChild(redoButton); dermObj.afterLanguageCall = ()=>{ document.getElementById('fmc_onboarding_slide_3_start').innerHTML = dermObj.textData['fashionplace customization'].fashionplace_onboarding_cta; dermObj.config.emailSubjectOverride = dermObj.textData["fashionplace customization"].fashionplace_email_subject; } } if (dermObj.customizationCheck('fragrancedirect.co.uk')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } // // uses default settings // // uses default settings if (dermObj.customizationCheck('pinalli.it')){ dermObj.config.hideEmailButtons = true; dermObj.config.hideContactBanners = true; } if (dermObj.customizationCheck('planetbeauty.com','planetbeauty')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/planet_beauty.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/planet_beauty_grey.png"; dermObj.config.brandingLogoScale = 3; dermObj.config.hideEmailButtons = true; } // PRODUCT LINKS SEEM TO BE ALL WRONG !!! if (dermObj.customizationCheck('pure-beauty.co.uk')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now"; } if (dermObj.customizationCheck('saloncentric.com','saloncentric')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/dermalogica_saloncentric_logos.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/dermalogica_saloncentric_logos_grey.png"; dermObj.config.brandingLogoScale = 3; // extra parameters on the store locator endpoint dermObj.config.storeLocator.extraParameters = "&maxStores=200&maxRadius=30"; dermObj.config.storeLocator.regexFilter = new RegExp(/(S|s)aloncentric/, 'g'); dermObj.config.storeLocator.showStores = true; } // cannot find any stores - but customized regex had been added if (dermObj.customizationCheck('salonservicespro.com','salonservices')){ //fmcForcedPage= "https://www.salonservicespro.com"; dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/logo_dermalogica_salonservices_white.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/logo_dermalogica_salonservices_grey.png"; dermObj.config.brandingLogoScale = 3; } if (dermObj.customizationCheck('sephora.com','sephora')){ dermObj.debug('CUSTOMIZATION FOR SEPHORA') if (/sephora.com\/ca\//g.test(window.location.hostname) || window.location.pathname.indexOf("sephoracanada") > -1 || /sephora\/ca\//g.test(dermObj.config.forcedPage)){ dermObj.config.forcedPage= "sephora/ca/en/"; }else{ dermObj.config.forcedPage= "https://www.sephora.com"; } // remove title and subtitle from "Therapist Section (store locator)" try{ dermObj.body.querySelectorAll('[data-widget-text-term=fmc_skin_therapist_tagline_1],[data-widget-text-term=fmc_skin_therapist_tagline_2]').forEach((htmlEl)=>{ htmlEl.style.display = "none"; }) }catch(err){ } // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/dermalogica_sephora_logos.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/dermalogica_sephora_logos_grey.png"; dermObj.config.brandingLogoScale = 3; dermObj.config.storeLocator.extraParameters = "&maxStores=200&maxRadius=30"; dermObj.config.storeLocator.regexFilter = new RegExp(/(S|s)ephora/, 'g'); dermObj.config.storeLocator.showStores = true; } // Customization for Canada might need to be revieweed - but was already not working for the old FMC anymore if (dermObj.customizationCheck('sephora.com.br', 'Sephora_BR')){ dermObj.debug('CUSTOMIZATION FOR SEPHORA BR') dermObj.config.userImgOnly = true; dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; dermObj.config.hideEmailButtons = true; dermObj.config.forcedLanguage = 'pt-br'; dermObj.config.forcedPage = 'https://sephora.com.br/'; dermObj.afterLanguageCall = ()=>{ dermObj.body.querySelectorAll('[data-widget-text-term="constent_we_care"]').forEach((textEl)=>{ textEl.innerHTML = "Nós, da Dermalogica LCC, nos preocupamos com a sua privacidade" }) dermObj.body.querySelectorAll('[data-widget-text-term="consent_legal_text_2"]').forEach((textEl)=>{ textEl.innerHTML = "Ao clicar \"EU CONCORDO\", você autoriza a Dermalogica, LCC e seus fornecedores de confiança a captar e processar a sua selfie para preparar relatórios faciais detalhados (incluindo geometria facial) e fornecer uma avaliação personalizada de pele e recomendações de produtos, assim como aprimorar as ferramentas, tecnologias e serviços de mapeamento facial e de pele. Para mais informações, por favor acesse Aviso de Privacidade e consulte Face Mapping® Privacy Statement.

*Nenhum dado ou informação capturados pelo FaceMapping serão compartilhados ou tratados pela Sephora." }) dermObj.body.querySelectorAll('[data-widget-text-term="consent_privacy_statement_7"]').forEach((textEl)=>{ textEl.innerHTML = "Para obter mais informações sobre nossas práticas de privacidade e outras informações pessoais que podemos coletar ou processar em relação a nossa plataforma, acesse Aviso de Privacidade." }) } } if (dermObj.customizationCheck('state-rda.com','stateRDA')){ // update logo at landing page dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/logo_dermalogica_state_rda_white.svg"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/logo_dermalogica_state_rda_grey.svg"; dermObj.config.brandingLogoScale = 3; dermObj.config.hideEmailButtons = true; dermObj.config.shopButton.hide = true; } if (dermObj.customizationCheck('therabeauticonline.co.uk') || dermObj.customizationCheck('www-therabeauticonline-co-uk.filesusr.com')){ dermObj.config.forcedPage = "therabeauticonline.co.uk"; dermObj.config.hideEmailButtons = true; } // // uses default settings if (dermObj.customizationCheck('ulta.com', 'ulta')){ // change "shop" button text dermObj.config.shopButton.textOverride = "shop now + free gift" dermObj.config.brandingLogoUrl = "https://facemapping.me/img/brands/derm_ulta_logo.png"; dermObj.config.brandingLogoUrlGrey = "https://facemapping.me/img/brands/derm_ulta_logo_grey.png"; dermObj.config.brandingLogoScale = 4; dermObj.config.storeLocator.extraParameters = "&maxStores=100&maxRadius=50"; dermObj.config.storeLocator.regexFilter = new RegExp(/(U|u)lta/, 'g'); dermObj.config.storeLocator.showStores = true; } // // TODO special coupon task if (dermObj.customizationCheck('yourskinexpert.ie')){ //remove email button dermObj.config.hideEmailButtons = true; dermObj.widget_wrapper.style.width = "100%" const pageContainer = dermObj.widget_wrapper.parentElement try{ pageContainer.classList.remove('PageContent--narrow','PageContent','Rte') }catch(err){} //dermObj.updateClassesDueWith() // not working here, since it is not defined yet } // TODO - needs to be checked once it is live. some adjustments had to be made to their site if (dermObj.customizationCheck('demo.just.the.microsite','demo')){ dermObj.config.useTreatmentBanners = true; dermObj.afterGDPRCall = () => { dermObj.backend = 'https://fmc-backend-staging.herokuapp.com'; } } if (dermObj.customizationCheck('lastfacemap.just.the.microsite','lastfacemap')){ dermObj.config.useTreatmentBanners = true; if (window.location.search.indexOf('fmhid') == -1){ const xhr = new XMLHttpRequest(); xhr.open('GET', `https://fmc-backend-staging.herokuapp.com/fmc/get_most_recent_face_map`, true); xhr.setRequestHeader('Content-Type', 'application/json') xhr.responseType = 'json'; xhr.onload = () => { dermObj.backendData = xhr.response; if (window.location.search == ''){ window.history.pushState('fmc_results_page', '', `${window.location.href}?fmhid=${xhr.response.hashid}&be=stg`); }else{ window.history.pushState('fmc_results_page', '', `${window.location.href}&fmhid=${xhr.response.hashid}&be=stg`); } dermObj.applyState(); } xhr.send(); } } if (dermObj.customizationCheck('dev_variables.com')){ dermObj.isPercMatchMiniPage = true; document.querySelector('html').style.backgroundColor = "#cc5555"; document.querySelector('html').style.padding ="5%"; window.dsrp = {} window.dsrp.gdpr = { "country_code": "AT", "region": "EU", "legal_copy": { "legal_text_top": "This app collects information and photos of your face and skin, along with descriptions of skin health conditions, concerns, and product recommendations. This information is collected by Dermalogica, LLC and is required for the app to work. Your data will not be seen by other users.", "legal_text_consent": "I consent to Dermalogica, LLC processing my information to provide the app service to me as explained above. I understand that my response will be remembered by this application. I am 16+ years old.", "legal_text_bottom": "If you do not want to provide your personal data, then you should not use this app because it is required for the app to function. To find out more about how we process your personal information and your rights, please see our Privacy Policy here and Terms and Conditions here." }, "faked": false, "state": "9", "city": "Vienna" } dermObj.config.shopButton.showPrices = true; dermObj.config.useShopify = true; dermObj.config.useCustomShopifyFunction = true; dermObj.config.forcedCountry = "US"; dermObj.config.useTreatmentBanners = true; dermObj.config.showQniConsentButton = true; dermObj.config.quizAfterImage = true; dermObj.config.qniChoiceFromLanding = true; dermObj.config.pageDict.landing = 'fmc_landing_page_brand_campaign'; dermObj.config.pageDict.onboarding = 'fmc_loading_page_default'; dermObj.config.pageDict.results = 'fmc_results_ai_steps'; dermObj.contactOpenHours = "Mon - Fri, 7am - 8pm PT | Sat - Sun, 10am - 2pm PT
(excludes public holidays)"; dermObj.config.percMatchFolder = 'US'; dermObj.config.allowCookies = true; } dermObj.configLoaded = true; dermObj.applyCustomizations(); try{ dermObj.referrer = dermObj.config.forcedPage != '' ? dermObj.config.forcedPage : dermObj.referrer; }catch(err){console.log(err)} try{ dermObj.dioxide = "https://dioxide.herokuapp.com"; if (window.location.search.indexOf('dx_ep=') > -1){ const dxLabel = window.location.search.split('dx_ep=')[1].split('&')[0]; switch(dxLabel){ case 'prod': dermObj.dioxide = 'https://dioxide.herokuapp.com' break; case 'stg': dermObj.dioxide = 'https://dioxide-staging.herokuapp.com' break; case 'lch': dermObj.dioxide = 'http://127.0.0.1:8000' break; default: dermObj.dioxide = 'https://dioxide.herokuapp.com' } } }catch(err){ dermObj.dioxide = 'https://dioxide.herokuapp.com'; console.log(err) } dermObj.applyState = async () => { let isResultsPage = false; let needsToBuildResults = true; if (window.location.search.indexOf('fmhid=') > -1 ){ isResultsPage = true; if (typeof dermObj.backendData == 'undefined'){ try{ if (window.location.search.indexOf('qni=1') > -1){ dermObj.config.quizNoImage = true; dermObj.config.use2FA = false; } dermObj.formerHash = window.location.search.split('fmhid=')[1].split('&')[0]; dermObj.requestPermissionBeforeLoadingFormerResult(); }catch(err){ console.warn("not a valid old fmc result",err); } }else{ needsToBuildResults = false; } } if (isResultsPage){ if (window.location.search.indexOf('rspg=') > -1 ){ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg == 'prep_treat_glow'){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } if (rspg == 'default'){ dermObj.config.pageDict.results = 'fmc_results_page_default'; } if (rspg == 'brand_campaign'){ dermObj.config.pageDict.results = 'fmc_results_brand_campaign'; } if (rspg == 'estr'){ dermObj.config.pageDict.results = 'fmc_estimated_results'; } if (rspg == 'quiz_no_image'){ dermObj.config.pageDict.results = 'fmc_results_quiz_no_image'; } if (rspg == 'ai_steps'){ dermObj.config.pageDict.results = 'fmc_results_ai_steps'; } } if (typeof dermObj.backendData != 'undefined'){ dermObj.gotoPage('results'); dermObj.body.style.opacity = 1; await dermObj.loadExtraLibraries(); try{ await dermObj.capture.initFaceLandmarkModel(false); }catch(err){ console.error(err) } if (dml_fmc.config.pageDict.results == 'fmc_results_page_default'){ if (needsToBuildResults || dermObj.body.querySelectorAll("#fmc_results_concerns_list .fmc_concern_info_item ").length == 0){ dermObj.pageControls.results_default.build(); } } } }else{ if (window.location.search.indexOf('rspg=') > -1 ){ let rspg = window.location.search.split('rspg=')[1].split('&')[0]; if (rspg == 'prep_treat_glow'){ dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; } if (rspg == 'default'){ dermObj.config.pageDict.results = 'fmc_results_page_default'; } if (rspg == 'brand_campaign'){ dermObj.config.pageDict.results = 'fmc_results_brand_campaign'; } } dermObj.removeUrlParameters('landing',['be','rspg']); if (dermObj.isPercMatchMiniPage == true){ dermObj.queueUrlParameters({fmc_mnpg_d:1}); window.fmc_collections_complete = false; window.fmc_collections_df = false; } dermObj.gotoPage("landing"); dermObj.body.style.opacity = 1; await dermObj.loadExtraLibraries(); // prepare capture page and init landmark model try{ await dermObj.capture.init({ captureContainerId : 'fmc_video_container', videoConstrains : { video: { facingMode: { ideal: 'user' }, width: { min: 720, ideal: 1080, max: 1920 }, height: {min: 720, ideal: 1080, max: 1920 } }, audio: false } }); }catch(err){ console.error(err) } try{ document.querySelector('.derm_manual_button').addEventListener('click',()=>{ dermObj.sendGA360("main flow","manual capture button clicked"); dermObj.sendGAFlowEvent("manual capture button clicked") }) }catch(err){ console.error(err) } let facemarkModelLoaded = false; try{ facemarkModelLoaded = await dermObj.capture.initFaceLandmarkModel(); }catch(err){ console.error(err) } if (window.location.href.indexOf("http://localhost:5000") > -1 || window.location.href.indexOf("http://192.168.0.150:5000") > -1){ //dermObj.gotoPage("onboarding"); //dermObj.gotoPage("capture"); //dermObj.gotoPage("waiting"); //dermObj.config.pageDict.results = 'fmc_results_prep_treat_glow'; //dermObj.gotoPage('results'); } } } dermObj.init = async () => { await dermObj.getLanguageData(); await dermObj.renderTextData(dermObj.textData); // FIX FOR POLISH LANGUAGE - ISSUES WITH HELVETICA NEUE STD - SECOND TIME AFTER QUIZ LOADED if (['pl','cs','ro'].includes(dermObj.lang_code)){ dermObj.body.querySelectorAll('p,span,a,h1,h2,h3').forEach((textEl) => { textEl.style.fontFamily = '"Helvetica Neue", "Arial"' }); } if (typeof dermObj.afterLanguageCall != 'undefined'){ try{ dermObj.afterLanguageCall(); }catch(err){console.error("error in afterLanguageCall - ",err)} } if (dermObj.isIOS || dermObj.isMacLike){ dermObj.body.querySelectorAll('.dml_horizontally_centered_text').forEach((centerEl) => { centerEl.style.paddingTop = '0.2em'; }) } (()=>{ dermObj.blogs.load(); })(); (async ()=>{ try{ await dermObj.getGDPR(); }catch(err){ console.log(err); } dermObj.applyState(); dermObj.applyLegalText(); if (dermObj.countryCode != 'IT'){ if (dermObj.uselegacyLegalCopy){ dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'none'; dermObj.body.querySelector('#fmc_legal_container_legacy').style.display = 'block'; }else{ dermObj.body.querySelector('#fmc_legal_container_default').style.display = 'block'; dermObj.body.querySelector('#fmc_legal_container_legacy').style.display = 'none'; } } try{ dermObj.siteLinks = await dermObj.getDioxideLinkData(); }catch(err){ dermObj.siteLinks = {}; console.warn('error in getting site links - ',err); } (async ()=>{ try{ await dermObj.getAllDioxideProducts(); try{ await dermObj.getAllDioxideTranslations(); dermObj.mergeDioxideAllProdAndTranslations(); }catch(errInner){ console.error(errInner) } }catch(err){ dermObj.dioxideAllProducts = {}; console.warn('error in getting dioxide Products - ',err); } })() if (dermObj.siteLinks.contact_us_url === null || dermObj.siteLinks.contact_us_url === '' || dermObj.siteLinks.contact_us_url === undefined || dermObj.config.hideContactBanners == true){ dermObj.body.querySelectorAll('.fmc_contact_section').forEach((contactSection) => { contactSection.style.display = 'none'; }) } if (dermObj.config.emailDoubleCheckbox == true){ document.querySelector('#fmc_email_popup .fmc_email_form_wrapper').classList.add('fmc_double_check_box'); } if (typeof dermObj.afterGDPRCall != 'undefined'){ try{ dermObj.afterGDPRCall(); }catch(err){console.error("error in afterGDPRCall - ",err)} } try{ dermObj.chat.setUpZendesk(); }catch(err){} })() dermObj.klaviyo.getId(); await dermObj.initClassesDueWidth(); try{ if (typeof dermObj.capture == 'object'){ dermObj.capture.initDone = false; } }catch(err){ console.error("error in reseting init variable for catpure script", err); } if (!initialized){ initialized = true; dermObj.loadedAppTS = Date.now(); dermObj.sendGA4Time('app_loading_time' , dermObj.loadedAppTS - dermObj.openAppTS); dermObj.debug('app loading time [ms]: ', dermObj.loadedAppTS - dermObj.openAppTS); } } dermObj.init(); window.onpopstate = ()=>{ if (dml_fmc.widget_wrapper.querySelector(`#fmc_body`) == null ) return; dermObj.applyState(); } })()