From 40c6036085794724338f43554d9e395655cc29d2 Mon Sep 17 00:00:00 2001 From: SheetJS Date: Sat, 29 Feb 2020 23:55:36 -0500 Subject: [PATCH] 1.0.0: a new hope --- .github/FUNDING.yml | 3 + .gitignore | 4 + LICENSE | 201 +++++++++++++ Makefile | 18 ++ README.md | 92 ++++++ dist/wmf.js | 2 + dist/wmf.js.map | 1 + dist/wmf.node.js | 2 + dist/wmf.node.js.map | 1 + index.html | 94 ++++++ js/Records.js | 37 +++ js/Records.js.map | 1 + js/canvas.js | 112 +++++++ js/canvas.js.map | 1 + js/index.js | 21 ++ js/index.js.map | 1 + js/util.js | 395 ++++++++++++++++++++++++ js/util.js.map | 1 + js/wmf.js | 428 ++++++++++++++++++++++++++ js/wmf.js.map | 1 + misc/entry.js | 3 + misc/webpack.browser.config.js | 37 +++ misc/webpack.node.config.js | 39 +++ package.json | 20 ++ src/Records.ts | 50 ++++ src/canvas.ts | 98 ++++++ src/index.ts | 17 ++ src/util.ts | 297 ++++++++++++++++++ src/wmf.ts | 533 +++++++++++++++++++++++++++++++++ test/.gitignore | 2 + test/fetch.html | 17 ++ test/filereader.html | 21 ++ test/node-canvas.js | 20 ++ test/parcel.html | 17 ++ test/parcel.js | 38 +++ test/wmf.js | 1 + tsconfig.json | 10 + 37 files changed, 2636 insertions(+) create mode 100644 .github/FUNDING.yml create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README.md create mode 100644 dist/wmf.js create mode 100644 dist/wmf.js.map create mode 100644 dist/wmf.node.js create mode 100644 dist/wmf.node.js.map create mode 100644 index.html create mode 100644 js/Records.js create mode 100644 js/Records.js.map create mode 100644 js/canvas.js create mode 100644 js/canvas.js.map create mode 100644 js/index.js create mode 100644 js/index.js.map create mode 100644 js/util.js create mode 100644 js/util.js.map create mode 100644 js/wmf.js create mode 100644 js/wmf.js.map create mode 100644 misc/entry.js create mode 100644 misc/webpack.browser.config.js create mode 100644 misc/webpack.node.config.js create mode 100644 package.json create mode 100644 src/Records.ts create mode 100644 src/canvas.ts create mode 100644 src/index.ts create mode 100644 src/util.ts create mode 100644 src/wmf.ts create mode 100644 test/.gitignore create mode 100644 test/fetch.html create mode 100644 test/filereader.html create mode 100644 test/node-canvas.js create mode 100644 test/parcel.html create mode 100644 test/parcel.js create mode 120000 test/wmf.js create mode 100644 tsconfig.json diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..092bd24 --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1,3 @@ +github: SheetJSDev +custom: https://sheetjs.com +open_collective: s5s diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d1c7bf2 --- /dev/null +++ b/.gitignore @@ -0,0 +1,4 @@ +fonts/ +node_modules/ +*.[wWeE][mM][fF] +*.[pP][nN][gG] diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..39cf482 --- /dev/null +++ b/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "{}" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright (C) 2020-present SheetJS LLC + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..a052c22 --- /dev/null +++ b/Makefile @@ -0,0 +1,18 @@ +.PHONY: all +all: node browser + +.PHONY: src/index.ts +js/index.js: src/index.ts + #tsc src/index.ts + tsc + +node: js/index.js + webpack-cli --config misc/webpack.node.config.js + +browser: js/index.js + webpack-cli --config misc/webpack.browser.config.js + +.PHONY: dist prod +dist prod: js/index.js + webpack-cli --mode=production --config misc/webpack.node.config.js + webpack-cli --mode=production --config misc/webpack.browser.config.js diff --git a/README.md b/README.md new file mode 100644 index 0000000..0b502de --- /dev/null +++ b/README.md @@ -0,0 +1,92 @@ +# js-wmf + +Processor for Windows MetaFile (WMF) files in JS (for the browser and nodejs). + + +## Installation + +With [npm](https://www.npmjs.org/package/wmf): + +```bash +$ npm install wmf +``` + +In the browser: + +```html + +``` + +The browser exposes a variable `WMF`. + + +## Usage + +The `data` argument is expected to be an `ArrayBuffer`, `Uint8Array` or `Buffer` + +- `WMF.image_size(data)` extracts the image offset and extents, returns an Array + `[width, height]` where both metrics are measured in pixels. + +- `WMF.draw_canvas(data, canvas)` parses the WMF and draws to a `Canvas`. + +### Notes + +- The library assumes the global `ImageData` is available. For nodejs-powered + canvas implementations, a shim must be exposed as a global. Using the `canvas` + npm package: + +```js +const { createImageData } = require("canvas"); +global.ImageData = createImageData; +``` + +- `OffscreenCanvas` in Chrome and some other Canvas implementations require + the dimensions in the constructor: + +```js +const size = WMF.image_size(data); +const canvas = new OffscreenCanvas(size[0], size[1]); +``` + + +## Examples + +
+ Browser Fetch into canvas (click to show) + +```js +// assume `canvas` is a DOM element +(async() => { + const res = await fetch("url/for/image.wmf"); + const ab = await res.arrayBuffer(); + WMF.draw_canvas(ab, document.getElementById("canvas")); +})(); +``` + +
+ +
+ NodeJS (using `canvas` npm module) (click to show) + +```js +const { createCanvas, createImageData } = require("canvas"); +global.ImageData = createImageData; + +const size = WMF.image_size(data); +const canvas = createCanvas(size[0], size[1]); +WMF.draw_canvas(data, canvas); +``` + +
+ + +## License + +Please consult the attached LICENSE file for details. All rights not explicitly +granted by the Apache 2.0 License are reserved by the Original Author. + + +## References + + - [MS-WMF]: Windows Metafile Format + diff --git a/dist/wmf.js b/dist/wmf.js new file mode 100644 index 0000000..b4ebc37 --- /dev/null +++ b/dist/wmf.js @@ -0,0 +1,2 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +var WMF=function(e){var n={};function i(t){if(n[t])return n[t].exports;var r=n[t]={i:t,l:!1,exports:{}};return e[t].call(r.exports,r,r.exports,i),r.l=!0,r.exports}return i.m=e,i.c=n,i.d=function(t,r,e){i.o(t,r)||Object.defineProperty(t,r,{enumerable:!0,get:e})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(r,t){if(1&t&&(r=i(r)),8&t)return r;if(4&t&&"object"==typeof r&&r&&r.__esModule)return r;var e=Object.create(null);if(i.r(e),Object.defineProperty(e,"default",{enumerable:!0,value:r}),2&t&&"string"!=typeof r)for(var n in r)i.d(e,n,function(t){return r[t]}.bind(null,n));return e},i.n=function(t){var r=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(r,"a",r),r},i.o=function(t,r){return Object.prototype.hasOwnProperty.call(t,r)},i.p="",i(i.s=2)}([function(t,U,r){"use strict";(function(u){Object.defineProperty(U,"__esModule",{value:!0});var t,c=!(void 0===u||"undefined"==typeof process||void 0===process.versions||!process.versions.node);if(U.has_buf=c,U.Buffer_from=t,void 0!==u){var r=!u.from;if(!r)try{u.from("foo","utf8")}catch(t){r=!0}U.Buffer_from=t=r?function(t,r){return r?new u(t,r):new u(t)}:u.from.bind(u),u.alloc||(u.alloc=function(t){return new u(t)}),u.allocUnsafe||(u.allocUnsafe=function(t){return new u(t)})}U.new_raw_buf=function(t){return c?u.alloc(t):new Array(t)},U.new_unsafe_buf=function(t){return c?u.allocUnsafe(t):new Array(t)},U._chr=function(t){return String.fromCharCode(t)},U.chr0=/\u0000/g,U.chr1=/[\u0001-\u0006]/g;var l,n,p=function(t,r){return t[r]},d=function(t,r){return 256*t[r+1]+t[r]},g=function(t,r){var e=256*t[r+1]+t[r];return e<32768?e:-1*(65535-e+1)},_=function(t,r){return t[r+3]*(1<<24)+(t[r+2]<<16)+(t[r+1]<<8)+t[r]},y=function(t,r){return t[r+3]<<24|t[r+2]<<16|t[r+1]<<8|t[r]},E=function(t,r){return t[r]<<24|t[r+1]<<16|t[r+2]<<8|t[r+3]},v=function(t,r,e){for(var n=[],i=r;i>>7),n=((127&t[r+7])<<4)+(t[r+6]>>>4&15),i=15&t[r+6],o=5;0<=o;--o)i=256*i+t[r+o];return 2047==n?0==i?1/0*e:NaN:(0==n?n=-1022:(n-=1023,i+=Math.pow(2,52)),e*Math.pow(2,n-52)*i)}(t,r)}var R=S,M=e;function C(t,r){var e,n,i,o,s,a="",f=0,h=[];switch(r){case"dbcs":if(s=this.l,c&&u.isBuffer(this))a=this.slice(this.l,this.l+2*t).toString("utf16le");else for(o=0;o>>8&255;l=2*r.length}else if("sbcs"===e){for(r=r.replace(/[^\x00-\x7F]/g,"_"),p=0;p!=r.length;++p)this[this.l+p]=255&r.charCodeAt(p);l=r.length}else{if("hex"===e){for(;p>8}for(;this.l>>=8,this[this.l+1]=255&r;break;case 3:l=3,this[this.l]=255&r,r>>>=8,this[this.l+1]=255&r,r>>>=8,this[this.l+2]=255&r;break;case 4:l=4,a=r,f=(s=this).l,s[f]=255&a,s[f+1]=a>>>8&255,s[f+2]=a>>>16&255,s[f+3]=a>>>24&255;break;case 8:if(l=8,"f"===e){!function(t,r,e){var n=(r<0||1/r==-1/0?1:0)<<7,i=0,o=0,s=n?-r:r;isFinite(s)?0==s?i=o=0:(i=Math.floor(Math.log(s)/Math.LN2),o=s*Math.pow(2,52-i),i<=-1023&&(!isFinite(o)||o>4|n}(this,r,this.l);break}case 16:break;case-4:l=4,i=r,o=(n=this).l,n[o]=255&i,n[o+1]=i>>8&255,n[o+2]=i>>16&255,n[o+3]=i>>24&255}}return this.l+=l,this}function B(t,r){var e=w(this,this.l,t.length>>1);if(e!==t)throw new Error(r+"Expected "+t+" saw "+e);this.l+=t.length>>1}U.WriteShift=P,U.CheckField=B;function O(t,r){t.l=r,t.read_shift=C,t.chk=B,t.write_shift=P}U.prep_blob=O;U.new_buf=function(t){var r=U.new_raw_buf(t);return O(r,0),r};var I=function(t){for(var r=!0,e=0;e>8),m=t.read_shift(4),S=t.read_shift(2,"i"),R=t.read_shift(2,"i");T||(t.l+=2);var M=t.read_shift(2,"i"),C=t.read_shift(2,"i"),P=t.read_shift(2,"i"),B={t:"cpy",src:[[R,C],[S,M]],dst:[t.read_shift(2,"i"),P],rop:m,s:Object.assign({},c)};if(T){var O=tt(t.slice(t.l,p));B.data=O}r.push(B);break;case 2881:T=e!=3+(n>>8),m=t.read_shift(4);var I=t.read_shift(2,"i"),U=t.read_shift(2,"i");S=t.read_shift(2,"i"),R=t.read_shift(2,"i");T||(t.l+=2);var x=t.read_shift(2,"i"),k=t.read_shift(2,"i");P=t.read_shift(2,"i"),B={t:"str",src:[[R,U],[S,I]],dst:[[t.read_shift(2,"i"),k],[P,x]],rop:m,s:Object.assign({},c)};if(T){O=tt(t.slice(t.l,p));B.data=O}r.push(B);break;case 2610:var L=t.read_shift(2),D=t.read_shift(2),Y=t.read_shift(2);6&t.read_shift(2)&&(t.l+=8);var N=t.read_shift(Y,"cpstr");t.l,r.push({t:"text",v:N,p:[D,L],s:Object.assign({},c)});break;case 805:case 804:for(var F=t.read_shift(2),j=[],H=0;H=e())throw new RangeError("Attempt to allocate Buffer larger than maximum size: 0x"+e().toString(16)+" bytes");return 0|t}function p(t,r){if(c.isBuffer(t))return t.length;if("undefined"!=typeof ArrayBuffer&&"function"==typeof ArrayBuffer.isView&&(ArrayBuffer.isView(t)||t instanceof ArrayBuffer))return t.byteLength;"string"!=typeof t&&(t=""+t);var e=t.length;if(0===e)return 0;for(var n=!1;;)switch(r){case"ascii":case"latin1":case"binary":return e;case"utf8":case"utf-8":case void 0:return L(t).length;case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return 2*e;case"hex":return e>>>1;case"base64":return D(t).length;default:if(n)return L(t).length;r=(""+r).toLowerCase(),n=!0}}function d(t,r,e){var n=t[r];t[r]=t[e],t[e]=n}function g(t,r,e,n,i){if(0===t.length)return-1;if("string"==typeof e?(n=e,e=0):2147483647=t.length){if(i)return-1;e=t.length-1}else if(e<0){if(!i)return-1;e=0}if("string"==typeof r&&(r=c.from(r,n)),c.isBuffer(r))return 0===r.length?-1:_(t,r,e,n,i);if("number"==typeof r)return r&=255,c.TYPED_ARRAY_SUPPORT&&"function"==typeof Uint8Array.prototype.indexOf?i?Uint8Array.prototype.indexOf.call(t,r,e):Uint8Array.prototype.lastIndexOf.call(t,r,e):_(t,[r],e,n,i);throw new TypeError("val must be string, number or Buffer")}function _(t,r,e,n,i){var o,s=1,a=t.length,f=r.length;if(void 0!==n&&("ucs2"===(n=String(n).toLowerCase())||"ucs-2"===n||"utf16le"===n||"utf-16le"===n)){if(t.length<2||r.length<2)return-1;a/=s=2,f/=2,e/=2}function h(t,r){return 1===s?t[r]:t.readUInt16BE(r*s)}if(i){var u=-1;for(o=e;o>8,i=e%256,o.push(i),o.push(n);return o}(r,t.length-e),t,e,n)}function w(t,r,e){return 0===r&&e===t.length?n.fromByteArray(t):n.fromByteArray(t.slice(r,e))}function b(t,r,e){e=Math.min(t.length,e);for(var n=[],i=r;i>>10&1023|55296),u=56320|1023&u),n.push(u),i+=c}return function(t){var r=t.length;if(r<=A)return String.fromCharCode.apply(String,t);var e="",n=0;for(;nthis.length)return"";if((void 0===e||e>this.length)&&(e=this.length),e<=0)return"";if((e>>>=0)<=(r>>>=0))return"";for(t=t||"utf8";;)switch(t){case"hex":return S(this,r,e);case"utf8":case"utf-8":return b(this,r,e);case"ascii":return T(this,r,e);case"latin1":case"binary":return m(this,r,e);case"base64":return w(this,r,e);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return R(this,r,e);default:if(n)throw new TypeError("Unknown encoding: "+t);t=(t+"").toLowerCase(),n=!0}}.apply(this,arguments)},c.prototype.equals=function(t){if(!c.isBuffer(t))throw new TypeError("Argument must be a Buffer");return this===t||0===c.compare(this,t)},c.prototype.inspect=function(){var t="",r=N.INSPECT_MAX_BYTES;return 0r&&(t+=" ... ")),""},c.prototype.compare=function(t,r,e,n,i){if(!c.isBuffer(t))throw new TypeError("Argument must be a Buffer");if(void 0===r&&(r=0),void 0===e&&(e=t?t.length:0),void 0===n&&(n=0),void 0===i&&(i=this.length),r<0||e>t.length||n<0||i>this.length)throw new RangeError("out of range index");if(i<=n&&e<=r)return 0;if(i<=n)return-1;if(e<=r)return 1;if(this===t)return 0;for(var o=(i>>>=0)-(n>>>=0),s=(e>>>=0)-(r>>>=0),a=Math.min(o,s),f=this.slice(n,i),h=t.slice(r,e),u=0;uthis.length)throw new RangeError("Attempt to write outside buffer bounds");n=n||"utf8";for(var o,s,a,f,h,u,c=!1;;)switch(n){case"hex":return y(this,t,r,e);case"utf8":case"utf-8":return h=r,u=e,Y(L(t,(f=this).length-h),f,h,u);case"ascii":return E(this,t,r,e);case"latin1":case"binary":return E(this,t,r,e);case"base64":return o=this,s=r,a=e,Y(D(t),o,s,a);case"ucs2":case"ucs-2":case"utf16le":case"utf-16le":return v(this,t,r,e);default:if(c)throw new TypeError("Unknown encoding: "+n);n=(""+n).toLowerCase(),c=!0}},c.prototype.toJSON=function(){return{type:"Buffer",data:Array.prototype.slice.call(this._arr||this,0)}};var A=4096;function T(t,r,e){var n="";e=Math.min(t.length,e);for(var i=r;it.length)throw new RangeError("Index out of range")}function P(t,r,e,n){r<0&&(r=65535+r+1);for(var i=0,o=Math.min(t.length-e,2);i>>8*(n?i:1-i)}function B(t,r,e,n){r<0&&(r=4294967295+r+1);for(var i=0,o=Math.min(t.length-e,4);i>>8*(n?i:3-i)&255}function O(t,r,e,n){if(e+n>t.length)throw new RangeError("Index out of range");if(e<0)throw new RangeError("Index out of range")}function I(t,r,e,n,i){return i||O(t,0,e,4),o.write(t,r,e,n,23,4),e+4}function U(t,r,e,n,i){return i||O(t,0,e,8),o.write(t,r,e,n,52,8),e+8}c.prototype.slice=function(t,r){var e,n=this.length;if((t=~~t)<0?(t+=n)<0&&(t=0):n>>8):P(this,t,r,!0),r+2},c.prototype.writeUInt16BE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,2,65535,0),c.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):P(this,t,r,!1),r+2},c.prototype.writeUInt32LE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[r+3]=t>>>24,this[r+2]=t>>>16,this[r+1]=t>>>8,this[r]=255&t):B(this,t,r,!0),r+4},c.prototype.writeUInt32BE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,4,4294967295,0),c.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):B(this,t,r,!1),r+4},c.prototype.writeIntLE=function(t,r,e,n){if(t=+t,r|=0,!n){var i=Math.pow(2,8*e-1);C(this,t,r,e,i-1,-i)}var o=0,s=1,a=0;for(this[r]=255&t;++o>0)-a&255;return r+e},c.prototype.writeIntBE=function(t,r,e,n){if(t=+t,r|=0,!n){var i=Math.pow(2,8*e-1);C(this,t,r,e,i-1,-i)}var o=e-1,s=1,a=0;for(this[r+o]=255&t;0<=--o&&(s*=256);)t<0&&0===a&&0!==this[r+o+1]&&(a=1),this[r+o]=(t/s>>0)-a&255;return r+e},c.prototype.writeInt8=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,1,127,-128),c.TYPED_ARRAY_SUPPORT||(t=Math.floor(t)),t<0&&(t=255+t+1),this[r]=255&t,r+1},c.prototype.writeInt16LE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8):P(this,t,r,!0),r+2},c.prototype.writeInt16BE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,2,32767,-32768),c.TYPED_ARRAY_SUPPORT?(this[r]=t>>>8,this[r+1]=255&t):P(this,t,r,!1),r+2},c.prototype.writeInt32LE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,4,2147483647,-2147483648),c.TYPED_ARRAY_SUPPORT?(this[r]=255&t,this[r+1]=t>>>8,this[r+2]=t>>>16,this[r+3]=t>>>24):B(this,t,r,!0),r+4},c.prototype.writeInt32BE=function(t,r,e){return t=+t,r|=0,e||C(this,t,r,4,2147483647,-2147483648),t<0&&(t=4294967295+t+1),c.TYPED_ARRAY_SUPPORT?(this[r]=t>>>24,this[r+1]=t>>>16,this[r+2]=t>>>8,this[r+3]=255&t):B(this,t,r,!1),r+4},c.prototype.writeFloatLE=function(t,r,e){return I(this,t,r,!0,e)},c.prototype.writeFloatBE=function(t,r,e){return I(this,t,r,!1,e)},c.prototype.writeDoubleLE=function(t,r,e){return U(this,t,r,!0,e)},c.prototype.writeDoubleBE=function(t,r,e){return U(this,t,r,!1,e)},c.prototype.copy=function(t,r,e,n){if(e=e||0,n||0===n||(n=this.length),r>=t.length&&(r=t.length),r=r||0,0=this.length)throw new RangeError("sourceStart out of bounds");if(n<0)throw new RangeError("sourceEnd out of bounds");n>this.length&&(n=this.length),t.length-r>>=0,e=void 0===e?this.length:e>>>0,"number"==typeof(t=t||0))for(o=r;o>6|192,63&e|128)}else if(e<65536){if((r-=3)<0)break;o.push(e>>12|224,e>>6&63|128,63&e|128)}else{if(!(e<1114112))throw new Error("Invalid code point");if((r-=4)<0)break;o.push(e>>18|240,e>>12&63|128,e>>6&63|128,63&e|128)}}return o}function D(t){return n.toByteArray(function(t){var r;if((t=((r=t).trim?r.trim():r.replace(/^\s+|\s+$/g,"")).replace(x,"")).length<2)return"";for(;t.length%4!=0;)t+="=";return t}(t))}function Y(t,r,e,n){for(var i=0;i=r.length||i>=t.length);++i)r[i+e]=t[i];return i}}).call(this,r(5))},function(t,r){var e;e=function(){return this}();try{e=e||new Function("return this")()}catch(t){"object"==typeof window&&(e=window)}t.exports=e},function(t,r,e){"use strict";r.byteLength=function(t){var r=c(t),e=r[0],n=r[1];return 3*(e+n)/4-n},r.toByteArray=function(t){var r,e,n=c(t),i=n[0],o=n[1],s=new u(function(t,r){return 3*(t+r)/4-r}(i,o)),a=0,f=0>16&255,s[a++]=r>>8&255,s[a++]=255&r;2===o&&(r=h[t.charCodeAt(e)]<<2|h[t.charCodeAt(e+1)]>>4,s[a++]=255&r);1===o&&(r=h[t.charCodeAt(e)]<<10|h[t.charCodeAt(e+1)]<<4|h[t.charCodeAt(e+2)]>>2,s[a++]=r>>8&255,s[a++]=255&r);return s},r.fromByteArray=function(t){for(var r,e=t.length,n=e%3,i=[],o=0,s=e-n;o>2]+a[r<<4&63]+"==")):2==n&&(r=(t[e-2]<<8)+t[e-1],i.push(a[r>>10]+a[r>>4&63]+a[r<<2&63]+"="));return i.join("")};for(var a=[],h=[],u="undefined"!=typeof Uint8Array?Uint8Array:Array,n="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/",i=0,o=n.length;i>18&63]+a[i>>12&63]+a[i>>6&63]+a[63&i]);return o.join("")}h["-".charCodeAt(0)]=62,h["_".charCodeAt(0)]=63},function(t,r){r.read=function(t,r,e,n,i){var o,s,a=8*i-n-1,f=(1<>1,u=-7,c=e?i-1:0,l=e?-1:1,p=t[r+c];for(c+=l,o=p&(1<<-u)-1,p>>=-u,u+=a;0>=-u,u+=n;0>1,l=23===i?Math.pow(2,-24)-Math.pow(2,-77):0,p=n?0:o-1,d=n?1:-1,g=r<0||0===r&&1/r<0?1:0;for(r=Math.abs(r),isNaN(r)||r===1/0?(a=isNaN(r)?1:0,s=u):(s=Math.floor(Math.log(r)/Math.LN2),r*(f=Math.pow(2,-s))<1&&(s--,f*=2),2<=(r+=1<=s+c?l/f:l*Math.pow(2,1-c))*f&&(s++,f/=2),u<=s+c?(a=0,s=u):1<=s+c?(a=(r*f-1)*Math.pow(2,i),s+=c):(a=r*Math.pow(2,c-1)*Math.pow(2,i),s=0));8<=i;t[e+p]=255&a,p+=d,a/=256,i-=8);for(s=s<>8&255).toString(16).padStart(2,"0")+(t>>16&255).toString(16).padStart(2,"0")},s.set_ctx_state=function(t,r){if(r){var e="";if(r.Font){r.Font.Italic&&(e+=" italic"),r.Font.Weight&&(e+=" "+(700==r.Font.Weight?"bold":400==r.Font.Weight?"":r.Font.Weight)),r.Font.Height<0?e+=" "+-r.Font.Height+"px":0 0) {\n throw new Error('Invalid string. Length must be a multiple of 4')\n }\n\n // Trim off extra bytes after placeholder bytes are found\n // See: https://github.com/beatgammit/base64-js/issues/42\n var validLen = b64.indexOf('=')\n if (validLen === -1) validLen = len\n\n var placeHoldersLen = validLen === len\n ? 0\n : 4 - (validLen % 4)\n\n return [validLen, placeHoldersLen]\n}\n\n// base64 is 4/3 + up to two characters of the original data\nfunction byteLength (b64) {\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction _byteLength (b64, validLen, placeHoldersLen) {\n return ((validLen + placeHoldersLen) * 3 / 4) - placeHoldersLen\n}\n\nfunction toByteArray (b64) {\n var tmp\n var lens = getLens(b64)\n var validLen = lens[0]\n var placeHoldersLen = lens[1]\n\n var arr = new Arr(_byteLength(b64, validLen, placeHoldersLen))\n\n var curByte = 0\n\n // if there are placeholders, only get up to the last complete 4 chars\n var len = placeHoldersLen > 0\n ? validLen - 4\n : validLen\n\n var i\n for (i = 0; i < len; i += 4) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 18) |\n (revLookup[b64.charCodeAt(i + 1)] << 12) |\n (revLookup[b64.charCodeAt(i + 2)] << 6) |\n revLookup[b64.charCodeAt(i + 3)]\n arr[curByte++] = (tmp >> 16) & 0xFF\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 2) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 2) |\n (revLookup[b64.charCodeAt(i + 1)] >> 4)\n arr[curByte++] = tmp & 0xFF\n }\n\n if (placeHoldersLen === 1) {\n tmp =\n (revLookup[b64.charCodeAt(i)] << 10) |\n (revLookup[b64.charCodeAt(i + 1)] << 4) |\n (revLookup[b64.charCodeAt(i + 2)] >> 2)\n arr[curByte++] = (tmp >> 8) & 0xFF\n arr[curByte++] = tmp & 0xFF\n }\n\n return arr\n}\n\nfunction tripletToBase64 (num) {\n return lookup[num >> 18 & 0x3F] +\n lookup[num >> 12 & 0x3F] +\n lookup[num >> 6 & 0x3F] +\n lookup[num & 0x3F]\n}\n\nfunction encodeChunk (uint8, start, end) {\n var tmp\n var output = []\n for (var i = start; i < end; i += 3) {\n tmp =\n ((uint8[i] << 16) & 0xFF0000) +\n ((uint8[i + 1] << 8) & 0xFF00) +\n (uint8[i + 2] & 0xFF)\n output.push(tripletToBase64(tmp))\n }\n return output.join('')\n}\n\nfunction fromByteArray (uint8) {\n var tmp\n var len = uint8.length\n var extraBytes = len % 3 // if we have 1 byte left, pad 2 bytes\n var parts = []\n var maxChunkLength = 16383 // must be multiple of 3\n\n // go through the array every three bytes, we'll deal with trailing stuff later\n for (var i = 0, len2 = len - extraBytes; i < len2; i += maxChunkLength) {\n parts.push(encodeChunk(\n uint8, i, (i + maxChunkLength) > len2 ? len2 : (i + maxChunkLength)\n ))\n }\n\n // pad the end with zeros, but make sure to not forget the extra bytes\n if (extraBytes === 1) {\n tmp = uint8[len - 1]\n parts.push(\n lookup[tmp >> 2] +\n lookup[(tmp << 4) & 0x3F] +\n '=='\n )\n } else if (extraBytes === 2) {\n tmp = (uint8[len - 2] << 8) + uint8[len - 1]\n parts.push(\n lookup[tmp >> 10] +\n lookup[(tmp >> 4) & 0x3F] +\n lookup[(tmp << 2) & 0x3F] +\n '='\n )\n }\n\n return parts.join('')\n}\n","/*!\n * The buffer module from node.js, for the browser.\n *\n * @author Feross Aboukhadijeh \n * @license MIT\n */\n/* eslint-disable no-proto */\n\n'use strict'\n\nvar base64 = require('base64-js')\nvar ieee754 = require('ieee754')\nvar isArray = require('isarray')\n\nexports.Buffer = Buffer\nexports.SlowBuffer = SlowBuffer\nexports.INSPECT_MAX_BYTES = 50\n\n/**\n * If `Buffer.TYPED_ARRAY_SUPPORT`:\n * === true Use Uint8Array implementation (fastest)\n * === false Use Object implementation (most compatible, even IE6)\n *\n * Browsers that support typed arrays are IE 10+, Firefox 4+, Chrome 7+, Safari 5.1+,\n * Opera 11.6+, iOS 4.2+.\n *\n * Due to various browser bugs, sometimes the Object implementation will be used even\n * when the browser supports typed arrays.\n *\n * Note:\n *\n * - Firefox 4-29 lacks support for adding new properties to `Uint8Array` instances,\n * See: https://bugzilla.mozilla.org/show_bug.cgi?id=695438.\n *\n * - Chrome 9-10 is missing the `TypedArray.prototype.subarray` function.\n *\n * - IE10 has a broken `TypedArray.prototype.subarray` function which returns arrays of\n * incorrect length in some situations.\n\n * We detect these buggy browsers and set `Buffer.TYPED_ARRAY_SUPPORT` to `false` so they\n * get the Object implementation, which is slower but behaves correctly.\n */\nBuffer.TYPED_ARRAY_SUPPORT = global.TYPED_ARRAY_SUPPORT !== undefined\n ? global.TYPED_ARRAY_SUPPORT\n : typedArraySupport()\n\n/*\n * Export kMaxLength after typed array support is determined.\n */\nexports.kMaxLength = kMaxLength()\n\nfunction typedArraySupport () {\n try {\n var arr = new Uint8Array(1)\n arr.__proto__ = {__proto__: Uint8Array.prototype, foo: function () { return 42 }}\n return arr.foo() === 42 && // typed array instances can be augmented\n typeof arr.subarray === 'function' && // chrome 9-10 lack `subarray`\n arr.subarray(1, 1).byteLength === 0 // ie10 has broken `subarray`\n } catch (e) {\n return false\n }\n}\n\nfunction kMaxLength () {\n return Buffer.TYPED_ARRAY_SUPPORT\n ? 0x7fffffff\n : 0x3fffffff\n}\n\nfunction createBuffer (that, length) {\n if (kMaxLength() < length) {\n throw new RangeError('Invalid typed array length')\n }\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = new Uint8Array(length)\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n if (that === null) {\n that = new Buffer(length)\n }\n that.length = length\n }\n\n return that\n}\n\n/**\n * The Buffer constructor returns instances of `Uint8Array` that have their\n * prototype changed to `Buffer.prototype`. Furthermore, `Buffer` is a subclass of\n * `Uint8Array`, so the returned instances will have all the node `Buffer` methods\n * and the `Uint8Array` methods. Square bracket notation works as expected -- it\n * returns a single octet.\n *\n * The `Uint8Array` prototype remains unmodified.\n */\n\nfunction Buffer (arg, encodingOrOffset, length) {\n if (!Buffer.TYPED_ARRAY_SUPPORT && !(this instanceof Buffer)) {\n return new Buffer(arg, encodingOrOffset, length)\n }\n\n // Common case.\n if (typeof arg === 'number') {\n if (typeof encodingOrOffset === 'string') {\n throw new Error(\n 'If encoding is specified then the first argument must be a string'\n )\n }\n return allocUnsafe(this, arg)\n }\n return from(this, arg, encodingOrOffset, length)\n}\n\nBuffer.poolSize = 8192 // not used by this implementation\n\n// TODO: Legacy, not needed anymore. Remove in next major version.\nBuffer._augment = function (arr) {\n arr.__proto__ = Buffer.prototype\n return arr\n}\n\nfunction from (that, value, encodingOrOffset, length) {\n if (typeof value === 'number') {\n throw new TypeError('\"value\" argument must not be a number')\n }\n\n if (typeof ArrayBuffer !== 'undefined' && value instanceof ArrayBuffer) {\n return fromArrayBuffer(that, value, encodingOrOffset, length)\n }\n\n if (typeof value === 'string') {\n return fromString(that, value, encodingOrOffset)\n }\n\n return fromObject(that, value)\n}\n\n/**\n * Functionally equivalent to Buffer(arg, encoding) but throws a TypeError\n * if value is a number.\n * Buffer.from(str[, encoding])\n * Buffer.from(array)\n * Buffer.from(buffer)\n * Buffer.from(arrayBuffer[, byteOffset[, length]])\n **/\nBuffer.from = function (value, encodingOrOffset, length) {\n return from(null, value, encodingOrOffset, length)\n}\n\nif (Buffer.TYPED_ARRAY_SUPPORT) {\n Buffer.prototype.__proto__ = Uint8Array.prototype\n Buffer.__proto__ = Uint8Array\n if (typeof Symbol !== 'undefined' && Symbol.species &&\n Buffer[Symbol.species] === Buffer) {\n // Fix subarray() in ES2016. See: https://github.com/feross/buffer/pull/97\n Object.defineProperty(Buffer, Symbol.species, {\n value: null,\n configurable: true\n })\n }\n}\n\nfunction assertSize (size) {\n if (typeof size !== 'number') {\n throw new TypeError('\"size\" argument must be a number')\n } else if (size < 0) {\n throw new RangeError('\"size\" argument must not be negative')\n }\n}\n\nfunction alloc (that, size, fill, encoding) {\n assertSize(size)\n if (size <= 0) {\n return createBuffer(that, size)\n }\n if (fill !== undefined) {\n // Only pay attention to encoding if it's a string. This\n // prevents accidentally sending in a number that would\n // be interpretted as a start offset.\n return typeof encoding === 'string'\n ? createBuffer(that, size).fill(fill, encoding)\n : createBuffer(that, size).fill(fill)\n }\n return createBuffer(that, size)\n}\n\n/**\n * Creates a new filled Buffer instance.\n * alloc(size[, fill[, encoding]])\n **/\nBuffer.alloc = function (size, fill, encoding) {\n return alloc(null, size, fill, encoding)\n}\n\nfunction allocUnsafe (that, size) {\n assertSize(size)\n that = createBuffer(that, size < 0 ? 0 : checked(size) | 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) {\n for (var i = 0; i < size; ++i) {\n that[i] = 0\n }\n }\n return that\n}\n\n/**\n * Equivalent to Buffer(num), by default creates a non-zero-filled Buffer instance.\n * */\nBuffer.allocUnsafe = function (size) {\n return allocUnsafe(null, size)\n}\n/**\n * Equivalent to SlowBuffer(num), by default creates a non-zero-filled Buffer instance.\n */\nBuffer.allocUnsafeSlow = function (size) {\n return allocUnsafe(null, size)\n}\n\nfunction fromString (that, string, encoding) {\n if (typeof encoding !== 'string' || encoding === '') {\n encoding = 'utf8'\n }\n\n if (!Buffer.isEncoding(encoding)) {\n throw new TypeError('\"encoding\" must be a valid string encoding')\n }\n\n var length = byteLength(string, encoding) | 0\n that = createBuffer(that, length)\n\n var actual = that.write(string, encoding)\n\n if (actual !== length) {\n // Writing a hex string, for example, that contains invalid characters will\n // cause everything after the first invalid character to be ignored. (e.g.\n // 'abxxcd' will be treated as 'ab')\n that = that.slice(0, actual)\n }\n\n return that\n}\n\nfunction fromArrayLike (that, array) {\n var length = array.length < 0 ? 0 : checked(array.length) | 0\n that = createBuffer(that, length)\n for (var i = 0; i < length; i += 1) {\n that[i] = array[i] & 255\n }\n return that\n}\n\nfunction fromArrayBuffer (that, array, byteOffset, length) {\n array.byteLength // this throws if `array` is not a valid ArrayBuffer\n\n if (byteOffset < 0 || array.byteLength < byteOffset) {\n throw new RangeError('\\'offset\\' is out of bounds')\n }\n\n if (array.byteLength < byteOffset + (length || 0)) {\n throw new RangeError('\\'length\\' is out of bounds')\n }\n\n if (byteOffset === undefined && length === undefined) {\n array = new Uint8Array(array)\n } else if (length === undefined) {\n array = new Uint8Array(array, byteOffset)\n } else {\n array = new Uint8Array(array, byteOffset, length)\n }\n\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n // Return an augmented `Uint8Array` instance, for best performance\n that = array\n that.__proto__ = Buffer.prototype\n } else {\n // Fallback: Return an object instance of the Buffer class\n that = fromArrayLike(that, array)\n }\n return that\n}\n\nfunction fromObject (that, obj) {\n if (Buffer.isBuffer(obj)) {\n var len = checked(obj.length) | 0\n that = createBuffer(that, len)\n\n if (that.length === 0) {\n return that\n }\n\n obj.copy(that, 0, 0, len)\n return that\n }\n\n if (obj) {\n if ((typeof ArrayBuffer !== 'undefined' &&\n obj.buffer instanceof ArrayBuffer) || 'length' in obj) {\n if (typeof obj.length !== 'number' || isnan(obj.length)) {\n return createBuffer(that, 0)\n }\n return fromArrayLike(that, obj)\n }\n\n if (obj.type === 'Buffer' && isArray(obj.data)) {\n return fromArrayLike(that, obj.data)\n }\n }\n\n throw new TypeError('First argument must be a string, Buffer, ArrayBuffer, Array, or array-like object.')\n}\n\nfunction checked (length) {\n // Note: cannot use `length < kMaxLength()` here because that fails when\n // length is NaN (which is otherwise coerced to zero.)\n if (length >= kMaxLength()) {\n throw new RangeError('Attempt to allocate Buffer larger than maximum ' +\n 'size: 0x' + kMaxLength().toString(16) + ' bytes')\n }\n return length | 0\n}\n\nfunction SlowBuffer (length) {\n if (+length != length) { // eslint-disable-line eqeqeq\n length = 0\n }\n return Buffer.alloc(+length)\n}\n\nBuffer.isBuffer = function isBuffer (b) {\n return !!(b != null && b._isBuffer)\n}\n\nBuffer.compare = function compare (a, b) {\n if (!Buffer.isBuffer(a) || !Buffer.isBuffer(b)) {\n throw new TypeError('Arguments must be Buffers')\n }\n\n if (a === b) return 0\n\n var x = a.length\n var y = b.length\n\n for (var i = 0, len = Math.min(x, y); i < len; ++i) {\n if (a[i] !== b[i]) {\n x = a[i]\n y = b[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\nBuffer.isEncoding = function isEncoding (encoding) {\n switch (String(encoding).toLowerCase()) {\n case 'hex':\n case 'utf8':\n case 'utf-8':\n case 'ascii':\n case 'latin1':\n case 'binary':\n case 'base64':\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return true\n default:\n return false\n }\n}\n\nBuffer.concat = function concat (list, length) {\n if (!isArray(list)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n\n if (list.length === 0) {\n return Buffer.alloc(0)\n }\n\n var i\n if (length === undefined) {\n length = 0\n for (i = 0; i < list.length; ++i) {\n length += list[i].length\n }\n }\n\n var buffer = Buffer.allocUnsafe(length)\n var pos = 0\n for (i = 0; i < list.length; ++i) {\n var buf = list[i]\n if (!Buffer.isBuffer(buf)) {\n throw new TypeError('\"list\" argument must be an Array of Buffers')\n }\n buf.copy(buffer, pos)\n pos += buf.length\n }\n return buffer\n}\n\nfunction byteLength (string, encoding) {\n if (Buffer.isBuffer(string)) {\n return string.length\n }\n if (typeof ArrayBuffer !== 'undefined' && typeof ArrayBuffer.isView === 'function' &&\n (ArrayBuffer.isView(string) || string instanceof ArrayBuffer)) {\n return string.byteLength\n }\n if (typeof string !== 'string') {\n string = '' + string\n }\n\n var len = string.length\n if (len === 0) return 0\n\n // Use a for loop to avoid recursion\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'ascii':\n case 'latin1':\n case 'binary':\n return len\n case 'utf8':\n case 'utf-8':\n case undefined:\n return utf8ToBytes(string).length\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return len * 2\n case 'hex':\n return len >>> 1\n case 'base64':\n return base64ToBytes(string).length\n default:\n if (loweredCase) return utf8ToBytes(string).length // assume utf8\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\nBuffer.byteLength = byteLength\n\nfunction slowToString (encoding, start, end) {\n var loweredCase = false\n\n // No need to verify that \"this.length <= MAX_UINT32\" since it's a read-only\n // property of a typed array.\n\n // This behaves neither like String nor Uint8Array in that we set start/end\n // to their upper/lower bounds if the value passed is out of range.\n // undefined is handled specially as per ECMA-262 6th Edition,\n // Section 13.3.3.7 Runtime Semantics: KeyedBindingInitialization.\n if (start === undefined || start < 0) {\n start = 0\n }\n // Return early if start > this.length. Done here to prevent potential uint32\n // coercion fail below.\n if (start > this.length) {\n return ''\n }\n\n if (end === undefined || end > this.length) {\n end = this.length\n }\n\n if (end <= 0) {\n return ''\n }\n\n // Force coersion to uint32. This will also coerce falsey/NaN values to 0.\n end >>>= 0\n start >>>= 0\n\n if (end <= start) {\n return ''\n }\n\n if (!encoding) encoding = 'utf8'\n\n while (true) {\n switch (encoding) {\n case 'hex':\n return hexSlice(this, start, end)\n\n case 'utf8':\n case 'utf-8':\n return utf8Slice(this, start, end)\n\n case 'ascii':\n return asciiSlice(this, start, end)\n\n case 'latin1':\n case 'binary':\n return latin1Slice(this, start, end)\n\n case 'base64':\n return base64Slice(this, start, end)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return utf16leSlice(this, start, end)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = (encoding + '').toLowerCase()\n loweredCase = true\n }\n }\n}\n\n// The property is used by `Buffer.isBuffer` and `is-buffer` (in Safari 5-7) to detect\n// Buffer instances.\nBuffer.prototype._isBuffer = true\n\nfunction swap (b, n, m) {\n var i = b[n]\n b[n] = b[m]\n b[m] = i\n}\n\nBuffer.prototype.swap16 = function swap16 () {\n var len = this.length\n if (len % 2 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 16-bits')\n }\n for (var i = 0; i < len; i += 2) {\n swap(this, i, i + 1)\n }\n return this\n}\n\nBuffer.prototype.swap32 = function swap32 () {\n var len = this.length\n if (len % 4 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 32-bits')\n }\n for (var i = 0; i < len; i += 4) {\n swap(this, i, i + 3)\n swap(this, i + 1, i + 2)\n }\n return this\n}\n\nBuffer.prototype.swap64 = function swap64 () {\n var len = this.length\n if (len % 8 !== 0) {\n throw new RangeError('Buffer size must be a multiple of 64-bits')\n }\n for (var i = 0; i < len; i += 8) {\n swap(this, i, i + 7)\n swap(this, i + 1, i + 6)\n swap(this, i + 2, i + 5)\n swap(this, i + 3, i + 4)\n }\n return this\n}\n\nBuffer.prototype.toString = function toString () {\n var length = this.length | 0\n if (length === 0) return ''\n if (arguments.length === 0) return utf8Slice(this, 0, length)\n return slowToString.apply(this, arguments)\n}\n\nBuffer.prototype.equals = function equals (b) {\n if (!Buffer.isBuffer(b)) throw new TypeError('Argument must be a Buffer')\n if (this === b) return true\n return Buffer.compare(this, b) === 0\n}\n\nBuffer.prototype.inspect = function inspect () {\n var str = ''\n var max = exports.INSPECT_MAX_BYTES\n if (this.length > 0) {\n str = this.toString('hex', 0, max).match(/.{2}/g).join(' ')\n if (this.length > max) str += ' ... '\n }\n return ''\n}\n\nBuffer.prototype.compare = function compare (target, start, end, thisStart, thisEnd) {\n if (!Buffer.isBuffer(target)) {\n throw new TypeError('Argument must be a Buffer')\n }\n\n if (start === undefined) {\n start = 0\n }\n if (end === undefined) {\n end = target ? target.length : 0\n }\n if (thisStart === undefined) {\n thisStart = 0\n }\n if (thisEnd === undefined) {\n thisEnd = this.length\n }\n\n if (start < 0 || end > target.length || thisStart < 0 || thisEnd > this.length) {\n throw new RangeError('out of range index')\n }\n\n if (thisStart >= thisEnd && start >= end) {\n return 0\n }\n if (thisStart >= thisEnd) {\n return -1\n }\n if (start >= end) {\n return 1\n }\n\n start >>>= 0\n end >>>= 0\n thisStart >>>= 0\n thisEnd >>>= 0\n\n if (this === target) return 0\n\n var x = thisEnd - thisStart\n var y = end - start\n var len = Math.min(x, y)\n\n var thisCopy = this.slice(thisStart, thisEnd)\n var targetCopy = target.slice(start, end)\n\n for (var i = 0; i < len; ++i) {\n if (thisCopy[i] !== targetCopy[i]) {\n x = thisCopy[i]\n y = targetCopy[i]\n break\n }\n }\n\n if (x < y) return -1\n if (y < x) return 1\n return 0\n}\n\n// Finds either the first index of `val` in `buffer` at offset >= `byteOffset`,\n// OR the last index of `val` in `buffer` at offset <= `byteOffset`.\n//\n// Arguments:\n// - buffer - a Buffer to search\n// - val - a string, Buffer, or number\n// - byteOffset - an index into `buffer`; will be clamped to an int32\n// - encoding - an optional encoding, relevant is val is a string\n// - dir - true for indexOf, false for lastIndexOf\nfunction bidirectionalIndexOf (buffer, val, byteOffset, encoding, dir) {\n // Empty buffer means no match\n if (buffer.length === 0) return -1\n\n // Normalize byteOffset\n if (typeof byteOffset === 'string') {\n encoding = byteOffset\n byteOffset = 0\n } else if (byteOffset > 0x7fffffff) {\n byteOffset = 0x7fffffff\n } else if (byteOffset < -0x80000000) {\n byteOffset = -0x80000000\n }\n byteOffset = +byteOffset // Coerce to Number.\n if (isNaN(byteOffset)) {\n // byteOffset: it it's undefined, null, NaN, \"foo\", etc, search whole buffer\n byteOffset = dir ? 0 : (buffer.length - 1)\n }\n\n // Normalize byteOffset: negative offsets start from the end of the buffer\n if (byteOffset < 0) byteOffset = buffer.length + byteOffset\n if (byteOffset >= buffer.length) {\n if (dir) return -1\n else byteOffset = buffer.length - 1\n } else if (byteOffset < 0) {\n if (dir) byteOffset = 0\n else return -1\n }\n\n // Normalize val\n if (typeof val === 'string') {\n val = Buffer.from(val, encoding)\n }\n\n // Finally, search either indexOf (if dir is true) or lastIndexOf\n if (Buffer.isBuffer(val)) {\n // Special case: looking for empty string/buffer always fails\n if (val.length === 0) {\n return -1\n }\n return arrayIndexOf(buffer, val, byteOffset, encoding, dir)\n } else if (typeof val === 'number') {\n val = val & 0xFF // Search for a byte value [0-255]\n if (Buffer.TYPED_ARRAY_SUPPORT &&\n typeof Uint8Array.prototype.indexOf === 'function') {\n if (dir) {\n return Uint8Array.prototype.indexOf.call(buffer, val, byteOffset)\n } else {\n return Uint8Array.prototype.lastIndexOf.call(buffer, val, byteOffset)\n }\n }\n return arrayIndexOf(buffer, [ val ], byteOffset, encoding, dir)\n }\n\n throw new TypeError('val must be string, number or Buffer')\n}\n\nfunction arrayIndexOf (arr, val, byteOffset, encoding, dir) {\n var indexSize = 1\n var arrLength = arr.length\n var valLength = val.length\n\n if (encoding !== undefined) {\n encoding = String(encoding).toLowerCase()\n if (encoding === 'ucs2' || encoding === 'ucs-2' ||\n encoding === 'utf16le' || encoding === 'utf-16le') {\n if (arr.length < 2 || val.length < 2) {\n return -1\n }\n indexSize = 2\n arrLength /= 2\n valLength /= 2\n byteOffset /= 2\n }\n }\n\n function read (buf, i) {\n if (indexSize === 1) {\n return buf[i]\n } else {\n return buf.readUInt16BE(i * indexSize)\n }\n }\n\n var i\n if (dir) {\n var foundIndex = -1\n for (i = byteOffset; i < arrLength; i++) {\n if (read(arr, i) === read(val, foundIndex === -1 ? 0 : i - foundIndex)) {\n if (foundIndex === -1) foundIndex = i\n if (i - foundIndex + 1 === valLength) return foundIndex * indexSize\n } else {\n if (foundIndex !== -1) i -= i - foundIndex\n foundIndex = -1\n }\n }\n } else {\n if (byteOffset + valLength > arrLength) byteOffset = arrLength - valLength\n for (i = byteOffset; i >= 0; i--) {\n var found = true\n for (var j = 0; j < valLength; j++) {\n if (read(arr, i + j) !== read(val, j)) {\n found = false\n break\n }\n }\n if (found) return i\n }\n }\n\n return -1\n}\n\nBuffer.prototype.includes = function includes (val, byteOffset, encoding) {\n return this.indexOf(val, byteOffset, encoding) !== -1\n}\n\nBuffer.prototype.indexOf = function indexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, true)\n}\n\nBuffer.prototype.lastIndexOf = function lastIndexOf (val, byteOffset, encoding) {\n return bidirectionalIndexOf(this, val, byteOffset, encoding, false)\n}\n\nfunction hexWrite (buf, string, offset, length) {\n offset = Number(offset) || 0\n var remaining = buf.length - offset\n if (!length) {\n length = remaining\n } else {\n length = Number(length)\n if (length > remaining) {\n length = remaining\n }\n }\n\n // must be an even number of digits\n var strLen = string.length\n if (strLen % 2 !== 0) throw new TypeError('Invalid hex string')\n\n if (length > strLen / 2) {\n length = strLen / 2\n }\n for (var i = 0; i < length; ++i) {\n var parsed = parseInt(string.substr(i * 2, 2), 16)\n if (isNaN(parsed)) return i\n buf[offset + i] = parsed\n }\n return i\n}\n\nfunction utf8Write (buf, string, offset, length) {\n return blitBuffer(utf8ToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nfunction asciiWrite (buf, string, offset, length) {\n return blitBuffer(asciiToBytes(string), buf, offset, length)\n}\n\nfunction latin1Write (buf, string, offset, length) {\n return asciiWrite(buf, string, offset, length)\n}\n\nfunction base64Write (buf, string, offset, length) {\n return blitBuffer(base64ToBytes(string), buf, offset, length)\n}\n\nfunction ucs2Write (buf, string, offset, length) {\n return blitBuffer(utf16leToBytes(string, buf.length - offset), buf, offset, length)\n}\n\nBuffer.prototype.write = function write (string, offset, length, encoding) {\n // Buffer#write(string)\n if (offset === undefined) {\n encoding = 'utf8'\n length = this.length\n offset = 0\n // Buffer#write(string, encoding)\n } else if (length === undefined && typeof offset === 'string') {\n encoding = offset\n length = this.length\n offset = 0\n // Buffer#write(string, offset[, length][, encoding])\n } else if (isFinite(offset)) {\n offset = offset | 0\n if (isFinite(length)) {\n length = length | 0\n if (encoding === undefined) encoding = 'utf8'\n } else {\n encoding = length\n length = undefined\n }\n // legacy write(string, encoding, offset, length) - remove in v0.13\n } else {\n throw new Error(\n 'Buffer.write(string, encoding, offset[, length]) is no longer supported'\n )\n }\n\n var remaining = this.length - offset\n if (length === undefined || length > remaining) length = remaining\n\n if ((string.length > 0 && (length < 0 || offset < 0)) || offset > this.length) {\n throw new RangeError('Attempt to write outside buffer bounds')\n }\n\n if (!encoding) encoding = 'utf8'\n\n var loweredCase = false\n for (;;) {\n switch (encoding) {\n case 'hex':\n return hexWrite(this, string, offset, length)\n\n case 'utf8':\n case 'utf-8':\n return utf8Write(this, string, offset, length)\n\n case 'ascii':\n return asciiWrite(this, string, offset, length)\n\n case 'latin1':\n case 'binary':\n return latin1Write(this, string, offset, length)\n\n case 'base64':\n // Warning: maxLength not taken into account in base64Write\n return base64Write(this, string, offset, length)\n\n case 'ucs2':\n case 'ucs-2':\n case 'utf16le':\n case 'utf-16le':\n return ucs2Write(this, string, offset, length)\n\n default:\n if (loweredCase) throw new TypeError('Unknown encoding: ' + encoding)\n encoding = ('' + encoding).toLowerCase()\n loweredCase = true\n }\n }\n}\n\nBuffer.prototype.toJSON = function toJSON () {\n return {\n type: 'Buffer',\n data: Array.prototype.slice.call(this._arr || this, 0)\n }\n}\n\nfunction base64Slice (buf, start, end) {\n if (start === 0 && end === buf.length) {\n return base64.fromByteArray(buf)\n } else {\n return base64.fromByteArray(buf.slice(start, end))\n }\n}\n\nfunction utf8Slice (buf, start, end) {\n end = Math.min(buf.length, end)\n var res = []\n\n var i = start\n while (i < end) {\n var firstByte = buf[i]\n var codePoint = null\n var bytesPerSequence = (firstByte > 0xEF) ? 4\n : (firstByte > 0xDF) ? 3\n : (firstByte > 0xBF) ? 2\n : 1\n\n if (i + bytesPerSequence <= end) {\n var secondByte, thirdByte, fourthByte, tempCodePoint\n\n switch (bytesPerSequence) {\n case 1:\n if (firstByte < 0x80) {\n codePoint = firstByte\n }\n break\n case 2:\n secondByte = buf[i + 1]\n if ((secondByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0x1F) << 0x6 | (secondByte & 0x3F)\n if (tempCodePoint > 0x7F) {\n codePoint = tempCodePoint\n }\n }\n break\n case 3:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0xC | (secondByte & 0x3F) << 0x6 | (thirdByte & 0x3F)\n if (tempCodePoint > 0x7FF && (tempCodePoint < 0xD800 || tempCodePoint > 0xDFFF)) {\n codePoint = tempCodePoint\n }\n }\n break\n case 4:\n secondByte = buf[i + 1]\n thirdByte = buf[i + 2]\n fourthByte = buf[i + 3]\n if ((secondByte & 0xC0) === 0x80 && (thirdByte & 0xC0) === 0x80 && (fourthByte & 0xC0) === 0x80) {\n tempCodePoint = (firstByte & 0xF) << 0x12 | (secondByte & 0x3F) << 0xC | (thirdByte & 0x3F) << 0x6 | (fourthByte & 0x3F)\n if (tempCodePoint > 0xFFFF && tempCodePoint < 0x110000) {\n codePoint = tempCodePoint\n }\n }\n }\n }\n\n if (codePoint === null) {\n // we did not generate a valid codePoint so insert a\n // replacement char (U+FFFD) and advance only 1 byte\n codePoint = 0xFFFD\n bytesPerSequence = 1\n } else if (codePoint > 0xFFFF) {\n // encode to utf16 (surrogate pair dance)\n codePoint -= 0x10000\n res.push(codePoint >>> 10 & 0x3FF | 0xD800)\n codePoint = 0xDC00 | codePoint & 0x3FF\n }\n\n res.push(codePoint)\n i += bytesPerSequence\n }\n\n return decodeCodePointsArray(res)\n}\n\n// Based on http://stackoverflow.com/a/22747272/680742, the browser with\n// the lowest limit is Chrome, with 0x10000 args.\n// We go 1 magnitude less, for safety\nvar MAX_ARGUMENTS_LENGTH = 0x1000\n\nfunction decodeCodePointsArray (codePoints) {\n var len = codePoints.length\n if (len <= MAX_ARGUMENTS_LENGTH) {\n return String.fromCharCode.apply(String, codePoints) // avoid extra slice()\n }\n\n // Decode in chunks to avoid \"call stack size exceeded\".\n var res = ''\n var i = 0\n while (i < len) {\n res += String.fromCharCode.apply(\n String,\n codePoints.slice(i, i += MAX_ARGUMENTS_LENGTH)\n )\n }\n return res\n}\n\nfunction asciiSlice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i] & 0x7F)\n }\n return ret\n}\n\nfunction latin1Slice (buf, start, end) {\n var ret = ''\n end = Math.min(buf.length, end)\n\n for (var i = start; i < end; ++i) {\n ret += String.fromCharCode(buf[i])\n }\n return ret\n}\n\nfunction hexSlice (buf, start, end) {\n var len = buf.length\n\n if (!start || start < 0) start = 0\n if (!end || end < 0 || end > len) end = len\n\n var out = ''\n for (var i = start; i < end; ++i) {\n out += toHex(buf[i])\n }\n return out\n}\n\nfunction utf16leSlice (buf, start, end) {\n var bytes = buf.slice(start, end)\n var res = ''\n for (var i = 0; i < bytes.length; i += 2) {\n res += String.fromCharCode(bytes[i] + bytes[i + 1] * 256)\n }\n return res\n}\n\nBuffer.prototype.slice = function slice (start, end) {\n var len = this.length\n start = ~~start\n end = end === undefined ? len : ~~end\n\n if (start < 0) {\n start += len\n if (start < 0) start = 0\n } else if (start > len) {\n start = len\n }\n\n if (end < 0) {\n end += len\n if (end < 0) end = 0\n } else if (end > len) {\n end = len\n }\n\n if (end < start) end = start\n\n var newBuf\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n newBuf = this.subarray(start, end)\n newBuf.__proto__ = Buffer.prototype\n } else {\n var sliceLen = end - start\n newBuf = new Buffer(sliceLen, undefined)\n for (var i = 0; i < sliceLen; ++i) {\n newBuf[i] = this[i + start]\n }\n }\n\n return newBuf\n}\n\n/*\n * Need to make sure that buffer isn't trying to write out of bounds.\n */\nfunction checkOffset (offset, ext, length) {\n if ((offset % 1) !== 0 || offset < 0) throw new RangeError('offset is not uint')\n if (offset + ext > length) throw new RangeError('Trying to access beyond buffer length')\n}\n\nBuffer.prototype.readUIntLE = function readUIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUIntBE = function readUIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n checkOffset(offset, byteLength, this.length)\n }\n\n var val = this[offset + --byteLength]\n var mul = 1\n while (byteLength > 0 && (mul *= 0x100)) {\n val += this[offset + --byteLength] * mul\n }\n\n return val\n}\n\nBuffer.prototype.readUInt8 = function readUInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n return this[offset]\n}\n\nBuffer.prototype.readUInt16LE = function readUInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return this[offset] | (this[offset + 1] << 8)\n}\n\nBuffer.prototype.readUInt16BE = function readUInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n return (this[offset] << 8) | this[offset + 1]\n}\n\nBuffer.prototype.readUInt32LE = function readUInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return ((this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16)) +\n (this[offset + 3] * 0x1000000)\n}\n\nBuffer.prototype.readUInt32BE = function readUInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] * 0x1000000) +\n ((this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n this[offset + 3])\n}\n\nBuffer.prototype.readIntLE = function readIntLE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var val = this[offset]\n var mul = 1\n var i = 0\n while (++i < byteLength && (mul *= 0x100)) {\n val += this[offset + i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readIntBE = function readIntBE (offset, byteLength, noAssert) {\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) checkOffset(offset, byteLength, this.length)\n\n var i = byteLength\n var mul = 1\n var val = this[offset + --i]\n while (i > 0 && (mul *= 0x100)) {\n val += this[offset + --i] * mul\n }\n mul *= 0x80\n\n if (val >= mul) val -= Math.pow(2, 8 * byteLength)\n\n return val\n}\n\nBuffer.prototype.readInt8 = function readInt8 (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 1, this.length)\n if (!(this[offset] & 0x80)) return (this[offset])\n return ((0xff - this[offset] + 1) * -1)\n}\n\nBuffer.prototype.readInt16LE = function readInt16LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset] | (this[offset + 1] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt16BE = function readInt16BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 2, this.length)\n var val = this[offset + 1] | (this[offset] << 8)\n return (val & 0x8000) ? val | 0xFFFF0000 : val\n}\n\nBuffer.prototype.readInt32LE = function readInt32LE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset]) |\n (this[offset + 1] << 8) |\n (this[offset + 2] << 16) |\n (this[offset + 3] << 24)\n}\n\nBuffer.prototype.readInt32BE = function readInt32BE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n\n return (this[offset] << 24) |\n (this[offset + 1] << 16) |\n (this[offset + 2] << 8) |\n (this[offset + 3])\n}\n\nBuffer.prototype.readFloatLE = function readFloatLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, true, 23, 4)\n}\n\nBuffer.prototype.readFloatBE = function readFloatBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 4, this.length)\n return ieee754.read(this, offset, false, 23, 4)\n}\n\nBuffer.prototype.readDoubleLE = function readDoubleLE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, true, 52, 8)\n}\n\nBuffer.prototype.readDoubleBE = function readDoubleBE (offset, noAssert) {\n if (!noAssert) checkOffset(offset, 8, this.length)\n return ieee754.read(this, offset, false, 52, 8)\n}\n\nfunction checkInt (buf, value, offset, ext, max, min) {\n if (!Buffer.isBuffer(buf)) throw new TypeError('\"buffer\" argument must be a Buffer instance')\n if (value > max || value < min) throw new RangeError('\"value\" argument is out of bounds')\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n}\n\nBuffer.prototype.writeUIntLE = function writeUIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var mul = 1\n var i = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUIntBE = function writeUIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n byteLength = byteLength | 0\n if (!noAssert) {\n var maxBytes = Math.pow(2, 8 * byteLength) - 1\n checkInt(this, value, offset, byteLength, maxBytes, 0)\n }\n\n var i = byteLength - 1\n var mul = 1\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n this[offset + i] = (value / mul) & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeUInt8 = function writeUInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0xff, 0)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nfunction objectWriteUInt16 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 2); i < j; ++i) {\n buf[offset + i] = (value & (0xff << (8 * (littleEndian ? i : 1 - i)))) >>>\n (littleEndian ? i : 1 - i) * 8\n }\n}\n\nBuffer.prototype.writeUInt16LE = function writeUInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeUInt16BE = function writeUInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0xffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nfunction objectWriteUInt32 (buf, value, offset, littleEndian) {\n if (value < 0) value = 0xffffffff + value + 1\n for (var i = 0, j = Math.min(buf.length - offset, 4); i < j; ++i) {\n buf[offset + i] = (value >>> (littleEndian ? i : 3 - i) * 8) & 0xff\n }\n}\n\nBuffer.prototype.writeUInt32LE = function writeUInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset + 3] = (value >>> 24)\n this[offset + 2] = (value >>> 16)\n this[offset + 1] = (value >>> 8)\n this[offset] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeUInt32BE = function writeUInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0xffffffff, 0)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeIntLE = function writeIntLE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = 0\n var mul = 1\n var sub = 0\n this[offset] = value & 0xFF\n while (++i < byteLength && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i - 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeIntBE = function writeIntBE (value, offset, byteLength, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) {\n var limit = Math.pow(2, 8 * byteLength - 1)\n\n checkInt(this, value, offset, byteLength, limit - 1, -limit)\n }\n\n var i = byteLength - 1\n var mul = 1\n var sub = 0\n this[offset + i] = value & 0xFF\n while (--i >= 0 && (mul *= 0x100)) {\n if (value < 0 && sub === 0 && this[offset + i + 1] !== 0) {\n sub = 1\n }\n this[offset + i] = ((value / mul) >> 0) - sub & 0xFF\n }\n\n return offset + byteLength\n}\n\nBuffer.prototype.writeInt8 = function writeInt8 (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 1, 0x7f, -0x80)\n if (!Buffer.TYPED_ARRAY_SUPPORT) value = Math.floor(value)\n if (value < 0) value = 0xff + value + 1\n this[offset] = (value & 0xff)\n return offset + 1\n}\n\nBuffer.prototype.writeInt16LE = function writeInt16LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n } else {\n objectWriteUInt16(this, value, offset, true)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt16BE = function writeInt16BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 2, 0x7fff, -0x8000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 8)\n this[offset + 1] = (value & 0xff)\n } else {\n objectWriteUInt16(this, value, offset, false)\n }\n return offset + 2\n}\n\nBuffer.prototype.writeInt32LE = function writeInt32LE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value & 0xff)\n this[offset + 1] = (value >>> 8)\n this[offset + 2] = (value >>> 16)\n this[offset + 3] = (value >>> 24)\n } else {\n objectWriteUInt32(this, value, offset, true)\n }\n return offset + 4\n}\n\nBuffer.prototype.writeInt32BE = function writeInt32BE (value, offset, noAssert) {\n value = +value\n offset = offset | 0\n if (!noAssert) checkInt(this, value, offset, 4, 0x7fffffff, -0x80000000)\n if (value < 0) value = 0xffffffff + value + 1\n if (Buffer.TYPED_ARRAY_SUPPORT) {\n this[offset] = (value >>> 24)\n this[offset + 1] = (value >>> 16)\n this[offset + 2] = (value >>> 8)\n this[offset + 3] = (value & 0xff)\n } else {\n objectWriteUInt32(this, value, offset, false)\n }\n return offset + 4\n}\n\nfunction checkIEEE754 (buf, value, offset, ext, max, min) {\n if (offset + ext > buf.length) throw new RangeError('Index out of range')\n if (offset < 0) throw new RangeError('Index out of range')\n}\n\nfunction writeFloat (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 4, 3.4028234663852886e+38, -3.4028234663852886e+38)\n }\n ieee754.write(buf, value, offset, littleEndian, 23, 4)\n return offset + 4\n}\n\nBuffer.prototype.writeFloatLE = function writeFloatLE (value, offset, noAssert) {\n return writeFloat(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeFloatBE = function writeFloatBE (value, offset, noAssert) {\n return writeFloat(this, value, offset, false, noAssert)\n}\n\nfunction writeDouble (buf, value, offset, littleEndian, noAssert) {\n if (!noAssert) {\n checkIEEE754(buf, value, offset, 8, 1.7976931348623157E+308, -1.7976931348623157E+308)\n }\n ieee754.write(buf, value, offset, littleEndian, 52, 8)\n return offset + 8\n}\n\nBuffer.prototype.writeDoubleLE = function writeDoubleLE (value, offset, noAssert) {\n return writeDouble(this, value, offset, true, noAssert)\n}\n\nBuffer.prototype.writeDoubleBE = function writeDoubleBE (value, offset, noAssert) {\n return writeDouble(this, value, offset, false, noAssert)\n}\n\n// copy(targetBuffer, targetStart=0, sourceStart=0, sourceEnd=buffer.length)\nBuffer.prototype.copy = function copy (target, targetStart, start, end) {\n if (!start) start = 0\n if (!end && end !== 0) end = this.length\n if (targetStart >= target.length) targetStart = target.length\n if (!targetStart) targetStart = 0\n if (end > 0 && end < start) end = start\n\n // Copy 0 bytes; we're done\n if (end === start) return 0\n if (target.length === 0 || this.length === 0) return 0\n\n // Fatal error conditions\n if (targetStart < 0) {\n throw new RangeError('targetStart out of bounds')\n }\n if (start < 0 || start >= this.length) throw new RangeError('sourceStart out of bounds')\n if (end < 0) throw new RangeError('sourceEnd out of bounds')\n\n // Are we oob?\n if (end > this.length) end = this.length\n if (target.length - targetStart < end - start) {\n end = target.length - targetStart + start\n }\n\n var len = end - start\n var i\n\n if (this === target && start < targetStart && targetStart < end) {\n // descending copy from end\n for (i = len - 1; i >= 0; --i) {\n target[i + targetStart] = this[i + start]\n }\n } else if (len < 1000 || !Buffer.TYPED_ARRAY_SUPPORT) {\n // ascending copy from start\n for (i = 0; i < len; ++i) {\n target[i + targetStart] = this[i + start]\n }\n } else {\n Uint8Array.prototype.set.call(\n target,\n this.subarray(start, start + len),\n targetStart\n )\n }\n\n return len\n}\n\n// Usage:\n// buffer.fill(number[, offset[, end]])\n// buffer.fill(buffer[, offset[, end]])\n// buffer.fill(string[, offset[, end]][, encoding])\nBuffer.prototype.fill = function fill (val, start, end, encoding) {\n // Handle string cases:\n if (typeof val === 'string') {\n if (typeof start === 'string') {\n encoding = start\n start = 0\n end = this.length\n } else if (typeof end === 'string') {\n encoding = end\n end = this.length\n }\n if (val.length === 1) {\n var code = val.charCodeAt(0)\n if (code < 256) {\n val = code\n }\n }\n if (encoding !== undefined && typeof encoding !== 'string') {\n throw new TypeError('encoding must be a string')\n }\n if (typeof encoding === 'string' && !Buffer.isEncoding(encoding)) {\n throw new TypeError('Unknown encoding: ' + encoding)\n }\n } else if (typeof val === 'number') {\n val = val & 255\n }\n\n // Invalid ranges are not set to a default, so can range check early.\n if (start < 0 || this.length < start || this.length < end) {\n throw new RangeError('Out of range index')\n }\n\n if (end <= start) {\n return this\n }\n\n start = start >>> 0\n end = end === undefined ? this.length : end >>> 0\n\n if (!val) val = 0\n\n var i\n if (typeof val === 'number') {\n for (i = start; i < end; ++i) {\n this[i] = val\n }\n } else {\n var bytes = Buffer.isBuffer(val)\n ? val\n : utf8ToBytes(new Buffer(val, encoding).toString())\n var len = bytes.length\n for (i = 0; i < end - start; ++i) {\n this[i + start] = bytes[i % len]\n }\n }\n\n return this\n}\n\n// HELPER FUNCTIONS\n// ================\n\nvar INVALID_BASE64_RE = /[^+\\/0-9A-Za-z-_]/g\n\nfunction base64clean (str) {\n // Node strips out invalid characters like \\n and \\t from the string, base64-js does not\n str = stringtrim(str).replace(INVALID_BASE64_RE, '')\n // Node converts strings with length < 2 to ''\n if (str.length < 2) return ''\n // Node allows for non-padded base64 strings (missing trailing ===), base64-js does not\n while (str.length % 4 !== 0) {\n str = str + '='\n }\n return str\n}\n\nfunction stringtrim (str) {\n if (str.trim) return str.trim()\n return str.replace(/^\\s+|\\s+$/g, '')\n}\n\nfunction toHex (n) {\n if (n < 16) return '0' + n.toString(16)\n return n.toString(16)\n}\n\nfunction utf8ToBytes (string, units) {\n units = units || Infinity\n var codePoint\n var length = string.length\n var leadSurrogate = null\n var bytes = []\n\n for (var i = 0; i < length; ++i) {\n codePoint = string.charCodeAt(i)\n\n // is surrogate component\n if (codePoint > 0xD7FF && codePoint < 0xE000) {\n // last char was a lead\n if (!leadSurrogate) {\n // no lead yet\n if (codePoint > 0xDBFF) {\n // unexpected trail\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n } else if (i + 1 === length) {\n // unpaired lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n continue\n }\n\n // valid lead\n leadSurrogate = codePoint\n\n continue\n }\n\n // 2 leads in a row\n if (codePoint < 0xDC00) {\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n leadSurrogate = codePoint\n continue\n }\n\n // valid surrogate pair\n codePoint = (leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00) + 0x10000\n } else if (leadSurrogate) {\n // valid bmp char, but last char was a lead\n if ((units -= 3) > -1) bytes.push(0xEF, 0xBF, 0xBD)\n }\n\n leadSurrogate = null\n\n // encode utf8\n if (codePoint < 0x80) {\n if ((units -= 1) < 0) break\n bytes.push(codePoint)\n } else if (codePoint < 0x800) {\n if ((units -= 2) < 0) break\n bytes.push(\n codePoint >> 0x6 | 0xC0,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x10000) {\n if ((units -= 3) < 0) break\n bytes.push(\n codePoint >> 0xC | 0xE0,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else if (codePoint < 0x110000) {\n if ((units -= 4) < 0) break\n bytes.push(\n codePoint >> 0x12 | 0xF0,\n codePoint >> 0xC & 0x3F | 0x80,\n codePoint >> 0x6 & 0x3F | 0x80,\n codePoint & 0x3F | 0x80\n )\n } else {\n throw new Error('Invalid code point')\n }\n }\n\n return bytes\n}\n\nfunction asciiToBytes (str) {\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n // Node's code seems to be doing this and not & 0x7F..\n byteArray.push(str.charCodeAt(i) & 0xFF)\n }\n return byteArray\n}\n\nfunction utf16leToBytes (str, units) {\n var c, hi, lo\n var byteArray = []\n for (var i = 0; i < str.length; ++i) {\n if ((units -= 2) < 0) break\n\n c = str.charCodeAt(i)\n hi = c >> 8\n lo = c % 256\n byteArray.push(lo)\n byteArray.push(hi)\n }\n\n return byteArray\n}\n\nfunction base64ToBytes (str) {\n return base64.toByteArray(base64clean(str))\n}\n\nfunction blitBuffer (src, dst, offset, length) {\n for (var i = 0; i < length; ++i) {\n if ((i + offset >= dst.length) || (i >= src.length)) break\n dst[i + offset] = src[i]\n }\n return i\n}\n\nfunction isnan (val) {\n return val !== val // eslint-disable-line no-self-compare\n}\n","exports.read = function (buffer, offset, isLE, mLen, nBytes) {\n var e, m\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var nBits = -7\n var i = isLE ? (nBytes - 1) : 0\n var d = isLE ? -1 : 1\n var s = buffer[offset + i]\n\n i += d\n\n e = s & ((1 << (-nBits)) - 1)\n s >>= (-nBits)\n nBits += eLen\n for (; nBits > 0; e = (e * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n m = e & ((1 << (-nBits)) - 1)\n e >>= (-nBits)\n nBits += mLen\n for (; nBits > 0; m = (m * 256) + buffer[offset + i], i += d, nBits -= 8) {}\n\n if (e === 0) {\n e = 1 - eBias\n } else if (e === eMax) {\n return m ? NaN : ((s ? -1 : 1) * Infinity)\n } else {\n m = m + Math.pow(2, mLen)\n e = e - eBias\n }\n return (s ? -1 : 1) * m * Math.pow(2, e - mLen)\n}\n\nexports.write = function (buffer, value, offset, isLE, mLen, nBytes) {\n var e, m, c\n var eLen = (nBytes * 8) - mLen - 1\n var eMax = (1 << eLen) - 1\n var eBias = eMax >> 1\n var rt = (mLen === 23 ? Math.pow(2, -24) - Math.pow(2, -77) : 0)\n var i = isLE ? 0 : (nBytes - 1)\n var d = isLE ? 1 : -1\n var s = value < 0 || (value === 0 && 1 / value < 0) ? 1 : 0\n\n value = Math.abs(value)\n\n if (isNaN(value) || value === Infinity) {\n m = isNaN(value) ? 1 : 0\n e = eMax\n } else {\n e = Math.floor(Math.log(value) / Math.LN2)\n if (value * (c = Math.pow(2, -e)) < 1) {\n e--\n c *= 2\n }\n if (e + eBias >= 1) {\n value += rt / c\n } else {\n value += rt * Math.pow(2, 1 - eBias)\n }\n if (value * c >= 2) {\n e++\n c /= 2\n }\n\n if (e + eBias >= eMax) {\n m = 0\n e = eMax\n } else if (e + eBias >= 1) {\n m = ((value * c) - 1) * Math.pow(2, mLen)\n e = e + eBias\n } else {\n m = value * Math.pow(2, eBias - 1) * Math.pow(2, mLen)\n e = 0\n }\n }\n\n for (; mLen >= 8; buffer[offset + i] = m & 0xff, i += d, m /= 256, mLen -= 8) {}\n\n e = (e << mLen) | m\n eLen += mLen\n for (; eLen > 0; buffer[offset + i] = e & 0xff, i += d, e /= 256, eLen -= 8) {}\n\n buffer[offset + i - d] |= s * 128\n}\n","var toString = {}.toString;\n\nmodule.exports = Array.isArray || function (arr) {\n return toString.call(arr) == '[object Array]';\n};\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nexport interface WMFRecord {\n\tn: string;\n}\n\nexport interface WMFEscape {\n\tn: string;\n}\n\n/* 2.1.1.1 RecordType Enumeration */\nexport const WMFRecords: {[key: number]: WMFRecord} = {\n\t0x0000: { n: \"META_EOF\" }, // 2.3.2.1\n\t0x0626: { n: \"META_ESCAPE\" }, // 2.3.6.1\n\n\t0x0940: { n: \"META_DIBBITBLT\" }, // 2.3.1.2\n\t0x0B41: { n: \"META_DIBSTRETCHBLT\" }, // 2.3.1.3\n\n\t0x0A32: { n: \"META_EXTTEXTOUT\" }, // 2.3.3.5\n\t0x0325: { n: \"META_POLYLINE\" }, // 2.3.3.14\n\t0x0324: { n: \"META_POLYGON\" }, // 2.3.3.15\n\t0x0538: { n: \"META_POLYPOLYGON\" }, // 2.3.3.16\n\n\t0x02FC: { n: \"META_CREATEBRUSHINDIRECT\" }, // 2.3.4.1\n\t0x02FB: { n: \"META_CREATEFONTINDIRECT\" }, // 2.3.4.2\n\t0x02FA: { n: \"META_CREATEPENINDIRECT\" }, // 2.3.4.5\n\t0x01F0: { n: \"META_DELETEOBJECT\" }, // 2.3.4.7\n\t0x012C: { n: \"META_SELECTCLIPREGION\" }, // 2.3.4.9\n\t0x012D: { n: \"META_SELECTOBJECT\" }, // 2.3.4.10\n\n\t0x0416: { n: \"META_INTERSECTCLIPRECT\" }, // 2.3.5.3\n\t0x0035: { n: \"META_REALIZEPALETTE\" }, // 2.3.5.8\n\t0x0127: { n: \"META_RESTOREDC\" }, // 2.3.5.10\n\t0x001E: { n: \"META_SAVEDC\" }, // 2.3.5.11\n\t0x0102: { n: \"META_SETBKMODE\" }, // 2.3.5.15\n\t0x0103: { n: \"META_SETMAPMODE\" }, // 2.3.5.17\n\t0x0037: { n: \"META_SETPALENTRIES\" }, // 2.3.5.19\n\t0x0106: { n: \"META_SETPOLYFILLMODE\" }, // 2.3.5.20\n\t0x0107: { n: \"META_SETSTRETCHBLTMODE\" }, // 2.3.5.23\n\t0x012E: { n: \"META_SETTEXTALIGN\" }, // 2.3.5.24\n\t0x0209: { n: \"META_SETTEXTCOLOR\" }, // 2.3.5.26\n\t0x020C: { n: \"META_SETWINDOWEXT\" }, // 2.3.5.30\n\t0x020B: { n: \"META_SETWINDOWORG\" }, // 2.3.5.31\n\n\t0xFFFF: { n: \"META_SHEETJS\" }\n};\n\nexport const WMFEscapes: {[key: number]: WMFEscape} = {\n\t0x000F: { n: \"META_ESCAPE_ENHANCED_METAFILE\" }\n};\n\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nimport { PreppedBytes, prep_blob } from './util';\nimport { Action, PlaybackDeviceContextState, get_actions_prepped_bytes } from './wmf'\n\nexport const css_color = (clr: number): string => `#${(clr & 0xFF).toString(16).padStart(2, \"0\")}${((clr>>8) & 0xFF).toString(16).padStart(2, \"0\")}${((clr>>16) & 0xFF).toString(16).padStart(2, \"0\")}`\n\nexport const set_ctx_state = (ctx: CanvasRenderingContext2D, state: PlaybackDeviceContextState): void => {\n\tif(!state) return;\n\tlet font = \"\";\n\tif(state.Font) {\n\t\tif(state.Font.Italic) font += \" italic\";\n\t\tif(state.Font.Weight) font += ` ${state.Font.Weight == 700 ? \"bold\" : state.Font.Weight == 400 ? \"\" : state.Font.Weight}`;\n\t\tif(state.Font.Height < 0) font += ` ${-state.Font.Height}px`;\n\t\telse if(state.Font.Height > 0) font += ` ${state.Font.Height}px`;\n\t\tlet name = state.Font.Name || \"\";\n\t\tif(name == \"System\") name = \"Calibri\"; // TODO: default sys font is Segoe UI\n\t\tif(name) font += ` '${name}', sans-serif`;\n\t\tctx.font = font.trim();\n\t}\n};\n\n// TODO: DIB BIT ORDER?\nexport const render_actions_to_context = (out: Action[], ctx: CanvasRenderingContext2D) => {\n\tout.forEach(act => {\n\t\tctx.save();\n\t\tset_ctx_state(ctx, act.s);\n\t\tswitch(act.t) {\n\t\t\tcase \"poly\":\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(act.p[0][0], act.p[0][1]);\n\t\t\t\tact.p.slice(1).forEach(([x,y]) => {\n\t\t\t\t\tctx.lineTo(x, y);\n\t\t\t\t});\n\t\t\t\tif(act.g) ctx.closePath();\n\t\t\t\tctx.stroke();\n\t\t\t\tbreak;\n\t\t\tcase \"text\":\n\t\t\t\tif(act.s && act.s.TextColor) ctx.fillStyle = css_color(act.s.TextColor);\n\t\t\t\tif(act.s.Font.Angle != 0) {\n\t\t\t\t\tctx.translate(act.p[0], act.p[1]);\n\t\t\t\t\tctx.rotate(-act.s.Font.Angle * Math.PI / 180);\n\t\t\t\t\tctx.fillText(act.v, 0, 0);\n\t\t\t\t\tctx.translate(-act.p[0], -act.p[1]);\n\t\t\t\t}\n\t\t\t\telse ctx.fillText(act.v, act.p[0], act.p[1]);\n\t\t\t\tbreak;\n\t\t\tcase \"cpy\": {\n\t\t\t\t// TODO: base on ROP\n\t\t\t\tconst idata = ctx.getImageData(act.src[0][0], act.src[1][0], act.src[0][1], act.src[1][1]);\n\t\t\t\tctx.putImageData(idata, act.dst[0], act.dst[1]);\n\t\t\t} break;\n\t\t\tcase \"str\": {\n\t\t\t\tif(act.data && act.data.BitCount == 24 && act.data.ImageData) {\n\t\t\t\t\tconst _o = new Uint8ClampedArray(act.data.Width * act.data.Height * 4);\n\t\t\t\t\tfor(let i = 0; i < act.data.Width * act.data.Height; ++i) {\n\t\t\t\t\t\tconst j = (i % act.data.Width) + act.data.Width * (act.data.Height - 1 - Math.floor(i / act.data.Width));\n\t\t\t\t\t\t_o[4*i] = act.data.ImageData[3*j+2];\n\t\t\t\t\t\t_o[4*i+1] = act.data.ImageData[3*j+1];\n\t\t\t\t\t\t_o[4*i+2] = act.data.ImageData[3*j];\n\t\t\t\t\t\t_o[4*i+3] = 255;\n\t\t\t\t\t}\n\t\t\t\t\tconst idata = new ImageData(_o, act.data.Width, act.data.Height);\n\t\t\t\t\tctx.putImageData(idata, act.dst[0][0], act.dst[1][0]);\n\t\t\t\t}\n\t\t\t\t// TODO: ROP et al\n\t\t\t}\n\t\t}\n\t\tctx.restore();\n\t});\n}\n\nexport const render_canvas = (out: Action[], image: HTMLCanvasElement): void => {\n\tlet ctx: CanvasRenderingContext2D;\n\n\t/* find first action with window info */\n\tout.forEach(act => {\n\t\tif(ctx) return;\n\t\tif(!act.s) return;\n\t\tif(!act.s.Extent || !act.s.Origin) return;\n\t\timage.width = act.s.Extent[0] - act.s.Origin[0];\n\t\timage.height = act.s.Extent[1] - act.s.Origin[1];\n\t\tctx = image.getContext('2d');\n\t\tctx.save();\n\t\tctx.fillStyle = 'rgb(255,255,255)';\n\t\tctx.fillRect(0, 0, act.s.Extent[0] - act.s.Origin[0], act.s.Extent[1] - act.s.Origin[1])\n\t\tctx.restore();\n\t});\n\n\tif(!ctx) ctx = image.getContext('2d');\n\trender_actions_to_context(out, ctx);\n}\n\nexport const draw_canvas = (data: Buffer | Uint8Array | ArrayBuffer, image: HTMLCanvasElement): void => {\n\tif(data instanceof ArrayBuffer) return draw_canvas(new Uint8Array(data), image);\n\tprep_blob((data as any), 0);\n\tconst out: Action[] = get_actions_prepped_bytes(data as PreppedBytes);\n\treturn render_canvas(out, image);\n};\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nimport { PreppedBytes, prep_blob } from './util';\nimport { Action, get_actions_prepped_bytes, image_size_prepped_bytes } from './wmf'\n\nexport { draw_canvas, render_canvas } from './canvas';\n\nexport const get_actions = (data: Buffer | Uint8Array | ArrayBuffer): Action[] => {\n\tif(data instanceof ArrayBuffer) return get_actions(new Uint8Array(data));\n\tprep_blob((data as any), 0);\n\treturn get_actions_prepped_bytes(data as PreppedBytes);\n}\n\nexport const image_size = (data: Buffer | Uint8Array | ArrayBuffer): [number, number] => {\n\tif(data instanceof ArrayBuffer) return image_size(new Uint8Array(data));\n\tprep_blob((data as any), 0);\n\treturn image_size_prepped_bytes(data as PreppedBytes);\n}\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nexport type RawBytes = Buffer | number[];\n\nexport type PreppedBytes = RawBytes & {\n l: number;\n read_shift(size: 1): number;\n read_shift(size: 2): number;\n read_shift(size: 2, t: \"i\"): number;\n read_shift(size: 4): number;\n read_shift(size: 4, t: \"i\"): number;\n read_shift(size: 8, t: \"f\"): number;\n read_shift(size: number, t: \"cstr\"): string;\n read_shift(size: number, t: \"cpstr\"): string;\n read_shift(size: number, t: \"_wstr\"): string;\n read_shift(size: number, t?: string): number|string;\n chk(hexstr: string, fld: string): void;\n write_shift(t: number, val: string|number, f?: string): void;\n};\n\n// ---\n\nconst has_buf = !!(typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);\n\nlet Buffer_from: typeof Buffer.from;\n\nif(typeof Buffer !== 'undefined') {\n let nbfs = !Buffer.from;\n\tif(!nbfs) try {\n Buffer.from(\"foo\", \"utf8\");\n } catch(e) { nbfs = true; }\n\tBuffer_from = nbfs ? ((buf, enc?: string): Buffer => (enc) ? new Buffer(buf, (enc as BufferEncoding)) : new Buffer(buf)) : Buffer.from.bind(Buffer);\n\tif(!Buffer.alloc) Buffer.alloc = function(n: number): Buffer { return new Buffer(n); };\n\tif(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n: number): Buffer { return new Buffer(n); };\n}\n\nexport { Buffer_from, has_buf };\n\nexport const new_raw_buf = (len: number): Buffer|number[] => has_buf ? Buffer.alloc(len) : new Array(len);\n\nexport const new_unsafe_buf = (len: number): Buffer|number[] => has_buf ? Buffer.allocUnsafe(len) : new Array(len);\n\nexport const _chr = (c: number): string => String.fromCharCode(c);\n\nexport const chr0 = /\\u0000/g; // eslint-disable-line no-control-regex\nexport const chr1 = /[\\u0001-\\u0006]/g; // eslint-disable-line no-control-regex\n\n// ---\n\nconst read_double_le = (b: RawBytes, idx: number): number => {\n\tconst s = 1 - 2 * (b[idx + 7] >>> 7);\n\tlet e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);\n\tlet m = (b[idx+6]&0x0f);\n\tfor(let i = 5; i >= 0; --i) m = m * 256 + b[idx + i];\n\tif(e == 0x7ff) return m == 0 ? (s * Infinity) : NaN;\n\tif(e == 0) e = -1022;\n\telse { e -= 1023; m += Math.pow(2,52); }\n\treturn s * Math.pow(2, e - 52) * m;\n};\n\nconst write_double_le = (b: RawBytes, v: number, idx: number): void => {\n\tconst bs = ((((v < 0) || (1/v == -Infinity)) ? 1 : 0) << 7);\n\tlet e = 0, m = 0;\n\tconst av = bs ? (-v) : v;\n\tif(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }\n\telse if(av == 0) e = m = 0;\n\telse {\n\t\te = Math.floor(Math.log(av) / Math.LN2);\n\t\tm = av * Math.pow(2, 52 - e);\n\t\tif((e <= -1023) && (!isFinite(m) || (m < Math.pow(2,52)))) { e = -1022; }\n\t\telse { m -= Math.pow(2,52); e+=1023; }\n\t}\n\tfor(let i = 0; i <= 5; ++i, m/=256) b[idx + i] = m & 0xff;\n\tb[idx + 6] = ((e & 0x0f) << 4) | (m & 0xf);\n\tb[idx + 7] = (e >> 4) | bs;\n};\n\nlet __toBuffer = (bufs/*:Array >*/): RawBytes => {\n\tconst x: number[] =[];\n\tfor(let i=0; i b[idx];\nconst __readUInt16LE = (b: RawBytes, idx: number): number => (b[idx+1]*(1<<8))+b[idx];\nconst __readInt16LE = (b: RawBytes, idx: number): number => { const u = (b[idx+1]*(1<<8))+b[idx]; return (u < 0x8000) ? u : ((0xffff - u + 1) * -1); };\nconst __readUInt32LE = (b: RawBytes, idx: number): number => b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx];\nconst __readInt32LE = (b: RawBytes, idx: number): number => (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx];\nconst __readInt32BE = (b: RawBytes, idx: number): number => (b[idx]<<24)|(b[idx+1]<<16)|(b[idx+2]<<8)|b[idx+3];\n\nlet __utf16le = (b: RawBytes, s: number, e: number): string => {\n\tconst ss: string[] = [];\n\tfor(let i=s; i 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___lpstr = __lpstr;\nlet __cpstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___cpstr = __cpstr;\nlet __lpwstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___lpwstr = __lpwstr;\nlet __lpp4, ___lpp4;\n__lpp4 = ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : \"\";};\nconst ___8lpp4 = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : \"\";};\nlet __8lpp4 = ___8lpp4;\nconst ___double = (b/*:RawBytes|CFBlob*/, idx: number): number => read_double_le(b, idx);\nlet __double = ___double;\n\nif(has_buf) {\n\t__utf16le = (b/*:RawBytes|CFBlob*/,s: number,e: number): string => (!Buffer.isBuffer(b)) ? ___utf16le(b,s,e) : b.toString('utf16le',s,e).replace(chr0,'');\n\t__hexlify = (b/*:RawBytes|CFBlob*/,s: number,l: number): string => Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l);\n\t__lpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : \"\";};\n\t__cpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___cpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : \"\";};\n\t__lpwstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); const len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};\n\t__lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};\n\t__8lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};\n\t__utf8 = (b/*:RawBytes|CFBlob*/, s: number, e: number): string => (Buffer.isBuffer(b)) ? b.toString('utf8',s,e) : ___utf8(b,s,e);\n\t__toBuffer = (bufs): RawBytes => (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);\n\t__double = (b/*:RawBytes|CFBlob*/, i: number): number => (Buffer.isBuffer(b)) ? b.readDoubleLE(i) : ___double(b,i);\n}\n\nfunction ReadShift(size: 1): number;\nfunction ReadShift(size: 2): number;\nfunction ReadShift(size: 2, t: \"i\"): number;\nfunction ReadShift(size: 4): number;\nfunction ReadShift(size: 4, t: \"i\"): number;\nfunction ReadShift(size: 8, t: \"f\"): number;\nfunction ReadShift(size: number, t: \"cstr\"): string;\nfunction ReadShift(size: number, t: \"cpstr\"): string;\nfunction ReadShift(size: number, t: \"_wstr\"): string;\nfunction ReadShift(size: number, t?: string): number|string {\n\tlet o=\"\", oI = 0, oR, w, vv, i, loc;\n\tconst oo = [];\n\tswitch(t) {\n\t\tcase 'dbcs':\n\t\t\tloc = this.l;\n\t\t\tif(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString(\"utf16le\");\n\t\t\telse for(i = 0; i < size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }\n\t\t\tsize *= 2;\n\t\t\tbreak;\n\n\t\tcase 'utf8': o = __utf8(this, this.l, this.l + size); break;\n\t\tcase 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;\n\n\t\tcase 'wstr':\n\t\t\treturn ReadShift.call(this, size, 'dbcs');\n\n\t\t/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */\n\t\tcase 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;\n\t\tcase 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;\n\t\t/* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */\n\t\tcase 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break;\n\t\t/* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */\n\t\tcase 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break;\n\t\t/* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */\n\t\tcase '8lpp4': size = 4 + __readUInt32LE(this, this.l); o = __8lpp4(this, this.l); if(size & 0x03) size += 4 - (size & 0x03); break;\n\n\t\tcase 'cstr': size = 0; o = \"\";\n\t\t\twhile((w=__readUInt8(this, this.l + size++))!==0) oo.push(String.fromCharCode(w));\n\t\t\to = oo.join(\"\"); break;\n\t\tcase '_wstr': size = 0; o = \"\";\n\t\t\twhile((w=__readUInt16LE(this,this.l +size))!==0){oo.push(String.fromCharCode(w));size+=2;}\n\t\t\tsize+=2; o = oo.join(\"\"); break;\n\n\t\t/* sbcs and dbcs support continue records in the SST way TODO codepages */\n\t\tcase 'dbcs-cont': o = \"\"; loc = this.l;\n\t\t\tfor(i = 0; i < size; ++i) {\n\t\t\t\tif(this.lens && this.lens.indexOf(loc) !== -1) {\n\t\t\t\t\tw = __readUInt8(this, loc);\n\t\t\t\t\tthis.l = loc + 1;\n\t\t\t\t\tvv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');\n\t\t\t\t\treturn oo.join(\"\") + vv;\n\t\t\t\t}\n\t\t\t\too.push(String.fromCharCode(__readUInt16LE(this, loc)));\n\t\t\t\tloc+=2;\n\t\t\t} o = oo.join(\"\"); size *= 2; break;\n\n\t\tcase 'cpstr':\n\t\t/* falls through */\n\t\tcase 'sbcs-cont': o = \"\"; loc = this.l;\n\t\t\tfor(i = 0; i != size; ++i) {\n\t\t\t\tif(this.lens && this.lens.indexOf(loc) !== -1) {\n\t\t\t\t\tw = __readUInt8(this, loc);\n\t\t\t\t\tthis.l = loc + 1;\n\t\t\t\t\tvv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');\n\t\t\t\t\treturn oo.join(\"\") + vv;\n\t\t\t\t}\n\t\t\t\too.push(String.fromCharCode(__readUInt8(this, loc)));\n\t\t\t\tloc+=1;\n\t\t\t} o = oo.join(\"\"); break;\n\n\t\tdefault:\n\tswitch(size) {\n\t\tcase 1: oI = __readUInt8(this, this.l); this.l++; return oI;\n\t\tcase 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI;\n\t\tcase 4: case -4:\n\t\t\tif(t === 'i' || ((this[this.l+3] & 0x80)===0)) { oI = ((size > 0) ? __readInt32LE : __readInt32BE)(this, this.l); this.l += 4; return oI; }\n\t\t\telse { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR;\n\t\tcase 8: case -8:\n\t\t\tif(t === 'f') {\n\t\t\t\tif(size == 8) oR = __double(this, this.l);\n\t\t\t\telse oR = __double([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]], 0);\n\t\t\t\tthis.l += 8; return oR;\n\t\t\t} else size = 8;\n\t\t/* falls through */\n\t\tcase 16: o = __hexlify(this, this.l, size); break;\n\t}}\n\tthis.l+=size; return o;\n}\n\nconst __writeUInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };\nconst __writeInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };\nconst __writeUInt16LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };\n\nfunction WriteShift(t: number, val: string|number, f?: string): void {\n\tlet size = 0, i = 0;\n\tif(f === 'dbcs') {\n\t\tif(typeof val !== 'string') throw new Error(\"expected string\");\n\t\tfor(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);\n\t\tsize = 2 * val.length;\n\t} else if(f === 'sbcs') {\n\t\t{\n\t\t\tval = (val as string).replace(/[^\\x00-\\x7F]/g, \"_\"); // eslint-disable-line no-control-regex\n\t\t\tfor(i = 0; i != val.length; ++i) this[this.l + i] = (val.charCodeAt(i) & 0xFF);\n\t\t}\n\t\tsize = val.length;\n\t} else if(f === 'hex') {\n\t\tfor(; i < t; ++i) {\n\t\t\tthis[this.l++] = (parseInt((val as string).slice(2*i, 2*i+2), 16)||0);\n\t\t} return this;\n\t} else if(f === 'utf16le') {\n\t\t\t/*:: if(typeof val !== \"string\") throw new Error(\"unreachable\"); */\n\t\t\tconst end: number = Math.min(this.l + t, this.length);\n\t\t\tfor(i = 0; i < Math.min((val as string).length, t); ++i) {\n\t\t\t\tconst cc = (val as string).charCodeAt(i);\n\t\t\t\tthis[this.l++] = (cc & 0xff);\n\t\t\t\tthis[this.l++] = (cc >> 8);\n\t\t\t}\n\t\t\twhile(this.l < end) this[this.l++] = 0;\n\t\t\treturn this;\n\t} else if(typeof val === 'number') switch(t) {\n\t\tcase 1: size = 1; this[this.l] = val&0xFF; break;\n\t\tcase 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;\n\t\tcase 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break;\n\t\tcase 4: size = 4; __writeUInt32LE(this, val, this.l); break;\n\t\tcase 8: size = 8; if(f === 'f') { write_double_le(this, val, this.l); break; }\n\t\t/* falls through */\n\t\tcase 16: break;\n\t\tcase -4: size = 4; __writeInt32LE(this, val, this.l); break;\n\t}\n\tthis.l += size; return this;\n}\n\nfunction CheckField(hexstr: string, fld: string): void {\n\tconst m = __hexlify(this,this.l,hexstr.length>>1);\n\tif(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);\n\tthis.l += hexstr.length>>1;\n}\n\nconst prep_blob = (blob: PreppedBytes, pos: number): void => {\n\tblob.l = pos;\n\tblob.read_shift = ReadShift;\n\tblob.chk = CheckField;\n\tblob.write_shift = WriteShift;\n};\n\nconst new_buf = (sz: number): PreppedBytes => {\n\tconst o = (new_raw_buf(sz) as PreppedBytes);\n\tprep_blob(o, 0);\n\treturn o;\n};\n\nexport { ReadShift, WriteShift, CheckField, prep_blob, new_buf, __utf16le };\n\n// ---\n\nconst __bconcat = function(bufs/*:Array*/): Buffer | Uint8Array | number[] {\n let is_all_arrays = true;\n for(let w = 0; w < bufs.length; ++w) if(!Array.isArray(bufs[w])) is_all_arrays = false;\n\tif(is_all_arrays) return [].concat(...bufs);\n\tlet maxlen = 0, i = 0;\n\tfor(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;\n\tconst o = new Uint8Array(maxlen);\n\tfor(i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen);\n\treturn o;\n};\nlet bconcat = __bconcat;\n\nif(has_buf) bconcat = (bufs): Buffer | Uint8Array | number[] => Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat(...bufs);\n\nexport { bconcat };\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nimport { PreppedBytes, RawBytes, bconcat, prep_blob } from './util';\nimport { WMFRecords, WMFEscapes } from './Records';\n\nexport interface Brush {\n\t/** Style (MS-WMF 2.1.1.4) */\n\tStyle?: Number;\n\t/** Brush color RGB */\n\tColor?: number;\n\t/** Hatch Type (2.1.1.12 if brush is hatched) */\n\tHatch?: number;\n}\n\nexport interface Pen {\n\tStyle?: number;\n\tWidth?: number;\n\tColor?: number;\n}\n\nexport interface Font {\n\tName?: string;\n\tHeight?: number;\n\tItalic?: boolean;\n\tWeight?: number;\n\tAngle?: number;\n}\n\nexport interface PlaybackDeviceContextState {\n\t/** Mapping mode (MS-WMF 2.1.1.16) */\n\tMapMode?: number;\n\t/** Output window origin (X, Y) */\n\tOrigin?: [number, number];\n\t/** Output window extents (X, Y) */\n\tExtent?: [number, number];\n\t/** Background Mix Mode (MS-WMF 2.1.1.20) */\n\tBkMode?: number;\n\t/** Polygon fill mode (MS-WMF 2.1.1.25) */\n\tPolyFillMode?: number;\n\t/** Bitmap stretching mode (MS-WMF 2.1.1.30) */\n\tStretchMode?: number;\n\t/** Text alignment mode (MS-WMF 2.1.2.3 / 2.1.2.4) */\n\tTextAlignmentMode?: number;\n\t/** Text foreground color RGB */\n\tTextColor?: number;\n\t/** Brush */\n\tBrush?: Brush;\n\t/** Font */\n\tFont?: Font;\n\t/** Pen */\n\tPen?: Pen;\n\t/** Clipping Region (x,y) LT (x,y) RB */\n\tClipRect?: [[number, number], [number, number]];\n}\n\n/** [x, y] */\nexport type Point = [ number, number ];\n\nexport interface ActionCommon {\n\t/** State */\n\ts?: PlaybackDeviceContextState;\n}\n\n/** Draw Text */\nexport interface ActionText extends ActionCommon {\n\t/** Action Type */\n\tt: \"text\";\n\n\t/** Text */\n\tv: string;\n\n\t/** Origin */\n\tp?: Point;\n}\n\n/** Draw Polygon (shape with stroke/fill) / Polyline (stroke only) */\nexport interface ActionPoly extends ActionCommon {\n\t/** Action Type */\n\tt: \"poly\";\n\n\t/** Points */\n\tp: Point[];\n\n\t/** Polygon (true) or Polyline (false) */\n\tg: boolean;\n}\n\nexport interface ActionRaster {\n\t/** Raster Operaton 2.1.1.31 */\n\trop?: number;\n}\n\nexport interface ActionCpy extends ActionCommon, ActionRaster {\n\tt: \"cpy\";\n\n\t/** Source [[X, W], [Y, H]] */\n\tsrc: [[number, number], [number, number]];\n\n\tdst: Point;\n\n\tdata?: any;\n}\n\nexport interface ActionStr extends ActionCommon, ActionRaster {\n\tt: \"str\";\n\n\t/** Source [[X, W], [Y, H]] */\n\tsrc: [[number, number], [number, number]];\n\n\t/** Dest [[X, W], [Y, H]] */\n\tdst: [[number, number], [number, number]];\n\n\tdata?: any;\n}\n\nexport type Action = ActionText | ActionPoly | ActionCpy | ActionStr;\n\nconst parse_emf = (data: PreppedBytes): void => {\n\t//try { require(\"fs\").writeFileSync(\"out.emf\", data); } catch(e) {}\n}\n\n/* 2.2.2.9 */\nconst parse_dib = (data: PreppedBytes) => {\n\tif(data.length == 0) return null;\n\tprep_blob(data, 0);\n\n\t/* DIBHeaderInfo */\n\tconst HeaderSize = data.read_shift(4);\n\tlet Width = 0, Height = 0, Planes = 0, BitCount = 0;\n\tlet Compression = 0, ImageSize = 0, XPelsPerMeter = 0, YPelsPerMeter = 0, ColorUsed = 0, ColorImportant = 0;\n\tif(HeaderSize == 0x0C) {\n\t\tWidth = data.read_shift(2);\n\t\tHeight = data.read_shift(2);\n\t} else {\n\t\tWidth = data.read_shift(4, 'i');\n\t\tHeight = data.read_shift(4, 'i');\n\t}\n\tPlanes = data.read_shift(2);\n\tBitCount = data.read_shift(2);\n\n\tconst out: object = {\n\t\tWidth,\n\t\tHeight,\n\t\tBitCount,\n\t};\n\n\tif(HeaderSize != 0x0C) {\n\t\tCompression = data.read_shift(4);\n\t\tImageSize = data.read_shift(4);\n\t\tXPelsPerMeter = data.read_shift(4, 'i');\n\t\tYPelsPerMeter = data.read_shift(4, 'i');\n\t\tColorUsed = data.read_shift(4);\n\t\tColorImportant = data.read_shift(4);\n\t\tout[\"Compression\"] = Compression;\n\t\tif(BitCount == 24 && ImageSize > Height * 3 * Width) Width = out[\"Width\"] = ImageSize / (Height * 3);\n\t}\n\n\t/* Colors */\n\t/* BitmapBuffer */\n\tif(ImageSize == data.length - data.l) {\n\t\tout[\"ImageData\"] = data.slice(data.l, data.length);\n\t\tprep_blob(out[\"ImageData\"], 0);\n\t}\n\treturn out;\n}\n\nconst add_to_objects = (objects: PlaybackDeviceContextState[], obj: PlaybackDeviceContextState): void => {\n\tlet found = false;\n\tfor(var i = 0; i < objects.length; ++i) if(!objects[i]) { objects[i] = obj; found = true; }\n\tif(!found) objects.push(obj);\n}\n\nexport const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {\n\tconst out: Action[] = [];\n\n\t/* 2.3.22 META_HEADER */\n\t// Type (2 bytes) must be 1 or 2\n\tlet h = data.read_shift(2);\n\tif(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`;\n\t// HeaderSize expected to be 9\n\tif((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`;\n\t// Version (2 bytes) 1 or 3\n\th = data.read_shift(2);\n\tif(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`;\n\t// SizeLow\n\t// SizeHigh\n\t// #Objects\n\t// MaxRecord\n\t// NumberOfMembers\n\tdata.l = 18;\n\n\tlet rt = 0;\n\n\t/* used for EMF */\n\tlet escapecnt = 0;\n\tlet CommentRecordCount = 0;\n\tlet RemainingBytes = 0;\n\tlet EnhancedMetafileDataSize = 0;\n\tlet bufs: RawBytes[] = [];\n\n\tlet objects: PlaybackDeviceContextState[] = [];\n\tlet states: PlaybackDeviceContextState[] = [];\n\tlet state: PlaybackDeviceContextState = {};\n\tlet sidx = -1;\n\n\twhile(data.l < data.length) {\n\t\th = data.read_shift(4);\n\t\tconst end = data.l + h*2 - 4;\n\n\t\trt = data.read_shift(2);\n\t\tlet Record = WMFRecords[rt];\n\t\tif(rt == 0x0000) break; // META_EOF\n\n\t\tswitch(rt) {\n\t\t\tcase 0x0626: { // META_ESCAPE\n\t\t\t\tconst EscapeFunction = data.read_shift(2);\n\t\t\t\tconst Escape = WMFEscapes[EscapeFunction];\n\t\t\t\t//console.log(\"::\", Escape);\n\t\t\t\t/* 2.3.6 */\n\t\t\t\tswitch(EscapeFunction) {\n\t\t\t\t\tcase 0x000F: { // META_ESCAPE_ENHANCED_METAFILE\n\t\t\t\t\t\tconst ByteCount = data.read_shift(2);\n\t\t\t\t\t\tlet tmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x43464D57) throw `Escape: Comment ID 0x${tmp.toString(16)} != 0x43464D57`;\n\t\t\t\t\t\ttmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x00000001) throw `Escape: Comment Type 0x${tmp.toString(16)} != 0x00000001`;\n\t\t\t\t\t\ttmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x00010000) throw `Escape: Version 0x${tmp.toString(16)} != 0x00010000`;\n\n\t\t\t\t\t\tconst Checksum = data.read_shift(2);\n\n\t\t\t\t\t\tdata.l += 4; // Flags\n\t\t\t\t\t\tif(escapecnt == 0) {\n\t\t\t\t\t\t\tCommentRecordCount = data.read_shift(4); // total number of records\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst _CommentRecordCount = data.read_shift(4);\n\t\t\t\t\t\t\tif(_CommentRecordCount != CommentRecordCount) throw `Escape: CommentRecordCount ${_CommentRecordCount} != ${CommentRecordCount}`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst CurrentRecordSize = data.read_shift(4); // size of this record\n\t\t\t\t\t\tconst _RemainingBytes = data.read_shift(4);\n\t\t\t\t\t\tif(escapecnt > 0 && CurrentRecordSize + _RemainingBytes != RemainingBytes) throw `Escape: ${RemainingBytes} != ${CurrentRecordSize} + ${_RemainingBytes}`;\n\t\t\t\t\t\tRemainingBytes = _RemainingBytes;\n\t\t\t\t\t\tconst _EnhancedMetafileDataSize = data.read_shift(4);\n\t\t\t\t\t\tif(escapecnt == 0) {\n\t\t\t\t\t\t\tif(_EnhancedMetafileDataSize != CurrentRecordSize + _RemainingBytes) throw `Escape: ${_EnhancedMetafileDataSize} != ${CurrentRecordSize} + ${_RemainingBytes}`;\n\t\t\t\t\t\t\tEnhancedMetafileDataSize = _EnhancedMetafileDataSize;\n\t\t\t\t\t\t} else if(EnhancedMetafileDataSize != _EnhancedMetafileDataSize) throw `Escape: ${EnhancedMetafileDataSize} != ${_EnhancedMetafileDataSize}`;\n\n\t\t\t\t\t\tif(ByteCount != (end - data.l) + 34) throw `Escape: Sizes ${ByteCount} != ${end - data.l} + 34`\n\t\t\t\t\t\tif(end - data.l != CurrentRecordSize) throw `Escape: CRSize ${CurrentRecordSize} != ${end - data.l}`;\n\t\t\t\t\t\tbufs.push(data.slice(data.l, end));\n\t\t\t\t\t\t++escapecnt;\n\t\t\t\t\t\tif(escapecnt == CommentRecordCount) {\n\t\t\t\t\t\t\tconst prepped: PreppedBytes = bconcat(bufs) as PreppedBytes;\n\t\t\t\t\t\t\tprep_blob(prepped, 0);\n\t\t\t\t\t\t\tparse_emf(prepped);\n\t\t\t\t\t\t}\n\t\t\t\t\t} break;\n\t\t\t\t\tdefault: throw `Escape: Unrecognized META_ESCAPE Type 0x${EscapeFunction.toString(16)}`;\n\t\t\t\t}\n\t\t\t} break;\n\n\t\t\t// #region 2.3.1 Bitmap Record Types\n\n\t\t\tcase 0x0940: { // 2.3.1.2 META_DIBBITBLT\n\t\t\t\tconst has_bitmap = h != (rt>>8)+3;\n\t\t\t\tconst RasterOperation = data.read_shift(4);\n\t\t\t\tconst YSrc = data.read_shift(2, \"i\");\n\t\t\t\tconst XSrc = data.read_shift(2, \"i\");\n\t\t\t\tif(!has_bitmap) data.l += 2;\n\t\t\t\tconst Height = data.read_shift(2, \"i\");\n\t\t\t\tconst Width = data.read_shift(2, \"i\");\n\t\t\t\tconst YDest = data.read_shift(2, \"i\");\n\t\t\t\tconst XDest = data.read_shift(2, \"i\");\n\t\t\t\tconst res: ActionCpy = {\n\t\t\t\t\tt: \"cpy\",\n\t\t\t\t\tsrc: [[XSrc, Width], [YSrc, Height]],\n\t\t\t\t\tdst: [XDest, YDest],\n\t\t\t\t\trop: RasterOperation,\n\t\t\t\t\ts: Object.assign({}, state)\n\t\t\t\t};\n\t\t\t\tif(has_bitmap) {\n\t\t\t\t\tconst DIB = parse_dib(data.slice(data.l, end) as PreppedBytes);\n\t\t\t\t\tres.data = DIB;\n\t\t\t\t}\n\t\t\t\tout.push(res);\n\t\t\t} break;\n\n\t\t\tcase 0x0B41: { // 2.3.1.3 META_DIBSTRETCHBLT\n\t\t\t\tconst has_bitmap = h != (rt>>8)+3;\n\t\t\t\tconst RasterOperation = data.read_shift(4);\n\t\t\t\tconst SrcHeight = data.read_shift(2, \"i\");\n\t\t\t\tconst SrcWidth = data.read_shift(2, \"i\");\n\t\t\t\tconst YSrc = data.read_shift(2, \"i\");\n\t\t\t\tconst XSrc = data.read_shift(2, \"i\");\n\t\t\t\tif(!has_bitmap) data.l += 2;\n\t\t\t\tconst DestHeight = data.read_shift(2, \"i\");\n\t\t\t\tconst DestWidth = data.read_shift(2, \"i\");\n\t\t\t\tconst YDest = data.read_shift(2, \"i\");\n\t\t\t\tconst XDest = data.read_shift(2, \"i\");\n\t\t\t\tconst res: ActionStr = {\n\t\t\t\t\tt: \"str\",\n\t\t\t\t\tsrc: [[XSrc, SrcWidth], [YSrc, SrcHeight]],\n\t\t\t\t\tdst: [[XDest, DestWidth], [YDest, DestHeight]],\n\t\t\t\t\trop: RasterOperation,\n\t\t\t\t\ts: Object.assign({}, state)\n\t\t\t\t};\n\t\t\t\tif(has_bitmap) {\n\t\t\t\t\tconst DIB = parse_dib(data.slice(data.l, end) as PreppedBytes);\n\t\t\t\t\tres.data = DIB;\n\t\t\t\t}\n\t\t\t\tout.push(res);\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.3 Drawing Record Types\n\n\t\t\tcase 0x0A32: { // 2.3.3.5 META_EXTTEXTOUT\n\t\t\t\tconst Y = data.read_shift(2);\n\t\t\t\tconst X = data.read_shift(2);\n\t\t\t\tconst StringLength = data.read_shift(2);\n\t\t\t\tconst fwOpts = data.read_shift(2); // 2.1.2.2\n\t\t\t\tif(fwOpts & 0x06) {\n\t\t\t\t\tdata.l += 8; // Rectangle 2.2.2.18 (for clipping/opaquing)\n\t\t\t\t}\n\t\t\t\tconst str = data.read_shift(StringLength, 'cpstr');\n\t\t\t\tif(data.l < end){/* TODO: Dx */}\n\t\t\t\tout.push({t: \"text\", v: str, p: [X, Y], s: Object.assign({}, state)});\n\t\t\t\t/* TODO!! */\n\t\t\t} break;\n\n\t\t\tcase 0x0325: // 2.3.3.14 META_POLYLINE\n\t\t\tcase 0x0324: // 2.3.3.15 META_POLYGON\n\t\t\t{\n\t\t\t\tconst nPoints = data.read_shift(2);\n\t\t\t\tconst points: Array = [];\n\t\t\t\tfor(let i = 0; i < nPoints; ++i) points.push([data.read_shift(2), data.read_shift(2)])\n\t\t\t\tout.push({t: \"poly\", p: points, g: rt !== 0x0325, s: state});\n\t\t\t} break;\n\n\t\t\tcase 0x0538: { // 2.3.3.16 META_POLYPOLYGON\n\t\t\t\tconst nPolygons = data.read_shift(2);\n\t\t\t\tconst polys: Array > = [];\n\t\t\t\tconst szs: number[] = [];\n\t\t\t\t/* 2.2.2.17 PolyPolygon */\n\t\t\t\tfor(let i = 0; i < nPolygons; ++i) szs[i] = data.read_shift(2);\n\t\t\t\tfor(let i = 0; i < szs.length; ++i) {\n\t\t\t\t\tpolys[i] = [];\n\t\t\t\t\tfor(let j = 0; j < szs[i]; ++j) polys[i].push([data.read_shift(2), data.read_shift(2)])\n\t\t\t\t\tout.push({t: \"poly\", p: polys[i], g: true, s: state});\n\t\t\t\t}\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.4 Object Record Types\n\n\t\t\tcase 0x02FC: { // 2.3.4.1 META_CREATEBRUSHINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Brush = {\n\t\t\t\t\tStyle: data.read_shift(2),\n\t\t\t\t\tColor: data.read_shift(4),\n\t\t\t\t\tHatch: data.read_shift(2)\n\t\t\t\t};\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x02FB: { // 2.3.4.2 META_CREATEFONTINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Font = {};\n\t\t\t\t/* 2.2.1.2 Font TODO!! */\n\t\t\t\tconst Height = data.read_shift(2, \"i\");\n\t\t\t\tconst Width = data.read_shift(2, \"i\");\n\t\t\t\tconst Escapement = data.read_shift(2, \"i\");\n\t\t\t\tconst Orientation = data.read_shift(2, \"i\");\n\t\t\t\tconst Weight = data.read_shift(2, \"i\");\n\t\t\t\tconst Italic = !!data.read_shift(1);\n\t\t\t\tconst Underline = !!data.read_shift(1);\n\t\t\t\tconst StrikeOut = !!data.read_shift(1);\n\t\t\t\tconst CharSet = data.read_shift(1);\n\t\t\t\tconst OutPrecision = data.read_shift(1);\n\t\t\t\tconst ClipPrecision = data.read_shift(1);\n\t\t\t\tconst Quality = data.read_shift(1);\n\t\t\t\tconst PitchAndFamily = data.read_shift(1);\n\t\t\t\tconst Facename = data.read_shift(32, \"cstr\");\n\t\t\t\tobj.Font.Name = Facename;\n\t\t\t\tobj.Font.Height = Height;\n\t\t\t\tobj.Font.Weight = Weight;\n\t\t\t\tobj.Font.Italic = Italic;\n\t\t\t\tobj.Font.Angle = Escapement / 10;\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x02FA: { // 2.3.4.5 META_CREATEPENINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Pen = {\n\t\t\t\t\tStyle: data.read_shift(2),\n\t\t\t\t\tWidth: data.read_shift(4) & 0xFF,\n\t\t\t\t\tColor: data.read_shift(4)\n\t\t\t\t};\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x01F0: { // 2.3.4.7 META_DELETEOBJECT\n\t\t\t\tconst ObjectIndex = data.read_shift(2);\n\t\t\t\t//console.log(\"DELETE\", ObjectIndex, objects[ObjectIndex]);\n\t\t\t\tobjects[ObjectIndex] = null;\n\t\t\t} break;\n\n\t\t\tcase 0x012C: { // 2.3.4.9 META_SELECTCLIPREGION\n\t\t\t\tconst Region = data.read_shift(2);\n\t\t\t\t//console.log(\"CLIPREGION\", Region, objects[Region]);\n\t\t\t\t//Object.assign(state, objects[Region]);\n\t\t\t} break;\n\n\t\t\tcase 0x012D: { // 2.3.4.10 META_SELECTOBJECT\n\t\t\t\tconst ObjectIndex = data.read_shift(2);\n\t\t\t\t//console.log(\"SELECT\", ObjectIndex, objects[ObjectIndex]);\n\t\t\t\tObject.assign(state, objects[ObjectIndex]);\n\t\t\t\t// TODO!!\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.5 State Record Types\n\n\t\t\tcase 0x0416: // 2.3.5.3 META_INTERSECTCLIPRECT\n\t\t\t\tstate.ClipRect = [[0,0],[0,0]];\n\t\t\t\tstate.ClipRect[1][1] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[1][0] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[0][1] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[0][0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0127: { // 2.3.5.10 META_RESTOREDC\n\t\t\t\tconst nSavedDC = data.read_shift(2, 'i');\n\t\t\t\tstate = states[sidx = (nSavedDC >= 0 ? nSavedDC : sidx + nSavedDC)];\n\t\t\t} break;\n\n\t\t\tcase 0x001E: // 2.3.5.11 META_SAVEDC\n\t\t\t\tstates.push(state);\n\t\t\t\tsidx = states.length - 1;\n\t\t\t\tstate = JSON.parse(JSON.stringify(state));\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0102: // 2.3.5.15 META_SETBKMODE\n\t\t\t\tstate.BkMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0103: // 2.3.5.17 META_SETMAPMODE\n\t\t\t\tstate.MapMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0106: // 2.3.5.20 META_SETPOLYFILLMODE\n\t\t\t\tstate.PolyFillMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0107: // 2.3.5.23 META_SETSTRETCHBLTMODE\n\t\t\t\tstate.StretchMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x012E: // 2.3.5.24 META_SETTEXTALIGN\n\t\t\t\tstate.TextAlignmentMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0209: // 2.3.5.26 META_SETTEXTCOLOR\n\t\t\t\tstate.TextColor = data.read_shift(4);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020C: // 2.3.5.30 META_SETWINDOWEXT\n\t\t\t\tstate.Extent = [0, 0];\n\t\t\t\tstate.Extent[1] = data.read_shift(2);\n\t\t\t\tstate.Extent[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020B: // 2.3.5.31 META_SETWINDOWORG\n\t\t\t\tstate.Origin = [0, 0];\n\t\t\t\tstate.Origin[1] = data.read_shift(2);\n\t\t\t\tstate.Origin[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\t// #endregion\n\n\t\t\tdefault:\n\t\t\t\tif(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`;\n\t\t\t\tconsole.log(Record);\n\t\t}\n\t\tdata.l = end;\n\t\t//if(rt != 0x0626) console.log(Record);\n\t}\n\tif(rt !== 0) throw `Record: Last Record Type ${rt} is not EOF type`;\n\treturn out;\n}\n\nexport const image_size_prepped_bytes = (data: PreppedBytes): [number, number] => {\n\tconst origin: Point = [NaN, NaN], extents: Point = [NaN, NaN];\n\n\t/* 2.3.22 META_HEADER */\n\t// Type (2 bytes) must be 1 or 2\n\tlet h = data.read_shift(2);\n\tif(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`;\n\t// HeaderSize expected to be 9\n\tif((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`;\n\t// Version (2 bytes) 1 or 3\n\th = data.read_shift(2);\n\tif(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`;\n\tdata.l = 18;\n\n\tlet rt = 0;\n\n\twhile(data.l < data.length) {\n\t\th = data.read_shift(4);\n\t\tconst end = data.l + h*2 - 4;\n\n\t\trt = data.read_shift(2);\n\t\tif(rt == 0x0000) break; // META_EOF\n\n\t\tswitch(rt) {\n\t\t\tcase 0x020C: // 2.3.5.30 META_SETWINDOWEXT\n\t\t\t\textents[1] = data.read_shift(2);\n\t\t\t\textents[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020B: // 2.3.5.31 META_SETWINDOWORG\n\t\t\t\torigin[1] = data.read_shift(2);\n\t\t\t\torigin[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\t\t}\n\t\tdata.l = end;\n\t}\n\n\treturn [extents[0] - origin[0], extents[1] - origin[1]];\n};","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nvar WMF = require(\"../js/\");\nmodule.exports = WMF;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/dist/wmf.node.js b/dist/wmf.node.js new file mode 100644 index 0000000..8a27fec --- /dev/null +++ b/dist/wmf.node.js @@ -0,0 +1,2 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +module.exports=function(r){var i={};function a(t){if(i[t])return i[t].exports;var e=i[t]={i:t,l:!1,exports:{}};return r[t].call(e.exports,e,e.exports,a),e.l=!0,e.exports}return a.m=r,a.c=i,a.d=function(t,e,r){a.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:r})},a.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},a.t=function(e,t){if(1&t&&(e=a(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(a.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var i in e)a.d(r,i,function(t){return e[t]}.bind(null,i));return r},a.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return a.d(e,"a",e),e},a.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},a.p="",a(a.s=2)}([function(t,s,e){"use strict";Object.defineProperty(s,"__esModule",{value:!0});var r,c=!("undefined"==typeof Buffer||"undefined"==typeof process||void 0===process.versions||!process.versions.node);if(s.has_buf=c,s.Buffer_from=r,"undefined"!=typeof Buffer){var i=!Buffer.from;if(!i)try{Buffer.from("foo","utf8")}catch(t){i=!0}s.Buffer_from=r=i?function(t,e){return e?new Buffer(t,e):new Buffer(t)}:Buffer.from.bind(Buffer),Buffer.alloc||(Buffer.alloc=function(t){return new Buffer(t)}),Buffer.allocUnsafe||(Buffer.allocUnsafe=function(t){return new Buffer(t)})}s.new_raw_buf=function(t){return c?Buffer.alloc(t):new Array(t)},s.new_unsafe_buf=function(t){return c?Buffer.allocUnsafe(t):new Array(t)},s._chr=function(t){return String.fromCharCode(t)},s.chr0=/\u0000/g,s.chr1=/[\u0001-\u0006]/g;var u,a,l=function(t,e){return t[e]},d=function(t,e){return 256*t[e+1]+t[e]},_=function(t,e){var r=256*t[e+1]+t[e];return r<32768?r:-1*(65535-r+1)},p=function(t,e){return t[e+3]*(1<<24)+(t[e+2]<<16)+(t[e+1]<<8)+t[e]},E=function(t,e){return t[e+3]<<24|t[e+2]<<16|t[e+1]<<8|t[e]},g=function(t,e){return t[e]<<24|t[e+1]<<16|t[e+2]<<8|t[e+3]},b=function(t,e,r){for(var i=[],a=e;a>>7),i=((127&t[e+7])<<4)+(t[e+6]>>>4&15),a=15&t[e+6],s=5;0<=s;--s)a=256*a+t[e+s];return 2047==i?0==a?1/0*r:NaN:(0==i?i=-1022:(i-=1023,a+=Math.pow(2,52)),r*Math.pow(2,i-52)*a)}(t,e)}var m=y,k=B;function O(t,e){var r,i,a,s,n,f="",h=0,o=[];switch(e){case"dbcs":if(n=this.l,c&&Buffer.isBuffer(this))f=this.slice(this.l,this.l+2*t).toString("utf16le");else for(s=0;s>>8&255;l=2*e.length}else if("sbcs"===r){for(e=e.replace(/[^\x00-\x7F]/g,"_"),d=0;d!=e.length;++d)this[this.l+d]=255&e.charCodeAt(d);l=e.length}else{if("hex"===r){for(;d>8}for(;this.l<_;)this[this.l++]=0;return this}if("number"==typeof e)switch(t){case 1:l=1,this[this.l]=255&e;break;case 2:l=2,this[this.l]=255&e,e>>>=8,this[this.l+1]=255&e;break;case 3:l=3,this[this.l]=255&e,e>>>=8,this[this.l+1]=255&e,e>>>=8,this[this.l+2]=255&e;break;case 4:l=4,f=e,h=(n=this).l,n[h]=255&f,n[h+1]=f>>>8&255,n[h+2]=f>>>16&255,n[h+3]=f>>>24&255;break;case 8:if(l=8,"f"===r){!function(t,e,r){var i=(e<0||1/e==-1/0?1:0)<<7,a=0,s=0,n=i?-e:e;isFinite(n)?0==n?a=s=0:(a=Math.floor(Math.log(n)/Math.LN2),s=n*Math.pow(2,52-a),a<=-1023&&(!isFinite(s)||s>4|i}(this,e,this.l);break}case 16:break;case-4:l=4,a=e,s=(i=this).l,i[s]=255&a,i[s+1]=a>>8&255,i[s+2]=a>>16&255,i[s+3]=a>>24&255}}return this.l+=l,this}function I(t,e){var r=v(this,this.l,t.length>>1);if(r!==t)throw new Error(e+"Expected "+t+" saw "+r);this.l+=t.length>>1}s.WriteShift=x,s.CheckField=I;function F(t,e){t.l=e,t.read_shift=O,t.chk=I,t.write_shift=x}s.prep_blob=F;s.new_buf=function(t){var e=s.new_raw_buf(t);return F(e,0),e};var N=function(t){for(var e=!0,r=0;r>8),w=t.read_shift(4),A=t.read_shift(2,"i"),y=t.read_shift(2,"i");C||(t.l+=2);var B=t.read_shift(2,"i"),m=t.read_shift(2,"i"),k=t.read_shift(2,"i"),O={t:"cpy",src:[[y,m],[A,B]],dst:[t.read_shift(2,"i"),k],rop:w,s:Object.assign({},u)};if(C){var x=tt(t.slice(t.l,d));O.data=x}e.push(O);break;case 2881:C=r!=3+(i>>8),w=t.read_shift(4);var I=t.read_shift(2,"i"),F=t.read_shift(2,"i");A=t.read_shift(2,"i"),y=t.read_shift(2,"i");C||(t.l+=2);var N=t.read_shift(2,"i"),R=t.read_shift(2,"i");k=t.read_shift(2,"i"),O={t:"str",src:[[y,F],[A,I]],dst:[[t.read_shift(2,"i"),R],[k,N]],rop:w,s:Object.assign({},u)};if(C){x=tt(t.slice(t.l,d));O.data=x}e.push(O);break;case 2610:var L=t.read_shift(2),P=t.read_shift(2),D=t.read_shift(2);6&t.read_shift(2)&&(t.l+=8);var j=t.read_shift(D,"cpstr");t.l,e.push({t:"text",v:j,p:[P,L],s:Object.assign({},u)});break;case 805:case 804:for(var H=t.read_shift(2),W=[],U=0;U>8&255).toString(16).padStart(2,"0")+(t>>16&255).toString(16).padStart(2,"0")},n.set_ctx_state=function(t,e){if(e){var r="";if(e.Font){e.Font.Italic&&(r+=" italic"),e.Font.Weight&&(r+=" "+(700==e.Font.Weight?"bold":400==e.Font.Weight?"":e.Font.Weight)),e.Font.Height<0?r+=" "+-e.Font.Height+"px":0 `#${(clr & 0xFF).toString(16).padStart(2, \"0\")}${((clr>>8) & 0xFF).toString(16).padStart(2, \"0\")}${((clr>>16) & 0xFF).toString(16).padStart(2, \"0\")}`\n\nexport const set_ctx_state = (ctx: CanvasRenderingContext2D, state: PlaybackDeviceContextState): void => {\n\tif(!state) return;\n\tlet font = \"\";\n\tif(state.Font) {\n\t\tif(state.Font.Italic) font += \" italic\";\n\t\tif(state.Font.Weight) font += ` ${state.Font.Weight == 700 ? \"bold\" : state.Font.Weight == 400 ? \"\" : state.Font.Weight}`;\n\t\tif(state.Font.Height < 0) font += ` ${-state.Font.Height}px`;\n\t\telse if(state.Font.Height > 0) font += ` ${state.Font.Height}px`;\n\t\tlet name = state.Font.Name || \"\";\n\t\tif(name == \"System\") name = \"Calibri\"; // TODO: default sys font is Segoe UI\n\t\tif(name) font += ` '${name}', sans-serif`;\n\t\tctx.font = font.trim();\n\t}\n};\n\n// TODO: DIB BIT ORDER?\nexport const render_actions_to_context = (out: Action[], ctx: CanvasRenderingContext2D) => {\n\tout.forEach(act => {\n\t\tctx.save();\n\t\tset_ctx_state(ctx, act.s);\n\t\tswitch(act.t) {\n\t\t\tcase \"poly\":\n\t\t\t\tctx.beginPath();\n\t\t\t\tctx.moveTo(act.p[0][0], act.p[0][1]);\n\t\t\t\tact.p.slice(1).forEach(([x,y]) => {\n\t\t\t\t\tctx.lineTo(x, y);\n\t\t\t\t});\n\t\t\t\tif(act.g) ctx.closePath();\n\t\t\t\tctx.stroke();\n\t\t\t\tbreak;\n\t\t\tcase \"text\":\n\t\t\t\tif(act.s && act.s.TextColor) ctx.fillStyle = css_color(act.s.TextColor);\n\t\t\t\tif(act.s.Font.Angle != 0) {\n\t\t\t\t\tctx.translate(act.p[0], act.p[1]);\n\t\t\t\t\tctx.rotate(-act.s.Font.Angle * Math.PI / 180);\n\t\t\t\t\tctx.fillText(act.v, 0, 0);\n\t\t\t\t\tctx.translate(-act.p[0], -act.p[1]);\n\t\t\t\t}\n\t\t\t\telse ctx.fillText(act.v, act.p[0], act.p[1]);\n\t\t\t\tbreak;\n\t\t\tcase \"cpy\": {\n\t\t\t\t// TODO: base on ROP\n\t\t\t\tconst idata = ctx.getImageData(act.src[0][0], act.src[1][0], act.src[0][1], act.src[1][1]);\n\t\t\t\tctx.putImageData(idata, act.dst[0], act.dst[1]);\n\t\t\t} break;\n\t\t\tcase \"str\": {\n\t\t\t\tif(act.data && act.data.BitCount == 24 && act.data.ImageData) {\n\t\t\t\t\tconst _o = new Uint8ClampedArray(act.data.Width * act.data.Height * 4);\n\t\t\t\t\tfor(let i = 0; i < act.data.Width * act.data.Height; ++i) {\n\t\t\t\t\t\tconst j = (i % act.data.Width) + act.data.Width * (act.data.Height - 1 - Math.floor(i / act.data.Width));\n\t\t\t\t\t\t_o[4*i] = act.data.ImageData[3*j+2];\n\t\t\t\t\t\t_o[4*i+1] = act.data.ImageData[3*j+1];\n\t\t\t\t\t\t_o[4*i+2] = act.data.ImageData[3*j];\n\t\t\t\t\t\t_o[4*i+3] = 255;\n\t\t\t\t\t}\n\t\t\t\t\tconst idata = new ImageData(_o, act.data.Width, act.data.Height);\n\t\t\t\t\tctx.putImageData(idata, act.dst[0][0], act.dst[1][0]);\n\t\t\t\t}\n\t\t\t\t// TODO: ROP et al\n\t\t\t}\n\t\t}\n\t\tctx.restore();\n\t});\n}\n\nexport const render_canvas = (out: Action[], image: HTMLCanvasElement): void => {\n\tlet ctx: CanvasRenderingContext2D;\n\n\t/* find first action with window info */\n\tout.forEach(act => {\n\t\tif(ctx) return;\n\t\tif(!act.s) return;\n\t\tif(!act.s.Extent || !act.s.Origin) return;\n\t\timage.width = act.s.Extent[0] - act.s.Origin[0];\n\t\timage.height = act.s.Extent[1] - act.s.Origin[1];\n\t\tctx = image.getContext('2d');\n\t\tctx.save();\n\t\tctx.fillStyle = 'rgb(255,255,255)';\n\t\tctx.fillRect(0, 0, act.s.Extent[0] - act.s.Origin[0], act.s.Extent[1] - act.s.Origin[1])\n\t\tctx.restore();\n\t});\n\n\tif(!ctx) ctx = image.getContext('2d');\n\trender_actions_to_context(out, ctx);\n}\n\nexport const draw_canvas = (data: Buffer | Uint8Array | ArrayBuffer, image: HTMLCanvasElement): void => {\n\tif(data instanceof ArrayBuffer) return draw_canvas(new Uint8Array(data), image);\n\tprep_blob((data as any), 0);\n\tconst out: Action[] = get_actions_prepped_bytes(data as PreppedBytes);\n\treturn render_canvas(out, image);\n};\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nimport { PreppedBytes, prep_blob } from './util';\nimport { Action, get_actions_prepped_bytes, image_size_prepped_bytes } from './wmf'\n\nexport { draw_canvas, render_canvas } from './canvas';\n\nexport const get_actions = (data: Buffer | Uint8Array | ArrayBuffer): Action[] => {\n\tif(data instanceof ArrayBuffer) return get_actions(new Uint8Array(data));\n\tprep_blob((data as any), 0);\n\treturn get_actions_prepped_bytes(data as PreppedBytes);\n}\n\nexport const image_size = (data: Buffer | Uint8Array | ArrayBuffer): [number, number] => {\n\tif(data instanceof ArrayBuffer) return image_size(new Uint8Array(data));\n\tprep_blob((data as any), 0);\n\treturn image_size_prepped_bytes(data as PreppedBytes);\n}\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nexport type RawBytes = Buffer | number[];\n\nexport type PreppedBytes = RawBytes & {\n l: number;\n read_shift(size: 1): number;\n read_shift(size: 2): number;\n read_shift(size: 2, t: \"i\"): number;\n read_shift(size: 4): number;\n read_shift(size: 4, t: \"i\"): number;\n read_shift(size: 8, t: \"f\"): number;\n read_shift(size: number, t: \"cstr\"): string;\n read_shift(size: number, t: \"cpstr\"): string;\n read_shift(size: number, t: \"_wstr\"): string;\n read_shift(size: number, t?: string): number|string;\n chk(hexstr: string, fld: string): void;\n write_shift(t: number, val: string|number, f?: string): void;\n};\n\n// ---\n\nconst has_buf = !!(typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node);\n\nlet Buffer_from: typeof Buffer.from;\n\nif(typeof Buffer !== 'undefined') {\n let nbfs = !Buffer.from;\n\tif(!nbfs) try {\n Buffer.from(\"foo\", \"utf8\");\n } catch(e) { nbfs = true; }\n\tBuffer_from = nbfs ? ((buf, enc?: string): Buffer => (enc) ? new Buffer(buf, (enc as BufferEncoding)) : new Buffer(buf)) : Buffer.from.bind(Buffer);\n\tif(!Buffer.alloc) Buffer.alloc = function(n: number): Buffer { return new Buffer(n); };\n\tif(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n: number): Buffer { return new Buffer(n); };\n}\n\nexport { Buffer_from, has_buf };\n\nexport const new_raw_buf = (len: number): Buffer|number[] => has_buf ? Buffer.alloc(len) : new Array(len);\n\nexport const new_unsafe_buf = (len: number): Buffer|number[] => has_buf ? Buffer.allocUnsafe(len) : new Array(len);\n\nexport const _chr = (c: number): string => String.fromCharCode(c);\n\nexport const chr0 = /\\u0000/g; // eslint-disable-line no-control-regex\nexport const chr1 = /[\\u0001-\\u0006]/g; // eslint-disable-line no-control-regex\n\n// ---\n\nconst read_double_le = (b: RawBytes, idx: number): number => {\n\tconst s = 1 - 2 * (b[idx + 7] >>> 7);\n\tlet e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f);\n\tlet m = (b[idx+6]&0x0f);\n\tfor(let i = 5; i >= 0; --i) m = m * 256 + b[idx + i];\n\tif(e == 0x7ff) return m == 0 ? (s * Infinity) : NaN;\n\tif(e == 0) e = -1022;\n\telse { e -= 1023; m += Math.pow(2,52); }\n\treturn s * Math.pow(2, e - 52) * m;\n};\n\nconst write_double_le = (b: RawBytes, v: number, idx: number): void => {\n\tconst bs = ((((v < 0) || (1/v == -Infinity)) ? 1 : 0) << 7);\n\tlet e = 0, m = 0;\n\tconst av = bs ? (-v) : v;\n\tif(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; }\n\telse if(av == 0) e = m = 0;\n\telse {\n\t\te = Math.floor(Math.log(av) / Math.LN2);\n\t\tm = av * Math.pow(2, 52 - e);\n\t\tif((e <= -1023) && (!isFinite(m) || (m < Math.pow(2,52)))) { e = -1022; }\n\t\telse { m -= Math.pow(2,52); e+=1023; }\n\t}\n\tfor(let i = 0; i <= 5; ++i, m/=256) b[idx + i] = m & 0xff;\n\tb[idx + 6] = ((e & 0x0f) << 4) | (m & 0xf);\n\tb[idx + 7] = (e >> 4) | bs;\n};\n\nlet __toBuffer = (bufs/*:Array >*/): RawBytes => {\n\tconst x: number[] =[];\n\tfor(let i=0; i b[idx];\nconst __readUInt16LE = (b: RawBytes, idx: number): number => (b[idx+1]*(1<<8))+b[idx];\nconst __readInt16LE = (b: RawBytes, idx: number): number => { const u = (b[idx+1]*(1<<8))+b[idx]; return (u < 0x8000) ? u : ((0xffff - u + 1) * -1); };\nconst __readUInt32LE = (b: RawBytes, idx: number): number => b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx];\nconst __readInt32LE = (b: RawBytes, idx: number): number => (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx];\nconst __readInt32BE = (b: RawBytes, idx: number): number => (b[idx]<<24)|(b[idx+1]<<16)|(b[idx+2]<<8)|b[idx+3];\n\nlet __utf16le = (b: RawBytes, s: number, e: number): string => {\n\tconst ss: string[] = [];\n\tfor(let i=s; i 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___lpstr = __lpstr;\nlet __cpstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___cpstr = __cpstr;\nlet __lpwstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : \"\";};\nconst ___lpwstr = __lpwstr;\nlet __lpp4, ___lpp4;\n__lpp4 = ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : \"\";};\nconst ___8lpp4 = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : \"\";};\nlet __8lpp4 = ___8lpp4;\nconst ___double = (b/*:RawBytes|CFBlob*/, idx: number): number => read_double_le(b, idx);\nlet __double = ___double;\n\nif(has_buf) {\n\t__utf16le = (b/*:RawBytes|CFBlob*/,s: number,e: number): string => (!Buffer.isBuffer(b)) ? ___utf16le(b,s,e) : b.toString('utf16le',s,e).replace(chr0,'');\n\t__hexlify = (b/*:RawBytes|CFBlob*/,s: number,l: number): string => Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l);\n\t__lpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : \"\";};\n\t__cpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___cpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : \"\";};\n\t__lpwstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); const len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);};\n\t__lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);};\n\t__8lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);};\n\t__utf8 = (b/*:RawBytes|CFBlob*/, s: number, e: number): string => (Buffer.isBuffer(b)) ? b.toString('utf8',s,e) : ___utf8(b,s,e);\n\t__toBuffer = (bufs): RawBytes => (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs);\n\t__double = (b/*:RawBytes|CFBlob*/, i: number): number => (Buffer.isBuffer(b)) ? b.readDoubleLE(i) : ___double(b,i);\n}\n\nfunction ReadShift(size: 1): number;\nfunction ReadShift(size: 2): number;\nfunction ReadShift(size: 2, t: \"i\"): number;\nfunction ReadShift(size: 4): number;\nfunction ReadShift(size: 4, t: \"i\"): number;\nfunction ReadShift(size: 8, t: \"f\"): number;\nfunction ReadShift(size: number, t: \"cstr\"): string;\nfunction ReadShift(size: number, t: \"cpstr\"): string;\nfunction ReadShift(size: number, t: \"_wstr\"): string;\nfunction ReadShift(size: number, t?: string): number|string {\n\tlet o=\"\", oI = 0, oR, w, vv, i, loc;\n\tconst oo = [];\n\tswitch(t) {\n\t\tcase 'dbcs':\n\t\t\tloc = this.l;\n\t\t\tif(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString(\"utf16le\");\n\t\t\telse for(i = 0; i < size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; }\n\t\t\tsize *= 2;\n\t\t\tbreak;\n\n\t\tcase 'utf8': o = __utf8(this, this.l, this.l + size); break;\n\t\tcase 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break;\n\n\t\tcase 'wstr':\n\t\t\treturn ReadShift.call(this, size, 'dbcs');\n\n\t\t/* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */\n\t\tcase 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;\n\t\tcase 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break;\n\t\t/* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */\n\t\tcase 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break;\n\t\t/* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */\n\t\tcase 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break;\n\t\t/* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */\n\t\tcase '8lpp4': size = 4 + __readUInt32LE(this, this.l); o = __8lpp4(this, this.l); if(size & 0x03) size += 4 - (size & 0x03); break;\n\n\t\tcase 'cstr': size = 0; o = \"\";\n\t\t\twhile((w=__readUInt8(this, this.l + size++))!==0) oo.push(String.fromCharCode(w));\n\t\t\to = oo.join(\"\"); break;\n\t\tcase '_wstr': size = 0; o = \"\";\n\t\t\twhile((w=__readUInt16LE(this,this.l +size))!==0){oo.push(String.fromCharCode(w));size+=2;}\n\t\t\tsize+=2; o = oo.join(\"\"); break;\n\n\t\t/* sbcs and dbcs support continue records in the SST way TODO codepages */\n\t\tcase 'dbcs-cont': o = \"\"; loc = this.l;\n\t\t\tfor(i = 0; i < size; ++i) {\n\t\t\t\tif(this.lens && this.lens.indexOf(loc) !== -1) {\n\t\t\t\t\tw = __readUInt8(this, loc);\n\t\t\t\t\tthis.l = loc + 1;\n\t\t\t\t\tvv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');\n\t\t\t\t\treturn oo.join(\"\") + vv;\n\t\t\t\t}\n\t\t\t\too.push(String.fromCharCode(__readUInt16LE(this, loc)));\n\t\t\t\tloc+=2;\n\t\t\t} o = oo.join(\"\"); size *= 2; break;\n\n\t\tcase 'cpstr':\n\t\t/* falls through */\n\t\tcase 'sbcs-cont': o = \"\"; loc = this.l;\n\t\t\tfor(i = 0; i != size; ++i) {\n\t\t\t\tif(this.lens && this.lens.indexOf(loc) !== -1) {\n\t\t\t\t\tw = __readUInt8(this, loc);\n\t\t\t\t\tthis.l = loc + 1;\n\t\t\t\t\tvv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont');\n\t\t\t\t\treturn oo.join(\"\") + vv;\n\t\t\t\t}\n\t\t\t\too.push(String.fromCharCode(__readUInt8(this, loc)));\n\t\t\t\tloc+=1;\n\t\t\t} o = oo.join(\"\"); break;\n\n\t\tdefault:\n\tswitch(size) {\n\t\tcase 1: oI = __readUInt8(this, this.l); this.l++; return oI;\n\t\tcase 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI;\n\t\tcase 4: case -4:\n\t\t\tif(t === 'i' || ((this[this.l+3] & 0x80)===0)) { oI = ((size > 0) ? __readInt32LE : __readInt32BE)(this, this.l); this.l += 4; return oI; }\n\t\t\telse { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR;\n\t\tcase 8: case -8:\n\t\t\tif(t === 'f') {\n\t\t\t\tif(size == 8) oR = __double(this, this.l);\n\t\t\t\telse oR = __double([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]], 0);\n\t\t\t\tthis.l += 8; return oR;\n\t\t\t} else size = 8;\n\t\t/* falls through */\n\t\tcase 16: o = __hexlify(this, this.l, size); break;\n\t}}\n\tthis.l+=size; return o;\n}\n\nconst __writeUInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); };\nconst __writeInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); };\nconst __writeUInt16LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); };\n\nfunction WriteShift(t: number, val: string|number, f?: string): void {\n\tlet size = 0, i = 0;\n\tif(f === 'dbcs') {\n\t\tif(typeof val !== 'string') throw new Error(\"expected string\");\n\t\tfor(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i);\n\t\tsize = 2 * val.length;\n\t} else if(f === 'sbcs') {\n\t\t{\n\t\t\tval = (val as string).replace(/[^\\x00-\\x7F]/g, \"_\"); // eslint-disable-line no-control-regex\n\t\t\tfor(i = 0; i != val.length; ++i) this[this.l + i] = (val.charCodeAt(i) & 0xFF);\n\t\t}\n\t\tsize = val.length;\n\t} else if(f === 'hex') {\n\t\tfor(; i < t; ++i) {\n\t\t\tthis[this.l++] = (parseInt((val as string).slice(2*i, 2*i+2), 16)||0);\n\t\t} return this;\n\t} else if(f === 'utf16le') {\n\t\t\t/*:: if(typeof val !== \"string\") throw new Error(\"unreachable\"); */\n\t\t\tconst end: number = Math.min(this.l + t, this.length);\n\t\t\tfor(i = 0; i < Math.min((val as string).length, t); ++i) {\n\t\t\t\tconst cc = (val as string).charCodeAt(i);\n\t\t\t\tthis[this.l++] = (cc & 0xff);\n\t\t\t\tthis[this.l++] = (cc >> 8);\n\t\t\t}\n\t\t\twhile(this.l < end) this[this.l++] = 0;\n\t\t\treturn this;\n\t} else if(typeof val === 'number') switch(t) {\n\t\tcase 1: size = 1; this[this.l] = val&0xFF; break;\n\t\tcase 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break;\n\t\tcase 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break;\n\t\tcase 4: size = 4; __writeUInt32LE(this, val, this.l); break;\n\t\tcase 8: size = 8; if(f === 'f') { write_double_le(this, val, this.l); break; }\n\t\t/* falls through */\n\t\tcase 16: break;\n\t\tcase -4: size = 4; __writeInt32LE(this, val, this.l); break;\n\t}\n\tthis.l += size; return this;\n}\n\nfunction CheckField(hexstr: string, fld: string): void {\n\tconst m = __hexlify(this,this.l,hexstr.length>>1);\n\tif(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m);\n\tthis.l += hexstr.length>>1;\n}\n\nconst prep_blob = (blob: PreppedBytes, pos: number): void => {\n\tblob.l = pos;\n\tblob.read_shift = ReadShift;\n\tblob.chk = CheckField;\n\tblob.write_shift = WriteShift;\n};\n\nconst new_buf = (sz: number): PreppedBytes => {\n\tconst o = (new_raw_buf(sz) as PreppedBytes);\n\tprep_blob(o, 0);\n\treturn o;\n};\n\nexport { ReadShift, WriteShift, CheckField, prep_blob, new_buf, __utf16le };\n\n// ---\n\nconst __bconcat = function(bufs/*:Array*/): Buffer | Uint8Array | number[] {\n let is_all_arrays = true;\n for(let w = 0; w < bufs.length; ++w) if(!Array.isArray(bufs[w])) is_all_arrays = false;\n\tif(is_all_arrays) return [].concat(...bufs);\n\tlet maxlen = 0, i = 0;\n\tfor(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length;\n\tconst o = new Uint8Array(maxlen);\n\tfor(i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen);\n\treturn o;\n};\nlet bconcat = __bconcat;\n\nif(has_buf) bconcat = (bufs): Buffer | Uint8Array | number[] => Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat(...bufs);\n\nexport { bconcat };\n","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nimport { PreppedBytes, RawBytes, bconcat, prep_blob } from './util';\nimport { WMFRecords, WMFEscapes } from './Records';\n\nexport interface Brush {\n\t/** Style (MS-WMF 2.1.1.4) */\n\tStyle?: Number;\n\t/** Brush color RGB */\n\tColor?: number;\n\t/** Hatch Type (2.1.1.12 if brush is hatched) */\n\tHatch?: number;\n}\n\nexport interface Pen {\n\tStyle?: number;\n\tWidth?: number;\n\tColor?: number;\n}\n\nexport interface Font {\n\tName?: string;\n\tHeight?: number;\n\tItalic?: boolean;\n\tWeight?: number;\n\tAngle?: number;\n}\n\nexport interface PlaybackDeviceContextState {\n\t/** Mapping mode (MS-WMF 2.1.1.16) */\n\tMapMode?: number;\n\t/** Output window origin (X, Y) */\n\tOrigin?: [number, number];\n\t/** Output window extents (X, Y) */\n\tExtent?: [number, number];\n\t/** Background Mix Mode (MS-WMF 2.1.1.20) */\n\tBkMode?: number;\n\t/** Polygon fill mode (MS-WMF 2.1.1.25) */\n\tPolyFillMode?: number;\n\t/** Bitmap stretching mode (MS-WMF 2.1.1.30) */\n\tStretchMode?: number;\n\t/** Text alignment mode (MS-WMF 2.1.2.3 / 2.1.2.4) */\n\tTextAlignmentMode?: number;\n\t/** Text foreground color RGB */\n\tTextColor?: number;\n\t/** Brush */\n\tBrush?: Brush;\n\t/** Font */\n\tFont?: Font;\n\t/** Pen */\n\tPen?: Pen;\n\t/** Clipping Region (x,y) LT (x,y) RB */\n\tClipRect?: [[number, number], [number, number]];\n}\n\n/** [x, y] */\nexport type Point = [ number, number ];\n\nexport interface ActionCommon {\n\t/** State */\n\ts?: PlaybackDeviceContextState;\n}\n\n/** Draw Text */\nexport interface ActionText extends ActionCommon {\n\t/** Action Type */\n\tt: \"text\";\n\n\t/** Text */\n\tv: string;\n\n\t/** Origin */\n\tp?: Point;\n}\n\n/** Draw Polygon (shape with stroke/fill) / Polyline (stroke only) */\nexport interface ActionPoly extends ActionCommon {\n\t/** Action Type */\n\tt: \"poly\";\n\n\t/** Points */\n\tp: Point[];\n\n\t/** Polygon (true) or Polyline (false) */\n\tg: boolean;\n}\n\nexport interface ActionRaster {\n\t/** Raster Operaton 2.1.1.31 */\n\trop?: number;\n}\n\nexport interface ActionCpy extends ActionCommon, ActionRaster {\n\tt: \"cpy\";\n\n\t/** Source [[X, W], [Y, H]] */\n\tsrc: [[number, number], [number, number]];\n\n\tdst: Point;\n\n\tdata?: any;\n}\n\nexport interface ActionStr extends ActionCommon, ActionRaster {\n\tt: \"str\";\n\n\t/** Source [[X, W], [Y, H]] */\n\tsrc: [[number, number], [number, number]];\n\n\t/** Dest [[X, W], [Y, H]] */\n\tdst: [[number, number], [number, number]];\n\n\tdata?: any;\n}\n\nexport type Action = ActionText | ActionPoly | ActionCpy | ActionStr;\n\nconst parse_emf = (data: PreppedBytes): void => {\n\t//try { require(\"fs\").writeFileSync(\"out.emf\", data); } catch(e) {}\n}\n\n/* 2.2.2.9 */\nconst parse_dib = (data: PreppedBytes) => {\n\tif(data.length == 0) return null;\n\tprep_blob(data, 0);\n\n\t/* DIBHeaderInfo */\n\tconst HeaderSize = data.read_shift(4);\n\tlet Width = 0, Height = 0, Planes = 0, BitCount = 0;\n\tlet Compression = 0, ImageSize = 0, XPelsPerMeter = 0, YPelsPerMeter = 0, ColorUsed = 0, ColorImportant = 0;\n\tif(HeaderSize == 0x0C) {\n\t\tWidth = data.read_shift(2);\n\t\tHeight = data.read_shift(2);\n\t} else {\n\t\tWidth = data.read_shift(4, 'i');\n\t\tHeight = data.read_shift(4, 'i');\n\t}\n\tPlanes = data.read_shift(2);\n\tBitCount = data.read_shift(2);\n\n\tconst out: object = {\n\t\tWidth,\n\t\tHeight,\n\t\tBitCount,\n\t};\n\n\tif(HeaderSize != 0x0C) {\n\t\tCompression = data.read_shift(4);\n\t\tImageSize = data.read_shift(4);\n\t\tXPelsPerMeter = data.read_shift(4, 'i');\n\t\tYPelsPerMeter = data.read_shift(4, 'i');\n\t\tColorUsed = data.read_shift(4);\n\t\tColorImportant = data.read_shift(4);\n\t\tout[\"Compression\"] = Compression;\n\t\tif(BitCount == 24 && ImageSize > Height * 3 * Width) Width = out[\"Width\"] = ImageSize / (Height * 3);\n\t}\n\n\t/* Colors */\n\t/* BitmapBuffer */\n\tif(ImageSize == data.length - data.l) {\n\t\tout[\"ImageData\"] = data.slice(data.l, data.length);\n\t\tprep_blob(out[\"ImageData\"], 0);\n\t}\n\treturn out;\n}\n\nconst add_to_objects = (objects: PlaybackDeviceContextState[], obj: PlaybackDeviceContextState): void => {\n\tlet found = false;\n\tfor(var i = 0; i < objects.length; ++i) if(!objects[i]) { objects[i] = obj; found = true; }\n\tif(!found) objects.push(obj);\n}\n\nexport const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => {\n\tconst out: Action[] = [];\n\n\t/* 2.3.22 META_HEADER */\n\t// Type (2 bytes) must be 1 or 2\n\tlet h = data.read_shift(2);\n\tif(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`;\n\t// HeaderSize expected to be 9\n\tif((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`;\n\t// Version (2 bytes) 1 or 3\n\th = data.read_shift(2);\n\tif(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`;\n\t// SizeLow\n\t// SizeHigh\n\t// #Objects\n\t// MaxRecord\n\t// NumberOfMembers\n\tdata.l = 18;\n\n\tlet rt = 0;\n\n\t/* used for EMF */\n\tlet escapecnt = 0;\n\tlet CommentRecordCount = 0;\n\tlet RemainingBytes = 0;\n\tlet EnhancedMetafileDataSize = 0;\n\tlet bufs: RawBytes[] = [];\n\n\tlet objects: PlaybackDeviceContextState[] = [];\n\tlet states: PlaybackDeviceContextState[] = [];\n\tlet state: PlaybackDeviceContextState = {};\n\tlet sidx = -1;\n\n\twhile(data.l < data.length) {\n\t\th = data.read_shift(4);\n\t\tconst end = data.l + h*2 - 4;\n\n\t\trt = data.read_shift(2);\n\t\tlet Record = WMFRecords[rt];\n\t\tif(rt == 0x0000) break; // META_EOF\n\n\t\tswitch(rt) {\n\t\t\tcase 0x0626: { // META_ESCAPE\n\t\t\t\tconst EscapeFunction = data.read_shift(2);\n\t\t\t\tconst Escape = WMFEscapes[EscapeFunction];\n\t\t\t\t//console.log(\"::\", Escape);\n\t\t\t\t/* 2.3.6 */\n\t\t\t\tswitch(EscapeFunction) {\n\t\t\t\t\tcase 0x000F: { // META_ESCAPE_ENHANCED_METAFILE\n\t\t\t\t\t\tconst ByteCount = data.read_shift(2);\n\t\t\t\t\t\tlet tmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x43464D57) throw `Escape: Comment ID 0x${tmp.toString(16)} != 0x43464D57`;\n\t\t\t\t\t\ttmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x00000001) throw `Escape: Comment Type 0x${tmp.toString(16)} != 0x00000001`;\n\t\t\t\t\t\ttmp = data.read_shift(4);\n\t\t\t\t\t\tif(tmp != 0x00010000) throw `Escape: Version 0x${tmp.toString(16)} != 0x00010000`;\n\n\t\t\t\t\t\tconst Checksum = data.read_shift(2);\n\n\t\t\t\t\t\tdata.l += 4; // Flags\n\t\t\t\t\t\tif(escapecnt == 0) {\n\t\t\t\t\t\t\tCommentRecordCount = data.read_shift(4); // total number of records\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst _CommentRecordCount = data.read_shift(4);\n\t\t\t\t\t\t\tif(_CommentRecordCount != CommentRecordCount) throw `Escape: CommentRecordCount ${_CommentRecordCount} != ${CommentRecordCount}`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tconst CurrentRecordSize = data.read_shift(4); // size of this record\n\t\t\t\t\t\tconst _RemainingBytes = data.read_shift(4);\n\t\t\t\t\t\tif(escapecnt > 0 && CurrentRecordSize + _RemainingBytes != RemainingBytes) throw `Escape: ${RemainingBytes} != ${CurrentRecordSize} + ${_RemainingBytes}`;\n\t\t\t\t\t\tRemainingBytes = _RemainingBytes;\n\t\t\t\t\t\tconst _EnhancedMetafileDataSize = data.read_shift(4);\n\t\t\t\t\t\tif(escapecnt == 0) {\n\t\t\t\t\t\t\tif(_EnhancedMetafileDataSize != CurrentRecordSize + _RemainingBytes) throw `Escape: ${_EnhancedMetafileDataSize} != ${CurrentRecordSize} + ${_RemainingBytes}`;\n\t\t\t\t\t\t\tEnhancedMetafileDataSize = _EnhancedMetafileDataSize;\n\t\t\t\t\t\t} else if(EnhancedMetafileDataSize != _EnhancedMetafileDataSize) throw `Escape: ${EnhancedMetafileDataSize} != ${_EnhancedMetafileDataSize}`;\n\n\t\t\t\t\t\tif(ByteCount != (end - data.l) + 34) throw `Escape: Sizes ${ByteCount} != ${end - data.l} + 34`\n\t\t\t\t\t\tif(end - data.l != CurrentRecordSize) throw `Escape: CRSize ${CurrentRecordSize} != ${end - data.l}`;\n\t\t\t\t\t\tbufs.push(data.slice(data.l, end));\n\t\t\t\t\t\t++escapecnt;\n\t\t\t\t\t\tif(escapecnt == CommentRecordCount) {\n\t\t\t\t\t\t\tconst prepped: PreppedBytes = bconcat(bufs) as PreppedBytes;\n\t\t\t\t\t\t\tprep_blob(prepped, 0);\n\t\t\t\t\t\t\tparse_emf(prepped);\n\t\t\t\t\t\t}\n\t\t\t\t\t} break;\n\t\t\t\t\tdefault: throw `Escape: Unrecognized META_ESCAPE Type 0x${EscapeFunction.toString(16)}`;\n\t\t\t\t}\n\t\t\t} break;\n\n\t\t\t// #region 2.3.1 Bitmap Record Types\n\n\t\t\tcase 0x0940: { // 2.3.1.2 META_DIBBITBLT\n\t\t\t\tconst has_bitmap = h != (rt>>8)+3;\n\t\t\t\tconst RasterOperation = data.read_shift(4);\n\t\t\t\tconst YSrc = data.read_shift(2, \"i\");\n\t\t\t\tconst XSrc = data.read_shift(2, \"i\");\n\t\t\t\tif(!has_bitmap) data.l += 2;\n\t\t\t\tconst Height = data.read_shift(2, \"i\");\n\t\t\t\tconst Width = data.read_shift(2, \"i\");\n\t\t\t\tconst YDest = data.read_shift(2, \"i\");\n\t\t\t\tconst XDest = data.read_shift(2, \"i\");\n\t\t\t\tconst res: ActionCpy = {\n\t\t\t\t\tt: \"cpy\",\n\t\t\t\t\tsrc: [[XSrc, Width], [YSrc, Height]],\n\t\t\t\t\tdst: [XDest, YDest],\n\t\t\t\t\trop: RasterOperation,\n\t\t\t\t\ts: Object.assign({}, state)\n\t\t\t\t};\n\t\t\t\tif(has_bitmap) {\n\t\t\t\t\tconst DIB = parse_dib(data.slice(data.l, end) as PreppedBytes);\n\t\t\t\t\tres.data = DIB;\n\t\t\t\t}\n\t\t\t\tout.push(res);\n\t\t\t} break;\n\n\t\t\tcase 0x0B41: { // 2.3.1.3 META_DIBSTRETCHBLT\n\t\t\t\tconst has_bitmap = h != (rt>>8)+3;\n\t\t\t\tconst RasterOperation = data.read_shift(4);\n\t\t\t\tconst SrcHeight = data.read_shift(2, \"i\");\n\t\t\t\tconst SrcWidth = data.read_shift(2, \"i\");\n\t\t\t\tconst YSrc = data.read_shift(2, \"i\");\n\t\t\t\tconst XSrc = data.read_shift(2, \"i\");\n\t\t\t\tif(!has_bitmap) data.l += 2;\n\t\t\t\tconst DestHeight = data.read_shift(2, \"i\");\n\t\t\t\tconst DestWidth = data.read_shift(2, \"i\");\n\t\t\t\tconst YDest = data.read_shift(2, \"i\");\n\t\t\t\tconst XDest = data.read_shift(2, \"i\");\n\t\t\t\tconst res: ActionStr = {\n\t\t\t\t\tt: \"str\",\n\t\t\t\t\tsrc: [[XSrc, SrcWidth], [YSrc, SrcHeight]],\n\t\t\t\t\tdst: [[XDest, DestWidth], [YDest, DestHeight]],\n\t\t\t\t\trop: RasterOperation,\n\t\t\t\t\ts: Object.assign({}, state)\n\t\t\t\t};\n\t\t\t\tif(has_bitmap) {\n\t\t\t\t\tconst DIB = parse_dib(data.slice(data.l, end) as PreppedBytes);\n\t\t\t\t\tres.data = DIB;\n\t\t\t\t}\n\t\t\t\tout.push(res);\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.3 Drawing Record Types\n\n\t\t\tcase 0x0A32: { // 2.3.3.5 META_EXTTEXTOUT\n\t\t\t\tconst Y = data.read_shift(2);\n\t\t\t\tconst X = data.read_shift(2);\n\t\t\t\tconst StringLength = data.read_shift(2);\n\t\t\t\tconst fwOpts = data.read_shift(2); // 2.1.2.2\n\t\t\t\tif(fwOpts & 0x06) {\n\t\t\t\t\tdata.l += 8; // Rectangle 2.2.2.18 (for clipping/opaquing)\n\t\t\t\t}\n\t\t\t\tconst str = data.read_shift(StringLength, 'cpstr');\n\t\t\t\tif(data.l < end){/* TODO: Dx */}\n\t\t\t\tout.push({t: \"text\", v: str, p: [X, Y], s: Object.assign({}, state)});\n\t\t\t\t/* TODO!! */\n\t\t\t} break;\n\n\t\t\tcase 0x0325: // 2.3.3.14 META_POLYLINE\n\t\t\tcase 0x0324: // 2.3.3.15 META_POLYGON\n\t\t\t{\n\t\t\t\tconst nPoints = data.read_shift(2);\n\t\t\t\tconst points: Array = [];\n\t\t\t\tfor(let i = 0; i < nPoints; ++i) points.push([data.read_shift(2), data.read_shift(2)])\n\t\t\t\tout.push({t: \"poly\", p: points, g: rt !== 0x0325, s: state});\n\t\t\t} break;\n\n\t\t\tcase 0x0538: { // 2.3.3.16 META_POLYPOLYGON\n\t\t\t\tconst nPolygons = data.read_shift(2);\n\t\t\t\tconst polys: Array > = [];\n\t\t\t\tconst szs: number[] = [];\n\t\t\t\t/* 2.2.2.17 PolyPolygon */\n\t\t\t\tfor(let i = 0; i < nPolygons; ++i) szs[i] = data.read_shift(2);\n\t\t\t\tfor(let i = 0; i < szs.length; ++i) {\n\t\t\t\t\tpolys[i] = [];\n\t\t\t\t\tfor(let j = 0; j < szs[i]; ++j) polys[i].push([data.read_shift(2), data.read_shift(2)])\n\t\t\t\t\tout.push({t: \"poly\", p: polys[i], g: true, s: state});\n\t\t\t\t}\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.4 Object Record Types\n\n\t\t\tcase 0x02FC: { // 2.3.4.1 META_CREATEBRUSHINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Brush = {\n\t\t\t\t\tStyle: data.read_shift(2),\n\t\t\t\t\tColor: data.read_shift(4),\n\t\t\t\t\tHatch: data.read_shift(2)\n\t\t\t\t};\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x02FB: { // 2.3.4.2 META_CREATEFONTINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Font = {};\n\t\t\t\t/* 2.2.1.2 Font TODO!! */\n\t\t\t\tconst Height = data.read_shift(2, \"i\");\n\t\t\t\tconst Width = data.read_shift(2, \"i\");\n\t\t\t\tconst Escapement = data.read_shift(2, \"i\");\n\t\t\t\tconst Orientation = data.read_shift(2, \"i\");\n\t\t\t\tconst Weight = data.read_shift(2, \"i\");\n\t\t\t\tconst Italic = !!data.read_shift(1);\n\t\t\t\tconst Underline = !!data.read_shift(1);\n\t\t\t\tconst StrikeOut = !!data.read_shift(1);\n\t\t\t\tconst CharSet = data.read_shift(1);\n\t\t\t\tconst OutPrecision = data.read_shift(1);\n\t\t\t\tconst ClipPrecision = data.read_shift(1);\n\t\t\t\tconst Quality = data.read_shift(1);\n\t\t\t\tconst PitchAndFamily = data.read_shift(1);\n\t\t\t\tconst Facename = data.read_shift(32, \"cstr\");\n\t\t\t\tobj.Font.Name = Facename;\n\t\t\t\tobj.Font.Height = Height;\n\t\t\t\tobj.Font.Weight = Weight;\n\t\t\t\tobj.Font.Italic = Italic;\n\t\t\t\tobj.Font.Angle = Escapement / 10;\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x02FA: { // 2.3.4.5 META_CREATEPENINDIRECT\n\t\t\t\tconst obj: PlaybackDeviceContextState = {};\n\t\t\t\tobj.Pen = {\n\t\t\t\t\tStyle: data.read_shift(2),\n\t\t\t\t\tWidth: data.read_shift(4) & 0xFF,\n\t\t\t\t\tColor: data.read_shift(4)\n\t\t\t\t};\n\t\t\t\tadd_to_objects(objects, obj);\n\t\t\t} break;\n\n\t\t\tcase 0x01F0: { // 2.3.4.7 META_DELETEOBJECT\n\t\t\t\tconst ObjectIndex = data.read_shift(2);\n\t\t\t\t//console.log(\"DELETE\", ObjectIndex, objects[ObjectIndex]);\n\t\t\t\tobjects[ObjectIndex] = null;\n\t\t\t} break;\n\n\t\t\tcase 0x012C: { // 2.3.4.9 META_SELECTCLIPREGION\n\t\t\t\tconst Region = data.read_shift(2);\n\t\t\t\t//console.log(\"CLIPREGION\", Region, objects[Region]);\n\t\t\t\t//Object.assign(state, objects[Region]);\n\t\t\t} break;\n\n\t\t\tcase 0x012D: { // 2.3.4.10 META_SELECTOBJECT\n\t\t\t\tconst ObjectIndex = data.read_shift(2);\n\t\t\t\t//console.log(\"SELECT\", ObjectIndex, objects[ObjectIndex]);\n\t\t\t\tObject.assign(state, objects[ObjectIndex]);\n\t\t\t\t// TODO!!\n\t\t\t} break;\n\n\t\t\t// #endregion\n\n\t\t\t// #region 2.3.5 State Record Types\n\n\t\t\tcase 0x0416: // 2.3.5.3 META_INTERSECTCLIPRECT\n\t\t\t\tstate.ClipRect = [[0,0],[0,0]];\n\t\t\t\tstate.ClipRect[1][1] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[1][0] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[0][1] = data.read_shift(2);\n\t\t\t\tstate.ClipRect[0][0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0127: { // 2.3.5.10 META_RESTOREDC\n\t\t\t\tconst nSavedDC = data.read_shift(2, 'i');\n\t\t\t\tstate = states[sidx = (nSavedDC >= 0 ? nSavedDC : sidx + nSavedDC)];\n\t\t\t} break;\n\n\t\t\tcase 0x001E: // 2.3.5.11 META_SAVEDC\n\t\t\t\tstates.push(state);\n\t\t\t\tsidx = states.length - 1;\n\t\t\t\tstate = JSON.parse(JSON.stringify(state));\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0102: // 2.3.5.15 META_SETBKMODE\n\t\t\t\tstate.BkMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0103: // 2.3.5.17 META_SETMAPMODE\n\t\t\t\tstate.MapMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0106: // 2.3.5.20 META_SETPOLYFILLMODE\n\t\t\t\tstate.PolyFillMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0107: // 2.3.5.23 META_SETSTRETCHBLTMODE\n\t\t\t\tstate.StretchMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x012E: // 2.3.5.24 META_SETTEXTALIGN\n\t\t\t\tstate.TextAlignmentMode = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x0209: // 2.3.5.26 META_SETTEXTCOLOR\n\t\t\t\tstate.TextColor = data.read_shift(4);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020C: // 2.3.5.30 META_SETWINDOWEXT\n\t\t\t\tstate.Extent = [0, 0];\n\t\t\t\tstate.Extent[1] = data.read_shift(2);\n\t\t\t\tstate.Extent[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020B: // 2.3.5.31 META_SETWINDOWORG\n\t\t\t\tstate.Origin = [0, 0];\n\t\t\t\tstate.Origin[1] = data.read_shift(2);\n\t\t\t\tstate.Origin[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\t// #endregion\n\n\t\t\tdefault:\n\t\t\t\tif(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`;\n\t\t\t\tconsole.log(Record);\n\t\t}\n\t\tdata.l = end;\n\t\t//if(rt != 0x0626) console.log(Record);\n\t}\n\tif(rt !== 0) throw `Record: Last Record Type ${rt} is not EOF type`;\n\treturn out;\n}\n\nexport const image_size_prepped_bytes = (data: PreppedBytes): [number, number] => {\n\tconst origin: Point = [NaN, NaN], extents: Point = [NaN, NaN];\n\n\t/* 2.3.22 META_HEADER */\n\t// Type (2 bytes) must be 1 or 2\n\tlet h = data.read_shift(2);\n\tif(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`;\n\t// HeaderSize expected to be 9\n\tif((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`;\n\t// Version (2 bytes) 1 or 3\n\th = data.read_shift(2);\n\tif(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`;\n\tdata.l = 18;\n\n\tlet rt = 0;\n\n\twhile(data.l < data.length) {\n\t\th = data.read_shift(4);\n\t\tconst end = data.l + h*2 - 4;\n\n\t\trt = data.read_shift(2);\n\t\tif(rt == 0x0000) break; // META_EOF\n\n\t\tswitch(rt) {\n\t\t\tcase 0x020C: // 2.3.5.30 META_SETWINDOWEXT\n\t\t\t\textents[1] = data.read_shift(2);\n\t\t\t\textents[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\n\t\t\tcase 0x020B: // 2.3.5.31 META_SETWINDOWORG\n\t\t\t\torigin[1] = data.read_shift(2);\n\t\t\t\torigin[0] = data.read_shift(2);\n\t\t\t\tbreak;\n\t\t}\n\t\tdata.l = end;\n\t}\n\n\treturn [extents[0] - origin[0], extents[1] - origin[1]];\n};","/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */\nvar WMF = require(\"../js/\");\nmodule.exports = WMF;\n"],"sourceRoot":""} \ No newline at end of file diff --git a/index.html b/index.html new file mode 100644 index 0000000..195b7d0 --- /dev/null +++ b/index.html @@ -0,0 +1,94 @@ + + + + + + +wmf.js Live Demo + + + +
+SheetJS wmf.js Preview Live Demo
+
+Source Code Repo
+Issues?  Something look weird?  Click here and report an issue
+
Drop a WMF File here to Preview data
+ ... or click here to select a file + +

