class EQMCData extends Object { constructor(obj) { super(); for (let key of Object.keys(obj)) { this[key] = obj[key]; } } } class EQMCAudioStream extends Object { constructor(obj) { super(); for (let key of Object.keys(obj)) { this[key] = obj[key]; } } } class EQMCError extends Error { constructor(props) { super(props); this.name = "EQMCError"; } } window.EQMC = { _base64ToArrayBuffer: (base64) => { var binary_string = window.atob(base64); var len = binary_string.length; var bytes = new Uint8Array(len); for (var i = 0; i < len; i++) { bytes[i] = binary_string.charCodeAt(i); } return bytes.buffer; }, isEQMCData: async (data) => { return data instanceof EQMCData && data["_eqmc"]; }, isEQMCAudioStream: async (data) => { return data instanceof EQMCAudioStream && data["data"]; }, create: async (file) => { try { return new EQMCData(JSON.parse(new TextDecoder("utf-8").decode(pako.inflate(new Uint8Array((await (await (await window.fetch(file)).blob()).arrayBuffer())))))); } catch (e) { console.error(e); throw new EQMCError("Failed to construct EQMCData object"); } }, decodeFile: async (data, file) => { if (!await EQMC.isEQMCData(data)) throw new EQMCError("Invalid input, expected EQMCData"); if (data.files.length - 1 >= file) { let s = data.files[file]; s["data"] = new Blob([pako.inflate(EQMC._base64ToArrayBuffer(s.data))]); return new EQMCAudioStream(s); } else { throw new EQMCError("File index is out of range"); } }, toAudio: async (data) => { if (!await EQMC.isEQMCAudioStream(data)) throw new EQMCError("Invalid input, expected EQMCAudioStream"); return new Audio(window.URL.createObjectURL(data.data)); }, quickAudio: async (url, id) => { let eqmc = await EQMC.create(url); let file = await EQMC.decodeFile(eqmc, id); return await EQMC.toAudio(file); } }