vec-idp-web-sdk
Version:
VECU Identity Verification Web SDK - A secure, easy-to-integrate identity verification solution
1 lines • 51.5 kB
JavaScript
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).VecuIDVSDK={})}(this,function(e){"use strict";class t extends Error{constructor(e,i,s,n){super(i),this.name="VecuError",this.code=e,this.provider=s,this.details=n,Error.captureStackTrace&&Error.captureStackTrace(this,t)}toJSON(){return{name:this.name,code:this.code,message:this.message,provider:this.provider,details:this.details,stack:this.stack}}}class i extends t{constructor(e,t,i){super("PROVIDER_ERROR",t,e,i),this.name="ProviderError"}}class s extends t{constructor(e,t){super("TIMEOUT_ERROR",e,void 0,{timeout:t}),this.name="TimeoutError"}}class n{constructor(e){this.requestInterceptors=[],this.responseInterceptors=[],this.baseUrl=e.baseUrl.replace(/\/$/,""),this.timeout=e.timeout||3e4,this.maxRetries=e.maxRetries||3,this.retryDelay=e.retryDelay||1e3}useRequestInterceptor(e){e&&this.requestInterceptors.push({request:e})}useResponseInterceptor(e,t){this.responseInterceptors.push({response:e,error:t})}setSessionToken(e){this.sessionToken=e}updateBaseUrl(e){this.baseUrl=e.replace(/\/$/,"")}getBaseUrl(){return this.baseUrl}async request(e,i={}){const s=`${this.baseUrl}${e}`;let n={...i,headers:{"Content-Type":"application/json",Accept:"application/json",...i.headers}};this.sessionToken&&(n.headers={...n.headers,Authorization:`Bearer ${this.sessionToken}`});for(const e of this.requestInterceptors)e.request&&(n=await e.request(n));const r=new AbortController,o=setTimeout(()=>r.abort(),this.timeout);n.signal=r.signal;try{let e=await this.fetchWithRetry(s,n);clearTimeout(o);for(const t of this.responseInterceptors)t.response&&(e=await t.response(e));const i=e.headers.get("content-type"),r=i?.includes("application/json");if(!e.ok){const i=r?await e.json():{message:await e.text()};throw new t(i.code||`HTTP_${e.status}`,i.message||`Request failed with status ${e.status}`)}return{success:!0,data:r?await e.json():null}}catch(e){clearTimeout(o);let t=e;for(const e of this.responseInterceptors)e.error&&(t=await e.error(t));return t instanceof Error?"AbortError"===t.name?{success:!1,error:{code:"TIMEOUT",message:`Request timed out after ${this.timeout}ms`}}:{success:!1,error:{code:t.code||"NETWORK_ERROR",message:t.message,details:t}}:{success:!1,error:{code:"UNKNOWN_ERROR",message:"An unknown error occurred",details:t}}}}async fetchWithRetry(e,t,i=0){try{const s=await fetch(e,t);if(s.status>=400&&s.status<500)return s;if(s.ok||i>=this.maxRetries)return s;throw new Error(`HTTP ${s.status}: ${s.statusText}`)}catch(s){if("AbortError"===s.name||i>=this.maxRetries)throw s;const n=this.retryDelay*Math.pow(2,i)+1e3*Math.random();return await new Promise(e=>setTimeout(e,n)),this.fetchWithRetry(e,t,i+1)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,i){return this.request(e,{...i,method:"POST",body:t?JSON.stringify(t):void 0})}put(e,t,i){return this.request(e,{...i,method:"PUT",body:t?JSON.stringify(t):void 0})}patch(e,t,i){return this.request(e,{...i,method:"PATCH",body:t?JSON.stringify(t):void 0})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}}class r{constructor(){this.events=new Map}on(e,t){this.events.has(e)||this.events.set(e,new Set),this.events.get(e).add(t)}off(e,t){const i=this.events.get(e);i&&(i.delete(t),0===i.size&&this.events.delete(e))}emit(e,t){const i=this.events.get(e);if(i){const s={type:e,timestamp:new Date,data:t};i.forEach(e=>{try{e(s)}catch{}})}"*"!==e&&this.emit("*",{type:e,data:t})}once(e,t){const i=s=>{this.off(e,i),t(s)};this.on(e,i)}removeAllListeners(e){e?this.events.delete(e):this.events.clear()}listenerCount(e){const t=this.events.get(e);return t?t.size:0}eventNames(){return Array.from(this.events.keys())}}class o{constructor(){this.providers=new Map}register(e){if(!e.name)throw new Error("Provider must have a name");this.providers.has(e.name)&&this.unregister(e.name),this.providers.set(e.name,e)}unregister(e){const t=this.providers.get(e);t&&(t.destroy(),this.providers.delete(e))}get(e){return this.providers.get(e)}getAll(){return Array.from(this.providers.values())}has(e){return this.providers.has(e)}clear(){this.providers.forEach(e=>{e.destroy()}),this.providers.clear()}getByFeature(e){return this.getAll().filter(t=>t.supportedFeatures.includes(e))}getLoadedProviders(){return this.getAll().filter(e=>e.isLoaded)}}class a{constructor(e,t){this.registry=e,this.loadingPromises=new Map,this.eventForwardingSetup=t}async load(e){const t=this.loadingPromises.get(e);if(t)return t;const i=this.registry.get(e);if(i&&i.isLoaded){if("socure"!==e)return i;{const t=i;if(t.socureDocVSDK&&t.sdkLoader.isLoaded())return i;this.registry.unregister(e)}}const s=this.loadProvider(e);this.loadingPromises.set(e,s);try{const t=await s;return this.loadingPromises.delete(e),t}catch(t){throw this.loadingPromises.delete(e),t}}async loadProvider(e){const t=await this.importProvider(e),i=t.default||t[`${this.capitalize(e)}Provider`];if(!i)throw new Error(`Provider class not found for ${e}`);const s=new i;return await s.loadSDK(),this.eventForwardingSetup.setupProviderEventForwarding(s,`auto-${e}-${Date.now()}`),this.registry.has(e)||this.registry.register(s),s}async importProvider(e){switch(e){case"socure":return Promise.resolve().then(function(){return U});case"incode":case"jumio":case"onfido":case"veriff":throw new Error(`Provider ${e} is not yet implemented`);default:throw new Error(`Unknown provider: ${e}`)}}isLoaded(e){const t=this.registry.get(e);return!!t&&t.isLoaded}getLoadedProviders(){return this.registry.getLoadedProviders().map(e=>e.name)}capitalize(e){return e.charAt(0).toUpperCase()+e.slice(1)}}class d{constructor(e){this.listeners=new Map,this.eventEmitter=e}setupProviderEventForwarding(e,t){const i=new Map;["verification:completed","verification:failed","verification:progress","ui:ready","ui:closed","address:verification_needed"].forEach(t=>{const s=e=>{const i=e&&"object"==typeof e&&"data"in e?e.data:e;this.eventEmitter.emit(t,i)};i.set(t,s),e.on(t,s)});const s=e=>{this.eventEmitter.emit("provider:event",e)};i.set("*",s),e.on("*",s),this.listeners.set(t,i)}cleanupProviderEventForwarding(e,t){const i=this.listeners.get(t);i&&(i.forEach((t,i)=>{try{e.off(i,t)}catch{}}),this.listeners.delete(t))}cleanupAll(){this.listeners.clear()}getActiveProviderCount(){return this.listeners.size}getActiveProviderIds(){return Array.from(this.listeners.keys())}}class c{constructor(e="info",t=!0,i="[VecuIDV]"){this.logLevels={error:0,warn:1,info:2,debug:3},this.level=e,this.enabled=t,this.prefix=i}error(e,...t){this.log("error",e,...t)}warn(e,...t){this.log("warn",e,...t)}info(e,...t){this.log("info",e,...t)}debug(e,...t){this.log("debug",e,...t)}log(e,t,...i){if(!this.enabled||!this.shouldLog(e))return;(new Date).toISOString();this.prefix,e.toUpperCase()}shouldLog(e){return this.logLevels[e]<=this.logLevels[this.level]}setLevel(e){this.level=e}setEnabled(e){this.enabled=e}createChildLogger(e){return new c(this.level,this.enabled,`${this.prefix} ${e}`)}}function u(e){const t=e.replace(/\D/g,"");return t?e.startsWith("+")?`+${t}`:10===t.length?`+1${t}`:t.length<10?t.length<=4?`+${t}`:t:`+${t}`:""}function l(e){const t=e;return{firstName:t.firstName,lastName:t.lastName,...t.middleName&&{middleName:t.middleName},...t.email&&{email:t.email},...t.phone&&{phone:u(t.phone)},address:{...t.address.line1&&{line_1:t.address.line1},...t.address.line2&&{line_2:t.address.line2},...t.address.locality&&{locality:t.address.locality},...t.address.minorAdminDivision&&{minor_admin_division:t.address.minorAdminDivision},...t.address.majorAdminDivision&&{major_admin_division:t.address.majorAdminDivision},country:t.address.country,...t.address.postalCode&&{postal_code:t.address.postalCode},...t.address.type&&{type:t.address.type}}}}const h={nonprod:"https://int.dev.api.coxautoinc.com/vehicle-services/wholesale/vecu-idv",sandbox:"https://uat.dev.api.coxautoinc.com/vehicle-services/wholesale/vecu-idv",production:"https://c0j9hytfof.execute-api.us-east-1.amazonaws.com/prod",preprod:"https://c0j9hytfof.execute-api.us-east-1.amazonaws.com/pre-prod"},p={socure:{sandbox:{key:"cnI4cTVxbnIxMzk3LXA5Mm8tc25vOS1vMHMxLTVwMzE0ODhx",url:h.sandbox,addressConfirmation:{enabled:!0,defaultAddress:{name:"John Michael Doe",addressLine1:"123 Main Street",addressLine2:"Apartment 4B",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}},nonprod:{key:"cnI4cTVxbnIxMzk3LXA5Mm8tc25vOS1vMHMxLTVwMzE0ODhx",url:h.nonprod,addressConfirmation:{enabled:!0,defaultAddress:{name:"John Michael Doe",addressLine1:"123 Main Street",addressLine2:"Apartment 4B",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}},production:{key:"placeholder-obfuscated-socure-production-key",url:h.production,addressConfirmation:{enabled:!0,defaultAddress:{name:"John Michael Doe",addressLine1:"123 Main Street",addressLine2:"Apartment 4B",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}},preprod:{key:"placeholder-obfuscated-socure-preprod-key",url:h.preprod,addressConfirmation:{enabled:!0,defaultAddress:{name:"John Michael Doe",addressLine1:"123 Main Street",addressLine2:"Apartment 4B",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}}}};class f{static validateProvider(e,t){if(!t)throw new Error(`No configuration found for provider: ${e}`)}static validateStageConfig(e,t,i){if(!i)throw new Error(`No configuration found for provider: ${e} in deployment stage: ${t}`)}static validateKey(e,t,i){if(!i)throw new Error(`No SDK key configured for provider: ${e} in deployment stage: ${t}`)}static validateUrl(e,t,i){if(!i)throw new Error(`No URL configured for provider: ${e} in deployment stage: ${t}`)}}class v{constructor(){}static getInstance(){return v.instance||(v.instance=new v),v.instance}getProviderConfig(e){return p[e.toLowerCase()]}getStageConfig(e,t){const i=this.getProviderConfig(e);return i?.[t]}getAllConfiguredProviders(){return Object.keys(p)}getProviderStages(e){const t=this.getProviderConfig(e);return t?Object.keys(t):[]}}class m{constructor(e=v.getInstance()){this.configManager=e}resolveKey(e,t="sandbox"){const i=this.configManager.getProviderConfig(e);f.validateProvider(e,i);const s=this.configManager.getStageConfig(e,t);return f.validateStageConfig(e,t,s),f.validateKey(e,t,s.key),s.key}hasKey(e,t="sandbox"){try{return this.resolveKey(e,t),!0}catch{return!1}}}class g{static resolveApiUrl(e="sandbox"){const t=h[e];if(!t)throw new Error(`No API URL configured for deployment stage: ${e}`);return t}static resolveSocureApiUrl(e="sandbox"){const t=h[e];if(!t)throw new Error(`No API URL configured for deployment stage: ${e}`);return t}}const y=new m;function w(e="sandbox"){return g.resolveApiUrl(e)}new class{constructor(e=v.getInstance()){this.configManager=e}resolveUrl(e,t="sandbox"){const i=this.configManager.getProviderConfig(e);f.validateProvider(e,i);const s=this.configManager.getStageConfig(e,t);return f.validateStageConfig(e,t,s),f.validateUrl(e,t,s.url),s.url}};const b=new class{constructor(){this.container=null,this.options=null,this.apiClient=null,this.logger=new c("info",!1)}injectStyles(){if(document.getElementById("vecu-address-confirmation-styles"))return;const e=document.createElement("style");e.id="vecu-address-confirmation-styles",e.textContent="\n .vecu-address-confirmation {\n background: white;\n padding: 30px;\n border-radius: 8px;\n max-width: 600px;\n margin: 0 auto;\n font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;\n }\n \n .vecu-address-confirmation h2 {\n color: #333;\n margin-bottom: 20px;\n text-align: center;\n font-size: 24px;\n }\n \n .vecu-address-display {\n background-color: #f8f9fa;\n padding: 20px;\n border-radius: 8px;\n margin-bottom: 30px;\n border: 1px solid #e9ecef;\n }\n \n .vecu-address-display h3 {\n margin-top: 0;\n margin-bottom: 15px;\n color: #495057;\n font-size: 18px;\n }\n \n .vecu-address-line {\n padding: 8px 0;\n color: #212529;\n font-size: 16px;\n line-height: 1.5;\n display: flex;\n align-items: center;\n }\n \n .vecu-address-line strong {\n display: inline-block;\n min-width: 120px;\n color: #6c757d;\n font-weight: 500;\n margin-right: 10px;\n }\n \n .vecu-address-input {\n flex: 1;\n padding: 8px 12px;\n border: 1px solid #ced4da;\n border-radius: 4px;\n font-size: 16px;\n font-family: inherit;\n transition: border-color 0.15s ease-in-out, box-shadow 0.15s ease-in-out;\n }\n \n .vecu-address-input:focus {\n outline: none;\n border-color: #80bdff;\n box-shadow: 0 0 0 0.2rem rgba(0, 123, 255, 0.25);\n }\n \n .vecu-address-input:disabled {\n background-color: #e9ecef;\n cursor: not-allowed;\n }\n \n .vecu-address-readonly {\n flex: 1;\n padding: 8px 0;\n }\n \n .vecu-confirmation-message {\n text-align: center;\n margin-bottom: 30px;\n color: #495057;\n font-size: 16px;\n }\n \n .vecu-button-group {\n display: flex;\n justify-content: center;\n gap: 20px;\n }\n \n .vecu-button {\n padding: 14px 32px;\n border: none;\n border-radius: 4px;\n cursor: pointer;\n font-size: 16px;\n transition: background-color 0.3s;\n min-width: 200px;\n font-weight: 500;\n }\n \n .vecu-button-confirm {\n background-color: #007bff;\n color: white;\n }\n \n .vecu-button-confirm:hover {\n background-color: #0056b3;\n }\n \n .vecu-success-message {\n text-align: center;\n padding: 40px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 300px;\n }\n \n .vecu-success-message h2 {\n color: #28a745;\n margin-bottom: 20px;\n }\n \n .vecu-success-icon {\n font-size: 48px;\n color: #28a745;\n margin-bottom: 20px;\n }\n \n .vecu-error-message {\n text-align: center;\n padding: 40px;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n min-height: 400px;\n }\n \n .vecu-error-message h2 {\n color: #dc3545;\n margin-bottom: 20px;\n font-size: 24px;\n }\n \n .vecu-error-message p {\n color: #dc3545;\n font-size: 16px;\n margin-bottom: 30px;\n max-width: 400px;\n }\n ",document.head.appendChild(e)}createFormHTML(e){return`\n <div class="vecu-address-confirmation">\n <h2>Address Verification</h2>\n \n <div class="vecu-confirmation-message">\n Please validate or edit this information:\n </div>\n \n <div class="vecu-address-display">\n <h3>Verified Address</h3>\n ${e.name?`\n <div class="vecu-address-line">\n <strong>Full Name:</strong> \n <span class="vecu-address-readonly">${e.name}</span>\n </div>\n `:""}\n <div class="vecu-address-line">\n <strong>Address Line 1:</strong> \n <input type="text" class="vecu-address-input" id="vecu-address1" value="${e.addressLine1}" />\n </div>\n ${e.addressLine2?`\n <div class="vecu-address-line">\n <strong>Address Line 2:</strong> \n <input type="text" class="vecu-address-input" id="vecu-address2" value="${e.addressLine2}" />\n </div>\n `:""}\n <div class="vecu-address-line">\n <strong>City:</strong> \n <input type="text" class="vecu-address-input" id="vecu-city" value="${e.city}" />\n </div>\n <div class="vecu-address-line">\n <strong>State:</strong> \n <input type="text" class="vecu-address-input" id="vecu-state" value="${e.state}" maxlength="2" />\n </div>\n <div class="vecu-address-line">\n <strong>ZIP Code:</strong> \n <input type="text" class="vecu-address-input" id="vecu-zipcode" value="${e.zipCode}" pattern="[0-9]{5}(-[0-9]{4})?" />\n </div>\n <div class="vecu-address-line">\n <strong>Country:</strong> \n <span class="vecu-address-readonly">${e.country}</span>\n </div>\n </div>\n \n <div class="vecu-button-group">\n <button class="vecu-button vecu-button-confirm" id="vecu-confirm-btn">\n Update Address\n </button>\n </div>\n </div>\n `}createSuccessHTML(){return'\n <div class="vecu-success-message">\n <div class="vecu-success-icon">✓</div>\n <h2>Address Updated Successfully!</h2>\n <p>Thank you for updating your address. The verification process is now complete.</p>\n </div>\n '}createErrorHTML(e){return`\n <div class="vecu-error-message">\n <h2>Error</h2>\n <p>${e}</p>\n <button class="vecu-button vecu-button-confirm" id="vecu-retry-btn">\n Try Again\n </button>\n </div>\n `}showErrorMessage(e){if(!this.container)return;this.container.innerHTML=this.createErrorHTML(e);const t=document.getElementById("vecu-retry-btn");t&&t.addEventListener("click",()=>{this.options&&(this.container.innerHTML=this.createFormHTML(this.options.addressData),this.attachEventListeners())})}show(e){this.options=e,this.container=e.container,this.apiClient=e.apiClient||null,this.injectStyles(),this.container.innerHTML=this.createFormHTML(e.addressData),this.attachEventListeners(),this.logger.info("Address verification form displayed")}attachEventListeners(){const e=document.getElementById("vecu-confirm-btn");e&&e.addEventListener("click",()=>{this.handleUpdate()})}async handleUpdate(){if(!this.options||!this.container)return;const e=document.getElementById("vecu-address1")?.value,t=document.getElementById("vecu-address2")?.value,i=document.getElementById("vecu-city")?.value,s=document.getElementById("vecu-state")?.value,n=document.getElementById("vecu-zipcode")?.value;if(!(e&&i&&s&&n))return void alert("Please fill in all required address fields");const r={...this.options.addressData,addressLine1:e,addressLine2:t||"",city:i,state:s.toUpperCase(),zipCode:n};this.logger.info("User updated address",r);const o=document.getElementById("vecu-confirm-btn");if(o&&(o.disabled=!0,o.textContent="Updating..."),this.options.verificationId&&this.apiClient)try{const e={addressData:r};this.logger.info("Making API call to update verification address",{verificationId:this.options.verificationId,addressData:r,endpoint:`/identity/verify/${this.options.verificationId}`});const t=await this.apiClient.patch(`/identity/verify/${this.options.verificationId}`,e);if(!t.success)return this.logger.error("API call failed",t.error),this.showErrorMessage("Failed to update address. Please try again."),void(o&&(o.disabled=!1,o.textContent="Update Address"));this.logger.info("Address update API call succeeded",t.data)}catch(e){return this.logger.error("API call threw error",e),this.showErrorMessage("Network error occurred. Please try again."),void(o&&(o.disabled=!1,o.textContent="Update Address"))}else if(this.options.verificationId||this.logger.warn("No verificationId provided, skipping API call"),!this.apiClient)return this.logger.error("No apiClient provided, cannot make API call. Bearer token not configured."),this.showErrorMessage("Configuration error: Bearer token not configured. Please contact support."),void(o&&(o.disabled=!1,o.textContent="Update Address"));this.container.innerHTML=this.createSuccessHTML(),this.options.onConfirm(this.options.sessionId,r)}destroy(){this.container&&(this.container.innerHTML=""),this.container=null,this.options=null,this.apiClient=null}};function D(e,i){let s=!1;const u=e?.deploymentStage||"sandbox",h={apiUrl:w(u),timeout:3e4,maxRetries:3,logLevel:"info",debug:!1,enableDirectAPI:!0,deploymentStage:u,apiEndpoints:{startVerification:"/identity/verify/start"},...e},p=new r,f=new c(h.logLevel,h.debug),D=function(e,t,i){const s=new n({baseUrl:e.apiUrl,timeout:e.timeout,maxRetries:e.maxRetries});e.bearerToken&&s.setSessionToken(e.bearerToken);const r=new o,c=new d(t);return{apiClient:s,eventEmitter:t,providerRegistry:r,providerLoader:new a(r,{setupProviderEventForwarding:(e,t=`auto-${e.name}-${Date.now()}`)=>{c.setupProviderEventForwarding(e,t)}}),eventForwarder:c,logger:i,keyResolver:new m,apiUrlResolver:g}}(h,p,f),{apiClient:S,providerRegistry:I,providerLoader:A,eventForwarder:E,apiUrlResolver:x}=D;function k(){if(s)f.warn("SDK already initialized");else try{p.emit("sdk:init"),s=!0,p.emit("sdk:ready"),f.info("SDK initialized successfully")}catch(e){throw f.error("Failed to initialize SDK",e),p.emit("sdk:error",{code:"SDK_INIT_FAILED",message:e instanceof Error?e.message:"Unknown error",details:e}),e}}async function C(e,i,n={}){s||k();try{f.info("Launching verification",{token:e});const s="string"==typeof i?document.querySelector(i):i;if(!s)throw new t("INVALID_CONTAINER","Container element not found");const r=n.provider||"socure",o=await A.load(r),a=`verification-${r}-${Date.now()}`;let d;n.onSuccess&&(p.once("address:verification_needed",t=>{(async()=>{const i=t&&"object"==typeof t&&"data"in t?t.data:t;if(i&&"object"==typeof i){const t=i,{verificationId:r,addressData:o,onConfirm:a,onDispute:d}=t;let c=o;if(n.addressConfirmation?.fetchAddress&&r)try{c=await n.addressConfirmation.fetchAddress(r)}catch(e){f.error("Failed to fetch custom address data",e)}const u=r||n.verificationId||e;b.show({container:s,addressData:c,sessionId:e,verificationId:u,apiClient:S,onConfirm:(e,t)=>{f.info("Address confirmed via SDK layer",t),a&&a(),n.addressConfirmation?.onConfirm&&n.addressConfirmation.onConfirm(e)},onDispute:e=>{f.info("Address disputed via SDK layer"),d&&d(),n.addressConfirmation?.onDispute&&n.addressConfirmation.onDispute(e)}})}})()}),p.once("verification:completed",t=>{(async()=>{const i=t.data,o={sessionId:e,provider:r,status:"completed",completedAt:new Date,addressConfirmed:i?.result?.addressConfirmed};if(!o.addressConfirmed&&!1!==o.addressConfirmed){const t=n.deploymentStage||h.deploymentStage||"sandbox",i=function(e,t="sandbox"){const i=v.getInstance().getStageConfig(e,t);return i?.addressConfirmation}(r,t);if((i?.enabled||n.addressConfirmation?.enabled)&&"socure"!==r){let t;if(f.info(`Legacy address confirmation enabled for provider: ${r}`),n.addressConfirmation?.fetchAddress)try{t=await n.addressConfirmation.fetchAddress(e)}catch(e){f.error("Failed to fetch address data, using provider default",e),t=i?.defaultAddress||{name:"John Doe",addressLine1:"123 Main St",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}else n.addressConfirmation?.addressData?t=n.addressConfirmation.addressData:i?.defaultAddress?(t=i.defaultAddress,f.info(`Using provider ${r} default address`)):(t={name:"John Doe",addressLine1:"123 Main St",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"},f.warn("No address data configured, using fallback"));return void b.show({container:s,addressData:t,sessionId:e,verificationId:n.verificationId||e,apiClient:S,onConfirm:(e,t)=>{f.info("Address confirmed by user",t),n.addressConfirmation?.onConfirm&&n.addressConfirmation.onConfirm(e);const i={...o,addressConfirmed:!0};n.onSuccess(i)},onDispute:e=>{f.info("Address disputed by user"),n.addressConfirmation?.onDispute&&n.addressConfirmation.onDispute(e);const t={...o,addressConfirmed:!1};n.onSuccess(t)}})}}n.onSuccess(o)})()})),n.onError&&p.on("verification:failed",e=>{const t=new Error(e.data&&"object"==typeof e.data&&"error"in e.data?e.data.error:"Verification failed");n.onError(t)}),n.onProgress&&p.on("verification:progress",e=>{e.data&&"object"==typeof e.data&&n.onProgress(e.data)});const c=n.deploymentStage||"sandbox";try{d=function(e,t="sandbox"){return y.resolveKey(e,t)}(r,c),f.info(`Using configured SDK key for provider: ${r} in deployment stage: ${c}`)}catch(e){throw f.error(`Failed to get SDK key for provider ${r} in deployment stage: ${c}:`,e),new t("PROVIDER_KEY_NOT_FOUND",`No SDK key configured for provider: ${r} in deployment stage: ${c}`)}const u={...n.config,sdkKey:d,deploymentStage:c},l=await o.initializeVerification({sessionId:e,token:e,container:s,mode:n.mode||"embedded",theme:n.theme,language:n.language,config:u,verificationId:n.verificationId,apiClient:S});return E.setupProviderEventForwarding(o,a),p.emit("verification:started",{provider:r,token:e,ui:l}),()=>{f.info("Cleaning up verification"),l&&"function"==typeof l.destroy&&l.destroy(),E.cleanupProviderEventForwarding(o,a),p.removeAllListeners("address:verification_needed"),p.removeAllListeners("verification:completed"),p.removeAllListeners("verification:failed"),p.removeAllListeners("verification:progress")}}catch(e){throw f.error("Failed to launch verification",e),p.emit("verification:failed",{error:e instanceof Error?e.message:"Unknown error"}),e}}return{launch:C,startVerificationWithCustomer:async function(e,i){if(!h.enableDirectAPI)throw new t("DIRECT_API_DISABLED","Direct API calls are not enabled. Use launch() with a transaction token instead.");s||k();try{f.info("Starting verification with customer info");const s={referenceId:i.referenceId||`customer_${Date.now()}`,config:{webhookUrl:"https://vecu-idv.emulator_idvp.com",...i.config},customerInfo:l(i.customerInfo)},n=h.apiEndpoints?.startVerification??"/identity/verify/start",r=await S.post(n,s);if(!r.success||!r.data)throw new t("VERIFICATION_START_FAILED",r.error&&"object"==typeof r.error&&"message"in r.error?r.error.message:"Failed to start verification");const o=r.data.provider_document_id||r.data.providerDocumentId;if(!o)throw new t("NO_PROVIDER_DOCUMENT_ID","No provider document ID received from API");const a=r.data.verification_id;f.info(`API returned verificationId: ${a}`);const d=r.data.provider||"socure";f.info(`API returned provider: ${d}`);const c={...i,provider:d,deploymentStage:i.deploymentStage,verificationId:a};return c.addressConfirmation?void 0===c.addressConfirmation.enabled&&(c.addressConfirmation.enabled=!0,f.info("Setting addressConfirmation.enabled to true (was undefined)")):(f.info("Auto-enabling address confirmation by default"),c.addressConfirmation={enabled:!0,onConfirm:e=>{f.info("Address confirmed via auto-enabled configuration",{sessionId:e})},onDispute:e=>{f.info("Address disputed via auto-enabled configuration",{sessionId:e})}}),C(o,e,c)}catch(e){throw f.error("Failed to start verification with customer info",e),e}},updateConfig:function(e){if(e.deploymentStage&&e.deploymentStage!==h.deploymentStage){const t=x.resolveApiUrl(e.deploymentStage);e.apiUrl=t,S.updateBaseUrl(t),f.info(`Updated API URL for deployment stage: ${e.deploymentStage} -> ${t}`)}void 0!==e.bearerToken&&e.bearerToken&&(S.setSessionToken(e.bearerToken),f.info("Bearer token updated on APIClient")),Object.assign(h,e),f.info("SDK configuration updated",e)},on:(e,t)=>p.on(e,t),off:(e,t)=>p.off(e,t),once:(e,t)=>p.once(e,t),destroy:()=>{E.cleanupAll(),p.removeAllListeners(),I.clear(),f.info("SDK destroyed")}}}function S(e){try{let t;t="undefined"!=typeof atob?atob(e):Buffer.from(e,"base64").toString();return t.split("").reverse().join("").replace(/[a-zA-Z0-9]/g,e=>{const t=e.charCodeAt(0);return t>=65&&t<=90?String.fromCharCode((t-65-13+26)%26+65):t>=97&&t<=122?String.fromCharCode((t-97-13+26)%26+97):t>=48&&t<=57?String.fromCharCode((t-48-5+10)%10+48):e})}catch{throw new Error("Invalid obfuscated key")}}let I={apiUrl:w("sandbox"),timeout:3e4,maxRetries:3,logLevel:"info",debug:!1,enableDirectAPI:!0,deploymentStage:"sandbox",apiEndpoints:{startVerification:"/identity/verify/start"}};const A=new Map,E={launch:(e,t,i,s={})=>{let n=e;if(/^[A-Za-z0-9+/]+=*$/.test(e)&&e.length>50)try{n=S(e)}catch{n=e}let r=A.get(n);if(!r){const e=D(I);A.set(n,e),r=e}return r.launch(t,i,s)},startVerificationWithCustomer:(e,t)=>{const i="default";let s=A.get(i);if(!s){const e=D(I);A.set(i,e),s=e}return s.startVerificationWithCustomer(e,t)},configure:e=>{const t={...e};e.deploymentStage&&e.deploymentStage!==I.deploymentStage&&(t.apiUrl=w(e.deploymentStage)),I={...I,...t,apiEndpoints:{...I.apiEndpoints,...e.apiEndpoints}},A.forEach(e=>{"updateConfig"in e&&"function"==typeof e.updateConfig&&e.updateConfig(t)})}};"undefined"!=typeof window&&(window.VecuIDVSDK=E);class x{constructor(){this.t=!1,this.sdkInstance=null,this.activeUI=null,this.apiClient=null,this.eventEmitter=new r,this.logger=new c("info",!0)}get isLoaded(){return this.t}mapEvent(e){if(!e||"object"!=typeof e)return null;const t=e;return{type:"string"==typeof t.type?t.type:"unknown",data:t.data||t,timestamp:new Date}}destroy(){this.activeUI&&(this.activeUI.destroy(),this.activeUI=null),this.sdkInstance&&(this.cleanupSDK(),this.sdkInstance=null),this.eventEmitter&&this.eventEmitter.removeAllListeners(),this.t=!1,this.logger.info(`${this.name} provider destroyed`)}async loadScript(e,i){return new Promise((s,n)=>{if(i&&window[i])return this.logger.info(`${this.name} SDK already loaded`),void s();const r=document.createElement("script");r.src=e,r.async=!0,r.crossOrigin="anonymous",r.onload=()=>{this.logger.info(`${this.name} SDK loaded successfully`),s()},r.onerror=i=>{this.logger.error(`Failed to load ${this.name} SDK`,i),n(new t("PROVIDER_SDK_LOAD_FAILED",`Failed to load ${this.name} SDK from ${e}`))},document.head.appendChild(r)})}createUIContainer(e,t){const i=document.createElement("div");i.className=`vecu-idv-${this.name}-container vecu-idv-${t}`,i.setAttribute("data-provider",this.name),i.style.cssText=`\n position: ${"modal"===t?"fixed":"relative"};\n width: 100%;\n height: 100%;\n ${"modal"===t?"top: 0; left: 0; z-index: 9999;":""}\n display: flex;\n align-items: center;\n justify-content: center;\n background-color: ${"modal"===t?"rgba(0, 0, 0, 0.5)":"transparent"};\n `;const s=this.createLoadingSpinner();return i.appendChild(s),e.appendChild(i),i}createLoadingSpinner(){const e=document.createElement("div");return e.className="vecu-idv-loading-spinner",e.setAttribute("role","status"),e.setAttribute("aria-label","Loading verification"),e.innerHTML='\n <style>\n .vecu-idv-loading-spinner {\n text-align: center;\n padding: 20px;\n }\n .vecu-idv-spinner {\n display: inline-block;\n width: 40px;\n height: 40px;\n border: 3px solid rgba(0, 0, 0, 0.1);\n border-radius: 50%;\n border-top-color: #3498db;\n animation: vecu-idv-spin 1s ease-in-out infinite;\n }\n .vecu-idv-loading-text {\n margin-top: 12px;\n color: #666;\n font-family: -apple-system, BlinkMacSystemFont, \'Segoe UI\', Roboto, sans-serif;\n font-size: 14px;\n }\n @keyframes vecu-idv-spin {\n to { transform: rotate(360deg); }\n }\n </style>\n <div class="vecu-idv-spinner"></div>\n <div class="vecu-idv-loading-text">Initializing verification...</div>\n ',e}removeLoadingSpinner(e){const t=e.querySelector(".vecu-idv-loading-spinner");t&&t.remove(),e.style.display="block",e.style.alignItems="",e.style.justifyContent=""}removeUIContainer(e){e&&e.parentNode&&e.parentNode.removeChild(e)}emitProviderEvent(e,t){const i={type:e,data:t,timestamp:new Date};"address:verification_needed"===e?this.eventEmitter.emit(e,t):this.eventEmitter.emit(e,i),this.eventEmitter.emit("provider:event",i)}handleProviderError(e,i){const s=e instanceof t?e:new t("PROVIDER_ERROR",`${this.name} provider error in ${i}: ${e instanceof Error?e.message:String(e)}`,this.name);throw this.logger.error(`${this.name} provider error`,s),this.emitProviderEvent("provider:error",{code:s.code,message:s.message,provider:this.name,context:i}),s}on(e,t){this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}validateInitOptions(e){if(!e.sessionId)throw new t("INVALID_OPTIONS","Session ID is required");if(!e.token)throw new t("INVALID_OPTIONS","Token is required");if(!(e.container&&e.container instanceof HTMLElement))throw new t("INVALID_OPTIONS","Valid HTML container element is required");if(!["modal","embedded"].includes(e.mode))throw new t("INVALID_OPTIONS",'Mode must be either "modal" or "embedded"')}}const k={socure:{scriptUrl:"https://websdk.socure.com/bundle.js",supportedFeatures:["document_verification","liveness_check","face_match","address_verification","database_check","qr_code_handoff"]}},C="ready";class _{constructor(){this.loadPromise=null,this.sdkInstance=null,this.isDestroyed=!1}static getInstance(){return _.instance||(_.instance=new _),_.instance}async load(){if((this.isDestroyed||!this.sdkInstance&&window.SocureDocVSDK)&&(this.isDestroyed=!1,this.sdkInstance=null,this.loadPromise=null,delete window.SocureDocVSDK),this.sdkInstance)return this.sdkInstance;if(this.loadPromise)return this.loadPromise;this.loadPromise=this.loadSDK();try{return this.sdkInstance=await this.loadPromise,this.sdkInstance}catch(e){throw this.loadPromise=null,e}}preload(){this.sdkInstance||this.loadPromise||this.load().catch(e=>{})}async loadSDK(){const e=k.socure,t="SocureDocVSDK";if(window[t])return window[t];const i=new Promise((e,t)=>{setTimeout(()=>{t(new s("Socure SDK load timeout after 30000ms",3e4))},3e4)}),n=(r=this.isDestroyed?`${e.scriptUrl}?t=${Date.now()}`:e.scriptUrl,o={"data-provider":"socure",crossorigin:"anonymous"},new Promise((e,t)=>{const i=function(e,t){const i=document.createElement("script");return t&&Object.entries(t).forEach(([e,t])=>{"className"===e?i.className=t:"style"===e?i.setAttribute("style",t):e.startsWith("data-")?i.setAttribute(e,t):i[e]=t}),i}(0,{src:r,async:"true",...o});i.onload=()=>e(),i.onerror=()=>t(new Error(`Failed to load script: ${r}`)),document.head.appendChild(i)})).then(()=>new Promise((e,i)=>{setTimeout(()=>{const s=window[t];s?e(s):i(new Error(`Socure DocV SDK not found at window.${t}`))},100)}));var r,o;return Promise.race([n,i])}isLoaded(){return null!==this.sdkInstance}getSDK(){return this.sdkInstance}destroy(){this.isDestroyed=!0,window.SocureDocVSDK&&delete window.SocureDocVSDK,document.querySelectorAll('script[src*="websdk.socure.com"]').forEach(e=>{e.remove()}),this.sdkInstance=null,this.loadPromise=null,_.instance=null}}_.instance=null;class T{static mapEvent(e){if(!e||"object"!=typeof e)return null;const t=e.type;return{type:this.eventMap[t]||t,data:this.mapEventData(t,e.data),timestamp:new Date(e.timestamp||Date.now())}}static mapEventData(e,t){switch(e){case"complete":return this.mapCompleteData(t);case"error":return this.mapErrorData(t);case"document_front_capture":case"document_back_capture":return this.mapDocumentCaptureData(t);case"liveness_complete":return this.mapLivenessData(t);case"qr_code_displayed":return this.mapQRCodeData(t);default:return t}}static mapCompleteData(e){if(!e||"object"!=typeof e)return{};const t=e;return{sessionId:t.referenceId||"",status:"completed",documentData:t.documentData?{type:t.documentData?.type,number:t.documentData?.documentNumber,issuingCountry:t.documentData?.issuingCountry,expirationDate:t.documentData?.expirationDate,firstName:t.documentData?.firstName,lastName:t.documentData?.lastName,dateOfBirth:t.documentData?.dateOfBirth,address:t.documentData?.address}:void 0,livenessData:t.livenessData?{passed:t.livenessData?.passed,score:t.livenessData?.score,confidence:t.livenessData?.confidence}:void 0,fraudSignals:t.fraud?{overallRisk:this.mapRiskLevel(t.fraud?.score),signals:(t.fraud?.signals||[]).map(e=>({type:e.name,risk:e.risk,description:e.description}))}:void 0}}static mapErrorData(e){if(!e||"object"!=typeof e)return{code:"UNKNOWN_ERROR",message:"Unknown error occurred"};const t=e;return{code:t.code||"SOCURE_ERROR",message:t.message||"Socure verification error",details:t.details,provider:"socure"}}static mapDocumentCaptureData(e){return{side:e?.side||"unknown",quality:e?.quality||"unknown",timestamp:(new Date).toISOString()}}static mapLivenessData(e){return{passed:e?.passed||!1,score:e?.score||0,confidence:e?.confidence||"low",timestamp:(new Date).toISOString()}}static mapQRCodeData(e){return{qrCodeUrl:e?.url,sessionUrl:e?.sessionUrl,expiresAt:e?.expiresAt}}static mapRiskLevel(e){return e<30?"low":e<70?"medium":"high"}static mapWebhookData(e){if(!e||"object"!=typeof e)return null;const t=e,i=t.documentVerification?.decision||t.selfieVerification?.decision||"review";return{sessionId:t.referenceId,provider:"socure",status:"complete"===t.status?"completed":"failed",decision:this.mapDecision(i),documentData:t.documentVerification?{type:t.documentVerification?.documentType,...t.documentVerification?.documentFields}:void 0,livenessData:t.selfieVerification?{passed:"accept"===t.selfieVerification?.decision,score:t.selfieVerification?.livenessScore,confidence:this.mapConfidence(t.selfieVerification?.livenessScore)}:void 0,fraudSignals:t.fraud?{overallRisk:this.mapRiskLevel(t.fraud?.score),signals:(t.fraud?.signals||[]).map(e=>({type:e,risk:"medium",description:e}))}:void 0,completedAt:t.updatedAt?new Date(t.updatedAt):new Date}}static mapDecision(e){switch(e){case"accept":return"approved";case"reject":return"declined";default:return"review"}}static mapConfidence(e){return e>=80?"high":e>=50?"medium":"low"}}T.eventMap={init:C,ready:C,start:"start",document_front_capture:"document:front:capture",document_back_capture:"document:back:capture",document_processing:"document:processing",liveness_start:"liveness:start",liveness_processing:"liveness:processing",liveness_complete:"liveness:complete",complete:"complete",error:"error",close:"close",qr_code_displayed:"qr_code:displayed",mobile_handoff:"mobile:handoff"};var U=Object.freeze({__proto__:null,SocureProvider:class extends x{getCompletionMessage(e){return e.mobileNumber?"Verification complete! Check your SMS for further instructions.":e.customerUserId?"Verification complete! Please check your email for further instructions.":"Verification completed successfully! You may now proceed."}constructor(){super(),this.name="socure",this.version="1.0.0",this.supportedFeatures=[...k.socure.supportedFeatures],this.socureDocVSDK=null,this.activeSession=null,this.deploymentStage="sandbox",this.sdkLoader=_.getInstance()}async loadSDK(){try{this.logger.info("Loading Socure DocV SDK..."),this.sdkLoader||(this.sdkLoader=_.getInstance()),this.socureDocVSDK=await this.sdkLoader.load(),this.t=!0,this.logger.info("Socure DocV SDK loaded successfully"),this.emitProviderEvent("provider:loaded",{provider:this.name})}catch(e){this.t=!1,this.handleProviderError(e,"loadSDK")}}async initializeVerification(e){try{if(this.validateInitOptions(e),e.apiClient&&(this.apiClient=e.apiClient,this.logger.info("APIClient received from SDK with bearer token configured")),this.currentVerificationId=e.verificationId,e.config?.deploymentStage&&(this.deploymentStage=e.config.deploymentStage,this.logger.info("Deployment stage set to:",this.deploymentStage)),window.SocureDocVSDK||document.querySelector('iframe[src*="socure"]')){if(this.logger.info("Detected existing Socure state, cleaning up before initialization..."),e.container instanceof HTMLElement)for(;e.container.firstChild;)e.container.removeChild(e.container.firstChild);this.clearSocureDOM(),this.clearSocureGlobals(),this.t=!1,this.socureDocVSDK=null,this.sdkLoader&&(this.sdkLoader.destroy(),this.sdkLoader=_.getInstance()),await new Promise(e=>setTimeout(e,100)),await this.loadSDK()}if(!this.socureDocVSDK)throw new i(this.name,"Socure DocV SDK not loaded");this.logger.info("Initializing Socure verification",{sessionId:e.sessionId,hasSDK:!!this.socureDocVSDK,sdkType:typeof this.socureDocVSDK,methods:this.socureDocVSDK?Object.keys(this.socureDocVSDK):[]});let t=e.config?.publicKey||e.config?.sdkKey;if(!t||"string"!=typeof t)throw new i(this.name,"Socure SDK key is required in provider config");if(/^[A-Za-z0-9+/]+=*$/.test(t)&&t.length>50)try{t=S(t),this.logger.info("Socure SDK key deobfuscated successfully")}catch{this.logger.warn("Failed to deobfuscate Socure SDK key, using as plain key")}const s=e.token;if(!s)throw new i(this.name,"docvTransactionToken is required");const n=this.createUIContainer(e.container,e.mode);this.emitProviderEvent("verification:progress",{sessionId:e.sessionId,step:"initializing_ui",percentage:20,message:"Preparing verification interface..."});const r={onProgress:t=>{this.logger.info("Socure progress event",t),this.handleProgressEvent(t,e.sessionId)},onSuccess:t=>{if(this.logger.info("Socure verification completed",t),"status"in t&&"DOCUMENTS_UPLOADED"===t.status)this.handleProgressEvent(t,e.sessionId).catch(e=>{this.logger.error("Error handling DOCUMENTS_UPLOADED event",e)});else if(!("status"in t)||"DOCUMENTS_UPLOADED"!==t.status){const i=T.mapEvent({type:"complete",data:t,timestamp:Date.now()});i&&this.emitProviderEvent(i.type,i.data);const s={sessionId:e.sessionId,message:"Verification completed successfully! You may now proceed.",result:t};this.emitProviderEvent("verification:completed",s)}},onError:t=>{if(this.logger.error("Socure verification error",t),!("status"in t)||"CONSENT_DECLINED"!==t.status&&"DOCUMENTS_UPLOAD_FAILED"!==t.status){const i=T.mapEvent({type:"error",data:t,timestamp:Date.now()});i&&this.emitProviderEvent(i.type,i.data),"code"in t&&"USER_CANCELLED"===t.code&&this.emitProviderEvent("ui:closed",{sessionId:e.sessionId})}else{const i="CONSENT_DECLINED"===t.status?"USER_CANCELLED":"UPLOAD_FAILED";this.emitProviderEvent("verification:failed",{sessionId:e.sessionId,error:{code:i,message:t.status.replace(/_/g," ").toLowerCase(),docvTransactionToken:t.docvTransactionToken}}),"CONSENT_DECLINED"===t.status&&this.emitProviderEvent("ui:closed",{sessionId:e.sessionId})}},qrCodeNeeded:Boolean(e.config?.qrCode)||!1},o=`socure-container-${Date.now()}`;n.id=o;const a=`#${o}`;let d;try{this.emitProviderEvent("verification:progress",{sessionId:e.sessionId,step:"loading_provider",percentage:40,message:"Loading identity verification..."}),d=this.socureDocVSDK.launch(t,s,a,r),this.removeLoadingSpinner(n)}catch(e){throw this.removeLoadingSpinner(n),e}this.activeSession=d&&"object"==typeof d?d:{id:e.sessionId,status:"active",destroy:()=>{this.logger.info("Destroying Socure session")}};const c={container:n,sessionId:e.sessionId,provider:this.name,destroy:()=>{this.destroySession(),this.removeUIContainer(n)}};return this.activeUI=c,this.emitProviderEvent("ui:created",{sessionId:e.sessionId}),setTimeout(()=>{this.emitProviderEvent("ui:ready",{sessionId:e.sessionId}),this.emitProviderEvent("verification:progress",{sessionId:e.sessionId,step:"ready",percentage:60,message:"Verification interface ready"})},100),c}catch(e){this.handleProviderError(e,"initializeVerification")}}processWebhookData(e){try{const t=T.mapWebhookData(e);if(!t)throw new i(this.name,"No mapped data returned from webhook");return{status:t.status||"unknown",decision:t.decision,data:{documentData:t.documentData||void 0,livenessData:t.livenessData||void 0,fraudSignals:t.fraudSignals||void 0},metadata:{provider:this.name,processedAt:(new Date).toISOString()}}}catch(e){throw this.logger.error("Failed to process webhook data",e),new i(this.name,"Failed to process webhook data")}}mapEvent(e){return T.mapEvent(e)}cleanupSDK(){this.destroySession(),this.clearSocureDOM(),this.clearSocureGlobals(),this.sdkLoader.destroy(),this.socureDocVSDK=null}clearSocureDOM(){['iframe[src*="socure"], iframe[id*="socure"]','[id*="socure-container"], .socure-sdk-container','script[src*="websdk.socure.com"]'].forEach(e=>{document.querySelectorAll(e).forEach(e=>{this.logger.info(`Removing Socure element: ${e.tagName}`),e.remove()})})}clearSocureGlobals(){["SocureDocVSDK","Socure","socure","SOCURE"].forEach(e=>{window[e]&&(this.logger.info(`Clearing global ${e}`),delete window[e])})}async handleProgressEvent(e,t){if(e.status){const i={WAITING_FOR_USER_TO_REDIRECT:"qr_code_displayed",WAITING_FOR_UPLOAD:"verification:started",DOCUMENTS_UPLOADED:"verification:completed"}[e.status]||"verification:progress";if("DOCUMENTS_UPLOADED"===e.status){const i=this.currentVerificationId||e.customerUserId||e.docvTransactionToken||e.key;if(i)try{this.logger.info("Fetching Socure evaluation for address verification",{socureEvalId:i,verificationId:this.currentVerificationId});const s=await this.fetchSocureEvaluation(i);let n=null;if(s.providerData?.parsedAddress){const e=s.providerData.parsedAddress;n={name:s.providerData.fullName||"N/A",addressLine1:e.physicalAddress||"",addressLine2:e.physicalAddress2||"",city:e.city||"",state:e.state||"",zipCode:e.zip||"",country:e.country||"USA"}}else if(s.data_enrichments&&Array.isArray(s.data_enrichments))for(let e=0;e<s.data_enrichments.length;e++){const t=s.data_enrichments[e];t.response&&"object"==typeof t.response&&t.response;const i=t.response?.documentData?.parsedAddress;if(i){n={name:`${i.firstName||""} ${i.lastName||""}`.trim()||"N/A",addressLine1:i.address||"",addressLine2:i.addressLine2||"",city:i.city||"",state:i.state||"",zipCode:i.postalCode||"",country:i.country||"United States"};break}}if(n)return this.logger.info("Address data extracted from Socure evaluation",n),void this.emitProviderEvent("address:verification_needed",{sessionId:t,verificationId:i,addressData:n,onConfirm:async()=>{this.logger.info("User confirmed address");try{await this.updateSocureEvaluation(this.currentVerificationId,{addressConfirmation:"confirmed",timestamp:(new Date).toISOString()}),this.logger.info("Socure evaluation updated with address confirmation")}catch(e){this.logger.error("Failed to update Socure evaluation",e)}const i=this.getCompletionMessage(e),s={sessionId:t,message:i,result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!0}};this.emitProviderEvent("verification:completed",s)},onDispute:async()=>{this.logger.info("User disputed address");try{await this.updateSocureEvaluation(this.currentVerificationId,{addressConfirmation:"disputed",timestamp:(new Date).toISOString()}),this.logger.info("Socure evaluation updated with address dispute")}catch(e){this.logger.error("Failed to update Socure evaluation",e)}const i={sessionId:t,message:"Address verification disputed. Additional review may be required.",result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!1}};this.emitProviderEvent("verification:completed",i)}});{this.logger.warn("No address data found in Socure evaluation, using default address");const s={sessionId:t,verificationId:i,addressData:{name:"John Doe",addressLine1:"123 Main Street",addressLine2:"Apt 4B",city:"Springfield",state:"IL",zipCode:"62704",country:"United States"},onConfirm:()=>{this.logger.info("User confirmed default address");const i=this.getCompletionMessage(e),s={sessionId:t,message:i,result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!0}};this.emitProviderEvent("verification:completed",s)},onDispute:()=>{this.logger.info("User disputed default address");const i={sessionId:t,message:"Address verification disputed. Additional review may be required.",result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!1}};this.emitProviderEvent("verification:completed",i)}};return void this.emitProviderEvent("address:verification_needed",s)}}catch(s){this.logger.error("Failed to fetch Socure evaluation for address verification",s);const n={name:"John Doe",addressLine1:"123 Main Street",addressLine2:"Apt 4B",city:"Springfield",state:"IL",zipCode:"62704",country:"United States"};return void this.emitProviderEvent("address:verification_needed",{sessionId:t,verificationId:i,addressData:n,onConfirm:()=>{this.logger.info("User confirmed default address");const i=this.getCompletionMessage(e),s={sessionId:t,message:i,result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!0}};this.emitProviderEvent("verification:completed",s)},onDispute:()=>{this.logger.info("User disputed default address");const i={sessionId:t,message:"Address verification disputed. Additional review may be required.",result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!1}};this.emitProviderEvent("verification:completed",i)}})}const s=this.getCompletionMessage(e),n={sessionId:t,message:s,result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId}};this.emitProviderEvent("verification:completed",n)}else this.emitProviderEvent(i,{sessionId:t,status:e.status,docvTransactionToken:e.docvTransactionToken,customerUserId:e.customerUserId,mobileNumber:e.mobileNumber}),this.emitProviderEvent("verification:progress",{sessionId:t,step:e.status,percentage:"WAITING_FOR_USER_TO_REDIRECT"===e.status?10:30,message:e.status.replace(/_/g," ").toLowerCase()})}else this.logger.warn("Received unexpected progress event structure from Socure",e)}async fetchSocureEvaluation(e,t=5){if(!this.apiClient)throw this.logger.error("APIClient not avai