Books: read DRM-free MOBI, AZW and AZW3; refuse Kindle files with DRM

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UaC9HmtHMdRP8dAbN4wAKj
This commit is contained in:
Claude committed 2026-10-24 02:54:34 +00:00
1 parent 07c16ddc25
commit 2e99893c8b
7 files changed
+138 -21

No files matched your search

+55 -14
View File
@@ -3,7 +3,8 @@
// they follow you between devices. Reading uses epub.js, pdf.js and mammoth from /vendor/reader, loaded only when a book is opened or added.
const rdApi = (p, o) => jfetch('/api/read' + p, o);
const rdJson = (m, o) => ({ method: m, headers: { 'content-type': 'application/json' }, body: JSON.stringify(o) });
const RD_LIBS = { epub: ['jszip.min.js', 'epub.min.js'], pdf: ['pdf.min.js'], docx: ['mammoth.browser.min.js'] };
const RD_LIBS = { epub: ['jszip.min.js', 'epub.min.js'], pdf: ['pdf.min.js'], docx: ['mammoth.browser.min.js'], mobi: ['mobi-parser.min.js'] };
const rdKind = ext => ['mobi', 'azw', 'azw3'].includes(ext) ? 'mobi' : ext;
const rdLoaded = {};
async function rdLibs(kind) {
for (const f of RD_LIBS[kind]) {
@@ -43,8 +44,8 @@ async function rdLibrary() {
const cover = b => `<span class="vimg rdcover" style="aspect-ratio:2/3">${b.cover ? `<img loading="lazy" alt="" src="/api/read/book/${b.id}/cover" onerror="this.remove()">` : ''}<em>${esc(b.title)}</em><span class="rdext">${esc(b.ext)}</span>${b.pct > 0 ? `<u class="rdprog"><s style="width:${Math.round(b.pct * 100)}%"></s></u>` : ''}</span>`;
const card = b => `<a class="vcard" href="#/read/open/${b.id}" data-id="${b.id}">${cover(b)}<b>${esc(b.title)}</b><small>${esc(b.author || b.ext.toUpperCase())}${b.pct > 0 ? ' · ' + Math.round(b.pct * 100) + '%' : ''}</small></a>`;
v.innerHTML = `<div class="wrap" id="rdlib"><div class="ptop"><h1>Books</h1><span class="pspace grow"></span><button class="btn" id="rdadd">${icon('plus')}Add books</button></div>
<input type="file" id="rdfile" accept=".epub,.pdf,.docx" multiple hidden>
<div id="rdbody"></div><p class="sub" id="rdhint" style="margin-top:16px">EPUB, PDF and DOCX. Add files with the button or drop them on this page. Your place, bookmarks and highlights follow you to every device.</p></div>`;
<input type="file" id="rdfile" accept=".epub,.pdf,.docx,.mobi,.azw,.azw3" multiple hidden>
<div id="rdbody"></div><p class="sub" id="rdhint" style="margin-top:16px">EPUB, PDF, DOCX, MOBI and AZW3 (without DRM). Add files with the button or drop them on this page. Your place, bookmarks and highlights follow you to every device.</p></div>`;
const draw = () => {
const f = q.trim().toLowerCase(), mine = books.filter(b => !f || (b.title + ' ' + b.author).toLowerCase().includes(f));
const sorted = [...mine].sort(sort === 'title' ? (a, b) => a.title.localeCompare(b.title) : sort === 'author' ? (a, b) => (a.author || '~').localeCompare(b.author || '~') || a.title.localeCompare(b.title) : sort === 'added' ? (a, b) => b.added - a.added : (a, b) => (b.read || b.added) - (a.read || a.added));
@@ -94,14 +95,14 @@ function rdEditBook(b) {
// ---- Adding books: the file goes up as it is; the browser reads the title, author and cover out of it afterwards.
async function rdAddAll(files) {
files = files.filter(f => /\.(epub|pdf|docx)$/i.test(f.name));
if (!files.length) return toast('Choose EPUB, PDF or DOCX files');
let added = 0, failed = 0;
files = files.filter(f => /\.(epub|pdf|docx|mobi|azw3?)$/i.test(f.name));
if (!files.length) return toast('Choose EPUB, PDF, DOCX, MOBI or AZW3 files');
let added = 0, failed = 0, why = '';
for (const [i, f] of files.entries()) {
toast(`Adding ${i + 1} of ${files.length}: ${f.name}`);
try { if (!(await rdAddOne(f)).duplicate) added++; } catch (e) { failed++; toast(f.name + ': ' + e.message); await new Promise(r => setTimeout(r, 1800)); }
try { if (!(await rdAddOne(f)).duplicate) added++; } catch (e) { failed++; why = f.name + ': ' + e.message; toast(why); await new Promise(r => setTimeout(r, 1800)); }
}
toast(added ? `Added ${added} book${added > 1 ? 's' : ''}${failed ? ', ' + failed + ' failed' : ''}` : failed ? 'Nothing was added' : 'Already in your library');
toast(added ? `Added ${added} book${added > 1 ? 's' : ''}${failed ? ', ' + failed + ' failed' : ''}` : failed ? (files.length === 1 ? why : 'Nothing was added') : 'Already in your library');
if (location.hash.startsWith('#/read') && !location.hash.startsWith('#/read/open')) route();
}
async function rdAddOne(file) {
@@ -134,8 +135,18 @@ async function rdMeta(ext, buf) {
} finally { pdf.destroy(); }
return out;
}
if (rdKind(ext) === 'mobi') {
await rdLibs('mobi'); const m = await rdMobiOpen(new Uint8Array(buf.slice(0))), out = {};
try { const md = m.getMetadata(); out.title = md.title; out.author = (md.author || []).join(', '); const cu = m.getCoverImage(); if (cu) { const blob = await (await fetch(cu)).blob(); if (/^image\/(jpeg|png|gif|webp)$/.test(blob.type)) out.cover = blob; } } finally { try { m.destroy(); } catch {} }
return out;
}
return {};
}
/** MOBI 6 and KF8 (AZW3) need different readers: try the newer format first, since the older reader can "open" a KF8 file and show nonsense. */
async function rdMobiOpen(u8) {
try { const k = await MobiParser.initKf8File(u8); if (k.getSpine().length) return k; try { k.destroy(); } catch {} } catch {}
return MobiParser.initMobiFile(u8);
}
// ======================================================= Reader
let rdCur = null; // the open book's reader, so leaving the page can close it
@@ -169,8 +180,8 @@ class RdReader {
this.root = $('#rdroot'); this.applyChrome();
this.hookUi();
try {
await rdLibs(b.ext);
this.A = b.ext === 'epub' ? new RdEpub(this) : b.ext === 'pdf' ? new RdPdf(this) : new RdDocx(this);
await rdLibs(rdKind(b.ext));
this.A = b.ext === 'epub' ? new RdEpub(this) : b.ext === 'pdf' ? new RdPdf(this) : rdKind(b.ext) === 'mobi' ? new RdMobi(this) : new RdDocx(this);
await this.A.open(this.$('#rdstage'), this.loc);
this.$('#rdload').remove();
} catch (e) { if (this.dead) return; this.$('#rdload').innerHTML = `<span class="err">${esc(e.message || 'This book could not be opened')}</span><br><a class="btn ghost" href="#/read" style="margin-top:12px">Back to library</a>`; }
@@ -514,12 +525,15 @@ class RdPdf {
// ======================================================= DOCX (converted to HTML in the browser; shown in a frame that cannot run scripts)
class RdDocx {
constructor(R) { this.R = R; }
async convert() {
const buf = await rdFetchBook(this.R.book.id, 'docx');
return { html: (await mammoth.convertToHtml({ arrayBuffer: buf }, { styleMap: ['p[style-name="Title"] => h1.title:fresh', 'p[style-name="Subtitle"] => p.subtitle:fresh'] })).value, head: '' };
}
async open(stage, loc) {
const R = this.R, buf = await rdFetchBook(R.book.id, 'docx');
const res = await mammoth.convertToHtml({ arrayBuffer: buf }, { styleMap: ['p[style-name="Title"] => h1.title:fresh', 'p[style-name="Subtitle"] => p.subtitle:fresh'] });
const R = this.R, res = await this.convert();
this.f = document.createElement('iframe'); this.f.setAttribute('sandbox', 'allow-same-origin'); this.f.title = R.book.title; this.f.className = 'rdframe';
stage.appendChild(this.f);
this.f.srcdoc = `<!doctype html><html><head><meta charset="utf-8"><style id="base">body{max-width:46em;margin:0 auto;padding:1.2em 6%;overflow-wrap:break-word}table{border-collapse:collapse}td,th{border:1px solid #8888;padding:.3em .5em}h1,h2,h3{line-height:1.25}mark.rdh{border-radius:2px;color:inherit;padding:0}mark.rdh.flash{outline:2px solid #e8590c}mark.rdq{background:#ffd43b88;color:inherit}</style><style id="theme"></style></head><body><article>${res.value}</article></body></html>`;
this.f.srcdoc = `<!doctype html><html><head><meta charset="utf-8"><style id="base">body{max-width:46em;margin:0 auto;padding:1.2em 6%;overflow-wrap:break-word}table{border-collapse:collapse}td,th{border:1px solid #8888;padding:.3em .5em}h1,h2,h3{line-height:1.25}mark.rdh{border-radius:2px;color:inherit;padding:0}mark.rdh.flash{outline:2px solid #e8590c}mark.rdq{background:#ffd43b88;color:inherit}</style><style id="theme"></style>${res.head}</head><body><article>${res.html}</article></body></html>`;
await new Promise(ok => { this.f.onload = ok; });
this.d = this.f.contentDocument; this.w = this.f.contentWindow; this.root = this.d.documentElement;
this.restyle();
@@ -527,12 +541,13 @@ class RdDocx {
this.d.addEventListener('mousedown', () => R.hideSel());
const sel = () => setTimeout(() => this.checkSel(), 30);
this.d.addEventListener('mouseup', sel); this.d.addEventListener('touchend', sel); this.d.addEventListener('keyup', sel);
this.d.addEventListener('click', e => { const s = this.w.getSelection(); if (s && !s.isCollapsed) return; if (e.target.closest('a[href]')) { e.preventDefault(); const a = e.target.closest('a[href]'); if (a.getAttribute('href').startsWith('#')) this.d.getElementById(a.getAttribute('href').slice(1))?.scrollIntoView(); return; } R.toggleBars(); });
this.d.addEventListener('click', e => { const s = this.w.getSelection(); if (s && !s.isCollapsed) return; if (e.target.closest('a[href]')) { e.preventDefault(); const a = e.target.closest('a[href]'); if (!this.link(a)) this.d.getElementById((a.getAttribute('href') || '').replace(/^#/, ''))?.scrollIntoView(); return; } R.toggleBars(); });
this.d.addEventListener('scroll', () => { if (!this.raf) this.raf = requestAnimationFrame(() => { this.raf = 0; this.report(); }); }, { passive: true });
this.w.addEventListener('scroll', () => { if (!this.raf) this.raf = requestAnimationFrame(() => { this.raf = 0; this.report(); }); }, { passive: true });
for (const n of R.notes) this.drawNote(n);
const m = /^o:(\d+)/.exec(loc || ''); if (m) this.gotoOffset(+m[1]); this.report();
}
link() { return false; }
scroller() { return this.d.scrollingElement || this.root; }
restyle(k) {
const R = this.R, t = rdTheme(R.P); this.d.getElementById('theme').textContent = rdCss(R.P, t); R.root.style.setProperty('--rd-bg', t.bg);
@@ -577,3 +592,29 @@ class RdDocx {
resize() {}
destroy() {}
}
// ======================================================= MOBI / AZW / AZW3 (DRM-free): every chapter is joined into one page, then read like a DOCX
class RdMobi extends RdDocx {
async convert() {
const buf = new Uint8Array(await rdFetchBook(this.R.book.id, 'mobi'));
this.m = await rdMobiOpen(buf); const spine = this.m.getSpine(), css = new Set(), parts = [];
for (const ch of spine) { const c = this.m.loadChapter(ch.id); if (!c) continue; (c.css || []).forEach(x => css.add(x.href)); parts.push(`<section class="rdch" id="rdch-${esc(ch.id)}" data-ch="${esc(ch.id)}">${c.html}</section>`); }
if (!parts.length) throw new Error('This book has no readable text. It may have DRM.');
return { html: parts.join(''), head: [...css].map(h => `<link rel="stylesheet" href="${esc(h)}">`).join('') };
}
/** a link inside the book: the parser says which chapter (and where in it) it points to */
link(a) {
const href = a.getAttribute('href') || ''; if (/^(https?:|mailto:)/i.test(href)) { window.open(href, '_blank', 'noopener'); return true; }
let r; try { r = this.m.resolveHref(href); } catch {} if (!r) return false;
const sec = this.d.getElementById('rdch-' + r.id); let el = sec; if (sec && r.selector) { try { el = sec.querySelector(r.selector) || sec; } catch {} }
if (el) { el.scrollIntoView(); return true; } return false;
}
async toc() {
const out = [], walk = (items, d) => (items || []).forEach(t => {
let loc = null; try { const r = this.m.resolveHref(t.href); const sec = r && this.d.getElementById('rdch-' + r.id); let el = sec; if (sec && r.selector) { try { el = sec.querySelector(r.selector) || sec; } catch {} } if (el) { const w = this.d.createTreeWalker(el, NodeFilter.SHOW_TEXT), first = w.nextNode(); if (first) loc = 'o:' + this.offsetTo(first, 0); } } catch {}
if (loc) out.push({ label: String(t.label || '').trim().slice(0, 120) || 'Untitled', loc, depth: d }); walk(t.children, d + 1); });
walk(this.m.getToc(), 0);
return out.length ? out : super.toc();
}
destroy() { try { this.m && this.m.destroy(); } catch {} }
}
+21
View File
@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2024 hhk-png
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
+16
View File
@@ -0,0 +1,16 @@
var MobiParser=(()=>{var Ut=Object.create;var Se=Object.defineProperty;var Mt=Object.getOwnPropertyDescriptor;var zt=Object.getOwnPropertyNames;var kt=Object.getPrototypeOf,Ht=Object.prototype.hasOwnProperty;var Gt=(r=>typeof require!="undefined"?require:typeof Proxy!="undefined"?new Proxy(r,{get:(e,t)=>(typeof require!="undefined"?require:e)[t]}):r)(function(r){if(typeof require!="undefined")return require.apply(this,arguments);throw Error('Dynamic require of "'+r+'" is not supported')});var Me=(r,e)=>()=>{try{return e||r((e={exports:{}}).exports,e),e.exports}catch(t){throw e=0,t}},jt=(r,e)=>{for(var t in e)Se(r,t,{get:e[t],enumerable:!0})},Ze=(r,e,t,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of zt(e))!Ht.call(r,o)&&o!==t&&Se(r,o,{get:()=>e[o],enumerable:!(s=Mt(e,o))||s.enumerable});return r};var ze=(r,e,t)=>(t=r!=null?Ut(kt(r)):{},Ze(e||!r||!r.__esModule?Se(t,"default",{value:r,enumerable:!0}):t,r)),Vt=r=>Ze(Se({},"__esModule",{value:!0}),r);var at=Me((sr,ot)=>{"use strict";function ie(r){if(typeof r!="string")throw new TypeError("Path must be a string. Received "+JSON.stringify(r))}function st(r,e){for(var t="",s=0,o=-1,l=0,a,u=0;u<=r.length;++u){if(u<r.length)a=r.charCodeAt(u);else{if(a===47)break;a=47}if(a===47){if(!(o===u-1||l===1))if(o!==u-1&&l===2){if(t.length<2||s!==2||t.charCodeAt(t.length-1)!==46||t.charCodeAt(t.length-2)!==46){if(t.length>2){var d=t.lastIndexOf("/");if(d!==t.length-1){d===-1?(t="",s=0):(t=t.slice(0,d),s=t.length-1-t.lastIndexOf("/")),o=u,l=0;continue}}else if(t.length===2||t.length===1){t="",s=0,o=u,l=0;continue}}e&&(t.length>0?t+="/..":t="..",s=2)}else t.length>0?t+="/"+r.slice(o+1,u):t=r.slice(o+1,u),s=u-o-1;o=u,l=0}else a===46&&l!==-1?++l:l=-1}return t}function on(r,e){var t=e.dir||e.root,s=e.base||(e.name||"")+(e.ext||"");return t?t===e.root?t+s:t+r+s:s}var he={resolve:function(){for(var e="",t=!1,s,o=arguments.length-1;o>=-1&&!t;o--){var l;o>=0?l=arguments[o]:(s===void 0&&(s=process.cwd()),l=s),ie(l),l.length!==0&&(e=l+"/"+e,t=l.charCodeAt(0)===47)}return e=st(e,!t),t?e.length>0?"/"+e:"/":e.length>0?e:"."},normalize:function(e){if(ie(e),e.length===0)return".";var t=e.charCodeAt(0)===47,s=e.charCodeAt(e.length-1)===47;return e=st(e,!t),e.length===0&&!t&&(e="."),e.length>0&&s&&(e+="/"),t?"/"+e:e},isAbsolute:function(e){return ie(e),e.length>0&&e.charCodeAt(0)===47},join:function(){if(arguments.length===0)return".";for(var e,t=0;t<arguments.length;++t){var s=arguments[t];ie(s),s.length>0&&(e===void 0?e=s:e+="/"+s)}return e===void 0?".":he.normalize(e)},relative:function(e,t){if(ie(e),ie(t),e===t||(e=he.resolve(e),t=he.resolve(t),e===t))return"";for(var s=1;s<e.length&&e.charCodeAt(s)===47;++s);for(var o=e.length,l=o-s,a=1;a<t.length&&t.charCodeAt(a)===47;++a);for(var u=t.length,d=u-a,m=l<d?l:d,v=-1,g=0;g<=m;++g){if(g===m){if(d>m){if(t.charCodeAt(a+g)===47)return t.slice(a+g+1);if(g===0)return t.slice(a+g)}else l>m&&(e.charCodeAt(s+g)===47?v=g:g===0&&(v=0));break}var p=e.charCodeAt(s+g),y=t.charCodeAt(a+g);if(p!==y)break;p===47&&(v=g)}var b="";for(g=s+v+1;g<=o;++g)(g===o||e.charCodeAt(g)===47)&&(b.length===0?b+="..":b+="/..");return b.length>0?b+t.slice(a+v):(a+=v,t.charCodeAt(a)===47&&++a,t.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(ie(e),e.length===0)return".";for(var t=e.charCodeAt(0),s=t===47,o=-1,l=!0,a=e.length-1;a>=1;--a)if(t=e.charCodeAt(a),t===47){if(!l){o=a;break}}else l=!1;return o===-1?s?"/":".":s&&o===1?"//":e.slice(0,o)},basename:function(e,t){if(t!==void 0&&typeof t!="string")throw new TypeError('"ext" argument must be a string');ie(e);var s=0,o=-1,l=!0,a;if(t!==void 0&&t.length>0&&t.length<=e.length){if(t.length===e.length&&t===e)return"";var u=t.length-1,d=-1;for(a=e.length-1;a>=0;--a){var m=e.charCodeAt(a);if(m===47){if(!l){s=a+1;break}}else d===-1&&(l=!1,d=a+1),u>=0&&(m===t.charCodeAt(u)?--u===-1&&(o=a):(u=-1,o=d))}return s===o?o=d:o===-1&&(o=e.length),e.slice(s,o)}else{for(a=e.length-1;a>=0;--a)if(e.charCodeAt(a)===47){if(!l){s=a+1;break}}else o===-1&&(l=!1,o=a+1);return o===-1?"":e.slice(s,o)}},extname:function(e){ie(e);for(var t=-1,s=0,o=-1,l=!0,a=0,u=e.length-1;u>=0;--u){var d=e.charCodeAt(u);if(d===47){if(!l){s=u+1;break}continue}o===-1&&(l=!1,o=u+1),d===46?t===-1?t=u:a!==1&&(a=1):t!==-1&&(a=-1)}return t===-1||o===-1||a===0||a===1&&t===o-1&&t===s+1?"":e.slice(t,o)},format:function(e){if(e===null||typeof e!="object")throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return on("/",e)},parse:function(e){ie(e);var t={root:"",dir:"",base:"",ext:"",name:""};if(e.length===0)return t;var s=e.charCodeAt(0),o=s===47,l;o?(t.root="/",l=1):l=0;for(var a=-1,u=0,d=-1,m=!0,v=e.length-1,g=0;v>=l;--v){if(s=e.charCodeAt(v),s===47){if(!m){u=v+1;break}continue}d===-1&&(m=!1,d=v+1),s===46?a===-1?a=v:g!==1&&(g=1):a!==-1&&(g=-1)}return a===-1||d===-1||g===0||g===1&&a===d-1&&a===u+1?d!==-1&&(u===0&&o?t.base=t.name=e.slice(1,d):t.base=t.name=e.slice(u,d)):(u===0&&o?(t.name=e.slice(1,a),t.baseLine truncated
`||i==="\r"||i===" "}function R(i){return i==='"'||i==="'"}function X(i){return i===">"||I(i)}function F(i,n){return i.test(n)}function k(i,n){return!F(i,n)}var f=0;r.STATE={BEGIN:f++,BEGIN_WHITESPACE:f++,TEXT:f++,TEXT_ENTITY:f++,OPEN_WAKA:f++,SGML_DECL:f++,SGML_DECL_QUOTED:f++,DOCTYPE:f++,DOCTYPE_QUOTED:f++,DOCTYPE_DTD:f++,DOCTYPE_DTD_QUOTED:f++,COMMENT_STARTING:f++,COMMENT:f++,COMMENT_ENDING:f++,COMMENT_ENDED:f++,CDATA:f++,CDATA_ENDING:f++,CDATA_ENDING_2:f++,PROC_INST:f++,PROC_INST_BODY:f++,PROC_INST_ENDING:f++,OPEN_TAG:f++,OPEN_TAG_SLASH:f++,ATTRIB:f++,ATTRIB_NAME:f++,ATTRIB_NAME_SAW_WHITE:f++,ATTRIB_VALUE:f++,ATTRIB_VALUE_QUOTED:f++,ATTRIB_VALUE_CLOSED:f++,ATTRIB_VALUE_UNQUOTED:f++,ATTRIB_VALUE_ENTITY_Q:f++,ATTRIB_VALUE_ENTITY_U:f++,CLOSE_TAG:f++,CLOSE_TAG_SAW_WHITE:f++,SCRIPT:f++,SCRIPT_ENDING:f++},r.XML_ENTITIES=Object.assign(Object.create(null),{amp:"&",gt:">",lt:"<",quot:'"',apos:"'"}),r.ENTITIES=Object.assign(Object.create(null),{amp:"&",gt:">",lt:"<",quot:'"',apos:"'",AElig:198,Aacute:193,Acirc:194,Agrave:192,Aring:197,Atilde:195,Auml:196,Ccedil:199,ETH:208,Eacute:201,Ecirc:202,Egrave:200,Euml:203,Iacute:205,Icirc:206,Igrave:204,Iuml:207,Ntilde:209,Oacute:211,Ocirc:212,Ograve:210,Oslash:216,Otilde:213,Ouml:214,THORN:222,Uacute:218,Ucirc:219,Ugrave:217,Uuml:220,Yacute:221,aacute:225,acirc:226,aelig:230,agrave:224,aring:229,atilde:227,auml:228,ccedil:231,eacute:233,ecirc:234,egrave:232,eth:240,euml:235,iacute:237,icirc:238,igrave:236,iuml:239,ntilde:241,oacute:243,ocirc:244,ograve:242,oslash:248,otilde:245,ouml:246,szlig:223,thorn:254,uacute:250,ucirc:251,ugrave:249,uuml:252,yacute:253,yuml:255,copy:169,reg:174,nbsp:160,iexcl:161,cent:162,pound:163,curren:164,yen:165,brvbar:166,sect:167,uml:168,ordf:170,laquo:171,not:172,shy:173,macr:175,deg:176,plusmn:177,sup1:185,sup2:178,sup3:179,acute:180,micro:181,para:182,middot:183,cedil:184,ordm:186,raquo:187,frac14:188,frac12:189,frac34:190,iquest:191,times:215,divide:247,OElig:338,oelig:339,Scaron:352,scaron:353,Yuml:376,fnof:402,circ:710,tilde:732,Alpha:913,Beta:914,Gamma:915,Delta:916,Epsilon:917,Zeta:918,Eta:919,Theta:920,Iota:921,Kappa:922,Lambda:923,Mu:924,Nu:925,Xi:926,Omicron:927,Pi:928,Rho:929,Sigma:931,Tau:932,Upsilon:933,Phi:934,Chi:935,Psi:936,Omega:937,alpha:945,beta:946,gamma:947,delta:948,epsilon:949,zeta:950,eta:951,theta:952,iota:953,kappa:954,lambda:955,mu:956,nu:957,xi:958,omicron:959,pi:960,rho:961,sigmaf:962,sigma:963,tau:964,upsilon:965,phi:966,chi:967,psi:968,omega:969,thetasym:977,upsih:978,piv:982,ensp:8194,emsp:8195,thinsp:8201,zwnj:8204,zwj:8205,lrm:8206,rlm:8207,ndash:8211,mdash:8212,lsquo:8216,rsquo:8217,sbquo:8218,ldquo:8220,rdquo:8221,bdquo:8222,dagger:8224,Dagger:8225,bull:8226,hellip:8230,permil:8240,prime:8242,Prime:8243,lsaquo:8249,rsaquo:8250,oline:8254,frasl:8260,euro:8364,image:8465,weierp:8472,real:8476,trade:8482,alefsym:8501,larr:8592,uarr:8593,rarr:8594,darr:8595,harr:8596,crarr:8629,lArr:8656,uArr:8657,rArr:8658,dArr:8659,hArr:8660,forall:8704,part:8706,exist:8707,empty:8709,nabla:8711,isin:8712,notin:8713,ni:8715,prod:8719,sum:8721,minus:8722,lowast:8727,radic:8730,prop:8733,infin:8734,ang:8736,and:8743,or:8744,cap:8745,cup:8746,int:8747,there4:8756,sim:8764,cong:8773,asymp:8776,ne:8800,equiv:8801,le:8804,ge:8805,sub:8834,sup:8835,nsub:8836,sube:8838,supe:8839,oplus:8853,otimes:8855,perp:8869,sdot:8901,lceil:8968,rceil:8969,lfloor:8970,rfloor:8971,lang:9001,rang:9002,loz:9674,spades:9824,clubs:9827,hearts:9829,diams:9830}),Object.keys(r.ENTITIES).forEach(function(i){var n=r.ENTITIES[i],h=typeof n=="number"?String.fromCharCode(n):n;r.ENTITIES[i]=h});for(var W in r.STATE)r.STATE[r.STATE[W]]=W;f=r.STATE;function _(i,n,h){i[n]&&i[n](h)}function J(i){var n=i&&i.match(/(?:^|\s)encoding\s*=\s*(['"])([^'"]+)\1/i);return n?n[2]:null}function ce(i){return i?i.toLowerCase().replace(/[^a-z0-9]/g,""):null}function ne(i,n){let h=ce(i),c=ce(n);return!h||!c?!0:c==="utf16"?h==="utf16le"||h==="utf16be":h===c}function Y(i,n){if(!(!i.strict||!i.encoding||!n||n.name!=="xml")){var h=J(n.body);h&&!ne(i.encoding,h)&&N(i,"XML declaration encoding "+h+" does not match detected stream encoding "+i.encoding.toUpperCase())}}function A(i,n,h){i.textNode&&U(i),_(i,n,h)}function U(i){i.textNode=pe(i.opt,i.textNode),i.textNode&&_(i,"ontext",i.textNode),i.textNode=""}function pe(i,n){return i.trim&&(n=n.trim()),i.normalize&&(n=n.replace(/\s+/g," ")),n}function z(i,n){return U(i),i.trackPosition&&(n+=`
Line: `+i.line+`
Column: `+i.column+`
Char: `+i.c),n=new Error(n),i.error=n,_(i,"onerror",n),i}function xe(i){return i.sawRoot&&!i.closedRoot&&N(i,"Unclosed root tag"),i.state!==f.BEGIN&&i.state!==f.BEGIN_WHITESPACE&&i.state!==f.TEXT&&z(i,"Unexpected end"),U(i),i.c="",i.closed=!0,_(i,"onend"),t.call(i,i.strict,i.opt),i}function N(i,n){if(typeof i!="object"||!(i instanceof t))throw new Error("bad call to strictFail");i.strict&&z(i,n)}function me(i){i.strict||(i.tagName=i.tagName[i.looseCase]());var n=i.tags[i.tags.length-1]||i,h=i.tag={name:i.tagName,attributes:{}};i.opt.xmlns&&(h.ns=n.ns),i.attribList.length=0,A(i,"onopentagstart",h)}function re(i,n){var h=i.indexOf(":"),c=h<0?["",i]:i.split(":"),S=c[0],L=c[1];return n&&i==="xmlns"&&(S="xmlns",L=""),{prefix:S,local:L}}function fe(i){if(i.strict||(i.attribName=i.attribName[i.looseCase]()),i.attribList.indexOf(i.attribName)!==-1||i.tag.attributes.hasOwnProperty(i.attribName)){i.attribName=i.attribValue="";return}if(i.opt.xmlns){var n=re(i.attribName,!0),h=n.prefix,c=n.local;if(h==="xmlns")if(c==="xml"&&i.attribValue!==y)N(i,"xml: prefix must be bound to "+y+`
Actual: `+i.attribValue);else if(c==="xmlns"&&i.attribValue!==b)N(i,"xmlns: prefix must be bound to "+b+`
Actual: `+i.attribValue);else{var S=i.tag,L=i.tags[i.tags.length-1]||i;S.ns===L.ns&&(S.ns=Object.create(L.ns)),S.ns[c]=i.attribValue}i.attribList.push([i.attribName,i.attribValue])}else i.tag.attributes[i.attribName]=i.attribValue,A(i,"onattribute",{name:i.attribName,value:i.attribValue});i.attribName=i.attribValue=""}function q(i,n){if(i.opt.xmlns){var h=i.tag,c=re(i.tagName);h.prefix=c.prefix,h.local=c.local,h.uri=h.ns[c.prefix]||"",h.prefix&&!h.uri&&(N(i,"Unbound namespace prefix: "+JSON.stringify(i.tagName)),h.uri=c.prefix);var S=i.tags[i.tags.length-1]||i;h.ns&&S.ns!==h.ns&&Object.keys(h.ns).forEach(function($e){A(i,"onopennamespace",{prefix:$e,uri:h.ns[$e]})});for(var L=0,P=i.attribList.length;L<P;L++){var j=i.attribList[L],V=j[0],se=j[1],M=re(V,!0),oe=M.prefix,Bt=M.local,We=oe===""?"":h.ns[oe]||"",Ue={name:V,value:se,prefix:oe,local:Bt,uri:We};oe&&oe!=="xmlns"&&!We&&(N(i,"Unbound namespace prefix: "+JSON.stringify(oe)),Ue.uri=oe),i.tag.attributes[V]=Ue,A(i,"onattribute",Ue)}i.attribList.length=0}i.tag.isSelfClosing=!!n,i.sawRoot=!0,i.tags.push(i.tag),A(i,"onopentag",i.tag),n||(!i.noscript&&i.tagName.toLowerCase()==="script"?i.state=f.SCRIPT:i.state=f.TEXT,i.tag=null,i.tagName=""),i.attribName=i.attribValue="",i.attribList.length=0}function le(i){if(!i.tagName){N(i,"Weird empty close tag."),i.textNode+="</>",i.state=f.TEXT;return}if(i.script){if(i.tagName!=="script"){i.script+="</"+i.tagName+">",i.tagName="",i.state=f.SCRIPT;return}A(i,"onscript",i.script),i.script=""}var n=i.tags.length,h=i.tagName;i.strict||(h=h[i.looseCase]());for(var c=h;n--;){var S=i.tags[n];if(S.name!==c)N(i,"Unexpected close tag");else break}if(n<0){N(i,"Unmatched closing tag: "+i.tagName),i.textNode+="</"+i.tagName+">",i.state=f.TEXT;return}i.tagName=h;for(var L=i.tags.length;L-- >n;){var P=i.tag=i.tags.pop();i.tagName=i.tag.name,A(i,"onclosetag",i.tagName);var j={};for(var V in P.ns)j[V]=P.ns[V];var se=i.tags[i.tags.length-1]||i;i.opt.xmlns&&P.ns!==se.ns&&Object.keys(P.ns).forEach(function(M){var oe=P.ns[M];A(i,"onclosenamespace",{prefix:M,uri:oe})})}n===0&&(i.closedRoot=!0),i.tagName=i.attribValue=i.attribName="",i.attribList.length=0,i.state=f.TEXT}function ye(i){var n=i.entity,h=n.toLowerCase(),c,S="";return i.ENTITIES[n]?i.ENTITIES[n]:i.ENTITIES[h]?i.ENTITIES[h]:(n=h,n.charAt(0)==="#"&&(n.charAt(1)==="x"?(n=n.slice(2),c=parseInt(n,16),S=c.toString(16)):(n=n.slice(1),c=parseInt(n,10),S=c.toString(10))),n=n.replace(/^0+/,""),isNaN(c)||S.toLowerCase()!==n||c<0||c>1114111||!Ne(c)?(N(i,"Invalid character entity"),"&"+i.entity+";"):String.fromCodePoint(c))}function Ne(i){return i===9||i===10||i===13||i>=32&&i<=55295||i>=57344&&i<=65533||i>=65536&&i<=1114111}function Te(i,n){n==="<"?(i.state=f.OPEN_WAKA,i.startTagPosition=i.position):I(n)||(N(i,"Non-whitespace before first tag."),i.textNode=n,i.state=f.TEXT)}function be(i,n){var h="";return n<i.length&&(h=i.charAt(n)),h}function Ie(i){var n=this;if(this.error)throw this.error;if(n.closed)return z(n,"Cannot write after close. Assign an onready handler.");if(i===null)return xe(n);typeof i=="object"&&(i=i.toString());for(var h=0,c="";c=be(i,h++),n.c=c,!!c;)switch(n.trackPosition&&(n.position++,c===`
`?(n.line++,n.column=0):n.column++),n.state){case f.BEGIN:if(n.state=f.BEGIN_WHITESPACE,c==="\uFEFF")continue;Te(n,c);continue;case f.BEGIN_WHITESPACE:Te(n,c);continue;case f.TEXT:if(n.sawRoot&&!n.closedRoot){for(var L=h-1;c&&c!=="<"&&c!=="&";)c=be(i,h++),c&&n.trackPosition&&(n.position++,c===`
`?(n.line++,n.column=0):n.column++);n.textNode+=i.substring(L,h-1)}c==="<"&&!(n.sawRoot&&n.closedRoot&&!n.strict)?(n.state=f.OPEN_WAKA,n.startTagPosition=n.position):(!I(c)&&(!n.sawRoot||n.closedRoot)&&N(n,"Text data outside of root node."),c==="&"?n.state=f.TEXT_ENTITY:n.textNode+=c);continue;case f.SCRIPT:c==="<"?n.state=f.SCRIPT_ENDING:n.script+=c;continue;case f.SCRIPT_ENDING:c==="/"?n.state=f.CLOSE_TAG:(n.script+="<"+c,n.state=f.SCRIPT);continue;case f.OPEN_WAKA:if(c==="!")n.state=f.SGML_DECL,n.sgmlDecl="";else if(!I(c))if(F(w,c))n.state=f.OPEN_TAG,n.tagName=c;else if(c==="/")n.state=f.CLOSE_TAG,n.tagName="";else if(c==="?")n.state=f.PROC_INST,n.procInstName=n.procInstBody="";else{if(N(n,"Unencoded <"),n.startTagPosition+1<n.position){var S=n.position-n.startTagPosition;c=new Array(S).join(" ")+c}n.textNode+="<"+c,n.state=f.TEXT}continue;case f.SGML_DECL:if(n.sgmlDecl+c==="--"){n.state=f.COMMENT,n.comment="",n.sgmlDecl="";continue}n.doctype&&n.doctype!==!0&&n.sgmlDecl?(n.state=f.DOCTYPE_DTD,n.doctype+="<!"+n.sgmlDecl+c,n.sgmlDecl=""):g.test(n.sgmlDecl+c)?(A(n,"onopencdata"),n.state=f.CDATA,n.sgmlDecl="",n.cdata=""):p.test(n.sgmlDecl+c)?(n.state=f.DOCTYPE,(n.doctype||n.sawRoot)&&N(n,"Inappropriately located doctype declaration"),n.doctype="",n.sgmlDecl=""):c===">"?(A(n,"onsgmldeclaration",n.sgmlDecl),n.sgmlDecl="",n.state=f.TEXT):(R(c)&&(n.state=f.SGML_DECL_QUOTED),n.sgmlDecl+=c);continue;case f.SGML_DECL_QUOTED:c===n.q&&(n.state=f.SGML_DECL,n.q=""),n.sgmlDecl+=c;continue;case f.DOCTYPE:c===">"?(n.state=f.TEXT,A(n,"ondoctype",n.doctype),n.doctype=!0):(n.doctype+=c,c==="["?n.state=f.DOCTYPE_DTD:R(c)&&(n.state=f.DOCTYPE_QUOTED,n.q=c));continue;case f.DOCTYPE_QUOTED:n.doctype+=c,c===n.q&&(n.q="",n.state=f.DOCTYPE);continue;case f.DOCTYPE_DTD:c==="]"?(n.doctype+=c,n.state=f.DOCTYPE):c==="<"?(n.state=f.OPEN_WAKA,n.startTagPosition=n.position):R(c)?(n.doctype+=c,n.state=f.DOCTYPE_DTD_QUOTED,n.q=c):n.doctype+=c;continue;case f.DOCTYPE_DTD_QUOTED:n.doctype+=c,c===n.q&&(n.state=f.DOCTYPE_DTD,n.q="");continue;case f.COMMENT:c==="-"?n.state=f.COMMENT_ENDING:n.comment+=c;continue;case f.COMMENT_ENDING:c==="-"?(n.state=f.COMMENT_ENDED,n.comment=pe(n.opt,n.comment),n.comment&&A(n,"oncomment",n.comment),n.comment=""):(n.comment+="-"+c,n.state=f.COMMENT);continue;case f.COMMENT_ENDED:c!==">"?(N(n,"Malformed comment"),n.comment+="--"+c,n.state=f.COMMENT):n.doctype&&n.doctype!==!0?n.state=f.DOCTYPE_DTD:n.state=f.TEXT;continue;case f.CDATA:for(var L=h-1;c&&c!=="]";)c=be(i,h++),c&&n.trackPosition&&(n.position++,c===`
`?(n.line++,n.column=0):n.column++);n.cdata+=i.substring(L,h-1),c==="]"&&(n.state=f.CDATA_ENDING);continue;case f.CDATA_ENDING:c==="]"?n.state=f.CDATA_ENDING_2:(n.cdata+="]"+c,n.state=f.CDATA);continue;case f.CDATA_ENDING_2:c===">"?(n.cdata&&A(n,"oncdata",n.cdata),A(n,"onclosecdata"),n.cdata="",n.state=f.TEXT):c==="]"?n.cdata+="]":(n.cdata+="]]"+c,n.state=f.CDATA);continue;case f.PROC_INST:c==="?"?n.state=f.PROC_INST_ENDING:I(c)?n.state=f.PROC_INST_BODY:n.procInstName+=c;continue;case f.PROC_INST_BODY:if(!n.procInstBody&&I(c))continue;c==="?"?n.state=f.PROC_INST_ENDING:n.procInstBody+=c;continue;case f.PROC_INST_ENDING:if(c===">"){let se={name:n.procInstName,body:n.procInstBody};Y(n,se),A(n,"onprocessinginstruction",se),n.procInstName=n.procInstBody="",n.state=f.TEXT}else n.procInstBody+="?"+c,n.state=f.PROC_INST_BODY;continue;case f.OPEN_TAG:F(C,c)?n.tagName+=c:(me(n),c===">"?q(n):c==="/"?n.state=f.OPEN_TAG_SLASH:(I(c)||N(n,"Invalid character in tag name"),n.state=f.ATTRIB));continue;case f.OPEN_TAG_SLASH:c===">"?(q(n,!0),le(n)):(N(n,"Forward-slash in opening tag not followed by >"),n.state=f.ATTRIB);continue;case f.ATTRIB:if(I(c))continue;c===">"?q(n):c==="/"?n.state=f.OPEN_TAG_SLASH:F(w,c)?(n.attribName=c,n.attribValue="",n.state=f.ATTRIB_NAME):N(n,"Invalid attribute name");continue;case f.ATTRIB_NAME:c==="="?n.state=f.ATTRIB_VALUE:c===">"?(N(n,"Attribute without value"),n.attribValue=n.attribName,fe(n),q(n)):I(c)?n.state=f.ATTRIB_NAME_SAW_WHITE:F(C,c)?n.attribName+=c:N(n,"Invalid attribute name");continue;case f.ATTRIB_NAME_SAW_WHITE:if(c==="=")n.state=f.ATTRIB_VALUE;else{if(I(c))continue;N(n,"Attribute without value"),n.tag.attributes[n.attribName]="",n.attribValue="",A(n,"onattribute",{name:n.attribName,value:""}),n.attribName="",c===">"?q(n):F(w,c)?(n.attribName=c,n.state=f.ATTRIB_NAME):(N(n,"Invalid attribute name"),n.state=f.ATTRIB)}continue;case f.ATTRIB_VALUE:if(I(c))continue;R(c)?(n.q=c,n.state=f.ATTRIB_VALUE_QUOTED):(n.opt.unquotedAttributeValues||z(n,"Unquoted attribute value"),n.state=f.ATTRIB_VALUE_UNQUOTED,n.attribValue=c);continue;case f.ATTRIB_VALUE_QUOTED:if(c!==n.q){c==="&"?n.state=f.ATTRIB_VALUE_ENTITY_Q:n.attribValue+=c;continue}fe(n),n.q="",n.state=f.ATTRIB_VALUE_CLOSED;continue;case f.ATTRIB_VALUE_CLOSED:I(c)?n.state=f.ATTRIB:c===">"?q(n):c==="/"?n.state=f.OPEN_TAG_SLASH:F(w,c)?(N(n,"No whitespace between attributes"),n.attribName=c,n.attribValue="",n.state=f.ATTRIB_NAME):N(n,"Invalid attribute name");continue;case f.ATTRIB_VALUE_UNQUOTED:if(!X(c)){c==="&"?n.state=f.ATTRIB_VALUE_ENTITY_U:n.attribValue+=c;continue}fe(n),c===">"?q(n):n.state=f.ATTRIB;continue;case f.CLOSE_TAG:if(n.tagName)c===">"?le(n):F(C,c)?n.tagName+=c:n.script?(n.script+="</"+n.tagName+c,n.tagName="",n.state=f.SCRIPT):(I(c)||N(n,"Invalid tagname in closing tag"),n.state=f.CLOSE_TAG_SAW_WHITE);else{if(I(c))continue;k(w,c)?n.script?(n.script+="</"+c,n.state=f.SCRIPT):N(n,"Invalid tagname in closing tag."):n.tagName=c}continue;case f.CLOSE_TAG_SAW_WHITE:if(I(c))continue;c===">"?le(n):N(n,"Invalid characters in closing tag");continue;case f.TEXT_ENTITY:case f.ATTRIB_VALUE_ENTITY_Q:case f.ATTRIB_VALUE_ENTITY_U:var P,j;switch(n.state){case f.TEXT_ENTITY:P=f.TEXT,j="textNode";break;case f.ATTRIB_VALUE_ENTITY_Q:P=f.ATTRIB_VALUE_QUOTED,j="attribValue";break;case f.ATTRIB_VALUE_ENTITY_U:P=f.ATTRIB_VALUE_UNQUOTED,j="attribValue";break}if(c===";"){var V=ye(n);n.opt.unparsedEntities&&!Object.values(r.XML_ENTITIES).includes(V)?((n.entityCount+=1)>n.opt.maxEntityCount&&z(n,"Parsed entity count exceeds max entity count"),(n.entityDepth+=1)>n.opt.maxEntityDepth&&z(n,"Parsed entity depth exceeds max entity depth"),n.entity="",n.state=P,n.write(V),n.entityDepth-=1):(n[j]+=V,n.entity="",n.state=P)}else F(n.entity.length?E:O,c)?n.entity+=c:(N(n,"Invalid character in entity name"),n[j]+="&"+n.entity+c,n.entity="",n.state=P);continue;default:throw new Error(n,"Unknown state: "+n.state)}return n.position>=n.bufferCheckPosition&&s(n),n}String.fromCodePoint||(function(){var i=String.fromCharCode,n=Math.floor,h=function(){var c=16384,S=[],L,P,j=-1,V=arguments.length;if(!V)return"";for(var se="";++j<V;){var M=Number(arguments[j]);if(!isFinite(M)||M<0||M>1114111||n(M)!==M)throw RangeError("Invalid code point: "+M);M<=65535?S.push(M):(M-=65536,L=(M>>10)+55296,P=M%1024+56320,S.push(L,P)),(j+1===V||S.length>c)&&(se+=i.apply(null,S),S.length=0)}return se};Object.defineProperty?Object.defineProperty(String,"fromCodePoint",{value:h,configurable:!0,writable:!0}):String.fromCodePoint=h})()})(typeof _e=="undefined"?_e.sax={}:_e)});var tr={};jt(tr,{initKf8File:()=>Rt,initMobiFile:()=>Pt});var $=Uint8Array,ue=Uint16Array,Xt=Int32Array,Qe=new $([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),Ke=new $([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),Yt=new $([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),Je=function(r,e){for(var t=new ue(31),s=0;s<31;++s)t[s]=e+=1<<r[s-1];for(var o=new Xt(t[30]),s=1;s<30;++ Line truncated
`},headless:!1,chunkSize:1e4,emptyTag:"",cdata:!1}};function pn(r){return r.toLowerCase()}function mn(r){return typeof r=="object"&&r!==null&&Object.keys(r).length===0}function Fe(r,e,t){for(let s of r)e=s(e,t);return e}function de(r,e,t){let s=Object.create(null);s.value=t,s.writable=!0,s.enumerable=!0,s.configurable=!0,Object.defineProperty(r,e,s)}var Ve=class extends wt.EventEmitter{constructor(e){super(),Z(this,"options"),Z(this,"remaining",""),Z(this,"saxParser"),Z(this,"resultObject",null),Z(this,"EXPLICIT_CHARKEY"),Z(this,"errThrown",!1),Z(this,"ended",!1),Z(this,"processAsync",()=>{try{if(this.remaining.length<=this.options.chunkSize){let t=this.remaining;this.remaining="",this.saxParser=this.saxParser.write(t),this.saxParser.close()}else{let t=this.remaining.slice(0,this.options.chunkSize);this.remaining=this.remaining.slice(this.options.chunkSize),this.saxParser=this.saxParser.write(t),setTimeout(this.processAsync,0)}}catch(t){this.errThrown||(this.errThrown=!0,this.emit("error",t))}}),Z(this,"assignOrPush",(t,s,o)=>{s in t?(Array.isArray(t[s])||de(t,s,[t[s]]),t[s].push(o)):this.options.explicitArray?de(t,s,[o]):de(t,s,o)}),Z(this,"reset",()=>{this.removeAllListeners(),this.saxParser=Et.default.parser(this.options.strict,{trim:!1,normalize:!1,xmlns:this.options.xmlns}),this.errThrown=!1,this.saxParser.onerror=a=>{this.saxParser.resume(),this.errThrown||(this.errThrown=!0,this.emit("error",a))},this.saxParser.onend=()=>{this.ended||(this.ended=!0,this.emit("end",this.resultObject))},this.ended=!1,this.EXPLICIT_CHARKEY=this.options.explicitCharkey,this.resultObject=null;let t=[],s=this.options.attrkey,o=this.options.charkey;this.saxParser.onopentag=a=>{let u={};u[o]="",this.options.ignoreAttrs||Object.keys(a.attributes).forEach(d=>{!(s in u)&&!this.options.mergeAttrs&&(u[s]={});let m=this.options.attrValueProcessors?Fe(this.options.attrValueProcessors,a.attributes[d],d):a.attributes[d],v=this.options.attrNameProcessors?Fe(this.options.attrNameProcessors,d):d;this.options.mergeAttrs?this.assignOrPush(u,v,m):de(u[s],v,m)}),u["#name"]=this.options.tagNameProcessors?Fe(this.options.tagNameProcessors,a.name):a.name,this.options.xmlns&&(u[this.options.xmlnskey]={uri:a.uri,local:a.local}),t.push(u)},this.saxParser.onclosetag=()=>{let a=t.pop(),u=a["#name"];(!this.options.explicitChildren||!this.options.preserveChildrenOrder)&&delete a["#name"];let d;a.cdata===!0&&(d=a.cdata,delete a.cdata);let m=t[t.length-1],v="";if(a[o].match(/^\s*$/)&&!d?(v=a[o],delete a[o]):(this.options.trim&&(a[o]=a[o].trim()),this.options.normalize&&(a[o]=a[o].replace(/\s{2,}/g," ").trim()),a[o]=this.options.valueProcessors?Fe(this.options.valueProcessors,a[o],u):a[o],Object.keys(a).length===1&&o in a&&!this.EXPLICIT_CHARKEY&&(a=a[o])),mn(a)&&(typeof this.options.emptyTag=="function"?a=this.options.emptyTag():a=this.options.emptyTag!==""?this.options.emptyTag:v),this.options.validator){let g=`/${t.map(p=>p["#name"]).concat(u).join("/")}`;(()=>{try{a=this.options.validator(g,m&&m[u],a)}catch(p){this.emit("error",p)}})()}if(this.options.explicitChildren&&!this.options.mergeAttrs&&typeof a=="object")if(this.options.preserveChildrenOrder){if(m){m[this.options.childkey]=m[this.options.childkey]||[];let g={};Object.keys(a).forEach(p=>{de(g,p,a[p])}),m[this.options.childkey].push(g),delete a["#name"],Object.keys(a).length===1&&o in a&&!this.EXPLICIT_CHARKEY&&(a=a[o])}}else{let g={};this.options.attrkey in a&&(g[this.options.attrkey]=a[this.options.attrkey],delete a[this.options.attrkey]),!this.options.charsAsChildren&&this.options.charkey in a&&(g[this.options.charkey]=a[this.options.charkey],delete a[this.options.charkey]),Object.getOwnPropertyNames(a).length>0&&(g[this.options.childkey]=a),a=g}if(t.length>0)this.assignOrPush(m,u,a);else{if(this.options.explicitRoot){let g=a,p={};de(p,u,g),a=p}this.resultObject=a,this.ended=!0,this.emit("end",this.resultObject)}};let l=a=>{let u=t[t.length-1];if(u&&(u[o]+=a,this.options.explicitChildren&&this.options.preserveChildrenOrder&&this.options.charsAsChildren&&(this.options.includeWhiteChars||a.replace(/\\n/g,"").trim()!==""))){u[this.options.childkey]=u[this.options.childkey]||[];let d={"#name":"__text__"};d[o]=a,this.options.normalize&&(d[o]=d[o].replace(/\s{2,}/g," ").trim()),u[this.options.childkey].push(d)}return u};this.saxParser.ontext=l,this.saxParser.oncdata=a=>{let u=l(a);u&&(u.cdata=!0)}}),Z(this,"parseString",(t,s)=>{s&&typeof s=="function"&&(this.on("end",o=>{this.reset(),s(null,o)}),this.on("error",o=>{this.reset(),s(o)}));try{return t=t.toString(),t.trim()===""?(this.emit("end",null),!0):(t=vn(t),this.options.async?(this.remaining=t,setTimeout(this.processAsync,0),this.saxParser):this.saxParser.write(t).close())}catch(o){if(!this.errThrown&&!this.ended)this.emit("error",o),this.errThrown=!0;else if(this.ended)throw o}}),Z(this,"parseStringPromise",t=>new Promise((s,o)=>{this.parseString(t,(l,a)=>{l?o(l):s(a)})})),this.options={},Object.keys(bt["0.2"]).forEach(t=>{this.options[t]=b Line truncated
/*! Bundled license information:
sax/lib/sax.js:
(*! http://mths.be/fromcodepoint v0.1.0 by @mathias *)
*/