fullpwerr commited on
Commit
d145b59
·
1 Parent(s): afc104e
Files changed (27) hide show
  1. .gitattributes +1 -0
  2. app.js +11 -9
  3. fnc/ai.js +63 -0
  4. fnc/apis.js +165 -0
  5. fnc/checktype.js +24 -0
  6. fnc/download.js +31 -0
  7. fnc/test.js +165 -0
  8. fnc/validate.js +26 -0
  9. lib/cookies/gtc.json +1 -0
  10. lib/cookies/qq.txt +10 -0
  11. lib/cookies/twt.txt +14 -0
  12. lib/cookies/yt.txt +26 -0
  13. lib/fb.js +89 -0
  14. lib/ig.js +70 -0
  15. lib/kuaishou.js +110 -0
  16. lib/pix.js +88 -0
  17. lib/pradigm.js +114 -0
  18. lib/qqm.js +114 -0
  19. lib/qqmusic.js +59 -0
  20. lib/skrep.js +160 -0
  21. lib/snapchat.js +48 -0
  22. lib/soundcloud.js +147 -0
  23. lib/spotify.js +171 -0
  24. lib/twt.js +54 -0
  25. lib/ytdl.js +130 -0
  26. package-lock.json +1390 -6
  27. package.json +8 -2
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ node_modules
app.js CHANGED
@@ -1,8 +1,13 @@
1
  const express = require("express");
2
  const cors = require("cors");
 
 
3
  require("dotenv").config();
4
  const bodyParser = require("body-parser");
5
 
 
 
 
6
  const app = express();
7
  const port = process.env.PORT || 7860;
8
 
@@ -20,17 +25,14 @@ app.use(bodyParser.urlencoded({
20
  extended: true
21
  }));
22
 
 
 
 
23
  app.get("/", (req, res) => {
24
- res.send(`
25
- <html>
26
- <head>
27
- <meta http-equiv="refresh" content="3;url=https://app.wzblueline.xyz" />
28
- </head>
29
- <body>
30
- </body>
31
- </html>
32
- `)
33
  });
 
 
34
 
35
  let server
36
  app.listen(port, () => {
 
1
  const express = require("express");
2
  const cors = require("cors");
3
+ const path = require("path");
4
+ const fs = require("fs");
5
  require("dotenv").config();
6
  const bodyParser = require("body-parser");
7
 
8
+ const apis = require("./fnc/apis");
9
+ const downloadf = require("./fnc/download");
10
+
11
  const app = express();
12
  const port = process.env.PORT || 7860;
13
 
 
25
  extended: true
26
  }));
27
 
28
+ app.use("/cdn", express.static(path.join(__dirname, "cdn")));
29
+ app.use("/tmp", express.static(path.join(__dirname, "tmp")));
30
+
31
  app.get("/", (req, res) => {
32
+ res.send({ error: "NIGGA"})
 
 
 
 
 
 
 
 
33
  });
34
+ app.post("/api", apis);
35
+ app.get("/download", downloadf);
36
 
37
  let server
38
  app.listen(port, () => {
fnc/ai.js ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { enhance } = require("../lib/pradigm");
2
+ const drawever = require("../lib/pix"); // Import dari pix.js
3
+ const fs = require("fs");
4
+ const path = require("path");
5
+ const { v4: uuidv4 } = require("uuid");
6
+
7
+ async function checkCaptcha(response) {
8
+ const url = new URL("https://www.google.com/recaptcha/api/siteverify");
9
+ url.searchParams.set("secret", "6Le0_-YqAAAAAPFjisvdA9ruGjWr_V0wv9j1OP-d");
10
+ url.searchParams.set("response", response);
11
+
12
+ const res = await fetch(url, {
13
+ method: "POST"
14
+ });
15
+ /** @type {{ success: boolean, challenge_ts: string, hostname: string, score: number, action: string, "error-codes": ("missing-input-secret"|"invalid-input-secret"|"missing-input-response"|"invalid-input-response"|"bad-request"|"timeout-or-duplicate")[] }} */
16
+ const data = await res.json();
17
+ return data;
18
+ }
19
+
20
+ module.exports = async function (req, res) {
21
+ try {
22
+ const { buffer, type, style = "anime", quality = "medium" } = req.body;
23
+ //const ip = req._ip;
24
+ /** @type {string} */
25
+ const authHeader = req.headers.authorization;
26
+
27
+ if(!authHeader || !authHeader.startsWith("Bearer ")) {
28
+ return res.status(401).json({
29
+ message: "Unauthorized: Token is missing or invalid"
30
+ });
31
+ }
32
+
33
+ if (!buffer) return res.status(400).json({ error: "Buffer diperlukan." });
34
+
35
+ if (type === "hd") {
36
+ const imgBuffer = Buffer.from(buffer);
37
+ const enhancedImage = await enhance(imgBuffer);
38
+ if (!enhancedImage) throw new Error("Gagal memproses gambar.");
39
+
40
+ res.setHeader("Content-Type", "image/png");
41
+ return res.send(enhancedImage);
42
+ }
43
+ if (type === "effect") {
44
+ // Simpan buffer ke file sementara
45
+ const fileName = `${uuidv4()}.png`;
46
+ const filePath = path.join(__dirname, "../cdn", fileName);
47
+ await fs.writeFileSync(filePath, Buffer.from(buffer));
48
+
49
+ // Proses gambar dengan pix.js
50
+ const imageUrl = `https://beta.wzblueline.xyz/cdn/${fileName}`;
51
+
52
+ const quality = "medium";
53
+
54
+ await drawever.create(imageUrl, style, quality);
55
+
56
+ return res.json({ url: imageUrl });
57
+ }
58
+
59
+ } catch (error) {
60
+ console.error(error);
61
+ res.status(500).json({ error: "Terjadi kesalahan saat memproses gambar." });
62
+ }
63
+ };
fnc/apis.js ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const {
2
+ fileTypeFromBuffer
3
+ } = require("file-type");
4
+ const twit = require("../lib/twt")
5
+ const {
6
+ ttt
7
+ } = require("../lib/skrep");
8
+ const {
9
+ soundcloud
10
+ } = require("../lib/soundcloud");
11
+ const ig = require("../lib/ig");
12
+ const {
13
+ spotifyTrack,
14
+ spotifyPlaylist
15
+ } = require("../lib/spotify");
16
+ const yt = require("../lib/ytdl");
17
+ const kwaii = require("../lib/kuaishou");
18
+ const qq = require("../lib/qqm");
19
+ const fesnuk = require("../lib/fb");
20
+
21
+ const IGr = /^(https?:\/\/)?(www\.)?instagram\.com\/.*$/i;
22
+ const SCr = /^(https?:\/\/)?(www\.|m\.)?(on\.|)soundcloud\.com\/[^\s]+$/i;
23
+ const TTr = /https?:\/\/(www\.|v(t|m)\.|t\.)?tiktok\.com/i;
24
+ const Sr = /https?:\/\/open\.spotify\.com\/track\/([a-zA-Z0-9]+)(\?.*)?/i;
25
+ const Ser = /https?:\/\/open\.spotify\.com\/playlist\/([a-zA-Z0-9]+)(\?.*)?/i;
26
+ const YTr = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?(?:music\.)?youtube(?:-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/i;
27
+ const Kr = /^https?:\/\/v\.kuaishou\.com\/[a-zA-Z0-9]+$/i;
28
+ const QQMr = /^https:\/\/c6\.y\.qq\.com\/base\/fcgi-bin\/u\?__=[a-zA-Z0-9]+$/;
29
+ const TwTr = /^https?:\/\/(www\.)?(twitter|x)\.com\/[^\/]+\/status\/\d+\/?$/i;
30
+ // Daftar domain yang diperbolehkan untuk Facebook
31
+ const allowX = [
32
+ "x.com",
33
+ "www.x.com",
34
+ "twitter.com",
35
+ "www.twitter.com"
36
+ ]
37
+ const allowedFacebookHosts = [
38
+ "facebook.com",
39
+ "www.facebook.com",
40
+ "m.facebook.com",
41
+ "fb.com"
42
+ ];
43
+
44
+ /**
45
+ * @param {string} response
46
+ * @returns {Promise<{ success: boolean, challenge_ts: string, hostname: string, score: number, action: string, "error-codes": ("missing-input-secret"|"invalid-input-secret"|"missing-input-response"|"invalid-input-response"|"bad-request"|"timeout-or-duplicate")[] }>}
47
+ */
48
+ async function checkCaptcha(response) {
49
+ const url = new URL("https://www.google.com/recaptcha/api/siteverify");
50
+ url.searchParams.set("secret", "6Ldr6_cqAAAAAApmQtOImEUOVLq8cAIFUZuuRSrM");
51
+ url.searchParams.set("response", response);
52
+
53
+ const res = await fetch(url, {
54
+ method: "POST"
55
+ });
56
+
57
+ return await res.json();
58
+ }
59
+
60
+ /** @type {Map<string, any>} */
61
+ const yt_info = new Map();
62
+ module.exports = async function(req, res) {
63
+ const {
64
+ url
65
+ } = req.body;
66
+ //const ip = req._ip;
67
+ if(!url) {
68
+ return res.status(400).json({
69
+ error: "URL diperlukan."
70
+ });
71
+ }
72
+
73
+ let parsedUrl;
74
+ try {
75
+ parsedUrl = new URL(url);
76
+ } catch (error) {
77
+ return res.status(400).json({ error: "URL tidak valid." });
78
+ }
79
+
80
+ const authHeader = req.headers.authorization;
81
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
82
+ return res.status(401).json({ message: "Unauthorized: Token is missing or invalid" });
83
+ }
84
+
85
+ const token = authHeader.split(" ")[1];
86
+ const { success: isValid, "error-codes": errors } = await checkCaptcha(token);
87
+
88
+ if (!isValid) {
89
+ return res.status(400).send({ message: "Invalid captcha", errors });
90
+ }
91
+
92
+ console.log(parsedUrl);
93
+ let ress;
94
+ try {
95
+ if(IGr.test(url)) {
96
+ ress = await ig(url);
97
+ ress.type = "instagram";
98
+ } else if(SCr.test(url)) {
99
+ ress = await soundcloud(url);
100
+ ress.type = "soundcloud";
101
+ } else if(Ser.test(url)) {
102
+ ress = await spotifyPlaylist(url);
103
+ ress.type = "spotifyPlaylist";
104
+ } else if(TTr.test(url)) {
105
+ ress = await ttt(url);
106
+ ress.type = "tiktok";
107
+ } else if(Sr.test(url)) {
108
+ ress = await spotifyTrack(url);
109
+ ress.type = "spotify";
110
+ } else if(QQMr.test(url)) {
111
+ ress = await qq(url);
112
+ ress.type = "qq";
113
+ } else if(allowedFacebookHosts.includes(parsedUrl.hostname)) {
114
+ ress = await fesnuk(url);
115
+ ress.type = "facebook"
116
+ } else if(allowX.includes(parsedUrl.hostname)) {
117
+ ress = await twit(url);
118
+ ress.type = "twitter"
119
+ } else if(YTr.test(url)) {
120
+ const format = String(
121
+ req.headers["x-selected-format"] ||
122
+ ""
123
+ ).trim();
124
+ const [, id] = YTr.exec(url);
125
+
126
+ if(!format) {
127
+ ress = (
128
+ yt_info.has(id)
129
+ ? yt_info.get(id)
130
+ : await yt.getInfo(url)
131
+ );
132
+ yt_info.set(id, ress);
133
+ ress.type = "yt_info";
134
+ } else {
135
+ const type = (
136
+ format === "audio"
137
+ ? "Audio"
138
+ : "Video"
139
+ );
140
+ ress = await yt[`get${type}`](url, format);
141
+ }
142
+ } else if(Kr.test(url)) {
143
+ ress = await kwaii(url);
144
+ ress.type = "kwaii";
145
+ } else {
146
+ ress = {
147
+ status: 400,
148
+ message: "failed request"
149
+ };
150
+ }
151
+ } catch (e) {
152
+ console.log(e);
153
+ ress = {
154
+ status: 404,
155
+ message: e.message
156
+ };
157
+ }
158
+
159
+ if(Buffer.isBuffer(ress)) {
160
+ const { mime } = await fileTypeFromBuffer(ress);
161
+ res.setHeader("Content-Type", mime);
162
+ res.setHeader("Content-Length", ress.length);
163
+ }
164
+ return res.status(ress.status || 200).send(ress.data || ress);
165
+ };
fnc/checktype.js ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fetch = require("node-fetch").default;
2
+ const axios = require("axios");
3
+
4
+ module.exports = async function(req, res) {
5
+ try {
6
+ const { url } = req.query;
7
+ if (!url) return res.status(400).json({ success: false, message: "URL tidak valid" });
8
+ const fileResponse = await axios.head(url, {
9
+ headers: { "User-Agent": "Mozilla/5.0" }
10
+ });
11
+
12
+ const contentType = fileResponse.headers["content-type"];
13
+ let fileExtension = "";
14
+
15
+ if (contentType === "video/mp4") fileExtension = ".mp4";
16
+ else if (contentType === "audio/mpeg") fileExtension = ".mp3";
17
+ else if (contentType?.startsWith("image")) fileExtension = ".jpg";
18
+
19
+ res.json({ success: true, extension: fileExtension });
20
+ } catch (error) {
21
+ console.error(error);
22
+ res.status(500).json({ success: false, message: "Gagal mendapatkan informasi file" });
23
+ }
24
+ }
fnc/download.js ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const fetch = require("node-fetch").default;
2
+ const axios = require("axios");
3
+
4
+ module.exports = async function(req, res, next) {
5
+ try {
6
+ const {
7
+ url,
8
+ name
9
+ } = req.query;
10
+ if(!url || !name) return next();
11
+
12
+ const _res = await fetch(url, {
13
+ headers: {
14
+ "Referer": url,
15
+ "Access-Control-Allow-Origin": "*",
16
+ "Referrer-Policy": "strict-origin-when-cross-origin",
17
+ "User-Agent": req.get("User-Agent"),
18
+ ...(req.headers.range ? {
19
+ Range: req.headers.range
20
+ } : {})
21
+ }
22
+ });
23
+ for(const [key, value] of _res.headers.entries()) res.setHeader(key, value);
24
+ res.setHeader("Transfer-Encoding", "chunked");
25
+ res.setHeader("Content-Disposition", `attachment; filename*=UTF-8''${encodeURIComponent(name)}`);
26
+ _res.body.pipe(res.status(_res.status));
27
+ } catch(e) {
28
+ console.error(e)
29
+ next();
30
+ };
31
+ }
fnc/test.js ADDED
@@ -0,0 +1,165 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const {
2
+ fileTypeFromBuffer
3
+ } = require("file-type");
4
+ const twit = require("../lib/twt")
5
+ const {
6
+ ttt
7
+ } = require("../lib/skrep");
8
+ const {
9
+ soundcloud
10
+ } = require("../lib/soundcloud");
11
+ const ig = require("../lib/ig");
12
+ const {
13
+ spotifyTrack,
14
+ spotifyPlaylist
15
+ } = require("../lib/spotify");
16
+ const yt = require("../lib/ytdl");
17
+ const kwaii = require("../lib/kuaishou");
18
+ const qq = require("../lib/qqm");
19
+ const fesnuk = require("../lib/fb");
20
+
21
+ const IGr = /^(https?:\/\/)?(www\.)?instagram\.com\/.*$/i;
22
+ const SCr = /^(https?:\/\/)?(www\.|m\.)?(on\.|)soundcloud\.com\/[^\s]+$/i;
23
+ const TTr = /https?:\/\/(www\.|v(t|m)\.|t\.)?tiktok\.com/i;
24
+ const Sr = /https?:\/\/open\.spotify\.com\/track\/([a-zA-Z0-9]+)(\?.*)?/i;
25
+ const Ser = /https?:\/\/open\.spotify\.com\/playlist\/([a-zA-Z0-9]+)(\?.*)?/i;
26
+ const YTr = /(?:http(?:s|):\/\/|)(?:(?:www\.|)?(?:music\.)?youtube(?:-nocookie|)\.com\/(?:shorts\/)?(?:watch\?.*(?:|&)v=|embed\/|v\/)?|youtu\.be\/)([-_0-9A-Za-z]{11})/i;
27
+ const Kr = /^https?:\/\/v\.kuaishou\.com\/[a-zA-Z0-9]+$/i;
28
+ const QQMr = /^https:\/\/c6\.y\.qq\.com\/base\/fcgi-bin\/u\?__=[a-zA-Z0-9]+$/;
29
+ const TwTr = /^https?:\/\/(www\.)?(twitter|x)\.com\/[^\/]+\/status\/\d+\/?$/i;
30
+ // Daftar domain yang diperbolehkan untuk Facebook
31
+ const allowX = [
32
+ "x.com",
33
+ "www.x.com",
34
+ "twitter.com",
35
+ "www.twitter.com"
36
+ ]
37
+ const allowedFacebookHosts = [
38
+ "facebook.com",
39
+ "www.facebook.com",
40
+ "m.facebook.com",
41
+ "fb.com"
42
+ ];
43
+
44
+ /**
45
+ * @param {string} response
46
+ * @returns {Promise<{ success: boolean, challenge_ts: string, hostname: string, score: number, action: string, "error-codes": ("missing-input-secret"|"invalid-input-secret"|"missing-input-response"|"invalid-input-response"|"bad-request"|"timeout-or-duplicate")[] }>}
47
+ */
48
+ async function checkCaptcha(response) {
49
+ const url = new URL("https://www.google.com/recaptcha/api/siteverify");
50
+ url.searchParams.set("secret", "6Ldr6_cqAAAAAApmQtOImEUOVLq8cAIFUZuuRSrM");
51
+ url.searchParams.set("response", response);
52
+
53
+ const res = await fetch(url, {
54
+ method: "POST"
55
+ });
56
+
57
+ return await res.json();
58
+ }
59
+
60
+ /** @type {Map<string, any>} */
61
+ const yt_info = new Map();
62
+ module.exports = async function(req, res) {
63
+ const {
64
+ url
65
+ } = req.body;
66
+ //const ip = req._ip;
67
+ if(!url) {
68
+ return res.status(400).json({
69
+ error: "URL diperlukan."
70
+ });
71
+ }
72
+
73
+ let parsedUrl;
74
+ try {
75
+ parsedUrl = new URL(url);
76
+ } catch (error) {
77
+ return res.status(400).json({ error: "URL tidak valid." });
78
+ }
79
+
80
+ /*const authHeader = req.headers.authorization;
81
+ if (!authHeader || !authHeader.startsWith("Bearer ")) {
82
+ return res.status(401).json({ message: "Unauthorized: Token is missing or invalid" });
83
+ }
84
+
85
+ const token = authHeader.split(" ")[1];
86
+ const { success: isValid, "error-codes": errors } = await checkCaptcha(token);
87
+
88
+ if (!isValid) {
89
+ return res.status(400).send({ message: "Invalid captcha", errors });
90
+ }*/
91
+
92
+ console.log(parsedUrl);
93
+ let ress;
94
+ try {
95
+ if(IGr.test(url)) {
96
+ ress = await ig(url);
97
+ ress.type = "instagram";
98
+ } else if(SCr.test(url)) {
99
+ ress = await soundcloud(url);
100
+ ress.type = "soundcloud";
101
+ } else if(Ser.test(url)) {
102
+ ress = await spotifyPlaylist(url);
103
+ ress.type = "spotifyPlaylist";
104
+ } else if(TTr.test(url)) {
105
+ ress = await ttt(url);
106
+ ress.type = "tiktok";
107
+ } else if(Sr.test(url)) {
108
+ ress = await spotifyTrack(url);
109
+ ress.type = "spotify";
110
+ } else if(QQMr.test(url)) {
111
+ ress = await qq(url);
112
+ ress.type = "qq";
113
+ } else if(allowedFacebookHosts.includes(parsedUrl.hostname)) {
114
+ ress = await fesnuk(url);
115
+ ress.type = "facebook"
116
+ } else if(allowX.includes(parsedUrl.hostname)) {
117
+ ress = await twit(url);
118
+ ress.type = "twitter"
119
+ } else if(YTr.test(url)) {
120
+ const format = String(
121
+ req.headers["x-selected-format"] ||
122
+ ""
123
+ ).trim();
124
+ const [, id] = YTr.exec(url);
125
+
126
+ if(!format) {
127
+ ress = (
128
+ yt_info.has(id)
129
+ ? yt_info.get(id)
130
+ : await yt.getInfo(url)
131
+ );
132
+ yt_info.set(id, ress);
133
+ ress.type = "yt_info";
134
+ } else {
135
+ const type = (
136
+ format === "audio"
137
+ ? "Audio"
138
+ : "Video"
139
+ );
140
+ ress = await yt[`get${type}`](url, format);
141
+ }
142
+ } else if(Kr.test(url)) {
143
+ ress = await kwaii(url);
144
+ ress.type = "kwaii";
145
+ } else {
146
+ ress = {
147
+ status: 400,
148
+ message: "failed request"
149
+ };
150
+ }
151
+ } catch (e) {
152
+ console.log(e);
153
+ ress = {
154
+ status: 404,
155
+ message: e.message
156
+ };
157
+ }
158
+
159
+ if(Buffer.isBuffer(ress)) {
160
+ const { mime } = await fileTypeFromBuffer(ress);
161
+ res.setHeader("Content-Type", mime);
162
+ res.setHeader("Content-Length", ress.length);
163
+ }
164
+ return res.status(ress.status || 200).send(ress.data || ress);
165
+ };
fnc/validate.js ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const crypto = require("crypto");
2
+
3
+ function generateToken() {
4
+ return crypto.randomBytes(35).toString("hex");
5
+ }
6
+
7
+ module.exports = async function(req, res) {
8
+ const ip = req._ip;
9
+ const token = generateToken()
10
+
11
+ global.tokenVd = global.tokenVd.filter(entry => entry.ip !== ip);
12
+ global.tokenVd.push({
13
+ ip,
14
+ token
15
+ });
16
+ res.setHeader("X-Auth-Token", token);
17
+ res.status(200).json({
18
+ status: "success",
19
+ message: "Your Ip device Has been stored",
20
+ timestamp: Date.now(),
21
+ device: {
22
+ ip,
23
+ "User-Agent": req.get("user-agent"),
24
+ },
25
+ })
26
+ }
lib/cookies/gtc.json ADDED
@@ -0,0 +1 @@
 
 
1
+ {"web.getcontact.com":{"/":{"accessToken":{"key":"accessToken","value":"k1epack1m7d3erpokmblc8o833","domain":"web.getcontact.com","path":"/","secure":true,"httpOnly":true,"hostOnly":true,"creation":"2024-09-09T12:16:31.281Z","lastAccessed":"2024-09-10T10:13:49.063Z","sameSite":"strict"}}},"getcontact.com":{"/":{"lang":{"key":"lang","value":"en","expires":"2024-09-17T10:13:49.000Z","maxAge":604800,"domain":"getcontact.com","path":"/","secure":true,"httpOnly":true,"hostOnly":false,"creation":"2024-09-09T12:16:31.282Z","lastAccessed":"2024-09-10T10:13:49.560Z","sameSite":"strict"}}}}
lib/cookies/qq.txt ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ # Netscape HTTP Cookie File
2
+ # This file is generated by yt-dlp. Do not edit.
3
+
4
+ .qq.com TRUE / FALSE 1775522690 pgv_pvid 3157539980
5
+ .qq.com TRUE / FALSE 1775522582 fqm_pvqid e76154ca-b120-4254-b3fa-e81072a8c12e
6
+ .qq.com TRUE / FALSE 0 fqm_sessionid 50e2ad78-403b-4e41-95a0-3d30f1a31924
7
+ .qq.com TRUE / FALSE 0 pgv_info ssid=s5472847215
8
+ .qq.com TRUE / FALSE 0 _qpsvr_localtk 0.7401285126283235
9
+ .qq.com TRUE / FALSE 0 login_type 2
10
+ .y.qq.com TRUE / FALSE 1775522690 ts_uid 1529878964
lib/cookies/twt.txt ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Netscape HTTP Cookie File
2
+ # This file is generated by yt-dlp. Do not edit.
3
+
4
+ .x.com TRUE / TRUE 1750331668 guest_id v1%3A170332686229870139
5
+ .x.com TRUE / TRUE 1776858318 guest_id_ads v1%3A170332686229870139
6
+ .x.com TRUE / TRUE 1776858318 guest_id_marketing v1%3A170332686229870139
7
+ .x.com TRUE / TRUE 1776657587 kdt If8CE3YGg35fVb3dXwdv2aWiW59aZ2EpcXDqKgPK
8
+ .x.com TRUE / TRUE 1776657587 auth_token e751059b3aa2d90324e12505ebee30208d90c215
9
+ .x.com TRUE / TRUE 1776657587 ct0 c68643bbe144913a294f85810497c713c399fd3ee66393e4c51ed24c0340c23ba255929274e56acb3b3ae1bf00570d57ce38ceaf46df27fa9b1370c9fbc09e83e430ba8dbf72d4e1daf51b6925728f40
10
+ .x.com TRUE / TRUE 1773834318 twid u%3D1457478990747164675
11
+ .x.com TRUE / TRUE 1773633591 personalization_id "v1_qrJD886R5QtsnFa6uKK4uw=="
12
+ .x.com TRUE / TRUE 1742443562 __cf_bm g8TUQZaJ.LJ.VamcvG7m2DsIa8r2VH2LIe2Cy4QWUoQ-1742441762-1.0.1.1-HBhyZuLG2FH4NTxPnpuVSS8bcXjaTQC0Qbgu.xYlHvlrtpJju353UtPmRPyXMD38Po2gXKk2evwLDOvgGmJHpNKMCsSwb5A1WkH0o1NNHsk
13
+ x.com FALSE / TRUE 1757649584 g_state {"i_l":0}
14
+ x.com FALSE / FALSE 0 lang id
lib/cookies/yt.txt ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Netscape HTTP Cookie File
2
+ # This file is generated by yt-dlp. Do not edit.
3
+
4
+ .youtube.com TRUE / FALSE 0 PREF tz=UTC&f7=100&f6=40000000&hl=en
5
+ .youtube.com TRUE / TRUE 1758439410 LOGIN_INFO AFmmF2swRAIgZr72nRfUBYe2WwOkhbprKXnQcJHi4BfBdkJEptWn8VMCIDZael58JymiEpDm-8DrJfI-gNP297FXnHZncNBncL8l:QUQ3MjNmd19hS2EtMlhSNzhSSy1rZGFDTV9KMm1Md1pZOURKUlFkaUxhUlZEenRqMUtwU1JVdDlCeHoybW9lcldfTFB1ZXlibFJIYU9aSE8zYWd4bUNVZmZ1VkRKS1JYUlpaOXhUaDFuZlc2dWFPZ3ZhM2FiNUNBdld3d3lrcnhjZ2NCVUM3LW5CYllEczVDQkNwZVVCbGpNOGJ6blU0alpR
6
+ .youtube.com TRUE / TRUE 1764899348 __Secure-1PSIDTS sidts-CjIBQT4rX_xBWbrFJa5rVnNKdO27WmQe-gLTIsnHycw9lNXR-EmxQAuoS169ydN4pqd3hBAA
7
+ .youtube.com TRUE / TRUE 1764899348 __Secure-3PSIDTS sidts-CjIBQT4rX_xBWbrFJa5rVnNKdO27WmQe-gLTIsnHycw9lNXR-EmxQAuoS169ydN4pqd3hBAA
8
+ .youtube.com TRUE / FALSE 1775036690 HSID A-Ic277KbNCjxQ95u
9
+ .youtube.com TRUE / TRUE 1775036690 SSID A-zx7Npkr9ni8J_Ot
10
+ .youtube.com TRUE / FALSE 1775036690 APISID NJ9bG6QnEs2eeGZK/AjVyxaqKXzrKkc0Gu
11
+ .youtube.com TRUE / TRUE 1775036690 SAPISID VAxN26302hYv3b09/AAUzwPVK4ySu-3dkL
12
+ .youtube.com TRUE / TRUE 1775036690 __Secure-1PAPISID VAxN26302hYv3b09/AAUzwPVK4ySu-3dkL
13
+ .youtube.com TRUE / TRUE 1775036690 __Secure-3PAPISID VAxN26302hYv3b09/AAUzwPVK4ySu-3dkL
14
+ .youtube.com TRUE / FALSE 1775036690 SID g.a000uAhrP7e8IUjWS8HrzePXGBkk5Lx9E59jxXxqcaew85Kurcz2HXHVPmBon1jGDVahJA8RNgACgYKAR8SARcSFQHGX2Mi7NzMZMn9z5RNz0p6nLbFQhoVAUF8yKrlcJ8si136TF9S4EiJofej0076
15
+ .youtube.com TRUE / TRUE 1775036690 __Secure-1PSID g.a000uAhrP7e8IUjWS8HrzePXGBkk5Lx9E59jxXxqcaew85Kurcz2dTxUea1qKKB7uBGEaCptBwACgYKAWgSARcSFQHGX2MixouKhILhILOnCgDau3ExyRoVAUF8yKqQ4ovWpp1yFksDx4KRx4nh0076
16
+ .youtube.com TRUE / TRUE 1775036690 __Secure-3PSID g.a000uAhrP7e8IUjWS8HrzePXGBkk5Lx9E59jxXxqcaew85Kurcz2Sn_2oMxfHSjvZoeUKJIQfAACgYKAUQSARcSFQHGX2MigCv66d6OMJWkAg-efbXYEBoVAUF8yKpBrjPafDMzILJYbbnWGqdC0076
17
+ .youtube.com TRUE / FALSE 1774210887 SIDCC AKEyXzWdRPAwby9kre7bBzSAXLItq69N8IjtbWUJRPoE01aKfAPkjth1vM0pexORLHxbC7eqF2g
18
+ .youtube.com TRUE / TRUE 1774210887 __Secure-1PSIDCC AKEyXzVQ0TXi0VCVegUrTDHoLg_HOwLbDpb9Kgz0XqiCKxdvEQRpCZSFOl1YqyIKEQeOGc7MaGY
19
+ .youtube.com TRUE / TRUE 1774210887 __Secure-3PSIDCC AKEyXzUl9WXrklM11Z-8f158yYngdLy1oJkTOpWbJuPF7ytjEvDaUMh_L6-NCbCYXpM-UhVlvp0
20
+ .youtube.com TRUE / TRUE 0 YSC Cp7zocGc5mQ
21
+ .youtube.com TRUE / TRUE 1758197457 __Secure-ROLLOUT_TOKEN CLvzx8Ttx-3WFhDCy7Gb1J2MAxjQtOSb1J2MAw%3D%3D
22
+ .youtube.com TRUE / TRUE 1758226887 VISITOR_INFO1_LIVE HfMgLjm828Y
23
+ .youtube.com TRUE / TRUE 1758226887 VISITOR_PRIVACY_METADATA CgJVUxIEGgAgKg%3D%3D
24
+ .youtube.com TRUE / TRUE 1758226887 YT_DEVICE_MEASUREMENT_ID qNFt3Rg=
25
+ .youtube.com TRUE / TRUE 1805746887 __Secure-YT_TVFAS t=484068&s=2
26
+ .youtube.com TRUE / TRUE 1758226887 DEVICE_INFO ChxOelE0TkRZd05USTBOell3TmpZeE5UZzFOQT09EMe3/L4GGNHR+r4G
lib/fb.js ADDED
@@ -0,0 +1,89 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const FormData = require("form-data")
3
+ const axios = require("axios")
4
+ const beautify = require("js-beautify")
5
+ const cheerio = require("cheerio")
6
+ const similarity = require("similarity")
7
+
8
+ async function getSize(url) {
9
+ try {
10
+ const res = await axios.head(url)
11
+ return res.headers["content-length"] ? parseInt(res.headers["content-length"]) : 0
12
+ } catch {
13
+ return 0
14
+ }
15
+ }
16
+
17
+ function bytesToSize(bytes) {
18
+ const sizes = ["B", "KB", "MB", "GB", "TB"]
19
+ if (bytes == 0 || isNaN(bytes)) return "0 B"
20
+ const i = parseInt(Math.floor(Math.log(bytes) / Math.log(1024)))
21
+ return (bytes / Math.pow(1024, i)).toFixed(1) + " " + sizes[i]
22
+ }
23
+
24
+ async function fbdl(url) {
25
+ if (!url) return { error: true, message: "URL Required" }
26
+
27
+ try {
28
+ const { hostname } = new URL(url)
29
+ const _sim = similarity("facebook.com", hostname)
30
+ if (!(_sim >= 0.65 && hostname.includes("facebook.com"))) throw false
31
+ } catch {
32
+ return { error: true, message: "Invalid URL" }
33
+ }
34
+
35
+ const form = new FormData()
36
+ form.append("url", url)
37
+
38
+ try {
39
+ const res = await axios.post("https://snapsave.app/action.php", form, {
40
+ headers: {
41
+ ...form.getHeaders(),
42
+ "User-Agent": "WhatsApp/2.24.6.21",
43
+ Referer: "https://snapsave.app/"
44
+ }
45
+ })
46
+
47
+ const script = res.data
48
+ let js
49
+ try {
50
+ js = eval(script.replace("eval", ""))
51
+ js = beautify(js).split("\n")[2]
52
+ } catch {
53
+ throw script
54
+ }
55
+
56
+ try {
57
+ const html = eval(js.slice(js.indexOf("<") - 1, -1))
58
+ const $ = cheerio.load(html)
59
+
60
+ const thumbnail = $(".image > img").attr("src")
61
+ const video = []
62
+
63
+ for (const i of $("table > tbody > tr")) {
64
+ const _$ = $(i).find.bind($(i))
65
+
66
+ const quality = _$(".video-quality").text()
67
+ let url = _$("a").attr("href")
68
+ if (!url) continue
69
+
70
+ url = new URL(url)
71
+ url.searchParams.delete("dl")
72
+ url = url.toString()
73
+ const size = await getSize(url)
74
+ const fSize = bytesToSize(size)
75
+
76
+ video.push({ resolusi: quality, url, size, fSize })
77
+ }
78
+
79
+ return { status: 200, title: "", thumbnail, video }
80
+ } catch (e) {
81
+ if (!(e instanceof SyntaxError)) throw e
82
+ return { error: true, message: eval(js.split(" = ")[1]) }
83
+ }
84
+ } catch (error) {
85
+ return { error: true, message: "Failed to fetch data" }
86
+ }
87
+ }
88
+
89
+ module.exports = fbdl
lib/ig.js ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const axios = require('axios');
3
+ const FormData = require('form-data');
4
+ const cheerio = require('cheerio');
5
+ const fromBuffer = x => import("file-type").then(v => v.fileTypeFromBuffer(x))
6
+
7
+ async function igdl(url) {
8
+ try {
9
+ const formData = new FormData();
10
+ formData.append('url', url);
11
+
12
+ const { data } = await axios.post('https://snapsave.app/id/action.php?lang=id', formData, {
13
+ headers: {
14
+ ...formData.getHeaders(),
15
+ 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36'
16
+ }
17
+ });
18
+
19
+ // eslint-disable-next-line no-unused-vars
20
+ const js = await new Promise(r => eval(data.replace('eval', 'r')));
21
+ const raw = js.match(/document\.getElementById\("download-section"\)\.innerHTML\s*=\s*"(.*?)";/s);
22
+ const $ = cheerio.load(raw[1].replace(/\\"/g, '"').replace(/\\n/g, '').replace(/\\t/g, '').replace(/\\\\/g, '\\'));
23
+
24
+ let thumb = "";
25
+ $("img").each((i, img) => {
26
+ const src = $(img).attr("src")
27
+ thumb = src
28
+ })
29
+
30
+ let res = {
31
+ status: 200,
32
+ type: "ig",
33
+ title: "",
34
+ thumbnail: thumb,
35
+ video: [],
36
+ image: []
37
+ };
38
+
39
+
40
+ let sesi = []
41
+ // Cek setiap link yang ada
42
+ $('.download-items__btn a').each(async (i, element) => {
43
+ const xk = $(element).attr('href');
44
+ sesi.push(xk)
45
+ });
46
+ for (const i of sesi) {
47
+ const response = await axios.get(i, { responseType: 'arraybuffer' });
48
+ const buffer = Buffer.from(response.data);
49
+ const type = await fromBuffer(buffer);
50
+
51
+ if (type) {
52
+ if (type.mime.startsWith('image')) {
53
+ res.image.push(i);
54
+ if (!res.thumbnail) {
55
+ res.thumbnail = i;
56
+ }
57
+ }
58
+ // Jika file adalah video
59
+ else if (type.mime.startsWith('video')) {
60
+ res.video.push({ resolusi: "HD", url: i, mimetype: type.mime });
61
+ }
62
+ }
63
+ }
64
+ return res;
65
+ } catch (err) {
66
+ console.error("[ERROR IG]\n\n", e);
67
+ return null;
68
+ }
69
+ }
70
+ module.exports = igdl;
lib/kuaishou.js ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const axios = require("axios");
3
+ const cheerio = require("cheerio");
4
+
5
+ function decodeKey(encodedKey) {
6
+ const unicodeDecoded = encodedKey.replace(/\\u[0-9a-fA-F]{4}/g, (match) =>
7
+ String.fromCharCode(parseInt(match.replace("\\u", ""), 16))
8
+ );
9
+ return unicodeDecoded
10
+ .split("")
11
+ .map((char) => {
12
+ if (char >= "a" && char <= "z") {
13
+ return String.fromCharCode(((char.charCodeAt(0) - 97 - 1 + 26) % 26) + 97);
14
+ } else if (char >= "A" && char <= "Z") {
15
+ return String.fromCharCode(((char.charCodeAt(0) - 65 - 1 + 26) % 26) + 65);
16
+ } else {
17
+ return char;
18
+ }
19
+ })
20
+ .join("");
21
+ }
22
+
23
+ async function scrapeKuaishou(url) {
24
+ try {
25
+ const { data: html } = await axios.get(url);
26
+ const $ = cheerio.load(html);
27
+
28
+ const scriptTag = $("script")
29
+ .filter((_, el) => $(el).html().includes("window.INIT_STATE"))
30
+ .html();
31
+
32
+ if (!scriptTag) {
33
+ console.warn("INIT_STATE tidak ditemukan.");
34
+ return null;
35
+ }
36
+
37
+ const jsonString = scriptTag.match(/window\.INIT_STATE\s*=\s*(\{.*\});?/)[1];
38
+ const result = JSON.parse(jsonString);
39
+
40
+ const decodedResult = Object.keys(result).reduce((acc, key) => {
41
+ const decodedKey = decodeKey(key);
42
+ acc[decodedKey] = result[key];
43
+ return acc;
44
+ }, {});
45
+
46
+ const photoKey = Object.keys(decodedResult).find((key) => {
47
+ const data = decodedResult[key];
48
+ return data && data.photo;
49
+ });
50
+
51
+ if (!photoKey) {
52
+ console.warn("Key dengan variabel 'photo' tidak ditemukan.");
53
+ return null;
54
+ }
55
+
56
+ const x_1a = decodedResult[photoKey];
57
+
58
+ const res = {
59
+ userInfo: {
60
+ id: x_1a.photo.userId,
61
+ username: x_1a.photo.kwaiId,
62
+ fullname: x_1a.photo.userName,
63
+ avatar: x_1a.photo.headUrl,
64
+ sex: x_1a.photo.userSex,
65
+ stats: x_1a.counts,
66
+ },
67
+ caption: x_1a.photo.caption,
68
+ };
69
+
70
+ if (x_1a.atlas) {
71
+ res.slide = {
72
+ size: x_1a.atlas.size,
73
+ urls: x_1a.atlas.list.map((v) => "https://p5.a.yximgs.com" + v),
74
+ };
75
+ }
76
+
77
+ if (x_1a.photo.photoType === "VIDEO") {
78
+ res.video = x_1a.photo.manifest.adaptationSet[0].representation[0].url;
79
+ }
80
+ if (x_1a.photo.soundTrack) {
81
+ res.sound = {
82
+ name: x_1a.photo.soundTrack.name,
83
+ cover: x_1a.photo.soundTrack.imageUrls[0].url,
84
+ audio: x_1a.photo.soundTrack.audioUrls[0].url,
85
+ };
86
+ }
87
+
88
+ return res;
89
+ } catch (error) {
90
+ console.warn(`Gagal scrape: ${error.message}`);
91
+ return null;
92
+ }
93
+ }
94
+
95
+ async function validasi(url, maxRetries = 3) {
96
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
97
+ console.log(`Step ${attempt}...`);
98
+ const result = await scrapeKuaishou(url);
99
+ if (result) {
100
+ console.log("Scraping berhasil!");
101
+ console.log(result);
102
+ return result;
103
+ }
104
+ console.log("Gagal, mencoba ulang...");
105
+ }
106
+ console.error("Scraping gagal setelah 3 kali percobaan.");
107
+ return null;
108
+ }
109
+
110
+ module.exports = validasi;
lib/pix.js ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const axios = require('axios');
2
+ const fs = require('fs');
3
+ const path = require('path');
4
+ const { v4: uuidv4 } = require('uuid');
5
+
6
+ //const styles = [ "anime", "manga", "3d", "comic", "realistic" ];
7
+ //const qualitys = [ "low", "medium" ];
8
+
9
+ const drawever = {
10
+ queue: async (imageUrl, style, quality) => {
11
+ const imageResponse = await axios.get(imageUrl, { responseType: 'arraybuffer' });
12
+ const mimeType = imageResponse.headers['content-type'];
13
+ const base64Image = Buffer.from(imageResponse.data).toString('base64');
14
+ const base64ImageUrl = `data:${mimeType};base64,${base64Image}`;
15
+
16
+ const data = JSON.stringify({
17
+ "image": base64ImageUrl,
18
+ "style": style,
19
+ "quality": quality,
20
+ "strength": 0.4
21
+ });
22
+
23
+ const config = {
24
+ method: 'POST',
25
+ url: 'https://www.drawever.com/api/tools/queue',
26
+ headers: {
27
+ 'User-Agent': 'Mozilla/5.0 (Android 10; Mobile; rv:131.0 Firefox/131.0',
28
+ 'Accept': 'application/json',
29
+ 'Content-Type': 'application/json',
30
+ 'accept-language': 'id-ID',
31
+ 'referer': 'https://www.drawever.com/ai/photo-to-anime?start=1736212737985',
32
+ 'path': '/ai/photo-to-anime',
33
+ 'origin': 'https://www.drawever.com',
34
+ 'alt-used': 'www.drawever.com',
35
+ 'sec-fetch-dest': 'empty',
36
+ 'sec-fetch-mode': 'cors',
37
+ 'sec-fetch-site': 'same-origin',
38
+ 'priority': 'u=0',
39
+ 'te': 'trailers',
40
+ 'Cookie': '_ga_H15YQYJC6R=GS1.1.1736212732.1.0.1736212732.0.0.0; _ga=GA1.1.1471909988.1736212732'
41
+ },
42
+ data: data
43
+ };
44
+
45
+ const api = await axios.request(config);
46
+ return api.data;
47
+ },
48
+ create: async (imageUrl, style, quality) => {
49
+ const { queueId } = await drawever.queue(imageUrl, style, quality);
50
+
51
+ const checkStatus = async () => {
52
+ const config = {
53
+ method: 'GET',
54
+ url: `https://www.drawever.com/api/tools/queue?queueId=${queueId}`,
55
+ headers: {
56
+ 'User-Agent': 'Mozilla/5.0 (Android 10; Mobile; rv:131.0) Gecko/131.0 Firefox/131.0',
57
+ 'accept-language': 'id-ID',
58
+ 'referer': 'https://www.drawever.com/ai/photo-to-anime?start=1736212737985',
59
+ 'content-type': 'application/json',
60
+ 'alt-used': 'www.drawever.com',
61
+ 'sec-fetch-dest': 'empty',
62
+ 'sec-fetch-mode': 'cors',
63
+ 'sec-fetch-site': 'same-origin',
64
+ 'priority': 'u=4',
65
+ 'te': 'trailers',
66
+ 'Cookie': '_ga_H15YQYJC6R=GS1.1.1736226490.2.1.1736226501.0.0.0; _ga=GA1.1.1471909988.1736212732; _ym_uid=1736782704433305783; _ym_d=1736782704; _ym_isad=2; _ym_visorc=w'
67
+ }
68
+ };
69
+
70
+ const api = await axios.request(config);
71
+ const output = api.data.output;
72
+
73
+ if (output) {
74
+ const base64Image = output.split(';base64,').pop();
75
+ const imageBuffer = Buffer.from(base64Image, 'base64');
76
+ const fileName = `${uuidv4()}.png`;
77
+ const filePath = path.join(__dirname, '../cdn', fileName);
78
+ fs.writeFileSync(filePath, imageBuffer);
79
+ console.log(api.data)
80
+ return imageBuffer
81
+ }
82
+ };
83
+ checkStatus();
84
+ }
85
+ };
86
+
87
+ // Example usage
88
+ module.exports = drawever
lib/pradigm.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const FormData = require("form-data");
2
+ const axios = require("axios");
3
+ const fs = require('fs');
4
+ const qs = require('qs');
5
+
6
+ const tool = [ 'removebg', 'enhance', 'upscale', 'restore', 'colorize' ];
7
+
8
+ const pxpic = {
9
+ upload: async (filePath) => {
10
+ const {
11
+ fileTypeFromBuffer: fromBuffer
12
+ } = await import( 'file-type')
13
+ const buffer = fs.readFileSync(filePath);
14
+ const { ext, mime } = (await fromBuffer(buffer)) || {};
15
+ const fileName = Date.now() + "." + ext;
16
+
17
+ const folder = "uploads";
18
+ const responsej = await axios.post("https://pxpic.com/getSignedUrl", { folder, fileName }, {
19
+ headers: {
20
+ "Content-Type": "application/json",
21
+ },
22
+ });
23
+
24
+ const { presignedUrl } = responsej.data;
25
+
26
+ await axios.put(presignedUrl, buffer, {
27
+ headers: {
28
+ "Content-Type": mime,
29
+ },
30
+ });
31
+
32
+ const cdnDomain = "https://files.fotoenhancer.com/uploads/";
33
+ const sourceFileUrl = cdnDomain + fileName;
34
+
35
+ return sourceFileUrl;
36
+ },
37
+ create: async (filePath, tools) => {
38
+ if (!tool.includes(tools)) {
39
+ return `Pilih salah satu dari tools ini: ${tool.join(', ')}`;
40
+ }
41
+ const url = await pxpic.upload(filePath);
42
+ let data = qs.stringify({
43
+ 'imageUrl': url,
44
+ 'targetFormat': 'png',
45
+ 'needCompress': 'no',
46
+ 'imageQuality': '100',
47
+ 'compressLevel': '6',
48
+ 'fileOriginalExtension': 'png',
49
+ 'aiFunction': tools,
50
+ 'upscalingLevel': ''
51
+ });
52
+
53
+ let config = {
54
+ method: 'POST',
55
+ url: 'https://pxpic.com/callAiFunction',
56
+ headers: {
57
+ 'User-Agent': 'Mozilla/5.0 (Android 10; Mobile; rv:131.0) Gecko/131.0 Firefox/131.0',
58
+ 'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/png,image/svg+xml,*/*;q=0.8',
59
+ 'Content-Type': 'application/x-www-form-urlencoded',
60
+ 'accept-language': 'id-ID'
61
+ },
62
+ data: data
63
+ };
64
+
65
+ const api = await axios.request(config);
66
+ return api.data;
67
+ }
68
+ }
69
+
70
+
71
+ const domain = {
72
+ efek: "https://effect-api.visual-paradigm.com",
73
+ ai: "https://ai-services.visual-paradigm.com"
74
+ }
75
+
76
+
77
+ const paradigm = {
78
+ async rmbg(buffer) {
79
+
80
+ const { fileTypeFromBuffer } = await import('file-type');
81
+ const fileType = await fileTypeFromBuffer(buffer);
82
+
83
+ if (!fileType || !['image/jpeg', 'image/png', 'image/gif'].includes(fileType.mime)) throw new Error("File yang diunggah bukan gambar. Hanya file gambar yang diperbolehkan.");
84
+
85
+ const form = new FormData();
86
+ form.append("file", buffer, `anjuc.jpg`);
87
+
88
+ const { data } = await axios.post(`${domain.efek}/remove-bg`, form, {
89
+ headers: form.getHeaders(),
90
+ responseType: "arraybuffer"
91
+ }).catch(e => e.response);
92
+
93
+ return data;
94
+ },
95
+ async enhance(buffer) {
96
+ const { fileTypeFromBuffer } = await import('file-type');
97
+
98
+ const fileType = await fileTypeFromBuffer(buffer);
99
+
100
+ if (!fileType || !['image/jpeg', 'image/png', 'image/gif'].includes(fileType.mime)) throw new Error("File yang diunggah bukan gambar. Hanya file gambar yang diperbolehkan.");
101
+
102
+ const form = new FormData();
103
+ form.append("file", buffer, `${Date.now()}.jpg`);
104
+
105
+ const { data } = await axios.post(`${domain.ai}/api/super-resolution/file`, form, {
106
+ headers: form.getHeaders(),
107
+ responseType: "arraybuffer"
108
+ }).catch(e => e.response);
109
+
110
+ return data;
111
+ }
112
+ };
113
+
114
+ module.exports = { enhance: paradigm.enhance, pxpic };
lib/qqm.js ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { exec } = require("child_process");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+ const axios = require("axios");
5
+
6
+ const COOKIES_PATH = path.join(__dirname, "./cookies/qq.txt");
7
+ const ytdlp = path.join(__dirname, "./yt-dlp")
8
+
9
+
10
+
11
+ async function getRedirectedURL(url) {
12
+ try {
13
+ const response = await axios.get(url, {
14
+ maxRedirects: 0,
15
+ validateStatus: (status) => status >= 300 && status < 400,
16
+ });
17
+
18
+ return response.headers.location || null;
19
+ } catch (error) {
20
+ console.error("Error mendapatkan URL redirect:", error.message);
21
+ return null;
22
+ }
23
+ }
24
+
25
+
26
+ function convertToSongDetailURL(url) {
27
+ try {
28
+ const urlObj = new URL(url);
29
+ const songmid = urlObj.searchParams.get("songmid");
30
+
31
+ if (songmid) {
32
+ return `https://y.qq.com/n/ryqq/songDetail/${songmid}`;
33
+ }
34
+ } catch (error) {
35
+ console.error("Error parsing URL:", error.message);
36
+ }
37
+ return null;
38
+ }
39
+
40
+ async function processQQMusicURL(url) {
41
+ try {
42
+ if (url.includes("y.qq.com/n/ryqq/songDetail/")) {
43
+ return url;
44
+ } else if (url.includes("c6.y.qq.com/base/fcgi-bin/u?")) {
45
+ const redirectedURL = await getRedirectedURL(url);
46
+ if (redirectedURL) {
47
+ return convertToSongDetailURL(redirectedURL);
48
+ }
49
+ } else if (url.includes("i.y.qq.com/v8/playsong.html")) {
50
+ return convertToSongDetailURL(url);
51
+ }
52
+ } catch (error) {
53
+ console.error("Error processing URL:", error.message);
54
+ }
55
+ return null;
56
+ }
57
+
58
+ async function getInfo(url) {
59
+ return new Promise(async(resolve, reject) => {
60
+ const thumbnail = await getQQMusicCover(url);
61
+
62
+ exec(`${ytdlp} -j --cookies ${COOKIES_PATH} "${await processQQMusicURL(url)}"`, (error, stdout, stderr) => {
63
+ if (error) {
64
+ return reject(`Error: ${stderr || error.message}`);
65
+ }
66
+ try {
67
+ const info = JSON.parse(stdout);
68
+
69
+ resolve({
70
+ status: 200,
71
+ title: info.title,
72
+ artist: info.creators[0],
73
+ duration: info.duration,
74
+ thumbnail,
75
+ music: info.formats.map(f => ({
76
+ format_id: f.format_id,
77
+ ext: f.ext,
78
+ filesize: f.size,
79
+ url: f.url
80
+ }))
81
+ });
82
+ } catch (e) {
83
+ reject(`Parsing Error: ${e.message}`);
84
+ }
85
+ });
86
+ });
87
+ }
88
+
89
+
90
+
91
+
92
+
93
+ async function getQQMusicCover(songURL) {
94
+ try {
95
+ const response = await axios.get(await getRedirectedURL(songURL));
96
+ const html = response.data;
97
+ const match = html.match(/window\.__ssrFirstPageData__\s*=\s*(\{.*?\})<\/script>/s);
98
+
99
+ if (match) {
100
+ const jsonData = JSON.parse(match[1]);
101
+ const coverURL = jsonData?.metaData?.image;
102
+
103
+ return coverURL;
104
+ } else {
105
+ throw new Error("Data JSON tidak ditemukan dalam HTML.");
106
+ }
107
+ } catch (error) {
108
+ console.error("Error mendapatkan cover:", error.message);
109
+ return null;
110
+ }
111
+ }
112
+
113
+
114
+ module.exports = getInfo
lib/qqmusic.js ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { exec } = require("child_process");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+
5
+ const COOKIES_PATH = "cookies/qq.txt";
6
+ const DOWNLOAD_DIR = path.join(__dirname, "tmp");
7
+
8
+ // Pastikan folder download ada
9
+ if (!fs.existsSync(DOWNLOAD_DIR)) {
10
+ fs.mkdirSync(DOWNLOAD_DIR, { recursive: true });
11
+ }
12
+
13
+ // Fungsi untuk mendapatkan informasi lagu
14
+ function getInfo(url) {
15
+ return new Promise((resolve, reject) => {
16
+ exec(`./yt-dlp -j --cookies ${COOKIES_PATH} "${url}"`, (error, stdout, stderr) => {
17
+ if (error) {
18
+ return reject(`Error: ${stderr || error.message}`);
19
+ }
20
+ try {
21
+ const info = JSON.parse(stdout);
22
+
23
+ resolve({
24
+ title: info.title,
25
+ artist: info.creators[0],
26
+ duration: info.duration,
27
+ thumbnail: info.thumbnai,
28
+ formats: info.formats.map(f => ({
29
+ format_id: f.format_id,
30
+ ext: f.ext,
31
+ filesize: f.size,
32
+ url: f.url
33
+ }))
34
+ });
35
+ } catch (e) {
36
+ reject(`Parsing Error: ${e.message}`);
37
+ }
38
+ });
39
+ });
40
+ }
41
+
42
+ // Fungsi untuk mengunduh lagu
43
+ function download(url) {
44
+ return new Promise((resolve, reject) => {
45
+ const command = `./yt-dlp -vU --cookies ${COOKIES_PATH} -f ba --extract-audio --audio-format mp3 -o "${DOWNLOAD_DIR}/%(title)s.%(ext)s" "${url}"`;
46
+
47
+ exec(command, (error, stdout, stderr) => {
48
+ if (error) {
49
+ return reject(`Download Error: ${stderr || error.message}`);
50
+ }
51
+ resolve(`${DOWNLOAD_DIR}`);
52
+ });
53
+ });
54
+ }
55
+
56
+ module.exports = {
57
+ getInfo,
58
+ download
59
+ }
lib/skrep.js ADDED
@@ -0,0 +1,160 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const axios = require("axios");
3
+ const FormData = require("form-data");
4
+ const fs = require("fs");
5
+ const { exec } = require("child_process");
6
+
7
+ async function ttt(link) {
8
+ const form = new FormData();
9
+ form.append("url", link);
10
+ form.append("count", "12");
11
+ form.append("cursor", "0");
12
+ form.append("web", "1");
13
+ form.append("hd", "1");
14
+
15
+ const { data } = await axios.post("https://www.tikwm.com/api/", form);
16
+
17
+ if (data.code === 0 && data.msg === "success") {
18
+ const baseUrl = "https://www.tikwm.com";
19
+ data.data.cover = baseUrl + data.data.cover;
20
+ data.data.play = baseUrl + data.data.play;
21
+ data.data.wmplay = baseUrl + data.data.wmplay;
22
+ data.data.hdplay = baseUrl + data.data.hdplay;
23
+ data.data.music = baseUrl + data.data.music;
24
+ data.data.author.avatar = baseUrl + data.data.author.avatar;
25
+ }
26
+
27
+ const res = {
28
+ status: 200,
29
+ type: "tiktok",
30
+ title: data.data?.title || null,
31
+ desc: null,
32
+ thumbnail: data.data.cover,
33
+ video: [
34
+ { url: data.data.hdplay },
35
+ { url: data.data.play },
36
+ ],
37
+ music: [{ url: data.data.music }],
38
+ image: data.data.images,
39
+ };
40
+
41
+ /*if (res.images) {
42
+ const outputDir = "./cdn";
43
+ await downloadImages(res.images, outputDir);
44
+
45
+ const FNvd = `tt_video_${Date.now()}.mp4`;
46
+ const FNad = `tt_audio_${Date.now()}.mp3`;
47
+ const videoPath = `${outputDir}/${FNvd}`;
48
+ const audioPath = `${outputDir}/${FNad}`;
49
+
50
+ // ✅ Unduh audio sebelum dipakai
51
+ await downloadAudio(res.music[0].url, audioPath);
52
+
53
+ const slideResult = await createSlideshow(outputDir, videoPath, audioPath);
54
+ if (slideResult) {
55
+ res.video.push({ resolusi: "Slide", url: `https://beta.wzblueline.xyz/cdn/${FNvd}` });
56
+ }
57
+ }
58
+ */
59
+ return res;
60
+ }
61
+
62
+ async function downloadAudio(audioUrl, outputFile) {
63
+ const response = await axios({
64
+ url: audioUrl,
65
+ responseType: "stream",
66
+ });
67
+
68
+ return new Promise((resolve, reject) => {
69
+ const writer = fs.createWriteStream(outputFile);
70
+ response.data.pipe(writer);
71
+ writer.on("finish", () => {
72
+ console.log(`✅ Audio telah diunduh: ${outputFile}`);
73
+ resolve(outputFile);
74
+ });
75
+ writer.on("error", reject);
76
+ });
77
+ }
78
+
79
+ async function downloadImages(imageUrls, outputDir) {
80
+ if (!fs.existsSync(outputDir)) fs.mkdirSync(outputDir);
81
+
82
+ let downloadPromises = imageUrls.map((url, index) => {
83
+ const filePath = `${outputDir}/image${index + 1}.jpg`;
84
+ return axios({ url, responseType: "stream" }).then((response) => {
85
+ return new Promise((resolve, reject) => {
86
+ const writer = fs.createWriteStream(filePath);
87
+ response.data.pipe(writer);
88
+ writer.on("finish", resolve);
89
+ writer.on("error", reject);
90
+ });
91
+ });
92
+ });
93
+
94
+ await Promise.all(downloadPromises);
95
+ console.log("✅ Semua gambar telah diunduh.");
96
+ }
97
+
98
+ async function getAudioDuration(audioFile) {
99
+ return new Promise((resolve, reject) => {
100
+ exec(`ffprobe -i ${audioFile} -show_entries format=duration -v quiet -of csv="p=0"`, (error, stdout) => {
101
+ if (error) {
102
+ reject("❌ Gagal mendapatkan durasi audio.");
103
+ return;
104
+ }
105
+ resolve(parseFloat(stdout.trim()));
106
+ });
107
+ });
108
+ }
109
+
110
+ async function createSlideshow(imagesDir, outputVideo, audioFile) {
111
+ const imageFiles = fs.readdirSync(imagesDir).filter(file => file.endsWith(".jpg"));
112
+ const totalImages = imageFiles.length;
113
+
114
+ if (totalImages === 0) {
115
+ console.error("❌ Tidak ada gambar untuk slideshow.");
116
+ return null;
117
+ }
118
+
119
+ try {
120
+ const audioDuration = await getAudioDuration(audioFile);
121
+ const frameDuration = audioDuration / totalImages;
122
+ const tempDirv = `./cdn/temp_video_${Date.now()}.mp4`
123
+ console.log(`📏 Durasi audio: ${audioDuration}s`);
124
+ console.log(`🖼 Durasi per gambar: ${frameDuration}s`);
125
+
126
+ const ffmpegCommand = `ffmpeg -framerate 1/${frameDuration} -i ${imagesDir}/image%d.jpg -filter_complex "pad=iw:ih:(ow-iw)/2:(oh-ih)/2" -r 25 -c:v libx264 -pix_fmt yuv420p ${tempDirv}`;
127
+
128
+ console.log("🚀 Membuat slideshow...");
129
+ return new Promise((resolve, reject) => {
130
+ exec(ffmpegCommand, (error) => {
131
+ if (error) {
132
+ console.error("❌ Error saat membuat slideshow:", error);
133
+ reject(null);
134
+ return;
135
+ }
136
+
137
+ console.log("✅ Slideshow selesai dibuat.");
138
+ const audioCommand = `ffmpeg -i ${tempDirv} -i ${audioFile} -filter_complex "[1:a]apad" -shortest -c:v libx264 -pix_fmt yuv420p -c:a aac -b:a 128k ${outputVideo}`;
139
+
140
+ exec(audioCommand, (audioError) => {
141
+ if (audioError) {
142
+ console.error("❌ Error saat menambahkan audio:", audioError);
143
+ reject(null);
144
+ return;
145
+ }
146
+
147
+ console.log("✅ Video dengan audio selesai dibuat.");
148
+
149
+ console.log("🧹 Folder gambar sementara dihapus.");
150
+ resolve(outputVideo); // ✅ Return path video hasil!
151
+ });
152
+ });
153
+ });
154
+ } catch (error) {
155
+ console.error(error);
156
+ return null;
157
+ }
158
+ }
159
+
160
+ module.exports = { ttt };
lib/snapchat.js ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const axios = require("axios");
3
+ const { JSDOM } = require("jsdom");
4
+
5
+ async function spotlight(url) {
6
+ try {
7
+ const { data } = await axios.get(url, {
8
+ headers: {
9
+ "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/121.0.0.0 Safari/537.36"
10
+ }
11
+ });
12
+
13
+ const dom = new JSDOM(data);
14
+ const scripts = dom.window.document.querySelectorAll('script[type="application/ld+json"]');
15
+
16
+ let jsonData = null;
17
+ scripts.forEach(script => {
18
+ try {
19
+ const parsedData = JSON.parse(script.textContent);
20
+ if (parsedData["@context"] === "https://schema.org") {
21
+ jsonData = {
22
+ status: 200,
23
+ thumbnail: parsedData["@graph"][0].thumbnailUrl,
24
+ title: parsedData["@graph"][0].name,
25
+ author: parsedData["@graph"][0].creator,
26
+ video: [{
27
+ resolusi: "Watermark",
28
+ url: parsedData["@graph"][0].contentUrl
29
+ }]
30
+ }
31
+ }
32
+ } catch {
33
+ /* empty */
34
+ }
35
+ });
36
+
37
+ if (jsonData) {
38
+ console.log("JSON ditemukan:");
39
+ console.log(JSON.stringify(jsonData, null, 2));
40
+ } else {
41
+ console.log("Tidak ditemukan data JSON yang sesuai.");
42
+ }
43
+ } catch (error) {
44
+ console.error("Gagal mengambil data:", error.message);
45
+ }
46
+ }
47
+
48
+ module.exports = { spotlight };
lib/soundcloud.js ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ /* eslint-disable jsdoc/require-jsdoc */
2
+ const FormData = require("form-data");
3
+ const axios = require("axios");
4
+ const cheerio = require("cheerio");
5
+
6
+
7
+ async function getRedirectedURL(url) {
8
+ try {
9
+ const response = await axios.get(url, {
10
+ maxRedirects: 0,
11
+ validateStatus: (status) => status >= 300 && status < 400,
12
+ });
13
+
14
+ return response.headers.location || null;
15
+ } catch (error) {
16
+ console.error("Error mendapatkan URL redirect:", error.message);
17
+ return null;
18
+ }
19
+ }
20
+
21
+
22
+ async function search(query) {
23
+ try {
24
+ const url = `https://m.soundcloud.com/search?q=${encodeURIComponent(query)}`;
25
+ const response = await axios.get(url);
26
+ const $ = await cheerio.load(response.data);
27
+
28
+ const results = [];
29
+
30
+ $(".List_VerticalList__2uQYU li").each((index, element) => {
31
+ const title = $(element).find(".Information_CellTitle__2KitR").text();
32
+ const artist = $(element).find(".Information_CellSubtitle__1mXGx").text();
33
+ const thumbnail = $(element)
34
+ .find(".Artwork_ArtworkImage__1Ws9-")
35
+ .attr("src");
36
+ const link = $(element)
37
+ .find(".Cell_CellLink__3yLVS")
38
+ .attr("href");
39
+
40
+ results.push({
41
+ title,
42
+ artist,
43
+ thumbnail,
44
+ link: `https://soundcloud.com${link}`,
45
+ });
46
+ });
47
+
48
+ return results;
49
+ } catch (error) {
50
+ console.error(error);
51
+ return [];
52
+ }
53
+ }
54
+
55
+ async function download(url) {
56
+ const form = new FormData();
57
+ form.append("formurl", url);
58
+
59
+ const {
60
+ data
61
+ } = await axios.post("https://www.forhub.io/download.php", form, {
62
+ headers: form.getHeaders(),
63
+ });
64
+
65
+ const $ = cheerio.load(data);
66
+ const fullTitleText = $("td.small-10.columns").text().trim();
67
+ // eslint-disable-next-line no-unused-vars
68
+ const [title] = fullTitleText.split("320 KB/S").map((text) => text.trim());
69
+ const music = $("td a").attr("href");
70
+ // eslint-disable-next-line no-unused-vars
71
+ const cover = $("td img").attr("src");
72
+
73
+ return music
74
+ }
75
+
76
+ async function metadata(url) {
77
+
78
+ const parsedd = new URL(url)
79
+ const scUri = [
80
+ "m.soundcloud.com"
81
+ ]
82
+ let Modif;
83
+ if (scUri.includes(parsedd.hostname)) {
84
+ Modif = url.replace(/(?:m\.)?soundcloud\.com/, "soundcloud.com");
85
+ } else {
86
+ Modif = await getRedirectedURL(url);
87
+ }
88
+
89
+ const { data } = await axios.get(Modif);
90
+ const $ = cheerio.load(data);
91
+
92
+ let hydrationData;
93
+ $("script").each(function() {
94
+ const scr = $(this).html();
95
+ if (scr.includes("window.__sc_hydration")) {
96
+ try {
97
+ // Ambil JSON dari bagian setelah "window.__sc_hydration = "
98
+ const jsonStr = scr.split("window.__sc_hydration = ")[1].trim().slice(0, -1); // Hapus titik koma terakhir
99
+ hydrationData = JSON.parse(jsonStr);
100
+ } catch (err) {
101
+ console.error("Gagal parse JSON:", err);
102
+ }
103
+ }
104
+ });
105
+
106
+ if (!hydrationData) {
107
+ throw new Error("Metadata tidak ditemukan.");
108
+ }
109
+
110
+ const trackData = hydrationData.find(entry => entry.hydratable === "sound")?.data;
111
+ if (!trackData) {
112
+ throw new Error("Data track tidak ditemukan.");
113
+ }
114
+
115
+ return trackData;
116
+ }
117
+
118
+ async function soundcloud(query, type) {
119
+ if(type === "search") {
120
+ const search_result = await search(query)
121
+ return search_result
122
+ } else {
123
+ const result_download = await download(query)
124
+ const result_metadata = await metadata(query)
125
+
126
+ const resd = {
127
+ status: 200,
128
+ title: result_metadata.title,
129
+ thumbnail: result_metadata.artwork_url,
130
+ music: [
131
+ {
132
+ resolusi: "default",
133
+ url: result_download
134
+ }
135
+ ]
136
+ }
137
+ console.log(resd)
138
+ return resd
139
+ }
140
+ }
141
+
142
+ module.exports = {
143
+ search,
144
+ download,
145
+ soundcloud,
146
+ metadata
147
+ }
lib/spotify.js ADDED
@@ -0,0 +1,171 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const axios = require('axios');
2
+ const yts = require("yt-search");
3
+ const { getAudio } = require("../lib/ytdl");
4
+ const path = require("path");
5
+ const fs = require("fs");
6
+ const { ID3Writer } = require('browser-id3-writer');
7
+
8
+ const dirTmp = path.join(__dirname, "../tmp");
9
+ const clientId = '8f777f61f80e4051b754d8e50310ad6e';
10
+ const clientSecret = '5802d3726d3149bfb880a577aa855fb3';
11
+ const tokenUrl = 'https://accounts.spotify.com/api/token';
12
+ const base64Credentials = Buffer.from(`${clientId}:${clientSecret}`).toString('base64');
13
+
14
+ // Pastikan folder tmp ada
15
+ if (!fs.existsSync(dirTmp)) {
16
+ fs.mkdirSync(dirTmp, { recursive: true });
17
+ }
18
+
19
+ async function getAccessToken() {
20
+ try {
21
+ const response = await axios.post(tokenUrl, 'grant_type=client_credentials', {
22
+ headers: {
23
+ 'Authorization': `Basic ${base64Credentials}`,
24
+ 'Content-Type': 'application/x-www-form-urlencoded',
25
+ },
26
+ });
27
+ return response.data.access_token;
28
+ } catch (error) {
29
+ console.error('Gagal mendapatkan token:', error.response?.data || error.message);
30
+ return null;
31
+ }
32
+ }
33
+
34
+ async function spotifyTrack(trackUrl) {
35
+ try {
36
+ const match = trackUrl.match(/track\/([a-zA-Z0-9]+)/);
37
+ if (!match) throw new Error('URL tidak valid');
38
+ const trackId = match[1];
39
+
40
+ // Dapatkan token
41
+ const accessToken = await getAccessToken();
42
+ if (!accessToken) throw new Error('Gagal mendapatkan token akses');
43
+
44
+ // Ambil metadata Spotify
45
+ const trackResponse = await axios.get(`https://api.spotify.com/v1/tracks/${trackId}`, {
46
+ headers: { Authorization: `Bearer ${accessToken}` },
47
+ });
48
+ const trackData = trackResponse.data;
49
+
50
+ // Cari lagu di YouTube
51
+ const searchResults = await yts(`${trackData.name} - ${trackData.artists.map(a => a.name).join(', ')}`);
52
+ if (!searchResults.videos.length) throw new Error('Video tidak ditemukan di YouTube');
53
+
54
+ const videoUrl = searchResults.videos[0].url;
55
+ const audio = await getAudio(videoUrl);
56
+ if (!audio) throw new Error("Gagal mendapatkan audio dari YouTube");
57
+
58
+ // Simpan file dengan nama unik
59
+ const Filename = `NSpotify_${Date.now()}_${Math.floor(Math.random() * 1000)}.mp3`;
60
+ const FilenameM = `Spotify_${Date.now()}_${Math.floor(Math.random() * 1000)}.mp3`;
61
+ await fs.writeFileSync(`${dirTmp}/${Filename}`, audio);
62
+
63
+ // Tambahkan ID3 Tag
64
+ const writer = new ID3Writer(fs.readFileSync(`${dirTmp}/${Filename}`));
65
+ writer
66
+ .setFrame('TIT2', trackData.name)
67
+ .setFrame('TPE1', trackData.artists.map(a => a.name))
68
+ .setFrame('TALB', trackData.album.name || "")
69
+ .setFrame('TYER', parseInt(trackData.album.release_date.split('-')[0]))
70
+ .setFrame('APIC', {
71
+ type: 3,
72
+ data: await urlToBuffer(trackData.album.images[0]?.url),
73
+ description: 'Super picture'
74
+ })
75
+ .addTag();
76
+
77
+ // Simpan file dengan tag ID3
78
+ const taggedSongBuffer = Buffer.from(writer.arrayBuffer);
79
+ await fs.writeFileSync(`${dirTmp}/${FilenameM}`, taggedSongBuffer);
80
+
81
+ const URI = `https://beta.wzblueline.xyz/tmp/${FilenameM}`;
82
+
83
+ const res = {
84
+ status: 200,
85
+ title: trackData.name,
86
+ artist: trackData.artists.map(artist => artist.name).join(', '),
87
+ album: trackData.album.name,
88
+ duration_ms: trackData.duration_ms,
89
+ release_date: trackData.album.release_date,
90
+ thumbnail: trackData.album.images[0]?.url || null,
91
+ music: [{ url: URI }]
92
+ };
93
+ console.log(res)
94
+ return res
95
+ } catch (error) {
96
+ console.error(error);
97
+ return null;
98
+ }
99
+ }
100
+
101
+ async function spotifyPlaylist(playlistUrl) {
102
+ try {
103
+ const match = playlistUrl.match(/playlist\/([a-zA-Z0-9]+)/);
104
+ if (!match) throw new Error('URL playlist tidak valid');
105
+ const playlistId = match[1];
106
+
107
+ const accessToken = await getAccessToken();
108
+ if (!accessToken) throw new Error('Gagal mendapatkan token akses');
109
+
110
+ const playlistResponse = await axios.get(`https://api.spotify.com/v1/playlists/${playlistId}`, {
111
+ headers: { Authorization: `Bearer ${accessToken}` },
112
+ });
113
+
114
+ const playlistData = playlistResponse.data;
115
+ const tracks = playlistData.tracks.items;
116
+ if (!tracks.length) throw new Error('Playlist kosong atau tidak ditemukan');
117
+
118
+ console.log(`🎵 Playlist: ${playlistData.name} (${tracks.length} lagu)`);
119
+
120
+ let results = [];
121
+
122
+
123
+ const limitedTracks = tracks.slice(0, 3);
124
+
125
+ for (const item of limitedTracks) {
126
+ const track = item.track;
127
+ if (!track) continue;
128
+
129
+ const trackUrl = `https://open.spotify.com/track/${track.id}`;
130
+ console.log(`🔄 Memproses: ${track.name} - ${track.artists.map(a => a.name).join(', ')}`);
131
+
132
+ const trackData = await spotifyTrack(trackUrl);
133
+ if (trackData) results.push(trackData.music[0].url);
134
+ }
135
+
136
+ return {
137
+ status: 200,
138
+ playlist_name: playlistData.name,
139
+ total_tracks: tracks.length,
140
+ cover_image: playlistData.images[0]?.url || null,
141
+ tracks: results
142
+ };
143
+ } catch (error) {
144
+ console.error(error);
145
+ return null;
146
+ }
147
+ }
148
+
149
+ const urlToBuffer = async (url, options) => {
150
+ try {
151
+ options ? options : {};
152
+ const res = await axios({
153
+ method: "get",
154
+ url,
155
+ headers: {
156
+ 'DNT': 1,
157
+ 'Upgrade-Insecure-Request': 1
158
+ },
159
+ ...options,
160
+ responseType: 'arraybuffer'
161
+ });
162
+ return res.data;
163
+ } catch (e) {
164
+ console.log(`Error : ${e}`);
165
+ }
166
+ };
167
+
168
+ module.exports = {
169
+ spotifyTrack,
170
+ spotifyPlaylist
171
+ }
lib/twt.js ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { exec } = require("child_process");
2
+ const path = require("path");
3
+
4
+ /**
5
+ * Mengambil metadata video Twitter menggunakan yt-dlp.
6
+ * @param {string} url - URL tweet yang berisi video.
7
+ * @returns {Promise<Object>} - Metadata video dalam format JSON.
8
+ */
9
+ async function getTwitterVideoInfo(url) {
10
+ return new Promise((resolve, reject) => {
11
+ exec(`${path.join(__dirname, "./yt-dlp")} -j "${url}" --cookies ${path.join(__dirname, "./cookies/twt.txt")}`, (error, stdout, stderr) => {
12
+ if (error) {
13
+ reject(`Error: ${stderr || error.message}`);
14
+ return;
15
+ }
16
+ try {
17
+ const x = JSON.parse(stdout);
18
+
19
+ // Filter video yang benar-benar memiliki video (video_ext valid atau URL mengandung .mp4)
20
+ const videoFormats = x.formats.filter(f =>
21
+ (f.video_ext !== 'none' && f.audio_ext !== 'none') ||
22
+ (f.url.includes(".mp4"))
23
+ );
24
+
25
+ // Filter audio yang benar-benar hanya audio
26
+ const audioFormats = x.formats.filter(f => f.video_ext === 'none' && f.audio_ext !== 'none');
27
+
28
+ const res = {
29
+ status: 200,
30
+ title: x.title,
31
+ description: x.description,
32
+ thumbnail: x.thumbnail,
33
+ video: videoFormats.map(v => ({
34
+ format_id: v.format_id,
35
+ resolution: v.resolution || `${v.width}x${v.height}`,
36
+ url: v.url
37
+ })),
38
+ audio: audioFormats.map(a => ({
39
+ format_id: a.format_id,
40
+ bitrate: a.abr,
41
+ url: a.url
42
+ }))
43
+ };
44
+
45
+ resolve(res);
46
+ } catch (parseError) {
47
+ reject("Failed to parse JSON response");
48
+ }
49
+ });
50
+ });
51
+ }
52
+
53
+
54
+ module.exports = getTwitterVideoInfo
lib/ytdl.js ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ const { exec } = require("child_process");
2
+ const path = require("path");
3
+ const fs = require("fs");
4
+
5
+ const tmp = path.join(__dirname, "../tmp"); // path to your tmp folder
6
+ const ytdlp =
7
+ // path to your yt-dlp
8
+ path.join(__dirname, "./yt-dlp") +
9
+ " --cookies " +
10
+ // path to your cookies (Netscape format)
11
+ path.join(__dirname, "./cookies/yt.txt");
12
+
13
+ /**
14
+ * Get YouTube Video Information
15
+ * @param {string} url
16
+ * @returns {Promise<{ id: string, title: string, thumbnail: string, description: string, duration: number, views: number, likes: number, comments: number, uploaded: string, channel: { id: string, handle: string, name: string, picture: string, subscribers: number, verified: boolean }, videos: string[] }>}
17
+ */
18
+ function getInfo(url) {
19
+ return new Promise((res, rej) => {
20
+ exec(`${ytdlp} -j "${url}"`, async (err, stdout) => {
21
+ if(err) {
22
+ return rej(err);
23
+ }
24
+
25
+ const info = JSON.parse(stdout);
26
+ const _res = await fetch("https://imageyoutube.com/profile-photo-download/imgyt", {
27
+ method: "POST",
28
+ headers: {
29
+ "Content-Type": "application/x-www-form-urlencoded",
30
+ Referer: "https://imageyoutube.com/profile-photo-download/"
31
+ },
32
+ body: `v=${encodeURIComponent(url)}&mcountry=en`
33
+ });
34
+ const txt = await _res.text();
35
+ const picture = /<img src='(.*)' alt/.exec(txt)[1];
36
+
37
+ res({
38
+ id: info.id,
39
+ title: info.title,
40
+ thumbnail: `https://i.ytimg.com/vi/${info.id}/maxresdefault.jpg`,
41
+ description: info.description,
42
+ duration: info.duration,
43
+ views: info.view_count,
44
+ likes: info.like_count,
45
+ comments: info.comment_count,
46
+ uploaded: info.timestamp,
47
+ channel: {
48
+ id: info.channel_id,
49
+ handle: info.uploader_id,
50
+ name: info.uploader,
51
+ picture,
52
+ subscribers: info.channel_follower_count,
53
+ verified: !!info.channel_is_verified
54
+ },
55
+ videos: [
56
+ ...new Set(
57
+ info.formats
58
+ .filter(v => v.video_ext === "mp4")
59
+ .map(v => v.height + "p")
60
+ )
61
+ ]
62
+ });
63
+ });
64
+ });
65
+ }
66
+
67
+ /**
68
+ * Download YouTube video as mp4
69
+ * @param {string} url
70
+ * @param {string} [quality="480p"]
71
+ * @returns {Promise<Buffer>}
72
+ */
73
+ function getVideo(url, quality = "480p") {
74
+ return new Promise((res, rej) => {
75
+ const ts = Date.now();
76
+ exec(`${ytdlp} -f "ba[ext=m4a]+bv[height=${quality.slice(0, -1)}]" -o "${tmp}/${ts}.%(ext)s" --merge-output-format mp4 "${url}"`, (_, stdout, stderr) => {
77
+ if(stderr.length) {
78
+ return rej(new Error(stderr));
79
+ }
80
+
81
+ try {
82
+ const filename = /Merging formats into "(.*)"/.exec(stdout)[1];
83
+ const result = fs.readFileSync(filename);
84
+ fs.unlinkSync(filename);
85
+ res(result);
86
+ } catch(e) {
87
+ rej(e);
88
+ }
89
+ });
90
+ });
91
+ }
92
+
93
+ /**
94
+ * Download YouTube video as mp3
95
+ * @param {string} url
96
+ * @returns {Promise<Buffer>}
97
+ */
98
+ function getAudio(url) {
99
+ return new Promise((res, rej) => {
100
+ const ts = Date.now();
101
+ exec(`${ytdlp} -f "ba" -o "${tmp}/${ts}.%(ext)s" "${url}"`, (_, stdout, stderr) => {
102
+ if(stderr.length) {
103
+ return rej(new Error(stderr));
104
+ }
105
+
106
+ const filename = /Destination: (.*)/.exec(stdout)[1];
107
+ exec(`ffmpeg -i ${filename} -vn -ar 44100 -ac 2 -b:a 192k ${tmp}/${ts}.mp3`, (err) => {
108
+ if(err) {
109
+ return rej(err);
110
+ }
111
+
112
+ try {
113
+ const result = fs.readFileSync(`${tmp}/${ts}.mp3`);
114
+ fs.unlinkSync(filename);
115
+ fs.unlinkSync(`${tmp}/${ts}.mp3`);
116
+
117
+ res(result);
118
+ } catch(e) {
119
+ rej(e);
120
+ }
121
+ });
122
+ });
123
+ });
124
+ }
125
+
126
+ module.exports = {
127
+ getInfo,
128
+ getAudio,
129
+ getVideo
130
+ }
package-lock.json CHANGED
@@ -11,10 +11,155 @@
11
  "dependencies": {
12
  "axios": "^1.8.4",
13
  "body-parser": "^2.2.0",
 
14
  "cheerio": "^1.0.0",
15
  "cors": "^2.8.5",
16
  "dotenv": "^16.4.7",
17
- "express": "^4.21.2"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
  }
19
  },
20
  "node_modules/accepts": {
@@ -30,12 +175,121 @@
30
  "node": ">= 0.6"
31
  }
32
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
33
  "node_modules/array-flatten": {
34
  "version": "1.1.1",
35
  "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
36
  "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
37
  "license": "MIT"
38
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  "node_modules/asynckit": {
40
  "version": "0.4.0",
41
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
@@ -53,6 +307,12 @@
53
  "proxy-from-env": "^1.1.0"
54
  }
55
  },
 
 
 
 
 
 
56
  "node_modules/body-parser": {
57
  "version": "2.2.0",
58
  "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
@@ -161,6 +421,28 @@
161
  "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
162
  "license": "ISC"
163
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  "node_modules/bytes": {
165
  "version": "3.1.2",
166
  "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
@@ -241,6 +523,38 @@
241
  "url": "https://github.com/sponsors/fb55"
242
  }
243
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
244
  "node_modules/combined-stream": {
245
  "version": "1.0.8",
246
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
@@ -253,6 +567,31 @@
253
  "node": ">= 0.8"
254
  }
255
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
256
  "node_modules/content-disposition": {
257
  "version": "0.5.4",
258
  "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
@@ -302,6 +641,20 @@
302
  "node": ">= 0.10"
303
  }
304
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
305
  "node_modules/css-select": {
306
  "version": "5.1.0",
307
  "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
@@ -330,6 +683,34 @@
330
  "url": "https://github.com/sponsors/fb55"
331
  }
332
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
333
  "node_modules/debug": {
334
  "version": "2.6.9",
335
  "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
@@ -448,12 +829,66 @@
448
  "node": ">= 0.4"
449
  }
450
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
  "node_modules/ee-first": {
452
  "version": "1.1.1",
453
  "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
454
  "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
455
  "license": "MIT"
456
  },
 
 
 
 
 
 
457
  "node_modules/encodeurl": {
458
  "version": "2.0.0",
459
  "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
@@ -533,12 +968,79 @@
533
  "node": ">= 0.4"
534
  }
535
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
536
  "node_modules/escape-html": {
537
  "version": "1.0.3",
538
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
539
  "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
540
  "license": "MIT"
541
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
542
  "node_modules/etag": {
543
  "version": "1.8.1",
544
  "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
@@ -548,6 +1050,16 @@
548
  "node": ">= 0.6"
549
  }
550
  },
 
 
 
 
 
 
 
 
 
 
551
  "node_modules/express": {
552
  "version": "4.21.2",
553
  "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
@@ -645,11 +1157,67 @@
645
  "node": ">= 0.8"
646
  }
647
  },
648
- "node_modules/finalhandler": {
649
- "version": "1.3.1",
650
- "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
651
- "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
652
- "license": "MIT",
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
653
  "dependencies": {
654
  "debug": "2.6.9",
655
  "encodeurl": "~2.0.0",
@@ -683,6 +1251,22 @@
683
  }
684
  }
685
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
686
  "node_modules/form-data": {
687
  "version": "4.0.2",
688
  "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
@@ -698,6 +1282,18 @@
698
  "node": ">= 6"
699
  }
700
  },
 
 
 
 
 
 
 
 
 
 
 
 
701
  "node_modules/forwarded": {
702
  "version": "0.2.0",
703
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
@@ -762,6 +1358,50 @@
762
  "node": ">= 0.4"
763
  }
764
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
765
  "node_modules/gopd": {
766
  "version": "1.2.0",
767
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
@@ -848,6 +1488,12 @@
848
  "node": ">= 0.8"
849
  }
850
  },
 
 
 
 
 
 
851
  "node_modules/iconv-lite": {
852
  "version": "0.6.3",
853
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
@@ -860,12 +1506,38 @@
860
  "node": ">=0.10.0"
861
  }
862
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
863
  "node_modules/inherits": {
864
  "version": "2.0.4",
865
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
866
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
867
  "license": "ISC"
868
  },
 
 
 
 
 
 
869
  "node_modules/ipaddr.js": {
870
  "version": "1.9.1",
871
  "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
@@ -875,6 +1547,115 @@
875
  "node": ">= 0.10"
876
  }
877
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
878
  "node_modules/math-intrinsics": {
879
  "version": "1.1.0",
880
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
@@ -893,6 +1674,25 @@
893
  "node": ">= 0.6"
894
  }
895
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
896
  "node_modules/merge-descriptors": {
897
  "version": "1.0.3",
898
  "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
@@ -944,6 +1744,36 @@
944
  "node": ">= 0.6"
945
  }
946
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
947
  "node_modules/ms": {
948
  "version": "2.0.0",
949
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
@@ -959,6 +1789,81 @@
959
  "node": ">= 0.6"
960
  }
961
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
962
  "node_modules/nth-check": {
963
  "version": "2.1.1",
964
  "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
@@ -1004,6 +1909,12 @@
1004
  "node": ">= 0.8"
1005
  }
1006
  },
 
 
 
 
 
 
1007
  "node_modules/parse5": {
1008
  "version": "7.2.1",
1009
  "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
@@ -1050,12 +1961,56 @@
1050
  "node": ">= 0.8"
1051
  }
1052
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1053
  "node_modules/path-to-regexp": {
1054
  "version": "0.1.12",
1055
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
1056
  "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
1057
  "license": "MIT"
1058
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1059
  "node_modules/proxy-addr": {
1060
  "version": "2.0.7",
1061
  "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
@@ -1114,6 +2069,15 @@
1114
  "node": ">= 0.8"
1115
  }
1116
  },
 
 
 
 
 
 
 
 
 
1117
  "node_modules/safe-buffer": {
1118
  "version": "5.2.1",
1119
  "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
@@ -1140,6 +2104,18 @@
1140
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
1141
  "license": "MIT"
1142
  },
 
 
 
 
 
 
 
 
 
 
 
 
1143
  "node_modules/send": {
1144
  "version": "0.19.0",
1145
  "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
@@ -1200,6 +2176,27 @@
1200
  "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
1201
  "license": "ISC"
1202
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1203
  "node_modules/side-channel": {
1204
  "version": "1.1.0",
1205
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
@@ -1272,6 +2269,30 @@
1272
  "url": "https://github.com/sponsors/ljharb"
1273
  }
1274
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1275
  "node_modules/statuses": {
1276
  "version": "2.0.1",
1277
  "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
@@ -1281,6 +2302,137 @@
1281
  "node": ">= 0.8"
1282
  }
1283
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1284
  "node_modules/toidentifier": {
1285
  "version": "1.0.1",
1286
  "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
@@ -1290,6 +2442,37 @@
1290
  "node": ">=0.6"
1291
  }
1292
  },
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1293
  "node_modules/type-is": {
1294
  "version": "1.6.18",
1295
  "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
@@ -1303,6 +2486,18 @@
1303
  "node": ">= 0.6"
1304
  }
1305
  },
 
 
 
 
 
 
 
 
 
 
 
 
1306
  "node_modules/undici": {
1307
  "version": "6.21.2",
1308
  "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz",
@@ -1339,6 +2534,15 @@
1339
  "node": ">= 0.8"
1340
  }
1341
  },
 
 
 
 
 
 
 
 
 
1342
  "node_modules/whatwg-encoding": {
1343
  "version": "3.1.1",
1344
  "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
@@ -1359,6 +2563,186 @@
1359
  "engines": {
1360
  "node": ">=18"
1361
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1362
  }
1363
  }
1364
  }
 
11
  "dependencies": {
12
  "axios": "^1.8.4",
13
  "body-parser": "^2.2.0",
14
+ "browser-id3-writer": "^6.2.0",
15
  "cheerio": "^1.0.0",
16
  "cors": "^2.8.5",
17
  "dotenv": "^16.4.7",
18
+ "express": "^4.21.2",
19
+ "file-type": "^20.4.1",
20
+ "js-beautify": "^1.15.4",
21
+ "node-fetch": "^3.3.2",
22
+ "similarity": "^1.2.1",
23
+ "yt-search": "^2.12.1"
24
+ }
25
+ },
26
+ "node_modules/@isaacs/cliui": {
27
+ "version": "8.0.2",
28
+ "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz",
29
+ "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==",
30
+ "license": "ISC",
31
+ "dependencies": {
32
+ "string-width": "^5.1.2",
33
+ "string-width-cjs": "npm:string-width@^4.2.0",
34
+ "strip-ansi": "^7.0.1",
35
+ "strip-ansi-cjs": "npm:strip-ansi@^6.0.1",
36
+ "wrap-ansi": "^8.1.0",
37
+ "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0"
38
+ },
39
+ "engines": {
40
+ "node": ">=12"
41
+ }
42
+ },
43
+ "node_modules/@isaacs/cliui/node_modules/ansi-regex": {
44
+ "version": "6.1.0",
45
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
46
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
47
+ "license": "MIT",
48
+ "engines": {
49
+ "node": ">=12"
50
+ },
51
+ "funding": {
52
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
53
+ }
54
+ },
55
+ "node_modules/@isaacs/cliui/node_modules/emoji-regex": {
56
+ "version": "9.2.2",
57
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
58
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
59
+ "license": "MIT"
60
+ },
61
+ "node_modules/@isaacs/cliui/node_modules/string-width": {
62
+ "version": "5.1.2",
63
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
64
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
65
+ "license": "MIT",
66
+ "dependencies": {
67
+ "eastasianwidth": "^0.2.0",
68
+ "emoji-regex": "^9.2.2",
69
+ "strip-ansi": "^7.0.1"
70
+ },
71
+ "engines": {
72
+ "node": ">=12"
73
+ },
74
+ "funding": {
75
+ "url": "https://github.com/sponsors/sindresorhus"
76
+ }
77
+ },
78
+ "node_modules/@isaacs/cliui/node_modules/strip-ansi": {
79
+ "version": "7.1.0",
80
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
81
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
82
+ "license": "MIT",
83
+ "dependencies": {
84
+ "ansi-regex": "^6.0.1"
85
+ },
86
+ "engines": {
87
+ "node": ">=12"
88
+ },
89
+ "funding": {
90
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
91
+ }
92
+ },
93
+ "node_modules/@one-ini/wasm": {
94
+ "version": "0.1.1",
95
+ "resolved": "https://registry.npmjs.org/@one-ini/wasm/-/wasm-0.1.1.tgz",
96
+ "integrity": "sha512-XuySG1E38YScSJoMlqovLru4KTUNSjgVTIjyh7qMX6aNN5HY5Ct5LhRJdxO79JtTzKfzV/bnWpz+zquYrISsvw==",
97
+ "license": "MIT"
98
+ },
99
+ "node_modules/@pkgjs/parseargs": {
100
+ "version": "0.11.0",
101
+ "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz",
102
+ "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==",
103
+ "license": "MIT",
104
+ "optional": true,
105
+ "engines": {
106
+ "node": ">=14"
107
+ }
108
+ },
109
+ "node_modules/@tokenizer/inflate": {
110
+ "version": "0.2.7",
111
+ "resolved": "https://registry.npmjs.org/@tokenizer/inflate/-/inflate-0.2.7.tgz",
112
+ "integrity": "sha512-MADQgmZT1eKjp06jpI2yozxaU9uVs4GzzgSL+uEq7bVcJ9V1ZXQkeGNql1fsSI0gMy1vhvNTNbUqrx+pZfJVmg==",
113
+ "license": "MIT",
114
+ "dependencies": {
115
+ "debug": "^4.4.0",
116
+ "fflate": "^0.8.2",
117
+ "token-types": "^6.0.0"
118
+ },
119
+ "engines": {
120
+ "node": ">=18"
121
+ },
122
+ "funding": {
123
+ "type": "github",
124
+ "url": "https://github.com/sponsors/Borewit"
125
+ }
126
+ },
127
+ "node_modules/@tokenizer/inflate/node_modules/debug": {
128
+ "version": "4.4.0",
129
+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz",
130
+ "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==",
131
+ "license": "MIT",
132
+ "dependencies": {
133
+ "ms": "^2.1.3"
134
+ },
135
+ "engines": {
136
+ "node": ">=6.0"
137
+ },
138
+ "peerDependenciesMeta": {
139
+ "supports-color": {
140
+ "optional": true
141
+ }
142
+ }
143
+ },
144
+ "node_modules/@tokenizer/inflate/node_modules/ms": {
145
+ "version": "2.1.3",
146
+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
147
+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
148
+ "license": "MIT"
149
+ },
150
+ "node_modules/@tokenizer/token": {
151
+ "version": "0.3.0",
152
+ "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz",
153
+ "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==",
154
+ "license": "MIT"
155
+ },
156
+ "node_modules/abbrev": {
157
+ "version": "2.0.0",
158
+ "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz",
159
+ "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==",
160
+ "license": "ISC",
161
+ "engines": {
162
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
163
  }
164
  },
165
  "node_modules/accepts": {
 
175
  "node": ">= 0.6"
176
  }
177
  },
178
+ "node_modules/ansi-regex": {
179
+ "version": "2.1.1",
180
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-2.1.1.tgz",
181
+ "integrity": "sha512-TIGnTpdo+E3+pCyAluZvtED5p5wCqLdezCyhPZzKPcxvFplEt4i+W7OONCKgeZFT3+y5NZZfOOS/Bdcanm1MYA==",
182
+ "license": "MIT",
183
+ "engines": {
184
+ "node": ">=0.10.0"
185
+ }
186
+ },
187
+ "node_modules/ansi-styles": {
188
+ "version": "6.2.1",
189
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz",
190
+ "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==",
191
+ "license": "MIT",
192
+ "engines": {
193
+ "node": ">=12"
194
+ },
195
+ "funding": {
196
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
197
+ }
198
+ },
199
  "node_modules/array-flatten": {
200
  "version": "1.1.1",
201
  "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz",
202
  "integrity": "sha512-PCVAQswWemu6UdxsDFFX/+gVeYqKAod3D3UVm91jHwynguOwAvYPhx8nNlM++NqRcK6CxxpUafjmhIdKiHibqg==",
203
  "license": "MIT"
204
  },
205
+ "node_modules/async.parallellimit": {
206
+ "version": "0.5.2",
207
+ "resolved": "https://registry.npmjs.org/async.parallellimit/-/async.parallellimit-0.5.2.tgz",
208
+ "integrity": "sha512-4Di2nFsb3jL7aUIICvRSvtw/oynpMIx0JrwYn5hqJI661Dd+mYBi2ElOukOQgRHihU1SCTapb86Vx/Snva5M1w==",
209
+ "license": "MIT",
210
+ "dependencies": {
211
+ "async.util.eachoflimit": "0.5.2",
212
+ "async.util.parallel": "0.5.2"
213
+ }
214
+ },
215
+ "node_modules/async.util.eachoflimit": {
216
+ "version": "0.5.2",
217
+ "resolved": "https://registry.npmjs.org/async.util.eachoflimit/-/async.util.eachoflimit-0.5.2.tgz",
218
+ "integrity": "sha512-oZksH0sBW0AEOJKgBCQ79io9DZruoRBLTAea/Ik36pejR7pDpByvtXeuJsoZdPwSVslsrQcsUfucbUaiXYBnAQ==",
219
+ "license": "MIT",
220
+ "dependencies": {
221
+ "async.util.keyiterator": "0.5.2",
222
+ "async.util.noop": "0.5.2",
223
+ "async.util.once": "0.5.2",
224
+ "async.util.onlyonce": "0.5.2"
225
+ }
226
+ },
227
+ "node_modules/async.util.isarray": {
228
+ "version": "0.5.2",
229
+ "resolved": "https://registry.npmjs.org/async.util.isarray/-/async.util.isarray-0.5.2.tgz",
230
+ "integrity": "sha512-wbUzlrwON8RUgi+v/rhF0U99Ce8Osjcn+JP/mFNg6ymvShcobAOvE6cvLajSY5dPqKCOE1xfdhefgBif11zZgw==",
231
+ "license": "MIT"
232
+ },
233
+ "node_modules/async.util.isarraylike": {
234
+ "version": "0.5.2",
235
+ "resolved": "https://registry.npmjs.org/async.util.isarraylike/-/async.util.isarraylike-0.5.2.tgz",
236
+ "integrity": "sha512-DbFpsz3ZFNkohAW8IpGTlm8gotU32zpqe3Y2XkEA/G3XNO6rmUTKPpo7XgXUruoI+AsGi8+0zWpJHe7t1sLiAg==",
237
+ "license": "MIT",
238
+ "dependencies": {
239
+ "async.util.isarray": "0.5.2"
240
+ }
241
+ },
242
+ "node_modules/async.util.keyiterator": {
243
+ "version": "0.5.2",
244
+ "resolved": "https://registry.npmjs.org/async.util.keyiterator/-/async.util.keyiterator-0.5.2.tgz",
245
+ "integrity": "sha512-cktrETawCwgu13y3KZs2uMGFnNHc+IjKPZsavtRaoCjLELkePb2co4zrr+ghPvEqLXZIJPTKqC2HFZgJTssMVw==",
246
+ "license": "MIT",
247
+ "dependencies": {
248
+ "async.util.isarraylike": "0.5.2",
249
+ "async.util.keys": "0.5.2"
250
+ }
251
+ },
252
+ "node_modules/async.util.keys": {
253
+ "version": "0.5.2",
254
+ "resolved": "https://registry.npmjs.org/async.util.keys/-/async.util.keys-0.5.2.tgz",
255
+ "integrity": "sha512-umCOCRCRYwIC2Ho3fbuhKwIIe7OhQsVoVKGoF5GoQiGJUmjP4TG0Bmmcdpm7yW/znoIGKpnjKzVQz0niH4tfqw==",
256
+ "license": "MIT"
257
+ },
258
+ "node_modules/async.util.noop": {
259
+ "version": "0.5.2",
260
+ "resolved": "https://registry.npmjs.org/async.util.noop/-/async.util.noop-0.5.2.tgz",
261
+ "integrity": "sha512-AdwShXwE0KoskgqVJAck8zcM32nIHj3AC8ZN62ZaR5srhrY235Nw18vOJZWxcOfhxdVM0hRVKM8kMx7lcl7cCQ==",
262
+ "license": "MIT"
263
+ },
264
+ "node_modules/async.util.once": {
265
+ "version": "0.5.2",
266
+ "resolved": "https://registry.npmjs.org/async.util.once/-/async.util.once-0.5.2.tgz",
267
+ "integrity": "sha512-YQ5WPzDTt2jlblUDkq2I5RV/KiAJErJ4/0cEFhYPaZzqIuF/xDzdGvnEKe7UeuoMszsVPeajzcpKgkbwdb9MUA==",
268
+ "license": "MIT"
269
+ },
270
+ "node_modules/async.util.onlyonce": {
271
+ "version": "0.5.2",
272
+ "resolved": "https://registry.npmjs.org/async.util.onlyonce/-/async.util.onlyonce-0.5.2.tgz",
273
+ "integrity": "sha512-UgQvkU9JZ+I0Cm1f56XyGXcII+J3d/5XWUuHpcevlItuA3WFSJcqZrsyAUck2FkRSD8BwYQX1zUTDp3SJMVESg==",
274
+ "license": "MIT"
275
+ },
276
+ "node_modules/async.util.parallel": {
277
+ "version": "0.5.2",
278
+ "resolved": "https://registry.npmjs.org/async.util.parallel/-/async.util.parallel-0.5.2.tgz",
279
+ "integrity": "sha512-0bEvwmQ8fxsTYNwacw5iq0i3PvGryRkXxZ01Rvox21izdMdls9IH2rAZjfunbgI8j6nFRyIdCmMINQ9kka99ow==",
280
+ "license": "MIT",
281
+ "dependencies": {
282
+ "async.util.isarraylike": "0.5.2",
283
+ "async.util.noop": "0.5.2",
284
+ "async.util.restparam": "0.5.2"
285
+ }
286
+ },
287
+ "node_modules/async.util.restparam": {
288
+ "version": "0.5.2",
289
+ "resolved": "https://registry.npmjs.org/async.util.restparam/-/async.util.restparam-0.5.2.tgz",
290
+ "integrity": "sha512-Q9Z+zgmtMxFX5i7CnBvNOkgrL5hptztCqwarQluyNudUUk4iCmyjmsQl8MuQEjNh3gGqP5ayvDaextL1VXXgIg==",
291
+ "license": "MIT"
292
+ },
293
  "node_modules/asynckit": {
294
  "version": "0.4.0",
295
  "resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
 
307
  "proxy-from-env": "^1.1.0"
308
  }
309
  },
310
+ "node_modules/balanced-match": {
311
+ "version": "1.0.2",
312
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
313
+ "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
314
+ "license": "MIT"
315
+ },
316
  "node_modules/body-parser": {
317
  "version": "2.2.0",
318
  "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-2.2.0.tgz",
 
421
  "integrity": "sha512-JZOSA7Mo9sNGB8+UjSgzdLtokWAky1zbztM3WRLCbZ70/3cTANmQmOdR7y2g+J0e2WXywy1yS468tY+IruqEww==",
422
  "license": "ISC"
423
  },
424
+ "node_modules/boolstring": {
425
+ "version": "1.0.2",
426
+ "resolved": "https://registry.npmjs.org/boolstring/-/boolstring-1.0.2.tgz",
427
+ "integrity": "sha512-0JLNSmZUv1m/O8sVayFm2t0naiOXwQ9O2Gq9u1eoIkhvu6U5NQER/e3k4BGpjZ33G775lWMT7TzJ7r5VtmEnbQ==",
428
+ "license": "MIT"
429
+ },
430
+ "node_modules/brace-expansion": {
431
+ "version": "1.1.11",
432
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
433
+ "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
434
+ "license": "MIT",
435
+ "dependencies": {
436
+ "balanced-match": "^1.0.0",
437
+ "concat-map": "0.0.1"
438
+ }
439
+ },
440
+ "node_modules/browser-id3-writer": {
441
+ "version": "6.2.0",
442
+ "resolved": "https://registry.npmjs.org/browser-id3-writer/-/browser-id3-writer-6.2.0.tgz",
443
+ "integrity": "sha512-1tZPvkQ1LpGLS/bLXtic/rUkcOjfZpfvPcSxyMBnt7eA1VmNiKeJjKj3m/0UhNLOOp84fEn9uOuGS827CYQjlg==",
444
+ "license": "MIT"
445
+ },
446
  "node_modules/bytes": {
447
  "version": "3.1.2",
448
  "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz",
 
523
  "url": "https://github.com/sponsors/fb55"
524
  }
525
  },
526
+ "node_modules/cli-color": {
527
+ "version": "1.2.0",
528
+ "resolved": "https://registry.npmjs.org/cli-color/-/cli-color-1.2.0.tgz",
529
+ "integrity": "sha512-AqfwItf/UqGif3FBErI3NHX04v5ywJtGYlL5z4OqWR50u7g+Fz3Xw2qcCIbKVPrqtJCBwSOkDgnSlHbcpwDKHw==",
530
+ "license": "MIT",
531
+ "dependencies": {
532
+ "ansi-regex": "^2.1.1",
533
+ "d": "1",
534
+ "es5-ext": "^0.10.12",
535
+ "es6-iterator": "2",
536
+ "memoizee": "^0.4.3",
537
+ "timers-ext": "0.1"
538
+ }
539
+ },
540
+ "node_modules/color-convert": {
541
+ "version": "2.0.1",
542
+ "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
543
+ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
544
+ "license": "MIT",
545
+ "dependencies": {
546
+ "color-name": "~1.1.4"
547
+ },
548
+ "engines": {
549
+ "node": ">=7.0.0"
550
+ }
551
+ },
552
+ "node_modules/color-name": {
553
+ "version": "1.1.4",
554
+ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
555
+ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
556
+ "license": "MIT"
557
+ },
558
  "node_modules/combined-stream": {
559
  "version": "1.0.8",
560
  "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
 
567
  "node": ">= 0.8"
568
  }
569
  },
570
+ "node_modules/commander": {
571
+ "version": "10.0.1",
572
+ "resolved": "https://registry.npmjs.org/commander/-/commander-10.0.1.tgz",
573
+ "integrity": "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==",
574
+ "license": "MIT",
575
+ "engines": {
576
+ "node": ">=14"
577
+ }
578
+ },
579
+ "node_modules/concat-map": {
580
+ "version": "0.0.1",
581
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
582
+ "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
583
+ "license": "MIT"
584
+ },
585
+ "node_modules/config-chain": {
586
+ "version": "1.1.13",
587
+ "resolved": "https://registry.npmjs.org/config-chain/-/config-chain-1.1.13.tgz",
588
+ "integrity": "sha512-qj+f8APARXHrM0hraqXYb2/bOVSV4PvJQlNZ/DVj0QrmNM2q2euizkeuVckQ57J+W0mRH6Hvi+k50M4Jul2VRQ==",
589
+ "license": "MIT",
590
+ "dependencies": {
591
+ "ini": "^1.3.4",
592
+ "proto-list": "~1.2.1"
593
+ }
594
+ },
595
  "node_modules/content-disposition": {
596
  "version": "0.5.4",
597
  "resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
 
641
  "node": ">= 0.10"
642
  }
643
  },
644
+ "node_modules/cross-spawn": {
645
+ "version": "7.0.6",
646
+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
647
+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
648
+ "license": "MIT",
649
+ "dependencies": {
650
+ "path-key": "^3.1.0",
651
+ "shebang-command": "^2.0.0",
652
+ "which": "^2.0.1"
653
+ },
654
+ "engines": {
655
+ "node": ">= 8"
656
+ }
657
+ },
658
  "node_modules/css-select": {
659
  "version": "5.1.0",
660
  "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz",
 
683
  "url": "https://github.com/sponsors/fb55"
684
  }
685
  },
686
+ "node_modules/d": {
687
+ "version": "1.0.2",
688
+ "resolved": "https://registry.npmjs.org/d/-/d-1.0.2.tgz",
689
+ "integrity": "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw==",
690
+ "license": "ISC",
691
+ "dependencies": {
692
+ "es5-ext": "^0.10.64",
693
+ "type": "^2.7.2"
694
+ },
695
+ "engines": {
696
+ "node": ">=0.12"
697
+ }
698
+ },
699
+ "node_modules/dasu": {
700
+ "version": "0.4.3",
701
+ "resolved": "https://registry.npmjs.org/dasu/-/dasu-0.4.3.tgz",
702
+ "integrity": "sha512-AFwspl5k7V8MW8H7tyIGJ0gtOauUg7JC+DgiRFUIXvPNNDFXTMtvnCkZY0macN6JLGqBjNP38WVnQN7Iv3RSlg==",
703
+ "license": "MIT"
704
+ },
705
+ "node_modules/data-uri-to-buffer": {
706
+ "version": "4.0.1",
707
+ "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-4.0.1.tgz",
708
+ "integrity": "sha512-0R9ikRb668HB7QDxT1vkpuUBtqc53YyAwMwGeUFKRojY/NWKvdZ+9UYtRfGmhqNbRkTSVpMbmyhXipFFv2cb/A==",
709
+ "license": "MIT",
710
+ "engines": {
711
+ "node": ">= 12"
712
+ }
713
+ },
714
  "node_modules/debug": {
715
  "version": "2.6.9",
716
  "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz",
 
829
  "node": ">= 0.4"
830
  }
831
  },
832
+ "node_modules/eastasianwidth": {
833
+ "version": "0.2.0",
834
+ "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz",
835
+ "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==",
836
+ "license": "MIT"
837
+ },
838
+ "node_modules/editorconfig": {
839
+ "version": "1.0.4",
840
+ "resolved": "https://registry.npmjs.org/editorconfig/-/editorconfig-1.0.4.tgz",
841
+ "integrity": "sha512-L9Qe08KWTlqYMVvMcTIvMAdl1cDUubzRNYL+WfA4bLDMHe4nemKkpmYzkznE1FwLKu0EEmy6obgQKzMJrg4x9Q==",
842
+ "license": "MIT",
843
+ "dependencies": {
844
+ "@one-ini/wasm": "0.1.1",
845
+ "commander": "^10.0.0",
846
+ "minimatch": "9.0.1",
847
+ "semver": "^7.5.3"
848
+ },
849
+ "bin": {
850
+ "editorconfig": "bin/editorconfig"
851
+ },
852
+ "engines": {
853
+ "node": ">=14"
854
+ }
855
+ },
856
+ "node_modules/editorconfig/node_modules/brace-expansion": {
857
+ "version": "2.0.1",
858
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
859
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
860
+ "license": "MIT",
861
+ "dependencies": {
862
+ "balanced-match": "^1.0.0"
863
+ }
864
+ },
865
+ "node_modules/editorconfig/node_modules/minimatch": {
866
+ "version": "9.0.1",
867
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.1.tgz",
868
+ "integrity": "sha512-0jWhJpD/MdhPXwPuiRkCbfYfSKp2qnn2eOc279qI7f+osl/l+prKSrvhg157zSYvx/1nmgn2NqdT6k2Z7zSH9w==",
869
+ "license": "ISC",
870
+ "dependencies": {
871
+ "brace-expansion": "^2.0.1"
872
+ },
873
+ "engines": {
874
+ "node": ">=16 || 14 >=14.17"
875
+ },
876
+ "funding": {
877
+ "url": "https://github.com/sponsors/isaacs"
878
+ }
879
+ },
880
  "node_modules/ee-first": {
881
  "version": "1.1.1",
882
  "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz",
883
  "integrity": "sha512-WMwm9LhRUo+WUaRN+vRuETqG89IgZphVSNkdFgeb6sS/E4OrDIN7t48CAewSHXc6C8lefD8KKfr5vY61brQlow==",
884
  "license": "MIT"
885
  },
886
+ "node_modules/emoji-regex": {
887
+ "version": "8.0.0",
888
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz",
889
+ "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==",
890
+ "license": "MIT"
891
+ },
892
  "node_modules/encodeurl": {
893
  "version": "2.0.0",
894
  "resolved": "https://registry.npmjs.org/encodeurl/-/encodeurl-2.0.0.tgz",
 
968
  "node": ">= 0.4"
969
  }
970
  },
971
+ "node_modules/es5-ext": {
972
+ "version": "0.10.64",
973
+ "resolved": "https://registry.npmjs.org/es5-ext/-/es5-ext-0.10.64.tgz",
974
+ "integrity": "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg==",
975
+ "hasInstallScript": true,
976
+ "license": "ISC",
977
+ "dependencies": {
978
+ "es6-iterator": "^2.0.3",
979
+ "es6-symbol": "^3.1.3",
980
+ "esniff": "^2.0.1",
981
+ "next-tick": "^1.1.0"
982
+ },
983
+ "engines": {
984
+ "node": ">=0.10"
985
+ }
986
+ },
987
+ "node_modules/es6-iterator": {
988
+ "version": "2.0.3",
989
+ "resolved": "https://registry.npmjs.org/es6-iterator/-/es6-iterator-2.0.3.tgz",
990
+ "integrity": "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g==",
991
+ "license": "MIT",
992
+ "dependencies": {
993
+ "d": "1",
994
+ "es5-ext": "^0.10.35",
995
+ "es6-symbol": "^3.1.1"
996
+ }
997
+ },
998
+ "node_modules/es6-symbol": {
999
+ "version": "3.1.4",
1000
+ "resolved": "https://registry.npmjs.org/es6-symbol/-/es6-symbol-3.1.4.tgz",
1001
+ "integrity": "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg==",
1002
+ "license": "ISC",
1003
+ "dependencies": {
1004
+ "d": "^1.0.2",
1005
+ "ext": "^1.7.0"
1006
+ },
1007
+ "engines": {
1008
+ "node": ">=0.12"
1009
+ }
1010
+ },
1011
+ "node_modules/es6-weak-map": {
1012
+ "version": "2.0.3",
1013
+ "resolved": "https://registry.npmjs.org/es6-weak-map/-/es6-weak-map-2.0.3.tgz",
1014
+ "integrity": "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA==",
1015
+ "license": "ISC",
1016
+ "dependencies": {
1017
+ "d": "1",
1018
+ "es5-ext": "^0.10.46",
1019
+ "es6-iterator": "^2.0.3",
1020
+ "es6-symbol": "^3.1.1"
1021
+ }
1022
+ },
1023
  "node_modules/escape-html": {
1024
  "version": "1.0.3",
1025
  "resolved": "https://registry.npmjs.org/escape-html/-/escape-html-1.0.3.tgz",
1026
  "integrity": "sha512-NiSupZ4OeuGwr68lGIeym/ksIZMJodUGOSCZ/FSnTxcrekbvqrgdUxlJOMpijaKZVjAJrWrGs/6Jy8OMuyj9ow==",
1027
  "license": "MIT"
1028
  },
1029
+ "node_modules/esniff": {
1030
+ "version": "2.0.1",
1031
+ "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz",
1032
+ "integrity": "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==",
1033
+ "license": "ISC",
1034
+ "dependencies": {
1035
+ "d": "^1.0.1",
1036
+ "es5-ext": "^0.10.62",
1037
+ "event-emitter": "^0.3.5",
1038
+ "type": "^2.7.2"
1039
+ },
1040
+ "engines": {
1041
+ "node": ">=0.10"
1042
+ }
1043
+ },
1044
  "node_modules/etag": {
1045
  "version": "1.8.1",
1046
  "resolved": "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz",
 
1050
  "node": ">= 0.6"
1051
  }
1052
  },
1053
+ "node_modules/event-emitter": {
1054
+ "version": "0.3.5",
1055
+ "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz",
1056
+ "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==",
1057
+ "license": "MIT",
1058
+ "dependencies": {
1059
+ "d": "1",
1060
+ "es5-ext": "~0.10.14"
1061
+ }
1062
+ },
1063
  "node_modules/express": {
1064
  "version": "4.21.2",
1065
  "resolved": "https://registry.npmjs.org/express/-/express-4.21.2.tgz",
 
1157
  "node": ">= 0.8"
1158
  }
1159
  },
1160
+ "node_modules/ext": {
1161
+ "version": "1.7.0",
1162
+ "resolved": "https://registry.npmjs.org/ext/-/ext-1.7.0.tgz",
1163
+ "integrity": "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw==",
1164
+ "license": "ISC",
1165
+ "dependencies": {
1166
+ "type": "^2.7.2"
1167
+ }
1168
+ },
1169
+ "node_modules/fetch-blob": {
1170
+ "version": "3.2.0",
1171
+ "resolved": "https://registry.npmjs.org/fetch-blob/-/fetch-blob-3.2.0.tgz",
1172
+ "integrity": "sha512-7yAQpD2UMJzLi1Dqv7qFYnPbaPx7ZfFK6PiIxQ4PfkGPyNyl2Ugx+a/umUonmKqjhM4DnfbMvdX6otXq83soQQ==",
1173
+ "funding": [
1174
+ {
1175
+ "type": "github",
1176
+ "url": "https://github.com/sponsors/jimmywarting"
1177
+ },
1178
+ {
1179
+ "type": "paypal",
1180
+ "url": "https://paypal.me/jimmywarting"
1181
+ }
1182
+ ],
1183
+ "license": "MIT",
1184
+ "dependencies": {
1185
+ "node-domexception": "^1.0.0",
1186
+ "web-streams-polyfill": "^3.0.3"
1187
+ },
1188
+ "engines": {
1189
+ "node": "^12.20 || >= 14.13"
1190
+ }
1191
+ },
1192
+ "node_modules/fflate": {
1193
+ "version": "0.8.2",
1194
+ "resolved": "https://registry.npmjs.org/fflate/-/fflate-0.8.2.tgz",
1195
+ "integrity": "sha512-cPJU47OaAoCbg0pBvzsgpTPhmhqI5eJjh/JIu8tPj5q+T7iLvW/JAYUqmE7KOB4R1ZyEhzBaIQpQpardBF5z8A==",
1196
+ "license": "MIT"
1197
+ },
1198
+ "node_modules/file-type": {
1199
+ "version": "20.4.1",
1200
+ "resolved": "https://registry.npmjs.org/file-type/-/file-type-20.4.1.tgz",
1201
+ "integrity": "sha512-hw9gNZXUfZ02Jo0uafWLaFVPter5/k2rfcrjFJJHX/77xtSDOfJuEFb6oKlFV86FLP1SuyHMW1PSk0U9M5tKkQ==",
1202
+ "license": "MIT",
1203
+ "dependencies": {
1204
+ "@tokenizer/inflate": "^0.2.6",
1205
+ "strtok3": "^10.2.0",
1206
+ "token-types": "^6.0.0",
1207
+ "uint8array-extras": "^1.4.0"
1208
+ },
1209
+ "engines": {
1210
+ "node": ">=18"
1211
+ },
1212
+ "funding": {
1213
+ "url": "https://github.com/sindresorhus/file-type?sponsor=1"
1214
+ }
1215
+ },
1216
+ "node_modules/finalhandler": {
1217
+ "version": "1.3.1",
1218
+ "resolved": "https://registry.npmjs.org/finalhandler/-/finalhandler-1.3.1.tgz",
1219
+ "integrity": "sha512-6BN9trH7bp3qvnrRyzsBz+g3lZxTNZTbVO2EV1CS0WIcDbawYVdYvGflME/9QP0h0pYlCDBCTjYa9nZzMDpyxQ==",
1220
+ "license": "MIT",
1221
  "dependencies": {
1222
  "debug": "2.6.9",
1223
  "encodeurl": "~2.0.0",
 
1251
  }
1252
  }
1253
  },
1254
+ "node_modules/foreground-child": {
1255
+ "version": "3.3.1",
1256
+ "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.3.1.tgz",
1257
+ "integrity": "sha512-gIXjKqtFuWEgzFRJA9WCQeSJLZDjgJUOMCMzxtvFq/37KojM1BFGufqsCy0r4qSQmYLsZYMeyRqzIWOMup03sw==",
1258
+ "license": "ISC",
1259
+ "dependencies": {
1260
+ "cross-spawn": "^7.0.6",
1261
+ "signal-exit": "^4.0.1"
1262
+ },
1263
+ "engines": {
1264
+ "node": ">=14"
1265
+ },
1266
+ "funding": {
1267
+ "url": "https://github.com/sponsors/isaacs"
1268
+ }
1269
+ },
1270
  "node_modules/form-data": {
1271
  "version": "4.0.2",
1272
  "resolved": "https://registry.npmjs.org/form-data/-/form-data-4.0.2.tgz",
 
1282
  "node": ">= 6"
1283
  }
1284
  },
1285
+ "node_modules/formdata-polyfill": {
1286
+ "version": "4.0.10",
1287
+ "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz",
1288
+ "integrity": "sha512-buewHzMvYL29jdeQTVILecSaZKnt/RJWjoZCF5OW60Z67/GmSLBkOFM7qh1PI3zFNtJbaZL5eQu1vLfazOwj4g==",
1289
+ "license": "MIT",
1290
+ "dependencies": {
1291
+ "fetch-blob": "^3.1.2"
1292
+ },
1293
+ "engines": {
1294
+ "node": ">=12.20.0"
1295
+ }
1296
+ },
1297
  "node_modules/forwarded": {
1298
  "version": "0.2.0",
1299
  "resolved": "https://registry.npmjs.org/forwarded/-/forwarded-0.2.0.tgz",
 
1358
  "node": ">= 0.4"
1359
  }
1360
  },
1361
+ "node_modules/glob": {
1362
+ "version": "10.4.5",
1363
+ "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz",
1364
+ "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==",
1365
+ "license": "ISC",
1366
+ "dependencies": {
1367
+ "foreground-child": "^3.1.0",
1368
+ "jackspeak": "^3.1.2",
1369
+ "minimatch": "^9.0.4",
1370
+ "minipass": "^7.1.2",
1371
+ "package-json-from-dist": "^1.0.0",
1372
+ "path-scurry": "^1.11.1"
1373
+ },
1374
+ "bin": {
1375
+ "glob": "dist/esm/bin.mjs"
1376
+ },
1377
+ "funding": {
1378
+ "url": "https://github.com/sponsors/isaacs"
1379
+ }
1380
+ },
1381
+ "node_modules/glob/node_modules/brace-expansion": {
1382
+ "version": "2.0.1",
1383
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz",
1384
+ "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==",
1385
+ "license": "MIT",
1386
+ "dependencies": {
1387
+ "balanced-match": "^1.0.0"
1388
+ }
1389
+ },
1390
+ "node_modules/glob/node_modules/minimatch": {
1391
+ "version": "9.0.5",
1392
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz",
1393
+ "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==",
1394
+ "license": "ISC",
1395
+ "dependencies": {
1396
+ "brace-expansion": "^2.0.1"
1397
+ },
1398
+ "engines": {
1399
+ "node": ">=16 || 14 >=14.17"
1400
+ },
1401
+ "funding": {
1402
+ "url": "https://github.com/sponsors/isaacs"
1403
+ }
1404
+ },
1405
  "node_modules/gopd": {
1406
  "version": "1.2.0",
1407
  "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.2.0.tgz",
 
1488
  "node": ">= 0.8"
1489
  }
1490
  },
1491
+ "node_modules/human-time": {
1492
+ "version": "0.0.2",
1493
+ "resolved": "https://registry.npmjs.org/human-time/-/human-time-0.0.2.tgz",
1494
+ "integrity": "sha512-sbYI90YhYmstslPTb70BLGjy6mdESa0lxL7uDR4fIVAx9Iobz8fLEqi7FqF4Q/6vblrzZALg//MsYJlIPBU8SA==",
1495
+ "license": "MIT"
1496
+ },
1497
  "node_modules/iconv-lite": {
1498
  "version": "0.6.3",
1499
  "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz",
 
1506
  "node": ">=0.10.0"
1507
  }
1508
  },
1509
+ "node_modules/ieee754": {
1510
+ "version": "1.2.1",
1511
+ "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz",
1512
+ "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==",
1513
+ "funding": [
1514
+ {
1515
+ "type": "github",
1516
+ "url": "https://github.com/sponsors/feross"
1517
+ },
1518
+ {
1519
+ "type": "patreon",
1520
+ "url": "https://www.patreon.com/feross"
1521
+ },
1522
+ {
1523
+ "type": "consulting",
1524
+ "url": "https://feross.org/support"
1525
+ }
1526
+ ],
1527
+ "license": "BSD-3-Clause"
1528
+ },
1529
  "node_modules/inherits": {
1530
  "version": "2.0.4",
1531
  "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
1532
  "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
1533
  "license": "ISC"
1534
  },
1535
+ "node_modules/ini": {
1536
+ "version": "1.3.8",
1537
+ "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.8.tgz",
1538
+ "integrity": "sha512-JV/yugV2uzW5iMRSiZAyDtQd+nxtUnjeLt0acNdw98kKLrvuRVyB80tsREOE7yvGVgalhZ6RNXCmEHkUKBKxew==",
1539
+ "license": "ISC"
1540
+ },
1541
  "node_modules/ipaddr.js": {
1542
  "version": "1.9.1",
1543
  "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz",
 
1547
  "node": ">= 0.10"
1548
  }
1549
  },
1550
+ "node_modules/is-fullwidth-code-point": {
1551
+ "version": "2.0.0",
1552
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
1553
+ "integrity": "sha512-VHskAKYM8RfSFXwee5t5cbN5PZeq1Wrh6qd5bkyiXIf6UQcN6w/A0eXM9r6t8d+GYOh+o6ZhiEnb88LN/Y8m2w==",
1554
+ "license": "MIT",
1555
+ "engines": {
1556
+ "node": ">=4"
1557
+ }
1558
+ },
1559
+ "node_modules/is-promise": {
1560
+ "version": "2.2.2",
1561
+ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz",
1562
+ "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==",
1563
+ "license": "MIT"
1564
+ },
1565
+ "node_modules/isexe": {
1566
+ "version": "2.0.0",
1567
+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1568
+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1569
+ "license": "ISC"
1570
+ },
1571
+ "node_modules/jackspeak": {
1572
+ "version": "3.4.3",
1573
+ "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz",
1574
+ "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==",
1575
+ "license": "BlueOak-1.0.0",
1576
+ "dependencies": {
1577
+ "@isaacs/cliui": "^8.0.2"
1578
+ },
1579
+ "funding": {
1580
+ "url": "https://github.com/sponsors/isaacs"
1581
+ },
1582
+ "optionalDependencies": {
1583
+ "@pkgjs/parseargs": "^0.11.0"
1584
+ }
1585
+ },
1586
+ "node_modules/js-beautify": {
1587
+ "version": "1.15.4",
1588
+ "resolved": "https://registry.npmjs.org/js-beautify/-/js-beautify-1.15.4.tgz",
1589
+ "integrity": "sha512-9/KXeZUKKJwqCXUdBxFJ3vPh467OCckSBmYDwSK/EtV090K+iMJ7zx2S3HLVDIWFQdqMIsZWbnaGiba18aWhaA==",
1590
+ "license": "MIT",
1591
+ "dependencies": {
1592
+ "config-chain": "^1.1.13",
1593
+ "editorconfig": "^1.0.4",
1594
+ "glob": "^10.4.2",
1595
+ "js-cookie": "^3.0.5",
1596
+ "nopt": "^7.2.1"
1597
+ },
1598
+ "bin": {
1599
+ "css-beautify": "js/bin/css-beautify.js",
1600
+ "html-beautify": "js/bin/html-beautify.js",
1601
+ "js-beautify": "js/bin/js-beautify.js"
1602
+ },
1603
+ "engines": {
1604
+ "node": ">=14"
1605
+ }
1606
+ },
1607
+ "node_modules/js-cookie": {
1608
+ "version": "3.0.5",
1609
+ "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-3.0.5.tgz",
1610
+ "integrity": "sha512-cEiJEAEoIbWfCZYKWhVwFuvPX1gETRYPw6LlaTKoxD3s2AkXzkCjnp6h0V77ozyqj0jakteJ4YqDJT830+lVGw==",
1611
+ "license": "MIT",
1612
+ "engines": {
1613
+ "node": ">=14"
1614
+ }
1615
+ },
1616
+ "node_modules/jsonpath-plus": {
1617
+ "version": "5.0.7",
1618
+ "resolved": "https://registry.npmjs.org/jsonpath-plus/-/jsonpath-plus-5.0.7.tgz",
1619
+ "integrity": "sha512-7TS6wsiw1s2UMK/A6nA4n0aUJuirCVhJ87nWX5je5MPOl0z5VTr2qs7nMP8NZ2ed3rlt6kePTqddgVPE9F0i0w==",
1620
+ "license": "MIT",
1621
+ "engines": {
1622
+ "node": ">=10.0.0"
1623
+ }
1624
+ },
1625
+ "node_modules/keypress": {
1626
+ "version": "0.2.1",
1627
+ "resolved": "https://registry.npmjs.org/keypress/-/keypress-0.2.1.tgz",
1628
+ "integrity": "sha512-HjorDJFNhnM4SicvaUXac0X77NiskggxJdesG72+O5zBKpSqKFCrqmndKVqpu3pFqkla0St6uGk8Ju0sCurrmg==",
1629
+ "license": "MIT"
1630
+ },
1631
+ "node_modules/levenshtein-edit-distance": {
1632
+ "version": "2.0.5",
1633
+ "resolved": "https://registry.npmjs.org/levenshtein-edit-distance/-/levenshtein-edit-distance-2.0.5.tgz",
1634
+ "integrity": "sha512-Yuraz7QnMX/JENJU1HA6UtdsbhRzoSFnGpVGVryjQgHtl2s/YmVgmNYkVs5yzVZ9aAvQR9wPBUH3lG755ylxGA==",
1635
+ "license": "MIT",
1636
+ "bin": {
1637
+ "levenshtein-edit-distance": "cli.js"
1638
+ },
1639
+ "funding": {
1640
+ "type": "github",
1641
+ "url": "https://github.com/sponsors/wooorm"
1642
+ }
1643
+ },
1644
+ "node_modules/lru-cache": {
1645
+ "version": "10.4.3",
1646
+ "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz",
1647
+ "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==",
1648
+ "license": "ISC"
1649
+ },
1650
+ "node_modules/lru-queue": {
1651
+ "version": "0.1.0",
1652
+ "resolved": "https://registry.npmjs.org/lru-queue/-/lru-queue-0.1.0.tgz",
1653
+ "integrity": "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ==",
1654
+ "license": "MIT",
1655
+ "dependencies": {
1656
+ "es5-ext": "~0.10.2"
1657
+ }
1658
+ },
1659
  "node_modules/math-intrinsics": {
1660
  "version": "1.1.0",
1661
  "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz",
 
1674
  "node": ">= 0.6"
1675
  }
1676
  },
1677
+ "node_modules/memoizee": {
1678
+ "version": "0.4.17",
1679
+ "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz",
1680
+ "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==",
1681
+ "license": "ISC",
1682
+ "dependencies": {
1683
+ "d": "^1.0.2",
1684
+ "es5-ext": "^0.10.64",
1685
+ "es6-weak-map": "^2.0.3",
1686
+ "event-emitter": "^0.3.5",
1687
+ "is-promise": "^2.2.2",
1688
+ "lru-queue": "^0.1.0",
1689
+ "next-tick": "^1.1.0",
1690
+ "timers-ext": "^0.1.7"
1691
+ },
1692
+ "engines": {
1693
+ "node": ">=0.12"
1694
+ }
1695
+ },
1696
  "node_modules/merge-descriptors": {
1697
  "version": "1.0.3",
1698
  "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz",
 
1744
  "node": ">= 0.6"
1745
  }
1746
  },
1747
+ "node_modules/minimatch": {
1748
+ "version": "3.0.8",
1749
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.8.tgz",
1750
+ "integrity": "sha512-6FsRAQsxQ61mw+qP1ZzbL9Bc78x2p5OqNgNpnoAFLTrX8n5Kxph0CsnhmKKNXTWjXqU5L0pGPR7hYk+XWZr60Q==",
1751
+ "license": "ISC",
1752
+ "dependencies": {
1753
+ "brace-expansion": "^1.1.7"
1754
+ },
1755
+ "engines": {
1756
+ "node": "*"
1757
+ }
1758
+ },
1759
+ "node_modules/minimist": {
1760
+ "version": "1.2.8",
1761
+ "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz",
1762
+ "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==",
1763
+ "license": "MIT",
1764
+ "funding": {
1765
+ "url": "https://github.com/sponsors/ljharb"
1766
+ }
1767
+ },
1768
+ "node_modules/minipass": {
1769
+ "version": "7.1.2",
1770
+ "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz",
1771
+ "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==",
1772
+ "license": "ISC",
1773
+ "engines": {
1774
+ "node": ">=16 || 14 >=14.17"
1775
+ }
1776
+ },
1777
  "node_modules/ms": {
1778
  "version": "2.0.0",
1779
  "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
 
1789
  "node": ">= 0.6"
1790
  }
1791
  },
1792
+ "node_modules/next-tick": {
1793
+ "version": "1.1.0",
1794
+ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz",
1795
+ "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==",
1796
+ "license": "ISC"
1797
+ },
1798
+ "node_modules/node-domexception": {
1799
+ "version": "1.0.0",
1800
+ "resolved": "https://registry.npmjs.org/node-domexception/-/node-domexception-1.0.0.tgz",
1801
+ "integrity": "sha512-/jKZoMpw0F8GRwl4/eLROPA3cfcXtLApP0QzLmUT/HuPCZWyB7IY9ZrMeKw2O/nFIqPQB3PVM9aYm0F312AXDQ==",
1802
+ "funding": [
1803
+ {
1804
+ "type": "github",
1805
+ "url": "https://github.com/sponsors/jimmywarting"
1806
+ },
1807
+ {
1808
+ "type": "github",
1809
+ "url": "https://paypal.me/jimmywarting"
1810
+ }
1811
+ ],
1812
+ "license": "MIT",
1813
+ "engines": {
1814
+ "node": ">=10.5.0"
1815
+ }
1816
+ },
1817
+ "node_modules/node-fetch": {
1818
+ "version": "3.3.2",
1819
+ "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz",
1820
+ "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==",
1821
+ "license": "MIT",
1822
+ "dependencies": {
1823
+ "data-uri-to-buffer": "^4.0.0",
1824
+ "fetch-blob": "^3.1.4",
1825
+ "formdata-polyfill": "^4.0.10"
1826
+ },
1827
+ "engines": {
1828
+ "node": "^12.20.0 || ^14.13.1 || >=16.0.0"
1829
+ },
1830
+ "funding": {
1831
+ "type": "opencollective",
1832
+ "url": "https://opencollective.com/node-fetch"
1833
+ }
1834
+ },
1835
+ "node_modules/node-fzf": {
1836
+ "version": "0.5.3",
1837
+ "resolved": "https://registry.npmjs.org/node-fzf/-/node-fzf-0.5.3.tgz",
1838
+ "integrity": "sha512-crN8rRfApu/GUrtKq+zJ6LueUyNAOJpFHxoT2Ru1Q+OYRa/F/H7CXvzcMrFc7D964yakYZEZ9XR3YbdSHXgyCw==",
1839
+ "license": "MIT",
1840
+ "dependencies": {
1841
+ "cli-color": "~1.2.0",
1842
+ "keypress": "~0.2.1",
1843
+ "minimist": "~1.2.0",
1844
+ "redstar": "0.0.2",
1845
+ "string-width": "~2.1.1",
1846
+ "ttys": "0.0.3"
1847
+ },
1848
+ "bin": {
1849
+ "nfzf": "bin/cli.js"
1850
+ }
1851
+ },
1852
+ "node_modules/nopt": {
1853
+ "version": "7.2.1",
1854
+ "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz",
1855
+ "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==",
1856
+ "license": "ISC",
1857
+ "dependencies": {
1858
+ "abbrev": "^2.0.0"
1859
+ },
1860
+ "bin": {
1861
+ "nopt": "bin/nopt.js"
1862
+ },
1863
+ "engines": {
1864
+ "node": "^14.17.0 || ^16.13.0 || >=18.0.0"
1865
+ }
1866
+ },
1867
  "node_modules/nth-check": {
1868
  "version": "2.1.1",
1869
  "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
 
1909
  "node": ">= 0.8"
1910
  }
1911
  },
1912
+ "node_modules/package-json-from-dist": {
1913
+ "version": "1.0.1",
1914
+ "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz",
1915
+ "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==",
1916
+ "license": "BlueOak-1.0.0"
1917
+ },
1918
  "node_modules/parse5": {
1919
  "version": "7.2.1",
1920
  "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz",
 
1961
  "node": ">= 0.8"
1962
  }
1963
  },
1964
+ "node_modules/path-key": {
1965
+ "version": "3.1.1",
1966
+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1967
+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1968
+ "license": "MIT",
1969
+ "engines": {
1970
+ "node": ">=8"
1971
+ }
1972
+ },
1973
+ "node_modules/path-scurry": {
1974
+ "version": "1.11.1",
1975
+ "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz",
1976
+ "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==",
1977
+ "license": "BlueOak-1.0.0",
1978
+ "dependencies": {
1979
+ "lru-cache": "^10.2.0",
1980
+ "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0"
1981
+ },
1982
+ "engines": {
1983
+ "node": ">=16 || 14 >=14.18"
1984
+ },
1985
+ "funding": {
1986
+ "url": "https://github.com/sponsors/isaacs"
1987
+ }
1988
+ },
1989
  "node_modules/path-to-regexp": {
1990
  "version": "0.1.12",
1991
  "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz",
1992
  "integrity": "sha512-RA1GjUVMnvYFxuqovrEqZoxxW5NUZqbwKtYz/Tt7nXerk0LbLblQmrsgdeOxV5SFHf0UDggjS/bSeOZwt1pmEQ==",
1993
  "license": "MIT"
1994
  },
1995
+ "node_modules/peek-readable": {
1996
+ "version": "7.0.0",
1997
+ "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-7.0.0.tgz",
1998
+ "integrity": "sha512-nri2TO5JE3/mRryik9LlHFT53cgHfRK0Lt0BAZQXku/AW3E6XLt2GaY8siWi7dvW/m1z0ecn+J+bpDa9ZN3IsQ==",
1999
+ "license": "MIT",
2000
+ "engines": {
2001
+ "node": ">=18"
2002
+ },
2003
+ "funding": {
2004
+ "type": "github",
2005
+ "url": "https://github.com/sponsors/Borewit"
2006
+ }
2007
+ },
2008
+ "node_modules/proto-list": {
2009
+ "version": "1.2.4",
2010
+ "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
2011
+ "integrity": "sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==",
2012
+ "license": "ISC"
2013
+ },
2014
  "node_modules/proxy-addr": {
2015
  "version": "2.0.7",
2016
  "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz",
 
2069
  "node": ">= 0.8"
2070
  }
2071
  },
