mailfile 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +203 -0
- package/dist/mailfile.cjs +2035 -0
- package/dist/mailfile.js +2037 -0
- package/dist/mailfile.min.js +30 -0
- package/package.json +84 -0
- package/src/cfb/index.js +4 -0
- package/src/cfb/read.js +221 -0
- package/src/cfb/write.js +262 -0
- package/src/errors.js +49 -0
- package/src/index.js +86 -0
- package/src/mapi/bag.js +195 -0
- package/src/mapi/index.js +6 -0
- package/src/mapi/tags.js +147 -0
- package/src/message.js +199 -0
- package/src/mime/build.js +100 -0
- package/src/mime/encodings.js +188 -0
- package/src/mime/headers.js +344 -0
- package/src/mime/index.js +12 -0
- package/src/mime/parse.js +153 -0
- package/src/msg/read.js +178 -0
- package/src/msg/write.js +124 -0
- package/src/rtf/deencapsulate.js +155 -0
- package/src/rtf/index.js +3 -0
- package/src/rtf/lzfu.js +67 -0
- package/src/util.js +59 -0
- package/types/cfb/index.d.ts +2 -0
- package/types/cfb/read.d.ts +70 -0
- package/types/cfb/write.d.ts +67 -0
- package/types/errors.d.ts +36 -0
- package/types/index.d.ts +73 -0
- package/types/mapi/bag.d.ts +77 -0
- package/types/mapi/index.d.ts +2 -0
- package/types/mapi/tags.d.ts +137 -0
- package/types/message.d.ts +94 -0
- package/types/mime/build.d.ts +27 -0
- package/types/mime/encodings.d.ts +52 -0
- package/types/mime/headers.d.ts +111 -0
- package/types/mime/index.d.ts +4 -0
- package/types/mime/parse.d.ts +43 -0
- package/types/msg/read.d.ts +26 -0
- package/types/msg/write.d.ts +6 -0
- package/types/rtf/deencapsulate.d.ts +23 -0
- package/types/rtf/index.d.ts +2 -0
- package/types/rtf/lzfu.d.ts +8 -0
- package/types/util.d.ts +25 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
var mailfile=(()=>{var Tt=Object.defineProperty;var ie=Object.getOwnPropertyDescriptor;var oe=Object.getOwnPropertyNames;var se=Object.prototype.hasOwnProperty;var ce=(t,e)=>{for(var n in e)Tt(t,n,{get:e[n],enumerable:!0})},ae=(t,e,n,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of oe(e))!se.call(t,o)&&o!==n&&Tt(t,o,{get:()=>e[o],enumerable:!(r=ie(e,o))||r.enumerable});return t};var le=t=>ae(Tt({},"__esModule",{value:!0}),t);var je={};ce(je,{ErrorCode:()=>U,Headers:()=>b,MailfileError:()=>R,Message:()=>W,convert:()=>Ye,detect:()=>re,version:()=>ye});var B="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";function ct(t){let e="",n,r=t.length;for(n=0;n+2<r;n+=3){let i=t[n]<<16|t[n+1]<<8|t[n+2];e+=B[i>>18&63]+B[i>>12&63]+B[i>>6&63]+B[i&63]}let o=r-n;if(o===1){let i=t[n]<<16;e+=B[i>>18&63]+B[i>>12&63]+"=="}else if(o===2){let i=t[n]<<16|t[n+1]<<8;e+=B[i>>18&63]+B[i>>12&63]+B[i>>6&63]+"="}return e}function at(t){let e=String(t).replace(/[^A-Za-z0-9+/=]/g,""),n=e.indexOf("=");n>=0&&(e=e.slice(0,n));let r=e.length,o=new Uint8Array(Math.floor(r*3/4)),i=0,c=0,u=0;for(let l=0;l<r;l++){let h=B.indexOf(e[l]);h<0||(c=c<<6|h,u+=6,u>=8&&(u-=8,o[i++]=c>>u&255))}return o.subarray(0,i)}function Nt(t,e){let n=[];for(let r=0;r<t.length;r+=e)n.push(t.slice(r,r+e));return n.join(`\r
|
|
2
|
+
`)}var fe=new TextEncoder;function L(t){return fe.encode(t)}function O(t,e){let n=(e||"utf-8").toLowerCase().replace(/^["']|["']$/g,"");(n==="us-ascii"||n==="ascii"||n==="ansi_x3.4-1968")&&(n="utf-8"),(n==="cp1252"||n==="win-1252")&&(n="windows-1252"),n==="utf8"&&(n="utf-8");try{return new TextDecoder(n,{fatal:!1}).decode(t)}catch{try{return new TextDecoder("windows-1252").decode(t)}catch{let r="";for(let o=0;o<t.length;o++)r+=String.fromCharCode(t[o]);return r}}}function lt(t){try{return new TextDecoder("utf-16le").decode(t)}catch{let e="";for(let n=0;n+1<t.length;n+=2)e+=String.fromCharCode(t[n]|t[n+1]<<8);return e}}function wt(t){let e=new Uint8Array(t.length*2);for(let n=0;n<t.length;n++){let r=t.charCodeAt(n);e[n*2]=r&255,e[n*2+1]=r>>8}return e}function ft(t,e){let n=[],r=0;for(;r<t.length;){let o=t[r];if(o==="="){if(t[r+1]==="\r"&&t[r+2]===`
|
|
3
|
+
`){r+=3;continue}if(t[r+1]===`
|
|
4
|
+
`){r+=2;continue}let i=t.substr(r+1,2);if(/^[0-9A-Fa-f]{2}$/.test(i)){n.push(parseInt(i,16)),r+=3;continue}n.push(61),r++}else e&&o==="_"?(n.push(32),r++):(n.push(t.charCodeAt(r)&255),r++)}return new Uint8Array(n)}function Rt(t){let e="",n=0;function r(i){n+i.length>75&&(e+=`=\r
|
|
5
|
+
`,n=0),e+=i,n+=i.length}let o=i=>"="+("0"+i.toString(16).toUpperCase()).slice(-2);for(let i=0;i<t.length;i++){let c=t[i];if(c===13&&t[i+1]===10){e+=`\r
|
|
6
|
+
`,n=0,i++;continue}if(c===10){e+=`\r
|
|
7
|
+
`,n=0;continue}if(c===32||c===9){let u=t[i+1];r(u===13||u===10||u===void 0?o(c):String.fromCharCode(c));continue}c===61||c<32||c>126?r(o(c)):r(String.fromCharCode(c))}return e}function K(t){return!t||t.indexOf("=?")<0?t||"":t.replace(/(\?=)(?:\r?\n)?[ \t]+(=\?)/g,"$1$2").replace(/=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g,(n,r,o,i)=>{try{let c=o.toUpperCase()==="B"?at(i):ft(i,!0);return O(c,r)}catch{return n}})}function ut(t){return/[^\x20-\x7E]/.test(t)}function ht(t){if(!ut(t))return t;let e=[],n="",r=0,o=Array.from(t);for(let i of o){let c=L(i).length;r+c>36&&(e.push(n),n="",r=0),n+=i,r+=c}return n&&e.push(n),e.map(i=>"=?UTF-8?B?"+ct(L(i))+"?=").join(`\r
|
|
8
|
+
`)}function gt(t,e){let n=t+": "+e;if(n.length<=78||/\r\n/.test(n))return n;let r="",o=t+":",i=e.split(" ");for(let c of i)o.length+1+c.length>78&&o!==t+":"?(r+=o+`\r
|
|
9
|
+
`,o=" "+c):o+=(o===" "?"":" ")+c;return r+o}function xt(t,e){return e=(e||"").trim(),t=(t||"").trim(),e?!t||t.toLowerCase()===e.toLowerCase()?e:ut(t)?ht(t)+" <"+e+">":/[()<>@,;:\\".\[\]]/.test(t)?'"'+t.replace(/(["\\])/g,"\\$1")+'" <'+e+">":t+" <"+e+">":t?ht(t):""}function ue(t){let e=[],n="",r=!1,o=0;for(let i=0;i<t.length;i++){let c=t[i];if(c==='"'&&t[i-1]!=="\\"&&(r=!r),!r&&(c==="<"||c==="(")&&o++,!r&&(c===">"||c===")")&&o--,c===","&&!r&&o<=0){e.push(n),n="";continue}n+=c}return n.trim()&&e.push(n),e.map(i=>i.trim()).filter(Boolean)}function he(t){let e=K(String(t).trim()),n=e.match(/^(.*)<([^>]*)>\s*$/);return n?{name:n[1].trim().replace(/^"(.*)"$/,"$1").replace(/\\(["\\])/g,"$1"),email:n[2].trim()}:{name:"",email:e.replace(/^<|>$/g,"").trim()}}function V(t){return t?ue(String(t)).map(he).filter(e=>e.email||e.name):[]}function St(t){let e="",n={},r=0,o=String(t||"");for(;r<o.length&&o[r]!==";";)e+=o[r],r++;let i=o.slice(r+1),c=/\s*([^=\s;]+)\s*=\s*("(?:[^"\\]|\\.)*"|[^;]*)\s*(?:;|$)/g,u={},l;for(;(l=c.exec(i))&&l[1];){let d=l[2].trim();d[0]==='"'&&(d=d.slice(1,-1).replace(/\\(.)/g,"$1")),u[l[1].toLowerCase()]=d}let h={};for(let d of Object.keys(u)){let p=d.match(/^([^*]+)(?:\*(\d+))?(\*)?$/);if(!p){n[d]=u[d];continue}let g=p[1],S=p[2]===void 0?-1:parseInt(p[2],10),E=!!p[3];if(S<0&&!E){g in h||(n[g]=u[d]);continue}h[g]=h[g]||[],h[g].push({idx:S<0?0:S,ext:E,v:u[d]})}for(let d of Object.keys(h)){let p=h[d].sort((E,I)=>E.idx-I.idx),g=null,S="";if(p.forEach((E,I)=>{let _=E.v;if(E.ext){if(I===0&&_.indexOf("'")>=0){let C=_.split("'");g=C[0],_=C.slice(2).join("'")}S+=_}else S+=_}),g||/%[0-9A-Fa-f]{2}/.test(S)){let E=[];for(let I=0;I<S.length;I++)S[I]==="%"&&/^[0-9A-Fa-f]{2}$/.test(S.substr(I+1,2))?(E.push(parseInt(S.substr(I+1,2),16)),I+=2):E.push(S.charCodeAt(I)&255);n[d]=O(new Uint8Array(E),g||"utf-8")}else n[d]=K(S)}return{value:e.trim(),params:n}}function At(t,e){if(!ut(e)&&!/[";\\]/.test(e))return t+'="'+e+'"';if(!ut(e))return t+'="'+e.replace(/(["\\])/g,"\\$1")+'"';let n=L(e),r="";for(let i of n)i>=48&&i<=57||i>=65&&i<=90||i>=97&&i<=122||i===45||i===46||i===95?r+=String.fromCharCode(i):r+="%"+("0"+i.toString(16).toUpperCase()).slice(-2);let o=e.replace(/[^\x20-\x7E]/g,"_").replace(/(["\\])/g,"");return t+'="'+o+'"; '+t+"*=UTF-8''"+r}var b=class t{constructor(e){this.entries=e?e.slice():[]}static parse(e){let n=String(e||"").replace(/\r?\n[ \t]+/g," "),r=[];for(let o of n.split(/\r?\n/)){if(!o.trim())continue;let i=o.indexOf(":");i<0||r.push([o.slice(0,i).trim(),o.slice(i+1).trim()])}return new t(r)}get(e){let n=e.toLowerCase();for(let[r,o]of this.entries)if(r.toLowerCase()===n)return o;return null}getAll(e){let n=e.toLowerCase();return this.entries.filter(([r])=>r.toLowerCase()===n).map(([,r])=>r)}has(e){return this.get(e)!==null}set(e,n){return this.delete(e),this.entries.push([e,n]),this}add(e,n){return this.entries.push([e,n]),this}delete(e){let n=e.toLowerCase();return this.entries=this.entries.filter(([r])=>r.toLowerCase()!==n),this}get raw(){return this.entries.map(([e,n])=>gt(e,n)).join(`\r
|
|
10
|
+
`)}[Symbol.iterator](){return this.entries[Symbol.iterator]()}};function Ft(t){let e=["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],n=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"],r=c=>(c<10?"0":"")+c,o=-t.getTimezoneOffset(),i=o>=0?"+":"-";return o=Math.abs(o),e[t.getDay()]+", "+t.getDate()+" "+n[t.getMonth()]+" "+t.getFullYear()+" "+r(t.getHours())+":"+r(t.getMinutes())+":"+r(t.getSeconds())+" "+i+r(Math.floor(o/60))+r(o%60)}function Ut(t){if(!t)return null;let e=new Date(String(t).replace(/\s*\([^)]*\)\s*$/,""));return isNaN(e.getTime())?null:e}function me(t){let e="";for(let n=0;n<24;n++)e+="0123456789abcdef"[Math.floor(Math.random()*16)];return"----=_"+t+"_"+e}function _t(t,e){return["Content-Type: "+t+'; charset="utf-8"',"Content-Transfer-Encoding: quoted-printable","",Rt(L(e))].join(`\r
|
|
11
|
+
`)}function Ot(t){let n=["Content-Type: "+(t.mime||"application/octet-stream")+"; "+At("name",t.filename),"Content-Transfer-Encoding: base64"];return t.cid&&n.push("Content-ID: <"+t.cid+">"),n.push("Content-Disposition: "+(t.inline?"inline":"attachment")+"; "+At("filename",t.filename)),n.push(""),n.push(Nt(ct(t.data),76)),n.join(`\r
|
|
12
|
+
`)}function Ct(t,e,n){let r=me(t.toUpperCase()),o="Content-Type: multipart/"+t+'; boundary="'+r+'"'+(n||""),i="";for(let c of e)i+="--"+r+`\r
|
|
13
|
+
`+c+`\r
|
|
14
|
+
`;return i+="--"+r+`--\r
|
|
15
|
+
`,{head:o,body:i}}function Pt(t){let e=[],n=[];for(let h of t.attachments||[])h.inline&&h.cid?e.push(h):n.push(h);let r=[];t.text&&r.push(_t("text/plain",t.text)),t.html&&r.push(_t("text/html",t.html)),r.length||r.push(_t("text/plain",""));let o;if(r.length>1){let h=Ct("alternative",r);o=h.head+`\r
|
|
16
|
+
\r
|
|
17
|
+
`+h.body}else o=r[0];if(e.length){let h=Ct("related",[o].concat(e.map(Ot)),'; type="text/html"');o=h.head+`\r
|
|
18
|
+
\r
|
|
19
|
+
`+h.body}if(n.length){let h=Ct("mixed",[o].concat(n.map(Ot)));o=h.head+`\r
|
|
20
|
+
\r
|
|
21
|
+
`+h.body}let i=o.indexOf(`\r
|
|
22
|
+
\r
|
|
23
|
+
`),c=o.slice(0,i),u=o.slice(i+4),l=[];for(let[h,d]of t.headers||[])l.push(gt(h,d));l.push("MIME-Version: 1.0");for(let h of c.split(`\r
|
|
24
|
+
`))h&&l.push(h);return L(l.join(`\r
|
|
25
|
+
`)+`\r
|
|
26
|
+
\r
|
|
27
|
+
`+u)}function pe(t){for(let e=0;e+1<t.length;e++){if(t[e]===10&&t[e+1]===10)return{end:e,bodyStart:e+2};if(t[e]===13&&t[e+1]===10&&t[e+2]===13&&t[e+3]===10)return{end:e,bodyStart:e+4}}return{end:t.length,bodyStart:t.length}}function de(t,e){let n=L("--"+e),r=[],o=[];for(let i=0;i<=t.length-n.length;i++){if(t[i]!==45||t[i+1]!==45||i>0&&t[i-1]!==10)continue;let c=!0;for(let p=0;p<n.length;p++)if(t[i+p]!==n[p]){c=!1;break}if(!c)continue;let u=i+n.length,l=t[u]===45&&t[u+1]===45,h=u+(l?2:0);for(;t[h]===32||t[h]===9;)h++;if(!(t[h]===13||t[h]===10||h>=t.length))continue;let d=h;if(t[d]===13&&d++,t[d]===10&&d++,o.push({at:i,contentStart:d,isEnd:l}),l)break}for(let i=0;i<o.length-1;i++){let c=o[i].contentStart,u=o[i+1].at;u>c&&t[u-1]===10&&u--,u>c&&t[u-1]===13&&u--,r.push(t.subarray(c,Math.max(c,u)))}return r}function Ee(t,e){let n=(e||"7bit").trim().toLowerCase();if(n==="base64")return at(O(t,"utf-8"));if(n==="quoted-printable"){let r="";for(let o=0;o<t.length;o++)r+=String.fromCharCode(t[o]);return ft(r,!1)}return t}function Lt(t,e=0){let n=pe(t),r=b.parse(O(t.subarray(0,n.end),"utf-8")),o=t.subarray(n.bodyStart),i=St(r.get("content-type")||"text/plain"),c={headers:r,contentType:(i.value||"text/plain").toLowerCase(),params:i.params,children:[]};if(c.contentType.startsWith("multipart/")&&i.params.boundary&&e<20)for(let u of de(o,i.params.boundary))c.children.push(Lt(u,e+1));else c.content=Ee(o,r.get("content-transfer-encoding"));return c}var Te={"text/plain":"txt","text/html":"html","image/png":"png","image/jpeg":"jpg","image/gif":"gif","application/pdf":"pdf","message/rfc822":"eml"};function ge(t,e){return"attachment-"+(e+1)+"."+(Te[t]||"bin")}function bt(t,e,n){if(t.children.length){for(let h of t.children)bt(h,e,t.contentType);return}let r=St(t.headers.get("content-disposition")||""),o=(r.value||"").toLowerCase(),i=r.params.filename||t.params.name||"",c=(t.headers.get("content-id")||"").replace(/^<|>$/g,"").trim();if((t.contentType==="text/plain"||t.contentType==="text/html")&&o!=="attachment"&&!i){let h=O(t.content,t.params.charset||"utf-8");t.contentType==="text/html"?e.html=e.html||h:e.text=e.text||h;return}e.attachments.push({filename:K(i)||ge(t.contentType,e.attachments.length),mime:t.contentType,data:t.content||new Uint8Array(0),cid:c,inline:o==="inline"||!!c&&n==="multipart/related"})}function Bt(t){let e=Lt(t,0),n={text:"",html:"",attachments:[],headers:e.headers,root:e};return bt(e,n,e.contentType),n}var U={NOT_COMPOUND_FILE:"NOT_COMPOUND_FILE",CORRUPT_CFB:"CORRUPT_CFB",TRUNCATED_STREAM:"TRUNCATED_STREAM",NOT_A_MESSAGE:"NOT_A_MESSAGE",EMPTY_INPUT:"EMPTY_INPUT",UNSUPPORTED:"UNSUPPORTED",MALFORMED:"MALFORMED"},R=class extends Error{constructor(e,n,r){super(n),this.name="MailfileError",this.code=e,r&&r.cause!==void 0&&(this.cause=r.cause)}};var xe=[208,207,17,224,161,177,26,225],rt=4294967295,it=4294967294,Se=4294967295,Ae=4096;function yt(t){if(!t||!t.length)throw new R(U.EMPTY_INPUT,"No data to read");if(t.length<512)throw new R(U.NOT_COMPOUND_FILE,"File is too small to be a compound file");let e=new DataView(t.buffer,t.byteOffset,t.byteLength);for(let f=0;f<8;f++)if(t[f]!==xe[f])throw new R(U.NOT_COMPOUND_FILE,"Not a compound file (bad OLE signature)");let n=1<<e.getUint16(30,!0),r=1<<e.getUint16(32,!0),o=e.getUint32(44,!0),i=e.getUint32(48,!0),c=e.getUint32(56,!0)||Ae,u=e.getUint32(60,!0),l=e.getUint32(68,!0);if(n<128||n>65536)throw new R(U.CORRUPT_CFB,"Invalid sector size");let h=Math.floor((t.length-n)/n),d=f=>(f+1)*n;function p(f){if(f>h||f<0)throw new R(U.CORRUPT_CFB,"Sector reference outside the file (offset "+f+")")}let g=[];for(let f=0;f<109&&g.length<o;f++){let x=e.getUint32(76+f*4,!0);if(x===rt||x===it)break;g.push(x)}let S=l,E=0;for(;S!==it&&S!==rt&&E++<1e5&&g.length<o;){p(S);let f=d(S);for(let x=0;x<n/4-1;x++){let s=e.getUint32(f+x*4,!0);if(s===rt||s===it)break;g.push(s)}S=e.getUint32(f+n-4,!0)}let I=n/4,_=new Uint32Array(g.length*I);for(let f=0;f<g.length;f++){p(g[f]);let x=d(g[f]);for(let s=0;s<I;s++)_[f*I+s]=e.getUint32(x+s*4,!0)}function C(f){let x=[],s=f,m=0;for(;s!==it&&s!==rt&&s!==void 0;){if(m++>_.length+8)throw new R(U.CORRUPT_CFB,"Sector chain loops back on itself");p(s),x.push(s),s=_[s]}return x}function M(f,x){let s=new Uint8Array(f.length*n);for(let m=0;m<f.length;m++)s.set(t.subarray(d(f[m]),d(f[m])+n),m*n);return x==null?s:s.subarray(0,x)}let A=M(C(u)),D=new Uint32Array(A.length>>2),N=new DataView(A.buffer,A.byteOffset,A.byteLength);for(let f=0;f<D.length;f++)D[f]=N.getUint32(f*4,!0);let G=M(C(i)),nt=Math.floor(G.length/128),F=new DataView(G.buffer,G.byteOffset,G.byteLength),P=[];for(let f=0;f<nt;f++){let x=f*128,s=F.getUint16(x+64,!0),m="";for(let T=0;T+1<s-1;T+=2){let w=F.getUint16(x+T,!0);if(w===0)break;m+=String.fromCharCode(w)}P.push({id:f,name:m,type:F.getUint8(x+66),left:F.getUint32(x+68,!0),right:F.getUint32(x+72,!0),child:F.getUint32(x+76,!0),start:F.getUint32(x+116,!0),size:F.getUint32(x+120,!0)+F.getUint32(x+124,!0)*4294967296,children:null})}if(!P.length)throw new R(U.CORRUPT_CFB,"Compound file has no directory");let v=P[0],z=M(C(v.start),v.size);function Q(f){if(!f||f.type!==2||!f.size)return new Uint8Array(0);if(f.size<c){let x=new Uint8Array(f.size),s=f.start,m=0,T=0;for(;s!==it&&s!==rt&&m<f.size;){if(T++>D.length+8)throw new R(U.CORRUPT_CFB,"Mini sector chain loops back on itself");let w=Math.min(r,f.size-m);x.set(z.subarray(s*r,s*r+w),m),m+=w,s=D[s]}return x}return M(C(f.start),f.size)}function k(f,x,s){if(f===Se||f>=P.length||s[f])return;s[f]=1;let m=P[f];k(m.left,x,s),x.push(m),k(m.right,x,s)}function $(f){if(f.children)return f.children;let x=[];k(f.child,x,{});let s=Object.create(null);for(let m=0;m<x.length;m++)s[x[m].name]=x[m];return f.children={list:x,map:s},f.children}return{root:v,entries:P,readStream:Q,childrenOf:$}}var _e=[208,207,17,224,161,177,26,225],mt=4294967295,y=4294967294,Ce=4294967293,Ie=4294967292,J=4294967295,Ht=4096;function Yt(t){return{name:"Root Entry",type:5,clsid:t||null,children:[]}}function pt(t,e,n){let r={name:e,type:1,clsid:n||null,children:[]};return t.children.push(r),r}function q(t,e,n){let r={name:e,type:2,data:n||new Uint8Array(0)};return t.children.push(r),r}function Me(t,e){if(t.length!==e.length)return t.length-e.length;let n=t.toUpperCase(),r=e.toUpperCase();for(let o=0;o<n.length;o++){let i=n.charCodeAt(o)-r.charCodeAt(o);if(i)return i}return 0}function jt(t){let e=[],n=s=>{s.id=e.length,e.push(s)};n(t);function r(s,m,T){if(m>=T)return J;let w=m+T>>1,X=s[w];return X.leftId=r(s,m,w),X.rightId=r(s,w+1,T),X.id}function o(s){if(!s.children||!s.children.length){s.childId=J;return}let m=s.children.slice().sort((T,w)=>Me(T.name,w.name));for(let T=0;T<m.length;T++)n(m[T]);s.childId=r(m,0,m.length);for(let T=0;T<m.length;T++)o(m[T])}o(t);let i=512,c=64,u=i/4,l=[],h=[];for(let s=1;s<e.length;s++){let m=e[s];if(m.type!==2){m.startSector=y,m.streamSize=0;continue}m.streamSize=m.data.length,m.data.length===0?m.startSector=y:m.data.length>=Ht?l.push(m):h.push(m)}let d=0;for(let s of h)s.startSector=d,d+=Math.ceil(s.data.length/c);let p=d*c,g=Math.ceil(p/i),S=new Uint8Array(g*i);for(let s of h)S.set(s.data,s.startSector*c);let E=l.map(s=>Math.ceil(s.data.length/i)),I=E.reduce((s,m)=>s+m,0),_=Math.ceil(d*4/i)||0,C=Math.ceil(e.length/4),M=1,A=0,D=0;for(let s=0;s<64;s++){D=I+g+_+C+M+A;let m=Math.max(1,Math.ceil(D/u)),T=m<=109?0:Math.ceil((m-109)/(u-1));if(m===M&&T===A)break;M=m,A=T}D=I+g+_+C+M+A;let N=0;for(let s=0;s<l.length;s++)l[s].startSector=N,N+=E[s];let G=g?N:y;N+=g;let nt=_?N:y;N+=_;let F=N;N+=C;let P=N;N+=M;let v=A?N:y;N+=A;let z=new Uint32Array(M*u);z.fill(mt);function Q(s,m){for(let T=0;T<m;T++)z[s+T]=T===m-1?y:s+T+1}for(let s=0;s<l.length;s++)Q(l[s].startSector,E[s]);g&&Q(G,g),_&&Q(nt,_),Q(F,C);for(let s=0;s<M;s++)z[P+s]=Ce;for(let s=0;s<A;s++)z[v+s]=Ie;let k=new Uint32Array(_*i/4);k.fill(mt);for(let s of h){let m=Math.ceil(s.data.length/c);for(let T=0;T<m;T++)k[s.startSector+T]=T===m-1?y:s.startSector+T+1}t.startSector=G,t.streamSize=p;let $=new Uint8Array(i*(1+D)),f=new DataView($.buffer);for(let s=0;s<8;s++)$[s]=_e[s];f.setUint16(24,62,!0),f.setUint16(26,3,!0),f.setUint16(28,65534,!0),f.setUint16(30,9,!0),f.setUint16(32,6,!0),f.setUint32(44,M,!0),f.setUint32(48,F,!0),f.setUint32(56,Ht,!0),f.setUint32(60,nt,!0),f.setUint32(64,_,!0),f.setUint32(68,v,!0),f.setUint32(72,A,!0);for(let s=0;s<109;s++)f.setUint32(76+s*4,s<M?P+s:mt,!0);let x=s=>i*(1+s);for(let s of l)$.set(s.data,x(s.startSector));if(g&&$.set(S,x(G)),_)for(let s=0;s<k.length;s++)f.setUint32(x(nt)+s*4,k[s],!0);for(let s=0;s<z.length;s++)f.setUint32(x(P)+s*4,z[s],!0);for(let s=0;s<A;s++){let m=x(v+s);for(let T=0;T<u-1;T++){let w=109+s*(u-1)+T;f.setUint32(m+T*4,w<M?P+w:mt,!0)}f.setUint32(m+i-4,s===A-1?y:v+s+1,!0)}for(let s=0;s<e.length;s++){let m=e[s],T=x(F)+s*128,w=Math.min(m.name.length,31);for(let st=0;st<w;st++)f.setUint16(T+st*2,m.name.charCodeAt(st),!0);f.setUint16(T+64,w*2+2,!0),f.setUint8(T+66,m.type),f.setUint8(T+67,1),f.setUint32(T+68,m.leftId==null?J:m.leftId,!0),f.setUint32(T+72,m.rightId==null?J:m.rightId,!0),f.setUint32(T+76,m.childId==null?J:m.childId,!0),m.clsid&&$.set(m.clsid,T+80),f.setUint32(T+116,m.startSector==null?y:m.startSector,!0);let X=m.streamSize||0;f.setUint32(T+120,X>>>0,!0),f.setUint32(T+124,Math.floor(X/4294967296),!0)}for(let s=e.length;s<C*4;s++){let m=x(F)+s*128;f.setUint32(m+68,J,!0),f.setUint32(m+72,J,!0),f.setUint32(m+76,J,!0),f.setUint32(m+116,y,!0)}return $}var a={SUBJECT:55,NORMALIZED_SUBJECT:3613,BODY:4096,RTF_COMPRESSED:4105,HTML:4115,MESSAGE_CLASS:26,TRANSPORT_HEADERS:125,CLIENT_SUBMIT_TIME:57,DELIVERY_TIME:3590,LAST_MODIFICATION_TIME:12296,CREATION_TIME:12295,INTERNET_MESSAGE_ID:4149,IN_REPLY_TO_ID:4162,INTERNET_REFERENCES:4153,DISPLAY_TO:3588,DISPLAY_CC:3587,DISPLAY_BCC:3586,SENDER_NAME:3098,SENDER_EMAIL:3103,SENDER_ADDRTYPE:3102,SENDER_SMTP:23809,SENT_REP_NAME:66,SENT_REP_EMAIL:101,SENT_REP_ADDRTYPE:100,SENT_REP_SMTP:23810,MESSAGE_FLAGS:3591,HASATTACH:3611,STORE_SUPPORT_MASK:13325,INTERNET_CPID:16350,MESSAGE_CODEPAGE:16381,PRIORITY:38,IMPORTANCE:23,OBJECT_TYPE:4094,DISPLAY_TYPE:14592,ROWID:12288,RECIPIENT_TYPE:3093,DISPLAY_NAME:12289,EMAIL_ADDRESS:12291,ADDRTYPE:12290,SMTP_ADDRESS:14846,ATTACH_METHOD:14085,ATTACH_DATA_BIN:14081,ATTACH_LONG_FILENAME:14087,ATTACH_FILENAME:14084,ATTACH_EXTENSION:14083,ATTACH_MIME_TAG:14094,ATTACH_CONTENT_ID:14098,ATTACH_SIZE:3616,ATTACH_NUM:3617,ATTACH_FLAGS:14100,ATTACHMENT_HIDDEN:32766,RENDERING_POSITION:14091},Y={SHORT:2,LONG:3,FLOAT:4,DOUBLE:5,BOOLEAN:11,I8:20,STRING8:30,UNICODE:31,SYSTIME:64,BINARY:258,OBJECT:13},Z={TO:1,CC:2,BCC:3},Gt={NONE:0,BY_VALUE:1,BY_REFERENCE:2,EMBEDDED_MSG:5},j={TOP_LEVEL:32,EMBEDDED:24,RECIPIENT:8,ATTACHMENT:8},vt=new Uint8Array([11,13,2,0,0,0,0,0,192,0,0,0,0,0,0,70]),zt={20127:"us-ascii",28591:"iso-8859-1",28592:"iso-8859-2",28595:"iso-8859-5",28597:"iso-8859-7",28598:"iso-8859-8",28599:"iso-8859-9",28605:"iso-8859-15",65e3:"utf-7",65001:"utf-8",1250:"windows-1250",1251:"windows-1251",1252:"windows-1252",1253:"windows-1253",1254:"windows-1254",1255:"windows-1255",1256:"windows-1256",1257:"windows-1257",1258:"windows-1258",932:"shift_jis",936:"gbk",949:"euc-kr",950:"big5",874:"windows-874"};function H(t){return("000"+t.toString(16).toUpperCase()).slice(-4)}function It(t){return("0000000"+t.toString(16).toUpperCase()).slice(-8)}function ot(t,e){return"__substg1.0_"+H(t)+H(e)}function kt(t,e){if(!t&&!e)return null;let r=(e*4294967296+t)/1e4-116444736e5;return!isFinite(r)||r<-22089888e5||r>41024448e5?null:new Date(r)}function $t(t){let e=Math.round((t.getTime()+116444736e5)*1e4);return{lo:e%4294967296,hi:Math.floor(e/4294967296)}}var tt=class{constructor(e,n,r){let o=e.childrenOf(n);this.vars=Object.create(null),this.fixed=Object.create(null),this.subStorages=[],this.cfb=e,this.childMap=o.map;for(let u of o.list){let l=/^__substg1\.0_([0-9A-Fa-f]{8})$/.exec(u.name);if(l){u.type===2?this.vars[l[1].toUpperCase()]=e.readStream(u):this.subStorages.push(u);continue}u.type===1&&this.subStorages.push(u)}let i=o.map["__properties_version1.0"];if(i){let u=e.readStream(i),l=new DataView(u.buffer,u.byteOffset,u.byteLength);for(let h=r;h+16<=u.length;h+=16)this.fixed[l.getUint16(h+2,!0)]={type:l.getUint16(h,!0),lo:l.getUint32(h+8,!0),hi:l.getUint32(h+12,!0),i32:l.getInt32(h+8,!0)}}let c=this.fixed[a.INTERNET_CPID]?.i32??this.fixed[a.MESSAGE_CODEPAGE]?.i32??0;this.charset=zt[c]||"windows-1252"}str(e){let n=this.vars[H(e)+"001F"];if(n)return lt(n);let r=this.vars[H(e)+"001E"];return r?O(r,this.charset):""}bin(e){return this.vars[H(e)+"0102"]||null}int(e){return this.fixed[e]?this.fixed[e].i32:null}bool(e){return this.fixed[e]?!!(this.fixed[e].lo&1):null}date(e){return this.fixed[e]?kt(this.fixed[e].lo,this.fixed[e].hi):null}has(e){let n=H(e);return!!(this.fixed[e]||this.vars[n+"001F"]||this.vars[n+"001E"]||this.vars[n+"0102"])}ids(){let e=new Set(Object.keys(this.fixed).map(Number));for(let n of Object.keys(this.vars))e.add(parseInt(n.slice(0,4),16));return[...e].sort((n,r)=>n-r)}storagesMatching(e){return this.subStorages.filter(n=>e.test(n.name)).sort((n,r)=>n.name.localeCompare(r.name))}},et=class{constructor(e,n){this.node=e,this.headerSize=n,this.entries=[]}_entry(e,n,r,o,i){this.entries.push({id:e,type:n,size:r,lo:o||0,hi:i||0})}str(e,n){if(n==null||n==="")return this;let r=wt(String(n));return q(this.node,ot(e,Y.UNICODE),r),this._entry(e,Y.UNICODE,r.length+2),this}bin(e,n){return n?(q(this.node,ot(e,Y.BINARY),n),this._entry(e,Y.BINARY,n.length),this):this}int32(e,n){return n==null?this:(this._entry(e,Y.LONG,null,n>>>0,0),this)}bool(e,n){return this._entry(e,Y.BOOLEAN,null,n?1:0,0),this}time(e,n){if(!n)return this;let r=$t(n);return this._entry(e,Y.SYSTIME,null,r.lo,r.hi),this}finish(e){let n=new Uint8Array(this.headerSize+this.entries.length*16),r=new DataView(n.buffer);e&&e(r);for(let o=0;o<this.entries.length;o++){let i=this.entries[o],c=this.headerSize+o*16;r.setUint16(c,i.type,!0),r.setUint16(c+2,i.id,!0),r.setUint32(c+4,6,!0),i.size!=null?(r.setUint32(c+8,i.size,!0),r.setUint32(c+12,0,!0)):(r.setUint32(c+8,i.lo,!0),r.setUint32(c+12,i.hi,!0))}q(this.node,"__properties_version1.0",n)}};var Mt=`{\\rtf1\\ansi\\mac\\deff0\\deftab720{\\fonttbl;}{\\f0\\fnil \\froman \\fswiss \\fmodern \\fscript \\fdecor MS Sans SerifSymbolArialTimes New RomanCourier{\\colortbl\\red0\\green0\\blue0\r
|
|
28
|
+
\\par \\pard\\plain\\f0\\fs20\\b\\i\\u\\tab\\tx`;function Vt(t){if(!t||t.length<16)return null;let e=new DataView(t.buffer,t.byteOffset,t.byteLength),n=e.getUint32(0,!0),r=e.getUint32(4,!0),o=e.getUint32(8,!0);if(o===1095517517)return t.subarray(16,Math.min(t.length,16+r));if(o!==1967544908)return null;let i=new Uint8Array(4096);for(let p=0;p<Mt.length;p++)i[p]=Mt.charCodeAt(p)&255;let c=Mt.length,u=new Uint8Array(r),l=0,h=16,d=Math.min(t.length,n+4);for(;h<d&&l<r;){let p=t[h++];for(let g=0;g<8&&h<d&&l<r;g++)if(p&1<<g){if(h+1>=d)return u.subarray(0,l);let S=t[h++],E=t[h++],I=S<<4|E>>4,_=(E&15)+2;if(I===c%4096)return u.subarray(0,l);for(let C=0;C<_&&l<r;C++){let M=i[(I+C)%4096];u[l++]=M,i[c%4096]=M,c++}}else{let S=t[h++];u[l++]=S,i[c%4096]=S,c++}}return u.subarray(0,l)}var De={"&":"&","<":"<",">":">"},Jt=t=>t.replace(/[&<>]/g,e=>De[e]),qt={lquote:"‘",rquote:"’",ldblquote:"“",rdblquote:"”",emdash:"—",endash:"–",bullet:"•",nbsp:" "},Ne=new Set(["fonttbl","colortbl","stylesheet","info","pntext","generator"]);function we(t){return/\\from(html|text)1?/.test(t.slice(0,4096))}function Re(t,e){let n=[],r=[],o=0,i=t.length,c=!1,u=0,l=0,h=0,d=!1,p=[],g=/\\fromtext/.test(t.slice(0,4096));function S(_){h||c&&!u||n.push(_)}function E(){if(!p.length)return;let _=e(new Uint8Array(p));p=[],S(u?_:Jt(_))}for(;o<i;){let _=t[o];if(_==="\\"){let C=t[o+1];if(C==="\\"||C==="{"||C==="}"){p.push(C.charCodeAt(0)),o+=2;continue}if(C==="'"){p.push(parseInt(t.substr(o+2,2),16)||0),o+=4;continue}if(C==="*"){o+=2,d=!0;continue}let M=/^\\([a-zA-Z]+)(-?\d+)? ?/.exec(t.slice(o));if(!M){o+=2;continue}let A=M[1],D=M[2]===void 0?null:parseInt(M[2],10);if(o+=M[0].length,E(),A==="htmltag"){d=!1,u=l;continue}if(A==="htmlrtf"){c=D!==0;continue}if(A==="mhtmltag"){h=l,d=!1;continue}if(d){h=l,d=!1;continue}if(A==="u"&&D!==null){if(!c||u){let N=D<0?D+65536:D;S(u?String.fromCharCode(N):Jt(String.fromCharCode(N)))}t[o]==="?"&&o++;continue}if(A==="par"||A==="line"){g&&S(`
|
|
29
|
+
`);continue}if(A==="tab"){S(" ");continue}if(qt[A]){S(qt[A]);continue}if(Ne.has(A)){h=l;continue}continue}if(_==="{"){E(),l++,r.push({suppress:c,inHtmlTag:u}),o++;continue}if(_==="}"){E(),h&&l===h&&(h=0),u&&l===u&&(u=0),l--;let C=r.pop();C&&(c=C.suppress),d=!1,o++;continue}if(_==="\r"||_===`
|
|
30
|
+
`){o++;continue}p.push(t.charCodeAt(o)&255),o++}E();let I=n.join("");return g?'<html><body><pre style="font-family:inherit;white-space:pre-wrap">'+I+"</pre></body></html>":I}function Zt(t,e){if(!t||!t.length)return null;let n="";for(let r=0;r<t.length;r++)n+=String.fromCharCode(t[r]);if(!we(n))return null;try{let r=Re(n,e);return r&&r.trim()?r:null}catch{return null}}var Fe={pdf:"application/pdf",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",bmp:"image/bmp",webp:"image/webp",svg:"image/svg+xml",txt:"text/plain",csv:"text/csv",html:"text/html",htm:"text/html",xml:"application/xml",json:"application/json",zip:"application/zip",doc:"application/msword",dot:"application/msword",docx:"application/vnd.openxmlformats-officedocument.wordprocessingml.document",xls:"application/vnd.ms-excel",xlsx:"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",ppt:"application/vnd.ms-powerpoint",pptx:"application/vnd.openxmlformats-officedocument.presentationml.presentation",eml:"message/rfc822",msg:"application/vnd.ms-outlook",ics:"text/calendar",rtf:"application/rtf",mp3:"audio/mpeg",mp4:"video/mp4"};function dt(t){let e=/\.([A-Za-z0-9]+)$/.exec(t||"");return e&&Fe[e[1].toLowerCase()]||"application/octet-stream"}function Wt(t){return String(t||"file").replace(/[\\/:*?"<>|\r\n\t]+/g,"_").replace(/^\.+/,"").slice(0,120)||"file"}function Qt(t){let e=/^(.*?)(\.[A-Za-z0-9]{1,3})?$/.exec(t||"file");return((e[1]||"file").replace(/[^A-Za-z0-9_-]/g,"").slice(0,8)||"file")+(e[2]||"")}function Xt(t,e){return(String(t).replace(/\.[^.\\/]+$/,"")||"message")+e}function Ue(t,e){let n="";for(let o=0;o<Math.min(t.length,2048);o++)n+=String.fromCharCode(t[o]);let r=/charset\s*=\s*["']?\s*([\w-]+)/i.exec(n);return r?r[1]:e}function Et(t,e,n,r,o){let i=t.str(e),c=t.str(o);if(!c){let u=(t.str(r)||"").toUpperCase(),l=t.str(n);(u==="SMTP"||l&&l.indexOf("@")>0&&l.indexOf("/")<0)&&(c=l)}return{name:i,email:c}}function Kt(t,e,n,r,o){let i=new tt(t,e,n),c={messageClass:i.str(a.MESSAGE_CLASS),subject:i.str(a.SUBJECT)||i.str(a.NORMALIZED_SUBJECT),messageId:i.str(a.INTERNET_MESSAGE_ID),inReplyTo:i.str(a.IN_REPLY_TO_ID),references:i.str(a.INTERNET_REFERENCES),date:i.date(a.CLIENT_SUBMIT_TIME)||i.date(a.DELIVERY_TIME)||i.date(a.LAST_MODIFICATION_TIME)||null,importance:i.int(a.IMPORTANCE),text:i.str(a.BODY),html:"",to:[],cc:[],bcc:[],attachments:[],headers:b.parse(i.str(a.TRANSPORT_HEADERS)),props:i},u=Et(i,a.SENT_REP_NAME,a.SENT_REP_EMAIL,a.SENT_REP_ADDRTYPE,a.SENT_REP_SMTP);if(!u.email&&!u.name)u=Et(i,a.SENDER_NAME,a.SENDER_EMAIL,a.SENDER_ADDRTYPE,a.SENDER_SMTP);else if(!u.email){let h=Et(i,a.SENDER_NAME,a.SENDER_EMAIL,a.SENDER_ADDRTYPE,a.SENDER_SMTP);h.email&&(u.email=h.email)}c.from=u;let l=i.bin(a.HTML);if(l&&l.length?c.html=O(l,Ue(l,i.charset)):i.vars[H(a.HTML)+"001F"]&&(c.html=lt(i.vars[H(a.HTML)+"001F"])),!c.html){let h=i.bin(a.RTF_COMPRESSED);if(h){let d=Vt(h);if(d){let p=i.charset,g=Zt(d,S=>O(S,p));g&&(c.html=g)}}}for(let h of i.storagesMatching(/^__recip_version1\.0_/)){let d=new tt(t,h,j.RECIPIENT),p=Et(d,a.DISPLAY_NAME,a.EMAIL_ADDRESS,a.ADDRTYPE,a.SMTP_ADDRESS);if(!p.email&&!p.name)continue;let g=d.int(a.RECIPIENT_TYPE);g===Z.CC?c.cc.push(p):g===Z.BCC?c.bcc.push(p):c.to.push(p)}!c.to.length&&!c.cc.length&&(c.to=V(i.str(a.DISPLAY_TO)),c.cc=V(i.str(a.DISPLAY_CC)));for(let h of i.storagesMatching(/^__attach_version1\.0_/)){let d=new tt(t,h,j.ATTACHMENT),p=d.int(a.ATTACH_METHOD),g=d.str(a.ATTACH_LONG_FILENAME)||d.str(a.ATTACH_FILENAME),S=d.str(a.ATTACH_CONTENT_ID),E=d.str(a.ATTACH_MIME_TAG),I=d.int(a.ATTACH_FLAGS)||0,_=d.bool(a.ATTACHMENT_HIDDEN);if(p===Gt.EMBEDDED_MSG){let A=d.childMap[ot(a.ATTACH_DATA_BIN,Y.OBJECT)];if(A&&o<10)try{let D=Kt(t,A,j.EMBEDDED,r,o+1);c.attachments.push({filename:Wt(g||D.subject||"message")+".eml",mime:"message/rfc822",embedded:D,cid:S,inline:!1})}catch{}continue}let C=g||"attachment"+(c.attachments.length+1)+(d.str(a.ATTACH_EXTENSION)||".bin"),M={filename:C,mime:E||dt(C),cid:S,inline:!!S&&((I&4)!==0||_===!0||!!c.html&&c.html.indexOf("cid:"+S)>=0)};if(r.lazy){let A=null;if(Object.defineProperty(M,"data",{enumerable:!0,configurable:!0,get(){return A||(A=d.bin(a.ATTACH_DATA_BIN)||new Uint8Array(0)),A}}),!d.has(a.ATTACH_DATA_BIN))continue}else{let A=d.bin(a.ATTACH_DATA_BIN);if(!A)continue;M.data=A}c.attachments.push(M)}return c}function te(t,e={}){let n=yt(t);return Kt(n,n.root,j.TOP_LEVEL,e,0)}var Oe=1,Pe=262144,ee=65001,Le=4,Dt=t=>t.name||t.email;function ne(t){let e=Yt(vt),n=pt(e,"__nameid_version1.0");q(n,"__substg1.0_00020102",new Uint8Array(0)),q(n,"__substg1.0_00030102",new Uint8Array(0)),q(n,"__substg1.0_00040102",new Uint8Array(0));let r=t.to||[],o=t.cc||[],i=t.bcc||[],c=t.attachments||[],u=t.from||{name:"",email:""},l=new et(e,j.TOP_LEVEL);l.str(a.MESSAGE_CLASS,t.messageClass||"IPM.Note"),l.str(a.SUBJECT,t.subject||""),l.str(a.NORMALIZED_SUBJECT,(t.subject||"").replace(/^\s*(re|fw|fwd)\s*:\s*/i,"")),l.str(a.BODY,t.text||""),t.html&&l.bin(a.HTML,L(t.html)),t.headersRaw&&l.str(a.TRANSPORT_HEADERS,t.headersRaw),l.str(a.INTERNET_MESSAGE_ID,t.messageId||""),l.str(a.IN_REPLY_TO_ID,t.inReplyTo||""),l.str(a.INTERNET_REFERENCES,t.references||"");let h=u.email?"SMTP":"";l.str(a.SENDER_NAME,u.name||u.email||""),l.str(a.SENDER_EMAIL,u.email||""),l.str(a.SENDER_ADDRTYPE,h),l.str(a.SENDER_SMTP,u.email||""),l.str(a.SENT_REP_NAME,u.name||u.email||""),l.str(a.SENT_REP_EMAIL,u.email||""),l.str(a.SENT_REP_ADDRTYPE,h),l.str(a.SENT_REP_SMTP,u.email||""),l.str(a.DISPLAY_TO,r.map(Dt).join("; ")),l.str(a.DISPLAY_CC,o.map(Dt).join("; ")),l.str(a.DISPLAY_BCC,i.map(Dt).join("; ")),l.time(a.CLIENT_SUBMIT_TIME,t.date),l.time(a.DELIVERY_TIME,t.date),l.time(a.CREATION_TIME,t.date||new Date),l.time(a.LAST_MODIFICATION_TIME,new Date),l.int32(a.MESSAGE_FLAGS,Oe),l.int32(a.STORE_SUPPORT_MASK,Pe),l.int32(a.INTERNET_CPID,ee),l.int32(a.MESSAGE_CODEPAGE,ee),t.importance!=null&&l.int32(a.IMPORTANCE,t.importance),l.bool(a.HASATTACH,c.length>0);let d=[...r.map(p=>({a:p,t:Z.TO})),...o.map(p=>({a:p,t:Z.CC})),...i.map(p=>({a:p,t:Z.BCC}))];return d.forEach((p,g)=>{let S=pt(e,"__recip_version1.0_#"+It(g)),E=new et(S,j.RECIPIENT);E.int32(a.ROWID,g),E.int32(a.RECIPIENT_TYPE,p.t),E.int32(a.OBJECT_TYPE,6),E.int32(a.DISPLAY_TYPE,0),E.str(a.DISPLAY_NAME,p.a.name||p.a.email),E.str(a.EMAIL_ADDRESS,p.a.email),E.str(a.SMTP_ADDRESS,p.a.email),E.str(a.ADDRTYPE,"SMTP"),E.finish()}),c.forEach((p,g)=>{let S=pt(e,"__attach_version1.0_#"+It(g)),E=new et(S,j.ATTACHMENT);E.int32(a.ATTACH_NUM,g),E.int32(a.ATTACH_METHOD,1),E.int32(a.OBJECT_TYPE,7),E.int32(a.ATTACH_SIZE,p.data.length),E.int32(a.RENDERING_POSITION,-1),E.bin(a.ATTACH_DATA_BIN,p.data),E.str(a.ATTACH_LONG_FILENAME,p.filename),E.str(a.ATTACH_FILENAME,Qt(p.filename));let I=/\.[A-Za-z0-9]+$/.exec(p.filename);I&&E.str(a.ATTACH_EXTENSION,I[0]),E.str(a.ATTACH_MIME_TAG,p.mime||dt(p.filename)),p.cid&&(E.str(a.ATTACH_CONTENT_ID,p.cid),p.inline&&(E.int32(a.ATTACH_FLAGS,Le),E.bool(a.ATTACHMENT_HIDDEN,!0))),E.finish()}),l.finish(p=>{p.setUint32(8,d.length,!0),p.setUint32(12,c.length,!0),p.setUint32(16,d.length,!0),p.setUint32(20,c.length,!0)}),jt(e)}var be=new Set(["mime-version","content-type","content-transfer-encoding","content-disposition","content-id","content-description","content-language","content-location"]),Be={low:0,normal:1,high:2},W=class t{constructor(e={}){this.subject=e.subject||"",this.from=e.from||{name:"",email:""},this.to=e.to||[],this.cc=e.cc||[],this.bcc=e.bcc||[],this.date=e.date||null,this.messageId=e.messageId||"",this.inReplyTo=e.inReplyTo||"",this.references=e.references||"",this.importance=e.importance==null?null:e.importance,this.messageClass=e.messageClass||"IPM.Note",this.text=e.text||"",this.html=e.html||"",this.attachments=e.attachments||[],this.headers=e.headers instanceof b?e.headers:new b(e.headers||[]),this.props=e.props||null}static fromMsg(e,n={}){let r=te(e,n);return r.attachments=r.attachments.map(o=>{if(!o.embedded)return o;let{embedded:i,...c}=o;return{...c,data:new t(i).toEml()}}),new t(r)}static fromEml(e){let n=Bt(e),r=n.headers;return new t({subject:K(r.get("subject")||""),from:V(r.get("from")||"")[0]||{name:"",email:""},to:V(r.get("to")||""),cc:V(r.get("cc")||""),bcc:V(r.get("bcc")||""),date:Ut(r.get("date")),messageId:r.get("message-id")||"",inReplyTo:r.get("in-reply-to")||"",references:r.get("references")||"",importance:Be[(r.get("importance")||"").toLowerCase()]??null,text:n.text,html:n.html,attachments:n.attachments,headers:r})}toEml(){let e=[],n=new Set;for(let[i,c]of this.headers)be.has(i.toLowerCase())||(e.push([i,c]),n.add(i.toLowerCase()));let r=(i,c)=>{!c||n.has(i.toLowerCase())||(e.push([i,c]),n.add(i.toLowerCase()))},o=i=>i.map(c=>xt(c.name,c.email)).filter(Boolean).join(", ");return this.date&&r("Date",Ft(this.date)),(this.from.email||this.from.name)&&r("From",xt(this.from.name,this.from.email)),this.to.length&&r("To",o(this.to)),this.cc.length&&r("Cc",o(this.cc)),this.bcc.length&&r("Bcc",o(this.bcc)),n.has("subject")||r("Subject",ht(this.subject||"")||" "),r("Message-ID",this.messageId),r("In-Reply-To",this.inReplyTo),r("References",this.references),Pt({headers:e,text:this.text,html:this.html,attachments:this.attachments})}toMsg(){return ne({messageClass:this.messageClass,subject:this.subject,from:this.from,to:this.to,cc:this.cc,bcc:this.bcc,date:this.date,messageId:this.messageId,inReplyTo:this.inReplyTo,references:this.references,importance:this.importance,text:this.text,html:this.html,attachments:this.attachments,headersRaw:this.headers.entries.length?this.headers.raw:""})}};var ye="0.1.0",He=[208,207,17,224,161,177,26,225];function re(t,e){if(t&&t.length>=8){let r=!0;for(let o=0;o<8;o++)if(t[o]!==He[o]){r=!1;break}if(r)return"msg"}let n=(/\.([^.]+)$/.exec(e||"")||[])[1];return n&&n.toLowerCase()==="msg"?"msg":"eml"}function Ye(t,e={}){if(!t||!t.length)throw new R(U.EMPTY_INPUT,"File is empty");let n=e.from||re(t,e.filename),r=e.to||(n==="msg"?"eml":"msg"),o=n==="msg"?W.fromMsg(t,{lazy:e.lazy}):W.fromEml(t);return{data:r==="msg"?o.toMsg():o.toEml(),format:r,sourceFormat:n,mime:r==="msg"?"application/vnd.ms-outlook":"message/rfc822",filename:e.filename?Xt(e.filename,"."+r):void 0,message:o}}return le(je);})();
|
package/package.json
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "mailfile",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Read and write Outlook .msg and RFC 5322 .eml files. Zero dependencies, runs in browsers, Node, Deno, Bun and workers.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Scott McKellar",
|
|
8
|
+
"repository": {
|
|
9
|
+
"type": "git",
|
|
10
|
+
"url": "git+https://github.com/smck83/mailfile.git"
|
|
11
|
+
},
|
|
12
|
+
"homepage": "https://github.com/smck83/mailfile#readme",
|
|
13
|
+
"bugs": {
|
|
14
|
+
"url": "https://github.com/smck83/mailfile/issues"
|
|
15
|
+
},
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"engines": {
|
|
18
|
+
"node": ">=18"
|
|
19
|
+
},
|
|
20
|
+
"main": "./dist/mailfile.cjs",
|
|
21
|
+
"module": "./src/index.js",
|
|
22
|
+
"types": "./types/index.d.ts",
|
|
23
|
+
"unpkg": "./dist/mailfile.min.js",
|
|
24
|
+
"jsdelivr": "./dist/mailfile.min.js",
|
|
25
|
+
"exports": {
|
|
26
|
+
".": {
|
|
27
|
+
"types": "./types/index.d.ts",
|
|
28
|
+
"require": "./dist/mailfile.cjs",
|
|
29
|
+
"default": "./src/index.js"
|
|
30
|
+
},
|
|
31
|
+
"./cfb": {
|
|
32
|
+
"types": "./types/cfb/index.d.ts",
|
|
33
|
+
"default": "./src/cfb/index.js"
|
|
34
|
+
},
|
|
35
|
+
"./mime": {
|
|
36
|
+
"types": "./types/mime/index.d.ts",
|
|
37
|
+
"default": "./src/mime/index.js"
|
|
38
|
+
},
|
|
39
|
+
"./mapi": {
|
|
40
|
+
"types": "./types/mapi/index.d.ts",
|
|
41
|
+
"default": "./src/mapi/index.js"
|
|
42
|
+
},
|
|
43
|
+
"./rtf": {
|
|
44
|
+
"types": "./types/rtf/index.d.ts",
|
|
45
|
+
"default": "./src/rtf/index.js"
|
|
46
|
+
},
|
|
47
|
+
"./package.json": "./package.json"
|
|
48
|
+
},
|
|
49
|
+
"files": [
|
|
50
|
+
"src",
|
|
51
|
+
"dist",
|
|
52
|
+
"types",
|
|
53
|
+
"README.md",
|
|
54
|
+
"LICENSE"
|
|
55
|
+
],
|
|
56
|
+
"scripts": {
|
|
57
|
+
"build": "node scripts/build.js",
|
|
58
|
+
"types": "tsc -p tsconfig.json",
|
|
59
|
+
"test": "node --test",
|
|
60
|
+
"corpus": "node scripts/corpus.js",
|
|
61
|
+
"prepublishOnly": "npm run build && npm run types && npm test"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"msg",
|
|
65
|
+
"eml",
|
|
66
|
+
"outlook",
|
|
67
|
+
"email",
|
|
68
|
+
"mime",
|
|
69
|
+
"rfc5322",
|
|
70
|
+
"mapi",
|
|
71
|
+
"cfb",
|
|
72
|
+
"ole2",
|
|
73
|
+
"compound-file",
|
|
74
|
+
"rtf",
|
|
75
|
+
"lzfu",
|
|
76
|
+
"converter",
|
|
77
|
+
"browser"
|
|
78
|
+
],
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@kenjiuno/msgreader": "^1.22.0",
|
|
81
|
+
"esbuild": "^0.24.0",
|
|
82
|
+
"typescript": "^5.6.3"
|
|
83
|
+
}
|
|
84
|
+
}
|
package/src/cfb/index.js
ADDED
package/src/cfb/read.js
ADDED
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Compound File Binary (OLE2 / CFBF) reader — MS-CFB.
|
|
3
|
+
* Used by .msg, but also by legacy .doc/.xls/.ppt, .msi and Thumbs.db.
|
|
4
|
+
*/
|
|
5
|
+
import { MailfileError, ErrorCode } from '../errors.js';
|
|
6
|
+
|
|
7
|
+
const SIG = [0xD0, 0xCF, 0x11, 0xE0, 0xA1, 0xB1, 0x1A, 0xE1];
|
|
8
|
+
const FREESECT = 0xFFFFFFFF;
|
|
9
|
+
const ENDOFCHAIN = 0xFFFFFFFE;
|
|
10
|
+
const NOSTREAM = 0xFFFFFFFF;
|
|
11
|
+
const MINI_CUTOFF = 4096;
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @typedef {object} DirEntry
|
|
15
|
+
* @property {number} id
|
|
16
|
+
* @property {string} name
|
|
17
|
+
* @property {number} type 1 = storage, 2 = stream, 5 = root
|
|
18
|
+
* @property {number} start First sector of the stream.
|
|
19
|
+
* @property {number} size Stream length in bytes.
|
|
20
|
+
* @property {number} left Left sibling id in the storage's red-black tree.
|
|
21
|
+
* @property {number} right Right sibling id.
|
|
22
|
+
* @property {number} child First child id, for storages.
|
|
23
|
+
* @property {{list: DirEntry[], map: Record<string, DirEntry>}|null} children
|
|
24
|
+
* Memoised child index, filled in by `childrenOf`.
|
|
25
|
+
*/
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* @typedef {object} CfbFile
|
|
29
|
+
* @property {DirEntry} root
|
|
30
|
+
* @property {DirEntry[]} entries
|
|
31
|
+
* @property {(entry: DirEntry) => Uint8Array} readStream
|
|
32
|
+
* @property {(entry: DirEntry) => {list: DirEntry[], map: Record<string, DirEntry>}} childrenOf
|
|
33
|
+
*/
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Parse a compound file.
|
|
37
|
+
* @param {Uint8Array} bytes
|
|
38
|
+
* @returns {CfbFile}
|
|
39
|
+
*/
|
|
40
|
+
export function read(bytes) {
|
|
41
|
+
if (!bytes || !bytes.length) {
|
|
42
|
+
throw new MailfileError(ErrorCode.EMPTY_INPUT, 'No data to read');
|
|
43
|
+
}
|
|
44
|
+
if (bytes.length < 512) {
|
|
45
|
+
throw new MailfileError(ErrorCode.NOT_COMPOUND_FILE,
|
|
46
|
+
'File is too small to be a compound file');
|
|
47
|
+
}
|
|
48
|
+
const dv = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
|
|
49
|
+
for (let i = 0; i < 8; i++) {
|
|
50
|
+
if (bytes[i] !== SIG[i]) {
|
|
51
|
+
throw new MailfileError(ErrorCode.NOT_COMPOUND_FILE,
|
|
52
|
+
'Not a compound file (bad OLE signature)');
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const sectorSize = 1 << dv.getUint16(30, true);
|
|
57
|
+
const miniSectorSize = 1 << dv.getUint16(32, true);
|
|
58
|
+
const numFatSectors = dv.getUint32(44, true);
|
|
59
|
+
const firstDirSector = dv.getUint32(48, true);
|
|
60
|
+
const miniCutoff = dv.getUint32(56, true) || MINI_CUTOFF;
|
|
61
|
+
const firstMiniFat = dv.getUint32(60, true);
|
|
62
|
+
const firstDifat = dv.getUint32(68, true);
|
|
63
|
+
|
|
64
|
+
if (sectorSize < 128 || sectorSize > 65536) {
|
|
65
|
+
throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Invalid sector size');
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
const maxSector = Math.floor((bytes.length - sectorSize) / sectorSize);
|
|
69
|
+
const sectorOffset = (s) => (s + 1) * sectorSize;
|
|
70
|
+
function checkSector(s) {
|
|
71
|
+
if (s > maxSector || s < 0) {
|
|
72
|
+
throw new MailfileError(ErrorCode.CORRUPT_CFB,
|
|
73
|
+
'Sector reference outside the file (offset ' + s + ')');
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// DIFAT -> list of FAT sector numbers
|
|
78
|
+
const fatSectors = [];
|
|
79
|
+
for (let d = 0; d < 109 && fatSectors.length < numFatSectors; d++) {
|
|
80
|
+
const v = dv.getUint32(76 + d * 4, true);
|
|
81
|
+
if (v === FREESECT || v === ENDOFCHAIN) break;
|
|
82
|
+
fatSectors.push(v);
|
|
83
|
+
}
|
|
84
|
+
let difSec = firstDifat;
|
|
85
|
+
let guard = 0;
|
|
86
|
+
while (difSec !== ENDOFCHAIN && difSec !== FREESECT &&
|
|
87
|
+
guard++ < 100000 && fatSectors.length < numFatSectors) {
|
|
88
|
+
checkSector(difSec);
|
|
89
|
+
const base = sectorOffset(difSec);
|
|
90
|
+
for (let k = 0; k < (sectorSize / 4) - 1; k++) {
|
|
91
|
+
const fv = dv.getUint32(base + k * 4, true);
|
|
92
|
+
if (fv === FREESECT || fv === ENDOFCHAIN) break;
|
|
93
|
+
fatSectors.push(fv);
|
|
94
|
+
}
|
|
95
|
+
difSec = dv.getUint32(base + sectorSize - 4, true);
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// FAT
|
|
99
|
+
const perSector = sectorSize / 4;
|
|
100
|
+
const fat = new Uint32Array(fatSectors.length * perSector);
|
|
101
|
+
for (let f = 0; f < fatSectors.length; f++) {
|
|
102
|
+
checkSector(fatSectors[f]);
|
|
103
|
+
const off = sectorOffset(fatSectors[f]);
|
|
104
|
+
for (let j = 0; j < perSector; j++) {
|
|
105
|
+
fat[f * perSector + j] = dv.getUint32(off + j * 4, true);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function chain(start) {
|
|
110
|
+
const out = [];
|
|
111
|
+
let s = start;
|
|
112
|
+
let n = 0;
|
|
113
|
+
while (s !== ENDOFCHAIN && s !== FREESECT && s !== undefined) {
|
|
114
|
+
if (n++ > fat.length + 8) {
|
|
115
|
+
throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Sector chain loops back on itself');
|
|
116
|
+
}
|
|
117
|
+
checkSector(s);
|
|
118
|
+
out.push(s);
|
|
119
|
+
s = fat[s];
|
|
120
|
+
}
|
|
121
|
+
return out;
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
function readSectors(list, size) {
|
|
125
|
+
const out = new Uint8Array(list.length * sectorSize);
|
|
126
|
+
for (let i = 0; i < list.length; i++) {
|
|
127
|
+
out.set(bytes.subarray(sectorOffset(list[i]), sectorOffset(list[i]) + sectorSize),
|
|
128
|
+
i * sectorSize);
|
|
129
|
+
}
|
|
130
|
+
return size == null ? out : out.subarray(0, size);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// MiniFAT
|
|
134
|
+
const miniFatBytes = readSectors(chain(firstMiniFat));
|
|
135
|
+
const miniFat = new Uint32Array(miniFatBytes.length >> 2);
|
|
136
|
+
const mdv = new DataView(miniFatBytes.buffer, miniFatBytes.byteOffset, miniFatBytes.byteLength);
|
|
137
|
+
for (let m = 0; m < miniFat.length; m++) miniFat[m] = mdv.getUint32(m * 4, true);
|
|
138
|
+
|
|
139
|
+
// Directory
|
|
140
|
+
const dirBytes = readSectors(chain(firstDirSector));
|
|
141
|
+
const count = Math.floor(dirBytes.length / 128);
|
|
142
|
+
const ddv = new DataView(dirBytes.buffer, dirBytes.byteOffset, dirBytes.byteLength);
|
|
143
|
+
const entries = [];
|
|
144
|
+
for (let e = 0; e < count; e++) {
|
|
145
|
+
const o = e * 128;
|
|
146
|
+
const nameLen = ddv.getUint16(o + 64, true);
|
|
147
|
+
let name = '';
|
|
148
|
+
for (let c = 0; c + 1 < nameLen - 1; c += 2) {
|
|
149
|
+
const code = ddv.getUint16(o + c, true);
|
|
150
|
+
if (code === 0) break;
|
|
151
|
+
name += String.fromCharCode(code);
|
|
152
|
+
}
|
|
153
|
+
entries.push({
|
|
154
|
+
id: e,
|
|
155
|
+
name,
|
|
156
|
+
type: ddv.getUint8(o + 66),
|
|
157
|
+
left: ddv.getUint32(o + 68, true),
|
|
158
|
+
right: ddv.getUint32(o + 72, true),
|
|
159
|
+
child: ddv.getUint32(o + 76, true),
|
|
160
|
+
start: ddv.getUint32(o + 116, true),
|
|
161
|
+
size: ddv.getUint32(o + 120, true) + ddv.getUint32(o + 124, true) * 4294967296,
|
|
162
|
+
children: null
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
if (!entries.length) {
|
|
166
|
+
throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Compound file has no directory');
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const root = entries[0];
|
|
170
|
+
const miniStream = readSectors(chain(root.start), root.size);
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* @param {DirEntry} entry
|
|
174
|
+
* @returns {Uint8Array}
|
|
175
|
+
*/
|
|
176
|
+
function readStream(entry) {
|
|
177
|
+
if (!entry || entry.type !== 2 || !entry.size) return new Uint8Array(0);
|
|
178
|
+
if (entry.size < miniCutoff) {
|
|
179
|
+
const out = new Uint8Array(entry.size);
|
|
180
|
+
let s = entry.start;
|
|
181
|
+
let pos = 0;
|
|
182
|
+
let n = 0;
|
|
183
|
+
while (s !== ENDOFCHAIN && s !== FREESECT && pos < entry.size) {
|
|
184
|
+
if (n++ > miniFat.length + 8) {
|
|
185
|
+
throw new MailfileError(ErrorCode.CORRUPT_CFB, 'Mini sector chain loops back on itself');
|
|
186
|
+
}
|
|
187
|
+
const take = Math.min(miniSectorSize, entry.size - pos);
|
|
188
|
+
out.set(miniStream.subarray(s * miniSectorSize, s * miniSectorSize + take), pos);
|
|
189
|
+
pos += take;
|
|
190
|
+
s = miniFat[s];
|
|
191
|
+
}
|
|
192
|
+
return out;
|
|
193
|
+
}
|
|
194
|
+
return readSectors(chain(entry.start), entry.size);
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Each storage's children live in a red-black tree; walk it in order.
|
|
198
|
+
function collect(nodeId, into, seen) {
|
|
199
|
+
if (nodeId === NOSTREAM || nodeId >= entries.length || seen[nodeId]) return;
|
|
200
|
+
seen[nodeId] = 1;
|
|
201
|
+
const n = entries[nodeId];
|
|
202
|
+
collect(n.left, into, seen);
|
|
203
|
+
into.push(n);
|
|
204
|
+
collect(n.right, into, seen);
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* @param {DirEntry} entry
|
|
209
|
+
*/
|
|
210
|
+
function childrenOf(entry) {
|
|
211
|
+
if (entry.children) return entry.children;
|
|
212
|
+
const list = [];
|
|
213
|
+
collect(entry.child, list, {});
|
|
214
|
+
const map = Object.create(null);
|
|
215
|
+
for (let i = 0; i < list.length; i++) map[list[i].name] = list[i];
|
|
216
|
+
entry.children = { list, map };
|
|
217
|
+
return entry.children;
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
return { root, entries, readStream, childrenOf };
|
|
221
|
+
}
|