@prose-reader/streamer 1.20.0 → 1.22.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.
@@ -1,19 +1,633 @@
1
- (function(f,u){typeof exports=="object"&&typeof module<"u"?u(exports,require("xmldoc"),require("@prose-reader/shared")):typeof define=="function"&&define.amd?define(["exports","xmldoc","@prose-reader/shared"],u):(f=typeof globalThis<"u"?globalThis:f||self,u(f["prose-streamer"]={},f.xmldoc,f["@prose-reader/shared"]))})(this,function(f,u,y){"use strict";const k=(e,{opfBasePath:i,baseUrl:n})=>{const a={contents:[],path:"",href:"",title:""};let t=e.childNamed("span")||e.childNamed("a");a.title=(t==null?void 0:t.attr.title)||(t==null?void 0:t.val.trim())||a.title;let r=t==null?void 0:t.name;r!=="a"&&(t=e.descendantWithPath(`${r}.a`),t&&(r=t.name.toLowerCase())),r==="a"&&(t!=null&&t.attr.href)&&(a.path=y.urlJoin(i,t.attr.href),a.href=y.urlJoin(n,i,t.attr.href));const o=e.childNamed("ol");if(o){const s=o.childrenNamed("li");s&&s.length>0&&(a.contents=s.map(d=>k(d,{opfBasePath:i,baseUrl:n})))}return a},M=(e,{opfBasePath:i,baseUrl:n})=>{var r,o;const a=[];let t;return e.descendantWithPath("body.nav.ol")?t=(r=e.descendantWithPath("body.nav.ol"))==null?void 0:r.children:e.descendantWithPath("body.section.nav.ol")&&(t=(o=e.descendantWithPath("body.section.nav.ol"))==null?void 0:o.children),t&&t.length>0&&t.filter(s=>s.name==="li").forEach(s=>a.push(k(s,{opfBasePath:i,baseUrl:n}))),a},B=async(e,i,{opfBasePath:n,baseUrl:a})=>{var r;const t=(r=e.childNamed("manifest"))==null?void 0:r.childrenNamed("item").find(o=>o.attr.properties==="nav");if(t){const o=Object.values(i.files).find(s=>s.uri.endsWith(t.attr.href||""));if(o){const s=new u.XmlDocument(await o.string());return M(s,{opfBasePath:n,baseUrl:a})}}},S=(e,{opfBasePath:i,baseUrl:n,prefix:a})=>{var s,d;const t=((s=e==null?void 0:e.childNamed(`${a}content`))==null?void 0:s.attr.src)||"",r={title:((d=e==null?void 0:e.descendantWithPath(`${a}navLabel.${a}text`))==null?void 0:d.val)||"",path:y.urlJoin(i,t),href:y.urlJoin(n,i,t),contents:[]},o=e.childrenNamed(`${a}navPoint`);return o&&o.length>0&&(r.contents=o.map(p=>S(p,{opfBasePath:i,baseUrl:n,prefix:a}))),r},J=(e,{opfBasePath:i,baseUrl:n})=>{var o;const a=[],t=e.name;let r="";return t.indexOf(":")!==-1&&(r=t.split(":")[0]+":"),(o=e.childNamed(`${r}navMap`))==null||o.childrenNamed(`${r}navPoint`).forEach(s=>a.push(S(s,{opfBasePath:i,baseUrl:n,prefix:r}))),a},U=async({opfData:e,opfBasePath:i,baseUrl:n,archive:a})=>{var o;const t=e.childNamed("spine"),r=t&&t.attr.toc;if(r){const s=(o=e.childNamed("manifest"))==null?void 0:o.childrenNamed("item").find(d=>d.attr.id===r);if(s){const d=`${i}${i===""?"":"/"}${s.attr.href}`,p=Object.values(a.files).find(m=>m.uri.endsWith(d));if(p){const m=new u.XmlDocument(await p.string());return J(m,{opfBasePath:i,baseUrl:n})}}}},H=async(e,i,{baseUrl:n})=>{const{basePath:a}=F(i)||{},t=await U({opfData:e,opfBasePath:a,archive:i,baseUrl:n});return t||await B(e,i,{opfBasePath:a,baseUrl:n})},V=async e=>{const i={renditionLayout:void 0};return await Promise.all(e.files.map(async n=>{var a,t;if(n.uri.endsWith("com.kobobooks.display-options.xml")){const o=(a=new u.XmlDocument(await n.string()).childNamed("platform"))==null?void 0:a.childNamed("option");((t=o==null?void 0:o.attr)==null?void 0:t.name)==="fixed-layout"&&o.val==="true"&&(i.renditionLayout="pre-paginated")}})),i};let v=!1;const b={enable:e=>{v=e},log:(...e)=>{v&&console.log("[prose-reader-streamer]",...e)},warn:(...e)=>{v&&console.warn("[prose-reader-streamer]",...e)},error:(...e)=>{console.error(...e)},time:e=>{v&&console.time(`[prose-reader-streamer] [metric] ${e}`)},timeEnd:e=>{v&&console.timeEnd(`[prose-reader-streamer] [metric] ${e}`)},metric:(e,i=1/0)=>{const n=typeof e=="number"?e:e.duration;v&&(e.duration<=i?console.log("[prose-reader-streamer] [metric] ",`${e.name} took ${n}ms`):console.warn("[prose-reader-streamer] [metric] ",`${e.name} took ${e.duration}ms which is above the ${i}ms target for this function`))},measurePerformance:(e,i=10,n)=>(...a)=>{const t=performance.now(),r=n(...a);if(r&&r.then)return r.then(s=>{const d=performance.now();return b.metric({name:e,duration:d-t},i),s});const o=performance.now();return b.metric({name:e,duration:o-t},i),r}},F=e=>{const n=Object.values(e.files).filter(a=>!a.dir).find(a=>a.uri.endsWith(".opf"));return{data:n,basePath:(n==null?void 0:n.uri.substring(0,n.uri.lastIndexOf("/")))||""}},C=async({archive:e})=>{const{data:i,basePath:n}=F(e)||{},a=await(i==null?void 0:i.string());if(!a)return[];const t=new u.XmlDocument(a),r=t.childNamed("manifest"),o=t.childNamed("spine"),s=o==null?void 0:o.childrenNamed("itemref").map(m=>m.attr.idref),d=(r==null?void 0:r.childrenNamed("item").filter(m=>s.includes(m.attr.id||"")))||[];return e.files.filter(m=>d.find(h=>n?`${n}/${h.attr.href}`===m.uri:`${h.attr.href}`===m.uri))},W=e=>{var n;const i=e.childNamed("manifest");return((n=i==null?void 0:i.childrenNamed("item"))==null?void 0:n.map(a=>({href:a.attr.href||"",id:a.attr.id||"",mediaType:a.attr["media-type"]})))||[]},q=({archive:e,baseUrl:i})=>async n=>{var P;const{data:a,basePath:t}=F(e)||{},r=await V(e);if(!a)return n;const o=await a.string();b.log(o,r);const s=new u.XmlDocument(o),d=await H(s,e,{baseUrl:i})||[],p=s.childNamed("metadata"),m=s.childNamed("manifest"),h=s.childNamed("spine"),N=s.childNamed("guide"),$=p==null?void 0:p.childNamed("dc:title"),x=(p==null?void 0:p.childrenNamed("meta"))||[],A=x.find(l=>l.attr.property==="rendition:layout"),I=x.find(l=>l.attr.property==="rendition:flow"),L=x.find(l=>l.attr.property==="rendition:spread"),O=A==null?void 0:A.val,le=I==null?void 0:I.val,me=L==null?void 0:L.val,fe=($==null?void 0:$.val)||((P=e.files.find(({dir:l})=>l))==null?void 0:P.basename)||"",pe=h==null?void 0:h.attr["page-progression-direction"],ue=(await C({archive:e})).reduce((l,c)=>c.size+l,0);return{filename:e.filename,nav:{toc:d},renditionLayout:O||r.renditionLayout||"reflowable",renditionFlow:le||"auto",renditionSpread:me,title:fe,readingDirection:pe||"ltr",spineItems:(h==null?void 0:h.childrenNamed("itemref").map(l=>{var j,X,R;const c=m==null?void 0:m.childrenNamed("item").find(g=>g.attr.id===(l==null?void 0:l.attr.idref)),he=(c==null?void 0:c.attr.href)||"",D=((j=l==null?void 0:l.attr.properties)==null?void 0:j.split(" "))||[],ge=((X=e.files.find(g=>g.uri.endsWith(he)))==null?void 0:X.size)||0,z=i??"";return{id:(c==null?void 0:c.attr.id)||"",href:(R=c==null?void 0:c.attr.href)!=null&&R.startsWith("https://")?c==null?void 0:c.attr.href:t?`${z}${t}/${c==null?void 0:c.attr.href}`:`${z}${c==null?void 0:c.attr.href}`,renditionLayout:O||"reflowable",...D.find(g=>g==="rendition:layout-reflowable")&&{renditionLayout:"reflowable"},progressionWeight:ge/ue,pageSpreadLeft:D.some(g=>g==="page-spread-left")||void 0,pageSpreadRight:D.some(g=>g==="page-spread-right")||void 0,mediaType:c==null?void 0:c.attr["media-type"]}}))||[],items:W(s),guide:N==null?void 0:N.childrenNamed("reference").map(l=>({href:l.attr.href||"",title:l.attr.title||"",type:l.attr.type}))}},_=async(e,i)=>{const n=Object.values(e.files).find(r=>r.uri===i),a=await G(e,i);if(!n)throw new Error("no file found");const t=await n.blob();return{body:t,params:{headers:{...t.type&&{"Content-Type":t.type},...n.encodingFormat&&{"Content-Type":n.encodingFormat},...a.mediaType&&{"Content-Type":a.mediaType}}}}},G=async(e,i)=>{var t,r;const a=await((t=F(e).data)==null?void 0:t.string());if(a){const o=new u.XmlDocument(a);return{mediaType:(r=W(o).find(d=>i.endsWith(d.href)))==null?void 0:r.mediaType}}return{mediaType:K(i)}},K=e=>{if(e.endsWith(".css"))return"text/css; charset=UTF-8";if(e.endsWith(".jpg"))return"image/jpg";if(e.endsWith(".xhtml"))return"application/xhtml+xml";if(e.endsWith(".mp4"))return"video/mp4";if(e.endsWith(".svg"))return"image/svg+xml"},Y=({archive:e,baseUrl:i})=>async()=>{var a;const n=Object.values(e.files).filter(t=>!t.dir);return{filename:e.filename,title:((a=e.files.find(({dir:t})=>t))==null?void 0:a.basename.replace(/\/$/,""))||"",renditionLayout:"pre-paginated",renditionSpread:"auto",readingDirection:"ltr",spineItems:n.map((t,r)=>({id:`${r}.${t.basename}`,href:encodeURI(`${i}${t.uri}`),renditionLayout:"pre-paginated",progressionWeight:1/n.length,pageSpreadLeft:void 0,pageSpreadRight:void 0,mediaType:t.encodingFormat})),items:n.map((t,r)=>({id:`${r}.${t.basename}`,href:`${i}${t.uri}`}))}},Q=({archive:e,baseUrl:i})=>async n=>{var s;const a=e.files.find(d=>d.basename.toLowerCase()==="comicinfo.xml");if(!a)return n;const t=await a.string(),o=((s=new u.XmlDocument(t).childNamed("Manga"))==null?void 0:s.val)||"unknown";return{...n,spineItems:n.spineItems.filter(d=>d.id.toLowerCase()!=="comicinfo.xml"),readingDirection:o==="YesAndRightToLeft"?"rtl":"ltr"}},Z=e=>{var n;const i=(n=e.descendantWithPath("head"))==null?void 0:n.childrenNamed("meta").find(a=>a.attr.name==="viewport");return!!(i&&i.attr.name==="viewport")},E=e=>e.reduce(async(i,n)=>{if(!await i||!y.isXmlBasedMimeType({mimeType:n.encodingFormat,uri:n.uri}))return!1;const t=await n.string();return t?Z(new u.XmlDocument(t)):!1},Promise.resolve(!0)),ee=({archive:e,baseUrl:i})=>async n=>{if(n.renditionLayout==="reflowable"&&n.spineItems.every(t=>t.renditionLayout==="reflowable")){const t=await C({archive:e});if(await E(t))return{...n,spineItems:n.spineItems.map(o=>({...o,renditionLayout:"pre-paginated"})),renditionLayout:"pre-paginated"}}return n},T=(e,i)=>{var t;const n=e.split(/(\d+)/),a=i.split(/(\d+)/);for(let r=0,o=n.length;r<o;r++)if(n[r]!==a[r])return(t=n[r])!=null&&t.match(/\d/)?+(n[r]||"")-+(a[r]||""):(n[r]||"").localeCompare(a[r]||"");return 1},te=({archive:e,baseUrl:i})=>async n=>{if(n.nav)return n;const a=[...e.files].sort((r,o)=>T(r.uri,o.uri)),t=Object.values(a).reduce((r,o)=>{const s=o.uri.split("/");return!o.dir&&s.length>1&&s.forEach((p,m)=>{if(m===s.length-1)return;r.find(({title:$})=>$===p)||r.push({contents:[],href:y.urlJoin(i,encodeURI(o.uri)).replace(/\/$/,""),path:o.uri.replace(/\/$/,""),title:s[0]??""})}),r},[]);return t.length===0?n:{...n,nav:{toc:t}}},ne={filename:"",items:[],nav:{toc:[]},readingDirection:"ltr",renditionLayout:"pre-paginated",renditionSpread:"auto",spineItems:[],title:""},re=async(e,{baseUrl:i=""}={})=>{const n=[Y({archive:e,baseUrl:i}),q({archive:e,baseUrl:i}),ee({archive:e,baseUrl:i}),Q({archive:e,baseUrl:i}),te({archive:e,baseUrl:i})];try{const a=await n.reduce(async(t,r)=>await r(await t),Promise.resolve(ne));return b.log("Generated manifest",a),a}catch(a){throw b.error(a),a}},w=e=>e.substring(e.lastIndexOf("/")+1)||e,ae=async(e,i)=>{const n=`
1
+ (function(global, factory) {
2
+ typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("@prose-reader/shared"), require("xmldoc")) : typeof define === "function" && define.amd ? define(["exports", "@prose-reader/shared", "xmldoc"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global["prose-streamer"] = {}, global["@prose-reader/shared"], global.xmldoc));
3
+ })(this, function(exports2, shared, xmldoc) {
4
+ "use strict";
5
+ let enabled = false;
6
+ const Report = {
7
+ enable: (enable) => {
8
+ enabled = enable;
9
+ },
10
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
11
+ log: (...data) => {
12
+ if (enabled) {
13
+ console.log(`[prose-reader-streamer]`, ...data);
14
+ }
15
+ },
16
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
17
+ warn: (...data) => {
18
+ if (enabled) {
19
+ console.warn(`[prose-reader-streamer]`, ...data);
20
+ }
21
+ },
22
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
23
+ error: (...data) => {
24
+ console.error(...data);
25
+ },
26
+ time: (label) => {
27
+ if (enabled) {
28
+ console.time(`[prose-reader-streamer] [metric] ${label}`);
29
+ }
30
+ },
31
+ timeEnd: (label) => {
32
+ if (enabled) {
33
+ console.timeEnd(`[prose-reader-streamer] [metric] ${label}`);
34
+ }
35
+ },
36
+ metric: (performanceEntry, targetDuration = Infinity) => {
37
+ const duration = typeof performanceEntry === `number` ? performanceEntry : performanceEntry.duration;
38
+ if (enabled) {
39
+ if (performanceEntry.duration <= targetDuration) {
40
+ console.log(`[prose-reader-streamer] [metric] `, `${performanceEntry.name} took ${duration}ms`);
41
+ } else {
42
+ console.warn(
43
+ `[prose-reader-streamer] [metric] `,
44
+ `${performanceEntry.name} took ${performanceEntry.duration}ms which is above the ${targetDuration}ms target for this function`
45
+ );
46
+ }
47
+ }
48
+ },
49
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
50
+ measurePerformance: (name, targetDuration = 10, functionToMeasure) => {
51
+ return (...args) => {
52
+ const t0 = performance.now();
53
+ const response = functionToMeasure(...args);
54
+ if (response && response.then) {
55
+ return response.then((res) => {
56
+ const t12 = performance.now();
57
+ Report.metric({ name, duration: t12 - t0 }, targetDuration);
58
+ return res;
59
+ });
60
+ }
61
+ const t1 = performance.now();
62
+ Report.metric({ name, duration: t1 - t0 }, targetDuration);
63
+ return response;
64
+ };
65
+ }
66
+ };
67
+ const cssFixHook = ({ archive, resourcePath }) => async (resource) => {
68
+ const file = Object.values(archive.files).find((file2) => file2.uri === resourcePath);
69
+ if (file == null ? void 0 : file.basename.endsWith(`.css`)) {
70
+ const bodyToParse = resource.body ?? await file.string();
71
+ const newBody = bodyToParse.replaceAll(`-webkit-writing-mode`, `writing-mode`);
72
+ return {
73
+ ...resource,
74
+ body: newBody
75
+ };
76
+ }
77
+ return resource;
78
+ };
79
+ const getArchiveOpfInfo = (archive) => {
80
+ const filesAsArray = Object.values(archive.files).filter((file2) => !file2.dir);
81
+ const file = filesAsArray.find((file2) => file2.uri.endsWith(`.opf`));
82
+ return {
83
+ data: file,
84
+ basePath: (file == null ? void 0 : file.uri.substring(0, file.uri.lastIndexOf(`/`))) || ``
85
+ };
86
+ };
87
+ const extractNavChapter = (li, { opfBasePath, baseUrl }) => {
88
+ const chp = {
89
+ contents: [],
90
+ path: ``,
91
+ href: ``,
92
+ title: ``
93
+ };
94
+ let contentNode = li.childNamed(`span`) || li.childNamed(`a`);
95
+ chp.title = (contentNode == null ? void 0 : contentNode.attr.title) || (contentNode == null ? void 0 : contentNode.val.trim()) || chp.title;
96
+ let node = contentNode == null ? void 0 : contentNode.name;
97
+ if (node !== `a`) {
98
+ contentNode = li.descendantWithPath(`${node}.a`);
99
+ if (contentNode) {
100
+ node = contentNode.name.toLowerCase();
101
+ }
102
+ }
103
+ if (node === `a` && (contentNode == null ? void 0 : contentNode.attr.href)) {
104
+ chp.path = shared.urlJoin(opfBasePath, contentNode.attr.href);
105
+ chp.href = shared.urlJoin(baseUrl, opfBasePath, contentNode.attr.href);
106
+ }
107
+ const sublistNode = li.childNamed(`ol`);
108
+ if (sublistNode) {
109
+ const children = sublistNode.childrenNamed(`li`);
110
+ if (children && children.length > 0) {
111
+ chp.contents = children.map((child) => extractNavChapter(child, { opfBasePath, baseUrl }));
112
+ }
113
+ }
114
+ return chp;
115
+ };
116
+ const buildTOCFromNav = (doc, { opfBasePath, baseUrl }) => {
117
+ var _a, _b;
118
+ const toc = [];
119
+ let navDataChildren;
120
+ if (doc.descendantWithPath(`body.nav.ol`)) {
121
+ navDataChildren = (_a = doc.descendantWithPath(`body.nav.ol`)) == null ? void 0 : _a.children;
122
+ } else if (doc.descendantWithPath(`body.section.nav.ol`)) {
123
+ navDataChildren = (_b = doc.descendantWithPath(`body.section.nav.ol`)) == null ? void 0 : _b.children;
124
+ }
125
+ if (navDataChildren && navDataChildren.length > 0) {
126
+ navDataChildren.filter((li) => li.name === `li`).forEach((li) => toc.push(extractNavChapter(li, { opfBasePath, baseUrl })));
127
+ }
128
+ return toc;
129
+ };
130
+ const parseTocFromNavPath = async (opfXmlDoc, archive, { opfBasePath, baseUrl }) => {
131
+ var _a;
132
+ const navItem = (_a = opfXmlDoc.childNamed(`manifest`)) == null ? void 0 : _a.childrenNamed(`item`).find((child) => child.attr.properties === `nav`);
133
+ if (navItem) {
134
+ const tocFile = Object.values(archive.files).find((item) => item.uri.endsWith(navItem.attr.href || ``));
135
+ if (tocFile) {
136
+ const doc = new xmldoc.XmlDocument(await tocFile.string());
137
+ return buildTOCFromNav(doc, { opfBasePath, baseUrl });
138
+ }
139
+ }
140
+ };
141
+ const mapNcxChapter = (point, { opfBasePath, baseUrl, prefix }) => {
142
+ var _a, _b;
143
+ const src = ((_a = point == null ? void 0 : point.childNamed(`${prefix}content`)) == null ? void 0 : _a.attr.src) || ``;
144
+ const out = {
145
+ title: ((_b = point == null ? void 0 : point.descendantWithPath(`${prefix}navLabel.${prefix}text`)) == null ? void 0 : _b.val) || ``,
146
+ path: shared.urlJoin(opfBasePath, src),
147
+ href: shared.urlJoin(baseUrl, opfBasePath, src),
148
+ contents: []
149
+ };
150
+ const children = point.childrenNamed(`${prefix}navPoint`);
151
+ if (children && children.length > 0) {
152
+ out.contents = children.map((pt) => mapNcxChapter(pt, { opfBasePath, baseUrl, prefix }));
153
+ }
154
+ return out;
155
+ };
156
+ const buildTOCFromNCX = (ncxData, { opfBasePath, baseUrl }) => {
157
+ var _a;
158
+ const toc = [];
159
+ const rootTagName = ncxData.name;
160
+ let prefix = ``;
161
+ if (rootTagName.indexOf(`:`) !== -1) {
162
+ prefix = rootTagName.split(`:`)[0] + `:`;
163
+ }
164
+ (_a = ncxData.childNamed(`${prefix}navMap`)) == null ? void 0 : _a.childrenNamed(`${prefix}navPoint`).forEach((point) => toc.push(mapNcxChapter(point, { opfBasePath, baseUrl, prefix })));
165
+ return toc;
166
+ };
167
+ const parseTocFromNcx = async ({
168
+ opfData,
169
+ opfBasePath,
170
+ baseUrl,
171
+ archive
172
+ }) => {
173
+ var _a;
174
+ const spine = opfData.childNamed(`spine`);
175
+ const ncxId = spine && spine.attr.toc;
176
+ if (ncxId) {
177
+ const ncxItem = (_a = opfData.childNamed(`manifest`)) == null ? void 0 : _a.childrenNamed(`item`).find((item) => item.attr.id === ncxId);
178
+ if (ncxItem) {
179
+ const ncxPath = `${opfBasePath}${opfBasePath === `` ? `` : `/`}${ncxItem.attr.href}`;
180
+ const file = Object.values(archive.files).find((item) => item.uri.endsWith(ncxPath));
181
+ if (file) {
182
+ const ncxData = new xmldoc.XmlDocument(await file.string());
183
+ return buildTOCFromNCX(ncxData, { opfBasePath, baseUrl });
184
+ }
185
+ }
186
+ }
187
+ };
188
+ const parseToc = async (opfXmlDoc, archive, { baseUrl }) => {
189
+ const { basePath: opfBasePath } = getArchiveOpfInfo(archive) || {};
190
+ const tocFromNcx = await parseTocFromNcx({
191
+ opfData: opfXmlDoc,
192
+ opfBasePath,
193
+ archive,
194
+ baseUrl
195
+ });
196
+ if (tocFromNcx) {
197
+ return tocFromNcx;
198
+ }
199
+ return await parseTocFromNavPath(opfXmlDoc, archive, { opfBasePath, baseUrl });
200
+ };
201
+ const extractKoboInformationFromArchive = async (archive) => {
202
+ const koboInformation = {
203
+ renditionLayout: void 0
204
+ };
205
+ await Promise.all(
206
+ archive.files.map(async (file) => {
207
+ var _a, _b;
208
+ if (file.uri.endsWith(`com.kobobooks.display-options.xml`)) {
209
+ const opfXmlDoc = new xmldoc.XmlDocument(await file.string());
210
+ const optionElement = (_a = opfXmlDoc.childNamed(`platform`)) == null ? void 0 : _a.childNamed(`option`);
211
+ if (((_b = optionElement == null ? void 0 : optionElement.attr) == null ? void 0 : _b.name) === `fixed-layout` && optionElement.val === `true`) {
212
+ koboInformation.renditionLayout = `pre-paginated`;
213
+ }
214
+ }
215
+ })
216
+ );
217
+ return koboInformation;
218
+ };
219
+ const getSpineItemFilesFromArchive = async ({ archive }) => {
220
+ const { data: opsFile, basePath: opfBasePath } = getArchiveOpfInfo(archive) || {};
221
+ const data = await (opsFile == null ? void 0 : opsFile.string());
222
+ if (!data)
223
+ return [];
224
+ const _opfXmlDoc = new xmldoc.XmlDocument(data);
225
+ const manifestElm = _opfXmlDoc.childNamed(`manifest`);
226
+ const spineElm = _opfXmlDoc.childNamed(`spine`);
227
+ const spineItemIds = spineElm == null ? void 0 : spineElm.childrenNamed(`itemref`).map((item) => item.attr.idref);
228
+ const manifestItemsFromSpine = (manifestElm == null ? void 0 : manifestElm.childrenNamed(`item`).filter((item) => spineItemIds.includes(item.attr.id || ``))) || [];
229
+ const archiveSpineItems = archive.files.filter((file) => {
230
+ return manifestItemsFromSpine.find((item) => {
231
+ if (!opfBasePath)
232
+ return `${item.attr.href}` === file.uri;
233
+ return `${opfBasePath}/${item.attr.href}` === file.uri;
234
+ });
235
+ });
236
+ return archiveSpineItems;
237
+ };
238
+ const getItemsFromDoc = (doc) => {
239
+ var _a;
240
+ const manifestElm = doc.childNamed(`manifest`);
241
+ return ((_a = manifestElm == null ? void 0 : manifestElm.childrenNamed(`item`)) == null ? void 0 : _a.map((el) => ({
242
+ href: el.attr.href || ``,
243
+ id: el.attr.id || ``,
244
+ mediaType: el.attr[`media-type`]
245
+ }))) || [];
246
+ };
247
+ const epubHook = ({ archive, baseUrl }) => async (manifest) => {
248
+ var _a;
249
+ const { data: opsFile, basePath: opfBasePath } = getArchiveOpfInfo(archive) || {};
250
+ const koboInformation = await extractKoboInformationFromArchive(archive);
251
+ if (!opsFile) {
252
+ return manifest;
253
+ }
254
+ const data = await opsFile.string();
255
+ Report.log(data, koboInformation);
256
+ const opfXmlDoc = new xmldoc.XmlDocument(data);
257
+ const toc = await parseToc(opfXmlDoc, archive, { baseUrl }) || [];
258
+ const metadataElm = opfXmlDoc.childNamed(`metadata`);
259
+ const manifestElm = opfXmlDoc.childNamed(`manifest`);
260
+ const spineElm = opfXmlDoc.childNamed(`spine`);
261
+ const guideElm = opfXmlDoc.childNamed(`guide`);
262
+ const titleElm = metadataElm == null ? void 0 : metadataElm.childNamed(`dc:title`);
263
+ const metaElmChildren = (metadataElm == null ? void 0 : metadataElm.childrenNamed(`meta`)) || [];
264
+ const metaElmWithRendition = metaElmChildren.find((meta) => meta.attr.property === `rendition:layout`);
265
+ const metaElmWithRenditionFlow = metaElmChildren.find((meta) => meta.attr.property === `rendition:flow`);
266
+ const metaElmWithRenditionSpread = metaElmChildren.find((meta) => meta.attr.property === `rendition:spread`);
267
+ const publisherRenditionLayout = metaElmWithRendition == null ? void 0 : metaElmWithRendition.val;
268
+ const publisherRenditionFlow = metaElmWithRenditionFlow == null ? void 0 : metaElmWithRenditionFlow.val;
269
+ const renditionSpread = metaElmWithRenditionSpread == null ? void 0 : metaElmWithRenditionSpread.val;
270
+ const title = (titleElm == null ? void 0 : titleElm.val) || ((_a = archive.files.find(({ dir }) => dir)) == null ? void 0 : _a.basename) || ``;
271
+ const pageProgressionDirection = spineElm == null ? void 0 : spineElm.attr[`page-progression-direction`];
272
+ const archiveSpineItems = await getSpineItemFilesFromArchive({ archive });
273
+ const totalSize = archiveSpineItems.reduce((size, file) => file.size + size, 0);
274
+ return {
275
+ filename: archive.filename,
276
+ nav: {
277
+ toc
278
+ },
279
+ renditionLayout: publisherRenditionLayout || koboInformation.renditionLayout || `reflowable`,
280
+ renditionFlow: publisherRenditionFlow || `auto`,
281
+ renditionSpread,
282
+ title,
283
+ readingDirection: pageProgressionDirection || `ltr`,
284
+ spineItems: (spineElm == null ? void 0 : spineElm.childrenNamed(`itemref`).map((itemrefElm) => {
285
+ var _a2, _b, _c;
286
+ const manifestItem = manifestElm == null ? void 0 : manifestElm.childrenNamed(`item`).find((item) => item.attr.id === (itemrefElm == null ? void 0 : itemrefElm.attr.idref));
287
+ const href = (manifestItem == null ? void 0 : manifestItem.attr.href) || ``;
288
+ const properties = ((_a2 = itemrefElm == null ? void 0 : itemrefElm.attr.properties) == null ? void 0 : _a2.split(` `)) || [];
289
+ const itemSize = ((_b = archive.files.find((file) => file.uri.endsWith(href))) == null ? void 0 : _b.size) || 0;
290
+ const hrefBaseUri = baseUrl ?? "";
291
+ return {
292
+ id: (manifestItem == null ? void 0 : manifestItem.attr.id) || ``,
293
+ href: ((_c = manifestItem == null ? void 0 : manifestItem.attr.href) == null ? void 0 : _c.startsWith(`https://`)) ? manifestItem == null ? void 0 : manifestItem.attr.href : opfBasePath ? `${hrefBaseUri}${opfBasePath}/${manifestItem == null ? void 0 : manifestItem.attr.href}` : `${hrefBaseUri}${manifestItem == null ? void 0 : manifestItem.attr.href}`,
294
+ renditionLayout: publisherRenditionLayout || `reflowable`,
295
+ ...properties.find((property) => property === `rendition:layout-reflowable`) && {
296
+ renditionLayout: `reflowable`
297
+ },
298
+ progressionWeight: itemSize / totalSize,
299
+ pageSpreadLeft: properties.some((property) => property === `page-spread-left`) || void 0,
300
+ pageSpreadRight: properties.some((property) => property === `page-spread-right`) || void 0,
301
+ // size: itemSize
302
+ mediaType: manifestItem == null ? void 0 : manifestItem.attr[`media-type`]
303
+ };
304
+ })) || [],
305
+ items: getItemsFromDoc(opfXmlDoc),
306
+ guide: guideElm == null ? void 0 : guideElm.childrenNamed(`reference`).map((elm) => {
307
+ return {
308
+ href: elm.attr.href || ``,
309
+ title: elm.attr.title || ``,
310
+ type: elm.attr.type
311
+ };
312
+ })
313
+ };
314
+ };
315
+ const getMetadata = async (archive, resourcePath) => {
316
+ var _a, _b;
317
+ const opfInfo = getArchiveOpfInfo(archive);
318
+ const data = await ((_a = opfInfo.data) == null ? void 0 : _a.string());
319
+ if (data) {
320
+ const opfXmlDoc = new xmldoc.XmlDocument(data);
321
+ const items = getItemsFromDoc(opfXmlDoc);
322
+ return {
323
+ mediaType: (_b = items.find((item) => resourcePath.endsWith(item.href))) == null ? void 0 : _b.mediaType
324
+ };
325
+ }
326
+ return {
327
+ mediaType: getContentTypeFromExtension(resourcePath)
328
+ };
329
+ };
330
+ const getContentTypeFromExtension = (uri) => {
331
+ if (uri.endsWith(`.css`)) {
332
+ return `text/css; charset=UTF-8`;
333
+ }
334
+ if (uri.endsWith(`.jpg`)) {
335
+ return `image/jpg`;
336
+ }
337
+ if (uri.endsWith(`.xhtml`)) {
338
+ return `application/xhtml+xml`;
339
+ }
340
+ if (uri.endsWith(`.mp4`)) {
341
+ return `video/mp4`;
342
+ }
343
+ if (uri.endsWith(`.svg`)) {
344
+ return `image/svg+xml`;
345
+ }
346
+ };
347
+ const defaultHook$1 = ({ archive, resourcePath }) => async (resource) => {
348
+ const file = Object.values(archive.files).find((file2) => file2.uri === resourcePath);
349
+ if (!file)
350
+ return resource;
351
+ const metadata = await getMetadata(archive, resourcePath);
352
+ return {
353
+ ...resource,
354
+ params: {
355
+ ...resource.params,
356
+ status: 200,
357
+ headers: {
358
+ ...(file == null ? void 0 : file.encodingFormat) && {
359
+ "Content-Type": file.encodingFormat
360
+ },
361
+ ...metadata.mediaType && {
362
+ "Content-Type": metadata.mediaType
363
+ }
364
+ }
365
+ }
366
+ };
367
+ };
368
+ const generateResourceFromArchive = async (archive, resourcePath) => {
369
+ const file = Object.values(archive.files).find((file2) => file2.uri === resourcePath);
370
+ if (!file) {
371
+ throw new Error(`no file found`);
372
+ }
373
+ const defaultResource = {
374
+ params: {
375
+ status: 200
376
+ }
377
+ };
378
+ const hooks = [defaultHook$1({ archive, resourcePath }), cssFixHook({ archive, resourcePath })];
379
+ try {
380
+ const resource = await hooks.reduce(async (manifest, gen) => {
381
+ return await gen(await manifest);
382
+ }, Promise.resolve(defaultResource));
383
+ Report.log("Generated resource", resourcePath, resource);
384
+ return {
385
+ ...resource,
386
+ body: resource.body || await file.blob()
387
+ };
388
+ } catch (e) {
389
+ Report.error(e);
390
+ throw e;
391
+ }
392
+ };
393
+ const generateResourceFromError = (error) => {
394
+ return {
395
+ body: `
396
+ <!DOCTYPE html>
397
+ <html xmlns="http://www.w3.org/1999/xhtml" xmlns:epub="http://www.idpf.org/2007/ops" xml:lang="en" lang="en">
398
+ <head>
399
+ <meta name="${shared.PROSE_READER_RESOURCE_ERROR_INJECTED_META_NAME}" content="${String(error)}" />
400
+ </head>
401
+ <body>
402
+ <pre>${String(error)}</pre>
403
+ </body>
404
+ </html>
405
+ `,
406
+ params: {
407
+ status: 500,
408
+ headers: {
409
+ "Content-Type": "text/html;charset=UTF-8"
410
+ }
411
+ }
412
+ };
413
+ };
414
+ const defaultHook = ({ archive, baseUrl }) => async () => {
415
+ var _a;
416
+ const files = Object.values(archive.files).filter((file) => !file.dir);
417
+ return {
418
+ filename: archive.filename,
419
+ title: ((_a = archive.files.find(({ dir }) => dir)) == null ? void 0 : _a.basename.replace(/\/$/, ``)) || ``,
420
+ renditionLayout: `pre-paginated`,
421
+ renditionSpread: `auto`,
422
+ readingDirection: `ltr`,
423
+ spineItems: files.map((file, index) => ({
424
+ // some books such as cbz can have same basename inside different sub folder
425
+ // we need to make sure to have unique index
426
+ // /chap01/01.png, /chap02/01.png, etc
427
+ id: `${index}.${file.basename}`,
428
+ href: encodeURI(`${baseUrl}${file.uri}`),
429
+ renditionLayout: `pre-paginated`,
430
+ progressionWeight: 1 / files.length,
431
+ pageSpreadLeft: void 0,
432
+ pageSpreadRight: void 0,
433
+ mediaType: file.encodingFormat
434
+ })),
435
+ items: files.map((file, index) => ({
436
+ id: `${index}.${file.basename}`,
437
+ href: `${baseUrl}${file.uri}`
438
+ }))
439
+ };
440
+ };
441
+ const comicInfoHook = ({ archive, baseUrl }) => async (manifest) => {
442
+ var _a;
443
+ const comicInfoFile = archive.files.find((file) => file.basename.toLowerCase() === `comicinfo.xml`);
444
+ if (!comicInfoFile) {
445
+ return manifest;
446
+ }
447
+ const content = await comicInfoFile.string();
448
+ const xmlDoc = new xmldoc.XmlDocument(content);
449
+ const mangaVal = ((_a = xmlDoc.childNamed(`Manga`)) == null ? void 0 : _a.val) || `unknown`;
450
+ return {
451
+ ...manifest,
452
+ spineItems: manifest.spineItems.filter((item) => item.id.toLowerCase() !== `comicinfo.xml`),
453
+ readingDirection: mangaVal === `YesAndRightToLeft` ? `rtl` : `ltr`
454
+ };
455
+ };
456
+ const hasDocMetaViewport = (doc) => {
457
+ var _a;
458
+ const metaElm = (_a = doc.descendantWithPath("head")) == null ? void 0 : _a.childrenNamed("meta").find((node) => node.attr.name === "viewport");
459
+ return !!(metaElm && metaElm.attr.name === "viewport");
460
+ };
461
+ const allFilesHaveViewportMeta = (files) => files.reduce(async (result, current) => {
462
+ const _result = await result;
463
+ if (!_result)
464
+ return false;
465
+ if (!shared.isXmlBasedMimeType({
466
+ mimeType: current.encodingFormat,
467
+ uri: current.uri
468
+ })) {
469
+ return false;
470
+ }
471
+ const file = await current.string();
472
+ if (!file)
473
+ return false;
474
+ return hasDocMetaViewport(new xmldoc.XmlDocument(file));
475
+ }, Promise.resolve(true));
476
+ const epubOptimizerHook = ({ archive, baseUrl }) => async (manifest) => {
477
+ const bookIsFullReflowable = manifest.renditionLayout === "reflowable" && manifest.spineItems.every((item) => item.renditionLayout === "reflowable");
478
+ if (bookIsFullReflowable) {
479
+ const files = await getSpineItemFilesFromArchive({ archive });
480
+ const hasAllViewport = await allFilesHaveViewportMeta(files);
481
+ if (hasAllViewport) {
482
+ return {
483
+ ...manifest,
484
+ spineItems: manifest.spineItems.map((item) => ({
485
+ ...item,
486
+ renditionLayout: "pre-paginated"
487
+ })),
488
+ renditionLayout: "pre-paginated"
489
+ };
490
+ }
491
+ }
492
+ return manifest;
493
+ };
494
+ const sortByTitleComparator = (a, b) => {
495
+ var _a;
496
+ const alist = a.split(/(\d+)/);
497
+ const blist = b.split(/(\d+)/);
498
+ for (let i = 0, len = alist.length; i < len; i++) {
499
+ if (alist[i] !== blist[i]) {
500
+ if ((_a = alist[i]) == null ? void 0 : _a.match(/\d/)) {
501
+ return +(alist[i] || ``) - +(blist[i] || ``);
502
+ } else {
503
+ return (alist[i] || ``).localeCompare(blist[i] || ``);
504
+ }
505
+ }
506
+ }
507
+ return 1;
508
+ };
509
+ const navigationFallbackHook = ({ archive, baseUrl }) => async (manifest) => {
510
+ if (manifest.nav)
511
+ return manifest;
512
+ const filesSortedByAlpha = [...archive.files].sort((a, b) => sortByTitleComparator(a.uri, b.uri));
513
+ const toc = Object.values(filesSortedByAlpha).reduce((acc, file) => {
514
+ const parts = file.uri.split("/");
515
+ const isFileUnderFolder = !file.dir && parts.length > 1;
516
+ if (isFileUnderFolder) {
517
+ parts.forEach((part, level) => {
518
+ const partIsFileName = level === parts.length - 1;
519
+ if (partIsFileName)
520
+ return;
521
+ const existingTocItem = acc.find(({ title }) => title === part);
522
+ if (existingTocItem)
523
+ ;
524
+ else {
525
+ acc.push({
526
+ contents: [],
527
+ href: shared.urlJoin(baseUrl, encodeURI(file.uri)).replace(/\/$/, ""),
528
+ path: file.uri.replace(/\/$/, ""),
529
+ title: parts[0] ?? ""
530
+ });
531
+ }
532
+ });
533
+ }
534
+ return acc;
535
+ }, []);
536
+ if (toc.length === 0)
537
+ return manifest;
538
+ return {
539
+ ...manifest,
540
+ nav: {
541
+ toc
542
+ }
543
+ };
544
+ };
545
+ const baseManifest = {
546
+ filename: ``,
547
+ items: [],
548
+ nav: {
549
+ toc: []
550
+ },
551
+ readingDirection: `ltr`,
552
+ renditionLayout: `pre-paginated`,
553
+ renditionSpread: `auto`,
554
+ spineItems: [],
555
+ title: ``
556
+ };
557
+ const generateManifestFromArchive = async (archive, { baseUrl = `` } = {}) => {
558
+ const hooks = [
559
+ defaultHook({ archive, baseUrl }),
560
+ epubHook({ archive, baseUrl }),
561
+ epubOptimizerHook({ archive, baseUrl }),
562
+ comicInfoHook({ archive, baseUrl }),
563
+ navigationFallbackHook({ archive, baseUrl })
564
+ ];
565
+ try {
566
+ const manifest = await hooks.reduce(async (manifest2, gen) => {
567
+ return await gen(await manifest2);
568
+ }, Promise.resolve(baseManifest));
569
+ Report.log("Generated manifest", manifest);
570
+ return manifest;
571
+ } catch (e) {
572
+ Report.error(e);
573
+ throw e;
574
+ }
575
+ };
576
+ const getUriBasename = (uri) => uri.substring(uri.lastIndexOf(`/`) + 1) || uri;
577
+ const createArchiveFromUrls = async (urls, options) => {
578
+ const opfFileData = `
2
579
  <?xml version="1.0" encoding="UTF-8"?><package xmlns="http://www.idpf.org/2007/opf" version="2.0" unique-identifier="bookid">
3
580
  <metadata>
4
- <meta property="rendition:layout">${i!=null&&i.useRenditionFlow?"reflowable":"pre-paginated"}</meta>
5
- ${i!=null&&i.useRenditionFlow?'<meta property="rendition:flow">scrolled-continuous</meta>':""}
581
+ <meta property="rendition:layout">${(options == null ? void 0 : options.useRenditionFlow) ? `reflowable` : `pre-paginated`}</meta>
582
+ ${(options == null ? void 0 : options.useRenditionFlow) ? `<meta property="rendition:flow">scrolled-continuous</meta>` : ``}
6
583
  </metadata>
7
584
  <manifest>
8
- ${e.map(r=>`<item id="${w(r)}" href="${r}" media-type="${y.detectMimeTypeFromName(r)}"/>`).join(`
585
+ ${urls.map((url) => `<item id="${getUriBasename(url)}" href="${url}" media-type="${shared.detectMimeTypeFromName(url)}"/>`).join(`
9
586
  `)}
10
587
  </manifest>
11
588
  <spine>
12
- ${e.map(r=>`<itemref idref="${w(r)}" />`).join(`
589
+ ${urls.map((url) => `<itemref idref="${getUriBasename(url)}" />`).join(`
13
590
  `)}
14
591
  </spine>
15
592
  </package>
16
- `,a=e.map(r=>({dir:!1,basename:w(r),encodingFormat:y.detectMimeTypeFromName(r),uri:r,size:100/e.length,base64:async()=>"",blob:async()=>new Blob,string:async()=>""}));return{filename:"",files:[{dir:!1,basename:"content.opf",uri:"content.opf",size:0,base64:async()=>n,blob:async()=>new Blob,string:async()=>n},...a]}},ie=async e=>new Promise(i=>{const n=new FileReader;n.readAsDataURL(e),n.onloadend=function(){const a=n.result;i(a)}}),oe=async(e,{mimeType:i,direction:n}={mimeType:"text/plain"})=>{const a=`
593
+ `;
594
+ const filesFromUrl = urls.map((url) => ({
595
+ dir: false,
596
+ basename: getUriBasename(url),
597
+ encodingFormat: shared.detectMimeTypeFromName(url),
598
+ uri: url,
599
+ size: 100 / urls.length,
600
+ base64: async () => ``,
601
+ blob: async () => new Blob(),
602
+ string: async () => ``
603
+ }));
604
+ const opfFile = {
605
+ dir: false,
606
+ basename: `content.opf`,
607
+ uri: `content.opf`,
608
+ size: 0,
609
+ base64: async () => opfFileData,
610
+ blob: async () => new Blob(),
611
+ string: async () => opfFileData
612
+ };
613
+ return {
614
+ filename: ``,
615
+ files: [opfFile, ...filesFromUrl]
616
+ };
617
+ };
618
+ const blobToBase64 = async (blob) => new Promise((resolve) => {
619
+ const reader = new FileReader();
620
+ reader.readAsDataURL(blob);
621
+ reader.onloadend = function() {
622
+ const base64data = reader.result;
623
+ resolve(base64data);
624
+ };
625
+ });
626
+ const createArchiveFromText = async (content, {
627
+ mimeType,
628
+ direction
629
+ } = { mimeType: "text/plain" }) => {
630
+ const txtOpfContent = `
17
631
  <?xml version="1.0" encoding="UTF-8"?>
18
632
  <package xmlns="http://www.idpf.org/2007/opf" version="3.0" xml:lang="ja" prefix="rendition: http://www.idpf.org/vocab/rendition/#"
19
633
  unique-identifier="ootuya-id">
@@ -24,9 +638,110 @@
24
638
  <manifest>
25
639
  <item id="p01" href="p01.txt" media-type="text/plain"/>
26
640
  </manifest>
27
- <spine page-progression-direction="${n??"ltr"}">
641
+ <spine page-progression-direction="${direction ?? `ltr`}">
28
642
  <itemref idref="p01" />
29
643
  </spine>
30
644
  </package>
31
- `;return{filename:"content.txt",files:[{dir:!1,basename:w("generated.opf"),uri:"generated.opf",blob:async()=>new Blob([a]),string:async()=>a,base64:async()=>btoa(a),size:0},{dir:!1,basename:w("p01.txt"),uri:"p01.txt",blob:async()=>typeof e=="string"?new Blob([e]):e,string:async()=>typeof e=="string"?e:e.text(),base64:async()=>typeof e=="string"?btoa(e):ie(e),size:typeof e=="string"?e.length:e.size,encodingFormat:i}]}},se=async(e,{orderByAlpha:i,name:n}={})=>{let a=Object.values(e.files);i&&(a=a.sort((r,o)=>T(r.name,o.name)));const t={filename:n||"",files:a.map(r=>({dir:r.dir,basename:w(r.name),uri:r.name,blob:()=>r.async("blob"),string:()=>r.async("string"),base64:()=>r.async("base64"),...r.internalStream&&{stream:r.internalStream},size:r._data.uncompressedSize}))};return b.log("Generated archive",t),t},ce=async(e,{orderByAlpha:i,name:n}={})=>{let a=e;return i&&(a=a.sort((t,r)=>T(t.name,r.name))),{filename:n||"",files:a.map(t=>({dir:t.isDir,basename:w(t.name),uri:t.name,blob:async()=>new Blob([await t.data()]),string:async()=>{const r=await t.data();return String.fromCharCode.apply(null,Array.from(new Uint16Array(r)))},base64:async()=>"",size:t.size}))}},de=({enableReport:e}={})=>{b.enable(!!e)};f.configure=de,f.createArchiveFromArrayBufferList=ce,f.createArchiveFromJszip=se,f.createArchiveFromText=oe,f.createArchiveFromUrls=ae,f.generateManifestFromArchive=re,f.generateResourceFromArchive=_,f.getArchiveOpfInfo=F,Object.defineProperty(f,Symbol.toStringTag,{value:"Module"})});
645
+ `;
646
+ const archive = {
647
+ filename: `content.txt`,
648
+ files: [
649
+ {
650
+ dir: false,
651
+ basename: getUriBasename(`generated.opf`),
652
+ uri: `generated.opf`,
653
+ blob: async () => new Blob([txtOpfContent]),
654
+ string: async () => txtOpfContent,
655
+ base64: async () => btoa(txtOpfContent),
656
+ size: 0
657
+ },
658
+ {
659
+ dir: false,
660
+ basename: getUriBasename(`p01.txt`),
661
+ uri: `p01.txt`,
662
+ blob: async () => {
663
+ if (typeof content === `string`)
664
+ return new Blob([content]);
665
+ return content;
666
+ },
667
+ string: async () => {
668
+ if (typeof content === `string`)
669
+ return content;
670
+ return content.text();
671
+ },
672
+ base64: async () => {
673
+ if (typeof content === `string`)
674
+ return btoa(content);
675
+ return blobToBase64(content);
676
+ },
677
+ size: typeof content === `string` ? content.length : content.size,
678
+ encodingFormat: mimeType
679
+ }
680
+ ]
681
+ };
682
+ return archive;
683
+ };
684
+ const createArchiveFromJszip = async (jszip, { orderByAlpha, name } = {}) => {
685
+ let files = Object.values(jszip.files);
686
+ if (orderByAlpha) {
687
+ files = files.sort((a, b) => sortByTitleComparator(a.name, b.name));
688
+ }
689
+ const archive = {
690
+ filename: name || ``,
691
+ files: files.map((file) => ({
692
+ dir: file.dir,
693
+ basename: getUriBasename(file.name),
694
+ uri: file.name,
695
+ blob: () => file.async(`blob`),
696
+ string: () => file.async(`string`),
697
+ base64: () => file.async(`base64`),
698
+ ...file.internalStream && {
699
+ stream: file.internalStream
700
+ },
701
+ // this is private API
702
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
703
+ // @ts-ignore
704
+ size: file._data.uncompressedSize
705
+ }))
706
+ };
707
+ Report.log("Generated archive", archive);
708
+ return archive;
709
+ };
710
+ const createArchiveFromArrayBufferList = async (list, { orderByAlpha, name } = {}) => {
711
+ let files = list;
712
+ if (orderByAlpha) {
713
+ files = files.sort((a, b) => sortByTitleComparator(a.name, b.name));
714
+ }
715
+ return {
716
+ filename: name || ``,
717
+ files: files.map((file) => ({
718
+ dir: file.isDir,
719
+ basename: getUriBasename(file.name),
720
+ uri: file.name,
721
+ blob: async () => new Blob([await file.data()]),
722
+ string: async () => {
723
+ const data = await file.data();
724
+ return String.fromCharCode.apply(null, Array.from(new Uint16Array(data)));
725
+ },
726
+ base64: async () => {
727
+ return ``;
728
+ },
729
+ size: file.size
730
+ }))
731
+ };
732
+ };
733
+ const configure = ({ enableReport } = {}) => {
734
+ Report.enable(!!enableReport);
735
+ };
736
+ exports2.configure = configure;
737
+ exports2.createArchiveFromArrayBufferList = createArchiveFromArrayBufferList;
738
+ exports2.createArchiveFromJszip = createArchiveFromJszip;
739
+ exports2.createArchiveFromText = createArchiveFromText;
740
+ exports2.createArchiveFromUrls = createArchiveFromUrls;
741
+ exports2.generateManifestFromArchive = generateManifestFromArchive;
742
+ exports2.generateResourceFromArchive = generateResourceFromArchive;
743
+ exports2.generateResourceFromError = generateResourceFromError;
744
+ exports2.getArchiveOpfInfo = getArchiveOpfInfo;
745
+ Object.defineProperty(exports2, Symbol.toStringTag, { value: "Module" });
746
+ });
32
747
  //# sourceMappingURL=prose-streamer.umd.cjs.map