UNPKG

ixfx

Version:

Bundle of ixfx libraries

156 lines 41.6 kB
import{n as e}from"./chunk-BKBlUVio.js";import{E as t,H as n,T as r,h as i,w as a}from"./src-DlHqXvlb.js";import{C as o,M as s,b as c,v as l}from"./src-CrVWx2VD.js";import{n as u}from"./src-BnFVBvwz.js";import{D as d}from"./src-BGZztchK.js";import{v as f}from"./src-ZyALqz2x.js";import{n as p}from"./src-CIW3LrR8.js";import{f as m,mt as ee,pt as te,rt as ne,w as re}from"./src-CWZAMrn_.js";import{W as ie}from"./src-wu7Ls46R.js";import{l as h}from"./src-Cn0v-PM5.js";import{E as ae,R as oe,T as g,U as _,a as v,i as se,o as y,r as b}from"./src-B8K2o5HY.js";import{h as ce,u as le}from"./src-BeF32bo4.js";import{r as ue}from"./src-DI_Ag7DT.js";var x=class{enc=new TextEncoder;dec=new TextDecoder(`utf-8`);toBuffer(e){return this.enc.encode(e)}fromBuffer(e){return this.dec.decode(e)}},S=class{buffer=``;stream;constructor(e,t=` `){this.onData=e,this.separator=t}async close(){let e=this.stream;e&&(await e.abort(),await e.close())}clear(){this.buffer=``}writable(){return this.stream===void 0&&(this.stream=this.createWritable()),this.stream}createWritable(){let e=this;return new WritableStream({write(t){e.add(t)},close(){e.clear()}})}addImpl(e){let t=e.indexOf(this.separator);if(t<0)return this.buffer+=e,``;let n=e.substring(0,t);try{this.onData(this.buffer+n),e=e.substring(n.length+this.separator.length)}catch(e){console.warn(e)}return this.buffer=``,e}add(e){for(;e.length>0;)e=this.addImpl(e)}},C=class{paused=!1;queue=new f;writer;stream;closed=!1;chunkSize;constructor(e,t={}){this.dataHandler=e,this.chunkSize=t.chunkSize??-1,this.writer=n(async()=>{await this.onWrite()},t.interval??10)}async close(){if(this.closed)return;let e=this.stream?.getWriter();e?.releaseLock(),await e?.close(),this.closed=!0}clear(){if(this.closed)throw Error(`Buffer closed`);this.queue=new f}writable(){if(this.closed)throw Error(`Buffer closed`);return this.stream===void 0&&(this.stream=this.createWritable()),this.stream}createWritable(){let e=this;return new WritableStream({write(t){e.add(t)},close(){e.clear()}})}async onWrite(){if(this.queue.isEmpty)return!1;if(this.paused)return console.warn(`WriteBuffer.onWrite: paused...`),!0;let e=this.queue.dequeue();return e===void 0?!1:(await this.dataHandler(e),!0)}get isClosed(){return this.closed}add(e){if(this.closed)throw Error(`Buffer closed`);this.chunkSize>0?this.queue.enqueue(...a(e,this.chunkSize)):this.queue.enqueue(e),this.writer.start()}};const w={ready:`connecting`,connecting:[`connected`,`closed`],connected:[`closed`],closed:`connecting`};var de=class extends p{states;codec;rx;tx;gatt;verboseLogging=!1;rxBuffer;txBuffer;constructor(e,t){super(),this.device=e,this.config=t,this.verboseLogging=t.debug,this.txBuffer=new C(async e=>{await this.writeInternal(e)},t),this.rxBuffer=new S(e=>{this.fireEvent(`data`,{data:e})}),this.codec=new x,this.states=new b(w,{initial:`ready`}),this.states.addEventListener(`change`,e=>{this.fireEvent(`change`,e),this.verbose(`${e.priorState} -> ${e.newState}`),e.priorState===`connected`&&(this.rxBuffer.clear(),this.txBuffer.clear())}),e.addEventListener(`gattserverdisconnected`,()=>{this.isClosed||(this.verbose(`GATT server disconnected`),this.states.state=`closed`)}),this.verbose(`ctor ${e.name} ${e.id}`)}get isConnected(){return this.states.state===`connected`}get isClosed(){return this.states.state===`closed`}write(e){if(this.states.state!==`connected`)throw Error(`Cannot write while state is ${this.states.state}`);this.txBuffer.add(e)}async writeInternal(e){this.verbose(`writeInternal ${e}`);let t=this.tx;if(t===void 0)throw Error(`Unexpectedly without tx characteristic`);try{await t.writeValue(this.codec.toBuffer(e))}catch(e){this.warn(e)}}disconnect(){this.states.state===`connected`&&this.gatt?.disconnect()}async connect(){let e=this.config.connectAttempts??3;this.states.state=`connecting`,this.verbose(`connect`);let t=this.device.gatt;if(t===void 0)throw Error(`Gatt not available on device`);await g(async()=>{this.verbose(`connect.retry`);let e=await t.connect();this.verbose(`Getting primary service`);let n=await e.getPrimaryService(this.config.service);this.verbose(`Getting characteristics`);let r=await n.getCharacteristic(this.config.rxGattCharacteristic),i=await n.getCharacteristic(this.config.txGattCharacteristic);return r.addEventListener(`characteristicvaluechanged`,e=>{this.onRx(e)}),this.rx=r,this.tx=i,this.gatt=t,this.states.state=`connected`,await r.startNotifications(),!0},{limitAttempts:e,startAt:200})}onRx(e){if(this.rx===void 0)return;let n=e.target.value;if(n===void 0)return;let i=this.codec.fromBuffer(n.buffer),a=r(i,19),o=r(i,17);o&&a<o&&(this.verbose(`Tx plz start`),i=t(i,o,1),this.txBuffer.paused=!1),a&&a>o&&(this.verbose(`Tx plz stop`),i=t(i,a,1),this.txBuffer.paused=!0),this.rxBuffer.add(i)}verbose(e){this.verboseLogging&&console.info(this.config.name,e)}log(e){console.log(this.config.name,e)}warn(e){console.warn(this.config.name,e)}},T=e({NordicBleDevice:()=>D,defaultOpts:()=>E});const E={chunkSize:20,service:`6e400001-b5a3-f393-e0a9-e50e24dcca9e`,txGattCharacteristic:`6e400002-b5a3-f393-e0a9-e50e24dcca9e`,rxGattCharacteristic:`6e400003-b5a3-f393-e0a9-e50e24dcca9e`,name:`NordicDevice`,connectAttempts:5,debug:!1};var D=class extends de{constructor(e,t={}){super(e,{...E,...t})}},O=class{freqMaxRange=200;audio;parent;lastPointer={x:0,y:0};pointerDown=!1;pointerClicking=!1;pointerClickDelayMs=100;pointerDelaying=!1;waveTracker;freqTracker;el;constructor(e,t){this.audio=t,this.parent=e,this.waveTracker=h(),this.freqTracker=h(),e.innerHTML=` <section> <button id="rendererComponentToggle">🔼</button> <div> <h1>Visualiser</h1> <div style="display:flex; flex-wrap: wrap"> <div class="visPanel"> <h2>Frequency distribution</h2> <br /> <canvas id="rendererComponentFreqData" height="200" width="400"></canvas> </div> <div class="visPanel"> <h2>Waveform</h2> <button id="rendererComponentWaveReset">Reset</button> <div> Press and hold on wave to measure </div> <br /> <canvas id="rendererComponentWaveData" height="200" width="400"></canvas> </div> </div> </div> </section> `,this.el=e.children[0],document.getElementById(`rendererComponentToggle`)?.addEventListener(`click`,()=>{this.setExpanded(!this.isExpanded())}),this.el.addEventListener(`pointermove`,e=>{this.onPointer(e)}),this.el.addEventListener(`pointerup`,()=>{this.pointerDelaying=!1,this.pointerDown=!1}),this.el.addEventListener(`pointerdown`,()=>{this.pointerDelaying=!0,setTimeout(()=>{this.pointerDelaying&&(this.pointerDelaying=!1,this.pointerDown=!0)},this.pointerClickDelayMs)}),this.el.addEventListener(`pointerleave`,()=>{this.pointerDelaying=!1,this.pointerDown=!1}),document.getElementById(`rendererComponentWaveReset`)?.addEventListener(`click`,()=>{this.clear()})}renderFreq(e){if(!this.isExpanded()||!e)return;let t=document.getElementById(`rendererComponentFreqData`);if(t===null)throw Error(`Cannot find canvas element`);let n=t.getContext(`2d`);if(n===null)throw Error(`Cannot create drawing context`);let r=e.length,i=t.clientWidth,a=t.clientHeight;n.clearRect(0,0,i,a);let o=this.getPointerRelativeTo(t),s=i/r,c=re(e);for(let t=0;t<r;t++){if(!Number.isFinite(e[t]))continue;let i=(e[t]-c.min)/this.freqMaxRange,l=Math.abs(a*i),u=a-l,d=t/r*360,f=t*s;if(n.fillStyle=`hsl(${d}, 100%, 50%)`,o.y>0&&o.y<=a&&o.x>=f&&o.x<=f+s){this.freqTracker.id!==t.toString()&&(this.freqTracker=h({id:t.toString()})),this.freqTracker.seen(e[t]);let r=this.freqTracker.getMinMaxAvg();n.fillStyle=`black`,this.audio&&n.fillText(`Frequency (${t}) at pointer: ${this.audio.getFrequencyAtIndex(t).toLocaleString(`en`)} - ${this.audio.getFrequencyAtIndex(t+1).toLocaleString(`en`)}`,2,10),n.fillText(`Raw value: ${e[t].toFixed(2)}`,2,20),n.fillText(`Min: ${r.min.toFixed(2)}`,2,40),n.fillText(`Max: ${r.max.toFixed(2)}`,60,40),n.fillText(`Avg: ${r.avg.toFixed(2)}`,120,40)}n.fillRect(f,u,s,l)}}isExpanded(){let e=this.el.querySelector(`div`);if(e===null)throw Error(`contents div not found`);return e.style.display===``}setExpanded(e){let t=this.el.querySelector(`div`),n=this.el.querySelector(`button`);if(n===null)throw Error(`Button element not found`);if(t===null)throw Error(`Contents element not found`);e?(t.style.display=``,n.innerText=`🔼`):(t.style.display=`none`,n.innerText=`🔽`)}clear(){this.clearCanvas(document.getElementById(`rendererComponentFreqData`)),this.clearCanvas(document.getElementById(`rendererComponentWaveData`))}clearCanvas(e){if(e===null)throw Error(`Canvas is null`);let t=e.getContext(`2d`);if(t===null)throw Error(`Cannot create drawing context`);t.fillStyle=`white`,t.fillRect(0,0,e.clientWidth,e.clientHeight)}renderWave(e,t=!0){if(!this.isExpanded()||!e)return;let n=document.getElementById(`rendererComponentWaveData`);if(n===null)throw Error(`Cannot find wave canvas`);let r=n.getContext(`2d`);if(r===null)throw Error(`Cannot create drawing context for wave`);let i=n.clientWidth,a=n.clientHeight,o=this.getPointerRelativeTo(n),s=e.length;r.fillStyle=`white`,r.fillRect(0,0,60,20);let c=i/s;r.fillStyle=`rgba(255, 255, 255, 0.03)`,r.fillRect(0,20,i,a),r.fillStyle=`red`,t?r.fillRect(0,a/2,i,1):r.fillRect(0,a-1,i,1),r.lineWidth=1,r.strokeStyle=`black`,r.beginPath();let l=0;for(let n=0;n<s;n++){let i=e[n]*a,o=t?a/2-i:a-i;n===0?r.moveTo(l,o):r.lineTo(l,o),l+=c,this.pointerDown&&this.waveTracker.seen(e[n])}if(r.lineTo(i,t?a/2:a),r.stroke(),this.pointerDown){let e=this.waveTracker.getMinMaxAvg();r.fillStyle=`rgba(255,255,0,1)`,r.fillRect(60,0,150,20),r.fillStyle=`black`,r.fillText(`Min: `+e.min.toFixed(2),60,10),r.fillText(`Max: `+e.max.toFixed(2),110,10),r.fillText(`Avg: `+e.avg.toFixed(2),160,10)}else this.waveTracker.reset();o.y>0&&o.y<=a&&o.x>=0&&o.x<=i&&(r.fillStyle=`black`,r.fillText(`Level: `+(1-o.y/a).toFixed(2),2,10))}getPointerRelativeTo(e){let t=e.getBoundingClientRect();return{x:this.lastPointer.x-t.left-window.scrollX,y:this.lastPointer.y-t.top-window.scrollY}}onPointer(e){this.lastPointer={x:e.pageX,y:e.pageY},e.preventDefault()}};const fe=(e,t={})=>new k((t,n)=>{let r=new Float32Array(t.frequencyBinCount),i=new Float32Array(t.fftSize);t.getFloatFrequencyData(r),t.getFloatTimeDomainData(i),e(r,i,n)},t),pe=(e,t={})=>new k((t,n)=>{let r=new Float32Array(t.frequencyBinCount);t.getFloatFrequencyData(r),e(r,n)},t),me=(e,t={})=>new k((t,n)=>{let r=new Float32Array(t.fftSize);t.getFloatTimeDomainData(r),e(ee(r),n)},t);var k=class{showVis;fftSize;smoothingTimeConstant;#e=!1;debug;#t=!1;visualiser;audioCtx;analyserNode;analyse;constructor(e,t={}){if(this.showVis=t.showVis??!1,this.fftSize=t.fftSize??1024,this.debug=t.debug??!1,this.smoothingTimeConstant=t.smoothingTimeConstant??.8,s(l(this.fftSize,`positive`,`opts.fftSize`),o(this.smoothingTimeConstant,`percentage`,`opts.smoothingTimeConstant`)),!c(this.fftSize))throw Error(`fftSize must be a power of two from 32 to 32768 (${this.fftSize})`);if(this.fftSize<32)throw Error(`fftSize must be at least 32`);if(this.fftSize>32768)throw Error(`fftSize must be no greater than 32768`);this.analyse=e,this.paused=!1,this.init();let n=document.querySelector(`#audio-visualiser`);if(n){let e=new O(n,this);e.setExpanded(this.showVis),this.visualiser=e}}init(){if(this.#t){this.debug&&console.debug(`Init already in progress`);return}this.#t=!0,navigator.mediaDevices.getUserMedia({audio:!0}).then(e=>{this.onMicSuccess(e)}).catch(e=>{this.#t=!1,console.error(e)})}get paused(){return this.#e}set paused(e){e!==this.#e&&(this.#e=e,e?this.debug&&console.log(`Paused`):(this.debug&&console.log(`Unpaused`),window.requestAnimationFrame(this.analyseLoop.bind(this))))}setup(e,t){let n=e.createAnalyser();return n.fftSize=this.fftSize,n.smoothingTimeConstant=this.smoothingTimeConstant,e.createMediaStreamSource(t).connect(n),n}onMicSuccess(e){try{let t=new AudioContext;t.addEventListener(`statechange`,()=>{this.debug&&console.log(`Audio context state: ${t.state}`)}),this.audioCtx=t,this.analyserNode=this.setup(t,e),window.requestAnimationFrame(this.analyseLoop.bind(this))}catch(e){this.#t=!1,console.error(e)}}analyseLoop(){if(this.paused){this.debug&&console.log(`Paused`);return}let e=this.analyserNode;if(e===void 0){console.warn(`Analyser undefined`);return}try{this.analyse(e,this)}catch(e){console.error(e)}window.requestAnimationFrame(this.analyseLoop.bind(this))}getFrequencyRangeMax(e,t,n){return te(this.sliceByFrequency(e,t,n))}sliceByFrequency(e,t,n){let r=this.getIndexForFrequency(e),i=this.getIndexForFrequency(t);return n.slice(r,i)}getFrequencyAtIndex(e){let t=this.analyserNode,n=this.audioCtx;if(t===void 0)throw Error(`Analyser not available`);if(n===void 0)throw Error(`Audio context not available`);if(s(l(e,`positive`,`index`)),e>t.frequencyBinCount)throw Error(`Index ${e} exceeds frequency bin count ${t.frequencyBinCount}`);return e*n.sampleRate/(t.frequencyBinCount*2)}getIndexForFrequency(e){let t=this.analyserNode;if(t===void 0)throw Error(`Analyser not available`);let n=t.context.sampleRate/2,r=Math.round(e/n*t.frequencyBinCount);return r<0?0:r>=t.frequencyBinCount?t.frequencyBinCount-1:r}},he=class{#e=!1;#t=new Map;filterType=`lowpass`;constructor(){}init(){if(!this.#e){this.#e=!0;for(let e of document.querySelectorAll(`audio`))this.#t.set(e.id,A(e,this.filterType))}}get(e){return this.init(),this.#t.get(e)}};function A(e,t=`lowpass`){let n=ie(e),r=new AudioContext,i=r.createMediaElementSource(n),a=r.createStereoPanner(),o=r.createGain(),s=r.createBiquadFilter();return s.type=t,i.connect(o),o.connect(a),a.connect(s),s.connect(r.destination),{pan:a,gain:o,filter:s,id:n.id,ctx:r,el:n}}function ge(e={}){let t=new AudioContext,n=e.type??`sawtooth`,r=e.frequency??440,i=e.id??ce(),a=t.createOscillator();a.type=n,a.frequency.setValueAtTime(r,t.currentTime);let o=t.createStereoPanner(),s=t.createGain(),c=t.createBiquadFilter();return a.connect(s),s.connect(o),o.connect(c),c.connect(t.destination),{pan:o,gain:s,filter:c,ctx:t,osc:a,id:i}}var j=e({AudioAnalyser:()=>k,AudioElements:()=>he,AudioVisualiser:()=>O,analyserBasic:()=>fe,analyserFrequency:()=>pe,analyserPeakLevel:()=>me,createFromAudioElement:()=>A,createOscillator:()=>ge});const M=(e,t,n,r,i=200,a)=>{let o={channel:t,note:n,velocity:r,command:`noteon`},s={channel:t,note:n,velocity:0,command:`noteoff`};e.send(P(o),a),e.send(P(s),window.performance.now()+i)},N=e=>{let t,n=e[0],r=e[1],i=e[2],a=0;if(n>=144&&n<=159?(a=n-143,t=i===0?`noteoff`:`noteon`):n>=128&&n<=143?(a=n-127,t=`noteoff`):n>=160&&n<=175?(a=n-159,t=`poly-at`):n>=176&&n<=191?(a=n-175,t=`cc`):n>=192&&n<=207?(a=n-191,t=`progchange`):n>=208&&n<=223?(a=n-207,t=`at`):n>=224&&n<=239&&(a=n-223,t=`pitchbend`),t===void 0)throw Error(`Unknown command: '${t}'`);return{command:t,note:r,velocity:i,channel:a}},P=e=>{let t=new Uint8Array(3);switch(t[1]=e.note,t[2]=e.velocity,e.command){case`cc`:t[0]=e.channel+175;break;case`noteon`:t[0]=e.channel+143;break;case`noteoff`:t[0]=e.channel+127;break;case`pitchbend`:t[0]=e.channel+223;break;case`poly-at`:t[0]=e.channel+159;break;case`progchange`:t[0]=e.channel+191;break;case`at`:t[0]=e.channel+207;break;default:throw Error(`Command not supported '${e.command}'`)}return Array.from(t)},F=[],I=()=>{if(F.length>0)return F;let e=`0 C-1 8.176 1 C#-1 8.662 2 D-1 9.177 3 D#-1 9.723 4 E-1 10.301 5 F-1 10.913 6 F#-1 11.562 7 G-1 12.250 8 G#-1 12.978 9 A-1 13.750 10 A#-1 14.568 11 B-1 15.434 12 C0 16.352 13 C#0 17.324 14 D0 18.354 15 D#0 19.445 16 E0 20.602 17 F0 21.827 18 F#0 23.125 19 G0 24.500 20 G#0 25.957 21 A0 27.500 22 A#0 29.135 23 B0 30.868 24 C1 32.703 25 C#1 34.648 26 D1 36.708 27 D#1 38.891 28 E1 41.203 29 F1 43.654 30 F#1 46.249 31 G1 48.999 32 G#1 51.913 33 A1 55.000 34 A#1 58.270 35 B1 61.735 36 C2 65.406 37 C#2 69.296 38 D2 73.416 39 D#2 77.782 40 E2 82.407 41 F2 87.307 42 F#2 92.499 43 G2 97.999 44 G#2 103.826 45 A2 110.000 46 A#2 116.541 47 B2 123.471 48 C3 130.813 49 C#3 138.591 50 D3 146.832 51 D#3 155.563 52 E3 164.814 53 F3 174.614 54 F#3 184.997 55 G3 195.998 56 G#3 207.652 57 A3 220.000 58 A#3 233.082 59 B3 246.942 60 C4 261.626 61 C#4 277.183 62 D4 293.665 63 D#4 311.127 64 E4 329.628 65 F4 349.228 66 F#4 369.994 67 G4 391.995 68 G#4 415.305 69 A4 440.000 70 A#4 466.164 71 B4 493.883 72 C5 523.251 73 C#5 554.365 74 D5 587.330 75 D#5 622.254 76 E5 659.255 77 F5 698.456 78 F#5 739.989 79 G5 783.991 80 G#5 830.609 81 A5 880.000 82 A#5 932.328 83 B5 987.767 84 C6 1046.502 85 C#6 1108.731 86 D6 1174.659 87 D#6 1244.508 88 E6 1318.510 89 F6 1396.913 90 F#6 1479.978 91 G6 1567.982 92 G#6 1661.219 93 A6 1760.000 94 A#6 1864.655 95 B6 1975.533 96 C7 2093.005 97 C#7 2217.461 98 D7 2349.318 99 D#7 2489.016 100 E7 2637.020 101 F7 2793.826 102 F#7 2959.955 103 G7 3135.963 104 G#7 3322.438 105 A7 3520.000 106 A#7 3729.310 107 B7 3951.066 108 C8 4186.009 109 C#8 4434.922 110 D8 4698.636 111 D#8 4978.032 112 E8 5274.041 113 F8 5587.652 114 F#8 5919.911 115 G8 6271.927 116 G#8 6644.875 117 A8 7040.000 118 A#8 7458.620 119 B8 7902.133 120 C9 8372.018 121 C#9 8869.844 122 D9 9397.273 123 D#9 9956.063 124 E9 10548.080 125 F9 11175.300 126 F#9 11839.820 127 G9 12543.850`.split(` `);for(let t of e){let e=t.split(` `);if(e.length!==3){console.warn(`Expected three elements, got ${e.length}. Line:`,e);continue}F.push([Number.parseInt(e[0]),e[1].toUpperCase(),Number.parseFloat(e[2])])}return F},_e=e=>{let t=I();e=e.toUpperCase();let n=t.find(t=>t[1]===e);return n?n[0]:NaN},ve=e=>{let t=I();e=e.toUpperCase();let n=t.find(t=>t[1]===e);return n?n[2]:NaN},L=e=>{let t=I().find(t=>t[0]===e);return t?t[1]:``},R=e=>{let t=I().find(t=>t[0]===e);return t?t[2]:NaN};var ye=class extends p{verbose=!0;#e;#t;#n=[];#r=[];#i=!0;#a=!0;#o=_(()=>this.#h(),1e3);#s=_(()=>this.#g(),1e3);constructor(){super(),this.#e={initialised:!1,errorReason:``},this.#S()}*getInUse(){for(let e of this.#n)yield e}*getInUseInput(){for(let e of this.#n)e.type===`input`&&(yield e)}*getInUseOutput(){for(let e of this.#n)e.type===`output`&&(yield e)}*known(){for(let e of this.#r)yield e}*knownInput(){for(let e of this.#r)e.type===`input`&&(yield e)}*knownOutput(){for(let e of this.#r)e.type===`output`&&(yield e)}async scan(){await this.#b();let e=this.#t;e&&(e.inputs.forEach(e=>{this.#c(e)}),e.outputs.forEach(e=>{this.#c(e)}),this.#i&&this.#o(),this.#a&&this.#s())}send(e,t,n){let r=P(e);if(t===void 0)for(let e of this.#n)e.type===`output`&&e.send(r,n);else t.send(r,n)}sendNote(e,t,n,r,i,a){if(a===void 0)for(let a of this.getInUseOutput())this.sendNote(e,t,n,r,i,a);else M(a,e,t,n,r,i)}#c(e){e.state===`connected`?(this.#f(e),e.connection===`open`&&this.#u(e)):e.state===`disconnected`&&this.#p(e)}#l=e=>{let t=e.data,n=e.currentTarget;if(!t)return;let r=N(t);if(r.command===`noteoff`||r.command===`noteon`){this.fireEvent(`message`,{...r,port:n,raw:t,frequency:R(r.note),noteName:L(r.note)});return}this.fireEvent(`message`,{...r,port:n,raw:t})};#u(e){let t=this.#n.find(t=>t.id===e.id);if(this.#v(`onPortOpen: id: ${e.id} name: ${e.name} (${e.type})`),t){this.#v(`-- bug, port already in use?`);return}this.#f(e),e.type===`input`&&e.addEventListener(`midimessage`,this.#l),this.#n=[...this.#n,e],this.fireEvent(`open`,{port:e})}#d(e){this.#n.find(t=>t.id===e.id)&&(e.type===`input`&&e.removeEventListener(`midimessage`,this.#l),this.#n=this.#n.filter(t=>t.id!==e.id),this.fireEvent(`close`,{port:e}))}#f(e){this.#r.find(t=>t.id===e.id)||(this.#r=[...this.#r,e],this.fireEvent(`deviceConnected`,{port:e}))}#p(e){this.#r.find(t=>t.id===e.id)&&(this.#d(e),this.#r=this.#r.filter(t=>t.id!==e.id),this.fireEvent(`deviceDisconnected`,{port:e}))}#m(e){return this.#n.find(t=>t.id===e.id)!==void 0}async closeAll(e=`both`){for(let t of this.#n)t.type==`input`&&(e===`both`||e===`input`)&&await t.close(),t.type==`output`&&(e===`both`||e===`output`)&&await t.close()}async setOmniInput(e){this.#i=e,await this.closeAll(`input`),e&&await this.#h()}get omniInput(){return this.#i}async setOmniOutput(e){this.#a=e,await this.closeAll(`output`),e&&await this.#g()}get omniOutput(){return this.#a}async#h(){let e=this.#t;e&&e.inputs.forEach(async e=>{if(e.connection===`closed`){if(this.#m(e))throw Error(`Bug: Input closed, but inUse?`);await e.open()}})}async#g(){let e=this.#t;e&&e.outputs.forEach(async e=>{if(e.connection===`closed`){if(this.#m(e))throw Error(`Bug: Output closed, but inUse?`);await e.open()}})}dumpToStringLines(){let e=[],t=e=>` - ${e.name} (${e.type}) state: ${e.state} conn: ${e.connection} id: ${e.id}`;return e.push(`MidiManager`),e.push(`In Use:`),e.push(...d(this.#n,t,` (none)`)),e.push(`Known:`),e.push(...d(this.#r,t,` (none)`)),e}#_(e){let t=e.port;t!==null&&(t.state===`connected`?t.connection===`open`?this.#u(t):t.connection===`closed`&&(this.#d(t),this.#f(t),this.#i&&t.type===`input`?this.#o():this.#a&&t.type===`output`&&this.#s()):t.state===`disconnected`&&this.#p(t))}async open(e,t=!1){t&&(e.type===`input`?await this.closeAll(`input`):e.type===`output`&&await this.closeAll(`output`)),e.open()}#v(e){this.verbose&&console.log(`MIDI`,e)}#y(e){this.#e={...this.#e,...e},this.#v(`State change: ${JSON.stringify(this.#e)}`)}async#b(){if(!(this.#e.initialised&&this.#t!==void 0)){if((await navigator.permissions.query({name:`midi`,software:!0,sysex:!1})).state===`denied`){this.#t=void 0,this.#y({initialised:!1,errorReason:`Permission denied`});return}this.#t=await navigator.requestMIDIAccess({software:!0,sysex:!1}),this.#t.addEventListener(`statechange`,e=>{this.#_(e)}),this.#y({initialised:!0,errorReason:``})}}#x(){return!!navigator.requestMIDIAccess}#S(){if(!window.isSecureContext)throw Error(`Code is not running in a secure context. Load it via https`);if(!this.#x())throw Error(`MIDI not supported in this browser`)}findKnownPort(e){return this.#r.find(e)}*filterKnownPort(e){yield*this.#r.filter(e)}findInUsePort(e){return this.#n.find(e)}*filterInUsePort(e){yield*this.#n.filter(e)}},be=class{channel=0;cc=-1;note=-1;output;portName;constructor(e={}){this.channel=e.channel??-1,this.cc=e.cc??-1,this.note=e.note??-1,this.output=e.output,this.portName=e.portName}setOutputPort(e){return e.type===`input`||this.portName!==void 0&&e.name!==this.portName?!1:(this.output=e,!0)}sendRaw(e){if(!this.output||this.channel<0||this.cc<0&&this.note<0)return!1;let t;return this.cc>=0?(t={channel:this.channel,command:`cc`,note:this.cc,velocity:e},console.log(t),this.output.send(P(t)),!0):(console.log(`sendNote: ch: ${this.channel} note: ${this.note} vel: ${e}`),M(this.output,this.channel,this.note,e,200),!0)}},xe=class e extends p{static controlCount=0;inputChannel=1;inputCommand=`cc`;inputNote=-1;inputVelocityScale=[0,127];feedbackChannel=1;feedbackCommand=`cc`;feedbackNote=-1;feedbackVelocity=1;name=`Control-${e.controlCount++}`;lastMessage;onInputMessage(e){return this.inputChannel>=0&&e.channel!==this.inputChannel||this.inputNote>=0&&e.note!==this.inputNote||this.inputCommand!==void 0&&e.command!==this.inputCommand?!1:(this.lastMessage=e,this.fireEvent(`change`,{velocity:e.velocity,velocityScaled:this.#e(e.velocity),control:this}),!0)}#e(e){return m(e,this.inputVelocityScale[0],this.inputVelocityScale[1])}get scaledVelocity(){return this.lastMessage?this.#e(this.lastMessage.velocity):NaN}},Se=class extends p{encoders=[];#e=-1;#t=`disconnected`;#n;#r;logOutgoing=!1;bankChangeChannel=4;sideButtonChannel=4;constructor(){super();for(let e=1;e<5;e++)for(let t=1;t<17;t++){let n=new z(this,{bank:e,encoder:t});this.encoders.push(n),n.addEventListener(`encoder`,e=>{this.fireEvent(`encoder`,e)}),n.addEventListener(`switch`,e=>{this.fireEvent(`switch`,e)})}}#i=e=>{let t=e.port;t&&(t===this.#r&&(t.state===`disconnected`||t.connection===`closed`)&&this.#o(),t===this.#n&&(t.state===`disconnected`||t.connection===`closed`)&&this.#a(),this.#r!==void 0&&this.#n!==void 0?this.#s(`ready`):this.#s(`disconnected`))};#a(){let e=this.#n;e!==void 0&&(e.removeEventListener(`statechange`,this.#i),e.removeEventListener(`midimessage`,this.#c)),this.#n=void 0}#o(){let e=this.#r;e!==void 0&&e.removeEventListener(`statechange`,this.#i),this.#r=void 0}setPort(e){e.name===`Midi Fighter Twister`&&(e.type===`output`?(this.#o(),this.#r=e,this.#r!==void 0&&this.#r.addEventListener(`statechange`,this.#i)):e.type===`input`&&(this.#a(),this.#n=e,e!==void 0&&(this.#n.addEventListener(`midimessage`,this.#c),this.#n.addEventListener(`statechange`,this.#i)))),this.#r!==void 0&&this.#n!==void 0&&this.#s(`ready`)}#s(e){let t=this.#t;t!==e&&(this.#t=e,this.fireEvent(`state`,{previous:t,state:e,mf:this}))}#c=e=>{let t=e.data;if(!t)return;let n=N(t);if(n.channel===this.bankChangeChannel&&n.command===`cc`&&n.note<4){this.#l(n.note+1,!1);return}if(n.channel===this.sideButtonChannel&&n.command==`cc`){let e=-1,t,r;if(n.note===8?(e=1,t=`top`,r=`left`):n.note===10?(e=1,r=`left`,t=`bottom`):n.note===11?(e=1,r=`right`,t=`top`):n.note===13?(e=1,r=`right`,t=`bottom`):n.note===14?(e=2,r=`left`,t=`top`):n.note===16?(e=2,r=`left`,t=`bottom`):n.note===17?(e=2,r=`right`,t=`top`):n.note===19?(e=2,r=`right`,t=`bottom`):n.note===20?(e=3,t=`top`,r=`left`):n.note===22?(e=3,t=`bottom`,r=`left`):n.note===23?(e=3,t=`top`,r=`right`):n.note==25?(e=3,t=`bottom`,r=`right`):n.note==26?(e=4,t=`top`,r=`left`):n.note==28?(e=4,t=`bottom`,r=`left`):n.note==29?(e=4,t=`top`,r=`right`):n.note==31&&(e=4,t=`bottom`,r=`right`),t!==void 0&&r!==void 0){e!==this.#e&&this.#l(e,!0),this.fireEvent(`sideButton`,{bank:e,position:t,side:r,mf:this});return}}for(let e of this.encoders){if(e.inputEncoderChannel===n.channel&&e.inputEncoderNoteOrCc===n.note){e.onValueSet(n.velocity);return}if(e.inputSwitchChannel===n.channel&&e.inputSwitchNoteOrCc===n.note){e.onSwitchSet(n.velocity);return}}};#l(e,t){let n=this.#e;this.#e=e,n!==e&&this.fireEvent(`bankChange`,{prev:n,current:this.#e,mf:this,implicit:t})}set bank(e){if(e<1||e>4)throw Error(`Bank must be 1-4`);this.#r&&(M(this.#r,this.bankChangeChannel,e-1,127,100),this.#l(e,!1))}get bank(){return this.#e}*getBank(e){if(e===void 0&&(e=this.#e),e<1||e>4)throw Error(`Bank out of range, expected 1-4`);for(let t of this.encoders)t.bank===e&&(yield t)}getEncoder(e,t){if(t===void 0&&(t=this.#e),t<1||t>4)throw Error(`Bank out of range, expected 1-4. Got: ${t}`);if(e<1||e>16)throw Error(`Encoder out of range, expected 1-16`);return this.encoders.find(n=>n.bank===t&&n.encoder===e)}send(e){return this.#r?(this.logOutgoing&&console.log(`MF send: ${JSON.stringify(e)}`),this.#r.send(P(e)),!0):!1}get outputPort(){return this.#r}get inputPort(){return this.#n}get state(){return this.#t}},z=class extends p{bank;encoder;inputEncoderNoteOrCc;inputEncoderChannel;inputSwitchChannel;inputSwitchNoteOrCc;ledEffectChannel=3;ledColourChannel=2;ledRingChannel=1;encoderStaticNote=0;lastEncoderValue=-1;lastSwitchValue=-1;constructor(e,t){super(),this.mf=e;let n=t.bank,r=t.encoder;if(n<0||n>4)throw Error(`Expected bank value 1-4. Got: ${n}`);if(r<0||r>16)throw Error(`Expected encoder number 1-16. Got: ${r}`);let i=(n-1)*16;this.encoderStaticNote=r-1+i,this.inputEncoderChannel=1,this.inputEncoderNoteOrCc=this.encoderStaticNote,this.inputSwitchChannel=2,this.inputSwitchNoteOrCc=this.encoderStaticNote,this.bank=n,this.encoder=r}onValueSet(e){let t=this.lastEncoderValue;this.lastEncoderValue=e,this.fireEvent(`encoder`,{previous:t,value:e,encoder:this})}onSwitchSet(e){let t=this.lastSwitchValue;this.lastSwitchValue=e,this.fireEvent(`switch`,{previous:t,value:e,encoder:this})}setLedRing(e){this.setLedRingRaw(ne(Math.floor(e*127)))}setLedRingRaw(e){if(e<0||e>127)throw Error(`Param 'v' should be between 0-127`);let t={channel:this.ledRingChannel,command:`cc`,note:this.encoderStaticNote,velocity:e};this.mf.send(t)}setSwitchColourHue(e){if(e<0||e>1)throw Error(`Param 'v' should be in 0-1 range`);let t=1-e+.7;t>1&&--t;let n=Math.floor(t*127);this.setSwitchColourRaw(n)}setSwitchColourRaw(e){if(e<0||e>127)throw Error(`Param 'v' should be between 0-127`);let t={channel:this.ledColourChannel,command:`cc`,note:this.encoderStaticNote,velocity:e};this.mf.send(t)}setSwitchEffect(e,t=1){let n=0;if(e===`rainbow`)n=127;else if(e===`pulse`){if(t<1||t>7)throw Error(`Pulse effect expects a value 1-7`);n=9+t}else if(e===`strobe`){if(t<1||t>8)throw Error(`Strobe effect expects a value 1-8`);n=t}else if(e===`none`)n=0;else throw Error(`Unknown kind: '${e}'`);let r={channel:this.ledEffectChannel,command:`cc`,note:this.encoderStaticNote,velocity:n};this.mf.send(r)}},B=e({Control:()=>xe,Feedback:()=>be,MidiFighter:()=>Se,MidiFighterEncoder:()=>z,MidiManager:()=>ye,getParsedNotes:()=>I,noteNameToFrequency:()=>ve,noteNameToNumber:()=>_e,noteNumberToFrequency:()=>R,noteNumberToName:()=>L,pack:()=>P,sendNote:()=>M,unpack:()=>N}),V=class extends D{evalTimeoutMs;evalReplyBluetooth=!0;constructor(e,t={}){super(e,t),this.evalTimeoutMs=t.evalTimeoutMs??5*1e3}async writeScript(e){this.write(`reset(); `),this.write(`\u0010${e}\n`)}async eval(e,t={},n){let r=t.debug??!1;return q(e,t,this,`Bluetooth.println`,r,n??(e=>{this.warn(e)}))}},Ce=class extends p{states;codec;verboseLogging=!1;name;connectAttempts;chunkSize;rxBuffer;txBuffer;constructor(e={}){super(),this.verboseLogging=e.debug??!1,this.chunkSize=e.chunkSize??1024,this.connectAttempts=e.connectAttempts??3,this.name=e.name??`JsonDevice`,this.txBuffer=new C(async e=>{await this.writeInternal(e)},e),this.rxBuffer=new S(e=>{this.fireEvent(`data`,{data:e})}),this.codec=new x,this.states=new b(w,{initial:`ready`}),this.states.addEventListener(`change`,e=>{this.fireEvent(`change`,e),this.verbose(`${e.priorState} -> ${e.newState}`),e.priorState===`connected`&&(this.rxBuffer.clear(),this.txBuffer.clear())})}get isConnected(){return this.states.state===`connected`}get isClosed(){return this.states.state===`closed`}write(e){if(this.states.state!==`connected`)throw Error(`Cannot write while state is ${this.states.state}`);this.txBuffer.add(e)}async close(){this.states.state===`connected`&&this.onClosed()}async connect(){let e=this.connectAttempts;this.states.state=`connecting`,await this.onPreConnect(),await g(async()=>(await this.onConnectAttempt(),this.states.state=`connected`,!0),{limitAttempts:e,startAt:200})}onRx(e){let n=e.target.value;if(n===void 0)return;let i=this.codec.fromBuffer(n.buffer),a=r(i,19),o=r(i,17);o&&a<o&&(this.verbose(`Tx plz start`),i=t(i,o,1),this.txBuffer.paused=!1),a&&a>o&&(this.verbose(`Tx plz stop`),i=t(i,a,1),this.txBuffer.paused=!0),this.rxBuffer.add(i)}verbose(e){this.verboseLogging&&console.info(this.name,e)}log(e){console.log(this.name,e)}warn(e){console.warn(this.name,e)}},H=e({Device:()=>U}),U=class extends Ce{port;tx;abort;baudRate;constructor(e={}){super(e),this.config=e,this.abort=new AbortController;let t=e.eol??`\r `;this.baudRate=e.baudRate??9600,e.name===void 0&&(this.name=`Serial.Device`),this.rxBuffer.separator=t}async writeInternal(e){if(this.tx===void 0)throw Error(`this.tx not ready`);try{await this.tx.write(e)}catch(e){this.warn(e)}}onClosed(){this.tx?.releaseLock(),this.abort.abort(`closing port`),this.states.state=`closed`}onPreConnect(){return Promise.resolve()}async onConnectAttempt(){let e={filters:[]},t={baudRate:this.baudRate};this.config.filters&&(e={filters:[...this.config.filters]}),this.port=await navigator.serial.requestPort(e),this.port.addEventListener(`disconnect`,e=>{this.close()}),await this.port.open(t);let n=this.port.writable,r=new TextEncoderStream;n!==null&&(r.readable.pipeTo(n,{signal:this.abort.signal}).catch(e=>{console.log(`Serial.onConnectAttempt txText pipe:`),console.log(e)}),this.tx=r.writable.getWriter());let i=this.port.readable,a=new TextDecoderStream;i!==null&&(i.pipeTo(a.writable,{signal:this.abort.signal}).catch(e=>{console.log(`Serial.onConnectAttempt rxR pipe:`),console.log(e)}),a.readable.pipeTo(this.rxBuffer.writable(),{signal:this.abort.signal}).catch(e=>{console.log(`Serial.onConnectAttempt rxText pipe:`),console.log(e);try{this.port?.close()}catch(e){console.log(e)}}))}},W=class extends U{evalTimeoutMs;evalReplyBluetooth=!1;constructor(e){super(e),e===void 0&&(e={}),this.evalTimeoutMs=e.evalTimeoutMs??5*1e3}async disconnect(){return super.close()}writeScript(e){this.write(`reset(); `),this.write(`\u0010${e}\n`)}async eval(e,t={},n){let r=t.debug??!1;return q(e,t,this,`USB.println`,r,n??(e=>{this.warn(e)}))}},G=e({EspruinoBleDevice:()=>V,EspruinoSerialDevice:()=>W,bangle:()=>Te,connectBle:()=>De,deviceEval:()=>q,puck:()=>we,serial:()=>Ee});const we=async(e={})=>{let t=e.name??`Puck`,n=e.debug??!1,r=await navigator.bluetooth.requestDevice({filters:K(e,`Puck.js`),optionalServices:[E.service]});e.debug&&console.info(`Espruino.puck device name: ${r.name}`);let i=new V(r,{name:t,debug:n});return await i.connect(),i},Te=async(e={})=>{let t=e.name??`Bangle`,n=e.debug??!1,r=await navigator.bluetooth.requestDevice({filters:K(e,`Bangle.js`),optionalServices:[E.service]});e.debug&&console.info(`Espruino.bangle device name: ${r.name}`);let i=new V(r,{name:t,debug:n});return await i.connect(),i},Ee=async(e={})=>{let t=new W(e);return await t.connect(),t},K=(e,t)=>{let n=[];return e.filters?n.push(...e.filters):e.name?(n.push({name:e.name}),console.info(`Filtering Bluetooth devices by name '${e.name}'`)):n.push({namePrefix:t}),n},De=async(e={})=>{let t=new V(await navigator.bluetooth.requestDevice({filters:K(e,`Puck.js`),optionalServices:[E.service]}),{name:`Espruino`,...e});return await t.connect(),t},q=async(e,t={},n,r,i,a)=>{let o=t.timeoutMs??n.evalTimeoutMs,s=t.assumeExclusive??!0;if(typeof e!=`string`)throw TypeError(`Param 'code' should be a string. Got: ${typeof e}`);return new Promise((t,c)=>{let l=le(5),d=e=>{try{let n=e.data.trim();n.startsWith(`>{`)&&n.endsWith(`}`)&&(n=n.slice(1));let r=JSON.parse(n);`reply`in r?r.reply===l?(p(),`result`in r&&t(r.result)):a(`Expected reply ${l}, got ${r.reply}`):a(`Expected packet, missing 'reply' field. Got: ${e.data}`)}catch(t){s?p(`Unexpected reply: ${e.data}. Error: ${u(t)}`):a(u(t))}},f=e=>{e.newState!==`connected`&&p(`State changed to '${e.newState}', aborting`)};n.addEventListener(`data`,d),n.addEventListener(`change`,f);let p=y(o,e=>{c(Error(e))},e=>{n.removeEventListener(`data`,d),n.removeEventListener(`change`,f)}),m=`\u0010${r}(JSON.stringify({reply:"${l}", result:JSON.stringify(${e})}))\n`;i&&a(m),n.write(m)})};var J=e({dumpDevices:()=>Oe,start:()=>Y});const Oe=async(e=`videoinput`)=>{let t=await navigator.mediaDevices.enumerateDevices();for(let n of t)n.kind===e&&(console.log(n.label),console.log(` Kind: ${n.kind}`),console.log(` Device id: ${n.deviceId}`))},Y=async(e={})=>{let t=document.createElement(`VIDEO`);t.style.display=`none`,t.playsInline=!0,t.muted=!0,t.classList.add(`ixfx-camera`),document.body.append(t);let n=()=>{},r=()=>{try{n()}catch{}t.remove()};try{return n=(await ke(t,e)).dispose,{videoEl:t,dispose:r}}catch(e){throw console.error(e),r(),e}},ke=async(e,t={})=>{if(e===void 0)throw Error(`videoEl undefined`);if(e===null)throw Error(`videoEl null`);let n=t.max,r=t.min,i=t.ideal,a={audio:!1,video:{width:{},height:{}}};t.facingMode===`front`&&(t={...t,facingMode:`user`}),t.facingMode===`back`&&(t={...t,facingMode:`environment`}),t.facingMode&&(a.video.facingMode=t.facingMode),t.deviceId&&(a.video.deviceId=t.deviceId),i&&(a.video.width={...a.video.width,ideal:i.width},a.video.height={...a.video.height,ideal:i.height}),n&&(a.video.width={...a.video.width,max:n.width},a.video.height={...a.video.height,max:n.height}),r&&(a.video.width={...a.video.width,min:r.width},a.video.height={...a.video.height,min:r.height});let o=y(t.startTimeoutMs??1e4,e=>{throw Error(`Camera getUserMedia failed: ${e}`)});try{let t=await navigator.mediaDevices.getUserMedia(a),n=()=>{e.pause();let n=t.getTracks();for(let e of n)e.stop()};e.srcObject=t,o();let r={videoEl:e,dispose:n};return new Promise((t,n)=>{e.addEventListener(`loadedmetadata`,()=>{e.play().then(()=>{t(r)}).catch(e=>{n(e)})})})}catch(e){throw o(u(e)),e}};var X=e({start:()=>Z});const Z=async e=>{let t=document.createElement(`VIDEO`);t.style.display=`none`,t.playsInline=!0,t.muted=!0,t.classList.add(`ixfx-video`),document.body.appendChild(t);let n=()=>{},r=()=>{try{n()}catch{}t.remove()};try{return n=(await Ae(t,e)).dispose,{videoEl:t,dispose:r}}catch(e){throw console.error(e),r(),e}},Ae=async(e,t)=>{if(e===void 0)throw Error(`videoEl undefined`);if(e===null)throw Error(`videoEl null`);e.src=URL.createObjectURL(t),e.loop=!0;let n={videoEl:e,dispose:()=>{e.pause()}};return new Promise((t,r)=>{e.addEventListener(`loadedmetadata`,()=>{e.play().then(()=>{t(n)}).catch(e=>{r(e)})})})};var Q=class{_source;_state;_teardownNeeded=!1;_cameraConstraints;_cameraStartResult;_videoSourceCapture;_videoFile;_videoStartResult;_showCanvas;_showPreview;_postCaptureDraw;_timer;_captureCanvasEl;constructor(e={}){this._state=`ready`,this._source=``,this._timer=performance.now(),this._showCanvas=e.showCanvas??!1,this._showPreview=e.showPreview??!1,this._cameraConstraints=e.cameraConstraints??void 0,this._captureCanvasEl=e.captureCanvasEl??void 0,this._postCaptureDraw=e.postCaptureDraw}showPreview(e){if(this._state===`disposed`)throw Error(`Disposed`);let t;switch(this._source){case`camera`:t=this._cameraStartResult?.videoEl,t!==void 0&&(t.style.display=e?`block`:`none`);break}this._showPreview=e}showCanvas(e){if(this._state===`disposed`)throw Error(`Disposed`);let t;if(this._source===`camera`||this._source===`video`)t=this._videoSourceCapture?.canvasEl,t!==void 0&&(t.style.display=e?`block`:`none`);else throw Error(`Source not implemented: ${this._source}`);this._showCanvas=e}getCapturer(){if(this._state===`disposed`)throw Error(`Disposed`);if(this._source===`camera`||this._source===`video`)return this._videoSourceCapture;throw Error(`Source kind not supported ${this._source}`)}async useCamera(e){if(this._state===`disposed`)throw Error(`Disposed`);this._source=`camera`,this._teardownNeeded&&this.teardown(),e&&(this._cameraConstraints=e),await this.init()}async useVideo(e){if(this._state===`disposed`)throw Error(`Disposed`);this._source=`video`,this._teardownNeeded&&this.teardown(),this._videoFile=e,await this.init()}async initCamera(){let e=await Y(this._cameraConstraints);if(e===void 0)throw Error(`Could not start camera`);this._cameraStartResult=e,this.postInit(e)}async initVideo(){if(!this._videoFile)throw Error(`Video file not defined`);let e=await Z(this._videoFile);this._videoStartResult=e,this.postInit(e)}async postInit(e){return this._showPreview&&(e.videoEl.style.display=`block`),this._videoSourceCapture=ue(e.videoEl,{postCaptureDraw:this._postCaptureDraw,showCanvas:this._showCanvas,canvasEl:this._captureCanvasEl}),this._teardownNeeded=!0,this._cameraStartResult=e,Promise.resolve()}dispose(){this._state!==`disposed`&&(this.teardown(),this._state=`disposed`)}async init(){switch(this._timer=performance.now(),this._source){case`camera`:await this.initCamera();break;case`video`:await this.initVideo();break}this._state=`initialised`}teardown(){if(this._teardownNeeded){switch((this._source===`camera`||this._source===`video`)&&this._videoSourceCapture?.dispose(),this._source){case`camera`:this._cameraStartResult?.dispose();break;case`video`:this._videoStartResult?.dispose();break}this._teardownNeeded=!1}}getFrame(){if(this._state===`disposed`)throw Error(`Disposed`);switch(this._source){case`camera`:return this.getFrameCamera();case`video`:return this.getFrameCamera();default:throw Error(`source type unhandled ${this._source}`)}}getTimestamp(){return performance.now()-this._timer}getFrameCamera(){return this._videoSourceCapture?.capture()}};const $=(e,t={})=>{let n=i(t.startDelay,2e3),r=i(t.maxDelay,n*10),a=i(t.checkStateMs,5e3);if(n>r)throw Error(`startDelay should be less than maxDelay`);if(a<0)throw Error(`Param 'checkState' should be above zero`);let o=!0,s=se({closed:`connecting`,open:`closed`,connecting:[`closed`,`open`]}),c,l=e=>{t.onError?t.onError(e):(console.log(`rw on error`,e),console.error(` error: ${e.error}`),console.error(` type: ${e.type}`),console.error(` error msg: ${e.message}`))},d=e=>{t.onMessage&&t.onMessage(e.data)},f=async()=>{if(s.value===`connecting`)throw Error(`Cannot connect twice`);s=v(s,`connecting`),c!==void 0&&(c.removeEventListener(`error`,l),t.onMessage&&c.removeEventListener(`message`,d),c=void 0);let r=await ae({async probe(t){try{let t=new WebSocket(e);return(await oe(t,[`open`,`error`],{timeoutMs:1e3})).type===`open`?{success:!0,value:t}:{success:!1,error:`Could not open`}}catch(e){return{success:!1,error:u(e)}}}},{predelayMs:n,limitAttempts:t.limitAttempts});c=r.value;let i=!1;return r.success&&c?(t.onMessage,i=!0,s=v(s,`open`),t.onConnected&&t.onConnected()):s=v(s,`closed`),i},p=e=>{if(c)c.readyState===c.OPEN?c.send(e):m();else throw Error(`Not connected`)},m=()=>{s.value!==`closed`&&(s.value===`open`&&(s=v(s,`closed`),t.onDisconnected&&t.onDisconnected()),o&&s.value!==`connecting`&&(console.log(`Scheduling connect`),setTimeout(()=>{f()},100)))};return f(),setInterval(()=>{if(c)switch(c.readyState){case c.CLOSED:s.value===`open`&&m();break}},a),{send:p,isConnected:()=>c?c.readyState===c.OPEN:!1,close:()=>{o=!1,s=v(s,`closed`),c?.close(),t.onDisconnected&&t.onDisconnected()},open:()=>(o=!0,s.value===`open`?Promise.resolve(!0):s.value===`connecting`?Promise.resolve(!1):f())}};var je=e({Audio:()=>j,Bluetooth:()=>T,Camera:()=>J,Codec:()=>x,Espruino:()=>G,FrameProcessor:()=>Q,Midi:()=>B,Serial:()=>H,StringReceiveBuffer:()=>S,StringWriteBuffer:()=>C,VideoFile:()=>X,genericStateTransitionsInstance:()=>w,reconnectingWebsocket:()=>$});export{J as a,B as c,w as d,C as f,X as i,j as l,x as m,$ as n,G as o,S as p,Q as r,H as s,je as t,T as u};