UNPKG

vec-idp-web-sdk

Version:

VECU Identity Verification Web SDK - A secure, easy-to-integrate identity verification solution

1 lines 55.4 kB
class e extends Error{constructor(t,s,i,r){super(s),this.name="VecuError",this.code=t,this.provider=i,this.details=r,Error.captureStackTrace&&Error.captureStackTrace(this,e)}toJSON(){return{name:this.name,code:this.code,message:this.message,provider:this.provider,details:this.details,stack:this.stack}}}class t extends e{constructor(e,t,s){super("PROVIDER_ERROR",t,e,s),this.name="ProviderError"}}class s extends e{constructor(e,t){super("TIMEOUT_ERROR",e,void 0,{timeout:t}),this.name="TimeoutError"}}const i={INVALID_API_KEY:"INVALID_API_KEY",MISSING_CONFIG:"MISSING_CONFIG",INVALID_CONFIG:"INVALID_CONFIG",SDK_NOT_INITIALIZED:"SDK_NOT_INITIALIZED",SDK_INIT_FAILED:"SDK_INIT_FAILED",SDK_ALREADY_INITIALIZED:"SDK_ALREADY_INITIALIZED",PROVIDER_NOT_FOUND:"PROVIDER_NOT_FOUND",PROVIDER_LOAD_FAILED:"PROVIDER_LOAD_FAILED",PROVIDER_SDK_LOAD_FAILED:"PROVIDER_SDK_LOAD_FAILED",PROVIDER_INIT_FAILED:"PROVIDER_INIT_FAILED",PROVIDER_NOT_SUPPORTED:"PROVIDER_NOT_SUPPORTED",SESSION_NOT_FOUND:"SESSION_NOT_FOUND",SESSION_EXPIRED:"SESSION_EXPIRED",SESSION_CREATE_FAILED:"SESSION_CREATE_FAILED",SESSION_ALREADY_EXISTS:"SESSION_ALREADY_EXISTS",VERIFICATION_FAILED:"VERIFICATION_FAILED",VERIFICATION_CANCELLED:"VERIFICATION_CANCELLED",VERIFICATION_TIMEOUT:"VERIFICATION_TIMEOUT",INVALID_CONTAINER:"INVALID_CONTAINER",UI_INIT_FAILED:"UI_INIT_FAILED",UI_DESTROYED:"UI_DESTROYED",NETWORK_ERROR:"NETWORK_ERROR",TIMEOUT_ERROR:"TIMEOUT_ERROR",API_ERROR:"API_ERROR",INVALID_OPTIONS:"INVALID_OPTIONS",INVALID_USER_DATA:"INVALID_USER_DATA",MISSING_REQUIRED_FIELD:"MISSING_REQUIRED_FIELD"};class r{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(t,s={}){const i=`${this.baseUrl}${t}`;let r={...s,headers:{"Content-Type":"application/json",Accept:"application/json",...s.headers}};this.sessionToken&&(r.headers={...r.headers,Authorization:`Bearer ${this.sessionToken}`});for(const e of this.requestInterceptors)e.request&&(r=await e.request(r));const n=new AbortController,o=setTimeout(()=>n.abort(),this.timeout);r.signal=n.signal;try{let t=await this.fetchWithRetry(i,r);clearTimeout(o);for(const e of this.responseInterceptors)e.response&&(t=await e.response(t));const s=t.headers.get("content-type"),n=s?.includes("application/json");if(!t.ok){const s=n?await t.json():{message:await t.text()};throw new e(s.code||`HTTP_${t.status}`,s.message||`Request failed with status ${t.status}`)}return{success:!0,data:n?await t.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,s=0){try{const i=await fetch(e,t);if(i.status>=400&&i.status<500)return i;if(i.ok||s>=this.maxRetries)return i;throw new Error(`HTTP ${i.status}: ${i.statusText}`)}catch(i){if("AbortError"===i.name||s>=this.maxRetries)throw i;const r=this.retryDelay*Math.pow(2,s)+1e3*Math.random();return await new Promise(e=>setTimeout(e,r)),this.fetchWithRetry(e,t,s+1)}}get(e,t){return this.request(e,{...t,method:"GET"})}post(e,t,s){return this.request(e,{...s,method:"POST",body:t?JSON.stringify(t):void 0})}put(e,t,s){return this.request(e,{...s,method:"PUT",body:t?JSON.stringify(t):void 0})}patch(e,t,s){return this.request(e,{...s,method:"PATCH",body:t?JSON.stringify(t):void 0})}delete(e,t){return this.request(e,{...t,method:"DELETE"})}}class n{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 s=this.events.get(e);s&&(s.delete(t),0===s.size&&this.events.delete(e))}emit(e,t){const s=this.events.get(e);if(s){const i={type:e,timestamp:new Date,data:t};s.forEach(e=>{try{e(i)}catch{}})}"*"!==e&&this.emit("*",{type:e,data:t})}once(e,t){const s=i=>{this.off(e,s),t(i)};this.on(e,s)}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 s=this.registry.get(e);if(s&&s.isLoaded){if("socure"!==e)return s;{const t=s;if(t.socureDocVSDK&&t.sdkLoader.isLoaded())return s;this.registry.unregister(e)}}const i=this.loadProvider(e);this.loadingPromises.set(e,i);try{const t=await i;return this.loadingPromises.delete(e),t}catch(t){throw this.loadingPromises.delete(e),t}}async loadProvider(e){const t=await this.importProvider(e),s=t.default||t[`${this.capitalize(e)}Provider`];if(!s)throw new Error(`Provider class not found for ${e}`);const i=new s;return await i.loadSDK(),this.eventForwardingSetup.setupProviderEventForwarding(i,`auto-${e}-${Date.now()}`),this.registry.has(e)||this.registry.register(i),i}async importProvider(e){switch(e){case"socure":return Promise.resolve().then(function(){return J});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 s=new Map;["verification:completed","verification:failed","verification:progress","ui:ready","ui:closed","address:verification_needed"].forEach(t=>{const i=e=>{const s=e&&"object"==typeof e&&"data"in e?e.data:e;this.eventEmitter.emit(t,s)};s.set(t,i),e.on(t,i)});const i=e=>{this.eventEmitter.emit("provider:event",e)};s.set("*",i),e.on("*",i),this.listeners.set(t,s)}cleanupProviderEventForwarding(e,t){const s=this.listeners.get(t);s&&(s.forEach((t,s)=>{try{e.off(s,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,s="[VecuIDV]"){this.logLevels={error:0,warn:1,info:2,debug:3},this.level=e,this.enabled=t,this.prefix=s}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,...s){if(!this.enabled||!this.shouldLog(e))return;const i=(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}`)}}let l=null;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 p(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 m={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"},f={socure:{sandbox:{key:"cnI4cTVxbnIxMzk3LXA5Mm8tc25vOS1vMHMxLTVwMzE0ODhx",url:m.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:m.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:m.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:m.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 h{static validateProvider(e,t){if(!t)throw new Error(`No configuration found for provider: ${e}`)}static validateStageConfig(e,t,s){if(!s)throw new Error(`No configuration found for provider: ${e} in deployment stage: ${t}`)}static validateKey(e,t,s){if(!s)throw new Error(`No SDK key configured for provider: ${e} in deployment stage: ${t}`)}static validateUrl(e,t,s){if(!s)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 f[e.toLowerCase()]}getStageConfig(e,t){const s=this.getProviderConfig(e);return s?.[t]}getAllConfiguredProviders(){return Object.keys(f)}getProviderStages(e){const t=this.getProviderConfig(e);return t?Object.keys(t):[]}}class g{constructor(e=v.getInstance()){this.configManager=e}resolveKey(e,t="sandbox"){const s=this.configManager.getProviderConfig(e);h.validateProvider(e,s);const i=this.configManager.getStageConfig(e,t);return h.validateStageConfig(e,t,i),h.validateKey(e,t,i.key),i.key}hasKey(e,t="sandbox"){try{return this.resolveKey(e,t),!0}catch{return!1}}}class I{static resolveApiUrl(e="sandbox"){const t=m[e];if(!t)throw new Error(`No API URL configured for deployment stage: ${e}`);return t}static resolveSocureApiUrl(e="sandbox"){const t=m[e];if(!t)throw new Error(`No API URL configured for deployment stage: ${e}`);return t}}const y=new g;function D(e="sandbox"){return I.resolveApiUrl(e)}function E(e="sandbox"){return I.resolveSocureApiUrl(e)}new class{constructor(e=v.getInstance()){this.configManager=e}resolveUrl(e,t="sandbox"){const s=this.configManager.getProviderConfig(e);h.validateProvider(e,s);const i=this.configManager.getStageConfig(e,t);return h.validateStageConfig(e,t,i),h.validateUrl(e,t,i.url),i.url}};class S{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,s=document.getElementById("vecu-city")?.value,i=document.getElementById("vecu-state")?.value,r=document.getElementById("vecu-zipcode")?.value;if(!(e&&s&&i&&r))return void alert("Please fill in all required address fields");const n={...this.options.addressData,addressLine1:e,addressLine2:t||"",city:s,state:i.toUpperCase(),zipCode:r};this.logger.info("User updated address",n);const o=document.getElementById("vecu-confirm-btn");if(o&&(o.disabled=!0,o.textContent="Updating..."),this.options.verificationId&&this.apiClient)try{const e={addressData:n};this.logger.info("Making API call to update verification address",{verificationId:this.options.verificationId,addressData:n,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,n)}destroy(){this.container&&(this.container.innerHTML=""),this.container=null,this.options=null,this.apiClient=null}}const w=new S;function A(e,t,s){const i=new r({baseUrl:e.apiUrl,timeout:e.timeout,maxRetries:e.maxRetries});e.bearerToken&&i.setSessionToken(e.bearerToken);const n=new o,c=new d(t);return{apiClient:i,eventEmitter:t,providerRegistry:n,providerLoader:new a(n,{setupProviderEventForwarding:(e,t=`auto-${e.name}-${Date.now()}`)=>{c.setupProviderEventForwarding(e,t)}}),eventForwarder:c,logger:s,keyResolver:new g,apiUrlResolver:I}}function C(t,s){let i=!1;const r=t?.deploymentStage||"sandbox",o={apiUrl:D(r),timeout:3e4,maxRetries:3,logLevel:"info",debug:!1,enableDirectAPI:!0,deploymentStage:r,apiEndpoints:{startVerification:"/identity/verify/start"},...t},a=s?.eventEmitter||new n,d=s?.logger||new c(o.logLevel,o.debug),l=s?{...A(o,a,d),...s}:A(o,a,d),{apiClient:u,providerRegistry:m,providerLoader:f,eventForwarder:h,apiUrlResolver:g}=l;function I(){if(i)d.warn("SDK already initialized");else try{a.emit("sdk:init"),i=!0,a.emit("sdk:ready"),d.info("SDK initialized successfully")}catch(e){throw d.error("Failed to initialize SDK",e),a.emit("sdk:error",{code:"SDK_INIT_FAILED",message:e instanceof Error?e.message:"Unknown error",details:e}),e}}async function E(t,s,r={}){i||I();try{d.info("Launching verification",{token:t});const i="string"==typeof s?document.querySelector(s):s;if(!i)throw new e("INVALID_CONTAINER","Container element not found");const n=r.provider||"socure",c=await f.load(n),l=`verification-${n}-${Date.now()}`;let p;r.onSuccess&&(a.once("address:verification_needed",e=>{(async()=>{const s=e&&"object"==typeof e&&"data"in e?e.data:e;if(s&&"object"==typeof s){const e=s,{verificationId:n,addressData:o,onConfirm:a,onDispute:c}=e;let l=o;if(r.addressConfirmation?.fetchAddress&&n)try{l=await r.addressConfirmation.fetchAddress(n)}catch(e){d.error("Failed to fetch custom address data",e)}const p=n||r.verificationId||t;w.show({container:i,addressData:l,sessionId:t,verificationId:p,apiClient:u,onConfirm:(e,t)=>{d.info("Address confirmed via SDK layer",t),a&&a(),r.addressConfirmation?.onConfirm&&r.addressConfirmation.onConfirm(e)},onDispute:e=>{d.info("Address disputed via SDK layer"),c&&c(),r.addressConfirmation?.onDispute&&r.addressConfirmation.onDispute(e)}})}})()}),a.once("verification:completed",e=>{(async()=>{const s=e.data,a={sessionId:t,provider:n,status:"completed",completedAt:new Date,addressConfirmed:s?.result?.addressConfirmed};if(!a.addressConfirmed&&!1!==a.addressConfirmed){const e=r.deploymentStage||o.deploymentStage||"sandbox",s=function(e,t="sandbox"){const s=v.getInstance().getStageConfig(e,t);return s?.addressConfirmation}(n,e);if((s?.enabled||r.addressConfirmation?.enabled)&&"socure"!==n){let e;if(d.info(`Legacy address confirmation enabled for provider: ${n}`),r.addressConfirmation?.fetchAddress)try{e=await r.addressConfirmation.fetchAddress(t)}catch(t){d.error("Failed to fetch address data, using provider default",t),e=s?.defaultAddress||{name:"John Doe",addressLine1:"123 Main St",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"}}else r.addressConfirmation?.addressData?e=r.addressConfirmation.addressData:s?.defaultAddress?(e=s.defaultAddress,d.info(`Using provider ${n} default address`)):(e={name:"John Doe",addressLine1:"123 Main St",city:"San Francisco",state:"CA",zipCode:"94105",country:"United States"},d.warn("No address data configured, using fallback"));return void w.show({container:i,addressData:e,sessionId:t,verificationId:r.verificationId||t,apiClient:u,onConfirm:(e,t)=>{d.info("Address confirmed by user",t),r.addressConfirmation?.onConfirm&&r.addressConfirmation.onConfirm(e);const s={...a,addressConfirmed:!0};r.onSuccess(s)},onDispute:e=>{d.info("Address disputed by user"),r.addressConfirmation?.onDispute&&r.addressConfirmation.onDispute(e);const t={...a,addressConfirmed:!1};r.onSuccess(t)}})}}r.onSuccess(a)})()})),r.onError&&a.on("verification:failed",e=>{const t=new Error(e.data&&"object"==typeof e.data&&"error"in e.data?e.data.error:"Verification failed");r.onError(t)}),r.onProgress&&a.on("verification:progress",e=>{e.data&&"object"==typeof e.data&&r.onProgress(e.data)});const m=r.deploymentStage||"sandbox";try{p=function(e,t="sandbox"){return y.resolveKey(e,t)}(n,m),d.info(`Using configured SDK key for provider: ${n} in deployment stage: ${m}`)}catch(t){throw d.error(`Failed to get SDK key for provider ${n} in deployment stage: ${m}:`,t),new e("PROVIDER_KEY_NOT_FOUND",`No SDK key configured for provider: ${n} in deployment stage: ${m}`)}const g={...r.config,sdkKey:p,deploymentStage:m},I=await c.initializeVerification({sessionId:t,token:t,container:i,mode:r.mode||"embedded",theme:r.theme,language:r.language,config:g,verificationId:r.verificationId,apiClient:u});return h.setupProviderEventForwarding(c,l),a.emit("verification:started",{provider:n,token:t,ui:I}),()=>{d.info("Cleaning up verification"),I&&"function"==typeof I.destroy&&I.destroy(),h.cleanupProviderEventForwarding(c,l),a.removeAllListeners("address:verification_needed"),a.removeAllListeners("verification:completed"),a.removeAllListeners("verification:failed"),a.removeAllListeners("verification:progress")}}catch(e){throw d.error("Failed to launch verification",e),a.emit("verification:failed",{error:e instanceof Error?e.message:"Unknown error"}),e}}return{launch:E,startVerificationWithCustomer:async function(t,s){if(!o.enableDirectAPI)throw new e("DIRECT_API_DISABLED","Direct API calls are not enabled. Use launch() with a transaction token instead.");i||I();try{d.info("Starting verification with customer info");const i={referenceId:s.referenceId||`customer_${Date.now()}`,config:{webhookUrl:"https://vecu-idv.emulator_idvp.com",...s.config},customerInfo:p(s.customerInfo)},r=o.apiEndpoints?.startVerification??"/identity/verify/start",n=await u.post(r,i);if(!n.success||!n.data)throw new e("VERIFICATION_START_FAILED",n.error&&"object"==typeof n.error&&"message"in n.error?n.error.message:"Failed to start verification");const a=n.data.provider_document_id||n.data.providerDocumentId;if(!a)throw new e("NO_PROVIDER_DOCUMENT_ID","No provider document ID received from API");const c=n.data.verification_id;d.info(`API returned verificationId: ${c}`);const l=n.data.provider||"socure";d.info(`API returned provider: ${l}`);const m={...s,provider:l,deploymentStage:s.deploymentStage,verificationId:c};return m.addressConfirmation?void 0===m.addressConfirmation.enabled&&(m.addressConfirmation.enabled=!0,d.info("Setting addressConfirmation.enabled to true (was undefined)")):(d.info("Auto-enabling address confirmation by default"),m.addressConfirmation={enabled:!0,onConfirm:e=>{d.info("Address confirmed via auto-enabled configuration",{sessionId:e})},onDispute:e=>{d.info("Address disputed via auto-enabled configuration",{sessionId:e})}}),E(a,t,m)}catch(e){throw d.error("Failed to start verification with customer info",e),e}},updateConfig:function(e){if(e.deploymentStage&&e.deploymentStage!==o.deploymentStage){const t=g.resolveApiUrl(e.deploymentStage);e.apiUrl=t,u.updateBaseUrl(t),d.info(`Updated API URL for deployment stage: ${e.deploymentStage} -> ${t}`)}void 0!==e.bearerToken&&e.bearerToken&&(u.setSessionToken(e.bearerToken),d.info("Bearer token updated on APIClient")),Object.assign(o,e),d.info("SDK configuration updated",e)},on:(e,t)=>a.on(e,t),off:(e,t)=>a.off(e,t),once:(e,t)=>a.once(e,t),destroy:()=>{h.cleanupAll(),a.removeAllListeners(),m.clear(),d.info("SDK destroyed")}}}const _="1.0.0",T="@vecu-idv-web-sdk",b={SDK_INIT:"sdk:init",SDK_READY:"sdk:ready",SDK_ERROR:"sdk:error",SDK_DESTROY:"sdk:destroy",PROVIDER_LOADED:"provider:loaded",PROVIDER_READY:"provider:ready",PROVIDER_ERROR:"provider:error",PROVIDER_EVENT:"provider:event",VERIFICATION_CREATED:"verification:created",VERIFICATION_STARTED:"verification:started",VERIFICATION_PROGRESS:"verification:progress",VERIFICATION_COMPLETED:"verification:completed",VERIFICATION_FAILED:"verification:failed",VERIFICATION_CANCELLED:"verification:cancelled",VERIFICATION_EXPIRED:"verification:expired",UI_CREATED:"ui:created",UI_READY:"ui:ready",UI_ERROR:"ui:error",UI_CLOSED:"ui:closed",UI_DESTROYED:"ui:destroyed"},L=["socure","incode","jumio","onfido","veriff"],R={DOCUMENT_VERIFICATION:"document_verification",LIVENESS_CHECK:"liveness_check",FACE_MATCH:"face_match",ADDRESS_VERIFICATION:"address_verification",DATABASE_CHECK:"database_check",PHONE_VERIFICATION:"phone_verification",EMAIL_VERIFICATION:"email_verification",QR_CODE_HANDOFF:"qr_code_handoff",VIDEO_VERIFICATION:"video_verification"},k=(l||(l=new c),l).createChildLogger("[SocureAPI]");class O{constructor(e,t="sandbox"){this.apiToken=e,this.baseUrl=E(t)}async fetchEvaluation(e){const t=`${this.baseUrl}/evaluation/${e}`;k.info(`Fetching evaluation data for ID: ${e}`);try{const e=await fetch(t,{method:"GET",headers:{Authorization:`Bearer ${this.apiToken}`,"X-API-Version":"",Accept:"application/json","Content-Type":"application/json"}});if(!e.ok)throw new Error(`API request failed with status: ${e.status}`);const s=await e.json();return k.debug("Received evaluation data",s),s}catch(e){throw k.error("Failed to fetch evaluation data",e),e}}extractAddressFromEvaluation(e){if(!e.data_enrichments||!Array.isArray(e.data_enrichments))return k.warn("No data enrichments found in evaluation response"),null;for(let t=0;t<e.data_enrichments.length;t++){const s=e.data_enrichments[t];if(s.response,s.response&&"object"==typeof s.response&&null!==s.response&&"documentVerification"in s.response&&"object"==typeof s.response.documentVerification&&null!==s.response.documentVerification&&"documentData"in s.response.documentVerification){const e=s.response.documentVerification.documentData;if(e.parsedAddress){k.info("Found parsed address in document data");return this.transformSocureAddress(e.parsedAddress,e.fullName)}if(e.address){k.info("Parsing raw address string");return this.parseRawAddress(e.address,e.fullName)}}}return k.warn("No address data found in evaluation response"),e.data_enrichments.forEach((e,t)=>{}),null}transformSocureAddress(e,t){return{name:t||"",addressLine1:e.physicalAddress||"",addressLine2:"",city:e.city||"",state:e.state||"",zipCode:e.zip||"",country:e.country||"USA"}}parseRawAddress(e,t){const s=e.split(",").map(e=>e.trim());let i="",r="";if(s.length>=3){const e=s[2],t=e.match(/^([A-Z]{2})\s+(\d{5}(?:-\d{4})?)$/);if(t)i=t[1],r=t[2];else{const t=e.split(" ");t.length>=2&&(i=t[0],r=t[1])}}return{name:t||"",addressLine1:s[0]||"",addressLine2:"",city:s[1]||"",state:i,zipCode:r,country:"USA"}}async fetchAddressFromEvaluation(e){try{const t=await this.fetchEvaluation(e),s=this.extractAddressFromEvaluation(t);if(!s)throw new Error("No address data found in evaluation response");return s}catch(e){throw k.error("Failed to fetch address from evaluation",e),e}}}function N(e,t="sandbox"){const s=new O(e,t);return async e=>s.fetchAddressFromEvaluation(e)}class P{constructor(){this._isLoaded=!1,this.sdkInstance=null,this.activeUI=null,this.apiClient=null,this.eventEmitter=new n,this.logger=new c("info",!0)}get isLoaded(){return this._isLoaded}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._isLoaded=!1,this.logger.info(`${this.name} provider destroyed`)}async loadScript(t,s){return new Promise((i,r)=>{if(s&&window[s])return this.logger.info(`${this.name} SDK already loaded`),void i();const n=document.createElement("script");n.src=t,n.async=!0,n.crossOrigin="anonymous",n.onload=()=>{this.logger.info(`${this.name} SDK loaded successfully`),i()},n.onerror=s=>{this.logger.error(`Failed to load ${this.name} SDK`,s),r(new e("PROVIDER_SDK_LOAD_FAILED",`Failed to load ${this.name} SDK from ${t}`))},document.head.appendChild(n)})}createUIContainer(e,t){const s=document.createElement("div");s.className=`vecu-idv-${this.name}-container vecu-idv-${t}`,s.setAttribute("data-provider",this.name),s.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 i=this.createLoadingSpinner();return s.appendChild(i),e.appendChild(s),s}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 s={type:e,data:t,timestamp:new Date};"address:verification_needed"===e?this.eventEmitter.emit(e,t):this.eventEmitter.emit(e,s),this.eventEmitter.emit("provider:event",s)}handleProviderError(t,s){const i=t instanceof e?t:new e("PROVIDER_ERROR",`${this.name} provider error in ${s}: ${t instanceof Error?t.message:String(t)}`,this.name);throw this.logger.error(`${this.name} provider error`,i),this.emitProviderEvent("provider:error",{code:i.code,message:i.message,provider:this.name,context:s}),i}on(e,t){this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}validateInitOptions(t){if(!t.sessionId)throw new e("INVALID_OPTIONS","Session ID is required");if(!t.token)throw new e("INVALID_OPTIONS","Token is required");if(!(t.container&&t.container instanceof HTMLElement))throw new e("INVALID_OPTIONS","Valid HTML container element is required");if(!["modal","embedded"].includes(t.mode))throw new e("INVALID_OPTIONS",'Mode must be either "modal" or "embedded"')}}const U={socure:{scriptUrl:"https://websdk.socure.com/bundle.js",supportedFeatures:["document_verification","liveness_check","face_match","address_verification","database_check","qr_code_handoff"]}},x="ready",V="start",F="complete",$="error",M="close",K="document:front:capture",z="document:back:capture",j="document:processing",q="liveness:start",B="liveness:processing",H="liveness:complete";function G(e,t){return new Promise((s,i)=>{const r=function(e,t){const s=document.createElement(e);return t&&Object.entries(t).forEach(([e,t])=>{"className"===e?s.className=t:"style"===e?s.setAttribute("style",t):e.startsWith("data-")?s.setAttribute(e,t):s[e]=t}),s}("script",{src:e,async:"true",...t});r.onload=()=>s(),r.onerror=()=>i(new Error(`Failed to load script: ${e}`)),document.head.appendChild(r)})}class W{constructor(){this.loadPromise=null,this.sdkInstance=null,this.isDestroyed=!1}static getInstance(){return W.instance||(W.instance=new W),W.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=U.socure,t="SocureDocVSDK";if(window[t])return window[t];const i=3e4,r=new Promise((e,t)=>{setTimeout(()=>{t(new s("Socure SDK load timeout after 30000ms",i))},i)}),n=G(this.isDestroyed?`${e.scriptUrl}?t=${Date.now()}`:e.scriptUrl,{"data-provider":"socure",crossorigin:"anonymous"}).then(()=>new Promise((e,s)=>{setTimeout(()=>{const i=window[t];i?e(i):s(new Error(`Socure DocV SDK not found at window.${t}`))},100)}));return Promise.race([n,r])}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,W.instance=null}}W.instance=null;class Y{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,s=t.documentVerification?.decision||t.selfieVerification?.decision||"review";return{sessionId:t.referenceId,provider:"socure",status:"complete"===t.status?"completed":"failed",decision:this.mapDecision(s),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"}}Y.eventMap={init:x,ready:x,start:V,document_front_capture:K,document_back_capture:z,document_processing:j,liveness_start:q,liveness_processing:B,liveness_complete:H,complete:F,error:$,close:M,qr_code_displayed:"qr_code:displayed",mobile_handoff:"mobile:handoff"};var J=Object.freeze({__proto__:null,SocureProvider:class extends P{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=[...U.socure.supportedFeatures],this.socureDocVSDK=null,this.activeSession=null,this.deploymentStage="sandbox",this.sdkLoader=W.getInstance()}async loadSDK(){try{this.logger.info("Loading Socure DocV SDK..."),this.sdkLoader||(this.sdkLoader=W.getInstance()),this.socureDocVSDK=await this.sdkLoader.load(),this._isLoaded=!0,this.logger.info("Socure DocV SDK loaded successfully"),this.emitProviderEvent("provider:loaded",{provider:this.name})}catch(e){this._isLoaded=!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._isLoaded=!1,this.socureDocVSDK=null,this.sdkLoader&&(this.sdkLoader.destroy(),this.sdkLoader=W.getInstance()),await new Promise(e=>setTimeout(e,100)),await this.loadSDK()}if(!this.socureDocVSDK)throw new t(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 s=e.config?.publicKey||e.config?.sdkKey;if(!s||"string"!=typeof s)throw new t(this.name,"Socure SDK key is required in provider config");if(/^[A-Za-z0-9+/]+=*$/.test(s)&&s.length>50)try{s=function(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")}}(s),this.logger.info("Socure SDK key deobfuscated successfully")}catch{this.logger.warn("Failed to deobfuscate Socure SDK key, using as plain key")}const i=e.token;if(!i)throw new t(this.name,"docvTransactionToken is required");const r=this.createUIContainer(e.container,e.mode);this.emitProviderEvent("verification:progress",{sessionId:e.sessionId,step:"initializing_ui",percentage:20,message:"Preparing verification interface..."});const n={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 s=Y.mapEvent({type:"complete",data:t,timestamp:Date.now()});s&&this.emitProviderEvent(s.type,s.data);const i={sessionId:e.sessionId,message:"Verification completed successfully! You may now proceed.",result:t};this.emitProviderEvent("verification:completed",i)}},onError:t=>{if(this.logger.error("Socure verification error",t),!("status"in t)||"CONSENT_DECLINED"!==t.status&&"DOCUMENTS_UPLOAD_FAILED"!==t.status){const s=Y.mapEvent({type:"error",data:t,timestamp:Date.now()});s&&this.emitProviderEvent(s.type,s.data),"code"in t&&"USER_CANCELLED"===t.code&&this.emitProviderEvent("ui:closed",{sessionId:e.sessionId})}else{const s="CONSENT_DECLINED"===t.status?"USER_CANCELLED":"UPLOAD_FAILED";this.emitProviderEvent("verification:failed",{sessionId:e.sessionId,error:{code:s,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()}`;r.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(s,i,a,n),this.removeLoadingSpinner(r)}catch(e){throw this.removeLoadingSpinner(r),e}this.activeSession=d&&"object"==typeof d?d:{id:e.sessionId,status:"active",destroy:()=>{this.logger.info("Destroying Socure session")}};const c={container:r,sessionId:e.sessionId,provider:this.name,destroy:()=>{this.destroySession(),this.removeUIContainer(r)}};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 s=Y.mapWebhookData(e);if(!s)throw new t(this.name,"No mapped data returned from webhook");return{status:s.status||"unknown",decision:s.decision,data:{documentData:s.documentData||void 0,livenessData:s.livenessData||void 0,fraudSignals:s.fraudSignals||void 0},metadata:{provider:this.name,processedAt:(new Date).toISOString()}}}catch(e){throw this.logger.error("Failed to process webhook data",e),new t(this.name,"Failed to process webhook data")}}mapEvent(e){return Y.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 s={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 s=this.currentVerificationId||e.customerUserId||e.docvTransactionToken||e.key;if(s)try{this.logger.info("Fetching Socure evaluation for address verification",{socureEvalId:s,verificationId:this.currentVerificationId});const i=await this.fetchSocureEvaluation(s);let r=null;if(i.providerData?.parsedAddress){const e=i.providerData.parsedAddress;r={name:i.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(i.data_enrichments&&Array.isArray(i.data_enrichments))for(let e=0;e<i.data_enrichments.length;e++){const t=i.data_enrichments[e];t.response&&"object"==typeof t.response&&t.response;const s=t.response?.documentData?.parsedAddress;if(s){r={name:`${s.firstName||""} ${s.lastName||""}`.trim()||"N/A",addressLine1:s.address||"",addressLine2:s.addressLine2||"",city:s.city||"",state:s.state||"",zipCode:s.postalCode||"",country:s.country||"United States"};break}}if(r)return this.logger.info("Address data extracted from Socure evaluation",r),void this.emitProviderEvent("address:verification_needed",{sessionId:t,verificationId:s,addressData:r,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 s=this.getCompletionMessage(e),i={sessionId:t,message:s,result:{status:"completed",docvTransactionToken:e.docvTransactionToken,deviceSessionToken:e.deviceSessionToken,customerUserId:e.customerUserId,addressConfirmed:!0}