tiny-essentials
Version:
Collection of small, essential scripts designed to be used across various projects. These simple utilities are crafted for speed, ease of use, and versatility.
1 lines • 26 kB
JavaScript
(()=>{"use strict";var t={7(t){var e,i="object"==typeof Reflect?Reflect:null,n=i&&"function"==typeof i.apply?i.apply:function(t,e,i){return Function.prototype.apply.call(t,e,i)};e=i&&"function"==typeof i.ownKeys?i.ownKeys:Object.getOwnPropertySymbols?function(t){return Object.getOwnPropertyNames(t).concat(Object.getOwnPropertySymbols(t))}:function(t){return Object.getOwnPropertyNames(t)};var r=Number.isNaN||function(t){return t!=t};function o(){o.init.call(this)}t.exports=o,t.exports.once=function(t,e){return new Promise(function(i,n){function r(i){t.removeListener(e,o),n(i)}function o(){"function"==typeof t.removeListener&&t.removeListener("error",r),i([].slice.call(arguments))}p(t,e,o,{once:!0}),"error"!==e&&function(t,e){"function"==typeof t.on&&p(t,"error",e,{once:!0})}(t,r)})},o.EventEmitter=o,o.prototype._events=void 0,o.prototype._eventsCount=0,o.prototype._maxListeners=void 0;var s=10;function a(t){if("function"!=typeof t)throw new TypeError('The "listener" argument must be of type Function. Received type '+typeof t)}function c(t){return void 0===t._maxListeners?o.defaultMaxListeners:t._maxListeners}function u(t,e,i,n){var r,o,s,u;if(a(i),void 0===(o=t._events)?(o=t._events=Object.create(null),t._eventsCount=0):(void 0!==o.newListener&&(t.emit("newListener",e,i.listener?i.listener:i),o=t._events),s=o[e]),void 0===s)s=o[e]=i,++t._eventsCount;else if("function"==typeof s?s=o[e]=n?[i,s]:[s,i]:n?s.unshift(i):s.push(i),(r=c(t))>0&&s.length>r&&!s.warned){s.warned=!0;var l=new Error("Possible EventEmitter memory leak detected. "+s.length+" "+String(e)+" listeners added. Use emitter.setMaxListeners() to increase limit");l.name="MaxListenersExceededWarning",l.emitter=t,l.type=e,l.count=s.length,u=l,console&&console.warn&&console.warn(u)}return t}function l(){if(!this.fired)return this.target.removeListener(this.type,this.wrapFn),this.fired=!0,0===arguments.length?this.listener.call(this.target):this.listener.apply(this.target,arguments)}function d(t,e,i){var n={fired:!1,wrapFn:void 0,target:t,type:e,listener:i},r=l.bind(n);return r.listener=i,n.wrapFn=r,r}function h(t,e,i){var n=t._events;if(void 0===n)return[];var r=n[e];return void 0===r?[]:"function"==typeof r?i?[r.listener||r]:[r]:i?function(t){for(var e=new Array(t.length),i=0;i<e.length;++i)e[i]=t[i].listener||t[i];return e}(r):f(r,r.length)}function m(t){var e=this._events;if(void 0!==e){var i=e[t];if("function"==typeof i)return 1;if(void 0!==i)return i.length}return 0}function f(t,e){for(var i=new Array(e),n=0;n<e;++n)i[n]=t[n];return i}function p(t,e,i,n){if("function"==typeof t.on)n.once?t.once(e,i):t.on(e,i);else{if("function"!=typeof t.addEventListener)throw new TypeError('The "emitter" argument must be of type EventEmitter. Received type '+typeof t);t.addEventListener(e,function r(o){n.once&&t.removeEventListener(e,r),i(o)})}}Object.defineProperty(o,"defaultMaxListeners",{enumerable:!0,get:function(){return s},set:function(t){if("number"!=typeof t||t<0||r(t))throw new RangeError('The value of "defaultMaxListeners" is out of range. It must be a non-negative number. Received '+t+".");s=t}}),o.init=function(){void 0!==this._events&&this._events!==Object.getPrototypeOf(this)._events||(this._events=Object.create(null),this._eventsCount=0),this._maxListeners=this._maxListeners||void 0},o.prototype.setMaxListeners=function(t){if("number"!=typeof t||t<0||r(t))throw new RangeError('The value of "n" is out of range. It must be a non-negative number. Received '+t+".");return this._maxListeners=t,this},o.prototype.getMaxListeners=function(){return c(this)},o.prototype.emit=function(t){for(var e=[],i=1;i<arguments.length;i++)e.push(arguments[i]);var r="error"===t,o=this._events;if(void 0!==o)r=r&&void 0===o.error;else if(!r)return!1;if(r){var s;if(e.length>0&&(s=e[0]),s instanceof Error)throw s;var a=new Error("Unhandled error."+(s?" ("+s.message+")":""));throw a.context=s,a}var c=o[t];if(void 0===c)return!1;if("function"==typeof c)n(c,this,e);else{var u=c.length,l=f(c,u);for(i=0;i<u;++i)n(l[i],this,e)}return!0},o.prototype.addListener=function(t,e){return u(this,t,e,!1)},o.prototype.on=o.prototype.addListener,o.prototype.prependListener=function(t,e){return u(this,t,e,!0)},o.prototype.once=function(t,e){return a(e),this.on(t,d(this,t,e)),this},o.prototype.prependOnceListener=function(t,e){return a(e),this.prependListener(t,d(this,t,e)),this},o.prototype.removeListener=function(t,e){var i,n,r,o,s;if(a(e),void 0===(n=this._events))return this;if(void 0===(i=n[t]))return this;if(i===e||i.listener===e)0===--this._eventsCount?this._events=Object.create(null):(delete n[t],n.removeListener&&this.emit("removeListener",t,i.listener||e));else if("function"!=typeof i){for(r=-1,o=i.length-1;o>=0;o--)if(i[o]===e||i[o].listener===e){s=i[o].listener,r=o;break}if(r<0)return this;0===r?i.shift():function(t,e){for(;e+1<t.length;e++)t[e]=t[e+1];t.pop()}(i,r),1===i.length&&(n[t]=i[0]),void 0!==n.removeListener&&this.emit("removeListener",t,s||e)}return this},o.prototype.off=o.prototype.removeListener,o.prototype.removeAllListeners=function(t){var e,i,n;if(void 0===(i=this._events))return this;if(void 0===i.removeListener)return 0===arguments.length?(this._events=Object.create(null),this._eventsCount=0):void 0!==i[t]&&(0===--this._eventsCount?this._events=Object.create(null):delete i[t]),this;if(0===arguments.length){var r,o=Object.keys(i);for(n=0;n<o.length;++n)"removeListener"!==(r=o[n])&&this.removeAllListeners(r);return this.removeAllListeners("removeListener"),this._events=Object.create(null),this._eventsCount=0,this}if("function"==typeof(e=i[t]))this.removeListener(t,e);else if(void 0!==e)for(n=e.length-1;n>=0;n--)this.removeListener(t,e[n]);return this},o.prototype.listeners=function(t){return h(this,t,!0)},o.prototype.rawListeners=function(t){return h(this,t,!1)},o.listenerCount=function(t,e){return"function"==typeof t.listenerCount?t.listenerCount(e):m.call(t,e)},o.prototype.listenerCount=m,o.prototype.eventNames=function(){return this._eventsCount>0?e(this._events):[]}}};const e={};function i(n){const r=e[n];if(void 0!==r)return r.exports;const o=e[n]={exports:{}};return t[n](o,o.exports,i),o.exports}i.d=(t,e)=>{if(Array.isArray(e))for(var n=0;n<e.length;){var r=e[n++],o=e[n++];i.o(t,r)?0===o&&n++:0===o?Object.defineProperty(t,r,{enumerable:!0,value:e[n++]}):Object.defineProperty(t,r,{enumerable:!0,get:o})}else for(var r in e)i.o(e,r)&&!i.o(t,r)&&Object.defineProperty(t,r,{enumerable:!0,get:e[r]})},i.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e);let n={};i.d(n,{TinyRadioFm:()=>m});var r=i(7);const o=new Map;class s extends Error{constructor(t,e,i){super(t),this.name="MediaLoadingError",this.url=e,this.stage=i}}const a=async t=>{const e=(new TextEncoder).encode(t),i=await crypto.subtle.digest("SHA-1",e);return Array.from(new Uint8Array(i)).map(t=>t.toString(16).padStart(2,"0")).join("").substring(0,8)},c=(t,e="image/jpeg")=>{const i=t=>{const e=URL.createObjectURL(t),i=o.get(e);return o.set(e,"number"==typeof i?i+1:1),e};if(t instanceof Uint8Array)return i(new Blob([t],{type:e}));if("string"==typeof t&&t.startsWith("data:")){const n=t.split(",")[1],r=atob(n),o=new Uint8Array(r.length);for(let t=0;t<r.length;t++)o[t]=r.charCodeAt(t);return i(new Blob([o],{type:e}))}return"string"==typeof t?t:""},u=async t=>{if("string"!=typeof t||!t.startsWith("blob:"))return t;try{const e=await fetch(t),i=await e.blob();return await new Promise((t,e)=>{const n=new FileReader;n.onloadend=()=>t(String(n.result)),n.onerror=e,n.readAsDataURL(i)})}catch(e){return console.warn(`[TinyAudioUtils] Failed to convert Blob URL to Base64 on export: ${t}`,e),t}},l=t=>{t&&Array.isArray(t.picture)&&t.picture.forEach(t=>{if("string"==typeof t.data&&t.data.startsWith("blob:")){const e=o.get(t.data)??0;e>1?o.set(t.data,e-1):o.delete(t.data),e<=1&&URL.revokeObjectURL(t.data)}})},d=async(t,e)=>{if("string"!=typeof t)throw new TypeError(`Expected url to be a string, but received ${typeof t}.`);if("function"!=typeof e)throw new TypeError(`Expected parseFile to be a function, but received ${typeof e}.`);try{const i=await fetch(t);if(!i.ok)throw new Error(`Failed to fetch audio file: ${i.status} ${i.statusText}`);const n=await i.blob(),r=await e(n);if(!r||"object"!=typeof r.common)throw new TypeError('Invalid metadata: "common" property is missing or not an object.');const o=r.common;return(t=>{((t,e)=>{const i=t=>e&&void 0===t,n=t=>i(t)||"string"==typeof t||null===t,r=(t,e)=>!!i(t)||!(!Array.isArray(t)||!t.every(e));if(!n(t.title))throw new TypeError('Invalid metadata: "title" must be a string or null.');if(!n(t.album))throw new TypeError('Invalid metadata: "album" must be a string or null.');if(!n(t.albumartist))throw new TypeError('Invalid metadata: "albumartist" must be a string or null.');if(!n(t.artist))throw new TypeError('Invalid metadata: "artist" must be a string or null.');if(o=t.year,!i(o)&&"number"!=typeof o&&null!==o)throw new TypeError('Invalid metadata: "year" must be a number or null.');var o;if(!r(t.albumartists,t=>"string"==typeof t))throw new TypeError('Invalid metadata: "albumartists" must be an array of string.');if(!r(t.genre,t=>"string"==typeof t))throw new TypeError('Invalid metadata: "genre" must be an array of string.');if(!r(t.label,t=>"string"==typeof t))throw new TypeError('Invalid metadata: "label" must be an array of string.');if(!r(t.composer,t=>"string"==typeof t))throw new TypeError('Invalid metadata: "composer" must be an array of string.');if(!r(t.artists,t=>"string"==typeof t))throw new TypeError('Invalid metadata: "artists" must be an array of string.');if(!r(t.picture,t=>!(void 0!==t.description&&"string"!=typeof t.description||void 0!==t.name&&"string"!=typeof t.name||void 0!==t.type&&"string"!=typeof t.type||"string"!=typeof t.format||!(t.data instanceof Uint8Array||"string"==typeof t.data))))throw new TypeError('Invalid metadata: "picture" must be an array of pictures.');const s=(t,e)=>{if(!i(t)){if(null==t)throw new TypeError(`Invalid metadata: "${e}" is required.`);if("object"!=typeof t)throw new TypeError(`Invalid metadata: "${e}" must be an object or null.`);if("number"!=typeof t.no&&null!==t.no)throw new TypeError(`Invalid metadata: "${e}.no" must be a number or null.`);if("number"!=typeof t.of&&null!==t.of)throw new TypeError(`Invalid metadata: "${e}.of" must be a number or null.`)}};s(t.disk,"disk"),s(t.track,"track")})(t,!0)})(o),{title:o?.title??null,album:o?.album??null,albumartist:o?.albumartist??null,albumartists:o?.albumartists??[],genre:o?.genre??[],label:o?.label??[],composer:o?.composer??[],year:o?.year??null,artist:o?.artist??null,artists:o?.artists??[],disk:o?.disk?{no:o.disk.no,of:o.disk.of}:{no:null,of:null},track:o?.track?{no:o.track.no,of:o.track.of}:{no:null,of:null},picture:o?.picture?.map(t=>({...t,data:c(t.data,t.format)}))??[]}}catch(t){throw t}};class h extends r.EventEmitter{static async parseContent(t,e,i,n,r){return(async(t,e={},i={},n=t=>new Promise((t,e)=>e(new TypeError("parseFile library not found."))),r={},o="null")=>{if("string"!=typeof t&&!(t instanceof HTMLMediaElement))throw new TypeError("Source must be a string or an HTMLMediaElement.");if(r.onProgress&&"function"!=typeof r.onProgress)throw new TypeError("callbacks.onProgress must be a function.");if(r.onError&&"function"!=typeof r.onError)throw new TypeError("callbacks.onError must be a function.");let c,u="";const l=(e,i)=>{r.onProgress&&r.onProgress({event:i,status:"loading",stage:e,url:u||(t instanceof HTMLMediaElement?t.src:"unknown")})},h=(e,i)=>{r.onError&&r.onError({error:e,url:u||(t instanceof HTMLMediaElement?t.src:"unknown"),stage:i})};try{l("INITIALIZING"),"string"==typeof t?(u=t,c=new Audio(u)):(c=t,u=c.src);try{await new Promise((t,e)=>{const i=t=>l("DOWNLOADING",t),n=()=>{o(),t(void 0)},r=t=>{o(),e(new Error(`HTMLMediaElement failed to load: ${t.message||"Unknown error"}`))},o=()=>{c.removeEventListener("progress",i),c.removeEventListener("loadedmetadata",n),c.removeEventListener("error",r)};c.addEventListener("progress",i),c.addEventListener("loadedmetadata",n),c.addEventListener("error",r),c.readyState>=1&&(o(),t(void 0))}),l("METADATA_LOADED")}catch(t){throw new s(t instanceof Error?t.message:"UNKNOWN ERROR",u,"METADATA")}const m={id:i.id||await a(u),duration:Math.floor(1e3*c.duration),url:u,weight:i.weight??1};let f={};l("EXTRACTING_ID3");try{f=await d(u,n)}catch(t){h(t instanceof Error?t:new Error("Unknown Error"),"ID3"),console.warn(`[TinyAudioUtils] ID3 extraction failed for ${u}. Falling back to filename.`)}const p=t=>{try{return(t.split(/[?#]/)[0].split("/").pop()??"").replace(/\.[^/.]+$/,"")||"Unknown Track"}catch{return"Unknown Track"}},y={...m,...e,...f,...i,title:f.title||i.title||p(u),artist:f.artist||i.artist||("string"==typeof o?o:String(o()))};return r.onProgress&&r.onProgress({status:"success",stage:"COMPLETE",url:u}),y}catch(t){if(t instanceof s)throw t;{const e=new s(t instanceof Error?t.message:"UNKNOWN ERROR",u,"INITIALIZING");throw h(e,"INITIALIZING"),e}}})(t,e,i,n,r,h.#t)}static#t="Unknown Artist";static get unknownArtist(){return h.#t}static set unknownArtist(t){if("string"!=typeof t&&"function"!=typeof t)throw new TypeError("unknownArtist must have an string or function.");h.#t=t}get size(){return this.#e.length+this.#i.length}get musicSize(){return this.#e.length}get voiceSize(){return this.#i.length}get customPosSize(){return this.#n.length}get tasksSize(){return this.#r.length}get cycleCacheSize(){return this.#o.size}#e=[];get musicList(){return structuredClone(this.#e)}#i=[];get voiceList(){return structuredClone(this.#i)}#n=[];get customPositions(){return structuredClone(this.#n)}#r=[];get scheduledTasks(){return structuredClone(this.#r)}get allList(){return[...this.musicList,...this.voiceList]}#s=0;get seed(){return this.#s}set seed(t){if("number"!=typeof t)throw new TypeError("Seed must be a number.");this.#s=t,this.#o.clear(),this.emit("seedChanged",{seed:t})}#a=Date.now();get anchorDate(){return this.#a}#o=new Map;#c={mode:"playlist",voiceMode:"playlist",silenceDuration:0,queryLimit:1e5,voiceAfterMusic:!0,voiceMin:0,voiceMax:1,musicMaxConsecutive:0,voiceMaxConsecutive:0};get config(){return structuredClone(this.#c)}set config(t){this.#u(t),this.#c=structuredClone(t),this.#o.clear(),this.emit("configChanged",{config:this.config})}#u(t){if("object"!=typeof t||null===t)throw new TypeError("Configuration must be a valid object.");const e=["playlist","random"];if(void 0!==t.mode&&!e.includes(t.mode))throw new TypeError(`Invalid mode: "${t.mode}". Must be one of: ${e.join(", ")}.`);if(void 0!==t.voiceMode&&!e.includes(t.voiceMode))throw new TypeError(`Invalid voiceMode: "${t.voiceMode}". Must be one of: ${e.join(", ")}.`);if(void 0!==t.silenceDuration&&("number"!=typeof t.silenceDuration||t.silenceDuration<0))throw new TypeError("silenceDuration must be a non-negative number.");if(void 0!==t.queryLimit&&("number"!=typeof t.queryLimit||t.queryLimit<=0))throw new TypeError("queryLimit must be a positive number.");if(void 0!==t.voiceAfterMusic&&"boolean"!=typeof t.voiceAfterMusic)throw new TypeError("voiceAfterMusic must be a boolean.");if(void 0!==t.voiceMin&&("number"!=typeof t.voiceMin||t.voiceMin<0))throw new TypeError("voiceMin must be a non-negative number.");if(void 0!==t.voiceMax&&("number"!=typeof t.voiceMax||t.voiceMax<0))throw new TypeError("voiceMax must be a non-negative number.");if(void 0!==t.musicMaxConsecutive&&("number"!=typeof t.musicMaxConsecutive||t.musicMaxConsecutive<-1))throw new TypeError("musicMaxConsecutive must be a number >= -1.");if(void 0!==t.voiceMaxConsecutive&&("number"!=typeof t.voiceMaxConsecutive||t.voiceMaxConsecutive<-1))throw new TypeError("voiceMaxConsecutive must be a number >= -1.");const i=t.voiceMin??this.#c.voiceMin,n=t.voiceMax??this.#c.voiceMax;if(n<i)throw new RangeError(`Logical error: voiceMax (${n}) cannot be less than voiceMin (${i}).`)}constructor(t=null,e=0){if(super(),null!==t&&"object"!=typeof t)throw new TypeError("initialData must be an object or null.");if("number"!=typeof e)throw new TypeError("seed must be a number.");this.#s=e,t?this.#l(t):this.#a=Date.now()}add(t,e,i=!0){if(!["music","voice","custom"].includes(t))throw new TypeError('Type must be "music", "voice", or "custom".');if(!e||"string"!=typeof e.id||"number"!=typeof e.duration)throw new TypeError("Content must have a string ID and a valid numerical duration in milliseconds.");if("boolean"!=typeof i)throw new TypeError("smartQueue must be a boolean.");"music"===t?(this.#e.push(e),this.#o.clear()):"voice"===t?(this.#i.push(e),this.#o.clear()):"custom"===t&&this.#d(e,i),this.#h(Date.now()),this.emit("contentAdded",{type:t,data:structuredClone(e)})}scheduleTask(t,e,i,n,r=!0){if("number"!=typeof t||isNaN(t))throw new TypeError("timestamp must be a valid number.");if(!["add","remove","move"].includes(e))throw new TypeError('action must be "add", "remove", or "move".');if(!["music","voice"].includes(i))throw new TypeError('type must be "music" or "voice".');if("boolean"!=typeof r)throw new TypeError("smartQueue must be a boolean.");if("add"===e){if("object"!=typeof n||null===n||"string"!=typeof n.id||"number"!=typeof n.duration)throw new TypeError('Payload for "add" must be a MediaContent object (id: string, duration: number).')}else if("remove"===e){if("string"!=typeof n)throw new TypeError('Payload for "remove" must be a string (the content ID).')}else if("move"===e&&("object"!=typeof n||null===n||"string"!=typeof n.id||"number"!=typeof n.newIndex))throw new TypeError('Payload for "move" must be a ScheduledMovePayload (id: string, newIndex: number).');let o=t;if(r){const e=this.#m(t,t);e&&(o=e.absoluteEnd)}const s={timestamp:o,action:e,type:i,payload:n};this.#r.push(s),this.#h(Date.now()),this.emit("taskScheduled",structuredClone(s))}remove(t){if("string"!=typeof t)throw new TypeError("id must be a string.");this.#e.filter(e=>e.id===t).forEach(t=>l(t)),this.#i.filter(e=>e.id===t).forEach(t=>l(t)),this.#n.filter(e=>e.content?.id===t).forEach(t=>l(t.content));const e=e=>e.id!==t&&e.content?.id!==t;this.#e=this.#e.filter(e),this.#i=this.#i.filter(e),this.#n=this.#n.filter(e),this.#r=this.#r.filter(e=>"add"===e.action&&"object"==typeof e.payload&&null!==e.payload&&"id"in e.payload?e.payload.id!==t||(l(e.payload),!1):e.payload!==t),this.#o.clear(),this.emit("contentRemoved",{id:t})}setConfig(t){this.#u(t);const e={...this.#c,...t};this.#u(e),this.#c=e,this.#o.clear(),this.emit("configChanged",{config:this.config})}getCurrentEvent(){const t=Date.now();return this.#h(t),this.#m(t,t)}queryTimeline(t,e=10){if("number"!=typeof e||isNaN(e))throw new TypeError("Invalid query limit value. Ensure it is a number.");if(e>this.#c.queryLimit||e<=0)throw new RangeError(`Invalid query limit. Ensure it is > 0 and <= ${this.#c.queryLimit}.`);const i=new h(JSON.parse(this._exportState())),n=[];let r=t;for(let o=0;o<e;o++){i.#h(r);const e=i.#f(r,t);if(!e)break;n.push(e),r=e.absoluteEnd}return i.destroy(!1),this.emit("timelineQueried",{targetDate:t,limit:e,resultCount:n.length}),n}searchCustomPositions(){return this.#h(Date.now()),[...this.#n]}async _processListForExport(t){return Promise.all(t.map(async t=>{const e=structuredClone(t);return e.picture&&Array.isArray(e.picture)&&(e.picture=await Promise.all(e.picture.map(async t=>({...t,data:await u(t.data)})))),e}))}_exportState(){return JSON.stringify({music:this.#e,voice:this.#i,custom:this.#n,tasks:this.#r,seed:this.#s,anchorDate:this.#a,config:this.#c})}async exportState(){const t=await this._processListForExport(this.#e),e=await this._processListForExport(this.#i),i=await Promise.all(this.#n.map(async t=>{const e=await this._processListForExport([t.content]);return{...t,content:e[0]}})),n=await Promise.all(this.#r.map(async t=>{if("add"===t.action&&t.payload&&"object"==typeof t.payload&&"title"in t.payload){const e=await this._processListForExport([t.payload]);return{...t,payload:e[0]}}return t}));return JSON.stringify({music:t,voice:e,custom:i,tasks:n,seed:this.#s,anchorDate:this.#a,config:this.#c})}importState(t){let e;if("string"==typeof t)try{e=JSON.parse(t)}catch{throw new TypeError("Provided string is not valid JSON.")}else{if("object"!=typeof t||null===t)throw new TypeError("Import data must be a valid JSON string or an object.");e=t}this.#l(e),this.emit("stateImported",{data:structuredClone(e)})}_prng(t){return function(){let e=t+=1831565813;return e=Math.imul(e^e>>>15,1|e),e^=e+Math.imul(e^e>>>7,61|e),((e^e>>>14)>>>0)/4294967296}}#p(t,e,i,n=0){if(0===t.length)return[];if("random"!==i)return[...t];const r=t.map(t=>({...t,weight:t.weight??1})),o=this._prng(e),s=[];let a=null,c=0;for(;r.length>0;){let t=r;-1!==n&&null!==a&&c>n&&(t=r.filter(t=>t.id!==a),0===t.length&&(t=r));const e=t.reduce((t,e)=>t+e.weight,0);if(e<=0){s.push(...t);break}const i=o()*e;let u=0,l=null,d=-1;for(let e=0;e<t.length;e++)if(u+=t[e].weight,i<=u){l=t[e],d=r.findIndex(t=>l&&t.id===l.id);break}l&&-1!==d||(l=t[0],d=r.findIndex(t=>l&&t.id===l.id)),s.push(l),r.splice(d,1),l.id===a?c++:(a=l.id,c=1)}return s}#y(t){const e=this.#s+t,i=this._prng(10*e),n=this.#p(this.#e,e+1,this.#c.mode,this.#c.musicMaxConsecutive),r=this.#p(this.#i,e+2,this.#c.voiceMode,this.#c.voiceMaxConsecutive),o=[];let s=0,a=0;for(let t=0;t<n.length;t++){const e=n[t];if(o.push({...e,cycleStart:s,cycleEnd:s+e.duration}),s+=e.duration+this.#c.silenceDuration,this.#c.voiceAfterMusic&&r.length>0){const t=this.#c.voiceMax-this.#c.voiceMin+1,e=Math.floor(i()*t)+this.#c.voiceMin;for(let t=0;t<e;t++){const t=r[a%r.length];a++,o.push({...t,cycleStart:s,cycleEnd:s+t.duration}),s+=t.duration+this.#c.silenceDuration}}}return{items:o,duration:s}}#v(t){if(0===this.#e.length)return null;let e=this.#a,i=0;for(;;){if(i>this.#c.queryLimit)throw new Error("Safety limit hit during cycle location.");let n=this.#o.get(i);if(n||(n=this.#y(i),this.#o.set(i,n)),0===n.duration)return null;if(t>=e&&t<e+n.duration)return{block:n,startTimestamp:e,loopIndex:i};e+=n.duration,i++}}#f(t,e){const i=this.#n.filter(e=>e.intendedTimestamp+e.content.duration>t).sort((t,e)=>t.intendedTimestamp-e.intendedTimestamp)[0];let n=null;if(i){const t=Math.max(e,i.intendedTimestamp);n=this.#g(i.content,i.intendedTimestamp,t,!0)}const r=this.#w(t,e);return r||n?r?n?n.absoluteStart<=r.absoluteStart?n:(n.absoluteStart<r.absoluteEnd&&(r.absoluteEnd=n.absoluteStart,r.duration=r.absoluteEnd-r.absoluteStart,r.remainingTime=Math.max(0,r.absoluteEnd-e),r.progress=Math.min(1,r.elapsedTime/r.duration)),r):r:n:null}#w(t,e){let i=this.#v(t);if(!i)return null;const{block:n,startTimestamp:r}=i,o=t-r;let s,a=n.items.find(t=>t.cycleEnd>o);if(a)s=r+a.cycleStart;else{if(i=this.#v(r+n.duration),!i||0===i.block.items.length)return null;a=i.block.items[0],s=i.startTimestamp+a.cycleStart}const c=Math.max(e,s);return this.#g(a,s,c,!1)}#m(t,e){const i=this.#n.find(e=>t>=e.intendedTimestamp&&t<e.intendedTimestamp+e.content.duration);if(i)return this.#g(i.content,i.intendedTimestamp,e,!0);const n=this.#v(t);if(!n)return null;const{block:r,startTimestamp:o}=n,s=t-o,a=r.items.find(t=>s>=t.cycleStart&&s<t.cycleEnd);return a?this.#g(a,o+a.cycleStart,e,!1):null}#g(t,e,i,n){const r=i-e;return{id:t.id,title:t.title,artist:t.artist,duration:t.duration,url:t.url,absoluteStart:e,absoluteEnd:e+t.duration,elapsedTime:r,remainingTime:t.duration-r,progress:Math.min(1,r/t.duration),isCustom:n}}#d(t,e){let i=t.timestamp||Date.now();const n=t.duration;if(e){const t=this.#m(i,i);t&&(i=t.absoluteEnd)}const r=[...this.#n].sort((t,e)=>t.intendedTimestamp-e.intendedTimestamp);let o=i;if(r.some(t=>i<t.intendedTimestamp+t.content.duration&&i+n>t.intendedTimestamp)){const t=[];let e=Date.now();for(const i of r)i.intendedTimestamp>e&&t.push({start:e,end:i.intendedTimestamp}),e=Math.max(e,i.intendedTimestamp+i.content.duration+this.#c.silenceDuration);t.push({start:e,end:1/0});let s=1/0;for(const e of t)if(e.end-e.start>=n){let t=null;if(i>=e.start&&i+n<=e.end?t=i:i<e.start?t=e.start:i>e.end&&(t=e.end-n),null!==t){const e=Math.abs(i-t);e<s&&(s=e,o=t)}}}this.#n.push({content:t,intendedTimestamp:o,originalTimestamp:t.timestamp||Date.now()})}#h(t){const e=this.#r.filter(e=>e.timestamp<=t);this.#r=this.#r.filter(e=>e.timestamp>t);const i=this.#n.filter(e=>e.intendedTimestamp+e.content.duration<=t);this.#n=this.#n.filter(e=>e.intendedTimestamp+e.content.duration>t);let n=!1;i.forEach(t=>{l(t.content),this.#s+=t.content.id.length,n=!0,this.emit("customPositionExpired",{contentId:t.content.id})}),e.length>0&&e.sort((t,e)=>t.timestamp-e.timestamp).forEach(t=>{const e="music"===t.type?this.#e:this.#i;if("add"===t.action)e.push(t.payload);else if("remove"===t.action){const i=t.payload,n=e.findIndex(t=>t.id===i);if(-1!==n){const[t]=e.splice(n,1);l(t)}}else if("move"===t.action){const i=t.payload,n=e.findIndex(t=>t.id===i.id);if(-1!==n){const[t]=e.splice(n,1);e.splice(i.newIndex,0,t)}}this.#a=t.timestamp,this.#s+=1,n=!0,this.emit("taskExecuted",structuredClone(t))}),n&&this.#o.clear()}#l(t){this.#e.forEach(t=>l(t)),this.#i.forEach(t=>l(t)),this.#n.forEach(t=>l(t.content)),this.#r.forEach(t=>{"add"===t.action&&t.payload&&"object"==typeof t.payload&&"title"in t.payload&&l(t.payload)});const e=t=>t.map(t=>{const e={...t};return e.picture&&Array.isArray(e.picture)&&(e.picture=e.picture.map(t=>({...t,data:c(t.data,t.format)}))),e});this.#e=e(t.music),this.#i=e(t.voice),this.#s=t.seed||0,this.#a=t.anchorDate||Date.now(),this.#c={...this.#c,...t.config||{}},this.#n=t.custom.map(t=>({...t,content:e([t.content])[0]})),this.#r=t.tasks.map(t=>"add"===t.action&&t.payload&&"object"==typeof t.payload&&"title"in t.payload?{...t,payload:e([t.payload])[0]}:t)}destroy(t=!0){t&&(this.#e.forEach(t=>l(t)),this.#i.forEach(t=>l(t)),this.#n.forEach(t=>l(t.content)),this.#r.forEach(t=>{"add"===t.action&&t.payload&&"object"==typeof t.payload&&"title"in t.payload&&l(t.payload)})),this.#e=[],this.#i=[],this.#n=[],this.#r=[],this.#o.clear(),this.emit("destroyed",{timestamp:Date.now()}),this.removeAllListeners()}}const m=h;window.TinyRadioFm=n.TinyRadioFm})();