cacophony 0.20.1 → 0.20.3
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.
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +378 -378
- package/dist/index.mjs.map +1 -1
- package/docs/classes/AudioCache.html +6 -6
- package/docs/classes/Cacophony.html +13 -13
- package/docs/classes/Group.html +12 -12
- package/docs/classes/MicrophonePlayback.html +3 -3
- package/docs/classes/Playback.html +31 -31
- package/docs/classes/Sound.html +18 -18
- package/docs/classes/Synth.html +15 -15
- package/docs/classes/SynthGroup.html +2 -2
- package/docs/enums/SoundType.html +2 -2
- package/docs/interfaces/AudioBuffer.html +2 -2
- package/docs/interfaces/AudioBufferSourceNode.html +4 -4
- package/docs/interfaces/AudioEventCallbacks.html +2 -2
- package/docs/interfaces/AudioListener.html +2 -2
- package/docs/interfaces/AudioNode.html +3 -3
- package/docs/interfaces/AudioParam.html +2 -2
- package/docs/interfaces/AudioWorkletNode.html +3 -3
- package/docs/interfaces/BaseAudioEvents.html +2 -2
- package/docs/interfaces/BaseContext.html +2 -2
- package/docs/interfaces/BaseSound.html +2 -2
- package/docs/interfaces/BiquadFilterNode.html +4 -4
- package/docs/interfaces/CacheErrorEvent.html +2 -2
- package/docs/interfaces/CacheHitEvent.html +2 -2
- package/docs/interfaces/CacheMissEvent.html +2 -2
- package/docs/interfaces/CacophonyEvents.html +2 -2
- package/docs/interfaces/ChannelMergerNode.html +3 -3
- package/docs/interfaces/ChannelSplitterNode.html +3 -3
- package/docs/interfaces/FadeStartEvent.html +2 -2
- package/docs/interfaces/GainNode.html +3 -3
- package/docs/interfaces/GlobalPlaybackEvent.html +2 -2
- package/docs/interfaces/LoadingCompleteEvent.html +2 -2
- package/docs/interfaces/LoadingErrorEvent.html +2 -2
- package/docs/interfaces/LoadingProgressEvent.html +2 -2
- package/docs/interfaces/LoadingStartEvent.html +2 -2
- package/docs/interfaces/MediaElementSourceNode.html +3 -3
- package/docs/interfaces/MediaStreamAudioSourceNode.html +3 -3
- package/docs/interfaces/OfflineOptions.html +2 -2
- package/docs/interfaces/OscillatorNode.html +4 -4
- package/docs/interfaces/PannerNode.html +3 -3
- package/docs/interfaces/PlayOptions.html +2 -2
- package/docs/interfaces/PlaybackErrorEvent.html +2 -2
- package/docs/interfaces/PlaybackEvents.html +2 -2
- package/docs/interfaces/RuntimeOptions.html +2 -2
- package/docs/interfaces/SoundCleanupHoldings.html +2 -2
- package/docs/interfaces/SoundErrorEvent.html +2 -2
- package/docs/interfaces/SoundEvents.html +2 -2
- package/docs/interfaces/StereoPannerNode.html +3 -3
- package/docs/interfaces/SynthEvents.html +2 -2
- package/docs/types/CacheEventCallback.html +1 -1
- package/docs/types/ErrorEventCallback.html +1 -1
- package/docs/types/FadeType.html +1 -1
- package/docs/types/LoadingEventCallback.html +1 -1
- package/docs/types/LoopCount.html +1 -1
- package/docs/types/Orientation.html +1 -1
- package/docs/types/PanType.html +1 -1
- package/docs/types/Position.html +1 -1
- package/docs/types/SourceNode.html +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class V{maxSize;cache;constructor(e){this.maxSize=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;const t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const s=this.cache.keys().next().value;s!==void 0&&this.cache.delete(s)}this.cache.set(e,t)}has(e){return this.cache.has(e)}}const k=100;function E(c){if(!c)return null;const e=c.match(/max-age\s*=\s*"?(\d+)"?/i);return e?parseInt(e[1],10):null}function Y(c){return c?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(c):!1}function v(c){return c instanceof DOMException&&c.name==="AbortError"?"abort":c instanceof Error?"network":"unknown"}class C{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new V(k);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(e){C.cacheExpirationTime=e}static async openCache(){try{return await caches.open("audio-cache")}catch(e){throw console.error("Failed to open cache:",e),e}}static callAllCallbacks(e,t,s){const o=C.pendingCallbacks.get(e);o&&o.forEach(g=>{const i=g[t];if(i)try{i(s)}catch(a){console.error(`Error in ${t} callback:`,a)}})}static async getOrCreatePendingRequest(e,t,s,o){if(s?.aborted)throw new DOMException("Operation was aborted","AbortError");if(o){const i=C.pendingCallbacks.get(e)||[];i.push(o),C.pendingCallbacks.set(e,i)}const g=C.pendingRequests.get(e);if(!g){const i=(async()=>{try{const a=await t();if(a===void 0)throw new Error("Failed to create audio buffer.");return a}finally{C.pendingRequests.delete(e),C.pendingCallbacks.delete(e)}})();return s?.addEventListener("abort",()=>{s.aborted&&(C.pendingRequests.delete(e),C.pendingCallbacks.delete(e))},{once:!0}),C.pendingRequests.set(e,i),i}return g}static async updateMetadata(e,t,s){const o={url:t,timestamp:Date.now(),...s};await e.put(`${t}:meta`,new Response(JSON.stringify(o),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(e,t){try{const s=await t.match(e);return s?.ok?await s.arrayBuffer():null}catch(s){return console.error("Failed to get data from cache:",s),null}}static async fetchAndCacheBuffer(e,t,s,o,g,i){const a=new Headers;s&&a.append("If-None-Match",s),o&&a.append("If-Modified-Since",o),console.debug(`[AudioCache] Fetching ${e}`,{headers:Object.fromEntries(a.entries()),hasEtag:!!s,hasLastModified:!!o});const n=await fetch(e,{headers:a,signal:g});if(console.debug(`[AudioCache] Response ${e}`,{status:n.status,statusText:n.statusText,etag:n.headers?.get("ETag"),lastModified:n.headers?.get("Last-Modified"),cacheControl:n.headers?.get("Cache-Control")}),n.status===304){const I=await t.match(e);if(I){i?.onCacheHit&&i.onCacheHit({url:e,cacheType:"conditional",timestamp:Date.now()});const r=Date.now(),l=n.headers?.get("Cache-Control");return await C.updateMetadata(t,e,{timestamp:r,etag:s,lastModified:o,...l?{cacheControl:l}:{}}),await I.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${e}: 304 response but no cached body. Re-fetching.`);const r=await fetch(e,{signal:g});if(r.status===200){const l=r.clone(),A=r.headers.get("ETag"),p=r.headers.get("Last-Modified"),m=r.headers.get("Cache-Control");try{await Promise.all([t.put(e,l),C.updateMetadata(t,e,{timestamp:Date.now(),etag:A||void 0,lastModified:p||void 0,cacheControl:m||void 0})])}catch(d){throw await t.delete(e),await t.delete(`${e}:meta`),d}if(r.body){const{stream:d,total:S}=C.createProgressTrackingStream(r,e);return await C.collectStreamToArrayBuffer(d,S||void 0)}else return await r.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${r.status} ${r.statusText}`)}}if(n.status===200){const I=n.clone(),r=n.headers.get("ETag"),l=n.headers.get("Last-Modified"),A=n.headers.get("Cache-Control");try{await Promise.all([t.put(e,I),C.updateMetadata(t,e,{timestamp:Date.now(),etag:r||void 0,lastModified:l||void 0,cacheControl:A||void 0})])}catch(p){throw await t.delete(e),await t.delete(`${e}:meta`),p}}if(g?.aborted)throw new DOMException("Operation was aborted","AbortError");if(n.body){const{stream:I,total:r}=C.createProgressTrackingStream(n,e);return await C.collectStreamToArrayBuffer(I,r||void 0)}else return await n.arrayBuffer()}static createProgressTrackingStream(e,t){const s=e.headers.get("content-length"),o=s?parseInt(s,10):null;let g=0;if(!e.body)throw new Error("Response body is null");const i=e.body.getReader();return{stream:new ReadableStream({start(n){function I(){return i.read().then(({done:r,value:l})=>{if(r){C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:g,total:o,progress:o?1:-1,timestamp:Date.now()}),n.close();return}if(l){g+=l.byteLength;const A=o?g/o:-1;C.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:g,total:o,progress:A,timestamp:Date.now()}),n.enqueue(l)}return I()}).catch(r=>{n.error(r)})}return I()},cancel(n){return i.cancel(n)}}),total:o}}static async collectStreamToArrayBuffer(e,t){const s=e.getReader();try{if(t!==void 0&&t>0){const o=new ArrayBuffer(t),g=new Uint8Array(o);let i=0;for(;;){const{done:a,value:n}=await s.read();if(a)break;n&&(g.set(n,i),i+=n.byteLength)}return o}else{let o=new Uint8Array(8192),g=0;for(;;){const{done:i,value:a}=await s.read();if(i)break;if(a){if(g+a.byteLength>o.length){const n=Math.max(o.length*2,g+a.byteLength),I=new Uint8Array(n);I.set(o.subarray(0,g)),o=I}o.set(a,g),g+=a.byteLength}}return o.slice(0,g).buffer}}finally{s.releaseLock()}}static async decodeAudioData(e,t){try{return await e.decodeAudioData(t)}catch(s){throw console.error("Failed to decode audio data:",s),s}}static async getMetadataFromCache(e,t){try{const s=await t.match(`${e}:meta`);return s?.ok?await s.json():null}catch(s){return console.error("Failed to get metadata from cache:",s),null}}async getAudioBuffer(e,t,s,o){if(o?.onLoadingStart&&o.onLoadingStart({url:t,timestamp:Date.now()}),C.decodedBuffers.has(t))return o?.onCacheHit&&o.onCacheHit({url:t,cacheType:"memory",timestamp:Date.now()}),C.decodedBuffers.get(t);if(t.startsWith("data:")){const n=t.split(",")[1],I=Uint8Array.from(atob(n),l=>l.charCodeAt(0)).buffer,r=await C.decodeAudioData(e,I);return C.decodedBuffers.set(t,r),r}const g=await C.openCache(),i=await C.getMetadataFromCache(t,g),a=(()=>{if(!i||Y(i.cacheControl))return!0;const n=E(i.cacheControl);if(n!==null){const I=(Date.now()-i.timestamp)/1e3;if(n>0&&I<n)return!1}return i.etag||i.lastModified?!0:Date.now()-i.timestamp>C.cacheExpirationTime})();return C.getOrCreatePendingRequest(t,async()=>{if(a){o?.onCacheMiss&&o.onCacheMiss({url:t,reason:i?"expired":"not-found",timestamp:Date.now()});try{const n=await C.fetchAndCacheBuffer(t,g,i?.etag,i?.lastModified,s,{onCacheHit:o?.onCacheHit});let I;try{I=await C.decodeAudioData(e,n)}catch(r){throw o?.onLoadingError&&o.onLoadingError({url:t,error:r,errorType:"decode",timestamp:Date.now()}),r}return o?.onLoadingComplete&&o.onLoadingComplete({url:t,duration:I.duration,size:n.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,I),I}catch(n){throw o?.onLoadingError&&o.onLoadingError({url:t,error:n,errorType:v(n),timestamp:Date.now()}),o?.onCacheError&&o.onCacheError({url:t,error:n,operation:"get",timestamp:Date.now()}),n}}else{const n=await C.getBufferFromCache(t,g);if(n){o?.onCacheHit&&o.onCacheHit({url:t,cacheType:"browser",timestamp:Date.now()});const I=await C.decodeAudioData(e,n);return C.decodedBuffers.set(t,I),I}else{o?.onCacheError&&o.onCacheError({url:t,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});try{const I=await C.fetchAndCacheBuffer(t,g,i?.etag,i?.lastModified,s,{onCacheHit:o?.onCacheHit});let r;try{r=await C.decodeAudioData(e,I)}catch(l){throw o?.onLoadingError&&o.onLoadingError({url:t,error:l,errorType:"decode",timestamp:Date.now()}),l}return o?.onLoadingComplete&&o.onLoadingComplete({url:t,duration:r.duration,size:I.byteLength,timestamp:Date.now()}),C.decodedBuffers.set(t,r),r}catch(I){throw o?.onLoadingError&&o.onLoadingError({url:t,error:I,errorType:v(I),timestamp:Date.now()}),I}}}},s,{onLoadingProgress:o?.onLoadingProgress})}clearMemoryCache(){C.decodedBuffers=new V(k),C.pendingRequests.clear()}}const D="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGdldERlZmF1bHRFeHBvcnRGcm9tQ2pzICh4KSB7CgkJcmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDsKCX0KCglmdW5jdGlvbiBGRlQoc2l6ZSkgewoJICB0aGlzLnNpemUgPSBzaXplIHwgMDsKCSAgaWYgKHRoaXMuc2l6ZSA8PSAxIHx8ICh0aGlzLnNpemUgJiAodGhpcy5zaXplIC0gMSkpICE9PSAwKQoJICAgIHRocm93IG5ldyBFcnJvcignRkZUIHNpemUgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBhbmQgYmlnZ2VyIHRoYW4gMScpOwoKCSAgdGhpcy5fY3NpemUgPSBzaXplIDw8IDE7CgoJICAvLyBOT1RFOiBVc2Ugb2YgYHZhcmAgaXMgaW50ZW50aW9uYWwgZm9yIG9sZCBWOCB2ZXJzaW9ucwoJICB2YXIgdGFibGUgPSBuZXcgQXJyYXkodGhpcy5zaXplICogMik7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFibGUubGVuZ3RoOyBpICs9IDIpIHsKCSAgICBjb25zdCBhbmdsZSA9IE1hdGguUEkgKiBpIC8gdGhpcy5zaXplOwoJICAgIHRhYmxlW2ldID0gTWF0aC5jb3MoYW5nbGUpOwoJICAgIHRhYmxlW2kgKyAxXSA9IC1NYXRoLnNpbihhbmdsZSk7CgkgIH0KCSAgdGhpcy50YWJsZSA9IHRhYmxlOwoKCSAgLy8gRmluZCBzaXplJ3MgcG93ZXIgb2YgdHdvCgkgIHZhciBwb3dlciA9IDA7CgkgIGZvciAodmFyIHQgPSAxOyB0aGlzLnNpemUgPiB0OyB0IDw8PSAxKQoJICAgIHBvd2VyKys7CgoJICAvLyBDYWxjdWxhdGUgaW5pdGlhbCBzdGVwJ3Mgd2lkdGg6CgkgIC8vICAgKiBJZiB3ZSBhcmUgZnVsbCByYWRpeC00IC0gaXQgaXMgMnggc21hbGxlciB0byBnaXZlIGluaXRhbCBsZW49OAoJICAvLyAgICogT3RoZXJ3aXNlIGl0IGlzIHRoZSBzYW1lIGFzIGBwb3dlcmAgdG8gZ2l2ZSBsZW49NAoJICB0aGlzLl93aWR0aCA9IHBvd2VyICUgMiA9PT0gMCA/IHBvd2VyIC0gMSA6IHBvd2VyOwoKCSAgLy8gUHJlLWNvbXB1dGUgYml0LXJldmVyc2FsIHBhdHRlcm5zCgkgIHRoaXMuX2JpdHJldiA9IG5ldyBBcnJheSgxIDw8IHRoaXMuX3dpZHRoKTsKCSAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLl9iaXRyZXYubGVuZ3RoOyBqKyspIHsKCSAgICB0aGlzLl9iaXRyZXZbal0gPSAwOwoJICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgc2hpZnQgPCB0aGlzLl93aWR0aDsgc2hpZnQgKz0gMikgewoJICAgICAgdmFyIHJldlNoaWZ0ID0gdGhpcy5fd2lkdGggLSBzaGlmdCAtIDI7CgkgICAgICB0aGlzLl9iaXRyZXZbal0gfD0gKChqID4+PiBzaGlmdCkgJiAzKSA8PCByZXZTaGlmdDsKCSAgICB9CgkgIH0KCgkgIHRoaXMuX291dCA9IG51bGw7CgkgIHRoaXMuX2RhdGEgPSBudWxsOwoJICB0aGlzLl9pbnYgPSAwOwoJfQoJdmFyIGZmdCA9IEZGVDsKCglGRlQucHJvdG90eXBlLmZyb21Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiBmcm9tQ29tcGxleEFycmF5KGNvbXBsZXgsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgbmV3IEFycmF5KGNvbXBsZXgubGVuZ3RoID4+PiAxKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21wbGV4Lmxlbmd0aDsgaSArPSAyKQoJICAgIHJlc1tpID4+PiAxXSA9IGNvbXBsZXhbaV07CgkgIHJldHVybiByZXM7Cgl9OwoKCUZGVC5wcm90b3R5cGUuY3JlYXRlQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gY3JlYXRlQ29tcGxleEFycmF5KCkgewoJICBjb25zdCByZXMgPSBuZXcgQXJyYXkodGhpcy5fY3NpemUpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKykKCSAgICByZXNbaV0gPSAwOwoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLnRvQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gdG9Db21wbGV4QXJyYXkoaW5wdXQsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgdGhpcy5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpICs9IDIpIHsKCSAgICByZXNbaV0gPSBpbnB1dFtpID4+PiAxXTsKCSAgICByZXNbaSArIDFdID0gMDsKCSAgfQoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLmNvbXBsZXRlU3BlY3RydW0gPSBmdW5jdGlvbiBjb21wbGV0ZVNwZWN0cnVtKHNwZWN0cnVtKSB7CgkgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgkgIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKCSAgZm9yICh2YXIgaSA9IDI7IGkgPCBoYWxmOyBpICs9IDIpIHsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaV0gPSBzcGVjdHJ1bVtpXTsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaSArIDFdID0gLXNwZWN0cnVtW2kgKyAxXTsKCSAgfQoJfTsKCglGRlQucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fdHJhbnNmb3JtNCgpOwoJICB0aGlzLl9vdXQgPSBudWxsOwoJICB0aGlzLl9kYXRhID0gbnVsbDsKCX07CgoJRkZULnByb3RvdHlwZS5yZWFsVHJhbnNmb3JtID0gZnVuY3Rpb24gcmVhbFRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fcmVhbFRyYW5zZm9ybTQoKTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCUZGVC5wcm90b3R5cGUuaW52ZXJzZVRyYW5zZm9ybSA9IGZ1bmN0aW9uIGludmVyc2VUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CgkgIGlmIChvdXQgPT09IGRhdGEpCgkgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCgkgIHRoaXMuX291dCA9IG91dDsKCSAgdGhpcy5fZGF0YSA9IGRhdGE7CgkgIHRoaXMuX2ludiA9IDE7CgkgIHRoaXMuX3RyYW5zZm9ybTQoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspCgkgICAgb3V0W2ldIC89IHRoaXMuc2l6ZTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCS8vIHJhZGl4LTQgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBVc2VzIG9mIGB2YXJgIGFyZSBpbnRlbnRpb25hbCBmb3Igb2xkZXIgVjggdmVyc2lvbiB0aGF0IGRvIG5vdAoJLy8gc3VwcG9ydCBib3RoIGBsZXQgY29tcG91bmQgYXNzaWdubWVudHNgIGFuZCBgY29uc3QgcGhpYAoJRkZULnByb3RvdHlwZS5fdHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF90cmFuc2Zvcm00KCkgewoJICB2YXIgb3V0ID0gdGhpcy5fb3V0OwoJICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKCSAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCgkgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwoJICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CgkgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgoJICB2YXIgb3V0T2ZmOwoJICB2YXIgdDsKCSAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKCSAgaWYgKGxlbiA9PT0gNCkgewoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIC8vIGxlbiA9PT0gOAoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGxlbiA+Pj4gMjsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIC8vIEZ1bGwgY2FzZQoJICAgICAgdmFyIGxpbWl0ID0gb3V0T2ZmICsgcXVhcnRlckxlbjsKCSAgICAgIGZvciAodmFyIGkgPSBvdXRPZmYsIGsgPSAwOyBpIDwgbGltaXQ7IGkgKz0gMiwgayArPSBzdGVwKSB7CgkgICAgICAgIGNvbnN0IEEgPSBpOwoJICAgICAgICBjb25zdCBCID0gQSArIHF1YXJ0ZXJMZW47CgkgICAgICAgIGNvbnN0IEMgPSBCICsgcXVhcnRlckxlbjsKCSAgICAgICAgY29uc3QgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IEFyID0gb3V0W0FdOwoJICAgICAgICBjb25zdCBBaSA9IG91dFtBICsgMV07CgkgICAgICAgIGNvbnN0IEJyID0gb3V0W0JdOwoJICAgICAgICBjb25zdCBCaSA9IG91dFtCICsgMV07CgkgICAgICAgIGNvbnN0IENyID0gb3V0W0NdOwoJICAgICAgICBjb25zdCBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIGNvbnN0IERyID0gb3V0W0RdOwoJICAgICAgICBjb25zdCBEaSA9IG91dFtEICsgMV07CgoJICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCgkgICAgICAgIGNvbnN0IE1BciA9IEFyOwoJICAgICAgICBjb25zdCBNQWkgPSBBaTsKCgkgICAgICAgIGNvbnN0IHRhYmxlQnIgPSB0YWJsZVtrXTsKCSAgICAgICAgY29uc3QgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgY29uc3QgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwoJICAgICAgICBjb25zdCBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgoJICAgICAgICBjb25zdCB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwoJICAgICAgICBjb25zdCBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICBjb25zdCB0YWJsZURyID0gdGFibGVbMyAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICBjb25zdCBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgoJICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IFQwciA9IE1BciArIE1DcjsKCSAgICAgICAgY29uc3QgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICBjb25zdCBUMXIgPSBNQXIgLSBNQ3I7CgkgICAgICAgIGNvbnN0IFQxaSA9IE1BaSAtIE1DaTsKCSAgICAgICAgY29uc3QgVDJyID0gTUJyICsgTURyOwoJICAgICAgICBjb25zdCBUMmkgPSBNQmkgKyBNRGk7CgkgICAgICAgIGNvbnN0IFQzciA9IGludiAqIChNQnIgLSBNRHIpOwoJICAgICAgICBjb25zdCBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgkgICAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCgkgICAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCSAgICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKCSAgICAgICAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICAgICAgICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICAgICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CgkgICAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoJICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CgkgICAgICAgIG91dFtEXSA9IEZEcjsKCSAgICAgICAgb3V0W0QgKyAxXSA9IEZEaTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX07CgoJLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgoJLy8KCS8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAoJRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBldmVuSSA9IGRhdGFbb2ZmICsgMV07CgkgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBvZGRJID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CgoJICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKCSAgY29uc3QgbGVmdEkgPSBldmVuSSArIG9kZEk7CgkgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCSAgY29uc3QgcmlnaHRJID0gZXZlbkkgLSBvZGRJOwoKCSAgb3V0W291dE9mZl0gPSBsZWZ0UjsKCSAgb3V0W291dE9mZiArIDFdID0gbGVmdEk7CgkgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKCSAgb3V0W291dE9mZiArIDNdID0gcmlnaHRJOwoJfTsKCgkvLyByYWRpeC00CgkvLwoJLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CglGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewoJICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CgkgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoJICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CgkgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CgkgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgoJICAvLyBPcmlnaW5hbCB2YWx1ZXMKCSAgY29uc3QgQXIgPSBkYXRhW29mZl07CgkgIGNvbnN0IEFpID0gZGF0YVtvZmYgKyAxXTsKCSAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBCaSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoJICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwoJICBjb25zdCBDaSA9IGRhdGFbb2ZmICsgc3RlcDIgKyAxXTsKCSAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCSAgY29uc3QgRGkgPSBkYXRhW29mZiArIHN0ZXAzICsgMV07CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQwaSA9IEFpICsgQ2k7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQxaSA9IEFpIC0gQ2k7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQyaSA9IEJpICsgRGk7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCSAgY29uc3QgVDNpID0gaW52ICogKEJpIC0gRGkpOwoKCSAgLy8gRmluYWwgdmFsdWVzCgkgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCSAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKCSAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgkgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCgkgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKCSAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKCSAgb3V0W291dE9mZl0gPSBGQXI7CgkgIG91dFtvdXRPZmYgKyAxXSA9IEZBaTsKCSAgb3V0W291dE9mZiArIDJdID0gRkJyOwoJICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CgkgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKCSAgb3V0W291dE9mZiArIDVdID0gRkNpOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJLy8gUmVhbCBpbnB1dCByYWRpeC00IGltcGxlbWVudGF0aW9uCglGRlQucHJvdG90eXBlLl9yZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9yZWFsVHJhbnNmb3JtNCgpIHsKCSAgdmFyIG91dCA9IHRoaXMuX291dDsKCSAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCgkgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQoJICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKCSAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwoJICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKCSAgdmFyIG91dE9mZjsKCSAgdmFyIHQ7CgkgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CgkgIGlmIChsZW4gPT09IDQpIHsKCSAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKCSAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKCSAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgLy8gbGVuID09PSA4CgkgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CgkgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CgkgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgaGFsZkxlbiA9IGxlbiA+Pj4gMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGhhbGZMZW4gPj4+IDE7CgkgICAgdmFyIGhxdWFydGVyTGVuID0gcXVhcnRlckxlbiA+Pj4gMTsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIGZvciAodmFyIGkgPSAwLCBrID0gMDsgaSA8PSBocXVhcnRlckxlbjsgaSArPSAyLCBrICs9IHN0ZXApIHsKCSAgICAgICAgdmFyIEEgPSBvdXRPZmYgKyBpOwoJICAgICAgICB2YXIgQiA9IEEgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgQyA9IEIgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIHZhciBBciA9IG91dFtBXTsKCSAgICAgICAgdmFyIEFpID0gb3V0W0EgKyAxXTsKCSAgICAgICAgdmFyIEJyID0gb3V0W0JdOwoJICAgICAgICB2YXIgQmkgPSBvdXRbQiArIDFdOwoJICAgICAgICB2YXIgQ3IgPSBvdXRbQ107CgkgICAgICAgIHZhciBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIHZhciBEciA9IG91dFtEXTsKCSAgICAgICAgdmFyIERpID0gb3V0W0QgKyAxXTsKCgkgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKCSAgICAgICAgdmFyIE1BciA9IEFyOwoJICAgICAgICB2YXIgTUFpID0gQWk7CgoJICAgICAgICB2YXIgdGFibGVCciA9IHRhYmxlW2tdOwoJICAgICAgICB2YXIgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgdmFyIE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKCSAgICAgICAgdmFyIE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCgkgICAgICAgIHZhciB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICB2YXIgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CgkgICAgICAgIHZhciBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CgkgICAgICAgIHZhciBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICB2YXIgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKCSAgICAgICAgdmFyIHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwoJICAgICAgICB2YXIgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICB2YXIgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKCSAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgVDByID0gTUFyICsgTUNyOwoJICAgICAgICB2YXIgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICB2YXIgVDFyID0gTUFyIC0gTUNyOwoJICAgICAgICB2YXIgVDFpID0gTUFpIC0gTUNpOwoJICAgICAgICB2YXIgVDJyID0gTUJyICsgTURyOwoJICAgICAgICB2YXIgVDJpID0gTUJpICsgTURpOwoJICAgICAgICB2YXIgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CgkgICAgICAgIHZhciBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgRkFyID0gVDByICsgVDJyOwoJICAgICAgICB2YXIgRkFpID0gVDBpICsgVDJpOwoKCSAgICAgICAgdmFyIEZCciA9IFQxciArIFQzaTsKCSAgICAgICAgdmFyIEZCaSA9IFQxaSAtIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoKCSAgICAgICAgLy8gT3V0cHV0IGZpbmFsIG1pZGRsZSBwb2ludAoJICAgICAgICBpZiAoaSA9PT0gMCkgewoJICAgICAgICAgIHZhciBGQ3IgPSBUMHIgLSBUMnI7CgkgICAgICAgICAgdmFyIEZDaSA9IFQwaSAtIFQyaTsKCSAgICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKCSAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoKCSAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSBvdXJzZWx2ZXMKCSAgICAgICAgaWYgKGkgPT09IGhxdWFydGVyTGVuKQoJICAgICAgICAgIGNvbnRpbnVlOwoKCSAgICAgICAgLy8gSW4gdGhlIGZsaXBwZWQgY2FzZToKCSAgICAgICAgLy8gTUFpID0gLU1BaQoJICAgICAgICAvLyBNQnI9LU1CaSwgTUJpPS1NQnIKCSAgICAgICAgLy8gTUNyPS1NQ3IKCSAgICAgICAgLy8gTURyPU1EaSwgTURpPU1EcgoJICAgICAgICB2YXIgU1QwciA9IFQxcjsKCSAgICAgICAgdmFyIFNUMGkgPSAtVDFpOwoJICAgICAgICB2YXIgU1QxciA9IFQwcjsKCSAgICAgICAgdmFyIFNUMWkgPSAtVDBpOwoJICAgICAgICB2YXIgU1QyciA9IC1pbnYgKiBUM2k7CgkgICAgICAgIHZhciBTVDJpID0gLWludiAqIFQzcjsKCSAgICAgICAgdmFyIFNUM3IgPSAtaW52ICogVDJpOwoJICAgICAgICB2YXIgU1QzaSA9IC1pbnYgKiBUMnI7CgoJICAgICAgICB2YXIgU0ZBciA9IFNUMHIgKyBTVDJyOwoJICAgICAgICB2YXIgU0ZBaSA9IFNUMGkgKyBTVDJpOwoKCSAgICAgICAgdmFyIFNGQnIgPSBTVDFyICsgU1QzaTsKCSAgICAgICAgdmFyIFNGQmkgPSBTVDFpIC0gU1QzcjsKCgkgICAgICAgIHZhciBTQSA9IG91dE9mZiArIHF1YXJ0ZXJMZW4gLSBpOwoJICAgICAgICB2YXIgU0IgPSBvdXRPZmYgKyBoYWxmTGVuIC0gaTsKCgkgICAgICAgIG91dFtTQV0gPSBTRkFyOwoJICAgICAgICBvdXRbU0EgKyAxXSA9IFNGQWk7CgkgICAgICAgIG91dFtTQl0gPSBTRkJyOwoJICAgICAgICBvdXRbU0IgKyAxXSA9IFNGQmk7CgkgICAgICB9CgkgICAgfQoJICB9Cgl9OwoKCS8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKCgkgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwoJICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CgoJICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IDA7Cgl9OwoKCS8vIHJhZGl4LTQKCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCSAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwoJICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKCSAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwoJICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CgkgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CgkgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCgkgIC8vIEZpbmFsIHZhbHVlcwoJICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgoJICBjb25zdCBGQnIgPSBUMXI7CgkgIGNvbnN0IEZCaSA9IC1UM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgoJICBjb25zdCBGRHIgPSBUMXI7CgkgIGNvbnN0IEZEaSA9IFQzcjsKCgkgIG91dFtvdXRPZmZdID0gRkFyOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKCSAgb3V0W291dE9mZiArIDRdID0gRkNyOwoJICBvdXRbb3V0T2ZmICsgNV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJdmFyIEZGVCQxID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKGZmdCk7CgoJY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKCWNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwoJLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KCWNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CgkgICAgbmJJbnB1dHM7CgkgICAgbmJPdXRwdXRzOwoJICAgIGJsb2NrU2l6ZTsKCSAgICBob3BTaXplOwoJICAgIG5iT3ZlcmxhcHM7CgkgICAgaW5wdXRCdWZmZXJzID0gW107CgkgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwoJICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwoJICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKCSAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwoJICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CgkgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKCSAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CgkgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKCSAgICB9CgkgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CgkgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IG5iQ2hhbm5lbHMgPSBpbnB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIG5iQ2hhbm5lbHMpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgY29uc3QgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBjb25zdCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewoJICAgICAgICAgICAgICAgIGNvbnN0IHdlYkF1ZGlvQmxvY2sgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHdlYkF1ZGlvQmxvY2suc2V0KHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5zdWJhcnJheSgwLCBXRUJBVURJT19CTE9DS19TSVpFKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgc2hpZnRJbnB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdE91dHB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uZmlsbCgwLCB0aGlzLmJsb2NrU2l6ZSAtIFdFQkFVRElPX0JMT0NLX1NJWkUpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByZXBhcmVJbnB1dEJ1ZmZlcnNUb1NlbmQoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaV1bal0uc2V0KHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpXVtqXSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHRoaXMuYmxvY2tTaXplOyBrKyspIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdW2tdICs9IHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CgkgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKCSAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKCSAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CgkgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CgkgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKCSAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCX0KCgljb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKCWZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CgkgICAgY29uc3Qgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwoJICAgIH0KCSAgICByZXR1cm4gd2luOwoJfQoJY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKCSAgICBmZnRTaXplOwoJICAgIHRpbWVDdXJzb3I7CgkgICAgaGFubldpbmRvdzsKCSAgICBmZnQ7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXI7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwoJICAgIHRpbWVDb21wbGV4QnVmZmVyOwoJICAgIG1hZ25pdHVkZXM7CgkgICAgcGVha0luZGV4ZXM7CgkgICAgbmJQZWFrczsKCSAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewoJICAgICAgICByZXR1cm4gWwoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCgkgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCgkgICAgICAgICAgICB9LAoJICAgICAgICBdOwoJICAgIH0KCSAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CgkgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKCSAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKCSAgICAgICAgfTsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwoJICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwoJICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCgkgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwoJICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKCSAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwoJICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwoJICAgIH0KCSAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewoJICAgICAgICBjb25zdCBwaXRjaEZhY3RvciA9IHBhcmFtZXRlcnMucGl0Y2hGYWN0b3JbcGFyYW1ldGVycy5waXRjaEZhY3Rvci5sZW5ndGggLSAxXTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmZmdC5yZWFsVHJhbnNmb3JtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIsIGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmNvbXB1dGVNYWduaXR1ZGVzKCk7CgkgICAgICAgICAgICAgICAgdGhpcy5maW5kUGVha3MoKTsKCSAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmNvbXBsZXRlU3BlY3RydW0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmludmVyc2VUcmFuc2Zvcm0odGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmZyb21Db21wbGV4QXJyYXkodGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgb3V0cHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhvdXRwdXQpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRoaXMudGltZUN1cnNvciArPSB0aGlzLmhvcFNpemU7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCSAgICBhcHBseUhhbm5XaW5kb3coaW5wdXQpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKSB7CgkgICAgICAgICAgICBpbnB1dFtpXSAqPSB0aGlzLmhhbm5XaW5kb3dbaV07CgkgICAgICAgIH0KCSAgICB9CgkgICAgY29tcHV0ZU1hZ25pdHVkZXMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHRoaXMubWFnbml0dWRlcy5sZW5ndGg7IGkrKywgaiArPSAyKSB7CgkgICAgICAgICAgICBjb25zdCByZWFsID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqXTsKCSAgICAgICAgICAgIGNvbnN0IGltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2ogKyAxXTsKCSAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpXSA9IHJlYWwgKiogMiArIGltYWcgKiogMjsKCSAgICAgICAgfQoJICAgIH0KCSAgICBmaW5kUGVha3MoKSB7CgkgICAgICAgIHRoaXMubmJQZWFrcyA9IDA7CgkgICAgICAgIGZvciAobGV0IGkgPSAyLCBlbmQgPSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoIC0gMjsgaSA8IGVuZDsgaSsrKSB7CgkgICAgICAgICAgICBjb25zdCBtYWcgPSB0aGlzLm1hZ25pdHVkZXNbaV07CgkgICAgICAgICAgICBpZiAodGhpcy5tYWduaXR1ZGVzW2kgLSAxXSA+PSBtYWcgfHwKCSAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fAoJICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMV0gPj0gbWFnIHx8CgkgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgKyAyXSA+PSBtYWcpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXNbdGhpcy5uYlBlYWtzKytdID0gaTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdFBlYWtzKHBpdGNoRmFjdG9yKSB7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkLmZpbGwoMCk7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYlBlYWtzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleCA9IHRoaXMucGVha0luZGV4ZXNbaV07CgkgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXhTaGlmdGVkID0gTWF0aC5yb3VuZChwZWFrSW5kZXggKiBwaXRjaEZhY3Rvcik7CgkgICAgICAgICAgICBpZiAocGVha0luZGV4U2hpZnRlZCA+IHRoaXMubWFnbml0dWRlcy5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBpID4gMCA/IHBlYWtJbmRleCAtIE1hdGguZmxvb3IoKHBlYWtJbmRleCAtIHRoaXMucGVha0luZGV4ZXNbaSAtIDFdKSAvIDIpIDogMDsKCSAgICAgICAgICAgIGNvbnN0IGVuZEluZGV4ID0gaSA8IHRoaXMubmJQZWFrcyAtIDEgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpIDogdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IHN0YXJ0SW5kZXggLSBwZWFrSW5kZXg7IGogPCBlbmRJbmRleCAtIHBlYWtJbmRleDsgaisrKSB7CgkgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXggPSBwZWFrSW5kZXggKyBqOwoJICAgICAgICAgICAgICAgIGNvbnN0IGJpbkluZGV4U2hpZnRlZCA9IHBlYWtJbmRleFNoaWZ0ZWQgKyBqOwoJICAgICAgICAgICAgICAgIGlmIChiaW5JbmRleFNoaWZ0ZWQgPj0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2FEZWx0YSA9ICgyICogTWF0aC5QSSAqIChiaW5JbmRleFNoaWZ0ZWQgLSBiaW5JbmRleCkpIC8gdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CgkgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKCSAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CgkgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKCSAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CgkgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKCSAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwoJICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9Cgl9CgkvLyBAdHMtZXhwZWN0LWVycm9yCglyZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7Cgljb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCglleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCglyZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhhc2Utdm9jb2Rlci1idW5kbGUuanMubWFwCg==",J="data:text/javascript;base64,dmFyIHN0ZXJlb1RvQmZvcm1hdCA9IChmdW5jdGlvbiAoZXhwb3J0cykgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IFNRUlQxXzIgPSBNYXRoLlNRUlQxXzI7CiAgICBmdW5jdGlvbiBlbmNvZGVTdGVyZW9Ub0JGb3JtYXQobGVmdCwgcmlnaHQsIHcsIHgsIHksIHopIHsKICAgICAgICBjb25zdCBmcmFtZUNvdW50ID0gTWF0aC5taW4obGVmdC5sZW5ndGgsIHJpZ2h0Lmxlbmd0aCwgdy5sZW5ndGgsIHgubGVuZ3RoLCB5Lmxlbmd0aCwgei5sZW5ndGgpOwogICAgICAgIGZvciAobGV0IGZyYW1lID0gMDsgZnJhbWUgPCBmcmFtZUNvdW50OyBmcmFtZSsrKSB7CiAgICAgICAgICAgIGNvbnN0IGwgPSBsZWZ0W2ZyYW1lXTsKICAgICAgICAgICAgY29uc3QgciA9IHJpZ2h0W2ZyYW1lXTsKICAgICAgICAgICAgd1tmcmFtZV0gPSAobCArIHIpICogU1FSVDFfMjsKICAgICAgICAgICAgeFtmcmFtZV0gPSAwOwogICAgICAgICAgICB5W2ZyYW1lXSA9IChsIC0gcikgKiBTUVJUMV8yOwogICAgICAgICAgICB6W2ZyYW1lXSA9IDA7CiAgICAgICAgfQogICAgfQoKICAgIGNvbnN0IFdPUktMRVRfTE9HX1BSRUZJWCA9ICJbY2Fjb3Bob255L3dvcmtsZXQ6c3RlcmVvLXRvLWJmb3JtYXRdIjsKICAgIGNsYXNzIFN0ZXJlb1RvQkZvcm1hdFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgcHJvY2VzcyhpbnB1dHMsIG91dHB1dHMpIHsKICAgICAgICAgICAgY29uc3QgaW5wdXQgPSBpbnB1dHNbMF07CiAgICAgICAgICAgIGNvbnN0IG91dHB1dCA9IG91dHB1dHNbMF07CiAgICAgICAgICAgIGlmICghaW5wdXQgfHwgaW5wdXQubGVuZ3RoIDwgMiB8fCAhb3V0cHV0IHx8IG91dHB1dC5sZW5ndGggPCA0KSB7CiAgICAgICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBlbmNvZGVTdGVyZW9Ub0JGb3JtYXQoaW5wdXRbMF0sIGlucHV0WzFdLCBvdXRwdXRbMF0sIG91dHB1dFsxXSwgb3V0cHV0WzJdLCBvdXRwdXRbM10pOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICB9CiAgICBjb25zb2xlLmluZm8oYCR7V09SS0xFVF9MT0dfUFJFRklYfSBtb2R1bGUgZXZhbHVhdGluZ2ApOwogICAgdHJ5IHsKICAgICAgICBjb25zb2xlLmluZm8oYCR7V09SS0xFVF9MT0dfUFJFRklYfSByZWdpc3RlclByb2Nlc3NvciBzdGFydGApOwogICAgICAgIHJlZ2lzdGVyUHJvY2Vzc29yKCJzdGVyZW8tdG8tYmZvcm1hdCIsIFN0ZXJlb1RvQkZvcm1hdFByb2Nlc3Nvcik7CiAgICAgICAgY29uc29sZS5pbmZvKGAke1dPUktMRVRfTE9HX1BSRUZJWH0gcmVnaXN0ZXJQcm9jZXNzb3IgY29tcGxldGVgKTsKICAgIH0KICAgIGNhdGNoIChlcnJvcikgewogICAgICAgIGNvbnNvbGUuZXJyb3IoYCR7V09SS0xFVF9MT0dfUFJFRklYfSByZWdpc3RlclByb2Nlc3NvciBmYWlsZWRgLCBlcnJvcik7CiAgICAgICAgdGhyb3cgZXJyb3I7CiAgICB9CgogICAgZXhwb3J0cy5TdGVyZW9Ub0JGb3JtYXRQcm9jZXNzb3IgPSBTdGVyZW9Ub0JGb3JtYXRQcm9jZXNzb3I7CgogICAgcmV0dXJuIGV4cG9ydHM7Cgp9KSh7fSk7Ci8vIyBzb3VyY2VNYXBwaW5nVVJMPXN0ZXJlby10by1iZm9ybWF0LWJ1bmRsZS5qcy5tYXAK";class Z{listeners={};on(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!1}),()=>this.off(e,t)}once(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!0}),()=>this.off(e,t)}off(e,t){const s=this.listeners[e];s&&(this.listeners[e]=s.filter(o=>o.fn!==t))}emit(e,t){const s=this.listeners[e];s&&(s.forEach(o=>o.fn(t)),this.listeners[e]=s.filter(o=>!o.once))}emitAsync(e,t){const s=this.listeners[e];if(s){const o=s.map(g=>Promise.resolve().then(()=>g.fn(t)).catch(i=>console.error(`Error in listener for event ${e}:`,i)));return this.listeners[e]=s.filter(g=>!g.once),Promise.all(o).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class w{constructor(e=[]){this.sounds=e}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const t=this.randomSound().preplay();return t.length>0?t[0]:void 0}playRandom(){const e=this.preplayRandom();return e&&e.play(),e}preplayOrdered(e=!0){if(this.sounds.length===0||this.playIndex>=this.sounds.length)return;const s=this.sounds[this.playIndex].preplay();if(s.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!e&&this.playIndex===0&&(this.playIndex=this.sounds.length),s[0]}playOrdered(e=!0){const t=this.preplayOrdered(e);return t&&t.play(),t}get duration(){return this.sounds.map(e=>e.duration).reduce((e,t)=>Math.max(e,t),0)}seek(e){this.sounds.forEach(t=>t.seek?.(e))}addSound(e){this.sounds.push(e)}randomSound(){if(this.sounds.length===0)throw new Error("Cannot get a random sound from an empty group");const e=Math.floor(Math.random()*this.sounds.length);return this.sounds[e]}preplay(){return this.sounds.map(t=>t.preplay()).flat()}play(){const e=[];return this.preplay().forEach(t=>{t.play(),e.push(t)}),e}get isPlaying(){return this.sounds.some(e=>e.isPlaying)}stop(){this.sounds.forEach(e=>e.stop())}pause(){this.sounds.forEach(e=>e.pause())}fadeTo(e,t,s){return Promise.all(this.sounds.map(o=>o.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.sounds.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.sounds.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.sounds.map(s=>s.stopWithFade(e,t))).then(()=>{})}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(t=>t.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(t=>t.addFilter(e))}removeFilter(e){this.sounds.forEach(t=>t.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(t=>t.position=this._position)}get position(){return this._position}get volume(){return this.sounds.length===0?1:this.sounds.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.sounds.length}set volume(e){this.sounds.forEach(t=>t.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(t=>t.playbackRate=e)}}class b{_filters=[];addFilter(e){if(this._filters.includes(e))throw new Error("Cannot add the same filter instance twice");this._filters.push(e)}removeFilter(e){const t=this._filters.length;if(this._filters=this._filters.filter(s=>s!==e),this._filters.length===t)throw new Error("Cannot remove filter that was never added to this container")}applyFilters(e){return this._filters.reduce((t,s)=>(t.connect(s),s),e),this._filters.length>0?this._filters[this._filters.length-1]:e}get filters(){return this._filters}addFilters(e){e.forEach(t=>this.addFilter(t))}removeFilters(e){e.forEach(t=>this.removeFilter(t))}cleanup(){this._filters.forEach(e=>e.disconnect()),this._filters=[]}}class X extends b{context;source;gainNode;panner;constructor(e,t,s,o=0){super(),this.source=e,this.gainNode=t,this.context=s,this.panner=s.createPanner(),e.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}get isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!0)}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,s,o]=e;this.panner.positionX.value=t,this.panner.positionY.value=s,this.panner.positionZ.value=o}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class T extends b{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e,t){super(),this.context=e,this.microphoneGainNode=this.context.createGain(),t&&(this.stream=t,this.streamSource=this.createStreamSource(t))}createStreamSource(e){if(!this.context.createMediaStreamSource)throw new Error("Media stream sources are not supported on this audio context (e.g. OfflineAudioContext).");return this.context.createMediaStreamSource(e)}play(){return this.stream?(this.streamPlayback||(this.streamSource=this.streamSource??this.createStreamSource(this.stream),this.streamPlayback=new X(this.streamSource,this.microphoneGainNode,this.context)),[this.streamPlayback]):(navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.createStreamSource(this.stream),this.streamPlayback=new X(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),[])}get duration(){return 0}seek(e){}get isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(e){this.streamPlayback&&this.streamPlayback.addFilter(e)}removeFilter(e){this.streamPlayback&&this.streamPlayback.removeFilter(e)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(e){this.streamPlayback&&(this.streamPlayback.volume=e)}get position(){return[0,0,0]}set position(e){}loop(e){return 0}get playbackRate(){return 1}set playbackRate(e){}}function W(c){class e extends c{playbacks=[];_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};_volume=1;play(){const s=this.preplay();return s.forEach(o=>o.play()),s}stop(){this.playbacks.forEach(s=>{s.stop(),s.cleanup()}),this.playbacks=[]}pause(){this.playbacks.forEach(s=>s.pause())}addFilter(s){super.addFilter(s)}removeFilter(s){super.removeFilter(s)}get isPlaying(){return this.playbacks.some(s=>s.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(s){this._threeDOptions.positionX=s[0],this._threeDOptions.positionY=s[1],this._threeDOptions.positionZ=s[2],this.playbacks.forEach(o=>o.position=s)}get threeDOptions(){return this._threeDOptions}set threeDOptions(s){this._threeDOptions={...this._threeDOptions,...s},this.playbacks.forEach(o=>o.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(s){this._stereoPan=s,this.playbacks.forEach(o=>o.stereoPan=s)}get volume(){return this._volume}set volume(s){this._volume=s,this.playbacks.forEach(o=>o.volume=s)}fadeTo(s,o,g){return this._volume=s,Promise.all(this.playbacks.map(i=>i.fadeTo(s,o,g))).then(()=>{})}fadeIn(s,o){return Promise.all(this.playbacks.map(g=>g.fadeIn(s,o))).then(()=>{})}fadeOut(s,o){return Promise.all(this.playbacks.map(g=>g.fadeOut(s,o))).then(()=>{})}stopWithFade(s,o){return this.fadeOut(s,o).then(()=>this.stop())}}return e}function F(c){class e extends c{panner;_panType="stereo";get panType(){return this._panType}setPanType(s,o){this._panType===s&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=s,s==="stereo"?this.panner=o.createStereoPanner():this.panner=o.createPanner())}setPannerNode(s){this.panner=s}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(s){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");if(s<-1||s>1)throw new RangeError("Stereo pan must be between -1 and 1.");this.panner.pan.setValueAtTime(s,this.panner.context.currentTime)}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const s=this.panner;return{coneInnerAngle:s.coneInnerAngle,coneOuterAngle:s.coneOuterAngle,coneOuterGain:s.coneOuterGain,distanceModel:s.distanceModel,maxDistance:s.maxDistance,channelCount:this.panner.channelCount,channelCountMode:s.channelCountMode,channelInterpretation:s.channelInterpretation,panningModel:s.panningModel,refDistance:s.refDistance,rolloffFactor:s.rolloffFactor,positionX:s.positionX.value,positionY:s.positionY.value,positionZ:s.positionZ.value,orientationX:s.orientationX.value,orientationY:s.orientationY.value,orientationZ:s.orientationZ.value}}set threeDOptions(s){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const o=this.panner;o.coneInnerAngle=s.coneInnerAngle!==void 0?s.coneInnerAngle:o.coneInnerAngle,o.coneOuterAngle=s.coneOuterAngle!==void 0?s.coneOuterAngle:o.coneOuterAngle,o.coneOuterGain=s.coneOuterGain!==void 0?s.coneOuterGain:o.coneOuterGain,o.distanceModel=s.distanceModel||o.distanceModel,o.maxDistance=s.maxDistance!==void 0?s.maxDistance:o.maxDistance,o.channelCount=s.channelCount!==void 0?s.channelCount:o.channelCount,o.channelCountMode=s.channelCountMode||o.channelCountMode,o.channelInterpretation=s.channelInterpretation||o.channelInterpretation,o.panningModel=s.panningModel||o.panningModel,o.refDistance=s.refDistance!==void 0?s.refDistance:o.refDistance,o.rolloffFactor=s.rolloffFactor!==void 0?s.rolloffFactor:o.rolloffFactor,o.positionX.value=s.positionX!==void 0?s.positionX:o.positionX.value,o.positionY.value=s.positionY!==void 0?s.positionY:o.positionY.value,o.positionZ.value=s.positionZ!==void 0?s.positionZ:o.positionZ.value,o.orientationX.value=s.orientationX!==void 0?s.orientationX:o.orientationX.value,o.orientationY.value=s.orientationY!==void 0?s.orientationY:o.orientationY.value,o.orientationZ.value=s.orientationZ!==void 0?s.orientationZ:o.orientationZ.value}set position(s){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[o,g,i]=s,a=this.panner;a.positionX.value=o,a.positionY.value=g,a.positionZ.value=i}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const s=this.panner;return[s.positionX.value,s.positionY.value,s.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return e}function H(c){class e extends c{gainNode;_fadeTimeout;_isFading=!1;setGainNode(s){this.gainNode=s}cleanup(){this.cancelFade(),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),super.cleanup()}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(s){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.cancelFade(),this.gainNode.gain.value=s}get isFading(){return this._isFading}fadeTo(s,o,g="linear"){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");this.cancelFade();const i=this.gainNode.context.currentTime,a=i+o/1e3;return this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,i),g==="exponential"?this.gainNode.gain.exponentialRampToValueAtTime(s===0?1e-4:s,a):this.gainNode.gain.linearRampToValueAtTime(s,a),this._isFading=!0,new Promise(n=>{this._fadeTimeout=setTimeout(()=>{this._isFading=!1,s===0&&g==="exponential"&&this.gainNode&&(this.gainNode.gain.value=0),n()},o)})}cancelFade(){if(this._fadeTimeout&&(clearTimeout(this._fadeTimeout),this._fadeTimeout=void 0),this._isFading&&this.gainNode){const s=this.gainNode.context.currentTime;this.gainNode.gain.cancelScheduledValues(s),this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,s)}this._isFading=!1}fadeIn(s,o){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");const g=this.gainNode.gain.value;return this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(g,s,o)}fadeOut(s,o){return this.fadeTo(0,s,o)}}return e}class N extends F(H(b)){source;_playing=!1;origin;eventEmitter=new Z;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}fadeTo(e,t,s="linear"){return this.emit("fadeStart",{target:e,duration:t,type:s}),super.fadeTo(e,t,s).then(()=>{this.emit("fadeEnd",void 0)})}cancelFade(){const e=this._isFading;super.cancelFade(),e&&this.emit("fadeCancel",void 0)}cleanup(){this.eventEmitter.removeAllListeners(),super.cleanup()}}class G extends N{constructor(e,t,s){super(),this.origin=e,this.context=e.context,this.loopCount=e.loopCount,this.setPanType(e.panType,e.context),this.source=t,"buffer"in t&&t.buffer&&(this.buffer=t.buffer),this.setupSourceNode(t),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;_fadeInConfig;_fadeOutConfig;_loopEndCallback;setupSourceNode(e){if("mediaElement"in e&&e.mediaElement)e.mediaElement.onended=this.loopEnded;else if("onended"in e)e.onended=this.loopEnded;else throw new Error("Unsupported source type")}get isPlaying(){return this._state===1}get duration(){if(!this.source)throw new Error("Cannot get duration of a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.duration:this.buffer?this.buffer.duration||NaN:NaN}get playbackRate(){return this._playbackRate}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}set playbackRate(e){if(e<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const t=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=t,this._startTime=this.context.currentTime}this._playbackRate=e,this.source&&("playbackRate"in this.source&&(this.source.playbackRate.value=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=e))}loopEnded=()=>{!this.source||this._state!==1||(this.currentLoop++,this.loopCount!=="infinite"&&this.currentLoop>this.loopCount?(this.emit("ended",void 0),this._fadeOutConfig?this.fadeOut(this._fadeOutConfig.duration,this._fadeOutConfig.type).then(()=>{this.stop(),this.removeFromOrigin()}):(this.stop(),this.removeFromOrigin())):(this._loopEndCallback?.(),this.seek(0),this._state!==1&&!("mediaElement"in this.source)&&this.play(),this._fadeInConfig?.perLoop&&this.gainNode&&(this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(this._fadeInConfig.targetVolume,this._fadeInConfig.duration,this._fadeInConfig.type))))};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");if(this._state===1)return[this];const e=this._state===2;try{let t;if(this._state===2?"mediaElement"in this.source&&this.source.mediaElement?t=this.source.mediaElement.play():(this.recreateSource(),"start"in this.source&&this.source.start&&this.source.start(0,this._offset)):"mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.currentTime=this._offset,t=this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),t){const s=this._state;t.then(()=>{this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()})},o=>{this._state=s,this.emitAsync("error",{error:o,errorType:"source",timestamp:Date.now(),recoverable:!0})})}else this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()});return[this]}catch(t){throw this.emitAsync("error",{error:t,errorType:"source",timestamp:Date.now(),recoverable:!0}),t}}pause(){if(!this.source||this._state!==1)return;const e=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=e,"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.pause():"stop"in this.source&&this.source.stop(),this._state=2,this.emit("pause",void 0),this.origin.cacophony?.emit("globalPause",{source:this.origin,timestamp:Date.now()})}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this._state===3||this._state===0||(this.cancelFade(),"stop"in this.source&&this._state===1&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this._offset=0,this._startTime=0,this._state=3,this.emit("stop",void 0),this.origin.cacophony?.emit("globalStop",{source:this.origin,timestamp:Date.now()}))}fadeIn(e,t,s){return s?.perLoop&&(this._fadeInConfig={duration:e,type:t||"linear",perLoop:!0,targetVolume:this.gainNode.gain.value}),super.fadeIn(e,t)}configureFadeOut(e,t){this._fadeOutConfig={duration:e,type:t||"linear"}}stopWithFade(e,t){return this.fadeOut(e,t).then(()=>this.stop())}seek(e){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");if(!Number.isFinite(e)||e<0)throw new Error("Invalid time value for seek");const t=this._state===1;t&&this.pause(),this._offset=e,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=e),t&&this.play()}get currentTime(){if(this._state===1){const e=(this.context.currentTime-this._startTime)*this._playbackRate;return this._offset+e}else return this._offset}removeFromOrigin(){const e=this.origin.playbacks.indexOf(this);e!==-1&&this.origin.playbacks.splice(e,1)}recreateSource(){if(!this.buffer||!this.panner||!this.context||!this.gainNode)throw new Error("Cannot recreate source of a sound that has been cleaned up");try{this.source&&(!("mediaElement"in this.source)&&"onended"in this.source&&(this.source.onended=null),this.source.disconnect()),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.loopEnded,this.playbackRate=this._playbackRate,this.refreshFilters()}catch(e){throw this.emitAsync("error",{error:e,errorType:"source",timestamp:Date.now(),recoverable:!1}),e}}set sourceLoop(e){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=e)}cleanup(){this.source&&("mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0,this.source.mediaElement.loop=!1,this.source.mediaElement.onended=null):"onended"in this.source&&(this.source.onended=null),this._offset=0,this._startTime=0,this._state=3,this.currentLoop=0,this.source.disconnect(),this.source=void 0,super.cleanup())}assertNotCleanedUp(){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot perform operation on a sound that has been cleaned up")}addFilter(e){this.assertNotCleanedUp(),super.addFilter(e),this.refreshFilters()}removeFilter(e){this.assertNotCleanedUp(),super.removeFilter(e),this.refreshFilters()}loop(e){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(e!==void 0&&(this.loopCount=e==="infinite"?"infinite":Math.max(0,e),this.currentLoop=0),"mediaElement"in this.source&&this.source.mediaElement){const t=this.source.mediaElement;t.loop=this.loopCount==="infinite"}else if("loop"in this.source)this.source.loop=this.loopCount==="infinite",this.source.buffer&&(this.source.loopEnd=this.source.buffer.duration,this.source.loopStart=0);else throw new Error("Unsupported source type");return this.loopCount}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get outputNode(){if(!this.gainNode)throw new Error("Cannot access output node of a playback that has been cleaned up");return this.gainNode}connect(e){return this.outputNode.connect(e)}disconnect(e){e?this.outputNode.disconnect(e):this.outputNode.disconnect()}clone(e={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const t=e.panType||this.panType,s=this.context.createGain();let o;if("buffer"in this.source&&this.source.buffer)o=this.context.createBufferSource(),o.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement){if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context.");o=this.context.createMediaElementSource(this.source.mediaElement)}else throw new Error("Unsupported source type");const g=e.loopCount!==void 0?e.loopCount:this.loopCount,i=new G(this.origin,o,s);return i.loopCount=g,i.currentLoop=this.currentLoop,i.setPanType(t,this.context),i.volume=this.volume,i.playbackRate=this._playbackRate,i._offset=this._offset,i._state=this._state,this._filters.forEach(a=>{const n=this.context.createBiquadFilter();n.type=a.type,n.frequency.value=a.frequency.value,n.Q.value=a.Q.value,n.gain.value=a.gain.value,i.addFilter(n)}),this._state===1&&i.play(),i}}class y extends W(b){constructor(e,t,s,o,g=f.Buffer,i="HRTF",a){super(),this.url=e,this.globalGainNode=o,this.soundType=g,this.panType=i,this._cacophony=a,this.buffer=t,this.context=s,this._cacophony?.registerSoundForCleanup(this,this._holdings,this._unregisterToken)}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new Z;_holdings={sources:[],gainNodes:[],mediaElements:[]};_unregisterToken={};get cacophony(){return this._cacophony}get volume(){return super.volume}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan,o=e.threeDOptions||this.threeDOptions,g=e.loopCount!==void 0?e.loopCount:this.loopCount,i=e.playbackRate||this.playbackRate,a=e.volume!==void 0?e.volume:this.volume,n=e.position!==void 0?e.position:this.position,I=e.filters?.length?e.filters:this._filters,r=new y(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,t,this.cacophony);return r.loop(g),r.playbackRate=i,r.volume=a,t==="HRTF"?(r.threeDOptions=o,r.position=n):r.stereoPan=s,r.addFilters(I),r}preplay(){try{let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context (e.g. OfflineAudioContext). Use buffer-based sounds instead.");const o=new Audio;o.crossOrigin="anonymous",o.src=this.url,o.preload="auto",e=this.context.createMediaElementSource(o)}const t=this.context.createGain();t.connect(this.globalGainNode);const s=new G(this,e,t);return this._holdings.sources.push(e),this._holdings.gainNodes.push(t),"mediaElement"in e&&e.mediaElement&&this._holdings.mediaElements.push(e.mediaElement),s.setGainNode(t),s.volume=this.volume,s.playbackRate=this.playbackRate,this._filters.forEach(o=>{const g=this.context.createBiquadFilter();g.type=o.type,g.frequency.value=o.frequency.value,g.Q.value=o.Q.value,g.gain.value=o.gain.value,s.addFilter(g)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),s.on("ended",()=>{this.emit("ended",void 0)}),s._loopEndCallback=()=>{this.emit("loopEnd",void 0)},s.on("error",o=>{this.emitAsync("soundError",{url:this.url,error:o.error,errorType:"playback",timestamp:o.timestamp,recoverable:o.recoverable})}),this.playbacks.push(s),[s]}catch(e){const t={url:this.url,error:e,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",t),e}}play(e){const t=this.preplay();for(const s of t){const o=i=>{g(),this.emit("play",i)},g=()=>{s.off("play",o),s.off("error",g)};s.on("play",o),s.on("error",g);try{s.play()}catch(i){throw g(),i}}if(e)for(const s of t)e.fadeIn!==void 0&&s.fadeIn(e.fadeIn,e.fadeType,{perLoop:e.fadeInPerLoop}),e.fadeOut!==void 0&&s.configureFadeOut(e.fadeOut,e.fadeType);return t}stop(){this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0)}seek(e){this.playbacks.forEach(t=>t.seek(e))}get duration(){return this.playbacks.length>0?this.playbacks[0].duration:this.buffer?.duration||NaN}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.playbacks.forEach(t=>t.loop(e)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(t=>t.playbackRate=e),this.emit("rateChange",e)}set volume(e){super.volume=e,this.emit("volumeChange",e)}cleanup(){this._cacophony?.unregisterSoundCleanup(this._unregisterToken),this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,this.playbacks.forEach(e=>e.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}function M(c){class e extends N{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(s){this._oscillatorOptions=s,this.source&&(this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type))}play(){if(!this.source)throw new Error("No source node found");return this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,[this]}stop(){this.source?.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(s){this.source.frequency.value=s,this.oscillatorOptions.frequency=s}get detune(){return this.source.detune.value}set detune(s){this.source.detune.value=s,this.oscillatorOptions.detune=s}get type(){return this.source.type}set type(s){this.source.type=s,this.oscillatorOptions.type=s}}return e}class O extends M(F(H(b))){constructor(e,t,s){super(),this.origin=e,this.source=t,this.context=e.context,this.setPanType(e.panType,e.context),this.source.connect(this.panner),this.setGainNode(s),this.panner.connect(this.gainNode),this.refreshFilters(),this.oscillatorOptions={detune:t.detune.value,frequency:t.frequency.value,type:t.type}}context;_state=0;play(){if(!this.source||!this.panner)throw new Error("Cannot play a synth that has been cleaned up");return this._state===1?[this]:((this._state===2||this._state===3)&&this.recreateSource(),this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,this._state=1,[this])}pause(){!this.source||this._state!==1||(this.source.stop(),this._playing=!1,this._state=2)}stop(){!this.source||this._state===0||this._state===3||(this._state===1&&this.source.stop(),this._playing=!1,this._state=3)}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}cleanup(){this.panner&&this.gainNode&&(this.source.disconnect(this.panner),this.panner.disconnect(),this.gainNode.disconnect()),this.eventEmitter.removeAllListeners()}recreateSource(){if(!this.panner)throw new Error("Cannot recreate source of a synth that has been cleaned up");this.source.disconnect(),this.source=this.context.createOscillator(),this.source.connect(this.panner)}}class B extends W(b){constructor(e,t,s=f.Oscillator,o="HRTF",g={},i){super(),this.context=e,this.globalGainNode=t,this.soundType=s,this.panType=o,this.cacophony=i,this.context=e,this._oscillatorOptions=g}_oscillatorOptions;playbacks=[];eventEmitter=new Z;on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,s=e.stereoPan!==void 0?e.stereoPan:this.stereoPan??0,o=e.threeDOptions||this.threeDOptions,g=e.volume!==void 0?e.volume:this.volume,i=e.position?.length?e.position:this.position,a=e.filters?.length?e.filters:this._filters,n=e.oscillatorOptions||this._oscillatorOptions,I=new B(this.context,this.globalGainNode,this.soundType,t,n,this.cacophony);return I._volume=g,I._position=i,I._stereoPan=s,I._threeDOptions=o,I.addFilters(a),I}preplay(){const e=this.context.createOscillator();return this.createPlayback(e)}createPlayback(e){this.oscillatorOptions.detune!==void 0&&(e.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(e.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.type=this.oscillatorOptions.type);const t=this.context.createGain();t.connect(this.globalGainNode);const s=new O(this,e,t);return s.volume=this.volume,this._filters.forEach(o=>{const g=this.context.createBiquadFilter();g.type=o.type,g.frequency.value=o.frequency.value,g.Q.value=o.Q.value,g.gain.value=o.gain.value,s.addFilter(g)}),this.panType==="HRTF"?(s.threeDOptions=this.threeDOptions,s.position=this.position):this.panType==="stereo"&&(s.stereoPan=this.stereoPan),this.playbacks.push(s),[s]}play(){const e=super.play();return this.emit("play",e[0]),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()}),e}stop(){super.stop(),this.emit("stop",void 0),this.cacophony?.emit("globalStop",{source:this,timestamp:Date.now()})}pause(){super.pause(),this.emit("pause",void 0),this.cacophony?.emit("globalPause",{source:this,timestamp:Date.now()})}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()})}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(e){this._oscillatorOptions=e,this.playbacks.forEach(t=>{t.source&&(this.oscillatorOptions.detune!==void 0&&(t.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(t.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(t.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency??440}set frequency(e){this._oscillatorOptions.frequency=e,this.playbacks.forEach(t=>t.frequency=e),this.emit("frequencyChange",e)}get detune(){return this.oscillatorOptions.detune}set detune(e){this._oscillatorOptions.detune=e,this.playbacks.forEach(t=>t.detune=e),this.emit("detuneChange",e)}get type(){return this.oscillatorOptions.type||"sine"}set type(e){this._oscillatorOptions.type=e,this.playbacks.forEach(t=>t.type=e),this.emit("typeChange",e)}}var f=(c=>(c.HTML="HTML",c.Streaming="Streaming",c.Buffer="Buffer",c.Oscillator="oscillator",c))(f||{});const u="[cacophony/worklet]";class R{context;globalGainNode;listener;prevVolume=1;loadedAudioWorklets=new Set;finalizationRegistry;eventEmitter=new Z;cache;createAudioWorkletNode;constructor(e,t,s={}){this.context=e||new AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=t||new C,this.createAudioWorkletNode=s.createAudioWorkletNode||((o,g,i)=>new AudioWorkletNode(o,g,i)),this.finalizationRegistry=new FinalizationRegistry(o=>{for(const g of o.sources)g.disconnect();for(const g of o.gainNodes)g.disconnect();for(const g of o.mediaElements)g.pause(),g.removeAttribute("src"),g.load()})}registerSoundForCleanup(e,t,s){this.finalizationRegistry.register(e,t,s)}unregisterSoundCleanup(e){this.finalizationRegistry.unregister(e)}static createOffline(e,t){const s=e.context||new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate);return new R(s,t)}get isOffline(){return typeof this.context.startRendering=="function"}async startRendering(){if(typeof this.context.startRendering!="function")throw new Error("startRendering() is only available on offline audio contexts. Use Cacophony.createOffline() to create one.");return this.context.startRendering()}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}async loadWorklets(e){this.context.audioWorklet?(await this.createWorkletNode("phase-vocoder",D,e),await this.loadStereoToBFormatWorklet(e)):console.warn("AudioWorklet not supported")}async loadStereoToBFormatWorklet(e){await this.loadAudioWorkletModule("stereo-to-bformat",J,e)}async createWorkletNode(e,t,s,o){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{const g=this.createAudioWorkletNode(this.context,e,o);return console.info(`${u} construct succeeded`,{name:e,loaded:this.loadedAudioWorklets.has(e)}),g}catch(g){console.warn(`${u} construct failed`,{name:e,loaded:this.loadedAudioWorklets.has(e),error:g});try{await this.loadAudioWorkletModule(e,t,s)}catch(i){throw console.error(`${u} load failed`,{name:e,error:i}),i}try{const i=this.createAudioWorkletNode(this.context,e,o);return console.info(`${u} construct after load succeeded`,{name:e}),i}catch(i){throw console.error(`${u} construct after load failed`,{name:e,error:i}),i}}}async createStereoToBFormatNode(e){return this.createWorkletNode("stereo-to-bformat",J,e,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[4],channelCount:2,channelCountMode:"explicit",channelInterpretation:"speakers"})}async loadAudioWorkletModule(e,t,s){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");if(this.loadedAudioWorklets.has(e)){console.info(`${u} load skipped`,{name:e});return}console.info(`${u} addModule start`,{name:e,url:t,aborted:s?.aborted??!1});try{await this.context.audioWorklet.addModule(t,{credentials:"same-origin",...s&&{signal:s}}),this.loadedAudioWorklets.add(e),console.info(`${u} addModule resolved`,{name:e})}catch(o){throw console.error(`${u} addModule rejected`,{name:e,error:o}),o}}createAbortError(){return new DOMException("Operation was aborted","AbortError")}createMediaSound(e,t,s,o){return o?.aborted?Promise.reject(this.createAbortError()):new Promise((g,i)=>{const a=new Audio;let n=!1;const I=()=>{a.removeEventListener("loadedmetadata",A),a.removeEventListener("error",p),o?.removeEventListener("abort",m)},r=()=>{a.pause(),a.src="",a.load()},l=d=>{n||(n=!0,I(),d())},A=()=>{l(()=>{g(new y(e,void 0,this.context,this.globalGainNode,t,s,this))})},p=()=>{const d=new Error(`Failed to load audio from ${e}`);l(()=>{r(),i(d)})},m=()=>{const d=this.createAbortError();l(()=>{r(),i(d)})};a.crossOrigin="anonymous",a.preload="auto",a.addEventListener("loadedmetadata",A),a.addEventListener("error",p),o?.addEventListener("abort",m,{once:!0}),a.src=e,a.load()})}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(e,t="HRTF"){return new B(this.context,this.globalGainNode,"oscillator",t,e,this)}async createSound(e,t="Buffer",s="HRTF",o){if(typeof e=="object")return Promise.resolve(new y("",e,this.context,this.globalGainNode,"Buffer",s,this));const g=e;return t==="HTML"?this.createMediaSound(g,"HTML",s,o):t==="Streaming"?this.createMediaSound(g,"Streaming",s,o):this.cache.getAudioBuffer(this.context,g,o,{onLoadingStart:i=>this.emitAsync("loadingStart",i),onLoadingProgress:i=>this.emitAsync("loadingProgress",i),onLoadingComplete:i=>this.emitAsync("loadingComplete",i),onLoadingError:i=>this.emitAsync("loadingError",i),onCacheHit:i=>this.emitAsync("cacheHit",i),onCacheMiss:i=>this.emitAsync("cacheMiss",i),onCacheError:i=>this.emitAsync("cacheError",i)}).then(i=>new y(g,i,this.context,this.globalGainNode,t,s,this))}async createGroup(e){const t=new w;return e.forEach(s=>t.addSound(s)),t}async createGroupFromUrls(e,t="Buffer",s="HRTF",o){const g=new w;return(await Promise.all(e.map(a=>this.createSound(a,t,s,o)))).forEach(a=>g.addSound(a)),g}async createStream(e,t){return this.createMediaSound(e,"Streaming","HRTF",t)}createBiquadFilter=({type:e,frequency:t,gain:s,Q:o})=>{t===void 0&&(t=350);const g=this.context.createBiquadFilter();return g.type=e||"lowpass",g.frequency.value=t,g.gain.value=s||0,g.Q.value=o||1,g};createSplitter(e=2){if(!this.context.createChannelSplitter)throw new Error("ChannelSplitterNode not supported");return this.context.createChannelSplitter(e)}createMerger(e=2){if(!this.context.createChannelMerger)throw new Error("ChannelMergerNode not supported");return this.context.createChannelMerger(e)}createPanner({coneInnerAngle:e,coneOuterAngle:t,coneOuterGain:s,distanceModel:o,maxDistance:g,channelCount:i,channelCountMode:a,channelInterpretation:n,panningModel:I,refDistance:r,rolloffFactor:l,positionX:A,positionY:p,positionZ:m,orientationX:d,orientationY:S,orientationZ:K}){const h=this.context.createPanner();return h.coneInnerAngle=e||360,h.coneOuterAngle=t||360,h.coneOuterGain=s||0,h.distanceModel=o||"inverse",h.maxDistance=g||1e4,h.channelCount=i||2,h.channelCountMode=a||"clamped-max",h.channelInterpretation=n||"speakers",h.panningModel=I||"HRTF",h.refDistance=r||1,h.rolloffFactor=l||1,h.positionX.value=A||0,h.positionY.value=p||0,h.positionZ.value=m||0,h.orientationX.value=d||0,h.orientationY.value=S||0,h.orientationZ.value=K||0,h}pause(){this.context.suspend&&(this.context.suspend(),this.emit("suspend",void 0))}resume(){this.context.resume&&(this.context.resume(),this.emit("resume",void 0))}setGlobalVolume(e){this.globalGainNode.gain.value!==e&&(this.globalGainNode.gain.value=e,this.emit("volumeChange",e))}get volume(){return this.globalGainNode.gain.value}set volume(e){if(this.muted){this.prevVolume=e;return}this.setGlobalVolume(e)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0),this.emit("mute",void 0))}unmute(){this.muted&&(this.setGlobalVolume(this.prevVolume),this.emit("unmute",void 0))}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(s=>{const o=new T(this.context,s);e(o)}).catch(s=>{t(s)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(e){const{forward:t,up:s}=e,[o,g,i]=t,[a,n,I]=s;this.listener.forwardX.value=o,this.listener.forwardY.value=g,this.listener.forwardZ.value=i,this.listener.upX.value=a,this.listener.upY.value=n,this.listener.upZ.value=I}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[t,s,o]=e;this.listener.upX.value=t,this.listener.upY.value=s,this.listener.upZ.value=o}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[t,s,o]=e;this.listener.forwardX.value=t,this.listener.forwardY.value=s,this.listener.forwardZ.value=o}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[t,s,o]=e,g=this.context.currentTime;this.listener.positionX.setValueAtTime(t,g),this.listener.positionY.setValueAtTime(s,g),this.listener.positionZ.setValueAtTime(o,g)}}class P{constructor(e=[]){this.synths=e}addSynth(e){this.synths.push(e)}removeSynth(e){const t=this.synths.indexOf(e);if(t!==-1)this.synths.splice(t,1);else throw new Error("Synth not found in group")}play(){return this.synths.flatMap(e=>e.play())}stop(){this.synths.forEach(e=>e.stop())}pause(){this.synths.forEach(e=>e.pause())}resume(){this.synths.forEach(e=>e.resume())}get isPlaying(){return this.synths.some(e=>e.isPlaying)}addFilter(e){this.synths.forEach(t=>t.addFilter(e))}removeFilter(e){this.synths.forEach(t=>t.removeFilter(e))}fadeTo(e,t,s){return Promise.all(this.synths.map(o=>o.fadeTo(e,t,s))).then(()=>{})}fadeIn(e,t){return Promise.all(this.synths.map(s=>s.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.synths.map(s=>s.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.synths.map(s=>s.stopWithFade(e,t))).then(()=>{})}get volume(){return this.synths.length===0?1:this.synths.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.synths.length}set volume(e){this.synths.forEach(t=>t.volume=e)}get stereoPan(){return this.synths.length===0?null:this.synths[0].stereoPan}set stereoPan(e){this.synths.forEach(t=>t.stereoPan=e)}get position(){return this.synths.length===0?[0,0,0]:this.synths[0].position}set position(e){this.synths.forEach(t=>t.position=e)}get frequency(){return this.synths.length===0?440:this.synths[0].frequency}set frequency(e){this.synths.forEach(t=>t.frequency=e)}get detune(){return this.synths[0]?.detune}set detune(e){this.synths.forEach(t=>t.detune=e)}get type(){return this.synths.length===0?"sine":this.synths[0].type}set type(e){this.synths.forEach(t=>t.type=e)}}exports.AudioCache=C;exports.Cacophony=R;exports.Group=w;exports.MicrophonePlayback=X;exports.Playback=G;exports.Sound=y;exports.SoundType=f;exports.Synth=B;exports.SynthGroup=P;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class V{maxSize;cache;constructor(e){this.maxSize=e,this.cache=new Map}get(e){if(!this.cache.has(e))return;const t=this.cache.get(e);return this.cache.delete(e),this.cache.set(e,t),t}set(e,t){if(this.cache.has(e))this.cache.delete(e);else if(this.cache.size>=this.maxSize){const g=this.cache.keys().next().value;g!==void 0&&this.cache.delete(g)}this.cache.set(e,t)}has(e){return this.cache.has(e)}}const k=100;function Y(c){if(!c)return null;const e=c.match(/max-age\s*=\s*"?(\d+)"?/i);return e?parseInt(e[1],10):null}function E(c){return c?/(?:^|,)\s*(no-cache|no-store|must-revalidate)\s*(?:,|$)/i.test(c):!1}function v(c){return c instanceof DOMException&&c.name==="AbortError"?"abort":c instanceof Error?"network":"unknown"}class r{static pendingRequests=new Map;static pendingCallbacks=new Map;static decodedBuffers=new V(k);static cacheExpirationTime=1440*60*1e3;static setCacheExpirationTime(e){r.cacheExpirationTime=e}static async openCache(){try{return await caches.open("audio-cache")}catch(e){throw console.error("Failed to open cache:",e),e}}static callAllCallbacks(e,t,g){const s=r.pendingCallbacks.get(e);s&&s.forEach(o=>{const i=o[t];if(i)try{i(g)}catch(a){console.error(`Error in ${t} callback:`,a)}})}static async getOrCreatePendingRequest(e,t,g,s){if(g?.aborted)throw new DOMException("Operation was aborted","AbortError");if(s){const i=r.pendingCallbacks.get(e)||[];i.push(s),r.pendingCallbacks.set(e,i)}const o=r.pendingRequests.get(e);if(!o){const i=(async()=>{try{const a=await t();if(a===void 0)throw new Error("Failed to create audio buffer.");return a}finally{r.pendingRequests.delete(e),r.pendingCallbacks.delete(e)}})();return g?.addEventListener("abort",()=>{g.aborted&&(r.pendingRequests.delete(e),r.pendingCallbacks.delete(e))},{once:!0}),r.pendingRequests.set(e,i),i}return o}static async updateMetadata(e,t,g){const s={url:t,timestamp:Date.now(),...g};await e.put(`${t}:meta`,new Response(JSON.stringify(s),{headers:{"Content-Type":"application/json"}}))}static async getBufferFromCache(e,t){try{const g=await t.match(e);return g?.ok?await g.arrayBuffer():null}catch(g){return console.error("Failed to get data from cache:",g),null}}static async fetchAndCacheBuffer(e,t,g,s,o,i){const a=new Headers;g&&a.append("If-None-Match",g),s&&a.append("If-Modified-Since",s),console.debug(`[AudioCache] Fetching ${e}`,{headers:Object.fromEntries(a.entries()),hasEtag:!!g,hasLastModified:!!s});const n=await fetch(e,{headers:a,signal:o});if(console.debug(`[AudioCache] Response ${e}`,{status:n.status,statusText:n.statusText,etag:n.headers?.get("ETag"),lastModified:n.headers?.get("Last-Modified"),cacheControl:n.headers?.get("Cache-Control")}),n.status===304){const I=await t.match(e);if(I){i?.onCacheHit&&i.onCacheHit({url:e,cacheType:"conditional",timestamp:Date.now()});const C=Date.now(),l=n.headers?.get("Cache-Control");return await r.updateMetadata(t,e,{timestamp:C,etag:g,lastModified:s,...l?{cacheControl:l}:{}}),await I.arrayBuffer()}else{console.warn(`Cache inconsistency detected for ${e}: 304 response but no cached body. Re-fetching.`);const C=await fetch(e,{signal:o});if(C.status===200){const l=C.clone(),h=C.headers.get("ETag"),p=C.headers.get("Last-Modified"),m=C.headers.get("Cache-Control");try{await Promise.all([t.put(e,l),r.updateMetadata(t,e,{timestamp:Date.now(),etag:h||void 0,lastModified:p||void 0,cacheControl:m||void 0})])}catch(d){throw await t.delete(e),await t.delete(`${e}:meta`),d}if(C.body){const{stream:d,total:w}=r.createProgressTrackingStream(C,e);return await r.collectStreamToArrayBuffer(d,w||void 0)}else return await C.arrayBuffer()}else throw new Error(`Failed to fetch resource after cache inconsistency: ${C.status} ${C.statusText}`)}}if(n.status===200){const I=n.clone(),C=n.headers.get("ETag"),l=n.headers.get("Last-Modified"),h=n.headers.get("Cache-Control");try{await Promise.all([t.put(e,I),r.updateMetadata(t,e,{timestamp:Date.now(),etag:C||void 0,lastModified:l||void 0,cacheControl:h||void 0})])}catch(p){throw await t.delete(e),await t.delete(`${e}:meta`),p}}if(o?.aborted)throw new DOMException("Operation was aborted","AbortError");if(n.body){const{stream:I,total:C}=r.createProgressTrackingStream(n,e);return await r.collectStreamToArrayBuffer(I,C||void 0)}else return await n.arrayBuffer()}static createProgressTrackingStream(e,t){const g=e.headers.get("content-length"),s=g?parseInt(g,10):null;let o=0;if(!e.body)throw new Error("Response body is null");const i=e.body.getReader();return{stream:new ReadableStream({start(n){function I(){return i.read().then(({done:C,value:l})=>{if(C){r.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:o,total:s,progress:s?1:-1,timestamp:Date.now()}),n.close();return}if(l){o+=l.byteLength;const h=s?o/s:-1;r.callAllCallbacks(t,"onLoadingProgress",{url:t,loaded:o,total:s,progress:h,timestamp:Date.now()}),n.enqueue(l)}return I()}).catch(C=>{n.error(C)})}return I()},cancel(n){return i.cancel(n)}}),total:s}}static async collectStreamToArrayBuffer(e,t){const g=e.getReader();try{if(t!==void 0&&t>0){const s=new ArrayBuffer(t),o=new Uint8Array(s);let i=0;for(;;){const{done:a,value:n}=await g.read();if(a)break;n&&(o.set(n,i),i+=n.byteLength)}return s}else{let s=new Uint8Array(8192),o=0;for(;;){const{done:i,value:a}=await g.read();if(i)break;if(a){if(o+a.byteLength>s.length){const n=Math.max(s.length*2,o+a.byteLength),I=new Uint8Array(n);I.set(s.subarray(0,o)),s=I}s.set(a,o),o+=a.byteLength}}return s.slice(0,o).buffer}}finally{g.releaseLock()}}static async decodeAudioData(e,t){try{return await e.decodeAudioData(t)}catch(g){throw console.error("Failed to decode audio data:",g),g}}static async getMetadataFromCache(e,t){try{const g=await t.match(`${e}:meta`);return g?.ok?await g.json():null}catch(g){return console.error("Failed to get metadata from cache:",g),null}}async getAudioBuffer(e,t,g,s){if(s?.onLoadingStart&&s.onLoadingStart({url:t,timestamp:Date.now()}),r.decodedBuffers.has(t))return s?.onCacheHit&&s.onCacheHit({url:t,cacheType:"memory",timestamp:Date.now()}),r.decodedBuffers.get(t);if(t.startsWith("data:")){const n=t.split(",")[1],I=Uint8Array.from(atob(n),l=>l.charCodeAt(0)).buffer,C=await r.decodeAudioData(e,I);return r.decodedBuffers.set(t,C),C}const o=await r.openCache(),i=await r.getMetadataFromCache(t,o),a=(()=>{if(!i||E(i.cacheControl))return!0;const n=Y(i.cacheControl);if(n!==null){const I=(Date.now()-i.timestamp)/1e3;if(n>0&&I<n)return!1}return i.etag||i.lastModified?!0:Date.now()-i.timestamp>r.cacheExpirationTime})();return r.getOrCreatePendingRequest(t,async()=>{if(a){s?.onCacheMiss&&s.onCacheMiss({url:t,reason:i?"expired":"not-found",timestamp:Date.now()});try{const n=await r.fetchAndCacheBuffer(t,o,i?.etag,i?.lastModified,g,{onCacheHit:s?.onCacheHit});let I;try{I=await r.decodeAudioData(e,n)}catch(C){throw s?.onLoadingError&&s.onLoadingError({url:t,error:C,errorType:"decode",timestamp:Date.now()}),C}return s?.onLoadingComplete&&s.onLoadingComplete({url:t,duration:I.duration,size:n.byteLength,timestamp:Date.now()}),r.decodedBuffers.set(t,I),I}catch(n){throw s?.onLoadingError&&s.onLoadingError({url:t,error:n,errorType:v(n),timestamp:Date.now()}),s?.onCacheError&&s.onCacheError({url:t,error:n,operation:"get",timestamp:Date.now()}),n}}else{const n=await r.getBufferFromCache(t,o);if(n){s?.onCacheHit&&s.onCacheHit({url:t,cacheType:"browser",timestamp:Date.now()});const I=await r.decodeAudioData(e,n);return r.decodedBuffers.set(t,I),I}else{s?.onCacheError&&s.onCacheError({url:t,error:new Error("Cache inconsistency: metadata exists but body is missing"),operation:"get",timestamp:Date.now()});try{const I=await r.fetchAndCacheBuffer(t,o,i?.etag,i?.lastModified,g,{onCacheHit:s?.onCacheHit});let C;try{C=await r.decodeAudioData(e,I)}catch(l){throw s?.onLoadingError&&s.onLoadingError({url:t,error:l,errorType:"decode",timestamp:Date.now()}),l}return s?.onLoadingComplete&&s.onLoadingComplete({url:t,duration:C.duration,size:I.byteLength,timestamp:Date.now()}),r.decodedBuffers.set(t,C),C}catch(I){throw s?.onLoadingError&&s.onLoadingError({url:t,error:I,errorType:v(I),timestamp:Date.now()}),I}}}},g,{onLoadingProgress:s?.onLoadingProgress})}clearMemoryCache(){r.decodedBuffers=new V(k),r.pendingRequests.clear()}}const D="data:text/javascript;base64,dmFyIHBoYXNlVm9jb2RlciA9IChmdW5jdGlvbiAoZXhwb3J0cykgewoJJ3VzZSBzdHJpY3QnOwoKCWZ1bmN0aW9uIGdldERlZmF1bHRFeHBvcnRGcm9tQ2pzICh4KSB7CgkJcmV0dXJuIHggJiYgeC5fX2VzTW9kdWxlICYmIE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbCh4LCAnZGVmYXVsdCcpID8geFsnZGVmYXVsdCddIDogeDsKCX0KCglmdW5jdGlvbiBGRlQoc2l6ZSkgewoJICB0aGlzLnNpemUgPSBzaXplIHwgMDsKCSAgaWYgKHRoaXMuc2l6ZSA8PSAxIHx8ICh0aGlzLnNpemUgJiAodGhpcy5zaXplIC0gMSkpICE9PSAwKQoJICAgIHRocm93IG5ldyBFcnJvcignRkZUIHNpemUgbXVzdCBiZSBhIHBvd2VyIG9mIHR3byBhbmQgYmlnZ2VyIHRoYW4gMScpOwoKCSAgdGhpcy5fY3NpemUgPSBzaXplIDw8IDE7CgoJICAvLyBOT1RFOiBVc2Ugb2YgYHZhcmAgaXMgaW50ZW50aW9uYWwgZm9yIG9sZCBWOCB2ZXJzaW9ucwoJICB2YXIgdGFibGUgPSBuZXcgQXJyYXkodGhpcy5zaXplICogMik7CgkgIGZvciAodmFyIGkgPSAwOyBpIDwgdGFibGUubGVuZ3RoOyBpICs9IDIpIHsKCSAgICBjb25zdCBhbmdsZSA9IE1hdGguUEkgKiBpIC8gdGhpcy5zaXplOwoJICAgIHRhYmxlW2ldID0gTWF0aC5jb3MoYW5nbGUpOwoJICAgIHRhYmxlW2kgKyAxXSA9IC1NYXRoLnNpbihhbmdsZSk7CgkgIH0KCSAgdGhpcy50YWJsZSA9IHRhYmxlOwoKCSAgLy8gRmluZCBzaXplJ3MgcG93ZXIgb2YgdHdvCgkgIHZhciBwb3dlciA9IDA7CgkgIGZvciAodmFyIHQgPSAxOyB0aGlzLnNpemUgPiB0OyB0IDw8PSAxKQoJICAgIHBvd2VyKys7CgoJICAvLyBDYWxjdWxhdGUgaW5pdGlhbCBzdGVwJ3Mgd2lkdGg6CgkgIC8vICAgKiBJZiB3ZSBhcmUgZnVsbCByYWRpeC00IC0gaXQgaXMgMnggc21hbGxlciB0byBnaXZlIGluaXRhbCBsZW49OAoJICAvLyAgICogT3RoZXJ3aXNlIGl0IGlzIHRoZSBzYW1lIGFzIGBwb3dlcmAgdG8gZ2l2ZSBsZW49NAoJICB0aGlzLl93aWR0aCA9IHBvd2VyICUgMiA9PT0gMCA/IHBvd2VyIC0gMSA6IHBvd2VyOwoKCSAgLy8gUHJlLWNvbXB1dGUgYml0LXJldmVyc2FsIHBhdHRlcm5zCgkgIHRoaXMuX2JpdHJldiA9IG5ldyBBcnJheSgxIDw8IHRoaXMuX3dpZHRoKTsKCSAgZm9yICh2YXIgaiA9IDA7IGogPCB0aGlzLl9iaXRyZXYubGVuZ3RoOyBqKyspIHsKCSAgICB0aGlzLl9iaXRyZXZbal0gPSAwOwoJICAgIGZvciAodmFyIHNoaWZ0ID0gMDsgc2hpZnQgPCB0aGlzLl93aWR0aDsgc2hpZnQgKz0gMikgewoJICAgICAgdmFyIHJldlNoaWZ0ID0gdGhpcy5fd2lkdGggLSBzaGlmdCAtIDI7CgkgICAgICB0aGlzLl9iaXRyZXZbal0gfD0gKChqID4+PiBzaGlmdCkgJiAzKSA8PCByZXZTaGlmdDsKCSAgICB9CgkgIH0KCgkgIHRoaXMuX291dCA9IG51bGw7CgkgIHRoaXMuX2RhdGEgPSBudWxsOwoJICB0aGlzLl9pbnYgPSAwOwoJfQoJdmFyIGZmdCA9IEZGVDsKCglGRlQucHJvdG90eXBlLmZyb21Db21wbGV4QXJyYXkgPSBmdW5jdGlvbiBmcm9tQ29tcGxleEFycmF5KGNvbXBsZXgsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgbmV3IEFycmF5KGNvbXBsZXgubGVuZ3RoID4+PiAxKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb21wbGV4Lmxlbmd0aDsgaSArPSAyKQoJICAgIHJlc1tpID4+PiAxXSA9IGNvbXBsZXhbaV07CgkgIHJldHVybiByZXM7Cgl9OwoKCUZGVC5wcm90b3R5cGUuY3JlYXRlQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gY3JlYXRlQ29tcGxleEFycmF5KCkgewoJICBjb25zdCByZXMgPSBuZXcgQXJyYXkodGhpcy5fY3NpemUpOwoJICBmb3IgKHZhciBpID0gMDsgaSA8IHJlcy5sZW5ndGg7IGkrKykKCSAgICByZXNbaV0gPSAwOwoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLnRvQ29tcGxleEFycmF5ID0gZnVuY3Rpb24gdG9Db21wbGV4QXJyYXkoaW5wdXQsIHN0b3JhZ2UpIHsKCSAgdmFyIHJlcyA9IHN0b3JhZ2UgfHwgdGhpcy5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCByZXMubGVuZ3RoOyBpICs9IDIpIHsKCSAgICByZXNbaV0gPSBpbnB1dFtpID4+PiAxXTsKCSAgICByZXNbaSArIDFdID0gMDsKCSAgfQoJICByZXR1cm4gcmVzOwoJfTsKCglGRlQucHJvdG90eXBlLmNvbXBsZXRlU3BlY3RydW0gPSBmdW5jdGlvbiBjb21wbGV0ZVNwZWN0cnVtKHNwZWN0cnVtKSB7CgkgIHZhciBzaXplID0gdGhpcy5fY3NpemU7CgkgIHZhciBoYWxmID0gc2l6ZSA+Pj4gMTsKCSAgZm9yICh2YXIgaSA9IDI7IGkgPCBoYWxmOyBpICs9IDIpIHsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaV0gPSBzcGVjdHJ1bVtpXTsKCSAgICBzcGVjdHJ1bVtzaXplIC0gaSArIDFdID0gLXNwZWN0cnVtW2kgKyAxXTsKCSAgfQoJfTsKCglGRlQucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uIHRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fdHJhbnNmb3JtNCgpOwoJICB0aGlzLl9vdXQgPSBudWxsOwoJICB0aGlzLl9kYXRhID0gbnVsbDsKCX07CgoJRkZULnByb3RvdHlwZS5yZWFsVHJhbnNmb3JtID0gZnVuY3Rpb24gcmVhbFRyYW5zZm9ybShvdXQsIGRhdGEpIHsKCSAgaWYgKG91dCA9PT0gZGF0YSkKCSAgICB0aHJvdyBuZXcgRXJyb3IoJ0lucHV0IGFuZCBvdXRwdXQgYnVmZmVycyBtdXN0IGJlIGRpZmZlcmVudCcpOwoKCSAgdGhpcy5fb3V0ID0gb3V0OwoJICB0aGlzLl9kYXRhID0gZGF0YTsKCSAgdGhpcy5faW52ID0gMDsKCSAgdGhpcy5fcmVhbFRyYW5zZm9ybTQoKTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCUZGVC5wcm90b3R5cGUuaW52ZXJzZVRyYW5zZm9ybSA9IGZ1bmN0aW9uIGludmVyc2VUcmFuc2Zvcm0ob3V0LCBkYXRhKSB7CgkgIGlmIChvdXQgPT09IGRhdGEpCgkgICAgdGhyb3cgbmV3IEVycm9yKCdJbnB1dCBhbmQgb3V0cHV0IGJ1ZmZlcnMgbXVzdCBiZSBkaWZmZXJlbnQnKTsKCgkgIHRoaXMuX291dCA9IG91dDsKCSAgdGhpcy5fZGF0YSA9IGRhdGE7CgkgIHRoaXMuX2ludiA9IDE7CgkgIHRoaXMuX3RyYW5zZm9ybTQoKTsKCSAgZm9yICh2YXIgaSA9IDA7IGkgPCBvdXQubGVuZ3RoOyBpKyspCgkgICAgb3V0W2ldIC89IHRoaXMuc2l6ZTsKCSAgdGhpcy5fb3V0ID0gbnVsbDsKCSAgdGhpcy5fZGF0YSA9IG51bGw7Cgl9OwoKCS8vIHJhZGl4LTQgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBVc2VzIG9mIGB2YXJgIGFyZSBpbnRlbnRpb25hbCBmb3Igb2xkZXIgVjggdmVyc2lvbiB0aGF0IGRvIG5vdAoJLy8gc3VwcG9ydCBib3RoIGBsZXQgY29tcG91bmQgYXNzaWdubWVudHNgIGFuZCBgY29uc3QgcGhpYAoJRkZULnByb3RvdHlwZS5fdHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF90cmFuc2Zvcm00KCkgewoJICB2YXIgb3V0ID0gdGhpcy5fb3V0OwoJICB2YXIgc2l6ZSA9IHRoaXMuX2NzaXplOwoKCSAgLy8gSW5pdGlhbCBzdGVwIChwZXJtdXRlIGFuZCB0cmFuc2Zvcm0pCgkgIHZhciB3aWR0aCA9IHRoaXMuX3dpZHRoOwoJICB2YXIgc3RlcCA9IDEgPDwgd2lkdGg7CgkgIHZhciBsZW4gPSAoc2l6ZSAvIHN0ZXApIDw8IDE7CgoJICB2YXIgb3V0T2ZmOwoJICB2YXIgdDsKCSAgdmFyIGJpdHJldiA9IHRoaXMuX2JpdHJldjsKCSAgaWYgKGxlbiA9PT0gNCkgewoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtMihvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9IGVsc2UgewoJICAgIC8vIGxlbiA9PT0gOAoJICAgIGZvciAob3V0T2ZmID0gMCwgdCA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4sIHQrKykgewoJICAgICAgY29uc3Qgb2ZmID0gYml0cmV2W3RdOwoJICAgICAgdGhpcy5fc2luZ2xlVHJhbnNmb3JtNChvdXRPZmYsIG9mZiwgc3RlcCk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGxlbiA+Pj4gMjsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIC8vIEZ1bGwgY2FzZQoJICAgICAgdmFyIGxpbWl0ID0gb3V0T2ZmICsgcXVhcnRlckxlbjsKCSAgICAgIGZvciAodmFyIGkgPSBvdXRPZmYsIGsgPSAwOyBpIDwgbGltaXQ7IGkgKz0gMiwgayArPSBzdGVwKSB7CgkgICAgICAgIGNvbnN0IEEgPSBpOwoJICAgICAgICBjb25zdCBCID0gQSArIHF1YXJ0ZXJMZW47CgkgICAgICAgIGNvbnN0IEMgPSBCICsgcXVhcnRlckxlbjsKCSAgICAgICAgY29uc3QgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IEFyID0gb3V0W0FdOwoJICAgICAgICBjb25zdCBBaSA9IG91dFtBICsgMV07CgkgICAgICAgIGNvbnN0IEJyID0gb3V0W0JdOwoJICAgICAgICBjb25zdCBCaSA9IG91dFtCICsgMV07CgkgICAgICAgIGNvbnN0IENyID0gb3V0W0NdOwoJICAgICAgICBjb25zdCBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIGNvbnN0IERyID0gb3V0W0RdOwoJICAgICAgICBjb25zdCBEaSA9IG91dFtEICsgMV07CgoJICAgICAgICAvLyBNaWRkbGUgdmFsdWVzCgkgICAgICAgIGNvbnN0IE1BciA9IEFyOwoJICAgICAgICBjb25zdCBNQWkgPSBBaTsKCgkgICAgICAgIGNvbnN0IHRhYmxlQnIgPSB0YWJsZVtrXTsKCSAgICAgICAgY29uc3QgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgY29uc3QgTUJyID0gQnIgKiB0YWJsZUJyIC0gQmkgKiB0YWJsZUJpOwoJICAgICAgICBjb25zdCBNQmkgPSBCciAqIHRhYmxlQmkgKyBCaSAqIHRhYmxlQnI7CgoJICAgICAgICBjb25zdCB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZUNpID0gaW52ICogdGFibGVbMiAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTUNyID0gQ3IgKiB0YWJsZUNyIC0gQ2kgKiB0YWJsZUNpOwoJICAgICAgICBjb25zdCBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICBjb25zdCB0YWJsZURyID0gdGFibGVbMyAqIGtdOwoJICAgICAgICBjb25zdCB0YWJsZURpID0gaW52ICogdGFibGVbMyAqIGsgKyAxXTsKCSAgICAgICAgY29uc3QgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICBjb25zdCBNRGkgPSBEciAqIHRhYmxlRGkgKyBEaSAqIHRhYmxlRHI7CgoJICAgICAgICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgICAgICAgIGNvbnN0IFQwciA9IE1BciArIE1DcjsKCSAgICAgICAgY29uc3QgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICBjb25zdCBUMXIgPSBNQXIgLSBNQ3I7CgkgICAgICAgIGNvbnN0IFQxaSA9IE1BaSAtIE1DaTsKCSAgICAgICAgY29uc3QgVDJyID0gTUJyICsgTURyOwoJICAgICAgICBjb25zdCBUMmkgPSBNQmkgKyBNRGk7CgkgICAgICAgIGNvbnN0IFQzciA9IGludiAqIChNQnIgLSBNRHIpOwoJICAgICAgICBjb25zdCBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgkgICAgICAgIGNvbnN0IEZBaSA9IFQwaSArIFQyaTsKCgkgICAgICAgIGNvbnN0IEZDciA9IFQwciAtIFQycjsKCSAgICAgICAgY29uc3QgRkNpID0gVDBpIC0gVDJpOwoKCSAgICAgICAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICAgICAgICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICAgICAgICBjb25zdCBGRHIgPSBUMXIgLSBUM2k7CgkgICAgICAgIGNvbnN0IEZEaSA9IFQxaSArIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoJICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgIG91dFtDICsgMV0gPSBGQ2k7CgkgICAgICAgIG91dFtEXSA9IEZEcjsKCSAgICAgICAgb3V0W0QgKyAxXSA9IEZEaTsKCSAgICAgIH0KCSAgICB9CgkgIH0KCX07CgoJLy8gcmFkaXgtMiBpbXBsZW1lbnRhdGlvbgoJLy8KCS8vIE5PVEU6IE9ubHkgY2FsbGVkIGZvciBsZW49NAoJRkZULnByb3RvdHlwZS5fc2luZ2xlVHJhbnNmb3JtMiA9IGZ1bmN0aW9uIF9zaW5nbGVUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmLAoJICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBldmVuSSA9IGRhdGFbb2ZmICsgMV07CgkgIGNvbnN0IG9kZFIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBvZGRJID0gZGF0YVtvZmYgKyBzdGVwICsgMV07CgoJICBjb25zdCBsZWZ0UiA9IGV2ZW5SICsgb2RkUjsKCSAgY29uc3QgbGVmdEkgPSBldmVuSSArIG9kZEk7CgkgIGNvbnN0IHJpZ2h0UiA9IGV2ZW5SIC0gb2RkUjsKCSAgY29uc3QgcmlnaHRJID0gZXZlbkkgLSBvZGRJOwoKCSAgb3V0W291dE9mZl0gPSBsZWZ0UjsKCSAgb3V0W291dE9mZiArIDFdID0gbGVmdEk7CgkgIG91dFtvdXRPZmYgKyAyXSA9IHJpZ2h0UjsKCSAgb3V0W291dE9mZiArIDNdID0gcmlnaHRJOwoJfTsKCgkvLyByYWRpeC00CgkvLwoJLy8gTk9URTogT25seSBjYWxsZWQgZm9yIGxlbj04CglGRlQucHJvdG90eXBlLl9zaW5nbGVUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVRyYW5zZm9ybTQob3V0T2ZmLCBvZmYsCgkgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RlcCkgewoJICBjb25zdCBvdXQgPSB0aGlzLl9vdXQ7CgkgIGNvbnN0IGRhdGEgPSB0aGlzLl9kYXRhOwoJICBjb25zdCBpbnYgPSB0aGlzLl9pbnYgPyAtMSA6IDE7CgkgIGNvbnN0IHN0ZXAyID0gc3RlcCAqIDI7CgkgIGNvbnN0IHN0ZXAzID0gc3RlcCAqIDM7CgoJICAvLyBPcmlnaW5hbCB2YWx1ZXMKCSAgY29uc3QgQXIgPSBkYXRhW29mZl07CgkgIGNvbnN0IEFpID0gZGF0YVtvZmYgKyAxXTsKCSAgY29uc3QgQnIgPSBkYXRhW29mZiArIHN0ZXBdOwoJICBjb25zdCBCaSA9IGRhdGFbb2ZmICsgc3RlcCArIDFdOwoJICBjb25zdCBDciA9IGRhdGFbb2ZmICsgc3RlcDJdOwoJICBjb25zdCBDaSA9IGRhdGFbb2ZmICsgc3RlcDIgKyAxXTsKCSAgY29uc3QgRHIgPSBkYXRhW29mZiArIHN0ZXAzXTsKCSAgY29uc3QgRGkgPSBkYXRhW29mZiArIHN0ZXAzICsgMV07CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQwaSA9IEFpICsgQ2k7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQxaSA9IEFpIC0gQ2k7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQyaSA9IEJpICsgRGk7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCSAgY29uc3QgVDNpID0gaW52ICogKEJpIC0gRGkpOwoKCSAgLy8gRmluYWwgdmFsdWVzCgkgIGNvbnN0IEZBciA9IFQwciArIFQycjsKCSAgY29uc3QgRkFpID0gVDBpICsgVDJpOwoKCSAgY29uc3QgRkJyID0gVDFyICsgVDNpOwoJICBjb25zdCBGQmkgPSBUMWkgLSBUM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgkgIGNvbnN0IEZDaSA9IFQwaSAtIFQyaTsKCgkgIGNvbnN0IEZEciA9IFQxciAtIFQzaTsKCSAgY29uc3QgRkRpID0gVDFpICsgVDNyOwoKCSAgb3V0W291dE9mZl0gPSBGQXI7CgkgIG91dFtvdXRPZmYgKyAxXSA9IEZBaTsKCSAgb3V0W291dE9mZiArIDJdID0gRkJyOwoJICBvdXRbb3V0T2ZmICsgM10gPSBGQmk7CgkgIG91dFtvdXRPZmYgKyA0XSA9IEZDcjsKCSAgb3V0W291dE9mZiArIDVdID0gRkNpOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJLy8gUmVhbCBpbnB1dCByYWRpeC00IGltcGxlbWVudGF0aW9uCglGRlQucHJvdG90eXBlLl9yZWFsVHJhbnNmb3JtNCA9IGZ1bmN0aW9uIF9yZWFsVHJhbnNmb3JtNCgpIHsKCSAgdmFyIG91dCA9IHRoaXMuX291dDsKCSAgdmFyIHNpemUgPSB0aGlzLl9jc2l6ZTsKCgkgIC8vIEluaXRpYWwgc3RlcCAocGVybXV0ZSBhbmQgdHJhbnNmb3JtKQoJICB2YXIgd2lkdGggPSB0aGlzLl93aWR0aDsKCSAgdmFyIHN0ZXAgPSAxIDw8IHdpZHRoOwoJICB2YXIgbGVuID0gKHNpemUgLyBzdGVwKSA8PCAxOwoKCSAgdmFyIG91dE9mZjsKCSAgdmFyIHQ7CgkgIHZhciBiaXRyZXYgPSB0aGlzLl9iaXRyZXY7CgkgIGlmIChsZW4gPT09IDQpIHsKCSAgICBmb3IgKG91dE9mZiA9IDAsIHQgPSAwOyBvdXRPZmYgPCBzaXplOyBvdXRPZmYgKz0gbGVuLCB0KyspIHsKCSAgICAgIGNvbnN0IG9mZiA9IGJpdHJldlt0XTsKCSAgICAgIHRoaXMuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwgb2ZmID4+PiAxLCBzdGVwID4+PiAxKTsKCSAgICB9CgkgIH0gZWxzZSB7CgkgICAgLy8gbGVuID09PSA4CgkgICAgZm9yIChvdXRPZmYgPSAwLCB0ID0gMDsgb3V0T2ZmIDwgc2l6ZTsgb3V0T2ZmICs9IGxlbiwgdCsrKSB7CgkgICAgICBjb25zdCBvZmYgPSBiaXRyZXZbdF07CgkgICAgICB0aGlzLl9zaW5nbGVSZWFsVHJhbnNmb3JtNChvdXRPZmYsIG9mZiA+Pj4gMSwgc3RlcCA+Pj4gMSk7CgkgICAgfQoJICB9CgoJICAvLyBMb29wIHRocm91Z2ggc3RlcHMgaW4gZGVjcmVhc2luZyBvcmRlcgoJICB2YXIgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICB2YXIgdGFibGUgPSB0aGlzLnRhYmxlOwoJICBmb3IgKHN0ZXAgPj49IDI7IHN0ZXAgPj0gMjsgc3RlcCA+Pj0gMikgewoJICAgIGxlbiA9IChzaXplIC8gc3RlcCkgPDwgMTsKCSAgICB2YXIgaGFsZkxlbiA9IGxlbiA+Pj4gMTsKCSAgICB2YXIgcXVhcnRlckxlbiA9IGhhbGZMZW4gPj4+IDE7CgkgICAgdmFyIGhxdWFydGVyTGVuID0gcXVhcnRlckxlbiA+Pj4gMTsKCgkgICAgLy8gTG9vcCB0aHJvdWdoIG9mZnNldHMgaW4gdGhlIGRhdGEKCSAgICBmb3IgKG91dE9mZiA9IDA7IG91dE9mZiA8IHNpemU7IG91dE9mZiArPSBsZW4pIHsKCSAgICAgIGZvciAodmFyIGkgPSAwLCBrID0gMDsgaSA8PSBocXVhcnRlckxlbjsgaSArPSAyLCBrICs9IHN0ZXApIHsKCSAgICAgICAgdmFyIEEgPSBvdXRPZmYgKyBpOwoJICAgICAgICB2YXIgQiA9IEEgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgQyA9IEIgKyBxdWFydGVyTGVuOwoJICAgICAgICB2YXIgRCA9IEMgKyBxdWFydGVyTGVuOwoKCSAgICAgICAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgICAgICAgIHZhciBBciA9IG91dFtBXTsKCSAgICAgICAgdmFyIEFpID0gb3V0W0EgKyAxXTsKCSAgICAgICAgdmFyIEJyID0gb3V0W0JdOwoJICAgICAgICB2YXIgQmkgPSBvdXRbQiArIDFdOwoJICAgICAgICB2YXIgQ3IgPSBvdXRbQ107CgkgICAgICAgIHZhciBDaSA9IG91dFtDICsgMV07CgkgICAgICAgIHZhciBEciA9IG91dFtEXTsKCSAgICAgICAgdmFyIERpID0gb3V0W0QgKyAxXTsKCgkgICAgICAgIC8vIE1pZGRsZSB2YWx1ZXMKCSAgICAgICAgdmFyIE1BciA9IEFyOwoJICAgICAgICB2YXIgTUFpID0gQWk7CgoJICAgICAgICB2YXIgdGFibGVCciA9IHRhYmxlW2tdOwoJICAgICAgICB2YXIgdGFibGVCaSA9IGludiAqIHRhYmxlW2sgKyAxXTsKCSAgICAgICAgdmFyIE1CciA9IEJyICogdGFibGVCciAtIEJpICogdGFibGVCaTsKCSAgICAgICAgdmFyIE1CaSA9IEJyICogdGFibGVCaSArIEJpICogdGFibGVCcjsKCgkgICAgICAgIHZhciB0YWJsZUNyID0gdGFibGVbMiAqIGtdOwoJICAgICAgICB2YXIgdGFibGVDaSA9IGludiAqIHRhYmxlWzIgKiBrICsgMV07CgkgICAgICAgIHZhciBNQ3IgPSBDciAqIHRhYmxlQ3IgLSBDaSAqIHRhYmxlQ2k7CgkgICAgICAgIHZhciBNQ2kgPSBDciAqIHRhYmxlQ2kgKyBDaSAqIHRhYmxlQ3I7CgoJICAgICAgICB2YXIgdGFibGVEciA9IHRhYmxlWzMgKiBrXTsKCSAgICAgICAgdmFyIHRhYmxlRGkgPSBpbnYgKiB0YWJsZVszICogayArIDFdOwoJICAgICAgICB2YXIgTURyID0gRHIgKiB0YWJsZURyIC0gRGkgKiB0YWJsZURpOwoJICAgICAgICB2YXIgTURpID0gRHIgKiB0YWJsZURpICsgRGkgKiB0YWJsZURyOwoKCSAgICAgICAgLy8gUHJlLUZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgVDByID0gTUFyICsgTUNyOwoJICAgICAgICB2YXIgVDBpID0gTUFpICsgTUNpOwoJICAgICAgICB2YXIgVDFyID0gTUFyIC0gTUNyOwoJICAgICAgICB2YXIgVDFpID0gTUFpIC0gTUNpOwoJICAgICAgICB2YXIgVDJyID0gTUJyICsgTURyOwoJICAgICAgICB2YXIgVDJpID0gTUJpICsgTURpOwoJICAgICAgICB2YXIgVDNyID0gaW52ICogKE1CciAtIE1Ecik7CgkgICAgICAgIHZhciBUM2kgPSBpbnYgKiAoTUJpIC0gTURpKTsKCgkgICAgICAgIC8vIEZpbmFsIHZhbHVlcwoJICAgICAgICB2YXIgRkFyID0gVDByICsgVDJyOwoJICAgICAgICB2YXIgRkFpID0gVDBpICsgVDJpOwoKCSAgICAgICAgdmFyIEZCciA9IFQxciArIFQzaTsKCSAgICAgICAgdmFyIEZCaSA9IFQxaSAtIFQzcjsKCgkgICAgICAgIG91dFtBXSA9IEZBcjsKCSAgICAgICAgb3V0W0EgKyAxXSA9IEZBaTsKCSAgICAgICAgb3V0W0JdID0gRkJyOwoJICAgICAgICBvdXRbQiArIDFdID0gRkJpOwoKCSAgICAgICAgLy8gT3V0cHV0IGZpbmFsIG1pZGRsZSBwb2ludAoJICAgICAgICBpZiAoaSA9PT0gMCkgewoJICAgICAgICAgIHZhciBGQ3IgPSBUMHIgLSBUMnI7CgkgICAgICAgICAgdmFyIEZDaSA9IFQwaSAtIFQyaTsKCSAgICAgICAgICBvdXRbQ10gPSBGQ3I7CgkgICAgICAgICAgb3V0W0MgKyAxXSA9IEZDaTsKCSAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgfQoKCSAgICAgICAgLy8gRG8gbm90IG92ZXJ3cml0ZSBvdXJzZWx2ZXMKCSAgICAgICAgaWYgKGkgPT09IGhxdWFydGVyTGVuKQoJICAgICAgICAgIGNvbnRpbnVlOwoKCSAgICAgICAgLy8gSW4gdGhlIGZsaXBwZWQgY2FzZToKCSAgICAgICAgLy8gTUFpID0gLU1BaQoJICAgICAgICAvLyBNQnI9LU1CaSwgTUJpPS1NQnIKCSAgICAgICAgLy8gTUNyPS1NQ3IKCSAgICAgICAgLy8gTURyPU1EaSwgTURpPU1EcgoJICAgICAgICB2YXIgU1QwciA9IFQxcjsKCSAgICAgICAgdmFyIFNUMGkgPSAtVDFpOwoJICAgICAgICB2YXIgU1QxciA9IFQwcjsKCSAgICAgICAgdmFyIFNUMWkgPSAtVDBpOwoJICAgICAgICB2YXIgU1QyciA9IC1pbnYgKiBUM2k7CgkgICAgICAgIHZhciBTVDJpID0gLWludiAqIFQzcjsKCSAgICAgICAgdmFyIFNUM3IgPSAtaW52ICogVDJpOwoJICAgICAgICB2YXIgU1QzaSA9IC1pbnYgKiBUMnI7CgoJICAgICAgICB2YXIgU0ZBciA9IFNUMHIgKyBTVDJyOwoJICAgICAgICB2YXIgU0ZBaSA9IFNUMGkgKyBTVDJpOwoKCSAgICAgICAgdmFyIFNGQnIgPSBTVDFyICsgU1QzaTsKCSAgICAgICAgdmFyIFNGQmkgPSBTVDFpIC0gU1QzcjsKCgkgICAgICAgIHZhciBTQSA9IG91dE9mZiArIHF1YXJ0ZXJMZW4gLSBpOwoJICAgICAgICB2YXIgU0IgPSBvdXRPZmYgKyBoYWxmTGVuIC0gaTsKCgkgICAgICAgIG91dFtTQV0gPSBTRkFyOwoJICAgICAgICBvdXRbU0EgKyAxXSA9IFNGQWk7CgkgICAgICAgIG91dFtTQl0gPSBTRkJyOwoJICAgICAgICBvdXRbU0IgKyAxXSA9IFNGQmk7CgkgICAgICB9CgkgICAgfQoJICB9Cgl9OwoKCS8vIHJhZGl4LTIgaW1wbGVtZW50YXRpb24KCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTQKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm0yID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm0yKG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCgkgIGNvbnN0IGV2ZW5SID0gZGF0YVtvZmZdOwoJICBjb25zdCBvZGRSID0gZGF0YVtvZmYgKyBzdGVwXTsKCgkgIGNvbnN0IGxlZnRSID0gZXZlblIgKyBvZGRSOwoJICBjb25zdCByaWdodFIgPSBldmVuUiAtIG9kZFI7CgoJICBvdXRbb3V0T2ZmXSA9IGxlZnRSOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSByaWdodFI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IDA7Cgl9OwoKCS8vIHJhZGl4LTQKCS8vCgkvLyBOT1RFOiBPbmx5IGNhbGxlZCBmb3IgbGVuPTgKCUZGVC5wcm90b3R5cGUuX3NpbmdsZVJlYWxUcmFuc2Zvcm00ID0gZnVuY3Rpb24gX3NpbmdsZVJlYWxUcmFuc2Zvcm00KG91dE9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9mZiwKCSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0ZXApIHsKCSAgY29uc3Qgb3V0ID0gdGhpcy5fb3V0OwoJICBjb25zdCBkYXRhID0gdGhpcy5fZGF0YTsKCSAgY29uc3QgaW52ID0gdGhpcy5faW52ID8gLTEgOiAxOwoJICBjb25zdCBzdGVwMiA9IHN0ZXAgKiAyOwoJICBjb25zdCBzdGVwMyA9IHN0ZXAgKiAzOwoKCSAgLy8gT3JpZ2luYWwgdmFsdWVzCgkgIGNvbnN0IEFyID0gZGF0YVtvZmZdOwoJICBjb25zdCBCciA9IGRhdGFbb2ZmICsgc3RlcF07CgkgIGNvbnN0IENyID0gZGF0YVtvZmYgKyBzdGVwMl07CgkgIGNvbnN0IERyID0gZGF0YVtvZmYgKyBzdGVwM107CgoJICAvLyBQcmUtRmluYWwgdmFsdWVzCgkgIGNvbnN0IFQwciA9IEFyICsgQ3I7CgkgIGNvbnN0IFQxciA9IEFyIC0gQ3I7CgkgIGNvbnN0IFQyciA9IEJyICsgRHI7CgkgIGNvbnN0IFQzciA9IGludiAqIChCciAtIERyKTsKCgkgIC8vIEZpbmFsIHZhbHVlcwoJICBjb25zdCBGQXIgPSBUMHIgKyBUMnI7CgoJICBjb25zdCBGQnIgPSBUMXI7CgkgIGNvbnN0IEZCaSA9IC1UM3I7CgoJICBjb25zdCBGQ3IgPSBUMHIgLSBUMnI7CgoJICBjb25zdCBGRHIgPSBUMXI7CgkgIGNvbnN0IEZEaSA9IFQzcjsKCgkgIG91dFtvdXRPZmZdID0gRkFyOwoJICBvdXRbb3V0T2ZmICsgMV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgMl0gPSBGQnI7CgkgIG91dFtvdXRPZmYgKyAzXSA9IEZCaTsKCSAgb3V0W291dE9mZiArIDRdID0gRkNyOwoJICBvdXRbb3V0T2ZmICsgNV0gPSAwOwoJICBvdXRbb3V0T2ZmICsgNl0gPSBGRHI7CgkgIG91dFtvdXRPZmYgKyA3XSA9IEZEaTsKCX07CgoJdmFyIEZGVCQxID0gLypAX19QVVJFX18qL2dldERlZmF1bHRFeHBvcnRGcm9tQ2pzKGZmdCk7CgoJY29uc3QgV0VCQVVESU9fQkxPQ0tfU0laRSA9IDEyODsKCWNvbnN0IERFRkFVTFRfQkxPQ0tfU0laRSA9IDEwMjQ7IC8vIERlZmF1bHQgYmxvY2sgc2l6ZSBpZiBub3QgcHJvdmlkZWQgaW4gb3B0aW9ucwoJLyoqIE92ZXJsYXAtQWRkIE5vZGUgKi8KCWNsYXNzIE9MQVByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CgkgICAgbmJJbnB1dHM7CgkgICAgbmJPdXRwdXRzOwoJICAgIGJsb2NrU2l6ZTsKCSAgICBob3BTaXplOwoJICAgIG5iT3ZlcmxhcHM7CgkgICAgaW5wdXRCdWZmZXJzID0gW107CgkgICAgaW5wdXRCdWZmZXJzSGVhZCA9IFtdOwoJICAgIGlucHV0QnVmZmVyc1RvU2VuZCA9IFtdOwoJICAgIG91dHB1dEJ1ZmZlcnMgPSBbXTsKCSAgICBvdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSA9IFtdOwoJICAgIGNvbnN0cnVjdG9yKG9wdGlvbnMpIHsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMubmJJbnB1dHMgPSBvcHRpb25zLm51bWJlck9mSW5wdXRzIHx8IDE7CgkgICAgICAgIHRoaXMubmJPdXRwdXRzID0gb3B0aW9ucy5udW1iZXJPZk91dHB1dHMgfHwgMTsKCSAgICAgICAgdGhpcy5ibG9ja1NpemUgPSBvcHRpb25zLnByb2Nlc3Nvck9wdGlvbnMuYmxvY2tTaXplIHx8IERFRkFVTFRfQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5ob3BTaXplID0gV0VCQVVESU9fQkxPQ0tfU0laRTsKCSAgICAgICAgdGhpcy5uYk92ZXJsYXBzID0gTWF0aC5mbG9vcih0aGlzLmJsb2NrU2l6ZSAvIHRoaXMuaG9wU2l6ZSk7CgkgICAgICAgIHRoaXMuaW5pdGlhbGl6ZUJ1ZmZlcnMoKTsKCSAgICB9CgkgICAgaW5pdGlhbGl6ZUJ1ZmZlcnMoKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWQgPSBuZXcgQXJyYXkodGhpcy5uYklucHV0cyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kID0gbmV3IEFycmF5KHRoaXMubmJJbnB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnMgPSBuZXcgQXJyYXkodGhpcy5uYk91dHB1dHMpOwoJICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNUb1JldHJpZXZlID0gbmV3IEFycmF5KHRoaXMubmJPdXRwdXRzKTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5hbGxvY2F0ZU91dHB1dENoYW5uZWxzKGksIDEpOwoJICAgICAgICB9CgkgICAgfQoJICAgIGFsbG9jYXRlSW5wdXRDaGFubmVscyhpbnB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICB0aGlzLmlucHV0QnVmZmVyc0hlYWRbaW5wdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzVG9TZW5kW2lucHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplICsgV0VCQVVESU9fQkxPQ0tfU0laRSk7CgkgICAgICAgICAgICB0aGlzLmlucHV0QnVmZmVyc1tpbnB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNIZWFkW2lucHV0SW5kZXhdW2ldID0gdGhpcy5pbnB1dEJ1ZmZlcnNbaW5wdXRJbmRleF1baV0uc3ViYXJyYXkoMCwgdGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaW5wdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBhbGxvY2F0ZU91dHB1dENoYW5uZWxzKG91dHB1dEluZGV4LCBuYkNoYW5uZWxzKSB7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1tvdXRwdXRJbmRleF0gPSBuZXcgQXJyYXkobmJDaGFubmVscyk7CgkgICAgICAgIHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbb3V0cHV0SW5kZXhdID0gbmV3IEFycmF5KG5iQ2hhbm5lbHMpOwoJICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IG5iQ2hhbm5lbHM7IGkrKykgewoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXSA9IG5ldyBGbG9hdDMyQXJyYXkodGhpcy5ibG9ja1NpemUpOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW291dHB1dEluZGV4XVtpXS5maWxsKDApOwoJICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZVtvdXRwdXRJbmRleF1baV0gPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgfQoJICAgIH0KCSAgICByZWFsbG9jYXRlQ2hhbm5lbHNJZk5lZWRlZChpbnB1dHMsIG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IG5iQ2hhbm5lbHMgPSBpbnB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgIHRoaXMuYWxsb2NhdGVJbnB1dENoYW5uZWxzKGksIG5iQ2hhbm5lbHMpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgY29uc3QgbmJDaGFubmVscyA9IG91dHB1dHNbaV0ubGVuZ3RoOwoJICAgICAgICAgICAgaWYgKG5iQ2hhbm5lbHMgIT09IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICB0aGlzLmFsbG9jYXRlT3V0cHV0Q2hhbm5lbHMoaSwgbmJDaGFubmVscyk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgcmVhZElucHV0cyhpbnB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5pbnB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBjb25zdCB3ZWJBdWRpb0Jsb2NrID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuaW5wdXRCdWZmZXJzW2ldW2pdLnNldCh3ZWJBdWRpb0Jsb2NrLCB0aGlzLmJsb2NrU2l6ZSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgd3JpdGVPdXRwdXRzKG91dHB1dHMpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iT3V0cHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMub3V0cHV0QnVmZmVyc1tpXS5sZW5ndGg7IGorKykgewoJICAgICAgICAgICAgICAgIGNvbnN0IHdlYkF1ZGlvQmxvY2sgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHdlYkF1ZGlvQmxvY2suc2V0KHRoaXMub3V0cHV0QnVmZmVyc1tpXVtqXS5zdWJhcnJheSgwLCBXRUJBVURJT19CTE9DS19TSVpFKSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgc2hpZnRJbnB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdE91dHB1dEJ1ZmZlcnMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uY29weVdpdGhpbigwLCBXRUJBVURJT19CTE9DS19TSVpFKTsKCSAgICAgICAgICAgICAgICB0aGlzLm91dHB1dEJ1ZmZlcnNbaV1bal0uZmlsbCgwLCB0aGlzLmJsb2NrU2l6ZSAtIFdFQkFVRElPX0JMT0NLX1NJWkUpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByZXBhcmVJbnB1dEJ1ZmZlcnNUb1NlbmQoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYklucHV0czsgaSsrKSB7CgkgICAgICAgICAgICBmb3IgKGxldCBqID0gMDsgaiA8IHRoaXMuaW5wdXRCdWZmZXJzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdGhpcy5pbnB1dEJ1ZmZlcnNUb1NlbmRbaV1bal0uc2V0KHRoaXMuaW5wdXRCdWZmZXJzSGVhZFtpXVtqXSk7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9CgkgICAgaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYk91dHB1dHM7IGkrKykgewoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCB0aGlzLm91dHB1dEJ1ZmZlcnNbaV0ubGVuZ3RoOyBqKyspIHsKCSAgICAgICAgICAgICAgICBmb3IgKGxldCBrID0gMDsgayA8IHRoaXMuYmxvY2tTaXplOyBrKyspIHsKCSAgICAgICAgICAgICAgICAgICAgdGhpcy5vdXRwdXRCdWZmZXJzW2ldW2pdW2tdICs9IHRoaXMub3V0cHV0QnVmZmVyc1RvUmV0cmlldmVbaV1bal1ba10gLyB0aGlzLm5iT3ZlcmxhcHM7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgfQoJICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzLCBwYXJhbWV0ZXJzKSB7CgkgICAgICAgIHRoaXMucmVhbGxvY2F0ZUNoYW5uZWxzSWZOZWVkZWQoaW5wdXRzLCBvdXRwdXRzKTsKCSAgICAgICAgdGhpcy5yZWFkSW5wdXRzKGlucHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRJbnB1dEJ1ZmZlcnMoKTsKCSAgICAgICAgdGhpcy5wcmVwYXJlSW5wdXRCdWZmZXJzVG9TZW5kKCk7CgkgICAgICAgIHRoaXMucHJvY2Vzc09MQSh0aGlzLmlucHV0QnVmZmVyc1RvU2VuZCwgdGhpcy5vdXRwdXRCdWZmZXJzVG9SZXRyaWV2ZSwgcGFyYW1ldGVycyk7CgkgICAgICAgIHRoaXMuaGFuZGxlT3V0cHV0QnVmZmVyc1RvUmV0cmlldmUoKTsKCSAgICAgICAgdGhpcy53cml0ZU91dHB1dHMob3V0cHV0cyk7CgkgICAgICAgIHRoaXMuc2hpZnRPdXRwdXRCdWZmZXJzKCk7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCX0KCgljb25zdCBCVUZGRVJFRF9CTE9DS19TSVpFID0gMjA0ODsKCWZ1bmN0aW9uIGdlbkhhbm5XaW5kb3cobGVuZ3RoKSB7CgkgICAgY29uc3Qgd2luID0gbmV3IEZsb2F0MzJBcnJheShsZW5ndGgpOwoJICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbGVuZ3RoOyBpKyspIHsKCSAgICAgICAgd2luW2ldID0gMC41ICogKDEgLSBNYXRoLmNvcygoMiAqIE1hdGguUEkgKiBpKSAvIGxlbmd0aCkpOwoJICAgIH0KCSAgICByZXR1cm4gd2luOwoJfQoJY2xhc3MgUGhhc2VWb2NvZGVyUHJvY2Vzc29yIGV4dGVuZHMgT0xBUHJvY2Vzc29yIHsKCSAgICBmZnRTaXplOwoJICAgIHRpbWVDdXJzb3I7CgkgICAgaGFubldpbmRvdzsKCSAgICBmZnQ7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXI7CgkgICAgZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkOwoJICAgIHRpbWVDb21wbGV4QnVmZmVyOwoJICAgIG1hZ25pdHVkZXM7CgkgICAgcGVha0luZGV4ZXM7CgkgICAgbmJQZWFrczsKCSAgICBzdGF0aWMgZ2V0IHBhcmFtZXRlckRlc2NyaXB0b3JzKCkgewoJICAgICAgICByZXR1cm4gWwoJICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgIG5hbWU6ICJwaXRjaEZhY3RvciIsCgkgICAgICAgICAgICAgICAgZGVmYXVsdFZhbHVlOiAxLjAsCgkgICAgICAgICAgICB9LAoJICAgICAgICBdOwoJICAgIH0KCSAgICBjb25zdHJ1Y3RvcihvcHRpb25zKSB7CgkgICAgICAgIG9wdGlvbnMucHJvY2Vzc29yT3B0aW9ucyA9IHsKCSAgICAgICAgICAgIGJsb2NrU2l6ZTogQlVGRkVSRURfQkxPQ0tfU0laRSwKCSAgICAgICAgfTsKCSAgICAgICAgc3VwZXIob3B0aW9ucyk7CgkgICAgICAgIHRoaXMuZmZ0U2l6ZSA9IHRoaXMuYmxvY2tTaXplOwoJICAgICAgICB0aGlzLnRpbWVDdXJzb3IgPSAwOwoJICAgICAgICB0aGlzLmhhbm5XaW5kb3cgPSBnZW5IYW5uV2luZG93KHRoaXMuYmxvY2tTaXplKTsKCSAgICAgICAgLy8gcHJlcGFyZSBGRlQgYW5kIHByZS1hbGxvY2F0ZSBidWZmZXJzCgkgICAgICAgIHRoaXMuZmZ0ID0gbmV3IEZGVCQxKHRoaXMuZmZ0U2l6ZSk7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQgPSB0aGlzLmZmdC5jcmVhdGVDb21wbGV4QXJyYXkoKTsKCSAgICAgICAgdGhpcy50aW1lQ29tcGxleEJ1ZmZlciA9IHRoaXMuZmZ0LmNyZWF0ZUNvbXBsZXhBcnJheSgpOwoJICAgICAgICB0aGlzLm1hZ25pdHVkZXMgPSBuZXcgRmxvYXQzMkFycmF5KHRoaXMuZmZ0U2l6ZSAvIDIgKyAxKTsKCSAgICAgICAgdGhpcy5wZWFrSW5kZXhlcyA9IG5ldyBJbnQzMkFycmF5KHRoaXMubWFnbml0dWRlcy5sZW5ndGgpOwoJICAgICAgICB0aGlzLm5iUGVha3MgPSAwOwoJICAgIH0KCSAgICBwcm9jZXNzT0xBKGlucHV0cywgb3V0cHV0cywgcGFyYW1ldGVycykgewoJICAgICAgICBjb25zdCBwaXRjaEZhY3RvciA9IHBhcmFtZXRlcnMucGl0Y2hGYWN0b3JbcGFyYW1ldGVycy5waXRjaEZhY3Rvci5sZW5ndGggLSAxXTsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm5iSW5wdXRzOyBpKyspIHsKCSAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgaW5wdXRzW2ldLmxlbmd0aDsgaisrKSB7CgkgICAgICAgICAgICAgICAgdmFyIGlucHV0ID0gaW5wdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHZhciBvdXRwdXQgPSBvdXRwdXRzW2ldW2pdOwoJICAgICAgICAgICAgICAgIHRoaXMuYXBwbHlIYW5uV2luZG93KGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmZmdC5yZWFsVHJhbnNmb3JtKHRoaXMuZnJlcUNvbXBsZXhCdWZmZXIsIGlucHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmNvbXB1dGVNYWduaXR1ZGVzKCk7CgkgICAgICAgICAgICAgICAgdGhpcy5maW5kUGVha3MoKTsKCSAgICAgICAgICAgICAgICB0aGlzLnNoaWZ0UGVha3MocGl0Y2hGYWN0b3IpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmNvbXBsZXRlU3BlY3RydW0odGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmludmVyc2VUcmFuc2Zvcm0odGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgdGhpcy5mcmVxQ29tcGxleEJ1ZmZlclNoaWZ0ZWQpOwoJICAgICAgICAgICAgICAgIHRoaXMuZmZ0LmZyb21Db21wbGV4QXJyYXkodGhpcy50aW1lQ29tcGxleEJ1ZmZlciwgb3V0cHV0KTsKCSAgICAgICAgICAgICAgICB0aGlzLmFwcGx5SGFubldpbmRvdyhvdXRwdXQpOwoJICAgICAgICAgICAgfQoJICAgICAgICB9CgkgICAgICAgIHRoaXMudGltZUN1cnNvciArPSB0aGlzLmhvcFNpemU7CgkgICAgICAgIHJldHVybiB0cnVlOwoJICAgIH0KCSAgICBhcHBseUhhbm5XaW5kb3coaW5wdXQpIHsKCSAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLmJsb2NrU2l6ZTsgaSsrKSB7CgkgICAgICAgICAgICBpbnB1dFtpXSAqPSB0aGlzLmhhbm5XaW5kb3dbaV07CgkgICAgICAgIH0KCSAgICB9CgkgICAgY29tcHV0ZU1hZ25pdHVkZXMoKSB7CgkgICAgICAgIGZvciAobGV0IGkgPSAwLCBqID0gMDsgaSA8IHRoaXMubWFnbml0dWRlcy5sZW5ndGg7IGkrKywgaiArPSAyKSB7CgkgICAgICAgICAgICBjb25zdCByZWFsID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltqXTsKCSAgICAgICAgICAgIGNvbnN0IGltYWcgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2ogKyAxXTsKCSAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpXSA9IHJlYWwgKiogMiArIGltYWcgKiogMjsKCSAgICAgICAgfQoJICAgIH0KCSAgICBmaW5kUGVha3MoKSB7CgkgICAgICAgIHRoaXMubmJQZWFrcyA9IDA7CgkgICAgICAgIGZvciAobGV0IGkgPSAyLCBlbmQgPSB0aGlzLm1hZ25pdHVkZXMubGVuZ3RoIC0gMjsgaSA8IGVuZDsgaSsrKSB7CgkgICAgICAgICAgICBjb25zdCBtYWcgPSB0aGlzLm1hZ25pdHVkZXNbaV07CgkgICAgICAgICAgICBpZiAodGhpcy5tYWduaXR1ZGVzW2kgLSAxXSA+PSBtYWcgfHwKCSAgICAgICAgICAgICAgICB0aGlzLm1hZ25pdHVkZXNbaSAtIDJdID49IG1hZyB8fAoJICAgICAgICAgICAgICAgIHRoaXMubWFnbml0dWRlc1tpICsgMV0gPj0gbWFnIHx8CgkgICAgICAgICAgICAgICAgdGhpcy5tYWduaXR1ZGVzW2kgKyAyXSA+PSBtYWcpIHsKCSAgICAgICAgICAgICAgICBjb250aW51ZTsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIHRoaXMucGVha0luZGV4ZXNbdGhpcy5uYlBlYWtzKytdID0gaTsKCSAgICAgICAgfQoJICAgIH0KCSAgICBzaGlmdFBlYWtzKHBpdGNoRmFjdG9yKSB7CgkgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkLmZpbGwoMCk7CgkgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5uYlBlYWtzOyBpKyspIHsKCSAgICAgICAgICAgIGNvbnN0IHBlYWtJbmRleCA9IHRoaXMucGVha0luZGV4ZXNbaV07CgkgICAgICAgICAgICBjb25zdCBwZWFrSW5kZXhTaGlmdGVkID0gTWF0aC5yb3VuZChwZWFrSW5kZXggKiBwaXRjaEZhY3Rvcik7CgkgICAgICAgICAgICBpZiAocGVha0luZGV4U2hpZnRlZCA+IHRoaXMubWFnbml0dWRlcy5sZW5ndGgpIHsKCSAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgIH0KCSAgICAgICAgICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBpID4gMCA/IHBlYWtJbmRleCAtIE1hdGguZmxvb3IoKHBlYWtJbmRleCAtIHRoaXMucGVha0luZGV4ZXNbaSAtIDFdKSAvIDIpIDogMDsKCSAgICAgICAgICAgIGNvbnN0IGVuZEluZGV4ID0gaSA8IHRoaXMubmJQZWFrcyAtIDEgPyBwZWFrSW5kZXggKyBNYXRoLmNlaWwoKHRoaXMucGVha0luZGV4ZXNbaSArIDFdIC0gcGVha0luZGV4KSAvIDIpIDogdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgZm9yIChsZXQgaiA9IHN0YXJ0SW5kZXggLSBwZWFrSW5kZXg7IGogPCBlbmRJbmRleCAtIHBlYWtJbmRleDsgaisrKSB7CgkgICAgICAgICAgICAgICAgY29uc3QgYmluSW5kZXggPSBwZWFrSW5kZXggKyBqOwoJICAgICAgICAgICAgICAgIGNvbnN0IGJpbkluZGV4U2hpZnRlZCA9IHBlYWtJbmRleFNoaWZ0ZWQgKyBqOwoJICAgICAgICAgICAgICAgIGlmIChiaW5JbmRleFNoaWZ0ZWQgPj0gdGhpcy5tYWduaXR1ZGVzLmxlbmd0aCkgewoJICAgICAgICAgICAgICAgICAgICBicmVhazsKCSAgICAgICAgICAgICAgICB9CgkgICAgICAgICAgICAgICAgY29uc3Qgb21lZ2FEZWx0YSA9ICgyICogTWF0aC5QSSAqIChiaW5JbmRleFNoaWZ0ZWQgLSBiaW5JbmRleCkpIC8gdGhpcy5mZnRTaXplOwoJICAgICAgICAgICAgICAgIGNvbnN0IHBoYXNlU2hpZnRSZWFsID0gTWF0aC5jb3Mob21lZ2FEZWx0YSAqIHRoaXMudGltZUN1cnNvcik7CgkgICAgICAgICAgICAgICAgY29uc3QgcGhhc2VTaGlmdEltYWcgPSBNYXRoLnNpbihvbWVnYURlbHRhICogdGhpcy50aW1lQ3Vyc29yKTsKCSAgICAgICAgICAgICAgICBjb25zdCBpbmRleFJlYWwgPSBiaW5JbmRleCAqIDI7CgkgICAgICAgICAgICAgICAgY29uc3QgaW5kZXhJbWFnID0gaW5kZXhSZWFsICsgMTsKCSAgICAgICAgICAgICAgICBjb25zdCB2YWx1ZVJlYWwgPSB0aGlzLmZyZXFDb21wbGV4QnVmZmVyW2luZGV4UmVhbF07CgkgICAgICAgICAgICAgICAgY29uc3QgdmFsdWVJbWFnID0gdGhpcy5mcmVxQ29tcGxleEJ1ZmZlcltpbmRleEltYWddOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZFJlYWwgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0UmVhbCAtIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRJbWFnOwoJICAgICAgICAgICAgICAgIGNvbnN0IHZhbHVlU2hpZnRlZEltYWcgPSB2YWx1ZVJlYWwgKiBwaGFzZVNoaWZ0SW1hZyArIHZhbHVlSW1hZyAqIHBoYXNlU2hpZnRSZWFsOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZFJlYWwgPSBiaW5JbmRleFNoaWZ0ZWQgKiAyOwoJICAgICAgICAgICAgICAgIGNvbnN0IGluZGV4U2hpZnRlZEltYWcgPSBpbmRleFNoaWZ0ZWRSZWFsICsgMTsKCSAgICAgICAgICAgICAgICB0aGlzLmZyZXFDb21wbGV4QnVmZmVyU2hpZnRlZFtpbmRleFNoaWZ0ZWRSZWFsXSArPSB2YWx1ZVNoaWZ0ZWRSZWFsOwoJICAgICAgICAgICAgICAgIHRoaXMuZnJlcUNvbXBsZXhCdWZmZXJTaGlmdGVkW2luZGV4U2hpZnRlZEltYWddICs9IHZhbHVlU2hpZnRlZEltYWc7CgkgICAgICAgICAgICB9CgkgICAgICAgIH0KCSAgICB9Cgl9CgkvLyBAdHMtZXhwZWN0LWVycm9yCglyZWdpc3RlclByb2Nlc3NvcigicGhhc2Utdm9jb2RlciIsIFBoYXNlVm9jb2RlclByb2Nlc3Nvcik7Cgljb25zb2xlLmxvZygiUGhhc2VWb2NvZGVyUHJvY2Vzc29yIHJlZ2lzdGVyZWQiKTsKCglleHBvcnRzLlBoYXNlVm9jb2RlclByb2Nlc3NvciA9IFBoYXNlVm9jb2RlclByb2Nlc3NvcjsKCglyZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9cGhhc2Utdm9jb2Rlci1idW5kbGUuanMubWFwCg==",J="data:text/javascript;base64,dmFyIHN0ZXJlb1RvQmZvcm1hdCA9IChmdW5jdGlvbiAoZXhwb3J0cykgewogICAgJ3VzZSBzdHJpY3QnOwoKICAgIGNvbnN0IFNRUlQxXzIgPSBNYXRoLlNRUlQxXzI7CiAgICBmdW5jdGlvbiBlbmNvZGVTdGVyZW9Ub0JGb3JtYXQobGVmdCwgcmlnaHQsIHcsIHksIHosIHgpIHsKICAgICAgICAvLyBFbWl0IGZpcnN0LW9yZGVyIGFtYmlzb25pY3MgaW4gQUNOIGNoYW5uZWwgb3JkZXIgVywgWSwgWiwgWC4KICAgICAgICBjb25zdCBmcmFtZUNvdW50ID0gTWF0aC5taW4obGVmdC5sZW5ndGgsIHJpZ2h0Lmxlbmd0aCwgdy5sZW5ndGgsIHgubGVuZ3RoLCB5Lmxlbmd0aCwgei5sZW5ndGgpOwogICAgICAgIGZvciAobGV0IGZyYW1lID0gMDsgZnJhbWUgPCBmcmFtZUNvdW50OyBmcmFtZSsrKSB7CiAgICAgICAgICAgIGNvbnN0IGwgPSBsZWZ0W2ZyYW1lXTsKICAgICAgICAgICAgY29uc3QgciA9IHJpZ2h0W2ZyYW1lXTsKICAgICAgICAgICAgd1tmcmFtZV0gPSAobCArIHIpICogU1FSVDFfMjsKICAgICAgICAgICAgeFtmcmFtZV0gPSAwOwogICAgICAgICAgICB5W2ZyYW1lXSA9IChsIC0gcikgKiBTUVJUMV8yOwogICAgICAgICAgICB6W2ZyYW1lXSA9IDA7CiAgICAgICAgfQogICAgfQoKICAgIGNvbnN0IFdPUktMRVRfTE9HX1BSRUZJWCA9ICJbY2Fjb3Bob255L3dvcmtsZXQ6c3RlcmVvLXRvLWJmb3JtYXRdIjsKICAgIGNsYXNzIFN0ZXJlb1RvQkZvcm1hdFByb2Nlc3NvciBleHRlbmRzIEF1ZGlvV29ya2xldFByb2Nlc3NvciB7CiAgICAgICAgZnJhbWVzUHJvY2Vzc2VkID0gMDsKICAgICAgICBmcmFtZXNTaG9ydElucHV0ID0gMDsKICAgICAgICBsYXN0UmVwb3J0RnJhbWUgPSAwOwogICAgICAgIHByb2Nlc3MoaW5wdXRzLCBvdXRwdXRzKSB7CiAgICAgICAgICAgIGNvbnN0IGlucHV0ID0gaW5wdXRzWzBdOwogICAgICAgICAgICBjb25zdCBvdXRwdXQgPSBvdXRwdXRzWzBdOwogICAgICAgICAgICBpZiAoIWlucHV0IHx8IGlucHV0Lmxlbmd0aCA8IDIgfHwgIW91dHB1dCB8fCBvdXRwdXQubGVuZ3RoIDwgNCkgewogICAgICAgICAgICAgICAgdGhpcy5mcmFtZXNTaG9ydElucHV0Kys7CiAgICAgICAgICAgICAgICB0aGlzLmZyYW1lc1Byb2Nlc3NlZCsrOwogICAgICAgICAgICAgICAgdGhpcy5tYXliZVJlcG9ydChpbnB1dD8ubGVuZ3RoID8/IDAsICJzaG9ydC1pbnB1dCIsIGlucHV0LCBvdXRwdXQpOwogICAgICAgICAgICAgICAgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgZW5jb2RlU3RlcmVvVG9CRm9ybWF0KGlucHV0WzBdLCBpbnB1dFsxXSwgb3V0cHV0WzBdLCBvdXRwdXRbMV0sIG91dHB1dFsyXSwgb3V0cHV0WzNdKTsKICAgICAgICAgICAgdGhpcy5mcmFtZXNQcm9jZXNzZWQrKzsKICAgICAgICAgICAgdGhpcy5tYXliZVJlcG9ydChpbnB1dC5sZW5ndGgsICJvayIsIGlucHV0LCBvdXRwdXQpOwogICAgICAgICAgICByZXR1cm4gdHJ1ZTsKICAgICAgICB9CiAgICAgICAgbWF5YmVSZXBvcnQoY2hhbm5lbHMsIGtpbmQsIGlucHV0LCBvdXRwdXQpIHsKICAgICAgICAgICAgaWYgKHRoaXMuZnJhbWVzUHJvY2Vzc2VkIC0gdGhpcy5sYXN0UmVwb3J0RnJhbWUgPCA3NTApCiAgICAgICAgICAgICAgICByZXR1cm47CiAgICAgICAgICAgIHRoaXMubGFzdFJlcG9ydEZyYW1lID0gdGhpcy5mcmFtZXNQcm9jZXNzZWQ7CiAgICAgICAgICAgIGxldCBzdGF0cyA9ICIiOwogICAgICAgICAgICBpZiAoaW5wdXQgJiYgaW5wdXQubGVuZ3RoID49IDIgJiYgb3V0cHV0ICYmIG91dHB1dC5sZW5ndGggPj0gNCkgewogICAgICAgICAgICAgICAgY29uc3QgcGVhayA9IChhKSA9PiB7CiAgICAgICAgICAgICAgICAgICAgbGV0IG0gPSAwOwogICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYS5sZW5ndGg7IGkrKykgewogICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB2ID0gTWF0aC5hYnMoYVtpXSk7CiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh2ID4gbSkKICAgICAgICAgICAgICAgICAgICAgICAgICAgIG0gPSB2OwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgICAgICByZXR1cm4gbTsKICAgICAgICAgICAgICAgIH07CiAgICAgICAgICAgICAgICBzdGF0cyA9CiAgICAgICAgICAgICAgICAgICAgYCBwZWFrTD0ke3BlYWsoaW5wdXRbMF0pLnRvRml4ZWQoNCl9YCArCiAgICAgICAgICAgICAgICAgICAgICAgIGAgcGVha1I9JHtwZWFrKGlucHV0WzFdKS50b0ZpeGVkKDQpfWAgKwogICAgICAgICAgICAgICAgICAgICAgICBgIHBlYWtXPSR7cGVhayhvdXRwdXRbMF0pLnRvRml4ZWQoNCl9YCArCiAgICAgICAgICAgICAgICAgICAgICAgIGAgcGVha1k9JHtwZWFrKG91dHB1dFsxXSkudG9GaXhlZCg0KX1gICsKICAgICAgICAgICAgICAgICAgICAgICAgYCBwZWFrWj0ke3BlYWsob3V0cHV0WzJdKS50b0ZpeGVkKDQpfWAgKwogICAgICAgICAgICAgICAgICAgICAgICBgIHBlYWtYPSR7cGVhayhvdXRwdXRbM10pLnRvRml4ZWQoNCl9YDsKICAgICAgICAgICAgfQogICAgICAgICAgICBjb25zb2xlLmluZm8oYCR7V09SS0xFVF9MT0dfUFJFRklYfSBwcm9jZXNzIHRpY2sgZnJhbWVzVG90YWw9JHt0aGlzLmZyYW1lc1Byb2Nlc3NlZH0gc2hvcnRJbnB1dD0ke3RoaXMuZnJhbWVzU2hvcnRJbnB1dH0gY2hhbm5lbHNUaGlzVGljaz0ke2NoYW5uZWxzfSBraW5kPSR7a2luZH0ke3N0YXRzfWApOwogICAgICAgIH0KICAgIH0KICAgIGNvbnNvbGUuaW5mbyhgJHtXT1JLTEVUX0xPR19QUkVGSVh9IG1vZHVsZSBldmFsdWF0aW5nYCk7CiAgICB0cnkgewogICAgICAgIGNvbnNvbGUuaW5mbyhgJHtXT1JLTEVUX0xPR19QUkVGSVh9IHJlZ2lzdGVyUHJvY2Vzc29yIHN0YXJ0YCk7CiAgICAgICAgcmVnaXN0ZXJQcm9jZXNzb3IoInN0ZXJlby10by1iZm9ybWF0IiwgU3RlcmVvVG9CRm9ybWF0UHJvY2Vzc29yKTsKICAgICAgICBjb25zb2xlLmluZm8oYCR7V09SS0xFVF9MT0dfUFJFRklYfSByZWdpc3RlclByb2Nlc3NvciBjb21wbGV0ZWApOwogICAgfQogICAgY2F0Y2ggKGVycm9yKSB7CiAgICAgICAgY29uc29sZS5lcnJvcihgJHtXT1JLTEVUX0xPR19QUkVGSVh9IHJlZ2lzdGVyUHJvY2Vzc29yIGZhaWxlZGAsIGVycm9yKTsKICAgICAgICB0aHJvdyBlcnJvcjsKICAgIH0KCiAgICBleHBvcnRzLlN0ZXJlb1RvQkZvcm1hdFByb2Nlc3NvciA9IFN0ZXJlb1RvQkZvcm1hdFByb2Nlc3NvcjsKCiAgICByZXR1cm4gZXhwb3J0czsKCn0pKHt9KTsKLy8jIHNvdXJjZU1hcHBpbmdVUkw9c3RlcmVvLXRvLWJmb3JtYXQtYnVuZGxlLmpzLm1hcAo=";class Z{listeners={};on(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!1}),()=>this.off(e,t)}once(e,t){return this.listeners[e]=this.listeners[e]??[],this.listeners[e].push({fn:t,once:!0}),()=>this.off(e,t)}off(e,t){const g=this.listeners[e];g&&(this.listeners[e]=g.filter(s=>s.fn!==t))}emit(e,t){const g=this.listeners[e];g&&(g.forEach(s=>s.fn(t)),this.listeners[e]=g.filter(s=>!s.once))}emitAsync(e,t){const g=this.listeners[e];if(g){const s=g.map(o=>Promise.resolve().then(()=>o.fn(t)).catch(i=>console.error(`Error in listener for event ${e}:`,i)));return this.listeners[e]=g.filter(o=>!o.once),Promise.all(s).then(()=>{})}return Promise.resolve()}removeAllListeners(){this.listeners={}}}class S{constructor(e=[]){this.sounds=e}_position=[0,0,0];loopCount=0;playIndex=0;preplayRandom(){if(this.sounds.length===0)return;const t=this.randomSound().preplay();return t.length>0?t[0]:void 0}playRandom(){const e=this.preplayRandom();return e&&e.play(),e}preplayOrdered(e=!0){if(this.sounds.length===0||this.playIndex>=this.sounds.length)return;const g=this.sounds[this.playIndex].preplay();if(g.length!==0)return this.playIndex=(this.playIndex+1)%this.sounds.length,!e&&this.playIndex===0&&(this.playIndex=this.sounds.length),g[0]}playOrdered(e=!0){const t=this.preplayOrdered(e);return t&&t.play(),t}get duration(){return this.sounds.map(e=>e.duration).reduce((e,t)=>Math.max(e,t),0)}seek(e){this.sounds.forEach(t=>t.seek?.(e))}addSound(e){this.sounds.push(e)}randomSound(){if(this.sounds.length===0)throw new Error("Cannot get a random sound from an empty group");const e=Math.floor(Math.random()*this.sounds.length);return this.sounds[e]}preplay(){return this.sounds.map(t=>t.preplay()).flat()}play(){const e=[];return this.preplay().forEach(t=>{t.play(),e.push(t)}),e}get isPlaying(){return this.sounds.some(e=>e.isPlaying)}stop(){this.sounds.forEach(e=>e.stop())}pause(){this.sounds.forEach(e=>e.pause())}fadeTo(e,t,g){return Promise.all(this.sounds.map(s=>s.fadeTo(e,t,g))).then(()=>{})}fadeIn(e,t){return Promise.all(this.sounds.map(g=>g.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.sounds.map(g=>g.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.sounds.map(g=>g.stopWithFade(e,t))).then(()=>{})}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.sounds.forEach(t=>t.loop(e)),this.loopCount)}addFilter(e){this.sounds.forEach(t=>t.addFilter(e))}removeFilter(e){this.sounds.forEach(t=>t.removeFilter(e))}set position(e){this._position=e,this.sounds.forEach(t=>t.position=this._position)}get position(){return this._position}get volume(){return this.sounds.length===0?1:this.sounds.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.sounds.length}set volume(e){this.sounds.forEach(t=>t.volume=e)}get playbackRate(){return this.sounds.length===0?1:this.sounds[0].playbackRate}set playbackRate(e){this.sounds.forEach(t=>t.playbackRate=e)}}class b{_filters=[];addFilter(e){if(this._filters.includes(e))throw new Error("Cannot add the same filter instance twice");this._filters.push(e)}removeFilter(e){const t=this._filters.length;if(this._filters=this._filters.filter(g=>g!==e),this._filters.length===t)throw new Error("Cannot remove filter that was never added to this container")}applyFilters(e){return this._filters.reduce((t,g)=>(t.connect(g),g),e),this._filters.length>0?this._filters[this._filters.length-1]:e}get filters(){return this._filters}addFilters(e){e.forEach(t=>this.addFilter(t))}removeFilters(e){e.forEach(t=>this.removeFilter(t))}cleanup(){this._filters.forEach(e=>e.disconnect()),this._filters=[]}}class X extends b{context;source;gainNode;panner;constructor(e,t,g,s=0){super(),this.source=e,this.gainNode=t,this.context=g,this.panner=g.createPanner(),e.connect(this.panner).connect(this.gainNode),this.refreshFilters()}get duration(){return 0}play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");return[this]}get isPlaying(){return!!this.source}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(e){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.gainNode.gain.value=e}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.stop())}pause(){if(!this.source)throw new Error("Cannot pause a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!1)}resume(){if(!this.source)throw new Error("Cannot resume a sound that has been cleaned up");this.source.mediaStream.getTracks().forEach(e=>e.enabled=!0)}addFilter(e){super.addFilter(e),this.refreshFilters()}removeFilter(e){super.removeFilter(e),this.refreshFilters()}set position(e){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");const[t,g,s]=e;this.panner.positionX.value=t,this.panner.positionY.value=g,this.panner.positionZ.value=s}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");return[this.panner.positionX.value,this.panner.positionY.value,this.panner.positionZ.value]}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get playbackRate(){return 1}set playbackRate(e){}}class T extends b{context;_position=[0,0,0];loopCount=0;prevVolume=1;microphoneGainNode;streamPlayback;stream;streamSource;constructor(e,t){super(),this.context=e,this.microphoneGainNode=this.context.createGain(),t&&(this.stream=t,this.streamSource=this.createStreamSource(t))}createStreamSource(e){if(!this.context.createMediaStreamSource)throw new Error("Media stream sources are not supported on this audio context (e.g. OfflineAudioContext).");return this.context.createMediaStreamSource(e)}play(){return this.stream?(this.streamPlayback||(this.streamSource=this.streamSource??this.createStreamSource(this.stream),this.streamPlayback=new X(this.streamSource,this.microphoneGainNode,this.context)),[this.streamPlayback]):(navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.stream=e,this.streamSource=this.createStreamSource(this.stream),this.streamPlayback=new X(this.streamSource,this.microphoneGainNode,this.context),this.streamPlayback.play()}).catch(e=>{console.error("Error initializing microphone stream:",e)}),[])}get duration(){return 0}seek(e){}get isPlaying(){return!!this.streamPlayback}stop(){this.streamPlayback&&(this.streamPlayback.stop(),this.streamPlayback=void 0)}pause(){this.streamPlayback&&this.streamPlayback.pause()}resume(){this.streamPlayback&&this.streamPlayback.resume()}addFilter(e){this.streamPlayback&&this.streamPlayback.addFilter(e)}removeFilter(e){this.streamPlayback&&this.streamPlayback.removeFilter(e)}get volume(){return this.streamPlayback?this.streamPlayback.volume:0}set volume(e){this.streamPlayback&&(this.streamPlayback.volume=e)}get position(){return[0,0,0]}set position(e){}loop(e){return 0}get playbackRate(){return 1}set playbackRate(e){}}function W(c){class e extends c{playbacks=[];_position=[0,0,0];_stereoPan=0;_threeDOptions={coneInnerAngle:360,coneOuterAngle:360,coneOuterGain:0,distanceModel:"inverse",maxDistance:1e4,channelCount:2,channelCountMode:"clamped-max",channelInterpretation:"speakers",panningModel:"HRTF",refDistance:1,rolloffFactor:1,positionX:0,positionY:0,positionZ:0,orientationX:0,orientationY:0,orientationZ:0};_volume=1;play(){const g=this.preplay();return g.forEach(s=>s.play()),g}stop(){this.playbacks.forEach(g=>{g.stop(),g.cleanup()}),this.playbacks=[]}pause(){this.playbacks.forEach(g=>g.pause())}addFilter(g){super.addFilter(g)}removeFilter(g){super.removeFilter(g)}get isPlaying(){return this.playbacks.some(g=>g.isPlaying)}get position(){return[this._threeDOptions.positionX,this._threeDOptions.positionY,this._threeDOptions.positionZ]}set position(g){this._threeDOptions.positionX=g[0],this._threeDOptions.positionY=g[1],this._threeDOptions.positionZ=g[2],this.playbacks.forEach(s=>s.position=g)}get threeDOptions(){return this._threeDOptions}set threeDOptions(g){this._threeDOptions={...this._threeDOptions,...g},this.playbacks.forEach(s=>s.threeDOptions=this._threeDOptions)}get stereoPan(){return this._stereoPan}set stereoPan(g){this._stereoPan=g,this.playbacks.forEach(s=>s.stereoPan=g)}get volume(){return this._volume}set volume(g){this._volume=g,this.playbacks.forEach(s=>s.volume=g)}fadeTo(g,s,o){return this._volume=g,Promise.all(this.playbacks.map(i=>i.fadeTo(g,s,o))).then(()=>{})}fadeIn(g,s){return Promise.all(this.playbacks.map(o=>o.fadeIn(g,s))).then(()=>{})}fadeOut(g,s){return Promise.all(this.playbacks.map(o=>o.fadeOut(g,s))).then(()=>{})}stopWithFade(g,s){return this.fadeOut(g,s).then(()=>this.stop())}}return e}function F(c){class e extends c{panner;_panType="stereo";get panType(){return this._panType}setPanType(g,s){this._panType===g&&this.panner||(this.panner&&this.panner.disconnect(),this._panType=g,g==="stereo"?this.panner=s.createStereoPanner():this.panner=s.createPanner())}setPannerNode(g){this.panner=g}get stereoPan(){return this.panType==="stereo"?this.panner.pan.value:null}set stereoPan(g){if(this.panType!=="stereo")throw new Error("Stereo panning is not available when using HRTF.");if(!this.panner)throw new Error("Cannot set stereo pan of a sound that has been cleaned up");if(g<-1||g>1)throw new RangeError("Stereo pan must be between -1 and 1.");this.panner.pan.setValueAtTime(g,this.panner.context.currentTime)}get threeDOptions(){if(!this.panner)throw new Error("Cannot get 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get 3D options of a sound that is not using HRTF");const g=this.panner;return{coneInnerAngle:g.coneInnerAngle,coneOuterAngle:g.coneOuterAngle,coneOuterGain:g.coneOuterGain,distanceModel:g.distanceModel,maxDistance:g.maxDistance,channelCount:this.panner.channelCount,channelCountMode:g.channelCountMode,channelInterpretation:g.channelInterpretation,panningModel:g.panningModel,refDistance:g.refDistance,rolloffFactor:g.rolloffFactor,positionX:g.positionX.value,positionY:g.positionY.value,positionZ:g.positionZ.value,orientationX:g.orientationX.value,orientationY:g.orientationY.value,orientationZ:g.orientationZ.value}}set threeDOptions(g){if(!this.panner)throw new Error("Cannot set 3D options of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot set 3D options of a sound that is not using HRTF");const s=this.panner;s.coneInnerAngle=g.coneInnerAngle!==void 0?g.coneInnerAngle:s.coneInnerAngle,s.coneOuterAngle=g.coneOuterAngle!==void 0?g.coneOuterAngle:s.coneOuterAngle,s.coneOuterGain=g.coneOuterGain!==void 0?g.coneOuterGain:s.coneOuterGain,s.distanceModel=g.distanceModel||s.distanceModel,s.maxDistance=g.maxDistance!==void 0?g.maxDistance:s.maxDistance,s.channelCount=g.channelCount!==void 0?g.channelCount:s.channelCount,s.channelCountMode=g.channelCountMode||s.channelCountMode,s.channelInterpretation=g.channelInterpretation||s.channelInterpretation,s.panningModel=g.panningModel||s.panningModel,s.refDistance=g.refDistance!==void 0?g.refDistance:s.refDistance,s.rolloffFactor=g.rolloffFactor!==void 0?g.rolloffFactor:s.rolloffFactor,s.positionX.value=g.positionX!==void 0?g.positionX:s.positionX.value,s.positionY.value=g.positionY!==void 0?g.positionY:s.positionY.value,s.positionZ.value=g.positionZ!==void 0?g.positionZ:s.positionZ.value,s.orientationX.value=g.orientationX!==void 0?g.orientationX:s.orientationX.value,s.orientationY.value=g.orientationY!==void 0?g.orientationY:s.orientationY.value,s.orientationZ.value=g.orientationZ!==void 0?g.orientationZ:s.orientationZ.value}set position(g){if(!this.panner)throw new Error("Cannot move a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot move a sound that is not using HRTF");const[s,o,i]=g,a=this.panner;a.positionX.value=s,a.positionY.value=o,a.positionZ.value=i}get position(){if(!this.panner)throw new Error("Cannot get position of a sound that has been cleaned up");if(this.panType!=="HRTF")throw new Error("Cannot get position of a sound that is not using HRTF");const g=this.panner;return[g.positionX.value,g.positionY.value,g.positionZ.value]}cleanup(){this.panner&&(this.panner.disconnect(),this.panner=void 0),super.cleanup()}}return e}function H(c){class e extends c{gainNode;_fadeTimeout;_isFading=!1;setGainNode(g){this.gainNode=g}cleanup(){this.cancelFade(),this.gainNode&&(this.gainNode.disconnect(),this.gainNode=void 0),super.cleanup()}get volume(){if(!this.gainNode)throw new Error("Cannot get volume of a sound that has been cleaned up");return this.gainNode.gain.value}set volume(g){if(!this.gainNode)throw new Error("Cannot set volume of a sound that has been cleaned up");this.cancelFade(),this.gainNode.gain.value=g}get isFading(){return this._isFading}fadeTo(g,s,o="linear"){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");this.cancelFade();const i=this.gainNode.context.currentTime,a=i+s/1e3;return this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,i),o==="exponential"?this.gainNode.gain.exponentialRampToValueAtTime(g===0?1e-4:g,a):this.gainNode.gain.linearRampToValueAtTime(g,a),this._isFading=!0,new Promise(n=>{this._fadeTimeout=setTimeout(()=>{this._isFading=!1,g===0&&o==="exponential"&&this.gainNode&&(this.gainNode.gain.value=0),n()},s)})}cancelFade(){if(this._fadeTimeout&&(clearTimeout(this._fadeTimeout),this._fadeTimeout=void 0),this._isFading&&this.gainNode){const g=this.gainNode.context.currentTime;this.gainNode.gain.cancelScheduledValues(g),this.gainNode.gain.setValueAtTime(this.gainNode.gain.value,g)}this._isFading=!1}fadeIn(g,s){if(!this.gainNode)throw new Error("Cannot fade a sound that has been cleaned up");const o=this.gainNode.gain.value;return this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(o,g,s)}fadeOut(g,s){return this.fadeTo(0,g,s)}}return e}class K extends F(H(b)){source;_playing=!1;origin;eventEmitter=new Z;constructor(){super()}get isPlaying(){return this.source?this._playing:!1}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}fadeTo(e,t,g="linear"){return this.emit("fadeStart",{target:e,duration:t,type:g}),super.fadeTo(e,t,g).then(()=>{this.emit("fadeEnd",void 0)})}cancelFade(){const e=this._isFading;super.cancelFade(),e&&this.emit("fadeCancel",void 0)}cleanup(){this.eventEmitter.removeAllListeners(),super.cleanup()}}class G extends K{constructor(e,t,g){super(),this.origin=e,this.context=e.context,this.loopCount=e.loopCount,this.setPanType(e.panType,e.context),this.source=t,"buffer"in t&&t.buffer&&(this.buffer=t.buffer),this.setupSourceNode(t),this.source.connect(this.panner),this.setGainNode(g),this.panner.connect(this.gainNode),this.refreshFilters()}context;loopCount=0;currentLoop=0;buffer;_offset=0;_startTime=0;_state=0;_playbackRate=1;_fadeInConfig;_fadeOutConfig;_loopEndCallback;setupSourceNode(e){if("mediaElement"in e&&e.mediaElement)e.mediaElement.onended=this.loopEnded;else if("onended"in e)e.onended=this.loopEnded;else throw new Error("Unsupported source type")}get isPlaying(){return this._state===1}get duration(){if(!this.source)throw new Error("Cannot get duration of a sound that has been cleaned up");return"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.duration:this.buffer?this.buffer.duration||NaN:NaN}get playbackRate(){return this._playbackRate}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}set playbackRate(e){if(e<=0)throw new Error("Playback rate must be greater than 0");if(this._state===1){const t=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=t,this._startTime=this.context.currentTime}this._playbackRate=e,this.source&&("playbackRate"in this.source&&(this.source.playbackRate.value=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.playbackRate=e))}loopEnded=()=>{!this.source||this._state!==1||(this.currentLoop++,this.loopCount!=="infinite"&&this.currentLoop>this.loopCount?(this.emit("ended",void 0),this._fadeOutConfig?this.fadeOut(this._fadeOutConfig.duration,this._fadeOutConfig.type).then(()=>{this.stop(),this.removeFromOrigin()}):(this.stop(),this.removeFromOrigin())):(this._loopEndCallback?.(),this.seek(0),this._state!==1&&!("mediaElement"in this.source)&&this.play(),this._fadeInConfig?.perLoop&&this.gainNode&&(this.gainNode.gain.setValueAtTime(1e-4,this.gainNode.context.currentTime),this.fadeTo(this._fadeInConfig.targetVolume,this._fadeInConfig.duration,this._fadeInConfig.type))))};play(){if(!this.source)throw new Error("Cannot play a sound that has been cleaned up");if(this._state===1)return[this];const e=this._state===2;try{let t;if(this._state===2?"mediaElement"in this.source&&this.source.mediaElement?t=this.source.mediaElement.play():(this.recreateSource(),"start"in this.source&&this.source.start&&this.source.start(0,this._offset)):"mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.currentTime=this._offset,t=this.source.mediaElement.play()):"start"in this.source&&this.source.start&&(this.recreateSource(),this.source.start(0,this._offset)),t){const g=this._state;t.then(()=>{this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()})},s=>{this._state=g,this.emitAsync("error",{error:s,errorType:"source",timestamp:Date.now(),recoverable:!0})})}else this._startTime=this.context.currentTime,this._state=1,this.emit("play",this),e&&this.emit("resume",void 0),this.origin.cacophony?.emit("globalPlay",{source:this.origin,timestamp:Date.now()});return[this]}catch(t){throw this.emitAsync("error",{error:t,errorType:"source",timestamp:Date.now(),recoverable:!0}),t}}pause(){if(!this.source||this._state!==1)return;const e=(this.context.currentTime-this._startTime)*this._playbackRate;this._offset+=e,"mediaElement"in this.source&&this.source.mediaElement?this.source.mediaElement.pause():"stop"in this.source&&this.source.stop(),this._state=2,this.emit("pause",void 0),this.origin.cacophony?.emit("globalPause",{source:this.origin,timestamp:Date.now()})}stop(){if(!this.source)throw new Error("Cannot stop a sound that has been cleaned up");this._state===3||this._state===0||(this.cancelFade(),"stop"in this.source&&this._state===1&&this.source.stop(),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0),this._offset=0,this._startTime=0,this._state=3,this.emit("stop",void 0),this.origin.cacophony?.emit("globalStop",{source:this.origin,timestamp:Date.now()}))}fadeIn(e,t,g){return g?.perLoop&&(this._fadeInConfig={duration:e,type:t||"linear",perLoop:!0,targetVolume:this.gainNode.gain.value}),super.fadeIn(e,t)}configureFadeOut(e,t){this._fadeOutConfig={duration:e,type:t||"linear"}}stopWithFade(e,t){return this.fadeOut(e,t).then(()=>this.stop())}seek(e){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot seek a sound that has been cleaned up");if(!Number.isFinite(e)||e<0)throw new Error("Invalid time value for seek");const t=this._state===1;t&&this.pause(),this._offset=e,"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.currentTime=e),t&&this.play()}get currentTime(){if(this._state===1){const e=(this.context.currentTime-this._startTime)*this._playbackRate;return this._offset+e}else return this._offset}removeFromOrigin(){const e=this.origin.playbacks.indexOf(this);e!==-1&&this.origin.playbacks.splice(e,1)}recreateSource(){if(!this.buffer||!this.panner||!this.context||!this.gainNode)throw new Error("Cannot recreate source of a sound that has been cleaned up");try{this.source&&(!("mediaElement"in this.source)&&"onended"in this.source&&(this.source.onended=null),this.source.disconnect()),this.source=this.context.createBufferSource(),this.source.buffer=this.buffer,this.source.connect(this.panner),this.source.onended=this.loopEnded,this.playbackRate=this._playbackRate,this.refreshFilters()}catch(e){throw this.emitAsync("error",{error:e,errorType:"source",timestamp:Date.now(),recoverable:!1}),e}}set sourceLoop(e){if(!this.source)throw new Error("Cannot set loop on a sound that has been cleaned up");"loop"in this.source&&(this.source.loop=e),"mediaElement"in this.source&&this.source.mediaElement&&(this.source.mediaElement.loop=e)}cleanup(){this.source&&("mediaElement"in this.source&&this.source.mediaElement?(this.source.mediaElement.pause(),this.source.mediaElement.currentTime=0,this.source.mediaElement.loop=!1,this.source.mediaElement.onended=null):"onended"in this.source&&(this.source.onended=null),this._offset=0,this._startTime=0,this._state=3,this.currentLoop=0,this.source.disconnect(),this.source=void 0,super.cleanup())}assertNotCleanedUp(){if(!this.source||!this.gainNode||!this.panner)throw new Error("Cannot perform operation on a sound that has been cleaned up")}addFilter(e){this.assertNotCleanedUp(),super.addFilter(e),this.refreshFilters()}removeFilter(e){this.assertNotCleanedUp(),super.removeFilter(e),this.refreshFilters()}loop(e){if(!this.source)throw new Error("Cannot loop a sound that has been cleaned up");if(e!==void 0&&(this.loopCount=e==="infinite"?"infinite":Math.max(0,e),this.currentLoop=0),"mediaElement"in this.source&&this.source.mediaElement){const t=this.source.mediaElement;t.loop=this.loopCount==="infinite"}else if("loop"in this.source)this.source.loop=this.loopCount==="infinite",this.source.buffer&&(this.source.loopEnd=this.source.buffer.duration,this.source.loopStart=0);else throw new Error("Unsupported source type");return this.loopCount}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}get outputNode(){if(!this.gainNode)throw new Error("Cannot access output node of a playback that has been cleaned up");return this.gainNode}connect(e){return this.outputNode.connect(e)}disconnect(e){e?this.outputNode.disconnect(e):this.outputNode.disconnect()}clone(e={}){if(!this.source||!this.gainNode||!this.context)throw new Error("Cannot clone a sound that has been cleaned up");const t=e.panType||this.panType,g=this.context.createGain();let s;if("buffer"in this.source&&this.source.buffer)s=this.context.createBufferSource(),s.buffer=this.source.buffer;else if("mediaElement"in this.source&&this.source.mediaElement){if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context.");s=this.context.createMediaElementSource(this.source.mediaElement)}else throw new Error("Unsupported source type");const o=e.loopCount!==void 0?e.loopCount:this.loopCount,i=new G(this.origin,s,g);return i.loopCount=o,i.currentLoop=this.currentLoop,i.setPanType(t,this.context),i.volume=this.volume,i.playbackRate=this._playbackRate,i._offset=this._offset,i._state=this._state,this._filters.forEach(a=>{const n=this.context.createBiquadFilter();n.type=a.type,n.frequency.value=a.frequency.value,n.Q.value=a.Q.value,n.gain.value=a.gain.value,i.addFilter(n)}),this._state===1&&i.play(),i}}class y extends W(b){constructor(e,t,g,s,o=f.Buffer,i="HRTF",a){super(),this.url=e,this.globalGainNode=s,this.soundType=o,this.panType=i,this._cacophony=a,this.buffer=t,this.context=g,this._cacophony?.registerSoundForCleanup(this,this._holdings,this._unregisterToken)}buffer;context;loopCount=0;_playbackRate=1;eventEmitter=new Z;_holdings={sources:[],gainNodes:[],mediaElements:[]};_unregisterToken={};get cacophony(){return this._cacophony}get volume(){return super.volume}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,g=e.stereoPan!==void 0?e.stereoPan:this.stereoPan,s=e.threeDOptions||this.threeDOptions,o=e.loopCount!==void 0?e.loopCount:this.loopCount,i=e.playbackRate||this.playbackRate,a=e.volume!==void 0?e.volume:this.volume,n=e.position!==void 0?e.position:this.position,I=e.filters?.length?e.filters:this._filters,C=new y(this.url,this.buffer,this.context,this.globalGainNode,this.soundType,t,this.cacophony);return C.loop(o),C.playbackRate=i,C.volume=a,t==="HRTF"?(C.threeDOptions=s,C.position=n):C.stereoPan=g,C.addFilters(I),C}preplay(){try{let e;if(this.buffer)e=this.context.createBufferSource(),e.buffer=this.buffer;else{if(!this.context.createMediaElementSource)throw new Error("Media element sources are not supported on this audio context (e.g. OfflineAudioContext). Use buffer-based sounds instead.");const s=new Audio;s.crossOrigin="anonymous",s.src=this.url,s.preload="auto",e=this.context.createMediaElementSource(s)}const t=this.context.createGain();t.connect(this.globalGainNode);const g=new G(this,e,t);return this._holdings.sources.push(e),this._holdings.gainNodes.push(t),"mediaElement"in e&&e.mediaElement&&this._holdings.mediaElements.push(e.mediaElement),g.setGainNode(t),g.volume=this.volume,g.playbackRate=this.playbackRate,this._filters.forEach(s=>{const o=this.context.createBiquadFilter();o.type=s.type,o.frequency.value=s.frequency.value,o.Q.value=s.Q.value,o.gain.value=s.gain.value,g.addFilter(o)}),this.panType==="HRTF"?(g.threeDOptions=this.threeDOptions,g.position=this.position):this.panType==="stereo"&&(g.stereoPan=this.stereoPan),g.on("ended",()=>{this.emit("ended",void 0)}),g._loopEndCallback=()=>{this.emit("loopEnd",void 0)},g.on("error",s=>{this.emitAsync("soundError",{url:this.url,error:s.error,errorType:"playback",timestamp:s.timestamp,recoverable:s.recoverable})}),this.playbacks.push(g),[g]}catch(e){const t={url:this.url,error:e,errorType:"playback",timestamp:Date.now(),recoverable:!0};throw this.emitAsync("soundError",t),e}}play(e){const t=this.preplay();for(const g of t){const s=i=>{o(),this.emit("play",i)},o=()=>{g.off("play",s),g.off("error",o)};g.on("play",s),g.on("error",o);try{g.play()}catch(i){throw o(),i}}if(e)for(const g of t)e.fadeIn!==void 0&&g.fadeIn(e.fadeIn,e.fadeType,{perLoop:e.fadeInPerLoop}),e.fadeOut!==void 0&&g.configureFadeOut(e.fadeOut,e.fadeType);return t}stop(){this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,super.stop(),this.emit("stop",void 0)}pause(){super.pause(),this.emit("pause",void 0)}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0)}seek(e){this.playbacks.forEach(t=>t.seek(e))}get duration(){return this.playbacks.length>0?this.playbacks[0].duration:this.buffer?.duration||NaN}loop(e){return e===void 0?this.loopCount:(this.loopCount=e,this.playbacks.forEach(t=>t.loop(e)),this.loopCount)}get playbackRate(){return this._playbackRate}set playbackRate(e){this._playbackRate=e,this.playbacks.forEach(t=>t.playbackRate=e),this.emit("rateChange",e)}set volume(e){super.volume=e,this.emit("volumeChange",e)}cleanup(){this._cacophony?.unregisterSoundCleanup(this._unregisterToken),this._holdings.sources.length=0,this._holdings.gainNodes.length=0,this._holdings.mediaElements.length=0,this.playbacks.forEach(e=>e.cleanup()),this.playbacks=[],this.eventEmitter.removeAllListeners()}}function M(c){class e extends K{_oscillatorOptions={};get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(g){this._oscillatorOptions=g,this.source&&(this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type))}play(){if(!this.source)throw new Error("No source node found");return this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,[this]}stop(){this.source?.stop&&(this.source.stop(),this._playing=!1)}pause(){this.stop()}get frequency(){return this.source.frequency.value}set frequency(g){this.source.frequency.value=g,this.oscillatorOptions.frequency=g}get detune(){return this.source.detune.value}set detune(g){this.source.detune.value=g,this.oscillatorOptions.detune=g}get type(){return this.source.type}set type(g){this.source.type=g,this.oscillatorOptions.type=g}}return e}class O extends M(F(H(b))){constructor(e,t,g){super(),this.origin=e,this.source=t,this.context=e.context,this.setPanType(e.panType,e.context),this.source.connect(this.panner),this.setGainNode(g),this.panner.connect(this.gainNode),this.refreshFilters(),this.oscillatorOptions={detune:t.detune.value,frequency:t.frequency.value,type:t.type}}context;_state=0;play(){if(!this.source||!this.panner)throw new Error("Cannot play a synth that has been cleaned up");return this._state===1?[this]:((this._state===2||this._state===3)&&this.recreateSource(),this.oscillatorOptions.detune!==void 0&&(this.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(this.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(this.source.type=this.oscillatorOptions.type),this.source.start(),this._playing=!0,this._state=1,[this])}pause(){!this.source||this._state!==1||(this.source.stop(),this._playing=!1,this._state=2)}stop(){!this.source||this._state===0||this._state===3||(this._state===1&&this.source.stop(),this._playing=!1,this._state=3)}refreshFilters(){if(!this.panner||!this.gainNode)throw new Error("Cannot update filters on a sound that has been cleaned up");let e=this.panner;e.disconnect(),e=this.applyFilters(e),e.connect(this.gainNode)}cleanup(){this.panner&&this.gainNode&&(this.source.disconnect(this.panner),this.panner.disconnect(),this.gainNode.disconnect()),this.eventEmitter.removeAllListeners()}recreateSource(){if(!this.panner)throw new Error("Cannot recreate source of a synth that has been cleaned up");this.source.disconnect(),this.source=this.context.createOscillator(),this.source.connect(this.panner)}}class B extends W(b){constructor(e,t,g=f.Oscillator,s="HRTF",o={},i){super(),this.context=e,this.globalGainNode=t,this.soundType=g,this.panType=s,this.cacophony=i,this.context=e,this._oscillatorOptions=o}_oscillatorOptions;playbacks=[];eventEmitter=new Z;on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}clone(e={}){const t=e.panType||this.panType,g=e.stereoPan!==void 0?e.stereoPan:this.stereoPan??0,s=e.threeDOptions||this.threeDOptions,o=e.volume!==void 0?e.volume:this.volume,i=e.position?.length?e.position:this.position,a=e.filters?.length?e.filters:this._filters,n=e.oscillatorOptions||this._oscillatorOptions,I=new B(this.context,this.globalGainNode,this.soundType,t,n,this.cacophony);return I._volume=o,I._position=i,I._stereoPan=g,I._threeDOptions=s,I.addFilters(a),I}preplay(){const e=this.context.createOscillator();return this.createPlayback(e)}createPlayback(e){this.oscillatorOptions.detune!==void 0&&(e.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(e.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(e.type=this.oscillatorOptions.type);const t=this.context.createGain();t.connect(this.globalGainNode);const g=new O(this,e,t);return g.volume=this.volume,this._filters.forEach(s=>{const o=this.context.createBiquadFilter();o.type=s.type,o.frequency.value=s.frequency.value,o.Q.value=s.Q.value,o.gain.value=s.gain.value,g.addFilter(o)}),this.panType==="HRTF"?(g.threeDOptions=this.threeDOptions,g.position=this.position):this.panType==="stereo"&&(g.stereoPan=this.stereoPan),this.playbacks.push(g),[g]}play(){const e=super.play();return this.emit("play",e[0]),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()}),e}stop(){super.stop(),this.emit("stop",void 0),this.cacophony?.emit("globalStop",{source:this,timestamp:Date.now()})}pause(){super.pause(),this.emit("pause",void 0),this.cacophony?.emit("globalPause",{source:this,timestamp:Date.now()})}resume(){this.playbacks.forEach(e=>e.play()),this.emit("resume",void 0),this.cacophony?.emit("globalPlay",{source:this,timestamp:Date.now()})}get volume(){return super.volume}set volume(e){super.volume=e,this.emit("volumeChange",e)}get oscillatorOptions(){return this._oscillatorOptions}set oscillatorOptions(e){this._oscillatorOptions=e,this.playbacks.forEach(t=>{t.source&&(this.oscillatorOptions.detune!==void 0&&(t.source.detune.value=this.oscillatorOptions.detune),this.oscillatorOptions.frequency!==void 0&&(t.source.frequency.value=this.oscillatorOptions.frequency),this.oscillatorOptions.type&&(t.source.type=this.oscillatorOptions.type))})}get frequency(){return this.oscillatorOptions.frequency??440}set frequency(e){this._oscillatorOptions.frequency=e,this.playbacks.forEach(t=>t.frequency=e),this.emit("frequencyChange",e)}get detune(){return this.oscillatorOptions.detune}set detune(e){this._oscillatorOptions.detune=e,this.playbacks.forEach(t=>t.detune=e),this.emit("detuneChange",e)}get type(){return this.oscillatorOptions.type||"sine"}set type(e){this._oscillatorOptions.type=e,this.playbacks.forEach(t=>t.type=e),this.emit("typeChange",e)}}var f=(c=>(c.HTML="HTML",c.Streaming="Streaming",c.Buffer="Buffer",c.Oscillator="oscillator",c))(f||{});const u="[cacophony/worklet]";class R{context;globalGainNode;listener;prevVolume=1;loadedAudioWorklets=new Set;finalizationRegistry;eventEmitter=new Z;cache;createAudioWorkletNode;constructor(e,t,g={}){this.context=e||new AudioContext,this.listener=this.context.listener,this.globalGainNode=this.context.createGain(),this.globalGainNode.connect(this.context.destination),this.cache=t||new r,this.createAudioWorkletNode=g.createAudioWorkletNode||((s,o,i)=>new AudioWorkletNode(s,o,i)),this.finalizationRegistry=new FinalizationRegistry(s=>{for(const o of s.sources)o.disconnect();for(const o of s.gainNodes)o.disconnect();for(const o of s.mediaElements)o.pause(),o.removeAttribute("src"),o.load()})}registerSoundForCleanup(e,t,g){this.finalizationRegistry.register(e,t,g)}unregisterSoundCleanup(e){this.finalizationRegistry.unregister(e)}static createOffline(e,t){const g=e.context||new OfflineAudioContext(e.numberOfChannels,e.length,e.sampleRate);return new R(g,t)}get isOffline(){return typeof this.context.startRendering=="function"}async startRendering(){if(typeof this.context.startRendering!="function")throw new Error("startRendering() is only available on offline audio contexts. Use Cacophony.createOffline() to create one.");return this.context.startRendering()}on(e,t){return this.eventEmitter.on(e,t)}off(e,t){this.eventEmitter.off(e,t)}emit(e,t){this.eventEmitter.emit(e,t)}async emitAsync(e,t){return this.eventEmitter.emitAsync(e,t)}async loadWorklets(e){this.context.audioWorklet?(await this.createWorkletNode("phase-vocoder",D,e),await this.loadStereoToBFormatWorklet(e)):console.warn("AudioWorklet not supported")}async loadStereoToBFormatWorklet(e){await this.loadAudioWorkletModule("stereo-to-bformat",J,e)}async createWorkletNode(e,t,g,s){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");try{const o=this.createAudioWorkletNode(this.context,e,s);return console.info(`${u} construct succeeded`,{name:e,loaded:this.loadedAudioWorklets.has(e)}),o}catch(o){console.warn(`${u} construct failed`,{name:e,loaded:this.loadedAudioWorklets.has(e),error:o});try{await this.loadAudioWorkletModule(e,t,g)}catch(i){throw console.error(`${u} load failed`,{name:e,error:i}),i}try{const i=this.createAudioWorkletNode(this.context,e,s);return console.info(`${u} construct after load succeeded`,{name:e}),i}catch(i){throw console.error(`${u} construct after load failed`,{name:e,error:i}),i}}}async createStereoToBFormatNode(e){return this.createWorkletNode("stereo-to-bformat",J,e,{numberOfInputs:1,numberOfOutputs:1,outputChannelCount:[4],channelCount:2,channelCountMode:"explicit",channelInterpretation:"speakers"})}async loadAudioWorkletModule(e,t,g){if(!this.context.audioWorklet)throw new Error("AudioWorklet not supported");if(this.loadedAudioWorklets.has(e)){console.info(`${u} load skipped`,{name:e});return}console.info(`${u} addModule start`,{name:e,url:t,aborted:g?.aborted??!1});try{await this.context.audioWorklet.addModule(t,{credentials:"same-origin",...g&&{signal:g}}),this.loadedAudioWorklets.add(e),console.info(`${u} addModule resolved`,{name:e})}catch(s){throw console.error(`${u} addModule rejected`,{name:e,error:s}),s}}createAbortError(){return new DOMException("Operation was aborted","AbortError")}createMediaSound(e,t,g,s){return s?.aborted?Promise.reject(this.createAbortError()):new Promise((o,i)=>{const a=new Audio;let n=!1;const I=()=>{a.removeEventListener("loadedmetadata",h),a.removeEventListener("error",p),s?.removeEventListener("abort",m)},C=()=>{a.pause(),a.src="",a.load()},l=d=>{n||(n=!0,I(),d())},h=()=>{l(()=>{o(new y(e,void 0,this.context,this.globalGainNode,t,g,this))})},p=()=>{const d=new Error(`Failed to load audio from ${e}`);l(()=>{C(),i(d)})},m=()=>{const d=this.createAbortError();l(()=>{C(),i(d)})};a.crossOrigin="anonymous",a.preload="auto",a.addEventListener("loadedmetadata",h),a.addEventListener("error",p),s?.addEventListener("abort",m,{once:!0}),a.src=e,a.load()})}clearMemoryCache(){this.cache.clearMemoryCache()}createOscillator(e,t="HRTF"){return new B(this.context,this.globalGainNode,"oscillator",t,e,this)}async createSound(e,t="Buffer",g="HRTF",s){if(typeof e=="object")return Promise.resolve(new y("",e,this.context,this.globalGainNode,"Buffer",g,this));const o=e;return t==="HTML"?this.createMediaSound(o,"HTML",g,s):t==="Streaming"?this.createMediaSound(o,"Streaming",g,s):this.cache.getAudioBuffer(this.context,o,s,{onLoadingStart:i=>this.emitAsync("loadingStart",i),onLoadingProgress:i=>this.emitAsync("loadingProgress",i),onLoadingComplete:i=>this.emitAsync("loadingComplete",i),onLoadingError:i=>this.emitAsync("loadingError",i),onCacheHit:i=>this.emitAsync("cacheHit",i),onCacheMiss:i=>this.emitAsync("cacheMiss",i),onCacheError:i=>this.emitAsync("cacheError",i)}).then(i=>new y(o,i,this.context,this.globalGainNode,t,g,this))}async createGroup(e){const t=new S;return e.forEach(g=>t.addSound(g)),t}async createGroupFromUrls(e,t="Buffer",g="HRTF",s){const o=new S;return(await Promise.all(e.map(a=>this.createSound(a,t,g,s)))).forEach(a=>o.addSound(a)),o}async createStream(e,t){return this.createMediaSound(e,"Streaming","HRTF",t)}createBiquadFilter=({type:e,frequency:t,gain:g,Q:s})=>{t===void 0&&(t=350);const o=this.context.createBiquadFilter();return o.type=e||"lowpass",o.frequency.value=t,o.gain.value=g||0,o.Q.value=s||1,o};createSplitter(e=2){if(!this.context.createChannelSplitter)throw new Error("ChannelSplitterNode not supported");return this.context.createChannelSplitter(e)}createMerger(e=2){if(!this.context.createChannelMerger)throw new Error("ChannelMergerNode not supported");return this.context.createChannelMerger(e)}createPanner({coneInnerAngle:e,coneOuterAngle:t,coneOuterGain:g,distanceModel:s,maxDistance:o,channelCount:i,channelCountMode:a,channelInterpretation:n,panningModel:I,refDistance:C,rolloffFactor:l,positionX:h,positionY:p,positionZ:m,orientationX:d,orientationY:w,orientationZ:N}){const A=this.context.createPanner();return A.coneInnerAngle=e||360,A.coneOuterAngle=t||360,A.coneOuterGain=g||0,A.distanceModel=s||"inverse",A.maxDistance=o||1e4,A.channelCount=i||2,A.channelCountMode=a||"clamped-max",A.channelInterpretation=n||"speakers",A.panningModel=I||"HRTF",A.refDistance=C||1,A.rolloffFactor=l||1,A.positionX.value=h||0,A.positionY.value=p||0,A.positionZ.value=m||0,A.orientationX.value=d||0,A.orientationY.value=w||0,A.orientationZ.value=N||0,A}pause(){this.context.suspend&&(this.context.suspend(),this.emit("suspend",void 0))}resume(){this.context.resume&&(this.context.resume(),this.emit("resume",void 0))}setGlobalVolume(e){this.globalGainNode.gain.value!==e&&(this.globalGainNode.gain.value=e,this.emit("volumeChange",e))}get volume(){return this.globalGainNode.gain.value}set volume(e){if(this.muted){this.prevVolume=e;return}this.setGlobalVolume(e)}mute(){this.muted||(this.prevVolume=this.globalGainNode.gain.value,this.setGlobalVolume(0),this.emit("mute",void 0))}unmute(){this.muted&&(this.setGlobalVolume(this.prevVolume),this.emit("unmute",void 0))}get muted(){return this.globalGainNode.gain.value===0}set muted(e){e!==this.muted&&(e?this.mute():this.unmute())}getMicrophoneStream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia({audio:!0}).then(g=>{const s=new T(this.context,g);e(s)}).catch(g=>{t(g)})})}get listenerOrientation(){return{forward:[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value],up:[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}}set listenerOrientation(e){const{forward:t,up:g}=e,[s,o,i]=t,[a,n,I]=g;this.listener.forwardX.value=s,this.listener.forwardY.value=o,this.listener.forwardZ.value=i,this.listener.upX.value=a,this.listener.upY.value=n,this.listener.upZ.value=I}get listenerUpOrientation(){return[this.listener.upX.value,this.listener.upY.value,this.listener.upZ.value]}set listenerUpOrientation(e){const[t,g,s]=e;this.listener.upX.value=t,this.listener.upY.value=g,this.listener.upZ.value=s}get listenerForwardOrientation(){return[this.listener.forwardX.value,this.listener.forwardY.value,this.listener.forwardZ.value]}set listenerForwardOrientation(e){const[t,g,s]=e;this.listener.forwardX.value=t,this.listener.forwardY.value=g,this.listener.forwardZ.value=s}get listenerPosition(){return[this.listener.positionX.value,this.listener.positionY.value,this.listener.positionZ.value]}set listenerPosition(e){const[t,g,s]=e,o=this.context.currentTime;this.listener.positionX.setValueAtTime(t,o),this.listener.positionY.setValueAtTime(g,o),this.listener.positionZ.setValueAtTime(s,o)}}class P{constructor(e=[]){this.synths=e}addSynth(e){this.synths.push(e)}removeSynth(e){const t=this.synths.indexOf(e);if(t!==-1)this.synths.splice(t,1);else throw new Error("Synth not found in group")}play(){return this.synths.flatMap(e=>e.play())}stop(){this.synths.forEach(e=>e.stop())}pause(){this.synths.forEach(e=>e.pause())}resume(){this.synths.forEach(e=>e.resume())}get isPlaying(){return this.synths.some(e=>e.isPlaying)}addFilter(e){this.synths.forEach(t=>t.addFilter(e))}removeFilter(e){this.synths.forEach(t=>t.removeFilter(e))}fadeTo(e,t,g){return Promise.all(this.synths.map(s=>s.fadeTo(e,t,g))).then(()=>{})}fadeIn(e,t){return Promise.all(this.synths.map(g=>g.fadeIn(e,t))).then(()=>{})}fadeOut(e,t){return Promise.all(this.synths.map(g=>g.fadeOut(e,t))).then(()=>{})}stopWithFade(e,t){return Promise.all(this.synths.map(g=>g.stopWithFade(e,t))).then(()=>{})}get volume(){return this.synths.length===0?1:this.synths.map(e=>e.volume).reduce((e,t)=>e+t,0)/this.synths.length}set volume(e){this.synths.forEach(t=>t.volume=e)}get stereoPan(){return this.synths.length===0?null:this.synths[0].stereoPan}set stereoPan(e){this.synths.forEach(t=>t.stereoPan=e)}get position(){return this.synths.length===0?[0,0,0]:this.synths[0].position}set position(e){this.synths.forEach(t=>t.position=e)}get frequency(){return this.synths.length===0?440:this.synths[0].frequency}set frequency(e){this.synths.forEach(t=>t.frequency=e)}get detune(){return this.synths[0]?.detune}set detune(e){this.synths.forEach(t=>t.detune=e)}get type(){return this.synths.length===0?"sine":this.synths[0].type}set type(e){this.synths.forEach(t=>t.type=e)}}exports.AudioCache=r;exports.Cacophony=R;exports.Group=S;exports.MicrophonePlayback=X;exports.Playback=G;exports.Sound=y;exports.SoundType=f;exports.Synth=B;exports.SynthGroup=P;
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|