@vidtreo/recorder-wc 1.7.0 → 1.7.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -123,7 +123,7 @@ The @mediabunny/ac3 extension package provides support for encoding and decoding
123
123
  The @mediabunny/flac-encoder extension package provides support for encoding FLAC.`)}else e.push(`
124
124
  Check the discardedTracks field for more info.`)}return e}async execute(){if(!this.isValid)throw Error(`Cannot execute this conversion because its output configuration is invalid. Make sure to always check the isValid field before executing a conversion.
125
125
  `+this._getInvalidityExplanation().join(``));if(this._executed)throw Error(`Conversion cannot be executed twice.`);this._executed=!0;for(let e of this._outputTrackIds)this._synchronizer.declareTrack(e);if(this.onProgress){let e=[...new Set(this.utilizedTracks)].map(async e=>await e.isLive()?1/0:await e.getDurationFromMetadata()??await e.computeDuration()),t=Math.max(0,...await Promise.all(e));this._computeProgress=!0,this._totalDuration=Math.min(t-this._startTimestamp,this._endTimestamp-this._startTimestamp);for(let e of this._outputTrackIds)this._maxTimestamps.set(e,0);this.onProgress?.(0,0)}await this.output.start(),this._start();try{await Promise.all(this._trackPromises)}catch(e){throw this._canceled||this.cancel(),e}if(this._canceled)throw new gv;if(await this.output.finalize(),this._computeProgress){let e=Math.min(...this._maxTimestamps.values());this.onProgress?.(1,e)}}async cancel(){if(!(this.output.state===`finalizing`||this.output.state===`finalized`)){if(this._canceled){console.warn(`Conversion already canceled.`);return}this._canceled=!0,await this.output.cancel()}}async _processVideoTrack(e,t,n){let r=await e.getCodec();if(!r){this.discardedTracks.push({track:e,reason:`unknown_source_codec`,trackOptions:t});return}let i,a=await e.getRotation(),o=Bn(a+(t.rotate??0)),s=o,c=this.output.format.supportsVideoRotationMetadata&&(t.allowRotationMetadata??!0),l=await e.getSquarePixelWidth(),u=await e.getSquarePixelHeight(),[d,f]=o%180==0?[l,u]:[u,l],p=t.crop;p&&=Ad(p,d,f);let[m,h]=p?[p.width,p.height]:[d,f],g=m,_=h,v=g/_;t.width!==void 0&&t.height===void 0?(g=_i(t.width),_=_i(Math.round(g/v))):t.width===void 0&&t.height!==void 0?(_=_i(t.height),g=_i(Math.round(_*v))):t.width!==void 0&&t.height!==void 0&&(g=_i(t.width),_=_i(t.height));let y=await e.getFirstTimestamp(),b=this.output.format.getSupportedVideoCodecs(),x=!!t.forceTranscode||y<this._startTimestamp||!!t.frameRate||t.keyFrameInterval!==void 0||t.process!==void 0||t.bitrate!==void 0||!b.includes(r)||t.codec&&t.codec!==r||g!==m||_!==h||o!==0&&!c||!!p,S=t.alpha??`discard`;if(x){if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`,trackOptions:t});return}t.codec&&(b=b.filter(e=>e===t.codec));let r=t.bitrate??uf,d=await bf(b,{width:t.process&&t.processedWidth?t.processedWidth:g,height:t.process&&t.processedHeight?t.processedHeight:_,bitrate:r});if(!d){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`,trackOptions:t});return}let f={codec:d,bitrate:r,keyFrameInterval:t.keyFrameInterval,sizeChangeBehavior:t.fit??`passThrough`,alpha:S,hardwareAcceleration:t.hardwareAcceleration,transform:{}};D(f.transform);let v=g!==m||_!==h||o!==0&&(!c||t.process!==void 0)||!!p||l!==await e.getCodedWidth()||u!==await e.getCodedHeight();if(!v){let t=new lv({format:new U_,target:new vg}),n=new g_(f);t.addVideoTrack(n),await t.start();let r=await new Zf(e).getSample(y);if(r)try{await n.add(r),r.close(),await t.finalize()}catch(e){console.info(`Error when probing encoder support. Falling back to rerender path.`,e),v=!0,t.cancel()}else await t.cancel()}t.frameRate&&(f.transform.frameRate=t.frameRate),v&&(s=0,f.transform.width=g,f.transform.height=_,f.transform.fit=t.fit??`fill`,f.transform.rotate=Bn(o-a),f.transform.crop=p,f.transform.alpha=S);let x=new g_(f);i=x,this._trackPromises.push((async()=>{await this._started;let r=new Zf(e);for await(let e of r.samples(this._startTimestamp,this._endTimestamp)){if(this._canceled){e.close();return}let r=Math.max(e.timestamp-this._startTimestamp,0);e.setTimestamp(r),await this._registerVideoSample(t,n,x,e),e.close()}x.close(),this._synchronizer.closeTrack(n)})())}else{let t=new d_(r);i=t,this._trackPromises.push((async()=>{await this._started;let r=new Uf(e),i={decoderConfig:await e.getDecoderConfig()??void 0};for await(let e of r.packets(void 0,void 0,{verifyKeyPackets:!0})){if(this._canceled)return;if(e.timestamp>=this._endTimestamp)break;let r=e.clone({timestamp:e.timestamp-this._startTimestamp,sideData:S===`discard`?{}:e.sideData});D(r.timestamp>=0),this._reportProgress(n,r.timestamp+r.duration),await t.add(r,i),this._synchronizer.shouldWait(n,r.timestamp)&&await this._synchronizer.wait(r.timestamp)}t.close(),this._synchronizer.closeTrack(n)})())}let C=null;t.group||(C=new sv);let ee=await e.getLanguageCode();this.output.addVideoTrack(i,{frameRate:t.frameRate,languageCode:kr(ee)?ee:void 0,name:await e.getName()??void 0,disposition:await e.getDisposition(),rotation:s,group:C??t.group}),this._addedCounts.video++,this._totalTrackCount++,this.utilizedTracks.push(e),this._outputTrackIds.push(n),this._outputOwnTrackGroups.push(C)}async _registerVideoSample(e,t,n,r){if(this._canceled)return;this._reportProgress(t,r.timestamp+r.duration);let i;if(!e.process)i=[r];else{let t=e.process(r);t instanceof Promise&&(t=await t),Array.isArray(t)||(t=t===null?[]:[t]),i=t.map(e=>e instanceof Sd?e:typeof VideoFrame<`u`&&e instanceof VideoFrame?new Sd(e):new Sd(e,{timestamp:r.timestamp,duration:r.duration}))}try{for(let e of i){if(this._canceled)break;await n.add(e),this._synchronizer.shouldWait(t,e.timestamp)&&await this._synchronizer.wait(e.timestamp)}}finally{for(let e of i)e!==r&&e.close()}}async _processAudioTrack(e,t,n){let r=await e.getCodec();if(!r){this.discardedTracks.push({track:e,reason:`unknown_source_codec`,trackOptions:t});return}let i,a=await e.getNumberOfChannels(),o=await e.getSampleRate(),s=await e.getFirstTimestamp(),c=t.numberOfChannels??a,l=t.sampleRate??o,u=c!==a||l!==o||s<this._startTimestamp||s>this._startTimestamp&&!this.output.format.supportsTimestampedMediaData,d=this.output.format.getSupportedAudioCodecs();if(!t.forceTranscode&&!t.bitrate&&!u&&d.includes(r)&&(!t.codec||t.codec===r)&&!t.process&&t.sampleFormat===void 0){let t=new b_(r);i=t,this._trackPromises.push((async()=>{await this._started;let r=new Uf(e),i={decoderConfig:await e.getDecoderConfig()??void 0};for await(let e of r.packets()){if(this._canceled)return;if(e.timestamp>=this._endTimestamp)break;let r=e.clone({timestamp:e.timestamp-this._startTimestamp});D(r.timestamp>=0),this._reportProgress(n,r.timestamp+r.duration),await t.add(r,i),this._synchronizer.shouldWait(n,r.timestamp)&&await this._synchronizer.wait(r.timestamp)}t.close(),this._synchronizer.closeTrack(n)})())}else{if(!await e.canDecode()){this.discardedTracks.push({track:e,reason:`undecodable_source_codec`,trackOptions:t});return}let r=null;t.codec&&(d=d.filter(e=>e===t.codec));let a=t.bitrate??uf,o=await vf(d,{numberOfChannels:t.process&&t.processedNumberOfChannels?t.processedNumberOfChannels:c,sampleRate:t.process&&t.processedSampleRate?t.processedSampleRate:l,bitrate:a});if(!o.some(e=>Ii.includes(e))&&d.some(e=>Ii.includes(e))&&(c!==pv||l!==mv)){let e=(await vf(d,{numberOfChannels:pv,sampleRate:mv,bitrate:a})).find(e=>Ii.includes(e));e&&(u=!0,r=e,c=pv,l=mv)}else r=o[0]??null;if(r===null){this.discardedTracks.push({track:e,reason:`no_encodable_target_codec`,trackOptions:t});return}if(u)i=this._resampleAudio(e,t,n,r,c,l,a);else{let o=new S_({codec:r,bitrate:a});i=o,this._trackPromises.push((async()=>{await this._started;let r=new tp(e);for await(let e of r.samples(void 0,this._endTimestamp)){if(this._canceled){e.close();return}e.setTimestamp(e.timestamp-this._startTimestamp),await this._registerAudioSample(t,n,o,e),e.close()}o.close(),this._synchronizer.closeTrack(n)})())}}let f=null;t.group||(f=new sv);let p=await e.getLanguageCode();this.output.addAudioTrack(i,{languageCode:kr(p)?p:void 0,name:await e.getName()??void 0,disposition:await e.getDisposition(),group:f??t.group}),this._addedCounts.audio++,this._totalTrackCount++,this.utilizedTracks.push(e),this._outputTrackIds.push(n),this._outputOwnTrackGroups.push(f)}async _registerAudioSample(e,t,n,r){if(this._canceled)return;let i=r;e.sampleFormat!==void 0&&qd(i.format)!==e.sampleFormat&&(i=Yd(i,e.sampleFormat)),this._reportProgress(t,i.timestamp+i.duration);let a;if(!e.process)a=[i];else{let t=e.process(i);if(t instanceof Promise&&(t=await t),Array.isArray(t)||(t=t===null?[]:[t]),!t.every(e=>e instanceof Vd))throw TypeError(`The audio process function must return an AudioSample, null, or an array of AudioSamples.`);a=t}try{for(let e of a){if(this._canceled)break;await n.add(e),this._synchronizer.shouldWait(t,e.timestamp)&&await this._synchronizer.wait(e.timestamp)}}finally{i!==r&&i.close();for(let e of a)e!==r&&e.close()}}_resampleAudio(e,t,n,r,i,a,o){let s=new S_({codec:r,bitrate:o});return this._trackPromises.push((async()=>{await this._started;let r=new o_({targetNumberOfChannels:i,targetSampleRate:a,startTime:this._startTimestamp,endTime:this._endTimestamp,onSample:async e=>{D(e.timestamp>=this._startTimestamp),e.setTimestamp(e.timestamp-this._startTimestamp),await this._registerAudioSample(t,n,s,e),e.close()}}),o=new tp(e).samples(this._startTimestamp,this._endTimestamp);for await(let e of o){if(this._canceled){e.close();return}await r.add(e),e.close()}await r.finalize(),s.close(),this._synchronizer.closeTrack(n)})()),s}_reportProgress(e,t){if(!this._computeProgress)return;D(this._totalDuration!==null),this._maxTimestamps.set(e,Math.max(t,this._maxTimestamps.get(e)));let n=Math.min(...this._maxTimestamps.values()),r=br(n/this._totalDuration,0,1);r!==this._lastProgress&&(this._lastProgress=r,this.onProgress?.(r,n))}},gv=class extends Error{constructor(e=`Conversion has been canceled.`){super(e),this.name=`ConversionCanceledError`}},_v=1,vv=class{constructor(){this.maxTimestamps=new Map,this.resolvers=[]}declareTrack(e){this.maxTimestamps.set(e,0)}shouldWait(e,t){let n=this.maxTimestamps.get(e);return D(n!==void 0),this.maxTimestamps.set(e,Math.max(t,n)),t-this.computeMinAndMaybeResolve()>_v}wait(e){let{promise:t,resolve:n}=P();return this.resolvers.push({timestamp:e,resolve:n}),t}closeTrack(e){this.maxTimestamps.delete(e),this.computeMinAndMaybeResolve()}computeMinAndMaybeResolve(){let e=1/0;for(let[,t]of this.maxTimestamps)e=Math.min(e,t);for(let t=0;t<this.resolvers.length;t++){let n=this.resolvers[t];n.timestamp-e<_v&&(n.resolve(),this.resolvers.splice(t,1),t--)}return e}}})),bv=r({ADTS:()=>Yu,ALL_FORMATS:()=>$u,ALL_TRACK_TYPES:()=>nv,AUDIO_CODECS:()=>Li,AdtsInputFormat:()=>zu,AdtsOutputFormat:()=>Z_,AppendOnlyStreamTarget:()=>gg,AttachedFile:()=>xi,AudioBufferSink:()=>np,AudioBufferSource:()=>C_,AudioSample:()=>Vd,AudioSampleResource:()=>Bd,AudioSampleSink:()=>tp,AudioSampleSource:()=>S_,AudioSource:()=>y_,BaseMediaSampleSink:()=>Gf,BlobSource:()=>ru,BufferSource:()=>nu,BufferTarget:()=>fg,CanvasSink:()=>Qf,CanvasSource:()=>__,CmafOutputFormat:()=>W_,ConcurrentRunner:()=>vi,Conversion:()=>hv,ConversionCanceledError:()=>gv,CustomAudioDecoder:()=>Tf,CustomAudioEncoder:()=>Df,CustomPathedSource:()=>tu,CustomVideoDecoder:()=>wf,CustomVideoEncoder:()=>Ef,EncodedAudioPacketSource:()=>b_,EncodedPacket:()=>R,EncodedPacketSink:()=>Uf,EncodedVideoPacketSource:()=>d_,EventEmitter:()=>gi,FLAC:()=>Xu,FilePathSource:()=>cu,FilePathTarget:()=>_g,FlacInputFormat:()=>Ru,FlacOutputFormat:()=>Q_,HLS:()=>Qu,HLS_FORMATS:()=>ed,HlsInputFormat:()=>Vu,HlsOutputFormat:()=>ev,Input:()=>vp,InputAudioTrack:()=>sp,InputDisposedError:()=>bp,InputFormat:()=>ku,InputTrack:()=>ip,InputVideoTrack:()=>op,IsobmffInputFormat:()=>Au,IsobmffOutputFormat:()=>H_,MATROSKA:()=>Wu,MP3:()=>Ku,MP4:()=>Hu,MPEG_TS:()=>Zu,MatroskaInputFormat:()=>Nu,MediaSource:()=>c_,MediaStreamAudioTrackSource:()=>w_,MediaStreamVideoTrackSource:()=>v_,MkvOutputFormat:()=>K_,MovOutputFormat:()=>G_,Mp3InputFormat:()=>Fu,Mp3OutputFormat:()=>J_,Mp4InputFormat:()=>ju,Mp4OutputFormat:()=>U_,MpegTsInputFormat:()=>Bu,MpegTsOutputFormat:()=>$_,NON_PCM_AUDIO_CODECS:()=>Ii,NullTarget:()=>vg,OGG:()=>Ju,OggInputFormat:()=>Lu,OggOutputFormat:()=>X_,Output:()=>lv,OutputAudioTrack:()=>av,OutputFormat:()=>V_,OutputSubtitleTrack:()=>ov,OutputTrack:()=>rv,OutputTrackGroup:()=>sv,OutputVideoTrack:()=>iv,PCM_AUDIO_CODECS:()=>Fi,PathedSource:()=>$l,PathedTarget:()=>bg,QTFF:()=>Uu,QUALITY_HIGH:()=>uf,QUALITY_LOW:()=>cf,QUALITY_MEDIUM:()=>lf,QUALITY_VERY_HIGH:()=>df,QUALITY_VERY_LOW:()=>sf,Quality:()=>of,QuickTimeInputFormat:()=>Mu,RangedSource:()=>pu,RangedTarget:()=>yg,ReadableStreamSource:()=>uu,RichImageData:()=>bi,SUBTITLE_CODECS:()=>Ri,Source:()=>Zl,SourceRef:()=>Ql,StreamSource:()=>lu,StreamTarget:()=>hg,SubtitleSource:()=>M_,Target:()=>lg,TextSubtitleSource:()=>N_,UnsupportedInputFormatError:()=>yp,UrlSource:()=>su,VIDEO_CODECS:()=>L,VIDEO_SAMPLE_PIXEL_FORMATS:()=>bd,VideoSample:()=>Sd,VideoSampleColorSpace:()=>Od,VideoSampleResource:()=>yd,VideoSampleSink:()=>Zf,VideoSampleSource:()=>g_,VideoSource:()=>l_,WAVE:()=>qu,WEBM:()=>Gu,WavOutputFormat:()=>Y_,WaveInputFormat:()=>Iu,WebMInputFormat:()=>Pu,WebMOutputFormat:()=>q_,asc:()=>cp,canDecode:()=>sd,canDecodeAudio:()=>ld,canDecodeVideo:()=>cd,canEncode:()=>ff,canEncodeAudio:()=>mf,canEncodeSubtitles:()=>hf,canEncodeVideo:()=>pf,desc:()=>lp,getDecodableAudioCodecs:()=>fd,getDecodableCodecs:()=>ud,getDecodableVideoCodecs:()=>dd,getEncodableAudioCodecs:()=>vf,getEncodableCodecs:()=>gf,getEncodableSubtitleCodecs:()=>yf,getEncodableVideoCodecs:()=>_f,getFirstEncodableAudioCodec:()=>xf,getFirstEncodableSubtitleCodec:()=>Sf,getFirstEncodableVideoCodec:()=>bf,prefer:()=>up,registerDecoder:()=>Mf,registerEncoder:()=>Nf,registerVideoSampleTransformer:()=>wd}),xv,Sv=n((()=>{uv(),tv(),P_(),ma(),pd(),Cf(),xg(),F(),mu(),nd(),xp(),mp(),Lo(),Xd(),rp(),yv(),Pf(),Ei(),xv=Symbol.for(`mediabunny loaded`),globalThis[xv]&&console.error(`[WARNING]
126
- Mediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly.`),globalThis[xv]=!0}));Sv();async function Cv(e){try{let t=new ru(e),n=new vp({formats:[Hu],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return wv(e)}}function wv(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}let Tv=[`video/mp4`,`video/quicktime`,`video/webm`];async function Ev(e,t={}){let n=t.maxFileSize===void 0?524288e3:t.maxFileSize;if(e.size>n)return{valid:!1,error:`File too large. Maximum size is ${Math.round(n/1024/1024)}MB`};let r=t.allowedFormats===void 0?Tv:t.allowedFormats;if(!r.includes(e.type))return{valid:!1,error:`Unsupported format. Please use: ${r.join(`, `)}`};let a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)return{valid:!1,error:`Failed to read video file: ${a.error}`};let o=a.duration;return t.maxRecordingTime!==null&&t.maxRecordingTime!==void 0&&o>t.maxRecordingTime?{valid:!1,error:`Video too long. Maximum duration is ${t.maxRecordingTime} seconds`}:{valid:!0}}let Dv=`unknown`;function Ov(){if(typeof navigator>`u`)return null;let e=navigator;return{userAgent:e.userAgent,platform:e.platform,hardwareConcurrency:e.hardwareConcurrency,deviceMemory:e.deviceMemory,onLine:e.onLine,connection:e.connection}}function kv(){return globalThis.isSecureContext===!0}function Av(){return globalThis.MediaRecorder!==void 0}function jv(){return globalThis.VideoEncoder!==void 0}function Mv(){return typeof navigator>`u`?null:navigator.mediaCapabilities}function Nv(e){let t=e.toLowerCase();return t.startsWith(`avc1`)||t.startsWith(`av01`)||t.startsWith(`hvc1`)||t.startsWith(`hev1`)?`video/mp4;codecs="${e}"`:t===`vp8`||t.startsWith(`vp09`)||t.startsWith(`vp9`)?`video/webm;codecs="${e}"`:null}function Pv(e){let t=Mv();if(!t)return Promise.resolve(null);let n=Nv(e.codec);return n===null||typeof e.bitrate!=`number`||typeof e.framerate!=`number`?Promise.resolve(null):t.encodingInfo({type:`record`,video:{contentType:n,width:e.width,height:e.height,bitrate:e.bitrate,framerate:e.framerate}})}function Fv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Iv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Fv,encodingCapabilityProbe:e?.encodingCapabilityProbe??Pv}}function Lv(e){let t=new wt(e??``).getResult(),n=t.browser.name??Dv;return{browser:{name:n,version:t.browser.version??``,normalizedName:n.toLowerCase()},os:{name:t.os.name??Dv,version:t.os.version??``}}}function Rv(e){return e instanceof Error?e.message:String(e)}async function zv(e,t,n){try{let r=await t(e.config),i=await Bv(e.config,n),a={id:e.id,config:e.config,supported:r.supported===!0};return i===void 0?a:{...a,encodingCapability:i}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Rv(t)}}}function Bv(e,t){return Promise.resolve().then(()=>t(e)).then(e=>{if(e!==null)return{supported:e.supported===!0,smooth:e.smooth===!0,powerEfficient:e.powerEfficient===!0}}).catch(e=>({supported:!1,smooth:!1,powerEfficient:!1,errorCode:`encoding-capability-probe-error`,errorMessage:Rv(e)}))}async function Vv(e={}){let t=Iv(e.dependencies),{browser:n,os:r}=Lv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>zv(e,t.codecSupportProbe,t.encodingCapabilityProbe)));return{browser:n,os:r,resources:{deviceMemory:t.navigatorProvider?.deviceMemory,hardwareConcurrency:t.navigatorProvider?.hardwareConcurrency},network:{online:t.navigatorProvider?.onLine,effectiveType:t.navigatorProvider?.connection?.effectiveType},features:{isSecureContext:t.secureContextProvider(),hasMediaRecorder:t.mediaRecorderAvailabilityProvider(),hasVideoEncoder:t.videoEncoderAvailabilityProvider()},codecProbeResults:i}}function Hv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function Uv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Wv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)}function Gv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Kv(e,t,n,r,i,a,o){let s=[];return e.features.isSecureContext||s.push(`insecure-context`),e.features.hasVideoEncoder||s.push(`webcodecs-unavailable`),t||s.push(`target-codec-unsupported`),n||s.push(`insufficient-device-memory`),r||s.push(`insufficient-hardware-concurrency`),i||s.push(`encoding-capability-unsupported`),a||s.push(`encoding-not-smooth`),o||s.push(`encoding-not-power-efficient`),s}function qv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Jv(e){return e.os.name.toLowerCase().includes(`android`)}function Yv(e,t){let n=[...t];return Jv(e)&&n.push(`android-post-recording-transcode`),n.push(`mediarecorder-supported`),n}function Xv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported===!0}function Zv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.smooth===!0}function Qv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.powerEfficient===!0}function $v(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??5,r=Wv(e.profile,e.targetCodecIds),i=r?.id,a=i!==void 0,o=Hv(e.profile,t),s=Uv(e.profile,n),c=Xv(r),l=Zv(r),u=Qv(r),d=Kv(e.profile,a,o,s,c,l,u);return Jv(e.profile)&&Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&a&&e.profile.network.online!==!1&&o&&s&&c&&l&&u?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:i}:Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:{route:`unsupported-with-guidance`,reasonCodes:[...d,...qv(e.profile)],guidance:{canRetry:!0,message:`Recording is not supported in this browser context. Use a secure connection, go online, and try a current Chrome or Edge browser.`}}}let ey=[`prefer-hardware`,`no-preference`,`prefer-software`];async function ty(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let ny={loadMediabunnyModule:ty};function ry(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?ny.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function iy(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function ay(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=iy(n,e);return n}function oy(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=iy(n,e);return n}function sy(e,t,n){let r=Error(`No encodable video codec available for format: ${e}`);return r.code=`recording.video-codec-unavailable`,r.details={candidates:t,format:e,probeErrors:n},r}async function cy(e,t,n){try{return await e(t,n)?{kind:`supported`,codec:t}:{kind:`unsupported`,codec:t}}catch(e){return{kind:`error`,codec:t,error:e}}}async function ly(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=ay(e.overrideCodec,e.policy),a={};e.width!==void 0&&(a.width=e.width),e.height!==void 0&&(a.height=e.height),e.bitrate!==void 0&&(a.bitrate=e.bitrate);let o=[];for(let e of ey){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>cy(n,e,t)));o.push(...i);for(let e of i)if(e.kind===`supported`)return e.codec}let s=o.filter(e=>e.kind===`error`).map(e=>`${e.codec}: ${i(e.error)}`);if(e.dependencies?.loadMediabunnyModule===void 0&&s.length===0&&typeof VideoEncoder>`u`)return e.policy.preferredVideoCodec;throw sy(e.format,r,s)}async function uy(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=oy(e.overrideCodec,e.policy),i={};e.bitrate!==void 0&&(i.bitrate=e.bitrate);let a=(await Promise.allSettled([n(r,i)]))[0];if(a.status===`rejected`)return e.policy.preferredAudioCodec;let o=a.value;if(o===null){if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}if(r.includes(o))return o;if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}function dy(e){switch(e){case`mp4`:return`video/mp4`;case`webm`:return`video/webm`;case`mkv`:return`video/x-matroska`;case`mov`:return`video/quicktime`;default:throw Error(`Unsupported output format: ${e}`)}}function fy(e){switch(e){case`mp4`:return`mp4`;case`webm`:return`webm`;case`mkv`:return`mkv`;case`mov`:return`mov`;default:throw Error(`Unsupported output format: ${e}`)}}Sv();function py(e){if(typeof e==`string`)return new cu(e);if(e instanceof Blob)return new ru(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function my(e){switch(e){case`mp4`:return new U_;case`webm`:return new q_;case`mkv`:return new K_;case`mov`:return new G_;default:throw Error(`Unsupported output format: ${e}`)}}function hy(e,t=!1){let n={fit:`contain`,forceTranscode:!0,allowRotationMetadata:!1};return e.width!==void 0&&(n.width=e.width),e.height!==void 0&&(n.height=e.height),e.fps!==void 0&&(n.frameRate=e.fps),e.bitrate!==void 0&&(n.bitrate=e.bitrate),e.codec!==void 0&&(n.codec=e.codec),t&&(n.bitrateMode=`variable`,n.latencyMode=`realtime`,n.hardwareAcceleration=`prefer-hardware`,n.keyFrameInterval=2),{video:n,audio:{codec:e.audioCodec,forceTranscode:!0,...t&&{bitrateMode:`variable`}}}}function gy(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function _y(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=py(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await uy({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new vp({formats:$u,source:a}),c=new lv({format:my(i.format),target:new fg}),l=await hv.init({input:s,output:c,...hy(i)});gy(l),n&&(l.onProgress=n),await l.execute();let u=c.target.buffer;if(!u)throw Error(`Transcoding completed but no output buffer was generated`);let d=dy(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function vy(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await uy({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new vp({formats:$u,source:new ru(e)}),s=new lv({format:my(i.format),target:new fg}),c=await hv.init({input:o,output:s,video:{codec:i.codec,width:i.width,height:i.height,frameRate:i.fps,bitrate:i.bitrate,fit:`contain`,allowRotationMetadata:!1},audio:{codec:i.audioCodec}});gy(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);let u=dy(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function yy(e,t=1e4){return new Promise((n,r)=>{let i=document.createElement(`video`);i.preload=`metadata`,i.muted=!0;let a=setTimeout(()=>{o(),r(Error(`Preview extraction timeout`))},t),o=()=>{clearTimeout(a),URL.revokeObjectURL(i.src)};i.addEventListener(`loadedmetadata`,()=>{i.currentTime=Math.max(0,i.duration-.1)}),i.addEventListener(`seeked`,()=>{let e=document.createElement(`canvas`);e.width=i.videoWidth,e.height=i.videoHeight;let t=e.getContext(`2d`);if(!t){o(),r(Error(`Canvas context unavailable`));return}if(i.videoWidth===0||i.videoHeight===0){o(),r(Error(`Invalid video dimensions`));return}if(!(Number.isFinite(i.videoWidth)&&Number.isFinite(i.videoHeight))){o(),r(Error(`Invalid video dimensions`));return}t.drawImage(i,0,0,e.width,e.height),e.toBlob(e=>{o(),e?n(e):r(Error(`Failed to create preview blob`))},`image/jpeg`,.8)}),i.addEventListener(`error`,()=>{o(),r(Error(`Failed to load video for preview extraction`))}),i.src=URL.createObjectURL(e)})}var by=class{constructor(e,t,n){this.pendingFile=null,this.configService=null,this.config=e,this.configService=t,this.uploadService=n}async handleFileSelection(e){let t=await Ev(e,{maxFileSize:this.config.maxFileSize===void 0?2*1024*1024*1024:this.config.maxFileSize,maxRecordingTime:this.config.maxRecordingTime,allowedFormats:[`video/mp4`,`video/quicktime`,`video/webm`]});if(!t.valid)throw Error(t.error);let n=await yy(e),r=URL.createObjectURL(n),a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)throw Error(`Failed to extract video duration: ${a.error}`);let o=a.duration;return this.pendingFile=e,{file:e,previewUrl:r,duration:o,validated:!0}}async processAndUpload(e,t){if(!this.pendingFile)throw Error(`No file selected`);let n=this.configService?await this.configService.fetchConfig():Xt,r=await this.resolveNativeCameraRouteDecision(n);if(r.route===`unsupported-with-guidance`)throw Error(r.guidance?.message??`This browser or device cannot safely process this video. Try another browser or upload from a different device.`);let i=(await vy(this.pendingFile,n,e)).blob;if(!(this.config.apiKey&&this.config.backendUrl))throw Error(`Upload requires API key and backend URL`);let a=await this.uploadService.uploadVideo(i,{apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,filename:this.resolveUploadFilename(i),userMetadata:this.config.userMetadata,onProgress:t});return this.pendingFile=null,{blob:i,recordingId:a.id,uploadUrl:a.uploadUrl||``}}async resolveNativeCameraRouteDecision(e){let t=this.buildCodecProbeCandidates(e);return $v({profile:await Vv({codecCandidates:t}),targetCodecIds:t.map(e=>e.id)})}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}resolveUploadFilename(e){let t=this.resolveUploadExtension(e.type);return`${Date.now()}.${t}`}resolveUploadExtension(e){switch(e){case`video/webm`:return`webm`;case`video/quicktime`:return`mov`;default:return`mp4`}}cancel(){this.pendingFile=null}async preloadConfig(){this.configService&&await this.configService.fetchConfig()}};let xy={isLinuxPlatform:on()};Ht(`mp4`,xy).preferredAudioCodec,Ht(`mov`,xy).preferredAudioCodec,Ht(`mkv`,xy).preferredAudioCodec,Ht(`webm`,xy).preferredAudioCodec;let Sy=`recording.invalid-container-layout`,Cy=`recording.no-video-track`,wy=`recording.no-audio-track`,Ty=`moov`,Ey=`trak`,Dy=`stsz`,Oy=`soun`;function ky(e){return e>=6e3&&e<=384e3}function Ay(e){let t=Error(Sy);return t.code=Sy,t.detectedBoxTypes=e,t}function jy(e){let t=Error(e);return t.code=e,t}function My(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function Ny(e,t){let n=e.getUint8(t),r=e.getUint8(t+1),i=e.getUint8(t+2),a=e.getUint8(t+3);return String.fromCharCode(n,r,i,a)}function Py(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Fy(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Iy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(i.map(e=>e.type));let l=a+s;i.push({type:t,size:o,startOffset:a,endOffset:c,payloadStartOffset:l}),a=c}return i}function Ly(e,t){for(let n of e)if(n.type===t)return n;return null}function Ry(e,t,n){if(!(t+4<=n))throw Ay([]);return Ny(e,t)}function zy(e,t){let n=Ly(t,`mdhd`);if(n===null||n.endOffset-n.payloadStartOffset<16||e.getUint8(n.payloadStartOffset)!==0)return 0;let r=n.payloadStartOffset+8,i=n.payloadStartOffset+12,a=e.getUint32(r,!1),o=e.getUint32(i,!1);return a===0?0:o/a}function By(e,t){let n=Ly(t,`stsd`);if(n===null)return{channelCount:0,sampleRate:0};let r=n.payloadStartOffset+4+4+8;if(r+28>n.endOffset)return{channelCount:0,sampleRate:0};let i=e.getUint16(r+16,!1),a=e.getUint32(r+24,!1);return{channelCount:i,sampleRate:Math.floor(a/65536)}}function Vy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=Ly(Iy(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Iy(e,i.payloadStartOffset,i.endOffset),o=Ly(a,`hdlr`);if(o===null||Ry(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=zy(r,a),c=Ly(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=Ly(Iy(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Iy(e,l.payloadStartOffset,l.endOffset),d=Ly(u,Dy);if(d===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let f=d.payloadStartOffset+8;if(!(f+4<=d.endOffset))throw Ay([Dy]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===Oy?By(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function Hy(e){let t=My(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Uy(e){let t=Hy(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw Ay(Fy(t))}function Wy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(Cy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(Cy);let i=!1;for(let e of r){let n=Vy(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw jy(i?`recording.no-video-frames`:Cy)}function Gy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(wy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(wy);let i=!1;for(let e of r){let n=Vy(t,e,Oy);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw jy(`recording.audio-zero-channels`);if(!ky(n.sampleRate))throw jy(`recording.audio-invalid-sample-rate`);return}}throw jy(i?`recording.no-audio-frames`:wy)}function Ky(){return new Blob([`"use strict";
126
+ Mediabunny was loaded twice. This will likely cause Mediabunny not to work correctly. Check if multiple dependencies are importing different versions of Mediabunny, or if something is being bundled incorrectly.`),globalThis[xv]=!0}));Sv();async function Cv(e){try{let t=new ru(e),n=new vp({formats:[Hu],source:t});if(typeof n.computeDuration!=`function`)throw Error(`computeDuration method is not available`);let r=await n.computeDuration();if(!r)throw Error(`Duration is missing from computeDuration`);if(r<=0)throw Error(`Invalid duration: must be greater than 0`);return r}catch{return wv(e)}}function wv(e){return new Promise((t,n)=>{let r=document.createElement(`video`),i=URL.createObjectURL(e),a=()=>{URL.revokeObjectURL(i)};r.addEventListener(`loadedmetadata`,()=>{a();let e=r.duration;if(!Number.isFinite(e)||e<=0){n(Error(`Invalid video duration`));return}t(e)}),r.addEventListener(`error`,()=>{a(),n(Error(`Failed to load video metadata`))}),r.src=i,r.load()})}let Tv=[`video/mp4`,`video/quicktime`,`video/webm`];async function Ev(e,t={}){let n=t.maxFileSize===void 0?524288e3:t.maxFileSize;if(e.size>n)return{valid:!1,error:`File too large. Maximum size is ${Math.round(n/1024/1024)}MB`};let r=t.allowedFormats===void 0?Tv:t.allowedFormats;if(!r.includes(e.type))return{valid:!1,error:`Unsupported format. Please use: ${r.join(`, `)}`};let a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)return{valid:!1,error:`Failed to read video file: ${a.error}`};let o=a.duration;return t.maxRecordingTime!==null&&t.maxRecordingTime!==void 0&&o>t.maxRecordingTime?{valid:!1,error:`Video too long. Maximum duration is ${t.maxRecordingTime} seconds`}:{valid:!0}}let Dv=`unknown`;function Ov(){if(typeof navigator>`u`)return null;let e=navigator;return{userAgent:e.userAgent,platform:e.platform,hardwareConcurrency:e.hardwareConcurrency,deviceMemory:e.deviceMemory,onLine:e.onLine,connection:e.connection}}function kv(){return globalThis.isSecureContext===!0}function Av(){return globalThis.MediaRecorder!==void 0}function jv(){return globalThis.VideoEncoder!==void 0}function Mv(){return typeof navigator>`u`?null:navigator.mediaCapabilities}function Nv(e){let t=e.toLowerCase();return t.startsWith(`avc1`)||t.startsWith(`av01`)||t.startsWith(`hvc1`)||t.startsWith(`hev1`)?`video/mp4;codecs="${e}"`:t===`vp8`||t.startsWith(`vp09`)||t.startsWith(`vp9`)?`video/webm;codecs="${e}"`:null}function Pv(e){let t=Mv();if(!t)return Promise.resolve(null);let n=Nv(e.codec);return n===null||typeof e.bitrate!=`number`||typeof e.framerate!=`number`?Promise.resolve(null):t.encodingInfo({type:`record`,video:{contentType:n,width:e.width,height:e.height,bitrate:e.bitrate,framerate:e.framerate}})}function Fv(e){return globalThis.VideoEncoder===void 0?Promise.resolve({config:e,supported:!1}):globalThis.VideoEncoder.isConfigSupported(e)}function Iv(e){return{navigatorProvider:e?.navigatorProvider??Ov(),secureContextProvider:e?.secureContextProvider??kv,mediaRecorderAvailabilityProvider:e?.mediaRecorderAvailabilityProvider??Av,videoEncoderAvailabilityProvider:e?.videoEncoderAvailabilityProvider??jv,codecSupportProbe:e?.codecSupportProbe??Fv,encodingCapabilityProbe:e?.encodingCapabilityProbe??Pv}}function Lv(e){let t=new wt(e??``).getResult(),n=t.browser.name??Dv;return{browser:{name:n,version:t.browser.version??``,normalizedName:n.toLowerCase()},os:{name:t.os.name??Dv,version:t.os.version??``}}}function Rv(e){return e instanceof Error?e.message:String(e)}async function zv(e,t,n){try{let r=await t(e.config),i=await Bv(e.config,n),a={id:e.id,config:e.config,supported:r.supported===!0};return i===void 0?a:{...a,encodingCapability:i}}catch(t){return{id:e.id,config:e.config,supported:!1,errorCode:`codec-probe-error`,errorMessage:Rv(t)}}}function Bv(e,t){return Promise.resolve().then(()=>t(e)).then(e=>{if(e!==null)return{supported:e.supported===!0,smooth:e.smooth===!0,powerEfficient:e.powerEfficient===!0}}).catch(e=>({supported:!1,smooth:!1,powerEfficient:!1,errorCode:`encoding-capability-probe-error`,errorMessage:Rv(e)}))}async function Vv(e={}){let t=Iv(e.dependencies),{browser:n,os:r}=Lv(t.navigatorProvider?.userAgent),i=await Promise.all((e.codecCandidates??[]).map(e=>zv(e,t.codecSupportProbe,t.encodingCapabilityProbe)));return{browser:n,os:r,resources:{deviceMemory:t.navigatorProvider?.deviceMemory,hardwareConcurrency:t.navigatorProvider?.hardwareConcurrency},network:{online:t.navigatorProvider?.onLine,effectiveType:t.navigatorProvider?.connection?.effectiveType},features:{isSecureContext:t.secureContextProvider(),hasMediaRecorder:t.mediaRecorderAvailabilityProvider(),hasVideoEncoder:t.videoEncoderAvailabilityProvider()},codecProbeResults:i}}function Hv(e,t){let n=e.resources.deviceMemory;return n===void 0||n>=t}function Uv(e,t){let n=e.resources.hardwareConcurrency;return n===void 0||n>=t}function Wv(e,t){let n=new Set(t);return e.codecProbeResults.find(e=>n.has(e.id)&&e.supported)}function Gv(e,t){return e.features.isSecureContext&&e.features.hasMediaRecorder&&e.features.hasVideoEncoder&&t&&e.network.online!==!1}function Kv(e,t,n,r,i,a,o){let s=[];return e.features.isSecureContext||s.push(`insecure-context`),e.features.hasVideoEncoder||s.push(`webcodecs-unavailable`),t||s.push(`target-codec-unsupported`),n||s.push(`insufficient-device-memory`),r||s.push(`insufficient-hardware-concurrency`),i||s.push(`encoding-capability-unsupported`),a||s.push(`encoding-not-smooth`),o||s.push(`encoding-not-power-efficient`),s}function qv(e){let t=[];return e.features.hasMediaRecorder||t.push(`mediarecorder-unavailable`),e.network.online===!1&&t.push(`offline`),t}function Jv(e){return e.os.name.toLowerCase().includes(`android`)}function Yv(e,t){let n=[...t];return Jv(e)&&n.push(`android-post-recording-transcode`),n.push(`mediarecorder-supported`),n}function Xv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported===!0}function Zv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.smooth===!0}function Qv(e){let t=e?.encodingCapability;return t===void 0||t.errorCode!==void 0||t.supported!==!0||t.powerEfficient===!0}function $v(e){let t=e.resourceThresholds?.minDeviceMemory??4,n=e.resourceThresholds?.minHardwareConcurrency??5,r=Wv(e.profile,e.targetCodecIds),i=r?.id,a=i!==void 0,o=Hv(e.profile,t),s=Uv(e.profile,n),c=Xv(r),l=Zv(r),u=Qv(r),d=Kv(e.profile,a,o,s,c,l,u);return Jv(e.profile)&&Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:e.profile.features.isSecureContext&&e.profile.features.hasVideoEncoder&&a&&e.profile.network.online!==!1&&o&&s&&c&&l&&u?{route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`],selectedCodecId:i}:Gv(e.profile,a)?{route:`safe-capture-post-recording-transcode`,reasonCodes:Yv(e.profile,d),selectedCodecId:i}:{route:`unsupported-with-guidance`,reasonCodes:[...d,...qv(e.profile)],guidance:{canRetry:!0,message:`Recording is not supported in this browser context. Use a secure connection, go online, and try a current Chrome or Edge browser.`}}}let ey=[`prefer-hardware`,`no-preference`,`prefer-software`];async function ty(){let e=(await Promise.allSettled([Promise.resolve().then(()=>(Sv(),bv))]))[0];return e.status===`fulfilled`?e.value:null}let ny={loadMediabunnyModule:ty};function ry(e){let t=e?.loadMediabunnyModule,n;return n=t===void 0?ny.loadMediabunnyModule:t,{loadMediabunnyModule:n}}function iy(e,t){return t===void 0||e.includes(t)?e:[...e,t]}function ay(e,t){let n=[];e!==void 0&&t.videoCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredVideoCodec);for(let e of t.videoCodecFallbackOrder)n=iy(n,e);return n}function oy(e,t){let n=[];e!==void 0&&t.audioCodecFallbackOrder.includes(e)&&(n=iy(n,e)),n=iy(n,t.preferredAudioCodec);for(let e of t.audioCodecFallbackOrder)n=iy(n,e);return n}function sy(e,t,n){let r=Error(`No encodable video codec available for format: ${e}`);return r.code=`recording.video-codec-unavailable`,r.details={candidates:t,format:e,probeErrors:n},r}async function cy(e,t,n){try{return await e(t,n)?{kind:`supported`,codec:t}:{kind:`unsupported`,codec:t}}catch(e){return{kind:`error`,codec:t,error:e}}}async function ly(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredVideoCodec;let n=t.canEncodeVideo;if(typeof n!=`function`)return e.policy.preferredVideoCodec;let r=ay(e.overrideCodec,e.policy),a={};e.width!==void 0&&(a.width=e.width),e.height!==void 0&&(a.height=e.height),e.bitrate!==void 0&&(a.bitrate=e.bitrate);let o=[];for(let e of ey){let t={...a,hardwareAcceleration:e},i=await Promise.all(r.map(e=>cy(n,e,t)));o.push(...i);for(let e of i)if(e.kind===`supported`)return e.codec}let s=o.filter(e=>e.kind===`error`).map(e=>`${e.codec}: ${i(e.error)}`);if(e.dependencies?.loadMediabunnyModule===void 0&&s.length===0&&typeof VideoEncoder>`u`)return e.policy.preferredVideoCodec;throw sy(e.format,r,s)}async function uy(e){let t=await ry(e.dependencies).loadMediabunnyModule();if(t===null)return e.policy.preferredAudioCodec;let n=t.getFirstEncodableAudioCodec;if(typeof n!=`function`)return e.policy.preferredAudioCodec;let r=oy(e.overrideCodec,e.policy),i={};e.bitrate!==void 0&&(i.bitrate=e.bitrate),e.numberOfChannels!==void 0&&(i.numberOfChannels=e.numberOfChannels),e.sampleRate!==void 0&&(i.sampleRate=e.sampleRate);let a=(await Promise.allSettled([n(r,i)]))[0];if(a.status===`rejected`)return e.policy.preferredAudioCodec;let o=a.value;if(o===null){if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}if(r.includes(o))return o;if(e.shouldThrowIfNoCodecAvailable)throw Error(`No encodable audio codec available for format: ${e.format}`);return e.policy.preferredAudioCodec}function dy(e){switch(e){case`mp4`:return`video/mp4`;case`webm`:return`video/webm`;case`mkv`:return`video/x-matroska`;case`mov`:return`video/quicktime`;default:throw Error(`Unsupported output format: ${e}`)}}function fy(e){switch(e){case`mp4`:return`mp4`;case`webm`:return`webm`;case`mkv`:return`mkv`;case`mov`:return`mov`;default:throw Error(`Unsupported output format: ${e}`)}}Sv();function py(e){if(typeof e==`string`)return new cu(e);if(e instanceof Blob)return new ru(e);throw Error(`Invalid input type. Expected Blob, File, or file path string.`)}function my(e){switch(e){case`mp4`:return new U_;case`webm`:return new q_;case`mkv`:return new K_;case`mov`:return new G_;default:throw Error(`Unsupported output format: ${e}`)}}function hy(e,t=!1){let n={fit:`contain`,forceTranscode:!0,allowRotationMetadata:!1};return e.width!==void 0&&(n.width=e.width),e.height!==void 0&&(n.height=e.height),e.fps!==void 0&&(n.frameRate=e.fps),e.bitrate!==void 0&&(n.bitrate=e.bitrate),e.codec!==void 0&&(n.codec=e.codec),t&&(n.bitrateMode=`variable`,n.latencyMode=`realtime`,n.hardwareAcceleration=`prefer-hardware`,n.keyFrameInterval=2),{video:n,audio:{codec:e.audioCodec,forceTranscode:!0,...t&&{bitrateMode:`variable`}}}}function gy(e){if(!e.isValid){let t=e.discardedTracks.map(e=>e.reason).join(`, `);throw Error(`Conversion is invalid. Discarded tracks: ${t}`)}}async function _y(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=py(e),o=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await uy({format:i.format,overrideCodec:i.audioCodec,policy:o,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:o,width:i.width,height:i.height,bitrate:i.bitrate});let s=new vp({formats:$u,source:a}),c=new lv({format:my(i.format),target:new fg}),l=await hv.init({input:s,output:c,...hy(i)});gy(l),n&&(l.onProgress=n),await l.execute();let u=c.target.buffer;if(!u)throw Error(`Transcoding completed but no output buffer was generated`);let d=dy(i.format);return{buffer:u,blob:new Blob([u],{type:d})}}async function vy(e,t={},n){let r=t.format;r===void 0&&(r=Xt.format);let i={...Xt,...t,format:r},a=Ht(i.format,{isLinuxPlatform:on()});i.audioBitrate===void 0&&(i.audioBitrate=Kt(i.format)),i.audioCodec=await uy({format:i.format,overrideCodec:i.audioCodec,policy:a,bitrate:i.audioBitrate}),i.codec=await ly({format:i.format,overrideCodec:i.codec,policy:a,width:i.width,height:i.height,bitrate:i.bitrate});let o=new vp({formats:$u,source:new ru(e)}),s=new lv({format:my(i.format),target:new fg}),c=await hv.init({input:o,output:s,video:{codec:i.codec,width:i.width,height:i.height,frameRate:i.fps,bitrate:i.bitrate,fit:`contain`,allowRotationMetadata:!1},audio:{codec:i.audioCodec}});gy(c),n&&(c.onProgress=n),await c.execute();let l=s.target.buffer;if(!l)throw Error(`Transcoding completed but no output buffer was generated`);let u=dy(i.format);return{buffer:l,blob:new Blob([l],{type:u})}}function yy(e,t=1e4){return new Promise((n,r)=>{let i=document.createElement(`video`);i.preload=`metadata`,i.muted=!0;let a=setTimeout(()=>{o(),r(Error(`Preview extraction timeout`))},t),o=()=>{clearTimeout(a),URL.revokeObjectURL(i.src)};i.addEventListener(`loadedmetadata`,()=>{i.currentTime=Math.max(0,i.duration-.1)}),i.addEventListener(`seeked`,()=>{let e=document.createElement(`canvas`);e.width=i.videoWidth,e.height=i.videoHeight;let t=e.getContext(`2d`);if(!t){o(),r(Error(`Canvas context unavailable`));return}if(i.videoWidth===0||i.videoHeight===0){o(),r(Error(`Invalid video dimensions`));return}if(!(Number.isFinite(i.videoWidth)&&Number.isFinite(i.videoHeight))){o(),r(Error(`Invalid video dimensions`));return}t.drawImage(i,0,0,e.width,e.height),e.toBlob(e=>{o(),e?n(e):r(Error(`Failed to create preview blob`))},`image/jpeg`,.8)}),i.addEventListener(`error`,()=>{o(),r(Error(`Failed to load video for preview extraction`))}),i.src=URL.createObjectURL(e)})}var by=class{constructor(e,t,n){this.pendingFile=null,this.configService=null,this.config=e,this.configService=t,this.uploadService=n}async handleFileSelection(e){let t=await Ev(e,{maxFileSize:this.config.maxFileSize===void 0?2*1024*1024*1024:this.config.maxFileSize,maxRecordingTime:this.config.maxRecordingTime,allowedFormats:[`video/mp4`,`video/quicktime`,`video/webm`]});if(!t.valid)throw Error(t.error);let n=await yy(e),r=URL.createObjectURL(n),a=await Cv(e).then(e=>({success:!0,duration:e})).catch(e=>({success:!1,error:i(e)}));if(a.success===!1)throw Error(`Failed to extract video duration: ${a.error}`);let o=a.duration;return this.pendingFile=e,{file:e,previewUrl:r,duration:o,validated:!0}}async processAndUpload(e,t){if(!this.pendingFile)throw Error(`No file selected`);let n=this.configService?await this.configService.fetchConfig():Xt,r=await this.resolveNativeCameraRouteDecision(n);if(r.route===`unsupported-with-guidance`)throw Error(r.guidance?.message??`This browser or device cannot safely process this video. Try another browser or upload from a different device.`);let i=(await vy(this.pendingFile,n,e)).blob;if(!(this.config.apiKey&&this.config.backendUrl))throw Error(`Upload requires API key and backend URL`);let a=await this.uploadService.uploadVideo(i,{apiKey:this.config.apiKey,backendUrl:this.config.backendUrl,filename:this.resolveUploadFilename(i),userMetadata:this.config.userMetadata,onProgress:t});return this.pendingFile=null,{blob:i,recordingId:a.id,uploadUrl:a.uploadUrl||``}}async resolveNativeCameraRouteDecision(e){let t=this.buildCodecProbeCandidates(e);return $v({profile:await Vv({codecCandidates:t}),targetCodecIds:t.map(e=>e.id)})}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}resolveUploadFilename(e){let t=this.resolveUploadExtension(e.type);return`${Date.now()}.${t}`}resolveUploadExtension(e){switch(e){case`video/webm`:return`webm`;case`video/quicktime`:return`mov`;default:return`mp4`}}cancel(){this.pendingFile=null}async preloadConfig(){this.configService&&await this.configService.fetchConfig()}};let xy={isLinuxPlatform:on()};Ht(`mp4`,xy).preferredAudioCodec,Ht(`mov`,xy).preferredAudioCodec,Ht(`mkv`,xy).preferredAudioCodec,Ht(`webm`,xy).preferredAudioCodec;let Sy=`recording.invalid-container-layout`,Cy=`recording.no-video-track`,wy=`recording.no-audio-track`,Ty=`moov`,Ey=`trak`,Dy=`stsz`,Oy=`soun`;function ky(e){return e>=6e3&&e<=384e3}function Ay(e){let t=Error(Sy);return t.code=Sy,t.detectedBoxTypes=e,t}function jy(e){let t=Error(e);return t.code=e,t}function My(e){return e instanceof Uint8Array?e:new Uint8Array(e)}function Ny(e,t){let n=e.getUint8(t),r=e.getUint8(t+1),i=e.getUint8(t+2),a=e.getUint8(t+3);return String.fromCharCode(n,r,i,a)}function Py(e,t){let n=e.getUint32(t,!1),r=e.getUint32(t+4,!1);return n*4294967296+r}function Fy(e){let t=new Set;for(let n of e)t.add(n);return[...t]}function Iy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=[],a=t;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(i.map(e=>e.type));let l=a+s;i.push({type:t,size:o,startOffset:a,endOffset:c,payloadStartOffset:l}),a=c}return i}function Ly(e,t){for(let n of e)if(n.type===t)return n;return null}function Ry(e,t,n){if(!(t+4<=n))throw Ay([]);return Ny(e,t)}function zy(e,t){let n=Ly(t,`mdhd`);if(n===null||n.endOffset-n.payloadStartOffset<16||e.getUint8(n.payloadStartOffset)!==0)return 0;let r=n.payloadStartOffset+8,i=n.payloadStartOffset+12,a=e.getUint32(r,!1),o=e.getUint32(i,!1);return a===0?0:o/a}function By(e,t){let n=Ly(t,`stsd`);if(n===null)return{channelCount:0,sampleRate:0};let r=n.payloadStartOffset+4+4+8;if(r+28>n.endOffset)return{channelCount:0,sampleRate:0};let i=e.getUint16(r+16,!1),a=e.getUint32(r+24,!1);return{channelCount:i,sampleRate:Math.floor(a/65536)}}function Vy(e,t,n){let r=new DataView(e.buffer,e.byteOffset,e.byteLength),i=Ly(Iy(e,t.payloadStartOffset,t.endOffset),`mdia`);if(i===null)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let a=Iy(e,i.payloadStartOffset,i.endOffset),o=Ly(a,`hdlr`);if(o===null||Ry(r,o.payloadStartOffset+8,o.endOffset)!==n)return{isMatchingTrack:!1,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:0};let s=zy(r,a),c=Ly(a,`minf`);if(c===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let l=Ly(Iy(e,c.payloadStartOffset,c.endOffset),`stbl`);if(l===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let u=Iy(e,l.payloadStartOffset,l.endOffset),d=Ly(u,Dy);if(d===null)return{isMatchingTrack:!0,sampleCount:0,channelCount:0,sampleRate:0,durationSeconds:s};let f=d.payloadStartOffset+8;if(!(f+4<=d.endOffset))throw Ay([Dy]);return{isMatchingTrack:!0,sampleCount:r.getUint32(f,!1),...n===Oy?By(r,u):{channelCount:0,sampleRate:0},durationSeconds:s}}function Hy(e){let t=My(e),n=t.byteLength,r=new DataView(t.buffer,t.byteOffset,t.byteLength),i=[],a=0;for(;a<n;){if(!(a+8<=n))throw Ay(i.map(e=>e.type));let e=r.getUint32(a,!1),t=Ny(r,a+4),o=e,s=8;if(e===1){let e=a+8;if(!(e+8<=n))throw Ay(i.map(e=>e.type));o=Py(r,e),s=16}if(e===0&&(o=n-a),!(o>=s))throw Ay(i.map(e=>e.type));let c=a+o;if(!(c<=n))throw Ay(i.map(e=>e.type));i.push({type:t,size:o,startOffset:a,endOffset:c}),a=c}return i}function Uy(e){let t=Hy(e).filter(e=>e.type===`moof`||e.type===`mfra`).map(e=>e.type);if(t.length>0)throw Ay(Fy(t))}function Wy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(Cy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(Cy);let i=!1;for(let e of r){let n=Vy(t,e,`vide`);if(n.isMatchingTrack&&(i=!0,n.sampleCount>0))return}throw jy(i?`recording.no-video-frames`:Cy)}function Gy(e){let t=My(e),n=Ly(Iy(t,0,t.byteLength),Ty);if(n===null)throw jy(wy);let r=Iy(t,n.payloadStartOffset,n.endOffset).filter(e=>e.type===Ey);if(r.length===0)throw jy(wy);let i=!1;for(let e of r){let n=Vy(t,e,Oy);if(n.isMatchingTrack&&(i=!0,n.sampleCount!==0)){if(n.channelCount===0)throw jy(`recording.audio-zero-channels`);if(!ky(n.sampleRate))throw jy(`recording.audio-invalid-sample-rate`);return}}throw jy(i?`recording.no-audio-frames`:wy)}function Ky(){return new Blob([`"use strict";
127
127
  var PROBE_MESSAGE_TYPE="probe";
128
128
  var PROBE_RESULT_TYPE="probeResult";
129
129
  self.onmessage=function(e){
@@ -137,7 +137,7 @@ hasOffscreenCanvas:typeof OffscreenCanvas!=="undefined",
137
137
  hasCreateImageBitmap:typeof createImageBitmap!=="undefined",
138
138
  hasReadableStream:typeof ReadableStream!=="undefined"
139
139
  });
140
- };`],{type:`application/javascript`})}function qy(){let e=Ky();return URL.createObjectURL(e)}function Jy(e){URL.revokeObjectURL(e)}let Yy=`probe`,Xy=`probeResult`,Zy=`mediaStreamTrackProcessor`,Qy=`unavailable`,$y=`unavailable`,eb=new Map,tb=new Map;function nb(e,t){return typeof e==`boolean`?e:t}function rb(e){return e?`1`:`0`}function ib(e,t){return[`audio`,rb(e),`watermark`,rb(t)].join(`|`)}function ab(){return typeof process>`u`||process.env,!0}function ob(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Qy}function sb(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:$y:`none-required`}function cb(e,t){return e.includes(t)?e:[...e,t]}function lb(e,t){let n=e;return t.hasWorker||(n=cb(n,`worker`)),t.probeResult.hasVideoFrame||(n=cb(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=cb(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=cb(n,`readableStream`)),n}function ub(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=cb(n,`createImageBitmap`)),n}function db(e,t){let n=e;return t.videoPath===Qy&&(n=cb(n,Zy)),n}function fb(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=cb(n,Zy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=cb(n,`audioData`)),n)}function pb(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=cb(n,`audioContext`)),t.hasAudioWorklet||(n=cb(n,`audioWorklet`)),n)}function mb(e,t){let n=e;return t.requiresAudio&&t.audioPath===$y?(n=fb(n,t),n=pb(n,t),n):n}function hb(e){let t=[];return t=lb(t,e),t=ub(t,e),t=db(t,e),t=mb(t,e),t}function gb(e,t){return!(e===Qy||t===$y)}function _b(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function vb(e={},t={}){let n=nb(e.requiresAudio,!0),r=nb(e.requiresWatermark,!1);if(!ab())return await yb(n,r,t);let i=ib(n,r),a=eb.get(i);if(a)return a;let o=tb.get(i);if(o)return await o;let s=yb(n,r,t).then(e=>(eb.set(i,e),tb.delete(i),e)).catch(e=>{throw tb.delete(i),e});return tb.set(i,s),await s}async function yb(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await bb(r,n),l=ob({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=sb({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=hb({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=gb(l,u),p=_b(c,t);return{isSupported:r&&f&&p,missing:d,hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMediaStreamTrackProcessor:c.hasMediaStreamTrackProcessor,hasMainThreadMediaStreamTrackProcessor:s,hasVideoFrame:c.hasVideoFrame,hasAudioData:c.hasAudioData,hasOffscreenCanvas:c.hasOffscreenCanvas,hasCreateImageBitmap:c.hasCreateImageBitmap,hasReadableStream:c.hasReadableStream,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}}async function bb(e,t){if(!e)return Sb();let n=await xb().catch(()=>null);return n?await new Promise(e=>{let r=!1,i=t.probeTimeoutMilliseconds??2e3,a=t=>{r||(r=!0,n.terminate(),e(t))},o=setTimeout(()=>{a(Sb())},i);n.onmessage=e=>{let t=e.data;t.type===Xy&&(clearTimeout(o),a({hasMediaStreamTrackProcessor:t.hasMediaStreamTrackProcessor===!0,hasVideoFrame:t.hasVideoFrame===!0,hasAudioData:t.hasAudioData===!0,hasOffscreenCanvas:t.hasOffscreenCanvas===!0,hasCreateImageBitmap:t.hasCreateImageBitmap===!0,hasReadableStream:t.hasReadableStream===!0}))},n.onerror=()=>{clearTimeout(o),a(Sb())},Promise.resolve().then(()=>{n.postMessage({type:Yy})}).catch(()=>{clearTimeout(o),a(Sb())})}):Sb()}function xb(){return Promise.resolve().then(()=>{let e=qy();try{let t=new Worker(e,{type:`classic`});return Jy(e),t}catch(t){throw Jy(e),t}})}function Sb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let Cb=`recording.audio-no-chunks`,wb=`recording.audio-silent`,Tb=`recording.audio-track-ended`,Eb=`audio.no-track-at-start`;function Db(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function Ob(){let e=Error(Eb);return e.code=Eb,e}function kb(e){if(!(e instanceof Error))return!1;let t=e;return t.code===Cb||t.code===wb||t.code===Tb||t.code===`recording.no-audio-track`||t.code===`recording.no-audio-frames`||t.code===`recording.audio-zero-channels`||t.code===`recording.audio-invalid-sample-rate`}function Ab(e){return e.hadTrackEndedWarning?{ok:!1,code:Tb}:e.totalChunks===0?{ok:!1,code:Cb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:wb}:{ok:!0}}let jb=`vidtreo-recorder`,Mb=`pending-uploads`,Nb=`status`,Pb=`createdAt`,Fb=`Failed to prepare upload data for storage. The recorded file could not be read.`,Ib=`__probe__`,Lb=new ArrayBuffer(1);var Rb=class{constructor(e){if(this.db=null,e){this.databaseFactory=e;return}this.databaseFactory=indexedDB}init(){return this.db?Promise.resolve():this.openDatabase(3,!0)}openDatabase(e,t){return new Promise((n,r)=>{let i=this.createOpenRequest(e);i.onerror=()=>{let e=i.error;if(t&&e&&e.name===`VersionError`){this.openDatabase(void 0,!1).then(n).catch(r);return}if(e){r(e);return}r(Error(`Failed to open database`))},i.onsuccess=()=>{if(!i.result){r(Error(`Database result is null`));return}let e=i.result,t=this.validateRequiredSchema(e);if(t){e.close(),r(t);return}this.db=e,n()},i.onupgradeneeded=e=>{let t=e.target.result;if(!t){r(Error(`Database upgrade result is null`));return}this.initializeStoreSchema(t)}})}createOpenRequest(e){return e===void 0?this.databaseFactory.open(jb):this.databaseFactory.open(jb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(Mb))return;let t=e.createObjectStore(Mb,{keyPath:`id`});t.createIndex(Nb,Nb,{unique:!1}),t.createIndex(Pb,Pb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(Mb))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([Mb],`readonly`).objectStore(Mb);return t.indexNames.contains(Nb)?t.indexNames.contains(Pb)?null:Error(`Database schema is missing required index: createdAt`):Error(`Database schema is missing required index: status`)}isInitialized(){return this.db!==null}async probeWriteCapability(){if(!this.db)return{ok:!1,reason:`Database not initialized`};try{return await this.executeTransaction(`readwrite`,e=>{let t={id:Ib,blobData:Lb,blobType:`application/octet-stream`,apiKey:``,backendUrl:``,filename:`probe`,status:`pending`,retryCount:0,createdAt:0,updatedAt:0};return new Promise((n,r)=>{let i=e.put(t);i.onsuccess=()=>{let t=e.delete(Ib);t.onsuccess=()=>n(),t.onerror=()=>{if(t.error){r(t.error);return}r(Error(`Probe delete failed`))}},i.onerror=()=>{if(i.error){r(i.error);return}r(Error(`Probe write failed`))}})}),{ok:!0}}catch(e){return{ok:!1,reason:`Storage write probe failed. Browser may be in private browsing mode or IndexedDB writes are restricted. ${e instanceof Error?e.message:String(e)}`}}}async savePendingUpload(e){let t=this.generateUploadId(),n=Date.now(),r={...e,id:t,status:`pending`,retryCount:0,createdAt:n,updatedAt:n,blobData:await this.readBlobData(e.blob),blobType:e.blob.type};return r.blob=void 0,this.executeTransaction(`readwrite`,e=>{let n=e.add(r);return new Promise((e,r)=>{n.onsuccess=()=>e(t),n.onerror=()=>{n.error?n.error.name===`QuotaExceededError`?r(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):r(n.error):r(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(Nb).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result.map(e=>this.hydrateUpload(e)))},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}async updateUploadStatus(e,t){let n=await this.createStoredUpdates(t);return this.executeTransaction(`readwrite`,r=>{let i=r.get(e);return new Promise((e,a)=>{i.onsuccess=()=>{let o=i.result;if(!o){a(Error(`Upload not found`));return}let s=t.updatedAt===void 0?Date.now():t.updatedAt,c={...o,...n,updatedAt:s},l=r.put(c);l.onsuccess=()=>e(),l.onerror=()=>{if(l.error){a(l.error);return}a(Error(`Failed to update upload`))}},i.onerror=()=>{i.error?a(i.error):a(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}hydrateUpload(e){if(`blobData`in e&&e.blobData){let{blobData:t,blobType:n,...r}=e;return{...r,blob:new Blob([t],{type:n})}}return e}async createStoredUpdates(e){let t={...e};return e.blob&&(t.blobData=await this.readBlobData(e.blob),t.blobType=e.blob.type,t.blob=void 0),t}readBlobData(e){return e.arrayBuffer().catch(e=>{throw e instanceof Error?Error(`${Fb} ${e.message}`):Error(Fb)})}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);let n=this.db.transaction([Mb],e),r=n.objectStore(Mb);return new Promise((e,i)=>{let a,o=!1,s=!1;n.oncomplete=()=>{!o||s||e(a)},n.onerror=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction failed`))},n.onabort=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction aborted`))},t(r).then(e=>{a=e,o=!0},e=>{s=!0,i(e)})})}},zb=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new Rb,this.storageService.isInitialized()||await this.storageService.init(),this.writeProbeResult=await this.storageService.probeWriteCapability(),this.setupCleanupInterval(e)}getWriteProbeResult(){return this.writeProbeResult}setupCleanupInterval(e){this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(t=>{e(i(t))})},36e5))}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getStorageService(){return this.storageService}isStorageWritable(){return this.writeProbeResult?.ok===!0}destroy(){this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};function Bb(){let e=globalThis;if(e.__VIDTREO_DEBUG__===!0||e.__VIDTREO_DEV__===!0)return!0;let t=typeof process<`u`&&process?.env?`production`:void 0;return t===`development`||t===`test`||typeof localStorage<`u`&&localStorage.getItem(`VIDTREO_DEBUG`)===`true`}let Vb=Bb(),Hb={reset:`\x1B[0m`,bright:`\x1B[1m`,dim:`\x1B[2m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`,white:`\x1B[37m`,gray:`\x1B[90m`};function Ub(e,t,n){if(!Vb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Hb[n?.color||Wb(e)]}${r}${Hb.reset} ${t}`}function Wb(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Gb(e,t,...n){if(!Vb)return;let r=Ub(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Gb(`log`,e,...t)},info:(e,...t)=>{Gb(`info`,e,...t)},warn:(e,...t)=>{Gb(`warn`,e,...t)},error:(e,...t)=>{Gb(`error`,e,...t)},debug:(e,...t)=>{Gb(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Vb)return;let n=Hb[t],r=Hb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Vb&&console.groupEnd()}};function Kb(e,t){if(e==null)throw Error(t);return e}function qb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function Jb(){if(typeof navigator>`u`||!navigator.mediaDevices?.getUserMedia){let e=typeof window<`u`&&window.isSecureContext===!0?`Camera access is not supported in this browser`:`Camera access requires HTTPS. Please use a secure connection (https://) or localhost.`;throw Error(e)}return navigator.mediaDevices}function Yb(e,t){let n={};if(t.originalCameraConstraints){let{deviceId:e,...r}=t.originalCameraConstraints;n={...n,...r}}e&&(n={...n,deviceId:{exact:e}});let r=t.getSelectedCameraDeviceId(),i=!1;return e&&(i=!0),n.deviceId&&(i=!0),!i&&r&&(n={...n,deviceId:{exact:r}}),n}function Xb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Zb=`live`;function Qb(e){for(let t of e)t.readyState===Zb&&t.stop()}function $b(e){Qb(e.getTracks())}function ex(e){Qb(e.getVideoTracks())}function tx(e){return e?e.readyState===Zb:!1}function nx(e,t){return tx(e)&&tx(t)}function rx(e,t,n){if(!tx(e)){$b(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let ix=`[SourceSwitchManager]`;var ax=class{constructor(e){this.dependencies=e}async createCameraStreamWithOriginalAudio(e){let t=this.dependencies.getOriginalCameraStream(),n;if(t&&(n=t.getAudioTracks()[0]),this.dependencies.logger.debug(`${ix} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:tx(n),cameraDeviceId:e}),!tx(n))return this.dependencies.logger.warn(`${ix} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=Yb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),i=Object.keys(r).length>0,a=!0;i&&(a=r);let o={video:a,audio:!1};this.dependencies.logger.debug(`${ix} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0];rx(c,`video`,s),this.dependencies.logger.debug(`${ix} New video stream obtained`,{newStreamId:s.id,videoTrackId:c.id,videoTrackReadyState:c.readyState,newStreamAudioTracksCount:s.getAudioTracks().length});let l=[c];n&&(l=[...l,n]),this.dependencies.logger.debug(`${ix} Creating combined stream with original audio`,{videoTrackId:c.id,audioTrackId:n?.id,audioTrackReadyState:n?.readyState,audioTrackEnabled:n?.enabled,audioTrackMuted:n?.muted,combinedTracksCount:l.length});let u=new MediaStream(l);Qb(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${ix} Combined stream created and assigned`,{combinedStreamId:u.id,previousOriginalCameraStreamId:d,newOriginalCameraStreamId:u.id,combinedStreamVideoTracksCount:u.getVideoTracks().length,combinedStreamAudioTracksCount:u.getAudioTracks().length,combinedStreamAudioTrackId:u.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:u.getAudioTracks()[0]?.readyState,audioTrackStillSame:u.getAudioTracks()[0]===n}),u}async createCameraStreamWithNewAudio(e){let t=this.dependencies.getSelectedMicDeviceId(),n=Yb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Xb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return rx(c,`video`,s),rx(l,`audio`,s),this.dependencies.setOriginalCameraStream(s),s}async createNewCameraStreamForRecording(){let e=this.dependencies.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(e){let t=this.dependencies.streamManager.isRecording(),n=this.dependencies.getSelectedCameraDeviceId(),r=this.dependencies.getSelectedMicDeviceId();if(this.dependencies.streamManager.setVideoDevice(n),this.dependencies.streamManager.setAudioDevice(r),e.canReuseOriginalStream()){let e=this.dependencies.getOriginalCameraStream();if(!e)throw Error(`Original camera stream is null`);return e}if(e.canReuseManagerStream()){let e=this.dependencies.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}t||this.dependencies.getOriginalCameraStream()&&this.dependencies.setOriginalCameraStream(null);let i=this.dependencies.streamManager.getStream();if(!t&&i&&i!==this.dependencies.getOriginalCameraStream()&&($b(i),this.dependencies.streamManager.setMediaStream(null)),t)return this.dependencies.streamManager.setVideoDevice(this.dependencies.getSelectedCameraDeviceId()),this.dependencies.streamManager.setAudioDevice(this.dependencies.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let a=await this.dependencies.streamManager.startStream();return this.dependencies.setOriginalCameraStream(a),a}};let ox=`screen`,sx=`No video track found in screen share stream`;async function cx(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error(sx);let i=n.combineScreenShareWithOriginalAudio(r),a=n.getOriginalCameraStream();t&&t!==a&&n.stopStreamVideoTracks(t);let o=e.getAudioTracks();for(let e of o)e.stop();return n.setCurrentSourceType(ox),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),lx(i,n),i}function lx(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error(sx);let r=t.getScreenShareTrackEndHandler();if(r){let e=t.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,r)}}let i=()=>{t.getCurrentSourceType()===ox&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function ux(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function dx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function fx(e){e.onTransitionEnd&&e.onTransitionEnd()}function px(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function mx(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function hx(e){mx(e),fx(e)}let gx=`Failed to get camera stream`;var _x=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t;let n=null,r=()=>n;this.getOriginalCameraConstraints=r,this.setOriginalCameraConstraints=e=>{n=e},this.cameraStreamBuilder=new ax({streamManager:this.streamManager,logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},getSelectedCameraDeviceId:()=>this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice(),getSelectedMicDeviceId:()=>this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice(),getOriginalCameraStream:()=>this.originalCameraStream,setOriginalCameraStream:e=>{this.originalCameraStream=e},getOriginalCameraConstraints:r})}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings(),r={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode},i=this.getOriginalCameraConstraints();i&&i.width===r.width&&i.height===r.height&&i.aspectRatio===r.aspectRatio&&i.frameRate===r.frameRate&&i.deviceId===r.deviceId&&i.facingMode===r.facingMode||this.setOriginalCameraConstraints(r)}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];nx(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(i(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t;this.originalCameraStream&&(t=this.originalCameraStream.getAudioTracks()[0]),$.debug(`[SourceSwitchManager] combineScreenShareWithOriginalAudio`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,hasOriginalAudioTrack:!!t,originalAudioTrackId:t?.id,originalAudioTrackReadyState:t?.readyState,originalAudioTrackEnabled:t?.enabled,originalAudioTrackMuted:t?.muted,originalAudioTrackLabel:t?.label,isTrackLive:tx(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];tx(t)&&t?(n=[...n,t],$.debug(`[SourceSwitchManager] Added original audio track to combined stream`,{audioTrackId:t.id,combinedTracksCount:n.length})):$.warn(`[SourceSwitchManager] Original audio track is not live, not adding to combined stream`,{audioTrackId:t?.id,audioTrackReadyState:t?.readyState,combinedTracksCount:n.length});let r=new MediaStream(n);return $.debug(`[SourceSwitchManager] Combined stream created`,{combinedStreamId:r.id,combinedStreamVideoTracksCount:r.getVideoTracks().length,combinedStreamAudioTracksCount:r.getAudioTracks().length,combinedStreamAudioTrackId:r.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:r.getAudioTracks()[0]?.readyState}),r}isPermissionDeniedError(e){let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0);let r=t.toLowerCase();return r.includes(`permission denied`)&&(n=!0),r.includes(`user denied`)&&(n=!0),n}switchToScreenCapture(){let e=this.streamManager.getStream();return e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),dx(this.callbacks,`Select screen to share...`),px(this.callbacks),Promise.resolve().then(async()=>{let t=Jb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return cx(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(hx(this.callbacks),this.isPermissionDeniedError(e))return null;throw e})}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!nx(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getScreenShareDependencies(){return{callbacks:this.callbacks,streamManager:this.streamManager,combineScreenShareWithOriginalAudio:e=>this.combineScreenShareWithOriginalAudio(e),stopStreamTracks:e=>$b(e),stopStreamVideoTracks:e=>ex(e),getCurrentSourceType:()=>this.currentSourceType,setCurrentSourceType:e=>{this.currentSourceType=e},getOriginalCameraStream:()=>this.originalCameraStream,getScreenShareStream:()=>this.screenShareStream,setScreenShareStream:e=>{this.screenShareStream=e},getScreenShareTrackEndHandler:()=>this.screenShareTrackEndHandler,setScreenShareTrackEndHandler:e=>{this.screenShareTrackEndHandler=e},switchToCamera:()=>this.switchToCamera(),handleSwitchError:e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}}}getCameraStream(){return this.cameraStreamBuilder.getCameraStream({canReuseOriginalStream:()=>this.canReuseOriginalStream(),canReuseManagerStream:()=>this.canReuseManagerStream()})}switchToCamera(){let e=this.streamManager.isRecording();return!e&&this.currentSourceType===`camera`?Promise.resolve():Promise.resolve().then(async()=>{dx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(gx);await this.applyCameraStream(t,e),fx(this.callbacks)}).catch(e=>{throw fx(this.callbacks),e})}stopScreenShareStreamTracks(e){let t=e.getVideoTracks(),n=e.getAudioTracks();$.debug(`[SourceSwitchManager] stopping screen share tracks`,{videoTracks:t.map(e=>({id:e.id,readyState:e.readyState,displaySurface:e.getSettings().displaySurface,constraints:e.getConstraints()})),audioTracks:n.map(e=>({id:e.id,readyState:e.readyState,constraints:e.getConstraints()}))});for(let e of t)e.stop();for(let e of n)e.stop()}stopDisplayTracks(e){if(e)for(let t of e.getVideoTracks())typeof t.getSettings().displaySurface==`string`&&tx(t)&&($.debug(`[SourceSwitchManager] stopping display track`,{id:t.id,readyState:t.readyState,constraints:t.getConstraints(),settings:t.getSettings()}),t.stop())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;$.debug(`[SourceSwitchManager] handleScreenShareStop invoked`,{currentSourceType:this.currentSourceType,hasScreenShareStream:!!this.screenShareStream,screenShareStreamId:this.screenShareStream?.id,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id});let e=this.screenShareStream,t=this.streamManager.getStream();if($.debug(`[SourceSwitchManager] Current stream state before stop`,{currentStreamId:t?.id,currentStreamVideoTracksCount:t?.getVideoTracks().length,currentStreamAudioTracksCount:t?.getAudioTracks().length,currentStreamAudioTrackId:t?.getAudioTracks()[0]?.id,currentStreamAudioTrackReadyState:t?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState}),e){let t=e.getAudioTracks();$.debug(`[SourceSwitchManager] Screen share stream audio tracks before stop`,{screenShareStreamId:e.id,screenShareAudioTracksCount:t.length,screenShareAudioTrackIds:t.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),ux(e,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(e),this.stopDisplayTracks(e),this.screenShareStream=null,await this.waitForTracksToEnd(0),$.debug(`[SourceSwitchManager] Screen share stream stopped`,{screenShareAudioTracksAfterStop:t.map(e=>({id:e.id,readyState:e.readyState}))})}if(t){let e=t.getAudioTracks();$.debug(`[SourceSwitchManager] Current stream audio tracks before video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:e.length,currentStreamAudioTrackIds:e.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),ex(t),this.stopDisplayTracks(t),$.debug(`[SourceSwitchManager] Current stream audio tracks after video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:t.getAudioTracks().length,currentStreamAudioTrackIds:t.getAudioTracks().map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))})}$.debug(`[SourceSwitchManager] Original camera stream state before source change`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackEnabled:this.originalCameraStream?.getAudioTracks()[0]?.enabled}),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),$.debug(`[SourceSwitchManager] handleScreenShareStop completed`,{hasScreenShareStream:!!this.screenShareStream,currentSourceType:this.currentSourceType,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState})}async applyCameraStream(e,t){this.streamManager.setMediaStream(e);let n=this.currentSourceType!==`camera`;this.currentSourceType=`camera`,n&&this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(!this.streamManager.isRecording())return;let e;e=this.currentSourceType===`camera`?this.switchToScreen():this.switchToCamera(),await e.catch(e=>{this.handleToggleError(e)})}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){fx(this.callbacks);return}dx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),fx(this.callbacks)}handleToggleError(e){fx(this.callbacks);let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0),n&&this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}),!n&&this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}await Promise.resolve().then(async()=>{let e=this.streamManager.getStream();e&&(ux(e,this.getScreenShareDependencies()),ex(e));let t=await this.getCameraStream();if(!t)throw Error(gx);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}).catch(e=>{throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}),this.cleanup()}cleanup(){this.screenShareStream&&=(ux(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&ux(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let vx=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),yx=Object.freeze({video:vx,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let bx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},xx={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function Sx(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function Cx(e){return i(e).toLowerCase()}function wx(e,t){let n=Cx(e),r=t===`camera`?`camera`:`audio`;return n.includes(`permission denied`)||n.includes(`permission dismissed`)||n.includes(`not allowed`)?`${r}.permission-denied`:n.includes(`requested device not found`)||n.includes(`device not found`)||n.includes(`no camera`)||n.includes(`no microphone`)?`${r}.not-found`:n.includes(`timeout starting`)||n.includes(`timed out`)||n.includes(`timeout`)?`${r}.timeout`:n.includes(`could not start video source`)||n.includes(`could not start audio source`)||n.includes(`device in use`)?`${r}.in-use`:null}function Tx(e){let t=wx(e,`camera`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=bx[n];if(e!==void 0)return e}return`camera.unknown`}function Ex(e){let t=wx(e,`audio`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=xx[n];if(e!==void 0)return e}return`audio.unknown`}function Dx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=Tx(e),n}function Ox(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=Ex(e),n}function kx(e){return Sx(e)===`NotReadableError`}function Ax(e){return new Promise(t=>setTimeout(t,e))}var jx=class{constructor(e={},t={}){this.mediaStream=null,this.state=`idle`,this.eventListeners=new Map,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.audioStatus=`pending`,this.audioAcquisitionPromise=null,this.pendingAudioError=null,this.acquisitionGeneration=0,this.streamConfig={...yx,...e},this.waitMilliseconds=t.waitMilliseconds??Ax,this.audioRetryDelayMilliseconds=t.audioRetryDelayMilliseconds??300}getAudioStatus(){return this.audioStatus}isAudioReady(){return this.audioStatus===`acquired`}async waitForAudio(){if(this.audioStatus!==`acquired`&&(this.audioStatus===`failed`||(this.audioAcquisitionPromise&&await this.audioAcquisitionPromise,this.getAudioStatus()===`failed`)))throw this.pendingAudioError??Ox(null)}setAudioStatus(e){this.audioStatus!==e&&(this.audioStatus=e,this.emit(`audiostatuschange`,{status:e}))}emitAudioTelemetry(e){this.emit(`audiotelemetry`,{event:e})}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${i(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if($.debug(`[StreamManager] startStream called`,{hasExistingStream:!!this.mediaStream,selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId}),this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)$.debug(`[StreamManager] Stopping existing stream to recreate`),this.stopStream();else return $.debug(`[StreamManager] Reusing existing stream`),this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return $.debug(`[StreamManager] Existing stream matches device, reusing`),this.mediaStream;$.debug(`[StreamManager] Device changed, stopping existing stream`),this.stopStream()}this.setState(`starting`),$.debug(`[StreamManager] State set to 'starting'`);try{return this.mediaStream=await this.acquireVideoAndAudioStream(),$.info(`[StreamManager] Media stream obtained`,{streamId:this.mediaStream.id,videoTracks:this.mediaStream.getVideoTracks().length,audioTracks:this.mediaStream.getAudioTracks().length}),this.setState(`active`),$.debug(`[StreamManager] State set to 'active'`),$.debug(`[StreamManager] Emitting streamstart event`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){if(e instanceof Error&&`code`in e&&(e.name===`CameraError`||e.name===`AudioError`))throw $.error(`[StreamManager] Failed to start stream`,e),this.setState(`error`),this.emit(`error`,{error:e}),e;let t=Dx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=Jb(),t=this.buildVideoConstraints(this.selectedVideoDeviceId),n=this.buildAudioConstraints(this.selectedAudioDeviceId);this.setAudioStatus(`pending`),this.pendingAudioError=null,$.debug(`[StreamManager] Attempting combined getUserMedia`,{selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId});try{let r=await e.getUserMedia({video:t,audio:n}),i=r.getVideoTracks().length>0,a=r.getAudioTracks().length>0;if(i&&a)return $.debug(`[StreamManager] Combined getUserMedia succeeded with video + audio`),this.setAudioStatus(`acquired`),r;$.warn(`[StreamManager] Combined getUserMedia returned incomplete stream`,{videoTracks:r.getVideoTracks().length,audioTracks:r.getAudioTracks().length}),this.stopStreamTracks(r)}catch(e){let t=Sx(e),n=i(e);$.warn(`[StreamManager] Combined getUserMedia failed, falling back to separate acquisition`,{error:n,errorName:t}),this.emitAudioTelemetry({name:`audio.acquisition.fallback`,properties:{reason:`combined_getUserMedia_failed`,originalError:n,originalErrorName:t,selectedAudioDeviceId:this.selectedAudioDeviceId,selectedVideoDeviceId:this.selectedVideoDeviceId}})}let r;try{r=await e.getUserMedia({video:t,audio:!1}),$.debug(`[StreamManager] Video-only stream acquired for preview`)}catch(e){throw this.setAudioStatus(`failed`),Dx(e)}this.mediaStream=r,this.acquisitionGeneration++;let a=this.acquisitionGeneration;return this.audioAcquisitionPromise=this.acquireAudioInBackground(e,n,a),r}async acquireAudioInBackground(e,t,n){try{let r=await this.acquireAudioTrackWithRetry(e,t);if(!this.mediaStream||this.acquisitionGeneration!==n){$.debug(`[StreamManager] Audio acquired but stream was replaced/stopped, discarding track`,{generation:n,currentGeneration:this.acquisitionGeneration}),r.stop();return}this.mediaStream.addTrack(r),$.info(`[StreamManager] Audio track added to stream`,{audioTrackId:r.id,audioTrackLabel:r.label,totalAudioTracks:this.mediaStream.getAudioTracks().length}),this.setAudioStatus(`acquired`)}catch(e){if(this.acquisitionGeneration!==n)return;let t=e instanceof Error&&`code`in e?e:Ox(e);this.pendingAudioError=t,this.setAudioStatus(`failed`),$.error(`[StreamManager] Background audio acquisition failed`,t),this.emitAudioTelemetry({name:`audio.acquisition.failed`,properties:{errorCode:t.code,errorName:t.name,maxRetries:2,retryDelayMs:this.audioRetryDelayMilliseconds,selectedAudioDeviceId:this.selectedAudioDeviceId},error:t}),this.emit(`error`,{error:t})}finally{this.audioAcquisitionPromise=null}}resolveAudioConstraintsForAttempt(e,t){if(t!==2||typeof e!=`object`)return e;let{deviceId:n,...r}=e,i=Object.keys(r).length>0?r:!0;return $.debug(`[StreamManager] Audio retry with relaxed constraints (no deviceId)`,{attempt:t}),i}async acquireAudioTrackWithRetry(e,t){let n=null;for(let r=0;r<=2;r++)try{let n=this.resolveAudioConstraintsForAttempt(t,r),i=await e.getUserMedia({video:!1,audio:n}),a=i.getAudioTracks()[0];if(!a)throw this.stopStreamTracks(i),Error(`getUserMedia returned no audio tracks`);for(let e of i.getVideoTracks())e.stop();return $.debug(`[StreamManager] Audio track acquired`,{attempt:r,trackId:a.id,trackLabel:a.label}),r>0&&this.emitAudioTelemetry({name:`audio.acquisition.recovered`,properties:{successAttempt:r,totalAttempts:r+1,audioTrackLabel:a.label,usedRelaxedConstraints:r===2}}),a}catch(e){n=e;let t=i(e),a=Sx(e),o=kx(e);if($.warn(`[StreamManager] Audio acquisition failed`,{attempt:r,maxRetries:2,error:t,errorName:a,isRetriable:o}),this.emitAudioTelemetry({name:`audio.acquisition.retry`,properties:{attempt:r,maxRetries:2,errorMessage:t,errorName:a??`unknown`,isRetriable:o,usedRelaxedConstraints:r===2,willRetry:r<2&&o}}),!(r<2&&o))break;await this.waitMilliseconds(this.audioRetryDelayMilliseconds)}throw Ox(n)}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.audioStatus=`pending`,this.pendingAudioError=null,this.audioAcquisitionPromise=null,this.acquisitionGeneration++,this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await Jb().getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}setMediaStream(e){this.mediaStream=e}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}destroy(){this.stopStream(),this.eventListeners.clear(),this.setState(`idle`)}};let Mx=`recording.stop-not-ready`,Nx=`recording.finalize-not-ready`,Px=`recording.finalize-timeout`,Fx=`recording.upload-in-progress`;function Ix(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Lx(e){return!(e instanceof Error)||Rx(e)?e:e.message===`Not currently recording`?Ix(Mx,`Recording is not ready to stop`):e.message===`Processing not active`?Ix(Nx,`Recording is not ready to finalize`):e}function Rx(e){let t=e;return t.code===Mx||t.code===Nx||t.code===Px||t.code===Fx}let zx=[`Bytes`,`KB`,`MB`,`GB`],Bx=1024;function Vx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(Bx));return`${Math.round(e/Bx**t*100)/100} ${zx[t]}`}function Hx(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let Ux={getCurrentTimestamp:()=>performance.now()};var Wx=class{constructor(e){this.recordingStartTime=0,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!1,this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),this.blurHandler=this.handleBlur.bind(this),this.focusHandler=this.handleFocus.bind(this);let t=e?.getCurrentTimestamp;t===void 0?this.getCurrentTimestamp=Ux.getCurrentTimestamp:this.getCurrentTimestamp=t}start(e){this.isTracking||(this.recordingStartTime=e,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!0,typeof document<`u`&&document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler)),this.checkInitialState())}pause(){!this.isTracking||this.pauseStartTime!==null||(this.pauseStartTime=this.getCurrentTimestamp(),this.endCurrentIntervalIfActive())}resume(){if(!this.isTracking||this.pauseStartTime===null)return;let e=this.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}getIntervals(){return this.endCurrentIntervalIfActive(),this.intervals.map(e=>({start:this.normalizeTimestamp(e.start),end:this.normalizeTimestamp(e.end)}))}reset(){this.intervals=[],this.currentIntervalStart=null,this.totalPausedTime=0,this.pauseStartTime=null}cleanup(){this.isTracking=!1,this.endCurrentIntervalIfActive(),typeof document<`u`&&document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),window.removeEventListener(`focus`,this.focusHandler)),this.reset()}checkInitialState(){typeof document>`u`||document.visibilityState===`hidden`&&this.startInterval()}handleVisibilityChange(){typeof document>`u`||(document.visibilityState===`hidden`?this.startInterval():this.endCurrentIntervalIfActive())}handleBlur(){this.startInterval()}handleFocus(){this.endCurrentIntervalIfActive()}startInterval(){this.currentIntervalStart!==null||!this.isTracking||this.pauseStartTime===null&&(this.currentIntervalStart=this.getCurrentTimestamp())}endCurrentIntervalIfActive(){if(this.currentIntervalStart===null)return;let e=this.getCurrentTimestamp(),t=this.currentIntervalStart;e>t&&this.intervals.push({start:t,end:e}),this.currentIntervalStart=null}normalizeTimestamp(e){let t=(e-this.recordingStartTime-this.totalPausedTime)/1e3;return Math.max(0,t)}};let Gx=1e3,Kx=1e3,qx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},Jx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}},Yx={width:{ideal:1280,max:1280},height:{ideal:720,max:720},frameRate:{ideal:24,max:24}},Xx=`android-post-recording-transcode`;function Zx(e){let t=e.guidance?.message??`This browser or device cannot safely record video. Try a supported browser or upload an existing video file.`,n=Error(t);return n.name=`RecordingUnsupportedError`,n.code=`recording.unsupported-with-guidance`,n.isRecoverable=!0,n}let Qx={checkRecorderSupport:vb,getCurrentTimestamp:()=>performance.now()};var $x=class{constructor(e,t){this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.tabVisibilityTracker=null,this.visibilityChangeHandler=null,this.blurHandler=null,this.focusHandler=null,this.preResolvedSupportReport=null,this.activeRouteDecision=qx,this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.mediaRecorderErrorTimeoutId=null,this.streamManager=e;let n=t?.checkRecorderSupport,r;r=n===void 0?Qx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Qx.getCurrentTimestamp:i,this.dependencies={checkRecorderSupport:r,getCurrentTimestamp:a}}setPreResolvedSupportReport(e){this.preResolvedSupportReport=e}isRecording(){return this.streamManager.getState()===`recording`}getStreamProcessor(){return this.streamProcessor}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.streamManager.getAudioStreamForAnalysis()}async startRecording(e,t,n,r,i){this.activeRouteDecision=i??qx;let a=this.streamManager.getStream(),o=0;if(a!==null&&(o=a.getAudioTracks().length),$.debug(`[StreamRecordingState] startRecording called`,{hasMediaStream:!!a,isRecording:this.isRecording(),hasProcessor:!!e,audioTracks:o}),!a)throw Error(`Stream must be started before recording`);if(this.isRecording())return $.debug(`[StreamRecordingState] Already recording, returning`),Promise.resolve();if(!(a.getAudioTracks().length>0))throw $.error(`[StreamRecordingState] Cannot start recording without audio tracks`),Ob();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw Zx(this.activeRouteDecision);if(this.activeRouteDecision.route===`local-webcodecs`){let e=t.watermark!==void 0,n;if(n=this.preResolvedSupportReport?.isSupported?this.preResolvedSupportReport:await this.dependencies.checkRecorderSupport({requiresAudio:!0,requiresWatermark:e}),!n.isSupported)throw Nt({missingCapabilities:n.missing,resolutionStage:`feature-preflight`})}this.streamProcessor=e,$.debug(`[StreamRecordingState] StreamProcessor assigned, setting callbacks`),e.setOnMuteStateChange(e=>{this.streamManager.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.streamManager.emit(`videosourcechange`,{stream:e})}),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=Vx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Gx),this.resetRecordingState();let s;n===!0&&(s={enabled:!0,text:this.resolveTabVisibilityOverlayText(r),recordingStartTime:this.recordingStartTime}),$.debug(`[StreamRecordingState] Overlay config`,{enableTabVisibilityOverlay:n,hasOverlayText:!!r,overlayText:r,overlayConfig:s}),this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?(await this.startSafeCaptureRecording(a,t),$.info(`[StreamRecordingState] MediaRecorder capture started for post-recording transcode`)):($.debug(`[StreamRecordingState] Starting processing`),await e.startProcessing(a,t,s),$.info(`[StreamRecordingState] Processing started and worker ready`)),n&&($.debug(`[StreamRecordingState] Setting up tab visibility tracking`,{recordingStartTime:this.recordingStartTime}),this.tabVisibilityTracker=new Wx,this.tabVisibilityTracker.start(this.recordingStartTime),this.setupVisibilityUpdates(e)),this.streamManager.setState(`recording`),this.streamManager.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer()}async stopRecording(){let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Kx;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Ix(Mx,`Recording is not ready to stop`,{hasStreamProcessor:!!this.streamProcessor,streamState:this.streamManager.getState()});this.streamManager.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState(),this.cleanupVisibilityUpdates();let t=[];this.tabVisibilityTracker?(t=this.tabVisibilityTracker.getIntervals(),$.debug(`[StreamRecordingState] Tab visibility intervals collected`,{intervalsCount:t.length,intervals:t}),this.tabVisibilityTracker.cleanup(),this.tabVisibilityTracker=null):$.debug(`[StreamRecordingState] No tab visibility tracker was active`);let n;if(this.activeRouteDecision.route===`safe-capture-post-recording-transcode`){let e=await this.stopSafeCaptureRecording();$.debug(`[StreamRecordingState] Finalizing MediaRecorder capture`),n={blob:e.blob,mediaRecorderDiagnostics:e.diagnostics}}else $.debug(`[StreamRecordingState] Finalizing stream processor`),n=await this.streamProcessor.finalize(),$.info(`[StreamRecordingState] Stream processor finalized`,{blobSize:n.blob.size,hasBlob:!!n.blob});return this.streamManager.setState(`active`),this.streamManager.emit(`recordingstop`,{blob:n.blob,mimeType:n.blob.type||`video/mp4`}),{blob:n.blob,tabVisibilityIntervals:t,recordingStats:n.recordingStats,encoderAcceleration:n.encoderAcceleration,mediaRecorderDiagnostics:n.mediaRecorderDiagnostics}}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=this.dependencies.getCurrentTimestamp()),this.tabVisibilityTracker&&this.tabVisibilityTracker.pause(),this.mediaRecorder?.state===`recording`&&this.mediaRecorder.pause?.(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=this.dependencies.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.tabVisibilityTracker&&this.tabVisibilityTracker.resume(),this.mediaRecorder?.state===`paused`&&this.mediaRecorder.resume?.(),this.startRecordingTimer(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.resume()}toggleMute(){qb(this.streamProcessor,`StreamProcessor`).toggleMute()}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!1)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!1),this.streamManager.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!0)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!0),this.streamManager.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();let e=this.streamManager.getStream();if(e){let t=e.getAudioTracks();return t.length>0&&t.every(e=>!e.enabled)}return!1}async switchVideoSource(e){await qb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Kb(qb(this.streamProcessor,`StreamProcessor`).getCurrentVideoSource(),`Current video source is not available`)}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Kx,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Gx)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=this.dependencies.getCurrentTimestamp(),this.totalPausedTime=0,this.pauseStartTime=null}async startSafeCaptureRecording(e,t){if(typeof MediaRecorder>`u`)throw Zx({route:`unsupported-with-guidance`,reasonCodes:[`mediarecorder-unavailable`],guidance:{canRetry:!0,message:`This browser cannot safely record on this device. Try a supported browser or upload an existing video file.`}});await this.applySafeCaptureTrackConstraints(e),this.mediaRecorderChunks=[],this.mediaRecorderError=null;let n=this.resolvePreferredSafeCaptureMimeType(t),r=n===void 0?void 0:{mimeType:n},i=new MediaRecorder(e,r);this.mediaRecorder=i,this.mediaRecorderStopPromise=new Promise((e,t)=>{this.mediaRecorderStopResolve=e,this.mediaRecorderStopReject=t}),this.mediaRecorderStopPromise.catch(()=>void 0),i.ondataavailable=e=>{e.data.size>0&&this.mediaRecorderChunks.push(e.data)},i.onstop=()=>{if(this.clearMediaRecorderErrorTimeout(),this.mediaRecorderError!==null){this.updateMediaRecorderErrorDiagnostics(i),this.mediaRecorderStopReject?.(this.mediaRecorderError);return}let e=i.mimeType||this.resolveSafeCaptureMimeType(),t=new Blob(this.mediaRecorderChunks,{type:e}),n=this.buildMediaRecorderDiagnostics(i);if(t.size>0){this.mediaRecorderStopResolve?.({blob:t,diagnostics:n});return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(i))},i.onerror=e=>{this.mediaRecorderError=this.createMediaRecorderError(e,i)},i.start(1e3)}async applySafeCaptureTrackConstraints(e){let t=this.resolveSafeCaptureVideoConstraints();if(t===null)return;let n=e.getVideoTracks();await Promise.all(n.map(async e=>{try{await e.applyConstraints(t)}catch(e){$.warn(`[StreamRecordingState] Could not apply safe capture video constraints`,e)}}))}resolveSafeCaptureVideoConstraints(){let e=this.activeRouteDecision.reasonCodes;return e.includes(`insufficient-device-memory`)||e.includes(`insufficient-hardware-concurrency`)||e.includes(`encoding-capability-unsupported`)||e.includes(`encoding-not-smooth`)||e.includes(`encoding-not-power-efficient`)?Jx:e.includes(Xx)?Yx:null}async stopSafeCaptureRecording(){let e=this.mediaRecorder,t=this.mediaRecorderStopPromise;if(!(e&&t))throw Error(`Safe capture recorder was not started`);e.state!==`inactive`&&e.stop(),this.scheduleMediaRecorderErrorFinalizeTimeout(e);try{return await t}finally{this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx}}resolveSafeCaptureMimeType(){return(this.streamManager.getStream()?.getVideoTracks().length??0)>0?`video/webm`:`audio/webm`}resolvePreferredSafeCaptureMimeType(e){let t=e=>typeof MediaRecorder.isTypeSupported==`function`?MediaRecorder.isTypeSupported(e):!1,n=[`video/webm;codecs=vp8,opus`,`video/webm;codecs=vp9,opus`,`video/webm`],r=[`video/mp4;codecs=avc1.42E01E,mp4a.40.2`,`video/mp4;codecs=avc1.42001f,mp4a.40.2`,`video/mp4`],i=r;return this.shouldPreferWebmSafeCapture(e)?i=[...n,...r]:e.format!==`mp4`&&(i=n),i.find(t)}shouldPreferWebmSafeCapture(e){return e.format===`mp4`?this.activeRouteDecision.reasonCodes.includes(Xx):!1}scheduleMediaRecorderErrorFinalizeTimeout(e){this.mediaRecorderErrorTimeoutId===null&&(this.mediaRecorderErrorTimeoutId=window.setTimeout(()=>{if(this.mediaRecorderError!==null){this.mediaRecorderStopReject?.(this.mediaRecorderError);return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(e))},5e3))}clearMediaRecorderErrorTimeout(){this.mediaRecorderErrorTimeoutId!==null&&(window.clearTimeout(this.mediaRecorderErrorTimeoutId),this.mediaRecorderErrorTimeoutId=null)}createMediaRecorderError(e,t){let n=e.error,r=Error(`Browser recording failed before upload could start`);return r.name=`MediaRecorderRecordingError`,r.code=`recording.mediarecorder-error`,r.mediaRecorderMimeType=t.mimeType,r.mediaRecorderChunkCount=this.mediaRecorderChunks.length,r.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),n?.name&&(r.mediaRecorderErrorName=n.name),n?.message&&(r.mediaRecorderErrorMessage=n.message),r}createEmptyMediaRecorderError(e){let t=Error(`Browser recording produced no data before upload could start`);return t.name=`MediaRecorderEmptyDataError`,t.code=`recording.mediarecorder-empty`,t.mediaRecorderMimeType=e.mimeType,t.mediaRecorderChunkCount=this.mediaRecorderChunks.length,t.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}updateMediaRecorderErrorDiagnostics(e){this.mediaRecorderError!==null&&(this.mediaRecorderError.mediaRecorderMimeType=e.mimeType,this.mediaRecorderError.mediaRecorderChunkCount=this.mediaRecorderChunks.length,this.mediaRecorderError.mediaRecorderChunkSize=this.getMediaRecorderChunkSize())}buildMediaRecorderDiagnostics(e){let t={mediaRecorderMimeType:e.mimeType,mediaRecorderChunkCount:this.mediaRecorderChunks.length,mediaRecorderChunkSize:this.getMediaRecorderChunkSize(),mediaRecorderHadError:this.mediaRecorderError!==null};return this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}getMediaRecorderChunkSize(){return this.mediaRecorderChunks.reduce((e,t)=>e+t.size,0)}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}resolveTabVisibilityOverlayText(e){return e===void 0||e.trim().length===0?`User in another tab`:e}setupVisibilityUpdates(e){if(typeof document>`u`||typeof window>`u`){$.warn(`[StreamRecordingState] Cannot setup visibility updates - document/window not available`);return}if(this.visibilityChangeHandler=()=>{if(typeof document>`u`)return;let t=document.visibilityState===`hidden`,n=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Visibility change`,{isHidden:t,timestamp:n,visibilityState:document.visibilityState}),e.updateTabVisibility(t,n)},this.blurHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window blur`,{timestamp:t}),e.updateTabVisibility(!0,t)},this.focusHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window focus`,{timestamp:t}),e.updateTabVisibility(!1,t)},document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler),document.visibilityState===`hidden`){let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Initial state is hidden`,{timestamp:t}),e.updateTabVisibility(!0,t)}else $.debug(`[StreamRecordingState] Initial state is visible`)}cleanupVisibilityUpdates(){this.visibilityChangeHandler&&typeof document<`u`&&(document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.blurHandler&&typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),this.blurHandler=null),this.focusHandler&&typeof window<`u`&&(window.removeEventListener(`focus`,this.focusHandler),this.focusHandler=null)}destroy(){this.mediaRecorder&&this.mediaRecorder.state!==`inactive`&&this.mediaRecorder.stop(),this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},eS=class{constructor(e={}){this.streamManager=new jx(e),this.recordingState=new $x(this.streamManager)}getState(){return this.streamManager.getState()}getStream(){return this.streamManager.getStream()}getAudioStreamForAnalysis(){return this.recordingState.getAudioStreamForAnalysis()}isRecording(){return this.recordingState.isRecording()}isActive(){return this.streamManager.isActive()}on(e,t){return this.streamManager.on(e,t)}off(e,t){this.streamManager.off(e,t)}once(e,t){return this.streamManager.once(e,t)}setAudioDevice(e){this.streamManager.setAudioDevice(e)}setVideoDevice(e){this.streamManager.setVideoDevice(e)}getAudioDevice(){return this.streamManager.getAudioDevice()}getVideoDevice(){return this.streamManager.getVideoDevice()}async getAvailableDevices(){return await this.streamManager.getAvailableDevices()}async startStream(){return await this.streamManager.startStream()}stopStream(){this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(e,t,n,r,i){return await this.recordingState.startRecording(e,t,n,r,i)}async stopRecording(){return await this.recordingState.stopRecording()}pauseRecording(){this.recordingState.pauseRecording()}resumeRecording(){this.recordingState.resumeRecording()}toggleMute(){this.recordingState.toggleMute()}muteAudio(){this.recordingState.muteAudio()}unmuteAudio(){this.recordingState.unmuteAudio()}isMuted(){return this.recordingState.isMuted()}async switchVideoSource(e){return await this.recordingState.switchVideoSource(e)}setMediaStream(e){this.streamManager.setMediaStream(e)}getCurrentVideoSource(){return this.recordingState.getCurrentVideoSource()}getAudioStatus(){return this.streamManager.getAudioStatus()}isAudioReady(){return this.streamManager.isAudioReady()}async waitForAudio(){return await this.streamManager.waitForAudio()}setPreResolvedSupportReport(e){this.recordingState.setPreResolvedSupportReport(e)}destroy(){this.recordingState.destroy(),this.streamManager.destroy()}};let tS=new Set([`recording.audio-no-chunks`,`recording.audio-silent`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`,`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]),nS=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),rS=new Set([`recording.post-recording-transcode-fallback`,`recording.mediarecorder-empty`,`recording.mediarecorder-error`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),iS=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),aS=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),oS=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),sS=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function cS(e){return e.startsWith(`recording.`)?tS.has(e):!1}function lS(e){return e==null?null:i(e)}function uS(e){if(!(e&&typeof e==`object`&&`code`in e))return null;let t=e.code;return typeof t!=`string`||t.length===0?null:t}function dS(e){return e?nS.has(e)?`recording.codec-unsupported`:rS.has(e)?`recording.post-recording-transcode-fallback`:iS.has(e)?`recording.no-video-frames`:aS.has(e)?`recording.finalize-timeout-low-resource`:oS.has(e)?`recording.not-started-state-race`:sS.has(e)?`recording.unsupported-device`:null:null}function fS(e,t){return t.some(t=>e.includes(t))}function pS(e){if(!e)return null;let t=e.toLowerCase();return fS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:fS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:fS(t,[`no video frames`,`zero video frames`,`video.first-frame-timeout`,`failed to yield first frame`,`frame-loss`,`excessive frame errors`])?`recording.no-video-frames`:fS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:fS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:fS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function mS(e){return dS(e.errorCode??uS(e.error))||pS(e.errorMessage??lS(e.error))}let hS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function gS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=mS({errorCode:t,error:r});if(t===`browser.unsupported`)return{visible:!0,variant:`browser`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!0,isPermissionDenied:!1};if(t&&cS(t))return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(i)return{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1,actionableCode:i,isRecordingPipelineError:!0};if(t?.startsWith(`camera.`)){let e=t===`camera.permission-denied`;return{visible:!0,variant:`camera`,canRetry:!e,isCameraError:!0,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:e}}if(n)return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(t?.startsWith(`audio.`)){let e=t===`audio.permission-denied`;return{visible:!0,variant:`audio`,canRetry:!e,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:e}}return r?{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1}:hS}let _S=`VIDTREO_INSTALLATION_ID`,vS=`unknown`,yS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,bS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i,xS=[`mediaRecorderErrorName`,`mediaRecorderErrorMessage`,`mediaRecorderMimeType`,`mediaRecorderChunkCount`,`mediaRecorderChunkSize`];function SS(e){let t=e.storageProvider,n=t?.getItem(_S);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=CS(e);return t?.setItem(_S,r),$.debug(`Created new installation ID`,{installationId:r}),r}function CS(e){let t=e.cryptoProvider;if(t?.getRandomValues){let e=new Uint8Array(16);return t.getRandomValues(e),Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}let n=e.nowProvider().toString(16),r=e.randomProvider();return`${n}-${Math.floor(r*1e9).toString(16)}`}let wS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],TS=[`stream.error`],ES={"sdk.init.started":`lifecycle`,"sdk.init.succeeded":`lifecycle`,"sdk.init.failed":`error`,"preview.start.succeeded":`interaction`,"preview.start.failed":`error`,"recording.start.requested":`interaction`,"recording.start.succeeded":`interaction`,"recording.start.failed":`error`,"recording.stop.requested":`interaction`,"recording.stop.succeeded":`interaction`,"recording.stop.failed":`error`,"recording.route.selected":`lifecycle`,"upload.started":`performance`,"upload.succeeded":`performance`,"upload.failed":`error`,"upload.route.selected":`lifecycle`,"transcode.route.selected":`lifecycle`,"source.switch.requested":`interaction`,"source.switch.succeeded":`interaction`,"source.switch.failed":`error`,"stream.error":`error`,"audio.acquisition.fallback":`lifecycle`,"audio.acquisition.retry":`lifecycle`,"audio.acquisition.recovered":`lifecycle`,"audio.acquisition.failed":`error`,"audio.warning":`performance`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var DS=class{constructor(e,t){this.pendingEvents=[],this.flushTimeoutId=null,this.throttledEventTimestamps=new Map,this.retryCountMap=new Map,this.oneTimeEventCache=new Map,this.config=e,this.dependencies=t,this.installationId=SS(this.dependencies),$.debug(`TelemetryClient initialized`,{installationId:this.installationId,backendUrl:e.backendUrl})}triggerTelemetryEvent(e){try{let t=this.dependencies.nowProvider();if(this.shouldSkipEvent(e.name,t))return;let n=ES[e.name],r=this.buildError(e.error),i=this.buildFingerprint(),a=this.buildContext(),o=this.mergeProperties(this.buildBaseProperties(i),e),s={event:e.name,category:n,timestamp:t,installationId:this.installationId,fingerprint:i,sdkVersion:`1.7.0`,context:a,properties:o,error:r};this.markEventTracking(e.name,t),this.enqueueEvent(s)}catch(t){$.error(`Telemetry event failed`,{eventName:e.name,error:i(t)})}}enqueueEvent(e){try{if(this.pendingEvents=[...this.pendingEvents,e],this.pendingEvents.length>=10){this.flushQueue();return}this.scheduleFlush()}catch(e){$.error(`Failed to enqueue telemetry event`,{error:i(e)})}}scheduleFlush(){this.flushTimeoutId||=this.dependencies.setTimeoutFunction(()=>{this.flushQueue()},1e3)}flushQueue(){try{if(this.pendingEvents.length===0){this.clearFlushTimer();return}let e=this.pendingEvents;this.pendingEvents=[],this.clearFlushTimer();let t=this.buildRequestPayload(e);$.debug(`Telemetry batch flush`,{eventsCount:t.events.length}),this.sendPayload(t).then(()=>{this.clearRetryMetadata(e)}).catch(()=>{this.requeueFailedEvents(e)})}catch(e){$.error(`Failed to flush telemetry queue`,{error:i(e)})}}clearFlushTimer(){this.flushTimeoutId&&=(this.dependencies.clearTimeoutFunction(this.flushTimeoutId),null)}buildRequestPayload(e){return{events:[...e]}}shouldSkipEvent(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);if(this.oneTimeEventCache.get(t))return $.debug(`Telemetry event skipped (dedupe)`,{event:e}),!0}if(this.isThrottledEvent(e)){let n=this.throttledEventTimestamps.get(e);if(n!==void 0&&t-n<5e3)return $.debug(`Telemetry event skipped (throttle)`,{event:e,lastSent:n}),!0}return!1}markEventTracking(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);this.oneTimeEventCache.set(t,!0)}this.isThrottledEvent(e)&&(this.throttledEventTimestamps=this.updateNumberMap(this.throttledEventTimestamps,e,t))}updateNumberMap(e,t,n){let r=new Map(e);return r.set(t,n),r}getOneTimeCacheKey(e){return`${this.installationId}:${e}`}isOneTimeEvent(e){return wS.includes(e)}isThrottledEvent(e){return TS.includes(e)}buildBaseProperties(e){let t={},n=e.userAgent,r=this.getBrowserName(n);return r&&(t={...t,browserName:r}),t}mergeProperties(e,t){let n=this.sanitizeEventProperties(t.properties),r=this.buildErrorProperties(t.error);if(Object.keys(e).length===0&&Object.keys(r).length===0&&!n)return;let i={...e,...r,...n};if(Object.keys(i).length>0)return i}sanitizeEventProperties(e){if(!e)return;let t=this.sanitizeRouteDecision(e.routeDecision);return t===void 0?e:{...e,routeDecision:t}}sanitizeRouteDecision(e){if(!(e&&typeof e==`object`))return;let t=e,n={};typeof t.selectedRoute==`string`&&(n={...n,selectedRoute:t.selectedRoute}),Array.isArray(t.reasonCodes)&&(n={...n,reasonCodes:t.reasonCodes.filter(e=>typeof e==`string`)});let r=this.sanitizeCapabilitySummary(t.capabilitySummary);if(r!==void 0&&(n={...n,capabilitySummary:r}),this.isRouteSourceType(t.sourceType)&&(n={...n,sourceType:t.sourceType}),typeof t.clientTranscodeDeferred==`boolean`&&(n={...n,clientTranscodeDeferred:t.clientTranscodeDeferred}),Object.keys(n).length!==0)return n}sanitizeCapabilitySummary(e){if(!(e&&typeof e==`object`))return;let t={};for(let[n,r]of Object.entries(e))this.isSafeCapabilityValue(r)&&(t={...t,[n]:r});if(Object.keys(t).length!==0)return t}isSafeCapabilityValue(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`?!0:Array.isArray(e)&&e.every(e=>typeof e==`string`)}isRouteSourceType(e){return e===`live-recorder`||e===`native-camera`||e===`file-upload`}buildErrorProperties(e){if(!e)return{};let t={},n=uS(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=mS({errorCode:a,error:e,errorMessage:r});return a&&(t={...t,errorCode:a}),o&&(t={...t,rawErrorClassification:o,recordingPipelineErrorCode:o}),{...t,...this.buildMediaRecorderErrorProperties(e)}}buildMediaRecorderErrorProperties(e){if(!(e&&typeof e==`object`))return{};let t=e,n={};for(let e of xS){let r=t[e];(typeof r==`string`||typeof r==`number`||typeof r==`boolean`)&&(n={...n,[e]:r})}return n}buildFingerprint(){let e=this.dependencies.navigatorProvider;if(!e)return{};let t={userAgent:e.userAgent,language:e.language,platform:e.platform};e.hardwareConcurrency&&(t={...t,hardwareConcurrency:e.hardwareConcurrency});let n=this.getDeviceMemory(e);return n!==null&&(t={...t,deviceMemory:n}),t}buildContext(){let e=this.config.pageUrl,t=this.config.referrerUrl;if(!e){let t=this.dependencies.locationProvider;t&&(e=t.href)}if(!t){let e=this.dependencies.documentProvider;if(e){let n=e.referrer;n&&(t=n)}}return{sessionId:this.config.sessionId,userId:this.config.userId,environmentId:this.config.environmentId,appVersion:this.config.appVersion,release:this.config.release,pageUrl:e,referrerUrl:t,sdkLocation:this.config.sdkLocation,clientLocation:this.config.clientLocation}}buildError(e){if(!e)return;let t=i(e),n={message:t},r=uS(e),a=r??this.extractNormalizedErrorCode(t);return a&&(n.normalizedCode=a),r?n.code=r:a&&(n.code=a),e instanceof Error&&(!n.code&&e.name&&(n.code=e.name),e.stack&&(n.stack=e.stack)),n}extractNormalizedErrorCode(e){let t=e.match(yS);if(t?.[1])return t[1];let n=e.match(bS);return n?.[1]?n[1]:null}getBrowserName(e){return e?e.includes(`Edg`)?`edge`:e.includes(`Chrome`)?`chrome`:e.includes(`Firefox`)?`firefox`:e.includes(`Safari`)?`safari`:vS:vS}getDeviceMemory(e){let t=e;return t.deviceMemory?t.deviceMemory:null}async sendPayload(e){let t=this.buildTelemetryEndpoint(),n={method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${this.config.apiKey}`},body:JSON.stringify(e)};$.debug(`Sending telemetry to endpoint`,{endpoint:t,payloadSize:JSON.stringify(e).length,hasApiKey:!!this.config.apiKey});let r=await this.dependencies.fetchFunction(t,n).catch(e=>{throw $.error(`Failed to send telemetry`,{endpoint:t,error:i(e)}),e});if(r&&!r.ok)throw $.error(`Telemetry endpoint returned error`,{status:r.status}),Error(`Telemetry HTTP ${r.status}`)}requeueFailedEvents(e){let t=e.filter(e=>(this.retryCountMap.get(e)??0)<3);for(let e of t){let t=this.retryCountMap.get(e)??0;this.retryCountMap.set(e,t+1)}let n=e.length-t.length;if(n>0){let r=e.filter(e=>!t.includes(e));this.clearRetryMetadata(r),$.warn(`Dropped ${n} telemetry events after max retries`)}if(t.length===0)return;let r=this.pendingEvents.length,i=Math.max(0,100-r);this.pendingEvents=[...t.slice(0,i),...this.pendingEvents],this.scheduleFlush()}clearRetryMetadata(e){for(let t of e)this.retryCountMap.delete(t)}buildTelemetryEndpoint(){return this.config.endpoint?this.config.endpoint:`${this.config.backendUrl}/api/v1/telemetry`}};function OS(){let e=typeof window<`u`,t=typeof document<`u`,n=fetch,r=null,i=null,a=null,o=null,s=null,c=setTimeout,l=clearTimeout;return e&&(n=window.fetch.bind(window),r=window.crypto,i=window.localStorage,a=window.navigator,o=window.location,c=window.setTimeout.bind(window),l=window.clearTimeout.bind(window)),t&&(s=document),{fetchFunction:n,cryptoProvider:r,storageProvider:i,navigatorProvider:a,locationProvider:o,documentProvider:s,nowProvider:()=>Date.now(),randomProvider:()=>Math.random(),setTimeoutFunction:c,clearTimeoutFunction:l}}function kS(e,t,n){return new DS({apiKey:e,backendUrl:t,endpoint:n?.endpoint,sessionId:n?.sessionId,userId:n?.userId,environmentId:n?.environmentId,appVersion:n?.appVersion,release:n?.release,pageUrl:n?.pageUrl,referrerUrl:n?.referrerUrl,sdkLocation:n?.sdkLocation,clientLocation:n?.clientLocation},OS())}var AS=class{constructor(e,t){this.isProcessing=!1,this.hasRecoveredStaleUploads=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=t,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`network-recovery`,Error(t))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`processing-loop`,Error(t))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue().catch(e=>{let n=i(e);this.callbacks.onUploadError?.(t,Error(n))}),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);if(!this.hasRecoveredStaleUploads){let e=await this.storageService.getPendingUploads(`uploading`);await Promise.all(e.map(e=>this.storageService.updateUploadStatus(e.id,{status:`pending`}))),this.hasRecoveredStaleUploads=!0}let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${i(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(t){let n=i(t),r=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:r,lastError:n}),r>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${n}`));else{let e=this.calculateRetryDelay(r);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`scheduled-retry`,Error(t))})},e)}clearTimer(e,t){e!==null&&t(e)}},jS=class{uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);return this.uploadVideoFile(e,t)}uploadVideoFile(e,t){return new Promise((n,r)=>{let i=new XMLHttpRequest,a=this.createUploadBlob(e,t.mimeType);if(t.onProgress){let e=t.onProgress;i.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}i.addEventListener(`load`,()=>{if(i.status>=200&&i.status<=299){this.parseSuccessResponse(i,n,r);return}this.parseErrorResponse(i,r)}),i.addEventListener(`error`,()=>{r(Error(`Network error during upload`))}),i.addEventListener(`abort`,()=>{r(Error(`Upload was aborted`))});let o=`${t.backendUrl}/api/v1/videos/upload`;i.open(`POST`,o),i.setRequestHeader(`Authorization`,`Bearer ${t.apiKey}`);let s=new FormData;s.append(`file`,a,t.filename);let c={filename:t.filename,mimeType:a.type};t.userMetadata&&(c.userMetadata=t.userMetadata),s.append(`metadata`,JSON.stringify(c)),i.send(s)})}createUploadBlob(e,t){let n=this.resolveUploadMimeType(e,t);return n===e.type?e:new Blob([e],{type:n})}resolveUploadMimeType(e,t){return t&&t.trim().length>0?this.normalizeMimeType(t):this.normalizeMimeType(e.type)}normalizeMimeType(e){let[t]=e.split(`;`);return t===void 0?e.trim().toLowerCase():t.trim().toLowerCase()}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}let i=r.data;if(!i){n(Error(`Failed to parse upload response: missing data`));return}t({id:i.id,publicId:i.publicId,filename:i.filename,fileSize:i.fileSize,mimeType:i.mimeType,duration:i.duration,status:i.status,uploadUrl:i.uploadUrl,createdAt:i.createdAt})}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let MS=e=>{},NS=e=>{},PS=e=>{},FS=()=>{},IS=e=>{},LS=(e,t)=>{},RS=e=>{},zS=e=>{},BS=e=>{},VS=()=>{},HS=e=>{};function US(e){let t={onProgress:MS,onSuccess:NS,onError:PS,onClearStatus:FS};return e.upload&&(t=e.upload),t}let WS=e=>{};function GS(e){let t=HS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function KS(e){let t=WS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function qS(e,t){let n=e.recording,r=IS;n?.onStateChange&&(r=n.onStateChange);let i=LS;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=RS;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=zS;n?.onError&&(o=n.onError);let s=BS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=VS;return n?.onClearUploadStatus&&(c=n.onClearUploadStatus),{onStateChange:r,onCountdownUpdate:i,onTimerUpdate:a,onError:o,onRecordingComplete:s,onClearUploadStatus:c,onStopAudioTracking:t.stopAudioTracking,onGetConfig:t.getConfig,...t.getRouteDecision&&{onGetRouteDecision:t.getRouteDecision},...t.onAudioWarning&&{onAudioWarning:t.onAudioWarning},...t.onAudioRecovered&&{onAudioRecovered:t.onAudioRecovered},...t.onTranscodingProgress&&{onTranscodingProgress:t.onTranscodingProgress}}}function JS(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,onScreenSelectionStart:()=>{t.isRecording()&&t.updateSourceType(!0)},onScreenSelectionEnd:()=>{t.isRecording()&&t.updateSourceType(!1)},getSelectedCameraDeviceId:t.getSelectedCameraDeviceId,getSelectedMicDeviceId:t.getSelectedMicDeviceId}}var YS=class{constructor(e={}){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1,this.silenceThreshold=this.resolveNumber(e.silenceThreshold,.001),this.lowSignalThreshold=this.resolveNumber(e.lowSignalThreshold,.05),this.mutedSpeechThreshold=this.resolveNumber(e.mutedSpeechThreshold,this.silenceThreshold),this.silentWarningDurationMs=this.resolveNumber(e.silentWarningDurationMs,2e3),this.lowSignalWarningDurationMs=this.resolveNumber(e.lowSignalWarningDurationMs,2e3),this.mutedSpeechWarningDurationMs=this.resolveNumber(e.mutedSpeechWarningDurationMs,1e4),this.noChunkWarningDurationMs=this.resolveNumber(e.noChunkWarningDurationMs,2e3)}recordChunk(e){this.markStarted(e.timestampMs),this.trackMuteState(e.timestampMs,e.isMuted);let t=this.calculateChunkStats(e.samples),n=this.resolveOptionalNumber(e.inputPeak,t.peak),r=this.resolveOptionalNumber(e.inputRms,t.rms),i=t.peak<=this.silenceThreshold,a=!e.isMuted&&t.peak>this.silenceThreshold&&t.peak<this.lowSignalThreshold,o=e.isMuted&&n>this.mutedSpeechThreshold;return this.totalChunks+=1,this.peak=t.peak,this.rms=t.rms,this.inputPeak=n,this.inputRms=r,i||(this.nonSilentChunks+=1,this.silentStartedAtMs=null),a&&(this.lowSignalChunks+=1),t.peak>=this.lowSignalThreshold&&(this.hasHealthySignal=!0),i&&this.silentStartedAtMs===null&&(this.silentStartedAtMs=e.timestampMs),a&&this.lowSignalStartedAtMs===null&&(this.lowSignalStartedAtMs=e.timestampMs),a||(this.lowSignalStartedAtMs=null),o&&this.mutedSpeechStartedAtMs===null&&(this.mutedSpeechStartedAtMs=e.timestampMs),o||(this.mutedSpeechStartedAtMs=null),this.lastChunkTimestampMs=e.timestampMs,this.snapshot(e.timestampMs,e.isMuted)}inspect(e,t){return this.markStarted(e),this.trackMuteState(e,t),this.snapshot(e,t)}reset(){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1}snapshot(e,t){let n=this.resolveSilentDuration(e),r=this.resolveLowSignalDuration(e),i=this.resolveMutedSpeechDuration(e),a=this.resolveNoChunkDuration(e),o=this.resolveMutedDuration(e,t);return{classification:this.classify(t,n,r,i,a),totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,peak:this.peak,rms:this.rms,inputPeak:this.inputPeak,inputRms:this.inputRms,consecutiveSilentDurationMs:n,consecutiveLowSignalDurationMs:r,consecutiveMutedSpeechDurationMs:i,noChunkDurationMs:a,mutedDurationMs:o,hasHealthySignal:this.hasHealthySignal}}getFinalSnapshot(e,t){let n=this.resolveMutedDuration(e,t);return{totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,mutedDurationMs:n,hasHealthySignal:this.hasHealthySignal}}classify(e,t,n,r,i){return this.totalChunks===0&&i>=this.noChunkWarningDurationMs?`no-chunks`:e&&r>=this.mutedSpeechWarningDurationMs?`speaking-while-muted`:e&&t>=this.silentWarningDurationMs?`muted-silence-expected`:!e&&t>=this.silentWarningDurationMs?`silent-while-unmuted`:!e&&this.nonSilentChunks>0&&this.peak<this.lowSignalThreshold&&n>=this.lowSignalWarningDurationMs?`low-signal`:`healthy`}calculateChunkStats(e){if(e.length===0)return{peak:0,rms:0};let t=0,n=0;for(let r of e){let e=Math.abs(r);t=Math.max(t,e),n+=r*r}return{peak:t,rms:Math.sqrt(n/e.length)}}resolveSilentDuration(e){return this.silentStartedAtMs===null?0:e-this.silentStartedAtMs}resolveLowSignalDuration(e){return this.lowSignalStartedAtMs===null?0:e-this.lowSignalStartedAtMs}resolveMutedSpeechDuration(e){return this.mutedSpeechStartedAtMs===null?0:e-this.mutedSpeechStartedAtMs}resolveNoChunkDuration(e){return this.lastChunkTimestampMs===null?this.startedAtMs===null?0:e-this.startedAtMs:e-this.lastChunkTimestampMs}markStarted(e){this.startedAtMs===null&&(this.startedAtMs=e)}trackMuteState(e,t){if(t!==this.currentMuted){if(t){this.mutedStartedAtMs=e,this.currentMuted=!0;return}this.mutedStartedAtMs!==null&&(this.mutedDurationMs+=e-this.mutedStartedAtMs),this.mutedStartedAtMs=null,this.currentMuted=!1}}resolveMutedDuration(e,t){return t&&this.mutedStartedAtMs!==null?this.mutedDurationMs+e-this.mutedStartedAtMs:this.mutedDurationMs}resolveNumber(e,t){if(e===void 0)return t;if(!Number.isFinite(e)||e<0)throw Error(`Audio health monitor option must be a non-negative number`);return e}resolveOptionalNumber(e,t){return e===void 0||!Number.isFinite(e)||e<0?t:e}};function XS(e){let t=e.getVideoTracks();if(t.length===0)return!1;let n=t[0];return`displaySurface`in n.getSettings()||n.label.toLowerCase().includes(`screen`)||n.label.toLowerCase().includes(`display`)}Sv();function ZS(e){if(e!==void 0)return typeof e==`number`?e:e===cf?`low`:e===lf?`medium`:e===uf?`high`:e===df?`very-high`:`high`}function QS(e){let t=null,n=0;function r(){if(!t){let n=e.createBlob();t=e.createObjectUrl(n)}return n+=1,t}function i(){n!==0&&(--n,n===0&&(t&&=(e.revokeObjectUrl(t),null)))}return{acquire:r,release:i}}let $S=`vidtreo-audio-worklet`,eC=`audioChunk`,tC=`setMuted`,nC=`setPaused`,rC=`shutdown`,iC=`
140
+ };`],{type:`application/javascript`})}function qy(){let e=Ky();return URL.createObjectURL(e)}function Jy(e){URL.revokeObjectURL(e)}let Yy=`probe`,Xy=`probeResult`,Zy=`mediaStreamTrackProcessor`,Qy=`unavailable`,$y=`unavailable`,eb=new Map,tb=new Map;function nb(e,t){return typeof e==`boolean`?e:t}function rb(e){return e?`1`:`0`}function ib(e,t){return[`audio`,rb(e),`watermark`,rb(t)].join(`|`)}function ab(){return typeof process>`u`||process.env,!0}function ob(e){return e.probeResult.hasMediaStreamTrackProcessor?`worker-track`:e.hasMainThreadMediaStreamTrackProcessor?`main-thread-stream`:Qy}function sb(e){return e.requiresAudio?e.hasMainThreadMediaStreamTrackProcessor&&e.probeResult.hasAudioData?`main-thread-audio-stream`:e.hasAudioContext&&e.hasAudioWorklet?`audio-worklet-chunks`:$y:`none-required`}function cb(e,t){return e.includes(t)?e:[...e,t]}function lb(e,t){let n=e;return t.hasWorker||(n=cb(n,`worker`)),t.probeResult.hasVideoFrame||(n=cb(n,`videoFrame`)),t.probeResult.hasOffscreenCanvas||(n=cb(n,`offscreenCanvas`)),t.probeResult.hasReadableStream||(n=cb(n,`readableStream`)),n}function ub(e,t){let n=e;return t.requiresWatermark&&!t.probeResult.hasCreateImageBitmap&&(n=cb(n,`createImageBitmap`)),n}function db(e,t){let n=e;return t.videoPath===Qy&&(n=cb(n,Zy)),n}function fb(e,t){let n=e;return t.hasMainThreadMediaStreamTrackProcessor&&t.probeResult.hasAudioData?n:(t.hasMainThreadMediaStreamTrackProcessor||(n=cb(n,Zy)),t.hasMainThreadMediaStreamTrackProcessor&&!t.probeResult.hasAudioData&&(n=cb(n,`audioData`)),n)}function pb(e,t){let n=e;return t.hasAudioContext&&t.hasAudioWorklet?n:(t.hasAudioContext||(n=cb(n,`audioContext`)),t.hasAudioWorklet||(n=cb(n,`audioWorklet`)),n)}function mb(e,t){let n=e;return t.requiresAudio&&t.audioPath===$y?(n=fb(n,t),n=pb(n,t),n):n}function hb(e){let t=[];return t=lb(t,e),t=ub(t,e),t=db(t,e),t=mb(t,e),t}function gb(e,t){return!(e===Qy||t===$y)}function _b(e,t){return!(!e.hasVideoFrame||!e.hasOffscreenCanvas||!e.hasReadableStream||t&&!e.hasCreateImageBitmap)}async function vb(e={},t={}){let n=nb(e.requiresAudio,!0),r=nb(e.requiresWatermark,!1);if(!ab())return await yb(n,r,t);let i=ib(n,r),a=eb.get(i);if(a)return a;let o=tb.get(i);if(o)return await o;let s=yb(n,r,t).then(e=>(eb.set(i,e),tb.delete(i),e)).catch(e=>{throw tb.delete(i),e});return tb.set(i,s),await s}async function yb(e,t,n){let r=typeof Worker<`u`,i=a()!==null,o=typeof AudioWorkletNode<`u`,s=typeof MediaStreamTrackProcessor<`u`,c=await bb(r,n),l=ob({probeResult:c,hasMainThreadMediaStreamTrackProcessor:s}),u=sb({requiresAudio:e,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c}),d=hb({hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMainThreadMediaStreamTrackProcessor:s,probeResult:c,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}),f=gb(l,u),p=_b(c,t);return{isSupported:r&&f&&p,missing:d,hasWorker:r,hasAudioContext:i,hasAudioWorklet:o,hasMediaStreamTrackProcessor:c.hasMediaStreamTrackProcessor,hasMainThreadMediaStreamTrackProcessor:s,hasVideoFrame:c.hasVideoFrame,hasAudioData:c.hasAudioData,hasOffscreenCanvas:c.hasOffscreenCanvas,hasCreateImageBitmap:c.hasCreateImageBitmap,hasReadableStream:c.hasReadableStream,requiresAudio:e,requiresWatermark:t,videoPath:l,audioPath:u}}async function bb(e,t){if(!e)return Sb();let n=await xb().catch(()=>null);return n?await new Promise(e=>{let r=!1,i=t.probeTimeoutMilliseconds??2e3,a=t=>{r||(r=!0,n.terminate(),e(t))},o=setTimeout(()=>{a(Sb())},i);n.onmessage=e=>{let t=e.data;t.type===Xy&&(clearTimeout(o),a({hasMediaStreamTrackProcessor:t.hasMediaStreamTrackProcessor===!0,hasVideoFrame:t.hasVideoFrame===!0,hasAudioData:t.hasAudioData===!0,hasOffscreenCanvas:t.hasOffscreenCanvas===!0,hasCreateImageBitmap:t.hasCreateImageBitmap===!0,hasReadableStream:t.hasReadableStream===!0}))},n.onerror=()=>{clearTimeout(o),a(Sb())},Promise.resolve().then(()=>{n.postMessage({type:Yy})}).catch(()=>{clearTimeout(o),a(Sb())})}):Sb()}function xb(){return Promise.resolve().then(()=>{let e=qy();try{let t=new Worker(e,{type:`classic`});return Jy(e),t}catch(t){throw Jy(e),t}})}function Sb(){return{hasMediaStreamTrackProcessor:!1,hasVideoFrame:!1,hasAudioData:!1,hasOffscreenCanvas:!1,hasCreateImageBitmap:!1,hasReadableStream:!1}}let Cb=`recording.audio-no-chunks`,wb=`recording.audio-silent`,Tb=`recording.audio-track-ended`,Eb=`audio.no-track-at-start`;function Db(e,t){let n=Error(e);return n.code=e,t&&(n.details=t),n}function Ob(){let e=Error(Eb);return e.code=Eb,e}function kb(e){if(!(e instanceof Error))return!1;let t=e;return t.code===Cb||t.code===wb||t.code===Tb||t.code===`recording.no-audio-track`||t.code===`recording.no-audio-frames`||t.code===`recording.audio-zero-channels`||t.code===`recording.audio-invalid-sample-rate`}function Ab(e){return e.hadTrackEndedWarning?{ok:!1,code:Tb}:e.totalChunks===0?{ok:!1,code:Cb}:e.nonSilentChunks===0&&(e.durationMs>0?e.mutedDurationMs/e.durationMs:0)<.9?{ok:!1,code:wb}:{ok:!0}}let jb=`vidtreo-recorder`,Mb=`pending-uploads`,Nb=`status`,Pb=`createdAt`,Fb=`Failed to prepare upload data for storage. The recorded file could not be read.`,Ib=`__probe__`,Lb=new ArrayBuffer(1);var Rb=class{constructor(e){if(this.db=null,e){this.databaseFactory=e;return}this.databaseFactory=indexedDB}init(){return this.db?Promise.resolve():this.openDatabase(3,!0)}openDatabase(e,t){return new Promise((n,r)=>{let i=this.createOpenRequest(e);i.onerror=()=>{let e=i.error;if(t&&e&&e.name===`VersionError`){this.openDatabase(void 0,!1).then(n).catch(r);return}if(e){r(e);return}r(Error(`Failed to open database`))},i.onsuccess=()=>{if(!i.result){r(Error(`Database result is null`));return}let e=i.result,t=this.validateRequiredSchema(e);if(t){e.close(),r(t);return}this.db=e,n()},i.onupgradeneeded=e=>{let t=e.target.result;if(!t){r(Error(`Database upgrade result is null`));return}this.initializeStoreSchema(t)}})}createOpenRequest(e){return e===void 0?this.databaseFactory.open(jb):this.databaseFactory.open(jb,e)}initializeStoreSchema(e){if(e.objectStoreNames.contains(Mb))return;let t=e.createObjectStore(Mb,{keyPath:`id`});t.createIndex(Nb,Nb,{unique:!1}),t.createIndex(Pb,Pb,{unique:!1})}validateRequiredSchema(e){if(!e.objectStoreNames.contains(Mb))return Error(`Database schema is missing required object store: pending-uploads`);let t=e.transaction([Mb],`readonly`).objectStore(Mb);return t.indexNames.contains(Nb)?t.indexNames.contains(Pb)?null:Error(`Database schema is missing required index: createdAt`):Error(`Database schema is missing required index: status`)}isInitialized(){return this.db!==null}async probeWriteCapability(){if(!this.db)return{ok:!1,reason:`Database not initialized`};try{return await this.executeTransaction(`readwrite`,e=>{let t={id:Ib,blobData:Lb,blobType:`application/octet-stream`,apiKey:``,backendUrl:``,filename:`probe`,status:`pending`,retryCount:0,createdAt:0,updatedAt:0};return new Promise((n,r)=>{let i=e.put(t);i.onsuccess=()=>{let t=e.delete(Ib);t.onsuccess=()=>n(),t.onerror=()=>{if(t.error){r(t.error);return}r(Error(`Probe delete failed`))}},i.onerror=()=>{if(i.error){r(i.error);return}r(Error(`Probe write failed`))}})}),{ok:!0}}catch(e){return{ok:!1,reason:`Storage write probe failed. Browser may be in private browsing mode or IndexedDB writes are restricted. ${e instanceof Error?e.message:String(e)}`}}}async savePendingUpload(e){let t=this.generateUploadId(),n=Date.now(),r={...e,id:t,status:`pending`,retryCount:0,createdAt:n,updatedAt:n,blobData:await this.readBlobData(e.blob),blobType:e.blob.type};return r.blob=void 0,this.executeTransaction(`readwrite`,e=>{let n=e.add(r);return new Promise((e,r)=>{n.onsuccess=()=>e(t),n.onerror=()=>{n.error?n.error.name===`QuotaExceededError`?r(Error(`Storage quota exceeded. Please free up space or delete old uploads.`)):r(n.error):r(Error(`Failed to save upload`))}})})}getPendingUploads(e){return this.executeTransaction(`readonly`,t=>{let n=e?t.index(Nb).getAll(e):t.getAll();return new Promise((e,t)=>{n.onsuccess=()=>{if(n.result===void 0){t(Error(`Failed to get uploads: result is undefined`));return}e(n.result.map(e=>this.hydrateUpload(e)))},n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to get uploads`))}})})}async updateUploadStatus(e,t){let n=await this.createStoredUpdates(t);return this.executeTransaction(`readwrite`,r=>{let i=r.get(e);return new Promise((e,a)=>{i.onsuccess=()=>{let o=i.result;if(!o){a(Error(`Upload not found`));return}let s=t.updatedAt===void 0?Date.now():t.updatedAt,c={...o,...n,updatedAt:s},l=r.put(c);l.onsuccess=()=>e(),l.onerror=()=>{if(l.error){a(l.error);return}a(Error(`Failed to update upload`))}},i.onerror=()=>{i.error?a(i.error):a(Error(`Failed to get upload`))}})})}deleteUpload(e){return this.executeTransaction(`readwrite`,t=>{let n=t.delete(e);return new Promise((e,t)=>{n.onsuccess=()=>e(),n.onerror=()=>{n.error?t(n.error):t(Error(`Failed to delete upload`))}})})}async cleanupPermanentlyFailedUploads(e){let t=e===void 0?24:e;if(typeof t!=`number`||t<0)throw Error(`retentionHours must be a non-negative number`);let n=Date.now()-t*36e5,r=(await this.getPendingUploads()).filter(e=>e.status===`failed`&&e.retryCount>=10&&e.updatedAt<n);for(let e of r)await this.deleteUpload(e.id);return r.length}async getTotalStorageSize(){return(await this.getPendingUploads()).reduce((e,t)=>e+t.blob.size,0)}hydrateUpload(e){if(`blobData`in e&&e.blobData){let{blobData:t,blobType:n,...r}=e;return{...r,blob:new Blob([t],{type:n})}}return e}async createStoredUpdates(e){let t={...e};return e.blob&&(t.blobData=await this.readBlobData(e.blob),t.blobType=e.blob.type,t.blob=void 0),t}readBlobData(e){return e.arrayBuffer().catch(e=>{throw e instanceof Error?Error(`${Fb} ${e.message}`):Error(Fb)})}generateUploadId(){return`upload-${Date.now()}-${Math.random().toString(36).substring(2,11)}`}executeTransaction(e,t){if(!this.db)throw Error(`Database not initialized`);let n=this.db.transaction([Mb],e),r=n.objectStore(Mb);return new Promise((e,i)=>{let a,o=!1,s=!1;n.oncomplete=()=>{!o||s||e(a)},n.onerror=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction failed`))},n.onabort=()=>{if(n.error){i(n.error);return}i(Error(`Storage transaction aborted`))},t(r).then(e=>{a=e,o=!0},e=>{s=!0,i(e)})})}},zb=class{constructor(){this.storageService=null,this.cleanupIntervalId=null,this.writeProbeResult=null}async initialize(e){this.storageService||=new Rb,this.storageService.isInitialized()||await this.storageService.init(),this.writeProbeResult=await this.storageService.probeWriteCapability(),this.setupCleanupInterval(e)}getWriteProbeResult(){return this.writeProbeResult}setupCleanupInterval(e){this.cleanupIntervalId===null&&(this.cleanupIntervalId=window.setInterval(()=>{this.performCleanup().catch(t=>{e(i(t))})},36e5))}async performCleanup(){if(!this.storageService)throw Error(`StorageService not initialized`);await this.storageService.cleanupPermanentlyFailedUploads(24)}getStorageService(){return this.storageService}isStorageWritable(){return this.writeProbeResult?.ok===!0}destroy(){this.cleanupIntervalId!==null&&(clearInterval(this.cleanupIntervalId),this.cleanupIntervalId=null)}};function Bb(){let e=globalThis;if(e.__VIDTREO_DEBUG__===!0||e.__VIDTREO_DEV__===!0)return!0;let t=typeof process<`u`&&process?.env?`production`:void 0;return t===`development`||t===`test`||typeof localStorage<`u`&&localStorage.getItem(`VIDTREO_DEBUG`)===`true`}let Vb=Bb(),Hb={reset:`\x1B[0m`,bright:`\x1B[1m`,dim:`\x1B[2m`,red:`\x1B[31m`,green:`\x1B[32m`,yellow:`\x1B[33m`,blue:`\x1B[34m`,magenta:`\x1B[35m`,cyan:`\x1B[36m`,white:`\x1B[37m`,gray:`\x1B[90m`};function Ub(e,t,n){if(!Vb)return``;let r=n?.prefix||`[${e.toUpperCase()}]`;return`${Hb[n?.color||Wb(e)]}${r}${Hb.reset} ${t}`}function Wb(e){switch(e){case`error`:return`red`;case`warn`:return`yellow`;case`info`:return`cyan`;case`debug`:return`gray`;default:return`white`}}function Gb(e,t,...n){if(!Vb)return;let r=Ub(e,t);console[e](r,...n)}let $={log:(e,...t)=>{Gb(`log`,e,...t)},info:(e,...t)=>{Gb(`info`,e,...t)},warn:(e,...t)=>{Gb(`warn`,e,...t)},error:(e,...t)=>{Gb(`error`,e,...t)},debug:(e,...t)=>{Gb(`debug`,e,...t)},group:(e,t=`cyan`)=>{if(!Vb)return;let n=Hb[t],r=Hb.reset;console.group(`${n}${e}${r}`)},groupEnd:()=>{Vb&&console.groupEnd()}};function Kb(e,t){if(e==null)throw Error(t);return e}function qb(e,t=`StreamProcessor`){if(!e)throw Error(`${t} is required`);return e}function Jb(){if(typeof navigator>`u`||!navigator.mediaDevices?.getUserMedia){let e=typeof window<`u`&&window.isSecureContext===!0?`Camera access is not supported in this browser`:`Camera access requires HTTPS. Please use a secure connection (https://) or localhost.`;throw Error(e)}return navigator.mediaDevices}function Yb(e,t){let n={};if(t.originalCameraConstraints){let{deviceId:e,...r}=t.originalCameraConstraints;n={...n,...r}}e&&(n={...n,deviceId:{exact:e}});let r=t.getSelectedCameraDeviceId(),i=!1;return e&&(i=!0),n.deviceId&&(i=!0),!i&&r&&(n={...n,deviceId:{exact:r}}),n}function Xb(e){let t={echoCancellation:!0,noiseSuppression:!0,autoGainControl:!0};return e?{...t,deviceId:{exact:e}}:t}let Zb=`live`;function Qb(e){for(let t of e)t.readyState===Zb&&t.stop()}function $b(e){Qb(e.getTracks())}function ex(e){Qb(e.getVideoTracks())}function tx(e){return e?e.readyState===Zb:!1}function nx(e,t){return tx(e)&&tx(t)}function rx(e,t,n){if(!tx(e)){$b(n);let r=`undefined`;throw e&&(r=e.readyState),Error(`Failed to get live camera ${t} track. ReadyState: ${r}`)}}let ix=`[SourceSwitchManager]`;var ax=class{constructor(e){this.dependencies=e}async createCameraStreamWithOriginalAudio(e){let t=this.dependencies.getOriginalCameraStream(),n;if(t&&(n=t.getAudioTracks()[0]),this.dependencies.logger.debug(`${ix} createCameraStreamWithOriginalAudio`,{hasOriginalCameraStream:!!t,originalCameraStreamId:t?.id,hasOriginalAudioTrack:!!n,originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState,originalAudioTrackEnabled:n?.enabled,originalAudioTrackMuted:n?.muted,originalAudioTrackLabel:n?.label,isTrackLive:tx(n),cameraDeviceId:e}),!tx(n))return this.dependencies.logger.warn(`${ix} Original audio track is not live, cannot reuse`,{originalAudioTrackId:n?.id,originalAudioTrackReadyState:n?.readyState}),null;let r=Yb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),i=Object.keys(r).length>0,a=!0;i&&(a=r);let o={video:a,audio:!1};this.dependencies.logger.debug(`${ix} Requesting new video stream`,{constraints:o,cameraDeviceId:e});let s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0];rx(c,`video`,s),this.dependencies.logger.debug(`${ix} New video stream obtained`,{newStreamId:s.id,videoTrackId:c.id,videoTrackReadyState:c.readyState,newStreamAudioTracksCount:s.getAudioTracks().length});let l=[c];n&&(l=[...l,n]),this.dependencies.logger.debug(`${ix} Creating combined stream with original audio`,{videoTrackId:c.id,audioTrackId:n?.id,audioTrackReadyState:n?.readyState,audioTrackEnabled:n?.enabled,audioTrackMuted:n?.muted,combinedTracksCount:l.length});let u=new MediaStream(l);Qb(s.getAudioTracks());let d=t?.id;return this.dependencies.setOriginalCameraStream(u),this.dependencies.logger.debug(`${ix} Combined stream created and assigned`,{combinedStreamId:u.id,previousOriginalCameraStreamId:d,newOriginalCameraStreamId:u.id,combinedStreamVideoTracksCount:u.getVideoTracks().length,combinedStreamAudioTracksCount:u.getAudioTracks().length,combinedStreamAudioTrackId:u.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:u.getAudioTracks()[0]?.readyState,audioTrackStillSame:u.getAudioTracks()[0]===n}),u}async createCameraStreamWithNewAudio(e){let t=this.dependencies.getSelectedMicDeviceId(),n=Yb(e,{originalCameraConstraints:this.dependencies.getOriginalCameraConstraints(),getSelectedCameraDeviceId:this.dependencies.getSelectedCameraDeviceId}),r=Xb(t),i=Object.keys(n).length>0,a=!0;i&&(a=n);let o={video:a,audio:r},s=await Jb().getUserMedia(o),c=s.getVideoTracks()[0],l=s.getAudioTracks()[0];return rx(c,`video`,s),rx(l,`audio`,s),this.dependencies.setOriginalCameraStream(s),s}async createNewCameraStreamForRecording(){let e=this.dependencies.getSelectedCameraDeviceId();return await this.createCameraStreamWithOriginalAudio(e)||this.createCameraStreamWithNewAudio(e)}async getCameraStream(e){let t=this.dependencies.streamManager.isRecording(),n=this.dependencies.getSelectedCameraDeviceId(),r=this.dependencies.getSelectedMicDeviceId();if(this.dependencies.streamManager.setVideoDevice(n),this.dependencies.streamManager.setAudioDevice(r),e.canReuseOriginalStream()){let e=this.dependencies.getOriginalCameraStream();if(!e)throw Error(`Original camera stream is null`);return e}if(e.canReuseManagerStream()){let e=this.dependencies.streamManager.getStream();if(!e)throw Error(`Manager stream is null`);return e}t||this.dependencies.getOriginalCameraStream()&&this.dependencies.setOriginalCameraStream(null);let i=this.dependencies.streamManager.getStream();if(!t&&i&&i!==this.dependencies.getOriginalCameraStream()&&($b(i),this.dependencies.streamManager.setMediaStream(null)),t)return this.dependencies.streamManager.setVideoDevice(this.dependencies.getSelectedCameraDeviceId()),this.dependencies.streamManager.setAudioDevice(this.dependencies.getSelectedMicDeviceId()),this.createNewCameraStreamForRecording();let a=await this.dependencies.streamManager.startStream();return this.dependencies.setOriginalCameraStream(a),a}};let ox=`screen`,sx=`No video track found in screen share stream`;async function cx(e,t,n){n.setScreenShareStream(e);let r=e.getVideoTracks()[0];if(!r)throw n.stopStreamTracks(e),Error(sx);let i=n.combineScreenShareWithOriginalAudio(r),a=n.getOriginalCameraStream();t&&t!==a&&n.stopStreamVideoTracks(t);let o=e.getAudioTracks();for(let e of o)e.stop();return n.setCurrentSourceType(ox),n.callbacks.onSourceChange&&await n.callbacks.onSourceChange(n.getCurrentSourceType()),lx(i,n),i}function lx(e,t){let n=e.getVideoTracks()[0];if(!n)throw Error(sx);let r=t.getScreenShareTrackEndHandler();if(r){let e=t.streamManager.getStream();if(e){let t=e.getVideoTracks()[0];t&&t.removeEventListener(`ended`,r)}}let i=()=>{t.getCurrentSourceType()===ox&&t.switchToCamera().catch(e=>{t.handleSwitchError(e)})};t.setScreenShareTrackEndHandler(i),n.addEventListener(`ended`,i)}function ux(e,t){let n=t.getScreenShareTrackEndHandler();if(!(n&&e))return;let r=e.getVideoTracks()[0];r&&r.removeEventListener(`ended`,n),t.setScreenShareTrackEndHandler(null)}function dx(e,t){e.onTransitionStart&&e.onTransitionStart(t)}function fx(e){e.onTransitionEnd&&e.onTransitionEnd()}function px(e){e.onScreenSelectionStart&&e.onScreenSelectionStart()}function mx(e){e.onScreenSelectionEnd&&e.onScreenSelectionEnd()}function hx(e){mx(e),fx(e)}let gx=`Failed to get camera stream`;var _x=class{constructor(e,t={}){this.currentSourceType=`camera`,this.originalCameraStream=null,this.screenShareStream=null,this.screenShareTrackEndHandler=null,this.streamManager=e,this.callbacks=t;let n=null,r=()=>n;this.getOriginalCameraConstraints=r,this.setOriginalCameraConstraints=e=>{n=e},this.cameraStreamBuilder=new ax({streamManager:this.streamManager,logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},getSelectedCameraDeviceId:()=>this.callbacks.getSelectedCameraDeviceId?this.callbacks.getSelectedCameraDeviceId():this.streamManager.getVideoDevice(),getSelectedMicDeviceId:()=>this.callbacks.getSelectedMicDeviceId?this.callbacks.getSelectedMicDeviceId():this.streamManager.getAudioDevice(),getOriginalCameraStream:()=>this.originalCameraStream,setOriginalCameraStream:e=>{this.originalCameraStream=e},getOriginalCameraConstraints:r})}getCurrentSourceType(){return this.currentSourceType}getOriginalCameraStream(){return this.originalCameraStream}storeOriginalCameraConstraints(e){let t=e.getVideoTracks()[0];if(!t)return;let n=t.getSettings(),r={width:n.width,height:n.height,aspectRatio:n.aspectRatio,frameRate:n.frameRate,deviceId:n.deviceId,facingMode:n.facingMode},i=this.getOriginalCameraConstraints();i&&i.width===r.width&&i.height===r.height&&i.aspectRatio===r.aspectRatio&&i.frameRate===r.frameRate&&i.deviceId===r.deviceId&&i.facingMode===r.facingMode||this.setOriginalCameraConstraints(r)}storeOriginalCameraStream(e){let t=e.getVideoTracks()[0],n=e.getAudioTracks()[0];nx(t,n)?this.originalCameraStream=new MediaStream([t,n]):this.originalCameraStream=e}createError(e){return e instanceof Error?e:Error(i(e))}waitForTracksToEnd(e){return new Promise(t=>{setTimeout(()=>{this.screenShareStream=null,t()},e)})}combineScreenShareWithOriginalAudio(e){let t;this.originalCameraStream&&(t=this.originalCameraStream.getAudioTracks()[0]),$.debug(`[SourceSwitchManager] combineScreenShareWithOriginalAudio`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,hasOriginalAudioTrack:!!t,originalAudioTrackId:t?.id,originalAudioTrackReadyState:t?.readyState,originalAudioTrackEnabled:t?.enabled,originalAudioTrackMuted:t?.muted,originalAudioTrackLabel:t?.label,isTrackLive:tx(t),screenVideoTrackId:e.id,screenVideoTrackReadyState:e.readyState});let n=[e];tx(t)&&t?(n=[...n,t],$.debug(`[SourceSwitchManager] Added original audio track to combined stream`,{audioTrackId:t.id,combinedTracksCount:n.length})):$.warn(`[SourceSwitchManager] Original audio track is not live, not adding to combined stream`,{audioTrackId:t?.id,audioTrackReadyState:t?.readyState,combinedTracksCount:n.length});let r=new MediaStream(n);return $.debug(`[SourceSwitchManager] Combined stream created`,{combinedStreamId:r.id,combinedStreamVideoTracksCount:r.getVideoTracks().length,combinedStreamAudioTracksCount:r.getAudioTracks().length,combinedStreamAudioTrackId:r.getAudioTracks()[0]?.id,combinedStreamAudioTrackReadyState:r.getAudioTracks()[0]?.readyState}),r}isPermissionDeniedError(e){let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0);let r=t.toLowerCase();return r.includes(`permission denied`)&&(n=!0),r.includes(`user denied`)&&(n=!0),n}switchToScreenCapture(){let e=this.streamManager.getStream();return e&&(this.storeOriginalCameraConstraints(e),this.storeOriginalCameraStream(e)),dx(this.callbacks,`Select screen to share...`),px(this.callbacks),Promise.resolve().then(async()=>{let t=Jb();if(typeof t.getDisplayMedia!=`function`)throw Error(`Screen sharing is not supported on this device`);return cx(await t.getDisplayMedia({video:!0,audio:!0}),e,this.getScreenShareDependencies())}).catch(e=>{if(hx(this.callbacks),this.isPermissionDeniedError(e))return null;throw e})}canReuseStream(e,t){if(!e||t&&e!==this.originalCameraStream)return!1;let n=e.getVideoTracks()[0],r=e.getAudioTracks()[0];return!(!nx(n,r)||this.callbacks.getSelectedCameraDeviceId&&this.callbacks.getSelectedCameraDeviceId()!==n.getSettings().deviceId)}canReuseOriginalStream(){return this.canReuseStream(this.originalCameraStream,!1)}canReuseManagerStream(){let e=this.streamManager.getStream();return e&&this.originalCameraStream?this.canReuseStream(e,!0):!1}getScreenShareDependencies(){return{callbacks:this.callbacks,streamManager:this.streamManager,combineScreenShareWithOriginalAudio:e=>this.combineScreenShareWithOriginalAudio(e),stopStreamTracks:e=>$b(e),stopStreamVideoTracks:e=>ex(e),getCurrentSourceType:()=>this.currentSourceType,setCurrentSourceType:e=>{this.currentSourceType=e},getOriginalCameraStream:()=>this.originalCameraStream,getScreenShareStream:()=>this.screenShareStream,setScreenShareStream:e=>{this.screenShareStream=e},getScreenShareTrackEndHandler:()=>this.screenShareTrackEndHandler,setScreenShareTrackEndHandler:e=>{this.screenShareTrackEndHandler=e},switchToCamera:()=>this.switchToCamera(),handleSwitchError:e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}}}getCameraStream(){return this.cameraStreamBuilder.getCameraStream({canReuseOriginalStream:()=>this.canReuseOriginalStream(),canReuseManagerStream:()=>this.canReuseManagerStream()})}switchToCamera(){let e=this.streamManager.isRecording();return!e&&this.currentSourceType===`camera`?Promise.resolve():Promise.resolve().then(async()=>{dx(this.callbacks,`Switching to camera...`),await this.handleScreenShareStop();let t=await this.getCameraStream();if(!t)throw Error(gx);await this.applyCameraStream(t,e),fx(this.callbacks)}).catch(e=>{throw fx(this.callbacks),e})}stopScreenShareStreamTracks(e){let t=e.getVideoTracks(),n=e.getAudioTracks();$.debug(`[SourceSwitchManager] stopping screen share tracks`,{videoTracks:t.map(e=>({id:e.id,readyState:e.readyState,displaySurface:e.getSettings().displaySurface,constraints:e.getConstraints()})),audioTracks:n.map(e=>({id:e.id,readyState:e.readyState,constraints:e.getConstraints()}))});for(let e of t)e.stop();for(let e of n)e.stop()}stopDisplayTracks(e){if(e)for(let t of e.getVideoTracks())typeof t.getSettings().displaySurface==`string`&&tx(t)&&($.debug(`[SourceSwitchManager] stopping display track`,{id:t.id,readyState:t.readyState,constraints:t.getConstraints(),settings:t.getSettings()}),t.stop())}async handleScreenShareStop(){if(this.currentSourceType!==`screen`)return;$.debug(`[SourceSwitchManager] handleScreenShareStop invoked`,{currentSourceType:this.currentSourceType,hasScreenShareStream:!!this.screenShareStream,screenShareStreamId:this.screenShareStream?.id,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id});let e=this.screenShareStream,t=this.streamManager.getStream();if($.debug(`[SourceSwitchManager] Current stream state before stop`,{currentStreamId:t?.id,currentStreamVideoTracksCount:t?.getVideoTracks().length,currentStreamAudioTracksCount:t?.getAudioTracks().length,currentStreamAudioTrackId:t?.getAudioTracks()[0]?.id,currentStreamAudioTrackReadyState:t?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState}),e){let t=e.getAudioTracks();$.debug(`[SourceSwitchManager] Screen share stream audio tracks before stop`,{screenShareStreamId:e.id,screenShareAudioTracksCount:t.length,screenShareAudioTrackIds:t.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),ux(e,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(e),this.stopDisplayTracks(e),this.screenShareStream=null,await this.waitForTracksToEnd(0),$.debug(`[SourceSwitchManager] Screen share stream stopped`,{screenShareAudioTracksAfterStop:t.map(e=>({id:e.id,readyState:e.readyState}))})}if(t){let e=t.getAudioTracks();$.debug(`[SourceSwitchManager] Current stream audio tracks before video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:e.length,currentStreamAudioTrackIds:e.map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))}),ex(t),this.stopDisplayTracks(t),$.debug(`[SourceSwitchManager] Current stream audio tracks after video stop`,{currentStreamId:t.id,currentStreamAudioTracksCount:t.getAudioTracks().length,currentStreamAudioTrackIds:t.getAudioTracks().map(e=>({id:e.id,readyState:e.readyState,enabled:e.enabled}))})}$.debug(`[SourceSwitchManager] Original camera stream state before source change`,{hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState,originalCameraStreamAudioTrackEnabled:this.originalCameraStream?.getAudioTracks()[0]?.enabled}),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),$.debug(`[SourceSwitchManager] handleScreenShareStop completed`,{hasScreenShareStream:!!this.screenShareStream,currentSourceType:this.currentSourceType,hasOriginalCameraStream:!!this.originalCameraStream,originalCameraStreamId:this.originalCameraStream?.id,originalCameraStreamAudioTracksCount:this.originalCameraStream?.getAudioTracks().length,originalCameraStreamAudioTrackId:this.originalCameraStream?.getAudioTracks()[0]?.id,originalCameraStreamAudioTrackReadyState:this.originalCameraStream?.getAudioTracks()[0]?.readyState})}async applyCameraStream(e,t){this.streamManager.setMediaStream(e);let n=this.currentSourceType!==`camera`;this.currentSourceType=`camera`,n&&this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),t&&await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e)}async toggleSource(){if(!this.streamManager.isRecording())return;let e;e=this.currentSourceType===`camera`?this.switchToScreen():this.switchToCamera(),await e.catch(e=>{this.handleToggleError(e)})}async switchToScreen(){let e=await this.switchToScreenCapture();if(!e){fx(this.callbacks);return}dx(this.callbacks,`Switching to screen...`),await this.streamManager.switchVideoSource(e),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(e),fx(this.callbacks)}handleToggleError(e){fx(this.callbacks);let t=i(e),n=!1;t.includes(`NotAllowedError`)&&(n=!0),t.includes(`AbortError`)&&(n=!0),n&&this.currentSourceType===`screen`&&this.switchToCamera().catch(e=>{this.callbacks.onError&&this.callbacks.onError(this.createError(e))}),!n&&this.callbacks.onError&&this.callbacks.onError(this.createError(e))}async handleRecordingStop(){if(this.currentSourceType!==`screen`){this.cleanup();return}await Promise.resolve().then(async()=>{let e=this.streamManager.getStream();e&&(ux(e,this.getScreenShareDependencies()),ex(e));let t=await this.getCameraStream();if(!t)throw Error(gx);this.streamManager.setMediaStream(t),this.currentSourceType=`camera`,this.callbacks.onSourceChange&&await this.callbacks.onSourceChange(this.currentSourceType),this.callbacks.onPreviewUpdate&&await this.callbacks.onPreviewUpdate(t)}).catch(e=>{throw this.callbacks.onError&&this.callbacks.onError(this.createError(e)),e}),this.cleanup()}cleanup(){this.screenShareStream&&=(ux(this.screenShareStream,this.getScreenShareDependencies()),this.stopScreenShareStreamTracks(this.screenShareStream),null);let e=this.streamManager.getStream();e&&ux(e,this.getScreenShareDependencies()),this.screenShareTrackEndHandler=null,this.originalCameraStream=null,this.setOriginalCameraConstraints(null)}setCallbacks(e){this.callbacks={...this.callbacks,...e}}};let vx=Object.freeze({width:{ideal:Xt.width||1920},height:{ideal:Xt.height||1080},frameRate:{ideal:Xt.fps||30}}),yx=Object.freeze({video:vx,audio:!0});Object.freeze({mimeType:`video/webm;codecs=vp9,opus`});let bx={NotReadableError:`camera.in-use`,NotFoundError:`camera.not-found`,NotAllowedError:`camera.permission-denied`,OverconstrainedError:`camera.overconstrained`,TimeoutError:`camera.timeout`},xx={NotReadableError:`audio.in-use`,NotFoundError:`audio.not-found`,NotAllowedError:`audio.permission-denied`,OverconstrainedError:`audio.overconstrained`,TimeoutError:`audio.timeout`};function Sx(e){return e instanceof DOMException||typeof e==`object`&&e&&`name`in e&&typeof e.name==`string`?e.name:null}function Cx(e){return i(e).toLowerCase()}function wx(e,t){let n=Cx(e),r=t===`camera`?`camera`:`audio`;return n.includes(`permission denied`)||n.includes(`permission dismissed`)||n.includes(`not allowed`)?`${r}.permission-denied`:n.includes(`requested device not found`)||n.includes(`device not found`)||n.includes(`no camera`)||n.includes(`no microphone`)?`${r}.not-found`:n.includes(`timeout starting`)||n.includes(`timed out`)||n.includes(`timeout`)?`${r}.timeout`:n.includes(`could not start video source`)||n.includes(`could not start audio source`)||n.includes(`device in use`)?`${r}.in-use`:null}function Tx(e){let t=wx(e,`camera`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=bx[n];if(e!==void 0)return e}return`camera.unknown`}function Ex(e){let t=wx(e,`audio`);if(t!==null)return t;let n=Sx(e);if(n!==null){let e=xx[n];if(e!==void 0)return e}return`audio.unknown`}function Dx(e){let t=i(e),n=Error(t);return n.name=`CameraError`,n.code=Tx(e),n}function Ox(e){let t=i(e),n=Error(t);return n.name=`AudioError`,n.code=Ex(e),n}function kx(e){return Sx(e)===`NotReadableError`}function Ax(e){return new Promise(t=>setTimeout(t,e))}var jx=class{constructor(e={},t={}){this.mediaStream=null,this.state=`idle`,this.eventListeners=new Map,this.selectedAudioDeviceId=null,this.selectedVideoDeviceId=null,this.audioStatus=`pending`,this.audioAcquisitionPromise=null,this.pendingAudioError=null,this.acquisitionGeneration=0,this.streamConfig={...yx,...e},this.waitMilliseconds=t.waitMilliseconds??Ax,this.audioRetryDelayMilliseconds=t.audioRetryDelayMilliseconds??300}getAudioStatus(){return this.audioStatus}isAudioReady(){return this.audioStatus===`acquired`}async waitForAudio(){if(this.audioStatus!==`acquired`&&(this.audioStatus===`failed`||(this.audioAcquisitionPromise&&await this.audioAcquisitionPromise,this.getAudioStatus()===`failed`)))throw this.pendingAudioError??Ox(null)}setAudioStatus(e){this.audioStatus!==e&&(this.audioStatus=e,this.emit(`audiostatuschange`,{status:e}))}emitAudioTelemetry(e){this.emit(`audiotelemetry`,{event:e})}getState(){return this.state}getStream(){return this.mediaStream}getAudioStreamForAnalysis(){return this.mediaStream&&this.mediaStream.getAudioTracks().length>0?this.mediaStream:null}isActive(){return this.state===`active`||this.state===`recording`}on(e,t){this.eventListeners.has(e)||this.eventListeners.set(e,new Set);let n=this.eventListeners.get(e);return n&&n.add(t),()=>{this.off(e,t)}}off(e,t){let n=this.eventListeners.get(e);n&&n.delete(t)}once(e,t){let n=(r=>{t(r),this.off(e,n)});return this.on(e,n)}emit(e,t){let n=this.eventListeners.get(e);if(n)for(let e of n)try{e(t)}catch{}}setState(e){if(this.state===e)return;let t=this.state;this.state=e,this.emit(`statechange`,{state:e,previousState:t})}setAudioDevice(e){this.selectedAudioDeviceId=e}setVideoDevice(e){this.selectedVideoDeviceId=e}getAudioDevice(){return this.selectedAudioDeviceId}getVideoDevice(){return this.selectedVideoDeviceId}async getAvailableDevices(){try{let e=await navigator.mediaDevices.enumerateDevices();return{audioinput:e.filter(e=>e.kind===`audioinput`),videoinput:e.filter(e=>e.kind===`videoinput`)}}catch(e){throw Error(`Failed to enumerate devices: ${i(e)}`)}}buildDeviceConstraints(e,t){return e?typeof t==`object`?{...t,deviceId:{exact:e}}:{deviceId:{exact:e}}:t}buildVideoConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.video)}buildAudioConstraints(e){return this.buildDeviceConstraints(e,this.streamConfig.audio)}async startStream(){if($.debug(`[StreamManager] startStream called`,{hasExistingStream:!!this.mediaStream,selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId}),this.mediaStream){let e=this.mediaStream.getVideoTracks()[0];if(this.selectedVideoDeviceId===null)if(e?.getSettings?.()?.deviceId)$.debug(`[StreamManager] Stopping existing stream to recreate`),this.stopStream();else return $.debug(`[StreamManager] Reusing existing stream`),this.mediaStream;if(e?.getSettings&&e.getSettings().deviceId===this.selectedVideoDeviceId)return $.debug(`[StreamManager] Existing stream matches device, reusing`),this.mediaStream;$.debug(`[StreamManager] Device changed, stopping existing stream`),this.stopStream()}this.setState(`starting`),$.debug(`[StreamManager] State set to 'starting'`);try{return this.mediaStream=await this.acquireVideoAndAudioStream(),$.info(`[StreamManager] Media stream obtained`,{streamId:this.mediaStream.id,videoTracks:this.mediaStream.getVideoTracks().length,audioTracks:this.mediaStream.getAudioTracks().length}),this.setState(`active`),$.debug(`[StreamManager] State set to 'active'`),$.debug(`[StreamManager] Emitting streamstart event`),this.emit(`streamstart`,{stream:this.mediaStream}),this.mediaStream}catch(e){if(e instanceof Error&&`code`in e&&(e.name===`CameraError`||e.name===`AudioError`))throw $.error(`[StreamManager] Failed to start stream`,e),this.setState(`error`),this.emit(`error`,{error:e}),e;let t=Dx(e);throw $.error(`[StreamManager] Failed to start stream`,t),this.setState(`error`),this.emit(`error`,{error:t}),t}}async acquireVideoAndAudioStream(){let e=Jb(),t=this.buildVideoConstraints(this.selectedVideoDeviceId),n=this.buildAudioConstraints(this.selectedAudioDeviceId);this.setAudioStatus(`pending`),this.pendingAudioError=null,$.debug(`[StreamManager] Attempting combined getUserMedia`,{selectedVideoDeviceId:this.selectedVideoDeviceId,selectedAudioDeviceId:this.selectedAudioDeviceId});try{let r=await e.getUserMedia({video:t,audio:n}),i=r.getVideoTracks().length>0,a=r.getAudioTracks().length>0;if(i&&a)return $.debug(`[StreamManager] Combined getUserMedia succeeded with video + audio`),this.setAudioStatus(`acquired`),r;$.warn(`[StreamManager] Combined getUserMedia returned incomplete stream`,{videoTracks:r.getVideoTracks().length,audioTracks:r.getAudioTracks().length}),this.stopStreamTracks(r)}catch(e){let t=Sx(e),n=i(e);$.warn(`[StreamManager] Combined getUserMedia failed, falling back to separate acquisition`,{error:n,errorName:t}),this.emitAudioTelemetry({name:`audio.acquisition.fallback`,properties:{reason:`combined_getUserMedia_failed`,originalError:n,originalErrorName:t,selectedAudioDeviceId:this.selectedAudioDeviceId,selectedVideoDeviceId:this.selectedVideoDeviceId}})}let r;try{r=await e.getUserMedia({video:t,audio:!1}),$.debug(`[StreamManager] Video-only stream acquired for preview`)}catch(e){throw this.setAudioStatus(`failed`),Dx(e)}this.mediaStream=r,this.acquisitionGeneration++;let a=this.acquisitionGeneration;return this.audioAcquisitionPromise=this.acquireAudioInBackground(e,n,a),r}async acquireAudioInBackground(e,t,n){try{let r=await this.acquireAudioTrackWithRetry(e,t);if(!this.mediaStream||this.acquisitionGeneration!==n){$.debug(`[StreamManager] Audio acquired but stream was replaced/stopped, discarding track`,{generation:n,currentGeneration:this.acquisitionGeneration}),r.stop();return}this.mediaStream.addTrack(r),$.info(`[StreamManager] Audio track added to stream`,{audioTrackId:r.id,audioTrackLabel:r.label,totalAudioTracks:this.mediaStream.getAudioTracks().length}),this.setAudioStatus(`acquired`)}catch(e){if(this.acquisitionGeneration!==n)return;let t=e instanceof Error&&`code`in e?e:Ox(e);this.pendingAudioError=t,this.setAudioStatus(`failed`),$.error(`[StreamManager] Background audio acquisition failed`,t),this.emitAudioTelemetry({name:`audio.acquisition.failed`,properties:{errorCode:t.code,errorName:t.name,maxRetries:2,retryDelayMs:this.audioRetryDelayMilliseconds,selectedAudioDeviceId:this.selectedAudioDeviceId},error:t}),this.emit(`error`,{error:t})}finally{this.audioAcquisitionPromise=null}}resolveAudioConstraintsForAttempt(e,t){if(t!==2||typeof e!=`object`)return e;let{deviceId:n,...r}=e,i=Object.keys(r).length>0?r:!0;return $.debug(`[StreamManager] Audio retry with relaxed constraints (no deviceId)`,{attempt:t}),i}async acquireAudioTrackWithRetry(e,t){let n=null;for(let r=0;r<=2;r++)try{let n=this.resolveAudioConstraintsForAttempt(t,r),i=await e.getUserMedia({video:!1,audio:n}),a=i.getAudioTracks()[0];if(!a)throw this.stopStreamTracks(i),Error(`getUserMedia returned no audio tracks`);for(let e of i.getVideoTracks())e.stop();return $.debug(`[StreamManager] Audio track acquired`,{attempt:r,trackId:a.id,trackLabel:a.label}),r>0&&this.emitAudioTelemetry({name:`audio.acquisition.recovered`,properties:{successAttempt:r,totalAttempts:r+1,audioTrackLabel:a.label,usedRelaxedConstraints:r===2}}),a}catch(e){n=e;let t=i(e),a=Sx(e),o=kx(e);if($.warn(`[StreamManager] Audio acquisition failed`,{attempt:r,maxRetries:2,error:t,errorName:a,isRetriable:o}),this.emitAudioTelemetry({name:`audio.acquisition.retry`,properties:{attempt:r,maxRetries:2,errorMessage:t,errorName:a??`unknown`,isRetriable:o,usedRelaxedConstraints:r===2,willRetry:r<2&&o}}),!(r<2&&o))break;await this.waitMilliseconds(this.audioRetryDelayMilliseconds)}throw Ox(n)}stopStream(){if(this.mediaStream){for(let e of this.mediaStream.getTracks())e.stop();this.mediaStream=null}this.audioStatus=`pending`,this.pendingAudioError=null,this.audioAcquisitionPromise=null,this.acquisitionGeneration++,this.state!==`idle`&&(this.setState(`idle`),this.emit(`streamstop`,void 0))}stopStreamTracks(e){for(let t of e.getTracks())t.stop()}isTrackLive(e){return e!==void 0&&e.readyState===`live`}async tryReplaceTrack(e,t,n){let r=e.replaceTrack;if(typeof r!=`function`)return!1;try{await r.call(e,t),e.stop();for(let e of n.getTracks())e!==t&&e.stop();return t.stop(),!0}catch{return!1}}recreateStreamWithNewTrack(e,t,n){for(let t of n.getTracks())t!==e&&t.stop();let r=[e];this.isTrackLive(t)&&t&&r.push(t);let i=new MediaStream(r);if(this.mediaStream)for(let e of this.mediaStream.getTracks())e!==t&&e.stop();return i}async switchDeviceTrack(e,t,n){if(!this.mediaStream)throw Error(`No active stream to switch device`);let r=t===`video`?this.mediaStream.getVideoTracks()[0]:this.mediaStream.getAudioTracks()[0],i=t===`video`?this.mediaStream.getAudioTracks()[0]:this.mediaStream.getVideoTracks()[0];if(!r){let e=t===`video`?`video`:`audio`;throw Error(`No ${e} track in current stream`)}let a={[t]:this.buildDeviceConstraints(e,n)},o=await Jb().getUserMedia(a),s=t===`video`?o.getVideoTracks()[0]:o.getAudioTracks()[0];if(!s){this.stopStreamTracks(o);let e=t===`video`?`video`:`audio`;throw Error(`Failed to get new ${e} track`)}return await this.tryReplaceTrack(r,s,o)||(r.stop(),this.mediaStream=this.recreateStreamWithNewTrack(s,i,o)),t===`video`?(this.selectedVideoDeviceId=e,this.emit(`videosourcechange`,{stream:this.mediaStream})):this.selectedAudioDeviceId=e,this.mediaStream}switchVideoDevice(e){return this.switchDeviceTrack(e,`video`,this.streamConfig.video)}switchAudioDevice(e){return this.switchDeviceTrack(e,`audio`,this.streamConfig.audio)}setMediaStream(e){this.mediaStream=e}setAudioTracksEnabled(e){if(!this.mediaStream)return;let t=this.mediaStream.getAudioTracks();for(let n of t)n.enabled=e}destroy(){this.stopStream(),this.eventListeners.clear(),this.setState(`idle`)}};let Mx=`recording.stop-not-ready`,Nx=`recording.finalize-not-ready`,Px=`recording.finalize-timeout`,Fx=`recording.upload-in-progress`;function Ix(e,t,n){let r=Error(`${t} [${e}]`);return r.code=e,r.isRecoverable=!0,n!==void 0&&(r.details=n),r}function Lx(e){return!(e instanceof Error)||Rx(e)?e:e.message===`Not currently recording`?Ix(Mx,`Recording is not ready to stop`):e.message===`Processing not active`?Ix(Nx,`Recording is not ready to finalize`):e}function Rx(e){let t=e;return t.code===Mx||t.code===Nx||t.code===Px||t.code===Fx}let zx=[`Bytes`,`KB`,`MB`,`GB`],Bx=1024;function Vx(e){if(e===0)return`0 Bytes`;let t=Math.floor(Math.log(e)/Math.log(Bx));return`${Math.round(e/Bx**t*100)/100} ${zx[t]}`}function Hx(e){let t=Math.floor(e/3600),n=Math.floor(e%3600/60),r=e%60;return t>0?`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`:`${n.toString().padStart(2,`0`)}:${r.toString().padStart(2,`0`)}`}let Ux={getCurrentTimestamp:()=>performance.now()};var Wx=class{constructor(e){this.recordingStartTime=0,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!1,this.visibilityChangeHandler=this.handleVisibilityChange.bind(this),this.blurHandler=this.handleBlur.bind(this),this.focusHandler=this.handleFocus.bind(this);let t=e?.getCurrentTimestamp;t===void 0?this.getCurrentTimestamp=Ux.getCurrentTimestamp:this.getCurrentTimestamp=t}start(e){this.isTracking||(this.recordingStartTime=e,this.totalPausedTime=0,this.pauseStartTime=null,this.intervals=[],this.currentIntervalStart=null,this.isTracking=!0,typeof document<`u`&&document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler)),this.checkInitialState())}pause(){!this.isTracking||this.pauseStartTime!==null||(this.pauseStartTime=this.getCurrentTimestamp(),this.endCurrentIntervalIfActive())}resume(){if(!this.isTracking||this.pauseStartTime===null)return;let e=this.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}getIntervals(){return this.endCurrentIntervalIfActive(),this.intervals.map(e=>({start:this.normalizeTimestamp(e.start),end:this.normalizeTimestamp(e.end)}))}reset(){this.intervals=[],this.currentIntervalStart=null,this.totalPausedTime=0,this.pauseStartTime=null}cleanup(){this.isTracking=!1,this.endCurrentIntervalIfActive(),typeof document<`u`&&document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),window.removeEventListener(`focus`,this.focusHandler)),this.reset()}checkInitialState(){typeof document>`u`||document.visibilityState===`hidden`&&this.startInterval()}handleVisibilityChange(){typeof document>`u`||(document.visibilityState===`hidden`?this.startInterval():this.endCurrentIntervalIfActive())}handleBlur(){this.startInterval()}handleFocus(){this.endCurrentIntervalIfActive()}startInterval(){this.currentIntervalStart!==null||!this.isTracking||this.pauseStartTime===null&&(this.currentIntervalStart=this.getCurrentTimestamp())}endCurrentIntervalIfActive(){if(this.currentIntervalStart===null)return;let e=this.getCurrentTimestamp(),t=this.currentIntervalStart;e>t&&this.intervals.push({start:t,end:e}),this.currentIntervalStart=null}normalizeTimestamp(e){let t=(e-this.recordingStartTime-this.totalPausedTime)/1e3;return Math.max(0,t)}};let Gx=1e3,Kx=1e3,qx={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},Jx={width:{ideal:854,max:854},height:{ideal:480,max:480},frameRate:{ideal:20,max:20}},Yx={width:{ideal:1280,max:1280},height:{ideal:720,max:720},frameRate:{ideal:24,max:24}},Xx=`android-post-recording-transcode`;function Zx(e){let t=e.guidance?.message??`This browser or device cannot safely record video. Try a supported browser or upload an existing video file.`,n=Error(t);return n.name=`RecordingUnsupportedError`,n.code=`recording.unsupported-with-guidance`,n.isRecoverable=!0,n}let Qx={checkRecorderSupport:vb,getCurrentTimestamp:()=>performance.now()};var $x=class{constructor(e,t){this.recordingStartTime=0,this.recordingTimer=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.bufferSizeUpdateInterval=null,this.tabVisibilityTracker=null,this.visibilityChangeHandler=null,this.blurHandler=null,this.focusHandler=null,this.preResolvedSupportReport=null,this.activeRouteDecision=qx,this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.mediaRecorderErrorTimeoutId=null,this.streamManager=e;let n=t?.checkRecorderSupport,r;r=n===void 0?Qx.checkRecorderSupport:n;let i=t?.getCurrentTimestamp,a;a=i===void 0?Qx.getCurrentTimestamp:i,this.dependencies={checkRecorderSupport:r,getCurrentTimestamp:a}}setPreResolvedSupportReport(e){this.preResolvedSupportReport=e}isRecording(){return this.streamManager.getState()===`recording`}getStreamProcessor(){return this.streamProcessor}getAudioStreamForAnalysis(){if(this.streamProcessor){let e=this.streamProcessor.getAudioStreamForAnalysis();if(e)return e}return this.streamManager.getAudioStreamForAnalysis()}async startRecording(e,t,n,r,i){this.activeRouteDecision=i??qx;let a=this.streamManager.getStream(),o=0;if(a!==null&&(o=a.getAudioTracks().length),$.debug(`[StreamRecordingState] startRecording called`,{hasMediaStream:!!a,isRecording:this.isRecording(),hasProcessor:!!e,audioTracks:o}),!a)throw Error(`Stream must be started before recording`);if(this.isRecording())return $.debug(`[StreamRecordingState] Already recording, returning`),Promise.resolve();if(!(a.getAudioTracks().length>0))throw $.error(`[StreamRecordingState] Cannot start recording without audio tracks`),Ob();if(this.activeRouteDecision.route===`unsupported-with-guidance`)throw Zx(this.activeRouteDecision);if(this.activeRouteDecision.route===`local-webcodecs`){let e=t.watermark!==void 0,n;if(n=this.preResolvedSupportReport?.isSupported?this.preResolvedSupportReport:await this.dependencies.checkRecorderSupport({requiresAudio:!0,requiresWatermark:e}),!n.isSupported)throw Nt({missingCapabilities:n.missing,resolutionStage:`feature-preflight`})}this.streamProcessor=e,$.debug(`[StreamRecordingState] StreamProcessor assigned, setting callbacks`),e.setOnMuteStateChange(e=>{this.streamManager.emit(`audiomutetoggle`,{muted:e})}),e.setOnSourceChange(e=>{this.streamManager.emit(`videosourcechange`,{stream:e})}),this.bufferSizeUpdateInterval=window.setInterval(()=>{if(!this.streamProcessor)return;let e=this.streamProcessor.getBufferSize(),t=Vx(e);this.streamManager.emit(`recordingbufferupdate`,{size:e,formatted:t})},Gx),this.resetRecordingState();let s;n===!0&&(s={enabled:!0,text:this.resolveTabVisibilityOverlayText(r),recordingStartTime:this.recordingStartTime}),$.debug(`[StreamRecordingState] Overlay config`,{enableTabVisibilityOverlay:n,hasOverlayText:!!r,overlayText:r,overlayConfig:s}),this.activeRouteDecision.route===`safe-capture-post-recording-transcode`?(await this.startSafeCaptureRecording(a,t),$.info(`[StreamRecordingState] MediaRecorder capture started for post-recording transcode`)):($.debug(`[StreamRecordingState] Starting processing`),await e.startProcessing(a,t,s),$.info(`[StreamRecordingState] Processing started and worker ready`)),n&&($.debug(`[StreamRecordingState] Setting up tab visibility tracking`,{recordingStartTime:this.recordingStartTime}),this.tabVisibilityTracker=new Wx,this.tabVisibilityTracker.start(this.recordingStartTime),this.setupVisibilityUpdates(e)),this.streamManager.setState(`recording`),this.streamManager.emit(`recordingstart`,{recorder:null}),this.startRecordingTimer()}async stopRecording(){let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Kx;if($.debug(`[StreamRecordingState] stopRecording called`,{hasStreamProcessor:!!this.streamProcessor,isRecording:this.isRecording(),recordingElapsedSeconds:e}),!(this.streamProcessor&&this.isRecording()))throw Ix(Mx,`Recording is not ready to stop`,{hasStreamProcessor:!!this.streamProcessor,streamState:this.streamManager.getState()});this.streamManager.setState(`stopping`),this.clearRecordingTimer(),this.clearBufferSizeInterval(),this.resetPauseState(),this.cleanupVisibilityUpdates();let t=[];this.tabVisibilityTracker?(t=this.tabVisibilityTracker.getIntervals(),$.debug(`[StreamRecordingState] Tab visibility intervals collected`,{intervalsCount:t.length,intervals:t}),this.tabVisibilityTracker.cleanup(),this.tabVisibilityTracker=null):$.debug(`[StreamRecordingState] No tab visibility tracker was active`);let n;if(this.activeRouteDecision.route===`safe-capture-post-recording-transcode`){let e=await this.stopSafeCaptureRecording();$.debug(`[StreamRecordingState] Finalizing MediaRecorder capture`),n={blob:e.blob,mediaRecorderDiagnostics:e.diagnostics}}else $.debug(`[StreamRecordingState] Finalizing stream processor`),n=await this.streamProcessor.finalize(),$.info(`[StreamRecordingState] Stream processor finalized`,{blobSize:n.blob.size,hasBlob:!!n.blob});return this.streamManager.setState(`active`),this.streamManager.emit(`recordingstop`,{blob:n.blob,mimeType:n.blob.type||`video/mp4`}),{blob:n.blob,tabVisibilityIntervals:t,recordingStats:n.recordingStats,encoderAcceleration:n.encoderAcceleration,mediaRecorderDiagnostics:n.mediaRecorderDiagnostics}}pauseRecording(){this.clearRecordingTimer(),this.pauseStartTime===null&&(this.pauseStartTime=this.dependencies.getCurrentTimestamp()),this.tabVisibilityTracker&&this.tabVisibilityTracker.pause(),this.mediaRecorder?.state===`recording`&&this.mediaRecorder.pause?.(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.pause()}resumeRecording(){if(this.pauseStartTime!==null){let e=this.dependencies.getCurrentTimestamp()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}this.tabVisibilityTracker&&this.tabVisibilityTracker.resume(),this.mediaRecorder?.state===`paused`&&this.mediaRecorder.resume?.(),this.startRecordingTimer(),this.streamProcessor&&this.isRecording()&&this.streamProcessor.resume()}toggleMute(){qb(this.streamProcessor,`StreamProcessor`).toggleMute()}muteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()||this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!1)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!1),this.streamManager.emit(`audiomutetoggle`,{muted:!0}))}unmuteAudio(){this.streamProcessor?(this.streamProcessor.isMutedState()&&this.streamProcessor.toggleMute(),this.streamManager.setAudioTracksEnabled(!0)):this.streamManager.getStream()&&(this.streamManager.setAudioTracksEnabled(!0),this.streamManager.emit(`audiomutetoggle`,{muted:!1}))}isMuted(){if(this.streamProcessor)return this.streamProcessor.isMutedState();let e=this.streamManager.getStream();if(e){let t=e.getAudioTracks();return t.length>0&&t.every(e=>!e.enabled)}return!1}async switchVideoSource(e){await qb(this.streamProcessor,`StreamProcessor`).switchVideoSource(e)}getCurrentVideoSource(){return Kb(qb(this.streamProcessor,`StreamProcessor`).getCurrentVideoSource(),`Current video source is not available`)}formatTimeElapsed(e){let t=Math.floor(e/60),n=Math.floor(e%60);return`${t.toString().padStart(2,`0`)}:${n.toString().padStart(2,`0`)}`}startRecordingTimer(){this.recordingTimer=window.setInterval(()=>{let e=(this.dependencies.getCurrentTimestamp()-this.recordingStartTime-this.totalPausedTime)/Kx,t=this.formatTimeElapsed(e);this.streamManager.emit(`recordingtimeupdate`,{elapsed:e,formatted:t})},Gx)}clearRecordingTimer(){this.recordingTimer!==null&&(clearInterval(this.recordingTimer),this.recordingTimer=null)}clearBufferSizeInterval(){this.bufferSizeUpdateInterval!==null&&(clearInterval(this.bufferSizeUpdateInterval),this.bufferSizeUpdateInterval=null)}resetRecordingState(){this.recordingStartTime=this.dependencies.getCurrentTimestamp(),this.totalPausedTime=0,this.pauseStartTime=null}async startSafeCaptureRecording(e,t){if(typeof MediaRecorder>`u`)throw Zx({route:`unsupported-with-guidance`,reasonCodes:[`mediarecorder-unavailable`],guidance:{canRetry:!0,message:`This browser cannot safely record on this device. Try a supported browser or upload an existing video file.`}});await this.applySafeCaptureTrackConstraints(e),this.mediaRecorderChunks=[],this.mediaRecorderError=null;let n=this.resolvePreferredSafeCaptureMimeType(t),r=n===void 0?void 0:{mimeType:n},i=new MediaRecorder(e,r);this.mediaRecorder=i,this.mediaRecorderStopPromise=new Promise((e,t)=>{this.mediaRecorderStopResolve=e,this.mediaRecorderStopReject=t}),this.mediaRecorderStopPromise.catch(()=>void 0),i.ondataavailable=e=>{e.data.size>0&&this.mediaRecorderChunks.push(e.data)},i.onstop=()=>{if(this.clearMediaRecorderErrorTimeout(),this.mediaRecorderError!==null){this.updateMediaRecorderErrorDiagnostics(i),this.mediaRecorderStopReject?.(this.mediaRecorderError);return}let e=i.mimeType||this.resolveSafeCaptureMimeType(),t=new Blob(this.mediaRecorderChunks,{type:e}),n=this.buildMediaRecorderDiagnostics(i);if(t.size>0){this.mediaRecorderStopResolve?.({blob:t,diagnostics:n});return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(i))},i.onerror=e=>{this.mediaRecorderError=this.createMediaRecorderError(e,i)},i.start(1e3)}async applySafeCaptureTrackConstraints(e){let t=this.resolveSafeCaptureVideoConstraints();if(t===null)return;let n=e.getVideoTracks();await Promise.all(n.map(async e=>{try{await e.applyConstraints(t)}catch(e){$.warn(`[StreamRecordingState] Could not apply safe capture video constraints`,e)}}))}resolveSafeCaptureVideoConstraints(){let e=this.activeRouteDecision.reasonCodes;return e.includes(`insufficient-device-memory`)||e.includes(`insufficient-hardware-concurrency`)||e.includes(`encoding-capability-unsupported`)||e.includes(`encoding-not-smooth`)||e.includes(`encoding-not-power-efficient`)?Jx:e.includes(Xx)?Yx:null}async stopSafeCaptureRecording(){let e=this.mediaRecorder,t=this.mediaRecorderStopPromise;if(!(e&&t))throw Error(`Safe capture recorder was not started`);e.state!==`inactive`&&e.stop(),this.scheduleMediaRecorderErrorFinalizeTimeout(e);try{return await t}finally{this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx}}resolveSafeCaptureMimeType(){return(this.streamManager.getStream()?.getVideoTracks().length??0)>0?`video/webm`:`audio/webm`}resolvePreferredSafeCaptureMimeType(e){let t=e=>typeof MediaRecorder.isTypeSupported==`function`?MediaRecorder.isTypeSupported(e):!1,n=[`video/webm;codecs=vp8,opus`,`video/webm;codecs=vp9,opus`,`video/webm`],r=[`video/mp4;codecs=avc1.42E01E,mp4a.40.2`,`video/mp4;codecs=avc1.42001f,mp4a.40.2`,`video/mp4`],i=r;return this.shouldPreferWebmSafeCapture(e)?i=[...n,...r]:e.format!==`mp4`&&(i=n),i.find(t)}shouldPreferWebmSafeCapture(e){return e.format===`mp4`?this.activeRouteDecision.reasonCodes.includes(Xx):!1}scheduleMediaRecorderErrorFinalizeTimeout(e){this.mediaRecorderErrorTimeoutId===null&&(this.mediaRecorderErrorTimeoutId=window.setTimeout(()=>{if(this.mediaRecorderError!==null){this.mediaRecorderStopReject?.(this.mediaRecorderError);return}this.mediaRecorderStopReject?.(this.createEmptyMediaRecorderError(e))},5e3))}clearMediaRecorderErrorTimeout(){this.mediaRecorderErrorTimeoutId!==null&&(window.clearTimeout(this.mediaRecorderErrorTimeoutId),this.mediaRecorderErrorTimeoutId=null)}createMediaRecorderError(e,t){let n=e.error,r=Error(`Browser recording failed before upload could start`);return r.name=`MediaRecorderRecordingError`,r.code=`recording.mediarecorder-error`,r.mediaRecorderMimeType=t.mimeType,r.mediaRecorderChunkCount=this.mediaRecorderChunks.length,r.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),n?.name&&(r.mediaRecorderErrorName=n.name),n?.message&&(r.mediaRecorderErrorMessage=n.message),r}createEmptyMediaRecorderError(e){let t=Error(`Browser recording produced no data before upload could start`);return t.name=`MediaRecorderEmptyDataError`,t.code=`recording.mediarecorder-empty`,t.mediaRecorderMimeType=e.mimeType,t.mediaRecorderChunkCount=this.mediaRecorderChunks.length,t.mediaRecorderChunkSize=this.getMediaRecorderChunkSize(),this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}updateMediaRecorderErrorDiagnostics(e){this.mediaRecorderError!==null&&(this.mediaRecorderError.mediaRecorderMimeType=e.mimeType,this.mediaRecorderError.mediaRecorderChunkCount=this.mediaRecorderChunks.length,this.mediaRecorderError.mediaRecorderChunkSize=this.getMediaRecorderChunkSize())}buildMediaRecorderDiagnostics(e){let t={mediaRecorderMimeType:e.mimeType,mediaRecorderChunkCount:this.mediaRecorderChunks.length,mediaRecorderChunkSize:this.getMediaRecorderChunkSize(),mediaRecorderHadError:this.mediaRecorderError!==null};return this.mediaRecorderError?.mediaRecorderErrorName&&(t.mediaRecorderErrorName=this.mediaRecorderError.mediaRecorderErrorName),this.mediaRecorderError?.mediaRecorderErrorMessage&&(t.mediaRecorderErrorMessage=this.mediaRecorderError.mediaRecorderErrorMessage),t}getMediaRecorderChunkSize(){return this.mediaRecorderChunks.reduce((e,t)=>e+t.size,0)}resetPauseState(){this.totalPausedTime=0,this.pauseStartTime=null}resolveTabVisibilityOverlayText(e){return e===void 0||e.trim().length===0?`User in another tab`:e}setupVisibilityUpdates(e){if(typeof document>`u`||typeof window>`u`){$.warn(`[StreamRecordingState] Cannot setup visibility updates - document/window not available`);return}if(this.visibilityChangeHandler=()=>{if(typeof document>`u`)return;let t=document.visibilityState===`hidden`,n=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Visibility change`,{isHidden:t,timestamp:n,visibilityState:document.visibilityState}),e.updateTabVisibility(t,n)},this.blurHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window blur`,{timestamp:t}),e.updateTabVisibility(!0,t)},this.focusHandler=()=>{let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Window focus`,{timestamp:t}),e.updateTabVisibility(!1,t)},document.addEventListener(`visibilitychange`,this.visibilityChangeHandler),window.addEventListener(`blur`,this.blurHandler),window.addEventListener(`focus`,this.focusHandler),document.visibilityState===`hidden`){let t=this.dependencies.getCurrentTimestamp();$.debug(`[StreamRecordingState] Initial state is hidden`,{timestamp:t}),e.updateTabVisibility(!0,t)}else $.debug(`[StreamRecordingState] Initial state is visible`)}cleanupVisibilityUpdates(){this.visibilityChangeHandler&&typeof document<`u`&&(document.removeEventListener(`visibilitychange`,this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.blurHandler&&typeof window<`u`&&(window.removeEventListener(`blur`,this.blurHandler),this.blurHandler=null),this.focusHandler&&typeof window<`u`&&(window.removeEventListener(`focus`,this.focusHandler),this.focusHandler=null)}destroy(){this.mediaRecorder&&this.mediaRecorder.state!==`inactive`&&this.mediaRecorder.stop(),this.mediaRecorder=null,this.mediaRecorderChunks=[],this.mediaRecorderStopPromise=null,this.mediaRecorderStopResolve=null,this.mediaRecorderStopReject=null,this.mediaRecorderError=null,this.clearMediaRecorderErrorTimeout(),this.activeRouteDecision=qx,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.cleanupVisibilityUpdates(),this.tabVisibilityTracker&&=(this.tabVisibilityTracker.cleanup(),null),this.clearRecordingTimer(),this.clearBufferSizeInterval()}},eS=class{constructor(e={}){this.streamManager=new jx(e),this.recordingState=new $x(this.streamManager)}getState(){return this.streamManager.getState()}getStream(){return this.streamManager.getStream()}getAudioStreamForAnalysis(){return this.recordingState.getAudioStreamForAnalysis()}isRecording(){return this.recordingState.isRecording()}isActive(){return this.streamManager.isActive()}on(e,t){return this.streamManager.on(e,t)}off(e,t){this.streamManager.off(e,t)}once(e,t){return this.streamManager.once(e,t)}setAudioDevice(e){this.streamManager.setAudioDevice(e)}setVideoDevice(e){this.streamManager.setVideoDevice(e)}getAudioDevice(){return this.streamManager.getAudioDevice()}getVideoDevice(){return this.streamManager.getVideoDevice()}async getAvailableDevices(){return await this.streamManager.getAvailableDevices()}async startStream(){return await this.streamManager.startStream()}stopStream(){this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(e,t,n,r,i){return await this.recordingState.startRecording(e,t,n,r,i)}async stopRecording(){return await this.recordingState.stopRecording()}pauseRecording(){this.recordingState.pauseRecording()}resumeRecording(){this.recordingState.resumeRecording()}toggleMute(){this.recordingState.toggleMute()}muteAudio(){this.recordingState.muteAudio()}unmuteAudio(){this.recordingState.unmuteAudio()}isMuted(){return this.recordingState.isMuted()}async switchVideoSource(e){return await this.recordingState.switchVideoSource(e)}setMediaStream(e){this.streamManager.setMediaStream(e)}getCurrentVideoSource(){return this.recordingState.getCurrentVideoSource()}getAudioStatus(){return this.streamManager.getAudioStatus()}isAudioReady(){return this.streamManager.isAudioReady()}async waitForAudio(){return await this.streamManager.waitForAudio()}setPreResolvedSupportReport(e){this.recordingState.setPreResolvedSupportReport(e)}destroy(){this.recordingState.destroy(),this.streamManager.destroy()}};let tS=new Set([`recording.audio-no-chunks`,`recording.audio-silent`,`recording.audio-track-ended`,`recording.no-audio-track`,`recording.no-audio-frames`,`recording.audio-zero-channels`,`recording.audio-invalid-sample-rate`]),nS=new Set([`recording.codec-unsupported`,`recording.video-codec-unavailable`]),rS=new Set([`recording.post-recording-transcode-fallback`,`recording.mediarecorder-empty`,`recording.mediarecorder-error`,`transcode.post-recording-fallback`,`route.post-recording-transcode-fallback`]),iS=new Set([`recording.no-video-frames`,`recording.frame-loss`,`recording.excessive-frame-errors`,`video.first-frame-timeout`]),aS=new Set([`recording.finalize-timeout`,`recording.finalize-timeout-low-resource`,`stop.pending-writes-timeout`]),oS=new Set([`recording.not-started`,`recording.state-race`,`recording.not-started-state-race`]),sS=new Set([`recording.unsupported-with-guidance`,`recording.unsupported-device`]);function cS(e){return e.startsWith(`recording.`)?tS.has(e):!1}function lS(e){return e==null?null:i(e)}function uS(e){if(!(e&&typeof e==`object`&&`code`in e))return null;let t=e.code;return typeof t!=`string`||t.length===0?null:t}function dS(e){return e?nS.has(e)?`recording.codec-unsupported`:rS.has(e)?`recording.post-recording-transcode-fallback`:iS.has(e)?`recording.no-video-frames`:aS.has(e)?`recording.finalize-timeout-low-resource`:oS.has(e)?`recording.not-started-state-race`:sS.has(e)?`recording.unsupported-device`:null:null}function fS(e,t){return t.some(t=>e.includes(t))}function pS(e){if(!e)return null;let t=e.toLowerCase();return fS(t,[`videoencoder.isconfigsupported`,`unknown codec`,`unsupported codec`,`no encodable video codec`,`video codec unavailable`])?`recording.codec-unsupported`:fS(t,[`input track cannot be ended`,`mediastreamtrackprocessor`,`video track ended`])?`recording.track-ended`:fS(t,[`no video frames`,`zero video frames`,`video.first-frame-timeout`,`failed to yield first frame`,`frame-loss`,`excessive frame errors`])?`recording.no-video-frames`:fS(t,[`finalize timeout`,`stop.pending-writes-timeout`])||t.includes(`pending writes`)&&t.includes(`timeout`)?`recording.finalize-timeout-low-resource`:fS(t,[`cannot finalize before starting`,`processing not active`,`worker not initialized`])?`recording.not-started-state-race`:fS(t,[`recording.unsupported-with-guidance`,`cannot safely record`,`recording is not supported in this browser context`])?`recording.unsupported-device`:null}function mS(e){return dS(e.errorCode??uS(e.error))||pS(e.errorMessage??lS(e.error))}let hS=Object.freeze({visible:!1,variant:`generic`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1});function gS(e){let{errorCode:t,hasAudioFailed:n,error:r}=e,i=mS({errorCode:t,error:r});if(t===`browser.unsupported`)return{visible:!0,variant:`browser`,canRetry:!1,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!0,isPermissionDenied:!1};if(t&&cS(t))return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(i)return{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1,actionableCode:i,isRecordingPipelineError:!0};if(t?.startsWith(`camera.`)){let e=t===`camera.permission-denied`;return{visible:!0,variant:`camera`,canRetry:!e,isCameraError:!0,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:e}}if(n)return{visible:!0,variant:`audio`,canRetry:!0,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:!1};if(t?.startsWith(`audio.`)){let e=t===`audio.permission-denied`;return{visible:!0,variant:`audio`,canRetry:!e,isCameraError:!1,isAudioError:!0,isBrowserUnsupported:!1,isPermissionDenied:e}}return r?{visible:!0,variant:`generic`,canRetry:!0,isCameraError:!1,isAudioError:!1,isBrowserUnsupported:!1,isPermissionDenied:!1}:hS}let _S=`VIDTREO_INSTALLATION_ID`,vS=`unknown`,yS=/\[([a-z]+(?:[.-][a-z0-9]+)+)\]/i,bS=/\b([a-z]+(?:[.-][a-z0-9]+)+)\b/i,xS=[`mediaRecorderErrorName`,`mediaRecorderErrorMessage`,`mediaRecorderMimeType`,`mediaRecorderChunkCount`,`mediaRecorderChunkSize`];function SS(e){let t=e.storageProvider,n=t?.getItem(_S);if(n)return $.debug(`Using existing installation ID from storage`,{installationId:n}),n;let r=CS(e);return t?.setItem(_S,r),$.debug(`Created new installation ID`,{installationId:r}),r}function CS(e){let t=e.cryptoProvider;if(t?.getRandomValues){let e=new Uint8Array(16);return t.getRandomValues(e),Array.from(e).map(e=>e.toString(16).padStart(2,`0`)).join(``)}let n=e.nowProvider().toString(16),r=e.randomProvider();return`${n}-${Math.floor(r*1e9).toString(16)}`}let wS=[`sdk.init.started`,`sdk.init.succeeded`,`sdk.init.failed`],TS=[`stream.error`],ES={"sdk.init.started":`lifecycle`,"sdk.init.succeeded":`lifecycle`,"sdk.init.failed":`error`,"preview.start.succeeded":`interaction`,"preview.start.failed":`error`,"recording.start.requested":`interaction`,"recording.start.succeeded":`interaction`,"recording.start.failed":`error`,"recording.stop.requested":`interaction`,"recording.stop.succeeded":`interaction`,"recording.stop.failed":`error`,"recording.route.selected":`lifecycle`,"upload.started":`performance`,"upload.succeeded":`performance`,"upload.failed":`error`,"upload.route.selected":`lifecycle`,"transcode.route.selected":`lifecycle`,"source.switch.requested":`interaction`,"source.switch.succeeded":`interaction`,"source.switch.failed":`error`,"stream.error":`error`,"audio.acquisition.fallback":`lifecycle`,"audio.acquisition.retry":`lifecycle`,"audio.acquisition.recovered":`lifecycle`,"audio.acquisition.failed":`error`,"audio.warning":`performance`,"recording.audio-missing":`error`,"storage.init.failed":`error`,"storage.write.probe.failed":`error`};var DS=class{constructor(e,t){this.pendingEvents=[],this.flushTimeoutId=null,this.throttledEventTimestamps=new Map,this.retryCountMap=new Map,this.oneTimeEventCache=new Map,this.config=e,this.dependencies=t,this.installationId=SS(this.dependencies),$.debug(`TelemetryClient initialized`,{installationId:this.installationId,backendUrl:e.backendUrl})}triggerTelemetryEvent(e){try{let t=this.dependencies.nowProvider();if(this.shouldSkipEvent(e.name,t))return;let n=ES[e.name],r=this.buildError(e.error),i=this.buildFingerprint(),a=this.buildContext(),o=this.mergeProperties(this.buildBaseProperties(i),e),s={event:e.name,category:n,timestamp:t,installationId:this.installationId,fingerprint:i,sdkVersion:`1.7.1`,context:a,properties:o,error:r};this.markEventTracking(e.name,t),this.enqueueEvent(s)}catch(t){$.error(`Telemetry event failed`,{eventName:e.name,error:i(t)})}}enqueueEvent(e){try{if(this.pendingEvents=[...this.pendingEvents,e],this.pendingEvents.length>=10){this.flushQueue();return}this.scheduleFlush()}catch(e){$.error(`Failed to enqueue telemetry event`,{error:i(e)})}}scheduleFlush(){this.flushTimeoutId||=this.dependencies.setTimeoutFunction(()=>{this.flushQueue()},1e3)}flushQueue(){try{if(this.pendingEvents.length===0){this.clearFlushTimer();return}let e=this.pendingEvents;this.pendingEvents=[],this.clearFlushTimer();let t=this.buildRequestPayload(e);$.debug(`Telemetry batch flush`,{eventsCount:t.events.length}),this.sendPayload(t).then(()=>{this.clearRetryMetadata(e)}).catch(()=>{this.requeueFailedEvents(e)})}catch(e){$.error(`Failed to flush telemetry queue`,{error:i(e)})}}clearFlushTimer(){this.flushTimeoutId&&=(this.dependencies.clearTimeoutFunction(this.flushTimeoutId),null)}buildRequestPayload(e){return{events:[...e]}}shouldSkipEvent(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);if(this.oneTimeEventCache.get(t))return $.debug(`Telemetry event skipped (dedupe)`,{event:e}),!0}if(this.isThrottledEvent(e)){let n=this.throttledEventTimestamps.get(e);if(n!==void 0&&t-n<5e3)return $.debug(`Telemetry event skipped (throttle)`,{event:e,lastSent:n}),!0}return!1}markEventTracking(e,t){if(this.isOneTimeEvent(e)){let t=this.getOneTimeCacheKey(e);this.oneTimeEventCache.set(t,!0)}this.isThrottledEvent(e)&&(this.throttledEventTimestamps=this.updateNumberMap(this.throttledEventTimestamps,e,t))}updateNumberMap(e,t,n){let r=new Map(e);return r.set(t,n),r}getOneTimeCacheKey(e){return`${this.installationId}:${e}`}isOneTimeEvent(e){return wS.includes(e)}isThrottledEvent(e){return TS.includes(e)}buildBaseProperties(e){let t={},n=e.userAgent,r=this.getBrowserName(n);return r&&(t={...t,browserName:r}),t}mergeProperties(e,t){let n=this.sanitizeEventProperties(t.properties),r=this.buildErrorProperties(t.error);if(Object.keys(e).length===0&&Object.keys(r).length===0&&!n)return;let i={...e,...r,...n};if(Object.keys(i).length>0)return i}sanitizeEventProperties(e){if(!e)return;let t=this.sanitizeRouteDecision(e.routeDecision);return t===void 0?e:{...e,routeDecision:t}}sanitizeRouteDecision(e){if(!(e&&typeof e==`object`))return;let t=e,n={};typeof t.selectedRoute==`string`&&(n={...n,selectedRoute:t.selectedRoute}),Array.isArray(t.reasonCodes)&&(n={...n,reasonCodes:t.reasonCodes.filter(e=>typeof e==`string`)});let r=this.sanitizeCapabilitySummary(t.capabilitySummary);if(r!==void 0&&(n={...n,capabilitySummary:r}),this.isRouteSourceType(t.sourceType)&&(n={...n,sourceType:t.sourceType}),typeof t.clientTranscodeDeferred==`boolean`&&(n={...n,clientTranscodeDeferred:t.clientTranscodeDeferred}),Object.keys(n).length!==0)return n}sanitizeCapabilitySummary(e){if(!(e&&typeof e==`object`))return;let t={};for(let[n,r]of Object.entries(e))this.isSafeCapabilityValue(r)&&(t={...t,[n]:r});if(Object.keys(t).length!==0)return t}isSafeCapabilityValue(e){return e===null||typeof e==`boolean`||typeof e==`number`||typeof e==`string`?!0:Array.isArray(e)&&e.every(e=>typeof e==`string`)}isRouteSourceType(e){return e===`live-recorder`||e===`native-camera`||e===`file-upload`}buildErrorProperties(e){if(!e)return{};let t={},n=uS(e),r=i(e),a=n??this.extractNormalizedErrorCode(r),o=mS({errorCode:a,error:e,errorMessage:r});return a&&(t={...t,errorCode:a}),o&&(t={...t,rawErrorClassification:o,recordingPipelineErrorCode:o}),{...t,...this.buildMediaRecorderErrorProperties(e)}}buildMediaRecorderErrorProperties(e){if(!(e&&typeof e==`object`))return{};let t=e,n={};for(let e of xS){let r=t[e];(typeof r==`string`||typeof r==`number`||typeof r==`boolean`)&&(n={...n,[e]:r})}return n}buildFingerprint(){let e=this.dependencies.navigatorProvider;if(!e)return{};let t={userAgent:e.userAgent,language:e.language,platform:e.platform};e.hardwareConcurrency&&(t={...t,hardwareConcurrency:e.hardwareConcurrency});let n=this.getDeviceMemory(e);return n!==null&&(t={...t,deviceMemory:n}),t}buildContext(){let e=this.config.pageUrl,t=this.config.referrerUrl;if(!e){let t=this.dependencies.locationProvider;t&&(e=t.href)}if(!t){let e=this.dependencies.documentProvider;if(e){let n=e.referrer;n&&(t=n)}}return{sessionId:this.config.sessionId,userId:this.config.userId,environmentId:this.config.environmentId,appVersion:this.config.appVersion,release:this.config.release,pageUrl:e,referrerUrl:t,sdkLocation:this.config.sdkLocation,clientLocation:this.config.clientLocation}}buildError(e){if(!e)return;let t=i(e),n={message:t},r=uS(e),a=r??this.extractNormalizedErrorCode(t);return a&&(n.normalizedCode=a),r?n.code=r:a&&(n.code=a),e instanceof Error&&(!n.code&&e.name&&(n.code=e.name),e.stack&&(n.stack=e.stack)),n}extractNormalizedErrorCode(e){let t=e.match(yS);if(t?.[1])return t[1];let n=e.match(bS);return n?.[1]?n[1]:null}getBrowserName(e){return e?e.includes(`Edg`)?`edge`:e.includes(`Chrome`)?`chrome`:e.includes(`Firefox`)?`firefox`:e.includes(`Safari`)?`safari`:vS:vS}getDeviceMemory(e){let t=e;return t.deviceMemory?t.deviceMemory:null}async sendPayload(e){let t=this.buildTelemetryEndpoint(),n={method:`POST`,headers:{"Content-Type":`application/json`,Authorization:`Bearer ${this.config.apiKey}`},body:JSON.stringify(e)};$.debug(`Sending telemetry to endpoint`,{endpoint:t,payloadSize:JSON.stringify(e).length,hasApiKey:!!this.config.apiKey});let r=await this.dependencies.fetchFunction(t,n).catch(e=>{throw $.error(`Failed to send telemetry`,{endpoint:t,error:i(e)}),e});if(r&&!r.ok)throw $.error(`Telemetry endpoint returned error`,{status:r.status}),Error(`Telemetry HTTP ${r.status}`)}requeueFailedEvents(e){let t=e.filter(e=>(this.retryCountMap.get(e)??0)<3);for(let e of t){let t=this.retryCountMap.get(e)??0;this.retryCountMap.set(e,t+1)}let n=e.length-t.length;if(n>0){let r=e.filter(e=>!t.includes(e));this.clearRetryMetadata(r),$.warn(`Dropped ${n} telemetry events after max retries`)}if(t.length===0)return;let r=this.pendingEvents.length,i=Math.max(0,100-r);this.pendingEvents=[...t.slice(0,i),...this.pendingEvents],this.scheduleFlush()}clearRetryMetadata(e){for(let t of e)this.retryCountMap.delete(t)}buildTelemetryEndpoint(){return this.config.endpoint?this.config.endpoint:`${this.config.backendUrl}/api/v1/telemetry`}};function OS(){let e=typeof window<`u`,t=typeof document<`u`,n=fetch,r=null,i=null,a=null,o=null,s=null,c=setTimeout,l=clearTimeout;return e&&(n=window.fetch.bind(window),r=window.crypto,i=window.localStorage,a=window.navigator,o=window.location,c=window.setTimeout.bind(window),l=window.clearTimeout.bind(window)),t&&(s=document),{fetchFunction:n,cryptoProvider:r,storageProvider:i,navigatorProvider:a,locationProvider:o,documentProvider:s,nowProvider:()=>Date.now(),randomProvider:()=>Math.random(),setTimeoutFunction:c,clearTimeoutFunction:l}}function kS(e,t,n){return new DS({apiKey:e,backendUrl:t,endpoint:n?.endpoint,sessionId:n?.sessionId,userId:n?.userId,environmentId:n?.environmentId,appVersion:n?.appVersion,release:n?.release,pageUrl:n?.pageUrl,referrerUrl:n?.referrerUrl,sdkLocation:n?.sdkLocation,clientLocation:n?.clientLocation},OS())}var AS=class{constructor(e,t){this.isProcessing=!1,this.hasRecoveredStaleUploads=!1,this.retryTimeoutId=null,this.callbacks={},this.storageService=e,this.uploadService=t,this.networkOnlineHandler=()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`network-recovery`,Error(t))})},window.addEventListener(`online`,this.networkOnlineHandler),this.processingIntervalId=window.setInterval(()=>{this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`processing-loop`,Error(t))})},5e3)}destroy(){this.clearTimer(this.processingIntervalId,clearInterval),this.clearTimer(this.retryTimeoutId,clearTimeout),window.removeEventListener(`online`,this.networkOnlineHandler)}setCallbacks(e){this.callbacks=e}async queueUpload(e){let t=await this.storageService.savePendingUpload(e);return this.processQueue().catch(e=>{let n=i(e);this.callbacks.onUploadError?.(t,Error(n))}),t}async processQueue(){if(!this.isProcessing){this.isProcessing=!0;try{if(!this.storageService.isInitialized())throw Error(`Database not initialized`);if(!this.hasRecoveredStaleUploads){let e=await this.storageService.getPendingUploads(`uploading`);await Promise.all(e.map(e=>this.storageService.updateUploadStatus(e.id,{status:`pending`}))),this.hasRecoveredStaleUploads=!0}let e=await this.storageService.getPendingUploads(`pending`);if(e.length>0){let t=this.getOldestUpload(e);await this.processUpload(t),this.isProcessing=!1;return}let t=(await this.storageService.getPendingUploads(`failed`)).filter(e=>e.retryCount<10);if(t.length>0){let e=this.getOldestFailedUpload(t),n=this.calculateRetryDelay(e.retryCount),r=Date.now()-e.updatedAt;if(r>=n)await this.storageService.updateUploadStatus(e.id,{status:`pending`,retryCount:e.retryCount}),await this.processUpload(e);else{let e=n-r;this.scheduleRetry(e)}}this.isProcessing=!1}catch(e){throw this.isProcessing=!1,Error(`Error processing upload queue: ${i(e)}`)}}}getPendingUploads(){return this.storageService.getPendingUploads()}async getStats(){let e=await this.storageService.getPendingUploads(),t={pending:0,uploading:0,failed:0,total:e.length};for(let n of e)n.status===`pending`?t.pending+=1:n.status===`uploading`?t.uploading+=1:n.status===`failed`&&(t.failed+=1);return t}getOldestUpload(e){if(e.length===0)throw Error(`Cannot get oldest upload from empty array`);return e.sort((e,t)=>e.createdAt-t.createdAt)[0]}getOldestFailedUpload(e){if(e.length===0)throw Error(`Cannot get oldest failed upload from empty array`);return e.sort((e,t)=>e.updatedAt-t.updatedAt)[0]}async processUpload(e){try{await this.storageService.updateUploadStatus(e.id,{status:`uploading`});let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:e.metadata,userMetadata:e.userMetadata,onProgress:t=>{this.callbacks.onUploadProgress?.(e.id,t)}});await this.storageService.deleteUpload(e.id),this.callbacks.onUploadComplete?.(e.id,t)}catch(t){let n=i(t),r=e.retryCount+1;if(await this.storageService.updateUploadStatus(e.id,{status:`failed`,retryCount:r,lastError:n}),r>=10)this.callbacks.onUploadError?.(e.id,Error(`Upload failed after 10 attempts: ${n}`));else{let e=this.calculateRetryDelay(r);this.scheduleRetry(e)}}}calculateRetryDelay(e){let t=2e3*1.5**(e-1);return Math.min(t,3e5)}scheduleRetry(e){this.clearTimer(this.retryTimeoutId,clearTimeout),this.retryTimeoutId=window.setTimeout(()=>{this.retryTimeoutId=null,this.processQueue().catch(e=>{let t=i(e);this.callbacks.onUploadError?.(`scheduled-retry`,Error(t))})},e)}clearTimer(e,t){e!==null&&t(e)}},jS=class{uploadVideo(e,t){if(!t.filename)throw Error(`Filename is required`);if(!e.type||e.type.trim()===``)throw Error(`Blob type is required`);return this.uploadVideoFile(e,t)}uploadVideoFile(e,t){return new Promise((n,r)=>{let i=new XMLHttpRequest,a=this.createUploadBlob(e,t.mimeType);if(t.onProgress){let e=t.onProgress;i.upload.addEventListener(`progress`,t=>{t.lengthComputable&&e(t.loaded/t.total)})}i.addEventListener(`load`,()=>{if(i.status>=200&&i.status<=299){this.parseSuccessResponse(i,n,r);return}this.parseErrorResponse(i,r)}),i.addEventListener(`error`,()=>{r(Error(`Network error during upload`))}),i.addEventListener(`abort`,()=>{r(Error(`Upload was aborted`))});let o=`${t.backendUrl}/api/v1/videos/upload`;i.open(`POST`,o),i.setRequestHeader(`Authorization`,`Bearer ${t.apiKey}`);let s=new FormData;s.append(`file`,a,t.filename);let c={filename:t.filename,mimeType:a.type};t.userMetadata&&(c.userMetadata=t.userMetadata),s.append(`metadata`,JSON.stringify(c)),i.send(s)})}createUploadBlob(e,t){let n=this.resolveUploadMimeType(e,t);return n===e.type?e:new Blob([e],{type:n})}resolveUploadMimeType(e,t){return t&&t.trim().length>0?this.normalizeMimeType(t):this.normalizeMimeType(e.type)}normalizeMimeType(e){let[t]=e.split(`;`);return t===void 0?e.trim().toLowerCase():t.trim().toLowerCase()}parseSuccessResponse(e,t,n){let r=this.safeParseJsonFromXhr(e);if(!r){n(Error(`Failed to parse upload response: invalid JSON`));return}let i=r.data;if(!i){n(Error(`Failed to parse upload response: missing data`));return}t({id:i.id,publicId:i.publicId,filename:i.filename,fileSize:i.fileSize,mimeType:i.mimeType,duration:i.duration,status:i.status,uploadUrl:i.uploadUrl,createdAt:i.createdAt})}parseErrorResponse(e,t){let n=this.safeParseJsonFromXhr(e);if(n&&typeof n==`object`&&`error`in n&&typeof n.error==`string`){t(Error(n.error));return}t(Error(`Upload failed: ${e.status} ${e.statusText}`))}safeParseJsonFromXhr(e){if(!e.responseText||e.responseText.trim()===``)return null;let t=e.responseText.trim();if(!(t.startsWith(`{`)&&t.endsWith(`}`))||t.length<2)return null;let n=JSON.parse(e.responseText);return typeof n==`object`&&n?n:null}};let MS=e=>{},NS=e=>{},PS=e=>{},FS=()=>{},IS=e=>{},LS=(e,t)=>{},RS=e=>{},zS=e=>{},BS=e=>{},VS=()=>{},HS=e=>{};function US(e){let t={onProgress:MS,onSuccess:NS,onError:PS,onClearStatus:FS};return e.upload&&(t=e.upload),t}let WS=e=>{};function GS(e){let t=HS;return e.onStorageCleanupError&&(t=e.onStorageCleanupError),t}function KS(e){let t=WS;return e.onStorageWriteError&&(t=e.onStorageWriteError),t}function qS(e,t){let n=e.recording,r=IS;n?.onStateChange&&(r=n.onStateChange);let i=LS;n?.onCountdownUpdate&&(i=n.onCountdownUpdate);let a=RS;n?.onTimerUpdate&&(a=n.onTimerUpdate);let o=zS;n?.onError&&(o=n.onError);let s=BS;n?.onRecordingComplete&&(s=n.onRecordingComplete);let c=VS;return n?.onClearUploadStatus&&(c=n.onClearUploadStatus),{onStateChange:r,onCountdownUpdate:i,onTimerUpdate:a,onError:o,onRecordingComplete:s,onClearUploadStatus:c,onStopAudioTracking:t.stopAudioTracking,onGetConfig:t.getConfig,...t.getRouteDecision&&{onGetRouteDecision:t.getRouteDecision},...t.onAudioWarning&&{onAudioWarning:t.onAudioWarning},...t.onAudioRecovered&&{onAudioRecovered:t.onAudioRecovered},...t.onTranscodingProgress&&{onTranscodingProgress:t.onTranscodingProgress}}}function JS(e,t){let n=e.sourceSwitch;return{onSourceChange:n?.onSourceChange,onPreviewUpdate:n?.onPreviewUpdate,onError:n?.onError,onTransitionStart:n?.onTransitionStart,onTransitionEnd:n?.onTransitionEnd,onScreenSelectionStart:()=>{t.isRecording()&&t.updateSourceType(!0)},onScreenSelectionEnd:()=>{t.isRecording()&&t.updateSourceType(!1)},getSelectedCameraDeviceId:t.getSelectedCameraDeviceId,getSelectedMicDeviceId:t.getSelectedMicDeviceId}}var YS=class{constructor(e={}){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1,this.silenceThreshold=this.resolveNumber(e.silenceThreshold,.001),this.lowSignalThreshold=this.resolveNumber(e.lowSignalThreshold,.05),this.mutedSpeechThreshold=this.resolveNumber(e.mutedSpeechThreshold,this.silenceThreshold),this.silentWarningDurationMs=this.resolveNumber(e.silentWarningDurationMs,2e3),this.lowSignalWarningDurationMs=this.resolveNumber(e.lowSignalWarningDurationMs,2e3),this.mutedSpeechWarningDurationMs=this.resolveNumber(e.mutedSpeechWarningDurationMs,1e4),this.noChunkWarningDurationMs=this.resolveNumber(e.noChunkWarningDurationMs,2e3)}recordChunk(e){this.markStarted(e.timestampMs),this.trackMuteState(e.timestampMs,e.isMuted);let t=this.calculateChunkStats(e.samples),n=this.resolveOptionalNumber(e.inputPeak,t.peak),r=this.resolveOptionalNumber(e.inputRms,t.rms),i=t.peak<=this.silenceThreshold,a=!e.isMuted&&t.peak>this.silenceThreshold&&t.peak<this.lowSignalThreshold,o=e.isMuted&&n>this.mutedSpeechThreshold;return this.totalChunks+=1,this.peak=t.peak,this.rms=t.rms,this.inputPeak=n,this.inputRms=r,i||(this.nonSilentChunks+=1,this.silentStartedAtMs=null),a&&(this.lowSignalChunks+=1),t.peak>=this.lowSignalThreshold&&(this.hasHealthySignal=!0),i&&this.silentStartedAtMs===null&&(this.silentStartedAtMs=e.timestampMs),a&&this.lowSignalStartedAtMs===null&&(this.lowSignalStartedAtMs=e.timestampMs),a||(this.lowSignalStartedAtMs=null),o&&this.mutedSpeechStartedAtMs===null&&(this.mutedSpeechStartedAtMs=e.timestampMs),o||(this.mutedSpeechStartedAtMs=null),this.lastChunkTimestampMs=e.timestampMs,this.snapshot(e.timestampMs,e.isMuted)}inspect(e,t){return this.markStarted(e),this.trackMuteState(e,t),this.snapshot(e,t)}reset(){this.totalChunks=0,this.nonSilentChunks=0,this.lowSignalChunks=0,this.peak=0,this.rms=0,this.inputPeak=0,this.inputRms=0,this.startedAtMs=null,this.lastChunkTimestampMs=null,this.silentStartedAtMs=null,this.lowSignalStartedAtMs=null,this.mutedSpeechStartedAtMs=null,this.mutedStartedAtMs=null,this.mutedDurationMs=0,this.currentMuted=!1,this.hasHealthySignal=!1}snapshot(e,t){let n=this.resolveSilentDuration(e),r=this.resolveLowSignalDuration(e),i=this.resolveMutedSpeechDuration(e),a=this.resolveNoChunkDuration(e),o=this.resolveMutedDuration(e,t);return{classification:this.classify(t,n,r,i,a),totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,peak:this.peak,rms:this.rms,inputPeak:this.inputPeak,inputRms:this.inputRms,consecutiveSilentDurationMs:n,consecutiveLowSignalDurationMs:r,consecutiveMutedSpeechDurationMs:i,noChunkDurationMs:a,mutedDurationMs:o,hasHealthySignal:this.hasHealthySignal}}getFinalSnapshot(e,t){let n=this.resolveMutedDuration(e,t);return{totalChunks:this.totalChunks,nonSilentChunks:this.nonSilentChunks,lowSignalChunks:this.lowSignalChunks,mutedDurationMs:n,hasHealthySignal:this.hasHealthySignal}}classify(e,t,n,r,i){return this.totalChunks===0&&i>=this.noChunkWarningDurationMs?`no-chunks`:e&&r>=this.mutedSpeechWarningDurationMs?`speaking-while-muted`:e&&t>=this.silentWarningDurationMs?`muted-silence-expected`:!e&&t>=this.silentWarningDurationMs?`silent-while-unmuted`:!e&&this.nonSilentChunks>0&&this.peak<this.lowSignalThreshold&&n>=this.lowSignalWarningDurationMs?`low-signal`:`healthy`}calculateChunkStats(e){if(e.length===0)return{peak:0,rms:0};let t=0,n=0;for(let r of e){let e=Math.abs(r);t=Math.max(t,e),n+=r*r}return{peak:t,rms:Math.sqrt(n/e.length)}}resolveSilentDuration(e){return this.silentStartedAtMs===null?0:e-this.silentStartedAtMs}resolveLowSignalDuration(e){return this.lowSignalStartedAtMs===null?0:e-this.lowSignalStartedAtMs}resolveMutedSpeechDuration(e){return this.mutedSpeechStartedAtMs===null?0:e-this.mutedSpeechStartedAtMs}resolveNoChunkDuration(e){return this.lastChunkTimestampMs===null?this.startedAtMs===null?0:e-this.startedAtMs:e-this.lastChunkTimestampMs}markStarted(e){this.startedAtMs===null&&(this.startedAtMs=e)}trackMuteState(e,t){if(t!==this.currentMuted){if(t){this.mutedStartedAtMs=e,this.currentMuted=!0;return}this.mutedStartedAtMs!==null&&(this.mutedDurationMs+=e-this.mutedStartedAtMs),this.mutedStartedAtMs=null,this.currentMuted=!1}}resolveMutedDuration(e,t){return t&&this.mutedStartedAtMs!==null?this.mutedDurationMs+e-this.mutedStartedAtMs:this.mutedDurationMs}resolveNumber(e,t){if(e===void 0)return t;if(!Number.isFinite(e)||e<0)throw Error(`Audio health monitor option must be a non-negative number`);return e}resolveOptionalNumber(e,t){return e===void 0||!Number.isFinite(e)||e<0?t:e}};function XS(e){let t=e.getVideoTracks();if(t.length===0)return!1;let n=t[0];return`displaySurface`in n.getSettings()||n.label.toLowerCase().includes(`screen`)||n.label.toLowerCase().includes(`display`)}Sv();function ZS(e){if(e!==void 0)return typeof e==`number`?e:e===cf?`low`:e===lf?`medium`:e===uf?`high`:e===df?`very-high`:`high`}function QS(e){let t=null,n=0;function r(){if(!t){let n=e.createBlob();t=e.createObjectUrl(n)}return n+=1,t}function i(){n!==0&&(--n,n===0&&(t&&=(e.revokeObjectUrl(t),null)))}return{acquire:r,release:i}}let $S=`vidtreo-audio-worklet`,eC=`audioChunk`,tC=`setMuted`,nC=`setPaused`,rC=`shutdown`,iC=`
141
141
  const AUDIO_WORKLET_MESSAGE_TYPE_AUDIO_CHUNK = "${eC}";
142
142
  const AUDIO_WORKLET_MESSAGE_TYPE_SET_MUTED = "${tC}";
143
143
  const AUDIO_WORKLET_MESSAGE_TYPE_SET_PAUSED = "${nC}";
@@ -12826,7 +12826,7 @@ Mediabunny was loaded twice.\` + " This will likely cause Mediabunny not to work
12826
12826
  initializeRecorderWorker();
12827
12827
  }
12828
12828
  })();
12829
- `],{type:`application/javascript`})}let PC=QS({createBlob:NC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function FC(){return PC.acquire()}function IC(){PC.release()}let LC=1e3,RC=`format`,zC=new Map,BC=new Map;function VC(e){return e===void 0?`undefined`:String(e)}function HC(e){return e.join(`,`)}function UC(e,t){return`${e}=${t}`}function WC(e,t,n){if(e.has(t)&&e.delete(t),e.set(t,n),e.size<=50)return;let r=e.keys().next();r.done||e.delete(r.value)}var GC=class{constructor(e={}){this.worker=null,this.hasWorkerUrlLease=!1,this.chunks=[],this.totalSize=0,this.isActive=!1,this.audioTrackClone=null,this.audioTrackWarningTarget=null,this.isMuted=!1,this.currentVideoTrack=null,this.isPaused=!1,this.overlayConfig=null,this.readyPromiseResolve=null,this.readyPromiseReject=null,this.lastConfigFps=30,this.pendingFatalError=null,this.lastRecordingStats=null,this.audioWasExpected=!1,this.lastEncoderAcceleration=null,this.audioHealthMonitor=new YS,this.audioHealthIntervalId=null,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.noFrameWatchdogId=null,this.handleAudioTrackEnded=()=>{this.audioTrackEndedDuringSession=!0,this.emitAudioWarningOnce({code:`audio.track-ended`})},this.handleAudioTrackMuted=()=>{this.emitAudioWarningOnce({code:`audio.track-muted-by-browser`})},this.handleAudioTrackUnmuted=()=>{this.emittedAudioWarnings.delete(`audio.track-muted-by-browser`)&&this.onAudioRecovered&&this.onAudioRecovered()};let t=e=>new Worker(e,{type:`classic`});e.createWorker&&(t=e.createWorker);let n=e=>typeof MediaStreamTrackProcessor>`u`?null:(dC(e,{stage:`main-thread-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable);e.createVideoStreamFromTrack&&(n=e.createVideoStreamFromTrack);let r=()=>on();e.isLinuxPlatform&&(r=e.isLinuxPlatform),this.createVideoStreamFromTrackFn=n,this.isLinuxPlatformFn=r,e.videoFramePreflightDeps?this.videoFramePreflightDeps=e.videoFramePreflightDeps:this.videoFramePreflightDeps={},e.noFrameWatchdogDelayMs===void 0?this.watchdogDelayMs=5e3:this.watchdogDelayMs=e.noFrameWatchdogDelayMs;let i=!!e.createWorker;this.workerProbeManager=new MC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new cC({onChunk:this.handleAudioWorkletChunk.bind(this)});let a=e=>{let t=e.data;switch(t.type){case`ready`:this.readyPromiseResolve&&(this.readyPromiseResolve(),this.readyPromiseResolve=null,this.readyPromiseReject=null);break;case Xy:this.workerProbeManager.handleProbeResult(t);break;case`debugLog`:t.payload?$.debug(t.message,t.payload):$.debug(t.message);break;case`error`:if($.error(`[WorkerProcessor] Worker error:`,t.error),this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(t.error));break}this.onError&&this.onError(Error(t.error));break;case`chunk`:this.chunks.push({data:t.data,position:t.position}),this.totalSize=Math.max(this.totalSize,t.position+t.data.length);break;case`bufferUpdate`:this.onBufferUpdate&&this.onBufferUpdate(t.size,t.formatted);break;case`stateChange`:$.debug(`[WorkerProcessor] State changed:`,t.state),this.isPaused=t.state===`paused`;break;case`fatalError`:if(this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(`${t.message} [${t.code}]`));break}this.pendingFatalError=t;break;case`recordingStats`:this.lastRecordingStats=t,this.handleNoFrameWatchdogStats(t);break;case`encoderAcceleration`:this.lastEncoderAcceleration=t.acceleration,$.info(`[WorkerProcessor] Encoder acceleration resolved`,{acceleration:t.acceleration});break;default:$.warn(`[WorkerProcessor] Unknown response type:`,t)}},o=e=>{if($.error(`[WorkerProcessor] Worker error event:`,{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno,error:e.error}),this.readyPromiseReject){let t=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,t(Error(e.message||`Unknown worker error`));return}if(this.onError){let t=e.message;t||=`Unknown worker error`,this.onError(Error(t))}},s=typeof Worker<`u`,c=!1;if(s&&(c=!0),i&&(c=!0),!c)throw $.error(`[WorkerProcessor] Web Workers are not supported`),Error(`Web Workers are not supported`);let l=FC();this.hasWorkerUrlLease=!0;try{this.worker=OC({createWorker:t,workerUrl:l,onMessage:a,onError:o,logger:$})}catch(e){throw this.releaseWorkerUrlLease(),e}}prewarm(){this.worker&&this.workerProbeManager.getProbeResult(this.worker).catch(()=>void 0)}getWorkerProbeResult(){let e=this.getWorkerOrThrow();return this.workerProbeManager.getProbeResult(e)}async startProcessing(e,t,n){this.getWorkerOrThrow(),this.ensureProcessingInactive(),this.resetProcessingState(n),this.stopAudioWorklet(),this.audioWorkletManager=new cC({onChunk:this.handleAudioWorkletChunk.bind(this)});let r=this.resolveRecordingFormat(t),i=Ht(r,{isLinuxPlatform:this.isLinuxPlatformFn()}),a=this.resolveAudioBitrate(t,r),o=await this.resolveAudioCodecWithCache(t,r,i,a),s=await this.resolveVideoCodecWithCache(t,r,i),c=XS(e);$.debug(`[WorkerProcessor] Starting processing`,{isScreenCapture:c,fps:t.fps,codec:s,bitrate:t.bitrate});let l=this.buildWorkerTranscodeConfig(t,o,a,s,r);typeof t.fps==`number`&&t.fps>0&&(this.lastConfigFps=t.fps);let u=e.getVideoTracks(),d=e.getAudioTracks();$.debug(`[WorkerProcessor] Preparing to start processing`,{videoTracksCount:u.length,audioTracksCount:d.length,hasWorker:!!this.worker});try{let e=this.getVideoInputSelectorDependencies(),t=vC(u,e),n=yC(d,e),r=await this.getWorkerProbeResult();t&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await mC(t,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let i=bC(t,r,e),a=SC(e),o=xC(t);wC(t,e),TC(e),CC(t,n,i.videoStream,e);let s=e.getViewportMetadata(),c;s&&(c={orientationAngle:s.orientationAngle,windowOrientation:s.windowOrientation});let{audioConfig:f,audioStream:p,shouldStartAudioWorklet:m}=await this.prepareAudioPipeline(n,r),h=this.buildOverlayConfigToSend(),g=kC({videoTrack:i.videoTrack,videoStream:i.videoStream,audioStream:p,isMobileDevice:a,videoSettings:o,viewportMetadata:c,audioConfig:f,workerConfig:l,overlayConfig:h}),_=jC(i.videoStream,p,i.videoTrack);$.debug(`[WorkerProcessor] Posting message to worker`,{transferablesCount:_.length,messageType:g.type}),await this.postStartMessage(g,_,m),this.startNoFrameWatchdog(),m&&this.startAudioHealthMonitoring()}catch(e){throw this.resetStartProcessingStateAfterFailure(),e}}getWorkerOrThrow(){if(!this.worker)throw Error(`Worker not initialized`);return this.worker}ensureProcessingInactive(){if(this.isActive)throw Error(`Processing already active`)}handleAudioWorkletChunk(e){if(!(this.isWorkerActive()&&this.worker))return;this.recordAudioHealthChunk(e);let t={type:`audioChunk`,data:e.data,frames:e.frames,numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,timestamp:e.timestamp},n=[];e.data.buffer instanceof ArrayBuffer&&n.push(e.data.buffer),this.worker.postMessage(t,n)}resetProcessingState(e){this.isActive=!0,this.isMuted=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.audioHealthMonitor.reset(),this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=performance.now(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),e?this.overlayConfig=e:this.overlayConfig=null}resetStartProcessingStateAfterFailure(){this.isActive=!1,this.isPaused=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.stopCurrentVideoTrack(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}recordAudioHealthChunk(e){let t=this.audioHealthMonitor.recordChunk({samples:e.data,timestampMs:performance.now(),isMuted:this.isMuted,inputPeak:e.inputPeak,inputRms:e.inputRms});this.emitAudioWarning(t.classification,{durationMs:Math.max(t.consecutiveSilentDurationMs,t.consecutiveLowSignalDurationMs,t.consecutiveMutedSpeechDurationMs),peak:t.inputPeak,rms:t.inputRms})}startAudioHealthMonitoring(){this.stopAudioHealthMonitoring(),this.audioHealthIntervalId=window.setInterval(()=>{if(!this.isActive)return;let e=this.audioHealthMonitor.inspect(performance.now(),this.isMuted);this.emitAudioWarning(e.classification,{durationMs:Math.max(e.noChunkDurationMs,e.consecutiveSilentDurationMs,e.consecutiveLowSignalDurationMs,e.consecutiveMutedSpeechDurationMs),peak:e.inputPeak,rms:e.inputRms})},1e3)}stopAudioHealthMonitoring(){this.audioHealthIntervalId!==null&&(window.clearInterval(this.audioHealthIntervalId),this.audioHealthIntervalId=null)}startNoFrameWatchdog(){this.stopNoFrameWatchdog(),this.noFrameWatchdogId=window.setTimeout(()=>{this.noFrameWatchdogId=null,this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`requestStats`})},this.watchdogDelayMs)}stopNoFrameWatchdog(){this.noFrameWatchdogId!==null&&(window.clearTimeout(this.noFrameWatchdogId),this.noFrameWatchdogId=null)}handleNoFrameWatchdogStats(e){if(!this.isActive||e.videoFrameCount>0)return;$.error(`[WorkerProcessor] No video frames received after watchdog delay`,{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed});let t=Error(`No video frames received after ${this.watchdogDelayMs/LC}s — video stream may be unresponsive [${fC}]`);this.onError&&this.onError(t),this.cancel()}emitAudioWarning(e,t){if(e===`healthy`){let e=this.emittedAudioWarnings.size>0;this.emittedAudioWarnings.clear(),e&&this.onAudioRecovered&&this.onAudioRecovered();return}if(e===`muted-silence-expected`){let e=!1;this.emittedAudioWarnings.delete(`audio.no-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.no-chunks`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.low-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.speaking-while-muted`)&&(e=!0),e&&this.onAudioRecovered&&this.onAudioRecovered();return}let n=this.createAudioWarning(e,t);n&&this.emitAudioWarningOnce(n)}emitAudioWarningOnce(e){this.onAudioWarning&&(this.emittedAudioWarnings.has(e.code)||(this.emittedAudioWarnings.add(e.code),this.onAudioWarning(e)))}createAudioWarning(e,t){return e===`no-chunks`?{code:`audio.no-chunks`,durationMs:t.durationMs}:e===`silent-while-unmuted`?{code:`audio.no-signal`,durationMs:t.durationMs}:e===`low-signal`?{code:`audio.low-signal`,peak:t.peak,rms:t.rms}:e===`speaking-while-muted`?{code:`audio.speaking-while-muted`,durationMs:t.durationMs,peak:t.peak,rms:t.rms}:null}assertRuntimeAudioHealth(){let e=performance.now(),t=this.recordingStartTimestampMs??e,n=Math.max(0,e-t),r=this.audioHealthMonitor.getFinalSnapshot(e,this.isMuted),i=Ab({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw Db(i.code,{totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession})}resolveRecordingFormat(e){let t=e.format;return t||=`mp4`,t}resolveAudioBitrate(e,t){return e.audioBitrate===void 0?Kt(t):e.audioBitrate}async resolveAudioCodec(e,t,n,r){return await uy({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r})}async resolveVideoCodec(e,t,n){return await ly({format:t,overrideCodec:e.codec,policy:n,width:e.width,height:e.height,bitrate:e.bitrate})}async resolveAudioCodecWithCache(e,t,n,r){let i=this.buildAudioCodecCacheKey(e,t,n,r),a=zC.get(i);if(a)return a;let o=await this.resolveAudioCodec(e,t,n,r);return WC(zC,i,o),o}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=BC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return WC(BC,r,a),a}buildAudioCodecCacheKey(e,t,n,r){let i=VC(e.audioCodec),a=VC(n.preferredAudioCodec),o=HC(n.audioCodecFallbackOrder),s=VC(r);return[UC(RC,VC(t)),UC(`audioOverride`,i),UC(`audioBitrate`,s),UC(`policyPreferredAudio`,a),UC(`policyAudioFallback`,o)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=VC(e.codec),i=VC(e.width),a=VC(e.height),o=VC(e.bitrate),s=VC(n.preferredVideoCodec),c=HC(n.videoCodecFallbackOrder);return[UC(RC,VC(t)),UC(`videoOverride`,r),UC(`width`,i),UC(`height`,a),UC(`videoBitrate`,o),UC(`policyPreferredVideo`,s),UC(`policyVideoFallback`,c)].join(`|`)}buildWorkerTranscodeConfig(e,t,n,r,i){return{width:e.width,height:e.height,fps:e.fps,bitrate:ZS(e.bitrate),audioCodec:t,audioBitrate:n,codec:r,keyFrameInterval:5,latencyMode:e.latencyMode,format:i,watermark:e.watermark}}async prepareAudioPipeline(e,t){if(!e)return $.debug(`[WorkerProcessor] Audio pipeline disabled (no track)`),{audioConfig:null,audioStream:null,shouldStartAudioWorklet:!1};let n=await this.prepareAudioConfig(e);if(!n)throw this.createBrowserUnsupportedError();return $.debug(`[WorkerProcessor] Audio pipeline selected`,{path:`audio-worklet-chunks`,sampleRate:n.sampleRate,numberOfChannels:n.numberOfChannels}),{audioConfig:n,audioStream:null,shouldStartAudioWorklet:!0}}buildOverlayConfigToSend(){if(this.overlayConfig)return this.overlayConfig}async postStartMessage(e,t,n){let r=this.getWorkerOrThrow(),i=new Promise((e,t)=>{this.readyPromiseResolve=e,this.readyPromiseReject=t});try{r.postMessage(e,t),$.debug(`[WorkerProcessor] Message posted successfully`),await i,$.debug(`[WorkerProcessor] Worker confirmed ready`),n&&(this.audioWasExpected=!0,await this.startAudioWorkletProcessing())}catch(e){throw $.error(`[WorkerProcessor] Failed to post message:`,e),this.readyPromiseResolve=null,this.readyPromiseReject=null,this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.isActive=!1,e}}pause(){this.worker&&this.isActive&&(this.worker.postMessage({type:`pause`}),this.setAudioWorkletPaused(!0))}resume(){this.isWorkerActive()&&this.worker&&(this.worker.postMessage({type:`resume`}),this.setAudioWorkletPaused(!1))}isWorkerActive(){return!!(this.worker&&this.isActive)}toggleMute(){this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted),this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`toggleMute`}),this.setAudioWorkletMuted(this.isMuted)}async switchVideoSource(e){if(!(this.isWorkerActive()&&this.worker))return $.debug(`[WorkerProcessor] Cannot switch source - worker not active`,{hasWorker:!!this.worker,isActive:this.isActive}),Promise.resolve();let t=e.getVideoTracks();if($.debug(`[WorkerProcessor] Switching video source`,{videoTracksCount:t.length}),t.length===0)return $.warn(`[WorkerProcessor] No video tracks in new stream`),Promise.resolve();let n=XS(e),r=this.lastConfigFps;$.debug(`[WorkerProcessor] Source type detected`,{isScreenCapture:n,targetFps:r});let i={type:`updateFps`,fps:r};this.worker.postMessage(i);let a={type:`updateSourceType`,isScreenCapture:n};this.worker.postMessage(a);let o=this.getVideoInputSelectorDependencies(),s=vC(t,o);if(!s)return $.warn(`[WorkerProcessor] Unable to prepare video track`),Promise.resolve();$.debug(`[WorkerProcessor] New video track details`,{trackId:s.id,trackKind:s.kind,trackReadyState:s.readyState});let c=bC(s,await this.getWorkerProbeResult(),o),l=AC(c.videoTrack,c.videoStream),u=jC(c.videoStream,null,c.videoTrack);try{return $.debug(`[WorkerProcessor] Posting switch source message`),this.worker.postMessage(l,u),$.debug(`[WorkerProcessor] Switch source message posted`),new Promise(e=>{setTimeout(()=>{e()},0)})}catch(e){throw $.error(`[WorkerProcessor] Failed to switch source:`,e),e}}finalize(){if(!this.isWorkerActive())throw Ix(Nx,`Recording is not ready to finalize`,{hasWorker:!!this.worker,isActive:this.isActive});let e=performance.now();return new Promise((t,n)=>{let r=this.worker;if(!r){n(Error(`Worker not initialized`));return}let i=null,a=()=>{i!==null&&(clearTimeout(i),i=null)},o=()=>{r.removeEventListener(`message`,l)},s=!1,c=()=>s?!1:(s=!0,a(),o(),!0),l=r=>{if(s)return;let i=r.data;if(i.type===`fatalError`){this.pendingFatalError=i;return}if(i.type===`recordingStats`){this.lastRecordingStats=i;return}if(i.type===`stateChange`&&i.state===`stopped`){this.handleFinalizeStopped(c,t,n,e);return}i.type===`error`&&this.handleFinalizeError(c,n,i.error,e)};i=setTimeout(()=>{if(!c())return;$.error(`[WorkerProcessor] Finalize timeout reached`,{elapsedSeconds:(performance.now()-e)/LC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Ix(Px,this.buildFinalizeTimeoutMessage(t),{recordingStats:this.buildRecordingStatsSummary(t)}))},3e4),r.addEventListener(`message`,l),r.postMessage({type:`requestStats`}),r.postMessage({type:`stop`})})}handleFinalizeStopped(e,t,n,r){let i=this.lastRecordingStats,a=this.lastEncoderAcceleration;if(this.pendingFatalError!==null){let t=this.pendingFatalError;if(!e())return;this.resetFinalizeRuntimeState(),n(Error(this.buildFatalFinalizeErrorMessage(t,i)));return}e()&&(this.resetFinalizeRuntimeState(),Promise.resolve().then(()=>this.createBlobFromChunks(i,a)).then(e=>{t(e)},e=>{this.rejectFinalizeBlobCreationError(n,e,r)}))}handleFinalizeError(e,t,n,r){e()&&(this.resetFinalizeRuntimeState(),$.error(`[WorkerProcessor] Finalize failed`,{elapsedSeconds:(performance.now()-r)/LC,error:n}),t(Error(n)))}buildFatalFinalizeErrorMessage(e,t){return t===null?`${e.message} [${e.code}]`:`${e.message} [${e.code}] frames=${t.videoFrameCount} errors=${t.totalFrameErrors}`}buildFinalizeTimeoutMessage(e){return e===null?`Finalize timeout`:`Finalize timeout frames=${e.videoFrameCount} errors=${e.totalFrameErrors} processed=${e.totalFramesProcessed}`}buildRecordingStatsSummary(e){return e===null?null:{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed}}resetFinalizeRuntimeState(){this.isActive=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}createBlobFromChunks(e,t){let n=[...this.chunks].sort((e,t)=>e.position-t.position),r=new ArrayBuffer(this.totalSize),i=new Uint8Array(r);for(let e of n)i.set(e.data,e.position);Uy(r),Wy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Gy(r));let a={blob:new Blob([r],{type:`video/mp4`}),totalSize:this.totalSize};return e!==null&&(a.recordingStats={totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed,videoFrameCount:e.videoFrameCount}),t!==null&&(a.encoderAcceleration=t),a}rejectFinalizeBlobCreationError(e,t,n){if($.error(`[WorkerProcessor] Finalize failed while creating blob`,{elapsedSeconds:(performance.now()-n)/LC,error:i(t)}),t instanceof Error){e(t);return}e(Error(i(t)))}cancel(){return this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,Promise.resolve()}destroy(){this.worker&&=(this.worker.terminate(),null),this.releaseWorkerUrlLease(),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0}cleanup(){this.destroy()}warmupEncoder(e){if(!this.worker)return;let t=e.format||`mp4`,n=Ht(t),r=e.codec||n.preferredVideoCodec,i=e.audioBitrate===void 0?n.audioBitrate:e.audioBitrate,a=Ht(t,{isLinuxPlatform:this.isLinuxPlatformFn()}),o=this.resolveAudioBitrate(e,t);this.resolveAudioCodecWithCache(e,t,a,o).catch(this.handleWarmupCacheError),this.resolveVideoCodecWithCache(e,t,a).catch(this.handleWarmupCacheError);let s={type:`warmup`,config:this.buildWorkerTranscodeConfig(e,n.preferredAudioCodec,i,r,t)};this.worker.postMessage(s)}getBufferSize(){return this.totalSize}getMutedState(){return this.isMuted}updateTabVisibility(e,t){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update visibility - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending visibility update to worker`,{isHidden:e,timestamp:t,timestampSeconds:t/LC});let n={type:`updateVisibility`,isHidden:e,timestamp:t};this.worker.postMessage(n)}updateSourceType(e){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update source type - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending source type update to worker`,{isScreenCapture:e});let t={type:`updateSourceType`,isScreenCapture:e};this.worker.postMessage(t)}async startAudioWorkletProcessing(){await this.audioWorkletManager.startProcessing()}stopAudioWorklet(){this.audioWorkletManager.stop()}setAudioWorkletMuted(e){this.audioWorkletManager.setMuted(e)}setAudioWorkletPaused(e){this.audioWorkletManager.setPaused(e)}prepareAudioConfig(e){return this.audioWorkletManager.prepareAudioConfig(e)}handleWarmupCacheError(){}createBrowserUnsupportedError(){return Nt({resolutionStage:`feature-preflight`})}getVideoInputSelectorDependencies(){return{stopCurrentVideoTrack:()=>this.stopCurrentVideoTrack(),cloneVideoTrack:e=>this.cloneVideoTrack(e),cloneAudioTrack:e=>this.cloneAudioTrack(e),setCurrentVideoTrack:e=>{this.currentVideoTrack=e},createVideoStreamFromTrack:e=>this.createVideoStreamFromTrackFn(e),createBrowserUnsupportedError:()=>this.createBrowserUnsupportedError(),getViewportMetadata:()=>{if(typeof window>`u`)return null;let e=window.screen,t,n,r,i;return e&&(i=e.orientation),i?.type&&(t=i.type),i&&typeof i.angle==`number`&&(n=i.angle),typeof window.orientation==`number`&&(r=window.orientation),{innerWidth:window.innerWidth,innerHeight:window.innerHeight,orientation:t,orientationAngle:n,windowOrientation:r}},logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},isMobileDevice:()=>Qt()}}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.audioTrackClone}getAudioStreamForAnalysis(){return this.audioTrackClone?new MediaStream([this.audioTrackClone]):null}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnMuteStateChange(e){this.onMuteStateChange=e}setOnAudioWarning(e){this.onAudioWarning=e}setOnAudioRecovered(e){this.onAudioRecovered=e}cloneVideoTrack(e){if($.debug(`[WorkerProcessor] Original video track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return $.debug(`[WorkerProcessor] Video track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone video track:`,e);let t=i(e);throw Error(`Failed to clone video track: ${t}`)}return $.warn(`[WorkerProcessor] Video track clone() not available, using original`),e}attachAudioTrackWarnings(e){this.detachAudioTrackWarnings(),e.addEventListener(`ended`,this.handleAudioTrackEnded),e.addEventListener(`mute`,this.handleAudioTrackMuted),e.addEventListener(`unmute`,this.handleAudioTrackUnmuted),this.audioTrackWarningTarget=e}detachAudioTrackWarnings(){this.audioTrackWarningTarget&&=(this.audioTrackWarningTarget.removeEventListener(`ended`,this.handleAudioTrackEnded),this.audioTrackWarningTarget.removeEventListener(`mute`,this.handleAudioTrackMuted),this.audioTrackWarningTarget.removeEventListener(`unmute`,this.handleAudioTrackUnmuted),null)}cloneAudioTrack(e){if($.debug(`[WorkerProcessor] Original audio track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return this.audioTrackClone=t,this.attachAudioTrackWarnings(t),$.debug(`[WorkerProcessor] Audio track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone audio track:`,e);let t=i(e);throw Error(`Failed to clone audio track: ${t}`)}return $.warn(`[WorkerProcessor] Audio track clone() not available, using original`),this.audioTrackClone=e,this.attachAudioTrackWarnings(e),e}stopCurrentVideoTrack(){this.currentVideoTrack&&this.currentVideoTrack.readyState===`live`&&this.currentVideoTrack.stop(),this.currentVideoTrack=null}releaseWorkerUrlLease(){this.hasWorkerUrlLease&&=(IC(),!1)}},KC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new GC;e.workerProcessorFactory&&(t=e.workerProcessorFactory);try{this.workerProcessor=t(),$.debug(`[StreamProcessor] Using worker-based processing`)}catch(e){let t=i(e);throw Error(`Failed to initialize worker: ${t}`)}}async startProcessing(e,t,n){this.workerProcessor.setOnBufferUpdate((e,t)=>{$.debug(`[StreamProcessor] Buffer update:`,{size:e,formatted:t}),this.onBufferUpdate&&this.onBufferUpdate(e,t)}),this.workerProcessor.setOnError(e=>{$.error(`[StreamProcessor] Worker error:`,e),this.onError&&this.onError(e)}),this.currentVideoStream=e,await this.workerProcessor.startProcessing(e,t,n)}updateTabVisibility(e,t){this.workerProcessor.updateTabVisibility(e,t)}updateSourceType(e){this.workerProcessor.updateSourceType(e)}pause(){this.workerProcessor.pause()}resume(){this.workerProcessor.resume()}isPausedState(){return this.workerProcessor.isPausedState()}async finalize(){return $.debug(`[StreamProcessor] finalize called`),await this.workerProcessor.finalize()}toggleMute(){this.workerProcessor.toggleMute()}isMutedState(){return this.workerProcessor.getMutedState()}getClonedAudioTrack(){return this.workerProcessor.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.workerProcessor.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.workerProcessor.switchVideoSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.workerProcessor.getBufferSize()}setOnMuteStateChange(e){this.workerProcessor.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnAudioWarning(e){this.workerProcessor.setOnAudioWarning(e)}setOnAudioRecovered(e){this.workerProcessor.setOnAudioRecovered(e)}warmupEncoder(e){this.workerProcessor.warmupEncoder(e)}prewarm(){this.workerProcessor.prewarm()}async cancel(){await this.workerProcessor.cancel(),this.currentVideoStream=null}destroy(){this.workerProcessor.destroy(),this.currentVideoStream=null}};let qC=1e3,JC=`recording`,YC=`idle`,XC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},ZC={transcodeVideo:_y};function QC(e,t){let n=dy(t.format);return e.type.toLowerCase().startsWith(n)}var $C=class{constructor(e,t,n){this.recordingState=YC,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingStartTime=null,this.maxTimeRemaining=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.enableTabVisibilityOverlay=!1,this.startupAborted=!1,this.activeRecordingConfig=null,this.activeRouteDecision=XC,this.streamManager=e,this.callbacks=t,this.dependencies={...ZC,...n}}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}setTabVisibilityOverlayConfig(e,t){this.enableTabVisibilityOverlay=e,this.tabVisibilityOverlayText=t}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}updateSourceType(e){this.recordingState!==JC||!this.streamProcessor||this.streamProcessor.updateSourceType(e)}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}prewarmStreamProcessor(e){let t=this.getOrCreateStreamProcessor();t.prewarm(),e&&t.warmupEncoder(e)}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=YC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/qC),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime,t=Math.max(0,Math.ceil((this.countdownDuration-e)/qC)),n=this.countdownRemaining;this.countdownRemaining=t,n!==t&&this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording().catch(()=>void 0)},this.countdownDuration)}async doStartRecording(){$.debug(`[RecordingManager] doStartRecording called`),this.cancelCountdown(),this.resetRecordingState(),this.startupAborted=!1;let e=this.streamManager.getStream();if($.debug(`[RecordingManager] Current stream:`,{hasStream:!!e,audioTracks:e?.getAudioTracks().length||0,videoTracks:e?.getVideoTracks().length||0}),!e){$.warn(`[RecordingManager] No stream available`),this.handleError(Error(`No stream available for recording`)),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}this.originalCameraStream=e,$.debug(`[RecordingManager] Ensuring stream processor`);let t=this.getOrCreateStreamProcessor();$.debug(`[RecordingManager] StreamProcessor ready:`,!!t);let n=null,r=await this.callbacks.onGetConfig().then(e=>(n=e,null)).catch(e=>e);if(r){this.handleError(r),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}this.callbacks.onAudioWarning&&t.setOnAudioWarning(this.callbacks.onAudioWarning),this.callbacks.onAudioRecovered&&t.setOnAudioRecovered(this.callbacks.onAudioRecovered),t.setOnError(e=>{this.handleFatalProcessorError(e)}),this.activeRecordingConfig=n,this.activeRouteDecision=i,$.debug(`[RecordingManager] Starting recording with stream manager`);let a=await this.streamManager.startRecording(t,n,this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText,i).then(()=>null).catch(e=>($.error(`[RecordingManager] Error starting recording:`,e),e));if(a){this.activeRecordingConfig=null,this.activeRouteDecision=XC,this.handleError(a),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=JC,this.callbacks.onStateChange(this.recordingState),this.startRecordingTimer(),this.recordingStartTime=Date.now(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeRemaining=this.maxRecordingTime,this.startMaxTimeTimer())}async stopRecording(){$.debug(`[RecordingManager] stopRecording called`);try{if(this.recordingState!==JC){let e=this.recordingState;throw this.cancelCountdown(),Ix(Mx,`Recording is not ready to stop`,{recordingState:e,hasStreamProcessor:!!this.streamProcessor})}this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking(),$.debug(`[RecordingManager] Stopping recording in stream manager`);let e=await this.streamManager.stopRecording(),t=await this.resolveFinalRecordingBlob(e.blob);$.info(`[RecordingManager] Recording stopped, blob size:`,t.size),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.callbacks.onRecordingComplete(t);let n={};return e.recordingStats!==void 0&&(n.videoFrameCount=e.recordingStats.videoFrameCount,n.totalFrameErrors=e.recordingStats.totalFrameErrors,n.totalFramesProcessed=e.recordingStats.totalFramesProcessed),e.encoderAcceleration!==void 0&&(n.encoderAcceleration=e.encoderAcceleration),e.mediaRecorderDiagnostics!==void 0&&Object.assign(n,e.mediaRecorderDiagnostics),{blob:t,telemetryProperties:n}}catch(e){let t=Lx(e);throw this.handleError(t),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.streamProcessor&&=(this.streamProcessor.destroy(),null),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=XC}}pauseRecording(){if(!(this.recordingState!==JC||this.isPaused)&&(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now(),this.maxTimeTimer!==null&&this.recordingStartTime!==null&&this.maxRecordingTime!==null)){let e=Date.now()-this.recordingStartTime-this.totalPausedTime;this.maxTimeRemaining=Math.max(0,this.maxRecordingTime-e),this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}}resumeRecording(){this.recordingState!==JC||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer(),this.maxTimeRemaining!==null&&this.maxTimeRemaining>0&&this.startMaxTimeTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=YC,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.streamProcessor&&=(this.streamProcessor.destroy(),null)}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null,this.recordingStartTime=null,this.maxTimeRemaining=null}async resolveFinalRecordingBlob(e){if(this.activeRouteDecision.route!==`safe-capture-post-recording-transcode`)return e;if(!this.activeRecordingConfig)throw Error(`Recording config unavailable for final video processing`);if(QC(e,this.activeRecordingConfig))return e;this.callbacks.onTranscodingProgress?.(0);let t=await this.dependencies.transcodeVideo(e,this.activeRecordingConfig,e=>{this.callbacks.onTranscodingProgress?.(e)});return this.callbacks.onTranscodingProgress?.(1),t.blob}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}getOrCreateStreamProcessor(){if(this.streamProcessor)return this.streamProcessor;let e=new KC;return this.streamProcessor=e,e}async resolveRouteDecision(){return this.callbacks.onGetRouteDecision?await this.callbacks.onGetRouteDecision().then(e=>e).catch(e=>e instanceof Error?e:Error(i(e))):XC}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){if(this.recordingIntervalId!==null)return;let e=Hx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Hx(this.recordingSeconds);this.callbacks.onTimerUpdate(e)},1e3)}startMaxTimeTimer(){this.maxTimeRemaining===null||this.maxTimeRemaining<=0||(this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===JC&&!this.isPaused&&await this.stopRecording()},this.maxTimeRemaining))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let t=e instanceof Error?e:Error(i(e));this.callbacks.onError(t)}handleFatalProcessorError(e){this.recordingState===JC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==JC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},ew=class{constructor(e){this.client=null,this.createTelemetryClient=e.createTelemetryClient}initialize(e,t){typeof e==`string`&&e.length>0&&typeof t==`string`&&t.length>0&&(this.client=this.createTelemetryClient(e,t))}sendEvent(e,t,n){if(!this.client)return;let r={name:e};t&&(r={...r,properties:t}),n&&(r={...r,error:n}),this.client.triggerTelemetryEvent(r)}async executeAction(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null;if(await e.action().catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;this.sendEvent(e.succeededEvent,e.properties)}async executeActionWithResult(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null,n=null;if(await e.action().then(e=>{n=e}).catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;if(n===null)throw Error(`Telemetry action failed to return result`);let r=this.resolveResultTelemetryProperties(n,e.getPropertiesFromResult),i=this.mergeTelemetryProperties(e.properties,r);return this.sendEvent(e.succeededEvent,i),n}resolveResultTelemetryProperties(e,t){if(t!==void 0)return t(e)}mergeTelemetryProperties(e,t){if(!(e===void 0&&t===void 0))return e===void 0?t:t===void 0?e:{...e,...t}}},tw=class{constructor(){this.metadataById=new Map}getMetadata(e){return this.metadataById.get(e)}setMetadata(e,t){let n=new Map(this.metadataById);n.set(e,t),this.metadataById=n}clearMetadata(e){let t=new Map(this.metadataById);t.delete(e),this.metadataById=t}};let nw=`[RecorderController]`;var rw=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new eS,this.configManager=new dn,this.storageManager=new zb,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new jS,this.uploadCallbacks=US(e),this.telemetryManager=new ew({createTelemetryClient:kS}),this.uploadMetadataManager=new tw;let t=qS(e,{stopAudioTracking:()=>this.audioLevelAnalyzer.stopTracking(),getConfig:()=>Promise.resolve(this.configManager.getConfigForRecording()),getRouteDecision:async()=>await this.resolveRecordingRouteDecision(`live-recorder`),onAudioWarning:e.recording?.onAudioWarning?t=>{this.sendAudioWarningTelemetry(t),e.recording?.onAudioWarning?.(t)}:e=>{this.sendAudioWarningTelemetry(e)},...e.recording?.onAudioRecovered&&{onAudioRecovered:e.recording.onAudioRecovered},...e.recording?.onTranscodingProgress&&{onTranscodingProgress:e.recording.onTranscodingProgress}});this.recordingManager=new $C(this.streamManager,t);let n=JS(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new _x(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${nw} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${nw} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${nw} stream error event received, calling callback`,e),this.telemetryManager.sendEvent(`stream.error`,{sourceType:this.getCurrentSourceType()},e),r.onError&&r.onError(e)})),this.audioTelemetryUnsub=this.streamManager.on(`audiotelemetry`,({event:e})=>{let t=this.getBrowserNameForTelemetry();this.telemetryManager.sendEvent(e.name,{...e.properties,browserName:t,sourceType:this.getCurrentSourceType()},e.error)})}async initialize(e){if(this.isInitialized)return;await this.validateRecorderSupport();let t=!1;typeof e.demo==`boolean`&&(t=e.demo),this.isDemo=t;let n=null;typeof e.apiKey==`string`&&e.apiKey.length>0&&(n=e.apiKey);let r=null;typeof e.backendUrl==`string`&&e.backendUrl.length>0&&(r=e.backendUrl),this.telemetryManager.initialize(n,r),await this.telemetryManager.executeAction({requestedEvent:`sdk.init.started`,succeededEvent:`sdk.init.succeeded`,failedEvent:`sdk.init.failed`,action:async()=>{await this.initializeConfig(n,r),this.applyRecordingConfig(e),await this.initializeStorage(),this.isInitialized=!0,this.scheduleRecordingWarmup()}})}async startStream(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({succeededEvent:`preview.start.succeeded`,failedEvent:`preview.start.failed`,action:async()=>{$.debug(`${nw} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${nw} startStream completed`)},properties:{sourceType:e}})}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({requestedEvent:`recording.start.requested`,succeededEvent:`recording.start.succeeded`,failedEvent:`recording.start.failed`,action:async()=>{if(this.isUploading())throw Ix(Fx,`Previous recording is still being uploaded`);await this.ensureConfigReady(),await this.streamManager.waitForAudio(),await this.recordingManager.startRecording()},properties:{sourceType:e}})}async stopRecording(){let e=this.getCurrentSourceType(),t=!0;try{return(await this.telemetryManager.executeActionWithResult({requestedEvent:`recording.stop.requested`,succeededEvent:`recording.stop.succeeded`,failedEvent:`recording.stop.failed`,action:async()=>{let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),e},properties:{sourceType:e},getPropertiesFromResult:e=>e.telemetryProperties})).blob}catch(e){throw t=this.shouldStopStreamAfterStopFailure(e),kb(e)&&this.sendAudioMissingTelemetry(e),e}finally{t&&this.streamManager.stopStream()}}shouldStopStreamAfterStopFailure(e){return e&&typeof e==`object`&&`code`in e?e.code!==Mx:!0}sendAudioMissingTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};e.details&&(t.durationMs=e.details.durationMs,t.totalChunks=e.details.totalChunks,t.nonSilentChunks=e.details.nonSilentChunks,t.mutedDurationMs=e.details.mutedDurationMs,t.silenceRatio=e.details.durationMs>0?e.details.mutedDurationMs/e.details.durationMs:0,t.hadTrackEndedWarning=e.details.hadTrackEndedWarning),this.telemetryManager.sendEvent(`recording.audio-missing`,t,e)}getTabVisibilityOverlayConfig(){return{enabled:this.enableTabVisibilityOverlay,text:this.tabVisibilityOverlayText}}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.telemetryManager.executeAction({requestedEvent:`source.switch.requested`,succeededEvent:`source.switch.succeeded`,failedEvent:`source.switch.failed`,action:async()=>{await this.sourceSwitchManager.toggleSource()},properties:{sourceType:e}})}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.streamManager.muteAudio()}unmuteAudio(){this.streamManager.unmuteAudio()}toggleMute(){this.streamManager.toggleMute()}getIsMuted(){return this.streamManager.isMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,()=>this.streamManager.isMuted()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}uploadVideo(e,t,n,r){return this.uploadCallbacks.onClearStatus(),this.isUploadInProgress=!0,this.uploadVideoAfterStatusClear(e,t,n,r).catch(e=>{throw this.isUploadInProgress=!1,e})}async uploadVideoAfterStatusClear(e,t,n,r){let i=await Cv(e),a=this.configManager.getConfigForRecording().format,o=`recording-${Date.now()}.${fy(a)}`,s=dy(a),c=this.getCurrentSourceType(),l;if(Object.keys(r).length>0&&(l=r),this.telemetryManager.sendEvent(`upload.started`,{filename:o,duration:i,sourceType:c}),!this.uploadQueueManager){await this.uploadDirectlyWithoutQueue({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,sourceType:c,userMetadata:l});return}let u=await this.uploadQueueManager.queueUpload({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,metadata:void 0,userMetadata:l});this.uploadMetadataManager.setMetadata(u,{filename:o,duration:i,sourceType:c})}async uploadDirectlyWithoutQueue(e){if(!this.uploadService){let t=Error(`Upload service not available`);throw this.uploadCallbacks.onError(t),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},t),t}try{let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:void 0,userMetadata:e.userMetadata,onProgress:this.uploadCallbacks.onProgress});this.uploadCallbacks.onSuccess(t),this.telemetryManager.sendEvent(`upload.succeeded`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType,recordingId:t.id})}catch(t){let n=t instanceof Error?t:Error(i(t));throw this.uploadCallbacks.onError(n),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},n),n}finally{this.isUploadInProgress=!1}}getStream(){return this.streamManager.getStream()}isConfigReady(){return this.configManager.isConfigReady()}ensureConfigReady(){return this.isDemo||this.configManager.isConfigReady()?Promise.resolve():this.configManager.fetchConfig().then(()=>void 0).catch(()=>void 0)}cleanup(){this.isDestroyed=!0,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),this.audioTelemetryUnsub&&=(this.audioTelemetryUnsub(),null),this.uploadQueueManager?.destroy(),this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}getUploadService(){return this.uploadService}isUploading(){return this.isUploadInProgress}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}isAudioReady(){return this.streamManager.isAudioReady()}getAudioStatus(){return this.streamManager.getAudioStatus()}sendAudioWarningTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};`durationMs`in e&&(t.durationMs=e.durationMs),`peak`in e&&(t.peak=e.peak),`rms`in e&&(t.rms=e.rms),this.telemetryManager.sendEvent(`audio.warning`,t)}getBrowserNameForTelemetry(){try{return Mt()}catch{return`unknown`}}async resolveRecordingRouteDecision(e){let t=this.configManager.getConfigForRecording(),n=this.buildCodecProbeCandidates(t),r=await Vv({codecCandidates:n}),i=$v({profile:r,targetCodecIds:n.map(e=>e.id)});return this.telemetryManager.sendEvent(`recording.route.selected`,{routeDecision:this.buildRouteTelemetryProperties(i,r,e)}),i}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}buildRouteTelemetryProperties(e,t,n){return{selectedRoute:e.route,reasonCodes:e.reasonCodes,sourceType:n,clientTranscodeDeferred:e.route===`safe-capture-post-recording-transcode`,capabilitySummary:{browserName:t.browser.normalizedName,osName:t.os.name,deviceMemory:t.resources.deviceMemory??null,hardwareConcurrency:t.resources.hardwareConcurrency??null,effectiveType:t.network.effectiveType??null,online:t.network.online??null,isSecureContext:t.features.isSecureContext,hasMediaRecorder:t.features.hasMediaRecorder,hasVideoEncoder:t.features.hasVideoEncoder,supportedCodecIds:t.codecProbeResults.filter(e=>e.supported).map(e=>e.id),supportedEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.supported===!0).map(e=>e.id),smoothEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.smooth===!0).map(e=>e.id),powerEfficientEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.powerEfficient===!0).map(e=>e.id)}}}async initializeConfig(e,t){let n=!0;e===null&&(n=!1),t===null&&(n=!1),n&&e!==null&&t!==null&&await this.configManager.initialize(e,t)}applyRecordingConfig(e){e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),e.enableTabVisibilityOverlay!==void 0&&(this.enableTabVisibilityOverlay=e.enableTabVisibilityOverlay),e.tabVisibilityOverlayText!==void 0&&(this.tabVisibilityOverlayText=e.tabVisibilityOverlayText),this.recordingManager.setTabVisibilityOverlayConfig(this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText)}async initializeStorage(){if(this.isDestroyed)return;let e=GS(this.callbacks);try{await this.storageManager.initialize(e)}catch(e){let t=e instanceof Error?e:Error(i(e)),n=i(t);this.telemetryManager.sendEvent(`storage.init.failed`,{reason:n},t),KS(this.callbacks)(n);return}if(this.isDestroyed)return;let t=this.storageManager.getWriteProbeResult();if(!t?.ok){let e=t?.reason??`Storage write probe did not complete`,n=Error(e);this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e},n),KS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new AS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.isUploadInProgress=!1,this.uploadCallbacks.onSuccess(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.succeeded`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType,recordingId:t.id}),this.uploadMetadataManager.clearMetadata(e))},onUploadError:(e,t)=>{this.isUploadInProgress=!1,this.uploadCallbacks.onError(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.failed`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType},t),this.uploadMetadataManager.clearMetadata(e))}}))}async validateRecorderSupport(){Ft();let e=await vb({requiresAudio:!1,requiresWatermark:!1});if(!e.isSupported)throw Nt({missingCapabilities:e.missing,resolutionStage:`feature-preflight`})}scheduleRecordingWarmup(){this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),!this.isDestroyed&&(this.recordingWarmupTimeoutId=setTimeout(()=>{this.recordingWarmupTimeoutId=null,!this.isDestroyed&&(this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})))},0))}ignorePromiseRejection(e){e.catch(()=>void 0)}prewarmSupportCheck(){this.ignorePromiseRejection(vb({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let iw=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,aw=/\starget=["'](?<target>[^"']+)["']/,ow=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,sw=`{version}`;function cw(e,t){return e?e.toLowerCase().includes(t):!1}function lw(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!ow.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function uw(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?pw(r.browserUnsupportedDynamic,t,n):cw(t,`safari`)?r.browserUnsupportedSafari:cw(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function dw(e,t){return e===`camera.in-use`?t.cameraInUse:e===`camera.not-found`?t.cameraNotFound:e===`camera.permission-denied`?t.cameraPermissionDenied:e===`camera.timeout`?t.cameraTimeout??t.failedToStartCamera:t.failedToStartCamera}function fw(e,t){return e===`audio.in-use`?t.audioInUse:e===`audio.not-found`?t.audioNotFound:e===`audio.permission-denied`?t.audioPermissionDenied:e===`audio.timeout`?t.audioTimeout??t.failedToStartAudio:t.failedToStartAudio}function pw(e,t,n){let r=`This browser`;t&&t.trim().length>0&&(r=t);let i=e.replace(`{browser}`,r);return n&&n.trim().length>0&&n?(i=i.replace(sw,n),i):(i=i.replace(` ({version})`,``),i=i.replace(sw,``),i)}function mw(e){let t=iw.exec(e);if(!t?.groups)return{prefix:e,linkText:null,linkHref:null,linkTarget:null,suffix:``};let n=t.index,r=n+t[0].length,i=e.slice(0,n),a=e.slice(r),o=lw(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=aw.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function hw(){let e=globalThis.navigator&&typeof globalThis.navigator.userAgent==`string`?globalThis.navigator.userAgent:``,t=new wt(e).getResult(),n=t.device.type,r=n===`mobile`||n===`tablet`;return $.debug(`Mobile detection result`,{userAgent:e,deviceType:n,isMobile:r,device:t.device,os:t.os,browser:t.browser}),r}function gw(){let e=jt(),t=null;e.name.length>0&&(t=e.name);let n=null;return e.version.length>0&&(n=e.version),{browserName:t,browserVersion:n}}function _w(e){let t=t=>{if(!(`code`in t))return;let n=t,r=typeof n.code==`string`?n.code:null;if(r===null)return;if(r!==`browser.unsupported`){(r.startsWith(`camera.`)||r.startsWith(`audio.`)||r.startsWith(`recording.`))&&e.updateState({errorCode:r,canRetry:!0,browserName:null,browserVersion:null});return}let i=gw(),a=i.browserName;n.browserName&&n.browserName.length>0&&(a=n.browserName);let o=i.browserVersion;n.browserVersion&&n.browserVersion.length>0&&(o=n.browserVersion),e.updateState({errorCode:`browser.unsupported`,canRetry:!1,browserName:a,browserVersion:o})};return{recording:{onStateChange:t=>{e.updateState({recordingState:t})},onCountdownUpdate:(t,n)=>{e.updateState({recordingState:t,countdown:n})},onTimerUpdate:t=>{e.updateState({timer:t})},onError:n=>{t(n),e.updateState({error:i(n),transcodingProgress:null,uploadProgress:null})},onRecordingComplete:t=>{e.updateState({countdown:null}),e.processRecordingBlob(t).catch(t=>{e.updateState({error:i(t),transcodingProgress:null,uploadProgress:null})})},onClearUploadStatus:()=>{e.updateState({uploadProgress:null})},onTranscodingProgress:t=>{e.updateState({transcodingProgress:t})},onAudioWarning:t=>{e.updateState({audioWarning:t}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-warning`,{detail:t}))},onAudioRecovered:()=>{e.updateState({audioWarning:null}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-recovered`))},onStopAudioTracking:()=>void 0,onGetConfig:()=>{if(!e.controller)throw Error(`Controller not initialized`);return e.isDemo?Promise.resolve(Zt(`mp4`)):e.controller.getConfig()}},sourceSwitch:{onSourceChange:e=>Promise.resolve(),onPreviewUpdate:t=>(e.updateState({stream:t}),Promise.resolve()),onError:n=>{t(n),e.updateState({error:i(n)})},onTransitionStart:t=>{e.updateState({transitionMessage:t})},onTransitionEnd:()=>{e.updateState({transitionMessage:null})}},storage:{onUploadProgress:()=>void 0,onUploadComplete:()=>void 0,onUploadError:()=>void 0},onStorageCleanupError:t=>{e.updateState({error:t})}}}function vw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function yw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function bw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function xw(e,t,n,r){return await e.stopRecording()}function Sw(e){e.pauseRecording()}function Cw(e){e.resumeRecording()}async function ww(e,t){await e.switchSource(t)}let Tw=`camera`,Ew=`screen`,Dw=`recording`,Ow=`browser.unsupported`,kw=[.8,1.2,.9];function Aw(e,t){let{uploadProgress:n,uploadingLabel:r}=e,{overlay:i,fill:a,text:o}=t;if(!i)return;if(n===null){i.style.display=`none`,jw(i.querySelector(`#finishingProgress`),!1),jw(i.querySelector(`#uploadProgress`),!1);return}i.style.display=`block`;let s=i.querySelector(`#finishingProgress`),c=i.querySelector(`#uploadProgress`),l=e.isTranscoding===!0&&s!==null;jw(s,l),jw(c,!l);let u=Math.round(n*100),d=a,f=o;if(l){let e=i.querySelector(`#finishingProgressFill`),t=i.querySelector(`#finishingProgressText`);e!==null&&(d=e),t!==null&&(f=t)}d&&(d.style.width=`${u}%`),f&&(f.textContent=`${r} ${u}%`)}function jw(e,t){e&&(e.style.display=t?`block`:`none`)}function Mw(e,t){let{transitionMessage:n}=e,{overlay:r,message:i}=t;if(r){if(!n){r.classList.remove(`vidtreo-active`);return}r.classList.add(`vidtreo-active`),i&&(i.textContent=n)}}let Nw=`none`,Pw=`flex`,Fw=`inline-flex`,Iw=`checking`,Lw=`blocked`,Rw=`ready`,zw=`vidtreo-active`,Bw=`vidtreo-permission-flow--fading`,Vw=`vidtreo-permission-flow-action--requesting`;function Hw(e){return{container:e.querySelector(`#permissionFlow`),spinner:e.querySelector(`#permissionFlowSpinner`),title:e.querySelector(`#permissionFlowTitle`),subtitle:e.querySelector(`#permissionFlowSubtitle`),actionButton:e.querySelector(`#btnAllowPermission`),buttonIcon:e.querySelector(`#permissionFlowBtnIcon`),buttonSpinner:e.querySelector(`#permissionFlowBtnSpinner`),buttonText:e.querySelector(`#permissionFlowBtnText`),recovery:e.querySelector(`#permissionFlowRecovery`),recoveryTitle:e.querySelector(`#permissionFlowRecoveryTitle`),recoveryText:e.querySelector(`#permissionFlowRecoveryText`),retryButton:e.querySelector(`#btnRetryPermission`),recoveryGuideUrl:e.querySelector(`#recoveryGuideUrl`),recoveryGuidePopoverUrl:e.querySelector(`#recoveryGuidePopoverUrl`)}}function Uw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Ww(e,t){return t.cameraTitle}function Gw(e,t){return t.cameraLabel}function Kw(e,t){return t.allowCamera}function qw(e,t,n){let r=e.step,i=!1;(r===Iw||r===`awaiting-user`||r===Lw||r===Rw)&&(i=!0);let a=r===Rw,o=r===Lw,s=r===Iw,c=Uw(e),l=Ww(c,t),u=Gw(c,t),d=Kw(c,t),f=t.recoveryInstructions;return e.recoveryData?.resetInstructions&&(f=e.recoveryData.resetInstructions),{isVisible:i,isFadingOut:n,isSpinnerOnly:a,isBlocked:o,isRequesting:s,titleText:l,subtitleText:u,actionLabel:d,requestingText:t.statusRequesting,recoveryTitleText:t.recoveryTitle,recoveryInstructionsText:f}}function Jw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=Nw}}function Yw(e,t){if(t.isVisible)e.classList.add(zw);else return e.classList.remove(zw),e.classList.remove(Bw),!1;return t.isFadingOut?e.classList.add(Bw):e.classList.remove(Bw),!0}function Xw(e,t,n){Jw(e.actionButton,n,Fw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(Vw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(Vw),e.actionButton.disabled=!1)),Jw(e.buttonIcon,n&&!t.isRequesting,Fw),Jw(e.buttonSpinner,n&&t.isRequesting,Fw),e.buttonText&&(t.isRequesting?e.buttonText.textContent=t.requestingText:e.buttonText.textContent=t.actionLabel)}function Zw(){if(globalThis.window===void 0)return`vidtreo.com`;let e=globalThis.window.location.hostname||`vidtreo.com`;return e.length>20?`${e.slice(0,20)}...`:e}function Qw(e,t){if(Jw(e.recovery,t.isBlocked,Pw),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Jw(e.recoveryText,!1,Nw),Jw(e.retryButton,!1,Nw),t.isBlocked){let t=Zw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function $w(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function eT(e,t,n){let{container:r}=t;if(!r||!Yw(r,e))return;let i=!e.isSpinnerOnly;Jw(t.spinner,e.isSpinnerOnly,Fw),Jw(t.title,i&&!e.isBlocked,Pw),Jw(t.subtitle,i&&!e.isBlocked,Pw),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Xw(t,e,i&&!e.isBlocked),Qw(t,e),$w(t,n)}function tT(e,t){e.textContent=``;let n=document.createTextNode(t.prefix);if(e.append(n),t.linkText&&t.linkHref){let n=document.createElement(`a`),r=t.linkTarget;n.href=t.linkHref,r&&(n.target=r),r===`_blank`&&(n.rel=`noopener noreferrer`),n.textContent=t.linkText,e.append(n)}let r=document.createTextNode(t.suffix);e.append(r)}function nT(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function rT(e,t){let{previewSkeleton:n,videoPreview:r}=t;n&&(e.showPreviewSkeleton?n.style.display=`block`:n.style.display=`none`),r&&(e.showVideoPreview?r.style.display=`block`:r.style.display=`none`)}function iT(e,t,n){let{videoPreview:r}=t,{onVideoLoaded:a,onError:o,startAudioAnalysis:s,stopAudioAnalysis:c}=n;if(r){if(!e){r.srcObject=null,c();return}r.srcObject=e,r.onloadeddata=()=>{a()},r.play().catch(e=>o(i(e))),s(e)}}function aT(e){return{startCameraArea:e.querySelector(`#startCameraArea`),startCameraButton:e.querySelector(`#startCameraButton`),cameraIcon:e.querySelector(`#startCameraArea .vidtreo-camera-icon`),cameraText:e.querySelector(`#startCameraArea .vidtreo-camera-text`),cameraHint:e.querySelector(`#startCameraArea .vidtreo-camera-hint`),previewSkeleton:e.querySelector(`#previewSkeleton`),previewSkeletonText:e.querySelector(`#previewSkeleton .vidtreo-skeleton-text`),videoPreview:e.querySelector(`#videoPreview`),countdownOverlay:e.querySelector(`#countdownOverlay`),countdownNumber:e.querySelector(`#countdownNumber`),recordingTimerRow:e.querySelector(`#recordingTimerRow`),recordingTimer:e.querySelector(`#recordingTimer`),recIndicatorTop:e.querySelector(`#recIndicatorTop`),audioLevelBars:e.querySelector(`#audioLevelBars`)}}function oT(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=gS({errorCode:e.errorCode,hasAudioFailed:!1,error:null}),s=o.isCameraError||o.isAudioError,c=!(o.isBrowserUnsupported||s),l=o.isBrowserUnsupported||s?`ph-fill ph-warning-circle`:`ph-fill ph-camera`,u=null,d=null;o.isBrowserUnsupported&&(u=mw(n)),o.isAudioError&&(d=i),o.isCameraError&&(d=r),c&&(d=t.initializingCamera);let f=c?t.grantPermissions:null,p=s&&!o.isPermissionDenied?a:null;return{shouldShow:!0,iconClassName:l,browserErrorContent:u,textContent:d,hintText:f,retryButtonLabel:p}}function sT(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function cT(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function lT(e,t){return{shouldShow:e,text:t.rec}}function uT(e,t){return{shouldShow:e,timer:t}}function dT(e){return{shouldShow:e}}function fT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;pT(oT(n,a,uw(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),dw(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),fw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),mT(sT(n.transitionMessage,a),t),rT(nT({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),hT(cT(n.recordingState,n.countdown,a),t),gT(lT(i,a),t),_T(uT(i,n.timer),t),vT(dT(i),t)}function pT(e,t,n){let{startCameraArea:r,startCameraButton:i,cameraIcon:a,cameraText:o,cameraHint:s}=t;if(r){if(!e.shouldShow){r.style.display=`none`;return}r.style.display=`block`,a&&(a.innerHTML=`<i class="${e.iconClassName}" style="font-size: 48px;"></i>`),o&&(e.browserErrorContent&&tT(o,e.browserErrorContent),e.textContent&&(o.textContent=e.textContent)),s&&(e.hintText?(s.textContent=e.hintText,s.style.display=`block`):s.style.display=`none`),i&&(e.retryButtonLabel?(i.textContent=e.retryButtonLabel,i.hidden=!1,i.className=`vidtreo-error-retry`,i.onclick=e=>{e.preventDefault(),e.stopPropagation(),n&&n()}):(i.hidden=!0,i.onclick=null))}}function mT(e,t){let{previewSkeleton:n,previewSkeletonText:r}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`,r&&(r.textContent=e.text))}function hT(e,t){let{countdownOverlay:n,countdownNumber:r}=t;n&&(e.shouldShow?n.classList.add(`vidtreo-active`):n.classList.remove(`vidtreo-active`),r&&e.countdown!==null&&(r.textContent=e.countdown.toString()))}function gT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function _T(e,t){let{recordingTimerRow:n,recordingTimer:r}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`,r&&(r.textContent=e.timer))}function vT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let yT=`inline-flex`;function bT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isProcessingRecording:o,isStopLocked:s,stopLockedTooltip:c,recordingState:l,buttonTranslations:u}=e,d=!!t,f=l===`idle`&&d&&!o,p=f&&!a,m=p?u.microphoneConnecting:``,h=!1;(n.showPauseButton||n.showResumeButton)&&(h=!0);let g=u.pause,_=`ph-fill ph-pause`;n.showResumeButton&&(g=u.resume,_=`ph-fill ph-play`);let v=u.mute,y=`ph-fill ph-microphone`;i&&(v=u.unmute,y=`ph-fill ph-microphone-slash`);let b=`ph-fill ph-monitor`;r!==Tw&&(b=`ph-fill ph-camera`);let x=!1;return n.showDownloadButton&&(x=!0),{showRecordingControls:d,showSettingsButton:n.showSettingsButton,showRecordButton:f,isRecordDisabled:p,recordTooltip:m,showMuteButton:n.showMuteButton,showPauseButton:h,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:x,pauseTitle:g,pauseIconClassName:_,muteTitle:v,muteIconClassName:y,switchSourceIconClassName:b,isMuted:i,isStopLocked:s,stopLockedTooltip:c,settingsTitle:u.settings,switchSourceTitle:u.switchSource,downloadTitle:u.download,buttonTranslations:u}}function xT(e){return{recordingControls:e.querySelector(`#recordingControls`),settingsButton:e.querySelector(`#btnSettings`),recordButton:e.querySelector(`#btnRecord`),muteButton:e.querySelector(`#btnMute`),muteIcon:e.querySelector(`#iconMute`),pauseButton:e.querySelector(`#btnPause`),pauseIcon:e.querySelector(`#iconPause`),stopButton:e.querySelector(`#btnStop`),switchSourceButton:e.querySelector(`#btnSwitchSource`),switchSourceIcon:e.querySelector(`#iconSwitchSource`),downloadButton:e.querySelector(`#btnDownload`)}}function ST(e,t){let{recordingControls:n,settingsButton:r,recordButton:i,muteButton:a,muteIcon:o,pauseButton:s,pauseIcon:c,stopButton:l,switchSourceButton:u,switchSourceIcon:d,downloadButton:f}=t;wT(n,e),TT(r,e),ET(i,e),DT(a,e),OT(o,e),kT(s,e),AT(c,e),jT(l,e),MT(u,e),NT(d,e),PT(f,e)}function CT(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function wT(e,t){CT(e,t.showRecordingControls,`block`)}function TT(e,t){CT(e,t.showSettingsButton,yT),e&&(e.title=t.settingsTitle)}function ET(e,t){if(CT(e,t.showRecordButton,yT),!e)return;e.disabled=t.isRecordDisabled,e.classList.toggle(`vidtreo-record-button-disabled`,t.isRecordDisabled),e.title=t.recordTooltip,e.setAttribute(`aria-disabled`,String(t.isRecordDisabled));let n=e.querySelector(`i`),r=e.querySelector(`span`);t.isRecordDisabled?(n&&(n.className=`ph-fill ph-microphone vidtreo-mic-connecting-indicator`,n.style.fontSize=`18px`),r&&(r.textContent=t.recordTooltip)):(n&&(n.className=`ph-fill ph-circle`,n.style.fontSize=`24px`),r&&(r.textContent=t.buttonTranslations?.record??`Record`))}function DT(e,t){CT(e,t.showMuteButton,yT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function OT(e,t){e&&(e.className=t.muteIconClassName)}function kT(e,t){CT(e,t.showPauseButton,yT),e&&(e.title=t.pauseTitle)}function AT(e,t){e&&(e.className=t.pauseIconClassName)}function jT(e,t){if(CT(e,t.showStopButton,yT),e){if(e.classList.toggle(`vidtreo-stop-button-locked`,t.isStopLocked),e.setAttribute(`aria-disabled`,String(t.isStopLocked)),t.isStopLocked){e.title=t.stopLockedTooltip;return}e.title=``}}function MT(e,t){CT(e,t.showSwitchSourceButton,yT),e&&(e.title=t.switchSourceTitle)}function NT(e,t){e&&(e.className=t.switchSourceIconClassName)}function PT(e,t){CT(e,t.showDownloadButton,yT),e&&(e.title=t.downloadTitle)}function FT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function IT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function LT(e){return e.toggleMute(),e.getIsMuted()}function RT(e){if(!e)return;let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`recording-${Date.now()}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}let zT={en:{initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,browserUnsupported:`This browser is not supported`,browserUnsupportedDynamic:`{browser} ({version}) is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Retry Camera`,cameraInUse:`Your camera is being used by another application. Close other apps using the camera (Zoom, Teams, Discord) and try again.`,cameraNotFound:`No camera detected. Connect a camera or check your device settings.`,cameraPermissionDenied:`Camera access was denied. Allow camera access in your browser settings and try again.`,cameraTimeout:`The camera took too long to start. Close other apps using the camera and try again.`,audioInUse:`Your microphone is being used by another application. Close other apps using the microphone (Zoom, Teams, Discord) and try again.`,audioNotFound:`No microphone detected. Connect a microphone or check your device settings.`,audioPermissionDenied:`Microphone access was denied. Allow microphone access in your browser settings and try again.`,audioTimeout:`The microphone took too long to start. Close other apps using the microphone and try again.`,failedToStartAudio:`Failed to start microphone`,audioErrorTitle:`Microphone unavailable`,audioErrorMessage:`We couldn't access your microphone. It may be in use by another app like Zoom, Teams, or Discord. Please close it and try again.`,audioErrorRetry:`Try again`,audioMissingTitle:`Recording has no audio`,audioMissingMessage:`We couldn't capture audio in this recording. Your microphone may have been disconnected or blocked by the browser. Check your microphone and record again.`,audioSilentTitle:`Recording is silent`,audioSilentMessage:`We didn't detect any sound during the recording. Make sure your microphone is working and not muted by your operating system, then record again.`,audioProcessingErrorTitle:`Audio processing error`,audioProcessingErrorMessage:`We couldn't process the audio in this recording. Please record again.`,audioMissingRetry:`Record again`,audioWarningNoSignalTitle:`No microphone signal`,audioWarningNoSignalMessage:`We're not detecting any sound. Check that your microphone is active.`,audioWarningLowSignalTitle:`Audio is very quiet`,audioWarningLowSignalMessage:`Move closer to the microphone or turn up the input volume.`,audioWarningSpeakingMutedTitle:`You're speaking while muted`,audioWarningSpeakingMutedMessage:`Unmute your microphone if you want your voice in the recording.`,audioWarningTrackEndedTitle:`Microphone disconnected`,audioWarningTrackEndedMessage:`The microphone was disconnected. Reconnect it before continuing.`,audioWarningNoChunksTitle:`No microphone input`,audioWarningNoChunksMessage:`We're not receiving audio from the microphone. Check browser permissions.`,audioWarningTrackMutedTitle:`Microphone muted by browser`,audioWarningTrackMutedMessage:`The browser muted your microphone. Check site settings.`,audioWarningDismiss:`Dismiss`,cameraErrorTitle:`Camera unavailable`,cameraErrorMessage:`We couldn't access your camera. It may be in use by another app or permissions may be denied.`,browserErrorTitle:`Browser not supported`,browserErrorMessage:`This browser is not supported. Please use Chrome for the best experience.`,recordingCodecUnsupportedTitle:`Recording format not supported`,recordingCodecUnsupportedMessage:`This device can't use the selected video format. Close other apps, update Chrome if possible, and record again.`,recordingServerTranscodeFallbackTitle:`Finalizing on device`,recordingServerTranscodeFallbackMessage:`We're finishing the video on this device before upload. Keep this tab open.`,recordingTrackEndedTitle:`Camera stopped during recording`,recordingTrackEndedMessage:`The camera feed ended before the recording finished. Check that the camera is still connected and record again.`,recordingFinalizeTimeoutTitle:`Recording took too long to finish`,recordingFinalizeTimeoutMessage:`This device may be low on memory or processing power. Close other apps or browser tabs, then record again.`,recordingStateRaceTitle:`Recording did not start correctly`,recordingStateRaceMessage:`The recording could not be finalized because it did not start cleanly. Please refresh the page and record again.`,recordingNoFramesTitle:`No video was captured`,recordingNoFramesMessage:`We couldn't receive video frames from the camera. Check your camera connection and record again.`,recordingUnsupportedTitle:`Recording not available`,recordingUnsupportedMessage:`This device or browser can't record video reliably right now. Check your connection, update Chrome if possible, or use another device.`,recordingPipelineRetry:`Record again`,genericErrorTitle:`Something went wrong`,genericErrorMessage:`An unexpected error occurred. Please try again.`,errorRetry:`Try again`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,microphoneConnecting:`Connecting microphone...`,minimumRecordingTimeNotReached:`You have not met the minimum recording time yet`,processVideo:`Process Video`,processing:`Processing...`,finishing:`Finishing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`,userInAnotherTab:`User in another tab`,download:`Download`,nativeCameraSelectVideo:`Select Video from Gallery`,nativeCameraRecordVideo:`Record with Camera`,errorTitle:`Configuration Error`,errorGeneric:`An error occurred while loading the configuration`,mobileOpenCamera:`Open Camera`,mobileOpenCameraTitle:`Record a Video`,mobileOpenCameraDescription:`Tap the button below to start recording`,mobileCloseCamera:`Close`,mobilePermissionDenied:`Camera Access Denied`,mobilePermissionDeniedDescription:`Please allow camera access in your browser settings to record video.`,permissionFlowTitle:`Set Up Your Camera`,permissionFlowCameraTitle:`Camera & Microphone`,permissionFlowMicrophoneTitle:`Camera & Microphone`,permissionFlowCameraLabel:`We need access to your camera and microphone to start recording`,permissionFlowMicrophoneLabel:`We need access to your camera and microphone to start recording`,permissionFlowStatusPending:`Pending`,permissionFlowStatusGranted:`Ready`,permissionFlowStatusDenied:`Blocked`,permissionFlowStatusRequesting:`Click "Allow" in the browser popup above`,permissionFlowAllowCamera:`Allow Access`,permissionFlowAllowMicrophone:`Allow Access`,permissionFlowRetry:`Try Again`,permissionFlowRecoveryTitle:`Allow access to continue`,permissionFlowRecoveryInstructions:`Open your browser settings and allow camera and microphone access, then try again.`,permissionFlowConnecting:`Setting up...`},es:{initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,browserUnsupported:`Este navegador no es compatible`,browserUnsupportedDynamic:`{browser} ({version}) no es compatible, por favor usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Reintentar Cámara`,cameraInUse:`Tu cámara está siendo usada por otra aplicación. Cierra otras apps que usen la cámara (Zoom, Teams, Discord) e intenta de nuevo.`,cameraNotFound:`No se detectó ninguna cámara. Conecta una cámara o revisa la configuración de tu dispositivo.`,cameraPermissionDenied:`Se denegó el acceso a la cámara. Permite el acceso a la cámara en la configuración de tu navegador e intenta de nuevo.`,cameraTimeout:`La cámara tardó demasiado en iniciar. Cierra otras apps que usen la cámara e intenta de nuevo.`,audioInUse:`Tu micrófono está siendo usado por otra aplicación. Cierra otras apps que usen el micrófono (Zoom, Teams, Discord) e intenta de nuevo.`,audioNotFound:`No se detectó ningún micrófono. Conecta un micrófono o revisa la configuración de tu dispositivo.`,audioPermissionDenied:`Se denegó el acceso al micrófono. Permite el acceso al micrófono en la configuración de tu navegador e intenta de nuevo.`,audioTimeout:`El micrófono tardó demasiado en iniciar. Cierra otras apps que usen el micrófono e intenta de nuevo.`,failedToStartAudio:`Error al iniciar el micrófono`,audioErrorTitle:`Micrófono no disponible`,audioErrorMessage:`No pudimos acceder a tu micrófono. Puede estar en uso por otra app como Zoom, Teams o Discord. Ciérrala e inténtalo de nuevo.`,audioErrorRetry:`Intentar de nuevo`,audioMissingTitle:`La grabación no tiene audio`,audioMissingMessage:`No pudimos capturar audio en esta grabación. Es posible que el micrófono se haya desconectado o que el navegador lo haya bloqueado. Verifica tu micrófono y vuelve a grabar.`,audioSilentTitle:`La grabación quedó en silencio`,audioSilentMessage:`No detectamos sonido durante la grabación. Verifica que tu micrófono esté funcionando y no esté silenciado por el sistema, luego vuelve a grabar.`,audioProcessingErrorTitle:`Error al procesar el audio`,audioProcessingErrorMessage:`No pudimos procesar el audio de esta grabación. Por favor vuelve a grabar.`,audioMissingRetry:`Grabar de nuevo`,audioWarningNoSignalTitle:`Sin señal del micrófono`,audioWarningNoSignalMessage:`No estamos detectando sonido. Verifica que tu micrófono esté activo.`,audioWarningLowSignalTitle:`Audio muy bajo`,audioWarningLowSignalMessage:`Acércate al micrófono o sube el volumen de entrada.`,audioWarningSpeakingMutedTitle:`Estás hablando muteado`,audioWarningSpeakingMutedMessage:`Activa el micrófono si quieres que tu voz se escuche en la grabación.`,audioWarningTrackEndedTitle:`Micrófono desconectado`,audioWarningTrackEndedMessage:`Se desconectó el micrófono. Reconéctalo antes de continuar.`,audioWarningNoChunksTitle:`Sin entrada del micrófono`,audioWarningNoChunksMessage:`No estamos recibiendo audio del micrófono. Revisa los permisos del navegador.`,audioWarningTrackMutedTitle:`Micrófono silenciado por el navegador`,audioWarningTrackMutedMessage:`El navegador silenció tu micrófono. Revisa la configuración del sitio.`,audioWarningDismiss:`Cerrar`,cameraErrorTitle:`Cámara no disponible`,cameraErrorMessage:`No pudimos acceder a tu cámara. Puede estar en uso por otra app o los permisos pueden estar denegados.`,browserErrorTitle:`Navegador no compatible`,browserErrorMessage:`Este navegador no es compatible. Por favor usa Chrome para la mejor experiencia.`,recordingCodecUnsupportedTitle:`Formato de grabación no compatible`,recordingCodecUnsupportedMessage:`Este dispositivo no puede usar el formato de video seleccionado. Cierra otras apps, actualiza Chrome si es posible y vuelve a grabar.`,recordingServerTranscodeFallbackTitle:`Finalizando en el dispositivo`,recordingServerTranscodeFallbackMessage:`Estamos finalizando el video en este dispositivo antes de subirlo. Mantén esta pestaña abierta.`,recordingTrackEndedTitle:`La cámara se detuvo durante la grabación`,recordingTrackEndedMessage:`La señal de la cámara terminó antes de finalizar la grabación. Verifica que la cámara siga conectada y vuelve a grabar.`,recordingFinalizeTimeoutTitle:`La grabación tardó demasiado en finalizar`,recordingFinalizeTimeoutMessage:`Es posible que este dispositivo tenga poca memoria o potencia de procesamiento. Cierra otras apps o pestañas del navegador y vuelve a grabar.`,recordingStateRaceTitle:`La grabación no inició correctamente`,recordingStateRaceMessage:`No se pudo finalizar la grabación porque no inició correctamente. Actualiza la página y vuelve a grabar.`,recordingNoFramesTitle:`No se capturó video`,recordingNoFramesMessage:`No pudimos recibir fotogramas de video de la cámara. Verifica la conexión de la cámara y vuelve a grabar.`,recordingUnsupportedTitle:`Grabación no disponible`,recordingUnsupportedMessage:`Este dispositivo o navegador no puede grabar video de forma estable ahora. Revisa tu conexión, actualiza Chrome si es posible o usa otro dispositivo.`,recordingPipelineRetry:`Grabar de nuevo`,genericErrorTitle:`Algo salió mal`,genericErrorMessage:`Ocurrió un error inesperado. Por favor intenta de nuevo.`,errorRetry:`Intentar de nuevo`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,microphoneConnecting:`Conectando micrófono...`,minimumRecordingTimeNotReached:`Aun no cumples el tiempo minimo de grabacion`,processVideo:`Procesar Video`,processing:`Procesando...`,finishing:`Finalizando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`,userInAnotherTab:`Usuario en otra pestaña`,download:`Descargar`,nativeCameraSelectVideo:`Seleccionar Video de la Galería`,nativeCameraRecordVideo:`Grabar con Cámara`,errorTitle:`Error de Configuración`,errorGeneric:`Ocurrió un error al cargar la configuración`,mobileOpenCamera:`Abrir Cámara`,mobileOpenCameraTitle:`Grabar un Video`,mobileOpenCameraDescription:`Toca el botón para comenzar a grabar`,mobileCloseCamera:`Cerrar`,mobilePermissionDenied:`Acceso a Cámara Denegado`,mobilePermissionDeniedDescription:`Por favor permite el acceso a la cámara en la configuración de tu navegador para grabar video.`,permissionFlowTitle:`Configurar tu Cámara`,permissionFlowCameraTitle:`Cámara y Micrófono`,permissionFlowMicrophoneTitle:`Cámara y Micrófono`,permissionFlowCameraLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowMicrophoneLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowStatusPending:`Pendiente`,permissionFlowStatusGranted:`Listo`,permissionFlowStatusDenied:`Bloqueado`,permissionFlowStatusRequesting:`Haz clic en "Permitir" en el aviso del navegador`,permissionFlowAllowCamera:`Permitir Acceso`,permissionFlowAllowMicrophone:`Permitir Acceso`,permissionFlowRetry:`Reintentar`,permissionFlowRecoveryTitle:`Permite el acceso para continuar`,permissionFlowRecoveryInstructions:`Abre la configuración de tu navegador y permite el acceso a la cámara y micrófono, luego intenta de nuevo.`,permissionFlowConnecting:`Preparando...`}};var BT=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(zT[this.lang]||zT.en)[e]}getAll(){return{...zT[this.lang]||zT.en,...this.customTexts}}};let VT=new Map;function HT(e){e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100vw`,e.style.height=`100vh`,e.style.height=`100dvh`,e.style.zIndex=`9999`,e.style.pointerEvents=`none`}function UT(e){e.style.pointerEvents=`auto`}function WT(e){e.style.pointerEvents=`none`}var GT=class{constructor(e=`vidtreo-portal-root`){this.portalContainer=null,this.contentWrapper=null,this.isRegistered=!1,this.containerId=e,this.instanceId=`portal-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get container(){return this.contentWrapper}get isActive(){return this.contentWrapper!==null&&this.portalContainer!==null}open(){let e=document.getElementById(this.containerId);return e||(e=document.createElement(`div`),e.id=this.containerId,HT(e),document.body.appendChild(e)),this.portalContainer=e,this.contentWrapper=document.createElement(`div`),this.contentWrapper.setAttribute(`data-portal-instance`,this.instanceId),this.contentWrapper.style.width=`100%`,this.contentWrapper.style.height=`100%`,this.portalContainer.appendChild(this.contentWrapper),this.registerInstance(),UT(e),this.contentWrapper}render(e){this.contentWrapper&&(this.contentWrapper.innerHTML=e)}querySelector(e){return this.contentWrapper?this.contentWrapper.querySelector(e):null}close(){this.contentWrapper&&=(this.contentWrapper.innerHTML=``,this.contentWrapper.remove(),null),this.unregisterInstance(),this.updatePortalContainerState()}destroy(){this.close(),this.portalContainer=null}registerInstance(){if(this.isRegistered)return;let e=VT.get(this.containerId);e||(e=new Set,VT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=VT.get(this.containerId);e&&(e.delete(this),e.size===0&&VT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=VT.get(this.containerId);e&&e.size>0?UT(this.portalContainer):(WT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},KT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new GT}get canCloseModal(){let{recordingState:e,uploadProgress:t,transcodingProgress:n}=this.callbacks.getState();return!(e===`recording`||e===`countdown`||t!==null||n!==null)}get isModalOpen(){return this.state.isModalOpen}get portal(){return this.portalManager}openModal(){this.state.isModalOpen=!0,this.state.permissionRequested=!1,this.portalManager.open(),document.body.style.overflow=`hidden`,this.setupEscapeHandler(),this.callbacks.renderMobile(),this.requestCameraPreview()}closeModal(){this.canCloseModal&&(this.callbacks.stopPreview(),this.state.isModalOpen=!1,this.state.permissionRequested=!1,document.body.style.overflow=``,this.removeEscapeHandler(),this.portalManager.close(),this.callbacks.renderMobile())}checkUploadCompletion(e){let t=this.state.prevUploading,n=e!==null;this.state.prevUploading=n,t&&!n&&this.state.isModalOpen&&this.closeModal()}requestCameraPreview(){if(this.state.permissionRequested)return;let e=()=>{this.callbacks.isInitialized()?(this.state.permissionRequested=!0,this.callbacks.startPreview().catch(()=>{})):this.initCheckInterval=setTimeout(e,100)};e()}setupEscapeHandler(){this.escapeHandler=e=>{e.key===`Escape`&&this.canCloseModal&&this.closeModal()},document.addEventListener(`keydown`,this.escapeHandler)}removeEscapeHandler(){this.escapeHandler&&=(document.removeEventListener(`keydown`,this.escapeHandler),null)}destroy(){this.removeEscapeHandler(),this.portalManager.destroy(),document.body.style.overflow=``,this.initCheckInterval&&=(clearTimeout(this.initCheckInterval),null)}},qT=class{constructor(e,t){this.state={file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1,isConfigLoading:!0,error:null,transcodedBlob:null},this.handler=null,this.config=e,this.callbacks=t;let n=e.backendUrl||`https://core.vidtreo.com`,r=null;e.apiKey&&!e.demo&&(r=un.getInstance({apiKey:e.apiKey,backendUrl:n}));let i=new jS;this.handler=new by({apiKey:e.apiKey,backendUrl:n,maxRecordingTime:e.maxRecordingTime,maxFileSize:e.maxFileSize,userMetadata:e.userMetadata},r,i),e.apiKey&&!e.demo?(this.updateState({isConfigLoading:!0}),this.handler.preloadConfig().then(()=>this.updateState({isConfigLoading:!1})).catch(()=>{this.updateState({isConfigLoading:!1,error:`Failed to load settings`})})):this.updateState({isConfigLoading:!1})}updateState(e){this.state={...this.state,...e},this.callbacks.onStateChange()}getState(){return this.state}async handleFileSelect(e){if(this.updateState({error:null}),!this.handler)throw Error(`Handler not initialized`);try{let t=await this.handler.handleFileSelection(e);return this.updateState({file:t}),t}catch(e){let t=i(e),n=e instanceof Error?e:Error(t);throw this.updateState({error:t}),this.callbacks.onError?.(n),n}}async processAndUpload(e){let t=e||this.state.file;if(!(t&&this.handler))return;let n=this.config.demo;try{if(this.updateState({isTranscoding:!0,transcodingProgress:0,error:null}),n){let e=await vy(t.file,Xt,e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)});this.updateState({transcodedBlob:e.blob,isTranscoding:!1,transcodingProgress:null})}else{let e=await this.handler.processAndUpload(e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)},e=>{this.updateState({uploadProgress:e}),this.callbacks.onUploadProgress?.(e)});this.updateState({file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1}),this.callbacks.onUploadComplete?.({recordingId:e.recordingId||``,uploadUrl:e.uploadUrl||``})}}catch(e){let t=i(e),r=e instanceof Error?e:Error(t);this.updateState({error:t,isTranscoding:!1,transcodingProgress:null,uploadProgress:null,transcodedBlob:null}),this.callbacks.onError?.(r),n||this.callbacks.onUploadError?.(r)}}downloadVideo(){if(!this.state.transcodedBlob)return;let e=URL.createObjectURL(this.state.transcodedBlob),t=document.createElement(`a`);t.href=e,t.download=`recording-${Date.now()}.mp4`,document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(e)}reset(){this.updateState({file:null,transcodingProgress:null,uploadProgress:null,error:null,isTranscoding:!1,transcodedBlob:null})}destroy(){this.handler&&this.handler.cancel(),this.handler=null}};function JT(e){return{preview:{initializingCamera:e.initializingCamera,grantPermissions:e.grantPermissions,browserUnsupported:e.browserUnsupported,browserUnsupportedDynamic:e.browserUnsupportedDynamic,browserUnsupportedSafari:e.browserUnsupportedSafari,browserUnsupportedFirefox:e.browserUnsupportedFirefox,retryCamera:e.retryCamera,cameraInUse:e.cameraInUse,cameraNotFound:e.cameraNotFound,cameraPermissionDenied:e.cameraPermissionDenied,cameraTimeout:e.cameraTimeout,failedToStartCamera:e.failedToStartCamera,audioInUse:e.audioInUse,audioNotFound:e.audioNotFound,audioPermissionDenied:e.audioPermissionDenied,audioTimeout:e.audioTimeout,failedToStartAudio:e.failedToStartAudio,switchingDevice:e.switchingDevice,recordingStartsIn:e.recordingStartsIn,rec:e.rec},buttons:{settings:e.settings,record:e.record,stop:e.stop,minimumRecordingTimeNotReached:e.minimumRecordingTimeNotReached,pause:e.pause,resume:e.resume,mute:e.mute,unmute:e.unmute,switchSource:e.switchSource,download:e.download,microphoneConnecting:e.microphoneConnecting},settings:{settings:e.settings,camera:e.camera,microphone:e.microphone}}}var YT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new jS}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},XT=`:root{--vidtreo-background:0 0% 100%;--vidtreo-foreground:0 0% 3.9%;--vidtreo-card:0 0% 100%;--vidtreo-card-foreground:0 0% 3.9%;--vidtreo-primary:0 0% 9%;--vidtreo-primary-foreground:0 0% 98%;--vidtreo-secondary:0 0% 96.1%;--vidtreo-secondary-foreground:0 0% 9%;--vidtreo-muted:0 0% 96.1%;--vidtreo-muted-foreground:0 0% 45.1%;--vidtreo-accent:0 0% 96.1%;--vidtreo-accent-foreground:0 0% 9%;--vidtreo-destructive:0 84.2% 60.2%;--vidtreo-destructive-foreground:0 0% 98%;--vidtreo-border:0 0% 89.8%;--vidtreo-input:0 0% 89.8%;--vidtreo-ring:0 0% 3.9%;--vidtreo-radius:.5rem;--vidtreo-preview-bg:0 0% 0%;--vidtreo-z-modal-overlay:9999;--vidtreo-z-settings-panel:200;--vidtreo-z-error-overlay:100;--vidtreo-z-countdown-overlay:20;--vidtreo-z-progress-overlay:20;--vidtreo-z-controls:10}.vidtreo-preview-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:layout style;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:visible;transform:translateZ(0)}.vidtreo-preview-container:before{display:none}@media (width>=768px){.vidtreo-preview-container{aspect-ratio:16/9}}.vidtreo-camera-area{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;contain:layout style paint;backface-visibility:hidden;isolation:isolate;will-change:auto;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:relative;transform:translateZ(0)}.vidtreo-source-transition-overlay{z-index:var(--vidtreo-z-error-overlay);backdrop-filter:blur(4px);contain:layout style paint;backface-visibility:hidden;will-change:opacity;background:#000000b3;border-radius:0;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-source-transition-overlay.vidtreo-active{animation:.2s vidtreo-fadeIn;display:flex}@keyframes vidtreo-fadeIn{0%{opacity:0}to{opacity:1}}.vidtreo-transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite vidtreo-spin}@keyframes vidtreo-spin{to{transform:rotate(360deg)}}.vidtreo-transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.vidtreo-camera-area.vidtreo-active{display:block}.vidtreo-preview-skeleton{z-index:var(--vidtreo-z-controls);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-skeleton-spinner{border:4px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite vidtreo-spin}.vidtreo-skeleton-text{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-video-preview{object-fit:cover;will-change:auto;backface-visibility:hidden;background:#000;border-radius:0;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-video-preview-skeleton{z-index:2;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;width:100%;height:100%;position:absolute;inset:0;overflow:hidden;transform:translateZ(0)}.vidtreo-skeleton-shimmer{background:linear-gradient(90deg, hsl(var(--vidtreo-muted)) 0%, hsl(var(--vidtreo-muted) / .5) 50%, hsl(var(--vidtreo-muted)) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite vidtreo-shimmer;position:absolute;inset:0}@keyframes vidtreo-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.vidtreo-video-preview-skeleton.vidtreo-hidden{opacity:0;pointer-events:none;transition:opacity .3s}.vidtreo-video-preview.vidtreo-screen-share{object-fit:cover}.vidtreo-video-preview.vidtreo-transitioning{opacity:.5;transform:scale(.98)}.vidtreo-countdown-overlay{z-index:var(--vidtreo-z-countdown-overlay);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000000f2;border-radius:0;justify-content:center;align-items:center;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-countdown-overlay.vidtreo-active{display:flex}.vidtreo-countdown-content{flex-direction:column;align-items:center;gap:1rem;display:flex}.vidtreo-countdown-number{color:#fff;font-size:9rem;font-weight:700;animation:.3s vidtreo-zoomIn}@keyframes vidtreo-zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.vidtreo-countdown-text{color:#fff;margin-top:1rem;font-size:.875rem;font-weight:500}.vidtreo-settings-panel{z-index:var(--vidtreo-z-settings-panel);contain:layout style paint;backface-visibility:hidden;background:#0006;border:none;border-radius:.75rem;flex-direction:column;width:90%;margin-left:-47%;padding:.625rem;display:none;overflow:hidden;transform:translateZ(0);position:absolute!important;bottom:4rem!important;left:50%!important}.vidtreo-settings-panel.vidtreo-active{display:flex}.vidtreo-settings-content{will-change:transform;backface-visibility:hidden;flex-direction:column;width:100%;display:flex;transform:translateZ(0)}.vidtreo-settings-content.vidtreo-slide-right{animation:.3s vidtreo-slideRight}.vidtreo-settings-content.vidtreo-slide-left{animation:.3s vidtreo-slideLeft}.vidtreo-settings-content.vidtreo-slide-none{will-change:auto;animation:none}@keyframes vidtreo-slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes vidtreo-slideRight{0%{opacity:0;transform:translate(-100%)}to{opacity:1;transform:translate(0)}}@keyframes vidtreo-slideLeft{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.vidtreo-settings-header{color:#fff;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.75rem;width:100%;margin-bottom:1rem;padding:0;display:flex}.vidtreo-settings-back-icon{color:#fff;flex-shrink:0}.vidtreo-settings-title{color:#fff;margin:0;font-size:.875rem;font-weight:600}.vidtreo-device-options-container{flex-direction:column;gap:.375rem;display:flex}.vidtreo-device-option-nav{cursor:pointer;color:#fff;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:1rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option-nav:hover{background:#fff3}.vidtreo-device-option-nav-content{flex-shrink:0;align-items:center;gap:.75rem;display:flex}.vidtreo-device-option-nav-label{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-device-option-nav-value{flex:1;justify-content:flex-end;align-items:center;gap:.5rem;min-width:0;display:flex}.vidtreo-device-option-nav-value-text{color:#fffc;text-overflow:ellipsis;white-space:nowrap;text-align:right;flex:1;font-size:.875rem;overflow:hidden}.vidtreo-device-option-nav-chevron{color:#fff;font-size:1.25rem;line-height:1}.vidtreo-device-list{flex-direction:column;gap:0;max-height:200px;display:flex;overflow-y:auto}.vidtreo-device-list::-webkit-scrollbar{width:4px}.vidtreo-device-list::-webkit-scrollbar-track{background:0 0}.vidtreo-device-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.vidtreo-device-list::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.vidtreo-device-option{cursor:pointer;color:#fff;text-align:left;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:.75rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option:hover{background:#fff3}.vidtreo-device-option-check-container{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:flex}.vidtreo-device-checkmark-placeholder{flex-shrink:0;width:20px;height:20px}.vidtreo-device-checkmark{color:#fff;flex-shrink:0}.vidtreo-device-option-label{color:#fff;flex:1;font-size:.875rem}.vidtreo-device-empty{color:#fff9;text-align:center;padding:1rem 0;font-size:.875rem}.vidtreo-audio-level-bars{height:1rem;z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;align-items:center;gap:.125rem;transform:translateZ(0);display:flex!important;position:absolute!important;bottom:.75rem!important;right:.75rem!important}@media (width>=768px){.vidtreo-audio-level-bars{height:1.25rem}}.vidtreo-audio-level-bar{background:#ffffff80;border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.vidtreo-recording-controls{z-index:var(--vidtreo-z-controls);contain:layout style;will-change:auto;backface-visibility:hidden;position:absolute!important;bottom:12px!important;left:50%!important;transform:translate(-50%)translateZ(0)!important}.vidtreo-recording-controls-row{will-change:auto;justify-content:center;align-items:center;gap:.5rem;display:flex;transform:translateZ(0)}.vidtreo-recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.vidtreo-recording-timer-badge{z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;right:.75rem!important}.vidtreo-recording-dot-small{background:hsl(var(--vidtreo-destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite vidtreo-pulse}.vidtreo-recording-timer-text{color:#fff;font-family:monospace;font-size:.75rem;font-weight:500}.vidtreo-control-buttons-row{will-change:auto;justify-content:center;align-items:center;gap:.375rem;height:auto;min-height:2rem;display:flex;transform:translateZ(0)}@media (width>=768px){.vidtreo-control-buttons-row{min-height:2.25rem}}.vidtreo-control-button{cursor:pointer;color:#fff;box-sizing:border-box;vertical-align:top;contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;width:2rem;height:2rem;min-height:2rem;max-height:2rem;margin:0;padding:.25rem;transition:background-color .2s;display:inline-flex;position:relative;transform:translateZ(0)}.vidtreo-control-button:before{content:"";z-index:0;border-radius:9999px;transition:background-color .2s;position:absolute;inset:.25rem}.vidtreo-control-button svg{color:inherit;z-index:1;flex-shrink:0;position:relative;width:22px!important;height:22px!important}@media (width>=768px){.vidtreo-control-button svg{width:24px!important;height:24px!important}.vidtreo-control-button{width:2.25rem;height:2.25rem;min-height:2.25rem;max-height:2.25rem}}.vidtreo-control-button:hover:not(:disabled):before{background:#fff3}.vidtreo-control-button:disabled{opacity:.5;cursor:not-allowed}.vidtreo-control-button.vidtreo-muted:before{background:#0000004d}.vidtreo-control-button.vidtreo-muted:hover:not(:disabled):before{background:#fff3}.vidtreo-record-button{background:hsl(var(--vidtreo-destructive));height:2rem;min-height:2rem;max-height:2rem;color:hsl(var(--vidtreo-destructive-foreground));box-sizing:border-box;vertical-align:top;cursor:pointer;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;width:auto;margin:0;padding:0 .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:background-color .2s,filter .2s;display:inline-flex}@media (width>=768px){.vidtreo-record-button{height:2.25rem;min-height:2.25rem;max-height:2.25rem;font-size:.875rem}}.vidtreo-record-button:hover:not(:disabled){filter:brightness(.85)}.vidtreo-record-button.vidtreo-stop-button-locked{opacity:.5;cursor:not-allowed;filter:none}.vidtreo-record-button.vidtreo-stop-button-locked:hover{filter:none}#startButton.vidtreo-record-button{animation:2s ease-in-out infinite vidtreo-record-glow-pulse}@keyframes vidtreo-record-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ef444466,0 0 16px 4px #ef444433}50%{box-shadow:0 0 16px 4px #ef444499,0 0 32px 8px #ef44444d}}#startButton.vidtreo-record-button:hover:not(:disabled){animation-play-state:paused;box-shadow:0 0 20px 6px #ef4444b3,0 0 40px 10px #ef444459}.vidtreo-rec-indicator-top{contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;left:.75rem!important}.vidtreo-rec-indicator-top span{color:#fff;font-size:.75rem;font-weight:500}.vidtreo-start-camera-area{text-align:center;cursor:pointer;z-index:1;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border:none;border-radius:0;flex-direction:column;justify-content:center;align-items:center;padding:40px;transition:all .3s;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-start-camera-area:hover:not(.vidtreo-loading){background:#000}.vidtreo-start-camera-area.vidtreo-loading{cursor:wait;opacity:.7}.vidtreo-start-camera-area.vidtreo-loading .vidtreo-camera-text{color:#fff;opacity:.7}.vidtreo-camera-icon{color:#fff;justify-content:center;margin-bottom:16px;font-size:48px;display:flex}.vidtreo-camera-text{color:#fff;margin-bottom:8px;font-weight:600}.vidtreo-camera-text a{color:#3b82f6;text-decoration:underline}.vidtreo-camera-text a:hover{color:#2563eb}.vidtreo-camera-hint{color:#fff;opacity:.8;font-size:12px}@keyframes vidtreo-pulse{0%,to{opacity:1}50%{opacity:.3}}.vidtreo-progress{margin-top:20px;display:none}.vidtreo-progress.vidtreo-active{display:block}.vidtreo-progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.vidtreo-progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:#fff;font-size:14px}.vidtreo-error{color:#fff;text-align:center;z-index:var(--vidtreo-z-error-overlay);word-wrap:break-word;background:#dc2626;border:none;border-radius:.5rem;max-width:90%;padding:1rem 1.25rem;font-size:.875rem;font-weight:500;display:none;position:absolute;top:.75rem;left:50%;transform:translate(-50%);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.vidtreo-error.vidtreo-active{animation:.3s ease-out vidtreo-error-fade-in-slide-down;display:block}@keyframes vidtreo-error-fade-in-slide-down{0%{opacity:0;transform:translate(-50%)translateY(-1rem)}to{opacity:1;transform:translate(-50%)translateY(0)}}.vidtreo-upload-progress{margin-top:20px;display:none}.vidtreo-upload-progress.vidtreo-active{display:block}.vidtreo-preview-container .vidtreo-upload-progress{margin-top:0}.vidtreo-upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.vidtreo-upload-status.vidtreo-active{display:block}.vidtreo-upload-status.vidtreo-success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.vidtreo-upload-status.vidtreo-error{color:#c33;background:#fee;border:2px solid #fcc}.vidtreo-upload-status-text{font-size:14px;font-weight:500}.vidtreo-preview-error{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:strict;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden;transform:translateZ(0)}@media (width>=768px){.vidtreo-preview-error{aspect-ratio:16/9}}.vidtreo-error-content{text-align:center;color:#fff;flex-direction:column;justify-content:center;align-items:center;gap:1rem;max-width:400px;padding:2rem;display:flex}.vidtreo-error-icon{font-size:3rem;line-height:1}.vidtreo-error-title{font-size:1.25rem;font-weight:600;line-height:1.2}.vidtreo-error-message{opacity:.9;word-break:break-word;font-size:.875rem;line-height:1.5}.vidtreo-error-config{text-align:left;border-top:1px solid #fff3;width:100%;margin-top:1.5rem;padding-top:1.5rem}.vidtreo-error-config-title{color:#fff;margin-bottom:.75rem;font-size:.875rem;font-weight:600}.vidtreo-error-config-item{color:#ffffffd9;margin-bottom:.5rem;font-size:.8125rem;line-height:1.6}.vidtreo-error-config-item code{color:#fff;background:#ffffff26;border-radius:.25rem;padding:.125rem .375rem;font-family:monospace;font-size:.75rem}.vidtreo-error-retry{background:hsl(var(--vidtreo-destructive));color:hsl(var(--vidtreo-destructive-foreground));cursor:pointer;border:none;border-radius:.375rem;margin-top:.5rem;padding:.5rem 1rem;font-size:.875rem;font-weight:500;transition:filter .2s}.vidtreo-error-retry:hover:not(:disabled){filter:brightness(.85)}.vidtreo-error-retry:disabled{opacity:.5;cursor:not-allowed}.vidtreo-error-overlay{background:hsl(var(--vidtreo-preview-bg));z-index:var(--vidtreo-z-error-overlay);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-native-camera-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.vidtreo-native-camera-container{aspect-ratio:16/9}}.vidtreo-native-camera-container:has(.vidtreo-native-camera-preview-container){background:0 0}.vidtreo-config-loading-indicator{z-index:var(--vidtreo-z-controls);position:absolute;top:8px;right:8px}.vidtreo-spinner-small{border:2px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin}.vidtreo-native-camera-empty-state{flex-direction:column;justify-content:center;align-items:center;gap:16px;width:100%;height:100%;padding:24px;display:flex;position:relative}.vidtreo-native-camera-buttons{flex-direction:column;gap:12px;width:100%;max-width:300px;display:flex}.vidtreo-native-camera-process-button,.vidtreo-native-camera-download-button{z-index:30;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}.vidtreo-native-camera-process-button .vidtreo-btn,.vidtreo-native-camera-download-button .vidtreo-btn{min-width:200px}.vidtreo-btn{border-radius:var(--vidtreo-radius);cursor:pointer;border:none;padding:12px 24px;font-size:1rem;font-weight:500;transition:all .2s}.vidtreo-btn:disabled{opacity:.5;cursor:not-allowed}.vidtreo-btn-primary{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground))}.vidtreo-btn-primary:hover:not(:disabled){filter:brightness(.9)}.vidtreo-btn-secondary{background:hsl(var(--vidtreo-secondary));color:hsl(var(--vidtreo-secondary-foreground));border:1px solid hsl(var(--vidtreo-border))}.vidtreo-btn-secondary:hover:not(:disabled){background:hsl(var(--vidtreo-accent))}.vidtreo-transcoding-progress{width:100%;max-width:400px;padding:16px}.vidtreo-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-fill{background:hsl(var(--vidtreo-primary));height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:hsl(var(--vidtreo-foreground));margin-top:8px;font-size:.875rem}.vidtreo-native-camera-preview-container{background:0 0;justify-content:center;align-items:center;width:100%;height:100%;display:flex;position:relative}.vidtreo-native-camera-preview-image{object-fit:contain;width:100%;height:100%;display:block}.vidtreo-progress-overlay{backdrop-filter:blur(4px);width:100%;height:100%;z-index:var(--vidtreo-z-progress-overlay);pointer-events:auto;background:#000000b3;flex-direction:column;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-progress-overlay .vidtreo-transcoding-progress,.vidtreo-progress-overlay .vidtreo-upload-progress{pointer-events:auto;background:0 0;flex-direction:column;align-items:center;gap:12px;width:90%;max-width:400px;padding:0;display:flex;position:relative}.vidtreo-progress-overlay .vidtreo-progress-bar,.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-text,.vidtreo-progress-overlay .vidtreo-upload-progress-text{text-align:center;color:#fff;margin-top:0;font-size:.875rem;font-weight:500}.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-upload-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-indeterminate{background:linear-gradient(90deg,#0000 0%,#fff 50%,#0000 100%) 0 0/200% 100%;width:100%;animation:1.5s ease-in-out infinite vidtreo-progress-indeterminate}@keyframes vidtreo-progress-indeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}.vidtreo-mobile-web-recorder{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif}.vidtreo-camera-area button,.vidtreo-camera-area input,.vidtreo-camera-area select,.vidtreo-camera-area textarea,.vidtreo-mobile-web-recorder button,.vidtreo-mobile-web-recorder input,.vidtreo-mobile-web-recorder select,.vidtreo-mobile-web-recorder textarea,.vidtreo-permission-flow button{font-family:inherit}.vidtreo-mobile-landing-container{aspect-ratio:4/3;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;min-height:100%;max-height:100%;display:flex;position:relative;overflow:hidden}.vidtreo-mobile-landing-content{text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;padding:2rem;display:flex}.vidtreo-mobile-landing-title{color:#fff;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-mobile-landing-description{color:#ffffffbf;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-mobile-open-camera-btn{border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}@keyframes vidtreo-btn-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ffffff4d,0 0 16px 4px #ffffff26}50%{box-shadow:0 0 16px 4px #ffffff80,0 0 32px 8px #ffffff40}}.vidtreo-mobile-open-camera-btn:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-mobile-open-camera-btn:active:not(:disabled){transform:scale(.98)}.vidtreo-mobile-open-camera-btn:disabled{box-shadow:none;animation:none}#vidtreo-portal-root{z-index:9999;pointer-events:none;width:100vw;height:100dvh;position:fixed;top:0;left:0}#vidtreo-portal-root>*{pointer-events:auto}.vidtreo-mobile-modal-overlay{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;width:100vw;height:100dvh;z-index:var(--vidtreo-z-modal-overlay);background:#000;flex-direction:column;height:-webkit-fill-available;animation:.3s ease-out vidtreo-modal-fade-in;display:flex;position:fixed;inset:0}@keyframes vidtreo-modal-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-mobile-modal-header{padding:.75rem;padding-top:calc(.75rem + var(--vidtreo-safe-top,0px));z-index:var(--vidtreo-z-error-overlay);pointer-events:none;justify-content:center;display:flex;position:absolute;top:0;left:0;right:0}.vidtreo-mobile-modal-close-btn{color:#ffffffe6;cursor:pointer;pointer-events:auto;backdrop-filter:blur(4px);background:#00000080;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.375rem;height:2rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}.vidtreo-mobile-modal-close-btn:hover:not(:disabled){background:#000000b3}.vidtreo-mobile-modal-close-btn:disabled{opacity:.3;cursor:not-allowed}.vidtreo-mobile-modal-content{width:100%;height:100%;padding-top:var(--vidtreo-safe-top,0px);padding-bottom:var(--vidtreo-safe-bottom,0px);padding-left:var(--vidtreo-safe-left,0px);padding-right:var(--vidtreo-safe-right,0px);flex-direction:column;flex:1;display:flex;position:relative}.vidtreo-mobile-recorder-content{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;flex-direction:column;width:100%;height:100%;display:flex;position:relative}.vidtreo-mobile-recorder-content .vidtreo-preview-container{aspect-ratio:unset;flex:1;width:100%;height:100%}.vidtreo-mobile-recorder-content .vidtreo-video-preview{object-fit:cover}.vidtreo-mobile-preview{flex:1;aspect-ratio:unset!important;height:100%!important}.vidtreo-mobile-recorder-content .vidtreo-recording-controls{bottom:calc(24px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-audio-level-bars{bottom:calc(12px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-settings-panel{bottom:calc(7rem + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-rec-indicator-top,.vidtreo-mobile-recorder-content .vidtreo-recording-timer-badge{contain:layout style;height:2rem;padding:0 .75rem;top:calc(.75rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-recording-timer-text{white-space:nowrap;color:#fff;min-width:3rem;font-size:.875rem;display:inline-block}.vidtreo-mobile-recorder-content .vidtreo-error{top:calc(3.5rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-control-buttons-row{gap:.75rem;min-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button{width:4rem;height:4rem;min-height:4rem;max-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button svg{width:1.5rem;height:1.5rem}.vidtreo-mobile-recorder-content .vidtreo-record-button{gap:.5rem;height:4rem;min-height:4rem;max-height:4rem;padding:0 1.5rem;font-size:1rem}.vidtreo-mobile-recorder-content .vidtreo-record-button svg{width:1.5rem;height:1.5rem}.vidtreo-permission-flow{z-index:var(--vidtreo-z-modal-overlay);contain:layout style paint;backface-visibility:hidden;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#000;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-permission-flow.vidtreo-active{animation:.4s cubic-bezier(.2,0,0,1) vidtreo-fadeIn;display:flex}.vidtreo-permission-flow-title{color:#fff;text-align:center;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-permission-flow-subtitle{color:#ffffffbf;text-align:center;letter-spacing:-.005em;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-permission-flow-action{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-action:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-action:active:not(:disabled){transform:scale(.98)}.vidtreo-permission-flow-action:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;animation:none}.vidtreo-permission-flow-action--requesting{opacity:.55;cursor:wait;box-shadow:none;animation:none}@keyframes vidtreo-spinner-rotate{to{transform:rotate(360deg)}}.vidtreo-permission-flow-spinner{border:2px solid #ffffff4d;border-top-color:hsl(var(--vidtreo-primary-foreground));border-radius:50%;flex-shrink:0;width:1.125rem;height:1.125rem;animation:.8s linear infinite vidtreo-spinner-rotate;display:inline-block}.vidtreo-permission-flow-spinner--large{border-width:3px;width:2.5rem;height:2.5rem}.vidtreo-permission-flow-recovery{text-align:center;flex-direction:column;align-items:center;gap:1.25rem;max-width:280px;display:flex}.vidtreo-permission-flow-recovery-text{color:#fff6;letter-spacing:-.005em;margin:0;font-size:.75rem;line-height:1.6}.vidtreo-permission-flow-retry{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-retry:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-retry:active:not(:disabled){transform:scale(.98)}@keyframes vidtreo-fadeOut{0%{opacity:1}to{opacity:0}}.vidtreo-permission-flow.vidtreo-permission-flow--fading{pointer-events:none;animation:.6s ease-out forwards vidtreo-fadeOut}.vidtreo-recovery-guide{width:100%;max-width:280px;margin:0 auto;position:relative}.vidtreo-recovery-guide:after{content:"";z-index:20;pointer-events:none;background:linear-gradient(#0000 0%,#000 100%);height:60px;position:absolute;bottom:0;left:0;right:0}.vidtreo-recovery-guide:before{content:"";z-index:20;pointer-events:none;background:linear-gradient(90deg,#0000 0%,#000 100%);width:50px;position:absolute;top:0;bottom:0;right:0}.vidtreo-recovery-guide-browser{background:#161616;border-top:1px solid #ffffff1a;border-left:1px solid #ffffff1a;border-radius:10px 0 0;animation:.5s vidtreo-fadeIn;position:relative;overflow:hidden}.vidtreo-recovery-guide-titlebar{z-index:3;background:#1e1e1e;border-bottom:1px solid #ffffff0f;align-items:center;gap:8px;padding:8px 10px;display:flex;position:relative}.vidtreo-recovery-guide-dots{flex-shrink:0;gap:5px;display:flex}.vidtreo-recovery-guide-dot{border-radius:50%;width:8px;height:8px}.vidtreo-recovery-guide-dot--close{background:#ff5f57}.vidtreo-recovery-guide-dot--min{background:#febc2e}.vidtreo-recovery-guide-dot--max{background:#28c840}.vidtreo-recovery-guide-addressbar{background:#2a2a2a;border-radius:5px;flex:1;align-items:center;gap:5px;min-width:0;padding:4px 8px;display:flex}.vidtreo-recovery-guide-lock{color:#ffffff80;flex-shrink:0;align-items:center;animation:7s ease-in-out infinite vidtreo-lock-pulse;display:flex}.vidtreo-recovery-guide-lock-svg{display:block}.vidtreo-recovery-guide-url{color:#ffffff80;white-space:nowrap;text-overflow:ellipsis;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;overflow:hidden}.vidtreo-recovery-guide-cursor{z-index:40;pointer-events:none;filter:drop-shadow(0 2px 4px #0009);animation:7s ease-in-out infinite vidtreo-cursor-move;position:absolute;top:12px;left:62px}.vidtreo-recovery-guide-cursor-svg{display:block}.vidtreo-recovery-guide-browser-bg{background:#161616;height:110px}.vidtreo-recovery-guide-popover{z-index:30;background:#252525;border:1px solid #ffffff1a;border-radius:10px;padding:8px 12px 12px;animation:7s ease-in-out infinite vidtreo-popover-reveal;position:absolute;top:34px;left:12px;right:12px;box-shadow:0 8px 30px #0009,0 2px 8px #0006,0 0 0 1px #ffffff0f}.vidtreo-recovery-guide-popover-header{color:#ffffffd9;white-space:nowrap;text-overflow:ellipsis;text-align:left;padding-bottom:6px;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;font-weight:600;overflow:hidden}.vidtreo-recovery-guide-popover-divider{background:#ffffff14;height:1px}.vidtreo-recovery-guide-perm-row{justify-content:space-between;align-items:center;padding:7px 0;display:flex}.vidtreo-recovery-guide-perm-row+.vidtreo-recovery-guide-perm-row{border-top:1px solid #ffffff0f}.vidtreo-recovery-guide-perm-group{align-items:center;gap:8px;display:flex}.vidtreo-recovery-guide-perm-icon{flex-shrink:0;width:14px;height:14px;position:relative}.vidtreo-recovery-guide-icon-off,.vidtreo-recovery-guide-icon-on{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-recovery-guide-icon-off{color:#fff6;animation:7s ease-in-out infinite vidtreo-icon-hide}.vidtreo-recovery-guide-icon-on{color:#34d399;animation:7s ease-in-out infinite vidtreo-icon-show}.vidtreo-recovery-guide-perm-label{color:#ffffffd9;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.7rem}.vidtreo-recovery-guide-switch{flex-shrink:0;width:32px;height:18px;position:relative}.vidtreo-recovery-guide-switch-track{background:#ffffff26;border-radius:9px;animation:7s ease-in-out infinite vidtreo-track-on;position:absolute;inset:0}.vidtreo-recovery-guide-switch-knob{background:#fff;border-radius:50%;width:14px;height:14px;animation:7s ease-in-out infinite vidtreo-knob-slide;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0000004d}.vidtreo-recovery-guide-switch--delayed{animation-delay:.85s}@keyframes vidtreo-cursor-move{0%{opacity:0;transform:translate(100px,12px)}8%{opacity:1}22%{transform:translate(0)}26%{transform:translate(0)scale(.75)}30%{opacity:1;transform:translate(0)scale(1)}33%{opacity:1;transform:translate(0)}38%{opacity:1;transform:translate(65px,63px)}42%{transform:translate(65px,63px)scale(.75)}45%{opacity:1;transform:translate(65px,63px)scale(1)}48%{opacity:1;transform:translate(65px,97px)}52%{transform:translate(65px,97px)scale(.75)}55%{opacity:1;transform:translate(65px,97px)scale(1)}60%{opacity:0}to{opacity:0;transform:translate(100px,12px)}}@keyframes vidtreo-popover-reveal{0%,27%{opacity:0;transform:translateY(-6px)scale(.96)}33%,82%{opacity:1;transform:translateY(0)scale(1)}88%,to{opacity:0;transform:translateY(-6px)scale(.96)}}@keyframes vidtreo-track-on{0%,34%{background:#ffffff26}40%,92%{background:#34d399}96%,to{background:#ffffff26}}@keyframes vidtreo-knob-slide{0%,34%{transform:translate(0)}40%,92%{transform:translate(14px)}96%,to{transform:translate(0)}}@keyframes vidtreo-icon-hide{0%,34%{opacity:1}40%,92%{opacity:0}96%,to{opacity:1}}@keyframes vidtreo-icon-show{0%,34%{opacity:0}40%,92%{opacity:1}96%,to{opacity:0}}@keyframes vidtreo-lock-pulse{0%,15%{color:#ffffff80}22%,30%{color:#34d399}38%,to{color:#ffffff80}}.vidtreo-record-button.vidtreo-record-button-disabled,.vidtreo-record-button-disabled{opacity:.6;cursor:not-allowed;pointer-events:none;filter:grayscale(.3)}.vidtreo-mic-connecting-indicator{justify-content:center;align-items:center;animation:1.4s ease-in-out infinite vidtreo-mic-pulse;display:inline-flex}@keyframes vidtreo-mic-pulse{0%,to{opacity:.4}50%{opacity:1}}.vidtreo-audio-error-overlay{z-index:var(--vidtreo-z-error-overlay);text-align:center;background:#000000d9;flex-direction:column;justify-content:center;align-items:center;padding:2rem 1.5rem;animation:.3s ease-out vidtreo-audio-overlay-fade-in;display:flex;position:absolute;inset:0}@supports (backdrop-filter:blur(8px)){.vidtreo-audio-error-overlay{-webkit-backdrop-filter:blur(8px);background:#000000bf}}@keyframes vidtreo-audio-overlay-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-audio-error-icon{background:#ef444426;border-radius:50%;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:1rem;display:flex}.vidtreo-audio-error-icon svg{color:#ef4444;width:28px;height:28px}.vidtreo-audio-error-title{color:#fff;margin:0 0 .5rem;font-size:1.125rem;font-weight:600;line-height:1.4}.vidtreo-audio-error-message{color:#ffffffb3;max-width:320px;margin:0 0 1.5rem;font-size:.875rem;line-height:1.6}.vidtreo-audio-error-retry{color:#111;cursor:pointer;background:#fff;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.75rem 1.5rem;font-family:inherit;font-size:.875rem;font-weight:600;transition:background .15s,transform .1s;display:inline-flex}.vidtreo-audio-error-retry:hover{background:#f0f0f0}.vidtreo-audio-error-retry:active{transform:scale(.97)}.vidtreo-audio-error-retry svg{width:16px;height:16px}.vidtreo-audio-warning-toast{z-index:var(--vidtreo-z-error-overlay);color:#ffffffeb;pointer-events:auto;background:#1111118c;border:1px solid #ffffff14;border-radius:12px;align-items:flex-start;gap:.625rem;max-width:min(420px,100% - 2rem);padding:.625rem .875rem;font-family:inherit;animation:.2s ease-out vidtreo-audio-warning-toast-fade-in;display:flex;position:absolute;top:1rem;left:50%;transform:translate(-50%);box-shadow:0 4px 16px #00000040}@supports (backdrop-filter:blur(10px)){.vidtreo-audio-warning-toast{-webkit-backdrop-filter:blur(10px)saturate(140%);background:#11111173}}.vidtreo-audio-warning-toast--critical{border-color:#ef444473}.vidtreo-audio-warning-toast--critical .vidtreo-audio-warning-toast__icon{color:#ef4444}.vidtreo-audio-warning-toast--soft{border-color:#f59e0b73}.vidtreo-audio-warning-toast--soft .vidtreo-audio-warning-toast__icon{color:#f59e0b}.vidtreo-audio-warning-toast__icon{flex:none;justify-content:center;align-items:center;width:20px;height:20px;margin-top:1px;display:inline-flex}.vidtreo-audio-warning-toast__content{flex-direction:column;flex:auto;gap:2px;min-width:0;display:flex}.vidtreo-audio-warning-toast__title{color:#fff;font-size:.8125rem;font-weight:600;line-height:1.3}.vidtreo-audio-warning-toast__message{color:#ffffffb8;font-size:.75rem;font-weight:400;line-height:1.4}.vidtreo-audio-warning-toast__dismiss{color:#ffffffa6;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;justify-content:center;align-items:center;width:22px;height:22px;margin-left:.25rem;padding:0;font-family:inherit;transition:background .15s,color .15s;display:inline-flex}.vidtreo-audio-warning-toast__dismiss:hover{color:#fffffff2;background:#ffffff1a}@keyframes vidtreo-audio-warning-toast-fade-in{0%{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%)}}`;function ZT(e){return`
12829
+ `],{type:`application/javascript`})}let PC=QS({createBlob:NC,createObjectUrl:e=>URL.createObjectURL(e),revokeObjectUrl:e=>{URL.revokeObjectURL(e)}});function FC(){return PC.acquire()}function IC(){PC.release()}let LC=1e3,RC=`format`,zC=new Map,BC=new Map;function VC(e){return e===void 0?`undefined`:String(e)}function HC(e){return e.join(`,`)}function UC(e,t){return`${e}=${t}`}function WC(e,t,n){if(e.has(t)&&e.delete(t),e.set(t,n),e.size<=50)return;let r=e.keys().next();r.done||e.delete(r.value)}var GC=class{constructor(e={}){this.worker=null,this.hasWorkerUrlLease=!1,this.chunks=[],this.totalSize=0,this.isActive=!1,this.audioTrackClone=null,this.audioTrackWarningTarget=null,this.isMuted=!1,this.currentVideoTrack=null,this.isPaused=!1,this.overlayConfig=null,this.readyPromiseResolve=null,this.readyPromiseReject=null,this.lastConfigFps=30,this.pendingFatalError=null,this.lastRecordingStats=null,this.audioWasExpected=!1,this.lastEncoderAcceleration=null,this.audioHealthMonitor=new YS,this.audioHealthIntervalId=null,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.noFrameWatchdogId=null,this.handleAudioTrackEnded=()=>{this.audioTrackEndedDuringSession=!0,this.emitAudioWarningOnce({code:`audio.track-ended`})},this.handleAudioTrackMuted=()=>{this.emitAudioWarningOnce({code:`audio.track-muted-by-browser`})},this.handleAudioTrackUnmuted=()=>{this.emittedAudioWarnings.delete(`audio.track-muted-by-browser`)&&this.onAudioRecovered&&this.onAudioRecovered()};let t=e=>new Worker(e,{type:`classic`});e.createWorker&&(t=e.createWorker);let n=e=>typeof MediaStreamTrackProcessor>`u`?null:(dC(e,{stage:`main-thread-stream-create`}),new MediaStreamTrackProcessor({track:e}).readable);e.createVideoStreamFromTrack&&(n=e.createVideoStreamFromTrack);let r=()=>on();e.isLinuxPlatform&&(r=e.isLinuxPlatform),this.createVideoStreamFromTrackFn=n,this.isLinuxPlatformFn=r,e.videoFramePreflightDeps?this.videoFramePreflightDeps=e.videoFramePreflightDeps:this.videoFramePreflightDeps={},e.noFrameWatchdogDelayMs===void 0?this.watchdogDelayMs=5e3:this.watchdogDelayMs=e.noFrameWatchdogDelayMs;let i=!!e.createWorker;this.workerProbeManager=new MC({setTimeout:window.setTimeout.bind(window),clearTimeout:window.clearTimeout.bind(window),timeoutMilliseconds:2e3}),this.audioWorkletManager=new cC({onChunk:this.handleAudioWorkletChunk.bind(this)});let a=e=>{let t=e.data;switch(t.type){case`ready`:this.readyPromiseResolve&&(this.readyPromiseResolve(),this.readyPromiseResolve=null,this.readyPromiseReject=null);break;case Xy:this.workerProbeManager.handleProbeResult(t);break;case`debugLog`:t.payload?$.debug(t.message,t.payload):$.debug(t.message);break;case`error`:if($.error(`[WorkerProcessor] Worker error:`,t.error),this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(t.error));break}this.onError&&this.onError(Error(t.error));break;case`chunk`:this.chunks.push({data:t.data,position:t.position}),this.totalSize=Math.max(this.totalSize,t.position+t.data.length);break;case`bufferUpdate`:this.onBufferUpdate&&this.onBufferUpdate(t.size,t.formatted);break;case`stateChange`:$.debug(`[WorkerProcessor] State changed:`,t.state),this.isPaused=t.state===`paused`;break;case`fatalError`:if(this.readyPromiseReject){let e=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,e(Error(`${t.message} [${t.code}]`));break}this.pendingFatalError=t;break;case`recordingStats`:this.lastRecordingStats=t,this.handleNoFrameWatchdogStats(t);break;case`encoderAcceleration`:this.lastEncoderAcceleration=t.acceleration,$.info(`[WorkerProcessor] Encoder acceleration resolved`,{acceleration:t.acceleration});break;default:$.warn(`[WorkerProcessor] Unknown response type:`,t)}},o=e=>{if($.error(`[WorkerProcessor] Worker error event:`,{message:e.message,filename:e.filename,lineno:e.lineno,colno:e.colno,error:e.error}),this.readyPromiseReject){let t=this.readyPromiseReject;this.readyPromiseReject=null,this.readyPromiseResolve=null,t(Error(e.message||`Unknown worker error`));return}if(this.onError){let t=e.message;t||=`Unknown worker error`,this.onError(Error(t))}},s=typeof Worker<`u`,c=!1;if(s&&(c=!0),i&&(c=!0),!c)throw $.error(`[WorkerProcessor] Web Workers are not supported`),Error(`Web Workers are not supported`);let l=FC();this.hasWorkerUrlLease=!0;try{this.worker=OC({createWorker:t,workerUrl:l,onMessage:a,onError:o,logger:$})}catch(e){throw this.releaseWorkerUrlLease(),e}}prewarm(){this.worker&&this.workerProbeManager.getProbeResult(this.worker).catch(()=>void 0)}getWorkerProbeResult(){let e=this.getWorkerOrThrow();return this.workerProbeManager.getProbeResult(e)}async startProcessing(e,t,n){this.getWorkerOrThrow(),this.ensureProcessingInactive(),this.resetProcessingState(n),this.stopAudioWorklet(),this.audioWorkletManager=new cC({onChunk:this.handleAudioWorkletChunk.bind(this)});let r=this.resolveRecordingFormat(t),i=Ht(r,{isLinuxPlatform:this.isLinuxPlatformFn()}),a=this.resolveAudioBitrate(t,r),o=await this.resolveVideoCodecWithCache(t,r,i),s=XS(e);$.debug(`[WorkerProcessor] Starting processing`,{isScreenCapture:s,fps:t.fps,codec:o,bitrate:t.bitrate}),typeof t.fps==`number`&&t.fps>0&&(this.lastConfigFps=t.fps);let c=e.getVideoTracks(),l=e.getAudioTracks();$.debug(`[WorkerProcessor] Preparing to start processing`,{videoTracksCount:c.length,audioTracksCount:l.length,hasWorker:!!this.worker});try{let e=this.getVideoInputSelectorDependencies(),n=vC(c,e),s=yC(l,e),u=await this.getWorkerProbeResult();n&&($.debug(`[WorkerProcessor] Running video first-frame preflight`),await mC(n,3e3,this.videoFramePreflightDeps),$.debug(`[WorkerProcessor] Video first-frame preflight passed`));let d=bC(n,u,e),f=SC(e),p=xC(n);wC(n,e),TC(e),CC(n,s,d.videoStream,e);let m=e.getViewportMetadata(),h;m&&(h={orientationAngle:m.orientationAngle,windowOrientation:m.windowOrientation});let{audioConfig:g,audioStream:_,shouldStartAudioWorklet:v}=await this.prepareAudioPipeline(s,u),y=await this.resolveAudioCodecWithCache(t,r,i,a,g),b=this.buildWorkerTranscodeConfig(t,y,a,o,r),x=this.buildOverlayConfigToSend(),S=kC({videoTrack:d.videoTrack,videoStream:d.videoStream,audioStream:_,isMobileDevice:f,videoSettings:p,viewportMetadata:h,audioConfig:g,workerConfig:b,overlayConfig:x}),C=jC(d.videoStream,_,d.videoTrack);$.debug(`[WorkerProcessor] Posting message to worker`,{transferablesCount:C.length,messageType:S.type}),await this.postStartMessage(S,C,v),this.startNoFrameWatchdog(),v&&this.startAudioHealthMonitoring()}catch(e){throw this.resetStartProcessingStateAfterFailure(),e}}getWorkerOrThrow(){if(!this.worker)throw Error(`Worker not initialized`);return this.worker}ensureProcessingInactive(){if(this.isActive)throw Error(`Processing already active`)}handleAudioWorkletChunk(e){if(!(this.isWorkerActive()&&this.worker))return;this.recordAudioHealthChunk(e);let t={type:`audioChunk`,data:e.data,frames:e.frames,numberOfChannels:e.numberOfChannels,sampleRate:e.sampleRate,timestamp:e.timestamp},n=[];e.data.buffer instanceof ArrayBuffer&&n.push(e.data.buffer),this.worker.postMessage(t,n)}resetProcessingState(e){this.isActive=!0,this.isMuted=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.audioHealthMonitor.reset(),this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=performance.now(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),e?this.overlayConfig=e:this.overlayConfig=null}resetStartProcessingStateAfterFailure(){this.isActive=!1,this.isPaused=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.stopCurrentVideoTrack(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}recordAudioHealthChunk(e){let t=this.audioHealthMonitor.recordChunk({samples:e.data,timestampMs:performance.now(),isMuted:this.isMuted,inputPeak:e.inputPeak,inputRms:e.inputRms});this.emitAudioWarning(t.classification,{durationMs:Math.max(t.consecutiveSilentDurationMs,t.consecutiveLowSignalDurationMs,t.consecutiveMutedSpeechDurationMs),peak:t.inputPeak,rms:t.inputRms})}startAudioHealthMonitoring(){this.stopAudioHealthMonitoring(),this.audioHealthIntervalId=window.setInterval(()=>{if(!this.isActive)return;let e=this.audioHealthMonitor.inspect(performance.now(),this.isMuted);this.emitAudioWarning(e.classification,{durationMs:Math.max(e.noChunkDurationMs,e.consecutiveSilentDurationMs,e.consecutiveLowSignalDurationMs,e.consecutiveMutedSpeechDurationMs),peak:e.inputPeak,rms:e.inputRms})},1e3)}stopAudioHealthMonitoring(){this.audioHealthIntervalId!==null&&(window.clearInterval(this.audioHealthIntervalId),this.audioHealthIntervalId=null)}startNoFrameWatchdog(){this.stopNoFrameWatchdog(),this.noFrameWatchdogId=window.setTimeout(()=>{this.noFrameWatchdogId=null,this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`requestStats`})},this.watchdogDelayMs)}stopNoFrameWatchdog(){this.noFrameWatchdogId!==null&&(window.clearTimeout(this.noFrameWatchdogId),this.noFrameWatchdogId=null)}handleNoFrameWatchdogStats(e){if(!this.isActive||e.videoFrameCount>0)return;$.error(`[WorkerProcessor] No video frames received after watchdog delay`,{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed});let t=Error(`No video frames received after ${this.watchdogDelayMs/LC}s — video stream may be unresponsive [${fC}]`);this.onError&&this.onError(t),this.cancel()}emitAudioWarning(e,t){if(e===`healthy`){let e=this.emittedAudioWarnings.size>0;this.emittedAudioWarnings.clear(),e&&this.onAudioRecovered&&this.onAudioRecovered();return}if(e===`muted-silence-expected`){let e=!1;this.emittedAudioWarnings.delete(`audio.no-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.no-chunks`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.low-signal`)&&(e=!0),this.emittedAudioWarnings.delete(`audio.speaking-while-muted`)&&(e=!0),e&&this.onAudioRecovered&&this.onAudioRecovered();return}let n=this.createAudioWarning(e,t);n&&this.emitAudioWarningOnce(n)}emitAudioWarningOnce(e){this.onAudioWarning&&(this.emittedAudioWarnings.has(e.code)||(this.emittedAudioWarnings.add(e.code),this.onAudioWarning(e)))}createAudioWarning(e,t){return e===`no-chunks`?{code:`audio.no-chunks`,durationMs:t.durationMs}:e===`silent-while-unmuted`?{code:`audio.no-signal`,durationMs:t.durationMs}:e===`low-signal`?{code:`audio.low-signal`,peak:t.peak,rms:t.rms}:e===`speaking-while-muted`?{code:`audio.speaking-while-muted`,durationMs:t.durationMs,peak:t.peak,rms:t.rms}:null}assertRuntimeAudioHealth(){let e=performance.now(),t=this.recordingStartTimestampMs??e,n=Math.max(0,e-t),r=this.audioHealthMonitor.getFinalSnapshot(e,this.isMuted),i=Ab({totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession});if(!i.ok)throw Db(i.code,{totalChunks:r.totalChunks,nonSilentChunks:r.nonSilentChunks,mutedDurationMs:r.mutedDurationMs,durationMs:n,hadTrackEndedWarning:this.audioTrackEndedDuringSession})}resolveRecordingFormat(e){let t=e.format;return t||=`mp4`,t}resolveAudioBitrate(e,t){return e.audioBitrate===void 0?Kt(t):e.audioBitrate}async resolveAudioCodec(e,t,n,r,i){return await uy({format:t,overrideCodec:e.audioCodec,policy:n,bitrate:r,numberOfChannels:i?.numberOfChannels,sampleRate:i?.sampleRate})}async resolveVideoCodec(e,t,n){return await ly({format:t,overrideCodec:e.codec,policy:n,width:e.width,height:e.height,bitrate:e.bitrate})}async resolveAudioCodecWithCache(e,t,n,r,i){let a=this.buildAudioCodecCacheKey(e,t,n,r,i),o=zC.get(a);if(o)return o;let s=await this.resolveAudioCodec(e,t,n,r,i);return WC(zC,a,s),s}async resolveVideoCodecWithCache(e,t,n){let r=this.buildVideoCodecCacheKey(e,t,n),i=BC.get(r);if(i)return i;let a=await this.resolveVideoCodec(e,t,n);return WC(BC,r,a),a}buildAudioCodecCacheKey(e,t,n,r,i){let a=VC(e.audioCodec),o=VC(n.preferredAudioCodec),s=HC(n.audioCodecFallbackOrder),c=VC(r),l=VC(i?.numberOfChannels),u=VC(i?.sampleRate);return[UC(RC,VC(t)),UC(`audioOverride`,a),UC(`audioBitrate`,c),UC(`audioChannels`,l),UC(`audioSampleRate`,u),UC(`policyPreferredAudio`,o),UC(`policyAudioFallback`,s)].join(`|`)}buildVideoCodecCacheKey(e,t,n){let r=VC(e.codec),i=VC(e.width),a=VC(e.height),o=VC(e.bitrate),s=VC(n.preferredVideoCodec),c=HC(n.videoCodecFallbackOrder);return[UC(RC,VC(t)),UC(`videoOverride`,r),UC(`width`,i),UC(`height`,a),UC(`videoBitrate`,o),UC(`policyPreferredVideo`,s),UC(`policyVideoFallback`,c)].join(`|`)}buildWorkerTranscodeConfig(e,t,n,r,i){return{width:e.width,height:e.height,fps:e.fps,bitrate:ZS(e.bitrate),audioCodec:t,audioBitrate:n,codec:r,keyFrameInterval:5,latencyMode:e.latencyMode,format:i,watermark:e.watermark}}async prepareAudioPipeline(e,t){if(!e)return $.debug(`[WorkerProcessor] Audio pipeline disabled (no track)`),{audioConfig:null,audioStream:null,shouldStartAudioWorklet:!1};let n=await this.prepareAudioConfig(e);if(!n)throw this.createBrowserUnsupportedError();return $.debug(`[WorkerProcessor] Audio pipeline selected`,{path:`audio-worklet-chunks`,sampleRate:n.sampleRate,numberOfChannels:n.numberOfChannels}),{audioConfig:n,audioStream:null,shouldStartAudioWorklet:!0}}buildOverlayConfigToSend(){if(this.overlayConfig)return this.overlayConfig}async postStartMessage(e,t,n){let r=this.getWorkerOrThrow(),i=new Promise((e,t)=>{this.readyPromiseResolve=e,this.readyPromiseReject=t});try{r.postMessage(e,t),$.debug(`[WorkerProcessor] Message posted successfully`),await i,$.debug(`[WorkerProcessor] Worker confirmed ready`),n&&(this.audioWasExpected=!0,await this.startAudioWorkletProcessing())}catch(e){throw $.error(`[WorkerProcessor] Failed to post message:`,e),this.readyPromiseResolve=null,this.readyPromiseReject=null,this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.isActive=!1,e}}pause(){this.worker&&this.isActive&&(this.worker.postMessage({type:`pause`}),this.setAudioWorkletPaused(!0))}resume(){this.isWorkerActive()&&this.worker&&(this.worker.postMessage({type:`resume`}),this.setAudioWorkletPaused(!1))}isWorkerActive(){return!!(this.worker&&this.isActive)}toggleMute(){this.isMuted=!this.isMuted,this.onMuteStateChange&&this.onMuteStateChange(this.isMuted),this.isWorkerActive()&&this.worker&&this.worker.postMessage({type:`toggleMute`}),this.setAudioWorkletMuted(this.isMuted)}async switchVideoSource(e){if(!(this.isWorkerActive()&&this.worker))return $.debug(`[WorkerProcessor] Cannot switch source - worker not active`,{hasWorker:!!this.worker,isActive:this.isActive}),Promise.resolve();let t=e.getVideoTracks();if($.debug(`[WorkerProcessor] Switching video source`,{videoTracksCount:t.length}),t.length===0)return $.warn(`[WorkerProcessor] No video tracks in new stream`),Promise.resolve();let n=XS(e),r=this.lastConfigFps;$.debug(`[WorkerProcessor] Source type detected`,{isScreenCapture:n,targetFps:r});let i={type:`updateFps`,fps:r};this.worker.postMessage(i);let a={type:`updateSourceType`,isScreenCapture:n};this.worker.postMessage(a);let o=this.getVideoInputSelectorDependencies(),s=vC(t,o);if(!s)return $.warn(`[WorkerProcessor] Unable to prepare video track`),Promise.resolve();$.debug(`[WorkerProcessor] New video track details`,{trackId:s.id,trackKind:s.kind,trackReadyState:s.readyState});let c=bC(s,await this.getWorkerProbeResult(),o),l=AC(c.videoTrack,c.videoStream),u=jC(c.videoStream,null,c.videoTrack);try{return $.debug(`[WorkerProcessor] Posting switch source message`),this.worker.postMessage(l,u),$.debug(`[WorkerProcessor] Switch source message posted`),new Promise(e=>{setTimeout(()=>{e()},0)})}catch(e){throw $.error(`[WorkerProcessor] Failed to switch source:`,e),e}}finalize(){if(!this.isWorkerActive())throw Ix(Nx,`Recording is not ready to finalize`,{hasWorker:!!this.worker,isActive:this.isActive});let e=performance.now();return new Promise((t,n)=>{let r=this.worker;if(!r){n(Error(`Worker not initialized`));return}let i=null,a=()=>{i!==null&&(clearTimeout(i),i=null)},o=()=>{r.removeEventListener(`message`,l)},s=!1,c=()=>s?!1:(s=!0,a(),o(),!0),l=r=>{if(s)return;let i=r.data;if(i.type===`fatalError`){this.pendingFatalError=i;return}if(i.type===`recordingStats`){this.lastRecordingStats=i;return}if(i.type===`stateChange`&&i.state===`stopped`){this.handleFinalizeStopped(c,t,n,e);return}i.type===`error`&&this.handleFinalizeError(c,n,i.error,e)};i=setTimeout(()=>{if(!c())return;$.error(`[WorkerProcessor] Finalize timeout reached`,{elapsedSeconds:(performance.now()-e)/LC,recordingStats:this.buildRecordingStatsSummary(this.lastRecordingStats)});let t=this.lastRecordingStats;this.resetFinalizeRuntimeState(),n(Ix(Px,this.buildFinalizeTimeoutMessage(t),{recordingStats:this.buildRecordingStatsSummary(t)}))},3e4),r.addEventListener(`message`,l),r.postMessage({type:`requestStats`}),r.postMessage({type:`stop`})})}handleFinalizeStopped(e,t,n,r){let i=this.lastRecordingStats,a=this.lastEncoderAcceleration;if(this.pendingFatalError!==null){let t=this.pendingFatalError;if(!e())return;this.resetFinalizeRuntimeState(),n(Error(this.buildFatalFinalizeErrorMessage(t,i)));return}e()&&(this.resetFinalizeRuntimeState(),Promise.resolve().then(()=>this.createBlobFromChunks(i,a)).then(e=>{t(e)},e=>{this.rejectFinalizeBlobCreationError(n,e,r)}))}handleFinalizeError(e,t,n,r){e()&&(this.resetFinalizeRuntimeState(),$.error(`[WorkerProcessor] Finalize failed`,{elapsedSeconds:(performance.now()-r)/LC,error:n}),t(Error(n)))}buildFatalFinalizeErrorMessage(e,t){return t===null?`${e.message} [${e.code}]`:`${e.message} [${e.code}] frames=${t.videoFrameCount} errors=${t.totalFrameErrors}`}buildFinalizeTimeoutMessage(e){return e===null?`Finalize timeout`:`Finalize timeout frames=${e.videoFrameCount} errors=${e.totalFrameErrors} processed=${e.totalFramesProcessed}`}buildRecordingStatsSummary(e){return e===null?null:{videoFrameCount:e.videoFrameCount,totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed}}resetFinalizeRuntimeState(){this.isActive=!1,this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null}createBlobFromChunks(e,t){let n=[...this.chunks].sort((e,t)=>e.position-t.position),r=new ArrayBuffer(this.totalSize),i=new Uint8Array(r);for(let e of n)i.set(e.data,e.position);Uy(r),Wy(r),this.audioWasExpected&&(this.assertRuntimeAudioHealth(),Gy(r));let a={blob:new Blob([r],{type:`video/mp4`}),totalSize:this.totalSize};return e!==null&&(a.recordingStats={totalFrameErrors:e.totalFrameErrors,totalFramesProcessed:e.totalFramesProcessed,videoFrameCount:e.videoFrameCount}),t!==null&&(a.encoderAcceleration=t),a}rejectFinalizeBlobCreationError(e,t,n){if($.error(`[WorkerProcessor] Finalize failed while creating blob`,{elapsedSeconds:(performance.now()-n)/LC,error:i(t)}),t instanceof Error){e(t);return}e(Error(i(t)))}cancel(){return this.worker&&this.isActive&&this.worker.postMessage({type:`stop`}),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0,this.audioWasExpected=!1,this.emittedAudioWarnings=new Set,this.audioTrackEndedDuringSession=!1,this.recordingStartTimestampMs=null,this.pendingFatalError=null,this.lastRecordingStats=null,this.lastEncoderAcceleration=null,Promise.resolve()}destroy(){this.worker&&=(this.worker.terminate(),null),this.releaseWorkerUrlLease(),this.stopAudioHealthMonitoring(),this.stopNoFrameWatchdog(),this.stopAudioWorklet(),this.detachAudioTrackWarnings(),this.isActive=!1,this.isPaused=!1,this.chunks=[],this.totalSize=0}cleanup(){this.destroy()}warmupEncoder(e){if(!this.worker)return;let t=e.format||`mp4`,n=Ht(t),r=e.codec||n.preferredVideoCodec,i=e.audioBitrate===void 0?n.audioBitrate:e.audioBitrate,a=Ht(t,{isLinuxPlatform:this.isLinuxPlatformFn()}),o=this.resolveAudioBitrate(e,t);this.resolveAudioCodecWithCache(e,t,a,o,null).catch(this.handleWarmupCacheError),this.resolveVideoCodecWithCache(e,t,a).catch(this.handleWarmupCacheError);let s={type:`warmup`,config:this.buildWorkerTranscodeConfig(e,n.preferredAudioCodec,i,r,t)};this.worker.postMessage(s)}getBufferSize(){return this.totalSize}getMutedState(){return this.isMuted}updateTabVisibility(e,t){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update visibility - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending visibility update to worker`,{isHidden:e,timestamp:t,timestampSeconds:t/LC});let n={type:`updateVisibility`,isHidden:e,timestamp:t};this.worker.postMessage(n)}updateSourceType(e){if(!(this.isWorkerActive()&&this.worker)){$.warn(`[WorkerProcessor] Cannot update source type - worker not active`,{isActive:this.isActive,hasWorker:!!this.worker});return}$.debug(`[WorkerProcessor] Sending source type update to worker`,{isScreenCapture:e});let t={type:`updateSourceType`,isScreenCapture:e};this.worker.postMessage(t)}async startAudioWorkletProcessing(){await this.audioWorkletManager.startProcessing()}stopAudioWorklet(){this.audioWorkletManager.stop()}setAudioWorkletMuted(e){this.audioWorkletManager.setMuted(e)}setAudioWorkletPaused(e){this.audioWorkletManager.setPaused(e)}prepareAudioConfig(e){return this.audioWorkletManager.prepareAudioConfig(e)}handleWarmupCacheError(){}createBrowserUnsupportedError(){return Nt({resolutionStage:`feature-preflight`})}getVideoInputSelectorDependencies(){return{stopCurrentVideoTrack:()=>this.stopCurrentVideoTrack(),cloneVideoTrack:e=>this.cloneVideoTrack(e),cloneAudioTrack:e=>this.cloneAudioTrack(e),setCurrentVideoTrack:e=>{this.currentVideoTrack=e},createVideoStreamFromTrack:e=>this.createVideoStreamFromTrackFn(e),createBrowserUnsupportedError:()=>this.createBrowserUnsupportedError(),getViewportMetadata:()=>{if(typeof window>`u`)return null;let e=window.screen,t,n,r,i;return e&&(i=e.orientation),i?.type&&(t=i.type),i&&typeof i.angle==`number`&&(n=i.angle),typeof window.orientation==`number`&&(r=window.orientation),{innerWidth:window.innerWidth,innerHeight:window.innerHeight,orientation:t,orientationAngle:n,windowOrientation:r}},logger:{debug:(e,t)=>$.debug(e,t),warn:(e,t)=>$.warn(e,t)},isMobileDevice:()=>Qt()}}isPausedState(){return this.isPaused}getClonedAudioTrack(){return this.audioTrackClone}getAudioStreamForAnalysis(){return this.audioTrackClone?new MediaStream([this.audioTrackClone]):null}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnMuteStateChange(e){this.onMuteStateChange=e}setOnAudioWarning(e){this.onAudioWarning=e}setOnAudioRecovered(e){this.onAudioRecovered=e}cloneVideoTrack(e){if($.debug(`[WorkerProcessor] Original video track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return $.debug(`[WorkerProcessor] Video track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone video track:`,e);let t=i(e);throw Error(`Failed to clone video track: ${t}`)}return $.warn(`[WorkerProcessor] Video track clone() not available, using original`),e}attachAudioTrackWarnings(e){this.detachAudioTrackWarnings(),e.addEventListener(`ended`,this.handleAudioTrackEnded),e.addEventListener(`mute`,this.handleAudioTrackMuted),e.addEventListener(`unmute`,this.handleAudioTrackUnmuted),this.audioTrackWarningTarget=e}detachAudioTrackWarnings(){this.audioTrackWarningTarget&&=(this.audioTrackWarningTarget.removeEventListener(`ended`,this.handleAudioTrackEnded),this.audioTrackWarningTarget.removeEventListener(`mute`,this.handleAudioTrackMuted),this.audioTrackWarningTarget.removeEventListener(`unmute`,this.handleAudioTrackUnmuted),null)}cloneAudioTrack(e){if($.debug(`[WorkerProcessor] Original audio track:`,{id:e.id,kind:e.kind,readyState:e.readyState,hasClone:typeof e.clone==`function`}),typeof e.clone==`function`)try{let t=e.clone();return this.audioTrackClone=t,this.attachAudioTrackWarnings(t),$.debug(`[WorkerProcessor] Audio track cloned successfully:`,{id:t.id,kind:t.kind,readyState:t.readyState}),t}catch(e){$.error(`[WorkerProcessor] Failed to clone audio track:`,e);let t=i(e);throw Error(`Failed to clone audio track: ${t}`)}return $.warn(`[WorkerProcessor] Audio track clone() not available, using original`),this.audioTrackClone=e,this.attachAudioTrackWarnings(e),e}stopCurrentVideoTrack(){this.currentVideoTrack&&this.currentVideoTrack.readyState===`live`&&this.currentVideoTrack.stop(),this.currentVideoTrack=null}releaseWorkerUrlLease(){this.hasWorkerUrlLease&&=(IC(),!1)}},KC=class{constructor(e={}){this.currentVideoStream=null;let t=()=>new GC;e.workerProcessorFactory&&(t=e.workerProcessorFactory);try{this.workerProcessor=t(),$.debug(`[StreamProcessor] Using worker-based processing`)}catch(e){let t=i(e);throw Error(`Failed to initialize worker: ${t}`)}}async startProcessing(e,t,n){this.workerProcessor.setOnBufferUpdate((e,t)=>{$.debug(`[StreamProcessor] Buffer update:`,{size:e,formatted:t}),this.onBufferUpdate&&this.onBufferUpdate(e,t)}),this.workerProcessor.setOnError(e=>{$.error(`[StreamProcessor] Worker error:`,e),this.onError&&this.onError(e)}),this.currentVideoStream=e,await this.workerProcessor.startProcessing(e,t,n)}updateTabVisibility(e,t){this.workerProcessor.updateTabVisibility(e,t)}updateSourceType(e){this.workerProcessor.updateSourceType(e)}pause(){this.workerProcessor.pause()}resume(){this.workerProcessor.resume()}isPausedState(){return this.workerProcessor.isPausedState()}async finalize(){return $.debug(`[StreamProcessor] finalize called`),await this.workerProcessor.finalize()}toggleMute(){this.workerProcessor.toggleMute()}isMutedState(){return this.workerProcessor.getMutedState()}getClonedAudioTrack(){return this.workerProcessor.getClonedAudioTrack()}getAudioStreamForAnalysis(){return this.workerProcessor.getAudioStreamForAnalysis()}async switchVideoSource(e){await this.workerProcessor.switchVideoSource(e),this.currentVideoStream=e,this.onSourceChange&&this.onSourceChange(e)}getCurrentVideoSource(){return this.currentVideoStream}getBufferSize(){return this.workerProcessor.getBufferSize()}setOnMuteStateChange(e){this.workerProcessor.setOnMuteStateChange(e)}setOnSourceChange(e){this.onSourceChange=e}setOnBufferUpdate(e){this.onBufferUpdate=e}setOnError(e){this.onError=e}setOnAudioWarning(e){this.workerProcessor.setOnAudioWarning(e)}setOnAudioRecovered(e){this.workerProcessor.setOnAudioRecovered(e)}warmupEncoder(e){this.workerProcessor.warmupEncoder(e)}prewarm(){this.workerProcessor.prewarm()}async cancel(){await this.workerProcessor.cancel(),this.currentVideoStream=null}destroy(){this.workerProcessor.destroy(),this.currentVideoStream=null}};let qC=1e3,JC=`recording`,YC=`idle`,XC={route:`local-webcodecs`,reasonCodes:[`webcodecs-supported`,`target-codec-supported`]},ZC={transcodeVideo:_y};function QC(e,t){let n=dy(t.format);return e.type.toLowerCase().startsWith(n)}var $C=class{constructor(e,t,n){this.recordingState=YC,this.countdownDuration=5e3,this.countdownRemaining=0,this.countdownTimeoutId=null,this.countdownIntervalId=null,this.countdownStartTime=null,this.isPaused=!1,this.maxRecordingTime=null,this.maxTimeTimer=null,this.recordingStartTime=null,this.maxTimeRemaining=null,this.recordingSeconds=0,this.recordingIntervalId=null,this.pauseStartTime=null,this.totalPausedTime=0,this.streamProcessor=null,this.originalCameraStream=null,this.enableTabVisibilityOverlay=!1,this.startupAborted=!1,this.activeRecordingConfig=null,this.activeRouteDecision=XC,this.streamManager=e,this.callbacks=t,this.dependencies={...ZC,...n}}setCountdownDuration(e){this.countdownDuration=e}setMaxRecordingTime(e){this.maxRecordingTime=e}setTabVisibilityOverlayConfig(e,t){this.enableTabVisibilityOverlay=e,this.tabVisibilityOverlayText=t}getRecordingState(){return this.recordingState}isPausedState(){return this.isPaused}getRecordingSeconds(){return this.recordingSeconds}getStreamProcessor(){return this.streamProcessor}updateSourceType(e){this.recordingState!==JC||!this.streamProcessor||this.streamProcessor.updateSourceType(e)}setOriginalCameraStream(e){this.originalCameraStream=e}getOriginalCameraStream(){return this.originalCameraStream}prewarmStreamProcessor(e){let t=this.getOrCreateStreamProcessor();t.prewarm(),e&&t.warmupEncoder(e)}async startRecording(){try{this.callbacks.onClearUploadStatus(),this.countdownDuration>0?this.startCountdown():await this.doStartRecording()}catch(e){this.handleError(e),this.recordingState=YC,this.cancelCountdown()}}startCountdown(){this.recordingState=`countdown`,this.countdownRemaining=Math.ceil(this.countdownDuration/qC),this.countdownStartTime=Date.now(),this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining),this.countdownIntervalId=window.setInterval(()=>{if(!this.countdownStartTime)return;let e=Date.now()-this.countdownStartTime,t=Math.max(0,Math.ceil((this.countdownDuration-e)/qC)),n=this.countdownRemaining;this.countdownRemaining=t,n!==t&&this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)},100),this.countdownTimeoutId=window.setTimeout(async()=>{await this.doStartRecording().catch(()=>void 0)},this.countdownDuration)}async doStartRecording(){$.debug(`[RecordingManager] doStartRecording called`),this.cancelCountdown(),this.resetRecordingState(),this.startupAborted=!1;let e=this.streamManager.getStream();if($.debug(`[RecordingManager] Current stream:`,{hasStream:!!e,audioTracks:e?.getAudioTracks().length||0,videoTracks:e?.getVideoTracks().length||0}),!e){$.warn(`[RecordingManager] No stream available`),this.handleError(Error(`No stream available for recording`)),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}this.originalCameraStream=e,$.debug(`[RecordingManager] Ensuring stream processor`);let t=this.getOrCreateStreamProcessor();$.debug(`[RecordingManager] StreamProcessor ready:`,!!t);let n=null,r=await this.callbacks.onGetConfig().then(e=>(n=e,null)).catch(e=>e);if(r){this.handleError(r),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}if(!n){this.handleError(Error(`Failed to get recording config`)),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}let i=await this.resolveRouteDecision();if(i instanceof Error){this.handleError(i),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}this.callbacks.onAudioWarning&&t.setOnAudioWarning(this.callbacks.onAudioWarning),this.callbacks.onAudioRecovered&&t.setOnAudioRecovered(this.callbacks.onAudioRecovered),t.setOnError(e=>{this.handleFatalProcessorError(e)}),this.activeRecordingConfig=n,this.activeRouteDecision=i,$.debug(`[RecordingManager] Starting recording with stream manager`);let a=await this.streamManager.startRecording(t,n,this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText,i).then(()=>null).catch(e=>($.error(`[RecordingManager] Error starting recording:`,e),e));if(a){this.activeRecordingConfig=null,this.activeRouteDecision=XC,this.handleError(a),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState);return}if(this.startupAborted){this.startupAborted=!1;return}$.info(`[RecordingManager] Recording started successfully`),this.recordingState=JC,this.callbacks.onStateChange(this.recordingState),this.startRecordingTimer(),this.recordingStartTime=Date.now(),this.maxRecordingTime&&this.maxRecordingTime>0&&(this.maxTimeRemaining=this.maxRecordingTime,this.startMaxTimeTimer())}async stopRecording(){$.debug(`[RecordingManager] stopRecording called`);try{if(this.recordingState!==JC){let e=this.recordingState;throw this.cancelCountdown(),Ix(Mx,`Recording is not ready to stop`,{recordingState:e,hasStreamProcessor:!!this.streamProcessor})}this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState(),this.callbacks.onStopAudioTracking(),$.debug(`[RecordingManager] Stopping recording in stream manager`);let e=await this.streamManager.stopRecording(),t=await this.resolveFinalRecordingBlob(e.blob);$.info(`[RecordingManager] Recording stopped, blob size:`,t.size),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.callbacks.onRecordingComplete(t);let n={};return e.recordingStats!==void 0&&(n.videoFrameCount=e.recordingStats.videoFrameCount,n.totalFrameErrors=e.recordingStats.totalFrameErrors,n.totalFramesProcessed=e.recordingStats.totalFramesProcessed),e.encoderAcceleration!==void 0&&(n.encoderAcceleration=e.encoderAcceleration),e.mediaRecorderDiagnostics!==void 0&&Object.assign(n,e.mediaRecorderDiagnostics),{blob:t,telemetryProperties:n}}catch(e){let t=Lx(e);throw this.handleError(t),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.streamProcessor&&=(this.streamProcessor.destroy(),null),t}finally{this.activeRecordingConfig=null,this.activeRouteDecision=XC}}pauseRecording(){if(!(this.recordingState!==JC||this.isPaused)&&(this.streamManager.pauseRecording(),this.isPaused=!0,this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.pauseStartTime=Date.now(),this.maxTimeTimer!==null&&this.recordingStartTime!==null&&this.maxRecordingTime!==null)){let e=Date.now()-this.recordingStartTime-this.totalPausedTime;this.maxTimeRemaining=Math.max(0,this.maxRecordingTime-e),this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null}}resumeRecording(){this.recordingState!==JC||!this.isPaused||(this.streamManager.resumeRecording(),this.isPaused=!1,this.updatePausedDuration(),this.startRecordingTimer(),this.maxTimeRemaining!==null&&this.maxTimeRemaining>0&&this.startMaxTimeTimer())}cancelCountdown(){this.clearTimer(this.countdownTimeoutId,clearTimeout),this.countdownTimeoutId=null,this.clearTimer(this.countdownIntervalId,clearInterval),this.countdownIntervalId=null,this.recordingState=YC,this.countdownRemaining=0,this.countdownStartTime=null,this.callbacks.onCountdownUpdate(this.recordingState,this.countdownRemaining)}cleanup(){this.cancelCountdown(),this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.streamProcessor&&=(this.streamProcessor.destroy(),null)}resetRecordingState(){this.isPaused=!1,this.recordingSeconds=0,this.totalPausedTime=0,this.pauseStartTime=null,this.recordingStartTime=null,this.maxTimeRemaining=null}async resolveFinalRecordingBlob(e){if(this.activeRouteDecision.route!==`safe-capture-post-recording-transcode`)return e;if(!this.activeRecordingConfig)throw Error(`Recording config unavailable for final video processing`);if(QC(e,this.activeRecordingConfig))return e;this.callbacks.onTranscodingProgress?.(0);let t=await this.dependencies.transcodeVideo(e,this.activeRecordingConfig,e=>{this.callbacks.onTranscodingProgress?.(e)});return this.callbacks.onTranscodingProgress?.(1),t.blob}resetPauseState(){this.isPaused=!1,this.pauseStartTime=null,this.totalPausedTime=0}getOrCreateStreamProcessor(){if(this.streamProcessor)return this.streamProcessor;let e=new KC;return this.streamProcessor=e,e}async resolveRouteDecision(){return this.callbacks.onGetRouteDecision?await this.callbacks.onGetRouteDecision().then(e=>e).catch(e=>e instanceof Error?e:Error(i(e))):XC}updatePausedDuration(){if(this.pauseStartTime===null)throw Error(`Pause start time not set`);let e=Date.now()-this.pauseStartTime;this.totalPausedTime+=e,this.pauseStartTime=null}startRecordingTimer(){if(this.recordingIntervalId!==null)return;let e=Hx(this.recordingSeconds);this.callbacks.onTimerUpdate(e),this.recordingIntervalId=window.setInterval(()=>{this.recordingSeconds+=1;let e=Hx(this.recordingSeconds);this.callbacks.onTimerUpdate(e)},1e3)}startMaxTimeTimer(){this.maxTimeRemaining===null||this.maxTimeRemaining<=0||(this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=window.setTimeout(async()=>{this.recordingState===JC&&!this.isPaused&&await this.stopRecording()},this.maxTimeRemaining))}clearTimer(e,t){e!==null&&t(e)}handleError(e){let t=e instanceof Error?e:Error(i(e));this.callbacks.onError(t)}handleFatalProcessorError(e){this.recordingState===JC&&(this.clearTimer(this.recordingIntervalId,clearInterval),this.recordingIntervalId=null,this.clearTimer(this.maxTimeTimer,clearTimeout),this.maxTimeTimer=null,this.resetPauseState()),!(!this.streamProcessor&&this.recordingState!==JC)&&($.error(`[RecordingManager] Fatal processor error, stopping recording`,e),this.startupAborted=!0,this.streamProcessor&&=(this.streamProcessor.destroy(),null),this.recordingState=YC,this.callbacks.onStateChange(this.recordingState),this.recordingSeconds=0,this.callbacks.onError(e))}},ew=class{constructor(e){this.client=null,this.createTelemetryClient=e.createTelemetryClient}initialize(e,t){typeof e==`string`&&e.length>0&&typeof t==`string`&&t.length>0&&(this.client=this.createTelemetryClient(e,t))}sendEvent(e,t,n){if(!this.client)return;let r={name:e};t&&(r={...r,properties:t}),n&&(r={...r,error:n}),this.client.triggerTelemetryEvent(r)}async executeAction(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null;if(await e.action().catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;this.sendEvent(e.succeededEvent,e.properties)}async executeActionWithResult(e){e.requestedEvent&&this.sendEvent(e.requestedEvent,e.properties);let t=null,n=null;if(await e.action().then(e=>{n=e}).catch(e=>{t=e}),t)throw this.sendEvent(e.failedEvent,e.properties,t),t;if(n===null)throw Error(`Telemetry action failed to return result`);let r=this.resolveResultTelemetryProperties(n,e.getPropertiesFromResult),i=this.mergeTelemetryProperties(e.properties,r);return this.sendEvent(e.succeededEvent,i),n}resolveResultTelemetryProperties(e,t){if(t!==void 0)return t(e)}mergeTelemetryProperties(e,t){if(!(e===void 0&&t===void 0))return e===void 0?t:t===void 0?e:{...e,...t}}},tw=class{constructor(){this.metadataById=new Map}getMetadata(e){return this.metadataById.get(e)}setMetadata(e,t){let n=new Map(this.metadataById);n.set(e,t),this.metadataById=n}clearMetadata(e){let t=new Map(this.metadataById);t.delete(e),this.metadataById=t}};let nw=`[RecorderController]`;var rw=class{constructor(e={}){this.uploadService=null,this.uploadQueueManager=null,this.isInitialized=!1,this.isDemo=!1,this.isDestroyed=!1,this.enableTabVisibilityOverlay=!1,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId=null,this.audioTelemetryUnsub=null,this.callbacks=e,this.streamManager=new eS,this.configManager=new dn,this.storageManager=new zb,this.deviceManager=new fn(this.streamManager,e.device),this.audioLevelAnalyzer=new o,this.uploadService=new jS,this.uploadCallbacks=US(e),this.telemetryManager=new ew({createTelemetryClient:kS}),this.uploadMetadataManager=new tw;let t=qS(e,{stopAudioTracking:()=>this.audioLevelAnalyzer.stopTracking(),getConfig:()=>Promise.resolve(this.configManager.getConfigForRecording()),getRouteDecision:async()=>await this.resolveRecordingRouteDecision(`live-recorder`),onAudioWarning:e.recording?.onAudioWarning?t=>{this.sendAudioWarningTelemetry(t),e.recording?.onAudioWarning?.(t)}:e=>{this.sendAudioWarningTelemetry(e)},...e.recording?.onAudioRecovered&&{onAudioRecovered:e.recording.onAudioRecovered},...e.recording?.onTranscodingProgress&&{onTranscodingProgress:e.recording.onTranscodingProgress}});this.recordingManager=new $C(this.streamManager,t);let n=JS(e,{isRecording:()=>this.isRecording(),updateSourceType:e=>{this.recordingManager.updateSourceType(e)},getSelectedCameraDeviceId:()=>this.deviceManager.getSelectedCameraDeviceId(),getSelectedMicDeviceId:()=>this.deviceManager.getSelectedMicDeviceId()});this.sourceSwitchManager=new _x(this.streamManager,n);let r=e.stream;r&&(this.streamManager.on(`streamstart`,({stream:e})=>{$.debug(`${nw} streamstart event received, calling callback`),r.onStreamStart&&r.onStreamStart(e)}),this.streamManager.on(`streamstop`,()=>{$.debug(`${nw} streamstop event received, calling callback`),r.onStreamStop&&r.onStreamStop()}),this.streamManager.on(`error`,({error:e})=>{$.error(`${nw} stream error event received, calling callback`,e),this.telemetryManager.sendEvent(`stream.error`,{sourceType:this.getCurrentSourceType()},e),r.onError&&r.onError(e)})),this.audioTelemetryUnsub=this.streamManager.on(`audiotelemetry`,({event:e})=>{let t=this.getBrowserNameForTelemetry();this.telemetryManager.sendEvent(e.name,{...e.properties,browserName:t,sourceType:this.getCurrentSourceType()},e.error)})}async initialize(e){if(this.isInitialized)return;await this.validateRecorderSupport();let t=!1;typeof e.demo==`boolean`&&(t=e.demo),this.isDemo=t;let n=null;typeof e.apiKey==`string`&&e.apiKey.length>0&&(n=e.apiKey);let r=null;typeof e.backendUrl==`string`&&e.backendUrl.length>0&&(r=e.backendUrl),this.telemetryManager.initialize(n,r),await this.telemetryManager.executeAction({requestedEvent:`sdk.init.started`,succeededEvent:`sdk.init.succeeded`,failedEvent:`sdk.init.failed`,action:async()=>{await this.initializeConfig(n,r),this.applyRecordingConfig(e),await this.initializeStorage(),this.isInitialized=!0,this.scheduleRecordingWarmup()}})}async startStream(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({succeededEvent:`preview.start.succeeded`,failedEvent:`preview.start.failed`,action:async()=>{$.debug(`${nw} startStream called`),await this.streamManager.startStream(),this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})),this.prewarmSupportCheck(),$.debug(`${nw} startStream completed`)},properties:{sourceType:e}})}async stopStream(){await this.streamManager.stopStream()}switchVideoDevice(e){return this.streamManager.switchVideoDevice(e)}switchAudioDevice(e){return this.streamManager.switchAudioDevice(e)}async startRecording(){let e=this.getCurrentSourceType();await this.telemetryManager.executeAction({requestedEvent:`recording.start.requested`,succeededEvent:`recording.start.succeeded`,failedEvent:`recording.start.failed`,action:async()=>{if(this.isUploading())throw Ix(Fx,`Previous recording is still being uploaded`);await this.ensureConfigReady(),await this.streamManager.waitForAudio(),await this.recordingManager.startRecording()},properties:{sourceType:e}})}async stopRecording(){let e=this.getCurrentSourceType(),t=!0;try{return(await this.telemetryManager.executeActionWithResult({requestedEvent:`recording.stop.requested`,succeededEvent:`recording.stop.succeeded`,failedEvent:`recording.stop.failed`,action:async()=>{let e=await this.recordingManager.stopRecording();return await this.sourceSwitchManager.handleRecordingStop().catch(()=>{throw Error(`Source switch cleanup failed`)}),e},properties:{sourceType:e},getPropertiesFromResult:e=>e.telemetryProperties})).blob}catch(e){throw t=this.shouldStopStreamAfterStopFailure(e),kb(e)&&this.sendAudioMissingTelemetry(e),e}finally{t&&this.streamManager.stopStream()}}shouldStopStreamAfterStopFailure(e){return e&&typeof e==`object`&&`code`in e?e.code!==Mx:!0}sendAudioMissingTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};e.details&&(t.durationMs=e.details.durationMs,t.totalChunks=e.details.totalChunks,t.nonSilentChunks=e.details.nonSilentChunks,t.mutedDurationMs=e.details.mutedDurationMs,t.silenceRatio=e.details.durationMs>0?e.details.mutedDurationMs/e.details.durationMs:0,t.hadTrackEndedWarning=e.details.hadTrackEndedWarning),this.telemetryManager.sendEvent(`recording.audio-missing`,t,e)}getTabVisibilityOverlayConfig(){return{enabled:this.enableTabVisibilityOverlay,text:this.tabVisibilityOverlayText}}pauseRecording(){this.recordingManager.pauseRecording()}resumeRecording(){this.recordingManager.resumeRecording()}async switchSource(e){await this.telemetryManager.executeAction({requestedEvent:`source.switch.requested`,succeededEvent:`source.switch.succeeded`,failedEvent:`source.switch.failed`,action:async()=>{await this.sourceSwitchManager.toggleSource()},properties:{sourceType:e}})}setCameraDevice(e){this.deviceManager.setCameraDevice(e)}setMicDevice(e){this.deviceManager.setMicDevice(e)}getAvailableDevices(){return this.deviceManager.getAvailableDevices()}muteAudio(){this.streamManager.muteAudio()}unmuteAudio(){this.streamManager.unmuteAudio()}toggleMute(){this.streamManager.toggleMute()}getIsMuted(){return this.streamManager.isMuted()}startAudioLevelTracking(e,t){if(!t)throw Error(`Audio level callbacks are required`);return this.audioLevelAnalyzer.startTracking(e,t,()=>this.streamManager.isMuted()),Promise.resolve()}stopAudioLevelTracking(){this.audioLevelAnalyzer.stopTracking()}getAudioLevel(){return this.audioLevelAnalyzer.getAudioLevel()}uploadVideo(e,t,n,r){return this.uploadCallbacks.onClearStatus(),this.isUploadInProgress=!0,this.uploadVideoAfterStatusClear(e,t,n,r).catch(e=>{throw this.isUploadInProgress=!1,e})}async uploadVideoAfterStatusClear(e,t,n,r){let i=await Cv(e),a=this.configManager.getConfigForRecording().format,o=`recording-${Date.now()}.${fy(a)}`,s=dy(a),c=this.getCurrentSourceType(),l;if(Object.keys(r).length>0&&(l=r),this.telemetryManager.sendEvent(`upload.started`,{filename:o,duration:i,sourceType:c}),!this.uploadQueueManager){await this.uploadDirectlyWithoutQueue({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,sourceType:c,userMetadata:l});return}let u=await this.uploadQueueManager.queueUpload({blob:e,apiKey:t,backendUrl:n,filename:o,mimeType:s,duration:i,metadata:void 0,userMetadata:l});this.uploadMetadataManager.setMetadata(u,{filename:o,duration:i,sourceType:c})}async uploadDirectlyWithoutQueue(e){if(!this.uploadService){let t=Error(`Upload service not available`);throw this.uploadCallbacks.onError(t),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},t),t}try{let t=await this.uploadService.uploadVideo(e.blob,{apiKey:e.apiKey,backendUrl:e.backendUrl,filename:e.filename,mimeType:e.mimeType,metadata:void 0,userMetadata:e.userMetadata,onProgress:this.uploadCallbacks.onProgress});this.uploadCallbacks.onSuccess(t),this.telemetryManager.sendEvent(`upload.succeeded`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType,recordingId:t.id})}catch(t){let n=t instanceof Error?t:Error(i(t));throw this.uploadCallbacks.onError(n),this.telemetryManager.sendEvent(`upload.failed`,{filename:e.filename,duration:e.duration,sourceType:e.sourceType},n),n}finally{this.isUploadInProgress=!1}}getStream(){return this.streamManager.getStream()}isConfigReady(){return this.configManager.isConfigReady()}ensureConfigReady(){return this.isDemo||this.configManager.isConfigReady()?Promise.resolve():this.configManager.fetchConfig().then(()=>void 0).catch(()=>void 0)}cleanup(){this.isDestroyed=!0,this.isUploadInProgress=!1,this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),this.audioTelemetryUnsub&&=(this.audioTelemetryUnsub(),null),this.uploadQueueManager?.destroy(),this.storageManager.destroy(),this.recordingManager.cleanup(),this.audioLevelAnalyzer.stopTracking(),this.sourceSwitchManager.cleanup()}getRecordingState(){return this.recordingManager.getRecordingState()}isPaused(){return this.recordingManager.isPausedState()}getCurrentSourceType(){return this.sourceSwitchManager.getCurrentSourceType()}getOriginalCameraStream(){return this.sourceSwitchManager.getOriginalCameraStream()}getStreamManager(){return this.streamManager}getAudioStreamForAnalysis(){return this.streamManager.getAudioStreamForAnalysis()}getDeviceManager(){return this.deviceManager}getConfig(){return this.configManager.getConfig()}getUploadService(){return this.uploadService}isUploading(){return this.isUploadInProgress}isRecording(){return this.streamManager.isRecording()}isActive(){return this.streamManager.isActive()}isAudioReady(){return this.streamManager.isAudioReady()}getAudioStatus(){return this.streamManager.getAudioStatus()}sendAudioWarningTelemetry(e){let t={code:e.code,sourceType:this.getCurrentSourceType(),browserName:this.getBrowserNameForTelemetry()};`durationMs`in e&&(t.durationMs=e.durationMs),`peak`in e&&(t.peak=e.peak),`rms`in e&&(t.rms=e.rms),this.telemetryManager.sendEvent(`audio.warning`,t)}getBrowserNameForTelemetry(){try{return Mt()}catch{return`unknown`}}async resolveRecordingRouteDecision(e){let t=this.configManager.getConfigForRecording(),n=this.buildCodecProbeCandidates(t),r=await Vv({codecCandidates:n}),i=$v({profile:r,targetCodecIds:n.map(e=>e.id)});return this.telemetryManager.sendEvent(`recording.route.selected`,{routeDecision:this.buildRouteTelemetryProperties(i,r,e)}),i}buildCodecProbeCandidates(e){let t=e.width??1280,n=e.height??720,r=typeof e.bitrate==`number`?e.bitrate:25e5,i=e.fps??30;return this.resolveTargetCodecIds(e.codec).map(e=>({id:`${e}-${t}x${n}`,config:{codec:e,width:t,height:n,bitrate:r,framerate:i}}))}resolveTargetCodecIds(e){switch(e){case`avc`:return[`avc1.640028`,`avc1.42001f`];case`vp9`:return[`vp09.00.10.08`];case`vp8`:return[`vp8`];case`av1`:return[`av01.0.08M.08`];case`hevc`:return[`hvc1.1.6.L123.B0`];default:return[`avc1.640028`,`avc1.42001f`,`vp09.00.10.08`,`vp8`]}}buildRouteTelemetryProperties(e,t,n){return{selectedRoute:e.route,reasonCodes:e.reasonCodes,sourceType:n,clientTranscodeDeferred:e.route===`safe-capture-post-recording-transcode`,capabilitySummary:{browserName:t.browser.normalizedName,osName:t.os.name,deviceMemory:t.resources.deviceMemory??null,hardwareConcurrency:t.resources.hardwareConcurrency??null,effectiveType:t.network.effectiveType??null,online:t.network.online??null,isSecureContext:t.features.isSecureContext,hasMediaRecorder:t.features.hasMediaRecorder,hasVideoEncoder:t.features.hasVideoEncoder,supportedCodecIds:t.codecProbeResults.filter(e=>e.supported).map(e=>e.id),supportedEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.supported===!0).map(e=>e.id),smoothEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.smooth===!0).map(e=>e.id),powerEfficientEncodingCodecIds:t.codecProbeResults.filter(e=>e.encodingCapability?.powerEfficient===!0).map(e=>e.id)}}}async initializeConfig(e,t){let n=!0;e===null&&(n=!1),t===null&&(n=!1),n&&e!==null&&t!==null&&await this.configManager.initialize(e,t)}applyRecordingConfig(e){e.countdownDuration!==void 0&&this.recordingManager.setCountdownDuration(e.countdownDuration),e.maxRecordingTime!==void 0&&this.recordingManager.setMaxRecordingTime(e.maxRecordingTime),e.enableTabVisibilityOverlay!==void 0&&(this.enableTabVisibilityOverlay=e.enableTabVisibilityOverlay),e.tabVisibilityOverlayText!==void 0&&(this.tabVisibilityOverlayText=e.tabVisibilityOverlayText),this.recordingManager.setTabVisibilityOverlayConfig(this.enableTabVisibilityOverlay,this.tabVisibilityOverlayText)}async initializeStorage(){if(this.isDestroyed)return;let e=GS(this.callbacks);try{await this.storageManager.initialize(e)}catch(e){let t=e instanceof Error?e:Error(i(e)),n=i(t);this.telemetryManager.sendEvent(`storage.init.failed`,{reason:n},t),KS(this.callbacks)(n);return}if(this.isDestroyed)return;let t=this.storageManager.getWriteProbeResult();if(!t?.ok){let e=t?.reason??`Storage write probe did not complete`,n=Error(e);this.telemetryManager.sendEvent(`storage.write.probe.failed`,{reason:e},n),KS(this.callbacks)(e);return}let n=this.storageManager.getStorageService();n&&this.uploadService&&(this.uploadQueueManager=new AS(n,this.uploadService),this.uploadQueueManager.setCallbacks({onUploadProgress:(e,t)=>{this.uploadCallbacks.onProgress(t)},onUploadComplete:(e,t)=>{this.isUploadInProgress=!1,this.uploadCallbacks.onSuccess(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.succeeded`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType,recordingId:t.id}),this.uploadMetadataManager.clearMetadata(e))},onUploadError:(e,t)=>{this.isUploadInProgress=!1,this.uploadCallbacks.onError(t);let n=this.uploadMetadataManager.getMetadata(e);n&&(this.telemetryManager.sendEvent(`upload.failed`,{filename:n.filename,duration:n.duration,sourceType:n.sourceType},t),this.uploadMetadataManager.clearMetadata(e))}}))}async validateRecorderSupport(){Ft();let e=await vb({requiresAudio:!1,requiresWatermark:!1});if(!e.isSupported)throw Nt({missingCapabilities:e.missing,resolutionStage:`feature-preflight`})}scheduleRecordingWarmup(){this.recordingWarmupTimeoutId!==null&&(clearTimeout(this.recordingWarmupTimeoutId),this.recordingWarmupTimeoutId=null),!this.isDestroyed&&(this.recordingWarmupTimeoutId=setTimeout(()=>{this.recordingWarmupTimeoutId=null,!this.isDestroyed&&(this.ignorePromiseRejection(this.ensureConfigReady()),this.ignorePromiseRejection(this.configManager.getConfig().then(e=>{this.recordingManager.prewarmStreamProcessor(e)})))},0))}ignorePromiseRejection(e){e.catch(()=>void 0)}prewarmSupportCheck(){this.ignorePromiseRejection(vb({requiresAudio:!0,requiresWatermark:!0}).then(e=>{this.streamManager.setPreResolvedSupportReport(e)}))}};let iw=/<a\s[^>]*href="(?<href>[^"]+)"[^>]*>(?<text>[^<]+)<\/a>/,aw=/\starget=["'](?<target>[^"']+)["']/,ow=/^[a-zA-Z][a-zA-Z\d+\-.]*:/,sw=`{version}`;function cw(e,t){return e?e.toLowerCase().includes(t):!1}function lw(e){let t=e.trim();if(!t)return null;let n=t.toLowerCase();return!ow.test(n)||n.startsWith(`http:`)||n.startsWith(`https:`)?t:null}function uw(e,t,n,r){return e===`browser.unsupported`?r.browserUnsupportedDynamic?pw(r.browserUnsupportedDynamic,t,n):cw(t,`safari`)?r.browserUnsupportedSafari:cw(t,`firefox`)?r.browserUnsupportedFirefox:r.browserUnsupported:r.browserUnsupported}function dw(e,t){return e===`camera.in-use`?t.cameraInUse:e===`camera.not-found`?t.cameraNotFound:e===`camera.permission-denied`?t.cameraPermissionDenied:e===`camera.timeout`?t.cameraTimeout??t.failedToStartCamera:t.failedToStartCamera}function fw(e,t){return e===`audio.in-use`?t.audioInUse:e===`audio.not-found`?t.audioNotFound:e===`audio.permission-denied`?t.audioPermissionDenied:e===`audio.timeout`?t.audioTimeout??t.failedToStartAudio:t.failedToStartAudio}function pw(e,t,n){let r=`This browser`;t&&t.trim().length>0&&(r=t);let i=e.replace(`{browser}`,r);return n&&n.trim().length>0&&n?(i=i.replace(sw,n),i):(i=i.replace(` ({version})`,``),i=i.replace(sw,``),i)}function mw(e){let t=iw.exec(e);if(!t?.groups)return{prefix:e,linkText:null,linkHref:null,linkTarget:null,suffix:``};let n=t.index,r=n+t[0].length,i=e.slice(0,n),a=e.slice(r),o=lw(t.groups.href);if(!o)return{prefix:i+t.groups.text+a,linkText:null,linkHref:null,linkTarget:null,suffix:``};let s=aw.exec(t[0])?.groups?.target??null;return{prefix:i,linkText:t.groups.text,linkHref:o,linkTarget:s,suffix:a}}function hw(){let e=globalThis.navigator&&typeof globalThis.navigator.userAgent==`string`?globalThis.navigator.userAgent:``,t=new wt(e).getResult(),n=t.device.type,r=n===`mobile`||n===`tablet`;return $.debug(`Mobile detection result`,{userAgent:e,deviceType:n,isMobile:r,device:t.device,os:t.os,browser:t.browser}),r}function gw(){let e=jt(),t=null;e.name.length>0&&(t=e.name);let n=null;return e.version.length>0&&(n=e.version),{browserName:t,browserVersion:n}}function _w(e){let t=t=>{if(!(`code`in t))return;let n=t,r=typeof n.code==`string`?n.code:null;if(r===null)return;if(r!==`browser.unsupported`){(r.startsWith(`camera.`)||r.startsWith(`audio.`)||r.startsWith(`recording.`))&&e.updateState({errorCode:r,canRetry:!0,browserName:null,browserVersion:null});return}let i=gw(),a=i.browserName;n.browserName&&n.browserName.length>0&&(a=n.browserName);let o=i.browserVersion;n.browserVersion&&n.browserVersion.length>0&&(o=n.browserVersion),e.updateState({errorCode:`browser.unsupported`,canRetry:!1,browserName:a,browserVersion:o})};return{recording:{onStateChange:t=>{e.updateState({recordingState:t})},onCountdownUpdate:(t,n)=>{e.updateState({recordingState:t,countdown:n})},onTimerUpdate:t=>{e.updateState({timer:t})},onError:n=>{t(n),e.updateState({error:i(n),transcodingProgress:null,uploadProgress:null})},onRecordingComplete:t=>{e.updateState({countdown:null}),e.processRecordingBlob(t).catch(t=>{e.updateState({error:i(t),transcodingProgress:null,uploadProgress:null})})},onClearUploadStatus:()=>{e.updateState({uploadProgress:null})},onTranscodingProgress:t=>{e.updateState({transcodingProgress:t})},onAudioWarning:t=>{e.updateState({audioWarning:t}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-warning`,{detail:t}))},onAudioRecovered:()=>{e.updateState({audioWarning:null}),e.dispatchEvent(new CustomEvent(`vidtreo:audio-recovered`))},onStopAudioTracking:()=>void 0,onGetConfig:()=>{if(!e.controller)throw Error(`Controller not initialized`);return e.isDemo?Promise.resolve(Zt(`mp4`)):e.controller.getConfig()}},sourceSwitch:{onSourceChange:e=>Promise.resolve(),onPreviewUpdate:t=>(e.updateState({stream:t}),Promise.resolve()),onError:n=>{t(n),e.updateState({error:i(n)})},onTransitionStart:t=>{e.updateState({transitionMessage:t})},onTransitionEnd:()=>{e.updateState({transitionMessage:null})}},storage:{onUploadProgress:()=>void 0,onUploadComplete:()=>void 0,onUploadError:()=>void 0},onStorageCleanupError:t=>{e.updateState({error:t})}}}function vw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setCameraDevice(n),e.switchVideoDevice(n)}function yw(e,t){let n=(e=>e===``||e===`default`?null:e)(t);return e.setMicDevice(n),e.switchAudioDevice(n)}async function bw(e,t=`camera`){e.isActive()||await e.startStream(),t!==e.getCurrentSourceType()&&await e.switchSource(t),await e.startRecording()}async function xw(e,t,n,r){return await e.stopRecording()}function Sw(e){e.pauseRecording()}function Cw(e){e.resumeRecording()}async function ww(e,t){await e.switchSource(t)}let Tw=`camera`,Ew=`screen`,Dw=`recording`,Ow=`browser.unsupported`,kw=[.8,1.2,.9];function Aw(e,t){let{uploadProgress:n,uploadingLabel:r}=e,{overlay:i,fill:a,text:o}=t;if(!i)return;if(n===null){i.style.display=`none`,jw(i.querySelector(`#finishingProgress`),!1),jw(i.querySelector(`#uploadProgress`),!1);return}i.style.display=`block`;let s=i.querySelector(`#finishingProgress`),c=i.querySelector(`#uploadProgress`),l=e.isTranscoding===!0&&s!==null;jw(s,l),jw(c,!l);let u=Math.round(n*100),d=a,f=o;if(l){let e=i.querySelector(`#finishingProgressFill`),t=i.querySelector(`#finishingProgressText`);e!==null&&(d=e),t!==null&&(f=t)}d&&(d.style.width=`${u}%`),f&&(f.textContent=`${r} ${u}%`)}function jw(e,t){e&&(e.style.display=t?`block`:`none`)}function Mw(e,t){let{transitionMessage:n}=e,{overlay:r,message:i}=t;if(r){if(!n){r.classList.remove(`vidtreo-active`);return}r.classList.add(`vidtreo-active`),i&&(i.textContent=n)}}let Nw=`none`,Pw=`flex`,Fw=`inline-flex`,Iw=`checking`,Lw=`blocked`,Rw=`ready`,zw=`vidtreo-active`,Bw=`vidtreo-permission-flow--fading`,Vw=`vidtreo-permission-flow-action--requesting`;function Hw(e){return{container:e.querySelector(`#permissionFlow`),spinner:e.querySelector(`#permissionFlowSpinner`),title:e.querySelector(`#permissionFlowTitle`),subtitle:e.querySelector(`#permissionFlowSubtitle`),actionButton:e.querySelector(`#btnAllowPermission`),buttonIcon:e.querySelector(`#permissionFlowBtnIcon`),buttonSpinner:e.querySelector(`#permissionFlowBtnSpinner`),buttonText:e.querySelector(`#permissionFlowBtnText`),recovery:e.querySelector(`#permissionFlowRecovery`),recoveryTitle:e.querySelector(`#permissionFlowRecoveryTitle`),recoveryText:e.querySelector(`#permissionFlowRecoveryText`),retryButton:e.querySelector(`#btnRetryPermission`),recoveryGuideUrl:e.querySelector(`#recoveryGuideUrl`),recoveryGuidePopoverUrl:e.querySelector(`#recoveryGuidePopoverUrl`)}}function Uw(e){return e.permissions.camera===`granted`?`microphone`:`camera`}function Ww(e,t){return t.cameraTitle}function Gw(e,t){return t.cameraLabel}function Kw(e,t){return t.allowCamera}function qw(e,t,n){let r=e.step,i=!1;(r===Iw||r===`awaiting-user`||r===Lw||r===Rw)&&(i=!0);let a=r===Rw,o=r===Lw,s=r===Iw,c=Uw(e),l=Ww(c,t),u=Gw(c,t),d=Kw(c,t),f=t.recoveryInstructions;return e.recoveryData?.resetInstructions&&(f=e.recoveryData.resetInstructions),{isVisible:i,isFadingOut:n,isSpinnerOnly:a,isBlocked:o,isRequesting:s,titleText:l,subtitleText:u,actionLabel:d,requestingText:t.statusRequesting,recoveryTitleText:t.recoveryTitle,recoveryInstructionsText:f}}function Jw(e,t,n){if(e){if(t){e.style.display=n;return}e.style.display=Nw}}function Yw(e,t){if(t.isVisible)e.classList.add(zw);else return e.classList.remove(zw),e.classList.remove(Bw),!1;return t.isFadingOut?e.classList.add(Bw):e.classList.remove(Bw),!0}function Xw(e,t,n){Jw(e.actionButton,n,Fw),e.actionButton&&(t.isRequesting?(e.actionButton.classList.add(Vw),e.actionButton.disabled=!0):(e.actionButton.classList.remove(Vw),e.actionButton.disabled=!1)),Jw(e.buttonIcon,n&&!t.isRequesting,Fw),Jw(e.buttonSpinner,n&&t.isRequesting,Fw),e.buttonText&&(t.isRequesting?e.buttonText.textContent=t.requestingText:e.buttonText.textContent=t.actionLabel)}function Zw(){if(globalThis.window===void 0)return`vidtreo.com`;let e=globalThis.window.location.hostname||`vidtreo.com`;return e.length>20?`${e.slice(0,20)}...`:e}function Qw(e,t){if(Jw(e.recovery,t.isBlocked,Pw),e.recoveryTitle&&(e.recoveryTitle.textContent=t.recoveryTitleText),Jw(e.recoveryText,!1,Nw),Jw(e.retryButton,!1,Nw),t.isBlocked){let t=Zw();e.recoveryGuideUrl&&(e.recoveryGuideUrl.textContent=t),e.recoveryGuidePopoverUrl&&(e.recoveryGuidePopoverUrl.textContent=t)}}function $w(e,t){t&&(e.actionButton&&t.onAllow&&(e.actionButton.onclick=t.onAllow),e.retryButton&&t.onRetry&&(e.retryButton.onclick=t.onRetry))}function eT(e,t,n){let{container:r}=t;if(!r||!Yw(r,e))return;let i=!e.isSpinnerOnly;Jw(t.spinner,e.isSpinnerOnly,Fw),Jw(t.title,i&&!e.isBlocked,Pw),Jw(t.subtitle,i&&!e.isBlocked,Pw),t.title&&(t.title.textContent=e.titleText),t.subtitle&&(t.subtitle.textContent=e.subtitleText),Xw(t,e,i&&!e.isBlocked),Qw(t,e),$w(t,n)}function tT(e,t){e.textContent=``;let n=document.createTextNode(t.prefix);if(e.append(n),t.linkText&&t.linkHref){let n=document.createElement(`a`),r=t.linkTarget;n.href=t.linkHref,r&&(n.target=r),r===`_blank`&&(n.rel=`noopener noreferrer`),n.textContent=t.linkText,e.append(n)}let r=document.createTextNode(t.suffix);e.append(r)}function nT(e){let{stream:t,transitionMessage:n,isVideoLoaded:r}=e;return{showPreviewSkeleton:!!t&&!r&&!n,showVideoPreview:!!t}}function rT(e,t){let{previewSkeleton:n,videoPreview:r}=t;n&&(e.showPreviewSkeleton?n.style.display=`block`:n.style.display=`none`),r&&(e.showVideoPreview?r.style.display=`block`:r.style.display=`none`)}function iT(e,t,n){let{videoPreview:r}=t,{onVideoLoaded:a,onError:o,startAudioAnalysis:s,stopAudioAnalysis:c}=n;if(r){if(!e){r.srcObject=null,c();return}r.srcObject=e,r.onloadeddata=()=>{a()},r.play().catch(e=>o(i(e))),s(e)}}function aT(e){return{startCameraArea:e.querySelector(`#startCameraArea`),startCameraButton:e.querySelector(`#startCameraButton`),cameraIcon:e.querySelector(`#startCameraArea .vidtreo-camera-icon`),cameraText:e.querySelector(`#startCameraArea .vidtreo-camera-text`),cameraHint:e.querySelector(`#startCameraArea .vidtreo-camera-hint`),previewSkeleton:e.querySelector(`#previewSkeleton`),previewSkeletonText:e.querySelector(`#previewSkeleton .vidtreo-skeleton-text`),videoPreview:e.querySelector(`#videoPreview`),countdownOverlay:e.querySelector(`#countdownOverlay`),countdownNumber:e.querySelector(`#countdownNumber`),recordingTimerRow:e.querySelector(`#recordingTimerRow`),recordingTimer:e.querySelector(`#recordingTimer`),recIndicatorTop:e.querySelector(`#recIndicatorTop`),audioLevelBars:e.querySelector(`#audioLevelBars`)}}function oT(e,t,n,r,i,a){if(e.stream)return{shouldShow:!1,iconClassName:``,browserErrorContent:null,textContent:null,hintText:null,retryButtonLabel:null};let o=gS({errorCode:e.errorCode,hasAudioFailed:!1,error:null}),s=o.isCameraError||o.isAudioError,c=!(o.isBrowserUnsupported||s),l=o.isBrowserUnsupported||s?`ph-fill ph-warning-circle`:`ph-fill ph-camera`,u=null,d=null;o.isBrowserUnsupported&&(u=mw(n)),o.isAudioError&&(d=i),o.isCameraError&&(d=r),c&&(d=t.initializingCamera);let f=c?t.grantPermissions:null,p=s&&!o.isPermissionDenied?a:null;return{shouldShow:!0,iconClassName:l,browserErrorContent:u,textContent:d,hintText:f,retryButtonLabel:p}}function sT(e,t){let n=!1;return e&&(n=!0),{shouldShow:n,text:t.switchingDevice}}function cT(e,t,n){let r=!1;return e===`countdown`&&t!==null&&(r=!0),{shouldShow:r,countdown:t,text:n.recordingStartsIn}}function lT(e,t){return{shouldShow:e,text:t.rec}}function uT(e,t){return{shouldShow:e,timer:t}}function dT(e){return{shouldShow:e}}function fT(e,t){let{state:n,isVideoLoaded:r,isRecording:i,translations:a}=e;pT(oT(n,a,uw(n.errorCode,n.browserName,n.browserVersion,{browserUnsupported:a.browserUnsupported,browserUnsupportedDynamic:a.browserUnsupportedDynamic,browserUnsupportedSafari:a.browserUnsupportedSafari,browserUnsupportedFirefox:a.browserUnsupportedFirefox}),dw(n.errorCode??``,{cameraInUse:a.cameraInUse,cameraNotFound:a.cameraNotFound,cameraPermissionDenied:a.cameraPermissionDenied,cameraTimeout:a.cameraTimeout,failedToStartCamera:a.failedToStartCamera}),fw(n.errorCode??``,{audioInUse:a.audioInUse,audioNotFound:a.audioNotFound,audioPermissionDenied:a.audioPermissionDenied,audioTimeout:a.audioTimeout,failedToStartAudio:a.failedToStartAudio}),a.retryCamera),t,e.onRetryCamera),mT(sT(n.transitionMessage,a),t),rT(nT({stream:n.stream,transitionMessage:n.transitionMessage,isVideoLoaded:r}),{previewSkeleton:t.previewSkeleton,videoPreview:t.videoPreview}),hT(cT(n.recordingState,n.countdown,a),t),gT(lT(i,a),t),_T(uT(i,n.timer),t),vT(dT(i),t)}function pT(e,t,n){let{startCameraArea:r,startCameraButton:i,cameraIcon:a,cameraText:o,cameraHint:s}=t;if(r){if(!e.shouldShow){r.style.display=`none`;return}r.style.display=`block`,a&&(a.innerHTML=`<i class="${e.iconClassName}" style="font-size: 48px;"></i>`),o&&(e.browserErrorContent&&tT(o,e.browserErrorContent),e.textContent&&(o.textContent=e.textContent)),s&&(e.hintText?(s.textContent=e.hintText,s.style.display=`block`):s.style.display=`none`),i&&(e.retryButtonLabel?(i.textContent=e.retryButtonLabel,i.hidden=!1,i.className=`vidtreo-error-retry`,i.onclick=e=>{e.preventDefault(),e.stopPropagation(),n&&n()}):(i.hidden=!0,i.onclick=null))}}function mT(e,t){let{previewSkeleton:n,previewSkeletonText:r}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`,r&&(r.textContent=e.text))}function hT(e,t){let{countdownOverlay:n,countdownNumber:r}=t;n&&(e.shouldShow?n.classList.add(`vidtreo-active`):n.classList.remove(`vidtreo-active`),r&&e.countdown!==null&&(r.textContent=e.countdown.toString()))}function gT(e,t){let{recIndicatorTop:n}=t;n&&(e.shouldShow?n.style.display=`block`:n.style.display=`none`)}function _T(e,t){let{recordingTimerRow:n,recordingTimer:r}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`,r&&(r.textContent=e.timer))}function vT(e,t){let{audioLevelBars:n}=t;n&&(e.shouldShow?n.style.display=`flex`:n.style.display=`none`)}let yT=`inline-flex`;function bT(e){let{stream:t,buttonVisibility:n,currentSourceType:r,isMuted:i,isAudioReady:a,isProcessingRecording:o,isStopLocked:s,stopLockedTooltip:c,recordingState:l,buttonTranslations:u}=e,d=!!t,f=l===`idle`&&d&&!o,p=f&&!a,m=p?u.microphoneConnecting:``,h=!1;(n.showPauseButton||n.showResumeButton)&&(h=!0);let g=u.pause,_=`ph-fill ph-pause`;n.showResumeButton&&(g=u.resume,_=`ph-fill ph-play`);let v=u.mute,y=`ph-fill ph-microphone`;i&&(v=u.unmute,y=`ph-fill ph-microphone-slash`);let b=`ph-fill ph-monitor`;r!==Tw&&(b=`ph-fill ph-camera`);let x=!1;return n.showDownloadButton&&(x=!0),{showRecordingControls:d,showSettingsButton:n.showSettingsButton,showRecordButton:f,isRecordDisabled:p,recordTooltip:m,showMuteButton:n.showMuteButton,showPauseButton:h,showStopButton:n.showStopButton,showSwitchSourceButton:n.showSwitchSourceButton,showDownloadButton:x,pauseTitle:g,pauseIconClassName:_,muteTitle:v,muteIconClassName:y,switchSourceIconClassName:b,isMuted:i,isStopLocked:s,stopLockedTooltip:c,settingsTitle:u.settings,switchSourceTitle:u.switchSource,downloadTitle:u.download,buttonTranslations:u}}function xT(e){return{recordingControls:e.querySelector(`#recordingControls`),settingsButton:e.querySelector(`#btnSettings`),recordButton:e.querySelector(`#btnRecord`),muteButton:e.querySelector(`#btnMute`),muteIcon:e.querySelector(`#iconMute`),pauseButton:e.querySelector(`#btnPause`),pauseIcon:e.querySelector(`#iconPause`),stopButton:e.querySelector(`#btnStop`),switchSourceButton:e.querySelector(`#btnSwitchSource`),switchSourceIcon:e.querySelector(`#iconSwitchSource`),downloadButton:e.querySelector(`#btnDownload`)}}function ST(e,t){let{recordingControls:n,settingsButton:r,recordButton:i,muteButton:a,muteIcon:o,pauseButton:s,pauseIcon:c,stopButton:l,switchSourceButton:u,switchSourceIcon:d,downloadButton:f}=t;wT(n,e),TT(r,e),ET(i,e),DT(a,e),OT(o,e),kT(s,e),AT(c,e),jT(l,e),MT(u,e),NT(d,e),PT(f,e)}function CT(e,t,n){e&&(t?e.style.display=n:e.style.display=`none`)}function wT(e,t){CT(e,t.showRecordingControls,`block`)}function TT(e,t){CT(e,t.showSettingsButton,yT),e&&(e.title=t.settingsTitle)}function ET(e,t){if(CT(e,t.showRecordButton,yT),!e)return;e.disabled=t.isRecordDisabled,e.classList.toggle(`vidtreo-record-button-disabled`,t.isRecordDisabled),e.title=t.recordTooltip,e.setAttribute(`aria-disabled`,String(t.isRecordDisabled));let n=e.querySelector(`i`),r=e.querySelector(`span`);t.isRecordDisabled?(n&&(n.className=`ph-fill ph-microphone vidtreo-mic-connecting-indicator`,n.style.fontSize=`18px`),r&&(r.textContent=t.recordTooltip)):(n&&(n.className=`ph-fill ph-circle`,n.style.fontSize=`24px`),r&&(r.textContent=t.buttonTranslations?.record??`Record`))}function DT(e,t){CT(e,t.showMuteButton,yT),e&&(e.title=t.muteTitle,e.classList.toggle(`vidtreo-muted`,t.isMuted))}function OT(e,t){e&&(e.className=t.muteIconClassName)}function kT(e,t){CT(e,t.showPauseButton,yT),e&&(e.title=t.pauseTitle)}function AT(e,t){e&&(e.className=t.pauseIconClassName)}function jT(e,t){if(CT(e,t.showStopButton,yT),e){if(e.classList.toggle(`vidtreo-stop-button-locked`,t.isStopLocked),e.setAttribute(`aria-disabled`,String(t.isStopLocked)),t.isStopLocked){e.title=t.stopLockedTooltip;return}e.title=``}}function MT(e,t){CT(e,t.showSwitchSourceButton,yT),e&&(e.title=t.switchSourceTitle)}function NT(e,t){e&&(e.className=t.switchSourceIconClassName)}function PT(e,t){CT(e,t.showDownloadButton,yT),e&&(e.title=t.downloadTitle)}function FT(e){let{stream:t,showSettings:n}=e,r=!1;return t&&n&&(r=!0),{shouldShow:r}}function IT(e,t,n){if(t){if(!e.shouldShow){t.classList.remove(`vidtreo-active`);return}t.classList.add(`vidtreo-active`),n()}}function LT(e){return e.toggleMute(),e.getIsMuted()}function RT(e){if(!e)return;let t=URL.createObjectURL(e),n=document.createElement(`a`);n.href=t,n.download=`recording-${Date.now()}.mp4`,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(t)}let zT={en:{initializingCamera:`Initializing camera...`,grantPermissions:`Grant camera and microphone permissions when prompted`,browserUnsupported:`This browser is not supported`,browserUnsupportedDynamic:`{browser} ({version}) is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox is not supported, please use <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Retry Camera`,cameraInUse:`Your camera is being used by another application. Close other apps using the camera (Zoom, Teams, Discord) and try again.`,cameraNotFound:`No camera detected. Connect a camera or check your device settings.`,cameraPermissionDenied:`Camera access was denied. Allow camera access in your browser settings and try again.`,cameraTimeout:`The camera took too long to start. Close other apps using the camera and try again.`,audioInUse:`Your microphone is being used by another application. Close other apps using the microphone (Zoom, Teams, Discord) and try again.`,audioNotFound:`No microphone detected. Connect a microphone or check your device settings.`,audioPermissionDenied:`Microphone access was denied. Allow microphone access in your browser settings and try again.`,audioTimeout:`The microphone took too long to start. Close other apps using the microphone and try again.`,failedToStartAudio:`Failed to start microphone`,audioErrorTitle:`Microphone unavailable`,audioErrorMessage:`We couldn't access your microphone. It may be in use by another app like Zoom, Teams, or Discord. Please close it and try again.`,audioErrorRetry:`Try again`,audioMissingTitle:`Recording has no audio`,audioMissingMessage:`We couldn't capture audio in this recording. Your microphone may have been disconnected or blocked by the browser. Check your microphone and record again.`,audioSilentTitle:`Recording is silent`,audioSilentMessage:`We didn't detect any sound during the recording. Make sure your microphone is working and not muted by your operating system, then record again.`,audioProcessingErrorTitle:`Audio processing error`,audioProcessingErrorMessage:`We couldn't process the audio in this recording. Please record again.`,audioMissingRetry:`Record again`,audioWarningNoSignalTitle:`No microphone signal`,audioWarningNoSignalMessage:`We're not detecting any sound. Check that your microphone is active.`,audioWarningLowSignalTitle:`Audio is very quiet`,audioWarningLowSignalMessage:`Move closer to the microphone or turn up the input volume.`,audioWarningSpeakingMutedTitle:`You're speaking while muted`,audioWarningSpeakingMutedMessage:`Unmute your microphone if you want your voice in the recording.`,audioWarningTrackEndedTitle:`Microphone disconnected`,audioWarningTrackEndedMessage:`The microphone was disconnected. Reconnect it before continuing.`,audioWarningNoChunksTitle:`No microphone input`,audioWarningNoChunksMessage:`We're not receiving audio from the microphone. Check browser permissions.`,audioWarningTrackMutedTitle:`Microphone muted by browser`,audioWarningTrackMutedMessage:`The browser muted your microphone. Check site settings.`,audioWarningDismiss:`Dismiss`,cameraErrorTitle:`Camera unavailable`,cameraErrorMessage:`We couldn't access your camera. It may be in use by another app or permissions may be denied.`,browserErrorTitle:`Browser not supported`,browserErrorMessage:`This browser is not supported. Please use Chrome for the best experience.`,recordingCodecUnsupportedTitle:`Recording format not supported`,recordingCodecUnsupportedMessage:`This device can't use the selected video format. Close other apps, update Chrome if possible, and record again.`,recordingServerTranscodeFallbackTitle:`Finalizing on device`,recordingServerTranscodeFallbackMessage:`We're finishing the video on this device before upload. Keep this tab open.`,recordingTrackEndedTitle:`Camera stopped during recording`,recordingTrackEndedMessage:`The camera feed ended before the recording finished. Check that the camera is still connected and record again.`,recordingFinalizeTimeoutTitle:`Recording took too long to finish`,recordingFinalizeTimeoutMessage:`This device may be low on memory or processing power. Close other apps or browser tabs, then record again.`,recordingStateRaceTitle:`Recording did not start correctly`,recordingStateRaceMessage:`The recording could not be finalized because it did not start cleanly. Please refresh the page and record again.`,recordingNoFramesTitle:`No video was captured`,recordingNoFramesMessage:`We couldn't receive video frames from the camera. Check your camera connection and record again.`,recordingUnsupportedTitle:`Recording not available`,recordingUnsupportedMessage:`This device or browser can't record video reliably right now. Check your connection, update Chrome if possible, or use another device.`,recordingPipelineRetry:`Record again`,genericErrorTitle:`Something went wrong`,genericErrorMessage:`An unexpected error occurred. Please try again.`,errorRetry:`Try again`,switchingDevice:`Switching device...`,recordingStartsIn:`Recording starts in...`,switchingSource:`Switching source...`,rec:`REC`,settings:`Settings`,record:`Record`,stop:`Stop`,pause:`Pause`,resume:`Resume`,mute:`Mute`,unmute:`Unmute`,switchSource:`Switch Source`,camera:`Camera`,microphone:`Microphone`,microphoneConnecting:`Connecting microphone...`,minimumRecordingTimeNotReached:`You have not met the minimum recording time yet`,processVideo:`Process Video`,processing:`Processing...`,finishing:`Finishing...`,uploading:`Uploading...`,switchingCamera:`Switching camera...`,switchingMicrophone:`Switching microphone...`,failedToStartCamera:`Failed to start camera`,userInAnotherTab:`User in another tab`,download:`Download`,nativeCameraSelectVideo:`Select Video from Gallery`,nativeCameraRecordVideo:`Record with Camera`,errorTitle:`Configuration Error`,errorGeneric:`An error occurred while loading the configuration`,mobileOpenCamera:`Open Camera`,mobileOpenCameraTitle:`Record a Video`,mobileOpenCameraDescription:`Tap the button below to start recording`,mobileCloseCamera:`Close`,mobilePermissionDenied:`Camera Access Denied`,mobilePermissionDeniedDescription:`Please allow camera access in your browser settings to record video.`,permissionFlowTitle:`Set Up Your Camera`,permissionFlowCameraTitle:`Camera & Microphone`,permissionFlowMicrophoneTitle:`Camera & Microphone`,permissionFlowCameraLabel:`We need access to your camera and microphone to start recording`,permissionFlowMicrophoneLabel:`We need access to your camera and microphone to start recording`,permissionFlowStatusPending:`Pending`,permissionFlowStatusGranted:`Ready`,permissionFlowStatusDenied:`Blocked`,permissionFlowStatusRequesting:`Click "Allow" in the browser popup above`,permissionFlowAllowCamera:`Allow Access`,permissionFlowAllowMicrophone:`Allow Access`,permissionFlowRetry:`Try Again`,permissionFlowRecoveryTitle:`Allow access to continue`,permissionFlowRecoveryInstructions:`Open your browser settings and allow camera and microphone access, then try again.`,permissionFlowConnecting:`Setting up...`},es:{initializingCamera:`Inicializando cámara...`,grantPermissions:`Otorga permisos de cámara y micrófono cuando se solicite`,browserUnsupported:`Este navegador no es compatible`,browserUnsupportedDynamic:`{browser} ({version}) no es compatible, por favor usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedSafari:`Safari no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,browserUnsupportedFirefox:`Firefox no es compatible, usa <a href="https://www.google.com/chrome/" target="_blank">Chrome</a>`,retryCamera:`Reintentar Cámara`,cameraInUse:`Tu cámara está siendo usada por otra aplicación. Cierra otras apps que usen la cámara (Zoom, Teams, Discord) e intenta de nuevo.`,cameraNotFound:`No se detectó ninguna cámara. Conecta una cámara o revisa la configuración de tu dispositivo.`,cameraPermissionDenied:`Se denegó el acceso a la cámara. Permite el acceso a la cámara en la configuración de tu navegador e intenta de nuevo.`,cameraTimeout:`La cámara tardó demasiado en iniciar. Cierra otras apps que usen la cámara e intenta de nuevo.`,audioInUse:`Tu micrófono está siendo usado por otra aplicación. Cierra otras apps que usen el micrófono (Zoom, Teams, Discord) e intenta de nuevo.`,audioNotFound:`No se detectó ningún micrófono. Conecta un micrófono o revisa la configuración de tu dispositivo.`,audioPermissionDenied:`Se denegó el acceso al micrófono. Permite el acceso al micrófono en la configuración de tu navegador e intenta de nuevo.`,audioTimeout:`El micrófono tardó demasiado en iniciar. Cierra otras apps que usen el micrófono e intenta de nuevo.`,failedToStartAudio:`Error al iniciar el micrófono`,audioErrorTitle:`Micrófono no disponible`,audioErrorMessage:`No pudimos acceder a tu micrófono. Puede estar en uso por otra app como Zoom, Teams o Discord. Ciérrala e inténtalo de nuevo.`,audioErrorRetry:`Intentar de nuevo`,audioMissingTitle:`La grabación no tiene audio`,audioMissingMessage:`No pudimos capturar audio en esta grabación. Es posible que el micrófono se haya desconectado o que el navegador lo haya bloqueado. Verifica tu micrófono y vuelve a grabar.`,audioSilentTitle:`La grabación quedó en silencio`,audioSilentMessage:`No detectamos sonido durante la grabación. Verifica que tu micrófono esté funcionando y no esté silenciado por el sistema, luego vuelve a grabar.`,audioProcessingErrorTitle:`Error al procesar el audio`,audioProcessingErrorMessage:`No pudimos procesar el audio de esta grabación. Por favor vuelve a grabar.`,audioMissingRetry:`Grabar de nuevo`,audioWarningNoSignalTitle:`Sin señal del micrófono`,audioWarningNoSignalMessage:`No estamos detectando sonido. Verifica que tu micrófono esté activo.`,audioWarningLowSignalTitle:`Audio muy bajo`,audioWarningLowSignalMessage:`Acércate al micrófono o sube el volumen de entrada.`,audioWarningSpeakingMutedTitle:`Estás hablando muteado`,audioWarningSpeakingMutedMessage:`Activa el micrófono si quieres que tu voz se escuche en la grabación.`,audioWarningTrackEndedTitle:`Micrófono desconectado`,audioWarningTrackEndedMessage:`Se desconectó el micrófono. Reconéctalo antes de continuar.`,audioWarningNoChunksTitle:`Sin entrada del micrófono`,audioWarningNoChunksMessage:`No estamos recibiendo audio del micrófono. Revisa los permisos del navegador.`,audioWarningTrackMutedTitle:`Micrófono silenciado por el navegador`,audioWarningTrackMutedMessage:`El navegador silenció tu micrófono. Revisa la configuración del sitio.`,audioWarningDismiss:`Cerrar`,cameraErrorTitle:`Cámara no disponible`,cameraErrorMessage:`No pudimos acceder a tu cámara. Puede estar en uso por otra app o los permisos pueden estar denegados.`,browserErrorTitle:`Navegador no compatible`,browserErrorMessage:`Este navegador no es compatible. Por favor usa Chrome para la mejor experiencia.`,recordingCodecUnsupportedTitle:`Formato de grabación no compatible`,recordingCodecUnsupportedMessage:`Este dispositivo no puede usar el formato de video seleccionado. Cierra otras apps, actualiza Chrome si es posible y vuelve a grabar.`,recordingServerTranscodeFallbackTitle:`Finalizando en el dispositivo`,recordingServerTranscodeFallbackMessage:`Estamos finalizando el video en este dispositivo antes de subirlo. Mantén esta pestaña abierta.`,recordingTrackEndedTitle:`La cámara se detuvo durante la grabación`,recordingTrackEndedMessage:`La señal de la cámara terminó antes de finalizar la grabación. Verifica que la cámara siga conectada y vuelve a grabar.`,recordingFinalizeTimeoutTitle:`La grabación tardó demasiado en finalizar`,recordingFinalizeTimeoutMessage:`Es posible que este dispositivo tenga poca memoria o potencia de procesamiento. Cierra otras apps o pestañas del navegador y vuelve a grabar.`,recordingStateRaceTitle:`La grabación no inició correctamente`,recordingStateRaceMessage:`No se pudo finalizar la grabación porque no inició correctamente. Actualiza la página y vuelve a grabar.`,recordingNoFramesTitle:`No se capturó video`,recordingNoFramesMessage:`No pudimos recibir fotogramas de video de la cámara. Verifica la conexión de la cámara y vuelve a grabar.`,recordingUnsupportedTitle:`Grabación no disponible`,recordingUnsupportedMessage:`Este dispositivo o navegador no puede grabar video de forma estable ahora. Revisa tu conexión, actualiza Chrome si es posible o usa otro dispositivo.`,recordingPipelineRetry:`Grabar de nuevo`,genericErrorTitle:`Algo salió mal`,genericErrorMessage:`Ocurrió un error inesperado. Por favor intenta de nuevo.`,errorRetry:`Intentar de nuevo`,switchingDevice:`Cambiando dispositivo...`,recordingStartsIn:`La grabación comienza en...`,switchingSource:`Cambiando fuente...`,rec:`GRAB`,settings:`Configuración`,record:`Grabar`,stop:`Detener`,pause:`Pausar`,resume:`Reanudar`,mute:`Silenciar`,unmute:`Activar sonido`,switchSource:`Cambiar Fuente`,camera:`Cámara`,microphone:`Micrófono`,microphoneConnecting:`Conectando micrófono...`,minimumRecordingTimeNotReached:`Aun no cumples el tiempo minimo de grabacion`,processVideo:`Procesar Video`,processing:`Procesando...`,finishing:`Finalizando...`,uploading:`Subiendo...`,switchingCamera:`Cambiando cámara...`,switchingMicrophone:`Cambiando micrófono...`,failedToStartCamera:`Error al iniciar la cámara`,userInAnotherTab:`Usuario en otra pestaña`,download:`Descargar`,nativeCameraSelectVideo:`Seleccionar Video de la Galería`,nativeCameraRecordVideo:`Grabar con Cámara`,errorTitle:`Error de Configuración`,errorGeneric:`Ocurrió un error al cargar la configuración`,mobileOpenCamera:`Abrir Cámara`,mobileOpenCameraTitle:`Grabar un Video`,mobileOpenCameraDescription:`Toca el botón para comenzar a grabar`,mobileCloseCamera:`Cerrar`,mobilePermissionDenied:`Acceso a Cámara Denegado`,mobilePermissionDeniedDescription:`Por favor permite el acceso a la cámara en la configuración de tu navegador para grabar video.`,permissionFlowTitle:`Configurar tu Cámara`,permissionFlowCameraTitle:`Cámara y Micrófono`,permissionFlowMicrophoneTitle:`Cámara y Micrófono`,permissionFlowCameraLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowMicrophoneLabel:`Necesitamos acceso a tu cámara y micrófono para comenzar a grabar`,permissionFlowStatusPending:`Pendiente`,permissionFlowStatusGranted:`Listo`,permissionFlowStatusDenied:`Bloqueado`,permissionFlowStatusRequesting:`Haz clic en "Permitir" en el aviso del navegador`,permissionFlowAllowCamera:`Permitir Acceso`,permissionFlowAllowMicrophone:`Permitir Acceso`,permissionFlowRetry:`Reintentar`,permissionFlowRecoveryTitle:`Permite el acceso para continuar`,permissionFlowRecoveryInstructions:`Abre la configuración de tu navegador y permite el acceso a la cámara y micrófono, luego intenta de nuevo.`,permissionFlowConnecting:`Preparando...`}};var BT=class{constructor(e=`en`,t={}){this.lang=e,this.customTexts=t}setLang(e){this.lang=e}setCustomTexts(e){this.customTexts=e}t(e){return this.customTexts[e]?this.customTexts[e]:(zT[this.lang]||zT.en)[e]}getAll(){return{...zT[this.lang]||zT.en,...this.customTexts}}};let VT=new Map;function HT(e){e.style.position=`fixed`,e.style.top=`0`,e.style.left=`0`,e.style.width=`100vw`,e.style.height=`100vh`,e.style.height=`100dvh`,e.style.zIndex=`9999`,e.style.pointerEvents=`none`}function UT(e){e.style.pointerEvents=`auto`}function WT(e){e.style.pointerEvents=`none`}var GT=class{constructor(e=`vidtreo-portal-root`){this.portalContainer=null,this.contentWrapper=null,this.isRegistered=!1,this.containerId=e,this.instanceId=`portal-${Date.now()}-${Math.random().toString(36).slice(2,9)}`}get container(){return this.contentWrapper}get isActive(){return this.contentWrapper!==null&&this.portalContainer!==null}open(){let e=document.getElementById(this.containerId);return e||(e=document.createElement(`div`),e.id=this.containerId,HT(e),document.body.appendChild(e)),this.portalContainer=e,this.contentWrapper=document.createElement(`div`),this.contentWrapper.setAttribute(`data-portal-instance`,this.instanceId),this.contentWrapper.style.width=`100%`,this.contentWrapper.style.height=`100%`,this.portalContainer.appendChild(this.contentWrapper),this.registerInstance(),UT(e),this.contentWrapper}render(e){this.contentWrapper&&(this.contentWrapper.innerHTML=e)}querySelector(e){return this.contentWrapper?this.contentWrapper.querySelector(e):null}close(){this.contentWrapper&&=(this.contentWrapper.innerHTML=``,this.contentWrapper.remove(),null),this.unregisterInstance(),this.updatePortalContainerState()}destroy(){this.close(),this.portalContainer=null}registerInstance(){if(this.isRegistered)return;let e=VT.get(this.containerId);e||(e=new Set,VT.set(this.containerId,e)),e.add(this),this.isRegistered=!0}unregisterInstance(){if(!this.isRegistered)return;let e=VT.get(this.containerId);e&&(e.delete(this),e.size===0&&VT.delete(this.containerId)),this.isRegistered=!1}updatePortalContainerState(){if(!this.portalContainer)return;let e=VT.get(this.containerId);e&&e.size>0?UT(this.portalContainer):(WT(this.portalContainer),this.portalContainer.childNodes.length===0&&this.portalContainer.remove())}},KT=class{constructor(e){this.state={isModalOpen:!1,permissionRequested:!1,prevUploading:!1},this.escapeHandler=null,this.initCheckInterval=null,this.callbacks=e,this.portalManager=new GT}get canCloseModal(){let{recordingState:e,uploadProgress:t,transcodingProgress:n}=this.callbacks.getState();return!(e===`recording`||e===`countdown`||t!==null||n!==null)}get isModalOpen(){return this.state.isModalOpen}get portal(){return this.portalManager}openModal(){this.state.isModalOpen=!0,this.state.permissionRequested=!1,this.portalManager.open(),document.body.style.overflow=`hidden`,this.setupEscapeHandler(),this.callbacks.renderMobile(),this.requestCameraPreview()}closeModal(){this.canCloseModal&&(this.callbacks.stopPreview(),this.state.isModalOpen=!1,this.state.permissionRequested=!1,document.body.style.overflow=``,this.removeEscapeHandler(),this.portalManager.close(),this.callbacks.renderMobile())}checkUploadCompletion(e){let t=this.state.prevUploading,n=e!==null;this.state.prevUploading=n,t&&!n&&this.state.isModalOpen&&this.closeModal()}requestCameraPreview(){if(this.state.permissionRequested)return;let e=()=>{this.callbacks.isInitialized()?(this.state.permissionRequested=!0,this.callbacks.startPreview().catch(()=>{})):this.initCheckInterval=setTimeout(e,100)};e()}setupEscapeHandler(){this.escapeHandler=e=>{e.key===`Escape`&&this.canCloseModal&&this.closeModal()},document.addEventListener(`keydown`,this.escapeHandler)}removeEscapeHandler(){this.escapeHandler&&=(document.removeEventListener(`keydown`,this.escapeHandler),null)}destroy(){this.removeEscapeHandler(),this.portalManager.destroy(),document.body.style.overflow=``,this.initCheckInterval&&=(clearTimeout(this.initCheckInterval),null)}},qT=class{constructor(e,t){this.state={file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1,isConfigLoading:!0,error:null,transcodedBlob:null},this.handler=null,this.config=e,this.callbacks=t;let n=e.backendUrl||`https://core.vidtreo.com`,r=null;e.apiKey&&!e.demo&&(r=un.getInstance({apiKey:e.apiKey,backendUrl:n}));let i=new jS;this.handler=new by({apiKey:e.apiKey,backendUrl:n,maxRecordingTime:e.maxRecordingTime,maxFileSize:e.maxFileSize,userMetadata:e.userMetadata},r,i),e.apiKey&&!e.demo?(this.updateState({isConfigLoading:!0}),this.handler.preloadConfig().then(()=>this.updateState({isConfigLoading:!1})).catch(()=>{this.updateState({isConfigLoading:!1,error:`Failed to load settings`})})):this.updateState({isConfigLoading:!1})}updateState(e){this.state={...this.state,...e},this.callbacks.onStateChange()}getState(){return this.state}async handleFileSelect(e){if(this.updateState({error:null}),!this.handler)throw Error(`Handler not initialized`);try{let t=await this.handler.handleFileSelection(e);return this.updateState({file:t}),t}catch(e){let t=i(e),n=e instanceof Error?e:Error(t);throw this.updateState({error:t}),this.callbacks.onError?.(n),n}}async processAndUpload(e){let t=e||this.state.file;if(!(t&&this.handler))return;let n=this.config.demo;try{if(this.updateState({isTranscoding:!0,transcodingProgress:0,error:null}),n){let e=await vy(t.file,Xt,e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)});this.updateState({transcodedBlob:e.blob,isTranscoding:!1,transcodingProgress:null})}else{let e=await this.handler.processAndUpload(e=>{this.updateState({transcodingProgress:e}),this.callbacks.onTranscodingProgress?.(e)},e=>{this.updateState({uploadProgress:e}),this.callbacks.onUploadProgress?.(e)});this.updateState({file:null,transcodingProgress:null,uploadProgress:null,isTranscoding:!1}),this.callbacks.onUploadComplete?.({recordingId:e.recordingId||``,uploadUrl:e.uploadUrl||``})}}catch(e){let t=i(e),r=e instanceof Error?e:Error(t);this.updateState({error:t,isTranscoding:!1,transcodingProgress:null,uploadProgress:null,transcodedBlob:null}),this.callbacks.onError?.(r),n||this.callbacks.onUploadError?.(r)}}downloadVideo(){if(!this.state.transcodedBlob)return;let e=URL.createObjectURL(this.state.transcodedBlob),t=document.createElement(`a`);t.href=e,t.download=`recording-${Date.now()}.mp4`,document.body.appendChild(t),t.click(),document.body.removeChild(t),URL.revokeObjectURL(e)}reset(){this.updateState({file:null,transcodingProgress:null,uploadProgress:null,error:null,isTranscoding:!1,transcodedBlob:null})}destroy(){this.handler&&this.handler.cancel(),this.handler=null}};function JT(e){return{preview:{initializingCamera:e.initializingCamera,grantPermissions:e.grantPermissions,browserUnsupported:e.browserUnsupported,browserUnsupportedDynamic:e.browserUnsupportedDynamic,browserUnsupportedSafari:e.browserUnsupportedSafari,browserUnsupportedFirefox:e.browserUnsupportedFirefox,retryCamera:e.retryCamera,cameraInUse:e.cameraInUse,cameraNotFound:e.cameraNotFound,cameraPermissionDenied:e.cameraPermissionDenied,cameraTimeout:e.cameraTimeout,failedToStartCamera:e.failedToStartCamera,audioInUse:e.audioInUse,audioNotFound:e.audioNotFound,audioPermissionDenied:e.audioPermissionDenied,audioTimeout:e.audioTimeout,failedToStartAudio:e.failedToStartAudio,switchingDevice:e.switchingDevice,recordingStartsIn:e.recordingStartsIn,rec:e.rec},buttons:{settings:e.settings,record:e.record,stop:e.stop,minimumRecordingTimeNotReached:e.minimumRecordingTimeNotReached,pause:e.pause,resume:e.resume,mute:e.mute,unmute:e.unmute,switchSource:e.switchSource,download:e.download,microphoneConnecting:e.microphoneConnecting},settings:{settings:e.settings,camera:e.camera,microphone:e.microphone}}}var YT=class{constructor(e){if(this.proxyEndpoint=e.proxyEndpoint,this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);this.service=new jS}uploadVideo(e,t){if(this.proxyEndpoint)throw Error(`Proxy mode not yet implemented`);return this.service.uploadVideo(e,t)}},XT=`:root{--vidtreo-background:0 0% 100%;--vidtreo-foreground:0 0% 3.9%;--vidtreo-card:0 0% 100%;--vidtreo-card-foreground:0 0% 3.9%;--vidtreo-primary:0 0% 9%;--vidtreo-primary-foreground:0 0% 98%;--vidtreo-secondary:0 0% 96.1%;--vidtreo-secondary-foreground:0 0% 9%;--vidtreo-muted:0 0% 96.1%;--vidtreo-muted-foreground:0 0% 45.1%;--vidtreo-accent:0 0% 96.1%;--vidtreo-accent-foreground:0 0% 9%;--vidtreo-destructive:0 84.2% 60.2%;--vidtreo-destructive-foreground:0 0% 98%;--vidtreo-border:0 0% 89.8%;--vidtreo-input:0 0% 89.8%;--vidtreo-ring:0 0% 3.9%;--vidtreo-radius:.5rem;--vidtreo-preview-bg:0 0% 0%;--vidtreo-z-modal-overlay:9999;--vidtreo-z-settings-panel:200;--vidtreo-z-error-overlay:100;--vidtreo-z-countdown-overlay:20;--vidtreo-z-progress-overlay:20;--vidtreo-z-controls:10}.vidtreo-preview-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:layout style;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:visible;transform:translateZ(0)}.vidtreo-preview-container:before{display:none}@media (width>=768px){.vidtreo-preview-container{aspect-ratio:16/9}}.vidtreo-camera-area{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;contain:layout style paint;backface-visibility:hidden;isolation:isolate;will-change:auto;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:relative;transform:translateZ(0)}.vidtreo-source-transition-overlay{z-index:var(--vidtreo-z-error-overlay);backdrop-filter:blur(4px);contain:layout style paint;backface-visibility:hidden;will-change:opacity;background:#000000b3;border-radius:0;flex-direction:column;justify-content:center;align-items:center;transition:opacity .3s;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-source-transition-overlay.vidtreo-active{animation:.2s vidtreo-fadeIn;display:flex}@keyframes vidtreo-fadeIn{0%{opacity:0}to{opacity:1}}.vidtreo-transition-spinner{border:4px solid #ffffff4d;border-top-color:#667eea;border-radius:50%;width:40px;height:40px;margin-bottom:12px;animation:.8s linear infinite vidtreo-spin}@keyframes vidtreo-spin{to{transform:rotate(360deg)}}.vidtreo-transition-message{color:#fff;text-align:center;font-size:14px;font-weight:500}.vidtreo-camera-area.vidtreo-active{display:block}.vidtreo-preview-skeleton{z-index:var(--vidtreo-z-controls);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;flex-direction:column;justify-content:center;align-items:center;gap:1rem;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-skeleton-spinner{border:4px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:40px;height:40px;animation:.8s linear infinite vidtreo-spin}.vidtreo-skeleton-text{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-video-preview{object-fit:cover;will-change:auto;backface-visibility:hidden;background:#000;border-radius:0;width:100%;height:100%;transition:opacity .3s,transform .3s;display:block;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-video-preview-skeleton{z-index:2;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border-radius:0;width:100%;height:100%;position:absolute;inset:0;overflow:hidden;transform:translateZ(0)}.vidtreo-skeleton-shimmer{background:linear-gradient(90deg, hsl(var(--vidtreo-muted)) 0%, hsl(var(--vidtreo-muted) / .5) 50%, hsl(var(--vidtreo-muted)) 100%);background-size:200% 100%;animation:1.5s ease-in-out infinite vidtreo-shimmer;position:absolute;inset:0}@keyframes vidtreo-shimmer{0%{background-position:-200% 0}to{background-position:200% 0}}.vidtreo-video-preview-skeleton.vidtreo-hidden{opacity:0;pointer-events:none;transition:opacity .3s}.vidtreo-video-preview.vidtreo-screen-share{object-fit:cover}.vidtreo-video-preview.vidtreo-transitioning{opacity:.5;transform:scale(.98)}.vidtreo-countdown-overlay{z-index:var(--vidtreo-z-countdown-overlay);contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000000f2;border-radius:0;justify-content:center;align-items:center;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-countdown-overlay.vidtreo-active{display:flex}.vidtreo-countdown-content{flex-direction:column;align-items:center;gap:1rem;display:flex}.vidtreo-countdown-number{color:#fff;font-size:9rem;font-weight:700;animation:.3s vidtreo-zoomIn}@keyframes vidtreo-zoomIn{0%{opacity:0;transform:scale(.5)}to{opacity:1;transform:scale(1)}}.vidtreo-countdown-text{color:#fff;margin-top:1rem;font-size:.875rem;font-weight:500}.vidtreo-settings-panel{z-index:var(--vidtreo-z-settings-panel);contain:layout style paint;backface-visibility:hidden;background:#0006;border:none;border-radius:.75rem;flex-direction:column;width:90%;margin-left:-47%;padding:.625rem;display:none;overflow:hidden;transform:translateZ(0);position:absolute!important;bottom:4rem!important;left:50%!important}.vidtreo-settings-panel.vidtreo-active{display:flex}.vidtreo-settings-content{will-change:transform;backface-visibility:hidden;flex-direction:column;width:100%;display:flex;transform:translateZ(0)}.vidtreo-settings-content.vidtreo-slide-right{animation:.3s vidtreo-slideRight}.vidtreo-settings-content.vidtreo-slide-left{animation:.3s vidtreo-slideLeft}.vidtreo-settings-content.vidtreo-slide-none{will-change:auto;animation:none}@keyframes vidtreo-slideIn{0%{opacity:0;transform:translateY(1rem)}to{opacity:1;transform:translateY(0)}}@keyframes vidtreo-slideRight{0%{opacity:0;transform:translate(-100%)}to{opacity:1;transform:translate(0)}}@keyframes vidtreo-slideLeft{0%{opacity:0;transform:translate(100%)}to{opacity:1;transform:translate(0)}}.vidtreo-settings-header{color:#fff;cursor:pointer;text-align:left;background:0 0;border:none;align-items:center;gap:.75rem;width:100%;margin-bottom:1rem;padding:0;display:flex}.vidtreo-settings-back-icon{color:#fff;flex-shrink:0}.vidtreo-settings-title{color:#fff;margin:0;font-size:.875rem;font-weight:600}.vidtreo-device-options-container{flex-direction:column;gap:.375rem;display:flex}.vidtreo-device-option-nav{cursor:pointer;color:#fff;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:1rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option-nav:hover{background:#fff3}.vidtreo-device-option-nav-content{flex-shrink:0;align-items:center;gap:.75rem;display:flex}.vidtreo-device-option-nav-label{color:#fff;font-size:.875rem;font-weight:500}.vidtreo-device-option-nav-value{flex:1;justify-content:flex-end;align-items:center;gap:.5rem;min-width:0;display:flex}.vidtreo-device-option-nav-value-text{color:#fffc;text-overflow:ellipsis;white-space:nowrap;text-align:right;flex:1;font-size:.875rem;overflow:hidden}.vidtreo-device-option-nav-chevron{color:#fff;font-size:1.25rem;line-height:1}.vidtreo-device-list{flex-direction:column;gap:0;max-height:200px;display:flex;overflow-y:auto}.vidtreo-device-list::-webkit-scrollbar{width:4px}.vidtreo-device-list::-webkit-scrollbar-track{background:0 0}.vidtreo-device-list::-webkit-scrollbar-thumb{background:#fff3;border-radius:2px}.vidtreo-device-list::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.vidtreo-device-option{cursor:pointer;color:#fff;text-align:left;background:0 0;border:none;border-radius:.5rem;align-items:center;gap:.75rem;width:100%;padding:.5rem .75rem;transition:background-color .2s;display:flex}.vidtreo-device-option:hover{background:#fff3}.vidtreo-device-option-check-container{flex-shrink:0;justify-content:center;align-items:center;width:20px;height:20px;display:flex}.vidtreo-device-checkmark-placeholder{flex-shrink:0;width:20px;height:20px}.vidtreo-device-checkmark{color:#fff;flex-shrink:0}.vidtreo-device-option-label{color:#fff;flex:1;font-size:.875rem}.vidtreo-device-empty{color:#fff9;text-align:center;padding:1rem 0;font-size:.875rem}.vidtreo-audio-level-bars{height:1rem;z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;align-items:center;gap:.125rem;transform:translateZ(0);display:flex!important;position:absolute!important;bottom:.75rem!important;right:.75rem!important}@media (width>=768px){.vidtreo-audio-level-bars{height:1.25rem}}.vidtreo-audio-level-bar{background:#ffffff80;border-radius:9999px;align-self:flex-end;width:.125rem;transition:all .1s}.vidtreo-recording-controls{z-index:var(--vidtreo-z-controls);contain:layout style;will-change:auto;backface-visibility:hidden;position:absolute!important;bottom:12px!important;left:50%!important;transform:translate(-50%)translateZ(0)!important}.vidtreo-recording-controls-row{will-change:auto;justify-content:center;align-items:center;gap:.5rem;display:flex;transform:translateZ(0)}.vidtreo-recording-timer-row{justify-content:space-between;align-items:center;gap:.5rem;display:flex}.vidtreo-recording-timer-badge{z-index:var(--vidtreo-z-controls);contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;right:.75rem!important}.vidtreo-recording-dot-small{background:hsl(var(--vidtreo-destructive));border-radius:50%;width:.375rem;height:.375rem;animation:1.5s ease-in-out infinite vidtreo-pulse}.vidtreo-recording-timer-text{color:#fff;font-family:monospace;font-size:.75rem;font-weight:500}.vidtreo-control-buttons-row{will-change:auto;justify-content:center;align-items:center;gap:.375rem;height:auto;min-height:2rem;display:flex;transform:translateZ(0)}@media (width>=768px){.vidtreo-control-buttons-row{min-height:2.25rem}}.vidtreo-control-button{cursor:pointer;color:#fff;box-sizing:border-box;vertical-align:top;contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;width:2rem;height:2rem;min-height:2rem;max-height:2rem;margin:0;padding:.25rem;transition:background-color .2s;display:inline-flex;position:relative;transform:translateZ(0)}.vidtreo-control-button:before{content:"";z-index:0;border-radius:9999px;transition:background-color .2s;position:absolute;inset:.25rem}.vidtreo-control-button svg{color:inherit;z-index:1;flex-shrink:0;position:relative;width:22px!important;height:22px!important}@media (width>=768px){.vidtreo-control-button svg{width:24px!important;height:24px!important}.vidtreo-control-button{width:2.25rem;height:2.25rem;min-height:2.25rem;max-height:2.25rem}}.vidtreo-control-button:hover:not(:disabled):before{background:#fff3}.vidtreo-control-button:disabled{opacity:.5;cursor:not-allowed}.vidtreo-control-button.vidtreo-muted:before{background:#0000004d}.vidtreo-control-button.vidtreo-muted:hover:not(:disabled):before{background:#fff3}.vidtreo-record-button{background:hsl(var(--vidtreo-destructive));height:2rem;min-height:2rem;max-height:2rem;color:hsl(var(--vidtreo-destructive-foreground));box-sizing:border-box;vertical-align:top;cursor:pointer;border:none;border-radius:9999px;flex-shrink:0;justify-content:center;align-items:center;gap:.375rem;width:auto;margin:0;padding:0 .75rem;font-size:.75rem;font-weight:500;line-height:1;transition:background-color .2s,filter .2s;display:inline-flex}@media (width>=768px){.vidtreo-record-button{height:2.25rem;min-height:2.25rem;max-height:2.25rem;font-size:.875rem}}.vidtreo-record-button:hover:not(:disabled){filter:brightness(.85)}.vidtreo-record-button.vidtreo-stop-button-locked{opacity:.5;cursor:not-allowed;filter:none}.vidtreo-record-button.vidtreo-stop-button-locked:hover{filter:none}#startButton.vidtreo-record-button{animation:2s ease-in-out infinite vidtreo-record-glow-pulse}@keyframes vidtreo-record-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ef444466,0 0 16px 4px #ef444433}50%{box-shadow:0 0 16px 4px #ef444499,0 0 32px 8px #ef44444d}}#startButton.vidtreo-record-button:hover:not(:disabled){animation-play-state:paused;box-shadow:0 0 20px 6px #ef4444b3,0 0 40px 10px #ef444459}.vidtreo-rec-indicator-top{contain:layout style paint;will-change:auto;backface-visibility:hidden;background:#0000004d;border:none;border-radius:9999px;align-items:center;gap:.375rem;padding:.25rem .5rem;transform:translateZ(0);box-shadow:0 1px 3px #0000001a,0 1px 2px -1px #0000001a;display:flex!important;position:absolute!important;top:.75rem!important;left:.75rem!important}.vidtreo-rec-indicator-top span{color:#fff;font-size:.75rem;font-weight:500}.vidtreo-start-camera-area{text-align:center;cursor:pointer;z-index:1;contain:layout style paint;backface-visibility:hidden;will-change:auto;background:#000;border:none;border-radius:0;flex-direction:column;justify-content:center;align-items:center;padding:40px;transition:all .3s;display:flex;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-start-camera-area:hover:not(.vidtreo-loading){background:#000}.vidtreo-start-camera-area.vidtreo-loading{cursor:wait;opacity:.7}.vidtreo-start-camera-area.vidtreo-loading .vidtreo-camera-text{color:#fff;opacity:.7}.vidtreo-camera-icon{color:#fff;justify-content:center;margin-bottom:16px;font-size:48px;display:flex}.vidtreo-camera-text{color:#fff;margin-bottom:8px;font-weight:600}.vidtreo-camera-text a{color:#3b82f6;text-decoration:underline}.vidtreo-camera-text a:hover{color:#2563eb}.vidtreo-camera-hint{color:#fff;opacity:.8;font-size:12px}@keyframes vidtreo-pulse{0%,to{opacity:1}50%{opacity:.3}}.vidtreo-progress{margin-top:20px;display:none}.vidtreo-progress.vidtreo-active{display:block}.vidtreo-progress-bar{background:#e0e0e0;border-radius:4px;width:100%;height:8px;margin-bottom:8px;overflow:hidden}.vidtreo-progress-fill{background:linear-gradient(90deg,#667eea 0%,#764ba2 100%);width:0%;height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:#fff;font-size:14px}.vidtreo-error{color:#fff;text-align:center;z-index:var(--vidtreo-z-error-overlay);word-wrap:break-word;background:#dc2626;border:none;border-radius:.5rem;max-width:90%;padding:1rem 1.25rem;font-size:.875rem;font-weight:500;display:none;position:absolute;top:.75rem;left:50%;transform:translate(-50%);box-shadow:0 4px 6px -1px #0000001a,0 2px 4px -2px #0000001a}.vidtreo-error.vidtreo-active{animation:.3s ease-out vidtreo-error-fade-in-slide-down;display:block}@keyframes vidtreo-error-fade-in-slide-down{0%{opacity:0;transform:translate(-50%)translateY(-1rem)}to{opacity:1;transform:translate(-50%)translateY(0)}}.vidtreo-upload-progress{margin-top:20px;display:none}.vidtreo-upload-progress.vidtreo-active{display:block}.vidtreo-preview-container .vidtreo-upload-progress{margin-top:0}.vidtreo-upload-status{border-radius:8px;margin-top:20px;padding:16px;display:none}.vidtreo-upload-status.vidtreo-active{display:block}.vidtreo-upload-status.vidtreo-success{color:#22543d;background:#f0f9ff;border:2px solid #48bb78}.vidtreo-upload-status.vidtreo-error{color:#c33;background:#fee;border:2px solid #fcc}.vidtreo-upload-status-text{font-size:14px;font-weight:500}.vidtreo-preview-error{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));contain:strict;will-change:auto;backface-visibility:hidden;isolation:isolate;border:none;border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden;transform:translateZ(0)}@media (width>=768px){.vidtreo-preview-error{aspect-ratio:16/9}}.vidtreo-error-content{text-align:center;color:#fff;flex-direction:column;justify-content:center;align-items:center;gap:1rem;max-width:400px;padding:2rem;display:flex}.vidtreo-error-icon{font-size:3rem;line-height:1}.vidtreo-error-title{font-size:1.25rem;font-weight:600;line-height:1.2}.vidtreo-error-message{opacity:.9;word-break:break-word;font-size:.875rem;line-height:1.5}.vidtreo-error-config{text-align:left;border-top:1px solid #fff3;width:100%;margin-top:1.5rem;padding-top:1.5rem}.vidtreo-error-config-title{color:#fff;margin-bottom:.75rem;font-size:.875rem;font-weight:600}.vidtreo-error-config-item{color:#ffffffd9;margin-bottom:.5rem;font-size:.8125rem;line-height:1.6}.vidtreo-error-config-item code{color:#fff;background:#ffffff26;border-radius:.25rem;padding:.125rem .375rem;font-family:monospace;font-size:.75rem}.vidtreo-error-retry{background:hsl(var(--vidtreo-destructive));color:hsl(var(--vidtreo-destructive-foreground));cursor:pointer;border:none;border-radius:.375rem;margin-top:.5rem;padding:.5rem 1rem;font-size:.875rem;font-weight:500;transition:filter .2s}.vidtreo-error-retry:hover:not(:disabled){filter:brightness(.85)}.vidtreo-error-retry:disabled{opacity:.5;cursor:not-allowed}.vidtreo-error-overlay{background:hsl(var(--vidtreo-preview-bg));z-index:var(--vidtreo-z-error-overlay);justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-native-camera-container{aspect-ratio:9/16;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;display:flex;position:relative;overflow:hidden}@media (width>=768px){.vidtreo-native-camera-container{aspect-ratio:16/9}}.vidtreo-native-camera-container:has(.vidtreo-native-camera-preview-container){background:0 0}.vidtreo-config-loading-indicator{z-index:var(--vidtreo-z-controls);position:absolute;top:8px;right:8px}.vidtreo-spinner-small{border:2px solid #ffffff4d;border-top-color:#fff;border-radius:50%;width:16px;height:16px;animation:.6s linear infinite spin}.vidtreo-native-camera-empty-state{flex-direction:column;justify-content:center;align-items:center;gap:16px;width:100%;height:100%;padding:24px;display:flex;position:relative}.vidtreo-native-camera-buttons{flex-direction:column;gap:12px;width:100%;max-width:300px;display:flex}.vidtreo-native-camera-process-button,.vidtreo-native-camera-download-button{z-index:30;position:absolute;bottom:24px;left:50%;transform:translate(-50%)}.vidtreo-native-camera-process-button .vidtreo-btn,.vidtreo-native-camera-download-button .vidtreo-btn{min-width:200px}.vidtreo-btn{border-radius:var(--vidtreo-radius);cursor:pointer;border:none;padding:12px 24px;font-size:1rem;font-weight:500;transition:all .2s}.vidtreo-btn:disabled{opacity:.5;cursor:not-allowed}.vidtreo-btn-primary{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground))}.vidtreo-btn-primary:hover:not(:disabled){filter:brightness(.9)}.vidtreo-btn-secondary{background:hsl(var(--vidtreo-secondary));color:hsl(var(--vidtreo-secondary-foreground));border:1px solid hsl(var(--vidtreo-border))}.vidtreo-btn-secondary:hover:not(:disabled){background:hsl(var(--vidtreo-accent))}.vidtreo-transcoding-progress{width:100%;max-width:400px;padding:16px}.vidtreo-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-fill{background:hsl(var(--vidtreo-primary));height:100%;transition:width .3s}.vidtreo-progress-text{text-align:center;color:hsl(var(--vidtreo-foreground));margin-top:8px;font-size:.875rem}.vidtreo-native-camera-preview-container{background:0 0;justify-content:center;align-items:center;width:100%;height:100%;display:flex;position:relative}.vidtreo-native-camera-preview-image{object-fit:contain;width:100%;height:100%;display:block}.vidtreo-progress-overlay{backdrop-filter:blur(4px);width:100%;height:100%;z-index:var(--vidtreo-z-progress-overlay);pointer-events:auto;background:#000000b3;flex-direction:column;justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-progress-overlay .vidtreo-transcoding-progress,.vidtreo-progress-overlay .vidtreo-upload-progress{pointer-events:auto;background:0 0;flex-direction:column;align-items:center;gap:12px;width:90%;max-width:400px;padding:0;display:flex;position:relative}.vidtreo-progress-overlay .vidtreo-progress-bar,.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-text,.vidtreo-progress-overlay .vidtreo-upload-progress-text{text-align:center;color:#fff;margin-top:0;font-size:.875rem;font-weight:500}.vidtreo-progress-overlay .vidtreo-upload-progress-bar{background:#fff3;border-radius:4px;width:100%;height:8px;overflow:hidden}.vidtreo-progress-overlay .vidtreo-upload-progress-fill{background:#fff;height:100%;transition:width .3s}.vidtreo-progress-overlay .vidtreo-progress-indeterminate{background:linear-gradient(90deg,#0000 0%,#fff 50%,#0000 100%) 0 0/200% 100%;width:100%;animation:1.5s ease-in-out infinite vidtreo-progress-indeterminate}@keyframes vidtreo-progress-indeterminate{0%{background-position:200% 0}to{background-position:-200% 0}}.vidtreo-mobile-web-recorder{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;width:100%;height:100%;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif}.vidtreo-camera-area button,.vidtreo-camera-area input,.vidtreo-camera-area select,.vidtreo-camera-area textarea,.vidtreo-mobile-web-recorder button,.vidtreo-mobile-web-recorder input,.vidtreo-mobile-web-recorder select,.vidtreo-mobile-web-recorder textarea,.vidtreo-permission-flow button{font-family:inherit}.vidtreo-mobile-landing-container{aspect-ratio:4/3;background:hsl(var(--vidtreo-preview-bg));border-radius:0;justify-content:center;align-items:center;width:100%;min-height:100%;max-height:100%;display:flex;position:relative;overflow:hidden}.vidtreo-mobile-landing-content{text-align:center;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;padding:2rem;display:flex}.vidtreo-mobile-landing-title{color:#fff;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-mobile-landing-description{color:#ffffffbf;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-mobile-open-camera-btn{border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}@keyframes vidtreo-btn-glow-pulse{0%,to{box-shadow:0 0 8px 2px #ffffff4d,0 0 16px 4px #ffffff26}50%{box-shadow:0 0 16px 4px #ffffff80,0 0 32px 8px #ffffff40}}.vidtreo-mobile-open-camera-btn:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-mobile-open-camera-btn:active:not(:disabled){transform:scale(.98)}.vidtreo-mobile-open-camera-btn:disabled{box-shadow:none;animation:none}#vidtreo-portal-root{z-index:9999;pointer-events:none;width:100vw;height:100dvh;position:fixed;top:0;left:0}#vidtreo-portal-root>*{pointer-events:auto}.vidtreo-mobile-modal-overlay{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;width:100vw;height:100dvh;z-index:var(--vidtreo-z-modal-overlay);background:#000;flex-direction:column;height:-webkit-fill-available;animation:.3s ease-out vidtreo-modal-fade-in;display:flex;position:fixed;inset:0}@keyframes vidtreo-modal-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-mobile-modal-header{padding:.75rem;padding-top:calc(.75rem + var(--vidtreo-safe-top,0px));z-index:var(--vidtreo-z-error-overlay);pointer-events:none;justify-content:center;display:flex;position:absolute;top:0;left:0;right:0}.vidtreo-mobile-modal-close-btn{color:#ffffffe6;cursor:pointer;pointer-events:auto;backdrop-filter:blur(4px);background:#00000080;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.375rem;height:2rem;padding:0 .75rem;font-size:.75rem;font-weight:500;transition:all .2s;display:flex}.vidtreo-mobile-modal-close-btn:hover:not(:disabled){background:#000000b3}.vidtreo-mobile-modal-close-btn:disabled{opacity:.3;cursor:not-allowed}.vidtreo-mobile-modal-content{width:100%;height:100%;padding-top:var(--vidtreo-safe-top,0px);padding-bottom:var(--vidtreo-safe-bottom,0px);padding-left:var(--vidtreo-safe-left,0px);padding-right:var(--vidtreo-safe-right,0px);flex-direction:column;flex:1;display:flex;position:relative}.vidtreo-mobile-recorder-content{--vidtreo-safe-top:0px;--vidtreo-safe-bottom:0px;--vidtreo-safe-left:0px;--vidtreo-safe-right:0px;flex-direction:column;width:100%;height:100%;display:flex;position:relative}.vidtreo-mobile-recorder-content .vidtreo-preview-container{aspect-ratio:unset;flex:1;width:100%;height:100%}.vidtreo-mobile-recorder-content .vidtreo-video-preview{object-fit:cover}.vidtreo-mobile-preview{flex:1;aspect-ratio:unset!important;height:100%!important}.vidtreo-mobile-recorder-content .vidtreo-recording-controls{bottom:calc(24px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-audio-level-bars{bottom:calc(12px + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-settings-panel{bottom:calc(7rem + var(--vidtreo-safe-bottom,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-rec-indicator-top,.vidtreo-mobile-recorder-content .vidtreo-recording-timer-badge{contain:layout style;height:2rem;padding:0 .75rem;top:calc(.75rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-recording-timer-text{white-space:nowrap;color:#fff;min-width:3rem;font-size:.875rem;display:inline-block}.vidtreo-mobile-recorder-content .vidtreo-error{top:calc(3.5rem + var(--vidtreo-safe-top,0px))!important}.vidtreo-mobile-recorder-content .vidtreo-control-buttons-row{gap:.75rem;min-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button{width:4rem;height:4rem;min-height:4rem;max-height:4rem}.vidtreo-mobile-recorder-content .vidtreo-control-button svg{width:1.5rem;height:1.5rem}.vidtreo-mobile-recorder-content .vidtreo-record-button{gap:.5rem;height:4rem;min-height:4rem;max-height:4rem;padding:0 1.5rem;font-size:1rem}.vidtreo-mobile-recorder-content .vidtreo-record-button svg{width:1.5rem;height:1.5rem}.vidtreo-permission-flow{z-index:var(--vidtreo-z-modal-overlay);contain:layout style paint;backface-visibility:hidden;-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;background:#000;flex-direction:column;justify-content:center;align-items:center;gap:1.25rem;font-family:-apple-system,BlinkMacSystemFont,SF Pro Display,SF Pro Text,system-ui,sans-serif;display:none;position:absolute;inset:0;transform:translateZ(0)}.vidtreo-permission-flow.vidtreo-active{animation:.4s cubic-bezier(.2,0,0,1) vidtreo-fadeIn;display:flex}.vidtreo-permission-flow-title{color:#fff;text-align:center;margin:0;font-size:1.25rem;font-weight:600;line-height:1.3}.vidtreo-permission-flow-subtitle{color:#ffffffbf;text-align:center;letter-spacing:-.005em;max-width:280px;margin:0;font-size:.875rem;line-height:1.5}.vidtreo-permission-flow-action{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;margin-top:.5rem;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-action:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-action:active:not(:disabled){transform:scale(.98)}.vidtreo-permission-flow-action:disabled{opacity:.5;cursor:not-allowed;box-shadow:none;animation:none}.vidtreo-permission-flow-action--requesting{opacity:.55;cursor:wait;box-shadow:none;animation:none}@keyframes vidtreo-spinner-rotate{to{transform:rotate(360deg)}}.vidtreo-permission-flow-spinner{border:2px solid #ffffff4d;border-top-color:hsl(var(--vidtreo-primary-foreground));border-radius:50%;flex-shrink:0;width:1.125rem;height:1.125rem;animation:.8s linear infinite vidtreo-spinner-rotate;display:inline-block}.vidtreo-permission-flow-spinner--large{border-width:3px;width:2.5rem;height:2.5rem}.vidtreo-permission-flow-recovery{text-align:center;flex-direction:column;align-items:center;gap:1.25rem;max-width:280px;display:flex}.vidtreo-permission-flow-recovery-text{color:#fff6;letter-spacing:-.005em;margin:0;font-size:.75rem;line-height:1.6}.vidtreo-permission-flow-retry{background:hsl(var(--vidtreo-primary));color:hsl(var(--vidtreo-primary-foreground));cursor:pointer;letter-spacing:-.01em;border:none;border-radius:9999px;justify-content:center;align-items:center;gap:.625rem;min-width:200px;padding:.875rem 1.75rem;font-size:1rem;font-weight:600;transition:all .2s;animation:2s ease-in-out infinite vidtreo-btn-glow-pulse;display:inline-flex}.vidtreo-permission-flow-retry:hover:not(:disabled){animation-play-state:paused;transform:scale(1.02);box-shadow:0 0 20px 6px #fff9,0 0 40px 10px #ffffff4d}.vidtreo-permission-flow-retry:active:not(:disabled){transform:scale(.98)}@keyframes vidtreo-fadeOut{0%{opacity:1}to{opacity:0}}.vidtreo-permission-flow.vidtreo-permission-flow--fading{pointer-events:none;animation:.6s ease-out forwards vidtreo-fadeOut}.vidtreo-recovery-guide{width:100%;max-width:280px;margin:0 auto;position:relative}.vidtreo-recovery-guide:after{content:"";z-index:20;pointer-events:none;background:linear-gradient(#0000 0%,#000 100%);height:60px;position:absolute;bottom:0;left:0;right:0}.vidtreo-recovery-guide:before{content:"";z-index:20;pointer-events:none;background:linear-gradient(90deg,#0000 0%,#000 100%);width:50px;position:absolute;top:0;bottom:0;right:0}.vidtreo-recovery-guide-browser{background:#161616;border-top:1px solid #ffffff1a;border-left:1px solid #ffffff1a;border-radius:10px 0 0;animation:.5s vidtreo-fadeIn;position:relative;overflow:hidden}.vidtreo-recovery-guide-titlebar{z-index:3;background:#1e1e1e;border-bottom:1px solid #ffffff0f;align-items:center;gap:8px;padding:8px 10px;display:flex;position:relative}.vidtreo-recovery-guide-dots{flex-shrink:0;gap:5px;display:flex}.vidtreo-recovery-guide-dot{border-radius:50%;width:8px;height:8px}.vidtreo-recovery-guide-dot--close{background:#ff5f57}.vidtreo-recovery-guide-dot--min{background:#febc2e}.vidtreo-recovery-guide-dot--max{background:#28c840}.vidtreo-recovery-guide-addressbar{background:#2a2a2a;border-radius:5px;flex:1;align-items:center;gap:5px;min-width:0;padding:4px 8px;display:flex}.vidtreo-recovery-guide-lock{color:#ffffff80;flex-shrink:0;align-items:center;animation:7s ease-in-out infinite vidtreo-lock-pulse;display:flex}.vidtreo-recovery-guide-lock-svg{display:block}.vidtreo-recovery-guide-url{color:#ffffff80;white-space:nowrap;text-overflow:ellipsis;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;overflow:hidden}.vidtreo-recovery-guide-cursor{z-index:40;pointer-events:none;filter:drop-shadow(0 2px 4px #0009);animation:7s ease-in-out infinite vidtreo-cursor-move;position:absolute;top:12px;left:62px}.vidtreo-recovery-guide-cursor-svg{display:block}.vidtreo-recovery-guide-browser-bg{background:#161616;height:110px}.vidtreo-recovery-guide-popover{z-index:30;background:#252525;border:1px solid #ffffff1a;border-radius:10px;padding:8px 12px 12px;animation:7s ease-in-out infinite vidtreo-popover-reveal;position:absolute;top:34px;left:12px;right:12px;box-shadow:0 8px 30px #0009,0 2px 8px #0006,0 0 0 1px #ffffff0f}.vidtreo-recovery-guide-popover-header{color:#ffffffd9;white-space:nowrap;text-overflow:ellipsis;text-align:left;padding-bottom:6px;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.65rem;font-weight:600;overflow:hidden}.vidtreo-recovery-guide-popover-divider{background:#ffffff14;height:1px}.vidtreo-recovery-guide-perm-row{justify-content:space-between;align-items:center;padding:7px 0;display:flex}.vidtreo-recovery-guide-perm-row+.vidtreo-recovery-guide-perm-row{border-top:1px solid #ffffff0f}.vidtreo-recovery-guide-perm-group{align-items:center;gap:8px;display:flex}.vidtreo-recovery-guide-perm-icon{flex-shrink:0;width:14px;height:14px;position:relative}.vidtreo-recovery-guide-icon-off,.vidtreo-recovery-guide-icon-on{justify-content:center;align-items:center;display:flex;position:absolute;inset:0}.vidtreo-recovery-guide-icon-off{color:#fff6;animation:7s ease-in-out infinite vidtreo-icon-hide}.vidtreo-recovery-guide-icon-on{color:#34d399;animation:7s ease-in-out infinite vidtreo-icon-show}.vidtreo-recovery-guide-perm-label{color:#ffffffd9;font-family:-apple-system,BlinkMacSystemFont,system-ui,sans-serif;font-size:.7rem}.vidtreo-recovery-guide-switch{flex-shrink:0;width:32px;height:18px;position:relative}.vidtreo-recovery-guide-switch-track{background:#ffffff26;border-radius:9px;animation:7s ease-in-out infinite vidtreo-track-on;position:absolute;inset:0}.vidtreo-recovery-guide-switch-knob{background:#fff;border-radius:50%;width:14px;height:14px;animation:7s ease-in-out infinite vidtreo-knob-slide;position:absolute;top:2px;left:2px;box-shadow:0 1px 3px #0000004d}.vidtreo-recovery-guide-switch--delayed{animation-delay:.85s}@keyframes vidtreo-cursor-move{0%{opacity:0;transform:translate(100px,12px)}8%{opacity:1}22%{transform:translate(0)}26%{transform:translate(0)scale(.75)}30%{opacity:1;transform:translate(0)scale(1)}33%{opacity:1;transform:translate(0)}38%{opacity:1;transform:translate(65px,63px)}42%{transform:translate(65px,63px)scale(.75)}45%{opacity:1;transform:translate(65px,63px)scale(1)}48%{opacity:1;transform:translate(65px,97px)}52%{transform:translate(65px,97px)scale(.75)}55%{opacity:1;transform:translate(65px,97px)scale(1)}60%{opacity:0}to{opacity:0;transform:translate(100px,12px)}}@keyframes vidtreo-popover-reveal{0%,27%{opacity:0;transform:translateY(-6px)scale(.96)}33%,82%{opacity:1;transform:translateY(0)scale(1)}88%,to{opacity:0;transform:translateY(-6px)scale(.96)}}@keyframes vidtreo-track-on{0%,34%{background:#ffffff26}40%,92%{background:#34d399}96%,to{background:#ffffff26}}@keyframes vidtreo-knob-slide{0%,34%{transform:translate(0)}40%,92%{transform:translate(14px)}96%,to{transform:translate(0)}}@keyframes vidtreo-icon-hide{0%,34%{opacity:1}40%,92%{opacity:0}96%,to{opacity:1}}@keyframes vidtreo-icon-show{0%,34%{opacity:0}40%,92%{opacity:1}96%,to{opacity:0}}@keyframes vidtreo-lock-pulse{0%,15%{color:#ffffff80}22%,30%{color:#34d399}38%,to{color:#ffffff80}}.vidtreo-record-button.vidtreo-record-button-disabled,.vidtreo-record-button-disabled{opacity:.6;cursor:not-allowed;pointer-events:none;filter:grayscale(.3)}.vidtreo-mic-connecting-indicator{justify-content:center;align-items:center;animation:1.4s ease-in-out infinite vidtreo-mic-pulse;display:inline-flex}@keyframes vidtreo-mic-pulse{0%,to{opacity:.4}50%{opacity:1}}.vidtreo-audio-error-overlay{z-index:var(--vidtreo-z-error-overlay);text-align:center;background:#000000d9;flex-direction:column;justify-content:center;align-items:center;padding:2rem 1.5rem;animation:.3s ease-out vidtreo-audio-overlay-fade-in;display:flex;position:absolute;inset:0}@supports (backdrop-filter:blur(8px)){.vidtreo-audio-error-overlay{-webkit-backdrop-filter:blur(8px);background:#000000bf}}@keyframes vidtreo-audio-overlay-fade-in{0%{opacity:0}to{opacity:1}}.vidtreo-audio-error-icon{background:#ef444426;border-radius:50%;justify-content:center;align-items:center;width:56px;height:56px;margin-bottom:1rem;display:flex}.vidtreo-audio-error-icon svg{color:#ef4444;width:28px;height:28px}.vidtreo-audio-error-title{color:#fff;margin:0 0 .5rem;font-size:1.125rem;font-weight:600;line-height:1.4}.vidtreo-audio-error-message{color:#ffffffb3;max-width:320px;margin:0 0 1.5rem;font-size:.875rem;line-height:1.6}.vidtreo-audio-error-retry{color:#111;cursor:pointer;background:#fff;border:none;border-radius:9999px;align-items:center;gap:.5rem;padding:.75rem 1.5rem;font-family:inherit;font-size:.875rem;font-weight:600;transition:background .15s,transform .1s;display:inline-flex}.vidtreo-audio-error-retry:hover{background:#f0f0f0}.vidtreo-audio-error-retry:active{transform:scale(.97)}.vidtreo-audio-error-retry svg{width:16px;height:16px}.vidtreo-audio-warning-toast{z-index:var(--vidtreo-z-error-overlay);color:#ffffffeb;pointer-events:auto;background:#1111118c;border:1px solid #ffffff14;border-radius:12px;align-items:flex-start;gap:.625rem;max-width:min(420px,100% - 2rem);padding:.625rem .875rem;font-family:inherit;animation:.2s ease-out vidtreo-audio-warning-toast-fade-in;display:flex;position:absolute;top:1rem;left:50%;transform:translate(-50%);box-shadow:0 4px 16px #00000040}@supports (backdrop-filter:blur(10px)){.vidtreo-audio-warning-toast{-webkit-backdrop-filter:blur(10px)saturate(140%);background:#11111173}}.vidtreo-audio-warning-toast--critical{border-color:#ef444473}.vidtreo-audio-warning-toast--critical .vidtreo-audio-warning-toast__icon{color:#ef4444}.vidtreo-audio-warning-toast--soft{border-color:#f59e0b73}.vidtreo-audio-warning-toast--soft .vidtreo-audio-warning-toast__icon{color:#f59e0b}.vidtreo-audio-warning-toast__icon{flex:none;justify-content:center;align-items:center;width:20px;height:20px;margin-top:1px;display:inline-flex}.vidtreo-audio-warning-toast__content{flex-direction:column;flex:auto;gap:2px;min-width:0;display:flex}.vidtreo-audio-warning-toast__title{color:#fff;font-size:.8125rem;font-weight:600;line-height:1.3}.vidtreo-audio-warning-toast__message{color:#ffffffb8;font-size:.75rem;font-weight:400;line-height:1.4}.vidtreo-audio-warning-toast__dismiss{color:#ffffffa6;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;justify-content:center;align-items:center;width:22px;height:22px;margin-left:.25rem;padding:0;font-family:inherit;transition:background .15s,color .15s;display:inline-flex}.vidtreo-audio-warning-toast__dismiss:hover{color:#fffffff2;background:#ffffff1a}@keyframes vidtreo-audio-warning-toast-fade-in{0%{opacity:0;transform:translate(-50%,-8px)}to{opacity:1;transform:translate(-50%)}}`;function ZT(e){return`
12830
12830
  <style>${XT}</style>
12831
12831
  <div class="vidtreo-mobile-landing-container">
12832
12832
  <div class="vidtreo-mobile-landing-content">