@muhgholy/next-drive 4.23.3 → 4.23.5
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/dist/{chunk-R43JCXQB.js → chunk-GV4HB2G6.js} +148 -138
- package/dist/chunk-GV4HB2G6.js.map +1 -0
- package/dist/{chunk-RBLDH7CP.cjs → chunk-VIB7R4JN.cjs} +148 -138
- package/dist/chunk-VIB7R4JN.cjs.map +1 -0
- package/dist/client/index.cjs +10 -10
- package/dist/client/index.cjs.map +1 -1
- package/dist/client/index.js +10 -10
- package/dist/client/index.js.map +1 -1
- package/dist/server/controllers/drive.d.ts +3 -0
- package/dist/server/controllers/drive.d.ts.map +1 -1
- package/dist/server/express.cjs +11 -11
- package/dist/server/express.js +2 -2
- package/dist/server/hono.cjs +11 -11
- package/dist/server/hono.js +2 -2
- package/dist/server/index.cjs +16 -16
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/index.js +1 -1
- package/dist/types/lib/database/drive.d.ts +1 -0
- package/dist/types/lib/database/drive.d.ts.map +1 -1
- package/package.json +3 -3
- package/dist/chunk-R43JCXQB.js.map +0 -1
- package/dist/chunk-RBLDH7CP.cjs.map +0 -1
|
@@ -5,9 +5,9 @@ import os2 from 'os';
|
|
|
5
5
|
import crypto2 from 'crypto';
|
|
6
6
|
import mongoose, { Schema, isValidObjectId } from 'mongoose';
|
|
7
7
|
import sharp2 from 'sharp';
|
|
8
|
-
import { z } from 'zod';
|
|
9
8
|
import ffmpeg from 'fluent-ffmpeg';
|
|
10
9
|
import { google } from 'googleapis';
|
|
10
|
+
import { z } from 'zod';
|
|
11
11
|
|
|
12
12
|
// src/server/index.ts
|
|
13
13
|
var informationSchema = new Schema({
|
|
@@ -324,35 +324,6 @@ var getDriveInformation = async (input) => {
|
|
|
324
324
|
}
|
|
325
325
|
return config.information(input);
|
|
326
326
|
};
|
|
327
|
-
var StorageAccountSchema = new Schema(
|
|
328
|
-
{
|
|
329
|
-
owner: { type: Schema.Types.Mixed, default: null },
|
|
330
|
-
name: { type: String, required: true },
|
|
331
|
-
metadata: {
|
|
332
|
-
provider: { type: String, enum: ["GOOGLE"], required: true },
|
|
333
|
-
google: {
|
|
334
|
-
email: { type: String, required: true },
|
|
335
|
-
credentials: { type: Schema.Types.Mixed, required: true }
|
|
336
|
-
}
|
|
337
|
-
},
|
|
338
|
-
createdAt: { type: Date, default: Date.now }
|
|
339
|
-
},
|
|
340
|
-
{ minimize: false }
|
|
341
|
-
);
|
|
342
|
-
StorageAccountSchema.index({ owner: 1, "metadata.provider": 1 });
|
|
343
|
-
StorageAccountSchema.index({ owner: 1, "metadata.google.email": 1 });
|
|
344
|
-
StorageAccountSchema.method("toClient", async function() {
|
|
345
|
-
const data = this.toJSON();
|
|
346
|
-
return {
|
|
347
|
-
id: String(data._id),
|
|
348
|
-
owner: data.owner,
|
|
349
|
-
name: data.name,
|
|
350
|
-
metadata: data.metadata,
|
|
351
|
-
createdAt: data.createdAt
|
|
352
|
-
};
|
|
353
|
-
});
|
|
354
|
-
var StorageAccount = mongoose.models.StorageAccount || mongoose.model("StorageAccount", StorageAccountSchema);
|
|
355
|
-
var account_default = StorageAccount;
|
|
356
327
|
var validateMimeType = (mime, allowedTypes) => {
|
|
357
328
|
if (allowedTypes.includes("*/*")) return true;
|
|
358
329
|
return allowedTypes.some((pattern) => {
|
|
@@ -516,97 +487,6 @@ var getImageSettings = (fileSizeInBytes, qualityPreset, display, size, fit, posi
|
|
|
516
487
|
...resolvedPosition && { position: resolvedPosition }
|
|
517
488
|
};
|
|
518
489
|
};
|
|
519
|
-
var objectIdSchema = z.string().refine((val) => isValidObjectId(val), {
|
|
520
|
-
message: "Invalid ObjectId format"
|
|
521
|
-
});
|
|
522
|
-
var sanitizeFilename = (name) => {
|
|
523
|
-
return name.replace(/[<>:"|?*\x00-\x1F]/g, "").replace(/^\.+/, "").replace(/\.+$/, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\.\.\//g, "").replace(/\.\.+/g, "").split("/").pop() || "".trim().slice(0, 255);
|
|
524
|
-
};
|
|
525
|
-
var sanitizeRegexInput = (input) => {
|
|
526
|
-
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").slice(0, 100);
|
|
527
|
-
};
|
|
528
|
-
var nameSchema = z.string().min(1, "Name is required").max(255, "Name too long").transform(sanitizeFilename).refine((val) => val.length > 0, { message: "Invalid name after sanitization" });
|
|
529
|
-
var uploadChunkSchema = z.object({
|
|
530
|
-
chunkIndex: z.number().int().min(0).max(1e4),
|
|
531
|
-
totalChunks: z.number().int().min(1).max(1e4),
|
|
532
|
-
driveId: z.string().optional(),
|
|
533
|
-
fileName: nameSchema,
|
|
534
|
-
fileSize: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
535
|
-
fileType: z.string().min(1).max(255),
|
|
536
|
-
folderId: z.string().optional()
|
|
537
|
-
}).refine((data) => data.chunkIndex < data.totalChunks, {
|
|
538
|
-
message: "Chunk index must be less than total chunks"
|
|
539
|
-
});
|
|
540
|
-
var listQuerySchema = z.object({
|
|
541
|
-
folderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]),
|
|
542
|
-
limit: z.string().optional().transform((val) => {
|
|
543
|
-
const num = parseInt(val || "50", 10);
|
|
544
|
-
return Math.min(Math.max(1, num), 100);
|
|
545
|
-
}),
|
|
546
|
-
afterId: objectIdSchema.optional()
|
|
547
|
-
});
|
|
548
|
-
z.object({
|
|
549
|
-
id: objectIdSchema,
|
|
550
|
-
token: z.string().optional()
|
|
551
|
-
});
|
|
552
|
-
z.object({
|
|
553
|
-
id: objectIdSchema,
|
|
554
|
-
size: z.enum(["small", "medium", "large"]).optional().default("medium"),
|
|
555
|
-
token: z.string().optional()
|
|
556
|
-
});
|
|
557
|
-
var renameBodySchema = z.object({
|
|
558
|
-
id: objectIdSchema,
|
|
559
|
-
newName: nameSchema
|
|
560
|
-
});
|
|
561
|
-
var deleteQuerySchema = z.object({
|
|
562
|
-
id: objectIdSchema
|
|
563
|
-
});
|
|
564
|
-
z.object({
|
|
565
|
-
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
566
|
-
});
|
|
567
|
-
var createFolderBodySchema = z.object({
|
|
568
|
-
name: nameSchema,
|
|
569
|
-
parentId: z.union([z.literal("root"), objectIdSchema, z.string().length(0), z.undefined()]).optional()
|
|
570
|
-
});
|
|
571
|
-
var moveBodySchema = z.object({
|
|
572
|
-
ids: z.array(objectIdSchema).min(1).max(1e3),
|
|
573
|
-
targetFolderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]).optional()
|
|
574
|
-
});
|
|
575
|
-
z.object({
|
|
576
|
-
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
577
|
-
});
|
|
578
|
-
var searchQuerySchema = z.object({
|
|
579
|
-
q: z.string().min(1).max(100).transform(sanitizeRegexInput),
|
|
580
|
-
folderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]).optional(),
|
|
581
|
-
limit: z.string().optional().transform((val) => {
|
|
582
|
-
const num = parseInt(val || "50", 10);
|
|
583
|
-
return Math.min(Math.max(1, num), 100);
|
|
584
|
-
}),
|
|
585
|
-
trashed: z.string().optional().transform((val) => val === "true")
|
|
586
|
-
});
|
|
587
|
-
z.object({
|
|
588
|
-
id: objectIdSchema
|
|
589
|
-
});
|
|
590
|
-
var cancelQuerySchema = z.object({
|
|
591
|
-
id: z.string().uuid()
|
|
592
|
-
});
|
|
593
|
-
z.object({
|
|
594
|
-
days: z.number().int().min(1).max(365).optional()
|
|
595
|
-
});
|
|
596
|
-
var driveFileSchemaZod = z.object({
|
|
597
|
-
id: z.string(),
|
|
598
|
-
file: z.object({
|
|
599
|
-
name: z.string(),
|
|
600
|
-
mime: z.string(),
|
|
601
|
-
size: z.number()
|
|
602
|
-
})
|
|
603
|
-
});
|
|
604
|
-
|
|
605
|
-
// src/server/security/cryptoUtils.ts
|
|
606
|
-
function sanitizeContentDispositionFilename(filename) {
|
|
607
|
-
const basename = filename.replace(/^.*[\\\/]/, "");
|
|
608
|
-
return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
|
|
609
|
-
}
|
|
610
490
|
var generatePlaceholderThumbnail = async (outputPath, mimeType) => {
|
|
611
491
|
const typeParts = mimeType.split("/");
|
|
612
492
|
const subtype = typeParts[1] || "file";
|
|
@@ -803,6 +683,37 @@ var LocalStorageProvider = {
|
|
|
803
683
|
revokeToken: async (owner, accountId) => {
|
|
804
684
|
}
|
|
805
685
|
};
|
|
686
|
+
var StorageAccountSchema = new Schema(
|
|
687
|
+
{
|
|
688
|
+
owner: { type: Schema.Types.Mixed, default: null },
|
|
689
|
+
name: { type: String, required: true },
|
|
690
|
+
metadata: {
|
|
691
|
+
provider: { type: String, enum: ["GOOGLE"], required: true },
|
|
692
|
+
google: {
|
|
693
|
+
email: { type: String, required: true },
|
|
694
|
+
credentials: { type: Schema.Types.Mixed, required: true }
|
|
695
|
+
}
|
|
696
|
+
},
|
|
697
|
+
createdAt: { type: Date, default: Date.now }
|
|
698
|
+
},
|
|
699
|
+
{ minimize: false }
|
|
700
|
+
);
|
|
701
|
+
StorageAccountSchema.index({ owner: 1, "metadata.provider": 1 });
|
|
702
|
+
StorageAccountSchema.index({ owner: 1, "metadata.google.email": 1 });
|
|
703
|
+
StorageAccountSchema.method("toClient", async function() {
|
|
704
|
+
const data = this.toJSON();
|
|
705
|
+
return {
|
|
706
|
+
id: String(data._id),
|
|
707
|
+
owner: data.owner,
|
|
708
|
+
name: data.name,
|
|
709
|
+
metadata: data.metadata,
|
|
710
|
+
createdAt: data.createdAt
|
|
711
|
+
};
|
|
712
|
+
});
|
|
713
|
+
var StorageAccount = mongoose.models.StorageAccount || mongoose.model("StorageAccount", StorageAccountSchema);
|
|
714
|
+
var account_default = StorageAccount;
|
|
715
|
+
|
|
716
|
+
// src/server/providers/google.ts
|
|
806
717
|
var createAuthClient = async (owner, accountId) => {
|
|
807
718
|
const query = { owner, "metadata.provider": "GOOGLE" };
|
|
808
719
|
if (accountId) query._id = accountId;
|
|
@@ -1269,6 +1180,8 @@ var GoogleDriveProvider = {
|
|
|
1269
1180
|
}
|
|
1270
1181
|
}
|
|
1271
1182
|
};
|
|
1183
|
+
|
|
1184
|
+
// src/server/controllers/drive.ts
|
|
1272
1185
|
var getNextOrderValue = async (owner) => {
|
|
1273
1186
|
const lastItem = await drive_default.findOne({ owner }, {}, { sort: { order: -1 } });
|
|
1274
1187
|
return lastItem ? lastItem.order + 1 : 0;
|
|
@@ -1289,7 +1202,22 @@ var driveGetUrl = (fileId, options) => {
|
|
|
1289
1202
|
}
|
|
1290
1203
|
const signature = crypto2.createHmac("sha256", secret).update(`${fileId}:${expiryTimestamp}`).digest("hex");
|
|
1291
1204
|
const token = Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url");
|
|
1292
|
-
return
|
|
1205
|
+
return `${config.apiUrl || "/api/drive"}?action=serve&id=${fileId}&token=${token}`;
|
|
1206
|
+
};
|
|
1207
|
+
var driveAddSignedUrlToken = (item, config) => {
|
|
1208
|
+
let token;
|
|
1209
|
+
if (config.security?.signedUrls?.enabled && config.security.signedUrls.secret) {
|
|
1210
|
+
const { secret, expiresIn } = config.security.signedUrls;
|
|
1211
|
+
const expiryTimestamp = Math.floor(Date.now() / 1e3) + expiresIn;
|
|
1212
|
+
const signature = crypto2.createHmac("sha256", secret).update(`${item.id}:${expiryTimestamp}`).digest("hex");
|
|
1213
|
+
token = Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url");
|
|
1214
|
+
}
|
|
1215
|
+
const apiUrl = config.apiUrl || "/api/drive";
|
|
1216
|
+
const url = `${apiUrl}?action=serve&id=${item.id}${token ? `&token=${token}` : ""}`;
|
|
1217
|
+
return { ...item, token, url };
|
|
1218
|
+
};
|
|
1219
|
+
var driveAddSignedUrlTokens = (items, config) => {
|
|
1220
|
+
return items.map((item) => driveAddSignedUrlToken(item, config));
|
|
1293
1221
|
};
|
|
1294
1222
|
var driveReadFile = async (file) => {
|
|
1295
1223
|
let drive;
|
|
@@ -1449,7 +1377,8 @@ var driveList = async (options) => {
|
|
|
1449
1377
|
query._id = { $lt: afterId };
|
|
1450
1378
|
}
|
|
1451
1379
|
const items = await drive_default.find(query, {}, { sort: { order: 1, _id: -1 }, limit });
|
|
1452
|
-
|
|
1380
|
+
const config = getDriveConfig();
|
|
1381
|
+
return driveAddSignedUrlTokens(await Promise.all(items.map((item) => item.toClient())), config);
|
|
1453
1382
|
};
|
|
1454
1383
|
var driveListFiles = async (options) => {
|
|
1455
1384
|
const { key, folderId, accountId } = options;
|
|
@@ -1485,8 +1414,9 @@ var driveListFiles = async (options) => {
|
|
|
1485
1414
|
drive_default.find(query, {}, { sort: { createdAt: -1 }, skip, limit })
|
|
1486
1415
|
]);
|
|
1487
1416
|
const totalPages = Math.ceil(totalCount / limit);
|
|
1417
|
+
const config = getDriveConfig();
|
|
1488
1418
|
return {
|
|
1489
|
-
items: await Promise.all(items.map((item) => item.toClient())),
|
|
1419
|
+
items: driveAddSignedUrlTokens(await Promise.all(items.map((item) => item.toClient())), config),
|
|
1490
1420
|
pagination: {
|
|
1491
1421
|
page,
|
|
1492
1422
|
limit,
|
|
@@ -1778,8 +1708,97 @@ var driveCleanup = async () => {
|
|
|
1778
1708
|
}
|
|
1779
1709
|
return { removed, totalFreedInBytes };
|
|
1780
1710
|
};
|
|
1711
|
+
var objectIdSchema = z.string().refine((val) => isValidObjectId(val), {
|
|
1712
|
+
message: "Invalid ObjectId format"
|
|
1713
|
+
});
|
|
1714
|
+
var sanitizeFilename = (name) => {
|
|
1715
|
+
return name.replace(/[<>:"|?*\x00-\x1F]/g, "").replace(/^\.+/, "").replace(/\.+$/, "").replace(/\\/g, "/").replace(/\/+/g, "/").replace(/\.\.\//g, "").replace(/\.\.+/g, "").split("/").pop() || "".trim().slice(0, 255);
|
|
1716
|
+
};
|
|
1717
|
+
var sanitizeRegexInput = (input) => {
|
|
1718
|
+
return input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&").slice(0, 100);
|
|
1719
|
+
};
|
|
1720
|
+
var nameSchema = z.string().min(1, "Name is required").max(255, "Name too long").transform(sanitizeFilename).refine((val) => val.length > 0, { message: "Invalid name after sanitization" });
|
|
1721
|
+
var uploadChunkSchema = z.object({
|
|
1722
|
+
chunkIndex: z.number().int().min(0).max(1e4),
|
|
1723
|
+
totalChunks: z.number().int().min(1).max(1e4),
|
|
1724
|
+
driveId: z.string().optional(),
|
|
1725
|
+
fileName: nameSchema,
|
|
1726
|
+
fileSize: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
|
|
1727
|
+
fileType: z.string().min(1).max(255),
|
|
1728
|
+
folderId: z.string().optional()
|
|
1729
|
+
}).refine((data) => data.chunkIndex < data.totalChunks, {
|
|
1730
|
+
message: "Chunk index must be less than total chunks"
|
|
1731
|
+
});
|
|
1732
|
+
var listQuerySchema = z.object({
|
|
1733
|
+
folderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]),
|
|
1734
|
+
limit: z.string().optional().transform((val) => {
|
|
1735
|
+
const num = parseInt(val || "50", 10);
|
|
1736
|
+
return Math.min(Math.max(1, num), 100);
|
|
1737
|
+
}),
|
|
1738
|
+
afterId: objectIdSchema.optional()
|
|
1739
|
+
});
|
|
1740
|
+
z.object({
|
|
1741
|
+
id: objectIdSchema,
|
|
1742
|
+
token: z.string().optional()
|
|
1743
|
+
});
|
|
1744
|
+
z.object({
|
|
1745
|
+
id: objectIdSchema,
|
|
1746
|
+
size: z.enum(["small", "medium", "large"]).optional().default("medium"),
|
|
1747
|
+
token: z.string().optional()
|
|
1748
|
+
});
|
|
1749
|
+
var renameBodySchema = z.object({
|
|
1750
|
+
id: objectIdSchema,
|
|
1751
|
+
newName: nameSchema
|
|
1752
|
+
});
|
|
1753
|
+
var deleteQuerySchema = z.object({
|
|
1754
|
+
id: objectIdSchema
|
|
1755
|
+
});
|
|
1756
|
+
z.object({
|
|
1757
|
+
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
1758
|
+
});
|
|
1759
|
+
var createFolderBodySchema = z.object({
|
|
1760
|
+
name: nameSchema,
|
|
1761
|
+
parentId: z.union([z.literal("root"), objectIdSchema, z.string().length(0), z.undefined()]).optional()
|
|
1762
|
+
});
|
|
1763
|
+
var moveBodySchema = z.object({
|
|
1764
|
+
ids: z.array(objectIdSchema).min(1).max(1e3),
|
|
1765
|
+
targetFolderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]).optional()
|
|
1766
|
+
});
|
|
1767
|
+
z.object({
|
|
1768
|
+
ids: z.array(objectIdSchema).min(1).max(1e3)
|
|
1769
|
+
});
|
|
1770
|
+
var searchQuerySchema = z.object({
|
|
1771
|
+
q: z.string().min(1).max(100).transform(sanitizeRegexInput),
|
|
1772
|
+
folderId: z.union([z.literal("root"), objectIdSchema, z.undefined()]).optional(),
|
|
1773
|
+
limit: z.string().optional().transform((val) => {
|
|
1774
|
+
const num = parseInt(val || "50", 10);
|
|
1775
|
+
return Math.min(Math.max(1, num), 100);
|
|
1776
|
+
}),
|
|
1777
|
+
trashed: z.string().optional().transform((val) => val === "true")
|
|
1778
|
+
});
|
|
1779
|
+
z.object({
|
|
1780
|
+
id: objectIdSchema
|
|
1781
|
+
});
|
|
1782
|
+
var cancelQuerySchema = z.object({
|
|
1783
|
+
id: z.string().uuid()
|
|
1784
|
+
});
|
|
1785
|
+
z.object({
|
|
1786
|
+
days: z.number().int().min(1).max(365).optional()
|
|
1787
|
+
});
|
|
1788
|
+
var driveFileSchemaZod = z.object({
|
|
1789
|
+
id: z.string(),
|
|
1790
|
+
file: z.object({
|
|
1791
|
+
name: z.string(),
|
|
1792
|
+
mime: z.string(),
|
|
1793
|
+
size: z.number()
|
|
1794
|
+
})
|
|
1795
|
+
});
|
|
1781
1796
|
|
|
1782
|
-
// src/server/
|
|
1797
|
+
// src/server/security/cryptoUtils.ts
|
|
1798
|
+
function sanitizeContentDispositionFilename(filename) {
|
|
1799
|
+
const basename = filename.replace(/^.*[\\\/]/, "");
|
|
1800
|
+
return basename.replace(/["\r\n]/g, "").replace(/[^\x20-\x7E]/g, "").slice(0, 255);
|
|
1801
|
+
}
|
|
1783
1802
|
var getProvider = async (req, owner) => {
|
|
1784
1803
|
const accountId = req.headers["x-drive-account"];
|
|
1785
1804
|
if (!accountId || accountId === "LOCAL") {
|
|
@@ -1793,19 +1812,10 @@ var getProvider = async (req, owner) => {
|
|
|
1793
1812
|
return { provider: LocalStorageProvider };
|
|
1794
1813
|
};
|
|
1795
1814
|
var addSignedUrlToken = (item, config) => {
|
|
1796
|
-
|
|
1797
|
-
return item;
|
|
1798
|
-
}
|
|
1799
|
-
const { secret, expiresIn } = config.security.signedUrls;
|
|
1800
|
-
const expiryTimestamp = Math.floor(Date.now() / 1e3) + expiresIn;
|
|
1801
|
-
const signature = crypto2.createHmac("sha256", secret).update(`${item.id}:${expiryTimestamp}`).digest("hex");
|
|
1802
|
-
return { ...item, token: Buffer.from(`${expiryTimestamp}:${signature}`).toString("base64url") };
|
|
1815
|
+
return driveAddSignedUrlToken(item, config);
|
|
1803
1816
|
};
|
|
1804
1817
|
var addSignedUrlTokens = (items, config) => {
|
|
1805
|
-
|
|
1806
|
-
return items;
|
|
1807
|
-
}
|
|
1808
|
-
return items.map((item) => addSignedUrlToken(item, config));
|
|
1818
|
+
return driveAddSignedUrlTokens(items, config);
|
|
1809
1819
|
};
|
|
1810
1820
|
var applyCorsHeaders = (req, res, config) => {
|
|
1811
1821
|
const cors = config.cors;
|
|
@@ -2525,5 +2535,5 @@ var driveAPIHandler = async (req, res) => {
|
|
|
2525
2535
|
};
|
|
2526
2536
|
|
|
2527
2537
|
export { driveAPIHandler, driveCleanup, driveConfiguration, driveDelete, driveFilePath, driveFileSchemaZod, driveGetUrl, driveInfo, driveList, driveListFiles, driveReadFile, driveUpload, drive_default, getDriveConfig, getDriveInformation };
|
|
2528
|
-
//# sourceMappingURL=chunk-
|
|
2529
|
-
//# sourceMappingURL=chunk-
|
|
2538
|
+
//# sourceMappingURL=chunk-GV4HB2G6.js.map
|
|
2539
|
+
//# sourceMappingURL=chunk-GV4HB2G6.js.map
|