sfiledl 2.0.0 → 2.1.1
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/lib.cjs +381 -132
- package/build/lib.cjs.map +1 -14
- package/build/lib.d.ts +40 -32
- package/build/lib.mjs +342 -124
- package/build/lib.mjs.map +1 -12
- package/changelog +685 -0
- package/license +661 -0
- package/package.json +6 -3
- package/readme.md +170 -0
package/build/lib.cjs
CHANGED
|
@@ -1,137 +1,386 @@
|
|
|
1
|
-
'use strict'
|
|
1
|
+
'use strict';
|
|
2
2
|
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true })
|
|
3
|
+
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
5
|
+
const path = require('path');
|
|
6
|
+
const fs = require('fs/promises');
|
|
7
|
+
const playwright = require('playwright');
|
|
8
|
+
const os = require('os');
|
|
9
|
+
|
|
10
|
+
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
11
|
+
|
|
12
|
+
function _interopNamespace(e) {
|
|
13
|
+
if (e && e.__esModule) return e;
|
|
14
|
+
const n = Object.create(null);
|
|
15
|
+
if (e) {
|
|
16
|
+
for (const k in e) {
|
|
17
|
+
if (k !== 'default') {
|
|
18
|
+
const d = Object.getOwnPropertyDescriptor(e, k);
|
|
19
|
+
Object.defineProperty(n, k, d.get ? d : {
|
|
20
|
+
enumerable: true,
|
|
21
|
+
get: function () { return e[k]; }
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
n.default = e;
|
|
27
|
+
return n;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const path__default = /*#__PURE__*/_interopDefault(path);
|
|
31
|
+
const fs__namespace = /*#__PURE__*/_interopNamespace(fs);
|
|
32
|
+
const os__default = /*#__PURE__*/_interopDefault(os);
|
|
33
|
+
|
|
34
|
+
class AppError extends Error {
|
|
35
|
+
code;
|
|
36
|
+
retryable;
|
|
37
|
+
timestamp;
|
|
38
|
+
context;
|
|
39
|
+
constructor(message, code, retryable = false, context) {
|
|
40
|
+
super(message);
|
|
41
|
+
this.code = code;
|
|
42
|
+
this.retryable = retryable;
|
|
43
|
+
this.name = this.constructor.name;
|
|
44
|
+
this.timestamp = new Date().toISOString();
|
|
45
|
+
this.context = context ? { ...context } : undefined;
|
|
46
|
+
Error.captureStackTrace?.(this, this.constructor);
|
|
47
|
+
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
name: this.name,
|
|
51
|
+
message: this.message,
|
|
52
|
+
code: this.code,
|
|
53
|
+
retryable: this.retryable,
|
|
54
|
+
timestamp: this.timestamp,
|
|
55
|
+
context: this.context,
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
class ValidationError extends AppError {
|
|
61
|
+
constructor(message, context) {
|
|
62
|
+
super(message, 'VALIDATION_ERROR', false, context);
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
class NetworkError extends AppError {
|
|
66
|
+
constructor(message, context) {
|
|
67
|
+
super(message, 'NETWORK_ERROR', true, context);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
class FileError extends AppError {
|
|
71
|
+
constructor(message, context) {
|
|
72
|
+
super(message, 'FILE_ERROR', false, context);
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
class BrowserError extends AppError {
|
|
76
|
+
constructor(message, context) {
|
|
77
|
+
super(message, 'BROWSER_ERROR', true, context);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
const DEFAULTS = {
|
|
82
|
+
userAgent: 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',
|
|
83
|
+
headless: true,
|
|
84
|
+
timeout: 100000,
|
|
85
|
+
downloadButtonTimeout: 100000,
|
|
86
|
+
fallbackWaitMs: 5000,
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
class SfilePageInteractions {
|
|
90
|
+
page;
|
|
91
|
+
logger;
|
|
92
|
+
constructor(page, logger) {
|
|
93
|
+
this.page = page;
|
|
94
|
+
this.logger = logger;
|
|
95
|
+
}
|
|
96
|
+
async waitForDownloadButton(timeout) {
|
|
97
|
+
this.logger.debug('Waiting for #download button to be visible');
|
|
98
|
+
const button = this.page.locator('#download');
|
|
99
|
+
await button.waitFor({ state: 'visible', timeout });
|
|
100
|
+
this.logger.debug('Waiting for button to become active (href != "#" and pointerEvents != "none")');
|
|
101
|
+
await this.page.waitForFunction(() => {
|
|
102
|
+
const btn = document.querySelector('#download');
|
|
103
|
+
if (!btn)
|
|
104
|
+
return false;
|
|
105
|
+
const href = btn.getAttribute('href');
|
|
106
|
+
const style = window.getComputedStyle(btn);
|
|
107
|
+
return href && href !== '#' && style.pointerEvents !== 'none';
|
|
108
|
+
}, { timeout });
|
|
109
|
+
}
|
|
110
|
+
async extractIntermediateUrl() {
|
|
111
|
+
this.logger.debug('Extracting href from #download');
|
|
112
|
+
const href = await this.page.$eval('#download', (el) => el.href);
|
|
113
|
+
if (!href || href === '#') {
|
|
114
|
+
throw new NetworkError('Download button href is invalid', { href });
|
|
115
|
+
}
|
|
116
|
+
return href;
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
function sanitizeFilename(name, replacement = '_') {
|
|
121
|
+
const sanitized = name
|
|
122
|
+
.replace(/[<>:"/\\|?*\x00-\x1F]/g, replacement)
|
|
123
|
+
.replace(new RegExp(`${replacement}+`, 'g'), replacement)
|
|
124
|
+
.trim()
|
|
125
|
+
.slice(0, 255);
|
|
126
|
+
return sanitized || 'file.bin';
|
|
127
|
+
}
|
|
128
|
+
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
|
|
129
|
+
function safeStringify(value) {
|
|
130
|
+
try {
|
|
131
|
+
return JSON.stringify(value);
|
|
132
|
+
}
|
|
133
|
+
catch {
|
|
134
|
+
return '[unserializable]';
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
class BrowserManager {
|
|
139
|
+
logger;
|
|
140
|
+
opts;
|
|
141
|
+
browser = null;
|
|
142
|
+
context = null;
|
|
143
|
+
page = null;
|
|
144
|
+
interactions = null;
|
|
145
|
+
debugDir = null;
|
|
146
|
+
constructor(logger, opts) {
|
|
147
|
+
this.logger = logger;
|
|
148
|
+
this.opts = opts;
|
|
149
|
+
}
|
|
150
|
+
async launch() {
|
|
151
|
+
try {
|
|
152
|
+
this.logger.info('Launching browser', { headless: this.opts.headless });
|
|
153
|
+
this.browser = await playwright.chromium.launch({
|
|
154
|
+
headless: this.opts.headless,
|
|
155
|
+
args: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],
|
|
156
|
+
});
|
|
157
|
+
this.context = await this.browser.newContext({
|
|
158
|
+
userAgent: this.opts.userAgent,
|
|
159
|
+
acceptDownloads: true,
|
|
160
|
+
locale: 'en-US',
|
|
161
|
+
});
|
|
162
|
+
await this.context.addCookies([
|
|
163
|
+
{
|
|
164
|
+
name: 'safe_link_counter',
|
|
165
|
+
value: '1',
|
|
166
|
+
domain: '.sfile.co',
|
|
167
|
+
path: '/',
|
|
168
|
+
expires: Math.floor(Date.now() / 1000) + 3600,
|
|
169
|
+
},
|
|
170
|
+
]);
|
|
171
|
+
this.page = await this.context.newPage();
|
|
172
|
+
this.interactions = new SfilePageInteractions(this.page, this.logger);
|
|
173
|
+
if (this.opts.debug) {
|
|
174
|
+
this.page.on('console', (msg) => {
|
|
175
|
+
if (msg.type() === 'error')
|
|
176
|
+
this.logger.error(`[console] ${msg.text()}`);
|
|
177
|
+
else if (msg.type() === 'warning')
|
|
178
|
+
this.logger.warn(`[console] ${msg.text()}`);
|
|
179
|
+
});
|
|
180
|
+
this.page.on('pageerror', (err) => this.logger.error(`[pageerror] ${err.message}`));
|
|
181
|
+
}
|
|
182
|
+
this.logger.info('Browser ready');
|
|
183
|
+
}
|
|
184
|
+
catch (err) {
|
|
185
|
+
throw new BrowserError(`Failed to launch browser: ${err.message}`);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
async goto(url, waitUntil = 'networkidle') {
|
|
189
|
+
if (!this.page)
|
|
190
|
+
throw new BrowserError('Page not initialized');
|
|
191
|
+
try {
|
|
192
|
+
this.logger.debug(`Navigating to ${url} (waitUntil=${waitUntil})`);
|
|
193
|
+
await this.page.goto(url, { waitUntil, timeout: this.opts.timeout });
|
|
194
|
+
}
|
|
195
|
+
catch (err) {
|
|
196
|
+
throw new NetworkError(`Navigation failed: ${err.message}`, { url });
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
async waitForDownloadButton() {
|
|
200
|
+
if (!this.interactions)
|
|
201
|
+
throw new BrowserError('Interactions not ready');
|
|
202
|
+
await this.interactions.waitForDownloadButton(DEFAULTS.downloadButtonTimeout);
|
|
203
|
+
}
|
|
204
|
+
async getIntermediateUrl() {
|
|
205
|
+
if (!this.interactions)
|
|
206
|
+
throw new BrowserError('Interactions not ready');
|
|
207
|
+
return this.interactions.extractIntermediateUrl();
|
|
208
|
+
}
|
|
209
|
+
async startDownloadAndWait(autoUrl) {
|
|
210
|
+
if (!this.page)
|
|
211
|
+
throw new BrowserError('Page not initialized');
|
|
212
|
+
const downloadPromise = this.page
|
|
213
|
+
.waitForEvent('download', { timeout: this.opts.timeout })
|
|
214
|
+
.catch((err) => {
|
|
215
|
+
this.logger.warn(`Download event wait failed: ${err.message}`);
|
|
216
|
+
return null;
|
|
217
|
+
});
|
|
218
|
+
this.logger.debug(`Navigating to auto URL: ${autoUrl}`);
|
|
219
|
+
await this.page.goto(autoUrl, { waitUntil: 'commit', timeout: this.opts.timeout });
|
|
220
|
+
const download = await downloadPromise;
|
|
221
|
+
if (download) {
|
|
222
|
+
this.logger.info('Download event captured');
|
|
223
|
+
return download;
|
|
224
|
+
}
|
|
225
|
+
return null;
|
|
226
|
+
}
|
|
227
|
+
async fallbackCollectFileResponse() {
|
|
228
|
+
if (!this.page)
|
|
229
|
+
throw new BrowserError('Page not initialized');
|
|
230
|
+
this.logger.warn('Falling back to response interception');
|
|
231
|
+
const responses = [];
|
|
232
|
+
const handler = (res) => responses.push(res);
|
|
233
|
+
this.page.on('response', handler);
|
|
234
|
+
await sleep(DEFAULTS.fallbackWaitMs);
|
|
235
|
+
this.page.off('response', handler);
|
|
236
|
+
const fileResponse = [...responses].reverse().find((r) => {
|
|
237
|
+
const disposition = r.headers()['content-disposition'];
|
|
238
|
+
return ((disposition && disposition.includes('attachment')) ||
|
|
239
|
+
r.url().includes('/downloadfile/'));
|
|
240
|
+
});
|
|
241
|
+
if (!fileResponse)
|
|
242
|
+
return null;
|
|
243
|
+
const buffer = await fileResponse.body();
|
|
244
|
+
let filename = fileResponse.url().split('/').pop()?.split('?')[0] || 'file.bin';
|
|
245
|
+
filename = filename.replace(/[<>:"/\\|?*]/g, '_');
|
|
246
|
+
return { buffer, filename };
|
|
247
|
+
}
|
|
248
|
+
async saveDebugArtifacts(errorMessage) {
|
|
249
|
+
if (!this.page)
|
|
250
|
+
return;
|
|
251
|
+
try {
|
|
252
|
+
this.debugDir = path__default.default.join(os__default.default.tmpdir(), `sfile_debug_${Date.now()}`);
|
|
253
|
+
await fs__namespace.mkdir(this.debugDir, { recursive: true });
|
|
254
|
+
await Promise.all([
|
|
255
|
+
this.page.screenshot({
|
|
256
|
+
path: path__default.default.join(this.debugDir, 'error.png'),
|
|
257
|
+
fullPage: true,
|
|
258
|
+
}),
|
|
259
|
+
fs__namespace.writeFile(path__default.default.join(this.debugDir, 'error.html'), await this.page.content()),
|
|
260
|
+
fs__namespace.writeFile(path__default.default.join(this.debugDir, 'error.txt'), errorMessage),
|
|
261
|
+
]);
|
|
262
|
+
this.logger.info(`Debug artifacts saved to ${this.debugDir}`);
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
this.logger.error(`Failed to save debug artifacts: ${e.message}`);
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
async close() {
|
|
269
|
+
if (this.page)
|
|
270
|
+
await this.page.close().catch(() => { });
|
|
271
|
+
if (this.context)
|
|
272
|
+
await this.context.close().catch(() => { });
|
|
273
|
+
if (this.browser)
|
|
274
|
+
await this.browser.close().catch(() => { });
|
|
275
|
+
this.logger.debug('Browser closed');
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
class Logger {
|
|
280
|
+
minLevel;
|
|
281
|
+
constructor(debugMode = false) {
|
|
282
|
+
this.minLevel = debugMode ? 'debug' : 'info';
|
|
283
|
+
}
|
|
284
|
+
setDebug(enabled) {
|
|
285
|
+
this.minLevel = enabled ? 'debug' : 'info';
|
|
286
|
+
}
|
|
287
|
+
shouldLog(level) {
|
|
288
|
+
const levels = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
289
|
+
return levels[level] >= levels[this.minLevel];
|
|
290
|
+
}
|
|
291
|
+
log(level, message, context) {
|
|
292
|
+
if (!this.shouldLog(level))
|
|
293
|
+
return;
|
|
294
|
+
const ts = new Date().toISOString();
|
|
295
|
+
const ctx = context ? ` ${safeStringify(context)}` : '';
|
|
296
|
+
console.log(`[${ts}] ${level.toUpperCase()}: ${message}${ctx}`);
|
|
297
|
+
}
|
|
298
|
+
debug(msg, ctx) {
|
|
299
|
+
this.log('debug', msg, ctx);
|
|
300
|
+
}
|
|
301
|
+
info(msg, ctx) {
|
|
302
|
+
this.log('info', msg, ctx);
|
|
303
|
+
}
|
|
304
|
+
warn(msg, ctx) {
|
|
305
|
+
this.log('warn', msg, ctx);
|
|
306
|
+
}
|
|
307
|
+
error(msg, ctx) {
|
|
308
|
+
this.log('error', msg, ctx);
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
function normalizeOptions(opts) {
|
|
313
|
+
return {
|
|
314
|
+
headless: opts?.headless ?? DEFAULTS.headless,
|
|
315
|
+
debug: opts?.debug ?? false,
|
|
316
|
+
userAgent: opts?.userAgent ?? DEFAULTS.userAgent,
|
|
317
|
+
timeout: opts?.timeout ?? DEFAULTS.timeout,
|
|
318
|
+
};
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
async function downloadSfile(url, saveDir, options) {
|
|
322
|
+
const opts = normalizeOptions(options);
|
|
323
|
+
const logger = new Logger(opts.debug);
|
|
324
|
+
if (!url || !url.includes('sfile.co')) {
|
|
325
|
+
throw new ValidationError('URL must contain sfile.co', { url });
|
|
326
|
+
}
|
|
327
|
+
await fs__namespace.default.mkdir(saveDir, { recursive: true });
|
|
328
|
+
const browserMgr = new BrowserManager(logger, {
|
|
329
|
+
headless: opts.headless,
|
|
330
|
+
userAgent: opts.userAgent,
|
|
331
|
+
timeout: opts.timeout,
|
|
332
|
+
debug: opts.debug,
|
|
333
|
+
});
|
|
334
|
+
try {
|
|
335
|
+
await browserMgr.launch();
|
|
336
|
+
await browserMgr.goto(url, 'networkidle');
|
|
337
|
+
await browserMgr.waitForDownloadButton();
|
|
338
|
+
const intermediateUrl = await browserMgr.getIntermediateUrl();
|
|
339
|
+
const autoUrl = intermediateUrl.includes('?')
|
|
340
|
+
? `${intermediateUrl}&auto=1`
|
|
341
|
+
: `${intermediateUrl}?auto=1`;
|
|
342
|
+
let download = await browserMgr.startDownloadAndWait(autoUrl);
|
|
343
|
+
let finalPath;
|
|
344
|
+
let fileSize;
|
|
345
|
+
let method;
|
|
346
|
+
if (download) {
|
|
347
|
+
const suggested = download.suggestedFilename() || 'file.bin';
|
|
348
|
+
const filename = sanitizeFilename(suggested);
|
|
349
|
+
finalPath = path__default.default.join(saveDir, filename);
|
|
350
|
+
await download.saveAs(finalPath);
|
|
351
|
+
const stat = await fs__namespace.default.stat(finalPath);
|
|
352
|
+
fileSize = stat.size;
|
|
353
|
+
method = 'direct';
|
|
354
|
+
logger.info(`Saved via direct download: ${finalPath} (${fileSize} bytes)`);
|
|
355
|
+
}
|
|
356
|
+
else {
|
|
357
|
+
const fallback = await browserMgr.fallbackCollectFileResponse();
|
|
358
|
+
if (!fallback) {
|
|
359
|
+
throw new NetworkError('No download event and no file response found');
|
|
360
|
+
}
|
|
361
|
+
const { buffer, filename: rawName } = fallback;
|
|
362
|
+
const filename = sanitizeFilename(rawName);
|
|
363
|
+
finalPath = path__default.default.join(saveDir, filename);
|
|
364
|
+
await fs__namespace.default.writeFile(finalPath, buffer);
|
|
365
|
+
fileSize = buffer.length;
|
|
366
|
+
method = 'fallback';
|
|
367
|
+
logger.info(`Saved via fallback: ${finalPath} (${fileSize} bytes)`);
|
|
368
|
+
}
|
|
369
|
+
return { filePath: finalPath, size: fileSize, method };
|
|
370
|
+
}
|
|
371
|
+
catch (err) {
|
|
372
|
+
await browserMgr.saveDebugArtifacts(err.message);
|
|
373
|
+
throw err;
|
|
374
|
+
}
|
|
375
|
+
finally {
|
|
376
|
+
await browserMgr.close();
|
|
377
|
+
}
|
|
129
378
|
}
|
|
130
379
|
|
|
131
|
-
exports.
|
|
132
|
-
exports.
|
|
133
|
-
exports.
|
|
134
|
-
exports.
|
|
135
|
-
exports.
|
|
136
|
-
exports.
|
|
380
|
+
exports.AppError = AppError;
|
|
381
|
+
exports.BrowserError = BrowserError;
|
|
382
|
+
exports.FileError = FileError;
|
|
383
|
+
exports.NetworkError = NetworkError;
|
|
384
|
+
exports.ValidationError = ValidationError;
|
|
385
|
+
exports.downloadSfile = downloadSfile;
|
|
137
386
|
//# sourceMappingURL=lib.cjs.map
|
package/build/lib.cjs.map
CHANGED
|
@@ -1,14 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"version": 3,
|
|
3
|
-
"file": "lib.cjs",
|
|
4
|
-
"sources": [
|
|
5
|
-
"../lib/lib.ts"
|
|
6
|
-
],
|
|
7
|
-
"sourcesContent": [
|
|
8
|
-
"const COLORS = {\n\tRESET: '\\x1b[0m',\n\tBRIGHT: '\\x1b[1m',\n\tYELLOW: '\\x1b[33m',\n\tRED: '\\x1b[31m',\n\tCYAN: '\\x1b[36m',\n\tGRAY: '\\x1b[90m',\n} as const\nexport enum LibraryStatus {\n\tUNDER_CONSTRUCTION = 'UNDER_CONSTRUCTION',\n\tSTABLE = 'STABLE',\n\tDEPRECATED = 'DEPRECATED',\n}\nexport const LIB_INFO = {\n\tname: 'MySuperFramework',\n\tcurrentVersion: '2.0.0-dev',\n\tpreviousVersion: '1.0.2',\n\tstatus: LibraryStatus.UNDER_CONSTRUCTION,\n\tisDeprecated: true,\n\tmessage:\n\t\t'This version represents a complete architectural refactor from CLI to framework. Not stable.',\n} as const\nlet warningDisplayed = false\nfunction stripAnsi(text: string): string {\n\treturn text.replace(/\\x1b\\[[0-9;]*[a-zA-Z]/g, '')\n}\nexport function isDevelopmentVersion(): boolean {\n\treturn LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION\n}\nexport class LibStatus {\n\tprivate static instance: LibStatus | undefined\n\tprivate constructor() {\n\t\tthis.displayDeveloperWarning()\n\t}\n\tpublic static getInstance(): LibStatus {\n\t\tif (!LibStatus.instance) {\n\t\t\tLibStatus.instance = new LibStatus()\n\t\t}\n\t\treturn LibStatus.instance\n\t}\n\tprivate displayDeveloperWarning(): void {\n\t\tif (typeof console === 'undefined' || typeof console.warn !== 'function') {\n\t\t\treturn\n\t\t}\n\t\tif (warningDisplayed) {\n\t\t\treturn\n\t\t}\n\t\tif (\n\t\t\ttypeof process !== 'undefined' &&\n\t\t\tprocess.env &&\n\t\t\tprocess.env['MY_SUPER_FRAMEWORK_SUPPRESS_WARNING'] === 'true'\n\t\t) {\n\t\t\treturn\n\t\t}\n\t\tconst border = `${COLORS.GRAY}${'='.repeat(80)}${COLORS.RESET}`\n\t\tconst label = `${COLORS.YELLOW}${COLORS.BRIGHT}[WARNING]${COLORS.RESET}`\n\t\tconst highlight = `${COLORS.CYAN}`\n\t\tconsole.warn(`\\n${border}`)\n\t\tconsole.warn(`${label} DEVELOPMENT VERSION IN USE`)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}Library: ${COLORS.RESET}${highlight}${LIB_INFO.name}${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}Current Version: ${COLORS.RESET}${highlight}${LIB_INFO.currentVersion}${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}Previous Version: ${COLORS.RESET}${highlight}${LIB_INFO.previousVersion}${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}Architecture: ${COLORS.RESET}${highlight}CLI -> Framework (Full Refactor)${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`\\n${COLORS.RED}${COLORS.BRIGHT}DO NOT USE IN PRODUCTION ENVIRONMENTS${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}API stability is not guaranteed. Breaking changes may occur without notice.${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(\n\t\t\t`${COLORS.GRAY}To suppress this warning, set env MY_SUPER_FRAMEWORK_SUPPRESS_WARNING=true${COLORS.RESET}`,\n\t\t)\n\t\tconsole.warn(`${border}\\n`)\n\t\twarningDisplayed = true\n\t}\n\tpublic suppressWarning(): void {\n\t\twarningDisplayed = true\n\t}\n\tpublic ensureStable(): void {\n\t\tif (LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION) {\n\t\t\tconst errorMessage =\n\t\t\t\t`${COLORS.RED}${COLORS.BRIGHT}[${LIB_INFO.name}] Stability Check Failed${COLORS.RESET}\\n` +\n\t\t\t\t`${COLORS.GRAY}Library version ${LIB_INFO.currentVersion} is under active development.${COLORS.RESET}\\n` +\n\t\t\t\t`${COLORS.GRAY}Current status: ${LIB_INFO.status}${COLORS.RESET}`\n\t\t\tthrow new Error(stripAnsi(errorMessage))\n\t\t}\n\t}\n\tpublic getVersion(): string {\n\t\treturn LIB_INFO.currentVersion\n\t}\n\tpublic getInfo(): Readonly<typeof LIB_INFO> {\n\t\treturn LIB_INFO\n\t}\n}\nexport function initFramework(): never {\n\tconst message =\n\t\t`${COLORS.RED}${COLORS.BRIGHT}[${LIB_INFO.name}] Initialization Blocked${COLORS.RESET}\\n` +\n\t\t`${COLORS.GRAY}Framework is undergoing complete architectural refactor.${COLORS.RESET}\\n` +\n\t\t`${COLORS.GRAY}Migration path: v${LIB_INFO.previousVersion} (CLI) -> v${LIB_INFO.currentVersion} (Framework)${COLORS.RESET}\\n` +\n\t\t`${COLORS.GRAY}Status: ${LIB_INFO.status}${COLORS.RESET}`\n\tthrow new Error(stripAnsi(message))\n}\nexport function isStable(): boolean {\n\treturn LIB_INFO.status !== LibraryStatus.UNDER_CONSTRUCTION\n}\nexport function assertStable(): void {\n\tif (LIB_INFO.status === LibraryStatus.UNDER_CONSTRUCTION) {\n\t\tthrow new Error(\n\t\t\t`[${LIB_INFO.name}] Cannot use unstable version ${LIB_INFO.currentVersion} in production. ` +\n\t\t\t\t`Status: ${LIB_INFO.status}`,\n\t\t)\n\t}\n}\nif (isDevelopmentVersion()) {\n\tLibStatus.getInstance()\n}\n"
|
|
9
|
-
],
|
|
10
|
-
"names": [
|
|
11
|
-
"LibraryStatus"
|
|
12
|
-
],
|
|
13
|
-
"mappings": "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"
|
|
14
|
-
}
|
|
1
|
+
{"version":3,"file":"lib.cjs","sources":["../lib/errors/base.ts","../lib/errors/errors.ts","../lib/config/defaults.ts","../lib/browser/page-interactions.ts","../lib/utils/helpers.ts","../lib/browser/browser-manager.ts","../lib/utils/logger.ts","../lib/config/schema.ts","../lib/core/downloader.ts"],"sourcesContent":["export abstract class AppError extends Error {\n\tpublic readonly timestamp: string\n\tpublic readonly context: Record<string, unknown> | undefined\n\tconstructor(\n\t\tmessage: string,\n\t\tpublic readonly code: string,\n\t\tpublic readonly retryable: boolean = false,\n\t\tcontext?: Record<string, unknown>,\n\t) {\n\t\tsuper(message)\n\t\tthis.name = this.constructor.name\n\t\tthis.timestamp = new Date().toISOString()\n\t\tthis.context = context ? { ...context } : undefined\n\t\tError.captureStackTrace?.(this, this.constructor)\n\t}\n\ttoJSON() {\n\t\treturn {\n\t\t\tname: this.name,\n\t\t\tmessage: this.message,\n\t\t\tcode: this.code,\n\t\t\tretryable: this.retryable,\n\t\t\ttimestamp: this.timestamp,\n\t\t\tcontext: this.context,\n\t\t}\n\t}\n}\n","import { AppError } from './base.js'\nexport class ValidationError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'VALIDATION_ERROR', false, context)\n\t}\n}\nexport class NetworkError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'NETWORK_ERROR', true, context)\n\t}\n}\nexport class FileError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'FILE_ERROR', false, context)\n\t}\n}\nexport class BrowserError extends AppError {\n\tconstructor(message: string, context?: Record<string, unknown>) {\n\t\tsuper(message, 'BROWSER_ERROR', true, context)\n\t}\n}\n","export const DEFAULTS = {\n\tuserAgent:\n\t\t'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/122.0.0.0 Safari/537.36',\n\theadless: true,\n\ttimeout: 100000,\n\tdownloadButtonTimeout: 100000,\n\tfallbackWaitMs: 5000,\n}\n","import { Page } from 'playwright'\nimport { Logger } from '../utils/logger.js'\nimport { NetworkError } from '../errors/index.js'\nexport class SfilePageInteractions {\n\tconstructor(\n\t\tprivate page: Page,\n\t\tprivate logger: Logger,\n\t) {}\n\tasync waitForDownloadButton(timeout: number): Promise<void> {\n\t\tthis.logger.debug('Waiting for #download button to be visible')\n\t\tconst button = this.page.locator('#download')\n\t\tawait button.waitFor({ state: 'visible', timeout })\n\t\tthis.logger.debug(\n\t\t\t'Waiting for button to become active (href != \"#\" and pointerEvents != \"none\")',\n\t\t)\n\t\tawait this.page.waitForFunction(\n\t\t\t() => {\n\t\t\t\tconst btn = document.querySelector('#download') as HTMLAnchorElement | null\n\t\t\t\tif (!btn) return false\n\t\t\t\tconst href = btn.getAttribute('href')\n\t\t\t\tconst style = window.getComputedStyle(btn)\n\t\t\t\treturn href && href !== '#' && style.pointerEvents !== 'none'\n\t\t\t},\n\t\t\t{ timeout },\n\t\t)\n\t}\n\tasync extractIntermediateUrl(): Promise<string> {\n\t\tthis.logger.debug('Extracting href from #download')\n\t\tconst href = await this.page.$eval('#download', (el) => (el as HTMLAnchorElement).href)\n\t\tif (!href || href === '#') {\n\t\t\tthrow new NetworkError('Download button href is invalid', { href })\n\t\t}\n\t\treturn href\n\t}\n}\n","export function sanitizeFilename(name: string, replacement = '_'): string {\n\tconst sanitized = name\n\t\t.replace(/[<>:\"/\\\\|?*\\x00-\\x1F]/g, replacement)\n\t\t.replace(new RegExp(`${replacement}+`, 'g'), replacement)\n\t\t.trim()\n\t\t.slice(0, 255)\n\treturn sanitized || 'file.bin'\n}\nexport const sleep = (ms: number) => new Promise((resolve) => setTimeout(resolve, ms))\nexport function safeStringify(value: unknown): string {\n\ttry {\n\t\treturn JSON.stringify(value)\n\t} catch {\n\t\treturn '[unserializable]'\n\t}\n}\n","import { chromium, Browser, BrowserContext, Page, Download, Response } from 'playwright'\nimport * as fs from 'fs/promises'\nimport path from 'path'\nimport os from 'os'\nimport { Logger } from '../utils/logger.js'\nimport { BrowserError, NetworkError } from '../errors/index.js'\nimport { DEFAULTS } from '../config/defaults.js'\nimport { SfilePageInteractions } from './page-interactions.js'\nimport { sleep } from '../utils/helpers.js'\nexport interface BrowserManagerOptions {\n\theadless: boolean\n\tuserAgent: string\n\ttimeout: number\n\tdebug: boolean\n}\nexport class BrowserManager {\n\tprivate browser: Browser | null = null\n\tprivate context: BrowserContext | null = null\n\tprivate page: Page | null = null\n\tprivate interactions: SfilePageInteractions | null = null\n\tprivate debugDir: string | null = null\n\tconstructor(\n\t\tprivate logger: Logger,\n\t\tprivate opts: BrowserManagerOptions,\n\t) {}\n\tasync launch(): Promise<void> {\n\t\ttry {\n\t\t\tthis.logger.info('Launching browser', { headless: this.opts.headless })\n\t\t\tthis.browser = await chromium.launch({\n\t\t\t\theadless: this.opts.headless,\n\t\t\t\targs: ['--no-sandbox', '--disable-setuid-sandbox', '--disable-dev-shm-usage'],\n\t\t\t})\n\t\t\tthis.context = await this.browser.newContext({\n\t\t\t\tuserAgent: this.opts.userAgent,\n\t\t\t\tacceptDownloads: true,\n\t\t\t\tlocale: 'en-US',\n\t\t\t})\n\t\t\tawait this.context.addCookies([\n\t\t\t\t{\n\t\t\t\t\tname: 'safe_link_counter',\n\t\t\t\t\tvalue: '1',\n\t\t\t\t\tdomain: '.sfile.co',\n\t\t\t\t\tpath: '/',\n\t\t\t\t\texpires: Math.floor(Date.now() / 1000) + 3600,\n\t\t\t\t},\n\t\t\t])\n\t\t\tthis.page = await this.context.newPage()\n\t\t\tthis.interactions = new SfilePageInteractions(this.page, this.logger)\n\t\t\tif (this.opts.debug) {\n\t\t\t\tthis.page.on('console', (msg) => {\n\t\t\t\t\tif (msg.type() === 'error') this.logger.error(`[console] ${msg.text()}`)\n\t\t\t\t\telse if (msg.type() === 'warning') this.logger.warn(`[console] ${msg.text()}`)\n\t\t\t\t})\n\t\t\t\tthis.page.on('pageerror', (err) => this.logger.error(`[pageerror] ${err.message}`))\n\t\t\t}\n\t\t\tthis.logger.info('Browser ready')\n\t\t} catch (err: any) {\n\t\t\tthrow new BrowserError(`Failed to launch browser: ${err.message}`)\n\t\t}\n\t}\n\tasync goto(\n\t\turl: string,\n\t\twaitUntil: 'load' | 'networkidle' | 'commit' = 'networkidle',\n\t): Promise<void> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\ttry {\n\t\t\tthis.logger.debug(`Navigating to ${url} (waitUntil=${waitUntil})`)\n\t\t\tawait this.page.goto(url, { waitUntil, timeout: this.opts.timeout })\n\t\t} catch (err: any) {\n\t\t\tthrow new NetworkError(`Navigation failed: ${err.message}`, { url })\n\t\t}\n\t}\n\tasync waitForDownloadButton(): Promise<void> {\n\t\tif (!this.interactions) throw new BrowserError('Interactions not ready')\n\t\tawait this.interactions.waitForDownloadButton(DEFAULTS.downloadButtonTimeout)\n\t}\n\tasync getIntermediateUrl(): Promise<string> {\n\t\tif (!this.interactions) throw new BrowserError('Interactions not ready')\n\t\treturn this.interactions.extractIntermediateUrl()\n\t}\n\tasync startDownloadAndWait(autoUrl: string): Promise<Download | null> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\tconst downloadPromise = this.page\n\t\t\t.waitForEvent('download', { timeout: this.opts.timeout })\n\t\t\t.catch((err) => {\n\t\t\t\tthis.logger.warn(`Download event wait failed: ${err.message}`)\n\t\t\t\treturn null\n\t\t\t})\n\t\tthis.logger.debug(`Navigating to auto URL: ${autoUrl}`)\n\t\tawait this.page.goto(autoUrl, { waitUntil: 'commit', timeout: this.opts.timeout })\n\t\tconst download = await downloadPromise\n\t\tif (download) {\n\t\t\tthis.logger.info('Download event captured')\n\t\t\treturn download\n\t\t}\n\t\treturn null\n\t}\n\tasync fallbackCollectFileResponse(): Promise<{ buffer: Buffer; filename: string } | null> {\n\t\tif (!this.page) throw new BrowserError('Page not initialized')\n\t\tthis.logger.warn('Falling back to response interception')\n\t\tconst responses: Response[] = []\n\t\tconst handler = (res: Response) => responses.push(res)\n\t\tthis.page.on('response', handler)\n\t\tawait sleep(DEFAULTS.fallbackWaitMs)\n\t\tthis.page.off('response', handler)\n\t\tconst fileResponse = [...responses].reverse().find((r) => {\n\t\t\tconst disposition = r.headers()['content-disposition']\n\t\t\treturn (\n\t\t\t\t(disposition && disposition.includes('attachment')) ||\n\t\t\t\tr.url().includes('/downloadfile/')\n\t\t\t)\n\t\t})\n\t\tif (!fileResponse) return null\n\t\tconst buffer = await fileResponse.body()\n\t\tlet filename = fileResponse.url().split('/').pop()?.split('?')[0] || 'file.bin'\n\t\tfilename = filename.replace(/[<>:\"/\\\\|?*]/g, '_')\n\t\treturn { buffer, filename }\n\t}\n\tasync saveDebugArtifacts(errorMessage: string): Promise<void> {\n\t\tif (!this.page) return\n\t\ttry {\n\t\t\tthis.debugDir = path.join(os.tmpdir(), `sfile_debug_${Date.now()}`)\n\t\t\tawait fs.mkdir(this.debugDir, { recursive: true })\n\t\t\tawait Promise.all([\n\t\t\t\tthis.page.screenshot({\n\t\t\t\t\tpath: path.join(this.debugDir, 'error.png'),\n\t\t\t\t\tfullPage: true,\n\t\t\t\t}),\n\t\t\t\tfs.writeFile(path.join(this.debugDir, 'error.html'), await this.page.content()),\n\t\t\t\tfs.writeFile(path.join(this.debugDir, 'error.txt'), errorMessage),\n\t\t\t])\n\t\t\tthis.logger.info(`Debug artifacts saved to ${this.debugDir}`)\n\t\t} catch (e: any) {\n\t\t\tthis.logger.error(`Failed to save debug artifacts: ${e.message}`)\n\t\t}\n\t}\n\tasync close(): Promise<void> {\n\t\tif (this.page) await this.page.close().catch(() => {})\n\t\tif (this.context) await this.context.close().catch(() => {})\n\t\tif (this.browser) await this.browser.close().catch(() => {})\n\t\tthis.logger.debug('Browser closed')\n\t}\n}\n","import { safeStringify } from './helpers.js'\ntype LogLevel = 'debug' | 'info' | 'warn' | 'error'\nexport class Logger {\n\tprivate minLevel: LogLevel\n\tconstructor(debugMode = false) {\n\t\tthis.minLevel = debugMode ? 'debug' : 'info'\n\t}\n\tsetDebug(enabled: boolean) {\n\t\tthis.minLevel = enabled ? 'debug' : 'info'\n\t}\n\tprivate shouldLog(level: LogLevel): boolean {\n\t\tconst levels: Record<LogLevel, number> = { debug: 0, info: 1, warn: 2, error: 3 }\n\t\treturn levels[level] >= levels[this.minLevel]\n\t}\n\tprivate log(level: LogLevel, message: string, context?: any) {\n\t\tif (!this.shouldLog(level)) return\n\t\tconst ts = new Date().toISOString()\n\t\tconst ctx = context ? ` ${safeStringify(context)}` : ''\n\t\tconsole.log(`[${ts}] ${level.toUpperCase()}: ${message}${ctx}`)\n\t}\n\tdebug(msg: string, ctx?: any) {\n\t\tthis.log('debug', msg, ctx)\n\t}\n\tinfo(msg: string, ctx?: any) {\n\t\tthis.log('info', msg, ctx)\n\t}\n\twarn(msg: string, ctx?: any) {\n\t\tthis.log('warn', msg, ctx)\n\t}\n\terror(msg: string, ctx?: any) {\n\t\tthis.log('error', msg, ctx)\n\t}\n}\n","import { DEFAULTS } from './defaults.js'\nexport interface DownloadOptions {\n\theadless?: boolean\n\tdebug?: boolean\n\tuserAgent?: string\n\ttimeout?: number\n}\nexport interface DownloadResult {\n\tfilePath: string\n\tsize: number\n\tmethod: 'direct' | 'fallback'\n}\nexport function normalizeOptions(opts?: DownloadOptions) {\n\treturn {\n\t\theadless: opts?.headless ?? DEFAULTS.headless,\n\t\tdebug: opts?.debug ?? false,\n\t\tuserAgent: opts?.userAgent ?? DEFAULTS.userAgent,\n\t\ttimeout: opts?.timeout ?? DEFAULTS.timeout,\n\t}\n}\n","import path from 'path'\nimport fs from 'fs/promises'\nimport { BrowserManager } from '../browser/browser-manager.js'\nimport { Logger } from '../utils/logger.js'\nimport { ValidationError, NetworkError } from '../errors/index.js'\nimport { DownloadOptions, DownloadResult, normalizeOptions } from '../config/schema.js'\nimport { sanitizeFilename } from '../utils/helpers.js'\nexport async function downloadSfile(\n\turl: string,\n\tsaveDir: string,\n\toptions?: DownloadOptions,\n): Promise<DownloadResult> {\n\tconst opts = normalizeOptions(options)\n\tconst logger = new Logger(opts.debug)\n\tif (!url || !url.includes('sfile.co')) {\n\t\tthrow new ValidationError('URL must contain sfile.co', { url })\n\t}\n\tawait fs.mkdir(saveDir, { recursive: true })\n\tconst browserMgr = new BrowserManager(logger, {\n\t\theadless: opts.headless,\n\t\tuserAgent: opts.userAgent,\n\t\ttimeout: opts.timeout,\n\t\tdebug: opts.debug,\n\t})\n\ttry {\n\t\tawait browserMgr.launch()\n\t\tawait browserMgr.goto(url, 'networkidle')\n\t\tawait browserMgr.waitForDownloadButton()\n\t\tconst intermediateUrl = await browserMgr.getIntermediateUrl()\n\t\tconst autoUrl = intermediateUrl.includes('?')\n\t\t\t? `${intermediateUrl}&auto=1`\n\t\t\t: `${intermediateUrl}?auto=1`\n\t\tlet download = await browserMgr.startDownloadAndWait(autoUrl)\n\t\tlet finalPath: string\n\t\tlet fileSize: number\n\t\tlet method: 'direct' | 'fallback'\n\t\tif (download) {\n\t\t\tconst suggested = download.suggestedFilename() || 'file.bin'\n\t\t\tconst filename = sanitizeFilename(suggested)\n\t\t\tfinalPath = path.join(saveDir, filename)\n\t\t\tawait download.saveAs(finalPath)\n\t\t\tconst stat = await fs.stat(finalPath)\n\t\t\tfileSize = stat.size\n\t\t\tmethod = 'direct'\n\t\t\tlogger.info(`Saved via direct download: ${finalPath} (${fileSize} bytes)`)\n\t\t} else {\n\t\t\tconst fallback = await browserMgr.fallbackCollectFileResponse()\n\t\t\tif (!fallback) {\n\t\t\t\tthrow new NetworkError('No download event and no file response found')\n\t\t\t}\n\t\t\tconst { buffer, filename: rawName } = fallback\n\t\t\tconst filename = sanitizeFilename(rawName)\n\t\t\tfinalPath = path.join(saveDir, filename)\n\t\t\tawait fs.writeFile(finalPath, buffer)\n\t\t\tfileSize = buffer.length\n\t\t\tmethod = 'fallback'\n\t\t\tlogger.info(`Saved via fallback: ${finalPath} (${fileSize} bytes)`)\n\t\t}\n\t\treturn { filePath: finalPath, size: fileSize, method }\n\t} catch (err: any) {\n\t\tawait browserMgr.saveDebugArtifacts(err.message)\n\t\tthrow err\n\t} finally {\n\t\tawait browserMgr.close()\n\t}\n}\n"],"names":["chromium","path","os","fs"],"mappings":"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"}
|