+
+
+ + + + diff --git a/js/Records.js b/js/Records.js new file mode 100644 index 0000000..fab86b7 --- /dev/null +++ b/js/Records.js @@ -0,0 +1,37 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/* 2.1.1.1 RecordType Enumeration */ +exports.WMFRecords = { + 0x0000: { n: "META_EOF" }, + 0x0626: { n: "META_ESCAPE" }, + 0x0940: { n: "META_DIBBITBLT" }, + 0x0B41: { n: "META_DIBSTRETCHBLT" }, + 0x0A32: { n: "META_EXTTEXTOUT" }, + 0x0325: { n: "META_POLYLINE" }, + 0x0324: { n: "META_POLYGON" }, + 0x0538: { n: "META_POLYPOLYGON" }, + 0x02FC: { n: "META_CREATEBRUSHINDIRECT" }, + 0x02FB: { n: "META_CREATEFONTINDIRECT" }, + 0x02FA: { n: "META_CREATEPENINDIRECT" }, + 0x01F0: { n: "META_DELETEOBJECT" }, + 0x012C: { n: "META_SELECTCLIPREGION" }, + 0x012D: { n: "META_SELECTOBJECT" }, + 0x0416: { n: "META_INTERSECTCLIPRECT" }, + 0x0035: { n: "META_REALIZEPALETTE" }, + 0x0127: { n: "META_RESTOREDC" }, + 0x001E: { n: "META_SAVEDC" }, + 0x0102: { n: "META_SETBKMODE" }, + 0x0103: { n: "META_SETMAPMODE" }, + 0x0037: { n: "META_SETPALENTRIES" }, + 0x0106: { n: "META_SETPOLYFILLMODE" }, + 0x0107: { n: "META_SETSTRETCHBLTMODE" }, + 0x012E: { n: "META_SETTEXTALIGN" }, + 0x0209: { n: "META_SETTEXTCOLOR" }, + 0x020C: { n: "META_SETWINDOWEXT" }, + 0x020B: { n: "META_SETWINDOWORG" }, + 0xFFFF: { n: "META_SHEETJS" } +}; +exports.WMFEscapes = { + 0x000F: { n: "META_ESCAPE_ENHANCED_METAFILE" } +}; +//# sourceMappingURL=Records.js.map \ No newline at end of file diff --git a/js/Records.js.map b/js/Records.js.map new file mode 100644 index 0000000..60f8703 --- /dev/null +++ b/js/Records.js.map @@ -0,0 +1 @@ +{"version":3,"file":"Records.js","sourceRoot":"","sources":["../src/Records.ts"],"names":[],"mappings":";;AASA,oCAAoC;AACvB,QAAA,UAAU,GAA+B;IACrD,MAAM,EAAE,EAAE,CAAC,EAAE,UAAU,EAAE;IACzB,MAAM,EAAE,EAAE,CAAC,EAAE,aAAa,EAAE;IAE5B,MAAM,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE;IAC/B,MAAM,EAAE,EAAE,CAAC,EAAE,oBAAoB,EAAE;IAEnC,MAAM,EAAE,EAAE,CAAC,EAAE,iBAAiB,EAAE;IAChC,MAAM,EAAE,EAAE,CAAC,EAAE,eAAe,EAAE;IAC9B,MAAM,EAAE,EAAE,CAAC,EAAE,cAAc,EAAE;IAC7B,MAAM,EAAE,EAAE,CAAC,EAAE,kBAAkB,EAAE;IAEjC,MAAM,EAAE,EAAE,CAAC,EAAE,0BAA0B,EAAE;IACzC,MAAM,EAAE,EAAE,CAAC,EAAE,yBAAyB,EAAE;IACxC,MAAM,EAAE,EAAE,CAAC,EAAE,wBAAwB,EAAE;IACvC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,uBAAuB,EAAE;IACtC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAElC,MAAM,EAAE,EAAE,CAAC,EAAE,wBAAwB,EAAE;IACvC,MAAM,EAAE,EAAE,CAAC,EAAE,qBAAqB,EAAE;IACpC,MAAM,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE;IAC/B,MAAM,EAAE,EAAE,CAAC,EAAE,aAAa,EAAE;IAC5B,MAAM,EAAE,EAAE,CAAC,EAAE,gBAAgB,EAAE;IAC/B,MAAM,EAAE,EAAE,CAAC,EAAE,iBAAiB,EAAE;IAChC,MAAM,EAAE,EAAE,CAAC,EAAE,oBAAoB,EAAE;IACnC,MAAM,EAAE,EAAE,CAAC,EAAE,sBAAsB,EAAE;IACrC,MAAM,EAAE,EAAE,CAAC,EAAE,wBAAwB,EAAE;IACvC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAClC,MAAM,EAAE,EAAE,CAAC,EAAE,mBAAmB,EAAE;IAElC,MAAM,EAAE,EAAE,CAAC,EAAE,cAAc,EAAE;CAC7B,CAAC;AAEW,QAAA,UAAU,GAA+B;IACrD,MAAM,EAAE,EAAE,CAAC,EAAE,+BAA+B,EAAE;CAC9C,CAAC"} \ No newline at end of file diff --git a/js/canvas.js b/js/canvas.js new file mode 100644 index 0000000..6c8dd21 --- /dev/null +++ b/js/canvas.js @@ -0,0 +1,112 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +var util_1 = require("./util"); +var wmf_1 = require("./wmf"); +exports.css_color = function (clr) { return "#" + (clr & 0xFF).toString(16).padStart(2, "0") + ((clr >> 8) & 0xFF).toString(16).padStart(2, "0") + ((clr >> 16) & 0xFF).toString(16).padStart(2, "0"); }; +exports.set_ctx_state = function (ctx, state) { + if (!state) + return; + var font = ""; + if (state.Font) { + if (state.Font.Italic) + font += " italic"; + if (state.Font.Weight) + font += " " + (state.Font.Weight == 700 ? "bold" : state.Font.Weight == 400 ? "" : state.Font.Weight); + if (state.Font.Height < 0) + font += " " + -state.Font.Height + "px"; + else if (state.Font.Height > 0) + font += " " + state.Font.Height + "px"; + var name_1 = state.Font.Name || ""; + if (name_1 == "System") + name_1 = "Calibri"; // TODO: default sys font is Segoe UI + if (name_1) + font += " '" + name_1 + "', sans-serif"; + ctx.font = font.trim(); + } +}; +// TODO: DIB BIT ORDER? +exports.render_actions_to_context = function (out, ctx) { + out.forEach(function (act) { + ctx.save(); + exports.set_ctx_state(ctx, act.s); + switch (act.t) { + case "poly": + ctx.beginPath(); + ctx.moveTo(act.p[0][0], act.p[0][1]); + act.p.slice(1).forEach(function (_a) { + var x = _a[0], y = _a[1]; + ctx.lineTo(x, y); + }); + if (act.g) + ctx.closePath(); + ctx.stroke(); + break; + case "text": + if (act.s && act.s.TextColor) + ctx.fillStyle = exports.css_color(act.s.TextColor); + if (act.s.Font.Angle != 0) { + ctx.translate(act.p[0], act.p[1]); + ctx.rotate(-act.s.Font.Angle * Math.PI / 180); + ctx.fillText(act.v, 0, 0); + ctx.translate(-act.p[0], -act.p[1]); + } + else + ctx.fillText(act.v, act.p[0], act.p[1]); + break; + case "cpy": + { + // TODO: base on ROP + var idata = ctx.getImageData(act.src[0][0], act.src[1][0], act.src[0][1], act.src[1][1]); + ctx.putImageData(idata, act.dst[0], act.dst[1]); + } + break; + case "str": { + if (act.data && act.data.BitCount == 24 && act.data.ImageData) { + var _o = new Uint8ClampedArray(act.data.Width * act.data.Height * 4); + for (var i = 0; i < act.data.Width * act.data.Height; ++i) { + var j = (i % act.data.Width) + act.data.Width * (act.data.Height - 1 - Math.floor(i / act.data.Width)); + _o[4 * i] = act.data.ImageData[3 * j + 2]; + _o[4 * i + 1] = act.data.ImageData[3 * j + 1]; + _o[4 * i + 2] = act.data.ImageData[3 * j]; + _o[4 * i + 3] = 255; + } + var idata = new ImageData(_o, act.data.Width, act.data.Height); + ctx.putImageData(idata, act.dst[0][0], act.dst[1][0]); + } + // TODO: ROP et al + } + } + ctx.restore(); + }); +}; +exports.render_canvas = function (out, image) { + var ctx; + /* find first action with window info */ + out.forEach(function (act) { + if (ctx) + return; + if (!act.s) + return; + if (!act.s.Extent || !act.s.Origin) + return; + image.width = act.s.Extent[0] - act.s.Origin[0]; + image.height = act.s.Extent[1] - act.s.Origin[1]; + ctx = image.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255,255,255)'; + ctx.fillRect(0, 0, act.s.Extent[0] - act.s.Origin[0], act.s.Extent[1] - act.s.Origin[1]); + ctx.restore(); + }); + if (!ctx) + ctx = image.getContext('2d'); + exports.render_actions_to_context(out, ctx); +}; +exports.draw_canvas = function (data, image) { + if (data instanceof ArrayBuffer) + return exports.draw_canvas(new Uint8Array(data), image); + util_1.prep_blob(data, 0); + var out = wmf_1.get_actions_prepped_bytes(data); + return exports.render_canvas(out, image); +}; +//# sourceMappingURL=canvas.js.map \ No newline at end of file diff --git a/js/canvas.js.map b/js/canvas.js.map new file mode 100644 index 0000000..ef4bd3c --- /dev/null +++ b/js/canvas.js.map @@ -0,0 +1 @@ +{"version":3,"file":"canvas.js","sourceRoot":"","sources":["../src/canvas.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/js/index.js b/js/index.js new file mode 100644 index 0000000..3f8104a --- /dev/null +++ b/js/index.js @@ -0,0 +1,21 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +var util_1 = require("./util"); +var wmf_1 = require("./wmf"); +var canvas_1 = require("./canvas"); +exports.draw_canvas = canvas_1.draw_canvas; +exports.render_canvas = canvas_1.render_canvas; +exports.get_actions = function (data) { + if (data instanceof ArrayBuffer) + return exports.get_actions(new Uint8Array(data)); + util_1.prep_blob(data, 0); + return wmf_1.get_actions_prepped_bytes(data); +}; +exports.image_size = function (data) { + if (data instanceof ArrayBuffer) + return exports.image_size(new Uint8Array(data)); + util_1.prep_blob(data, 0); + return wmf_1.image_size_prepped_bytes(data); +}; +//# sourceMappingURL=index.js.map \ No newline at end of file diff --git a/js/index.js.map b/js/index.js.map new file mode 100644 index 0000000..11eab64 --- /dev/null +++ b/js/index.js.map @@ -0,0 +1 @@ +{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,iEAAiE;AACjE,+BAAiD;AACjD,6BAAmF;AAEnF,mCAAsD;AAA7C,+BAAA,WAAW,CAAA;AAAE,iCAAA,aAAa,CAAA;AAEtB,QAAA,WAAW,GAAG,UAAC,IAAuC;IAClE,IAAG,IAAI,YAAY,WAAW;QAAE,OAAO,mBAAW,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACzE,gBAAS,CAAE,IAAY,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,+BAAyB,CAAC,IAAoB,CAAC,CAAC;AACxD,CAAC,CAAA;AAEY,QAAA,UAAU,GAAG,UAAC,IAAuC;IACjE,IAAG,IAAI,YAAY,WAAW;QAAE,OAAO,kBAAU,CAAC,IAAI,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC;IACxE,gBAAS,CAAE,IAAY,EAAE,CAAC,CAAC,CAAC;IAC5B,OAAO,8BAAwB,CAAC,IAAoB,CAAC,CAAC;AACvD,CAAC,CAAA"} \ No newline at end of file diff --git a/js/util.js b/js/util.js new file mode 100644 index 0000000..01e6158 --- /dev/null +++ b/js/util.js @@ -0,0 +1,395 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +// --- +var has_buf = !!(typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); +exports.has_buf = has_buf; +var Buffer_from; +exports.Buffer_from = Buffer_from; +if (typeof Buffer !== 'undefined') { + var nbfs = !Buffer.from; + if (!nbfs) + try { + Buffer.from("foo", "utf8"); + } + catch (e) { + nbfs = true; + } + exports.Buffer_from = Buffer_from = nbfs ? (function (buf, enc) { return (enc) ? new Buffer(buf, enc) : new Buffer(buf); }) : Buffer.from.bind(Buffer); + if (!Buffer.alloc) + Buffer.alloc = function (n) { return new Buffer(n); }; + if (!Buffer.allocUnsafe) + Buffer.allocUnsafe = function (n) { return new Buffer(n); }; +} +exports.new_raw_buf = function (len) { return has_buf ? Buffer.alloc(len) : new Array(len); }; +exports.new_unsafe_buf = function (len) { return has_buf ? Buffer.allocUnsafe(len) : new Array(len); }; +exports._chr = function (c) { return String.fromCharCode(c); }; +exports.chr0 = /\u0000/g; // eslint-disable-line no-control-regex +exports.chr1 = /[\u0001-\u0006]/g; // eslint-disable-line no-control-regex +// --- +var read_double_le = function (b, idx) { + var s = 1 - 2 * (b[idx + 7] >>> 7); + var e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f); + var m = (b[idx + 6] & 0x0f); + for (var i = 5; i >= 0; --i) + m = m * 256 + b[idx + i]; + if (e == 0x7ff) + return m == 0 ? (s * Infinity) : NaN; + if (e == 0) + e = -1022; + else { + e -= 1023; + m += Math.pow(2, 52); + } + return s * Math.pow(2, e - 52) * m; +}; +var write_double_le = function (b, v, idx) { + var bs = ((((v < 0) || (1 / v == -Infinity)) ? 1 : 0) << 7); + var e = 0, m = 0; + var av = bs ? (-v) : v; + if (!isFinite(av)) { + e = 0x7ff; + m = isNaN(v) ? 0x6969 : 0; + } + else if (av == 0) + e = m = 0; + else { + e = Math.floor(Math.log(av) / Math.LN2); + m = av * Math.pow(2, 52 - e); + if ((e <= -1023) && (!isFinite(m) || (m < Math.pow(2, 52)))) { + e = -1022; + } + else { + m -= Math.pow(2, 52); + e += 1023; + } + } + for (var i = 0; i <= 5; ++i, m /= 256) + b[idx + i] = m & 0xff; + b[idx + 6] = ((e & 0x0f) << 4) | (m & 0xf); + b[idx + 7] = (e >> 4) | bs; +}; +var __toBuffer = function (bufs /*:Array >*/) { + var x = []; + for (var i = 0; i < bufs[0].length; ++i) + if (bufs[0][i]) + for (var j = 0, L = bufs[0][i].length; j < L; j += 10240) + x.push.apply(x, bufs[0][i].slice(j, j + 10240)); + return x; +}; +var ___toBuffer = __toBuffer; +var __readUInt8 = function (b, idx) { return b[idx]; }; +var __readUInt16LE = function (b, idx) { return (b[idx + 1] * (1 << 8)) + b[idx]; }; +var __readInt16LE = function (b, idx) { var u = (b[idx + 1] * (1 << 8)) + b[idx]; return (u < 0x8000) ? u : ((0xffff - u + 1) * -1); }; +var __readUInt32LE = function (b, idx) { return b[idx + 3] * (1 << 24) + (b[idx + 2] << 16) + (b[idx + 1] << 8) + b[idx]; }; +var __readInt32LE = function (b, idx) { return (b[idx + 3] << 24) | (b[idx + 2] << 16) | (b[idx + 1] << 8) | b[idx]; }; +var __readInt32BE = function (b, idx) { return (b[idx] << 24) | (b[idx + 1] << 16) | (b[idx + 2] << 8) | b[idx + 3]; }; +var __utf16le = function (b, s, e) { + var ss = []; + for (var i = s; i < e; i += 2) + ss.push(String.fromCharCode(__readUInt16LE(b, i))); + return ss.join("").replace(exports.chr0, ''); +}; +exports.__utf16le = __utf16le; +var ___utf16le = __utf16le; +var __hexlify = function (b /*:RawBytes|CFBlob*/, s, l) { var ss = []; for (var i = s; i < s + l; ++i) + ss.push(("0" + b[i].toString(16)).slice(-2)); return ss.join(""); }; +var ___hexlify = __hexlify; +var __utf8 = function (b /*:RawBytes|CFBlob*/, s, e) { var ss = []; for (var i = s; i < e; i++) + ss.push(String.fromCharCode(__readUInt8(b, i))); return ss.join(""); }; +var ___utf8 = __utf8; +var __lpstr = function (b /*:RawBytes|CFBlob*/, i) { var len = __readUInt32LE(b, i); return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : ""; }; +var ___lpstr = __lpstr; +var __cpstr = function (b /*:RawBytes|CFBlob*/, i) { var len = __readUInt32LE(b, i); return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : ""; }; +var ___cpstr = __cpstr; +var __lpwstr = function (b /*:RawBytes|CFBlob*/, i) { var len = 2 * __readUInt32LE(b, i); return len > 0 ? __utf8(b, i + 4, i + 4 + len - 1) : ""; }; +var ___lpwstr = __lpwstr; +var __lpp4, ___lpp4; +__lpp4 = ___lpp4 = function lpp4_(b /*:RawBytes|CFBlob*/, i) { var len = __readUInt32LE(b, i); return len > 0 ? __utf16le(b, i + 4, i + 4 + len) : ""; }; +var ___8lpp4 = function (b /*:RawBytes|CFBlob*/, i) { var len = __readUInt32LE(b, i); return len > 0 ? __utf8(b, i + 4, i + 4 + len) : ""; }; +var __8lpp4 = ___8lpp4; +var ___double = function (b /*:RawBytes|CFBlob*/, idx) { return read_double_le(b, idx); }; +var __double = ___double; +if (has_buf) { + exports.__utf16le = __utf16le = function (b /*:RawBytes|CFBlob*/, s, e) { return (!Buffer.isBuffer(b)) ? ___utf16le(b, s, e) : b.toString('utf16le', s, e).replace(exports.chr0, ''); }; + __hexlify = function (b /*:RawBytes|CFBlob*/, s, l) { return Buffer.isBuffer(b) ? b.toString('hex', s, s + l) : ___hexlify(b, s, l); }; + __lpstr = function (b /*:RawBytes|CFBlob*/, i) { if (!Buffer.isBuffer(b)) + return ___lpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8', i + 4, i + 4 + len - 1) : ""; }; + __cpstr = function (b /*:RawBytes|CFBlob*/, i) { if (!Buffer.isBuffer(b)) + return ___cpstr(b, i); var len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8', i + 4, i + 4 + len - 1) : ""; }; + __lpwstr = function (b /*:RawBytes|CFBlob*/, i) { if (!Buffer.isBuffer(b)) + return ___lpwstr(b, i); var len = 2 * b.readUInt32LE(i); return b.toString('utf16le', i + 4, i + 4 + len - 1); }; + __lpp4 = function (b /*:RawBytes|CFBlob*/, i) { if (!Buffer.isBuffer(b)) + return ___lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf16le', i + 4, i + 4 + len); }; + __8lpp4 = function (b /*:RawBytes|CFBlob*/, i) { if (!Buffer.isBuffer(b)) + return ___8lpp4(b, i); var len = b.readUInt32LE(i); return b.toString('utf8', i + 4, i + 4 + len); }; + __utf8 = function (b /*:RawBytes|CFBlob*/, s, e) { return (Buffer.isBuffer(b)) ? b.toString('utf8', s, e) : ___utf8(b, s, e); }; + __toBuffer = function (bufs) { return (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs); }; + __double = function (b /*:RawBytes|CFBlob*/, i) { return (Buffer.isBuffer(b)) ? b.readDoubleLE(i) : ___double(b, i); }; +} +function ReadShift(size, t) { + var o = "", oI = 0, oR, w, vv, i, loc; + var oo = []; + switch (t) { + case 'dbcs': + loc = this.l; + if (has_buf && Buffer.isBuffer(this)) + o = this.slice(this.l, this.l + 2 * size).toString("utf16le"); + else + for (i = 0; i < size; ++i) { + o += String.fromCharCode(__readUInt16LE(this, loc)); + loc += 2; + } + size *= 2; + break; + case 'utf8': + o = __utf8(this, this.l, this.l + size); + break; + case 'utf16le': + size *= 2; + o = __utf16le(this, this.l, this.l + size); + break; + case 'wstr': + return ReadShift.call(this, size, 'dbcs'); + /* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */ + case 'lpstr-ansi': + o = __lpstr(this, this.l); + size = 4 + __readUInt32LE(this, this.l); + break; + case 'lpstr-cp': + o = __cpstr(this, this.l); + size = 4 + __readUInt32LE(this, this.l); + break; + /* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */ + case 'lpwstr': + o = __lpwstr(this, this.l); + size = 4 + 2 * __readUInt32LE(this, this.l); + break; + /* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */ + case 'lpp4': + size = 4 + __readUInt32LE(this, this.l); + o = __lpp4(this, this.l); + if (size & 0x02) + size += 2; + break; + /* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */ + case '8lpp4': + size = 4 + __readUInt32LE(this, this.l); + o = __8lpp4(this, this.l); + if (size & 0x03) + size += 4 - (size & 0x03); + break; + case 'cstr': + size = 0; + o = ""; + while ((w = __readUInt8(this, this.l + size++)) !== 0) + oo.push(String.fromCharCode(w)); + o = oo.join(""); + break; + case '_wstr': + size = 0; + o = ""; + while ((w = __readUInt16LE(this, this.l + size)) !== 0) { + oo.push(String.fromCharCode(w)); + size += 2; + } + size += 2; + o = oo.join(""); + break; + /* sbcs and dbcs support continue records in the SST way TODO codepages */ + case 'dbcs-cont': + o = ""; + loc = this.l; + for (i = 0; i < size; ++i) { + if (this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size - i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(String.fromCharCode(__readUInt16LE(this, loc))); + loc += 2; + } + o = oo.join(""); + size *= 2; + break; + case 'cpstr': + /* falls through */ + case 'sbcs-cont': + o = ""; + loc = this.l; + for (i = 0; i != size; ++i) { + if (this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size - i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(String.fromCharCode(__readUInt8(this, loc))); + loc += 1; + } + o = oo.join(""); + break; + default: + switch (size) { + case 1: + oI = __readUInt8(this, this.l); + this.l++; + return oI; + case 2: + oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); + this.l += 2; + return oI; + case 4: + case -4: + if (t === 'i' || ((this[this.l + 3] & 0x80) === 0)) { + oI = ((size > 0) ? __readInt32LE : __readInt32BE)(this, this.l); + this.l += 4; + return oI; + } + else { + oR = __readUInt32LE(this, this.l); + this.l += 4; + } + return oR; + case 8: + case -8: + if (t === 'f') { + if (size == 8) + oR = __double(this, this.l); + else + oR = __double([this[this.l + 7], this[this.l + 6], this[this.l + 5], this[this.l + 4], this[this.l + 3], this[this.l + 2], this[this.l + 1], this[this.l + 0]], 0); + this.l += 8; + return oR; + } + else + size = 8; + /* falls through */ + case 16: + o = __hexlify(this, this.l, size); + break; + } + } + this.l += size; + return o; +} +exports.ReadShift = ReadShift; +var __writeUInt32LE = function (b /*:RawBytes|CFBlob*/, val, idx) { b[idx] = (val & 0xFF); b[idx + 1] = ((val >>> 8) & 0xFF); b[idx + 2] = ((val >>> 16) & 0xFF); b[idx + 3] = ((val >>> 24) & 0xFF); }; +var __writeInt32LE = function (b /*:RawBytes|CFBlob*/, val, idx) { b[idx] = (val & 0xFF); b[idx + 1] = ((val >> 8) & 0xFF); b[idx + 2] = ((val >> 16) & 0xFF); b[idx + 3] = ((val >> 24) & 0xFF); }; +var __writeUInt16LE = function (b /*:RawBytes|CFBlob*/, val, idx) { b[idx] = (val & 0xFF); b[idx + 1] = ((val >>> 8) & 0xFF); }; +function WriteShift(t, val, f) { + var size = 0, i = 0; + if (f === 'dbcs') { + if (typeof val !== 'string') + throw new Error("expected string"); + for (i = 0; i != val.length; ++i) + __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i); + size = 2 * val.length; + } + else if (f === 'sbcs') { + { + val = val.replace(/[^\x00-\x7F]/g, "_"); // eslint-disable-line no-control-regex + for (i = 0; i != val.length; ++i) + this[this.l + i] = (val.charCodeAt(i) & 0xFF); + } + size = val.length; + } + else if (f === 'hex') { + for (; i < t; ++i) { + this[this.l++] = (parseInt(val.slice(2 * i, 2 * i + 2), 16) || 0); + } + return this; + } + else if (f === 'utf16le') { + /*:: if(typeof val !== "string") throw new Error("unreachable"); */ + var end = Math.min(this.l + t, this.length); + for (i = 0; i < Math.min(val.length, t); ++i) { + var cc = val.charCodeAt(i); + this[this.l++] = (cc & 0xff); + this[this.l++] = (cc >> 8); + } + while (this.l < end) + this[this.l++] = 0; + return this; + } + else if (typeof val === 'number') + switch (t) { + case 1: + size = 1; + this[this.l] = val & 0xFF; + break; + case 2: + size = 2; + this[this.l] = val & 0xFF; + val >>>= 8; + this[this.l + 1] = val & 0xFF; + break; + case 3: + size = 3; + this[this.l] = val & 0xFF; + val >>>= 8; + this[this.l + 1] = val & 0xFF; + val >>>= 8; + this[this.l + 2] = val & 0xFF; + break; + case 4: + size = 4; + __writeUInt32LE(this, val, this.l); + break; + case 8: + size = 8; + if (f === 'f') { + write_double_le(this, val, this.l); + break; + } + /* falls through */ + case 16: break; + case -4: + size = 4; + __writeInt32LE(this, val, this.l); + break; + } + this.l += size; + return this; +} +exports.WriteShift = WriteShift; +function CheckField(hexstr, fld) { + var m = __hexlify(this, this.l, hexstr.length >> 1); + if (m !== hexstr) + throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m); + this.l += hexstr.length >> 1; +} +exports.CheckField = CheckField; +var prep_blob = function (blob, pos) { + blob.l = pos; + blob.read_shift = ReadShift; + blob.chk = CheckField; + blob.write_shift = WriteShift; +}; +exports.prep_blob = prep_blob; +var new_buf = function (sz) { + var o = exports.new_raw_buf(sz); + prep_blob(o, 0); + return o; +}; +exports.new_buf = new_buf; +// --- +var __bconcat = function (bufs /*:Array*/) { + var is_all_arrays = true; + for (var w = 0; w < bufs.length; ++w) + if (!Array.isArray(bufs[w])) + is_all_arrays = false; + if (is_all_arrays) + return [].concat.apply([], bufs); + var maxlen = 0, i = 0; + for (i = 0; i < bufs.length; ++i) + maxlen += bufs[i].length; + var o = new Uint8Array(maxlen); + for (i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) + o.set(bufs[i], maxlen); + return o; +}; +var bconcat = __bconcat; +exports.bconcat = bconcat; +if (has_buf) + exports.bconcat = bconcat = function (bufs) { return Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat.apply([], bufs); }; +//# sourceMappingURL=util.js.map \ No newline at end of file diff --git a/js/util.js.map b/js/util.js.map new file mode 100644 index 0000000..b4bf951 --- /dev/null +++ b/js/util.js.map @@ -0,0 +1 @@ +{"version":3,"file":"util.js","sourceRoot":"","sources":["../src/util.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/js/wmf.js b/js/wmf.js new file mode 100644 index 0000000..1c5700c --- /dev/null +++ b/js/wmf.js @@ -0,0 +1,428 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +var util_1 = require("./util"); +var Records_1 = require("./Records"); +var parse_emf = function (data) { + //try { require("fs").writeFileSync("out.emf", data); } catch(e) {} +}; +/* 2.2.2.9 */ +var parse_dib = function (data) { + if (data.length == 0) + return null; + util_1.prep_blob(data, 0); + /* DIBHeaderInfo */ + var HeaderSize = data.read_shift(4); + var Width = 0, Height = 0, Planes = 0, BitCount = 0; + var Compression = 0, ImageSize = 0, XPelsPerMeter = 0, YPelsPerMeter = 0, ColorUsed = 0, ColorImportant = 0; + if (HeaderSize == 0x0C) { + Width = data.read_shift(2); + Height = data.read_shift(2); + } + else { + Width = data.read_shift(4, 'i'); + Height = data.read_shift(4, 'i'); + } + Planes = data.read_shift(2); + BitCount = data.read_shift(2); + var out = { + Width: Width, + Height: Height, + BitCount: BitCount, + }; + if (HeaderSize != 0x0C) { + Compression = data.read_shift(4); + ImageSize = data.read_shift(4); + XPelsPerMeter = data.read_shift(4, 'i'); + YPelsPerMeter = data.read_shift(4, 'i'); + ColorUsed = data.read_shift(4); + ColorImportant = data.read_shift(4); + out["Compression"] = Compression; + if (BitCount == 24 && ImageSize > Height * 3 * Width) + Width = out["Width"] = ImageSize / (Height * 3); + } + /* Colors */ + /* BitmapBuffer */ + if (ImageSize == data.length - data.l) { + out["ImageData"] = data.slice(data.l, data.length); + util_1.prep_blob(out["ImageData"], 0); + } + return out; +}; +var add_to_objects = function (objects, obj) { + var found = false; + for (var i = 0; i < objects.length; ++i) + if (!objects[i]) { + objects[i] = obj; + found = true; + } + if (!found) + objects.push(obj); +}; +exports.get_actions_prepped_bytes = function (data) { + var out = []; + /* 2.3.22 META_HEADER */ + // Type (2 bytes) must be 1 or 2 + var h = data.read_shift(2); + if (h != 1 && h != 2) + throw "Header: Type " + h + " must be 1 or 2"; + // HeaderSize expected to be 9 + if ((h = data.read_shift(2)) != 9) + throw "Header: HeaderSize " + h + " must be 9"; + // Version (2 bytes) 1 or 3 + h = data.read_shift(2); + if (h != 0x0100 && h != 0x0300) + throw "Header: Version " + h + " must be 0x0100 or 0x0300"; + // SizeLow + // SizeHigh + // #Objects + // MaxRecord + // NumberOfMembers + data.l = 18; + var rt = 0; + /* used for EMF */ + var escapecnt = 0; + var CommentRecordCount = 0; + var RemainingBytes = 0; + var EnhancedMetafileDataSize = 0; + var bufs = []; + var objects = []; + var states = []; + var state = {}; + var sidx = -1; + while (data.l < data.length) { + h = data.read_shift(4); + var end = data.l + h * 2 - 4; + rt = data.read_shift(2); + var Record = Records_1.WMFRecords[rt]; + if (rt == 0x0000) + break; // META_EOF + switch (rt) { + case 0x0626: + { // META_ESCAPE + var EscapeFunction = data.read_shift(2); + var Escape = Records_1.WMFEscapes[EscapeFunction]; + //console.log("::", Escape); + /* 2.3.6 */ + switch (EscapeFunction) { + case 0x000F: + { // META_ESCAPE_ENHANCED_METAFILE + var ByteCount = data.read_shift(2); + var tmp = data.read_shift(4); + if (tmp != 0x43464D57) + throw "Escape: Comment ID 0x" + tmp.toString(16) + " != 0x43464D57"; + tmp = data.read_shift(4); + if (tmp != 0x00000001) + throw "Escape: Comment Type 0x" + tmp.toString(16) + " != 0x00000001"; + tmp = data.read_shift(4); + if (tmp != 0x00010000) + throw "Escape: Version 0x" + tmp.toString(16) + " != 0x00010000"; + var Checksum = data.read_shift(2); + data.l += 4; // Flags + if (escapecnt == 0) { + CommentRecordCount = data.read_shift(4); // total number of records + } + else { + var _CommentRecordCount = data.read_shift(4); + if (_CommentRecordCount != CommentRecordCount) + throw "Escape: CommentRecordCount " + _CommentRecordCount + " != " + CommentRecordCount; + } + var CurrentRecordSize = data.read_shift(4); // size of this record + var _RemainingBytes = data.read_shift(4); + if (escapecnt > 0 && CurrentRecordSize + _RemainingBytes != RemainingBytes) + throw "Escape: " + RemainingBytes + " != " + CurrentRecordSize + " + " + _RemainingBytes; + RemainingBytes = _RemainingBytes; + var _EnhancedMetafileDataSize = data.read_shift(4); + if (escapecnt == 0) { + if (_EnhancedMetafileDataSize != CurrentRecordSize + _RemainingBytes) + throw "Escape: " + _EnhancedMetafileDataSize + " != " + CurrentRecordSize + " + " + _RemainingBytes; + EnhancedMetafileDataSize = _EnhancedMetafileDataSize; + } + else if (EnhancedMetafileDataSize != _EnhancedMetafileDataSize) + throw "Escape: " + EnhancedMetafileDataSize + " != " + _EnhancedMetafileDataSize; + if (ByteCount != (end - data.l) + 34) + throw "Escape: Sizes " + ByteCount + " != " + (end - data.l) + " + 34"; + if (end - data.l != CurrentRecordSize) + throw "Escape: CRSize " + CurrentRecordSize + " != " + (end - data.l); + bufs.push(data.slice(data.l, end)); + ++escapecnt; + if (escapecnt == CommentRecordCount) { + var prepped = util_1.bconcat(bufs); + util_1.prep_blob(prepped, 0); + parse_emf(prepped); + } + } + break; + default: throw "Escape: Unrecognized META_ESCAPE Type 0x" + EscapeFunction.toString(16); + } + } + break; + // #region 2.3.1 Bitmap Record Types + case 0x0940: + { // 2.3.1.2 META_DIBBITBLT + var has_bitmap = h != (rt >> 8) + 3; + var RasterOperation = data.read_shift(4); + var YSrc = data.read_shift(2, "i"); + var XSrc = data.read_shift(2, "i"); + if (!has_bitmap) + data.l += 2; + var Height = data.read_shift(2, "i"); + var Width = data.read_shift(2, "i"); + var YDest = data.read_shift(2, "i"); + var XDest = data.read_shift(2, "i"); + var res = { + t: "cpy", + src: [[XSrc, Width], [YSrc, Height]], + dst: [XDest, YDest], + rop: RasterOperation, + s: Object.assign({}, state) + }; + if (has_bitmap) { + var DIB = parse_dib(data.slice(data.l, end)); + res.data = DIB; + } + out.push(res); + } + break; + case 0x0B41: + { // 2.3.1.3 META_DIBSTRETCHBLT + var has_bitmap = h != (rt >> 8) + 3; + var RasterOperation = data.read_shift(4); + var SrcHeight = data.read_shift(2, "i"); + var SrcWidth = data.read_shift(2, "i"); + var YSrc = data.read_shift(2, "i"); + var XSrc = data.read_shift(2, "i"); + if (!has_bitmap) + data.l += 2; + var DestHeight = data.read_shift(2, "i"); + var DestWidth = data.read_shift(2, "i"); + var YDest = data.read_shift(2, "i"); + var XDest = data.read_shift(2, "i"); + var res = { + t: "str", + src: [[XSrc, SrcWidth], [YSrc, SrcHeight]], + dst: [[XDest, DestWidth], [YDest, DestHeight]], + rop: RasterOperation, + s: Object.assign({}, state) + }; + if (has_bitmap) { + var DIB = parse_dib(data.slice(data.l, end)); + res.data = DIB; + } + out.push(res); + } + break; + // #endregion + // #region 2.3.3 Drawing Record Types + case 0x0A32: + { // 2.3.3.5 META_EXTTEXTOUT + var Y = data.read_shift(2); + var X = data.read_shift(2); + var StringLength = data.read_shift(2); + var fwOpts = data.read_shift(2); // 2.1.2.2 + if (fwOpts & 0x06) { + data.l += 8; // Rectangle 2.2.2.18 (for clipping/opaquing) + } + var str = data.read_shift(StringLength, 'cpstr'); + if (data.l < end) { /* TODO: Dx */ } + out.push({ t: "text", v: str, p: [X, Y], s: Object.assign({}, state) }); + /* TODO!! */ + } + break; + case 0x0325: // 2.3.3.14 META_POLYLINE + case 0x0324: // 2.3.3.15 META_POLYGON + { + var nPoints = data.read_shift(2); + var points = []; + for (var i = 0; i < nPoints; ++i) + points.push([data.read_shift(2), data.read_shift(2)]); + out.push({ t: "poly", p: points, g: rt !== 0x0325, s: state }); + } + break; + case 0x0538: + { // 2.3.3.16 META_POLYPOLYGON + var nPolygons = data.read_shift(2); + var polys = []; + var szs = []; + /* 2.2.2.17 PolyPolygon */ + for (var i = 0; i < nPolygons; ++i) + szs[i] = data.read_shift(2); + for (var i = 0; i < szs.length; ++i) { + polys[i] = []; + for (var j = 0; j < szs[i]; ++j) + polys[i].push([data.read_shift(2), data.read_shift(2)]); + out.push({ t: "poly", p: polys[i], g: true, s: state }); + } + } + break; + // #endregion + // #region 2.3.4 Object Record Types + case 0x02FC: + { // 2.3.4.1 META_CREATEBRUSHINDIRECT + var obj = {}; + obj.Brush = { + Style: data.read_shift(2), + Color: data.read_shift(4), + Hatch: data.read_shift(2) + }; + add_to_objects(objects, obj); + } + break; + case 0x02FB: + { // 2.3.4.2 META_CREATEFONTINDIRECT + var obj = {}; + obj.Font = {}; + /* 2.2.1.2 Font TODO!! */ + var Height = data.read_shift(2, "i"); + var Width = data.read_shift(2, "i"); + var Escapement = data.read_shift(2, "i"); + var Orientation = data.read_shift(2, "i"); + var Weight = data.read_shift(2, "i"); + var Italic = !!data.read_shift(1); + var Underline = !!data.read_shift(1); + var StrikeOut = !!data.read_shift(1); + var CharSet = data.read_shift(1); + var OutPrecision = data.read_shift(1); + var ClipPrecision = data.read_shift(1); + var Quality = data.read_shift(1); + var PitchAndFamily = data.read_shift(1); + var Facename = data.read_shift(32, "cstr"); + obj.Font.Name = Facename; + obj.Font.Height = Height; + obj.Font.Weight = Weight; + obj.Font.Italic = Italic; + obj.Font.Angle = Escapement / 10; + add_to_objects(objects, obj); + } + break; + case 0x02FA: + { // 2.3.4.5 META_CREATEPENINDIRECT + var obj = {}; + obj.Pen = { + Style: data.read_shift(2), + Width: data.read_shift(4) & 0xFF, + Color: data.read_shift(4) + }; + add_to_objects(objects, obj); + } + break; + case 0x01F0: + { // 2.3.4.7 META_DELETEOBJECT + var ObjectIndex = data.read_shift(2); + //console.log("DELETE", ObjectIndex, objects[ObjectIndex]); + objects[ObjectIndex] = null; + } + break; + case 0x012C: + { // 2.3.4.9 META_SELECTCLIPREGION + var Region = data.read_shift(2); + //console.log("CLIPREGION", Region, objects[Region]); + //Object.assign(state, objects[Region]); + } + break; + case 0x012D: + { // 2.3.4.10 META_SELECTOBJECT + var ObjectIndex = data.read_shift(2); + //console.log("SELECT", ObjectIndex, objects[ObjectIndex]); + Object.assign(state, objects[ObjectIndex]); + // TODO!! + } + break; + // #endregion + // #region 2.3.5 State Record Types + case 0x0416: // 2.3.5.3 META_INTERSECTCLIPRECT + state.ClipRect = [[0, 0], [0, 0]]; + state.ClipRect[1][1] = data.read_shift(2); + state.ClipRect[1][0] = data.read_shift(2); + state.ClipRect[0][1] = data.read_shift(2); + state.ClipRect[0][0] = data.read_shift(2); + break; + case 0x0127: + { // 2.3.5.10 META_RESTOREDC + var nSavedDC = data.read_shift(2, 'i'); + state = states[sidx = (nSavedDC >= 0 ? nSavedDC : sidx + nSavedDC)]; + } + break; + case 0x001E: // 2.3.5.11 META_SAVEDC + states.push(state); + sidx = states.length - 1; + state = JSON.parse(JSON.stringify(state)); + break; + case 0x0102: // 2.3.5.15 META_SETBKMODE + state.BkMode = data.read_shift(2); + break; + case 0x0103: // 2.3.5.17 META_SETMAPMODE + state.MapMode = data.read_shift(2); + break; + case 0x0106: // 2.3.5.20 META_SETPOLYFILLMODE + state.PolyFillMode = data.read_shift(2); + break; + case 0x0107: // 2.3.5.23 META_SETSTRETCHBLTMODE + state.StretchMode = data.read_shift(2); + break; + case 0x012E: // 2.3.5.24 META_SETTEXTALIGN + state.TextAlignmentMode = data.read_shift(2); + break; + case 0x0209: // 2.3.5.26 META_SETTEXTCOLOR + state.TextColor = data.read_shift(4); + break; + case 0x020C: // 2.3.5.30 META_SETWINDOWEXT + state.Extent = [0, 0]; + state.Extent[1] = data.read_shift(2); + state.Extent[0] = data.read_shift(2); + break; + case 0x020B: // 2.3.5.31 META_SETWINDOWORG + state.Origin = [0, 0]; + state.Origin[1] = data.read_shift(2); + state.Origin[0] = data.read_shift(2); + break; + // #endregion + default: + if (!Record) + throw "Record: Unrecognized type 0x" + rt.toString(16); + console.log(Record); + } + data.l = end; + //if(rt != 0x0626) console.log(Record); + } + if (rt !== 0) + throw "Record: Last Record Type " + rt + " is not EOF type"; + return out; +}; +exports.image_size_prepped_bytes = function (data) { + var origin = [NaN, NaN], extents = [NaN, NaN]; + /* 2.3.22 META_HEADER */ + // Type (2 bytes) must be 1 or 2 + var h = data.read_shift(2); + if (h != 1 && h != 2) + throw "Header: Type " + h + " must be 1 or 2"; + // HeaderSize expected to be 9 + if ((h = data.read_shift(2)) != 9) + throw "Header: HeaderSize " + h + " must be 9"; + // Version (2 bytes) 1 or 3 + h = data.read_shift(2); + if (h != 0x0100 && h != 0x0300) + throw "Header: Version " + h + " must be 0x0100 or 0x0300"; + data.l = 18; + var rt = 0; + while (data.l < data.length) { + h = data.read_shift(4); + var end = data.l + h * 2 - 4; + rt = data.read_shift(2); + if (rt == 0x0000) + break; // META_EOF + switch (rt) { + case 0x020C: // 2.3.5.30 META_SETWINDOWEXT + extents[1] = data.read_shift(2); + extents[0] = data.read_shift(2); + break; + case 0x020B: // 2.3.5.31 META_SETWINDOWORG + origin[1] = data.read_shift(2); + origin[0] = data.read_shift(2); + break; + } + data.l = end; + } + return [extents[0] - origin[0], extents[1] - origin[1]]; +}; +//# sourceMappingURL=wmf.js.map \ No newline at end of file diff --git a/js/wmf.js.map b/js/wmf.js.map new file mode 100644 index 0000000..6018ed6 --- /dev/null +++ b/js/wmf.js.map @@ -0,0 +1 @@ +{"version":3,"file":"wmf.js","sourceRoot":"","sources":["../src/wmf.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/misc/entry.js b/misc/entry.js new file mode 100644 index 0000000..f0a1e7e --- /dev/null +++ b/misc/entry.js @@ -0,0 +1,3 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +var WMF = require("../js/"); +module.exports = WMF; diff --git a/misc/webpack.browser.config.js b/misc/webpack.browser.config.js new file mode 100644 index 0000000..a3a5993 --- /dev/null +++ b/misc/webpack.browser.config.js @@ -0,0 +1,37 @@ +const webpack = require('webpack'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); + +const banner = '/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */'; + +module.exports = { + mode: 'development', + entry: './misc/entry.js', + devtool: 'source-map', + output: { + library: 'WMF', + libraryTarget: 'var', + filename: 'wmf.js', + }, + node: { process: false }, + module: { + rules: [ + { + test: /\.js$/, + use: ['source-map-loader'], + enforce: 'pre' + } + ] + }, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + uglifyOptions: { + output: { beautify: false, preamble: banner } + } + }) + ] + }, + plugins: [ + new webpack.BannerPlugin({ banner, raw: true, entryOnly: true }) + ] +}; diff --git a/misc/webpack.node.config.js b/misc/webpack.node.config.js new file mode 100644 index 0000000..68690ec --- /dev/null +++ b/misc/webpack.node.config.js @@ -0,0 +1,39 @@ +const webpack = require('webpack'); +const UglifyJsPlugin = require('uglifyjs-webpack-plugin'); +var nodeExternals = require('webpack-node-externals'); + +const banner = '/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */'; + +module.exports = { + mode: 'development', + entry: './misc/entry.js', + devtool: 'source-map', + output: { + library: 'WMF', + libraryTarget: 'commonjs2', + filename: 'wmf.node.js' + }, + target: 'node', + externals: [nodeExternals()], + module: { + rules: [ + { + test: /\.js$/, + use: ['source-map-loader'], + enforce: 'pre' + } + ] + }, + optimization: { + minimizer: [ + new UglifyJsPlugin({ + uglifyOptions: { + output: { beautify: false, preamble: banner } + } + }) + ] + }, + plugins: [ + new webpack.BannerPlugin({ banner, raw: true, entryOnly: true }) + ] +}; diff --git a/package.json b/package.json new file mode 100644 index 0000000..fa778f6 --- /dev/null +++ b/package.json @@ -0,0 +1,20 @@ +{ + "name": "wmf", + "version": "1.0.0", + "author": "sheetjs", + "description": "Windows MetaFile (WMF) parser", + "keywords": [ "wmf", "image" ], + "main": "./dist/wmf.node.js", + "browser": "./js/index.js", + "dependencies": { + }, + "devDependencies": { + "source-map-loader": "^0.2.4", + "uglifyjs-webpack-plugin": "^2.2.0" + }, + "homepage": "https://sheetjs.com/", + "files": ["dist/", "LICENSE", "README.md", "js/"], + "bugs": { "url": "https://github.com/SheetJS/js-wmf/issues" }, + "license": "Apache-2.0", + "engines": { "node": ">=12.0" } +} diff --git a/src/Records.ts b/src/Records.ts new file mode 100644 index 0000000..992bba5 --- /dev/null +++ b/src/Records.ts @@ -0,0 +1,50 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +export interface WMFRecord { + n: string; +} + +export interface WMFEscape { + n: string; +} + +/* 2.1.1.1 RecordType Enumeration */ +export const WMFRecords: {[key: number]: WMFRecord} = { + 0x0000: { n: "META_EOF" }, // 2.3.2.1 + 0x0626: { n: "META_ESCAPE" }, // 2.3.6.1 + + 0x0940: { n: "META_DIBBITBLT" }, // 2.3.1.2 + 0x0B41: { n: "META_DIBSTRETCHBLT" }, // 2.3.1.3 + + 0x0A32: { n: "META_EXTTEXTOUT" }, // 2.3.3.5 + 0x0325: { n: "META_POLYLINE" }, // 2.3.3.14 + 0x0324: { n: "META_POLYGON" }, // 2.3.3.15 + 0x0538: { n: "META_POLYPOLYGON" }, // 2.3.3.16 + + 0x02FC: { n: "META_CREATEBRUSHINDIRECT" }, // 2.3.4.1 + 0x02FB: { n: "META_CREATEFONTINDIRECT" }, // 2.3.4.2 + 0x02FA: { n: "META_CREATEPENINDIRECT" }, // 2.3.4.5 + 0x01F0: { n: "META_DELETEOBJECT" }, // 2.3.4.7 + 0x012C: { n: "META_SELECTCLIPREGION" }, // 2.3.4.9 + 0x012D: { n: "META_SELECTOBJECT" }, // 2.3.4.10 + + 0x0416: { n: "META_INTERSECTCLIPRECT" }, // 2.3.5.3 + 0x0035: { n: "META_REALIZEPALETTE" }, // 2.3.5.8 + 0x0127: { n: "META_RESTOREDC" }, // 2.3.5.10 + 0x001E: { n: "META_SAVEDC" }, // 2.3.5.11 + 0x0102: { n: "META_SETBKMODE" }, // 2.3.5.15 + 0x0103: { n: "META_SETMAPMODE" }, // 2.3.5.17 + 0x0037: { n: "META_SETPALENTRIES" }, // 2.3.5.19 + 0x0106: { n: "META_SETPOLYFILLMODE" }, // 2.3.5.20 + 0x0107: { n: "META_SETSTRETCHBLTMODE" }, // 2.3.5.23 + 0x012E: { n: "META_SETTEXTALIGN" }, // 2.3.5.24 + 0x0209: { n: "META_SETTEXTCOLOR" }, // 2.3.5.26 + 0x020C: { n: "META_SETWINDOWEXT" }, // 2.3.5.30 + 0x020B: { n: "META_SETWINDOWORG" }, // 2.3.5.31 + + 0xFFFF: { n: "META_SHEETJS" } +}; + +export const WMFEscapes: {[key: number]: WMFEscape} = { + 0x000F: { n: "META_ESCAPE_ENHANCED_METAFILE" } +}; + diff --git a/src/canvas.ts b/src/canvas.ts new file mode 100644 index 0000000..7f1d0f2 --- /dev/null +++ b/src/canvas.ts @@ -0,0 +1,98 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +import { PreppedBytes, prep_blob } from './util'; +import { Action, PlaybackDeviceContextState, get_actions_prepped_bytes } from './wmf' + +export const css_color = (clr: number): string => `#${(clr & 0xFF).toString(16).padStart(2, "0")}${((clr>>8) & 0xFF).toString(16).padStart(2, "0")}${((clr>>16) & 0xFF).toString(16).padStart(2, "0")}` + +export const set_ctx_state = (ctx: CanvasRenderingContext2D, state: PlaybackDeviceContextState): void => { + if(!state) return; + let font = ""; + if(state.Font) { + if(state.Font.Italic) font += " italic"; + if(state.Font.Weight) font += ` ${state.Font.Weight == 700 ? "bold" : state.Font.Weight == 400 ? "" : state.Font.Weight}`; + if(state.Font.Height < 0) font += ` ${-state.Font.Height}px`; + else if(state.Font.Height > 0) font += ` ${state.Font.Height}px`; + let name = state.Font.Name || ""; + if(name == "System") name = "Calibri"; // TODO: default sys font is Segoe UI + if(name) font += ` '${name}', sans-serif`; + ctx.font = font.trim(); + } +}; + +// TODO: DIB BIT ORDER? +export const render_actions_to_context = (out: Action[], ctx: CanvasRenderingContext2D) => { + out.forEach(act => { + ctx.save(); + set_ctx_state(ctx, act.s); + switch(act.t) { + case "poly": + ctx.beginPath(); + ctx.moveTo(act.p[0][0], act.p[0][1]); + act.p.slice(1).forEach(([x,y]) => { + ctx.lineTo(x, y); + }); + if(act.g) ctx.closePath(); + ctx.stroke(); + break; + case "text": + if(act.s && act.s.TextColor) ctx.fillStyle = css_color(act.s.TextColor); + if(act.s.Font.Angle != 0) { + ctx.translate(act.p[0], act.p[1]); + ctx.rotate(-act.s.Font.Angle * Math.PI / 180); + ctx.fillText(act.v, 0, 0); + ctx.translate(-act.p[0], -act.p[1]); + } + else ctx.fillText(act.v, act.p[0], act.p[1]); + break; + case "cpy": { + // TODO: base on ROP + const idata = ctx.getImageData(act.src[0][0], act.src[1][0], act.src[0][1], act.src[1][1]); + ctx.putImageData(idata, act.dst[0], act.dst[1]); + } break; + case "str": { + if(act.data && act.data.BitCount == 24 && act.data.ImageData) { + const _o = new Uint8ClampedArray(act.data.Width * act.data.Height * 4); + for(let i = 0; i < act.data.Width * act.data.Height; ++i) { + const j = (i % act.data.Width) + act.data.Width * (act.data.Height - 1 - Math.floor(i / act.data.Width)); + _o[4*i] = act.data.ImageData[3*j+2]; + _o[4*i+1] = act.data.ImageData[3*j+1]; + _o[4*i+2] = act.data.ImageData[3*j]; + _o[4*i+3] = 255; + } + const idata = new ImageData(_o, act.data.Width, act.data.Height); + ctx.putImageData(idata, act.dst[0][0], act.dst[1][0]); + } + // TODO: ROP et al + } + } + ctx.restore(); + }); +} + +export const render_canvas = (out: Action[], image: HTMLCanvasElement): void => { + let ctx: CanvasRenderingContext2D; + + /* find first action with window info */ + out.forEach(act => { + if(ctx) return; + if(!act.s) return; + if(!act.s.Extent || !act.s.Origin) return; + image.width = act.s.Extent[0] - act.s.Origin[0]; + image.height = act.s.Extent[1] - act.s.Origin[1]; + ctx = image.getContext('2d'); + ctx.save(); + ctx.fillStyle = 'rgb(255,255,255)'; + ctx.fillRect(0, 0, act.s.Extent[0] - act.s.Origin[0], act.s.Extent[1] - act.s.Origin[1]) + ctx.restore(); + }); + + if(!ctx) ctx = image.getContext('2d'); + render_actions_to_context(out, ctx); +} + +export const draw_canvas = (data: Buffer | Uint8Array | ArrayBuffer, image: HTMLCanvasElement): void => { + if(data instanceof ArrayBuffer) return draw_canvas(new Uint8Array(data), image); + prep_blob((data as any), 0); + const out: Action[] = get_actions_prepped_bytes(data as PreppedBytes); + return render_canvas(out, image); +}; diff --git a/src/index.ts b/src/index.ts new file mode 100644 index 0000000..409c8d6 --- /dev/null +++ b/src/index.ts @@ -0,0 +1,17 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +import { PreppedBytes, prep_blob } from './util'; +import { Action, get_actions_prepped_bytes, image_size_prepped_bytes } from './wmf' + +export { draw_canvas, render_canvas } from './canvas'; + +export const get_actions = (data: Buffer | Uint8Array | ArrayBuffer): Action[] => { + if(data instanceof ArrayBuffer) return get_actions(new Uint8Array(data)); + prep_blob((data as any), 0); + return get_actions_prepped_bytes(data as PreppedBytes); +} + +export const image_size = (data: Buffer | Uint8Array | ArrayBuffer): [number, number] => { + if(data instanceof ArrayBuffer) return image_size(new Uint8Array(data)); + prep_blob((data as any), 0); + return image_size_prepped_bytes(data as PreppedBytes); +} diff --git a/src/util.ts b/src/util.ts new file mode 100644 index 0000000..60b0c96 --- /dev/null +++ b/src/util.ts @@ -0,0 +1,297 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +export type RawBytes = Buffer | number[]; + +export type PreppedBytes = RawBytes & { + l: number; + read_shift(size: 1): number; + read_shift(size: 2): number; + read_shift(size: 2, t: "i"): number; + read_shift(size: 4): number; + read_shift(size: 4, t: "i"): number; + read_shift(size: 8, t: "f"): number; + read_shift(size: number, t: "cstr"): string; + read_shift(size: number, t: "cpstr"): string; + read_shift(size: number, t: "_wstr"): string; + read_shift(size: number, t?: string): number|string; + chk(hexstr: string, fld: string): void; + write_shift(t: number, val: string|number, f?: string): void; +}; + +// --- + +const has_buf = !!(typeof Buffer !== 'undefined' && typeof process !== 'undefined' && typeof process.versions !== 'undefined' && process.versions.node); + +let Buffer_from: typeof Buffer.from; + +if(typeof Buffer !== 'undefined') { + let nbfs = !Buffer.from; + if(!nbfs) try { + Buffer.from("foo", "utf8"); + } catch(e) { nbfs = true; } + Buffer_from = nbfs ? ((buf, enc?: string): Buffer => (enc) ? new Buffer(buf, (enc as BufferEncoding)) : new Buffer(buf)) : Buffer.from.bind(Buffer); + if(!Buffer.alloc) Buffer.alloc = function(n: number): Buffer { return new Buffer(n); }; + if(!Buffer.allocUnsafe) Buffer.allocUnsafe = function(n: number): Buffer { return new Buffer(n); }; +} + +export { Buffer_from, has_buf }; + +export const new_raw_buf = (len: number): Buffer|number[] => has_buf ? Buffer.alloc(len) : new Array(len); + +export const new_unsafe_buf = (len: number): Buffer|number[] => has_buf ? Buffer.allocUnsafe(len) : new Array(len); + +export const _chr = (c: number): string => String.fromCharCode(c); + +export const chr0 = /\u0000/g; // eslint-disable-line no-control-regex +export const chr1 = /[\u0001-\u0006]/g; // eslint-disable-line no-control-regex + +// --- + +const read_double_le = (b: RawBytes, idx: number): number => { + const s = 1 - 2 * (b[idx + 7] >>> 7); + let e = ((b[idx + 7] & 0x7f) << 4) + ((b[idx + 6] >>> 4) & 0x0f); + let m = (b[idx+6]&0x0f); + for(let i = 5; i >= 0; --i) m = m * 256 + b[idx + i]; + if(e == 0x7ff) return m == 0 ? (s * Infinity) : NaN; + if(e == 0) e = -1022; + else { e -= 1023; m += Math.pow(2,52); } + return s * Math.pow(2, e - 52) * m; +}; + +const write_double_le = (b: RawBytes, v: number, idx: number): void => { + const bs = ((((v < 0) || (1/v == -Infinity)) ? 1 : 0) << 7); + let e = 0, m = 0; + const av = bs ? (-v) : v; + if(!isFinite(av)) { e = 0x7ff; m = isNaN(v) ? 0x6969 : 0; } + else if(av == 0) e = m = 0; + else { + e = Math.floor(Math.log(av) / Math.LN2); + m = av * Math.pow(2, 52 - e); + if((e <= -1023) && (!isFinite(m) || (m < Math.pow(2,52)))) { e = -1022; } + else { m -= Math.pow(2,52); e+=1023; } + } + for(let i = 0; i <= 5; ++i, m/=256) b[idx + i] = m & 0xff; + b[idx + 6] = ((e & 0x0f) << 4) | (m & 0xf); + b[idx + 7] = (e >> 4) | bs; +}; + +let __toBuffer = (bufs/*:Array >*/): RawBytes => { + const x: number[] =[]; + for(let i=0; i b[idx]; +const __readUInt16LE = (b: RawBytes, idx: number): number => (b[idx+1]*(1<<8))+b[idx]; +const __readInt16LE = (b: RawBytes, idx: number): number => { const u = (b[idx+1]*(1<<8))+b[idx]; return (u < 0x8000) ? u : ((0xffff - u + 1) * -1); }; +const __readUInt32LE = (b: RawBytes, idx: number): number => b[idx+3]*(1<<24)+(b[idx+2]<<16)+(b[idx+1]<<8)+b[idx]; +const __readInt32LE = (b: RawBytes, idx: number): number => (b[idx+3]<<24)|(b[idx+2]<<16)|(b[idx+1]<<8)|b[idx]; +const __readInt32BE = (b: RawBytes, idx: number): number => (b[idx]<<24)|(b[idx+1]<<16)|(b[idx+2]<<8)|b[idx+3]; + +let __utf16le = (b: RawBytes, s: number, e: number): string => { + const ss: string[] = []; + for(let i=s; i 0 ? __utf8(b, i+4,i+4+len-1) : "";}; +const ___lpstr = __lpstr; +let __cpstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";}; +const ___cpstr = __cpstr; +let __lpwstr = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = 2*__readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len-1) : "";}; +const ___lpwstr = __lpwstr; +let __lpp4, ___lpp4; +__lpp4 = ___lpp4 = function lpp4_(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf16le(b, i+4,i+4+len) : "";}; +const ___8lpp4 = function(b/*:RawBytes|CFBlob*/,i: number): string { const len = __readUInt32LE(b,i); return len > 0 ? __utf8(b, i+4,i+4+len) : "";}; +let __8lpp4 = ___8lpp4; +const ___double = (b/*:RawBytes|CFBlob*/, idx: number): number => read_double_le(b, idx); +let __double = ___double; + +if(has_buf) { + __utf16le = (b/*:RawBytes|CFBlob*/,s: number,e: number): string => (!Buffer.isBuffer(b)) ? ___utf16le(b,s,e) : b.toString('utf16le',s,e).replace(chr0,''); + __hexlify = (b/*:RawBytes|CFBlob*/,s: number,l: number): string => Buffer.isBuffer(b) ? b.toString('hex',s,s+l) : ___hexlify(b,s,l); + __lpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";}; + __cpstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___cpstr(b, i); const len = b.readUInt32LE(i); return len > 0 ? b.toString('utf8',i+4,i+4+len-1) : "";}; + __lpwstr = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpwstr(b, i); const len = 2*b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len-1);}; + __lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf16le',i+4,i+4+len);}; + __8lpp4 = (b/*:RawBytes|CFBlob*/, i: number): string => { if(!Buffer.isBuffer(b)) return ___8lpp4(b, i); const len = b.readUInt32LE(i); return b.toString('utf8',i+4,i+4+len);}; + __utf8 = (b/*:RawBytes|CFBlob*/, s: number, e: number): string => (Buffer.isBuffer(b)) ? b.toString('utf8',s,e) : ___utf8(b,s,e); + __toBuffer = (bufs): RawBytes => (bufs[0].length > 0 && Buffer.isBuffer(bufs[0][0])) ? Buffer.concat(bufs[0]) : ___toBuffer(bufs); + __double = (b/*:RawBytes|CFBlob*/, i: number): number => (Buffer.isBuffer(b)) ? b.readDoubleLE(i) : ___double(b,i); +} + +function ReadShift(size: 1): number; +function ReadShift(size: 2): number; +function ReadShift(size: 2, t: "i"): number; +function ReadShift(size: 4): number; +function ReadShift(size: 4, t: "i"): number; +function ReadShift(size: 8, t: "f"): number; +function ReadShift(size: number, t: "cstr"): string; +function ReadShift(size: number, t: "cpstr"): string; +function ReadShift(size: number, t: "_wstr"): string; +function ReadShift(size: number, t?: string): number|string { + let o="", oI = 0, oR, w, vv, i, loc; + const oo = []; + switch(t) { + case 'dbcs': + loc = this.l; + if(has_buf && Buffer.isBuffer(this)) o = this.slice(this.l, this.l+2*size).toString("utf16le"); + else for(i = 0; i < size; ++i) { o+=String.fromCharCode(__readUInt16LE(this, loc)); loc+=2; } + size *= 2; + break; + + case 'utf8': o = __utf8(this, this.l, this.l + size); break; + case 'utf16le': size *= 2; o = __utf16le(this, this.l, this.l + size); break; + + case 'wstr': + return ReadShift.call(this, size, 'dbcs'); + + /* [MS-OLEDS] 2.1.4 LengthPrefixedAnsiString */ + case 'lpstr-ansi': o = __lpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break; + case 'lpstr-cp': o = __cpstr(this, this.l); size = 4 + __readUInt32LE(this, this.l); break; + /* [MS-OLEDS] 2.1.5 LengthPrefixedUnicodeString */ + case 'lpwstr': o = __lpwstr(this, this.l); size = 4 + 2 * __readUInt32LE(this, this.l); break; + /* [MS-OFFCRYPTO] 2.1.2 Length-Prefixed Padded Unicode String (UNICODE-LP-P4) */ + case 'lpp4': size = 4 + __readUInt32LE(this, this.l); o = __lpp4(this, this.l); if(size & 0x02) size += 2; break; + /* [MS-OFFCRYPTO] 2.1.3 Length-Prefixed UTF-8 String (UTF-8-LP-P4) */ + case '8lpp4': size = 4 + __readUInt32LE(this, this.l); o = __8lpp4(this, this.l); if(size & 0x03) size += 4 - (size & 0x03); break; + + case 'cstr': size = 0; o = ""; + while((w=__readUInt8(this, this.l + size++))!==0) oo.push(String.fromCharCode(w)); + o = oo.join(""); break; + case '_wstr': size = 0; o = ""; + while((w=__readUInt16LE(this,this.l +size))!==0){oo.push(String.fromCharCode(w));size+=2;} + size+=2; o = oo.join(""); break; + + /* sbcs and dbcs support continue records in the SST way TODO codepages */ + case 'dbcs-cont': o = ""; loc = this.l; + for(i = 0; i < size; ++i) { + if(this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(String.fromCharCode(__readUInt16LE(this, loc))); + loc+=2; + } o = oo.join(""); size *= 2; break; + + case 'cpstr': + /* falls through */ + case 'sbcs-cont': o = ""; loc = this.l; + for(i = 0; i != size; ++i) { + if(this.lens && this.lens.indexOf(loc) !== -1) { + w = __readUInt8(this, loc); + this.l = loc + 1; + vv = ReadShift.call(this, size-i, w ? 'dbcs-cont' : 'sbcs-cont'); + return oo.join("") + vv; + } + oo.push(String.fromCharCode(__readUInt8(this, loc))); + loc+=1; + } o = oo.join(""); break; + + default: + switch(size) { + case 1: oI = __readUInt8(this, this.l); this.l++; return oI; + case 2: oI = (t === 'i' ? __readInt16LE : __readUInt16LE)(this, this.l); this.l += 2; return oI; + case 4: case -4: + if(t === 'i' || ((this[this.l+3] & 0x80)===0)) { oI = ((size > 0) ? __readInt32LE : __readInt32BE)(this, this.l); this.l += 4; return oI; } + else { oR = __readUInt32LE(this, this.l); this.l += 4; } return oR; + case 8: case -8: + if(t === 'f') { + if(size == 8) oR = __double(this, this.l); + else oR = __double([this[this.l+7],this[this.l+6],this[this.l+5],this[this.l+4],this[this.l+3],this[this.l+2],this[this.l+1],this[this.l+0]], 0); + this.l += 8; return oR; + } else size = 8; + /* falls through */ + case 16: o = __hexlify(this, this.l, size); break; + }} + this.l+=size; return o; +} + +const __writeUInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); b[idx+2] = ((val >>> 16) & 0xFF); b[idx+3] = ((val >>> 24) & 0xFF); }; +const __writeInt32LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >> 8) & 0xFF); b[idx+2] = ((val >> 16) & 0xFF); b[idx+3] = ((val >> 24) & 0xFF); }; +const __writeUInt16LE = (b/*:RawBytes|CFBlob*/, val: number, idx: number): void => { b[idx] = (val & 0xFF); b[idx+1] = ((val >>> 8) & 0xFF); }; + +function WriteShift(t: number, val: string|number, f?: string): void { + let size = 0, i = 0; + if(f === 'dbcs') { + if(typeof val !== 'string') throw new Error("expected string"); + for(i = 0; i != val.length; ++i) __writeUInt16LE(this, val.charCodeAt(i), this.l + 2 * i); + size = 2 * val.length; + } else if(f === 'sbcs') { + { + val = (val as string).replace(/[^\x00-\x7F]/g, "_"); // eslint-disable-line no-control-regex + for(i = 0; i != val.length; ++i) this[this.l + i] = (val.charCodeAt(i) & 0xFF); + } + size = val.length; + } else if(f === 'hex') { + for(; i < t; ++i) { + this[this.l++] = (parseInt((val as string).slice(2*i, 2*i+2), 16)||0); + } return this; + } else if(f === 'utf16le') { + /*:: if(typeof val !== "string") throw new Error("unreachable"); */ + const end: number = Math.min(this.l + t, this.length); + for(i = 0; i < Math.min((val as string).length, t); ++i) { + const cc = (val as string).charCodeAt(i); + this[this.l++] = (cc & 0xff); + this[this.l++] = (cc >> 8); + } + while(this.l < end) this[this.l++] = 0; + return this; + } else if(typeof val === 'number') switch(t) { + case 1: size = 1; this[this.l] = val&0xFF; break; + case 2: size = 2; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; break; + case 3: size = 3; this[this.l] = val&0xFF; val >>>= 8; this[this.l+1] = val&0xFF; val >>>= 8; this[this.l+2] = val&0xFF; break; + case 4: size = 4; __writeUInt32LE(this, val, this.l); break; + case 8: size = 8; if(f === 'f') { write_double_le(this, val, this.l); break; } + /* falls through */ + case 16: break; + case -4: size = 4; __writeInt32LE(this, val, this.l); break; + } + this.l += size; return this; +} + +function CheckField(hexstr: string, fld: string): void { + const m = __hexlify(this,this.l,hexstr.length>>1); + if(m !== hexstr) throw new Error(fld + 'Expected ' + hexstr + ' saw ' + m); + this.l += hexstr.length>>1; +} + +const prep_blob = (blob: PreppedBytes, pos: number): void => { + blob.l = pos; + blob.read_shift = ReadShift; + blob.chk = CheckField; + blob.write_shift = WriteShift; +}; + +const new_buf = (sz: number): PreppedBytes => { + const o = (new_raw_buf(sz) as PreppedBytes); + prep_blob(o, 0); + return o; +}; + +export { ReadShift, WriteShift, CheckField, prep_blob, new_buf, __utf16le }; + +// --- + +const __bconcat = function(bufs/*:Array*/): Buffer | Uint8Array | number[] { + let is_all_arrays = true; + for(let w = 0; w < bufs.length; ++w) if(!Array.isArray(bufs[w])) is_all_arrays = false; + if(is_all_arrays) return [].concat(...bufs); + let maxlen = 0, i = 0; + for(i = 0; i < bufs.length; ++i) maxlen += bufs[i].length; + const o = new Uint8Array(maxlen); + for(i = 0, maxlen = 0; i < bufs.length; maxlen += bufs[i].length, ++i) o.set(bufs[i], maxlen); + return o; +}; +let bconcat = __bconcat; + +if(has_buf) bconcat = (bufs): Buffer | Uint8Array | number[] => Buffer.isBuffer(bufs[0]) ? Buffer.concat(bufs) : [].concat(...bufs); + +export { bconcat }; diff --git a/src/wmf.ts b/src/wmf.ts new file mode 100644 index 0000000..0e7d8f9 --- /dev/null +++ b/src/wmf.ts @@ -0,0 +1,533 @@ +/*! wmf.js (C) 2020-present SheetJS LLC -- https://sheetjs.com */ +import { PreppedBytes, RawBytes, bconcat, prep_blob } from './util'; +import { WMFRecords, WMFEscapes } from './Records'; + +export interface Brush { + /** Style (MS-WMF 2.1.1.4) */ + Style?: Number; + /** Brush color RGB */ + Color?: number; + /** Hatch Type (2.1.1.12 if brush is hatched) */ + Hatch?: number; +} + +export interface Pen { + Style?: number; + Width?: number; + Color?: number; +} + +export interface Font { + Name?: string; + Height?: number; + Italic?: boolean; + Weight?: number; + Angle?: number; +} + +export interface PlaybackDeviceContextState { + /** Mapping mode (MS-WMF 2.1.1.16) */ + MapMode?: number; + /** Output window origin (X, Y) */ + Origin?: [number, number]; + /** Output window extents (X, Y) */ + Extent?: [number, number]; + /** Background Mix Mode (MS-WMF 2.1.1.20) */ + BkMode?: number; + /** Polygon fill mode (MS-WMF 2.1.1.25) */ + PolyFillMode?: number; + /** Bitmap stretching mode (MS-WMF 2.1.1.30) */ + StretchMode?: number; + /** Text alignment mode (MS-WMF 2.1.2.3 / 2.1.2.4) */ + TextAlignmentMode?: number; + /** Text foreground color RGB */ + TextColor?: number; + /** Brush */ + Brush?: Brush; + /** Font */ + Font?: Font; + /** Pen */ + Pen?: Pen; + /** Clipping Region (x,y) LT (x,y) RB */ + ClipRect?: [[number, number], [number, number]]; +} + +/** [x, y] */ +export type Point = [ number, number ]; + +export interface ActionCommon { + /** State */ + s?: PlaybackDeviceContextState; +} + +/** Draw Text */ +export interface ActionText extends ActionCommon { + /** Action Type */ + t: "text"; + + /** Text */ + v: string; + + /** Origin */ + p?: Point; +} + +/** Draw Polygon (shape with stroke/fill) / Polyline (stroke only) */ +export interface ActionPoly extends ActionCommon { + /** Action Type */ + t: "poly"; + + /** Points */ + p: Point[]; + + /** Polygon (true) or Polyline (false) */ + g: boolean; +} + +export interface ActionRaster { + /** Raster Operaton 2.1.1.31 */ + rop?: number; +} + +export interface ActionCpy extends ActionCommon, ActionRaster { + t: "cpy"; + + /** Source [[X, W], [Y, H]] */ + src: [[number, number], [number, number]]; + + dst: Point; + + data?: any; +} + +export interface ActionStr extends ActionCommon, ActionRaster { + t: "str"; + + /** Source [[X, W], [Y, H]] */ + src: [[number, number], [number, number]]; + + /** Dest [[X, W], [Y, H]] */ + dst: [[number, number], [number, number]]; + + data?: any; +} + +export type Action = ActionText | ActionPoly | ActionCpy | ActionStr; + +const parse_emf = (data: PreppedBytes): void => { + //try { require("fs").writeFileSync("out.emf", data); } catch(e) {} +} + +/* 2.2.2.9 */ +const parse_dib = (data: PreppedBytes) => { + if(data.length == 0) return null; + prep_blob(data, 0); + + /* DIBHeaderInfo */ + const HeaderSize = data.read_shift(4); + let Width = 0, Height = 0, Planes = 0, BitCount = 0; + let Compression = 0, ImageSize = 0, XPelsPerMeter = 0, YPelsPerMeter = 0, ColorUsed = 0, ColorImportant = 0; + if(HeaderSize == 0x0C) { + Width = data.read_shift(2); + Height = data.read_shift(2); + } else { + Width = data.read_shift(4, 'i'); + Height = data.read_shift(4, 'i'); + } + Planes = data.read_shift(2); + BitCount = data.read_shift(2); + + const out: object = { + Width, + Height, + BitCount, + }; + + if(HeaderSize != 0x0C) { + Compression = data.read_shift(4); + ImageSize = data.read_shift(4); + XPelsPerMeter = data.read_shift(4, 'i'); + YPelsPerMeter = data.read_shift(4, 'i'); + ColorUsed = data.read_shift(4); + ColorImportant = data.read_shift(4); + out["Compression"] = Compression; + if(BitCount == 24 && ImageSize > Height * 3 * Width) Width = out["Width"] = ImageSize / (Height * 3); + } + + /* Colors */ + /* BitmapBuffer */ + if(ImageSize == data.length - data.l) { + out["ImageData"] = data.slice(data.l, data.length); + prep_blob(out["ImageData"], 0); + } + return out; +} + +const add_to_objects = (objects: PlaybackDeviceContextState[], obj: PlaybackDeviceContextState): void => { + let found = false; + for(var i = 0; i < objects.length; ++i) if(!objects[i]) { objects[i] = obj; found = true; } + if(!found) objects.push(obj); +} + +export const get_actions_prepped_bytes = (data: PreppedBytes): Action[] => { + const out: Action[] = []; + + /* 2.3.22 META_HEADER */ + // Type (2 bytes) must be 1 or 2 + let h = data.read_shift(2); + if(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`; + // HeaderSize expected to be 9 + if((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`; + // Version (2 bytes) 1 or 3 + h = data.read_shift(2); + if(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`; + // SizeLow + // SizeHigh + // #Objects + // MaxRecord + // NumberOfMembers + data.l = 18; + + let rt = 0; + + /* used for EMF */ + let escapecnt = 0; + let CommentRecordCount = 0; + let RemainingBytes = 0; + let EnhancedMetafileDataSize = 0; + let bufs: RawBytes[] = []; + + let objects: PlaybackDeviceContextState[] = []; + let states: PlaybackDeviceContextState[] = []; + let state: PlaybackDeviceContextState = {}; + let sidx = -1; + + while(data.l < data.length) { + h = data.read_shift(4); + const end = data.l + h*2 - 4; + + rt = data.read_shift(2); + let Record = WMFRecords[rt]; + if(rt == 0x0000) break; // META_EOF + + switch(rt) { + case 0x0626: { // META_ESCAPE + const EscapeFunction = data.read_shift(2); + const Escape = WMFEscapes[EscapeFunction]; + //console.log("::", Escape); + /* 2.3.6 */ + switch(EscapeFunction) { + case 0x000F: { // META_ESCAPE_ENHANCED_METAFILE + const ByteCount = data.read_shift(2); + let tmp = data.read_shift(4); + if(tmp != 0x43464D57) throw `Escape: Comment ID 0x${tmp.toString(16)} != 0x43464D57`; + tmp = data.read_shift(4); + if(tmp != 0x00000001) throw `Escape: Comment Type 0x${tmp.toString(16)} != 0x00000001`; + tmp = data.read_shift(4); + if(tmp != 0x00010000) throw `Escape: Version 0x${tmp.toString(16)} != 0x00010000`; + + const Checksum = data.read_shift(2); + + data.l += 4; // Flags + if(escapecnt == 0) { + CommentRecordCount = data.read_shift(4); // total number of records + } else { + const _CommentRecordCount = data.read_shift(4); + if(_CommentRecordCount != CommentRecordCount) throw `Escape: CommentRecordCount ${_CommentRecordCount} != ${CommentRecordCount}`; + } + const CurrentRecordSize = data.read_shift(4); // size of this record + const _RemainingBytes = data.read_shift(4); + if(escapecnt > 0 && CurrentRecordSize + _RemainingBytes != RemainingBytes) throw `Escape: ${RemainingBytes} != ${CurrentRecordSize} + ${_RemainingBytes}`; + RemainingBytes = _RemainingBytes; + const _EnhancedMetafileDataSize = data.read_shift(4); + if(escapecnt == 0) { + if(_EnhancedMetafileDataSize != CurrentRecordSize + _RemainingBytes) throw `Escape: ${_EnhancedMetafileDataSize} != ${CurrentRecordSize} + ${_RemainingBytes}`; + EnhancedMetafileDataSize = _EnhancedMetafileDataSize; + } else if(EnhancedMetafileDataSize != _EnhancedMetafileDataSize) throw `Escape: ${EnhancedMetafileDataSize} != ${_EnhancedMetafileDataSize}`; + + if(ByteCount != (end - data.l) + 34) throw `Escape: Sizes ${ByteCount} != ${end - data.l} + 34` + if(end - data.l != CurrentRecordSize) throw `Escape: CRSize ${CurrentRecordSize} != ${end - data.l}`; + bufs.push(data.slice(data.l, end)); + ++escapecnt; + if(escapecnt == CommentRecordCount) { + const prepped: PreppedBytes = bconcat(bufs) as PreppedBytes; + prep_blob(prepped, 0); + parse_emf(prepped); + } + } break; + default: throw `Escape: Unrecognized META_ESCAPE Type 0x${EscapeFunction.toString(16)}`; + } + } break; + + // #region 2.3.1 Bitmap Record Types + + case 0x0940: { // 2.3.1.2 META_DIBBITBLT + const has_bitmap = h != (rt>>8)+3; + const RasterOperation = data.read_shift(4); + const YSrc = data.read_shift(2, "i"); + const XSrc = data.read_shift(2, "i"); + if(!has_bitmap) data.l += 2; + const Height = data.read_shift(2, "i"); + const Width = data.read_shift(2, "i"); + const YDest = data.read_shift(2, "i"); + const XDest = data.read_shift(2, "i"); + const res: ActionCpy = { + t: "cpy", + src: [[XSrc, Width], [YSrc, Height]], + dst: [XDest, YDest], + rop: RasterOperation, + s: Object.assign({}, state) + }; + if(has_bitmap) { + const DIB = parse_dib(data.slice(data.l, end) as PreppedBytes); + res.data = DIB; + } + out.push(res); + } break; + + case 0x0B41: { // 2.3.1.3 META_DIBSTRETCHBLT + const has_bitmap = h != (rt>>8)+3; + const RasterOperation = data.read_shift(4); + const SrcHeight = data.read_shift(2, "i"); + const SrcWidth = data.read_shift(2, "i"); + const YSrc = data.read_shift(2, "i"); + const XSrc = data.read_shift(2, "i"); + if(!has_bitmap) data.l += 2; + const DestHeight = data.read_shift(2, "i"); + const DestWidth = data.read_shift(2, "i"); + const YDest = data.read_shift(2, "i"); + const XDest = data.read_shift(2, "i"); + const res: ActionStr = { + t: "str", + src: [[XSrc, SrcWidth], [YSrc, SrcHeight]], + dst: [[XDest, DestWidth], [YDest, DestHeight]], + rop: RasterOperation, + s: Object.assign({}, state) + }; + if(has_bitmap) { + const DIB = parse_dib(data.slice(data.l, end) as PreppedBytes); + res.data = DIB; + } + out.push(res); + } break; + + // #endregion + + // #region 2.3.3 Drawing Record Types + + case 0x0A32: { // 2.3.3.5 META_EXTTEXTOUT + const Y = data.read_shift(2); + const X = data.read_shift(2); + const StringLength = data.read_shift(2); + const fwOpts = data.read_shift(2); // 2.1.2.2 + if(fwOpts & 0x06) { + data.l += 8; // Rectangle 2.2.2.18 (for clipping/opaquing) + } + const str = data.read_shift(StringLength, 'cpstr'); + if(data.l < end){/* TODO: Dx */} + out.push({t: "text", v: str, p: [X, Y], s: Object.assign({}, state)}); + /* TODO!! */ + } break; + + case 0x0325: // 2.3.3.14 META_POLYLINE + case 0x0324: // 2.3.3.15 META_POLYGON + { + const nPoints = data.read_shift(2); + const points: Array = []; + for(let i = 0; i < nPoints; ++i) points.push([data.read_shift(2), data.read_shift(2)]) + out.push({t: "poly", p: points, g: rt !== 0x0325, s: state}); + } break; + + case 0x0538: { // 2.3.3.16 META_POLYPOLYGON + const nPolygons = data.read_shift(2); + const polys: Array > = []; + const szs: number[] = []; + /* 2.2.2.17 PolyPolygon */ + for(let i = 0; i < nPolygons; ++i) szs[i] = data.read_shift(2); + for(let i = 0; i < szs.length; ++i) { + polys[i] = []; + for(let j = 0; j < szs[i]; ++j) polys[i].push([data.read_shift(2), data.read_shift(2)]) + out.push({t: "poly", p: polys[i], g: true, s: state}); + } + } break; + + // #endregion + + // #region 2.3.4 Object Record Types + + case 0x02FC: { // 2.3.4.1 META_CREATEBRUSHINDIRECT + const obj: PlaybackDeviceContextState = {}; + obj.Brush = { + Style: data.read_shift(2), + Color: data.read_shift(4), + Hatch: data.read_shift(2) + }; + add_to_objects(objects, obj); + } break; + + case 0x02FB: { // 2.3.4.2 META_CREATEFONTINDIRECT + const obj: PlaybackDeviceContextState = {}; + obj.Font = {}; + /* 2.2.1.2 Font TODO!! */ + const Height = data.read_shift(2, "i"); + const Width = data.read_shift(2, "i"); + const Escapement = data.read_shift(2, "i"); + const Orientation = data.read_shift(2, "i"); + const Weight = data.read_shift(2, "i"); + const Italic = !!data.read_shift(1); + const Underline = !!data.read_shift(1); + const StrikeOut = !!data.read_shift(1); + const CharSet = data.read_shift(1); + const OutPrecision = data.read_shift(1); + const ClipPrecision = data.read_shift(1); + const Quality = data.read_shift(1); + const PitchAndFamily = data.read_shift(1); + const Facename = data.read_shift(32, "cstr"); + obj.Font.Name = Facename; + obj.Font.Height = Height; + obj.Font.Weight = Weight; + obj.Font.Italic = Italic; + obj.Font.Angle = Escapement / 10; + add_to_objects(objects, obj); + } break; + + case 0x02FA: { // 2.3.4.5 META_CREATEPENINDIRECT + const obj: PlaybackDeviceContextState = {}; + obj.Pen = { + Style: data.read_shift(2), + Width: data.read_shift(4) & 0xFF, + Color: data.read_shift(4) + }; + add_to_objects(objects, obj); + } break; + + case 0x01F0: { // 2.3.4.7 META_DELETEOBJECT + const ObjectIndex = data.read_shift(2); + //console.log("DELETE", ObjectIndex, objects[ObjectIndex]); + objects[ObjectIndex] = null; + } break; + + case 0x012C: { // 2.3.4.9 META_SELECTCLIPREGION + const Region = data.read_shift(2); + //console.log("CLIPREGION", Region, objects[Region]); + //Object.assign(state, objects[Region]); + } break; + + case 0x012D: { // 2.3.4.10 META_SELECTOBJECT + const ObjectIndex = data.read_shift(2); + //console.log("SELECT", ObjectIndex, objects[ObjectIndex]); + Object.assign(state, objects[ObjectIndex]); + // TODO!! + } break; + + // #endregion + + // #region 2.3.5 State Record Types + + case 0x0416: // 2.3.5.3 META_INTERSECTCLIPRECT + state.ClipRect = [[0,0],[0,0]]; + state.ClipRect[1][1] = data.read_shift(2); + state.ClipRect[1][0] = data.read_shift(2); + state.ClipRect[0][1] = data.read_shift(2); + state.ClipRect[0][0] = data.read_shift(2); + break; + + case 0x0127: { // 2.3.5.10 META_RESTOREDC + const nSavedDC = data.read_shift(2, 'i'); + state = states[sidx = (nSavedDC >= 0 ? nSavedDC : sidx + nSavedDC)]; + } break; + + case 0x001E: // 2.3.5.11 META_SAVEDC + states.push(state); + sidx = states.length - 1; + state = JSON.parse(JSON.stringify(state)); + break; + + case 0x0102: // 2.3.5.15 META_SETBKMODE + state.BkMode = data.read_shift(2); + break; + + case 0x0103: // 2.3.5.17 META_SETMAPMODE + state.MapMode = data.read_shift(2); + break; + + case 0x0106: // 2.3.5.20 META_SETPOLYFILLMODE + state.PolyFillMode = data.read_shift(2); + break; + + case 0x0107: // 2.3.5.23 META_SETSTRETCHBLTMODE + state.StretchMode = data.read_shift(2); + break; + + case 0x012E: // 2.3.5.24 META_SETTEXTALIGN + state.TextAlignmentMode = data.read_shift(2); + break; + + case 0x0209: // 2.3.5.26 META_SETTEXTCOLOR + state.TextColor = data.read_shift(4); + break; + + case 0x020C: // 2.3.5.30 META_SETWINDOWEXT + state.Extent = [0, 0]; + state.Extent[1] = data.read_shift(2); + state.Extent[0] = data.read_shift(2); + break; + + case 0x020B: // 2.3.5.31 META_SETWINDOWORG + state.Origin = [0, 0]; + state.Origin[1] = data.read_shift(2); + state.Origin[0] = data.read_shift(2); + break; + + // #endregion + + default: + if(!Record) throw `Record: Unrecognized type 0x${rt.toString(16)}`; + console.log(Record); + } + data.l = end; + //if(rt != 0x0626) console.log(Record); + } + if(rt !== 0) throw `Record: Last Record Type ${rt} is not EOF type`; + return out; +} + +export const image_size_prepped_bytes = (data: PreppedBytes): [number, number] => { + const origin: Point = [NaN, NaN], extents: Point = [NaN, NaN]; + + /* 2.3.22 META_HEADER */ + // Type (2 bytes) must be 1 or 2 + let h = data.read_shift(2); + if(h != 1 && h != 2) throw `Header: Type ${h} must be 1 or 2`; + // HeaderSize expected to be 9 + if((h = data.read_shift(2)) != 9) throw `Header: HeaderSize ${h} must be 9`; + // Version (2 bytes) 1 or 3 + h = data.read_shift(2); + if(h != 0x0100 && h != 0x0300) throw `Header: Version ${h} must be 0x0100 or 0x0300`; + data.l = 18; + + let rt = 0; + + while(data.l < data.length) { + h = data.read_shift(4); + const end = data.l + h*2 - 4; + + rt = data.read_shift(2); + if(rt == 0x0000) break; // META_EOF + + switch(rt) { + case 0x020C: // 2.3.5.30 META_SETWINDOWEXT + extents[1] = data.read_shift(2); + extents[0] = data.read_shift(2); + break; + + case 0x020B: // 2.3.5.31 META_SETWINDOWORG + origin[1] = data.read_shift(2); + origin[0] = data.read_shift(2); + break; + } + data.l = end; + } + + return [extents[0] - origin[0], extents[1] - origin[1]]; +}; \ No newline at end of file diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..ba70f38 --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,2 @@ +.cache +dist diff --git a/test/fetch.html b/test/fetch.html new file mode 100644 index 0000000..a0dc628 --- /dev/null +++ b/test/fetch.html @@ -0,0 +1,17 @@ + + + + + + diff --git a/test/filereader.html b/test/filereader.html new file mode 100644 index 0000000..4928a6d --- /dev/null +++ b/test/filereader.html @@ -0,0 +1,21 @@ + + +
+ + + + diff --git a/test/node-canvas.js b/test/node-canvas.js new file mode 100644 index 0000000..33dabf0 --- /dev/null +++ b/test/node-canvas.js @@ -0,0 +1,20 @@ +const fs = require("fs"); +const { createCanvas, createImageData } = require("canvas"); +const WMF = require("../"); + +/* WMF uses ImageData -- make it visible to the library */ +global.ImageData = createImageData; + +/* read data */ +const data = fs.readFileSync(process.argv[2] || "./static/image1.wmf"); + +/* create canvas */ +const size = WMF.image_size(data); +const canvas = createCanvas(size[0], size[1]); + +/* do it! */ +WMF.draw_canvas(data, canvas); + +/* export to file */ +const res = canvas.toBuffer("image/png"); +fs.writeFileSync("out.png", res); \ No newline at end of file diff --git a/test/parcel.html b/test/parcel.html new file mode 100644 index 0000000..4f8e579 --- /dev/null +++ b/test/parcel.html @@ -0,0 +1,17 @@ + + + + + + diff --git a/test/parcel.js b/test/parcel.js new file mode 100644 index 0000000..1e73f73 --- /dev/null +++ b/test/parcel.js @@ -0,0 +1,38 @@ +import * as WMF from '../'; +import * as fs from 'fs'; + +Buffer; // this line is required by Parcel to pull in the buffer shim + +const data = fs.readFileSync("static/image1.wmf"); +const domelt/*: HTMLCanvasElement*/ = document.getElementById("canvas")/* as HTMLCanvasElement*/; + +const mode = window["MODE"] || "OFFSCREEN"; +console.log(mode); +switch(mode) { + case "DIRECT": { + /* draw_canvas automatically resizes the canvas */ + WMF.draw_canvas(data, domelt); + } break; + case "INDIRECT": { + const newelt = document.createElement("canvas"); + WMF.draw_canvas(data, newelt); + /* the copy_canvas helper performs a resize of the new canvas */ + copy_canvas(domelt, newelt); + } break; + case "OFFSCREEN": { + /* OffscreenCanvas requires the size beforehand */ + const size = WMF.image_size(data); + const newelt = new OffscreenCanvas(size[0], size[1]); + WMF.draw_canvas(data, newelt); + copy_canvas(domelt, newelt); + } break; +} + +function copy_canvas(dst, src) { + dst.height = src.height; + dst.width = src.width; + const ctxdst = dst.getContext('2d'); + const ctxsrc = src.getContext('2d'); + const imdata = ctxsrc.getImageData(0, 0, domelt.width, domelt.height); + ctxdst.putImageData(imdata, 0, 0); +} \ No newline at end of file diff --git a/test/wmf.js b/test/wmf.js new file mode 120000 index 0000000..6f10bee --- /dev/null +++ b/test/wmf.js @@ -0,0 +1 @@ +../dist/wmf.js \ No newline at end of file diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..9379112 --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,10 @@ +{ + "compilerOptions": { + "target": "es5", + "moduleResolution": "node", + "outDir": "./js", + "lib": [ "es5", "DOM" ], + "sourceMap": true, + "noImplicitReturns": true + } +}