diff --git a/.gitignore b/.gitignore
index ff71ee0..44a42ff 100644
--- a/.gitignore
+++ b/.gitignore
@@ -13,4 +13,8 @@
.externalNativeBuild
.cxx
local.properties
-keystore/
\ No newline at end of file
+keystore/node_modules/
+package-lock.json
+
+node_modules/
+package-lock.json
diff --git a/WEB/.gitignore b/WEB/.gitignore
new file mode 100644
index 0000000..504afef
--- /dev/null
+++ b/WEB/.gitignore
@@ -0,0 +1,2 @@
+node_modules/
+package-lock.json
diff --git a/WEB/app.js b/WEB/app.js
new file mode 100644
index 0000000..cc246a9
--- /dev/null
+++ b/WEB/app.js
@@ -0,0 +1,372 @@
+// API Configuration (Local Node Backend)
+const BACKEND_URL = "http://localhost:3000";
+
+// State
+let tracks = [];
+let currentTrackIndex = -1;
+let isPlaying = false;
+let isAudioOnly = true;
+let currentTab = 'trending';
+
+// DOM Elements
+const trackListContainer = document.getElementById('trackList');
+const searchInput = document.getElementById('searchInput');
+const searchBtn = document.getElementById('searchBtn');
+const qualityToggle = document.getElementById('qualityToggle');
+
+// Player Elements
+const videoContainer = document.getElementById('videoContainer');
+const closeVideoBtn = document.getElementById('closeVideoBtn');
+const playerDock = document.getElementById('playerDock');
+
+// HTML5 Media Players (Replacing YouTube IFrame API)
+let audioPlayer = document.getElementById('audioPlayer');
+let videoPlayer = document.getElementById('videoPlayer');
+
+if (!audioPlayer) {
+ audioPlayer = document.createElement('audio');
+ audioPlayer.id = 'audioPlayer';
+ playerDock.appendChild(audioPlayer);
+}
+
+if (!videoPlayer) {
+ videoPlayer = document.createElement('video');
+ videoPlayer.id = 'videoPlayer';
+ videoPlayer.className = 'shadow-brutal';
+ videoPlayer.controls = true;
+
+ // Clear out any leftover iframe or divs
+ const ytDiv = document.getElementById('ytplayer');
+ if (ytDiv) ytDiv.remove();
+
+ videoContainer.insertBefore(videoPlayer, closeVideoBtn);
+}
+
+// UI Elements
+const loader = document.getElementById('loader');
+const heroSection = document.getElementById('heroSection');
+const heroTitle = document.getElementById('heroTitle');
+const heroVinylArt = document.getElementById('heroVinylArt');
+const heroPlayBtn = document.getElementById('heroPlayBtn');
+
+// Controls
+const dockTitle = document.getElementById('dockTitle');
+const dockArtist = document.getElementById('dockArtist');
+const dockArt = document.getElementById('dockArt');
+const btnPlayPause = document.getElementById('btnPlayPause');
+const iconPlay = document.getElementById('iconPlay');
+const iconPause = document.getElementById('iconPause');
+const btnPrev = document.getElementById('btnPrev');
+const btnNext = document.getElementById('btnNext');
+const timeCurrent = document.getElementById('timeCurrent');
+const timeTotal = document.getElementById('timeTotal');
+const progressFill = document.getElementById('progressFill');
+const progressHandle = document.getElementById('progressHandle');
+const progressBar = document.getElementById('progressBar');
+
+// Format Time (Seconds to MM:SS)
+function formatTime(seconds) {
+ if (isNaN(seconds) || !isFinite(seconds)) return "0:00";
+ const m = Math.floor(seconds / 60);
+ const s = Math.floor(seconds % 60);
+ return `${m}:${s.toString().padStart(2, '0')}`;
+}
+
+// Show/Hide Loader
+function setLoader(show) {
+ if (show) {
+ loader.classList.remove('hidden');
+ trackListContainer.innerHTML = '';
+ trackListContainer.appendChild(loader);
+ } else {
+ loader.classList.add('hidden');
+ }
+}
+
+// Load Trending
+async function loadTrending(filter = "music") {
+ setLoader(true);
+
+ try {
+ const res = await fetch(`${BACKEND_URL}/trending?filter=${filter}`);
+ if (!res.ok) throw new Error("Backend failed");
+
+ const data = await res.json();
+ if (data.length === 0) throw new Error("Empty data");
+
+ tracks = data;
+ renderTracks();
+
+ // Update Hero
+ if (tracks.length > 0) {
+ const safeHeroTitle = tracks[0].title.replace(//g, ">");
+ heroTitle.innerHTML = safeHeroTitle.split(' ').slice(0,3).join('
');
+ heroVinylArt.style.backgroundImage = `url('${tracks[0].art}')`;
+ heroVinylArt.style.backgroundSize = 'cover';
+ }
+ } catch (err) {
+ console.error("Trending Error", err);
+ trackListContainer.innerHTML = '
Failed to load from Server. Please ensure backend is running.
';
+ } finally {
+ setLoader(false);
+ }
+}
+
+// Search
+async function search(query) {
+ if (!query) return;
+ setLoader(true);
+
+ try {
+ const searchUrl = `${BACKEND_URL}/search?q=${encodeURIComponent(query)}`;
+ const res = await fetch(searchUrl);
+ if (!res.ok) throw new Error("Search failed");
+
+ const data = await res.json();
+ if (data.length === 0) {
+ trackListContainer.innerHTML = 'No results found
';
+ return;
+ }
+
+ tracks = data;
+ renderTracks();
+ } catch (err) {
+ console.error("Search Error", err);
+ trackListContainer.innerHTML = 'Error searching
';
+ } finally {
+ setLoader(false);
+ }
+}
+
+// Render Tracks (Safely construct HTML)
+function renderTracks() {
+ trackListContainer.innerHTML = '';
+ tracks.forEach((track, index) => {
+ const item = document.createElement('article');
+ item.className = `track-item shadow-brutal ${index === currentTrackIndex && isPlaying ? 'playing' : ''}`;
+ item.dataset.index = index;
+
+ const safeTitle = track.title.replace(//g, ">");
+ const safeArtist = track.artist.replace(//g, ">");
+
+ item.innerHTML = `
+ ${String(index + 1).padStart(2, '0')}
+
+
+
${safeTitle}
+
${safeArtist}
+
+ ${track.duration}
+
+ `;
+
+ item.addEventListener('click', () => {
+ if (currentTrackIndex === index) {
+ togglePlay();
+ } else {
+ playTrack(index);
+ }
+ });
+
+ trackListContainer.appendChild(item);
+ });
+}
+
+// Media Logic: Fetch stream from backend
+async function playTrack(index) {
+ if (index < 0 || index >= tracks.length) return;
+
+ currentTrackIndex = index;
+ const track = tracks[currentTrackIndex];
+
+ updateUI(track, true);
+
+ // Pause both players
+ audioPlayer.pause();
+ videoPlayer.pause();
+
+ try {
+ const endpoint = isAudioOnly ? '/audio' : '/video';
+ const res = await fetch(`${BACKEND_URL}${endpoint}?id=${track.id}`);
+
+ if (!res.ok) throw new Error("Failed to extract stream");
+
+ const data = await res.json();
+
+ if (isAudioOnly) {
+ audioPlayer.src = data.url;
+ audioPlayer.play();
+ videoContainer.classList.add('hidden');
+ } else {
+ videoPlayer.src = data.url;
+ videoPlayer.play();
+ videoContainer.classList.remove('hidden');
+ }
+
+ isPlaying = true;
+ updateUI(track, false);
+
+ } catch (err) {
+ console.error("Playback Error:", err);
+ alert("Failed to stream media. It might be age-restricted or blocked.");
+ isPlaying = false;
+ updateUI(track, false);
+ }
+}
+
+function togglePlay() {
+ if (currentTrackIndex === -1) {
+ if (tracks.length > 0) playTrack(0);
+ return;
+ }
+
+ const activePlayer = isAudioOnly ? audioPlayer : videoPlayer;
+
+ if (activePlayer.paused) {
+ activePlayer.play();
+ isPlaying = true;
+ } else {
+ activePlayer.pause();
+ isPlaying = false;
+ }
+ updateUI(tracks[currentTrackIndex], false);
+}
+
+// Media Event Listeners for sync
+const getActivePlayerObj = () => isAudioOnly ? audioPlayer : videoPlayer;
+
+audioPlayer.addEventListener('timeupdate', updateProgress);
+videoPlayer.addEventListener('timeupdate', updateProgress);
+
+audioPlayer.addEventListener('ended', () => playTrack(currentTrackIndex + 1));
+videoPlayer.addEventListener('ended', () => playTrack(currentTrackIndex + 1));
+
+function updateProgress() {
+ const player = getActivePlayerObj();
+ if (!player.duration || isNaN(player.duration)) return;
+
+ const percent = (player.currentTime / player.duration) * 100;
+ progressFill.style.width = `${percent}%`;
+ progressHandle.style.left = `${percent}%`;
+
+ timeCurrent.textContent = formatTime(player.currentTime);
+ timeTotal.textContent = formatTime(player.duration);
+}
+
+// Seek
+progressBar.addEventListener('click', (e) => {
+ const player = getActivePlayerObj();
+ if (player.duration) {
+ const rect = progressBar.getBoundingClientRect();
+ const percent = (e.clientX - rect.left) / rect.width;
+ player.currentTime = player.duration * percent;
+ }
+});
+
+// UI Updates
+function updateUI(track, isLoading) {
+ if (playerDock.classList.contains('hidden')) {
+ playerDock.classList.remove('hidden');
+ }
+
+ dockTitle.textContent = isLoading ? "Extracting Stream..." : track.title.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>');
+ dockArtist.textContent = track.artist.replace(/&/g, '&');
+ dockArt.style.backgroundImage = `url('${track.art}')`;
+
+ if (isPlaying && !isLoading) {
+ iconPlay.classList.add('hidden');
+ iconPause.classList.remove('hidden');
+ btnPlayPause.style.backgroundColor = 'var(--accent-red)';
+ } else {
+ iconPlay.classList.remove('hidden');
+ iconPause.classList.add('hidden');
+ btnPlayPause.style.backgroundColor = 'var(--accent-yellow)';
+ }
+
+ document.querySelectorAll('.track-item').forEach((el, idx) => {
+ if (idx === currentTrackIndex && isPlaying && !isLoading) {
+ el.classList.add('playing');
+ } else {
+ el.classList.remove('playing');
+ }
+ });
+}
+
+// Button Listeners
+btnPlayPause.addEventListener('click', togglePlay);
+btnNext.addEventListener('click', () => playTrack(currentTrackIndex + 1));
+btnPrev.addEventListener('click', () => playTrack(currentTrackIndex - 1));
+heroPlayBtn.addEventListener('click', () => {
+ if(tracks.length > 0) playTrack(0);
+});
+
+closeVideoBtn.addEventListener('click', () => {
+ // Hide video container
+ videoContainer.classList.add('hidden');
+ videoPlayer.pause();
+
+ isAudioOnly = true;
+ qualityToggle.textContent = "Audio Only";
+ qualityToggle.style.backgroundColor = "";
+ qualityToggle.style.color = "";
+
+ // Resume audio
+ if (currentTrackIndex !== -1 && isPlaying) {
+ const currentTime = videoPlayer.currentTime;
+ playTrack(currentTrackIndex).then(() => {
+ audioPlayer.currentTime = currentTime;
+ });
+ }
+});
+
+qualityToggle.addEventListener('click', () => {
+ isAudioOnly = !isAudioOnly;
+ qualityToggle.textContent = isAudioOnly ? "Audio Only" : "Video Mode";
+ qualityToggle.style.backgroundColor = isAudioOnly ? "" : "var(--accent-purple)";
+ qualityToggle.style.color = isAudioOnly ? "" : "white";
+
+ if (currentTrackIndex !== -1 && isPlaying) {
+ const previousPlayer = !isAudioOnly ? audioPlayer : videoPlayer;
+ const currentTime = previousPlayer.currentTime;
+ previousPlayer.pause();
+
+ playTrack(currentTrackIndex).then(() => {
+ getActivePlayerObj().currentTime = currentTime;
+ });
+ }
+});
+
+searchBtn.addEventListener('click', () => search(searchInput.value));
+searchInput.addEventListener('keypress', (e) => {
+ if (e.key === 'Enter') search(searchInput.value);
+});
+
+// Tabs
+document.querySelectorAll('.nav-pills .pill').forEach(pill => {
+ if (pill.id === 'qualityToggle') return;
+
+ pill.addEventListener('click', (e) => {
+ document.querySelectorAll('.nav-pills .pill').forEach(p => p.classList.remove('active'));
+ e.target.classList.add('active');
+
+ const color = e.target.dataset.color;
+ document.documentElement.style.setProperty('--accent-blue', color);
+
+ currentTab = e.target.id.replace('tab', '').toLowerCase();
+
+ if (currentTab === 'trending') {
+ loadTrending('all');
+ } else if (currentTab === 'music') {
+ loadTrending('music');
+ } else {
+ loadTrending('video');
+ }
+ });
+});
+
+// Init
+loadTrending('all');
diff --git a/WEB/index.html b/WEB/index.html
new file mode 100644
index 0000000..b557bda
--- /dev/null
+++ b/WEB/index.html
@@ -0,0 +1,105 @@
+
+
+
+
+
+ Jukebox PLAY
+
+
+
+
+
+
+
+
+
+
+
+
+ NOW TRENDING
+ Loading
Vibes...
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
No track playing
+
+
Select a track
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/WEB/package-lock.json b/WEB/package-lock.json
new file mode 100644
index 0000000..0d0c094
--- /dev/null
+++ b/WEB/package-lock.json
@@ -0,0 +1,1641 @@
+{
+ "name": "web",
+ "version": "1.0.0",
+ "lockfileVersion": 3,
+ "requires": true,
+ "packages": {
+ "": {
+ "name": "web",
+ "version": "1.0.0",
+ "license": "ISC",
+ "dependencies": {
+ "@distube/ytdl-core": "^4.16.12",
+ "cors": "^2.8.6",
+ "express": "^5.2.1",
+ "yt-search": "^2.13.1"
+ }
+ },
+ "node_modules/@distube/ytdl-core": {
+ "version": "4.16.12",
+ "resolved": "https://registry.npmjs.org/@distube/ytdl-core/-/ytdl-core-4.16.12.tgz",
+ "integrity": "sha512-/NR8Jur1Q4E2oD+DJta7uwWu7SkqdEkhwERt7f4iune70zg7ZlLLTOHs1+jgg3uD2jQjpdk7RGC16FqstG4RsA==",
+ "license": "MIT",
+ "dependencies": {
+ "http-cookie-agent": "^7.0.1",
+ "https-proxy-agent": "^7.0.6",
+ "m3u8stream": "^0.8.6",
+ "miniget": "^4.2.3",
+ "sax": "^1.4.1",
+ "tough-cookie": "^5.1.2",
+ "undici": "^7.8.0"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ },
+ "funding": {
+ "url": "https://github.com/distubejs/ytdl-core?sponsor"
+ }
+ },
+ "node_modules/@jsep-plugin/assignment": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/@jsep-plugin/assignment/-/assignment-1.3.0.tgz",
+ "integrity": "sha512-VVgV+CXrhbMI3aSusQyclHkenWSAm95WaiKrMxRFam3JSUiIaQjoMIw2sEs/OX4XifnqeQUN4DYbJjlA8EfktQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.16.0"
+ },
+ "peerDependencies": {
+ "jsep": "^0.4.0||^1.0.0"
+ }
+ },
+ "node_modules/@jsep-plugin/regex": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/@jsep-plugin/regex/-/regex-1.0.4.tgz",
+ "integrity": "sha512-q7qL4Mgjs1vByCaTnDFcBnV9HS7GVPJX5vyVoCgZHNSC9rjwIlmbXG5sUuorR5ndfHAIlJ8pVStxvjXHbNvtUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.16.0"
+ },
+ "peerDependencies": {
+ "jsep": "^0.4.0||^1.0.0"
+ }
+ },
+ "node_modules/accepts": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/accepts/-/accepts-2.0.0.tgz",
+ "integrity": "sha512-5cvg6CtKwfgdmVqY1WIiXKc3Q1bkRqGLi+2W/6ao+6Y7gu/RCwRuAhGEzh5B4KlszSuTLgZYuqFqo5bImjNKng==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-types": "^3.0.0",
+ "negotiator": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/agent-base": {
+ "version": "7.1.4",
+ "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.4.tgz",
+ "integrity": "sha512-MnA+YT8fwfJPgBx3m60MNqakm30XOkyIoH1y6huTQvC0PwZG7ki8NacLBcrPbNoo8vEZy7Jpuk7+jMO+CUovTQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/ansi-regex": {
+ "version": "3.0.1",
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/async.parallellimit": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.parallellimit/-/async.parallellimit-0.5.2.tgz",
+ "integrity": "sha512-4Di2nFsb3jL7aUIICvRSvtw/oynpMIx0JrwYn5hqJI661Dd+mYBi2ElOukOQgRHihU1SCTapb86Vx/Snva5M1w==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.eachoflimit": "0.5.2",
+ "async.util.parallel": "0.5.2"
+ }
+ },
+ "node_modules/async.util.eachoflimit": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.eachoflimit/-/async.util.eachoflimit-0.5.2.tgz",
+ "integrity": "sha512-oZksH0sBW0AEOJKgBCQ79io9DZruoRBLTAea/Ik36pejR7pDpByvtXeuJsoZdPwSVslsrQcsUfucbUaiXYBnAQ==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.keyiterator": "0.5.2",
+ "async.util.noop": "0.5.2",
+ "async.util.once": "0.5.2",
+ "async.util.onlyonce": "0.5.2"
+ }
+ },
+ "node_modules/async.util.isarray": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz",
+ "integrity": "sha512-wbUzlrwON8RUgi+v/rhF0U99Ce8Osjcn+JP/mFNg6ymvShcobAOvE6cvLajSY5dPqKCOE1xfdhefgBif11zZgw==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.isarraylike": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.isarraylike/-/async.util.isarraylike-0.5.2.tgz",
+ "integrity": "sha512-DbFpsz3ZFNkohAW8IpGTlm8gotU32zpqe3Y2XkEA/G3XNO6rmUTKPpo7XgXUruoI+AsGi8+0zWpJHe7t1sLiAg==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.isarray": "0.5.2"
+ }
+ },
+ "node_modules/async.util.keyiterator": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.keyiterator/-/async.util.keyiterator-0.5.2.tgz",
+ "integrity": "sha512-cktrETawCwgu13y3KZs2uMGFnNHc+IjKPZsavtRaoCjLELkePb2co4zrr+ghPvEqLXZIJPTKqC2HFZgJTssMVw==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.isarraylike": "0.5.2",
+ "async.util.keys": "0.5.2"
+ }
+ },
+ "node_modules/async.util.keys": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.keys/-/async.util.keys-0.5.2.tgz",
+ "integrity": "sha512-umCOCRCRYwIC2Ho3fbuhKwIIe7OhQsVoVKGoF5GoQiGJUmjP4TG0Bmmcdpm7yW/znoIGKpnjKzVQz0niH4tfqw==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.noop": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz",
+ "integrity": "sha512-AdwShXwE0KoskgqVJAck8zcM32nIHj3AC8ZN62ZaR5srhrY235Nw18vOJZWxcOfhxdVM0hRVKM8kMx7lcl7cCQ==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.once": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.once/-/async.util.once-0.5.2.tgz",
+ "integrity": "sha512-YQ5WPzDTt2jlblUDkq2I5RV/KiAJErJ4/0cEFhYPaZzqIuF/xDzdGvnEKe7UeuoMszsVPeajzcpKgkbwdb9MUA==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.onlyonce": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz",
+ "integrity": "sha512-UgQvkU9JZ+I0Cm1f56XyGXcII+J3d/5XWUuHpcevlItuA3WFSJcqZrsyAUck2FkRSD8BwYQX1zUTDp3SJMVESg==",
+ "license": "MIT"
+ },
+ "node_modules/async.util.parallel": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.parallel/-/async.util.parallel-0.5.2.tgz",
+ "integrity": "sha512-0bEvwmQ8fxsTYNwacw5iq0i3PvGryRkXxZ01Rvox21izdMdls9IH2rAZjfunbgI8j6nFRyIdCmMINQ9kka99ow==",
+ "license": "MIT",
+ "dependencies": {
+ "async.util.isarraylike": "0.5.2",
+ "async.util.noop": "0.5.2",
+ "async.util.restparam": "0.5.2"
+ }
+ },
+ "node_modules/async.util.restparam": {
+ "version": "0.5.2",
+ "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz",
+ "integrity": "sha512-Q9Z+zgmtMxFX5i7CnBvNOkgrL5hptztCqwarQluyNudUUk4iCmyjmsQl8MuQEjNh3gGqP5ayvDaextL1VXXgIg==",
+ "license": "MIT"
+ },
+ "node_modules/balanced-match": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
+ "license": "MIT"
+ },
+ "node_modules/body-parser": {
+ "version": "2.2.2",
+ "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.2.tgz",
+ "integrity": "sha512-oP5VkATKlNwcgvxi0vM0p/D3n2C3EReYVX+DNYs5TjZFn/oQt2j+4sVJtSMr18pdRr8wjTcBl6LoV+FUwzPmNA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "^3.1.2",
+ "content-type": "^1.0.5",
+ "debug": "^4.4.3",
+ "http-errors": "^2.0.0",
+ "iconv-lite": "^0.7.0",
+ "on-finished": "^2.4.1",
+ "qs": "^6.14.1",
+ "raw-body": "^3.0.1",
+ "type-is": "^2.0.1"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/boolbase": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/boolbase/-/boolbase-1.0.0.tgz",
+ "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
+ "license": "ISC"
+ },
+ "node_modules/boolstring": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/boolstring/-/boolstring-2.0.1.tgz",
+ "integrity": "sha512-tpNlEZsRdZzIP7KElpv0GRiRsnkh7+Ko+W2ohZt2DcH3/z/Gya1r+0dlSSNc5GWGSt0zG7c4JV02U7ZCk/1lWw==",
+ "license": "MIT"
+ },
+ "node_modules/brace-expansion": {
+ "version": "1.1.12",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.12.tgz",
+ "integrity": "sha512-9T9UjW3r0UW5c1Q7GTwllptXwhvYmEzFhzMfZ9H7FQWt+uZePjZPjBP/W1ZEyZ1twGWom5/56TF4lPcqjnDHcg==",
+ "license": "MIT",
+ "dependencies": {
+ "balanced-match": "^1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "node_modules/bytes": {
+ "version": "3.1.2",
+ "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
+ "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/call-bind-apply-helpers": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/call-bind-apply-helpers/-/call-bind-apply-helpers-1.0.2.tgz",
+ "integrity": "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/call-bound": {
+ "version": "1.0.4",
+ "resolved": "https://registry.npmjs.org/call-bound/-/call-bound-1.0.4.tgz",
+ "integrity": "sha512-+ys997U96po4Kx/ABpBCqhA9EuxJaQWDQg7295H4hBphv3IZg0boBKuwYpt4YXp6MZ5AmZQnU/tyMTlRpaSejg==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "get-intrinsic": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/cheerio": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.2.0.tgz",
+ "integrity": "sha512-WDrybc/gKFpTYQutKIK6UvfcuxijIZfMfXaYm8NMsPQxSYvf+13fXUJ4rztGGbJcBQ/GF55gvrZ0Bc0bj/mqvg==",
+ "license": "MIT",
+ "dependencies": {
+ "cheerio-select": "^2.1.0",
+ "dom-serializer": "^2.0.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "encoding-sniffer": "^0.2.1",
+ "htmlparser2": "^10.1.0",
+ "parse5": "^7.3.0",
+ "parse5-htmlparser2-tree-adapter": "^7.1.0",
+ "parse5-parser-stream": "^7.1.2",
+ "undici": "^7.19.0",
+ "whatwg-mimetype": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=20.18.1"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/cheerio?sponsor=1"
+ }
+ },
+ "node_modules/cheerio-select": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz",
+ "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-select": "^5.1.0",
+ "css-what": "^6.1.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
+ "license": "MIT"
+ },
+ "node_modules/content-disposition": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-1.0.1.tgz",
+ "integrity": "sha512-oIXISMynqSqm241k6kcQ5UwttDILMK4BiurCfGEREw6+X9jkkpEe5T9FZaApyLGGOnFuyMWZpdolTXMtvEJ08Q==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/content-type": {
+ "version": "1.0.5",
+ "resolved": "https://registry.npmjs.org/content-type/-/content-type-1.0.5.tgz",
+ "integrity": "sha512-nTjqfcBFEipKdXCv4YDQWCfmcLZKm81ldF0pAopTvyrFGVbcR6P/VAAd5G7N+0tTr8QqiU0tFadD6FK4NtJwOA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.7.2.tgz",
+ "integrity": "sha512-yki5XnKuf750l50uGTllt6kKILY4nQ1eNIQatoXEByZ5dWgnKqbnqmTrBE5B4N7lrMJKQ2ytWMiTO2o0v6Ew/w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/cookie-signature": {
+ "version": "1.2.2",
+ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.2.2.tgz",
+ "integrity": "sha512-D76uU73ulSXrD1UXF4KE2TMxVVwhsnCgfAyTg9k8P6KGZjlXKrOLe4dJQKI3Bxi5wjesZoFXJWElNWBjPZMbhg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6.6.0"
+ }
+ },
+ "node_modules/cors": {
+ "version": "2.8.6",
+ "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.6.tgz",
+ "integrity": "sha512-tJtZBBHA6vjIAaF6EnIaq6laBBP9aq/Y3ouVJjEfoHbRBcHBAHYcMh/w8LDrk2PvIMMq8gmopa5D4V8RmbrxGw==",
+ "license": "MIT",
+ "dependencies": {
+ "object-assign": "^4",
+ "vary": "^1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/css-select": {
+ "version": "5.2.2",
+ "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.2.2.tgz",
+ "integrity": "sha512-TizTzUddG/xYLA3NXodFM0fSbNizXjOKhqiQQwvhlspadZokn1KDy0NZFS0wuEubIYAV5/c1/lAr0TaaFXEXzw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0",
+ "css-what": "^6.1.0",
+ "domhandler": "^5.0.2",
+ "domutils": "^3.0.1",
+ "nth-check": "^2.0.1"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/css-what": {
+ "version": "6.2.2",
+ "resolved": "https://registry.npmjs.org/css-what/-/css-what-6.2.2.tgz",
+ "integrity": "sha512-u/O3vwbptzhMs3L1fQE82ZSLHQQfto5gyZzwteVIEyeaY5Fc7R4dapF/BvRoSYFeqfBk4m0V1Vafq5Pjv25wvA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">= 6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/fb55"
+ }
+ },
+ "node_modules/dasu": {
+ "version": "0.4.3",
+ "resolved": "https://registry.npmjs.org/dasu/-/dasu-0.4.3.tgz",
+ "integrity": "sha512-AFwspl5k7V8MW8H7tyIGJ0gtOauUg7JC+DgiRFUIXvPNNDFXTMtvnCkZY0macN6JLGqBjNP38WVnQN7Iv3RSlg==",
+ "license": "MIT"
+ },
+ "node_modules/debug": {
+ "version": "4.4.3",
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz",
+ "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==",
+ "license": "MIT",
+ "dependencies": {
+ "ms": "^2.1.3"
+ },
+ "engines": {
+ "node": ">=6.0"
+ },
+ "peerDependenciesMeta": {
+ "supports-color": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/depd": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+ "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/dom-serializer": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz",
+ "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==",
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.2",
+ "entities": "^4.2.0"
+ },
+ "funding": {
+ "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1"
+ }
+ },
+ "node_modules/domelementtype": {
+ "version": "2.3.0",
+ "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-2.3.0.tgz",
+ "integrity": "sha512-OLETBj6w0OsagBwdXnPdN0cnMfF9opN69co+7ZrbfPGrdpPVNBUj02spi6B1N7wChLQiPn4CSH/zJvXw56gmHw==",
+ "funding": [
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "BSD-2-Clause"
+ },
+ "node_modules/domhandler": {
+ "version": "5.0.3",
+ "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz",
+ "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "domelementtype": "^2.3.0"
+ },
+ "engines": {
+ "node": ">= 4"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domhandler?sponsor=1"
+ }
+ },
+ "node_modules/domutils": {
+ "version": "3.2.2",
+ "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.2.tgz",
+ "integrity": "sha512-6kZKyUajlDuqlHKVX1w7gyslj9MPIXzIFiz/rGu35uC1wMi+kMhQwGhl4lt9unC9Vb9INnY9Z3/ZA3+FhASLaw==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "dom-serializer": "^2.0.0",
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/domutils?sponsor=1"
+ }
+ },
+ "node_modules/dunder-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
+ "integrity": "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "gopd": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/ee-first": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
+ "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
+ "license": "MIT"
+ },
+ "node_modules/encodeurl": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
+ "integrity": "sha512-Q0n9HRi4m6JuGIV1eFlmvJB7ZEVxu93IrMyiMsGC0lrMJMWzRgx6WGquyfQgZVb31vhGgXnfmPNNXmxnOkRBrg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/encoding-sniffer": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.1.tgz",
+ "integrity": "sha512-5gvq20T6vfpekVtqrYQsSCFZ1wEg5+wW0/QaZMWkFr6BqD3NfKs0rLCx4rrVlSWJeZb5NBJgVLswK/w2MWU+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "^0.6.3",
+ "whatwg-encoding": "^3.1.1"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/encoding-sniffer?sponsor=1"
+ }
+ },
+ "node_modules/encoding-sniffer/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/entities": {
+ "version": "4.5.0",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-4.5.0.tgz",
+ "integrity": "sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/es-define-property": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.1.tgz",
+ "integrity": "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-errors": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz",
+ "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/es-object-atoms": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/es-object-atoms/-/es-object-atoms-1.1.1.tgz",
+ "integrity": "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/escape-html": {
+ "version": "1.0.3",
+ "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
+ "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
+ "license": "MIT"
+ },
+ "node_modules/etag": {
+ "version": "1.8.1",
+ "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
+ "integrity": "sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/express": {
+ "version": "5.2.1",
+ "resolved": "https://registry.npmjs.org/express/-/express-5.2.1.tgz",
+ "integrity": "sha512-hIS4idWWai69NezIdRt2xFVofaF4j+6INOpJlVOLDO8zXGpUVEVzIYk12UUi2JzjEzWL3IOAxcTubgz9Po0yXw==",
+ "license": "MIT",
+ "dependencies": {
+ "accepts": "^2.0.0",
+ "body-parser": "^2.2.1",
+ "content-disposition": "^1.0.0",
+ "content-type": "^1.0.5",
+ "cookie": "^0.7.1",
+ "cookie-signature": "^1.2.1",
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "finalhandler": "^2.1.0",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.0",
+ "merge-descriptors": "^2.0.0",
+ "mime-types": "^3.0.0",
+ "on-finished": "^2.4.1",
+ "once": "^1.4.0",
+ "parseurl": "^1.3.3",
+ "proxy-addr": "^2.0.7",
+ "qs": "^6.14.0",
+ "range-parser": "^1.2.1",
+ "router": "^2.2.0",
+ "send": "^1.1.0",
+ "serve-static": "^2.2.0",
+ "statuses": "^2.0.1",
+ "type-is": "^2.0.1",
+ "vary": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/finalhandler": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-2.1.1.tgz",
+ "integrity": "sha512-S8KoZgRZN+a5rNwqTxlZZePjT/4cnm0ROV70LedRHZ0p8u9fRID0hJUZQpkKLzro8LfmC8sx23bY6tVNxv8pQA==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "on-finished": "^2.4.1",
+ "parseurl": "^1.3.3",
+ "statuses": "^2.0.1"
+ },
+ "engines": {
+ "node": ">= 18.0.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/forwarded": {
+ "version": "0.2.0",
+ "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
+ "integrity": "sha512-buRG0fpBtRHSTCOASe6hD258tEubFoRLb4ZNA6NxMVHNw2gOcwHo9wyablzMzOA5z9xA9L1KNjk/Nt6MT9aYow==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/fresh": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/fresh/-/fresh-2.0.0.tgz",
+ "integrity": "sha512-Rx/WycZ60HOaqLKAi6cHRKKI7zxWbJ31MhntmtwMoaTeF7XFH9hhBp8vITaMidfljRQ6eYWCKkaTK+ykVJHP2A==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/function-bind": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz",
+ "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-intrinsic": {
+ "version": "1.3.0",
+ "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.3.0.tgz",
+ "integrity": "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bind-apply-helpers": "^1.0.2",
+ "es-define-property": "^1.0.1",
+ "es-errors": "^1.3.0",
+ "es-object-atoms": "^1.1.1",
+ "function-bind": "^1.1.2",
+ "get-proto": "^1.0.1",
+ "gopd": "^1.2.0",
+ "has-symbols": "^1.1.0",
+ "hasown": "^2.0.2",
+ "math-intrinsics": "^1.1.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/get-proto": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/get-proto/-/get-proto-1.0.1.tgz",
+ "integrity": "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g==",
+ "license": "MIT",
+ "dependencies": {
+ "dunder-proto": "^1.0.1",
+ "es-object-atoms": "^1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/gopd": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
+ "integrity": "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/has-symbols": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.1.0.tgz",
+ "integrity": "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/hasown": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz",
+ "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==",
+ "license": "MIT",
+ "dependencies": {
+ "function-bind": "^1.1.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/htmlparser2": {
+ "version": "10.1.0",
+ "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-10.1.0.tgz",
+ "integrity": "sha512-VTZkM9GWRAtEpveh7MSF6SjjrpNVNNVJfFup7xTY3UpFtm67foy9HDVXneLtFVt4pMz5kZtgNcvCniNFb1hlEQ==",
+ "funding": [
+ "https://github.com/fb55/htmlparser2?sponsor=1",
+ {
+ "type": "github",
+ "url": "https://github.com/sponsors/fb55"
+ }
+ ],
+ "license": "MIT",
+ "dependencies": {
+ "domelementtype": "^2.3.0",
+ "domhandler": "^5.0.3",
+ "domutils": "^3.2.2",
+ "entities": "^7.0.1"
+ }
+ },
+ "node_modules/htmlparser2/node_modules/entities": {
+ "version": "7.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-7.0.1.tgz",
+ "integrity": "sha512-TWrgLOFUQTH994YUyl1yT4uyavY5nNB5muff+RtWaqNVCAK408b5ZnnbNAUEWLTCpum9w6arT70i1XdQ4UeOPA==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/http-cookie-agent": {
+ "version": "7.0.3",
+ "resolved": "https://registry.npmjs.org/http-cookie-agent/-/http-cookie-agent-7.0.3.tgz",
+ "integrity": "sha512-EeZo7CGhfqPW6R006rJa4QtZZUpBygDa2HZH3DJqsTzTjyRE6foDBVQIv/pjVsxHC8z2GIdbB1Hvn9SRorP3WQ==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.4"
+ },
+ "engines": {
+ "node": ">=20.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/3846masa"
+ },
+ "peerDependencies": {
+ "tough-cookie": "^4.0.0 || ^5.0.0 || ^6.0.0",
+ "undici": "^7.0.0"
+ },
+ "peerDependenciesMeta": {
+ "undici": {
+ "optional": true
+ }
+ }
+ },
+ "node_modules/http-errors": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/http-errors/-/http-errors-2.0.1.tgz",
+ "integrity": "sha512-4FbRdAX+bSdmo4AUFuS0WNiPz8NgFt+r8ThgNWmlrjQjt1Q7ZR9+zTlce2859x4KSXrwIsaeTqDoKQmtP8pLmQ==",
+ "license": "MIT",
+ "dependencies": {
+ "depd": "~2.0.0",
+ "inherits": "~2.0.4",
+ "setprototypeof": "~1.2.0",
+ "statuses": "~2.0.2",
+ "toidentifier": "~1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/https-proxy-agent": {
+ "version": "7.0.6",
+ "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.6.tgz",
+ "integrity": "sha512-vK9P5/iUfdl95AI+JVyUuIcVtd4ofvtrOr3HNtM2yxC9bnMbEdp3x01OhQNnjb8IJYi38VlTE3mBXwcfvywuSw==",
+ "license": "MIT",
+ "dependencies": {
+ "agent-base": "^7.1.2",
+ "debug": "4"
+ },
+ "engines": {
+ "node": ">= 14"
+ }
+ },
+ "node_modules/human-time": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/human-time/-/human-time-0.0.2.tgz",
+ "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==",
+ "license": "MIT"
+ },
+ "node_modules/iconv-lite": {
+ "version": "0.7.2",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.7.2.tgz",
+ "integrity": "sha512-im9DjEDQ55s9fL4EYzOAv0yMqmMBSZp6G0VvFyTMPKWxiSBHUj9NW/qqLmXUwXrrM7AvqSlTCfvqRb0cM8yYqw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/inherits": {
+ "version": "2.0.4",
+ "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
+ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
+ "license": "ISC"
+ },
+ "node_modules/ipaddr.js": {
+ "version": "1.9.1",
+ "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
+ "integrity": "sha512-0KI/607xoxSToH7GjN1FfSbLoU0+btTicjsQSWQlh/hZykN8KpmMf7uYwPW3R+akZ6R/w18ZlXSHBYXiYUPO3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/is-fullwidth-code-point": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/is-promise": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-4.0.0.tgz",
+ "integrity": "sha512-hvpoI6korhJMnej285dSg6nu1+e6uxs7zG3BYAm5byqDsgJNWwxzM6z6iZiAgQR4TJ30JmBTOwqZUw3WlyH3AQ==",
+ "license": "MIT"
+ },
+ "node_modules/jsep": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/jsep/-/jsep-1.4.0.tgz",
+ "integrity": "sha512-B7qPcEVE3NVkmSJbaYxvv4cHkVW7DQsZz13pUMrfS8z8Q/BuShN+gcTXrUlPiGqM2/t/EEaI030bpxMqY8gMlw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 10.16.0"
+ }
+ },
+ "node_modules/jsonpath-plus": {
+ "version": "10.3.0",
+ "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-10.3.0.tgz",
+ "integrity": "sha512-8TNmfeTCk2Le33A3vRRwtuworG/L5RrgMvdjhKZxvyShO+mBu2fP50OWUjRLNtvw344DdDarFh9buFAZs5ujeA==",
+ "license": "MIT",
+ "dependencies": {
+ "@jsep-plugin/assignment": "^1.3.0",
+ "@jsep-plugin/regex": "^1.0.4",
+ "jsep": "^1.4.0"
+ },
+ "bin": {
+ "jsonpath": "bin/jsonpath-cli.js",
+ "jsonpath-plus": "bin/jsonpath-cli.js"
+ },
+ "engines": {
+ "node": ">=18.0.0"
+ }
+ },
+ "node_modules/keypress": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz",
+ "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==",
+ "license": "MIT"
+ },
+ "node_modules/m3u8stream": {
+ "version": "0.8.6",
+ "resolved": "https://registry.npmjs.org/m3u8stream/-/m3u8stream-0.8.6.tgz",
+ "integrity": "sha512-LZj8kIVf9KCphiHmH7sbFQTVe4tOemb202fWwvJwR9W5ENW/1hxJN6ksAWGhQgSBSa3jyWhnjKU1Fw1GaOdbyA==",
+ "license": "MIT",
+ "dependencies": {
+ "miniget": "^4.2.2",
+ "sax": "^1.2.4"
+ },
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/math-intrinsics": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
+ "integrity": "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ }
+ },
+ "node_modules/media-typer": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-1.1.0.tgz",
+ "integrity": "sha512-aisnrDP4GNe06UcKFnV5bfMNPBUw4jsLGaWwWfnH3v02GnBuXX2MCVn5RbrWo0j3pczUilYblq7fQ7Nw2t5XKw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/merge-descriptors": {
+ "version": "2.0.0",
+ "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-2.0.0.tgz",
+ "integrity": "sha512-Snk314V5ayFLhp3fkUREub6WtjBfPdCPY1Ln8/8munuLuiYhsABgBVWsozAG+MWMbVEvcdcpbi9R7ww22l9Q3g==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/mime-db": {
+ "version": "1.54.0",
+ "resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
+ "integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/mime-types": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/mime-types/-/mime-types-3.0.2.tgz",
+ "integrity": "sha512-Lbgzdk0h4juoQ9fCKXW4by0UJqj+nOOrI9MJ1sSj4nI8aI2eo1qmvQEie4VD1glsS250n15LsWsYtCugiStS5A==",
+ "license": "MIT",
+ "dependencies": {
+ "mime-db": "^1.54.0"
+ },
+ "engines": {
+ "node": ">=18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/mimic-fn": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
+ "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=6"
+ }
+ },
+ "node_modules/miniget": {
+ "version": "4.2.3",
+ "resolved": "https://registry.npmjs.org/miniget/-/miniget-4.2.3.tgz",
+ "integrity": "sha512-SjbDPDICJ1zT+ZvQwK0hUcRY4wxlhhNpHL9nJOB2MEAXRGagTljsO8MEDzQMTFf0Q8g4QNi8P9lEm/g7e+qgzA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=12"
+ }
+ },
+ "node_modules/minimatch": {
+ "version": "3.0.8",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
+ "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
+ "license": "ISC",
+ "dependencies": {
+ "brace-expansion": "^1.1.7"
+ },
+ "engines": {
+ "node": "*"
+ }
+ },
+ "node_modules/minimist": {
+ "version": "1.2.8",
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
+ "license": "MIT",
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/ms": {
+ "version": "2.1.3",
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
+ "license": "MIT"
+ },
+ "node_modules/negotiator": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/negotiator/-/negotiator-1.0.0.tgz",
+ "integrity": "sha512-8Ofs/AUQh8MaEcrlq5xOX0CQ9ypTF5dl78mjlMNfOK08fzpgTHQRQPBxcPlEtIw0yRpws+Zo/3r+5WRby7u3Gg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/node-fzf": {
+ "version": "0.14.0",
+ "resolved": "https://registry.npmjs.org/node-fzf/-/node-fzf-0.14.0.tgz",
+ "integrity": "sha512-VZU+nuj8zzEEtGzeYGGzKdSmj7W9oHm9xK2A1g1kEPmlyK3726T1iT1e9FCxWiaKKjEn3oqR+p3So7EjU94JaA==",
+ "license": "MIT",
+ "dependencies": {
+ "keypress": "~0.2.1",
+ "minimist": "~1.2.5",
+ "picocolors": "~1.1.1",
+ "redstar": "0.0.2",
+ "restore-cursor": "~3.1.0",
+ "string-width": "~2.1.1",
+ "ttys": "0.0.3"
+ },
+ "bin": {
+ "nfzf": "bin/cli.js"
+ }
+ },
+ "node_modules/nth-check": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
+ "integrity": "sha512-lqjrjmaOoAnWfMmBPL+XNnynZh2+swxiX3WUE0s4yEHI6m+AwrK2UZOimIRl3X/4QctVqS8AiZjFqyOGrMXb/w==",
+ "license": "BSD-2-Clause",
+ "dependencies": {
+ "boolbase": "^1.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/nth-check?sponsor=1"
+ }
+ },
+ "node_modules/object-assign": {
+ "version": "4.1.1",
+ "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
+ "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/object-inspect": {
+ "version": "1.13.4",
+ "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.4.tgz",
+ "integrity": "sha512-W67iLl4J2EXEGTbfeHCffrjDfitvLANg0UlX3wFUUSTx92KXRFegMHUVgSqE+wvhAbi4WqjGg9czysTV2Epbew==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/on-finished": {
+ "version": "2.4.1",
+ "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz",
+ "integrity": "sha512-oVlzkg3ENAhCk2zdv7IJwd/QUD4z2RxRwpkcGY8psCVcCYZNq4wYnVWALHM+brtuJjePWiYF/ClmuDr8Ch5+kg==",
+ "license": "MIT",
+ "dependencies": {
+ "ee-first": "1.1.1"
+ },
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/once": {
+ "version": "1.4.0",
+ "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
+ "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==",
+ "license": "ISC",
+ "dependencies": {
+ "wrappy": "1"
+ }
+ },
+ "node_modules/onetime": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
+ "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
+ "license": "MIT",
+ "dependencies": {
+ "mimic-fn": "^2.1.0"
+ },
+ "engines": {
+ "node": ">=6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/sindresorhus"
+ }
+ },
+ "node_modules/parse5": {
+ "version": "7.3.0",
+ "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.3.0.tgz",
+ "integrity": "sha512-IInvU7fabl34qmi9gY8XOVxhYyMyuH2xUNpb2q8/Y+7552KlejkRvqvD19nMoUW/uQGGbqNpA6Tufu5FL5BZgw==",
+ "license": "MIT",
+ "dependencies": {
+ "entities": "^6.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-htmlparser2-tree-adapter": {
+ "version": "7.1.0",
+ "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz",
+ "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==",
+ "license": "MIT",
+ "dependencies": {
+ "domhandler": "^5.0.3",
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5-parser-stream": {
+ "version": "7.1.2",
+ "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz",
+ "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==",
+ "license": "MIT",
+ "dependencies": {
+ "parse5": "^7.0.0"
+ },
+ "funding": {
+ "url": "https://github.com/inikulin/parse5?sponsor=1"
+ }
+ },
+ "node_modules/parse5/node_modules/entities": {
+ "version": "6.0.1",
+ "resolved": "https://registry.npmjs.org/entities/-/entities-6.0.1.tgz",
+ "integrity": "sha512-aN97NXWF6AWBTahfVOIrB/NShkzi5H7F9r1s9mD3cDj4Ko5f2qhhVoYMibXF7GlLveb/D2ioWay8lxI97Ven3g==",
+ "license": "BSD-2-Clause",
+ "engines": {
+ "node": ">=0.12"
+ },
+ "funding": {
+ "url": "https://github.com/fb55/entities?sponsor=1"
+ }
+ },
+ "node_modules/parseurl": {
+ "version": "1.3.3",
+ "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz",
+ "integrity": "sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/path-to-regexp": {
+ "version": "8.3.0",
+ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-8.3.0.tgz",
+ "integrity": "sha512-7jdwVIRtsP8MYpdXSwOS0YdD0Du+qOoF/AEPIt88PcCFrZCzx41oxku1jD88hZBwbNUIEfpqvuhjFaMAqMTWnA==",
+ "license": "MIT",
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/picocolors": {
+ "version": "1.1.1",
+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
+ "license": "ISC"
+ },
+ "node_modules/proxy-addr": {
+ "version": "2.0.7",
+ "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
+ "integrity": "sha512-llQsMLSUDUPT44jdrU/O37qlnifitDP+ZwrmmZcoSKyLKvtZxpyV0n2/bD/N4tBAAZ/gJEdZU7KMraoK1+XYAg==",
+ "license": "MIT",
+ "dependencies": {
+ "forwarded": "0.2.0",
+ "ipaddr.js": "1.9.1"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/qs": {
+ "version": "6.15.0",
+ "resolved": "https://registry.npmjs.org/qs/-/qs-6.15.0.tgz",
+ "integrity": "sha512-mAZTtNCeetKMH+pSjrb76NAM8V9a05I9aBZOHztWy/UqcJdQYNsf59vrRKWnojAT9Y+GbIvoTBC++CPHqpDBhQ==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "side-channel": "^1.1.0"
+ },
+ "engines": {
+ "node": ">=0.6"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/range-parser": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/range-parser/-/range-parser-1.2.1.tgz",
+ "integrity": "sha512-Hrgsx+orqoygnmhFbKaHE6c296J+HTAQXoxEF6gNupROmmGJRoyzfG3ccAveqCBrwr/2yxQ5BVd/GTl5agOwSg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/raw-body": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-3.0.2.tgz",
+ "integrity": "sha512-K5zQjDllxWkf7Z5xJdV0/B0WTNqx6vxG70zJE4N0kBs4LovmEYWJzQGxC9bS9RAKu3bgM40lrd5zoLJ12MQ5BA==",
+ "license": "MIT",
+ "dependencies": {
+ "bytes": "~3.1.2",
+ "http-errors": "~2.0.1",
+ "iconv-lite": "~0.7.0",
+ "unpipe": "~1.0.0"
+ },
+ "engines": {
+ "node": ">= 0.10"
+ }
+ },
+ "node_modules/redstar": {
+ "version": "0.0.2",
+ "resolved": "https://registry.npmjs.org/redstar/-/redstar-0.0.2.tgz",
+ "integrity": "sha512-VNvLaLxMJMYiAasJX5Q/GC+Os7FXL0yPWFDuTodhR7Na9wqzrXsePPWC+EtIv4t3q5DyAK00w423xi5mQN2fqg==",
+ "license": "MIT",
+ "dependencies": {
+ "minimatch": "~3.0.4"
+ }
+ },
+ "node_modules/restore-cursor": {
+ "version": "3.1.0",
+ "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz",
+ "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==",
+ "license": "MIT",
+ "dependencies": {
+ "onetime": "^5.1.0",
+ "signal-exit": "^3.0.2"
+ },
+ "engines": {
+ "node": ">=8"
+ }
+ },
+ "node_modules/router": {
+ "version": "2.2.0",
+ "resolved": "https://registry.npmjs.org/router/-/router-2.2.0.tgz",
+ "integrity": "sha512-nLTrUKm2UyiL7rlhapu/Zl45FwNgkZGaCpZbIHajDYgwlJCOzLSk+cIPAnsEqV955GjILJnKbdQC1nVPz+gAYQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.0",
+ "depd": "^2.0.0",
+ "is-promise": "^4.0.0",
+ "parseurl": "^1.3.3",
+ "path-to-regexp": "^8.0.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ }
+ },
+ "node_modules/safer-buffer": {
+ "version": "2.1.2",
+ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
+ "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
+ "license": "MIT"
+ },
+ "node_modules/sax": {
+ "version": "1.5.0",
+ "resolved": "https://registry.npmjs.org/sax/-/sax-1.5.0.tgz",
+ "integrity": "sha512-21IYA3Q5cQf089Z6tgaUTr7lDAyzoTPx5HRtbhsME8Udispad8dC/+sziTNugOEx54ilvatQ9YCzl4KQLPcRHA==",
+ "license": "BlueOak-1.0.0",
+ "engines": {
+ "node": ">=11.0.0"
+ }
+ },
+ "node_modules/send": {
+ "version": "1.2.1",
+ "resolved": "https://registry.npmjs.org/send/-/send-1.2.1.tgz",
+ "integrity": "sha512-1gnZf7DFcoIcajTjTwjwuDjzuz4PPcY2StKPlsGAQ1+YH20IRVrBaXSWmdjowTJ6u8Rc01PoYOGHXfP1mYcZNQ==",
+ "license": "MIT",
+ "dependencies": {
+ "debug": "^4.4.3",
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "etag": "^1.8.1",
+ "fresh": "^2.0.0",
+ "http-errors": "^2.0.1",
+ "mime-types": "^3.0.2",
+ "ms": "^2.1.3",
+ "on-finished": "^2.4.1",
+ "range-parser": "^1.2.1",
+ "statuses": "^2.0.2"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/serve-static": {
+ "version": "2.2.1",
+ "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-2.2.1.tgz",
+ "integrity": "sha512-xRXBn0pPqQTVQiC8wyQrKs2MOlX24zQ0POGaj0kultvoOCstBQM5yvOhAVSUwOMjQtTvsPWoNCHfPGwaaQJhTw==",
+ "license": "MIT",
+ "dependencies": {
+ "encodeurl": "^2.0.0",
+ "escape-html": "^1.0.3",
+ "parseurl": "^1.3.3",
+ "send": "^1.2.0"
+ },
+ "engines": {
+ "node": ">= 18"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
+ }
+ },
+ "node_modules/setprototypeof": {
+ "version": "1.2.0",
+ "resolved": "https://registry.npmjs.org/setprototypeof/-/setprototypeof-1.2.0.tgz",
+ "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
+ "license": "ISC"
+ },
+ "node_modules/side-channel": {
+ "version": "1.1.0",
+ "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
+ "integrity": "sha512-ZX99e6tRweoUXqR+VBrslhda51Nh5MTQwou5tnUDgbtyM0dBgmhEDtWGP/xbKn6hqfPRHujUNwz5fy/wbbhnpw==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3",
+ "side-channel-list": "^1.0.0",
+ "side-channel-map": "^1.0.1",
+ "side-channel-weakmap": "^1.0.2"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-list": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/side-channel-list/-/side-channel-list-1.0.0.tgz",
+ "integrity": "sha512-FCLHtRD/gnpCiCHEiJLOwdmFP+wzCmDEkc9y7NsYxeF4u7Btsn1ZuwgwJGxImImHicJArLP4R0yX4c2KCrMrTA==",
+ "license": "MIT",
+ "dependencies": {
+ "es-errors": "^1.3.0",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-map": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/side-channel-map/-/side-channel-map-1.0.1.tgz",
+ "integrity": "sha512-VCjCNfgMsby3tTdo02nbjtM/ewra6jPHmpThenkTYh8pG9ucZ/1P8So4u4FGBek/BjpOVsDCMoLA/iuBKIFXRA==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/side-channel-weakmap": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/side-channel-weakmap/-/side-channel-weakmap-1.0.2.tgz",
+ "integrity": "sha512-WPS/HvHQTYnHisLo9McqBHOJk2FkHO/tlpvldyrnem4aeQp4hai3gythswg6p01oSoTl58rcpiFAjF2br2Ak2A==",
+ "license": "MIT",
+ "dependencies": {
+ "call-bound": "^1.0.2",
+ "es-errors": "^1.3.0",
+ "get-intrinsic": "^1.2.5",
+ "object-inspect": "^1.13.3",
+ "side-channel-map": "^1.0.1"
+ },
+ "engines": {
+ "node": ">= 0.4"
+ },
+ "funding": {
+ "url": "https://github.com/sponsors/ljharb"
+ }
+ },
+ "node_modules/signal-exit": {
+ "version": "3.0.7",
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
+ "integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
+ "license": "ISC"
+ },
+ "node_modules/statuses": {
+ "version": "2.0.2",
+ "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.2.tgz",
+ "integrity": "sha512-DvEy55V3DB7uknRo+4iOGT5fP1slR8wQohVdknigZPMpMstaKJQWhwiYBACJE3Ul2pTnATihhBYnRhZQHGBiRw==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/string-width": {
+ "version": "2.1.1",
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
+ "license": "MIT",
+ "dependencies": {
+ "is-fullwidth-code-point": "^2.0.0",
+ "strip-ansi": "^4.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/strip-ansi": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
+ "license": "MIT",
+ "dependencies": {
+ "ansi-regex": "^3.0.0"
+ },
+ "engines": {
+ "node": ">=4"
+ }
+ },
+ "node_modules/tldts": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts/-/tldts-6.1.86.tgz",
+ "integrity": "sha512-WMi/OQ2axVTf/ykqCQgXiIct+mSQDFdH2fkwhPwgEwvJ1kSzZRiinb0zF2Xb8u4+OqPChmyI6MEu4EezNJz+FQ==",
+ "license": "MIT",
+ "dependencies": {
+ "tldts-core": "^6.1.86"
+ },
+ "bin": {
+ "tldts": "bin/cli.js"
+ }
+ },
+ "node_modules/tldts-core": {
+ "version": "6.1.86",
+ "resolved": "https://registry.npmjs.org/tldts-core/-/tldts-core-6.1.86.tgz",
+ "integrity": "sha512-Je6p7pkk+KMzMv2XXKmAE3McmolOQFdxkKw0R8EYNr7sELW46JqnNeTX8ybPiQgvg1ymCoF8LXs5fzFaZvJPTA==",
+ "license": "MIT"
+ },
+ "node_modules/toidentifier": {
+ "version": "1.0.1",
+ "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
+ "integrity": "sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=0.6"
+ }
+ },
+ "node_modules/tough-cookie": {
+ "version": "5.1.2",
+ "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-5.1.2.tgz",
+ "integrity": "sha512-FVDYdxtnj0G6Qm/DhNPSb8Ju59ULcup3tuJxkFb5K8Bv2pUXILbf0xZWU8PX8Ov19OXljbUyveOFwRMwkXzO+A==",
+ "license": "BSD-3-Clause",
+ "dependencies": {
+ "tldts": "^6.1.32"
+ },
+ "engines": {
+ "node": ">=16"
+ }
+ },
+ "node_modules/ttys": {
+ "version": "0.0.3",
+ "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz",
+ "integrity": "sha512-UCqXRZS2S7U4aVB7Salj3ChPRSsb57ogJpJ1eMCvyowxFOBGsaHKcRU8bovcDwajX1mRbv0IpUnYkoG7Ieo5Zg==",
+ "engines": {
+ "node": ">= 0.6.0"
+ }
+ },
+ "node_modules/type-is": {
+ "version": "2.0.1",
+ "resolved": "https://registry.npmjs.org/type-is/-/type-is-2.0.1.tgz",
+ "integrity": "sha512-OZs6gsjF4vMp32qrCbiVSkrFmXtG/AZhY3t0iAMrMBiAZyV9oALtXO8hsrHbMXF9x6L3grlFuwW2oAz7cav+Gw==",
+ "license": "MIT",
+ "dependencies": {
+ "content-type": "^1.0.5",
+ "media-typer": "^1.1.0",
+ "mime-types": "^3.0.0"
+ },
+ "engines": {
+ "node": ">= 0.6"
+ }
+ },
+ "node_modules/undici": {
+ "version": "7.22.0",
+ "resolved": "https://registry.npmjs.org/undici/-/undici-7.22.0.tgz",
+ "integrity": "sha512-RqslV2Us5BrllB+JeiZnK4peryVTndy9Dnqq62S3yYRRTj0tFQCwEniUy2167skdGOy3vqRzEvl1Dm4sV2ReDg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=20.18.1"
+ }
+ },
+ "node_modules/unpipe": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz",
+ "integrity": "sha512-pjy2bYhSsufwWlKwPc+l3cN7+wuJlK6uz0YdJEOlQDbl6jo/YlPi4mb8agUkVC8BF7V8NuzeyPNqRksA3hztKQ==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/vary": {
+ "version": "1.1.2",
+ "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz",
+ "integrity": "sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">= 0.8"
+ }
+ },
+ "node_modules/whatwg-encoding": {
+ "version": "3.1.1",
+ "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
+ "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==",
+ "deprecated": "Use @exodus/bytes instead for a more spec-conformant and faster implementation",
+ "license": "MIT",
+ "dependencies": {
+ "iconv-lite": "0.6.3"
+ },
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/whatwg-encoding/node_modules/iconv-lite": {
+ "version": "0.6.3",
+ "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
+ "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==",
+ "license": "MIT",
+ "dependencies": {
+ "safer-buffer": ">= 2.1.2 < 3.0.0"
+ },
+ "engines": {
+ "node": ">=0.10.0"
+ }
+ },
+ "node_modules/whatwg-mimetype": {
+ "version": "4.0.0",
+ "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz",
+ "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==",
+ "license": "MIT",
+ "engines": {
+ "node": ">=18"
+ }
+ },
+ "node_modules/wrappy": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
+ "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==",
+ "license": "ISC"
+ },
+ "node_modules/yt-search": {
+ "version": "2.13.1",
+ "resolved": "https://registry.npmjs.org/yt-search/-/yt-search-2.13.1.tgz",
+ "integrity": "sha512-iUvUpUYyG1Gk5MxwdxUkSeugXR2DcWX+pEq3rJlsNHHNp4+Lka+fCwNYEdoN5ovxltAzAvx0K3/3MbX7FqDdAw==",
+ "license": "MIT",
+ "dependencies": {
+ "async.parallellimit": "~0.5.2",
+ "boolstring": "~2.0.1",
+ "cheerio": "^1.0.0-rc.10",
+ "dasu": "~0.4.3",
+ "human-time": "0.0.2",
+ "jsonpath-plus": "~10.3.0",
+ "minimist": "~1.2.5",
+ "node-fzf": "~0.14.0"
+ },
+ "bin": {
+ "yt-search": "bin/cli.js",
+ "yt-search-audio": "bin/mpv_audio.sh",
+ "yt-search-video": "bin/mpv_video.sh"
+ }
+ }
+ }
+}
diff --git a/WEB/package.json b/WEB/package.json
new file mode 100644
index 0000000..c0ff68a
--- /dev/null
+++ b/WEB/package.json
@@ -0,0 +1,19 @@
+{
+ "name": "web",
+ "version": "1.0.0",
+ "description": "",
+ "main": "app.js",
+ "scripts": {
+ "test": "echo \"Error: no test specified\" && exit 1"
+ },
+ "keywords": [],
+ "author": "",
+ "license": "ISC",
+ "type": "commonjs",
+ "dependencies": {
+ "@distube/ytdl-core": "^4.16.12",
+ "cors": "^2.8.6",
+ "express": "^5.2.1",
+ "yt-search": "^2.13.1"
+ }
+}
diff --git a/WEB/server.js b/WEB/server.js
new file mode 100644
index 0000000..7a7b669
--- /dev/null
+++ b/WEB/server.js
@@ -0,0 +1,120 @@
+const express = require("express");
+const cors = require("cors");
+const ytdl = require("@distube/ytdl-core");
+const yts = require("yt-search");
+
+const app = express();
+app.use(cors());
+
+// --- ENDPOINTS ---
+
+// Search Endpoint
+app.get("/search", async (req, res) => {
+ try {
+ const query = req.query.q;
+ if (!query) return res.status(400).json({ error: "Missing query parameter" });
+
+ const result = await yts(query);
+ const videos = result.videos.slice(0, 20).map(v => ({
+ id: v.videoId,
+ title: v.title,
+ artist: v.author.name,
+ duration: v.timestamp,
+ durationSec: v.seconds,
+ art: v.thumbnail,
+ hasVideo: true
+ }));
+
+ res.json(videos);
+ } catch (err) {
+ console.error("Search Error:", err);
+ res.status(500).json({ error: "Error searching videos" });
+ }
+});
+
+// Trending Endpoint (yt-search doesn't have a strict trending, so we use a popular search)
+app.get("/trending", async (req, res) => {
+ try {
+ const query = req.query.filter === 'video' ? 'trending viral videos' : 'trending popular music hits official';
+ const result = await yts(query);
+ const videos = result.videos.slice(0, 20).map(v => ({
+ id: v.videoId,
+ title: v.title,
+ artist: v.author.name,
+ duration: v.timestamp,
+ durationSec: v.seconds,
+ art: v.thumbnail,
+ hasVideo: true
+ }));
+
+ res.json(videos);
+ } catch (err) {
+ console.error("Trending Error:", err);
+ res.status(500).json({ error: "Error loading trending" });
+ }
+});
+
+// Audio Stream Endpoint
+app.get("/audio", async (req, res) => {
+ try {
+ const id = req.query.id;
+ if (!id) return res.status(400).send("Invalid Video ID");
+
+ const url = `https://www.youtube.com/watch?v=${id}`;
+
+ if (!ytdl.validateURL(url)) {
+ return res.status(400).send("Invalid YouTube URL");
+ }
+
+ const info = await ytdl.getInfo(url);
+ // Find best audio format
+ const audioFormat = ytdl.chooseFormat(info.formats, { filter: 'audioonly', quality: 'highestaudio' });
+
+ if (!audioFormat) return res.status(404).send("No audio format found");
+
+ res.json({
+ url: audioFormat.url,
+ mimeType: audioFormat.mimeType,
+ title: info.videoDetails.title
+ });
+
+ } catch (err) {
+ console.error("Audio Extractor Error:", err);
+ res.status(500).send("Error extracting audio");
+ }
+});
+
+// Video Stream Endpoint
+app.get("/video", async (req, res) => {
+ try {
+ const id = req.query.id;
+ if (!id) return res.status(400).send("Invalid Video ID");
+
+ const url = `https://www.youtube.com/watch?v=${id}`;
+
+ if (!ytdl.validateURL(url)) {
+ return res.status(400).send("Invalid YouTube URL");
+ }
+
+ const info = await ytdl.getInfo(url);
+ // Find best format that has both video and audio (MP4)
+ const videoFormat = ytdl.chooseFormat(info.formats, { filter: 'audioandvideo', quality: 'highest' });
+
+ if (!videoFormat) return res.status(404).send("No video format found");
+
+ res.json({
+ url: videoFormat.url,
+ mimeType: videoFormat.mimeType,
+ title: info.videoDetails.title
+ });
+
+ } catch (err) {
+ console.error("Video Extractor Error:", err);
+ res.status(500).send("Error extracting video");
+ }
+});
+
+const PORT = process.env.PORT || 3000;
+app.listen(PORT, () => {
+ console.log(`Backend Server running on port ${PORT}`);
+});
diff --git a/WEB/style.css b/WEB/style.css
new file mode 100644
index 0000000..0b826c6
--- /dev/null
+++ b/WEB/style.css
@@ -0,0 +1,716 @@
+:root {
+ /* Bold, Playful Neo-Brutalist Palette */
+ --bg-color: #f7f3eb; /* Paper/cream base */
+ --accent-red: #FF5D73;
+ --accent-blue: #4D9DE0;
+ --accent-yellow: #E1BC29;
+ --accent-green: #3BB273;
+ --accent-purple: #7768AE;
+
+ --text-main: #1C1C1C;
+ --text-muted: #555555;
+
+ --border-dark: #1C1C1C;
+ --border-width: 3px;
+
+ --shadow-offset: 6px;
+ --shadow-color: #1C1C1C;
+
+ /* Typography */
+ --font-display: 'Shrikhand', serif;
+ --font-body: 'DM Sans', sans-serif;
+
+ /* Motion */
+ --spring: cubic-bezier(0.175, 0.885, 0.32, 1.275);
+ --bounce: cubic-bezier(0.34, 1.56, 0.64, 1);
+}
+
+* {
+ box-sizing: border-box;
+ margin: 0;
+ padding: 0;
+}
+
+body {
+ background-color: var(--bg-color);
+ color: var(--text-main);
+ font-family: var(--font-body);
+ min-height: 100vh;
+ overflow-x: hidden;
+ padding: 1.5rem;
+ position: relative;
+ /* Custom playful cursor */
+ cursor: crosshair;
+}
+
+/* Grungy Noise Texture Overlay */
+.noise-overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ pointer-events: none;
+ z-index: 9999;
+ opacity: 0.04;
+ background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 200 200' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noiseFilter'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.65' numOctaves='3' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noiseFilter)'/%3E%3C/svg%3E");
+}
+
+/* Utilities */
+.shadow-brutal {
+ border: var(--border-width) solid var(--border-dark);
+ box-shadow: var(--shadow-offset) var(--shadow-offset) 0 var(--shadow-color);
+ transition: transform 0.2s var(--bounce), box-shadow 0.2s var(--bounce);
+}
+
+.shadow-brutal:hover {
+ transform: translate(calc(var(--shadow-offset) * -0.5), calc(var(--shadow-offset) * -0.5));
+ box-shadow: calc(var(--shadow-offset) * 1.5) calc(var(--shadow-offset) * 1.5) 0 var(--shadow-color);
+}
+
+.shadow-brutal:active {
+ transform: translate(var(--shadow-offset), var(--shadow-offset));
+ box-shadow: 0 0 0 var(--shadow-color);
+}
+
+.hidden {
+ display: none !important;
+}
+
+/* Header */
+.top-nav {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ margin-bottom: 3rem;
+ position: sticky;
+ top: 1.5rem;
+ z-index: 100;
+}
+
+.logo-container {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+ transform: rotate(-2deg);
+}
+
+.logo-shape {
+ width: 48px;
+ height: 48px;
+ background-color: var(--accent-yellow);
+ border: var(--border-width) solid var(--border-dark);
+ /* Flower/Star shape */
+ clip-path: polygon(50% 0%, 61% 35%, 98% 35%, 68% 57%, 79% 91%, 50% 70%, 21% 91%, 32% 57%, 2% 35%, 39% 35%);
+ animation: spin 10s linear infinite;
+}
+
+@keyframes spin {
+ 100% { transform: rotate(360deg); }
+}
+
+.logo-text {
+ font-family: var(--font-display);
+ font-size: 1.8rem;
+ line-height: 0.9;
+ text-transform: uppercase;
+ letter-spacing: -1px;
+ color: var(--accent-red);
+ text-shadow: 2px 2px 0 var(--border-dark);
+}
+
+.nav-pills {
+ display: flex;
+ gap: 1rem;
+ background: white;
+ padding: 0.5rem;
+ border: var(--border-width) solid var(--border-dark);
+ border-radius: 50px;
+ box-shadow: 4px 4px 0 var(--border-dark);
+}
+
+.pill {
+ background: none;
+ border: 2px solid transparent;
+ padding: 0.5rem 1.5rem;
+ font-family: var(--font-body);
+ font-weight: 800;
+ font-size: 1rem;
+ border-radius: 40px;
+ cursor: pointer;
+ transition: all 0.3s var(--spring);
+}
+
+.pill:hover {
+ transform: translateY(-2px);
+}
+
+.pill.active {
+ background-color: var(--accent-blue);
+ color: white;
+ border-color: var(--border-dark);
+}
+
+.user-avatar {
+ width: 60px;
+ height: 60px;
+ background-color: var(--accent-purple);
+ border-radius: 50%;
+ border: var(--border-width) solid var(--border-dark);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ box-shadow: 4px 4px 0 var(--border-dark);
+ cursor: pointer;
+ transition: transform 0.3s var(--spring);
+}
+
+.user-avatar:hover {
+ transform: scale(1.1) rotate(10deg);
+}
+
+.avatar-face {
+ font-family: monospace;
+ font-size: 1.2rem;
+ font-weight: bold;
+ color: white;
+}
+
+/* Main Grid */
+.content-grid {
+ display: grid;
+ grid-template-columns: 1fr 1fr;
+ gap: 2rem;
+ max-width: 1200px;
+ margin: 0 auto;
+ padding-bottom: 120px; /* Space for dock */
+}
+
+/* Hero Section */
+.hero-card {
+ background-color: var(--accent-blue);
+ border-radius: 24px;
+ padding: 2.5rem;
+ position: relative;
+ overflow: hidden;
+ display: flex;
+ flex-direction: column;
+ justify-content: center;
+ min-height: 400px;
+}
+
+.hero-badge {
+ position: absolute;
+ top: 2rem;
+ left: 2rem;
+ background: var(--accent-yellow);
+ color: var(--border-dark);
+ font-weight: 900;
+ padding: 0.5rem 1rem;
+ border: 2px solid var(--border-dark);
+ border-radius: 50px;
+ font-size: 0.8rem;
+ letter-spacing: 1px;
+ transform: rotate(-5deg);
+}
+
+.hero-title {
+ font-family: var(--font-display);
+ font-size: 4.5rem;
+ line-height: 0.9;
+ color: white;
+ text-shadow: 4px 4px 0 var(--border-dark);
+ z-index: 2;
+ position: relative;
+ margin-top: 2rem;
+}
+
+.hero-art {
+ position: absolute;
+ right: -4rem;
+ bottom: -4rem;
+ width: 300px;
+ height: 300px;
+ z-index: 1;
+}
+
+.vinyl-record {
+ width: 100%;
+ height: 100%;
+ background-color: #111;
+ border-radius: 50%;
+ border: 10px solid #333;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ animation: spin 4s linear infinite;
+ box-shadow: inset 0 0 0 4px #222, inset 0 0 0 12px #111, inset 0 0 0 16px #222, inset 0 0 0 24px #111, inset 0 0 0 28px #222;
+}
+
+.vinyl-center {
+ width: 100px;
+ height: 100px;
+ background-color: var(--accent-red);
+ border-radius: 50%;
+ border: 4px solid var(--border-dark);
+ position: relative;
+}
+
+.vinyl-center::after {
+ content: '';
+ position: absolute;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 12px;
+ height: 12px;
+ background-color: var(--bg-color);
+ border-radius: 50%;
+ border: 2px solid var(--border-dark);
+}
+
+.btn-play-massive {
+ position: absolute;
+ bottom: 2rem;
+ left: 2rem;
+ width: 80px;
+ height: 80px;
+ background-color: var(--accent-yellow);
+ border-radius: 50%;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+ z-index: 3;
+}
+
+.btn-play-massive svg {
+ width: 40px;
+ height: 40px;
+ color: var(--border-dark);
+ margin-left: 6px;
+}
+
+/* Track List */
+.track-list {
+ display: flex;
+ flex-direction: column;
+ gap: 1rem;
+}
+
+.track-item {
+ display: flex;
+ align-items: center;
+ background: white;
+ padding: 1rem;
+ border-radius: 16px;
+ gap: 1.5rem;
+ cursor: pointer;
+ position: relative;
+ overflow: hidden;
+}
+
+.track-item::before {
+ content: '';
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 0;
+ height: 100%;
+ background-color: var(--accent-yellow);
+ z-index: 0;
+ transition: width 0.3s var(--spring);
+}
+
+.track-item:hover::before {
+ width: 100%;
+}
+
+.track-item.playing::before {
+ width: 100%;
+ background-color: var(--accent-green);
+}
+
+.track-number {
+ font-family: var(--font-display);
+ font-size: 2rem;
+ color: var(--border-dark);
+ opacity: 0.3;
+ width: 40px;
+ z-index: 1;
+}
+
+.track-art {
+ width: 64px;
+ height: 64px;
+ border-radius: 8px;
+ border: 2px solid var(--border-dark);
+ background-size: cover;
+ background-position: center;
+ z-index: 1;
+}
+
+.track-info {
+ flex-grow: 1;
+ z-index: 1;
+}
+
+.track-title {
+ font-weight: 800;
+ font-size: 1.2rem;
+ margin-bottom: 0.2rem;
+ color: var(--border-dark);
+}
+
+.track-artist {
+ font-size: 0.9rem;
+ color: var(--text-muted);
+ font-weight: 500;
+}
+
+.track-item:hover .track-title,
+.track-item.playing .track-title {
+ color: var(--border-dark);
+}
+
+.track-duration {
+ font-weight: bold;
+ font-family: monospace;
+ font-size: 1.1rem;
+ z-index: 1;
+}
+
+/* Visualizer Bars */
+.playing-bars {
+ display: flex;
+ gap: 3px;
+ height: 24px;
+ align-items: flex-end;
+ z-index: 1;
+ display: none;
+}
+
+.track-item.playing .playing-bars {
+ display: flex;
+}
+
+.track-item.playing .track-duration {
+ display: none;
+}
+
+.bar {
+ width: 5px;
+ background-color: var(--border-dark);
+ border-radius: 2px 2px 0 0;
+ animation: bounce 1s infinite alternate ease-in-out;
+}
+
+.bar:nth-child(1) { animation-delay: 0s; height: 10px; }
+.bar:nth-child(2) { animation-delay: 0.2s; height: 20px; }
+.bar:nth-child(3) { animation-delay: 0.4s; height: 15px; }
+
+@keyframes bounce {
+ 0% { height: 5px; }
+ 100% { height: 24px; }
+}
+
+/* Player Dock - Floating, toy-like */
+.player-dock {
+ position: fixed;
+ bottom: 2rem;
+ left: 50%;
+ transform: translateX(-50%);
+ width: 90%;
+ max-width: 900px;
+ background-color: white;
+ border-radius: 30px;
+ padding: 1.2rem 2rem;
+ display: grid;
+ grid-template-columns: 2fr 1fr 2fr;
+ align-items: center;
+ gap: 2rem;
+ z-index: 1000;
+ animation: slideUp 0.5s var(--spring) forwards;
+}
+
+@keyframes slideUp {
+ from { bottom: -150px; transform: translate(-50%, 0) rotate(5deg); }
+ to { bottom: 2rem; transform: translate(-50%, 0) rotate(0deg); }
+}
+
+.player-info {
+ display: flex;
+ align-items: center;
+ gap: 1.5rem;
+ overflow: hidden;
+}
+
+.now-playing-art {
+ width: 70px;
+ height: 70px;
+ border-radius: 12px;
+ background-color: var(--accent-purple);
+ flex-shrink: 0;
+ background-size: cover;
+ background-position: center;
+}
+
+.now-playing-text {
+ flex-grow: 1;
+ overflow: hidden;
+}
+
+.scrolling-text-container {
+ width: 100%;
+ white-space: nowrap;
+ overflow: hidden;
+ position: relative;
+}
+
+#dockTitle {
+ font-family: var(--font-display);
+ font-size: 1.5rem;
+ color: var(--border-dark);
+ display: inline-block;
+ /* Marquee effect if text is long, handled in JS */
+}
+
+#dockArtist {
+ font-weight: bold;
+ color: var(--text-muted);
+}
+
+.player-controls {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+}
+
+.ctrl-btn {
+ width: 48px;
+ height: 48px;
+ border-radius: 50%;
+ background-color: var(--bg-color);
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ cursor: pointer;
+}
+
+.ctrl-btn svg {
+ width: 24px;
+ height: 24px;
+}
+
+.play-pause {
+ width: 64px;
+ height: 64px;
+ background-color: var(--accent-red);
+}
+
+.play-pause svg {
+ width: 32px;
+ height: 32px;
+ color: white;
+}
+
+.play-pause svg#iconPlay { margin-left: 4px; }
+
+.progress-container {
+ display: flex;
+ align-items: center;
+ gap: 1rem;
+}
+
+.time {
+ font-family: monospace;
+ font-weight: bold;
+ font-size: 1rem;
+}
+
+.progress-bar {
+ flex-grow: 1;
+ height: 24px;
+ background-color: var(--bg-color);
+ border-radius: 12px;
+ position: relative;
+ cursor: pointer;
+}
+
+.progress-fill {
+ height: 100%;
+ background-color: var(--accent-blue);
+ width: 0%;
+ border-radius: 9px;
+ border-right: 2px solid var(--border-dark);
+ transition: width 0.1s linear;
+}
+
+.progress-handle {
+ width: 30px;
+ height: 30px;
+ background-color: var(--accent-yellow);
+ border-radius: 50%;
+ position: absolute;
+ top: -3px;
+ left: 0%;
+ transform: translateX(-50%);
+ pointer-events: none;
+ transition: left 0.1s linear;
+}
+
+/* Responsive */
+@media (max-width: 900px) {
+ .content-grid {
+ grid-template-columns: 1fr;
+ }
+
+ .player-dock {
+ grid-template-columns: 1fr;
+ padding: 1.5rem;
+ border-radius: 20px;
+ }
+
+ .player-info {
+ justify-content: center;
+ text-align: center;
+ }
+
+ .now-playing-art {
+ display: none;
+ }
+}
+
+/* Additional Styles for New Features */
+.search-container {
+ display: flex;
+ background: white;
+ border-radius: 40px;
+ padding: 0.5rem;
+ flex-grow: 0.4;
+ min-width: 300px;
+}
+
+.search-input {
+ border: none;
+ outline: none;
+ font-family: var(--font-body);
+ font-weight: 600;
+ font-size: 1.1rem;
+ padding: 0 1rem;
+ flex-grow: 1;
+ background: transparent;
+}
+
+.search-btn {
+ background: var(--accent-yellow);
+ border: 2px solid var(--border-dark);
+ border-radius: 50%;
+ width: 40px;
+ height: 40px;
+ cursor: pointer;
+ font-size: 1.2rem;
+ transition: transform 0.2s var(--bounce);
+}
+
+.search-btn:hover {
+ transform: scale(1.1) rotate(15deg);
+}
+
+/* Loader */
+.loader-container {
+ display: flex;
+ justify-content: center;
+ align-items: center;
+ gap: 1rem;
+ padding: 3rem;
+ width: 100%;
+}
+
+.bouncy-loader {
+ width: 24px;
+ height: 24px;
+ border-radius: 50%;
+ border: var(--border-width) solid var(--border-dark);
+ animation: loaderBounce 0.6s infinite alternate var(--spring);
+}
+
+.bouncy-loader:nth-child(1) { background-color: var(--accent-red); animation-delay: 0s; }
+.bouncy-loader:nth-child(2) { background-color: var(--accent-blue); animation-delay: 0.2s; }
+.bouncy-loader:nth-child(3) { background-color: var(--accent-yellow); animation-delay: 0.4s; }
+
+@keyframes loaderBounce {
+ from { transform: translateY(0); }
+ to { transform: translateY(-20px); }
+}
+
+/* Video Player */
+.video-container {
+ position: fixed;
+ top: 50%;
+ left: 50%;
+ transform: translate(-50%, -50%);
+ width: 80%;
+ max-width: 1000px;
+ z-index: 2000;
+ background: var(--bg-color);
+ padding: 1rem;
+ border-radius: 16px;
+ border: var(--border-width) solid var(--border-dark);
+ box-shadow: 10px 10px 0 var(--shadow-color);
+}
+
+.video-container video {
+ width: 100%;
+ border-radius: 8px;
+ outline: none;
+}
+
+.close-btn {
+ position: absolute;
+ top: -20px;
+ right: -20px;
+ background: var(--accent-red);
+ color: white;
+ font-weight: 900;
+ font-family: var(--font-body);
+ padding: 0.5rem 1rem;
+ border-radius: 40px;
+ cursor: pointer;
+}
+
+/* Overlays & Modals */
+.overlay {
+ position: fixed;
+ top: 0;
+ left: 0;
+ width: 100%;
+ height: 100%;
+ background: rgba(0,0,0,0.5);
+ z-index: 1500;
+ backdrop-filter: blur(5px);
+}
+
+/* Fixes for YouTube IFrame Integration */
+#ytplayer {
+ display: block;
+ width: 100%;
+ aspect-ratio: 16/9;
+ border: none;
+ border-radius: 8px;
+ background-color: var(--border-dark);
+}
+
+.video-container {
+ background-color: var(--accent-yellow); /* Bold brutalist color for video backing */
+ border: var(--border-width) solid var(--border-dark);
+ box-shadow: 12px 12px 0 var(--border-dark);
+}
+
+.close-btn {
+ top: -20px;
+ right: -20px;
+ border: var(--border-width) solid var(--border-dark);
+ z-index: 2500;
+}