New Case Study:See how Anthropic automated 95% of dependency reviews with Socket.Learn More
Socket
Sign inDemoInstall
Socket

@speechly/browser-client

Package Overview
Dependencies
Maintainers
6
Versions
79
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@speechly/browser-client - npm Package Compare versions

Comparing version 2.6.2 to 2.6.3

2

core/speechly.umd.min.js
!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).Speechly={})}(this,(function(t){"use strict";const e=new Error("Current device does not support microphone API"),i=new Error("AppId changed without project login");class s extends Error{constructor(t,e,i,...s){super(...s),this.name=`WebsocketError code ${e}`,this.message=t,this.code=e,this.wasClean=i}}const n=16e3;class o{constructor(t,e){this.isFinalized=!1,this.words=[],this.entities=new Map,this.intent={intent:"",isFinal:!1},this.contextId=t,this.id=e}toSegment(){let t=0;const e=new Array(this.entities.size);return this.entities.forEach((i=>{e[t]=i,t++})),{id:this.id,contextId:this.contextId,isFinal:this.isFinalized,words:this.words,entities:e,intent:this.intent}}toString(){const t=this.toSegment(),e=t.words.filter((t=>t.value)),i=Object.assign(Object.assign({},t),{words:e});return JSON.stringify(i,null,2)}updateTranscript(t){return t.forEach((t=>{this.isFinalized&&!t.isFinal||(this.words[t.index]=t)})),this}updateEntities(t){return t.forEach((t=>{this.isFinalized&&!t.isFinal||this.entities.set(this.entityMapKey(t),t)})),this}updateIntent(t){return this.isFinalized&&!t.isFinal||(this.intent=t),this}finalize(){return this.entities.forEach(((t,e)=>{t.isFinal||this.entities.delete(e)})),this.words=this.words.filter((t=>t.isFinal)),this.intent.isFinal||(this.intent.intent="",this.intent.isFinal=!0),this.isFinalized=!0,this}entityMapKey(t){return`${t.startPosition.toString()}:${t.endPosition.toString()}`}}function a(t,e,i,s){return new(i||(i=Promise))((function(n,o){function a(t){try{c(s.next(t))}catch(t){o(t)}}function d(t){try{c(s.throw(t))}catch(t){o(t)}}function c(t){var e;t.done?n(t.value):(e=t.value,e instanceof i?e:new i((function(t){t(e)}))).then(a,d)}c((s=s.apply(t,e||[])).next())}))}const d=new Error("Microphone is not initialized"),c=new Error("Microphone is already initialized"),l=new Error("Microphone consent is not given");var r,h,u,p;t.AudioSourceState=void 0,(r=t.AudioSourceState||(t.AudioSourceState={})).NoAudioConsent="NoAudioConsent",r.NoBrowserSupport="NoBrowserSupport",r.Stopped="Stopped",r.Starting="Starting",r.Started="Started";t.WebsocketResponseType=void 0,(h=t.WebsocketResponseType||(t.WebsocketResponseType={})).Started="started",h.Stopped="stopped",h.SegmentEnd="segment_end",h.Transcript="transcript",h.Entity="entity",h.Intent="intent",h.TentativeTranscript="tentative_transcript",h.TentativeEntities="tentative_entities",h.TentativeIntent="tentative_intent",t.WorkerSignal=void 0,(u=t.WorkerSignal||(t.WorkerSignal={})).Opened="WEBSOCKET_OPEN",u.Closed="WEBSOCKET_CLOSED",u.AudioProcessorReady="SOURCE_SAMPLE_RATE_SET_SUCCESS",u.VadSignalHigh="VadSignalHigh",u.VadSignalLow="VadSignalLow",u.RequestContextStart="RequestContextStart",t.ControllerSignal=void 0,(p=t.ControllerSignal||(t.ControllerSignal={})).connect="connect",p.initAudioProcessor="initAudioProcessor",p.adjustAudioProcessor="adjustAudioProcessor",p.SET_SHARED_ARRAY_BUFFERS="SET_SHARED_ARRAY_BUFFERS",p.CLOSE="CLOSE",p.START_CONTEXT="START_CONTEXT",p.SWITCH_CONTEXT="SWITCH_CONTEXT",p.STOP_CONTEXT="STOP_CONTEXT",p.AUDIO="AUDIO",p.startStream="startStream",p.stopStream="stopStream",p.setContextOptions="setContextOptions";const b=new Error("Current device does not support storage API"),m=new Error("Requested key was not present in storage"),Z={connect:!0,apiUrl:"https://api.speechly.com",sampleRate:n,debug:!1,logSegments:!1,frameMillis:30,historyFrames:5},y={enabled:!1,controlListening:!0,signalToNoiseDb:3,noiseGateDb:-24,noiseLearnHalftimeMillis:400,signalSearchFrames:5,signalActivation:.7,signalRelease:.2,signalSustainMillis:3e3},G={preserveSegments:!1,sampleRate:n,immediate:!1,autoStarted:!1};var v;t.DecoderState=void 0,(v=t.DecoderState||(t.DecoderState={}))[v.Failed=0]="Failed",v[v.Disconnected=1]="Disconnected",v[v.Connected=2]="Connected",v[v.Active=3]="Active";class W extends Array{addEventListener(t){this.push(t)}removeEventListener(t){const e=this.findIndex((e=>e===t));e>=0&&this.splice(e,1)}}class R{constructor(){this.stateChangeCbs=new W,this.transcriptCbs=new W,this.entityCbs=new W,this.intentCbs=new W,this.segmentChangeCbs=new W,this.tentativeTranscriptCbs=new W,this.tentativeEntityCbs=new W,this.tentativeIntentCbs=new W,this.contextStartedCbs=new W,this.contextStoppedCbs=new W,this.onVadStateChange=new W}}const S=new Error("BrowserClient already started"),X=new Error("BrowserClient already stopped");function V(t){var e;return null!==(e=g.get(t))&&void 0!==e?e:"unknown"}const g=new Map([[t.DecoderState.Failed,"Failed"],[t.DecoderState.Disconnected,"Disconnected"],[t.DecoderState.Connected,"Connected"],[t.DecoderState.Active,"Active"]]);var C,z=new Uint8Array(16);function N(){if(!C&&!(C="undefined"!=typeof crypto&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto)||"undefined"!=typeof msCrypto&&"function"==typeof msCrypto.getRandomValues&&msCrypto.getRandomValues.bind(msCrypto)))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return C(z)}var T=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;function Y(t){return"string"==typeof t&&T.test(t)}for(var f=[],F=0;F<256;++F)f.push((F+256).toString(16).substr(1));function x(t,e,i){var s=(t=t||{}).random||(t.rng||N)();if(s[6]=15&s[6]|64,s[8]=63&s[8]|128,e){i=i||0;for(var n=0;n<16;++n)e[i+n]=s[n];return e}return function(t){var e=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,i=(f[t[e+0]]+f[t[e+1]]+f[t[e+2]]+f[t[e+3]]+"-"+f[t[e+4]]+f[t[e+5]]+"-"+f[t[e+6]]+f[t[e+7]]+"-"+f[t[e+8]]+f[t[e+9]]+"-"+f[t[e+10]]+f[t[e+11]]+f[t[e+12]]+f[t[e+13]]+f[t[e+14]]+f[t[e+15]]).toLowerCase();if(!Y(i))throw TypeError("Stringified UUID is invalid");return i}(s)}var L="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:{},I={exports:{}};
/*! http://mths.be/base64 v0.1.0 by @mathias | MIT license */
!function(t,e){!function(i){var s=e,n=t&&t.exports==s&&t,o="object"==typeof L&&L;o.global!==o&&o.window!==o||(i=o);var a=function(t){this.message=t};(a.prototype=new Error).name="InvalidCharacterError";var d=function(t){throw new a(t)},c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=/[\t\n\f\r ]/g,r={encode:function(t){t=String(t),/[^\0-\xFF]/.test(t)&&d("The string to be encoded contains characters outside of the Latin1 range.");for(var e,i,s,n,o=t.length%3,a="",l=-1,r=t.length-o;++l<r;)e=t.charCodeAt(l)<<16,i=t.charCodeAt(++l)<<8,s=t.charCodeAt(++l),a+=c.charAt((n=e+i+s)>>18&63)+c.charAt(n>>12&63)+c.charAt(n>>6&63)+c.charAt(63&n);return 2==o?(e=t.charCodeAt(l)<<8,i=t.charCodeAt(++l),a+=c.charAt((n=e+i)>>10)+c.charAt(n>>4&63)+c.charAt(n<<2&63)+"="):1==o&&(n=t.charCodeAt(l),a+=c.charAt(n>>2)+c.charAt(n<<4&63)+"=="),a},decode:function(t){var e=(t=String(t).replace(l,"")).length;e%4==0&&(e=(t=t.replace(/==?$/,"")).length),(e%4==1||/[^+a-zA-Z0-9/]/.test(t))&&d("Invalid character: the string to be decoded is not correctly encoded.");for(var i,s,n=0,o="",a=-1;++a<e;)s=c.indexOf(t.charAt(a)),i=n%4?64*i+s:s,n++%4&&(o+=String.fromCharCode(255&i>>(-2*n&6)));return o},version:"0.1.0"};if(s&&!s.nodeType)if(n)n.exports=r;else for(var h in r)r.hasOwnProperty(h)&&(s[h]=r[h]);else i.base64=r}(L)}(I,I.exports);function w(t,e,i,s,n=Date.now){const o=function(t){const e=t.split(".")[1];let i;try{i=JSON.parse(I.exports.decode(e))}catch(t){throw new Error("Error decoding Speechly token!")}return{appId:i.appId,projectId:i.projectId,deviceId:i.deviceId,configId:i.configId,scopes:i.scope.split(" "),issuer:i.iss,audience:i.aud,expiresAtMs:1e3*i.exp}}(t);return!(o.expiresAtMs-n()<36e5)&&(o.appId===i&&o.projectId===e&&o.deviceId===s)}class k{constructor(){this.startCbs=[],this.stopCbs=[],this.onResponseCb=()=>{},this.onCloseCb=()=>{},this.onWebsocketMessage=e=>{const i=e.data;switch(i.type){case t.WorkerSignal.Opened:this.onInitResolve&&this.onInitResolve();break;case t.WorkerSignal.Closed:const n=new s(e.data.reason,e.data.code,e.data.wasClean);this.onInitReject?this.onInitReject(n):this.onCloseCb(n);break;case t.WorkerSignal.AudioProcessorReady:null!=this.resolveSourceSampleRateSet&&this.resolveSourceSampleRateSet();break;case t.WebsocketResponseType.Started:this.onResponseCb(i),this.startCbs.forEach((t=>{try{t(void 0,i.audio_context)}catch(t){console.error('[SpeechlyClient] Error while invoking "onStart" callback:',t)}})),this.startCbs.length=0;break;case t.WebsocketResponseType.Stopped:this.onResponseCb(i),this.stopCbs.forEach((t=>{try{t(void 0,i.audio_context)}catch(t){console.error('[SpeechlyClient] Error while invoking "onStop" callback:',t)}})),this.stopCbs.length=0;break;default:this.onResponseCb(i)}},this.worker=new"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwp2YXIgd29ya2VyX2NvZGU9ZnVuY3Rpb24odCl7InVzZSBzdHJpY3QiO2NsYXNzIGV7c3RhdGljIGRvd25zYW1wbGUodCxlLHM9MCxpPS0xLG89MCxhPS0xKXtpZihpPDAmJihpPXQubGVuZ3RoLXMpLGE8MCYmKGE9ZS5sZW5ndGgtbyksYT5pKXRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZG93bnNhbXBsZTogc291cmNlIGFycmF5IGxlbmd0aCAoJHtpfSkgaXMgc2hvcnRlciB0aGFuIGRlc3RpbmF0aW9uICgke2F9KWApO2lmKDA9PT1hKXRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZG93bnNhbXBsZTogc291cmNlIGFycmF5IGxlbmd0aCAoJHtpfSkgY2FuJ3QgYmUgZG93bnNhbXBsZWQgdG8gemVyby1sZW5ndGggZGVzdGluYXRpb24uYCk7aWYoMD09PWkpdGhyb3cgbmV3IEVycm9yKCJDYW4ndCBkb3duc2FtcGxlOiBzb3VyY2UgcmFuZ2UgY2FuJ3QgYmUgemVybyBsZW5ndGguIik7aWYoMT09PWkpcmV0dXJuIHZvaWQoZVswXT10WzBdKTtsZXQgcj0wO2NvbnN0IG49KGEtMSkvKGktMSk7bGV0IGg9MCxkPTA7Y29uc3QgbD1zK2k7Zm9yKDtzPGw7cysrKXtjb25zdCBpPS41LU1hdGguYWJzKHIpO2grPXRbc10qaSxkKz1pLHIrPW4scj49LjUmJihyLT0xLGVbbysrXT1oL2QsaD0wLGQ9MCl9ZD4wJiYoZVtvKytdPWgvZCl9c3RhdGljIGdldEVuZXJneSh0LGU9MCxzPS0xKXtpZihzPDAmJihzPXQubGVuZ3RoLWUpLHM8PTApcmV0dXJuIDA7Y29uc3QgaT1lK3M7bGV0IG89MDtmb3IoO2U8aTtlKyspbys9dFtlXSp0W2VdO3JldHVybiBNYXRoLnNxcnQoby9zKX1zdGF0aWMgZ2V0QXVkaW9QZWFrKHQsZT0wLHM9LTEpe2lmKHM8MCYmKHM9dC5sZW5ndGgtZSksczw9MClyZXR1cm4gMDtjb25zdCBpPWUrcztsZXQgbz0wO2Zvcig7ZTxpO2UrKyl0W2VdPm8mJihvPXRbZV0pO3JldHVybiBvfXN0YXRpYyBjb252ZXJ0SW50MTZUb0Zsb2F0KHQsZSxzPTAsaT0tMSxvPTApe2k8MCYmKGk9dC5sZW5ndGgvMi1zKTtjb25zdCBhPU1hdGgubWluKHQubGVuZ3RoLzItcyxlLmxlbmd0aC1vKTtpZigoaT1NYXRoLm1pbihpLGEpKTw9MClyZXR1cm4gMDtsZXQgcj0yKnM7Y29uc3Qgbj1yKzIqaTtmb3IoO3I8bjspZVtvKytdPSh0W3IrK10rKHRbcisrXTw8OCkpLzMyNzY3O3JldHVybiBpfXN0YXRpYyBjb252ZXJ0RmxvYXRUb0ludDE2KHQsZSxzPTAsaT0tMSxvPTApe2k8MCYmKGk9dC5sZW5ndGgtcyk7Y29uc3QgYT1zK2k7Zm9yKDtzPGE7KWVbbysrXT1+figzMjc2Nyp0W3MrK10pfXN0YXRpYyBlbmVyZ3lUb0RiKHQpe3JldHVybiAxMCpNYXRoLmxvZyh0KS9lLkxPR18yX1BMVVNfTE9HXzV9c3RhdGljIGRiVG9FbmVyZ3kodCl7cmV0dXJuIE1hdGgucG93KDEwLHQvMTApfX1lLkxPR18yX1BMVVNfTE9HXzU9TWF0aC5sb2coMikrTWF0aC5sb2coNSk7Y2xhc3Mgc3tjb25zdHJ1Y3Rvcih0LGUscyxpKXt0aGlzLmlzU2VuZGluZz0hMSx0aGlzLnN0cmVhbVNhbXBsZVBvcz0wLHRoaXMuc2FtcGxlc1NlbnQ9MCx0aGlzLnV0dGVyYW5jZVNlcmlhbD0tMSx0aGlzLm9uU2VuZEF1ZGlvPSh0LGUscyk9Pnt9LHRoaXMub25WYWRTdGF0ZUNoYW5nZT10PT57fSx0aGlzLmlucHV0U2FtcGxlUmF0ZT0xNmUzLHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlPTE2ZTMsdGhpcy5oaXN0b3J5RnJhbWVzPTUsdGhpcy5mcmFtZU1pbGxpcz0zMCx0aGlzLmN1cnJlbnRGcmFtZU51bWJlcj0wLHRoaXMuZnJhbWVTYW1wbGVQb3M9MCx0aGlzLnN0cmVhbUZyYW1lUG9zPTAsdGhpcy53YXNTaWduYWxEZXRlY3RlZD0hMSx0aGlzLmlucHV0U2FtcGxlUmF0ZT10LHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlPWUsdGhpcy5mcmFtZU1pbGxpcz1zLHRoaXMuaGlzdG9yeUZyYW1lcz1pLHRoaXMuZnJhbWVTYW1wbGVzPX5+KHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKnRoaXMuZnJhbWVNaWxsaXMvMWUzKSx0aGlzLnNhbXBsZVJpbmdCdWZmZXI9bmV3IEZsb2F0MzJBcnJheSh0aGlzLmZyYW1lU2FtcGxlcyp0aGlzLmhpc3RvcnlGcmFtZXMpfXByb2Nlc3NBdWRpbyh0LHM9MCxpPS0xLG89ITEpe2lmKGk8MCYmKGk9dC5sZW5ndGgpLDA9PT1pKXJldHVybiB2b2lkKG8mJnRoaXMucHJvY2Vzc0VvcygpKTtsZXQgYT1zO2NvbnN0IHI9cytpO2Zvcig7YTxyOyl7Y29uc3Qgcz10aGlzLmN1cnJlbnRGcmFtZU51bWJlcip0aGlzLmZyYW1lU2FtcGxlcztpZih0aGlzLmlucHV0U2FtcGxlUmF0ZT09PXRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKXtjb25zdCBlPU1hdGgubWluKHItYSx0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKSxpPXRoaXMuZnJhbWVTYW1wbGVQb3MrZTtmb3IoO3RoaXMuZnJhbWVTYW1wbGVQb3M8aTspdGhpcy5zYW1wbGVSaW5nQnVmZmVyW3MrdGhpcy5mcmFtZVNhbXBsZVBvcysrXT10W2ErK119ZWxzZXtjb25zdCBpPTEqdGhpcy5pbnB1dFNhbXBsZVJhdGUvdGhpcy5pbnRlcm5hbFNhbXBsZVJhdGUsbz1NYXRoLm1pbihyLWEsTWF0aC5yb3VuZChpKih0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKSkpLG49TWF0aC5taW4oTWF0aC5yb3VuZCgoci1hKS9pKSx0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKTtuPjAmJmUuZG93bnNhbXBsZSh0LHRoaXMuc2FtcGxlUmluZ0J1ZmZlcixhLG8scyt0aGlzLmZyYW1lU2FtcGxlUG9zLG4pLGErPW8sdGhpcy5mcmFtZVNhbXBsZVBvcys9bn1jb25zdCBpPWE9PT1yJiZvO2lmKHRoaXMuZnJhbWVTYW1wbGVQb3M9PT10aGlzLmZyYW1lU2FtcGxlc3x8aSl7Y29uc3QgdD1pP3RoaXMuZnJhbWVTYW1wbGVQb3M6dGhpcy5mcmFtZVNhbXBsZXM7aWYodGhpcy5wcm9jZXNzRnJhbWUodGhpcy5zYW1wbGVSaW5nQnVmZmVyLHMsdCxpKSx0aGlzLmlzU2VuZGluZyl7aWYoMD09PXRoaXMuc2FtcGxlc1NlbnQpe2NvbnN0IHQ9TWF0aC5taW4odGhpcy5zdHJlYW1GcmFtZVBvcyx0aGlzLmhpc3RvcnlGcmFtZXMtMSk7bGV0IGU9KHRoaXMuY3VycmVudEZyYW1lTnVtYmVyK3RoaXMuaGlzdG9yeUZyYW1lcy10KSV0aGlzLmhpc3RvcnlGcmFtZXM7Zm9yKDtlIT09dGhpcy5jdXJyZW50RnJhbWVOdW1iZXI7KXRoaXMub25TZW5kQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLGUqdGhpcy5mcmFtZVNhbXBsZXMsdGhpcy5mcmFtZVNhbXBsZXMpLHRoaXMuc2FtcGxlc1NlbnQrPXRoaXMuZnJhbWVTYW1wbGVzLGU9KGUrMSkldGhpcy5oaXN0b3J5RnJhbWVzfXRoaXMub25TZW5kQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLHMsdCksdGhpcy5zYW1wbGVzU2VudCs9dH1pPyh0aGlzLnN0cmVhbVNhbXBsZVBvcys9dCx0aGlzLnByb2Nlc3NFb3MoKSk6dGhpcy5mcmFtZVNhbXBsZVBvcz09PXRoaXMuZnJhbWVTYW1wbGVzJiYodGhpcy5mcmFtZVNhbXBsZVBvcz0wLHRoaXMuc3RyZWFtRnJhbWVQb3MrPTEsdGhpcy5zdHJlYW1TYW1wbGVQb3MrPXQsdGhpcy5jdXJyZW50RnJhbWVOdW1iZXI9KHRoaXMuY3VycmVudEZyYW1lTnVtYmVyKzEpJXRoaXMuaGlzdG9yeUZyYW1lcyl9dGhpcy52YWQmJih0aGlzLndhc1NpZ25hbERldGVjdGVkPXRoaXMudmFkLmlzU2lnbmFsRGV0ZWN0ZWQpfX1zZXRTZW5kQXVkaW8odCl7dGhpcy5pc1NlbmRpbmc9dCx0JiYodGhpcy5zYW1wbGVzU2VudD0wLHRoaXMudXR0ZXJhbmNlU2VyaWFsKyspfXJlc2V0KHQpe3ZhciBlO3RoaXMuaXNTZW5kaW5nPSExLHRoaXMuc3RyZWFtRnJhbWVQb3M9MCx0aGlzLnN0cmVhbVNhbXBsZVBvcz0wLHRoaXMuZnJhbWVTYW1wbGVQb3M9MCx0aGlzLmN1cnJlbnRGcmFtZU51bWJlcj0wLHRoaXMudXR0ZXJhbmNlU2VyaWFsPS0xLHQmJih0aGlzLmlucHV0U2FtcGxlUmF0ZT10KSx0aGlzLndhc1NpZ25hbERldGVjdGVkPSExLG51bGw9PT0oZT10aGlzLnZhZCl8fHZvaWQgMD09PWV8fGUucmVzZXRWQUQoKX1nZXRTdHJlYW1Qb3NpdGlvbigpe3JldHVybiBNYXRoLnJvdW5kKHRoaXMuc3RyZWFtU2FtcGxlUG9zL3RoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKjFlMyl9ZW9zKCl7dGhpcy5wcm9jZXNzQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLDAsdGhpcy5mcmFtZVNhbXBsZVBvcywhMCl9cHJvY2Vzc0ZyYW1lKHQsZT0wLHM9LTEsaT0hMSl7dmFyIG87KG51bGw9PT0obz10aGlzLnZhZCl8fHZvaWQgMD09PW8/dm9pZCAwOm8udmFkT3B0aW9ucy5lbmFibGVkKSYmKHRoaXMudmFkLnByb2Nlc3NGcmFtZSh0LGUscyxpKSx0aGlzLnZhZC5pc1NpZ25hbERldGVjdGVkIT09dGhpcy53YXNTaWduYWxEZXRlY3RlZCYmdGhpcy5vblZhZFN0YXRlQ2hhbmdlKHRoaXMudmFkLmlzU2lnbmFsRGV0ZWN0ZWQpKX1wcm9jZXNzRW9zKCl7dmFyIHQ7dGhpcy5pc1NlbmRpbmcmJihudWxsPT09KHQ9dGhpcy52YWQpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LnZhZE9wdGlvbnMuZW5hYmxlZCkmJih0aGlzLnZhZC5yZXNldFZBRCgpLHRoaXMub25WYWRTdGF0ZUNoYW5nZSghMSkpfX1jbGFzcyBpe2NvbnN0cnVjdG9yKHQsZSl7dGhpcy5pc1NpZ25hbERldGVjdGVkPSExLHRoaXMuc2lnbmFsRGI9LTkwLHRoaXMubm9pc2VMZXZlbERiPS05MCx0aGlzLmZyYW1lTWlsbGlzPTMwLHRoaXMuZW5lcmd5PTAsdGhpcy5iYXNlbGluZUVuZXJneT0tMSx0aGlzLmxvdWRGcmFtZUJpdHM9MCx0aGlzLnZhZFN1c3RhaW5NaWxsaXNMZWZ0PTAsdGhpcy5mcmFtZU1pbGxpcz10LHRoaXMudmFkT3B0aW9ucz1lfWFkanVzdFZhZE9wdGlvbnModCl7dGhpcy52YWRPcHRpb25zPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSx0aGlzLnZhZE9wdGlvbnMpLHQpfXJlc2V0VkFEKCl7dGhpcy5pc1NpZ25hbERldGVjdGVkPSExLHRoaXMubG91ZEZyYW1lQml0cz0wLHRoaXMuZW5lcmd5PTAsdGhpcy5iYXNlbGluZUVuZXJneT0tMX1wcm9jZXNzRnJhbWUodCxzPTAsaT0tMSxvPSExKXtpZighdGhpcy52YWRPcHRpb25zLmVuYWJsZWQpcmV0dXJuIHZvaWQgdGhpcy5yZXNldFZBRCgpO2lmKG8pcmV0dXJuO3RoaXMuZW5lcmd5PWUuZ2V0RW5lcmd5KHQscyxpKSx0aGlzLmJhc2VsaW5lRW5lcmd5PDAmJih0aGlzLmJhc2VsaW5lRW5lcmd5PXRoaXMuZW5lcmd5KTtjb25zdCBhPXRoaXMuZW5lcmd5Pk1hdGgubWF4KGUuZGJUb0VuZXJneSh0aGlzLnZhZE9wdGlvbnMubm9pc2VHYXRlRGIpLHRoaXMuYmFzZWxpbmVFbmVyZ3kqZS5kYlRvRW5lcmd5KHRoaXMudmFkT3B0aW9ucy5zaWduYWxUb05vaXNlRGIpKTt0aGlzLnB1c2hGcmFtZUhpc3RvcnkoYSksdGhpcy5pc1NpZ25hbERldGVjdGVkPXRoaXMuZGV0ZXJtaW5lTmV3U2lnbmFsU3RhdGUodGhpcy5pc1NpZ25hbERldGVjdGVkKSx0aGlzLmFkYXB0QmFja2dyb3VuZE5vaXNlKCksdGhpcy5zaWduYWxEYj1lLmVuZXJneVRvRGIodGhpcy5lbmVyZ3kvdGhpcy5iYXNlbGluZUVuZXJneSksdGhpcy5ub2lzZUxldmVsRGI9ZS5lbmVyZ3lUb0RiKHRoaXMuYmFzZWxpbmVFbmVyZ3kpfWRldGVybWluZU5ld1NpZ25hbFN0YXRlKHQpe3RoaXMudmFkU3VzdGFpbk1pbGxpc0xlZnQ9TWF0aC5tYXgodGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdC10aGlzLmZyYW1lTWlsbGlzLDApO2NvbnN0IGU9dGhpcy5jb3VudExvdWRGcmFtZXModGhpcy52YWRPcHRpb25zLnNpZ25hbFNlYXJjaEZyYW1lcykscz1NYXRoLnJvdW5kKHRoaXMudmFkT3B0aW9ucy5zaWduYWxBY3RpdmF0aW9uKnRoaXMudmFkT3B0aW9ucy5zaWduYWxTZWFyY2hGcmFtZXMpLGk9TWF0aC5yb3VuZCh0aGlzLnZhZE9wdGlvbnMuc2lnbmFsUmVsZWFzZSp0aGlzLnZhZE9wdGlvbnMuc2lnbmFsU2VhcmNoRnJhbWVzKTtyZXR1cm4gZT49cz8odGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdD10aGlzLnZhZE9wdGlvbnMuc2lnbmFsU3VzdGFpbk1pbGxpcywhMCk6IShlPD1pJiYwPT09dGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdCkmJnR9YWRhcHRCYWNrZ3JvdW5kTm9pc2UoKXtpZighdGhpcy5pc1NpZ25hbERldGVjdGVkJiZ0aGlzLnZhZE9wdGlvbnMubm9pc2VMZWFybkhhbGZ0aW1lTWlsbGlzPjApe3ZhciB0PU1hdGgucG93KDIsLXRoaXMuZnJhbWVNaWxsaXMvdGhpcy52YWRPcHRpb25zLm5vaXNlTGVhcm5IYWxmdGltZU1pbGxpcyk7dGhpcy5iYXNlbGluZUVuZXJneT10aGlzLmJhc2VsaW5lRW5lcmd5KnQrdGhpcy5lbmVyZ3kqKDEtdCl9fXB1c2hGcmFtZUhpc3RvcnkodCl7dGhpcy5sb3VkRnJhbWVCaXRzPSh0PzE6MCl8dGhpcy5sb3VkRnJhbWVCaXRzPDwxfWNvdW50TG91ZEZyYW1lcyh0KXtsZXQgZT0wLHM9dGhpcy5sb3VkRnJhbWVCaXRzO2Zvcig7dD4wOykxPT0oMSZzKSYmZSsrLHM+Pj0xLHQtLTtyZXR1cm4gZX19dmFyIG8sYSxyOyFmdW5jdGlvbih0KXt0LlN0YXJ0ZWQ9InN0YXJ0ZWQiLHQuU3RvcHBlZD0ic3RvcHBlZCIsdC5TZWdtZW50RW5kPSJzZWdtZW50X2VuZCIsdC5UcmFuc2NyaXB0PSJ0cmFuc2NyaXB0Iix0LkVudGl0eT0iZW50aXR5Iix0LkludGVudD0iaW50ZW50Iix0LlRlbnRhdGl2ZVRyYW5zY3JpcHQ9InRlbnRhdGl2ZV90cmFuc2NyaXB0Iix0LlRlbnRhdGl2ZUVudGl0aWVzPSJ0ZW50YXRpdmVfZW50aXRpZXMiLHQuVGVudGF0aXZlSW50ZW50PSJ0ZW50YXRpdmVfaW50ZW50In0ob3x8KG89e30pKSxmdW5jdGlvbih0KXt0Lk9wZW5lZD0iV0VCU09DS0VUX09QRU4iLHQuQ2xvc2VkPSJXRUJTT0NLRVRfQ0xPU0VEIix0LkF1ZGlvUHJvY2Vzc29yUmVhZHk9IlNPVVJDRV9TQU1QTEVfUkFURV9TRVRfU1VDQ0VTUyIsdC5WYWRTaWduYWxIaWdoPSJWYWRTaWduYWxIaWdoIix0LlZhZFNpZ25hbExvdz0iVmFkU2lnbmFsTG93Iix0LlJlcXVlc3RDb250ZXh0U3RhcnQ9IlJlcXVlc3RDb250ZXh0U3RhcnQifShhfHwoYT17fSkpLGZ1bmN0aW9uKHQpe3QuY29ubmVjdD0iY29ubmVjdCIsdC5pbml0QXVkaW9Qcm9jZXNzb3I9ImluaXRBdWRpb1Byb2Nlc3NvciIsdC5hZGp1c3RBdWRpb1Byb2Nlc3Nvcj0iYWRqdXN0QXVkaW9Qcm9jZXNzb3IiLHQuU0VUX1NIQVJFRF9BUlJBWV9CVUZGRVJTPSJTRVRfU0hBUkVEX0FSUkFZX0JVRkZFUlMiLHQuQ0xPU0U9IkNMT1NFIix0LlNUQVJUX0NPTlRFWFQ9IlNUQVJUX0NPTlRFWFQiLHQuU1dJVENIX0NPTlRFWFQ9IlNXSVRDSF9DT05URVhUIix0LlNUT1BfQ09OVEVYVD0iU1RPUF9DT05URVhUIix0LkFVRElPPSJBVURJTyIsdC5zdGFydFN0cmVhbT0ic3RhcnRTdHJlYW0iLHQuc3RvcFN0cmVhbT0ic3RvcFN0cmVhbSIsdC5zZXRDb250ZXh0T3B0aW9ucz0ic2V0Q29udGV4dE9wdGlvbnMifShyfHwocj17fSkpO2NvbnN0IG49MCxoPTEsZD0yO2NsYXNzIGx7Y29uc3RydWN0b3IodCl7dGhpcy50YXJnZXRTYW1wbGVSYXRlPTE2ZTMsdGhpcy5pc0NvbnRleHRTdGFydGVkPSExLHRoaXMuYXVkaW9Db250ZXh0U3RhcnRUaW1lcz1bXSx0aGlzLmltbWVkaWF0ZU1vZGU9ITEsdGhpcy5mcmFtZU1pbGxpcz0zMCx0aGlzLm91dHB1dEF1ZGlvRnJhbWU9bmV3IEludDE2QXJyYXkodGhpcy5mcmFtZU1pbGxpcyp0aGlzLnRhcmdldFNhbXBsZVJhdGUvMWUzKSx0aGlzLmRlYnVnPSExLHRoaXMub25XZWJzb2NrZXRDbG9zZT10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwib25XZWJzb2NrZXRDbG9zZSIpLHRoaXMuY2xvc2VXZWJzb2NrZXQodC5jb2RlLHQucmVhc29uLHQud2FzQ2xlYW4sITEpfSx0aGlzLm9uV2Vic29ja2V0T3Blbj10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwid2Vic29ja2V0IG9wZW5lZCIpLHRoaXMud29ya2VyQ3R4LnBvc3RNZXNzYWdlKHt0eXBlOmEuT3BlbmVkfSl9LHRoaXMub25XZWJzb2NrZXRFcnJvcj10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwid2Vic29ja2V0IGVycm9yIil9LHRoaXMub25XZWJzb2NrZXRNZXNzYWdlPXQ9PntsZXQgZTt0cnl7ZT1KU09OLnBhcnNlKHQuZGF0YSl9Y2F0Y2godCl7cmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJlcnJvciBwYXJzaW5nIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlcjoiLHQpfWlmKGUudHlwZT09PW8uU3RhcnRlZCl7bGV0IHQ9dGhpcy5hdWRpb0NvbnRleHRTdGFydFRpbWVzLnNoaWZ0KCk7dm9pZCAwPT09dCYmKGNvbnNvbGUud2FybigiTm8gdmFsaWQgdmFsdWUgZm9yIGNvbnRleHRTdGFydE1pbGxpcyIpLHQ9MCk7Y29uc3Qgcz17YXVkaW9TdGFydFRpbWVNaWxsaXM6dH07ZS5wYXJhbXM9c310aGlzLndvcmtlckN0eC5wb3N0TWVzc2FnZShlKX0sdGhpcy53b3JrZXJDdHg9dH1jb25uZWN0KHQsZSxzLGkpe3RoaXMuZGVidWc9aSx0aGlzLmRlYnVnJiZjb25zb2xlLmxvZygiW1dlYlNvY2tldENsaWVudF0iLCJjb25uZWN0aW5nIHRvICIsdCksdGhpcy50YXJnZXRTYW1wbGVSYXRlPXMsdGhpcy5pc0NvbnRleHRTdGFydGVkPSExLHRoaXMud2Vic29ja2V0PW5ldyBXZWJTb2NrZXQodCxlKSx0aGlzLndlYnNvY2tldC5hZGRFdmVudExpc3RlbmVyKCJvcGVuIix0aGlzLm9uV2Vic29ja2V0T3BlbiksdGhpcy53ZWJzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsdGhpcy5vbldlYnNvY2tldE1lc3NhZ2UpLHRoaXMud2Vic29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIix0aGlzLm9uV2Vic29ja2V0RXJyb3IpLHRoaXMud2Vic29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoImNsb3NlIix0aGlzLm9uV2Vic29ja2V0Q2xvc2UpfWluaXRBdWRpb1Byb2Nlc3Nvcih0LG8scixuKXt0aGlzLmF1ZGlvUHJvY2Vzc29yPW5ldyBzKHQsdGhpcy50YXJnZXRTYW1wbGVSYXRlLG8sciksbiYmKHRoaXMuYXVkaW9Qcm9jZXNzb3IudmFkPW5ldyBpKG8sbiksdGhpcy5hdWRpb1Byb2Nlc3Nvci5vblZhZFN0YXRlQ2hhbmdlPXQ9Pnt2YXIgZSxzO2NvbnN0IGk9bnVsbD09PShzPW51bGw9PT0oZT10aGlzLmF1ZGlvUHJvY2Vzc29yKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS52YWQpfHx2b2lkIDA9PT1zP3ZvaWQgMDpzLnZhZE9wdGlvbnM7aSYmKHQmJih0aGlzLmltbWVkaWF0ZU1vZGU/aS5jb250cm9sTGlzdGVuaW5nJiZ0aGlzLnN0YXJ0Q29udGV4dCh0aGlzLmRlZmF1bHRDb250ZXh0T3B0aW9ucyk6dGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5WYWRTaWduYWxIaWdofSkpLHR8fCh0aGlzLmltbWVkaWF0ZU1vZGU/aS5jb250cm9sTGlzdGVuaW5nJiZ0aGlzLnN0b3BDb250ZXh0KCk6dGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5WYWRTaWduYWxMb3d9KSkpfSksdGhpcy5hdWRpb1Byb2Nlc3Nvci5vblNlbmRBdWRpbz0odCxzLGkpPT57ZS5jb252ZXJ0RmxvYXRUb0ludDE2KHQsdGhpcy5vdXRwdXRBdWRpb0ZyYW1lLHMsaSksdGhpcy5zZW5kKHRoaXMub3V0cHV0QXVkaW9GcmFtZSl9LHZvaWQgMCE9PXRoaXMud29ya2VyQ3R4JiZ0aGlzLndvcmtlckN0eC5wb3N0TWVzc2FnZSh7dHlwZTphLkF1ZGlvUHJvY2Vzc29yUmVhZHl9KX1hZGp1c3RBdWRpb1Byb2Nlc3Nvcih0KXtpZih0aGlzLmF1ZGlvUHJvY2Vzc29yJiZ0LnZhZCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IudmFkKXRocm93IG5ldyBFcnJvcigiTm8gVkFEIGluIEF1ZGlvUHJvY2Vzc29yLiBEaWQgeW91IGRlZmluZSBgdmFkYCBpbiBCcm93c2VyQ2xpZW50IGNvbnN0cnVjdG9yIHBhcmFtZXRlcnM/Iik7dGhpcy5hdWRpb1Byb2Nlc3Nvci52YWQuYWRqdXN0VmFkT3B0aW9ucyh0LnZhZCl9fXNldFNoYXJlZEFycmF5QnVmZmVycyh0LGUpe3RoaXMuY29udHJvbFNBQj1uZXcgSW50MzJBcnJheSh0KSx0aGlzLmRhdGFTQUI9bmV3IEZsb2F0MzJBcnJheShlKTtjb25zdCBzPXRoaXMuZGF0YVNBQi5sZW5ndGgvMzI7dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwiQXVkaW8gaGFuZGxlIGludGVydmFsIixzLCJtcyIpLHNldEludGVydmFsKHRoaXMucHJvY2Vzc0F1ZGlvU0FCLmJpbmQodGhpcykscyl9c3RhcnRTdHJlYW0odCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgbmV3IEVycm9yKCJObyBBdWRpb1Byb2Nlc3NvciIpO3RoaXMuaW1tZWRpYXRlTW9kZT10LmltbWVkaWF0ZSx0aGlzLmF1ZGlvUHJvY2Vzc29yLnJlc2V0KHQuc2FtcGxlUmF0ZSksdGhpcy5hdWRpb0NvbnRleHRTdGFydFRpbWVzPVtdfXN0b3BTdHJlYW0oKXtpZighdGhpcy5hdWRpb1Byb2Nlc3Nvcil0aHJvdyBuZXcgRXJyb3IoIk5vIEF1ZGlvUHJvY2Vzc29yIik7dGhpcy5hdWRpb1Byb2Nlc3Nvci5lb3MoKX1wcm9jZXNzQXVkaW8odCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgbmV3IEVycm9yKCJObyBBdWRpb1Byb2Nlc3NvciIpO3RoaXMuYXVkaW9Qcm9jZXNzb3IucHJvY2Vzc0F1ZGlvKHQpfXByb2Nlc3NBdWRpb1NBQigpe2lmKCF0aGlzLmNvbnRyb2xTQUJ8fCF0aGlzLmRhdGFTQUIpdGhyb3cgbmV3IEVycm9yKCJObyBTaGFyZWRBcnJheUJ1ZmZlcnMiKTtjb25zdCB0PXRoaXMuY29udHJvbFNBQltoXTtpZigwPT09dGhpcy5jb250cm9sU0FCW2RdJiZ0PjApe2NvbnN0IGU9dGhpcy5kYXRhU0FCLnN1YmFycmF5KDAsdCk7dGhpcy5jb250cm9sU0FCW2hdPTAsdGhpcy5jb250cm9sU0FCW25dPTAsZS5sZW5ndGg+MCYmdGhpcy5wcm9jZXNzQXVkaW8oZSl9fXN0YXJ0Q29udGV4dCh0KXt2YXIgZTtpZighdGhpcy5hdWRpb1Byb2Nlc3Nvcil0aHJvdyBFcnJvcigiTm8gQXVkaW9Qcm9jZXNzb3IiKTtpZih0aGlzLmlzQ29udGV4dFN0YXJ0ZWQpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzdGFydCBjb250ZXh0OiBhY3RpdmUgY29udGV4dCBleGlzdHMiKTt0aGlzLmF1ZGlvUHJvY2Vzc29yLnNldFNlbmRBdWRpbyghMCksdGhpcy5pc0NvbnRleHRTdGFydGVkPSEwLHRoaXMuYXVkaW9Db250ZXh0U3RhcnRUaW1lcy5wdXNoKHRoaXMuYXVkaW9Qcm9jZXNzb3IuZ2V0U3RyZWFtUG9zaXRpb24oKSksdGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5SZXF1ZXN0Q29udGV4dFN0YXJ0fSk7bGV0IHM9bnVsbCE9PShlPXRoaXMuZGVmYXVsdENvbnRleHRPcHRpb25zKSYmdm9pZCAwIT09ZT9lOnt9O3ZvaWQgMCE9PXQmJihzPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KSk7Y29uc3QgaT11KHMpO2kuZXZlbnQ9InN0YXJ0Iix0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoaSkpfXN0b3BDb250ZXh0KCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgRXJyb3IoIk5vIEF1ZGlvUHJvY2Vzc29yIik7aWYoIXRoaXMuaXNDb250ZXh0U3RhcnRlZClyZXR1cm4gdm9pZCBjb25zb2xlLmVycm9yKCJbV2ViU29ja2V0Q2xpZW50XSIsImNhbid0IHN0b3AgY29udGV4dDogbm8gYWN0aXZlIGNvbnRleHQiKTt0aGlzLmF1ZGlvUHJvY2Vzc29yLnNldFNlbmRBdWRpbyghMSksdGhpcy5pc0NvbnRleHRTdGFydGVkPSExO2NvbnN0IHQ9SlNPTi5zdHJpbmdpZnkoe2V2ZW50OiJzdG9wIn0pO3RoaXMuc2VuZCh0KX1zd2l0Y2hDb250ZXh0KHQpe2lmKCF0aGlzLndlYnNvY2tldCl0aHJvdyBFcnJvcigiV2ViU29ja2V0IGlzIHVuZGVmaW5lZCIpO2lmKCF0aGlzLmlzQ29udGV4dFN0YXJ0ZWQpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzd2l0Y2ggY29udGV4dDogbm8gYWN0aXZlIGNvbnRleHQiKTtpZih2b2lkIDA9PT0obnVsbD09dD92b2lkIDA6dC5hcHBJZCkpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzd2l0Y2ggY29udGV4dDogbmV3IGFwcCBpZCBpcyB1bmRlZmluZWQiKTtjb25zdCBlPUpTT04uc3RyaW5naWZ5KHtldmVudDoic3RvcCJ9KTt0aGlzLnNlbmQoZSk7Y29uc3Qgcz11KHQpO3MuZXZlbnQ9InN0YXJ0Iix0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkocykpfWNsb3NlV2Vic29ja2V0KHQ9MTAwNSxlPSJObyBTdGF0dXMgUmVjZWl2ZWQiLHM9ITAsaT0hMCl7dmFyIG87dGhpcy53ZWJzb2NrZXQ/KHRoaXMuZGVidWcmJmNvbnNvbGUubG9nKCJbV2ViU29ja2V0Q2xpZW50XSIsaT8iV2Vic29ja2V0IGNsb3NlIHJlcXVlc3RlZCI6IldlYnNvY2tldCBjbG9zZWQiKSxudWxsPT09KG89dGhpcy5hdWRpb1Byb2Nlc3Nvcil8fHZvaWQgMD09PW98fG8ucmVzZXQoKSx0aGlzLndlYnNvY2tldC5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIix0aGlzLm9uV2Vic29ja2V0T3BlbiksdGhpcy53ZWJzb2NrZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsdGhpcy5vbldlYnNvY2tldE1lc3NhZ2UpLHRoaXMud2Vic29ja2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIix0aGlzLm9uV2Vic29ja2V0RXJyb3IpLHRoaXMud2Vic29ja2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsb3NlIix0aGlzLm9uV2Vic29ja2V0Q2xvc2UpLGkmJnRoaXMud2Vic29ja2V0LmNsb3NlKHQsZSksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwLHRoaXMud29ya2VyQ3R4LnBvc3RNZXNzYWdlKHt0eXBlOmEuQ2xvc2VkLGNvZGU6dCxyZWFzb246ZSx3YXNDbGVhbjpzfSkpOmNvbnNvbGUud2FybigiV2ViU29ja2V0IGFscmVhZHkgY2xvc2VkIil9c2VuZCh0KXtpZighdGhpcy53ZWJzb2NrZXQpdGhyb3cgbmV3IEVycm9yKCJObyBXZWJzb2NrZXQiKTtpZih0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09dGhpcy53ZWJzb2NrZXQuT1BFTil0cnl7dGhpcy53ZWJzb2NrZXQuc2VuZCh0KX1jYXRjaCh0KXtjb25zb2xlLmxvZygiW1dlYlNvY2tldENsaWVudF0iLCJzZXJ2ZXIgY29ubmVjdGlvbiBlcnJvciIsdCl9ZWxzZSBjb25zb2xlLndhcm4oYEV4cGVjdGVkIE9QRU4gV2Vic29ja2V0IHN0YXRlLCBidXQgZ290ICR7dGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZX1gKX1zZXRDb250ZXh0T3B0aW9ucyh0KXt0aGlzLmRlZmF1bHRDb250ZXh0T3B0aW9ucz10fX1jb25zdCBjPXNlbGYsbT1uZXcgbChjKTtmdW5jdGlvbiB1KHQpe2NvbnN0IGU9e29wdGlvbnM6e3RpbWV6b25lOltJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmVdfX07cmV0dXJuIHZvaWQgMD09PXR8fChlLm9wdGlvbnMudm9jYWJ1bGFyeT10LnZvY2FidWxhcnksZS5vcHRpb25zLnZvY2FidWxhcnlfYmlhcz10LnZvY2FidWxhcnlCaWFzLGUub3B0aW9ucy5zaWxlbmNlX3RyaWdnZXJlZF9zZWdtZW50YXRpb249dC5zaWxlbmNlVHJpZ2dlcmVkU2VnbWVudGF0aW9uLHQubm9uU3RyZWFtaW5nTmx1P2Uub3B0aW9ucy5ub25fc3RyZWFtaW5nX25sdT1bInllcyJdOmUub3B0aW9ucy5ub25fc3RyZWFtaW5nX25sdT1bIm5vIl0sdm9pZCAwIT09KG51bGw9PXQ/dm9pZCAwOnQudGltZXpvbmUpJiYoZS5vcHRpb25zLnRpbWV6b25lPW51bGw9PXQ/dm9pZCAwOnQudGltZXpvbmUpLHZvaWQgMCE9PXQuYXBwSWQmJihlLmFwcElkPXQuYXBwSWQpKSxlfXJldHVybiBjLm9ubWVzc2FnZT1mdW5jdGlvbih0KXtzd2l0Y2godC5kYXRhLnR5cGUpe2Nhc2Ugci5jb25uZWN0Om0uY29ubmVjdCh0LmRhdGEuYXBpVXJsLHQuZGF0YS5hdXRoVG9rZW4sdC5kYXRhLnRhcmdldFNhbXBsZVJhdGUsdC5kYXRhLmRlYnVnKTticmVhaztjYXNlIHIuaW5pdEF1ZGlvUHJvY2Vzc29yOm0uaW5pdEF1ZGlvUHJvY2Vzc29yKHQuZGF0YS5zb3VyY2VTYW1wbGVSYXRlLHQuZGF0YS5mcmFtZU1pbGxpcyx0LmRhdGEuaGlzdG9yeUZyYW1lcyx0LmRhdGEudmFkT3B0aW9ucyk7YnJlYWs7Y2FzZSByLmFkanVzdEF1ZGlvUHJvY2Vzc29yOm0uYWRqdXN0QXVkaW9Qcm9jZXNzb3IodC5kYXRhLnBhcmFtcyk7YnJlYWs7Y2FzZSByLlNFVF9TSEFSRURfQVJSQVlfQlVGRkVSUzptLnNldFNoYXJlZEFycmF5QnVmZmVycyh0LmRhdGEuY29udHJvbFNBQix0LmRhdGEuZGF0YVNBQik7YnJlYWs7Y2FzZSByLkNMT1NFOm0uY2xvc2VXZWJzb2NrZXQoMWUzLCJDbG9zZSByZXF1ZXN0ZWQgYnkgY2xpZW50IiwhMCwhMCk7YnJlYWs7Y2FzZSByLnN0YXJ0U3RyZWFtOm0uc3RhcnRTdHJlYW0odC5kYXRhLnN0cmVhbU9wdGlvbnMpO2JyZWFrO2Nhc2Ugci5zdG9wU3RyZWFtOm0uc3RvcFN0cmVhbSgpO2JyZWFrO2Nhc2Ugci5TVEFSVF9DT05URVhUOm0uc3RhcnRDb250ZXh0KHQuZGF0YS5vcHRpb25zKTticmVhaztjYXNlIHIuU1dJVENIX0NPTlRFWFQ6bS5zd2l0Y2hDb250ZXh0KHQuZGF0YS5vcHRpb25zKTticmVhaztjYXNlIHIuU1RPUF9DT05URVhUOm0uc3RvcENvbnRleHQoKTticmVhaztjYXNlIHIuQVVESU86bS5wcm9jZXNzQXVkaW8odC5kYXRhLnBheWxvYWQpO2JyZWFrO2Nhc2Ugci5zZXRDb250ZXh0T3B0aW9uczptLnNldENvbnRleHRPcHRpb25zKHQuZGF0YS5vcHRpb25zKTticmVhaztkZWZhdWx0OmNvbnNvbGUubG9nKCJXT1JLRVIiLHQpfX0sdC5jb250ZXh0T3B0aW9uc1RvTXNnPXUsdC5kZWZhdWx0PWwsT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHR9KHt9KTsKCg==",this.worker.addEventListener("message",this.onWebsocketMessage)}onResponse(t){this.onResponseCb=t}onClose(t){this.onCloseCb=t}initialize(e,i,s,n){return a(this,void 0,void 0,(function*(){return this.worker.postMessage({type:t.ControllerSignal.connect,apiUrl:e,authToken:i,targetSampleRate:s,debug:n}),this.startCbs=[],this.stopCbs=[],new Promise(((t,e)=>{this.onInitResolve=()=>{this.onInitResolve=void 0,this.onInitReject=void 0,t()},this.onInitReject=t=>{this.onInitResolve=void 0,this.onInitReject=void 0,e(t)}}))}))}initAudioProcessor(e,i,s,n){return a(this,void 0,void 0,(function*(){return this.worker.postMessage({type:t.ControllerSignal.initAudioProcessor,sourceSampleRate:e,frameMillis:i,historyFrames:s,vadOptions:n}),new Promise((t=>{this.resolveSourceSampleRateSet=t}))}))}adjustAudioProcessor(e){this.worker.postMessage({type:t.ControllerSignal.adjustAudioProcessor,params:e})}close(){return a(this,void 0,void 0,(function*(){return new Promise(((e,i)=>{this.worker.postMessage({type:t.ControllerSignal.CLOSE,code:1e3,message:"Client has ended the session"}),e()}))}))}startStream(e){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.startStream,streamOptions:e})}))}stopStream(){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.stopStream})}))}startContext(e){return a(this,void 0,void 0,(function*(){return new Promise(((i,s)=>{this.startCbs.push(((t,e)=>{void 0!==t?s(t):i(e)})),this.worker.postMessage({type:t.ControllerSignal.START_CONTEXT,options:e})}))}))}stopContext(){return a(this,void 0,void 0,(function*(){return new Promise(((e,i)=>{this.stopCbs.push(((t,s)=>{void 0!==t?i(t):e(s)})),this.worker.postMessage({type:t.ControllerSignal.STOP_CONTEXT})}))}))}switchContext(e){return a(this,void 0,void 0,(function*(){return new Promise(((i,s)=>{this.startCbs.push(((t,e)=>{void 0!==t?s(t):i(e)})),this.worker.postMessage({type:t.ControllerSignal.SWITCH_CONTEXT,options:e})}))}))}postMessage(t){this.worker.postMessage(t)}sendAudio(e){this.worker.postMessage({type:t.ControllerSignal.AUDIO,payload:e})}setContextOptions(e){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.setContextOptions,options:e})}))}}class E{constructor(){this.storage=window.localStorage}get(t){return this.storage.getItem(t)}set(t,e){this.storage.setItem(t,e)}getOrSet(t,e){let i=this.storage.getItem(t);return null===i&&(i=e(),this.storage.setItem(t,i)),i}}function M(t,e){return{intent:t.intent,isFinal:e}}const J="speechly-auth-token";class U{constructor(e){var i,s;if(this.streamOptions=G,this.activeContexts=0,this.audioContexts=new Map,this.maxReconnectAttemptCount=10,this.connectAttempt=0,this.connectPromise=null,this.cbs=[],this.state=t.DecoderState.Disconnected,this.handleWebsocketResponse=e=>{var i;switch(this.debug&&console.log("[Decoder]","Received response",e),e.type){case t.WorkerSignal.VadSignalHigh:this.cbs.forEach((t=>t.onVadStateChange.forEach((t=>t(!0)))));break;case t.WorkerSignal.VadSignalLow:this.cbs.forEach((t=>t.onVadStateChange.forEach((t=>t(!1)))));break;case t.WorkerSignal.RequestContextStart:this.activeContexts++;break;case t.WebsocketResponseType.Started:{const t=e.params;this.audioContexts.set(e.audio_context,{segments:new Map,audioStartTimeMillis:null!==(i=null==t?void 0:t.audioStartTimeMillis)&&void 0!==i?i:0}),this.cbs.forEach((t=>t.contextStartedCbs.forEach((t=>t(e.audio_context)))));break}case t.WebsocketResponseType.Stopped:this.activeContexts--,this.cbs.forEach((t=>t.contextStoppedCbs.forEach((t=>t(e.audio_context))))),this.streamOptions.preserveSegments||this.audioContexts.delete(e.audio_context),void 0!==this.resolveStopStream&&0===this.activeContexts&&this.resolveStopStream();break;default:this.handleSegmentUpdate(e)}},this.handleSegmentUpdate=e=>{var i;const{audio_context:s,segment_id:n,type:a}=e;let{data:d}=e;const c=this.audioContexts.get(s);if(void 0===c)return void console.warn("[Decoder]","Received response for non-existent context",s);let l=null!==(i=c.segments.get(n))&&void 0!==i?i:new o(s,n);switch(a){case t.WebsocketResponseType.TentativeTranscript:const e=function(t,e){return t.words.map((({word:t,index:i,start_timestamp:s,end_timestamp:n})=>({value:t,index:i,startTimestamp:s+e,endTimestamp:n+e,isFinal:!1})))}(d,c.audioStartTimeMillis),i=d.transcript;this.cbs.forEach((t=>t.tentativeTranscriptCbs.forEach((t=>t(s,n,e,i))))),l=l.updateTranscript(e);break;case t.WebsocketResponseType.Transcript:const o=function(t,e){return{value:t.word,index:t.index,startTimestamp:t.start_timestamp+e,endTimestamp:t.end_timestamp+e,isFinal:!0}}(d,c.audioStartTimeMillis);this.cbs.forEach((t=>t.transcriptCbs.forEach((t=>t(s,n,o))))),l=l.updateTranscript([o]);break;case t.WebsocketResponseType.TentativeEntities:const a=function(t){return t.entities.map((({entity:t,value:e,start_position:i,end_position:s})=>({type:t,value:e,startPosition:i,endPosition:s,isFinal:!1})))}(d);this.cbs.forEach((t=>t.tentativeEntityCbs.forEach((t=>t(s,n,a))))),l=l.updateEntities(a);break;case t.WebsocketResponseType.Entity:const r=function(t){return{type:t.entity,value:t.value,startPosition:t.start_position,endPosition:t.end_position,isFinal:!0}}(d);this.cbs.forEach((t=>t.entityCbs.forEach((t=>t(s,n,r))))),l=l.updateEntities([r]);break;case t.WebsocketResponseType.TentativeIntent:const h=M(d,!1);this.cbs.forEach((t=>t.tentativeIntentCbs.forEach((t=>t(s,n,h))))),l=l.updateIntent(h);break;case t.WebsocketResponseType.Intent:const u=M(d,!0);this.cbs.forEach((t=>t.intentCbs.forEach((t=>t(s,n,u))))),l=l.updateIntent(u);break;case t.WebsocketResponseType.SegmentEnd:l=l.finalize()}c.segments.set(n,l),this.audioContexts.set(s,c),this.logSegments&&console.info(l.toString()),this.cbs.forEach((t=>t.segmentChangeCbs.forEach((t=>t(l.toSegment())))))},this.handleWebsocketClosure=e=>{if(1e3===e.code)this.debug&&console.log("[Decoder]","Websocket closed",e);else{if(console.error("[Decoder]","Websocket closed due to error",e),void 0===this.deviceId)return this.setState(t.DecoderState.Failed),void console.error("[Decoder]","No deviceId. Giving up reconnecting.");this.setState(t.DecoderState.Disconnected),this.activeContexts=0,this.audioContexts.clear(),this.reconnect()}},this.logSegments=e.logSegments,this.appId=e.appId,this.projectId=e.projectId,this.sampleRate=e.sampleRate,this.debug=e.debug,void 0!==this.appId&&void 0!==this.projectId)throw Error("[Decoder] You cannot use both appId and projectId at the same time");if(void 0===this.appId&&void 0===this.projectId)throw Error("[Decoder] Either an appId or a projectId is required");const n=e.apiUrl;this.apiUrl=function(t,e){const i=new URLSearchParams;return i.append("sampleRate",e.toString()),`${t}?${i.toString()}`}(n.replace("http","ws")+"/ws/v1",this.sampleRate),this.loginUrl=`${n}/login`;try{this.storage=null!==(i=e.storage)&&void 0!==i?i:new E,this.deviceId=this.storage.getOrSet("speechly-device-id",x)}catch(t){this.deviceId=x()}this.apiClient=new k,this.apiClient.onResponse(this.handleWebsocketResponse),this.apiClient.onClose(this.handleWebsocketClosure),(null===(s=e.connect)||void 0===s||s)&&this.connect()}getReconnectDelayMs(t){return 100*Math.pow(2,t)}sleep(t){return a(this,void 0,void 0,(function*(){return new Promise((e=>setTimeout(e,t)))}))}connect(){return a(this,void 0,void 0,(function*(){null===this.connectPromise&&(this.connectPromise=(()=>a(this,void 0,void 0,(function*(){var e;this.setState(t.DecoderState.Disconnected);const i=null===(e=this.storage)||void 0===e?void 0:e.get(J);if(i&&w(i,this.projectId,this.appId,this.deviceId))this.authToken=i;else try{this.authToken=yield function(t,e,i,s,n=fetch,o=Date.now){var d;return a(this,void 0,void 0,(function*(){let a;a=void 0!==e?{projectId:e,deviceId:s}:{appId:i,deviceId:s};const c=yield n(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),l=yield c.json();if(200!==c.status)throw Error(null!==(d=l.error)&&void 0!==d?d:`Speechly API login request failed with ${c.status}`);if(void 0===l.access_token)throw Error("Invalid login response from Speechly API");if(!w(l.access_token,e,i,s,o))throw Error("Invalid token received from Speechly API");return l.access_token}))}(this.loginUrl,this.projectId,this.appId,this.deviceId,fetch),this.storage&&this.storage.set(J,this.authToken)}catch(e){throw this.connectPromise=null,this.setState(t.DecoderState.Failed),e}try{yield this.apiClient.initialize(this.apiUrl,this.authToken,this.sampleRate,this.debug)}catch(e){throw this.connectPromise=null,e instanceof s&&1e3===e.code||this.setState(t.DecoderState.Failed),e}this.advanceState(t.DecoderState.Connected)})))()),yield this.connectPromise}))}adjustAudioProcessor(t){this.apiClient.adjustAudioProcessor(t)}close(){return a(this,void 0,void 0,(function*(){let e;try{yield this.apiClient.close()}catch(t){e=t.message}if(this.audioContexts.clear(),this.activeContexts=0,this.connectPromise=null,this.setState(t.DecoderState.Disconnected),void 0!==e)throw Error(e)}))}startStream(t){return a(this,void 0,void 0,(function*(){this.debug&&console.log("[Decoder]","startStream"),this.streamOptions=t,this.audioContexts.clear(),this.activeContexts=0,yield this.apiClient.startStream(t)}))}stopStream(){return a(this,void 0,void 0,(function*(){this.debug&&console.log("[Decoder]","stopStream"),yield this.apiClient.stopStream(),yield this.waitResults()}))}waitResults(){return a(this,void 0,void 0,(function*(){if(this.activeContexts>0){const t=new Promise((t=>{this.resolveStopStream=t}));yield t}this.resolveStopStream=void 0}))}startContext(e){return a(this,void 0,void 0,(function*(){if(this.state===t.DecoderState.Failed)throw Error("[Decoder] startContext cannot be run in Failed state.");if(this.state<t.DecoderState.Connected)yield this.connect();else if(this.state>t.DecoderState.Connected)throw Error("[Decoder] Unable to complete startContext: Expected Connected state, but was in "+V(this.state)+".");let s;if(this.setState(t.DecoderState.Active),null!=this.projectId){if(!(null==e?void 0:e.appId))throw new Error("options.appId is required with project login");s=yield this.apiClient.startContext(e)}else{if(null!=(null==e?void 0:e.appId)&&this.appId!==(null==e?void 0:e.appId))throw this.setState(t.DecoderState.Failed),i;s=yield this.apiClient.startContext(e)}if(this.state<t.DecoderState.Active)throw Error("[Decoder] Unable to complete startContext: Problem acquiring contextId");return s}))}sendAudio(t){this.apiClient.sendAudio(t)}stopContext(e){return a(this,void 0,void 0,(function*(){if(this.state===t.DecoderState.Failed)throw Error("[Decoder] stopContext cannot be run in unrecovable error state.");if(this.state!==t.DecoderState.Active)throw Error("[Decoder] Unable to complete stopContext: Expected Active state, but was in "+V(this.state)+".");e>0&&(yield this.sleep(e));const i=yield this.apiClient.stopContext();return this.setState(t.DecoderState.Connected),i}))}switchContext(e){return a(this,void 0,void 0,(function*(){if(this.state!==t.DecoderState.Active)throw Error("[Decoder] Unable to complete switchContext: Expected Active state, but was in "+V(this.state)+".");return yield this.apiClient.switchContext(e)}))}registerListener(t){this.cbs.push(t)}initAudioProcessor(t,e,i,s){return a(this,void 0,void 0,(function*(){yield this.apiClient.initAudioProcessor(t,e,i,s)}))}useSharedArrayBuffers(t,e){this.apiClient.postMessage({type:"SET_SHARED_ARRAY_BUFFERS",controlSAB:t,dataSAB:e})}setContextOptions(t){return a(this,void 0,void 0,(function*(){yield this.apiClient.setContextOptions(t)}))}reconnect(){return a(this,void 0,void 0,(function*(){console.log("Speechly reconnecting"),this.connectPromise=null,this.connectAttempt<this.maxReconnectAttemptCount?(yield this.sleep(this.getReconnectDelayMs(this.connectAttempt++)),yield this.connect()):console.error("[Decoder] Maximum reconnect count reached, giving up automatic reconnect.")}))}advanceState(t){this.state>=t||this.setState(t)}setState(t){this.state!==t&&(this.debug&&console.log("[Decoder]",V(this.state),"->",V(t)),this.state=t,this.cbs.forEach((e=>{var i;return null===(i=e.stateChangeCbs)||void 0===i?void 0:i.forEach((e=>e(t)))})))}getSegments(){const t=[];return this.audioContexts.forEach(((e,i)=>{e.segments.forEach(((e,i)=>{const s=JSON.parse(JSON.stringify(e));t.push(s)}))})),t}}t.BrowserClient=class{constructor(t){var e,i;this.contextStopDelay=250,this.debug=!1,this.initialized=!1,this.audioProcessorInitialized=!1,this.isStreaming=!1,this.active=!1,this.listeningPromise=null,this.streamOptions=Object.assign({},G),this.stats={maxSignalEnergy:0,sentSamples:0},this.decoderOptions=Object.assign(Object.assign(Object.assign({},Z),t),{vad:t.vad?Object.assign(Object.assign({},y),t.vad):void 0});const s=window.navigator.mediaDevices.getSupportedConstraints();this.nativeResamplingSupported=!0===s.sampleRate,this.isMobileSafari=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].indexOf(navigator.platform)>=0||navigator.userAgent.includes("Mac")&&"ontouchend"in document,this.isSafari=this.isMobileSafari||void 0!==window.safari,this.useSAB=!this.isSafari,this.debug=null===(e=this.decoderOptions.debug)||void 0===e||e,this.callbacks=new R,this.callbacks.stateChangeCbs.addEventListener(this.handleStateChange.bind(this)),this.callbacks.onVadStateChange.addEventListener(this.autoControlListening.bind(this)),this.decoder=null!==(i=this.decoderOptions.decoder)&&void 0!==i?i:new U(this.decoderOptions),this.decoder.registerListener(this.callbacks)}initialize(t){var i,o;return a(this,void 0,void 0,(function*(){if(!this.initialized){this.debug&&console.log("[BrowserClient]","initializing"),this.initialized=!0;try{yield this.decoder.connect()}catch(t){if(this.initialized=!1,t instanceof s){if(1e3===t.code)return void(this.debug&&console.log("[BrowserClient]","Early close of websocket."));throw Error(`Unable to connect. Most likely there is no connection to network. Websocket error code: ${t.code}`)}throw t}try{const t={};if(this.nativeResamplingSupported&&(t.sampleRate=n),void 0!==window.webkitAudioContext)try{this.audioContext=new window.webkitAudioContext(t)}catch(t){this.debug&&console.log("[BrowserClient]","creating audioContext without samplerate conversion",t),this.audioContext=new window.webkitAudioContext}else this.audioContext=new window.AudioContext(t),void 0!==window.webkitAudioContext&&(yield this.audioContext.resume())}catch(t){throw this.initialized=!1,e}if(this.isSafari||void 0===window.AudioWorkletNode){if(this.debug&&console.log("[BrowserClient]","using ScriptProcessorNode"),void 0!==window.webkitAudioContext){const t=this.audioContext.sampleRate/n,e=4096*Math.pow(2,Math.ceil(Math.log(t)/Math.log(2)));this.audioProcessor=this.audioContext.createScriptProcessor(e,1,1)}else this.audioProcessor=this.audioContext.createScriptProcessor(void 0,1,1);this.audioProcessor.connect(this.audioContext.destination),this.audioProcessor.addEventListener("audioprocess",(t=>{this.handleAudio(t.inputBuffer.getChannelData(0))}))}else{this.debug&&console.log("[BrowserClient]","using AudioWorkletNode");const t=new Blob(["\n// Indices for the Control SAB.\nconst CONTROL = {\n 'WRITE_INDEX': 0,\n 'FRAMES_AVAILABLE': 1,\n 'LOCK': 2,\n};\n\nclass SpeechlyProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n\n this._initialized = false;\n this.debug = false;\n this.port.onmessage = this._initialize.bind(this);\n }\n\n _initialize(event) {\n this.controlSAB = new Int32Array(event.data.controlSAB);\n this.dataSAB = new Float32Array(event.data.dataSAB);\n this.debug = event.data.debug;\n if (this.debug) {\n console.log('[BrowserClient AudioWorkletNode]', 'initializing audioworklet');\n }\n this.sharedBufferSize = this.dataSAB.length;\n this.buffer = new Float32Array(0);\n this._initialized = true;\n }\n\n _transferDataToSharedBuffer(data) {\n this.controlSAB[CONTROL.LOCK] = 1;\n let inputWriteIndex = this.controlSAB[CONTROL.WRITE_INDEX];\n if (this.controlSAB[CONTROL.FRAMES_AVAILABLE] > 0) {\n if (inputWriteIndex + data.length > this.sharedBufferSize) {\n // console.log('buffer overflow')\n inputWriteIndex = 0;\n }\n }\n this.dataSAB.set(data, inputWriteIndex);\n this.controlSAB[CONTROL.WRITE_INDEX] = inputWriteIndex + data.length;\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = inputWriteIndex + data.length;\n this.controlSAB[CONTROL.LOCK] = 0;\n }\n\n _pushData(data) {\n if (this.debug) {\n const signalEnergy = getStandardDeviation(data)\n this.port.postMessage({\n type: 'STATS',\n signalEnergy: signalEnergy,\n samples: data.length,\n });\n }\n\n if (this.buffer.length > this.sharedBufferSize) {\n const dataToTransfer = this.buffer.subarray(0, this.sharedBufferSize);\n this._transferDataToSharedBuffer(dataToTransfer);\n this.buffer = this.buffer.subarray(this.sharedBufferSize);\n }\n let concat = new Float32Array(this.buffer.length + data.length);\n concat.set(this.buffer);\n concat.set(data, this.buffer.length);\n this.buffer = concat;\n }\n\n process(inputs, outputs, parameters) {\n const inputChannelData = inputs[0][0];\n if (inputChannelData !== undefined) {\n if (this.controlSAB && this.dataSAB) {\n this._pushData(inputChannelData);\n } else {\n this.port.postMessage({\n type: 'DATA',\n frames: inputChannelData\n });\n }\n }\n\n return true;\n }\n}\n\nfunction getStandardDeviation(array) {\n const n = array.length\n const mean = array.reduce((a, b) => a + b) / n\n return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)\n}\n\nregisterProcessor('speechly-worklet', SpeechlyProcessor);\n"],{type:"text/javascript"}),e=window.URL.createObjectURL(t);if(yield this.audioContext.audioWorklet.addModule(e),this.speechlyNode=new AudioWorkletNode(this.audioContext,"speechly-worklet"),this.speechlyNode.connect(this.audioContext.destination),this.useSAB&&void 0!==window.SharedArrayBuffer){this.debug&&console.log("[BrowserClient]","using SharedArrayBuffer");const t=new window.SharedArrayBuffer(4*Int32Array.BYTES_PER_ELEMENT),e=new window.SharedArrayBuffer(1024*Float32Array.BYTES_PER_ELEMENT);this.decoder.useSharedArrayBuffers(t,e),this.speechlyNode.port.postMessage({type:"SET_SHARED_ARRAY_BUFFERS",controlSAB:t,dataSAB:e,debug:this.debug})}else this.debug&&console.log("[BrowserClient]","can not use SharedArrayBuffer");this.speechlyNode.port.onmessage=t=>{switch(t.data.type){case"STATS":t.data.signalEnergy>this.stats.maxSignalEnergy&&(this.stats.maxSignalEnergy=t.data.signalEnergy),this.stats.sentSamples+=parseInt(t.data.samples);break;case"DATA":this.handleAudio(t.data.frames)}}}this.debug&&console.log("[BrowserClient]","audioContext sampleRate is",null===(i=this.audioContext)||void 0===i?void 0:i.sampleRate),this.streamOptions.sampleRate=null===(o=this.audioContext)||void 0===o?void 0:o.sampleRate,yield this.decoder.initAudioProcessor(this.streamOptions.sampleRate,this.decoderOptions.frameMillis,this.decoderOptions.historyFrames,this.decoderOptions.vad),this.audioProcessorInitialized=!0,(null==t?void 0:t.mediaStream)&&(yield this.attach(null==t?void 0:t.mediaStream))}}))}attach(t){var e,i,s,n,o,d;return a(this,void 0,void 0,(function*(){if(yield this.initialize(),yield this.detach(),this.stream=null===(e=this.audioContext)||void 0===e?void 0:e.createMediaStreamSource(t),"running"!==(null===(i=this.audioContext)||void 0===i?void 0:i.state)&&(this.debug&&console.log("[BrowserClient]","audioContext resume required, state is",null===(s=this.audioContext)||void 0===s?void 0:s.state),yield null===(n=this.audioContext)||void 0===n?void 0:n.resume()),this.speechlyNode)null===(o=this.stream)||void 0===o||o.connect(this.speechlyNode);else{if(!this.audioProcessor)throw Error("[BrowserClient] cannot attach to mediaStream, not initialized");null===(d=this.stream)||void 0===d||d.connect(this.audioProcessor)}yield this.autoControlStream()}))}isActive(){return this.active}start(t){return a(this,void 0,void 0,(function*(){if(this.active)throw S;this.active=!0;return yield this.queueTask((()=>a(this,void 0,void 0,(function*(){yield this.initialize(),this.isStreaming||(yield this.startStream({autoStarted:!0}));return yield this.decoder.startContext(t)}))))}))}stop(t=this.contextStopDelay){return a(this,void 0,void 0,(function*(){if(!this.active)throw X;this.active=!1;return yield this.queueTask((()=>a(this,void 0,void 0,(function*(){var e;try{const i=yield this.decoder.stopContext(t);return!(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)&&this.isStreaming&&this.streamOptions.autoStarted&&(yield this.stopStream()),0===this.stats.sentSamples&&console.warn("[BrowserClient]","audioContext contained no audio data"),i}catch(t){console.warn("[BrowserClient]","stop() failed",t)}finally{this.stats.sentSamples=0}}))))}))}setContextOptions(t){return a(this,void 0,void 0,(function*(){yield this.decoder.setContextOptions(t)}))}adjustAudioProcessor(t){var e;if(t.vad){if(!this.decoderOptions.vad)throw Error("Unable to adjust VAD - it was not defined in the constructor");this.decoderOptions.vad=Object.assign(Object.assign({},this.decoderOptions.vad),t.vad)}this.decoder.adjustAudioProcessor(t),(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)?this.autoControlStream():this.active&&this.stop()}uploadAudioData(t,e){var i,s,n;return a(this,void 0,void 0,(function*(){yield this.initialize();const o=yield null===(i=this.audioContext)||void 0===i?void 0:i.decodeAudioData(t);if(void 0===o)throw Error("Could not decode audioData");const a=o.getChannelData(0);if(o.numberOfChannels>1){const t=o.getChannelData(1);for(let e=0;e<a.length;e++)a[e]=(a[e]+t[e])/2}this.active&&(yield this.stop(0)),this.isStreaming&&(yield this.stopStream()),yield this.startStream({sampleRate:o.sampleRate,preserveSegments:!0,immediate:!0});const d=(null===(s=this.decoderOptions.vad)||void 0===s?void 0:s.enabled)&&(null===(n=this.decoderOptions.vad)||void 0===n?void 0:n.controlListening),c=1e3;let l,r=0;if(d){if(e&&(yield this.setContextOptions(e)),this.decoderOptions.vad.signalSustainMillis>=c){r=c/(10/(1e4/this.decoderOptions.vad.signalSustainMillis))}else console.warn("Throttling disabled due to low (<= 1000) VAD sustain value. Server may disconnect while processing if contexts are created at high rate.");r=0}else yield this.start(e);const h=Math.round(o.sampleRate*c/1e3);for(let t=0;t<a.length;t+=h){const e=t+h;l=e>a.length?a.slice(t):a.slice(t,e),this.handleAudio(l),yield this.sleep(r)}d||(yield this.stop(0)),yield this.stopStream();return this.decoder.getSegments()}))}startStream(t){return a(this,void 0,void 0,(function*(){this.streamOptions=Object.assign(Object.assign(Object.assign({},this.streamOptions),{autoStarted:!1}),t),yield this.decoder.startStream(this.streamOptions),this.isStreaming=!0}))}stopStream(){return a(this,void 0,void 0,(function*(){this.isStreaming&&(this.isStreaming=!1,yield this.decoder.stopStream())}))}queueTask(t){return a(this,void 0,void 0,(function*(){const e=this.listeningPromise;return this.listeningPromise=(()=>a(this,void 0,void 0,(function*(){return yield e,t()})))(),this.listeningPromise}))}autoControlListening(t){var e;this.debug&&console.log("[BrowserClient]","autoControlListening",t),(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.controlListening)&&(t?this.active||this.start():this.active&&this.stop(0))}autoControlStream(){var t,e;return a(this,void 0,void 0,(function*(){this.audioProcessorInitialized&&this.stream&&(!(null===(t=this.decoderOptions.vad)||void 0===t?void 0:t.enabled)||this.isStreaming?!(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)&&this.isStreaming&&this.streamOptions.autoStarted&&(yield this.stopStream()):yield this.startStream({autoStarted:!0}))}))}handleStateChange(e){switch(e){case t.DecoderState.Disconnected:case t.DecoderState.Failed:this.stopStream(),this.active=!1,this.listeningPromise=null}}detach(){return a(this,void 0,void 0,(function*(){this.active&&(yield this.stop(0)),this.stream&&(this.stream.disconnect(),this.stream=void 0)}))}close(){var t,e,i;return a(this,void 0,void 0,(function*(){this.debug&&console.log("[BrowserClient]","close"),yield this.detach(),null!==this.speechlyNode&&(null===(t=this.speechlyNode)||void 0===t||t.port.close(),null===(e=this.speechlyNode)||void 0===e||e.disconnect()),void 0!==this.audioProcessor&&(null===(i=this.audioProcessor)||void 0===i||i.disconnect()),yield this.decoder.close(),this.initialized=!1,this.listeningPromise=null}))}sleep(t){return a(this,void 0,void 0,(function*(){return new Promise((e=>setTimeout(e,t)))}))}handleAudio(t){this.isStreaming&&(this.stats.sentSamples+=t.length,this.decoder.sendAudio(t))}onStart(t){this.callbacks.contextStartedCbs.addEventListener(t)}onStop(t){this.callbacks.contextStoppedCbs.addEventListener(t)}onSegmentChange(t){this.callbacks.segmentChangeCbs.addEventListener(t)}onTranscript(t){this.callbacks.transcriptCbs.addEventListener(t)}onEntity(t){this.callbacks.entityCbs.addEventListener(t)}onIntent(t){this.callbacks.intentCbs.addEventListener(t)}onTentativeTranscript(t){this.callbacks.tentativeTranscriptCbs.addEventListener(t)}onTentativeEntities(t){this.callbacks.tentativeEntityCbs.addEventListener(t)}onTentativeIntent(t){this.callbacks.tentativeIntentCbs.addEventListener(t)}onStateChange(t){this.callbacks.stateChangeCbs.addEventListener(t)}},t.BrowserMicrophone=class{constructor(){this.muted=!1,this.initialized=!1,this.state=t.AudioSourceState.Stopped,this.debug=!1,this.stateChangeCbs=[];try{const t=window.navigator.mediaDevices.getSupportedConstraints();this.nativeResamplingSupported=!0===t.sampleRate,this.autoGainControlSupported=!0===t.autoGainControl}catch(t){this.nativeResamplingSupported=!1,this.autoGainControlSupported=!1}}onStateChange(t){this.stateChangeCbs.push(t)}initialize(){var i;return a(this,void 0,void 0,(function*(){if(this.initialized)return;if(void 0===(null===(i=window.navigator)||void 0===i?void 0:i.mediaDevices))throw this.setState(t.AudioSourceState.NoBrowserSupport),e;const s={video:!1};this.nativeResamplingSupported||this.autoGainControlSupported?s.audio={sampleRate:n,autoGainControl:this.autoGainControlSupported}:s.audio=!0;try{this.setState(t.AudioSourceState.Starting),this.mediaStream=yield window.navigator.mediaDevices.getUserMedia(s)}catch(e){throw this.setState(t.AudioSourceState.NoAudioConsent),console.error(e),l}this.initialized=!0,this.muted=!0,this.setState(t.AudioSourceState.Started)}))}setState(t){this.state!==t&&(this.debug&&console.log("[BrowserMicrophone]",this.state,"->",t),this.state=t,this.stateChangeCbs.forEach((e=>e(t))))}close(){return a(this,void 0,void 0,(function*(){if(!this.initialized)return;this.muted=!0;this.mediaStream.getTracks().forEach((t=>t.stop())),this.mediaStream=void 0,this.initialized=!1,this.setState(t.AudioSourceState.Stopped)}))}isRecording(){return!this.muted}},t.CloudDecoder=U,t.DecoderDefaultOptions=Z,t.DefaultSampleRate=n,t.ErrAlreadyInitialized=c,t.ErrAlreadyStarted=S,t.ErrAlreadyStopped=X,t.ErrAppIdChangeWithoutProjectLogin=i,t.ErrDeviceNotSupported=e,t.ErrKeyNotFound=m,t.ErrNoAudioConsent=l,t.ErrNoStorageSupport=b,t.ErrNotInitialized=d,t.EventCallbacks=R,t.ListenerArray=W,t.SegmentState=o,t.StreamDefaultOptions=G,t.VadDefaultOptions=y,t.WebsocketError=s,t.stateToString=V,Object.defineProperty(t,"__esModule",{value:!0})}));
!function(t,e){!function(i){var s=e,n=t&&t.exports==s&&t,o="object"==typeof L&&L;o.global!==o&&o.window!==o||(i=o);var a=function(t){this.message=t};(a.prototype=new Error).name="InvalidCharacterError";var d=function(t){throw new a(t)},c="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",l=/[\t\n\f\r ]/g,r={encode:function(t){t=String(t),/[^\0-\xFF]/.test(t)&&d("The string to be encoded contains characters outside of the Latin1 range.");for(var e,i,s,n,o=t.length%3,a="",l=-1,r=t.length-o;++l<r;)e=t.charCodeAt(l)<<16,i=t.charCodeAt(++l)<<8,s=t.charCodeAt(++l),a+=c.charAt((n=e+i+s)>>18&63)+c.charAt(n>>12&63)+c.charAt(n>>6&63)+c.charAt(63&n);return 2==o?(e=t.charCodeAt(l)<<8,i=t.charCodeAt(++l),a+=c.charAt((n=e+i)>>10)+c.charAt(n>>4&63)+c.charAt(n<<2&63)+"="):1==o&&(n=t.charCodeAt(l),a+=c.charAt(n>>2)+c.charAt(n<<4&63)+"=="),a},decode:function(t){var e=(t=String(t).replace(l,"")).length;e%4==0&&(e=(t=t.replace(/==?$/,"")).length),(e%4==1||/[^+a-zA-Z0-9/]/.test(t))&&d("Invalid character: the string to be decoded is not correctly encoded.");for(var i,s,n=0,o="",a=-1;++a<e;)s=c.indexOf(t.charAt(a)),i=n%4?64*i+s:s,n++%4&&(o+=String.fromCharCode(255&i>>(-2*n&6)));return o},version:"0.1.0"};if(s&&!s.nodeType)if(n)n.exports=r;else for(var h in r)r.hasOwnProperty(h)&&(s[h]=r[h]);else i.base64=r}(L)}(I,I.exports);function w(t,e,i,s,n=Date.now){const o=function(t){const e=t.split(".")[1];let i;try{i=JSON.parse(I.exports.decode(e))}catch(t){throw new Error("Error decoding Speechly token!")}return{appId:i.appId,projectId:i.projectId,deviceId:i.deviceId,configId:i.configId,scopes:i.scope.split(" "),issuer:i.iss,audience:i.aud,expiresAtMs:1e3*i.exp}}(t);return!(o.expiresAtMs-n()<36e5)&&(o.appId===i&&o.projectId===e&&o.deviceId===s)}class k{onResponse(t){this.onResponseCb=t}onClose(t){this.onCloseCb=t}constructor(){this.startCbs=[],this.stopCbs=[],this.onResponseCb=()=>{},this.onCloseCb=()=>{},this.onWebsocketMessage=e=>{const i=e.data;switch(i.type){case t.WorkerSignal.Opened:this.onInitResolve&&this.onInitResolve();break;case t.WorkerSignal.Closed:const n=new s(e.data.reason,e.data.code,e.data.wasClean);this.onInitReject?this.onInitReject(n):this.onCloseCb(n);break;case t.WorkerSignal.AudioProcessorReady:null!=this.resolveSourceSampleRateSet&&this.resolveSourceSampleRateSet();break;case t.WebsocketResponseType.Started:this.onResponseCb(i),this.startCbs.forEach((t=>{try{t(void 0,i.audio_context)}catch(t){console.error('[SpeechlyClient] Error while invoking "onStart" callback:',t)}})),this.startCbs.length=0;break;case t.WebsocketResponseType.Stopped:this.onResponseCb(i),this.stopCbs.forEach((t=>{try{t(void 0,i.audio_context)}catch(t){console.error('[SpeechlyClient] Error while invoking "onStop" callback:',t)}})),this.stopCbs.length=0;break;default:this.onResponseCb(i)}},this.worker=new"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwp2YXIgd29ya2VyX2NvZGU9ZnVuY3Rpb24odCl7InVzZSBzdHJpY3QiO2NsYXNzIGV7c3RhdGljIGRvd25zYW1wbGUodCxlLHM9MCxpPS0xLG89MCxhPS0xKXtpZihpPDAmJihpPXQubGVuZ3RoLXMpLGE8MCYmKGE9ZS5sZW5ndGgtbyksYT5pKXRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZG93bnNhbXBsZTogc291cmNlIGFycmF5IGxlbmd0aCAoJHtpfSkgaXMgc2hvcnRlciB0aGFuIGRlc3RpbmF0aW9uICgke2F9KWApO2lmKDA9PT1hKXRocm93IG5ldyBFcnJvcihgQ2FuJ3QgZG93bnNhbXBsZTogc291cmNlIGFycmF5IGxlbmd0aCAoJHtpfSkgY2FuJ3QgYmUgZG93bnNhbXBsZWQgdG8gemVyby1sZW5ndGggZGVzdGluYXRpb24uYCk7aWYoMD09PWkpdGhyb3cgbmV3IEVycm9yKCJDYW4ndCBkb3duc2FtcGxlOiBzb3VyY2UgcmFuZ2UgY2FuJ3QgYmUgemVybyBsZW5ndGguIik7aWYoMT09PWkpcmV0dXJuIHZvaWQoZVswXT10WzBdKTtsZXQgcj0wO2NvbnN0IG49KGEtMSkvKGktMSk7bGV0IGg9MCxkPTA7Y29uc3QgbD1zK2k7Zm9yKDtzPGw7cysrKXtjb25zdCBpPS41LU1hdGguYWJzKHIpO2grPXRbc10qaSxkKz1pLHIrPW4scj49LjUmJihyLT0xLGVbbysrXT1oL2QsaD0wLGQ9MCl9ZD4wJiYoZVtvKytdPWgvZCl9c3RhdGljIGdldEVuZXJneSh0LGU9MCxzPS0xKXtpZihzPDAmJihzPXQubGVuZ3RoLWUpLHM8PTApcmV0dXJuIDA7Y29uc3QgaT1lK3M7bGV0IG89MDtmb3IoO2U8aTtlKyspbys9dFtlXSp0W2VdO3JldHVybiBNYXRoLnNxcnQoby9zKX1zdGF0aWMgZ2V0QXVkaW9QZWFrKHQsZT0wLHM9LTEpe2lmKHM8MCYmKHM9dC5sZW5ndGgtZSksczw9MClyZXR1cm4gMDtjb25zdCBpPWUrcztsZXQgbz0wO2Zvcig7ZTxpO2UrKyl0W2VdPm8mJihvPXRbZV0pO3JldHVybiBvfXN0YXRpYyBjb252ZXJ0SW50MTZUb0Zsb2F0KHQsZSxzPTAsaT0tMSxvPTApe2k8MCYmKGk9dC5sZW5ndGgvMi1zKTtjb25zdCBhPU1hdGgubWluKHQubGVuZ3RoLzItcyxlLmxlbmd0aC1vKTtpZigoaT1NYXRoLm1pbihpLGEpKTw9MClyZXR1cm4gMDtsZXQgcj0yKnM7Y29uc3Qgbj1yKzIqaTtmb3IoO3I8bjspZVtvKytdPSh0W3IrK10rKHRbcisrXTw8OCkpLzMyNzY3O3JldHVybiBpfXN0YXRpYyBjb252ZXJ0RmxvYXRUb0ludDE2KHQsZSxzPTAsaT0tMSxvPTApe2k8MCYmKGk9dC5sZW5ndGgtcyk7Y29uc3QgYT1zK2k7Zm9yKDtzPGE7KWVbbysrXT1+figzMjc2Nyp0W3MrK10pfXN0YXRpYyBlbmVyZ3lUb0RiKHQpe3JldHVybiAxMCpNYXRoLmxvZyh0KS9lLkxPR18yX1BMVVNfTE9HXzV9c3RhdGljIGRiVG9FbmVyZ3kodCl7cmV0dXJuIE1hdGgucG93KDEwLHQvMTApfX1lLkxPR18yX1BMVVNfTE9HXzU9TWF0aC5sb2coMikrTWF0aC5sb2coNSk7Y2xhc3Mgc3tjb25zdHJ1Y3Rvcih0LGUscyxpKXt0aGlzLmlzU2VuZGluZz0hMSx0aGlzLnN0cmVhbVNhbXBsZVBvcz0wLHRoaXMuc2FtcGxlc1NlbnQ9MCx0aGlzLnV0dGVyYW5jZVNlcmlhbD0tMSx0aGlzLm9uU2VuZEF1ZGlvPSh0LGUscyk9Pnt9LHRoaXMub25WYWRTdGF0ZUNoYW5nZT10PT57fSx0aGlzLmlucHV0U2FtcGxlUmF0ZT0xNmUzLHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlPTE2ZTMsdGhpcy5oaXN0b3J5RnJhbWVzPTUsdGhpcy5mcmFtZU1pbGxpcz0zMCx0aGlzLmN1cnJlbnRGcmFtZU51bWJlcj0wLHRoaXMuZnJhbWVTYW1wbGVQb3M9MCx0aGlzLnN0cmVhbUZyYW1lUG9zPTAsdGhpcy53YXNTaWduYWxEZXRlY3RlZD0hMSx0aGlzLmlucHV0U2FtcGxlUmF0ZT10LHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlPWUsdGhpcy5mcmFtZU1pbGxpcz1zLHRoaXMuaGlzdG9yeUZyYW1lcz1pLHRoaXMuZnJhbWVTYW1wbGVzPX5+KHRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKnRoaXMuZnJhbWVNaWxsaXMvMWUzKSx0aGlzLnNhbXBsZVJpbmdCdWZmZXI9bmV3IEZsb2F0MzJBcnJheSh0aGlzLmZyYW1lU2FtcGxlcyp0aGlzLmhpc3RvcnlGcmFtZXMpfXByb2Nlc3NBdWRpbyh0LHM9MCxpPS0xLG89ITEpe2lmKGk8MCYmKGk9dC5sZW5ndGgpLDA9PT1pKXJldHVybiB2b2lkKG8mJnRoaXMucHJvY2Vzc0VvcygpKTtsZXQgYT1zO2NvbnN0IHI9cytpO2Zvcig7YTxyOyl7Y29uc3Qgcz10aGlzLmN1cnJlbnRGcmFtZU51bWJlcip0aGlzLmZyYW1lU2FtcGxlcztpZih0aGlzLmlucHV0U2FtcGxlUmF0ZT09PXRoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKXtjb25zdCBlPU1hdGgubWluKHItYSx0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKSxpPXRoaXMuZnJhbWVTYW1wbGVQb3MrZTtmb3IoO3RoaXMuZnJhbWVTYW1wbGVQb3M8aTspdGhpcy5zYW1wbGVSaW5nQnVmZmVyW3MrdGhpcy5mcmFtZVNhbXBsZVBvcysrXT10W2ErK119ZWxzZXtjb25zdCBpPTEqdGhpcy5pbnB1dFNhbXBsZVJhdGUvdGhpcy5pbnRlcm5hbFNhbXBsZVJhdGUsbz1NYXRoLm1pbihyLWEsTWF0aC5yb3VuZChpKih0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKSkpLG49TWF0aC5taW4oTWF0aC5yb3VuZCgoci1hKS9pKSx0aGlzLmZyYW1lU2FtcGxlcy10aGlzLmZyYW1lU2FtcGxlUG9zKTtuPjAmJmUuZG93bnNhbXBsZSh0LHRoaXMuc2FtcGxlUmluZ0J1ZmZlcixhLG8scyt0aGlzLmZyYW1lU2FtcGxlUG9zLG4pLGErPW8sdGhpcy5mcmFtZVNhbXBsZVBvcys9bn1jb25zdCBpPWE9PT1yJiZvO2lmKHRoaXMuZnJhbWVTYW1wbGVQb3M9PT10aGlzLmZyYW1lU2FtcGxlc3x8aSl7Y29uc3QgdD1pP3RoaXMuZnJhbWVTYW1wbGVQb3M6dGhpcy5mcmFtZVNhbXBsZXM7aWYodGhpcy5wcm9jZXNzRnJhbWUodGhpcy5zYW1wbGVSaW5nQnVmZmVyLHMsdCxpKSx0aGlzLmlzU2VuZGluZyl7aWYoMD09PXRoaXMuc2FtcGxlc1NlbnQpe2NvbnN0IHQ9TWF0aC5taW4odGhpcy5zdHJlYW1GcmFtZVBvcyx0aGlzLmhpc3RvcnlGcmFtZXMtMSk7bGV0IGU9KHRoaXMuY3VycmVudEZyYW1lTnVtYmVyK3RoaXMuaGlzdG9yeUZyYW1lcy10KSV0aGlzLmhpc3RvcnlGcmFtZXM7Zm9yKDtlIT09dGhpcy5jdXJyZW50RnJhbWVOdW1iZXI7KXRoaXMub25TZW5kQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLGUqdGhpcy5mcmFtZVNhbXBsZXMsdGhpcy5mcmFtZVNhbXBsZXMpLHRoaXMuc2FtcGxlc1NlbnQrPXRoaXMuZnJhbWVTYW1wbGVzLGU9KGUrMSkldGhpcy5oaXN0b3J5RnJhbWVzfXRoaXMub25TZW5kQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLHMsdCksdGhpcy5zYW1wbGVzU2VudCs9dH1pPyh0aGlzLnN0cmVhbVNhbXBsZVBvcys9dCx0aGlzLnByb2Nlc3NFb3MoKSk6dGhpcy5mcmFtZVNhbXBsZVBvcz09PXRoaXMuZnJhbWVTYW1wbGVzJiYodGhpcy5mcmFtZVNhbXBsZVBvcz0wLHRoaXMuc3RyZWFtRnJhbWVQb3MrPTEsdGhpcy5zdHJlYW1TYW1wbGVQb3MrPXQsdGhpcy5jdXJyZW50RnJhbWVOdW1iZXI9KHRoaXMuY3VycmVudEZyYW1lTnVtYmVyKzEpJXRoaXMuaGlzdG9yeUZyYW1lcyl9dGhpcy52YWQmJih0aGlzLndhc1NpZ25hbERldGVjdGVkPXRoaXMudmFkLmlzU2lnbmFsRGV0ZWN0ZWQpfX1zZXRTZW5kQXVkaW8odCl7dGhpcy5pc1NlbmRpbmc9dCx0JiYodGhpcy5zYW1wbGVzU2VudD0wLHRoaXMudXR0ZXJhbmNlU2VyaWFsKyspfXJlc2V0KHQpe3ZhciBlO3RoaXMuaXNTZW5kaW5nPSExLHRoaXMuc3RyZWFtRnJhbWVQb3M9MCx0aGlzLnN0cmVhbVNhbXBsZVBvcz0wLHRoaXMuZnJhbWVTYW1wbGVQb3M9MCx0aGlzLmN1cnJlbnRGcmFtZU51bWJlcj0wLHRoaXMudXR0ZXJhbmNlU2VyaWFsPS0xLHQmJih0aGlzLmlucHV0U2FtcGxlUmF0ZT10KSx0aGlzLndhc1NpZ25hbERldGVjdGVkPSExLG51bGw9PT0oZT10aGlzLnZhZCl8fHZvaWQgMD09PWV8fGUucmVzZXRWQUQoKX1nZXRTdHJlYW1Qb3NpdGlvbigpe3JldHVybiBNYXRoLnJvdW5kKHRoaXMuc3RyZWFtU2FtcGxlUG9zL3RoaXMuaW50ZXJuYWxTYW1wbGVSYXRlKjFlMyl9ZW9zKCl7dGhpcy5wcm9jZXNzQXVkaW8odGhpcy5zYW1wbGVSaW5nQnVmZmVyLDAsdGhpcy5mcmFtZVNhbXBsZVBvcywhMCl9cHJvY2Vzc0ZyYW1lKHQsZT0wLHM9LTEsaT0hMSl7dmFyIG87KG51bGw9PT0obz10aGlzLnZhZCl8fHZvaWQgMD09PW8/dm9pZCAwOm8udmFkT3B0aW9ucy5lbmFibGVkKSYmKHRoaXMudmFkLnByb2Nlc3NGcmFtZSh0LGUscyxpKSx0aGlzLnZhZC5pc1NpZ25hbERldGVjdGVkIT09dGhpcy53YXNTaWduYWxEZXRlY3RlZCYmdGhpcy5vblZhZFN0YXRlQ2hhbmdlKHRoaXMudmFkLmlzU2lnbmFsRGV0ZWN0ZWQpKX1wcm9jZXNzRW9zKCl7dmFyIHQ7dGhpcy5pc1NlbmRpbmcmJihudWxsPT09KHQ9dGhpcy52YWQpfHx2b2lkIDA9PT10P3ZvaWQgMDp0LnZhZE9wdGlvbnMuZW5hYmxlZCkmJih0aGlzLnZhZC5yZXNldFZBRCgpLHRoaXMub25WYWRTdGF0ZUNoYW5nZSghMSkpfX1jbGFzcyBpe2NvbnN0cnVjdG9yKHQsZSl7dGhpcy5pc1NpZ25hbERldGVjdGVkPSExLHRoaXMuc2lnbmFsRGI9LTkwLHRoaXMubm9pc2VMZXZlbERiPS05MCx0aGlzLmZyYW1lTWlsbGlzPTMwLHRoaXMuZW5lcmd5PTAsdGhpcy5iYXNlbGluZUVuZXJneT0tMSx0aGlzLmxvdWRGcmFtZUJpdHM9MCx0aGlzLnZhZFN1c3RhaW5NaWxsaXNMZWZ0PTAsdGhpcy5mcmFtZU1pbGxpcz10LHRoaXMudmFkT3B0aW9ucz1lfWFkanVzdFZhZE9wdGlvbnModCl7dGhpcy52YWRPcHRpb25zPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSx0aGlzLnZhZE9wdGlvbnMpLHQpfXJlc2V0VkFEKCl7dGhpcy5pc1NpZ25hbERldGVjdGVkPSExLHRoaXMubG91ZEZyYW1lQml0cz0wLHRoaXMuZW5lcmd5PTAsdGhpcy5iYXNlbGluZUVuZXJneT0tMX1wcm9jZXNzRnJhbWUodCxzPTAsaT0tMSxvPSExKXtpZighdGhpcy52YWRPcHRpb25zLmVuYWJsZWQpcmV0dXJuIHZvaWQgdGhpcy5yZXNldFZBRCgpO2lmKG8pcmV0dXJuO3RoaXMuZW5lcmd5PWUuZ2V0RW5lcmd5KHQscyxpKSx0aGlzLmJhc2VsaW5lRW5lcmd5PDAmJih0aGlzLmJhc2VsaW5lRW5lcmd5PXRoaXMuZW5lcmd5KTtjb25zdCBhPXRoaXMuZW5lcmd5Pk1hdGgubWF4KGUuZGJUb0VuZXJneSh0aGlzLnZhZE9wdGlvbnMubm9pc2VHYXRlRGIpLHRoaXMuYmFzZWxpbmVFbmVyZ3kqZS5kYlRvRW5lcmd5KHRoaXMudmFkT3B0aW9ucy5zaWduYWxUb05vaXNlRGIpKTt0aGlzLnB1c2hGcmFtZUhpc3RvcnkoYSksdGhpcy5pc1NpZ25hbERldGVjdGVkPXRoaXMuZGV0ZXJtaW5lTmV3U2lnbmFsU3RhdGUodGhpcy5pc1NpZ25hbERldGVjdGVkKSx0aGlzLmFkYXB0QmFja2dyb3VuZE5vaXNlKCksdGhpcy5zaWduYWxEYj1lLmVuZXJneVRvRGIodGhpcy5lbmVyZ3kvdGhpcy5iYXNlbGluZUVuZXJneSksdGhpcy5ub2lzZUxldmVsRGI9ZS5lbmVyZ3lUb0RiKHRoaXMuYmFzZWxpbmVFbmVyZ3kpfWRldGVybWluZU5ld1NpZ25hbFN0YXRlKHQpe3RoaXMudmFkU3VzdGFpbk1pbGxpc0xlZnQ9TWF0aC5tYXgodGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdC10aGlzLmZyYW1lTWlsbGlzLDApO2NvbnN0IGU9dGhpcy5jb3VudExvdWRGcmFtZXModGhpcy52YWRPcHRpb25zLnNpZ25hbFNlYXJjaEZyYW1lcykscz1NYXRoLnJvdW5kKHRoaXMudmFkT3B0aW9ucy5zaWduYWxBY3RpdmF0aW9uKnRoaXMudmFkT3B0aW9ucy5zaWduYWxTZWFyY2hGcmFtZXMpLGk9TWF0aC5yb3VuZCh0aGlzLnZhZE9wdGlvbnMuc2lnbmFsUmVsZWFzZSp0aGlzLnZhZE9wdGlvbnMuc2lnbmFsU2VhcmNoRnJhbWVzKTtyZXR1cm4gZT49cz8odGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdD10aGlzLnZhZE9wdGlvbnMuc2lnbmFsU3VzdGFpbk1pbGxpcywhMCk6IShlPD1pJiYwPT09dGhpcy52YWRTdXN0YWluTWlsbGlzTGVmdCkmJnR9YWRhcHRCYWNrZ3JvdW5kTm9pc2UoKXtpZighdGhpcy5pc1NpZ25hbERldGVjdGVkJiZ0aGlzLnZhZE9wdGlvbnMubm9pc2VMZWFybkhhbGZ0aW1lTWlsbGlzPjApe3ZhciB0PU1hdGgucG93KDIsLXRoaXMuZnJhbWVNaWxsaXMvdGhpcy52YWRPcHRpb25zLm5vaXNlTGVhcm5IYWxmdGltZU1pbGxpcyk7dGhpcy5iYXNlbGluZUVuZXJneT10aGlzLmJhc2VsaW5lRW5lcmd5KnQrdGhpcy5lbmVyZ3kqKDEtdCl9fXB1c2hGcmFtZUhpc3RvcnkodCl7dGhpcy5sb3VkRnJhbWVCaXRzPSh0PzE6MCl8dGhpcy5sb3VkRnJhbWVCaXRzPDwxfWNvdW50TG91ZEZyYW1lcyh0KXtsZXQgZT0wLHM9dGhpcy5sb3VkRnJhbWVCaXRzO2Zvcig7dD4wOykxPT0oMSZzKSYmZSsrLHM+Pj0xLHQtLTtyZXR1cm4gZX19dmFyIG8sYSxyOyFmdW5jdGlvbih0KXt0LlN0YXJ0ZWQ9InN0YXJ0ZWQiLHQuU3RvcHBlZD0ic3RvcHBlZCIsdC5TZWdtZW50RW5kPSJzZWdtZW50X2VuZCIsdC5UcmFuc2NyaXB0PSJ0cmFuc2NyaXB0Iix0LkVudGl0eT0iZW50aXR5Iix0LkludGVudD0iaW50ZW50Iix0LlRlbnRhdGl2ZVRyYW5zY3JpcHQ9InRlbnRhdGl2ZV90cmFuc2NyaXB0Iix0LlRlbnRhdGl2ZUVudGl0aWVzPSJ0ZW50YXRpdmVfZW50aXRpZXMiLHQuVGVudGF0aXZlSW50ZW50PSJ0ZW50YXRpdmVfaW50ZW50In0ob3x8KG89e30pKSxmdW5jdGlvbih0KXt0Lk9wZW5lZD0iV0VCU09DS0VUX09QRU4iLHQuQ2xvc2VkPSJXRUJTT0NLRVRfQ0xPU0VEIix0LkF1ZGlvUHJvY2Vzc29yUmVhZHk9IlNPVVJDRV9TQU1QTEVfUkFURV9TRVRfU1VDQ0VTUyIsdC5WYWRTaWduYWxIaWdoPSJWYWRTaWduYWxIaWdoIix0LlZhZFNpZ25hbExvdz0iVmFkU2lnbmFsTG93Iix0LlJlcXVlc3RDb250ZXh0U3RhcnQ9IlJlcXVlc3RDb250ZXh0U3RhcnQifShhfHwoYT17fSkpLGZ1bmN0aW9uKHQpe3QuY29ubmVjdD0iY29ubmVjdCIsdC5pbml0QXVkaW9Qcm9jZXNzb3I9ImluaXRBdWRpb1Byb2Nlc3NvciIsdC5hZGp1c3RBdWRpb1Byb2Nlc3Nvcj0iYWRqdXN0QXVkaW9Qcm9jZXNzb3IiLHQuU0VUX1NIQVJFRF9BUlJBWV9CVUZGRVJTPSJTRVRfU0hBUkVEX0FSUkFZX0JVRkZFUlMiLHQuQ0xPU0U9IkNMT1NFIix0LlNUQVJUX0NPTlRFWFQ9IlNUQVJUX0NPTlRFWFQiLHQuU1dJVENIX0NPTlRFWFQ9IlNXSVRDSF9DT05URVhUIix0LlNUT1BfQ09OVEVYVD0iU1RPUF9DT05URVhUIix0LkFVRElPPSJBVURJTyIsdC5zdGFydFN0cmVhbT0ic3RhcnRTdHJlYW0iLHQuc3RvcFN0cmVhbT0ic3RvcFN0cmVhbSIsdC5zZXRDb250ZXh0T3B0aW9ucz0ic2V0Q29udGV4dE9wdGlvbnMifShyfHwocj17fSkpO2NvbnN0IG49MCxoPTEsZD0yO2NsYXNzIGx7Y29uc3RydWN0b3IodCl7dGhpcy50YXJnZXRTYW1wbGVSYXRlPTE2ZTMsdGhpcy5pc0NvbnRleHRTdGFydGVkPSExLHRoaXMuYXVkaW9Db250ZXh0U3RhcnRUaW1lcz1bXSx0aGlzLmltbWVkaWF0ZU1vZGU9ITEsdGhpcy5mcmFtZU1pbGxpcz0zMCx0aGlzLm91dHB1dEF1ZGlvRnJhbWU9bmV3IEludDE2QXJyYXkodGhpcy5mcmFtZU1pbGxpcyp0aGlzLnRhcmdldFNhbXBsZVJhdGUvMWUzKSx0aGlzLmRlYnVnPSExLHRoaXMub25XZWJzb2NrZXRDbG9zZT10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwib25XZWJzb2NrZXRDbG9zZSIpLHRoaXMuY2xvc2VXZWJzb2NrZXQodC5jb2RlLHQucmVhc29uLHQud2FzQ2xlYW4sITEpfSx0aGlzLm9uV2Vic29ja2V0T3Blbj10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwid2Vic29ja2V0IG9wZW5lZCIpLHRoaXMud29ya2VyQ3R4LnBvc3RNZXNzYWdlKHt0eXBlOmEuT3BlbmVkfSl9LHRoaXMub25XZWJzb2NrZXRFcnJvcj10PT57dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwid2Vic29ja2V0IGVycm9yIil9LHRoaXMub25XZWJzb2NrZXRNZXNzYWdlPXQ9PntsZXQgZTt0cnl7ZT1KU09OLnBhcnNlKHQuZGF0YSl9Y2F0Y2godCl7cmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJlcnJvciBwYXJzaW5nIHJlc3BvbnNlIGZyb20gdGhlIHNlcnZlcjoiLHQpfWlmKGUudHlwZT09PW8uU3RhcnRlZCl7bGV0IHQ9dGhpcy5hdWRpb0NvbnRleHRTdGFydFRpbWVzLnNoaWZ0KCk7dm9pZCAwPT09dCYmKGNvbnNvbGUud2FybigiTm8gdmFsaWQgdmFsdWUgZm9yIGNvbnRleHRTdGFydE1pbGxpcyIpLHQ9MCk7Y29uc3Qgcz17YXVkaW9TdGFydFRpbWVNaWxsaXM6dH07ZS5wYXJhbXM9c310aGlzLndvcmtlckN0eC5wb3N0TWVzc2FnZShlKX0sdGhpcy53b3JrZXJDdHg9dH1jb25uZWN0KHQsZSxzLGkpe3RoaXMuZGVidWc9aSx0aGlzLmRlYnVnJiZjb25zb2xlLmxvZygiW1dlYlNvY2tldENsaWVudF0iLCJjb25uZWN0aW5nIHRvICIsdCksdGhpcy50YXJnZXRTYW1wbGVSYXRlPXMsdGhpcy5pc0NvbnRleHRTdGFydGVkPSExLHRoaXMud2Vic29ja2V0PW5ldyBXZWJTb2NrZXQodCxlKSx0aGlzLndlYnNvY2tldC5hZGRFdmVudExpc3RlbmVyKCJvcGVuIix0aGlzLm9uV2Vic29ja2V0T3BlbiksdGhpcy53ZWJzb2NrZXQuYWRkRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsdGhpcy5vbldlYnNvY2tldE1lc3NhZ2UpLHRoaXMud2Vic29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoImVycm9yIix0aGlzLm9uV2Vic29ja2V0RXJyb3IpLHRoaXMud2Vic29ja2V0LmFkZEV2ZW50TGlzdGVuZXIoImNsb3NlIix0aGlzLm9uV2Vic29ja2V0Q2xvc2UpfWluaXRBdWRpb1Byb2Nlc3Nvcih0LG8scixuKXt0aGlzLmF1ZGlvUHJvY2Vzc29yPW5ldyBzKHQsdGhpcy50YXJnZXRTYW1wbGVSYXRlLG8sciksbiYmKHRoaXMuYXVkaW9Qcm9jZXNzb3IudmFkPW5ldyBpKG8sbiksdGhpcy5hdWRpb1Byb2Nlc3Nvci5vblZhZFN0YXRlQ2hhbmdlPXQ9Pnt2YXIgZSxzO2NvbnN0IGk9bnVsbD09PShzPW51bGw9PT0oZT10aGlzLmF1ZGlvUHJvY2Vzc29yKXx8dm9pZCAwPT09ZT92b2lkIDA6ZS52YWQpfHx2b2lkIDA9PT1zP3ZvaWQgMDpzLnZhZE9wdGlvbnM7aSYmKHQmJih0aGlzLmltbWVkaWF0ZU1vZGU/aS5jb250cm9sTGlzdGVuaW5nJiZ0aGlzLnN0YXJ0Q29udGV4dCh0aGlzLmRlZmF1bHRDb250ZXh0T3B0aW9ucyk6dGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5WYWRTaWduYWxIaWdofSkpLHR8fCh0aGlzLmltbWVkaWF0ZU1vZGU/aS5jb250cm9sTGlzdGVuaW5nJiZ0aGlzLnN0b3BDb250ZXh0KCk6dGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5WYWRTaWduYWxMb3d9KSkpfSksdGhpcy5hdWRpb1Byb2Nlc3Nvci5vblNlbmRBdWRpbz0odCxzLGkpPT57ZS5jb252ZXJ0RmxvYXRUb0ludDE2KHQsdGhpcy5vdXRwdXRBdWRpb0ZyYW1lLHMsaSksdGhpcy5zZW5kKHRoaXMub3V0cHV0QXVkaW9GcmFtZSl9LHZvaWQgMCE9PXRoaXMud29ya2VyQ3R4JiZ0aGlzLndvcmtlckN0eC5wb3N0TWVzc2FnZSh7dHlwZTphLkF1ZGlvUHJvY2Vzc29yUmVhZHl9KX1hZGp1c3RBdWRpb1Byb2Nlc3Nvcih0KXtpZih0aGlzLmF1ZGlvUHJvY2Vzc29yJiZ0LnZhZCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IudmFkKXRocm93IG5ldyBFcnJvcigiTm8gVkFEIGluIEF1ZGlvUHJvY2Vzc29yLiBEaWQgeW91IGRlZmluZSBgdmFkYCBpbiBCcm93c2VyQ2xpZW50IGNvbnN0cnVjdG9yIHBhcmFtZXRlcnM/Iik7dGhpcy5hdWRpb1Byb2Nlc3Nvci52YWQuYWRqdXN0VmFkT3B0aW9ucyh0LnZhZCl9fXNldFNoYXJlZEFycmF5QnVmZmVycyh0LGUpe3RoaXMuY29udHJvbFNBQj1uZXcgSW50MzJBcnJheSh0KSx0aGlzLmRhdGFTQUI9bmV3IEZsb2F0MzJBcnJheShlKTtjb25zdCBzPXRoaXMuZGF0YVNBQi5sZW5ndGgvMzI7dGhpcy5kZWJ1ZyYmY29uc29sZS5sb2coIltXZWJTb2NrZXRDbGllbnRdIiwiQXVkaW8gaGFuZGxlIGludGVydmFsIixzLCJtcyIpLHNldEludGVydmFsKHRoaXMucHJvY2Vzc0F1ZGlvU0FCLmJpbmQodGhpcykscyl9c3RhcnRTdHJlYW0odCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgbmV3IEVycm9yKCJObyBBdWRpb1Byb2Nlc3NvciIpO3RoaXMuaW1tZWRpYXRlTW9kZT10LmltbWVkaWF0ZSx0aGlzLmF1ZGlvUHJvY2Vzc29yLnJlc2V0KHQuc2FtcGxlUmF0ZSksdGhpcy5hdWRpb0NvbnRleHRTdGFydFRpbWVzPVtdfXN0b3BTdHJlYW0oKXtpZighdGhpcy5hdWRpb1Byb2Nlc3Nvcil0aHJvdyBuZXcgRXJyb3IoIk5vIEF1ZGlvUHJvY2Vzc29yIik7dGhpcy5hdWRpb1Byb2Nlc3Nvci5lb3MoKX1wcm9jZXNzQXVkaW8odCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgbmV3IEVycm9yKCJObyBBdWRpb1Byb2Nlc3NvciIpO3RoaXMuYXVkaW9Qcm9jZXNzb3IucHJvY2Vzc0F1ZGlvKHQpfXByb2Nlc3NBdWRpb1NBQigpe2lmKCF0aGlzLmNvbnRyb2xTQUJ8fCF0aGlzLmRhdGFTQUIpdGhyb3cgbmV3IEVycm9yKCJObyBTaGFyZWRBcnJheUJ1ZmZlcnMiKTtjb25zdCB0PXRoaXMuY29udHJvbFNBQltoXTtpZigwPT09dGhpcy5jb250cm9sU0FCW2RdJiZ0PjApe2NvbnN0IGU9dGhpcy5kYXRhU0FCLnN1YmFycmF5KDAsdCk7dGhpcy5jb250cm9sU0FCW2hdPTAsdGhpcy5jb250cm9sU0FCW25dPTAsZS5sZW5ndGg+MCYmdGhpcy5wcm9jZXNzQXVkaW8oZSl9fXN0YXJ0Q29udGV4dCh0KXt2YXIgZTtpZighdGhpcy5hdWRpb1Byb2Nlc3Nvcil0aHJvdyBFcnJvcigiTm8gQXVkaW9Qcm9jZXNzb3IiKTtpZih0aGlzLmlzQ29udGV4dFN0YXJ0ZWQpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzdGFydCBjb250ZXh0OiBhY3RpdmUgY29udGV4dCBleGlzdHMiKTt0aGlzLmF1ZGlvUHJvY2Vzc29yLnNldFNlbmRBdWRpbyghMCksdGhpcy5pc0NvbnRleHRTdGFydGVkPSEwLHRoaXMuYXVkaW9Db250ZXh0U3RhcnRUaW1lcy5wdXNoKHRoaXMuYXVkaW9Qcm9jZXNzb3IuZ2V0U3RyZWFtUG9zaXRpb24oKSksdGhpcy53b3JrZXJDdHgucG9zdE1lc3NhZ2Uoe3R5cGU6YS5SZXF1ZXN0Q29udGV4dFN0YXJ0fSk7bGV0IHM9bnVsbCE9PShlPXRoaXMuZGVmYXVsdENvbnRleHRPcHRpb25zKSYmdm9pZCAwIT09ZT9lOnt9O3ZvaWQgMCE9PXQmJihzPU9iamVjdC5hc3NpZ24oT2JqZWN0LmFzc2lnbih7fSxzKSx0KSk7Y29uc3QgaT11KHMpO2kuZXZlbnQ9InN0YXJ0Iix0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkoaSkpfXN0b3BDb250ZXh0KCl7aWYoIXRoaXMuYXVkaW9Qcm9jZXNzb3IpdGhyb3cgRXJyb3IoIk5vIEF1ZGlvUHJvY2Vzc29yIik7aWYoIXRoaXMuaXNDb250ZXh0U3RhcnRlZClyZXR1cm4gdm9pZCBjb25zb2xlLmVycm9yKCJbV2ViU29ja2V0Q2xpZW50XSIsImNhbid0IHN0b3AgY29udGV4dDogbm8gYWN0aXZlIGNvbnRleHQiKTt0aGlzLmF1ZGlvUHJvY2Vzc29yLnNldFNlbmRBdWRpbyghMSksdGhpcy5pc0NvbnRleHRTdGFydGVkPSExO2NvbnN0IHQ9SlNPTi5zdHJpbmdpZnkoe2V2ZW50OiJzdG9wIn0pO3RoaXMuc2VuZCh0KX1zd2l0Y2hDb250ZXh0KHQpe2lmKCF0aGlzLndlYnNvY2tldCl0aHJvdyBFcnJvcigiV2ViU29ja2V0IGlzIHVuZGVmaW5lZCIpO2lmKCF0aGlzLmlzQ29udGV4dFN0YXJ0ZWQpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzd2l0Y2ggY29udGV4dDogbm8gYWN0aXZlIGNvbnRleHQiKTtpZih2b2lkIDA9PT0obnVsbD09dD92b2lkIDA6dC5hcHBJZCkpcmV0dXJuIHZvaWQgY29uc29sZS5lcnJvcigiW1dlYlNvY2tldENsaWVudF0iLCJjYW4ndCBzd2l0Y2ggY29udGV4dDogbmV3IGFwcCBpZCBpcyB1bmRlZmluZWQiKTtjb25zdCBlPUpTT04uc3RyaW5naWZ5KHtldmVudDoic3RvcCJ9KTt0aGlzLnNlbmQoZSk7Y29uc3Qgcz11KHQpO3MuZXZlbnQ9InN0YXJ0Iix0aGlzLnNlbmQoSlNPTi5zdHJpbmdpZnkocykpfWNsb3NlV2Vic29ja2V0KHQ9MTAwNSxlPSJObyBTdGF0dXMgUmVjZWl2ZWQiLHM9ITAsaT0hMCl7dmFyIG87dGhpcy53ZWJzb2NrZXQ/KHRoaXMuZGVidWcmJmNvbnNvbGUubG9nKCJbV2ViU29ja2V0Q2xpZW50XSIsaT8iV2Vic29ja2V0IGNsb3NlIHJlcXVlc3RlZCI6IldlYnNvY2tldCBjbG9zZWQiKSxudWxsPT09KG89dGhpcy5hdWRpb1Byb2Nlc3Nvcil8fHZvaWQgMD09PW98fG8ucmVzZXQoKSx0aGlzLndlYnNvY2tldC5yZW1vdmVFdmVudExpc3RlbmVyKCJvcGVuIix0aGlzLm9uV2Vic29ja2V0T3BlbiksdGhpcy53ZWJzb2NrZXQucmVtb3ZlRXZlbnRMaXN0ZW5lcigibWVzc2FnZSIsdGhpcy5vbldlYnNvY2tldE1lc3NhZ2UpLHRoaXMud2Vic29ja2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImVycm9yIix0aGlzLm9uV2Vic29ja2V0RXJyb3IpLHRoaXMud2Vic29ja2V0LnJlbW92ZUV2ZW50TGlzdGVuZXIoImNsb3NlIix0aGlzLm9uV2Vic29ja2V0Q2xvc2UpLGkmJnRoaXMud2Vic29ja2V0LmNsb3NlKHQsZSksdGhpcy53ZWJzb2NrZXQ9dm9pZCAwLHRoaXMud29ya2VyQ3R4LnBvc3RNZXNzYWdlKHt0eXBlOmEuQ2xvc2VkLGNvZGU6dCxyZWFzb246ZSx3YXNDbGVhbjpzfSkpOmNvbnNvbGUud2FybigiV2ViU29ja2V0IGFscmVhZHkgY2xvc2VkIil9c2VuZCh0KXtpZighdGhpcy53ZWJzb2NrZXQpdGhyb3cgbmV3IEVycm9yKCJObyBXZWJzb2NrZXQiKTtpZih0aGlzLndlYnNvY2tldC5yZWFkeVN0YXRlPT09dGhpcy53ZWJzb2NrZXQuT1BFTil0cnl7dGhpcy53ZWJzb2NrZXQuc2VuZCh0KX1jYXRjaCh0KXtjb25zb2xlLmxvZygiW1dlYlNvY2tldENsaWVudF0iLCJzZXJ2ZXIgY29ubmVjdGlvbiBlcnJvciIsdCl9ZWxzZSBjb25zb2xlLndhcm4oYEV4cGVjdGVkIE9QRU4gV2Vic29ja2V0IHN0YXRlLCBidXQgZ290ICR7dGhpcy53ZWJzb2NrZXQucmVhZHlTdGF0ZX1gKX1zZXRDb250ZXh0T3B0aW9ucyh0KXt0aGlzLmRlZmF1bHRDb250ZXh0T3B0aW9ucz10fX1jb25zdCBjPXNlbGYsbT1uZXcgbChjKTtmdW5jdGlvbiB1KHQpe2NvbnN0IGU9e29wdGlvbnM6e3RpbWV6b25lOltJbnRsLkRhdGVUaW1lRm9ybWF0KCkucmVzb2x2ZWRPcHRpb25zKCkudGltZVpvbmVdfX07cmV0dXJuIHZvaWQgMD09PXR8fChlLm9wdGlvbnMudm9jYWJ1bGFyeT10LnZvY2FidWxhcnksZS5vcHRpb25zLnZvY2FidWxhcnlfYmlhcz10LnZvY2FidWxhcnlCaWFzLGUub3B0aW9ucy5zaWxlbmNlX3RyaWdnZXJlZF9zZWdtZW50YXRpb249dC5zaWxlbmNlVHJpZ2dlcmVkU2VnbWVudGF0aW9uLHQubm9uU3RyZWFtaW5nTmx1P2Uub3B0aW9ucy5ub25fc3RyZWFtaW5nX25sdT1bInllcyJdOmUub3B0aW9ucy5ub25fc3RyZWFtaW5nX25sdT1bIm5vIl0sdm9pZCAwIT09KG51bGw9PXQ/dm9pZCAwOnQudGltZXpvbmUpJiYoZS5vcHRpb25zLnRpbWV6b25lPW51bGw9PXQ/dm9pZCAwOnQudGltZXpvbmUpLHZvaWQgMCE9PXQuYXBwSWQmJihlLmFwcElkPXQuYXBwSWQpKSxlfXJldHVybiBjLm9ubWVzc2FnZT1mdW5jdGlvbih0KXtzd2l0Y2godC5kYXRhLnR5cGUpe2Nhc2Ugci5jb25uZWN0Om0uY29ubmVjdCh0LmRhdGEuYXBpVXJsLHQuZGF0YS5hdXRoVG9rZW4sdC5kYXRhLnRhcmdldFNhbXBsZVJhdGUsdC5kYXRhLmRlYnVnKTticmVhaztjYXNlIHIuaW5pdEF1ZGlvUHJvY2Vzc29yOm0uaW5pdEF1ZGlvUHJvY2Vzc29yKHQuZGF0YS5zb3VyY2VTYW1wbGVSYXRlLHQuZGF0YS5mcmFtZU1pbGxpcyx0LmRhdGEuaGlzdG9yeUZyYW1lcyx0LmRhdGEudmFkT3B0aW9ucyk7YnJlYWs7Y2FzZSByLmFkanVzdEF1ZGlvUHJvY2Vzc29yOm0uYWRqdXN0QXVkaW9Qcm9jZXNzb3IodC5kYXRhLnBhcmFtcyk7YnJlYWs7Y2FzZSByLlNFVF9TSEFSRURfQVJSQVlfQlVGRkVSUzptLnNldFNoYXJlZEFycmF5QnVmZmVycyh0LmRhdGEuY29udHJvbFNBQix0LmRhdGEuZGF0YVNBQik7YnJlYWs7Y2FzZSByLkNMT1NFOm0uY2xvc2VXZWJzb2NrZXQoMWUzLCJDbG9zZSByZXF1ZXN0ZWQgYnkgY2xpZW50IiwhMCwhMCk7YnJlYWs7Y2FzZSByLnN0YXJ0U3RyZWFtOm0uc3RhcnRTdHJlYW0odC5kYXRhLnN0cmVhbU9wdGlvbnMpO2JyZWFrO2Nhc2Ugci5zdG9wU3RyZWFtOm0uc3RvcFN0cmVhbSgpO2JyZWFrO2Nhc2Ugci5TVEFSVF9DT05URVhUOm0uc3RhcnRDb250ZXh0KHQuZGF0YS5vcHRpb25zKTticmVhaztjYXNlIHIuU1dJVENIX0NPTlRFWFQ6bS5zd2l0Y2hDb250ZXh0KHQuZGF0YS5vcHRpb25zKTticmVhaztjYXNlIHIuU1RPUF9DT05URVhUOm0uc3RvcENvbnRleHQoKTticmVhaztjYXNlIHIuQVVESU86bS5wcm9jZXNzQXVkaW8odC5kYXRhLnBheWxvYWQpO2JyZWFrO2Nhc2Ugci5zZXRDb250ZXh0T3B0aW9uczptLnNldENvbnRleHRPcHRpb25zKHQuZGF0YS5vcHRpb25zKTticmVhaztkZWZhdWx0OmNvbnNvbGUubG9nKCJXT1JLRVIiLHQpfX0sdC5jb250ZXh0T3B0aW9uc1RvTXNnPXUsdC5kZWZhdWx0PWwsT2JqZWN0LmRlZmluZVByb3BlcnR5KHQsIl9fZXNNb2R1bGUiLHt2YWx1ZTohMH0pLHR9KHt9KTsKCg==",this.worker.addEventListener("message",this.onWebsocketMessage)}initialize(e,i,s,n){return a(this,void 0,void 0,(function*(){return this.worker.postMessage({type:t.ControllerSignal.connect,apiUrl:e,authToken:i,targetSampleRate:s,debug:n}),this.startCbs=[],this.stopCbs=[],new Promise(((t,e)=>{this.onInitResolve=()=>{this.onInitResolve=void 0,this.onInitReject=void 0,t()},this.onInitReject=t=>{this.onInitResolve=void 0,this.onInitReject=void 0,e(t)}}))}))}initAudioProcessor(e,i,s,n){return a(this,void 0,void 0,(function*(){return this.worker.postMessage({type:t.ControllerSignal.initAudioProcessor,sourceSampleRate:e,frameMillis:i,historyFrames:s,vadOptions:n}),new Promise((t=>{this.resolveSourceSampleRateSet=t}))}))}adjustAudioProcessor(e){this.worker.postMessage({type:t.ControllerSignal.adjustAudioProcessor,params:e})}close(){return a(this,void 0,void 0,(function*(){return new Promise(((e,i)=>{this.worker.postMessage({type:t.ControllerSignal.CLOSE,code:1e3,message:"Client has ended the session"}),e()}))}))}startStream(e){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.startStream,streamOptions:e})}))}stopStream(){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.stopStream})}))}startContext(e){return a(this,void 0,void 0,(function*(){return new Promise(((i,s)=>{this.startCbs.push(((t,e)=>{void 0!==t?s(t):i(e)})),this.worker.postMessage({type:t.ControllerSignal.START_CONTEXT,options:e})}))}))}stopContext(){return a(this,void 0,void 0,(function*(){return new Promise(((e,i)=>{this.stopCbs.push(((t,s)=>{void 0!==t?i(t):e(s)})),this.worker.postMessage({type:t.ControllerSignal.STOP_CONTEXT})}))}))}switchContext(e){return a(this,void 0,void 0,(function*(){return new Promise(((i,s)=>{this.startCbs.push(((t,e)=>{void 0!==t?s(t):i(e)})),this.worker.postMessage({type:t.ControllerSignal.SWITCH_CONTEXT,options:e})}))}))}postMessage(t){this.worker.postMessage(t)}sendAudio(e){this.worker.postMessage({type:t.ControllerSignal.AUDIO,payload:e})}setContextOptions(e){return a(this,void 0,void 0,(function*(){this.worker.postMessage({type:t.ControllerSignal.setContextOptions,options:e})}))}}class E{constructor(){this.storage=window.localStorage}get(t){return this.storage.getItem(t)}set(t,e){this.storage.setItem(t,e)}getOrSet(t,e){let i=this.storage.getItem(t);return null===i&&(i=e(),this.storage.setItem(t,i)),i}}function M(t,e){return{intent:t.intent,isFinal:e}}const J="speechly-auth-token";class U{constructor(e){var i,s;if(this.streamOptions=G,this.activeContexts=0,this.audioContexts=new Map,this.maxReconnectAttemptCount=10,this.connectAttempt=0,this.connectPromise=null,this.cbs=[],this.state=t.DecoderState.Disconnected,this.handleWebsocketResponse=e=>{var i;switch(this.debug&&console.log("[Decoder]","Received response",e),e.type){case t.WorkerSignal.VadSignalHigh:this.cbs.forEach((t=>t.onVadStateChange.forEach((t=>t(!0)))));break;case t.WorkerSignal.VadSignalLow:this.cbs.forEach((t=>t.onVadStateChange.forEach((t=>t(!1)))));break;case t.WorkerSignal.RequestContextStart:this.activeContexts++;break;case t.WebsocketResponseType.Started:{const t=e.params;this.audioContexts.set(e.audio_context,{segments:new Map,audioStartTimeMillis:null!==(i=null==t?void 0:t.audioStartTimeMillis)&&void 0!==i?i:0}),this.cbs.forEach((t=>t.contextStartedCbs.forEach((t=>t(e.audio_context)))));break}case t.WebsocketResponseType.Stopped:this.activeContexts--,this.cbs.forEach((t=>t.contextStoppedCbs.forEach((t=>t(e.audio_context))))),this.streamOptions.preserveSegments||this.audioContexts.delete(e.audio_context),void 0!==this.resolveStopStream&&0===this.activeContexts&&this.resolveStopStream();break;default:this.handleSegmentUpdate(e)}},this.handleSegmentUpdate=e=>{var i;const{audio_context:s,segment_id:n,type:a}=e;let{data:d}=e;const c=this.audioContexts.get(s);if(void 0===c)return void console.warn("[Decoder]","Received response for non-existent context",s);let l=null!==(i=c.segments.get(n))&&void 0!==i?i:new o(s,n);switch(a){case t.WebsocketResponseType.TentativeTranscript:const e=function(t,e){return t.words.map((({word:t,index:i,start_timestamp:s,end_timestamp:n})=>({value:t,index:i,startTimestamp:s+e,endTimestamp:n+e,isFinal:!1})))}(d,c.audioStartTimeMillis),i=d.transcript;this.cbs.forEach((t=>t.tentativeTranscriptCbs.forEach((t=>t(s,n,e,i))))),l=l.updateTranscript(e);break;case t.WebsocketResponseType.Transcript:const o=function(t,e){return{value:t.word,index:t.index,startTimestamp:t.start_timestamp+e,endTimestamp:t.end_timestamp+e,isFinal:!0}}(d,c.audioStartTimeMillis);this.cbs.forEach((t=>t.transcriptCbs.forEach((t=>t(s,n,o))))),l=l.updateTranscript([o]);break;case t.WebsocketResponseType.TentativeEntities:const a=function(t){return t.entities.map((({entity:t,value:e,start_position:i,end_position:s})=>({type:t,value:e,startPosition:i,endPosition:s,isFinal:!1})))}(d);this.cbs.forEach((t=>t.tentativeEntityCbs.forEach((t=>t(s,n,a))))),l=l.updateEntities(a);break;case t.WebsocketResponseType.Entity:const r=function(t){return{type:t.entity,value:t.value,startPosition:t.start_position,endPosition:t.end_position,isFinal:!0}}(d);this.cbs.forEach((t=>t.entityCbs.forEach((t=>t(s,n,r))))),l=l.updateEntities([r]);break;case t.WebsocketResponseType.TentativeIntent:const h=M(d,!1);this.cbs.forEach((t=>t.tentativeIntentCbs.forEach((t=>t(s,n,h))))),l=l.updateIntent(h);break;case t.WebsocketResponseType.Intent:const u=M(d,!0);this.cbs.forEach((t=>t.intentCbs.forEach((t=>t(s,n,u))))),l=l.updateIntent(u);break;case t.WebsocketResponseType.SegmentEnd:l=l.finalize()}c.segments.set(n,l),this.audioContexts.set(s,c),this.logSegments&&console.info(l.toString()),this.cbs.forEach((t=>t.segmentChangeCbs.forEach((t=>t(l.toSegment())))))},this.handleWebsocketClosure=e=>{if(1e3===e.code)this.debug&&console.log("[Decoder]","Websocket closed",e);else{if(console.error("[Decoder]","Websocket closed due to error",e),void 0===this.deviceId)return this.setState(t.DecoderState.Failed),void console.error("[Decoder]","No deviceId. Giving up reconnecting.");this.setState(t.DecoderState.Disconnected),this.activeContexts=0,this.audioContexts.clear(),this.reconnect()}},this.logSegments=e.logSegments,this.appId=e.appId,this.projectId=e.projectId,this.sampleRate=e.sampleRate,this.debug=e.debug,void 0!==this.appId&&void 0!==this.projectId)throw Error("[Decoder] You cannot use both appId and projectId at the same time");if(void 0===this.appId&&void 0===this.projectId)throw Error("[Decoder] Either an appId or a projectId is required");const n=e.apiUrl;this.apiUrl=function(t,e){const i=new URLSearchParams;return i.append("sampleRate",e.toString()),`${t}?${i.toString()}`}(n.replace("http","ws")+"/ws/v1",this.sampleRate),this.loginUrl=`${n}/login`;try{this.storage=null!==(i=e.storage)&&void 0!==i?i:new E,this.deviceId=this.storage.getOrSet("speechly-device-id",x)}catch(t){this.deviceId=x()}this.apiClient=new k,this.apiClient.onResponse(this.handleWebsocketResponse),this.apiClient.onClose(this.handleWebsocketClosure),(null===(s=e.connect)||void 0===s||s)&&this.connect()}getReconnectDelayMs(t){return 100*Math.pow(2,t)}sleep(t){return a(this,void 0,void 0,(function*(){return new Promise((e=>setTimeout(e,t)))}))}connect(){return a(this,void 0,void 0,(function*(){null===this.connectPromise&&(this.connectPromise=(()=>a(this,void 0,void 0,(function*(){var e;this.setState(t.DecoderState.Disconnected);const i=null===(e=this.storage)||void 0===e?void 0:e.get(J);if(i&&w(i,this.projectId,this.appId,this.deviceId))this.authToken=i;else try{this.authToken=yield function(t,e,i,s,n=fetch,o=Date.now){var d;return a(this,void 0,void 0,(function*(){let a;a=void 0!==e?{projectId:e,deviceId:s}:{appId:i,deviceId:s};const c=yield n(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),l=yield c.json();if(200!==c.status)throw Error(null!==(d=l.error)&&void 0!==d?d:`Speechly API login request failed with ${c.status}`);if(void 0===l.access_token)throw Error("Invalid login response from Speechly API");if(!w(l.access_token,e,i,s,o))throw Error("Invalid token received from Speechly API");return l.access_token}))}(this.loginUrl,this.projectId,this.appId,this.deviceId,fetch),this.storage&&this.storage.set(J,this.authToken)}catch(e){throw this.connectPromise=null,this.setState(t.DecoderState.Failed),e}try{yield this.apiClient.initialize(this.apiUrl,this.authToken,this.sampleRate,this.debug)}catch(e){throw this.connectPromise=null,e instanceof s&&1e3===e.code||this.setState(t.DecoderState.Failed),e}this.advanceState(t.DecoderState.Connected)})))()),yield this.connectPromise}))}adjustAudioProcessor(t){this.apiClient.adjustAudioProcessor(t)}close(){return a(this,void 0,void 0,(function*(){let e;try{yield this.apiClient.close()}catch(t){e=t.message}if(this.audioContexts.clear(),this.activeContexts=0,this.connectPromise=null,this.setState(t.DecoderState.Disconnected),void 0!==e)throw Error(e)}))}startStream(t){return a(this,void 0,void 0,(function*(){this.debug&&console.log("[Decoder]","startStream"),this.streamOptions=t,this.audioContexts.clear(),this.activeContexts=0,yield this.apiClient.startStream(t)}))}stopStream(){return a(this,void 0,void 0,(function*(){this.debug&&console.log("[Decoder]","stopStream"),yield this.apiClient.stopStream(),yield this.waitResults()}))}waitResults(){return a(this,void 0,void 0,(function*(){if(this.activeContexts>0){const t=new Promise((t=>{this.resolveStopStream=t}));yield t}this.resolveStopStream=void 0}))}startContext(e){return a(this,void 0,void 0,(function*(){if(this.state===t.DecoderState.Failed)throw Error("[Decoder] startContext cannot be run in Failed state.");if(this.state<t.DecoderState.Connected)yield this.connect();else if(this.state>t.DecoderState.Connected)throw Error("[Decoder] Unable to complete startContext: Expected Connected state, but was in "+V(this.state)+".");let s;if(this.setState(t.DecoderState.Active),null!=this.projectId){if(!(null==e?void 0:e.appId))throw new Error("options.appId is required with project login");s=yield this.apiClient.startContext(e)}else{if(null!=(null==e?void 0:e.appId)&&this.appId!==(null==e?void 0:e.appId))throw this.setState(t.DecoderState.Failed),i;s=yield this.apiClient.startContext(e)}if(this.state<t.DecoderState.Active)throw Error("[Decoder] Unable to complete startContext: Problem acquiring contextId");return s}))}sendAudio(t){this.apiClient.sendAudio(t)}stopContext(e){return a(this,void 0,void 0,(function*(){if(this.state===t.DecoderState.Failed)throw Error("[Decoder] stopContext cannot be run in unrecovable error state.");if(this.state!==t.DecoderState.Active)throw Error("[Decoder] Unable to complete stopContext: Expected Active state, but was in "+V(this.state)+".");e>0&&(yield this.sleep(e));const i=yield this.apiClient.stopContext();return this.setState(t.DecoderState.Connected),i}))}switchContext(e){return a(this,void 0,void 0,(function*(){if(this.state!==t.DecoderState.Active)throw Error("[Decoder] Unable to complete switchContext: Expected Active state, but was in "+V(this.state)+".");return yield this.apiClient.switchContext(e)}))}registerListener(t){this.cbs.push(t)}initAudioProcessor(t,e,i,s){return a(this,void 0,void 0,(function*(){yield this.apiClient.initAudioProcessor(t,e,i,s)}))}useSharedArrayBuffers(t,e){this.apiClient.postMessage({type:"SET_SHARED_ARRAY_BUFFERS",controlSAB:t,dataSAB:e})}setContextOptions(t){return a(this,void 0,void 0,(function*(){yield this.apiClient.setContextOptions(t)}))}reconnect(){return a(this,void 0,void 0,(function*(){console.log("Speechly reconnecting"),this.connectPromise=null,this.connectAttempt<this.maxReconnectAttemptCount?(yield this.sleep(this.getReconnectDelayMs(this.connectAttempt++)),yield this.connect()):console.error("[Decoder] Maximum reconnect count reached, giving up automatic reconnect.")}))}advanceState(t){this.state>=t||this.setState(t)}setState(t){this.state!==t&&(this.debug&&console.log("[Decoder]",V(this.state),"->",V(t)),this.state=t,this.cbs.forEach((e=>{var i;return null===(i=e.stateChangeCbs)||void 0===i?void 0:i.forEach((e=>e(t)))})))}getSegments(){const t=[];return this.audioContexts.forEach(((e,i)=>{e.segments.forEach(((e,i)=>{const s=JSON.parse(JSON.stringify(e));t.push(s)}))})),t}}t.BrowserClient=class{constructor(t){var e,i;this.contextStopDelay=250,this.debug=!1,this.initialized=!1,this.audioProcessorInitialized=!1,this.isStreaming=!1,this.active=!1,this.listeningPromise=null,this.streamOptions=Object.assign({},G),this.stats={maxSignalEnergy:0,sentSamples:0},this.decoderOptions=Object.assign(Object.assign(Object.assign({},Z),t),{vad:t.vad?Object.assign(Object.assign({},y),t.vad):void 0});const s=window.navigator.mediaDevices.getSupportedConstraints();this.nativeResamplingSupported=!0===s.sampleRate,this.isMobileSafari=["iPad Simulator","iPhone Simulator","iPod Simulator","iPad","iPhone","iPod"].indexOf(navigator.platform)>=0||navigator.userAgent.includes("Mac")&&"ontouchend"in document,this.isSafari=this.isMobileSafari||void 0!==window.safari,this.useSAB=!this.isSafari,this.debug=null===(e=this.decoderOptions.debug)||void 0===e||e,this.callbacks=new R,this.callbacks.stateChangeCbs.addEventListener(this.handleStateChange.bind(this)),this.callbacks.onVadStateChange.addEventListener(this.autoControlListening.bind(this)),this.decoder=null!==(i=this.decoderOptions.decoder)&&void 0!==i?i:new U(this.decoderOptions),this.decoder.registerListener(this.callbacks)}initialize(t){var i,o;return a(this,void 0,void 0,(function*(){if(!this.initialized){this.debug&&console.log("[BrowserClient]","initializing"),this.initialized=!0;try{yield this.decoder.connect()}catch(t){if(this.initialized=!1,t instanceof s){if(1e3===t.code)return void(this.debug&&console.log("[BrowserClient]","Early close of websocket."));throw Error(`Unable to connect. Most likely there is no connection to network. Websocket error code: ${t.code}`)}throw t}try{const t={};if(this.nativeResamplingSupported&&(t.sampleRate=n),void 0!==window.webkitAudioContext)try{this.audioContext=new window.webkitAudioContext(t)}catch(t){this.debug&&console.log("[BrowserClient]","creating audioContext without samplerate conversion",t),this.audioContext=new window.webkitAudioContext}else this.audioContext=new window.AudioContext(t),void 0!==window.webkitAudioContext&&(yield this.audioContext.resume())}catch(t){throw this.initialized=!1,e}if(this.isSafari||void 0===window.AudioWorkletNode){if(this.debug&&console.log("[BrowserClient]","using ScriptProcessorNode"),void 0!==window.webkitAudioContext){const t=this.audioContext.sampleRate/n,e=4096*Math.pow(2,Math.ceil(Math.log(t)/Math.log(2)));this.audioProcessor=this.audioContext.createScriptProcessor(e,1,1)}else this.audioProcessor=this.audioContext.createScriptProcessor(void 0,1,1);this.audioProcessor.connect(this.audioContext.destination),this.audioProcessor.addEventListener("audioprocess",(t=>{this.handleAudio(t.inputBuffer.getChannelData(0))}))}else{this.debug&&console.log("[BrowserClient]","using AudioWorkletNode");const t=new Blob(["\n// Indices for the Control SAB.\nconst CONTROL = {\n 'WRITE_INDEX': 0,\n 'FRAMES_AVAILABLE': 1,\n 'LOCK': 2,\n};\n\nclass SpeechlyProcessor extends AudioWorkletProcessor {\n constructor() {\n super();\n\n this._initialized = false;\n this.debug = false;\n this.port.onmessage = this._initialize.bind(this);\n }\n\n _initialize(event) {\n this.controlSAB = new Int32Array(event.data.controlSAB);\n this.dataSAB = new Float32Array(event.data.dataSAB);\n this.debug = event.data.debug;\n if (this.debug) {\n console.log('[BrowserClient AudioWorkletNode]', 'initializing audioworklet');\n }\n this.sharedBufferSize = this.dataSAB.length;\n this.buffer = new Float32Array(0);\n this._initialized = true;\n }\n\n _transferDataToSharedBuffer(data) {\n this.controlSAB[CONTROL.LOCK] = 1;\n let inputWriteIndex = this.controlSAB[CONTROL.WRITE_INDEX];\n if (this.controlSAB[CONTROL.FRAMES_AVAILABLE] > 0) {\n if (inputWriteIndex + data.length > this.sharedBufferSize) {\n // console.log('buffer overflow')\n inputWriteIndex = 0;\n }\n }\n this.dataSAB.set(data, inputWriteIndex);\n this.controlSAB[CONTROL.WRITE_INDEX] = inputWriteIndex + data.length;\n this.controlSAB[CONTROL.FRAMES_AVAILABLE] = inputWriteIndex + data.length;\n this.controlSAB[CONTROL.LOCK] = 0;\n }\n\n _pushData(data) {\n if (this.debug) {\n const signalEnergy = getStandardDeviation(data)\n this.port.postMessage({\n type: 'STATS',\n signalEnergy: signalEnergy,\n samples: data.length,\n });\n }\n\n if (this.buffer.length > this.sharedBufferSize) {\n const dataToTransfer = this.buffer.subarray(0, this.sharedBufferSize);\n this._transferDataToSharedBuffer(dataToTransfer);\n this.buffer = this.buffer.subarray(this.sharedBufferSize);\n }\n let concat = new Float32Array(this.buffer.length + data.length);\n concat.set(this.buffer);\n concat.set(data, this.buffer.length);\n this.buffer = concat;\n }\n\n process(inputs, outputs, parameters) {\n const inputChannelData = inputs[0][0];\n if (inputChannelData !== undefined) {\n if (this.controlSAB && this.dataSAB) {\n this._pushData(inputChannelData);\n } else {\n this.port.postMessage({\n type: 'DATA',\n frames: inputChannelData\n });\n }\n }\n\n return true;\n }\n}\n\nfunction getStandardDeviation(array) {\n const n = array.length\n const mean = array.reduce((a, b) => a + b) / n\n return Math.sqrt(array.map(x => Math.pow(x - mean, 2)).reduce((a, b) => a + b) / n)\n}\n\nregisterProcessor('speechly-worklet', SpeechlyProcessor);\n"],{type:"text/javascript"}),e=window.URL.createObjectURL(t);if(yield this.audioContext.audioWorklet.addModule(e),this.speechlyNode=new AudioWorkletNode(this.audioContext,"speechly-worklet"),this.speechlyNode.connect(this.audioContext.destination),this.useSAB&&void 0!==window.SharedArrayBuffer){this.debug&&console.log("[BrowserClient]","using SharedArrayBuffer");const t=new window.SharedArrayBuffer(4*Int32Array.BYTES_PER_ELEMENT),e=new window.SharedArrayBuffer(1024*Float32Array.BYTES_PER_ELEMENT);this.decoder.useSharedArrayBuffers(t,e),this.speechlyNode.port.postMessage({type:"SET_SHARED_ARRAY_BUFFERS",controlSAB:t,dataSAB:e,debug:this.debug})}else this.debug&&console.log("[BrowserClient]","can not use SharedArrayBuffer");this.speechlyNode.port.onmessage=t=>{switch(t.data.type){case"STATS":t.data.signalEnergy>this.stats.maxSignalEnergy&&(this.stats.maxSignalEnergy=t.data.signalEnergy),this.stats.sentSamples+=parseInt(t.data.samples);break;case"DATA":this.handleAudio(t.data.frames)}}}this.debug&&console.log("[BrowserClient]","audioContext sampleRate is",null===(i=this.audioContext)||void 0===i?void 0:i.sampleRate),this.streamOptions.sampleRate=null===(o=this.audioContext)||void 0===o?void 0:o.sampleRate,yield this.decoder.initAudioProcessor(this.streamOptions.sampleRate,this.decoderOptions.frameMillis,this.decoderOptions.historyFrames,this.decoderOptions.vad),this.audioProcessorInitialized=!0,(null==t?void 0:t.mediaStream)&&(yield this.attach(null==t?void 0:t.mediaStream))}}))}attach(t){var e,i,s,n,o,d;return a(this,void 0,void 0,(function*(){if(yield this.initialize(),yield this.detach(),this.stream=null===(e=this.audioContext)||void 0===e?void 0:e.createMediaStreamSource(t),"running"!==(null===(i=this.audioContext)||void 0===i?void 0:i.state)&&(this.debug&&console.log("[BrowserClient]","audioContext resume required, state is",null===(s=this.audioContext)||void 0===s?void 0:s.state),yield null===(n=this.audioContext)||void 0===n?void 0:n.resume()),this.speechlyNode)null===(o=this.stream)||void 0===o||o.connect(this.speechlyNode);else{if(!this.audioProcessor)throw Error("[BrowserClient] cannot attach to mediaStream, not initialized");null===(d=this.stream)||void 0===d||d.connect(this.audioProcessor)}yield this.autoControlStream()}))}isActive(){return this.active}start(t){return a(this,void 0,void 0,(function*(){if(this.active)throw S;this.active=!0;return yield this.queueTask((()=>a(this,void 0,void 0,(function*(){yield this.initialize(),this.isStreaming||(yield this.startStream({autoStarted:!0}));return yield this.decoder.startContext(t)}))))}))}stop(t=this.contextStopDelay){return a(this,void 0,void 0,(function*(){if(!this.active)throw X;this.active=!1;return yield this.queueTask((()=>a(this,void 0,void 0,(function*(){var e;try{const i=yield this.decoder.stopContext(t);return!(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)&&this.isStreaming&&this.streamOptions.autoStarted&&(yield this.stopStream()),0===this.stats.sentSamples&&console.warn("[BrowserClient]","audioContext contained no audio data"),i}catch(t){console.warn("[BrowserClient]","stop() failed",t)}finally{this.stats.sentSamples=0}}))))}))}setContextOptions(t){return a(this,void 0,void 0,(function*(){yield this.decoder.setContextOptions(t)}))}adjustAudioProcessor(t){var e;if(t.vad){if(!this.decoderOptions.vad)throw Error("Unable to adjust VAD - it was not defined in the constructor");this.decoderOptions.vad=Object.assign(Object.assign({},this.decoderOptions.vad),t.vad)}this.decoder.adjustAudioProcessor(t),(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)?this.autoControlStream():this.active&&this.stop()}uploadAudioData(t,e){var i,s,n;return a(this,void 0,void 0,(function*(){yield this.initialize();const o=yield null===(i=this.audioContext)||void 0===i?void 0:i.decodeAudioData(t);if(void 0===o)throw Error("Could not decode audioData");const a=o.getChannelData(0);if(o.numberOfChannels>1){const t=o.getChannelData(1);for(let e=0;e<a.length;e++)a[e]=(a[e]+t[e])/2}this.active&&(yield this.stop(0)),this.isStreaming&&(yield this.stopStream()),yield this.startStream({sampleRate:o.sampleRate,preserveSegments:!0,immediate:!0});const d=(null===(s=this.decoderOptions.vad)||void 0===s?void 0:s.enabled)&&(null===(n=this.decoderOptions.vad)||void 0===n?void 0:n.controlListening),c=1e3;let l,r=0;if(d){if(e&&(yield this.setContextOptions(e)),this.decoderOptions.vad.signalSustainMillis>=c){r=c/(10/(1e4/this.decoderOptions.vad.signalSustainMillis))}else console.warn("Throttling disabled due to low (<= 1000) VAD sustain value. Server may disconnect while processing if contexts are created at high rate.");r=0}else yield this.start(e);const h=Math.round(o.sampleRate*c/1e3);for(let t=0;t<a.length;t+=h){const e=t+h;l=e>a.length?a.slice(t):a.slice(t,e),this.handleAudio(l),yield this.sleep(r)}d||(yield this.stop(0)),yield this.stopStream();return this.decoder.getSegments()}))}startStream(t){return a(this,void 0,void 0,(function*(){this.streamOptions=Object.assign(Object.assign(Object.assign({},this.streamOptions),{autoStarted:!1}),t),yield this.decoder.startStream(this.streamOptions),this.isStreaming=!0}))}stopStream(){return a(this,void 0,void 0,(function*(){this.isStreaming&&(this.isStreaming=!1,yield this.decoder.stopStream())}))}queueTask(t){return a(this,void 0,void 0,(function*(){const e=this.listeningPromise;return this.listeningPromise=(()=>a(this,void 0,void 0,(function*(){return yield e,t()})))(),this.listeningPromise}))}autoControlListening(t){var e;this.debug&&console.log("[BrowserClient]","autoControlListening",t),(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.controlListening)&&(t?this.active||this.start():this.active&&this.stop(0))}autoControlStream(){var t,e;return a(this,void 0,void 0,(function*(){this.audioProcessorInitialized&&this.stream&&(!(null===(t=this.decoderOptions.vad)||void 0===t?void 0:t.enabled)||this.isStreaming?!(null===(e=this.decoderOptions.vad)||void 0===e?void 0:e.enabled)&&this.isStreaming&&this.streamOptions.autoStarted&&(yield this.stopStream()):yield this.startStream({autoStarted:!0}))}))}handleStateChange(e){switch(e){case t.DecoderState.Disconnected:case t.DecoderState.Failed:this.stopStream(),this.active=!1,this.listeningPromise=null}}detach(){return a(this,void 0,void 0,(function*(){this.active&&(yield this.stop(0)),this.stream&&(this.stream.disconnect(),this.stream=void 0)}))}close(){var t,e,i;return a(this,void 0,void 0,(function*(){this.debug&&console.log("[BrowserClient]","close"),yield this.detach(),null!==this.speechlyNode&&(null===(t=this.speechlyNode)||void 0===t||t.port.close(),null===(e=this.speechlyNode)||void 0===e||e.disconnect()),void 0!==this.audioProcessor&&(null===(i=this.audioProcessor)||void 0===i||i.disconnect()),yield this.decoder.close(),this.initialized=!1,this.listeningPromise=null}))}sleep(t){return a(this,void 0,void 0,(function*(){return new Promise((e=>setTimeout(e,t)))}))}handleAudio(t){this.isStreaming&&(this.stats.sentSamples+=t.length,this.decoder.sendAudio(t))}onStart(t){this.callbacks.contextStartedCbs.addEventListener(t)}onStop(t){this.callbacks.contextStoppedCbs.addEventListener(t)}onSegmentChange(t){this.callbacks.segmentChangeCbs.addEventListener(t)}onTranscript(t){this.callbacks.transcriptCbs.addEventListener(t)}onEntity(t){this.callbacks.entityCbs.addEventListener(t)}onIntent(t){this.callbacks.intentCbs.addEventListener(t)}onTentativeTranscript(t){this.callbacks.tentativeTranscriptCbs.addEventListener(t)}onTentativeEntities(t){this.callbacks.tentativeEntityCbs.addEventListener(t)}onTentativeIntent(t){this.callbacks.tentativeIntentCbs.addEventListener(t)}onStateChange(t){this.callbacks.stateChangeCbs.addEventListener(t)}},t.BrowserMicrophone=class{constructor(){this.muted=!1,this.initialized=!1,this.state=t.AudioSourceState.Stopped,this.debug=!1,this.stateChangeCbs=[];try{const t=window.navigator.mediaDevices.getSupportedConstraints();this.nativeResamplingSupported=!0===t.sampleRate,this.autoGainControlSupported=!0===t.autoGainControl}catch(t){this.nativeResamplingSupported=!1,this.autoGainControlSupported=!1}}onStateChange(t){this.stateChangeCbs.push(t)}initialize(){var i;return a(this,void 0,void 0,(function*(){if(this.initialized)return;if(void 0===(null===(i=window.navigator)||void 0===i?void 0:i.mediaDevices))throw this.setState(t.AudioSourceState.NoBrowserSupport),e;const s={video:!1};this.nativeResamplingSupported||this.autoGainControlSupported?s.audio={sampleRate:n,autoGainControl:this.autoGainControlSupported}:s.audio=!0;try{this.setState(t.AudioSourceState.Starting),this.mediaStream=yield window.navigator.mediaDevices.getUserMedia(s)}catch(e){throw this.setState(t.AudioSourceState.NoAudioConsent),console.error(e),l}this.initialized=!0,this.muted=!0,this.setState(t.AudioSourceState.Started)}))}setState(t){this.state!==t&&(this.debug&&console.log("[BrowserMicrophone]",this.state,"->",t),this.state=t,this.stateChangeCbs.forEach((e=>e(t))))}close(){return a(this,void 0,void 0,(function*(){if(!this.initialized)return;this.muted=!0;this.mediaStream.getTracks().forEach((t=>t.stop())),this.mediaStream=void 0,this.initialized=!1,this.setState(t.AudioSourceState.Stopped)}))}isRecording(){return!this.muted}},t.CloudDecoder=U,t.DecoderDefaultOptions=Z,t.DefaultSampleRate=n,t.ErrAlreadyInitialized=c,t.ErrAlreadyStarted=S,t.ErrAlreadyStopped=X,t.ErrAppIdChangeWithoutProjectLogin=i,t.ErrDeviceNotSupported=e,t.ErrKeyNotFound=m,t.ErrNoAudioConsent=l,t.ErrNoStorageSupport=b,t.ErrNotInitialized=d,t.EventCallbacks=R,t.ListenerArray=W,t.SegmentState=o,t.StreamDefaultOptions=G,t.VadDefaultOptions=y,t.WebsocketError=s,t.stateToString=V,Object.defineProperty(t,"__esModule",{value:!0})}));
//# sourceMappingURL=speechly.umd.min.js.map

