manhuagui-cli 1.0.0 → 1.0.2
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/README.md +172 -58
- package/README_EN.md +172 -56
- package/dist/lib/browser.d.ts +4 -0
- package/dist/lib/browser.d.ts.map +1 -0
- package/dist/lib/browser.js +22 -0
- package/dist/lib/browser.js.map +1 -0
- package/dist/lib/chapter.d.ts +19 -3
- package/dist/lib/chapter.d.ts.map +1 -1
- package/dist/lib/chapter.js +142 -63
- package/dist/lib/chapter.js.map +1 -1
- package/dist/lib/cli.d.ts +20 -0
- package/dist/lib/cli.d.ts.map +1 -1
- package/dist/lib/cli.js +142 -131
- package/dist/lib/cli.js.map +1 -1
- package/dist/lib/comic.d.ts.map +1 -1
- package/dist/lib/comic.js +26 -17
- package/dist/lib/comic.js.map +1 -1
- package/dist/lib/config.d.ts +26 -19
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +92 -33
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/logger.d.ts +3 -0
- package/dist/lib/logger.d.ts.map +1 -1
- package/dist/lib/logger.js +6 -2
- package/dist/lib/logger.js.map +1 -1
- package/dist/lib/progress.d.ts +11 -5
- package/dist/lib/progress.d.ts.map +1 -1
- package/dist/lib/progress.js +17 -15
- package/dist/lib/progress.js.map +1 -1
- package/dist/lib/prompts.d.ts +1 -0
- package/dist/lib/prompts.d.ts.map +1 -1
- package/dist/lib/prompts.js +9 -12
- package/dist/lib/prompts.js.map +1 -1
- package/dist/lib/speed.d.ts +16 -0
- package/dist/lib/speed.d.ts.map +1 -0
- package/dist/lib/speed.js +83 -0
- package/dist/lib/speed.js.map +1 -0
- package/dist/lib/tasks.d.ts +21 -0
- package/dist/lib/tasks.d.ts.map +1 -0
- package/dist/lib/tasks.js +124 -0
- package/dist/lib/tasks.js.map +1 -0
- package/dist/lib/ui.d.ts +33 -0
- package/dist/lib/ui.d.ts.map +1 -0
- package/dist/lib/ui.js +216 -0
- package/dist/lib/ui.js.map +1 -0
- package/package.json +5 -3
package/dist/lib/config.js
CHANGED
|
@@ -1,42 +1,101 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { existsSync, readFileSync } from "node:fs";
|
|
2
|
+
import { homedir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { logger, setLogLevel } from "./logger.js";
|
|
2
5
|
try {
|
|
3
6
|
process.loadEnvFile?.();
|
|
4
7
|
}
|
|
5
8
|
catch {
|
|
6
9
|
logger.warn("Failed to load .env file");
|
|
7
10
|
}
|
|
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
|
-
|
|
11
|
+
const BUILTIN_USER_AGENTS = [
|
|
12
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
13
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/130.0.0.0 Safari/537.36",
|
|
14
|
+
"Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
15
|
+
"Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/131.0.0.0 Safari/537.36",
|
|
16
|
+
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:133.0) Gecko/20100101 Firefox/133.0",
|
|
17
|
+
];
|
|
18
|
+
const DEFAULTS = {
|
|
19
|
+
outputBase: "./output",
|
|
20
|
+
imageConcurrency: 2,
|
|
21
|
+
downloadDelay: 3000,
|
|
22
|
+
chapterDelayMin: 3000,
|
|
23
|
+
chapterDelayMax: 6000,
|
|
24
|
+
retryCount: 3,
|
|
25
|
+
retryBackoffBase: 1000,
|
|
26
|
+
imageLoadDelay: 200,
|
|
27
|
+
logLevel: "info",
|
|
28
|
+
userAgents: BUILTIN_USER_AGENTS,
|
|
29
|
+
padMinLength: 3,
|
|
30
|
+
pageLoadTimeout: 30000,
|
|
31
|
+
chapterSelectorTimeout: 30000,
|
|
32
|
+
adultSelectorTimeout: 10000,
|
|
33
|
+
adultClickSettleDelay: 300,
|
|
34
|
+
tabLoadTimeout: 5000,
|
|
35
|
+
nextPageTimeout: 15000,
|
|
36
|
+
viewportMinWidth: 1200,
|
|
37
|
+
viewportMaxWidth: 1600,
|
|
38
|
+
viewportMinHeight: 800,
|
|
39
|
+
viewportMaxHeight: 1000,
|
|
40
|
+
};
|
|
41
|
+
function loadFromEnv() {
|
|
42
|
+
const overrides = {};
|
|
43
|
+
if (process.env.OUTPUT_BASE)
|
|
44
|
+
overrides.outputBase = process.env.OUTPUT_BASE;
|
|
45
|
+
if (process.env.IMAGE_CONCURRENCY)
|
|
46
|
+
overrides.imageConcurrency = Number(process.env.IMAGE_CONCURRENCY);
|
|
47
|
+
if (process.env.DOWNLOAD_DELAY)
|
|
48
|
+
overrides.downloadDelay = Number(process.env.DOWNLOAD_DELAY);
|
|
49
|
+
if (process.env.CHAPTER_DELAY_MIN)
|
|
50
|
+
overrides.chapterDelayMin = Number(process.env.CHAPTER_DELAY_MIN);
|
|
51
|
+
if (process.env.CHAPTER_DELAY_MAX)
|
|
52
|
+
overrides.chapterDelayMax = Number(process.env.CHAPTER_DELAY_MAX);
|
|
53
|
+
if (process.env.RETRY_COUNT)
|
|
54
|
+
overrides.retryCount = Number(process.env.RETRY_COUNT);
|
|
55
|
+
if (process.env.RETRY_BACKOFF_BASE)
|
|
56
|
+
overrides.retryBackoffBase = Number(process.env.RETRY_BACKOFF_BASE);
|
|
57
|
+
if (process.env.IMAGE_LOAD_DELAY)
|
|
58
|
+
overrides.imageLoadDelay = Number(process.env.IMAGE_LOAD_DELAY);
|
|
59
|
+
if (process.env.LOG_LEVEL) {
|
|
60
|
+
const level = process.env.LOG_LEVEL.toLowerCase();
|
|
61
|
+
if (["debug", "info", "warn", "error"].includes(level))
|
|
62
|
+
overrides.logLevel = level;
|
|
63
|
+
}
|
|
64
|
+
if (process.env.USER_AGENTS) {
|
|
65
|
+
overrides.userAgents = process.env.USER_AGENTS.split("\n")
|
|
66
|
+
.map((s) => s.trim())
|
|
67
|
+
.filter(Boolean);
|
|
68
|
+
}
|
|
69
|
+
return overrides;
|
|
70
|
+
}
|
|
71
|
+
function readJSONFile(filePath) {
|
|
72
|
+
try {
|
|
73
|
+
if (existsSync(filePath)) {
|
|
74
|
+
const content = readFileSync(filePath, "utf-8");
|
|
75
|
+
return JSON.parse(content);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
catch {
|
|
79
|
+
/* ignore invalid config files */
|
|
80
|
+
}
|
|
81
|
+
return null;
|
|
82
|
+
}
|
|
83
|
+
function loadConfigFile() {
|
|
84
|
+
const globalFile = readJSONFile(join(homedir(), ".config", "manhuagui-cli", "config.json"));
|
|
85
|
+
const projectFile = readJSONFile(join(process.cwd(), ".manhuaguirc.json"));
|
|
86
|
+
return { ...globalFile, ...projectFile };
|
|
87
|
+
}
|
|
88
|
+
function buildConfig(overrides) {
|
|
89
|
+
const file = loadConfigFile();
|
|
90
|
+
const env = loadFromEnv();
|
|
91
|
+
return { ...DEFAULTS, ...env, ...file, ...overrides };
|
|
92
|
+
}
|
|
93
|
+
export let config = buildConfig();
|
|
94
|
+
export function initConfig(cliOverrides) {
|
|
95
|
+
config = buildConfig(cliOverrides);
|
|
96
|
+
setLogLevel(config.logLevel);
|
|
97
|
+
}
|
|
35
98
|
export function pickUserAgent() {
|
|
36
|
-
return
|
|
99
|
+
return config.userAgents[Math.floor(Math.random() * config.userAgents.length)];
|
|
37
100
|
}
|
|
38
|
-
export const VIEWPORT_MIN_WIDTH = 1200;
|
|
39
|
-
export const VIEWPORT_MAX_WIDTH = 1600;
|
|
40
|
-
export const VIEWPORT_MIN_HEIGHT = 800;
|
|
41
|
-
export const VIEWPORT_MAX_HEIGHT = 1000;
|
|
42
101
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/logger.d.ts
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
|
+
type LogLevel = "debug" | "info" | "warn" | "error";
|
|
2
|
+
export declare function setLogLevel(level: LogLevel): void;
|
|
1
3
|
export declare const logger: {
|
|
2
4
|
debug: (msg: string) => false | void;
|
|
3
5
|
info: (msg: string) => false | void;
|
|
4
6
|
warn: (msg: string) => false | void;
|
|
5
7
|
error: (msg: string) => false | void;
|
|
6
8
|
};
|
|
9
|
+
export {};
|
|
7
10
|
//# sourceMappingURL=logger.d.ts.map
|
package/dist/lib/logger.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"logger.d.ts","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAAA,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAYpD,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,GAAG,IAAI,CAEjD;AAMD,eAAO,MAAM,MAAM;iBACJ,MAAM;gBACP,MAAM;gBACN,MAAM;iBACL,MAAM;CACpB,CAAC"}
|
package/dist/lib/logger.js
CHANGED
|
@@ -1,12 +1,16 @@
|
|
|
1
1
|
const LEVELS = { debug: 0, info: 1, warn: 2, error: 3 };
|
|
2
|
-
|
|
2
|
+
let _level = getLevelFromEnv();
|
|
3
|
+
function getLevelFromEnv() {
|
|
3
4
|
const env = process.env.LOG_LEVEL?.toLowerCase();
|
|
4
5
|
if (env && env in LEVELS)
|
|
5
6
|
return env;
|
|
6
7
|
return "info";
|
|
7
8
|
}
|
|
9
|
+
export function setLogLevel(level) {
|
|
10
|
+
_level = level;
|
|
11
|
+
}
|
|
8
12
|
function shouldLog(level) {
|
|
9
|
-
return LEVELS[level] >= LEVELS[
|
|
13
|
+
return LEVELS[level] >= LEVELS[_level];
|
|
10
14
|
}
|
|
11
15
|
export const logger = {
|
|
12
16
|
debug: (msg) => shouldLog("debug") && console.error(`[DEBUG] ${msg}`),
|
package/dist/lib/logger.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAElF,SAAS,
|
|
1
|
+
{"version":3,"file":"logger.js","sourceRoot":"","sources":["../../src/lib/logger.ts"],"names":[],"mappings":"AAEA,MAAM,MAAM,GAA6B,EAAE,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;AAElF,IAAI,MAAM,GAAa,eAAe,EAAE,CAAC;AAEzC,SAAS,eAAe;IACtB,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,CAAC;IACjD,IAAI,GAAG,IAAI,GAAG,IAAI,MAAM;QAAE,OAAO,GAAe,CAAC;IACjD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,KAAe;IACzC,MAAM,GAAG,KAAK,CAAC;AACjB,CAAC;AAED,SAAS,SAAS,CAAC,KAAe;IAChC,OAAO,MAAM,CAAC,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC;AACzC,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAAG;IACpB,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;IAC7E,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC;IAC5D,IAAI,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,EAAE,CAAC;IAC1E,KAAK,EAAE,CAAC,GAAW,EAAE,EAAE,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,OAAO,CAAC,KAAK,CAAC,WAAW,GAAG,EAAE,CAAC;CAC9E,CAAC"}
|
package/dist/lib/progress.d.ts
CHANGED
|
@@ -9,14 +9,20 @@ export interface ProgressData {
|
|
|
9
9
|
comicUrl: string;
|
|
10
10
|
chapters: Record<string, ChapterProgress>;
|
|
11
11
|
}
|
|
12
|
-
export declare function loadProgress(comicDir: string): ProgressData | null;
|
|
13
|
-
export declare function loadProgressOrWarn(comicDir: string): ProgressData | null;
|
|
12
|
+
export declare function loadProgress(comicDir: string, warnOnError?: boolean): ProgressData | null;
|
|
14
13
|
export declare function createProgress(comicTitle: string, comicUrl: string): ProgressData;
|
|
15
14
|
export declare function saveProgress(comicDir: string, data: ProgressData): void;
|
|
16
|
-
export declare function markChapter(
|
|
17
|
-
|
|
18
|
-
|
|
15
|
+
export declare function markChapter(opts: {
|
|
16
|
+
comicDir: string;
|
|
17
|
+
progress: ProgressData;
|
|
18
|
+
key: string;
|
|
19
|
+
status: "done" | "failed";
|
|
20
|
+
extra?: {
|
|
21
|
+
pageCount?: number;
|
|
22
|
+
error?: string;
|
|
23
|
+
};
|
|
19
24
|
}): void;
|
|
20
25
|
export declare function chapterKey(sectionName: string, chapterTitle: string): string;
|
|
26
|
+
export declare function countCompletedPages(progress: ProgressData): number;
|
|
21
27
|
export declare function filterPending(progress: ProgressData | null, sections: Section[]): Section[];
|
|
22
28
|
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3C;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"progress.d.ts","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAG1C,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,YAAY;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,eAAe,CAAC,CAAC;CAC3C;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,WAAW,UAAQ,GAAG,YAAY,GAAG,IAAI,CAWvF;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,YAAY,CAEjF;AAED,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,YAAY,GAAG,IAAI,CAEvE;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAChC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,YAAY,CAAC;IACvB,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,QAAQ,CAAC;IAC1B,KAAK,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;CAChD,GAAG,IAAI,CAGP;AAED,wBAAgB,UAAU,CAAC,WAAW,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,MAAM,CAE5E;AAED,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,YAAY,GAAG,MAAM,CAQlE;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,YAAY,GAAG,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAY3F"}
|
package/dist/lib/progress.js
CHANGED
|
@@ -2,23 +2,16 @@ import { readFileSync } from "node:fs";
|
|
|
2
2
|
import { join } from "node:path";
|
|
3
3
|
import { logger } from "./logger.js";
|
|
4
4
|
import { atomicSaveJSON } from "./utils.js";
|
|
5
|
-
export function loadProgress(comicDir) {
|
|
6
|
-
try {
|
|
7
|
-
const raw = readFileSync(join(comicDir, "progress.json"), "utf-8");
|
|
8
|
-
return JSON.parse(raw);
|
|
9
|
-
}
|
|
10
|
-
catch {
|
|
11
|
-
return null;
|
|
12
|
-
}
|
|
13
|
-
}
|
|
14
|
-
export function loadProgressOrWarn(comicDir) {
|
|
5
|
+
export function loadProgress(comicDir, warnOnError = false) {
|
|
15
6
|
try {
|
|
16
7
|
const raw = readFileSync(join(comicDir, "progress.json"), "utf-8");
|
|
17
8
|
return JSON.parse(raw);
|
|
18
9
|
}
|
|
19
10
|
catch (err) {
|
|
20
|
-
|
|
21
|
-
|
|
11
|
+
if (warnOnError) {
|
|
12
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
13
|
+
logger.warn(`Failed to load progress.json: ${message}`);
|
|
14
|
+
}
|
|
22
15
|
return null;
|
|
23
16
|
}
|
|
24
17
|
}
|
|
@@ -28,13 +21,22 @@ export function createProgress(comicTitle, comicUrl) {
|
|
|
28
21
|
export function saveProgress(comicDir, data) {
|
|
29
22
|
atomicSaveJSON(join(comicDir, "progress.json"), data);
|
|
30
23
|
}
|
|
31
|
-
export function markChapter(
|
|
32
|
-
progress.chapters[key] = { status, ...extra };
|
|
33
|
-
saveProgress(comicDir, progress);
|
|
24
|
+
export function markChapter(opts) {
|
|
25
|
+
opts.progress.chapters[opts.key] = { status: opts.status, ...opts.extra };
|
|
26
|
+
saveProgress(opts.comicDir, opts.progress);
|
|
34
27
|
}
|
|
35
28
|
export function chapterKey(sectionName, chapterTitle) {
|
|
36
29
|
return `${sectionName}::${chapterTitle}`;
|
|
37
30
|
}
|
|
31
|
+
export function countCompletedPages(progress) {
|
|
32
|
+
let count = 0;
|
|
33
|
+
for (const entry of Object.values(progress.chapters)) {
|
|
34
|
+
if (entry.status === "done" && entry.pageCount) {
|
|
35
|
+
count += entry.pageCount;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
return count;
|
|
39
|
+
}
|
|
38
40
|
export function filterPending(progress, sections) {
|
|
39
41
|
if (!progress)
|
|
40
42
|
return sections;
|
package/dist/lib/progress.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAc5C,MAAM,UAAU,YAAY,CAAC,QAAgB;
|
|
1
|
+
{"version":3,"file":"progress.js","sourceRoot":"","sources":["../../src/lib/progress.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAErC,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAc5C,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,WAAW,GAAG,KAAK;IAChE,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,OAAO,CAAC,CAAC;QACnE,OAAO,IAAI,CAAC,KAAK,CAAC,GAAG,CAAiB,CAAC;IACzC,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,IAAI,WAAW,EAAE,CAAC;YAChB,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACjE,MAAM,CAAC,IAAI,CAAC,iCAAiC,OAAO,EAAE,CAAC,CAAC;QAC1D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,cAAc,CAAC,UAAkB,EAAE,QAAgB;IACjE,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE,EAAE,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,IAAkB;IAC/D,cAAc,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,CAAC;AACxD,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,IAM3B;IACC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,EAAE,CAAC;IAC1E,YAAY,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC7C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,WAAmB,EAAE,YAAoB;IAClE,OAAO,GAAG,WAAW,KAAK,YAAY,EAAE,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,QAAsB;IACxD,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QACrD,IAAI,KAAK,CAAC,MAAM,KAAK,MAAM,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAC/C,KAAK,IAAI,KAAK,CAAC,SAAS,CAAC;QAC3B,CAAC;IACH,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,QAA6B,EAAE,QAAmB;IAC9E,IAAI,CAAC,QAAQ;QAAE,OAAO,QAAQ,CAAC;IAE/B,OAAO,QAAQ;SACZ,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACX,GAAG,CAAC;QACJ,QAAQ,EAAE,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE;YAChC,MAAM,CAAC,GAAG,QAAQ,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;YACzD,OAAO,CAAC,EAAE,MAAM,KAAK,MAAM,CAAC;QAC9B,CAAC,CAAC;KACH,CAAC,CAAC;SACF,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;AAC1C,CAAC"}
|
package/dist/lib/prompts.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Section } from "./types.js";
|
|
2
|
+
export declare function assertNotCanceled<T>(result: T | symbol): asserts result is T;
|
|
2
3
|
export declare function promptUrl(): Promise<string>;
|
|
3
4
|
export declare function promptSections(sections: Section[]): Promise<Section[]>;
|
|
4
5
|
export declare function promptConfirm(count: number): Promise<boolean>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,wBAAgB,iBAAiB,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,MAAM,GAAG,OAAO,CAAC,MAAM,IAAI,CAAC,CAI5E;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAajD;AAED,wBAAsB,cAAc,CAAC,QAAQ,EAAE,OAAO,EAAE,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC,CAkB5E;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQnE;AAED,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAQhF"}
|
package/dist/lib/prompts.js
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
import { confirm, isCancel, multiselect, text } from "@clack/prompts";
|
|
2
2
|
import { CancelledError } from "./errors.js";
|
|
3
|
+
export function assertNotCanceled(result) {
|
|
4
|
+
if (isCancel(result)) {
|
|
5
|
+
throw new CancelledError();
|
|
6
|
+
}
|
|
7
|
+
}
|
|
3
8
|
export async function promptUrl() {
|
|
4
9
|
const result = await text({
|
|
5
10
|
message: "Comic URL",
|
|
@@ -10,9 +15,7 @@ export async function promptUrl() {
|
|
|
10
15
|
}
|
|
11
16
|
},
|
|
12
17
|
});
|
|
13
|
-
|
|
14
|
-
throw new CancelledError();
|
|
15
|
-
}
|
|
18
|
+
assertNotCanceled(result);
|
|
16
19
|
return result;
|
|
17
20
|
}
|
|
18
21
|
export async function promptSections(sections) {
|
|
@@ -28,9 +31,7 @@ export async function promptSections(sections) {
|
|
|
28
31
|
options,
|
|
29
32
|
required: true,
|
|
30
33
|
});
|
|
31
|
-
|
|
32
|
-
throw new CancelledError();
|
|
33
|
-
}
|
|
34
|
+
assertNotCanceled(selected);
|
|
34
35
|
return sections.filter((s) => selected.includes(s.name));
|
|
35
36
|
}
|
|
36
37
|
export async function promptConfirm(count) {
|
|
@@ -38,9 +39,7 @@ export async function promptConfirm(count) {
|
|
|
38
39
|
message: `Download ${count} chapters?`,
|
|
39
40
|
initialValue: true,
|
|
40
41
|
});
|
|
41
|
-
|
|
42
|
-
throw new CancelledError();
|
|
43
|
-
}
|
|
42
|
+
assertNotCanceled(result);
|
|
44
43
|
return result;
|
|
45
44
|
}
|
|
46
45
|
export async function promptResume(done, total) {
|
|
@@ -48,9 +47,7 @@ export async function promptResume(done, total) {
|
|
|
48
47
|
message: `Detected previous progress (${done}/${total} chapters done). Resume?`,
|
|
49
48
|
initialValue: true,
|
|
50
49
|
});
|
|
51
|
-
|
|
52
|
-
throw new CancelledError();
|
|
53
|
-
}
|
|
50
|
+
assertNotCanceled(result);
|
|
54
51
|
return result;
|
|
55
52
|
}
|
|
56
53
|
//# sourceMappingURL=prompts.js.map
|
package/dist/lib/prompts.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;QACxB,OAAO,EAAE,WAAW;QACpB,WAAW,EAAE,qCAAqC;QAClD,QAAQ,CAAC,KAAK;YACZ,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,kCAAkC,CAAC,EAAE,CAAC;gBAC3D,OAAO,uCAAuC,CAAC;YACjD,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/lib/prompts.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,WAAW,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AACtE,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAG7C,MAAM,UAAU,iBAAiB,CAAI,MAAkB;IACrD,IAAI,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,cAAc,EAAE,CAAC;IAC7B,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,SAAS;IAC7B,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC;QACxB,OAAO,EAAE,WAAW;QACpB,WAAW,EAAE,qCAAqC;QAClD,QAAQ,CAAC,KAAK;YACZ,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,kCAAkC,CAAC,EAAE,CAAC;gBAC3D,OAAO,uCAAuC,CAAC;YACjD,CAAC;QACH,CAAC;KACF,CAAC,CAAC;IAEH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,QAAmB;IACtD,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,MAAM,IAAI,KAAK,CAAC,wEAAwE,CAAC,CAAC;IAC5F,CAAC;IAED,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;QACnC,KAAK,EAAE,CAAC,CAAC,IAAI;QACb,KAAK,EAAE,GAAG,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,QAAQ,CAAC,MAAM,YAAY;KACnD,CAAC,CAAC,CAAC;IAEJ,MAAM,QAAQ,GAAG,MAAM,WAAW,CAAC;QACjC,OAAO,EAAE,6BAA6B;QACtC,OAAO;QACP,QAAQ,EAAE,IAAI;KACf,CAAC,CAAC;IAEH,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAC5B,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;AAC3D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,KAAa;IAC/C,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC3B,OAAO,EAAE,YAAY,KAAK,YAAY;QACtC,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,KAAa;IAC5D,MAAM,MAAM,GAAG,MAAM,OAAO,CAAC;QAC3B,OAAO,EAAE,+BAA+B,IAAI,IAAI,KAAK,0BAA0B;QAC/E,YAAY,EAAE,IAAI;KACnB,CAAC,CAAC;IAEH,iBAAiB,CAAC,MAAM,CAAC,CAAC;IAC1B,OAAO,MAAM,CAAC;AAChB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export declare class SpeedTracker {
|
|
2
|
+
private samples;
|
|
3
|
+
private maxSamples;
|
|
4
|
+
private chapterDurations;
|
|
5
|
+
private maxChapterSamples;
|
|
6
|
+
record(bytes: number, durationMs: number): void;
|
|
7
|
+
recordChapter(durationMs: number): void;
|
|
8
|
+
get bytesPerSecond(): number;
|
|
9
|
+
get avgBytesPerImage(): number;
|
|
10
|
+
get avgChapterDurationMs(): number;
|
|
11
|
+
get sampleCount(): number;
|
|
12
|
+
estimateSection(remainingImages: number, remainingChapters: number): number;
|
|
13
|
+
static formatMs(ms: number): string;
|
|
14
|
+
static formatMsCompact(ms: number): string;
|
|
15
|
+
}
|
|
16
|
+
//# sourceMappingURL=speed.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speed.d.ts","sourceRoot":"","sources":["../../src/lib/speed.ts"],"names":[],"mappings":"AAOA,qBAAa,YAAY;IACvB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,UAAU,CAAM;IACxB,OAAO,CAAC,gBAAgB,CAAgB;IACxC,OAAO,CAAC,iBAAiB,CAAM;IAE/B,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAQ/C,aAAa,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAQvC,IAAI,cAAc,IAAI,MAAM,CAI3B;IAED,IAAI,gBAAgB,IAAI,MAAM,CAG7B;IAED,IAAI,oBAAoB,IAAI,MAAM,CAGjC;IAED,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,eAAe,CAAC,eAAe,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,GAAG,MAAM;IAiB3E,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;IAYnC,MAAM,CAAC,eAAe,CAAC,EAAE,EAAE,MAAM,GAAG,MAAM;CAW3C"}
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import { config } from "./config.js";
|
|
2
|
+
export class SpeedTracker {
|
|
3
|
+
samples = [];
|
|
4
|
+
maxSamples = 20;
|
|
5
|
+
chapterDurations = [];
|
|
6
|
+
maxChapterSamples = 50;
|
|
7
|
+
record(bytes, durationMs) {
|
|
8
|
+
if (bytes <= 0 || durationMs <= 0)
|
|
9
|
+
return;
|
|
10
|
+
this.samples.push({ bytes, durationMs });
|
|
11
|
+
if (this.samples.length > this.maxSamples) {
|
|
12
|
+
this.samples.shift();
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
recordChapter(durationMs) {
|
|
16
|
+
if (durationMs <= 0)
|
|
17
|
+
return;
|
|
18
|
+
this.chapterDurations.push(durationMs);
|
|
19
|
+
if (this.chapterDurations.length > this.maxChapterSamples) {
|
|
20
|
+
this.chapterDurations.shift();
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
get bytesPerSecond() {
|
|
24
|
+
const totalBytes = this.samples.reduce((s, x) => s + x.bytes, 0);
|
|
25
|
+
const totalMs = this.samples.reduce((s, x) => s + x.durationMs, 0);
|
|
26
|
+
return totalMs > 0 ? (totalBytes / totalMs) * 1000 : 0;
|
|
27
|
+
}
|
|
28
|
+
get avgBytesPerImage() {
|
|
29
|
+
if (this.samples.length === 0)
|
|
30
|
+
return 0;
|
|
31
|
+
return this.samples.reduce((s, x) => s + x.bytes, 0) / this.samples.length;
|
|
32
|
+
}
|
|
33
|
+
get avgChapterDurationMs() {
|
|
34
|
+
if (this.chapterDurations.length === 0)
|
|
35
|
+
return 0;
|
|
36
|
+
return this.chapterDurations.reduce((s, x) => s + x, 0) / this.chapterDurations.length;
|
|
37
|
+
}
|
|
38
|
+
get sampleCount() {
|
|
39
|
+
return this.samples.length;
|
|
40
|
+
}
|
|
41
|
+
estimateSection(remainingImages, remainingChapters) {
|
|
42
|
+
const speed = this.bytesPerSecond;
|
|
43
|
+
const avgBytes = this.avgBytesPerImage;
|
|
44
|
+
if (speed <= 0 || avgBytes <= 0 || remainingImages <= 0)
|
|
45
|
+
return 0;
|
|
46
|
+
const downloadTime = ((remainingImages * avgBytes) / speed) * 1000;
|
|
47
|
+
const batchCount = Math.ceil(remainingImages / config.imageConcurrency);
|
|
48
|
+
const avgBatchDelay = config.downloadDelay * 0.75;
|
|
49
|
+
const batchDelay = Math.max(0, batchCount - 1) * avgBatchDelay;
|
|
50
|
+
const avgChapterDelay = (config.chapterDelayMin + config.chapterDelayMax) / 2;
|
|
51
|
+
const chapterDelay = Math.max(0, remainingChapters - 1) * avgChapterDelay;
|
|
52
|
+
return Math.round(downloadTime + batchDelay + chapterDelay);
|
|
53
|
+
}
|
|
54
|
+
static formatMs(ms) {
|
|
55
|
+
if (ms <= 0)
|
|
56
|
+
return "--";
|
|
57
|
+
const seconds = Math.round(ms / 1000);
|
|
58
|
+
if (seconds < 60)
|
|
59
|
+
return `${seconds}s`;
|
|
60
|
+
const minutes = Math.floor(seconds / 60);
|
|
61
|
+
const secs = seconds % 60;
|
|
62
|
+
if (minutes < 60)
|
|
63
|
+
return secs > 0 ? `${minutes}m ${secs}s` : `${minutes}m`;
|
|
64
|
+
const hours = Math.floor(minutes / 60);
|
|
65
|
+
const mins = minutes % 60;
|
|
66
|
+
return mins > 0 ? `${hours}h ${mins}m` : `${hours}h`;
|
|
67
|
+
}
|
|
68
|
+
static formatMsCompact(ms) {
|
|
69
|
+
if (ms <= 0)
|
|
70
|
+
return "--";
|
|
71
|
+
const seconds = Math.round(ms / 1000);
|
|
72
|
+
if (seconds < 60)
|
|
73
|
+
return `${seconds}s`;
|
|
74
|
+
const minutes = Math.floor(seconds / 60);
|
|
75
|
+
const secs = seconds % 60;
|
|
76
|
+
if (minutes < 60)
|
|
77
|
+
return secs > 0 ? `${minutes}m${secs}s` : `${minutes}m`;
|
|
78
|
+
const hours = Math.floor(minutes / 60);
|
|
79
|
+
const mins = minutes % 60;
|
|
80
|
+
return mins > 0 ? `${hours}h${mins}m` : `${hours}h`;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
//# sourceMappingURL=speed.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"speed.js","sourceRoot":"","sources":["../../src/lib/speed.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Browser } from "playwright";
|
|
2
|
+
import type { Section } from "./types.js";
|
|
3
|
+
export interface PipelineResult {
|
|
4
|
+
collected: Record<string, {
|
|
5
|
+
urls: string[];
|
|
6
|
+
chapterUrl: string;
|
|
7
|
+
}>;
|
|
8
|
+
errors: string[];
|
|
9
|
+
ok: number;
|
|
10
|
+
failed: number;
|
|
11
|
+
}
|
|
12
|
+
export interface RunPipelineOptions {
|
|
13
|
+
sections: Section[];
|
|
14
|
+
comicTitle: string;
|
|
15
|
+
comicUrl: string;
|
|
16
|
+
browser: Browser;
|
|
17
|
+
resume: boolean;
|
|
18
|
+
totalPagesExpected: number;
|
|
19
|
+
}
|
|
20
|
+
export declare function runPipeline(opts: RunPipelineOptions): Promise<PipelineResult>;
|
|
21
|
+
//# sourceMappingURL=tasks.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"tasks.d.ts","sourceRoot":"","sources":["../../src/lib/tasks.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAc1C,OAAO,KAAK,EAAW,OAAO,EAAE,MAAM,YAAY,CAAC;AAInD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAAC,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAClE,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;CAChB;AAkCD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,CAAC;IAChB,kBAAkB,EAAE,MAAM,CAAC;CAC5B;AAED,wBAAsB,WAAW,CAAC,IAAI,EAAE,kBAAkB,GAAG,OAAO,CAAC,cAAc,CAAC,CAyGnF"}
|