frond-js 0.4.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.en.md +247 -0
- package/README.md +211 -0
- package/dist/abort-BY8vBk0v.d.cts +99 -0
- package/dist/abort-BY8vBk0v.d.ts +99 -0
- package/dist/adapter-3G46J3CA.cjs +503 -0
- package/dist/adapter-3ONQWJVQ.js +501 -0
- package/dist/adapter-55QHWRSE.js +124 -0
- package/dist/adapter-DF34GBWJ.cjs +19 -0
- package/dist/adapter-EXTNILTC.cjs +126 -0
- package/dist/adapter-GOFC7TMC.js +284 -0
- package/dist/adapter-LRJTQ47I.cjs +286 -0
- package/dist/adapter-TWWZML4A.js +17 -0
- package/dist/adapter-ZM5FQTJT.js +1415 -0
- package/dist/adapter-ZRNSDQUV.cjs +1417 -0
- package/dist/chunk-2SUG7YFZ.cjs +108 -0
- package/dist/chunk-B2L2YVXD.js +89 -0
- package/dist/chunk-D4KWSEZD.js +393 -0
- package/dist/chunk-EZTIZO6R.cjs +430 -0
- package/dist/chunk-G7DLWGBW.cjs +103 -0
- package/dist/chunk-GTGLDLJD.cjs +479 -0
- package/dist/chunk-IIV6VIUJ.cjs +83 -0
- package/dist/chunk-JDTHZQUK.js +102 -0
- package/dist/chunk-JJVXT3AC.js +30 -0
- package/dist/chunk-LIXRYQL2.js +473 -0
- package/dist/chunk-NABYHI6X.cjs +400 -0
- package/dist/chunk-SJVOYNTF.js +425 -0
- package/dist/chunk-SLI2YL25.cjs +252 -0
- package/dist/chunk-U4264IQH.js +78 -0
- package/dist/chunk-UY2YRCFC.js +250 -0
- package/dist/chunk-WCZTTQ7Z.cjs +32 -0
- package/dist/core/index.cjs +162 -0
- package/dist/core/index.d.cts +321 -0
- package/dist/core/index.d.ts +321 -0
- package/dist/core/index.js +49 -0
- package/dist/default-DRLIJX73.js +1183 -0
- package/dist/default-UK52WOO5.cjs +1192 -0
- package/dist/formats/epub/index.cjs +29 -0
- package/dist/formats/epub/index.d.cts +286 -0
- package/dist/formats/epub/index.d.ts +286 -0
- package/dist/formats/epub/index.js +11 -0
- package/dist/index.cjs +655 -0
- package/dist/index.d.cts +335 -0
- package/dist/index.d.ts +335 -0
- package/dist/index.js +600 -0
- package/dist/render/index.cjs +2 -0
- package/dist/render/index.d.cts +116 -0
- package/dist/render/index.d.ts +116 -0
- package/dist/render/index.js +1 -0
- package/dist/types-B76GOMxj.d.ts +129 -0
- package/dist/types-B7mslPBY.d.cts +166 -0
- package/dist/types-B7mslPBY.d.ts +166 -0
- package/dist/types-BH88rUYt.d.cts +129 -0
- package/dist/types-C-5eHSRH.d.ts +379 -0
- package/dist/types-CPUqTEPW.d.cts +379 -0
- package/dist/types-DQYmArgv.d.cts +17 -0
- package/dist/types-DQYmArgv.d.ts +17 -0
- package/package.json +115 -0
|
@@ -0,0 +1,479 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkG7DLWGBW_cjs = require('./chunk-G7DLWGBW.cjs');
|
|
4
|
+
|
|
5
|
+
// src/core/cfi/serialize.ts
|
|
6
|
+
var ESCAPABLE = "^[](),;=";
|
|
7
|
+
function escapeValue(value) {
|
|
8
|
+
let out = "";
|
|
9
|
+
for (const char of value) {
|
|
10
|
+
out += ESCAPABLE.includes(char) ? `^${char}` : char;
|
|
11
|
+
}
|
|
12
|
+
return out;
|
|
13
|
+
}
|
|
14
|
+
function serializeSide(side) {
|
|
15
|
+
if (side === void 0) return "";
|
|
16
|
+
return `;s=${side === "before" ? "b" : "a"}`;
|
|
17
|
+
}
|
|
18
|
+
function wrapAssertion(body) {
|
|
19
|
+
return body === "" ? "" : `[${body}]`;
|
|
20
|
+
}
|
|
21
|
+
function serializeStep(step) {
|
|
22
|
+
const body = `${step.id === void 0 ? "" : escapeValue(step.id)}${serializeSide(step.side)}`;
|
|
23
|
+
return `/${step.index}${wrapAssertion(body)}`;
|
|
24
|
+
}
|
|
25
|
+
function serializeOffset(offset, point) {
|
|
26
|
+
if (offset === void 0) {
|
|
27
|
+
if (point.text === void 0 && point.textAfter === void 0 && point.side === void 0) {
|
|
28
|
+
return "";
|
|
29
|
+
}
|
|
30
|
+
throw new chunkG7DLWGBW_cjs.FormatError("\u504F\u79FB\u65AD\u8A00\u7F3A\u5C11\u5B57\u7B26\u504F\u79FB");
|
|
31
|
+
}
|
|
32
|
+
const values = point.text === void 0 ? point.textAfter === void 0 ? "" : `,${escapeValue(point.textAfter)}` : `${escapeValue(point.text)}${point.textAfter === void 0 ? "" : `,${escapeValue(point.textAfter)}`}`;
|
|
33
|
+
return `:${offset}${wrapAssertion(`${values}${serializeSide(point.side)}`)}`;
|
|
34
|
+
}
|
|
35
|
+
function serializeSteps(steps) {
|
|
36
|
+
return steps.map(serializeStep).join("");
|
|
37
|
+
}
|
|
38
|
+
function serializePaths(paths) {
|
|
39
|
+
return paths.map((path) => serializeSteps(path.steps)).join("!");
|
|
40
|
+
}
|
|
41
|
+
function serializePointBody(point) {
|
|
42
|
+
return `${serializePaths(point.paths)}${serializeOffset(point.offset, point)}`;
|
|
43
|
+
}
|
|
44
|
+
function serializePoint(point) {
|
|
45
|
+
return `epubcfi(${serializePointBody(point)})`;
|
|
46
|
+
}
|
|
47
|
+
function relativeSubpath(parent, point, label) {
|
|
48
|
+
const parentLength = parent.length;
|
|
49
|
+
const mismatch = new chunkG7DLWGBW_cjs.FormatError(`${label} \u4E0E\u7236\u8DEF\u5F84\u7ED3\u6784\u4E0D\u4E00\u81F4\uFF0C\u65E0\u6CD5\u56DE\u5199\u4E3A\u89C4\u8303\u5F62\u6001`);
|
|
50
|
+
if (parentLength === 0 || point.paths.length < parentLength) throw mismatch;
|
|
51
|
+
const sameSteps = (left, right) => {
|
|
52
|
+
if (left.length !== right.length) return false;
|
|
53
|
+
return left.every((step, index) => step.index === right[index]?.index);
|
|
54
|
+
};
|
|
55
|
+
for (let i = 0; i < parentLength - 1; i += 1) {
|
|
56
|
+
const expected = parent[i];
|
|
57
|
+
const actual = point.paths[i];
|
|
58
|
+
if (expected === void 0 || actual === void 0 || !sameSteps(expected.steps, actual.steps)) {
|
|
59
|
+
throw mismatch;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
const parentLast = parent[parentLength - 1];
|
|
63
|
+
const merged = point.paths[parentLength - 1];
|
|
64
|
+
if (parentLast === void 0 || merged === void 0) throw mismatch;
|
|
65
|
+
const prefix = parentLast.steps;
|
|
66
|
+
if (merged.steps.length < prefix.length) throw mismatch;
|
|
67
|
+
for (let i = 0; i < prefix.length; i += 1) {
|
|
68
|
+
if (prefix[i]?.index !== merged.steps[i]?.index) throw mismatch;
|
|
69
|
+
}
|
|
70
|
+
let body = serializeSteps(merged.steps.slice(prefix.length));
|
|
71
|
+
for (const path of point.paths.slice(parentLength)) {
|
|
72
|
+
body += `!${serializeSteps(path.steps)}`;
|
|
73
|
+
}
|
|
74
|
+
return `${body}${serializeOffset(point.offset, point)}`;
|
|
75
|
+
}
|
|
76
|
+
function serializeRange(range) {
|
|
77
|
+
if (range.parent === null) {
|
|
78
|
+
return `epubcfi(${serializePointBody(range.start)},${serializePointBody(range.end)})`;
|
|
79
|
+
}
|
|
80
|
+
const parentBody = serializePaths(range.parent);
|
|
81
|
+
const startBody = relativeSubpath(range.parent, range.start, "\u8303\u56F4\u8D77\u70B9");
|
|
82
|
+
const endBody = relativeSubpath(range.parent, range.end, "\u8303\u56F4\u7EC8\u70B9");
|
|
83
|
+
return `epubcfi(${parentBody},${startBody},${endBody})`;
|
|
84
|
+
}
|
|
85
|
+
function serializeCfi(cfi) {
|
|
86
|
+
return cfi.kind === "point" ? serializePoint(cfi) : serializeRange(cfi);
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
// src/core/cfi/collapse.ts
|
|
90
|
+
function collapseCfi(cfi, toEnd = false) {
|
|
91
|
+
if (cfi.kind === "point") return serializePoint(cfi);
|
|
92
|
+
return serializePoint(toEnd ? cfi.end : cfi.start);
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
// src/core/cfi/parse.ts
|
|
96
|
+
var ESCAPABLE2 = "^[](),;=";
|
|
97
|
+
function isDigit(char) {
|
|
98
|
+
return char !== void 0 && char >= "0" && char <= "9";
|
|
99
|
+
}
|
|
100
|
+
function splitTopLevel(raw, separator, context) {
|
|
101
|
+
const parts = [];
|
|
102
|
+
let current = "";
|
|
103
|
+
let depth = 0;
|
|
104
|
+
for (let i = 0; i < raw.length; i += 1) {
|
|
105
|
+
const char = raw[i];
|
|
106
|
+
if (char === "^") {
|
|
107
|
+
const next = raw[i + 1];
|
|
108
|
+
if (next === void 0) {
|
|
109
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8F6C\u4E49\u7B26 '^' \u540E\u7F3A\u5C11\u5B57\u7B26\uFF08${context}\uFF09`);
|
|
110
|
+
}
|
|
111
|
+
current += char + next;
|
|
112
|
+
i += 1;
|
|
113
|
+
continue;
|
|
114
|
+
}
|
|
115
|
+
if (char === "[") {
|
|
116
|
+
depth += 1;
|
|
117
|
+
current += char;
|
|
118
|
+
continue;
|
|
119
|
+
}
|
|
120
|
+
if (char === "]") {
|
|
121
|
+
depth -= 1;
|
|
122
|
+
if (depth < 0) {
|
|
123
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u51FA\u73B0\u672A\u914D\u5BF9\u7684 ']'\uFF08${context}\uFF09`);
|
|
124
|
+
}
|
|
125
|
+
current += char;
|
|
126
|
+
continue;
|
|
127
|
+
}
|
|
128
|
+
if (char === separator && depth === 0) {
|
|
129
|
+
parts.push(current);
|
|
130
|
+
current = "";
|
|
131
|
+
continue;
|
|
132
|
+
}
|
|
133
|
+
current += char;
|
|
134
|
+
}
|
|
135
|
+
if (depth !== 0) {
|
|
136
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u65B9\u62EC\u53F7\u672A\u95ED\u5408\uFF08${context}\uFF09`);
|
|
137
|
+
}
|
|
138
|
+
parts.push(current);
|
|
139
|
+
return parts;
|
|
140
|
+
}
|
|
141
|
+
function unescapeValue(raw, context) {
|
|
142
|
+
let out = "";
|
|
143
|
+
for (let i = 0; i < raw.length; i += 1) {
|
|
144
|
+
const char = raw[i];
|
|
145
|
+
if (char !== "^") {
|
|
146
|
+
out += char;
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
const next = raw[i + 1];
|
|
150
|
+
if (next === void 0) {
|
|
151
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u65AD\u8A00\u4E2D\u5B58\u5728\u672A\u5B8C\u6210\u7684\u8F6C\u4E49\u7B26 '^'\uFF08${context}\uFF09`);
|
|
152
|
+
}
|
|
153
|
+
if (!ESCAPABLE2.includes(next)) {
|
|
154
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u65AD\u8A00\u4E2D\u7684\u8F6C\u4E49\u5B57\u7B26\u975E\u6CD5\uFF1A'^${next}'\uFF08${context}\uFF09`);
|
|
155
|
+
}
|
|
156
|
+
out += next;
|
|
157
|
+
i += 1;
|
|
158
|
+
}
|
|
159
|
+
return out;
|
|
160
|
+
}
|
|
161
|
+
function containsUnescapedOpenBracket(raw) {
|
|
162
|
+
for (let i = 0; i < raw.length; i += 1) {
|
|
163
|
+
const char = raw[i];
|
|
164
|
+
if (char === "^") {
|
|
165
|
+
i += 1;
|
|
166
|
+
continue;
|
|
167
|
+
}
|
|
168
|
+
if (char === "[") return true;
|
|
169
|
+
}
|
|
170
|
+
return false;
|
|
171
|
+
}
|
|
172
|
+
function parseAssertion(raw, context) {
|
|
173
|
+
if (containsUnescapedOpenBracket(raw)) {
|
|
174
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u65AD\u8A00\u4E2D\u7684 '[' \u5FC5\u987B\u8F6C\u4E49\u4E3A '^['\uFF08${context}\uFF09`);
|
|
175
|
+
}
|
|
176
|
+
const [valuePart = "", ...parameters] = splitTopLevel(raw, ";", context);
|
|
177
|
+
let leading;
|
|
178
|
+
let trailing;
|
|
179
|
+
if (valuePart !== "") {
|
|
180
|
+
const values = splitTopLevel(valuePart, ",", context);
|
|
181
|
+
if (values.length > 2) {
|
|
182
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u65AD\u8A00\u4E2D\u9017\u53F7\u5206\u9694\u7684\u503C\u8D85\u8FC7 2 \u4E2A\uFF08${context}\uFF09`);
|
|
183
|
+
}
|
|
184
|
+
const [first = "", second] = values;
|
|
185
|
+
if (first !== "") {
|
|
186
|
+
leading = unescapeValue(first, context);
|
|
187
|
+
}
|
|
188
|
+
if (second !== void 0 && second !== "") {
|
|
189
|
+
trailing = unescapeValue(second, context);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
let side;
|
|
193
|
+
for (const parameter of parameters) {
|
|
194
|
+
const equal = parameter.indexOf("=");
|
|
195
|
+
if (equal <= 0) {
|
|
196
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u65AD\u8A00\u53C2\u6570\u7F3A\u5C11 'k=v' \u5F62\u5F0F\uFF1A${JSON.stringify(parameter)}\uFF08${context}\uFF09`);
|
|
197
|
+
}
|
|
198
|
+
const name = parameter.slice(0, equal);
|
|
199
|
+
const value = parameter.slice(equal + 1);
|
|
200
|
+
if (name !== "s") {
|
|
201
|
+
throw new chunkG7DLWGBW_cjs.FormatError(
|
|
202
|
+
`\u65AD\u8A00\u53C2\u6570\u540D\u4E0D\u652F\u6301\uFF1A${JSON.stringify(name)}\uFF08\u4EC5\u652F\u6301 's'\uFF09\uFF08${context}\uFF09`
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
if (value === "b") {
|
|
206
|
+
side = "before";
|
|
207
|
+
} else if (value === "a") {
|
|
208
|
+
side = "after";
|
|
209
|
+
} else {
|
|
210
|
+
throw new chunkG7DLWGBW_cjs.FormatError(
|
|
211
|
+
`side bias \u53D6\u503C\u975E\u6CD5\uFF1A${JSON.stringify(value)}\uFF08\u4EC5\u652F\u6301 'b' / 'a'\uFF09\uFF08${context}\uFF09`
|
|
212
|
+
);
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
return {
|
|
216
|
+
...leading !== void 0 ? { leading } : {},
|
|
217
|
+
...trailing !== void 0 ? { trailing } : {},
|
|
218
|
+
...side !== void 0 ? { side } : {}
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
function tryReadAssertion(raw, start, context) {
|
|
222
|
+
if (raw[start] !== "[") return null;
|
|
223
|
+
let depth = 0;
|
|
224
|
+
for (let i = start; i < raw.length; i += 1) {
|
|
225
|
+
const char = raw[i];
|
|
226
|
+
if (char === "^") {
|
|
227
|
+
i += 1;
|
|
228
|
+
continue;
|
|
229
|
+
}
|
|
230
|
+
if (char === "[") {
|
|
231
|
+
depth += 1;
|
|
232
|
+
} else if (char === "]") {
|
|
233
|
+
depth -= 1;
|
|
234
|
+
if (depth === 0) {
|
|
235
|
+
return { content: raw.slice(start + 1, i), next: i + 1 };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u65B9\u62EC\u53F7\u672A\u95ED\u5408\uFF08${context}\uFF09`);
|
|
240
|
+
}
|
|
241
|
+
function parseInteger(raw, context) {
|
|
242
|
+
if (raw.length > 1 && raw.startsWith("0")) {
|
|
243
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u6570\u5B57\u4E0D\u5141\u8BB8\u524D\u5BFC\u96F6\uFF1A${JSON.stringify(raw)}\uFF08${context}\uFF09`);
|
|
244
|
+
}
|
|
245
|
+
const value = Number(raw);
|
|
246
|
+
if (!Number.isSafeInteger(value)) {
|
|
247
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u6570\u5B57\u8D85\u51FA\u5B89\u5168\u6574\u6570\u8303\u56F4\uFF1A${JSON.stringify(raw)}\uFF08${context}\uFF09`);
|
|
248
|
+
}
|
|
249
|
+
return value;
|
|
250
|
+
}
|
|
251
|
+
function parseSegment(raw, context) {
|
|
252
|
+
const steps = [];
|
|
253
|
+
let offset;
|
|
254
|
+
let assertion;
|
|
255
|
+
let index = 0;
|
|
256
|
+
while (index < raw.length) {
|
|
257
|
+
const char = raw[index];
|
|
258
|
+
if (char === "/") {
|
|
259
|
+
if (offset !== void 0) {
|
|
260
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u5B57\u7B26\u504F\u79FB\u4E4B\u540E\u4E0D\u5141\u8BB8\u518D\u51FA\u73B0\u6B65\u9AA4\uFF08${context}\uFF09`);
|
|
261
|
+
}
|
|
262
|
+
index += 1;
|
|
263
|
+
const digitsStart = index;
|
|
264
|
+
while (isDigit(raw[index])) index += 1;
|
|
265
|
+
if (index === digitsStart) {
|
|
266
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u6B65\u9AA4\u7F3A\u5C11\u7D22\u5F15\u6570\u5B57\uFF08${context}\uFF09`);
|
|
267
|
+
}
|
|
268
|
+
const stepIndex = parseInteger(raw.slice(digitsStart, index), context);
|
|
269
|
+
const scanned = tryReadAssertion(raw, index, context);
|
|
270
|
+
let step = { index: stepIndex };
|
|
271
|
+
if (scanned !== null) {
|
|
272
|
+
index = scanned.next;
|
|
273
|
+
const parsed = parseAssertion(scanned.content, context);
|
|
274
|
+
if (parsed.trailing !== void 0) {
|
|
275
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u6B65\u9AA4\u4E0A\u7684\u65AD\u8A00\u4E0D\u63A5\u53D7\u9017\u53F7\u5206\u9694\u7684\u7B2C\u4E8C\u4E2A\u503C\uFF08${context}\uFF09`);
|
|
276
|
+
}
|
|
277
|
+
step = {
|
|
278
|
+
index: stepIndex,
|
|
279
|
+
...parsed.leading !== void 0 ? { id: parsed.leading } : {},
|
|
280
|
+
...parsed.side !== void 0 ? { side: parsed.side } : {}
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
steps.push(step);
|
|
284
|
+
continue;
|
|
285
|
+
}
|
|
286
|
+
if (char === ":") {
|
|
287
|
+
if (offset !== void 0) {
|
|
288
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8DEF\u5F84\u4E2D\u51FA\u73B0\u91CD\u590D\u7684\u5B57\u7B26\u504F\u79FB\uFF08${context}\uFF09`);
|
|
289
|
+
}
|
|
290
|
+
index += 1;
|
|
291
|
+
const digitsStart = index;
|
|
292
|
+
while (isDigit(raw[index])) index += 1;
|
|
293
|
+
if (index === digitsStart) {
|
|
294
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u5B57\u7B26\u504F\u79FB\u7F3A\u5C11\u6570\u5B57\uFF08${context}\uFF09`);
|
|
295
|
+
}
|
|
296
|
+
offset = parseInteger(raw.slice(digitsStart, index), context);
|
|
297
|
+
const scanned = tryReadAssertion(raw, index, context);
|
|
298
|
+
if (scanned !== null) {
|
|
299
|
+
index = scanned.next;
|
|
300
|
+
assertion = parseAssertion(scanned.content, context);
|
|
301
|
+
}
|
|
302
|
+
continue;
|
|
303
|
+
}
|
|
304
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8DEF\u5F84\u4E2D\u51FA\u73B0\u65E0\u6CD5\u8BC6\u522B\u7684\u5B57\u7B26 ${JSON.stringify(char)}\uFF08${context}\uFF09`);
|
|
305
|
+
}
|
|
306
|
+
if (steps.length === 0) {
|
|
307
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8DEF\u5F84\u6BB5\u7F3A\u5C11\u6B65\u9AA4\uFF08${context}\uFF09`);
|
|
308
|
+
}
|
|
309
|
+
return {
|
|
310
|
+
paths: [{ steps }],
|
|
311
|
+
...offset !== void 0 ? { offset } : {},
|
|
312
|
+
...assertion !== void 0 ? { assertion } : {}
|
|
313
|
+
};
|
|
314
|
+
}
|
|
315
|
+
function parsePath(raw, context) {
|
|
316
|
+
if (raw === "") {
|
|
317
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8DEF\u5F84\u4E3A\u7A7A\uFF08${context}\uFF09`);
|
|
318
|
+
}
|
|
319
|
+
const segments = splitTopLevel(raw, "!", context);
|
|
320
|
+
const paths = [];
|
|
321
|
+
let offset;
|
|
322
|
+
let assertion;
|
|
323
|
+
segments.forEach((segment, segmentIndex) => {
|
|
324
|
+
const isLast = segmentIndex === segments.length - 1;
|
|
325
|
+
if (segment === "") {
|
|
326
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`'!' \u4E4B\u540E\u7F3A\u5C11\u8DEF\u5F84\u6BB5\uFF08${context}\uFF09`);
|
|
327
|
+
}
|
|
328
|
+
if (!segment.startsWith("/")) {
|
|
329
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8DEF\u5F84\u6BB5\u5FC5\u987B\u4EE5 '/' \u5F00\u5934\uFF1A${JSON.stringify(segment)}\uFF08${context}\uFF09`);
|
|
330
|
+
}
|
|
331
|
+
const parsed = parseSegment(segment, context);
|
|
332
|
+
if (isLast) {
|
|
333
|
+
offset = parsed.offset;
|
|
334
|
+
assertion = parsed.assertion;
|
|
335
|
+
} else if (parsed.offset !== void 0) {
|
|
336
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u975E\u672B\u6BB5\u4E0D\u5141\u8BB8\u51FA\u73B0\u5B57\u7B26\u504F\u79FB\uFF08${context}\uFF09`);
|
|
337
|
+
}
|
|
338
|
+
for (const path of parsed.paths) paths.push(path);
|
|
339
|
+
});
|
|
340
|
+
return {
|
|
341
|
+
paths,
|
|
342
|
+
...offset !== void 0 ? { offset } : {},
|
|
343
|
+
...assertion !== void 0 ? { assertion } : {}
|
|
344
|
+
};
|
|
345
|
+
}
|
|
346
|
+
function toPoint(parsed) {
|
|
347
|
+
const draft = {
|
|
348
|
+
kind: "point",
|
|
349
|
+
paths: parsed.paths,
|
|
350
|
+
...parsed.offset !== void 0 ? { offset: parsed.offset } : {},
|
|
351
|
+
...parsed.assertion?.leading !== void 0 ? { text: parsed.assertion.leading } : {},
|
|
352
|
+
...parsed.assertion?.trailing !== void 0 ? { textAfter: parsed.assertion.trailing } : {},
|
|
353
|
+
...parsed.assertion?.side !== void 0 ? { side: parsed.assertion.side } : {},
|
|
354
|
+
value: ""
|
|
355
|
+
};
|
|
356
|
+
return { ...draft, value: serializePoint(draft) };
|
|
357
|
+
}
|
|
358
|
+
function concatPath(parent, child, context) {
|
|
359
|
+
if (parent.offset !== void 0) {
|
|
360
|
+
throw new chunkG7DLWGBW_cjs.FormatError(`\u8303\u56F4\u7236\u8DEF\u5F84\u4E0D\u5141\u8BB8\u5E26\u5B57\u7B26\u504F\u79FB\uFF08${context}\uFF09`);
|
|
361
|
+
}
|
|
362
|
+
const lastIndex = parent.paths.length - 1;
|
|
363
|
+
const lastPath = parent.paths[lastIndex];
|
|
364
|
+
const childFirst = child.paths[0];
|
|
365
|
+
if (lastPath === void 0 || childFirst === void 0) {
|
|
366
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8303\u56F4\u8DEF\u5F84\u4E3A\u7A7A\uFF08${context}\uFF09`);
|
|
367
|
+
}
|
|
368
|
+
const merged = { steps: [...lastPath.steps, ...childFirst.steps] };
|
|
369
|
+
return {
|
|
370
|
+
paths: [...parent.paths.slice(0, lastIndex), merged, ...child.paths.slice(1)],
|
|
371
|
+
...child.offset !== void 0 ? { offset: child.offset } : {},
|
|
372
|
+
...child.assertion !== void 0 ? { assertion: child.assertion } : {}
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
function freezeCfi(cfi) {
|
|
376
|
+
const freezePaths = (paths) => {
|
|
377
|
+
for (const path of paths) {
|
|
378
|
+
for (const step of path.steps) Object.freeze(step);
|
|
379
|
+
Object.freeze(path.steps);
|
|
380
|
+
Object.freeze(path);
|
|
381
|
+
}
|
|
382
|
+
Object.freeze(paths);
|
|
383
|
+
};
|
|
384
|
+
if (cfi.kind === "point") {
|
|
385
|
+
freezePaths(cfi.paths);
|
|
386
|
+
} else {
|
|
387
|
+
freezeCfi(cfi.start);
|
|
388
|
+
freezeCfi(cfi.end);
|
|
389
|
+
if (cfi.parent !== null) freezePaths(cfi.parent);
|
|
390
|
+
}
|
|
391
|
+
return Object.freeze(cfi);
|
|
392
|
+
}
|
|
393
|
+
function stripWrapper(input, context) {
|
|
394
|
+
if (input.startsWith("epubcfi(")) {
|
|
395
|
+
if (!input.endsWith(")")) {
|
|
396
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u7F3A\u5C11\u7ED3\u5C3E\u7684 ')'\uFF08${context}\uFF09`);
|
|
397
|
+
}
|
|
398
|
+
return input.slice("epubcfi(".length, -1);
|
|
399
|
+
}
|
|
400
|
+
if (input.endsWith(")") && input.includes("(")) {
|
|
401
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`CFI \u524D\u7F00\u975E\u6CD5\uFF08\u5E94\u4E3A 'epubcfi('\uFF09\uFF1A${JSON.stringify(input)}\uFF08${context}\uFF09`);
|
|
402
|
+
}
|
|
403
|
+
return input;
|
|
404
|
+
}
|
|
405
|
+
function parseCfi(input) {
|
|
406
|
+
const context = `CFI ${JSON.stringify(input)}`;
|
|
407
|
+
const inner = stripWrapper(input, context);
|
|
408
|
+
if (inner === "") {
|
|
409
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`CFI \u5185\u5BB9\u4E3A\u7A7A\uFF08${context}\uFF09`);
|
|
410
|
+
}
|
|
411
|
+
const parts = splitTopLevel(inner, ",", context);
|
|
412
|
+
if (parts.length === 1) {
|
|
413
|
+
return freezeCfi(toPoint(parsePath(parts[0], context)));
|
|
414
|
+
}
|
|
415
|
+
if (parts.length === 2) {
|
|
416
|
+
const [startRaw, endRaw] = parts;
|
|
417
|
+
const draft = {
|
|
418
|
+
kind: "range",
|
|
419
|
+
start: toPoint(parsePath(startRaw, context)),
|
|
420
|
+
end: toPoint(parsePath(endRaw, context)),
|
|
421
|
+
parent: null,
|
|
422
|
+
value: ""
|
|
423
|
+
};
|
|
424
|
+
return freezeCfi({ ...draft, value: serializeCfi(draft) });
|
|
425
|
+
}
|
|
426
|
+
if (parts.length === 3) {
|
|
427
|
+
const [parentRaw, startRaw, endRaw] = parts;
|
|
428
|
+
const parent = parsePath(parentRaw, context);
|
|
429
|
+
const startParsed = startRaw === "" ? parent : concatPath(parent, parsePath(startRaw, context), context);
|
|
430
|
+
const endParsed = endRaw === "" ? parent : concatPath(parent, parsePath(endRaw, context), context);
|
|
431
|
+
const draft = {
|
|
432
|
+
kind: "range",
|
|
433
|
+
start: toPoint(startParsed),
|
|
434
|
+
end: toPoint(endParsed),
|
|
435
|
+
parent: parent.paths,
|
|
436
|
+
value: ""
|
|
437
|
+
};
|
|
438
|
+
return freezeCfi({ ...draft, value: serializeCfi(draft) });
|
|
439
|
+
}
|
|
440
|
+
throw new chunkG7DLWGBW_cjs.ParseError(`\u8303\u56F4\u6700\u591A\u63A5\u53D7 3 \u4E2A\u9017\u53F7\u5206\u9694\u7684\u90E8\u5206\uFF0C\u5B9E\u9645 ${parts.length} \u4E2A\uFF08${context}\uFF09`);
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
// src/core/cfi/guards.ts
|
|
444
|
+
function isRecord(value) {
|
|
445
|
+
return typeof value === "object" && value !== null;
|
|
446
|
+
}
|
|
447
|
+
function isPathsLike(value) {
|
|
448
|
+
return Array.isArray(value) && value.every((path) => isRecord(path) && Array.isArray(path["steps"]));
|
|
449
|
+
}
|
|
450
|
+
function isPointLike(value) {
|
|
451
|
+
if (!isRecord(value)) return false;
|
|
452
|
+
return value["kind"] === "point" && isPathsLike(value["paths"]) && typeof value["value"] === "string";
|
|
453
|
+
}
|
|
454
|
+
function isRangeLike(value) {
|
|
455
|
+
if (!isRecord(value)) return false;
|
|
456
|
+
const parent = value["parent"];
|
|
457
|
+
return value["kind"] === "range" && isPointLike(value["start"]) && isPointLike(value["end"]) && (parent === null || isPathsLike(parent)) && typeof value["value"] === "string";
|
|
458
|
+
}
|
|
459
|
+
function isCfi(value) {
|
|
460
|
+
return isPointLike(value) || isRangeLike(value);
|
|
461
|
+
}
|
|
462
|
+
function isCfiString(value) {
|
|
463
|
+
if (typeof value !== "string") return false;
|
|
464
|
+
const trimmed = value.trim();
|
|
465
|
+
if (trimmed === "") return false;
|
|
466
|
+
if (!(trimmed.startsWith("epubcfi(") || trimmed.startsWith("/"))) return false;
|
|
467
|
+
try {
|
|
468
|
+
parseCfi(trimmed);
|
|
469
|
+
return true;
|
|
470
|
+
} catch {
|
|
471
|
+
return false;
|
|
472
|
+
}
|
|
473
|
+
}
|
|
474
|
+
|
|
475
|
+
exports.collapseCfi = collapseCfi;
|
|
476
|
+
exports.isCfi = isCfi;
|
|
477
|
+
exports.isCfiString = isCfiString;
|
|
478
|
+
exports.parseCfi = parseCfi;
|
|
479
|
+
exports.serializeCfi = serializeCfi;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunkG7DLWGBW_cjs = require('./chunk-G7DLWGBW.cjs');
|
|
4
|
+
|
|
5
|
+
// src/core/archive-path.ts
|
|
6
|
+
var DEFAULT_LABEL = "\u5F52\u6863\u8DEF\u5F84";
|
|
7
|
+
var UNKNOWN_SOURCE = "<unknown>";
|
|
8
|
+
function formatError(suffix, options) {
|
|
9
|
+
const label = options.label ?? DEFAULT_LABEL;
|
|
10
|
+
const source = options.source ?? UNKNOWN_SOURCE;
|
|
11
|
+
return new chunkG7DLWGBW_cjs.FormatError(`${label}${suffix}\uFF08\u6E90: ${source}\uFF09`);
|
|
12
|
+
}
|
|
13
|
+
function hasControlCharacter(value) {
|
|
14
|
+
for (let index = 0; index < value.length; index += 1) {
|
|
15
|
+
const code = value.charCodeAt(index);
|
|
16
|
+
if (code <= 31 || code === 127) return true;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
20
|
+
function namesNoEntry(value) {
|
|
21
|
+
for (const segment of value.replace(/\\/g, "/").split("/")) {
|
|
22
|
+
if (segment !== "" && segment !== "." && segment !== "..") return false;
|
|
23
|
+
}
|
|
24
|
+
return true;
|
|
25
|
+
}
|
|
26
|
+
var SCHEME_PATTERN = /^[a-zA-Z][a-zA-Z0-9+.-]*:/;
|
|
27
|
+
function classifyReference(rawValue) {
|
|
28
|
+
const value = rawValue.trim();
|
|
29
|
+
if (value === "") return "empty";
|
|
30
|
+
if (value.startsWith("#")) return "fragment";
|
|
31
|
+
if (value.startsWith("//")) return "protocol-relative";
|
|
32
|
+
if (SCHEME_PATTERN.test(value)) return "absolute";
|
|
33
|
+
return "archive";
|
|
34
|
+
}
|
|
35
|
+
function normalizeArchivePath(rawPath, options = {}) {
|
|
36
|
+
if (rawPath === "") {
|
|
37
|
+
throw formatError(" \u4E3A\u7A7A", options);
|
|
38
|
+
}
|
|
39
|
+
if (hasControlCharacter(rawPath)) {
|
|
40
|
+
throw formatError(" \u542B\u63A7\u5236\u5B57\u7B26", options);
|
|
41
|
+
}
|
|
42
|
+
const segments = [];
|
|
43
|
+
for (const segment of rawPath.replace(/\\/g, "/").split("/")) {
|
|
44
|
+
if (segment === "" || segment === ".") continue;
|
|
45
|
+
if (segment === "..") {
|
|
46
|
+
if (segments.length === 0) {
|
|
47
|
+
throw formatError(` \u8D8A\u51FA\u5F52\u6863\u6839\u76EE\u5F55\uFF1A"${rawPath}"`, options);
|
|
48
|
+
}
|
|
49
|
+
segments.pop();
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
segments.push(segment);
|
|
53
|
+
}
|
|
54
|
+
if (segments.length === 0) {
|
|
55
|
+
throw formatError(` \u89C4\u8303\u5316\u540E\u4E3A\u7A7A\uFF1A"${rawPath}"`, options);
|
|
56
|
+
}
|
|
57
|
+
return segments.join("/");
|
|
58
|
+
}
|
|
59
|
+
function resolveArchivePath(basePath, href, options = {}) {
|
|
60
|
+
if (namesNoEntry(href)) {
|
|
61
|
+
throw formatError(` \u672A\u6307\u5411\u4EFB\u4F55\u6761\u76EE\uFF1A"${href}"`, options);
|
|
62
|
+
}
|
|
63
|
+
const kind = classifyReference(href);
|
|
64
|
+
if (kind !== "archive") {
|
|
65
|
+
throw formatError(
|
|
66
|
+
` \u4E0D\u662F\u76F8\u5BF9\u5F15\u7528\uFF1A"${href.trim()}"\uFF08\u5E26 scheme\u3001\u534F\u8BAE\u76F8\u5BF9 // \u6216\u7EAF fragment \u90FD\u4E0D\u6307\u5411\u5F52\u6863\u5185\u7684\u6761\u76EE\uFF09`,
|
|
67
|
+
options
|
|
68
|
+
);
|
|
69
|
+
}
|
|
70
|
+
if (href.startsWith("/")) {
|
|
71
|
+
return normalizeArchivePath(href, options);
|
|
72
|
+
}
|
|
73
|
+
return normalizeArchivePath(basePath === "" ? href : `${basePath}/${href}`, options);
|
|
74
|
+
}
|
|
75
|
+
function directoryOf(archivePath) {
|
|
76
|
+
const index = archivePath.lastIndexOf("/");
|
|
77
|
+
return index === -1 ? "" : archivePath.slice(0, index);
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
exports.classifyReference = classifyReference;
|
|
81
|
+
exports.directoryOf = directoryOf;
|
|
82
|
+
exports.normalizeArchivePath = normalizeArchivePath;
|
|
83
|
+
exports.resolveArchivePath = resolveArchivePath;
|
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
// src/core/formats/probe.ts
|
|
2
|
+
var PROBE_PREFIX_BYTES = 1024;
|
|
3
|
+
var PDF_MAGIC = "%PDF-";
|
|
4
|
+
var ZIP_MAGIC = [80, 75, 3, 4];
|
|
5
|
+
var MOBI_MARKER = "BOOKMOBI";
|
|
6
|
+
var MOBI_MARKER_OFFSET = 60;
|
|
7
|
+
var XML_DECLARATION = "<?xml";
|
|
8
|
+
var FB2_ROOT = "<FictionBook";
|
|
9
|
+
var UTF8_BOM = [239, 187, 191];
|
|
10
|
+
var EPUB_CONTAINER_ENTRY = "META-INF/container.xml";
|
|
11
|
+
var FB2_EXTENSION = ".fb2";
|
|
12
|
+
var IMAGE_EXTENSIONS = [".jpg", ".jpeg", ".png", ".gif", ".webp", ".avif"];
|
|
13
|
+
function probeFormat(prefix) {
|
|
14
|
+
if (matchesAscii(prefix, 0, PDF_MAGIC)) {
|
|
15
|
+
return { kind: "format", format: "pdf", evidence: `%PDF- \u9B54\u6570\uFF08offset 0\uFF09` };
|
|
16
|
+
}
|
|
17
|
+
if (matchesBytes(prefix, 0, ZIP_MAGIC)) {
|
|
18
|
+
return {
|
|
19
|
+
kind: "container",
|
|
20
|
+
container: "zip",
|
|
21
|
+
evidence: "PK\\x03\\x04 \u9B54\u6570\uFF08offset 0\uFF09\u2014\u2014 ZIP \u5BB9\u5668\uFF0C\u9700\u8BFB\u6761\u76EE\u540D\u624D\u80FD\u5B9A\u683C\u5F0F"
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (matchesAscii(prefix, MOBI_MARKER_OFFSET, MOBI_MARKER)) {
|
|
25
|
+
return {
|
|
26
|
+
kind: "format",
|
|
27
|
+
format: "mobi",
|
|
28
|
+
evidence: `BOOKMOBI \u6807\u8BB0\uFF08offset ${String(MOBI_MARKER_OFFSET)}\uFF0CPalmDB \u5934\uFF09`
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
if (looksLikeFb2(prefix)) {
|
|
32
|
+
return {
|
|
33
|
+
kind: "format",
|
|
34
|
+
format: "fb2",
|
|
35
|
+
evidence: "XML \u58F0\u660E\u6216 <FictionBook> \u6839\u5143\u7D20 + \u542B <FictionBook>"
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
return null;
|
|
39
|
+
}
|
|
40
|
+
function probeZipContainer(names) {
|
|
41
|
+
const entries = names.filter((name) => !name.endsWith("/"));
|
|
42
|
+
if (entries.includes(EPUB_CONTAINER_ENTRY)) {
|
|
43
|
+
return {
|
|
44
|
+
kind: "format",
|
|
45
|
+
format: "epub",
|
|
46
|
+
evidence: `ZIP \u5185\u542B ${EPUB_CONTAINER_ENTRY}\uFF08OCF \u89C4\u8303\u56FA\u5B9A\u4F4D\u7F6E\uFF09`
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
if (entries.some((name) => name.toLowerCase().endsWith(FB2_EXTENSION))) {
|
|
50
|
+
return {
|
|
51
|
+
kind: "format",
|
|
52
|
+
format: "fb2",
|
|
53
|
+
evidence: `ZIP \u5185\u542B ${FB2_EXTENSION} \u4E14\u65E0 ${EPUB_CONTAINER_ENTRY}\uFF08.fb2.zip \u53D8\u4F53\uFF09`
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
if (entries.some(
|
|
57
|
+
(name) => IMAGE_EXTENSIONS.some((extension) => name.toLowerCase().endsWith(extension))
|
|
58
|
+
)) {
|
|
59
|
+
return {
|
|
60
|
+
kind: "format",
|
|
61
|
+
format: "cbz",
|
|
62
|
+
evidence: `ZIP \u5185\u53EA\u6709\u56FE\u7247\u6761\u76EE\u4E14\u65E0 ${EPUB_CONTAINER_ENTRY}\uFF08CBZ\uFF09`
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
function matchesAscii(bytes, offset, text) {
|
|
68
|
+
if (offset < 0 || offset + text.length > bytes.byteLength) return false;
|
|
69
|
+
for (let i = 0; i < text.length; i++) {
|
|
70
|
+
if (bytes[offset + i] !== text.charCodeAt(i)) return false;
|
|
71
|
+
}
|
|
72
|
+
return true;
|
|
73
|
+
}
|
|
74
|
+
function matchesBytes(bytes, offset, expected) {
|
|
75
|
+
if (offset + expected.length > bytes.byteLength) return false;
|
|
76
|
+
for (let i = 0; i < expected.length; i++) {
|
|
77
|
+
if (bytes[offset + i] !== expected[i]) return false;
|
|
78
|
+
}
|
|
79
|
+
return true;
|
|
80
|
+
}
|
|
81
|
+
function indexOfAscii(bytes, text) {
|
|
82
|
+
const limit = bytes.byteLength - text.length;
|
|
83
|
+
for (let start = 0; start <= limit; start++) {
|
|
84
|
+
if (matchesAscii(bytes, start, text)) return start;
|
|
85
|
+
}
|
|
86
|
+
return -1;
|
|
87
|
+
}
|
|
88
|
+
function looksLikeFb2(prefix) {
|
|
89
|
+
if (indexOfAscii(prefix, FB2_ROOT) === -1) return false;
|
|
90
|
+
let start = matchesBytes(prefix, 0, UTF8_BOM) ? UTF8_BOM.length : 0;
|
|
91
|
+
for (; ; ) {
|
|
92
|
+
const byte = prefix[start];
|
|
93
|
+
if (byte === void 0 || !isAsciiWhitespace(byte)) break;
|
|
94
|
+
start++;
|
|
95
|
+
}
|
|
96
|
+
return matchesAscii(prefix, start, XML_DECLARATION) || matchesAscii(prefix, start, FB2_ROOT);
|
|
97
|
+
}
|
|
98
|
+
function isAsciiWhitespace(byte) {
|
|
99
|
+
return byte === 32 || byte === 9 || byte === 13 || byte === 10 || byte === 12 || byte === 11;
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
export { EPUB_CONTAINER_ENTRY, IMAGE_EXTENSIONS, PROBE_PREFIX_BYTES, probeFormat, probeZipContainer };
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { FormatError } from './chunk-B2L2YVXD.js';
|
|
2
|
+
|
|
3
|
+
// src/core/formats/bytes.ts
|
|
4
|
+
function isBookBytes(value) {
|
|
5
|
+
return ArrayBuffer.isView(value);
|
|
6
|
+
}
|
|
7
|
+
async function resolveBookBytes(source, options = {}) {
|
|
8
|
+
if (isBookBytes(source)) return source;
|
|
9
|
+
const label = options.source ?? "<anonymous>";
|
|
10
|
+
const { size } = source;
|
|
11
|
+
if (size === null) {
|
|
12
|
+
throw new FormatError(
|
|
13
|
+
`\u65E0\u6CD5\u6253\u5F00\u4E66\u7C4D\uFF1A\u5B57\u8282\u6E90\u672A\u63D0\u4F9B\u603B\u957F\uFF08size \u4E3A null\uFF09\uFF0C\u4E00\u6B21\u6027\u8BFB\u53D6\u9700\u8981\u5DF2\u77E5\u957F\u5EA6\uFF08\u6E90: ${label}\uFF09`
|
|
14
|
+
);
|
|
15
|
+
}
|
|
16
|
+
if (!Number.isInteger(size) || size < 0) {
|
|
17
|
+
throw new FormatError(
|
|
18
|
+
`\u65E0\u6CD5\u6253\u5F00\u4E66\u7C4D\uFF1A\u5B57\u8282\u6E90\u62A5\u544A\u7684\u603B\u957F\u975E\u6CD5\uFF08size = ${String(size)}\uFF09\uFF08\u6E90: ${label}\uFF09`
|
|
19
|
+
);
|
|
20
|
+
}
|
|
21
|
+
const bytes = await source.read({ start: 0, end: size }, options);
|
|
22
|
+
if (bytes.byteLength !== size) {
|
|
23
|
+
throw new FormatError(
|
|
24
|
+
`\u65E0\u6CD5\u6253\u5F00\u4E66\u7C4D\uFF1A\u5B57\u8282\u6E90\u8FD4\u56DE ${String(bytes.byteLength)} \u5B57\u8282\uFF0C\u4E0E\u62A5\u544A\u7684\u603B\u957F ${String(size)} \u4E0D\u7B26\uFF08\u6E90: ${label}\uFF09`
|
|
25
|
+
);
|
|
26
|
+
}
|
|
27
|
+
return bytes;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
export { resolveBookBytes };
|