@@ -1,3 +0,3 @@

declare type fetchFn = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
declare type nowFn = () => number;
type fetchFn = (input: RequestInfo, init?: RequestInit) => Promise<Response>;
type nowFn = () => number;
export declare const minTokenValidTime: number;

@@ -4,0 +4,0 @@ /**

@@ -166,3 +166,3 @@ import { AudioProcessorParameters, ContextOptions, StreamOptions, VadOptions } from '../client';

*/
export declare type ResponseCallback = (response: WebsocketResponse) => void;
export type ResponseCallback = (response: WebsocketResponse) => void;
/**

@@ -172,3 +172,3 @@ * A callback that is invoked whenever WebSocket connection is closed.

*/
export declare type CloseCallback = (err: WebsocketError) => void;
export type CloseCallback = (err: WebsocketError) => void;
/**

@@ -175,0 +175,0 @@ * The interface for a client for Speechly SLU WebSocket API.

{
"name": "@speechly/browser-client",
"version": "2.6.2",
"description": "Browser client for Speechly API",
"version": "2.6.3",
"description": "Browser client for Speechly Streaming API",
"keywords": [

@@ -6,0 +6,0 @@ "client",

<div align="center" markdown="1">
<a href="https://www.speechly.com">
<img src="https://d33wubrfki0l68.cloudfront.net/f15fc952956e1952d6bd23661b7a7ee6b775faaa/c1b30/img/speechly-logo-duo-black.svg" height="48" />
</a>
<br/>
### Real-time automatic speech recognition and natural language understanding tools in one flexible API
![speechly-logo-duo-black](https://user-images.githubusercontent.com/2579244/193574443-130d16d6-76f1-4401-90f2-0ed753b39bc0.svg)
[Website](https://www.speechly.com/)
&ensp;|&ensp;
&ensp;&middot;&ensp;
[Docs](https://docs.speechly.com/)
&ensp;|&ensp;
[Discussions](https://github.com/speechly/speechly/discussions)
&ensp;|&ensp;
&ensp;&middot;&ensp;
[Support](https://github.com/speechly/speechly/discussions)
&ensp;&middot;&ensp;
[Blog](https://www.speechly.com/blog/)
&ensp;|&ensp;
[Podcast](https://anchor.fm/the-speechly-podcast)
&ensp;&middot;&ensp;
[Login](https://api.speechly.com/dashboard/)
---
<br/>
</div>
# Speechly browser client
# Speechly Browser Client
![Release build](https://github.com/speechly/browser-client/workflows/Release%20build/badge.svg?branch=master&event=release)
[![npm version](https://badge.fury.io/js/%40speechly%2Fbrowser-client.svg)](https://badge.fury.io/js/%40speechly%2Fbrowser-client)
[![License](http://img.shields.io/:license-mit-blue.svg)](LICENSE)
![build](https://img.shields.io/github/actions/workflow/status/speechly/speechly/build.yaml?branch=main&logo=github)
[![npm](https://img.shields.io/npm/v/@speechly/browser-client?color=cb3837&logo=npm)](https://www.npmjs.com/package/@speechly/browser-client)
[![license](http://img.shields.io/:license-mit-blue.svg)](/LICENSE)
> 🚧 Browser Client v2.0 is a breaking change. Read more about the major changes and how to upgrade from our blog: https://speechly.com/blog/speechly-browser-client-v2-released
With the Speechly browser client you can add voice features to any website. It handles authentication, audio capture, network streaming and connection management with the Speechly Streaming API.
With the browser-client you can add voice features to any website. It handles authentication, audio capture, network streaming and connection management with the Speechly Voice API.
If you are using React, you can use the [Speechly React Client](https://github.com/speechly/speechly/tree/main/libraries/react-client) instead. It provides the same functionalities, but provides a programming model that is idiomatic to React.
Check out the [browser-client-example](https://github.com/speechly/speechly/tree/main/examples/browser-client-example) repository for a demo app built using this client.
Check out the [browser client example](https://github.com/speechly/speechly/tree/main/examples/browser-client-example) for an example app built using this client.
NOTE: If you are using React, you can use our [React client](https://github.com/speechly/speechly/tree/main/libraries/react-client) instead. It provides the same functionalities, but provides a programming model that is idiomatic to React.
🚧 Browser client `v2.0` is a breaking change. Read more about the major changes and how to upgrade from [our blog post](https://speechly.com/blog/speechly-browser-client-v2-released).
## API Documentation
- [API documentation (TypeDoc generated)](https://github.com/speechly/speechly/blob/main/libraries/browser-client/docs/classes/client.BrowserClient.md)
## Using in web sites built with eg. rollup

@@ -159,4 +152,5 @@

- [API documentation](https://github.com/speechly/speechly/blob/main/libraries/browser-client/docs/classes/client.BrowserClient.md) in GitHub
- [Basic usage in docs.speechly.com](https://docs.speechly.com/?utm_source=github&utm_medium=browser-client&utm_campaign=text) for more information.
- [API reference](https://github.com/speechly/speechly/blob/main/libraries/browser-client/docs/classes/client.BrowserClient.md) (GitHub)
- [Basic usage](https://dreamy-cori-a02de1.netlify.app/client-libraries/usage/) (Docs)
- [Example application](https://github.com/speechly/speechly/tree/main/examples/browser-client-example)

@@ -163,0 +157,0 @@ ## Contributing

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc