@darrenjaws/spotify-mcp 1.0.1 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/bin.js +4 -4
- package/build/index.js +135 -24
- package/build/index.js.map +1 -1
- package/build/setup.d.ts.map +1 -1
- package/build/setup.js +156 -156
- package/build/setup.js.map +1 -1
- package/build/spotify/auth.d.ts +4 -0
- package/build/spotify/auth.d.ts.map +1 -1
- package/build/spotify/auth.js +38 -15
- package/build/spotify/auth.js.map +1 -1
- package/build/spotify/client.d.ts +8 -2
- package/build/spotify/client.d.ts.map +1 -1
- package/build/spotify/client.js +72 -4
- package/build/spotify/client.js.map +1 -1
- package/build/tools/library.d.ts.map +1 -1
- package/build/tools/library.js +58 -30
- package/build/tools/library.js.map +1 -1
- package/build/tools/playback.d.ts.map +1 -1
- package/build/tools/playback.js +40 -20
- package/build/tools/playback.js.map +1 -1
- package/build/tools/playlists.d.ts.map +1 -1
- package/build/tools/playlists.js +39 -17
- package/build/tools/playlists.js.map +1 -1
- package/build/tools/search.d.ts.map +1 -1
- package/build/tools/search.js +11 -5
- package/build/tools/search.js.map +1 -1
- package/build/tools/user.d.ts.map +1 -1
- package/build/tools/user.js +11 -6
- package/build/tools/user.js.map +1 -1
- package/build/types.d.ts +42 -0
- package/build/types.d.ts.map +1 -1
- package/build/utils/logger.d.ts.map +1 -1
- package/build/utils/logger.js +32 -16
- package/build/utils/logger.js.map +1 -1
- package/build/utils/validation.d.ts +40 -0
- package/build/utils/validation.d.ts.map +1 -0
- package/build/utils/validation.js +57 -0
- package/build/utils/validation.js.map +1 -0
- package/package.json +6 -2
package/build/spotify/auth.js
CHANGED
|
@@ -15,11 +15,11 @@ const TOKEN_FILE = path.join(TOKEN_DIR, "tokens.json");
|
|
|
15
15
|
*/
|
|
16
16
|
function escapeHtml(str) {
|
|
17
17
|
const htmlEscapeMap = {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
'"':
|
|
22
|
-
"'":
|
|
18
|
+
"&": "&",
|
|
19
|
+
"<": "<",
|
|
20
|
+
">": ">",
|
|
21
|
+
'"': """,
|
|
22
|
+
"'": "'",
|
|
23
23
|
};
|
|
24
24
|
return str.replace(/[&<>"']/g, (char) => htmlEscapeMap[char] || char);
|
|
25
25
|
}
|
|
@@ -57,6 +57,17 @@ export async function loadTokens() {
|
|
|
57
57
|
logger.debug("No stored tokens found");
|
|
58
58
|
return null;
|
|
59
59
|
}
|
|
60
|
+
// Handle corrupted token file (e.g., invalid JSON)
|
|
61
|
+
if (error instanceof SyntaxError) {
|
|
62
|
+
logger.warn("Corrupted tokens file detected, deleting and re-authenticating");
|
|
63
|
+
try {
|
|
64
|
+
await fs.unlink(TOKEN_FILE);
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
// Ignore unlink errors — file may already be gone
|
|
68
|
+
}
|
|
69
|
+
return null;
|
|
70
|
+
}
|
|
60
71
|
logger.error("Error loading tokens:", error);
|
|
61
72
|
throw error;
|
|
62
73
|
}
|
|
@@ -75,6 +86,18 @@ export async function saveTokens(tokens) {
|
|
|
75
86
|
throw error;
|
|
76
87
|
}
|
|
77
88
|
}
|
|
89
|
+
/**
|
|
90
|
+
* Delete stored tokens file (used when tokens are invalid and re-auth is needed)
|
|
91
|
+
*/
|
|
92
|
+
export async function deleteTokens() {
|
|
93
|
+
try {
|
|
94
|
+
await fs.unlink(TOKEN_FILE);
|
|
95
|
+
logger.debug("Deleted tokens file");
|
|
96
|
+
}
|
|
97
|
+
catch {
|
|
98
|
+
// Ignore errors — file may not exist
|
|
99
|
+
}
|
|
100
|
+
}
|
|
78
101
|
/**
|
|
79
102
|
* Check if tokens are expired or will expire soon (within 5 minutes)
|
|
80
103
|
*/
|
|
@@ -128,7 +151,7 @@ export async function startOAuthFlow(client) {
|
|
|
128
151
|
"user-follow-modify",
|
|
129
152
|
];
|
|
130
153
|
// Generate cryptographically secure state parameter for CSRF protection
|
|
131
|
-
const state = crypto.randomBytes(32).toString(
|
|
154
|
+
const state = crypto.randomBytes(32).toString("hex");
|
|
132
155
|
const authorizeURL = client.createAuthorizeURL(scopes, state);
|
|
133
156
|
logger.info("Starting OAuth flow...");
|
|
134
157
|
logger.info(`Authorization URL: ${authorizeURL}`);
|
|
@@ -144,20 +167,20 @@ export async function startOAuthFlow(client) {
|
|
|
144
167
|
if (requestCount > MAX_REQUESTS) {
|
|
145
168
|
logger.warn("OAuth callback server: too many requests, rejecting");
|
|
146
169
|
res.writeHead(429, { "Content-Type": "text/html; charset=utf-8" });
|
|
147
|
-
res.end(
|
|
170
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>Too Many Requests</h1></body></html>');
|
|
148
171
|
return;
|
|
149
172
|
}
|
|
150
173
|
// Security: only accept requests from localhost
|
|
151
174
|
const remoteAddress = req.socket.remoteAddress;
|
|
152
|
-
if (remoteAddress && ![
|
|
175
|
+
if (remoteAddress && !["127.0.0.1", "::1", "::ffff:127.0.0.1"].includes(remoteAddress)) {
|
|
153
176
|
logger.warn(`OAuth callback server: rejected request from ${remoteAddress}`);
|
|
154
177
|
res.writeHead(403, { "Content-Type": "text/html; charset=utf-8" });
|
|
155
|
-
res.end(
|
|
178
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>Forbidden</h1></body></html>');
|
|
156
179
|
return;
|
|
157
180
|
}
|
|
158
181
|
if (!req.url?.startsWith("/callback")) {
|
|
159
182
|
res.writeHead(404, { "Content-Type": "text/html; charset=utf-8" });
|
|
160
|
-
res.end(
|
|
183
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>Not Found</h1></body></html>');
|
|
161
184
|
return;
|
|
162
185
|
}
|
|
163
186
|
const url = new URL(req.url, "http://127.0.0.1:3000");
|
|
@@ -173,14 +196,14 @@ export async function startOAuthFlow(client) {
|
|
|
173
196
|
}
|
|
174
197
|
if (returnedState !== state) {
|
|
175
198
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
176
|
-
res.end(
|
|
199
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>State mismatch</h1><p>Invalid state parameter. Please try again.</p></body></html>');
|
|
177
200
|
server.close();
|
|
178
201
|
reject(new Error("State mismatch in OAuth callback"));
|
|
179
202
|
return;
|
|
180
203
|
}
|
|
181
204
|
if (!code) {
|
|
182
205
|
res.writeHead(400, { "Content-Type": "text/html; charset=utf-8" });
|
|
183
|
-
res.end(
|
|
206
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>No authorization code received</h1><p>The authorization process was incomplete. Please try again.</p></body></html>');
|
|
184
207
|
server.close();
|
|
185
208
|
reject(new Error("No authorization code received"));
|
|
186
209
|
return;
|
|
@@ -196,14 +219,14 @@ export async function startOAuthFlow(client) {
|
|
|
196
219
|
};
|
|
197
220
|
await saveTokens(tokens);
|
|
198
221
|
res.writeHead(200, { "Content-Type": "text/html; charset=utf-8" });
|
|
199
|
-
res.end(
|
|
222
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>✓ Authorization successful!</h1><p>You can close this window and return to your application.</p></body></html>');
|
|
200
223
|
server.close();
|
|
201
224
|
resolve(tokens);
|
|
202
225
|
}
|
|
203
226
|
catch (error) {
|
|
204
227
|
logger.error("Error exchanging code for tokens:", error);
|
|
205
228
|
res.writeHead(500, { "Content-Type": "text/html; charset=utf-8" });
|
|
206
|
-
res.end(
|
|
229
|
+
res.end('<html><head><meta charset="utf-8"></head><body><h1>Error exchanging authorization code</h1><p>An error occurred during authentication. Please try again.</p></body></html>');
|
|
207
230
|
server.close();
|
|
208
231
|
reject(error);
|
|
209
232
|
}
|
|
@@ -218,7 +241,7 @@ export async function startOAuthFlow(client) {
|
|
|
218
241
|
}
|
|
219
242
|
}, 5 * 60 * 1000); // 5 minutes
|
|
220
243
|
// Clear timeout when server closes
|
|
221
|
-
server.on(
|
|
244
|
+
server.on("close", () => {
|
|
222
245
|
clearTimeout(serverTimeout);
|
|
223
246
|
serverClosed = true;
|
|
224
247
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/spotify/auth.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../src/spotify/auth.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Spotify API client wrapper with automatic token refresh
|
|
2
|
+
* Spotify API client wrapper with automatic token refresh and retry logic
|
|
3
3
|
*/
|
|
4
4
|
import SpotifyWebApi from "spotify-web-api-node";
|
|
5
|
+
import type { SpotifyClient } from "../types.js";
|
|
6
|
+
/**
|
|
7
|
+
* Wrap a SpotifyWebApi instance with retry logic for 429 (rate limit) responses.
|
|
8
|
+
* Uses exponential backoff: 1s, 2s, 4s — and respects Retry-After header if present.
|
|
9
|
+
*/
|
|
10
|
+
export declare function withRetry(client: SpotifyWebApi): SpotifyWebApi;
|
|
5
11
|
/**
|
|
6
12
|
* Get an authenticated Spotify client
|
|
7
13
|
* Handles token loading, refresh, and OAuth flow as needed
|
|
8
14
|
*/
|
|
9
|
-
export declare function getAuthenticatedClient(): Promise<
|
|
15
|
+
export declare function getAuthenticatedClient(): Promise<SpotifyClient>;
|
|
10
16
|
/**
|
|
11
17
|
* Reset the client (useful for testing or forcing re-authentication)
|
|
12
18
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/spotify/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,aAAa,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/spotify/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,aAAa,MAAM,sBAAsB,CAAC;AAWjD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAcjD;;;GAGG;AACH,wBAAgB,SAAS,CAAC,MAAM,EAAE,aAAa,GAAG,aAAa,CAqD9D;AAED;;;GAGG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,aAAa,CAAC,CAkCrE;AAED;;GAEG;AACH,wBAAgB,WAAW,IAAI,IAAI,CAElC"}
|
package/build/spotify/client.js
CHANGED
|
@@ -1,9 +1,70 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Spotify API client wrapper with automatic token refresh
|
|
2
|
+
* Spotify API client wrapper with automatic token refresh and retry logic
|
|
3
3
|
*/
|
|
4
|
-
import { getCredentials, loadTokens, areTokensExpired, createSpotifyClient, refreshAccessToken, startOAuthFlow, } from "./auth.js";
|
|
4
|
+
import { getCredentials, loadTokens, areTokensExpired, createSpotifyClient, refreshAccessToken, deleteTokens, startOAuthFlow, } from "./auth.js";
|
|
5
5
|
import { logger } from "../utils/logger.js";
|
|
6
|
+
const MAX_RETRIES = 3;
|
|
7
|
+
const BASE_DELAY_MS = 1000;
|
|
6
8
|
let spotifyClient = null;
|
|
9
|
+
/**
|
|
10
|
+
* Sleep for a given number of milliseconds
|
|
11
|
+
*/
|
|
12
|
+
function sleep(ms) {
|
|
13
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Wrap a SpotifyWebApi instance with retry logic for 429 (rate limit) responses.
|
|
17
|
+
* Uses exponential backoff: 1s, 2s, 4s — and respects Retry-After header if present.
|
|
18
|
+
*/
|
|
19
|
+
export function withRetry(client) {
|
|
20
|
+
return new Proxy(client, {
|
|
21
|
+
get(target, prop) {
|
|
22
|
+
const original = target[prop];
|
|
23
|
+
if (typeof original !== "function") {
|
|
24
|
+
return original;
|
|
25
|
+
}
|
|
26
|
+
// Only wrap API-calling methods, not setters/getters
|
|
27
|
+
const nonRetryMethods = [
|
|
28
|
+
"setAccessToken",
|
|
29
|
+
"setRefreshToken",
|
|
30
|
+
"setClientId",
|
|
31
|
+
"setClientSecret",
|
|
32
|
+
"setRedirectURI",
|
|
33
|
+
"getAccessToken",
|
|
34
|
+
"getRefreshToken",
|
|
35
|
+
"getClientId",
|
|
36
|
+
"getClientSecret",
|
|
37
|
+
"getRedirectURI",
|
|
38
|
+
"createAuthorizeURL",
|
|
39
|
+
"authorizationCodeGrant",
|
|
40
|
+
"refreshAccessToken",
|
|
41
|
+
];
|
|
42
|
+
if (nonRetryMethods.includes(prop)) {
|
|
43
|
+
return original.bind(target);
|
|
44
|
+
}
|
|
45
|
+
return async function (...args) {
|
|
46
|
+
for (let attempt = 0; attempt <= MAX_RETRIES; attempt++) {
|
|
47
|
+
try {
|
|
48
|
+
return await original.apply(target, args);
|
|
49
|
+
}
|
|
50
|
+
catch (error) {
|
|
51
|
+
const statusCode = error?.statusCode ?? error?.body?.error?.status;
|
|
52
|
+
if (statusCode !== 429 || attempt >= MAX_RETRIES) {
|
|
53
|
+
throw error;
|
|
54
|
+
}
|
|
55
|
+
// Determine delay: use Retry-After header if available, else exponential backoff
|
|
56
|
+
const retryAfter = error?.headers?.["retry-after"];
|
|
57
|
+
const delayMs = retryAfter
|
|
58
|
+
? parseInt(retryAfter, 10) * 1000
|
|
59
|
+
: BASE_DELAY_MS * Math.pow(2, attempt);
|
|
60
|
+
logger.warn(`Rate limited (429) on ${prop}, retrying in ${delayMs}ms (attempt ${attempt + 1}/${MAX_RETRIES})`);
|
|
61
|
+
await sleep(delayMs);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
};
|
|
65
|
+
},
|
|
66
|
+
});
|
|
67
|
+
}
|
|
7
68
|
/**
|
|
8
69
|
* Get an authenticated Spotify client
|
|
9
70
|
* Handles token loading, refresh, and OAuth flow as needed
|
|
@@ -24,12 +85,19 @@ export async function getAuthenticatedClient() {
|
|
|
24
85
|
// Refresh tokens if expired
|
|
25
86
|
if (areTokensExpired(tokens)) {
|
|
26
87
|
logger.info("Tokens expired, refreshing");
|
|
27
|
-
|
|
88
|
+
try {
|
|
89
|
+
tokens = await refreshAccessToken(spotifyClient, tokens.refreshToken);
|
|
90
|
+
}
|
|
91
|
+
catch (error) {
|
|
92
|
+
logger.error("Token refresh failed:", error);
|
|
93
|
+
await deleteTokens();
|
|
94
|
+
throw new Error("Session expired. Please re-authenticate.");
|
|
95
|
+
}
|
|
28
96
|
}
|
|
29
97
|
// Set tokens on client
|
|
30
98
|
spotifyClient.setAccessToken(tokens.accessToken);
|
|
31
99
|
spotifyClient.setRefreshToken(tokens.refreshToken);
|
|
32
|
-
return spotifyClient;
|
|
100
|
+
return withRetry(spotifyClient);
|
|
33
101
|
}
|
|
34
102
|
/**
|
|
35
103
|
* Reset the client (useful for testing or forcing re-authentication)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/spotify/client.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,EACL,cAAc,EACd,UAAU,EACV,gBAAgB,EAChB,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,GACf,MAAM,WAAW,CAAC;AACnB,OAAO,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;
|
|
1
|
+
{"version":3,"file":"client.js","sourceRoot":"","sources":["../../src/spotify/client.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"library.d.ts","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH,OAAO,KAAK,EACV,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,sBAAsB,EACtB,cAAc,EACd,cAAc,EACd,iBAAiB,EAClB,MAAM,aAAa,CAAC;AAErB,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiCpF;AAED,wBAAsB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,YAAY,CAAC,CAiCpF;AAED,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,sBAAsB,GAAG,OAAO,CAAC,YAAY,CAAC,CA0C5F;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAkB5E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBnF;AAED,wBAAsB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAkB5E;AAED,wBAAsB,iBAAiB,CAAC,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBnF;AAED,wBAAsB,aAAa,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBlF;AAED,wBAAsB,eAAe,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBpF"}
|
package/build/tools/library.js
CHANGED
|
@@ -3,28 +3,33 @@
|
|
|
3
3
|
*/
|
|
4
4
|
import { getAuthenticatedClient } from "../spotify/client.js";
|
|
5
5
|
import { handleToolError } from "../spotify/errors.js";
|
|
6
|
+
import { validateArraySize } from "../utils/validation.js";
|
|
6
7
|
export async function getSavedTracks(args) {
|
|
7
8
|
try {
|
|
8
9
|
const client = await getAuthenticatedClient();
|
|
9
10
|
const limit = args.limit || 20;
|
|
10
11
|
const offset = args.offset || 0;
|
|
11
12
|
const result = await client.getMySavedTracks({ limit, offset });
|
|
12
|
-
const items = result.body
|
|
13
|
+
const items = result.body?.items ?? [];
|
|
13
14
|
if (items.length === 0) {
|
|
14
15
|
return {
|
|
15
16
|
content: [{ type: "text", text: "No saved tracks found" }],
|
|
16
17
|
};
|
|
17
18
|
}
|
|
18
19
|
const formatted = items.map((item, index) => {
|
|
19
|
-
const track = item
|
|
20
|
-
|
|
20
|
+
const track = item?.track;
|
|
21
|
+
if (!track)
|
|
22
|
+
return `${offset + index + 1}. [Unknown track]`;
|
|
23
|
+
const artists = track.artists?.map((a) => a.name).join(", ") ?? "Unknown artist";
|
|
21
24
|
return `${offset + index + 1}. ${track.name} - ${artists} (${track.uri})`;
|
|
22
25
|
});
|
|
23
26
|
return {
|
|
24
|
-
content: [
|
|
27
|
+
content: [
|
|
28
|
+
{
|
|
25
29
|
type: "text",
|
|
26
30
|
text: `Saved tracks (${result.body.total} total):\n\n${formatted.join("\n")}`,
|
|
27
|
-
}
|
|
31
|
+
},
|
|
32
|
+
],
|
|
28
33
|
};
|
|
29
34
|
}
|
|
30
35
|
catch (error) {
|
|
@@ -37,22 +42,26 @@ export async function getSavedAlbums(args) {
|
|
|
37
42
|
const limit = args.limit || 20;
|
|
38
43
|
const offset = args.offset || 0;
|
|
39
44
|
const result = await client.getMySavedAlbums({ limit, offset });
|
|
40
|
-
const items = result.body
|
|
45
|
+
const items = result.body?.items ?? [];
|
|
41
46
|
if (items.length === 0) {
|
|
42
47
|
return {
|
|
43
48
|
content: [{ type: "text", text: "No saved albums found" }],
|
|
44
49
|
};
|
|
45
50
|
}
|
|
46
51
|
const formatted = items.map((item, index) => {
|
|
47
|
-
const album = item
|
|
48
|
-
|
|
52
|
+
const album = item?.album;
|
|
53
|
+
if (!album)
|
|
54
|
+
return `${offset + index + 1}. [Unknown album]`;
|
|
55
|
+
const artists = album.artists?.map((a) => a.name).join(", ") ?? "Unknown artist";
|
|
49
56
|
return `${offset + index + 1}. ${album.name} - ${artists} (${album.uri})`;
|
|
50
57
|
});
|
|
51
58
|
return {
|
|
52
|
-
content: [
|
|
59
|
+
content: [
|
|
60
|
+
{
|
|
53
61
|
type: "text",
|
|
54
62
|
text: `Saved albums (${result.body.total} total):\n\n${formatted.join("\n")}`,
|
|
55
|
-
}
|
|
63
|
+
},
|
|
64
|
+
],
|
|
56
65
|
};
|
|
57
66
|
}
|
|
58
67
|
catch (error) {
|
|
@@ -68,28 +77,29 @@ export async function getFollowedArtists(args) {
|
|
|
68
77
|
options.after = args.after;
|
|
69
78
|
}
|
|
70
79
|
const result = await client.getFollowedArtists(options);
|
|
71
|
-
const artists = result.body
|
|
72
|
-
const items = artists
|
|
80
|
+
const artists = result.body?.artists;
|
|
81
|
+
const items = artists?.items ?? [];
|
|
73
82
|
if (items.length === 0) {
|
|
74
83
|
return {
|
|
75
84
|
content: [{ type: "text", text: "No followed artists found" }],
|
|
76
85
|
};
|
|
77
86
|
}
|
|
78
87
|
const formatted = items.map((artist, index) => {
|
|
79
|
-
const
|
|
80
|
-
|
|
81
|
-
: "";
|
|
88
|
+
const genreList = artist.genres ?? [];
|
|
89
|
+
const genres = genreList.length > 0 ? ` (${genreList.slice(0, 2).join(", ")})` : "";
|
|
82
90
|
return `${index + 1}. ${artist.name}${genres} (${artist.uri})`;
|
|
83
91
|
});
|
|
84
|
-
const nextCursor = artists
|
|
92
|
+
const nextCursor = artists?.cursors?.after;
|
|
85
93
|
const cursorNote = nextCursor
|
|
86
94
|
? `\n\nMore artists available. Use after: "${nextCursor}" to see the next page.`
|
|
87
95
|
: "";
|
|
88
96
|
return {
|
|
89
|
-
content: [
|
|
97
|
+
content: [
|
|
98
|
+
{
|
|
90
99
|
type: "text",
|
|
91
100
|
text: `Followed artists:\n\n${formatted.join("\n")}${cursorNote}`,
|
|
92
|
-
}
|
|
101
|
+
},
|
|
102
|
+
],
|
|
93
103
|
};
|
|
94
104
|
}
|
|
95
105
|
catch (error) {
|
|
@@ -98,13 +108,16 @@ export async function getFollowedArtists(args) {
|
|
|
98
108
|
}
|
|
99
109
|
export async function saveTracks(args) {
|
|
100
110
|
try {
|
|
111
|
+
validateArraySize(args.track_ids, 50, "track_ids");
|
|
101
112
|
const client = await getAuthenticatedClient();
|
|
102
113
|
await client.addToMySavedTracks(args.track_ids);
|
|
103
114
|
return {
|
|
104
|
-
content: [
|
|
115
|
+
content: [
|
|
116
|
+
{
|
|
105
117
|
type: "text",
|
|
106
118
|
text: `Saved ${args.track_ids.length} track(s) to your library`,
|
|
107
|
-
}
|
|
119
|
+
},
|
|
120
|
+
],
|
|
108
121
|
};
|
|
109
122
|
}
|
|
110
123
|
catch (error) {
|
|
@@ -113,13 +126,16 @@ export async function saveTracks(args) {
|
|
|
113
126
|
}
|
|
114
127
|
export async function removeSavedTracks(args) {
|
|
115
128
|
try {
|
|
129
|
+
validateArraySize(args.track_ids, 50, "track_ids");
|
|
116
130
|
const client = await getAuthenticatedClient();
|
|
117
131
|
await client.removeFromMySavedTracks(args.track_ids);
|
|
118
132
|
return {
|
|
119
|
-
content: [
|
|
133
|
+
content: [
|
|
134
|
+
{
|
|
120
135
|
type: "text",
|
|
121
136
|
text: `Removed ${args.track_ids.length} track(s) from your library`,
|
|
122
|
-
}
|
|
137
|
+
},
|
|
138
|
+
],
|
|
123
139
|
};
|
|
124
140
|
}
|
|
125
141
|
catch (error) {
|
|
@@ -128,13 +144,16 @@ export async function removeSavedTracks(args) {
|
|
|
128
144
|
}
|
|
129
145
|
export async function saveAlbums(args) {
|
|
130
146
|
try {
|
|
147
|
+
validateArraySize(args.album_ids, 50, "album_ids");
|
|
131
148
|
const client = await getAuthenticatedClient();
|
|
132
149
|
await client.addToMySavedAlbums(args.album_ids);
|
|
133
150
|
return {
|
|
134
|
-
content: [
|
|
151
|
+
content: [
|
|
152
|
+
{
|
|
135
153
|
type: "text",
|
|
136
154
|
text: `Saved ${args.album_ids.length} album(s) to your library`,
|
|
137
|
-
}
|
|
155
|
+
},
|
|
156
|
+
],
|
|
138
157
|
};
|
|
139
158
|
}
|
|
140
159
|
catch (error) {
|
|
@@ -143,13 +162,16 @@ export async function saveAlbums(args) {
|
|
|
143
162
|
}
|
|
144
163
|
export async function removeSavedAlbums(args) {
|
|
145
164
|
try {
|
|
165
|
+
validateArraySize(args.album_ids, 50, "album_ids");
|
|
146
166
|
const client = await getAuthenticatedClient();
|
|
147
167
|
await client.removeFromMySavedAlbums(args.album_ids);
|
|
148
168
|
return {
|
|
149
|
-
content: [
|
|
169
|
+
content: [
|
|
170
|
+
{
|
|
150
171
|
type: "text",
|
|
151
172
|
text: `Removed ${args.album_ids.length} album(s) from your library`,
|
|
152
|
-
}
|
|
173
|
+
},
|
|
174
|
+
],
|
|
153
175
|
};
|
|
154
176
|
}
|
|
155
177
|
catch (error) {
|
|
@@ -158,13 +180,16 @@ export async function removeSavedAlbums(args) {
|
|
|
158
180
|
}
|
|
159
181
|
export async function followArtists(args) {
|
|
160
182
|
try {
|
|
183
|
+
validateArraySize(args.artist_ids, 50, "artist_ids");
|
|
161
184
|
const client = await getAuthenticatedClient();
|
|
162
185
|
await client.followArtists(args.artist_ids);
|
|
163
186
|
return {
|
|
164
|
-
content: [
|
|
187
|
+
content: [
|
|
188
|
+
{
|
|
165
189
|
type: "text",
|
|
166
190
|
text: `Now following ${args.artist_ids.length} artist(s)`,
|
|
167
|
-
}
|
|
191
|
+
},
|
|
192
|
+
],
|
|
168
193
|
};
|
|
169
194
|
}
|
|
170
195
|
catch (error) {
|
|
@@ -173,13 +198,16 @@ export async function followArtists(args) {
|
|
|
173
198
|
}
|
|
174
199
|
export async function unfollowArtists(args) {
|
|
175
200
|
try {
|
|
201
|
+
validateArraySize(args.artist_ids, 50, "artist_ids");
|
|
176
202
|
const client = await getAuthenticatedClient();
|
|
177
203
|
await client.unfollowArtists(args.artist_ids);
|
|
178
204
|
return {
|
|
179
|
-
content: [
|
|
205
|
+
content: [
|
|
206
|
+
{
|
|
180
207
|
type: "text",
|
|
181
208
|
text: `Unfollowed ${args.artist_ids.length} artist(s)`,
|
|
182
|
-
}
|
|
209
|
+
},
|
|
210
|
+
],
|
|
183
211
|
};
|
|
184
212
|
}
|
|
185
213
|
catch (error) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"library.js","sourceRoot":"","sources":["../../src/tools/library.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAW3D,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwB;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAQ,MAAM,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAEvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;aAC3D,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,KAAa,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;YAC1B,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,mBAAmB,CAAC;YAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC;YACtF,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,OAAO,KAAK,KAAK,CAAC,GAAG,GAAG,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,iBAAiB,MAAM,CAAC,IAAI,CAAC,KAAK,eAAe,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC9E;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,IAAwB;IAC3D,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,CAAC,CAAC;QAEhC,MAAM,MAAM,GAAQ,MAAM,MAAM,CAAC,gBAAgB,CAAC,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACrE,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;QAEvC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,uBAAuB,EAAE,CAAC;aAC3D,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,IAAS,EAAE,KAAa,EAAE,EAAE;YACvD,MAAM,KAAK,GAAG,IAAI,EAAE,KAAK,CAAC;YAC1B,IAAI,CAAC,KAAK;gBAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,mBAAmB,CAAC;YAC5D,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,gBAAgB,CAAC;YACtF,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,CAAC,KAAK,KAAK,CAAC,IAAI,MAAM,OAAO,KAAK,KAAK,CAAC,GAAG,GAAG,CAAC;QAC5E,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,iBAAiB,MAAM,CAAC,IAAI,CAAC,KAAK,eAAe,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;iBAC9E;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAA4B;IACnE,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;QAE/B,MAAM,OAAO,GAAQ,EAAE,KAAK,EAAE,CAAC;QAC/B,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC;QAC7B,CAAC;QAED,MAAM,MAAM,GAAQ,MAAM,MAAM,CAAC,kBAAkB,CAAC,OAAO,CAAC,CAAC;QAC7D,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,EAAE,OAAO,CAAC;QACrC,MAAM,KAAK,GAAG,OAAO,EAAE,KAAK,IAAI,EAAE,CAAC;QAEnC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO;gBACL,OAAO,EAAE,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,2BAA2B,EAAE,CAAC;aAC/D,CAAC;QACJ,CAAC;QAED,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,MAAW,EAAE,KAAa,EAAE,EAAE;YACzD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,IAAI,EAAE,CAAC;YACtC,MAAM,MAAM,GAAG,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;YACpF,OAAO,GAAG,KAAK,GAAG,CAAC,KAAK,MAAM,CAAC,IAAI,GAAG,MAAM,KAAK,MAAM,CAAC,GAAG,GAAG,CAAC;QACjE,CAAC,CAAC,CAAC;QAEH,MAAM,UAAU,GAAG,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC;QAC3C,MAAM,UAAU,GAAG,UAAU;YAC3B,CAAC,CAAC,2CAA2C,UAAU,yBAAyB;YAChF,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,wBAAwB,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,UAAU,EAAE;iBAClE;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,8BAA8B,CAAC,CAAC;IAChE,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,2BAA2B;iBAChE;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAoB;IAC1D,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAErD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,6BAA6B;iBACpE;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,6BAA6B,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,IAAoB;IACnD,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,kBAAkB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAEhD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,SAAS,IAAI,CAAC,SAAS,CAAC,MAAM,2BAA2B;iBAChE;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,qBAAqB,CAAC,CAAC;IACvD,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,IAAoB;IAC1D,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,SAAS,EAAE,EAAE,EAAE,WAAW,CAAC,CAAC;QAEnD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,uBAAuB,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAErD,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,WAAW,IAAI,CAAC,SAAS,CAAC,MAAM,6BAA6B;iBACpE;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,6BAA6B,CAAC,CAAC;IAC/D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,IAAuB;IACzD,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,aAAa,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE5C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,iBAAiB,IAAI,CAAC,UAAU,CAAC,MAAM,YAAY;iBAC1D;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,wBAAwB,CAAC,CAAC;IAC1D,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAuB;IAC3D,IAAI,CAAC;QACH,iBAAiB,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,EAAE,YAAY,CAAC,CAAC;QAErD,MAAM,MAAM,GAAG,MAAM,sBAAsB,EAAE,CAAC;QAC9C,MAAM,MAAM,CAAC,eAAe,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAE9C,OAAO;YACL,OAAO,EAAE;gBACP;oBACE,IAAI,EAAE,MAAM;oBACZ,IAAI,EAAE,cAAc,IAAI,CAAC,UAAU,CAAC,MAAM,YAAY;iBACvD;aACF;SACF,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,eAAe,CAAC,KAAK,EAAE,0BAA0B,CAAC,CAAC;IAC5D,CAAC;AACH,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/tools/playback.ts"],"names":[],"mappings":"AAAA;;GAEG;
|
|
1
|
+
{"version":3,"file":"playback.d.ts","sourceRoot":"","sources":["../../src/tools/playback.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,OAAO,KAAK,EACV,YAAY,EACZ,YAAY,EACZ,UAAU,EACV,oBAAoB,EAErB,MAAM,aAAa,CAAC;AAwCrB,wBAAsB,IAAI,CAAC,IAAI,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC,CAsEpE;AAED,wBAAsB,KAAK,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAyB/E;AAED,wBAAsB,IAAI,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAyB9E;AAED,wBAAsB,QAAQ,CAAC,IAAI,EAAE;IAAE,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,YAAY,CAAC,CAyBlF;AAED,wBAAsB,SAAS,CAAC,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,YAAY,CAAC,CAyBvE;AAED,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,YAAY,CAAC,CAkE9D;AAED,wBAAsB,UAAU,IAAI,OAAO,CAAC,YAAY,CAAC,CAsCxD;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,oBAAoB,GAAG,OAAO,CAAC,YAAY,CAAC,CAkBxF"}
|