@storyteller-platform/align 0.1.27 → 0.1.29
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/align/align.cjs +217 -78
- package/dist/align/align.d.cts +1 -0
- package/dist/align/align.d.ts +1 -0
- package/dist/align/align.js +231 -81
- package/dist/align/getSentenceRanges.cjs +4 -1
- package/dist/align/getSentenceRanges.js +4 -1
- package/dist/align/parse.cjs +14 -3
- package/dist/align/parse.d.cts +3 -0
- package/dist/align/parse.d.ts +3 -0
- package/dist/align/parse.js +14 -3
- package/dist/align/textFragments.cjs +60 -99
- package/dist/align/textFragments.d.cts +5 -18
- package/dist/align/textFragments.d.ts +5 -18
- package/dist/align/textFragments.js +60 -99
- package/dist/cli/bin.cjs +2 -0
- package/dist/cli/bin.js +2 -0
- package/dist/errorAlign/graphMetadata.cjs +2 -2
- package/dist/errorAlign/graphMetadata.js +1 -1
- package/dist/markup/parseDom.cjs +1 -1
- package/dist/markup/parseDom.js +1 -1
- package/dist/readium/guidedNavigation.cjs +234 -0
- package/dist/readium/guidedNavigation.d.cts +7 -0
- package/dist/readium/guidedNavigation.d.ts +7 -0
- package/dist/readium/guidedNavigation.js +210 -0
- package/dist/readium/manifest.cjs +260 -0
- package/dist/readium/manifest.d.cts +6 -0
- package/dist/readium/manifest.d.ts +6 -0
- package/dist/readium/manifest.js +242 -0
- package/dist/snapshot/snapshot.cjs +13 -1
- package/dist/snapshot/snapshot.js +16 -2
- package/dist/types/smil-clockvalue.d.cjs +1 -0
- package/dist/types/smil-clockvalue.d.d.cts +3 -0
- package/dist/types/smil-clockvalue.d.d.ts +3 -0
- package/dist/types/smil-clockvalue.d.js +0 -0
- package/package.json +7 -2
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __export = (target, all) => {
|
|
9
|
+
for (var name in all)
|
|
10
|
+
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
+
};
|
|
12
|
+
var __copyProps = (to, from, except, desc) => {
|
|
13
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
14
|
+
for (let key of __getOwnPropNames(from))
|
|
15
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
16
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
17
|
+
}
|
|
18
|
+
return to;
|
|
19
|
+
};
|
|
20
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
21
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
22
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
23
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
24
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
25
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
26
|
+
mod
|
|
27
|
+
));
|
|
28
|
+
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
29
|
+
var guidedNavigation_exports = {};
|
|
30
|
+
__export(guidedNavigation_exports, {
|
|
31
|
+
generateGuidedNavigationDocuments: () => generateGuidedNavigationDocuments,
|
|
32
|
+
generateGuidedNavigationManifest: () => generateGuidedNavigationManifest
|
|
33
|
+
});
|
|
34
|
+
module.exports = __toCommonJS(guidedNavigation_exports);
|
|
35
|
+
var import_shared = require("@readium/shared");
|
|
36
|
+
var import_change_case = require("change-case");
|
|
37
|
+
var import_itertools = require("itertools");
|
|
38
|
+
var import_smil_clockvalue = __toESM(require("smil-clockvalue"), 1);
|
|
39
|
+
var import_audiobook = require("@storyteller-platform/audiobook");
|
|
40
|
+
var import_epub = require("@storyteller-platform/epub");
|
|
41
|
+
function generateGuidedNavigationManifest(title, guidedNavDocs) {
|
|
42
|
+
const readingOrder = [];
|
|
43
|
+
for (const doc of guidedNavDocs) {
|
|
44
|
+
const href = doc.links?.findWithRel("self")?.href;
|
|
45
|
+
if (!href) continue;
|
|
46
|
+
const textref = doc.guided?.[0]?.textref;
|
|
47
|
+
if (!textref) continue;
|
|
48
|
+
const referencedAudioFiles = {};
|
|
49
|
+
const pars = flatten(doc.guided ?? []);
|
|
50
|
+
for (const par of pars) {
|
|
51
|
+
if (!par.audioFile) continue;
|
|
52
|
+
const range = par.audioTime;
|
|
53
|
+
if (!range) continue;
|
|
54
|
+
const [startString, endString] = range.slice(2).split(",");
|
|
55
|
+
const start = parseFloat(startString ?? "0");
|
|
56
|
+
const end = endString ? parseFloat(endString) : null;
|
|
57
|
+
const existing = referencedAudioFiles[par.audioFile];
|
|
58
|
+
if (!existing) {
|
|
59
|
+
referencedAudioFiles[par.audioFile] = {
|
|
60
|
+
start,
|
|
61
|
+
end
|
|
62
|
+
};
|
|
63
|
+
continue;
|
|
64
|
+
}
|
|
65
|
+
existing.end = end;
|
|
66
|
+
}
|
|
67
|
+
const audioReferences = Object.entries(referencedAudioFiles).map(
|
|
68
|
+
([audioFile, { start, end }]) => ({
|
|
69
|
+
href: `${audioFile}#t=${start},${end}`,
|
|
70
|
+
type: (0, import_audiobook.lookupAudioMime)(audioFile)
|
|
71
|
+
})
|
|
72
|
+
);
|
|
73
|
+
readingOrder.push(
|
|
74
|
+
new import_shared.Link({
|
|
75
|
+
href,
|
|
76
|
+
properties: new import_shared.Properties({
|
|
77
|
+
references: [
|
|
78
|
+
{
|
|
79
|
+
href: textref,
|
|
80
|
+
type: "application/xhtml+xml"
|
|
81
|
+
},
|
|
82
|
+
...audioReferences
|
|
83
|
+
]
|
|
84
|
+
})
|
|
85
|
+
})
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
return new import_shared.Manifest({
|
|
89
|
+
metadata: new import_shared.Metadata({
|
|
90
|
+
title,
|
|
91
|
+
conformsTo: [
|
|
92
|
+
"https://readium.org/webpub-manifest/profiles/guided-navigation"
|
|
93
|
+
]
|
|
94
|
+
}),
|
|
95
|
+
links: new import_shared.Links([
|
|
96
|
+
new import_shared.Link({
|
|
97
|
+
href: "manifest.json",
|
|
98
|
+
type: "application/webpub+json",
|
|
99
|
+
rels: /* @__PURE__ */ new Set(["self"])
|
|
100
|
+
})
|
|
101
|
+
]),
|
|
102
|
+
readingOrder: new import_shared.Links(readingOrder)
|
|
103
|
+
});
|
|
104
|
+
}
|
|
105
|
+
async function generateGuidedNavigationDocuments(epub) {
|
|
106
|
+
const manifest = await epub.getManifest();
|
|
107
|
+
const spine = await epub.getSpineItems();
|
|
108
|
+
const mediaOverlays = [];
|
|
109
|
+
for (const item of spine) {
|
|
110
|
+
if (!item.mediaOverlay) continue;
|
|
111
|
+
const mediaOverlayItem = manifest[item.mediaOverlay];
|
|
112
|
+
if (!mediaOverlayItem) continue;
|
|
113
|
+
mediaOverlays.push(mediaOverlayItem);
|
|
114
|
+
}
|
|
115
|
+
const guidedNavDocs = [];
|
|
116
|
+
for (const [i, overlay] of (0, import_itertools.enumerate)(mediaOverlays)) {
|
|
117
|
+
const contents = await epub.readItemContents(overlay.id, "utf-8");
|
|
118
|
+
const xml = import_epub.Epub.xmlParser.parse(contents);
|
|
119
|
+
const body = import_epub.Epub.findXmlDescendantByName("body", xml);
|
|
120
|
+
if (!body) continue;
|
|
121
|
+
const links = [];
|
|
122
|
+
const prevOverlay = mediaOverlays[i - 1];
|
|
123
|
+
if (prevOverlay) {
|
|
124
|
+
links.push(
|
|
125
|
+
new import_shared.Link({
|
|
126
|
+
rels: /* @__PURE__ */ new Set(["prev"]),
|
|
127
|
+
href: `GND/${prevOverlay.id}.json`,
|
|
128
|
+
type: "application/guided-navigation+json"
|
|
129
|
+
})
|
|
130
|
+
);
|
|
131
|
+
}
|
|
132
|
+
links.push(
|
|
133
|
+
new import_shared.Link({
|
|
134
|
+
rels: /* @__PURE__ */ new Set(["self"]),
|
|
135
|
+
href: `GND/${overlay.id}.json`,
|
|
136
|
+
type: "application/guided-navigation+json"
|
|
137
|
+
})
|
|
138
|
+
);
|
|
139
|
+
const nextOverlay = mediaOverlays[i + 1];
|
|
140
|
+
if (nextOverlay) {
|
|
141
|
+
links.push(
|
|
142
|
+
new import_shared.Link({
|
|
143
|
+
rels: /* @__PURE__ */ new Set(["next"]),
|
|
144
|
+
href: `GND/${nextOverlay.id}.json`,
|
|
145
|
+
type: "application/guided-navigation+json"
|
|
146
|
+
})
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
const guidedNavDoc = new import_shared.GuidedNavigationDocument({
|
|
150
|
+
links: new import_shared.Links(links),
|
|
151
|
+
guided: await parseGuidedNavigationObjects(
|
|
152
|
+
epub,
|
|
153
|
+
overlay.href,
|
|
154
|
+
import_epub.Epub.getXmlChildren(body)
|
|
155
|
+
)
|
|
156
|
+
});
|
|
157
|
+
guidedNavDocs.push(guidedNavDoc);
|
|
158
|
+
}
|
|
159
|
+
return guidedNavDocs;
|
|
160
|
+
}
|
|
161
|
+
async function parseGuidedNavigationObjects(epub, overlayHref, xml) {
|
|
162
|
+
const guidedNavObjects = [];
|
|
163
|
+
const children = xml.filter(
|
|
164
|
+
(node) => !import_epub.Epub.isXmlTextNode(node) && ["seq", "par"].includes(import_epub.Epub.getXmlElementName(node))
|
|
165
|
+
);
|
|
166
|
+
for (const element of children) {
|
|
167
|
+
if (import_epub.Epub.getXmlElementName(element) === "par") {
|
|
168
|
+
const text = import_epub.Epub.findXmlChildByName("text", import_epub.Epub.getXmlChildren(element));
|
|
169
|
+
const audio = import_epub.Epub.findXmlChildByName(
|
|
170
|
+
"audio",
|
|
171
|
+
import_epub.Epub.getXmlChildren(element)
|
|
172
|
+
);
|
|
173
|
+
if (!text || !audio) continue;
|
|
174
|
+
const textSrc = import_epub.Epub.getXmlAttributes(text)["src"];
|
|
175
|
+
const { src: audioSrc, clipBegin, clipEnd } = import_epub.Epub.getXmlAttributes(audio);
|
|
176
|
+
if (!textSrc || !audioSrc || clipBegin === void 0 || clipEnd === void 0) {
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const textref = await epub.resolveHref(textSrc, overlayHref, {
|
|
180
|
+
toRoot: true
|
|
181
|
+
});
|
|
182
|
+
const audioref = await epub.resolveHref(audioSrc, overlayHref, {
|
|
183
|
+
toRoot: true
|
|
184
|
+
});
|
|
185
|
+
const clipBeginSeconds = (0, import_smil_clockvalue.default)(clipBegin) / 1e3;
|
|
186
|
+
const clipEndSeconds = (0, import_smil_clockvalue.default)(clipEnd) / 1e3;
|
|
187
|
+
guidedNavObjects.push(
|
|
188
|
+
new import_shared.GuidedNavigationObject({
|
|
189
|
+
// Slice off the leading slash
|
|
190
|
+
textref,
|
|
191
|
+
audioref: `${audioref}#t=${clipBeginSeconds},${clipEndSeconds}`
|
|
192
|
+
})
|
|
193
|
+
);
|
|
194
|
+
}
|
|
195
|
+
if (import_epub.Epub.getXmlElementName(element) === "seq") {
|
|
196
|
+
const attrs = import_epub.Epub.getXmlAttributes(element);
|
|
197
|
+
const epubType = attrs["epub:type"];
|
|
198
|
+
const role = epubType && (0, import_change_case.camelCase)(epubType);
|
|
199
|
+
const textref = attrs["epub:textref"];
|
|
200
|
+
if (!textref) continue;
|
|
201
|
+
const children2 = await parseGuidedNavigationObjects(
|
|
202
|
+
epub,
|
|
203
|
+
overlayHref,
|
|
204
|
+
import_epub.Epub.getXmlChildren(element)
|
|
205
|
+
);
|
|
206
|
+
guidedNavObjects.push(
|
|
207
|
+
new import_shared.GuidedNavigationObject({
|
|
208
|
+
textref: await epub.resolveHref(textref, overlayHref, {
|
|
209
|
+
toRoot: true
|
|
210
|
+
}),
|
|
211
|
+
...role && { role: /* @__PURE__ */ new Set([role]) },
|
|
212
|
+
children: children2
|
|
213
|
+
})
|
|
214
|
+
);
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
return guidedNavObjects;
|
|
218
|
+
}
|
|
219
|
+
function flatten(input) {
|
|
220
|
+
const pars = [];
|
|
221
|
+
for (const obj of input) {
|
|
222
|
+
if (obj.children) {
|
|
223
|
+
pars.push(...flatten(obj.children));
|
|
224
|
+
} else {
|
|
225
|
+
pars.push(obj);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
return pars;
|
|
229
|
+
}
|
|
230
|
+
// Annotate the CommonJS export names for ESM import in node:
|
|
231
|
+
0 && (module.exports = {
|
|
232
|
+
generateGuidedNavigationDocuments,
|
|
233
|
+
generateGuidedNavigationManifest
|
|
234
|
+
});
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LocalizedString, GuidedNavigationDocument, Manifest } from '@readium/shared';
|
|
2
|
+
import { Epub } from '@storyteller-platform/epub';
|
|
3
|
+
|
|
4
|
+
declare function generateGuidedNavigationManifest(title: LocalizedString, guidedNavDocs: GuidedNavigationDocument[]): Manifest;
|
|
5
|
+
declare function generateGuidedNavigationDocuments(epub: Epub): Promise<GuidedNavigationDocument[]>;
|
|
6
|
+
|
|
7
|
+
export { generateGuidedNavigationDocuments, generateGuidedNavigationManifest };
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { LocalizedString, GuidedNavigationDocument, Manifest } from '@readium/shared';
|
|
2
|
+
import { Epub } from '@storyteller-platform/epub';
|
|
3
|
+
|
|
4
|
+
declare function generateGuidedNavigationManifest(title: LocalizedString, guidedNavDocs: GuidedNavigationDocument[]): Manifest;
|
|
5
|
+
declare function generateGuidedNavigationDocuments(epub: Epub): Promise<GuidedNavigationDocument[]>;
|
|
6
|
+
|
|
7
|
+
export { generateGuidedNavigationDocuments, generateGuidedNavigationManifest };
|
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
import "../chunk-BIEQXUOY.js";
|
|
2
|
+
import {
|
|
3
|
+
GuidedNavigationDocument,
|
|
4
|
+
GuidedNavigationObject,
|
|
5
|
+
Link,
|
|
6
|
+
Links,
|
|
7
|
+
Manifest,
|
|
8
|
+
Metadata,
|
|
9
|
+
Properties
|
|
10
|
+
} from "@readium/shared";
|
|
11
|
+
import { camelCase } from "change-case";
|
|
12
|
+
import { enumerate } from "itertools";
|
|
13
|
+
import clockvalue from "smil-clockvalue";
|
|
14
|
+
import { lookupAudioMime } from "@storyteller-platform/audiobook";
|
|
15
|
+
import {
|
|
16
|
+
Epub
|
|
17
|
+
} from "@storyteller-platform/epub";
|
|
18
|
+
function generateGuidedNavigationManifest(title, guidedNavDocs) {
|
|
19
|
+
const readingOrder = [];
|
|
20
|
+
for (const doc of guidedNavDocs) {
|
|
21
|
+
const href = doc.links?.findWithRel("self")?.href;
|
|
22
|
+
if (!href) continue;
|
|
23
|
+
const textref = doc.guided?.[0]?.textref;
|
|
24
|
+
if (!textref) continue;
|
|
25
|
+
const referencedAudioFiles = {};
|
|
26
|
+
const pars = flatten(doc.guided ?? []);
|
|
27
|
+
for (const par of pars) {
|
|
28
|
+
if (!par.audioFile) continue;
|
|
29
|
+
const range = par.audioTime;
|
|
30
|
+
if (!range) continue;
|
|
31
|
+
const [startString, endString] = range.slice(2).split(",");
|
|
32
|
+
const start = parseFloat(startString ?? "0");
|
|
33
|
+
const end = endString ? parseFloat(endString) : null;
|
|
34
|
+
const existing = referencedAudioFiles[par.audioFile];
|
|
35
|
+
if (!existing) {
|
|
36
|
+
referencedAudioFiles[par.audioFile] = {
|
|
37
|
+
start,
|
|
38
|
+
end
|
|
39
|
+
};
|
|
40
|
+
continue;
|
|
41
|
+
}
|
|
42
|
+
existing.end = end;
|
|
43
|
+
}
|
|
44
|
+
const audioReferences = Object.entries(referencedAudioFiles).map(
|
|
45
|
+
([audioFile, { start, end }]) => ({
|
|
46
|
+
href: `${audioFile}#t=${start},${end}`,
|
|
47
|
+
type: lookupAudioMime(audioFile)
|
|
48
|
+
})
|
|
49
|
+
);
|
|
50
|
+
readingOrder.push(
|
|
51
|
+
new Link({
|
|
52
|
+
href,
|
|
53
|
+
properties: new Properties({
|
|
54
|
+
references: [
|
|
55
|
+
{
|
|
56
|
+
href: textref,
|
|
57
|
+
type: "application/xhtml+xml"
|
|
58
|
+
},
|
|
59
|
+
...audioReferences
|
|
60
|
+
]
|
|
61
|
+
})
|
|
62
|
+
})
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
return new Manifest({
|
|
66
|
+
metadata: new Metadata({
|
|
67
|
+
title,
|
|
68
|
+
conformsTo: [
|
|
69
|
+
"https://readium.org/webpub-manifest/profiles/guided-navigation"
|
|
70
|
+
]
|
|
71
|
+
}),
|
|
72
|
+
links: new Links([
|
|
73
|
+
new Link({
|
|
74
|
+
href: "manifest.json",
|
|
75
|
+
type: "application/webpub+json",
|
|
76
|
+
rels: /* @__PURE__ */ new Set(["self"])
|
|
77
|
+
})
|
|
78
|
+
]),
|
|
79
|
+
readingOrder: new Links(readingOrder)
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
async function generateGuidedNavigationDocuments(epub) {
|
|
83
|
+
const manifest = await epub.getManifest();
|
|
84
|
+
const spine = await epub.getSpineItems();
|
|
85
|
+
const mediaOverlays = [];
|
|
86
|
+
for (const item of spine) {
|
|
87
|
+
if (!item.mediaOverlay) continue;
|
|
88
|
+
const mediaOverlayItem = manifest[item.mediaOverlay];
|
|
89
|
+
if (!mediaOverlayItem) continue;
|
|
90
|
+
mediaOverlays.push(mediaOverlayItem);
|
|
91
|
+
}
|
|
92
|
+
const guidedNavDocs = [];
|
|
93
|
+
for (const [i, overlay] of enumerate(mediaOverlays)) {
|
|
94
|
+
const contents = await epub.readItemContents(overlay.id, "utf-8");
|
|
95
|
+
const xml = Epub.xmlParser.parse(contents);
|
|
96
|
+
const body = Epub.findXmlDescendantByName("body", xml);
|
|
97
|
+
if (!body) continue;
|
|
98
|
+
const links = [];
|
|
99
|
+
const prevOverlay = mediaOverlays[i - 1];
|
|
100
|
+
if (prevOverlay) {
|
|
101
|
+
links.push(
|
|
102
|
+
new Link({
|
|
103
|
+
rels: /* @__PURE__ */ new Set(["prev"]),
|
|
104
|
+
href: `GND/${prevOverlay.id}.json`,
|
|
105
|
+
type: "application/guided-navigation+json"
|
|
106
|
+
})
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
links.push(
|
|
110
|
+
new Link({
|
|
111
|
+
rels: /* @__PURE__ */ new Set(["self"]),
|
|
112
|
+
href: `GND/${overlay.id}.json`,
|
|
113
|
+
type: "application/guided-navigation+json"
|
|
114
|
+
})
|
|
115
|
+
);
|
|
116
|
+
const nextOverlay = mediaOverlays[i + 1];
|
|
117
|
+
if (nextOverlay) {
|
|
118
|
+
links.push(
|
|
119
|
+
new Link({
|
|
120
|
+
rels: /* @__PURE__ */ new Set(["next"]),
|
|
121
|
+
href: `GND/${nextOverlay.id}.json`,
|
|
122
|
+
type: "application/guided-navigation+json"
|
|
123
|
+
})
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
const guidedNavDoc = new GuidedNavigationDocument({
|
|
127
|
+
links: new Links(links),
|
|
128
|
+
guided: await parseGuidedNavigationObjects(
|
|
129
|
+
epub,
|
|
130
|
+
overlay.href,
|
|
131
|
+
Epub.getXmlChildren(body)
|
|
132
|
+
)
|
|
133
|
+
});
|
|
134
|
+
guidedNavDocs.push(guidedNavDoc);
|
|
135
|
+
}
|
|
136
|
+
return guidedNavDocs;
|
|
137
|
+
}
|
|
138
|
+
async function parseGuidedNavigationObjects(epub, overlayHref, xml) {
|
|
139
|
+
const guidedNavObjects = [];
|
|
140
|
+
const children = xml.filter(
|
|
141
|
+
(node) => !Epub.isXmlTextNode(node) && ["seq", "par"].includes(Epub.getXmlElementName(node))
|
|
142
|
+
);
|
|
143
|
+
for (const element of children) {
|
|
144
|
+
if (Epub.getXmlElementName(element) === "par") {
|
|
145
|
+
const text = Epub.findXmlChildByName("text", Epub.getXmlChildren(element));
|
|
146
|
+
const audio = Epub.findXmlChildByName(
|
|
147
|
+
"audio",
|
|
148
|
+
Epub.getXmlChildren(element)
|
|
149
|
+
);
|
|
150
|
+
if (!text || !audio) continue;
|
|
151
|
+
const textSrc = Epub.getXmlAttributes(text)["src"];
|
|
152
|
+
const { src: audioSrc, clipBegin, clipEnd } = Epub.getXmlAttributes(audio);
|
|
153
|
+
if (!textSrc || !audioSrc || clipBegin === void 0 || clipEnd === void 0) {
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
const textref = await epub.resolveHref(textSrc, overlayHref, {
|
|
157
|
+
toRoot: true
|
|
158
|
+
});
|
|
159
|
+
const audioref = await epub.resolveHref(audioSrc, overlayHref, {
|
|
160
|
+
toRoot: true
|
|
161
|
+
});
|
|
162
|
+
const clipBeginSeconds = clockvalue(clipBegin) / 1e3;
|
|
163
|
+
const clipEndSeconds = clockvalue(clipEnd) / 1e3;
|
|
164
|
+
guidedNavObjects.push(
|
|
165
|
+
new GuidedNavigationObject({
|
|
166
|
+
// Slice off the leading slash
|
|
167
|
+
textref,
|
|
168
|
+
audioref: `${audioref}#t=${clipBeginSeconds},${clipEndSeconds}`
|
|
169
|
+
})
|
|
170
|
+
);
|
|
171
|
+
}
|
|
172
|
+
if (Epub.getXmlElementName(element) === "seq") {
|
|
173
|
+
const attrs = Epub.getXmlAttributes(element);
|
|
174
|
+
const epubType = attrs["epub:type"];
|
|
175
|
+
const role = epubType && camelCase(epubType);
|
|
176
|
+
const textref = attrs["epub:textref"];
|
|
177
|
+
if (!textref) continue;
|
|
178
|
+
const children2 = await parseGuidedNavigationObjects(
|
|
179
|
+
epub,
|
|
180
|
+
overlayHref,
|
|
181
|
+
Epub.getXmlChildren(element)
|
|
182
|
+
);
|
|
183
|
+
guidedNavObjects.push(
|
|
184
|
+
new GuidedNavigationObject({
|
|
185
|
+
textref: await epub.resolveHref(textref, overlayHref, {
|
|
186
|
+
toRoot: true
|
|
187
|
+
}),
|
|
188
|
+
...role && { role: /* @__PURE__ */ new Set([role]) },
|
|
189
|
+
children: children2
|
|
190
|
+
})
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
return guidedNavObjects;
|
|
195
|
+
}
|
|
196
|
+
function flatten(input) {
|
|
197
|
+
const pars = [];
|
|
198
|
+
for (const obj of input) {
|
|
199
|
+
if (obj.children) {
|
|
200
|
+
pars.push(...flatten(obj.children));
|
|
201
|
+
} else {
|
|
202
|
+
pars.push(obj);
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return pars;
|
|
206
|
+
}
|
|
207
|
+
export {
|
|
208
|
+
generateGuidedNavigationDocuments,
|
|
209
|
+
generateGuidedNavigationManifest
|
|
210
|
+
};
|