commit b8043a2c168dfaaf4fb2351493deb4c45608c7f3 Author: Dakedres Date: Tue Feb 4 14:25:34 2025 -0700 prototype diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..f3c4a92 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +music-metadata/ +node_modules/ \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..2b777de --- /dev/null +++ b/index.html @@ -0,0 +1,72 @@ + + + + + + + + + + + +
+ +
+ +
+ +

Bocce

+

Patricia Taxxon

+ +
+ +00:00 +00:00 + +
+ +
+ +
    + +
    +
    + +
    Back
    + +
    Add Files
    + +
    + +
    + + diff --git a/index.js b/index.js new file mode 100644 index 0000000..294bc14 --- /dev/null +++ b/index.js @@ -0,0 +1,528 @@ +let view = {} +let extensions = { + audio: [ "mp3", "wav", "ogg" ] +} +let entryTypes = { + DIRECTORY: 0, + AUDIO: 1 +} +let list = { + focused: false, + directory: null, + entries: [] +} +let player = { + audio: null, + queue: [], + history: [] +} + +const main = async () => { + view.list = document.getElementById('list') + + view.trackTitle = document.getElementById('track-title') + view.trackArtist = document.getElementById('track-artist') + + view.playbackProgress = document.getElementById('playback-progress') + view.timestamp = document.getElementById('timestamp') + view.trackLength = document.getElementById('track-length') + + view.prev = document.getElementById('prev') + view.playpause = document.getElementById('playpause') + view.next = document.getElementById('next') + + view.pauseIcon = document.getElementById('pause-icon') + view.playIcon = document.getElementById('play-icon') + + view.prev.addEventListener('click', previousTrack) + view.next.addEventListener('click', nextTrack) + view.playpause.addEventListener('click', togglePlay) + + window.addEventListener('keydown', onKeydown) + window.addEventListener('mousemove', onMouseMove) + + let files = await IDBStore.get('files') ?? { + entries: [], + root: true + } + + displayPaused() + openDirectory(files) + grabFocus() +} + +/* Interface */ + +const renderList = (entries, isRoot) => { + let focused = isListFocused() + + while (view.list.firstChild) { + view.list.removeChild(view.list.lastChild) + } + + list.entries = [] + let audioEntries = [] + let index = 0 + + const appendEntry = entry => { + view.list.appendChild(renderEntry(entry, index)) + list.entries.push(entry) + index++ + } + + for(let entry of entries) { + if(entry.type == entryTypes.DIRECTORY) { + appendEntry(entry) + } else { + audioEntries.push(entry) + } + } + + for(let entry of orderTracks(audioEntries)) { + appendEntry(entry) + } + + if(focused) { + grabFocus() + } +} + +const orderTracks = (entries) => { + return entries.sort((a, b) => a.tags.trackNumber - b.tags.trackNumber) +} + +const renderEntry = (entry, index) => { + let button = document.createElement('button') + let item = document.createElement('li') + + if(entry.type == entryTypes.DIRECTORY) { + populateDirectoryEntry(entry, button) + } else { + populateTrackEntry(entry, button) + } + + item.appendChild(button) + button.dataset.index = index + button.addEventListener('click', () => onClickListButton(button)) + + return item +} + +const populateDirectoryEntry = (entry, button) => { + button.classList.add('directory') + button.innerText = entry.name + '/' +} + +const populateTrackEntry = (entry, button) => { + if(!entry.tags.title) { + button.innerText = entry.name + return + } + + button.classList.add('titled-track') + + let trackNumber = document.createElement('code') + let title = document.createElement('b') + let artist = document.createElement('cite') + + trackNumber.innerText = formatTrackNumber(entry.tags.trackNumber) + title.innerText = entry.tags.title + artist.innerText = entry.tags.artist + + button.appendChild(trackNumber) + button.appendChild(title) + button.appendChild(artist) +} + +const formatTrackNumber = trackNumber => { + return trackNumber == Infinity ? '--' : trackNumber.toString().padStart(2, '0') +} + +const openDirectory = (entry) => { + renderList(entry.entries, entry.root) + list.directory = entry +} + + +const displayPlaying = () => { + view.playIcon.style.display = "none" + view.pauseIcon.style.display = "" +} + +const displayPaused = () => { + view.playIcon.style.display = "" + view.pauseIcon.style.display = "none" +} + +/* Population */ + +const onAddFiles = async () => { + const fileHandle = await window.showDirectoryPicker({ + mode: 'read', + startIn: 'music' + }) + + let entry = await loadDirectory(fileHandle, null, true) + await IDBStore.set('files', entry) + openDirectory(entry) +} + +const loadDirectory = async (dirHandle, parent, isRoot) => { + let root = { + entries: [], + type: entryTypes.DIRECTORY, + name: dirHandle.name, + root: isRoot, + parent + } + + for await (const [key, value] of dirHandle.entries()) { + if(value instanceof FileSystemDirectoryHandle) { + root.entries.push( + await loadDirectory(value, root) + ) + } else if(value instanceof FileSystemFileHandle) { + let entry = await loadEntry(value, dirHandle) + + if(entry) { + root.entries.push(entry) + } + } + } + + return root +} + +const loadEntry = async (fileHandle, dirHandle) => { + if(fileHandle.kind !== "file") { + return + } + + let extension = fileHandle.name.split('.').pop() + if(extensions.audio.includes(extension)) { + let entry = { + type: entryTypes.AUDIO, + name: fileHandle.name, + handle: fileHandle + } + + return await tagEntry(entry) + } +} + +const getTags = blob => new Promise((resolve, reject) => { + jsmediatags.read(blob, { + onSuccess(tags) { + resolve(tags) + }, + onError(err) { + reject(err) + } + }) +}) + +const tagEntry = async (entry) => { + let file = await entry.handle.getFile() + let tags = await getTags(file) + .catch(console.error) + .then(data => data?.tags) + + if(!tags) { + tags = /((?\d+)\s+)?((?.+)-\s*)?\s*(?.+)\s*\.\w+/ + .exec(entry.name) + .groups + + console.log(tags) + } + + entry.tags = { + album: tags.album, + title: tags.title, + artist: tags.artist ?? "Unknown Artist", + trackNumber: tags.track ? parseInt(tags.track) : Infinity + } + + return entry +} + +// const tagEntry = async (entry) => { +// let file = await entry.handle.getFile() +// let mp3tag = new MP3Tag(await toArrayBuffer(file)) + +// mp3tag.read() +// entry.tags = mp3tag.tags +// console.log(mp3tag) +// return entry +// } + +// const toArrayBuffer = fileOrBlob => new Promise((resolve, reject) => { +// let fileReader = new FileReader() +// fileReader.addEventListener('load', event => { +// resolve(fileReader.result) +// }) +// fileReader.addEventListener('error', event => { +// reject(event) +// }) +// fileReader.readAsArrayBuffer(fileOrBlob) +// }) + +/* Playback */ + +const createPlayback = async entry => { + let file = await entry.handle.getFile() + let url = URL.createObjectURL(file) + let audio = new Audio(url) + + return { + file, + audio, + entry + } +} + +const startPlayback = (playback) => { + if(player.audio) { + player.audio.pause() + } + let audio = playback.audio + player.audio = playback.audio + player.current = playback + + audio.addEventListener('playing', () => { + view.playbackProgress.max = audio.duration + view.trackLength.innerText = formatTime(audio.duration) + displayPlaying() + }) + audio.addEventListener('play', displayPlaying) + audio.addEventListener('pause', displayPaused) + audio.addEventListener('ended', () => { + onPlaybackEnded(playback) + }) + audio.addEventListener('timeupdate', () => { + onTimeUpdate(playback) + }) + + view.trackTitle.innerText = playback.entry.tags.title + view.trackArtist.innerText = playback.entry.tags.artist + view.playbackProgress.value = 0 + + audio.play() +} + +const onPlaybackEnded = (playback) => { + player.history.push(playback.entry) + let startedNext = nextTrack() + + if(!startedNext) { + player.audio.pause() + player.audio.seek(0) + } +} + +const onTimeUpdate = (playback) => { + view.playbackProgress.value = playback.audio.currentTime + view.timestamp.innerText = formatTime(playback.audio.currentTime) +} + +const formatTime = currentTime => { + let minutes = Math.floor(currentTime / 60).toString() + let seconds = Math.floor(currentTime % 60).toString() + + return minutes.padStart(2, '0') + ':' + seconds.padStart(2, '0') +} + +const playTrack = async (entry) => { + let playback = await createPlayback(entry) + startPlayback(playback) +} + +const nextTrack = async () => { + if(player.queue.length > 0) { + startPlayback(await player.queue.shift().playback) + return true + } else { + return false + } +} + +const queueTrack = (entry) => { + player.queue.push({ + entry, + playback: createPlayback(entry) + }) +} + +const togglePlay = () => { + if(!player.audio) + return + + if(player.audio.paused) { + player.audio.play() + } else { + player.audio.pause() + } +} + +const previousTrack = () => { + +} + +/* Controls */ + +const onMouseMove = event => { + if(isListFocused()) { + document.activeElement.blur() + } +} + +const onKeydown = event => { + let prevent = true + let entry = getSelectedEntry() + + switch(event.key) { + case 'ArrowDown': + navigateList(1) + break + + case 'ArrowUp': + navigateList(-1) + break + + case 'ArrowRight': + case 'Enter': + if(entry) { + openEntry(entry) + } + break + + case 'ArrowLeft': + goBack() + break + + case 'c': + case ' ': + togglePlay() + break + + case 'q': + case '7': + if(entry) { + queueTrack(entry) + } + break + + case 'p': + case '8': + if(entry) { + playEntry(entry) + } + break + + default: + prevent = false + } + + if(prevent) { + event.preventDefault() + } +} + +const getSelectedEntry = () => { + if(isListFocused()) { + return getEntry(document.activeElement) + } +} + +const isListFocused = () => + view.list.contains(document.activeElement) + +const navigateList = (distance) => { + let index = 0 + let children = Array.from(view.list.children) + + if(isListFocused()) { + index = parseInt(document.activeElement.dataset.index) + } + + index += distance + if(index >= children.length) { + index = 0 + } else if(index < 0) { + index = children.length - 1 + } + // children[Math.max(0, index - 4)] + let element = children[index].querySelector('button') + + children[Math.max(0, index - 7)].scrollIntoView() + element.focus({ preventScroll: true }) +} + +const goBack = () => { + if(list.directory.parent) { + openDirectory(list.directory.parent) + } +} + +const getEntry = (listButton) => { + return list.entries[listButton.dataset.index] +} + +const onClickListButton = (listButton) => { + openEntry(getEntry(listButton)) +} + +const openEntry = entry => { + switch(entry.type) { + case entryTypes.DIRECTORY: + openDirectory(entry) + break + + case entryTypes.AUDIO: + playTrack(entry) + break + } +} + +const playEntry = entry => { + switch(entry.type) { + case entryTypes.DIRECTORY: + playDirectory(entry) + break + + case entryTypes.AUDIO: + playTrack(entry) + break + } +} + +const playDirectory = dir => { + let tracks = getAllTracks(dir) + + orderTracks(tracks) + playTrack(tracks[0]) + for(let i = 1; i < tracks.length; i++) { + queueTrack(tracks[i]) + } +} + +const getAllTracks = dir => { + let tracks = [] + + for(entry of dir.entries) { + switch(entry.type) { + case entryTypes.DIRECTORY: + tracks = tracks.concat(getAllTracks(entry)) + break + + case entryTypes.AUDIO: + tracks.push(entry) + break + } + } + + return tracks +} + +const grabFocus = () => { + view.list.children[0]?.querySelector('button').focus() +} \ No newline at end of file diff --git a/music-metadata.js b/music-metadata.js new file mode 100644 index 0000000..b55f20b --- /dev/null +++ b/music-metadata.js @@ -0,0 +1,3 @@ +import { parseBlob } from 'music-metadata' + +export { parseBlob } \ No newline at end of file diff --git a/package.json b/package.json new file mode 100644 index 0000000..df51f46 --- /dev/null +++ b/package.json @@ -0,0 +1,18 @@ +{ + "name": "audioplayer", + "version": "1.0.0", + "main": "index.js", + "license": "MIT", + "dependencies": { + "@rollup/plugin-commonjs": "^28.0.1", + "@rollup/plugin-node-resolve": "^15.3.0", + "idb-keyval": "^6.2.1", + "jsmediatags": "^3.9.7", + "mp3tag": "^1.0.5", + "mp3tag.js": "^3.11.0", + "music-metadata": "^10.5.1", + "music-metadata-browser": "^2.5.11", + "rollup": "^4.24.0" + }, + "type": "module" +} diff --git a/pause.svg b/pause.svg new file mode 100644 index 0000000..a50cd24 --- /dev/null +++ b/pause.svg @@ -0,0 +1 @@ +<svg xmlns="http://www.w3.org/2000/svg" baseProfile="full" version="1.1" width="750px" height="945px" style="stroke-width: 17; stroke-linecap: round; stroke-linejoin: round; stroke: currentcolor; fill: rgb(10, 10, 10);"><path d="M30,15 L30,15 L30,120 L45,120 L45,15 L30,15 L30,120 M90,15 L90,15 L90,120 L105,120 L105,15 L90,15 "/></svg> diff --git a/rollup.config.js b/rollup.config.js new file mode 100644 index 0000000..d45bac7 --- /dev/null +++ b/rollup.config.js @@ -0,0 +1,23 @@ +import commonjs from '@rollup/plugin-commonjs'; +import { nodeResolve } from '@rollup/plugin-node-resolve'; + +export default { + input: './music-metadata.js', + output: { + dir: 'music-metadata', + format: 'es' + }, + plugins: [ + { + resolveId(name) { + if(name == 'strtok3') { + return "/home/dakedres/projects/audioplayer/node_modules/strtok3/lib/index.js" + } + } + }, + nodeResolve({ + browser: true + }), + commonjs() + ] +}; \ No newline at end of file diff --git a/style.css b/style.css new file mode 100644 index 0000000..547e5f9 --- /dev/null +++ b/style.css @@ -0,0 +1,166 @@ +:root { + --vii: #000; + --vi: #444; + --v: #0bb; + --iv: #aaa; + --iiv: #fff; + --a: #f33; +} + +button { + color: var(--iiv); + background: unset; + border: 0; +} +button:hover, button:focus { + color: var(--a) +} +button:active { + color: var(--v) +} + +body { + margin: 0; + background: var(--vii); +} + +main { + display: flex; + flex-direction: column; + + background: var(--vii); + color: var(--iiv); + + font-family: sans-serif; + font-size: 15px; + + /* width: 320px; */ + /* height: 480px; */ +} + +.content { + flex-grow: 1; + overflow-y: auto; +} + +.controls { + position: relative; +} +header, nav { + margin: 10px 0; +} + +header { + text-align: center; +} +header h3, header p { + margin-block: 0; + line-height: 1.3; +} + +nav button { + width: 45px; + height: 45px; +} +nav, nav button { + display: flex; + justify-content: center; + align-items: center; +} +nav svg { + stroke-width: 0; + stroke-linecap: square; + stroke-linejoin: square; + stroke: currentcolor; + fill: currentcolor; + width: 28px; + height: 28px; +} +#playpause { + width: 50px; + height: 50px; + border-radius: 50%; + border: 3px solid currentcolor; +} + +#timestamp, #track-length { + position: absolute; + padding: 5px; + font-size: 13px; + bottom: 0; +} +#timestamp { + color: var(--iiv); + left: 0; +} +#track-length { + color: var(--iv); + right: 0; +} + +progress { + width: 100%; + block-size: 3px; + appearance: none; +} +progress::-webkit-progress-bar { + background-color: var(--vi); +} +progress::-webkit-progress-value { + background-color: var(--iiv); +} + +ul { + margin: 0; + padding: 5px 0; + line-height: 1.4; +} + +ul li { + list-style-type: none; +} + +ul button { + text-align: left; + width: 100%; +} + +/* ul .titled-track { + border-bottom: 1px dotted var(--iv); +} */ + +ul code { + margin-right: 5px; + color: var(--v) +} + +ul cite { + float: right; +} + +ul .directory:after { + float: right; + content: ">"; +} + +footer { + padding: 5px; + font-size: 13px; + display: flex; + justify-content: center; +} +#left-action { + margin-right: auto; +} +#right-action { + margin-left: auto; +} + +::-webkit-scrollbar { + background: none; + width: 5px; +} + +::-webkit-scrollbar-thumb { + background-color: var(--iv); +} diff --git a/yarn-error.log b/yarn-error.log new file mode 100644 index 0000000..dc90085 --- /dev/null +++ b/yarn-error.log @@ -0,0 +1,41 @@ +Arguments: + /usr/bin/node /usr/bin/yarnpkg add idbkeyval + +PATH: + /home/dakedres/bin:/usr/local/bin:/home/dakedres/go/bin:/home/dakedres/bin:/home/dakedres/.cargo/bin:/home/dakedres/.local/bin:/home/dakedres/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin:/home/dakedres/.dotnet/tools + +Yarn version: + 1.22.19 + +Node version: + 18.13.0 + +Platform: + linux x64 + +Trace: + Error: https://registry.yarnpkg.com/idbkeyval: Not found + at params.callback [as _callback] (/usr/share/nodejs/yarn/lib/util/request-manager.js:594:20) + at self.callback (/usr/share/nodejs/request/request.js:185:22) + at Request.emit (node:events:513:28) + at Request.<anonymous> (/usr/share/nodejs/request/request.js:1161:10) + at Request.emit (node:events:513:28) + at IncomingMessage.<anonymous> (/usr/share/nodejs/request/request.js:1083:12) + at Object.onceWrapper (node:events:627:28) + at IncomingMessage.emit (node:events:525:35) + at endReadableNT (node:internal/streams/readable:1359:12) + at process.processTicksAndRejections (node:internal/process/task_queues:82:21) + +npm manifest: + { + "name": "audioplayer", + "version": "1.0.0", + "main": "index.js", + "license": "MIT" + } + +yarn manifest: + No manifest + +Lockfile: + No lockfile diff --git a/yarn.lock b/yarn.lock new file mode 100644 index 0000000..9878a64 --- /dev/null +++ b/yarn.lock @@ -0,0 +1,520 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"@jridgewell/sourcemap-codec@^1.5.0": + version "1.5.0" + resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz#3188bcb273a414b0d215fd22a58540b989b9409a" + integrity sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ== + +"@rollup/plugin-commonjs@^28.0.1": + version "28.0.1" + resolved "https://registry.yarnpkg.com/@rollup/plugin-commonjs/-/plugin-commonjs-28.0.1.tgz#e2138e31cc0637676dc3d5cae7739131f7cd565e" + integrity sha512-+tNWdlWKbpB3WgBN7ijjYkq9X5uhjmcvyjEght4NmH5fAU++zfQzAJ6wumLS+dNcvwEZhKx2Z+skY8m7v0wGSA== + dependencies: + "@rollup/pluginutils" "^5.0.1" + commondir "^1.0.1" + estree-walker "^2.0.2" + fdir "^6.2.0" + is-reference "1.2.1" + magic-string "^0.30.3" + picomatch "^4.0.2" + +"@rollup/plugin-node-resolve@^15.3.0": + version "15.3.0" + resolved "https://registry.yarnpkg.com/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz#efbb35515c9672e541c08d59caba2eff492a55d5" + integrity sha512-9eO5McEICxMzJpDW9OnMYSv4Sta3hmt7VtBFz5zR9273suNOydOyq/FrGeGy+KsTRFm8w0SLVhzig2ILFT63Ag== + dependencies: + "@rollup/pluginutils" "^5.0.1" + "@types/resolve" "1.20.2" + deepmerge "^4.2.2" + is-module "^1.0.0" + resolve "^1.22.1" + +"@rollup/pluginutils@^5.0.1": + version "5.1.2" + resolved "https://registry.yarnpkg.com/@rollup/pluginutils/-/pluginutils-5.1.2.tgz#d3bc9f0fea4fd4086aaac6aa102f3fa587ce8bd9" + integrity sha512-/FIdS3PyZ39bjZlwqFnWqCOVnW7o963LtKMwQOD0NhQqw22gSr2YY1afu3FxRip4ZCZNsD5jq6Aaz6QV3D/Njw== + dependencies: + "@types/estree" "^1.0.0" + estree-walker "^2.0.2" + picomatch "^2.3.1" + +"@rollup/rollup-android-arm-eabi@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.24.0.tgz#1661ff5ea9beb362795304cb916049aba7ac9c54" + integrity sha512-Q6HJd7Y6xdB48x8ZNVDOqsbh2uByBhgK8PiQgPhwkIw/HC/YX5Ghq2mQY5sRMZWHb3VsFkWooUVOZHKr7DmDIA== + +"@rollup/rollup-android-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.24.0.tgz#2ffaa91f1b55a0082b8a722525741aadcbd3971e" + integrity sha512-ijLnS1qFId8xhKjT81uBHuuJp2lU4x2yxa4ctFPtG+MqEE6+C5f/+X/bStmxapgmwLwiL3ih122xv8kVARNAZA== + +"@rollup/rollup-darwin-arm64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.24.0.tgz#627007221b24b8cc3063703eee0b9177edf49c1f" + integrity sha512-bIv+X9xeSs1XCk6DVvkO+S/z8/2AMt/2lMqdQbMrmVpgFvXlmde9mLcbQpztXm1tajC3raFDqegsH18HQPMYtA== + +"@rollup/rollup-darwin-x64@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.24.0.tgz#0605506142b9e796c370d59c5984ae95b9758724" + integrity sha512-X6/nOwoFN7RT2svEQWUsW/5C/fYMBe4fnLK9DQk4SX4mgVBiTA9h64kjUYPvGQ0F/9xwJ5U5UfTbl6BEjaQdBQ== + +"@rollup/rollup-linux-arm-gnueabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.24.0.tgz#62dfd196d4b10c0c2db833897164d2d319ee0cbb" + integrity sha512-0KXvIJQMOImLCVCz9uvvdPgfyWo93aHHp8ui3FrtOP57svqrF/roSSR5pjqL2hcMp0ljeGlU4q9o/rQaAQ3AYA== + +"@rollup/rollup-linux-arm-musleabihf@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.24.0.tgz#53ce72aeb982f1f34b58b380baafaf6a240fddb3" + integrity sha512-it2BW6kKFVh8xk/BnHfakEeoLPv8STIISekpoF+nBgWM4d55CZKc7T4Dx1pEbTnYm/xEKMgy1MNtYuoA8RFIWw== + +"@rollup/rollup-linux-arm64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.24.0.tgz#1632990f62a75c74f43e4b14ab3597d7ed416496" + integrity sha512-i0xTLXjqap2eRfulFVlSnM5dEbTVque/3Pi4g2y7cxrs7+a9De42z4XxKLYJ7+OhE3IgxvfQM7vQc43bwTgPwA== + +"@rollup/rollup-linux-arm64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.24.0.tgz#8c03a996efb41e257b414b2e0560b7a21f2d9065" + integrity sha512-9E6MKUJhDuDh604Qco5yP/3qn3y7SLXYuiC0Rpr89aMScS2UAmK1wHP2b7KAa1nSjWJc/f/Lc0Wl1L47qjiyQw== + +"@rollup/rollup-linux-powerpc64le-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.24.0.tgz#5b98729628d5bcc8f7f37b58b04d6845f85c7b5d" + integrity sha512-2XFFPJ2XMEiF5Zi2EBf4h73oR1V/lycirxZxHZNc93SqDN/IWhYYSYj8I9381ikUFXZrz2v7r2tOVk2NBwxrWw== + +"@rollup/rollup-linux-riscv64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.24.0.tgz#48e42e41f4cabf3573cfefcb448599c512e22983" + integrity sha512-M3Dg4hlwuntUCdzU7KjYqbbd+BLq3JMAOhCKdBE3TcMGMZbKkDdJ5ivNdehOssMCIokNHFOsv7DO4rlEOfyKpg== + +"@rollup/rollup-linux-s390x-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.24.0.tgz#e0b4f9a966872cb7d3e21b9e412a4b7efd7f0b58" + integrity sha512-mjBaoo4ocxJppTorZVKWFpy1bfFj9FeCMJqzlMQGjpNPY9JwQi7OuS1axzNIk0nMX6jSgy6ZURDZ2w0QW6D56g== + +"@rollup/rollup-linux-x64-gnu@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.24.0.tgz#78144741993100f47bd3da72fce215e077ae036b" + integrity sha512-ZXFk7M72R0YYFN5q13niV0B7G8/5dcQ9JDp8keJSfr3GoZeXEoMHP/HlvqROA3OMbMdfr19IjCeNAnPUG93b6A== + +"@rollup/rollup-linux-x64-musl@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.24.0.tgz#d9fe32971883cd1bd858336bd33a1c3ca6146127" + integrity sha512-w1i+L7kAXZNdYl+vFvzSZy8Y1arS7vMgIy8wusXJzRrPyof5LAb02KGr1PD2EkRcl73kHulIID0M501lN+vobQ== + +"@rollup/rollup-win32-arm64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.24.0.tgz#71fa3ea369316db703a909c790743972e98afae5" + integrity sha512-VXBrnPWgBpVDCVY6XF3LEW0pOU51KbaHhccHw6AS6vBWIC60eqsH19DAeeObl+g8nKAz04QFdl/Cefta0xQtUQ== + +"@rollup/rollup-win32-ia32-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.24.0.tgz#653f5989a60658e17d7576a3996deb3902e342e2" + integrity sha512-xrNcGDU0OxVcPTH/8n/ShH4UevZxKIO6HJFK0e15XItZP2UcaiLFd5kiX7hJnqCbSztUF8Qot+JWBC/QXRPYWQ== + +"@rollup/rollup-win32-x64-msvc@4.24.0": + version "4.24.0" + resolved "https://registry.yarnpkg.com/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.24.0.tgz#0574d7e87b44ee8511d08cc7f914bcb802b70818" + integrity sha512-fbMkAF7fufku0N2dE5TBXcNlg0pt0cJue4xBRE2Qc5Vqikxr4VCgKj/ht6SMdFcOacVA9rqF70APJ8RN/4vMJw== + +"@sec-ant/readable-stream@^0.4.1": + version "0.4.1" + resolved "https://registry.yarnpkg.com/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz#60de891bb126abfdc5410fdc6166aca065f10a0c" + integrity sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg== + +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.yarnpkg.com/@tokenizer/token/-/token-0.3.0.tgz#fe98a93fe789247e998c75e74e9c7c63217aa276" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + +"@types/estree@*", "@types/estree@1.0.6", "@types/estree@^1.0.0": + version "1.0.6" + resolved "https://registry.yarnpkg.com/@types/estree/-/estree-1.0.6.tgz#628effeeae2064a1b4e79f78e81d87b7e5fc7b50" + integrity sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw== + +"@types/resolve@1.20.2": + version "1.20.2" + resolved "https://registry.yarnpkg.com/@types/resolve/-/resolve-1.20.2.tgz#97d26e00cd4a0423b4af620abecf3e6f442b7975" + integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== + +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/abort-controller/-/abort-controller-3.0.0.tgz#eaf54d53b62bae4138e809ca225c8439a6efb392" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + +base64-js@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.5.1.tgz#1b1b440160a5bf7ad40b650f095963481903930a" + integrity sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA== + +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-6.0.3.tgz#2ace578459cc8fbe2a70aaa8f52ee63b6a74c6c6" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + integrity sha512-W9pAhw0ja1Edb5GVdIF1mjZw/ASI0AlShXM83UUGe2DVr5TdAPEA1OA8m/g8zWp9x6On7gqufY+FatDbC3MDQg== + +content-type@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.5.tgz#8b773162656d1d1086784c8f23a54ce6d73d7918" + integrity sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA== + +debug@^4.3.4, debug@^4.3.7: + version "4.3.7" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.7.tgz#87945b4151a011d76d95a198d7111c865c360a52" + integrity sha512-Er2nc/H7RrMXZBFCEim6TCmMk02Z8vLC2Rbi1KEBggpo0fS6l0S1nnapwmIi3yW/+GOJap1Krg4w0Hg80oCqgQ== + dependencies: + ms "^2.1.3" + +deepmerge@^4.2.2: + version "4.3.1" + resolved "https://registry.yarnpkg.com/deepmerge/-/deepmerge-4.3.1.tgz#44b5f2147cd3b00d4b56137685966f26fd25dd4a" + integrity sha512-3sUqbMEc77XqpdNO7FRyRog+eW3ph+GYCbj+rK+uYyRMuwsVy0rMiVtPn+QJlKFvWP/1PYpapqYn0Me2knFn+A== + +estree-walker@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" + integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== + +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + +events@^3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/events/-/events-3.3.0.tgz#31a95ad0a924e2d2c419a813aeb2c4e878ea7400" + integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== + +fdir@^6.2.0: + version "6.4.2" + resolved "https://registry.yarnpkg.com/fdir/-/fdir-6.4.2.tgz#ddaa7ce1831b161bc3657bb99cb36e1622702689" + integrity sha512-KnhMXsKSPZlAhp7+IjUkRZKPb4fUyccpDrdFXbi4QL1qkmFh9kVY09Yox+n4MaOb3lHZ1Tv829C3oaaXoMYPDQ== + +file-type@^16.5.4: + version "16.5.4" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-16.5.4.tgz#474fb4f704bee427681f98dd390058a172a6c2fd" + integrity sha512-/yFHK0aGjFEgDJjEKP0pWCplsPFPhwyfwevf/pVxiN0tmE4L9LmwWxWukdJSHdoCli4VgQLehjJtwQBnqmsKcw== + dependencies: + readable-web-to-node-stream "^3.0.0" + strtok3 "^6.2.4" + token-types "^4.1.1" + +file-type@^19.6.0: + version "19.6.0" + resolved "https://registry.yarnpkg.com/file-type/-/file-type-19.6.0.tgz#b43d8870453363891884cf5e79bb3e4464f2efd3" + integrity sha512-VZR5I7k5wkD0HgFnMsq5hOsSc710MJMu5Nc5QYsbe38NN5iPV/XTObYLc/cpttRTf6lX538+5uO1ZQRhYibiZQ== + dependencies: + get-stream "^9.0.1" + strtok3 "^9.0.1" + token-types "^6.0.0" + uint8array-extras "^1.3.0" + +fsevents@~2.3.2: + version "2.3.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.3.tgz#cac6407785d03675a2a5e1a5305c697b347d90d6" + integrity sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw== + +function-bind@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.2.tgz#2c02d864d97f3ea6c8830c464cbd11ab6eab7a1c" + integrity sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA== + +get-stream@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/get-stream/-/get-stream-9.0.1.tgz#95157d21df8eb90d1647102b63039b1df60ebd27" + integrity sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA== + dependencies: + "@sec-ant/readable-stream" "^0.4.1" + is-stream "^4.0.1" + +hasown@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/hasown/-/hasown-2.0.2.tgz#003eaf91be7adc372e84ec59dc37252cedb80003" + integrity sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ== + dependencies: + function-bind "^1.1.2" + +idb-keyval@^6.2.1: + version "6.2.1" + resolved "https://registry.yarnpkg.com/idb-keyval/-/idb-keyval-6.2.1.tgz#94516d625346d16f56f3b33855da11bfded2db33" + integrity sha512-8Sb3veuYCyrZL+VBt9LJfZjLUPWVvqn8tG28VqYNFCo43KHcKuq+b4EiXGeuaLAQWL2YmyDgMp2aSpH9JHsEQg== + +ieee754@^1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.2.1.tgz#8eb7a10a63fff25d15a57b001586d177d1b0d352" + integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== + +inherits@^2.0.3: + version "2.0.4" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.4.tgz#0fa2c64f932917c3433a0ded55363aae37416b7c" + integrity sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ== + +is-core-module@^2.13.0: + version "2.15.1" + resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.15.1.tgz#a7363a25bee942fefab0de13bf6aa372c82dcc37" + integrity sha512-z0vtXSwucUJtANQWldhbtbt7BnL0vxiFjIdDLAatwhDYty2bad6s+rijD6Ri4YuYJubLzIJLUidCh09e1djEVQ== + dependencies: + hasown "^2.0.2" + +is-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-module/-/is-module-1.0.0.tgz#3258fb69f78c14d5b815d664336b4cffb6441591" + integrity sha512-51ypPSPCoTEIN9dy5Oy+h4pShgJmPCygKfyRCISBI+JoWT/2oJvK8QPxmwv7b/p239jXrm9M1mlQbyKJ5A152g== + +is-reference@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/is-reference/-/is-reference-1.2.1.tgz#8b2dac0b371f4bc994fdeaba9eb542d03002d0b7" + integrity sha512-U82MsXXiFIrjCK4otLT+o2NA2Cd2g5MLoOVXUZjIOhLurrRxpEXzI8O0KZHr3IjLvlAH1kTPYSuqer5T9ZVBKQ== + dependencies: + "@types/estree" "*" + +is-stream@^4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-4.0.1.tgz#375cf891e16d2e4baec250b85926cffc14720d9b" + integrity sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A== + +jsmediatags@^3.9.7: + version "3.9.7" + resolved "https://registry.yarnpkg.com/jsmediatags/-/jsmediatags-3.9.7.tgz#808c6713b5ccb9712a4dc4b2149a0cb253c641a2" + integrity sha512-xCAO8C3li3t5hYkXqn8iv8zQQUB4T1QqRN2aSONHMls21ICdEvXi4xtb6W70/fAFYSDwMHd32hIqvo4YuXoNcQ== + dependencies: + xhr2 "^0.1.4" + +lodash@^4.17.4: + version "4.17.21" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c" + integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== + +magic-string@^0.30.3: + version "0.30.12" + resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.30.12.tgz#9eb11c9d072b9bcb4940a5b2c2e1a217e4ee1a60" + integrity sha512-Ea8I3sQMVXr8JhN4z+H/d8zwo+tYDgHE9+5G4Wnrwhs0gaK9fXTKx0Tw5Xwsd/bCPTTZNRAdpyzvoeORe9LYpw== + dependencies: + "@jridgewell/sourcemap-codec" "^1.5.0" + +media-typer@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-1.1.0.tgz#6ab74b8f2d3320f2064b2a87a38e7931ff3a5561" + integrity sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw== + +mp3tag.js@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/mp3tag.js/-/mp3tag.js-3.11.0.tgz#bca38f118d80e425234ab6e0d553c2b9b5c01d19" + integrity sha512-CSWc+OClkOYKRdDODCEA5nILWNHItsqcJNhHeE1nlBKjgbFdvARen31ECt7Zh/40Y7ukfCSiHyTcQRrQv5C5Hg== + +mp3tag@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/mp3tag/-/mp3tag-1.0.5.tgz#2cb5b79bc950be18f85fb732a4bdab176d314edb" + integrity sha512-GpFi5nXg9TzsJcnH2+1VM36isLdhO9TZkxY7UbF9S2CaPWKISju158O2VI3ObkMlwr3xXZFcADLp06nSxRgBKA== + dependencies: + lodash "^4.17.4" + +ms@^2.1.3: + version "2.1.3" + resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.3.tgz#574c8138ce1d2b5861f0b44579dbadd60c6615b2" + integrity sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA== + +music-metadata-browser@^2.5.11: + version "2.5.11" + resolved "https://registry.yarnpkg.com/music-metadata-browser/-/music-metadata-browser-2.5.11.tgz#dd28bc6506075ac46ce33f72e6828742b4b6cb9e" + integrity sha512-Khq5nYapffIet0PUVb5J69pZPgqgn+/yoEr0jkO/OjH5xwfdz6rdwj0zsWPaqo3ylv+OthXoGjT6EegVHbMkJQ== + dependencies: + buffer "^6.0.3" + debug "^4.3.4" + music-metadata "^7.13.3" + readable-stream "^4.3.0" + readable-web-to-node-stream "^3.0.2" + +music-metadata@^10.5.1: + version "10.5.1" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-10.5.1.tgz#2f19b6dd70ba2d93f9b15ee5da068f247d80fe42" + integrity sha512-lrBqOlhgAlqzBkqEMiqnVaCXwfQBkid8eXborPVceYv/t4lfXN3DiCBHed3fu+5kpqpaAez/rn3/PiT/fCYU4g== + dependencies: + "@tokenizer/token" "^0.3.0" + content-type "^1.0.5" + debug "^4.3.7" + file-type "^19.6.0" + media-typer "^1.1.0" + strtok3 "^9.0.1" + token-types "^6.0.0" + uint8array-extras "^1.4.0" + +music-metadata@^7.13.3: + version "7.14.0" + resolved "https://registry.yarnpkg.com/music-metadata/-/music-metadata-7.14.0.tgz#74e3e5fc8e09b86d1a3e791fb5ce9ccdc4347ad9" + integrity sha512-xrm3w7SV0Wk+OythZcSbaI8mcr/KHd0knJieu8bVpaPfMv/Agz5EooCAPz3OR5hbYMiUG6dgAPKZKnMzV+3amA== + dependencies: + "@tokenizer/token" "^0.3.0" + content-type "^1.0.5" + debug "^4.3.4" + file-type "^16.5.4" + media-typer "^1.1.0" + strtok3 "^6.3.0" + token-types "^4.2.1" + +path-parse@^1.0.7: + version "1.0.7" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735" + integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw== + +peek-readable@^4.1.0: + version "4.1.0" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-4.1.0.tgz#4ece1111bf5c2ad8867c314c81356847e8a62e72" + integrity sha512-ZI3LnwUv5nOGbQzD9c2iDG6toheuXSZP5esSHBjopsXH4dg19soufvpUGA3uohi5anFtGb2lhAVdHzH6R/Evvg== + +peek-readable@^5.3.1: + version "5.3.1" + resolved "https://registry.yarnpkg.com/peek-readable/-/peek-readable-5.3.1.tgz#9cc2c275cceda9f3d07a988f4f664c2080387dff" + integrity sha512-GVlENSDW6KHaXcd9zkZltB7tCLosKB/4Hg0fqBJkAoBgYG2Tn1xtMgXtSUuMU9AK/gCm/tTdT8mgAeF4YNeeqw== + +picomatch@^2.3.1: + version "2.3.1" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" + integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== + +picomatch@^4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-4.0.2.tgz#77c742931e8f3b8820946c76cd0c1f13730d1dab" + integrity sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + +readable-stream@^3.6.0: + version "3.6.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-3.6.2.tgz#56a9b36ea965c00c5a93ef31eb111a0f11056967" + integrity sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA== + dependencies: + inherits "^2.0.3" + string_decoder "^1.1.1" + util-deprecate "^1.0.1" + +readable-stream@^4.3.0: + version "4.5.2" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-4.5.2.tgz#9e7fc4c45099baeed934bff6eb97ba6cf2729e09" + integrity sha512-yjavECdqeZ3GLXNgRXgeQEdz9fvDDkNKyHnbHRFtOr7/LcfgBcmct7t/ET+HaCTqfh06OzoAxrkN/IfjJBVe+g== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + +readable-web-to-node-stream@^3.0.0, readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz#5d52bb5df7b54861fd48d015e93a2cb87b3ee0bb" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + +resolve@^1.22.1: + version "1.22.8" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.8.tgz#b6c87a9f2aa06dfab52e3d70ac8cde321fa5a48d" + integrity sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw== + dependencies: + is-core-module "^2.13.0" + path-parse "^1.0.7" + supports-preserve-symlinks-flag "^1.0.0" + +rollup@^4.24.0: + version "4.24.0" + resolved "https://registry.yarnpkg.com/rollup/-/rollup-4.24.0.tgz#c14a3576f20622ea6a5c9cad7caca5e6e9555d05" + integrity sha512-DOmrlGSXNk1DM0ljiQA+i+o0rSLhtii1je5wgk60j49d1jHT5YYttBv1iWOnYSTG+fZZESUOSNiAl89SIet+Cg== + dependencies: + "@types/estree" "1.0.6" + optionalDependencies: + "@rollup/rollup-android-arm-eabi" "4.24.0" + "@rollup/rollup-android-arm64" "4.24.0" + "@rollup/rollup-darwin-arm64" "4.24.0" + "@rollup/rollup-darwin-x64" "4.24.0" + "@rollup/rollup-linux-arm-gnueabihf" "4.24.0" + "@rollup/rollup-linux-arm-musleabihf" "4.24.0" + "@rollup/rollup-linux-arm64-gnu" "4.24.0" + "@rollup/rollup-linux-arm64-musl" "4.24.0" + "@rollup/rollup-linux-powerpc64le-gnu" "4.24.0" + "@rollup/rollup-linux-riscv64-gnu" "4.24.0" + "@rollup/rollup-linux-s390x-gnu" "4.24.0" + "@rollup/rollup-linux-x64-gnu" "4.24.0" + "@rollup/rollup-linux-x64-musl" "4.24.0" + "@rollup/rollup-win32-arm64-msvc" "4.24.0" + "@rollup/rollup-win32-ia32-msvc" "4.24.0" + "@rollup/rollup-win32-x64-msvc" "4.24.0" + fsevents "~2.3.2" + +safe-buffer@~5.2.0: + version "5.2.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6" + integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ== + +string_decoder@^1.1.1, string_decoder@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.3.0.tgz#42f114594a46cf1a8e30b0a84f56c78c3edac21e" + integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== + dependencies: + safe-buffer "~5.2.0" + +strtok3@^6.2.4, strtok3@^6.3.0: + version "6.3.0" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-6.3.0.tgz#358b80ffe6d5d5620e19a073aa78ce947a90f9a0" + integrity sha512-fZtbhtvI9I48xDSywd/somNqgUHl2L2cstmXCCif0itOf96jeW18MBSyrLuNicYQVkvpOxkZtkzujiTJ9LW5Jw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^4.1.0" + +strtok3@^9.0.1: + version "9.0.1" + resolved "https://registry.yarnpkg.com/strtok3/-/strtok3-9.0.1.tgz#7e3d7bbd2b829c9def6a7bb90d82e240abdd32be" + integrity sha512-ERPW+XkvX9W2A+ov07iy+ZFJpVdik04GhDA4eVogiG9hpC97Kem2iucyzhFxbFRvQ5o2UckFtKZdp1hkGvnrEw== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.3.1" + +supports-preserve-symlinks-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09" + integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w== + +token-types@^4.1.1, token-types@^4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-4.2.1.tgz#0f897f03665846982806e138977dbe72d44df753" + integrity sha512-6udB24Q737UD/SDsKAHI9FCRP7Bqc9D/MQUV02ORQg5iskjtLJlZJNdN4kKtcdtwCeWIwIHDGaUsTsCCAa8sFQ== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +token-types@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/token-types/-/token-types-6.0.0.tgz#1ab26be1ef9c434853500c071acfe5c8dd6544a3" + integrity sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +uint8array-extras@^1.3.0, uint8array-extras@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/uint8array-extras/-/uint8array-extras-1.4.0.tgz#e42a678a6dd335ec2d21661333ed42f44ae7cc74" + integrity sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ== + +util-deprecate@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + integrity sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw== + +xhr2@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/xhr2/-/xhr2-0.1.4.tgz#7f87658847716db5026323812f818cadab387a5f" + integrity sha512-3QGhDryRzTbIDj+waTRvMBe8SyPhW79kz3YnNb+HQt/6LPYQT3zT3Jt0Y8pBofZqQX26x8Ecfv0FXR72uH5VpA==