2072
+ "node_modules/redstar": {
2073
+ "version": "0.0.2",
2074
+ "resolved": "https://registry.npmjs.org/redstar/-/redstar-0.0.2.tgz",
2075
+ "integrity": "sha512-VNvLaLxMJMYiAasJX5Q/GC+Os7FXL0yPWFDuTodhR7Na9wqzrXsePPWC+EtIv4t3q5DyAK00w423xi5mQN2fqg==",
2076
+ "license": "MIT",
2077
+ "dependencies": {
2078
+ "minimatch": "~3.0.4"
2079
+ }
2080
+ },
2081
  "node_modules/safe-buffer": {
2082
  "version": "5.2.1",
2083
  "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.2.1.tgz",
 
2104
  "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
2105
  "license": "MIT"
2106
  },
2107
+ "node_modules/semver": {
2108
+ "version": "7.7.1",
2109
+ "resolved": "https://registry.npmjs.org/semver/-/semver-7.7.1.tgz",
2110
+ "integrity": "sha512-hlq8tAfn0m/61p4BVRcPzIGr6LKiMwo4VM6dGi6pt4qcRkmNzTcWq6eCEjEh+qXjkMDvPlOFFSGwQjoEa6gyMA==",
2111
+ "license": "ISC",
2112
+ "bin": {
2113
+ "semver": "bin/semver.js"
2114
+ },
2115
+ "engines": {
2116
+ "node": ">=10"
2117
+ }
2118
+ },
2119
  "node_modules/send": {
2120
  "version": "0.19.0",
2121
  "resolved": "https://registry.npmjs.org/send/-/send-0.19.0.tgz",
 
2176
  "integrity": "sha512-E5LDX7Wrp85Kil5bhZv46j8jOeboKq5JMmYM3gVGdGH8xFpPWXUMsNrlODCrkoxMEeNi/XZIwuRvY4XNwYMJpw==",
2177
  "license": "ISC"
2178
  },
2179
+ "node_modules/shebang-command": {
2180
+ "version": "2.0.0",
2181
+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
2182
+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
2183
+ "license": "MIT",
2184
+ "dependencies": {
2185
+ "shebang-regex": "^3.0.0"
2186
+ },
2187
+ "engines": {
2188
+ "node": ">=8"
2189
+ }
2190
+ },
2191
+ "node_modules/shebang-regex": {
2192
+ "version": "3.0.0",
2193
+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
2194
+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
2195
+ "license": "MIT",
2196
+ "engines": {
2197
+ "node": ">=8"
2198
+ }
2199
+ },
2200
  "node_modules/side-channel": {
2201
  "version": "1.1.0",
2202
  "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.1.0.tgz",
 
2269
  "url": "https://github.com/sponsors/ljharb"
2270
  }
2271
  },
2272
+ "node_modules/signal-exit": {
2273
+ "version": "4.1.0",
2274
+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
2275
+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
2276
+ "license": "ISC",
2277
+ "engines": {
2278
+ "node": ">=14"
2279
+ },
2280
+ "funding": {
2281
+ "url": "https://github.com/sponsors/isaacs"
2282
+ }
2283
+ },
2284
+ "node_modules/similarity": {
2285
+ "version": "1.2.1",
2286
+ "resolved": "https://registry.npmjs.org/similarity/-/similarity-1.2.1.tgz",
2287
+ "integrity": "sha512-lMOpWVaWrTnyL+tkvDs8oGV/KAUBQ3wfbZtdiwDcC+KYGlwO8kgtiyag1B6akAjALDMwn5rN5YHHei1hr4X7nw==",
2288
+ "license": "ISC",
2289
+ "dependencies": {
2290
+ "levenshtein-edit-distance": "^2.0.0"
2291
+ },
2292
+ "bin": {
2293
+ "similarity": "cli.js"
2294
+ }
2295
+ },
2296
  "node_modules/statuses": {
2297
  "version": "2.0.1",
2298
  "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz",
 
2302
  "node": ">= 0.8"
2303
  }
2304
  },
2305
+ "node_modules/string-width": {
2306
+ "version": "2.1.1",
2307
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz",
2308
+ "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==",
2309
+ "license": "MIT",
2310
+ "dependencies": {
2311
+ "is-fullwidth-code-point": "^2.0.0",
2312
+ "strip-ansi": "^4.0.0"
2313
+ },
2314
+ "engines": {
2315
+ "node": ">=4"
2316
+ }
2317
+ },
2318
+ "node_modules/string-width-cjs": {
2319
+ "name": "string-width",
2320
+ "version": "4.2.3",
2321
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2322
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2323
+ "license": "MIT",
2324
+ "dependencies": {
2325
+ "emoji-regex": "^8.0.0",
2326
+ "is-fullwidth-code-point": "^3.0.0",
2327
+ "strip-ansi": "^6.0.1"
2328
+ },
2329
+ "engines": {
2330
+ "node": ">=8"
2331
+ }
2332
+ },
2333
+ "node_modules/string-width-cjs/node_modules/ansi-regex": {
2334
+ "version": "5.0.1",
2335
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2336
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2337
+ "license": "MIT",
2338
+ "engines": {
2339
+ "node": ">=8"
2340
+ }
2341
+ },
2342
+ "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
2343
+ "version": "3.0.0",
2344
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
2345
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
2346
+ "license": "MIT",
2347
+ "engines": {
2348
+ "node": ">=8"
2349
+ }
2350
+ },
2351
+ "node_modules/string-width-cjs/node_modules/strip-ansi": {
2352
+ "version": "6.0.1",
2353
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2354
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2355
+ "license": "MIT",
2356
+ "dependencies": {
2357
+ "ansi-regex": "^5.0.1"
2358
+ },
2359
+ "engines": {
2360
+ "node": ">=8"
2361
+ }
2362
+ },
2363
+ "node_modules/strip-ansi": {
2364
+ "version": "4.0.0",
2365
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz",
2366
+ "integrity": "sha512-4XaJ2zQdCzROZDivEVIDPkcQn8LMFSa8kj8Gxb/Lnwzv9A8VctNZ+lfivC/sV3ivW8ElJTERXZoPBRrZKkNKow==",
2367
+ "license": "MIT",
2368
+ "dependencies": {
2369
+ "ansi-regex": "^3.0.0"
2370
+ },
2371
+ "engines": {
2372
+ "node": ">=4"
2373
+ }
2374
+ },
2375
+ "node_modules/strip-ansi-cjs": {
2376
+ "name": "strip-ansi",
2377
+ "version": "6.0.1",
2378
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2379
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2380
+ "license": "MIT",
2381
+ "dependencies": {
2382
+ "ansi-regex": "^5.0.1"
2383
+ },
2384
+ "engines": {
2385
+ "node": ">=8"
2386
+ }
2387
+ },
2388
+ "node_modules/strip-ansi-cjs/node_modules/ansi-regex": {
2389
+ "version": "5.0.1",
2390
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2391
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2392
+ "license": "MIT",
2393
+ "engines": {
2394
+ "node": ">=8"
2395
+ }
2396
+ },
2397
+ "node_modules/strip-ansi/node_modules/ansi-regex": {
2398
+ "version": "3.0.1",
2399
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz",
2400
+ "integrity": "sha512-+O9Jct8wf++lXxxFc4hc8LsjaSq0HFzzL7cVsw8pRDIPdjKD2mT4ytDZlLuSBZ4cLKZFXIrMGO7DbQCtMJJMKw==",
2401
+ "license": "MIT",
2402
+ "engines": {
2403
+ "node": ">=4"
2404
+ }
2405
+ },
2406
+ "node_modules/strtok3": {
2407
+ "version": "10.2.2",
2408
+ "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-10.2.2.tgz",
2409
+ "integrity": "sha512-Xt18+h4s7Z8xyZ0tmBoRmzxcop97R4BAh+dXouUDCYn+Em+1P3qpkUfI5ueWLT8ynC5hZ+q4iPEmGG1urvQGBg==",
2410
+ "license": "MIT",
2411
+ "dependencies": {
2412
+ "@tokenizer/token": "^0.3.0",
2413
+ "peek-readable": "^7.0.0"
2414
+ },
2415
+ "engines": {
2416
+ "node": ">=18"
2417
+ },
2418
+ "funding": {
2419
+ "type": "github",
2420
+ "url": "https://github.com/sponsors/Borewit"
2421
+ }
2422
+ },
2423
+ "node_modules/timers-ext": {
2424
+ "version": "0.1.8",
2425
+ "resolved": "https://registry.npmjs.org/timers-ext/-/timers-ext-0.1.8.tgz",
2426
+ "integrity": "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww==",
2427
+ "license": "ISC",
2428
+ "dependencies": {
2429
+ "es5-ext": "^0.10.64",
2430
+ "next-tick": "^1.1.0"
2431
+ },
2432
+ "engines": {
2433
+ "node": ">=0.12"
2434
+ }
2435
+ },
2436
  "node_modules/toidentifier": {
2437
  "version": "1.0.1",
2438
  "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz",
 
2442
  "node": ">=0.6"
2443
  }
2444
  },
2445
+ "node_modules/token-types": {
2446
+ "version": "6.0.0",
2447
+ "resolved": "https://registry.npmjs.org/token-types/-/token-types-6.0.0.tgz",
2448
+ "integrity": "sha512-lbDrTLVsHhOMljPscd0yitpozq7Ga2M5Cvez5AjGg8GASBjtt6iERCAJ93yommPmz62fb45oFIXHEZ3u9bfJEA==",
2449
+ "license": "MIT",
2450
+ "dependencies": {
2451
+ "@tokenizer/token": "^0.3.0",
2452
+ "ieee754": "^1.2.1"
2453
+ },
2454
+ "engines": {
2455
+ "node": ">=14.16"
2456
+ },
2457
+ "funding": {
2458
+ "type": "github",
2459
+ "url": "https://github.com/sponsors/Borewit"
2460
+ }
2461
+ },
2462
+ "node_modules/ttys": {
2463
+ "version": "0.0.3",
2464
+ "resolved": "https://registry.npmjs.org/ttys/-/ttys-0.0.3.tgz",
2465
+ "integrity": "sha512-UCqXRZS2S7U4aVB7Salj3ChPRSsb57ogJpJ1eMCvyowxFOBGsaHKcRU8bovcDwajX1mRbv0IpUnYkoG7Ieo5Zg==",
2466
+ "engines": {
2467
+ "node": ">= 0.6.0"
2468
+ }
2469
+ },
2470
+ "node_modules/type": {
2471
+ "version": "2.7.3",
2472
+ "resolved": "https://registry.npmjs.org/type/-/type-2.7.3.tgz",
2473
+ "integrity": "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ==",
2474
+ "license": "ISC"
2475
+ },
2476
  "node_modules/type-is": {
2477
  "version": "1.6.18",
2478
  "resolved": "https://registry.npmjs.org/type-is/-/type-is-1.6.18.tgz",
 
2486
  "node": ">= 0.6"
2487
  }
2488
  },
2489
+ "node_modules/uint8array-extras": {
2490
+ "version": "1.4.0",
2491
+ "resolved": "https://registry.npmjs.org/uint8array-extras/-/uint8array-extras-1.4.0.tgz",
2492
+ "integrity": "sha512-ZPtzy0hu4cZjv3z5NW9gfKnNLjoz4y6uv4HlelAjDK7sY/xOkKZv9xK/WQpcsBB3jEybChz9DPC2U/+cusjJVQ==",
2493
+ "license": "MIT",
2494
+ "engines": {
2495
+ "node": ">=18"
2496
+ },
2497
+ "funding": {
2498
+ "url": "https://github.com/sponsors/sindresorhus"
2499
+ }
2500
+ },
2501
  "node_modules/undici": {
2502
  "version": "6.21.2",
2503
  "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.2.tgz",
 
2534
  "node": ">= 0.8"
2535
  }
2536
  },
2537
+ "node_modules/web-streams-polyfill": {
2538
+ "version": "3.3.3",
2539
+ "resolved": "https://registry.npmjs.org/web-streams-polyfill/-/web-streams-polyfill-3.3.3.tgz",
2540
+ "integrity": "sha512-d2JWLCivmZYTSIoge9MsgFCZrt571BikcWGYkjC1khllbTeDlGqZ2D8vD8E/lJa8WGWbb7Plm8/XJYV7IJHZZw==",
2541
+ "license": "MIT",
2542
+ "engines": {
2543
+ "node": ">= 8"
2544
+ }
2545
+ },
2546
  "node_modules/whatwg-encoding": {
2547
  "version": "3.1.1",
2548
  "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz",
 
2563
  "engines": {
2564
  "node": ">=18"
2565
  }
2566
+ },
2567
+ "node_modules/which": {
2568
+ "version": "2.0.2",
2569
+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2570
+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2571
+ "license": "ISC",
2572
+ "dependencies": {
2573
+ "isexe": "^2.0.0"
2574
+ },
2575
+ "bin": {
2576
+ "node-which": "bin/node-which"
2577
+ },
2578
+ "engines": {
2579
+ "node": ">= 8"
2580
+ }
2581
+ },
2582
+ "node_modules/wrap-ansi": {
2583
+ "version": "8.1.0",
2584
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz",
2585
+ "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==",
2586
+ "license": "MIT",
2587
+ "dependencies": {
2588
+ "ansi-styles": "^6.1.0",
2589
+ "string-width": "^5.0.1",
2590
+ "strip-ansi": "^7.0.1"
2591
+ },
2592
+ "engines": {
2593
+ "node": ">=12"
2594
+ },
2595
+ "funding": {
2596
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2597
+ }
2598
+ },
2599
+ "node_modules/wrap-ansi-cjs": {
2600
+ "name": "wrap-ansi",
2601
+ "version": "7.0.0",
2602
+ "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz",
2603
+ "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==",
2604
+ "license": "MIT",
2605
+ "dependencies": {
2606
+ "ansi-styles": "^4.0.0",
2607
+ "string-width": "^4.1.0",
2608
+ "strip-ansi": "^6.0.0"
2609
+ },
2610
+ "engines": {
2611
+ "node": ">=10"
2612
+ },
2613
+ "funding": {
2614
+ "url": "https://github.com/chalk/wrap-ansi?sponsor=1"
2615
+ }
2616
+ },
2617
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-regex": {
2618
+ "version": "5.0.1",
2619
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.1.tgz",
2620
+ "integrity": "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ==",
2621
+ "license": "MIT",
2622
+ "engines": {
2623
+ "node": ">=8"
2624
+ }
2625
+ },
2626
+ "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": {
2627
+ "version": "4.3.0",
2628
+ "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
2629
+ "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
2630
+ "license": "MIT",
2631
+ "dependencies": {
2632
+ "color-convert": "^2.0.1"
2633
+ },
2634
+ "engines": {
2635
+ "node": ">=8"
2636
+ },
2637
+ "funding": {
2638
+ "url": "https://github.com/chalk/ansi-styles?sponsor=1"
2639
+ }
2640
+ },
2641
+ "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
2642
+ "version": "3.0.0",
2643
+ "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
2644
+ "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
2645
+ "license": "MIT",
2646
+ "engines": {
2647
+ "node": ">=8"
2648
+ }
2649
+ },
2650
+ "node_modules/wrap-ansi-cjs/node_modules/string-width": {
2651
+ "version": "4.2.3",
2652
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
2653
+ "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==",
2654
+ "license": "MIT",
2655
+ "dependencies": {
2656
+ "emoji-regex": "^8.0.0",
2657
+ "is-fullwidth-code-point": "^3.0.0",
2658
+ "strip-ansi": "^6.0.1"
2659
+ },
2660
+ "engines": {
2661
+ "node": ">=8"
2662
+ }
2663
+ },
2664
+ "node_modules/wrap-ansi-cjs/node_modules/strip-ansi": {
2665
+ "version": "6.0.1",
2666
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
2667
+ "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==",
2668
+ "license": "MIT",
2669
+ "dependencies": {
2670
+ "ansi-regex": "^5.0.1"
2671
+ },
2672
+ "engines": {
2673
+ "node": ">=8"
2674
+ }
2675
+ },
2676
+ "node_modules/wrap-ansi/node_modules/ansi-regex": {
2677
+ "version": "6.1.0",
2678
+ "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz",
2679
+ "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==",
2680
+ "license": "MIT",
2681
+ "engines": {
2682
+ "node": ">=12"
2683
+ },
2684
+ "funding": {
2685
+ "url": "https://github.com/chalk/ansi-regex?sponsor=1"
2686
+ }
2687
+ },
2688
+ "node_modules/wrap-ansi/node_modules/emoji-regex": {
2689
+ "version": "9.2.2",
2690
+ "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz",
2691
+ "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==",
2692
+ "license": "MIT"
2693
+ },
2694
+ "node_modules/wrap-ansi/node_modules/string-width": {
2695
+ "version": "5.1.2",
2696
+ "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz",
2697
+ "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==",
2698
+ "license": "MIT",
2699
+ "dependencies": {
2700
+ "eastasianwidth": "^0.2.0",
2701
+ "emoji-regex": "^9.2.2",
2702
+ "strip-ansi": "^7.0.1"
2703
+ },
2704
+ "engines": {
2705
+ "node": ">=12"
2706
+ },
2707
+ "funding": {
2708
+ "url": "https://github.com/sponsors/sindresorhus"
2709
+ }
2710
+ },
2711
+ "node_modules/wrap-ansi/node_modules/strip-ansi": {
2712
+ "version": "7.1.0",
2713
+ "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz",
2714
+ "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==",
2715
+ "license": "MIT",
2716
+ "dependencies": {
2717
+ "ansi-regex": "^6.0.1"
2718
+ },
2719
+ "engines": {
2720
+ "node": ">=12"
2721
+ },
2722
+ "funding": {
2723
+ "url": "https://github.com/chalk/strip-ansi?sponsor=1"
2724
+ }
2725
+ },
2726
+ "node_modules/yt-search": {
2727
+ "version": "2.12.1",
2728
+ "resolved": "https://registry.npmjs.org/yt-search/-/yt-search-2.12.1.tgz",
2729
+ "integrity": "sha512-suEbEGqIDa7OBuZQSNabPKS4sZrHrocak7JhxSw3gagCUxPgHqyEDqyWEruvLYax2uCIQ7UhQoDVqQGOFn+jrQ==",
2730
+ "license": "MIT",
2731
+ "dependencies": {
2732
+ "async.parallellimit": "~0.5.2",
2733
+ "boolstring": "~1.0.2",
2734
+ "cheerio": "^1.0.0-rc.10",
2735
+ "dasu": "~0.4.3",
2736
+ "human-time": "0.0.2",
2737
+ "jsonpath-plus": "~5.0.2",
2738
+ "minimist": "~1.2.5",
2739
+ "node-fzf": "~0.5.1"
2740
+ },
2741
+ "bin": {
2742
+ "yt-search": "bin/cli.js",
2743
+ "yt-search-audio": "bin/mpv_audio.sh",
2744
+ "yt-search-video": "bin/mpv_video.sh"
2745
+ }
2746
  }
2747
  }
2748
  }
package.json CHANGED
@@ -2,7 +2,7 @@
2
  "name": "api",
3
  "version": "1.0.0",
4
  "main": "app.js",
5
- "scripts": {
6
  "start": "node app.js",
7
  "dev": "nodemon app.js"
8
  },
@@ -12,9 +12,15 @@
12
  "dependencies": {
13
  "axios": "^1.8.4",
14
  "body-parser": "^2.2.0",
 
15
  "cheerio": "^1.0.0",
16
  "cors": "^2.8.5",
17
  "dotenv": "^16.4.7",
18
- "express": "^4.21.2"
 
 
 
 
 
19
  }
20
  }
 
2
  "name": "api",
3
  "version": "1.0.0",
4
  "main": "app.js",
5
+ "scripts": {
6
  "start": "node app.js",
7
  "dev": "nodemon app.js"
8
  },
 
12
  "dependencies": {
13
  "axios": "^1.8.4",
14
  "body-parser": "^2.2.0",
15
+ "browser-id3-writer": "^6.2.0",
16
  "cheerio": "^1.0.0",
17
  "cors": "^2.8.5",
18
  "dotenv": "^16.4.7",
19
+ "express": "^4.21.2",
20
+ "file-type": "^20.4.1",
21
+ "js-beautify": "^1.15.4",
22
+ "node-fetch": "^3.3.2",
23
+ "similarity": "^1.2.1",
24
+ "yt-search": "^2.12.1"
25
  }
26
  }