From 1dd82b259b4f033a77bebb0682d80278fb5338da Mon Sep 17 00:00:00 2001
From: "Marko.Taht"
Date: Mon, 5 Oct 2020 13:33:08 +0300
Subject: [PATCH 1/9] Replace Deflater with pako
---
bower.json | 3 +
dist/jspdf.es.js | 9742 ++++++++++++++++++-----------------
dist/jspdf.es.js.map | 2 +-
dist/jspdf.es.min.js | 90 +-
dist/jspdf.es.min.js.map | 2 +-
dist/jspdf.node.js | 9798 ++++++++++++++++++-----------------
dist/jspdf.node.js.map | 2 +-
dist/jspdf.node.min.js | 90 +-
dist/jspdf.node.min.js.map | 2 +-
dist/jspdf.umd.js | 9818 ++++++++++++++++++------------------
dist/jspdf.umd.js.map | 2 +-
dist/jspdf.umd.min.js | 88 +-
dist/jspdf.umd.min.js.map | 2 +-
dist/polyfills.es.js | 2 +-
dist/polyfills.umd.js | 2 +-
package-lock.json | 5 +-
package.json | 3 +
rollup.config.js | 6 +
src/libs/pako.js | 7 +
src/modules/filters.js | 14 +-
20 files changed, 14805 insertions(+), 14875 deletions(-)
create mode 100644 src/libs/pako.js
diff --git a/bower.json b/bower.json
index 735c7cd4f..5cf978bbb 100644
--- a/bower.json
+++ b/bower.json
@@ -23,6 +23,9 @@
"dompurify": "^2.0.12",
"html2canvas": "^1.0.0-rc.5"
},
+ "peerDependencies": {
+ "pako": "^1.0.11"
+ },
"devDependencies": {
"@babel/core": "^7.8.4",
"@babel/plugin-external-helpers": "7.2.0",
diff --git a/dist/jspdf.es.js b/dist/jspdf.es.js
index 5d2ade086..6e116e8b2 100644
--- a/dist/jspdf.es.js
+++ b/dist/jspdf.es.js
@@ -1,7 +1,7 @@
/** @license
*
* jsPDF - PDF Document creation from JavaScript
- * Version 2.1.1 Built on 2020-09-07T12:58:19.950Z
+ * Version 2.1.0 Built on 2020-09-24T13:30:44.570Z
* CommitID 00000000
*
* Copyright (c) 2010-2020 James Hall , https://github.com/MrRio/jsPDF
@@ -6385,7 +6385,7 @@ jsPDF.API = {
* @type {string}
* @memberof jsPDF#
*/
-jsPDF.version = "2.1.1";
+jsPDF.version = "2.1.0";
/* global jsPDF */
@@ -14188,5370 +14188,5342 @@ var AcroForm = jsPDF.AcroForm;
};
})(jsPDF.API);
-/**
- * @license
- Copyright (c) 2013 Gildas Lormeau. All rights reserved.
+var pako;
- Redistribution and use in source and binary forms, with or without
- modification, are permitted provided that the following conditions are met:
+(function() {
+ pako = require("pako");
+})();
- 1. Redistributions of source code must retain the above copyright notice,
- this list of conditions and the following disclaimer.
+/**
+ * @license
+ * jsPDF filters PlugIn
+ * Copyright (c) 2014 Aras Abbasi
+ *
+ * Licensed under the MIT License.
+ * http://opensource.org/licenses/mit-license
+ */
- 2. Redistributions in binary form must reproduce the above copyright
- notice, this list of conditions and the following disclaimer in
- the documentation and/or other materials provided with the distribution.
+(function(jsPDFAPI) {
- 3. The names of the authors may not be used to endorse or promote products
- derived from this software without specific prior written permission.
+ var ASCII85Encode = function(a) {
+ var b, c, d, e, f, g, h, i, j, k;
+ // eslint-disable-next-line no-control-regex
+ for (
+ !/[^\x00-\xFF]/.test(a),
+ b = "\x00\x00\x00\x00".slice(a.length % 4 || 4),
+ a += b,
+ c = [],
+ d = 0,
+ e = a.length;
+ e > d;
+ d += 4
+ )
+ (f =
+ (a.charCodeAt(d) << 24) +
+ (a.charCodeAt(d + 1) << 16) +
+ (a.charCodeAt(d + 2) << 8) +
+ a.charCodeAt(d + 3)),
+ 0 !== f
+ ? ((k = f % 85),
+ (f = (f - k) / 85),
+ (j = f % 85),
+ (f = (f - j) / 85),
+ (i = f % 85),
+ (f = (f - i) / 85),
+ (h = f % 85),
+ (f = (f - h) / 85),
+ (g = f % 85),
+ c.push(g + 33, h + 33, i + 33, j + 33, k + 33))
+ : c.push(122);
+ return (
+ (function(a, b) {
+ for (var c = b; c > 0; c--) a.pop();
+ })(c, b.length),
+ String.fromCharCode.apply(String, c) + "~>"
+ );
+ };
- THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
- INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
- INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
- OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
- NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
- EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
+ var ASCII85Decode = function(a) {
+ var c,
+ d,
+ e,
+ f,
+ g,
+ h = String,
+ l = "length",
+ w = 255,
+ x = "charCodeAt",
+ y = "slice",
+ z = "replace";
+ for (
+ "~>" === a[y](-2),
+ a = a[y](0, -2)
+ [z](/\s/g, "")
+ [z]("z", "!!!!!"),
+ c = "uuuuu"[y](a[l] % 5 || 5),
+ a += c,
+ e = [],
+ f = 0,
+ g = a[l];
+ g > f;
+ f += 5
+ )
+ (d =
+ 52200625 * (a[x](f) - 33) +
+ 614125 * (a[x](f + 1) - 33) +
+ 7225 * (a[x](f + 2) - 33) +
+ 85 * (a[x](f + 3) - 33) +
+ (a[x](f + 4) - 33)),
+ e.push(w & (d >> 24), w & (d >> 16), w & (d >> 8), w & d);
+ return (
+ (function(a, b) {
+ for (var c = b; c > 0; c--) a.pop();
+ })(e, c[l]),
+ h.fromCharCode.apply(h, e)
+ );
+ };
-/*
- * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
- * JZlib is based on zlib-1.1.3, so all credit should go authors
- * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
- * and contributors of zlib.
- */
+ var ASCIIHexEncode = function(value) {
+ return (
+ value
+ .split("")
+ .map(function(value) {
+ return ("0" + value.charCodeAt().toString(16)).slice(-2);
+ })
+ .join("") + ">"
+ );
+ };
-// Global
+ var ASCIIHexDecode = function(value) {
+ var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/);
+ value = value.replace(/\s/g, "");
+ if (value.indexOf(">") !== -1) {
+ value = value.substr(0, value.indexOf(">"));
+ }
+ if (value.length % 2) {
+ value += "0";
+ }
+ if (regexCheckIfHex.test(value) === false) {
+ return "";
+ }
+ var result = "";
+ for (var i = 0; i < value.length; i += 2) {
+ result += String.fromCharCode("0x" + (value[i] + value[i + 1]));
+ }
+ return result;
+ };
-var MAX_BITS = 15;
-var D_CODES = 30;
-var BL_CODES = 19;
+ var FlateEncode = function(data) {
+ var arr = [];
+ var i = data.length;
+ var adler32;
-var LENGTH_CODES = 29;
-var LITERALS = 256;
-var L_CODES = LITERALS + 1 + LENGTH_CODES;
-var HEAP_SIZE = 2 * L_CODES + 1;
+ while (i--) {
+ arr[i] = data.charCodeAt(i);
+ }
+ adler32 = jsPDFAPI.adler32cs.from(data);
+ data = pako.deflate(arr);
+ arr = new Uint8Array(data.byteLength + 4);
+ arr.set(data, 0);
+ arr.set(
+ new Uint8Array([
+ adler32 & 0xff,
+ (adler32 >> 8) & 0xff,
+ (adler32 >> 16) & 0xff,
+ (adler32 >> 24) & 0xff
+ ]),
+ data.byteLength
+ );
+ data = arr.reduce(function(data, byte) {
+ return data + String.fromCharCode(byte);
+ }, "");
+ return data;
+ };
-var END_BLOCK = 256;
+ jsPDFAPI.processDataByFilters = function(origData, filterChain) {
+ var i = 0;
+ var data = origData || "";
+ var reverseChain = [];
+ filterChain = filterChain || [];
-// Bit length codes must not exceed MAX_BL_BITS bits
-var MAX_BL_BITS = 7;
+ if (typeof filterChain === "string") {
+ filterChain = [filterChain];
+ }
-// repeat previous bit length 3-6 times (2 bits of repeat count)
-var REP_3_6 = 16;
+ for (i = 0; i < filterChain.length; i += 1) {
+ switch (filterChain[i]) {
+ case "ASCII85Decode":
+ case "/ASCII85Decode":
+ data = ASCII85Decode(data);
+ reverseChain.push("/ASCII85Encode");
+ break;
+ case "ASCII85Encode":
+ case "/ASCII85Encode":
+ data = ASCII85Encode(data);
+ reverseChain.push("/ASCII85Decode");
+ break;
+ case "ASCIIHexDecode":
+ case "/ASCIIHexDecode":
+ data = ASCIIHexDecode(data);
+ reverseChain.push("/ASCIIHexEncode");
+ break;
+ case "ASCIIHexEncode":
+ case "/ASCIIHexEncode":
+ data = ASCIIHexEncode(data);
+ reverseChain.push("/ASCIIHexDecode");
+ break;
+ case "FlateEncode":
+ case "/FlateEncode":
+ data = FlateEncode(data);
+ reverseChain.push("/FlateDecode");
+ break;
+ default:
+ throw new Error(
+ 'The filter: "' + filterChain[i] + '" is not implemented'
+ );
+ }
+ }
-// repeat a zero length 3-10 times (3 bits of repeat count)
-var REPZ_3_10 = 17;
+ return { data: data, reverseChain: reverseChain.reverse().join(" ") };
+ };
+})(jsPDF.API);
-// repeat a zero length 11-138 times (7 bits of repeat count)
-var REPZ_11_138 = 18;
+/**
+ * @license
+ * jsPDF fileloading PlugIn
+ * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)
+ *
+ * Licensed under the MIT License.
+ * http://opensource.org/licenses/mit-license
+ */
-// The lengths of the bit length codes are sent in order of decreasing
-// probability, to avoid transmitting the lengths for unused bit
-// length codes.
+/**
+ * @name fileloading
+ * @module
+ */
+(function(jsPDFAPI) {
-var Buf_size = 8 * 2;
+ /**
+ * @name loadFile
+ * @function
+ * @param {string} url
+ * @param {boolean} sync
+ * @param {function} callback
+ * @returns {string|undefined} result
+ */
+ jsPDFAPI.loadFile = function(url, sync, callback) {
+ return browserRequest(url, sync, callback);
-// JZlib version : "1.0.2"
-var Z_DEFAULT_COMPRESSION = -1;
+ };
-// compression strategy
-var Z_FILTERED = 1;
-var Z_HUFFMAN_ONLY = 2;
-var Z_DEFAULT_STRATEGY = 0;
+ /**
+ * @name loadImageFile
+ * @function
+ * @param {string} path
+ * @param {boolean} sync
+ * @param {function} callback
+ */
+ jsPDFAPI.loadImageFile = jsPDFAPI.loadFile;
-var Z_NO_FLUSH = 0;
-var Z_PARTIAL_FLUSH = 1;
-var Z_FULL_FLUSH = 3;
-var Z_FINISH = 4;
+ function browserRequest(url, sync, callback) {
+ sync = sync === false ? false : true;
+ callback = typeof callback === "function" ? callback : function() {};
+ var result = undefined;
-var Z_OK = 0;
-var Z_STREAM_END = 1;
-var Z_NEED_DICT = 2;
-var Z_STREAM_ERROR = -2;
-var Z_DATA_ERROR = -3;
-var Z_BUF_ERROR = -5;
+ var xhr = function(url, sync, callback) {
+ var request = new XMLHttpRequest();
+ var i = 0;
-// Tree
+ var sanitizeUnicode = function(data) {
+ var dataLength = data.length;
+ var charArray = [];
+ var StringFromCharCode = String.fromCharCode;
-// see definition of array dist_code below
-var _dist_code = [
- 0,
- 1,
- 2,
- 3,
- 4,
- 4,
- 5,
- 5,
- 6,
- 6,
- 6,
- 6,
- 7,
- 7,
- 7,
- 7,
- 8,
- 8,
- 8,
- 8,
- 8,
- 8,
- 8,
- 8,
- 9,
- 9,
- 9,
- 9,
- 9,
- 9,
- 9,
- 9,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 10,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 11,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 12,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 13,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 14,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 15,
- 0,
- 0,
- 16,
- 17,
- 18,
- 18,
- 19,
- 19,
- 20,
- 20,
- 20,
- 20,
- 21,
- 21,
- 21,
- 21,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 28,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29,
- 29
-];
-
-function Tree() {
- var that = this;
-
- // dyn_tree; // the dynamic tree
- // max_code; // largest code with non zero frequency
- // stat_desc; // the corresponding static tree
-
- // Compute the optimal bit lengths for a tree and update the total bit
- // length
- // for the current block.
- // IN assertion: the fields freq and dad are set, heap[heap_max] and
- // above are the tree nodes sorted by increasing frequency.
- // OUT assertions: the field len is set to the optimal bit length, the
- // array bl_count contains the frequencies for each bit length.
- // The length opt_len is updated; static_len is also updated if stree is
- // not null.
- function gen_bitlen(s) {
- var tree = that.dyn_tree;
- var stree = that.stat_desc.static_tree;
- var extra = that.stat_desc.extra_bits;
- var base = that.stat_desc.extra_base;
- var max_length = that.stat_desc.max_length;
- var h; // heap index
- var n, m; // iterate over the tree elements
- var bits; // bit length
- var xbits; // extra bits
- var f; // frequency
- var overflow = 0; // number of elements with bit length too large
-
- for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0;
-
- // In a first pass, compute the optimal bit lengths (which may
- // overflow in the case of the bit length tree).
- tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
-
- for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
- n = s.heap[h];
- bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
- if (bits > max_length) {
- bits = max_length;
- overflow++;
- }
- tree[n * 2 + 1] = bits;
- // We overwrite tree[n*2+1] which is no longer needed
-
- if (n > that.max_code) continue; // not a leaf node
-
- s.bl_count[bits]++;
- xbits = 0;
- if (n >= base) xbits = extra[n - base];
- f = tree[n * 2];
- s.opt_len += f * (bits + xbits);
- if (stree) s.static_len += f * (stree[n * 2 + 1] + xbits);
- }
- if (overflow === 0) return;
-
- // This happens for example on obj2 and pic of the Calgary corpus
- // Find the first bit length which could increase:
- do {
- bits = max_length - 1;
- while (s.bl_count[bits] === 0) bits--;
- s.bl_count[bits]--; // move one leaf down the tree
- s.bl_count[bits + 1] += 2; // move one overflow item as its brother
- s.bl_count[max_length]--;
- // The brother of the overflow item also moves one step up,
- // but this does not affect bl_count[max_length]
- overflow -= 2;
- } while (overflow > 0);
-
- for (bits = max_length; bits !== 0; bits--) {
- n = s.bl_count[bits];
- while (n !== 0) {
- m = s.heap[--h];
- if (m > that.max_code) continue;
- if (tree[m * 2 + 1] !== bits) {
- s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
- tree[m * 2 + 1] = bits;
- }
- n--;
- }
- }
- }
-
- // Reverse the first len bits of a code, using straightforward code (a
- // faster
- // method would use a table)
- // IN assertion: 1 <= len <= 15
- function bi_reverse(
- code, // the value to invert
- len // its bit length
- ) {
- var res = 0;
- do {
- res |= code & 1;
- code >>>= 1;
- res <<= 1;
- } while (--len > 0);
- return res >>> 1;
- }
-
- // Generate the codes for a given tree and bit counts (which need not be
- // optimal).
- // IN assertion: the array bl_count contains the bit length statistics for
- // the given tree and the field len is set for all tree elements.
- // OUT assertion: the field code is set for all tree elements of non
- // zero code length.
- function gen_codes(
- tree, // the tree to decorate
- max_code, // largest code with non zero frequency
- bl_count // number of codes at each bit length
- ) {
- var next_code = []; // next code value for each
- // bit length
- var code = 0; // running code value
- var bits; // bit index
- var n; // code index
- var len;
-
- // The distribution counts are first used to generate the code values
- // without bit reversal.
- for (bits = 1; bits <= MAX_BITS; bits++) {
- next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
- }
-
- // Check that the bit counts in bl_count are consistent. The last code
- // must be all ones.
- // Assert (code + bl_count[MAX_BITS]-1 === (1<= 1; n--) s.pqdownheap(tree, n);
-
- // Construct the Huffman tree by repeatedly combining the least two
- // frequent nodes.
-
- node = elems; // next internal node of the tree
- do {
- // n = node of least frequency
- n = s.heap[1];
- s.heap[1] = s.heap[s.heap_len--];
- s.pqdownheap(tree, 1);
- m = s.heap[1]; // m = node of next least frequency
-
- s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
- s.heap[--s.heap_max] = m;
-
- // Create a new node father of n and m
- tree[node * 2] = tree[n * 2] + tree[m * 2];
- s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
- tree[n * 2 + 1] = tree[m * 2 + 1] = node;
-
- // and insert the new node in the heap
- s.heap[1] = node++;
- s.pqdownheap(tree, 1);
- } while (s.heap_len >= 2);
-
- s.heap[--s.heap_max] = s.heap[1];
-
- // At this point, the fields freq and dad are set. We can now
- // generate the bit lengths.
-
- gen_bitlen(s);
-
- // The field len is now set, we can generate the bit codes
- gen_codes(tree, that.max_code, s.bl_count);
- };
-}
-
-Tree._length_code = [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 8,
- 9,
- 9,
- 10,
- 10,
- 11,
- 11,
- 12,
- 12,
- 12,
- 12,
- 13,
- 13,
- 13,
- 13,
- 14,
- 14,
- 14,
- 14,
- 15,
- 15,
- 15,
- 15,
- 16,
- 16,
- 16,
- 16,
- 16,
- 16,
- 16,
- 16,
- 17,
- 17,
- 17,
- 17,
- 17,
- 17,
- 17,
- 17,
- 18,
- 18,
- 18,
- 18,
- 18,
- 18,
- 18,
- 18,
- 19,
- 19,
- 19,
- 19,
- 19,
- 19,
- 19,
- 19,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 20,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 21,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 22,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 23,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 24,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 25,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 26,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 27,
- 28
-];
-
-Tree.base_length = [
- 0,
- 1,
- 2,
- 3,
- 4,
- 5,
- 6,
- 7,
- 8,
- 10,
- 12,
- 14,
- 16,
- 20,
- 24,
- 28,
- 32,
- 40,
- 48,
- 56,
- 64,
- 80,
- 96,
- 112,
- 128,
- 160,
- 192,
- 224,
- 0
-];
-
-Tree.base_dist = [
- 0,
- 1,
- 2,
- 3,
- 4,
- 6,
- 8,
- 12,
- 16,
- 24,
- 32,
- 48,
- 64,
- 96,
- 128,
- 192,
- 256,
- 384,
- 512,
- 768,
- 1024,
- 1536,
- 2048,
- 3072,
- 4096,
- 6144,
- 8192,
- 12288,
- 16384,
- 24576
-];
-
-// Mapping from a distance to a distance code. dist is the distance - 1 and
-// must not have side effects. _dist_code[256] and _dist_code[257] are never
-// used.
-Tree.d_code = function(dist) {
- return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
-};
-
-// extra bits for each length code
-Tree.extra_lbits = [
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 0,
- 1,
- 1,
- 1,
- 1,
- 2,
- 2,
- 2,
- 2,
- 3,
- 3,
- 3,
- 3,
- 4,
- 4,
- 4,
- 4,
- 5,
- 5,
- 5,
- 5,
- 0
-];
-
-// extra bits for each distance code
-Tree.extra_dbits = [
- 0,
- 0,
- 0,
- 0,
- 1,
- 1,
- 2,
- 2,
- 3,
- 3,
- 4,
- 4,
- 5,
- 5,
- 6,
- 6,
- 7,
- 7,
- 8,
- 8,
- 9,
- 9,
- 10,
- 10,
- 11,
- 11,
- 12,
- 12,
- 13,
- 13
-];
-
-// extra bits for each bit length code
-Tree.extra_blbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7];
-
-Tree.bl_order = [
- 16,
- 17,
- 18,
- 0,
- 8,
- 7,
- 9,
- 6,
- 10,
- 5,
- 11,
- 4,
- 12,
- 3,
- 13,
- 2,
- 14,
- 1,
- 15
-];
-
-// StaticTree
-
-function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
- var that = this;
- that.static_tree = static_tree;
- that.extra_bits = extra_bits;
- that.extra_base = extra_base;
- that.elems = elems;
- that.max_length = max_length;
-}
-
-StaticTree.static_ltree = [
- 12,
- 8,
- 140,
- 8,
- 76,
- 8,
- 204,
- 8,
- 44,
- 8,
- 172,
- 8,
- 108,
- 8,
- 236,
- 8,
- 28,
- 8,
- 156,
- 8,
- 92,
- 8,
- 220,
- 8,
- 60,
- 8,
- 188,
- 8,
- 124,
- 8,
- 252,
- 8,
- 2,
- 8,
- 130,
- 8,
- 66,
- 8,
- 194,
- 8,
- 34,
- 8,
- 162,
- 8,
- 98,
- 8,
- 226,
- 8,
- 18,
- 8,
- 146,
- 8,
- 82,
- 8,
- 210,
- 8,
- 50,
- 8,
- 178,
- 8,
- 114,
- 8,
- 242,
- 8,
- 10,
- 8,
- 138,
- 8,
- 74,
- 8,
- 202,
- 8,
- 42,
- 8,
- 170,
- 8,
- 106,
- 8,
- 234,
- 8,
- 26,
- 8,
- 154,
- 8,
- 90,
- 8,
- 218,
- 8,
- 58,
- 8,
- 186,
- 8,
- 122,
- 8,
- 250,
- 8,
- 6,
- 8,
- 134,
- 8,
- 70,
- 8,
- 198,
- 8,
- 38,
- 8,
- 166,
- 8,
- 102,
- 8,
- 230,
- 8,
- 22,
- 8,
- 150,
- 8,
- 86,
- 8,
- 214,
- 8,
- 54,
- 8,
- 182,
- 8,
- 118,
- 8,
- 246,
- 8,
- 14,
- 8,
- 142,
- 8,
- 78,
- 8,
- 206,
- 8,
- 46,
- 8,
- 174,
- 8,
- 110,
- 8,
- 238,
- 8,
- 30,
- 8,
- 158,
- 8,
- 94,
- 8,
- 222,
- 8,
- 62,
- 8,
- 190,
- 8,
- 126,
- 8,
- 254,
- 8,
- 1,
- 8,
- 129,
- 8,
- 65,
- 8,
- 193,
- 8,
- 33,
- 8,
- 161,
- 8,
- 97,
- 8,
- 225,
- 8,
- 17,
- 8,
- 145,
- 8,
- 81,
- 8,
- 209,
- 8,
- 49,
- 8,
- 177,
- 8,
- 113,
- 8,
- 241,
- 8,
- 9,
- 8,
- 137,
- 8,
- 73,
- 8,
- 201,
- 8,
- 41,
- 8,
- 169,
- 8,
- 105,
- 8,
- 233,
- 8,
- 25,
- 8,
- 153,
- 8,
- 89,
- 8,
- 217,
- 8,
- 57,
- 8,
- 185,
- 8,
- 121,
- 8,
- 249,
- 8,
- 5,
- 8,
- 133,
- 8,
- 69,
- 8,
- 197,
- 8,
- 37,
- 8,
- 165,
- 8,
- 101,
- 8,
- 229,
- 8,
- 21,
- 8,
- 149,
- 8,
- 85,
- 8,
- 213,
- 8,
- 53,
- 8,
- 181,
- 8,
- 117,
- 8,
- 245,
- 8,
- 13,
- 8,
- 141,
- 8,
- 77,
- 8,
- 205,
- 8,
- 45,
- 8,
- 173,
- 8,
- 109,
- 8,
- 237,
- 8,
- 29,
- 8,
- 157,
- 8,
- 93,
- 8,
- 221,
- 8,
- 61,
- 8,
- 189,
- 8,
- 125,
- 8,
- 253,
- 8,
- 19,
- 9,
- 275,
- 9,
- 147,
- 9,
- 403,
- 9,
- 83,
- 9,
- 339,
- 9,
- 211,
- 9,
- 467,
- 9,
- 51,
- 9,
- 307,
- 9,
- 179,
- 9,
- 435,
- 9,
- 115,
- 9,
- 371,
- 9,
- 243,
- 9,
- 499,
- 9,
- 11,
- 9,
- 267,
- 9,
- 139,
- 9,
- 395,
- 9,
- 75,
- 9,
- 331,
- 9,
- 203,
- 9,
- 459,
- 9,
- 43,
- 9,
- 299,
- 9,
- 171,
- 9,
- 427,
- 9,
- 107,
- 9,
- 363,
- 9,
- 235,
- 9,
- 491,
- 9,
- 27,
- 9,
- 283,
- 9,
- 155,
- 9,
- 411,
- 9,
- 91,
- 9,
- 347,
- 9,
- 219,
- 9,
- 475,
- 9,
- 59,
- 9,
- 315,
- 9,
- 187,
- 9,
- 443,
- 9,
- 123,
- 9,
- 379,
- 9,
- 251,
- 9,
- 507,
- 9,
- 7,
- 9,
- 263,
- 9,
- 135,
- 9,
- 391,
- 9,
- 71,
- 9,
- 327,
- 9,
- 199,
- 9,
- 455,
- 9,
- 39,
- 9,
- 295,
- 9,
- 167,
- 9,
- 423,
- 9,
- 103,
- 9,
- 359,
- 9,
- 231,
- 9,
- 487,
- 9,
- 23,
- 9,
- 279,
- 9,
- 151,
- 9,
- 407,
- 9,
- 87,
- 9,
- 343,
- 9,
- 215,
- 9,
- 471,
- 9,
- 55,
- 9,
- 311,
- 9,
- 183,
- 9,
- 439,
- 9,
- 119,
- 9,
- 375,
- 9,
- 247,
- 9,
- 503,
- 9,
- 15,
- 9,
- 271,
- 9,
- 143,
- 9,
- 399,
- 9,
- 79,
- 9,
- 335,
- 9,
- 207,
- 9,
- 463,
- 9,
- 47,
- 9,
- 303,
- 9,
- 175,
- 9,
- 431,
- 9,
- 111,
- 9,
- 367,
- 9,
- 239,
- 9,
- 495,
- 9,
- 31,
- 9,
- 287,
- 9,
- 159,
- 9,
- 415,
- 9,
- 95,
- 9,
- 351,
- 9,
- 223,
- 9,
- 479,
- 9,
- 63,
- 9,
- 319,
- 9,
- 191,
- 9,
- 447,
- 9,
- 127,
- 9,
- 383,
- 9,
- 255,
- 9,
- 511,
- 9,
- 0,
- 7,
- 64,
- 7,
- 32,
- 7,
- 96,
- 7,
- 16,
- 7,
- 80,
- 7,
- 48,
- 7,
- 112,
- 7,
- 8,
- 7,
- 72,
- 7,
- 40,
- 7,
- 104,
- 7,
- 24,
- 7,
- 88,
- 7,
- 56,
- 7,
- 120,
- 7,
- 4,
- 7,
- 68,
- 7,
- 36,
- 7,
- 100,
- 7,
- 20,
- 7,
- 84,
- 7,
- 52,
- 7,
- 116,
- 7,
- 3,
- 8,
- 131,
- 8,
- 67,
- 8,
- 195,
- 8,
- 35,
- 8,
- 163,
- 8,
- 99,
- 8,
- 227,
- 8
-];
+ //Transform Unicode to ASCII
+ for (i = 0; i < dataLength; i += 1) {
+ charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
+ }
+ return charArray.join("");
+ };
-StaticTree.static_dtree = [
- 0,
- 5,
- 16,
- 5,
- 8,
- 5,
- 24,
- 5,
- 4,
- 5,
- 20,
- 5,
- 12,
- 5,
- 28,
- 5,
- 2,
- 5,
- 18,
- 5,
- 10,
- 5,
- 26,
- 5,
- 6,
- 5,
- 22,
- 5,
- 14,
- 5,
- 30,
- 5,
- 1,
- 5,
- 17,
- 5,
- 9,
- 5,
- 25,
- 5,
- 5,
- 5,
- 21,
- 5,
- 13,
- 5,
- 29,
- 5,
- 3,
- 5,
- 19,
- 5,
- 11,
- 5,
- 27,
- 5,
- 7,
- 5,
- 23,
- 5
-];
+ request.open("GET", url, !sync);
+ // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
+ request.overrideMimeType("text/plain; charset=x-user-defined");
-StaticTree.static_l_desc = new StaticTree(
- StaticTree.static_ltree,
- Tree.extra_lbits,
- LITERALS + 1,
- L_CODES,
- MAX_BITS
-);
+ if (sync === false) {
+ request.onload = function() {
+ if (request.status === 200) {
+ callback(sanitizeUnicode(this.responseText));
+ } else {
+ callback(undefined);
+ }
+ };
+ }
+ request.send(null);
-StaticTree.static_d_desc = new StaticTree(
- StaticTree.static_dtree,
- Tree.extra_dbits,
- 0,
- D_CODES,
- MAX_BITS
-);
+ if (sync && request.status === 200) {
+ return sanitizeUnicode(request.responseText);
+ }
+ };
+ try {
+ result = xhr(url, sync, callback);
+ // eslint-disable-next-line no-empty
+ } catch (e) {}
+ return result;
+ }
+})(jsPDF.API);
-StaticTree.static_bl_desc = new StaticTree(
- null,
- Tree.extra_blbits,
- 0,
- BL_CODES,
- MAX_BL_BITS
-);
+/**
+ * @license
+ * Copyright (c) 2018 Erik Koopmans
+ * Released under the MIT License.
+ *
+ * Licensed under the MIT License.
+ * http://opensource.org/licenses/mit-license
+ */
-// Deflate
+/**
+ * jsPDF html PlugIn
+ *
+ * @name html
+ * @module
+ */
+(function(jsPDFAPI) {
-var MAX_MEM_LEVEL = 9;
-var DEF_MEM_LEVEL = 8;
+ function loadHtml2Canvas() {
+ return (function() {
+ if (globalObject["html2canvas"]) {
+ return Promise.resolve(globalObject["html2canvas"]);
+ }
-function Config(good_length, max_lazy, nice_length, max_chain, func) {
- var that = this;
- that.good_length = good_length;
- that.max_lazy = max_lazy;
- that.nice_length = nice_length;
- that.max_chain = max_chain;
- that.func = func;
-}
+ return import('html2canvas');
+
+ })()
+ .catch(function(e) {
+ return Promise.reject(new Error("Could not load dompurify: " + e));
+ })
+ .then(function(html2canvas) {
+ return html2canvas.default ? html2canvas.default : html2canvas;
+ });
+ }
+
+ function loadDomPurify() {
+ return (function() {
+ if (globalObject["DOMPurify"]) {
+ return Promise.resolve(globalObject["DOMPurify"]);
+ }
+
+ return import('dompurify');
+
+ })()
+ .catch(function(e) {
+ return Promise.reject(new Error("Could not load dompurify: " + e));
+ })
+ .then(function(dompurify) {
+ return dompurify.default ? dompurify.default : dompurify;
+ });
+ }
+
+ /**
+ * Determine the type of a variable/object.
+ *
+ * @private
+ * @ignore
+ */
+ var objType = function(obj) {
+ var type = typeof obj;
+ if (type === "undefined") return "undefined";
+ else if (type === "string" || obj instanceof String) return "string";
+ else if (type === "number" || obj instanceof Number) return "number";
+ else if (type === "function" || obj instanceof Function) return "function";
+ else if (!!obj && obj.constructor === Array) return "array";
+ else if (obj && obj.nodeType === 1) return "element";
+ else if (type === "object") return "object";
+ else return "unknown";
+ };
+
+ /**
+ * Create an HTML element with optional className, innerHTML, and style.
+ *
+ * @private
+ * @ignore
+ */
+ var createElement = function(tagName, opt) {
+ var el = document.createElement(tagName);
+ if (opt.className) el.className = opt.className;
+ if (opt.innerHTML && opt.dompurify) {
+ el.innerHTML = opt.dompurify.sanitize(opt.innerHTML);
+ }
+ for (var key in opt.style) {
+ el.style[key] = opt.style[key];
+ }
+ return el;
+ };
+
+ /**
+ * Deep-clone a node and preserve contents/properties.
+ *
+ * @private
+ * @ignore
+ */
+ var cloneNode = function(node, javascriptEnabled) {
+ // Recursively clone the node.
+ var clone =
+ node.nodeType === 3
+ ? document.createTextNode(node.nodeValue)
+ : node.cloneNode(false);
+ for (var child = node.firstChild; child; child = child.nextSibling) {
+ if (
+ javascriptEnabled === true ||
+ child.nodeType !== 1 ||
+ child.nodeName !== "SCRIPT"
+ ) {
+ clone.appendChild(cloneNode(child, javascriptEnabled));
+ }
+ }
+
+ if (node.nodeType === 1) {
+ // Preserve contents/properties of special nodes.
+ if (node.nodeName === "CANVAS") {
+ clone.width = node.width;
+ clone.height = node.height;
+ clone.getContext("2d").drawImage(node, 0, 0);
+ } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
+ clone.value = node.value;
+ }
-var STORED = 0;
-var FAST = 1;
-var SLOW = 2;
-var config_table = [
- new Config(0, 0, 0, 0, STORED),
- new Config(4, 4, 8, 4, FAST),
- new Config(4, 5, 16, 8, FAST),
- new Config(4, 6, 32, 32, FAST),
- new Config(4, 4, 16, 16, SLOW),
- new Config(8, 16, 32, 32, SLOW),
- new Config(8, 16, 128, 128, SLOW),
- new Config(8, 32, 128, 256, SLOW),
- new Config(32, 128, 258, 1024, SLOW),
- new Config(32, 258, 258, 4096, SLOW)
-];
+ // Preserve the node's scroll position when it loads.
+ clone.addEventListener(
+ "load",
+ function() {
+ clone.scrollTop = node.scrollTop;
+ clone.scrollLeft = node.scrollLeft;
+ },
+ true
+ );
+ }
-var z_errmsg = [
- "need dictionary", // Z_NEED_DICT
- // 2
- "stream end", // Z_STREAM_END 1
- "", // Z_OK 0
- "", // Z_ERRNO (-1)
- "stream error", // Z_STREAM_ERROR (-2)
- "data error", // Z_DATA_ERROR (-3)
- "", // Z_MEM_ERROR (-4)
- "buffer error", // Z_BUF_ERROR (-5)
- "", // Z_VERSION_ERROR (-6)
- ""
-];
+ // Return the cloned node.
+ return clone;
+ };
-// block not completed, need more input or more output
-var NeedMore = 0;
+ /* ----- CONSTRUCTOR ----- */
-// block flush performed
-var BlockDone = 1;
+ var Worker = function Worker(opt) {
+ // Create the root parent for the proto chain, and the starting Worker.
+ var root = Object.assign(
+ Worker.convert(Promise.resolve()),
+ JSON.parse(JSON.stringify(Worker.template))
+ );
+ var self = Worker.convert(Promise.resolve(), root);
-// finish started, need only more output at next deflate
-var FinishStarted = 2;
+ // Set progress, optional settings, and return.
+ self = self.setProgress(1, Worker, 1, [Worker]);
+ self = self.set(opt);
+ return self;
+ };
-// finish done, accept no more input or output
-var FinishDone = 3;
+ // Boilerplate for subclassing Promise.
+ Worker.prototype = Object.create(Promise.prototype);
+ Worker.prototype.constructor = Worker;
-// preset dictionary flag in zlib header
-var PRESET_DICT = 0x20;
+ // Converts/casts promises into Workers.
+ Worker.convert = function convert(promise, inherit) {
+ // Uses prototypal inheritance to receive changes made to ancestors' properties.
+ promise.__proto__ = inherit || Worker.prototype;
+ return promise;
+ };
-var INIT_STATE = 42;
-var BUSY_STATE = 113;
-var FINISH_STATE = 666;
+ Worker.template = {
+ prop: {
+ src: null,
+ container: null,
+ overlay: null,
+ canvas: null,
+ img: null,
+ pdf: null,
+ pageSize: null,
+ callback: function() {}
+ },
+ progress: {
+ val: 0,
+ state: null,
+ n: 0,
+ stack: []
+ },
+ opt: {
+ filename: "file.pdf",
+ margin: [0, 0, 0, 0],
+ enableLinks: true,
+ x: 0,
+ y: 0,
+ html2canvas: {},
+ jsPDF: {},
+ backgroundColor: "transparent"
+ }
+ };
-// The deflate compression method
-var Z_DEFLATED = 8;
+ /* ----- FROM / TO ----- */
-var STORED_BLOCK = 0;
-var STATIC_TREES = 1;
-var DYN_TREES = 2;
+ Worker.prototype.from = function from(src, type) {
+ function getType(src) {
+ switch (objType(src)) {
+ case "string":
+ return "string";
+ case "element":
+ return src.nodeName.toLowerCase === "canvas" ? "canvas" : "element";
+ default:
+ return "unknown";
+ }
+ }
-var MIN_MATCH = 3;
-var MAX_MATCH = 258;
-var MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
+ return this.then(function from_main() {
+ type = type || getType(src);
+ switch (type) {
+ case "string":
+ return this.then(loadDomPurify).then(function(dompurify) {
+ return this.set({
+ src: createElement("div", {
+ innerHTML: src,
+ dompurify: dompurify
+ })
+ });
+ });
+ case "element":
+ return this.set({ src: src });
+ case "canvas":
+ return this.set({ canvas: src });
+ case "img":
+ return this.set({ img: src });
+ default:
+ return this.error("Unknown source type.");
+ }
+ });
+ };
-function smaller(tree, n, m, depth) {
- var tn2 = tree[n * 2];
- var tm2 = tree[m * 2];
- return tn2 < tm2 || (tn2 === tm2 && depth[n] <= depth[m]);
-}
+ Worker.prototype.to = function to(target) {
+ // Route the 'to' request to the appropriate method.
+ switch (target) {
+ case "container":
+ return this.toContainer();
+ case "canvas":
+ return this.toCanvas();
+ case "img":
+ return this.toImg();
+ case "pdf":
+ return this.toPdf();
+ default:
+ return this.error("Invalid target.");
+ }
+ };
-function Deflate() {
- var that = this;
- var strm; // pointer back to this zlib stream
- var status; // as the name implies
- // pending_buf; // output still pending
- var pending_buf_size; // size of pending_buf
- var last_flush; // value of flush param for previous deflate call
+ Worker.prototype.toContainer = function toContainer() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkSrc() {
+ return (
+ this.prop.src || this.error("Cannot duplicate - no source HTML.")
+ );
+ },
+ function checkPageSize() {
+ return this.prop.pageSize || this.setPageSize();
+ }
+ ];
+ return this.thenList(prereqs).then(function toContainer_main() {
+ // Define the CSS styles for the container and its overlay parent.
+ var overlayCSS = {
+ position: "fixed",
+ overflow: "hidden",
+ zIndex: 1000,
+ left: "-100000px",
+ right: 0,
+ bottom: 0,
+ top: 0
+ };
+ var containerCSS = {
+ position: "relative",
+ display: "inline-block",
+ width:
+ Math.max(
+ this.prop.src.clientWidth,
+ this.prop.src.scrollWidth,
+ this.prop.src.offsetWidth
+ ) + "px",
+ left: 0,
+ right: 0,
+ top: 0,
+ margin: "auto",
+ backgroundColor: this.opt.backgroundColor
+ }; // Set the overlay to hidden (could be changed in the future to provide a print preview).
- var w_size; // LZ77 window size (32K by default)
- var w_bits; // log2(w_size) (8..16)
- var w_mask; // w_size - 1
+ var source = cloneNode(
+ this.prop.src,
+ this.opt.html2canvas.javascriptEnabled
+ );
- var window;
- // Sliding window. Input bytes are read into the second half of the window,
- // and move to the first half later to keep a dictionary of at least wSize
- // bytes. With this organization, matches are limited to a distance of
- // wSize-MAX_MATCH bytes, but this ensures that IO is always
- // performed with a length multiple of the block size. Also, it limits
- // the window size to 64K, which is quite useful on MSDOS.
- // To do: use the user input buffer as sliding window.
+ if (source.tagName === "BODY") {
+ containerCSS.height =
+ Math.max(
+ document.body.scrollHeight,
+ document.body.offsetHeight,
+ document.documentElement.clientHeight,
+ document.documentElement.scrollHeight,
+ document.documentElement.offsetHeight
+ ) + "px";
+ }
+
+ this.prop.overlay = createElement("div", {
+ className: "html2pdf__overlay",
+ style: overlayCSS
+ });
+ this.prop.container = createElement("div", {
+ className: "html2pdf__container",
+ style: containerCSS
+ });
+ this.prop.container.appendChild(source);
+ this.prop.container.firstChild.appendChild(
+ createElement("div", {
+ style: {
+ clear: "both",
+ border: "0 none transparent",
+ margin: 0,
+ padding: 0,
+ height: 0
+ }
+ })
+ );
+ this.prop.container.style.float = "none";
+ this.prop.overlay.appendChild(this.prop.container);
+ document.body.appendChild(this.prop.overlay);
+ this.prop.container.firstChild.style.position = "relative";
+ this.prop.container.height =
+ Math.max(
+ this.prop.container.firstChild.clientHeight,
+ this.prop.container.firstChild.scrollHeight,
+ this.prop.container.firstChild.offsetHeight
+ ) + "px";
+ });
+ };
- var window_size;
- // Actual size of window: 2*wSize, except when the user input buffer
- // is directly used as sliding window.
+ Worker.prototype.toCanvas = function toCanvas() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkContainer() {
+ return (
+ document.body.contains(this.prop.container) || this.toContainer()
+ );
+ }
+ ];
- var prev;
- // Link to older string with same hash index. To limit the size of this
- // array to 64K, this link is maintained only for the last 32K strings.
- // An index in this array is thus a window index modulo 32K.
+ // Fulfill prereqs then create the canvas.
+ return this.thenList(prereqs)
+ .then(loadHtml2Canvas)
+ .then(function toCanvas_main(html2canvas) {
+ // Handle old-fashioned 'onrendered' argument.
+ var options = Object.assign({}, this.opt.html2canvas);
+ delete options.onrendered;
- var head; // Heads of the hash chains or NIL.
+ return html2canvas(this.prop.container, options);
+ })
+ .then(function toCanvas_post(canvas) {
+ // Handle old-fashioned 'onrendered' argument.
+ var onRendered = this.opt.html2canvas.onrendered || function() {};
+ onRendered(canvas);
- var ins_h; // hash index of string to be inserted
- var hash_size; // number of elements in hash table
- var hash_bits; // log2(hash_size)
- var hash_mask; // hash_size-1
+ this.prop.canvas = canvas;
+ document.body.removeChild(this.prop.overlay);
+ });
+ };
- // Number of bits by which ins_h must be shifted at each input
- // step. It must be such that after MIN_MATCH steps, the oldest
- // byte no longer takes part in the hash key, that is:
- // hash_shift * MIN_MATCH >= hash_bits
- var hash_shift;
+ Worker.prototype.toContext2d = function toContext2d() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkContainer() {
+ return (
+ document.body.contains(this.prop.container) || this.toContainer()
+ );
+ }
+ ];
- // Window position at the beginning of the current output block. Gets
- // negative when the window is moved backwards.
+ // Fulfill prereqs then create the canvas.
+ return this.thenList(prereqs)
+ .then(loadHtml2Canvas)
+ .then(function toContext2d_main(html2canvas) {
+ // Handle old-fashioned 'onrendered' argument.
- var block_start;
+ var pdf = this.opt.jsPDF;
+ var options = Object.assign(
+ {
+ async: true,
+ allowTaint: true,
+ scale: 1,
+ scrollX: this.opt.scrollX || 0,
+ scrollY: this.opt.scrollY || 0,
+ backgroundColor: "#ffffff",
+ imageTimeout: 15000,
+ logging: true,
+ proxy: null,
+ removeContainer: true,
+ foreignObjectRendering: false,
+ useCORS: false
+ },
+ this.opt.html2canvas
+ );
+ delete options.onrendered;
- var match_length; // length of best match
- var prev_match; // previous match
- var match_available; // set if previous match exists
- var strstart; // start of string to insert
- var match_start; // start of matching string
- var lookahead; // number of valid bytes ahead in window
+ pdf.context2d.autoPaging = true;
+ pdf.context2d.posX = this.opt.x;
+ pdf.context2d.posY = this.opt.y;
- // Length of the best match at previous step. Matches not greater than this
- // are discarded. This is used in the lazy match evaluation.
- var prev_length;
+ options.windowHeight = options.windowHeight || 0;
+ options.windowHeight =
+ options.windowHeight == 0
+ ? Math.max(
+ this.prop.container.clientHeight,
+ this.prop.container.scrollHeight,
+ this.prop.container.offsetHeight
+ )
+ : options.windowHeight;
- // To speed up deflation, hash chains are never searched beyond this
- // length. A higher limit improves compression ratio but degrades the speed.
- var max_chain_length;
+ return html2canvas(this.prop.container, options);
+ })
+ .then(function toContext2d_post(canvas) {
+ // Handle old-fashioned 'onrendered' argument.
+ var onRendered = this.opt.html2canvas.onrendered || function() {};
+ onRendered(canvas);
- // Attempt to find a better match only when the current match is strictly
- // smaller than this value. This mechanism is used only for compression
- // levels >= 4.
- var max_lazy_match;
+ this.prop.canvas = canvas;
+ document.body.removeChild(this.prop.overlay);
+ });
+ };
- // Insert new strings in the hash table only if the match length is not
- // greater than this length. This saves time but degrades compression.
- // max_insert_length is used only for compression levels <= 3.
+ Worker.prototype.toImg = function toImg() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkCanvas() {
+ return this.prop.canvas || this.toCanvas();
+ }
+ ];
- var level; // compression level (1..9)
- var strategy; // favor or force Huffman coding
+ // Fulfill prereqs then create the image.
+ return this.thenList(prereqs).then(function toImg_main() {
+ var imgData = this.prop.canvas.toDataURL(
+ "image/" + this.opt.image.type,
+ this.opt.image.quality
+ );
+ this.prop.img = document.createElement("img");
+ this.prop.img.src = imgData;
+ });
+ };
- // Use a faster search when the previous match is longer than this
- var good_match;
+ Worker.prototype.toPdf = function toPdf() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkContext2d() {
+ return this.toContext2d();
+ }
+ //function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
+ ];
- // Stop searching when current match exceeds this
- var nice_match;
+ // Fulfill prereqs then create the image.
+ return this.thenList(prereqs).then(function toPdf_main() {
+ // Create local copies of frequently used properties.
+ this.prop.pdf = this.prop.pdf || this.opt.jsPDF;
+ });
+ };
- var dyn_ltree; // literal and length tree
- var dyn_dtree; // distance tree
- var bl_tree; // Huffman tree for bit lengths
+ /* ----- OUTPUT / SAVE ----- */
- var l_desc = new Tree(); // desc for literal tree
- var d_desc = new Tree(); // desc for distance tree
- var bl_desc = new Tree(); // desc for bit length tree
+ Worker.prototype.output = function output(type, options, src) {
+ // Redirect requests to the correct function (outputPdf / outputImg).
+ src = src || "pdf";
+ if (src.toLowerCase() === "img" || src.toLowerCase() === "image") {
+ return this.outputImg(type, options);
+ } else {
+ return this.outputPdf(type, options);
+ }
+ };
- // that.heap_len; // number of elements in the heap
- // that.heap_max; // element of largest frequency
- // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
- // The same heap array is used to build all trees.
+ Worker.prototype.outputPdf = function outputPdf(type, options) {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkPdf() {
+ return this.prop.pdf || this.toPdf();
+ }
+ ];
- // Depth of each subtree used as tie breaker for trees of equal frequency
- that.depth = [];
+ // Fulfill prereqs then perform the appropriate output.
+ return this.thenList(prereqs).then(function outputPdf_main() {
+ /* Currently implemented output types:
+ * https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
+ * save(options), arraybuffer, blob, bloburi/bloburl,
+ * datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
+ */
+ return this.prop.pdf.output(type, options);
+ });
+ };
- var l_buf; // index for literals or lengths */
+ Worker.prototype.outputImg = function outputImg(type) {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkImg() {
+ return this.prop.img || this.toImg();
+ }
+ ];
- // Size of match buffer for literals/lengths. There are 4 reasons for
- // limiting lit_bufsize to 64K:
- // - frequencies can be kept in 16 bit counters
- // - if compression is not successful for the first block, all input
- // data is still in the window so we can still emit a stored block even
- // when input comes from standard input. (This can also be done for
- // all blocks if lit_bufsize is not greater than 32K.)
- // - if compression is not successful for a file smaller than 64K, we can
- // even emit a stored file instead of a stored block (saving 5 bytes).
- // This is applicable only for zip (not gzip or zlib).
- // - creating new Huffman trees less frequently may not provide fast
- // adaptation to changes in the input data statistics. (Take for
- // example a binary file with poorly compressible code followed by
- // a highly compressible string table.) Smaller buffer sizes give
- // fast adaptation but have of course the overhead of transmitting
- // trees more frequently.
- // - I can't count above 4
- var lit_bufsize;
+ // Fulfill prereqs then perform the appropriate output.
+ return this.thenList(prereqs).then(function outputImg_main() {
+ switch (type) {
+ case undefined:
+ case "img":
+ return this.prop.img;
+ case "datauristring":
+ case "dataurlstring":
+ return this.prop.img.src;
+ case "datauri":
+ case "dataurl":
+ return (document.location.href = this.prop.img.src);
+ default:
+ throw 'Image output type "' + type + '" is not supported.';
+ }
+ });
+ };
- var last_lit; // running index in l_buf
+ Worker.prototype.save = function save(filename) {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkPdf() {
+ return this.prop.pdf || this.toPdf();
+ }
+ ];
- // Buffer for distances. To simplify the code, d_buf and l_buf have
- // the same number of elements. To use different lengths, an extra flag
- // array would be necessary.
+ // Fulfill prereqs, update the filename (if provided), and save the PDF.
+ return this.thenList(prereqs)
+ .set(filename ? { filename: filename } : null)
+ .then(function save_main() {
+ this.prop.pdf.save(this.opt.filename);
+ });
+ };
- var d_buf; // index of pendig_buf
+ Worker.prototype.doCallback = function doCallback() {
+ // Set up function prerequisites.
+ var prereqs = [
+ function checkPdf() {
+ return this.prop.pdf || this.toPdf();
+ }
+ ];
- // that.opt_len; // bit length of current block with optimal trees
- // that.static_len; // bit length of current block with static trees
- var matches; // number of string matches in current block
- var last_eob_len; // bit length of EOB code for last block
+ // Fulfill prereqs, update the filename (if provided), and save the PDF.
+ return this.thenList(prereqs).then(function doCallback_main() {
+ this.prop.callback(this.prop.pdf);
+ });
+ };
- // Output buffer. bits are inserted starting at the bottom (least
- // significant bits).
- var bi_buf;
+ /* ----- SET / GET ----- */
- // Number of valid bits in bi_buf. All bits above the last valid bit
- // are always zero.
- var bi_valid;
+ Worker.prototype.set = function set(opt) {
+ // TODO: Implement ordered pairs?
- // number of codes at each bit length for an optimal tree
- that.bl_count = [];
+ // Silently ignore invalid or empty input.
+ if (objType(opt) !== "object") {
+ return this;
+ }
- // heap used to build the Huffman trees
- that.heap = [];
+ // Build an array of setter functions to queue.
+ var fns = Object.keys(opt || {}).map(function(key) {
+ if (key in Worker.template.prop) {
+ // Set pre-defined properties.
+ return function set_prop() {
+ this.prop[key] = opt[key];
+ };
+ } else {
+ switch (key) {
+ case "margin":
+ return this.setMargin.bind(this, opt.margin);
+ case "jsPDF":
+ return function set_jsPDF() {
+ this.opt.jsPDF = opt.jsPDF;
+ return this.setPageSize();
+ };
+ case "pageSize":
+ return this.setPageSize.bind(this, opt.pageSize);
+ default:
+ // Set any other properties in opt.
+ return function set_opt() {
+ this.opt[key] = opt[key];
+ };
+ }
+ }
+ }, this);
- dyn_ltree = [];
- dyn_dtree = [];
- bl_tree = [];
+ // Set properties within the promise chain.
+ return this.then(function set_main() {
+ return this.thenList(fns);
+ });
+ };
- function lm_init() {
- var i;
- window_size = 2 * w_size;
+ Worker.prototype.get = function get(key, cbk) {
+ return this.then(function get_main() {
+ // Fetch the requested property, either as a predefined prop or in opt.
+ var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
+ return cbk ? cbk(val) : val;
+ });
+ };
- head[hash_size - 1] = 0;
- for (i = 0; i < hash_size - 1; i++) {
- head[i] = 0;
- }
+ Worker.prototype.setMargin = function setMargin(margin) {
+ return this.then(function setMargin_main() {
+ // Parse the margin property.
+ switch (objType(margin)) {
+ case "number":
+ margin = [margin, margin, margin, margin];
+ // eslint-disable-next-line no-fallthrough
+ case "array":
+ if (margin.length === 2) {
+ margin = [margin[0], margin[1], margin[0], margin[1]];
+ }
+ if (margin.length === 4) {
+ break;
+ }
+ // eslint-disable-next-line no-fallthrough
+ default:
+ return this.error("Invalid margin array.");
+ }
- // Set the default configuration parameters:
- max_lazy_match = config_table[level].max_lazy;
- good_match = config_table[level].good_length;
- nice_match = config_table[level].nice_length;
- max_chain_length = config_table[level].max_chain;
+ // Set the margin property, then update pageSize.
+ this.opt.margin = margin;
+ }).then(this.setPageSize);
+ };
- strstart = 0;
- block_start = 0;
- lookahead = 0;
- match_length = prev_length = MIN_MATCH - 1;
- match_available = 0;
- ins_h = 0;
- }
+ Worker.prototype.setPageSize = function setPageSize(pageSize) {
+ function toPx(val, k) {
+ return Math.floor(((val * k) / 72) * 96);
+ }
- function init_block() {
- var i;
- // Initialize the trees.
- for (i = 0; i < L_CODES; i++) dyn_ltree[i * 2] = 0;
- for (i = 0; i < D_CODES; i++) dyn_dtree[i * 2] = 0;
- for (i = 0; i < BL_CODES; i++) bl_tree[i * 2] = 0;
+ return this.then(function setPageSize_main() {
+ // Retrieve page-size based on jsPDF settings, if not explicitly provided.
+ pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
- dyn_ltree[END_BLOCK * 2] = 1;
- that.opt_len = that.static_len = 0;
- last_lit = matches = 0;
- }
+ // Add 'inner' field if not present.
+ if (!pageSize.hasOwnProperty("inner")) {
+ pageSize.inner = {
+ width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
+ height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
+ };
+ pageSize.inner.px = {
+ width: toPx(pageSize.inner.width, pageSize.k),
+ height: toPx(pageSize.inner.height, pageSize.k)
+ };
+ pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+ }
- // Initialize the tree data structures for a new zlib stream.
- function tr_init() {
- l_desc.dyn_tree = dyn_ltree;
- l_desc.stat_desc = StaticTree.static_l_desc;
+ // Attach pageSize to this.
+ this.prop.pageSize = pageSize;
+ });
+ };
- d_desc.dyn_tree = dyn_dtree;
- d_desc.stat_desc = StaticTree.static_d_desc;
+ Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
+ // Immediately update all progress values.
+ if (val != null) this.progress.val = val;
+ if (state != null) this.progress.state = state;
+ if (n != null) this.progress.n = n;
+ if (stack != null) this.progress.stack = stack;
+ this.progress.ratio = this.progress.val / this.progress.state;
- bl_desc.dyn_tree = bl_tree;
- bl_desc.stat_desc = StaticTree.static_bl_desc;
+ // Return this for command chaining.
+ return this;
+ };
- bi_buf = 0;
- bi_valid = 0;
- last_eob_len = 8; // enough lookahead for inflate
+ Worker.prototype.updateProgress = function updateProgress(
+ val,
+ state,
+ n,
+ stack
+ ) {
+ // Immediately update all progress values, using setProgress.
+ return this.setProgress(
+ val ? this.progress.val + val : null,
+ state ? state : null,
+ n ? this.progress.n + n : null,
+ stack ? this.progress.stack.concat(stack) : null
+ );
+ };
- // Initialize the first block of the first file:
- init_block();
- }
+ /* ----- PROMISE MAPPING ----- */
- // Restore the heap property by moving down the tree starting at node k,
- // exchanging a node with the smallest of its two sons if necessary,
- // stopping
- // when the heap property is re-established (each father smaller than its
- // two sons).
- that.pqdownheap = function(
- tree, // the tree to restore
- k // node to move down
- ) {
- var heap = that.heap;
- var v = heap[k];
- var j = k << 1; // left son of k
- while (j <= that.heap_len) {
- // Set j to the smallest of the two sons:
- if (
- j < that.heap_len &&
- smaller(tree, heap[j + 1], heap[j], that.depth)
- ) {
- j++;
- }
- // Exit if v is smaller than both sons
- if (smaller(tree, v, heap[j], that.depth)) break;
+ Worker.prototype.then = function then(onFulfilled, onRejected) {
+ // Wrap `this` for encapsulation.
+ var self = this;
- // Exchange v with the smallest son
- heap[k] = heap[j];
- k = j;
- // And continue down the tree, setting j to the left son of k
- j <<= 1;
- }
- heap[k] = v;
+ return this.thenCore(onFulfilled, onRejected, function then_main(
+ onFulfilled,
+ onRejected
+ ) {
+ // Update progress while queuing, calling, and resolving `then`.
+ self.updateProgress(null, null, 1, [onFulfilled]);
+ return Promise.prototype.then
+ .call(this, function then_pre(val) {
+ self.updateProgress(null, onFulfilled);
+ return val;
+ })
+ .then(onFulfilled, onRejected)
+ .then(function then_post(val) {
+ self.updateProgress(1);
+ return val;
+ });
+ });
};
- // Scan a literal or distance tree to determine the frequencies of the codes
- // in the bit length tree.
- function scan_tree(
- tree, // the tree to be scanned
- max_code // and its largest code of non zero frequency
+ Worker.prototype.thenCore = function thenCore(
+ onFulfilled,
+ onRejected,
+ thenBase
) {
- var n; // iterates over all tree elements
- var prevlen = -1; // last emitted length
- var curlen; // length of current code
- var nextlen = tree[0 * 2 + 1]; // length of next code
- var count = 0; // repeat count of the current code
- var max_count = 7; // max repeat count
- var min_count = 4; // min repeat count
+ // Handle optional thenBase parameter.
+ thenBase = thenBase || Promise.prototype.then;
- if (nextlen === 0) {
- max_count = 138;
- min_count = 3;
+ // Wrap `this` for encapsulation and bind it to the promise handlers.
+ var self = this;
+ if (onFulfilled) {
+ onFulfilled = onFulfilled.bind(self);
}
- tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
-
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[(n + 1) * 2 + 1];
- if (++count < max_count && curlen === nextlen) {
- continue;
- } else if (count < min_count) {
- bl_tree[curlen * 2] += count;
- } else if (curlen !== 0) {
- if (curlen !== prevlen) bl_tree[curlen * 2]++;
- bl_tree[REP_3_6 * 2]++;
- } else if (count <= 10) {
- bl_tree[REPZ_3_10 * 2]++;
- } else {
- bl_tree[REPZ_11_138 * 2]++;
- }
- count = 0;
- prevlen = curlen;
- if (nextlen === 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen === nextlen) {
- max_count = 6;
- min_count = 3;
- } else {
- max_count = 7;
- min_count = 4;
- }
+ if (onRejected) {
+ onRejected = onRejected.bind(self);
}
- }
- // Construct the Huffman tree for the bit lengths and return the index in
- // bl_order of the last bit length code to send.
- function build_bl_tree() {
- var max_blindex; // index of last bit length code of non zero freq
+ // Cast self into a Promise to avoid polyfills recursively defining `then`.
+ var isNative =
+ Promise.toString().indexOf("[native code]") !== -1 &&
+ Promise.name === "Promise";
+ var selfPromise = isNative
+ ? self
+ : Worker.convert(Object.assign({}, self), Promise.prototype);
- // Determine the bit length frequencies for literal and distance trees
- scan_tree(dyn_ltree, l_desc.max_code);
- scan_tree(dyn_dtree, d_desc.max_code);
+ // Return the promise, after casting it into a Worker and preserving props.
+ var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
+ return Worker.convert(returnVal, self.__proto__);
+ };
- // Build the bit length tree:
- bl_desc.build_tree(that);
- // opt_len now includes the length of the tree representations, except
- // the lengths of the bit lengths codes and the 5+5+4 bits for the
- // counts.
+ Worker.prototype.thenExternal = function thenExternal(
+ onFulfilled,
+ onRejected
+ ) {
+ // Call `then` and return a standard promise (exits the Worker chain).
+ return Promise.prototype.then.call(this, onFulfilled, onRejected);
+ };
- // Determine the number of bit length codes to send. The pkzip format
- // requires that at least 4 bit length codes be sent. (appnote.txt says
- // 3 but the actual value used is 4.)
- for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
- if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0) break;
+ Worker.prototype.thenList = function thenList(fns) {
+ // Queue a series of promise 'factories' into the promise chain.
+ var self = this;
+ fns.forEach(function thenList_forEach(fn) {
+ self = self.thenCore(fn);
+ });
+ return self;
+ };
+
+ Worker.prototype["catch"] = function(onRejected) {
+ // Bind `this` to the promise handler, call `catch`, and return a Worker.
+ if (onRejected) {
+ onRejected = onRejected.bind(this);
}
- // Update opt_len to include the bit length tree and counts
- that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
+ var returnVal = Promise.prototype["catch"].call(this, onRejected);
+ return Worker.convert(returnVal, this);
+ };
- return max_blindex;
- }
+ Worker.prototype.catchExternal = function catchExternal(onRejected) {
+ // Call `catch` and return a standard promise (exits the Worker chain).
+ return Promise.prototype["catch"].call(this, onRejected);
+ };
- // Output a byte on the stream.
- // IN assertion: there is enough room in pending_buf.
- function put_byte(p) {
- that.pending_buf[that.pending++] = p;
- }
+ Worker.prototype.error = function error(msg) {
+ // Throw the error in the Promise chain.
+ return this.then(function error_main() {
+ throw new Error(msg);
+ });
+ };
- function put_short(w) {
- put_byte(w & 0xff);
- put_byte((w >>> 8) & 0xff);
- }
+ /* ----- ALIASES ----- */
- function putShortMSB(b) {
- put_byte((b >> 8) & 0xff);
- put_byte(b & 0xff & 0xff);
- }
+ Worker.prototype.using = Worker.prototype.set;
+ Worker.prototype.saveAs = Worker.prototype.save;
+ Worker.prototype.export = Worker.prototype.output;
+ Worker.prototype.run = Worker.prototype.then;
- function send_bits(value, length) {
- var val,
- len = length;
- if (bi_valid > Buf_size - len) {
- val = value;
- // bi_buf |= (val << bi_valid);
- bi_buf |= (val << bi_valid) & 0xffff;
- put_short(bi_buf);
- bi_buf = val >>> (Buf_size - bi_valid);
- bi_valid += len - Buf_size;
- } else {
- // bi_buf |= (value) << bi_valid;
- bi_buf |= (value << bi_valid) & 0xffff;
- bi_valid += len;
+ // Get dimensions of a PDF page, as determined by jsPDF.
+ jsPDF.getPageSize = function(orientation, unit, format) {
+ // Decode options object
+ if (typeof orientation === "object") {
+ var options = orientation;
+ orientation = options.orientation;
+ unit = options.unit || unit;
+ format = options.format || format;
}
- }
- function send_code(c, tree) {
- var c2 = c * 2;
- send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
- }
+ // Default options
+ unit = unit || "mm";
+ format = format || "a4";
+ orientation = ("" + (orientation || "P")).toLowerCase();
+ var format_as_string = ("" + format).toLowerCase();
- // Send a literal or distance tree in compressed form, using the codes in
- // bl_tree.
- function send_tree(
- tree, // the tree to be sent
- max_code // and its largest code of non zero frequency
- ) {
- var n; // iterates over all tree elements
- var prevlen = -1; // last emitted length
- var curlen; // length of current code
- var nextlen = tree[0 * 2 + 1]; // length of next code
- var count = 0; // repeat count of the current code
- var max_count = 7; // max repeat count
- var min_count = 4; // min repeat count
+ // Size in pt of various paper formats
+ var pageFormats = {
+ a0: [2383.94, 3370.39],
+ a1: [1683.78, 2383.94],
+ a2: [1190.55, 1683.78],
+ a3: [841.89, 1190.55],
+ a4: [595.28, 841.89],
+ a5: [419.53, 595.28],
+ a6: [297.64, 419.53],
+ a7: [209.76, 297.64],
+ a8: [147.4, 209.76],
+ a9: [104.88, 147.4],
+ a10: [73.7, 104.88],
+ b0: [2834.65, 4008.19],
+ b1: [2004.09, 2834.65],
+ b2: [1417.32, 2004.09],
+ b3: [1000.63, 1417.32],
+ b4: [708.66, 1000.63],
+ b5: [498.9, 708.66],
+ b6: [354.33, 498.9],
+ b7: [249.45, 354.33],
+ b8: [175.75, 249.45],
+ b9: [124.72, 175.75],
+ b10: [87.87, 124.72],
+ c0: [2599.37, 3676.54],
+ c1: [1836.85, 2599.37],
+ c2: [1298.27, 1836.85],
+ c3: [918.43, 1298.27],
+ c4: [649.13, 918.43],
+ c5: [459.21, 649.13],
+ c6: [323.15, 459.21],
+ c7: [229.61, 323.15],
+ c8: [161.57, 229.61],
+ c9: [113.39, 161.57],
+ c10: [79.37, 113.39],
+ dl: [311.81, 623.62],
+ letter: [612, 792],
+ "government-letter": [576, 756],
+ legal: [612, 1008],
+ "junior-legal": [576, 360],
+ ledger: [1224, 792],
+ tabloid: [792, 1224],
+ "credit-card": [153, 243]
+ };
- if (nextlen === 0) {
- max_count = 138;
- min_count = 3;
+ var k;
+ // Unit conversion
+ switch (unit) {
+ case "pt":
+ k = 1;
+ break;
+ case "mm":
+ k = 72 / 25.4;
+ break;
+ case "cm":
+ k = 72 / 2.54;
+ break;
+ case "in":
+ k = 72;
+ break;
+ case "px":
+ k = 72 / 96;
+ break;
+ case "pc":
+ k = 12;
+ break;
+ case "em":
+ k = 12;
+ break;
+ case "ex":
+ k = 6;
+ break;
+ default:
+ throw "Invalid unit: " + unit;
}
+ var pageHeight = 0;
+ var pageWidth = 0;
- for (n = 0; n <= max_code; n++) {
- curlen = nextlen;
- nextlen = tree[(n + 1) * 2 + 1];
- if (++count < max_count && curlen === nextlen) {
- continue;
- } else if (count < min_count) {
- do {
- send_code(curlen, bl_tree);
- } while (--count !== 0);
- } else if (curlen !== 0) {
- if (curlen !== prevlen) {
- send_code(curlen, bl_tree);
- count--;
- }
- send_code(REP_3_6, bl_tree);
- send_bits(count - 3, 2);
- } else if (count <= 10) {
- send_code(REPZ_3_10, bl_tree);
- send_bits(count - 3, 3);
- } else {
- send_code(REPZ_11_138, bl_tree);
- send_bits(count - 11, 7);
- }
- count = 0;
- prevlen = curlen;
- if (nextlen === 0) {
- max_count = 138;
- min_count = 3;
- } else if (curlen === nextlen) {
- max_count = 6;
- min_count = 3;
- } else {
- max_count = 7;
- min_count = 4;
+ // Dimensions are stored as user units and converted to points on output
+ if (pageFormats.hasOwnProperty(format_as_string)) {
+ pageHeight = pageFormats[format_as_string][1] / k;
+ pageWidth = pageFormats[format_as_string][0] / k;
+ } else {
+ try {
+ pageHeight = format[1];
+ pageWidth = format[0];
+ } catch (err) {
+ throw new Error("Invalid format: " + format);
}
}
- }
-
- // Send the header for a block using dynamic Huffman trees: the counts, the
- // lengths of the bit length codes, the literal tree and the distance tree.
- // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
- function send_all_trees(lcodes, dcodes, blcodes) {
- var rank; // index in bl_order
- send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
- send_bits(dcodes - 1, 5);
- send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
- for (rank = 0; rank < blcodes; rank++) {
- send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
+ var tmp;
+ // Handle page orientation
+ if (orientation === "p" || orientation === "portrait") {
+ orientation = "p";
+ if (pageWidth > pageHeight) {
+ tmp = pageWidth;
+ pageWidth = pageHeight;
+ pageHeight = tmp;
+ }
+ } else if (orientation === "l" || orientation === "landscape") {
+ orientation = "l";
+ if (pageHeight > pageWidth) {
+ tmp = pageWidth;
+ pageWidth = pageHeight;
+ pageHeight = tmp;
+ }
+ } else {
+ throw "Invalid orientation: " + orientation;
}
- send_tree(dyn_ltree, lcodes - 1); // literal tree
- send_tree(dyn_dtree, dcodes - 1); // distance tree
- }
- // Flush the bit buffer, keeping at most 7 bits in it.
- function bi_flush() {
- if (bi_valid === 16) {
- put_short(bi_buf);
- bi_buf = 0;
- bi_valid = 0;
- } else if (bi_valid >= 8) {
- put_byte(bi_buf & 0xff);
- bi_buf >>>= 8;
- bi_valid -= 8;
- }
- }
+ // Return information (k is the unit conversion ratio from pts)
+ var info = {
+ width: pageWidth,
+ height: pageHeight,
+ unit: unit,
+ k: k,
+ orientation: orientation
+ };
+ return info;
+ };
- // Send one empty static block to give enough lookahead for inflate.
- // This takes 10 bits, of which 7 may remain in the bit buffer.
- // The current inflate code requires 9 bits of lookahead. If the
- // last two codes for the previous block (real code plus EOB) were coded
- // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
- // the last real code. In this case we send two empty static blocks instead
- // of one. (There are no problems if the previous block is stored or fixed.)
- // To simplify the code, we assume the worst case of last real code encoded
- // on one bit only.
- function _tr_align() {
- send_bits(STATIC_TREES << 1, 3);
- send_code(END_BLOCK, StaticTree.static_ltree);
+ /**
+ * Generate a PDF from an HTML element or string using.
+ *
+ * @name html
+ * @function
+ * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML.
+ * @param {Object} [options] Collection of settings
+ * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance
+ *
+ * @example
+ * var doc = new jsPDF();
+ *
+ * doc.html(document.body, {
+ * callback: function (doc) {
+ * doc.save();
+ * }
+ * });
+ */
+ jsPDFAPI.html = function(src, options) {
- bi_flush();
+ options = options || {};
+ options.callback = options.callback || function() {};
+ options.html2canvas = options.html2canvas || {};
+ options.html2canvas.canvas = options.html2canvas.canvas || this.canvas;
+ options.jsPDF = options.jsPDF || this;
+ // Create a new worker with the given options.
+ var worker = new Worker(options);
- // Of the 10 bits for the empty block, we have already sent
- // (10 - bi_valid) bits. The lookahead for the last real code (before
- // the EOB of the previous block) was thus at least one plus the length
- // of the EOB plus what we have just sent of the empty static block.
- if (1 + last_eob_len + 10 - bi_valid < 9) {
- send_bits(STATIC_TREES << 1, 3);
- send_code(END_BLOCK, StaticTree.static_ltree);
- bi_flush();
+ if (!options.worker) {
+ // If worker is not set to true, perform the traditional 'simple' operation.
+ return worker.from(src).doCallback();
+ } else {
+ // Otherwise, return the worker for new Promise-based operation.
+ return worker;
}
- last_eob_len = 7;
- }
-
- // Save the match info and tally the frequency counts. Return true if
- // the current block must be flushed.
- function _tr_tally(
- dist, // distance of matched string
- lc // match length-MIN_MATCH or unmatched char (if dist==0)
- ) {
- var out_length, in_length, dcode;
- that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
- that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
+ };
+})(jsPDF.API);
- that.pending_buf[l_buf + last_lit] = lc & 0xff;
- last_lit++;
+/**
+ * @license
+ * ====================================================================
+ * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+ * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+ * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+ * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+ * ====================================================================
+ */
- if (dist === 0) {
- // lc is the unmatched char
- dyn_ltree[lc * 2]++;
- } else {
- matches++;
- // Here, lc is the match length - MIN_MATCH
- dist--; // dist = match distance - 1
- dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
- dyn_dtree[Tree.d_code(dist) * 2]++;
- }
+/**
+ * jsPDF JavaScript plugin
+ *
+ * @name javascript
+ * @module
+ */
+(function(jsPDFAPI) {
+ var jsNamesObj, jsJsObj, text;
+ /**
+ * @name addJS
+ * @function
+ * @param {string} javascript The javascript to be embedded into the PDF-file.
+ * @returns {jsPDF}
+ */
+ jsPDFAPI.addJS = function(javascript) {
+ text = javascript;
+ this.internal.events.subscribe("postPutResources", function() {
+ jsNamesObj = this.internal.newObject();
+ this.internal.out("<<");
+ this.internal.out("/Names [(EmbeddedJS) " + (jsNamesObj + 1) + " 0 R]");
+ this.internal.out(">>");
+ this.internal.out("endobj");
- if ((last_lit & 0x1fff) === 0 && level > 2) {
- // Compute an upper bound for the compressed length
- out_length = last_lit * 8;
- in_length = strstart - block_start;
- for (dcode = 0; dcode < D_CODES; dcode++) {
- out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
+ jsJsObj = this.internal.newObject();
+ this.internal.out("<<");
+ this.internal.out("/S /JavaScript");
+ this.internal.out("/JS (" + text + ")");
+ this.internal.out(">>");
+ this.internal.out("endobj");
+ });
+ this.internal.events.subscribe("putCatalog", function() {
+ if (jsNamesObj !== undefined && jsJsObj !== undefined) {
+ this.internal.out("/Names <>");
}
- out_length >>>= 3;
- if (
- matches < Math.floor(last_lit / 2) &&
- out_length < Math.floor(in_length / 2)
- )
- return true;
- }
+ });
+ return this;
+ };
+})(jsPDF.API);
- return last_lit === lit_bufsize - 1;
- // We avoid equality with lit_bufsize because of wraparound at 64K
- // on 16 bit machines and because stored blocks are restricted to
- // 64K-1 bytes.
- }
+/**
+ * @license
+ * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
+ *
+ * Licensed under the MIT License.
+ * http://opensource.org/licenses/mit-license
+ */
- // Send the block data compressed using the given Huffman trees
- function compress_block(ltree, dtree) {
- var dist; // distance of matched string
- var lc; // match length or unmatched char (if dist === 0)
- var lx = 0; // running index in l_buf
- var code; // the code to send
- var extra; // number of extra bits to send
+/**
+ * jsPDF Outline PlugIn
+ *
+ * Generates a PDF Outline
+ * @name outline
+ * @module
+ */
+(function(jsPDFAPI) {
- if (last_lit !== 0) {
- do {
- dist =
- ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) |
- (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
- lc = that.pending_buf[l_buf + lx] & 0xff;
- lx++;
+ var namesOid;
+ //var destsGoto = [];
- if (dist === 0) {
- send_code(lc, ltree); // send a literal byte
- } else {
- // Here, lc is the match length - MIN_MATCH
- code = Tree._length_code[lc];
+ jsPDFAPI.events.push([
+ "postPutResources",
+ function() {
+ var pdf = this;
+ var rx = /^(\d+) 0 obj$/;
- send_code(code + LITERALS + 1, ltree); // send the length
- // code
- extra = Tree.extra_lbits[code];
- if (extra !== 0) {
- lc -= Tree.base_length[code];
- send_bits(lc, extra); // send the extra length bits
+ // Write action goto objects for each page
+ // this.outline.destsGoto = [];
+ // for (var i = 0; i < totalPages; i++) {
+ // var id = pdf.internal.newObject();
+ // this.outline.destsGoto.push(id);
+ // pdf.internal.write("<> endobj");
+ // }
+ //
+ // for (var i = 0; i < dests.length; i++) {
+ // pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
+ // R");
+ // }
+ //
+ if (this.outline.root.children.length > 0) {
+ var lines = pdf.outline.render().split(/\r\n/);
+ for (var i = 0; i < lines.length; i++) {
+ var line = lines[i];
+ var m = rx.exec(line);
+ if (m != null) {
+ var oid = m[1];
+ pdf.internal.newObjectDeferredBegin(oid, false);
}
- dist--; // dist is now the match distance - 1
- code = Tree.d_code(dist);
+ pdf.internal.write(line);
+ }
+ }
- send_code(code, dtree); // send the distance code
- extra = Tree.extra_dbits[code];
- if (extra !== 0) {
- dist -= Tree.base_dist[code];
- send_bits(dist, extra); // send the extra distance bits
- }
- } // literal or match pair ?
+ // This code will write named destination for each page reference
+ // (page_1, etc)
+ if (this.outline.createNamedDestinations) {
+ var totalPages = this.internal.pages.length;
+ // WARNING: this assumes jsPDF starts on page 3 and pageIDs
+ // follow 5, 7, 9, etc
+ // Write destination objects for each page
+ var dests = [];
+ for (var i = 0; i < totalPages; i++) {
+ var id = pdf.internal.newObject();
+ dests.push(id);
+ var info = pdf.internal.getPageInfo(i + 1);
+ pdf.internal.write(
+ "<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj"
+ );
+ }
- // Check that the overlay between pending_buf and d_buf+l_buf is
- // ok:
- } while (lx < last_lit);
- }
+ // assign a name for each destination
+ var names2Oid = pdf.internal.newObject();
+ pdf.internal.write("<< /Names [ ");
+ for (var i = 0; i < dests.length; i++) {
+ pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
+ }
+ pdf.internal.write(" ] >>", "endobj");
- send_code(END_BLOCK, ltree);
- last_eob_len = ltree[END_BLOCK * 2 + 1];
- }
+ // var kids = pdf.internal.newObject();
+ // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
+ // pdf.internal.write(' ] >>', 'endobj');
- // Flush the bit buffer and align the output on a byte boundary
- function bi_windup() {
- if (bi_valid > 8) {
- put_short(bi_buf);
- } else if (bi_valid > 0) {
- put_byte(bi_buf & 0xff);
+ namesOid = pdf.internal.newObject();
+ pdf.internal.write("<< /Dests " + names2Oid + " 0 R");
+ pdf.internal.write(">>", "endobj");
+ }
}
- bi_buf = 0;
- bi_valid = 0;
- }
-
- // Copy a stored block, storing first the length and its
- // one's complement if requested.
- function copy_block(
- buf, // the input data
- len, // its length
- header // true if block header must be written
- ) {
- bi_windup(); // align on byte boundary
- last_eob_len = 8; // enough lookahead for inflate
+ ]);
- if (header) {
- put_short(len);
- put_short(~len);
+ jsPDFAPI.events.push([
+ "putCatalog",
+ function() {
+ var pdf = this;
+ if (pdf.outline.root.children.length > 0) {
+ pdf.internal.write(
+ "/Outlines",
+ this.outline.makeRef(this.outline.root)
+ );
+ if (this.outline.createNamedDestinations) {
+ pdf.internal.write("/Names " + namesOid + " 0 R");
+ }
+ // Open with Bookmarks showing
+ // pdf.internal.write("/PageMode /UseOutlines");
+ }
}
+ ]);
- that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
- that.pending += len;
- }
-
- // Send a stored block
- function _tr_stored_block(
- buf, // input block
- stored_len, // length of input block
- eof // true if this is the last block for a file
- ) {
- send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
- copy_block(buf, stored_len, true); // with header
- }
+ jsPDFAPI.events.push([
+ "initialized",
+ function() {
+ var pdf = this;
- // Determine the best encoding for the current block: dynamic trees, static
- // trees or store, and output the encoded block to the zip file.
- function _tr_flush_block(
- buf, // input block, or NULL if too old
- stored_len, // length of input block
- eof // true if this is the last block for a file
- ) {
- var opt_lenb, static_lenb; // opt_len and static_len in bytes
- var max_blindex = 0; // index of last bit length code of non zero freq
+ pdf.outline = {
+ createNamedDestinations: false,
+ root: {
+ children: []
+ }
+ };
- // Build the Huffman trees unless a stored block is forced
- if (level > 0) {
- // Construct the literal and distance trees
- l_desc.build_tree(that);
+ /**
+ * Options: pageNumber
+ */
+ pdf.outline.add = function(parent, title, options) {
+ var item = {
+ title: title,
+ options: options,
+ children: []
+ };
+ if (parent == null) {
+ parent = this.root;
+ }
+ parent.children.push(item);
+ return item;
+ };
- d_desc.build_tree(that);
+ pdf.outline.render = function() {
+ this.ctx = {};
+ this.ctx.val = "";
+ this.ctx.pdf = pdf;
- // At this point, opt_len and static_len are the total bit lengths
- // of
- // the compressed block data, excluding the tree representations.
+ this.genIds_r(this.root);
+ this.renderRoot(this.root);
+ this.renderItems(this.root);
- // Build the bit length tree for the above two trees, and get the
- // index
- // in bl_order of the last bit length code to send.
- max_blindex = build_bl_tree();
+ return this.ctx.val;
+ };
- // Determine the best encoding. Compute first the block length in
- // bytes
- opt_lenb = (that.opt_len + 3 + 7) >>> 3;
- static_lenb = (that.static_len + 3 + 7) >>> 3;
+ pdf.outline.genIds_r = function(node) {
+ node.id = pdf.internal.newObjectDeferred();
+ for (var i = 0; i < node.children.length; i++) {
+ this.genIds_r(node.children[i]);
+ }
+ };
- if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
- } else {
- opt_lenb = static_lenb = stored_len + 5; // force a stored block
- }
+ pdf.outline.renderRoot = function(node) {
+ this.objStart(node);
+ this.line("/Type /Outlines");
+ if (node.children.length > 0) {
+ this.line("/First " + this.makeRef(node.children[0]));
+ this.line(
+ "/Last " + this.makeRef(node.children[node.children.length - 1])
+ );
+ }
+ this.line(
+ "/Count " +
+ this.count_r(
+ {
+ count: 0
+ },
+ node
+ )
+ );
+ this.objEnd();
+ };
- if (stored_len + 4 <= opt_lenb && buf !== -1) {
- // 4: two words for the lengths
- // The test buf !== NULL is only necessary if LIT_BUFSIZE > WSIZE.
- // Otherwise we can't have processed more than WSIZE input bytes
- // since
- // the last block flush, because compression would have been
- // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
- // transform a block into a stored block.
- _tr_stored_block(buf, stored_len, eof);
- } else if (static_lenb === opt_lenb) {
- send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
- compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
- } else {
- send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
- send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
- compress_block(dyn_ltree, dyn_dtree);
- }
+ pdf.outline.renderItems = function(node) {
+ var getVerticalCoordinateString = this.ctx.pdf.internal
+ .getVerticalCoordinateString;
+ for (var i = 0; i < node.children.length; i++) {
+ var item = node.children[i];
+ this.objStart(item);
- // The above check is made mod 2^32, for files larger than 512 MB
- // and uLong implemented on 32 bits.
+ this.line("/Title " + this.makeString(item.title));
- init_block();
+ this.line("/Parent " + this.makeRef(node));
+ if (i > 0) {
+ this.line("/Prev " + this.makeRef(node.children[i - 1]));
+ }
+ if (i < node.children.length - 1) {
+ this.line("/Next " + this.makeRef(node.children[i + 1]));
+ }
+ if (item.children.length > 0) {
+ this.line("/First " + this.makeRef(item.children[0]));
+ this.line(
+ "/Last " + this.makeRef(item.children[item.children.length - 1])
+ );
+ }
- if (eof) {
- bi_windup();
- }
- }
+ var count = (this.count = this.count_r(
+ {
+ count: 0
+ },
+ item
+ ));
+ if (count > 0) {
+ this.line("/Count " + count);
+ }
- function flush_block_only(eof) {
- _tr_flush_block(
- block_start >= 0 ? block_start : -1,
- strstart - block_start,
- eof
- );
- block_start = strstart;
- strm.flush_pending();
- }
+ if (item.options) {
+ if (item.options.pageNumber) {
+ // Explicit Destination
+ //WARNING this assumes page ids are 3,5,7, etc.
+ var info = pdf.internal.getPageInfo(item.options.pageNumber);
+ this.line(
+ "/Dest " +
+ "[" +
+ info.objId +
+ " 0 R /XYZ 0 " +
+ getVerticalCoordinateString(0) +
+ " 0]"
+ );
+ // this line does not work on all clients (pageNumber instead of page ref)
+ //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
- // Fill the window when the lookahead becomes insufficient.
- // Updates strstart and lookahead.
- //
- // IN assertion: lookahead < MIN_LOOKAHEAD
- // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
- // At least one byte has been read, or avail_in === 0; reads are
- // performed for at least two bytes (required for the zip translate_eol
- // option -- not supported here).
- function fill_window() {
- var n, m;
- var p;
- var more; // Amount of free space at the end of the window.
+ // Named Destination
+ // this.line('/Dest (page_' + (item.options.pageNumber) + ')');
- do {
- more = window_size - lookahead - strstart;
+ // Action Destination
+ // var id = pdf.internal.newObject();
+ // pdf.internal.write('<> endobj');
+ // this.line('/A ' + id + ' 0 R' );
+ }
+ }
+ this.objEnd();
+ }
+ for (var z = 0; z < node.children.length; z++) {
+ this.renderItems(node.children[z]);
+ }
+ };
- // Deal with !@#$% 64K limit:
- if (more === 0 && strstart === 0 && lookahead === 0) {
- more = w_size;
- } else if (more === -1) {
- // Very unlikely, but possible on 16 bit machine if strstart ==
- // 0
- // and lookahead === 1 (input done one byte at time)
- more--;
+ pdf.outline.line = function(text) {
+ this.ctx.val += text + "\r\n";
+ };
- // If the window is almost full and there is insufficient
- // lookahead,
- // move the upper half to the lower one to make room in the
- // upper half.
- } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
- window.set(window.subarray(w_size, w_size + w_size), 0);
+ pdf.outline.makeRef = function(node) {
+ return node.id + " 0 R";
+ };
- match_start -= w_size;
- strstart -= w_size; // we now have strstart >= MAX_DIST
- block_start -= w_size;
+ pdf.outline.makeString = function(val) {
+ return "(" + pdf.internal.pdfEscape(val) + ")";
+ };
- // Slide the hash table (could be avoided with 32 bit values
- // at the expense of memory usage). We slide even when level ==
- // 0
- // to keep the hash table consistent if we switch back to level
- // > 0
- // later. (Using level 0 permanently is not an optimal usage of
- // zlib, so we don't care about this pathological case.)
+ pdf.outline.objStart = function(node) {
+ this.ctx.val += "\r\n" + node.id + " 0 obj" + "\r\n<<\r\n";
+ };
- n = hash_size;
- p = n;
- do {
- m = head[--p] & 0xffff;
- head[p] = m >= w_size ? m - w_size : 0;
- } while (--n !== 0);
+ pdf.outline.objEnd = function() {
+ this.ctx.val += ">> \r\n" + "endobj" + "\r\n";
+ };
- n = w_size;
- p = n;
- do {
- m = prev[--p] & 0xffff;
- prev[p] = m >= w_size ? m - w_size : 0;
- // If n is not on any hash chain, prev[n] is garbage but
- // its value will never be used.
- } while (--n !== 0);
- more += w_size;
- }
+ pdf.outline.count_r = function(ctx, node) {
+ for (var i = 0; i < node.children.length; i++) {
+ ctx.count++;
+ this.count_r(ctx, node.children[i]);
+ }
+ return ctx.count;
+ };
+ }
+ ]);
- if (strm.avail_in === 0) return;
+ return this;
+})(jsPDF.API);
- // If there was no sliding:
- // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
- // more === window_size - lookahead - strstart
- // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
- // => more >= window_size - 2*WSIZE + 2
- // In the BIG_MEM or MMAP case (not yet supported),
- // window_size === input_size + MIN_LOOKAHEAD &&
- // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
- // Otherwise, window_size === 2*WSIZE so more >= 2.
- // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+/**
+ * @license
+ *
+ * Licensed under the MIT License.
+ * http://opensource.org/licenses/mit-license
+ */
- n = strm.read_buf(window, strstart + lookahead, more);
- lookahead += n;
+/**
+ * jsPDF jpeg Support PlugIn
+ *
+ * @name jpeg_support
+ * @module
+ */
+(function(jsPDFAPI) {
- // Initialize the hash value now that we have some input:
- if (lookahead >= MIN_MATCH) {
- ins_h = window[strstart] & 0xff;
- ins_h =
- ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
- }
- // If the whole input has less than MIN_MATCH bytes, ins_h is
- // garbage,
- // but this is not important since only literal bytes will be
- // emitted.
- } while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
- }
+ /**
+ * 0xc0 (SOF) Huffman - Baseline DCT
+ * 0xc1 (SOF) Huffman - Extended sequential DCT
+ * 0xc2 Progressive DCT (SOF2)
+ * 0xc3 Spatial (sequential) lossless (SOF3)
+ * 0xc4 Differential sequential DCT (SOF5)
+ * 0xc5 Differential progressive DCT (SOF6)
+ * 0xc6 Differential spatial (SOF7)
+ * 0xc7
+ */
+ var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7];
- // Copy without compression as much as possible from the input stream,
- // return
- // the current block state.
- // This function does not insert new strings in the dictionary since
- // uncompressible data is probably not useful. This function is used
- // only for the level=0 compression option.
- // NOTE: this function should be optimized to avoid extra copying from
- // window to pending_buf.
- function deflate_stored(flush) {
- // Stored blocks are limited to 0xffff bytes, pending_buf is limited
- // to pending_buf_size, and each stored block has a 5 byte header:
+ //takes a string imgData containing the raw bytes of
+ //a jpeg image and returns [width, height]
+ //Algorithm from: http://www.64lines.com/jpeg-width-height
+ var getJpegInfo = function(imgData) {
+ var width, height, numcomponents;
+ var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
+ var len = imgData.length;
+ var result = { width: 0, height: 0, numcomponents: 1 };
+ for (var i = 4; i < len; i += 2) {
+ i += blockLength;
+ if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) {
+ height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
+ width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
+ numcomponents = imgData.charCodeAt(i + 9);
+ result = { width: width, height: height, numcomponents: numcomponents };
+ break;
+ } else {
+ blockLength =
+ imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3);
+ }
+ }
+ return result;
+ };
- var max_block_size = 0xffff;
- var max_start;
+ /**
+ * @ignore
+ */
+ jsPDFAPI.processJPEG = function(
+ data,
+ index,
+ alias,
+ compression,
+ dataAsBinaryString,
+ colorSpace
+ ) {
+ var filter = this.decode.DCT_DECODE,
+ bpc = 8,
+ dims,
+ result = null;
- if (max_block_size > pending_buf_size - 5) {
- max_block_size = pending_buf_size - 5;
- }
+ if (
+ typeof data === "string" ||
+ this.__addimage__.isArrayBuffer(data) ||
+ this.__addimage__.isArrayBufferView(data)
+ ) {
+ // if we already have a stored binary string rep use that
+ data = dataAsBinaryString || data;
+ data = this.__addimage__.isArrayBuffer(data)
+ ? new Uint8Array(data)
+ : data;
+ data = this.__addimage__.isArrayBufferView(data)
+ ? this.__addimage__.arrayBufferToBinaryString(data)
+ : data;
- // Copy as much as possible from input to output:
- while (true) {
- // Fill the window as much as possible:
- if (lookahead <= 1) {
- fill_window();
- if (lookahead === 0 && flush === Z_NO_FLUSH) return NeedMore;
- if (lookahead === 0) break; // flush the current block
+ dims = getJpegInfo(data);
+ switch (dims.numcomponents) {
+ case 1:
+ colorSpace = this.color_spaces.DEVICE_GRAY;
+ break;
+ case 4:
+ colorSpace = this.color_spaces.DEVICE_CMYK;
+ break;
+ case 3:
+ colorSpace = this.color_spaces.DEVICE_RGB;
+ break;
}
- strstart += lookahead;
- lookahead = 0;
+ result = {
+ data: data,
+ width: dims.width,
+ height: dims.height,
+ colorSpace: colorSpace,
+ bitsPerComponent: bpc,
+ filter: filter,
+ index: index,
+ alias: alias
+ };
+ }
+ return result;
+ };
+})(jsPDF.API);
- // Emit a stored block if pending_buf will be full:
- max_start = block_start + max_block_size;
- if (strstart === 0 || strstart >= max_start) {
- // strstart === 0 is possible when wraparound on 16-bit machine
- lookahead = strstart - max_start;
- strstart = max_start;
+/**
+ * @license
+ Copyright (c) 2013 Gildas Lormeau. All rights reserved.
- flush_block_only(false);
- if (strm.avail_out === 0) return NeedMore;
- }
+ Redistribution and use in source and binary forms, with or without
+ modification, are permitted provided that the following conditions are met:
- // Flush if we may have to slide, otherwise block_start may become
- // negative and the data will be gone:
- if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
- flush_block_only(false);
- if (strm.avail_out === 0) return NeedMore;
- }
- }
+ 1. Redistributions of source code must retain the above copyright notice,
+ this list of conditions and the following disclaimer.
- flush_block_only(flush === Z_FINISH);
- if (strm.avail_out === 0)
- return flush === Z_FINISH ? FinishStarted : NeedMore;
+ 2. Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in
+ the documentation and/or other materials provided with the distribution.
- return flush === Z_FINISH ? FinishDone : BlockDone;
- }
+ 3. The names of the authors may not be used to endorse or promote products
+ derived from this software without specific prior written permission.
- function longest_match(cur_match) {
- var chain_length = max_chain_length; // max hash chain length
- var scan = strstart; // current string
- var match; // matched string
- var len; // length of current match
- var best_len = prev_length; // best match length so far
- var limit =
- strstart > w_size - MIN_LOOKAHEAD
- ? strstart - (w_size - MIN_LOOKAHEAD)
- : 0;
- var _nice_match = nice_match;
+ THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
+ INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL JCRAFT,
+ INC. OR ANY CONTRIBUTORS TO THIS SOFTWARE BE LIABLE FOR ANY DIRECT, INDIRECT,
+ INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
+ OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+ EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
- // Stop when cur_match becomes <= limit. To simplify the code,
- // we prevent matches with the string of window index 0.
+/*
+ * This program is based on JZlib 1.0.2 ymnk, JCraft,Inc.
+ * JZlib is based on zlib-1.1.3, so all credit should go authors
+ * Jean-loup Gailly(jloup@gzip.org) and Mark Adler(madler@alumni.caltech.edu)
+ * and contributors of zlib.
+ */
- var wmask = w_mask;
+// Global
- var strend = strstart + MAX_MATCH;
- var scan_end1 = window[scan + best_len - 1];
- var scan_end = window[scan + best_len];
+var MAX_BITS = 15;
+var D_CODES = 30;
+var BL_CODES = 19;
- // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
- // 16.
- // It is easy to get rid of this optimization if necessary.
+var LENGTH_CODES = 29;
+var LITERALS = 256;
+var L_CODES = LITERALS + 1 + LENGTH_CODES;
+var HEAP_SIZE = 2 * L_CODES + 1;
- // Do not waste too much time if we already have a good match:
- if (prev_length >= good_match) {
- chain_length >>= 2;
- }
+var END_BLOCK = 256;
- // Do not look for matches beyond the end of the input. This is
- // necessary
- // to make deflate deterministic.
- if (_nice_match > lookahead) _nice_match = lookahead;
+// Bit length codes must not exceed MAX_BL_BITS bits
+var MAX_BL_BITS = 7;
- do {
- match = cur_match;
+// repeat previous bit length 3-6 times (2 bits of repeat count)
+var REP_3_6 = 16;
- // Skip to next match if the match length cannot increase
- // or if the match length is less than 2:
- if (
- window[match + best_len] !== scan_end ||
- window[match + best_len - 1] !== scan_end1 ||
- window[match] !== window[scan] ||
- window[++match] !== window[scan + 1]
- )
- continue;
+// repeat a zero length 3-10 times (3 bits of repeat count)
+var REPZ_3_10 = 17;
- // The check at best_len-1 can be removed because it will be made
- // again later. (This heuristic is not always a win.)
- // It is not necessary to compare scan[2] and match[2] since they
- // are always equal when the other bytes match, given that
- // the hash keys are equal and that HASH_BITS >= 8.
- scan += 2;
- match++;
+// repeat a zero length 11-138 times (7 bits of repeat count)
+var REPZ_11_138 = 18;
- // We check for insufficient lookahead only every 8th comparison;
- // the 256th check will be made at strstart+258.
- do {} while (
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- window[++scan] === window[++match] &&
- scan < strend
- );
+// The lengths of the bit length codes are sent in order of decreasing
+// probability, to avoid transmitting the lengths for unused bit
+// length codes.
- len = MAX_MATCH - (strend - scan);
- scan = strend - MAX_MATCH;
+var Buf_size = 8 * 2;
- if (len > best_len) {
- match_start = cur_match;
- best_len = len;
- if (len >= _nice_match) break;
- scan_end1 = window[scan + best_len - 1];
- scan_end = window[scan + best_len];
- }
- } while (
- (cur_match = prev[cur_match & wmask] & 0xffff) > limit &&
- --chain_length !== 0
- );
+// JZlib version : "1.0.2"
+var Z_DEFAULT_COMPRESSION = -1;
- if (best_len <= lookahead) return best_len;
- return lookahead;
- }
+// compression strategy
+var Z_FILTERED = 1;
+var Z_HUFFMAN_ONLY = 2;
+var Z_DEFAULT_STRATEGY = 0;
- // Compress as much as possible from the input stream, return the current
- // block state.
- // This function does not perform lazy evaluation of matches and inserts
- // new strings in the dictionary only for unmatched strings or for short
- // matches. It is used only for the fast compression options.
- function deflate_fast(flush) {
- // short hash_head = 0; // head of the hash chain
- var hash_head = 0; // head of the hash chain
- var bflush; // set if current block must be flushed
+var Z_NO_FLUSH = 0;
+var Z_PARTIAL_FLUSH = 1;
+var Z_FULL_FLUSH = 3;
+var Z_FINISH = 4;
- while (true) {
- // Make sure that we always have enough lookahead, except
- // at the end of the input file. We need MAX_MATCH bytes
- // for the next match, plus MIN_MATCH bytes to insert the
- // string following the next match.
- if (lookahead < MIN_LOOKAHEAD) {
- fill_window();
- if (lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
- return NeedMore;
- }
- if (lookahead === 0) break; // flush the current block
- }
+var Z_OK = 0;
+var Z_STREAM_END = 1;
+var Z_NEED_DICT = 2;
+var Z_STREAM_ERROR = -2;
+var Z_DATA_ERROR = -3;
+var Z_BUF_ERROR = -5;
+
+// Tree
+
+// see definition of array dist_code below
+var _dist_code = [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 4,
+ 5,
+ 5,
+ 6,
+ 6,
+ 6,
+ 6,
+ 7,
+ 7,
+ 7,
+ 7,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 8,
+ 9,
+ 9,
+ 9,
+ 9,
+ 9,
+ 9,
+ 9,
+ 9,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 10,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 11,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 12,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 13,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 14,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 15,
+ 0,
+ 0,
+ 16,
+ 17,
+ 18,
+ 18,
+ 19,
+ 19,
+ 20,
+ 20,
+ 20,
+ 20,
+ 21,
+ 21,
+ 21,
+ 21,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 28,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29,
+ 29
+];
- // Insert the string window[strstart .. strstart+2] in the
- // dictionary, and set hash_head to the head of the hash chain:
- if (lookahead >= MIN_MATCH) {
- ins_h =
- ((ins_h << hash_shift) ^
- (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
- hash_mask;
+function Tree() {
+ var that = this;
- // prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head = head[ins_h] & 0xffff;
- prev[strstart & w_mask] = head[ins_h];
- head[ins_h] = strstart;
- }
+ // dyn_tree; // the dynamic tree
+ // max_code; // largest code with non zero frequency
+ // stat_desc; // the corresponding static tree
- // Find the longest match, discarding those <= prev_length.
- // At this point we have always match_length < MIN_MATCH
+ // Compute the optimal bit lengths for a tree and update the total bit
+ // length
+ // for the current block.
+ // IN assertion: the fields freq and dad are set, heap[heap_max] and
+ // above are the tree nodes sorted by increasing frequency.
+ // OUT assertions: the field len is set to the optimal bit length, the
+ // array bl_count contains the frequencies for each bit length.
+ // The length opt_len is updated; static_len is also updated if stree is
+ // not null.
+ function gen_bitlen(s) {
+ var tree = that.dyn_tree;
+ var stree = that.stat_desc.static_tree;
+ var extra = that.stat_desc.extra_bits;
+ var base = that.stat_desc.extra_base;
+ var max_length = that.stat_desc.max_length;
+ var h; // heap index
+ var n, m; // iterate over the tree elements
+ var bits; // bit length
+ var xbits; // extra bits
+ var f; // frequency
+ var overflow = 0; // number of elements with bit length too large
- if (
- hash_head !== 0 &&
- ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD
- ) {
- // To simplify the code, we prevent matches with the string
- // of window index 0 (in particular we have to avoid a match
- // of the string with itself at the start of the input file).
- if (strategy !== Z_HUFFMAN_ONLY) {
- match_length = longest_match(hash_head);
- }
- // longest_match() sets match_start
- }
- if (match_length >= MIN_MATCH) {
- // check_match(strstart, match_start, match_length);
+ for (bits = 0; bits <= MAX_BITS; bits++) s.bl_count[bits] = 0;
- bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
+ // In a first pass, compute the optimal bit lengths (which may
+ // overflow in the case of the bit length tree).
+ tree[s.heap[s.heap_max] * 2 + 1] = 0; // root of the heap
- lookahead -= match_length;
+ for (h = s.heap_max + 1; h < HEAP_SIZE; h++) {
+ n = s.heap[h];
+ bits = tree[tree[n * 2 + 1] * 2 + 1] + 1;
+ if (bits > max_length) {
+ bits = max_length;
+ overflow++;
+ }
+ tree[n * 2 + 1] = bits;
+ // We overwrite tree[n*2+1] which is no longer needed
- // Insert new strings in the hash table only if the match length
- // is not too large. This saves time but degrades compression.
- if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
- match_length--; // string at strstart already in hash table
- do {
- strstart++;
+ if (n > that.max_code) continue; // not a leaf node
- ins_h =
- ((ins_h << hash_shift) ^
- (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
- hash_mask;
- // prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head = head[ins_h] & 0xffff;
- prev[strstart & w_mask] = head[ins_h];
- head[ins_h] = strstart;
+ s.bl_count[bits]++;
+ xbits = 0;
+ if (n >= base) xbits = extra[n - base];
+ f = tree[n * 2];
+ s.opt_len += f * (bits + xbits);
+ if (stree) s.static_len += f * (stree[n * 2 + 1] + xbits);
+ }
+ if (overflow === 0) return;
- // strstart never exceeds WSIZE-MAX_MATCH, so there are
- // always MIN_MATCH bytes ahead.
- } while (--match_length !== 0);
- strstart++;
- } else {
- strstart += match_length;
- match_length = 0;
- ins_h = window[strstart] & 0xff;
+ // This happens for example on obj2 and pic of the Calgary corpus
+ // Find the first bit length which could increase:
+ do {
+ bits = max_length - 1;
+ while (s.bl_count[bits] === 0) bits--;
+ s.bl_count[bits]--; // move one leaf down the tree
+ s.bl_count[bits + 1] += 2; // move one overflow item as its brother
+ s.bl_count[max_length]--;
+ // The brother of the overflow item also moves one step up,
+ // but this does not affect bl_count[max_length]
+ overflow -= 2;
+ } while (overflow > 0);
- ins_h =
- ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
- // If lookahead < MIN_MATCH, ins_h is garbage, but it does
- // not
- // matter since it will be recomputed at next deflate call.
+ for (bits = max_length; bits !== 0; bits--) {
+ n = s.bl_count[bits];
+ while (n !== 0) {
+ m = s.heap[--h];
+ if (m > that.max_code) continue;
+ if (tree[m * 2 + 1] !== bits) {
+ s.opt_len += (bits - tree[m * 2 + 1]) * tree[m * 2];
+ tree[m * 2 + 1] = bits;
}
- } else {
- // No match, output a literal byte
-
- bflush = _tr_tally(0, window[strstart] & 0xff);
- lookahead--;
- strstart++;
- }
- if (bflush) {
- flush_block_only(false);
- if (strm.avail_out === 0) return NeedMore;
+ n--;
}
}
+ }
- flush_block_only(flush === Z_FINISH);
- if (strm.avail_out === 0) {
- if (flush === Z_FINISH) return FinishStarted;
- else return NeedMore;
- }
- return flush === Z_FINISH ? FinishDone : BlockDone;
+ // Reverse the first len bits of a code, using straightforward code (a
+ // faster
+ // method would use a table)
+ // IN assertion: 1 <= len <= 15
+ function bi_reverse(
+ code, // the value to invert
+ len // its bit length
+ ) {
+ var res = 0;
+ do {
+ res |= code & 1;
+ code >>>= 1;
+ res <<= 1;
+ } while (--len > 0);
+ return res >>> 1;
}
- // Same as above, but achieves better compression. We use a lazy
- // evaluation for matches: a match is finally adopted only if there is
- // no better match at the next window position.
- function deflate_slow(flush) {
- // short hash_head = 0; // head of hash chain
- var hash_head = 0; // head of hash chain
- var bflush; // set if current block must be flushed
- var max_insert;
+ // Generate the codes for a given tree and bit counts (which need not be
+ // optimal).
+ // IN assertion: the array bl_count contains the bit length statistics for
+ // the given tree and the field len is set for all tree elements.
+ // OUT assertion: the field code is set for all tree elements of non
+ // zero code length.
+ function gen_codes(
+ tree, // the tree to decorate
+ max_code, // largest code with non zero frequency
+ bl_count // number of codes at each bit length
+ ) {
+ var next_code = []; // next code value for each
+ // bit length
+ var code = 0; // running code value
+ var bits; // bit index
+ var n; // code index
+ var len;
- // Process the input block.
- while (true) {
- // Make sure that we always have enough lookahead, except
- // at the end of the input file. We need MAX_MATCH bytes
- // for the next match, plus MIN_MATCH bytes to insert the
- // string following the next match.
+ // The distribution counts are first used to generate the code values
+ // without bit reversal.
+ for (bits = 1; bits <= MAX_BITS; bits++) {
+ next_code[bits] = code = (code + bl_count[bits - 1]) << 1;
+ }
- if (lookahead < MIN_LOOKAHEAD) {
- fill_window();
- if (lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
- return NeedMore;
- }
- if (lookahead === 0) break; // flush the current block
- }
+ // Check that the bit counts in bl_count are consistent. The last code
+ // must be all ones.
+ // Assert (code + bl_count[MAX_BITS]-1 === (1<= MIN_MATCH) {
- ins_h =
- ((ins_h << hash_shift) ^
- (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
- hash_mask;
- // prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head = head[ins_h] & 0xffff;
- prev[strstart & w_mask] = head[ins_h];
- head[ins_h] = strstart;
+ // Construct one Huffman tree and assigns the code bit strings and lengths.
+ // Update the total bit length for the current block.
+ // IN assertion: the field freq is set for all tree elements.
+ // OUT assertions: the fields len and code are set to the optimal bit length
+ // and corresponding code. The length opt_len is updated; static_len is
+ // also updated if stree is not null. The field max_code is set.
+ that.build_tree = function(s) {
+ var tree = that.dyn_tree;
+ var stree = that.stat_desc.static_tree;
+ var elems = that.stat_desc.elems;
+ var n, m; // iterate over heap elements
+ var max_code = -1; // largest code with non zero frequency
+ var node; // new node being created
+
+ // Construct the initial heap, with least frequent element in
+ // heap[1]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
+ // heap[0] is not used.
+ s.heap_len = 0;
+ s.heap_max = HEAP_SIZE;
+
+ for (n = 0; n < elems; n++) {
+ if (tree[n * 2] !== 0) {
+ s.heap[++s.heap_len] = max_code = n;
+ s.depth[n] = 0;
+ } else {
+ tree[n * 2 + 1] = 0;
}
+ }
- // Find the longest match, discarding those <= prev_length.
- prev_length = match_length;
- prev_match = match_start;
- match_length = MIN_MATCH - 1;
+ // The pkzip format requires that at least one distance code exists,
+ // and that at least one bit should be sent even if there is only one
+ // possible code. So to avoid special checks later on we force at least
+ // two codes of non zero frequency.
+ while (s.heap_len < 2) {
+ node = s.heap[++s.heap_len] = max_code < 2 ? ++max_code : 0;
+ tree[node * 2] = 1;
+ s.depth[node] = 0;
+ s.opt_len--;
+ if (stree) s.static_len -= stree[node * 2 + 1];
+ // node is 0 or 1 so it does not have extra bits
+ }
+ that.max_code = max_code;
- if (
- hash_head !== 0 &&
- prev_length < max_lazy_match &&
- ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD
- ) {
- // To simplify the code, we prevent matches with the string
- // of window index 0 (in particular we have to avoid a match
- // of the string with itself at the start of the input file).
+ // The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
+ // establish sub-heaps of increasing lengths:
- if (strategy !== Z_HUFFMAN_ONLY) {
- match_length = longest_match(hash_head);
- }
- // longest_match() sets match_start
+ for (n = Math.floor(s.heap_len / 2); n >= 1; n--) s.pqdownheap(tree, n);
- if (
- match_length <= 5 &&
- (strategy === Z_FILTERED ||
- (match_length === MIN_MATCH && strstart - match_start > 4096))
- ) {
- // If prev_match is also MIN_MATCH, match_start is garbage
- // but we will ignore the current match anyway.
- match_length = MIN_MATCH - 1;
- }
- }
+ // Construct the Huffman tree by repeatedly combining the least two
+ // frequent nodes.
- // If there was a match at the previous step and the current
- // match is not better, output the previous match:
- if (prev_length >= MIN_MATCH && match_length <= prev_length) {
- max_insert = strstart + lookahead - MIN_MATCH;
- // Do not insert strings in hash table beyond this.
+ node = elems; // next internal node of the tree
+ do {
+ // n = node of least frequency
+ n = s.heap[1];
+ s.heap[1] = s.heap[s.heap_len--];
+ s.pqdownheap(tree, 1);
+ m = s.heap[1]; // m = node of next least frequency
- // check_match(strstart-1, prev_match, prev_length);
+ s.heap[--s.heap_max] = n; // keep the nodes sorted by frequency
+ s.heap[--s.heap_max] = m;
- bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
+ // Create a new node father of n and m
+ tree[node * 2] = tree[n * 2] + tree[m * 2];
+ s.depth[node] = Math.max(s.depth[n], s.depth[m]) + 1;
+ tree[n * 2 + 1] = tree[m * 2 + 1] = node;
- // Insert in hash table all strings up to the end of the match.
- // strstart-1 and strstart are already inserted. If there is not
- // enough lookahead, the last two strings are not inserted in
- // the hash table.
- lookahead -= prev_length - 1;
- prev_length -= 2;
- do {
- if (++strstart <= max_insert) {
- ins_h =
- ((ins_h << hash_shift) ^
- (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
- hash_mask;
- // prev[strstart&w_mask]=hash_head=head[ins_h];
- hash_head = head[ins_h] & 0xffff;
- prev[strstart & w_mask] = head[ins_h];
- head[ins_h] = strstart;
- }
- } while (--prev_length !== 0);
- match_available = 0;
- match_length = MIN_MATCH - 1;
- strstart++;
+ // and insert the new node in the heap
+ s.heap[1] = node++;
+ s.pqdownheap(tree, 1);
+ } while (s.heap_len >= 2);
- if (bflush) {
- flush_block_only(false);
- if (strm.avail_out === 0) return NeedMore;
- }
- } else if (match_available !== 0) {
- // If there was no match at the previous position, output a
- // single literal. If there was a match but the current match
- // is longer, truncate the previous match to a single literal.
+ s.heap[--s.heap_max] = s.heap[1];
- bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+ // At this point, the fields freq and dad are set. We can now
+ // generate the bit lengths.
- if (bflush) {
- flush_block_only(false);
- }
- strstart++;
- lookahead--;
- if (strm.avail_out === 0) return NeedMore;
- } else {
- // There is no previous match to compare with, wait for
- // the next step to decide.
+ gen_bitlen(s);
- match_available = 1;
- strstart++;
- lookahead--;
- }
- }
+ // The field len is now set, we can generate the bit codes
+ gen_codes(tree, that.max_code, s.bl_count);
+ };
+}
- if (match_available !== 0) {
- bflush = _tr_tally(0, window[strstart - 1] & 0xff);
- match_available = 0;
- }
- flush_block_only(flush === Z_FINISH);
+Tree._length_code = [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 8,
+ 9,
+ 9,
+ 10,
+ 10,
+ 11,
+ 11,
+ 12,
+ 12,
+ 12,
+ 12,
+ 13,
+ 13,
+ 13,
+ 13,
+ 14,
+ 14,
+ 14,
+ 14,
+ 15,
+ 15,
+ 15,
+ 15,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 16,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 17,
+ 18,
+ 18,
+ 18,
+ 18,
+ 18,
+ 18,
+ 18,
+ 18,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 19,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 20,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 21,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 22,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 23,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 24,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 25,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 26,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 27,
+ 28
+];
- if (strm.avail_out === 0) {
- if (flush === Z_FINISH) return FinishStarted;
- else return NeedMore;
- }
+Tree.base_length = [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 10,
+ 12,
+ 14,
+ 16,
+ 20,
+ 24,
+ 28,
+ 32,
+ 40,
+ 48,
+ 56,
+ 64,
+ 80,
+ 96,
+ 112,
+ 128,
+ 160,
+ 192,
+ 224,
+ 0
+];
- return flush === Z_FINISH ? FinishDone : BlockDone;
- }
+Tree.base_dist = [
+ 0,
+ 1,
+ 2,
+ 3,
+ 4,
+ 6,
+ 8,
+ 12,
+ 16,
+ 24,
+ 32,
+ 48,
+ 64,
+ 96,
+ 128,
+ 192,
+ 256,
+ 384,
+ 512,
+ 768,
+ 1024,
+ 1536,
+ 2048,
+ 3072,
+ 4096,
+ 6144,
+ 8192,
+ 12288,
+ 16384,
+ 24576
+];
- function deflateReset(strm) {
- strm.total_in = strm.total_out = 0;
- strm.msg = null; //
+// Mapping from a distance to a distance code. dist is the distance - 1 and
+// must not have side effects. _dist_code[256] and _dist_code[257] are never
+// used.
+Tree.d_code = function(dist) {
+ return dist < 256 ? _dist_code[dist] : _dist_code[256 + (dist >>> 7)];
+};
- that.pending = 0;
- that.pending_out = 0;
+// extra bits for each length code
+Tree.extra_lbits = [
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 1,
+ 1,
+ 2,
+ 2,
+ 2,
+ 2,
+ 3,
+ 3,
+ 3,
+ 3,
+ 4,
+ 4,
+ 4,
+ 4,
+ 5,
+ 5,
+ 5,
+ 5,
+ 0
+];
- status = BUSY_STATE;
+// extra bits for each distance code
+Tree.extra_dbits = [
+ 0,
+ 0,
+ 0,
+ 0,
+ 1,
+ 1,
+ 2,
+ 2,
+ 3,
+ 3,
+ 4,
+ 4,
+ 5,
+ 5,
+ 6,
+ 6,
+ 7,
+ 7,
+ 8,
+ 8,
+ 9,
+ 9,
+ 10,
+ 10,
+ 11,
+ 11,
+ 12,
+ 12,
+ 13,
+ 13
+];
- last_flush = Z_NO_FLUSH;
+// extra bits for each bit length code
+Tree.extra_blbits = [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 3, 7];
- tr_init();
- lm_init();
- return Z_OK;
- }
+Tree.bl_order = [
+ 16,
+ 17,
+ 18,
+ 0,
+ 8,
+ 7,
+ 9,
+ 6,
+ 10,
+ 5,
+ 11,
+ 4,
+ 12,
+ 3,
+ 13,
+ 2,
+ 14,
+ 1,
+ 15
+];
- that.deflateInit = function(
- strm,
- _level,
- bits,
- _method,
- memLevel,
- _strategy
- ) {
- if (!_method) _method = Z_DEFLATED;
- if (!memLevel) memLevel = DEF_MEM_LEVEL;
- if (!_strategy) _strategy = Z_DEFAULT_STRATEGY;
+// StaticTree
- // byte[] my_version=ZLIB_VERSION;
+function StaticTree(static_tree, extra_bits, extra_base, elems, max_length) {
+ var that = this;
+ that.static_tree = static_tree;
+ that.extra_bits = extra_bits;
+ that.extra_base = extra_base;
+ that.elems = elems;
+ that.max_length = max_length;
+}
- //
- // if (!version || version[0] !== my_version[0]
- // || stream_size !== sizeof(z_stream)) {
- // return Z_VERSION_ERROR;
- // }
+StaticTree.static_ltree = [
+ 12,
+ 8,
+ 140,
+ 8,
+ 76,
+ 8,
+ 204,
+ 8,
+ 44,
+ 8,
+ 172,
+ 8,
+ 108,
+ 8,
+ 236,
+ 8,
+ 28,
+ 8,
+ 156,
+ 8,
+ 92,
+ 8,
+ 220,
+ 8,
+ 60,
+ 8,
+ 188,
+ 8,
+ 124,
+ 8,
+ 252,
+ 8,
+ 2,
+ 8,
+ 130,
+ 8,
+ 66,
+ 8,
+ 194,
+ 8,
+ 34,
+ 8,
+ 162,
+ 8,
+ 98,
+ 8,
+ 226,
+ 8,
+ 18,
+ 8,
+ 146,
+ 8,
+ 82,
+ 8,
+ 210,
+ 8,
+ 50,
+ 8,
+ 178,
+ 8,
+ 114,
+ 8,
+ 242,
+ 8,
+ 10,
+ 8,
+ 138,
+ 8,
+ 74,
+ 8,
+ 202,
+ 8,
+ 42,
+ 8,
+ 170,
+ 8,
+ 106,
+ 8,
+ 234,
+ 8,
+ 26,
+ 8,
+ 154,
+ 8,
+ 90,
+ 8,
+ 218,
+ 8,
+ 58,
+ 8,
+ 186,
+ 8,
+ 122,
+ 8,
+ 250,
+ 8,
+ 6,
+ 8,
+ 134,
+ 8,
+ 70,
+ 8,
+ 198,
+ 8,
+ 38,
+ 8,
+ 166,
+ 8,
+ 102,
+ 8,
+ 230,
+ 8,
+ 22,
+ 8,
+ 150,
+ 8,
+ 86,
+ 8,
+ 214,
+ 8,
+ 54,
+ 8,
+ 182,
+ 8,
+ 118,
+ 8,
+ 246,
+ 8,
+ 14,
+ 8,
+ 142,
+ 8,
+ 78,
+ 8,
+ 206,
+ 8,
+ 46,
+ 8,
+ 174,
+ 8,
+ 110,
+ 8,
+ 238,
+ 8,
+ 30,
+ 8,
+ 158,
+ 8,
+ 94,
+ 8,
+ 222,
+ 8,
+ 62,
+ 8,
+ 190,
+ 8,
+ 126,
+ 8,
+ 254,
+ 8,
+ 1,
+ 8,
+ 129,
+ 8,
+ 65,
+ 8,
+ 193,
+ 8,
+ 33,
+ 8,
+ 161,
+ 8,
+ 97,
+ 8,
+ 225,
+ 8,
+ 17,
+ 8,
+ 145,
+ 8,
+ 81,
+ 8,
+ 209,
+ 8,
+ 49,
+ 8,
+ 177,
+ 8,
+ 113,
+ 8,
+ 241,
+ 8,
+ 9,
+ 8,
+ 137,
+ 8,
+ 73,
+ 8,
+ 201,
+ 8,
+ 41,
+ 8,
+ 169,
+ 8,
+ 105,
+ 8,
+ 233,
+ 8,
+ 25,
+ 8,
+ 153,
+ 8,
+ 89,
+ 8,
+ 217,
+ 8,
+ 57,
+ 8,
+ 185,
+ 8,
+ 121,
+ 8,
+ 249,
+ 8,
+ 5,
+ 8,
+ 133,
+ 8,
+ 69,
+ 8,
+ 197,
+ 8,
+ 37,
+ 8,
+ 165,
+ 8,
+ 101,
+ 8,
+ 229,
+ 8,
+ 21,
+ 8,
+ 149,
+ 8,
+ 85,
+ 8,
+ 213,
+ 8,
+ 53,
+ 8,
+ 181,
+ 8,
+ 117,
+ 8,
+ 245,
+ 8,
+ 13,
+ 8,
+ 141,
+ 8,
+ 77,
+ 8,
+ 205,
+ 8,
+ 45,
+ 8,
+ 173,
+ 8,
+ 109,
+ 8,
+ 237,
+ 8,
+ 29,
+ 8,
+ 157,
+ 8,
+ 93,
+ 8,
+ 221,
+ 8,
+ 61,
+ 8,
+ 189,
+ 8,
+ 125,
+ 8,
+ 253,
+ 8,
+ 19,
+ 9,
+ 275,
+ 9,
+ 147,
+ 9,
+ 403,
+ 9,
+ 83,
+ 9,
+ 339,
+ 9,
+ 211,
+ 9,
+ 467,
+ 9,
+ 51,
+ 9,
+ 307,
+ 9,
+ 179,
+ 9,
+ 435,
+ 9,
+ 115,
+ 9,
+ 371,
+ 9,
+ 243,
+ 9,
+ 499,
+ 9,
+ 11,
+ 9,
+ 267,
+ 9,
+ 139,
+ 9,
+ 395,
+ 9,
+ 75,
+ 9,
+ 331,
+ 9,
+ 203,
+ 9,
+ 459,
+ 9,
+ 43,
+ 9,
+ 299,
+ 9,
+ 171,
+ 9,
+ 427,
+ 9,
+ 107,
+ 9,
+ 363,
+ 9,
+ 235,
+ 9,
+ 491,
+ 9,
+ 27,
+ 9,
+ 283,
+ 9,
+ 155,
+ 9,
+ 411,
+ 9,
+ 91,
+ 9,
+ 347,
+ 9,
+ 219,
+ 9,
+ 475,
+ 9,
+ 59,
+ 9,
+ 315,
+ 9,
+ 187,
+ 9,
+ 443,
+ 9,
+ 123,
+ 9,
+ 379,
+ 9,
+ 251,
+ 9,
+ 507,
+ 9,
+ 7,
+ 9,
+ 263,
+ 9,
+ 135,
+ 9,
+ 391,
+ 9,
+ 71,
+ 9,
+ 327,
+ 9,
+ 199,
+ 9,
+ 455,
+ 9,
+ 39,
+ 9,
+ 295,
+ 9,
+ 167,
+ 9,
+ 423,
+ 9,
+ 103,
+ 9,
+ 359,
+ 9,
+ 231,
+ 9,
+ 487,
+ 9,
+ 23,
+ 9,
+ 279,
+ 9,
+ 151,
+ 9,
+ 407,
+ 9,
+ 87,
+ 9,
+ 343,
+ 9,
+ 215,
+ 9,
+ 471,
+ 9,
+ 55,
+ 9,
+ 311,
+ 9,
+ 183,
+ 9,
+ 439,
+ 9,
+ 119,
+ 9,
+ 375,
+ 9,
+ 247,
+ 9,
+ 503,
+ 9,
+ 15,
+ 9,
+ 271,
+ 9,
+ 143,
+ 9,
+ 399,
+ 9,
+ 79,
+ 9,
+ 335,
+ 9,
+ 207,
+ 9,
+ 463,
+ 9,
+ 47,
+ 9,
+ 303,
+ 9,
+ 175,
+ 9,
+ 431,
+ 9,
+ 111,
+ 9,
+ 367,
+ 9,
+ 239,
+ 9,
+ 495,
+ 9,
+ 31,
+ 9,
+ 287,
+ 9,
+ 159,
+ 9,
+ 415,
+ 9,
+ 95,
+ 9,
+ 351,
+ 9,
+ 223,
+ 9,
+ 479,
+ 9,
+ 63,
+ 9,
+ 319,
+ 9,
+ 191,
+ 9,
+ 447,
+ 9,
+ 127,
+ 9,
+ 383,
+ 9,
+ 255,
+ 9,
+ 511,
+ 9,
+ 0,
+ 7,
+ 64,
+ 7,
+ 32,
+ 7,
+ 96,
+ 7,
+ 16,
+ 7,
+ 80,
+ 7,
+ 48,
+ 7,
+ 112,
+ 7,
+ 8,
+ 7,
+ 72,
+ 7,
+ 40,
+ 7,
+ 104,
+ 7,
+ 24,
+ 7,
+ 88,
+ 7,
+ 56,
+ 7,
+ 120,
+ 7,
+ 4,
+ 7,
+ 68,
+ 7,
+ 36,
+ 7,
+ 100,
+ 7,
+ 20,
+ 7,
+ 84,
+ 7,
+ 52,
+ 7,
+ 116,
+ 7,
+ 3,
+ 8,
+ 131,
+ 8,
+ 67,
+ 8,
+ 195,
+ 8,
+ 35,
+ 8,
+ 163,
+ 8,
+ 99,
+ 8,
+ 227,
+ 8
+];
- strm.msg = null;
+StaticTree.static_dtree = [
+ 0,
+ 5,
+ 16,
+ 5,
+ 8,
+ 5,
+ 24,
+ 5,
+ 4,
+ 5,
+ 20,
+ 5,
+ 12,
+ 5,
+ 28,
+ 5,
+ 2,
+ 5,
+ 18,
+ 5,
+ 10,
+ 5,
+ 26,
+ 5,
+ 6,
+ 5,
+ 22,
+ 5,
+ 14,
+ 5,
+ 30,
+ 5,
+ 1,
+ 5,
+ 17,
+ 5,
+ 9,
+ 5,
+ 25,
+ 5,
+ 5,
+ 5,
+ 21,
+ 5,
+ 13,
+ 5,
+ 29,
+ 5,
+ 3,
+ 5,
+ 19,
+ 5,
+ 11,
+ 5,
+ 27,
+ 5,
+ 7,
+ 5,
+ 23,
+ 5
+];
- if (_level === Z_DEFAULT_COMPRESSION) _level = 6;
+StaticTree.static_l_desc = new StaticTree(
+ StaticTree.static_ltree,
+ Tree.extra_lbits,
+ LITERALS + 1,
+ L_CODES,
+ MAX_BITS
+);
- if (
- memLevel < 1 ||
- memLevel > MAX_MEM_LEVEL ||
- _method !== Z_DEFLATED ||
- bits < 9 ||
- bits > 15 ||
- _level < 0 ||
- _level > 9 ||
- _strategy < 0 ||
- _strategy > Z_HUFFMAN_ONLY
- ) {
- return Z_STREAM_ERROR;
- }
+StaticTree.static_d_desc = new StaticTree(
+ StaticTree.static_dtree,
+ Tree.extra_dbits,
+ 0,
+ D_CODES,
+ MAX_BITS
+);
- strm.dstate = that;
+StaticTree.static_bl_desc = new StaticTree(
+ null,
+ Tree.extra_blbits,
+ 0,
+ BL_CODES,
+ MAX_BL_BITS
+);
- w_bits = bits;
- w_size = 1 << w_bits;
- w_mask = w_size - 1;
+// Deflate
- hash_bits = memLevel + 7;
- hash_size = 1 << hash_bits;
- hash_mask = hash_size - 1;
- hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
+var MAX_MEM_LEVEL = 9;
+var DEF_MEM_LEVEL = 8;
- window = new Uint8Array(w_size * 2);
- prev = [];
- head = [];
+function Config(good_length, max_lazy, nice_length, max_chain, func) {
+ var that = this;
+ that.good_length = good_length;
+ that.max_lazy = max_lazy;
+ that.nice_length = nice_length;
+ that.max_chain = max_chain;
+ that.func = func;
+}
- lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
+var STORED = 0;
+var FAST = 1;
+var SLOW = 2;
+var config_table = [
+ new Config(0, 0, 0, 0, STORED),
+ new Config(4, 4, 8, 4, FAST),
+ new Config(4, 5, 16, 8, FAST),
+ new Config(4, 6, 32, 32, FAST),
+ new Config(4, 4, 16, 16, SLOW),
+ new Config(8, 16, 32, 32, SLOW),
+ new Config(8, 16, 128, 128, SLOW),
+ new Config(8, 32, 128, 256, SLOW),
+ new Config(32, 128, 258, 1024, SLOW),
+ new Config(32, 258, 258, 4096, SLOW)
+];
- // We overlay pending_buf and d_buf+l_buf. This works since the average
- // output size for (length,distance) codes is <= 24 bits.
- that.pending_buf = new Uint8Array(lit_bufsize * 4);
- pending_buf_size = lit_bufsize * 4;
+var z_errmsg = [
+ "need dictionary", // Z_NEED_DICT
+ // 2
+ "stream end", // Z_STREAM_END 1
+ "", // Z_OK 0
+ "", // Z_ERRNO (-1)
+ "stream error", // Z_STREAM_ERROR (-2)
+ "data error", // Z_DATA_ERROR (-3)
+ "", // Z_MEM_ERROR (-4)
+ "buffer error", // Z_BUF_ERROR (-5)
+ "", // Z_VERSION_ERROR (-6)
+ ""
+];
- d_buf = Math.floor(lit_bufsize / 2);
- l_buf = (1 + 2) * lit_bufsize;
+// block not completed, need more input or more output
+var NeedMore = 0;
- level = _level;
+// block flush performed
+var BlockDone = 1;
- strategy = _strategy;
+// finish started, need only more output at next deflate
+var FinishStarted = 2;
- return deflateReset(strm);
- };
+// finish done, accept no more input or output
+var FinishDone = 3;
- that.deflateEnd = function() {
- if (
- status !== INIT_STATE &&
- status !== BUSY_STATE &&
- status !== FINISH_STATE
- ) {
- return Z_STREAM_ERROR;
- }
- // Deallocate in reverse order of allocations:
- that.pending_buf = null;
- head = null;
- prev = null;
- window = null;
- // free
- that.dstate = null;
- return status === BUSY_STATE ? Z_DATA_ERROR : Z_OK;
- };
+// preset dictionary flag in zlib header
+var PRESET_DICT = 0x20;
- that.deflateParams = function(strm, _level, _strategy) {
- var err = Z_OK;
+var INIT_STATE = 42;
+var BUSY_STATE = 113;
+var FINISH_STATE = 666;
- if (_level === Z_DEFAULT_COMPRESSION) {
- _level = 6;
- }
- if (
- _level < 0 ||
- _level > 9 ||
- _strategy < 0 ||
- _strategy > Z_HUFFMAN_ONLY
- ) {
- return Z_STREAM_ERROR;
- }
+// The deflate compression method
+var Z_DEFLATED = 8;
- if (
- config_table[level].func !== config_table[_level].func &&
- strm.total_in !== 0
- ) {
- // Flush the last buffer:
- err = strm.deflate(Z_PARTIAL_FLUSH);
- }
+var STORED_BLOCK = 0;
+var STATIC_TREES = 1;
+var DYN_TREES = 2;
- if (level !== _level) {
- level = _level;
- max_lazy_match = config_table[level].max_lazy;
- good_match = config_table[level].good_length;
- nice_match = config_table[level].nice_length;
- max_chain_length = config_table[level].max_chain;
- }
- strategy = _strategy;
- return err;
- };
+var MIN_MATCH = 3;
+var MAX_MATCH = 258;
+var MIN_LOOKAHEAD = MAX_MATCH + MIN_MATCH + 1;
- that.deflateSetDictionary = function(strm, dictionary, dictLength) {
- var length = dictLength;
- var n,
- index = 0;
+function smaller(tree, n, m, depth) {
+ var tn2 = tree[n * 2];
+ var tm2 = tree[m * 2];
+ return tn2 < tm2 || (tn2 === tm2 && depth[n] <= depth[m]);
+}
- if (!dictionary || status !== INIT_STATE) return Z_STREAM_ERROR;
+function Deflate() {
+ var that = this;
+ var strm; // pointer back to this zlib stream
+ var status; // as the name implies
+ // pending_buf; // output still pending
+ var pending_buf_size; // size of pending_buf
+ var last_flush; // value of flush param for previous deflate call
- if (length < MIN_MATCH) return Z_OK;
- if (length > w_size - MIN_LOOKAHEAD) {
- length = w_size - MIN_LOOKAHEAD;
- index = dictLength - length; // use the tail of the dictionary
- }
- window.set(dictionary.subarray(index, index + length), 0);
+ var w_size; // LZ77 window size (32K by default)
+ var w_bits; // log2(w_size) (8..16)
+ var w_mask; // w_size - 1
- strstart = length;
- block_start = length;
+ var window;
+ // Sliding window. Input bytes are read into the second half of the window,
+ // and move to the first half later to keep a dictionary of at least wSize
+ // bytes. With this organization, matches are limited to a distance of
+ // wSize-MAX_MATCH bytes, but this ensures that IO is always
+ // performed with a length multiple of the block size. Also, it limits
+ // the window size to 64K, which is quite useful on MSDOS.
+ // To do: use the user input buffer as sliding window.
- // Insert all strings in the hash table (except for the last two bytes).
- // s->lookahead stays null, so s->ins_h will be recomputed at the next
- // call of fill_window.
+ var window_size;
+ // Actual size of window: 2*wSize, except when the user input buffer
+ // is directly used as sliding window.
- ins_h = window[0] & 0xff;
- ins_h = ((ins_h << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
+ var prev;
+ // Link to older string with same hash index. To limit the size of this
+ // array to 64K, this link is maintained only for the last 32K strings.
+ // An index in this array is thus a window index modulo 32K.
- for (n = 0; n <= length - MIN_MATCH; n++) {
- ins_h =
- ((ins_h << hash_shift) ^ (window[n + (MIN_MATCH - 1)] & 0xff)) &
- hash_mask;
- prev[n & w_mask] = head[ins_h];
- head[ins_h] = n;
- }
- return Z_OK;
- };
+ var head; // Heads of the hash chains or NIL.
- that.deflate = function(_strm, flush) {
- var i, header, level_flags, old_flush, bstate;
+ var ins_h; // hash index of string to be inserted
+ var hash_size; // number of elements in hash table
+ var hash_bits; // log2(hash_size)
+ var hash_mask; // hash_size-1
- if (flush > Z_FINISH || flush < 0) {
- return Z_STREAM_ERROR;
- }
+ // Number of bits by which ins_h must be shifted at each input
+ // step. It must be such that after MIN_MATCH steps, the oldest
+ // byte no longer takes part in the hash key, that is:
+ // hash_shift * MIN_MATCH >= hash_bits
+ var hash_shift;
- if (
- !_strm.next_out ||
- (!_strm.next_in && _strm.avail_in !== 0) ||
- (status === FINISH_STATE && flush !== Z_FINISH)
- ) {
- _strm.msg = z_errmsg[Z_NEED_DICT - Z_STREAM_ERROR];
- return Z_STREAM_ERROR;
- }
- if (_strm.avail_out === 0) {
- _strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
- return Z_BUF_ERROR;
- }
+ // Window position at the beginning of the current output block. Gets
+ // negative when the window is moved backwards.
- strm = _strm; // just in case
- old_flush = last_flush;
- last_flush = flush;
+ var block_start;
- // Write the zlib header
- if (status === INIT_STATE) {
- header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
- level_flags = ((level - 1) & 0xff) >> 1;
+ var match_length; // length of best match
+ var prev_match; // previous match
+ var match_available; // set if previous match exists
+ var strstart; // start of string to insert
+ var match_start; // start of matching string
+ var lookahead; // number of valid bytes ahead in window
- if (level_flags > 3) level_flags = 3;
- header |= level_flags << 6;
- if (strstart !== 0) header |= PRESET_DICT;
- header += 31 - (header % 31);
+ // Length of the best match at previous step. Matches not greater than this
+ // are discarded. This is used in the lazy match evaluation.
+ var prev_length;
- status = BUSY_STATE;
- putShortMSB(header);
- }
+ // To speed up deflation, hash chains are never searched beyond this
+ // length. A higher limit improves compression ratio but degrades the speed.
+ var max_chain_length;
- // Flush as much pending output as possible
- if (that.pending !== 0) {
- strm.flush_pending();
- if (strm.avail_out === 0) {
- // console.log(" avail_out==0");
- // Since avail_out is 0, deflate will be called again with
- // more output space, but possibly with both pending and
- // avail_in equal to zero. There won't be anything to do,
- // but this is not an error situation so make sure we
- // return OK instead of BUF_ERROR at next call of deflate:
- last_flush = -1;
- return Z_OK;
- }
+ // Attempt to find a better match only when the current match is strictly
+ // smaller than this value. This mechanism is used only for compression
+ // levels >= 4.
+ var max_lazy_match;
- // Make sure there is something to do and avoid duplicate
- // consecutive
- // flushes. For repeated and useless calls with Z_FINISH, we keep
- // returning Z_STREAM_END instead of Z_BUFF_ERROR.
- } else if (
- strm.avail_in === 0 &&
- flush <= old_flush &&
- flush !== Z_FINISH
- ) {
- strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
- return Z_BUF_ERROR;
- }
+ // Insert new strings in the hash table only if the match length is not
+ // greater than this length. This saves time but degrades compression.
+ // max_insert_length is used only for compression levels <= 3.
- // User must not provide more input after the first FINISH:
- if (status === FINISH_STATE && strm.avail_in !== 0) {
- _strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
- return Z_BUF_ERROR;
- }
+ var level; // compression level (1..9)
+ var strategy; // favor or force Huffman coding
- // Start a new block or continue the current one.
- if (
- strm.avail_in !== 0 ||
- lookahead !== 0 ||
- (flush !== Z_NO_FLUSH && status !== FINISH_STATE)
- ) {
- bstate = -1;
- switch (config_table[level].func) {
- case STORED:
- bstate = deflate_stored(flush);
- break;
- case FAST:
- bstate = deflate_fast(flush);
- break;
- case SLOW:
- bstate = deflate_slow(flush);
- break;
- }
+ // Use a faster search when the previous match is longer than this
+ var good_match;
- if (bstate === FinishStarted || bstate === FinishDone) {
- status = FINISH_STATE;
- }
- if (bstate === NeedMore || bstate === FinishStarted) {
- if (strm.avail_out === 0) {
- last_flush = -1; // avoid BUF_ERROR next call, see above
- }
- return Z_OK;
- // If flush !== Z_NO_FLUSH && avail_out === 0, the next call
- // of deflate should use the same flush parameter to make sure
- // that the flush is complete. So we don't have to output an
- // empty block here, this will be done at next call. This also
- // ensures that for a very small output buffer, we emit at most
- // one empty block.
- }
+ // Stop searching when current match exceeds this
+ var nice_match;
- if (bstate === BlockDone) {
- if (flush === Z_PARTIAL_FLUSH) {
- _tr_align();
- } else {
- // FULL_FLUSH or SYNC_FLUSH
- _tr_stored_block(0, 0, false);
- // For a full flush, this empty block will be recognized
- // as a special marker by inflate_sync().
- if (flush === Z_FULL_FLUSH) {
- // state.head[s.hash_size-1]=0;
- for (i = 0; i < hash_size /*-1*/; i++)
- // forget history
- head[i] = 0;
- }
- }
- strm.flush_pending();
- if (strm.avail_out === 0) {
- last_flush = -1; // avoid BUF_ERROR at next call, see above
- return Z_OK;
- }
- }
- }
+ var dyn_ltree; // literal and length tree
+ var dyn_dtree; // distance tree
+ var bl_tree; // Huffman tree for bit lengths
- if (flush !== Z_FINISH) return Z_OK;
- return Z_STREAM_END;
- };
-}
+ var l_desc = new Tree(); // desc for literal tree
+ var d_desc = new Tree(); // desc for distance tree
+ var bl_desc = new Tree(); // desc for bit length tree
-// ZStream
+ // that.heap_len; // number of elements in the heap
+ // that.heap_max; // element of largest frequency
+ // The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
+ // The same heap array is used to build all trees.
-function ZStream() {
- var that = this;
- that.next_in_index = 0;
- that.next_out_index = 0;
- // that.next_in; // next input byte
- that.avail_in = 0; // number of bytes available at next_in
- that.total_in = 0; // total nb of input bytes read so far
- // that.next_out; // next output byte should be put there
- that.avail_out = 0; // remaining free space at next_out
- that.total_out = 0; // total nb of bytes output so far
- // that.msg;
- // that.dstate;
-}
+ // Depth of each subtree used as tie breaker for trees of equal frequency
+ that.depth = [];
-ZStream.prototype = {
- deflateInit: function(level, bits) {
- var that = this;
- that.dstate = new Deflate();
- if (!bits) bits = MAX_BITS;
- return that.dstate.deflateInit(that, level, bits);
- },
+ var l_buf; // index for literals or lengths */
- deflate: function(flush) {
- var that = this;
- if (!that.dstate) {
- return Z_STREAM_ERROR;
- }
- return that.dstate.deflate(that, flush);
- },
+ // Size of match buffer for literals/lengths. There are 4 reasons for
+ // limiting lit_bufsize to 64K:
+ // - frequencies can be kept in 16 bit counters
+ // - if compression is not successful for the first block, all input
+ // data is still in the window so we can still emit a stored block even
+ // when input comes from standard input. (This can also be done for
+ // all blocks if lit_bufsize is not greater than 32K.)
+ // - if compression is not successful for a file smaller than 64K, we can
+ // even emit a stored file instead of a stored block (saving 5 bytes).
+ // This is applicable only for zip (not gzip or zlib).
+ // - creating new Huffman trees less frequently may not provide fast
+ // adaptation to changes in the input data statistics. (Take for
+ // example a binary file with poorly compressible code followed by
+ // a highly compressible string table.) Smaller buffer sizes give
+ // fast adaptation but have of course the overhead of transmitting
+ // trees more frequently.
+ // - I can't count above 4
+ var lit_bufsize;
- deflateEnd: function() {
- var that = this;
- if (!that.dstate) return Z_STREAM_ERROR;
- var ret = that.dstate.deflateEnd();
- that.dstate = null;
- return ret;
- },
+ var last_lit; // running index in l_buf
- deflateParams: function(level, strategy) {
- var that = this;
- if (!that.dstate) return Z_STREAM_ERROR;
- return that.dstate.deflateParams(that, level, strategy);
- },
+ // Buffer for distances. To simplify the code, d_buf and l_buf have
+ // the same number of elements. To use different lengths, an extra flag
+ // array would be necessary.
- deflateSetDictionary: function(dictionary, dictLength) {
- var that = this;
- if (!that.dstate) return Z_STREAM_ERROR;
- return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
- },
+ var d_buf; // index of pendig_buf
- // Read a new buffer from the current input stream, update the
- // total number of bytes read. All deflate() input goes through
- // this function so some applications may wish to modify it to avoid
- // allocating a large strm->next_in buffer and copying from it.
- // (See also flush_pending()).
- read_buf: function(buf, start, size) {
- var that = this;
- var len = that.avail_in;
- if (len > size) len = size;
- if (len === 0) return 0;
- that.avail_in -= len;
- buf.set(
- that.next_in.subarray(that.next_in_index, that.next_in_index + len),
- start
- );
- that.next_in_index += len;
- that.total_in += len;
- return len;
- },
+ // that.opt_len; // bit length of current block with optimal trees
+ // that.static_len; // bit length of current block with static trees
+ var matches; // number of string matches in current block
+ var last_eob_len; // bit length of EOB code for last block
- // Flush as much pending output as possible. All deflate() output goes
- // through this function so some applications may wish to modify it
- // to avoid allocating a large strm->next_out buffer and copying into it.
- // (See also read_buf()).
- flush_pending: function() {
- var that = this;
- var len = that.dstate.pending;
+ // Output buffer. bits are inserted starting at the bottom (least
+ // significant bits).
+ var bi_buf;
- if (len > that.avail_out) len = that.avail_out;
- if (len === 0) return;
+ // Number of valid bits in bi_buf. All bits above the last valid bit
+ // are always zero.
+ var bi_valid;
- // if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
- // || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
- // len)) {
- // console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
- // that.next_out_index + ", " + len);
- // console.log("avail_out=" + that.avail_out);
- // }
+ // number of codes at each bit length for an optimal tree
+ that.bl_count = [];
- that.next_out.set(
- that.dstate.pending_buf.subarray(
- that.dstate.pending_out,
- that.dstate.pending_out + len
- ),
- that.next_out_index
- );
+ // heap used to build the Huffman trees
+ that.heap = [];
- that.next_out_index += len;
- that.dstate.pending_out += len;
- that.total_out += len;
- that.avail_out -= len;
- that.dstate.pending -= len;
- if (that.dstate.pending === 0) {
- that.dstate.pending_out = 0;
+ dyn_ltree = [];
+ dyn_dtree = [];
+ bl_tree = [];
+
+ function lm_init() {
+ var i;
+ window_size = 2 * w_size;
+
+ head[hash_size - 1] = 0;
+ for (i = 0; i < hash_size - 1; i++) {
+ head[i] = 0;
}
+
+ // Set the default configuration parameters:
+ max_lazy_match = config_table[level].max_lazy;
+ good_match = config_table[level].good_length;
+ nice_match = config_table[level].nice_length;
+ max_chain_length = config_table[level].max_chain;
+
+ strstart = 0;
+ block_start = 0;
+ lookahead = 0;
+ match_length = prev_length = MIN_MATCH - 1;
+ match_available = 0;
+ ins_h = 0;
}
-};
-// Deflater
+ function init_block() {
+ var i;
+ // Initialize the trees.
+ for (i = 0; i < L_CODES; i++) dyn_ltree[i * 2] = 0;
+ for (i = 0; i < D_CODES; i++) dyn_dtree[i * 2] = 0;
+ for (i = 0; i < BL_CODES; i++) bl_tree[i * 2] = 0;
+
+ dyn_ltree[END_BLOCK * 2] = 1;
+ that.opt_len = that.static_len = 0;
+ last_lit = matches = 0;
+ }
+
+ // Initialize the tree data structures for a new zlib stream.
+ function tr_init() {
+ l_desc.dyn_tree = dyn_ltree;
+ l_desc.stat_desc = StaticTree.static_l_desc;
-function Deflater(options) {
- var that = this;
- var z = new ZStream();
- var bufsize = 512;
- var flush = Z_NO_FLUSH;
- var buf = new Uint8Array(bufsize);
- var level = options ? options.level : Z_DEFAULT_COMPRESSION;
- if (typeof level === "undefined") level = Z_DEFAULT_COMPRESSION;
- z.deflateInit(level);
- z.next_out = buf;
+ d_desc.dyn_tree = dyn_dtree;
+ d_desc.stat_desc = StaticTree.static_d_desc;
- that.append = function(data, onprogress) {
- var err,
- buffers = [],
- lastIndex = 0,
- bufferIndex = 0,
- bufferSize = 0,
- array;
- if (!data.length) return;
- z.next_in_index = 0;
- z.next_in = data;
- z.avail_in = data.length;
- do {
- z.next_out_index = 0;
- z.avail_out = bufsize;
- err = z.deflate(flush);
- if (err !== Z_OK) throw new Error("deflating: " + z.msg);
- if (z.next_out_index)
- if (z.next_out_index === bufsize) buffers.push(new Uint8Array(buf));
- else buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
- bufferSize += z.next_out_index;
- if (onprogress && z.next_in_index > 0 && z.next_in_index !== lastIndex) {
- onprogress(z.next_in_index);
- lastIndex = z.next_in_index;
- }
- } while (z.avail_in > 0 || z.avail_out === 0);
- array = new Uint8Array(bufferSize);
- buffers.forEach(function(chunk) {
- array.set(chunk, bufferIndex);
- bufferIndex += chunk.length;
- });
- return array;
- };
- that.flush = function() {
- var err,
- buffers = [],
- bufferIndex = 0,
- bufferSize = 0,
- array;
- do {
- z.next_out_index = 0;
- z.avail_out = bufsize;
- err = z.deflate(Z_FINISH);
- if (err !== Z_STREAM_END && err !== Z_OK)
- throw new Error("deflating: " + z.msg);
- if (bufsize - z.avail_out > 0)
- buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
- bufferSize += z.next_out_index;
- } while (z.avail_in > 0 || z.avail_out === 0);
- z.deflateEnd();
- array = new Uint8Array(bufferSize);
- buffers.forEach(function(chunk) {
- array.set(chunk, bufferIndex);
- bufferIndex += chunk.length;
- });
- return array;
- };
-}
+ bl_desc.dyn_tree = bl_tree;
+ bl_desc.stat_desc = StaticTree.static_bl_desc;
-/**
- * @license
- * jsPDF filters PlugIn
- * Copyright (c) 2014 Aras Abbasi
- *
- * Licensed under the MIT License.
- * http://opensource.org/licenses/mit-license
- */
+ bi_buf = 0;
+ bi_valid = 0;
+ last_eob_len = 8; // enough lookahead for inflate
-(function(jsPDFAPI) {
+ // Initialize the first block of the first file:
+ init_block();
+ }
- var ASCII85Encode = function(a) {
- var b, c, d, e, f, g, h, i, j, k;
- // eslint-disable-next-line no-control-regex
- for (
- !/[^\x00-\xFF]/.test(a),
- b = "\x00\x00\x00\x00".slice(a.length % 4 || 4),
- a += b,
- c = [],
- d = 0,
- e = a.length;
- e > d;
- d += 4
- )
- (f =
- (a.charCodeAt(d) << 24) +
- (a.charCodeAt(d + 1) << 16) +
- (a.charCodeAt(d + 2) << 8) +
- a.charCodeAt(d + 3)),
- 0 !== f
- ? ((k = f % 85),
- (f = (f - k) / 85),
- (j = f % 85),
- (f = (f - j) / 85),
- (i = f % 85),
- (f = (f - i) / 85),
- (h = f % 85),
- (f = (f - h) / 85),
- (g = f % 85),
- c.push(g + 33, h + 33, i + 33, j + 33, k + 33))
- : c.push(122);
- return (
- (function(a, b) {
- for (var c = b; c > 0; c--) a.pop();
- })(c, b.length),
- String.fromCharCode.apply(String, c) + "~>"
- );
- };
+ // Restore the heap property by moving down the tree starting at node k,
+ // exchanging a node with the smallest of its two sons if necessary,
+ // stopping
+ // when the heap property is re-established (each father smaller than its
+ // two sons).
+ that.pqdownheap = function(
+ tree, // the tree to restore
+ k // node to move down
+ ) {
+ var heap = that.heap;
+ var v = heap[k];
+ var j = k << 1; // left son of k
+ while (j <= that.heap_len) {
+ // Set j to the smallest of the two sons:
+ if (
+ j < that.heap_len &&
+ smaller(tree, heap[j + 1], heap[j], that.depth)
+ ) {
+ j++;
+ }
+ // Exit if v is smaller than both sons
+ if (smaller(tree, v, heap[j], that.depth)) break;
- var ASCII85Decode = function(a) {
- var c,
- d,
- e,
- f,
- g,
- h = String,
- l = "length",
- w = 255,
- x = "charCodeAt",
- y = "slice",
- z = "replace";
- for (
- "~>" === a[y](-2),
- a = a[y](0, -2)
- [z](/\s/g, "")
- [z]("z", "!!!!!"),
- c = "uuuuu"[y](a[l] % 5 || 5),
- a += c,
- e = [],
- f = 0,
- g = a[l];
- g > f;
- f += 5
- )
- (d =
- 52200625 * (a[x](f) - 33) +
- 614125 * (a[x](f + 1) - 33) +
- 7225 * (a[x](f + 2) - 33) +
- 85 * (a[x](f + 3) - 33) +
- (a[x](f + 4) - 33)),
- e.push(w & (d >> 24), w & (d >> 16), w & (d >> 8), w & d);
- return (
- (function(a, b) {
- for (var c = b; c > 0; c--) a.pop();
- })(e, c[l]),
- h.fromCharCode.apply(h, e)
- );
+ // Exchange v with the smallest son
+ heap[k] = heap[j];
+ k = j;
+ // And continue down the tree, setting j to the left son of k
+ j <<= 1;
+ }
+ heap[k] = v;
};
- var ASCIIHexEncode = function(value) {
- return (
- value
- .split("")
- .map(function(value) {
- return ("0" + value.charCodeAt().toString(16)).slice(-2);
- })
- .join("") + ">"
- );
- };
+ // Scan a literal or distance tree to determine the frequencies of the codes
+ // in the bit length tree.
+ function scan_tree(
+ tree, // the tree to be scanned
+ max_code // and its largest code of non zero frequency
+ ) {
+ var n; // iterates over all tree elements
+ var prevlen = -1; // last emitted length
+ var curlen; // length of current code
+ var nextlen = tree[0 * 2 + 1]; // length of next code
+ var count = 0; // repeat count of the current code
+ var max_count = 7; // max repeat count
+ var min_count = 4; // min repeat count
- var ASCIIHexDecode = function(value) {
- var regexCheckIfHex = new RegExp(/^([0-9A-Fa-f]{2})+$/);
- value = value.replace(/\s/g, "");
- if (value.indexOf(">") !== -1) {
- value = value.substr(0, value.indexOf(">"));
- }
- if (value.length % 2) {
- value += "0";
+ if (nextlen === 0) {
+ max_count = 138;
+ min_count = 3;
}
- if (regexCheckIfHex.test(value) === false) {
- return "";
+ tree[(max_code + 1) * 2 + 1] = 0xffff; // guard
+
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen;
+ nextlen = tree[(n + 1) * 2 + 1];
+ if (++count < max_count && curlen === nextlen) {
+ continue;
+ } else if (count < min_count) {
+ bl_tree[curlen * 2] += count;
+ } else if (curlen !== 0) {
+ if (curlen !== prevlen) bl_tree[curlen * 2]++;
+ bl_tree[REP_3_6 * 2]++;
+ } else if (count <= 10) {
+ bl_tree[REPZ_3_10 * 2]++;
+ } else {
+ bl_tree[REPZ_11_138 * 2]++;
+ }
+ count = 0;
+ prevlen = curlen;
+ if (nextlen === 0) {
+ max_count = 138;
+ min_count = 3;
+ } else if (curlen === nextlen) {
+ max_count = 6;
+ min_count = 3;
+ } else {
+ max_count = 7;
+ min_count = 4;
+ }
}
- var result = "";
- for (var i = 0; i < value.length; i += 2) {
- result += String.fromCharCode("0x" + (value[i] + value[i + 1]));
+ }
+
+ // Construct the Huffman tree for the bit lengths and return the index in
+ // bl_order of the last bit length code to send.
+ function build_bl_tree() {
+ var max_blindex; // index of last bit length code of non zero freq
+
+ // Determine the bit length frequencies for literal and distance trees
+ scan_tree(dyn_ltree, l_desc.max_code);
+ scan_tree(dyn_dtree, d_desc.max_code);
+
+ // Build the bit length tree:
+ bl_desc.build_tree(that);
+ // opt_len now includes the length of the tree representations, except
+ // the lengths of the bit lengths codes and the 5+5+4 bits for the
+ // counts.
+
+ // Determine the number of bit length codes to send. The pkzip format
+ // requires that at least 4 bit length codes be sent. (appnote.txt says
+ // 3 but the actual value used is 4.)
+ for (max_blindex = BL_CODES - 1; max_blindex >= 3; max_blindex--) {
+ if (bl_tree[Tree.bl_order[max_blindex] * 2 + 1] !== 0) break;
}
- return result;
- };
- /*
- var FlatePredictors = {
- None: 1,
- TIFF: 2,
- PNG_None: 10,
- PNG_Sub: 11,
- PNG_Up: 12,
- PNG_Average: 13,
- PNG_Paeth: 14,
- PNG_Optimum: 15
- };
- */
+ // Update opt_len to include the bit length tree and counts
+ that.opt_len += 3 * (max_blindex + 1) + 5 + 5 + 4;
- var appendBuffer = function(buffer1, buffer2) {
- var combinedBuffer = new Uint8Array(
- buffer1.byteLength + buffer2.byteLength
- );
- combinedBuffer.set(new Uint8Array(buffer1), 0);
- combinedBuffer.set(new Uint8Array(buffer2), buffer1.byteLength);
- return combinedBuffer;
- };
+ return max_blindex;
+ }
- var FlateEncode = function(data) {
- var arr = [];
- var i = data.length;
- var adler32;
- var deflater;
+ // Output a byte on the stream.
+ // IN assertion: there is enough room in pending_buf.
+ function put_byte(p) {
+ that.pending_buf[that.pending++] = p;
+ }
- while (i--) {
- arr[i] = data.charCodeAt(i);
+ function put_short(w) {
+ put_byte(w & 0xff);
+ put_byte((w >>> 8) & 0xff);
+ }
+
+ function putShortMSB(b) {
+ put_byte((b >> 8) & 0xff);
+ put_byte(b & 0xff & 0xff);
+ }
+
+ function send_bits(value, length) {
+ var val,
+ len = length;
+ if (bi_valid > Buf_size - len) {
+ val = value;
+ // bi_buf |= (val << bi_valid);
+ bi_buf |= (val << bi_valid) & 0xffff;
+ put_short(bi_buf);
+ bi_buf = val >>> (Buf_size - bi_valid);
+ bi_valid += len - Buf_size;
+ } else {
+ // bi_buf |= (value) << bi_valid;
+ bi_buf |= (value << bi_valid) & 0xffff;
+ bi_valid += len;
}
- adler32 = jsPDFAPI.adler32cs.from(data);
- deflater = new Deflater(6);
- data = deflater.append(new Uint8Array(arr));
- data = appendBuffer(data, deflater.flush());
- arr = new Uint8Array(data.byteLength + 6);
- arr.set(new Uint8Array([120, 156]));
- arr.set(data, 2);
- arr.set(
- new Uint8Array([
- adler32 & 0xff,
- (adler32 >> 8) & 0xff,
- (adler32 >> 16) & 0xff,
- (adler32 >> 24) & 0xff
- ]),
- data.byteLength + 2
- );
- data = arr.reduce(function(data, byte) {
- return data + String.fromCharCode(byte);
- }, "");
- return data;
- };
+ }
- jsPDFAPI.processDataByFilters = function(origData, filterChain) {
- var i = 0;
- var data = origData || "";
- var reverseChain = [];
- filterChain = filterChain || [];
+ function send_code(c, tree) {
+ var c2 = c * 2;
+ send_bits(tree[c2] & 0xffff, tree[c2 + 1] & 0xffff);
+ }
- if (typeof filterChain === "string") {
- filterChain = [filterChain];
+ // Send a literal or distance tree in compressed form, using the codes in
+ // bl_tree.
+ function send_tree(
+ tree, // the tree to be sent
+ max_code // and its largest code of non zero frequency
+ ) {
+ var n; // iterates over all tree elements
+ var prevlen = -1; // last emitted length
+ var curlen; // length of current code
+ var nextlen = tree[0 * 2 + 1]; // length of next code
+ var count = 0; // repeat count of the current code
+ var max_count = 7; // max repeat count
+ var min_count = 4; // min repeat count
+
+ if (nextlen === 0) {
+ max_count = 138;
+ min_count = 3;
}
- for (i = 0; i < filterChain.length; i += 1) {
- switch (filterChain[i]) {
- case "ASCII85Decode":
- case "/ASCII85Decode":
- data = ASCII85Decode(data);
- reverseChain.push("/ASCII85Encode");
- break;
- case "ASCII85Encode":
- case "/ASCII85Encode":
- data = ASCII85Encode(data);
- reverseChain.push("/ASCII85Decode");
- break;
- case "ASCIIHexDecode":
- case "/ASCIIHexDecode":
- data = ASCIIHexDecode(data);
- reverseChain.push("/ASCIIHexEncode");
- break;
- case "ASCIIHexEncode":
- case "/ASCIIHexEncode":
- data = ASCIIHexEncode(data);
- reverseChain.push("/ASCIIHexDecode");
- break;
- case "FlateEncode":
- case "/FlateEncode":
- data = FlateEncode(data);
- reverseChain.push("/FlateDecode");
- break;
- default:
- throw new Error(
- 'The filter: "' + filterChain[i] + '" is not implemented'
- );
+ for (n = 0; n <= max_code; n++) {
+ curlen = nextlen;
+ nextlen = tree[(n + 1) * 2 + 1];
+ if (++count < max_count && curlen === nextlen) {
+ continue;
+ } else if (count < min_count) {
+ do {
+ send_code(curlen, bl_tree);
+ } while (--count !== 0);
+ } else if (curlen !== 0) {
+ if (curlen !== prevlen) {
+ send_code(curlen, bl_tree);
+ count--;
+ }
+ send_code(REP_3_6, bl_tree);
+ send_bits(count - 3, 2);
+ } else if (count <= 10) {
+ send_code(REPZ_3_10, bl_tree);
+ send_bits(count - 3, 3);
+ } else {
+ send_code(REPZ_11_138, bl_tree);
+ send_bits(count - 11, 7);
+ }
+ count = 0;
+ prevlen = curlen;
+ if (nextlen === 0) {
+ max_count = 138;
+ min_count = 3;
+ } else if (curlen === nextlen) {
+ max_count = 6;
+ min_count = 3;
+ } else {
+ max_count = 7;
+ min_count = 4;
}
}
+ }
- return { data: data, reverseChain: reverseChain.reverse().join(" ") };
- };
-})(jsPDF.API);
+ // Send the header for a block using dynamic Huffman trees: the counts, the
+ // lengths of the bit length codes, the literal tree and the distance tree.
+ // IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
+ function send_all_trees(lcodes, dcodes, blcodes) {
+ var rank; // index in bl_order
-/**
- * @license
- * jsPDF fileloading PlugIn
- * Copyright (c) 2018 Aras Abbasi (aras.abbasi@gmail.com)
- *
- * Licensed under the MIT License.
- * http://opensource.org/licenses/mit-license
- */
+ send_bits(lcodes - 257, 5); // not +255 as stated in appnote.txt
+ send_bits(dcodes - 1, 5);
+ send_bits(blcodes - 4, 4); // not -3 as stated in appnote.txt
+ for (rank = 0; rank < blcodes; rank++) {
+ send_bits(bl_tree[Tree.bl_order[rank] * 2 + 1], 3);
+ }
+ send_tree(dyn_ltree, lcodes - 1); // literal tree
+ send_tree(dyn_dtree, dcodes - 1); // distance tree
+ }
-/**
- * @name fileloading
- * @module
- */
-(function(jsPDFAPI) {
+ // Flush the bit buffer, keeping at most 7 bits in it.
+ function bi_flush() {
+ if (bi_valid === 16) {
+ put_short(bi_buf);
+ bi_buf = 0;
+ bi_valid = 0;
+ } else if (bi_valid >= 8) {
+ put_byte(bi_buf & 0xff);
+ bi_buf >>>= 8;
+ bi_valid -= 8;
+ }
+ }
+
+ // Send one empty static block to give enough lookahead for inflate.
+ // This takes 10 bits, of which 7 may remain in the bit buffer.
+ // The current inflate code requires 9 bits of lookahead. If the
+ // last two codes for the previous block (real code plus EOB) were coded
+ // on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
+ // the last real code. In this case we send two empty static blocks instead
+ // of one. (There are no problems if the previous block is stored or fixed.)
+ // To simplify the code, we assume the worst case of last real code encoded
+ // on one bit only.
+ function _tr_align() {
+ send_bits(STATIC_TREES << 1, 3);
+ send_code(END_BLOCK, StaticTree.static_ltree);
+
+ bi_flush();
+
+ // Of the 10 bits for the empty block, we have already sent
+ // (10 - bi_valid) bits. The lookahead for the last real code (before
+ // the EOB of the previous block) was thus at least one plus the length
+ // of the EOB plus what we have just sent of the empty static block.
+ if (1 + last_eob_len + 10 - bi_valid < 9) {
+ send_bits(STATIC_TREES << 1, 3);
+ send_code(END_BLOCK, StaticTree.static_ltree);
+ bi_flush();
+ }
+ last_eob_len = 7;
+ }
+
+ // Save the match info and tally the frequency counts. Return true if
+ // the current block must be flushed.
+ function _tr_tally(
+ dist, // distance of matched string
+ lc // match length-MIN_MATCH or unmatched char (if dist==0)
+ ) {
+ var out_length, in_length, dcode;
+ that.pending_buf[d_buf + last_lit * 2] = (dist >>> 8) & 0xff;
+ that.pending_buf[d_buf + last_lit * 2 + 1] = dist & 0xff;
- /**
- * @name loadFile
- * @function
- * @param {string} url
- * @param {boolean} sync
- * @param {function} callback
- * @returns {string|undefined} result
- */
- jsPDFAPI.loadFile = function(url, sync, callback) {
- return browserRequest(url, sync, callback);
+ that.pending_buf[l_buf + last_lit] = lc & 0xff;
+ last_lit++;
- };
+ if (dist === 0) {
+ // lc is the unmatched char
+ dyn_ltree[lc * 2]++;
+ } else {
+ matches++;
+ // Here, lc is the match length - MIN_MATCH
+ dist--; // dist = match distance - 1
+ dyn_ltree[(Tree._length_code[lc] + LITERALS + 1) * 2]++;
+ dyn_dtree[Tree.d_code(dist) * 2]++;
+ }
- /**
- * @name loadImageFile
- * @function
- * @param {string} path
- * @param {boolean} sync
- * @param {function} callback
- */
- jsPDFAPI.loadImageFile = jsPDFAPI.loadFile;
+ if ((last_lit & 0x1fff) === 0 && level > 2) {
+ // Compute an upper bound for the compressed length
+ out_length = last_lit * 8;
+ in_length = strstart - block_start;
+ for (dcode = 0; dcode < D_CODES; dcode++) {
+ out_length += dyn_dtree[dcode * 2] * (5 + Tree.extra_dbits[dcode]);
+ }
+ out_length >>>= 3;
+ if (
+ matches < Math.floor(last_lit / 2) &&
+ out_length < Math.floor(in_length / 2)
+ )
+ return true;
+ }
- function browserRequest(url, sync, callback) {
- sync = sync === false ? false : true;
- callback = typeof callback === "function" ? callback : function() {};
- var result = undefined;
+ return last_lit === lit_bufsize - 1;
+ // We avoid equality with lit_bufsize because of wraparound at 64K
+ // on 16 bit machines and because stored blocks are restricted to
+ // 64K-1 bytes.
+ }
- var xhr = function(url, sync, callback) {
- var request = new XMLHttpRequest();
- var i = 0;
+ // Send the block data compressed using the given Huffman trees
+ function compress_block(ltree, dtree) {
+ var dist; // distance of matched string
+ var lc; // match length or unmatched char (if dist === 0)
+ var lx = 0; // running index in l_buf
+ var code; // the code to send
+ var extra; // number of extra bits to send
- var sanitizeUnicode = function(data) {
- var dataLength = data.length;
- var charArray = [];
- var StringFromCharCode = String.fromCharCode;
+ if (last_lit !== 0) {
+ do {
+ dist =
+ ((that.pending_buf[d_buf + lx * 2] << 8) & 0xff00) |
+ (that.pending_buf[d_buf + lx * 2 + 1] & 0xff);
+ lc = that.pending_buf[l_buf + lx] & 0xff;
+ lx++;
- //Transform Unicode to ASCII
- for (i = 0; i < dataLength; i += 1) {
- charArray.push(StringFromCharCode(data.charCodeAt(i) & 0xff));
- }
- return charArray.join("");
- };
+ if (dist === 0) {
+ send_code(lc, ltree); // send a literal byte
+ } else {
+ // Here, lc is the match length - MIN_MATCH
+ code = Tree._length_code[lc];
- request.open("GET", url, !sync);
- // XHR binary charset opt by Marcus Granado 2006 [http://mgran.blogspot.com]
- request.overrideMimeType("text/plain; charset=x-user-defined");
+ send_code(code + LITERALS + 1, ltree); // send the length
+ // code
+ extra = Tree.extra_lbits[code];
+ if (extra !== 0) {
+ lc -= Tree.base_length[code];
+ send_bits(lc, extra); // send the extra length bits
+ }
+ dist--; // dist is now the match distance - 1
+ code = Tree.d_code(dist);
- if (sync === false) {
- request.onload = function() {
- if (request.status === 200) {
- callback(sanitizeUnicode(this.responseText));
- } else {
- callback(undefined);
+ send_code(code, dtree); // send the distance code
+ extra = Tree.extra_dbits[code];
+ if (extra !== 0) {
+ dist -= Tree.base_dist[code];
+ send_bits(dist, extra); // send the extra distance bits
}
- };
- }
- request.send(null);
+ } // literal or match pair ?
- if (sync && request.status === 200) {
- return sanitizeUnicode(request.responseText);
- }
- };
- try {
- result = xhr(url, sync, callback);
- // eslint-disable-next-line no-empty
- } catch (e) {}
- return result;
- }
-})(jsPDF.API);
+ // Check that the overlay between pending_buf and d_buf+l_buf is
+ // ok:
+ } while (lx < last_lit);
+ }
-/**
- * @license
- * Copyright (c) 2018 Erik Koopmans
- * Released under the MIT License.
- *
- * Licensed under the MIT License.
- * http://opensource.org/licenses/mit-license
- */
+ send_code(END_BLOCK, ltree);
+ last_eob_len = ltree[END_BLOCK * 2 + 1];
+ }
-/**
- * jsPDF html PlugIn
- *
- * @name html
- * @module
- */
-(function(jsPDFAPI) {
+ // Flush the bit buffer and align the output on a byte boundary
+ function bi_windup() {
+ if (bi_valid > 8) {
+ put_short(bi_buf);
+ } else if (bi_valid > 0) {
+ put_byte(bi_buf & 0xff);
+ }
+ bi_buf = 0;
+ bi_valid = 0;
+ }
- function loadHtml2Canvas() {
- return (function() {
- if (globalObject["html2canvas"]) {
- return Promise.resolve(globalObject["html2canvas"]);
- }
+ // Copy a stored block, storing first the length and its
+ // one's complement if requested.
+ function copy_block(
+ buf, // the input data
+ len, // its length
+ header // true if block header must be written
+ ) {
+ bi_windup(); // align on byte boundary
+ last_eob_len = 8; // enough lookahead for inflate
- return import('html2canvas');
+ if (header) {
+ put_short(len);
+ put_short(~len);
+ }
- })()
- .catch(function(e) {
- return Promise.reject(new Error("Could not load dompurify: " + e));
- })
- .then(function(html2canvas) {
- return html2canvas.default ? html2canvas.default : html2canvas;
- });
+ that.pending_buf.set(window.subarray(buf, buf + len), that.pending);
+ that.pending += len;
}
- function loadDomPurify() {
- return (function() {
- if (globalObject["DOMPurify"]) {
- return Promise.resolve(globalObject["DOMPurify"]);
- }
+ // Send a stored block
+ function _tr_stored_block(
+ buf, // input block
+ stored_len, // length of input block
+ eof // true if this is the last block for a file
+ ) {
+ send_bits((STORED_BLOCK << 1) + (eof ? 1 : 0), 3); // send block type
+ copy_block(buf, stored_len, true); // with header
+ }
- return import('dompurify');
+ // Determine the best encoding for the current block: dynamic trees, static
+ // trees or store, and output the encoded block to the zip file.
+ function _tr_flush_block(
+ buf, // input block, or NULL if too old
+ stored_len, // length of input block
+ eof // true if this is the last block for a file
+ ) {
+ var opt_lenb, static_lenb; // opt_len and static_len in bytes
+ var max_blindex = 0; // index of last bit length code of non zero freq
- })()
- .catch(function(e) {
- return Promise.reject(new Error("Could not load dompurify: " + e));
- })
- .then(function(dompurify) {
- return dompurify.default ? dompurify.default : dompurify;
- });
- }
+ // Build the Huffman trees unless a stored block is forced
+ if (level > 0) {
+ // Construct the literal and distance trees
+ l_desc.build_tree(that);
- /**
- * Determine the type of a variable/object.
- *
- * @private
- * @ignore
- */
- var objType = function(obj) {
- var type = typeof obj;
- if (type === "undefined") return "undefined";
- else if (type === "string" || obj instanceof String) return "string";
- else if (type === "number" || obj instanceof Number) return "number";
- else if (type === "function" || obj instanceof Function) return "function";
- else if (!!obj && obj.constructor === Array) return "array";
- else if (obj && obj.nodeType === 1) return "element";
- else if (type === "object") return "object";
- else return "unknown";
- };
+ d_desc.build_tree(that);
- /**
- * Create an HTML element with optional className, innerHTML, and style.
- *
- * @private
- * @ignore
- */
- var createElement = function(tagName, opt) {
- var el = document.createElement(tagName);
- if (opt.className) el.className = opt.className;
- if (opt.innerHTML && opt.dompurify) {
- el.innerHTML = opt.dompurify.sanitize(opt.innerHTML);
- }
- for (var key in opt.style) {
- el.style[key] = opt.style[key];
+ // At this point, opt_len and static_len are the total bit lengths
+ // of
+ // the compressed block data, excluding the tree representations.
+
+ // Build the bit length tree for the above two trees, and get the
+ // index
+ // in bl_order of the last bit length code to send.
+ max_blindex = build_bl_tree();
+
+ // Determine the best encoding. Compute first the block length in
+ // bytes
+ opt_lenb = (that.opt_len + 3 + 7) >>> 3;
+ static_lenb = (that.static_len + 3 + 7) >>> 3;
+
+ if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
+ } else {
+ opt_lenb = static_lenb = stored_len + 5; // force a stored block
}
- return el;
- };
- /**
- * Deep-clone a node and preserve contents/properties.
- *
- * @private
- * @ignore
- */
- var cloneNode = function(node, javascriptEnabled) {
- // Recursively clone the node.
- var clone =
- node.nodeType === 3
- ? document.createTextNode(node.nodeValue)
- : node.cloneNode(false);
- for (var child = node.firstChild; child; child = child.nextSibling) {
- if (
- javascriptEnabled === true ||
- child.nodeType !== 1 ||
- child.nodeName !== "SCRIPT"
- ) {
- clone.appendChild(cloneNode(child, javascriptEnabled));
- }
+ if (stored_len + 4 <= opt_lenb && buf !== -1) {
+ // 4: two words for the lengths
+ // The test buf !== NULL is only necessary if LIT_BUFSIZE > WSIZE.
+ // Otherwise we can't have processed more than WSIZE input bytes
+ // since
+ // the last block flush, because compression would have been
+ // successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
+ // transform a block into a stored block.
+ _tr_stored_block(buf, stored_len, eof);
+ } else if (static_lenb === opt_lenb) {
+ send_bits((STATIC_TREES << 1) + (eof ? 1 : 0), 3);
+ compress_block(StaticTree.static_ltree, StaticTree.static_dtree);
+ } else {
+ send_bits((DYN_TREES << 1) + (eof ? 1 : 0), 3);
+ send_all_trees(l_desc.max_code + 1, d_desc.max_code + 1, max_blindex + 1);
+ compress_block(dyn_ltree, dyn_dtree);
}
- if (node.nodeType === 1) {
- // Preserve contents/properties of special nodes.
- if (node.nodeName === "CANVAS") {
- clone.width = node.width;
- clone.height = node.height;
- clone.getContext("2d").drawImage(node, 0, 0);
- } else if (node.nodeName === "TEXTAREA" || node.nodeName === "SELECT") {
- clone.value = node.value;
- }
+ // The above check is made mod 2^32, for files larger than 512 MB
+ // and uLong implemented on 32 bits.
- // Preserve the node's scroll position when it loads.
- clone.addEventListener(
- "load",
- function() {
- clone.scrollTop = node.scrollTop;
- clone.scrollLeft = node.scrollLeft;
- },
- true
- );
+ init_block();
+
+ if (eof) {
+ bi_windup();
}
+ }
- // Return the cloned node.
- return clone;
- };
+ function flush_block_only(eof) {
+ _tr_flush_block(
+ block_start >= 0 ? block_start : -1,
+ strstart - block_start,
+ eof
+ );
+ block_start = strstart;
+ strm.flush_pending();
+ }
- /* ----- CONSTRUCTOR ----- */
+ // Fill the window when the lookahead becomes insufficient.
+ // Updates strstart and lookahead.
+ //
+ // IN assertion: lookahead < MIN_LOOKAHEAD
+ // OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
+ // At least one byte has been read, or avail_in === 0; reads are
+ // performed for at least two bytes (required for the zip translate_eol
+ // option -- not supported here).
+ function fill_window() {
+ var n, m;
+ var p;
+ var more; // Amount of free space at the end of the window.
- var Worker = function Worker(opt) {
- // Create the root parent for the proto chain, and the starting Worker.
- var root = Object.assign(
- Worker.convert(Promise.resolve()),
- JSON.parse(JSON.stringify(Worker.template))
- );
- var self = Worker.convert(Promise.resolve(), root);
+ do {
+ more = window_size - lookahead - strstart;
- // Set progress, optional settings, and return.
- self = self.setProgress(1, Worker, 1, [Worker]);
- self = self.set(opt);
- return self;
- };
+ // Deal with !@#$% 64K limit:
+ if (more === 0 && strstart === 0 && lookahead === 0) {
+ more = w_size;
+ } else if (more === -1) {
+ // Very unlikely, but possible on 16 bit machine if strstart ==
+ // 0
+ // and lookahead === 1 (input done one byte at time)
+ more--;
- // Boilerplate for subclassing Promise.
- Worker.prototype = Object.create(Promise.prototype);
- Worker.prototype.constructor = Worker;
+ // If the window is almost full and there is insufficient
+ // lookahead,
+ // move the upper half to the lower one to make room in the
+ // upper half.
+ } else if (strstart >= w_size + w_size - MIN_LOOKAHEAD) {
+ window.set(window.subarray(w_size, w_size + w_size), 0);
- // Converts/casts promises into Workers.
- Worker.convert = function convert(promise, inherit) {
- // Uses prototypal inheritance to receive changes made to ancestors' properties.
- promise.__proto__ = inherit || Worker.prototype;
- return promise;
- };
+ match_start -= w_size;
+ strstart -= w_size; // we now have strstart >= MAX_DIST
+ block_start -= w_size;
- Worker.template = {
- prop: {
- src: null,
- container: null,
- overlay: null,
- canvas: null,
- img: null,
- pdf: null,
- pageSize: null,
- callback: function() {}
- },
- progress: {
- val: 0,
- state: null,
- n: 0,
- stack: []
- },
- opt: {
- filename: "file.pdf",
- margin: [0, 0, 0, 0],
- enableLinks: true,
- x: 0,
- y: 0,
- html2canvas: {},
- jsPDF: {},
- backgroundColor: "transparent"
- }
- };
+ // Slide the hash table (could be avoided with 32 bit values
+ // at the expense of memory usage). We slide even when level ==
+ // 0
+ // to keep the hash table consistent if we switch back to level
+ // > 0
+ // later. (Using level 0 permanently is not an optimal usage of
+ // zlib, so we don't care about this pathological case.)
- /* ----- FROM / TO ----- */
+ n = hash_size;
+ p = n;
+ do {
+ m = head[--p] & 0xffff;
+ head[p] = m >= w_size ? m - w_size : 0;
+ } while (--n !== 0);
- Worker.prototype.from = function from(src, type) {
- function getType(src) {
- switch (objType(src)) {
- case "string":
- return "string";
- case "element":
- return src.nodeName.toLowerCase === "canvas" ? "canvas" : "element";
- default:
- return "unknown";
+ n = w_size;
+ p = n;
+ do {
+ m = prev[--p] & 0xffff;
+ prev[p] = m >= w_size ? m - w_size : 0;
+ // If n is not on any hash chain, prev[n] is garbage but
+ // its value will never be used.
+ } while (--n !== 0);
+ more += w_size;
}
- }
- return this.then(function from_main() {
- type = type || getType(src);
- switch (type) {
- case "string":
- return this.then(loadDomPurify).then(function(dompurify) {
- return this.set({
- src: createElement("div", {
- innerHTML: src,
- dompurify: dompurify
- })
- });
- });
- case "element":
- return this.set({ src: src });
- case "canvas":
- return this.set({ canvas: src });
- case "img":
- return this.set({ img: src });
- default:
- return this.error("Unknown source type.");
+ if (strm.avail_in === 0) return;
+
+ // If there was no sliding:
+ // strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
+ // more === window_size - lookahead - strstart
+ // => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
+ // => more >= window_size - 2*WSIZE + 2
+ // In the BIG_MEM or MMAP case (not yet supported),
+ // window_size === input_size + MIN_LOOKAHEAD &&
+ // strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
+ // Otherwise, window_size === 2*WSIZE so more >= 2.
+ // If there was sliding, more >= WSIZE. So in all cases, more >= 2.
+
+ n = strm.read_buf(window, strstart + lookahead, more);
+ lookahead += n;
+
+ // Initialize the hash value now that we have some input:
+ if (lookahead >= MIN_MATCH) {
+ ins_h = window[strstart] & 0xff;
+ ins_h =
+ ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
}
- });
- };
+ // If the whole input has less than MIN_MATCH bytes, ins_h is
+ // garbage,
+ // but this is not important since only literal bytes will be
+ // emitted.
+ } while (lookahead < MIN_LOOKAHEAD && strm.avail_in !== 0);
+ }
+
+ // Copy without compression as much as possible from the input stream,
+ // return
+ // the current block state.
+ // This function does not insert new strings in the dictionary since
+ // uncompressible data is probably not useful. This function is used
+ // only for the level=0 compression option.
+ // NOTE: this function should be optimized to avoid extra copying from
+ // window to pending_buf.
+ function deflate_stored(flush) {
+ // Stored blocks are limited to 0xffff bytes, pending_buf is limited
+ // to pending_buf_size, and each stored block has a 5 byte header:
- Worker.prototype.to = function to(target) {
- // Route the 'to' request to the appropriate method.
- switch (target) {
- case "container":
- return this.toContainer();
- case "canvas":
- return this.toCanvas();
- case "img":
- return this.toImg();
- case "pdf":
- return this.toPdf();
- default:
- return this.error("Invalid target.");
+ var max_block_size = 0xffff;
+ var max_start;
+
+ if (max_block_size > pending_buf_size - 5) {
+ max_block_size = pending_buf_size - 5;
}
- };
- Worker.prototype.toContainer = function toContainer() {
- // Set up function prerequisites.
- var prereqs = [
- function checkSrc() {
- return (
- this.prop.src || this.error("Cannot duplicate - no source HTML.")
- );
- },
- function checkPageSize() {
- return this.prop.pageSize || this.setPageSize();
+ // Copy as much as possible from input to output:
+ while (true) {
+ // Fill the window as much as possible:
+ if (lookahead <= 1) {
+ fill_window();
+ if (lookahead === 0 && flush === Z_NO_FLUSH) return NeedMore;
+ if (lookahead === 0) break; // flush the current block
}
- ];
- return this.thenList(prereqs).then(function toContainer_main() {
- // Define the CSS styles for the container and its overlay parent.
- var overlayCSS = {
- position: "fixed",
- overflow: "hidden",
- zIndex: 1000,
- left: "-100000px",
- right: 0,
- bottom: 0,
- top: 0
- };
- var containerCSS = {
- position: "relative",
- display: "inline-block",
- width:
- Math.max(
- this.prop.src.clientWidth,
- this.prop.src.scrollWidth,
- this.prop.src.offsetWidth
- ) + "px",
- left: 0,
- right: 0,
- top: 0,
- margin: "auto",
- backgroundColor: this.opt.backgroundColor
- }; // Set the overlay to hidden (could be changed in the future to provide a print preview).
- var source = cloneNode(
- this.prop.src,
- this.opt.html2canvas.javascriptEnabled
- );
+ strstart += lookahead;
+ lookahead = 0;
- if (source.tagName === "BODY") {
- containerCSS.height =
- Math.max(
- document.body.scrollHeight,
- document.body.offsetHeight,
- document.documentElement.clientHeight,
- document.documentElement.scrollHeight,
- document.documentElement.offsetHeight
- ) + "px";
- }
+ // Emit a stored block if pending_buf will be full:
+ max_start = block_start + max_block_size;
+ if (strstart === 0 || strstart >= max_start) {
+ // strstart === 0 is possible when wraparound on 16-bit machine
+ lookahead = strstart - max_start;
+ strstart = max_start;
- this.prop.overlay = createElement("div", {
- className: "html2pdf__overlay",
- style: overlayCSS
- });
- this.prop.container = createElement("div", {
- className: "html2pdf__container",
- style: containerCSS
- });
- this.prop.container.appendChild(source);
- this.prop.container.firstChild.appendChild(
- createElement("div", {
- style: {
- clear: "both",
- border: "0 none transparent",
- margin: 0,
- padding: 0,
- height: 0
- }
- })
- );
- this.prop.container.style.float = "none";
- this.prop.overlay.appendChild(this.prop.container);
- document.body.appendChild(this.prop.overlay);
- this.prop.container.firstChild.style.position = "relative";
- this.prop.container.height =
- Math.max(
- this.prop.container.firstChild.clientHeight,
- this.prop.container.firstChild.scrollHeight,
- this.prop.container.firstChild.offsetHeight
- ) + "px";
- });
- };
+ flush_block_only(false);
+ if (strm.avail_out === 0) return NeedMore;
+ }
- Worker.prototype.toCanvas = function toCanvas() {
- // Set up function prerequisites.
- var prereqs = [
- function checkContainer() {
- return (
- document.body.contains(this.prop.container) || this.toContainer()
- );
+ // Flush if we may have to slide, otherwise block_start may become
+ // negative and the data will be gone:
+ if (strstart - block_start >= w_size - MIN_LOOKAHEAD) {
+ flush_block_only(false);
+ if (strm.avail_out === 0) return NeedMore;
}
- ];
+ }
- // Fulfill prereqs then create the canvas.
- return this.thenList(prereqs)
- .then(loadHtml2Canvas)
- .then(function toCanvas_main(html2canvas) {
- // Handle old-fashioned 'onrendered' argument.
- var options = Object.assign({}, this.opt.html2canvas);
- delete options.onrendered;
+ flush_block_only(flush === Z_FINISH);
+ if (strm.avail_out === 0)
+ return flush === Z_FINISH ? FinishStarted : NeedMore;
- return html2canvas(this.prop.container, options);
- })
- .then(function toCanvas_post(canvas) {
- // Handle old-fashioned 'onrendered' argument.
- var onRendered = this.opt.html2canvas.onrendered || function() {};
- onRendered(canvas);
+ return flush === Z_FINISH ? FinishDone : BlockDone;
+ }
- this.prop.canvas = canvas;
- document.body.removeChild(this.prop.overlay);
- });
- };
+ function longest_match(cur_match) {
+ var chain_length = max_chain_length; // max hash chain length
+ var scan = strstart; // current string
+ var match; // matched string
+ var len; // length of current match
+ var best_len = prev_length; // best match length so far
+ var limit =
+ strstart > w_size - MIN_LOOKAHEAD
+ ? strstart - (w_size - MIN_LOOKAHEAD)
+ : 0;
+ var _nice_match = nice_match;
- Worker.prototype.toContext2d = function toContext2d() {
- // Set up function prerequisites.
- var prereqs = [
- function checkContainer() {
- return (
- document.body.contains(this.prop.container) || this.toContainer()
- );
- }
- ];
+ // Stop when cur_match becomes <= limit. To simplify the code,
+ // we prevent matches with the string of window index 0.
- // Fulfill prereqs then create the canvas.
- return this.thenList(prereqs)
- .then(loadHtml2Canvas)
- .then(function toContext2d_main(html2canvas) {
- // Handle old-fashioned 'onrendered' argument.
+ var wmask = w_mask;
- var pdf = this.opt.jsPDF;
- var options = Object.assign(
- {
- async: true,
- allowTaint: true,
- scale: 1,
- scrollX: this.opt.scrollX || 0,
- scrollY: this.opt.scrollY || 0,
- backgroundColor: "#ffffff",
- imageTimeout: 15000,
- logging: true,
- proxy: null,
- removeContainer: true,
- foreignObjectRendering: false,
- useCORS: false
- },
- this.opt.html2canvas
- );
- delete options.onrendered;
+ var strend = strstart + MAX_MATCH;
+ var scan_end1 = window[scan + best_len - 1];
+ var scan_end = window[scan + best_len];
- pdf.context2d.autoPaging = true;
- pdf.context2d.posX = this.opt.x;
- pdf.context2d.posY = this.opt.y;
+ // The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of
+ // 16.
+ // It is easy to get rid of this optimization if necessary.
- options.windowHeight = options.windowHeight || 0;
- options.windowHeight =
- options.windowHeight == 0
- ? Math.max(
- this.prop.container.clientHeight,
- this.prop.container.scrollHeight,
- this.prop.container.offsetHeight
- )
- : options.windowHeight;
+ // Do not waste too much time if we already have a good match:
+ if (prev_length >= good_match) {
+ chain_length >>= 2;
+ }
- return html2canvas(this.prop.container, options);
- })
- .then(function toContext2d_post(canvas) {
- // Handle old-fashioned 'onrendered' argument.
- var onRendered = this.opt.html2canvas.onrendered || function() {};
- onRendered(canvas);
+ // Do not look for matches beyond the end of the input. This is
+ // necessary
+ // to make deflate deterministic.
+ if (_nice_match > lookahead) _nice_match = lookahead;
- this.prop.canvas = canvas;
- document.body.removeChild(this.prop.overlay);
- });
- };
+ do {
+ match = cur_match;
+
+ // Skip to next match if the match length cannot increase
+ // or if the match length is less than 2:
+ if (
+ window[match + best_len] !== scan_end ||
+ window[match + best_len - 1] !== scan_end1 ||
+ window[match] !== window[scan] ||
+ window[++match] !== window[scan + 1]
+ )
+ continue;
- Worker.prototype.toImg = function toImg() {
- // Set up function prerequisites.
- var prereqs = [
- function checkCanvas() {
- return this.prop.canvas || this.toCanvas();
- }
- ];
+ // The check at best_len-1 can be removed because it will be made
+ // again later. (This heuristic is not always a win.)
+ // It is not necessary to compare scan[2] and match[2] since they
+ // are always equal when the other bytes match, given that
+ // the hash keys are equal and that HASH_BITS >= 8.
+ scan += 2;
+ match++;
- // Fulfill prereqs then create the image.
- return this.thenList(prereqs).then(function toImg_main() {
- var imgData = this.prop.canvas.toDataURL(
- "image/" + this.opt.image.type,
- this.opt.image.quality
+ // We check for insufficient lookahead only every 8th comparison;
+ // the 256th check will be made at strstart+258.
+ do {} while (
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ window[++scan] === window[++match] &&
+ scan < strend
);
- this.prop.img = document.createElement("img");
- this.prop.img.src = imgData;
- });
- };
- Worker.prototype.toPdf = function toPdf() {
- // Set up function prerequisites.
- var prereqs = [
- function checkContext2d() {
- return this.toContext2d();
- }
- //function checkCanvas() { return this.prop.canvas || this.toCanvas(); }
- ];
+ len = MAX_MATCH - (strend - scan);
+ scan = strend - MAX_MATCH;
- // Fulfill prereqs then create the image.
- return this.thenList(prereqs).then(function toPdf_main() {
- // Create local copies of frequently used properties.
- this.prop.pdf = this.prop.pdf || this.opt.jsPDF;
- });
- };
+ if (len > best_len) {
+ match_start = cur_match;
+ best_len = len;
+ if (len >= _nice_match) break;
+ scan_end1 = window[scan + best_len - 1];
+ scan_end = window[scan + best_len];
+ }
+ } while (
+ (cur_match = prev[cur_match & wmask] & 0xffff) > limit &&
+ --chain_length !== 0
+ );
- /* ----- OUTPUT / SAVE ----- */
+ if (best_len <= lookahead) return best_len;
+ return lookahead;
+ }
- Worker.prototype.output = function output(type, options, src) {
- // Redirect requests to the correct function (outputPdf / outputImg).
- src = src || "pdf";
- if (src.toLowerCase() === "img" || src.toLowerCase() === "image") {
- return this.outputImg(type, options);
- } else {
- return this.outputPdf(type, options);
- }
- };
+ // Compress as much as possible from the input stream, return the current
+ // block state.
+ // This function does not perform lazy evaluation of matches and inserts
+ // new strings in the dictionary only for unmatched strings or for short
+ // matches. It is used only for the fast compression options.
+ function deflate_fast(flush) {
+ // short hash_head = 0; // head of the hash chain
+ var hash_head = 0; // head of the hash chain
+ var bflush; // set if current block must be flushed
- Worker.prototype.outputPdf = function outputPdf(type, options) {
- // Set up function prerequisites.
- var prereqs = [
- function checkPdf() {
- return this.prop.pdf || this.toPdf();
+ while (true) {
+ // Make sure that we always have enough lookahead, except
+ // at the end of the input file. We need MAX_MATCH bytes
+ // for the next match, plus MIN_MATCH bytes to insert the
+ // string following the next match.
+ if (lookahead < MIN_LOOKAHEAD) {
+ fill_window();
+ if (lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+ return NeedMore;
+ }
+ if (lookahead === 0) break; // flush the current block
}
- ];
- // Fulfill prereqs then perform the appropriate output.
- return this.thenList(prereqs).then(function outputPdf_main() {
- /* Currently implemented output types:
- * https://rawgit.com/MrRio/jsPDF/master/docs/jspdf.js.html#line992
- * save(options), arraybuffer, blob, bloburi/bloburl,
- * datauristring/dataurlstring, dataurlnewwindow, datauri/dataurl
- */
- return this.prop.pdf.output(type, options);
- });
- };
+ // Insert the string window[strstart .. strstart+2] in the
+ // dictionary, and set hash_head to the head of the hash chain:
+ if (lookahead >= MIN_MATCH) {
+ ins_h =
+ ((ins_h << hash_shift) ^
+ (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
+ hash_mask;
- Worker.prototype.outputImg = function outputImg(type) {
- // Set up function prerequisites.
- var prereqs = [
- function checkImg() {
- return this.prop.img || this.toImg();
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = head[ins_h] & 0xffff;
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = strstart;
}
- ];
- // Fulfill prereqs then perform the appropriate output.
- return this.thenList(prereqs).then(function outputImg_main() {
- switch (type) {
- case undefined:
- case "img":
- return this.prop.img;
- case "datauristring":
- case "dataurlstring":
- return this.prop.img.src;
- case "datauri":
- case "dataurl":
- return (document.location.href = this.prop.img.src);
- default:
- throw 'Image output type "' + type + '" is not supported.';
- }
- });
- };
+ // Find the longest match, discarding those <= prev_length.
+ // At this point we have always match_length < MIN_MATCH
- Worker.prototype.save = function save(filename) {
- // Set up function prerequisites.
- var prereqs = [
- function checkPdf() {
- return this.prop.pdf || this.toPdf();
+ if (
+ hash_head !== 0 &&
+ ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD
+ ) {
+ // To simplify the code, we prevent matches with the string
+ // of window index 0 (in particular we have to avoid a match
+ // of the string with itself at the start of the input file).
+ if (strategy !== Z_HUFFMAN_ONLY) {
+ match_length = longest_match(hash_head);
+ }
+ // longest_match() sets match_start
}
- ];
+ if (match_length >= MIN_MATCH) {
+ // check_match(strstart, match_start, match_length);
- // Fulfill prereqs, update the filename (if provided), and save the PDF.
- return this.thenList(prereqs)
- .set(filename ? { filename: filename } : null)
- .then(function save_main() {
- this.prop.pdf.save(this.opt.filename);
- });
- };
+ bflush = _tr_tally(strstart - match_start, match_length - MIN_MATCH);
- Worker.prototype.doCallback = function doCallback() {
- // Set up function prerequisites.
- var prereqs = [
- function checkPdf() {
- return this.prop.pdf || this.toPdf();
- }
- ];
+ lookahead -= match_length;
- // Fulfill prereqs, update the filename (if provided), and save the PDF.
- return this.thenList(prereqs).then(function doCallback_main() {
- this.prop.callback(this.prop.pdf);
- });
- };
+ // Insert new strings in the hash table only if the match length
+ // is not too large. This saves time but degrades compression.
+ if (match_length <= max_lazy_match && lookahead >= MIN_MATCH) {
+ match_length--; // string at strstart already in hash table
+ do {
+ strstart++;
- /* ----- SET / GET ----- */
+ ins_h =
+ ((ins_h << hash_shift) ^
+ (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
+ hash_mask;
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = head[ins_h] & 0xffff;
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = strstart;
- Worker.prototype.set = function set(opt) {
- // TODO: Implement ordered pairs?
+ // strstart never exceeds WSIZE-MAX_MATCH, so there are
+ // always MIN_MATCH bytes ahead.
+ } while (--match_length !== 0);
+ strstart++;
+ } else {
+ strstart += match_length;
+ match_length = 0;
+ ins_h = window[strstart] & 0xff;
- // Silently ignore invalid or empty input.
- if (objType(opt) !== "object") {
- return this;
+ ins_h =
+ ((ins_h << hash_shift) ^ (window[strstart + 1] & 0xff)) & hash_mask;
+ // If lookahead < MIN_MATCH, ins_h is garbage, but it does
+ // not
+ // matter since it will be recomputed at next deflate call.
+ }
+ } else {
+ // No match, output a literal byte
+
+ bflush = _tr_tally(0, window[strstart] & 0xff);
+ lookahead--;
+ strstart++;
+ }
+ if (bflush) {
+ flush_block_only(false);
+ if (strm.avail_out === 0) return NeedMore;
+ }
+ }
+
+ flush_block_only(flush === Z_FINISH);
+ if (strm.avail_out === 0) {
+ if (flush === Z_FINISH) return FinishStarted;
+ else return NeedMore;
}
+ return flush === Z_FINISH ? FinishDone : BlockDone;
+ }
+
+ // Same as above, but achieves better compression. We use a lazy
+ // evaluation for matches: a match is finally adopted only if there is
+ // no better match at the next window position.
+ function deflate_slow(flush) {
+ // short hash_head = 0; // head of hash chain
+ var hash_head = 0; // head of hash chain
+ var bflush; // set if current block must be flushed
+ var max_insert;
+
+ // Process the input block.
+ while (true) {
+ // Make sure that we always have enough lookahead, except
+ // at the end of the input file. We need MAX_MATCH bytes
+ // for the next match, plus MIN_MATCH bytes to insert the
+ // string following the next match.
- // Build an array of setter functions to queue.
- var fns = Object.keys(opt || {}).map(function(key) {
- if (key in Worker.template.prop) {
- // Set pre-defined properties.
- return function set_prop() {
- this.prop[key] = opt[key];
- };
- } else {
- switch (key) {
- case "margin":
- return this.setMargin.bind(this, opt.margin);
- case "jsPDF":
- return function set_jsPDF() {
- this.opt.jsPDF = opt.jsPDF;
- return this.setPageSize();
- };
- case "pageSize":
- return this.setPageSize.bind(this, opt.pageSize);
- default:
- // Set any other properties in opt.
- return function set_opt() {
- this.opt[key] = opt[key];
- };
+ if (lookahead < MIN_LOOKAHEAD) {
+ fill_window();
+ if (lookahead < MIN_LOOKAHEAD && flush === Z_NO_FLUSH) {
+ return NeedMore;
}
+ if (lookahead === 0) break; // flush the current block
}
- }, this);
-
- // Set properties within the promise chain.
- return this.then(function set_main() {
- return this.thenList(fns);
- });
- };
- Worker.prototype.get = function get(key, cbk) {
- return this.then(function get_main() {
- // Fetch the requested property, either as a predefined prop or in opt.
- var val = key in Worker.template.prop ? this.prop[key] : this.opt[key];
- return cbk ? cbk(val) : val;
- });
- };
+ // Insert the string window[strstart .. strstart+2] in the
+ // dictionary, and set hash_head to the head of the hash chain:
- Worker.prototype.setMargin = function setMargin(margin) {
- return this.then(function setMargin_main() {
- // Parse the margin property.
- switch (objType(margin)) {
- case "number":
- margin = [margin, margin, margin, margin];
- // eslint-disable-next-line no-fallthrough
- case "array":
- if (margin.length === 2) {
- margin = [margin[0], margin[1], margin[0], margin[1]];
- }
- if (margin.length === 4) {
- break;
- }
- // eslint-disable-next-line no-fallthrough
- default:
- return this.error("Invalid margin array.");
+ if (lookahead >= MIN_MATCH) {
+ ins_h =
+ ((ins_h << hash_shift) ^
+ (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
+ hash_mask;
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = head[ins_h] & 0xffff;
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = strstart;
}
- // Set the margin property, then update pageSize.
- this.opt.margin = margin;
- }).then(this.setPageSize);
- };
+ // Find the longest match, discarding those <= prev_length.
+ prev_length = match_length;
+ prev_match = match_start;
+ match_length = MIN_MATCH - 1;
- Worker.prototype.setPageSize = function setPageSize(pageSize) {
- function toPx(val, k) {
- return Math.floor(((val * k) / 72) * 96);
- }
+ if (
+ hash_head !== 0 &&
+ prev_length < max_lazy_match &&
+ ((strstart - hash_head) & 0xffff) <= w_size - MIN_LOOKAHEAD
+ ) {
+ // To simplify the code, we prevent matches with the string
+ // of window index 0 (in particular we have to avoid a match
+ // of the string with itself at the start of the input file).
- return this.then(function setPageSize_main() {
- // Retrieve page-size based on jsPDF settings, if not explicitly provided.
- pageSize = pageSize || jsPDF.getPageSize(this.opt.jsPDF);
+ if (strategy !== Z_HUFFMAN_ONLY) {
+ match_length = longest_match(hash_head);
+ }
+ // longest_match() sets match_start
- // Add 'inner' field if not present.
- if (!pageSize.hasOwnProperty("inner")) {
- pageSize.inner = {
- width: pageSize.width - this.opt.margin[1] - this.opt.margin[3],
- height: pageSize.height - this.opt.margin[0] - this.opt.margin[2]
- };
- pageSize.inner.px = {
- width: toPx(pageSize.inner.width, pageSize.k),
- height: toPx(pageSize.inner.height, pageSize.k)
- };
- pageSize.inner.ratio = pageSize.inner.height / pageSize.inner.width;
+ if (
+ match_length <= 5 &&
+ (strategy === Z_FILTERED ||
+ (match_length === MIN_MATCH && strstart - match_start > 4096))
+ ) {
+ // If prev_match is also MIN_MATCH, match_start is garbage
+ // but we will ignore the current match anyway.
+ match_length = MIN_MATCH - 1;
+ }
}
- // Attach pageSize to this.
- this.prop.pageSize = pageSize;
- });
- };
-
- Worker.prototype.setProgress = function setProgress(val, state, n, stack) {
- // Immediately update all progress values.
- if (val != null) this.progress.val = val;
- if (state != null) this.progress.state = state;
- if (n != null) this.progress.n = n;
- if (stack != null) this.progress.stack = stack;
- this.progress.ratio = this.progress.val / this.progress.state;
+ // If there was a match at the previous step and the current
+ // match is not better, output the previous match:
+ if (prev_length >= MIN_MATCH && match_length <= prev_length) {
+ max_insert = strstart + lookahead - MIN_MATCH;
+ // Do not insert strings in hash table beyond this.
- // Return this for command chaining.
- return this;
- };
+ // check_match(strstart-1, prev_match, prev_length);
- Worker.prototype.updateProgress = function updateProgress(
- val,
- state,
- n,
- stack
- ) {
- // Immediately update all progress values, using setProgress.
- return this.setProgress(
- val ? this.progress.val + val : null,
- state ? state : null,
- n ? this.progress.n + n : null,
- stack ? this.progress.stack.concat(stack) : null
- );
- };
+ bflush = _tr_tally(strstart - 1 - prev_match, prev_length - MIN_MATCH);
- /* ----- PROMISE MAPPING ----- */
+ // Insert in hash table all strings up to the end of the match.
+ // strstart-1 and strstart are already inserted. If there is not
+ // enough lookahead, the last two strings are not inserted in
+ // the hash table.
+ lookahead -= prev_length - 1;
+ prev_length -= 2;
+ do {
+ if (++strstart <= max_insert) {
+ ins_h =
+ ((ins_h << hash_shift) ^
+ (window[strstart + (MIN_MATCH - 1)] & 0xff)) &
+ hash_mask;
+ // prev[strstart&w_mask]=hash_head=head[ins_h];
+ hash_head = head[ins_h] & 0xffff;
+ prev[strstart & w_mask] = head[ins_h];
+ head[ins_h] = strstart;
+ }
+ } while (--prev_length !== 0);
+ match_available = 0;
+ match_length = MIN_MATCH - 1;
+ strstart++;
- Worker.prototype.then = function then(onFulfilled, onRejected) {
- // Wrap `this` for encapsulation.
- var self = this;
+ if (bflush) {
+ flush_block_only(false);
+ if (strm.avail_out === 0) return NeedMore;
+ }
+ } else if (match_available !== 0) {
+ // If there was no match at the previous position, output a
+ // single literal. If there was a match but the current match
+ // is longer, truncate the previous match to a single literal.
- return this.thenCore(onFulfilled, onRejected, function then_main(
- onFulfilled,
- onRejected
- ) {
- // Update progress while queuing, calling, and resolving `then`.
- self.updateProgress(null, null, 1, [onFulfilled]);
- return Promise.prototype.then
- .call(this, function then_pre(val) {
- self.updateProgress(null, onFulfilled);
- return val;
- })
- .then(onFulfilled, onRejected)
- .then(function then_post(val) {
- self.updateProgress(1);
- return val;
- });
- });
- };
+ bflush = _tr_tally(0, window[strstart - 1] & 0xff);
- Worker.prototype.thenCore = function thenCore(
- onFulfilled,
- onRejected,
- thenBase
- ) {
- // Handle optional thenBase parameter.
- thenBase = thenBase || Promise.prototype.then;
+ if (bflush) {
+ flush_block_only(false);
+ }
+ strstart++;
+ lookahead--;
+ if (strm.avail_out === 0) return NeedMore;
+ } else {
+ // There is no previous match to compare with, wait for
+ // the next step to decide.
- // Wrap `this` for encapsulation and bind it to the promise handlers.
- var self = this;
- if (onFulfilled) {
- onFulfilled = onFulfilled.bind(self);
- }
- if (onRejected) {
- onRejected = onRejected.bind(self);
+ match_available = 1;
+ strstart++;
+ lookahead--;
+ }
}
- // Cast self into a Promise to avoid polyfills recursively defining `then`.
- var isNative =
- Promise.toString().indexOf("[native code]") !== -1 &&
- Promise.name === "Promise";
- var selfPromise = isNative
- ? self
- : Worker.convert(Object.assign({}, self), Promise.prototype);
+ if (match_available !== 0) {
+ bflush = _tr_tally(0, window[strstart - 1] & 0xff);
+ match_available = 0;
+ }
+ flush_block_only(flush === Z_FINISH);
- // Return the promise, after casting it into a Worker and preserving props.
- var returnVal = thenBase.call(selfPromise, onFulfilled, onRejected);
- return Worker.convert(returnVal, self.__proto__);
- };
+ if (strm.avail_out === 0) {
+ if (flush === Z_FINISH) return FinishStarted;
+ else return NeedMore;
+ }
- Worker.prototype.thenExternal = function thenExternal(
- onFulfilled,
- onRejected
- ) {
- // Call `then` and return a standard promise (exits the Worker chain).
- return Promise.prototype.then.call(this, onFulfilled, onRejected);
- };
+ return flush === Z_FINISH ? FinishDone : BlockDone;
+ }
- Worker.prototype.thenList = function thenList(fns) {
- // Queue a series of promise 'factories' into the promise chain.
- var self = this;
- fns.forEach(function thenList_forEach(fn) {
- self = self.thenCore(fn);
- });
- return self;
- };
+ function deflateReset(strm) {
+ strm.total_in = strm.total_out = 0;
+ strm.msg = null; //
- Worker.prototype["catch"] = function(onRejected) {
- // Bind `this` to the promise handler, call `catch`, and return a Worker.
- if (onRejected) {
- onRejected = onRejected.bind(this);
- }
- var returnVal = Promise.prototype["catch"].call(this, onRejected);
- return Worker.convert(returnVal, this);
- };
+ that.pending = 0;
+ that.pending_out = 0;
- Worker.prototype.catchExternal = function catchExternal(onRejected) {
- // Call `catch` and return a standard promise (exits the Worker chain).
- return Promise.prototype["catch"].call(this, onRejected);
- };
+ status = BUSY_STATE;
- Worker.prototype.error = function error(msg) {
- // Throw the error in the Promise chain.
- return this.then(function error_main() {
- throw new Error(msg);
- });
- };
+ last_flush = Z_NO_FLUSH;
- /* ----- ALIASES ----- */
+ tr_init();
+ lm_init();
+ return Z_OK;
+ }
- Worker.prototype.using = Worker.prototype.set;
- Worker.prototype.saveAs = Worker.prototype.save;
- Worker.prototype.export = Worker.prototype.output;
- Worker.prototype.run = Worker.prototype.then;
+ that.deflateInit = function(
+ strm,
+ _level,
+ bits,
+ _method,
+ memLevel,
+ _strategy
+ ) {
+ if (!_method) _method = Z_DEFLATED;
+ if (!memLevel) memLevel = DEF_MEM_LEVEL;
+ if (!_strategy) _strategy = Z_DEFAULT_STRATEGY;
- // Get dimensions of a PDF page, as determined by jsPDF.
- jsPDF.getPageSize = function(orientation, unit, format) {
- // Decode options object
- if (typeof orientation === "object") {
- var options = orientation;
- orientation = options.orientation;
- unit = options.unit || unit;
- format = options.format || format;
- }
+ // byte[] my_version=ZLIB_VERSION;
- // Default options
- unit = unit || "mm";
- format = format || "a4";
- orientation = ("" + (orientation || "P")).toLowerCase();
- var format_as_string = ("" + format).toLowerCase();
+ //
+ // if (!version || version[0] !== my_version[0]
+ // || stream_size !== sizeof(z_stream)) {
+ // return Z_VERSION_ERROR;
+ // }
- // Size in pt of various paper formats
- var pageFormats = {
- a0: [2383.94, 3370.39],
- a1: [1683.78, 2383.94],
- a2: [1190.55, 1683.78],
- a3: [841.89, 1190.55],
- a4: [595.28, 841.89],
- a5: [419.53, 595.28],
- a6: [297.64, 419.53],
- a7: [209.76, 297.64],
- a8: [147.4, 209.76],
- a9: [104.88, 147.4],
- a10: [73.7, 104.88],
- b0: [2834.65, 4008.19],
- b1: [2004.09, 2834.65],
- b2: [1417.32, 2004.09],
- b3: [1000.63, 1417.32],
- b4: [708.66, 1000.63],
- b5: [498.9, 708.66],
- b6: [354.33, 498.9],
- b7: [249.45, 354.33],
- b8: [175.75, 249.45],
- b9: [124.72, 175.75],
- b10: [87.87, 124.72],
- c0: [2599.37, 3676.54],
- c1: [1836.85, 2599.37],
- c2: [1298.27, 1836.85],
- c3: [918.43, 1298.27],
- c4: [649.13, 918.43],
- c5: [459.21, 649.13],
- c6: [323.15, 459.21],
- c7: [229.61, 323.15],
- c8: [161.57, 229.61],
- c9: [113.39, 161.57],
- c10: [79.37, 113.39],
- dl: [311.81, 623.62],
- letter: [612, 792],
- "government-letter": [576, 756],
- legal: [612, 1008],
- "junior-legal": [576, 360],
- ledger: [1224, 792],
- tabloid: [792, 1224],
- "credit-card": [153, 243]
- };
+ strm.msg = null;
- var k;
- // Unit conversion
- switch (unit) {
- case "pt":
- k = 1;
- break;
- case "mm":
- k = 72 / 25.4;
- break;
- case "cm":
- k = 72 / 2.54;
- break;
- case "in":
- k = 72;
- break;
- case "px":
- k = 72 / 96;
- break;
- case "pc":
- k = 12;
- break;
- case "em":
- k = 12;
- break;
- case "ex":
- k = 6;
- break;
- default:
- throw "Invalid unit: " + unit;
- }
- var pageHeight = 0;
- var pageWidth = 0;
+ if (_level === Z_DEFAULT_COMPRESSION) _level = 6;
- // Dimensions are stored as user units and converted to points on output
- if (pageFormats.hasOwnProperty(format_as_string)) {
- pageHeight = pageFormats[format_as_string][1] / k;
- pageWidth = pageFormats[format_as_string][0] / k;
- } else {
- try {
- pageHeight = format[1];
- pageWidth = format[0];
- } catch (err) {
- throw new Error("Invalid format: " + format);
- }
+ if (
+ memLevel < 1 ||
+ memLevel > MAX_MEM_LEVEL ||
+ _method !== Z_DEFLATED ||
+ bits < 9 ||
+ bits > 15 ||
+ _level < 0 ||
+ _level > 9 ||
+ _strategy < 0 ||
+ _strategy > Z_HUFFMAN_ONLY
+ ) {
+ return Z_STREAM_ERROR;
}
- var tmp;
- // Handle page orientation
- if (orientation === "p" || orientation === "portrait") {
- orientation = "p";
- if (pageWidth > pageHeight) {
- tmp = pageWidth;
- pageWidth = pageHeight;
- pageHeight = tmp;
- }
- } else if (orientation === "l" || orientation === "landscape") {
- orientation = "l";
- if (pageHeight > pageWidth) {
- tmp = pageWidth;
- pageWidth = pageHeight;
- pageHeight = tmp;
- }
- } else {
- throw "Invalid orientation: " + orientation;
- }
+ strm.dstate = that;
- // Return information (k is the unit conversion ratio from pts)
- var info = {
- width: pageWidth,
- height: pageHeight,
- unit: unit,
- k: k,
- orientation: orientation
- };
- return info;
- };
+ w_bits = bits;
+ w_size = 1 << w_bits;
+ w_mask = w_size - 1;
- /**
- * Generate a PDF from an HTML element or string using.
- *
- * @name html
- * @function
- * @param {HTMLElement|string} source The source HTMLElement or a string containing HTML.
- * @param {Object} [options] Collection of settings
- * @param {function} [options.callback] The mandatory callback-function gets as first parameter the current jsPDF instance
- * @param {number|array} [options.margin] Array of margins [left, bottom, right, top]
- * @param {string} [options.filename] name of the file
- * @param {HTMLOptionImage} [options.image] image settings when converting HTML to image
- * @param {Html2CanvasOptions} [options.html2canvas] html2canvas options
- * @param {jsPDF} [options.jsPDF] jsPDF instance
- * @param {number} [options.x] x position on the PDF document
- * @param {number} [options.y] y position on the PDF document
- *
- * @example
- * var doc = new jsPDF();
- *
- * doc.html(document.body, {
- * callback: function (doc) {
- * doc.save();
- * },
- * x: 10,
- * y: 10
- * });
- */
- jsPDFAPI.html = function(src, options) {
+ hash_bits = memLevel + 7;
+ hash_size = 1 << hash_bits;
+ hash_mask = hash_size - 1;
+ hash_shift = Math.floor((hash_bits + MIN_MATCH - 1) / MIN_MATCH);
- options = options || {};
- options.callback = options.callback || function() {};
- options.html2canvas = options.html2canvas || {};
- options.html2canvas.canvas = options.html2canvas.canvas || this.canvas;
- options.jsPDF = options.jsPDF || this;
- // Create a new worker with the given options.
- var worker = new Worker(options);
+ window = new Uint8Array(w_size * 2);
+ prev = [];
+ head = [];
+
+ lit_bufsize = 1 << (memLevel + 6); // 16K elements by default
+
+ // We overlay pending_buf and d_buf+l_buf. This works since the average
+ // output size for (length,distance) codes is <= 24 bits.
+ that.pending_buf = new Uint8Array(lit_bufsize * 4);
+ pending_buf_size = lit_bufsize * 4;
- if (!options.worker) {
- // If worker is not set to true, perform the traditional 'simple' operation.
- return worker.from(src).doCallback();
- } else {
- // Otherwise, return the worker for new Promise-based operation.
- return worker;
- }
- };
-})(jsPDF.API);
+ d_buf = Math.floor(lit_bufsize / 2);
+ l_buf = (1 + 2) * lit_bufsize;
-/**
- * @license
- * ====================================================================
- * Copyright (c) 2013 Youssef Beddad, youssef.beddad@gmail.com
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
- * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
- * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
- * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
- * ====================================================================
- */
+ level = _level;
-/**
- * jsPDF JavaScript plugin
- *
- * @name javascript
- * @module
- */
-(function(jsPDFAPI) {
- var jsNamesObj, jsJsObj, text;
- /**
- * @name addJS
- * @function
- * @param {string} javascript The javascript to be embedded into the PDF-file.
- * @returns {jsPDF}
- */
- jsPDFAPI.addJS = function(javascript) {
- text = javascript;
- this.internal.events.subscribe("postPutResources", function() {
- jsNamesObj = this.internal.newObject();
- this.internal.out("<<");
- this.internal.out("/Names [(EmbeddedJS) " + (jsNamesObj + 1) + " 0 R]");
- this.internal.out(">>");
- this.internal.out("endobj");
+ strategy = _strategy;
- jsJsObj = this.internal.newObject();
- this.internal.out("<<");
- this.internal.out("/S /JavaScript");
- this.internal.out("/JS (" + text + ")");
- this.internal.out(">>");
- this.internal.out("endobj");
- });
- this.internal.events.subscribe("putCatalog", function() {
- if (jsNamesObj !== undefined && jsJsObj !== undefined) {
- this.internal.out("/Names <>");
- }
- });
- return this;
+ return deflateReset(strm);
};
-})(jsPDF.API);
-
-/**
- * @license
- * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv
- *
- * Licensed under the MIT License.
- * http://opensource.org/licenses/mit-license
- */
-/**
- * jsPDF Outline PlugIn
- *
- * Generates a PDF Outline
- * @name outline
- * @module
- */
-(function(jsPDFAPI) {
+ that.deflateEnd = function() {
+ if (
+ status !== INIT_STATE &&
+ status !== BUSY_STATE &&
+ status !== FINISH_STATE
+ ) {
+ return Z_STREAM_ERROR;
+ }
+ // Deallocate in reverse order of allocations:
+ that.pending_buf = null;
+ head = null;
+ prev = null;
+ window = null;
+ // free
+ that.dstate = null;
+ return status === BUSY_STATE ? Z_DATA_ERROR : Z_OK;
+ };
- var namesOid;
- //var destsGoto = [];
+ that.deflateParams = function(strm, _level, _strategy) {
+ var err = Z_OK;
- jsPDFAPI.events.push([
- "postPutResources",
- function() {
- var pdf = this;
- var rx = /^(\d+) 0 obj$/;
+ if (_level === Z_DEFAULT_COMPRESSION) {
+ _level = 6;
+ }
+ if (
+ _level < 0 ||
+ _level > 9 ||
+ _strategy < 0 ||
+ _strategy > Z_HUFFMAN_ONLY
+ ) {
+ return Z_STREAM_ERROR;
+ }
- // Write action goto objects for each page
- // this.outline.destsGoto = [];
- // for (var i = 0; i < totalPages; i++) {
- // var id = pdf.internal.newObject();
- // this.outline.destsGoto.push(id);
- // pdf.internal.write("<> endobj");
- // }
- //
- // for (var i = 0; i < dests.length; i++) {
- // pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0
- // R");
- // }
- //
- if (this.outline.root.children.length > 0) {
- var lines = pdf.outline.render().split(/\r\n/);
- for (var i = 0; i < lines.length; i++) {
- var line = lines[i];
- var m = rx.exec(line);
- if (m != null) {
- var oid = m[1];
- pdf.internal.newObjectDeferredBegin(oid, false);
- }
- pdf.internal.write(line);
- }
- }
+ if (
+ config_table[level].func !== config_table[_level].func &&
+ strm.total_in !== 0
+ ) {
+ // Flush the last buffer:
+ err = strm.deflate(Z_PARTIAL_FLUSH);
+ }
- // This code will write named destination for each page reference
- // (page_1, etc)
- if (this.outline.createNamedDestinations) {
- var totalPages = this.internal.pages.length;
- // WARNING: this assumes jsPDF starts on page 3 and pageIDs
- // follow 5, 7, 9, etc
- // Write destination objects for each page
- var dests = [];
- for (var i = 0; i < totalPages; i++) {
- var id = pdf.internal.newObject();
- dests.push(id);
- var info = pdf.internal.getPageInfo(i + 1);
- pdf.internal.write(
- "<< /D[" + info.objId + " 0 R /XYZ null null null]>> endobj"
- );
- }
+ if (level !== _level) {
+ level = _level;
+ max_lazy_match = config_table[level].max_lazy;
+ good_match = config_table[level].good_length;
+ nice_match = config_table[level].nice_length;
+ max_chain_length = config_table[level].max_chain;
+ }
+ strategy = _strategy;
+ return err;
+ };
- // assign a name for each destination
- var names2Oid = pdf.internal.newObject();
- pdf.internal.write("<< /Names [ ");
- for (var i = 0; i < dests.length; i++) {
- pdf.internal.write("(page_" + (i + 1) + ")" + dests[i] + " 0 R");
- }
- pdf.internal.write(" ] >>", "endobj");
+ that.deflateSetDictionary = function(strm, dictionary, dictLength) {
+ var length = dictLength;
+ var n,
+ index = 0;
- // var kids = pdf.internal.newObject();
- // pdf.internal.write('<< /Kids [ ' + names2Oid + ' 0 R');
- // pdf.internal.write(' ] >>', 'endobj');
+ if (!dictionary || status !== INIT_STATE) return Z_STREAM_ERROR;
- namesOid = pdf.internal.newObject();
- pdf.internal.write("<< /Dests " + names2Oid + " 0 R");
- pdf.internal.write(">>", "endobj");
- }
+ if (length < MIN_MATCH) return Z_OK;
+ if (length > w_size - MIN_LOOKAHEAD) {
+ length = w_size - MIN_LOOKAHEAD;
+ index = dictLength - length; // use the tail of the dictionary
}
- ]);
+ window.set(dictionary.subarray(index, index + length), 0);
- jsPDFAPI.events.push([
- "putCatalog",
- function() {
- var pdf = this;
- if (pdf.outline.root.children.length > 0) {
- pdf.internal.write(
- "/Outlines",
- this.outline.makeRef(this.outline.root)
- );
- if (this.outline.createNamedDestinations) {
- pdf.internal.write("/Names " + namesOid + " 0 R");
- }
- // Open with Bookmarks showing
- // pdf.internal.write("/PageMode /UseOutlines");
- }
- }
- ]);
+ strstart = length;
+ block_start = length;
- jsPDFAPI.events.push([
- "initialized",
- function() {
- var pdf = this;
+ // Insert all strings in the hash table (except for the last two bytes).
+ // s->lookahead stays null, so s->ins_h will be recomputed at the next
+ // call of fill_window.
- pdf.outline = {
- createNamedDestinations: false,
- root: {
- children: []
- }
- };
+ ins_h = window[0] & 0xff;
+ ins_h = ((ins_h << hash_shift) ^ (window[1] & 0xff)) & hash_mask;
+
+ for (n = 0; n <= length - MIN_MATCH; n++) {
+ ins_h =
+ ((ins_h << hash_shift) ^ (window[n + (MIN_MATCH - 1)] & 0xff)) &
+ hash_mask;
+ prev[n & w_mask] = head[ins_h];
+ head[ins_h] = n;
+ }
+ return Z_OK;
+ };
- /**
- * Options: pageNumber
- */
- pdf.outline.add = function(parent, title, options) {
- var item = {
- title: title,
- options: options,
- children: []
- };
- if (parent == null) {
- parent = this.root;
- }
- parent.children.push(item);
- return item;
- };
+ that.deflate = function(_strm, flush) {
+ var i, header, level_flags, old_flush, bstate;
- pdf.outline.render = function() {
- this.ctx = {};
- this.ctx.val = "";
- this.ctx.pdf = pdf;
+ if (flush > Z_FINISH || flush < 0) {
+ return Z_STREAM_ERROR;
+ }
- this.genIds_r(this.root);
- this.renderRoot(this.root);
- this.renderItems(this.root);
+ if (
+ !_strm.next_out ||
+ (!_strm.next_in && _strm.avail_in !== 0) ||
+ (status === FINISH_STATE && flush !== Z_FINISH)
+ ) {
+ _strm.msg = z_errmsg[Z_NEED_DICT - Z_STREAM_ERROR];
+ return Z_STREAM_ERROR;
+ }
+ if (_strm.avail_out === 0) {
+ _strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
+ return Z_BUF_ERROR;
+ }
- return this.ctx.val;
- };
+ strm = _strm; // just in case
+ old_flush = last_flush;
+ last_flush = flush;
- pdf.outline.genIds_r = function(node) {
- node.id = pdf.internal.newObjectDeferred();
- for (var i = 0; i < node.children.length; i++) {
- this.genIds_r(node.children[i]);
- }
- };
+ // Write the zlib header
+ if (status === INIT_STATE) {
+ header = (Z_DEFLATED + ((w_bits - 8) << 4)) << 8;
+ level_flags = ((level - 1) & 0xff) >> 1;
- pdf.outline.renderRoot = function(node) {
- this.objStart(node);
- this.line("/Type /Outlines");
- if (node.children.length > 0) {
- this.line("/First " + this.makeRef(node.children[0]));
- this.line(
- "/Last " + this.makeRef(node.children[node.children.length - 1])
- );
- }
- this.line(
- "/Count " +
- this.count_r(
- {
- count: 0
- },
- node
- )
- );
- this.objEnd();
- };
+ if (level_flags > 3) level_flags = 3;
+ header |= level_flags << 6;
+ if (strstart !== 0) header |= PRESET_DICT;
+ header += 31 - (header % 31);
- pdf.outline.renderItems = function(node) {
- var getVerticalCoordinateString = this.ctx.pdf.internal
- .getVerticalCoordinateString;
- for (var i = 0; i < node.children.length; i++) {
- var item = node.children[i];
- this.objStart(item);
+ status = BUSY_STATE;
+ putShortMSB(header);
+ }
- this.line("/Title " + this.makeString(item.title));
+ // Flush as much pending output as possible
+ if (that.pending !== 0) {
+ strm.flush_pending();
+ if (strm.avail_out === 0) {
+ // console.log(" avail_out==0");
+ // Since avail_out is 0, deflate will be called again with
+ // more output space, but possibly with both pending and
+ // avail_in equal to zero. There won't be anything to do,
+ // but this is not an error situation so make sure we
+ // return OK instead of BUF_ERROR at next call of deflate:
+ last_flush = -1;
+ return Z_OK;
+ }
- this.line("/Parent " + this.makeRef(node));
- if (i > 0) {
- this.line("/Prev " + this.makeRef(node.children[i - 1]));
- }
- if (i < node.children.length - 1) {
- this.line("/Next " + this.makeRef(node.children[i + 1]));
- }
- if (item.children.length > 0) {
- this.line("/First " + this.makeRef(item.children[0]));
- this.line(
- "/Last " + this.makeRef(item.children[item.children.length - 1])
- );
- }
+ // Make sure there is something to do and avoid duplicate
+ // consecutive
+ // flushes. For repeated and useless calls with Z_FINISH, we keep
+ // returning Z_STREAM_END instead of Z_BUFF_ERROR.
+ } else if (
+ strm.avail_in === 0 &&
+ flush <= old_flush &&
+ flush !== Z_FINISH
+ ) {
+ strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
+ return Z_BUF_ERROR;
+ }
- var count = (this.count = this.count_r(
- {
- count: 0
- },
- item
- ));
- if (count > 0) {
- this.line("/Count " + count);
- }
+ // User must not provide more input after the first FINISH:
+ if (status === FINISH_STATE && strm.avail_in !== 0) {
+ _strm.msg = z_errmsg[Z_NEED_DICT - Z_BUF_ERROR];
+ return Z_BUF_ERROR;
+ }
- if (item.options) {
- if (item.options.pageNumber) {
- // Explicit Destination
- //WARNING this assumes page ids are 3,5,7, etc.
- var info = pdf.internal.getPageInfo(item.options.pageNumber);
- this.line(
- "/Dest " +
- "[" +
- info.objId +
- " 0 R /XYZ 0 " +
- getVerticalCoordinateString(0) +
- " 0]"
- );
- // this line does not work on all clients (pageNumber instead of page ref)
- //this.line('/Dest ' + '[' + (item.options.pageNumber - 1) + ' /XYZ 0 ' + this.ctx.pdf.internal.pageSize.getHeight() + ' 0]');
+ // Start a new block or continue the current one.
+ if (
+ strm.avail_in !== 0 ||
+ lookahead !== 0 ||
+ (flush !== Z_NO_FLUSH && status !== FINISH_STATE)
+ ) {
+ bstate = -1;
+ switch (config_table[level].func) {
+ case STORED:
+ bstate = deflate_stored(flush);
+ break;
+ case FAST:
+ bstate = deflate_fast(flush);
+ break;
+ case SLOW:
+ bstate = deflate_slow(flush);
+ break;
+ }
- // Named Destination
- // this.line('/Dest (page_' + (item.options.pageNumber) + ')');
+ if (bstate === FinishStarted || bstate === FinishDone) {
+ status = FINISH_STATE;
+ }
+ if (bstate === NeedMore || bstate === FinishStarted) {
+ if (strm.avail_out === 0) {
+ last_flush = -1; // avoid BUF_ERROR next call, see above
+ }
+ return Z_OK;
+ // If flush !== Z_NO_FLUSH && avail_out === 0, the next call
+ // of deflate should use the same flush parameter to make sure
+ // that the flush is complete. So we don't have to output an
+ // empty block here, this will be done at next call. This also
+ // ensures that for a very small output buffer, we emit at most
+ // one empty block.
+ }
- // Action Destination
- // var id = pdf.internal.newObject();
- // pdf.internal.write('<> endobj');
- // this.line('/A ' + id + ' 0 R' );
- }
+ if (bstate === BlockDone) {
+ if (flush === Z_PARTIAL_FLUSH) {
+ _tr_align();
+ } else {
+ // FULL_FLUSH or SYNC_FLUSH
+ _tr_stored_block(0, 0, false);
+ // For a full flush, this empty block will be recognized
+ // as a special marker by inflate_sync().
+ if (flush === Z_FULL_FLUSH) {
+ // state.head[s.hash_size-1]=0;
+ for (i = 0; i < hash_size /*-1*/; i++)
+ // forget history
+ head[i] = 0;
}
- this.objEnd();
}
- for (var z = 0; z < node.children.length; z++) {
- this.renderItems(node.children[z]);
+ strm.flush_pending();
+ if (strm.avail_out === 0) {
+ last_flush = -1; // avoid BUF_ERROR at next call, see above
+ return Z_OK;
}
- };
+ }
+ }
- pdf.outline.line = function(text) {
- this.ctx.val += text + "\r\n";
- };
+ if (flush !== Z_FINISH) return Z_OK;
+ return Z_STREAM_END;
+ };
+}
- pdf.outline.makeRef = function(node) {
- return node.id + " 0 R";
- };
+// ZStream
+
+function ZStream() {
+ var that = this;
+ that.next_in_index = 0;
+ that.next_out_index = 0;
+ // that.next_in; // next input byte
+ that.avail_in = 0; // number of bytes available at next_in
+ that.total_in = 0; // total nb of input bytes read so far
+ // that.next_out; // next output byte should be put there
+ that.avail_out = 0; // remaining free space at next_out
+ that.total_out = 0; // total nb of bytes output so far
+ // that.msg;
+ // that.dstate;
+}
+
+ZStream.prototype = {
+ deflateInit: function(level, bits) {
+ var that = this;
+ that.dstate = new Deflate();
+ if (!bits) bits = MAX_BITS;
+ return that.dstate.deflateInit(that, level, bits);
+ },
+
+ deflate: function(flush) {
+ var that = this;
+ if (!that.dstate) {
+ return Z_STREAM_ERROR;
+ }
+ return that.dstate.deflate(that, flush);
+ },
- pdf.outline.makeString = function(val) {
- return "(" + pdf.internal.pdfEscape(val) + ")";
- };
+ deflateEnd: function() {
+ var that = this;
+ if (!that.dstate) return Z_STREAM_ERROR;
+ var ret = that.dstate.deflateEnd();
+ that.dstate = null;
+ return ret;
+ },
- pdf.outline.objStart = function(node) {
- this.ctx.val += "\r\n" + node.id + " 0 obj" + "\r\n<<\r\n";
- };
+ deflateParams: function(level, strategy) {
+ var that = this;
+ if (!that.dstate) return Z_STREAM_ERROR;
+ return that.dstate.deflateParams(that, level, strategy);
+ },
- pdf.outline.objEnd = function() {
- this.ctx.val += ">> \r\n" + "endobj" + "\r\n";
- };
+ deflateSetDictionary: function(dictionary, dictLength) {
+ var that = this;
+ if (!that.dstate) return Z_STREAM_ERROR;
+ return that.dstate.deflateSetDictionary(that, dictionary, dictLength);
+ },
- pdf.outline.count_r = function(ctx, node) {
- for (var i = 0; i < node.children.length; i++) {
- ctx.count++;
- this.count_r(ctx, node.children[i]);
- }
- return ctx.count;
- };
- }
- ]);
+ // Read a new buffer from the current input stream, update the
+ // total number of bytes read. All deflate() input goes through
+ // this function so some applications may wish to modify it to avoid
+ // allocating a large strm->next_in buffer and copying from it.
+ // (See also flush_pending()).
+ read_buf: function(buf, start, size) {
+ var that = this;
+ var len = that.avail_in;
+ if (len > size) len = size;
+ if (len === 0) return 0;
+ that.avail_in -= len;
+ buf.set(
+ that.next_in.subarray(that.next_in_index, that.next_in_index + len),
+ start
+ );
+ that.next_in_index += len;
+ that.total_in += len;
+ return len;
+ },
- return this;
-})(jsPDF.API);
+ // Flush as much pending output as possible. All deflate() output goes
+ // through this function so some applications may wish to modify it
+ // to avoid allocating a large strm->next_out buffer and copying into it.
+ // (See also read_buf()).
+ flush_pending: function() {
+ var that = this;
+ var len = that.dstate.pending;
-/**
- * @license
- *
- * Licensed under the MIT License.
- * http://opensource.org/licenses/mit-license
- */
+ if (len > that.avail_out) len = that.avail_out;
+ if (len === 0) return;
-/**
- * jsPDF jpeg Support PlugIn
- *
- * @name jpeg_support
- * @module
- */
-(function(jsPDFAPI) {
+ // if (that.dstate.pending_buf.length <= that.dstate.pending_out || that.next_out.length <= that.next_out_index
+ // || that.dstate.pending_buf.length < (that.dstate.pending_out + len) || that.next_out.length < (that.next_out_index +
+ // len)) {
+ // console.log(that.dstate.pending_buf.length + ", " + that.dstate.pending_out + ", " + that.next_out.length + ", " +
+ // that.next_out_index + ", " + len);
+ // console.log("avail_out=" + that.avail_out);
+ // }
- /**
- * 0xc0 (SOF) Huffman - Baseline DCT
- * 0xc1 (SOF) Huffman - Extended sequential DCT
- * 0xc2 Progressive DCT (SOF2)
- * 0xc3 Spatial (sequential) lossless (SOF3)
- * 0xc4 Differential sequential DCT (SOF5)
- * 0xc5 Differential progressive DCT (SOF6)
- * 0xc6 Differential spatial (SOF7)
- * 0xc7
- */
- var markers = [0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7];
+ that.next_out.set(
+ that.dstate.pending_buf.subarray(
+ that.dstate.pending_out,
+ that.dstate.pending_out + len
+ ),
+ that.next_out_index
+ );
- //takes a string imgData containing the raw bytes of
- //a jpeg image and returns [width, height]
- //Algorithm from: http://www.64lines.com/jpeg-width-height
- var getJpegInfo = function(imgData) {
- var width, height, numcomponents;
- var blockLength = imgData.charCodeAt(4) * 256 + imgData.charCodeAt(5);
- var len = imgData.length;
- var result = { width: 0, height: 0, numcomponents: 1 };
- for (var i = 4; i < len; i += 2) {
- i += blockLength;
- if (markers.indexOf(imgData.charCodeAt(i + 1)) !== -1) {
- height = imgData.charCodeAt(i + 5) * 256 + imgData.charCodeAt(i + 6);
- width = imgData.charCodeAt(i + 7) * 256 + imgData.charCodeAt(i + 8);
- numcomponents = imgData.charCodeAt(i + 9);
- result = { width: width, height: height, numcomponents: numcomponents };
- break;
- } else {
- blockLength =
- imgData.charCodeAt(i + 2) * 256 + imgData.charCodeAt(i + 3);
- }
+ that.next_out_index += len;
+ that.dstate.pending_out += len;
+ that.total_out += len;
+ that.avail_out -= len;
+ that.dstate.pending -= len;
+ if (that.dstate.pending === 0) {
+ that.dstate.pending_out = 0;
}
- return result;
- };
+ }
+};
- /**
- * @ignore
- */
- jsPDFAPI.processJPEG = function(
- data,
- index,
- alias,
- compression,
- dataAsBinaryString,
- colorSpace
- ) {
- var filter = this.decode.DCT_DECODE,
- bpc = 8,
- dims,
- result = null;
+// Deflater
- if (
- typeof data === "string" ||
- this.__addimage__.isArrayBuffer(data) ||
- this.__addimage__.isArrayBufferView(data)
- ) {
- // if we already have a stored binary string rep use that
- data = dataAsBinaryString || data;
- data = this.__addimage__.isArrayBuffer(data)
- ? new Uint8Array(data)
- : data;
- data = this.__addimage__.isArrayBufferView(data)
- ? this.__addimage__.arrayBufferToBinaryString(data)
- : data;
+function Deflater(options) {
+ var that = this;
+ var z = new ZStream();
+ var bufsize = 512;
+ var flush = Z_NO_FLUSH;
+ var buf = new Uint8Array(bufsize);
+ var level = options ? options.level : Z_DEFAULT_COMPRESSION;
+ if (typeof level === "undefined") level = Z_DEFAULT_COMPRESSION;
+ z.deflateInit(level);
+ z.next_out = buf;
- dims = getJpegInfo(data);
- switch (dims.numcomponents) {
- case 1:
- colorSpace = this.color_spaces.DEVICE_GRAY;
- break;
- case 4:
- colorSpace = this.color_spaces.DEVICE_CMYK;
- break;
- case 3:
- colorSpace = this.color_spaces.DEVICE_RGB;
- break;
+ that.append = function(data, onprogress) {
+ var err,
+ buffers = [],
+ lastIndex = 0,
+ bufferIndex = 0,
+ bufferSize = 0,
+ array;
+ if (!data.length) return;
+ z.next_in_index = 0;
+ z.next_in = data;
+ z.avail_in = data.length;
+ do {
+ z.next_out_index = 0;
+ z.avail_out = bufsize;
+ err = z.deflate(flush);
+ if (err !== Z_OK) throw new Error("deflating: " + z.msg);
+ if (z.next_out_index)
+ if (z.next_out_index === bufsize) buffers.push(new Uint8Array(buf));
+ else buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+ bufferSize += z.next_out_index;
+ if (onprogress && z.next_in_index > 0 && z.next_in_index !== lastIndex) {
+ onprogress(z.next_in_index);
+ lastIndex = z.next_in_index;
}
-
- result = {
- data: data,
- width: dims.width,
- height: dims.height,
- colorSpace: colorSpace,
- bitsPerComponent: bpc,
- filter: filter,
- index: index,
- alias: alias
- };
- }
- return result;
+ } while (z.avail_in > 0 || z.avail_out === 0);
+ array = new Uint8Array(bufferSize);
+ buffers.forEach(function(chunk) {
+ array.set(chunk, bufferIndex);
+ bufferIndex += chunk.length;
+ });
+ return array;
};
-})(jsPDF.API);
+ that.flush = function() {
+ var err,
+ buffers = [],
+ bufferIndex = 0,
+ bufferSize = 0,
+ array;
+ do {
+ z.next_out_index = 0;
+ z.avail_out = bufsize;
+ err = z.deflate(Z_FINISH);
+ if (err !== Z_STREAM_END && err !== Z_OK)
+ throw new Error("deflating: " + z.msg);
+ if (bufsize - z.avail_out > 0)
+ buffers.push(new Uint8Array(buf.subarray(0, z.next_out_index)));
+ bufferSize += z.next_out_index;
+ } while (z.avail_in > 0 || z.avail_out === 0);
+ z.deflateEnd();
+ array = new Uint8Array(bufferSize);
+ buffers.forEach(function(chunk) {
+ array.set(chunk, bufferIndex);
+ bufferIndex += chunk.length;
+ });
+ return array;
+ };
+}
/**
* @license
diff --git a/dist/jspdf.es.js.map b/dist/jspdf.es.js.map
index 9227a0760..3d88b9f31 100644
--- a/dist/jspdf.es.js.map
+++ b/dist/jspdf.es.js.map
@@ -1 +1 @@
-{"version":3,"file":"jspdf.es.js","sources":["../src/libs/globalObject.js","../src/libs/console.js","../src/libs/FileSaver.js","../src/libs/rgbcolor.js","../src/libs/AtobBtoa.js","../src/jspdf.js","../src/modules/acroform.js","../src/modules/addimage.js","../src/modules/annotations.js","../src/modules/arabic.js","../src/modules/autoprint.js","../src/modules/canvas.js","../src/modules/cell.js","../src/modules/context2d.js","../src/libs/Deflater.js","../src/modules/filters.js","../src/modules/fileloading.js","../src/modules/html.js","../src/modules/javascript.js","../src/modules/outline.js","../src/modules/jpeg_support.js","../src/libs/zlib.js","../src/libs/png.js","../src/modules/png_support.js","../src/libs/omggif.js","../src/libs/JPEGEncoder.js","../src/modules/gif_support.js","../src/libs/BMPDecoder.js","../src/modules/bmp_support.js","../src/libs/WebPDecoder.js","../src/modules/webp_support.js","../src/modules/setlanguage.js","../src/modules/split_text_to_size.js","../src/modules/standard_fonts_metrics.js","../src/modules/ttfsupport.js","../src/modules/svg.js","../src/modules/total_pages.js","../src/modules/viewerpreferences.js","../src/modules/xmp_metadata.js","../src/modules/utf8.js","../src/modules/vfs.js","../src/libs/bidiEngine.js","../src/libs/ttffont.js","../src/libs/adler32cs.js"],"sourcesContent":["export var globalObject = (function() {\n return \"undefined\" !== typeof window\n ? window\n : \"undefined\" !== typeof global\n ? global\n : \"undefined\" !== typeof self\n ? self\n : this;\n})();\n","import { globalObject } from \"./globalObject.js\";\n\nfunction consoleLog() {\n if (globalObject.console && typeof globalObject.console.log === \"function\") {\n globalObject.console.log.apply(globalObject.console, arguments);\n }\n}\n\nfunction consoleWarn(str) {\n if (globalObject.console) {\n if (typeof globalObject.console.warn === \"function\") {\n globalObject.console.warn.apply(globalObject.console, arguments);\n } else {\n consoleLog.call(null, arguments);\n }\n }\n}\n\nfunction consoleError(str) {\n if (globalObject.console) {\n if (typeof globalObject.console.error === \"function\") {\n globalObject.console.error.apply(globalObject.console, arguments);\n } else {\n consoleLog(str);\n }\n }\n}\nexport var console = {\n log: consoleLog,\n warn: consoleWarn,\n error: consoleError\n};\n","/**\n * @license\n * FileSaver.js\n * A saveAs() FileSaver implementation.\n *\n * By Eli Grey, http://eligrey.com\n *\n * License : https://github.com/eligrey/FileSaver.js/blob/master/LICENSE.md (MIT)\n * source : http://purl.eligrey.com/github/FileSaver.js\n */\n\nimport { globalObject as _global } from \"./globalObject.js\";\nimport { console } from \"./console.js\";\n\nfunction bom(blob, opts) {\n if (typeof opts === \"undefined\") opts = { autoBom: false };\n else if (typeof opts !== \"object\") {\n console.warn(\"Deprecated: Expected third argument to be a object\");\n opts = { autoBom: !opts };\n }\n\n // prepend BOM for UTF-8 XML and text/* types (including HTML)\n // note: your browser will automatically convert UTF-16 U+FEFF to EF BB BF\n if (\n opts.autoBom &&\n /^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(\n blob.type\n )\n ) {\n return new Blob([String.fromCharCode(0xfeff), blob], { type: blob.type });\n }\n return blob;\n}\n\nfunction download(url, name, opts) {\n var xhr = new XMLHttpRequest();\n xhr.open(\"GET\", url);\n xhr.responseType = \"blob\";\n xhr.onload = function() {\n saveAs(xhr.response, name, opts);\n };\n xhr.onerror = function() {\n console.error(\"could not download file\");\n };\n xhr.send();\n}\n\nfunction corsEnabled(url) {\n var xhr = new XMLHttpRequest();\n // use sync to avoid popup blocker\n xhr.open(\"HEAD\", url, false);\n try {\n xhr.send();\n } catch (e) {}\n return xhr.status >= 200 && xhr.status <= 299;\n}\n\n// `a.click()` doesn't work for all browsers (#465)\nfunction click(node) {\n try {\n node.dispatchEvent(new MouseEvent(\"click\"));\n } catch (e) {\n var evt = document.createEvent(\"MouseEvents\");\n evt.initMouseEvent(\n \"click\",\n true,\n true,\n window,\n 0,\n 0,\n 0,\n 80,\n 20,\n false,\n false,\n false,\n false,\n 0,\n null\n );\n node.dispatchEvent(evt);\n }\n}\n\nvar saveAs =\n _global.saveAs ||\n // probably in some web worker\n (typeof window !== \"object\" || window !== _global\n ? function saveAs() {\n /* noop */\n }\n : // Use download attribute first if possible (#193 Lumia mobile)\n \"download\" in HTMLAnchorElement.prototype\n ? function saveAs(blob, name, opts) {\n var URL = _global.URL || _global.webkitURL;\n var a = document.createElement(\"a\");\n name = name || blob.name || \"download\";\n\n a.download = name;\n a.rel = \"noopener\"; // tabnabbing\n\n // TODO: detect chrome extensions & packaged apps\n // a.target = '_blank'\n\n if (typeof blob === \"string\") {\n // Support regular links\n a.href = blob;\n if (a.origin !== location.origin) {\n corsEnabled(a.href)\n ? download(blob, name, opts)\n : click(a, (a.target = \"_blank\"));\n } else {\n click(a);\n }\n } else {\n // Support blobs\n a.href = URL.createObjectURL(blob);\n setTimeout(function() {\n URL.revokeObjectURL(a.href);\n }, 4e4); // 40s\n setTimeout(function() {\n click(a);\n }, 0);\n }\n }\n : // Use msSaveOrOpenBlob as a second approach\n \"msSaveOrOpenBlob\" in navigator\n ? function saveAs(blob, name, opts) {\n name = name || blob.name || \"download\";\n\n if (typeof blob === \"string\") {\n if (corsEnabled(blob)) {\n download(blob, name, opts);\n } else {\n var a = document.createElement(\"a\");\n a.href = blob;\n a.target = \"_blank\";\n setTimeout(function() {\n click(a);\n });\n }\n } else {\n navigator.msSaveOrOpenBlob(bom(blob, opts), name);\n }\n }\n : // Fallback to using FileReader and a popup\n function saveAs(blob, name, opts, popup) {\n // Open a popup immediately do go around popup blocker\n // Mostly only available on user interaction and the fileReader is async so...\n popup = popup || open(\"\", \"_blank\");\n if (popup) {\n popup.document.title = popup.document.body.innerText =\n \"downloading...\";\n }\n\n if (typeof blob === \"string\") return download(blob, name, opts);\n\n var force = blob.type === \"application/octet-stream\";\n var isSafari =\n /constructor/i.test(_global.HTMLElement) || _global.safari;\n var isChromeIOS = /CriOS\\/[\\d]+/.test(navigator.userAgent);\n\n if (\n (isChromeIOS || (force && isSafari)) &&\n typeof FileReader === \"object\"\n ) {\n // Safari doesn't allow downloading of blob URLs\n var reader = new FileReader();\n reader.onloadend = function() {\n var url = reader.result;\n url = isChromeIOS\n ? url\n : url.replace(/^data:[^;]*;/, \"data:attachment/file;\");\n if (popup) popup.location.href = url;\n else location = url;\n popup = null; // reverse-tabnabbing #460\n };\n reader.readAsDataURL(blob);\n } else {\n var URL = _global.URL || _global.webkitURL;\n var url = URL.createObjectURL(blob);\n if (popup) popup.location = url;\n else location.href = url;\n popup = null; // reverse-tabnabbing #460\n setTimeout(function() {\n URL.revokeObjectURL(url);\n }, 4e4); // 40s\n }\n });\n\nexport { saveAs };\n","/**\n * A class to parse color values\n * @author Stoyan Stefanov \n * {@link http://www.phpied.com/rgb-color-parser-in-javascript/}\n * @license Use it if you like it\n */\n\nfunction RGBColor(color_string) {\n color_string = color_string || \"\";\n this.ok = false;\n\n // strip any leading #\n if (color_string.charAt(0) == \"#\") {\n // remove # if any\n color_string = color_string.substr(1, 6);\n }\n\n color_string = color_string.replace(/ /g, \"\");\n color_string = color_string.toLowerCase();\n\n var channels;\n\n // before getting into regexps, try simple matches\n // and overwrite the input\n var simple_colors = {\n aliceblue: \"f0f8ff\",\n antiquewhite: \"faebd7\",\n aqua: \"00ffff\",\n aquamarine: \"7fffd4\",\n azure: \"f0ffff\",\n beige: \"f5f5dc\",\n bisque: \"ffe4c4\",\n black: \"000000\",\n blanchedalmond: \"ffebcd\",\n blue: \"0000ff\",\n blueviolet: \"8a2be2\",\n brown: \"a52a2a\",\n burlywood: \"deb887\",\n cadetblue: \"5f9ea0\",\n chartreuse: \"7fff00\",\n chocolate: \"d2691e\",\n coral: \"ff7f50\",\n cornflowerblue: \"6495ed\",\n cornsilk: \"fff8dc\",\n crimson: \"dc143c\",\n cyan: \"00ffff\",\n darkblue: \"00008b\",\n darkcyan: \"008b8b\",\n darkgoldenrod: \"b8860b\",\n darkgray: \"a9a9a9\",\n darkgreen: \"006400\",\n darkkhaki: \"bdb76b\",\n darkmagenta: \"8b008b\",\n darkolivegreen: \"556b2f\",\n darkorange: \"ff8c00\",\n darkorchid: \"9932cc\",\n darkred: \"8b0000\",\n darksalmon: \"e9967a\",\n darkseagreen: \"8fbc8f\",\n darkslateblue: \"483d8b\",\n darkslategray: \"2f4f4f\",\n darkturquoise: \"00ced1\",\n darkviolet: \"9400d3\",\n deeppink: \"ff1493\",\n deepskyblue: \"00bfff\",\n dimgray: \"696969\",\n dodgerblue: \"1e90ff\",\n feldspar: \"d19275\",\n firebrick: \"b22222\",\n floralwhite: \"fffaf0\",\n forestgreen: \"228b22\",\n fuchsia: \"ff00ff\",\n gainsboro: \"dcdcdc\",\n ghostwhite: \"f8f8ff\",\n gold: \"ffd700\",\n goldenrod: \"daa520\",\n gray: \"808080\",\n green: \"008000\",\n greenyellow: \"adff2f\",\n honeydew: \"f0fff0\",\n hotpink: \"ff69b4\",\n indianred: \"cd5c5c\",\n indigo: \"4b0082\",\n ivory: \"fffff0\",\n khaki: \"f0e68c\",\n lavender: \"e6e6fa\",\n lavenderblush: \"fff0f5\",\n lawngreen: \"7cfc00\",\n lemonchiffon: \"fffacd\",\n lightblue: \"add8e6\",\n lightcoral: \"f08080\",\n lightcyan: \"e0ffff\",\n lightgoldenrodyellow: \"fafad2\",\n lightgrey: \"d3d3d3\",\n lightgreen: \"90ee90\",\n lightpink: \"ffb6c1\",\n lightsalmon: \"ffa07a\",\n lightseagreen: \"20b2aa\",\n lightskyblue: \"87cefa\",\n lightslateblue: \"8470ff\",\n lightslategray: \"778899\",\n lightsteelblue: \"b0c4de\",\n lightyellow: \"ffffe0\",\n lime: \"00ff00\",\n limegreen: \"32cd32\",\n linen: \"faf0e6\",\n magenta: \"ff00ff\",\n maroon: \"800000\",\n mediumaquamarine: \"66cdaa\",\n mediumblue: \"0000cd\",\n mediumorchid: \"ba55d3\",\n mediumpurple: \"9370d8\",\n mediumseagreen: \"3cb371\",\n mediumslateblue: \"7b68ee\",\n mediumspringgreen: \"00fa9a\",\n mediumturquoise: \"48d1cc\",\n mediumvioletred: \"c71585\",\n midnightblue: \"191970\",\n mintcream: \"f5fffa\",\n mistyrose: \"ffe4e1\",\n moccasin: \"ffe4b5\",\n navajowhite: \"ffdead\",\n navy: \"000080\",\n oldlace: \"fdf5e6\",\n olive: \"808000\",\n olivedrab: \"6b8e23\",\n orange: \"ffa500\",\n orangered: \"ff4500\",\n orchid: \"da70d6\",\n palegoldenrod: \"eee8aa\",\n palegreen: \"98fb98\",\n paleturquoise: \"afeeee\",\n palevioletred: \"d87093\",\n papayawhip: \"ffefd5\",\n peachpuff: \"ffdab9\",\n peru: \"cd853f\",\n pink: \"ffc0cb\",\n plum: \"dda0dd\",\n powderblue: \"b0e0e6\",\n purple: \"800080\",\n red: \"ff0000\",\n rosybrown: \"bc8f8f\",\n royalblue: \"4169e1\",\n saddlebrown: \"8b4513\",\n salmon: \"fa8072\",\n sandybrown: \"f4a460\",\n seagreen: \"2e8b57\",\n seashell: \"fff5ee\",\n sienna: \"a0522d\",\n silver: \"c0c0c0\",\n skyblue: \"87ceeb\",\n slateblue: \"6a5acd\",\n slategray: \"708090\",\n snow: \"fffafa\",\n springgreen: \"00ff7f\",\n steelblue: \"4682b4\",\n tan: \"d2b48c\",\n teal: \"008080\",\n thistle: \"d8bfd8\",\n tomato: \"ff6347\",\n turquoise: \"40e0d0\",\n violet: \"ee82ee\",\n violetred: \"d02090\",\n wheat: \"f5deb3\",\n white: \"ffffff\",\n whitesmoke: \"f5f5f5\",\n yellow: \"ffff00\",\n yellowgreen: \"9acd32\"\n };\n color_string = simple_colors[color_string] || color_string;\n\n // array of color definition objects\n var color_defs = [\n {\n re: /^rgb\\((\\d{1,3}),\\s*(\\d{1,3}),\\s*(\\d{1,3})\\)$/,\n example: [\"rgb(123, 234, 45)\", \"rgb(255,234,245)\"],\n process: function(bits) {\n return [parseInt(bits[1]), parseInt(bits[2]), parseInt(bits[3])];\n }\n },\n {\n re: /^(\\w{2})(\\w{2})(\\w{2})$/,\n example: [\"#00ff00\", \"336699\"],\n process: function(bits) {\n return [\n parseInt(bits[1], 16),\n parseInt(bits[2], 16),\n parseInt(bits[3], 16)\n ];\n }\n },\n {\n re: /^(\\w{1})(\\w{1})(\\w{1})$/,\n example: [\"#fb0\", \"f0f\"],\n process: function(bits) {\n return [\n parseInt(bits[1] + bits[1], 16),\n parseInt(bits[2] + bits[2], 16),\n parseInt(bits[3] + bits[3], 16)\n ];\n }\n }\n ];\n\n // search through the definitions to find a match\n for (var i = 0; i < color_defs.length; i++) {\n var re = color_defs[i].re;\n var processor = color_defs[i].process;\n var bits = re.exec(color_string);\n if (bits) {\n channels = processor(bits);\n this.r = channels[0];\n this.g = channels[1];\n this.b = channels[2];\n this.ok = true;\n }\n }\n\n // validate/cleanup values\n this.r = this.r < 0 || isNaN(this.r) ? 0 : this.r > 255 ? 255 : this.r;\n this.g = this.g < 0 || isNaN(this.g) ? 0 : this.g > 255 ? 255 : this.g;\n this.b = this.b < 0 || isNaN(this.b) ? 0 : this.b > 255 ? 255 : this.b;\n\n // some getters\n this.toRGB = function() {\n return \"rgb(\" + this.r + \", \" + this.g + \", \" + this.b + \")\";\n };\n this.toHex = function() {\n var r = this.r.toString(16);\n var g = this.g.toString(16);\n var b = this.b.toString(16);\n if (r.length == 1) r = \"0\" + r;\n if (g.length == 1) g = \"0\" + g;\n if (b.length == 1) b = \"0\" + b;\n return \"#\" + r + g + b;\n };\n}\n\nexport { RGBColor };\n","import { globalObject } from \"./globalObject.js\";\n\nvar atob, btoa;\n\n(function() {\n atob = globalObject.atob;\n btoa = globalObject.btoa;\n return;\n\n})();\n\nexport { atob, btoa };\n","/* eslint-disable no-console */\n\nimport { saveAs } from \"./libs/FileSaver.js\";\nimport { globalObject } from \"./libs/globalObject.js\";\nimport { RGBColor } from \"./libs/rgbcolor.js\";\nimport { btoa } from \"./libs/AtobBtoa.js\";\nimport { console } from \"./libs/console.js\";\n\n/**\n * jsPDF's Internal PubSub Implementation.\n * Backward compatible rewritten on 2014 by\n * Diego Casorran, https://github.com/diegocr\n *\n * @class\n * @name PubSub\n * @ignore\n */\nfunction PubSub(context) {\n if (typeof context !== \"object\") {\n throw new Error(\n \"Invalid Context passed to initialize PubSub (jsPDF-module)\"\n );\n }\n var topics = {};\n\n this.subscribe = function(topic, callback, once) {\n once = once || false;\n if (\n typeof topic !== \"string\" ||\n typeof callback !== \"function\" ||\n typeof once !== \"boolean\"\n ) {\n throw new Error(\n \"Invalid arguments passed to PubSub.subscribe (jsPDF-module)\"\n );\n }\n\n if (!topics.hasOwnProperty(topic)) {\n topics[topic] = {};\n }\n\n var token = Math.random().toString(35);\n topics[topic][token] = [callback, !!once];\n\n return token;\n };\n\n this.unsubscribe = function(token) {\n for (var topic in topics) {\n if (topics[topic][token]) {\n delete topics[topic][token];\n if (Object.keys(topics[topic]).length === 0) {\n delete topics[topic];\n }\n return true;\n }\n }\n return false;\n };\n\n this.publish = function(topic) {\n if (topics.hasOwnProperty(topic)) {\n var args = Array.prototype.slice.call(arguments, 1),\n tokens = [];\n\n for (var token in topics[topic]) {\n var sub = topics[topic][token];\n try {\n sub[0].apply(context, args);\n } catch (ex) {\n if (globalObject.console) {\n console.error(\"jsPDF PubSub Error\", ex.message, ex);\n }\n }\n if (sub[1]) tokens.push(token);\n }\n if (tokens.length) tokens.forEach(this.unsubscribe);\n }\n };\n\n this.getTopics = function() {\n return topics;\n };\n}\n\nfunction GState(parameters) {\n if (!(this instanceof GState)) {\n return new GState(parameters);\n }\n\n /**\n * @name GState#opacity\n * @type {any}\n */\n /**\n * @name GState#stroke-opacity\n * @type {any}\n */\n var supported = \"opacity,stroke-opacity\".split(\",\");\n for (var p in parameters) {\n if (parameters.hasOwnProperty(p) && supported.indexOf(p) >= 0) {\n this[p] = parameters[p];\n }\n }\n /**\n * @name GState#id\n * @type {string}\n */\n this.id = \"\"; // set by addGState()\n /**\n * @name GState#objectNumber\n * @type {number}\n */\n this.objectNumber = -1; // will be set by putGState()\n}\n\nGState.prototype.equals = function equals(other) {\n var ignore = \"id,objectNumber,equals\";\n var p;\n if (!other || typeof other !== typeof this) return false;\n var count = 0;\n for (p in this) {\n if (ignore.indexOf(p) >= 0) continue;\n if (this.hasOwnProperty(p) && !other.hasOwnProperty(p)) return false;\n if (this[p] !== other[p]) return false;\n count++;\n }\n for (p in other) {\n if (other.hasOwnProperty(p) && ignore.indexOf(p) < 0) count--;\n }\n return count === 0;\n};\n\nfunction Pattern(gState, matrix) {\n this.gState = gState;\n this.matrix = matrix;\n\n this.id = \"\"; // set by addPattern()\n this.objectNumber = -1; // will be set by putPattern()\n}\n\nfunction ShadingPattern(type, coords, colors, gState, matrix) {\n if (!(this instanceof ShadingPattern)) {\n return new ShadingPattern(type, coords, colors, gState, matrix);\n }\n\n // see putPattern() for information how they are realized\n this.type = type === \"axial\" ? 2 : 3;\n this.coords = coords;\n this.colors = colors;\n\n Pattern.call(this, gState, matrix);\n}\n\nfunction TilingPattern(boundingBox, xStep, yStep, gState, matrix) {\n if (!(this instanceof TilingPattern)) {\n return new TilingPattern(boundingBox, xStep, yStep, gState, matrix);\n }\n\n this.boundingBox = boundingBox;\n this.xStep = xStep;\n this.yStep = yStep;\n\n this.stream = \"\"; // set by endTilingPattern();\n\n this.cloneIndex = 0;\n\n Pattern.call(this, gState, matrix);\n}\n\n/**\n * Creates new jsPDF document object instance.\n * @name jsPDF\n * @class\n * @param {Object} [options] - Collection of settings initializing the jsPDF-instance\n * @param {string} [options.orientation=portrait] - Orientation of the first page. Possible values are \"portrait\" or \"landscape\" (or shortcuts \"p\" or \"l\").
\n * @param {string} [options.unit=mm] Measurement unit (base unit) to be used when coordinates are specified.
\n * Possible values are \"pt\" (points), \"mm\", \"cm\", \"m\", \"in\" or \"px\".\n * @param {string/Array} [options.format=a4] The format of the first page. Can be:- a0 - a10
- b0 - b10
- c0 - c10
- dl
- letter
- government-letter
- legal
- junior-legal
- ledger
- tabloid
- credit-card
\n * Default is \"a4\". If you want to use your own format just pass instead of one of the above predefined formats the size as an number-array, e.g. [595.28, 841.89]\n * @param {boolean} [options.putOnlyUsedFonts=false] Only put fonts into the PDF, which were used.\n * @param {boolean} [options.compress=false] Compress the generated PDF.\n * @param {number} [options.precision=16] Precision of the element-positions.\n * @param {number} [options.userUnit=1.0] Not to be confused with the base unit. Please inform yourself before you use it.\n * @param {number|\"smart\"} [options.floatPrecision=16]\n * @returns {jsPDF} jsPDF-instance\n * @description\n * ```\n * {\n * orientation: 'p',\n * unit: 'mm',\n * format: 'a4',\n * putOnlyUsedFonts:true,\n * floatPrecision: 16 // or \"smart\", default is 16\n * }\n * ```\n *\n * @constructor\n */\nfunction jsPDF(options) {\n var orientation = typeof arguments[0] === \"string\" ? arguments[0] : \"p\";\n var unit = arguments[1];\n var format = arguments[2];\n var compressPdf = arguments[3];\n var filters = [];\n var userUnit = 1.0;\n var precision;\n var floatPrecision = 16;\n var defaultPathOperation = \"S\";\n\n options = options || {};\n\n if (typeof options === \"object\") {\n orientation = options.orientation;\n unit = options.unit || unit;\n format = options.format || format;\n compressPdf = options.compress || options.compressPdf || compressPdf;\n userUnit =\n typeof options.userUnit === \"number\" ? Math.abs(options.userUnit) : 1.0;\n if (typeof options.precision !== \"undefined\") {\n precision = options.precision;\n }\n if (typeof options.floatPrecision !== \"undefined\") {\n floatPrecision = options.floatPrecision;\n }\n defaultPathOperation = options.defaultPathOperation || \"S\";\n }\n\n filters =\n options.filters || (compressPdf === true ? [\"FlateEncode\"] : filters);\n\n unit = unit || \"mm\";\n orientation = (\"\" + (orientation || \"P\")).toLowerCase();\n var putOnlyUsedFonts = options.putOnlyUsedFonts || false;\n var usedFonts = {};\n\n var API = {\n internal: {},\n __private__: {}\n };\n\n API.__private__.PubSub = PubSub;\n\n var pdfVersion = \"1.3\";\n var getPdfVersion = (API.__private__.getPdfVersion = function() {\n return pdfVersion;\n });\n\n API.__private__.setPdfVersion = function(value) {\n pdfVersion = value;\n };\n\n // Size in pt of various paper formats\n var pageFormats = {\n a0: [2383.94, 3370.39],\n a1: [1683.78, 2383.94],\n a2: [1190.55, 1683.78],\n a3: [841.89, 1190.55],\n a4: [595.28, 841.89],\n a5: [419.53, 595.28],\n a6: [297.64, 419.53],\n a7: [209.76, 297.64],\n a8: [147.4, 209.76],\n a9: [104.88, 147.4],\n a10: [73.7, 104.88],\n b0: [2834.65, 4008.19],\n b1: [2004.09, 2834.65],\n b2: [1417.32, 2004.09],\n b3: [1000.63, 1417.32],\n b4: [708.66, 1000.63],\n b5: [498.9, 708.66],\n b6: [354.33, 498.9],\n b7: [249.45, 354.33],\n b8: [175.75, 249.45],\n b9: [124.72, 175.75],\n b10: [87.87, 124.72],\n c0: [2599.37, 3676.54],\n c1: [1836.85, 2599.37],\n c2: [1298.27, 1836.85],\n c3: [918.43, 1298.27],\n c4: [649.13, 918.43],\n c5: [459.21, 649.13],\n c6: [323.15, 459.21],\n c7: [229.61, 323.15],\n c8: [161.57, 229.61],\n c9: [113.39, 161.57],\n c10: [79.37, 113.39],\n dl: [311.81, 623.62],\n letter: [612, 792],\n \"government-letter\": [576, 756],\n legal: [612, 1008],\n \"junior-legal\": [576, 360],\n ledger: [1224, 792],\n tabloid: [792, 1224],\n \"credit-card\": [153, 243]\n };\n\n API.__private__.getPageFormats = function() {\n return pageFormats;\n };\n\n var getPageFormat = (API.__private__.getPageFormat = function(value) {\n return pageFormats[value];\n });\n\n format = format || \"a4\";\n\n var ApiMode = {\n COMPAT: \"compat\",\n ADVANCED: \"advanced\"\n };\n var apiMode = ApiMode.COMPAT;\n\n function advancedAPI() {\n // prepend global change of basis matrix\n // (Now, instead of converting every coordinate to the pdf coordinate system, we apply a matrix\n // that does this job for us (however, texts, images and similar objects must be drawn bottom up))\n this.saveGraphicsState();\n out(\n new Matrix(\n scaleFactor,\n 0,\n 0,\n -scaleFactor,\n 0,\n getPageHeight() * scaleFactor\n ).toString() + \" cm\"\n );\n this.setFontSize(this.getFontSize() / scaleFactor);\n\n // The default in MrRio's implementation is \"S\" (stroke), whereas the default in the yWorks implementation\n // was \"n\" (none). Although this has nothing to do with transforms, we should use the API switch here.\n defaultPathOperation = \"n\";\n\n apiMode = ApiMode.ADVANCED;\n }\n\n function compatAPI() {\n this.restoreGraphicsState();\n defaultPathOperation = \"S\";\n apiMode = ApiMode.COMPAT;\n }\n\n /**\n * @callback ApiSwitchBody\n * @param {jsPDF} pdf\n */\n\n /**\n * For compatibility reasons jsPDF offers two API modes which differ in the way they convert between the the usual\n * screen coordinates and the PDF coordinate system.\n * - \"compat\": Offers full compatibility across all plugins but does not allow arbitrary transforms\n * - \"advanced\": Allows arbitrary transforms and more advanced features like pattern fills. Some plugins might\n * not support this mode, though.\n * Initial mode is \"compat\".\n *\n * You can either provide a callback to the body argument, which means that jsPDF will automatically switch back to\n * the original API mode afterwards; or you can omit the callback and switch back manually using {@link compatAPI}.\n *\n * Note, that the calls to {@link saveGraphicsState} and {@link restoreGraphicsState} need to be balanced within the\n * callback or between calls of this method and its counterpart {@link compatAPI}. Calls to {@link beginFormObject}\n * or {@link beginTilingPattern} need to be closed by their counterparts before switching back to \"compat\" API mode.\n *\n * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.\n * The API mode will be switched back automatically afterwards.\n * @returns {jsPDF}\n * @memberof jsPDF#\n * @name advancedAPI\n */\n API.advancedAPI = function(body) {\n var doSwitch = apiMode === ApiMode.COMPAT;\n\n if (doSwitch) {\n advancedAPI.call(this);\n }\n\n if (typeof body !== \"function\") {\n return this;\n }\n\n body(this);\n\n if (doSwitch) {\n compatAPI.call(this);\n }\n\n return this;\n };\n\n /**\n * Switches to \"compat\" API mode. See {@link advancedAPI} for more details.\n *\n * @param {ApiSwitchBody=} body When provided, this callback will be called after the API mode has been switched.\n * The API mode will be switched back automatically afterwards.\n * @return {jsPDF}\n * @memberof jsPDF#\n * @name compatApi\n */\n API.compatAPI = function(body) {\n var doSwitch = apiMode === ApiMode.ADVANCED;\n\n if (doSwitch) {\n compatAPI.call(this);\n }\n\n if (typeof body !== \"function\") {\n return this;\n }\n\n body(this);\n\n if (doSwitch) {\n advancedAPI.call(this);\n }\n\n return this;\n };\n\n /**\n * @return {boolean} True iff the current API mode is \"advanced\". See {@link advancedAPI}.\n * @memberof jsPDF#\n * @name isAdvancedAPI\n */\n API.isAdvancedAPI = function() {\n return apiMode === ApiMode.ADVANCED;\n };\n\n var advancedApiModeTrap = function(methodName) {\n if (apiMode !== ApiMode.ADVANCED) {\n throw new Error(\n methodName +\n \" is only available in 'advanced' API mode. \" +\n \"You need to call advancedAPI() first.\"\n );\n }\n };\n\n var roundToPrecision = (API.roundToPrecision = API.__private__.roundToPrecision = function(\n number,\n parmPrecision\n ) {\n var tmpPrecision = precision || parmPrecision;\n if (isNaN(number) || isNaN(tmpPrecision)) {\n throw new Error(\"Invalid argument passed to jsPDF.roundToPrecision\");\n }\n return number.toFixed(tmpPrecision).replace(/0+$/, \"\");\n });\n\n // high precision float\n var hpf;\n if (typeof floatPrecision === \"number\") {\n hpf = API.hpf = API.__private__.hpf = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n }\n return roundToPrecision(number, floatPrecision);\n };\n } else if (floatPrecision === \"smart\") {\n hpf = API.hpf = API.__private__.hpf = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n }\n if (number > -1 && number < 1) {\n return roundToPrecision(number, 16);\n } else {\n return roundToPrecision(number, 5);\n }\n };\n } else {\n hpf = API.hpf = API.__private__.hpf = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.hpf\");\n }\n return roundToPrecision(number, 16);\n };\n }\n var f2 = (API.f2 = API.__private__.f2 = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.f2\");\n }\n return roundToPrecision(number, 2);\n });\n\n var f3 = (API.__private__.f3 = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.f3\");\n }\n return roundToPrecision(number, 3);\n });\n\n var scale = (API.scale = API.__private__.scale = function(number) {\n if (isNaN(number)) {\n throw new Error(\"Invalid argument passed to jsPDF.scale\");\n }\n if (apiMode === ApiMode.COMPAT) {\n return number * scaleFactor;\n } else if (apiMode === ApiMode.ADVANCED) {\n return number;\n }\n });\n\n var transformY = function(y) {\n if (apiMode === ApiMode.COMPAT) {\n return getPageHeight() - y;\n } else if (apiMode === ApiMode.ADVANCED) {\n return y;\n }\n };\n\n var transformScaleY = function(y) {\n return scale(transformY(y));\n };\n\n /**\n * @name setPrecision\n * @memberof jsPDF#\n * @function\n * @instance\n * @param {string} precision\n * @returns {jsPDF}\n */\n API.__private__.setPrecision = API.setPrecision = function(value) {\n if (typeof parseInt(value, 10) === \"number\") {\n precision = parseInt(value, 10);\n }\n };\n\n var fileId = \"00000000000000000000000000000000\";\n\n var getFileId = (API.__private__.getFileId = function() {\n return fileId;\n });\n\n var setFileId = (API.__private__.setFileId = function(value) {\n if (typeof value !== \"undefined\" && /^[a-fA-F0-9]{32}$/.test(value)) {\n fileId = value.toUpperCase();\n } else {\n fileId = fileId\n .split(\"\")\n .map(function() {\n return \"ABCDEF0123456789\".charAt(Math.floor(Math.random() * 16));\n })\n .join(\"\");\n }\n return fileId;\n });\n\n /**\n * @name setFileId\n * @memberof jsPDF#\n * @function\n * @instance\n * @param {string} value GUID.\n * @returns {jsPDF}\n */\n API.setFileId = function(value) {\n setFileId(value);\n return this;\n };\n\n /**\n * @name getFileId\n * @memberof jsPDF#\n * @function\n * @instance\n *\n * @returns {string} GUID.\n */\n API.getFileId = function() {\n return getFileId();\n };\n\n var creationDate;\n\n var convertDateToPDFDate = (API.__private__.convertDateToPDFDate = function(\n parmDate\n ) {\n var result = \"\";\n var tzoffset = parmDate.getTimezoneOffset(),\n tzsign = tzoffset < 0 ? \"+\" : \"-\",\n tzhour = Math.floor(Math.abs(tzoffset / 60)),\n tzmin = Math.abs(tzoffset % 60),\n timeZoneString = [tzsign, padd2(tzhour), \"'\", padd2(tzmin), \"'\"].join(\"\");\n\n result = [\n \"D:\",\n parmDate.getFullYear(),\n padd2(parmDate.getMonth() + 1),\n padd2(parmDate.getDate()),\n padd2(parmDate.getHours()),\n padd2(parmDate.getMinutes()),\n padd2(parmDate.getSeconds()),\n timeZoneString\n ].join(\"\");\n return result;\n });\n\n var convertPDFDateToDate = (API.__private__.convertPDFDateToDate = function(\n parmPDFDate\n ) {\n var year = parseInt(parmPDFDate.substr(2, 4), 10);\n var month = parseInt(parmPDFDate.substr(6, 2), 10) - 1;\n var date = parseInt(parmPDFDate.substr(8, 2), 10);\n var hour = parseInt(parmPDFDate.substr(10, 2), 10);\n var minutes = parseInt(parmPDFDate.substr(12, 2), 10);\n var seconds = parseInt(parmPDFDate.substr(14, 2), 10);\n // var timeZoneHour = parseInt(parmPDFDate.substr(16, 2), 10);\n // var timeZoneMinutes = parseInt(parmPDFDate.substr(20, 2), 10);\n\n var resultingDate = new Date(year, month, date, hour, minutes, seconds, 0);\n return resultingDate;\n });\n\n var setCreationDate = (API.__private__.setCreationDate = function(date) {\n var tmpCreationDateString;\n var regexPDFCreationDate = /^D:(20[0-2][0-9]|203[0-7]|19[7-9][0-9])(0[0-9]|1[0-2])([0-2][0-9]|3[0-1])(0[0-9]|1[0-9]|2[0-3])(0[0-9]|[1-5][0-9])(0[0-9]|[1-5][0-9])(\\+0[0-9]|\\+1[0-4]|-0[0-9]|-1[0-1])'(0[0-9]|[1-5][0-9])'?$/;\n if (typeof date === \"undefined\") {\n date = new Date();\n }\n\n if (date instanceof Date) {\n tmpCreationDateString = convertDateToPDFDate(date);\n } else if (regexPDFCreationDate.test(date)) {\n tmpCreationDateString = date;\n } else {\n throw new Error(\"Invalid argument passed to jsPDF.setCreationDate\");\n }\n creationDate = tmpCreationDateString;\n return creationDate;\n });\n\n var getCreationDate = (API.__private__.getCreationDate = function(type) {\n var result = creationDate;\n if (type === \"jsDate\") {\n result = convertPDFDateToDate(creationDate);\n }\n return result;\n });\n\n /**\n * @name setCreationDate\n * @memberof jsPDF#\n * @function\n * @instance\n * @param {Object} date\n * @returns {jsPDF}\n */\n API.setCreationDate = function(date) {\n setCreationDate(date);\n return this;\n };\n\n /**\n * @name getCreationDate\n * @memberof jsPDF#\n * @function\n * @instance\n * @param {Object} type\n * @returns {Object}\n */\n API.getCreationDate = function(type) {\n return getCreationDate(type);\n };\n\n var padd2 = (API.__private__.padd2 = function(number) {\n return (\"0\" + parseInt(number)).slice(-2);\n });\n\n var padd2Hex = (API.__private__.padd2Hex = function(hexString) {\n hexString = hexString.toString();\n return (\"00\" + hexString).substr(hexString.length);\n });\n\n var objectNumber = 0; // 'n' Current object number\n var offsets = []; // List of offsets. Activated and reset by buildDocument(). Pupulated by various calls buildDocument makes.\n var content = [];\n var contentLength = 0;\n var additionalObjects = [];\n\n var pages = [];\n var currentPage;\n var hasCustomDestination = false;\n var outputDestination = content;\n\n var resetDocument = function() {\n //reset fields relevant for objectNumber generation and xref.\n objectNumber = 0;\n contentLength = 0;\n content = [];\n offsets = [];\n additionalObjects = [];\n\n rootDictionaryObjId = newObjectDeferred();\n resourceDictionaryObjId = newObjectDeferred();\n };\n\n API.__private__.setCustomOutputDestination = function(destination) {\n hasCustomDestination = true;\n outputDestination = destination;\n };\n var setOutputDestination = function(destination) {\n if (!hasCustomDestination) {\n outputDestination = destination;\n }\n };\n\n API.__private__.resetCustomOutputDestination = function() {\n hasCustomDestination = false;\n outputDestination = content;\n };\n\n var out = (API.__private__.out = function(string) {\n string = string.toString();\n contentLength += string.length + 1;\n outputDestination.push(string);\n\n return outputDestination;\n });\n\n var write = (API.__private__.write = function(value) {\n return out(\n arguments.length === 1\n ? value.toString()\n : Array.prototype.join.call(arguments, \" \")\n );\n });\n\n var getArrayBuffer = (API.__private__.getArrayBuffer = function(data) {\n var len = data.length,\n ab = new ArrayBuffer(len),\n u8 = new Uint8Array(ab);\n\n while (len--) u8[len] = data.charCodeAt(len);\n return ab;\n });\n\n var standardFonts = [\n [\"Helvetica\", \"helvetica\", \"normal\", \"WinAnsiEncoding\"],\n [\"Helvetica-Bold\", \"helvetica\", \"bold\", \"WinAnsiEncoding\"],\n [\"Helvetica-Oblique\", \"helvetica\", \"italic\", \"WinAnsiEncoding\"],\n [\"Helvetica-BoldOblique\", \"helvetica\", \"bolditalic\", \"WinAnsiEncoding\"],\n [\"Courier\", \"courier\", \"normal\", \"WinAnsiEncoding\"],\n [\"Courier-Bold\", \"courier\", \"bold\", \"WinAnsiEncoding\"],\n [\"Courier-Oblique\", \"courier\", \"italic\", \"WinAnsiEncoding\"],\n [\"Courier-BoldOblique\", \"courier\", \"bolditalic\", \"WinAnsiEncoding\"],\n [\"Times-Roman\", \"times\", \"normal\", \"WinAnsiEncoding\"],\n [\"Times-Bold\", \"times\", \"bold\", \"WinAnsiEncoding\"],\n [\"Times-Italic\", \"times\", \"italic\", \"WinAnsiEncoding\"],\n [\"Times-BoldItalic\", \"times\", \"bolditalic\", \"WinAnsiEncoding\"],\n [\"ZapfDingbats\", \"zapfdingbats\", \"normal\", null],\n [\"Symbol\", \"symbol\", \"normal\", null]\n ];\n\n API.__private__.getStandardFonts = function() {\n return standardFonts;\n };\n\n var activeFontSize = options.fontSize || 16;\n\n /**\n * Sets font size for upcoming text elements.\n *\n * @param {number} size Font size in points.\n * @function\n * @instance\n * @returns {jsPDF}\n * @memberof jsPDF#\n * @name setFontSize\n */\n API.__private__.setFontSize = API.setFontSize = function(size) {\n if (apiMode === ApiMode.ADVANCED) {\n activeFontSize = size / scaleFactor;\n } else {\n activeFontSize = size;\n }\n return this;\n };\n\n /**\n * Gets the fontsize for upcoming text elements.\n *\n * @function\n * @instance\n * @returns {number}\n * @memberof jsPDF#\n * @name getFontSize\n */\n var getFontSize = (API.__private__.getFontSize = API.getFontSize = function() {\n if (apiMode === ApiMode.COMPAT) {\n return activeFontSize;\n } else {\n return activeFontSize * scaleFactor;\n }\n });\n\n var R2L = options.R2L || false;\n\n /**\n * Set value of R2L functionality.\n *\n * @param {boolean} value\n * @function\n * @instance\n * @returns {jsPDF} jsPDF-instance\n * @memberof jsPDF#\n * @name setR2L\n */\n API.__private__.setR2L = API.setR2L = function(value) {\n R2L = value;\n return this;\n };\n\n /**\n * Get value of R2L functionality.\n *\n * @function\n * @instance\n * @returns {boolean} jsPDF-instance\n * @memberof jsPDF#\n * @name getR2L\n */\n API.__private__.getR2L = API.getR2L = function() {\n return R2L;\n };\n\n var zoomMode; // default: 1;\n\n var setZoomMode = (API.__private__.setZoomMode = function(zoom) {\n var validZoomModes = [\n undefined,\n null,\n \"fullwidth\",\n \"fullheight\",\n \"fullpage\",\n \"original\"\n ];\n\n if (/^\\d*\\.?\\d*%$/.test(zoom)) {\n zoomMode = zoom;\n } else if (!isNaN(zoom)) {\n zoomMode = parseInt(zoom, 10);\n } else if (validZoomModes.indexOf(zoom) !== -1) {\n zoomMode = zoom;\n } else {\n throw new Error(\n 'zoom must be Integer (e.g. 2), a percentage Value (e.g. 300%) or fullwidth, fullheight, fullpage, original. \"' +\n zoom +\n '\" is not recognized.'\n );\n }\n });\n\n API.__private__.getZoomMode = function() {\n return zoomMode;\n };\n\n var pageMode; // default: 'UseOutlines';\n var setPageMode = (API.__private__.setPageMode = function(pmode) {\n var validPageModes = [\n undefined,\n null,\n \"UseNone\",\n \"UseOutlines\",\n \"UseThumbs\",\n \"FullScreen\"\n ];\n\n if (validPageModes.indexOf(pmode) == -1) {\n throw new Error(\n 'Page mode must be one of UseNone, UseOutlines, UseThumbs, or FullScreen. \"' +\n pmode +\n '\" is not recognized.'\n );\n }\n pageMode = pmode;\n });\n\n API.__private__.getPageMode = function() {\n return pageMode;\n };\n\n var layoutMode; // default: 'continuous';\n var setLayoutMode = (API.__private__.setLayoutMode = function(layout) {\n var validLayoutModes = [\n undefined,\n null,\n \"continuous\",\n \"single\",\n \"twoleft\",\n \"tworight\",\n \"two\"\n ];\n\n if (validLayoutModes.indexOf(layout) == -1) {\n throw new Error(\n 'Layout mode must be one of continuous, single, twoleft, tworight. \"' +\n layout +\n '\" is not recognized.'\n );\n }\n layoutMode = layout;\n });\n\n API.__private__.getLayoutMode = function() {\n return layoutMode;\n };\n\n /**\n * Set the display mode options of the page like zoom and layout.\n *\n * @name setDisplayMode\n * @memberof jsPDF#\n * @function\n * @instance\n * @param {integer|String} zoom You can pass an integer or percentage as\n * a string. 2 will scale the document up 2x, '200%' will scale up by the\n * same amount. You can also set it to 'fullwidth', 'fullheight',\n * 'fullpage', or 'original'.\n *\n * Only certain PDF readers support this, such as Adobe Acrobat.\n *\n * @param {string} layout Layout mode can be: 'continuous' - this is the\n * default continuous scroll. 'single' - the single page mode only shows one\n * page at a time. 'twoleft' - two column left mode, first page starts on\n * the left, and 'tworight' - pages are laid out in two columns, with the\n * first page on the right. This would be used for books.\n * @param {string} pmode 'UseOutlines' - it shows the\n * outline of the document on the left. 'UseThumbs' - shows thumbnails along\n * the left. 'FullScreen' - prompts the user to enter fullscreen mode.\n *\n * @returns {jsPDF}\n */\n API.__private__.setDisplayMode = API.setDisplayMode = function(\n zoom,\n layout,\n pmode\n ) {\n setZoomMode(zoom);\n setLayoutMode(layout);\n setPageMode(pmode);\n return this;\n };\n\n var documentProperties = {\n title: \"\",\n subject: \"\",\n author: \"\",\n keywords: \"\",\n creator: \"\"\n };\n\n API.__private__.getDocumentProperty = function(key) {\n if (Object.keys(documentProperties).indexOf(key) === -1) {\n throw new Error(\"Invalid argument passed to jsPDF.getDocumentProperty\");\n }\n return documentProperties[key];\n };\n\n API.__private__.getDocumentProperties = function() {\n return documentProperties;\n };\n\n /**\n * Adds a properties to the PDF document.\n *\n * @param {Object} A property_name-to-property_value object structure.\n * @function\n * @instance\n * @returns {jsPDF}\n * @memberof jsPDF#\n * @name setDocumentProperties\n */\n API.__private__.setDocumentProperties = API.setProperties = API.setDocumentProperties = function(\n properties\n ) {\n // copying only those properties we can render.\n for (var property in documentProperties) {\n if (documentProperties.hasOwnProperty(property) && properties[property]) {\n documentProperties[property] = properties[property];\n }\n }\n return this;\n };\n\n API.__private__.setDocumentProperty = function(key, value) {\n if (Object.keys(documentProperties).indexOf(key) === -1) {\n throw new Error(\"Invalid arguments passed to jsPDF.setDocumentProperty\");\n }\n return (documentProperties[key] = value);\n };\n\n var fonts = {}; // collection of font objects, where key is fontKey - a dynamically created label for a given font.\n var fontmap = {}; // mapping structure fontName > fontStyle > font key - performance layer. See addFont()\n var activeFontKey; // will be string representing the KEY of the font as combination of fontName + fontStyle\n var fontStateStack = []; //\n var patterns = {}; // collection of pattern objects\n var patternMap = {}; // see fonts\n var gStates = {}; // collection of graphic state objects\n var gStatesMap = {}; // see fonts\n var activeGState = null;\n var scaleFactor; // Scale factor\n var page = 0;\n var pagesContext = [];\n var events = new PubSub(API);\n var hotfixes = options.hotfixes || [];\n\n var renderTargets = {};\n var renderTargetMap = {};\n var renderTargetStack = [];\n var pageX;\n var pageY;\n var pageMatrix; // only used for FormObjects\n\n /**\n * A matrix object for 2D homogenous transformations:
\n * | a b 0 |
\n * | c d 0 |
\n * | e f 1 |
\n * pdf multiplies matrices righthand: v' = v x m1 x m2 x ...\n *\n * @class\n * @name Matrix\n * @param {number} sx\n * @param {number} shy\n * @param {number} shx\n * @param {number} sy\n * @param {number} tx\n * @param {number} ty\n * @constructor\n */\n var Matrix = function(sx, shy, shx, sy, tx, ty) {\n if (!(this instanceof Matrix)) {\n return new Matrix(sx, shy, shx, sy, tx, ty);\n }\n\n if (isNaN(sx)) sx = 1;\n if (isNaN(shy)) shy = 0;\n if (isNaN(shx)) shx = 0;\n if (isNaN(sy)) sy = 1;\n if (isNaN(tx)) tx = 0;\n if (isNaN(ty)) ty = 0;\n\n this._matrix = [sx, shy, shx, sy, tx, ty];\n };\n\n /**\n * @name sx\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"sx\", {\n get: function() {\n return this._matrix[0];\n },\n set: function(value) {\n this._matrix[0] = value;\n }\n });\n\n /**\n * @name shy\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"shy\", {\n get: function() {\n return this._matrix[1];\n },\n set: function(value) {\n this._matrix[1] = value;\n }\n });\n\n /**\n * @name shx\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"shx\", {\n get: function() {\n return this._matrix[2];\n },\n set: function(value) {\n this._matrix[2] = value;\n }\n });\n\n /**\n * @name sy\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"sy\", {\n get: function() {\n return this._matrix[3];\n },\n set: function(value) {\n this._matrix[3] = value;\n }\n });\n\n /**\n * @name tx\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"tx\", {\n get: function() {\n return this._matrix[4];\n },\n set: function(value) {\n this._matrix[4] = value;\n }\n });\n\n /**\n * @name ty\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"ty\", {\n get: function() {\n return this._matrix[5];\n },\n set: function(value) {\n this._matrix[5] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"a\", {\n get: function() {\n return this._matrix[0];\n },\n set: function(value) {\n this._matrix[0] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"b\", {\n get: function() {\n return this._matrix[1];\n },\n set: function(value) {\n this._matrix[1] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"c\", {\n get: function() {\n return this._matrix[2];\n },\n set: function(value) {\n this._matrix[2] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"d\", {\n get: function() {\n return this._matrix[3];\n },\n set: function(value) {\n this._matrix[3] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"e\", {\n get: function() {\n return this._matrix[4];\n },\n set: function(value) {\n this._matrix[4] = value;\n }\n });\n\n Object.defineProperty(Matrix.prototype, \"f\", {\n get: function() {\n return this._matrix[5];\n },\n set: function(value) {\n this._matrix[5] = value;\n }\n });\n\n /**\n * @name rotation\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"rotation\", {\n get: function() {\n return Math.atan2(this.shx, this.sx);\n }\n });\n\n /**\n * @name scaleX\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"scaleX\", {\n get: function() {\n return this.decompose().scale.sx;\n }\n });\n\n /**\n * @name scaleY\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"scaleY\", {\n get: function() {\n return this.decompose().scale.sy;\n }\n });\n\n /**\n * @name isIdentity\n * @memberof Matrix#\n */\n Object.defineProperty(Matrix.prototype, \"isIdentity\", {\n get: function() {\n if (this.sx !== 1) {\n return false;\n }\n if (this.shy !== 0) {\n return false;\n }\n if (this.shx !== 0) {\n return false;\n }\n if (this.sy !== 1) {\n return false;\n }\n if (this.tx !== 0) {\n return false;\n }\n if (this.ty !== 0) {\n return false;\n }\n return true;\n }\n });\n\n /**\n * Join the Matrix Values to a String\n *\n * @function join\n * @param {string} separator Specifies a string to separate each pair of adjacent elements of the array. The separator is converted to a string if necessary. If omitted, the array elements are separated with a comma (\",\"). If separator is an empty string, all elements are joined without any characters in between them.\n * @returns {string} A string with all array elements joined.\n * @memberof Matrix#\n */\n Matrix.prototype.join = function(separator) {\n return [this.sx, this.shy, this.shx, this.sy, this.tx, this.ty]\n .map(hpf)\n .join(separator);\n };\n\n /**\n * Multiply the matrix with given Matrix\n *\n * @function multiply\n * @param matrix\n * @returns {Matrix}\n * @memberof Matrix#\n */\n Matrix.prototype.multiply = function(matrix) {\n var sx = matrix.sx * this.sx + matrix.shy * this.shx;\n var shy = matrix.sx * this.shy + matrix.shy * this.sy;\n var shx = matrix.shx * this.sx + matrix.sy * this.shx;\n var sy = matrix.shx * this.shy + matrix.sy * this.sy;\n var tx = matrix.tx * this.sx + matrix.ty * this.shx + this.tx;\n var ty = matrix.tx * this.shy + matrix.ty * this.sy + this.ty;\n\n return new Matrix(sx, shy, shx, sy, tx, ty);\n };\n\n /**\n * @function decompose\n * @memberof Matrix#\n */\n Matrix.prototype.decompose = function() {\n var a = this.sx;\n var b = this.shy;\n var c = this.shx;\n var d = this.sy;\n var e = this.tx;\n var f = this.ty;\n\n var scaleX = Math.sqrt(a * a + b * b);\n a /= scaleX;\n b /= scaleX;\n\n var shear = a * c + b * d;\n c -= a * shear;\n d -= b * shear;\n\n var scaleY = Math.sqrt(c * c + d * d);\n c /= scaleY;\n d /= scaleY;\n shear /= scaleY;\n\n if (a * d < b * c) {\n a = -a;\n b = -b;\n shear = -shear;\n scaleX = -scaleX;\n }\n\n return {\n scale: new Matrix(scaleX, 0, 0, scaleY, 0, 0),\n translate: new Matrix(1, 0, 0, 1, e, f),\n rotate: new Matrix(a, b, -b, a, 0, 0),\n skew: new Matrix(1, 0, shear, 1, 0, 0)\n };\n };\n\n /**\n * @function toString\n * @memberof Matrix#\n */\n Matrix.prototype.toString = function(parmPrecision) {\n return this.join(\" \");\n };\n\n /**\n * @function inversed\n * @memberof Matrix#\n */\n Matrix.prototype.inversed = function() {\n var a = this.sx,\n b = this.shy,\n c = this.shx,\n d = this.sy,\n e = this.tx,\n f = this.ty;\n\n var quot = 1 / (a * d - b * c);\n\n var aInv = d * quot;\n var bInv = -b * quot;\n var cInv = -c * quot;\n var dInv = a * quot;\n var eInv = -aInv * e - cInv * f;\n var fInv = -bInv * e - dInv * f;\n\n return new Matrix(aInv, bInv, cInv, dInv, eInv, fInv);\n };\n\n /**\n * @function applyToPoint\n * @memberof Matrix#\n */\n Matrix.prototype.applyToPoint = function(pt) {\n var x = pt.x * this.sx + pt.y * this.shx + this.tx;\n var y = pt.x * this.shy + pt.y * this.sy + this.ty;\n return new Point(x, y);\n };\n\n /**\n * @function applyToRectangle\n * @memberof Matrix#\n */\n Matrix.prototype.applyToRectangle = function(rect) {\n var pt1 = this.applyToPoint(rect);\n var pt2 = this.applyToPoint(new Point(rect.x + rect.w, rect.y + rect.h));\n return new Rectangle(pt1.x, pt1.y, pt2.x - pt1.x, pt2.y - pt1.y);\n };\n\n /**\n * Clone the Matrix\n *\n * @function clone\n * @memberof Matrix#\n * @name clone\n * @instance\n */\n Matrix.prototype.clone = function() {\n var sx = this.sx;\n var shy = this.shy;\n var shx = this.shx;\n var sy = this.sy;\n var tx = this.tx;\n var ty = this.ty;\n\n return new Matrix(sx, shy, shx, sy, tx, ty);\n };\n\n API.Matrix = Matrix;\n\n /**\n * Multiplies two matrices. (see {@link Matrix})\n * @param {Matrix} m1\n * @param {Matrix} m2\n * @memberof jsPDF#\n * @name matrixMult\n */\n var matrixMult = (API.matrixMult = function(m1, m2) {\n return m2.multiply(m1);\n });\n\n /**\n * The identity matrix (equivalent to new Matrix(1, 0, 0, 1, 0, 0)).\n * @type {Matrix}\n * @memberof! jsPDF#\n * @name identityMatrix\n */\n var identityMatrix = new Matrix(1, 0, 0, 1, 0, 0);\n API.unitMatrix = API.identityMatrix = identityMatrix;\n\n /**\n * Adds a new pattern for later use.\n * @param {String} key The key by it can be referenced later. The keys must be unique!\n * @param {API.Pattern} pattern The pattern\n */\n var addPattern = function(key, pattern) {\n // only add it if it is not already present (the keys provided by the user must be unique!)\n if (patternMap[key]) return;\n\n var prefix = pattern instanceof ShadingPattern ? \"Sh\" : \"P\";\n var patternKey = prefix + (Object.keys(patterns).length + 1).toString(10);\n pattern.id = patternKey;\n\n patternMap[key] = patternKey;\n patterns[patternKey] = pattern;\n\n events.publish(\"addPattern\", pattern);\n };\n\n /**\n * A pattern describing a shading pattern.\n *\n * Only available in \"advanced\" API mode.\n *\n * @param {String} type One of \"axial\" or \"radial\"\n * @param {Array} coords Either [x1, y1, x2, y2] for \"axial\" type describing the two interpolation points\n * or [x1, y1, r, x2, y2, r2] for \"radial\" describing inner and the outer circle.\n * @param {Array
\n * @name annotations\n * @module\n */\n\n/*\n Destination Magnification Factors\n See PDF 1.3 Page 386 for meanings and options\n\n [supported]\n\tXYZ (options; left top zoom)\n\tFit (no options)\n\tFitH (options: top)\n\tFitV (options: left)\n\n\t[not supported]\n\tFitR\n\tFitB\n\tFitBH\n\tFitBV\n */\n\nimport { jsPDF } from \"../jspdf.js\";\n\n(function(jsPDFAPI) {\n \"use strict\";\n\n var notEmpty = function(obj) {\n if (typeof obj != \"undefined\") {\n if (obj != \"\") {\n return true;\n }\n }\n };\n\n jsPDF.API.events.push([\n \"addPage\",\n function(addPageData) {\n var pageInfo = this.internal.getPageInfo(addPageData.pageNumber);\n pageInfo.pageContext.annotations = [];\n }\n ]);\n\n jsPDFAPI.events.push([\n \"putPage\",\n function(putPageData) {\n var getHorizontalCoordinateString = this.internal.getCoordinateString;\n var getVerticalCoordinateString = this.internal\n .getVerticalCoordinateString;\n var pageInfo = this.internal.getPageInfoByObjId(putPageData.objId);\n var pageAnnos = putPageData.pageContext.annotations;\n\n var anno, rect, line;\n var found = false;\n for (var a = 0; a < pageAnnos.length && !found; a++) {\n anno = pageAnnos[a];\n switch (anno.type) {\n case \"link\":\n if (\n notEmpty(anno.options.url) ||\n notEmpty(anno.options.pageNumber)\n ) {\n found = true;\n }\n break;\n case \"reference\":\n case \"text\":\n case \"freetext\":\n found = true;\n break;\n }\n }\n if (found == false) {\n return;\n }\n\n this.internal.write(\"/Annots [\");\n for (var i = 0; i < pageAnnos.length; i++) {\n anno = pageAnnos[i];\n\n switch (anno.type) {\n case \"reference\":\n // References to Widget Annotations (for AcroForm Fields)\n this.internal.write(\" \" + anno.object.objId + \" 0 R \");\n break;\n case \"text\":\n // Create a an object for both the text and the popup\n var objText = this.internal.newAdditionalObject();\n var objPopup = this.internal.newAdditionalObject();\n\n var title = anno.title || \"Note\";\n rect =\n \"/Rect [\" +\n getHorizontalCoordinateString(anno.bounds.x) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) +\n \" \" +\n getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y) +\n \"] \";\n line =\n \"<>\";\n objText.content = line;\n\n var parent = objText.objId + \" 0 R\";\n var popoff = 30;\n rect =\n \"/Rect [\" +\n getHorizontalCoordinateString(anno.bounds.x + popoff) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) +\n \" \" +\n getHorizontalCoordinateString(\n anno.bounds.x + anno.bounds.w + popoff\n ) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y) +\n \"] \";\n line =\n \"<>\";\n objPopup.content = line;\n\n this.internal.write(objText.objId, \"0 R\", objPopup.objId, \"0 R\");\n\n break;\n case \"freetext\":\n rect =\n \"/Rect [\" +\n getHorizontalCoordinateString(anno.bounds.x) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y) +\n \" \" +\n getHorizontalCoordinateString(anno.bounds.x + anno.bounds.w) +\n \" \" +\n getVerticalCoordinateString(anno.bounds.y + anno.bounds.h) +\n \"] \";\n var color = anno.color || \"#000000\";\n line =\n \"<>\";\n this.internal.write(line);\n break;\n case \"link\":\n if (anno.options.name) {\n var loc = this.annotations._nameMap[anno.options.name];\n anno.options.pageNumber = loc.page;\n anno.options.top = loc.y;\n } else {\n if (!anno.options.top) {\n anno.options.top = 0;\n }\n }\n\n rect =\n \"/Rect [\" +\n getHorizontalCoordinateString(anno.x) +\n \" \" +\n getVerticalCoordinateString(anno.y) +\n \" \" +\n getHorizontalCoordinateString(anno.x + anno.w) +\n \" \" +\n getVerticalCoordinateString(anno.y + anno.h) +\n \"] \";\n\n line = \"\";\n if (anno.options.url) {\n line =\n \"<>\";\n } else if (anno.options.pageNumber) {\n // first page is 0\n var info = this.internal.getPageInfo(anno.options.pageNumber);\n line =\n \"<>\";\n this.internal.write(line);\n }\n break;\n }\n }\n this.internal.write(\"]\");\n }\n ]);\n\n /**\n * @name createAnnotation\n * @function\n * @param {Object} options\n */\n jsPDFAPI.createAnnotation = function(options) {\n var pageInfo = this.internal.getCurrentPageInfo();\n switch (options.type) {\n case \"link\":\n this.link(\n options.bounds.x,\n options.bounds.y,\n options.bounds.w,\n options.bounds.h,\n options\n );\n break;\n case \"text\":\n case \"freetext\":\n pageInfo.pageContext.annotations.push(options);\n break;\n }\n };\n\n /**\n * Create a link\n *\n * valid options\n * pageNumber or url [required]\n * If pageNumber is specified, top and zoom may also be specified
\n * @name link\n * @function\n * @param {number} x\n * @param {number} y\n * @param {number} w\n * @param {number} h\n * @param {Object} options\n */\n jsPDFAPI.link = function(x, y, w, h, options) {\n var pageInfo = this.internal.getCurrentPageInfo();\n pageInfo.pageContext.annotations.push({\n x: x,\n y: y,\n w: w,\n h: h,\n options: options,\n type: \"link\"\n });\n };\n\n /**\n * Currently only supports single line text.\n * Returns the width of the text/link\n *\n * @name textWithLink\n * @function\n * @param {string} text\n * @param {number} x\n * @param {number} y\n * @param {Object} options\n * @returns {number} width the width of the text/link\n */\n jsPDFAPI.textWithLink = function(text, x, y, options) {\n var width = this.getTextWidth(text);\n var height = this.internal.getLineHeight() / this.internal.scaleFactor;\n this.text(text, x, y, options);\n //TODO We really need the text baseline height to do this correctly.\n // Or ability to draw text on top, bottom, center, or baseline.\n y += height * 0.2;\n this.link(x, y - height, width, height, options);\n return width;\n };\n\n //TODO move into external library\n /**\n * @name getTextWidth\n * @function\n * @param {string} text\n * @returns {number} txtWidth\n */\n jsPDFAPI.getTextWidth = function(text) {\n var fontSize = this.internal.getFontSize();\n var txtWidth =\n (this.getStringUnitWidth(text) * fontSize) / this.internal.scaleFactor;\n return txtWidth;\n };\n\n return this;\n})(jsPDF.API);\n","/**\n * @license\n * Copyright (c) 2017 Aras Abbasi\n *\n * Licensed under the MIT License.\n * http://opensource.org/licenses/mit-license\n */\n\nimport { jsPDF } from \"../jspdf.js\";\n\n/**\n * jsPDF arabic parser PlugIn\n *\n * @name arabic\n * @module\n */\n(function(jsPDFAPI) {\n \"use strict\";\n\n /**\n * Arabic shape substitutions: char code => (isolated, final, initial, medial).\n * Arabic Substition A\n */\n var arabicSubstitionA = {\n 0x0621: [0xfe80], // ARABIC LETTER HAMZA\n 0x0622: [0xfe81, 0xfe82], // ARABIC LETTER ALEF WITH MADDA ABOVE\n 0x0623: [0xfe83, 0xfe84], // ARABIC LETTER ALEF WITH HAMZA ABOVE\n 0x0624: [0xfe85, 0xfe86], // ARABIC LETTER WAW WITH HAMZA ABOVE\n 0x0625: [0xfe87, 0xfe88], // ARABIC LETTER ALEF WITH HAMZA BELOW\n 0x0626: [0xfe89, 0xfe8a, 0xfe8b, 0xfe8c], // ARABIC LETTER YEH WITH HAMZA ABOVE\n 0x0627: [0xfe8d, 0xfe8e], // ARABIC LETTER ALEF\n 0x0628: [0xfe8f, 0xfe90, 0xfe91, 0xfe92], // ARABIC LETTER BEH\n 0x0629: [0xfe93, 0xfe94], // ARABIC LETTER TEH MARBUTA\n 0x062a: [0xfe95, 0xfe96, 0xfe97, 0xfe98], // ARABIC LETTER TEH\n 0x062b: [0xfe99, 0xfe9a, 0xfe9b, 0xfe9c], // ARABIC LETTER THEH\n 0x062c: [0xfe9d, 0xfe9e, 0xfe9f, 0xfea0], // ARABIC LETTER JEEM\n 0x062d: [0xfea1, 0xfea2, 0xfea3, 0xfea4], // ARABIC LETTER HAH\n 0x062e: [0xfea5, 0xfea6, 0xfea7, 0xfea8], // ARABIC LETTER KHAH\n 0x062f: [0xfea9, 0xfeaa], // ARABIC LETTER DAL\n 0x0630: [0xfeab, 0xfeac], // ARABIC LETTER THAL\n 0x0631: [0xfead, 0xfeae], // ARABIC LETTER REH\n 0x0632: [0xfeaf, 0xfeb0], // ARABIC LETTER ZAIN\n 0x0633: [0xfeb1, 0xfeb2, 0xfeb3, 0xfeb4], // ARABIC LETTER SEEN\n 0x0634: [0xfeb5, 0xfeb6, 0xfeb7, 0xfeb8], // ARABIC LETTER SHEEN\n 0x0635: [0xfeb9, 0xfeba, 0xfebb, 0xfebc], // ARABIC LETTER SAD\n 0x0636: [0xfebd, 0xfebe, 0xfebf, 0xfec0], // ARABIC LETTER DAD\n 0x0637: [0xfec1, 0xfec2, 0xfec3, 0xfec4], // ARABIC LETTER TAH\n 0x0638: [0xfec5, 0xfec6, 0xfec7, 0xfec8], // ARABIC LETTER ZAH\n 0x0639: [0xfec9, 0xfeca, 0xfecb, 0xfecc], // ARABIC LETTER AIN\n 0x063a: [0xfecd, 0xfece, 0xfecf, 0xfed0], // ARABIC LETTER GHAIN\n 0x0641: [0xfed1, 0xfed2, 0xfed3, 0xfed4], // ARABIC LETTER FEH\n 0x0642: [0xfed5, 0xfed6, 0xfed7, 0xfed8], // ARABIC LETTER QAF\n 0x0643: [0xfed9, 0xfeda, 0xfedb, 0xfedc], // ARABIC LETTER KAF\n 0x0644: [0xfedd, 0xfede, 0xfedf, 0xfee0], // ARABIC LETTER LAM\n 0x0645: [0xfee1, 0xfee2, 0xfee3, 0xfee4], // ARABIC LETTER MEEM\n 0x0646: [0xfee5, 0xfee6, 0xfee7, 0xfee8], // ARABIC LETTER NOON\n 0x0647: [0xfee9, 0xfeea, 0xfeeb, 0xfeec], // ARABIC LETTER HEH\n 0x0648: [0xfeed, 0xfeee], // ARABIC LETTER WAW\n 0x0649: [0xfeef, 0xfef0, 64488, 64489], // ARABIC LETTER ALEF MAKSURA\n 0x064a: [0xfef1, 0xfef2, 0xfef3, 0xfef4], // ARABIC LETTER YEH\n 0x0671: [0xfb50, 0xfb51], // ARABIC LETTER ALEF WASLA\n 0x0677: [0xfbdd], // ARABIC LETTER U WITH HAMZA ABOVE\n 0x0679: [0xfb66, 0xfb67, 0xfb68, 0xfb69], // ARABIC LETTER TTEH\n 0x067a: [0xfb5e, 0xfb5f, 0xfb60, 0xfb61], // ARABIC LETTER TTEHEH\n 0x067b: [0xfb52, 0xfb53, 0xfb54, 0xfb55], // ARABIC LETTER BEEH\n 0x067e: [0xfb56, 0xfb57, 0xfb58, 0xfb59], // ARABIC LETTER PEH\n 0x067f: [0xfb62, 0xfb63, 0xfb64, 0xfb65], // ARABIC LETTER TEHEH\n 0x0680: [0xfb5a, 0xfb5b, 0xfb5c, 0xfb5d], // ARABIC LETTER BEHEH\n 0x0683: [0xfb76, 0xfb77, 0xfb78, 0xfb79], // ARABIC LETTER NYEH\n 0x0684: [0xfb72, 0xfb73, 0xfb74, 0xfb75], // ARABIC LETTER DYEH\n 0x0686: [0xfb7a, 0xfb7b, 0xfb7c, 0xfb7d], // ARABIC LETTER TCHEH\n 0x0687: [0xfb7e, 0xfb7f, 0xfb80, 0xfb81], // ARABIC LETTER TCHEHEH\n 0x0688: [0xfb88, 0xfb89], // ARABIC LETTER DDAL\n 0x068c: [0xfb84, 0xfb85], // ARABIC LETTER DAHAL\n 0x068d: [0xfb82, 0xfb83], // ARABIC LETTER DDAHAL\n 0x068e: [0xfb86, 0xfb87], // ARABIC LETTER DUL\n 0x0691: [0xfb8c, 0xfb8d], // ARABIC LETTER RREH\n 0x0698: [0xfb8a, 0xfb8b], // ARABIC LETTER JEH\n 0x06a4: [0xfb6a, 0xfb6b, 0xfb6c, 0xfb6d], // ARABIC LETTER VEH\n 0x06a6: [0xfb6e, 0xfb6f, 0xfb70, 0xfb71], // ARABIC LETTER PEHEH\n 0x06a9: [0xfb8e, 0xfb8f, 0xfb90, 0xfb91], // ARABIC LETTER KEHEH\n 0x06ad: [0xfbd3, 0xfbd4, 0xfbd5, 0xfbd6], // ARABIC LETTER NG\n 0x06af: [0xfb92, 0xfb93, 0xfb94, 0xfb95], // ARABIC LETTER GAF\n 0x06b1: [0xfb9a, 0xfb9b, 0xfb9c, 0xfb9d], // ARABIC LETTER NGOEH\n 0x06b3: [0xfb96, 0xfb97, 0xfb98, 0xfb99], // ARABIC LETTER GUEH\n 0x06ba: [0xfb9e, 0xfb9f], // ARABIC LETTER NOON GHUNNA\n 0x06bb: [0xfba0, 0xfba1, 0xfba2, 0xfba3], // ARABIC LETTER RNOON\n 0x06be: [0xfbaa, 0xfbab, 0xfbac, 0xfbad], // ARABIC LETTER HEH DOACHASHMEE\n 0x06c0: [0xfba4, 0xfba5], // ARABIC LETTER HEH WITH YEH ABOVE\n 0x06c1: [0xfba6, 0xfba7, 0xfba8, 0xfba9], // ARABIC LETTER HEH GOAL\n 0x06c5: [0xfbe0, 0xfbe1], // ARABIC LETTER KIRGHIZ OE\n 0x06c6: [0xfbd9, 0xfbda], // ARABIC LETTER OE\n 0x06c7: [0xfbd7, 0xfbd8], // ARABIC LETTER U\n 0x06c8: [0xfbdb, 0xfbdc], // ARABIC LETTER YU\n 0x06c9: [0xfbe2, 0xfbe3], // ARABIC LETTER KIRGHIZ YU\n 0x06cb: [0xfbde, 0xfbdf], // ARABIC LETTER VE\n 0x06cc: [0xfbfc, 0xfbfd, 0xfbfe, 0xfbff], // ARABIC LETTER FARSI YEH\n 0x06d0: [0xfbe4, 0xfbe5, 0xfbe6, 0xfbe7], //ARABIC LETTER E\n 0x06d2: [0xfbae, 0xfbaf], // ARABIC LETTER YEH BARREE\n 0x06d3: [0xfbb0, 0xfbb1] // ARABIC LETTER YEH BARREE WITH HAMZA ABOVE\n };\n\n /*\n var ligaturesSubstitutionA = {\n 0xFBEA: []// ARABIC LIGATURE YEH WITH HAMZA ABOVE WITH ALEF ISOLATED FORM\n };\n */\n\n var ligatures = {\n 0xfedf: {\n 0xfe82: 0xfef5, // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM\n 0xfe84: 0xfef7, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM\n 0xfe88: 0xfef9, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM\n 0xfe8e: 0xfefb // ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM\n },\n 0xfee0: {\n 0xfe82: 0xfef6, // ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM\n 0xfe84: 0xfef8, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM\n 0xfe88: 0xfefa, // ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM\n 0xfe8e: 0xfefc // ARABIC LIGATURE LAM WITH ALEF FINAL FORM\n },\n 0xfe8d: { 0xfedf: { 0xfee0: { 0xfeea: 0xfdf2 } } }, // ALLAH\n 0x0651: {\n 0x064c: 0xfc5e, // Shadda + Dammatan\n 0x064d: 0xfc5f, // Shadda + Kasratan\n 0x064e: 0xfc60, // Shadda + Fatha\n 0x064f: 0xfc61, // Shadda + Damma\n 0x0650: 0xfc62 // Shadda + Kasra\n }\n };\n\n var arabic_diacritics = {\n 1612: 64606, // Shadda + Dammatan\n 1613: 64607, // Shadda + Kasratan\n 1614: 64608, // Shadda + Fatha\n 1615: 64609, // Shadda + Damma\n 1616: 64610 // Shadda + Kasra\n };\n\n var alfletter = [1570, 1571, 1573, 1575];\n\n var noChangeInForm = -1;\n var isolatedForm = 0;\n var finalForm = 1;\n var initialForm = 2;\n var medialForm = 3;\n\n jsPDFAPI.__arabicParser__ = {};\n\n //private\n var isInArabicSubstitutionA = (jsPDFAPI.__arabicParser__.isInArabicSubstitutionA = function(\n letter\n ) {\n return typeof arabicSubstitionA[letter.charCodeAt(0)] !== \"undefined\";\n });\n\n var isArabicLetter = (jsPDFAPI.__arabicParser__.isArabicLetter = function(\n letter\n ) {\n return (\n typeof letter === \"string\" &&\n /^[\\u0600-\\u06FF\\u0750-\\u077F\\u08A0-\\u08FF\\uFB50-\\uFDFF\\uFE70-\\uFEFF]+$/.test(\n letter\n )\n );\n });\n\n var isArabicEndLetter = (jsPDFAPI.__arabicParser__.isArabicEndLetter = function(\n letter\n ) {\n return (\n isArabicLetter(letter) &&\n isInArabicSubstitutionA(letter) &&\n arabicSubstitionA[letter.charCodeAt(0)].length <= 2\n );\n });\n\n var isArabicAlfLetter = (jsPDFAPI.__arabicParser__.isArabicAlfLetter = function(\n letter\n ) {\n return (\n isArabicLetter(letter) && alfletter.indexOf(letter.charCodeAt(0)) >= 0\n );\n });\n\n jsPDFAPI.__arabicParser__.arabicLetterHasIsolatedForm = function(letter) {\n return (\n isArabicLetter(letter) &&\n isInArabicSubstitutionA(letter) &&\n arabicSubstitionA[letter.charCodeAt(0)].length >= 1\n );\n };\n\n var arabicLetterHasFinalForm = (jsPDFAPI.__arabicParser__.arabicLetterHasFinalForm = function(\n letter\n ) {\n return (\n isArabicLetter(letter) &&\n isInArabicSubstitutionA(letter) &&\n arabicSubstitionA[letter.charCodeAt(0)].length >= 2\n );\n });\n\n jsPDFAPI.__arabicParser__.arabicLetterHasInitialForm = function(letter) {\n return (\n isArabicLetter(letter) &&\n isInArabicSubstitutionA(letter) &&\n arabicSubstitionA[letter.charCodeAt(0)].length >= 3\n );\n };\n\n var arabicLetterHasMedialForm = (jsPDFAPI.__arabicParser__.arabicLetterHasMedialForm = function(\n letter\n ) {\n return (\n isArabicLetter(letter) &&\n isInArabicSubstitutionA(letter) &&\n arabicSubstitionA[letter.charCodeAt(0)].length == 4\n );\n });\n\n var resolveLigatures = (jsPDFAPI.__arabicParser__.resolveLigatures = function(\n letters\n ) {\n var i = 0;\n var tmpLigatures = ligatures;\n var result = \"\";\n var effectedLetters = 0;\n\n for (i = 0; i < letters.length; i += 1) {\n if (typeof tmpLigatures[letters.charCodeAt(i)] !== \"undefined\") {\n effectedLetters++;\n tmpLigatures = tmpLigatures[letters.charCodeAt(i)];\n\n if (typeof tmpLigatures === \"number\") {\n result += String.fromCharCode(tmpLigatures);\n tmpLigatures = ligatures;\n effectedLetters = 0;\n }\n if (i === letters.length - 1) {\n tmpLigatures = ligatures;\n result += letters.charAt(i - (effectedLetters - 1));\n i = i - (effectedLetters - 1);\n effectedLetters = 0;\n }\n } else {\n tmpLigatures = ligatures;\n result += letters.charAt(i - effectedLetters);\n i = i - effectedLetters;\n effectedLetters = 0;\n }\n }\n\n return result;\n });\n\n jsPDFAPI.__arabicParser__.isArabicDiacritic = function(letter) {\n return (\n letter !== undefined &&\n arabic_diacritics[letter.charCodeAt(0)] !== undefined\n );\n };\n\n var getCorrectForm = (jsPDFAPI.__arabicParser__.getCorrectForm = function(\n currentChar,\n beforeChar,\n nextChar\n ) {\n if (!isArabicLetter(currentChar)) {\n return -1;\n }\n\n if (isInArabicSubstitutionA(currentChar) === false) {\n return noChangeInForm;\n }\n if (\n !arabicLetterHasFinalForm(currentChar) ||\n (!isArabicLetter(beforeChar) && !isArabicLetter(nextChar)) ||\n (!isArabicLetter(nextChar) && isArabicEndLetter(beforeChar)) ||\n (isArabicEndLetter(currentChar) && !isArabicLetter(beforeChar)) ||\n (isArabicEndLetter(currentChar) && isArabicAlfLetter(beforeChar)) ||\n (isArabicEndLetter(currentChar) && isArabicEndLetter(beforeChar))\n ) {\n return isolatedForm;\n }\n\n if (\n arabicLetterHasMedialForm(currentChar) &&\n isArabicLetter(beforeChar) &&\n !isArabicEndLetter(beforeChar) &&\n isArabicLetter(nextChar) &&\n arabicLetterHasFinalForm(nextChar)\n ) {\n return medialForm;\n }\n\n if (isArabicEndLetter(currentChar) || !isArabicLetter(nextChar)) {\n return finalForm;\n }\n return initialForm;\n });\n\n /**\n * @name processArabic\n * @function\n * @param {string} text\n * @returns {string}\n */\n var parseArabic = function(text) {\n text = text || \"\";\n\n var result = \"\";\n var i = 0;\n var j = 0;\n var position = 0;\n var currentLetter = \"\";\n var prevLetter = \"\";\n var nextLetter = \"\";\n\n var words = text.split(\"\\\\s+\");\n var newWords = [];\n for (i = 0; i < words.length; i += 1) {\n newWords.push(\"\");\n for (j = 0; j < words[i].length; j += 1) {\n currentLetter = words[i][j];\n prevLetter = words[i][j - 1];\n nextLetter = words[i][j + 1];\n if (isArabicLetter(currentLetter)) {\n position = getCorrectForm(currentLetter, prevLetter, nextLetter);\n if (position !== -1) {\n newWords[i] += String.fromCharCode(\n arabicSubstitionA[currentLetter.charCodeAt(0)][position]\n );\n } else {\n newWords[i] += currentLetter;\n }\n } else {\n newWords[i] += currentLetter;\n }\n }\n\n newWords[i] = resolveLigatures(newWords[i]);\n }\n result = newWords.join(\" \");\n\n return result;\n };\n\n var processArabic = (jsPDFAPI.__arabicParser__.processArabic = jsPDFAPI.processArabic = function() {\n var text =\n typeof arguments[0] === \"string\" ? arguments[0] : arguments[0].text;\n var tmpText = [];\n var result;\n\n if (Array.isArray(text)) {\n var i = 0;\n tmpText = [];\n for (i = 0; i < text.length; i += 1) {\n if (Array.isArray(text[i])) {\n tmpText.push([parseArabic(text[i][0]), text[i][1], text[i][2]]);\n } else {\n tmpText.push([parseArabic(text[i])]);\n }\n }\n result = tmpText;\n } else {\n result = parseArabic(text);\n }\n if (typeof arguments[0] === \"string\") {\n return result;\n } else {\n arguments[0].text = result;\n return arguments[0];\n }\n });\n\n jsPDFAPI.events.push([\"preProcessText\", processArabic]);\n})(jsPDF.API);\n","/** @license\n * jsPDF Autoprint Plugin\n *\n * Licensed under the MIT License.\n * http://opensource.org/licenses/mit-license\n */\n\nimport { jsPDF } from \"../jspdf.js\";\n\n/**\n * @name autoprint\n * @module\n */\n(function(jsPDFAPI) {\n \"use strict\";\n\n /**\n * Makes the PDF automatically open the print-Dialog when opened in a PDF-viewer.\n *\n * @name autoPrint\n * @function\n * @param {Object} options (optional) Set the attribute variant to 'non-conform' (default) or 'javascript' to activate different methods of automatic printing when opening in a PDF-viewer .\n * @returns {jsPDF}\n * @example\n * var doc = new jsPDF();\n * doc.text(10, 10, 'This is a test');\n * doc.autoPrint({variant: 'non-conform'});\n * doc.save('autoprint.pdf');\n */\n jsPDFAPI.autoPrint = function(options) {\n \"use strict\";\n var refAutoPrintTag;\n options = options || {};\n options.variant = options.variant || \"non-conform\";\n\n switch (options.variant) {\n case \"javascript\":\n //https://github.com/Rob--W/pdf.js/commit/c676ecb5a0f54677b9f3340c3ef2cf42225453bb\n this.addJS(\"print({});\");\n break;\n case \"non-conform\":\n default:\n this.internal.events.subscribe(\"postPutResources\", function() {\n refAutoPrintTag = this.internal.newObject();\n this.internal.out(\"<<\");\n this.internal.out(\"/S /Named\");\n this.internal.out(\"/Type /Action\");\n this.internal.out(\"/N /Print\");\n this.internal.out(\">>\");\n this.internal.out(\"endobj\");\n });\n\n this.internal.events.subscribe(\"putCatalog\", function() {\n this.internal.out(\"/OpenAction \" + refAutoPrintTag + \" 0 R\");\n });\n break;\n }\n return this;\n };\n})(jsPDF.API);\n","/**\n * @license\n * Copyright (c) 2014 Steven Spungin (TwelveTone LLC) steven@twelvetone.tv\n *\n * Licensed under the MIT License.\n * http://opensource.org/licenses/mit-license\n */\n\nimport { jsPDF } from \"../jspdf.js\";\n\n/**\n * jsPDF Canvas PlugIn\n * This plugin mimics the HTML5 Canvas\n *\n * The goal is to provide a way for current canvas users to print directly to a PDF.\n * @name canvas\n * @module\n */\n(function(jsPDFAPI) {\n \"use strict\";\n\n /**\n * @class Canvas\n * @classdesc A Canvas Wrapper for jsPDF\n */\n var Canvas = function() {\n var jsPdfInstance = undefined;\n Object.defineProperty(this, \"pdf\", {\n get: function() {\n return jsPdfInstance;\n },\n set: function(value) {\n jsPdfInstance = value;\n }\n });\n\n var _width = 150;\n /**\n * The height property is a positive integer reflecting the height HTML attribute of the