UNPKG

@syncfusion/ej2-pdf

Version:

Feature-rich JavaScript PDF library with built-in support for loading and manipulating PDF document.

4,425 lines 187 kB
var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
import { _PdfContentStream, _PdfStream } from './base-stream';
import { _PdfCrossReference } from './pdf-cross-reference';
import { _Linearization } from './pdf-parser';
import { _isWhiteSpace, FormatError, _decode, _getNewGuidString, _isNullOrUndefined, _updatePageSettings, _updatePageCount, _convertDateToString, _convertStringToDate, _getCjkEncoding, _getCjkDescendantFont, _resolveStandardFontFamily, _resolveCjkFontFamily, _bytesToHex } from './utils';
import { _PdfCatalog } from './pdf-catalog';
import { _PdfDictionary, _PdfReference, _isName, _PdfName, _clearPrimitiveCaches } from './pdf-primitives';
import { PdfPage } from './pdf-page';
import { Save } from '@syncfusion/ej2-file-utils';
import { DataFormat, PdfPermissionFlag, PdfTextAlignment, PdfPageOrientation, PdfRotationAngle, _PdfWordWrapType, PdfTemplateHorizontalAlignment, PdfTemplateVerticalAlignment, PdfTemplateLayerMode, _PdfDocumentTemplateKey, _TemplateSide, _PdfAlignmentStyle } from './enumerator';
import { PdfForm } from './form/form';
import { _PdfTransformationMatrix, PdfBrush, PdfGraphics } from './graphics/pdf-graphics';
import { _PdfCjkStandardFontMetricsFactory, _PdfStandardFontMetricsFactory, PdfCjkStandardFont, PdfFontFamily, PdfFontStyle, PdfStandardFont, PdfTrueTypeFont } from './fonts/pdf-standard-font';
import { PdfStringFormat, PdfVerticalAlignment } from './fonts/pdf-string-format';
import { _XfdfDocument } from './import-export/xfdf-document';
import { _JsonDocument } from './import-export/json-document';
import { _FdfDocument } from './import-export/fdf-document';
import { PdfBookmarkBase, _PdfNamedDestinationCollection } from './pdf-outline';
import { _XmlDocument } from './import-export/xml-document';
import { PdfFileStructure } from './pdf-file-structure';
import { _PdfMergeHelper } from './pdf-merge';
import { PdfPageImportOptions } from './pdf-page-import-options';
import { PdfLayerCollection } from './layers/layer-collection';
import { PdfSection } from './pdf-section';
import { _UnicodeTrueTypeFont } from './fonts/unicode-true-type-font';
import { _MD5 } from './security/encryptors/messageDigest5';
import { PdfSignature } from './security/digital-signature/signature/pdf-signature';
import { initializeTelemetry, initializeTelemetryFeature, validateLicense } from '@syncfusion/ej2-base';
import { PdfUriAnnotation } from './annotations/annotation';
import { _PdfStringLayouter } from './fonts/string-layouter';
import { PdfXmpMetadata } from './xmp/pdf-xmp-metadata';
import { _XmlReader } from './xmp/xml-reader';
import { _PdfFlateStream } from './flate-stream';
import { PdfCustomMetadata } from './xmp/pdf-custom-metadata';
import { _PdfStreamWriter } from './graphics/pdf-stream-writer';
/**
 * Represents a PDF document and can be used to parse an existing PDF document.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Flatten annotations and form fields
 * document.flatten = true;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfDocument = /** @class */ (function () {
    function PdfDocument(data, password) {
        this._headerSignature = new Uint8Array([0x25, 0x50, 0x44, 0x46, 0x2d]);
        this._startXrefSignature = new Uint8Array([0x73, 0x74, 0x61, 0x72, 0x74, 0x78, 0x72, 0x65, 0x66]);
        this._endObjSignature = new Uint8Array([0x65, 0x6e, 0x64, 0x6f, 0x62, 0x6a]);
        this._version = '';
        /**
         * Effective permission flags for the current document.
         *
         * @private
         */
        this._permissions = PdfPermissionFlag.default;
        /**
         * Indicates whether the source document is encrypted.
         *
         * @private
         */
        this._isEncrypted = false;
        /**
         * Indicates whether a user password was used to decrypt the document.
         *
         * @private
         */
        this._isUserPassword = false;
        /**
         * Indicates whether only a user password is present for the document.
         *
         * @private
         */
        this._hasUserPasswordOnly = false;
        /**
         * Indicates whether only attachments should be encrypted.
         *
         * @private
         */
        this._encryptOnlyAttachment = false;
        /**
         * Indicates whether metadata needs to be encrypted.
         *
         * @private
         */
        this._encryptMetaData = false;
        /**
         * Indicates whether the current operation is an export action (annotations/forms).
         *
         * @private
         */
        this._isExport = false;
        this._allowCustomData = false;
        /**
         * Indicates that the current import operation is duplicating an existing page.
         *
         * @private
         */
        this._isDuplicatePage = false;
        /**
         * Indicates that the current document is used during a split operation.
         *
         * @private
         */
        this._isSplitDocument = false;
        /**
         * Optional content configuration dictionary references.
         *
         * @private
         */
        this._optionalContentDictionaries = [];
        /**
         * Optional content order array of OCG/OCMD references.
         *
         * @private
         */
        this._order = [];
        /**
         * Optional content groups to be set ON.
         *
         * @private
         */
        this._on = [];
        /**
         * Optional content groups to be set OFF.
         *
         * @private
         */
        this._off = [];
        /**
         * Optional content group/intent relationships.
         *
         * @private
         */
        this._as = [];
        /**
         * Optional content groups to be printed.
         *
         * @private
         */
        this._printLayer = [];
        /**
         * Indicates whether the document was loaded from an existing byte source.
         *
         * @private
         */
        this._isLoaded = true;
        this._isFormImport = false;
        /**
         * Collection of sections within the document.
         *
         * @private
         */
        this._sections = [];
        /**
         * Maintains background layer mappings for each page.
         *
         * @private
         */
        this._backgroundLayers = new Map();
        /**
         * Indicates whether template rendering has started for the document.
         *
         * @private
         */
        this._templateRenderingStarted = false;
        initializeTelemetry('PDFLibrary');
        this._fontCollection = new Map();
        if (data) {
            this._stream = new _PdfStream(typeof data === 'string' ? _decode(data) : data);
            this._fileStructure = new PdfFileStructure();
            this._crossReference = new _PdfCrossReference(this, password);
            this._pages = new Map();
            this._checkHeader();
            this._crossReference._setStartXRef(this._startXRef);
            try {
                this._parse(false);
            }
            catch (e) {
                if (e.name === 'XRefParseException') {
                    this._parse(true);
                }
                else {
                    throw e;
                }
            }
            this._crossReference._version = this._version;
        }
        else {
            this._isLoaded = false;
            this._stream = new _PdfStream([]);
            this._version = '1.4';
            this._fileStructure = new PdfFileStructure();
            this._fileStructure.isIncrementalUpdate = false;
            this._crossReference = new _PdfCrossReference(this);
            this._crossReference._version = this._version;
            this._crossReference._nextReferenceNumber = 1;
            var catalogDictionary = new _PdfDictionary(this._crossReference);
            catalogDictionary.update('Type', _PdfName.get('Catalog'));
            var catalogReference = this._crossReference._getNextReference();
            catalogDictionary.objId = catalogReference.objectNumber + ' ' + catalogReference.generationNumber;
            this._crossReference._cacheMap.set(catalogReference, catalogDictionary);
            var trailerDictionary = new _PdfDictionary();
            trailerDictionary.update('Root', catalogReference);
            this._crossReference._trailer = trailerDictionary;
            this._crossReference._root = catalogDictionary;
            var topPagesDictionary = new _PdfDictionary(this._crossReference);
            topPagesDictionary.update('Type', _PdfName.get('Pages'));
            topPagesDictionary.update('Kids', []);
            topPagesDictionary.update('Count', 0);
            var topPagesReference = this._crossReference._getNextReference();
            this._crossReference._cacheMap.set(topPagesReference, topPagesDictionary);
            catalogDictionary.update('Pages', topPagesReference);
            this._catalog = new _PdfCatalog(this._crossReference);
            this._pages = new Map();
        }
    }
    Object.defineProperty(PdfDocument.prototype, "_allowImportCustomData", {
        /**
         * Gets whether custom data import is allowed.
         *
         * @private
         * @returns {boolean} `true` if importing custom data is allowed; otherwise, `false`.
         */
        get: function () {
            return this._allowCustomData;
        },
        /**
         * Sets whether custom data import is allowed.
         *
         * @private
         * @param {boolean} value `true` to allow custom data import; otherwise, `false`.
         */
        set: function (value) {
            this._allowCustomData = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "_linearization", {
        /**
         * Gets the parsed linearization information if available.
         *
         * @private
         * @returns {_Linearization} The linearization helper if the document is linearized; otherwise, `undefined`.
         */
        get: function () {
            if (!this._linear) {
                var value = void 0;
                try {
                    value = new _Linearization(this._stream);
                }
                catch (err) { } // eslint-disable-line
                this._linear = value;
            }
            return this._linear;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "_startXRef", {
        /**
         * Locates and returns the byte offset of the startxref section.
         *
         * @private
         * @returns {number} The position of the last `startxref` marker; otherwise, 0 if not found.
         */
        get: function () {
            var stream = this._stream;
            var startXRef = 0;
            if (this._linearization && this._linearization.isValid) {
                stream.reset();
                if (this._find(stream, this._endObjSignature)) {
                    startXRef = stream.position + 6 - stream.start;
                }
            }
            else {
                var step = 1024;
                var startXRefLength = this._startXrefSignature.length;
                var found = false;
                var position = stream.end;
                while (!found && position > 0) {
                    position -= step - startXRefLength;
                    if (position < 0) {
                        position = 0;
                    }
                    stream.position = position;
                    found = this._find(stream, this._startXrefSignature, step, true);
                }
                if (found) {
                    stream.skip(9);
                    var ch = void 0;
                    do {
                        ch = stream.getByte();
                    } while (_isWhiteSpace(ch));
                    var str = '';
                    while (ch >= 0x20 && ch <= 0x39) {
                        str += String.fromCharCode(ch);
                        ch = stream.getByte();
                    }
                    startXRef = parseInt(str, 10);
                    if (isNaN(startXRef)) {
                        startXRef = 0;
                    }
                }
            }
            return startXRef;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "isEncrypted", {
        /**
         * Gets a value indicating whether the document is encrypted. (Read Only).
         *
         * @returns {boolean} A boolean value indicates whether the document is encrypted.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Gets a value indicating whether the document is encrypted.
         * let isEncrypted: boolean = document.isEncrypted;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._isEncrypted;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "isUserPassword", {
        /**
         * Gets a value indicating whether the document is decrypted using the user password. (Read only).
         *
         * @returns {boolean} A boolean value indicates whether the document is decrypted using the user password.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Gets a value indicating whether the document is decrypted using the user password
         * let isUserPassword: boolean = document.isUserPassword;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._isUserPassword;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "pageCount", {
        /**
         * Gets the page count (Read only).
         *
         * @returns {number} Number of pages
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Gets the page count
         * let count: number = document.pageCount;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._pageCount === 'undefined') {
                this._pageCount = 0;
                if (this._linearization && this._linearization.isValid) {
                    this._pageCount = this._linearization.pageCount;
                }
                else {
                    this._pageCount = this._catalog.pageCount;
                }
            }
            return this._pageCount;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "form", {
        /**
         * Gets the PDF form fields included in the document (Read only).
         *
         * @returns {PdfForm} Form object
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access loaded form
         * let form: PdfForm = document.form;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._form === 'undefined') {
                this._form = new PdfForm(this._catalog.acroForm, this._crossReference);
            }
            return this._form;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "flatten", {
        /**
         * Gets the boolean flag to flatten the annotations and form fields.
         *
         * @returns {boolean} Flag to flatten
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Gets the flatten value applied
         * let flatten: boolean = document.flatten;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._flatten;
        },
        /**
         * Sets the boolean flag to flatten the annotations and form fields.
         *
         * @param {boolean} value to flatten
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Flatten PDF annotations and form fields
         * document.flatten = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._flatten = value;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Decompresses PDF stream bytes if they are compressed with a filter.
     *
     * @private
     * @param {_PdfStream} stream The PDF stream to decompress.
     * @returns {Uint8Array} The decompressed bytes, or original bytes if not compressed.
     */
    PdfDocument.prototype._getDecompressedStreamBytes = function (stream) {
        if (stream instanceof _PdfFlateStream) {
            var len = stream.bytes ? stream.bytes.length : (stream.bufferLength || 0); // eslint-disable-line
            return stream.getBytes(len);
        }
        return stream.bytes;
    };
    /**
     * Gets the XMP metadata of the PDF document.
     *
     * @private
     * @returns {PdfXmpMetadata} The XMP metadata object present.
     */
    PdfDocument.prototype._getMetadataValue = function () {
        if (this._xmpMetadata) {
            return this._xmpMetadata;
        }
        if (this._catalog && this._catalog._catalogDictionary.has('Metadata')) {
            var metadataRef = this._catalog._catalogDictionary.getRaw('Metadata'); // eslint-disable-line
            var metadataStream = void 0; // eslint-disable-line
            if (metadataRef instanceof _PdfReference) {
                var obj = this._crossReference._fetch(metadataRef); // eslint-disable-line
                if (obj instanceof _PdfStream || obj instanceof _PdfFlateStream) {
                    metadataStream = obj;
                }
            }
            else if (metadataRef instanceof _PdfStream || metadataRef instanceof _PdfFlateStream) {
                metadataStream = metadataRef;
            }
            if (metadataStream) {
                var reader = new _XmlReader();
                reader._load(this._getDecompressedStreamBytes(metadataStream));
                this._xmpMetadata = reader._parseXmp();
                return this._xmpMetadata;
            }
        }
        this._xmpMetadata = new PdfXmpMetadata();
        return this._xmpMetadata;
    };
    Object.defineProperty(PdfDocument.prototype, "permissions", {
        /**
         * Gets the permission flag of the PDF document (Read only).
         *
         * @returns {PdfPermissionFlag} permission flag. Default value is PdfPermissionFlag.default.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Gets the permission flag
         * let permission: PdfPermissionFlag = document.permissions;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._crossReference) {
                var flag = this._crossReference._permissionFlags;
                if (typeof flag !== 'undefined') {
                    this._permissions = (flag & ~-3904);
                }
            }
            return this._permissions;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "bookmarks", {
        /**
         * Gets the bookmarks (Read only).
         *
         * @returns {PdfBookmarkBase} Bookmarks.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get bookmarks
         * let bookmarks: PdfBookmarkBase = document.bookmarks;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            var catalog = this._catalog;
            if (catalog) {
                if (catalog._catalogDictionary.has('Outlines')) {
                    var reference = catalog._catalogDictionary._get('Outlines');
                    var outlines = catalog._catalogDictionary.get('Outlines');
                    if (outlines) {
                        this._bookmarkBase = new PdfBookmarkBase(outlines, this._crossReference);
                        this._bookmarkBase._reference = reference;
                        if (outlines.has('First')) {
                            this._bookmarkBase._reproduceTree();
                        }
                    }
                }
                else {
                    var outlines = new _PdfDictionary(this._crossReference);
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, outlines);
                    catalog._catalogDictionary.update('Outlines', reference);
                    this._crossReference._allowCatalog = true;
                    this._bookmarkBase = new PdfBookmarkBase(outlines, this._crossReference);
                    this._bookmarkBase._reference = reference;
                }
            }
            return this._bookmarkBase;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "fileStructure", {
        /**
         * Gets the internal structure of the PDF document.
         *
         * @returns {PdfFileStructure} The internal structure of the PDF document.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the internal file structure of the PDF document
         * let fileStructure: PdfFileStructure = document.fileStructure;
         * // Get the cross reference type
         * let type: PdfCrossReferenceType = fileStructure.crossReferenceType;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._fileStructure;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "layers", {
        /**
         * Gets the collection of `PdfLayer` from the document.
         *
         * @returns {PdfLayerCollection} Layer collection.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Access the collection of layers in the document
         * let layers: PdfLayerCollection = document.layers;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._layers) {
                this._layers = new PdfLayerCollection(this);
            }
            return this._layers;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocument.prototype, "template", {
        /**
         * Gets the template configuration for document-level headers and footers.
         *
         * ```typescript
         * // Create new document
         * let document: PdfDocument = new PdfDocument();
         * // Initialize the standard font
         * const font: PdfStandardFont = new PdfStandardFont(PdfFontFamily.helvetica, 12);
         * / Initialize brush
         * const brush: PdfBrush = new PdfBrush({ r: 0, g: 0, b: 0 });
         * // Create header template
         * let headerTemplate: PdfPageTemplateElement = new PdfPageTemplateElement({width: 500, height: 50});
         * // Draw content on header
         * headerTemplate.graphics.drawString('Document Header', font, {x: 10, y: 10, width: 400, height: 30}, brush);
         * // Assign template to document
         * document.template.top = {template: headerTemplate };
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         *
         * @returns {PdfDocumentTemplate} The document template.
         */
        get: function () {
            if (this._isLoaded) {
                return this._template;
            }
            if (!this._template) {
                this._template = {};
            }
            return this._template;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Gets an array of revision numbers for the PDF document.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * // Retrieve all revision indexes of the PDF document
     * let revisions: number[] = document.getRevisions();
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @returns {number[]} - The list of revisions in the document.
     */
    PdfDocument.prototype.getRevisions = function () {
        var _this = this;
        if (!this._isLoaded) {
            return undefined;
        }
        if (this._revisions) {
            return this._revisions;
        }
        var startCrossReferences = this._startXRefParsedCache
            ? this._startXRefParsedCache.sort(function (a, b) { return a - b; })
            : [];
        if (startCrossReferences.length === 0) {
            return (this._revisions = []);
        }
        var eofSig = new Uint8Array([0x25, 0x25, 0x45, 0x4F, 0x46]);
        var stream = this._stream;
        var endOfFileSign = [];
        startCrossReferences.forEach(function (entry) {
            stream.position = entry;
            var remaining = stream.end - stream.position;
            if (remaining < eofSig.length || !_this._find(stream, eofSig, remaining, false)) {
                return;
            }
            var j = stream.position + eofSig.length;
            stream.position = j;
            if (stream.position < stream.end) {
                var nextCharacter = stream.getByte();
                if (nextCharacter === 0x0d) {
                    j++;
                    if (stream.position < stream.end && stream.getByte() === 0x0a) {
                        j++;
                    }
                }
                else if (nextCharacter === 0x0a) {
                    j++;
                }
            }
            endOfFileSign.push(j);
        });
        return (this._revisions = endOfFileSign);
    };
    PdfDocument.prototype.embedFont = function (arg1, arg2, arg3, arg4) {
        var key;
        var primitive;
        if (typeof arg1 === 'string' || arg1 instanceof Uint8Array) {
            var fontData = typeof arg1 === 'string' ? _decode(arg1) : arg1;
            key = this._computeFontHash(fontData);
            var size_1 = arg2;
            var options = arg3;
            primitive = this._getOrCreateFontPrimitive(key, { type: 'ttf', data: fontData });
            this._fontCollection.set(key, primitive);
            var style_1 = PdfFontStyle.regular;
            if (options && options.shouldUnderline) {
                style_1 = PdfFontStyle.underline;
            }
            if (options && options.shouldStrikeout) {
                style_1 = PdfFontStyle.strikeout;
            }
            var trueTypeFont = new PdfTrueTypeFont(fontData, size_1, style_1, primitive);
            trueTypeFont._document = this;
            return trueTypeFont;
        }
        var fontFamily = arg1; // eslint-disable-line
        var style = arg3;
        var size = arg2;
        var isCjk = false;
        if (typeof arg4 === 'boolean') {
            isCjk = arg4;
        }
        if (isCjk) {
            var cjkFamily = fontFamily;
            key = "cjk_" + cjkFamily + "_" + style;
            primitive = this._getOrCreateFontPrimitive(key, { type: 'cjk', family: cjkFamily, style: style });
        }
        else {
            var standardFamily = fontFamily;
            key = "standard_" + standardFamily + "_" + style;
            primitive = this._getOrCreateFontPrimitive(key, { type: 'standard', family: standardFamily, style: style });
        }
        return this._createFontFromPrimitive(primitive, size, style);
    };
    /**
     * Creates or retrieves a font primitive for the specified key and font data.
     *
     * @private
     * @param {string} key Unique key used to cache the font primitive.
     * @param {_FontData} fontData Font descriptor and/or data used to build a font primitive.
     * @returns {_PdfFontPrimitive} The created or cached font primitive.
     */
    PdfDocument.prototype._getOrCreateFontPrimitive = function (key, fontData) {
        if (typeof key === 'string' && this._fontCollection.has(key)) {
            return this._fontCollection.get(key);
        }
        var dictionary = new _PdfDictionary();
        var primitive;
        switch (fontData.type) {
            case 'standard': {
                var metrics = _PdfStandardFontMetricsFactory._getMetrics(fontData.family, fontData.style);
                dictionary._updated = true;
                dictionary.set('Type', _PdfName.get('Font'));
                dictionary.set('Subtype', _PdfName.get('Type1'));
                dictionary.set('BaseFont', new _PdfName(metrics._postScriptName));
                if (fontData.family !== PdfFontFamily.symbol && fontData.family !== PdfFontFamily.zapfDingbats) {
                    dictionary.set('Encoding', new _PdfName('WinAnsiEncoding'));
                }
                primitive = { dictionary: dictionary, metrices: metrics };
                break;
            }
            case 'cjk': {
                var metrics = _PdfCjkStandardFontMetricsFactory._getMetrics(fontData.family, fontData.style);
                dictionary._updated = true;
                dictionary.set('Type', _PdfName.get('Font'));
                dictionary.set('Subtype', _PdfName.get('Type0'));
                dictionary.set('BaseFont', new _PdfName(metrics._postScriptName));
                dictionary.set('Encoding', _getCjkEncoding(fontData.family));
                dictionary.set('DescendantFonts', _getCjkDescendantFont(fontData.family, fontData.style, metrics));
                primitive = { dictionary: dictionary, metrices: metrics };
                break;
            }
            case 'ttf': {
                var fontInternal = new _UnicodeTrueTypeFont(fontData.data);
                fontInternal._createInternals();
                dictionary = fontInternal._getInternals();
                fontInternal._metrics._isUnicodeFont = true;
                primitive = { dictionary: dictionary, metrices: fontInternal._metrics, fontInternal: fontInternal };
                break;
            }
            default:
                throw new Error('Unsupported font type.');
        }
        this._fontCollection.set(key, primitive);
        return primitive;
    };
    /**
     * Creates a concrete `PdfFont` from a font primitive and style/size.
     *
     * @private
     * @param {_PdfFontPrimitive} primitive The source font primitive.
     * @param {number} size The font size.
     * @param {PdfFontStyle} style The font style.
     * @returns {PdfFont} The created font wrapper object.
     */
    PdfDocument.prototype._createFontFromPrimitive = function (primitive, size, style) {
        var subtype = primitive.dictionary.get('Subtype').name;
        var baseFontName = primitive.dictionary.get('BaseFont').name;
        var font;
        switch (subtype) {
            case 'Type1':
                font = new PdfStandardFont(_resolveStandardFontFamily(baseFontName), size, style, primitive);
                break;
            case 'Type0':
                font = new PdfCjkStandardFont(_resolveCjkFontFamily(baseFontName), size, style, primitive);
                break;
            default:
                throw new Error("Unsupported font subtype: " + subtype);
        }
        font.style = style;
        font._document = this;
        return font;
    };
    /**
     * Computes a stable hash for font data (MD5 hex).
     *
     * @private
     * @param {Uint8Array} fontData Raw font bytes.
     * @returns {string} Hex-encoded MD5 hash of the font bytes.
     */
    PdfDocument.prototype._computeFontHash = function (fontData) {
        var md5 = new _MD5();
        var hashBytes = md5.hash(fontData, 0, fontData.length);
        return _bytesToHex(hashBytes);
    };
    /**
     * Gets the `PdfPage` at the specified index.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Access first page
     * let page: PdfPage = document.getPage(0);
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {number} pageIndex Page index.
     * @returns {PdfPage} PDF page at the specified index.
     */
    PdfDocument.prototype.getPage = function (pageIndex) {
        if (pageIndex < 0 || pageIndex >= this.pageCount) {
            throw new Error('Invalid page index');
        }
        var cachedPage = this._pages.get(pageIndex);
        if (cachedPage) {
            return cachedPage;
        }
        var _a = this, _catalog = _a._catalog, _linearization = _a._linearization;
        var promise;
        if (_linearization && _linearization.isValid && _linearization.pageFirst === pageIndex) {
            promise = this._getLinearizationPage(pageIndex);
        }
        else {
            promise = _catalog._getPageDictionary(pageIndex);
        }
        var page = new PdfPage(this._crossReference, pageIndex, promise.dictionary, promise.reference);
        this._pages.set(pageIndex, page);
        return page;
    };
    PdfDocument.prototype.addPage = function (arg1, arg2) {
        var settings;
        var pageIndex;
        if (typeof arg2 !== 'undefined') {
            settings = arg2;
            pageIndex = arg1;
            this._checkPageNumber(pageIndex);
        }
        else if (typeof arg1 === 'undefined') {
            settings = new PdfPageSettings();
            pageIndex = this.pageCount;
        }
        else if (arg1 instanceof PdfPageSettings) {
            settings = arg1;
            pageIndex = this.pageCount;
        }
        else {
            settings = new PdfPageSettings();
            pageIndex = arg1;
            this._checkPageNumber(pageIndex);
        }
        var sectionDictionary = new _PdfDictionary(this._crossReference);
        sectionDictionary.update('Type', _PdfName.get('Pages'));
        sectionDictionary.update('Count', 1);
        _updatePageSettings(sectionDictionary, settings);
        var sectionReference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(sectionReference, sectionDictionary);
        sectionDictionary.objId = sectionReference.toString();
        var pageDictionary = new _PdfDictionary(this._crossReference);
        pageDictionary.update('Type', _PdfName.get('Page'));
        var pageReference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(pageReference, pageDictionary);
        pageDictionary.objId = pageReference.toString();
        pageDictionary.update('Parent', sectionReference);
        sectionDictionary.update('Kids', [pageReference]);
        if (this.pageCount === 0) {
            var parentReference = this._catalog._catalogDictionary._get('Pages');
            if (parentReference && this._catalog._topPagesDictionary) {
                var isUpdated = false;
                if (this._catalog._topPagesDictionary.has('Kids')) {
                    var kids = this._catalog._topPagesDictionary.get('Kids');
                    if (kids) {
                        kids.push(sectionReference);
                        this._catalog._topPagesDictionary.update('Kids', kids);
                        isUpdated = true;
                    }
                }
                if (!isUpdated) {
                    this._catalog._topPagesDictionary.update('Kids', [sectionReference]);
                }
                this._catalog._topPagesDictionary.update('Count', 1);
                sectionDictionary.update('Parent', parentReference);
            }
            else {
                this._catalog._catalogDictionary.update('Pages', sectionReference);
            }
            this._pages = new Map();
            this._pageCount = 1;
        }
        else {
            var lastPage_1 = this.getPage(pageIndex === this.pageCount ? (pageIndex - 1) : pageIndex);
            if (lastPage_1 && lastPage_1._pageDictionary) {
                var parentReference = lastPage_1._pageDictionary._get('Parent');
                var parentDictionary = this._crossReference._fetch(parentReference);
                if (parentDictionary && parentDictionary.has('Kids')) {
                    var kids = parentDictionary.get('Kids');
                    if (kids) {
                        if (pageIndex === this.pageCount) {
                            kids.push(sectionReference);
                        }
                        else {
                            var newKids_1 = [];
                            kids.forEach(function (entry) {
                                if (entry === lastPage_1._ref) {
                                    newKids_1.push(sectionReference);
                                }
                                newKids_1.push(entry);
                            });
                            kids = newKids_1;
                            this._updatePageCache(pageIndex);
                        }
                        parentDictionary.update('Kids', kids);
                        sectionDictionary.update('Parent', parentReference);
                        _updatePageCount(parentDictionary, 1);
                        this._pageCount = this.pageCount + 1;
                    }
                }
            }
        }
        var result = new PdfPage(this._crossReference, pageIndex, pageDictionary, pageReference);
        result._pageSettings = settings;
        result._isNew = true;
        this._pages.set(pageIndex, result);
        return result;
    };
    PdfDocument.prototype.addSection = function (settings) {
        var result;
        if (!this._isLoaded) {
            var pageSettings = settings ? settings : new PdfPageSettings();
            result = new PdfSection(this, pageSettings);
            this._sections.push(result);
        }
        return result;
    };
    PdfDocument.prototype.removePage = function (argument) {
        var targetPage = (argument instanceof PdfPage) ? argument : this.getPage(argument);
        this._removePage(targetPage);
    };
    /**
     * Gets the document information of the PDF.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Gets the document information of the PDF
     * let documentProperties: PdfDocumentInformation = document.getDocumentInformation();
     * // Gets the title of the PDF document
     * let title = documentProperties.title;
     * // Gets the author of the PDF document
     * let author = documentProperties.author;
     * // Gets the subject of the PDF document
     * let subject = documentProperties.subject;
     * // Gets the keywords of the PDF document
     * let keywords = documentProperties.keywords;
     * // Gets the creator of the PDF document
     * let creator = documentProperties.creator;
     * // Gets the producer of the PDF document
     * let producer = documentProperties.producer;
     * // Gets the language of the PDF document
     * let language = documentProperties.language;
     * // Gets the creation date of the PDF document
     * let creationDate = documentProperties.creationDate;
     * // Gets the modification date of the PDF document
     * let modificationDate = documentProperties.modificationDate;
     * document.destroy();
     * ```
     *
     * @param {boolean} skipMetadata flag value to skip the metadata.
     * @returns {PdfDocumentInformation} Document information.
     */
    PdfDocument.prototype.getDocumentInformation = function (skipMetadata) {
        if (skipMetadata === void 0) { skipMetadata = true; }
        var infoDict = this._getInfoDictionary(false);
        var catalogDictionary = this._catalog._catalogDictionary;
        var result = {};
        if (!infoDict) {
            if (!skipMetadata) {
                result.xmpMetadata = this._getMetadataValue();
            }
            result.customMetadata = new PdfCustomMetadata();
            return result;
        }
        result.title = this._readInfoString(infoDict, 'Title');
        result.author = this._readInfoString(infoDict, 'Author');
        result.subject = this._readInfoString(infoDict, 'Subject');
        result.keywords = this._readInfoString(infoDict, 'Keywords');
        result.creator = this._readInfoString(infoDict, 'Creator');
        result.producer = this._readInfoString(infoDict, 'Producer');
        result.language = this._readInfoString(catalogDictionary, 'Lang');
        var creation = this._readInfoString(infoDict, 'CreationDate');
        if (typeof creation === 'string') {
            result.creationDate = _convertStringToDate(creation);
        }
        var mod = this._readInfoString(infoDict, 'ModDate');
        if (typeof mod === 'string') {
            result.modificationDate = _convertStringToDate(mod);
        }
        if (!skipMetadata) {
            result.xmpMetadata = this._getMetadataValue();
        }
        var standardKeys = new Set([
            'Title', 'Author', 'Subject', 'Keywords',
            'Creator', 'Producer', 'CreationDate', 'ModDate', 'Trapped'
        ]);
        var custom = new PdfCustomMetadata();
        for (var _i = 0, _a = Object.keys(infoDict._map); _i < _a.length; _i++) {
            var key = _a[_i];
            if (!standardKeys.has(key)) {
                var value = infoDict.get(key); // eslint-disable-line
                if (typeof value === 'string') {
                    custom.set(key, value);
                }
            }
        }
        result.customMetadata = custom;
        return result;
    };
    PdfDocument.prototype._readInfoString = function (dict, key) {
        if (dict && !dict.has(key)) {
            return undefined;
        }
        var value = dict.get(key); // eslint-disable-line
        return typeof value === 'string' ? value : undefined;
    };
    /**
     * Sets the document information of the PDF.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Sets the document information of the PDF
     * document.setDocumentInformation({
     *   author: 'Syncfusion',
     *   modificationDate: Date.now(),
     *   creator: 'Essential PDF',
     *   keywords: 'PDF',
     *   subject: 'Document information DEMO',
     *   title: 'Essential PDF Sample',
     *   producer: 'Syncfusion PDF'
     * });
     * // Save the document
     * document.save('output.pdf);
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {PdfDocumentInformation} information Fields to set.
     * @returns {void} Returns nothing.
     */
    PdfDocument.prototype.setDocumentInformation = function (information) {
        var _this = this;
        var infoDict = this._getInfoDictionary(true);
        var catalogDictionary = this._catalog._catalogDictionary;
        this._writeInfoString(infoDict, 'Title', information.title);
        this._writeInfoString(infoDict, 'Author', information.author);
        this._writeInfoString(infoDict, 'Subject', information.subject);
        this._writeInfoString(infoDict, 'Keywords', information.keywords);
        this._writeInfoString(infoDict, 'Creator', information.creator);
        this._writeInfoString(infoDict, 'Producer', information.producer);
        this._writeInfoString(catalogDictionary, 'Lang', information.language);
        this._writeInfoDate(infoDict, 'CreationDate', information.creationDate);
        this._writeInfoDate(infoDict, 'ModDate', information.modificationDate);
        if (information.customMetadata) {
            var map = information.customMetadata._customData;
            var schemaMap_1;
            if (this._xmpMetadata) {
                schemaMap_1 = this._xmpMetadata.customSchema.customData;
            }
            map.forEach(function (value, key) {
                if (typeof key === 'string' && typeof value === 'string') {
                    _this._writeInfoString(infoDict, key, value);
                }
                if (_this._xmpMetadata) {
                    if (!schemaMap_1.has(key)) {
                        schemaMap_1.set(key, value);
                    }
                }
            });
            if (this._xmpMetadata) {
                this._xmpMetadata.customSchema.customData = schemaMap_1;
            }
        }
        infoDict._updated = true;
    };
    /**
     * Writes a string value into the document information dictionary.
     *
     * @private
     * @param {_PdfDictionary} dict Target dictionary.
     * @param {string} key Info key to update.
     * @param {string} [value] String value to write if defined.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._writeInfoString = function (dict, key, value) {
        if (value !== null && typeof value === 'string') {
            dict.update(key, value);
        }
    };
    /**
     * Writes a date value into the document information dictionary.
     *
     * @private
     * @param {_PdfDictionary} dict Target dictionary.
     * @param {string} key Info key to update.
     * @param {Date} [value] Date value to write if provided.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._writeInfoDate = function (dict, key, value) {
        if (value && value instanceof Date) {
            dict.update(key, _convertDateToString(value));
        }
    };
    PdfDocument.prototype._getInfoDictionary = function (createIfMissing) {
        var trailer;
        if (this._crossReference && this._crossReference._trailer) {
            trailer = this._crossReference._trailer;
        }
        if (!trailer) {
            return undefined;
        }
        if (trailer.has('Info')) {
            var raw = trailer.get('Info'); // eslint-disable-line
            if (raw instanceof _PdfReference) {
                var dict = this._crossReference._fetch(raw);
                return dict;
            }
            else if (raw instanceof _PdfDictionary) {
                return raw;
            }
        }
        if (!createIfMissing) {
            return undefined;
        }
        var info = new _PdfDictionary(this._crossReference);
        var infoRef = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(infoRef, info);
        info.objId = infoRef.toString();
        trailer.update('Info', infoRef);
        return info;
    };
    /**
     * Validates a page index against the current page count.
     *
     * @private
     * @param {number} index Zero-based page index to validate.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._checkPageNumber = function (index) {
        if (index < 0 || index > this.pageCount) {
            throw new Error('Index out of range');
        }
    };
    /**
     * Rebuilds the pages cache after insertion or removal and updates page indices.
     *
     * @private
     * @param {number} index The index at which pages were inserted or removed.
     * @param {boolean} [isIncrement=true] Set to `true` when inserting; set to `false` when removing.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._updatePageCache = function (index, isIncrement) {
        if (isIncrement === void 0) { isIncrement = true; }
        var updatedData = new Map();
        for (var i = this.pageCount - 1; i >= 0; i--) {
            var page = this.getPage(i);
            if (isIncrement) {
                if (i >= index) {
                    updatedData.set(i + 1, page);
                    page._pageIndex = i + 1;
                }
                else {
                    updatedData.set(i, page);
                }
            }
            else {
                if (i > index) {
                    updatedData.set(i - 1, page);
                    page._pageIndex = i - 1;
                }
                else if (i !== index) {
                    updatedData.set(i, page);
                }
            }
        }
        this._pages = updatedData;
        if (!isIncrement) {
            this._pageCount = this._pages.size;
        }
    };
    /**
     * Removes the specified page and updates bookmarks, templates, form fields, and page tree.
     *
     * @private
     * @param {PdfPage} pageToRemove The page to remove from the document.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._removePage = function (pageToRemove) {
        var bookMarkMap = this._parseBookmarkDestination();
        if (bookMarkMap && bookMarkMap.has(pageToRemove)) {
            var bookmarks = bookMarkMap.get(pageToRemove);
            if (bookmarks) {
                bookmarks.forEach(function (bookmark) {
                    if (bookmark && bookmark._dictionary) {
                        if (bookmark._dictionary) {
                            if (bookmark._dictionary.has('A')) {
                                bookmark._dictionary.update('A', null);
                            }
                            bookmark._dictionary.update('Dest', null);
                        }
                    }
                });
            }
        }
        this._removePageTemplates(pageToRemove);
        for (var i = this.form.count - 1; i >= 0; --i) {
            var field = this.form.fieldAt(i);
            if (field && field.page === pageToRemove) {
                this.form.removeFieldAt(i);
            }
        }
        this._updatePageCache(pageToRemove._pageIndex, false);
        this._removeParent(pageToRemove._ref, pageToRemove._pageDictionary);
        if (this._crossReference._cacheMap.has(pageToRemove._ref)) {
            pageToRemove._pageDictionary._updated = false;
        }
        if (this.pageCount === 0) {
            this._catalog._topPagesDictionary.update('Kids', []);
        }
    };
    /**
     * Removes a page reference from its parents Kids array and updates page counts accordingly.
     *
     * @private
     * @param {_PdfReference} referenceToRemove The page indirect reference to remove.
     * @param {_PdfDictionary} dictionary The page dictionary whose parent will be updated.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._removeParent = function (referenceToRemove, dictionary) {
        if (dictionary.has('Parent')) {
            var parentReference = dictionary._get('Parent');
            var parentDictionary = this._crossReference._fetch(parentReference);
            if (parentDictionary && parentDictionary.has('Kids')) {
                var kids = parentDictionary.get('Kids');
                if (_isNullOrUndefined(kids) && kids.length === 1 && parentDictionary && parentDictionary.get('Type').name === 'Pages') {
                    this._removeParent(parentReference, parentDictionary);
                }
                else {
                    kids = kids.filter(function (item) { return item !== referenceToRemove; });
                    parentDictionary.update('Kids', kids);
                    _updatePageCount(parentDictionary, -1);
                }
            }
        }
    };
    /**
     * Builds and returns a map of pages to the bookmarks that reference them.
     *
     * @private
     * @returns {Map<PdfPage, PdfBookmarkBase[]>} A map of pages to associated bookmark nodes.
     */
    PdfDocument.prototype._parseBookmarkDestination = function () {
        var current = this.bookmarks;
        if (typeof this._bookmarkHashTable === 'undefined' && current) {
            this._bookmarkHashTable = new Map();
            var stack = [];
            var nodeInformation = { index: 0, kids: current._bookMarkList };
            do {
                for (; nodeInformation.index < nodeInformation.kids.length;) {
                    current = nodeInformation.kids[nodeInformation.index];
                    var namedDestination = current.namedDestination;
                    if (namedDestination) {
                        if (namedDestination.destination) {
                            var page = namedDestination.destination.page;
                            var list = this._bookmarkHashTable.get(page);
                            if (!list) {
                                list = [];
                            }
                            list.push(current);
                            this._bookmarkHashTable.set(page, list);
                        }
                    }
                    else {
                        var destination = current.destination;
                        if (destination) {
                            var page = destination.page;
                            var list = this._bookmarkHashTable.get(page);
                            if (!list) {
                                list = [];
                            }
                            list.push(current);
                            this._bookmarkHashTable.set(page, list);
                        }
                    }
                    nodeInformation.index += 1;
                    if (current.count > 0) {
                        stack.push(nodeInformation);
                        nodeInformation = { index: 0, kids: current._bookMarkList };
                        continue;
                    }
                }
                if (stack.length > 0) {
                    nodeInformation = stack.pop();
                    while (nodeInformation.index === nodeInformation.kids.length && stack.length > 0) {
                        nodeInformation = stack.pop();
                    }
                }
            } while (nodeInformation.index < nodeInformation.kids.length);
        }
        return this._bookmarkHashTable;
    };
    /**
     * Removes template/name entries associated with the specified page from the names dictionary.
     *
     * @private
     * @param {PdfPage} page The page whose template/name entries should be removed.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._removePageTemplates = function (page) {
        var dictionary;
        if (this._catalog._catalogDictionary.has('Names')) {
            dictionary = this._catalog._catalogDictionary.get('Names');
            if (dictionary) {
                this._removeInternalTemplates(dictionary, 'Pages', page);
                this._removeInternalTemplates(dictionary, 'Templates', page);
            }
        }
    };
    /**
     * Removes entries from a particular names tree (by key) that reference the specified page.
     *
     * @private
     * @param {_PdfDictionary} dictionary The root names dictionary.
     * @param {string} key The names tree key to update (for example, 'Pages' or 'Templates').
     * @param {PdfPage} page The page used to filter out entries.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._removeInternalTemplates = function (dictionary, key, page) {
        if (dictionary.has(key)) {
            var namedObject = dictionary.get(key);
            if (namedObject && namedObject.has('Names')) {
                var nameCollection = namedObject.getArray('Names');
                if (nameCollection && nameCollection.length > 0) {
                    var namedPageCollection = this._getUpdatedPageTemplates(nameCollection, page);
                    var namedPageDictionary = new _PdfDictionary(this._crossReference);
                    namedPageDictionary.update('Names', namedPageCollection);
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, namedPageDictionary);
                    namedPageDictionary.objId = reference.toString();
                    dictionary.update(key, reference);
                }
            }
        }
    };
    /**
     * Returns a filtered Names array with entries for the specified page removed.
     *
     * @private
     * @param {_PdfDictionary[]} namedPages The original Names array entries.
     * @param {PdfPage} page The page whose entries should be removed.
     * @returns {_PdfDictionary[]} The updated Names array without the specified page entries.
     */
    PdfDocument.prototype._getUpdatedPageTemplates = function (namedPages, page) {
        if (namedPages.length > 0) {
            for (var i = 1; i <= namedPages.length; i = i + 2) {
                var pageDictionary = namedPages[i];
                if (pageDictionary && page._pageDictionary === pageDictionary) {
                    namedPages.pop();
                    namedPages.pop();
                    return namedPages;
                }
            }
        }
        return namedPages;
    };
    /**
     * Reorders the pages in the PDF document.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Reorders the pages in the PDF document
     * document.reorderPages([3, 2, 1]);
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {number[]} orderArray The page sequence to arrange the pages.
     * @returns {void} Nothing.
     */
    PdfDocument.prototype.reorderPages = function (orderArray) {
        var _this = this;
        orderArray.forEach(function (pageNumber) {
            _this._checkPageNumber(pageNumber);
        });
        var sortedArray = this._sortedArray(orderArray);
        var ascendingOrder = orderArray.slice().sort(function (a, b) { return a - b; });
        var inputArray = Array.from({ length: this.pageCount }, function (_, i) { return i; });
        var pagesToRemove = inputArray.filter(function (element) { return sortedArray.indexOf(element) === -1; });
        for (var i = pagesToRemove.length - 1; i >= 0; i--) {
            this.removePage(pagesToRemove[i]);
        }
        var newkids = [];
        var newPages = new Map();
        var parentReference = this._catalog._catalogDictionary._get('Pages');
        sortedArray.forEach(function (sortedItem, i) {
            var indexPage = _this.getPage(ascendingOrder.indexOf(sortedItem));
            indexPage._pageIndex = i;
            newPages.set(i, indexPage);
            var sectionDictionary = new _PdfDictionary(_this._crossReference);
            sectionDictionary.update('Type', _PdfName.get('Pages'));
            sectionDictionary.update('Count', 1);
            sectionDictionary.update('Parent', parentReference);
            var sectionReference = _this._crossReference._getNextReference();
            sectionDictionary.objId = sectionReference.toString();
            sectionDictionary.update('Kids', [indexPage._ref]);
            newkids.push(sectionReference);
            var parentDictionary = indexPage._pageDictionary.get('Parent');
            while (parentDictionary && parentDictionary.get('Type').name === 'Pages') {
                parentDictionary.forEach(function (key, value) {
                    switch (key) {
                        case 'Parent':
                        case 'Kids':
                        case 'Type':
                        case 'Count':
                            break;
                        case 'Resources':
                            _this._cloneResources(parentDictionary.get('Resources'), sectionDictionary);
                            break;
                        default:
                            if (!sectionDictionary.has(key)) {
                                sectionDictionary.update(key, value);
                            }
                            break;
                    }
                });
                if (parentDictionary.has('Parent')) {
                    parentDictionary = parentDictionary.get('Parent');
                }
                else {
                    break;
                }
            }
            _this._crossReference._cacheMap.set(sectionReference, sectionDictionary);
            var pageSection = _this._crossReference._fetch(indexPage._ref);
            pageSection.update('Parent', sectionReference);
        });
        this._pages = newPages;
        if (this._catalog) {
            var parentDictionary = this._catalog._topPagesDictionary;
            if (parentDictionary && parentDictionary.has('Kids')) {
                var kids = parentDictionary.get('Kids');
                kids = newkids;
                parentDictionary.update('Kids', kids);
            }
        }
    };
    /**
     * Returns a distinct array preserving the first occurrence order.
     *
     * @private
     * @param {number[]} order Array of page indexes to deduplicate.
     * @returns {number[]} The deduplicated array in original order.
     */
    PdfDocument.prototype._sortedArray = function (order) {
        var sortedArray = [];
        order.forEach(function (num) {
            if (sortedArray.indexOf(num) === -1) {
                sortedArray.push(num);
            }
        });
        return sortedArray;
    };
    /**
     * Clones resource dictionaries from source to target, merging entries where appropriate.
     *
     * @private
     * @param {_PdfDictionary} source Source resource dictionary.
     * @param {_PdfDictionary} target Target page/section dictionary to receive merged resources.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._cloneResources = function (source, target) {
        var _this = this;
        if (!target.has('Resources')) {
            target.update('Resources', source);
        }
        else {
            var resourceDictionary_1 = target.get('Resources');
            source.forEach(function (key, value) {
                if (resourceDictionary_1.has(key)) {
                    _this._cloneInnerResources(key, value, resourceDictionary_1);
                }
                else {
                    resourceDictionary_1.update(key, value);
                }
            });
        }
    };
    /**
     * Merges nested resource entries (dictionaries or arrays) into a target resource dictionary.
     *
     * @private
     * @param {string} key Resource key to merge.
     * @param {any} value Incoming resource value (dictionary or array).
     * @param {_PdfDictionary} resourceDictionary Target resource dictionary to update.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._cloneInnerResources = function (key, value, resourceDictionary) {
        if (value instanceof _PdfDictionary) {
            var oldObject_1 = resourceDictionary.get(key);
            if (oldObject_1) {
                var hasNew_1 = false;
                oldObject_1.forEach(function (innerKey, innerValue) {
                    if (!oldObject_1.has(innerKey)) {
                        oldObject_1.update(innerKey, innerValue);
                        hasNew_1 = true;
                    }
                });
                if (hasNew_1) {
                    resourceDictionary._updated = true;
                }
            }
            else {
                resourceDictionary.update(key, value);
            }
        }
        else if (Array.isArray(value)) {
            var oldArray_1 = resourceDictionary.get(key); // eslint-disable-line
            if (oldArray_1) {
                var hasNew_2 = false;
                value.forEach(function (entry) {
                    if (oldArray_1.indexOf(entry) === -1) {
                        oldArray_1.push(entry);
                        hasNew_2 = true;
                    }
                });
                if (hasNew_2) {
                    resourceDictionary._updated = true;
                }
            }
            else {
                resourceDictionary.update(key, value);
            }
        }
    };
    PdfDocument.prototype.save = function (filename) {
        if (!this._isLoaded && this.pageCount === 0) {
            this.addSection().addPage();
        }
        this._doPostProcess(this._flatten);
        if (!validateLicense('pdf')) {
            this._addWatermarkText();
        }
        if (typeof filename === 'string') {
            Save.save(filename, new Blob([this._crossReference._save()], { type: 'application/pdf' }));
        }
        else {
            return this._crossReference._save();
        }
    };
    PdfDocument.prototype.saveAsync = function (filename) {
        return __awaiter(this, void 0, void 0, function () {
            var pdfBytes;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!this._isLoaded && this.pageCount === 0) {
                            this.addSection().addPage();
                        }
                        return [4 /*yield*/, Promise.resolve(this._doPostProcess(this._flatten))];
                    case 1:
                        _a.sent();
                        if (!(typeof filename === 'string')) return [3 /*break*/, 4];
                        return [4 /*yield*/, this._crossReference._saveAsync()];
                    case 2:
                        pdfBytes = _a.sent();
                        return [4 /*yield*/, Promise.resolve(Save.save(filename, new Blob([pdfBytes], { type: 'application/pdf' })))];
                    case 3:
                        _a.sent();
                        return [3 /*break*/, 6];
                    case 4: return [4 /*yield*/, this._crossReference._saveAsync()];
                    case 5: return [2 /*return*/, _a.sent()];
                    case 6: return [2 /*return*/];
                }
            });
        });
    };
    /**
     * Saves the document to the specified output stream and return the stream as Blob.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * // Save the document
     * let data: Promise<{ blobData: Blob }> = document.saveAsBlob();
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @returns {Promise<{ blobData: Blob }>} Saved PDF data as `Blob`.
     */
    PdfDocument.prototype.saveAsBlob = function () {
        var _this = this;
        return new Promise(function (resolve) {
            var obj = { blobData: new Blob([_this._crossReference._save()], { type: 'application/pdf' }) };
            resolve(obj);
        });
    };
    PdfDocument.prototype.exportAnnotations = function (arg1, arg2) {
        initializeTelemetryFeature('Annotation', 'PDFLibrary');
        this._isExport = true;
        this._doPostProcessOnAnnotations();
        var helper;
        var settings;
        if (arg1 && arg1 instanceof PdfAnnotationExportSettings) {
            settings = arg1;
        }
        else if (arg2 && arg2 instanceof PdfAnnotationExportSettings) {
            settings = arg2;
        }
        if (settings) {
            if (settings.dataFormat === DataFormat.xfdf) {
                helper = new _XfdfDocument();
            }
            else if (settings.dataFormat === DataFormat.json) {
                helper = new _JsonDocument();
            }
            else if (settings.dataFormat === DataFormat.fdf) {
                helper = new _FdfDocument();
            }
            else {
                return undefined;
            }
            helper.exportAppearance = settings.exportAppearance;
        }
        else {
            helper = new _XfdfDocument();
        }
        var result = helper._exportAnnotations(this);
        if (arg1 && typeof arg1 === 'string') {
            Save.save(arg1, new Blob([result], { type: 'text/plain' }));
        }
        else {
            return result;
        }
    };
    PdfDocument.prototype.exportFormData = function (arg1, arg2) {
        initializeTelemetryFeature('AcroForm', 'PDFLibrary');
        this._doPostProcessOnFormFields();
        var helper;
        var settings;
        if (arg1 && arg1 instanceof PdfFormFieldExportSettings) {
            settings = arg1;
        }
        else if (arg2 && arg2 instanceof PdfFormFieldExportSettings) {
            settings = arg2;
        }
        if (settings) {
            if (settings.dataFormat === DataFormat.xfdf) {
                helper = new _XfdfDocument(settings.exportName);
            }
            else if (settings.dataFormat === DataFormat.json) {
                helper = new _JsonDocument(settings.exportName);
            }
            else if (settings.dataFormat === DataFormat.fdf) {
                helper = new _FdfDocument(settings.exportName);
            }
            else if (settings.dataFormat === DataFormat.xml) {
                helper = new _XmlDocument(settings.exportName);
            }
            else {
                return undefined;
            }
            helper._asPerSpecification = settings.asPerSpecification;
        }
        else {
            helper = new _XfdfDocument();
            helper._asPerSpecification = false;
        }
        if (arg1 && typeof arg1 === 'string') {
            Save.save(arg1, new Blob([helper._exportFormFields(this)], { type: 'text/plain' }));
        }
        else {
            return helper._exportFormFields(this);
        }
    };
    PdfDocument.prototype.importAnnotations = function (data, dataFormat) {
        initializeTelemetryFeature('Annotation', 'PDFLibrary');
        if (dataFormat === DataFormat.xfdf) {
            var xfdf = new _XfdfDocument();
            xfdf._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
        }
        else if (dataFormat === DataFormat.json) {
            var json = new _JsonDocument();
            json._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
        }
        else if (dataFormat === DataFormat.fdf) {
            var fdf = new _FdfDocument();
            fdf._importAnnotations(this, (typeof data === 'string') ? _decode(data) : data);
        }
    };
    PdfDocument.prototype.importFormData = function (data, dataFormat) {
        initializeTelemetryFeature('AcroForm', 'PDFLibrary');
        if (this._form && this._form._requiresPostProcessing) {
            this._doPostProcessOnFormFields();
        }
        this._isFormImport = true;
        if (this.form.count > 0) {
            if (dataFormat === DataFormat.xfdf) {
                var xfdf = new _XfdfDocument();
                xfdf._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
            }
            else if (dataFormat === DataFormat.json) {
                var json = new _JsonDocument();
                json._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
            }
            else if (dataFormat === DataFormat.fdf) {
                var fdf = new _FdfDocument();
                fdf._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
            }
            else if (dataFormat === DataFormat.xml) {
                var xml = new _XmlDocument();
                xml._importFormData(this, (typeof data === 'string') ? _decode(data) : data);
            }
        }
    };
    /**
     * Disposes the current instance of `PdfDocument` class.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @returns {void} Nothing.
     */
    PdfDocument.prototype.destroy = function () {
        if (this._crossReference) {
            this._crossReference._destroy();
            this._crossReference = undefined;
        }
        if (this._xmpMetadata) {
            this._xmpMetadata._destroy();
        }
        if (this._catalog) {
            this._catalog._destroy();
            this._catalog = undefined;
        }
        this._endObjSignature = undefined;
        this._headerSignature = undefined;
        if (this._pages && this._pages.size > 0) {
            this._pages.forEach(function (value) {
                value._destroy();
            });
        }
        if (this._pages) {
            this._pages.clear();
            this._pages = undefined;
        }
        this._startXrefSignature = undefined;
        this._stream = undefined;
        if (this._form) {
            this._form._fontCache = undefined;
            this._form = undefined;
        }
        this._fontCollection.clear();
        _clearPrimitiveCaches();
        if (this._mergeHelperCache) {
            if (this._mergeHelperCache.size > 0) {
                this._mergeHelperCache.forEach(function (value) {
                    if (value) {
                        value._objectDispose();
                    }
                });
            }
            this._mergeHelperCache.clear();
            this._mergeHelperCache = undefined;
        }
    };
    Object.defineProperty(PdfDocument.prototype, "_destinationCollection", {
        /**
         * Lazily retrieves the named destination collection from the document catalog.
         *
         * @private
         * @returns {_PdfNamedDestinationCollection} The named destination collection.
         */
        get: function () {
            if (this._namedDestinationCollection === null || typeof this._namedDestinationCollection === 'undefined') {
                if (this._catalog._catalogDictionary.has('Names')) {
                    var names = this._catalog._catalogDictionary.get('Names');
                    this._namedDestinationCollection = new _PdfNamedDestinationCollection(names, this._crossReference);
                }
                else {
                    this._namedDestinationCollection = new _PdfNamedDestinationCollection();
                }
            }
            return this._namedDestinationCollection;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Retrieves the linearization page dictionary and reference for the given page index.
     *
     * @private
     * @param {number} pageIndex - The zero-based index of the page to retrieve.
     * @returns {{dictionary: _PdfDictionary, reference: _PdfReference}} returns reference .
     */
    PdfDocument.prototype._getLinearizationPage = function (pageIndex) {
        var _a = this, _catalog = _a._catalog, _linearization = _a._linearization, _crossReference = _a._crossReference;
        var ref = _PdfReference.get(_linearization.objectNumberFirst, 0);
        try {
            var obj = _crossReference._fetch(ref); // eslint-disable-line
            if (obj instanceof _PdfDictionary) {
                var type = obj.get('Type');
                if (_isName(type, 'Page') || (!obj.has('Type') && !obj.has('Kids'))) {
                    if (!_catalog.pageKidsCountCache.has(ref)) {
                        _catalog.pageKidsCountCache.put(ref, 1);
                    }
                    if (!_catalog.pageIndexCache.has(ref)) {
                        _catalog.pageIndexCache.put(ref, 0);
                    }
                    return { dictionary: obj, reference: ref };
                }
            }
            throw new FormatError('The Linearization dictionary does not point to a valid Page dictionary.');
        }
        catch (reason) {
            return _catalog._getPageDictionary(pageIndex);
        }
    };
    /**
     * Validates and reads the document header to determine the PDF version and update file structure.
     *
     * @private
     * @returns {void} nothing.
     */
    PdfDocument.prototype._checkHeader = function () {
        var stream = this._stream;
        stream.reset();
        if (!this._find(stream, this._headerSignature)) {
            return;
        }
        stream.moveStart();
        var version = '';
        var ch = stream.getByte();
        while (ch > 0x20) {
            if (version.length >= 12) {
                break;
            }
            version += String.fromCharCode(ch);
            ch = stream.getByte();
        }
        if (!this._version) {
            this._version = version.substring(5);
            // if (this._version === '%PDF-1.3' || this._version === '%PDF-1.0' || this._version === '%PDF-1.1'
            //     || this._version === '%PDF-1.2') {
            //     this.fileStructure.isIncrementalUpdate = false;
            // }
        }
    };
    /**
     * Parses cross-reference sections and builds the catalog.
     *
     * @private
     * @param {boolean} recoveryMode Set `true` to enable fallback parsing strategies.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._parse = function (recoveryMode) {
        this._crossReference._parse(recoveryMode);
        this._catalog = new _PdfCatalog(this._crossReference);
        if (this._catalog.version) {
            this._version = this._catalog.version;
        }
    };
    /**
     * Searches the given stream for a signature within a byte limit.
     *
     * @private
     * @param {_PdfStream} stream The stream to scan.
     * @param {Uint8Array} signature The byte signature to locate.
     * @param {number} [limit=1024] Max number of bytes to scan.
     * @param {boolean} [backwards=false] If `true`, scans from the end backwards.
     * @returns {boolean} `true` if the signature is found; otherwise, `false`.
     */
    PdfDocument.prototype._find = function (stream, signature, limit, backwards) {
        if (limit === void 0) { limit = 1024; }
        if (backwards === void 0) { backwards = false; }
        var signatureLength = signature.length;
        var scanBytes = stream.peekBytes(limit);
        var scanLength = scanBytes.length - signatureLength;
        if (scanLength <= 0) {
            return false;
        }
        if (backwards) {
            var signatureEnd = signatureLength - 1;
            var position = scanBytes.length - 1;
            while (position >= signatureEnd) {
                var j = 0;
                while (j < signatureLength && scanBytes[position - j] === signature[signatureEnd - j]) {
                    j++;
                }
                if (j >= signatureLength) {
                    stream.position += position - signatureEnd;
                    return true;
                }
                position--;
            }
        }
        else {
            var position = 0;
            while (position <= scanLength) {
                var j = 0;
                while (j < signatureLength && scanBytes[position + j] === signature[j]) { // eslint-disable-line
                    j++;
                }
                if (j >= signatureLength) {
                    stream.position += position;
                    return true;
                }
                position++;
            }
        }
        return false;
    };
    /**
     * Performs post-processing for forms and annotations, optionally flattening them.
     *
     * @private
     * @param {boolean} [isFlatten=false] Set `true` to flatten annotations and form fields.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        this._renderDocumentTemplates(PdfTemplateLayerMode.background);
        this._renderDocumentTemplates(undefined);
        this._doPostProcessOnFormFields(isFlatten);
        this._doPostProcessOnAnnotations(isFlatten);
        this._addXmpMetadata();
        this._renderDocumentTemplates(PdfTemplateLayerMode.foreground);
    };
    /**
     * Adds XMP metadata stream to the PDF document catalog.
     *
     * @private
     * @returns {void} nothing.
     */
    PdfDocument.prototype._addXmpMetadata = function () {
        if (this._xmpMetadata && !this._xmpMetadata._isUpdated) {
            this._xmpMetadata._serializeToStream();
            var xmpStream = this._xmpMetadata._xmpStream;
            if (xmpStream) {
                if (!xmpStream.dictionary) {
                    var dict = new _PdfDictionary(this._crossReference);
                    dict._updated = true;
                    xmpStream.dictionary = dict;
                }
                xmpStream.dictionary.update('Type', _PdfName.get('Metadata'));
                xmpStream.dictionary.update('Subtype', _PdfName.get('XML'));
                xmpStream._isCompress = false;
                var reference = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference, xmpStream);
                this._catalog._catalogDictionary.update('Metadata', reference);
                this._crossReference._allowCatalog = true;
                this._xmpMetadata._isUpdated = true;
            }
        }
    };
    /**
     * Renders document templates (headers/footers) onto all pages for the specified layer mode.
     *
     * @private
     * @param {PdfTemplateLayerMode} mode The template layer mode to render (background|foreground|undefined for default).
     * @returns {void} Nothing.
     */
    PdfDocument.prototype._renderDocumentTemplates = function (mode) {
        var hasTemplate = typeof this._template !== 'undefined' && this._template !== null;
        if (!hasTemplate && this._sections) {
            for (var _i = 0, _a = this._sections; _i < _a.length; _i++) {
                var section = _a[_i];
                if (section.template) {
                    hasTemplate = true;
                    break;
                }
            }
        }
        if (!hasTemplate) {
            return;
        }
        for (var i = 0; i < this.pageCount; i++) {
            var page = this.getPage(i);
            var pageNumber = i + 1;
            var isOddPage = pageNumber % 2 === 1;
            this._renderPageTemplates(page, isOddPage, mode);
        }
    };
    /**
     * Renders templates for a specific page based on odd/even precedence.
     *
     * @private
     * @param {PdfPage} page The page to render templates on.
     * @param {boolean} isOddPage Whether the page is odd-numbered.
     * @param {PdfTemplateLayerMode | undefined} mode The template layer mode to render (background|foreground|undefined for default).
     * @returns {void} Nothing.
     */
    PdfDocument.prototype._renderPageTemplates = function (page, isOddPage, mode) {
        this._templateRenderingStarted = true;
        var sectionIndex = page._getSectionIndex();
        var sides = [
            _TemplateSide.top,
            _TemplateSide.bottom,
            _TemplateSide.left,
            _TemplateSide.right
        ];
        var pageGraphics;
        for (var _i = 0, sides_1 = sides; _i < sides_1.length; _i++) {
            var side = sides_1[_i];
            var templateInserted = false;
            var isLateGraphics = typeof page._g !== 'undefined' && page._g !== null && !page._needInitializeGraphics; // eslint-disable-line
            var sectionTemplateInfo = (sectionIndex >= 0 && sectionIndex < this._sections.length)
                ? this._getSectionTemplateForSide(this._sections[sectionIndex], side, isOddPage)
                : null;
            var documentTemplateInfo = this._getTemplateForSide(side, isOddPage); // eslint-disable-line
            var templatesToRender = []; // eslint-disable-line
            if (documentTemplateInfo && documentTemplateInfo.template) {
                templatesToRender.push(documentTemplateInfo);
            }
            if (sectionTemplateInfo && sectionTemplateInfo.template) {
                templatesToRender.push(sectionTemplateInfo);
            }
            for (var _a = 0, templatesToRender_1 = templatesToRender; _a < templatesToRender_1.length; _a++) {
                var templateInfo = templatesToRender_1[_a];
                if (!templateInfo || !templateInfo.template) {
                    continue;
                }
                var templateMode = templateInfo.templateLayerMode;
                var matchesMode = (typeof templateMode !== 'undefined' && templateMode === mode) ||
                    (typeof templateMode === 'undefined' && mode === undefined);
                if (!matchesMode) {
                    continue;
                }
                var position = this._getTemplateAlignmentPosition(page, templateInfo.documentTemplate, templateInfo.alignment, side, isOddPage);
                var direction = void 0;
                if (typeof templateInfo.alignment === 'undefined') {
                    direction = this._templateSideToString(side);
                }
                var fixNeeded = isLateGraphics && page._accessedBeforeTemplate &&
                    !page._templatesRendered;
                if (templateMode === PdfTemplateLayerMode.background) {
                    var bgLayer = this._backgroundLayers.get(page);
                    if (!bgLayer) {
                        bgLayer = this.layers.add('_background');
                        this.layers.move(0, bgLayer);
                        this._backgroundLayers.set(page, bgLayer);
                    }
                    var bgGraphics = bgLayer.createGraphics(page);
                    var state = bgGraphics.save();
                    bgGraphics.setTransparency(0.5);
                    templateInfo.template._draw(bgGraphics, position.x, position.y, position.width, position.height, direction);
                    bgGraphics.restore(state);
                }
                else if (templateMode === PdfTemplateLayerMode.foreground) {
                    if (!page._contents || page._contents.length === 0) {
                        page.graphics.save();
                        page.graphics.restore();
                    }
                    this._drawForegroundTemplate(page, templateInfo.template._template, position);
                }
                else {
                    if (fixNeeded && !templateInserted) {
                        page._templatesRendered = true;
                        templateInserted = true;
                        page._loadContents();
                        if (page._contents && page._contents.length > 0) {
                            var tempStream = new _PdfContentStream([]);
                            var g = new PdfGraphics(page.size, tempStream, this._crossReference, page);
                            g._initializeCoordinates();
                            var margins = page._pageSettings.margins;
                            var bounds = [margins.left, margins.top,
                                page.size.width - margins.left - margins.right,
                                page.size.height - margins.top - margins.bottom
                            ];
                            g._clipTranslateMargins(bounds);
                            g.translateTransform({ x: position.x, y: 0 });
                            templateInfo.template._draw(g, 0, 0, position.width, position.height, direction);
                            tempStream._bytes = [32, 113, 32, 10].concat(tempStream._bytes, [32, 81, 32, 10]);
                            var ref = this._crossReference._getNextReference();
                            this._crossReference._cacheMap.set(ref, tempStream);
                            var insertIndex = page._contents.length - 1;
                            page._contents.splice(insertIndex, 0, ref);
                            page._pageDictionary.set('Contents', page._contents);
                            page._pageDictionary._updated = true;
                        }
                    }
                    else {
                        if (!pageGraphics) {
                            pageGraphics = page.graphics;
                        }
                        templateInfo.template._draw(pageGraphics, position.x, position.y, position.width, position.height, direction);
                    }
                }
            }
        }
    };
    /**
     * Gets the index of the section that contains the specified page reference.
     *
     * @param {_PdfReference} parentRef - The reference of the page's parent section.
     * @returns {number} The zero-based index of the matching section, or -1 if not found.
     * @private
     */
    PdfDocument.prototype._getSectionIndexByPage = function (parentRef) {
        if (!this._sections || this._sections.length === 0) {
            return -1;
        }
        for (var i = 0; i < this._sections.length; i++) {
            var section = this._sections[i];
            if (section && section._reference === parentRef) {
                return i;
            }
        }
        return -1;
    };
    /**
     * Renders a `PdfTemplate` into the page contents as a form XObject (foreground).
     * This method creates a content stream that places and scales the template
     * to the provided `bounds`, registers the template as an XObject resource,
     * and appends the resulting content stream to the page contents.
     *
     * @private
     * @param {PdfPage} page The target page to draw the template onto.
     * @param {PdfTemplate} template The template to render as an XObject.
     * @param {Rectangle} bounds The bounds on the page where the template should be drawn.
     * @returns {void} Nothing.
     */
    PdfDocument.prototype._drawForegroundTemplate = function (page, template, bounds) {
        var stream = new _PdfContentStream([]);
        var sw = new _PdfStreamWriter(stream);
        sw._write('q');
        var matrix = new _PdfTransformationMatrix();
        matrix._translate(bounds.x, -(bounds.y + bounds.height));
        matrix._scale(bounds.width / template._size.width, bounds.height / template._size.height);
        sw._modifyCtm(matrix);
        var pageResources = page._pageDictionary.get('Resources');
        if (!pageResources) {
            pageResources = new _PdfDictionary(this._crossReference);
            page._pageDictionary.set('Resources', pageResources);
        }
        stream.dictionary.update('Resources', pageResources);
        var xObject = pageResources.get('XObject');
        if (!xObject) {
            xObject = new _PdfDictionary(this._crossReference);
            pageResources.set('XObject', xObject);
        }
        if (!template._key) {
            template._key = _getNewGuidString();
        }
        var key = _PdfName.get(template._key);
        var ref = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(ref, template._content);
        xObject.set(key.name, ref);
        sw._executeObject(key);
        sw._write('Q');
        page._loadContents();
        var cref = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(cref, stream);
        page._contents.push(cref);
    };
    /**
     * Gets the appropriate template and alignment for the specified side based on odd or even page.
     *
     * @private
     * @param {_TemplateSide} side The template side (top, bottom, left, or right).
     * @param {boolean} isOddPage Whether the current page is odd-numbered.
     * @param {number} sectionIndex The section index to resolve section-specific templates or -1 if not applicable.
     * @returns {Object} The resolved template information, template layer mode and alignment, or null if none is found.
     */
    PdfDocument.prototype._getTemplateForSide = function (side, isOddPage, sectionIndex) {
        if (sectionIndex === void 0) { sectionIndex = -1; }
        var templateKeyMap = new Map([
            [_TemplateSide.top, {
                    odd: _PdfDocumentTemplateKey.oddTop,
                    even: _PdfDocumentTemplateKey.evenTop,
                    base: _PdfDocumentTemplateKey.top
                }],
            [_TemplateSide.bottom, {
                    odd: _PdfDocumentTemplateKey.oddBottom,
                    even: _PdfDocumentTemplateKey.evenBottom,
                    base: _PdfDocumentTemplateKey.bottom
                }],
            [_TemplateSide.left, {
                    odd: _PdfDocumentTemplateKey.oddLeft,
                    even: _PdfDocumentTemplateKey.evenLeft,
                    base: _PdfDocumentTemplateKey.left
                }],
            [_TemplateSide.right, {
                    odd: _PdfDocumentTemplateKey.oddRight,
                    even: _PdfDocumentTemplateKey.evenRight,
                    base: _PdfDocumentTemplateKey.right
                }]
        ]);
        var keys = templateKeyMap.get(side); // eslint-disable-line
        if (!keys) {
            return null;
        }
        if (sectionIndex >= 0 && sectionIndex < this._sections.length) {
            var section = this._sections[sectionIndex];
            var sectionTemplateInfo = this._getSectionTemplateForSide(section, side, isOddPage); // eslint-disable-line
            if (sectionTemplateInfo) {
                return sectionTemplateInfo;
            }
        }
        var templateKeyToCheck = isOddPage ? keys.odd : keys.even; // eslint-disable-line
        var templateObj = this._getTemplateByKey(templateKeyToCheck); // eslint-disable-line
        if (templateObj && templateObj.template) {
            return {
                template: templateObj.template,
                templateLayerMode: templateObj.templateLayerMode,
                alignment: templateObj.alignment,
                documentTemplate: this._template
            };
        }
        var baseTemplateObj = this._getTemplateByKey(keys.base); // eslint-disable-line
        if (baseTemplateObj && baseTemplateObj.template) {
            return {
                template: baseTemplateObj.template,
                templateLayerMode: baseTemplateObj.templateLayerMode,
                alignment: baseTemplateObj.alignment,
                documentTemplate: this._template
            };
        }
        return null;
    };
    /**
     * Retrieves template object by template key.
     *
     * @private
     * @param {_PdfDocumentTemplateKey} key The template key.
     * @returns {any} The template object or undefined.
     */
    PdfDocument.prototype._getTemplateByKey = function (key) {
        if (!this._template) {
            return;
        }
        switch (key) {
            case _PdfDocumentTemplateKey.top:
                return this._template.top;
            case _PdfDocumentTemplateKey.bottom:
                return this._template.bottom;
            case _PdfDocumentTemplateKey.left:
                return this._template.left;
            case _PdfDocumentTemplateKey.right:
                return this._template.right;
            case _PdfDocumentTemplateKey.evenTop:
                return this._template.evenTop;
            case _PdfDocumentTemplateKey.evenBottom:
                return this._template.evenBottom;
            case _PdfDocumentTemplateKey.evenLeft:
                return this._template.evenLeft;
            case _PdfDocumentTemplateKey.evenRight:
                return this._template.evenRight;
            case _PdfDocumentTemplateKey.oddTop:
                return this._template.oddTop;
            case _PdfDocumentTemplateKey.oddBottom:
                return this._template.oddBottom;
            case _PdfDocumentTemplateKey.oddLeft:
                return this._template.oddLeft;
            case _PdfDocumentTemplateKey.oddRight:
                return this._template.oddRight;
            default:
                return undefined;
        }
    };
    /**
     * Gets the appropriate template and alignment for a section.
     *
     * @param {PdfSection} section The section to get the template from.
     * @param {_TemplateSide} side The template side.
     * @param {boolean} isOddPage Whether the page is odd-numbered.
     * @returns {Object} The resolved template info, or null if none is found.
     * @private
     */
    PdfDocument.prototype._getSectionTemplateForSide = function (section, side, isOddPage) {
        var sectionTemplate = section.template; // eslint-disable-line
        var templateKeyMap = new Map([
            [_TemplateSide.top, 'top'],
            [_TemplateSide.bottom, 'bottom'],
            [_TemplateSide.left, 'left'],
            [_TemplateSide.right, 'right']
        ]);
        var baseKey = templateKeyMap.get(side);
        if (!baseKey) {
            return null;
        }
        var cap = baseKey.charAt(0).toUpperCase() + baseKey.slice(1);
        var oddKey = 'odd' + cap;
        var evenKey = 'even' + cap;
        var templateInfo = undefined; // eslint-disable-line
        if (isOddPage && sectionTemplate[oddKey]) {
            templateInfo = sectionTemplate[oddKey];
        }
        else if (!isOddPage && sectionTemplate[evenKey]) {
            templateInfo = sectionTemplate[evenKey];
        }
        if (!templateInfo && sectionTemplate[baseKey]) {
            templateInfo = sectionTemplate[baseKey];
        }
        if (templateInfo && templateInfo.template) {
            return { template: templateInfo.template,
                alignment: templateInfo.alignment,
                templateLayerMode: templateInfo.templateLayerMode,
                documentTemplate: section.template
            };
        }
        return null;
    };
    /**
     * Gets the alignment position for a template on a page.
     *
     * @private
     * @param {PdfPage} page The target page on which the template will be positioned.
     * @param {PdfDocumentTemplate} documentTemplate The document template containing the template elements.
     * @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment | undefined} alignment Specifies the alignment
     * (horizontal or vertical) used to position the template within the page.
     * @param {_TemplateSide} side Specifies the side of the page (such as top, bottom, left, or right)
     * where the template should be placed.
     * @param {boolean} isOddPage Indicates whether the current page is an odd-numbered page,
     * which may affect template placement (e.g., for mirrored layouts).
     * @returns {{ x: number, y: number, width: number, height: number }} An object representing
     * the calculated position (x, y) and dimensions (width, height) of the template.
     */
    PdfDocument.prototype._getTemplateAlignmentPosition = function (page, documentTemplate, alignment, side, isOddPage) {
        var result;
        var baseKey = this._templateSideToString(side);
        var cap = baseKey.charAt(0).toUpperCase() + baseKey.slice(1);
        var oddKey = ('odd' + cap);
        var evenKey = ('even' + cap);
        var base = baseKey;
        var templateObj; // eslint-disable-line
        if (isOddPage && documentTemplate[oddKey]) {
            templateObj = documentTemplate[oddKey];
        }
        else if (!isOddPage && documentTemplate[evenKey]) {
            templateObj = documentTemplate[evenKey];
        }
        else {
            templateObj = documentTemplate[base];
        }
        if (!templateObj) {
            return { x: 0, y: 0, width: 0, height: 0 };
        }
        var template = templateObj.template;
        if (typeof alignment !== 'undefined' && alignment !== PdfTemplateVerticalAlignment.none &&
            alignment !== PdfTemplateHorizontalAlignment.none) {
            result = this._getAlignmentBounds(side, template, page, alignment);
        }
        else {
            var direction = this._templateSideToString(side);
            result = this._getTemplateDockBounds(page, template, direction);
        }
        return result;
    };
    /**
     * Gets alignment bounds for a template.
     *
     * @private
     * @param {_TemplateSide} side The template side.
     * @param {PdfPageTemplateElement} template The template element.
     * @param {PdfPage} page The page.
     * @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment | undefined} alignment The alignment.
     * @returns {Rectangle} The alignment bounds.
     */
    PdfDocument.prototype._getAlignmentBounds = function (side, template, page, alignment) {
        var alignStyle = this._mapTemplateAlignmentStyle(side, alignment);
        return this._getTemplateAlignmentBounds(template, page, alignStyle, side);
    };
    /**
     * Converts template side enum to string for legacy compatibility.
     *
     * @private
     * @param {_TemplateSide} side The template side enum.
     * @returns {string} The side as string ('top', 'bottom', 'left', 'right').
     */
    PdfDocument.prototype._templateSideToString = function (side) {
        switch (side) {
            case _TemplateSide.top:
                return 'top';
            case _TemplateSide.bottom:
                return 'bottom';
            case _TemplateSide.left:
                return 'left';
            case _TemplateSide.right:
                return 'right';
            default:
                return 'top';
        }
    };
    /**
     * Normalizes a document template key or template side into its corresponding
     * base template side (Top, Bottom, Left, or Right).
     *
     * @private
     * @param {_PdfDocumentTemplateKey | _TemplateSide} key
     * The document template key or template side to normalize.
     * @returns {_TemplateSide} The normalized base template side.
     */
    PdfDocument.prototype._normalizeTemplateSide = function (key) {
        if (key === _TemplateSide.top ||
            key === _TemplateSide.bottom ||
            key === _TemplateSide.left ||
            key === _TemplateSide.right) {
            return key;
        }
        switch (key) {
            case _PdfDocumentTemplateKey.top:
            case _PdfDocumentTemplateKey.evenTop:
            case _PdfDocumentTemplateKey.oddTop:
                return _TemplateSide.top;
            case _PdfDocumentTemplateKey.bottom:
            case _PdfDocumentTemplateKey.evenBottom:
            case _PdfDocumentTemplateKey.oddBottom:
                return _TemplateSide.bottom;
            case _PdfDocumentTemplateKey.left:
            case _PdfDocumentTemplateKey.evenLeft:
            case _PdfDocumentTemplateKey.oddLeft:
                return _TemplateSide.left;
            case _PdfDocumentTemplateKey.right:
            case _PdfDocumentTemplateKey.evenRight:
            case _PdfDocumentTemplateKey.oddRight:
            default:
                return _TemplateSide.right;
        }
    };
    /**
     * Resolves the effective template alignment style based on the document template key
     * (including odd/even variants) and the specified horizontal or vertical alignment.
     *
     * @private
     * @param {_PdfDocumentTemplateKey | _TemplateSide} templateKey
     * The document template key or normalized template side used to determine alignment context.
     * @param {PdfTemplateHorizontalAlignment | PdfTemplateVerticalAlignment} alignment
     * The alignment value applied to the template.
     * @returns {_PdfAlignmentStyle} The resolved alignment style for positioning the template.
     */
    PdfDocument.prototype._mapTemplateAlignmentStyle = function (templateKey, alignment) {
        var side = this._normalizeTemplateSide(templateKey);
        if (typeof alignment === 'undefined' ||
            alignment === PdfTemplateHorizontalAlignment.none ||
            alignment === PdfTemplateVerticalAlignment.none) {
            switch (side) {
                case _TemplateSide.top:
                case _TemplateSide.left:
                    return _PdfAlignmentStyle.topLeft;
                case _TemplateSide.bottom:
                    return _PdfAlignmentStyle.bottomLeft;
                case _TemplateSide.right:
                    return _PdfAlignmentStyle.topRight;
            }
        }
        if (side === _TemplateSide.top || side === _TemplateSide.bottom) {
            var isTop = side === _TemplateSide.top;
            switch (alignment) {
                case PdfTemplateHorizontalAlignment.center:
                    return isTop
                        ? _PdfAlignmentStyle.topCenter
                        : _PdfAlignmentStyle.bottomCenter;
                case PdfTemplateHorizontalAlignment.right:
                    return isTop
                        ? _PdfAlignmentStyle.topRight
                        : _PdfAlignmentStyle.bottomRight;
                case PdfTemplateHorizontalAlignment.left:
                default:
                    return isTop
                        ? _PdfAlignmentStyle.topLeft
                        : _PdfAlignmentStyle.bottomLeft;
            }
        }
        if (side === _TemplateSide.left || side === _TemplateSide.right) {
            var isLeft = side === _TemplateSide.left;
            switch (alignment) {
                case PdfTemplateVerticalAlignment.middle:
                    return isLeft
                        ? _PdfAlignmentStyle.middleLeft
                        : _PdfAlignmentStyle.middleRight;
                case PdfTemplateVerticalAlignment.bottom:
                    return isLeft
                        ? _PdfAlignmentStyle.bottomLeft
                        : _PdfAlignmentStyle.bottomRight;
                case PdfTemplateVerticalAlignment.top:
                default:
                    return isLeft
                        ? _PdfAlignmentStyle.topLeft
                        : _PdfAlignmentStyle.topRight;
            }
        }
        return _PdfAlignmentStyle.topLeft;
    };
    /**
     * Gets the template alignment bounds based on alignment style.
     *
     * @private
     * @param {PdfPageTemplateElement} template The template element.
     * @param {PdfPage} page The page.
     * @param {_PdfAlignmentStyle} alignmentStyle The alignment style enum.
     * @param {_TemplateSide} [side] Optional template side for context-specific positioning.
     * @returns {Rectangle} The alignment bounds.
     */
    PdfDocument.prototype._getTemplateAlignmentBounds = function (template, page, alignmentStyle, side) {
        var result = template._bounds;
        var actualBounds;
        if (page._isNew) {
            actualBounds = page._getActualTemplateBounds(page._pageSettings);
        }
        if (actualBounds && actualBounds.length > 0) {
            var x = template._bounds.x;
            var y = template._bounds.y;
            switch (alignmentStyle) {
                case _PdfAlignmentStyle.topLeft:
                    x = -actualBounds[0];
                    y = (side === _TemplateSide.top) ? -actualBounds[1] : 0;
                    break;
                case _PdfAlignmentStyle.topCenter:
                    x = (actualBounds[2] - template._bounds.width) / 2;
                    y = -actualBounds[1];
                    break;
                case _PdfAlignmentStyle.topRight:
                    x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
                    y = (side === _TemplateSide.top) ? -actualBounds[1] : 0;
                    break;
                case _PdfAlignmentStyle.middleLeft:
                    x = -actualBounds[0];
                    y = (actualBounds[3] - template._bounds.height) / 2;
                    break;
                case _PdfAlignmentStyle.middleCenter:
                    x = (actualBounds[2] - template._bounds.width) / 2;
                    y = (actualBounds[3] - template._bounds.height) / 2;
                    break;
                case _PdfAlignmentStyle.middleRight:
                    x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
                    y = (actualBounds[3] - template._bounds.height) / 2;
                    break;
                case _PdfAlignmentStyle.bottomLeft:
                    x = -actualBounds[0];
                    y = (side === _TemplateSide.bottom)
                        ? actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height
                        : actualBounds[3] - template._bounds.height;
                    break;
                case _PdfAlignmentStyle.bottomCenter:
                    x = (actualBounds[2] - template._bounds.width) / 2;
                    y = actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height;
                    break;
                case _PdfAlignmentStyle.bottomRight:
                    x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
                    y = (side === _TemplateSide.bottom)
                        ? actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height
                        : actualBounds[3] - template._bounds.height;
                    break;
            }
            result.x = x;
            result.y = y;
        }
        return result;
    };
    /**
     * Checks if a template should not reserve space (background or foreground templates).
     *
     * @param {PdfTemplateLayerMode} templateLayerMode Template layer mode.
     * @returns {boolean} True if the template should not reserve space.
     * @private
     */
    PdfDocument.prototype._isNonReservingTemplate = function (templateLayerMode) {
        if (typeof templateLayerMode === 'undefined') {
            return false;
        }
        return templateLayerMode === PdfTemplateLayerMode.background || templateLayerMode === PdfTemplateLayerMode.foreground;
    };
    /**
     * Calculates the left indent width reserved by page templates and optional page margins.
     *
     * @private
     * @param {PdfPage} page The page to compute the left indent for.
     * @param {boolean} includeMargins If true, include the page left margin in the returned width.
     * @returns {number} The total left indent width (in points).
     */
    PdfDocument.prototype._getLeftIndentWidth = function (page, includeMargins) {
        var value = 0;
        if (includeMargins) {
            value += page._pageSettings.margins.left;
        }
        var templates = page._crossReference._document.template;
        if (templates) {
            var pageIndex = page._pageIndex ? page._pageIndex : 0;
            var isEven = ((pageIndex + 1) % 2) === 0;
            var widths = [];
            if (templates.left && !this._isNonReservingTemplate(templates.left.templateLayerMode)) {
                widths.push(templates.left.template._bounds.width);
            }
            if (isEven && templates.evenLeft && !this._isNonReservingTemplate(templates.evenLeft.templateLayerMode)) {
                widths.push(templates.evenLeft.template._bounds.width);
            }
            if (!isEven && templates.oddLeft && !this._isNonReservingTemplate(templates.oddLeft.templateLayerMode)) {
                widths.push(templates.oddLeft.template._bounds.width);
            }
            if (widths.length > 0) {
                value += Math.max.apply(Math, widths);
            }
        }
        return value;
    };
    /**
     * Calculates the top indent height reserved by page templates and optional page margins.
     *
     * @private
     * @param {PdfPage} page The page to compute the top indent for.
     * @param {boolean} includeMargins If true, include the page top margin in the returned height.
     * @returns {number} The total top indent height (in points).
     */
    PdfDocument.prototype._getTopIndentHeight = function (page, includeMargins) {
        var value = 0;
        if (includeMargins) {
            value += page._pageSettings.margins.top;
        }
        var templates = page._crossReference._document.template;
        if (templates) {
            var pageIndex = page._pageIndex ? page._pageIndex : 0;
            var isEven = ((pageIndex + 1) % 2) === 0;
            var heights = [];
            if (templates.top && !this._isNonReservingTemplate(templates.top.templateLayerMode)) {
                heights.push(templates.top.template._bounds.height);
            }
            if (isEven && templates.evenTop && !this._isNonReservingTemplate(templates.evenTop.templateLayerMode)) {
                heights.push(templates.evenTop.template._bounds.height);
            }
            if (!isEven && templates.oddTop && !this._isNonReservingTemplate(templates.oddTop.templateLayerMode)) {
                heights.push(templates.oddTop.template._bounds.height);
            }
            if (heights.length > 0) {
                value += Math.max.apply(Math, heights);
            }
        }
        return value;
    };
    /**
     * Calculates the right indent width reserved by page templates and optional page margins.
     *
     * @private
     * @param {PdfPage} page The page to compute the right indent for.
     * @param {boolean} includeMargins If true, include the page right margin in the returned width.
     * @returns {number} The total right indent width (in points).
     */
    PdfDocument.prototype._getRightIndentWidth = function (page, includeMargins) {
        var value = 0;
        if (includeMargins) {
            value += page._pageSettings.margins.right;
        }
        var templates = page._crossReference._document.template;
        if (templates) {
            var pageIndex = page._pageIndex ? page._pageIndex : 0;
            var isEven = ((pageIndex + 1) % 2) === 0;
            var widths = [];
            if (templates.right && !this._isNonReservingTemplate(templates.right.templateLayerMode)) {
                widths.push(templates.right.template._bounds.width);
            }
            if (isEven && templates.evenRight && !this._isNonReservingTemplate(templates.evenRight.templateLayerMode)) {
                widths.push(templates.evenRight.template._bounds.width);
            }
            if (!isEven && templates.oddRight && !this._isNonReservingTemplate(templates.oddRight.templateLayerMode)) {
                widths.push(templates.oddRight.template._bounds.width);
            }
            if (widths.length > 0) {
                value += Math.max.apply(Math, widths);
            }
        }
        return value;
    };
    /**
     * Calculates the bottom indent height reserved by page templates and optional page margins.
     *
     * @private
     * @param {PdfPage} page The page to compute the bottom indent for.
     * @param {boolean} includeMargins If true, include the page bottom margin in the returned height.
     * @returns {number} The total bottom indent height (in points).
     */
    PdfDocument.prototype._getBottomIndentHeight = function (page, includeMargins) {
        var value = 0;
        if (includeMargins) {
            value += page._pageSettings.margins.bottom;
        }
        var templates = page._crossReference._document.template;
        if (templates) {
            var pageIndex = page._pageIndex ? page._pageIndex : 0;
            var isEven = ((pageIndex + 1) % 2) === 0;
            var heights = [];
            if (templates.bottom && !this._isNonReservingTemplate(templates.bottom.templateLayerMode)) {
                heights.push(templates.bottom.template._bounds.height);
            }
            if (isEven && templates.evenBottom && !this._isNonReservingTemplate(templates.evenBottom.templateLayerMode)) {
                heights.push(templates.evenBottom.template._bounds.height);
            }
            if (!isEven && templates.oddBottom && !this._isNonReservingTemplate(templates.oddBottom.templateLayerMode)) {
                heights.push(templates.oddBottom.template._bounds.height);
            }
            if (heights.length > 0) {
                value += Math.max.apply(Math, heights);
            }
        }
        return value;
    };
    /**
     * Calculates the docking bounds for a page template based on the specified dock position.
     *
     * @private
     * @param {PdfPage} page The page on which the template is being positioned.
     * @param {PdfPageTemplateElement} template The template element to dock.
     * @param {string} dock The dock position applied to the template ('left', 'top', 'right', or 'bottom').
     * @returns {Rectangle} The calculated bounds of the docked template.
     */
    PdfDocument.prototype._getTemplateDockBounds = function (page, template, dock) {
        var result = template._bounds;
        var actualBounds;
        var actualSize;
        if (page._isNew) {
            actualBounds = page._getActualTemplateBounds(page._pageSettings);
            actualSize = page._pageSettings._getActualSize();
        }
        if (actualBounds && actualBounds.length > 0 && actualSize && actualSize.length > 0) {
            var x = template._bounds.x;
            var y = template._bounds.y;
            var width = template._bounds.width;
            var height = template._bounds.height;
            var topIndent = this._getTopIndentHeight(page, false);
            var bottomIndent = this._getBottomIndentHeight(page, false);
            switch (dock) {
                case 'left':
                    x = -actualBounds[0];
                    y = topIndent > 0 ? topIndent : 0;
                    width = template._bounds.width;
                    height = actualBounds[3] - topIndent - bottomIndent;
                    break;
                case 'top':
                    x = -actualBounds[0];
                    y = -actualBounds[1];
                    width = actualSize[0];
                    height = template._bounds.height;
                    if (actualBounds[3] < 0) {
                        y = -actualBounds[1] + actualSize[1];
                    }
                    break;
                case 'right':
                    x = actualBounds[2] + this._getRightIndentWidth(page, false) - template._bounds.width;
                    y = topIndent > 0 ? topIndent : 0;
                    width = template._bounds.width;
                    height = actualBounds[3] - topIndent - bottomIndent;
                    break;
                case 'bottom':
                    x = -actualBounds[0];
                    y = actualBounds[3] + this._getBottomIndentHeight(page, false) - template._bounds.height;
                    width = actualSize[0];
                    height = template._bounds.height;
                    if (actualBounds[3] < 0) {
                        y -= actualSize[1];
                    }
                    break;
            }
            result = { x: x, y: y, width: width, height: height };
        }
        return result;
    };
    /**
     * Finalizes form fields, optionally flattening and updating appearance flags.
     *
     * @private
     * @param {boolean} [isFlatten=false] Set `true` to flatten form fields.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._doPostProcessOnFormFields = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._catalog._catalogDictionary.has('AcroForm')) {
            this.form._doPostProcess(isFlatten);
            this.form._requiresPostProcessing = false;
            if (isFlatten) {
                var formObject = this._catalog._catalogDictionary.getRaw('AcroForm');
                var dictionary = new _PdfDictionary(this._crossReference);
                dictionary._updated = true;
                if (formObject instanceof _PdfReference) {
                    this._crossReference._cacheMap.set(formObject, dictionary);
                }
                else {
                    this.form._dictionary = dictionary;
                    this._crossReference._allowCatalog = true;
                }
                this.form._clear();
            }
            if (this.form._isDefaultAppearance) {
                this.form._dictionary.update('NeedAppearances', this.form._isDefaultAppearance);
            }
            else if (!this.form._isDefaultAppearance && this.form._dictionary.has('NeedAppearances') && this.form._isNeedAppearances) {
                this.form._dictionary.update('NeedAppearances', false);
            }
            else if (!this.form._isDefaultAppearance && this.form._dictionary.has('NeedAppearances')) {
                this.form._dictionary.update('NeedAppearances', this.form.needAppearances);
            }
        }
    };
    /**
     * Finalizes annotations for all pages, optionally flattening them.
     *
     * @private
     * @param {boolean} [isFlatten=false] Set `true` to flatten annotations.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._doPostProcessOnAnnotations = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        for (var i = 0; i < this.pageCount; i++) {
            var page = this.getPage(i);
            page.annotations._isExport = this._isExport;
            page.annotations._doPostProcess(isFlatten);
            if (isFlatten) {
                if (page._pageDictionary.has('Annots')) {
                    delete page._pageDictionary._map.Annots;
                    page._pageDictionary._updated = true;
                }
                page.annotations._clear();
            }
        }
    };
    /**
     * Adds the evaluation watermark text to all pages when license validation fails.
     *
     * @private
     * @returns {void} nothing.
     */
    PdfDocument.prototype._addWatermarkText = function () {
        for (var i = 0; i < this.pageCount; i++) {
            this._addLincenseWaterMark(this.getPage(i), i === 0, i === this.pageCount - 1);
        }
    };
    /**
     * Add license watermark on the page.
     *
     * @private
     * @param { PdfPage } page PDF-page.
     * @param { boolean } isFirstPage It denotes it is a first page or not.
     * @param { boolean } isLastPage It denotes it is a last page or not.
     * @returns { void } Returns void
     */
    PdfDocument.prototype._addLincenseWaterMark = function (page, isFirstPage, isLastPage) {
        var diagonalText = 'Created with a trial version of Syncfusion PDF library.';
        var formatCenter = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
        var fontSize = 14;
        var graphics = page.graphics;
        var clientSize = graphics.clientSize;
        if (page.size.width < 400) {
            fontSize = page.size.width * 0.035;
        }
        var font = new PdfStandardFont(PdfFontFamily.helvetica, fontSize, PdfFontStyle.regular);
        if (isFirstPage) {
            this._drawWatermarkOnPage(page, font, graphics, false);
        }
        else if (isLastPage) {
            this._drawWatermarkOnPage(page, font, graphics, true);
        }
        var textSize = font.measureString(diagonalText, clientSize.width);
        var centerX = clientSize.width / 2;
        var centerY = clientSize.height / 2;
        graphics.save();
        if (!page._isNew && (page.rotation === PdfRotationAngle.angle90)) {
            graphics.translateTransform({ x: centerY, y: centerX });
        }
        else {
            graphics.translateTransform({ x: centerX, y: centerY });
        }
        graphics.setTransparency(0.5);
        if (page._isNew) {
            switch (page.rotation) {
                case PdfRotationAngle.angle90:
                    graphics.rotateTransform(-135);
                    break;
                case PdfRotationAngle.angle180:
                    graphics.rotateTransform(-225);
                    break;
                case PdfRotationAngle.angle270:
                    graphics.rotateTransform(-315);
                    break;
                default:
                    graphics.rotateTransform(-45);
                    break;
            }
        }
        else {
            graphics.rotateTransform(-45);
        }
        var x = textSize.width / 2;
        var y = textSize.height / 2;
        var x1 = centerX - x;
        graphics.drawString(diagonalText, font, { x: -x, y: -(y / 2), width: clientSize.width - (x1 + x1), height: textSize.height }, new PdfBrush({ r: 255, g: 0, b: 0 }), formatCenter);
        graphics.restore();
        graphics.restore();
    };
    /**
     * Draw the watermark in the header and footer of the page.
     *
     * @private
     * @param { PdfPage } page PDF-page.
     * @param { PdfStandardFont } font It denotes the font for the text added.
     * @param { PdfGraphics } graphics It denotes the graphis of the page.
     * @param { boolean } isLastPage It denotes it is a last page or not.
     * @returns {void} Returns void.
     */
    PdfDocument.prototype._drawWatermarkOnPage = function (page, font, graphics, isLastPage) {
        var watermarkHeaderText = 'Created with a trial version of Syncfusion PDF library or registered the wrong key in your application. To obtain the valid key, Click';
        var watermarkLinkText = 'here';
        var xPosition = 40;
        var yPostion = 10;
        var rotation = page.rotation;
        var size = page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)
            ? { width: graphics.clientSize.width, height: graphics.clientSize.height - 70 }
            : { width: graphics.clientSize.width - 70, height: graphics.clientSize.height };
        if (!page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)) {
            size = { width: page.size.height - 70, height: page.size.width };
        }
        var textFormat = new PdfStringFormat();
        textFormat._wordWrap = _PdfWordWrapType.word;
        var redBrush = new PdfBrush({ r: 255, g: 0, b: 0 });
        var blueBrush = new PdfBrush({ r: 0, g: 0, b: 255 });
        var headerSize = font.measureString(watermarkHeaderText);
        var linkSize = font.measureString(watermarkLinkText);
        var lineHeight = headerSize.height;
        var availableWidth = (page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90))
            ? size.height : size.width;
        var currentX = rotation === PdfRotationAngle.angle90 && page._isNew ? xPosition - 70 : xPosition;
        var currentY = isLastPage
            ? (page._isNew && (rotation === PdfRotationAngle.angle270 || rotation === PdfRotationAngle.angle90)
                ? size.width : size.height) - (page.orientation === PdfPageOrientation.landscape &&
                page.size.width === 420 || page.size.height === 420 ? lineHeight * 4 : lineHeight * 3) - yPostion : yPostion;
        if (page._isNew) {
            if (page.rotation !== PdfRotationAngle.angle0) {
                graphics.save();
                if (rotation === PdfRotationAngle.angle90) {
                    graphics.rotateTransform(-90);
                }
                else if (rotation === PdfRotationAngle.angle180) {
                    graphics.rotateTransform(-180);
                }
                else if (rotation === PdfRotationAngle.angle270) {
                    graphics.rotateTransform(-270);
                }
            }
        }
        var adjustBoundsForRotation = function (rect) {
            if (page._isNew) {
                if (rotation === PdfRotationAngle.angle90) {
                    return {
                        x: -(size.height - rect.x),
                        y: rect.y,
                        width: rect.height - xPosition,
                        height: rect.width
                    };
                }
                if (rotation === PdfRotationAngle.angle180) {
                    return {
                        x: -(graphics.clientSize.width - rect.x),
                        y: -(size.height - rect.y),
                        width: rect.width - xPosition,
                        height: rect.height
                    };
                }
                if (rotation === PdfRotationAngle.angle270) {
                    return {
                        x: rect.x,
                        y: -(size.width - rect.y),
                        width: rect.height - xPosition,
                        height: rect.width
                    };
                }
            }
            return rect;
        };
        var headerBounds = adjustBoundsForRotation({
            x: currentX,
            y: currentY,
            width: size.width,
            height: size.height
        });
        graphics.drawString(watermarkHeaderText, font, headerBounds, redBrush, textFormat);
        var layouter = new _PdfStringLayouter();
        var headerLayoutResult = layouter._layout(watermarkHeaderText, font, textFormat, [headerBounds.width, headerBounds.height]);
        var headerLines = headerLayoutResult._layoutLines;
        var lastLine = headerLines[headerLines.length - 1];
        currentX += lastLine._width + 5;
        if (headerLayoutResult._lineCount >= 2) {
            currentY += headerLayoutResult._lineHeight * (headerLayoutResult._lineCount - 1);
        }
        if (currentX + linkSize.width > availableWidth) {
            currentX = xPosition;
            currentY += headerLayoutResult._lineHeight;
        }
        var linkRect = {
            x: currentX,
            y: currentY,
            width: linkSize.width,
            height: linkSize.height
        };
        var rotatedLinkRect = adjustBoundsForRotation(linkRect);
        rotatedLinkRect.width += 70;
        graphics.drawString(watermarkLinkText, font, rotatedLinkRect, blueBrush, textFormat);
        rotatedLinkRect.width -= 70;
        var annotationRect;
        if (page._isNew) {
            switch (rotation) {
                case PdfRotationAngle.angle0:
                    annotationRect = __assign({}, linkRect);
                    break;
                case PdfRotationAngle.angle90:
                    annotationRect = {
                        x: linkRect.y,
                        y: size.height - linkRect.x - linkRect.width,
                        width: linkRect.height,
                        height: linkRect.width
                    };
                    break;
                case PdfRotationAngle.angle180:
                    annotationRect = {
                        x: size.width - linkRect.x + 40,
                        y: size.height - linkRect.y - linkRect.height,
                        width: linkRect.width,
                        height: linkRect.height
                    };
                    break;
                case PdfRotationAngle.angle270:
                    annotationRect = {
                        x: size.width - linkRect.y - linkRect.height,
                        y: linkRect.x,
                        width: linkRect.height,
                        height: linkRect.width
                    };
                    break;
            }
        }
        else {
            switch (rotation) {
                case PdfRotationAngle.angle0:
                    annotationRect = __assign({}, linkRect);
                    break;
                case PdfRotationAngle.angle90:
                    annotationRect = {
                        x: linkRect.y,
                        y: page.size.height - linkRect.x - linkRect.width,
                        width: linkRect.height,
                        height: linkRect.width
                    };
                    break;
                case PdfRotationAngle.angle180:
                    annotationRect = {
                        x: page.size.width - linkRect.x - linkRect.width,
                        y: page.size.height - linkRect.y - linkRect.height,
                        width: linkRect.width,
                        height: linkRect.height
                    };
                    break;
                case PdfRotationAngle.angle270:
                    annotationRect = {
                        x: page.size.width - linkRect.y - linkRect.height,
                        y: linkRect.x,
                        width: linkRect.height,
                        height: linkRect.width
                    };
                    break;
            }
        }
        var linkAnnotation = new PdfUriAnnotation(annotationRect, 'http://www.syncfusion.com');
        linkAnnotation.border.width = 0;
        linkAnnotation.border.hRadius = 0;
        linkAnnotation.border.vRadius = 0;
        page.annotations.add(linkAnnotation);
        linkAnnotation._doPostProcess();
        if (page.rotation !== PdfRotationAngle.angle0 && page._isNew) {
            graphics.restore();
        }
        else {
            graphics.save();
        }
    };
    PdfDocument.prototype.importPageRange = function (sourceDocument, startIndex, endIndex, options) {
        if (startIndex > endIndex || startIndex >= sourceDocument.pageCount) {
            throw new Error('The start index is greater then the end index, which might indicate the error in the program.');
        }
        this._importPages(sourceDocument, startIndex, endIndex, options);
    };
    /**
     * Imports pages from the specified source document into this document.
     *
     * @private
     * @param {PdfDocument} sourceDocument - The source PDF document to import pages from.
     * @param {number} startIndex - The starting page index in the source document.
     * @param {number} endIndex - The ending page index in the source document.
     * @param {PdfPageImportOptions} [options] - Optional settings that control import behavior.
     * @returns {void} nothing.
     */
    PdfDocument.prototype._importPages = function (sourceDocument, startIndex, endIndex, options) {
        initializeTelemetryFeature('MergePDF', 'PDFLibrary');
        var sourceOCProperties;
        var correspondancePagecount = 0;
        var ocProperties;
        if (typeof options !== 'undefined' && typeof options.targetIndex === 'number') {
            if (options.targetIndex > this.pageCount) {
                throw new Error('The target index is out of range.');
            }
            this._targetIndex = options.targetIndex;
        }
        var pageReference = new Map();
        if (!this._isDuplicatePage) {
            var start = Math.max(0, startIndex);
            var end = Math.min(endIndex, sourceDocument.pageCount - 1);
            for (var index = start; index <= end; index++) {
                var srcPage = sourceDocument.getPage(index);
                pageReference.set(srcPage._pageDictionary, null);
            }
        }
        var helper;
        if (!this._mergeHelperCache) {
            this._mergeHelperCache = new Map();
        }
        if (!sourceDocument._uniqueID) {
            sourceDocument._uniqueID = _getNewGuidString();
        }
        if (this._mergeHelperCache.has(sourceDocument._uniqueID)) {
            helper = this._mergeHelperCache.get(sourceDocument._uniqueID);
        }
        else {
            helper = new _PdfMergeHelper(this._crossReference, this, sourceDocument, pageReference, options);
            this._mergeHelperCache.set(sourceDocument._uniqueID, helper);
        }
        var isLayersPresent = false;
        var hasOCProps = sourceDocument._catalog._catalogDictionary.has('OCProperties');
        if (hasOCProps && (!this._isDuplicatePage || (options && !options.optimizeResources))) {
            isLayersPresent = true;
            sourceOCProperties = sourceDocument._catalog._catalogDictionary.get('OCProperties');
            ocProperties = new _PdfDictionary(this._crossReference);
            helper._writeObject(sourceDocument, ocProperties, sourceOCProperties, sourceOCProperties, 'OCProperties', null, null);
            ocProperties._updated = true;
        }
        var flattenSource = sourceDocument.flatten;
        var isSplitImport = sourceDocument._isSplitDocument;
        for (var i = startIndex; i <= endIndex; i++) {
            var page = sourceDocument.getPage(i);
            sourceDocument.form._doPostProcess(flattenSource, page);
            if (page.annotations.count > 0) {
                page.annotations._doPostProcess(flattenSource);
                if (flattenSource) {
                    if (page._pageDictionary.has('Annots')) {
                        delete page._pageDictionary._map.Annots;
                        page._pageDictionary._updated = true;
                    }
                    page.annotations._clear();
                }
            }
            if (isSplitImport) {
                helper._importPages(page, this._targetIndex, isLayersPresent, this._isDuplicatePage, options, isSplitImport);
            }
            else {
                helper._importPages(page, this._targetIndex, isLayersPresent, this._isDuplicatePage, options);
            }
            correspondancePagecount++;
            if (typeof this._targetIndex === 'number') {
                ++this._targetIndex;
            }
        }
        if (!this._isDuplicatePage) {
            helper._fixDestinations(sourceDocument);
        }
        helper._exportBookmarks(sourceDocument, correspondancePagecount);
        helper._mergeFormFieldsWithDocument();
        if (isLayersPresent && (!this._isDuplicatePage || (options && !options.optimizeResources))) {
            helper._importLayers(ocProperties, true);
        }
        helper._objectDispose();
        this._isDuplicatePage = false;
    };
    PdfDocument.prototype.importPage = function (arg1, arg2, options) {
        if (typeof arg1 === 'number') {
            this._isDuplicatePage = true;
            if (arg2 instanceof PdfPageImportOptions) {
                this._importPages(this, arg1, arg1, arg2);
            }
            else {
                this._importPages(this, arg1, arg1);
            }
        }
        else if (arg1 instanceof PdfPage && arg2 instanceof PdfDocument) {
            var index = arg1._pageIndex;
            this.importPageRange(arg2, index, index, options);
        }
    };
    /**
     * Splitting a PDF file into individual pages.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * document.splitEvent = documentSplitEvent;
     * // Split PDF document into individual pages
     * document.split();
     * // Event to invoke while splitting PDF document data
     * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
     *   Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
     * }
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @returns {void} Nothing
     */
    PdfDocument.prototype.split = function () {
        this.splitByFixedNumber(1);
    };
    /**
     * Splits the PDF document into parts, each containing a maximum number of pages specified.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * document.splitEvent = documentSplitEvent;
     * // Split PDF document by fixed number of pages
     * document.splitByFixedNumber(1);
     * // Event to invoke while splitting PDF document data
     * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
     *   Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
     * }
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {number} fixedNumber specifies the maximum number of pages in each split PDF. The default value is 1.
     * @returns {void} Nothing
     */
    PdfDocument.prototype.splitByFixedNumber = function (fixedNumber) {
        var pageCount = this.pageCount;
        if (this.splitEvent && pageCount >= fixedNumber && fixedNumber > 0) {
            var splitIndex = 0;
            for (var tempValue = 0; tempValue < pageCount; tempValue += fixedNumber) {
                var endIndex = Math.min(tempValue + fixedNumber - 1, pageCount - 1);
                var pdfData = this._importDocumentPages(tempValue, endIndex);
                this._invokeSplitEvent(splitIndex, pdfData);
                splitIndex++;
            }
        }
        else {
            throw new Error('Invalid split number. Split number should be greater than zero and less than or equal to page count.');
        }
    };
    /**
     * Splits the PDF document into multiple parts based on the specified page ranges.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * document.splitEvent = documentSplitEvent;
     * // Split PDF document by page ranges specified
     * document.splitByPageRanges([[0, 4], [5, 9]]);
     * // Event to invoke while splitting PDF document data
     * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
     *   Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
     * }
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {Array<number[]>} ranges The two dimensional number array specified for start and end page indexes to split PDF documents.
     * @returns {void} Nothing
     */
    PdfDocument.prototype.splitByPageRanges = function (ranges) {
        var _this = this;
        var pageCount = this.pageCount;
        if (this.splitEvent) {
            var splitIndex_1 = 0;
            ranges.forEach(function (range) {
                if (Array.isArray(range) && range.length < 2) {
                    throw new Error('Invalid page range. Start and end page indexes should be specified.');
                }
                var start = range[0];
                var end = range[1];
                if (start < 0 || end < 0 || start >= pageCount || end >= pageCount || start > end) {
                    throw new Error("Invalid page range: start (" + start + ") and end (" + end + ").");
                }
                var pdfData = _this._importDocumentPages(start, end);
                _this._invokeSplitEvent(splitIndex_1, pdfData);
                splitIndex_1++;
            });
        }
    };
    PdfDocument.prototype._importDocumentPages = function (startIndex, endIndex) {
        this._isSplitDocument = true;
        var document = new PdfDocument();
        for (var i = startIndex; i <= endIndex; i++) {
            var page = this.getPage(i);
            document.importPage(page, this);
        }
        var result = document.save();
        document.destroy();
        return result;
    };
    PdfDocument.prototype._invokeSplitEvent = function (splitIndex, pdfData) {
        initializeTelemetryFeature('SplitPDF', 'PDFLibrary');
        var args = new PdfDocumentSplitEventArgs(splitIndex, pdfData);
        this.splitEvent(this, args);
    };
    /**
     * Retrieves and initializes a PDF signature instance from the given dictionary and field.
     *
     * @private
     * @param {_PdfDictionary} dictionary - The signature dictionary from the PDF.
     * @param {any} field - The associated form field containing the signature.
     * @returns {PdfSignature} The initialized `PdfSignature` object.
     */
    PdfDocument.prototype._getSignature = function (dictionary, field) {
        var signature = new PdfSignature();
        signature._initializeInternals(dictionary, field);
        return signature;
    };
    /**
     * Determines whether the document has any template content (headers/footers) defined.
     *
     * @private
     * @returns {boolean} `true` if the document has template content; otherwise, `false`.
     */
    PdfDocument.prototype._hasTemplateContent = function () {
        if (!this._template) {
            return false;
        }
        return ((this._template.oddTop !== null && typeof this._template.oddTop !== 'undefined') ||
            (this._template.evenTop !== null && typeof this._template.evenTop !== 'undefined') ||
            (this._template.oddBottom !== null && typeof this._template.oddBottom !== 'undefined') ||
            (this._template.evenBottom !== null && typeof this._template.evenBottom !== 'undefined') ||
            (this._template.left !== null && typeof this._template.left !== 'undefined') ||
            (this._template.oddLeft !== null && typeof this._template.oddLeft !== 'undefined') ||
            (this._template.evenLeft !== null && typeof this._template.evenLeft !== 'undefined') ||
            (this._template.right !== null && typeof this._template.right !== 'undefined') ||
            (this._template.oddRight !== null && typeof this._template.oddRight !== 'undefined') ||
            (this._template.evenRight !== null && typeof this._template.evenRight !== 'undefined') ||
            (this._template.top !== null && typeof this._template.top !== 'undefined') ||
            (this._template.bottom !== null && typeof this._template.bottom !== 'undefined'));
    };
    Object.defineProperty(PdfDocument.prototype, "_hasTemplateContentValue", {
        /**
         * Gets a value indicating whether the document contains any header or footer templates.
         *
         * @private
         * @returns {boolean} `true` if at least one template is defined; otherwise, `false`.
         */
        get: function () {
            return this._hasTemplateContent();
        },
        enumerable: true,
        configurable: true
    });
    return PdfDocument;
}());
export { PdfDocument };
/**
 * Represents annotation export settings.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Sets export data format as JSON type to annotation export settings
 * let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
 * // Set the data format defined in annotation export settings
 * settings.dataFormat = DataFormat.json;
 * // Export annotations to JSON format
 * let json: Uint8Array = document.exportAnnotations(settings);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAnnotationExportSettings = /** @class */ (function () {
    function PdfAnnotationExportSettings() {
        /**
         * @private
         */
        this._format = DataFormat.xfdf;
        this._exportAppearance = false;
    }
    Object.defineProperty(PdfAnnotationExportSettings.prototype, "dataFormat", {
        /**
         * Gets the data format defined in annotation export settings.
         *
         * @returns {DataFormat} - Returns the data format.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Sets export data format as JSON type to annotation export settings
         * let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
         * // Export annotations to JSON format
         * let json: Uint8Array = document.exportAnnotations(settings);
         * // Get the data format defined in annotation export settings
         * let dataFormat: DataFormat = settings.dataFormat;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._format;
        },
        /**
         * Sets the data format defined in annotation export settings.
         *
         * @param {DataFormat} format - Specifies the data format.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Sets export data format as JSON type to annotation export settings
         * let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
         * // Set the data format defined in annotation export settings
         * settings.dataFormat = DataFormat.json;
         * // Export annotations to JSON format
         * let json: Uint8Array = document.exportAnnotations(settings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (format) {
            this._format = format;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationExportSettings.prototype, "exportAppearance", {
        /**
         * Gets the boolean value indicating whether the appearance of a particular object can be exported or not.
         *
         * @returns {boolean} - Returns the boolean value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Sets the annotation export settings with enabled export appearance.
         * let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
         * // Export annotations to XFDF format
         * let xfdf: Uint8Array = document.exportAnnotations(settings);
         * // Get the boolean value indicating whether the appearance of a particular object can be exported or not
         * let appearance: boolean = settings.exportAppearance;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._exportAppearance;
        },
        /**
         * Sets the boolean value indicating whether the appearance of a particular object can be exported or not.
         *
         * @param {boolean} value - The boolean value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Sets the annotation export settings with enabled export appearance.
         * let settings: PdfAnnotationExportSettings = new PdfAnnotationExportSettings();
         * // Set the boolean value indicating whether the appearance of a particular object can be exported or not
         * settings.exportAppearance = true;
         * // Export annotations to XFDF format
         * let xfdf: Uint8Array = document.exportAnnotations(settings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._exportAppearance = value;
        },
        enumerable: true,
        configurable: true
    });
    return PdfAnnotationExportSettings;
}());
export { PdfAnnotationExportSettings };
/**
 * Represents form fields export settings.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * // Sets the form field data export settings with output data format.
 * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
 * // Set the data format defined in form field export settings.
 * settings.dataFormat = DataFormat.json;
 * // Export form field to JSON format
 * let json: Uint8Array = document.exportFormData(settings);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfFormFieldExportSettings = /** @class */ (function () {
    function PdfFormFieldExportSettings() {
        /**
         * @private
         */
        this._format = DataFormat.xfdf;
        /**
         * @private
         */
        this._exportName = '';
        /**
         * @private
         */
        this._asPerSpecification = true;
    }
    Object.defineProperty(PdfFormFieldExportSettings.prototype, "dataFormat", {
        /**
         * Gets the data format defined in form field export settings.
         *
         * @returns {DataFormat} - Returns the data format.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the form field data export settings with output data format.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Get the data format defined in form field export settings
         * let dataFormat: DataFormat = settings.dataFormat;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._format;
        },
        /**
         * Sets the data format defined in form field export settings.
         *
         * @param {DataFormat} format - Specifies the data format.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the form field data export settings with output data format.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Set the data format defined in form field export settings.
         * settings.dataFormat = DataFormat.json;
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (format) {
            this._format = format;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFormFieldExportSettings.prototype, "exportName", {
        /**
         * Gets the export name defined in form field export settings.
         *
         * @returns {string} - Returns the string value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the form field data export settings with export name.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Get the export name defined in form field export settings
         * let name: boolean = settings.exportName;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._exportName;
        },
        /**
         * Sets the export name defined in form field export settings.
         *
         * @param {string} name - Specifies the export name of the form.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the form field data export settings with export name.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Set the export name defined in form field export settings.
         * settings.exportName = 'JobApplication'.
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (name) {
            this._exportName = name;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFormFieldExportSettings.prototype, "asPerSpecification", {
        /**
         * Gets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         *
         * @returns {boolean} - Returns the boolean value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Get the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         * let asPerSpecification: boolean = settings.asPerSpecification;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._asPerSpecification;
        },
        /**
         * Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         *
         * @param {boolean} value - The boolean value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Sets the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         * let settings: PdfFormFieldExportSettings = new PdfFormFieldExportSettings();
         * // Set the boolean value indicating whether the data in a form field can be exported based on a certain specification.
         * settings.asPerSpecification = true;
         * // Export form field to JSON format
         * let json: Uint8Array = document.exportFormData(settings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._asPerSpecification = value;
        },
        enumerable: true,
        configurable: true
    });
    return PdfFormFieldExportSettings;
}());
export { PdfFormFieldExportSettings };
/**
 * The class provides various settings related to PDF pages.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Create a new PDF page settings instance
 * let pageSettings: PdfPageSettings = new PdfPageSettings();
 * // Sets the margins
 * pageSettings.margins = new PdfMargins(40);
 * // Sets the page size
 * pageSettings.size = {width: 595, height: 842};
 * // Sets the page orientation
 * pageSettings.orientation = PdfPageOrientation.landscape;
 * // Add a new PDF page with page settings
 * page = document.addPage(pageSettings);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfPageSettings = /** @class */ (function () {
    /**
     * Initializes a new instance of the `PdfPageSettings` class.
     *
     * @param {object} [options] Optional settings to initialize the page.
     * @param {PdfPageOrientation} [options.orientation] Page orientation.
     * @param {Size} [options.size] Page size.
     * @param {PdfMargins} [options.margins] Page margins.
     * @param {PdfRotationAngle} [options.rotation] Page rotation angle.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Create a new PDF page settings with custom options
     * let pageSettings = new PdfPageSettings({
     *   orientation: PdfPageOrientation.landscape,
     *   size: { width: 842, height: 595 },
     *   margins: new PdfMargins(40),
     *   rotation: PdfRotationAngle.angle90
     * });
     * // Add a new PDF page with page settings
     * page = document.addPage(pageSettings);
     * // Destroy the document
     * document.destroy();
     * ```
     */
    function PdfPageSettings(options) {
        /**
         * @private
         */
        this._size = { width: 595, height: 842 };
        /**
         * @private
         */
        this._isOrientation = false;
        if (options && 'orientation' in options && options.orientation !== null && typeof options.orientation !== 'undefined') {
            this.orientation = options.orientation;
        }
        else {
            this._orientation = PdfPageOrientation.portrait;
        }
        if (options && 'size' in options && options.size !== null && typeof options.size !== 'undefined') {
            this.size = options.size;
        }
        else {
            this._size = { width: 595, height: 842 };
        }
        if (options && 'margins' in options && options.margins !== null && typeof options.margins !== 'undefined') {
            this.margins = options.margins;
        }
        else {
            this._margins = new PdfMargins();
        }
        if (options && 'rotation' in options && options.rotation !== null && typeof options.rotation !== 'undefined') {
            this.rotation = options.rotation;
        }
        else {
            this._rotation = PdfRotationAngle.angle0;
        }
    }
    Object.defineProperty(PdfPageSettings.prototype, "orientation", {
        /**
         * Gets the orientation of the page.
         *
         * @returns {PdfPageOrientation} The orientation.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the page size
         * pageSettings.size = {width: 842, height: 595};
         * // Gets the page orientation
         * let orientation: PdfPageOrientation = pageSettings.orientation;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._orientation;
        },
        /**
         * Sets the orientation of the page.
         *
         * @param {PdfPageOrientation} value The orientation.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._isOrientation = true;
            if (this._orientation !== value) {
                this._orientation = value;
                this._updateSize(value);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPageSettings.prototype, "size", {
        /**
         * Gets the size of the page.
         *
         * @returns {Size} The width and height of the page as number array.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the first page
         * let page: PdfPage = document.getPage(0);
         * // Gets the width and height of the PDF page as number array
         * let size: Size = page.size;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._size;
        },
        /**
         * Sets the width and height of the page.
         *
         * @param {Size} value The width and height of the page as number array.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the page size
         * pageSettings.size = {width: 595, height: 842};
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._isOrientation) {
                this._updateSize(value);
            }
            else {
                this._size = value;
                this._updateOrientation();
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPageSettings.prototype, "margins", {
        /**
         * Gets the margin value of the page.
         *
         * @returns {PdfMargins} PDF margins
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the margins
         * let margins: PdfMargins = pageSettings.margins;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._margins;
        },
        /**
         * Sets the margin value of the page.
         *
         * @param {PdfMargins} value PDF margins
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the margins
         * pageSettings.margins = new PdfMargins(40);
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._margins = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPageSettings.prototype, "rotation", {
        /**
         * Gets the rotation angle of the PDF page.
         *
         * @returns {PdfRotationAngle} PDF rotation angle
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the rotation angle
         * let rotation: PdfRotationAngle = pageSettings.rotation;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._rotation;
        },
        /**
         * Sets the rotation angle of the PDF page.
         *
         * @param {PdfRotationAngle} value PDF rotation angle
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the rotation angle
         * pageSettings.rotation = PdfRotationAngle.angle90;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._rotation = value;
            if (value >= 4) {
                this._rotation = (value % 4);
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Updates the page size using either a `Size` object or a `PdfPageOrientation`, normalizing width/height accordingly.
     *
     * @private
     * @param {Size | PdfPageOrientation} value The target size or orientation.
     * @returns {void} nothing.
     */
    PdfPageSettings.prototype._updateSize = function (value) {
        var pageOrientation;
        var pageSize;
        if (typeof value !== 'number' && 'width' in value && 'height' in value && typeof value.width !== 'undefined' && typeof value.height !== 'undefined') {
            pageOrientation = this.orientation;
            pageSize = value;
        }
        else {
            pageOrientation = value;
            pageSize = this._size;
        }
        if (pageOrientation === PdfPageOrientation.portrait) {
            this._size = { width: Math.min(pageSize.width, pageSize.height), height: Math.max(pageSize.width, pageSize.height) };
        }
        else {
            this._size = { width: Math.max(pageSize.width, pageSize.height), height: Math.min(pageSize.width, pageSize.height) };
        }
    };
    /**
     * Recomputes the page orientation from the current size (portrait if height ≥ width; otherwise landscape).
     *
     * @private
     * @returns {void} nothing.
     */
    PdfPageSettings.prototype._updateOrientation = function () {
        this._orientation = (this._size.height >= this._size.width) ? PdfPageOrientation.portrait : PdfPageOrientation.landscape;
    };
    /**
     * Computes the drawable content size by subtracting margins from the page size.
     *
     * @private
     * @returns {number[]} A two-element array.
     */
    PdfPageSettings.prototype._getActualSize = function () {
        var width = this._size.width - (this._margins._left + this._margins._right);
        var height = this._size.height - (this._margins._top + this._margins._bottom);
        return [width, height];
    };
    return PdfPageSettings;
}());
export { PdfPageSettings };
/**
 * A class representing PDF page margins.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Create a new PDF page settings instance
 * let pageSettings: PdfPageSettings = new PdfPageSettings();
 * // Sets the margins
 * pageSettings.margins = new PdfMargins(40);
 * // Sets the page size
 * pageSettings.size = {width: 595, height: 842};
 * // Sets the page orientation
 * pageSettings.orientation = PdfPageOrientation.landscape;
 * // Add a new PDF page with page settings
 * page = document.addPage(pageSettings);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfMargins = /** @class */ (function () {
    function PdfMargins(all) {
        if (typeof all === 'undefined') {
            this._left = this._right = this._top = this._bottom = 40;
        }
        else {
            this._left = this._right = this._top = this._bottom = all;
        }
    }
    Object.defineProperty(PdfMargins.prototype, "left", {
        /**
         * Gets the left margin value of the page.
         *
         * @returns {number} Left margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the left margin
         * let left: number = pageSettings.margins.left;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._left;
        },
        /**
         * Sets the left margin value of the page.
         *
         * @param {number} value Left margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the margins
         * let margins: PdfMargins = new PdfMargins();
         * margins.left = 40;
         * margins.right = 40;
         * margins.top = 20;
         * margins.bottom = 20;
         * pageSettings.margins = margins;
         * // Sets the page size
         * pageSettings.size = {width: 595, height: 842};
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._left = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfMargins.prototype, "right", {
        /**
         * Gets the right margin value of the page.
         *
         * @returns {number} Right margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the right margin
         * let right: number = pageSettings.margins.right;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._right;
        },
        /**
         * Sets the right margin value of the page.
         *
         * @param {number} value - Right margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the margins
         * let margins: PdfMargins = new PdfMargins();
         * margins.left = 40;
         * margins.right = 40;
         * margins.top = 20;
         * margins.bottom = 20;
         * pageSettings.margins = margins;
         * // Sets the page size
         * pageSettings.size = {width: 595, height: 842};
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._right = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfMargins.prototype, "top", {
        /**
         * Gets the top margin value of the page.
         *
         * @returns {number} Top margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the top margin
         * let top: number = pageSettings.margins.top;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._top;
        },
        /**
         *Sets the top margin value of the page.
         *
         * @param {number} value Top margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the margins
         * let margins: PdfMargins = new PdfMargins();
         * margins.left = 40;
         * margins.right = 40;
         * margins.top = 20;
         * margins.bottom = 20;
         * pageSettings.margins = margins;
         * // Sets the page size
         * pageSettings.size = {width: 595, height: 842};
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._top = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfMargins.prototype, "bottom", {
        /**
         * Get the bottom margin value of the page.
         *
         * @returns {number} Bottom margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Gets the bottom margin
         * let bottom: number = pageSettings.margins.bottom;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._bottom;
        },
        /**
         * Sets the bottom margin value of the page.
         *
         * @param {number} value Bottom margin.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Create a new PDF page settings instance
         * let pageSettings: PdfPageSettings = new PdfPageSettings();
         * // Sets the margins
         * let margins: PdfMargins = new PdfMargins();
         * margins.left = 40;
         * margins.right = 40;
         * margins.top = 20;
         * margins.bottom = 20;
         * pageSettings.margins = margins;
         * // Sets the page size
         * pageSettings.size = {width: 595, height: 842};
         * // Sets the page orientation
         * pageSettings.orientation = PdfPageOrientation.landscape;
         * // Add a new PDF page with page settings
         * page = document.addPage(pageSettings);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._bottom = value;
        },
        enumerable: true,
        configurable: true
    });
    return PdfMargins;
}());
export { PdfMargins };
/**
 * Public class to provide data for the document split event, including the split index and PDF data.
 *
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * document.splitEvent = documentSplitEvent;
 * // Split PDF document by fixed number of pages
 * document.splitByFixedNumber(1);
 * // Event to invoke while splitting PDF document data
 * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
 *  Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
 * }
 * // Destroy the document
 * document.destroy();
 */
var PdfDocumentSplitEventArgs = /** @class */ (function () {
    /*
     * Initializes a new instance of the `PdfDocumentSplitEventArgs` class.
     *
     * @param {number} splitIndex The fixed number to split PDF document pages. The default value is 1.
     * @param {Uint8Array} pdfData The byte array of the split PDF document data.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data);
     * document.splitEvent = documentSplitEvent;
     * // Split PDF document by fixed number of pages
     * document.splitByFixedNumber(1);
     * // Event to invoke while splitting PDF document data
     * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
     *   Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
     * }
     * // Destroy the document
     * document.destroy();
     */
    function PdfDocumentSplitEventArgs(splitIndex, pdfData) {
        this._index = splitIndex;
        this._pdfData = pdfData;
    }
    Object.defineProperty(PdfDocumentSplitEventArgs.prototype, "pdfData", {
        /*
         * Gets the byte array of the PDF document data.
         *
         * @returns {Uint8Array} The byte array of the PDF document data.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * document.splitEvent = documentSplitEvent;
         * // Split PDF document by fixed number of pages
         * document.splitByFixedNumber(1);
         * // Event to invoke while splitting PDF document data
         * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
         *  Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
         * }
         * // Destroy the document
         * document.destroy();
         */
        get: function () {
            return this._pdfData;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfDocumentSplitEventArgs.prototype, "index", {
        /*
         * Gets the split index of the PDF document.
         *
         * @returns {Uint8Array} The index that defines the number of event calls during the PDF document split.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * document.splitEvent = documentSplitEvent;
         * // Split PDF document by fixed number of pages
         * document.splitByFixedNumber(1);
         * // Event to invoke while splitting PDF document data
         * function documentSplitEvent(sender: PdfDocument, args: PdfDocumentSplitEventArgs): void {
         *  Save.save('output_' + args.splitIndex + '.pdf', new Blob([args.pdfData], { type: 'application/pdf' }));
         * }
         * // Destroy the document
         * document.destroy();
         */
        get: function () {
            return this._index;
        },
        enumerable: true,
        configurable: true
    });
    return PdfDocumentSplitEventArgs;
}());
export { PdfDocumentSplitEventArgs };