From 660c9a437a6f705655a5241a5a6ff22ca24eea26 Mon Sep 17 00:00:00 2001 From: Stefano Brilli Date: Wed, 20 Jan 2021 14:43:42 +0100 Subject: [PATCH] Updates --- asset-manifest.json | 8 ++++---- final-service-worker.js | 2 +- index.html | 2 +- ... precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js | 8 ++++---- service-worker.js | 2 +- static/js/main.8336c8e1.chunk.js | 2 -- static/js/main.8336c8e1.chunk.js.map | 1 - static/js/main.ec094e9a.chunk.js | 2 ++ static/js/main.ec094e9a.chunk.js.map | 1 + 9 files changed, 14 insertions(+), 14 deletions(-) rename precache-manifest.54524a83821e19b41c07f0e0784c478d.js => precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js (92%) delete mode 100644 static/js/main.8336c8e1.chunk.js delete mode 100644 static/js/main.8336c8e1.chunk.js.map create mode 100644 static/js/main.ec094e9a.chunk.js create mode 100644 static/js/main.ec094e9a.chunk.js.map diff --git a/asset-manifest.json b/asset-manifest.json index 3903d69..2c3a47a 100644 --- a/asset-manifest.json +++ b/asset-manifest.json @@ -1,8 +1,8 @@ { "files": { "main.css": "/webminidisc/static/css/main.6d9c03e4.chunk.css", - "main.js": "/webminidisc/static/js/main.8336c8e1.chunk.js", - "main.js.map": "/webminidisc/static/js/main.8336c8e1.chunk.js.map", + "main.js": "/webminidisc/static/js/main.ec094e9a.chunk.js", + "main.js.map": "/webminidisc/static/js/main.ec094e9a.chunk.js.map", "runtime-main.js": "/webminidisc/static/js/runtime-main.114d47b9.js", "runtime-main.js.map": "/webminidisc/static/js/runtime-main.114d47b9.js.map", "static/js/2.254aeff7.chunk.js": "/webminidisc/static/js/2.254aeff7.chunk.js", @@ -14,7 +14,7 @@ "ffb88193b05ec63929fd.worker.js.LICENSE.txt": "/webminidisc/ffb88193b05ec63929fd.worker.js.LICENSE.txt", "ffb88193b05ec63929fd.worker.js.map": "/webminidisc/ffb88193b05ec63929fd.worker.js.map", "index.html": "/webminidisc/index.html", - "precache-manifest.54524a83821e19b41c07f0e0784c478d.js": "/webminidisc/precache-manifest.54524a83821e19b41c07f0e0784c478d.js", + "precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js": "/webminidisc/precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js", "service-worker.js": "/webminidisc/service-worker.js", "static/css/main.6d9c03e4.chunk.css.map": "/webminidisc/static/css/main.6d9c03e4.chunk.css.map", "static/js/2.254aeff7.chunk.js.LICENSE.txt": "/webminidisc/static/js/2.254aeff7.chunk.js.LICENSE.txt", @@ -29,6 +29,6 @@ "static/js/runtime-main.114d47b9.js", "static/js/2.254aeff7.chunk.js", "static/css/main.6d9c03e4.chunk.css", - "static/js/main.8336c8e1.chunk.js" + "static/js/main.ec094e9a.chunk.js" ] } \ No newline at end of file diff --git a/final-service-worker.js b/final-service-worker.js index 2bae82a..a555994 100644 --- a/final-service-worker.js +++ b/final-service-worker.js @@ -35,7 +35,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "/webminidisc/precache-manifest.54524a83821e19b41c07f0e0784c478d.js" + "/webminidisc/precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js" ); self.addEventListener('message', (event) => { diff --git a/index.html b/index.html index bb1fcac..45db1d0 100644 --- a/index.html +++ b/index.html @@ -1 +1 @@ -Web MiniDisc - Brings NetMD Devices to the Web
\ No newline at end of file +Web MiniDisc - Brings NetMD Devices to the Web
\ No newline at end of file diff --git a/precache-manifest.54524a83821e19b41c07f0e0784c478d.js b/precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js similarity index 92% rename from precache-manifest.54524a83821e19b41c07f0e0784c478d.js rename to precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js index 4082bd1..5eb3d04 100644 --- a/precache-manifest.54524a83821e19b41c07f0e0784c478d.js +++ b/precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js @@ -16,11 +16,11 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/webminidisc/ffb88193b05ec63929fd.worker.js.LICENSE.txt" }, { - "revision": "de737097eae6dfb927e40e2f52c85aa3", + "revision": "e2b1654aa1e31f3557ec9399092d7c42", "url": "/webminidisc/index.html" }, { - "revision": "60734728ceb454f16907", + "revision": "acc4beb0bb446ad3ea13", "url": "/webminidisc/static/css/main.6d9c03e4.chunk.css" }, { @@ -32,8 +32,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "/webminidisc/static/js/2.254aeff7.chunk.js.LICENSE.txt" }, { - "revision": "60734728ceb454f16907", - "url": "/webminidisc/static/js/main.8336c8e1.chunk.js" + "revision": "acc4beb0bb446ad3ea13", + "url": "/webminidisc/static/js/main.ec094e9a.chunk.js" }, { "revision": "b873df5f5158f06b4f7b", diff --git a/service-worker.js b/service-worker.js index dac2db8..ab191d4 100644 --- a/service-worker.js +++ b/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "/webminidisc/precache-manifest.54524a83821e19b41c07f0e0784c478d.js" + "/webminidisc/precache-manifest.d7e81b850f98fbdf289fa23256d1903b.js" ); self.addEventListener('message', (event) => { diff --git a/static/js/main.8336c8e1.chunk.js b/static/js/main.8336c8e1.chunk.js deleted file mode 100644 index aa5b5b5..0000000 --- a/static/js/main.8336c8e1.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(this.webpackJsonpwebmd=this.webpackJsonpwebmd||[]).push([[0],{277:function(e,t,a){e.exports=a.p+"static/media/chrome-icon.f3b6c54c.svg"},303:function(e,t,a){e.exports=a(544)},327:function(e,t){},329:function(e,t){},361:function(e,t){},362:function(e,t){},495:function(e,t){},497:function(e,t){},527:function(e,t,a){},528:function(e,t,a){},543:function(e,t,a){e.exports=function(){return new Worker(a.p+"ffb88193b05ec63929fd.worker.js")}},544:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),l=a(16),i=a.n(l),o=a(18);const c=Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));function s(e,t){navigator.serviceWorker.register(e).then(e=>{e.onupdatefound=()=>{const a=e.installing;null!=a&&(a.onstatechange=()=>{console.log("state change",a.state),"installed"===a.state&&(navigator.serviceWorker.controller?(console.log("New content is available and will be used when all tabs for this page are closed. See https://bit.ly/CRA-PWA."),t&&t.onUpdate&&t.onUpdate(e)):(console.log("Content is cached for offline use."),t&&t.onSuccess&&t.onSuccess(e)))})},e.update()}).catch(e=>{console.error("Error during service worker registration:",e)})}var d=a(31),m=a(21),u=a(264);function p(e){return new Promise(t=>{setTimeout(t,e)})}async function g(e,t){let a=1,n=setInterval(()=>{a++,t(Math.min(100,1e3*a/e*100))},1e3);await p(e),window.clearInterval(n)}function b(e){return Object(o.d)(e,o.b)}function f(e){return`/webminidisc/${e}`}function h(e,t){localStorage.setItem(e,JSON.stringify(t))}function v(e,t){let a=localStorage.getItem(e);if(null===a)return t;try{return JSON.parse(a)}catch(n){return t}}function y(e){return e.normalize("NFD").replace(/[^\x00-\x7F]/g,"")}const E={[m.Encoding.sp]:"SP",[m.Encoding.lp2]:"LP2",[m.Encoding.lp4]:"LP4"};function w(e){let t=[];if(null!==e)for(let r of e.groups)for(let e of r.tracks){var a,n;t.push({index:e.index,title:null!==(a=e.title)&&void 0!==a?a:"Unknown Title",group:null!==(n=r.title)&&void 0!==n?n:"",encoding:E[e.encoding],duration:Object(m.formatTimeFromFrames)(e.duration,!1)})}return t.sort((e,t)=>e.index-t.index),t}function k(e,t,a){const n=a.value;return a.value=async function(...e){const t=this.mutex,a=await t.acquire();try{return await n.apply(this,e)}finally{a()}},a}function C(e){return e.breakpoints.up(600+2*e.spacing(2))}function O(e){return e.breakpoints.down(600+2*e.spacing(2))}function j(e){return e.breakpoints.up(700+2*e.spacing(2))+" and (min-height: 750px)"}var S,D=a(289);const x=a(428);let M=(S=class{constructor({debug:e=!1}){if(this.netmdInterface=void 0,this.logger=void 0,this.mutex=new D.a,this.statusMonitorTimer=void 0,e){const e=(...e)=>{e&&e[0]&&e[0].method&&console.log(...e)};this.logger={debug:e,info:e,warn:e,error:e,child:()=>this.logger}}}async pair(){let e=await Object(m.openNewDevice)(navigator.usb,this.logger);return null!==e&&(this.netmdInterface=e,!0)}async connect(){let e=await Object(m.openPairedDevice)(navigator.usb,this.logger);return null!==e&&(this.netmdInterface=e,!0)}async listContent(){return await Object(m.listContent)(this.netmdInterface)}async getDeviceStatus(){return await Object(m.getDeviceStatus)(this.netmdInterface)}async getDeviceName(){return await this.netmdInterface.netMd.getDeviceName()}async finalize(){await this.netmdInterface.netMd.finalize()}async renameTrack(e,t){t=y(t),await this.netmdInterface.cacheTOC(),await this.netmdInterface.setTrackTitle(e,t),await this.netmdInterface.syncTOC()}async renameDisc(e){const t=await this.netmdInterface.getDiscTitle(),a=await this.netmdInterface._getDiscTitle(),n=a.indexOf("//")>=0,r=a.startsWith("0;");if(e===t)return;let l;l=n?r?a.replace(/^0;.*?\/\//,""!==e?`0;${e}//`:""):`0;${e}//${a}`:e,await this.netmdInterface.cacheTOC(),await this.netmdInterface.setDiscTitle(l),await this.netmdInterface.syncTOC()}async deleteTrack(e){await this.netmdInterface.eraseTrack(e),await p(100)}async wipeDisc(){await this.netmdInterface.eraseDisc()}async moveTrack(e,t){await this.netmdInterface.moveTrack(e,t)}async upload(e,t,a,n){let r=t.byteLength,l=0,i=0;function o(){n({written:l,encrypted:i,total:r})}let c=new x,s=Object(u.makeGetAsyncPacketIteratorOnWorkerThread)(c,({encryptedBytes:e})=>{i=e,o()});e=y(e);let d=new m.MDTrack(e,a,t,524288,s);await Object(m.download)(this.netmdInterface,d,({writtenBytes:e})=>{l=e,o()}),c.terminate()}async play(){await this.netmdInterface.play()}async pause(){await this.netmdInterface.pause()}async stop(){await this.netmdInterface.stop()}async next(){await this.netmdInterface.nextTrack()}async prev(){await this.netmdInterface.previousTrack()}async gotoTrack(e){await this.netmdInterface.gotoTrack(e)}async getPosition(){return await this.netmdInterface.getPosition()}},Object(d.a)(S.prototype,"listContent",[k],Object.getOwnPropertyDescriptor(S.prototype,"listContent"),S.prototype),Object(d.a)(S.prototype,"getDeviceStatus",[k],Object.getOwnPropertyDescriptor(S.prototype,"getDeviceStatus"),S.prototype),Object(d.a)(S.prototype,"getDeviceName",[k],Object.getOwnPropertyDescriptor(S.prototype,"getDeviceName"),S.prototype),Object(d.a)(S.prototype,"finalize",[k],Object.getOwnPropertyDescriptor(S.prototype,"finalize"),S.prototype),Object(d.a)(S.prototype,"renameTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"renameTrack"),S.prototype),Object(d.a)(S.prototype,"renameDisc",[k],Object.getOwnPropertyDescriptor(S.prototype,"renameDisc"),S.prototype),Object(d.a)(S.prototype,"deleteTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"deleteTrack"),S.prototype),Object(d.a)(S.prototype,"wipeDisc",[k],Object.getOwnPropertyDescriptor(S.prototype,"wipeDisc"),S.prototype),Object(d.a)(S.prototype,"moveTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"moveTrack"),S.prototype),Object(d.a)(S.prototype,"play",[k],Object.getOwnPropertyDescriptor(S.prototype,"play"),S.prototype),Object(d.a)(S.prototype,"pause",[k],Object.getOwnPropertyDescriptor(S.prototype,"pause"),S.prototype),Object(d.a)(S.prototype,"stop",[k],Object.getOwnPropertyDescriptor(S.prototype,"stop"),S.prototype),Object(d.a)(S.prototype,"next",[k],Object.getOwnPropertyDescriptor(S.prototype,"next"),S.prototype),Object(d.a)(S.prototype,"prev",[k],Object.getOwnPropertyDescriptor(S.prototype,"prev"),S.prototype),Object(d.a)(S.prototype,"gotoTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"gotoTrack"),S.prototype),Object(d.a)(S.prototype,"getPosition",[k],Object.getOwnPropertyDescriptor(S.prototype,"getPosition"),S.prototype),S);var T={},N=a(46),P=a(23),I=a(17);const z=Object(P.b)({name:"uploadDialog",initialState:{visible:!1,cancelled:!1,writtenProgress:0,encryptedProgress:0,totalProgress:1,trackTotal:1,trackConverting:0,trackCurrent:0,titleCurrent:"",titleConverting:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setWriteProgress:(e,t)=>{e.encryptedProgress=t.payload.encrypted,e.writtenProgress=t.payload.written,e.totalProgress=t.payload.total},setCancelUpload:(e,t)=>{e.cancelled=t.payload},setTrackProgress:(e,t)=>{e.trackTotal=t.payload.total,e.trackCurrent=t.payload.current,e.trackConverting=t.payload.converting,e.titleCurrent=t.payload.titleCurrent,e.titleConverting=t.payload.titleConverting}}}),{reducer:R,actions:F}=z;var W=Object(I.enableBatching)(R);const L=Object(P.b)({name:"renameDialog",initialState:{visible:!1,title:"",index:-1},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setCurrentName:(e,t)=>{e.title=t.payload},setIndex:(e,t)=>{e.index=t.payload}}}),{reducer:A,actions:B}=L;var $=Object(I.enableBatching)(A);const V={visible:!1,error:""},U=Object(P.b)({name:"errorDialog",initialState:V,reducers:{setVisible:(e,t)=>{e.visible=t.payload},setErrorMessage:(e,t)=>{e.error=`${t.payload}`}}}),{actions:_,reducer:G}=U;var H=Object(I.enableBatching)(G);const J=Object(P.b)({name:"panicDialog",initialState:{visible:!1,dismissed:!1},reducers:{setVisible:(e,t)=>{e.visible=t.payload},dismiss:(e,t)=>{e.visible=!1,e.dismissed=!0}}}),{actions:Y,reducer:q}=J;var K=Object(I.enableBatching)(q);const X={visible:!1,format:"LP2",titleSource:v("trackTitleSource","file"),titleFormat:v("trackTitleFormat","title")},Q=Object(P.b)({name:"convertDialog",initialState:X,reducers:{setVisible:(e,t)=>{e.visible=t.payload},setFormat:(e,t)=>{e.format=t.payload},setTitleSource:(e,t)=>{e.titleSource=t.payload,h("trackTitleSource",e.titleSource)},setTitleFormat:(e,t)=>{e.titleFormat=t.payload,h("trackTitleFormat",e.titleFormat)}}}),{actions:Z,reducer:ee}=Q;var te=Object(I.enableBatching)(ee);const ae=Object(P.b)({name:"dumpDialog",initialState:{visible:!1,inputDeviceId:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setInputDeviceId:(e,t)=>{e.inputDeviceId=t.payload}}}),{reducer:ne,actions:re}=ae;var le=Object(I.enableBatching)(ne);const ie=Object(P.b)({name:"recordDialog",initialState:{visible:!1,trackTotal:1,trackDone:0,trackCurrent:0,titleCurrent:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setProgress:(e,t)=>{e.trackTotal=t.payload.trackTotal,e.trackDone=t.payload.trackDone,e.trackCurrent=t.payload.trackCurrent,e.titleCurrent=t.payload.titleCurrent}}}),{reducer:oe,actions:ce}=ie;var se=Object(I.enableBatching)(oe);const de={mainView:"WELCOME",loading:!1,pairingFailed:!1,pairingMessage:"",browserSupported:!0,darkMode:v("darkMode",!1),aboutDialogVisible:!1},me=Object(P.b)({name:"app",initialState:de,reducers:{setState:(e,t)=>{e.mainView=t.payload},setLoading:(e,t)=>{e.loading=t.payload},setPairingFailed:(e,t)=>{e.pairingFailed=t.payload},setPairingMessage:(e,t)=>{e.pairingMessage=t.payload},setBrowserSupported:(e,t)=>{e.browserSupported=t.payload},setDarkMode:(e,t)=>{e.darkMode=t.payload,h("darkMode",e.darkMode)},showAboutDialog:(e,t)=>{e.aboutDialogVisible=t.payload}}}),{reducer:ue,actions:pe}=me;var ge=Object(I.enableBatching)(ue);const be=Object(P.b)({name:"main",initialState:{disc:null,deviceName:"",deviceStatus:null},reducers:{setDisc:(e,t)=>{e.disc=t.payload},setDeviceName:(e,t)=>{e.deviceName=t.payload},setDeviceStatus:(e,t)=>{e.deviceStatus=t.payload}}}),{reducer:fe,actions:he}=be;var ve=Object(I.enableBatching)(fe);let ye=Object(N.c)({renameDialog:$,uploadDialog:W,errorDialog:H,panicDialog:K,convertDialog:te,dumpDialog:le,recordDialog:se,appState:ge,main:ve});const Ee=pe.setState.toString(),we=Object(P.a)({reducer:function(...e){const[t,a]=e;return a.type===Ee&&"WELCOME"===a.payload?ke:ye(...e)},middleware:[e=>e=>async t=>{try{await e(t)}catch(a){console.error(a),e(Y.setVisible(!0))}},...Object(P.c)()]}),ke=Object.freeze(we.getState());var Ce=a(609),Oe=a(549),je=a(610),Se=a(589),De=a(287),xe=a(601),Me=a(265);function Te(e,t){return async function(a,n){switch(e){case"play":await T.netmdService.play();break;case"stop":await T.netmdService.stop();break;case"next":await T.netmdService.next();break;case"prev":await T.netmdService.prev();break;case"goto":t&&"number"===typeof t&&t>=0&&await T.netmdService.gotoTrack(t)}await p(500);try{let e=await T.netmdService.getDeviceStatus();a(he.setDeviceStatus(e))}catch(r){console.log("control: Cannot get device status")}}}function Ne(){return async function(e){e(pe.setLoading(!0));let t=await T.netmdService.listContent(),a=await T.netmdService.getDeviceName(),n=null;try{n=await T.netmdService.getDeviceStatus()}catch(r){console.log("listContent: Cannot get device status")}e(Object(I.batchActions)([he.setDisc(t),he.setDeviceName(a),he.setDeviceStatus(n),pe.setLoading(!1)]))}}const Pe={SP:m.Wireformat.pcm,LP2:m.Wireformat.lp2,LP105:m.Wireformat.l105kbps,LP4:m.Wireformat.lp4};async function Ie(e,t){var a,n,r;const l=await e.arrayBuffer(),i=new Blob([new Uint8Array(l)]);let o=await Me.parseBlob(i);const c=null!==(a=o.common.title)&&void 0!==a?a:"Unknown Title",s=null!==(n=o.common.artist)&&void 0!==n?n:"Unknown Artist",d=null!==(r=o.common.album)&&void 0!==r?r:"Unknown Album";switch(t){case"title":return c;case"artist-title":return`${s} - ${c}`;case"album-title":return`${d} - ${c}`;case"artist-album-title":return`${s} - ${d} - ${c}`}}function ze(e,t,a,n){return async function(r,l){const{audioExportService:i,netmdService:o}=T,c=Pe[t];await(null===o||void 0===o?void 0:o.stop()),r(Object(I.batchActions)([F.setVisible(!0),F.setCancelUpload(!1)]));const s=({written:e,encrypted:t,total:a})=>{r(F.setWriteProgress({written:e,encrypted:t,total:a}))},d=()=>l().uploadDialog.cancelled;let u={current:0,converting:0,total:e.length,titleCurrent:"",titleConverting:""};const p=()=>{r(F.setTrackProgress(u))};let g=l().main.disc,b=g?1700-Object(m.getTracks)(g).map(e=>e.title||"").reduce((e,t)=>e+t.length,0):-1;let f;b=Math.floor(b/e.length);let h="",v=1;for await(let m of async function*(e){let a=[],n=0;!function r(){if(n===e.length||d())return u.converting=n,u.titleConverting="",void p();let l=e[n];u.converting=n,u.titleConverting=l.name,p(),n++,a.push(new Promise(async(e,a)=>{let n;try{await i.prepare(l),n=await i.export({format:t}),r(),e({file:l,data:n})}catch(o){f=o,h=`${l.name}: Unsupported or unrecognized format`,a(o)}}))}();let r=0;for(;r0&&(r=r.substring(0,l)),b>-1&&(r=r.substring(0,b)),u.current=v++,u.titleCurrent=r,p(),s({written:0,encrypted:0,total:100});try{await(null===o||void 0===o?void 0:o.upload(r,t,c,s))}catch(w){f=w,h=`${e.name}: Error uploading to device`;break}}let E=[F.setVisible(!1)];f&&(console.error(f),E=E.concat([_.setVisible(!0),_.setErrorMessage(h)])),r(Object(I.batchActions)(E)),Ne()(r)}}var Re=a(588),Fe=a(83),We=a(595),Le=a(596),Ae=a(614),Be=a(586),$e=a(580),Ve=a(587),Ue=a(584),_e=a(585),Ge=a(583),He=a(579);const Je=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Ye=e=>{const t=Object(o.c)();let a=b(e=>e.appState.aboutDialogVisible);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:Je,"aria-labelledby":"about-dialog-slide-title"},r.a.createElement(Ge.a,{id:"about-dialog-slide-title"},"About Web MiniDisc"),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,null,"Web MiniDisc has been made possible by"),r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://www.ffmpeg.org/",target:"_blank"},"FFmpeg")," ","and"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/ffmpegjs/FFmpeg",target:"_blank"},"ffmpegjs"),", to read your audio files (wav, mp3, ogg, mp4, etc...)."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/dcherednik/atracdenc/",target:"_blank"},"Atracdenc"),", to support atrac3 encoding (lp2, lp4 audio formats)."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://emscripten.org/",target:"_blank"},"Emscripten"),", to run both FFmpeg and Atracdenc in the browser."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/netmd-js",target:"_blank"},"netmd-js"),", to send commands to NetMD devices using Javascript."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/glaubitz/linux-minidisc",target:"_blank"},"linux-minidisc"),", to make the netmd-js project possible."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://material-ui.com/",target:"_blank"},"material-ui"),", to build the user interface.")),r.a.createElement(_e.a,null,"Attribution"),r.a.createElement("ul",null,r.a.createElement("li",null,"MiniDisc logo from"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://en.wikipedia.org/wiki/MiniDisc",target:"_blank"},"https://en.wikipedia.org/wiki/MiniDisc")),r.a.createElement("li",null,"MiniDisc icon from"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://www.deviantart.com/blinkybill/art/Sony-MiniDisc-Plastic-Icon-473812540",target:"_blank"},"http://fav.me/d7u3g3g")))),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:()=>{t(pe.showAboutDialog(!1))}},"Close")))};var qe=a(592),Ke=a(290),Xe=a(615),Qe=a(276),Ze=a.n(Qe),et=a(590),tt=a(591),at=a(269),nt=a.n(at),rt=a(142),lt=a.n(rt),it=a(275),ot=a.n(it),ct=a(270),st=a.n(ct),dt=a(271),mt=a.n(dt),ut=a(274),pt=a.n(ut),gt=a(273),bt=a.n(gt),ft=a(272),ht=a.n(ft);const vt=Object(Se.a)(e=>({listItemIcon:{minWidth:e.spacing(5)}})),yt=function(){const e=vt(),t=Object(o.c)();let{mainView:a,darkMode:l}=b(e=>e.appState),i=b(e=>{var t,a;return null!==(t=null===(a=e.main.disc)||void 0===a?void 0:a.title)&&void 0!==t?t:""});const c=r.a.useRef(null),[s,d]=r.a.useState(null),m=Boolean(s),u=Object(n.useCallback)(e=>{d(e.currentTarget)},[d]),p=Object(n.useCallback)(()=>{t(pe.setDarkMode(!l))},[t,l]),g=Object(n.useCallback)(()=>{d(null)},[d]),f=Object(n.useCallback)(()=>{t((async function(e){if(!window.confirm("Proceed with Wipe Disc? This operation cannot be undone."))return;const{netmdService:t}=T;e(pe.setLoading(!0)),await t.wipeDisc(),Ne()(e)})),g()},[t,g]),h=Object(n.useCallback)(()=>{t(Ne()),g()},[t,g]),v=Object(n.useCallback)(()=>{t(Object(I.batchActions)([B.setVisible(!0),B.setCurrentName(i),B.setIndex(-1)])),g()},[t,g,i]),y=Object(n.useCallback)(()=>{t(pe.setState("WELCOME")),g()},[t,g]),E=Object(n.useCallback)(()=>{t(pe.showAboutDialog(!0)),g()},[t,g]),w=Object(n.useCallback)(e=>{var t;(e.stopPropagation(),e.target!==c.current)&&(null===(t=c.current)||void 0===t||t.click());g()},[g]),k=[];return"MAIN"===a&&(k.push(r.a.createElement(Xe.a,{key:"update",onClick:h},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(nt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Reload TOC"))),k.push(r.a.createElement(Xe.a,{key:"title",onClick:v},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(lt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Rename Disc"))),k.push(r.a.createElement(Xe.a,{key:"wipe",onClick:f},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(st.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Wipe Disc"))),k.push(r.a.createElement(Xe.a,{key:"exit",onClick:y},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(mt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Exit")))),k.push(r.a.createElement(Xe.a,{key:"darkMode",onClick:p},r.a.createElement(et.a,{className:e.listItemIcon},l?r.a.createElement(ht.a,{fontSize:"small"}):r.a.createElement(bt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Dark Mode"))),k.push(r.a.createElement(Xe.a,{key:"about",onClick:E},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(pt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"About"))),k.push(r.a.createElement(Xe.a,{key:"github",onClick:w},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(ot.a,{fontSize:"small"})),r.a.createElement(tt.a,null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/webminidisc",target:"_blank",ref:c,onClick:w},"Fork me on GitHub")))),r.a.createElement(r.a.Fragment,null,r.a.createElement(qe.a,{"aria-label":"actions","aria-controls":"actions-menu","aria-haspopup":"true",onClick:u},r.a.createElement(Ze.a,null)),r.a.createElement(Ke.a,{id:"actions-menu",anchorEl:s,keepMounted:!0,open:m,onClose:g},k))};var Et=a(277),wt=a.n(Et);const kt=Object(Se.a)(e=>({main:{position:"relative",flex:"1 1 auto",display:"flex",justifyContent:"center",flexDirection:"column",alignItems:"center"},button:{marginTop:e.spacing(3),minWidth:150},spacing:{marginTop:e.spacing(1)},chromeLogo:{marginTop:e.spacing(1),width:96,height:96},why:{alignSelf:"flex-start",marginTop:e.spacing(3)},headBox:{display:"flex",justifyContent:"space-between"}})),Ct=e=>{const t=kt(),a=Object(o.c)(),{browserSupported:l,pairingFailed:i,pairingMessage:c}=b(e=>e.appState);c.toLowerCase().match(/denied/);const[s,d]=Object(n.useState)(!1);return r.a.createElement(r.a.Fragment,null,r.a.createElement(Ae.a,{className:t.headBox},r.a.createElement(Fe.a,{component:"h1",variant:"h4"},"Web MiniDisc"),r.a.createElement(yt,null)),r.a.createElement(Fe.a,{component:"h2",variant:"body2"},"Brings NetMD Devices to the Web"),r.a.createElement(Ae.a,{className:t.main},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Press the button to connect to a NetMD device"),r.a.createElement(Re.a,{variant:"contained",color:"primary",onClick:()=>a((async function(e,t){e(pe.setPairingFailed(!1)),await T.audioExportService.init();try{if(await T.netmdService.connect())return void e(pe.setState("MAIN"))}catch(a){console.error(a)}try{if(await T.netmdService.pair())return void e(pe.setState("MAIN"));e(Object(I.batchActions)([pe.setPairingMessage("Connection Failed"),pe.setPairingFailed(!0)]))}catch(a){console.error(a);let t=a.message;e(Object(I.batchActions)([pe.setPairingMessage(t),pe.setPairingFailed(!0)]))}})),className:t.button},"Connect"),r.a.createElement(We.a,{error:!0,className:t.spacing,style:{visibility:i?"visible":"hidden"}},r.a.createElement(Le.a,null,c))):r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"This Web browser is not supported.\xa0",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"#",onClick:e=>{e.preventDefault(),d(!0)}},"Learn Why")),r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},r.a.createElement("img",{alt:"Chrome Logo",src:wt.a,className:t.chromeLogo})),r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Try using"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},"Chrome")," ","instead"),s?r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"p",variant:"body2",className:t.why},"Web MiniDisc requires a browser that supports both"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://wicg.github.io/webusb/"},"WebUSB")," ","and"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://webassembly.org/"},"WebAssembly"),"."),r.a.createElement("ul",null,r.a.createElement("li",null,"WebUSB is needed to control the NetMD device via the USB connection to your computer."),r.a.createElement("li",null,"WebAssembly is used to convert the music to a MiniDisc compatible format"))):null)),r.a.createElement(Ye,null))};var Ot=a(3),jt=a(288),St=a(12),Dt=a(608),xt=a(285),Mt=a.n(xt),Tt=a(284),Nt=a.n(Tt),Pt=a(603),It=a(607),zt=a(606),Rt=a(604),Ft=a(605),Wt=a(602),Lt=a(616),At=a(613);const Bt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),$t=e=>{let t=Object(o.c)(),a=b(e=>e.renameDialog.visible),n=b(e=>e.renameDialog.title),l=b(e=>e.renameDialog.index);const i=l<0?"Disc":"Track",c=()=>{t(B.setVisible(!1))},s=()=>{t(l<0?function({newName:e}){return async function(t){const{netmdService:a}=T;await a.renameDisc(e),t(B.setVisible(!1)),Ne()(t)}}({newName:n}):function({index:e,newName:t}){return async function(a){const{netmdService:n}=T;a(B.setVisible(!1));try{await n.renameTrack(e,t)}catch(r){console.error(r),a(Object(I.batchActions)([_.setVisible(!0),_.setErrorMessage("Rename failed.")]))}Ne()(a)}}({index:l,newName:n}))};return r.a.createElement($e.a,{open:a,onClose:c,maxWidth:"sm",fullWidth:!0,TransitionComponent:Bt,"aria-labelledby":"rename-dialog-title"},r.a.createElement(Ge.a,{id:"rename-dialog-title"},"Rename ",i),r.a.createElement(Ue.a,null,r.a.createElement(At.a,{autoFocus:!0,id:"name",label:`${i} Name`,type:"text",fullWidth:!0,value:n,onKeyDown:e=>{"Enter"===e.key&&s()},onChange:e=>{t(B.setCurrentName(e.target.value.substring(0,120)))}})),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:c},"Cancel"),r.a.createElement(Re.a,{color:"primary",onClick:s},"Rename")))};var Vt=a(599);const Ut=Object(Se.a)(e=>({progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)},uploadLabel:{marginTop:e.spacing(3)}})),_t=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Gt=e=>{const t=Ut(),a=Object(o.c)();let{visible:l,cancelled:i,writtenProgress:c,encryptedProgress:s,totalProgress:d,trackTotal:m,trackCurrent:u,trackConverting:p,titleCurrent:g,titleConverting:f}=b(e=>e.uploadDialog);const h=Object(n.useCallback)(()=>{a(F.setCancelUpload(!0))},[a]);let v=Math.floor(c/d*100),y=Math.floor(s/d*100),E=Math.floor(p/m*100);return r.a.createElement($e.a,{open:l,maxWidth:"sm",fullWidth:!0,TransitionComponent:_t,"aria-labelledby":"alert-dialog-slide-title","aria-describedby":"alert-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Recording..."),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"alert-dialog-slide-description"},100===E&&p===m?"Conversion completed":`Converting ${p+1} of ${m}: ${f}`),r.a.createElement(Vt.a,{className:t.progressBar,variant:0===E?"indeterminate":"determinate",color:"primary",value:E}),r.a.createElement(Ae.a,{className:t.progressPerc},E,"%"),r.a.createElement(_e.a,{id:"alert-dialog-slide-description",className:t.uploadLabel},"Uploading ",u," of ",m,": ",g),r.a.createElement(Vt.a,{className:t.progressBar,variant:"buffer",color:"secondary",value:v,valueBuffer:y}),r.a.createElement(Ae.a,{className:t.progressPerc},v,"%")),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{disabled:i,onClick:h},i?"Stopping after current track...":"Cancel Recording")))},Ht=Object(Se.a)(e=>({progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)}})),Jt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Yt=e=>{const t=Ht();let{visible:a,trackTotal:n,trackDone:l,trackCurrent:i,titleCurrent:o}=b(e=>e.recordDialog),c=Math.round(i);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:Jt,"aria-labelledby":"record-dialog-slide-title","aria-describedby":"record-dialog-slide-description"},r.a.createElement(Ge.a,{id:"record-dialog-slide-title"},"Recording..."),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"record-dialog-slide-description"},`Recording track ${l+1} of ${n}: ${o}`),r.a.createElement(Vt.a,{className:t.progressBar,variant:i>=0?"determinate":"indeterminate",color:"primary",value:c}),r.a.createElement(Ae.a,{className:t.progressPerc},c>=0?`${c}%`:"")),r.a.createElement(Ve.a,null))},qt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Kt=e=>{const t=Object(o.c)();let{visible:a,error:l}=b(e=>e.errorDialog);const i=Object(n.useCallback)(()=>{t(_.setVisible(!1))},[t]);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:qt,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Error"),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"alert-dialog-slide-description"},l)),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:i},"Close")))},Xt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Qt=e=>{const t=Object(o.c)();let{visible:a,dismissed:l}=b(e=>e.panicDialog);const i=Object(n.useCallback)(()=>{window.location.reload()},[]),c=Object(n.useCallback)(()=>{t(Y.dismiss())},[t]);return r.a.createElement($e.a,{open:a&&!l,maxWidth:"sm",fullWidth:!0,scroll:"paper",TransitionComponent:Xt,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Oops\u2026 Something unexpected happened."),r.a.createElement(Ue.a,null,r.a.createElement(Fe.a,{color:"textSecondary",variant:"body1",component:"div"},"Try to restart the app. If the error persists, try the followings:",r.a.createElement("ol",null,r.a.createElement("li",null,"Use your browser in incognito mode."),r.a.createElement("li",null,"Use a blank MiniDisc."),r.a.createElement("li",null,"Try to use Web MiniDisc on another computer.")),"If this does not solve the error, your unit might not be supported yet or you have encountered a bug. The full error is reported in the JS console.")),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:c,size:"small"},"Ignore and Continue"),r.a.createElement(Re.a,{onClick:i,color:"primary"},"Restart the App")))};var Zt=a(600),ea=a(618),ta=a(612),aa=a(597);const na=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),ra=Object(Se.a)(e=>({container:{display:"flex",flexDirection:"row"},formControl:{minWidth:60},toggleButton:{minWidth:40},dialogContent:{display:"flex",flexWrap:"wrap",justifyContent:"space-between"},rightBlock:{display:"flex",flexDirection:"column"},titleFormControl:{marginTop:e.spacing(1)}})),la=e=>{const t=Object(o.c)(),a=ra();let{visible:l,format:i,titleSource:c,titleFormat:s}=b(e=>e.convertDialog);const d=Object(n.useCallback)(()=>{t(Z.setVisible(!1))},[t]),m=Object(n.useCallback)((e,a)=>{null!==a&&t(Z.setFormat(a))},[t]),u=Object(n.useCallback)((e,a)=>{null!==a&&t(Z.setTitleSource(a))},[t]),p=Object(n.useCallback)(e=>{t(Z.setTitleFormat(e.target.value))},[t]),g=Object(n.useCallback)(()=>{d(),t(ze(e.files,i,c,s))},[t,e,i,c,s,d]);return r.a.createElement($e.a,{open:l,maxWidth:"xs",fullWidth:!0,TransitionComponent:na,"aria-labelledby":"convert-dialog-slide-title","aria-describedby":"convert-dialog-slide-description"},r.a.createElement(Ge.a,{id:"convert-dialog-slide-title"},"Upload Settings"),r.a.createElement(Ue.a,{className:a.dialogContent},r.a.createElement(We.a,null,r.a.createElement(Fe.a,{component:"label",variant:"caption",color:"textSecondary"},"Recording Mode"),r.a.createElement(ea.a,{value:i,exclusive:!0,onChange:m,size:"small"},r.a.createElement(Zt.a,{className:a.toggleButton,value:"SP"},"SP"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"LP2"},"LP2"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"LP4"},"LP4"))),r.a.createElement("div",{className:a.rightBlock},r.a.createElement(We.a,{className:a.formControl},r.a.createElement(Fe.a,{component:"label",variant:"caption",color:"textSecondary"},"Track title"),r.a.createElement(ea.a,{value:c,exclusive:!0,onChange:u,size:"small"},r.a.createElement(Zt.a,{className:a.toggleButton,value:"file"},"Filename"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"media"},"Media tags"))),"media"===c?r.a.createElement(We.a,{className:a.titleFormControl},r.a.createElement(ta.a,{value:s,color:"secondary",input:r.a.createElement(aa.a,null),onChange:p},r.a.createElement(Xe.a,{value:"title"},"Title"),r.a.createElement(Xe.a,{value:"album-title"},"Album - Title"),r.a.createElement(Xe.a,{value:"artist-title"},"Artist - Title"),r.a.createElement(Xe.a,{value:"artist-album-title"},"Artist - Album - Title"))):null)),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:d},"Cancel"),r.a.createElement(Re.a,{onClick:g},"Ok")))};var ia=a(280),oa=a.n(ia),ca=a(281),sa=a.n(ca),da=a(282),ma=a.n(da),ua=a(279),pa=a.n(ua);function ga(){return(ga=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",ga({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,ba),ha=r.a.forwardRef((e,t)=>r.a.createElement(fa,ga({svgRef:t},e)));a.p;function va(){return(va=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",va({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,ya),wa=r.a.forwardRef((e,t)=>r.a.createElement(Ea,va({svgRef:t},e)));a.p;function ka(){return(ka=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",ka({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,Ca),ja=r.a.forwardRef((e,t)=>r.a.createElement(Oa,ka({svgRef:t},e)));a.p;function Sa(){return(Sa=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",Sa({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,Da),Ma=r.a.forwardRef((e,t)=>r.a.createElement(xa,Sa({svgRef:t},e)));a.p;const Ta=[ha,wa,ja,Ma],Na=Object(Se.a)(e=>({"@keyframes scrollLeft":{from:{transform:"translateX(0%)"},to:{}},container:{display:"flex",flex:"1 1 auto",[O(e)]:{flexWrap:"wrap"}},lcd:{flex:"1 1 auto",position:"relative",marginLeft:e.spacing(1.5),marginRight:e.spacing(1.5),paddingLeft:e.spacing(3),paddingRight:e.spacing(3),borderRadius:e.spacing(3),backgroundColor:e.palette.background.default,minWidth:150,height:48,[O(e)]:{marginLeft:0,marginRight:e.spacing(2)}},lcdText:{overflow:"hidden",position:"relative",width:"calc(100% - 40px)",left:40,height:"100%",fontFamily:"LCDDot"},lcdDisc:{position:"absolute",top:0,left:20},lcdDiscIcon:{width:28,height:48,"& g":{fill:e.palette.action.active}},scrollingStatusMessage:{position:"absolute",width:"100%",whiteSpace:"nowrap",animationName:"$scrollLeft",animationTimingFunction:"linear",animationIterationCount:"1",top:15,left:1},statusMessage:{position:"absolute",width:"100%",whiteSpace:"nowrap",top:15,left:1},button:{}})),Pa=()=>{var e,t,a;const l=Object(o.c)(),i=b(e=>e.main.deviceStatus),c=b(e=>e.main.disc),s=Na(),d=Object(n.useCallback)(()=>{l(Te("prev"))},[l]),m=Object(n.useCallback)(()=>{l(Te("play"))},[l]),u=Object(n.useCallback)(()=>{l(Te("stop"))},[l]),p=Object(n.useCallback)(()=>{l(Te("next"))},[l]);let g="",f=null!==(e=null===i||void 0===i?void 0:i.track)&&void 0!==e?e:null,h=null!==(t=null===i||void 0===i?void 0:i.state)&&void 0!==t?t:null,v=null!==(a=null===i||void 0===i?void 0:i.discPresent)&&void 0!==a&&a;const y=w(c);v?"readingTOC"===h?g="READING TOC":0===y.length?g="BLANKDISC":i&&null!==i.track&&(g=`${i.track+1} - `+y[i.track].title):g="";const[E,k]=Object(n.useState)(0),[C,O]=Object(n.useState)(0),[j,S]=Object(n.useState)(0),D=Object(n.useRef)(null),x=Object(n.useRef)(null);Object(n.useEffect)(()=>(clearTimeout(D.current),k(0),D.current=setTimeout(()=>{(()=>{var e,t,a;const n=x.current,r=null!==(e=null===n||void 0===n?void 0:n.scrollWidth)&&void 0!==e?e:0,l=null!==(t=null===n||void 0===n?void 0:null===(a=n.parentElement)||void 0===a?void 0:a.offsetWidth)&&void 0!==t?t:0,i=r>l?r/20:0;k(r>l?100*r/l:0),O(i),i>0&&(D.current=setTimeout(()=>{k(0)},1e3*i+500))})()},2e3),()=>{clearTimeout(D.current)}),[f,h,g]);const M=Object(n.useRef)(null);Object(n.useEffect)(()=>(clearInterval(M.current),"playing"===h||"readingTOC"===h?M.current=setInterval(()=>{S(1+j%(Ta.length-1))},600):S(0),()=>{clearInterval(M.current)}),[h,j]);const T=Ta[j];return r.a.createElement(Ae.a,{className:s.container},r.a.createElement(qe.a,{"aria-label":"prev",onClick:d,className:s.button},r.a.createElement(pa.a,null)),r.a.createElement(qe.a,{"aria-label":"play",onClick:m,className:s.button},r.a.createElement(oa.a,null)),r.a.createElement(qe.a,{"aria-label":"stop",onClick:u,className:s.button},r.a.createElement(sa.a,null)),r.a.createElement(qe.a,{"aria-label":"next",onClick:p,className:s.button},r.a.createElement(ma.a,null)),r.a.createElement("div",{className:s.lcd},r.a.createElement("div",{className:s.lcdText},r.a.createElement("span",{className:E?s.scrollingStatusMessage:s.statusMessage,ref:x,style:g&&E>0?{animationDuration:`${C}s`,transform:`translate(-${E}%)`}:{}},g)),r.a.createElement("div",{className:s.lcdDisc},v&&r.a.createElement(T,{className:s.lcdDiscIcon}))))},Ia=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),za=Object(Se.a)(e=>({container:{display:"flex",flexDirection:"row",alignItems:"flex-end",justifyContent:"space-between",marginRight:-e.spacing(2),flexFlow:"wrap"},formControl:{minWidth:120},selectEmpty:{marginTop:e.spacing(2)},head:{textShadow:"0px 0px 12px rgba(150, 150, 150, 1)",fontSize:e.typography.h2.fontSize,textAlign:"center",marginBottom:e.spacing(2)}})),Ra=({trackIndexes:e})=>{const t=Object(o.c)(),a=za(),[l,i]=Object(n.useState)([]),[c,s]=Object(n.useState)("");let{visible:d}=b(e=>e.dumpDialog);const u=Object(n.useCallback)(()=>{var e;s(""),null===(e=T.mediaRecorderService)||void 0===e||e.stopTestInput(),t(re.setVisible(!1))},[t]),f=Object(n.useCallback)(e=>{var t,a;const n=e.target.value;s(n),null===(t=T.mediaRecorderService)||void 0===t||t.stopTestInput(),null===(a=T.mediaRecorderService)||void 0===a||a.playTestInput(n)},[s]),h=Object(n.useCallback)(()=>{var a,n;t((a=e,n=c,async function(e,t){e(Object(I.batchActions)([ce.setVisible(!0),ce.setProgress({trackTotal:a.length,trackDone:0,trackCurrent:0,titleCurrent:""})]));let r=t().main.disc,l=Object(m.getTracks)(r).filter(e=>a.indexOf(e.index)>=0);const{netmdService:i,mediaRecorderService:o}=T;await T.netmdService.stop();for(let[a,s]of l.entries()){var c;e(ce.setProgress({trackTotal:l.length,trackDone:a,trackCurrent:-1,titleCurrent:null!==(c=s.title)&&void 0!==c?c:""})),await i.gotoTrack(s.index),await i.play(),console.log("Waiting for track to be ready to play");let t=await i.getPosition(),r=[s.index,0,0,1];for(;null===t||!r.every((e,a)=>r[a]===t[a]);)await p(250),t=await i.getPosition();await i.pause(),await(null===i||void 0===i?void 0:i.gotoTrack(s.index)),console.log("Track is ready to play"),await(null===o||void 0===o?void 0:o.initStream(n)),await(null===o||void 0===o?void 0:o.startRecording()),await i.play();let d=s.duration/512;await g(1e3*d,t=>{var n;e(ce.setProgress({trackTotal:l.length,trackDone:a,trackCurrent:t,titleCurrent:null!==(n=s.title)&&void 0!==n?n:""}))}),await(null===o||void 0===o?void 0:o.stopRecording()),null===o||void 0===o||o.downloadRecorded(`${s.title}`),await(null===o||void 0===o?void 0:o.closeStream())}await i.stop(),e(ce.setVisible(!1))})),u()},[e,c,t,u]);return Object(n.useEffect)(()=>{d&&async function(){await navigator.mediaDevices.getUserMedia({audio:!0});let e=(await navigator.mediaDevices.enumerateDevices()).filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label}));i(e)}()},[d,i]),r.a.createElement($e.a,{open:d,maxWidth:"sm",fullWidth:!0,TransitionComponent:Ia,"aria-labelledby":"dump-dialog-slide-title","aria-describedby":"dump-dialog-slide-description"},r.a.createElement(Ge.a,{id:"dump-dialog-slide-title"},"Record Selected Tracks"),r.a.createElement(Ue.a,null,r.a.createElement(Fe.a,{component:"p",variant:"h2",className:a.head},"\ud83d\udcbb \u2b05 \ud83d\udcbd"),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"1. Connect your MD Player line-out to your PC audio line-in."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"2. Use the controls at the bottom right to play some tracks."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"3. Select the input source. You should hear the tracks playing on your PC."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"4. Adjust the input gain and the line-out volume of your device."),r.a.createElement(Ae.a,{className:a.container},r.a.createElement(We.a,{className:a.formControl},r.a.createElement(ta.a,{value:c,onChange:f,displayEmpty:!0,className:a.selectEmpty},r.a.createElement(Xe.a,{value:"",disabled:!0},"Input Source"),l.map(e=>r.a.createElement(Xe.a,{key:e.deviceId,value:e.deviceId},e.label))),r.a.createElement(Le.a,null,"Input Source")),r.a.createElement(Pa,null))),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:u},"Cancel"),r.a.createElement(Re.a,{onClick:h,disabled:""===c},"Start Record")))};var Fa=a(611),Wa=a(180);const La=Object(Se.a)(e=>({add:{position:"absolute",bottom:e.spacing(3),right:e.spacing(3),[O(e)]:{bottom:e.spacing(2)}},main:{overflowY:"auto",flex:"1 1 auto",marginBottom:e.spacing(3),outline:"none",marginLeft:e.spacing(-1),marginRight:e.spacing(-1),[C(e)]:{marginLeft:e.spacing(-2),marginRight:e.spacing(-2)}},toolbar:{marginTop:e.spacing(3),marginLeft:e.spacing(-2),marginRight:e.spacing(-2),[e.breakpoints.up(600+2*e.spacing(2))]:{marginLeft:e.spacing(-3),marginRight:e.spacing(-3)}},toolbarLabel:{flex:"1 1 100%"},toolbarHighlight:"light"===e.palette.type?{color:e.palette.secondary.main,backgroundColor:Object(St.d)(e.palette.secondary.light,.85)}:{color:e.palette.text.primary,backgroundColor:e.palette.secondary.dark},headBox:{display:"flex",justifyContent:"space-between"},spacing:{marginTop:e.spacing(1)},formatBadge:{...Wa.styles(e).badge,...Wa.styles(e).colorPrimary,position:"static",display:"inline-flex",border:`2px solid ${e.palette.background.paper}`,padding:"0 4px",verticalAlign:"middle",width:e.spacing(4.5),marginRight:e.spacing(.5)},titleCell:{overflow:"hidden",maxWidth:"40ch",textOverflow:"ellipsis"},durationCell:{whiteSpace:"nowrap"},durationCellTime:{verticalAlign:"middle"},indexCell:{whiteSpace:"nowrap",paddingRight:0,width:"2ch"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},remainingTimeTooltip:{textDecoration:"underline",textDecorationStyle:"dotted"}})),Aa=e=>{let t=Object(o.c)(),a=b(e=>e.main.disc),l=b(e=>e.main.deviceName);const[i,c]=r.a.useState([]),s=i.length,[d,u]=r.a.useState(null),p=Object(n.useCallback)(e=>{u(e.currentTarget)},[]),g=Object(n.useCallback)(()=>{u(null)},[]),f=Object(n.useCallback)(e=>{t(function(e,t){return async function(a){const{netmdService:n}=T;await n.moveTrack(e,t),Ne()(a)}}(i[0],e)),g()},[t,i,g]),h=Object(n.useCallback)(()=>{t(re.setVisible(!0))},[t]);Object(n.useEffect)(()=>{t(Ne())},[t]),Object(n.useEffect)(()=>{c([])},[a]);let[v,y]=r.a.useState([]);const E=Object(n.useCallback)((e,a)=>{y(e),t(Z.setVisible(!0))},[t]),{getRootProps:k,getInputProps:C,isDragActive:O,open:j}=Object(jt.a)({onDrop:E,accept:["audio/*","video/mp4"],noClick:!0}),S=La(),D=w(a),x=(e,n)=>{var r,l;let i=n,o=null!==(r=null===(l=Object(m.getTracks)(a).find(e=>e.index===i))||void 0===l?void 0:l.title)&&void 0!==r?r:"";t(Object(I.batchActions)([B.setVisible(!0),B.setCurrentName(o),B.setIndex(i)]))};return r.a.createElement(r.a.Fragment,null,r.a.createElement(Ae.a,{className:S.headBox},r.a.createElement(Fe.a,{component:"h1",variant:"h4"},l||"Loading..."),r.a.createElement(yt,null)),r.a.createElement(Fe.a,{component:"h2",variant:"body2"},null!==a?r.a.createElement(r.a.Fragment,null,r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(a.left,!1)} left of ${Object(m.formatTimeFromFrames)(a.total,!1)} `),r.a.createElement(Lt.a,{title:r.a.createElement(r.a.Fragment,null,r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(2*a.left,!1)} left in LP2 Mode`),r.a.createElement("br",null),r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(4*a.left,!1)} left in LP4 Mode`)),arrow:!0},r.a.createElement("span",{className:S.remainingTimeTooltip},"SP Mode"))):"Loading..."),r.a.createElement(Wt.a,{className:Object(Ot.default)(S.toolbar,{[S.toolbarHighlight]:s>0})},s>0?r.a.createElement(Fa.a,{indeterminate:s>0&&s0,onChange:e=>{i.lengthe.index)):c([])},inputProps:{"aria-label":"select all tracks"}}):null,s>0?r.a.createElement(Fe.a,{className:S.toolbarLabel,color:"inherit",variant:"subtitle1"},s," selected"):r.a.createElement(Fe.a,{component:"h3",variant:"h6",className:S.toolbarLabel},(null===a||void 0===a?void 0:a.title)||"Untitled Disc"),1===s?r.a.createElement(r.a.Fragment,null,r.a.createElement(Lt.a,{title:"Move to Position"},r.a.createElement(Re.a,{"aria-controls":"move-menu","aria-label":"Move",onClick:p},"Move")),r.a.createElement(Ke.a,{id:"move-menu",anchorEl:d,open:!!d,onClose:g,PaperProps:{style:{maxHeight:300}}},Array(D.length).fill(null).map((e,t)=>r.a.createElement(Xe.a,{key:`pos-${t}`,onClick:()=>f(t)},t+1)))):null,s>0?r.a.createElement(r.a.Fragment,null,r.a.createElement(Lt.a,{title:"Record from MD"},r.a.createElement(Re.a,{"aria-label":"Record",onClick:h},"Record"))):null,s>0?r.a.createElement(Lt.a,{title:"Delete"},r.a.createElement(qe.a,{"aria-label":"delete",onClick:e=>{var a;t((a=i,async function(e){if(!window.confirm(`Proceed with Delete Track${1!==a.length?"s":""}? This operation cannot be undone.`))return;const{netmdService:t}=T;e(pe.setLoading(!0)),(a=a.sort()).reverse();for(let n of a)await t.deleteTrack(n);Ne()(e)}))}},r.a.createElement(Nt.a,null))):null,s>0?r.a.createElement(Lt.a,{title:"Rename"},r.a.createElement(qe.a,{"aria-label":"rename",disabled:1!==s,onClick:e=>{x(0,i[0])}},r.a.createElement(lt.a,null))):null),r.a.createElement(Ae.a,Object.assign({className:S.main},k()),r.a.createElement("input",C()),r.a.createElement(Pt.a,{size:"small"},r.a.createElement(Rt.a,null,r.a.createElement(Ft.a,null,r.a.createElement(zt.a,{className:S.indexCell},"#"),r.a.createElement(zt.a,null,"Title"),r.a.createElement(zt.a,{align:"right"},"Duration"))),r.a.createElement(It.a,null,D.map(e=>r.a.createElement(Ft.a,{hover:!0,selected:i.includes(e.index),key:e.index,onDoubleClick:t=>x(0,e.index),onClick:t=>{return a=e.index,void(i.includes(a)?c(i.filter(e=>e!==a)):c([...i,a]));var a}},r.a.createElement(zt.a,{className:S.indexCell},e.index+1),r.a.createElement(zt.a,{className:S.titleCell,title:e.title},e.title||"No Title"),r.a.createElement(zt.a,{align:"right",className:S.durationCell},r.a.createElement("span",{className:S.formatBadge},e.encoding),r.a.createElement("span",{className:S.durationCellTime},e.duration)))))),r.a.createElement(Oe.a,{className:S.backdrop,open:O},"Drop your Music to Upload")),r.a.createElement(Dt.a,{color:"primary","aria-label":"add",className:S.add,onClick:j},r.a.createElement(Mt.a,null)),r.a.createElement(Gt,null),r.a.createElement($t,null),r.a.createElement(Kt,null),r.a.createElement(la,{files:v}),r.a.createElement(Yt,null),r.a.createElement(Ra,{trackIndexes:i}),r.a.createElement(Ye,null),r.a.createElement(Qt,null))};var Ba=a(545);const $a=Object(Se.a)(e=>({layout:{width:"auto",height:"100%",[C(e)]:{width:600,marginLeft:"auto",marginRight:"auto"},[j(e)]:{width:700}},paper:{position:"relative",display:"flex",flexDirection:"column",padding:e.spacing(2),height:"calc(100% - 20px)",[C(e)]:{marginTop:e.spacing(2),marginBottom:e.spacing(1),padding:e.spacing(3),height:600},[j(e)]:{height:700}},bottomBar:{display:"flex",alignItems:"center",[O(e)]:{flexWrap:"wrap"},marginLeft:-e.spacing(2)},copyrightTypography:{marginRight:e.spacing(1),textAlign:"center"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},minidiscLogo:{width:48},controlsContainer:{flex:"0 0 auto",width:"100%",paddingRight:e.spacing(8),[O(e)]:{paddingLeft:0}}})),Va=Object(De.a)({palette:{type:"dark",primary:{light:"#6ec6ff",main:"#2196f3",dark:"#0069c0",contrastText:"#fff"}}}),Ua=Object(De.a)({palette:{type:"light"}});var _a=()=>{const e=$a();Object(o.c)();let{mainView:t,loading:a,darkMode:n}=b(e=>e.appState);return r.a.createElement(r.a.Fragment,null,r.a.createElement(xe.a,{theme:n?Va:Ua},r.a.createElement(Ce.a,null),r.a.createElement("main",{className:e.layout},r.a.createElement(Ba.a,{className:e.paper},"WELCOME"===t?r.a.createElement(Ct,null):null,"MAIN"===t?r.a.createElement(Aa,null):null,r.a.createElement(Ae.a,{className:e.controlsContainer},"MAIN"===t?r.a.createElement(Pa,null):null)),r.a.createElement(Fe.a,{variant:"body2",color:"textSecondary",className:e.copyrightTypography},"\xa9 ",r.a.createElement(Be.a,{rel:"noopener noreferrer",color:"inherit",target:"_blank",href:"https://stefano.brilli.me/"},"Stefano Brilli")," ",(new Date).getFullYear(),".")),r.a.createElement(Oe.a,{className:e.backdrop,open:a},r.a.createElement(je.a,{color:"inherit"}))))},Ga=(a(527),a(528),a(181));class Ha{constructor(e){this.worker=e,this.messageCallback=void 0,e.onmessage=this.handleMessage.bind(this)}async init(){await new Promise(e=>{this.messageCallback=e,this.worker.postMessage({action:"init"})})}async encode(e,t){return(await new Promise(a=>{this.messageCallback=a,this.worker.postMessage({action:"encode",bitrate:t,data:e},[e])})).data.result}terminate(){this.worker.terminate()}handleMessage(e){this.messageCallback(e),this.messageCallback=void 0}}if("undefined"!==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope){let e;onmessage=async t=>{const{action:a,...n}=t.data;if("init"===a)self.importScripts(f("atracdenc.js")),self.Module().then(t=>{e=t,self.postMessage({action:"init"}),e.setLogger&&e.setLogger((e,t)=>console.log(`${t}: ${e}`))});else if("encode"===a){const{bitrate:t,data:a}=n,r="inWavFile.wav",l="outAt3File.aea",i=new Uint8Array(a);e.FS.writeFile(`${r}`,i),e.callMain(["-e","atrac3","-i",r,"-o",l,"--bitrate",t]);let o=e.FS.stat(l).size,c=new Uint8Array(o-96),s=e.FS.open(l,"r");e.FS.read(s,c,0,c.length,96),e.FS.close(s);let d=c.buffer;self.postMessage({action:"encode",result:d},[d])}}}const Ja=a(543);var Ya=a(286),qa=a.n(Ya);T.netmdService=new M({debug:!0}),T.audioExportService=new class{constructor(){this.ffmpegProcess=void 0,this.atracdencProcess=void 0,this.loglines=[],this.inFileName="",this.outFileNameNoExt=""}async init(){Object(Ga.setLogging)(!0)}async prepare(e){this.loglines=[],this.ffmpegProcess=Object(Ga.createWorker)({logger:e=>{this.loglines.push(e),console.log(e.action,e.message)},corePath:f("ffmpeg-core.js"),workerPath:f("worker.min.js")}),await this.ffmpegProcess.load(),this.atracdencProcess=new Ha(new Ja),await this.atracdencProcess.init();let t=e.name.split(".").slice(-1);if(0===t.length)throw new Error(`Unrecognized file format: ${e.name}`);this.inFileName=`inAudioFile.${t[0]}`,this.outFileNameNoExt="outAudioFile",await this.ffmpegProcess.write(this.inFileName,e)}async info(){await this.ffmpegProcess.transcode(this.inFileName,`${this.outFileNameNoExt}.metadata`,"-f ffmetadata");let e=/Audio:\s(.*?),/,t=/Input #0,\s(.*?),/,a=null,n=null;for(let r of this.loglines){let l=r.message.match(e);if(null===l)if(l=r.message.match(t),null===l){if(null!==a&&null!==n)break}else n=l[1];else a=l[1]}return{format:a,input:n}}async export({format:e}){let t;if("SP"===e){const e=`${this.outFileNameNoExt}.raw`;await this.ffmpegProcess.transcode(this.inFileName,e,"-f s16be -ar 44100");let{data:a}=await this.ffmpegProcess.read(e);t=a.buffer}else{const a=`${this.outFileNameNoExt}.wav`;await this.ffmpegProcess.transcode(this.inFileName,a,"-f wav -ar 44100");let{data:n}=await this.ffmpegProcess.read(a),r="0";switch(e){case"LP2":r="128";break;case"LP105":r="102";break;case"LP4":r="64"}t=await this.atracdencProcess.encode(n.buffer,r)}return this.ffmpegProcess.worker.terminate(),this.atracdencProcess.terminate(),t}},T.mediaRecorderService=new class{constructor(){this.recorder=void 0,this.stream=void 0,this.audioContext=void 0,this.analyserNode=void 0,this.gainNode=void 0}playTestInput(e){this.audioContext=new AudioContext,this.gainNode=this.audioContext.createGain(),this.analyserNode=this.audioContext.createAnalyser(),this.initStream(e).then(()=>{this.audioContext.createMediaStreamSource(this.stream).connect(this.gainNode),this.gainNode.connect(this.analyserNode),this.analyserNode.connect(this.audioContext.destination)})}stopTestInput(){var e;this.audioContext&&(null===(e=this.audioContext)||void 0===e||e.close(),delete this.audioContext,this.closeStream())}async initStream(e){const t={autoGainControl:!1,channelCount:2,deviceId:e,echoCancellation:!1,noiseSuppression:!1,sampleRate:44100,highpassFilter:!1};this.stream=await navigator.mediaDevices.getUserMedia({audio:t});const a=this.stream.getAudioTracks();a.length>0&&console.log("Record Setings:",a[0].getSettings())}async startRecording(){this.audioContext=new AudioContext;const e=this.audioContext.createMediaStreamSource(this.stream);this.recorder=new qa.a(e,{workerPath:f("recorderWorker.js")}),this.recorder.record()}async stopRecording(){this.recorder.stop()}async closeStream(){var e;null===(e=this.stream)||void 0===e||e.getTracks().forEach(e=>e.stop())}downloadRecorded(e){this.recorder.exportWAV(t=>{let a=URL.createObjectURL(t),n=document.createElement("a");document.body.appendChild(n),n.style.display="none",n.href=a,n.download=`${y(e)}.wav`,n.click(),window.URL.revokeObjectURL(a),document.body.removeChild(n)})}},function(){let e;window.addEventListener("beforeunload",e=>{we.getState().uploadDialog.visible&&(e.preventDefault(),e.returnValue="Warning! Recording will be interrupted")}),navigator&&navigator.usb?navigator.usb.ondisconnect=function(){we.dispatch(pe.setState("WELCOME"))}:we.dispatch(pe.setBrowserSupported(!1)),window.addEventListener("beforeinstallprompt",t=>{t.preventDefault(),e=t})}(),function(){let e=null,t=!1;function a(e){var a;return!t&&"MAIN"===e.appState.mainView&&!1===e.appState.loading&&"playing"===(null===(a=e.main.deviceStatus)||void 0===a?void 0:a.state)&&!1===e.convertDialog.visible&&!1===e.uploadDialog.visible&&!1===e.recordDialog.visible&&!1===e.panicDialog.visible&&!1===e.errorDialog.visible&&!1===e.dumpDialog.visible}we.subscribe((function(){const n=we.getState();!0===a(n)&&null===e?e=setInterval(async()=>{try{const e=await T.netmdService.getDeviceStatus();we.dispatch(he.setDeviceStatus(e))}catch(e){console.error(e),t=!0}},5e3):!1===a(n)&&null!==e&&(clearInterval(e),e=null)}))}(),i.a.render(r.a.createElement(o.a,{store:we},r.a.createElement(_a,null)),document.getElementById("root")),function(e){if("serviceWorker"in navigator){if(new URL("/webminidisc",window.location.href).origin!==window.location.origin)return;window.addEventListener("load",()=>{const t="/webminidisc/final-service-worker.js";c?(!function(e,t){fetch(e,{headers:{"Service-Worker":"script"}}).then(a=>{const n=a.headers.get("content-type");404===a.status||null!=n&&-1===n.indexOf("javascript")?navigator.serviceWorker.ready.then(e=>{e.unregister().then(()=>{window.location.reload()})}):s(e,t)}).catch(()=>{console.log("No internet connection found. App is running in offline mode.")})}(t,e),navigator.serviceWorker.ready.then(()=>{console.log("This web app is being served cache-first by a service worker. To learn more, visit https://bit.ly/CRA-PWA")})):s(t,e)})}}()}},[[303,1,2]]]); -//# sourceMappingURL=main.8336c8e1.chunk.js.map \ No newline at end of file diff --git a/static/js/main.8336c8e1.chunk.js.map b/static/js/main.8336c8e1.chunk.js.map deleted file mode 100644 index a4281bf..0000000 --- a/static/js/main.8336c8e1.chunk.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["images/chrome-icon.svg","webpack:///./src/services/atracdenc-worker.ts?dc3c","serviceWorker.ts","utils.ts","services/netmd.ts","services/registry.ts","redux/upload-dialog-feature.ts","redux/rename-dialog-feature.ts","redux/error-dialog-feature.ts","redux/panic-dialog-feature.ts","redux/convert-dialog-feature.ts","redux/dump-dialog-feature.ts","redux/record-dialog-feature.ts","redux/app-feature.ts","redux/main-feature.ts","redux/store.ts","redux/actions.ts","components/about-dialog.tsx","components/topmenu.tsx","components/welcome.tsx","components/rename-dialog.tsx","components/upload-dialog.tsx","components/record-dialog.tsx","components/error-dialog.tsx","components/panic-dialog.tsx","components/convert-dialog.tsx","images/md0.svg","images/md1.svg","images/md2.svg","images/md3.svg","components/controls.tsx","components/dump-dialog.tsx","components/main.tsx","components/app.tsx","services/atracdenc-worker.ts","services/audio-export.ts","index.tsx","services/mediarecorder.ts"],"names":["module","exports","Worker","isLocalhost","Boolean","window","location","hostname","match","registerValidSW","swUrl","config","navigator","serviceWorker","register","then","registration","onupdatefound","installingWorker","installing","onstatechange","console","log","state","controller","onUpdate","onSuccess","update","catch","error","sleep","ms","Promise","resolve","setTimeout","async","sleepWithProgressCallback","cb","elapsedSecs","interval","setInterval","Math","min","clearInterval","useShallowEqualSelector","selector","useSelector","shallowEqual","getPublicPathFor","script","savePreference","key","value","localStorage","setItem","JSON","stringify","loadPreference","defaultValue","res","getItem","parse","e","sanitizeTitle","title","normalize","replace","EncodingName","Encoding","sp","lp2","lp4","getSortedTracks","disc","tracks","group","groups","track","push","index","encoding","duration","formatTimeFromFrames","sort","l","r","asyncMutex","target","propertyKey","descriptor","oldValue","args","mutex","this","release","acquire","apply","forAnyDesktop","theme","breakpoints","up","spacing","belowDesktop","down","forWideDesktop","require","NetMDUSBService","constructor","debug","netmdInterface","logger","Mutex","statusMonitorTimer","_fn","method","info","warn","child","iface","openNewDevice","usb","openPairedDevice","listContent","getDeviceStatus","netMd","getDeviceName","finalize","cacheTOC","setTrackTitle","syncTOC","newName","oldName","getDiscTitle","oldRawName","_getDiscTitle","hasGroups","indexOf","hasGroupsAndTitle","startsWith","newNameWithGroups","setDiscTitle","eraseTrack","eraseDisc","src","dst","moveTrack","data","format","progressCallback","total","byteLength","written","encrypted","updateProgress","w","webWorkerAsyncPacketIterator","makeGetAsyncPacketIteratorOnWorkerThread","encryptedBytes","mdTrack","MDTrack","download","writtenBytes","terminate","play","pause","stop","nextTrack","previousTrack","gotoTrack","getPosition","ServiceRegistry","slice","createSlice","name","initialState","visible","cancelled","writtenProgress","encryptedProgress","totalProgress","trackTotal","trackConverting","trackCurrent","titleCurrent","titleConverting","reducers","setVisible","action","payload","setWriteProgress","setCancelUpload","setTrackProgress","current","converting","reducer","actions","enableBatching","setCurrentName","setIndex","setErrorMessage","dismissed","dismiss","titleSource","titleFormat","setFormat","setTitleSource","setTitleFormat","inputDeviceId","setInputDeviceId","trackDone","setProgress","mainView","loading","pairingFailed","pairingMessage","browserSupported","darkMode","aboutDialogVisible","setState","setLoading","setPairingFailed","setPairingMessage","setBrowserSupported","setDarkMode","showAboutDialog","deviceName","deviceStatus","setDisc","setDeviceName","setDeviceStatus","combineReducers","renameDialog","uploadDialog","errorDialog","panicDialog","convertDialog","dumpDialog","recordDialog","appState","main","resetStateAction","appActions","toString","store","configureStore","type","middleware","next","panicDialogActions","getDefaultMiddleware","Object","freeze","getState","control","params","dispatch","serviceRegistry","netmdService","prev","mainActions","appStateActions","batchActions","WireformatDict","SP","Wireformat","pcm","LP2","LP105","l105kbps","LP4","getTrackNameFromMediaTags","file","fileData","arrayBuffer","blob","Blob","Uint8Array","metadata","mm","common","artist","album","convertAndUpload","files","audioExportService","wireformat","uploadDialogActions","updateProgressCallback","hasUploadBeenCancelled","trackUpdate","length","updateTrack","maxTitleLength","getTracks","map","reduce","acc","floor","errorMessage","i","item","converted","convertNext","f","reject","prepare","export","err","j","conversionIterator","extStartIndex","lastIndexOf","substring","upload","actionToDispatch","concat","errorDialogAction","Transition","React","forwardRef","props","ref","Slide","direction","AboutDialog","useDispatch","Dialog","open","maxWidth","fullWidth","TransitionComponent","aria-labelledby","DialogTitle","id","DialogContent","DialogContentText","Link","rel","href","DialogActions","Button","onClick","useStyles","makeStyles","listItemIcon","minWidth","TopMenu","classes","discTitle","githubLinkRef","useRef","menuAnchorEl","setMenuAnchorEl","useState","menuOpen","handleMenuOpen","useCallback","event","currentTarget","handleDarkMode","handleMenuClose","handleWipeDisc","confirm","wipeDisc","handleRefresh","handleRenameDisc","renameDialogActions","handleExit","handleShowAbout","handleGithubLink","stopPropagation","click","menuItems","MenuItem","ListItemIcon","className","fontSize","ListItemText","Fragment","IconButton","aria-label","aria-controls","aria-haspopup","Menu","anchorEl","keepMounted","onClose","position","flex","display","justifyContent","flexDirection","alignItems","button","marginTop","chromeLogo","width","height","why","alignSelf","headBox","Welcome","toLowerCase","showWhyUnsupported","setWhyUnsupported","Box","Typography","component","variant","align","color","init","connect","pair","message","FormControl","style","visibility","FormHelperText","preventDefault","alt","ChromeIconPath","RenameDialog","renameDialogVisible","renameDialogTitle","renameDialogIndex","what","handleCancelRename","handleDoRename","renameDisc","renameTrack","TextField","autoFocus","label","onKeyDown","onChange","progressPerc","progressBar","uploadLabel","UploadDialog","handleCancelUpload","progressValue","bufferValue","convertedValue","aria-describedby","LinearProgress","valueBuffer","disabled","RecordDialog","round","ErrorDialog","handleClose","errorDialogActions","PanicDialog","handleReloadApp","reload","handleIgnore","scroll","size","container","formControl","toggleButton","dialogContent","flexWrap","rightBlock","titleFormControl","ConvertDialog","convertDialogActions","handleChangeFormat","ev","newFormat","handleChangeTitleSource","newTitleSource","handleChangeTitleFormat","handleConvert","ToggleButtonGroup","exclusive","ToggleButton","Select","input","Input","_extends","assign","arguments","source","prototype","hasOwnProperty","call","createElement","fill","fillRule","d","SvgMd0","svgRef","viewBox","ForwardRef","SvgMd1","SvgMd2","SvgMd3","frames","MDIcon0","MDIcon1","MDIcon2","MDIcon3","from","transform","to","lcd","marginLeft","marginRight","paddingLeft","paddingRight","borderRadius","backgroundColor","palette","background","default","lcdText","overflow","left","fontFamily","lcdDisc","top","lcdDiscIcon","active","scrollingStatusMessage","whiteSpace","animationName","animationTimingFunction","animationIterationCount","statusMessage","Controls","handlePrev","handlePlay","handleStop","handleNext","trackIndex","deviceState","discPresent","lcdScroll","setLcdScroll","lcdScrollDuration","setLcdScrollDuration","lcdIconFrame","setLcdIconFrame","scrollTimerRef","lcdRef","useEffect","clearTimeout","domEl","textWidth","scrollWidth","lcdWidth","parentElement","offsetWidth","scrollDurationInSec","updateLCDScroll","lcdIconAnimationTimer","DiscFrame","animationDuration","flexFlow","selectEmpty","head","textShadow","typography","h2","textAlign","marginBottom","DumpDialog","trackIndexes","devices","setDevices","mediaRecorderService","stopTestInput","dumpDialogActions","handleChange","deviceId","playTestInput","handleStartTransfer","indexes","recordDialogAction","filter","t","entries","expected","every","_","initStream","startRecording","durationInSec","perc","stopRecording","downloadRecorded","closeStream","mediaDevices","getUserMedia","audio","inputDevices","enumerateDevices","device","kind","updateDeviceList","displayEmpty","add","bottom","right","overflowY","outline","toolbar","toolbarLabel","toolbarHighlight","secondary","lighten","light","text","primary","dark","formatBadge","BadgeImpl","badge","colorPrimary","border","paper","padding","verticalAlign","titleCell","textOverflow","durationCell","durationCellTime","indexCell","backdrop","zIndex","drawer","remainingTimeTooltip","textDecoration","textDecorationStyle","Main","selected","setSelected","selectedCount","moveMenuAnchorEl","setMoveMenuAnchorEl","handleShowMoveMenu","handleCloseMoveMenu","handleMoveSelectedTrack","destIndex","srcIndex","handleShowDumpDialog","uploadedFiles","setUploadedFiles","onDrop","acceptedFiles","rejectedFiles","getRootProps","getInputProps","isDragActive","useDropzone","accept","noClick","handleRenameDoubleClick","selectedIndex","currentName","find","Tooltip","arrow","Toolbar","clsx","Checkbox","indeterminate","checked","inputProps","PaperProps","maxHeight","Array","reverse","deleteTrack","Table","TableHead","TableRow","TableCell","TableBody","hover","includes","onDoubleClick","handleSelectClick","Backdrop","Fab","layout","bottomBar","copyrightTypography","minidiscLogo","controlsContainer","darkTheme","createMuiTheme","contrastText","lightTheme","App","ThemeProvider","CssBaseline","Paper","Date","getFullYear","CircularProgress","AtracdencProcess","worker","messageCallback","onmessage","handleMessage","bind","postMessage","bitrate","result","undefined","WorkerGlobalScope","self","Module","others","importScripts","m","setLogger","msg","stream","inWavFile","outAt3File","dataArray","FS","writeFile","callMain","stat","tmp","outAt3FileStream","read","close","buffer","AtracdencWorker","ffmpegProcess","atracdencProcess","loglines","inFileName","outFileNameNoExt","setLogging","createWorker","corePath","workerPath","load","ext","split","Error","write","transcode","audioFormatRegex","inputFormatRegex","line","outFileName","encode","recorder","audioContext","analyserNode","gainNode","AudioContext","createGain","createAnalyser","createMediaStreamSource","destination","recordConstraints","autoGainControl","channelCount","echoCancellation","noiseSuppression","sampleRate","highpassFilter","audioTracks","getAudioTracks","getSettings","Recorder","record","forEach","exportWAV","url","URL","createObjectURL","a","document","body","appendChild","revokeObjectURL","removeChild","deferredPrompt","addEventListener","returnValue","ondisconnect","statusMonitorInterval","exceptionOccurred","shouldMonitorBeRunning","subscribe","ReactDOM","render","getElementById","process","origin","fetch","headers","response","contentType","get","status","ready","unregister","checkValidServiceWorker"],"mappings":"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","file":"static/js/main.8336c8e1.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/chrome-icon.f3b6c54c.svg\";","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"ffb88193b05ec63929fd.worker.js\");\n};","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/final-service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' + 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n console.log('state change', installingWorker.state);\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n registration.update(); // Check for new version everytime we load the page\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import { Disc, formatTimeFromFrames, Encoding } from 'netmd-js';\nimport { useSelector, shallowEqual } from 'react-redux';\nimport { RootState } from './redux/store';\nimport { Mutex } from 'async-mutex';\nimport { Theme } from '@material-ui/core';\n\nexport function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nexport async function sleepWithProgressCallback(ms: number, cb: (perc: number) => void) {\n let elapsedSecs = 1;\n let interval = setInterval(() => {\n elapsedSecs++;\n cb(Math.min(100, ((elapsedSecs * 1000) / ms) * 100));\n }, 1000);\n await sleep(ms);\n window.clearInterval(interval);\n}\n\nexport function useShallowEqualSelector(selector: (state: TState) => TSelected): TSelected {\n return useSelector(selector, shallowEqual);\n}\n\nexport function debugEnabled() {\n return process.env.NODE_ENV === 'development';\n}\n\nexport function getPublicPathFor(script: string) {\n return `${process.env.PUBLIC_URL}/${script}`;\n}\n\nexport function savePreference(key: string, value: unknown) {\n localStorage.setItem(key, JSON.stringify(value));\n}\n\nexport function loadPreference(key: string, defaultValue: T): T {\n let res = localStorage.getItem(key);\n if (res === null) {\n return defaultValue;\n } else {\n try {\n return JSON.parse(res) as T;\n } catch (e) {\n return defaultValue;\n }\n }\n}\n\nexport function getAvailableCharsForTrackTitle(trackTitles: string[]) {\n const maxChars = 1700; // see https://www.minidisc.org/md_toc.html\n const usedChars = trackTitles.reduce((acc, title) => {\n return acc + title.length;\n }, 0);\n return maxChars - usedChars;\n}\n\nexport function framesToSec(frames: number) {\n return frames / 512;\n}\n\nexport function sanitizeTitle(title: string) {\n return title.normalize('NFD').replace(/[^\\x00-\\x7F]/g, '');\n}\n\nconst EncodingName: { [k: number]: string } = {\n [Encoding.sp]: 'SP',\n [Encoding.lp2]: 'LP2',\n [Encoding.lp4]: 'LP4',\n};\n\nexport function getSortedTracks(disc: Disc | null) {\n let tracks: { index: number; title: string; group: string; duration: string; encoding: string }[] = [];\n if (disc !== null) {\n for (let group of disc.groups) {\n for (let track of group.tracks) {\n tracks.push({\n index: track.index,\n title: track.title ?? `Unknown Title`,\n group: group.title ?? ``,\n encoding: EncodingName[track.encoding],\n duration: formatTimeFromFrames(track.duration, false),\n });\n }\n }\n }\n tracks.sort((l, r) => l.index - r.index);\n return tracks;\n}\n\nexport function asyncMutex(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n // This is meant to be used only with classes having a \"mutex\" instance property\n const oldValue = descriptor.value;\n descriptor.value = async function(...args: any) {\n const mutex = (this as any).mutex as Mutex;\n const release = await mutex.acquire();\n try {\n return await oldValue.apply(this, args);\n } finally {\n release();\n }\n };\n return descriptor;\n}\n\nexport function forAnyDesktop(theme: Theme) {\n return theme.breakpoints.up(600 + theme.spacing(2) * 2);\n}\n\nexport function belowDesktop(theme: Theme) {\n return theme.breakpoints.down(600 + theme.spacing(2) * 2);\n}\n\nexport function forWideDesktop(theme: Theme) {\n return theme.breakpoints.up(700 + theme.spacing(2) * 2) + ` and (min-height: 750px)`;\n}\n\ndeclare let process: any;\n","import {\n openNewDevice,\n NetMDInterface,\n Disc,\n listContent,\n openPairedDevice,\n Wireformat,\n MDTrack,\n download,\n getDeviceStatus,\n DeviceStatus,\n} from 'netmd-js';\nimport { makeGetAsyncPacketIteratorOnWorkerThread } from 'netmd-js/dist/web-encrypt-worker';\nimport { Logger } from 'netmd-js/dist/logger';\nimport { asyncMutex, sanitizeTitle, sleep } from '../utils';\nimport { Mutex } from 'async-mutex';\n\nconst Worker = require('worker-loader!netmd-js/dist/web-encrypt-worker.js'); // eslint-disable-line import/no-webpack-loader-syntax\n\nexport interface NetMDService {\n mutex: Mutex;\n getDeviceStatus(): Promise;\n pair(): Promise;\n connect(): Promise;\n listContent(): Promise;\n getDeviceName(): Promise;\n finalize(): Promise;\n renameTrack(index: number, newTitle: string): Promise;\n renameDisc(newName: string): Promise;\n deleteTrack(index: number): Promise;\n moveTrack(src: number, dst: number): Promise;\n wipeDisc(): Promise;\n upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ): Promise;\n\n play(): Promise;\n pause(): Promise;\n stop(): Promise;\n next(): Promise;\n prev(): Promise;\n gotoTrack(index: number): Promise;\n getPosition(): Promise;\n}\n\nexport class NetMDUSBService implements NetMDService {\n private netmdInterface?: NetMDInterface;\n private logger?: Logger;\n public mutex = new Mutex();\n public statusMonitorTimer: any;\n\n constructor({ debug = false }: { debug: boolean }) {\n if (debug) {\n // Logging a few methods that have been causing issues with some units\n const _fn = (...args: any) => {\n if (args && args[0] && args[0].method) {\n console.log(...args);\n }\n };\n this.logger = {\n debug: _fn,\n info: _fn,\n warn: _fn,\n error: _fn,\n child: () => this.logger!,\n };\n }\n }\n\n async pair() {\n let iface = await openNewDevice(navigator.usb, this.logger);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async connect() {\n let iface = await openPairedDevice(navigator.usb, this.logger);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n @asyncMutex\n async listContent() {\n return await listContent(this.netmdInterface!);\n }\n\n @asyncMutex\n async getDeviceStatus() {\n return await getDeviceStatus(this.netmdInterface!);\n }\n\n @asyncMutex\n async getDeviceName() {\n return await this.netmdInterface!.netMd.getDeviceName();\n }\n\n @asyncMutex\n async finalize() {\n await this.netmdInterface!.netMd.finalize();\n }\n\n @asyncMutex\n async renameTrack(index: number, title: string) {\n // Removing non ascii chars... Sorry, I didn't implement char encoding.\n title = sanitizeTitle(title);\n await this.netmdInterface!.cacheTOC();\n await this.netmdInterface!.setTrackTitle(index, title);\n await this.netmdInterface!.syncTOC();\n }\n\n @asyncMutex\n async renameDisc(newName: string) {\n // TODO: This whole function should be moved in netmd-js\n const oldName = await this.netmdInterface!.getDiscTitle();\n const oldRawName = await this.netmdInterface!._getDiscTitle();\n const hasGroups = oldRawName.indexOf('//') >= 0;\n const hasGroupsAndTitle = oldRawName.startsWith('0;');\n\n if (newName === oldName) {\n return;\n }\n\n let newNameWithGroups;\n\n if (hasGroups) {\n if (hasGroupsAndTitle) {\n newNameWithGroups = oldRawName.replace(/^0;.*?\\/\\//, newName !== '' ? `0;${newName}//` : ``); // Replace or delete the old title\n } else {\n newNameWithGroups = `0;${newName}//${oldRawName}`; // Add the new title\n }\n } else {\n newNameWithGroups = newName;\n }\n\n await this.netmdInterface!.cacheTOC();\n await this.netmdInterface!.setDiscTitle(newNameWithGroups);\n await this.netmdInterface!.syncTOC();\n }\n\n @asyncMutex\n async deleteTrack(index: number) {\n await this.netmdInterface!.eraseTrack(index);\n await sleep(100);\n }\n\n @asyncMutex\n async wipeDisc() {\n await this.netmdInterface!.eraseDisc();\n }\n\n @asyncMutex\n async moveTrack(src: number, dst: number) {\n await this.netmdInterface!.moveTrack(src, dst);\n }\n\n async upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ) {\n let total = data.byteLength;\n let written = 0;\n let encrypted = 0;\n function updateProgress() {\n progressCallback({ written, encrypted, total });\n }\n\n let w = new Worker();\n\n let webWorkerAsyncPacketIterator = makeGetAsyncPacketIteratorOnWorkerThread(w, ({ encryptedBytes }) => {\n encrypted = encryptedBytes;\n updateProgress();\n });\n\n // Removing non ascii chars... Sorry, I didn't implement char encoding.\n title = sanitizeTitle(title);\n let mdTrack = new MDTrack(title, format, data, 0x80000, webWorkerAsyncPacketIterator);\n\n await download(this.netmdInterface!, mdTrack, ({ writtenBytes }) => {\n written = writtenBytes;\n updateProgress();\n });\n\n w.terminate();\n }\n\n @asyncMutex\n async play() {\n await this.netmdInterface!.play();\n }\n @asyncMutex\n async pause() {\n await this.netmdInterface!.pause();\n }\n @asyncMutex\n async stop() {\n await this.netmdInterface!.stop();\n }\n @asyncMutex\n async next() {\n await this.netmdInterface!.nextTrack();\n }\n @asyncMutex\n async prev() {\n await this.netmdInterface!.previousTrack();\n }\n\n @asyncMutex\n async gotoTrack(index: number) {\n await this.netmdInterface!.gotoTrack(index);\n }\n\n @asyncMutex\n async getPosition() {\n return await this.netmdInterface!.getPosition();\n }\n}\n","import { NetMDService } from './netmd';\nimport { AudioExportService } from './audio-export';\nimport { MediaRecorderService } from './mediarecorder';\n\ninterface ServiceRegistry {\n netmdService?: NetMDService;\n audioExportService?: AudioExportService;\n mediaRecorderService?: MediaRecorderService;\n}\n\nconst ServiceRegistry: ServiceRegistry = {};\n\nexport default ServiceRegistry;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface LoadingDialogState {\n visible: boolean;\n cancelled: boolean;\n\n writtenProgress: number;\n encryptedProgress: number;\n totalProgress: number;\n\n trackTotal: number;\n trackConverting: number;\n trackCurrent: number;\n\n titleCurrent: string;\n titleConverting: string;\n}\n\nconst initialState: LoadingDialogState = {\n visible: false,\n cancelled: false,\n\n // Current Track Upload\n writtenProgress: 0,\n encryptedProgress: 0,\n totalProgress: 1,\n\n // Tracks done\n trackTotal: 1,\n trackConverting: 0,\n trackCurrent: 0,\n titleCurrent: '',\n titleConverting: '',\n};\n\nexport const slice = createSlice({\n name: 'uploadDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setWriteProgress: (state, action: PayloadAction<{ written: number; encrypted: number; total: number }>) => {\n state.encryptedProgress = action.payload.encrypted;\n state.writtenProgress = action.payload.written;\n state.totalProgress = action.payload.total;\n },\n setCancelUpload: (state, action: PayloadAction) => {\n state.cancelled = action.payload;\n },\n setTrackProgress: (\n state,\n action: PayloadAction<{ total: number; current: number; converting: number; titleCurrent: string; titleConverting: string }>\n ) => {\n state.trackTotal = action.payload.total;\n state.trackCurrent = action.payload.current;\n state.trackConverting = action.payload.converting;\n state.titleCurrent = action.payload.titleCurrent;\n state.titleConverting = action.payload.titleConverting;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RenameDialogState {\n visible: boolean;\n title: string;\n index: number;\n}\n\nconst initialState: RenameDialogState = {\n visible: false,\n title: '',\n index: -1,\n};\n\nexport const slice = createSlice({\n name: 'renameDialog',\n initialState,\n reducers: {\n setVisible: (state: RenameDialogState, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setCurrentName: (state: RenameDialogState, action: PayloadAction) => {\n state.title = action.payload;\n },\n setIndex: (state: RenameDialogState, action: PayloadAction) => {\n state.index = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ErrorDialogState {\n visible: boolean;\n error: string;\n}\n\nconst initialState: ErrorDialogState = {\n visible: false,\n error: ``,\n};\n\nconst slice = createSlice({\n name: 'errorDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setErrorMessage: (state, action: PayloadAction) => {\n state.error = `${action.payload}`;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport const initialState = {\n visible: false,\n dismissed: false, // This will prevent showing the dialog during the same session\n};\n\nconst slice = createSlice({\n name: 'panicDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n dismiss: (state, action: PayloadAction) => {\n state.visible = false;\n state.dismissed = true;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\nexport type TitleSourceType = 'file' | 'media';\nexport type TitleFormatType = 'title' | 'album-title' | 'artist-title' | 'artist-album-title';\n\nexport interface ConvertDialogFeature {\n visible: boolean;\n format: string;\n titleSource: TitleSourceType;\n titleFormat: TitleFormatType;\n}\n\nconst initialState: ConvertDialogFeature = {\n visible: false,\n format: `LP2`,\n titleSource: loadPreference('trackTitleSource', 'file') as TitleSourceType,\n titleFormat: loadPreference('trackTitleFormat', 'title') as TitleFormatType,\n};\n\nconst slice = createSlice({\n name: 'convertDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setFormat: (state, action: PayloadAction) => {\n state.format = action.payload;\n },\n setTitleSource: (state, action: PayloadAction) => {\n state.titleSource = action.payload;\n savePreference('trackTitleSource', state.titleSource);\n },\n setTitleFormat: (state, action: PayloadAction) => {\n state.titleFormat = action.payload;\n savePreference('trackTitleFormat', state.titleFormat);\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface DumpDialogState {\n visible: boolean;\n inputDeviceId: string;\n}\n\nconst initialState: DumpDialogState = {\n visible: false,\n inputDeviceId: '',\n};\n\nexport const slice = createSlice({\n name: 'dumpDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setInputDeviceId: (state, action: PayloadAction) => {\n state.inputDeviceId = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RecordingDialogState {\n visible: boolean;\n\n trackTotal: number;\n trackDone: number;\n trackCurrent: number;\n\n titleCurrent: string;\n}\n\nconst initialState: RecordingDialogState = {\n visible: false,\n\n trackTotal: 1,\n trackDone: 0,\n trackCurrent: 0,\n\n titleCurrent: '',\n\n // visible: true,\n // trackTotal: 4,\n // trackDone: 1,\n // trackCurrent: 25,\n\n // titleCurrent: 'Seconda traccia',\n};\n\nexport const slice = createSlice({\n name: 'recordDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setProgress: (\n state,\n action: PayloadAction<{ trackTotal: number; trackDone: number; trackCurrent: number; titleCurrent: string }>\n ) => {\n state.trackTotal = action.payload.trackTotal;\n state.trackDone = action.payload.trackDone;\n state.trackCurrent = action.payload.trackCurrent;\n state.titleCurrent = action.payload.titleCurrent;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\ntype Views = 'WELCOME' | 'MAIN';\n\nexport interface AppState {\n mainView: Views;\n loading: boolean;\n pairingFailed: boolean;\n pairingMessage: string;\n browserSupported: boolean;\n darkMode: boolean;\n aboutDialogVisible: boolean;\n}\n\nconst initialState: AppState = {\n mainView: 'WELCOME',\n loading: false,\n pairingFailed: false,\n pairingMessage: ``,\n browserSupported: true,\n darkMode: loadPreference('darkMode', false),\n aboutDialogVisible: false,\n};\n\nexport const slice = createSlice({\n name: 'app',\n initialState,\n reducers: {\n setState: (state, action: PayloadAction) => {\n state.mainView = action.payload;\n },\n setLoading: (state, action: PayloadAction) => {\n state.loading = action.payload;\n },\n setPairingFailed: (state, action: PayloadAction) => {\n state.pairingFailed = action.payload;\n },\n setPairingMessage: (state, action: PayloadAction) => {\n state.pairingMessage = action.payload;\n },\n setBrowserSupported: (state, action: PayloadAction) => {\n state.browserSupported = action.payload;\n },\n setDarkMode: (state, action: PayloadAction) => {\n state.darkMode = action.payload;\n savePreference('darkMode', state.darkMode);\n },\n showAboutDialog: (state, action: PayloadAction) => {\n state.aboutDialogVisible = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { Disc, DeviceStatus } from 'netmd-js';\nimport { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface MainState {\n disc: Disc | null;\n deviceName: string;\n deviceStatus: DeviceStatus | null;\n}\n\nconst initialState: MainState = {\n disc: null,\n deviceName: '',\n deviceStatus: null,\n};\n\nexport const slice = createSlice({\n name: 'main',\n initialState,\n reducers: {\n setDisc: (state, action: PayloadAction) => {\n state.disc = action.payload;\n },\n setDeviceName: (state, action: PayloadAction) => {\n state.deviceName = action.payload;\n },\n setDeviceStatus: (state, action: PayloadAction) => {\n state.deviceStatus = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { configureStore, getDefaultMiddleware, Middleware, combineReducers } from '@reduxjs/toolkit';\nimport uploadDialog from './upload-dialog-feature';\nimport renameDialog from './rename-dialog-feature';\nimport errorDialog from './error-dialog-feature';\nimport panicDialog, { actions as panicDialogActions } from './panic-dialog-feature';\nimport convertDialog from './convert-dialog-feature';\nimport dumpDialog from './dump-dialog-feature';\nimport recordDialog from './record-dialog-feature';\nimport appState, { actions as appActions } from './app-feature';\nimport main from './main-feature';\n\nconst errorCatcher: Middleware = store => next => async action => {\n try {\n await next(action);\n } catch (e) {\n console.error(e);\n next(panicDialogActions.setVisible(true));\n }\n};\n\nlet reducer = combineReducers({\n renameDialog,\n uploadDialog,\n errorDialog,\n panicDialog,\n convertDialog,\n dumpDialog,\n recordDialog,\n appState,\n main,\n});\n\nconst resetStateAction = appActions.setState.toString();\nconst resetStatePayoload = 'WELCOME';\nconst resetStateReducer: typeof reducer = function(...args) {\n const [state, action] = args;\n if (action.type === resetStateAction && action.payload === resetStatePayoload) {\n return initialState;\n }\n return reducer(...args);\n};\n\nexport const store = configureStore({\n reducer: resetStateReducer,\n middleware: [errorCatcher, ...getDefaultMiddleware()],\n});\n\nconst initialState = Object.freeze(store.getState());\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","import { batchActions } from 'redux-batched-actions';\nimport { AppDispatch, RootState } from './store';\nimport { actions as uploadDialogActions } from './upload-dialog-feature';\nimport { actions as renameDialogActions } from './rename-dialog-feature';\nimport { actions as errorDialogAction } from './error-dialog-feature';\nimport { actions as recordDialogAction } from './record-dialog-feature';\nimport { actions as appStateActions } from './app-feature';\nimport { actions as mainActions } from './main-feature';\nimport serviceRegistry from '../services/registry';\nimport { Wireformat, getTracks } from 'netmd-js';\nimport { AnyAction } from '@reduxjs/toolkit';\nimport { getAvailableCharsForTrackTitle, framesToSec, sleepWithProgressCallback, sleep } from '../utils';\nimport * as mm from 'music-metadata-browser';\nimport { TitleSourceType, TitleFormatType } from './convert-dialog-feature';\n\nexport function control(action: 'play' | 'stop' | 'next' | 'prev' | 'goto', params?: unknown) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n switch (action) {\n case 'play':\n await serviceRegistry.netmdService!.play();\n break;\n case 'stop':\n await serviceRegistry.netmdService!.stop();\n break;\n case 'next':\n await serviceRegistry.netmdService!.next();\n break;\n case 'prev':\n await serviceRegistry.netmdService!.prev();\n break;\n case 'goto':\n if (params && typeof params === 'number' && params >= 0) {\n await serviceRegistry.netmdService!.gotoTrack(params);\n }\n break;\n }\n // CAVEAT: change-track might take a up to a few seconds to complete.\n // We wait 500ms and let the monitor do further updates\n await sleep(500);\n try {\n let deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n dispatch(mainActions.setDeviceStatus(deviceStatus));\n } catch (e) {\n console.log('control: Cannot get device status');\n }\n };\n}\n\nexport function pair() {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(appStateActions.setPairingFailed(false));\n\n await serviceRegistry.audioExportService!.init();\n\n try {\n let connected = await serviceRegistry.netmdService!.connect();\n if (connected) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n } catch (err) {\n console.error(err);\n // In case of error, just log and try to pair\n }\n\n try {\n let paired = await serviceRegistry.netmdService!.pair();\n if (paired) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n dispatch(batchActions([appStateActions.setPairingMessage(`Connection Failed`), appStateActions.setPairingFailed(true)]));\n } catch (err) {\n console.error(err);\n let message = (err as Error).message;\n dispatch(batchActions([appStateActions.setPairingMessage(message), appStateActions.setPairingFailed(true)]));\n }\n };\n}\n\nexport function listContent() {\n return async function(dispatch: AppDispatch) {\n // Issue loading\n dispatch(appStateActions.setLoading(true));\n let disc = await serviceRegistry.netmdService!.listContent();\n let deviceName = await serviceRegistry.netmdService!.getDeviceName();\n let deviceStatus = null;\n try {\n deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n } catch (e) {\n console.log('listContent: Cannot get device status');\n }\n dispatch(\n batchActions([\n mainActions.setDisc(disc),\n mainActions.setDeviceName(deviceName),\n mainActions.setDeviceStatus(deviceStatus),\n appStateActions.setLoading(false),\n ])\n );\n };\n}\n\nexport function renameTrack({ index, newName }: { index: number; newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(renameDialogActions.setVisible(false));\n try {\n await netmdService!.renameTrack(index, newName);\n } catch (err) {\n console.error(err);\n dispatch(batchActions([errorDialogAction.setVisible(true), errorDialogAction.setErrorMessage(`Rename failed.`)]));\n }\n listContent()(dispatch);\n };\n}\n\nexport function renameDisc({ newName }: { newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.renameDisc(newName);\n dispatch(renameDialogActions.setVisible(false));\n listContent()(dispatch);\n };\n}\n\nexport function deleteTracks(indexes: number[]) {\n return async function(dispatch: AppDispatch) {\n const confirmation = window.confirm(\n `Proceed with Delete Track${indexes.length !== 1 ? 's' : ''}? This operation cannot be undone.`\n );\n if (!confirmation) {\n return;\n }\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n indexes = indexes.sort();\n indexes.reverse();\n for (let index of indexes) {\n await netmdService!.deleteTrack(index);\n }\n listContent()(dispatch);\n };\n}\n\nexport function wipeDisc() {\n return async function(dispatch: AppDispatch) {\n const confirmation = window.confirm(`Proceed with Wipe Disc? This operation cannot be undone.`);\n if (!confirmation) {\n return;\n }\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n await netmdService!.wipeDisc();\n listContent()(dispatch);\n };\n}\n\nexport function moveTrack(srcIndex: number, destIndex: number) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.moveTrack(srcIndex, destIndex);\n listContent()(dispatch);\n };\n}\n\nexport function recordTracks(indexes: number[], deviceId: string) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(\n batchActions([\n recordDialogAction.setVisible(true),\n recordDialogAction.setProgress({ trackTotal: indexes.length, trackDone: 0, trackCurrent: 0, titleCurrent: '' }),\n ])\n );\n\n let disc = getState().main.disc;\n let tracks = getTracks(disc!).filter(t => indexes.indexOf(t.index) >= 0);\n\n const { netmdService, mediaRecorderService } = serviceRegistry;\n await serviceRegistry.netmdService!.stop();\n\n for (let [i, track] of tracks.entries()) {\n dispatch(\n recordDialogAction.setProgress({\n trackTotal: tracks.length,\n trackDone: i,\n trackCurrent: -1,\n titleCurrent: track.title ?? '',\n })\n );\n\n // Wait for the track to be ready to play from 0:00\n await netmdService!.gotoTrack(track.index);\n await netmdService!.play();\n console.log('Waiting for track to be ready to play');\n let position = await netmdService!.getPosition();\n let expected = [track.index, 0, 0, 1];\n while (position === null || !expected.every((_, i) => expected[i] === position![i])) {\n await sleep(250);\n position = await netmdService!.getPosition();\n }\n await netmdService!.pause();\n await netmdService?.gotoTrack(track.index);\n console.log('Track is ready to play');\n\n // Start recording and play track\n await mediaRecorderService?.initStream(deviceId);\n await mediaRecorderService?.startRecording();\n await netmdService!.play();\n\n // Wait until track is finished\n let durationInSec = framesToSec(track.duration);\n // await sleep(durationInSec * 1000);\n await sleepWithProgressCallback(durationInSec * 1000, (perc: number) => {\n dispatch(\n recordDialogAction.setProgress({\n trackTotal: tracks.length,\n trackDone: i,\n trackCurrent: perc,\n titleCurrent: track.title ?? '',\n })\n );\n });\n\n // Stop recording and download the wav\n await mediaRecorderService?.stopRecording();\n mediaRecorderService?.downloadRecorded(`${track.title}`);\n\n await mediaRecorderService?.closeStream();\n }\n\n await netmdService!.stop();\n dispatch(recordDialogAction.setVisible(false));\n };\n}\n\nexport const WireformatDict: { [k: string]: Wireformat } = {\n SP: Wireformat.pcm,\n LP2: Wireformat.lp2,\n LP105: Wireformat.l105kbps,\n LP4: Wireformat.lp4,\n};\n\nasync function getTrackNameFromMediaTags(file: File, titleFormat: TitleFormatType) {\n const fileData = await file.arrayBuffer();\n const blob = new Blob([new Uint8Array(fileData)]);\n let metadata = await mm.parseBlob(blob);\n const title = metadata.common.title ?? 'Unknown Title';\n const artist = metadata.common.artist ?? 'Unknown Artist';\n const album = metadata.common.album ?? 'Unknown Album';\n switch (titleFormat) {\n case 'title': {\n return title;\n }\n case 'artist-title': {\n return `${artist} - ${title}`;\n }\n case 'album-title': {\n return `${album} - ${title}`;\n }\n case 'artist-album-title': {\n return `${artist} - ${album} - ${title}`;\n }\n }\n}\n\nexport function convertAndUpload(files: File[], format: string, titleSource: TitleSourceType, titleFormat: TitleFormatType) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n const { audioExportService, netmdService } = serviceRegistry;\n const wireformat = WireformatDict[format];\n\n await netmdService?.stop();\n dispatch(batchActions([uploadDialogActions.setVisible(true), uploadDialogActions.setCancelUpload(false)]));\n\n const updateProgressCallback = ({ written, encrypted, total }: { written: number; encrypted: number; total: number }) => {\n dispatch(uploadDialogActions.setWriteProgress({ written, encrypted, total }));\n };\n\n const hasUploadBeenCancelled = () => {\n return getState().uploadDialog.cancelled;\n };\n\n let trackUpdate: {\n current: number;\n converting: number;\n total: number;\n titleCurrent: string;\n titleConverting: string;\n } = {\n current: 0,\n converting: 0,\n total: files.length,\n titleCurrent: '',\n titleConverting: '',\n };\n const updateTrack = () => {\n dispatch(uploadDialogActions.setTrackProgress(trackUpdate));\n };\n\n let conversionIterator = async function*(files: File[]) {\n let converted: Promise<{ file: File; data: ArrayBuffer }>[] = [];\n\n let i = 0;\n function convertNext() {\n if (i === files.length || hasUploadBeenCancelled()) {\n trackUpdate.converting = i;\n trackUpdate.titleConverting = ``;\n updateTrack();\n return;\n }\n\n let f = files[i];\n trackUpdate.converting = i;\n trackUpdate.titleConverting = f.name;\n updateTrack();\n i++;\n\n converted.push(\n new Promise(async (resolve, reject) => {\n let data: ArrayBuffer;\n try {\n await audioExportService!.prepare(f);\n data = await audioExportService!.export({ format });\n convertNext();\n resolve({ file: f, data: data });\n } catch (err) {\n error = err;\n errorMessage = `${f.name}: Unsupported or unrecognized format`;\n reject(err);\n }\n })\n );\n }\n convertNext();\n\n let j = 0;\n while (j < converted.length) {\n yield await converted[j];\n delete converted[j];\n j++;\n }\n };\n\n let disc = getState().main.disc;\n let maxTitleLength = disc ? getAvailableCharsForTrackTitle(getTracks(disc).map(track => track.title || ``)) : -1;\n maxTitleLength = Math.floor(maxTitleLength / files.length);\n\n let error: any;\n let errorMessage = ``;\n let i = 1;\n for await (let item of conversionIterator(files)) {\n if (hasUploadBeenCancelled()) {\n break;\n }\n\n const { file, data } = item;\n\n let title = file.name;\n if (titleSource === 'media') {\n try {\n title = (await getTrackNameFromMediaTags(file, titleFormat)) ?? file.name;\n } catch (err) {\n console.error(err);\n }\n }\n\n const extStartIndex = title.lastIndexOf('.');\n if (extStartIndex > 0) {\n title = title.substring(0, extStartIndex);\n }\n if (maxTitleLength > -1) {\n title = title.substring(0, maxTitleLength);\n }\n\n trackUpdate.current = i++;\n trackUpdate.titleCurrent = title;\n updateTrack();\n updateProgressCallback({ written: 0, encrypted: 0, total: 100 });\n try {\n await netmdService?.upload(title, data, wireformat, updateProgressCallback);\n } catch (err) {\n error = err;\n errorMessage = `${file.name}: Error uploading to device`;\n break;\n }\n }\n\n let actionToDispatch: AnyAction[] = [uploadDialogActions.setVisible(false)];\n\n if (error) {\n console.error(error);\n actionToDispatch = actionToDispatch.concat([\n errorDialogAction.setVisible(true),\n errorDialogAction.setErrorMessage(errorMessage),\n ]);\n }\n\n dispatch(batchActions(actionToDispatch));\n listContent()(dispatch);\n };\n}\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as appActions } from '../redux/app-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport Link from '@material-ui/core/Link';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const AboutDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let visible = useShallowEqualSelector(state => state.appState.aboutDialogVisible);\n\n const handleClose = () => {\n dispatch(appActions.showAboutDialog(false));\n };\n\n return (\n \n About Web MiniDisc\n \n Web MiniDisc has been made possible by\n
    \n
  • \n \n FFmpeg\n {' '}\n and{' '}\n \n ffmpegjs\n \n , to read your audio files (wav, mp3, ogg, mp4, etc...).\n
  • \n
  • \n \n Atracdenc\n \n , to support atrac3 encoding (lp2, lp4 audio formats).\n
  • \n
  • \n \n Emscripten\n \n , to run both FFmpeg and Atracdenc in the browser.\n
  • \n
  • \n \n netmd-js\n \n , to send commands to NetMD devices using Javascript.\n
  • \n
  • \n \n linux-minidisc\n \n , to make the netmd-js project possible.\n
  • \n
  • \n \n material-ui\n \n , to build the user interface.\n
  • \n
\n Attribution\n
    \n
  • \n MiniDisc logo from{' '}\n \n https://en.wikipedia.org/wiki/MiniDisc\n \n
  • \n
  • \n MiniDisc icon from{' '}\n \n http://fav.me/d7u3g3g\n \n
  • \n
\n
\n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { batchActions } from 'redux-batched-actions';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\n\nimport { wipeDisc, listContent } from '../redux/actions';\nimport { actions as appActions } from '../redux/app-feature';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { useShallowEqualSelector } from '../utils';\nimport Link from '@material-ui/core/Link';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport EditIcon from '@material-ui/icons/Edit';\nimport GitHubIcon from '@material-ui/icons/GitHub';\nimport DeleteForeverIcon from '@material-ui/icons/DeleteForever';\nimport ExitToAppIcon from '@material-ui/icons/ExitToApp';\nimport InfoIcon from '@material-ui/icons/Info';\nimport ToggleOffIcon from '@material-ui/icons/ToggleOff';\nimport ToggleOnIcon from '@material-ui/icons/ToggleOn';\n\nconst useStyles = makeStyles(theme => ({\n listItemIcon: {\n minWidth: theme.spacing(5),\n },\n}));\n\nexport const TopMenu = function() {\n const classes = useStyles();\n const dispatch = useDispatch();\n\n let { mainView, darkMode } = useShallowEqualSelector(state => state.appState);\n let discTitle = useShallowEqualSelector(state => state.main.disc?.title ?? ``);\n\n const githubLinkRef = React.useRef(null);\n const [menuAnchorEl, setMenuAnchorEl] = React.useState(null);\n const menuOpen = Boolean(menuAnchorEl);\n\n const handleMenuOpen = useCallback(\n (event: React.MouseEvent) => {\n setMenuAnchorEl(event.currentTarget);\n },\n [setMenuAnchorEl]\n );\n\n const handleDarkMode = useCallback(() => {\n dispatch(appActions.setDarkMode(!darkMode));\n }, [dispatch, darkMode]);\n\n const handleMenuClose = useCallback(() => {\n setMenuAnchorEl(null);\n }, [setMenuAnchorEl]);\n\n const handleWipeDisc = useCallback(() => {\n dispatch(wipeDisc());\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleRefresh = useCallback(() => {\n dispatch(listContent());\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleRenameDisc = useCallback(() => {\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(discTitle),\n renameDialogActions.setIndex(-1),\n ])\n );\n handleMenuClose();\n }, [dispatch, handleMenuClose, discTitle]);\n\n const handleExit = useCallback(() => {\n dispatch(appActions.setState('WELCOME'));\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleShowAbout = useCallback(() => {\n dispatch(appActions.showAboutDialog(true));\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleGithubLink = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n if (event.target !== githubLinkRef.current) {\n // Prevent opening the link twice\n githubLinkRef.current?.click();\n }\n handleMenuClose();\n },\n [handleMenuClose]\n );\n\n const menuItems = [];\n if (mainView === 'MAIN') {\n menuItems.push(\n \n \n \n \n Reload TOC\n \n );\n menuItems.push(\n \n \n \n \n Rename Disc\n \n );\n menuItems.push(\n \n \n \n \n Wipe Disc\n \n );\n menuItems.push(\n \n \n \n \n Exit\n \n );\n }\n menuItems.push(\n \n \n {/* */}\n {darkMode ? : }\n \n Dark Mode\n \n );\n menuItems.push(\n \n \n \n \n About\n \n );\n menuItems.push(\n \n \n \n \n \n \n Fork me on GitHub\n \n \n \n );\n\n return (\n \n \n \n \n \n {menuItems}\n \n \n );\n};\n","import React, { useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { pair } from '../redux/actions';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Button from '@material-ui/core/Button';\nimport Typography from '@material-ui/core/Typography';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Box from '@material-ui/core/Box';\nimport Link from '@material-ui/core/Link';\n\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport ChromeIconPath from '../images/chrome-icon.svg';\n\nconst useStyles = makeStyles(theme => ({\n main: {\n position: 'relative',\n flex: '1 1 auto',\n display: 'flex',\n justifyContent: 'center',\n flexDirection: 'column',\n alignItems: 'center',\n },\n button: {\n marginTop: theme.spacing(3),\n minWidth: 150,\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n chromeLogo: {\n marginTop: theme.spacing(1),\n width: 96,\n height: 96,\n },\n why: {\n alignSelf: 'flex-start',\n marginTop: theme.spacing(3),\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n}));\n\nexport const Welcome = (props: {}) => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n const { browserSupported, pairingFailed, pairingMessage } = useShallowEqualSelector(state => state.appState);\n if (pairingMessage.toLowerCase().match(/denied/)) {\n // show linux instructions\n }\n // Access denied.\n\n const [showWhyUnsupported, setWhyUnsupported] = useState(false);\n const handleLearnWhy = (event: React.SyntheticEvent) => {\n event.preventDefault();\n setWhyUnsupported(true);\n };\n\n return (\n \n \n \n Web MiniDisc\n \n \n \n \n Brings NetMD Devices to the Web\n \n \n {browserSupported ? (\n \n \n Press the button to connect to a NetMD device\n \n\n \n\n \n {pairingMessage}\n \n \n ) : (\n \n \n This Web browser is not supported. \n \n Learn Why\n \n \n\n \n \"Chrome\n \n\n \n Try using{' '}\n \n Chrome\n {' '}\n instead\n \n\n {showWhyUnsupported ? (\n <>\n \n Web MiniDisc requires a browser that supports both{' '}\n \n WebUSB\n {' '}\n and{' '}\n \n WebAssembly\n \n .\n \n
    \n
  • WebUSB is needed to control the NetMD device via the USB connection to your computer.
  • \n
  • WebAssembly is used to convert the music to a MiniDisc compatible format
  • \n
\n \n ) : null}\n
\n )}\n
\n \n
\n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { renameTrack, renameDisc } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport TextField from '@material-ui/core/TextField';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const RenameDialog = (props: {}) => {\n let dispatch = useDispatch();\n\n let renameDialogVisible = useShallowEqualSelector(state => state.renameDialog.visible);\n let renameDialogTitle = useShallowEqualSelector(state => state.renameDialog.title);\n let renameDialogIndex = useShallowEqualSelector(state => state.renameDialog.index);\n\n const what = renameDialogIndex < 0 ? `Disc` : `Track`;\n\n const handleCancelRename = () => {\n dispatch(renameDialogActions.setVisible(false));\n };\n\n const handleDoRename = () => {\n if (renameDialogIndex < 0) {\n dispatch(renameDisc({ newName: renameDialogTitle }));\n } else {\n dispatch(renameTrack({ index: renameDialogIndex, newName: renameDialogTitle }));\n }\n };\n\n return (\n \n Rename {what}\n \n {\n event.key === `Enter` && handleDoRename();\n }}\n onChange={event => {\n dispatch(renameDialogActions.setCurrentName(event.target.value.substring(0, 120))); // MAX title length\n }}\n />\n \n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as uploadDialogActions } from '../redux/upload-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Button } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n uploadLabel: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const UploadDialog = (props: {}) => {\n const classes = useStyles();\n const dispatch = useDispatch();\n\n let {\n visible,\n cancelled,\n writtenProgress,\n encryptedProgress,\n totalProgress,\n\n trackTotal,\n trackCurrent,\n trackConverting,\n titleCurrent,\n titleConverting,\n } = useShallowEqualSelector(state => state.uploadDialog);\n\n const handleCancelUpload = useCallback(() => {\n dispatch(uploadDialogActions.setCancelUpload(true));\n }, [dispatch]);\n\n let progressValue = Math.floor((writtenProgress / totalProgress) * 100);\n let bufferValue = Math.floor((encryptedProgress / totalProgress) * 100);\n let convertedValue = Math.floor((trackConverting / trackTotal) * 100);\n return (\n \n Recording...\n \n \n {convertedValue === 100 && trackConverting === trackTotal\n ? `Conversion completed`\n : `Converting ${trackConverting + 1} of ${trackTotal}: ${titleConverting}`}\n \n \n {convertedValue}%\n\n \n Uploading {trackCurrent} of {trackTotal}: {titleCurrent}\n \n \n {progressValue}%\n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const RecordDialog = (props: {}) => {\n const classes = useStyles();\n\n let { visible, trackTotal, trackDone, trackCurrent, titleCurrent } = useShallowEqualSelector(state => state.recordDialog);\n\n let progressValue = Math.round(trackCurrent);\n return (\n \n Recording...\n \n \n {`Recording track ${trackDone + 1} of ${trackTotal}: ${titleCurrent}`}\n \n = 0 ? 'determinate' : 'indeterminate'}\n color=\"primary\"\n value={progressValue}\n />\n {progressValue >= 0 ? `${progressValue}%` : ``}\n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as errorDialogActions } from '../redux/error-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const ErrorDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, error } = useShallowEqualSelector(state => state.errorDialog);\n\n const handleClose = useCallback(() => {\n dispatch(errorDialogActions.setVisible(false));\n }, [dispatch]);\n\n return (\n \n Error\n \n {error}\n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as panicDialogActions } from '../redux/panic-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Typography } from '@material-ui/core';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const PanicDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, dismissed } = useShallowEqualSelector(state => state.panicDialog);\n\n const handleReloadApp = useCallback(() => {\n window.location.reload();\n }, []);\n\n const handleIgnore = useCallback(() => {\n dispatch(panicDialogActions.dismiss());\n }, [dispatch]);\n\n return (\n \n Oops… Something unexpected happened.\n \n \n Try to restart the app. If the error persists, try the followings:\n
    \n
  1. Use your browser in incognito mode.
  2. \n
  3. Use a blank MiniDisc.
  4. \n
  5. Try to use Web MiniDisc on another computer.
  6. \n
\n If this does not solve the error, your unit might not be supported yet or you have encountered a bug. The full error is\n reported in the JS console.\n
\n
\n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { convertAndUpload } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport ToggleButton from '@material-ui/lab/ToggleButton';\nimport ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Typography } from '@material-ui/core';\nimport Select from '@material-ui/core/Select';\nimport Input from '@material-ui/core/Input';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n },\n formControl: {\n minWidth: 60,\n },\n toggleButton: {\n minWidth: 40,\n },\n dialogContent: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n },\n rightBlock: {\n display: 'flex',\n flexDirection: 'column',\n },\n titleFormControl: {\n marginTop: theme.spacing(1),\n },\n}));\n\nexport const ConvertDialog = (props: { files: File[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n let { visible, format, titleSource, titleFormat } = useShallowEqualSelector(state => state.convertDialog);\n\n const handleClose = useCallback(() => {\n dispatch(convertDialogActions.setVisible(false));\n }, [dispatch]);\n\n const handleChangeFormat = useCallback(\n (ev, newFormat) => {\n if (newFormat === null) {\n return;\n }\n dispatch(convertDialogActions.setFormat(newFormat as string));\n },\n [dispatch]\n );\n\n const handleChangeTitleSource = useCallback(\n (ev, newTitleSource) => {\n if (newTitleSource === null) {\n return;\n }\n dispatch(convertDialogActions.setTitleSource(newTitleSource));\n },\n [dispatch]\n );\n\n const handleChangeTitleFormat = useCallback(\n (event: React.ChangeEvent<{ value: any }>) => {\n dispatch(convertDialogActions.setTitleFormat(event.target.value));\n },\n [dispatch]\n );\n\n const handleConvert = useCallback(() => {\n handleClose();\n dispatch(convertAndUpload(props.files, format, titleSource, titleFormat));\n }, [dispatch, props, format, titleSource, titleFormat, handleClose]);\n\n return (\n \n Upload Settings\n \n \n \n Recording Mode\n \n \n \n SP\n \n \n LP2\n \n \n LP4\n \n \n \n
\n \n \n Track title\n \n \n \n Filename\n \n \n Media tags\n \n \n \n {titleSource === 'media' ? (\n \n \n \n ) : null}\n
\n
\n \n \n \n \n \n );\n};\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M53.259 20.337c6.582-5.574 6.582-5.574 14.753-12.436C62.599 6.72 56.322 6 49.946 6c-6.485 0-12.82.747-18.303 1.966 6.675 5.894 7.084 6.191 14.006 12.252 3.48-.293 3.97-.293 7.61.12zM36.927 24.504c.992-1.544 2.25-2.448 5.124-3.474-5.486-4.744-7.34-6.324-14.003-12.173-11.485 3.264-19.33 9.02-20.049 15.647h28.928zM61.159 24.504c14.02 0 20.615 0 30.732-.004-.789-6.629-8.72-12.468-20.269-15.706-2.061 1.766-11.14 9.316-14.827 12.484 1.793.813 3.226 1.35 4.364 3.226zM40.996 30.602c-2.045-.884-3.476-1.935-4.042-3.102-1.056 0-26.431 0-28.782.039C9.53 33.6 16.924 38.847 27.455 41.964c4.236-3.528 8.255-6.948 13.541-11.362zM49.946 45c6.284 0 12.247-.64 17.6-1.79-4.721-4.135-7.729-6.721-13.454-11.689-3.681.692-6.213.59-9.6.068-4.888 4.125-10.974 9.218-13.473 11.324C36.707 44.248 43.137 45 49.946 45zM57.47 30.45c4.38 3.707 9.262 8.068 13.687 11.884 11.265-3.066 19.178-8.5 20.57-14.83H61.18c-.667.999-1.516 1.917-3.71 2.946z\"\n}));\n\nconst SvgMd0 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd0, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md0.a7574f83.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M36.927 24.504c.992-1.544 2.25-2.448 5.124-3.474-5.486-4.744-7.34-6.324-14.003-12.173-11.485 3.264-19.33 9.02-20.049 15.647h28.928zM57.47 30.45c4.38 3.707 9.262 8.068 13.687 11.884 11.265-3.066 19.178-8.5 20.57-14.83H61.18c-.667.999-1.516 1.917-3.71 2.946z\"\n}));\n\nconst SvgMd1 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd1, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md1.1ffb5f6c.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M53.259 20.337c6.582-5.574 6.582-5.574 14.753-12.436C62.599 6.72 56.322 6 49.946 6c-6.485 0-12.82.747-18.303 1.966 6.675 5.894 7.084 6.191 14.006 12.252 3.48-.293 3.97-.293 7.61.12zM49.946 45c6.284 0 12.247-.64 17.6-1.79-4.721-4.135-7.729-6.721-13.454-11.689-3.681.692-6.213.59-9.6.068-4.888 4.125-10.974 9.218-13.473 11.324C36.707 44.248 43.137 45 49.946 45z\"\n}));\n\nconst SvgMd2 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd2, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md2.33dd03b3.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M61.159 24.504c14.02 0 20.615 0 30.732-.004-.789-6.629-8.72-12.468-20.269-15.706-2.061 1.766-11.14 9.316-14.827 12.484 1.793.813 3.226 1.35 4.364 3.226zM40.996 30.602c-2.045-.884-3.476-1.935-4.042-3.102-1.056 0-26.431 0-28.782.039C9.53 33.6 16.924 38.847 27.455 41.964c4.236-3.528 8.255-6.948 13.541-11.362z\"\n}));\n\nconst SvgMd3 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd3, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md3.80f42826.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useCallback, useRef, useEffect, useState } from 'react';\n\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow';\nimport StopIcon from '@material-ui/icons/Stop';\nimport SkipNextIcon from '@material-ui/icons/SkipNext';\nimport SkipPreviousIcon from '@material-ui/icons/SkipPrevious';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Box from '@material-ui/core/Box';\n\nimport { makeStyles } from '@material-ui/core';\nimport { belowDesktop, getSortedTracks, useShallowEqualSelector } from '../utils';\nimport { control } from '../redux/actions';\nimport { useDispatch } from 'react-redux';\n\nimport { ReactComponent as MDIcon0 } from '../images/md0.svg';\nimport { ReactComponent as MDIcon1 } from '../images/md1.svg';\nimport { ReactComponent as MDIcon2 } from '../images/md2.svg';\nimport { ReactComponent as MDIcon3 } from '../images/md3.svg';\n\nconst frames = [MDIcon0, MDIcon1, MDIcon2, MDIcon3];\n\nconst useStyles = makeStyles(theme => ({\n '@keyframes scrollLeft': {\n from: {\n transform: `translateX(0%)`,\n },\n to: {},\n },\n container: {\n display: 'flex',\n flex: '1 1 auto',\n [belowDesktop(theme)]: {\n flexWrap: 'wrap',\n },\n },\n lcd: {\n flex: '1 1 auto',\n position: 'relative',\n marginLeft: theme.spacing(1.5),\n marginRight: theme.spacing(1.5),\n paddingLeft: theme.spacing(3),\n paddingRight: theme.spacing(3),\n borderRadius: theme.spacing(3),\n backgroundColor: theme.palette.background.default,\n minWidth: 150,\n height: 48,\n [belowDesktop(theme)]: {\n marginLeft: 0,\n marginRight: theme.spacing(2),\n },\n },\n lcdText: {\n overflow: 'hidden',\n position: 'relative',\n width: 'calc(100% - 40px)',\n left: 40,\n height: '100%',\n fontFamily: 'LCDDot',\n },\n lcdDisc: {\n position: 'absolute',\n top: 0,\n left: 20,\n },\n lcdDiscIcon: {\n width: 28,\n height: 48,\n '& g': {\n fill: theme.palette.action.active,\n },\n },\n scrollingStatusMessage: {\n position: 'absolute',\n width: '100%',\n whiteSpace: 'nowrap',\n animationName: '$scrollLeft',\n animationTimingFunction: 'linear',\n animationIterationCount: '1',\n top: 15,\n left: 1,\n },\n statusMessage: {\n position: 'absolute',\n width: '100%',\n whiteSpace: 'nowrap',\n top: 15,\n left: 1,\n },\n button: {\n // padding: 8,\n },\n}));\n\nexport const Controls = () => {\n const dispatch = useDispatch();\n // TODO: The shallow equality won't work for these 2 states\n const deviceStatus = useShallowEqualSelector(state => state.main.deviceStatus);\n const disc = useShallowEqualSelector(state => state.main.disc);\n\n const classes = useStyles();\n const handlePrev = useCallback(() => {\n dispatch(control('prev'));\n }, [dispatch]);\n const handlePlay = useCallback(() => {\n dispatch(control('play'));\n }, [dispatch]);\n const handleStop = useCallback(() => {\n dispatch(control('stop'));\n }, [dispatch]);\n const handleNext = useCallback(() => {\n dispatch(control('next'));\n }, [dispatch]);\n\n let message = ``;\n let trackIndex = deviceStatus?.track ?? null;\n let deviceState = deviceStatus?.state ?? null;\n let discPresent = deviceStatus?.discPresent ?? false;\n const tracks = getSortedTracks(disc);\n if (!discPresent) {\n message = ``;\n } else if (deviceState === 'readingTOC') {\n message = 'READING TOC';\n } else if (tracks.length === 0) {\n message = `BLANKDISC`;\n } else if (deviceStatus && deviceStatus.track !== null) {\n message = `${deviceStatus.track + 1} - ` + tracks[deviceStatus.track].title;\n }\n\n const [lcdScroll, setLcdScroll] = useState(0);\n const [lcdScrollDuration, setLcdScrollDuration] = useState(0);\n const [lcdIconFrame, setLcdIconFrame] = useState(0);\n\n // LCD Text scrolling\n const animationDelayInMS = 2000;\n const scrollTimerRef = useRef(null);\n const lcdRef = useRef(null);\n useEffect(() => {\n const updateLCDScroll = () => {\n const domEl = lcdRef.current;\n const textWidth = domEl?.scrollWidth ?? 0;\n const lcdWidth = domEl?.parentElement?.offsetWidth ?? 0;\n const scrollPerc = textWidth > lcdWidth ? (textWidth * 100) / lcdWidth : 0;\n const scrollDurationInSec = textWidth > lcdWidth ? textWidth / 20 : 0; // Compute duration to achieve constant speed\n setLcdScroll(scrollPerc);\n setLcdScrollDuration(scrollDurationInSec);\n if (scrollDurationInSec > 0) {\n scrollTimerRef.current = setTimeout(() => {\n setLcdScroll(0);\n }, scrollDurationInSec * 1000 + 500); // stop animation timer\n }\n };\n\n clearTimeout(scrollTimerRef.current);\n setLcdScroll(0);\n scrollTimerRef.current = setTimeout(() => {\n updateLCDScroll();\n }, animationDelayInMS); // start animation timer\n\n return () => {\n clearTimeout(scrollTimerRef.current); // clear all the timers on unmount\n };\n }, [trackIndex, deviceState, message]);\n\n // Disc animation\n const lcdIconAnimationTimer = useRef(null);\n useEffect(() => {\n clearInterval(lcdIconAnimationTimer.current);\n if (deviceState === 'playing' || deviceState === 'readingTOC') {\n lcdIconAnimationTimer.current = setInterval(() => {\n setLcdIconFrame(1 + (lcdIconFrame % (frames.length - 1)));\n }, 600);\n } else {\n setLcdIconFrame(0);\n }\n return () => {\n clearInterval(lcdIconAnimationTimer.current);\n };\n }, [deviceState, lcdIconFrame]);\n\n const DiscFrame = frames[lcdIconFrame];\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n 0\n ? { animationDuration: `${lcdScrollDuration}s`, transform: `translate(-${lcdScroll}%)` }\n : {}\n }\n >\n {message}\n \n
\n
{discPresent && }
\n
\n
\n );\n};\n","import React, { useEffect, useState, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { recordTracks } from '../redux/actions';\nimport { actions as dumpDialogActions } from '../redux/dump-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport Select from '@material-ui/core/Select';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Typography from '@material-ui/core/Typography';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport { Controls } from './controls';\nimport Box from '@material-ui/core/Box';\nimport serviceRegistry from '../services/registry';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'flex-end',\n justifyContent: 'space-between',\n marginRight: -theme.spacing(2),\n flexFlow: 'wrap',\n },\n formControl: {\n minWidth: 120,\n },\n selectEmpty: {\n marginTop: theme.spacing(2),\n },\n head: {\n textShadow: '0px 0px 12px rgba(150, 150, 150, 1)',\n fontSize: theme.typography.h2.fontSize,\n textAlign: 'center',\n marginBottom: theme.spacing(2),\n },\n}));\n\nexport const DumpDialog = ({ trackIndexes }: { trackIndexes: number[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n const [devices, setDevices] = useState<{ deviceId: string; label: string }[]>([]);\n const [inputDeviceId, setInputDeviceId] = useState('');\n\n let { visible } = useShallowEqualSelector(state => state.dumpDialog);\n\n const handleClose = useCallback(() => {\n setInputDeviceId('');\n serviceRegistry.mediaRecorderService?.stopTestInput();\n dispatch(dumpDialogActions.setVisible(false));\n }, [dispatch]);\n\n const handleChange = useCallback(\n (ev: React.ChangeEvent<{ value: unknown }>) => {\n const deviceId = ev.target.value as string;\n setInputDeviceId(deviceId);\n serviceRegistry.mediaRecorderService?.stopTestInput();\n serviceRegistry.mediaRecorderService?.playTestInput(deviceId);\n },\n [setInputDeviceId]\n );\n\n const handleStartTransfer = useCallback(() => {\n dispatch(recordTracks(trackIndexes, inputDeviceId));\n handleClose();\n }, [trackIndexes, inputDeviceId, dispatch, handleClose]);\n\n useEffect(() => {\n async function updateDeviceList() {\n await navigator.mediaDevices.getUserMedia({ audio: true });\n let devices = await navigator.mediaDevices.enumerateDevices();\n let inputDevices = devices\n .filter(device => device.kind === 'audioinput')\n .map(device => ({ deviceId: device.deviceId, label: device.label }));\n setDevices(inputDevices);\n }\n if (visible) {\n updateDeviceList();\n }\n }, [visible, setDevices]);\n\n return (\n \n Record Selected Tracks\n \n \n {`💻 ⬅ 💽`}\n \n \n 1. Connect your MD Player line-out to your PC audio line-in.\n \n \n 2. Use the controls at the bottom right to play some tracks.\n \n \n 3. Select the input source. You should hear the tracks playing on your PC.\n \n \n 4. Adjust the input gain and the line-out volume of your device.\n \n \n \n \n Input Source\n \n \n \n \n \n \n \n \n \n );\n};\n","import React, { useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport clsx from 'clsx';\nimport { useDropzone } from 'react-dropzone';\nimport { listContent, deleteTracks, moveTrack } from '../redux/actions';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { actions as dumpDialogActions } from '../redux/dump-dialog-feature';\n\nimport { formatTimeFromFrames, getTracks } from 'netmd-js';\n\nimport { belowDesktop, forAnyDesktop, getSortedTracks, useShallowEqualSelector } from '../utils';\n\nimport { lighten, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport Fab from '@material-ui/core/Fab';\nimport AddIcon from '@material-ui/icons/Add';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport Backdrop from '@material-ui/core/Backdrop';\n\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableHead from '@material-ui/core/TableHead';\nimport TableRow from '@material-ui/core/TableRow';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { batchActions } from 'redux-batched-actions';\n\nimport { RenameDialog } from './rename-dialog';\nimport { UploadDialog } from './upload-dialog';\nimport { RecordDialog } from './record-dialog';\nimport { ErrorDialog } from './error-dialog';\nimport { PanicDialog } from './panic-dialog';\nimport { ConvertDialog } from './convert-dialog';\nimport { AboutDialog } from './about-dialog';\nimport { DumpDialog } from './dump-dialog';\nimport { TopMenu } from './topmenu';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport * as BadgeImpl from '@material-ui/core/Badge/Badge';\nimport Button from '@material-ui/core/Button';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst useStyles = makeStyles(theme => ({\n add: {\n position: 'absolute',\n bottom: theme.spacing(3),\n right: theme.spacing(3),\n [belowDesktop(theme)]: {\n bottom: theme.spacing(2),\n },\n },\n main: {\n overflowY: 'auto',\n flex: '1 1 auto',\n marginBottom: theme.spacing(3),\n outline: 'none',\n marginLeft: theme.spacing(-1),\n marginRight: theme.spacing(-1),\n [forAnyDesktop(theme)]: {\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n },\n },\n toolbar: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginLeft: theme.spacing(-3),\n marginRight: theme.spacing(-3),\n },\n },\n toolbarLabel: {\n flex: '1 1 100%',\n },\n toolbarHighlight:\n theme.palette.type === 'light'\n ? {\n color: theme.palette.secondary.main,\n backgroundColor: lighten(theme.palette.secondary.light, 0.85),\n }\n : {\n color: theme.palette.text.primary,\n backgroundColor: theme.palette.secondary.dark,\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n formatBadge: {\n ...(BadgeImpl as any).styles(theme).badge,\n ...(BadgeImpl as any).styles(theme).colorPrimary,\n position: 'static',\n display: 'inline-flex',\n border: `2px solid ${theme.palette.background.paper}`,\n padding: '0 4px',\n verticalAlign: 'middle',\n width: theme.spacing(4.5),\n marginRight: theme.spacing(0.5),\n },\n titleCell: {\n overflow: 'hidden',\n maxWidth: '40ch',\n textOverflow: 'ellipsis',\n // whiteSpace: 'nowrap',\n },\n durationCell: {\n whiteSpace: 'nowrap',\n },\n durationCellTime: {\n verticalAlign: 'middle',\n },\n indexCell: {\n whiteSpace: 'nowrap',\n paddingRight: 0,\n width: `2ch`,\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n remainingTimeTooltip: {\n textDecoration: 'underline',\n textDecorationStyle: 'dotted',\n },\n}));\n\nexport const Main = (props: {}) => {\n let dispatch = useDispatch();\n let disc = useShallowEqualSelector(state => state.main.disc);\n let deviceName = useShallowEqualSelector(state => state.main.deviceName);\n\n const [selected, setSelected] = React.useState([]);\n const selectedCount = selected.length;\n\n const [moveMenuAnchorEl, setMoveMenuAnchorEl] = React.useState(null);\n const handleShowMoveMenu = useCallback((event: React.MouseEvent) => {\n setMoveMenuAnchorEl(event.currentTarget);\n }, []);\n const handleCloseMoveMenu = useCallback(() => {\n setMoveMenuAnchorEl(null);\n }, []);\n const handleMoveSelectedTrack = useCallback(\n (destIndex: number) => {\n dispatch(moveTrack(selected[0], destIndex));\n handleCloseMoveMenu();\n },\n [dispatch, selected, handleCloseMoveMenu]\n );\n\n const handleShowDumpDialog = useCallback(() => {\n dispatch(dumpDialogActions.setVisible(true));\n }, [dispatch]);\n\n useEffect(() => {\n dispatch(listContent());\n }, [dispatch]);\n\n useEffect(() => {\n setSelected([]); // Reset selection if disc changes\n }, [disc]);\n\n let [uploadedFiles, setUploadedFiles] = React.useState([]);\n const onDrop = useCallback(\n (acceptedFiles: File[], rejectedFiles: File[]) => {\n setUploadedFiles(acceptedFiles);\n dispatch(convertDialogActions.setVisible(true));\n },\n [dispatch]\n );\n const { getRootProps, getInputProps, isDragActive, open } = useDropzone({\n onDrop,\n accept: [`audio/*`, `video/mp4`],\n noClick: true,\n });\n\n const classes = useStyles();\n const tracks = getSortedTracks(disc);\n\n // Action Handlers\n const handleSelectClick = (event: React.MouseEvent, item: number) => {\n if (selected.includes(item)) {\n setSelected(selected.filter(i => i !== item));\n } else {\n setSelected([...selected, item]);\n }\n };\n\n const handleSelectAllClick = (event: React.ChangeEvent) => {\n if (selected.length < tracks.length) {\n setSelected(tracks.map(t => t.index));\n } else {\n setSelected([]);\n }\n };\n\n const handleRenameDoubleClick = (event: React.MouseEvent, item: number) => {\n let selectedIndex = item;\n let currentName = getTracks(disc!).find(track => track.index === selectedIndex)?.title ?? '';\n\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(currentName),\n renameDialogActions.setIndex(selectedIndex),\n ])\n );\n };\n\n const handleRenameActionClick = (event: React.MouseEvent) => {\n handleRenameDoubleClick(event, selected[0]);\n };\n\n const handleDeleteSelected = (event: React.MouseEvent) => {\n dispatch(deleteTracks(selected));\n };\n\n return (\n \n \n \n {deviceName || `Loading...`}\n \n \n \n \n {disc !== null ? (\n \n {`${formatTimeFromFrames(disc.left, false)} left of ${formatTimeFromFrames(disc.total, false)} `}\n \n {`${formatTimeFromFrames(disc.left * 2, false)} left in LP2 Mode`}\n
\n {`${formatTimeFromFrames(disc.left * 4, false)} left in LP4 Mode`}\n
\n }\n arrow\n >\n SP Mode\n \n
\n ) : (\n `Loading...`\n )}\n \n 0,\n })}\n >\n {selectedCount > 0 ? (\n 0 && selectedCount < tracks.length}\n checked={selectedCount > 0}\n onChange={handleSelectAllClick}\n inputProps={{ 'aria-label': 'select all tracks' }}\n />\n ) : null}\n {selectedCount > 0 ? (\n \n {selectedCount} selected\n \n ) : (\n \n {disc?.title || `Untitled Disc`}\n \n )}\n {selectedCount === 1 ? (\n \n \n \n \n \n {Array(tracks.length)\n .fill(null)\n .map((_, i) => {\n return (\n handleMoveSelectedTrack(i)}>\n {i + 1}\n \n );\n })}\n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n \n \n \n \n \n \n #\n Title\n Duration\n \n \n \n {tracks.map(track => (\n handleRenameDoubleClick(event, track.index)}\n onClick={event => handleSelectClick(event, track.index)}\n >\n {track.index + 1}\n \n {track.title || `No Title`}\n \n \n {track.encoding}\n {track.duration}\n \n \n ))}\n \n
\n \n Drop your Music to Upload\n \n
\n \n \n \n\n \n \n \n \n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { belowDesktop, forAnyDesktop, forWideDesktop, useShallowEqualSelector } from '../utils';\n\nimport CssBaseline from '@material-ui/core/CssBaseline';\nimport Backdrop from '@material-ui/core/Backdrop';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles, createMuiTheme, ThemeProvider } from '@material-ui/core/styles';\n\nimport { Welcome } from './welcome';\nimport { Main } from './main';\nimport { Controls } from './controls';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport Link from '@material-ui/core/Link';\nimport Box from '@material-ui/core/Box';\nimport { useDispatch } from 'react-redux';\n\nconst useStyles = makeStyles(theme => ({\n layout: {\n width: 'auto',\n height: '100%',\n [forAnyDesktop(theme)]: {\n width: 600,\n marginLeft: 'auto',\n marginRight: 'auto',\n },\n [forWideDesktop(theme)]: {\n width: 700,\n },\n },\n\n paper: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n padding: theme.spacing(2),\n height: 'calc(100% - 20px)',\n [forAnyDesktop(theme)]: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(1),\n padding: theme.spacing(3),\n height: 600,\n },\n [forWideDesktop(theme)]: {\n height: 700,\n },\n },\n bottomBar: {\n display: 'flex',\n alignItems: 'center',\n [belowDesktop(theme)]: {\n flexWrap: 'wrap',\n },\n marginLeft: -theme.spacing(2),\n },\n copyrightTypography: {\n marginRight: theme.spacing(1),\n textAlign: 'center',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n minidiscLogo: {\n width: 48,\n },\n controlsContainer: {\n flex: '0 0 auto',\n width: '100%',\n paddingRight: theme.spacing(8),\n [belowDesktop(theme)]: {\n paddingLeft: 0,\n },\n },\n}));\n\nconst darkTheme = createMuiTheme({\n palette: {\n type: 'dark',\n primary: {\n light: '#6ec6ff',\n main: '#2196f3',\n dark: '#0069c0',\n contrastText: '#fff',\n },\n },\n});\n\nconst lightTheme = createMuiTheme({\n palette: {\n type: 'light',\n },\n});\n\nconst App = () => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n let { mainView, loading, darkMode } = useShallowEqualSelector(state => state.appState);\n\n return (\n \n \n \n\n
\n \n {mainView === 'WELCOME' ? : null}\n {mainView === 'MAIN' ?
: null}\n\n {mainView === 'MAIN' ? : null}\n \n \n {'© '}\n \n Stefano Brilli\n {' '}\n {new Date().getFullYear()}\n {'.'}\n \n
\n\n \n \n \n \n \n );\n};\n\nexport default App;\n","/* eslint no-restricted-globals: 0 */\nimport { getPublicPathFor } from '../utils';\nexport class AtracdencProcess {\n private messageCallback?: (ev: MessageEvent) => void;\n\n constructor(public worker: Worker) {\n worker.onmessage = this.handleMessage.bind(this);\n }\n\n async init() {\n await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'init' });\n });\n }\n\n async encode(data: ArrayBuffer, bitrate: string) {\n let eventData = await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'encode', bitrate, data }, [data]);\n });\n return eventData.data.result as Uint8Array;\n }\n\n terminate() {\n this.worker.terminate();\n }\n\n handleMessage(ev: MessageEvent) {\n this.messageCallback!(ev);\n this.messageCallback = undefined;\n }\n}\n\nif (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n // Worker\n let Module: any;\n onmessage = async (ev: MessageEvent) => {\n const { action, ...others } = ev.data;\n if (action === 'init') {\n self.importScripts(getPublicPathFor(`atracdenc.js`));\n (self as any).Module().then((m: any) => {\n Module = m;\n self.postMessage({ action: 'init' });\n Module.setLogger && Module.setLogger((msg: string, stream: string) => console.log(`${stream}: ${msg}`));\n });\n } else if (action === 'encode') {\n const { bitrate, data } = others;\n const inWavFile = `inWavFile.wav`;\n const outAt3File = `outAt3File.aea`;\n const dataArray = new Uint8Array(data);\n Module.FS.writeFile(`${inWavFile}`, dataArray);\n Module.callMain([`-e`, `atrac3`, `-i`, inWavFile, `-o`, outAt3File, `--bitrate`, bitrate]);\n\n // Read file and trim header (96 bytes)\n let fileStat = Module.FS.stat(outAt3File);\n let size = fileStat.size;\n let tmp = new Uint8Array(size - 96);\n let outAt3FileStream = Module.FS.open(outAt3File, 'r');\n Module.FS.read(outAt3FileStream, tmp, 0, tmp.length, 96);\n Module.FS.close(outAt3FileStream);\n\n let result = tmp.buffer;\n\n self.postMessage(\n {\n action: 'encode',\n result,\n },\n [result]\n );\n }\n };\n} else {\n // Main\n}\n","import { createWorker, setLogging } from '@ffmpeg/ffmpeg';\nimport { AtracdencProcess } from './atracdenc-worker';\nimport { getPublicPathFor } from '../utils';\nconst AtracdencWorker = require('worker-loader!./atracdenc-worker'); // eslint-disable-line import/no-webpack-loader-syntax\n\ninterface LogPayload {\n message: string;\n action: string;\n}\n\nexport interface AudioExportService {\n init(): Promise;\n export(params: { format: string }): Promise;\n info(): Promise<{ format: string | null; input: string | null }>;\n prepare(file: File): Promise;\n}\n\nexport class FFMpegAudioExportService implements AudioExportService {\n public ffmpegProcess: any;\n public atracdencProcess?: AtracdencProcess;\n public loglines: { action: string; message: string }[] = [];\n public inFileName: string = ``;\n public outFileNameNoExt: string = ``;\n\n async init() {\n setLogging(true);\n }\n\n async prepare(file: File) {\n this.loglines = [];\n this.ffmpegProcess = createWorker({\n logger: (payload: LogPayload) => {\n this.loglines.push(payload);\n console.log(payload.action, payload.message);\n },\n corePath: getPublicPathFor('ffmpeg-core.js'),\n workerPath: getPublicPathFor('worker.min.js'),\n });\n await this.ffmpegProcess.load();\n\n this.atracdencProcess = new AtracdencProcess(new AtracdencWorker());\n await this.atracdencProcess.init();\n\n let ext = file.name.split('.').slice(-1);\n if (ext.length === 0) {\n throw new Error(`Unrecognized file format: ${file.name}`);\n }\n\n this.inFileName = `inAudioFile.${ext[0]}`;\n this.outFileNameNoExt = `outAudioFile`;\n\n await this.ffmpegProcess.write(this.inFileName, file);\n }\n\n async info() {\n await this.ffmpegProcess.transcode(this.inFileName, `${this.outFileNameNoExt}.metadata`, `-f ffmetadata`);\n\n let audioFormatRegex = /Audio:\\s(.*?),/; // Actual content\n let inputFormatRegex = /Input #0,\\s(.*?),/; // Container\n let format: string | null = null;\n let input: string | null = null;\n\n for (let line of this.loglines) {\n let match = line.message.match(audioFormatRegex);\n if (match !== null) {\n format = match[1];\n continue;\n }\n match = line.message.match(inputFormatRegex);\n if (match !== null) {\n input = match[1];\n continue;\n }\n if (format !== null && input !== null) {\n break;\n }\n }\n\n return { format, input };\n }\n\n async export({ format }: { format: string }) {\n let result: ArrayBuffer;\n if (format === `SP`) {\n const outFileName = `${this.outFileNameNoExt}.raw`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f s16be -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n result = data.buffer;\n } else {\n const outFileName = `${this.outFileNameNoExt}.wav`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f wav -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n let bitrate: string = `0`;\n switch (format) {\n case `LP2`:\n bitrate = `128`;\n break;\n case `LP105`:\n bitrate = `102`;\n break;\n case `LP4`:\n bitrate = `64`;\n break;\n }\n result = await this.atracdencProcess!.encode(data.buffer, bitrate);\n }\n this.ffmpegProcess.worker.terminate();\n this.atracdencProcess!.terminate();\n return result;\n }\n}\n","/* eslint no-restricted-globals: 0 */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport * as serviceWorker from './serviceWorker';\nimport { NetMDUSBService } from './services/netmd';\nimport { NetMDMockService } from './services/netmd-mock';\nimport serviceRegistry from './services/registry';\n\nimport { store } from './redux/store';\nimport { actions as appActions } from './redux/app-feature';\nimport { actions as mainActions } from './redux/main-feature';\n\nimport App from './components/app';\n\nimport './index.css';\nimport './fonts/fonts.css';\n\nimport { FFMpegAudioExportService } from './services/audio-export';\nimport { MediaRecorderService } from './services/mediarecorder';\n\nserviceRegistry.netmdService = new NetMDUSBService({ debug: true });\n// serviceRegistry.netmdService = new NetMDMockService(); // Uncomment to work without a device attached\nserviceRegistry.audioExportService = new FFMpegAudioExportService();\nserviceRegistry.mediaRecorderService = new MediaRecorderService();\n\n(function setupEventHandlers() {\n window.addEventListener('beforeunload', ev => {\n let isUploading = store.getState().uploadDialog.visible;\n if (!isUploading) {\n return;\n }\n ev.preventDefault();\n ev.returnValue = `Warning! Recording will be interrupted`;\n });\n\n if (navigator && navigator.usb) {\n navigator.usb.ondisconnect = function() {\n store.dispatch(appActions.setState('WELCOME'));\n };\n } else {\n store.dispatch(appActions.setBrowserSupported(false));\n }\n\n // eslint-disable-next-line\n let deferredPrompt: any;\n window.addEventListener('beforeinstallprompt', (e: any) => {\n e.preventDefault();\n deferredPrompt = e;\n });\n})();\n\n(function statusMonitorManager() {\n // Polls the device for its state while playing tracks\n let statusMonitorInterval: ReturnType | null = null;\n let exceptionOccurred: boolean = false;\n\n function shouldMonitorBeRunning(state: ReturnType): boolean {\n return (\n !exceptionOccurred &&\n // App ready\n state.appState.mainView === 'MAIN' &&\n state.appState.loading === false &&\n // Disc playing\n state.main.deviceStatus?.state === 'playing' &&\n // No operational dialogs running\n state.convertDialog.visible === false &&\n state.uploadDialog.visible === false &&\n state.recordDialog.visible === false &&\n state.panicDialog.visible === false &&\n state.errorDialog.visible === false &&\n state.dumpDialog.visible === false\n );\n }\n\n store.subscribe(function() {\n const state = store.getState();\n if (shouldMonitorBeRunning(state) === true && statusMonitorInterval === null) {\n // start monitor\n statusMonitorInterval = setInterval(async () => {\n try {\n const deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n store.dispatch(mainActions.setDeviceStatus(deviceStatus));\n } catch (e) {\n console.error(e);\n exceptionOccurred = true; // Stop monitor on exception\n }\n }, 5000);\n } else if (shouldMonitorBeRunning(state) === false && statusMonitorInterval !== null) {\n // stop monitor\n clearInterval(statusMonitorInterval);\n statusMonitorInterval = null;\n }\n });\n})();\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// serviceWorker.unregister();\nserviceWorker.register();\n","import { sanitizeTitle, getPublicPathFor } from '../utils';\nimport Recorder from 'recorderjs';\n\nexport class MediaRecorderService {\n public recorder: any;\n public stream?: MediaStream;\n public audioContext?: AudioContext;\n public analyserNode?: AnalyserNode;\n public gainNode?: GainNode;\n\n playTestInput(deviceId: string) {\n this.audioContext = new AudioContext();\n this.gainNode = this.audioContext.createGain();\n this.analyserNode = this.audioContext.createAnalyser();\n\n this.initStream(deviceId).then(() => {\n const source = this.audioContext!.createMediaStreamSource(this.stream!);\n source.connect(this.gainNode!);\n this.gainNode!.connect(this.analyserNode!);\n this.analyserNode!.connect(this.audioContext!.destination);\n });\n }\n\n stopTestInput() {\n if (!this.audioContext) {\n return;\n }\n this.audioContext?.close();\n delete this.audioContext;\n this.closeStream();\n }\n\n async initStream(deviceId: string) {\n const recordConstraints = {\n // Try to set the best recording params for ripping the audio tracks\n autoGainControl: false,\n channelCount: 2,\n deviceId: deviceId,\n echoCancellation: false,\n noiseSuppression: false,\n sampleRate: 44100,\n highpassFilter: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia({ audio: recordConstraints });\n\n // Dump recording settings\n const audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length > 0) {\n console.log('Record Setings:', audioTracks[0].getSettings());\n }\n }\n\n async startRecording() {\n this.audioContext = new AudioContext();\n const input = this.audioContext.createMediaStreamSource(this.stream!);\n this.recorder = new Recorder(input, { workerPath: getPublicPathFor(`recorderWorker.js`) });\n this.recorder.record();\n }\n\n async stopRecording() {\n this.recorder.stop();\n }\n\n async closeStream() {\n this.stream?.getTracks().forEach(track => track.stop());\n }\n\n downloadRecorded(title: string) {\n this.recorder.exportWAV((buffer: Blob) => {\n let url = URL.createObjectURL(buffer);\n let a = document.createElement('a');\n document.body.appendChild(a);\n a.style.display = 'none';\n a.href = url;\n a.download = `${sanitizeTitle(title)}.wav`;\n a.click();\n window.URL.revokeObjectURL(url);\n document.body.removeChild(a);\n });\n }\n}\n"],"sourceRoot":""} \ No newline at end of file diff --git a/static/js/main.ec094e9a.chunk.js b/static/js/main.ec094e9a.chunk.js new file mode 100644 index 0000000..8c332ac --- /dev/null +++ b/static/js/main.ec094e9a.chunk.js @@ -0,0 +1,2 @@ +(this.webpackJsonpwebmd=this.webpackJsonpwebmd||[]).push([[0],{277:function(e,t,a){e.exports=a.p+"static/media/chrome-icon.f3b6c54c.svg"},303:function(e,t,a){e.exports=a(544)},327:function(e,t){},329:function(e,t){},361:function(e,t){},362:function(e,t){},495:function(e,t){},497:function(e,t){},527:function(e,t,a){},528:function(e,t,a){},543:function(e,t,a){e.exports=function(){return new Worker(a.p+"ffb88193b05ec63929fd.worker.js")}},544:function(e,t,a){"use strict";a.r(t);var n=a(0),r=a.n(n),l=a(16),i=a.n(l),o=a(18);const c=Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));function s(e,t){navigator.serviceWorker.register(e).then(e=>{e.onupdatefound=()=>{const a=e.installing;null!=a&&(a.onstatechange=()=>{console.log("state change",a.state),"installed"===a.state&&(navigator.serviceWorker.controller?(console.log("New content is available and will be used when all tabs for this page are closed. See https://bit.ly/CRA-PWA."),t&&t.onUpdate&&t.onUpdate(e)):(console.log("Content is cached for offline use."),t&&t.onSuccess&&t.onSuccess(e)))})},e.update()}).catch(e=>{console.error("Error during service worker registration:",e)})}var d=a(31),m=a(21),u=a(264);function p(e){return new Promise(t=>{setTimeout(t,e)})}async function g(e,t){let a=1,n=setInterval(()=>{a++,t(Math.min(100,1e3*a/e*100))},1e3);await p(e),window.clearInterval(n)}function b(e){return Object(o.d)(e,o.b)}function f(e){return`/webminidisc/${e}`}function h(e,t){localStorage.setItem(e,JSON.stringify(t))}function v(e,t){let a=localStorage.getItem(e);if(null===a)return t;try{return JSON.parse(a)}catch(n){return t}}function y(e){return e.normalize("NFD").replace(/[^\x00-\x7F]/g,"")}const E={[m.Encoding.sp]:"SP",[m.Encoding.lp2]:"LP2",[m.Encoding.lp4]:"LP4"};function w(e){let t=[];if(null!==e)for(let r of e.groups)for(let e of r.tracks){var a,n;t.push({index:e.index,title:null!==(a=e.title)&&void 0!==a?a:"Unknown Title",group:null!==(n=r.title)&&void 0!==n?n:"",encoding:E[e.encoding],duration:Object(m.formatTimeFromFrames)(e.duration,!1)})}return t.sort((e,t)=>e.index-t.index),t}function k(e,t,a){const n=a.value;return a.value=async function(...e){const t=this.mutex,a=await t.acquire();try{return await n.apply(this,e)}finally{a()}},a}function C(e){return e.breakpoints.up(600+2*e.spacing(2))}function O(e){return e.breakpoints.down(600+2*e.spacing(2))}function j(e){return e.breakpoints.up(700+2*e.spacing(2))+" and (min-height: 750px)"}var S,D=a(289);const x=a(428);let M=(S=class{constructor({debug:e=!1}){if(this.netmdInterface=void 0,this.logger=void 0,this.mutex=new D.a,this.statusMonitorTimer=void 0,e){const e=(...e)=>{e&&e[0]&&e[0].method&&console.log(...e)};this.logger={debug:e,info:e,warn:e,error:e,child:()=>this.logger}}}async pair(){let e=await Object(m.openNewDevice)(navigator.usb,this.logger);return null!==e&&(this.netmdInterface=e,!0)}async connect(){let e=await Object(m.openPairedDevice)(navigator.usb,this.logger);return null!==e&&(this.netmdInterface=e,!0)}async listContent(){return await Object(m.listContent)(this.netmdInterface)}async getDeviceStatus(){return await Object(m.getDeviceStatus)(this.netmdInterface)}async getDeviceName(){return await this.netmdInterface.netMd.getDeviceName()}async finalize(){await this.netmdInterface.netMd.finalize()}async renameTrack(e,t){t=y(t),await this.netmdInterface.cacheTOC(),await this.netmdInterface.setTrackTitle(e,t),await this.netmdInterface.syncTOC()}async renameDisc(e){const t=await this.netmdInterface.getDiscTitle(),a=await this.netmdInterface._getDiscTitle(),n=a.indexOf("//")>=0,r=a.startsWith("0;");if(e===t)return;let l;l=n?r?a.replace(/^0;.*?\/\//,""!==e?`0;${e}//`:""):`0;${e}//${a}`:e,await this.netmdInterface.cacheTOC(),await this.netmdInterface.setDiscTitle(l),await this.netmdInterface.syncTOC()}async deleteTrack(e){await this.netmdInterface.eraseTrack(e),await p(100)}async wipeDisc(){await this.netmdInterface.eraseDisc()}async moveTrack(e,t){await this.netmdInterface.moveTrack(e,t)}async upload(e,t,a,n){let r=t.byteLength,l=0,i=0;function o(){n({written:l,encrypted:i,total:r})}let c=new x,s=Object(u.makeGetAsyncPacketIteratorOnWorkerThread)(c,({encryptedBytes:e})=>{i=e,o()});e=y(e);let d=new m.MDTrack(e,a,t,524288,s);await Object(m.download)(this.netmdInterface,d,({writtenBytes:e})=>{l=e,o()}),c.terminate()}async play(){await this.netmdInterface.play()}async pause(){await this.netmdInterface.pause()}async stop(){await this.netmdInterface.stop()}async next(){await this.netmdInterface.nextTrack()}async prev(){await this.netmdInterface.previousTrack()}async gotoTrack(e){await this.netmdInterface.gotoTrack(e)}async getPosition(){return await this.netmdInterface.getPosition()}},Object(d.a)(S.prototype,"listContent",[k],Object.getOwnPropertyDescriptor(S.prototype,"listContent"),S.prototype),Object(d.a)(S.prototype,"getDeviceStatus",[k],Object.getOwnPropertyDescriptor(S.prototype,"getDeviceStatus"),S.prototype),Object(d.a)(S.prototype,"getDeviceName",[k],Object.getOwnPropertyDescriptor(S.prototype,"getDeviceName"),S.prototype),Object(d.a)(S.prototype,"finalize",[k],Object.getOwnPropertyDescriptor(S.prototype,"finalize"),S.prototype),Object(d.a)(S.prototype,"renameTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"renameTrack"),S.prototype),Object(d.a)(S.prototype,"renameDisc",[k],Object.getOwnPropertyDescriptor(S.prototype,"renameDisc"),S.prototype),Object(d.a)(S.prototype,"deleteTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"deleteTrack"),S.prototype),Object(d.a)(S.prototype,"wipeDisc",[k],Object.getOwnPropertyDescriptor(S.prototype,"wipeDisc"),S.prototype),Object(d.a)(S.prototype,"moveTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"moveTrack"),S.prototype),Object(d.a)(S.prototype,"play",[k],Object.getOwnPropertyDescriptor(S.prototype,"play"),S.prototype),Object(d.a)(S.prototype,"pause",[k],Object.getOwnPropertyDescriptor(S.prototype,"pause"),S.prototype),Object(d.a)(S.prototype,"stop",[k],Object.getOwnPropertyDescriptor(S.prototype,"stop"),S.prototype),Object(d.a)(S.prototype,"next",[k],Object.getOwnPropertyDescriptor(S.prototype,"next"),S.prototype),Object(d.a)(S.prototype,"prev",[k],Object.getOwnPropertyDescriptor(S.prototype,"prev"),S.prototype),Object(d.a)(S.prototype,"gotoTrack",[k],Object.getOwnPropertyDescriptor(S.prototype,"gotoTrack"),S.prototype),Object(d.a)(S.prototype,"getPosition",[k],Object.getOwnPropertyDescriptor(S.prototype,"getPosition"),S.prototype),S);var T={},N=a(46),P=a(23),I=a(17);const z=Object(P.b)({name:"uploadDialog",initialState:{visible:!1,cancelled:!1,writtenProgress:0,encryptedProgress:0,totalProgress:1,trackTotal:1,trackConverting:0,trackCurrent:0,titleCurrent:"",titleConverting:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setWriteProgress:(e,t)=>{e.encryptedProgress=t.payload.encrypted,e.writtenProgress=t.payload.written,e.totalProgress=t.payload.total},setCancelUpload:(e,t)=>{e.cancelled=t.payload},setTrackProgress:(e,t)=>{e.trackTotal=t.payload.total,e.trackCurrent=t.payload.current,e.trackConverting=t.payload.converting,e.titleCurrent=t.payload.titleCurrent,e.titleConverting=t.payload.titleConverting}}}),{reducer:R,actions:F}=z;var W=Object(I.enableBatching)(R);const L=Object(P.b)({name:"renameDialog",initialState:{visible:!1,title:"",index:-1},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setCurrentName:(e,t)=>{e.title=t.payload},setIndex:(e,t)=>{e.index=t.payload}}}),{reducer:A,actions:B}=L;var $=Object(I.enableBatching)(A);const V={visible:!1,error:""},U=Object(P.b)({name:"errorDialog",initialState:V,reducers:{setVisible:(e,t)=>{e.visible=t.payload},setErrorMessage:(e,t)=>{e.error=`${t.payload}`}}}),{actions:_,reducer:G}=U;var H=Object(I.enableBatching)(G);const J=Object(P.b)({name:"panicDialog",initialState:{visible:!1,dismissed:!1},reducers:{setVisible:(e,t)=>{e.visible=t.payload},dismiss:(e,t)=>{e.visible=!1,e.dismissed=!0}}}),{actions:Y,reducer:q}=J;var K=Object(I.enableBatching)(q);const X={visible:!1,format:v("uploadFormat","LP2"),titleSource:v("trackTitleSource","file"),titleFormat:v("trackTitleFormat","title")},Q=Object(P.b)({name:"convertDialog",initialState:X,reducers:{setVisible:(e,t)=>{e.visible=t.payload},setFormat:(e,t)=>{e.format=t.payload,h("uploadFormat",e.format)},setTitleSource:(e,t)=>{e.titleSource=t.payload,h("trackTitleSource",e.titleSource)},setTitleFormat:(e,t)=>{e.titleFormat=t.payload,h("trackTitleFormat",e.titleFormat)}}}),{actions:Z,reducer:ee}=Q;var te=Object(I.enableBatching)(ee);const ae=Object(P.b)({name:"dumpDialog",initialState:{visible:!1,inputDeviceId:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setInputDeviceId:(e,t)=>{e.inputDeviceId=t.payload}}}),{reducer:ne,actions:re}=ae;var le=Object(I.enableBatching)(ne);const ie=Object(P.b)({name:"recordDialog",initialState:{visible:!1,trackTotal:1,trackDone:0,trackCurrent:0,titleCurrent:""},reducers:{setVisible:(e,t)=>{e.visible=t.payload},setProgress:(e,t)=>{e.trackTotal=t.payload.trackTotal,e.trackDone=t.payload.trackDone,e.trackCurrent=t.payload.trackCurrent,e.titleCurrent=t.payload.titleCurrent}}}),{reducer:oe,actions:ce}=ie;var se=Object(I.enableBatching)(oe);const de={mainView:"WELCOME",loading:!1,pairingFailed:!1,pairingMessage:"",browserSupported:!0,darkMode:v("darkMode",!1),aboutDialogVisible:!1},me=Object(P.b)({name:"app",initialState:de,reducers:{setState:(e,t)=>{e.mainView=t.payload},setLoading:(e,t)=>{e.loading=t.payload},setPairingFailed:(e,t)=>{e.pairingFailed=t.payload},setPairingMessage:(e,t)=>{e.pairingMessage=t.payload},setBrowserSupported:(e,t)=>{e.browserSupported=t.payload},setDarkMode:(e,t)=>{e.darkMode=t.payload,h("darkMode",e.darkMode)},showAboutDialog:(e,t)=>{e.aboutDialogVisible=t.payload}}}),{reducer:ue,actions:pe}=me;var ge=Object(I.enableBatching)(ue);const be=Object(P.b)({name:"main",initialState:{disc:null,deviceName:"",deviceStatus:null},reducers:{setDisc:(e,t)=>{e.disc=t.payload},setDeviceName:(e,t)=>{e.deviceName=t.payload},setDeviceStatus:(e,t)=>{e.deviceStatus=t.payload}}}),{reducer:fe,actions:he}=be;var ve=Object(I.enableBatching)(fe);let ye=Object(N.c)({renameDialog:$,uploadDialog:W,errorDialog:H,panicDialog:K,convertDialog:te,dumpDialog:le,recordDialog:se,appState:ge,main:ve});const Ee=pe.setState.toString(),we=Object(P.a)({reducer:function(...e){const[t,a]=e;return a.type===Ee&&"WELCOME"===a.payload?ke:ye(...e)},middleware:[e=>e=>async t=>{try{await e(t)}catch(a){console.error(a),e(Y.setVisible(!0))}},...Object(P.c)()]}),ke=Object.freeze(we.getState());var Ce=a(609),Oe=a(549),je=a(610),Se=a(589),De=a(287),xe=a(601),Me=a(265);function Te(e,t){return async function(a,n){switch(e){case"play":await T.netmdService.play();break;case"stop":await T.netmdService.stop();break;case"next":await T.netmdService.next();break;case"prev":await T.netmdService.prev();break;case"goto":t&&"number"===typeof t&&t>=0&&await T.netmdService.gotoTrack(t)}await p(500);try{let e=await T.netmdService.getDeviceStatus();a(he.setDeviceStatus(e))}catch(r){console.log("control: Cannot get device status")}}}function Ne(){return async function(e){e(pe.setLoading(!0));let t=await T.netmdService.listContent(),a=await T.netmdService.getDeviceName(),n=null;try{n=await T.netmdService.getDeviceStatus()}catch(r){console.log("listContent: Cannot get device status")}e(Object(I.batchActions)([he.setDisc(t),he.setDeviceName(a),he.setDeviceStatus(n),pe.setLoading(!1)]))}}const Pe={SP:m.Wireformat.pcm,LP2:m.Wireformat.lp2,LP105:m.Wireformat.l105kbps,LP4:m.Wireformat.lp4};async function Ie(e,t){var a,n,r;const l=await e.arrayBuffer(),i=new Blob([new Uint8Array(l)]);let o=await Me.parseBlob(i);const c=null!==(a=o.common.title)&&void 0!==a?a:"Unknown Title",s=null!==(n=o.common.artist)&&void 0!==n?n:"Unknown Artist",d=null!==(r=o.common.album)&&void 0!==r?r:"Unknown Album";switch(t){case"title":return c;case"artist-title":return`${s} - ${c}`;case"album-title":return`${d} - ${c}`;case"artist-album-title":return`${s} - ${d} - ${c}`}}function ze(e,t,a,n){return async function(r,l){const{audioExportService:i,netmdService:o}=T,c=Pe[t];await(null===o||void 0===o?void 0:o.stop()),r(Object(I.batchActions)([F.setVisible(!0),F.setCancelUpload(!1)]));const s=({written:e,encrypted:t,total:a})=>{r(F.setWriteProgress({written:e,encrypted:t,total:a}))},d=()=>l().uploadDialog.cancelled;let u={current:0,converting:0,total:e.length,titleCurrent:"",titleConverting:""};const p=()=>{r(F.setTrackProgress(u))};let g=l().main.disc,b=g?1700-Object(m.getTracks)(g).map(e=>e.title||"").reduce((e,t)=>e+t.length,0):-1;let f;b=Math.floor(b/e.length);let h="",v=1;for await(let m of async function*(e){let a=[],n=0;!function r(){if(n===e.length||d())return u.converting=n,u.titleConverting="",void p();let l=e[n];u.converting=n,u.titleConverting=l.name,p(),n++,a.push(new Promise(async(e,a)=>{let n;try{await i.prepare(l),n=await i.export({format:t}),r(),e({file:l,data:n})}catch(o){f=o,h=`${l.name}: Unsupported or unrecognized format`,a(o)}}))}();let r=0;for(;r0&&(r=r.substring(0,l)),b>-1&&(r=r.substring(0,b)),u.current=v++,u.titleCurrent=r,p(),s({written:0,encrypted:0,total:100});try{await(null===o||void 0===o?void 0:o.upload(r,t,c,s))}catch(w){f=w,h=`${e.name}: Error uploading to device`;break}}let E=[F.setVisible(!1)];f&&(console.error(f),E=E.concat([_.setVisible(!0),_.setErrorMessage(h)])),r(Object(I.batchActions)(E)),Ne()(r)}}var Re=a(588),Fe=a(83),We=a(595),Le=a(596),Ae=a(614),Be=a(586),$e=a(580),Ve=a(587),Ue=a(584),_e=a(585),Ge=a(583),He=a(579);const Je=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Ye=e=>{const t=Object(o.c)();let a=b(e=>e.appState.aboutDialogVisible);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:Je,"aria-labelledby":"about-dialog-slide-title"},r.a.createElement(Ge.a,{id:"about-dialog-slide-title"},"About Web MiniDisc"),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,null,"Web MiniDisc has been made possible by"),r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://www.ffmpeg.org/",target:"_blank"},"FFmpeg")," ","and"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/ffmpegjs/FFmpeg",target:"_blank"},"ffmpegjs"),", to read your audio files (wav, mp3, ogg, mp4, etc...)."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/dcherednik/atracdenc/",target:"_blank"},"Atracdenc"),", to support atrac3 encoding (lp2, lp4 audio formats)."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://emscripten.org/",target:"_blank"},"Emscripten"),", to run both FFmpeg and Atracdenc in the browser."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/netmd-js",target:"_blank"},"netmd-js"),", to send commands to NetMD devices using Javascript."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/glaubitz/linux-minidisc",target:"_blank"},"linux-minidisc"),", to make the netmd-js project possible."),r.a.createElement("li",null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://material-ui.com/",target:"_blank"},"material-ui"),", to build the user interface.")),r.a.createElement(_e.a,null,"Attribution"),r.a.createElement("ul",null,r.a.createElement("li",null,"MiniDisc logo from"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://en.wikipedia.org/wiki/MiniDisc",target:"_blank"},"https://en.wikipedia.org/wiki/MiniDisc")),r.a.createElement("li",null,"MiniDisc icon from"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://www.deviantart.com/blinkybill/art/Sony-MiniDisc-Plastic-Icon-473812540",target:"_blank"},"http://fav.me/d7u3g3g")))),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:()=>{t(pe.showAboutDialog(!1))}},"Close")))};var qe=a(592),Ke=a(290),Xe=a(615),Qe=a(276),Ze=a.n(Qe),et=a(590),tt=a(591),at=a(269),nt=a.n(at),rt=a(142),lt=a.n(rt),it=a(275),ot=a.n(it),ct=a(270),st=a.n(ct),dt=a(271),mt=a.n(dt),ut=a(274),pt=a.n(ut),gt=a(273),bt=a.n(gt),ft=a(272),ht=a.n(ft);const vt=Object(Se.a)(e=>({listItemIcon:{minWidth:e.spacing(5)}})),yt=function(){const e=vt(),t=Object(o.c)();let{mainView:a,darkMode:l}=b(e=>e.appState),i=b(e=>{var t,a;return null!==(t=null===(a=e.main.disc)||void 0===a?void 0:a.title)&&void 0!==t?t:""});const c=r.a.useRef(null),[s,d]=r.a.useState(null),m=Boolean(s),u=Object(n.useCallback)(e=>{d(e.currentTarget)},[d]),p=Object(n.useCallback)(()=>{t(pe.setDarkMode(!l))},[t,l]),g=Object(n.useCallback)(()=>{d(null)},[d]),f=Object(n.useCallback)(()=>{t((async function(e){if(!window.confirm("Proceed with Wipe Disc? This operation cannot be undone."))return;const{netmdService:t}=T;e(pe.setLoading(!0)),await t.wipeDisc(),Ne()(e)})),g()},[t,g]),h=Object(n.useCallback)(()=>{t(Ne()),g()},[t,g]),v=Object(n.useCallback)(()=>{t(Object(I.batchActions)([B.setVisible(!0),B.setCurrentName(i),B.setIndex(-1)])),g()},[t,g,i]),y=Object(n.useCallback)(()=>{t(pe.setState("WELCOME")),g()},[t,g]),E=Object(n.useCallback)(()=>{t(pe.showAboutDialog(!0)),g()},[t,g]),w=Object(n.useCallback)(e=>{var t;(e.stopPropagation(),e.target!==c.current)&&(null===(t=c.current)||void 0===t||t.click());g()},[g]),k=[];return"MAIN"===a&&(k.push(r.a.createElement(Xe.a,{key:"update",onClick:h},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(nt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Reload TOC"))),k.push(r.a.createElement(Xe.a,{key:"title",onClick:v},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(lt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Rename Disc"))),k.push(r.a.createElement(Xe.a,{key:"wipe",onClick:f},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(st.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Wipe Disc"))),k.push(r.a.createElement(Xe.a,{key:"exit",onClick:y},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(mt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Exit")))),k.push(r.a.createElement(Xe.a,{key:"darkMode",onClick:p},r.a.createElement(et.a,{className:e.listItemIcon},l?r.a.createElement(ht.a,{fontSize:"small"}):r.a.createElement(bt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"Dark Mode"))),k.push(r.a.createElement(Xe.a,{key:"about",onClick:E},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(pt.a,{fontSize:"small"})),r.a.createElement(tt.a,null,"About"))),k.push(r.a.createElement(Xe.a,{key:"github",onClick:w},r.a.createElement(et.a,{className:e.listItemIcon},r.a.createElement(ot.a,{fontSize:"small"})),r.a.createElement(tt.a,null,r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"https://github.com/cybercase/webminidisc",target:"_blank",ref:c,onClick:w},"Fork me on GitHub")))),r.a.createElement(r.a.Fragment,null,r.a.createElement(qe.a,{"aria-label":"actions","aria-controls":"actions-menu","aria-haspopup":"true",onClick:u},r.a.createElement(Ze.a,null)),r.a.createElement(Ke.a,{id:"actions-menu",anchorEl:s,keepMounted:!0,open:m,onClose:g},k))};var Et=a(277),wt=a.n(Et);const kt=Object(Se.a)(e=>({main:{position:"relative",flex:"1 1 auto",display:"flex",justifyContent:"center",flexDirection:"column",alignItems:"center"},button:{marginTop:e.spacing(3),minWidth:150},spacing:{marginTop:e.spacing(1)},chromeLogo:{marginTop:e.spacing(1),width:96,height:96},why:{alignSelf:"flex-start",marginTop:e.spacing(3)},headBox:{display:"flex",justifyContent:"space-between"}})),Ct=e=>{const t=kt(),a=Object(o.c)(),{browserSupported:l,pairingFailed:i,pairingMessage:c}=b(e=>e.appState);c.toLowerCase().match(/denied/);const[s,d]=Object(n.useState)(!1);return r.a.createElement(r.a.Fragment,null,r.a.createElement(Ae.a,{className:t.headBox},r.a.createElement(Fe.a,{component:"h1",variant:"h4"},"Web MiniDisc"),r.a.createElement(yt,null)),r.a.createElement(Fe.a,{component:"h2",variant:"body2"},"Brings NetMD Devices to the Web"),r.a.createElement(Ae.a,{className:t.main},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Press the button to connect to a NetMD device"),r.a.createElement(Re.a,{variant:"contained",color:"primary",onClick:()=>a((async function(e,t){e(pe.setPairingFailed(!1)),await T.audioExportService.init();try{if(await T.netmdService.connect())return void e(pe.setState("MAIN"))}catch(a){console.error(a)}try{if(await T.netmdService.pair())return void e(pe.setState("MAIN"));e(Object(I.batchActions)([pe.setPairingMessage("Connection Failed"),pe.setPairingFailed(!0)]))}catch(a){console.error(a);let t=a.message;e(Object(I.batchActions)([pe.setPairingMessage(t),pe.setPairingFailed(!0)]))}})),className:t.button},"Connect"),r.a.createElement(We.a,{error:!0,className:t.spacing,style:{visibility:i?"visible":"hidden"}},r.a.createElement(Le.a,null,c))):r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"This Web browser is not supported.\xa0",r.a.createElement(Be.a,{rel:"noopener noreferrer",href:"#",onClick:e=>{e.preventDefault(),d(!0)}},"Learn Why")),r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},r.a.createElement("img",{alt:"Chrome Logo",src:wt.a,className:t.chromeLogo})),r.a.createElement(Fe.a,{component:"h2",variant:"subtitle1",align:"center",className:t.spacing},"Try using"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://www.google.com/chrome/"},"Chrome")," ","instead"),s?r.a.createElement(r.a.Fragment,null,r.a.createElement(Fe.a,{component:"p",variant:"body2",className:t.why},"Web MiniDisc requires a browser that supports both"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://wicg.github.io/webusb/"},"WebUSB")," ","and"," ",r.a.createElement(Be.a,{rel:"noopener noreferrer",target:"_blank",href:"https://webassembly.org/"},"WebAssembly"),"."),r.a.createElement("ul",null,r.a.createElement("li",null,"WebUSB is needed to control the NetMD device via the USB connection to your computer."),r.a.createElement("li",null,"WebAssembly is used to convert the music to a MiniDisc compatible format"))):null)),r.a.createElement(Ye,null))};var Ot=a(3),jt=a(288),St=a(12),Dt=a(608),xt=a(285),Mt=a.n(xt),Tt=a(284),Nt=a.n(Tt),Pt=a(603),It=a(607),zt=a(606),Rt=a(604),Ft=a(605),Wt=a(602),Lt=a(616),At=a(613);const Bt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),$t=e=>{let t=Object(o.c)(),a=b(e=>e.renameDialog.visible),n=b(e=>e.renameDialog.title),l=b(e=>e.renameDialog.index);const i=l<0?"Disc":"Track",c=()=>{t(B.setVisible(!1))},s=()=>{t(l<0?function({newName:e}){return async function(t){const{netmdService:a}=T;await a.renameDisc(e),t(B.setVisible(!1)),Ne()(t)}}({newName:n}):function({index:e,newName:t}){return async function(a){const{netmdService:n}=T;a(B.setVisible(!1));try{await n.renameTrack(e,t)}catch(r){console.error(r),a(Object(I.batchActions)([_.setVisible(!0),_.setErrorMessage("Rename failed.")]))}Ne()(a)}}({index:l,newName:n}))};return r.a.createElement($e.a,{open:a,onClose:c,maxWidth:"sm",fullWidth:!0,TransitionComponent:Bt,"aria-labelledby":"rename-dialog-title"},r.a.createElement(Ge.a,{id:"rename-dialog-title"},"Rename ",i),r.a.createElement(Ue.a,null,r.a.createElement(At.a,{autoFocus:!0,id:"name",label:`${i} Name`,type:"text",fullWidth:!0,value:n,onKeyDown:e=>{"Enter"===e.key&&s()},onChange:e=>{t(B.setCurrentName(e.target.value.substring(0,120)))}})),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:c},"Cancel"),r.a.createElement(Re.a,{color:"primary",onClick:s},"Rename")))};var Vt=a(599);const Ut=Object(Se.a)(e=>({progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)},uploadLabel:{marginTop:e.spacing(3)}})),_t=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Gt=e=>{const t=Ut(),a=Object(o.c)();let{visible:l,cancelled:i,writtenProgress:c,encryptedProgress:s,totalProgress:d,trackTotal:m,trackCurrent:u,trackConverting:p,titleCurrent:g,titleConverting:f}=b(e=>e.uploadDialog);const h=Object(n.useCallback)(()=>{a(F.setCancelUpload(!0))},[a]);let v=Math.floor(c/d*100),y=Math.floor(s/d*100),E=Math.floor(p/m*100);return r.a.createElement($e.a,{open:l,maxWidth:"sm",fullWidth:!0,TransitionComponent:_t,"aria-labelledby":"alert-dialog-slide-title","aria-describedby":"alert-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Recording..."),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"alert-dialog-slide-description"},100===E&&p===m?"Conversion completed":`Converting ${p+1} of ${m}: ${f}`),r.a.createElement(Vt.a,{className:t.progressBar,variant:0===E?"indeterminate":"determinate",color:"primary",value:E}),r.a.createElement(Ae.a,{className:t.progressPerc},E,"%"),r.a.createElement(_e.a,{id:"alert-dialog-slide-description",className:t.uploadLabel},"Uploading ",u," of ",m,": ",g),r.a.createElement(Vt.a,{className:t.progressBar,variant:"buffer",color:"secondary",value:v,valueBuffer:y}),r.a.createElement(Ae.a,{className:t.progressPerc},v,"%")),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{disabled:i,onClick:h},i?"Stopping after current track...":"Cancel Recording")))},Ht=Object(Se.a)(e=>({progressPerc:{marginTop:e.spacing(1)},progressBar:{marginTop:e.spacing(3)}})),Jt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Yt=e=>{const t=Ht();let{visible:a,trackTotal:n,trackDone:l,trackCurrent:i,titleCurrent:o}=b(e=>e.recordDialog),c=Math.round(i);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:Jt,"aria-labelledby":"record-dialog-slide-title","aria-describedby":"record-dialog-slide-description"},r.a.createElement(Ge.a,{id:"record-dialog-slide-title"},"Recording..."),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"record-dialog-slide-description"},`Recording track ${l+1} of ${n}: ${o}`),r.a.createElement(Vt.a,{className:t.progressBar,variant:i>=0?"determinate":"indeterminate",color:"primary",value:c}),r.a.createElement(Ae.a,{className:t.progressPerc},c>=0?`${c}%`:"")),r.a.createElement(Ve.a,null))},qt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Kt=e=>{const t=Object(o.c)();let{visible:a,error:l}=b(e=>e.errorDialog);const i=Object(n.useCallback)(()=>{t(_.setVisible(!1))},[t]);return r.a.createElement($e.a,{open:a,maxWidth:"sm",fullWidth:!0,TransitionComponent:qt,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Error"),r.a.createElement(Ue.a,null,r.a.createElement(_e.a,{id:"alert-dialog-slide-description"},l)),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:i},"Close")))},Xt=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),Qt=e=>{const t=Object(o.c)();let{visible:a,dismissed:l}=b(e=>e.panicDialog);const i=Object(n.useCallback)(()=>{window.location.reload()},[]),c=Object(n.useCallback)(()=>{t(Y.dismiss())},[t]);return r.a.createElement($e.a,{open:a&&!l,maxWidth:"sm",fullWidth:!0,scroll:"paper",TransitionComponent:Xt,"aria-labelledby":"error-dialog-slide-title","aria-describedby":"error-dialog-slide-description"},r.a.createElement(Ge.a,{id:"alert-dialog-slide-title"},"Oops\u2026 Something unexpected happened."),r.a.createElement(Ue.a,null,r.a.createElement(Fe.a,{color:"textSecondary",variant:"body1",component:"div"},"Try to restart the app. If the error persists, try the followings:",r.a.createElement("ol",null,r.a.createElement("li",null,"Use your browser in incognito mode."),r.a.createElement("li",null,"Use a blank MiniDisc."),r.a.createElement("li",null,"Try to use Web MiniDisc on another computer.")),"If this does not solve the error, your unit might not be supported yet or you have encountered a bug. The full error is reported in the JS console.")),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:c,size:"small"},"Ignore and Continue"),r.a.createElement(Re.a,{onClick:i,color:"primary"},"Restart the App")))};var Zt=a(600),ea=a(618),ta=a(612),aa=a(597);const na=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),ra=Object(Se.a)(e=>({container:{display:"flex",flexDirection:"row"},formControl:{minWidth:60},toggleButton:{minWidth:40},dialogContent:{display:"flex",flexWrap:"wrap",justifyContent:"space-between"},rightBlock:{display:"flex",flexDirection:"column"},titleFormControl:{marginTop:e.spacing(1)}})),la=e=>{const t=Object(o.c)(),a=ra();let{visible:l,format:i,titleSource:c,titleFormat:s}=b(e=>e.convertDialog);const d=Object(n.useCallback)(()=>{t(Z.setVisible(!1))},[t]),m=Object(n.useCallback)((e,a)=>{null!==a&&t(Z.setFormat(a))},[t]),u=Object(n.useCallback)((e,a)=>{null!==a&&t(Z.setTitleSource(a))},[t]),p=Object(n.useCallback)(e=>{t(Z.setTitleFormat(e.target.value))},[t]),g=Object(n.useCallback)(()=>{d(),t(ze(e.files,i,c,s))},[t,e,i,c,s,d]);return r.a.createElement($e.a,{open:l,maxWidth:"xs",fullWidth:!0,TransitionComponent:na,"aria-labelledby":"convert-dialog-slide-title","aria-describedby":"convert-dialog-slide-description"},r.a.createElement(Ge.a,{id:"convert-dialog-slide-title"},"Upload Settings"),r.a.createElement(Ue.a,{className:a.dialogContent},r.a.createElement(We.a,null,r.a.createElement(Fe.a,{component:"label",variant:"caption",color:"textSecondary"},"Recording Mode"),r.a.createElement(ea.a,{value:i,exclusive:!0,onChange:m,size:"small"},r.a.createElement(Zt.a,{className:a.toggleButton,value:"SP"},"SP"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"LP2"},"LP2"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"LP4"},"LP4"))),r.a.createElement("div",{className:a.rightBlock},r.a.createElement(We.a,{className:a.formControl},r.a.createElement(Fe.a,{component:"label",variant:"caption",color:"textSecondary"},"Track title"),r.a.createElement(ea.a,{value:c,exclusive:!0,onChange:u,size:"small"},r.a.createElement(Zt.a,{className:a.toggleButton,value:"file"},"Filename"),r.a.createElement(Zt.a,{className:a.toggleButton,value:"media"},"Media tags"))),"media"===c?r.a.createElement(We.a,{className:a.titleFormControl},r.a.createElement(ta.a,{value:s,color:"secondary",input:r.a.createElement(aa.a,null),onChange:p},r.a.createElement(Xe.a,{value:"title"},"Title"),r.a.createElement(Xe.a,{value:"album-title"},"Album - Title"),r.a.createElement(Xe.a,{value:"artist-title"},"Artist - Title"),r.a.createElement(Xe.a,{value:"artist-album-title"},"Artist - Album - Title"))):null)),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:d},"Cancel"),r.a.createElement(Re.a,{onClick:g},"Ok")))};var ia=a(280),oa=a.n(ia),ca=a(281),sa=a.n(ca),da=a(282),ma=a.n(da),ua=a(279),pa=a.n(ua);function ga(){return(ga=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",ga({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,ba),ha=r.a.forwardRef((e,t)=>r.a.createElement(fa,ga({svgRef:t},e)));a.p;function va(){return(va=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",va({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,ya),wa=r.a.forwardRef((e,t)=>r.a.createElement(Ea,va({svgRef:t},e)));a.p;function ka(){return(ka=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",ka({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,Ca),ja=r.a.forwardRef((e,t)=>r.a.createElement(Oa,ka({svgRef:t},e)));a.p;function Sa(){return(Sa=Object.assign||function(e){for(var t=1;tr.a.createElement("svg",Sa({width:98,height:52,viewBox:"0 0 98 52",ref:e},a),t?r.a.createElement("title",null,t):null,Da),Ma=r.a.forwardRef((e,t)=>r.a.createElement(xa,Sa({svgRef:t},e)));a.p;const Ta=[ha,wa,ja,Ma],Na=Object(Se.a)(e=>({"@keyframes scrollLeft":{from:{transform:"translateX(0%)"},to:{}},container:{display:"flex",flex:"1 1 auto",[O(e)]:{flexWrap:"wrap"}},lcd:{flex:"1 1 auto",position:"relative",marginLeft:e.spacing(1.5),marginRight:e.spacing(1.5),paddingLeft:e.spacing(3),paddingRight:e.spacing(3),borderRadius:e.spacing(3),backgroundColor:e.palette.background.default,minWidth:150,height:48,[O(e)]:{marginLeft:0,marginRight:e.spacing(2)}},lcdText:{overflow:"hidden",position:"relative",width:"calc(100% - 40px)",left:40,height:"100%",fontFamily:"LCDDot"},lcdDisc:{position:"absolute",top:0,left:20},lcdDiscIcon:{width:28,height:48,"& g":{fill:e.palette.action.active}},scrollingStatusMessage:{position:"absolute",width:"100%",whiteSpace:"nowrap",animationName:"$scrollLeft",animationTimingFunction:"linear",animationIterationCount:"1",top:15,left:1},statusMessage:{position:"absolute",width:"100%",whiteSpace:"nowrap",top:15,left:1},button:{}})),Pa=()=>{var e,t,a;const l=Object(o.c)(),i=b(e=>e.main.deviceStatus),c=b(e=>e.main.disc),s=Na(),d=Object(n.useCallback)(()=>{l(Te("prev"))},[l]),m=Object(n.useCallback)(()=>{l(Te("play"))},[l]),u=Object(n.useCallback)(()=>{l(Te("stop"))},[l]),p=Object(n.useCallback)(()=>{l(Te("next"))},[l]);let g="",f=null!==(e=null===i||void 0===i?void 0:i.track)&&void 0!==e?e:null,h=null!==(t=null===i||void 0===i?void 0:i.state)&&void 0!==t?t:null,v=null!==(a=null===i||void 0===i?void 0:i.discPresent)&&void 0!==a&&a;const y=w(c);v?"readingTOC"===h?g="READING TOC":0===y.length?g="BLANKDISC":i&&null!==i.track&&(g=`${i.track+1} - `+y[i.track].title):g="";const[E,k]=Object(n.useState)(0),[C,O]=Object(n.useState)(0),[j,S]=Object(n.useState)(0),D=Object(n.useRef)(null),x=Object(n.useRef)(null);Object(n.useEffect)(()=>(clearTimeout(D.current),k(0),D.current=setTimeout(()=>{(()=>{var e,t,a;const n=x.current,r=null!==(e=null===n||void 0===n?void 0:n.scrollWidth)&&void 0!==e?e:0,l=null!==(t=null===n||void 0===n?void 0:null===(a=n.parentElement)||void 0===a?void 0:a.offsetWidth)&&void 0!==t?t:0,i=r>l?r/20:0;k(r>l?100*r/l:0),O(i),i>0&&(D.current=setTimeout(()=>{k(0)},1e3*i+500))})()},2e3),()=>{clearTimeout(D.current)}),[f,h,g]);const M=Object(n.useRef)(null);Object(n.useEffect)(()=>(clearInterval(M.current),"playing"===h||"readingTOC"===h?M.current=setInterval(()=>{S(1+j%(Ta.length-1))},600):S(0),()=>{clearInterval(M.current)}),[h,j]);const T=Ta[j];return r.a.createElement(Ae.a,{className:s.container},r.a.createElement(qe.a,{"aria-label":"prev",onClick:d,className:s.button},r.a.createElement(pa.a,null)),r.a.createElement(qe.a,{"aria-label":"play",onClick:m,className:s.button},r.a.createElement(oa.a,null)),r.a.createElement(qe.a,{"aria-label":"stop",onClick:u,className:s.button},r.a.createElement(sa.a,null)),r.a.createElement(qe.a,{"aria-label":"next",onClick:p,className:s.button},r.a.createElement(ma.a,null)),r.a.createElement("div",{className:s.lcd},r.a.createElement("div",{className:s.lcdText},r.a.createElement("span",{className:E?s.scrollingStatusMessage:s.statusMessage,ref:x,style:g&&E>0?{animationDuration:`${C}s`,transform:`translate(-${E}%)`}:{}},g)),r.a.createElement("div",{className:s.lcdDisc},v&&r.a.createElement(T,{className:s.lcdDiscIcon}))))},Ia=r.a.forwardRef((function(e,t){return r.a.createElement(He.a,Object.assign({direction:"up",ref:t},e))})),za=Object(Se.a)(e=>({container:{display:"flex",flexDirection:"row",alignItems:"flex-end",justifyContent:"space-between",marginRight:-e.spacing(2),flexFlow:"wrap"},formControl:{minWidth:120},selectEmpty:{marginTop:e.spacing(2)},head:{textShadow:"0px 0px 12px rgba(150, 150, 150, 1)",fontSize:e.typography.h2.fontSize,textAlign:"center",marginBottom:e.spacing(2)}})),Ra=({trackIndexes:e})=>{const t=Object(o.c)(),a=za(),[l,i]=Object(n.useState)([]),[c,s]=Object(n.useState)("");let{visible:d}=b(e=>e.dumpDialog);const u=Object(n.useCallback)(()=>{var e;s(""),null===(e=T.mediaRecorderService)||void 0===e||e.stopTestInput(),t(re.setVisible(!1))},[t]),f=Object(n.useCallback)(e=>{var t,a;const n=e.target.value;s(n),null===(t=T.mediaRecorderService)||void 0===t||t.stopTestInput(),null===(a=T.mediaRecorderService)||void 0===a||a.playTestInput(n)},[s]),h=Object(n.useCallback)(()=>{var a,n;t((a=e,n=c,async function(e,t){e(Object(I.batchActions)([ce.setVisible(!0),ce.setProgress({trackTotal:a.length,trackDone:0,trackCurrent:0,titleCurrent:""})]));let r=t().main.disc,l=Object(m.getTracks)(r).filter(e=>a.indexOf(e.index)>=0);const{netmdService:i,mediaRecorderService:o}=T;await T.netmdService.stop();for(let[a,s]of l.entries()){var c;e(ce.setProgress({trackTotal:l.length,trackDone:a,trackCurrent:-1,titleCurrent:null!==(c=s.title)&&void 0!==c?c:""})),await i.gotoTrack(s.index),await i.play(),console.log("Waiting for track to be ready to play");let t=await i.getPosition(),r=[s.index,0,0,1];for(;null===t||!r.every((e,a)=>r[a]===t[a]);)await p(250),t=await i.getPosition();await i.pause(),await(null===i||void 0===i?void 0:i.gotoTrack(s.index)),console.log("Track is ready to play"),await(null===o||void 0===o?void 0:o.initStream(n)),await(null===o||void 0===o?void 0:o.startRecording()),await i.play();let d=s.duration/512;await g(1e3*d,t=>{var n;e(ce.setProgress({trackTotal:l.length,trackDone:a,trackCurrent:t,titleCurrent:null!==(n=s.title)&&void 0!==n?n:""}))}),await(null===o||void 0===o?void 0:o.stopRecording()),null===o||void 0===o||o.downloadRecorded(`${s.title}`),await(null===o||void 0===o?void 0:o.closeStream())}await i.stop(),e(ce.setVisible(!1))})),u()},[e,c,t,u]);return Object(n.useEffect)(()=>{d&&async function(){await navigator.mediaDevices.getUserMedia({audio:!0});let e=(await navigator.mediaDevices.enumerateDevices()).filter(e=>"audioinput"===e.kind).map(e=>({deviceId:e.deviceId,label:e.label}));i(e)}()},[d,i]),r.a.createElement($e.a,{open:d,maxWidth:"sm",fullWidth:!0,TransitionComponent:Ia,"aria-labelledby":"dump-dialog-slide-title","aria-describedby":"dump-dialog-slide-description"},r.a.createElement(Ge.a,{id:"dump-dialog-slide-title"},"Record Selected Tracks"),r.a.createElement(Ue.a,null,r.a.createElement(Fe.a,{component:"p",variant:"h2",className:a.head},"\ud83d\udcbb \u2b05 \ud83d\udcbd"),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"1. Connect your MD Player line-out to your PC audio line-in."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"2. Use the controls at the bottom right to play some tracks."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"3. Select the input source. You should hear the tracks playing on your PC."),r.a.createElement(Fe.a,{component:"p",variant:"body2"},"4. Adjust the input gain and the line-out volume of your device."),r.a.createElement(Ae.a,{className:a.container},r.a.createElement(We.a,{className:a.formControl},r.a.createElement(ta.a,{value:c,onChange:f,displayEmpty:!0,className:a.selectEmpty},r.a.createElement(Xe.a,{value:"",disabled:!0},"Input Source"),l.map(e=>r.a.createElement(Xe.a,{key:e.deviceId,value:e.deviceId},e.label))),r.a.createElement(Le.a,null,"Input Source")),r.a.createElement(Pa,null))),r.a.createElement(Ve.a,null,r.a.createElement(Re.a,{onClick:u},"Cancel"),r.a.createElement(Re.a,{onClick:h,disabled:""===c},"Start Record")))};var Fa=a(611),Wa=a(180);const La=Object(Se.a)(e=>({add:{position:"absolute",bottom:e.spacing(3),right:e.spacing(3),[O(e)]:{bottom:e.spacing(2)}},main:{overflowY:"auto",flex:"1 1 auto",marginBottom:e.spacing(3),outline:"none",marginLeft:e.spacing(-1),marginRight:e.spacing(-1),[C(e)]:{marginLeft:e.spacing(-2),marginRight:e.spacing(-2)}},toolbar:{marginTop:e.spacing(3),marginLeft:e.spacing(-2),marginRight:e.spacing(-2),[e.breakpoints.up(600+2*e.spacing(2))]:{marginLeft:e.spacing(-3),marginRight:e.spacing(-3)}},toolbarLabel:{flex:"1 1 100%"},toolbarHighlight:"light"===e.palette.type?{color:e.palette.secondary.main,backgroundColor:Object(St.d)(e.palette.secondary.light,.85)}:{color:e.palette.text.primary,backgroundColor:e.palette.secondary.dark},headBox:{display:"flex",justifyContent:"space-between"},spacing:{marginTop:e.spacing(1)},formatBadge:{...Wa.styles(e).badge,...Wa.styles(e).colorPrimary,position:"static",display:"inline-flex",border:`2px solid ${e.palette.background.paper}`,padding:"0 4px",verticalAlign:"middle",width:e.spacing(4.5),marginRight:e.spacing(.5)},titleCell:{overflow:"hidden",maxWidth:"40ch",textOverflow:"ellipsis"},durationCell:{whiteSpace:"nowrap"},durationCellTime:{verticalAlign:"middle"},indexCell:{whiteSpace:"nowrap",paddingRight:0,width:"2ch"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},remainingTimeTooltip:{textDecoration:"underline",textDecorationStyle:"dotted"}})),Aa=e=>{let t=Object(o.c)(),a=b(e=>e.main.disc),l=b(e=>e.main.deviceName);const[i,c]=r.a.useState([]),s=i.length,[d,u]=r.a.useState(null),p=Object(n.useCallback)(e=>{u(e.currentTarget)},[]),g=Object(n.useCallback)(()=>{u(null)},[]),f=Object(n.useCallback)(e=>{t(function(e,t){return async function(a){const{netmdService:n}=T;await n.moveTrack(e,t),Ne()(a)}}(i[0],e)),g()},[t,i,g]),h=Object(n.useCallback)(()=>{t(re.setVisible(!0))},[t]);Object(n.useEffect)(()=>{t(Ne())},[t]),Object(n.useEffect)(()=>{c([])},[a]);let[v,y]=r.a.useState([]);const E=Object(n.useCallback)((e,a)=>{y(e),t(Z.setVisible(!0))},[t]),{getRootProps:k,getInputProps:C,isDragActive:O,open:j}=Object(jt.a)({onDrop:E,accept:["audio/*","video/mp4"],noClick:!0}),S=La(),D=w(a),x=(e,n)=>{var r,l;let i=n,o=null!==(r=null===(l=Object(m.getTracks)(a).find(e=>e.index===i))||void 0===l?void 0:l.title)&&void 0!==r?r:"";t(Object(I.batchActions)([B.setVisible(!0),B.setCurrentName(o),B.setIndex(i)]))};return r.a.createElement(r.a.Fragment,null,r.a.createElement(Ae.a,{className:S.headBox},r.a.createElement(Fe.a,{component:"h1",variant:"h4"},l||"Loading..."),r.a.createElement(yt,null)),r.a.createElement(Fe.a,{component:"h2",variant:"body2"},null!==a?r.a.createElement(r.a.Fragment,null,r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(a.left,!1)} left of ${Object(m.formatTimeFromFrames)(a.total,!1)} `),r.a.createElement(Lt.a,{title:r.a.createElement(r.a.Fragment,null,r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(2*a.left,!1)} left in LP2 Mode`),r.a.createElement("br",null),r.a.createElement("span",null,`${Object(m.formatTimeFromFrames)(4*a.left,!1)} left in LP4 Mode`)),arrow:!0},r.a.createElement("span",{className:S.remainingTimeTooltip},"SP Mode"))):"Loading..."),r.a.createElement(Wt.a,{className:Object(Ot.default)(S.toolbar,{[S.toolbarHighlight]:s>0})},s>0?r.a.createElement(Fa.a,{indeterminate:s>0&&s0,onChange:e=>{i.lengthe.index)):c([])},inputProps:{"aria-label":"select all tracks"}}):null,s>0?r.a.createElement(Fe.a,{className:S.toolbarLabel,color:"inherit",variant:"subtitle1"},s," selected"):r.a.createElement(Fe.a,{component:"h3",variant:"h6",className:S.toolbarLabel},(null===a||void 0===a?void 0:a.title)||"Untitled Disc"),1===s?r.a.createElement(r.a.Fragment,null,r.a.createElement(Lt.a,{title:"Move to Position"},r.a.createElement(Re.a,{"aria-controls":"move-menu","aria-label":"Move",onClick:p},"Move")),r.a.createElement(Ke.a,{id:"move-menu",anchorEl:d,open:!!d,onClose:g,PaperProps:{style:{maxHeight:300}}},Array(D.length).fill(null).map((e,t)=>r.a.createElement(Xe.a,{key:`pos-${t}`,onClick:()=>f(t)},t+1)))):null,s>0?r.a.createElement(r.a.Fragment,null,r.a.createElement(Lt.a,{title:"Record from MD"},r.a.createElement(Re.a,{"aria-label":"Record",onClick:h},"Record"))):null,s>0?r.a.createElement(Lt.a,{title:"Delete"},r.a.createElement(qe.a,{"aria-label":"delete",onClick:e=>{var a;t((a=i,async function(e){if(!window.confirm(`Proceed with Delete Track${1!==a.length?"s":""}? This operation cannot be undone.`))return;const{netmdService:t}=T;e(pe.setLoading(!0)),(a=a.sort()).reverse();for(let n of a)await t.deleteTrack(n);Ne()(e)}))}},r.a.createElement(Nt.a,null))):null,s>0?r.a.createElement(Lt.a,{title:"Rename"},r.a.createElement(qe.a,{"aria-label":"rename",disabled:1!==s,onClick:e=>{x(0,i[0])}},r.a.createElement(lt.a,null))):null),r.a.createElement(Ae.a,Object.assign({className:S.main},k()),r.a.createElement("input",C()),r.a.createElement(Pt.a,{size:"small"},r.a.createElement(Rt.a,null,r.a.createElement(Ft.a,null,r.a.createElement(zt.a,{className:S.indexCell},"#"),r.a.createElement(zt.a,null,"Title"),r.a.createElement(zt.a,{align:"right"},"Duration"))),r.a.createElement(It.a,null,D.map(e=>r.a.createElement(Ft.a,{hover:!0,selected:i.includes(e.index),key:e.index,onDoubleClick:t=>x(0,e.index),onClick:t=>{return a=e.index,void(i.includes(a)?c(i.filter(e=>e!==a)):c([...i,a]));var a}},r.a.createElement(zt.a,{className:S.indexCell},e.index+1),r.a.createElement(zt.a,{className:S.titleCell,title:e.title},e.title||"No Title"),r.a.createElement(zt.a,{align:"right",className:S.durationCell},r.a.createElement("span",{className:S.formatBadge},e.encoding),r.a.createElement("span",{className:S.durationCellTime},e.duration)))))),r.a.createElement(Oe.a,{className:S.backdrop,open:O},"Drop your Music to Upload")),r.a.createElement(Dt.a,{color:"primary","aria-label":"add",className:S.add,onClick:j},r.a.createElement(Mt.a,null)),r.a.createElement(Gt,null),r.a.createElement($t,null),r.a.createElement(Kt,null),r.a.createElement(la,{files:v}),r.a.createElement(Yt,null),r.a.createElement(Ra,{trackIndexes:i}),r.a.createElement(Ye,null),r.a.createElement(Qt,null))};var Ba=a(545);const $a=Object(Se.a)(e=>({layout:{width:"auto",height:"100%",[C(e)]:{width:600,marginLeft:"auto",marginRight:"auto"},[j(e)]:{width:700}},paper:{position:"relative",display:"flex",flexDirection:"column",padding:e.spacing(2),height:"calc(100% - 20px)",[C(e)]:{marginTop:e.spacing(2),marginBottom:e.spacing(1),padding:e.spacing(3),height:600},[j(e)]:{height:700}},bottomBar:{display:"flex",alignItems:"center",[O(e)]:{flexWrap:"wrap"},marginLeft:-e.spacing(2)},copyrightTypography:{marginRight:e.spacing(1),textAlign:"center"},backdrop:{zIndex:e.zIndex.drawer+1,color:"#fff"},minidiscLogo:{width:48},controlsContainer:{flex:"0 0 auto",width:"100%",paddingRight:e.spacing(8),[O(e)]:{paddingLeft:0}}})),Va=Object(De.a)({palette:{type:"dark",primary:{light:"#6ec6ff",main:"#2196f3",dark:"#0069c0",contrastText:"#fff"}}}),Ua=Object(De.a)({palette:{type:"light"}});var _a=()=>{const e=$a();Object(o.c)();let{mainView:t,loading:a,darkMode:n}=b(e=>e.appState);return r.a.createElement(r.a.Fragment,null,r.a.createElement(xe.a,{theme:n?Va:Ua},r.a.createElement(Ce.a,null),r.a.createElement("main",{className:e.layout},r.a.createElement(Ba.a,{className:e.paper},"WELCOME"===t?r.a.createElement(Ct,null):null,"MAIN"===t?r.a.createElement(Aa,null):null,r.a.createElement(Ae.a,{className:e.controlsContainer},"MAIN"===t?r.a.createElement(Pa,null):null)),r.a.createElement(Fe.a,{variant:"body2",color:"textSecondary",className:e.copyrightTypography},"\xa9 ",r.a.createElement(Be.a,{rel:"noopener noreferrer",color:"inherit",target:"_blank",href:"https://stefano.brilli.me/"},"Stefano Brilli")," ",(new Date).getFullYear(),".")),r.a.createElement(Oe.a,{className:e.backdrop,open:a},r.a.createElement(je.a,{color:"inherit"}))))},Ga=(a(527),a(528),a(181));class Ha{constructor(e){this.worker=e,this.messageCallback=void 0,e.onmessage=this.handleMessage.bind(this)}async init(){await new Promise(e=>{this.messageCallback=e,this.worker.postMessage({action:"init"})})}async encode(e,t){return(await new Promise(a=>{this.messageCallback=a,this.worker.postMessage({action:"encode",bitrate:t,data:e},[e])})).data.result}terminate(){this.worker.terminate()}handleMessage(e){this.messageCallback(e),this.messageCallback=void 0}}if("undefined"!==typeof WorkerGlobalScope&&self instanceof WorkerGlobalScope){let e;onmessage=async t=>{const{action:a,...n}=t.data;if("init"===a)self.importScripts(f("atracdenc.js")),self.Module().then(t=>{e=t,self.postMessage({action:"init"}),e.setLogger&&e.setLogger((e,t)=>console.log(`${t}: ${e}`))});else if("encode"===a){const{bitrate:t,data:a}=n,r="inWavFile.wav",l="outAt3File.aea",i=new Uint8Array(a);e.FS.writeFile(`${r}`,i),e.callMain(["-e","atrac3","-i",r,"-o",l,"--bitrate",t]);let o=e.FS.stat(l).size,c=new Uint8Array(o-96),s=e.FS.open(l,"r");e.FS.read(s,c,0,c.length,96),e.FS.close(s);let d=c.buffer;self.postMessage({action:"encode",result:d},[d])}}}const Ja=a(543);var Ya=a(286),qa=a.n(Ya);T.netmdService=new M({debug:!0}),T.audioExportService=new class{constructor(){this.ffmpegProcess=void 0,this.atracdencProcess=void 0,this.loglines=[],this.inFileName="",this.outFileNameNoExt=""}async init(){Object(Ga.setLogging)(!0)}async prepare(e){this.loglines=[],this.ffmpegProcess=Object(Ga.createWorker)({logger:e=>{this.loglines.push(e),console.log(e.action,e.message)},corePath:f("ffmpeg-core.js"),workerPath:f("worker.min.js")}),await this.ffmpegProcess.load(),this.atracdencProcess=new Ha(new Ja),await this.atracdencProcess.init();let t=e.name.split(".").slice(-1);if(0===t.length)throw new Error(`Unrecognized file format: ${e.name}`);this.inFileName=`inAudioFile.${t[0]}`,this.outFileNameNoExt="outAudioFile",await this.ffmpegProcess.write(this.inFileName,e)}async info(){await this.ffmpegProcess.transcode(this.inFileName,`${this.outFileNameNoExt}.metadata`,"-f ffmetadata");let e=/Audio:\s(.*?),/,t=/Input #0,\s(.*?),/,a=null,n=null;for(let r of this.loglines){let l=r.message.match(e);if(null===l)if(l=r.message.match(t),null===l){if(null!==a&&null!==n)break}else n=l[1];else a=l[1]}return{format:a,input:n}}async export({format:e}){let t;if("SP"===e){const e=`${this.outFileNameNoExt}.raw`;await this.ffmpegProcess.transcode(this.inFileName,e,"-f s16be -ar 44100");let{data:a}=await this.ffmpegProcess.read(e);t=a.buffer}else{const a=`${this.outFileNameNoExt}.wav`;await this.ffmpegProcess.transcode(this.inFileName,a,"-f wav -ar 44100");let{data:n}=await this.ffmpegProcess.read(a),r="0";switch(e){case"LP2":r="128";break;case"LP105":r="102";break;case"LP4":r="64"}t=await this.atracdencProcess.encode(n.buffer,r)}return this.ffmpegProcess.worker.terminate(),this.atracdencProcess.terminate(),t}},T.mediaRecorderService=new class{constructor(){this.recorder=void 0,this.stream=void 0,this.audioContext=void 0,this.analyserNode=void 0,this.gainNode=void 0}playTestInput(e){this.audioContext=new AudioContext,this.gainNode=this.audioContext.createGain(),this.analyserNode=this.audioContext.createAnalyser(),this.initStream(e).then(()=>{this.audioContext.createMediaStreamSource(this.stream).connect(this.gainNode),this.gainNode.connect(this.analyserNode),this.analyserNode.connect(this.audioContext.destination)})}stopTestInput(){var e;this.audioContext&&(null===(e=this.audioContext)||void 0===e||e.close(),delete this.audioContext,this.closeStream())}async initStream(e){const t={autoGainControl:!1,channelCount:2,deviceId:e,echoCancellation:!1,noiseSuppression:!1,sampleRate:44100,highpassFilter:!1};this.stream=await navigator.mediaDevices.getUserMedia({audio:t});const a=this.stream.getAudioTracks();a.length>0&&console.log("Record Setings:",a[0].getSettings())}async startRecording(){this.audioContext=new AudioContext;const e=this.audioContext.createMediaStreamSource(this.stream);this.recorder=new qa.a(e,{workerPath:f("recorderWorker.js")}),this.recorder.record()}async stopRecording(){this.recorder.stop()}async closeStream(){var e;null===(e=this.stream)||void 0===e||e.getTracks().forEach(e=>e.stop())}downloadRecorded(e){this.recorder.exportWAV(t=>{let a=URL.createObjectURL(t),n=document.createElement("a");document.body.appendChild(n),n.style.display="none",n.href=a,n.download=`${y(e)}.wav`,n.click(),window.URL.revokeObjectURL(a),document.body.removeChild(n)})}},function(){let e;window.addEventListener("beforeunload",e=>{we.getState().uploadDialog.visible&&(e.preventDefault(),e.returnValue="Warning! Recording will be interrupted")}),navigator&&navigator.usb?navigator.usb.ondisconnect=function(){we.dispatch(pe.setState("WELCOME"))}:we.dispatch(pe.setBrowserSupported(!1)),window.addEventListener("beforeinstallprompt",t=>{t.preventDefault(),e=t})}(),function(){let e=null,t=!1;function a(e){var a;return!t&&"MAIN"===e.appState.mainView&&!1===e.appState.loading&&"playing"===(null===(a=e.main.deviceStatus)||void 0===a?void 0:a.state)&&!1===e.convertDialog.visible&&!1===e.uploadDialog.visible&&!1===e.recordDialog.visible&&!1===e.panicDialog.visible&&!1===e.errorDialog.visible&&!1===e.dumpDialog.visible}we.subscribe((function(){const n=we.getState();!0===a(n)&&null===e?e=setInterval(async()=>{try{const e=await T.netmdService.getDeviceStatus();we.dispatch(he.setDeviceStatus(e))}catch(e){console.error(e),t=!0}},5e3):!1===a(n)&&null!==e&&(clearInterval(e),e=null)}))}(),i.a.render(r.a.createElement(o.a,{store:we},r.a.createElement(_a,null)),document.getElementById("root")),function(e){if("serviceWorker"in navigator){if(new URL("/webminidisc",window.location.href).origin!==window.location.origin)return;window.addEventListener("load",()=>{const t="/webminidisc/final-service-worker.js";c?(!function(e,t){fetch(e,{headers:{"Service-Worker":"script"}}).then(a=>{const n=a.headers.get("content-type");404===a.status||null!=n&&-1===n.indexOf("javascript")?navigator.serviceWorker.ready.then(e=>{e.unregister().then(()=>{window.location.reload()})}):s(e,t)}).catch(()=>{console.log("No internet connection found. App is running in offline mode.")})}(t,e),navigator.serviceWorker.ready.then(()=>{console.log("This web app is being served cache-first by a service worker. To learn more, visit https://bit.ly/CRA-PWA")})):s(t,e)})}}()}},[[303,1,2]]]); +//# sourceMappingURL=main.ec094e9a.chunk.js.map \ No newline at end of file diff --git a/static/js/main.ec094e9a.chunk.js.map b/static/js/main.ec094e9a.chunk.js.map new file mode 100644 index 0000000..659e9c7 --- /dev/null +++ b/static/js/main.ec094e9a.chunk.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["images/chrome-icon.svg","webpack:///./src/services/atracdenc-worker.ts?dc3c","serviceWorker.ts","utils.ts","services/netmd.ts","services/registry.ts","redux/upload-dialog-feature.ts","redux/rename-dialog-feature.ts","redux/error-dialog-feature.ts","redux/panic-dialog-feature.ts","redux/convert-dialog-feature.ts","redux/dump-dialog-feature.ts","redux/record-dialog-feature.ts","redux/app-feature.ts","redux/main-feature.ts","redux/store.ts","redux/actions.ts","components/about-dialog.tsx","components/topmenu.tsx","components/welcome.tsx","components/rename-dialog.tsx","components/upload-dialog.tsx","components/record-dialog.tsx","components/error-dialog.tsx","components/panic-dialog.tsx","components/convert-dialog.tsx","images/md0.svg","images/md1.svg","images/md2.svg","images/md3.svg","components/controls.tsx","components/dump-dialog.tsx","components/main.tsx","components/app.tsx","services/atracdenc-worker.ts","services/audio-export.ts","index.tsx","services/mediarecorder.ts"],"names":["module","exports","Worker","isLocalhost","Boolean","window","location","hostname","match","registerValidSW","swUrl","config","navigator","serviceWorker","register","then","registration","onupdatefound","installingWorker","installing","onstatechange","console","log","state","controller","onUpdate","onSuccess","update","catch","error","sleep","ms","Promise","resolve","setTimeout","async","sleepWithProgressCallback","cb","elapsedSecs","interval","setInterval","Math","min","clearInterval","useShallowEqualSelector","selector","useSelector","shallowEqual","getPublicPathFor","script","savePreference","key","value","localStorage","setItem","JSON","stringify","loadPreference","defaultValue","res","getItem","parse","e","sanitizeTitle","title","normalize","replace","EncodingName","Encoding","sp","lp2","lp4","getSortedTracks","disc","tracks","group","groups","track","push","index","encoding","duration","formatTimeFromFrames","sort","l","r","asyncMutex","target","propertyKey","descriptor","oldValue","args","mutex","this","release","acquire","apply","forAnyDesktop","theme","breakpoints","up","spacing","belowDesktop","down","forWideDesktop","require","NetMDUSBService","constructor","debug","netmdInterface","logger","Mutex","statusMonitorTimer","_fn","method","info","warn","child","iface","openNewDevice","usb","openPairedDevice","listContent","getDeviceStatus","netMd","getDeviceName","finalize","cacheTOC","setTrackTitle","syncTOC","newName","oldName","getDiscTitle","oldRawName","_getDiscTitle","hasGroups","indexOf","hasGroupsAndTitle","startsWith","newNameWithGroups","setDiscTitle","eraseTrack","eraseDisc","src","dst","moveTrack","data","format","progressCallback","total","byteLength","written","encrypted","updateProgress","w","webWorkerAsyncPacketIterator","makeGetAsyncPacketIteratorOnWorkerThread","encryptedBytes","mdTrack","MDTrack","download","writtenBytes","terminate","play","pause","stop","nextTrack","previousTrack","gotoTrack","getPosition","ServiceRegistry","slice","createSlice","name","initialState","visible","cancelled","writtenProgress","encryptedProgress","totalProgress","trackTotal","trackConverting","trackCurrent","titleCurrent","titleConverting","reducers","setVisible","action","payload","setWriteProgress","setCancelUpload","setTrackProgress","current","converting","reducer","actions","enableBatching","setCurrentName","setIndex","setErrorMessage","dismissed","dismiss","titleSource","titleFormat","setFormat","setTitleSource","setTitleFormat","inputDeviceId","setInputDeviceId","trackDone","setProgress","mainView","loading","pairingFailed","pairingMessage","browserSupported","darkMode","aboutDialogVisible","setState","setLoading","setPairingFailed","setPairingMessage","setBrowserSupported","setDarkMode","showAboutDialog","deviceName","deviceStatus","setDisc","setDeviceName","setDeviceStatus","combineReducers","renameDialog","uploadDialog","errorDialog","panicDialog","convertDialog","dumpDialog","recordDialog","appState","main","resetStateAction","appActions","toString","store","configureStore","type","middleware","next","panicDialogActions","getDefaultMiddleware","Object","freeze","getState","control","params","dispatch","serviceRegistry","netmdService","prev","mainActions","appStateActions","batchActions","WireformatDict","SP","Wireformat","pcm","LP2","LP105","l105kbps","LP4","getTrackNameFromMediaTags","file","fileData","arrayBuffer","blob","Blob","Uint8Array","metadata","mm","common","artist","album","convertAndUpload","files","audioExportService","wireformat","uploadDialogActions","updateProgressCallback","hasUploadBeenCancelled","trackUpdate","length","updateTrack","maxTitleLength","getTracks","map","reduce","acc","floor","errorMessage","i","item","converted","convertNext","f","reject","prepare","export","err","j","conversionIterator","extStartIndex","lastIndexOf","substring","upload","actionToDispatch","concat","errorDialogAction","Transition","React","forwardRef","props","ref","Slide","direction","AboutDialog","useDispatch","Dialog","open","maxWidth","fullWidth","TransitionComponent","aria-labelledby","DialogTitle","id","DialogContent","DialogContentText","Link","rel","href","DialogActions","Button","onClick","useStyles","makeStyles","listItemIcon","minWidth","TopMenu","classes","discTitle","githubLinkRef","useRef","menuAnchorEl","setMenuAnchorEl","useState","menuOpen","handleMenuOpen","useCallback","event","currentTarget","handleDarkMode","handleMenuClose","handleWipeDisc","confirm","wipeDisc","handleRefresh","handleRenameDisc","renameDialogActions","handleExit","handleShowAbout","handleGithubLink","stopPropagation","click","menuItems","MenuItem","ListItemIcon","className","fontSize","ListItemText","Fragment","IconButton","aria-label","aria-controls","aria-haspopup","Menu","anchorEl","keepMounted","onClose","position","flex","display","justifyContent","flexDirection","alignItems","button","marginTop","chromeLogo","width","height","why","alignSelf","headBox","Welcome","toLowerCase","showWhyUnsupported","setWhyUnsupported","Box","Typography","component","variant","align","color","init","connect","pair","message","FormControl","style","visibility","FormHelperText","preventDefault","alt","ChromeIconPath","RenameDialog","renameDialogVisible","renameDialogTitle","renameDialogIndex","what","handleCancelRename","handleDoRename","renameDisc","renameTrack","TextField","autoFocus","label","onKeyDown","onChange","progressPerc","progressBar","uploadLabel","UploadDialog","handleCancelUpload","progressValue","bufferValue","convertedValue","aria-describedby","LinearProgress","valueBuffer","disabled","RecordDialog","round","ErrorDialog","handleClose","errorDialogActions","PanicDialog","handleReloadApp","reload","handleIgnore","scroll","size","container","formControl","toggleButton","dialogContent","flexWrap","rightBlock","titleFormControl","ConvertDialog","convertDialogActions","handleChangeFormat","ev","newFormat","handleChangeTitleSource","newTitleSource","handleChangeTitleFormat","handleConvert","ToggleButtonGroup","exclusive","ToggleButton","Select","input","Input","_extends","assign","arguments","source","prototype","hasOwnProperty","call","createElement","fill","fillRule","d","SvgMd0","svgRef","viewBox","ForwardRef","SvgMd1","SvgMd2","SvgMd3","frames","MDIcon0","MDIcon1","MDIcon2","MDIcon3","from","transform","to","lcd","marginLeft","marginRight","paddingLeft","paddingRight","borderRadius","backgroundColor","palette","background","default","lcdText","overflow","left","fontFamily","lcdDisc","top","lcdDiscIcon","active","scrollingStatusMessage","whiteSpace","animationName","animationTimingFunction","animationIterationCount","statusMessage","Controls","handlePrev","handlePlay","handleStop","handleNext","trackIndex","deviceState","discPresent","lcdScroll","setLcdScroll","lcdScrollDuration","setLcdScrollDuration","lcdIconFrame","setLcdIconFrame","scrollTimerRef","lcdRef","useEffect","clearTimeout","domEl","textWidth","scrollWidth","lcdWidth","parentElement","offsetWidth","scrollDurationInSec","updateLCDScroll","lcdIconAnimationTimer","DiscFrame","animationDuration","flexFlow","selectEmpty","head","textShadow","typography","h2","textAlign","marginBottom","DumpDialog","trackIndexes","devices","setDevices","mediaRecorderService","stopTestInput","dumpDialogActions","handleChange","deviceId","playTestInput","handleStartTransfer","indexes","recordDialogAction","filter","t","entries","expected","every","_","initStream","startRecording","durationInSec","perc","stopRecording","downloadRecorded","closeStream","mediaDevices","getUserMedia","audio","inputDevices","enumerateDevices","device","kind","updateDeviceList","displayEmpty","add","bottom","right","overflowY","outline","toolbar","toolbarLabel","toolbarHighlight","secondary","lighten","light","text","primary","dark","formatBadge","BadgeImpl","badge","colorPrimary","border","paper","padding","verticalAlign","titleCell","textOverflow","durationCell","durationCellTime","indexCell","backdrop","zIndex","drawer","remainingTimeTooltip","textDecoration","textDecorationStyle","Main","selected","setSelected","selectedCount","moveMenuAnchorEl","setMoveMenuAnchorEl","handleShowMoveMenu","handleCloseMoveMenu","handleMoveSelectedTrack","destIndex","srcIndex","handleShowDumpDialog","uploadedFiles","setUploadedFiles","onDrop","acceptedFiles","rejectedFiles","getRootProps","getInputProps","isDragActive","useDropzone","accept","noClick","handleRenameDoubleClick","selectedIndex","currentName","find","Tooltip","arrow","Toolbar","clsx","Checkbox","indeterminate","checked","inputProps","PaperProps","maxHeight","Array","reverse","deleteTrack","Table","TableHead","TableRow","TableCell","TableBody","hover","includes","onDoubleClick","handleSelectClick","Backdrop","Fab","layout","bottomBar","copyrightTypography","minidiscLogo","controlsContainer","darkTheme","createMuiTheme","contrastText","lightTheme","App","ThemeProvider","CssBaseline","Paper","Date","getFullYear","CircularProgress","AtracdencProcess","worker","messageCallback","onmessage","handleMessage","bind","postMessage","bitrate","result","undefined","WorkerGlobalScope","self","Module","others","importScripts","m","setLogger","msg","stream","inWavFile","outAt3File","dataArray","FS","writeFile","callMain","stat","tmp","outAt3FileStream","read","close","buffer","AtracdencWorker","ffmpegProcess","atracdencProcess","loglines","inFileName","outFileNameNoExt","setLogging","createWorker","corePath","workerPath","load","ext","split","Error","write","transcode","audioFormatRegex","inputFormatRegex","line","outFileName","encode","recorder","audioContext","analyserNode","gainNode","AudioContext","createGain","createAnalyser","createMediaStreamSource","destination","recordConstraints","autoGainControl","channelCount","echoCancellation","noiseSuppression","sampleRate","highpassFilter","audioTracks","getAudioTracks","getSettings","Recorder","record","forEach","exportWAV","url","URL","createObjectURL","a","document","body","appendChild","revokeObjectURL","removeChild","deferredPrompt","addEventListener","returnValue","ondisconnect","statusMonitorInterval","exceptionOccurred","shouldMonitorBeRunning","subscribe","ReactDOM","render","getElementById","process","origin","fetch","headers","response","contentType","get","status","ready","unregister","checkValidServiceWorker"],"mappings":"mFAAAA,EAAOC,QAAU,IAA0B,yC,8NCA3CD,EAAOC,QAAU,WACf,OAAO,IAAIC,OAAO,IAA0B,oC,qFCW9C,MAAMC,EAAcC,QACa,cAA7BC,OAAOC,SAASC,UAEiB,UAA7BF,OAAOC,SAASC,UAEhBF,OAAOC,SAASC,SAASC,MAAM,2DAyCvC,SAASC,EAAgBC,EAAeC,GACpCC,UAAUC,cACLC,SAASJ,GACTK,KAAKC,IACFA,EAAaC,cAAgB,KACzB,MAAMC,EAAmBF,EAAaG,WACd,MAApBD,IAGJA,EAAiBE,cAAgB,KAC7BC,QAAQC,IAAI,eAAgBJ,EAAiBK,OACd,cAA3BL,EAAiBK,QACbX,UAAUC,cAAcW,YAIxBH,QAAQC,IACJ,iHAKAX,GAAUA,EAAOc,UACjBd,EAAOc,SAAST,KAMpBK,QAAQC,IAAI,sCAGRX,GAAUA,EAAOe,WACjBf,EAAOe,UAAUV,QAMrCA,EAAaW,WAEhBC,MAAMC,IACHR,QAAQQ,MAAM,4CAA6CA,K,6BC9FhE,SAASC,EAAMC,GAClB,OAAO,IAAIC,QAAQC,IACfC,WAAWD,EAASF,KAIrBI,eAAeC,EAA0BL,EAAYM,GACxD,IAAIC,EAAc,EACdC,EAAWC,YAAY,KACvBF,IACAD,EAAGI,KAAKC,IAAI,IAAqB,IAAdJ,EAAsBP,EAAM,OAChD,WACGD,EAAMC,GACZ1B,OAAOsC,cAAcJ,GAGlB,SAASK,EAAiEC,GAC7E,OAAOC,YAAYD,EAAUE,KAO1B,SAASC,EAAiBC,GAC7B,MAAQ,gBAA4BA,IAGjC,SAASC,EAAeC,EAAaC,GACxCC,aAAaC,QAAQH,EAAKI,KAAKC,UAAUJ,IAGtC,SAASK,EAAkBN,EAAaO,GAC3C,IAAIC,EAAMN,aAAaO,QAAQT,GAC/B,GAAY,OAARQ,EACA,OAAOD,EAEP,IACI,OAAOH,KAAKM,MAAMF,GACpB,MAAOG,GACL,OAAOJ,GAiBZ,SAASK,EAAcC,GAC1B,OAAOA,EAAMC,UAAU,OAAOC,QAAQ,gBAAiB,IAG3D,MAAMC,EAAwC,CAC1C,CAACC,WAASC,IAAK,KACf,CAACD,WAASE,KAAM,MAChB,CAACF,WAASG,KAAM,OAGb,SAASC,EAAgBC,GAC5B,IAAIC,EAAgG,GACpG,GAAa,OAATD,EACA,IAAK,IAAIE,KAASF,EAAKG,OACnB,IAAK,IAAIC,KAASF,EAAMD,OAAQ,CAAC,IAAD,IAC5BA,EAAOI,KAAK,CACRC,MAAOF,EAAME,MACbf,MAAK,UAAEa,EAAMb,aAAR,QAAkB,gBACvBW,MAAK,UAAEA,EAAMX,aAAR,QAAkB,GACvBgB,SAAUb,EAAaU,EAAMG,UAC7BC,SAAUC,+BAAqBL,EAAMI,UAAU,KAM/D,OADAP,EAAOS,KAAK,CAACC,EAAGC,IAAMD,EAAEL,MAAQM,EAAEN,OAC3BL,EAGJ,SAASY,EAAWC,EAAaC,EAAqBC,GAEzD,MAAMC,EAAWD,EAAWrC,MAU5B,OATAqC,EAAWrC,MAAQjB,kBAAkBwD,GACjC,MAAMC,EAASC,KAAaD,MACtBE,QAAgBF,EAAMG,UAC5B,IACI,aAAaL,EAASM,MAAMH,KAAMF,GADtC,QAGIG,MAGDL,EAGJ,SAASQ,EAAcC,GAC1B,OAAOA,EAAMC,YAAYC,GAAG,IAAyB,EAAnBF,EAAMG,QAAQ,IAG7C,SAASC,EAAaJ,GACzB,OAAOA,EAAMC,YAAYI,KAAK,IAAyB,EAAnBL,EAAMG,QAAQ,IAG/C,SAASG,EAAeN,GAC3B,OAAOA,EAAMC,YAAYC,GAAG,IAAyB,EAAnBF,EAAMG,QAAQ,IAAW,2B,eCnG/D,MAAMnG,EAASuG,EAAQ,KA+BhB,IAAMC,GAAb,EAAO,MAMHC,aAAY,MAAEC,GAAQ,IAClB,GADgD,KAL5CC,oBAK2C,OAJ3CC,YAI2C,OAH5ClB,MAAQ,IAAImB,IAGgC,KAF5CC,wBAE4C,EAC3CJ,EAAO,CAEP,MAAMK,EAAM,IAAItB,KACRA,GAAQA,EAAK,IAAMA,EAAK,GAAGuB,QAC3B7F,QAAQC,OAAOqE,IAGvBE,KAAKiB,OAAS,CACVF,MAAOK,EACPE,KAAMF,EACNG,KAAMH,EACNpF,MAAOoF,EACPI,MAAO,IAAMxB,KAAKiB,SAK9B,aACI,IAAIQ,QAAcC,wBAAc3G,UAAU4G,IAAK3B,KAAKiB,QACpD,OAAc,OAAVQ,IAGJzB,KAAKgB,eAAiBS,GACf,GAGX,gBACI,IAAIA,QAAcG,2BAAiB7G,UAAU4G,IAAK3B,KAAKiB,QACvD,OAAc,OAAVQ,IAGJzB,KAAKgB,eAAiBS,GACf,GAGX,oBAEI,aAAaI,sBAAY7B,KAAKgB,gBAGlC,wBAEI,aAAac,0BAAgB9B,KAAKgB,gBAGtC,sBAEI,aAAahB,KAAKgB,eAAgBe,MAAMC,gBAG5C,uBAEUhC,KAAKgB,eAAgBe,MAAME,WAGrC,kBACkB/C,EAAef,GAE7BA,EAAQD,EAAcC,SAChB6B,KAAKgB,eAAgBkB,iBACrBlC,KAAKgB,eAAgBmB,cAAcjD,EAAOf,SAC1C6B,KAAKgB,eAAgBoB,UAG/B,iBACiBC,GAEb,MAAMC,QAAgBtC,KAAKgB,eAAgBuB,eACrCC,QAAmBxC,KAAKgB,eAAgByB,gBACxCC,EAAYF,EAAWG,QAAQ,OAAS,EACxCC,EAAoBJ,EAAWK,WAAW,MAEhD,GAAIR,IAAYC,EACZ,OAGJ,IAAIQ,EAIIA,EAFJJ,EACIE,EACoBJ,EAAWnE,QAAQ,aAA0B,KAAZgE,EAAkB,KAAIA,MAAe,IAErE,KAAIA,MAAYG,IAGrBH,QAGlBrC,KAAKgB,eAAgBkB,iBACrBlC,KAAKgB,eAAgB+B,aAAaD,SAClC9C,KAAKgB,eAAgBoB,UAG/B,kBACkBlD,SACRc,KAAKgB,eAAgBgC,WAAW9D,SAChCjD,EAAM,KAGhB,uBAEU+D,KAAKgB,eAAgBiC,YAG/B,gBACgBC,EAAaC,SACnBnD,KAAKgB,eAAgBoC,UAAUF,EAAKC,GAG9C,aACIhF,EACAkF,EACAC,EACAC,GAEA,IAAIC,EAAQH,EAAKI,WACbC,EAAU,EACVC,EAAY,EAChB,SAASC,IACLL,EAAiB,CAAEG,UAASC,YAAWH,UAG3C,IAAIK,EAAI,IAAIxJ,EAERyJ,EAA+BC,mDAAyCF,EAAG,EAAGG,qBAC9EL,EAAYK,EACZJ,MAIJzF,EAAQD,EAAcC,GACtB,IAAI8F,EAAU,IAAIC,UAAQ/F,EAAOmF,EAAQD,EAAM,OAASS,SAElDK,mBAASnE,KAAKgB,eAAiBiD,EAAS,EAAGG,mBAC7CV,EAAUU,EACVR,MAGJC,EAAEQ,YAGN,mBAEUrE,KAAKgB,eAAgBsD,OAE/B,oBAEUtE,KAAKgB,eAAgBuD,QAE/B,mBAEUvE,KAAKgB,eAAgBwD,OAE/B,mBAEUxE,KAAKgB,eAAgByD,YAE/B,mBAEUzE,KAAKgB,eAAgB0D,gBAG/B,gBACgBxF,SACNc,KAAKgB,eAAgB2D,UAAUzF,GAGzC,oBAEI,aAAac,KAAKgB,eAAgB4D,gBAhL1C,uCA0CKnF,GA1CL,mHA+CKA,GA/CL,qHAoDKA,GApDL,8GAyDKA,GAzDL,4GA8DKA,GA9DL,8GAuEKA,GAvEL,8GAoGKA,GApGL,4GA0GKA,GA1GL,0GA+GKA,GA/GL,sGAoJKA,GApJL,kGAwJKA,GAxJL,kGA4JKA,GA5JL,iGAgKKA,GAhKL,iGAoKKA,GApKL,sGAyKKA,GAzKL,6GA8KKA,GA9KL,2ECpCeoF,MAF0B,G,wBCSzC,MAiBaC,EAAQC,YAAY,CAC7BC,KAAM,eACNC,aAnBqC,CACrCC,SAAS,EACTC,WAAW,EAGXC,gBAAiB,EACjBC,kBAAmB,EACnBC,cAAe,EAGfC,WAAY,EACZC,gBAAiB,EACjBC,aAAc,EACdC,aAAc,GACdC,gBAAiB,IAMjBC,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3BC,iBAAkB,CAACtK,EAAOoK,KACtBpK,EAAM2J,kBAAoBS,EAAOC,QAAQpC,UACzCjI,EAAM0J,gBAAkBU,EAAOC,QAAQrC,QACvChI,EAAM4J,cAAgBQ,EAAOC,QAAQvC,OAEzCyC,gBAAiB,CAACvK,EAAOoK,KACrBpK,EAAMyJ,UAAYW,EAAOC,SAE7BG,iBAAkB,CACdxK,EACAoK,KAEApK,EAAM6J,WAAaO,EAAOC,QAAQvC,MAClC9H,EAAM+J,aAAeK,EAAOC,QAAQI,QACpCzK,EAAM8J,gBAAkBM,EAAOC,QAAQK,WACvC1K,EAAMgK,aAAeI,EAAOC,QAAQL,aACpChK,EAAMiK,gBAAkBG,EAAOC,QAAQJ,qBAKtC,QAAEU,EAAF,QAAWC,GAAYxB,EACrByB,+BAAeF,GCxD9B,MAMavB,EAAQC,YAAY,CAC7BC,KAAM,eACNC,aARoC,CACpCC,SAAS,EACT/G,MAAO,GACPe,OAAQ,GAMR0G,SAAU,CACNC,WAAY,CAACnK,EAA0BoK,KACnCpK,EAAMwJ,QAAUY,EAAOC,SAE3BS,eAAgB,CAAC9K,EAA0BoK,KACvCpK,EAAMyC,MAAQ2H,EAAOC,SAEzBU,SAAU,CAAC/K,EAA0BoK,KACjCpK,EAAMwD,MAAQ4G,EAAOC,aAKlBM,QAAF,EAAWC,QAAX,GAAuBxB,EACrByB,+BAAeF,GCxB9B,MAAMpB,EAAiC,CACnCC,SAAS,EACTlJ,MAAQ,IAGN8I,EAAQC,YAAY,CACtBC,KAAM,cACNC,aAFsB,EAGtBW,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3BW,gBAAiB,CAAChL,EAAOoK,KACrBpK,EAAMM,MAAS,GAAE8J,EAAOC,eAKrBO,QAAF,EAAWD,QAAX,GAAuBvB,EACrByB,+BAAeF,GCxBvB,MAKDvB,EAAQC,YAAY,CACtBC,KAAM,cACNC,aAPwB,CACxBC,SAAS,EACTyB,WAAW,GAMXf,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3Ba,QAAS,CAAClL,EAAOoK,KACbpK,EAAMwJ,SAAU,EAChBxJ,EAAMiL,WAAY,OAKfL,QAAF,EAAWD,QAAX,GAAuBvB,EACrByB,+BAAeF,GCR9B,MAAMpB,EAAqC,CACvCC,SAAS,EACT5B,OAAQ1F,EAAe,eAAgB,OACvCiJ,YAAajJ,EAAe,mBAAoB,QAChDkJ,YAAalJ,EAAe,mBAAoB,UAG9CkH,EAAQC,YAAY,CACtBC,KAAM,gBACNC,aAFsB,EAGtBW,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3BgB,UAAW,CAACrL,EAAOoK,KACfpK,EAAM4H,OAASwC,EAAOC,QACtB1I,EAAe,eAAgB3B,EAAM4H,SAEzC0D,eAAgB,CAACtL,EAAOoK,KACpBpK,EAAMmL,YAAcf,EAAOC,QAC3B1I,EAAe,mBAAoB3B,EAAMmL,cAE7CI,eAAgB,CAACvL,EAAOoK,KACpBpK,EAAMoL,YAAchB,EAAOC,QAC3B1I,EAAe,mBAAoB3B,EAAMoL,kBAKtCR,QAAF,EAAWD,QAAX,IAAuBvB,EACrByB,gCAAeF,ICrC9B,MAKavB,GAAQC,YAAY,CAC7BC,KAAM,aACNC,aAPkC,CAClCC,SAAS,EACTgC,cAAe,IAMftB,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3BoB,iBAAkB,CAACzL,EAAOoK,KACtBpK,EAAMwL,cAAgBpB,EAAOC,aAK1BM,QAAF,GAAWC,QAAX,IAAuBxB,GACrByB,gCAAeF,ICd9B,MAiBavB,GAAQC,YAAY,CAC7BC,KAAM,eACNC,aAnBuC,CACvCC,SAAS,EAETK,WAAY,EACZ6B,UAAW,EACX3B,aAAc,EAEdC,aAAc,IAadE,SAAU,CACNC,WAAY,CAACnK,EAAOoK,KAChBpK,EAAMwJ,QAAUY,EAAOC,SAE3BsB,YAAa,CACT3L,EACAoK,KAEApK,EAAM6J,WAAaO,EAAOC,QAAQR,WAClC7J,EAAM0L,UAAYtB,EAAOC,QAAQqB,UACjC1L,EAAM+J,aAAeK,EAAOC,QAAQN,aACpC/J,EAAMgK,aAAeI,EAAOC,QAAQL,kBAKjCW,QAAF,GAAWC,QAAX,IAAuBxB,GACrByB,gCAAeF,IClC9B,MAAMpB,GAAyB,CAC3BqC,SAAU,UACVC,SAAS,EACTC,eAAe,EACfC,eAAiB,GACjBC,kBAAkB,EAClBC,SAAU/J,EAAe,YAAY,GACrCgK,oBAAoB,GAGX9C,GAAQC,YAAY,CAC7BC,KAAM,MACNC,aAF6B,GAG7BW,SAAU,CACNiC,SAAU,CAACnM,EAAOoK,KACdpK,EAAM4L,SAAWxB,EAAOC,SAE5B+B,WAAY,CAACpM,EAAOoK,KAChBpK,EAAM6L,QAAUzB,EAAOC,SAE3BgC,iBAAkB,CAACrM,EAAOoK,KACtBpK,EAAM8L,cAAgB1B,EAAOC,SAEjCiC,kBAAmB,CAACtM,EAAOoK,KACvBpK,EAAM+L,eAAiB3B,EAAOC,SAElCkC,oBAAqB,CAACvM,EAAOoK,KACzBpK,EAAMgM,iBAAmB5B,EAAOC,SAEpCmC,YAAa,CAACxM,EAAOoK,KACjBpK,EAAMiM,SAAW7B,EAAOC,QACxB1I,EAAe,WAAY3B,EAAMiM,WAErCQ,gBAAiB,CAACzM,EAAOoK,KACrBpK,EAAMkM,mBAAqB9B,EAAOC,aAK/BM,QAAF,GAAWC,QAAX,IAAuBxB,GACrByB,gCAAeF,IC9C9B,MAMavB,GAAQC,YAAY,CAC7BC,KAAM,OACNC,aAR4B,CAC5BrG,KAAM,KACNwJ,WAAY,GACZC,aAAc,MAMdzC,SAAU,CACN0C,QAAS,CAAC5M,EAAOoK,KACbpK,EAAMkD,KAAOkH,EAAOC,SAExBwC,cAAe,CAAC7M,EAAOoK,KACnBpK,EAAM0M,WAAatC,EAAOC,SAE9ByC,gBAAiB,CAAC9M,EAAOoK,KACrBpK,EAAM2M,aAAevC,EAAOC,aAKzBM,QAAF,GAAWC,QAAX,IAAuBxB,GACrByB,gCAAeF,ICb9B,IAAIA,GAAUoC,YAAgB,CAC1BC,eACAC,eACAC,cACAC,cACAC,iBACAC,cACAC,gBACAC,YACAC,UAGJ,MAAMC,GAAmBC,GAAWvB,SAASwB,WAUhCC,GAAQC,YAAe,CAChClD,QATsC,YAAYvG,GAClD,MAAOpE,EAAOoK,GAAUhG,EACxB,OAAIgG,EAAO0D,OAASL,IAHG,YAGiBrD,EAAOC,QACpCd,GAEJoB,MAAWvG,IAKlB2J,WAAY,CAjCiBH,GAASI,GAAQpN,UAC9C,UACUoN,EAAK5D,GACb,MAAO7H,GACLzC,QAAQQ,MAAMiC,GACdyL,EAAKC,EAAmB9D,YAAW,SA4BT+D,iBAG5B3E,GAAe4E,OAAOC,OAAOR,GAAMS,Y,0EChClC,SAASC,GAAQlE,EAAoDmE,GACxE,OAAO3N,eAAe4N,EAAuBH,GACzC,OAAQjE,GACJ,IAAK,aACKqE,EAAgBC,aAAc9F,OACpC,MACJ,IAAK,aACK6F,EAAgBC,aAAc5F,OACpC,MACJ,IAAK,aACK2F,EAAgBC,aAAcV,OACpC,MACJ,IAAK,aACKS,EAAgBC,aAAcC,OACpC,MACJ,IAAK,OACGJ,GAA4B,kBAAXA,GAAuBA,GAAU,SAC5CE,EAAgBC,aAAczF,UAAUsF,SAMpDhO,EAAM,KACZ,IACI,IAAIoM,QAAqB8B,EAAgBC,aAActI,kBACvDoI,EAASI,GAAY9B,gBAAgBH,IACvC,MAAOpK,GACLzC,QAAQC,IAAI,uCAqCjB,SAASoG,KACZ,OAAOvF,eAAe4N,GAElBA,EAASK,GAAgBzC,YAAW,IACpC,IAAIlJ,QAAauL,EAAgBC,aAAcvI,cAC3CuG,QAAmB+B,EAAgBC,aAAcpI,gBACjDqG,EAAe,KACnB,IACIA,QAAqB8B,EAAgBC,aAActI,kBACrD,MAAO7D,GACLzC,QAAQC,IAAI,yCAEhByO,EACIM,uBAAa,CACTF,GAAYhC,QAAQ1J,GACpB0L,GAAY/B,cAAcH,GAC1BkC,GAAY9B,gBAAgBH,GAC5BkC,GAAgBzC,YAAW,OA2IpC,MAAM2C,GAA8C,CACvDC,GAAIC,aAAWC,IACfC,IAAKF,aAAWlM,IAChBqM,MAAOH,aAAWI,SAClBC,IAAKL,aAAWjM,KAGpBpC,eAAe2O,GAA0BC,EAAYpE,GAA+B,IAAD,MAC/E,MAAMqE,QAAiBD,EAAKE,cACtBC,EAAO,IAAIC,KAAK,CAAC,IAAIC,WAAWJ,KACtC,IAAIK,QAAiBC,aAAaJ,GAClC,MAAMlN,EAAK,UAAGqN,EAASE,OAAOvN,aAAnB,QAA4B,gBACjCwN,EAAM,UAAGH,EAASE,OAAOC,cAAnB,QAA6B,iBACnCC,EAAK,UAAGJ,EAASE,OAAOE,aAAnB,QAA4B,gBACvC,OAAQ9E,GACJ,IAAK,QACD,OAAO3I,EAEX,IAAK,eACD,MAAQ,GAAEwN,OAAYxN,IAE1B,IAAK,cACD,MAAQ,GAAEyN,OAAWzN,IAEzB,IAAK,qBACD,MAAQ,GAAEwN,OAAYC,OAAWzN,KAKtC,SAAS0N,GAAiBC,EAAexI,EAAsBuD,EAA8BC,GAChG,OAAOxK,eAAe4N,EAAuBH,GACzC,MAAM,mBAAEgC,EAAF,aAAsB3B,GAAiBD,EACvC6B,EAAavB,GAAenH,SAElC,OAAM8G,QAAN,IAAMA,OAAN,EAAMA,EAAc5F,QACpB0F,EAASM,uBAAa,CAACyB,EAAoBpG,YAAW,GAAOoG,EAAoBhG,iBAAgB,MAEjG,MAAMiG,EAAyB,EAAGxI,UAASC,YAAWH,YAClD0G,EAAS+B,EAAoBjG,iBAAiB,CAAEtC,UAASC,YAAWH,YAGlE2I,EAAyB,IACpBpC,IAAWpB,aAAaxD,UAGnC,IAAIiH,EAMA,CACAjG,QAAS,EACTC,WAAY,EACZ5C,MAAOsI,EAAMO,OACb3G,aAAc,GACdC,gBAAiB,IAErB,MAAM2G,EAAc,KAChBpC,EAAS+B,EAAoB/F,iBAAiBkG,KAGlD,IA4CIxN,EAAOmL,IAAWb,KAAKtK,KACvB2N,EAAiB3N,EbpSR,KaoS8C4N,oBAAU5N,GAAM6N,IAAIzN,GAASA,EAAMb,OAAU,IbnS9EuO,OAAO,CAACC,EAAKxO,IAChCwO,EAAMxO,EAAMkO,OACpB,IaiSgH,EAG/G,IAAIrQ,EAFJuQ,EAAiB3P,KAAKgQ,MAAML,EAAiBT,EAAMO,QAGnD,IAAIQ,EAAgB,GAChBC,EAAI,EACR,UAAW,IAAIC,KAnDUzQ,gBAAgBwP,GACrC,IAAIkB,EAA0D,GAE1DF,EAAI,GACR,SAASG,IACL,GAAIH,IAAMhB,EAAMO,QAAUF,IAItB,OAHAC,EAAYhG,WAAa0G,EACzBV,EAAYzG,gBAAmB,QAC/B2G,IAIJ,IAAIY,EAAIpB,EAAMgB,GACdV,EAAYhG,WAAa0G,EACzBV,EAAYzG,gBAAkBuH,EAAElI,KAChCsH,IACAQ,IAEAE,EAAU/N,KACN,IAAI9C,QAAQG,MAAOF,EAAS+Q,KACxB,IAAI9J,EACJ,UACU0I,EAAoBqB,QAAQF,GAClC7J,QAAa0I,EAAoBsB,OAAO,CAAE/J,WAC1C2J,IACA7Q,EAAQ,CAAE8O,KAAMgC,EAAG7J,KAAMA,IAC3B,MAAOiK,GACLtR,EAAQsR,EACRT,EAAgB,GAAEK,EAAElI,2CACpBmI,EAAOG,OAKvBL,GAEA,IAAIM,EAAI,EACR,KAAOA,EAAIP,EAAUX,oBACLW,EAAUO,UACfP,EAAUO,GACjBA,IAWeC,CAAmB1B,GAAQ,CAC9C,GAAIK,IACA,MAGJ,MAAM,KAAEjB,EAAF,KAAQ7H,GAAS0J,EAEvB,IAAI5O,EAAQ+M,EAAKlG,KACjB,GAAoB,UAAhB6B,EACA,IAAK,IAAD,EACA1I,EAAK,gBAAU8M,GAA0BC,EAAMpE,UAA1C,QAA2DoE,EAAKlG,KACvE,MAAOsI,GACL9R,QAAQQ,MAAMsR,GAItB,MAAMG,EAAgBtP,EAAMuP,YAAY,KACpCD,EAAgB,IAChBtP,EAAQA,EAAMwP,UAAU,EAAGF,IAE3BlB,GAAkB,IAClBpO,EAAQA,EAAMwP,UAAU,EAAGpB,IAG/BH,EAAYjG,QAAU2G,IACtBV,EAAY1G,aAAevH,EAC3BmO,IACAJ,EAAuB,CAAExI,QAAS,EAAGC,UAAW,EAAGH,MAAO,MAC1D,UACI,OAAM4G,QAAN,IAAMA,OAAN,EAAMA,EAAcwD,OAAOzP,EAAOkF,EAAM2I,EAAYE,IACtD,MAAOoB,GACLtR,EAAQsR,EACRT,EAAgB,GAAE3B,EAAKlG,kCACvB,OAIR,IAAI6I,EAAgC,CAAC5B,EAAoBpG,YAAW,IAEhE7J,IACAR,QAAQQ,MAAMA,GACd6R,EAAmBA,EAAiBC,OAAO,CACvCC,EAAkBlI,YAAW,GAC7BkI,EAAkBrH,gBAAgBmG,MAI1C3C,EAASM,uBAAaqD,IACtBhM,KAAcqI,I,2HC9XtB,MAAM8D,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCI,GAAeJ,IACxB,MAAMjE,EAAWsE,cAEjB,IAAItJ,EAAUnI,EAAwBrB,GAASA,EAAMuN,SAASrB,oBAM9D,OACI,kBAAC6G,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,4BAEhB,kBAACC,GAAA,EAAD,CAAaC,GAAG,4BAAhB,sBACA,kBAACC,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,+CACA,4BACI,4BACI,kBAACC,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,0BAA0B3P,OAAO,UAAtE,UAEQ,IAHZ,MAIQ,IACJ,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,qCAAqC3P,OAAO,UAAjF,YALJ,4DAUA,4BACI,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,2CAA2C3P,OAAO,UAAvF,aADJ,0DAMA,4BACI,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,0BAA0B3P,OAAO,UAAtE,cADJ,sDAMA,4BACI,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,wCAAwC3P,OAAO,UAApF,YADJ,yDAMA,4BACI,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,6CAA6C3P,OAAO,UAAzF,kBADJ,4CAMA,4BACI,kBAACyP,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,2BAA2B3P,OAAO,UAAvE,eADJ,mCAOJ,kBAACwP,GAAA,EAAD,oBACA,4BACI,iDACuB,IACnB,kBAACC,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,yCAAyC3P,OAAO,UAArF,2CAIJ,iDACuB,IACnB,kBAACyP,GAAA,EAAD,CACIC,IAAI,sBACJC,KAAK,iFACL3P,OAAO,UAHX,4BAUZ,kBAAC4P,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QA9EA,KAChBtF,EAASd,GAAWjB,iBAAgB,MA6E5B,Y,mPC/EhB,MAAMsH,GAAYC,aAAWrP,IAAK,CAC9BsP,aAAc,CACVC,SAAUvP,EAAMG,QAAQ,OAInBqP,GAAU,WACnB,MAAMC,EAAUL,KACVvF,EAAWsE,cAEjB,IAAI,SAAElH,EAAF,SAAYK,GAAa5K,EAAwBrB,GAASA,EAAMuN,UAChE8G,EAAYhT,EAAwBrB,IAAK,mCAAIA,EAAMwN,KAAKtK,YAAf,aAAI,EAAiBT,aAArB,QAA+B,KAE5E,MAAM6R,EAAgB/B,IAAMgC,OAAiC,OACtDC,EAAcC,GAAmBlC,IAAMmC,SAA6B,MACrEC,EAAW9V,QAAQ2V,GAEnBI,EAAiBC,sBAClBC,IACGL,EAAgBK,EAAMC,gBAE1B,CAACN,IAGCO,EAAiBH,sBAAY,KAC/BrG,EAASd,GAAWlB,aAAaP,KAClC,CAACuC,EAAUvC,IAERgJ,EAAkBJ,sBAAY,KAChCJ,EAAgB,OACjB,CAACA,IAEES,EAAiBL,sBAAY,KAC/BrG,GFsFG5N,eAAe4N,GAElB,IADqB1P,OAAOqW,QAAS,4DAEjC,OAEJ,MAAM,aAAEzG,GAAiBD,EACzBD,EAASK,GAAgBzC,YAAW,UAC9BsC,EAAc0G,WACpBjP,KAAcqI,ME7FdyG,KACD,CAACzG,EAAUyG,IAERI,EAAgBR,sBAAY,KAC9BrG,EAASrI,MACT8O,KACD,CAACzG,EAAUyG,IAERK,EAAmBT,sBAAY,KACjCrG,EACIM,uBAAa,CACTyG,EAAoBpL,YAAW,GAC/BoL,EAAoBzK,eAAeuJ,GACnCkB,EAAoBxK,UAAU,MAGtCkK,KACD,CAACzG,EAAUyG,EAAiBZ,IAEzBmB,EAAaX,sBAAY,KAC3BrG,EAASd,GAAWvB,SAAS,YAC7B8I,KACD,CAACzG,EAAUyG,IAERQ,EAAkBZ,sBAAY,KAChCrG,EAASd,GAAWjB,iBAAgB,IACpCwI,KACD,CAACzG,EAAUyG,IAERS,EAAmBb,sBACpBC,IAEgD,IAAD,GAD5CA,EAAMa,kBACFb,EAAM9Q,SAAWsQ,EAAc7J,WAE/B,UAAA6J,EAAc7J,eAAd,SAAuBmL,SAE3BX,KAEJ,CAACA,IAGCY,EAAY,GAuElB,MAtEiB,SAAbjK,IACAiK,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,SAASkS,QAASuB,GAC5B,kBAACU,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAagC,SAAS,WAE1B,kBAACC,GAAA,EAAD,qBAGRL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,QAAQkS,QAASwB,GAC3B,kBAACS,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAUgC,SAAS,WAEvB,kBAACC,GAAA,EAAD,sBAGRL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,OAAOkS,QAASoB,GAC1B,kBAACa,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAmBgC,SAAS,WAEhC,kBAACC,GAAA,EAAD,oBAGRL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,OAAOkS,QAAS0B,GAC1B,kBAACO,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAegC,SAAS,WAE5B,kBAACC,GAAA,EAAD,gBAIZL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,WAAWkS,QAASkB,GAC9B,kBAACe,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAE5BhI,EAAW,kBAAC,KAAD,CAAcgK,SAAS,UAAa,kBAAC,KAAD,CAAeA,SAAS,WAE5E,kBAACC,GAAA,EAAD,oBAGRL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,QAAQkS,QAAS2B,GAC3B,kBAACM,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAUgC,SAAS,WAEvB,kBAACC,GAAA,EAAD,gBAGRL,EAAUtS,KACN,kBAACuS,GAAA,EAAD,CAAUlU,IAAI,SAASkS,QAAS4B,GAC5B,kBAACK,GAAA,EAAD,CAAcC,UAAW5B,EAAQH,cAC7B,kBAAC,KAAD,CAAYgC,SAAS,WAEzB,kBAACC,GAAA,EAAD,KACI,kBAACzC,GAAA,EAAD,CACIC,IAAI,sBACJC,KAAK,2CACL3P,OAAO,SACP0O,IAAK4B,EACLR,QAAS4B,GALb,wBAcR,kBAAC,IAAMS,SAAP,KACI,kBAACC,GAAA,EAAD,CAAYC,aAAW,UAAUC,gBAAc,eAAeC,gBAAc,OAAOzC,QAASc,GACxF,kBAAC,KAAD,OAEJ,kBAAC4B,GAAA,EAAD,CAAMlD,GAAG,eAAemD,SAAUjC,EAAckC,aAAW,EAAC1D,KAAM2B,EAAUgC,QAAS1B,GAChFY,K,yBCjKjB,MAAM9B,GAAYC,aAAWrP,IAAK,CAC9B6I,KAAM,CACFoJ,SAAU,WACVC,KAAM,WACNC,QAAS,OACTC,eAAgB,SAChBC,cAAe,SACfC,WAAY,UAEhBC,OAAQ,CACJC,UAAWxS,EAAMG,QAAQ,GACzBoP,SAAU,KAEdpP,QAAS,CACLqS,UAAWxS,EAAMG,QAAQ,IAE7BsS,WAAY,CACRD,UAAWxS,EAAMG,QAAQ,GACzBuS,MAAO,GACPC,OAAQ,IAEZC,IAAK,CACDC,UAAW,aACXL,UAAWxS,EAAMG,QAAQ,IAE7B2S,QAAS,CACLX,QAAS,OACTC,eAAgB,oBAIXW,GAAWjF,IACpB,MAAM2B,EAAUL,KAEVvF,EAAWsE,eACX,iBAAE9G,EAAF,cAAoBF,EAApB,eAAmCC,GAAmB1K,EAAwBrB,GAASA,EAAMuN,UAC/FxB,EAAe4L,cAAc1Y,MAAM,UAKvC,MAAO2Y,EAAoBC,GAAqBnD,oBAAS,GAMzD,OACI,kBAAC,IAAMyB,SAAP,KACI,kBAAC2B,GAAA,EAAD,CAAK9B,UAAW5B,EAAQqD,SACpB,kBAACM,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,MAAnC,gBAGA,kBAAC9D,GAAD,OAEJ,kBAAC4D,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,SAAnC,mCAGA,kBAACH,GAAA,EAAD,CAAK9B,UAAW5B,EAAQ5G,MACnBxB,EACG,kBAAC,IAAMmK,SAAP,KACI,kBAAC4B,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,YAAYC,MAAM,SAASlC,UAAW5B,EAAQtP,SAAjF,iDAIA,kBAAC+O,GAAA,EAAD,CAAQoE,QAAQ,YAAYE,MAAM,UAAUrE,QAAS,IAAMtF,GHlCxE5N,eAAe4N,EAAuBH,GACzCG,EAASK,GAAgBxC,kBAAiB,UAEpCoC,EAAgB4B,mBAAoB+H,OAE1C,IAEI,SADsB3J,EAAgBC,aAAc2J,UAGhD,YADA7J,EAASK,GAAgB1C,SAAS,SAGxC,MAAOyF,GACL9R,QAAQQ,MAAMsR,GAIlB,IAEI,SADmBnD,EAAgBC,aAAc4J,OAG7C,YADA9J,EAASK,GAAgB1C,SAAS,SAGtCqC,EAASM,uBAAa,CAACD,GAAgBvC,kBAAmB,qBAAqBuC,GAAgBxC,kBAAiB,MAClH,MAAOuF,GACL9R,QAAQQ,MAAMsR,GACd,IAAI2G,EAAW3G,EAAc2G,QAC7B/J,EAASM,uBAAa,CAACD,GAAgBvC,kBAAkBiM,GAAU1J,GAAgBxC,kBAAiB,UGQX2J,UAAW5B,EAAQ8C,QAAhG,WAIA,kBAACsB,GAAA,EAAD,CAAalY,OAAO,EAAM0V,UAAW5B,EAAQtP,QAAS2T,MAAO,CAAEC,WAAY5M,EAAgB,UAAY,WACnG,kBAAC6M,GAAA,EAAD,KAAiB5M,KAIzB,kBAAC,IAAMoK,SAAP,KACI,kBAAC4B,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,YAAYC,MAAM,SAASlC,UAAW5B,EAAQtP,SAAjF,yCAEI,kBAAC2O,GAAA,EAAD,CAAMC,IAAI,sBAAsBC,KAAK,IAAIG,QAnCzCgB,IACpBA,EAAM8D,iBACNf,GAAkB,KAiCE,cAKJ,kBAACpE,GAAA,EAAD,CAAMC,IAAI,sBAAsB1P,OAAO,SAAS2P,KAAK,kCACjD,yBAAKkF,IAAI,cAAcrR,IAAKsR,KAAgB9C,UAAW5B,EAAQgD,cAGnE,kBAACW,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,YAAYC,MAAM,SAASlC,UAAW5B,EAAQtP,SAAjF,YACc,IACV,kBAAC2O,GAAA,EAAD,CAAMC,IAAI,sBAAsB1P,OAAO,SAAS2P,KAAK,kCAArD,UAEQ,IAJZ,WAQCiE,EACG,oCACI,kBAACG,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,QAAQjC,UAAW5B,EAAQmD,KAA7D,qDACuD,IACnD,kBAAC9D,GAAA,EAAD,CAAMC,IAAI,sBAAsB1P,OAAO,SAAS2P,KAAK,kCAArD,UAEQ,IAJZ,MAKQ,IACJ,kBAACF,GAAA,EAAD,CAAMC,IAAI,sBAAsB1P,OAAO,SAAS2P,KAAK,4BAArD,eANJ,KAWA,4BACI,qHACA,0GAGR,OAIhB,kBAACd,GAAD,Q,mKCvHZ,MAAMP,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCsG,GAAgBtG,IACzB,IAAIjE,EAAWsE,cAEXkG,EAAsB3X,EAAwBrB,GAASA,EAAMgN,aAAaxD,SAC1EyP,EAAoB5X,EAAwBrB,GAASA,EAAMgN,aAAavK,OACxEyW,EAAoB7X,EAAwBrB,GAASA,EAAMgN,aAAaxJ,OAE5E,MAAM2V,EAAOD,EAAoB,EAAK,OAAS,QAEzCE,EAAqB,KACvB5K,EAAS+G,EAAoBpL,YAAW,KAGtCkP,EAAiB,KAEf7K,EADA0K,EAAoB,EJiFzB,UAAoB,QAAEvS,IACzB,OAAO/F,eAAe4N,GAClB,MAAM,aAAEE,GAAiBD,QACnBC,EAAc4K,WAAW3S,GAC/B6H,EAAS+G,EAAoBpL,YAAW,IACxChE,KAAcqI,IIrFD8K,CAAW,CAAE3S,QAASsS,IJkEpC,UAAqB,MAAEzV,EAAF,QAASmD,IACjC,OAAO/F,eAAe4N,GAClB,MAAM,aAAEE,GAAiBD,EACzBD,EAAS+G,EAAoBpL,YAAW,IACxC,UACUuE,EAAc6K,YAAY/V,EAAOmD,GACzC,MAAOiL,GACL9R,QAAQQ,MAAMsR,GACdpD,EAASM,uBAAa,CAACuD,EAAkBlI,YAAW,GAAOkI,EAAkBrH,gBAAiB,qBAElG7E,KAAcqI,II1ED+K,CAAY,CAAE/V,MAAO0V,EAAmBvS,QAASsS,MAIlE,OACI,kBAAClG,GAAA,EAAD,CACIC,KAAMgG,EACNrC,QAASyC,EACTnG,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,uBAEhB,kBAACC,GAAA,EAAD,CAAaC,GAAG,uBAAhB,UAA8C6F,GAC9C,kBAAC5F,GAAA,EAAD,KACI,kBAACiG,GAAA,EAAD,CACIC,WAAS,EACTnG,GAAG,OACHoG,MAAQ,GAAEP,SACVrL,KAAK,OACLoF,WAAS,EACTrR,MAAOoX,EACPU,UAAW7E,IACQ,UAAfA,EAAMlT,KAAmByX,KAE7BO,SAAU9E,IACNtG,EAAS+G,EAAoBzK,eAAegK,EAAM9Q,OAAOnC,MAAMoQ,UAAU,EAAG,WAIxF,kBAAC2B,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QAASsF,GAAjB,UACA,kBAACvF,GAAA,EAAD,CAAQsE,MAAO,UAAWrE,QAASuF,GAAnC,a,cCrDhB,MAAMtF,GAAYC,aAAWrP,IAAK,CAC9BkV,aAAc,CACV1C,UAAWxS,EAAMG,QAAQ,IAE7BgV,YAAa,CACT3C,UAAWxS,EAAMG,QAAQ,IAE7BiV,YAAa,CACT5C,UAAWxS,EAAMG,QAAQ,OAI3BwN,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCuH,GAAgBvH,IACzB,MAAM2B,EAAUL,KACVvF,EAAWsE,cAEjB,IAAI,QACAtJ,EADA,UAEAC,EAFA,gBAGAC,EAHA,kBAIAC,EAJA,cAKAC,EALA,WAOAC,EAPA,aAQAE,EARA,gBASAD,EATA,aAUAE,EAVA,gBAWAC,GACA5I,EAAwBrB,GAASA,EAAMiN,cAE3C,MAAMgN,EAAqBpF,sBAAY,KACnCrG,EAAS+B,EAAoBhG,iBAAgB,KAC9C,CAACiE,IAEJ,IAAI0L,EAAgBhZ,KAAKgQ,MAAOxH,EAAkBE,EAAiB,KAC/DuQ,EAAcjZ,KAAKgQ,MAAOvH,EAAoBC,EAAiB,KAC/DwQ,EAAiBlZ,KAAKgQ,MAAOpH,EAAkBD,EAAc,KACjE,OACI,kBAACkJ,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,2BAChBiH,mBAAiB,kCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,4BAAhB,gBACA,kBAACC,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAmBF,GAAG,kCACE,MAAnB8G,GAA0BtQ,IAAoBD,EACxC,uBACA,cAAaC,EAAkB,QAAQD,MAAeI,KAEjE,kBAACqQ,GAAA,EAAD,CACItE,UAAW5B,EAAQ0F,YACnB7B,QAA4B,IAAnBmC,EAAuB,gBAAkB,cAClDjC,MAAM,UACNtW,MAAOuY,IAEX,kBAACtC,GAAA,EAAD,CAAK9B,UAAW5B,EAAQyF,cAAeO,EAAvC,KAEA,kBAAC5G,GAAA,EAAD,CAAmBF,GAAG,iCAAiC0C,UAAW5B,EAAQ2F,aAA1E,aACehQ,EADf,OACiCF,EADjC,KAC+CG,GAE/C,kBAACsQ,GAAA,EAAD,CACItE,UAAW5B,EAAQ0F,YACnB7B,QAAQ,SACRE,MAAM,YACNtW,MAAOqY,EACPK,YAAaJ,IAEjB,kBAACrC,GAAA,EAAD,CAAK9B,UAAW5B,EAAQyF,cAAeK,EAAvC,MAEJ,kBAACtG,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQ2G,SAAU/Q,EAAWqK,QAASmG,GACjCxQ,EAAa,kCAAoC,uBCtFhEsK,GAAYC,aAAWrP,IAAK,CAC9BkV,aAAc,CACV1C,UAAWxS,EAAMG,QAAQ,IAE7BgV,YAAa,CACT3C,UAAWxS,EAAMG,QAAQ,OAI3BwN,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCgI,GAAgBhI,IACzB,MAAM2B,EAAUL,KAEhB,IAAI,QAAEvK,EAAF,WAAWK,EAAX,UAAuB6B,EAAvB,aAAkC3B,EAAlC,aAAgDC,GAAiB3I,EAAwBrB,GAASA,EAAMsN,cAExG4M,EAAgBhZ,KAAKwZ,MAAM3Q,GAC/B,OACI,kBAACgJ,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,4BAChBiH,mBAAiB,mCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,6BAAhB,gBACA,kBAACC,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAmBF,GAAG,mCAChB,mBAAkB5H,EAAY,QAAQ7B,MAAeG,KAE3D,kBAACsQ,GAAA,EAAD,CACItE,UAAW5B,EAAQ0F,YACnB7B,QAASlO,GAAgB,EAAI,cAAgB,gBAC7CoO,MAAM,UACNtW,MAAOqY,IAEX,kBAACpC,GAAA,EAAD,CAAK9B,UAAW5B,EAAQyF,cAAeK,GAAiB,EAAK,GAAEA,KAAoB,KAEvF,kBAACtG,GAAA,EAAD,QC3CNtB,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCkI,GAAelI,IACxB,MAAMjE,EAAWsE,cAEjB,IAAI,QAAEtJ,EAAF,MAAWlJ,GAAUe,EAAwBrB,GAASA,EAAMkN,aAEhE,MAAM0N,EAAc/F,sBAAY,KAC5BrG,EAASqM,EAAmB1Q,YAAW,KACxC,CAACqE,IAEJ,OACI,kBAACuE,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,2BAChBiH,mBAAiB,kCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,4BAAhB,SACA,kBAACC,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAmBF,GAAG,kCAAkChT,IAE5D,kBAACsT,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QAAS8G,GAAjB,YC/BVtI,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGlCqI,GAAerI,IACxB,MAAMjE,EAAWsE,cAEjB,IAAI,QAAEtJ,EAAF,UAAWyB,GAAc5J,EAAwBrB,GAASA,EAAMmN,aAEpE,MAAM4N,EAAkBlG,sBAAY,KAChC/V,OAAOC,SAASic,UACjB,IAEGC,EAAepG,sBAAY,KAC7BrG,EAASP,EAAmB/C,YAC7B,CAACsD,IAEJ,OACI,kBAACuE,GAAA,EAAD,CACIC,KAAMxJ,IAAYyB,EAClBgI,SAAU,KACVC,WAAW,EACXgI,OAAQ,QACR/H,oBAAqBb,GACrBc,kBAAgB,2BAChBiH,mBAAiB,kCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,4BAAhB,6CACA,kBAACC,GAAA,EAAD,KACI,kBAACwE,GAAA,EAAD,CAAYI,MAAM,gBAAgBF,QAAQ,QAAQD,UAAU,OAA5D,qEAEI,4BACI,mEACA,qDACA,6EALR,wJAWJ,kBAACpE,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QAASmH,EAAcE,KAAK,SAApC,uBAGA,kBAACtH,GAAA,EAAD,CAAQC,QAASiH,EAAiB5C,MAAM,WAAxC,sB,4CCtChB,MAAM7F,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGzCsB,GAAYC,aAAWrP,IAAK,CAC9ByW,UAAW,CACPtE,QAAS,OACTE,cAAe,OAEnBqE,YAAa,CACTnH,SAAU,IAEdoH,aAAc,CACVpH,SAAU,IAEdqH,cAAe,CACXzE,QAAS,OACT0E,SAAU,OACVzE,eAAgB,iBAEpB0E,WAAY,CACR3E,QAAS,OACTE,cAAe,UAEnB0E,iBAAkB,CACdvE,UAAWxS,EAAMG,QAAQ,OAIpB6W,GAAiBlJ,IAC1B,MAAMjE,EAAWsE,cACXsB,EAAUL,KAEhB,IAAI,QAAEvK,EAAF,OAAW5B,EAAX,YAAmBuD,EAAnB,YAAgCC,GAAgB/J,EAAwBrB,GAASA,EAAMoN,eAE3F,MAAMwN,EAAc/F,sBAAY,KAC5BrG,EAASoN,EAAqBzR,YAAW,KAC1C,CAACqE,IAEEqN,EAAqBhH,sBACvB,CAACiH,EAAIC,KACiB,OAAdA,GAGJvN,EAASoN,EAAqBvQ,UAAU0Q,KAE5C,CAACvN,IAGCwN,EAA0BnH,sBAC5B,CAACiH,EAAIG,KACsB,OAAnBA,GAGJzN,EAASoN,EAAqBtQ,eAAe2Q,KAEjD,CAACzN,IAGC0N,EAA0BrH,sBAC3BC,IACGtG,EAASoN,EAAqBrQ,eAAeuJ,EAAM9Q,OAAOnC,SAE9D,CAAC2M,IAGC2N,EAAgBtH,sBAAY,KAC9B+F,IACApM,EAAS2B,GAAiBsC,EAAMrC,MAAOxI,EAAQuD,EAAaC,KAC7D,CAACoD,EAAUiE,EAAO7K,EAAQuD,EAAaC,EAAawP,IAEvD,OACI,kBAAC7H,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,6BAChBiH,mBAAiB,oCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,8BAAhB,mBACA,kBAACC,GAAA,EAAD,CAAeyC,UAAW5B,EAAQmH,eAC9B,kBAAC/C,GAAA,EAAD,KACI,kBAACT,GAAA,EAAD,CAAYC,UAAU,QAAQC,QAAQ,UAAUE,MAAM,iBAAtD,kBAGA,kBAACiE,GAAA,EAAD,CAAmBva,MAAO+F,EAAQyU,WAAS,EAACzC,SAAUiC,EAAoBV,KAAK,SAC3E,kBAACmB,GAAA,EAAD,CAActG,UAAW5B,EAAQkH,aAAczZ,MAAM,MAArD,MAGA,kBAACya,GAAA,EAAD,CAActG,UAAW5B,EAAQkH,aAAczZ,MAAM,OAArD,OAGA,kBAACya,GAAA,EAAD,CAActG,UAAW5B,EAAQkH,aAAczZ,MAAM,OAArD,SAKR,yBAAKmU,UAAW5B,EAAQqH,YACpB,kBAACjD,GAAA,EAAD,CAAaxC,UAAW5B,EAAQiH,aAC5B,kBAACtD,GAAA,EAAD,CAAYC,UAAU,QAAQC,QAAQ,UAAUE,MAAM,iBAAtD,eAGA,kBAACiE,GAAA,EAAD,CAAmBva,MAAOsJ,EAAakR,WAAS,EAACzC,SAAUoC,EAAyBb,KAAK,SACrF,kBAACmB,GAAA,EAAD,CAActG,UAAW5B,EAAQkH,aAAczZ,MAAM,QAArD,YAGA,kBAACya,GAAA,EAAD,CAActG,UAAW5B,EAAQkH,aAAczZ,MAAM,SAArD,gBAKS,UAAhBsJ,EACG,kBAACqN,GAAA,EAAD,CAAaxC,UAAW5B,EAAQsH,kBAC5B,kBAACa,GAAA,EAAD,CAAQ1a,MAAOuJ,EAAa+M,MAAM,YAAYqE,MAAO,kBAACC,GAAA,EAAD,MAAW7C,SAAUsC,GACtE,kBAACpG,GAAA,EAAD,CAAUjU,MAAQ,SAAlB,SACA,kBAACiU,GAAA,EAAD,CAAUjU,MAAQ,eAAlB,iBACA,kBAACiU,GAAA,EAAD,CAAUjU,MAAQ,gBAAlB,kBACA,kBAACiU,GAAA,EAAD,CAAUjU,MAAQ,sBAAlB,4BAGR,OAGZ,kBAAC+R,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QAAS8G,GAAjB,UACA,kBAAC/G,GAAA,EAAD,CAAQC,QAASqI,GAAjB,S,wFCxJhB,SAASO,KAA2Q,OAA9PA,GAAWvO,OAAOwO,QAAU,SAAU3Y,GAAU,IAAK,IAAIoN,EAAI,EAAGA,EAAIwL,UAAUjM,OAAQS,IAAK,CAAE,IAAIyL,EAASD,UAAUxL,GAAI,IAAK,IAAIxP,KAAOib,EAAc1O,OAAO2O,UAAUC,eAAeC,KAAKH,EAAQjb,KAAQoC,EAAOpC,GAAOib,EAAOjb,IAAY,OAAOoC,IAA2BS,MAAMH,KAAMsY,WAIhT,IAAI,GAEJ,IAAMK,cAAc,IAAK,CACvBC,KAAM,OACNC,SAAU,WACT,IAAMF,cAAc,IAAK,CAC1BE,SAAU,WACT,IAAMF,cAAc,OAAQ,CAC7BG,EAAG,02CACA,IAAMH,cAAc,OAAQ,CAC/BG,EAAG,g6BAGL,MAAMC,GAAS,EACbC,SACA7a,WACGgQ,KACC,IAAMwK,cAAc,MAAOP,GAAS,CACxCrF,MAAO,GACPC,OAAQ,GACRiG,QAAS,YACT7K,IAAK4K,GACJ7K,GAAQhQ,EAAQ,IAAMwa,cAAc,QAAS,KAAMxa,GAAS,KAAM,IAE/D+a,GAAa,IAAMhL,WAAW,CAACC,EAAOC,IAAQ,IAAMuK,cAAcI,GAAQX,GAAS,CACvFY,OAAQ5K,GACPD,KACY,IC/Bf,SAAS,KAA2Q,OAA9P,GAAWtE,OAAOwO,QAAU,SAAU3Y,GAAU,IAAK,IAAIoN,EAAI,EAAGA,EAAIwL,UAAUjM,OAAQS,IAAK,CAAE,IAAIyL,EAASD,UAAUxL,GAAI,IAAK,IAAIxP,KAAOib,EAAc1O,OAAO2O,UAAUC,eAAeC,KAAKH,EAAQjb,KAAQoC,EAAOpC,GAAOib,EAAOjb,IAAY,OAAOoC,IAA2BS,MAAMH,KAAMsY,WAIhT,IAAI,GAEJ,IAAMK,cAAc,IAAK,CACvBC,KAAM,OACNC,SAAU,WACT,IAAMF,cAAc,IAAK,CAC1BE,SAAU,WACT,IAAMF,cAAc,OAAQ,CAC7BG,EAAG,02CACA,IAAMH,cAAc,OAAQ,CAC/BG,EAAG,sQAGL,MAAMK,GAAS,EACbH,SACA7a,WACGgQ,KACC,IAAMwK,cAAc,MAAO,GAAS,CACxC5F,MAAO,GACPC,OAAQ,GACRiG,QAAS,YACT7K,IAAK4K,GACJ7K,GAAQhQ,EAAQ,IAAMwa,cAAc,QAAS,KAAMxa,GAAS,KAAM,IAE/D,GAAa,IAAM+P,WAAW,CAACC,EAAOC,IAAQ,IAAMuK,cAAcQ,GAAQ,GAAS,CACvFH,OAAQ5K,GACPD,KACY,IC/Bf,SAAS,KAA2Q,OAA9P,GAAWtE,OAAOwO,QAAU,SAAU3Y,GAAU,IAAK,IAAIoN,EAAI,EAAGA,EAAIwL,UAAUjM,OAAQS,IAAK,CAAE,IAAIyL,EAASD,UAAUxL,GAAI,IAAK,IAAIxP,KAAOib,EAAc1O,OAAO2O,UAAUC,eAAeC,KAAKH,EAAQjb,KAAQoC,EAAOpC,GAAOib,EAAOjb,IAAY,OAAOoC,IAA2BS,MAAMH,KAAMsY,WAIhT,IAAI,GAEJ,IAAMK,cAAc,IAAK,CACvBC,KAAM,OACNC,SAAU,WACT,IAAMF,cAAc,IAAK,CAC1BE,SAAU,WACT,IAAMF,cAAc,OAAQ,CAC7BG,EAAG,02CACA,IAAMH,cAAc,OAAQ,CAC/BG,EAAG,6WAGL,MAAMM,GAAS,EACbJ,SACA7a,WACGgQ,KACC,IAAMwK,cAAc,MAAO,GAAS,CACxC5F,MAAO,GACPC,OAAQ,GACRiG,QAAS,YACT7K,IAAK4K,GACJ7K,GAAQhQ,EAAQ,IAAMwa,cAAc,QAAS,KAAMxa,GAAS,KAAM,IAE/D,GAAa,IAAM+P,WAAW,CAACC,EAAOC,IAAQ,IAAMuK,cAAcS,GAAQ,GAAS,CACvFJ,OAAQ5K,GACPD,KACY,IC/Bf,SAAS,KAA2Q,OAA9P,GAAWtE,OAAOwO,QAAU,SAAU3Y,GAAU,IAAK,IAAIoN,EAAI,EAAGA,EAAIwL,UAAUjM,OAAQS,IAAK,CAAE,IAAIyL,EAASD,UAAUxL,GAAI,IAAK,IAAIxP,KAAOib,EAAc1O,OAAO2O,UAAUC,eAAeC,KAAKH,EAAQjb,KAAQoC,EAAOpC,GAAOib,EAAOjb,IAAY,OAAOoC,IAA2BS,MAAMH,KAAMsY,WAIhT,IAAI,GAEJ,IAAMK,cAAc,IAAK,CACvBC,KAAM,OACNC,SAAU,WACT,IAAMF,cAAc,IAAK,CAC1BE,SAAU,WACT,IAAMF,cAAc,OAAQ,CAC7BG,EAAG,02CACA,IAAMH,cAAc,OAAQ,CAC/BG,EAAG,yTAGL,MAAMO,GAAS,EACbL,SACA7a,WACGgQ,KACC,IAAMwK,cAAc,MAAO,GAAS,CACxC5F,MAAO,GACPC,OAAQ,GACRiG,QAAS,YACT7K,IAAK4K,GACJ7K,GAAQhQ,EAAQ,IAAMwa,cAAc,QAAS,KAAMxa,GAAS,KAAM,IAE/D,GAAa,IAAM+P,WAAW,CAACC,EAAOC,IAAQ,IAAMuK,cAAcU,GAAQ,GAAS,CACvFL,OAAQ5K,GACPD,KACY,ICXf,MAAMmL,GAAS,CAACC,GAASC,GAASC,GAASC,IAErCjK,GAAYC,aAAWrP,IAAK,CAC9B,wBAAyB,CACrBsZ,KAAM,CACFC,UAAY,kBAEhBC,GAAI,IAER/C,UAAW,CACPtE,QAAS,OACTD,KAAM,WACN,CAAC9R,EAAaJ,IAAS,CACnB6W,SAAU,SAGlB4C,IAAK,CACDvH,KAAM,WACND,SAAU,WACVyH,WAAY1Z,EAAMG,QAAQ,KAC1BwZ,YAAa3Z,EAAMG,QAAQ,KAC3ByZ,YAAa5Z,EAAMG,QAAQ,GAC3B0Z,aAAc7Z,EAAMG,QAAQ,GAC5B2Z,aAAc9Z,EAAMG,QAAQ,GAC5B4Z,gBAAiB/Z,EAAMga,QAAQC,WAAWC,QAC1C3K,SAAU,IACVoD,OAAQ,GACR,CAACvS,EAAaJ,IAAS,CACnB0Z,WAAY,EACZC,YAAa3Z,EAAMG,QAAQ,KAGnCga,QAAS,CACLC,SAAU,SACVnI,SAAU,WACVS,MAAO,oBACP2H,KAAM,GACN1H,OAAQ,OACR2H,WAAY,UAEhBC,QAAS,CACLtI,SAAU,WACVuI,IAAK,EACLH,KAAM,IAEVI,YAAa,CACT/H,MAAO,GACPC,OAAQ,GACR,MAAO,CACH4F,KAAMvY,EAAMga,QAAQvU,OAAOiV,SAGnCC,uBAAwB,CACpB1I,SAAU,WACVS,MAAO,OACPkI,WAAY,SACZC,cAAe,cACfC,wBAAyB,SACzBC,wBAAyB,IACzBP,IAAK,GACLH,KAAM,GAEVW,cAAe,CACX/I,SAAU,WACVS,MAAO,OACPkI,WAAY,SACZJ,IAAK,GACLH,KAAM,GAEV9H,OAAQ,MAKC0I,GAAW,KAAO,IAAD,MAC1B,MAAMpR,EAAWsE,cAEXnG,EAAetL,EAAwBrB,GAASA,EAAMwN,KAAKb,cAC3DzJ,EAAO7B,EAAwBrB,GAASA,EAAMwN,KAAKtK,MAEnDkR,EAAUL,KACV8L,EAAahL,sBAAY,KAC3BrG,EAASF,GAAQ,UAClB,CAACE,IACEsR,EAAajL,sBAAY,KAC3BrG,EAASF,GAAQ,UAClB,CAACE,IACEuR,EAAalL,sBAAY,KAC3BrG,EAASF,GAAQ,UAClB,CAACE,IACEwR,EAAanL,sBAAY,KAC3BrG,EAASF,GAAQ,UAClB,CAACE,IAEJ,IAAI+J,EAAW,GACX0H,EAAU,iBAAGtT,QAAH,IAAGA,OAAH,EAAGA,EAAcrJ,aAAjB,QAA0B,KACpC4c,EAAW,iBAAGvT,QAAH,IAAGA,OAAH,EAAGA,EAAc3M,aAAjB,QAA0B,KACrCmgB,EAAW,iBAAGxT,QAAH,IAAGA,OAAH,EAAGA,EAAcwT,mBAAjB,SACf,MAAMhd,EAASF,EAAgBC,GAC1Bid,EAEsB,eAAhBD,EACP3H,EAAU,cACe,IAAlBpV,EAAOwN,OACd4H,EAAW,YACJ5L,GAAuC,OAAvBA,EAAarJ,QACpCiV,EAAW,GAAE5L,EAAarJ,MAAQ,OAASH,EAAOwJ,EAAarJ,OAAOb,OANtE8V,EAAW,GASf,MAAO6H,EAAWC,GAAgB3L,mBAAS,IACpC4L,EAAmBC,GAAwB7L,mBAAS,IACpD8L,EAAcC,GAAmB/L,mBAAS,GAI3CgM,EAAiBnM,iBAAY,MAC7BoM,EAASpM,iBAA6B,MAC5CqM,oBAAU,KAgBNC,aAAaH,EAAejW,SAC5B4V,EAAa,GACbK,EAAejW,QAAU9J,WAAW,KAjBZ,MAAO,IAAD,MAC1B,MAAMmgB,EAAQH,EAAOlW,QACfsW,EAAS,iBAAGD,QAAH,IAAGA,OAAH,EAAGA,EAAOE,mBAAV,QAAyB,EAClCC,EAAQ,iBAAGH,QAAH,IAAGA,OAAH,YAAGA,EAAOI,qBAAV,aAAG,EAAsBC,mBAAzB,QAAwC,EAEhDC,EAAsBL,EAAYE,EAAWF,EAAY,GAAK,EACpEV,EAFmBU,EAAYE,EAAwB,IAAZF,EAAmBE,EAAW,GAGzEV,EAAqBa,GACjBA,EAAsB,IACtBV,EAAejW,QAAU9J,WAAW,KAChC0f,EAAa,IACQ,IAAtBe,EAA6B,OAOpCC,IAtBmB,KAyBhB,KACHR,aAAaH,EAAejW,WAEjC,CAACwV,EAAYC,EAAa3H,IAG7B,MAAM+I,EAAwB/M,iBAAY,MAC1CqM,oBAAU,KACNxf,cAAckgB,EAAsB7W,SAChB,YAAhByV,GAA6C,eAAhBA,EAC7BoB,EAAsB7W,QAAUxJ,YAAY,KACxCwf,EAAgB,EAAKD,GAAgB5C,GAAOjN,OAAS,KACtD,KAEH8P,EAAgB,GAEb,KACHrf,cAAckgB,EAAsB7W,WAEzC,CAACyV,EAAaM,IAEjB,MAAMe,EAAY3D,GAAO4C,GACzB,OACI,kBAAC1I,GAAA,EAAD,CAAK9B,UAAW5B,EAAQgH,WACpB,kBAAChF,GAAA,EAAD,CAAYC,aAAW,OAAOvC,QAAS+L,EAAY7J,UAAW5B,EAAQ8C,QAClE,kBAAC,KAAD,OAEJ,kBAACd,GAAA,EAAD,CAAYC,aAAW,OAAOvC,QAASgM,EAAY9J,UAAW5B,EAAQ8C,QAClE,kBAAC,KAAD,OAEJ,kBAACd,GAAA,EAAD,CAAYC,aAAW,OAAOvC,QAASiM,EAAY/J,UAAW5B,EAAQ8C,QAClE,kBAAC,KAAD,OAEJ,kBAACd,GAAA,EAAD,CAAYC,aAAW,OAAOvC,QAASkM,EAAYhK,UAAW5B,EAAQ8C,QAClE,kBAAC,KAAD,OAEJ,yBAAKlB,UAAW5B,EAAQgK,KACpB,yBAAKpI,UAAW5B,EAAQ0K,SACpB,0BACI9I,UAAWoK,EAAYhM,EAAQkL,uBAAyBlL,EAAQuL,cAChEjN,IAAKiO,EACLlI,MACIF,GAAW6H,EAAY,EACjB,CAAEoB,kBAAoB,GAAElB,KAAsBpC,UAAY,cAAakC,OACvE,IAGT7H,IAGT,yBAAKvC,UAAW5B,EAAQ8K,SAAUiB,GAAe,kBAACoB,EAAD,CAAWvL,UAAW5B,EAAQgL,kBCzLzF9M,GAAaC,IAAMC,YAAW,SAChCC,EACAC,GAEA,OAAO,kBAACC,GAAA,EAAD,eAAOC,UAAU,KAAKF,IAAKA,GAASD,OAGzCsB,GAAYC,aAAWrP,IAAK,CAC9ByW,UAAW,CACPtE,QAAS,OACTE,cAAe,MACfC,WAAY,WACZF,eAAgB,gBAChBuH,aAAc3Z,EAAMG,QAAQ,GAC5B2c,SAAU,QAEdpG,YAAa,CACTnH,SAAU,KAEdwN,YAAa,CACTvK,UAAWxS,EAAMG,QAAQ,IAE7B6c,KAAM,CACFC,WAAY,sCACZ3L,SAAUtR,EAAMkd,WAAWC,GAAG7L,SAC9B8L,UAAW,SACXC,aAAcrd,EAAMG,QAAQ,OAIvBmd,GAAa,EAAGC,mBACzB,MAAM1T,EAAWsE,cACXsB,EAAUL,MAEToO,EAASC,GAAc1N,mBAAgD,KACvElJ,EAAeC,GAAoBiJ,mBAAiB,IAE3D,IAAI,QAAElL,GAAYnI,EAAwBrB,GAASA,EAAMqN,YAEzD,MAAMuN,EAAc/F,sBAAY,KAAO,IAAD,EAClCpJ,EAAiB,IACjB,UAAAgD,EAAgB4T,4BAAhB,SAAsCC,gBACtC9T,EAAS+T,GAAkBpY,YAAW,KACvC,CAACqE,IAEEgU,EAAe3N,sBAChBiH,IAA+C,IAAD,IAC3C,MAAM2G,EAAW3G,EAAG9X,OAAOnC,MAC3B4J,EAAiBgX,GACjB,UAAAhU,EAAgB4T,4BAAhB,SAAsCC,gBACtC,UAAA7T,EAAgB4T,4BAAhB,SAAsCK,cAAcD,IAExD,CAAChX,IAGCkX,EAAsB9N,sBAAY,KfuFrC,IAAsB+N,EAAmBH,EetFxCjU,GfsFqBoU,EetFCV,EfsFkBO,EetFJjX,EfuFjC5K,eAAe4N,EAAuBH,GACzCG,EACIM,uBAAa,CACT+T,GAAmB1Y,YAAW,GAC9B0Y,GAAmBlX,YAAY,CAAE9B,WAAY+Y,EAAQjS,OAAQjF,UAAW,EAAG3B,aAAc,EAAGC,aAAc,QAIlH,IAAI9G,EAAOmL,IAAWb,KAAKtK,KACvBC,EAAS2N,oBAAU5N,GAAO4f,OAAOC,GAAKH,EAAQ3b,QAAQ8b,EAAEvf,QAAU,GAEtE,MAAM,aAAEkL,EAAF,qBAAgB2T,GAAyB5T,QACzCA,EAAgBC,aAAc5F,OAEpC,IAAK,IAAKsI,EAAG9N,KAAUH,EAAO6f,UAAW,CAAC,IAAD,EACrCxU,EACIqU,GAAmBlX,YAAY,CAC3B9B,WAAY1G,EAAOwN,OACnBjF,UAAW0F,EACXrH,cAAe,EACfC,aAAY,UAAE1G,EAAMb,aAAR,QAAiB,YAK/BiM,EAAczF,UAAU3F,EAAME,aAC9BkL,EAAc9F,OACpB9I,QAAQC,IAAI,yCACZ,IAAI6W,QAAiBlI,EAAcxF,cAC/B+Z,EAAW,CAAC3f,EAAME,MAAO,EAAG,EAAG,GACnC,KAAoB,OAAboT,IAAsBqM,EAASC,MAAM,CAACC,EAAG/R,IAAM6R,EAAS7R,KAAOwF,EAAUxF,WACtE7Q,EAAM,KACZqW,QAAiBlI,EAAcxF,oBAE7BwF,EAAc7F,cACpB,OAAM6F,QAAN,IAAMA,OAAN,EAAMA,EAAczF,UAAU3F,EAAME,QACpC1D,QAAQC,IAAI,gCAGZ,OAAMsiB,QAAN,IAAMA,OAAN,EAAMA,EAAsBe,WAAWX,UACvC,OAAMJ,QAAN,IAAMA,OAAN,EAAMA,EAAsBgB,wBACtB3U,EAAc9F,OAGpB,IAAI0a,EAA4BhgB,EAAMI,SbvJ9B,UayJF7C,EAA0C,IAAhByiB,EAAuBC,IAAkB,IAAD,EACpE/U,EACIqU,GAAmBlX,YAAY,CAC3B9B,WAAY1G,EAAOwN,OACnBjF,UAAW0F,EACXrH,aAAcwZ,EACdvZ,aAAY,UAAE1G,EAAMb,aAAR,QAAiB,cAMzC,OAAM4f,QAAN,IAAMA,OAAN,EAAMA,EAAsBmB,iBACR,OAApBnB,QAAoB,IAApBA,KAAsBoB,iBAAkB,GAAEngB,EAAMb,eAEhD,OAAM4f,QAAN,IAAMA,OAAN,EAAMA,EAAsBqB,qBAG1BhV,EAAc5F,OACpB0F,EAASqU,GAAmB1Y,YAAW,OevJvCyQ,KACD,CAACsH,EAAc1W,EAAegD,EAAUoM,IAgB3C,OAdAgG,oBAAU,KASFpX,GARJ5I,uBACUvB,UAAUskB,aAAaC,aAAa,CAAEC,OAAO,IACnD,IACIC,SADgBzkB,UAAUskB,aAAaI,oBAEtCjB,OAAOkB,GAA0B,eAAhBA,EAAOC,MACxBlT,IAAIiT,IAAM,CAAOvB,SAAUuB,EAAOvB,SAAU/I,MAAOsK,EAAOtK,SAC/D0I,EAAW0B,GAGXI,IAEL,CAAC1a,EAAS4Y,IAGT,kBAACrP,GAAA,EAAD,CACIC,KAAMxJ,EACNyJ,SAAU,KACVC,WAAW,EACXC,oBAAqBb,GACrBc,kBAAgB,0BAChBiH,mBAAiB,iCAEjB,kBAAChH,GAAA,EAAD,CAAaC,GAAG,2BAAhB,0BACA,kBAACC,GAAA,EAAD,KACI,kBAACwE,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,KAAKjC,UAAW5B,EAAQuN,MACpD,oCAEN,kBAAC5J,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,SAAlC,gEAGA,kBAACF,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,SAAlC,gEAGA,kBAACF,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,SAAlC,8EAGA,kBAACF,GAAA,EAAD,CAAYC,UAAU,IAAIC,QAAQ,SAAlC,oEAGA,kBAACH,GAAA,EAAD,CAAK9B,UAAW5B,EAAQgH,WACpB,kBAAC5C,GAAA,EAAD,CAAaxC,UAAW5B,EAAQiH,aAC5B,kBAACkB,GAAA,EAAD,CAAQ1a,MAAO2J,EAAeoO,SAAU4I,EAAc2B,cAAY,EAACnO,UAAW5B,EAAQsN,aAClF,kBAAC5L,GAAA,EAAD,CAAUjU,MAAM,GAAG2Y,UAAQ,GAA3B,gBAGC2H,EAAQpR,IAAIiT,GACT,kBAAClO,GAAA,EAAD,CAAUlU,IAAKoiB,EAAOvB,SAAU5gB,MAAOmiB,EAAOvB,UACzCuB,EAAOtK,SAIpB,kBAACf,GAAA,EAAD,sBAEJ,kBAACiH,GAAD,QAGR,kBAAChM,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAQC,QAAS8G,GAAjB,UACA,kBAAC/G,GAAA,EAAD,CAAQC,QAAS6O,EAAqBnI,SAA4B,KAAlBhP,GAAhD,mB,wBC/FhB,MAAMuI,GAAYC,aAAWrP,IAAK,CAC9Byf,IAAK,CACDxN,SAAU,WACVyN,OAAQ1f,EAAMG,QAAQ,GACtBwf,MAAO3f,EAAMG,QAAQ,GACrB,CAACC,EAAaJ,IAAS,CACnB0f,OAAQ1f,EAAMG,QAAQ,KAG9B0I,KAAM,CACF+W,UAAW,OACX1N,KAAM,WACNmL,aAAcrd,EAAMG,QAAQ,GAC5B0f,QAAS,OACTnG,WAAY1Z,EAAMG,SAAS,GAC3BwZ,YAAa3Z,EAAMG,SAAS,GAC5B,CAACJ,EAAcC,IAAS,CACpB0Z,WAAY1Z,EAAMG,SAAS,GAC3BwZ,YAAa3Z,EAAMG,SAAS,KAGpC2f,QAAS,CACLtN,UAAWxS,EAAMG,QAAQ,GACzBuZ,WAAY1Z,EAAMG,SAAS,GAC3BwZ,YAAa3Z,EAAMG,SAAS,GAC5B,CAACH,EAAMC,YAAYC,GAAG,IAAyB,EAAnBF,EAAMG,QAAQ,KAAU,CAChDuZ,WAAY1Z,EAAMG,SAAS,GAC3BwZ,YAAa3Z,EAAMG,SAAS,KAGpC4f,aAAc,CACV7N,KAAM,YAEV8N,iBAC2B,UAAvBhgB,EAAMga,QAAQ7Q,KACR,CACIqK,MAAOxT,EAAMga,QAAQiG,UAAUpX,KAC/BkR,gBAAiBmG,aAAQlgB,EAAMga,QAAQiG,UAAUE,MAAO,MAE5D,CACI3M,MAAOxT,EAAMga,QAAQoG,KAAKC,QAC1BtG,gBAAiB/Z,EAAMga,QAAQiG,UAAUK,MAEvDxN,QAAS,CACLX,QAAS,OACTC,eAAgB,iBAEpBjS,QAAS,CACLqS,UAAWxS,EAAMG,QAAQ,IAE7BogB,YAAa,IACLC,UAAyBxgB,GAAOygB,SAChCD,UAAyBxgB,GAAO0gB,aACpCzO,SAAU,SACVE,QAAS,cACTwO,OAAS,aAAY3gB,EAAMga,QAAQC,WAAW2G,QAC9CC,QAAS,QACTC,cAAe,SACfpO,MAAO1S,EAAMG,QAAQ,KACrBwZ,YAAa3Z,EAAMG,QAAQ,KAE/B4gB,UAAW,CACP3G,SAAU,SACV9L,SAAU,OACV0S,aAAc,YAGlBC,aAAc,CACVrG,WAAY,UAEhBsG,iBAAkB,CACdJ,cAAe,UAEnBK,UAAW,CACPvG,WAAY,SACZf,aAAc,EACdnH,MAAQ,OAEZ0O,SAAU,CACNC,OAAQrhB,EAAMqhB,OAAOC,OAAS,EAC9B9N,MAAO,QAEX+N,qBAAsB,CAClBC,eAAgB,YAChBC,oBAAqB,aAIhBC,GAAQ5T,IACjB,IAAIjE,EAAWsE,cACX5P,EAAO7B,EAAwBrB,GAASA,EAAMwN,KAAKtK,MACnDwJ,EAAarL,EAAwBrB,GAASA,EAAMwN,KAAKd,YAE7D,MAAO4Z,EAAUC,GAAehU,IAAMmC,SAAmB,IACnD8R,EAAgBF,EAAS3V,QAExB8V,EAAkBC,GAAuBnU,IAAMmC,SAA6B,MAC7EiS,EAAqB9R,sBAAaC,IACpC4R,EAAoB5R,EAAMC,gBAC3B,IACG6R,EAAsB/R,sBAAY,KACpC6R,EAAoB,OACrB,IACGG,EAA0BhS,sBAC3BiS,IACGtY,EhBKL,SAAmBuY,EAAkBD,GACxC,OAAOlmB,eAAe4N,GAClB,MAAM,aAAEE,GAAiBD,QACnBC,EAAchH,UAAUqf,EAAUD,GACxC3gB,KAAcqI,IgBTD9G,CAAU4e,EAAS,GAAIQ,IAChCF,KAEJ,CAACpY,EAAU8X,EAAUM,IAGnBI,EAAuBnS,sBAAY,KACrCrG,EAAS+T,GAAkBpY,YAAW,KACvC,CAACqE,IAEJoS,oBAAU,KACNpS,EAASrI,OACV,CAACqI,IAEJoS,oBAAU,KACN2F,EAAY,KACb,CAACrjB,IAEJ,IAAK+jB,EAAeC,GAAoB3U,IAAMmC,SAAiB,IAC/D,MAAMyS,EAAStS,sBACX,CAACuS,EAAuBC,KACpBH,EAAiBE,GACjB5Y,EAASoN,EAAqBzR,YAAW,KAE7C,CAACqE,KAEC,aAAE8Y,EAAF,cAAgBC,EAAhB,aAA+BC,EAA/B,KAA6CxU,GAASyU,aAAY,CACpEN,SACAO,OAAQ,CAAE,UAAW,aACrBC,SAAS,IAGPvT,EAAUL,KACV5Q,EAASF,EAAgBC,GAmBzB0kB,EAA0B,CAAC9S,EAAyBzD,KAAkB,IAAD,IACvE,IAAIwW,EAAgBxW,EAChByW,EAAW,oBAAGhX,oBAAU5N,GAAO6kB,KAAKzkB,GAASA,EAAME,QAAUqkB,UAAlD,aAAG,EAA+DplB,aAAlE,QAA2E,GAE1F+L,EACIM,uBAAa,CACTyG,EAAoBpL,YAAW,GAC/BoL,EAAoBzK,eAAegd,GACnCvS,EAAoBxK,SAAS8c,OAazC,OACI,kBAAC,IAAM1R,SAAP,KACI,kBAAC2B,GAAA,EAAD,CAAK9B,UAAW5B,EAAQqD,SACpB,kBAACM,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,MAC9BvL,GAAe,cAEpB,kBAACyH,GAAD,OAEJ,kBAAC4D,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,SACrB,OAAT/U,EACG,kBAAC,IAAMiT,SAAP,KACI,8BAAQ,GAAExS,+BAAqBT,EAAK8b,MAAM,cAAkBrb,+BAAqBT,EAAK4E,OAAO,OAC7F,kBAACkgB,GAAA,EAAD,CACIvlB,MACI,kBAAC,IAAM0T,SAAP,KACI,8BAAQ,GAAExS,+BAAiC,EAAZT,EAAK8b,MAAU,uBAC9C,6BACA,8BAAQ,GAAErb,+BAAiC,EAAZT,EAAK8b,MAAU,wBAGtDiJ,OAAK,GAEL,0BAAMjS,UAAW5B,EAAQ8R,sBAAzB,aAIP,cAGT,kBAACgC,GAAA,EAAD,CACIlS,UAAWmS,mBAAK/T,EAAQqQ,QAAS,CAC7B,CAACrQ,EAAQuQ,kBAAmB6B,EAAgB,KAG/CA,EAAgB,EACb,kBAAC4B,GAAA,EAAD,CACIC,cAAe7B,EAAgB,GAAKA,EAAgBrjB,EAAOwN,OAC3D2X,QAAS9B,EAAgB,EACzB5M,SAnEU9E,IACtBwR,EAAS3V,OAASxN,EAAOwN,OACzB4V,EAAYpjB,EAAO4N,IAAIgS,GAAKA,EAAEvf,QAE9B+iB,EAAY,KAgEAgC,WAAY,CAAE,aAAc,uBAEhC,KACH/B,EAAgB,EACb,kBAACzO,GAAA,EAAD,CAAY/B,UAAW5B,EAAQsQ,aAAcvM,MAAM,UAAUF,QAAQ,aAChEuO,EADL,aAIA,kBAACzO,GAAA,EAAD,CAAYC,UAAU,KAAKC,QAAQ,KAAKjC,UAAW5B,EAAQsQ,eAClD,OAAJxhB,QAAI,IAAJA,OAAA,EAAAA,EAAMT,QAAU,iBAGN,IAAlB+jB,EACG,kBAAC,IAAMrQ,SAAP,KACI,kBAAC6R,GAAA,EAAD,CAASvlB,MAAM,oBACX,kBAACoR,GAAA,EAAD,CAAQyC,gBAAc,YAAYD,aAAW,OAAOvC,QAAS6S,GAA7D,SAIJ,kBAACnQ,GAAA,EAAD,CACIlD,GAAG,YACHmD,SAAUgQ,EACVzT,OAAQyT,EACR9P,QAASiQ,EACT4B,WAAY,CACR/P,MAAO,CACHgQ,UAAW,OAIlBC,MAAMvlB,EAAOwN,QACTuM,KAAK,MACLnM,IAAI,CAACoS,EAAG/R,IAED,kBAAC0E,GAAA,EAAD,CAAUlU,IAAM,OAAMwP,IAAK0C,QAAS,IAAM+S,EAAwBzV,IAC7DA,EAAI,MAM7B,KAEHoV,EAAgB,EACb,kBAAC,IAAMrQ,SAAP,KACI,kBAAC6R,GAAA,EAAD,CAASvlB,MAAM,kBACX,kBAACoR,GAAA,EAAD,CAAQwC,aAAW,SAASvC,QAASkT,GAArC,YAKR,KAEHR,EAAgB,EACb,kBAACwB,GAAA,EAAD,CAASvlB,MAAM,UACX,kBAAC2T,GAAA,EAAD,CAAYC,aAAW,SAASvC,QAlGtBgB,IhBhG3B,IAAsB8N,EgBiGrBpU,GhBjGqBoU,EgBiGC0D,EhBhGnB1lB,eAAe4N,GAIlB,IAHqB1P,OAAOqW,QACvB,4BAA8C,IAAnByN,EAAQjS,OAAe,IAAM,wCAGzD,OAEJ,MAAM,aAAEjC,GAAiBD,EACzBD,EAASK,GAAgBzC,YAAW,KACpCwW,EAAUA,EAAQhf,QACV+kB,UACR,IAAK,IAAInlB,KAASof,QACRlU,EAAcka,YAAYplB,GAEpC2C,KAAcqI,QgBoLM,kBAAC,KAAD,QAGR,KAEHgY,EAAgB,EACb,kBAACwB,GAAA,EAAD,CAASvlB,MAAM,UACX,kBAAC2T,GAAA,EAAD,CAAYC,aAAW,SAASmE,SAA4B,IAAlBgM,EAAqB1S,QA9GlDgB,IAC7B8S,EAAwB9S,EAAOwR,EAAS,MA8GpB,kBAAC,KAAD,QAGR,MAER,kBAACxO,GAAA,EAAD,eAAK9B,UAAW5B,EAAQ5G,MAAU8Z,KAC9B,0BAAWC,KACX,kBAACsB,GAAA,EAAD,CAAO1N,KAAK,SACR,kBAAC2N,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,KACI,kBAACC,GAAA,EAAD,CAAWhT,UAAW5B,EAAQ0R,WAA9B,KACA,kBAACkD,GAAA,EAAD,cACA,kBAACA,GAAA,EAAD,CAAW9Q,MAAM,SAAjB,cAGR,kBAAC+Q,GAAA,EAAD,KACK9lB,EAAO4N,IAAIzN,GACR,kBAACylB,GAAA,EAAD,CACIG,OAAK,EACL5C,SAAUA,EAAS6C,SAAS7lB,EAAME,OAClC5B,IAAK0B,EAAME,MACX4lB,cAAetU,GAAS8S,EAAwB9S,EAAOxR,EAAME,OAC7DsQ,QAASgB,IAASuU,OAlKMhY,EAkKmB/N,EAAME,WAjKrE8iB,EAAS6C,SAAS9X,GAClBkV,EAAYD,EAASxD,OAAO1R,GAAKA,IAAMC,IAEvCkV,EAAY,IAAID,EAAUjV,KAJR,IAA0BA,IAoKxB,kBAAC2X,GAAA,EAAD,CAAWhT,UAAW5B,EAAQ0R,WAAYxiB,EAAME,MAAQ,GACxD,kBAACwlB,GAAA,EAAD,CAAWhT,UAAW5B,EAAQsR,UAAWjjB,MAAOa,EAAMb,OACjDa,EAAMb,OAAU,YAErB,kBAACumB,GAAA,EAAD,CAAW9Q,MAAM,QAAQlC,UAAW5B,EAAQwR,cACxC,0BAAM5P,UAAW5B,EAAQ8Q,aAAc5hB,EAAMG,UAC7C,0BAAMuS,UAAW5B,EAAQyR,kBAAmBviB,EAAMI,eAMtE,kBAAC4lB,GAAA,EAAD,CAAUtT,UAAW5B,EAAQ2R,SAAU/S,KAAMwU,GAA7C,8BAIJ,kBAAC+B,GAAA,EAAD,CAAKpR,MAAM,UAAU9B,aAAW,MAAML,UAAW5B,EAAQgQ,IAAKtQ,QAASd,GACnE,kBAAC,KAAD,OAGJ,kBAACgH,GAAD,MACA,kBAACjB,GAAD,MACA,kBAAC4B,GAAD,MACA,kBAACgB,GAAD,CAAevL,MAAO6W,IACtB,kBAACxM,GAAD,MACA,kBAACwH,GAAD,CAAYC,aAAcoE,IAC1B,kBAACzT,GAAD,MACA,kBAACiI,GAAD,Q,cC3WZ,MAAM/G,GAAYC,aAAWrP,IAAK,CAC9B6kB,OAAQ,CACJnS,MAAO,OACPC,OAAQ,OACR,CAAC5S,EAAcC,IAAS,CACpB0S,MAAO,IACPgH,WAAY,OACZC,YAAa,QAEjB,CAACrZ,EAAeN,IAAS,CACrB0S,MAAO,MAIfkO,MAAO,CACH3O,SAAU,WACVE,QAAS,OACTE,cAAe,SACfwO,QAAS7gB,EAAMG,QAAQ,GACvBwS,OAAQ,oBACR,CAAC5S,EAAcC,IAAS,CACpBwS,UAAWxS,EAAMG,QAAQ,GACzBkd,aAAcrd,EAAMG,QAAQ,GAC5B0gB,QAAS7gB,EAAMG,QAAQ,GACvBwS,OAAQ,KAEZ,CAACrS,EAAeN,IAAS,CACrB2S,OAAQ,MAGhBmS,UAAW,CACP3S,QAAS,OACTG,WAAY,SACZ,CAAClS,EAAaJ,IAAS,CACnB6W,SAAU,QAEd6C,YAAa1Z,EAAMG,QAAQ,IAE/B4kB,oBAAqB,CACjBpL,YAAa3Z,EAAMG,QAAQ,GAC3Bid,UAAW,UAEfgE,SAAU,CACNC,OAAQrhB,EAAMqhB,OAAOC,OAAS,EAC9B9N,MAAO,QAEXwR,aAAc,CACVtS,MAAO,IAEXuS,kBAAmB,CACf/S,KAAM,WACNQ,MAAO,OACPmH,aAAc7Z,EAAMG,QAAQ,GAC5B,CAACC,EAAaJ,IAAS,CACnB4Z,YAAa,OAKnBsL,GAAYC,aAAe,CAC7BnL,QAAS,CACL7Q,KAAM,OACNkX,QAAS,CACLF,MAAO,UACPtX,KAAM,UACNyX,KAAM,UACN8E,aAAc,WAKpBC,GAAaF,aAAe,CAC9BnL,QAAS,CACL7Q,KAAM,WAwCCmc,OApCH,KACR,MAAM7V,EAAUL,KAECjB,cACjB,IAAI,SAAElH,EAAF,QAAYC,EAAZ,SAAqBI,GAAa5K,EAAwBrB,GAASA,EAAMuN,UAE7E,OACI,kBAAC,IAAM4I,SAAP,KACI,kBAAC+T,GAAA,EAAD,CAAevlB,MAAOsH,EAAW4d,GAAYG,IACzC,kBAACG,GAAA,EAAD,MAEA,0BAAMnU,UAAW5B,EAAQoV,QACrB,kBAACY,GAAA,EAAD,CAAOpU,UAAW5B,EAAQmR,OACR,YAAb3Z,EAAyB,kBAAC8L,GAAD,MAAc,KAC1B,SAAb9L,EAAsB,kBAACya,GAAD,MAAW,KAElC,kBAACvO,GAAA,EAAD,CAAK9B,UAAW5B,EAAQwV,mBAAiC,SAAbhe,EAAsB,kBAACgU,GAAD,MAAe,OAErF,kBAAC7H,GAAA,EAAD,CAAYE,QAAQ,QAAQE,MAAM,gBAAgBnC,UAAW5B,EAAQsV,qBAChE,QACD,kBAACjW,GAAA,EAAD,CAAMC,IAAI,sBAAsByE,MAAM,UAAUnU,OAAO,SAAS2P,KAAK,8BAArE,kBAEQ,KACP,IAAI0W,MAAOC,cACX,MAIT,kBAAChB,GAAA,EAAD,CAAUtT,UAAW5B,EAAQ2R,SAAU/S,KAAMnH,GACzC,kBAAC0e,GAAA,EAAD,CAAkBpS,MAAM,gB,0BCzHrC,MAAMqS,GAGTplB,YAAmBqlB,GAAiB,KAAjBA,SAAgB,KAF3BC,qBAE2B,EAC/BD,EAAOE,UAAYrmB,KAAKsmB,cAAcC,KAAKvmB,MAG/C,mBACU,IAAI7D,QAAsBC,IAC5B4D,KAAKomB,gBAAkBhqB,EACvB4D,KAAKmmB,OAAOK,YAAY,CAAE1gB,OAAQ,WAI1C,aAAazC,EAAmBojB,GAK5B,aAJsB,IAAItqB,QAAsBC,IAC5C4D,KAAKomB,gBAAkBhqB,EACvB4D,KAAKmmB,OAAOK,YAAY,CAAE1gB,OAAQ,SAAU2gB,UAASpjB,QAAQ,CAACA,OAEjDA,KAAKqjB,OAG1BriB,YACIrE,KAAKmmB,OAAO9hB,YAGhBiiB,cAAc9O,GACVxX,KAAKomB,gBAAiB5O,GACtBxX,KAAKomB,qBAAkBO,GAI/B,GAAiC,qBAAtBC,mBAAqCC,gBAAgBD,kBAAmB,CAE/E,IAAIE,EACJT,UAAY/pB,UACR,MAAM,OAAEwJ,KAAWihB,GAAWvP,EAAGnU,KACjC,GAAe,SAAXyC,EACA+gB,KAAKG,cAAc7pB,EAAkB,iBACpC0pB,KAAaC,SAAS5rB,KAAM+rB,IACzBH,EAASG,EACTJ,KAAKL,YAAY,CAAE1gB,OAAQ,SAC3BghB,EAAOI,WAAaJ,EAAOI,UAAU,CAACC,EAAaC,IAAmB5rB,QAAQC,IAAK,GAAE2rB,MAAWD,aAEjG,GAAe,WAAXrhB,EAAqB,CAC5B,MAAM,QAAE2gB,EAAF,KAAWpjB,GAAS0jB,EACpBM,EAAa,gBACbC,EAAc,iBACdC,EAAY,IAAIhc,WAAWlI,GACjCyjB,EAAOU,GAAGC,UAAW,GAAEJ,IAAaE,GACpCT,EAAOY,SAAS,CAAE,KAAM,SAAU,KAAKL,EAAY,KAAKC,EAAa,YAAYb,IAGjF,IACI5P,EADWiQ,EAAOU,GAAGG,KAAKL,GACVzQ,KAChB+Q,EAAM,IAAIrc,WAAWsL,EAAO,IAC5BgR,EAAmBf,EAAOU,GAAG9Y,KAAK4Y,EAAY,KAClDR,EAAOU,GAAGM,KAAKD,EAAkBD,EAAK,EAAGA,EAAIvb,OAAQ,IACrDya,EAAOU,GAAGO,MAAMF,GAEhB,IAAInB,EAASkB,EAAII,OAEjBnB,KAAKL,YACD,CACI1gB,OAAQ,SACR4gB,UAEJ,CAACA,MClEjB,MAAMuB,GAAkBrnB,EAAQ,K,yBCkBhCuJ,EAAgBC,aAAe,IAAIvJ,EAAgB,CAAEE,OAAO,IAE5DoJ,EAAgB4B,mBAAqB,IDN9B,MAA8D,cAAD,KACzDmc,mBADyD,OAEzDC,sBAFyD,OAGzDC,SAAkD,GAHO,KAIzDC,WAAsB,GAJmC,KAKzDC,iBAA4B,GAEnC,aACIC,uBAAW,GAGf,cAAcrd,GACVlL,KAAKooB,SAAW,GAChBpoB,KAAKkoB,cAAgBM,wBAAa,CAC9BvnB,OAAS8E,IACL/F,KAAKooB,SAASnpB,KAAK8G,GACnBvK,QAAQC,IAAIsK,EAAQD,OAAQC,EAAQkO,UAExCwU,SAAUtrB,EAAiB,kBAC3BurB,WAAYvrB,EAAiB,yBAE3B6C,KAAKkoB,cAAcS,OAEzB3oB,KAAKmoB,iBAAmB,IAAIjC,GAAiB,IAAI+B,UAC3CjoB,KAAKmoB,iBAAiBrU,OAE5B,IAAI8U,EAAM1d,EAAKlG,KAAK6jB,MAAM,KAAK/jB,OAAO,GACtC,GAAmB,IAAf8jB,EAAIvc,OACJ,MAAM,IAAIyc,MAAO,6BAA4B5d,EAAKlG,QAGtDhF,KAAKqoB,WAAc,eAAcO,EAAI,KACrC5oB,KAAKsoB,iBAAoB,qBAEnBtoB,KAAKkoB,cAAca,MAAM/oB,KAAKqoB,WAAYnd,GAGpD,mBACUlL,KAAKkoB,cAAcc,UAAUhpB,KAAKqoB,WAAa,GAAEroB,KAAKsoB,4BAA8B,iBAE1F,IAAIW,EAAmB,iBACnBC,EAAmB,oBACnB5lB,EAAwB,KACxB4U,EAAuB,KAE3B,IAAK,IAAIiR,KAAQnpB,KAAKooB,SAAU,CAC5B,IAAIztB,EAAQwuB,EAAKlV,QAAQtZ,MAAMsuB,GAC/B,GAAc,OAAVtuB,EAKJ,GADAA,EAAQwuB,EAAKlV,QAAQtZ,MAAMuuB,GACb,OAAVvuB,GAIJ,GAAe,OAAX2I,GAA6B,OAAV4U,EACnB,WAJAA,EAAQvd,EAAM,QALd2I,EAAS3I,EAAM,GAavB,MAAO,CAAE2I,SAAQ4U,SAGrB,cAAa,OAAE5U,IACX,IAAIojB,EACJ,GAAgB,OAAZpjB,EAAiB,CACjB,MAAM8lB,EAAe,GAAEppB,KAAKsoB,6BACtBtoB,KAAKkoB,cAAcc,UAAUhpB,KAAKqoB,WAAYe,EAAa,sBACjE,IAAI,KAAE/lB,SAAerD,KAAKkoB,cAAcJ,KAAKsB,GAC7C1C,EAASrjB,EAAK2kB,WACX,CACH,MAAMoB,EAAe,GAAEppB,KAAKsoB,6BACtBtoB,KAAKkoB,cAAcc,UAAUhpB,KAAKqoB,WAAYe,EAAa,oBACjE,IAAI,KAAE/lB,SAAerD,KAAKkoB,cAAcJ,KAAKsB,GACzC3C,EAAmB,IACvB,OAAQnjB,GACJ,IAAM,MACFmjB,EAAW,MACX,MACJ,IAAM,QACFA,EAAW,MACX,MACJ,IAAM,MACFA,EAAW,KAGnBC,QAAe1mB,KAAKmoB,iBAAkBkB,OAAOhmB,EAAK2kB,OAAQvB,GAI9D,OAFAzmB,KAAKkoB,cAAc/B,OAAO9hB,YAC1BrE,KAAKmoB,iBAAkB9jB,YAChBqiB,ICpFfvc,EAAgB4T,qBAAuB,ICrBhC,MAA4B,cAAD,KACvBuL,cADuB,OAEvBlC,YAFuB,OAGvBmC,kBAHuB,OAIvBC,kBAJuB,OAKvBC,cALuB,EAO9BrL,cAAcD,GACVne,KAAKupB,aAAe,IAAIG,aACxB1pB,KAAKypB,SAAWzpB,KAAKupB,aAAaI,aAClC3pB,KAAKwpB,aAAexpB,KAAKupB,aAAaK,iBAEtC5pB,KAAK8e,WAAWX,GAAUjjB,KAAK,KACZ8E,KAAKupB,aAAcM,wBAAwB7pB,KAAKonB,QACxDrT,QAAQ/T,KAAKypB,UACpBzpB,KAAKypB,SAAU1V,QAAQ/T,KAAKwpB,cAC5BxpB,KAAKwpB,aAAczV,QAAQ/T,KAAKupB,aAAcO,eAItD9L,gBAAiB,IAAD,EACPhe,KAAKupB,eAGV,UAAAvpB,KAAKupB,oBAAL,SAAmBxB,eACZ/nB,KAAKupB,aACZvpB,KAAKof,eAGT,iBAAiBjB,GACb,MAAM4L,EAAoB,CAEtBC,iBAAiB,EACjBC,aAAc,EACd9L,SAAUA,EACV+L,kBAAkB,EAClBC,kBAAkB,EAClBC,WAAY,MACZC,gBAAgB,GAEpBrqB,KAAKonB,aAAersB,UAAUskB,aAAaC,aAAa,CAAEC,MAAOwK,IAGjE,MAAMO,EAActqB,KAAKonB,OAAOmD,iBAC5BD,EAAYje,OAAS,GACrB7Q,QAAQC,IAAI,kBAAmB6uB,EAAY,GAAGE,eAItD,uBACIxqB,KAAKupB,aAAe,IAAIG,aACxB,MAAMxR,EAAQlY,KAAKupB,aAAaM,wBAAwB7pB,KAAKonB,QAC7DpnB,KAAKspB,SAAW,IAAImB,KAASvS,EAAO,CAAEwQ,WAAYvrB,EAAkB,uBACpE6C,KAAKspB,SAASoB,SAGlB,sBACI1qB,KAAKspB,SAAS9kB,OAGlB,oBAAqB,IAAD,EAChB,UAAAxE,KAAKonB,cAAL,SAAa5a,YAAYme,QAAQ3rB,GAASA,EAAMwF,QAGpD2a,iBAAiBhhB,GACb6B,KAAKspB,SAASsB,UAAW5C,IACrB,IAAI6C,EAAMC,IAAIC,gBAAgB/C,GAC1BgD,EAAIC,SAAStS,cAAc,KAC/BsS,SAASC,KAAKC,YAAYH,GAC1BA,EAAE7W,MAAM3B,QAAU,OAClBwY,EAAE3b,KAAOwb,EACTG,EAAE7mB,SAAY,GAAEjG,EAAcC,SAC9B6sB,EAAE1Z,QACF9W,OAAOswB,IAAIM,gBAAgBP,GAC3BI,SAASC,KAAKG,YAAYL,ODnDtC,WAmBI,IAAIM,EAlBJ9wB,OAAO+wB,iBAAiB,eAAgB/T,IAClBlO,GAAMS,WAAWpB,aAAazD,UAIhDsS,EAAGlD,iBACHkD,EAAGgU,YAAe,4CAGlBzwB,WAAaA,UAAU4G,IACvB5G,UAAU4G,IAAI8pB,aAAe,WACzBniB,GAAMY,SAASd,GAAWvB,SAAS,aAGvCyB,GAAMY,SAASd,GAAWnB,qBAAoB,IAKlDzN,OAAO+wB,iBAAiB,sBAAwBttB,IAC5CA,EAAEqW,iBACFgX,EAAiBrtB,IAtBzB,GA0BA,WAEI,IAAIytB,EAA+D,KAC/DC,GAA6B,EAEjC,SAASC,EAAuBlwB,GAAoD,IAAD,EAC/E,OACKiwB,GAE2B,SAA5BjwB,EAAMuN,SAAS3B,WACY,IAA3B5L,EAAMuN,SAAS1B,SAEoB,aAAnC,UAAA7L,EAAMwN,KAAKb,oBAAX,eAAyB3M,SAEO,IAAhCA,EAAMoN,cAAc5D,UACW,IAA/BxJ,EAAMiN,aAAazD,UACY,IAA/BxJ,EAAMsN,aAAa9D,UACW,IAA9BxJ,EAAMmN,YAAY3D,UACY,IAA9BxJ,EAAMkN,YAAY1D,UACW,IAA7BxJ,EAAMqN,WAAW7D,QAIzBoE,GAAMuiB,WAAU,WACZ,MAAMnwB,EAAQ4N,GAAMS,YACkB,IAAlC6hB,EAAuBlwB,IAA6C,OAA1BgwB,EAE1CA,EAAwB/uB,YAAYL,UAChC,IACI,MAAM+L,QAAqB8B,EAAgBC,aAActI,kBACzDwH,GAAMY,SAASI,GAAY9B,gBAAgBH,IAC7C,MAAOpK,GACLzC,QAAQQ,MAAMiC,GACd0tB,GAAoB,IAEzB,MACsC,IAAlCC,EAAuBlwB,IAA8C,OAA1BgwB,IAElD5uB,cAAc4uB,GACdA,EAAwB,SAvCpC,GA4CAI,IAASC,OACL,kBAAC,IAAD,CAAUziB,MAAOA,IACb,kBAAC,GAAD,OAEJ2hB,SAASe,eAAe,SlC3ErB,SAAkBlxB,GACrB,GAA6C,kBAAmBC,UAAW,CAGvE,GADkB,IAAI+vB,IAAImB,eAAwBzxB,OAAOC,SAAS4U,MACpD6c,SAAW1xB,OAAOC,SAASyxB,OAIrC,OAGJ1xB,OAAO+wB,iBAAiB,OAAQ,KAC5B,MAAM1wB,EAAS,uCAEXP,IAiEhB,SAAiCO,EAAeC,GAE5CqxB,MAAMtxB,EAAO,CACTuxB,QAAS,CAAE,iBAAkB,YAE5BlxB,KAAKmxB,IAEF,MAAMC,EAAcD,EAASD,QAAQG,IAAI,gBACjB,MAApBF,EAASG,QAAkC,MAAfF,IAA8D,IAAvCA,EAAY3pB,QAAQ,cAEvE5H,UAAUC,cAAcyxB,MAAMvxB,KAAKC,IAC/BA,EAAauxB,aAAaxxB,KAAK,KAC3BV,OAAOC,SAASic,aAKxB9b,EAAgBC,EAAOC,KAG9BiB,MAAM,KACHP,QAAQC,IAAI,mEApFRkxB,CAAwB9xB,EAAOC,GAI/BC,UAAUC,cAAcyxB,MAAMvxB,KAAK,KAC/BM,QAAQC,IACJ,gHAKRb,EAAgBC,EAAOC,MkCoDvCE,K","file":"static/js/main.ec094e9a.chunk.js","sourcesContent":["module.exports = __webpack_public_path__ + \"static/media/chrome-icon.f3b6c54c.svg\";","module.exports = function() {\n return new Worker(__webpack_public_path__ + \"ffb88193b05ec63929fd.worker.js\");\n};","// This optional code is used to register a service worker.\n// register() is not called by default.\n\n// This lets the app load faster on subsequent visits in production, and gives\n// it offline capabilities. However, it also means that developers (and users)\n// will only see deployed updates on subsequent visits to a page, after all the\n// existing tabs open on the page have been closed, since previously cached\n// resources are updated in the background.\n\n// To learn more about the benefits of this model and instructions on how to\n// opt-in, read https://bit.ly/CRA-PWA\n\nconst isLocalhost = Boolean(\n window.location.hostname === 'localhost' ||\n // [::1] is the IPv6 localhost address.\n window.location.hostname === '[::1]' ||\n // 127.0.0.0/8 are considered localhost for IPv4.\n window.location.hostname.match(/^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/)\n);\n\ntype Config = {\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\n};\n\nexport function register(config?: Config) {\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\n // The URL constructor is available in all browsers that support SW.\n const publicUrl = new URL(process.env.PUBLIC_URL, window.location.href);\n if (publicUrl.origin !== window.location.origin) {\n // Our service worker won't work if PUBLIC_URL is on a different origin\n // from what our page is served on. This might happen if a CDN is used to\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\n return;\n }\n\n window.addEventListener('load', () => {\n const swUrl = `${process.env.PUBLIC_URL}/final-service-worker.js`;\n\n if (isLocalhost) {\n // This is running on localhost. Let's check if a service worker still exists or not.\n checkValidServiceWorker(swUrl, config);\n\n // Add some additional logging to localhost, pointing developers to the\n // service worker/PWA documentation.\n navigator.serviceWorker.ready.then(() => {\n console.log(\n 'This web app is being served cache-first by a service ' + 'worker. To learn more, visit https://bit.ly/CRA-PWA'\n );\n });\n } else {\n // Is not localhost. Just register service worker\n registerValidSW(swUrl, config);\n }\n });\n }\n}\n\nfunction registerValidSW(swUrl: string, config?: Config) {\n navigator.serviceWorker\n .register(swUrl)\n .then(registration => {\n registration.onupdatefound = () => {\n const installingWorker = registration.installing;\n if (installingWorker == null) {\n return;\n }\n installingWorker.onstatechange = () => {\n console.log('state change', installingWorker.state);\n if (installingWorker.state === 'installed') {\n if (navigator.serviceWorker.controller) {\n // At this point, the updated precached content has been fetched,\n // but the previous service worker will still serve the older\n // content until all client tabs are closed.\n console.log(\n 'New content is available and will be used when all ' +\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\n );\n\n // Execute callback\n if (config && config.onUpdate) {\n config.onUpdate(registration);\n }\n } else {\n // At this point, everything has been precached.\n // It's the perfect time to display a\n // \"Content is cached for offline use.\" message.\n console.log('Content is cached for offline use.');\n\n // Execute callback\n if (config && config.onSuccess) {\n config.onSuccess(registration);\n }\n }\n }\n };\n };\n registration.update(); // Check for new version everytime we load the page\n })\n .catch(error => {\n console.error('Error during service worker registration:', error);\n });\n}\n\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\n // Check if the service worker can be found. If it can't reload the page.\n fetch(swUrl, {\n headers: { 'Service-Worker': 'script' },\n })\n .then(response => {\n // Ensure service worker exists, and that we really are getting a JS file.\n const contentType = response.headers.get('content-type');\n if (response.status === 404 || (contentType != null && contentType.indexOf('javascript') === -1)) {\n // No service worker found. Probably a different app. Reload the page.\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister().then(() => {\n window.location.reload();\n });\n });\n } else {\n // Service worker found. Proceed as normal.\n registerValidSW(swUrl, config);\n }\n })\n .catch(() => {\n console.log('No internet connection found. App is running in offline mode.');\n });\n}\n\nexport function unregister() {\n if ('serviceWorker' in navigator) {\n navigator.serviceWorker.ready.then(registration => {\n registration.unregister();\n });\n }\n}\n","import { Disc, formatTimeFromFrames, Encoding } from 'netmd-js';\nimport { useSelector, shallowEqual } from 'react-redux';\nimport { RootState } from './redux/store';\nimport { Mutex } from 'async-mutex';\nimport { Theme } from '@material-ui/core';\n\nexport function sleep(ms: number) {\n return new Promise(resolve => {\n setTimeout(resolve, ms);\n });\n}\n\nexport async function sleepWithProgressCallback(ms: number, cb: (perc: number) => void) {\n let elapsedSecs = 1;\n let interval = setInterval(() => {\n elapsedSecs++;\n cb(Math.min(100, ((elapsedSecs * 1000) / ms) * 100));\n }, 1000);\n await sleep(ms);\n window.clearInterval(interval);\n}\n\nexport function useShallowEqualSelector(selector: (state: TState) => TSelected): TSelected {\n return useSelector(selector, shallowEqual);\n}\n\nexport function debugEnabled() {\n return process.env.NODE_ENV === 'development';\n}\n\nexport function getPublicPathFor(script: string) {\n return `${process.env.PUBLIC_URL}/${script}`;\n}\n\nexport function savePreference(key: string, value: unknown) {\n localStorage.setItem(key, JSON.stringify(value));\n}\n\nexport function loadPreference(key: string, defaultValue: T): T {\n let res = localStorage.getItem(key);\n if (res === null) {\n return defaultValue;\n } else {\n try {\n return JSON.parse(res) as T;\n } catch (e) {\n return defaultValue;\n }\n }\n}\n\nexport function getAvailableCharsForTrackTitle(trackTitles: string[]) {\n const maxChars = 1700; // see https://www.minidisc.org/md_toc.html\n const usedChars = trackTitles.reduce((acc, title) => {\n return acc + title.length;\n }, 0);\n return maxChars - usedChars;\n}\n\nexport function framesToSec(frames: number) {\n return frames / 512;\n}\n\nexport function sanitizeTitle(title: string) {\n return title.normalize('NFD').replace(/[^\\x00-\\x7F]/g, '');\n}\n\nconst EncodingName: { [k: number]: string } = {\n [Encoding.sp]: 'SP',\n [Encoding.lp2]: 'LP2',\n [Encoding.lp4]: 'LP4',\n};\n\nexport function getSortedTracks(disc: Disc | null) {\n let tracks: { index: number; title: string; group: string; duration: string; encoding: string }[] = [];\n if (disc !== null) {\n for (let group of disc.groups) {\n for (let track of group.tracks) {\n tracks.push({\n index: track.index,\n title: track.title ?? `Unknown Title`,\n group: group.title ?? ``,\n encoding: EncodingName[track.encoding],\n duration: formatTimeFromFrames(track.duration, false),\n });\n }\n }\n }\n tracks.sort((l, r) => l.index - r.index);\n return tracks;\n}\n\nexport function asyncMutex(target: any, propertyKey: string, descriptor: PropertyDescriptor) {\n // This is meant to be used only with classes having a \"mutex\" instance property\n const oldValue = descriptor.value;\n descriptor.value = async function(...args: any) {\n const mutex = (this as any).mutex as Mutex;\n const release = await mutex.acquire();\n try {\n return await oldValue.apply(this, args);\n } finally {\n release();\n }\n };\n return descriptor;\n}\n\nexport function forAnyDesktop(theme: Theme) {\n return theme.breakpoints.up(600 + theme.spacing(2) * 2);\n}\n\nexport function belowDesktop(theme: Theme) {\n return theme.breakpoints.down(600 + theme.spacing(2) * 2);\n}\n\nexport function forWideDesktop(theme: Theme) {\n return theme.breakpoints.up(700 + theme.spacing(2) * 2) + ` and (min-height: 750px)`;\n}\n\ndeclare let process: any;\n","import {\n openNewDevice,\n NetMDInterface,\n Disc,\n listContent,\n openPairedDevice,\n Wireformat,\n MDTrack,\n download,\n getDeviceStatus,\n DeviceStatus,\n} from 'netmd-js';\nimport { makeGetAsyncPacketIteratorOnWorkerThread } from 'netmd-js/dist/web-encrypt-worker';\nimport { Logger } from 'netmd-js/dist/logger';\nimport { asyncMutex, sanitizeTitle, sleep } from '../utils';\nimport { Mutex } from 'async-mutex';\n\nconst Worker = require('worker-loader!netmd-js/dist/web-encrypt-worker.js'); // eslint-disable-line import/no-webpack-loader-syntax\n\nexport interface NetMDService {\n mutex: Mutex;\n getDeviceStatus(): Promise;\n pair(): Promise;\n connect(): Promise;\n listContent(): Promise;\n getDeviceName(): Promise;\n finalize(): Promise;\n renameTrack(index: number, newTitle: string): Promise;\n renameDisc(newName: string): Promise;\n deleteTrack(index: number): Promise;\n moveTrack(src: number, dst: number): Promise;\n wipeDisc(): Promise;\n upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ): Promise;\n\n play(): Promise;\n pause(): Promise;\n stop(): Promise;\n next(): Promise;\n prev(): Promise;\n gotoTrack(index: number): Promise;\n getPosition(): Promise;\n}\n\nexport class NetMDUSBService implements NetMDService {\n private netmdInterface?: NetMDInterface;\n private logger?: Logger;\n public mutex = new Mutex();\n public statusMonitorTimer: any;\n\n constructor({ debug = false }: { debug: boolean }) {\n if (debug) {\n // Logging a few methods that have been causing issues with some units\n const _fn = (...args: any) => {\n if (args && args[0] && args[0].method) {\n console.log(...args);\n }\n };\n this.logger = {\n debug: _fn,\n info: _fn,\n warn: _fn,\n error: _fn,\n child: () => this.logger!,\n };\n }\n }\n\n async pair() {\n let iface = await openNewDevice(navigator.usb, this.logger);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n async connect() {\n let iface = await openPairedDevice(navigator.usb, this.logger);\n if (iface === null) {\n return false;\n }\n this.netmdInterface = iface;\n return true;\n }\n\n @asyncMutex\n async listContent() {\n return await listContent(this.netmdInterface!);\n }\n\n @asyncMutex\n async getDeviceStatus() {\n return await getDeviceStatus(this.netmdInterface!);\n }\n\n @asyncMutex\n async getDeviceName() {\n return await this.netmdInterface!.netMd.getDeviceName();\n }\n\n @asyncMutex\n async finalize() {\n await this.netmdInterface!.netMd.finalize();\n }\n\n @asyncMutex\n async renameTrack(index: number, title: string) {\n // Removing non ascii chars... Sorry, I didn't implement char encoding.\n title = sanitizeTitle(title);\n await this.netmdInterface!.cacheTOC();\n await this.netmdInterface!.setTrackTitle(index, title);\n await this.netmdInterface!.syncTOC();\n }\n\n @asyncMutex\n async renameDisc(newName: string) {\n // TODO: This whole function should be moved in netmd-js\n const oldName = await this.netmdInterface!.getDiscTitle();\n const oldRawName = await this.netmdInterface!._getDiscTitle();\n const hasGroups = oldRawName.indexOf('//') >= 0;\n const hasGroupsAndTitle = oldRawName.startsWith('0;');\n\n if (newName === oldName) {\n return;\n }\n\n let newNameWithGroups;\n\n if (hasGroups) {\n if (hasGroupsAndTitle) {\n newNameWithGroups = oldRawName.replace(/^0;.*?\\/\\//, newName !== '' ? `0;${newName}//` : ``); // Replace or delete the old title\n } else {\n newNameWithGroups = `0;${newName}//${oldRawName}`; // Add the new title\n }\n } else {\n newNameWithGroups = newName;\n }\n\n await this.netmdInterface!.cacheTOC();\n await this.netmdInterface!.setDiscTitle(newNameWithGroups);\n await this.netmdInterface!.syncTOC();\n }\n\n @asyncMutex\n async deleteTrack(index: number) {\n await this.netmdInterface!.eraseTrack(index);\n await sleep(100);\n }\n\n @asyncMutex\n async wipeDisc() {\n await this.netmdInterface!.eraseDisc();\n }\n\n @asyncMutex\n async moveTrack(src: number, dst: number) {\n await this.netmdInterface!.moveTrack(src, dst);\n }\n\n async upload(\n title: string,\n data: ArrayBuffer,\n format: Wireformat,\n progressCallback: (progress: { written: number; encrypted: number; total: number }) => void\n ) {\n let total = data.byteLength;\n let written = 0;\n let encrypted = 0;\n function updateProgress() {\n progressCallback({ written, encrypted, total });\n }\n\n let w = new Worker();\n\n let webWorkerAsyncPacketIterator = makeGetAsyncPacketIteratorOnWorkerThread(w, ({ encryptedBytes }) => {\n encrypted = encryptedBytes;\n updateProgress();\n });\n\n // Removing non ascii chars... Sorry, I didn't implement char encoding.\n title = sanitizeTitle(title);\n let mdTrack = new MDTrack(title, format, data, 0x80000, webWorkerAsyncPacketIterator);\n\n await download(this.netmdInterface!, mdTrack, ({ writtenBytes }) => {\n written = writtenBytes;\n updateProgress();\n });\n\n w.terminate();\n }\n\n @asyncMutex\n async play() {\n await this.netmdInterface!.play();\n }\n @asyncMutex\n async pause() {\n await this.netmdInterface!.pause();\n }\n @asyncMutex\n async stop() {\n await this.netmdInterface!.stop();\n }\n @asyncMutex\n async next() {\n await this.netmdInterface!.nextTrack();\n }\n @asyncMutex\n async prev() {\n await this.netmdInterface!.previousTrack();\n }\n\n @asyncMutex\n async gotoTrack(index: number) {\n await this.netmdInterface!.gotoTrack(index);\n }\n\n @asyncMutex\n async getPosition() {\n return await this.netmdInterface!.getPosition();\n }\n}\n","import { NetMDService } from './netmd';\nimport { AudioExportService } from './audio-export';\nimport { MediaRecorderService } from './mediarecorder';\n\ninterface ServiceRegistry {\n netmdService?: NetMDService;\n audioExportService?: AudioExportService;\n mediaRecorderService?: MediaRecorderService;\n}\n\nconst ServiceRegistry: ServiceRegistry = {};\n\nexport default ServiceRegistry;\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface LoadingDialogState {\n visible: boolean;\n cancelled: boolean;\n\n writtenProgress: number;\n encryptedProgress: number;\n totalProgress: number;\n\n trackTotal: number;\n trackConverting: number;\n trackCurrent: number;\n\n titleCurrent: string;\n titleConverting: string;\n}\n\nconst initialState: LoadingDialogState = {\n visible: false,\n cancelled: false,\n\n // Current Track Upload\n writtenProgress: 0,\n encryptedProgress: 0,\n totalProgress: 1,\n\n // Tracks done\n trackTotal: 1,\n trackConverting: 0,\n trackCurrent: 0,\n titleCurrent: '',\n titleConverting: '',\n};\n\nexport const slice = createSlice({\n name: 'uploadDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setWriteProgress: (state, action: PayloadAction<{ written: number; encrypted: number; total: number }>) => {\n state.encryptedProgress = action.payload.encrypted;\n state.writtenProgress = action.payload.written;\n state.totalProgress = action.payload.total;\n },\n setCancelUpload: (state, action: PayloadAction) => {\n state.cancelled = action.payload;\n },\n setTrackProgress: (\n state,\n action: PayloadAction<{ total: number; current: number; converting: number; titleCurrent: string; titleConverting: string }>\n ) => {\n state.trackTotal = action.payload.total;\n state.trackCurrent = action.payload.current;\n state.trackConverting = action.payload.converting;\n state.titleCurrent = action.payload.titleCurrent;\n state.titleConverting = action.payload.titleConverting;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RenameDialogState {\n visible: boolean;\n title: string;\n index: number;\n}\n\nconst initialState: RenameDialogState = {\n visible: false,\n title: '',\n index: -1,\n};\n\nexport const slice = createSlice({\n name: 'renameDialog',\n initialState,\n reducers: {\n setVisible: (state: RenameDialogState, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setCurrentName: (state: RenameDialogState, action: PayloadAction) => {\n state.title = action.payload;\n },\n setIndex: (state: RenameDialogState, action: PayloadAction) => {\n state.index = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface ErrorDialogState {\n visible: boolean;\n error: string;\n}\n\nconst initialState: ErrorDialogState = {\n visible: false,\n error: ``,\n};\n\nconst slice = createSlice({\n name: 'errorDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setErrorMessage: (state, action: PayloadAction) => {\n state.error = `${action.payload}`;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport const initialState = {\n visible: false,\n dismissed: false, // This will prevent showing the dialog during the same session\n};\n\nconst slice = createSlice({\n name: 'panicDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n dismiss: (state, action: PayloadAction) => {\n state.visible = false;\n state.dismissed = true;\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\nexport type TitleSourceType = 'file' | 'media';\nexport type TitleFormatType = 'title' | 'album-title' | 'artist-title' | 'artist-album-title';\nexport type UploadFormat = 'SP' | 'LP2' | 'LP4';\n\nexport interface ConvertDialogFeature {\n visible: boolean;\n format: UploadFormat;\n titleSource: TitleSourceType;\n titleFormat: TitleFormatType;\n}\n\nconst initialState: ConvertDialogFeature = {\n visible: false,\n format: loadPreference('uploadFormat', 'LP2') as UploadFormat,\n titleSource: loadPreference('trackTitleSource', 'file') as TitleSourceType,\n titleFormat: loadPreference('trackTitleFormat', 'title') as TitleFormatType,\n};\n\nconst slice = createSlice({\n name: 'convertDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setFormat: (state, action: PayloadAction) => {\n state.format = action.payload;\n savePreference('uploadFormat', state.format);\n },\n setTitleSource: (state, action: PayloadAction) => {\n state.titleSource = action.payload;\n savePreference('trackTitleSource', state.titleSource);\n },\n setTitleFormat: (state, action: PayloadAction) => {\n state.titleFormat = action.payload;\n savePreference('trackTitleFormat', state.titleFormat);\n },\n },\n});\n\nexport const { actions, reducer } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface DumpDialogState {\n visible: boolean;\n inputDeviceId: string;\n}\n\nconst initialState: DumpDialogState = {\n visible: false,\n inputDeviceId: '',\n};\n\nexport const slice = createSlice({\n name: 'dumpDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setInputDeviceId: (state, action: PayloadAction) => {\n state.inputDeviceId = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface RecordingDialogState {\n visible: boolean;\n\n trackTotal: number;\n trackDone: number;\n trackCurrent: number;\n\n titleCurrent: string;\n}\n\nconst initialState: RecordingDialogState = {\n visible: false,\n\n trackTotal: 1,\n trackDone: 0,\n trackCurrent: 0,\n\n titleCurrent: '',\n\n // visible: true,\n // trackTotal: 4,\n // trackDone: 1,\n // trackCurrent: 25,\n\n // titleCurrent: 'Seconda traccia',\n};\n\nexport const slice = createSlice({\n name: 'recordDialog',\n initialState,\n reducers: {\n setVisible: (state, action: PayloadAction) => {\n state.visible = action.payload;\n },\n setProgress: (\n state,\n action: PayloadAction<{ trackTotal: number; trackDone: number; trackCurrent: number; titleCurrent: string }>\n ) => {\n state.trackTotal = action.payload.trackTotal;\n state.trackDone = action.payload.trackDone;\n state.trackCurrent = action.payload.trackCurrent;\n state.titleCurrent = action.payload.titleCurrent;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\nimport { savePreference, loadPreference } from '../utils';\n\ntype Views = 'WELCOME' | 'MAIN';\n\nexport interface AppState {\n mainView: Views;\n loading: boolean;\n pairingFailed: boolean;\n pairingMessage: string;\n browserSupported: boolean;\n darkMode: boolean;\n aboutDialogVisible: boolean;\n}\n\nconst initialState: AppState = {\n mainView: 'WELCOME',\n loading: false,\n pairingFailed: false,\n pairingMessage: ``,\n browserSupported: true,\n darkMode: loadPreference('darkMode', false),\n aboutDialogVisible: false,\n};\n\nexport const slice = createSlice({\n name: 'app',\n initialState,\n reducers: {\n setState: (state, action: PayloadAction) => {\n state.mainView = action.payload;\n },\n setLoading: (state, action: PayloadAction) => {\n state.loading = action.payload;\n },\n setPairingFailed: (state, action: PayloadAction) => {\n state.pairingFailed = action.payload;\n },\n setPairingMessage: (state, action: PayloadAction) => {\n state.pairingMessage = action.payload;\n },\n setBrowserSupported: (state, action: PayloadAction) => {\n state.browserSupported = action.payload;\n },\n setDarkMode: (state, action: PayloadAction) => {\n state.darkMode = action.payload;\n savePreference('darkMode', state.darkMode);\n },\n showAboutDialog: (state, action: PayloadAction) => {\n state.aboutDialogVisible = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { Disc, DeviceStatus } from 'netmd-js';\nimport { createSlice, PayloadAction } from '@reduxjs/toolkit';\nimport { enableBatching } from 'redux-batched-actions';\n\nexport interface MainState {\n disc: Disc | null;\n deviceName: string;\n deviceStatus: DeviceStatus | null;\n}\n\nconst initialState: MainState = {\n disc: null,\n deviceName: '',\n deviceStatus: null,\n};\n\nexport const slice = createSlice({\n name: 'main',\n initialState,\n reducers: {\n setDisc: (state, action: PayloadAction) => {\n state.disc = action.payload;\n },\n setDeviceName: (state, action: PayloadAction) => {\n state.deviceName = action.payload;\n },\n setDeviceStatus: (state, action: PayloadAction) => {\n state.deviceStatus = action.payload;\n },\n },\n});\n\nexport const { reducer, actions } = slice;\nexport default enableBatching(reducer);\n","import { configureStore, getDefaultMiddleware, Middleware, combineReducers } from '@reduxjs/toolkit';\nimport uploadDialog from './upload-dialog-feature';\nimport renameDialog from './rename-dialog-feature';\nimport errorDialog from './error-dialog-feature';\nimport panicDialog, { actions as panicDialogActions } from './panic-dialog-feature';\nimport convertDialog from './convert-dialog-feature';\nimport dumpDialog from './dump-dialog-feature';\nimport recordDialog from './record-dialog-feature';\nimport appState, { actions as appActions } from './app-feature';\nimport main from './main-feature';\n\nconst errorCatcher: Middleware = store => next => async action => {\n try {\n await next(action);\n } catch (e) {\n console.error(e);\n next(panicDialogActions.setVisible(true));\n }\n};\n\nlet reducer = combineReducers({\n renameDialog,\n uploadDialog,\n errorDialog,\n panicDialog,\n convertDialog,\n dumpDialog,\n recordDialog,\n appState,\n main,\n});\n\nconst resetStateAction = appActions.setState.toString();\nconst resetStatePayoload = 'WELCOME';\nconst resetStateReducer: typeof reducer = function(...args) {\n const [state, action] = args;\n if (action.type === resetStateAction && action.payload === resetStatePayoload) {\n return initialState;\n }\n return reducer(...args);\n};\n\nexport const store = configureStore({\n reducer: resetStateReducer,\n middleware: [errorCatcher, ...getDefaultMiddleware()],\n});\n\nconst initialState = Object.freeze(store.getState());\n\nexport type RootState = ReturnType;\nexport type AppDispatch = typeof store.dispatch;\n","import { batchActions } from 'redux-batched-actions';\nimport { AppDispatch, RootState } from './store';\nimport { actions as uploadDialogActions } from './upload-dialog-feature';\nimport { actions as renameDialogActions } from './rename-dialog-feature';\nimport { actions as errorDialogAction } from './error-dialog-feature';\nimport { actions as recordDialogAction } from './record-dialog-feature';\nimport { actions as appStateActions } from './app-feature';\nimport { actions as mainActions } from './main-feature';\nimport serviceRegistry from '../services/registry';\nimport { Wireformat, getTracks } from 'netmd-js';\nimport { AnyAction } from '@reduxjs/toolkit';\nimport { getAvailableCharsForTrackTitle, framesToSec, sleepWithProgressCallback, sleep } from '../utils';\nimport * as mm from 'music-metadata-browser';\nimport { TitleSourceType, TitleFormatType, UploadFormat } from './convert-dialog-feature';\n\nexport function control(action: 'play' | 'stop' | 'next' | 'prev' | 'goto', params?: unknown) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n switch (action) {\n case 'play':\n await serviceRegistry.netmdService!.play();\n break;\n case 'stop':\n await serviceRegistry.netmdService!.stop();\n break;\n case 'next':\n await serviceRegistry.netmdService!.next();\n break;\n case 'prev':\n await serviceRegistry.netmdService!.prev();\n break;\n case 'goto':\n if (params && typeof params === 'number' && params >= 0) {\n await serviceRegistry.netmdService!.gotoTrack(params);\n }\n break;\n }\n // CAVEAT: change-track might take a up to a few seconds to complete.\n // We wait 500ms and let the monitor do further updates\n await sleep(500);\n try {\n let deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n dispatch(mainActions.setDeviceStatus(deviceStatus));\n } catch (e) {\n console.log('control: Cannot get device status');\n }\n };\n}\n\nexport function pair() {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(appStateActions.setPairingFailed(false));\n\n await serviceRegistry.audioExportService!.init();\n\n try {\n let connected = await serviceRegistry.netmdService!.connect();\n if (connected) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n } catch (err) {\n console.error(err);\n // In case of error, just log and try to pair\n }\n\n try {\n let paired = await serviceRegistry.netmdService!.pair();\n if (paired) {\n dispatch(appStateActions.setState('MAIN'));\n return;\n }\n dispatch(batchActions([appStateActions.setPairingMessage(`Connection Failed`), appStateActions.setPairingFailed(true)]));\n } catch (err) {\n console.error(err);\n let message = (err as Error).message;\n dispatch(batchActions([appStateActions.setPairingMessage(message), appStateActions.setPairingFailed(true)]));\n }\n };\n}\n\nexport function listContent() {\n return async function(dispatch: AppDispatch) {\n // Issue loading\n dispatch(appStateActions.setLoading(true));\n let disc = await serviceRegistry.netmdService!.listContent();\n let deviceName = await serviceRegistry.netmdService!.getDeviceName();\n let deviceStatus = null;\n try {\n deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n } catch (e) {\n console.log('listContent: Cannot get device status');\n }\n dispatch(\n batchActions([\n mainActions.setDisc(disc),\n mainActions.setDeviceName(deviceName),\n mainActions.setDeviceStatus(deviceStatus),\n appStateActions.setLoading(false),\n ])\n );\n };\n}\n\nexport function renameTrack({ index, newName }: { index: number; newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n dispatch(renameDialogActions.setVisible(false));\n try {\n await netmdService!.renameTrack(index, newName);\n } catch (err) {\n console.error(err);\n dispatch(batchActions([errorDialogAction.setVisible(true), errorDialogAction.setErrorMessage(`Rename failed.`)]));\n }\n listContent()(dispatch);\n };\n}\n\nexport function renameDisc({ newName }: { newName: string }) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.renameDisc(newName);\n dispatch(renameDialogActions.setVisible(false));\n listContent()(dispatch);\n };\n}\n\nexport function deleteTracks(indexes: number[]) {\n return async function(dispatch: AppDispatch) {\n const confirmation = window.confirm(\n `Proceed with Delete Track${indexes.length !== 1 ? 's' : ''}? This operation cannot be undone.`\n );\n if (!confirmation) {\n return;\n }\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n indexes = indexes.sort();\n indexes.reverse();\n for (let index of indexes) {\n await netmdService!.deleteTrack(index);\n }\n listContent()(dispatch);\n };\n}\n\nexport function wipeDisc() {\n return async function(dispatch: AppDispatch) {\n const confirmation = window.confirm(`Proceed with Wipe Disc? This operation cannot be undone.`);\n if (!confirmation) {\n return;\n }\n const { netmdService } = serviceRegistry;\n dispatch(appStateActions.setLoading(true));\n await netmdService!.wipeDisc();\n listContent()(dispatch);\n };\n}\n\nexport function moveTrack(srcIndex: number, destIndex: number) {\n return async function(dispatch: AppDispatch) {\n const { netmdService } = serviceRegistry;\n await netmdService!.moveTrack(srcIndex, destIndex);\n listContent()(dispatch);\n };\n}\n\nexport function recordTracks(indexes: number[], deviceId: string) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n dispatch(\n batchActions([\n recordDialogAction.setVisible(true),\n recordDialogAction.setProgress({ trackTotal: indexes.length, trackDone: 0, trackCurrent: 0, titleCurrent: '' }),\n ])\n );\n\n let disc = getState().main.disc;\n let tracks = getTracks(disc!).filter(t => indexes.indexOf(t.index) >= 0);\n\n const { netmdService, mediaRecorderService } = serviceRegistry;\n await serviceRegistry.netmdService!.stop();\n\n for (let [i, track] of tracks.entries()) {\n dispatch(\n recordDialogAction.setProgress({\n trackTotal: tracks.length,\n trackDone: i,\n trackCurrent: -1,\n titleCurrent: track.title ?? '',\n })\n );\n\n // Wait for the track to be ready to play from 0:00\n await netmdService!.gotoTrack(track.index);\n await netmdService!.play();\n console.log('Waiting for track to be ready to play');\n let position = await netmdService!.getPosition();\n let expected = [track.index, 0, 0, 1];\n while (position === null || !expected.every((_, i) => expected[i] === position![i])) {\n await sleep(250);\n position = await netmdService!.getPosition();\n }\n await netmdService!.pause();\n await netmdService?.gotoTrack(track.index);\n console.log('Track is ready to play');\n\n // Start recording and play track\n await mediaRecorderService?.initStream(deviceId);\n await mediaRecorderService?.startRecording();\n await netmdService!.play();\n\n // Wait until track is finished\n let durationInSec = framesToSec(track.duration);\n // await sleep(durationInSec * 1000);\n await sleepWithProgressCallback(durationInSec * 1000, (perc: number) => {\n dispatch(\n recordDialogAction.setProgress({\n trackTotal: tracks.length,\n trackDone: i,\n trackCurrent: perc,\n titleCurrent: track.title ?? '',\n })\n );\n });\n\n // Stop recording and download the wav\n await mediaRecorderService?.stopRecording();\n mediaRecorderService?.downloadRecorded(`${track.title}`);\n\n await mediaRecorderService?.closeStream();\n }\n\n await netmdService!.stop();\n dispatch(recordDialogAction.setVisible(false));\n };\n}\n\nexport const WireformatDict: { [k: string]: Wireformat } = {\n SP: Wireformat.pcm,\n LP2: Wireformat.lp2,\n LP105: Wireformat.l105kbps,\n LP4: Wireformat.lp4,\n};\n\nasync function getTrackNameFromMediaTags(file: File, titleFormat: TitleFormatType) {\n const fileData = await file.arrayBuffer();\n const blob = new Blob([new Uint8Array(fileData)]);\n let metadata = await mm.parseBlob(blob);\n const title = metadata.common.title ?? 'Unknown Title';\n const artist = metadata.common.artist ?? 'Unknown Artist';\n const album = metadata.common.album ?? 'Unknown Album';\n switch (titleFormat) {\n case 'title': {\n return title;\n }\n case 'artist-title': {\n return `${artist} - ${title}`;\n }\n case 'album-title': {\n return `${album} - ${title}`;\n }\n case 'artist-album-title': {\n return `${artist} - ${album} - ${title}`;\n }\n }\n}\n\nexport function convertAndUpload(files: File[], format: UploadFormat, titleSource: TitleSourceType, titleFormat: TitleFormatType) {\n return async function(dispatch: AppDispatch, getState: () => RootState) {\n const { audioExportService, netmdService } = serviceRegistry;\n const wireformat = WireformatDict[format];\n\n await netmdService?.stop();\n dispatch(batchActions([uploadDialogActions.setVisible(true), uploadDialogActions.setCancelUpload(false)]));\n\n const updateProgressCallback = ({ written, encrypted, total }: { written: number; encrypted: number; total: number }) => {\n dispatch(uploadDialogActions.setWriteProgress({ written, encrypted, total }));\n };\n\n const hasUploadBeenCancelled = () => {\n return getState().uploadDialog.cancelled;\n };\n\n let trackUpdate: {\n current: number;\n converting: number;\n total: number;\n titleCurrent: string;\n titleConverting: string;\n } = {\n current: 0,\n converting: 0,\n total: files.length,\n titleCurrent: '',\n titleConverting: '',\n };\n const updateTrack = () => {\n dispatch(uploadDialogActions.setTrackProgress(trackUpdate));\n };\n\n let conversionIterator = async function*(files: File[]) {\n let converted: Promise<{ file: File; data: ArrayBuffer }>[] = [];\n\n let i = 0;\n function convertNext() {\n if (i === files.length || hasUploadBeenCancelled()) {\n trackUpdate.converting = i;\n trackUpdate.titleConverting = ``;\n updateTrack();\n return;\n }\n\n let f = files[i];\n trackUpdate.converting = i;\n trackUpdate.titleConverting = f.name;\n updateTrack();\n i++;\n\n converted.push(\n new Promise(async (resolve, reject) => {\n let data: ArrayBuffer;\n try {\n await audioExportService!.prepare(f);\n data = await audioExportService!.export({ format });\n convertNext();\n resolve({ file: f, data: data });\n } catch (err) {\n error = err;\n errorMessage = `${f.name}: Unsupported or unrecognized format`;\n reject(err);\n }\n })\n );\n }\n convertNext();\n\n let j = 0;\n while (j < converted.length) {\n yield await converted[j];\n delete converted[j];\n j++;\n }\n };\n\n let disc = getState().main.disc;\n let maxTitleLength = disc ? getAvailableCharsForTrackTitle(getTracks(disc).map(track => track.title || ``)) : -1;\n maxTitleLength = Math.floor(maxTitleLength / files.length);\n\n let error: any;\n let errorMessage = ``;\n let i = 1;\n for await (let item of conversionIterator(files)) {\n if (hasUploadBeenCancelled()) {\n break;\n }\n\n const { file, data } = item;\n\n let title = file.name;\n if (titleSource === 'media') {\n try {\n title = (await getTrackNameFromMediaTags(file, titleFormat)) ?? file.name;\n } catch (err) {\n console.error(err);\n }\n }\n\n const extStartIndex = title.lastIndexOf('.');\n if (extStartIndex > 0) {\n title = title.substring(0, extStartIndex);\n }\n if (maxTitleLength > -1) {\n title = title.substring(0, maxTitleLength);\n }\n\n trackUpdate.current = i++;\n trackUpdate.titleCurrent = title;\n updateTrack();\n updateProgressCallback({ written: 0, encrypted: 0, total: 100 });\n try {\n await netmdService?.upload(title, data, wireformat, updateProgressCallback);\n } catch (err) {\n error = err;\n errorMessage = `${file.name}: Error uploading to device`;\n break;\n }\n }\n\n let actionToDispatch: AnyAction[] = [uploadDialogActions.setVisible(false)];\n\n if (error) {\n console.error(error);\n actionToDispatch = actionToDispatch.concat([\n errorDialogAction.setVisible(true),\n errorDialogAction.setErrorMessage(errorMessage),\n ]);\n }\n\n dispatch(batchActions(actionToDispatch));\n listContent()(dispatch);\n };\n}\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as appActions } from '../redux/app-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport Link from '@material-ui/core/Link';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const AboutDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let visible = useShallowEqualSelector(state => state.appState.aboutDialogVisible);\n\n const handleClose = () => {\n dispatch(appActions.showAboutDialog(false));\n };\n\n return (\n \n About Web MiniDisc\n \n Web MiniDisc has been made possible by\n
    \n
  • \n \n FFmpeg\n {' '}\n and{' '}\n \n ffmpegjs\n \n , to read your audio files (wav, mp3, ogg, mp4, etc...).\n
  • \n
  • \n \n Atracdenc\n \n , to support atrac3 encoding (lp2, lp4 audio formats).\n
  • \n
  • \n \n Emscripten\n \n , to run both FFmpeg and Atracdenc in the browser.\n
  • \n
  • \n \n netmd-js\n \n , to send commands to NetMD devices using Javascript.\n
  • \n
  • \n \n linux-minidisc\n \n , to make the netmd-js project possible.\n
  • \n
  • \n \n material-ui\n \n , to build the user interface.\n
  • \n
\n Attribution\n
    \n
  • \n MiniDisc logo from{' '}\n \n https://en.wikipedia.org/wiki/MiniDisc\n \n
  • \n
  • \n MiniDisc icon from{' '}\n \n http://fav.me/d7u3g3g\n \n
  • \n
\n
\n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { batchActions } from 'redux-batched-actions';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport MoreVertIcon from '@material-ui/icons/MoreVert';\n\nimport { wipeDisc, listContent } from '../redux/actions';\nimport { actions as appActions } from '../redux/app-feature';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { useShallowEqualSelector } from '../utils';\nimport Link from '@material-ui/core/Link';\nimport ListItemIcon from '@material-ui/core/ListItemIcon';\nimport ListItemText from '@material-ui/core/ListItemText';\nimport { makeStyles } from '@material-ui/core/styles';\n\nimport RefreshIcon from '@material-ui/icons/Refresh';\nimport EditIcon from '@material-ui/icons/Edit';\nimport GitHubIcon from '@material-ui/icons/GitHub';\nimport DeleteForeverIcon from '@material-ui/icons/DeleteForever';\nimport ExitToAppIcon from '@material-ui/icons/ExitToApp';\nimport InfoIcon from '@material-ui/icons/Info';\nimport ToggleOffIcon from '@material-ui/icons/ToggleOff';\nimport ToggleOnIcon from '@material-ui/icons/ToggleOn';\n\nconst useStyles = makeStyles(theme => ({\n listItemIcon: {\n minWidth: theme.spacing(5),\n },\n}));\n\nexport const TopMenu = function() {\n const classes = useStyles();\n const dispatch = useDispatch();\n\n let { mainView, darkMode } = useShallowEqualSelector(state => state.appState);\n let discTitle = useShallowEqualSelector(state => state.main.disc?.title ?? ``);\n\n const githubLinkRef = React.useRef(null);\n const [menuAnchorEl, setMenuAnchorEl] = React.useState(null);\n const menuOpen = Boolean(menuAnchorEl);\n\n const handleMenuOpen = useCallback(\n (event: React.MouseEvent) => {\n setMenuAnchorEl(event.currentTarget);\n },\n [setMenuAnchorEl]\n );\n\n const handleDarkMode = useCallback(() => {\n dispatch(appActions.setDarkMode(!darkMode));\n }, [dispatch, darkMode]);\n\n const handleMenuClose = useCallback(() => {\n setMenuAnchorEl(null);\n }, [setMenuAnchorEl]);\n\n const handleWipeDisc = useCallback(() => {\n dispatch(wipeDisc());\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleRefresh = useCallback(() => {\n dispatch(listContent());\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleRenameDisc = useCallback(() => {\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(discTitle),\n renameDialogActions.setIndex(-1),\n ])\n );\n handleMenuClose();\n }, [dispatch, handleMenuClose, discTitle]);\n\n const handleExit = useCallback(() => {\n dispatch(appActions.setState('WELCOME'));\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleShowAbout = useCallback(() => {\n dispatch(appActions.showAboutDialog(true));\n handleMenuClose();\n }, [dispatch, handleMenuClose]);\n\n const handleGithubLink = useCallback(\n (event: React.MouseEvent) => {\n event.stopPropagation();\n if (event.target !== githubLinkRef.current) {\n // Prevent opening the link twice\n githubLinkRef.current?.click();\n }\n handleMenuClose();\n },\n [handleMenuClose]\n );\n\n const menuItems = [];\n if (mainView === 'MAIN') {\n menuItems.push(\n \n \n \n \n Reload TOC\n \n );\n menuItems.push(\n \n \n \n \n Rename Disc\n \n );\n menuItems.push(\n \n \n \n \n Wipe Disc\n \n );\n menuItems.push(\n \n \n \n \n Exit\n \n );\n }\n menuItems.push(\n \n \n {/* */}\n {darkMode ? : }\n \n Dark Mode\n \n );\n menuItems.push(\n \n \n \n \n About\n \n );\n menuItems.push(\n \n \n \n \n \n \n Fork me on GitHub\n \n \n \n );\n\n return (\n \n \n \n \n \n {menuItems}\n \n \n );\n};\n","import React, { useState } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { pair } from '../redux/actions';\n\nimport { useShallowEqualSelector } from '../utils';\n\nimport { makeStyles } from '@material-ui/core/styles';\nimport Button from '@material-ui/core/Button';\nimport Typography from '@material-ui/core/Typography';\nimport FormControl from '@material-ui/core/FormControl';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport Box from '@material-ui/core/Box';\nimport Link from '@material-ui/core/Link';\n\nimport { AboutDialog } from './about-dialog';\nimport { TopMenu } from './topmenu';\nimport ChromeIconPath from '../images/chrome-icon.svg';\n\nconst useStyles = makeStyles(theme => ({\n main: {\n position: 'relative',\n flex: '1 1 auto',\n display: 'flex',\n justifyContent: 'center',\n flexDirection: 'column',\n alignItems: 'center',\n },\n button: {\n marginTop: theme.spacing(3),\n minWidth: 150,\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n chromeLogo: {\n marginTop: theme.spacing(1),\n width: 96,\n height: 96,\n },\n why: {\n alignSelf: 'flex-start',\n marginTop: theme.spacing(3),\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n}));\n\nexport const Welcome = (props: {}) => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n const { browserSupported, pairingFailed, pairingMessage } = useShallowEqualSelector(state => state.appState);\n if (pairingMessage.toLowerCase().match(/denied/)) {\n // show linux instructions\n }\n // Access denied.\n\n const [showWhyUnsupported, setWhyUnsupported] = useState(false);\n const handleLearnWhy = (event: React.SyntheticEvent) => {\n event.preventDefault();\n setWhyUnsupported(true);\n };\n\n return (\n \n \n \n Web MiniDisc\n \n \n \n \n Brings NetMD Devices to the Web\n \n \n {browserSupported ? (\n \n \n Press the button to connect to a NetMD device\n \n\n \n\n \n {pairingMessage}\n \n \n ) : (\n \n \n This Web browser is not supported. \n \n Learn Why\n \n \n\n \n \"Chrome\n \n\n \n Try using{' '}\n \n Chrome\n {' '}\n instead\n \n\n {showWhyUnsupported ? (\n <>\n \n Web MiniDisc requires a browser that supports both{' '}\n \n WebUSB\n {' '}\n and{' '}\n \n WebAssembly\n \n .\n \n
    \n
  • WebUSB is needed to control the NetMD device via the USB connection to your computer.
  • \n
  • WebAssembly is used to convert the music to a MiniDisc compatible format
  • \n
\n \n ) : null}\n
\n )}\n
\n \n
\n );\n};\n","import React from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { renameTrack, renameDisc } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport TextField from '@material-ui/core/TextField';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const RenameDialog = (props: {}) => {\n let dispatch = useDispatch();\n\n let renameDialogVisible = useShallowEqualSelector(state => state.renameDialog.visible);\n let renameDialogTitle = useShallowEqualSelector(state => state.renameDialog.title);\n let renameDialogIndex = useShallowEqualSelector(state => state.renameDialog.index);\n\n const what = renameDialogIndex < 0 ? `Disc` : `Track`;\n\n const handleCancelRename = () => {\n dispatch(renameDialogActions.setVisible(false));\n };\n\n const handleDoRename = () => {\n if (renameDialogIndex < 0) {\n dispatch(renameDisc({ newName: renameDialogTitle }));\n } else {\n dispatch(renameTrack({ index: renameDialogIndex, newName: renameDialogTitle }));\n }\n };\n\n return (\n \n Rename {what}\n \n {\n event.key === `Enter` && handleDoRename();\n }}\n onChange={event => {\n dispatch(renameDialogActions.setCurrentName(event.target.value.substring(0, 120))); // MAX title length\n }}\n />\n \n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as uploadDialogActions } from '../redux/upload-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Button } from '@material-ui/core';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n uploadLabel: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const UploadDialog = (props: {}) => {\n const classes = useStyles();\n const dispatch = useDispatch();\n\n let {\n visible,\n cancelled,\n writtenProgress,\n encryptedProgress,\n totalProgress,\n\n trackTotal,\n trackCurrent,\n trackConverting,\n titleCurrent,\n titleConverting,\n } = useShallowEqualSelector(state => state.uploadDialog);\n\n const handleCancelUpload = useCallback(() => {\n dispatch(uploadDialogActions.setCancelUpload(true));\n }, [dispatch]);\n\n let progressValue = Math.floor((writtenProgress / totalProgress) * 100);\n let bufferValue = Math.floor((encryptedProgress / totalProgress) * 100);\n let convertedValue = Math.floor((trackConverting / trackTotal) * 100);\n return (\n \n Recording...\n \n \n {convertedValue === 100 && trackConverting === trackTotal\n ? `Conversion completed`\n : `Converting ${trackConverting + 1} of ${trackTotal}: ${titleConverting}`}\n \n \n {convertedValue}%\n\n \n Uploading {trackCurrent} of {trackTotal}: {titleCurrent}\n \n \n {progressValue}%\n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { useShallowEqualSelector } from '../utils';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport LinearProgress from '@material-ui/core/LinearProgress';\nimport Box from '@material-ui/core/Box';\nimport { makeStyles } from '@material-ui/core/styles';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst useStyles = makeStyles(theme => ({\n progressPerc: {\n marginTop: theme.spacing(1),\n },\n progressBar: {\n marginTop: theme.spacing(3),\n },\n}));\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const RecordDialog = (props: {}) => {\n const classes = useStyles();\n\n let { visible, trackTotal, trackDone, trackCurrent, titleCurrent } = useShallowEqualSelector(state => state.recordDialog);\n\n let progressValue = Math.round(trackCurrent);\n return (\n \n Recording...\n \n \n {`Recording track ${trackDone + 1} of ${trackTotal}: ${titleCurrent}`}\n \n = 0 ? 'determinate' : 'indeterminate'}\n color=\"primary\"\n value={progressValue}\n />\n {progressValue >= 0 ? `${progressValue}%` : ``}\n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as errorDialogActions } from '../redux/error-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogContentText from '@material-ui/core/DialogContentText';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const ErrorDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, error } = useShallowEqualSelector(state => state.errorDialog);\n\n const handleClose = useCallback(() => {\n dispatch(errorDialogActions.setVisible(false));\n }, [dispatch]);\n\n return (\n \n Error\n \n {error}\n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\nimport { actions as panicDialogActions } from '../redux/panic-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Typography } from '@material-ui/core';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nexport const PanicDialog = (props: {}) => {\n const dispatch = useDispatch();\n\n let { visible, dismissed } = useShallowEqualSelector(state => state.panicDialog);\n\n const handleReloadApp = useCallback(() => {\n window.location.reload();\n }, []);\n\n const handleIgnore = useCallback(() => {\n dispatch(panicDialogActions.dismiss());\n }, [dispatch]);\n\n return (\n \n Oops… Something unexpected happened.\n \n \n Try to restart the app. If the error persists, try the followings:\n
    \n
  1. Use your browser in incognito mode.
  2. \n
  3. Use a blank MiniDisc.
  4. \n
  5. Try to use Web MiniDisc on another computer.
  6. \n
\n If this does not solve the error, your unit might not be supported yet or you have encountered a bug. The full error is\n reported in the JS console.\n
\n
\n \n \n \n \n \n );\n};\n","import React, { useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { convertAndUpload } from '../redux/actions';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport ToggleButton from '@material-ui/lab/ToggleButton';\nimport ToggleButtonGroup from '@material-ui/lab/ToggleButtonGroup';\nimport { TransitionProps } from '@material-ui/core/transitions';\nimport { Typography } from '@material-ui/core';\nimport Select from '@material-ui/core/Select';\nimport Input from '@material-ui/core/Input';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n },\n formControl: {\n minWidth: 60,\n },\n toggleButton: {\n minWidth: 40,\n },\n dialogContent: {\n display: 'flex',\n flexWrap: 'wrap',\n justifyContent: 'space-between',\n },\n rightBlock: {\n display: 'flex',\n flexDirection: 'column',\n },\n titleFormControl: {\n marginTop: theme.spacing(1),\n },\n}));\n\nexport const ConvertDialog = (props: { files: File[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n let { visible, format, titleSource, titleFormat } = useShallowEqualSelector(state => state.convertDialog);\n\n const handleClose = useCallback(() => {\n dispatch(convertDialogActions.setVisible(false));\n }, [dispatch]);\n\n const handleChangeFormat = useCallback(\n (ev, newFormat) => {\n if (newFormat === null) {\n return;\n }\n dispatch(convertDialogActions.setFormat(newFormat));\n },\n [dispatch]\n );\n\n const handleChangeTitleSource = useCallback(\n (ev, newTitleSource) => {\n if (newTitleSource === null) {\n return;\n }\n dispatch(convertDialogActions.setTitleSource(newTitleSource));\n },\n [dispatch]\n );\n\n const handleChangeTitleFormat = useCallback(\n (event: React.ChangeEvent<{ value: any }>) => {\n dispatch(convertDialogActions.setTitleFormat(event.target.value));\n },\n [dispatch]\n );\n\n const handleConvert = useCallback(() => {\n handleClose();\n dispatch(convertAndUpload(props.files, format, titleSource, titleFormat));\n }, [dispatch, props, format, titleSource, titleFormat, handleClose]);\n\n return (\n \n Upload Settings\n \n \n \n Recording Mode\n \n \n \n SP\n \n \n LP2\n \n \n LP4\n \n \n \n
\n \n \n Track title\n \n \n \n Filename\n \n \n Media tags\n \n \n \n {titleSource === 'media' ? (\n \n \n \n ) : null}\n
\n
\n \n \n \n \n \n );\n};\n","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M53.259 20.337c6.582-5.574 6.582-5.574 14.753-12.436C62.599 6.72 56.322 6 49.946 6c-6.485 0-12.82.747-18.303 1.966 6.675 5.894 7.084 6.191 14.006 12.252 3.48-.293 3.97-.293 7.61.12zM36.927 24.504c.992-1.544 2.25-2.448 5.124-3.474-5.486-4.744-7.34-6.324-14.003-12.173-11.485 3.264-19.33 9.02-20.049 15.647h28.928zM61.159 24.504c14.02 0 20.615 0 30.732-.004-.789-6.629-8.72-12.468-20.269-15.706-2.061 1.766-11.14 9.316-14.827 12.484 1.793.813 3.226 1.35 4.364 3.226zM40.996 30.602c-2.045-.884-3.476-1.935-4.042-3.102-1.056 0-26.431 0-28.782.039C9.53 33.6 16.924 38.847 27.455 41.964c4.236-3.528 8.255-6.948 13.541-11.362zM49.946 45c6.284 0 12.247-.64 17.6-1.79-4.721-4.135-7.729-6.721-13.454-11.689-3.681.692-6.213.59-9.6.068-4.888 4.125-10.974 9.218-13.473 11.324C36.707 44.248 43.137 45 49.946 45zM57.47 30.45c4.38 3.707 9.262 8.068 13.687 11.884 11.265-3.066 19.178-8.5 20.57-14.83H61.18c-.667.999-1.516 1.917-3.71 2.946z\"\n}));\n\nconst SvgMd0 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd0, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md0.a7574f83.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M36.927 24.504c.992-1.544 2.25-2.448 5.124-3.474-5.486-4.744-7.34-6.324-14.003-12.173-11.485 3.264-19.33 9.02-20.049 15.647h28.928zM57.47 30.45c4.38 3.707 9.262 8.068 13.687 11.884 11.265-3.066 19.178-8.5 20.57-14.83H61.18c-.667.999-1.516 1.917-3.71 2.946z\"\n}));\n\nconst SvgMd1 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd1, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md1.1ffb5f6c.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M53.259 20.337c6.582-5.574 6.582-5.574 14.753-12.436C62.599 6.72 56.322 6 49.946 6c-6.485 0-12.82.747-18.303 1.966 6.675 5.894 7.084 6.191 14.006 12.252 3.48-.293 3.97-.293 7.61.12zM49.946 45c6.284 0 12.247-.64 17.6-1.79-4.721-4.135-7.729-6.721-13.454-11.689-3.681.692-6.213.59-9.6.068-4.888 4.125-10.974 9.218-13.473 11.324C36.707 44.248 43.137 45 49.946 45z\"\n}));\n\nconst SvgMd2 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd2, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md2.33dd03b3.svg\";\nexport { ForwardRef as ReactComponent };","function _extends() { _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends.apply(this, arguments); }\n\nimport React from \"react\";\n\nvar _ref =\n/*#__PURE__*/\nReact.createElement(\"g\", {\n fill: \"#000\",\n fillRule: \"evenodd\"\n}, React.createElement(\"g\", {\n fillRule: \"nonzero\"\n}, React.createElement(\"path\", {\n d: \"M5.756 14.036l2.101 2.14c-2.173 2.135-3.623 4.401-4.303 6.721l-.101.367-2.906-.748c.776-3.013 2.552-5.872 5.209-8.48zM23.576 4.241l.902 2.861c-5.329 1.682-9.916 3.879-13.464 6.436l-.438.322-1.796-2.403c3.894-2.91 8.94-5.368 14.796-7.216zM47.825.5l.054 3c-6.79.122-13.336.962-19.288 2.445l-.846.216-.76-2.902C33.395 1.581 40.477.632 47.825.5zM92.67 14.036l-2.101 2.14c2.173 2.135 3.624 4.401 4.303 6.721l.101.367 2.906-.748c-.776-3.013-2.552-5.872-5.209-8.48zM74.85 4.241l-.902 2.861c5.329 1.682 9.916 3.879 13.464 6.436l.438.322 1.796-2.403c-3.893-2.91-8.94-5.368-14.796-7.216zM50.601.5l-.054 3c6.79.122 13.336.962 19.288 2.445l.846.216.76-2.902C65.031 1.581 57.95.632 50.601.5zM5.756 37.964l2.101-2.14c-2.173-2.135-3.623-4.401-4.303-6.721l-.101-.367-2.906.748c.776 3.013 2.552 5.872 5.209 8.48zM23.576 47.759l.902-2.861c-5.329-1.682-9.916-3.879-13.464-6.436l-.438-.322-1.796 2.403c3.894 2.91 8.94 5.368 14.796 7.216zM47.825 51.5l.054-3c-6.79-.122-13.336-.962-19.288-2.445l-.846-.216-.76 2.902c6.41 1.678 13.492 2.627 20.84 2.759zM92.67 37.964l-2.101-2.14c2.173-2.135 3.624-4.401 4.303-6.721l.101-.367 2.906.748c-.776 3.013-2.552 5.872-5.209 8.48zM74.85 47.759l-.902-2.861c5.329-1.682 9.916-3.879 13.464-6.436l.438-.322 1.796 2.403c-3.893 2.91-8.94 5.368-14.796 7.216zM50.601 51.5l-.054-3c6.79-.122 13.336-.962 19.288-2.445l.846-.216.76 2.902c-6.41 1.678-13.492 2.627-20.84 2.759z\"\n})), React.createElement(\"path\", {\n d: \"M61.159 24.504c14.02 0 20.615 0 30.732-.004-.789-6.629-8.72-12.468-20.269-15.706-2.061 1.766-11.14 9.316-14.827 12.484 1.793.813 3.226 1.35 4.364 3.226zM40.996 30.602c-2.045-.884-3.476-1.935-4.042-3.102-1.056 0-26.431 0-28.782.039C9.53 33.6 16.924 38.847 27.455 41.964c4.236-3.528 8.255-6.948 13.541-11.362z\"\n}));\n\nconst SvgMd3 = ({\n svgRef,\n title,\n ...props\n}) => React.createElement(\"svg\", _extends({\n width: 98,\n height: 52,\n viewBox: \"0 0 98 52\",\n ref: svgRef\n}, props), title ? React.createElement(\"title\", null, title) : null, _ref);\n\nconst ForwardRef = React.forwardRef((props, ref) => React.createElement(SvgMd3, _extends({\n svgRef: ref\n}, props)));\nexport default __webpack_public_path__ + \"static/media/md3.80f42826.svg\";\nexport { ForwardRef as ReactComponent };","import React, { useCallback, useRef, useEffect, useState } from 'react';\n\nimport PlayArrowIcon from '@material-ui/icons/PlayArrow';\nimport StopIcon from '@material-ui/icons/Stop';\nimport SkipNextIcon from '@material-ui/icons/SkipNext';\nimport SkipPreviousIcon from '@material-ui/icons/SkipPrevious';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Box from '@material-ui/core/Box';\n\nimport { makeStyles } from '@material-ui/core';\nimport { belowDesktop, getSortedTracks, useShallowEqualSelector } from '../utils';\nimport { control } from '../redux/actions';\nimport { useDispatch } from 'react-redux';\n\nimport { ReactComponent as MDIcon0 } from '../images/md0.svg';\nimport { ReactComponent as MDIcon1 } from '../images/md1.svg';\nimport { ReactComponent as MDIcon2 } from '../images/md2.svg';\nimport { ReactComponent as MDIcon3 } from '../images/md3.svg';\n\nconst frames = [MDIcon0, MDIcon1, MDIcon2, MDIcon3];\n\nconst useStyles = makeStyles(theme => ({\n '@keyframes scrollLeft': {\n from: {\n transform: `translateX(0%)`,\n },\n to: {},\n },\n container: {\n display: 'flex',\n flex: '1 1 auto',\n [belowDesktop(theme)]: {\n flexWrap: 'wrap',\n },\n },\n lcd: {\n flex: '1 1 auto',\n position: 'relative',\n marginLeft: theme.spacing(1.5),\n marginRight: theme.spacing(1.5),\n paddingLeft: theme.spacing(3),\n paddingRight: theme.spacing(3),\n borderRadius: theme.spacing(3),\n backgroundColor: theme.palette.background.default,\n minWidth: 150,\n height: 48,\n [belowDesktop(theme)]: {\n marginLeft: 0,\n marginRight: theme.spacing(2),\n },\n },\n lcdText: {\n overflow: 'hidden',\n position: 'relative',\n width: 'calc(100% - 40px)',\n left: 40,\n height: '100%',\n fontFamily: 'LCDDot',\n },\n lcdDisc: {\n position: 'absolute',\n top: 0,\n left: 20,\n },\n lcdDiscIcon: {\n width: 28,\n height: 48,\n '& g': {\n fill: theme.palette.action.active,\n },\n },\n scrollingStatusMessage: {\n position: 'absolute',\n width: '100%',\n whiteSpace: 'nowrap',\n animationName: '$scrollLeft',\n animationTimingFunction: 'linear',\n animationIterationCount: '1',\n top: 15,\n left: 1,\n },\n statusMessage: {\n position: 'absolute',\n width: '100%',\n whiteSpace: 'nowrap',\n top: 15,\n left: 1,\n },\n button: {\n // padding: 8,\n },\n}));\n\nexport const Controls = () => {\n const dispatch = useDispatch();\n // TODO: The shallow equality won't work for these 2 states\n const deviceStatus = useShallowEqualSelector(state => state.main.deviceStatus);\n const disc = useShallowEqualSelector(state => state.main.disc);\n\n const classes = useStyles();\n const handlePrev = useCallback(() => {\n dispatch(control('prev'));\n }, [dispatch]);\n const handlePlay = useCallback(() => {\n dispatch(control('play'));\n }, [dispatch]);\n const handleStop = useCallback(() => {\n dispatch(control('stop'));\n }, [dispatch]);\n const handleNext = useCallback(() => {\n dispatch(control('next'));\n }, [dispatch]);\n\n let message = ``;\n let trackIndex = deviceStatus?.track ?? null;\n let deviceState = deviceStatus?.state ?? null;\n let discPresent = deviceStatus?.discPresent ?? false;\n const tracks = getSortedTracks(disc);\n if (!discPresent) {\n message = ``;\n } else if (deviceState === 'readingTOC') {\n message = 'READING TOC';\n } else if (tracks.length === 0) {\n message = `BLANKDISC`;\n } else if (deviceStatus && deviceStatus.track !== null) {\n message = `${deviceStatus.track + 1} - ` + tracks[deviceStatus.track].title;\n }\n\n const [lcdScroll, setLcdScroll] = useState(0);\n const [lcdScrollDuration, setLcdScrollDuration] = useState(0);\n const [lcdIconFrame, setLcdIconFrame] = useState(0);\n\n // LCD Text scrolling\n const animationDelayInMS = 2000;\n const scrollTimerRef = useRef(null);\n const lcdRef = useRef(null);\n useEffect(() => {\n const updateLCDScroll = () => {\n const domEl = lcdRef.current;\n const textWidth = domEl?.scrollWidth ?? 0;\n const lcdWidth = domEl?.parentElement?.offsetWidth ?? 0;\n const scrollPerc = textWidth > lcdWidth ? (textWidth * 100) / lcdWidth : 0;\n const scrollDurationInSec = textWidth > lcdWidth ? textWidth / 20 : 0; // Compute duration to achieve constant speed\n setLcdScroll(scrollPerc);\n setLcdScrollDuration(scrollDurationInSec);\n if (scrollDurationInSec > 0) {\n scrollTimerRef.current = setTimeout(() => {\n setLcdScroll(0);\n }, scrollDurationInSec * 1000 + 500); // stop animation timer\n }\n };\n\n clearTimeout(scrollTimerRef.current);\n setLcdScroll(0);\n scrollTimerRef.current = setTimeout(() => {\n updateLCDScroll();\n }, animationDelayInMS); // start animation timer\n\n return () => {\n clearTimeout(scrollTimerRef.current); // clear all the timers on unmount\n };\n }, [trackIndex, deviceState, message]);\n\n // Disc animation\n const lcdIconAnimationTimer = useRef(null);\n useEffect(() => {\n clearInterval(lcdIconAnimationTimer.current);\n if (deviceState === 'playing' || deviceState === 'readingTOC') {\n lcdIconAnimationTimer.current = setInterval(() => {\n setLcdIconFrame(1 + (lcdIconFrame % (frames.length - 1)));\n }, 600);\n } else {\n setLcdIconFrame(0);\n }\n return () => {\n clearInterval(lcdIconAnimationTimer.current);\n };\n }, [deviceState, lcdIconFrame]);\n\n const DiscFrame = frames[lcdIconFrame];\n return (\n \n \n \n \n \n \n \n \n \n \n \n \n \n
\n
\n 0\n ? { animationDuration: `${lcdScrollDuration}s`, transform: `translate(-${lcdScroll}%)` }\n : {}\n }\n >\n {message}\n \n
\n
{discPresent && }
\n
\n
\n );\n};\n","import React, { useEffect, useState, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport { useShallowEqualSelector } from '../utils';\n\nimport { recordTracks } from '../redux/actions';\nimport { actions as dumpDialogActions } from '../redux/dump-dialog-feature';\n\nimport Dialog from '@material-ui/core/Dialog';\nimport DialogActions from '@material-ui/core/DialogActions';\nimport DialogContent from '@material-ui/core/DialogContent';\nimport DialogTitle from '@material-ui/core/DialogTitle';\nimport Slide from '@material-ui/core/Slide';\nimport Button from '@material-ui/core/Button';\nimport { makeStyles } from '@material-ui/core/styles';\nimport FormControl from '@material-ui/core/FormControl';\nimport Select from '@material-ui/core/Select';\nimport MenuItem from '@material-ui/core/MenuItem';\nimport Typography from '@material-ui/core/Typography';\nimport FormHelperText from '@material-ui/core/FormHelperText';\nimport { Controls } from './controls';\nimport Box from '@material-ui/core/Box';\nimport serviceRegistry from '../services/registry';\nimport { TransitionProps } from '@material-ui/core/transitions';\n\nconst Transition = React.forwardRef(function Transition(\n props: TransitionProps & { children?: React.ReactElement },\n ref: React.Ref\n) {\n return ;\n});\n\nconst useStyles = makeStyles(theme => ({\n container: {\n display: 'flex',\n flexDirection: 'row',\n alignItems: 'flex-end',\n justifyContent: 'space-between',\n marginRight: -theme.spacing(2),\n flexFlow: 'wrap',\n },\n formControl: {\n minWidth: 120,\n },\n selectEmpty: {\n marginTop: theme.spacing(2),\n },\n head: {\n textShadow: '0px 0px 12px rgba(150, 150, 150, 1)',\n fontSize: theme.typography.h2.fontSize,\n textAlign: 'center',\n marginBottom: theme.spacing(2),\n },\n}));\n\nexport const DumpDialog = ({ trackIndexes }: { trackIndexes: number[] }) => {\n const dispatch = useDispatch();\n const classes = useStyles();\n\n const [devices, setDevices] = useState<{ deviceId: string; label: string }[]>([]);\n const [inputDeviceId, setInputDeviceId] = useState('');\n\n let { visible } = useShallowEqualSelector(state => state.dumpDialog);\n\n const handleClose = useCallback(() => {\n setInputDeviceId('');\n serviceRegistry.mediaRecorderService?.stopTestInput();\n dispatch(dumpDialogActions.setVisible(false));\n }, [dispatch]);\n\n const handleChange = useCallback(\n (ev: React.ChangeEvent<{ value: unknown }>) => {\n const deviceId = ev.target.value as string;\n setInputDeviceId(deviceId);\n serviceRegistry.mediaRecorderService?.stopTestInput();\n serviceRegistry.mediaRecorderService?.playTestInput(deviceId);\n },\n [setInputDeviceId]\n );\n\n const handleStartTransfer = useCallback(() => {\n dispatch(recordTracks(trackIndexes, inputDeviceId));\n handleClose();\n }, [trackIndexes, inputDeviceId, dispatch, handleClose]);\n\n useEffect(() => {\n async function updateDeviceList() {\n await navigator.mediaDevices.getUserMedia({ audio: true });\n let devices = await navigator.mediaDevices.enumerateDevices();\n let inputDevices = devices\n .filter(device => device.kind === 'audioinput')\n .map(device => ({ deviceId: device.deviceId, label: device.label }));\n setDevices(inputDevices);\n }\n if (visible) {\n updateDeviceList();\n }\n }, [visible, setDevices]);\n\n return (\n \n Record Selected Tracks\n \n \n {`💻 ⬅ 💽`}\n \n \n 1. Connect your MD Player line-out to your PC audio line-in.\n \n \n 2. Use the controls at the bottom right to play some tracks.\n \n \n 3. Select the input source. You should hear the tracks playing on your PC.\n \n \n 4. Adjust the input gain and the line-out volume of your device.\n \n \n \n \n Input Source\n \n \n \n \n \n \n \n \n \n );\n};\n","import React, { useEffect, useCallback } from 'react';\nimport { useDispatch } from 'react-redux';\nimport clsx from 'clsx';\nimport { useDropzone } from 'react-dropzone';\nimport { listContent, deleteTracks, moveTrack } from '../redux/actions';\nimport { actions as renameDialogActions } from '../redux/rename-dialog-feature';\nimport { actions as convertDialogActions } from '../redux/convert-dialog-feature';\nimport { actions as dumpDialogActions } from '../redux/dump-dialog-feature';\n\nimport { formatTimeFromFrames, getTracks } from 'netmd-js';\n\nimport { belowDesktop, forAnyDesktop, getSortedTracks, useShallowEqualSelector } from '../utils';\n\nimport { lighten, makeStyles } from '@material-ui/core/styles';\nimport Typography from '@material-ui/core/Typography';\nimport Box from '@material-ui/core/Box';\nimport Fab from '@material-ui/core/Fab';\nimport AddIcon from '@material-ui/icons/Add';\nimport DeleteIcon from '@material-ui/icons/Delete';\nimport EditIcon from '@material-ui/icons/Edit';\nimport Backdrop from '@material-ui/core/Backdrop';\n\nimport Table from '@material-ui/core/Table';\nimport TableBody from '@material-ui/core/TableBody';\nimport TableCell from '@material-ui/core/TableCell';\nimport TableHead from '@material-ui/core/TableHead';\nimport TableRow from '@material-ui/core/TableRow';\n\nimport IconButton from '@material-ui/core/IconButton';\nimport Toolbar from '@material-ui/core/Toolbar';\nimport Tooltip from '@material-ui/core/Tooltip';\nimport { batchActions } from 'redux-batched-actions';\n\nimport { RenameDialog } from './rename-dialog';\nimport { UploadDialog } from './upload-dialog';\nimport { RecordDialog } from './record-dialog';\nimport { ErrorDialog } from './error-dialog';\nimport { PanicDialog } from './panic-dialog';\nimport { ConvertDialog } from './convert-dialog';\nimport { AboutDialog } from './about-dialog';\nimport { DumpDialog } from './dump-dialog';\nimport { TopMenu } from './topmenu';\nimport Checkbox from '@material-ui/core/Checkbox';\nimport * as BadgeImpl from '@material-ui/core/Badge/Badge';\nimport Button from '@material-ui/core/Button';\nimport Menu from '@material-ui/core/Menu';\nimport MenuItem from '@material-ui/core/MenuItem';\n\nconst useStyles = makeStyles(theme => ({\n add: {\n position: 'absolute',\n bottom: theme.spacing(3),\n right: theme.spacing(3),\n [belowDesktop(theme)]: {\n bottom: theme.spacing(2),\n },\n },\n main: {\n overflowY: 'auto',\n flex: '1 1 auto',\n marginBottom: theme.spacing(3),\n outline: 'none',\n marginLeft: theme.spacing(-1),\n marginRight: theme.spacing(-1),\n [forAnyDesktop(theme)]: {\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n },\n },\n toolbar: {\n marginTop: theme.spacing(3),\n marginLeft: theme.spacing(-2),\n marginRight: theme.spacing(-2),\n [theme.breakpoints.up(600 + theme.spacing(2) * 2)]: {\n marginLeft: theme.spacing(-3),\n marginRight: theme.spacing(-3),\n },\n },\n toolbarLabel: {\n flex: '1 1 100%',\n },\n toolbarHighlight:\n theme.palette.type === 'light'\n ? {\n color: theme.palette.secondary.main,\n backgroundColor: lighten(theme.palette.secondary.light, 0.85),\n }\n : {\n color: theme.palette.text.primary,\n backgroundColor: theme.palette.secondary.dark,\n },\n headBox: {\n display: 'flex',\n justifyContent: 'space-between',\n },\n spacing: {\n marginTop: theme.spacing(1),\n },\n formatBadge: {\n ...(BadgeImpl as any).styles(theme).badge,\n ...(BadgeImpl as any).styles(theme).colorPrimary,\n position: 'static',\n display: 'inline-flex',\n border: `2px solid ${theme.palette.background.paper}`,\n padding: '0 4px',\n verticalAlign: 'middle',\n width: theme.spacing(4.5),\n marginRight: theme.spacing(0.5),\n },\n titleCell: {\n overflow: 'hidden',\n maxWidth: '40ch',\n textOverflow: 'ellipsis',\n // whiteSpace: 'nowrap',\n },\n durationCell: {\n whiteSpace: 'nowrap',\n },\n durationCellTime: {\n verticalAlign: 'middle',\n },\n indexCell: {\n whiteSpace: 'nowrap',\n paddingRight: 0,\n width: `2ch`,\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n remainingTimeTooltip: {\n textDecoration: 'underline',\n textDecorationStyle: 'dotted',\n },\n}));\n\nexport const Main = (props: {}) => {\n let dispatch = useDispatch();\n let disc = useShallowEqualSelector(state => state.main.disc);\n let deviceName = useShallowEqualSelector(state => state.main.deviceName);\n\n const [selected, setSelected] = React.useState([]);\n const selectedCount = selected.length;\n\n const [moveMenuAnchorEl, setMoveMenuAnchorEl] = React.useState(null);\n const handleShowMoveMenu = useCallback((event: React.MouseEvent) => {\n setMoveMenuAnchorEl(event.currentTarget);\n }, []);\n const handleCloseMoveMenu = useCallback(() => {\n setMoveMenuAnchorEl(null);\n }, []);\n const handleMoveSelectedTrack = useCallback(\n (destIndex: number) => {\n dispatch(moveTrack(selected[0], destIndex));\n handleCloseMoveMenu();\n },\n [dispatch, selected, handleCloseMoveMenu]\n );\n\n const handleShowDumpDialog = useCallback(() => {\n dispatch(dumpDialogActions.setVisible(true));\n }, [dispatch]);\n\n useEffect(() => {\n dispatch(listContent());\n }, [dispatch]);\n\n useEffect(() => {\n setSelected([]); // Reset selection if disc changes\n }, [disc]);\n\n let [uploadedFiles, setUploadedFiles] = React.useState([]);\n const onDrop = useCallback(\n (acceptedFiles: File[], rejectedFiles: File[]) => {\n setUploadedFiles(acceptedFiles);\n dispatch(convertDialogActions.setVisible(true));\n },\n [dispatch]\n );\n const { getRootProps, getInputProps, isDragActive, open } = useDropzone({\n onDrop,\n accept: [`audio/*`, `video/mp4`],\n noClick: true,\n });\n\n const classes = useStyles();\n const tracks = getSortedTracks(disc);\n\n // Action Handlers\n const handleSelectClick = (event: React.MouseEvent, item: number) => {\n if (selected.includes(item)) {\n setSelected(selected.filter(i => i !== item));\n } else {\n setSelected([...selected, item]);\n }\n };\n\n const handleSelectAllClick = (event: React.ChangeEvent) => {\n if (selected.length < tracks.length) {\n setSelected(tracks.map(t => t.index));\n } else {\n setSelected([]);\n }\n };\n\n const handleRenameDoubleClick = (event: React.MouseEvent, item: number) => {\n let selectedIndex = item;\n let currentName = getTracks(disc!).find(track => track.index === selectedIndex)?.title ?? '';\n\n dispatch(\n batchActions([\n renameDialogActions.setVisible(true),\n renameDialogActions.setCurrentName(currentName),\n renameDialogActions.setIndex(selectedIndex),\n ])\n );\n };\n\n const handleRenameActionClick = (event: React.MouseEvent) => {\n handleRenameDoubleClick(event, selected[0]);\n };\n\n const handleDeleteSelected = (event: React.MouseEvent) => {\n dispatch(deleteTracks(selected));\n };\n\n return (\n \n \n \n {deviceName || `Loading...`}\n \n \n \n \n {disc !== null ? (\n \n {`${formatTimeFromFrames(disc.left, false)} left of ${formatTimeFromFrames(disc.total, false)} `}\n \n {`${formatTimeFromFrames(disc.left * 2, false)} left in LP2 Mode`}\n
\n {`${formatTimeFromFrames(disc.left * 4, false)} left in LP4 Mode`}\n
\n }\n arrow\n >\n SP Mode\n \n
\n ) : (\n `Loading...`\n )}\n \n 0,\n })}\n >\n {selectedCount > 0 ? (\n 0 && selectedCount < tracks.length}\n checked={selectedCount > 0}\n onChange={handleSelectAllClick}\n inputProps={{ 'aria-label': 'select all tracks' }}\n />\n ) : null}\n {selectedCount > 0 ? (\n \n {selectedCount} selected\n \n ) : (\n \n {disc?.title || `Untitled Disc`}\n \n )}\n {selectedCount === 1 ? (\n \n \n \n \n \n {Array(tracks.length)\n .fill(null)\n .map((_, i) => {\n return (\n handleMoveSelectedTrack(i)}>\n {i + 1}\n \n );\n })}\n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n\n {selectedCount > 0 ? (\n \n \n \n \n \n ) : null}\n \n \n \n \n \n \n #\n Title\n Duration\n \n \n \n {tracks.map(track => (\n handleRenameDoubleClick(event, track.index)}\n onClick={event => handleSelectClick(event, track.index)}\n >\n {track.index + 1}\n \n {track.title || `No Title`}\n \n \n {track.encoding}\n {track.duration}\n \n \n ))}\n \n
\n \n Drop your Music to Upload\n \n
\n \n \n \n\n \n \n \n \n \n \n \n \n \n );\n};\n","import React from 'react';\nimport { belowDesktop, forAnyDesktop, forWideDesktop, useShallowEqualSelector } from '../utils';\n\nimport CssBaseline from '@material-ui/core/CssBaseline';\nimport Backdrop from '@material-ui/core/Backdrop';\nimport CircularProgress from '@material-ui/core/CircularProgress';\nimport { makeStyles, createMuiTheme, ThemeProvider } from '@material-ui/core/styles';\n\nimport { Welcome } from './welcome';\nimport { Main } from './main';\nimport { Controls } from './controls';\nimport Paper from '@material-ui/core/Paper';\nimport Typography from '@material-ui/core/Typography';\nimport Link from '@material-ui/core/Link';\nimport Box from '@material-ui/core/Box';\nimport { useDispatch } from 'react-redux';\n\nconst useStyles = makeStyles(theme => ({\n layout: {\n width: 'auto',\n height: '100%',\n [forAnyDesktop(theme)]: {\n width: 600,\n marginLeft: 'auto',\n marginRight: 'auto',\n },\n [forWideDesktop(theme)]: {\n width: 700,\n },\n },\n\n paper: {\n position: 'relative',\n display: 'flex',\n flexDirection: 'column',\n padding: theme.spacing(2),\n height: 'calc(100% - 20px)',\n [forAnyDesktop(theme)]: {\n marginTop: theme.spacing(2),\n marginBottom: theme.spacing(1),\n padding: theme.spacing(3),\n height: 600,\n },\n [forWideDesktop(theme)]: {\n height: 700,\n },\n },\n bottomBar: {\n display: 'flex',\n alignItems: 'center',\n [belowDesktop(theme)]: {\n flexWrap: 'wrap',\n },\n marginLeft: -theme.spacing(2),\n },\n copyrightTypography: {\n marginRight: theme.spacing(1),\n textAlign: 'center',\n },\n backdrop: {\n zIndex: theme.zIndex.drawer + 1,\n color: '#fff',\n },\n minidiscLogo: {\n width: 48,\n },\n controlsContainer: {\n flex: '0 0 auto',\n width: '100%',\n paddingRight: theme.spacing(8),\n [belowDesktop(theme)]: {\n paddingLeft: 0,\n },\n },\n}));\n\nconst darkTheme = createMuiTheme({\n palette: {\n type: 'dark',\n primary: {\n light: '#6ec6ff',\n main: '#2196f3',\n dark: '#0069c0',\n contrastText: '#fff',\n },\n },\n});\n\nconst lightTheme = createMuiTheme({\n palette: {\n type: 'light',\n },\n});\n\nconst App = () => {\n const classes = useStyles();\n\n const dispatch = useDispatch();\n let { mainView, loading, darkMode } = useShallowEqualSelector(state => state.appState);\n\n return (\n \n \n \n\n
\n \n {mainView === 'WELCOME' ? : null}\n {mainView === 'MAIN' ?
: null}\n\n {mainView === 'MAIN' ? : null}\n \n \n {'© '}\n \n Stefano Brilli\n {' '}\n {new Date().getFullYear()}\n {'.'}\n \n
\n\n \n \n \n \n \n );\n};\n\nexport default App;\n","/* eslint no-restricted-globals: 0 */\nimport { getPublicPathFor } from '../utils';\nexport class AtracdencProcess {\n private messageCallback?: (ev: MessageEvent) => void;\n\n constructor(public worker: Worker) {\n worker.onmessage = this.handleMessage.bind(this);\n }\n\n async init() {\n await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'init' });\n });\n }\n\n async encode(data: ArrayBuffer, bitrate: string) {\n let eventData = await new Promise(resolve => {\n this.messageCallback = resolve;\n this.worker.postMessage({ action: 'encode', bitrate, data }, [data]);\n });\n return eventData.data.result as Uint8Array;\n }\n\n terminate() {\n this.worker.terminate();\n }\n\n handleMessage(ev: MessageEvent) {\n this.messageCallback!(ev);\n this.messageCallback = undefined;\n }\n}\n\nif (typeof WorkerGlobalScope !== 'undefined' && self instanceof WorkerGlobalScope) {\n // Worker\n let Module: any;\n onmessage = async (ev: MessageEvent) => {\n const { action, ...others } = ev.data;\n if (action === 'init') {\n self.importScripts(getPublicPathFor(`atracdenc.js`));\n (self as any).Module().then((m: any) => {\n Module = m;\n self.postMessage({ action: 'init' });\n Module.setLogger && Module.setLogger((msg: string, stream: string) => console.log(`${stream}: ${msg}`));\n });\n } else if (action === 'encode') {\n const { bitrate, data } = others;\n const inWavFile = `inWavFile.wav`;\n const outAt3File = `outAt3File.aea`;\n const dataArray = new Uint8Array(data);\n Module.FS.writeFile(`${inWavFile}`, dataArray);\n Module.callMain([`-e`, `atrac3`, `-i`, inWavFile, `-o`, outAt3File, `--bitrate`, bitrate]);\n\n // Read file and trim header (96 bytes)\n let fileStat = Module.FS.stat(outAt3File);\n let size = fileStat.size;\n let tmp = new Uint8Array(size - 96);\n let outAt3FileStream = Module.FS.open(outAt3File, 'r');\n Module.FS.read(outAt3FileStream, tmp, 0, tmp.length, 96);\n Module.FS.close(outAt3FileStream);\n\n let result = tmp.buffer;\n\n self.postMessage(\n {\n action: 'encode',\n result,\n },\n [result]\n );\n }\n };\n} else {\n // Main\n}\n","import { createWorker, setLogging } from '@ffmpeg/ffmpeg';\nimport { AtracdencProcess } from './atracdenc-worker';\nimport { getPublicPathFor } from '../utils';\nconst AtracdencWorker = require('worker-loader!./atracdenc-worker'); // eslint-disable-line import/no-webpack-loader-syntax\n\ninterface LogPayload {\n message: string;\n action: string;\n}\n\nexport interface AudioExportService {\n init(): Promise;\n export(params: { format: string }): Promise;\n info(): Promise<{ format: string | null; input: string | null }>;\n prepare(file: File): Promise;\n}\n\nexport class FFMpegAudioExportService implements AudioExportService {\n public ffmpegProcess: any;\n public atracdencProcess?: AtracdencProcess;\n public loglines: { action: string; message: string }[] = [];\n public inFileName: string = ``;\n public outFileNameNoExt: string = ``;\n\n async init() {\n setLogging(true);\n }\n\n async prepare(file: File) {\n this.loglines = [];\n this.ffmpegProcess = createWorker({\n logger: (payload: LogPayload) => {\n this.loglines.push(payload);\n console.log(payload.action, payload.message);\n },\n corePath: getPublicPathFor('ffmpeg-core.js'),\n workerPath: getPublicPathFor('worker.min.js'),\n });\n await this.ffmpegProcess.load();\n\n this.atracdencProcess = new AtracdencProcess(new AtracdencWorker());\n await this.atracdencProcess.init();\n\n let ext = file.name.split('.').slice(-1);\n if (ext.length === 0) {\n throw new Error(`Unrecognized file format: ${file.name}`);\n }\n\n this.inFileName = `inAudioFile.${ext[0]}`;\n this.outFileNameNoExt = `outAudioFile`;\n\n await this.ffmpegProcess.write(this.inFileName, file);\n }\n\n async info() {\n await this.ffmpegProcess.transcode(this.inFileName, `${this.outFileNameNoExt}.metadata`, `-f ffmetadata`);\n\n let audioFormatRegex = /Audio:\\s(.*?),/; // Actual content\n let inputFormatRegex = /Input #0,\\s(.*?),/; // Container\n let format: string | null = null;\n let input: string | null = null;\n\n for (let line of this.loglines) {\n let match = line.message.match(audioFormatRegex);\n if (match !== null) {\n format = match[1];\n continue;\n }\n match = line.message.match(inputFormatRegex);\n if (match !== null) {\n input = match[1];\n continue;\n }\n if (format !== null && input !== null) {\n break;\n }\n }\n\n return { format, input };\n }\n\n async export({ format }: { format: string }) {\n let result: ArrayBuffer;\n if (format === `SP`) {\n const outFileName = `${this.outFileNameNoExt}.raw`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f s16be -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n result = data.buffer;\n } else {\n const outFileName = `${this.outFileNameNoExt}.wav`;\n await this.ffmpegProcess.transcode(this.inFileName, outFileName, '-f wav -ar 44100');\n let { data } = await this.ffmpegProcess.read(outFileName);\n let bitrate: string = `0`;\n switch (format) {\n case `LP2`:\n bitrate = `128`;\n break;\n case `LP105`:\n bitrate = `102`;\n break;\n case `LP4`:\n bitrate = `64`;\n break;\n }\n result = await this.atracdencProcess!.encode(data.buffer, bitrate);\n }\n this.ffmpegProcess.worker.terminate();\n this.atracdencProcess!.terminate();\n return result;\n }\n}\n","/* eslint no-restricted-globals: 0 */\nimport React from 'react';\nimport ReactDOM from 'react-dom';\nimport { Provider } from 'react-redux';\nimport * as serviceWorker from './serviceWorker';\nimport { NetMDUSBService } from './services/netmd';\nimport { NetMDMockService } from './services/netmd-mock';\nimport serviceRegistry from './services/registry';\n\nimport { store } from './redux/store';\nimport { actions as appActions } from './redux/app-feature';\nimport { actions as mainActions } from './redux/main-feature';\n\nimport App from './components/app';\n\nimport './index.css';\nimport './fonts/fonts.css';\n\nimport { FFMpegAudioExportService } from './services/audio-export';\nimport { MediaRecorderService } from './services/mediarecorder';\n\nserviceRegistry.netmdService = new NetMDUSBService({ debug: true });\n// serviceRegistry.netmdService = new NetMDMockService(); // Uncomment to work without a device attached\nserviceRegistry.audioExportService = new FFMpegAudioExportService();\nserviceRegistry.mediaRecorderService = new MediaRecorderService();\n\n(function setupEventHandlers() {\n window.addEventListener('beforeunload', ev => {\n let isUploading = store.getState().uploadDialog.visible;\n if (!isUploading) {\n return;\n }\n ev.preventDefault();\n ev.returnValue = `Warning! Recording will be interrupted`;\n });\n\n if (navigator && navigator.usb) {\n navigator.usb.ondisconnect = function() {\n store.dispatch(appActions.setState('WELCOME'));\n };\n } else {\n store.dispatch(appActions.setBrowserSupported(false));\n }\n\n // eslint-disable-next-line\n let deferredPrompt: any;\n window.addEventListener('beforeinstallprompt', (e: any) => {\n e.preventDefault();\n deferredPrompt = e;\n });\n})();\n\n(function statusMonitorManager() {\n // Polls the device for its state while playing tracks\n let statusMonitorInterval: ReturnType | null = null;\n let exceptionOccurred: boolean = false;\n\n function shouldMonitorBeRunning(state: ReturnType): boolean {\n return (\n !exceptionOccurred &&\n // App ready\n state.appState.mainView === 'MAIN' &&\n state.appState.loading === false &&\n // Disc playing\n state.main.deviceStatus?.state === 'playing' &&\n // No operational dialogs running\n state.convertDialog.visible === false &&\n state.uploadDialog.visible === false &&\n state.recordDialog.visible === false &&\n state.panicDialog.visible === false &&\n state.errorDialog.visible === false &&\n state.dumpDialog.visible === false\n );\n }\n\n store.subscribe(function() {\n const state = store.getState();\n if (shouldMonitorBeRunning(state) === true && statusMonitorInterval === null) {\n // start monitor\n statusMonitorInterval = setInterval(async () => {\n try {\n const deviceStatus = await serviceRegistry.netmdService!.getDeviceStatus();\n store.dispatch(mainActions.setDeviceStatus(deviceStatus));\n } catch (e) {\n console.error(e);\n exceptionOccurred = true; // Stop monitor on exception\n }\n }, 5000);\n } else if (shouldMonitorBeRunning(state) === false && statusMonitorInterval !== null) {\n // stop monitor\n clearInterval(statusMonitorInterval);\n statusMonitorInterval = null;\n }\n });\n})();\n\nReactDOM.render(\n \n \n ,\n document.getElementById('root')\n);\n\n// serviceWorker.unregister();\nserviceWorker.register();\n","import { sanitizeTitle, getPublicPathFor } from '../utils';\nimport Recorder from 'recorderjs';\n\nexport class MediaRecorderService {\n public recorder: any;\n public stream?: MediaStream;\n public audioContext?: AudioContext;\n public analyserNode?: AnalyserNode;\n public gainNode?: GainNode;\n\n playTestInput(deviceId: string) {\n this.audioContext = new AudioContext();\n this.gainNode = this.audioContext.createGain();\n this.analyserNode = this.audioContext.createAnalyser();\n\n this.initStream(deviceId).then(() => {\n const source = this.audioContext!.createMediaStreamSource(this.stream!);\n source.connect(this.gainNode!);\n this.gainNode!.connect(this.analyserNode!);\n this.analyserNode!.connect(this.audioContext!.destination);\n });\n }\n\n stopTestInput() {\n if (!this.audioContext) {\n return;\n }\n this.audioContext?.close();\n delete this.audioContext;\n this.closeStream();\n }\n\n async initStream(deviceId: string) {\n const recordConstraints = {\n // Try to set the best recording params for ripping the audio tracks\n autoGainControl: false,\n channelCount: 2,\n deviceId: deviceId,\n echoCancellation: false,\n noiseSuppression: false,\n sampleRate: 44100,\n highpassFilter: false,\n };\n this.stream = await navigator.mediaDevices.getUserMedia({ audio: recordConstraints });\n\n // Dump recording settings\n const audioTracks = this.stream.getAudioTracks();\n if (audioTracks.length > 0) {\n console.log('Record Setings:', audioTracks[0].getSettings());\n }\n }\n\n async startRecording() {\n this.audioContext = new AudioContext();\n const input = this.audioContext.createMediaStreamSource(this.stream!);\n this.recorder = new Recorder(input, { workerPath: getPublicPathFor(`recorderWorker.js`) });\n this.recorder.record();\n }\n\n async stopRecording() {\n this.recorder.stop();\n }\n\n async closeStream() {\n this.stream?.getTracks().forEach(track => track.stop());\n }\n\n downloadRecorded(title: string) {\n this.recorder.exportWAV((buffer: Blob) => {\n let url = URL.createObjectURL(buffer);\n let a = document.createElement('a');\n document.body.appendChild(a);\n a.style.display = 'none';\n a.href = url;\n a.download = `${sanitizeTitle(title)}.wav`;\n a.click();\n window.URL.revokeObjectURL(url);\n document.body.removeChild(a);\n });\n }\n}\n"],"sourceRoot":""} \ No newline at end of file