1 2class Utils{isTouchDevice(){return'ontouchstart'in window||navigator.MaxTouchPoints>0||navigator.msMaxTouchPoints>0?true:false;} 3isObject(value){return value&&typeof value==='object'&&value.constructor===Object;} 4mergeDeep(target,...sources){if(!sources.length)return target;const source=sources.shift();if(this.isObject(target)&&this.isObject(source)){for(const key in source){if(this.isObject(source[key])){if(!target[key])Object.assign(target,{[key]:{}});this.mergeDeep(target[key],source[key]);}else{Object.assign(target,{[key]:source[key]});}}} 5return this.mergeDeep(target,...sources);} 6partial(func,...argsBound){return function(...args){return func.call(this,...argsBound,...args);};} 7curry(fn){const argsLength=fn.length;return function fn1(...args){if(args.length>=argsLength){return fn(...args);} 8return function fn2(...moreArgs){const newArgs=args.concat(moreArgs);return fn1(...newArgs);};};} 9debounce(f,ms){let isReady=false;let wrapper=function(){if(isReady)return;f.apply(this,arguments);isReady=true;setTimeout(function(){isReady=false;},ms);};return wrapper;} 10throttle(func,ms){let isThrottled=false,savedArgs,savedThis;function wrapper(){if(isThrottled){savedArgs=arguments;savedThis=this;return;} 11func.apply(this,arguments);isThrottled=true;setTimeout(function(){isThrottled=false;if(savedArgs){wrapper.apply(savedThis,savedArgs);savedArgs=savedThis=null;}},ms);} 12return wrapper;} 13memorySizeOf(obj){let bytes=0;function sizeOf(obj){if(obj!==null&&obj!==undefined){switch(typeof obj){case'number':bytes+=8;break;case'string':bytes+=obj.length*2;break;case'boolean':bytes+=4;break;case'object':const objClass=Object.prototype.toString.call(obj).slice(8,-1);if(objClass==='Object'||objClass==='Array'){for(let key in obj){if(!obj.hasOwnProperty(key))continue;sizeOf(obj[key]);}}else bytes+=obj.toString().length*2;break;}} 14return bytes;} 15return sizeOf(obj);}} 16class Mutex{constructor(){this.locked=false;this.waitingQueue=[];} 17async lock(){if(this.locked){await new Promise(resolve=>this.waitingQueue.push(resolve));} 18this.locked=true;} 19unlock(){if(this.locked){this.locked=false;if(this.waitingQueue.length>0){const resolve=this.waitingQueue.shift();resolve();}}}} 20class MultiStep{constructor(validator,{formContainer,fields,props},suggestLocation){this.validator=validator;this.formContainer=formContainer;this.fields=fields;this.suggestLocation=suggestLocation;this.props=props;this.init();} 21init(){const{stepContainer,formControls,pagination,activeClass}=this.props;this.stepsList=this.formContainer.querySelectorAll(stepContainer);this.maxStep=this.stepsList.length;this.currentStep=Array.from(this.stepsList).find((step)=>step.classList.contains(activeClass));this.currentStepIndex=!this.currentStep?0:Array.from(this.stepsList).findIndex((step)=>step.classList.contains(activeClass));this.setCurrentStepData(this.currentStepIndex);const nextBtnsNodes=document.querySelectorAll(formControls.nextElement);const nextCustomBtnsNodes=document.querySelectorAll(formControls.nextCustomElement);this.nextBtns=[...nextBtnsNodes,...nextCustomBtnsNodes];this.prevBtns=this.formContainer.querySelectorAll(formControls.prevElement);if(pagination.exist){this.initPagination();} 22this.setEvents();} 23setEvents(){const onNextClick=(e)=>{if(e.currentTarget.disabled)return;e.preventDefault();e.target.focus();this.setDisabledBtn();this.next();};this.nextBtns.forEach((btn)=>{btn&&btn.addEventListener("mousedown",onNextClick);});const onPrevClick=(e)=>{e.preventDefault();this.prev();};this.prevBtns.forEach((btn)=>{btn&&btn.addEventListener("click",onPrevClick);});this.fields.forEach((field)=>{field.element.addEventListener("focus",(e)=>this.resetDisabledBtn());});} 24setCurrentStepData(index){this.stepsList[index].classList.add(this.props.activeClass);this.currentStep=this.stepsList[index];this.formContainer.dataset.currentStepIndex=index+1;document.body.dataset.currentStepIndex=index+1;document.body.dataset.currentStepName=this.currentStep.dataset.stepName;} 25isLastStep(){return this.currentStepIndex+1===this.maxStep;} 26getStepNodes(index){const step=this.stepsList[index];if(!step){return;} 27return Array.from(step.querySelectorAll('input, select')).map((node)=>
27node.name.trim()).filter(Boolean);} 28getCurrentStepFields(index){const currentStepNodes=this.getStepNodes(index);return this.fields.filter((field)=>currentStepNodes.includes(field.fieldName));} 29getCurrentStepRequiredFields(index){const currentStepRequiredNodes=this.getStepNodes(index);return this.fields.filter((field)=>{return field.validateRule&&field.validateRule.required&¤tStepRequiredNodes.some(node=>field.fieldName.includes(node));});} 30getPrevStepFields(index){const prevStepNodes=this.getStepNodes(index-1);if(!prevStepNodes)return null;return this.fields.filter((field)=>prevStepNodes.includes(field.fieldName));} 31getNextStepFields(index){const nextStepNodes=this.getStepNodes(index+1);if(!nextStepNodes)return null;return this.fields.filter((field)=>nextStepNodes.includes(field.fieldName));} 32setDisabledBtn(){this.nextBtns.forEach((btn)=>{btn.disabled=true;btn.classList.add(this.props.disabledClass);});} 33resetDisabledBtn(){this.nextBtns.forEach((btn)=>{btn.disabled=false;btn.classList.remove(this.props.disabledClass);});} 34showNextStep(){if(this.currentStepIndex<this.stepsList.length-1){this.currentStepIndex++;this.stepBy(this.currentStepIndex,"step-next");this.dispatchMultistepEvent("step-next");this.dispatchMultistepEvent("step-change");}} 35next(input){const currentStepFields=this.getCurrentStepRequiredFields(this.currentStepIndex);if(currentStepFields.length){this.validator.validate(currentStepFields,this.resetDisabledBtn.bind(this)).then((errorList)=>{const currentStepErrorNames=currentStepFields.map((field)=>field.errorName).filter((field)=>errorList.has(field));this.resetDisabledBtn();if(!errorList.size||!currentStepErrorNames.length){this.showNextStep();if(this.suggestLocation&&this.suggestLocation.isSuggestActive)this.suggestLocation.closeSuggest();if(input)input.blur();}}).catch((err)=>{console.error(err);return err;});}else{this.resetDisabledBtn();this.showNextStep();}} 36prev(){this.resetDisabledBtn();if(this.currentStepIndex>0){this.currentStepIndex--;this.stepBy(this.currentStepIndex);this.dispatchMultistepEvent("step-prev");this.dispatchMultistepEvent("step-change");}} 37stepBy(index){this.currentStep.classList.remove(this.props.activeClass);this.setCurrentStepData(index);} 38dispatchMultistepEvent(name="step-change"){const event=new CustomEvent(name,{detail:{maxStep:this.maxStep,currentStep:this.currentStep,currentStepIndex:this.currentStepIndex,currentStepFields:this.getCurrentStepFields(this.currentStepIndex),prevStepFields:this.getPrevStepFields(this.currentStepIndex),nextStepFields:this.getNextStepFields(this.currentStepIndex),},});this.formContainer.dispatchEvent(event);} 39initPagination(){const{root,container,item}=this.props.pagination;let items=`<div class="${container}">`;for(let i=1;i<=this.maxStep;i++){items+=`<div class="${item}" data-pagination-index="${i}"><span>${i}</span></div>`;} 40items+="</div>";root.insertAdjacentHTML("beforeend",items);this.paginationContainer=document.querySelector(`.${container}`);this.paginations=[...this.paginationContainer.children];this.updatePagination(0);this.formContainer.addEventListener("step-next",(e)=>this.updatePagination(e.detail.currentStepIndex));this.formContainer.addEventListener("step-prev",(e)=>this.updatePagination(e.detail.currentStepIndex));} 41updatePagination(i){const{currentClass,visitedClass}=this.props.pagination;this.paginations.forEach((el)=>{el.classList.remove(currentClass);el.classList.remove(visitedClass);});this.paginations.filter((el,index)=>index<=i).forEach((el)=>{el.classList.add(visitedClass);});this.paginationContainer.children[i].classList.remove(visitedClass);this.paginationContainer.children[i].classList.add(currentClass);}} 42class SuggestLocation{constructor(fieldContainer,{props}){if(!fieldContainer){console.error('Set correct field container');return;} 43this.container=fieldContainer;this.options=this.setOptions();this.inputField=this.container.querySelector(`[name="${props.formNamespace}[location]"]`);this.suggestField=this.container.querySelector(`.${this.options.suggestFieldClass}`);this.lastInputValue=this.inputField.value;this.isSuggestActive=false;this.isSendingData=false;this.currentItemIndex=-1;this.keycode={enter:13,esc:27,arrowUp:38,arrowDown:40,};this.setEvents();} 44setOptions(){return{suggestFieldClass:'suggest',suggestActiveClass:'suggest--active',suggestActiveClassTop:'suggest--opened-top',suggestItemClass:'suggest__item',currentClass:'current',minLength:2,maxLength:25,requestUrl:'/geo/suggestLocation',limit:30,debaunceDelay:300,boxHeight:300,};} 45setEvents(){this.inputField.addEventListener('keyup',this.debounce(event=>{const inputValue=event.target.value.trim();if(this.isValueValid(inputValue,event)){this.lastInputValue=inputValue;
45this.getSuggestData(inputValue);}},this.options.debaunceDelay));this.container.addEventListener('keyup',({keyCode:currentKeyCode})=>{if(!this.isSuggestActive){return;} 46switch(currentKeyCode){case this.keycode.enter:this.setSuggestValue();this.closeSuggest();break;case this.keycode.esc:this.closeSuggest();break;case this.keycode.arrowUp:this.moveCurrentItem('up');break;case this.keycode.arrowDown:this.moveCurrentItem('down');break;}});this.suggestField.addEventListener('click',({target})=>{if(target.className===this.options.suggestItemClass){target.classList.add(this.options.currentClass);this.setSuggestValue();this.closeSuggest();} 47this.inputField.dispatchEvent(new Event('blur'));this.inputField.dispatchEvent(new Event('touchend'));});document.addEventListener('click',event=>{const itemClosest=event.target.closest('.'+this.options.suggestFieldClass);if(!itemClosest){this.suggestField.classList.remove(this.options.suggestActiveClass,this.options.suggestActiveClassTop);}});} 48isValueValid(inputValue,event){const inputValueLength=inputValue.length;return inputValue&&this.lastInputValue!=inputValue&&inputValueLength>=this.options.minLength&&inputValueLength<=this.options.maxLength&&!this.isSendingData?true:false;} 49getSuggestData(searchValue){const{url,options}=this.prepareData(searchValue);this.isSendingData=true;this.fetchData(url,options);} 50prepareData(searchValue){const headers=new Headers({'x-requested-with':'XMLHttpRequest','Content-Type':'application/json',});const data={q:searchValue,limit:this.options.limit,};return{url:this.getFetchUrl(this.options.requestUrl,data),options:{method:'GET',headers,},};} 51fetchData(url,options){fetch(url,options).then(res=>res.json()).then(({data,meta})=>{this.isSendingData=false;if(meta.code===200&&data.locations.length){this.generateSuggestList(data.locations);this.openSuggest();}});} 52getFetchUrl(url,data){let getParams='';for(let key in data){if(getParams!==''){getParams+='&';} 53getParams+=key+'='+encodeURIComponent(data[key]);} 54return url+'?'+getParams;} 55generateSuggestList(data){const html=data.reduce((acc,item)=>{acc+=`<div class="${this.options.suggestItemClass}">${item}</div>`;return acc;},'');this.suggestField.innerHTML=html;} 56openSuggest(){this.isSuggestActive=true;if(this.isOpenToTop())this.suggestField.classList.add(this.options.suggestActiveClassTop);this.suggestField.classList.add(this.options.suggestActiveClass);} 57closeSuggest(){this.isSuggestActive=false;this.currentItemIndex=-1;this.suggestField.classList.remove(this.options.suggestActiveClass,this.options.suggestActiveClassTop);this.inputField.dispatchEvent(new Event('blur'));} 58setSuggestValue(){const selectedItem=this.suggestField.querySelector(`.${this.options.currentClass}`);if(selectedItem){this.lastInputValue=this.inputField.value=selectedItem.textContent;}} 59moveCurrentItem(way){const suggestItems=this.suggestField.querySelectorAll(`.${this.options.suggestItemClass}`);const suggestItemsLength=suggestItems.length;switch(way){case'up':this.currentItemIndex--;if(this.currentItemIndex<0)this.currentItemIndex=suggestItemsLength-1;break;case'down':this.currentItemIndex++;if(this.currentItemIndex>suggestItemsLength-1)this.currentItemIndex=0;} 60suggestItems.forEach(el=>{el.classList.remove(this.options.currentClass);});const currentItem=suggestItems[this.currentItemIndex];currentItem.classList.add(this.options.currentClass);const offsetItem=currentItem.offsetTop;this.suggestField.scrollTop=offsetItem;} 61isOpenToTop(){const windowHeight=window.innerHeight;const clientRectBottom=this.container.getBoundingClientRect().bottom;return windowHeight-clientRectBottom<this.options.boxHeight;} 62debounce(fn,delay){let timer=null;return function(){let context=this,args=arguments;clearTimeout(timer);timer=setTimeout(()=>{fn.apply(context,args);},delay);};}} 63class UserRecovery{constructor({formContainer,props:{userRecoveryProps}}){this.formContainer=formContainer;this.userRecoveryProps=userRecoveryProps;this.init();} 64init(){this.emailElement=this.formContainer.querySelector(this.userRecoveryProps.emailElement);const tokenElement=this.formContainer.querySelector(this.userRecoveryProps.tokenElement);this.token=tokenElement?tokenElement.value:'';this.setEvents();} 65setEvents(){this.formContainer.addEventListener('click',e=>{if(e.target.matches(this.userRecoveryProps.passwordElement)){this.recoveryPassword(e.target.href);} 66if(e.target.matches(this.userRecoveryProps.confirmElement)){this.recoveryConfirm(e.target.href);} 67if(e.target.matches(this.userRecoveryProps.cancelElement)){this.recoveryCancel(e.target.href);}});} 68recoveryRequest(url,formData){const headers=new Headers({'x-requested-with':'XMLHttpRequest',});const options={method:'POST',headers:headers,body:formData,};fetch(url,options).then(res=>res.json()).then(({status,data,meta})=>{if(status==='error'&&meta.code===302&&meta.redirect){this.redirectToCaptcha(meta.redirect);return;} 69const message=status==='success'?data.message:meta.description.description;this.showErrorMessage(message);}).catch(err=>{console.error(err);});} 70recoveryPassword(url){const formData=new FormData();formData.append('RecoveryForm[email]',this.emailElement.value);this.recoveryRequest(url,formData);} 71recoveryConfirm(url){const recoveryId=url.substr(-32);url=url.replace('/id/'+recoveryId,'');const formData=new FormData();formData.append('id',recoveryId);formData.append('YII_CSRF_TOKEN',this.token);this.recoveryRequest(url,formData);} 72recoveryCancel(url){this.recoveryRequest(url);} 73showErrorMessage(msg){this.errorElement=this.formContainer.querySelector(this.userRecoveryProps.errorElement);this.errorElement&&(this.errorElement.innerHTML=msg);} 74redirectToCaptcha(url){const exp=new RegExp(/\/\/(www|m)/);if(!exp.test(url)){url=location.protocol+'//'+location.host+(url[0]==='/'?url:'/'
74+url);} 75window.location.href=url;}} 76class Validator{constructor({props,formContainer,fields}){this.formContainer=formContainer;this.props=props;this.fields=fields;this.storage={};this.errorList=new Set();this.lastErrorNames=[];this.isSubmitted=false;this.mutex=new Mutex();this.setEvents();} 77setEvents(){this.formContainer.addEventListener('field-validate',e=>{this.highlight(e.detail.response);});} 78prepareFormData(fields){const formDataList=fields.reduce((acc,item)=>{if(this.storage[item.name]===item.element.value){return acc;} 79const formData=new FormData();formData.append('ajax','register-form');formData.append('scenario',item.validateRule.scenario);if(item.name==='day'||item.name==='month'||item.name==='year'){formData.append(`UserForm[day]`,this.formContainer.querySelector(`input[data-type="day"]`).value);formData.append(`UserForm[month]`,this.formContainer.querySelector(`input[data-type="month"]`).value);formData.append(`UserForm[year]`,this.formContainer.querySelector(`input[data-type="year"]`).value);}else{formData.append(item.fieldName,item.element.value);} 80if(item.extraFormData){for(const[key,value]of Object.entries(item.extraFormData)){formData.append(key,value);}} 81acc.push(formData);this.storage[item.name]=item.element.value;this.lastErrorNames.push(item.errorName);return acc;},[]);return formDataList;} 82prepareRequests(dataList){return dataList.map(request=>{const data={method:'POST',body:request,};return fetch(this.props.actionURL,data);});} 83async validate(fields,successCallback,failureCallback){await this.mutex.lock();const notEmptyFields=this.props.hasValidationEmptyFields?this.checkEmptyFields(fields):fields;const fieldsData=this.prepareFormData(notEmptyFields);const promises=this.prepareRequests(fieldsData);return Promise.all(promises).then(responses=>{const jsons=responses.map(res=>res.json());const headers=responses.map(res=>res.headers);return[jsons,headers];}).then(async responses=>{const[jsons,headers]=responses;for(const[i,json]of jsons.entries()){const data=await json;if(Array.isArray(data)&&!data.length){this.unhighlight();successCallback&&successCallback();}else{const eventFieldValidate=new CustomEvent('field-validate',{detail:{response:data,header:headers[i],},});this.formContainer.dispatchEvent(eventFieldValidate);failureCallback&&failureCallback();}} 84return this.errorList;}).catch(err=>{console.error(err);}).finally(()=>{this.mutex.unlock();});} 85checkEmptyFields(fields){const emptyFields=fields.filter(field=>field.element.value.length===0).map(field=>field.errorName);emptyFields.forEach(name=>this.renderEmptyFieldError(name));return fields.filter(field=>field.element.value.length!==0);} 86renderEmptyFieldError(name){if(!window.jqueryValidationMessages)return;const fieldName=this.fields.filter(field=>field.errorName===name).map(field=>field.fieldName);const errorName=window.jqueryValidationMessages[fieldName];const errorMessage=errorName&&errorName.required;this.renderErrorMessage(name,errorMessage);} 87getErrorElements(name){const{fieldContainer,errorContainer}=this.props;const errorField=this.fields.find(field=>field.errorName===name);if(!errorField)return;const parent=errorField.element.closest(fieldContainer);const container=parent.querySelector(errorContainer);return{errorField,parent,container,};} 88resetErrors(name){const{errorClass,validClass}=this.props;const{parent,container}=this.getErrorElements(name);container.innerHTML='';parent.classList.remove(errorClass);parent.classList.add(validClass);this.errorList.delete(name);} 89renderErrorMessage(name,message){const{errorClass,validClass}=this.props;const{parent,container}=this.getErrorElements(name);container.dataset.errorName=name;container.innerHTML=`<p>${message}</p>`;parent.classList.add(errorClass);parent.classList.remove(validClass);this.errorList.add(name);} 90unhighlight(name){if(this.lastErrorNames.includes('UserForm_day')||this.lastErrorNames.includes('UserForm_month')||this.lastErrorNames.includes('UserForm_year')){this.errorList.delete('UserForm_day');this.errorList.delete('UserForm_month');this.errorList.delete('UserForm_year');}
91this.lastErrorNames.forEach(errorName=>{this.resetErrors(errorName);});this.lastErrorNames=[];} 92highlight(data){const[errorName]=Object.keys(data);const[errorMessage]=Object.values(data);this.renderErrorMessage(errorName,errorMessage[0]);this.lastErrorNames=[];}} 93class FData{constructor({fields}){this.fData=this.getFdata();this.fDataEmailTransfer=new FDataEmailTransfer(this.fData,fields);} 94getFdata(){const url=new URL(window.location.href);const fData=url.searchParams.get('_fData');return fData?this.prepareFdata(fData):'';} 95prepareFdata(fData){try{const decodedFData=decodeURIComponent(fData);const base64Decoded=this.b64DecodeUnicode(decodedFData);return JSON.parse(base64Decoded);}catch(e){console.error('Your fData from URL is not correct',e);}} 96b64DecodeUnicode(str){return decodeURIComponent(atob(str).split('').map(c=>'%'+('00'+c.charCodeAt(0).toString(16)).slice(-2)).join(''));}} 97class FDataEmailTransfer{constructor(fData,fields){if(!fData)return;this.fData=fData;this.fields=fields;this.emailValue=this.getEmail();this.setEmail(this.emailValue);} 98getEmail(){const{email}=this.fData;return this.isValidEmail(email)?email:'';} 99setEmail(value){const emailInput=this.fields.find(field=>field.name==='email').element;emailInput.value=value;} 100isValidEmail(emailValue){const pattern=new RegExp(/^[a-zA-Z0-9.!#$%&â*+/=?^_`{|}~-]+@[a-zA-Z0-9-]+(?:\.[a-zA-Z0-9-]+)*$/);return this.fData.hasOwnProperty('email')&&pattern.test(emailValue);}} 101const REGMODE_APEX='apex';const REGMODE_DEFAULT='default';class Regform extends Utils{constructor(formContainer,options={}){super();this.formContainer=formContainer;this.props=this.initProps(options);this.state=this.initState(this.formContainer,this.props);this.formId=`${this.props.formNamespace}-${Date.now()}`;this.init();} 102init(){this.form=this.formContainer.querySelector(this.props.formElement);this.validator=new Validator(this.state);this.userRecovery=new UserRecovery(this.state);const suggestContainer=this.getSuggestContainer();if(suggestContainer){this.suggestLocation=new SuggestLocation(suggestContainer,this.state);} 103if(this.props.hasMultiSteps){this.multiStep=new MultiStep(this.validator,this.state,this.suggestLocation);} 104this.fData=new FData(this.state);this.setValidatorEvents();this.setCustomEvents();} 105initProps(options){const defaults={formNamespace:'UserForm',formElement:'.register-hidden-form',actionURL:'/user/register',stepContainer:'.form-step-item',fieldContainer:'.form-item',errorContainer:'.form-error-block',errorClass:'error-field',validClass:'valid-field',activeClass:'is-active',disabledClass:'is-disabled',formControls:{submitElement:'.submit-btn',nextElement:'.next-btn',prevElement:'.prev-btn',nextCustomElement:'.next-custom-btn',blurPreventValidationSelector:'[data-prevent-validation="blur"]',},hasMultiSteps:false,pagination:{exist:true,root:this.formContainer,container:'pagination-block',item:'pagination-item',currentClass:'is-current',visitedClass:'is-visited',},hasValidationEmptyFields:false,fields:{gender:{name:'gender',btn:'.gender-btn',btnBlock:'.gender-btns-block',validateRule:{required:false,},},partnerGender:{name:'partnerGender',btn:'.partner-gender-btn',btnBlock:'.partner-gender-btns-block',validateRule:{required:false,},},sexual_orientation:{name:'sexual_orientation',validateRule:{required:false,},},age:{name:'age',validateRule:{required:true,scenario:'ageOnly',},},day:{name:'day',validateRule:{required:true,scenario:'secondStep',},},month:{name:'month',validateRule:{required:true,scenario:'secondStep',},},year:{name:'year',validateRule:{required:true,scenario:'secondStep',},},screenname:{name:'login',validateRule:{required:true,scenario:'loginOnly',},},region:{name:'region',validateRule:{required:true,scenario:'region',},},location:{name:'location',validateRule:{required:true,scenario:'location',},},email:{name:'email',validateRule:{required:true,scenario:'email',},},password:{name:'password',validateRule:{required:true,scenario:'passwordOnly',},},termsConsent:{name:'termsConsent',validateRule:{required:true,scenario:'termsConsentOnly',},},policyConsent:{name:'policyConsent',validateRule:{required:true,scenario:'policyConsentOnly',},},},userRecoveryProps:{formNamespace:'UserForm',errorElement:`div[data-error-name="UserForm_email"]`,cancelElement:'#recoveryCancelUser',confirmElement:'#recoveryConfirm',passwordElement:'#recoveryPassword',tokenElement:'input[name="YII_CSRF_TOKEN"]',emailElement:`input[name="UserForm[email]"]`,},fData:{},};return this.mergeDeep(defaults,options);} 106initState(formContainer,props){const fields=this.setFields();return{props,formContainer,fields,};} 107getRegMode(){const url=new URL(window.location.href);const urlRegMode=url.searchParams.get('ar');const globalRegMode=window.apexRegMode||'';const regMode=globalRegMode||urlRegMode;switch(regMode){case'1':return REGMODE_APEX;default:return REGMODE_DEFAULT;}} 108get regMode(){return this.getRegMode();} 109setFields(){return Object.values(this.props.fields).reduce((acc,field)=>{const element=this.formContainer.querySelector(`[name='${this.props.formNamespace}[${field.name}]']:not([type='hidden'])`);if(element){const fieldName=element.name;const extendedField={element,fieldName,errorName:`${this.props.formNamespace}_${field.name}`,};acc.push(Object.assign(field,extendedField));} 110const elementWithShortName=this.formContainer.querySelector(`[name='${field.name}']:not([type='hidden'])`);if(elementWithShortName){const fieldName=`${this.props.formNamespace}[${elementWithShortName.name}]`;const extendedField={element:elementWithShortName,fieldName,errorName:`${this.props.formNamespace}_${field.name}`,};acc.push(Object.assign(field,extendedField));} 111return acc;},[]);} 112getFieldsElement(name){const elem=this.state.fields.find(field=>field.name===name);return elem&&elem.element;} 113setFieldValue(name,value){const element=this.state.fields.find(field=>field.name===name).element;element.value=value;element.dispatchEvent(new Event('blur'));element.dispatchEvent(new Event('change'));} 114updateFieldValue(fields){const nodes=fields.map(field=>field.element);
114nodes.forEach(({name,value})=>{const input=this.form.querySelector(`[name*='${name}']`);input&&(input.value=value);});} 115getSuggestContainer(){const suggestInput=this.getFieldsElement('location');this.suggestContainer=suggestInput&&suggestInput.closest(this.props.fieldContainer);return this.suggestContainer;} 116setValidatorEvents(){const validateRequiredFields=this.state.fields.filter(({validateRule})=>validateRule&&validateRule.required);const inputs=validateRequiredFields.filter(input=>input.element.tagName==='INPUT'&&input.element.type!=='checkbox');const termsCheckboxes=validateRequiredFields.filter(input=>input.element.tagName==='INPUT'&&input.element.type=='checkbox');const selects=validateRequiredFields.filter(select=>select.element.tagName==='SELECT');this.submitBtn=this.formContainer.querySelector(this.props.formControls.submitElement);this.submitBtn.addEventListener('mousedown',e=>{if(e.detail>1)return;e.preventDefault();e.target.focus();e.currentTarget.classList.add(this.props.disabledClass);const eventFormSubmitClick=new Event('form-submit-click');this.formContainer.dispatchEvent(eventFormSubmitClick);this.submit(validateRequiredFields);});const eventInputBlur=new Event('field-blur');const handleInputBlur=e=>{const blurPreventSelectors=Array.from(document.querySelectorAll(this.props.formControls.blurPreventValidationSelector));if((this.submitBtn&&this.submitBtn===e.relatedTarget)||(this.multiStep&&this.multiStep.nextBtns.length&&this.multiStep.nextBtns.some(btn=>btn===e.relatedTarget))||(blurPreventSelectors&&blurPreventSelectors.length&&blurPreventSelectors.some(btn=>btn===e.relatedTarget))||(this.suggestLocation&&this.suggestLocation.isSuggestActive)){return;} 117e.target.dispatchEvent(eventInputBlur);};inputs.forEach(input=>{input.element.addEventListener('field-blur',e=>{this.updateFieldValue([input]);this.validator.validate([input]);});input.element.addEventListener('blur',handleInputBlur);input.element.addEventListener('keypress',e=>{if(e.keyCode==13){if(this.multiStep){this.multiStep.nextBtns.forEach((btn)=>{if(!btn.disabled){this.multiStep.setDisabledBtn();this.multiStep.isLastStep()?this.submit(validateRequiredFields):this.multiStep.next(input.element);}});}else{this.submit(validateRequiredFields);}}});});const eventTermsCheckboxesChange=new Event('field-terms-change');termsCheckboxes.forEach(checkbox=>{checkbox.element.addEventListener('field-terms-change',e=>{e.currentTarget.value=e.currentTarget.checked;this.updateFieldValue([checkbox]);this.validator.validate([checkbox]);});checkbox.element.addEventListener('change',e=>{e.target.dispatchEvent(eventTermsCheckboxesChange);});});this.eventFieldChange=new Event('field-change');selects.forEach(select=>{select.element.addEventListener('field-change',e=>{this.updateFieldValue([select]);this.validator.validate([select]);});select.element.addEventListener('change',e=>{e.target.dispatchEvent(this.eventFieldChange);});});inputs.forEach(input=>{input.element.addEventListener('change',e=>{e.target.dispatchEvent(this.eventFieldChange);});});const eventFieldClick=new Event('field-click');inputs.forEach(input=>{input.element.addEventListener('click',e=>{e.target.dispatchEvent(eventFieldClick);});});document.querySelectorAll('.form-select').forEach(select=>{select.addEventListener('click',e=>{e.currentTarget.querySelector('select').dispatchEvent(eventFieldClick);});});this.formContainer.addEventListener('field-validate',()=>{this.updateFieldValue(validateRequiredFields);});} 118setCustomEvents(){const{activeClass}=this.state.props;const notRequiredFields=this.state.fields.filter(({validateRule})=>validateRule&&!validateRule.required);const genderField=this.getFieldsElement('gender');const partnerGenderField=this.getFieldsElement('partnerGender');notRequiredFields.forEach(field=>{field.element.addEventListener('change',()=>{this.updateFieldValue(notRequiredFields);});switch(field.name){case'gender':genderField.addEventListener('change',({target})=>
118{if(partnerGenderField){this.changeOrientation(target.value,partnerGenderField.value);}});const genderBtnsBlock=this.formContainer.querySelector(field.btnBlock);const genderBtns=genderBtnsBlock.querySelectorAll(field.btn);genderBtns.forEach(btn=>{btn.addEventListener('click',e=>{genderBtnsBlock.querySelector(`.${activeClass}`).classList.remove(activeClass);e.currentTarget.classList.add(activeClass);const partnerGenderBtn=this.state.fields.find(field=>field.name=='partnerGender').btn;const partnerGenderValue=this.formContainer.querySelector(`${partnerGenderBtn}.${activeClass}`).dataset.partnerGender;this.changeOrientation(e.currentTarget.dataset.gender,partnerGenderValue);});});break;case'partnerGender':partnerGenderField.addEventListener('change',({target})=>{this.changeOrientation(genderField.value,target.value);});const partnerGenderBtnsBlock=this.formContainer.querySelector(field.btnBlock);const partnerGenderBtns=partnerGenderBtnsBlock.querySelectorAll(field.btn);partnerGenderBtns.forEach(btn=>{btn.addEventListener('click',e=>{partnerGenderBtnsBlock.querySelector(`.${activeClass}`).classList.remove(activeClass);e.currentTarget.classList.add(activeClass);const genderBtn=this.state.fields.find(field=>field.name=='gender').btn;const genderValue=this.formContainer.querySelector(`${genderBtn}.${activeClass}`).dataset.gender;this.changeOrientation(genderValue,e.currentTarget.dataset.partnerGender);});});break;case'sexual_orientation':const orientationField=this.getFieldsElement('sexual_orientation');const eventOrientationChange=new Event('orientation-change');orientationField.addEventListener('orientation-change',({target})=>
118{if(target.dataset.genderSelected){target.dataset.genderSelected=target.selectedOptions[0].dataset.genderValue;this.setOrientation(target.dataset.genderSelected,target.value);return;} 119this.form.querySelector(`[name='${target.name}']`).value=target.value;});orientationField.addEventListener('change',({target})=>{target.dispatchEvent(eventOrientationChange);target.dispatchEvent(this.eventFieldChange);});default:break;}});} 120changeOrientation(gender,partnerGender){if(`${gender}-${partnerGender}`==='male-female')this.setOrientation('male','hetero');if(`${gender}-${partnerGender}`==='male-male')this.setOrientation('male','homo');if(`${gender}-${partnerGender}`==='female-male')this.setOrientation('female','hetero');if(`${gender}-${partnerGender}`==='female-female')this.setOrientation('female','homo');} 121setOrientation(gender,orientation){this.form.querySelector(`[name='${this.state.props.formNamespace}[gender]']`).value=gender;this.form.querySelector(`[name='${this.state.props.formNamespace}[sexual_orientation]']`).value=orientation;document.body.dataset.orientation=`${orientation}-${gender}`;} 122submitApex(){document.body.dataset.regMode=this.regMode;const formData=new FormData(this.form);formData.append('apexReg','1');formData.append('ajax','register-form');formData.append('scenario','register');fetch(this.props.actionURL,{method:'POST',body:formData,}).then(res=>{if(!res.ok){throw new Error(`${res.status} ${res.statusText}`);} 123return res.json();}).then(data=>{if(data.redirectUrl){window.location.href=data.redirectUrl;}}).catch(err=>{console.log('err',err);});} 124async submit(fields){if(!this.isSubmitted){this.updateFieldValue(fields);const errors=await this.validator.validate(fields);if(!errors.size&&!this.isSubmitted){const eventFormSubmit=new Event('form-submit');this.formContainer.dispatchEvent(eventFormSubmit);this.isSubmitted=true;if(this.regMode===REGMODE_APEX){this.submitApex();return;} 125this.form.submit();} 126if(errors.size){this.submitBtn.classList.remove(this.props.disabledClass);}}}}'use strict';var webPushService={loggerEnabled:false,subscribeFlag:false,subscribeOneSignalFlag:false,datinginformUser:null,urlParams:{},initOneSignalFlag:false,safariOptions:false,safariSubscriptionProposed:false,ip:false,vapidAccountId:false,vapidPublicKey:false,init:function(options){this.loggerEnabled=options.loggerEnabled||false;this.oneSignalAllowed=options.oneSignalAllowed||false;this.safariOptions=options.safari||false;this.vapidAccountId=options.vapidAccountId||false;this.vapidPublicKey=options.vapidPublicKey||false;var self=this;if(options.disabledAfterLogin){return false;} 127if(options.oneSignalAllowed){self.initOneSignal({appId:options.safari.appId,safariWebId:options.safari.webId});}else if(options.enabled){if(self.isSupported()){self.registerServiceWorker();}else if(self.isSafariPushSupported()){self.subscribeSafari();}else{if(window.console&&options.loggerEnabled)console.log('Push messaging not supported');if(!options.defaultBlocked)self.track('blocked');}}},isSupported:function(){if(!('serviceWorker'in navigator)){if(window.console&&this.loggerEnabled){console.warn('Service workers aren\'t supported in this browser.');} 128return false;} 129if(!('showNotification'in ServiceWorkerRegistration.prototype)){if(window.console&&this.loggerEnabled){console.warn('Notifications aren\'t supported.');} 130return false;} 131if(Notification.permission==='denied'){if(window.console&&this.loggerEnabled){console.warn('The user has blocked notifications.');} 132return false;} 133if(!('PushManager'in window)){if(window.console&&this.loggerEnabled){console.warn('Push messaging isn\'t supported.');} 134return false;} 135return true;},registerServiceWorker:function(){if(window.console&&this.loggerEnabled)console.log('Register service worker');var self=this;var isSubscriptionProposed=false;navigator.serviceWorker.register('/webPushWorker.js').then(function(serviceWorkerRegistration){if(window.console&&self.loggerEnabled)console.log('Worker ready',serviceWorkerRegistration);navigator.serviceWorker.ready.then(function(serviceWorkerRegistration){if(Notification.permission==='default'){isSubscriptionProposed=true;window.dispatchEvent(new CustomEvent("pushNotificationShow"));self.track('proposed');} 136serviceWorkerRegistration.pushManager.getSubscription().then(function(pushSubscription){return new Promise(function(resolve,reject){if(pushSubscription instanceof PushSub
136scription){if(window.console&&self.loggerEnabled)console.log('Get subscription');resolve(pushSubscription);}else{if(!self.subscribeFlag){self.subscribeFlag=true;var subscribeParams={userVisibleOnly:true};if(self.vapidPublicKey){subscribeParams.applicationServerKey=self.urlBase64ToUint8Array(self.vapidPublicKey);} 137serviceWorkerRegistration.pushManager.subscribe(subscribeParams).then(function(pushSubscription){if(window.console&&self.loggerEnabled)console.log('Subscribe');resolve(pushSubscription);}).catch(function(e){reject(e);});}}});}).then(function(pushSubscription){if(window.console&&self.loggerEnabled)console.log(pushSubscription);if(isSubscriptionProposed){var promise=self.track('accepted',pushSubscription);window.dispatchEvent(new CustomEvent("pushNotificationAccepted"));} 138self.subscribeUser(self.getUserId(),pushSubscription,promise,self.vapidAccountId);}).catch(function(error){if(window.console&&self.loggerEnabled)console.log(error);self.subscribeFlag=false;if(isSubscriptionProposed&&Notification.permission==='denied'){window.dispatchEvent(new CustomEvent("pushNotificationDeclined"));self.track('denied');} 139if(isSubscriptionProposed&&Notification.permission==='default'){window.dispatchEvent(new CustomEvent("pushNotificationClose"));self.track('close');}});}).catch(function(er){if(window.console&&self.loggerEnabled)console.log(er);});}).catch(function(error){if(window.console&&self.loggerEnabled)console.log(error);});},urlBase64ToUint8Array:function(base64String){const padding='='.repeat((4-base64String.length%4)%4);const base64=(base64String+padding).replace(/\-/g,'+').replace(/_/g,'/');const rawData=window.atob(base64);const outputArray=new Uint8Array(rawData.length);for(var i=0;i<rawData.length;++i){outputArray[i]=rawData.charCodeAt(i);} 140return outputArray;},getUserId:function(){if(window.currentUser&&window.currentUser.id){return window.currentUser.id;}else if(window.app&&app.appData&&app.appData().get('user')&&app.appData().get('user').id){return app.appData().get('user').id;}else if(this.isDatinginformUser()&&this.getUrlParams().wpUserId){return this.getUrlParams().wpUserId;}else if(window.app&&app.isB2bApp&&app.managerId){return app.managerId;} 141return'';},getUrlParams:function(){if(!!Object.keys(this.urlParams).length){return this.urlParams;} 142window.location.href.replace(/[?&]+([^=&]+)=([^&]*)/gi,function(m,name,value){this.urlParams[name]=value;}.bind(this));return this.urlParams;},sendSubscribe:function(data,promise){var xhr=new XMLHttpRequest(),self=this;xhr.open("POST","/crm/webPush/subscribe",true);xhr.setRequestHeader("Content-type","application/x-www-form-urlencoded; charset=UTF-8");xhr.onreadystatechange=function(){if(this.readyState==4){if(this.status!=200){if(window.console&&self.loggerEnabled)console.log("Subscribe user",this.responseText);if(promise&&self.isDatinginformUser()){promise.then(function(){window.close();});} 143return;} 144if(promise&&self.isDatinginformUser()){promise.then(function(){window.close();});} 145if(window.console&&self.loggerEnabled)console.log("Not subscribe user",this.responseText);}};xhr.send(data);},isEmptyObj:function(obj){for(var key in obj){if(Object.prototype.hasOwnProperty.call(obj,key)){return false;}} 146return true;},subscribeUser:function(userId,pushSubscription,promise,vapidAccountId){if(window.console&&this.loggerEnabled)console.log('Update user subscription');var self=this;this.getLocalIp(function(ip){var data="userId="+self.getUserId() 147+((window.app&&!self.isEmptyObj(app.csrfToken))?"&"+app.csrfToken.name+"="+app.csrfToken.value:"") 148+"&fingerprint="+self.getFingerprint(ip);if(pushSubscription.subscriptionId&&pushSubscription.endpoint.indexOf(pushSubscription.subscriptionId)===-1){data+="&endpoint="+pushSubscription.endpoint+'/'+ 149pushSubscription.subscriptionId;}else{data+="&subscription="+JSON.stringify(pushSubscription);} 150if(vapidAccountId){data+="&vapidAccountId="+vapidAccountId;} 151data+=self.addMarketingParams();self.sendSubscribe(data,promise);});},addMarketingParams:function(){data='';let searchParams=new URLSearchParams(window.location.search);if(searchParams.has('tds_ac_id')){data+="&tds_campaign="+searchParams.get('tds_ac_id');data+="&tdsId="+searchParams.get('tds_ac_id')+'_r';} 152if(searchParams.has('utm_campaign')){data+="&utm_campaign="+searchParams.get('utm_campaign');}
153if(searchParams.has('utm_content')){data+="&utm_content="+searchParams.get('utm_content');} 154if(searchParams.has('s3')){data+="&s3="+searchParams.get('s3');} 155if(searchParams.has('s1')){data+="&s1="+searchParams.get('s1');} 156if(searchParams.has('utm_source')){data+="&utm_source="+searchParams.get('utm_source');} 157if(searchParams.has('h1')){data+="&h1="+searchParams.get('h1');} 158if(searchParams.has('tds_host')){data+="&tds_host="+searchParams.get('tds_host');} 159if(searchParams.has('utm_term')){data+="&utm_term="+searchParams.get('utm_term');} 160if(searchParams.has('data2')){data+="&data2="+searchParams.get('data2');} 161if(searchParams.has('tds_cid')){data+="&tds_cid="+searchParams.get('tds_cid');} 162if(searchParams.has('p_tds_cid')){data+="&p_tds_cid="+searchParams.get('p_tds_cid');} 163if(searchParams.has('tags')){data+="&tags="+searchParams.get('tags');} 164return data;},sendTrack:function(url,action){var xhr=new XMLHttpRequest(),self=this;xhr.open("GET",url,true);var promiseResolve,promise=new Promise(function(resolve){promiseResolve=resolve;});xhr.onreadystatechange=function(){if(this.readyState==4){promiseResolve();if(this.status!=200){if(window.console&&self.loggerEnabled)console.log("Error while track",this.responseText);return;} 165if(promise&&self.isDatinginformUser()&&(action==="dateinformDenied"||action==='denied')){promise.then(window.close);} 166if(window.console&&self.loggerEnabled)console.log("Tracked",this.responseText);}};xhr.send();return promise;},track:function(action,pushSubscription){if(this.isDatinginformUser()&&(["proposed","denied","accepted","close"].indexOf(action)!==-1)){action="dateinform"+action.charAt(0).toUpperCase()+action.slice(1);} 167if(window.console&&this.loggerEnabled)console.log('Track subscribe '+action);var self=this,url="/crm/webPush/track?userId="+self.getUserId() 168+"&track="+action;if(pushSubscription){url+="&endpoint="+self.getEndpoint(pushSubscription);} 169return this.sendTrack(url,action);},isDatinginformUser:function(){if(typeof this.datinginformUser==="boolean"){return this.datinginformUser;} 170this.datinginformUser=(typeof app!=="object")&&(window.location.host.indexOf("dateinform")!==-1);return this.datinginformUser;},getEndpoint:function(pushSubscription){if(pushSubscription.endpoint.indexOf('https://android.googleapis.com/gcm/send')!==0){return pushSubscription.endpoint;} 171var mergedEndpoint=pushSubscription.endpoint;if(pushSubscription.subscriptionId&&pushSubscription.endpoint.indexOf(pushSubscription.subscriptionId)===-1){mergedEndpoint=pushSubscription.endpoint+'/'+ 172pushSubscription.subscriptionId;} 173return mergedEndpoint;},initOneSignal:function(params){var self=this;window.OneSignal.push(function(){if(OneSignal.isPushNotificationsSupported()){if(!self.initOneSignalFlag){window.OneSignal.push(["init",{appId:params.appId,safari_web_id:params.safariWebId,autoRegister:false}]);self.initOneSignalFlag=true;} 174window.OneSignal.push(["registerForPushNotifications",{modalPrompt:true}]);}});},subscribeOneSignal:function(){var self=this;if(this.oneSignalAllowed){window.OneSignal.push(function(){if(OneSignal.isPushNotificationsSupported()&&!self.subscribeOneSignalFlag){OneSignal.push(["isPushNotificationsEnabled",function(enabled){if(enabled){window.OneSignal.push(["getIdsAvailable",function(ids){if(ids&&ids.userId){var params="userId="+self.getUserId() 175+((window.app&&!self.isEmptyObj(app.csrfToken))?"&"+app.csrfToken.name+"="+app.csrfToken.value:"") 176+"&type=safari®istrationId="+ids.userId;self.sendSubscribe(params);}}]);}}]);}});}},isSafariPushSupported:function(){return this.safariOptions.websitePushId&&'safari'in window&&'pushNotification'in window.safari;},subscribeSafari:function(){var permissionData=window.safari.pushNotification.permission(this.safariOptions.websitePushId);this.checkSafariPermissions(permissionData);},__getSafariWebServiceUrl:function(){if(this.safariOptions&&this.safariOptions.webServiceUrl){return this.safariOptions.webServiceUrl;} 177return'https://'+location.host+'/safariWebPush';},checkSafariPermissions:function(permissionData){if(window.console&&this.loggerEnabled)console.log(permissionData);var self=this;if(permissionData.permission==='default'){self.subscribeProposed=true;if(window.console&&this.loggerEnabled)console.log('request permission');self.track('proposed');window.safari.pushNotification.requestPermission(this.__getSafariWebServiceUrl(),self.safariOptions.websitePushId,{'userId':self.getUserId()},self.checkSafariPermissions);} 178else if(permissionData.permission==='denied'){if(self.subscribeProposed){self.track('denied');self.subscribeProposed=false;} 179if(window.console&&this.loggerEnabled)console.log('The user said no.');} 180else if(permissionData.permission==='granted'){if(window.console&&this.loggerEnabled)console.log('The web service URL is a valid push provider, and the user said yes.');if(window.console&&this.loggerEnabled)console.log(permissionData);if(self.subscribeProposed){self.track('accepted');self.subscribeProposed=false;} 181this.getLocalIp(function(ip){var params="userId="+self.getUserId() 182+((window.app&&!self.isEmptyObj(app.csrfToken))?"&"+app.csrfToken.name+"="+app.csrfToken.value:"") 183+"&type=safari®istrationId="+permissionData.deviceToken 184+"&fingerprint="+self.getFingerprint(ip);self.sendSubscribe(params);});}},getFingerprint:function(ip){var keys=[screen.colorDepth||-1,window.devicePixelRatio||"",navigator.hardwareConcurrency||"unknown",new Date().getTimezoneOffset(),navigator.cpuClass||"unknown",navigator.platform||"unknown"];if(typeof navigator.maxTouchPoints!=="undefined"){keys.push(navigator.maxTouchPoints);}else if(typeof navigator.msMaxTouchPoints!=="undefined"){keys.push(navigator.msMaxTouchPoints);}else{keys.push(0);} 185try{document.createEvent("TouchEvent");keys.push(1);}catch(_){keys.push(0);} 186keys.push("ontouchstart"in window);keys.push(ip);return keys.join('');},getLocalIp:function(callback){if(this.ip){callback(this.ip);return;} 187var RTCPeerConnection=window.RTCPeerConnection||window.mozRTCPeerConnection||window.webkitRTCPeerConnection;var pc=new RTCPeerConnection({iceServers:[{urls:"stun:stun.l.google.com:19302"}]}),noop=function(){};
187pc.createDataChannel("");pc.createOffer(pc.setLocalDescription.bind(pc),noop);pc.onicecandidate=function(ice){if(!ice||!ice.candidate||!ice.candidate.candidate)return;var ip=/([0-9]{1,3}(\.[0-9]{1,3}){3}|[a-f0-9]{1,4}(:[a-f0-9]{1,4}){7})/.exec(ice.candidate.candidate)[1];callback(ip);pc.onicecandidate=noop;};}};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.