@harryy/react-file-browser 0.0.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/LICENSE +21 -0
- package/README.md +247 -0
- package/dist/adapters/cloud-adapter-base.d.ts +27 -0
- package/dist/adapters/cloud-adapter-base.d.ts.map +1 -0
- package/dist/adapters/in-memory/in-memory-file-browser-adapter.d.ts +53 -0
- package/dist/adapters/in-memory/in-memory-file-browser-adapter.d.ts.map +1 -0
- package/dist/adapters/in-memory/index.d.ts +2 -0
- package/dist/adapters/in-memory/index.d.ts.map +1 -0
- package/dist/adapters/in-memory/index.js +270 -0
- package/dist/adapters/in-memory/index.js.map +1 -0
- package/dist/adapters/r2/index.d.ts +7 -0
- package/dist/adapters/r2/index.d.ts.map +1 -0
- package/dist/adapters/r2/index.js +11 -0
- package/dist/adapters/r2/index.js.map +1 -0
- package/dist/adapters/s3/index.d.ts +7 -0
- package/dist/adapters/s3/index.d.ts.map +1 -0
- package/dist/adapters/s3/index.js +11 -0
- package/dist/adapters/s3/index.js.map +1 -0
- package/dist/adapters/s3-compatible-adapter.d.ts +50 -0
- package/dist/adapters/s3-compatible-adapter.d.ts.map +1 -0
- package/dist/adapters/supabase/index.d.ts +7 -0
- package/dist/adapters/supabase/index.d.ts.map +1 -0
- package/dist/adapters/supabase/index.js +216 -0
- package/dist/adapters/supabase/index.js.map +1 -0
- package/dist/adapters/supabase/supabase-file-browser-adapter.d.ts +88 -0
- package/dist/adapters/supabase/supabase-file-browser-adapter.d.ts.map +1 -0
- package/dist/chunks/browser-4lIkMGbo.js +436 -0
- package/dist/chunks/browser-4lIkMGbo.js.map +1 -0
- package/dist/chunks/cloud-adapter-base-CBUoZYLS.js +39 -0
- package/dist/chunks/cloud-adapter-base-CBUoZYLS.js.map +1 -0
- package/dist/chunks/path-CPm7s9NF.js +52 -0
- package/dist/chunks/path-CPm7s9NF.js.map +1 -0
- package/dist/chunks/s3-compatible-adapter-D9agsn9e.js +317 -0
- package/dist/chunks/s3-compatible-adapter-D9agsn9e.js.map +1 -0
- package/dist/components/file-browser.d.ts +28 -0
- package/dist/components/file-browser.d.ts.map +1 -0
- package/dist/core/path.d.ts +9 -0
- package/dist/core/path.d.ts.map +1 -0
- package/dist/core/types.d.ts +84 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/upload-drop.d.ts +7 -0
- package/dist/core/upload-drop.d.ts.map +1 -0
- package/dist/core/use-file-browser.d.ts +78 -0
- package/dist/core/use-file-browser.d.ts.map +1 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3212 -0
- package/dist/index.js.map +1 -0
- package/dist/theme/index.d.ts +25 -0
- package/dist/theme/index.d.ts.map +1 -0
- package/dist/theme/index.js +28 -0
- package/dist/theme/index.js.map +1 -0
- package/dist/transfers/file-browser-provider.d.ts +13 -0
- package/dist/transfers/file-browser-provider.d.ts.map +1 -0
- package/dist/transfers/transfer-manager.d.ts +118 -0
- package/dist/transfers/transfer-manager.d.ts.map +1 -0
- package/package.json +137 -0
|
@@ -0,0 +1,317 @@
|
|
|
1
|
+
import { a as e, c as t, n, o as r } from "./path-CPm7s9NF.js";
|
|
2
|
+
import { t as i } from "./cloud-adapter-base-CBUoZYLS.js";
|
|
3
|
+
import { AbortMultipartUploadCommand as a, CompleteMultipartUploadCommand as o, CopyObjectCommand as s, CreateMultipartUploadCommand as c, DeleteObjectsCommand as l, GetObjectCommand as u, HeadObjectCommand as d, ListObjectsV2Command as f, PutObjectCommand as p, UploadPartCommand as m } from "@aws-sdk/client-s3";
|
|
4
|
+
import { getSignedUrl as h } from "@aws-sdk/s3-request-presigner";
|
|
5
|
+
//#region src/adapters/s3-compatible-adapter.ts
|
|
6
|
+
var g = 3600, _ = 8 * 1024 * 1024, v = class {
|
|
7
|
+
createFolder;
|
|
8
|
+
rename;
|
|
9
|
+
move;
|
|
10
|
+
copy;
|
|
11
|
+
stat;
|
|
12
|
+
exists;
|
|
13
|
+
createMultipartUpload;
|
|
14
|
+
uploadPart;
|
|
15
|
+
completeMultipartUpload;
|
|
16
|
+
abortMultipartUpload;
|
|
17
|
+
bulkDownloadUrl;
|
|
18
|
+
delegate;
|
|
19
|
+
multipartSessions = /* @__PURE__ */ new Map();
|
|
20
|
+
sdk;
|
|
21
|
+
constructor(e, t = {}) {
|
|
22
|
+
if (!t.client || !t.bucket) {
|
|
23
|
+
this.delegate = new i(e, t), this.createFolder = this.delegate.createFolder?.bind(this.delegate), this.rename = this.delegate.rename?.bind(this.delegate), this.move = this.delegate.move?.bind(this.delegate), this.copy = this.delegate.copy?.bind(this.delegate), this.stat = this.delegate.stat?.bind(this.delegate), this.exists = this.delegate.exists?.bind(this.delegate), this.createMultipartUpload = this.delegate.createMultipartUpload?.bind(this.delegate), this.uploadPart = this.delegate.uploadPart?.bind(this.delegate), this.completeMultipartUpload = this.delegate.completeMultipartUpload?.bind(this.delegate), this.abortMultipartUpload = this.delegate.abortMultipartUpload?.bind(this.delegate), this.bulkDownloadUrl = this.delegate.bulkDownloadUrl?.bind(this.delegate);
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
this.sdk = {
|
|
27
|
+
bucket: t.bucket,
|
|
28
|
+
client: t.client,
|
|
29
|
+
multipartPartSize: Math.max(1, t.multipartPartSize ?? _),
|
|
30
|
+
prefix: y(t.prefix),
|
|
31
|
+
signedUrlExpiresIn: t.signedUrlExpiresIn ?? g
|
|
32
|
+
}, this.createFolder = this.createFolderEntry.bind(this), this.copy = this.copyEntries.bind(this), this.stat = this.statEntry.bind(this), this.exists = this.existsEntries.bind(this), this.createMultipartUpload = this.createMultipartUploadEntry.bind(this), this.uploadPart = this.uploadMultipartPart.bind(this), this.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this), this.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this);
|
|
33
|
+
}
|
|
34
|
+
async list(e, t = {}) {
|
|
35
|
+
if (!this.sdk) return this.delegate.list(e, t);
|
|
36
|
+
T(t.signal);
|
|
37
|
+
let i = await this.send(new f({
|
|
38
|
+
Bucket: this.sdk.bucket,
|
|
39
|
+
ContinuationToken: t.cursor,
|
|
40
|
+
Delimiter: "/",
|
|
41
|
+
Prefix: this.pathToPrefix(e)
|
|
42
|
+
})), a = i.CommonPrefixes?.flatMap((e) => e.Prefix ? [{
|
|
43
|
+
kind: "folder",
|
|
44
|
+
name: n(this.keyToPath(e.Prefix, !0)),
|
|
45
|
+
path: this.keyToPath(e.Prefix, !0)
|
|
46
|
+
}] : []) ?? [], o = i.Contents?.flatMap((e) => {
|
|
47
|
+
if (!e.Key || e.Key.endsWith("/")) return [];
|
|
48
|
+
let t = this.keyToPath(e.Key);
|
|
49
|
+
return t === r(t) ? [{
|
|
50
|
+
etag: b(e.ETag),
|
|
51
|
+
kind: "file",
|
|
52
|
+
mimeType: e.ContentType,
|
|
53
|
+
modifiedAt: e.LastModified?.toISOString(),
|
|
54
|
+
name: n(t),
|
|
55
|
+
path: t,
|
|
56
|
+
size: e.Size
|
|
57
|
+
}] : [];
|
|
58
|
+
}) ?? [];
|
|
59
|
+
return {
|
|
60
|
+
cursor: i.NextContinuationToken,
|
|
61
|
+
items: [...a, ...o].sort(x)
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
async createFolderEntry(e) {
|
|
65
|
+
let i = this.sdk;
|
|
66
|
+
if (!i) throw new t("not_supported", "S3 adapter method createFolder requires a host-backed implementation.");
|
|
67
|
+
let a = r(e);
|
|
68
|
+
return await this.send(new p({
|
|
69
|
+
Body: "",
|
|
70
|
+
Bucket: i.bucket,
|
|
71
|
+
ContentType: "application/x-directory",
|
|
72
|
+
Key: this.pathToPrefix(a)
|
|
73
|
+
})), {
|
|
74
|
+
kind: "folder",
|
|
75
|
+
name: n(a),
|
|
76
|
+
path: a
|
|
77
|
+
};
|
|
78
|
+
}
|
|
79
|
+
async delete(e) {
|
|
80
|
+
if (!this.sdk) return this.delegate.delete(e);
|
|
81
|
+
let t = /* @__PURE__ */ new Set();
|
|
82
|
+
for (let n of e) for (let e of await this.resolveKeysForPath(n)) t.add(e);
|
|
83
|
+
for (let e of w(Array.from(t), 1e3)) e.length !== 0 && await this.send(new l({
|
|
84
|
+
Bucket: this.sdk.bucket,
|
|
85
|
+
Delete: {
|
|
86
|
+
Objects: e.map((e) => ({ Key: e })),
|
|
87
|
+
Quiet: !0
|
|
88
|
+
}
|
|
89
|
+
}));
|
|
90
|
+
}
|
|
91
|
+
async signedUrl(e) {
|
|
92
|
+
return this.sdk ? h(this.sdk.client, new u({
|
|
93
|
+
Bucket: this.sdk.bucket,
|
|
94
|
+
Key: this.pathToKey(e)
|
|
95
|
+
}), { expiresIn: this.sdk.signedUrlExpiresIn }) : this.delegate.signedUrl(e);
|
|
96
|
+
}
|
|
97
|
+
async upload(e, t, r = {}) {
|
|
98
|
+
if (!this.sdk) return this.delegate.upload(e, t, r);
|
|
99
|
+
T(r.signal);
|
|
100
|
+
let i = await this.resolveUploadPath(e, r.onConflict);
|
|
101
|
+
r.onProgress?.(0, t.size), T(r.signal);
|
|
102
|
+
let a = await this.send(new p({
|
|
103
|
+
Body: t,
|
|
104
|
+
Bucket: this.sdk.bucket,
|
|
105
|
+
ContentType: t.type || void 0,
|
|
106
|
+
Key: this.pathToKey(i)
|
|
107
|
+
}));
|
|
108
|
+
return r.onProgress?.(t.size, t.size), {
|
|
109
|
+
etag: b(a.ETag),
|
|
110
|
+
kind: "file",
|
|
111
|
+
mimeType: t.type || void 0,
|
|
112
|
+
name: n(i) || t.name,
|
|
113
|
+
path: i,
|
|
114
|
+
size: t.size
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
async statEntry(e) {
|
|
118
|
+
let i = r(e), a = this.pathToKey(i);
|
|
119
|
+
try {
|
|
120
|
+
let e = await this.send(new d({
|
|
121
|
+
Bucket: this.sdk.bucket,
|
|
122
|
+
Key: a
|
|
123
|
+
}));
|
|
124
|
+
return {
|
|
125
|
+
etag: b(e.ETag),
|
|
126
|
+
kind: "file",
|
|
127
|
+
mimeType: e.ContentType,
|
|
128
|
+
modifiedAt: e.LastModified?.toISOString(),
|
|
129
|
+
name: n(i),
|
|
130
|
+
path: i,
|
|
131
|
+
size: e.ContentLength
|
|
132
|
+
};
|
|
133
|
+
} catch (e) {
|
|
134
|
+
if (!E(e)) throw e;
|
|
135
|
+
}
|
|
136
|
+
if (((await this.send(new f({
|
|
137
|
+
Bucket: this.sdk.bucket,
|
|
138
|
+
MaxKeys: 1,
|
|
139
|
+
Prefix: this.pathToPrefix(i)
|
|
140
|
+
}))).Contents?.length ?? 0) > 0) return {
|
|
141
|
+
kind: "folder",
|
|
142
|
+
name: n(i),
|
|
143
|
+
path: i
|
|
144
|
+
};
|
|
145
|
+
throw new t("not_found", `No file browser entry exists at ${i}`);
|
|
146
|
+
}
|
|
147
|
+
async existsEntries(e) {
|
|
148
|
+
let t = {};
|
|
149
|
+
return await Promise.all(e.map(async (e) => {
|
|
150
|
+
let n = r(e);
|
|
151
|
+
try {
|
|
152
|
+
await this.statEntry(n), t[n] = !0;
|
|
153
|
+
} catch (e) {
|
|
154
|
+
if (!E(e)) throw e;
|
|
155
|
+
t[n] = !1;
|
|
156
|
+
}
|
|
157
|
+
})), t;
|
|
158
|
+
}
|
|
159
|
+
async copyEntries(t, i) {
|
|
160
|
+
for (let a of t) {
|
|
161
|
+
let t = r(a), o = this.pathToPrefix(t), c = this.pathToKey(e(i, n(t))), l = await this.resolveKeysForPath(t);
|
|
162
|
+
for (let e of l) {
|
|
163
|
+
let t = e.startsWith(o) ? e.slice(o.length) : n(this.keyToPath(e)), r = t ? `${c}/${t}` : c;
|
|
164
|
+
await this.send(new s({
|
|
165
|
+
Bucket: this.sdk.bucket,
|
|
166
|
+
CopySource: S(this.sdk.bucket, e),
|
|
167
|
+
Key: r
|
|
168
|
+
}));
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
async createMultipartUploadEntry(e, n) {
|
|
173
|
+
let i = r(e), a = this.pathToKey(i), o = await this.send(new c({
|
|
174
|
+
Bucket: this.sdk.bucket,
|
|
175
|
+
Key: a
|
|
176
|
+
}));
|
|
177
|
+
if (!o.UploadId) throw new t("not_supported", "S3-compatible multipart upload did not return an upload id.");
|
|
178
|
+
return this.multipartSessions.set(o.UploadId, {
|
|
179
|
+
key: a,
|
|
180
|
+
path: i,
|
|
181
|
+
size: n
|
|
182
|
+
}), {
|
|
183
|
+
partSize: this.sdk.multipartPartSize,
|
|
184
|
+
uploadId: o.UploadId
|
|
185
|
+
};
|
|
186
|
+
}
|
|
187
|
+
async uploadMultipartPart({ chunk: e, onProgress: t, partNumber: n, signal: r, uploadId: i }) {
|
|
188
|
+
T(r);
|
|
189
|
+
let a = this.getMultipartSession(i), o = await this.send(new m({
|
|
190
|
+
Body: e,
|
|
191
|
+
Bucket: this.sdk.bucket,
|
|
192
|
+
Key: a.key,
|
|
193
|
+
PartNumber: n,
|
|
194
|
+
UploadId: i
|
|
195
|
+
}));
|
|
196
|
+
return t?.(e.size), { etag: b(o.ETag) ?? `part-${n}` };
|
|
197
|
+
}
|
|
198
|
+
async completeMultipartUploadEntry({ parts: e, uploadId: t }) {
|
|
199
|
+
let r = this.getMultipartSession(t), i = await this.send(new o({
|
|
200
|
+
Bucket: this.sdk.bucket,
|
|
201
|
+
Key: r.key,
|
|
202
|
+
MultipartUpload: { Parts: e.map((e) => ({
|
|
203
|
+
ETag: e.etag,
|
|
204
|
+
PartNumber: e.partNumber
|
|
205
|
+
})) },
|
|
206
|
+
UploadId: t
|
|
207
|
+
}));
|
|
208
|
+
return this.multipartSessions.delete(t), {
|
|
209
|
+
etag: b(i.ETag),
|
|
210
|
+
kind: "file",
|
|
211
|
+
name: n(r.path),
|
|
212
|
+
path: r.path,
|
|
213
|
+
size: r.size
|
|
214
|
+
};
|
|
215
|
+
}
|
|
216
|
+
async abortMultipartUploadEntry(e) {
|
|
217
|
+
let t = this.getMultipartSession(e);
|
|
218
|
+
await this.send(new a({
|
|
219
|
+
Bucket: this.sdk.bucket,
|
|
220
|
+
Key: t.key,
|
|
221
|
+
UploadId: e
|
|
222
|
+
})), this.multipartSessions.delete(e);
|
|
223
|
+
}
|
|
224
|
+
async resolveKeysForPath(e) {
|
|
225
|
+
let t = r(e), n = this.pathToKey(t), i = /* @__PURE__ */ new Set();
|
|
226
|
+
await this.objectExists(n) && i.add(n);
|
|
227
|
+
let a = this.pathToPrefix(t), o;
|
|
228
|
+
do {
|
|
229
|
+
let e = await this.send(new f({
|
|
230
|
+
Bucket: this.sdk.bucket,
|
|
231
|
+
ContinuationToken: o,
|
|
232
|
+
Prefix: a
|
|
233
|
+
}));
|
|
234
|
+
for (let t of e.Contents ?? []) t.Key && i.add(t.Key);
|
|
235
|
+
o = e.NextContinuationToken;
|
|
236
|
+
} while (o);
|
|
237
|
+
return Array.from(i);
|
|
238
|
+
}
|
|
239
|
+
async objectExists(e) {
|
|
240
|
+
try {
|
|
241
|
+
return await this.send(new d({
|
|
242
|
+
Bucket: this.sdk.bucket,
|
|
243
|
+
Key: e
|
|
244
|
+
})), !0;
|
|
245
|
+
} catch (e) {
|
|
246
|
+
if (E(e)) return !1;
|
|
247
|
+
throw e;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
async resolveUploadPath(e, n) {
|
|
251
|
+
let i = r(e);
|
|
252
|
+
if (n === "replace" || !await this.objectExists(this.pathToKey(i))) return i;
|
|
253
|
+
if (n !== "keep-both") throw new t("conflict", `A file browser entry already exists at ${i}`);
|
|
254
|
+
for (let t = 1; t < 2 ** 53 - 1; t += 1) if (i = C(e, t), !await this.objectExists(this.pathToKey(i))) return i;
|
|
255
|
+
throw new t("conflict", `Could not allocate a unique file browser path for ${e}`);
|
|
256
|
+
}
|
|
257
|
+
getMultipartSession(e) {
|
|
258
|
+
let n = this.multipartSessions.get(e);
|
|
259
|
+
if (!n) throw new t("not_found", `No multipart upload session exists for ${e}`);
|
|
260
|
+
return n;
|
|
261
|
+
}
|
|
262
|
+
pathToKey(e) {
|
|
263
|
+
let t = r(e), n = t === "/" ? "" : t.slice(1);
|
|
264
|
+
return this.sdk.prefix && n ? `${this.sdk.prefix}/${n}` : this.sdk.prefix || n;
|
|
265
|
+
}
|
|
266
|
+
pathToPrefix(e) {
|
|
267
|
+
let t = this.pathToKey(e);
|
|
268
|
+
return t ? `${t.replace(/\/$/, "")}/` : "";
|
|
269
|
+
}
|
|
270
|
+
keyToPath(e, t = !1) {
|
|
271
|
+
let n = e;
|
|
272
|
+
return this.sdk.prefix && n === this.sdk.prefix ? n = "" : this.sdk.prefix && n.startsWith(`${this.sdk.prefix}/`) && (n = n.slice(this.sdk.prefix.length + 1)), t && (n = n.replace(/\/$/, "")), r(`/${n}`);
|
|
273
|
+
}
|
|
274
|
+
async send(e) {
|
|
275
|
+
try {
|
|
276
|
+
return await this.sdk.client.send(e);
|
|
277
|
+
} catch (e) {
|
|
278
|
+
throw D(e);
|
|
279
|
+
}
|
|
280
|
+
}
|
|
281
|
+
};
|
|
282
|
+
function y(e) {
|
|
283
|
+
return (e ?? "").trim().replace(/^\/+|\/+$/g, "");
|
|
284
|
+
}
|
|
285
|
+
function b(e) {
|
|
286
|
+
return e?.replace(/^"|"$/g, "");
|
|
287
|
+
}
|
|
288
|
+
function x(e, t) {
|
|
289
|
+
return e.kind === t.kind ? e.name.localeCompare(t.name) : e.kind === "folder" ? -1 : 1;
|
|
290
|
+
}
|
|
291
|
+
function S(e, t) {
|
|
292
|
+
return `${e}/${encodeURIComponent(t).replace(/%2F/g, "/")}`;
|
|
293
|
+
}
|
|
294
|
+
function C(e, t) {
|
|
295
|
+
let i = r(e), a = n(i), o = a.lastIndexOf("."), s = o > 0, c = s ? a.slice(0, o) : a, l = s ? a.slice(o) : "";
|
|
296
|
+
return r(`${i.slice(0, Math.max(1, i.lastIndexOf("/")))}/${c} (${t})${l}`);
|
|
297
|
+
}
|
|
298
|
+
function w(e, t) {
|
|
299
|
+
let n = [];
|
|
300
|
+
for (let r = 0; r < e.length; r += t) n.push(e.slice(r, r + t));
|
|
301
|
+
return n;
|
|
302
|
+
}
|
|
303
|
+
function T(e) {
|
|
304
|
+
if (e?.aborted) throw new t("aborted", "The operation was aborted.");
|
|
305
|
+
}
|
|
306
|
+
function E(e) {
|
|
307
|
+
return e instanceof t && e.code === "not_found";
|
|
308
|
+
}
|
|
309
|
+
function D(e) {
|
|
310
|
+
if (e instanceof t) return e;
|
|
311
|
+
let n = e, r = n.$metadata?.httpStatusCode;
|
|
312
|
+
return n.name === "AbortError" ? new t("aborted", "The operation was aborted.", { cause: e }) : r === 403 || n.name === "AccessDenied" ? new t("access_denied", n.message ?? "Access denied by the object store.", { cause: e }) : r === 404 || n.name === "NotFound" || n.name === "NoSuchKey" ? new t("not_found", n.message ?? "The object does not exist.", { cause: e }) : new t("not_supported", n.message ?? "The object store request failed.", { cause: e });
|
|
313
|
+
}
|
|
314
|
+
//#endregion
|
|
315
|
+
export { v as t };
|
|
316
|
+
|
|
317
|
+
//# sourceMappingURL=s3-compatible-adapter-D9agsn9e.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-compatible-adapter-D9agsn9e.js","names":[],"sources":["../../src/adapters/s3-compatible-adapter.ts"],"sourcesContent":["import {\n\tAbortMultipartUploadCommand,\n\tCompleteMultipartUploadCommand,\n\tCopyObjectCommand,\n\tCreateMultipartUploadCommand,\n\tDeleteObjectsCommand,\n\tGetObjectCommand,\n\tHeadObjectCommand,\n\tListObjectsV2Command,\n\tPutObjectCommand,\n\tUploadPartCommand\n} from '@aws-sdk/client-s3'\nimport { getSignedUrl } from '@aws-sdk/s3-request-presigner'\nimport { FileBrowserAdapterError } from '../core/types'\nimport type {\n\tFileBrowserAdapter,\n\tFileBrowserListOptions,\n\tFileBrowserListResult,\n\tFileBrowserUploadOptions,\n\tFileNode,\n\tMultipartUploadPart\n} from '../core/types'\nimport { getFileBrowserBasename, joinFileBrowserPath, normalizeFileBrowserPath } from '../core/path'\nimport { UnsupportedCloudFileBrowserAdapter } from './cloud-adapter-base'\nimport type { CloudAdapterName, CloudFileBrowserAdapterOptions } from './cloud-adapter-base'\n\nexport type S3CompatibleClient = {\n\tsend(command: object): Promise<unknown>\n}\n\nexport type S3CompatibleFileBrowserAdapterOptions = CloudFileBrowserAdapterOptions & {\n\tbucket?: string\n\tclient?: S3CompatibleClient\n\tmultipartPartSize?: number\n\tprefix?: string\n\tsignedUrlExpiresIn?: number\n}\n\ntype S3SdkConfig = {\n\tbucket: string\n\tclient: S3CompatibleClient\n\tmultipartPartSize: number\n\tprefix: string\n\tsignedUrlExpiresIn: number\n}\n\ntype S3ListResponse = {\n\tCommonPrefixes?: Array<{ Prefix?: string }>\n\tContents?: Array<{\n\t\tContentType?: string\n\t\tETag?: string\n\t\tKey?: string\n\t\tLastModified?: Date\n\t\tSize?: number\n\t}>\n\tNextContinuationToken?: string\n}\n\ntype S3HeadResponse = {\n\tContentLength?: number\n\tContentType?: string\n\tETag?: string\n\tLastModified?: Date\n}\n\ntype S3PutResponse = {\n\tETag?: string\n}\n\ntype S3MultipartCreateResponse = {\n\tUploadId?: string\n}\n\ntype S3UploadPartResponse = {\n\tETag?: string\n}\n\ntype S3MultipartSession = {\n\tkey: string\n\tpath: string\n\tsize: number\n}\n\nconst DEFAULT_SIGNED_URL_EXPIRES_IN = 60 * 60\nconst DEFAULT_MULTIPART_PART_SIZE = 8 * 1024 * 1024\n\nexport class S3CompatibleFileBrowserAdapter implements FileBrowserAdapter {\n\tcreateFolder?: NonNullable<FileBrowserAdapter['createFolder']>\n\trename?: NonNullable<FileBrowserAdapter['rename']>\n\tmove?: NonNullable<FileBrowserAdapter['move']>\n\tcopy?: NonNullable<FileBrowserAdapter['copy']>\n\tstat?: NonNullable<FileBrowserAdapter['stat']>\n\texists?: NonNullable<FileBrowserAdapter['exists']>\n\tcreateMultipartUpload?: NonNullable<FileBrowserAdapter['createMultipartUpload']>\n\tuploadPart?: NonNullable<FileBrowserAdapter['uploadPart']>\n\tcompleteMultipartUpload?: NonNullable<FileBrowserAdapter['completeMultipartUpload']>\n\tabortMultipartUpload?: NonNullable<FileBrowserAdapter['abortMultipartUpload']>\n\tbulkDownloadUrl?: NonNullable<FileBrowserAdapter['bulkDownloadUrl']>\n\n\tprivate readonly delegate?: UnsupportedCloudFileBrowserAdapter\n\tprivate readonly multipartSessions = new Map<string, S3MultipartSession>()\n\tprivate readonly sdk?: S3SdkConfig\n\n\tconstructor(adapterName: CloudAdapterName, options: S3CompatibleFileBrowserAdapterOptions = {}) {\n\t\tif (!options.client || !options.bucket) {\n\t\t\tthis.delegate = new UnsupportedCloudFileBrowserAdapter(adapterName, options)\n\t\t\tthis.createFolder = this.delegate.createFolder?.bind(this.delegate)\n\t\t\tthis.rename = this.delegate.rename?.bind(this.delegate)\n\t\t\tthis.move = this.delegate.move?.bind(this.delegate)\n\t\t\tthis.copy = this.delegate.copy?.bind(this.delegate)\n\t\t\tthis.stat = this.delegate.stat?.bind(this.delegate)\n\t\t\tthis.exists = this.delegate.exists?.bind(this.delegate)\n\t\t\tthis.createMultipartUpload = this.delegate.createMultipartUpload?.bind(this.delegate)\n\t\t\tthis.uploadPart = this.delegate.uploadPart?.bind(this.delegate)\n\t\t\tthis.completeMultipartUpload = this.delegate.completeMultipartUpload?.bind(this.delegate)\n\t\t\tthis.abortMultipartUpload = this.delegate.abortMultipartUpload?.bind(this.delegate)\n\t\t\tthis.bulkDownloadUrl = this.delegate.bulkDownloadUrl?.bind(this.delegate)\n\t\t\treturn\n\t\t}\n\n\t\tthis.sdk = {\n\t\t\tbucket: options.bucket,\n\t\t\tclient: options.client,\n\t\t\tmultipartPartSize: Math.max(1, options.multipartPartSize ?? DEFAULT_MULTIPART_PART_SIZE),\n\t\t\tprefix: normalizeObjectPrefix(options.prefix),\n\t\t\tsignedUrlExpiresIn: options.signedUrlExpiresIn ?? DEFAULT_SIGNED_URL_EXPIRES_IN\n\t\t}\n\t\tthis.createFolder = this.createFolderEntry.bind(this)\n\t\tthis.copy = this.copyEntries.bind(this)\n\t\tthis.stat = this.statEntry.bind(this)\n\t\tthis.exists = this.existsEntries.bind(this)\n\t\tthis.createMultipartUpload = this.createMultipartUploadEntry.bind(this)\n\t\tthis.uploadPart = this.uploadMultipartPart.bind(this)\n\t\tthis.completeMultipartUpload = this.completeMultipartUploadEntry.bind(this)\n\t\tthis.abortMultipartUpload = this.abortMultipartUploadEntry.bind(this)\n\t}\n\n\tasync list(path: string, opts: FileBrowserListOptions = {}): Promise<FileBrowserListResult> {\n\t\tif (!this.sdk) {\n\t\t\treturn this.delegate!.list(path, opts)\n\t\t}\n\n\t\tthrowIfAborted(opts.signal)\n\t\tconst response = await this.send<S3ListResponse>(\n\t\t\tnew ListObjectsV2Command({\n\t\t\t\tBucket: this.sdk.bucket,\n\t\t\t\tContinuationToken: opts.cursor,\n\t\t\t\tDelimiter: '/',\n\t\t\t\tPrefix: this.pathToPrefix(path)\n\t\t\t})\n\t\t)\n\t\tconst folderItems =\n\t\t\tresponse.CommonPrefixes?.flatMap((entry) => {\n\t\t\t\tif (!entry.Prefix) {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tkind: 'folder' as const,\n\t\t\t\t\t\tname: getFileBrowserBasename(this.keyToPath(entry.Prefix, true)),\n\t\t\t\t\t\tpath: this.keyToPath(entry.Prefix, true)\n\t\t\t\t\t}\n\t\t\t\t]\n\t\t\t}) ?? []\n\t\tconst fileItems =\n\t\t\tresponse.Contents?.flatMap((entry) => {\n\t\t\t\tif (!entry.Key || entry.Key.endsWith('/')) {\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tconst path = this.keyToPath(entry.Key)\n\t\t\t\tif (path === normalizeFileBrowserPath(path)) {\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tetag: cleanEtag(entry.ETag),\n\t\t\t\t\t\t\tkind: 'file' as const,\n\t\t\t\t\t\t\tmimeType: entry.ContentType,\n\t\t\t\t\t\t\tmodifiedAt: entry.LastModified?.toISOString(),\n\t\t\t\t\t\t\tname: getFileBrowserBasename(path),\n\t\t\t\t\t\t\tpath,\n\t\t\t\t\t\t\tsize: entry.Size\n\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t\treturn []\n\t\t\t}) ?? []\n\n\t\treturn {\n\t\t\tcursor: response.NextContinuationToken,\n\t\t\titems: [...folderItems, ...fileItems].sort(compareNodes)\n\t\t}\n\t}\n\n\tprivate async createFolderEntry(path: string): Promise<FileNode> {\n\t\tconst sdk = this.sdk\n\t\tif (!sdk) {\n\t\t\tthrow new FileBrowserAdapterError(\n\t\t\t\t'not_supported',\n\t\t\t\t'S3 adapter method createFolder requires a host-backed implementation.'\n\t\t\t)\n\t\t}\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tawait this.send<S3PutResponse>(\n\t\t\tnew PutObjectCommand({\n\t\t\t\tBody: '',\n\t\t\t\tBucket: sdk.bucket,\n\t\t\t\tContentType: 'application/x-directory',\n\t\t\t\tKey: this.pathToPrefix(normalized)\n\t\t\t})\n\t\t)\n\t\treturn {\n\t\t\tkind: 'folder',\n\t\t\tname: getFileBrowserBasename(normalized),\n\t\t\tpath: normalized\n\t\t}\n\t}\n\n\tasync delete(paths: string[]): Promise<void> {\n\t\tif (!this.sdk) {\n\t\t\treturn this.delegate!.delete(paths)\n\t\t}\n\n\t\tconst keys = new Set<string>()\n\t\tfor (const path of paths) {\n\t\t\tfor (const key of await this.resolveKeysForPath(path)) {\n\t\t\t\tkeys.add(key)\n\t\t\t}\n\t\t}\n\n\t\tfor (const chunk of chunkArray(Array.from(keys), 1000)) {\n\t\t\tif (chunk.length === 0) {\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tawait this.send<unknown>(\n\t\t\t\tnew DeleteObjectsCommand({\n\t\t\t\t\tBucket: this.sdk.bucket,\n\t\t\t\t\tDelete: {\n\t\t\t\t\t\tObjects: chunk.map((key) => ({ Key: key })),\n\t\t\t\t\t\tQuiet: true\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t)\n\t\t}\n\t}\n\n\tasync signedUrl(path: string): Promise<string> {\n\t\tif (!this.sdk) {\n\t\t\treturn this.delegate!.signedUrl(path)\n\t\t}\n\n\t\treturn getSignedUrl(\n\t\t\tthis.sdk.client as never,\n\t\t\tnew GetObjectCommand({\n\t\t\t\tBucket: this.sdk.bucket,\n\t\t\t\tKey: this.pathToKey(path)\n\t\t\t}),\n\t\t\t{ expiresIn: this.sdk.signedUrlExpiresIn }\n\t\t)\n\t}\n\n\tasync upload(path: string, file: File, opts: FileBrowserUploadOptions = {}): Promise<FileNode> {\n\t\tif (!this.sdk) {\n\t\t\treturn this.delegate!.upload(path, file, opts)\n\t\t}\n\n\t\tthrowIfAborted(opts.signal)\n\t\tconst normalized = await this.resolveUploadPath(path, opts.onConflict)\n\t\topts.onProgress?.(0, file.size)\n\t\tthrowIfAborted(opts.signal)\n\n\t\tconst response = await this.send<S3PutResponse>(\n\t\t\tnew PutObjectCommand({\n\t\t\t\tBody: file,\n\t\t\t\tBucket: this.sdk.bucket,\n\t\t\t\tContentType: file.type || undefined,\n\t\t\t\tKey: this.pathToKey(normalized)\n\t\t\t})\n\t\t)\n\t\topts.onProgress?.(file.size, file.size)\n\n\t\treturn {\n\t\t\tetag: cleanEtag(response.ETag),\n\t\t\tkind: 'file',\n\t\t\tmimeType: file.type || undefined,\n\t\t\tname: getFileBrowserBasename(normalized) || file.name,\n\t\t\tpath: normalized,\n\t\t\tsize: file.size\n\t\t}\n\t}\n\n\tprivate async statEntry(path: string): Promise<FileNode> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst key = this.pathToKey(normalized)\n\n\t\ttry {\n\t\t\tconst response = await this.send<S3HeadResponse>(\n\t\t\t\tnew HeadObjectCommand({\n\t\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\t\tKey: key\n\t\t\t\t})\n\t\t\t)\n\t\t\treturn {\n\t\t\t\tetag: cleanEtag(response.ETag),\n\t\t\t\tkind: 'file',\n\t\t\t\tmimeType: response.ContentType,\n\t\t\t\tmodifiedAt: response.LastModified?.toISOString(),\n\t\t\t\tname: getFileBrowserBasename(normalized),\n\t\t\t\tpath: normalized,\n\t\t\t\tsize: response.ContentLength\n\t\t\t}\n\t\t} catch (error) {\n\t\t\tif (!isAdapterNotFound(error)) {\n\t\t\t\tthrow error\n\t\t\t}\n\t\t}\n\n\t\tconst response = await this.send<S3ListResponse>(\n\t\t\tnew ListObjectsV2Command({\n\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\tMaxKeys: 1,\n\t\t\t\tPrefix: this.pathToPrefix(normalized)\n\t\t\t})\n\t\t)\n\t\tif ((response.Contents?.length ?? 0) > 0) {\n\t\t\treturn {\n\t\t\t\tkind: 'folder',\n\t\t\t\tname: getFileBrowserBasename(normalized),\n\t\t\t\tpath: normalized\n\t\t\t}\n\t\t}\n\n\t\tthrow new FileBrowserAdapterError('not_found', `No file browser entry exists at ${normalized}`)\n\t}\n\n\tprivate async existsEntries(paths: string[]): Promise<Record<string, boolean>> {\n\t\tconst entries: Record<string, boolean> = {}\n\t\tawait Promise.all(\n\t\t\tpaths.map(async (path) => {\n\t\t\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\t\t\ttry {\n\t\t\t\t\tawait this.statEntry(normalized)\n\t\t\t\t\tentries[normalized] = true\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!isAdapterNotFound(error)) {\n\t\t\t\t\t\tthrow error\n\t\t\t\t\t}\n\t\t\t\t\tentries[normalized] = false\n\t\t\t\t}\n\t\t\t})\n\t\t)\n\t\treturn entries\n\t}\n\n\tprivate async copyEntries(from: string[], toDir: string): Promise<void> {\n\t\tfor (const sourcePath of from) {\n\t\t\tconst normalizedSource = normalizeFileBrowserPath(sourcePath)\n\t\t\tconst sourceBase = this.pathToPrefix(normalizedSource)\n\t\t\tconst destinationBase = this.pathToKey(joinFileBrowserPath(toDir, getFileBrowserBasename(normalizedSource)))\n\t\t\tconst keys = await this.resolveKeysForPath(normalizedSource)\n\n\t\t\tfor (const sourceKey of keys) {\n\t\t\t\tconst suffix = sourceKey.startsWith(sourceBase)\n\t\t\t\t\t? sourceKey.slice(sourceBase.length)\n\t\t\t\t\t: getFileBrowserBasename(this.keyToPath(sourceKey))\n\t\t\t\tconst destinationKey = suffix ? `${destinationBase}/${suffix}` : destinationBase\n\t\t\t\tawait this.send<unknown>(\n\t\t\t\t\tnew CopyObjectCommand({\n\t\t\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\t\t\tCopySource: encodeCopySource(this.sdk!.bucket, sourceKey),\n\t\t\t\t\t\tKey: destinationKey\n\t\t\t\t\t})\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\tprivate async createMultipartUploadEntry(\n\t\tpath: string,\n\t\tsize: number\n\t): Promise<{ uploadId: string; partSize: number }> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst key = this.pathToKey(normalized)\n\t\tconst response = await this.send<S3MultipartCreateResponse>(\n\t\t\tnew CreateMultipartUploadCommand({\n\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\tKey: key\n\t\t\t})\n\t\t)\n\t\tif (!response.UploadId) {\n\t\t\tthrow new FileBrowserAdapterError('not_supported', 'S3-compatible multipart upload did not return an upload id.')\n\t\t}\n\t\tthis.multipartSessions.set(response.UploadId, {\n\t\t\tkey,\n\t\t\tpath: normalized,\n\t\t\tsize\n\t\t})\n\t\treturn {\n\t\t\tpartSize: this.sdk!.multipartPartSize,\n\t\t\tuploadId: response.UploadId\n\t\t}\n\t}\n\n\tprivate async uploadMultipartPart({\n\t\tchunk,\n\t\tonProgress,\n\t\tpartNumber,\n\t\tsignal,\n\t\tuploadId\n\t}: {\n\t\tuploadId: string\n\t\tpartNumber: number\n\t\tchunk: Blob\n\t\tsignal?: AbortSignal\n\t\tonProgress?: (loaded: number) => void\n\t}): Promise<{ etag: string }> {\n\t\tthrowIfAborted(signal)\n\t\tconst session = this.getMultipartSession(uploadId)\n\t\tconst response = await this.send<S3UploadPartResponse>(\n\t\t\tnew UploadPartCommand({\n\t\t\t\tBody: chunk,\n\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\tKey: session.key,\n\t\t\t\tPartNumber: partNumber,\n\t\t\t\tUploadId: uploadId\n\t\t\t})\n\t\t)\n\t\tonProgress?.(chunk.size)\n\t\treturn {\n\t\t\tetag: cleanEtag(response.ETag) ?? `part-${partNumber}`\n\t\t}\n\t}\n\n\tprivate async completeMultipartUploadEntry({\n\t\tparts,\n\t\tuploadId\n\t}: {\n\t\tuploadId: string\n\t\tparts: MultipartUploadPart[]\n\t}): Promise<FileNode> {\n\t\tconst session = this.getMultipartSession(uploadId)\n\t\tconst response = await this.send<S3PutResponse>(\n\t\t\tnew CompleteMultipartUploadCommand({\n\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\tKey: session.key,\n\t\t\t\tMultipartUpload: {\n\t\t\t\t\tParts: parts.map((part) => ({\n\t\t\t\t\t\tETag: part.etag,\n\t\t\t\t\t\tPartNumber: part.partNumber\n\t\t\t\t\t}))\n\t\t\t\t},\n\t\t\t\tUploadId: uploadId\n\t\t\t})\n\t\t)\n\t\tthis.multipartSessions.delete(uploadId)\n\t\treturn {\n\t\t\tetag: cleanEtag(response.ETag),\n\t\t\tkind: 'file',\n\t\t\tname: getFileBrowserBasename(session.path),\n\t\t\tpath: session.path,\n\t\t\tsize: session.size\n\t\t}\n\t}\n\n\tprivate async abortMultipartUploadEntry(uploadId: string): Promise<void> {\n\t\tconst session = this.getMultipartSession(uploadId)\n\t\tawait this.send<unknown>(\n\t\t\tnew AbortMultipartUploadCommand({\n\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\tKey: session.key,\n\t\t\t\tUploadId: uploadId\n\t\t\t})\n\t\t)\n\t\tthis.multipartSessions.delete(uploadId)\n\t}\n\n\tprivate async resolveKeysForPath(path: string): Promise<string[]> {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst exactKey = this.pathToKey(normalized)\n\t\tconst keys = new Set<string>()\n\n\t\tif (await this.objectExists(exactKey)) {\n\t\t\tkeys.add(exactKey)\n\t\t}\n\n\t\tconst folderPrefix = this.pathToPrefix(normalized)\n\t\tlet cursor: string | undefined\n\t\tdo {\n\t\t\tconst response = await this.send<S3ListResponse>(\n\t\t\t\tnew ListObjectsV2Command({\n\t\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\t\tContinuationToken: cursor,\n\t\t\t\t\tPrefix: folderPrefix\n\t\t\t\t})\n\t\t\t)\n\t\t\tfor (const entry of response.Contents ?? []) {\n\t\t\t\tif (entry.Key) {\n\t\t\t\t\tkeys.add(entry.Key)\n\t\t\t\t}\n\t\t\t}\n\t\t\tcursor = response.NextContinuationToken\n\t\t} while (cursor)\n\n\t\treturn Array.from(keys)\n\t}\n\n\tprivate async objectExists(key: string): Promise<boolean> {\n\t\ttry {\n\t\t\tawait this.send<S3HeadResponse>(\n\t\t\t\tnew HeadObjectCommand({\n\t\t\t\t\tBucket: this.sdk!.bucket,\n\t\t\t\t\tKey: key\n\t\t\t\t})\n\t\t\t)\n\t\t\treturn true\n\t\t} catch (error) {\n\t\t\tif (isAdapterNotFound(error)) {\n\t\t\t\treturn false\n\t\t\t}\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tprivate async resolveUploadPath(path: string, onConflict: FileBrowserUploadOptions['onConflict']): Promise<string> {\n\t\tlet normalized = normalizeFileBrowserPath(path)\n\t\tif (onConflict === 'replace') {\n\t\t\treturn normalized\n\t\t}\n\n\t\tif (!(await this.objectExists(this.pathToKey(normalized)))) {\n\t\t\treturn normalized\n\t\t}\n\n\t\tif (onConflict !== 'keep-both') {\n\t\t\tthrow new FileBrowserAdapterError('conflict', `A file browser entry already exists at ${normalized}`)\n\t\t}\n\n\t\tfor (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n\t\t\tnormalized = addCopySuffix(path, index)\n\t\t\tif (!(await this.objectExists(this.pathToKey(normalized)))) {\n\t\t\t\treturn normalized\n\t\t\t}\n\t\t}\n\n\t\tthrow new FileBrowserAdapterError('conflict', `Could not allocate a unique file browser path for ${path}`)\n\t}\n\n\tprivate getMultipartSession(uploadId: string): S3MultipartSession {\n\t\tconst session = this.multipartSessions.get(uploadId)\n\t\tif (!session) {\n\t\t\tthrow new FileBrowserAdapterError('not_found', `No multipart upload session exists for ${uploadId}`)\n\t\t}\n\t\treturn session\n\t}\n\n\tprivate pathToKey(path: string): string {\n\t\tconst normalized = normalizeFileBrowserPath(path)\n\t\tconst relative = normalized === '/' ? '' : normalized.slice(1)\n\t\tif (this.sdk!.prefix && relative) {\n\t\t\treturn `${this.sdk!.prefix}/${relative}`\n\t\t}\n\t\treturn this.sdk!.prefix || relative\n\t}\n\n\tprivate pathToPrefix(path: string): string {\n\t\tconst key = this.pathToKey(path)\n\t\treturn key ? `${key.replace(/\\/$/, '')}/` : ''\n\t}\n\n\tprivate keyToPath(key: string, folder = false): string {\n\t\tlet relative = key\n\t\tif (this.sdk!.prefix && relative === this.sdk!.prefix) {\n\t\t\trelative = ''\n\t\t} else if (this.sdk!.prefix && relative.startsWith(`${this.sdk!.prefix}/`)) {\n\t\t\trelative = relative.slice(this.sdk!.prefix.length + 1)\n\t\t}\n\t\tif (folder) {\n\t\t\trelative = relative.replace(/\\/$/, '')\n\t\t}\n\t\treturn normalizeFileBrowserPath(`/${relative}`)\n\t}\n\n\tprivate async send<T>(command: object): Promise<T> {\n\t\ttry {\n\t\t\treturn (await this.sdk!.client.send(command)) as T\n\t\t} catch (error) {\n\t\t\tthrow toS3AdapterError(error)\n\t\t}\n\t}\n}\n\nfunction normalizeObjectPrefix(prefix: string | undefined): string {\n\treturn (prefix ?? '').trim().replace(/^\\/+|\\/+$/g, '')\n}\n\nfunction cleanEtag(etag: string | undefined): string | undefined {\n\treturn etag?.replace(/^\"|\"$/g, '')\n}\n\nfunction compareNodes(left: FileNode, right: FileNode): number {\n\tif (left.kind !== right.kind) {\n\t\treturn left.kind === 'folder' ? -1 : 1\n\t}\n\treturn left.name.localeCompare(right.name)\n}\n\nfunction encodeCopySource(bucket: string, key: string): string {\n\treturn `${bucket}/${encodeURIComponent(key).replace(/%2F/g, '/')}`\n}\n\nfunction addCopySuffix(path: string, index: number): string {\n\tconst normalized = normalizeFileBrowserPath(path)\n\tconst basename = getFileBrowserBasename(normalized)\n\tconst dotIndex = basename.lastIndexOf('.')\n\tconst hasExtension = dotIndex > 0\n\tconst stem = hasExtension ? basename.slice(0, dotIndex) : basename\n\tconst extension = hasExtension ? basename.slice(dotIndex) : ''\n\tconst dir = normalized.slice(0, Math.max(1, normalized.lastIndexOf('/')))\n\treturn normalizeFileBrowserPath(`${dir}/${stem} (${index})${extension}`)\n}\n\nfunction chunkArray<T>(items: T[], size: number): T[][] {\n\tconst chunks: T[][] = []\n\tfor (let index = 0; index < items.length; index += size) {\n\t\tchunks.push(items.slice(index, index + size))\n\t}\n\treturn chunks\n}\n\nfunction throwIfAborted(signal: AbortSignal | undefined): void {\n\tif (signal?.aborted) {\n\t\tthrow new FileBrowserAdapterError('aborted', 'The operation was aborted.')\n\t}\n}\n\nfunction isAdapterNotFound(error: unknown): boolean {\n\treturn error instanceof FileBrowserAdapterError && error.code === 'not_found'\n}\n\nfunction toS3AdapterError(error: unknown): FileBrowserAdapterError {\n\tif (error instanceof FileBrowserAdapterError) {\n\t\treturn error\n\t}\n\n\tconst candidate = error as {\n\t\t$metadata?: { httpStatusCode?: number }\n\t\tmessage?: string\n\t\tname?: string\n\t}\n\tconst status = candidate.$metadata?.httpStatusCode\n\tif (candidate.name === 'AbortError') {\n\t\treturn new FileBrowserAdapterError('aborted', 'The operation was aborted.', {\n\t\t\tcause: error\n\t\t})\n\t}\n\tif (status === 403 || candidate.name === 'AccessDenied') {\n\t\treturn new FileBrowserAdapterError('access_denied', candidate.message ?? 'Access denied by the object store.', {\n\t\t\tcause: error\n\t\t})\n\t}\n\tif (status === 404 || candidate.name === 'NotFound' || candidate.name === 'NoSuchKey') {\n\t\treturn new FileBrowserAdapterError('not_found', candidate.message ?? 'The object does not exist.', { cause: error })\n\t}\n\treturn new FileBrowserAdapterError('not_supported', candidate.message ?? 'The object store request failed.', {\n\t\tcause: error\n\t})\n}\n"],"mappings":"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"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { FileBrowserDensity } from '../theme';
|
|
2
|
+
import type { FileBrowserAdapter } from '../core/types';
|
|
3
|
+
import type { FileBrowserUploadCandidate } from '../core/upload-drop';
|
|
4
|
+
export type FileBrowserProps = {
|
|
5
|
+
adapter: FileBrowserAdapter;
|
|
6
|
+
initialPath?: string;
|
|
7
|
+
density?: FileBrowserDensity;
|
|
8
|
+
readOnly?: boolean;
|
|
9
|
+
showDetailsPanel?: boolean;
|
|
10
|
+
uploadPolicy?: FileBrowserUploadPolicy;
|
|
11
|
+
warnZipSizeBytes?: number;
|
|
12
|
+
};
|
|
13
|
+
export type FileBrowserUploadPolicy = {
|
|
14
|
+
allowedMimeTypes?: string[];
|
|
15
|
+
maxFileSizeBytes?: number;
|
|
16
|
+
remainingQuotaBytes?: number;
|
|
17
|
+
validate?: (candidate: FileBrowserUploadCandidate, context: {
|
|
18
|
+
acceptedBytes: number;
|
|
19
|
+
currentPath: string;
|
|
20
|
+
}) => string | string[] | null | undefined;
|
|
21
|
+
};
|
|
22
|
+
export type FileBrowserUploadRejection = {
|
|
23
|
+
fileName: string;
|
|
24
|
+
relativePath: string;
|
|
25
|
+
reasons: string[];
|
|
26
|
+
};
|
|
27
|
+
export declare function FileBrowser({ adapter, initialPath, density, readOnly, showDetailsPanel, uploadPolicy, warnZipSizeBytes }: FileBrowserProps): import("react").JSX.Element;
|
|
28
|
+
//# sourceMappingURL=file-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-browser.d.ts","sourceRoot":"","sources":["../../src/components/file-browser.tsx"],"names":[],"mappings":"AAuBA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAA;AAKlD,OAAO,KAAK,EAAE,kBAAkB,EAAY,MAAM,eAAe,CAAA;AAEjE,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAA;AAIrE,MAAM,MAAM,gBAAgB,GAAG;IAC9B,OAAO,EAAE,kBAAkB,CAAA;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,OAAO,CAAC,EAAE,kBAAkB,CAAA;IAC5B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,uBAAuB,CAAA;IACtC,gBAAgB,CAAC,EAAE,MAAM,CAAA;CACzB,CAAA;AAED,MAAM,MAAM,uBAAuB,GAAG;IACrC,gBAAgB,CAAC,EAAE,MAAM,EAAE,CAAA;IAC3B,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,mBAAmB,CAAC,EAAE,MAAM,CAAA;IAC5B,QAAQ,CAAC,EAAE,CACV,SAAS,EAAE,0BAA0B,EACrC,OAAO,EAAE;QACR,aAAa,EAAE,MAAM,CAAA;QACrB,WAAW,EAAE,MAAM,CAAA;KACnB,KACG,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,GAAG,SAAS,CAAA;CACzC,CAAA;AAED,MAAM,MAAM,0BAA0B,GAAG;IACxC,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;IACpB,OAAO,EAAE,MAAM,EAAE,CAAA;CACjB,CAAA;AAgFD,wBAAgB,WAAW,CAAC,EAC3B,OAAO,EACP,WAAiB,EACjB,OAAuB,EACvB,QAAgB,EAChB,gBAAuB,EACvB,YAAY,EACZ,gBAAgB,EAChB,EAAE,gBAAgB,+BAy0ClB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare const ROOT_PATH = "/";
|
|
2
|
+
export declare function normalizeFileBrowserPath(path: string): string;
|
|
3
|
+
export declare function getFileBrowserBasename(path: string): string;
|
|
4
|
+
export declare function getFileBrowserDirname(path: string): string;
|
|
5
|
+
export declare function joinFileBrowserPath(dir: string, name: string): string;
|
|
6
|
+
export declare function assertValidFileBrowserName(name: string): void;
|
|
7
|
+
export declare function isFileBrowserDescendantOrSelf(parentPath: string, candidatePath: string): boolean;
|
|
8
|
+
export declare function replaceFileBrowserPathPrefix(path: string, fromPrefix: string, toPrefix: string): string;
|
|
9
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/core/path.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,SAAS,MAAM,CAAA;AAE5B,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU7D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQ3D;AAED,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAS1D;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAIrE;AAED,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAM7D;AAED,wBAAgB,6BAA6B,CAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAShG;AAED,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM,CAcvG"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
export type FileNodeKind = 'file' | 'folder';
|
|
2
|
+
export type FileNode = {
|
|
3
|
+
path: string;
|
|
4
|
+
name: string;
|
|
5
|
+
kind: FileNodeKind;
|
|
6
|
+
size?: number;
|
|
7
|
+
mimeType?: string;
|
|
8
|
+
modifiedAt?: string;
|
|
9
|
+
etag?: string;
|
|
10
|
+
thumbnailUrl?: string;
|
|
11
|
+
};
|
|
12
|
+
export type FileBrowserListOptions = {
|
|
13
|
+
cursor?: string;
|
|
14
|
+
signal?: AbortSignal;
|
|
15
|
+
};
|
|
16
|
+
export type FileBrowserListResult = {
|
|
17
|
+
items: FileNode[];
|
|
18
|
+
cursor?: string;
|
|
19
|
+
};
|
|
20
|
+
export type FileBrowserUploadOptions = {
|
|
21
|
+
onProgress?: (loaded: number, total: number) => void;
|
|
22
|
+
onConflict?: 'replace' | 'keep-both';
|
|
23
|
+
signal?: AbortSignal;
|
|
24
|
+
};
|
|
25
|
+
export type MultipartUploadPart = {
|
|
26
|
+
partNumber: number;
|
|
27
|
+
etag: string;
|
|
28
|
+
};
|
|
29
|
+
export type FileBrowserAdapter = {
|
|
30
|
+
list(path: string, opts?: FileBrowserListOptions): Promise<FileBrowserListResult>;
|
|
31
|
+
createFolder?(path: string): Promise<FileNode>;
|
|
32
|
+
delete(paths: string[]): Promise<void>;
|
|
33
|
+
signedUrl(path: string): Promise<string>;
|
|
34
|
+
upload(path: string, file: File, opts?: FileBrowserUploadOptions): Promise<FileNode>;
|
|
35
|
+
rename?(path: string, newName: string): Promise<FileNode>;
|
|
36
|
+
move?(from: string[], toDir: string): Promise<void>;
|
|
37
|
+
copy?(from: string[], toDir: string): Promise<void>;
|
|
38
|
+
stat?(path: string): Promise<FileNode>;
|
|
39
|
+
exists?(paths: string[]): Promise<Record<string, boolean>>;
|
|
40
|
+
createMultipartUpload?(path: string, size: number): Promise<{
|
|
41
|
+
uploadId: string;
|
|
42
|
+
partSize: number;
|
|
43
|
+
}>;
|
|
44
|
+
uploadPart?(args: {
|
|
45
|
+
uploadId: string;
|
|
46
|
+
partNumber: number;
|
|
47
|
+
chunk: Blob;
|
|
48
|
+
signal?: AbortSignal;
|
|
49
|
+
onProgress?: (loaded: number) => void;
|
|
50
|
+
}): Promise<{
|
|
51
|
+
etag: string;
|
|
52
|
+
}>;
|
|
53
|
+
completeMultipartUpload?(args: {
|
|
54
|
+
uploadId: string;
|
|
55
|
+
parts: MultipartUploadPart[];
|
|
56
|
+
}): Promise<FileNode>;
|
|
57
|
+
abortMultipartUpload?(uploadId: string): Promise<void>;
|
|
58
|
+
bulkDownloadUrl?(paths: string[]): Promise<{
|
|
59
|
+
url: string;
|
|
60
|
+
expiresAt: string;
|
|
61
|
+
}>;
|
|
62
|
+
};
|
|
63
|
+
export declare class FileBrowserAdapterError extends Error {
|
|
64
|
+
readonly code: 'access_denied' | 'aborted' | 'conflict' | 'invalid_path' | 'not_found' | 'not_supported';
|
|
65
|
+
constructor(code: FileBrowserAdapterError['code'], message: string, options?: ErrorOptions);
|
|
66
|
+
}
|
|
67
|
+
export type FileBrowserBulkAction = 'delete' | 'move' | 'copy';
|
|
68
|
+
export type FileBrowserBulkActionFailure = {
|
|
69
|
+
path: string;
|
|
70
|
+
message: string;
|
|
71
|
+
};
|
|
72
|
+
export declare class FileBrowserBulkActionError extends Error {
|
|
73
|
+
readonly action: FileBrowserBulkAction;
|
|
74
|
+
readonly succeededPaths: string[];
|
|
75
|
+
readonly failures: FileBrowserBulkActionFailure[];
|
|
76
|
+
readonly totalCount: number;
|
|
77
|
+
constructor(action: FileBrowserBulkAction, options: {
|
|
78
|
+
succeededPaths: string[];
|
|
79
|
+
failures: FileBrowserBulkActionFailure[];
|
|
80
|
+
totalCount: number;
|
|
81
|
+
message?: string;
|
|
82
|
+
});
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/core/types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type FileBrowserUploadCandidate = {
|
|
2
|
+
file: File;
|
|
3
|
+
relativePath: string;
|
|
4
|
+
};
|
|
5
|
+
export declare function collectUploadCandidatesFromDataTransfer(dataTransfer: DataTransfer): Promise<FileBrowserUploadCandidate[]>;
|
|
6
|
+
export declare function getFileBrowserUploadCandidates(files: File[] | FileList): FileBrowserUploadCandidate[];
|
|
7
|
+
//# sourceMappingURL=upload-drop.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-drop.d.ts","sourceRoot":"","sources":["../../src/core/upload-drop.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,0BAA0B,GAAG;IACxC,IAAI,EAAE,IAAI,CAAA;IACV,YAAY,EAAE,MAAM,CAAA;CACpB,CAAA;AAwBD,wBAAsB,uCAAuC,CAC5D,YAAY,EAAE,YAAY,GACxB,OAAO,CAAC,0BAA0B,EAAE,CAAC,CAcvC;AAED,wBAAgB,8BAA8B,CAAC,KAAK,EAAE,IAAI,EAAE,GAAG,QAAQ,GAAG,0BAA0B,EAAE,CAKrG"}
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import type { Dispatch, SetStateAction } from 'react';
|
|
2
|
+
import type { FileBrowserAdapter, FileNode } from './types';
|
|
3
|
+
export type FileBrowserStatus = 'idle' | 'loading' | 'ready' | 'error';
|
|
4
|
+
export type FileBrowserView = 'grid' | 'list';
|
|
5
|
+
export type FileBrowserKindFilter = 'all' | 'files' | 'folders';
|
|
6
|
+
export type FileBrowserUploadConflictResolution = 'replace' | 'keep-both' | 'skip';
|
|
7
|
+
export type FileBrowserUploadFilesOptions = {
|
|
8
|
+
onConflict?: FileBrowserUploadConflictResolution;
|
|
9
|
+
};
|
|
10
|
+
export type FileBrowserClipboard = {
|
|
11
|
+
type: 'copy';
|
|
12
|
+
paths: string[];
|
|
13
|
+
} | {
|
|
14
|
+
type: 'cut';
|
|
15
|
+
paths: string[];
|
|
16
|
+
} | null;
|
|
17
|
+
export type FileBrowserCapabilities = {
|
|
18
|
+
createFolder: boolean;
|
|
19
|
+
rename: boolean;
|
|
20
|
+
move: boolean;
|
|
21
|
+
copy: boolean;
|
|
22
|
+
stat: boolean;
|
|
23
|
+
exists: boolean;
|
|
24
|
+
multipart: boolean;
|
|
25
|
+
bulkDownload: boolean;
|
|
26
|
+
};
|
|
27
|
+
export type UseFileBrowserOptions = {
|
|
28
|
+
adapter: FileBrowserAdapter;
|
|
29
|
+
initialPath?: string;
|
|
30
|
+
};
|
|
31
|
+
export type UseFileBrowserResult = {
|
|
32
|
+
adapter: FileBrowserAdapter;
|
|
33
|
+
capabilities: FileBrowserCapabilities;
|
|
34
|
+
currentPath: string;
|
|
35
|
+
status: FileBrowserStatus;
|
|
36
|
+
items: FileNode[];
|
|
37
|
+
error: Error | null;
|
|
38
|
+
hasMore: boolean;
|
|
39
|
+
selectedPaths: string[];
|
|
40
|
+
selectedItems: FileNode[];
|
|
41
|
+
focusedPath: string | null;
|
|
42
|
+
clipboard: FileBrowserClipboard;
|
|
43
|
+
view: FileBrowserView;
|
|
44
|
+
searchQuery: string;
|
|
45
|
+
filterKind: FileBrowserKindFilter;
|
|
46
|
+
sortBy: 'name' | 'modifiedAt' | 'size';
|
|
47
|
+
sortDirection: 'asc' | 'desc';
|
|
48
|
+
filteredItems: FileNode[];
|
|
49
|
+
setView: Dispatch<SetStateAction<FileBrowserView>>;
|
|
50
|
+
setSearchQuery: Dispatch<SetStateAction<string>>;
|
|
51
|
+
setFilterKind: Dispatch<SetStateAction<FileBrowserKindFilter>>;
|
|
52
|
+
setSortBy: Dispatch<SetStateAction<'name' | 'modifiedAt' | 'size'>>;
|
|
53
|
+
setSortDirection: Dispatch<SetStateAction<'asc' | 'desc'>>;
|
|
54
|
+
refresh: () => Promise<void>;
|
|
55
|
+
loadMore: () => Promise<void>;
|
|
56
|
+
navigate: (path: string) => Promise<void>;
|
|
57
|
+
open: (node: FileNode) => Promise<void>;
|
|
58
|
+
selectOnly: (path: string) => void;
|
|
59
|
+
toggleSelection: (path: string) => void;
|
|
60
|
+
selectRange: (path: string) => void;
|
|
61
|
+
setSelection: (paths: string[], options?: {
|
|
62
|
+
additive?: boolean;
|
|
63
|
+
}) => void;
|
|
64
|
+
selectAllLoaded: () => void;
|
|
65
|
+
clearSelection: () => void;
|
|
66
|
+
createFolder: (name: string) => Promise<FileNode>;
|
|
67
|
+
rename: (path: string, newName: string) => Promise<FileNode>;
|
|
68
|
+
deleteSelected: () => Promise<void>;
|
|
69
|
+
deletePaths: (paths: string[]) => Promise<void>;
|
|
70
|
+
movePathsTo: (paths: string[], toDir: string) => Promise<void>;
|
|
71
|
+
moveSelectedTo: (toDir: string) => Promise<void>;
|
|
72
|
+
copySelection: (paths?: string[]) => void;
|
|
73
|
+
cutSelection: (paths?: string[]) => void;
|
|
74
|
+
pasteInto: (toDir: string) => Promise<void>;
|
|
75
|
+
uploadFiles: (files: File[] | FileList, options?: FileBrowserUploadFilesOptions) => Promise<FileNode[]>;
|
|
76
|
+
};
|
|
77
|
+
export declare function useFileBrowser({ adapter, initialPath }: UseFileBrowserOptions): UseFileBrowserResult;
|
|
78
|
+
//# sourceMappingURL=use-file-browser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"use-file-browser.d.ts","sourceRoot":"","sources":["../../src/core/use-file-browser.ts"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { FileBrowserAdapterError, FileBrowserBulkActionError, type FileBrowserAdapter, type FileBrowserBulkAction, type FileBrowserBulkActionFailure, type FileBrowserListOptions, type FileBrowserListResult, type FileBrowserUploadOptions, type FileNode, type FileNodeKind, type MultipartUploadPart } from './core/types';
|
|
2
|
+
export { ROOT_PATH, getFileBrowserBasename, getFileBrowserDirname, isFileBrowserDescendantOrSelf, joinFileBrowserPath, normalizeFileBrowserPath, replaceFileBrowserPathPrefix } from './core/path';
|
|
3
|
+
export { FILE_BROWSER_THEME_CONTRACT, getFileBrowserDensityAttributes, type FileBrowserDensity } from './theme';
|
|
4
|
+
export { useFileBrowser, type FileBrowserCapabilities, type FileBrowserClipboard, type FileBrowserStatus, type FileBrowserView, type UseFileBrowserOptions, type UseFileBrowserResult } from './core/use-file-browser';
|
|
5
|
+
export { FileBrowser, type FileBrowserProps } from './components/file-browser';
|
|
6
|
+
export type { FileBrowserUploadPolicy, FileBrowserUploadRejection } from './components/file-browser';
|
|
7
|
+
export { FileBrowserProvider, useTransferSnapshot, useTransfers, type FileBrowserProviderProps } from './transfers/file-browser-provider';
|
|
8
|
+
export { TransferManager, type BulkDownloadJob, type EnqueueUploadInput, type PrepareBulkDownloadInput, type PrepareSingleDownloadInput, type ResumeRestoredUploadInput, type TransferManagerOptions, type TransferSnapshot, type TransferStatus, type UploadTransfer, type UploadTransferGroup } from './transfers/transfer-manager';
|
|
9
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACN,uBAAuB,EACvB,0BAA0B,EAC1B,KAAK,kBAAkB,EACvB,KAAK,qBAAqB,EAC1B,KAAK,4BAA4B,EACjC,KAAK,sBAAsB,EAC3B,KAAK,qBAAqB,EAC1B,KAAK,wBAAwB,EAC7B,KAAK,QAAQ,EACb,KAAK,YAAY,EACjB,KAAK,mBAAmB,EACxB,MAAM,cAAc,CAAA;AACrB,OAAO,EACN,SAAS,EACT,sBAAsB,EACtB,qBAAqB,EACrB,6BAA6B,EAC7B,mBAAmB,EACnB,wBAAwB,EACxB,4BAA4B,EAC5B,MAAM,aAAa,CAAA;AACpB,OAAO,EAAE,2BAA2B,EAAE,+BAA+B,EAAE,KAAK,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAC/G,OAAO,EACN,cAAc,EACd,KAAK,uBAAuB,EAC5B,KAAK,oBAAoB,EACzB,KAAK,iBAAiB,EACtB,KAAK,eAAe,EACpB,KAAK,qBAAqB,EAC1B,KAAK,oBAAoB,EACzB,MAAM,yBAAyB,CAAA;AAChC,OAAO,EAAE,WAAW,EAAE,KAAK,gBAAgB,EAAE,MAAM,2BAA2B,CAAA;AAC9E,YAAY,EAAE,uBAAuB,EAAE,0BAA0B,EAAE,MAAM,2BAA2B,CAAA;AACpG,OAAO,EACN,mBAAmB,EACnB,mBAAmB,EACnB,YAAY,EACZ,KAAK,wBAAwB,EAC7B,MAAM,mCAAmC,CAAA;AAC1C,OAAO,EACN,eAAe,EACf,KAAK,eAAe,EACpB,KAAK,kBAAkB,EACvB,KAAK,wBAAwB,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,yBAAyB,EAC9B,KAAK,sBAAsB,EAC3B,KAAK,gBAAgB,EACrB,KAAK,cAAc,EACnB,KAAK,cAAc,EACnB,KAAK,mBAAmB,EACxB,MAAM,8BAA8B,CAAA"}
|