UNPKG

@syncfusion/ej2-pdf

Version:

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

20,022 lines 901 kB
var __extends = (this && this.__extends) || (function () {
    var extendStatics = function (d, b) {
        extendStatics = Object.setPrototypeOf ||
            ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) ||
            function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; };
        return extendStatics(d, b);
    };
    return function (d, b) {
        extendStatics(d, b);
        function __() { this.constructor = d; }
        d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __());
    };
})();
import { _PdfDestinationHelper } from './../pdf-page';
import { _PdfDictionary, _PdfName, _PdfReference } from './../pdf-primitives';
import { PdfFormFieldVisibility, _PdfCheckFieldState, PdfAnnotationFlag, PdfBorderStyle, PdfLineCaptionType, PdfLineEndingStyle, PdfLineIntent, PdfRotationAngle, PdfTextAlignment, PdfBorderEffectStyle, PdfMeasurementUnit, _PdfGraphicsUnit, PdfCircleMeasurementType, PdfRubberStampAnnotationIcon, PdfCheckBoxStyle, PdfTextMarkupAnnotationType, PdfPopupIcon, PdfAnnotationState, PdfAnnotationStateModel, PdfAttachmentIcon, PdfAnnotationIntent, _PdfAnnotationType, PdfBlendMode, PdfDashStyle, PdfLineCap, _PdfColorSpace, DataFormat } from './../enumerator';
import { _checkField, _removeDuplicateReference, _updateVisibility, _checkComment, _checkReview, _mapAnnotationStateModel, _mapAnnotationState, _decode, _setMatrix, _convertToColor, _findPage, _getItemValue, _areNotEqual, _calculateBounds, _parseColor, _mapHighlightMode, _reverseMapHighlightMode, _getUpdatedBounds, _mapBorderStyle, _mapLineEndingStyle, _reverseMapEndingStyle, _toRectangle, _mapBorderEffectStyle, _getStateTemplate, _mapMeasurementUnit, _mapGraphicsUnit, _stringToStyle, _styleToString, _mapMarkupAnnotationType, _reverseMarkupAnnotationType, _reverseMapAnnotationState, _reverseMapAnnotationStateModel, _mapPopupIcon, _mapRubberStampIcon, _mapAttachmentIcon, _mapAnnotationIntent, _reverseMapPdfFontStyle, _fromRectangle, _getNewGuidString, _getFontStyle, _mapFont, _checkInkPoints, _updateBounds, _isNullOrUndefined, _obtainFontDetails, _areArrayEqual, _arePointsNotEqual, _convertToPoints, _isPointArray, _convertPointsToNumberArrays, _convertNumberToPointArrays, _convertNumberArraysToPoints, _convertPointToNumberArray, _pad2, _getPageIndex, _stringToBytes } from './../utils';
import { PdfField, PdfTextBoxField, _PdfDefaultAppearance, PdfListBoxField, PdfComboBoxField } from './../form/field';
import { PdfTemplate } from './../graphics/pdf-template';
import { _TextRenderingMode, PdfBrush, PdfPen, _PdfTransformationMatrix, _PdfUnitConvertor } from './../graphics/pdf-graphics';
import { PdfPath } from './../graphics/pdf-path';
import { PdfFontFamily, PdfStandardFont, PdfFont, PdfFontStyle, PdfTrueTypeFont, PdfCjkStandardFont } from './../fonts/pdf-standard-font';
import { PdfStringFormat, PdfVerticalAlignment } from './../fonts/pdf-string-format';
import { _PdfBaseStream, _PdfStream } from './../base-stream';
import { PdfAppearance } from './pdf-appearance';
import { PdfPopupAnnotationCollection } from './annotation-collection';
import { _ContentParser } from '../content-parser';
import { _XfdfDocument } from './../import-export/xfdf-document';
import { _JsonDocument } from './../import-export/json-document';
import { _XmlWriter } from './../import-export/xml-writer';
import { initializeTelemetryFeature } from '@syncfusion/ej2-base';
/**
 * Represents the base class for annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: PdfAnnotation = page.annotations.at(0);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAnnotation = /** @class */ (function () {
    function PdfAnnotation() {
        /**
         * Indicates whether this annotation was imported from an existing document.
         *
         * @private
         */
        this._isImported = false;
        /**
         * Specifies whether the annotation was loaded from an existing document.
         *
         * @private
         */
        this._isLoaded = false;
        /**
         * Indicates whether an appearance stream has been explicitly set.
         *
         * @private
         */
        this._setAppearance = false;
        /**
         * Flags whether the annotation is currently being exported.
         *
         * @private
         */
        this._isExport = false;
        /**
         * Controls the transparency level of the annotation appearance.
         *
         * @private
         */
        this._opacity = 1;
        /**
         * When true, applies rotation to all relevant elements of the annotation.
         *
         * @private
         */
        this._isAllRotation = true;
        /**
         * Determines whether the annotation should be flattened when saved.
         *
         * @private
         */
        this._flatten = false;
        /**
         * Default font used for popup content rendering.
         *
         * @private
         */
        this._popUpFont = new PdfStandardFont(PdfFontFamily.helvetica, 10.5);
        /**
         * Bold font used for author text in popups.
         *
         * @private
         */
        this._authorBoldFont = new PdfStandardFont(PdfFontFamily.helvetica, 10.5, PdfFontStyle.bold);
        /**
         * Font used for line caption text.
         *
         * @private
         */
        this._lineCaptionFont = new PdfStandardFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular);
        /**
         * Font used for circle caption text.
         *
         * @private
         */
        this._circleCaptionFont = new PdfStandardFont(PdfFontFamily.helvetica, 8, PdfFontStyle.regular);
        /**
         * Indicates whether the color used should be treated as transparent.
         *
         * @private
         */
        this._isTransparentColor = false;
        /**
         * Tracks whether the annotation has been rotated.
         *
         * @private
         */
        this._isRotated = false;
        /**
         * Flags if any property of the annotation has changed.
         *
         * @private
         */
        this._isChanged = false;
        /**
         * Stores the quad points for text markup annotations.
         *
         * @private
         */
        this._quadPoints = new Array(8);
        /**
         * Holds multiple bounding rectangles for complex annotations.
         *
         * @private
         */
        this._boundsCollection = [];
        /**
         * Caches custom appearance templates keyed by usage.
         *
         * @private
         */
        this._customTemplate = new Map();
        /**
         * Indicates whether the annotation text was updated.
         *
         * @private
         */
        this._isTextUpdated = false;
    }
    Object.defineProperty(PdfAnnotation.prototype, "author", {
        /**
         * Gets the author of the annotation.
         *
         * @returns {string} Author.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the author of the annotation.
         * let author: string = annotation.author;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._author === 'undefined' && this._dictionary.has('Author')) {
                var author = this._dictionary.get('Author');
                if (author) {
                    this._author = author;
                }
            }
            if (typeof this._author === 'undefined' && this._dictionary.has('T')) {
                var author = this._dictionary.get('T');
                if (author) {
                    this._author = author;
                }
            }
            return this._author;
        },
        /**
         * Sets the author of the annotation.
         *
         * @param {string} value Author.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the author of the annotation.
         * annotation.author = 'Syncfusion';
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._isLoaded && typeof value === 'string' && value !== this.author) {
                var hasKey = false;
                if (this._dictionary && this._dictionary.has('T')) {
                    this._dictionary.update('T', value);
                    this._author = value;
                    hasKey = true;
                }
                if (this._dictionary && this._dictionary.has('Author')) {
                    this._dictionary.update('Author', value);
                    this._author = value;
                    hasKey = true;
                }
                if (!hasKey) {
                    this._dictionary.update('T', value);
                    this._author = value;
                }
            }
            if (!this._isLoaded && typeof value === 'string') {
                this._dictionary.update('T', value);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "border", {
        /**
         * Gets the border of the annotation.
         *
         * @returns {PdfAnnotationBorder} Annotation border.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the border of the annotation.
         * let border: PdfAnnotationBorder = annotation.border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._border === 'undefined') {
                var value = new PdfAnnotationBorder({ width: 1, style: PdfBorderStyle.solid });
                value._dictionary = this._dictionary;
                if (this._dictionary && this._dictionary.has('Border')) {
                    var border = this._dictionary.getArray('Border');
                    if (border && border.length >= 3) {
                        value._hRadius = border[0];
                        value._vRadius = border[1];
                        value._width = border[2];
                    }
                }
                var borderDictionary = void 0;
                if (this._dictionary && this._dictionary.has('BS')) {
                    borderDictionary = this._dictionary;
                }
                else if (this instanceof PdfRadioButtonListItem && this._field && this._field._dictionary && this._field._dictionary.has('BS')) {
                    borderDictionary = this._field._dictionary;
                }
                if (borderDictionary) {
                    var border = borderDictionary.get('BS');
                    if (border) {
                        if (border.has('W')) {
                            var width = border.get('W');
                            if (typeof width !== 'undefined' && !Number.isNaN(width)) {
                                value._width = width;
                            }
                        }
                        if (border.has('S')) {
                            var style = border.get('S');
                            if (style) {
                                switch (style.name) {
                                    case 'D':
                                        value._style = PdfBorderStyle.dashed;
                                        break;
                                    case 'B':
                                        value._style = PdfBorderStyle.beveled;
                                        break;
                                    case 'I':
                                        value._style = PdfBorderStyle.inset;
                                        break;
                                    case 'U':
                                        value._style = PdfBorderStyle.underline;
                                        break;
                                    default:
                                        value._style = PdfBorderStyle.solid;
                                        break;
                                }
                            }
                        }
                        if (border.has('D')) {
                            var dash = border.getArray('D');
                            if (dash) {
                                value._dash = dash;
                            }
                        }
                    }
                }
                this._border = value;
            }
            return this._border;
        },
        /**
         * Sets the border of the annotation.
         *
         * @param {PdfAnnotationBorder} value Border.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the `PdfAnnotationBorder` class.
         * let border: PdfAnnotationBorder = new PdfAnnotationBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF annotation
         * annotation.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var current = this.border;
            var width;
            if (!this._isLoaded || (typeof value.width !== 'undefined' && current.width !== value.width)) {
                width = value.width;
            }
            var hRadius;
            if (!this._isLoaded || (typeof value.hRadius !== 'undefined' && current.hRadius !== value.hRadius)) {
                hRadius = value.hRadius;
            }
            var vRadius;
            if (!this._isLoaded || (typeof value.vRadius !== 'undefined' && current.vRadius !== value.vRadius)) {
                vRadius = value.vRadius;
            }
            var style;
            if (!this._isLoaded || (typeof value.style !== 'undefined' && current.style !== value.style)) {
                style = value.style;
            }
            var dash;
            if (typeof value.dash !== 'undefined' && current.dash !== value.dash) {
                dash = value.dash;
            }
            if (!this._isWidget && this._dictionary && this._dictionary.has('Border') || (width || vRadius || hRadius)) {
                this._border._hRadius = typeof hRadius !== 'undefined' ? hRadius : current.hRadius;
                this._border._vRadius = typeof vRadius !== 'undefined' ? vRadius : current.vRadius;
                this._border._width = typeof width !== 'undefined' ? width : current.width;
                this._dictionary.update('Border', [this._border.hRadius, this._border.vRadius, this._border.width]);
            }
            if (this._dictionary !== null && this._dictionary && this._dictionary.has('BS') || (width || style || dash)) {
                this._border._width = typeof width !== 'undefined' ? width : current.width;
                this._border._style = typeof style !== 'undefined' ? style : current.style;
                this._border._dash = typeof dash !== 'undefined' ? dash : current.dash;
                var bs = this._dictionary.has('BS') ? this._dictionary.get('BS') : new _PdfDictionary(this._crossReference);
                bs.update('Type', _PdfName.get('Border'));
                bs.update('W', this._border.width);
                bs.update('S', _mapBorderStyle(this._border.style));
                if (typeof this._border.dash !== 'undefined') {
                    bs.update('D', this._border.dash);
                }
                this._dictionary.update('BS', bs);
                this._dictionary._updated = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "flags", {
        /**
         * Gets the flags of the annotation.
         *
         * @returns {PdfAnnotationFlag} Annotation flag.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the flags of the annotation.
         * let flag: PdfAnnotationFlag = annotation.flags;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._annotFlags === 'undefined') {
                this._annotFlags = PdfAnnotationFlag.default;
                if (this._dictionary && this._dictionary.has('F')) {
                    this._annotFlags = this._dictionary.get('F');
                }
            }
            return this._annotFlags;
        },
        /**
         * Sets the flags of the annotation.
         *
         * @param {PdfAnnotationFlag} value flag value.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the flags of the annotation.
         * annotation.flags = PdfAnnotationFlag.print;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined' && value !== this._annotFlags) {
                this._annotFlags = value;
                this._dictionary.update('F', value);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "color", {
        /**
         * Gets the fore color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the color of the annotation.
         * let color: PdfColor = annotation.color;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._color === 'undefined' && this._dictionary.has('C')) {
                this._color = _parseColor(this._dictionary.getArray('C'));
            }
            return this._color;
        },
        /**
         * Sets the fore color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the color of the annotation.
         * annotation.color = {r: 255, g: 0, b: 0};
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== null && typeof value !== 'undefined') {
                var extColor = this.color;
                if (!this._isLoaded || typeof extColor === 'undefined' || (extColor.r !== value.r || extColor.g !== value.g || extColor.b !== value.b)) {
                    this._color = value;
                    this._dictionary.update('C', [Number.parseFloat((value.r / 255).toFixed(7)),
                        Number.parseFloat((value.g / 255).toFixed(7)),
                        Number.parseFloat((value.b / 255).toFixed(7))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "innerColor", {
        /**
         * Gets the inner color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the inner color of the annotation.
         * let innerColor: PdfColor = annotation.innerColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._innerColor === 'undefined' && this._dictionary.has('IC')) {
                this._innerColor = _parseColor(this._dictionary.getArray('IC'));
            }
            return this._innerColor;
        },
        /**
         * Sets the inner color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the inner color of the annotation.
         * annotation.innerColor = {r: 255, g: 0, b: 0};
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                var extColor = this.innerColor;
                if (!this._isLoaded ||
                    typeof extColor === 'undefined' ||
                    (extColor.r !== value.r || extColor.g !== value.g || extColor.b !== value.b)) {
                    this._innerColor = value;
                    this._dictionary.update('IC', [Number.parseFloat((value.r / 255).toFixed(7)),
                        Number.parseFloat((value.g / 255).toFixed(7)),
                        Number.parseFloat((value.b / 255).toFixed(7))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "creationDate", {
        /**
         * Gets the creation date of the annotation.
         *
         * @returns {Date} Creation date.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the creation date of the annotation.
         * let creationDate: Date = annotation.creationDate;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if ((typeof this._creationDate === 'undefined' || this._creationDate === null) && this._dictionary.has('CreationDate')) {
                var value = this._dictionary.get('CreationDate'); // eslint-disable-line
                if (value !== null && typeof value === 'string') {
                    this._creationDate = this._stringToDate(value);
                }
            }
            return this._creationDate;
        },
        /**
         * Sets the creation date of the annotation.
         *
         * @param {Date} value Creation date.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Set the creation date of the annotation.
         * annotation.creationDate = new Date();
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._creationDate = value;
            this._dictionary.update('CreationDate', this._dateToString(value));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "modifiedDate", {
        /**
         * Gets the modification date of the annotation.
         *
         * @returns {Date} Modified date.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the modified date of the annotation.
         * let modifiedDate: Date = annotation.modifiedDate;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if ((typeof this._modifiedDate === 'undefined' || this._modifiedDate === null)) {
                var value = void 0; // eslint-disable-line
                if (this._dictionary && this._dictionary.has('ModDate')) {
                    value = this._dictionary.get('ModDate');
                }
                else if (this._dictionary.has('M')) {
                    value = this._dictionary.get('M');
                }
                if (value !== null && typeof value === 'string') {
                    this._modifiedDate = this._stringToDate(value);
                }
            }
            return this._modifiedDate;
        },
        /**
         * Sets the modification date of the annotation.
         *
         * @param {Date} value Modified date.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Set the modified date of the annotation.
         * annotation.modifiedDate = new Date();
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._modifiedDate = value;
            this._dictionary.update('M', this._dateToString(value));
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "bounds", {
        /**
         * Gets the bounds of the annotation.
         *
         * @returns {Rectangle} Bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the bounds of the annotation.
         * let bounds: Rectangle = annotation.bounds;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                this._bounds = _calculateBounds(this._dictionary, this._page);
            }
            return this._bounds;
        },
        /**
         * Sets the bounds of the annotation.
         *
         * @param {Rectangle} value bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the bounds of the annotation.
         * annotation.bounds = {x: 10, y: 10, width: 150, height: 5};
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                this._isBounds = true;
                if (this._isLoaded) {
                    if ((value.x !== this.bounds.x) || (value.y !== this.bounds.y) ||
                        (value.width !== this.bounds.width) || (value.height !== this.bounds.height)) {
                        var size = this._page.size;
                        if (size) {
                            var y = size.height - (value.y + value.height);
                            var height = y + value.height;
                            this._dictionary.update('Rect', [value.x, y, value.x + value.width, height]);
                            this._bounds = value;
                            this._isChanged = true;
                        }
                    }
                }
                else {
                    this._bounds = value;
                    this._isChanged = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "caption", {
        /**
         * Gets the caption of the annotation.
         *
         * @returns {PdfAnnotationCaption} Annotation caption.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the caption of the annotation.
         * let caption: PdfAnnotationCaption = annotation.caption;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._caption === 'undefined') {
                var value = new PdfAnnotationCaption();
                value._dictionary = this._dictionary;
                if (this._dictionary && this._dictionary.has('Cap')) {
                    value._cap = this._dictionary.get('Cap');
                }
                if (this._dictionary && this._dictionary.has('CP')) {
                    var capType = this._dictionary.get('CP');
                    if (capType) {
                        value._type = capType.name === 'Top' ? PdfLineCaptionType.top : PdfLineCaptionType.inline;
                    }
                }
                if (this._dictionary && this._dictionary.has('CO')) {
                    var offset = this._dictionary.getArray('CO');
                    value._offset = { x: offset[0], y: offset[1] };
                }
                this._caption = value;
            }
            return this._caption;
        },
        /**
         * Sets the caption of the annotation.
         *
         * @param {PdfAnnotationCaption} value Annottion caption.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Create and set annotation caption values
         * annotation.caption = new PdfAnnotationCaption(true, PdfLineCaptionType.inline, {x: 10, y: 10});
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var current = this.caption;
            if (value) {
                if (!this._isLoaded || value.cap !== current.cap) {
                    this._caption.cap = value.cap;
                }
                if (!this._isLoaded || value.type !== current.type) {
                    this._caption.type = value.type;
                }
                if (!this._isLoaded || value.offset !== current.offset) {
                    this._caption.offset = value.offset;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "opacity", {
        /**
         * Gets the opacity of the annotation.
         *
         * @returns {number} Opacity in between 0 t0 1.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the opacity of the annotation.
         * let opacity: number = annotation.opacity;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary && this._dictionary.has('CA')) {
                var opacity = this._dictionary.get('CA');
                if (typeof opacity !== 'undefined') {
                    this._opacity = opacity;
                }
            }
            return this._opacity;
        },
        /**
         * Sets the opacity of the annotation.
         *
         * @param {number} value opacity in between 0 t0 1.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the opacity of the annotation.
         * annotation.opacity = 0.5;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined' && !Number.isNaN(value)) {
                if (value >= 0 && value <= 1) {
                    this._dictionary.update('CA', value);
                    this._opacity = value;
                }
                else if (value < 0) {
                    this._dictionary.update('CA', 0);
                }
                else {
                    this._dictionary.update('CA', 1);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "subject", {
        /**
         * Gets the subject of the annotation.
         *
         * @returns {string} Subject.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the subject of the annotation.
         * let subject: string = annotation.subject;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._subject === 'undefined') {
                this._subject = this._dictionary.get('Subject', 'Subj');
            }
            return this._subject;
        },
        /**
         * Sets the subject of the annotation.
         *
         * @param {string} value Subject.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the subject of the annotation.
         * annotation.subject = 'Line Annotation';
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string' && this.subject !== value) {
                this._dictionary.update('Subj', value);
                this._subject = value;
                if (this._dictionary.has('Subject')) {
                    this._dictionary.update('Subject', value);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "name", {
        /**
         * Gets the name of the annotation.
         *
         * @returns {string} Name.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the name of the annotation.
         * let name: string = annotation.name;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._name === 'undefined' && this._dictionary.has('NM')) {
                this._name = this._dictionary.get('NM');
            }
            return this._name;
        },
        /**
         * Sets the name of the annotation.
         *
         * @param {string} value Name.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the name of the annotation.
         * annotation.name = 'LineAnnotation';
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string') {
                this._dictionary.update('NM', value);
                this._name = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "text", {
        /**
         * Gets the text of the annotation.
         *
         * @returns {string} Text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the text of the annotation.
         * let text: string = annotation.text;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._text === 'undefined' && this._dictionary.has('Contents')) {
                this._text = this._dictionary.get('Contents');
            }
            return this._text;
        },
        /**
         * Sets the text of the annotation.
         *
         * @param {string} value Text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the text of the annotation.
         * annotation.text = 'LineAnnotation';
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string') {
                this._text = this._dictionary.get('Contents');
                if (value !== this._text) {
                    if ((this instanceof PdfLineAnnotation || this instanceof PdfCircleAnnotation
                        || this instanceof PdfSquareAnnotation) && this.measure) {
                        if (typeof this._unit === 'undefined' || this._isLoaded) {
                            if (this._dictionary.has('Contents')) {
                                this._isTextUpdated = true;
                                var text = this._dictionary.get('Contents');
                                this._unit = _mapMeasurementUnit(text.substring(text.length - 2));
                            }
                        }
                    }
                    this._dictionary.update('Contents', value);
                    this._text = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "rotationAngle", {
        /**
         * Gets the rotation of the annotation.
         *
         * @returns {PdfRotationAngle} Rotation angle.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the rotation angle of the annotation.
         * let rotationAngle: PdfRotationAngle = annotation.rotationAngle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._rotate === 'undefined' && this._dictionary && this._dictionary.has('Rotate')) {
                this._rotate = (this._dictionary.get('Rotate') / 90);
            }
            if (this._rotate === null || typeof this._rotate === 'undefined') {
                this._rotate = PdfRotationAngle.angle0;
            }
            return this._rotate;
        },
        /**
         * Sets the rotation of the annotation.
         *
         * @param {PdfRotationAngle} value rotation angle.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the rotation angle of the annotation.
         * annotation.rotationAngle = PdfRotationAngle.angle180;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var prevRotate = this.rotationAngle;
            if (typeof value !== 'undefined' && typeof prevRotate !== 'undefined') {
                value = ((value + prevRotate) % 4);
            }
            this._dictionary.update('Rotate', value * 90);
            this._isRotated = true;
            this._rotate = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "rotate", {
        /**
         * Gets the rotation angle of the annotation (Read only).
         *
         * @returns {number} Rotation angle.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * //Get the rotation angle of the annotation.
         * let rotate: number = annotation.rotate;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            var angle = this._getRotationAngle();
            if (angle < 0) {
                angle = 360 + angle;
            }
            if (angle >= 360) {
                angle = 360 - angle;
            }
            return angle;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "flattenPopups", {
        /**
         * Gets the boolean flag indicating whether annotations popup have been flattened or not.
         *
         * @returns {boolean} Flatten Popup.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the boolean flag indicating whether annotations popup have been flattened or not.
         * let flattenPopups: boolean = annotation.flattenPopups;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._isFlattenPopups;
        },
        /**
         * Sets the boolean flag indicating whether the annotations popup have been flattened or not.
         *
         * @param {boolean} value Flatten Popup.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the boolean flag indicating whether the annotations popup have been flattened or not.
         * annotation.flattenPopups = false;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._isFlattenPopups = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "flatten", {
        /**
         * Gets the boolean flag indicating whether the annotation have been flattened or not.
         *
         * @returns {boolean} Flatten.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the boolean flag indicating whether the annotation have been flattened or not.
         * let flatten: boolean = annotation.flatten;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._flatten;
        },
        /**
         * Sets the boolean flag indicating whether the annotation have been flattened or not.
         *
         * @param {boolean} value Flatten.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the boolean flag indicating whether the annotation have been flattened or not.
         * annotation.flatten = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._flatten = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "_hasFlags", {
        /**
         * Indicates whether the annotation dictionary defines flag entries,
         * allowing consumers to detect the presence of annotation-level flags.
         *
         * @private
         * @returns {boolean} hasFlags.
         */
        get: function () {
            return this._dictionary.has('F');
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "_degreeToRadian", {
        /**
         * Converts degrees to radians on demand, initializing the cached conversion
         * ratio if necessary and returning the precomputed value for reuse.
         *
         * @private
         * @returns {number} degreeToRadian.
         */
        get: function () {
            if (typeof this._ratio === 'undefined') {
                this._ratio = Math.PI / 180;
            }
            return this._ratio;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotation.prototype, "layer", {
        /**
         * Gets the `PdfLayer` of the annotation.
         *
         * @returns {PdfLayer} PDF layer to the annotation.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Get the first page of the document
         * let page: PdfPage = document.getPage(0);
         * // Access the first annotation on the page
         * let annotation: PdfAnnotation = page.annotations.at(0);
         * // Get the layer of the annotation
         * let layer: PdfLayer = annotation.layer;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._layer) {
                this._layer = this._getDocumentLayer();
            }
            return this._layer;
        },
        /**
         * Set the `PdfLayer` to the annotation.
         *
         * @param {PdfLayer} value PDF layer to the annotation.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Get the first page of the document
         * let page: PdfPage = document.getPage(0);
         * // Access the collection of layers in the document
         * let layers: PdfLayerCollection = document.layers;
         * // Add a new layer to the document with the name 'Layer1'
         * let layer: PdfLayer = layers.add('Layer1');
         * // Access the first annotation on the page
         * let annotation: PdfAnnotation = page.annotations.at(0);
         * // Assign the layer to the annotation
         * annotation.layer = layer;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!this._layer) {
                this._layer = value;
                if (this._layer) {
                    this._dictionary.update('OC', this._layer._referenceHolder);
                }
                else {
                    delete this._dictionary._map['OC'];
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Set the boolean flag to create a new appearance stream for annotations.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Set the boolean flag to create a new appearance stream for annotations.
     * document.getPage(0).annotations.at(0).setAppearance(true);
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {boolean} value Set appearance.
     * @returns {void} Nothing.
     */
    PdfAnnotation.prototype.setAppearance = function (value) {
        this._setAppearance = value;
        if (value) {
            this._dictionary._updated = true;
        }
    };
    /**
     * Gets the values associated with the specified key.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Gets the values associated with the key 'Author'.
     * let values: string[] = document.getPage(0).annotations.at(0).getValues('Author');
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {string} name Key.
     * @returns {string[]} Values associated with the key.
     */
    PdfAnnotation.prototype.getValues = function (name) {
        var values = [];
        if (this._dictionary && this._dictionary.has(name)) {
            var value = this._dictionary.get(name); // eslint-disable-line
            if (Array.isArray(value)) {
                value = this._dictionary.getArray(name);
                value.forEach(function (element) {
                    if (element instanceof _PdfName) {
                        values.push(element.name);
                    }
                    else if (typeof element === 'string') {
                        values.push(element);
                    }
                    else if (typeof element === 'number') {
                        values.push(element.toString());
                    }
                });
            }
            else if (value instanceof _PdfName) {
                values.push(value.name);
            }
            else if (typeof value === 'string') {
                values.push(value);
            }
            else {
                throw new Error('PdfException: ' + name + ' is not found');
            }
        }
        else {
            throw new Error('PdfException: ' + name + ' is not found');
        }
        return values;
    };
    /**
     * Sets the values associated with the specified key.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Access the annotation at index 0
     * let annotation: PdfAnnotation = document.getPage(0).annotations.at(0);
     * // Set Unknown state and model
     * annotation.setValues('State', 'StateModel');
     * annotation.setValues('StateModel', 'CustomState');
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @param {string} name Key.
     * @param {string} value Value associated with the key..
     * @returns {void} Nothing.
     */
    PdfAnnotation.prototype.setValues = function (name, value) {
        if (name && name !== '' && value && value !== '') {
            this._dictionary.update(name, value);
        }
    };
    /**
     * Exports a single annotation to the specified format (XFDF or JSON).
     *
     * @private
     * @param {DataFormat} format The format to export (DataFormat.xfdf or DataFormat.json).
     * @returns {Uint8Array} Exported annotation data as byte array.
     */
    PdfAnnotation.prototype._export = function (format) {
        if (!this._page || !this._dictionary) {
            throw new Error('Annotation must be added to a page before export.');
        }
        var document = this._crossReference._document;
        var pageIndex;
        if (this._dictionary && this._dictionary.has('P')) {
            var pageDictionary = this._dictionary.get('P');
            pageIndex = _getPageIndex(document, pageDictionary);
        }
        else {
            pageIndex = this._page._pageIndex;
        }
        if (format === DataFormat.xfdf) {
            return this._exportAsXfdf(document, pageIndex);
        }
        else if (format === DataFormat.json) {
            return this._exportAsJson(document, pageIndex);
        }
        else {
            throw new Error('Unsupported export format. Use DataFormat.xfdf or DataFormat.json.');
        }
    };
    /**
     * Exports the annotation as XFDF format.
     *
     * @private
     * @param {PdfDocument} document The PDF document.
     * @param {number} pageIndex The page index.
     * @returns {Uint8Array} XFDF data as byte array.
     */
    PdfAnnotation.prototype._exportAsXfdf = function (document, pageIndex) {
        var helper = new _XfdfDocument();
        helper.exportAppearance = true;
        helper._document = document;
        helper._crossReference = document._crossReference;
        this._crossReference = document._crossReference;
        helper._isAnnotationExport = true;
        var writer = new _XmlWriter();
        writer._writeStartDocument();
        writer._writeStartElement('xfdf');
        writer._writeAttributeString(null, 'http://ns.adobe.com/xfdf/', 'xmlns', null);
        writer._writeAttributeString('space', 'preserve', 'xml', null);
        writer._writeStartElement('annots');
        this._doPostProcess(false);
        helper._exportAnnotationData(this, writer, pageIndex);
        var annotation = this; // eslint-disable-line
        if (annotation && annotation.reviewHistory && annotation.reviewHistory.count > 0) {
            for (var i = 0; i < annotation.reviewHistory.count; i++) {
                var reply = annotation.reviewHistory.at(i);
                reply._page = this._page;
                reply._doPostProcess(false);
                helper._exportAnnotationData(reply, writer, pageIndex);
            }
        }
        if (annotation && annotation.comments && annotation.comments.count > 0) {
            for (var i = 0; i < annotation.comments.count; i++) {
                var comment = annotation.comments.at(i);
                comment._page = this._page;
                comment._doPostProcess(false);
                helper._exportAnnotationData(comment, writer, pageIndex);
                var commentAnnotation = comment; // eslint-disable-line
                if (commentAnnotation && commentAnnotation.reviewHistory && commentAnnotation.reviewHistory.count > 0) {
                    for (var j = 0; j < commentAnnotation.reviewHistory.count; j++) {
                        var nestedReply = commentAnnotation.reviewHistory.at(j);
                        nestedReply._page = this._page;
                        nestedReply._doPostProcess(false);
                        helper._exportAnnotationData(nestedReply, writer, pageIndex);
                    }
                }
            }
        }
        writer._writeEndElement();
        if (!helper._asPerSpecification) {
            writer._writeStartElement('f');
            writer._writeAttributeString('href', helper._fileName || '');
            writer._writeEndElement();
        }
        writer._writeEndElement();
        var result = writer._save();
        writer._destroy();
        return result;
    };
    /**
     * Exports the annotation as JSON format.
     *
     * @private
     * @param {PdfDocument} document The PDF document.
     * @param {number} pageIndex The page index.
     * @returns {Uint8Array} JSON data as byte array.
     */
    PdfAnnotation.prototype._exportAsJson = function (document, pageIndex) {
        var _a;
        var helper = new _JsonDocument();
        helper.exportAppearance = true;
        helper._document = document;
        helper._crossReference = document._crossReference;
        this._crossReference = document._crossReference;
        helper._isAnnotationExport = true;
        var json = {
            pdfAnnotation: (_a = {},
                _a[pageIndex] = {
                    shapeAnnotation: []
                },
                _a)
        };
        this._doPostProcess(false);
        helper._table.clear();
        helper._exportAnnotation(this, pageIndex);
        json.pdfAnnotation[pageIndex].shapeAnnotation.push(JSON.parse(helper._convertToJson(helper._table)));
        var annotation = this; // eslint-disable-line
        if (annotation && annotation.reviewHistory && annotation.reviewHistory.count > 0) {
            for (var i = 0; i < annotation.reviewHistory.count; i++) {
                var reply = annotation.reviewHistory.at(i);
                reply._page = this._page;
                reply._doPostProcess(false);
                helper._table.clear();
                helper._exportAnnotation(reply, pageIndex);
                json.pdfAnnotation[pageIndex].shapeAnnotation.push(JSON.parse(helper._convertToJson(helper._table)));
            }
        }
        if (annotation && annotation.comments && annotation.comments.count > 0) {
            for (var i = 0; i < annotation.comments.count; i++) {
                var comment = annotation.comments.at(i);
                comment._page = this._page;
                comment._doPostProcess(false);
                helper._table.clear();
                helper._exportAnnotation(comment, pageIndex);
                json.pdfAnnotation[pageIndex].shapeAnnotation.push(JSON.parse(helper._convertToJson(helper._table)));
                var commentAnnotation = comment; // eslint-disable-line
                if (commentAnnotation && commentAnnotation.reviewHistory && commentAnnotation.reviewHistory.count > 0) {
                    for (var j = 0; j < commentAnnotation.reviewHistory.count; j++) {
                        var nestedReply = commentAnnotation.reviewHistory.at(j);
                        nestedReply._page = this._page;
                        nestedReply._doPostProcess(false);
                        helper._table.clear();
                        helper._exportAnnotation(nestedReply, pageIndex);
                        json.pdfAnnotation[pageIndex].shapeAnnotation.push(JSON.parse(helper._convertToJson(helper._table)));
                    }
                }
            }
        }
        var jsonString = JSON.stringify(json);
        return _stringToBytes(jsonString);
    };
    /**
     * Initializes the annotation with its owning page and dictionary,
     * assigning cross reference information and setting the page reference
     * when loading a new annotation instance.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Annotation dictionary to initialize from.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._initialize = function (page, dictionary) {
        this._page = page;
        this._crossReference = page._crossReference;
        if (dictionary) {
            this._dictionary = dictionary;
        }
        if (!this._isLoaded) {
            this._dictionary.set('P', this._page._ref);
            this._dictionary.assignXref(this._crossReference);
        }
    };
    /**
     * Retrieves the rotation angle for the annotation from its dictionary,
     * preferring `Rotate` over `Rotation`, and skipping polygon/rectangle types.
     *
     * @private
     * @returns {number} angle Rotation angle in degrees.
     */
    PdfAnnotation.prototype._getRotationAngle = function () {
        var angle = 0;
        if (this._dictionary && !(this instanceof PdfRectangleAnnotation) &&
            !(this instanceof PdfPolygonAnnotation)) {
            if (this._dictionary.has('Rotate')) {
                angle = this._dictionary.get('Rotate');
            }
            else if (this._dictionary.has('Rotation')) {
                angle = this._dictionary.get('Rotation');
            }
        }
        return angle;
    };
    /**
     * Retrieves the pages media box or crop box array, returning the media box
     * when available, otherwise falling back to the crop box definition.
     *
     * @private
     * @param {PdfPage} page Page whose box is requested.
     * @returns {number[]} box Array in the form [x, y, width, height].
     */
    PdfAnnotation.prototype._getMediaOrCropBox = function (page) {
        var cropOrMediaBox;
        if (page && page._pageDictionary && page._pageDictionary.has('MediaBox')) {
            cropOrMediaBox = page._pageDictionary.get('MediaBox');
        }
        else if (page && page._pageDictionary && page._pageDictionary.has('CropBox')) {
            cropOrMediaBox = page._pageDictionary.get('CropBox');
        }
        return cropOrMediaBox;
    };
    /**
     * Computes the bounding rectangle from a flat array of line coordinates,
     * optionally expanding the bounds by the annotations border width padding.
     *
     * @private
     * @param {number[]} linePoints Flat array of points [x1, y1, x2, y2, ...].
     * @param {number} [borderWidth] Optional border width to pad the bounds.
     * @returns {{x: number, y: number, width: number, height: number}} bounds.
     */
    PdfAnnotation.prototype._getBoundsValue = function (linePoints, borderWidth) {
        var count = 0;
        if (_isNullOrUndefined(linePoints)) {
            count = linePoints.length;
        }
        var x = [];
        var y = [];
        if (count > 0) {
            linePoints.forEach(function (value, i) {
                if (i % 2 === 0) {
                    x.push(value);
                }
                else {
                    y.push(value);
                }
            });
        }
        x.sort(function (a, b) { return a > b ? 1 : -1; });
        y.sort(function (a, b) { return a > b ? 1 : -1; });
        if (borderWidth) {
            var extraPadding = this.border.width * 2;
            return { x: x[0] - extraPadding, y: y[0] - extraPadding, width: x[x.length - 1] - x[0] + (2 * extraPadding),
                height: y[y.length - 1] - y[0] + (2 * extraPadding) };
        }
        else {
            return { x: x[0], y: y[0], width: x[x.length - 1] - x[0], height: y[y.length - 1] - y[0] };
        }
    };
    /**
     * Validates the transformation matrix for the annotations appearance stream.
     * When no template is provided, checks for identity rotation and flags location
     * displacement when applicable. When a template is provided, draws the template
     * with page graphics if offsets require it and removes the annotation; otherwise
     * leaves the annotation as-is.
     *
     * @private
     * @param {_PdfDictionary} dictionary Appearance dictionary.
     * @param {PdfTemplate} [template] Appearance template (optional).
     * @returns {boolean} valid True if matrix is valid and annotation/template kept.
     */
    PdfAnnotation.prototype._validateTemplateMatrix = function (dictionary, template) {
        var isRotatedMatrix = false;
        var isValidMatrix = true;
        if (template === null || typeof template === 'undefined') {
            if (dictionary && dictionary.has('Matrix')) {
                var matrix = dictionary.getArray('Matrix');
                if (matrix && matrix.length > 3) {
                    if (typeof matrix[0] !== 'undefined' &&
                        typeof matrix[1] !== 'undefined' &&
                        typeof matrix[2] !== 'undefined' &&
                        typeof matrix[3] !== 'undefined') {
                        if (matrix[0] === 1 && matrix[1] === 0 && matrix[2] === 0 && matrix[3] === 1) {
                            isRotatedMatrix = true;
                            var locationX = 0;
                            var locationY = 0;
                            var templateX = 0;
                            var templateY = 0;
                            if (matrix.length > 4) {
                                templateX = -matrix[4];
                                if (matrix.length > 5) {
                                    templateY = -matrix[5];
                                }
                            }
                            var annotationBounds = void 0;
                            if (this._dictionary && this._dictionary.has('Rect')) {
                                annotationBounds = this._dictionary.getArray('Rect');
                                if (annotationBounds && annotationBounds.length > 1) {
                                    locationX = annotationBounds[0];
                                    locationY = annotationBounds[1];
                                }
                            }
                            if (!(locationX === templateX && locationY === templateY) && templateX === 0 && templateY === 0) {
                                this._locationDisplaced = true;
                            }
                        }
                    }
                }
            }
            else {
                isRotatedMatrix = true;
            }
            return isRotatedMatrix;
        }
        else {
            var point = this.bounds;
            if (dictionary && dictionary.has('Matrix')) {
                var box = dictionary.getArray('BBox');
                var matrix = dictionary.getArray('Matrix');
                if (matrix && box && matrix.length > 3 && box.length > 2) {
                    if (typeof matrix[0] !== 'undefined' &&
                        typeof matrix[1] !== 'undefined' &&
                        typeof matrix[2] !== 'undefined' &&
                        typeof matrix[3] !== 'undefined') {
                        if (matrix[0] === 1 && matrix[1] === 0 && matrix[2] === 0 && matrix[3] === 1) {
                            if (typeof box[0] !== 'undefined' &&
                                typeof box[1] !== 'undefined' &&
                                typeof box[2] !== 'undefined' &&
                                typeof box[3] !== 'undefined') {
                                if (this._page && box[0] !== -(matrix[4]) && box[1] !== -(matrix[5]) ||
                                    (box[0] === 0 && -matrix[4] === 0)) {
                                    var graphics = this._page.graphics;
                                    var state = graphics.save();
                                    if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                                        graphics.setTransparency(this._opacity);
                                    }
                                    point.x -= box[0];
                                    point.y += box[1];
                                    graphics.drawTemplate(template, point);
                                    graphics.restore(state);
                                    this._page.annotations.remove(this);
                                    isValidMatrix = false;
                                }
                            }
                        }
                    }
                }
            }
            return isValidMatrix;
        }
    };
    /**
     * Flattens the annotations appearance template onto the page graphics,
     * normalizing bounds with media/crop box adjustments, handling rotation and
     * non identity matrices including rubber stamp scaling, applying opacity,
     * drawing the template, and removing the annotation from the page.
     *
     * @private
     * @param {PdfTemplate} template Appearance template to draw.
     * @param {boolean} isNormalMatrix True if the template uses an identity matrix.
     * @param {boolean} [isLineAnnotation=false] True if invoked for a line annotation.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._flattenAnnotationTemplate = function (template, isNormalMatrix, isLineAnnotation) {
        if (isLineAnnotation === void 0) { isLineAnnotation = false; }
        this._page._isLineAnnotation = isLineAnnotation;
        var graphics = this._page.graphics;
        var currentBounds = this.bounds;
        if (this instanceof PdfLineAnnotation && this._dictionary && !this._dictionary.has('AP')) {
            if (this._isLoaded) {
                currentBounds = this._bounds;
            }
            else {
                if (this instanceof PdfLineAnnotation && !this.measure) {
                    currentBounds = _toRectangle([this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height]);
                }
                else {
                    if (this._setAppearance && this.flatten && !this.measure) {
                        currentBounds = this._bounds;
                    }
                    else {
                        currentBounds = _toRectangle([this.bounds.x, this.bounds.y,
                            this.bounds.width, this.bounds.height]);
                    }
                }
            }
            if (this._page) {
                var size = this._page.size;
                var mBox = this._page.mediaBox;
                var cropBox = this._page.cropBox;
                if (cropBox && Array.isArray(cropBox) && cropBox.length === 4 && this._page._pageDictionary.has('CropBox') &&
                    !this._isLoaded && !this._flatten) {
                    if ((cropBox[0] !== 0 || cropBox[1] !== 0 || size.width === cropBox[2] ||
                        size.height === cropBox[3]) && (currentBounds.x !== cropBox[0])) {
                        currentBounds.x -= cropBox[0];
                        currentBounds.y = cropBox[3] - (currentBounds.y + currentBounds.height);
                    }
                    else {
                        currentBounds.y = size.height - (currentBounds.y + currentBounds.height);
                    }
                }
                else if (mBox && Array.isArray(mBox) && mBox.length === 4 && this._page._pageDictionary.has('MediaBox') &&
                    !this._isLoaded && !this._flatten) {
                    if (mBox[0] > 0 || mBox[1] > 0 || size.width === mBox[2] || size.height === mBox[3]) {
                        currentBounds.x -= mBox[0];
                        currentBounds.y = mBox[3] - (currentBounds.y + currentBounds.height);
                    }
                    else {
                        currentBounds.y = size.height - (currentBounds.y + currentBounds.height);
                    }
                }
                else {
                    if (this instanceof PdfLineAnnotation && !this.measure && !this._isLoaded) {
                        currentBounds.y = size.height - (currentBounds.y + currentBounds.height);
                    }
                    else {
                        if (this._setAppearance && this.flatten && !this.measure) {
                            currentBounds = this.bounds;
                        }
                        else if (!this._isLoaded) {
                            currentBounds.y = size.height - (currentBounds.y + currentBounds.height);
                        }
                    }
                }
            }
            else {
                currentBounds.y = currentBounds.y + currentBounds.height;
            }
        }
        if (typeof currentBounds !== 'undefined' && currentBounds !== null) {
            if (this._page && typeof this._page._getTemplateReservedSpace === 'function') {
                var reserved = this._page._getTemplateReservedSpace();
                if (reserved && Array.isArray(reserved) && reserved.length === 4) {
                    currentBounds.x += reserved[3];
                    currentBounds.y -= reserved[0];
                }
            }
            var state = graphics.save();
            this._page._needInitializeGraphics = true;
            if (this._type === _PdfAnnotationType.rubberStampAnnotation) {
                var needScale = true;
                if (this._dictionary && this._dictionary.has('AP')) {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        if (this.rotate === 270 && this._page.rotation === PdfRotationAngle.angle270
                            && appearanceStream && appearanceStream.dictionary
                            && appearanceStream.dictionary.has('Matrix')) {
                            var matrix = appearanceStream.dictionary.getArray('Matrix');
                            if (matrix && matrix.length === 6 && matrix[4] === 0 && matrix[5] !== 0) {
                                needScale = false;
                            }
                        }
                    }
                    if (!isNormalMatrix && this.rotate !== PdfRotationAngle.angle180 && needScale) {
                        template._isAnnotationTemplate = true;
                        template._needScale = true;
                    }
                }
            }
            if (!isNormalMatrix && this._type !== _PdfAnnotationType.rubberStampAnnotation) {
                template._isAnnotationTemplate = true;
                template._needScale = true;
            }
            if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                graphics.setTransparency(this._opacity);
            }
            var bounds = this._calculateTemplateBounds(currentBounds, this._page, template, isNormalMatrix, graphics);
            if (this._type === _PdfAnnotationType.rubberStampAnnotation) {
                var size = void 0;
                var location_1;
                if (this.rotate === PdfRotationAngle.angle0) {
                    size = { width: bounds.width, height: bounds.height };
                    location_1 = [bounds.x, bounds.y];
                }
                else {
                    size = template._size;
                    location_1 = [bounds.x, bounds.y];
                }
                var isRotatedMatrix = false;
                if (this.rotate !== PdfRotationAngle.angle0 && template._content) {
                    if (template._content.dictionary.has('Matrix')) {
                        var matrix = template._content.dictionary.getArray('Matrix');
                        if (matrix && matrix.length === 6 && matrix[4] === 0 && matrix[5] !== 0) {
                            isRotatedMatrix = true;
                        }
                    }
                }
                var scaleX = (template._size.width > 0) ? bounds.width / template._size.width : 1;
                var scaleY = (template._size.height > 0) ? bounds.height / template._size.height : 1;
                var needScale = !(Math.trunc(scaleX * 1000) / 1000 === 1 && Math.trunc(scaleY * 1000) / 1000 === 1);
                if (this.rotate !== PdfRotationAngle.angle0 && isRotatedMatrix) {
                    if (this.rotate === PdfRotationAngle.angle90) {
                        if (this._page && this._page.rotation === PdfRotationAngle.angle270) {
                            if (needScale && !(bounds.x === 0 && bounds.y === 0)) {
                                location_1[0] += (size.width - size.height);
                                location_1[1] += size.width;
                            }
                            else {
                                location_1[0] += size.height;
                                location_1[1] += (size.width - size.height) + (size.width - size.height);
                            }
                        }
                        else if (!needScale) {
                            location_1[0] += size.height;
                        }
                    }
                    else if (this.rotate === PdfRotationAngle.angle270) {
                        if (this._page && this._page.rotation === PdfRotationAngle.angle270) {
                            if (needScale && template._isAnnotationTemplate) {
                                location_1[1] = bounds.y - bounds.width;
                            }
                            else if (needScale) {
                                location_1[1] += (size.width - size.height);
                            }
                        }
                        else {
                            if (!needScale && !(bounds.x === 0 && bounds.y === 0)) {
                                location_1[1] += -(size.width);
                            }
                            else {
                                location_1[1] += -(size.width - size.height);
                            }
                        }
                    }
                    else if (this.rotate === PdfRotationAngle.angle180) {
                        location_1[0] += size.width;
                        location_1[1] += -(size.height);
                    }
                }
            }
            if (!template._content.dictionary.has('Matrix') && template._content.dictionary.has('BBox')) {
                var box = template._content.dictionary.getArray('BBox');
                bounds.x -= box[0];
                bounds.y += box[1];
            }
            if (this instanceof PdfAngleMeasurementAnnotation && !this._isLoaded) {
                bounds = _calculateBounds(this._dictionary, this._page);
            }
            graphics.drawTemplate(template, bounds);
            graphics.restore(state);
        }
        this._page.annotations.remove(this);
    };
    /* eslint-disable */
    /**
     * Computes the templates final drawing bounds on the page by considering the page graphics rotation,
     * annotation rotation, and non identity matrices, applying the necessary transforms and size swaps.
     *
     * @private
     * @param {{x: number, y: number, width: number, height: number}} bounds Annotation bounds in page space. // eslint-disable-line
     * @param {PdfPage} page Page to draw on.
     * @param {PdfTemplate} template Appearance template.
     * @param {boolean} isNormalMatrix True when the template uses identity matrix.
     * @param {PdfGraphics} graphics Target graphics.
     * @returns {{x: number, y: number, width: number, height: number}} computedBounds.
     */
    PdfAnnotation.prototype._calculateTemplateBounds = function (bounds, page, template, isNormalMatrix, graphics) {
        var annotationBounds = bounds;
        var x = bounds.x;
        var y = bounds.y;
        var width = bounds.width;
        var height = bounds.height;
        if (!isNormalMatrix) {
            var rect = this._dictionary.getArray('Rect');
            if (rect) {
                annotationBounds = _toRectangle(rect);
            }
        }
        if (typeof page !== 'undefined') {
            var graphicsRotation = this._obtainGraphicsRotation(graphics._matrix);
            if (graphicsRotation === 90) {
                graphics.translateTransform({ x: template._size.height, y: 0 });
                graphics.rotateTransform(90);
                if (isNormalMatrix || (typeof this._rotate !== 'undefined' && this._rotate === PdfRotationAngle.angle180)) {
                    x = bounds.x;
                    if (!this._locationDisplaced) {
                        y = -(page.size.height - bounds.y - bounds.height);
                    }
                    else if (page._origin && page._o[1] !== 0) {
                        y = bounds.y + bounds.height;
                    }
                    else {
                        y = -(page.size.height - (bounds.height + bounds.y) + (bounds.height - template._size.height));
                    }
                }
                else {
                    x = bounds.x;
                    y = -(page.size.height - (bounds.height + bounds.y) + (bounds.width - template._size.height));
                    width = bounds.height;
                    height = bounds.width;
                }
            }
            else if (graphicsRotation === 180) {
                graphics.translateTransform({ x: template._size.width, y: template._size.height });
                graphics.rotateTransform(180);
                if (isNormalMatrix) {
                    x = -(page.size.width - (bounds.x + bounds.width));
                    y = -(page.size.height - bounds.y - bounds.height);
                }
                else {
                    x = -(page.size.width - (bounds.x + template._size.width));
                    y = -(page.size.height - bounds.y - template._size.height);
                    if (typeof this.rotationAngle !== 'undefined' &&
                        (this._rotate === PdfRotationAngle.angle90 ||
                            this._rotate === PdfRotationAngle.angle270)) {
                        y = (-(page.size.height - bounds.y - template._size.height) - (bounds.width - bounds.height));
                        width = bounds.height;
                        height = bounds.width;
                    }
                }
            }
            else if (graphicsRotation === 270) {
                graphics.translateTransform({ x: 0, y: template._size.width });
                graphics.rotateTransform(270);
                if (isNormalMatrix || (typeof this.rotationAngle !== 'undefined' && this._rotate === PdfRotationAngle.angle180)) {
                    x = -(page.size.width - bounds.x - bounds.width);
                    y = bounds.y;
                }
                else {
                    x = -(page.size.width - annotationBounds.x - template._size.width);
                    var matrix = template._content.dictionary.getArray('Matrix');
                    var box = template._content.dictionary.getArray('BBox');
                    if (matrix && box && matrix[5] !== box[2]) {
                        y = bounds.y - (bounds.height - bounds.width);
                    }
                    else {
                        y = (bounds.y + bounds.height) - bounds.width;
                    }
                    width = bounds.height;
                    height = bounds.width;
                }
            }
            else if (graphicsRotation === 0) {
                if (!isNormalMatrix &&
                    (typeof this.rotationAngle !== 'undefined' &&
                        (this.rotationAngle === PdfRotationAngle.angle90 ||
                            this.rotationAngle === PdfRotationAngle.angle270))) {
                    x = bounds.x;
                    y = (bounds.y + bounds.height - bounds.width);
                    width = bounds.height;
                    height = bounds.width;
                }
            }
        }
        return { x: x, y: y, width: width, height: height };
    };
    /* eslint-enable */
    /**
     * Derives the graphics rotation angle in degrees from the transformation matrix and normalizes it to standard orientations.
     *
     * @private
     * @param {_PdfTransformationMatrix} matrix Graphics transformation matrix.
     * @returns {number} angle Rotation angle in degrees (0, 90, 180, 270).
     */
    PdfAnnotation.prototype._obtainGraphicsRotation = function (matrix) {
        var radians = Math.atan2(matrix._matrix._elements[2], matrix._matrix._elements[0]);
        var angle = Math.round(radians * 180 / Math.PI);
        switch (angle) {
            case -90:
                angle = 90;
                break;
            case -180:
                angle = 180;
                break;
            case 90:
                angle = 270;
                break;
        }
        return angle;
    };
    /**
     * Removes the specified annotation from the given page and marks the page dictionary as updated.
     *
     * @private
     * @param {PdfPage} page Page from which to remove the annotation.
     * @param {PdfAnnotation} annotation Annotation to remove.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._removeAnnotation = function (page, annotation) {
        if (page && annotation) {
            page.annotations.remove(annotation);
            page._pageDictionary._updated = true;
        }
    };
    /**
     * Draws a cloud-style path along the given polyline by laying out overlapping circular arcs (using radius/overlap),
     * resolving arc angles, building the path in appearance or page space, and rendering it with the provided brush/pen.
     *
     * @private
     * @param {PdfGraphics} graphics Target graphics.
     * @param {PdfBrush} brush Fill brush (optional).
     * @param {PdfPen} pen Stroke pen.
     * @param {number} radius Arc radius.
     * @param {number} overlap Overlap factor (0..1).
     * @param {Array<Point>} points Polyline points.
     * @param {boolean} isAppearance True if drawing in appearance space.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawCloudStyle = function (graphics, brush, pen, radius, overlap, points, isAppearance) {
        if (_isNullOrUndefined(points) && this._isClockWise(points)) {
            points.reverse();
        }
        var circles = [];
        var circleOverlap = 2 * radius * overlap;
        var previousPoint;
        if (_isNullOrUndefined(points)) {
            previousPoint = points[points.length - 1];
        }
        else {
            points = [];
        }
        for (var i = 0; i < points.length; i++) {
            var currentPoint = points[i];
            var dx = currentPoint.x - previousPoint.x;
            var dy = currentPoint.y - previousPoint.y;
            var length_1 = Math.sqrt(dx * dx + dy * dy);
            dx = dx / length_1;
            dy = dy / length_1;
            for (var a = 0; a + 0.1 * circleOverlap < length_1; a += circleOverlap) {
                var cur = new _CloudStyleArc();
                cur.point = { x: previousPoint.x + a * dx, y: previousPoint.y + a * dy };
                circles.push(cur);
            }
            previousPoint = currentPoint;
        }
        var previousCurvedStyleArc = circles[circles.length - 1];
        for (var i = 0; i < circles.length; i++) {
            var currentCurvedStyleArc = circles[i];
            var angle = this._getIntersectionDegrees([previousCurvedStyleArc.point.x, previousCurvedStyleArc.point.y], [currentCurvedStyleArc.point.x, currentCurvedStyleArc.point.y], radius);
            previousCurvedStyleArc.endAngle = angle[0];
            currentCurvedStyleArc.startAngle = angle[1];
            previousCurvedStyleArc = currentCurvedStyleArc;
        }
        var path = new PdfPath();
        for (var i = 0; i < circles.length; i++) {
            var current = circles[i];
            var startAngle = current.startAngle % 360;
            var endAngle = current.endAngle % 360;
            var sweepAngel = 0;
            if (startAngle > 0 && endAngle < 0) {
                sweepAngel = (180 - startAngle) + (180 - (endAngle < 0 ? -endAngle : endAngle));
            }
            else if (startAngle < 0 && endAngle > 0) {
                sweepAngel = -startAngle + endAngle;
            }
            else if (startAngle > 0 && endAngle > 0) {
                var difference = 0;
                if (startAngle > endAngle) {
                    difference = startAngle - endAngle;
                    sweepAngel = 360 - difference;
                }
                else {
                    sweepAngel = endAngle - startAngle;
                }
            }
            else if (startAngle < 0 && endAngle < 0) {
                var difference = 0;
                if (startAngle > endAngle) {
                    difference = startAngle - endAngle;
                    sweepAngel = 360 - difference;
                }
                else {
                    sweepAngel = -(startAngle + (-endAngle));
                }
            }
            if (sweepAngel < 0) {
                sweepAngel = -sweepAngel;
            }
            current.endAngle = sweepAngel;
            path.addArc({ x: current.point.x - radius, y: current.point.y - radius,
                width: 2 * radius, height: 2 * radius }, startAngle, sweepAngel);
        }
        path.closeFigure();
        var tempPoints = [];
        if (isAppearance) {
            tempPoints = path._points.map(function (point) { return ({ x: point.x, y: -point.y }); });
        }
        var pdfpath;
        if (isAppearance) {
            pdfpath = new PdfPath();
            pdfpath._points = tempPoints;
            pdfpath._pathTypes = path._pathTypes;
        }
        else {
            pdfpath = new PdfPath();
            pdfpath._points = path._points;
            pdfpath._pathTypes = path._pathTypes;
        }
        if (_isNullOrUndefined(brush)) {
            graphics.drawPath(pdfpath, brush);
        }
        var incise = 180 / (Math.PI * 3);
        path = new PdfPath();
        for (var i = 0; i < circles.length; i++) {
            var current = circles[i];
            path.addArc({ x: current.point.x - radius,
                y: current.point.y - radius,
                width: 2 * radius,
                height: 2 * radius }, current.startAngle, current.endAngle + incise);
        }
        path.closeFigure();
        tempPoints = [];
        if (isAppearance) {
            tempPoints = path._points.map(function (point) { return ({ x: point.x, y: -point.y }); });
        }
        if (isAppearance) {
            pdfpath = new PdfPath();
            pdfpath._points = tempPoints;
            pdfpath._pathTypes = path._pathTypes;
        }
        else {
            pdfpath = new PdfPath();
            pdfpath._points = path._points;
            pdfpath._pathTypes = path._pathTypes;
        }
        graphics.drawPath(pdfpath, pen);
    };
    /**
     * Determines whether the given polygon/polyline points are ordered clockwise using a signed edge-sum test.
     *
     * @private
     * @param {Array<Point>} points Points of polygon/polyline.
     * @returns {boolean} isClockwise.
     */
    PdfAnnotation.prototype._isClockWise = function (points) {
        var sum = 0;
        if (_isNullOrUndefined(points)) {
            for (var i = 0; i < points.length; i++) {
                var first = points[i];
                var second = points[(i + 1) % points.length];
                sum += (second.x - first.x) * (second.y + first.y);
            }
        }
        return sum > 0;
    };
    /**
     * Computes the pair of intersection angles in degrees between two points
     * for a circle of the given radius, returning [startAngle, endAngle].
     *
     * @private
     * @param {number[]} first First point as [x, y].
     * @param {number[]} second Second point as [x, y].
     * @param {number} radius Circle radius.
     * @returns {number[]} degreesPair [startAngle, endAngle] in degrees.
     */
    PdfAnnotation.prototype._getIntersectionDegrees = function (first, second, radius) {
        var dx = second[0] - first[0];
        var dy = second[1] - first[1];
        var length = Math.sqrt(dx * dx + dy * dy);
        var a = 0.5 * length / radius;
        if (a < -1) {
            a = -1;
        }
        else if (a > 1) {
            a = 1;
        }
        var radian = Math.atan2(dy, dx);
        var cosvalue = Math.acos(a);
        return [(radian - cosvalue) * (180 / Math.PI), (Math.PI + radian + cosvalue) * (180 / Math.PI)];
    };
    /**
     * Applies border style settings like dash/dash pattern and adjusts the given rectangle based on border width,
     * dictionary RD insets, and the provided parameter (paint bounds or cloudy effect), then returns the updated bounds.
     *
     * @private
     * @param {PdfPen} borderPen Border pen (modified when dashes are present).
     * @param {number[]} rectangle Rectangle as [x, y, width, height] (updated in place).
     * @param {number} borderWidth Half of border width.
     * @param {PdfBorderEffect|_PaintParameter} [parameter] Optional border effect or paint parameter.
     * @returns {number[]} rect Updated rectangle [x, y, width, height].
     */
    PdfAnnotation.prototype._obtainStyle = function (borderPen, rectangle, borderWidth, parameter) {
        var dash = this.border.dash;
        if (dash && dash.length > 0) {
            var isDash = false;
            var dashPattern = dash.slice();
            isDash = dash.some(function (value) { return value > 0; });
            if (isDash && this.border.style === PdfBorderStyle.dashed) {
                borderPen._dashStyle = PdfDashStyle.dash;
                borderPen._dashPattern = dashPattern;
            }
        }
        if (parameter) {
            if (parameter instanceof _PaintParameter) {
                if (!this._isBounds && this._dictionary.has('RD')) {
                    var array = this._dictionary.getArray('RD');
                    if (array) {
                        rectangle[0] = rectangle[0] + array[0];
                        rectangle[1] = rectangle[1] + borderWidth + array[1];
                        rectangle[2] = rectangle[2] - (array[0] + array[2]);
                        rectangle[3] = rectangle[3] - (array[1] + array[3]);
                    }
                }
                else {
                    rectangle[0] = rectangle[0] + borderWidth;
                    rectangle[1] = rectangle[1] + borderWidth;
                    rectangle[2] = rectangle[2] - this.border.width;
                    rectangle[3] = rectangle[3] - this.border.width;
                }
                parameter.bounds = { x: rectangle[0], y: rectangle[1], width: rectangle[2], height: rectangle[3] };
            }
            else {
                if (parameter.intensity !== 0 && parameter.style === PdfBorderEffectStyle.cloudy) {
                    var radius = parameter.intensity * 5;
                    rectangle[0] = rectangle[0] + radius + borderWidth;
                    rectangle[1] = rectangle[1] + radius + borderWidth;
                    rectangle[2] = rectangle[2] - (2 * radius) - 2 * borderWidth;
                    rectangle[3] = rectangle[3] - (2 * radius) - 2 * borderWidth;
                }
                else {
                    rectangle[0] = rectangle[0] + borderWidth;
                    rectangle[1] = rectangle[1] + borderWidth;
                    rectangle[2] = rectangle[2] - this.border.width;
                    rectangle[3] = this.bounds.height - this.border.width;
                }
            }
        }
        else {
            if (!this._isBounds && this._dictionary && this._dictionary.has('RD')) {
                var array = this._dictionary.getArray('RD');
                if (array) {
                    rectangle[0] = rectangle[0] + array[0];
                    rectangle[1] = rectangle[1] + borderWidth + array[1];
                    rectangle[2] = rectangle[2] - (2 * array[2]);
                    rectangle[3] = rectangle[3] - this.border.width;
                    rectangle[3] = rectangle[3] - (2 * array[3]);
                }
            }
            else {
                rectangle[1] = rectangle[1] + borderWidth;
                rectangle[3] = this.bounds.height - this.border.width;
            }
        }
        return rectangle;
    };
    /**
     * Creates the normal appearance template for a rectangle annotation, updating RD/bounds for cloudy effects,
     * configuring pens/brushes and opacity, and drawing either a clouded or standard rectangle.
     *
     * @private
     * @param {PdfBorderEffect} borderEffect Border effect (cloudy) definition.
     * @returns {PdfTemplate} template Appearance template.
     */
    PdfAnnotation.prototype._createRectangleAppearance = function (borderEffect) {
        var width = this.border.width;
        var rdArray = this._dictionary.getArray('RD');
        if (!rdArray && borderEffect !== null && typeof borderEffect !== 'undefined' && borderEffect.intensity !== 0 && borderEffect.style === PdfBorderEffectStyle.cloudy) {
            var cloudRectangle = { x: this.bounds.x - borderEffect.intensity * 5 - width / 2,
                y: this.bounds.y - borderEffect.intensity * 5 - width / 2,
                width: this.bounds.width + borderEffect.intensity * 10 + width,
                height: this.bounds.height + borderEffect.intensity * 10 + width };
            var radius = borderEffect.intensity * 5;
            rdArray = [radius + width / 2, radius + width / 2, radius + width / 2, radius + width / 2];
            this._dictionary.set('RD', rdArray);
            this.bounds = cloudRectangle;
        }
        if (!this._isBounds && rdArray) {
            var cloudRectangle = { x: this.bounds.x + rdArray[0],
                y: this.bounds.y + rdArray[1],
                width: this.bounds.width - rdArray[2] * 2,
                height: this.bounds.height - rdArray[3] * 2 };
            if (borderEffect.intensity !== 0 && borderEffect.style === PdfBorderEffectStyle.cloudy) {
                cloudRectangle.x = cloudRectangle.x - borderEffect.intensity * 5 - width / 2;
                cloudRectangle.y = cloudRectangle.y - borderEffect.intensity * 5 - width / 2;
                cloudRectangle.width = cloudRectangle.width + borderEffect.intensity * 10 + width;
                cloudRectangle.height = cloudRectangle.height + borderEffect.intensity * 10 + width;
                var radius = borderEffect.intensity * 5;
                this._dictionary.set('RD', [radius + width / 2, radius + width / 2, radius + width / 2, radius + width / 2]);
            }
            else {
                delete this._dictionary._map.RD;
            }
            this.bounds = cloudRectangle;
        }
        var borderWidth = width / 2;
        var nativeRectangle = [0, 0, this.bounds.width, this.bounds.height];
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
        }
        else {
            template = new PdfTemplate(nativeRectangle, this._crossReference);
            _setMatrix(template, this._getRotationAngle());
            if (borderEffect.intensity !== 0 && borderEffect.style === PdfBorderEffectStyle.cloudy) {
                template._writeTransformation = false;
            }
            var graphics = template.graphics;
            var parameter = new _PaintParameter();
            if (this.innerColor) {
                parameter.backBrush = new PdfBrush(this._innerColor);
            }
            if (width > 0 && this.color) {
                parameter.borderPen = new PdfPen(this._color, width);
            }
            if (this.color) {
                parameter.foreBrush = new PdfBrush(this._color);
            }
            var rectangle = this._obtainStyle(parameter.borderPen, nativeRectangle, borderWidth, borderEffect);
            if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                graphics.save();
                graphics.setTransparency(this._opacity);
            }
            if (borderEffect.intensity !== 0 && borderEffect.style === PdfBorderEffectStyle.cloudy) {
                this._drawRectangleAppearance(rectangle, graphics, parameter, borderEffect.intensity);
            }
            else {
                graphics.drawRectangle({ x: rectangle[0], y: rectangle[1],
                    width: rectangle[2], height: rectangle[3] }, parameter.borderPen, parameter.backBrush);
            }
            if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                graphics.restore();
            }
        }
        return template;
    };
    /**
     * Renders a rectangle annotation appearance, using a cloudy outline when intensity produces a positive radius,
     * otherwise drawing a standard rectangle with the provided pen and brush.
     *
     * @private
     * @param {number[]} rectangle Rectangle [x, y, width, height] in template space.
     * @param {PdfGraphics} graphics Target graphics.
     * @param {_PaintParameter} parameter Paint parameter containing pen/brush.
     * @param {number} intensity Cloudy intensity (affects radius).
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawRectangleAppearance = function (rectangle, graphics, parameter, intensity) {
        var graphicsPath = new PdfPath();
        if (_isNullOrUndefined(rectangle) && rectangle.length === 4) {
            graphicsPath.addRectangle({ x: rectangle[0], y: rectangle[1], width: rectangle[2], height: rectangle[3] });
        }
        var radius = 0;
        if (_isNullOrUndefined(intensity)) {
            radius = intensity * 4.25;
        }
        if (radius > 0) {
            var points = graphicsPath._points.map(function (point) { return ({ x: point.x, y: -point.y }); });
            graphicsPath = new PdfPath();
            graphicsPath.addPolygon(points);
            this._drawCloudStyle(graphics, parameter.backBrush, parameter.borderPen, radius, 0.833, graphicsPath._points, false);
        }
        else {
            graphics.drawRectangle({ x: rectangle[0], y: rectangle[1],
                width: rectangle[2], height: rectangle[3] }, parameter.borderPen, parameter.backBrush);
        }
    };
    /**
     * Creates the normal appearance template for a circle/ellipse annotation, configuring dash styles and brushes,
     * adjusting bounds via border insets, handling opacity and BE effects, and drawing the ellipse.
     *
     * @private
     * @returns {PdfTemplate} template Appearance template.
     */
    PdfAnnotation.prototype._createCircleAppearance = function () {
        var nativeBounds = [0, 0, this.bounds.width, this.bounds.height];
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
        }
        else {
            template = new PdfTemplate(nativeBounds, this._crossReference);
            _setMatrix(template, this._getRotationAngle(), this);
            if (this._dictionary.has('BE')) {
                template._writeTransformation = false;
            }
            if (typeof this.color === 'undefined') {
                this._isTransparentColor = true;
            }
            var graphics = template.graphics;
            var width = this.border.width;
            var borderPen = new PdfPen(this.color, width);
            if (this.border.style === PdfBorderStyle.dashed) {
                borderPen._dashStyle = PdfDashStyle.dash;
                borderPen._dashPattern = [3, 1];
            }
            else if (this.border.style === PdfBorderStyle.dot) {
                borderPen._dashStyle = PdfDashStyle.dot;
                borderPen._dashPattern = [1, 1];
            }
            var parameter = new _PaintParameter();
            if (this.innerColor) {
                parameter.backBrush = new PdfBrush(this._innerColor);
            }
            if (width > 0) {
                parameter.borderPen = borderPen;
            }
            if (this.color) {
                parameter.foreBrush = new PdfBrush(this._color);
            }
            parameter.borderWidth = width;
            var borderWidth = width / 2;
            var rectangle = this._obtainStyle(borderPen, nativeBounds, borderWidth);
            if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                graphics.save();
                graphics.setTransparency(this._opacity);
            }
            if (this._dictionary.has('BE')) {
                this._drawCircleAppearance(rectangle, borderWidth, graphics, parameter);
            }
            else {
                graphics.drawEllipse({ x: rectangle[0] + borderWidth,
                    y: rectangle[1],
                    width: rectangle[2] - width,
                    height: rectangle[3] }, parameter.borderPen, parameter.backBrush);
            }
            if (typeof this._opacity !== 'undefined' && this._opacity < 1) {
                graphics.restore();
            }
        }
        return template;
    };
    /**
     * Draws the circle/ellipse annotation appearance, using a cloudy outline when an RD-derived radius is present;
     * otherwise renders a standard ellipse with the given border width, pen, and brush.
     *
     * @private
     * @param {number[]} rectangle Rectangle [x, y, width, height] in template space.
     * @param {number} borderWidth Half of border width.
     * @param {PdfGraphics} graphics Target graphics.
     * @param {_PaintParameter} parameter Paint parameter with pen/brush.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawCircleAppearance = function (rectangle, borderWidth, graphics, parameter) {
        var radius = 0;
        if (this._dictionary.has('RD')) {
            var array = this._dictionary.getArray('RD');
            if (array && array.length > 0) {
                radius = array[0];
            }
        }
        if (radius > 0) {
            var rect = [rectangle[0] + borderWidth,
                -rectangle[1] - rectangle[3],
                rectangle[2] - this.border.width,
                rectangle[3]];
            var left = rect[0];
            var top_1 = rect[1];
            var right = rect[0] + rect[2];
            var bottom = rect[1] + rect[3];
            var controlPointList = [];
            controlPointList.push([right, bottom]);
            controlPointList.push([left, bottom]);
            controlPointList.push([left, top_1]);
            controlPointList.push([right, top_1]);
            var startPointList = [];
            startPointList.push([right, top_1 + (rect[3] / 2)]);
            startPointList.push([left + rect[2] / 2, bottom]);
            startPointList.push([left, top_1 + (rect[3] / 2)]);
            startPointList.push([left + (rect[2] / 2), top_1]);
            var endPointList = [];
            endPointList.push([left + rect[2] / 2, bottom]);
            endPointList.push([left, top_1 + (rect[3] / 2)]);
            endPointList.push([left + (rect[2] / 2), top_1]);
            endPointList.push([right, top_1 + (rect[3] / 2)]);
            var points = [];
            for (var i = 0; i < controlPointList.length; i++) {
                this._createBezier(startPointList[i], controlPointList[i], endPointList[i], points);
            }
            this._drawCloudStyle(graphics, parameter.backBrush, parameter.borderPen, radius, 0.833, points.map(function (_a) {
                var x = _a[0], y = _a[1];
                return ({ x: x, y: y });
            }), false); // eslint-disable-line
        }
        else {
            graphics.drawEllipse({ x: rectangle[0] + borderWidth,
                y: -rectangle[1],
                width: rectangle[2] - this.border.width,
                height: -rectangle[3] }, parameter.borderPen, parameter.backBrush);
        }
    };
    /**
     * Generates Bezier points between the given start and end knots using the control point,
     * seeding both endpoints and delegating subdivision to the internal routine, and appends them to the output list.
     *
     * @private
     * @param {number[]} first Start point [x, y].
     * @param {number[]} second Control point [x, y].
     * @param {number[]} third End point [x, y].
     * @param {Array<number[]>} bezierPoints Output array to receive points.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._createBezier = function (first, second, third, bezierPoints) {
        bezierPoints.push(first);
        this._populateBezierPoints(first, second, third, 0, bezierPoints);
        bezierPoints.push(third);
    };
    /**
     * Recursively subdivides a quadratic Bézier segment using midpoints to refine the curve up to the iteration limit,
     * appending the computed midpoints to the output list.
     *
     * @private
     * @param {number[]} first Start point [x, y].
     * @param {number[]} second Control point [x, y].
     * @param {number[]} third End point [x, y].
     * @param {number} currentIteration Current iteration count.
     * @param {Array<number[]>} bezierPoints Output point array.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._populateBezierPoints = function (first, second, third, currentIteration, bezierPoints) {
        if (currentIteration < 2) {
            var midPoint1 = this._midPoint(first, second);
            var midPoint2 = this._midPoint(second, third);
            var midPoint3 = this._midPoint(midPoint1, midPoint2);
            currentIteration++;
            this._populateBezierPoints(first, midPoint1, midPoint3, currentIteration, bezierPoints);
            bezierPoints.push(midPoint3);
            this._populateBezierPoints(midPoint3, midPoint2, third, currentIteration, bezierPoints);
        }
    };
    /**
     * Computes the midpoint between two 2D points represented as [x, y] coordinate arrays.
     *
     * @private
     * @param {number[]} first First point [x, y].
     * @param {number[]} second Second point [x, y].
     * @returns {number[]} midpoint [x, y].
     */
    PdfAnnotation.prototype._midPoint = function (first, second) {
        return [(first[0] + second[0]) / 2, (first[1] + second[1]) / 2];
    };
    /**
     * Calculates the absolute angle in degrees of a line defined by two points, normalizing to the range 0..360 and handling vertical lines.
     *
     * @private
     * @param {Point[]} linePoints Two points defining a line.
     * @returns {number} angle Angle in degrees.
     */
    PdfAnnotation.prototype._getAngle = function (linePoints) {
        var x1 = linePoints[0].x;
        var y1 = linePoints[0].y;
        var x2 = linePoints[1].x;
        var y2 = linePoints[1].y;
        var angle = 0;
        if (x2 - x1 === 0) {
            angle = (y2 > y1) ? 90 : 270;
        }
        else {
            var angleRatio = (y2 - y1) / (x2 - x1);
            var radians = Math.atan(angleRatio);
            angle = radians * (180 / Math.PI);
            if ((x2 - x1) < 0 || (y2 - y1) < 0) {
                angle += 180;
            }
            if ((x2 - x1) > 0 && (y2 - y1) < 0) {
                angle -= 180;
            }
            if (angle < 0) {
                angle += 360;
            }
        }
        return angle;
    };
    /**
     * Computes a new point by offsetting the given coordinate by the specified angle and optional length using degree-to-radian conversion.
     *
     * @private
     * @param {Point} value Base coordinate.
     * @param {number} angle Angle in degrees.
     * @param {number} [length] Offset length (defaults to 0).
     * @returns {Point} point New coordinate.
     */
    PdfAnnotation.prototype._getAxisValue = function (value, angle, length) {
        if (length === null || typeof length === 'undefined') {
            length = 0;
        }
        return { x: value.x + Math.cos(angle * this._degreeToRadian) * length,
            y: value.y + Math.sin(angle * this._degreeToRadian) * length };
    };
    /**
     * Computes the geometry for an open arrowhead at the lines begin or end.
     *
     * @private
     * @param {boolean} isBegin True for begin, false for end.
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{startPoint: Point, first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareOpenArrow = function (isBegin, axisPoint, angle, length) {
        var arraowAngle = isBegin ? 30 : 150;
        var count = 9 * length;
        var startPoint = this._getAxisValue(axisPoint, angle, (isBegin ? length : (-length)));
        var first = this._getAxisValue(startPoint, (angle + arraowAngle), count);
        var second = this._getAxisValue(startPoint, (angle - arraowAngle), count);
        return { startPoint: startPoint, first: first, second: second };
    };
    /**
     * Computes the geometry for a reverse open arrowhead at the lines begin or end.
     *
     * @private
     * @param {boolean} isBegin True for begin, false for end.
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{startPoint: Point, first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareReverseOpenArrow = function (isBegin, axisPoint, angle, length) {
        var arraowAngle = isBegin ? 150 : 30;
        var count = 9 * length;
        var startPoint = this._getAxisValue(axisPoint, angle, (isBegin ? (-length) : length));
        var first = this._getAxisValue(startPoint, (angle + arraowAngle), count);
        var second = this._getAxisValue(startPoint, (angle - arraowAngle), count);
        return { startPoint: startPoint, first: first, second: second };
    };
    /**
     * Computes the geometry for a closed arrowhead at the lines begin or end.
     *
     * @private
     * @param {boolean} isBegin True for begin, false for end.
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{startPoint: Point, first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareClosedArrow = function (isBegin, axisPoint, angle, length) {
        var arraowAngle = isBegin ? 30 : 150;
        var count = 9 * length;
        var startPoint = this._getAxisValue(axisPoint, angle, (isBegin ? length : (-length)));
        var first = this._getAxisValue(startPoint, (angle + arraowAngle), count);
        var second = this._getAxisValue(startPoint, (angle - arraowAngle), count);
        return { startPoint: startPoint, first: first, second: second };
    };
    /**
     * Computes the geometry for a reverse closed arrowhead at the lines begin or end.
     *
     * @private
     * @param {boolean} isBegin True for begin, false for end.
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{startPoint: Point, first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareReverseCloseArrow = function (isBegin, axisPoint, angle, length) {
        var arraowAngle = isBegin ? 150 : 30;
        var count = 9 * length;
        var startPoint = this._getAxisValue(axisPoint, angle, (isBegin ? (-length) : length));
        var first = this._getAxisValue(startPoint, (angle + arraowAngle), count);
        var second = this._getAxisValue(startPoint, (angle - arraowAngle), count);
        return { startPoint: startPoint, first: first, second: second };
    };
    /**
     * Computes the two points of a slash marker relative to the axis point by offsetting at angle ± fixed offsets scaled by the given length.
     *
     * @private
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareSlash = function (axisPoint, angle, length) {
        var count = 9 * length;
        var first = this._getAxisValue(axisPoint, (angle + 60), count);
        var second = this._getAxisValue(axisPoint, (angle - 120), count);
        return { first: first, second: second };
    };
    /**
     * Computes the four vertices of a diamond centered at the axis point by offsetting at 0°, 90°, 180°, scaled by the given length.
     *
     * @private
     * @param {Point} axisPoint Axis point.
     * @param {number} length Marker length unit.
     * @returns {{first: Point, second: Point, third: Point, fourth: Point}} points.
     */
    PdfAnnotation.prototype._prepareDiamond = function (axisPoint, length) {
        var count = 3 * length;
        var first = this._getAxisValue(axisPoint, 180, count);
        var second = this._getAxisValue(axisPoint, 90, count);
        var third = this._getAxisValue(axisPoint, 0, count);
        var fourth = this._getAxisValue(axisPoint, -90, count);
        return { first: first, second: second, third: third, fourth: fourth };
    };
    /**
     * Computes the two points of a butt marker relative to the axis point by offsetting at angle ±90°, scaled by the given length.
     *
     * @private
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {number} length Marker length unit.
     * @returns {{first: Point, second: Point}} points.
     */
    PdfAnnotation.prototype._prepareButt = function (axisPoint, angle, length) {
        var count = 3 * length;
        var first = this._getAxisValue(axisPoint, (angle + 90), count);
        var second = this._getAxisValue(axisPoint, (angle - 90), count);
        return { first: first, second: second };
    };
    /**
     * Computes the bounding rectangle for the specified line ending style at the given axis point and angle,
     * using the provided pen, length, and begin/end flag.
     *
     * @private
     * @param {Point} axisPoint Axis point.
     * @param {number} angle Angle in degrees.
     * @param {PdfPen} pen Pen used to draw (for path metrics).
     * @param {PdfLineEndingStyle} style Line ending style.
     * @param {number} length Marker length unit.
     * @param {boolean} isBegin True if begin marker.
     * @returns {{x: number, y: number, width: number, height: number}} bounds.
     */
    PdfAnnotation.prototype._getBoundsFromLineEndStyle = function (axisPoint, angle, pen, style, length, isBegin) {
        var result;
        var path;
        var bounds;
        var values; // eslint-disable-line
        switch (style) {
            case PdfLineEndingStyle.square:
            case PdfLineEndingStyle.circle:
                result = { x: axisPoint.x - (3 * length),
                    y: axisPoint.y + (3 * length),
                    width: (6 * length),
                    height: (6 * length) };
                break;
            case PdfLineEndingStyle.openArrow:
                values = this._prepareOpenArrow(isBegin, axisPoint, angle, length);
                path = new PdfPath();
                path._pen = pen;
                path.addLine({ x: values.startPoint.x, y: values.startPoint.y }, { x: values.first.x, y: values.first.y });
                path.addLine({ x: values.startPoint.x, y: values.startPoint.y }, { x: values.second.x, y: values.second.y });
                bounds = path._getBounds();
                result = { x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] };
                break;
            case PdfLineEndingStyle.closedArrow:
                values = this._prepareClosedArrow(isBegin, axisPoint, angle, length);
                result = this._getBoundsValue([values.startPoint.x, values.startPoint.y,
                    values.first.x, values.first.y,
                    values.second.x, values.second.y]);
                break;
            case PdfLineEndingStyle.rOpenArrow:
                values = this._prepareReverseOpenArrow(isBegin, axisPoint, angle, length);
                path = new PdfPath();
                path._pen = pen;
                path.addLine({ x: values.startPoint.x, y: values.startPoint.y }, { x: values.first.x, y: values.first.y });
                path.addLine({ x: values.startPoint.x, y: values.startPoint.y }, { x: values.second.x, y: values.second.y });
                bounds = path._getBounds();
                result = { x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] };
                break;
            case PdfLineEndingStyle.rClosedArrow:
                values = this._prepareReverseCloseArrow(isBegin, axisPoint, angle, length);
                result = this._getBoundsValue([values.startPoint.x, values.startPoint.y,
                    values.first.x, values.first.y,
                    values.second.x, values.second.y]);
                break;
            case PdfLineEndingStyle.slash:
                values = this._prepareSlash(axisPoint, angle, length);
                result = this._getBoundsValue([axisPoint.x, axisPoint.y, values.first.x,
                    values.first.y, values.second.x, values.second.y]);
                break;
            case PdfLineEndingStyle.diamond:
                values = this._prepareDiamond(axisPoint, length);
                result = this._getBoundsValue([values.first.x, values.first.y, values.second.x,
                    values.second.y, values.third.x, values.third.y,
                    values.fourth.x, values.fourth.y]);
                break;
            case PdfLineEndingStyle.butt:
                values = this._prepareButt(axisPoint, angle, length);
                result = this._getBoundsValue([values.first.x, values.first.y, values.second.x, values.second.y]);
                break;
        }
        return result;
    };
    /**
     * Draws the specified line ending style at the given axis point and angle using the provided pen and brush,
     * honoring the marker length and whether it applies to the begin or end of the line.
     *
     * @private
     * @param {Point} axisPoint Axis point.
     * @param {PdfGraphics} graphics Target graphics.
     * @param {number} angle Angle in degrees.
     * @param {PdfPen} pen Stroke pen.
     * @param {PdfBrush} brush Fill brush.
     * @param {PdfLineEndingStyle} style Line ending style.
     * @param {number} length Marker length unit.
     * @param {boolean} isBegin True if begin marker.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawLineEndStyle = function (axisPoint, graphics, angle, pen, brush, style, length, isBegin) {
        var path;
        var values; // eslint-disable-line
        switch (style) {
            case PdfLineEndingStyle.square:
                graphics.drawRectangle({ x: axisPoint.x - (3 * length),
                    y: -(axisPoint.y + (3 * length)),
                    width: (6 * length),
                    height: (6 * length) }, pen, brush);
                break;
            case PdfLineEndingStyle.circle:
                graphics.drawEllipse({ x: axisPoint.x - (3 * length),
                    y: -(axisPoint.y + (3 * length)),
                    width: (6 * length),
                    height: (6 * length) }, pen, brush);
                break;
            case PdfLineEndingStyle.openArrow:
                values = this._prepareOpenArrow(isBegin, axisPoint, angle, length);
                path = new PdfPath();
                path._pen = pen;
                path.addLine({ x: values.startPoint.x, y: -values.startPoint.y }, { x: values.first.x, y: -values.first.y });
                path.addLine({ x: values.startPoint.x, y: -values.startPoint.y }, { x: values.second.x, y: -values.second.y });
                graphics._stateControl(pen, null, null);
                graphics._buildUpPath(path._points, path._pathTypes);
                graphics._drawGraphicsPath(pen, null, path._fillMode, false);
                break;
            case PdfLineEndingStyle.closedArrow:
                values = this._prepareClosedArrow(isBegin, axisPoint, angle, length);
                graphics.drawPolygon([{ x: values.startPoint.x, y: -values.startPoint.y },
                    { x: values.first.x, y: -values.first.y }, { x: values.second.x,
                        y: -values.second.y }], pen, brush);
                break;
            case PdfLineEndingStyle.rOpenArrow:
                values = this._prepareReverseOpenArrow(isBegin, axisPoint, angle, length);
                path = new PdfPath();
                path._pen = pen;
                path.addLine({ x: values.startPoint.x, y: -values.startPoint.y }, { x: values.first.x, y: -values.first.y });
                path.addLine({ x: values.startPoint.x, y: -values.startPoint.y }, { x: values.second.x, y: -values.second.y });
                graphics._stateControl(pen, null, null);
                graphics._buildUpPath(path._points, path._pathTypes);
                graphics._drawGraphicsPath(pen, null, path._fillMode, false);
                break;
            case PdfLineEndingStyle.rClosedArrow:
                values = this._prepareReverseCloseArrow(isBegin, axisPoint, angle, length);
                graphics.drawPolygon([{ x: values.startPoint.x, y: -values.startPoint.y },
                    { x: values.first.x, y: -values.first.y }, { x: values.second.x,
                        y: -values.second.y }], pen, brush);
                break;
            case PdfLineEndingStyle.slash:
                values = this._prepareSlash(axisPoint, angle, length);
                graphics.drawLine(pen, { x: axisPoint.x, y: -axisPoint.y }, { x: values.first.x, y: -values.first.y });
                graphics.drawLine(pen, { x: axisPoint.x, y: -axisPoint.y }, { x: values.second.x, y: -values.second.y });
                break;
            case PdfLineEndingStyle.diamond:
                values = this._prepareDiamond(axisPoint, length);
                graphics.drawPolygon([{ x: values.first.x, y: -values.first.y },
                    { x: values.second.x, y: -values.second.y }, { x: values.third.x, y: -values.third.y },
                    { x: values.fourth.x, y: -values.fourth.y }], pen, brush);
                break;
            case PdfLineEndingStyle.butt:
                values = this._prepareButt(axisPoint, angle, length);
                graphics.drawLine(pen, { x: values.first.x, y: -values.first.y }, { x: values.second.x, y: -values.second.y });
                break;
        }
    };
    /* eslint-disable */
    /**
     * Computes the minimal bounding rectangle that encloses both input rectangles and returns the combined bounds.
     *
     * @private
     * @param {{x: number, y: number, width: number, height: number}} rect1 First rectangle.
     * @param {{x: number, y: number, width: number, height: number}} rect2 Second rectangle.
     * @returns {{x: number, y: number, width: number, height: number}} combinedBounds.
     */
    PdfAnnotation.prototype._getCombinedRectangleBounds = function (rect1, rect2) {
        var left = Math.min(rect1.x, rect2.x);
        var top = Math.min(rect1.y, rect2.y);
        var right = Math.max(rect1.x + rect1.width, rect2.x + rect2.width);
        var bottom = Math.max(rect1.y + rect1.height, rect2.y + rect2.height);
        return {
            x: left,
            y: top,
            width: right - left,
            height: bottom - top
        };
    };
    /* eslint-enable */
    /**
     * Draws the lines begin and end markers using the given angle, pen, brush, and marker length, defaulting the length when zero.
     *
     * @private
     * @param {Point} start Start point of the line.
     * @param {Point} end End point of the line.
     * @param {PdfGraphics} graphics Target graphics.
     * @param {number} angle Line angle in degrees.
     * @param {PdfPen} pen Border pen (or null).
     * @param {PdfBrush} brush Fill brush.
     * @param {PdfAnnotationLineEndingStyle} lineStyle Begin/end line-ending styles.
     * @param {number} length Marker length unit.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawLineStyle = function (start, end, graphics, angle, pen, brush, lineStyle, length) {
        if (length === 0) {
            length = 1;
            pen = null;
        }
        this._drawLineEndStyle(start, graphics, angle, pen, brush, lineStyle.begin, length, true);
        this._drawLineEndStyle(end, graphics, angle, pen, brush, lineStyle.end, length, false);
    };
    /**
     * Extracts and returns the annotations font settingsfamily, size, and style—by parsing DS/DA entries or appearance streams,
     * normalizing font names and flags, and honoring FreeText font overrides.
     *
     * @private
     * @returns {{ name: string, size: number, style: PdfFontStyle }} fontData.
     */
    PdfAnnotation.prototype._obtainFontDetails = function () {
        var fontFamily = '';
        var fontSize;
        var style = PdfFontStyle.regular;
        if (this._dictionary.has('DS') || this._dictionary.has('DA')) {
            var fontStyle_1;
            var skipProcess = false;
            if (this._dictionary.has('DS')) {
                var collection = this._dictionary.get('DS').split(';');
                collection.forEach(function (item) {
                    var entry = item.split(':');
                    if (item.indexOf('font-family') !== -1) {
                        fontFamily = entry[1];
                    }
                    else if (item.indexOf('font-size') !== -1) {
                        if (entry[1].endsWith('pt')) {
                            fontSize = Number.parseFloat(entry[1].replace('pt', ''));
                        }
                    }
                    else if (item.indexOf('font-style') !== -1 || item.indexOf('style') !== -1) {
                        fontStyle_1 = entry[1];
                    }
                    else if (item.indexOf('font') !== -1) {
                        var name_1 = entry[1];
                        var split = name_1.split(' ');
                        split.forEach(function (part) {
                            if (part !== '' && !part.endsWith('pt')) {
                                fontFamily += part + ' ';
                            }
                            if (part.endsWith('pt')) {
                                fontSize = Number.parseFloat(part.replace('pt', ''));
                            }
                        });
                        while (fontFamily !== ' ' && fontFamily.endsWith(' ')) {
                            fontFamily = fontFamily.substring(0, fontFamily.length - 1);
                        }
                        if (fontFamily.indexOf(',') !== -1) {
                            fontFamily = fontFamily.split(',')[0];
                        }
                    }
                });
            }
            else {
                var value = this._dictionary.get('DA');
                if (value && value !== '' && value.indexOf('Tf') !== -1) {
                    var textCollection_1 = value.split(' ');
                    textCollection_1.forEach(function (text, i) {
                        if (text.indexOf('Tf') !== -1) {
                            fontFamily = textCollection_1[i - 2];
                            while (fontFamily !== '' && fontFamily.length > 1 && fontFamily[0] === '/') {
                                fontFamily = fontFamily.substring(1);
                            }
                            fontSize = Number.parseFloat(textCollection_1[i - 1]);
                        }
                    });
                }
                else if (this._dictionary.has('AP')) {
                    var appearanceDict = this._dictionary.get('AP');
                    var fontData = this._parseFontFromAppearance(appearanceDict, (this instanceof PdfRedactionAnnotation) ?
                        ['R', 'N', 'D'] : ['N', 'R', 'D']);
                    switch (fontData.name) {
                        case 'Helvetica':
                        case 'Courier':
                        case 'Symbol':
                        case 'TimesRoman':
                        case 'ZapfDingbats':
                        case 'MonotypeSungLight':
                        case 'SinoTypeSongLight':
                        case 'MonotypeHeiMedium':
                        case 'HanyangSystemsGothicMedium':
                        case 'HanyangSystemsShinMyeongJoMedium':
                        case 'HeiseiKakuGothicW5':
                        case 'HeiseiMinchoW3':
                            fontFamily = fontData.name;
                            break;
                        case 'Times-Roman':
                            fontFamily = 'TimesRoman';
                            break;
                        default:
                            fontFamily = 'Helvetica';
                            break;
                    }
                    fontSize = fontData.fontSize;
                    if (typeof fontData.style === 'undefined' || fontData.style === null) {
                        style = PdfFontStyle.regular;
                    }
                    else {
                        style = fontData.style;
                    }
                    skipProcess = true;
                }
            }
            if (!skipProcess) {
                if (fontStyle_1 && fontStyle_1 !== '') {
                    var styleArray = [fontStyle_1];
                    if (fontStyle_1.includes(':')) {
                        styleArray = fontStyle_1.split(':');
                    }
                    else if (fontStyle_1.includes(',')) {
                        styleArray = fontStyle_1.split(',');
                    }
                    if (styleArray) {
                        styleArray.forEach(function (entry) {
                            entry = entry.trim();
                            switch (entry.toLowerCase()) {
                                case 'bold':
                                    style |= PdfFontStyle.bold;
                                    break;
                                case 'italic':
                                    style |= PdfFontStyle.italic;
                                    break;
                                case 'strikeout':
                                    style |= PdfFontStyle.strikeout;
                                    break;
                                case 'underline':
                                    style |= PdfFontStyle.underline;
                                    break;
                            }
                        });
                    }
                }
            }
            if (fontFamily) {
                fontFamily = fontFamily.trim();
            }
        }
        else if (this._dictionary.has('AP')) {
            var appearanceDict = this._dictionary.get('AP');
            var fontData = this._parseFontFromAppearance(appearanceDict, (this instanceof PdfRedactionAnnotation) ?
                ['R', 'N', 'D'] : ['N', 'R', 'D']);
            fontFamily = fontData.name;
            fontSize = fontData.fontSize;
            style = fontData.style;
        }
        if (this instanceof PdfFreeTextAnnotation && this._font && this._font.style !== style) {
            style = this._font.style;
        }
        return { name: fontFamily, size: fontSize, style: style };
    };
    /* eslint-disable */
    /**
     * Parses the appearance dictionary using the provided key order to extract font family, size, and style
     * from the selected appearance stream.
     *
     * @private
     * @param {_PdfDictionary} source Appearance dictionary (AP).
     * @param {string[]} keys Order of keys to check (e.g., N, R, D).
     * @returns {{ name: string; fontSize: number; style: PdfFontStyle }} fontData.
     */
    PdfAnnotation.prototype._parseFontFromAppearance = function (source, keys) {
        var fontData;
        var fontFamily;
        var fontSize;
        var style;
        if (source) {
            for (var _i = 0, keys_1 = keys; _i < keys_1.length; _i++) {
                var key = keys_1[_i];
                if (source.has(key)) {
                    var appearance = source.get(key);
                    if (appearance) {
                        fontData = this._obtainAppearanceFont(appearance, fontFamily, fontSize, style);
                    }
                    break;
                }
            }
        }
        return fontData;
    };
    /**
     * Parses font information from an appearance streams resources by reading `Tf` operators,
     * resolving the BaseFont name, inferring bold/italic style flags, and extracting the font size.
     *
     * @private
     * @param {any} resourceDict Appearance stream (or reference) containing resources. // eslint-disable-line
     * @param {string} fontFamily Placeholder for resolved font family (unused input).
     * @param {number} fontSize Placeholder for resolved size (unused input).
     * @param {PdfFontStyle} style Placeholder for resolved style (unused input).
     * @returns {{ name: string; fontSize: number; style: PdfFontStyle }} fontData.
     */
    PdfAnnotation.prototype._obtainAppearanceFont = function (resourceDict, fontFamily, fontSize, style) {
        if (resourceDict && resourceDict instanceof _PdfBaseStream && resourceDict.dictionary &&
            resourceDict.dictionary.has('Resources')) {
            var resourcesDict = resourceDict.dictionary.get('Resources');
            var pdfStream = resourceDict;
            var contentParser = new _ContentParser(pdfStream.getBytes());
            var pdfRecords = contentParser._readContent();
            for (var _i = 0, pdfRecords_1 = pdfRecords; _i < pdfRecords_1.length; _i++) {
                var record = pdfRecords_1[_i];
                var operandTokens = record._operands;
                var operatorToken = record._operator;
                if (operatorToken === 'Tf') {
                    var fontFamilyToken = operandTokens[0];
                    if (resourcesDict.has('Font')) {
                        var fontDict = resourcesDict.get('Font');
                        if (fontDict && fontFamilyToken.includes('/')) {
                            fontFamilyToken = fontFamilyToken.replace(/\//g, '');
                            var fontRefDict = fontDict.get(fontFamilyToken);
                            if (fontRefDict && fontRefDict.has('BaseFont')) {
                                var baseFontName = fontRefDict.get('BaseFont');
                                fontFamily = baseFontName.name;
                                if (fontFamily) {
                                    var containsBold = fontFamily.includes('Bold');
                                    var containsItalic = fontFamily.includes('Italic') || fontFamily.includes('Oblique');
                                    if (fontFamily.includes('Times') || fontFamily.includes('Helvetica') || fontFamily.includes('Courier')) {
                                        if (containsBold && containsItalic) {
                                            style = PdfFontStyle.bold | PdfFontStyle.italic;
                                        }
                                        else if (containsBold) {
                                            style = PdfFontStyle.bold;
                                        }
                                        else if (containsItalic) {
                                            style = PdfFontStyle.italic;
                                        }
                                    }
                                    if (operandTokens[1]) {
                                        fontSize = Number.parseFloat(operandTokens[1]);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        return { name: fontFamily, fontSize: fontSize, style: style };
    };
    /* eslint-enable */
    /**
     * Obtains and returns the resolved PdfFont instance by mapping the parsed font name, size, and style
     * from the annotations appearance or DS/DA settings.
     *
     * @private
     * @returns {PdfFont} font.
     */
    PdfAnnotation.prototype._obtainFont = function () {
        var fontData = this._obtainFontDetails();
        return _mapFont(fontData.name, fontData.size, fontData.style, this);
    };
    /**
     * Maps the given measurement unit to its corresponding graphics unit and canonical unit string e.g., in, cm, mm, p, pt,
     * defaulting to inches.
     *
     * @private
     * @param {PdfMeasurementUnit} measurementUnit Input measurement unit.
     * @param {string} unitString Output unit string (updated in return object).
     * @returns {{graphicsUnit: _PdfGraphicsUnit, unitString: string}} mapping.
     */
    PdfAnnotation.prototype._getEqualPdfGraphicsUnit = function (measurementUnit, unitString) {
        var graphicsUnit;
        switch (measurementUnit) {
            case PdfMeasurementUnit.inch:
                graphicsUnit = _PdfGraphicsUnit.inch;
                unitString = 'in';
                break;
            case PdfMeasurementUnit.centimeter:
                graphicsUnit = _PdfGraphicsUnit.centimeter;
                unitString = 'cm';
                break;
            case PdfMeasurementUnit.millimeter:
                graphicsUnit = _PdfGraphicsUnit.millimeter;
                unitString = 'mm';
                break;
            case PdfMeasurementUnit.pica:
                graphicsUnit = _PdfGraphicsUnit.pica;
                unitString = 'p';
                break;
            case PdfMeasurementUnit.point:
                graphicsUnit = _PdfGraphicsUnit.point;
                unitString = 'pt';
                break;
            default:
                graphicsUnit = _PdfGraphicsUnit.inch;
                unitString = 'in';
                break;
        }
        return { graphicsUnit: graphicsUnit, unitString: unitString };
    };
    /**
     * Creates and returns a Measure dictionary configured for the given unit string, initializing distance/area entries,
     * formatting fields, and unit conversion factors.
     *
     * @private
     * @param {string} unitString Canonical unit string (in, cm, mm, pt, p).
     * @returns {_PdfDictionary} measureDictionary.
     */
    PdfAnnotation.prototype._createMeasureDictionary = function (unitString) {
        var d = new _PdfDictionary();
        d.set('C', 1);
        d.set('D', 100);
        d.set('F', _PdfName.get('D'));
        d.set('RD', '.');
        d.set('RT', '');
        d.set('SS', '');
        d.set('U', unitString);
        var a = new _PdfDictionary();
        a.set('C', 1);
        a.set('D', 100);
        a.set('F', _PdfName.get('D'));
        a.set('RD', '.');
        a.set('RT', '');
        a.set('SS', '');
        a.set('U', 'sq ' + unitString);
        var x = new _PdfDictionary();
        if (unitString === 'in') {
            x.set('C', 0.0138889);
        }
        else if (unitString === 'cm') {
            x.set('C', 0.0352778);
        }
        else if (unitString === 'mm') {
            x.set('C', 0.352778);
        }
        else if (unitString === 'pt') {
            x.set('C', 1);
        }
        else if (unitString === 'p') {
            x.set('C', 0.0833333);
        }
        x.set('D', 100);
        x.set('F', _PdfName.get('D'));
        x.set('RD', '.');
        x.set('RT', '');
        x.set('SS', '');
        x.set('U', unitString);
        var measureDictionary = new _PdfDictionary();
        measureDictionary.set('A', [a]);
        measureDictionary.set('D', [d]);
        measureDictionary.set('R', '1 ' + unitString + ' = 1 ' + unitString);
        measureDictionary.set('Type', _PdfName.get('Measure'));
        measureDictionary.set('X', [x]);
        return measureDictionary;
    };
    /**
     * Converts an RGB triplet to a hex color string, defaulting to black when undefined.
     *
     * @private
     * @param {number[]} col RGB array [r, g, b].
     * @returns {string} hex Hex color string (#RRGGBB).
     */
    PdfAnnotation.prototype._colorToHex = function (col) {
        if (col) {
            return '#' + this._componentToHex(col[0]) + this._componentToHex(col[1]) + this._componentToHex(col[2]);
        }
        else {
            return '#' + this._componentToHex(0) + this._componentToHex(0) + this._componentToHex(0);
        }
    };
    /**
     * Converts a single byte component to a two-digit hexadecimal string.
     *
     * @private
     * @param {number} c Component value (0..255).
     * @returns {string} hex Two-digit hex.
     */
    PdfAnnotation.prototype._componentToHex = function (c) {
        var hex = c.toString(16);
        return hex.length === 1 ? '0' + hex : hex;
    };
    /* eslint-disable */
    /**
     * Computes the axis-aligned bounding box of a rectangle after rotation by the given angle and returns the rotated bounds.
     *
     * @private
     * @param {{ x: number, y: number, width: number, height: number }} bounds Rectangle bounds. // eslint-disable-line
     * @param {number} rotateAngle Rotation angle in degrees.
     * @returns {{ x: number, y: number, width: number, height: number }} rotatedBounds.
     */
    PdfAnnotation.prototype._getRotatedBounds = function (bounds, rotateAngle) {
        if (bounds.width > 0 && bounds.height > 0) {
            var matrix_1 = new _PdfTransformationMatrix();
            matrix_1._rotate(rotateAngle);
            var corners = [];
            corners.push({ x: bounds.x, y: bounds.y });
            corners.push({ x: bounds.x + bounds.width, y: bounds.y });
            corners.push({ x: bounds.x + bounds.width, y: bounds.y + bounds.height });
            corners.push({ x: bounds.x, y: bounds.y + bounds.height });
            corners = corners.map(function (point) { return matrix_1._matrix._transform(point); });
            var path = new PdfPath();
            path.addRectangle({ x: bounds.x, y: bounds.y, width: bounds.width, height: bounds.height });
            path._points = corners.slice(0, 4);
            var minX = corners[0].x;
            var maxX = corners[3].x;
            var minY = corners[0].y;
            var maxY = corners[3].y;
            for (var i = 0; i < 4; i++) {
                if (corners[i].x < minX) {
                    minX = corners[i].x;
                }
                if (corners[i].x > maxX) {
                    maxX = corners[i].x;
                }
                if (corners[i].y < minY) {
                    minY = corners[i].y;
                }
                if (corners[i].y > maxY) {
                    maxY = corners[i].y;
                }
            }
            return { x: bounds.x, y: bounds.y, width: Math.round(maxX - minX), height: Math.round(maxY - minY) };
        }
        return bounds;
    };
    /* eslint-enable */
    /**
     * Flattens the current annotations pop-up by drawing a static popup appearance onto the page.
     *
     * @private
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._flattenPopUp = function () {
        this._flattenPop(this._page, this.color, this.bounds, this.border, this.author, this.subject, this.text);
    };
    /* eslint-disable */
    /**
     * Renders and flattens a pop-up annotation onto the specified page using the provided visual settings and content.
     *
     * @private
     * @param {PdfPage} _page Target page.
     * @param {PdfColor} color Background color.
     * @param {{ x: number, y: number, width: number, height: number }} boundsValue Popup bounds. // eslint-disable-line
     * @param {PdfAnnotationBorder} border Popup border.
     * @param {string} author Author name.
     * @param {string} subject Subject text.
     * @param {string} text Content text.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._flattenPop = function (_page, color, boundsValue, border, author, subject, text) {
        var clientSize = { width: 0, height: 0 };
        if (_page && _page.size) {
            clientSize = _page.size;
        }
        var x = clientSize.width - 180;
        var annotBounds = boundsValue;
        var y = (annotBounds.y + 142) < clientSize.height ? annotBounds.y : clientSize.height - 142;
        var bounds = [x, y, 180, 142];
        if (this._dictionary.has('Popup')) {
            var dictionary = this._dictionary.get('Popup');
            if (dictionary) {
                var rectValue = this._dictionary.getArray('Rect');
                if (rectValue && rectValue.length === 4) {
                    var left = rectValue[0];
                    var top_2 = rectValue[1];
                    var width = rectValue[2];
                    var height = rectValue[3];
                    bounds = [left, top_2, width - left, height - top_2];
                }
            }
        }
        if (typeof color === 'undefined') {
            color = { r: 0, g: 0, b: 0 };
        }
        var backBrush = new PdfBrush(color);
        var borderWidth = border.width / 2;
        var pen = new PdfPen({ r: 0, g: 0, b: 0 }, 1);
        var track = 0;
        var aBrush = new PdfBrush(this._getForeColor(color));
        if (typeof author !== 'undefined' && author !== null && author !== '') {
            track = this._drawAuthor(author, subject, bounds, backBrush, aBrush, _page, track, border);
        }
        else if (typeof subject !== 'undefined' && subject !== null && subject !== '') {
            var titleRect = [bounds[0] + borderWidth, bounds[1] + borderWidth, bounds[2] - border.width, 40];
            this._saveGraphics(_page, PdfBlendMode.hardLight);
            if (this._isTransparentColor) {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen);
            }
            else {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen, backBrush);
            }
            _page.graphics.restore();
            var contentRect = [titleRect[0] + 11, titleRect[1], titleRect[2], titleRect[3] / 2];
            contentRect = [contentRect[0], (contentRect[1] + contentRect[3] - 2), contentRect[2], titleRect[3] / 2];
            this._saveGraphics(_page, PdfBlendMode.normal);
            this._drawSubject(subject, { x: contentRect[0], y: contentRect[1], width: contentRect[2], height: contentRect[3] }, _page);
            _page.graphics.restore();
            track = 40;
        }
        else {
            this._saveGraphics(_page, PdfBlendMode.hardLight);
            var titleRect = [bounds[0] + borderWidth, bounds[1] + borderWidth, bounds[2] - border.width, 20];
            if (this._isTransparentColor) {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen);
            }
            else {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen, backBrush);
            }
            track = 20;
            _page.graphics.restore();
        }
        var rect = [bounds[0] + borderWidth, bounds[1] + borderWidth + track,
            bounds[2] - border.width, bounds[3] - (track + border.width)];
        this._saveGraphics(_page, PdfBlendMode.hardLight);
        _page.graphics.drawRectangle({ x: rect[0], y: rect[1],
            width: rect[2], height: rect[3] }, new PdfPen({ r: 0, g: 0, b: 0 }, 1), new PdfBrush({ r: 255, g: 255, b: 255 }));
        rect[0] += 11;
        rect[1] += 5;
        rect[2] -= 22;
        _page.graphics.restore();
        this._saveGraphics(_page, PdfBlendMode.normal);
        if (typeof text !== 'undefined' && text !== null && text !== '') {
            _page.graphics.drawString(text, this._popUpFont, { x: rect[0], y: rect[1],
                width: rect[2], height: rect[3] }, null, new PdfBrush({ r: 0, g: 0, b: 0 }), null);
        }
        _page.graphics.restore();
    };
    /* eslint-enable */
    /**
     * Flattens a previously loaded pop-up annotation by rendering its stored content and removing the interactive object.
     *
     * @private
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._flattenLoadedPopUp = function () {
        var content = '';
        if (this._dictionary.has('Contents')) {
            content = this._dictionary.get('Contents');
        }
        var author = this.author;
        var subject = this.subject;
        var pen = new PdfPen({ r: 0, g: 0, b: 0 }, 1);
        if (!this._dictionary.has('Popup')) {
            this._flattenPop(this._page, this.color, this.bounds, this.border, author, subject, content);
            this._page.annotations.remove(this);
        }
        else {
            var bounds = this._getRectangleBoundsValue();
            if (typeof this.color === 'undefined') {
                this.color = { r: 0, g: 0, b: 0 };
            }
            var backBrush = new PdfBrush(this.color);
            var borderWidth = this.border.width / 2;
            var track = 0;
            var aBrush = new PdfBrush(this._getForeColor(this.color));
            if (typeof this.author !== 'undefined' && this.author !== null && this.author !== '') {
                track = this._drawAuthor(this.author, this.subject, bounds, backBrush, aBrush, this._page, track, this.border);
            }
            else if (typeof this.subject !== 'undefined' && this.subject !== null && this.subject !== '') {
                var titleRect = [bounds[0] + borderWidth, bounds[1] + borderWidth, bounds[2] - this.border.width, 40];
                this._saveGraphics(this._page, PdfBlendMode.hardLight);
                this._page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1],
                    width: titleRect[2], height: titleRect[3] }, pen, backBrush);
                this._page.graphics.restore();
                var contentRect = [titleRect[0] + 11, titleRect[1], titleRect[2], titleRect[3] / 2];
                contentRect = [contentRect[0], (contentRect[1] + contentRect[3] - 2), contentRect[2], titleRect[3] / 2];
                this._saveGraphics(this._page, PdfBlendMode.normal);
                this._drawSubject(this.subject, { x: contentRect[0], y: contentRect[1],
                    width: contentRect[2], height: contentRect[3] }, this._page);
                track = 40;
                this._page.graphics.restore();
            }
            else {
                this._saveGraphics(this._page, PdfBlendMode.hardLight);
                var titleRect = [bounds[0] + borderWidth, bounds[1] + borderWidth, bounds[2] - this.border.width, 20];
                this._page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1],
                    width: titleRect[2], height: titleRect[3] }, pen, backBrush);
                track = 20;
                this._page.graphics.restore();
            }
            this._saveGraphics(this._page, PdfBlendMode.hardLight);
            var rect = [bounds[0] + borderWidth, bounds[1] + borderWidth + track,
                bounds[2] - this.border.width, bounds[3] - (track + this.border.width)];
            this._page.graphics.drawRectangle({ x: rect[0], y: rect[1], width: rect[2],
                height: rect[3] }, pen, new PdfBrush({ r: 255, g: 255, b: 255 }));
            rect[0] += 11;
            rect[1] += 5;
            rect[2] -= 22;
            this._page.graphics.restore();
            this._saveGraphics(this._page, PdfBlendMode.normal);
            this._page.graphics.restore();
            //let xmlData: Array<any> = Array<any>();
            // if (this._dictionary.has('RC')) {
            //     //xmlData = this.parseXMLData();
            // }
            // if (xmlData !== null) {
            //     // Need to add xml data code
            // } else {
            if (typeof content !== 'undefined' && content !== null && content !== '') {
                this._page.graphics.drawString(content, this._popUpFont, { x: rect[0], y: rect[1],
                    width: rect[2], height: rect[3] }, null, new PdfBrush({ r: 0, g: 0, b: 0 }), null);
            }
            // }
            this._page.graphics.restore();
            this._page.annotations.remove(this);
        }
    };
    /**
     * Retrieves and normalizes the rectangle bounds of the pop up from the dictionary, converting coordinates to page space.
     *
     * @private
     * @returns {number[]} rect Normalized array [x, y, width, height].
     */
    PdfAnnotation.prototype._getRectangleBoundsValue = function () {
        if (this._dictionary.has('Popup')) {
            var dic = this._dictionary.get('Popup');
            var rect = dic.getArray('Rect');
            if (rect !== null) {
                if (this._page !== null) {
                    if (rect[1] === 0 && rect[3] === 0) {
                        rect[1] = rect[1] + rect[3];
                    }
                    else {
                        rect[1] = this._page._size.height - (rect[1] + rect[3]);
                    }
                }
                else {
                    rect[1] = (rect[1] - rect[3]);
                }
                return rect;
            }
            else {
                return [0, 0, 0, 0];
            }
        }
        else {
            return [0, 0, 0, 0];
        }
    };
    /**
     * Determines a contrasting foreground color (black or white) based on the luminance of the given background color.
     *
     * @private
     * @param {PdfColor} color Background color.
     * @returns {PdfColor} foreColor.
     */
    PdfAnnotation.prototype._getForeColor = function (color) {
        var fore = (((color.r + color.g + color.b) / 3) > 128) ? { r: 0, g: 0, b: 0 } : { r: 255, g: 255, b: 255 };
        return fore;
    };
    /**
     * Draws the author/subject title area of a pop-up and returns the consumed vertical space (tracking height).
     *
     * @private
     * @param {string} author Author text.
     * @param {string} subject Subject text.
     * @param {number[]} bounds Bounds array [x, y, width, height].
     * @param {PdfBrush} backBrush Background brush.
     * @param {PdfBrush} aBrush Foreground brush.
     * @param {PdfPage} _page Target page.
     * @param {number} trackingHeight Current tracking height.
     * @param {PdfAnnotationBorder} border Annotation border.
     * @returns {number} consumedHeight.
     */
    PdfAnnotation.prototype._drawAuthor = function (author, subject, bounds, backBrush, aBrush, _page, trackingHeight, border) {
        var borderWidth = this.border.width / 2;
        var pen = new PdfPen({ r: 0, g: 0, b: 0 }, 1);
        var format = new PdfStringFormat(PdfTextAlignment.left, PdfVerticalAlignment.middle);
        var titleRect = [bounds[0] + borderWidth, bounds[1] + borderWidth, bounds[2] - border.width, 20];
        if (typeof subject !== 'undefined' && subject !== null && subject !== '') {
            titleRect[3] += 20;
            trackingHeight = titleRect[3];
            this._saveGraphics(_page, PdfBlendMode.hardLight);
            if (this._isTransparentColor) {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen);
            }
            else {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen, backBrush);
            }
            _page.graphics.restore();
            var contentRect = { x: titleRect[0] + 11, y: titleRect[1], width: titleRect[2], height: titleRect[3] / 2 };
            this._saveGraphics(this._page, PdfBlendMode.normal);
            _page.graphics.drawString(author, this._authorBoldFont, contentRect, null, aBrush, format);
            contentRect = { x: contentRect.x, y: (contentRect.y + contentRect.height - 2), width: contentRect.width,
                height: titleRect[3] / 2 };
            this._drawSubject(subject, contentRect, _page);
            _page.graphics.restore();
        }
        else {
            this._saveGraphics(_page, PdfBlendMode.hardLight);
            if (this._isTransparentColor) {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen);
            }
            else {
                _page.graphics.drawRectangle({ x: titleRect[0], y: titleRect[1], width: titleRect[2], height: titleRect[3] }, pen, backBrush);
            }
            _page.graphics.restore();
            var contentRect = { x: titleRect[0] + 11, y: titleRect[1], width: titleRect[2], height: titleRect[3] };
            this._saveGraphics(_page, PdfBlendMode.normal);
            _page.graphics.drawString(author, this._popUpFont, contentRect, null, aBrush, format);
            trackingHeight = titleRect[3];
            _page.graphics.restore();
        }
        return trackingHeight;
    };
    /**
     * Draws the subject text inside the provided content rectangle on the given page using the bold author font and left middle alignment.
     *
     * @private
     * @param {string} subject Subject text.
     * @param {Rectangle} contentRect Content rectangle.
     * @param {PdfPage} _page Target page.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawSubject = function (subject, contentRect, _page) {
        var format = new PdfStringFormat(PdfTextAlignment.left, PdfVerticalAlignment.middle);
        _page.graphics.drawString(subject, this._authorBoldFont, contentRect, null, new PdfBrush({ r: 0, g: 0, b: 0 }), format);
    };
    /**
     * Saves the graphics state and applies transparency with the specified blend mode for subsequent drawing operations.
     *
     * @private
     * @param {PdfPage} _page Target page.
     * @param {PdfBlendMode} blendMode Blend mode to apply.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._saveGraphics = function (_page, blendMode) {
        _page.graphics.save();
        _page.graphics.setTransparency(0.8, 0.8, blendMode);
    };
    /**
     * Formats the given RGB color as a PDF stroke color command string with 3 decimal precision per component.
     *
     * @private
     * @param {PdfColor} color RGB color.
     * @returns {string} command PDF color command string.
     */
    PdfAnnotation.prototype._getBorderColorString = function (color) {
        return (color.r / 255).toFixed(3) + ' ' + (color.g / 255).toFixed(3) + ' ' + (color.b / 255).toFixed(3) + ' rg ';
    };
    /**
     * Converts a JavaScript Date to a PDF date string (D:YYYYMMDDHHmmSSOHH'mm') including the local timezone offset.
     *
     * @private
     * @param {Date} dateTime Input date.
     * @returns {string} pdfDate PDF date string.
     */
    PdfAnnotation.prototype._dateToString = function (dateTime) {
        var year = dateTime.getFullYear();
        var month = _pad2(dateTime.getMonth() + 1);
        var day = _pad2(dateTime.getDate());
        var hours = _pad2(dateTime.getHours());
        var mins = _pad2(dateTime.getMinutes());
        var secs = _pad2(dateTime.getSeconds());
        var utcOffsetMinutes = -dateTime.getTimezoneOffset();
        var sign = utcOffsetMinutes >= 0 ? '+' : '-'; // eslint-disable-line
        var absMin = Math.abs(utcOffsetMinutes);
        var offH = _pad2(Math.floor(absMin / 60));
        var offM = _pad2(absMin % 60);
        return "D:" + year + month + day + hours + mins + secs + sign + offH + "'" + offM + "'";
    };
    /**
     * Parses a PDF or common date string into a JavaScript Date, handling D: format, slashed dates, and timezone offsets.
     *
     * @private
     * @param {string} date Date string.
     * @returns {Date} parsedDate.
     */
    PdfAnnotation.prototype._stringToDate = function (date) {
        if (!date || typeof date !== 'string') {
            return new Date(date); // eslint-disable-line
        }
        if (date.indexOf('/') !== -1) {
            var list = date.split('/');
            var year = parseInt(list[2].split(' ')[0], 10);
            var month = parseInt(list[0], 10) - 1;
            var day = parseInt(list[1], 10);
            var timePart = (list[2].split(' ')[1] || '00:00:00').split(':');
            var hour = parseInt(timePart[0] || '0', 10);
            var minute = parseInt(timePart[1] || '0', 10);
            var second = parseInt(timePart[2] || '0', 10);
            return new Date(year, month, day, hour, minute, second);
        }
        if (date.startsWith('D:')) {
            date = date.substring(2);
        }
        var raw = date.replace(/'/g, '').trim();
        var y = parseInt(raw.slice(0, 4), 10);
        var haveM = raw.length >= 6;
        var haveD = raw.length >= 8;
        var haveH = raw.length >= 10;
        var havem = raw.length >= 12;
        var haves = raw.length >= 14;
        var m = haveM ? parseInt(raw.slice(4, 6), 10) : 1;
        var d = haveD ? parseInt(raw.slice(6, 8), 10) : 1;
        var h = haveH ? parseInt(raw.slice(8, 10), 10) : 0;
        var min = havem ? parseInt(raw.slice(10, 12), 10) : 0;
        var s = haves ? parseInt(raw.slice(12, 14), 10) : 0;
        var tzTail = raw.slice(14);
        if (/^[+-]\d{2}:\d{2}$/.test(tzTail)) {
            tzTail = tzTail.replace(':', '');
        }
        var hasTz = false;
        var tzSign = 0;
        var tzH = 0;
        var tzM = 0;
        if (tzTail) {
            if (/^[Zz]$/.test(tzTail)) {
                hasTz = true;
                tzSign = +1;
                tzH = 0;
                tzM = 0;
            }
            else if (/^[+-]\d{2}\d{2}$/.test(tzTail)) {
                hasTz = true;
                tzSign = tzTail[0] === '+' ? +1 : -1;
                tzH = parseInt(tzTail.slice(1, 3), 10);
                tzM = parseInt(tzTail.slice(3, 5), 10);
            }
            else if (/^[+-]\d{2}$/.test(tzTail)) {
                hasTz = true;
                tzSign = tzTail[0] === '+' ? +1 : -1;
                tzH = parseInt(tzTail.slice(1, 3), 10);
                tzM = 0;
            }
        }
        if (hasTz) {
            var localUTCms = Date.UTC(y, m - 1, d, h, min, s);
            var offsetMinutes = tzSign * (tzH * 60 + tzM);
            return new Date(localUTCms - offsetMinutes * 60 * 1000);
        }
        else {
            return new Date(y, m - 1, d, h, min, s);
        }
    };
    /**
     * Computes the native PDF rectangle array [x, y, right, top] from annotation bounds,
     * adjusting for page size and Crop/MediaBox offsets.
     *
     * @private
     * @returns {number[]} rect [x, y, right, top].
     */
    PdfAnnotation.prototype._obtainNativeRectangle = function () {
        var rect = [this._bounds.x, this._bounds.y, this.bounds.x + this._bounds.width, this.bounds.y + this._bounds.height];
        var cropBoxOrMediaBox = this._getCropOrMediaBox();
        if (this._page) {
            var size = this._page.size;
            rect[1] = size.height - rect[3];
            if (cropBoxOrMediaBox && cropBoxOrMediaBox.length > 2 && (cropBoxOrMediaBox[0] !== 0 || cropBoxOrMediaBox[1] !== 0)) {
                rect[0] += cropBoxOrMediaBox[0];
                rect[1] += cropBoxOrMediaBox[1];
            }
        }
        return rect;
    };
    /**
     * Returns a transformed copy of polygon points adjusted by the page CropBox/MediaBox offsets when present.
     *
     * @private
     * @param {Point[]} polygonPoints Points to transform.
     * @returns {Point[]} transformedPoints.
     */
    PdfAnnotation.prototype._getPoints = function (polygonPoints) {
        var cropOrMediaBox = this._getCropOrMediaBox();
        var points = polygonPoints ? polygonPoints.map(function (p) { return ({ x: p.x, y: p.y }); }) : []; // eslint-disable-line
        if (cropOrMediaBox && cropOrMediaBox.length > 3 && typeof cropOrMediaBox[0] === 'number' && typeof cropOrMediaBox[1] === 'number' &&
            (cropOrMediaBox[0] !== 0 || cropOrMediaBox[1] !== 0)) {
            for (var j = 0; j < points.length; j++) {
                var x = points[j].x;
                var y = points[j].y;
                points[j].x = x + cropOrMediaBox[0];
                if (this._page._pageDictionary.has('MediaBox') && !this._page._pageDictionary.has('CropBox') && cropOrMediaBox[3] === 0 && cropOrMediaBox[1] > 0) {
                    points[j].y = y + cropOrMediaBox[3];
                }
                else {
                    points[j].y = y + cropOrMediaBox[1];
                }
            }
        }
        return points;
    };
    /**
     * Retrieves the page CropBox or MediaBox as a normalized array, correcting negative height cases and defaulting to [0, 0, 0, 0].
     *
     * @private
     * @returns {number[]} box [x, y, width, height] or zeros.
     */
    PdfAnnotation.prototype._getCropOrMediaBox = function () {
        var cropOrMediaBox;
        if (this._page && this._page._pageDictionary.has('CropBox')) {
            cropOrMediaBox = this._page.cropBox;
        }
        if (!cropOrMediaBox && this._page && this._page._pageDictionary.has('MediaBox')) {
            cropOrMediaBox = this._page.mediaBox;
        }
        if (cropOrMediaBox && cropOrMediaBox[3] < 0) {
            var y = cropOrMediaBox[1];
            var height = cropOrMediaBox[3];
            cropOrMediaBox[3] = y;
            cropOrMediaBox[1] = height;
        }
        return cropOrMediaBox ? cropOrMediaBox : [0, 0, 0, 0];
    };
    PdfAnnotation.prototype._getDocumentLayer = function () {
        if (this._dictionary.has('OC')) {
            var reference = this._dictionary.getRaw('OC');
            var page = this._page;
            if (reference && page && this._crossReference._document) {
                var layerCollection = this._crossReference._document.layers;
                if (layerCollection) {
                    this._isMatched(layerCollection, reference, page);
                }
            }
        }
        return this.layer;
    };
    PdfAnnotation.prototype._isMatched = function (layerCollection, expectedReference, page) {
        for (var i = 0; i < layerCollection.count; i++) {
            var reference = layerCollection.at(i)._referenceHolder;
            if (reference && reference === expectedReference) {
                if (layerCollection.at(i).name) {
                    this._layer = layerCollection.at(i);
                    break;
                }
            }
            else if (layerCollection.at(i).layers && layerCollection.at(i).layers.count > 0) {
                this._isMatched(layerCollection.at(i).layers, expectedReference, page);
            }
        }
    };
    /**
     * Computes and sets the QuadPoints for text selections from stored bounds, accounting for margins, page height, and Crop/MediaBox offsets.
     *
     * @private
     * @param {Size} pageSize represents the page size.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._setQuadPoints = function (pageSize) {
        var textQuadLocation = [];
        var pageHeight = pageSize.height;
        var margins;
        if (this._page && this._page._isNew && this._page._pageSettings && this._page._pageSettings.margins) {
            var margin = this._page._pageSettings.margins;
            margins = {
                left: margin.left,
                top: margin.top,
                right: margin.right,
                bottom: margin.bottom
            };
        }
        else {
            margins = { left: 0, top: 0, right: 0, bottom: 0 };
        }
        if (this.bounds.x !== 0 &&
            this.bounds.y !== 0 &&
            this.bounds.width !== 0 &&
            this.bounds.height !== 0) {
            this._boundsCollection[0] = this.bounds;
        }
        var noofRect = this._quadPoints.length / 8;
        var cropOrMediaBox = this._getMediaOrCropBox(this._page);
        var isContainscropOrMediaBox = false;
        if (!this._isLoaded && cropOrMediaBox && cropOrMediaBox.length > 3 && !this.flatten) {
            var cropOrMediaBoxX = cropOrMediaBox[0];
            var cropOrMediaBoxY = cropOrMediaBox[1];
            if (cropOrMediaBoxX !== 0 || cropOrMediaBoxY !== 0) {
                for (var i = 0; i < noofRect; i++) {
                    var rect = this._boundsCollection[i];
                    var locationX = rect.x + margins.left + cropOrMediaBoxX;
                    var locationY = cropOrMediaBoxY + margins.top;
                    textQuadLocation[0 + i * 8] = locationX + margins.left;
                    textQuadLocation[1 + i * 8] = pageHeight + locationY - margins.top - rect.y;
                    textQuadLocation[2 + i * 8] = locationX + rect.width + margins.left;
                    textQuadLocation[3 + i * 8] = pageHeight + locationY - margins.top - rect.y;
                    textQuadLocation[4 + i * 8] = locationX + margins.left;
                    textQuadLocation[5 + i * 8] = textQuadLocation[1 + i * 8] - rect.height;
                    textQuadLocation[6 + i * 8] = locationX + rect.width + margins.left;
                    textQuadLocation[7 + i * 8] = textQuadLocation[5 + i * 8];
                }
                isContainscropOrMediaBox = true;
            }
        }
        if (!isContainscropOrMediaBox && this._boundsCollection.length > 0) {
            for (var i = 0; i < noofRect; i++) {
                var rect = this._boundsCollection[i];
                var locationX = rect.x;
                var locationY = rect.y;
                textQuadLocation[0 + i * 8] = locationX + margins.left;
                textQuadLocation[1 + i * 8] = pageHeight - locationY - margins.top;
                textQuadLocation[2 + i * 8] = locationX + rect.width + margins.left;
                textQuadLocation[3 + i * 8] = pageHeight - locationY - margins.top;
                textQuadLocation[4 + i * 8] = locationX + margins.left;
                textQuadLocation[5 + i * 8] = textQuadLocation[1 + i * 8] - rect.height;
                textQuadLocation[6 + i * 8] = locationX + rect.width + margins.left;
                textQuadLocation[7 + i * 8] = textQuadLocation[5 + i * 8];
            }
        }
        this._points = [];
        for (var i = 0; i < textQuadLocation.length; i += 2) {
            this._points.push({ x: textQuadLocation[i], y: textQuadLocation[i + 1] });
        }
        this._dictionary.set('QuadPoints', textQuadLocation);
    };
    /**
     * Creates a PdfTemplate for the requested appearance key by reading AP streams, resolving Matrix/BBox,
     * normalizing size, and exporting the stream.
     *
     * @private
     * @param {string} [key] Appearance key ('N' by default).
     * @returns {PdfTemplate} template or undefined if not found.
     */
    PdfAnnotation.prototype._createTemplate = function (key) {
        var template;
        if (this._isLoaded) {
            if (!key) {
                key = 'N';
            }
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has(key)) {
                    var appearanceStream = dictionary.get(key);
                    var ref = dictionary.getRaw(key);
                    if (ref && appearanceStream) {
                        template = new PdfTemplate();
                        template._isExported = true;
                        var templateDictionary = appearanceStream.dictionary;
                        var matrix = templateDictionary.getArray('Matrix');
                        var bounds = templateDictionary.getArray('BBox');
                        if (matrix) {
                            var mMatrix = [];
                            for (var i = 0; i < matrix.length; i++) {
                                var value = matrix[i];
                                mMatrix[i] = value;
                            }
                            if (bounds && bounds.length > 3) {
                                var rect = _toRectangle(bounds);
                                var rectangle = this._transformBBox(rect, mMatrix);
                                template._size = { width: rectangle[2], height: rectangle[3] };
                                template._templateOriginalSize = { width: rect.width, height: rect.height };
                            }
                            if (appearanceStream && typeof appearanceStream.offset === 'number' && appearanceStream.offset !== 0) {
                                appearanceStream.offset = 0;
                            }
                        }
                        else if (bounds && (bounds[2] === this.bounds.width && bounds[3] === this.bounds.height) || _areArrayEqual(this._dictionary.get('Rect'), bounds)) {
                            templateDictionary.update('Matrix', [1, 0, 0, 1, -bounds[0], -bounds[1]]);
                            if (this._dictionary.has('Vertices')) {
                                template._size = { width: bounds[2], height: bounds[3] };
                            }
                            else {
                                template._size = { width: this.bounds.width, height: this.bounds.height };
                                this._crossReference._cacheMap.set(ref, appearanceStream);
                            }
                        }
                        else {
                            var identityMatrix = [1, 0, 0, 1, 0, 0];
                            var templateSize = this._getTransformMatrix(this._dictionary.get('Rect'), bounds, identityMatrix);
                            if (this.bounds.width === templateSize[0] && this.bounds.height === templateSize[3]) {
                                templateDictionary.update('Matrix', [templateSize[0], 0, 0, templateSize[3], 0, 0]);
                                template._size = { width: templateSize[0], height: templateSize[3] };
                                this._crossReference._cacheMap.set(ref, appearanceStream);
                            }
                            else {
                                templateDictionary.update('Matrix', [1, 0, 0, 1, -bounds[0], -bounds[1]]);
                                template._size = { width: bounds[2], height: bounds[3] };
                            }
                        }
                        template._exportStream(dictionary, this._crossReference, key);
                    }
                }
            }
        }
        return template;
    };
    /**
     * Creates a PdfTemplate for the requested appearance key by reading AP streams, resolving Matrix/BBox,
     * normalizing size, and exporting the stream.
     *
     * @private
     * @param {number[]} rect Appearance key .
     * @param {number[]} bbox Appearance key .
     * @param {number[]} matrix matrix for appearance.
     * @returns {number[]} template or undefined if not found.
     */
    PdfAnnotation.prototype._getTransformMatrix = function (rect, bbox, matrix) {
        var _a = this._getAxialAlignedBoundingBox(bbox, matrix), minX = _a[0], minY = _a[1], maxX = _a[2], maxY = _a[3];
        if (minX === maxX || minY === maxY) {
            return [1, 0, 0, 1, rect[0], rect[1]];
        }
        var xRatio = (rect[2] - rect[0]) / (maxX - minX);
        var yRatio = (rect[3] - rect[1]) / (maxY - minY);
        return [xRatio, 0, 0, yRatio, rect[0] - minX * xRatio, rect[1] - minY * yRatio];
    };
    /**
     * Returns the axis aligned bounding box [minX, minY, maxX, maxY] of the rectangle r after applying the transform m.
     *
     * @private
     * @param {number[]} r Rectangle [x0, y0, x1, y1].
     * @param {number[]} m 2D affine matrix [a, b, c, d, e, f].
     * @returns {number[]} aabb [minX, minY, maxX, maxY].
     */
    PdfAnnotation.prototype._getAxialAlignedBoundingBox = function (r, m) {
        var p1 = this._applyTransform(r, m);
        var p2 = this._applyTransform(r.slice(2, 4), m);
        var p3 = this._applyTransform([r[0], r[3]], m);
        var p4 = this._applyTransform([r[2], r[1]], m);
        return [
            Math.min(p1[0], p2[0], p3[0], p4[0]),
            Math.min(p1[1], p2[1], p3[1], p4[1]),
            Math.max(p1[0], p2[0], p3[0], p4[0]),
            Math.max(p1[1], p2[1], p3[1], p4[1])
        ];
    };
    /**
     * Applies the 2D affine transform m to point p and returns the transformed coordinate.
     *
     * @private
     * @param {number[]} p Point [x, y].
     * @param {number[]} m Matrix [a, b, c, d, e, f].
     * @returns {number[]} pt [x', y'].
     */
    PdfAnnotation.prototype._applyTransform = function (p, m) {
        var xt = p[0] * m[0] + p[1] * m[2] + m[4];
        var yt = p[0] * m[1] + p[1] * m[3] + m[5];
        return [xt, yt];
    };
    /* eslint-disable */
    /**
     * Transforms the bounding box through the given matrix and returns the resulting [minX, minY, maxX, maxY] extent.
     *
     * @private
     * @param {{ x: number, y: number, width: number, height: number }} bBoxValue Bounds object.
     * @param {number[]} matrix Matrix [a, b, c, d, e, f].
     * @returns {number[]} rect [minX, minY, maxX, maxY].
     */
    PdfAnnotation.prototype._transformBBox = function (bBoxValue, matrix) {
        var xCoordinate = [];
        var yCoordinate = [];
        var point1 = this._transformPoint(bBoxValue.x, bBoxValue.y + bBoxValue.height, matrix);
        xCoordinate[0] = point1[0];
        yCoordinate[0] = point1[1];
        var point2 = this._transformPoint(bBoxValue.x + bBoxValue.width, bBoxValue.y, matrix);
        xCoordinate[1] = point2[0];
        yCoordinate[1] = point2[1];
        var point3 = this._transformPoint(bBoxValue.x, bBoxValue.y, matrix);
        xCoordinate[2] = point3[0];
        yCoordinate[2] = point3[1];
        var point4 = this._transformPoint(bBoxValue.x + bBoxValue.width, bBoxValue.y + bBoxValue.height, matrix);
        xCoordinate[3] = point4[0];
        yCoordinate[3] = point4[1];
        var rect = [this._minValue(xCoordinate), this._minValue(yCoordinate),
            this._maxValue(xCoordinate), this._maxValue(yCoordinate)];
        return rect;
    };
    /* eslint-enable */
    /**
     * Transforms a point (x, y) using the provided 2D affine matrix and returns the resulting coordinate.
     *
     * @private
     * @param {number} x X coordinate.
     * @param {number} y Y coordinate.
     * @param {number[]} matrix Matrix [a, b, c, d, e, f].
     * @returns {number[]} pt [x', y'].
     */
    PdfAnnotation.prototype._transformPoint = function (x, y, matrix) {
        var point = [];
        point[0] = x * matrix[0] + y * matrix[2] + matrix[4];
        point[1] = x * matrix[1] + y * matrix[3] + matrix[5];
        return point;
    };
    /**
     * Returns the minimum numeric value from the given array.
     *
     * @private
     * @param {number[]} values Array of numbers.
     * @returns {number} min Minimum value.
     */
    PdfAnnotation.prototype._minValue = function (values) {
        var minimum = values[0];
        for (var i = 1; i < values.length; i++) {
            if (values[i] < minimum) {
                minimum = values[i];
            }
        }
        return minimum;
    };
    /**
     * Returns the maximum numeric value from the given array.
     *
     * @private
     * @param {number[]} values Array of numbers.
     * @returns {number} min Maximum value.
     */
    PdfAnnotation.prototype._maxValue = function (values) {
        var maximum = values[0];
        for (var i = 1; i < values.length; i++) {
            if (values[i] > maximum) {
                maximum = values[i];
            }
        }
        return maximum;
    };
    /**
     * Imports and registers a template under the specified key, ensuring proper crossreference handling and resource export state.
     *
     * @private
     * @param {PdfTemplate} template Template to register.
     * @param {string} key Appearance key.
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawTemplate = function (template, key) {
        if (template && key) {
            if (template._isExported || template._isResourceExport) {
                if (this._crossReference) {
                    template._crossReference = this._crossReference;
                    template._importStream(true, template._isResourceExport);
                }
                else {
                    template._importStream(false, template._isResourceExport);
                }
            }
            this._customTemplate.set(key, template);
        }
    };
    /**
     * Writes all custom templates into the appearance dictionary, allocating new references and updating the cross reference cache.
     *
     * @private
     * @param {_PdfDictionary} appearance Appearance dictionary (AP).
     * @returns {void} nothing.
     */
    PdfAnnotation.prototype._drawCustomAppearance = function (appearance) {
        var _this = this;
        this._customTemplate.forEach(function (template, key) {
            _removeDuplicateReference(appearance, _this._crossReference, key);
            var reference = _this._crossReference._getNextReference();
            template._content.reference = reference;
            template._content.dictionary._update = true;
            _this._crossReference._cacheMap.set(reference, template._content);
            appearance.update(key, reference);
        });
    };
    return PdfAnnotation;
}());
export { PdfAnnotation };
/**
 * Represents the annotations which have comments and review history.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: PdfComment = page.annotations.at(0) as PdfComment;
 * // Gets the comments of annotation
 * let comment: PdfPopupAnnotationCollection = annotation.comments;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfComment = /** @class */ (function (_super) {
    __extends(PdfComment, _super);
    function PdfComment() {
        return _super !== null && _super.apply(this, arguments) || this;
    }
    Object.defineProperty(PdfComment.prototype, "comments", {
        /**
         * Gets the comments of the PDF annotation (Read only).
         *
         * @returns {PdfPopupAnnotationCollection} Annotation comments
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Access first page
         * let page: PdfPage = document.getPage(0);
         * // Access the annotation at index 0
         * let annotation: PdfRectangleAnnotation = page.annotations.at(0) as PdfRectangleAnnotation;
         * // Gets the comments of the PDF annotation
         * let comments: PdfPopupAnnotationCollection = annotation.comments;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._comments) {
                return this._comments;
            }
            else {
                return this._comments = new PdfPopupAnnotationCollection(this, false);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfComment.prototype, "reviewHistory", {
        /**
         * Gets the review history of the PDF annotation (Read only).
         *
         * @returns {PdfPopupAnnotationCollection} Annotation review history.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Access first page
         * let page: PdfPage = document.getPage(0);
         * // Access the annotation at index 0
         * let annotation: PdfRectangleAnnotation = page.annotations.at(0) as PdfRectangleAnnotation;
         * // Gets the comments of the PDF annotation
         * let comments: PdfPopupAnnotationCollection = annotation.reviewHistory;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._reviewHistory) {
                return this._reviewHistory;
            }
            else {
                return this._reviewHistory = new PdfPopupAnnotationCollection(this, true);
            }
        },
        enumerable: true,
        configurable: true
    });
    return PdfComment;
}(PdfAnnotation));
export { PdfComment };
/**
 * `PdfLineAnnotation` class represents the line annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new line annotation with line points
 * const annotation: PdfLineAnnotation = new PdfLineAnnotation({x: 10, y: 50}, {x: 250, y: 50});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfLineAnnotation = /** @class */ (function (_super) {
    __extends(PdfLineAnnotation, _super);
    function PdfLineAnnotation(startPoint, endPoint, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the measurement unit used for line annotations.
         *
         * @private
         */
        _this._unit = PdfMeasurementUnit.centimeter;
        _this._unitString = '';
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Line'));
        if (startPoint !== null && typeof startPoint !== 'undefined' && endPoint !== null && typeof endPoint !== 'undefined') {
            _this.linePoints = [startPoint, endPoint];
        }
        _this._type = _PdfAnnotationType.lineAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('lineEndingStyle' in properties && _isNullOrUndefined(properties.lineEndingStyle)) {
                _this.lineEndingStyle = properties.lineEndingStyle;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
            if ('measurementUnit' in properties && _isNullOrUndefined(properties.measurementUnit)) {
                _this.measure = true;
                _this.unit = properties.measurementUnit;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfLineAnnotation.prototype, "linePoints", {
        /**
         * Gets the line points of the line annotation.
         *
         * @returns {Point[]} Line points.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the line points of the line annotation.
         * let linePoints: Point[] = annotation.linePoints;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._linePoints === 'undefined' && this._dictionary.has('L')) {
                var points = this._dictionary.getArray('L');
                if (points.length === 4) {
                    this._linePoints = [{ x: points[0], y: points[1] }, { x: points[2], y: points[3] }];
                }
            }
            return this._linePoints;
        },
        /**
         * Sets the line points of the line annotation.
         *
         * @param {Point[]} value Line points.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the line points of the line annotation.
         * annotation.linePoints = [{x: 10, y: 50}, {x: 250, y: 50}];
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (Array.isArray(value) && (typeof this._linePoints === 'undefined' || _arePointsNotEqual(value, this._linePoints))) {
                if (value.length === 2) {
                    this._dictionary.update('L', [value[0].x, value[0].y, value[1].x, value[1].y]);
                    this._linePoints = value;
                }
                else {
                    throw new Error('Line points length should be 2.');
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "leaderExt", {
        /**
         * Gets the line extension of the line annotation.
         *
         * @returns {number} Leader line extension.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the line extension of the line annotation.
         * let leaderExt: number = annotation.leaderExt;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._leaderExt === 'undefined' && this._dictionary.has('LLE')) {
                var leaderExt = this._dictionary.get('LLE');
                if (typeof leaderExt !== 'undefined') {
                    this._leaderExt = leaderExt;
                }
            }
            return this._leaderExt;
        },
        /**
         * Sets the line extension of the line annotation.
         *
         * @param {number} value Line extension.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the line extension of the line annotation.
         * annotation.leaderExt = 4;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!Number.isNaN(value)) {
                this._dictionary.update('LLE', value);
                this._leaderExt = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "leaderLine", {
        /**
         * Gets the leader line of the line annotation.
         *
         * @returns {number} Leader line.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the leader line of the line annotation.
         * let leaderLine: number = annotation.leaderLine;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._leaderLine === 'undefined' && this._dictionary.has('LL')) {
                var leaderLine = this._dictionary.get('LL');
                if (typeof leaderLine !== 'undefined') {
                    this._leaderLine = leaderLine;
                }
            }
            return this._leaderLine;
        },
        /**
         * Sets the leader line of the line annotation.
         *
         * @param {number} value Leader line.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the leader line of the line annotation.
         * annotation.leaderLine = 5;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!Number.isNaN(value) && this.leaderExt !== 0) {
                this._dictionary.update('LL', value);
                this._leaderLine = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "lineEndingStyle", {
        /**
         * Gets the line ending style of the line annotation.
         *
         * @returns {PdfAnnotationLineEndingStyle} Line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the line ending style of the line annotation.
         * let lineEndingStyle: PdfAnnotationLineEndingStyle = annotation.lineEndingStyle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._lineEndingStyle === 'undefined') {
                var value = new PdfAnnotationLineEndingStyle();
                value._dictionary = this._dictionary;
                if (this._dictionary.has('LE')) {
                    var lineStyles = this._dictionary.getArray('LE');
                    if (lineStyles && Array.isArray(lineStyles)) {
                        value._begin = _mapLineEndingStyle(lineStyles[0].name);
                        value._end = _mapLineEndingStyle(lineStyles[1].name);
                    }
                }
                this._lineEndingStyle = value;
            }
            return this._lineEndingStyle;
        },
        /**
         * Sets the line ending style of the line annotation.
         *
         * @param {PdfAnnotationLineEndingStyle} value Line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the line ending style of the line annotation.
         * annotation.lineEndingStyle = new PdfAnnotationLineEndingStyle({begin: PdfLineEndingStyle.openArrow, end: PdfLineEndingStyle.closeArrow});
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var style = this.lineEndingStyle;
            if (style.begin !== value.begin || style.end !== value.end) {
                style.begin = value.begin;
                style.end = value.end;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "leaderOffset", {
        /**
         * Gets the leader offset of the line annotation.
         *
         * @returns {number} Leader offset.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the leader offset value of the line annotation
         * let leaderOffset: number = annotation.leaderOffset;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._leaderOffset === 'undefined' && this._dictionary.has('LLO')) {
                var leaderOffset = this._dictionary.get('LLO');
                if (typeof leaderOffset !== 'undefined' && leaderOffset >= 0) {
                    this._leaderOffset = leaderOffset;
                }
            }
            return this._leaderOffset;
        },
        /**
         * Sets the leader offset of the line annotation.
         *
         * @param {number} value Leader line offset.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the leader offset of the line annotation.
         * annotation.leaderOffset = 1;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!Number.isNaN(value)) {
                this._dictionary.update('LLO', value);
                this._leaderOffset = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "lineIntent", {
        /**
         * Gets the line intent of the line annotation.
         *
         * @returns {PdfLineIntent} Line intent.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the line intent value of the line annotation
         * let lineIntent: PdfLineIntent = annotation.lineIntent;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._lineIntent === 'undefined' && this._dictionary.has('IT')) {
                var lineIntent = this._dictionary.get('IT');
                if (lineIntent) {
                    this._lineIntent = lineIntent.name === 'LineDimension' ? PdfLineIntent.lineDimension : PdfLineIntent.lineArrow;
                }
            }
            return this._lineIntent;
        },
        /**
         * Sets the line intent of the line annotation.
         *
         * @param {PdfLineIntent} value Line intent.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the line intent of the line annotation.
         * annotation.lineIntent = PdfLineIntent.lineDimension;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined' && value !== this.lineIntent) {
                this._lineIntent = value;
                this._dictionary.update('IT', _PdfName.get(value === PdfLineIntent.lineDimension ? 'LineDimension' : 'LineArrow'));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "measure", {
        /**
         * Gets the flag to have measurement dictionary of the line annotation.
         *
         * @returns {boolean} measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the flag to have measurement dictionary of the line annotation.
         * let measure: boolean = annotation.measure;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._measure === 'undefined') {
                this._measure = this._dictionary.has('Measure');
            }
            return this._measure;
        },
        /**
         * Sets the flag to add measurement dictionary to the line annotation.
         *
         * @param {boolean} value Measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the flag to have measurement dictionary of the line annotation.
         * annotation.measure = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                if (!this._isLoaded) {
                    this._measure = value;
                    this.caption.cap = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfLineAnnotation.prototype, "unit", {
        /**
         * Gets the measurement unit of the annotation.
         *
         * @returns {PdfMeasurementUnit} Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the measurement unit of the annotation.
         * let unit: PdfMeasurementUnit = annotation.unit;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isTextUpdated) {
                return this._unit;
            }
            if (typeof this._unit === 'undefined' || this._isLoaded) {
                if (this._dictionary.has('Contents')) {
                    var text = this._dictionary.get('Contents');
                    this._unitString = text.substring(text.length - 2);
                    this._unit = _mapMeasurementUnit(this._unitString);
                }
                else {
                    this._unit = PdfMeasurementUnit.centimeter;
                }
            }
            return this._unit;
        },
        /**
         * Sets the measurement unit of the line annotation.
         *
         * @param {PdfMeasurementUnit} value Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the measurement unit of the annotation.
         * annotation.unit = PdfMeasurementUnit.centimeter;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._measure) {
                if (!this._isLoaded && typeof value !== 'undefined') {
                    this._unit = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a line annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page Page containing the annotation.
     * @param {_PdfDictionary} dictionary Source annotation dictionary.
     * @returns {PdfLineAnnotation} annot Loaded line annotation.
     */
    PdfLineAnnotation._load = function (page, dictionary) {
        var annot = new PdfLineAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the line annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary.
     * @returns {void} nothing.
     */
    PdfLineAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation after creation/load: validates line points, adjusts for Crop/MediaBox offsets, sets defaults, and prepares bounds/appearance.
     *
     * @private
     * @param {boolean} flatten True if invoked during flattening.
     * @returns {void} nothing.
     */
    PdfLineAnnotation.prototype._postProcess = function (flatten) {
        if (typeof this.linePoints === 'undefined' || this.linePoints === null) {
            throw new Error('Line points cannot be null or undefined');
        }
        else {
            var cropOrMediaBox = this._getCropOrMediaBox();
            if (cropOrMediaBox && cropOrMediaBox.length > 3 && this.linePoints.length > 1 && typeof cropOrMediaBox[0] === 'number' && typeof cropOrMediaBox[1] === 'number' && (cropOrMediaBox[0] !== 0 || cropOrMediaBox[1] !== 0)) {
                this._linePoints[0].x += cropOrMediaBox[0];
                this._linePoints[0].y += cropOrMediaBox[1];
                this._linePoints[1].x += cropOrMediaBox[0];
                this._linePoints[1].y += cropOrMediaBox[1];
                this._dictionary.update('L', [this._linePoints[0].x, this._linePoints[0].y, this._linePoints[1].x, this._linePoints[1].y]);
            }
        }
        if (!this._dictionary.has('Cap')) {
            this._dictionary.set('Cap', false);
        }
        if (!this._dictionary.has('CP')) {
            this._dictionary.set('CP', _PdfName.get('Inline'));
        }
        if (!this._dictionary.has('LE')) {
            this.lineEndingStyle = new PdfAnnotationLineEndingStyle();
        }
        if (!this._dictionary.has('LL')) {
            this.leaderLine = 0;
        }
        if (!this._dictionary.has('LLE')) {
            this.leaderExt = 0;
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (this.border.dash === null || typeof this.border.dash === 'undefined') {
            this.border.dash = [];
            if (this.border.style === PdfBorderStyle.dashed) {
                this.border.dash = [3, 1];
            }
            else if (this.border.style === PdfBorderStyle.dot) {
                this.border.dash = [1, 1];
            }
        }
        if (this._measure) {
            this._appearanceTemplate = this._createLineMeasureAppearance(flatten);
        }
        else {
            var isUpdated = false;
            if (this._setAppearance || (this._customTemplate.has('N'))) {
                this._appearanceTemplate = this._createAppearance();
                if (this._page._isNew && !(this._flatten || flatten)) {
                    var boundsArray = this._obtainLineBounds();
                    var bounds = {
                        x: boundsArray[0],
                        y: boundsArray[1], width: boundsArray[2], height: boundsArray[3]
                    };
                    this._bounds = bounds;
                    var updatedBounds = [this._bounds.x,
                        this._bounds.y,
                        this._bounds.x + this._bounds.width,
                        this._bounds.y + this._bounds.height];
                    this._dictionary.update('Rect', updatedBounds);
                    isUpdated = true;
                }
            }
            else {
                var bounds = this._obtainLineBounds();
                var rectangleBounds = _fromRectangle({ x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] });
                if (this._page._isNew && this._page._pageSettings && this._setAppearance && !this.flatten) {
                    rectangleBounds = _updateBounds(this, bounds);
                }
                this.bounds = { x: rectangleBounds[0], y: rectangleBounds[1], width: rectangleBounds[2], height: rectangleBounds[3] };
                this._dictionary.update('Rect', rectangleBounds);
                isUpdated = true;
            }
            if (this._dictionary.has('Measure') && !isUpdated) {
                var boundsArray = this._obtainLineBounds();
                var bounds = { x: boundsArray[0],
                    y: boundsArray[1], width: boundsArray[2], height: boundsArray[3] };
                this._bounds = bounds;
                var updatedBounds = void 0;
                if (this._page && this._page._isNew && this._page._pageSettings && !this._setAppearance && !this.flatten) {
                    updatedBounds = _updateBounds(this);
                }
                else {
                    updatedBounds = [this._bounds.x,
                        this._bounds.y,
                        this._bounds.x + this._bounds.width,
                        this._bounds.y + this._bounds.height];
                }
                this._dictionary.update('Rect', updatedBounds);
                if (this.flatten && !this.measure && this._page && this._page.size && Array.isArray(this._page.size) &&
                    this._page.size.length >= 2) {
                    this._bounds = { x: boundsArray[0], y: this._page.size[1] - (boundsArray[1] + boundsArray[3]),
                        width: boundsArray[2], height: boundsArray[3] };
                }
            }
        }
    };
    /**
     * Builds or imports the appearance stream depending on state, optionally flattens the annotation (and pop-ups), and updates AP dictionary entries.
     *
     * @private
     * @param {boolean} [isFlatten=false] True if flattening is requested.
     * @returns {void} nothing.
     */
    PdfLineAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                if (this._dictionary.has('Measure')) {
                    this._appearanceTemplate = this._createLineMeasureAppearance(isFlatten);
                }
                else {
                    this._appearanceTemplate = this._createAppearance();
                }
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    if (appearanceStream instanceof _PdfBaseStream) {
                        var reference = dictionary.getRaw('N');
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate) {
                if (isFlatten) {
                    if (!this._dictionary.has('AP')) {
                        this._appearanceTemplate = this._createAppearance();
                    }
                    else {
                        var dictionary = this._dictionary.get('AP');
                        if (dictionary !== null && typeof dictionary !== 'undefined' && dictionary.has('N')) {
                            var appearanceStream = dictionary.get('N');
                            if (appearanceStream) {
                                var reference = dictionary.getRaw('N');
                                if (reference) {
                                    appearanceStream.reference = reference;
                                }
                                this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                            }
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups && isFlatten) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix, true);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else {
            var appearance = void 0;
            if (this._setAppearance || this._customTemplate.size > 0) {
                if (this._dictionary.has('AP')) {
                    appearance = this._dictionary.get('AP');
                }
                else {
                    var reference = this._crossReference._getNextReference();
                    appearance = new _PdfDictionary(this._crossReference);
                    appearance._updated = true;
                    this._crossReference._cacheMap.set(reference, appearance);
                    this._dictionary.update('AP', reference);
                }
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else if (appearance && this._appearanceTemplate && this._appearanceTemplate._content) {
                _removeDuplicateReference(appearance, this._crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Creates the measured line appearance template, draws the line, leaders, end styles, and caption with unit conversion, and updates related dictionary entries.
     *
     * @private
     * @param {boolean} _isFlatten True if called during flattening.
     * @returns {PdfTemplate} template Appearance template.
     */
    PdfLineAnnotation.prototype._createLineMeasureAppearance = function (_isFlatten) {
        var nativeRectangle = [0, 0, 0, 0];
        var area = this._convertToUnit();
        var linePoints1 = this._obtainLinePoints();
        var points = linePoints1.slice(); // shallow copy
        var graphicsPath = new PdfPath();
        graphicsPath._points = points;
        graphicsPath._pathTypes = [0, 1];
        var rectPath = graphicsPath._getBounds();
        this._bounds = { x: rectPath[0], y: rectPath[1], width: rectPath[2], height: rectPath[3] };
        var borderPen = new PdfPen(typeof this.color !== 'undefined' ? this._color : { r: 0, g: 0, b: 0 }, this.border.width);
        var backBrush;
        if (this.innerColor) {
            backBrush = new PdfBrush(this._innerColor);
        }
        nativeRectangle = this._obtainLineBounds();
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
            var bounds = [nativeRectangle[0],
                nativeRectangle[1],
                nativeRectangle[0] + nativeRectangle[2],
                nativeRectangle[1] + nativeRectangle[3]];
            this._dictionary.update('Rect', bounds);
            this._bounds = { x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] };
        }
        else {
            template = new PdfTemplate(nativeRectangle, this._crossReference);
            _setMatrix(template, 0);
            var parameter = new _PaintParameter();
            template._writeTransformation = false;
            var graphics = template.graphics;
            parameter.borderPen = borderPen;
            if (this.border.style === PdfBorderStyle.dashed) {
                parameter.borderPen._dashStyle = PdfDashStyle.dash;
                parameter.borderPen._dashPattern = [3, 1];
            }
            else if (this.border.style === PdfBorderStyle.dot) {
                parameter.borderPen._dashStyle = PdfDashStyle.dot;
                parameter.borderPen._dashPattern = [1, 1];
            }
            parameter.backBrush = backBrush;
            parameter.foreBrush = new PdfBrush(this.color);
            var linePoints = this._obtainLinePoints();
            var font = this._obtainFont();
            if ((typeof font === 'undefined' || font === null) || (!this._isLoaded && font.size === 1)) {
                font = this._lineCaptionFont;
                this._pdfFont = font;
            }
            if (typeof linePoints !== 'undefined' && linePoints.length === 2) {
                var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
                var fontSize = font.measureString(area.toFixed(2) + ' ' + this._unitString, { width: 0, height: 0 }, format, 0, 0);
                var angle = this._getAngle(this._linePoints);
                var leaderLine = 0;
                var lineAngle = 0;
                if (this.leaderLine < 0) {
                    leaderLine = -(this.leaderLine);
                    lineAngle = angle + 180;
                }
                else {
                    leaderLine = this.leaderLine;
                    lineAngle = angle;
                }
                var offset = (typeof this.leaderOffset !== 'undefined') ? (leaderLine + this.leaderOffset) : leaderLine;
                var startPoint = this._getAxisValue(this._linePoints[0], (lineAngle + 90), offset);
                var endPoint = this._getAxisValue(this._linePoints[1], (lineAngle + 90), offset);
                var lineDistance = (Math.sqrt(Math.pow((endPoint.x - startPoint.x), 2) +
                    Math.pow((endPoint.y - startPoint.y), 2)));
                var centerWidth = lineDistance / 2 - ((fontSize.width / 2) + this.border.width);
                var first = this._getAxisValue(startPoint, angle, centerWidth);
                var second = this._getAxisValue(endPoint, (angle + 180), centerWidth);
                var start = (this.lineEndingStyle.begin === PdfLineEndingStyle.openArrow ||
                    this.lineEndingStyle.begin === PdfLineEndingStyle.closedArrow) ?
                    this._getAxisValue(startPoint, angle, this.border.width) :
                    startPoint;
                var end = (this.lineEndingStyle.end === PdfLineEndingStyle.openArrow ||
                    this.lineEndingStyle.end === PdfLineEndingStyle.closedArrow) ?
                    this._getAxisValue(endPoint, angle, -this.border.width) :
                    endPoint;
                var state = void 0;
                if (this.opacity && this._opacity < 1) {
                    state = graphics.save();
                    graphics.setTransparency(this._opacity);
                }
                if (this.caption.type === PdfLineCaptionType.top ||
                    (!this.caption.cap && this.caption.type === PdfLineCaptionType.inline)) {
                    graphics.drawLine(borderPen, { x: start.x, y: -start.y }, { x: end.x, y: -end.y });
                }
                else {
                    graphics.drawLine(borderPen, { x: start.x, y: -start.y }, { x: first.x, y: -first.y });
                    graphics.drawLine(borderPen, { x: end.x, y: -end.y }, { x: second.x, y: -second.y });
                }
                if (this.opacity && this._opacity < 1) {
                    graphics.restore(state);
                }
                this._drawLineStyle(startPoint, endPoint, graphics, angle, borderPen, backBrush, this.lineEndingStyle, this.border.width);
                var leaderExt = (typeof this.leaderExt !== 'undefined' ? this._leaderExt : 0);
                var beginLineExt = this._getAxisValue(startPoint, (lineAngle + 90), leaderExt);
                graphics.drawLine(borderPen, { x: startPoint.x, y: -startPoint.y }, { x: beginLineExt.x, y: -beginLineExt.y });
                var endLineExt = this._getAxisValue(endPoint, (lineAngle + 90), leaderExt);
                graphics.drawLine(borderPen, { x: endPoint.x, y: -endPoint.y }, { x: endLineExt.x, y: -endLineExt.y });
                var beginLeaderLine = this._getAxisValue(startPoint, (lineAngle - 90), leaderLine);
                graphics.drawLine(borderPen, { x: startPoint.x, y: -startPoint.y }, { x: beginLeaderLine.x, y: -beginLeaderLine.y });
                var endLeaderLine = this._getAxisValue(endPoint, (lineAngle - 90), leaderLine);
                graphics.drawLine(borderPen, { x: endPoint.x, y: -endPoint.y }, { x: endLeaderLine.x, y: -endLeaderLine.y });
                var midpoint = lineDistance / 2;
                var centerPoint = this._getAxisValue(startPoint, angle, midpoint);
                var captionPosition = void 0;
                var height = font._getHeight();
                if (this.caption.type === PdfLineCaptionType.top) {
                    captionPosition = this._getAxisValue(centerPoint, (angle + 90), height);
                }
                else {
                    captionPosition = this._getAxisValue(centerPoint, (angle + 90), (height / 2));
                }
                graphics.translateTransform({ x: captionPosition.x, y: -captionPosition.y });
                graphics.rotateTransform(-angle);
                graphics.drawString(area.toFixed(2) + ' ' + this._unitString, font, { x: (-fontSize.width / 2), y: 0, width: 0, height: 0 }, null, parameter.foreBrush);
                graphics.restore();
            }
            if ((typeof _isFlatten !== 'undefined' && !_isFlatten) || !this._isLoaded) {
                template._content.dictionary._updated = true;
                var ref = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(ref, template._content);
                template._content.reference = ref;
                var nativeRectangle1 = [this.bounds.x,
                    this.bounds.y + this.bounds.height,
                    this.bounds.width,
                    this.bounds.height];
                var size = this._page.size;
                nativeRectangle1[1] = size.height - (this.bounds.y + this.bounds.height);
                if (this._isBounds && !this.measure) {
                    nativeRectangle = nativeRectangle1;
                    this._dictionary.update('Rect', [nativeRectangle1[0], nativeRectangle1[1], nativeRectangle1[2], nativeRectangle1[3]]);
                }
                else {
                    this._dictionary.update('Rect', [nativeRectangle[0], nativeRectangle[1], nativeRectangle[2], nativeRectangle[3]]);
                }
                var ds = 'font:' +
                    font._metrics._postScriptName +
                    ' ' +
                    font._size +
                    'pt; color:' +
                    this._colorToHex([this.color.r, this.color.g, this.color.b]);
                this._dictionary.update('DS', ds);
                if (typeof _isFlatten !== 'undefined' && !_isFlatten) {
                    if (this._dictionary.has('AP')) {
                        _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
                    }
                    var dic = new _PdfDictionary();
                    dic.set('N', ref);
                    dic._updated = true;
                    this._dictionary.set('AP', dic);
                    var measureDictionary = this._createMeasureDictionary(this._unitString);
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, measureDictionary);
                    measureDictionary._updated = true;
                    if (this._dictionary.has('Measure')) {
                        _removeDuplicateReference(this._dictionary, this._crossReference, 'Measure');
                    }
                    this._dictionary.update('Measure', reference);
                }
                var lineStyles = [];
                lineStyles.push(_PdfName.get(_reverseMapEndingStyle(this.lineEndingStyle.begin)));
                lineStyles.push(_PdfName.get(_reverseMapEndingStyle(this.lineEndingStyle.end)));
                this._dictionary.update('LE', lineStyles);
                if (this._linePoints !== null) {
                    this._dictionary.update('L', [this._linePoints[0].x, this._linePoints[0].y, this._linePoints[1].x, this._linePoints[1].y]);
                }
                else {
                    throw new Error('LinePoints cannot be null');
                }
                this._dictionary.update('C', [Number.parseFloat((this.color.r / 255).toFixed(3)),
                    Number.parseFloat((this.color.g / 255).toFixed(3)),
                    Number.parseFloat((this.color.b / 255).toFixed(3))]);
                var offset = this._dictionary.has('LLO') ? this.leaderOffset : 0;
                this._dictionary.update('Subtype', new _PdfName('Line'));
                if (this._text && this._text !== '') {
                    this._dictionary.update('Contents', this._text + ' ' + area.toFixed(2) + ' ' + this._unitString);
                }
                else {
                    this._dictionary.update('Contents', area.toFixed(2) + ' ' + this._unitString);
                }
                this._dictionary.update('IT', new _PdfName('LineDimension'));
                this._dictionary.update('LLE', this.leaderExt);
                this._dictionary.update('LLO', offset);
                if (typeof this.leaderLine !== 'undefined' && this.leaderLine !== null) {
                    this._dictionary.update('LL', this.leaderLine);
                }
                this._dictionary.update('CP', _PdfName.get(this.caption.type === PdfLineCaptionType.top ? 'Top' : 'Inline'));
                this._dictionary.update('Cap', this.caption.cap);
                var bounds = [nativeRectangle[0],
                    nativeRectangle[1],
                    nativeRectangle[0] + nativeRectangle[2],
                    nativeRectangle[1] + nativeRectangle[3]];
                this._dictionary.update('Rect', bounds);
                this._bounds = { x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] };
            }
        }
        return template;
    };
    /**
     * Calculates the signed angle between two points using arctangent and returns the negated result.
     *
     * @private
     * @param {number} startPointX Start X.
     * @param {number} startPointY Start Y.
     * @param {number} endPointX End X.
     * @param {number} endPointY End Y.
     * @returns {number} angle Angle in degrees (negated).
     */
    PdfLineAnnotation.prototype._calculateAngle = function (startPointX, startPointY, endPointX, endPointY) {
        return -(Math.atan2((endPointY - startPointY), (endPointX - startPointX)) * (180 / Math.PI));
    };
    /**
     * Computes the axis-aligned bounds of a line considering leader offset/extension, end styles, and border width.
     *
     * @private
     * @param {Point[]} linePoints Two line points [{x,y},{x,y}].
     * @param {number} leaderLineExt Leader line extension length.
     * @param {number} leaderLine Leader line length (can be negative).
     * @param {number} leaderOffset Offset distance from the line.
     * @param {PdfAnnotationLineEndingStyle} lineStyle Line ending styles (begin/end).
     * @param {number} borderWidth Stroke width.
     * @returns {{ x: number, y: number, width: number, height: number }} bounds Computed bounds.
     */
    PdfLineAnnotation.prototype._calculateLineBounds = function (linePoints, leaderLineExt, leaderLine, leaderOffset, lineStyle, borderWidth) {
        var bounds = { x: 0, y: 0, width: 0, height: 0 };
        if (linePoints && linePoints.length === 2) {
            var angle = this._getAngle(linePoints);
            var leaderLines = 0;
            var lineAngle = 0;
            if (leaderLine < 0) {
                leaderLines = -(leaderLine);
                lineAngle = angle + 180;
            }
            else {
                leaderLines = leaderLine;
                lineAngle = angle;
            }
            var point1 = { x: linePoints[0].x, y: linePoints[0].y };
            var point2 = { x: linePoints[1].x, y: linePoints[1].y };
            var x1y1 = point1;
            var x2y2 = point2;
            if (leaderOffset !== 0) {
                var offsetPoint1 = this._getAxisValue(x1y1, (lineAngle + 90), leaderOffset);
                var offsetPoint2 = this._getAxisValue(x2y2, (lineAngle + 90), leaderOffset);
                linePoints[0].x = offsetPoint1.x;
                linePoints[0].y = offsetPoint1.y;
                linePoints[1].x = offsetPoint2.x;
                linePoints[1].y = offsetPoint2.y;
                this._dictionary.update('L', [linePoints[0].x, linePoints[0].y, linePoints[1].x, linePoints[1].y]);
            }
            var startingPoint = this._getAxisValue(x1y1, (lineAngle + 90), leaderLines + leaderOffset);
            var endingPoint = this._getAxisValue(x2y2, (lineAngle + 90), leaderLines + leaderOffset);
            var beginLineLeader = this._getAxisValue(x1y1, (lineAngle + 90), leaderLineExt + leaderLines + leaderOffset);
            var endLineLeader = this._getAxisValue(x2y2, (lineAngle + 90), leaderLineExt + leaderLines + leaderOffset);
            var beginLinePoint = this._getLinePoint(lineStyle.begin, borderWidth);
            var endLinePoint = this._getLinePoint(lineStyle.end, borderWidth);
            var widthX = [];
            var heightY = [];
            if ((lineAngle >= 45 && lineAngle <= 135) || (lineAngle >= 225 && lineAngle <= 315)) {
                widthX[0] = beginLinePoint.y;
                heightY[0] = beginLinePoint.x;
                widthX[1] = endLinePoint.y;
                heightY[1] = endLinePoint.x;
            }
            else {
                widthX[0] = beginLinePoint.x;
                heightY[0] = beginLinePoint.y;
                widthX[1] = endLinePoint.x;
                heightY[1] = endLinePoint.y;
            }
            var width = Math.max(widthX[0], widthX[1]);
            var height = Math.max(heightY[0], heightY[1]);
            if (width === 0) {
                width = 1;
            }
            if (height === 0) {
                height = 1;
            }
            if (startingPoint.x === Math.min(startingPoint.x, endingPoint.x)) {
                startingPoint.x -= width * borderWidth;
                endingPoint.x += width * borderWidth;
                startingPoint.x = Math.min(startingPoint.x, linePoints[0].x);
                startingPoint.x = Math.min(startingPoint.x, beginLineLeader.x);
                endingPoint.x = Math.max(endingPoint.x, linePoints[1].x);
                endingPoint.x = Math.max(endingPoint.x, endLineLeader.x);
            }
            else {
                startingPoint.x += width * borderWidth;
                endingPoint.x -= width * borderWidth;
                startingPoint.x = Math.max(startingPoint.x, linePoints[0].x);
                startingPoint.x = Math.max(startingPoint.x, beginLineLeader.x);
                endingPoint.x = Math.min(endingPoint.x, linePoints[1].x);
                endingPoint.x = Math.min(endingPoint.x, endLineLeader.x);
            }
            if (startingPoint.y === Math.min(startingPoint.y, endingPoint.y)) {
                startingPoint.y -= height * borderWidth;
                endingPoint.y += height * borderWidth;
                startingPoint.y = Math.min(startingPoint.y, linePoints[0].y);
                startingPoint.y = Math.min(startingPoint.y, beginLineLeader.y);
                endingPoint.y = Math.max(endingPoint.y, linePoints[1].y);
                endingPoint.y = Math.max(endingPoint.y, endLineLeader.y);
            }
            else {
                startingPoint.y += height * borderWidth;
                endingPoint.y -= height * borderWidth;
                startingPoint.y = Math.max(startingPoint.y, linePoints[0].y);
                startingPoint.y = Math.max(startingPoint.y, beginLineLeader.y);
                endingPoint.y = Math.min(endingPoint.y, linePoints[1].y);
                endingPoint.y = Math.min(endingPoint.y, endLineLeader.y);
            }
            bounds = this._getBounds([startingPoint, endingPoint]);
        }
        return bounds;
    };
    /**
     * Returns characteristic half extents for a given line ending style used to expand bounds in x/y.
     *
     * @private
     * @param {PdfLineEndingStyle} style Line ending style.
     * @param {number} borderWidth Stroke width.
     * @returns {{x: number, y: number}} extents Half extents in x/y.
     */
    PdfLineAnnotation.prototype._getLinePoint = function (style, borderWidth) {
        var point = { x: 0, y: 0 };
        if (style) {
            switch (style) {
                case PdfLineEndingStyle.square:
                case PdfLineEndingStyle.circle:
                case PdfLineEndingStyle.diamond:
                    point.x = 3;
                    point.y = 3;
                    break;
                case PdfLineEndingStyle.openArrow:
                case PdfLineEndingStyle.closedArrow:
                    point.x = 1;
                    point.y = 5;
                    break;
                case PdfLineEndingStyle.rOpenArrow:
                case PdfLineEndingStyle.rClosedArrow:
                    point.x = 9 + (borderWidth / 2);
                    point.y = 5 + (borderWidth / 2);
                    break;
                case PdfLineEndingStyle.slash:
                    point.x = 5;
                    point.y = 9;
                    break;
                case PdfLineEndingStyle.butt:
                    point.x = 1;
                    point.y = 3;
                    break;
                default:
                    point.x = 0;
                    point.y = 0;
                    break;
            }
        }
        return point;
    };
    /**
     * Computes the minimal axis aligned bounding rectangle that encloses the given points.
     *
     * @private
     * @param {{x: number, y: number}[]} points Points to enclose.
     * @returns {{x: number, y: number, width: number, height: number}} bounds Enclosing rectangle.
     */
    PdfLineAnnotation.prototype._getBounds = function (points) {
        var bounds = { x: 0, y: 0, width: 0, height: 0 };
        if (points.length > 0) {
            var xmin = points[0].x;
            var xmax = points[0].x;
            var ymin = points[0].y;
            var ymax = points[0].y;
            for (var i = 1; i < points.length; ++i) {
                var point = points[i];
                xmin = Math.min(point.x, xmin);
                xmax = Math.max(point.x, xmax);
                ymin = Math.min(point.y, ymin);
                ymax = Math.max(point.y, ymax);
            }
            bounds.x = xmin;
            bounds.y = ymin;
            bounds.width = xmax - xmin;
            bounds.height = ymax - ymin;
        }
        return bounds;
    };
    /**
     * Obtains the padded line bounds from current line points and leader/ending settings and returns them as [x, y, width, height].
     *
     * @private
     * @returns {number[]} bounds Array [x, y, width, height].
     */
    PdfLineAnnotation.prototype._obtainLineBounds = function () {
        var bounds = this.bounds;
        if (typeof this.linePoints !== 'undefined' && this._linePoints.length === 2) {
            var leaderOffset = this._dictionary.has('LLO') ? this.leaderOffset : 0;
            var leaderExt = this._dictionary.has('LLE') ? this.leaderExt : 0;
            var leaderLine = this._dictionary.has('LL') ? this.leaderLine : 0;
            bounds = this._calculateLineBounds(this._linePoints, leaderExt, leaderLine, leaderOffset, this.lineEndingStyle, this.border.width);
            bounds = { x: bounds.x - 8, y: bounds.y - 8, width: (bounds.width + 2 * 8), height: (bounds.height + 2 * 8) };
        }
        return [bounds.x, bounds.y, bounds.width, bounds.height];
    };
    /**
     * Creates or reuses the normal appearance template for a line annotation, drawing the line, leaders, end styles, and optional caption.
     *
     * @private
     * @returns {PdfTemplate} returns normal appearance.
     */
    PdfLineAnnotation.prototype._createAppearance = function () {
        var bounds = this._obtainLineBounds();
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
        }
        else {
            template = new PdfTemplate(bounds, this._crossReference);
            _setMatrix(template, 0);
            var parameter = new _PaintParameter();
            template._writeTransformation = false;
            var graphics = template.graphics;
            var pen = new PdfPen(typeof this.color !== 'undefined' ? this._color : { r: 0, g: 0, b: 0 }, this.border.width);
            if (this.border.style === PdfBorderStyle.dashed) {
                pen._dashStyle = PdfDashStyle.dash;
                pen._dashPattern = [3, 1];
            }
            else if (this.border.style === PdfBorderStyle.dot) {
                pen._dashStyle = PdfDashStyle.dot;
                pen._dashPattern = [1, 1];
            }
            if (this.border.style !== PdfBorderStyle.solid && this.border.dash) {
                pen._dashPattern = this.border.dash;
            }
            parameter.borderPen = pen;
            parameter.foreBrush = new PdfBrush(this.color);
            var brush = void 0;
            if (this.innerColor) {
                brush = new PdfBrush(this._innerColor);
            }
            var font = this._obtainFont();
            if ((typeof font === 'undefined' || font === null) || (!this._isLoaded && font.size === 1)) {
                font = this._lineCaptionFont;
                this._pdfFont = font;
            }
            if (!this.text && !this._dictionary.has('Contents')) {
                this.text = this.subject;
            }
            var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
            var lineWidth = 0;
            if (this.caption.cap) {
                lineWidth = font.measureString(this.text ? this.text : '', { width: 0, height: 0 }, format, 0, 0).width; //66.71001;
            }
            if (typeof this.linePoints !== 'undefined' && this._linePoints.length === 2) {
                var angle = this._getAngle(this._linePoints);
                var leaderLine = 0;
                var lineAngle = 0;
                var leaderLineValue = this.leaderLine;
                if (leaderLineValue === null || typeof leaderLineValue === 'undefined') {
                    this._leaderLine = 0;
                    leaderLineValue = 0;
                }
                if (leaderLineValue < 0) {
                    leaderLine = -(leaderLineValue);
                    lineAngle = angle + 180;
                }
                else {
                    leaderLine = leaderLineValue;
                    lineAngle = angle;
                }
                var offset = (typeof this.leaderOffset !== 'undefined') ? (leaderLine + this.leaderOffset) : leaderLine;
                var startPoint = this._getAxisValue(this._linePoints[0], (lineAngle + 90), offset);
                var endPoint = this._getAxisValue(this._linePoints[1], (lineAngle + 90), offset);
                var lineDistance = (Math.sqrt(Math.pow((endPoint.x - startPoint.x), 2) +
                    Math.pow((endPoint.y - startPoint.y), 2)));
                var centerWidth = lineDistance / 2 - ((lineWidth / 2) + this.border.width);
                var first = this._getAxisValue(startPoint, angle, centerWidth);
                var second = this._getAxisValue(endPoint, (angle + 180), centerWidth);
                var start = (this.lineEndingStyle.begin === PdfLineEndingStyle.openArrow ||
                    this.lineEndingStyle.begin === PdfLineEndingStyle.closedArrow) ?
                    this._getAxisValue(startPoint, angle, this.border.width) :
                    startPoint;
                var end = (this.lineEndingStyle.end === PdfLineEndingStyle.openArrow ||
                    this.lineEndingStyle.end === PdfLineEndingStyle.closedArrow) ?
                    this._getAxisValue(endPoint, angle, -this.border.width) :
                    endPoint;
                if (this.opacity && this._opacity < 1) {
                    var state = graphics.save();
                    graphics.setTransparency(this._opacity);
                    this._drawLine(graphics, pen, start, end, first, second);
                    graphics.restore(state);
                }
                else {
                    this._drawLine(graphics, pen, start, end, first, second);
                }
                this._drawLineStyle(startPoint, endPoint, graphics, angle, pen, brush, this.lineEndingStyle, this.border.width);
                var leaderExt = (typeof this.leaderExt !== 'undefined' ? this._leaderExt : 0);
                var beginLineExt = this._getAxisValue(startPoint, (lineAngle + 90), leaderExt);
                graphics.drawLine(pen, { x: startPoint.x, y: -startPoint.y }, { x: beginLineExt.x, y: -beginLineExt.y });
                var endLineExt = this._getAxisValue(endPoint, (lineAngle + 90), leaderExt);
                graphics.drawLine(pen, { x: endPoint.x, y: -endPoint.y }, { x: endLineExt.x, y: -endLineExt.y });
                var beginLeaderLine = this._getAxisValue(startPoint, (lineAngle - 90), leaderLine);
                graphics.drawLine(pen, { x: startPoint.x, y: -startPoint.y }, { x: beginLeaderLine.x, y: -beginLeaderLine.y });
                var endLeaderLine = this._getAxisValue(endPoint, (lineAngle - 90), leaderLine);
                graphics.drawLine(pen, { x: endPoint.x, y: -endPoint.y }, { x: endLeaderLine.x, y: -endLeaderLine.y });
                var midpoint = lineDistance / 2;
                var centerPoint = this._getAxisValue(startPoint, angle, midpoint);
                var captionPosition = void 0;
                var height = font._getHeight();
                if (this.caption.type === PdfLineCaptionType.top) {
                    if (this._measure) {
                        captionPosition = this._getAxisValue(centerPoint, (angle + 90), 2 * height);
                    }
                    else {
                        captionPosition = this._getAxisValue(centerPoint, (angle + 90), height);
                    }
                }
                else {
                    if (this._measure) {
                        captionPosition = this._getAxisValue(centerPoint, (angle + 90), 3 * (height / 2));
                    }
                    else {
                        captionPosition = this._getAxisValue(centerPoint, (angle + 90), (height / 2));
                    }
                }
                graphics.translateTransform({ x: captionPosition.x, y: -captionPosition.y });
                graphics.rotateTransform(-angle);
                if (this.caption.cap) {
                    graphics.drawString(this.text, font, { x: (-lineWidth / 2), y: 0, width: 0, height: 0 }, null, parameter.foreBrush);
                }
                graphics.restore();
            }
        }
        var rectangleBounds = _fromRectangle({ x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] });
        this.bounds = { x: rectangleBounds[0], y: rectangleBounds[1], width: rectangleBounds[2], height: rectangleBounds[3] };
        if ((!this.measure) && (!this._dictionary.has('Measure'))) {
            this._dictionary.update('Rect', [rectangleBounds[0], rectangleBounds[1], rectangleBounds[2], rectangleBounds[3]]);
        }
        return template;
    };
    /**
     * Draws the line either as a single segment or split around the caption gap when inline captions are enabled.
     *
     * @private
     * @param {PdfGraphics} graphics Target graphics.
     * @param {PdfPen} pen Stroke pen.
     * @param {Point} start Start point (possibly adjusted).
     * @param {Point} end End point (possibly adjusted).
     * @param {Point} first First split point around caption.
     * @param {Point} second Second split point around caption.
     * @returns {void} nothing.
     */
    PdfLineAnnotation.prototype._drawLine = function (graphics, pen, start, end, first, second) {
        if (typeof this.text === 'undefined' ||
            this._text === '' ||
            this.caption.type === PdfLineCaptionType.top ||
            (!this.caption.cap && this.caption.type === PdfLineCaptionType.inline)) {
            graphics.drawLine(pen, { x: start.x, y: -start.y }, { x: end.x, y: -end.y });
        }
        else {
            graphics.drawLine(pen, { x: start.x, y: -start.y }, { x: first.x, y: -first.y });
            graphics.drawLine(pen, { x: end.x, y: -end.y }, { x: second.x, y: -second.y });
        }
    };
    /**
     * Computes the line length converted from points to the configured measurement unit and returns the numeric value.
     *
     * @private
     * @returns {number} length Line length in selected unit.
     */
    PdfLineAnnotation.prototype._convertToUnit = function () {
        var points = this._obtainLinePoints();
        var flatData = _convertPointToNumberArray(points);
        var data = new Array(flatData.length / 2);
        var count = 0;
        for (var j = 0; j < flatData.length; j = j + 2) {
            data[count] = [flatData[j], (flatData[j + 1])];
            count++;
        }
        var distance = Math.sqrt(Math.pow((data[1][0] - data[0][0]), 2) + Math.pow((data[1][1] - data[0][1]), 2));
        var value = this._getEqualPdfGraphicsUnit(this.unit, this._unitString);
        this._unitString = value.unitString;
        return (new _PdfUnitConvertor())._convertUnits(distance, _PdfGraphicsUnit.point, value.graphicsUnit);
    };
    /**
     * Returns a shallow copy of the current line points array.
     *
     * @private
     * @returns {Point[]} points Copy of line points.
     */
    PdfLineAnnotation.prototype._obtainLinePoints = function () {
        var points = this.linePoints ? this._linePoints.slice() : [];
        return points;
    };
    return PdfLineAnnotation;
}(PdfComment));
export { PdfLineAnnotation };
/**
 * `PdfCircleAnnotation` class represents the circle annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new circle annotation with circle bounds
 * const annotation: PdfCircleAnnotation = new PdfCircleAnnotation({x: 10, y: 10, width: 100, height: 100});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfCircleAnnotation = /** @class */ (function (_super) {
    __extends(PdfCircleAnnotation, _super);
    function PdfCircleAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the measurement unit used for circle annotations.
         *
         * @private
         */
        _this._unit = PdfMeasurementUnit.centimeter;
        /**
         * Determines whether the circle is measured by radius or diameter.
         *
         * @private
         */
        _this._measureType = PdfCircleMeasurementType.diameter;
        _this._unitString = '';
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Circle'));
        if (bounds !== null && typeof bounds !== 'undefined' && typeof bounds.x !== 'undefined' && typeof bounds.y !== 'undefined' && typeof bounds.width !== 'undefined' && typeof bounds.height !== 'undefined') {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.circleAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
            if ('measure' in properties && _isNullOrUndefined(properties.measure)) {
                var measure = properties.measure;
                if ('unit' in measure && _isNullOrUndefined(measure.unit)) {
                    _this.measure = true;
                    _this.unit = measure.unit;
                }
                if ('type' in measure && _isNullOrUndefined(measure.type)) {
                    _this.measure = true;
                    _this.measureType = measure.type;
                }
            }
        }
        return _this;
    }
    Object.defineProperty(PdfCircleAnnotation.prototype, "measure", {
        /**
         * Gets the flag to have measurement dictionary of the circle annotation.
         *
         * @returns {boolean} measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Gets the flag to have measurement dictionary of the circle annotation.
         * let measure: boolean = annotation.measure;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._measure) {
                this._measure = this._dictionary.has('Measure');
            }
            return this._measure;
        },
        /**
         * Sets the flag to add measurement dictionary to the annotation.
         *
         * @param {boolean} value Measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Sets the flag to have measurement dictionary of the circle annotation.
         * annotation.measure = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                if (!this._isLoaded) {
                    this._measure = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfCircleAnnotation.prototype, "unit", {
        /**
         * Gets the measurement unit of the annotation.
         *
         * @returns {PdfMeasurementUnit} Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Gets the measurement unit of the annotation.
         * let unit: PdfMeasurementUnit = annotation.unit;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isTextUpdated) {
                return this._unit;
            }
            if (typeof this._unit === 'undefined' || this._isLoaded) {
                if (this._dictionary.has('Contents')) {
                    var text = this._dictionary.get('Contents');
                    this._unitString = text.substring(text.length - 2);
                    this._unit = _mapMeasurementUnit(this._unitString);
                }
                else {
                    this._unit = PdfMeasurementUnit.centimeter;
                }
            }
            return this._unit;
        },
        /**
         * Sets the measurement unit of the annotation.
         *
         * @param {PdfMeasurementUnit} value Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Sets the measurement unit of the annotation.
         * annotation.unit = PdfMeasurementUnit.centimeter;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._measure) {
                if (!this._isLoaded && typeof value !== 'undefined') {
                    this._unit = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfCircleAnnotation.prototype, "measureType", {
        /**
         * Gets the measurement type of the annotation.
         *
         * @returns {PdfCircleMeasurementType} Measurement type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Gets the measurement type of the annotation.
         * let type: PdfCircleMeasurementType = annotation.type;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Contents')) {
                var text = this._dictionary.get('Contents');
                this._unitString = text.substring(text.length - 2);
                this._unit = _mapMeasurementUnit(this._unitString);
                var value = text.substring(0, text.length - 2);
                var converter = new _PdfUnitConvertor();
                var radius = converter._convertUnits(this.bounds.width / 2, _PdfGraphicsUnit.point, _mapGraphicsUnit(this._unitString));
                if (radius.toString() === value) {
                    this._measureType = PdfCircleMeasurementType.radius;
                }
                else {
                    this._measureType = PdfCircleMeasurementType.diameter;
                }
            }
            return this._measureType;
        },
        /**
         * Sets the measurement type of the annotation.
         *
         * @param {PdfCircleMeasurementType} value Measurement type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfCircleAnnotation = page.annotations.at(0) as PdfCircleAnnotation;
         * // Sets the measurement type of the annotation.
         * annotation.type = PdfCircleMeasurementType.diameter;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._measure) {
                if (!this._isLoaded && typeof value !== 'undefined') {
                    this._measureType = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a circle annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page Page containing the annotation.
     * @param {_PdfDictionary} dictionary Source annotation dictionary.
     * @returns {PdfCircleAnnotation} annot Loaded circle annotation.
     */
    PdfCircleAnnotation._load = function (page, dictionary) {
        var annot = new PdfCircleAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the circle annotation for the specified page and optional dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary.
     * @returns {void} nothing.
     */
    PdfCircleAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation setup: validates bounds, ensures BS/color defaults, updates Rect,
     * and builds appearance or measure appearance as needed.
     *
     * @private
     * @param {boolean} isFlatten True if invoked during flattening.
     * @returns {void} nothing.
     */
    PdfCircleAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (this._measure) {
            this._appearanceTemplate = this._createCircleMeasureAppearance(isFlatten);
        }
        else {
            this._dictionary.update('Rect', _updateBounds(this));
            if (this._setAppearance || (isFlatten && !this._dictionary.has('AP')) || this._customTemplate.size > 0) {
                this._appearanceTemplate = this._createCircleAppearance();
            }
        }
    };
    /**
     * Creates or imports the circle s appearance stream based on state, optionally flattens including pop ups,
     * and updates AP entries accordingly.
     *
     * @private
     * @param {boolean} [isFlatten=false] True if flattening is requested.
     * @returns {void} nothing.
     */
    PdfCircleAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if ((this._setAppearance || this._customTemplate.size > 0) || (isFlatten && !this._dictionary.has('AP'))) {
                if (this._dictionary.has('Measure')) {
                    this._appearanceTemplate = this._createCircleMeasureAppearance(isFlatten);
                }
                else {
                    this._appearanceTemplate = this._createCircleAppearance();
                }
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createCircleAppearance();
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary !== null && typeof dictionary !== 'undefined' && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups && isFlatten) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            var crossReference = this._crossReference;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = crossReference._getNextReference();
                appearance = new _PdfDictionary(crossReference);
                appearance._updated = true;
                crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Creates the measured circle appearance template, draws the ellipse and diameter/radius indicator
     * with a caption, and updates related dictionary entries.
     *
     * @private
     * @param {boolean} _isFlatten True if called during flattening.
     * @returns {PdfTemplate} template Appearance template.
     */
    PdfCircleAnnotation.prototype._createCircleMeasureAppearance = function (_isFlatten) {
        var borderWidth = this.border.width;
        var dictionary = this._dictionary;
        var font = this._obtainFont();
        if ((typeof font === 'undefined' || font === null) || (!this._isLoaded && font.size === 1)) {
            font = this._circleCaptionFont;
            this._pdfFont = font;
        }
        var area = this._convertToUnit();
        var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
        var str = area.toFixed(2) + ' ' + this._unitString;
        var fontsize = font.measureString(str, { width: 0, height: 0 }, format, 0, 0);
        var color = this.color ? this.color : { r: 0, g: 0, b: 0 };
        var borderPen = new PdfPen(color, borderWidth);
        var nativeRectangle = [this.bounds.x,
            (this.bounds.y + this.bounds.height),
            this.bounds.width,
            this.bounds.height];
        nativeRectangle[1] = nativeRectangle[1] - nativeRectangle[3];
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
            dictionary.update('Rect', _updateBounds(this));
        }
        else {
            template = new PdfTemplate(nativeRectangle, this._crossReference);
            var parameter = new _PaintParameter();
            template._writeTransformation = false;
            var graphics = template.graphics;
            var width = borderWidth / 2;
            parameter.borderPen = borderPen;
            if (this.innerColor) {
                parameter.backBrush = new PdfBrush(this._innerColor);
            }
            parameter.foreBrush = new PdfBrush(color);
            var rect = [nativeRectangle[0],
                -nativeRectangle[1] - nativeRectangle[3],
                nativeRectangle[2],
                nativeRectangle[3]];
            graphics.save();
            graphics.drawEllipse({ x: rect[0] + width,
                y: rect[1] + width,
                width: rect[2] - borderWidth,
                height: rect[3] - borderWidth }, new PdfPen(color, this.border.width));
            if (this._measureType === PdfCircleMeasurementType.diameter) {
                graphics.save();
                graphics.translateTransform({ x: nativeRectangle[0], y: -nativeRectangle[1] });
                var x = (nativeRectangle[3] / 2) - (fontsize.width / 2);
                graphics.drawLine(parameter.borderPen, { x: 0,
                    y: -nativeRectangle[3] / 2 }, { x: nativeRectangle[0] + nativeRectangle[2],
                    y: -nativeRectangle[3] / 2 });
                graphics.translateTransform({ x: x, y: -(nativeRectangle[3] / 2) - font._getHeight() });
                graphics.drawString(area.toFixed(2) + ' ' + this._unitString, font, { x: 0, y: 0, width: 0, height: 0 }, null, parameter.foreBrush);
                graphics.restore();
            }
            else {
                graphics.save();
                graphics.translateTransform({ x: nativeRectangle[0], y: -nativeRectangle[1] });
                var x = (nativeRectangle[2] / 2) + ((nativeRectangle[2] / 4) - (fontsize.width / 2));
                graphics.drawLine(parameter.borderPen, { x: nativeRectangle[2] / 2,
                    y: -nativeRectangle[3] / 2 }, { x: nativeRectangle[0] + nativeRectangle[2],
                    y: -nativeRectangle[3] / 2 });
                graphics.translateTransform({ x: x, y: -(nativeRectangle[3] / 2) - font._getHeight() });
                graphics.drawString(area.toFixed(2) + ' ' + this._unitString, font, { x: 0, y: 0, width: 0, height: 0 }, null, parameter.foreBrush);
                graphics.restore();
            }
            graphics.restore();
            if ((typeof _isFlatten !== 'undefined' && !_isFlatten) || !this._isLoaded) {
                if (dictionary.has('AP')) {
                    _removeDuplicateReference(dictionary.get('AP'), this._crossReference, 'N');
                }
                var dic = new _PdfDictionary();
                graphics._template._content.dictionary._updated = true;
                var ref = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(ref, graphics._template._content);
                graphics._template._content.reference = ref;
                dic.set('N', ref);
                dic._updated = true;
                dictionary.set('AP', dic);
                dictionary.update('Rect', _updateBounds(this));
                if (dictionary.has('Measure')) {
                    _removeDuplicateReference(dictionary, this._crossReference, 'Measure');
                }
                var measureDictionary = this._createMeasureDictionary(this._unitString);
                var reference = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference, measureDictionary);
                measureDictionary._updated = true;
                dictionary.update('Measure', reference);
                dictionary.update('Subtype', new _PdfName('Circle'));
                if (this._text && this._text !== '') {
                    dictionary.update('Contents', this._text + ' ' + area.toFixed(2) + ' ' + this._unitString);
                }
                else {
                    dictionary.update('Contents', area.toFixed(2) + ' ' + this._unitString);
                }
                var ds = 'font:' +
                    font._metrics._postScriptName +
                    ' ' +
                    font._size +
                    'pt; color:' +
                    this._colorToHex([this.color.r, this.color.g, this.color.b]);
                dictionary.update('DS', ds);
            }
        }
        return template;
    };
    /**
     * Converts the circles size from points to the configured measurement unit and returns the numeric value.
     *
     * @private
     * @returns {number} value Radius or diameter in the configured unit.
     */
    PdfCircleAnnotation.prototype._convertToUnit = function () {
        var converter = new _PdfUnitConvertor();
        var value = this._getEqualPdfGraphicsUnit(this.unit, this._unitString);
        this._unitString = value.unitString;
        var radius = converter._convertUnits(this.bounds.width / 2, _PdfGraphicsUnit.point, value.graphicsUnit);
        if (this._measureType === PdfCircleMeasurementType.diameter) {
            radius = 2 * radius;
        }
        return radius;
    };
    return PdfCircleAnnotation;
}(PdfComment));
export { PdfCircleAnnotation };
/**
 * `PdfEllipseAnnotation` class represents the ellipse annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new ellipse annotation with bounds
 * const annotation: PdfEllipseAnnotation = new PdfEllipseAnnotation({x: 10, y: 10, width: 100, height: 100});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfEllipseAnnotation = /** @class */ (function (_super) {
    __extends(PdfEllipseAnnotation, _super);
    function PdfEllipseAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Circle'));
        if (bounds !== null && typeof bounds !== 'undefined' && typeof bounds.x !== 'undefined' && typeof bounds.y !== 'undefined' && typeof bounds.width !== 'undefined' && typeof bounds.height !== 'undefined') {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.ellipseAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    /**
     * Loads an ellipse annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page Page containing the annotation.
     * @param {_PdfDictionary} dictionary Source annotation dictionary.
     * @returns {PdfEllipseAnnotation} annot Loaded ellipse annotation.
     */
    PdfEllipseAnnotation._load = function (page, dictionary) {
        var annot = new PdfEllipseAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the ellipse annotation for the specified page and optional dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary.
     * @returns {void} nothing.
     */
    PdfEllipseAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation setup: validates bounds, ensures BS/color defaults, builds appearance when needed,
     * and updates the Rect entry.
     *
     * @private
     * @param {boolean} isFlatten True if invoked during flattening.
     * @returns {void} nothing.
     */
    PdfEllipseAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (this._setAppearance || (isFlatten && !this._dictionary.has('AP')) || this._customTemplate.size > 0) {
            this._appearanceTemplate = this._createCircleAppearance();
        }
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Creates or imports the ellipses appearance stream based on state, optionally flattens,
     * and updates AP entries accordingly.
     *
     * @private
     * @param {boolean} [isFlatten=false] True if flattening is requested.
     * @returns {void} nothing.
     */
    PdfEllipseAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createCircleAppearance();
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createCircleAppearance();
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            var crossReference = this._crossReference;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = crossReference._getNextReference();
                appearance = new _PdfDictionary(crossReference);
                appearance._updated = true;
                crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, crossReference, 'N');
                var reference = crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    return PdfEllipseAnnotation;
}(PdfComment));
export { PdfEllipseAnnotation };
/**
 * `PdfSquareAnnotation` class represents the square annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new square annotation with bounds
 * const annotation: PdfSquareAnnotation = new PdfSquareAnnotation({x: 10, y: 10, width: 100, height: 100});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfSquareAnnotation = /** @class */ (function (_super) {
    __extends(PdfSquareAnnotation, _super);
    function PdfSquareAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the measurement unit used for square annotations.
         *
         * @private
         */
        _this._unit = PdfMeasurementUnit.centimeter;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Square'));
        if (bounds !== null && typeof bounds !== 'undefined' && typeof bounds.x !== 'undefined' && typeof bounds.y !== 'undefined' && typeof bounds.width !== 'undefined' && typeof bounds.height !== 'undefined') {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.squareAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
            if ('measurementUnit' in properties && _isNullOrUndefined(properties.measurementUnit)) {
                _this.measure = true;
                _this.unit = properties.measurementUnit;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfSquareAnnotation.prototype, "borderEffect", {
        /**
         * Gets the border effect of the square annotation.
         *
         * @returns {PdfBorderEffect} Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Gets the border effect of the square annotation.
         * let borderEffect: PdfBorderEffect = annotation.borderEffect;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._borderEffect === 'undefined') {
                var value = new PdfBorderEffect();
                value._dictionary = this._dictionary;
                if (this._dictionary.has('BE')) {
                    var dictionary = this._dictionary.get('BE');
                    value._intensity = dictionary.get('I');
                    value._style = _mapBorderEffectStyle(dictionary.get('S').name);
                }
                else {
                    value._style = PdfBorderEffectStyle.solid;
                }
                this._borderEffect = value;
            }
            return this._borderEffect;
        },
        /**
         * Sets the border effect of the square annotation.
         *
         * @param {PdfBorderEffect} value Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Sets the border effect of the square annotation.
         * annotation.borderEffect.intensity = 1;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._borderEffect = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfSquareAnnotation.prototype, "measure", {
        /**
         * Gets the flag to have measurement dictionary of the Square annotation.
         *
         * @returns {boolean} measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Gets the flag to have measurement dictionary of the square annotation.
         * let measure: boolean = annotation.measure;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._measure === 'undefined' && this._dictionary.has('Measure')) {
                this._measure = this._dictionary.get('Measure');
            }
            return this._measure;
        },
        /**
         * Sets the flag to add measurement dictionary to the annotation.
         *
         * @param {boolean} value Measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Sets the flag to have measurement dictionary of the square annotation.
         * annotation.measure = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                if (!this._isLoaded) {
                    this._measure = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfSquareAnnotation.prototype, "unit", {
        /**
         * Gets the measurement unit of the annotation.
         *
         * @returns {PdfMeasurementUnit} Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Gets the measurement unit of the annotation.
         * let unit: PdfMeasurementUnit = annotation.unit;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isTextUpdated) {
                return this._unit;
            }
            if (typeof this._unit === 'undefined') {
                this._unit = PdfMeasurementUnit.centimeter;
                if (this._dictionary.has('Contents')) {
                    var text = this._dictionary.get('Contents');
                    this._unitString = text.substring(text.length - 2);
                    this._unit = _mapMeasurementUnit(this._unitString);
                }
            }
            return this._unit;
        },
        /**
         * Sets the measurement unit of the annotation.
         *
         * @param {PdfMeasurementUnit} value Measurement unit.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Sets the measurement unit of the annotation.
         * annotation.unit = PdfMeasurementUnit.centimeter;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._measure) {
                if (!this._isLoaded && typeof value !== 'undefined') {
                    this._unit = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a square annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page Page containing the annotation.
     * @param {_PdfDictionary} dictionary Source annotation dictionary.
     * @returns {PdfSquareAnnotation} annot Loaded square annotation.
     */
    PdfSquareAnnotation._load = function (page, dictionary) {
        var annot = new PdfSquareAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the square/rectangle annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary.
     * @returns {void} nothing.
     */
    PdfSquareAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation setup: validates bounds, ensures BS/color defaults, optionally creates appearance or measure appearance,
     * updates Rect, and writes BE for cloudy borders.
     *
     * @private
     * @param {boolean} isFlatten True if invoked during flattening.
     * @returns {void} nothing.
     */
    PdfSquareAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (this._measure) {
            this._appearanceTemplate = this._createSquareMeasureAppearance(isFlatten);
        }
        else {
            if (this._setAppearance || (isFlatten && !this._dictionary.has('AP')) || this._customTemplate.size > 0) {
                this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
            }
            this._dictionary.update('Rect', _updateBounds(this));
            if (typeof this._intensity === 'undefined' &&
                typeof this._borderEffect !== 'undefined' &&
                this._borderEffect.style === PdfBorderEffectStyle.cloudy) {
                var dictionary = new _PdfDictionary(this._crossReference);
                dictionary.set('I', this.borderEffect._intensity);
                if (this.borderEffect._style === PdfBorderEffectStyle.cloudy) {
                    dictionary.set('S', _PdfName.get('C'));
                }
                this._dictionary.update('BE', dictionary);
            }
        }
    };
    /**
     * Creates or imports the rectangles appearance stream based on state or flattening needs, handles pop-up flattening, and updates AP entries accordingly.
     *
     * @private
     * @param {boolean} [isFlatten=false] True if flattening is requested.
     * @returns {void} nothing.
     */
    PdfSquareAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                if (this._dictionary.has('Measure')) {
                    this._appearanceTemplate = this._createSquareMeasureAppearance(isFlatten);
                }
                else {
                    this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
                }
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups && !this.measure) {
            if (this._isLoaded && !this._dictionary.has('Measure')) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            var crossReference = this._crossReference;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                appearance._updated = true;
                crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, crossReference, 'N');
                var reference = crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Creates the measured square appearance template, draws the rectangle and caption with area in the configured unit,
     * and updates related dictionary entries.
     *
     * @private
     * @param {boolean} _isFlatten True if flattening is requested.
     * @returns {PdfTemplate} template Appearance template.
     */
    PdfSquareAnnotation.prototype._createSquareMeasureAppearance = function (_isFlatten) {
        var borderWidth = this.border.width;
        var font = this._obtainFont();
        if ((typeof font === 'undefined' || font === null) || (!this._isLoaded && font.size === 1)) {
            font = this._circleCaptionFont;
            this._pdfFont = font;
        }
        var area = this._calculateAreaOfSquare();
        var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
        var str = area.toFixed(2) + ' sq ' + this._unitString;
        var fontsize = font.measureString(str, { width: 0, height: 0 }, format, 0, 0);
        var borderPen = new PdfPen(this.color, borderWidth);
        var backBrush;
        if (this.innerColor) {
            backBrush = new PdfBrush(this._innerColor);
        }
        var nativeRectangle = [this.bounds.x,
            (this.bounds.y + this.bounds.height),
            this.bounds.width,
            this.bounds.height];
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
            var nativeRectangle1 = [this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height];
            var size = this._page.size;
            var bounds = this.bounds;
            nativeRectangle1[1] = size.height - (bounds.y + bounds.height);
            nativeRectangle1[2] = (bounds.x + bounds.width);
            nativeRectangle1[3] = size.height - bounds.y;
            if (this._isBounds) {
                nativeRectangle = nativeRectangle1;
            }
            if (this._page._isNew && this._page._pageSettings) {
                nativeRectangle1 = _updateBounds(this);
            }
            this._dictionary.update('Rect', [nativeRectangle1[0], nativeRectangle1[1], nativeRectangle1[2], nativeRectangle1[3]]);
        }
        else {
            var appearance = new PdfAppearance({ x: this.bounds.x, y: this.bounds.y, width: this.bounds.width,
                height: this.bounds.height }, this);
            nativeRectangle[1] = nativeRectangle[1] - nativeRectangle[3];
            appearance.normal = new PdfTemplate(nativeRectangle, this._crossReference);
            template = appearance.normal;
            var parameter = new _PaintParameter();
            template._writeTransformation = false;
            var graphics = appearance.normal.graphics;
            var width = borderWidth / 2;
            parameter.borderPen = borderPen;
            parameter.backBrush = backBrush;
            parameter.foreBrush = new PdfBrush(this.color);
            var rect = [nativeRectangle[0],
                -nativeRectangle[1] - nativeRectangle[3],
                nativeRectangle[2],
                nativeRectangle[3]];
            graphics.drawRectangle({ x: rect[0] + width,
                y: rect[1] + width,
                width: rect[2] - borderWidth,
                height: rect[3] - borderWidth }, new PdfPen(this.color, this.border.width));
            graphics.save();
            graphics.translateTransform({ x: nativeRectangle[0], y: -nativeRectangle[1] });
            var x = (nativeRectangle[2] / 2) - (fontsize.width / 2);
            var y = (nativeRectangle[3] / 2) - (fontsize.height / 2);
            graphics.translateTransform({ x: x, y: -y - font._getHeight() });
            graphics.drawString((area.toFixed(2) + ' sq ' + this._unitString), font, { x: 0, y: 0, width: 0, height: 0 }, null, parameter.foreBrush);
            graphics.restore();
            if ((typeof _isFlatten !== 'undefined' && !_isFlatten) || !this._isLoaded) {
                if (this._dictionary.has('AP')) {
                    _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
                }
                var dic = new _PdfDictionary();
                var tem = graphics._template._content;
                tem.dictionary._updated = true;
                var ref = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(ref, tem);
                graphics._template._content.reference = ref;
                dic.set('N', ref);
                dic._updated = true;
                this._dictionary.set('AP', dic);
                var nativeRectangle1 = [this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height];
                var size = this._page.size;
                nativeRectangle1[1] = size.height - (this.bounds.y + this.bounds.height);
                nativeRectangle1[2] = (this.bounds.x + this.bounds.width);
                nativeRectangle1[3] = size.height - this.bounds.y;
                if (this._isBounds) {
                    nativeRectangle = nativeRectangle1;
                }
                if (this._page._isNew && this._page._pageSettings) {
                    nativeRectangle1 = _updateBounds(this);
                }
                this._dictionary.update('Rect', [nativeRectangle1[0], nativeRectangle1[1], nativeRectangle1[2], nativeRectangle1[3]]);
                if (this._dictionary.has('Measure')) {
                    _removeDuplicateReference(this._dictionary, this._crossReference, 'Measure');
                }
                var reference = this._crossReference._getNextReference();
                var measureDictionary = this._createMeasureDictionary(this._unitString);
                this._crossReference._cacheMap.set(reference, measureDictionary);
                measureDictionary._updated = true;
                this._dictionary.update('Measure', reference);
                var ds = 'font:' +
                    font._metrics._postScriptName +
                    ' ' +
                    font._size +
                    'pt; color:' +
                    this._colorToHex([this.color.r, this.color.g, this.color.b]);
                this._dictionary.update('DS', ds);
                if (this._text && this._text !== '') {
                    this._dictionary.update('Contents', this._text + ' ' + area.toFixed(2) + ' sq ' + this._unitString);
                }
                else {
                    this._dictionary.update('Contents', area.toFixed(2) + ' sq ' + this._unitString);
                }
                this._dictionary.update('Subject', ('Area Measurement'));
                if (typeof this.subject === 'undefined') {
                    this._dictionary.update('Subject', ('Area Measurement'));
                }
                this._dictionary.update('MeasurementTypes', 129);
                this._dictionary.update('Subtype', new _PdfName('Square'));
                this._dictionary.update('IT', new _PdfName('SquareDimension'));
                var elements = this._dictionary.getArray('Rect');
                var vertices = new Array(elements.length * 2);
                vertices[0] = elements[0];
                vertices[1] = elements[3];
                vertices[2] = elements[0];
                vertices[3] = elements[1];
                vertices[4] = elements[2];
                vertices[5] = elements[1];
                vertices[6] = elements[2];
                vertices[7] = elements[3];
                this._dictionary.update('Vertices', vertices);
            }
        }
        return template;
    };
    /**
     * Computes the square/rectangle area in the configured measurement unit by converting width/height from points and returning the numeric area.
     *
     * @private
     * @returns {number} area Area in the configured unit.
     */
    PdfSquareAnnotation.prototype._calculateAreaOfSquare = function () {
        var area;
        var converter = new _PdfUnitConvertor();
        var value;
        if (this.bounds.width === this.bounds.height) {
            value = this._getEqualPdfGraphicsUnit(this.unit, this._unitString);
            this._unitString = value.unitString;
            var width = converter._convertUnits(this.bounds.width, _PdfGraphicsUnit.point, value.graphicsUnit);
            area = width * width;
        }
        else {
            value = this._getEqualPdfGraphicsUnit(this.unit, this._unitString);
            this._unitString = value.unitString;
            var width = converter._convertUnits(this.bounds.width, _PdfGraphicsUnit.point, value.graphicsUnit);
            value = this._getEqualPdfGraphicsUnit(this.unit, this._unitString);
            this._unitString = value.unitString;
            var height = converter._convertUnits(this.bounds.height, _PdfGraphicsUnit.point, value.graphicsUnit);
            area = width * height;
        }
        return area;
    };
    return PdfSquareAnnotation;
}(PdfComment));
export { PdfSquareAnnotation };
/**
 * `PdfRectangleAnnotation` class represents the rectangle annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new square annotation with bounds
 * const annotation: PdfRectangleAnnotation = new PdfRectangleAnnotation({x: 10, y: 10, width: 200, height: 100});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfRectangleAnnotation = /** @class */ (function (_super) {
    __extends(PdfRectangleAnnotation, _super);
    function PdfRectangleAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Square'));
        if (bounds !== null && typeof bounds !== 'undefined' && typeof bounds.x !== 'undefined' && typeof bounds.y !== 'undefined' && typeof bounds.width !== 'undefined' && typeof bounds.height !== 'undefined') {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.rectangleAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfRectangleAnnotation.prototype, "borderEffect", {
        /**
         * Gets the border effect of the rectangle annotation.
         *
         * @returns {PdfBorderEffect} Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRectangleAnnotation = page.annotations.at(0) as PdfRectangleAnnotation;
         * // Gets the border effect of the rectangle annotation.
         * let borderEffect: PdfBorderEffect = annotation.borderEffect;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._borderEffect === 'undefined') {
                var value = new PdfBorderEffect();
                value._dictionary = this._dictionary;
                if (this._dictionary.has('BE')) {
                    var dictionary = this._dictionary.get('BE');
                    value._intensity = dictionary.get('I');
                    value._style = _mapBorderEffectStyle(dictionary.get('S').name);
                }
                else {
                    value._style = PdfBorderEffectStyle.solid;
                }
                this._borderEffect = value;
            }
            return this._borderEffect;
        },
        /**
         * Sets the border effect of the rectangle annotation.
         *
         * @param {PdfBorderEffect} value Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRectangleAnnotation = page.annotations.at(0) as PdfRectangleAnnotation;
         * // Sets the border effect of rectangle annotation.
         * annotation. borderEffect.style = PdfBorderEffectStyle.cloudy;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._borderEffect = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a rectangle annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page Page containing the annotation.
     * @param {_PdfDictionary} dictionary Source annotation dictionary.
     * @returns {PdfRectangleAnnotation} annot Loaded rectangle annotation.
     */
    PdfRectangleAnnotation._load = function (page, dictionary) {
        var annot = new PdfRectangleAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page Owning page.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary.
     * @returns {void} nothing.
     */
    PdfRectangleAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup after creation or load: validates bounds, ensures BS/color defaults, updates Rect,
     * creates appearance when needed, and writes BE for cloudy borders.
     *
     * @private
     * @param {boolean} isFlatten True if invoked during flattening.
     * @returns {void} nothing.
     */
    PdfRectangleAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dic = new _PdfDictionary(this._crossReference);
            dic.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dic);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        this._dictionary.update('Rect', _updateBounds(this));
        if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
            this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
        }
        if (typeof this._intensity === 'undefined' &&
            typeof this._borderEffect !== 'undefined' &&
            this._borderEffect.style === PdfBorderEffectStyle.cloudy) {
            var dic = new _PdfDictionary(this._crossReference);
            dic.set('I', this.borderEffect._intensity);
            if (this.borderEffect._style === PdfBorderEffectStyle.cloudy) {
                dic.set('S', _PdfName.get('C'));
            }
            this._dictionary.update('BE', dic);
        }
    };
    /**
     * Creates or imports the rectangle appearance based on state or flattening, optionally flattens (and pop-ups), and updates AP entries accordingly.
     *
     * @private
     * @param {boolean} [isFlatten=false] True if flattening is requested.
     * @returns {void} nothing.
     */
    PdfRectangleAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createRectangleAppearance(this.borderEffect);
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                if (isNormalMatrix && this._page && this._page.rotation !== PdfRotationAngle.angle0 ||
                    this._isValidTemplateMatrix(this._appearanceTemplate._content.dictionary, this.bounds, this._appearanceTemplate)) {
                    this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
                }
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, this._crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /* eslint-disable */
    /**
     * Verifies whether the templates Matrix/BBox align with the target bounds; if misaligned,
     * draws the template directly and removes the annotation.
     *
     * @private
     * @param {_PdfDictionary} dictionary Appearance stream dictionary.
     * @param {any} bounds Target bounds on page.
     * @param {PdfTemplate} appearanceTemplate Template to draw if misaligned.
     * @returns {boolean} isValidMatrix True if matrix is valid; false if drawn & removed.
     */
    PdfRectangleAnnotation.prototype._isValidTemplateMatrix = function (dictionary, bounds, appearanceTemplate) {
        var isValidMatrix = true;
        var pointF = bounds;
        if (dictionary && dictionary.has('Matrix')) {
            var box = dictionary.getArray('BBox');
            var matrix = dictionary.getArray('Matrix');
            if (matrix && box && matrix.length > 3 && box.length > 2) {
                if (typeof matrix[0] !== 'undefined' &&
                    typeof matrix[1] !== 'undefined' &&
                    typeof matrix[2] !== 'undefined' &&
                    typeof matrix[3] !== 'undefined') {
                    if (matrix[0] === 1 && matrix[1] === 0 && matrix[2] === 0 && matrix[3] === 1) {
                        if (typeof box[0] !== 'undefined' &&
                            typeof box[1] !== 'undefined' &&
                            typeof box[2] !== 'undefined' &&
                            typeof box[3] !== 'undefined') {
                            if (Math.round(box[0]) !== Math.round(-(matrix[4])) && Math.round(box[1]) !== Math.round(-(matrix[5])) ||
                                box[0] === 0 && Math.round(-(matrix[4])) === 0) {
                                var graphics = this._page.graphics;
                                var state = graphics.save();
                                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                                    graphics.setTransparency(this._opacity);
                                }
                                pointF.x -= box[0];
                                pointF.y += box[1];
                                graphics.drawTemplate(appearanceTemplate, pointF);
                                graphics.restore(state);
                                this._page.annotations.remove(this);
                                isValidMatrix = false;
                            }
                        }
                    }
                }
            }
        }
        return isValidMatrix;
    };
    return PdfRectangleAnnotation;
}(PdfComment));
export { PdfRectangleAnnotation };
/**
 * `PdfPolygonAnnotation` class represents the polygon annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new polygon annotation with bounds
 * const annotation: PdfPolygonAnnotation = new PdfPolygonAnnotation([{x: 100, y: 300}, {x: 150, y: 200}, {x: 300, y: 200}, {x: 350, y: 300}, {x: 300, y: 400}, {x: 150, y: 400}]);
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfPolygonAnnotation = /** @class */ (function (_super) {
    __extends(PdfPolygonAnnotation, _super);
    function PdfPolygonAnnotation(points, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Polygon'));
        if (typeof points !== 'undefined') {
            _this._points = points;
        }
        _this._type = _PdfAnnotationType.polygonAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfPolygonAnnotation.prototype, "borderEffect", {
        /**
         * Gets the border effect of the polygon annotation.
         *
         * @returns {PdfBorderEffect} Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation;
         * // Gets the border effect of the polygon annotation.
         * let borderEffect: PdfBorderEffect = annotation.borderEffect;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._borderEffect === 'undefined') {
                var value = new PdfBorderEffect();
                value._dictionary = this._dictionary;
                if (this._dictionary.has('BE')) {
                    var dictionary = this._dictionary.get('BE');
                    value._intensity = dictionary.get('I');
                    value._style = _mapBorderEffectStyle(dictionary.get('S').name);
                }
                else {
                    value._style = PdfBorderEffectStyle.solid;
                }
                this._borderEffect = value;
            }
            return this._borderEffect;
        },
        /**
         * Sets the border effect of the polygon annotation.
         *
         * @param {PdfBorderEffect} value Border effect.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation;
         * // Sets the border effect of the polygon annotation
         * annotation.borderEffect = new PdfBorderEffect(style: PdfBorderEffectStyle.cloudy);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._borderEffect = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPolygonAnnotation.prototype, "lineExtension", {
        /**
         * Gets the line extension of the polygon annotation.
         *
         * @returns {number} Line extension.
         *  ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation;
         * // Gets the line extension of the polygon annotation
         * let lineExtension: number = annotation.lineExtension;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._lineExtension === 'undefined' && this._dictionary.has('LLE')) {
                var lineExt = this._dictionary.get('LLE');
                if (typeof lineExt !== 'undefined' && lineExt >= 0) {
                    this._lineExtension = lineExt;
                }
            }
            return this._lineExtension;
        },
        /**
         * Sets the line extension of the polygon annotation.
         *
         * @param {number} value Line extension.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolygonAnnotation = page.annotations.at(0) as PdfPolygonAnnotation;
         * // Sets the line extension of the polygon annotation
         * annotation.lineExtension = 5;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!Number.isNaN(value)) {
                if (value >= 0) {
                    this._dictionary.update('LLE', value);
                    this._lineExtension = value;
                }
                else {
                    throw new Error('LineExtension should be non negative number');
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a polygon annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page containing the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfPolygonAnnotation} annot The loaded polygon annotation.
     */
    PdfPolygonAnnotation._load = function (page, dictionary) {
        var annot = new PdfPolygonAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the polygon annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to load from.
     * @returns {void} void No return value.
     */
    PdfPolygonAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup: validates input points, ensures defaults (line extension, color, border), normalizes points with Crop/MediaBox,
     * updates Rect/Vertices, and creates appearance when needed.
     *
     * @private
     * @param {boolean} isFlatten Whether the annotation is being flattened.
     * @returns {void} void No return value.
     */
    PdfPolygonAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this._points === 'undefined' || this._points === null) {
            throw new Error('Points cannot be null or undefined');
        }
        if (!this._dictionary.has('LLE')) {
            this.lineExtension = 0;
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dic = new _PdfDictionary(this._crossReference);
            dic.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dic);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        var array = [];
        array.push.apply(array, this._points);
        this._points = this._getPoints(this._points);
        if (array[0] !== array[array.length - 2] || array[1] !== array[array.length - 1]) {
            this._points.push(this._points[0]);
        }
        var flatData = _convertPointToNumberArray(this._points);
        var polygonBounds = this._getBoundsValue(flatData);
        var bounds = [polygonBounds.x,
            polygonBounds.y,
            polygonBounds.x + polygonBounds.width,
            polygonBounds.y + polygonBounds.height];
        this._dictionary.update('Rect', bounds);
        this._dictionary.update('LLE', this._lineExtension);
        if (this._setAppearance || (isFlatten && !this._dictionary.has('AP')) || this._customTemplate.size > 0) {
            this._appearanceTemplate = this._createPolygonAppearance(isFlatten);
        }
        var data = _convertPointToNumberArray(this._points);
        this._dictionary.update('Vertices', data);
        if (typeof this._intensity === 'undefined' &&
            typeof this._borderEffect !== 'undefined' &&
            this._borderEffect.style === PdfBorderEffectStyle.cloudy) {
            var dic = new _PdfDictionary(this._crossReference);
            dic.set('I', this.borderEffect._intensity);
            if (this.borderEffect._style === PdfBorderEffectStyle.cloudy) {
                dic.set('S', _PdfName.get('C'));
            }
            this._dictionary.update('BE', dic);
        }
    };
    /**
     * Builds or imports the polygon appearance depending on state, optionally flattens and normalizes the template matrix,
     * and updates AP entries as required.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation.
     * @returns {void} void No return value.
     */
    PdfPolygonAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        this._flatten = isFlatten;
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createPolygonAppearance(isFlatten);
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (this._dictionary.has('AP')) {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                    var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                    if (box && box.length >= 2) {
                        this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                    }
                }
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                appearance._updated = true;
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, this._crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Creates the polygon appearance template; when flattening, draws directly to the page (optionally with cloudy border),
     * otherwise builds a normal appearance with rotation and transparency handling.
     *
     * @private
     * @param {boolean} flatten Whether to build a flattening appearance.
     * @returns {PdfTemplate} template The created or imported appearance template.
     */
    PdfPolygonAnnotation.prototype._createPolygonAppearance = function (flatten) {
        if (typeof flatten !== 'undefined' && flatten) {
            var template = void 0;
            if (this._customTemplate.has('N')) {
                template = this._customTemplate.get('N');
                var flatData = _convertPointToNumberArray(this._points);
                var polygonBounds = this._getBoundsValue(flatData);
                this.bounds = { x: polygonBounds.x,
                    y: this._page.size.height - polygonBounds.y,
                    width: polygonBounds.width,
                    height: polygonBounds.height };
            }
            else {
                var borderPen = void 0;
                if (this.color && this.border.width > 0) {
                    borderPen = new PdfPen(this.color, this.border.width);
                }
                var backgroundBrush = void 0;
                if (this.innerColor) {
                    backgroundBrush = new PdfBrush(this.innerColor);
                }
                var graphics = this._page.graphics;
                if (borderPen || backgroundBrush) {
                    var state = void 0;
                    if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                        state = graphics.save();
                        graphics.setTransparency(this._opacity);
                    }
                    if (this.borderEffect.intensity !== 0 && this.borderEffect.style === PdfBorderEffectStyle.cloudy) {
                        var radius = this.borderEffect.intensity * 4 + 0.5 * this.border.width;
                        var graphicsPath = new PdfPath();
                        graphicsPath.addPolygon(this._getLinePoints());
                        this._drawCloudStyle(graphics, backgroundBrush, borderPen, radius, 0.833, graphicsPath._points, false);
                    }
                    else {
                        graphics.drawPolygon(this._getLinePoints(), borderPen, backgroundBrush);
                    }
                    if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                        graphics.restore(state);
                    }
                }
                template = graphics._template;
            }
            return template;
        }
        else {
            var boundsValue = void 0;
            var rect = { x: 0, y: 0, width: 0, height: 0 };
            if (typeof this._points === 'undefined' && this._dictionary.has('Vertices')) {
                var data = this._dictionary.get('Vertices');
                this._points = _convertToPoints(data);
                boundsValue = this._getBoundsValue(data);
            }
            else {
                var data = _convertPointToNumberArray(this._points);
                boundsValue = this._getBoundsValue(data);
            }
            if (typeof this._borderEffect !== 'undefined' &&
                typeof this.borderEffect.intensity !== 'undefined' && this.borderEffect.intensity !== 0 &&
                this._borderEffect.style === PdfBorderEffectStyle.cloudy) {
                rect.x = boundsValue.x - (this.borderEffect.intensity * 5) - this.border.width;
                rect.y = boundsValue.y - (this.borderEffect.intensity * 5) - this.border.width;
                rect.width = boundsValue.width + (this.borderEffect.intensity * 10) + (2 * this.border.width);
                rect.height = boundsValue.height + (this.borderEffect.intensity * 10) + (2 * this.border.width);
            }
            else {
                rect.x = boundsValue.x - this.border.width;
                rect.y = boundsValue.y - this.border.width;
                rect.width = boundsValue.width + (2 * this.border.width);
                rect.height = boundsValue.height + (2 * this.border.width);
            }
            var template = void 0;
            if (this._customTemplate.has('N')) {
                template = this._customTemplate.get('N');
            }
            else {
                var appearance = new PdfAppearance({ x: rect.x, y: rect.y, width: rect.width, height: rect.height }, this);
                appearance.normal = new PdfTemplate([rect.x, rect.y, rect.width, rect.height], this._crossReference);
                template = appearance.normal;
                _setMatrix(template, this._getRotationAngle());
                template._writeTransformation = false;
                var graphics = appearance.normal.graphics;
                var parameter = new _PaintParameter();
                if (this.innerColor) {
                    parameter.backBrush = new PdfBrush(this._innerColor);
                }
                if (this.border.width > 0 && this.color) {
                    parameter.borderPen = new PdfPen(this._color, this.border.width);
                }
                if (this.color) {
                    parameter.foreBrush = new PdfBrush(this._color);
                }
                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                    graphics.save();
                    graphics.setTransparency(this._opacity);
                }
                else {
                    graphics.save();
                }
                if (_isNullOrUndefined(this.borderEffect) && _isNullOrUndefined(this.borderEffect.intensity) &&
                    this.borderEffect.intensity !== 0 && this.borderEffect.style === PdfBorderEffectStyle.cloudy) {
                    var radius = this.borderEffect.intensity * 4 + 0.5 * this.border.width;
                    var graphicsPath = new PdfPath();
                    graphicsPath.addPolygon(this._getLinePoints());
                    this._drawCloudStyle(graphics, parameter.backBrush, parameter.borderPen, radius, 0.833, graphicsPath._points, false);
                }
                else {
                    graphics.drawPolygon(this._getLinePoints(), parameter.borderPen, parameter.backBrush);
                }
                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                    graphics.restore();
                }
                graphics.restore();
                if (this._isBounds) {
                    template._content.dictionary._updated = true;
                    if (typeof this.lineExtension === 'number') {
                        this._dictionary.update('LLE', this.lineExtension);
                    }
                    var data = _convertPointToNumberArray(this._points);
                    this._dictionary.update('Vertices', data);
                }
            }
            this._dictionary.update('Rect', [rect.x, rect.y, rect.x + rect.width, rect.y + rect.height]);
            return template;
        }
    };
    /**
     * Returns the polygons points transformed into page or appearance space, accounting for page rotation, flattening, and Vertices storage.
     *
     * @private
     * @returns {Point[]} polygonPointArray the transformed polygon points.
     */
    PdfPolygonAnnotation.prototype._getLinePoints = function () {
        var _this = this;
        var polygonPoints;
        var pageSize = this._page.size;
        var pageHeight = pageSize.height;
        var pageWidth = pageSize.width;
        if (this._dictionary.has('Vertices') && !this._isBounds) {
            var rotation = void 0;
            if (this._page._pageDictionary.has('Rotate')) {
                rotation = this._page._pageDictionary.get('Rotate');
            }
            var pageRotation = this._page.rotation;
            if (this._page && pageRotation) {
                if (pageRotation === PdfRotationAngle.angle90) {
                    rotation = 90;
                }
                else if (pageRotation === PdfRotationAngle.angle180) {
                    rotation = 180;
                }
                else if (pageRotation === PdfRotationAngle.angle270) {
                    rotation = 270;
                }
            }
            var linePoints = this._dictionary.getArray('Vertices');
            if (linePoints) {
                var points = linePoints.slice();
                polygonPoints = [];
                for (var j = 0; j < points.length; j = j + 2) {
                    var yValue = this.flatten ? (pageHeight - points[j + 1]) : -points[j + 1];
                    polygonPoints.push([points[j], yValue]);
                }
                if (rotation) {
                    if (rotation === 270) {
                        polygonPoints.forEach(function (point) {
                            var x = point[0];
                            point[0] = point[1];
                            point[1] = pageWidth - x;
                        });
                    }
                    else if (rotation === 90) {
                        polygonPoints.forEach(function (point) {
                            var x = point[0];
                            if (_this._page._origin[1] !== 0) {
                                point[0] = pageHeight - (point[1] - pageHeight);
                            }
                            else {
                                point[0] = pageHeight - point[1];
                            }
                            point[1] = x;
                        });
                    }
                    else if (rotation === 180) {
                        polygonPoints.forEach(function (point) {
                            var x = point[0];
                            point[0] = pageWidth - x;
                            point[1] = pageHeight - point[1];
                        });
                    }
                }
            }
        }
        else if (this._points) {
            var points = _convertPointToNumberArray(this._points);
            polygonPoints = [];
            for (var j = 0; j < points.length; j = j + 2) {
                var yValue = this.flatten ? (pageHeight - points[j + 1]) : -points[j + 1];
                polygonPoints.push([points[j], yValue]);
            }
        }
        var polygonPointArray = _convertNumberArraysToPoints(polygonPoints);
        return polygonPointArray;
    };
    return PdfPolygonAnnotation;
}(PdfComment));
export { PdfPolygonAnnotation };
/**
 * `PdfPolyLineAnnotation` class represents the polyline annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new poly line annotation with bounds
 * const annotation: PdfPolyLineAnnotation = new PdfPolyLineAnnotation ([{x: 100, y: 300}, {x: 180, y: 250}, {x: 300, y: 260}, {x: 360, y: 320}]);
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfPolyLineAnnotation = /** @class */ (function (_super) {
    __extends(PdfPolyLineAnnotation, _super);
    function PdfPolyLineAnnotation(points, properties) {
        var _this = _super.call(this) || this;
        _this._beginLine = PdfLineEndingStyle.none;
        _this._endLine = PdfLineEndingStyle.none;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('PolyLine'));
        if (typeof points !== 'undefined') {
            _this._points = points;
        }
        else {
            _this._points = [];
        }
        _this._type = _PdfAnnotationType.polyLineAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('lineEndingStyle' in properties && _isNullOrUndefined(properties.lineEndingStyle)) {
                _this.beginLineStyle = properties.lineEndingStyle.begin;
                _this.endLineStyle = properties.lineEndingStyle.end;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfPolyLineAnnotation.prototype, "beginLineStyle", {
        /**
         * Gets the begin line ending style of the annotation.
         *
         * @returns {PdfLineEndingStyle} Begin line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Gets the begin line ending style of the annotation.
         * let beginLineStyle: PdfLineEndingStyle = annotation.beginLineStyle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('LE')) {
                var lineStyles = this._dictionary.getArray('LE');
                if (lineStyles && Array.isArray(lineStyles)) {
                    this._beginLine = _mapLineEndingStyle(lineStyles[0].name);
                }
            }
            return this._beginLine;
        },
        /**
         * Sets the begin line ending style of the annotation.
         *
         * @param {PdfLineEndingStyle} value Begin line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Sets the begin line ending style of the annotation.
         * annotation.beginLineStyle = PdfLineEndingStyle.slash;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._beginLine) {
                this._beginLine = value;
                if (this._dictionary) {
                    var lineStyle = [];
                    lineStyle.push(_PdfName.get(_reverseMapEndingStyle(value)));
                    lineStyle.push(_PdfName.get(_reverseMapEndingStyle(this.endLineStyle)));
                    this._dictionary.update('LE', lineStyle);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPolyLineAnnotation.prototype, "endLineStyle", {
        /**
         * Gets the end line ending style of the annotation.
         *
         * @returns {PdfLineEndingStyle} End line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Gets the end line ending style of the annotation.
         * let endLineStyle: PdfLineEndingStyle = annotation.endLineStyle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('LE')) {
                var lineStyles = this._dictionary.getArray('LE');
                if (lineStyles && Array.isArray(lineStyles)) {
                    this._endLine = _mapLineEndingStyle(lineStyles[1].name);
                }
            }
            return this._endLine;
        },
        /**
         * Sets the end line ending style of the annotation.
         *
         * @param {PdfLineEndingStyle} value End line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Sets the end line ending style of the annotation.
         * annotation.endLineStyle = PdfLineEndingStyle.square;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._endLine) {
                this._endLine = value;
                if (this._dictionary) {
                    var lineStyle = [];
                    lineStyle.push(_PdfName.get(_reverseMapEndingStyle(this.beginLineStyle)));
                    lineStyle.push(_PdfName.get(_reverseMapEndingStyle(value)));
                    this._dictionary.update('LE', lineStyle);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPolyLineAnnotation.prototype, "lineExtension", {
        /**
         * Gets the line extension of the square annotation.
         *
         * @returns {number} Line extension.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Gets the line extension of annotation.
         * let lineExtension: number = annotation.lineExtension;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._lineExtension === 'undefined' && this._dictionary.has('LLE')) {
                var lineExt = this._dictionary.get('LLE');
                if (typeof lineExt !== 'undefined' && lineExt >= 0) {
                    this._lineExtension = lineExt;
                }
            }
            return this._lineExtension;
        },
        /**
         * Sets the line extension of the square annotation.
         *
         * @param {number} value Line extension.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPolyLineAnnotation = page.annotations.at(0) as PdfPolyLineAnnotation;
         * // Sets the line extension of the annotation.
         * annotation.lineExtension = 3;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!Number.isNaN(value)) {
                if (value >= 0) {
                    this._dictionary.update('LLE', value);
                    this._lineExtension = value;
                }
                else {
                    throw new Error('LineExtension should be non negative number');
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a polyline annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains this annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfPolyLineAnnotation} annot The loaded polyline annotation instance.
     */
    PdfPolyLineAnnotation._load = function (page, dictionary) {
        var annot = new PdfPolyLineAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the polyline annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfPolyLineAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by validating points, setting defaults for line extension, color, and border,
     * computing bounds, updating dictionary entries, and generating appearance when required.
     *
     * @private
     * @param {boolean} isFlatten Whether the annotation is being flattened.
     * @returns {void} void No return value.
     */
    PdfPolyLineAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this._points === 'undefined' || this._points === null) {
            throw new Error('Points cannot be null or undefined');
        }
        if (!this._dictionary.has('LLE')) {
            this.lineExtension = 0;
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        var points = this._getLinePoints();
        var pathTypes = [];
        pathTypes.push(0);
        for (var i = 1; i < points.length; i++) {
            pathTypes.push(1);
        }
        this._polylinePoints = points;
        this._pathTypes = pathTypes;
        var path = new PdfPath();
        path._points = points;
        path._pathTypes = pathTypes;
        var newPoints = [];
        for (var _i = 0, _a = this._points; _i < _a.length; _i++) {
            var pt = _a[_i];
            newPoints.push(pt.x, pt.y);
        }
        this._dictionary.update('Vertices', newPoints);
        var lineStyle = [];
        lineStyle.push(_PdfName.get(_reverseMapEndingStyle(this.beginLineStyle)));
        lineStyle.push(_PdfName.get(_reverseMapEndingStyle(this.endLineStyle)));
        this._dictionary.update('LE', lineStyle);
        this._dictionary.update('LLE', this._lineExtension);
        var data = _convertPointToNumberArray(this._points);
        var polyLineBounds = this._getBoundsValue(data);
        var rectangle = [polyLineBounds.x,
            polyLineBounds.y,
            polyLineBounds.x + polyLineBounds.width,
            polyLineBounds.y + polyLineBounds.height];
        this._dictionary.update('Rect', rectangle);
        if (this._setAppearance || (isFlatten && !this._dictionary.has('AP')) || this._customTemplate.size > 0) {
            this._appearanceTemplate = this._createPolyLineAppearance(isFlatten);
        }
    };
    /**
     * Builds or imports the polyline appearance based on state, handles flattening logic,
     * updates AP entries, and draws or replaces templates when needed.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfPolyLineAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        this._flatten = isFlatten;
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createPolyLineAppearance(isFlatten);
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createPolyLineAppearance(isFlatten);
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                    var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                    if (box) {
                        this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                    }
                }
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                appearance._updated = true;
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, this._crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Converts a point from annotation coordinate space into PDF drawing coordinate space by negating the y axis.
     *
     * @private
     * @param {Point} point The point to transform.
     * @returns {Point} transformedPoint The transformed point in PDF coordinate space.
     */
    PdfPolyLineAnnotation.prototype._transformToPdfCoordinates = function (point) {
        return { x: point.x, y: -point.y };
    };
    /* eslint-disable */
    /**
     * Expands the provided bounds by the specified border width and returns the updated rectangle.
     *
     * @private
     * @param {{x: number, y: number, width: number, height: number}} boundsValue The original bounds. // eslint-disable-line
     * @param {number} borderWidth The border width to expand by.
     * @returns {{x: number, y: number, width: number, height: number}} updatedBounds The expanded bounds rectangle.
     */
    PdfPolyLineAnnotation.prototype._updateBorder = function (boundsValue, borderWidth) {
        return { x: boundsValue.x - borderWidth,
            y: boundsValue.y - borderWidth, width: boundsValue.width + (2 * borderWidth),
            height: boundsValue.height + (2 * borderWidth) };
    };
    /* eslint-enable */
    /**
     * Computes the start and end angles of the polyline based on its transformed points and returns angle values
     * along with the transformed endpoints.
     *
     * @private
     * @param {PdfPath} path The path representing the polyline.
     * @returns {{startAngle: number, endAngle: number, transformedStart: Point, transformedEnd: Point}} result Angles and transformed endpoints.
     */
    PdfPolyLineAnnotation.prototype._prepareStartEndAngle = function (path) {
        var transformedStart = this._transformToPdfCoordinates(path._points[0]);
        var transformedNext = this._transformToPdfCoordinates(path._points[1]);
        var transformedEnd = this._transformToPdfCoordinates(path._points[path._points.length - 1]);
        var transformedPrev = this._transformToPdfCoordinates(path._points[path._points.length - 2]);
        var startAngle = this._getAngle([transformedStart, transformedNext]);
        var endAngle = this._getAngle([transformedPrev, transformedEnd]);
        return { startAngle: startAngle, endAngle: endAngle, transformedStart: transformedStart, transformedEnd: transformedEnd };
    };
    /**
     * Creates the polyline appearance template, handling flattening, path construction, border and fill rendering,
     * and drawing of start/end line styles.
     *
     * @private
     * @param {boolean} flatten Whether to build a flattening appearance.
     * @returns {PdfTemplate} template The created or imported appearance template.
     */
    PdfPolyLineAnnotation.prototype._createPolyLineAppearance = function (flatten) {
        var color = this.color ? this.color : { r: 0, g: 0, b: 0 };
        if (typeof flatten !== 'undefined' && flatten) {
            var template = void 0;
            if (this._customTemplate.has('N')) {
                template = this._customTemplate.get('N');
                var data = _convertPointToNumberArray(this._points);
                var polyLineBounds = this._getBoundsValue(data);
                this.bounds = { x: polyLineBounds.x,
                    y: this._page.size.height - polyLineBounds.y,
                    width: polyLineBounds.width,
                    height: polyLineBounds.height };
            }
            else {
                var borderPen = void 0;
                if (this.border.width > 0) {
                    borderPen = new PdfPen(color, this.border.width);
                }
                var backBrush = void 0;
                if (this.innerColor) {
                    backBrush = new PdfBrush(this._innerColor);
                }
                var graphics = this._page.graphics;
                if (borderPen) {
                    var state = void 0;
                    if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                        state = graphics.save();
                        graphics.setTransparency(this._opacity);
                    }
                    var points = this._getLinePoints();
                    var pathTypes = [];
                    pathTypes.push(0);
                    if (points && points.length > 0) {
                        for (var i = 1; i < points.length; i++) {
                            pathTypes.push(1);
                        }
                        var path = new PdfPath();
                        path._points = points;
                        path._pathTypes = pathTypes;
                        var angles = this._prepareStartEndAngle(path);
                        var startPoint = this._getAxisValue(angles.transformedStart, angles.startAngle + 90);
                        var endPoint = this._getAxisValue(angles.transformedEnd, angles.endAngle + 90);
                        var startPoint1 = startPoint;
                        var endPoint1 = endPoint;
                        if (this.beginLineStyle === PdfLineEndingStyle.closedArrow ||
                            this.beginLineStyle === PdfLineEndingStyle.openArrow) {
                            startPoint1 = this._getAxisValue(startPoint, angles.startAngle, this.border.width);
                            path._points[0].x = startPoint1.x;
                            path._points[0].y = -startPoint1.y;
                        }
                        if (this.endLineStyle === PdfLineEndingStyle.closedArrow || this.endLineStyle === PdfLineEndingStyle.openArrow) {
                            endPoint1 = this._getAxisValue(endPoint, angles.endAngle, -this.border.width);
                            path._points[path._points.length - 1].x = endPoint1.x;
                        }
                        graphics.drawPath(path, borderPen);
                        if (this.beginLineStyle !== PdfLineEndingStyle.none) {
                            this._drawLineEndStyle(startPoint, graphics, angles.startAngle, borderPen, backBrush, this.beginLineStyle, this.border.width, true);
                        }
                        if (this.endLineStyle !== PdfLineEndingStyle.none) {
                            this._drawLineEndStyle(endPoint, graphics, angles.endAngle, borderPen, backBrush, this.endLineStyle, this.border.width, false);
                        }
                        if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                            graphics.restore(state);
                        }
                    }
                }
                template = graphics._template;
            }
            return template;
        }
        else {
            var rect = { x: 0, y: 0, width: 0, height: 0 };
            var data = void 0;
            if ((typeof this._points === 'undefined' || (this._points && this._points.length === 0)) && this._dictionary.has('Vertices')) {
                data = this._dictionary.get('Vertices');
                this._points = _convertToPoints(data);
            }
            else if (_isPointArray(this._points)) {
                data = _convertPointToNumberArray(this._points);
            }
            rect = this._updateBorder(this._getBoundsValue(data), this.border.width);
            var parameter = new _PaintParameter();
            if (this.innerColor) {
                parameter.backBrush = new PdfBrush(this._innerColor);
            }
            if (this.border.width > 0 && color) {
                parameter.borderPen = new PdfPen(color, this.border.width);
            }
            if (color) {
                parameter.foreBrush = new PdfBrush(color);
            }
            var path = new PdfPath();
            if (typeof this._polylinePoints !== 'undefined' && this._polylinePoints !== null) {
                path._points = this._polylinePoints;
            }
            else {
                path._points = this._getLinePoints();
            }
            if (typeof this._pathTypes !== 'undefined' && this._polylinePoints !== null) {
                path._pathTypes = this._pathTypes;
            }
            else {
                this._pathTypes = [];
                this._pathTypes.push(0);
                for (var i = 1; i < path._points.length; i++) {
                    this._pathTypes.push(1);
                }
                path._pathTypes = this._pathTypes;
            }
            var angles = this._prepareStartEndAngle(path);
            var startPoint = this._getAxisValue(angles.transformedStart, angles.startAngle + 90);
            var endPoint = this._getAxisValue(angles.transformedEnd, angles.endAngle + 90);
            var newStart = startPoint;
            var newEnd = endPoint;
            if (this.beginLineStyle === PdfLineEndingStyle.closedArrow || this.beginLineStyle === PdfLineEndingStyle.openArrow) {
                newStart = this._getAxisValue(startPoint, angles.startAngle, this.border.width);
                path._points[0].x = newStart.x;
                path._points[0].y = -newStart.y;
            }
            if (this.endLineStyle === PdfLineEndingStyle.closedArrow || this.endLineStyle === PdfLineEndingStyle.openArrow) {
                newEnd = this._getAxisValue(endPoint, angles.endAngle, -this.border.width);
                path._points[path._points.length - 1].x = newEnd.x;
            }
            var beginLineStyleBounds = void 0;
            if (this.beginLineStyle !== PdfLineEndingStyle.none) {
                beginLineStyleBounds = this._getBoundsFromLineEndStyle(startPoint, angles.startAngle, parameter.borderPen, this.beginLineStyle, this.border.width, true);
                rect = this._getCombinedRectangleBounds(rect, beginLineStyleBounds);
            }
            var endLineStyleBounds = void 0;
            if (this.endLineStyle !== PdfLineEndingStyle.none) {
                endLineStyleBounds = this._getBoundsFromLineEndStyle(endPoint, angles.endAngle, parameter.borderPen, this.endLineStyle, this.border.width, false);
                rect = this._getCombinedRectangleBounds(rect, endLineStyleBounds);
            }
            var template = void 0;
            if (this._customTemplate.has('N')) {
                template = this._customTemplate.get('N');
            }
            else {
                var appearance = new PdfAppearance({ x: rect.x, y: rect.y, width: rect.width, height: rect.height }, this);
                appearance.normal = new PdfTemplate([rect.x, rect.y, rect.width, rect.height], this._crossReference);
                template = appearance.normal;
                _setMatrix(template, 0);
                template._writeTransformation = false;
                var graphics = appearance.normal.graphics;
                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                    graphics.save();
                    graphics.setTransparency(this._opacity);
                }
                else {
                    graphics.save();
                }
                graphics.drawPath(path, parameter.borderPen);
                if (this.beginLineStyle !== PdfLineEndingStyle.none) {
                    this._drawLineEndStyle(startPoint, graphics, angles.startAngle, parameter.borderPen, parameter.backBrush, this.beginLineStyle, this.border.width, true);
                }
                if (this.endLineStyle !== PdfLineEndingStyle.none) {
                    this._drawLineEndStyle(endPoint, graphics, angles.endAngle, parameter.borderPen, parameter.backBrush, this.endLineStyle, this.border.width, false);
                }
                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                    graphics.restore();
                }
                graphics.restore();
                if (this._isBounds) {
                    template._content.dictionary._updated = true;
                    this._dictionary.update('LE', [_PdfName.get(_reverseMapEndingStyle(this.beginLineStyle)), _PdfName.get(_reverseMapEndingStyle(this.endLineStyle))]);
                    this._dictionary.update('LLE', this.lineExtension);
                    var vertices_1 = [];
                    this._points.forEach(function (point) {
                        vertices_1.push(point.x, point.y);
                    });
                    this._dictionary.update('Vertices', vertices_1);
                }
            }
            this._dictionary.update('Rect', [rect.x, rect.y, rect.x + rect.width, rect.y + rect.height]);
            return template;
        }
    };
    /**
     * Returns the polylines points transformed into page or annotation space, accounting for Vertices usage,
     * page rotation, and flattening conditions.
     *
     * @private
     * @returns {Point[]} points The transformed polyline points.
     */
    PdfPolyLineAnnotation.prototype._getLinePoints = function () {
        var pageSize = this._page.size;
        var pageHeight = pageSize.height;
        var points = [];
        if (this._dictionary.has('Vertices') && !this._isBounds && (!this._setAppearance || (this._setAppearance && this.flatten))) {
            var linePoints = this._dictionary.getArray('Vertices');
            if (linePoints) {
                for (var j = 0; j < linePoints.length; j += 2) {
                    points.push({
                        x: linePoints[j],
                        y: pageHeight - linePoints[j + 1]
                    });
                }
            }
        }
        else if (this._points) {
            this._points = this._getPoints(this._points);
            var polyLinepoints_1 = [];
            this._points.forEach(function (pt) {
                polyLinepoints_1.push(pt.x, pt.y);
            });
            for (var j = 0; j < polyLinepoints_1.length; j += 2) {
                var yValue = this.flatten ? (pageHeight - polyLinepoints_1[j + 1]) : -polyLinepoints_1[j + 1];
                points.push({
                    x: polyLinepoints_1[j],
                    y: yValue
                });
            }
        }
        return points;
    };
    return PdfPolyLineAnnotation;
}(PdfComment));
export { PdfPolyLineAnnotation };
/**
 * `PdfAngleMeasurementAnnotation` class represents the angle measurement annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new angle measurement annotation
 * const annotation: PdfAngleMeasurementAnnotation = new PdfAngleMeasurementAnnotation({x: 100, y: 700}, {x: 150, y: 650}, {x: 100, y: 600});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAngleMeasurementAnnotation = /** @class */ (function (_super) {
    __extends(PdfAngleMeasurementAnnotation, _super);
    function PdfAngleMeasurementAnnotation(startPoint, midPoint, endPoint, properties) {
        var _this = _super.call(this) || this;
        /**
         * Stores the points used to define the angle for measurement.
         *
         * @private
         */
        _this._linePoints = [];
        _this._firstIntersectionPoint = [0, 0];
        _this._secondIntersectionPoint = [0, 0];
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('PolyLine'));
        if (startPoint && midPoint && endPoint) {
            _this._pointArray = [startPoint, midPoint, endPoint];
        }
        if (Array.isArray(_this._pointArray) && _this._pointArray.length > 3) {
            throw new Error('Points length should not be greater than 3');
        }
        _this._linePoints = [];
        if (Array.isArray(_this._pointArray) && _this._pointArray.length > 0) {
            _this._pointArray.forEach(function (point) {
                _this._linePoints.push(point.x);
                _this._linePoints.push(point.y);
            });
        }
        _this._type = _PdfAnnotationType.angleMeasurementAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfAngleMeasurementAnnotation.prototype, "measure", {
        /**
         * Gets the flag to have measurement dictionary of the angle measurement annotation.
         *
         * @returns {boolean} measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfAngleMeasurementAnnotation = page.annotations.at(0) as PdfAngleMeasurementAnnotation;
         * // Gets the flag to have measurement dictionary of the angle annotation.
         * let measure: boolean = annotation.measure;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._measure === 'undefined' && this._dictionary.has('Measure')) {
                this._measure = this._dictionary.get('Measure');
            }
            return this._measure;
        },
        /**
         * Sets the flag to add measurement dictionary to the annotation.
         *
         * @param {boolean} value Measure.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfAngleMeasurementAnnotation = page.annotations.at(0) as PdfAngleMeasurementAnnotation;
         * // Sets the flag to add measurement dictionary to the annotation.
         * annotation.measure = true;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value && !this._isLoaded) {
                this._measure = value;
                this.caption.cap = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads an angle measurement annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfAngleMeasurementAnnotation} annot The loaded angle measurement annotation instance.
     */
    PdfAngleMeasurementAnnotation._load = function (page, dictionary) {
        var annot = new PdfAngleMeasurementAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the angle measurement annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfAngleMeasurementAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by validating points, ensuring BS/color defaults, setting a fallback border width, and generating the angle measurement appearance.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfAngleMeasurementAnnotation.prototype._postProcess = function () {
        if (!this._pointArray) {
            throw new Error('Points cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        this._appearanceTemplate = this._createAngleMeasureAppearance();
    };
    /**
     * Builds or imports the angle measurement appearance based on state and flattening, updates AP entries, or flattens the template when required.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfAngleMeasurementAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (!isFlatten && (this._setAppearance || this._customTemplate.size > 0)) {
                this._appearanceTemplate = this._createAngleMeasureAppearance();
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess();
            if (!this._appearanceTemplate) {
                if (isFlatten) {
                    if (!this._dictionary.has('AP')) {
                        this._appearanceTemplate = this._createAngleMeasureAppearance();
                    }
                    else {
                        var dictionary = this._dictionary.get('AP');
                        if (dictionary && dictionary.has('N')) {
                            var appearanceStream = dictionary.get('N');
                            var reference = dictionary.getRaw('N');
                            if (appearanceStream) {
                                if (reference) {
                                    appearanceStream.reference = reference;
                                }
                                this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                            }
                        }
                    }
                }
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                    var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                    if (box) {
                        this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                    }
                }
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
        }
        else if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                appearance._updated = true;
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, this._crossReference, 'N');
                var reference = this._crossReference._getNextReference();
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                appearance.update('N', reference);
            }
        }
    };
    /**
     * Creates the angle measurement appearance template, computes the angle/caption, writes measurement metadata, draws the polyline and arc, and updates AP/Rect entries.
     *
     * @private
     * @returns {PdfTemplate} template The created or imported appearance template.
     */
    PdfAngleMeasurementAnnotation.prototype._createAngleMeasureAppearance = function () {
        var borderWidth = this.border.width;
        var font = this._obtainFont();
        if ((typeof font === 'undefined' || font === null) || (!this._isLoaded && font.size === 1)) {
            font = this._circleCaptionFont;
            this._pdfFont = font;
        }
        var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
        var angle = (this._calculateAngle() * (180.0 / Math.PI));
        if (angle < 0) {
            angle = -angle;
        }
        if (angle > 180) {
            angle = 360 - angle;
        }
        this._dictionary.update('Vertices', this._linePoints);
        var ds = 'font:' +
            font._metrics._postScriptName +
            ' ' +
            font._size +
            'pt; color:' +
            this._colorToHex([this.color.r, this.color.g, this.color.b]);
        this._dictionary.update('DS', ds);
        if (this.text === (' ' + angle.toFixed(2) + '°')) {
            this._dictionary.update('Contents', this.text);
        }
        else if (this.text) {
            this._dictionary.update('Contents', this.text);
        }
        if (typeof this.subject === 'undefined') {
            this._dictionary.update('Subject', 'Angle Measurement');
        }
        this._dictionary.update('MeasurementTypes', 1152);
        this._dictionary.update('Subtype', new _PdfName('PolyLine'));
        this._dictionary.update('IT', new _PdfName('PolyLineAngle'));
        var measureDictionary = new _PdfDictionary();
        var d = [];
        var t = [];
        var a = [];
        var x = [];
        var v = [];
        measureDictionary.set('Type', _PdfName.get('measureDictionary'));
        measureDictionary.set('R', '1 in = 1 in');
        measureDictionary.set('Subtype', 'RL');
        measureDictionary.set('TargetUnitConversion', 0.1388889);
        var dDictionary = new _PdfDictionary();
        dDictionary.set('U', 'in');
        dDictionary.set('Type', 'NumberFormat');
        dDictionary.set('C', 1);
        dDictionary.set('D', 1);
        dDictionary.set('SS', '');
        d.push(dDictionary);
        var tDictionary = new _PdfDictionary();
        tDictionary.set('U', '°');
        tDictionary.set('Type', 'NumberFormat');
        tDictionary.set('C', 1);
        tDictionary.set('D', 1);
        tDictionary.set('FD', true);
        tDictionary.set('SS', '');
        t.push(tDictionary);
        var aDictionary = new _PdfDictionary();
        aDictionary.set('U', 'sq in');
        aDictionary.set('Type', 'NumberFormat');
        aDictionary.set('C', 1);
        aDictionary.set('D', 1);
        aDictionary.set('FD', true);
        aDictionary.set('SS', '');
        a.push(aDictionary);
        var vDictionary = new _PdfDictionary();
        vDictionary.set('U', 'cu in');
        vDictionary.set('Type', 'NumberFormat');
        vDictionary.set('C', 1);
        vDictionary.set('D', 1);
        vDictionary.set('FD', true);
        vDictionary.set('SS', '');
        v.push(vDictionary);
        var xDictionary = new _PdfDictionary();
        xDictionary.set('U', 'in');
        xDictionary.set('Type', 'NumberFormat');
        xDictionary.set('C', 1);
        xDictionary.set('D', 1);
        xDictionary.set('SS', '');
        x.push(xDictionary);
        measureDictionary.set('D', d);
        measureDictionary.set('T', t);
        measureDictionary.set('A', a);
        measureDictionary.set('X', x);
        measureDictionary.set('V', v);
        if (this._dictionary.has('Measure')) {
            _removeDuplicateReference(this._dictionary, this._crossReference, 'Measure');
        }
        var reference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(reference, measureDictionary);
        measureDictionary._updated = true;
        this._dictionary.update('Measure', reference);
        var rectValue = [0, 0, 0, 0];
        var boundsValue = this._getAngleBoundsValue();
        var points = this._obtainLinePoints();
        var pathTypes = [];
        pathTypes.push(0);
        for (var i = 1; i < points.length; i++) {
            pathTypes.push(1);
        }
        var graphicspath = new PdfPath();
        graphicspath.addRectangle({ x: points[1][0] - this._radius,
            y: -(points[1][1] + this._radius),
            width: 2 * this._radius,
            height: 2 * this._radius });
        var size = font.measureString(angle.toString() + '°', { width: 0, height: 0 }, format, 0, 0);
        var midPoint = [(this._firstIntersectionPoint[0] + this._secondIntersectionPoint[0]) / 2,
            ((this._firstIntersectionPoint[1] + this._secondIntersectionPoint[1]) / 2)];
        var center = [points[1][0], -points[1][1]];
        var x1 = points[1][0] + this._radius * Math.cos((this._startAngle + (this._sweepAngle / 2)) * (Math.PI / 180.0));
        var y = points[1][1] + this._radius * Math.sin((this._startAngle + (this._sweepAngle / 2)) * (Math.PI / 180.0));
        var start = [midPoint[0], midPoint[1]];
        var xDiff = start[0] - center[0];
        var yDiff = start[1] - center[1];
        var midpointAngle = ((Math.atan2(yDiff, xDiff)) * (180.0 / Math.PI));
        var left = false;
        var right = false;
        var up = false;
        var down = false;
        if (midpointAngle > 0) {
            if (midpointAngle < 45) {
                right = true;
            }
            else if (midpointAngle >= 45 && midpointAngle < 135) {
                up = true;
            }
            else {
                left = true;
            }
        }
        else {
            midpointAngle = -midpointAngle;
            if (midpointAngle === 0) {
                (new PdfPath()).addRectangle({ x: boundsValue[0], y: boundsValue[1], width: boundsValue[2], height: boundsValue[3] });
            }
            else if (midpointAngle < 45) {
                right = true;
            }
            else if (midpointAngle >= 45 && midpointAngle < 135) {
                down = true;
            }
            else {
                left = true;
            }
        }
        if (rectValue[0] === 0 && rectValue[1] === 0 && rectValue[2] === 0 && rectValue[3] === 0) {
            rectValue = boundsValue;
            this.bounds = { x: boundsValue[0], y: boundsValue[1], width: boundsValue[2], height: boundsValue[3] };
        }
        var path = new PdfPath();
        path._pathTypes = pathTypes;
        path._points = points.map(function (p) { return ({ x: p[0], y: p[1] }); }); // eslint-disable-line
        this._dictionary.set('Rect', [rectValue[0], rectValue[1], rectValue[0] + rectValue[2], rectValue[1] + rectValue[3]]);
        var template;
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
        }
        else {
            var appearance = new PdfAppearance({ x: boundsValue[0], y: boundsValue[1], width: boundsValue[2],
                height: boundsValue[3] }, this);
            appearance.normal = new PdfTemplate(rectValue, this._crossReference);
            template = appearance.normal;
            template._writeTransformation = false;
            var graphics = appearance.normal.graphics;
            var width = borderWidth / 2;
            var pen = new PdfPen(this._color, width);
            if (this.border.style === PdfBorderStyle.dashed) {
                pen._dashStyle = PdfDashStyle.dash;
            }
            var brush = new PdfBrush(this._color);
            graphics.save();
            graphics.drawPath(path, pen);
            path.addArc({ x: points[1][0] - this._radius,
                y: points[1][1] - this._radius,
                width: 2 * this._radius,
                height: 2 * this._radius }, this._startAngle, this._sweepAngle);
            if (up) {
                graphics.drawString(angle.toString() + '°', font, { x: x1 - (size.width / 2), y: -(-y + font._getHeight() + 2), width: 0, height: 0 }, null, brush);
            }
            else if (right) {
                graphics.drawString(angle.toString() + '°', font, { x: x1 + 2, y: -(-y + font._getHeight() / 2), width: 0, height: 0 }, null, brush);
            }
            else if (left) {
                graphics.drawString(angle.toString() + '°', font, { x: x1 - size.width - 2, y: -(-y + font._getHeight() / 2), width: 0, height: 0 }, null, brush);
            }
            else if (down) {
                graphics.drawString(angle.toString() + '°', font, { x: x1 - (size.width / 2), y: (y + 2), width: 0, height: 0 }, null, brush);
            }
            graphics.restore();
            graphics._template._content.dictionary._updated = true;
            var reference1 = this._crossReference._getNextReference();
            this._crossReference._cacheMap.set(reference1, graphics._template._content);
            graphics._template._content.reference = reference1;
            if (this._dictionary.has('AP')) {
                _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
            }
            var appearanceDictionary = new _PdfDictionary();
            appearanceDictionary.set('N', reference1);
            appearanceDictionary._updated = true;
            this._dictionary.set('AP', appearanceDictionary);
        }
        return template;
    };
    /**
     * Calculates and returns the axis-aligned bounds of the angle polyline after Y-axis normalization.
     *
     * @private
     * @returns {number[]} bounds The [x, y, width, height] bounds array.
     */
    PdfAngleMeasurementAnnotation.prototype._getAngleBoundsValue = function () {
        var points = this._obtainLinePoints();
        for (var i = 0; i < points.length; i++) {
            points[i][1] = -points[i][1];
        }
        var path = new PdfPath();
        path._points = points.map(function (p) { return ({ x: p[0], y: p[1] }); }); // eslint-disable-line
        path._pathTypes = [0, 1, 1];
        return path._getBounds();
    };
    /**
     * Returns the three angle-defining points as [x, y] arrays with PDF coordinate Y inversion applied.
     *
     * @private
     * @returns {Array<number[]>} collection The three points as [x, y] arrays.
     */
    PdfAngleMeasurementAnnotation.prototype._obtainLinePoints = function () {
        var points;
        var collection;
        if (this._linePoints) {
            points = this._linePoints.slice();
            collection = new Array(points.length / 2);
            var count = 0;
            for (var j = 0; j < points.length; j = j + 2) {
                collection[count] = [points[j], -points[j + 1]];
                count++;
            }
        }
        return collection;
    };
    /**
     * Computes the interior angle at the vertex, determines arc start/sweep angles using line circle intersections, and returns the signed angle in radians.
     *
     * @private
     * @returns {number} angle The signed interior angle in radians.
     */
    PdfAngleMeasurementAnnotation.prototype._calculateAngle = function () {
        var points = [0, 0];
        if (typeof this._linePoints !== 'undefined' && this._linePoints.length === 0 && this._isLoaded) {
            if (this._dictionary.has('Vertices')) {
                this._linePoints = this._dictionary.get('Vertices');
            }
        }
        points = this._linePoints.slice();
        var collection = [];
        for (var j = 0; j < points.length; j = j + 2) {
            collection.push([points[j], points[j + 1]]);
        }
        var point1 = collection[0];
        var point2 = collection[1];
        var point3 = collection[2];
        var firstLineDistance = Math.sqrt(Math.pow((point2[0] - point1[0]), 2) + Math.pow((point2[1] - point1[1]), 2));
        var secondLineDistance = Math.sqrt(Math.pow((point2[0] - point3[0]), 2) + Math.pow((point2[1] - point3[1]), 2));
        this._radius = Math.min(firstLineDistance, secondLineDistance) / 4;
        var graphicsPath = new PdfPath();
        graphicsPath._points = collection.map(function (p) { return ({ x: p[0], y: p[1] }); }); // eslint-disable-line
        graphicsPath._pathTypes = [0, 1, 1];
        var intersectionPoint1;
        var intersectionPoint2;
        var value = this._findLineCircleIntersectionPoints(point2[0], point2[1], this._radius, point1, point2, intersectionPoint1, intersectionPoint2);
        intersectionPoint1 = value.first;
        intersectionPoint2 = value.second;
        if (this._firstIntersectionPoint[0] === 0 && this._firstIntersectionPoint[1] === 0) {
            this._firstIntersectionPoint = intersectionPoint2;
        }
        intersectionPoint1 = [0, 0];
        intersectionPoint2 = [0, 0];
        value = this._findLineCircleIntersectionPoints(point2[0], point2[1], this._radius, point3, point2, intersectionPoint1, intersectionPoint2);
        intersectionPoint1 = value.first;
        intersectionPoint2 = value.second;
        if (this._secondIntersectionPoint[0] === 0 && this._secondIntersectionPoint[1] === 0) {
            this._secondIntersectionPoint = intersectionPoint2;
        }
        var xDiff = this._firstIntersectionPoint[0] - point2[0];
        var yDiff = this._firstIntersectionPoint[1] - point2[1];
        var startAngle = (Math.atan2(yDiff, xDiff) * (180.0 / Math.PI));
        xDiff = this._secondIntersectionPoint[0] - point2[0];
        yDiff = this._secondIntersectionPoint[1] - point2[1];
        var sweepAngle = (Math.atan2(yDiff, xDiff) * (180.0 / Math.PI));
        startAngle = startAngle > 0 ? startAngle = 360 - startAngle : -startAngle;
        sweepAngle = sweepAngle > 0 ? sweepAngle = 360 - sweepAngle : -sweepAngle;
        if (startAngle === 180 && sweepAngle === 0) {
            this._startAngle = startAngle;
            this._sweepAngle = 180;
        }
        else if (startAngle === 0 && sweepAngle === 180) {
            this._startAngle = sweepAngle;
            this._sweepAngle = 180;
        }
        else if (startAngle < 180) {
            if (startAngle > sweepAngle) {
                this._startAngle = sweepAngle;
                this._sweepAngle = startAngle - sweepAngle;
            }
            else if (startAngle + 180 < sweepAngle) {
                this._startAngle = sweepAngle;
                this._sweepAngle = (360 - sweepAngle) + startAngle;
            }
            else {
                this._startAngle = startAngle;
                this._sweepAngle = sweepAngle - startAngle;
            }
        }
        else {
            if (startAngle < sweepAngle) {
                this._startAngle = startAngle;
                this._sweepAngle = sweepAngle - startAngle;
            }
            else if (startAngle - 180 > sweepAngle) {
                this._startAngle = startAngle;
                this._sweepAngle = (360 - startAngle) + sweepAngle;
            }
            else {
                this._startAngle = sweepAngle;
                this._sweepAngle = startAngle - sweepAngle;
            }
        }
        return (Math.atan2((point3[0] - point2[0]), (point3[1] - point2[1])) -
            Math.atan2((point1[0] - point2[0]), (point1[1] - point2[1])));
    };
    /**
     * Finds the intersection points between a line segment and a circle centered at centerX, centerY with the given radius and returns both intersections.
     *
     * @private
     * @param {number} centerX X-coordinate of the circle center.
     * @param {number} centerY Y-coordinate of the circle center.
     * @param {number} radius Circle radius.
     * @param {number[]} point1 First point of the segment [x, y].
     * @param {number[]} point2 Second point of the segment [x, y].
     * @param {number[]} intersection1 Output first intersection [x, y].
     * @param {number[]} intersection2 Output second intersection [x, y].
     * @returns {{first: number[], second: number[]}} result The pair of intersections {first, second}.
     */
    PdfAngleMeasurementAnnotation.prototype._findLineCircleIntersectionPoints = function (centerX, centerY, radius, point1, point2, intersection1, intersection2) {
        var dx = point2[0] - point1[0];
        var dy = point2[1] - point1[1];
        var a = dx * dx + dy * dy;
        var b = 2 * (dx * (point1[0] - centerX) + dy * (point1[1] - centerY));
        var c = (point1[0] - centerX) * (point1[0] - centerX) + (point1[1] - centerY) * (point1[1] - centerY) - radius * radius;
        var e = b * b - 4 * a * c;
        if ((a <= 0.0000001) || (e < 0)) {
            intersection1 = [Number.NaN, Number.NaN];
            intersection2 = [Number.NaN, Number.NaN];
        }
        else if (e === 0) {
            var t = -b / (2 * a);
            intersection1 = [point1[0] + t * dx, point1[1] + t * dy];
            intersection2 = [Number.NaN, Number.NaN];
        }
        else {
            var t = ((-b + Math.sqrt(e)) / (2 * a));
            intersection1 = [point1[0] + t * dx, point1[1] + t * dy];
            t = ((-b - Math.sqrt(e)) / (2 * a));
            intersection2 = [point1[0] + t * dx, point1[1] + t * dy];
        }
        return { first: intersection1, second: intersection2 };
    };
    return PdfAngleMeasurementAnnotation;
}(PdfComment));
export { PdfAngleMeasurementAnnotation };
/**
 * `PdfInkAnnotation` class represents the ink annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new ink annotation with the bounds and ink points
 * const annotation: PdfInkAnnotation = new PdfInkAnnotation({x: 0, y: 0, width: 300, height: 400}, [{x: 40, y: 300}, {x: 60, y: 100}, {x: 40, y: 50}, {x: 40, y: 300}]);
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfInkAnnotation = /** @class */ (function (_super) {
    __extends(PdfInkAnnotation, _super);
    function PdfInkAnnotation(bounds, points, properties) {
        var _this = _super.call(this) || this;
        _this._inkPointsCollection = [];
        _this._previousCollection = [];
        /**
         * Indicates whether the ink annotation has been modified.
         *
         * @private
         */
        _this._isModified = false;
        /**
         * Enables or disables interactive control points for editing.
         *
         * @private
         */
        _this._isEnableControlPoints = true;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Ink'));
        if (typeof points !== 'undefined') {
            _this._points = [{ x: bounds.x, y: bounds.y }, { x: bounds.width, y: bounds.height }];
            _this.bounds = bounds;
        }
        if (typeof points !== 'undefined') {
            _this._linePoints = points;
        }
        _this._type = _PdfAnnotationType.inkAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('thickness' in properties && _isNullOrUndefined(properties.thickness)) {
                _this.border.width = properties.thickness;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('pointsCollection' in properties && _isNullOrUndefined(properties.pointsCollection)) {
                _this.inkPointsCollection = properties.pointsCollection;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfInkAnnotation.prototype, "inkPointsCollection", {
        /**
         * Gets the ink points collection of the annotation.
         *
         * @returns {Array<Point[]>} Ink points collection.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfInkAnnotation = page.annotations.at(0) as PdfInkAnnotation;
         * // Get the ink points collection of the annotation
         * let inkPointsCollection: Array<Point[]> = annotation.inkPointsCollection;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._inkPointsCollection.length === 0 && this._dictionary.has('InkList')) {
                var inkList = this._dictionary.get('InkList');
                if (Array.isArray(inkList) && inkList.length > 0) {
                    var cropOrMediaBox = this._getMediaOrCropBox(this._page);
                    var cropX_1 = cropOrMediaBox && cropOrMediaBox.length > 0 ? cropOrMediaBox[0] : 0;
                    var cropY_1 = cropOrMediaBox && cropOrMediaBox.length > 1 ? cropOrMediaBox[1] : 0;
                    if (cropX_1 !== 0 || cropY_1 !== 0) {
                        var adjusted = inkList.map(function (stroke) {
                            var result = stroke.slice();
                            for (var k = 0; k < result.length; k += 2) {
                                result[k] = result[k] - cropX_1;
                                result[k + 1] = result[k + 1] - cropY_1;
                            }
                            return result;
                        });
                        this._inkPointsCollection = _convertNumberToPointArrays(adjusted);
                    }
                    else {
                        this._inkPointsCollection = _convertNumberToPointArrays(inkList);
                    }
                }
            }
            return this._inkPointsCollection;
        },
        /**
         * Sets the ink points collection of the annotation.
         *
         * @param {Array<Point[]>} value Ink points collection.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * // Create a new ink annotation
         * const annotation: PdfInkAnnotation = new PdfInkAnnotation([0, 0, 300, 400], [{x: 40, y: 300}, {x: 60, y: 100}, {x: 40, y: 50}, {x: 40, y: 300}]);
         * // Set the ink points collection of the annotation
         * annotation.inkPointsCollection = [[{x: 422, y: 690}, {x: 412, y: 708}, {x: 408, y: 715}, {x: 403, y: 720}, {x: 400, y: 725}], [{x: 420, y: 725}, {x: 420, y: 715}, {x: 415, y: 705}, {x: 400, y: 690}, {x: 405, y: 695}]];
         * // Add annotation to the page
         * page.annotations.add(annotation);
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (Array.isArray(value) && value.length > 0 && value !== this._inkPointsCollection) {
                this._inkPointsCollection = value;
                this._isModified = true;
                if (this._isLoaded) {
                    this._dictionary.update('InkList', _convertPointsToNumberArrays(value));
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads an ink annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfInkAnnotation} annot The loaded ink annotation instance.
     */
    PdfInkAnnotation._load = function (page, dictionary) {
        var annot = new PdfInkAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the ink annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfInkAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by validating points, ensuring BS/color defaults, computing bounds from ink data, updating Rect, and creating or attaching the appearance stream.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfInkAnnotation.prototype._postProcess = function () {
        if (typeof this._points === 'undefined' || this._points === null) {
            throw new Error('Points cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (!this._dictionary.has('C')) {
            this.color = { r: 0, g: 0, b: 0 };
            this._isTransparentColor = true;
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        var nativeRectangle = this._addInkPoints();
        var bounds = [nativeRectangle.x,
            nativeRectangle.y,
            nativeRectangle.x + nativeRectangle.width,
            nativeRectangle.y + nativeRectangle.height];
        this._dictionary.update('Rect', bounds);
        if (this._setAppearance || this._customTemplate.size > 0) {
            var appearanceDictionary = void 0;
            if (this._dictionary.has('AP')) {
                appearanceDictionary = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearanceDictionary = new _PdfDictionary(this._crossReference);
                this._crossReference._cacheMap.set(reference, appearanceDictionary);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._appearanceTemplate = this._customTemplate.get('N');
                this._drawCustomAppearance(appearanceDictionary);
            }
            else {
                _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
                var appearance = new PdfAppearance(nativeRectangle, this);
                appearance.normal = new PdfTemplate(nativeRectangle, this._crossReference);
                var template = appearance.normal;
                _setMatrix(template, 0, this);
                template._writeTransformation = false;
                this._appearanceTemplate = this._createInkAppearance(template);
                this._appearanceTemplate._content.dictionary._updated = true;
                var reference = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                this._appearanceTemplate._content.reference = reference;
                appearanceDictionary.set('N', reference);
                appearanceDictionary._updated = true;
            }
        }
    };
    /**
     * Builds or imports the ink appearance based on state and flattening, updates AP entries, adjusts Rect, and optionally flattens the annotation and its popup.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation into page content.
     * @returns {void} void No return value.
     */
    PdfInkAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        this._isFlatten = isFlatten;
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                if (this._inkPointsCollection.length === 0) {
                    this._inkPointsCollection = _convertNumberToPointArrays(this._obtainInkListCollection());
                }
                var rect = this._getInkBoundsValue();
                if (this._customTemplate.size > 0) {
                    this._appearanceTemplate = this._customTemplate.get('N');
                }
                else {
                    var template = new PdfTemplate(rect, this._crossReference);
                    var box = template._content.dictionary.getArray('BBox');
                    var angle = this._getRotationAngle();
                    if (box && angle !== null && typeof angle !== 'undefined') {
                        template._content.dictionary.set('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                    }
                    template._writeTransformation = false;
                    this._appearanceTemplate = this._createInkAppearance(template);
                }
                this._dictionary.update('Rect', [rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3]]);
                if (!isFlatten) {
                    var appearance = void 0;
                    if (this._dictionary.has('AP')) {
                        appearance = this._dictionary.get('AP');
                    }
                    else {
                        var reference = this._crossReference._getNextReference();
                        appearance = new _PdfDictionary(this._crossReference);
                        appearance._updated = true;
                        this._crossReference._cacheMap.set(reference, appearance);
                        this._dictionary.update('AP', reference);
                    }
                    if (this._customTemplate.size > 0) {
                        this._drawCustomAppearance(appearance);
                    }
                    else {
                        _removeDuplicateReference(appearance, this._crossReference, 'N');
                        this._appearanceTemplate._content.dictionary._updated = true;
                        var reference = this._crossReference._getNextReference();
                        this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                        this._appearanceTemplate._content.reference = reference;
                        appearance.set('N', reference);
                        appearance._updated = true;
                    }
                }
            }
            else if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess();
            if (!this._appearanceTemplate && isFlatten) {
                if (this._dictionary.has('AP')) {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        var reference = dictionary.getRaw('N');
                        if (appearanceStream) {
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
                else {
                    if (this._inkPointsCollection.length === 0) {
                        this._inkPointsCollection = _convertNumberToPointArrays(this._obtainInkListCollection());
                    }
                    var rect = this._getInkBoundsValue();
                    var template = new PdfTemplate(rect, this._crossReference);
                    _setMatrix(template, this._getRotationAngle(), this);
                    template._writeTransformation = false;
                    this._appearanceTemplate = this._createInkAppearance(template);
                    this._dictionary.update('Rect', [rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3]]);
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten) {
            if (this._appearanceTemplate &&
                this._appearanceTemplate._size !== null &&
                typeof this._appearanceTemplate._size !== 'undefined') {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                var box = void 0;
                var matrix = void 0;
                if (this._appearanceTemplate._content.dictionary.has('BBox')) {
                    box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                }
                if (this._appearanceTemplate._content.dictionary.has('Matrix')) {
                    matrix = this._appearanceTemplate._content.dictionary.getArray('Matrix');
                }
                if (box && matrix && (box[0] !== -matrix[4] || box[1] !== -matrix[5])) {
                    this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                }
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else {
                this._page.annotations.remove(this);
            }
            if (!this.flattenPopups && this._dictionary.has('Popup')) {
                var reference = this._dictionary.getRaw('Popup');
                if (this._page._pageDictionary.has('Annots')) {
                    var annots = this._page._pageDictionary.getRaw('Annots'); // eslint-disable-line
                    if (annots && Array.isArray(annots) && annots.length > 0) {
                        var index = annots.indexOf(reference);
                        if (index >= 0) {
                            this._page.annotations.removeAt(index);
                        }
                    }
                }
            }
        }
    };
    /**
     * Renders the ink strokes into the provided template, handling dots/lines/bezier paths, opacity, and pen settings (e.g., round caps when loaded).
     *
     * @private
     * @param {PdfTemplate} template The template into which the ink appearance is drawn.
     * @returns {PdfTemplate} template The same template after drawing content.
     */
    PdfInkAnnotation.prototype._createInkAppearance = function (template) {
        var graphics = template.graphics;
        if (this.inkPointsCollection !== null &&
            this.inkPointsCollection.length > 0 &&
            this.color !== null &&
            typeof this._color !== 'undefined') {
            for (var l = 0; l < this.inkPointsCollection.length; l++) {
                var isDot = false;
                var inkPointsCollection = _convertPointsToNumberArrays(this.inkPointsCollection);
                var inkPoints = inkPointsCollection[l];
                if (inkPoints.length === 2) {
                    var locx = inkPoints[0] - 0.5;
                    var locy = inkPoints[1] - 0.5;
                    var locw = inkPoints[0] + 0.5;
                    var loch = inkPoints[1] + 0.5;
                    inkPoints = [locx, locy, locw, loch];
                    isDot = true;
                }
                var point = new Array(inkPoints.length / 2);
                var count = 0;
                for (var j = 0; j < inkPoints.length; j = j + 2) {
                    point[count] = [inkPoints[j], inkPoints[j + 1]];
                    count++;
                }
                var pathPointCont = count + (count * 2) - 2;
                var pathPoints = new Array(pathPointCont);
                if (this._isEnableControlPoints) {
                    var p1 = [];
                    var p2 = [];
                    var value = this._getControlPoints(point, p1, p2);
                    p1 = value.controlP1;
                    p2 = value.controlP2;
                    var index = 0;
                    for (var i = 0; i < pathPointCont - 1; i = i + 3) {
                        pathPoints[i] = point[index];
                        pathPoints[i + 1] = p1[index];
                        pathPoints[i + 2] = p2[index];
                        index++;
                    }
                }
                else {
                    if (count % 3 === 1) {
                        pathPointCont = count;
                        pathPoints = new Array(pathPointCont);
                        pathPoints = point;
                    }
                    else if (count % 3 === 0) {
                        pathPointCont = count + 1;
                        pathPoints = new Array(pathPointCont);
                        for (var i = 0; i < point.length; i++) {
                            pathPoints[i] = point[i];
                        }
                    }
                    else {
                        pathPointCont = count + 2;
                        pathPoints = new Array(pathPointCont);
                        for (var i = 0; i < point.length; i++) {
                            pathPoints[i] = point[i];
                        }
                        pathPoints[pathPointCont - 2] = point[point.length - 2];
                    }
                }
                pathPoints[pathPointCont - 1] = point[point.length - 1];
                if (pathPoints !== null) {
                    var pointsCollection = pathPoints;
                    for (var k = 0; k < pointsCollection.length; k++) {
                        var point_1 = pointsCollection[k];
                        pointsCollection[k] = [point_1[0], (-point_1[1])];
                    }
                    var path1 = new PdfPath();
                    var path2 = null;
                    if (isDot) {
                        var width = point[1][0] - point[0][0];
                        var height = point[1][1] - point[0][1];
                        path1.addEllipse({ x: point[0][0] + (0.5), y: -(point[0][1] + height + (0.5)), width: width, height: height });
                        path2 = new PdfPath();
                        path2._pathTypes = path1._pathTypes;
                        path2._points = path1._points;
                    }
                    else if (point.length === 2) {
                        path1.addLine({ x: point[0][0], y: -point[0][1] }, { x: point[1][0], y: -point[1][1] });
                        path2 = new PdfPath();
                        path2._pathTypes = path1._pathTypes;
                        path2._points = path1._points;
                    }
                    else {
                        path1._addBezierPoints(pointsCollection);
                        path2 = new PdfPath();
                        path2._pathTypes = path1._pathTypes;
                        path2._points = _convertNumberArraysToPoints(pointsCollection);
                    }
                    var borderPen = new PdfPen(this.color, this.border.width);
                    if (this._isLoaded) {
                        borderPen._lineCap = PdfLineCap.round;
                    }
                    if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                        var state = graphics.save();
                        graphics.setTransparency(this._opacity);
                        graphics.drawPath(path2, borderPen);
                        graphics.restore(state);
                    }
                    else {
                        graphics.drawPath(path2, borderPen);
                    }
                }
            }
            if (this._isFlatten) {
                if (this._page && this._page._isNew && this._page._pageSettings && this._page._pageSettings.margins) {
                    var margins = this._page._pageSettings.margins;
                    this.bounds = {
                        x: this.bounds.x - margins.left,
                        y: this._page.size.height - (this.bounds.y + this.bounds.height) - margins.top,
                        width: this.bounds.width,
                        height: this.bounds.height
                    };
                }
                else {
                    this.bounds = { x: this.bounds.x,
                        y: (this._page.size.height - (this.bounds.y + this.bounds.height)), width: this.bounds.width,
                        height: this.bounds.height };
                }
            }
        }
        return template;
    };
    /* eslint-disable */
    /**
     * Computes cubic Bézier control points for a sequence of knots to produce a smooth ink spline, returning paired control point arrays.
     *
     * @private
     * @param {number[][]} point The knot points as [x,y] pairs.
     * @param {number[][]} p1 Output array for the first control points.
     * @param {number[][]} p2 Output array for the second control points.
     * @returns {{ controlP1: Array<number[]>, controlP2: Array<number[]> }} result The paired control points.
     */
    PdfInkAnnotation.prototype._getControlPoints = function (point, p1, p2) {
        if (point === null) {
            throw new Error('pointCollection');
        }
        var pointCount = point.length - 1;
        if (pointCount < 1) {
            throw new Error('At least two knot PointFs required pointCollection');
        }
        if (pointCount === 1) {
            p1 = [[((2 * point[0][0] + point[1][0]) / 3), ((2 * point[0][1] + point[1][1]) / 3)]];
            p2 = [[(2 * p1[0][0] - point[0][0]), (2 * p1[0][1] - point[0][1])]];
        }
        var rightVector = [];
        for (var i = 1; i < pointCount - 1; ++i) {
            rightVector[i] = 4 * point[i][0] + 2 * point[i + 1][0];
        }
        rightVector[0] = point[0][0] + 2 * point[1][0];
        rightVector[pointCount - 1] = (8 * point[pointCount - 1][0] + point[pointCount][0]) / 2.0;
        var xValue = this._getSingleControlPoint(rightVector);
        for (var i = 1; i < pointCount - 1; ++i) {
            rightVector[i] = 4 * point[i][1] + 2 * point[i + 1][1];
        }
        rightVector[0] = point[0][1] + 2 * point[1][1];
        rightVector[pointCount - 1] = (8 * point[pointCount - 1][1] + point[pointCount][1]) / 2.0;
        var yValue = this._getSingleControlPoint(rightVector);
        p1 = new Array(pointCount);
        p2 = new Array(pointCount);
        for (var i = 0; i < pointCount; ++i) {
            p1[i] = [xValue[i], yValue[i]];
            if (i < pointCount - 1) {
                p2[i] = [2 * point[i + 1][0] - xValue[i + 1], 2 * point[i + 1][1] - yValue[i + 1]];
            }
            else {
                var x = (point[pointCount][0] + xValue[pointCount - 1]) / 2;
                var y = (point[pointCount][1] + yValue[pointCount - 1]) / 2;
                p2[i] = [x, y];
            }
        }
        return { controlP1: p1, controlP2: p2 };
    };
    /* eslint-enable */
    /**
     * Solves a tridiagonal system to compute a single set of control point components from the right-hand side vector.
     *
     * @private
     * @param {number[]} rightVector The right-hand side vector.
     * @returns {number[]} vector The computed control point components.
     */
    PdfInkAnnotation.prototype._getSingleControlPoint = function (rightVector) {
        var count = rightVector.length;
        var vector = [];
        var tmpVector = [];
        var divisor = 2.0;
        vector[0] = rightVector[0] / divisor;
        for (var i = 1; i < count; i++) {
            tmpVector[i] = 1 / divisor;
            divisor = (i < count - 1 ? 4.0 : 3.5) - tmpVector[i];
            vector[i] = (rightVector[i] - vector[i - 1]) / divisor;
        }
        for (var i = 1; i < count; i++) {
            vector[count - i - 1] -= tmpVector[count - i] * vector[count - i];
        }
        return vector;
    };
    /**
     * Updates the InkList from current ink collections (respecting Crop/MediaBox offsets), synchronizes previous/modified state, and returns the resulting bounds.
     *
     * @private
     * @returns {Rectangle} bounds The resulting bounds after updating the InkList.
     */
    PdfInkAnnotation.prototype._addInkPoints = function () {
        var _this = this;
        var _a;
        var inkCollection = [];
        if (this._linePoints !== null && (this._previousCollection.length === 0 || this._isModified)) {
            this._inkPointsCollection.unshift(this._linePoints);
        }
        if (this.inkPointsCollection.length === 0 && this._previousCollection.length > 0) {
            this._inkPointsCollection = this._previousCollection;
        }
        var isEqual = _checkInkPoints(this._inkPointsCollection, this._previousCollection);
        var inkPointsData = _convertPointsToNumberArrays(this._inkPointsCollection);
        if (inkPointsData !== null && inkPointsData.length > 0 && !isEqual) {
            inkPointsData.forEach(function (inkPoint) {
                var inkList = inkPoint.slice();
                inkCollection.push(inkList);
            });
            this._dictionary.update('InkList', inkCollection);
        }
        if (this._inkPointsCollection.length > 0 && (!isEqual || this._isModified)) {
            (_a = this._previousCollection).push.apply(_a, this._inkPointsCollection);
            this._isModified = false;
        }
        var cropOrMediaBox = this._getCropOrMediaBox();
        var containsCropOrMediaBox = false;
        if (cropOrMediaBox && cropOrMediaBox.length > 3 && typeof cropOrMediaBox[0] === 'number' && typeof cropOrMediaBox[1] === 'number' && (cropOrMediaBox[0] !== 0 || cropOrMediaBox[1] !== 0)) {
            containsCropOrMediaBox = true;
            inkCollection.forEach(function (inkList, i) {
                var modifiedInkList = inkList;
                for (var j = 0; j < inkList.length; j += 2) {
                    var x = inkList[j];
                    var y = inkList[j + 1];
                    x = x + cropOrMediaBox[0];
                    if (_this._page._pageDictionary.has('MediaBox') && !_this._page._pageDictionary.has('CropBox') &&
                        cropOrMediaBox[3] === 0 && cropOrMediaBox[1] > 0) {
                        y = y + cropOrMediaBox[3];
                    }
                    else {
                        y = y + cropOrMediaBox[1];
                    }
                    modifiedInkList[j] = x;
                    modifiedInkList[j + 1] = y;
                    inkCollection[i] = modifiedInkList;
                }
            });
            this._dictionary.update('InkList', inkCollection);
        }
        if (this._isEnableControlPoints || containsCropOrMediaBox) {
            var result = this._getInkBoundsValue(inkCollection);
            return { x: result[0], y: result[1], width: result[2], height: result[3] };
        }
        else {
            if (!this._isFlatten) {
                this._updateInkListCollection(inkCollection);
            }
            return this.bounds;
        }
    };
    /**
     * Converts a flat numeric InkList into a collection of Point arrays and stores it in the ink points collection.
     *
     * @private
     * @param {Array<number[]>} inkCollection The InkList numeric collection per stroke.
     * @returns {void} void No return value.
     */
    PdfInkAnnotation.prototype._updateInkListCollection = function (inkCollection) {
        var pointCollection = inkCollection.map(function (innerArray) {
            var points = [];
            for (var i = 0; i < innerArray.length; i += 2) {
                points.push({ x: innerArray[i], y: innerArray[i + 1] });
            }
            return points;
        });
        this._inkPointsCollection = pointCollection;
    };
    /**
     * Calculates and returns the bounding rectangle for the current ink strokes, padding for border width when needed and updating the annotation bounds.
     *
     * @private
     * @param {Array<number[]>} [inkCollection] Optional numeric InkList to base bounds on.
     * @returns {number[]} bounds The [x, y, width, height] bounds of the ink.
     */
    PdfInkAnnotation.prototype._getInkBoundsValue = function (inkCollection) {
        var bounds = [0, 0, 0, 0];
        if (this._points && this._points.length > 0) {
            var firstPoint = this._points[0];
            if (typeof firstPoint.x === 'number' && typeof firstPoint.y === 'number') {
                if (this._points.length > 1) {
                    var secondPoint = this._points[1];
                    if (typeof secondPoint.x === 'number' && typeof secondPoint.y === 'number') {
                        this.bounds = {
                            x: firstPoint.x,
                            y: firstPoint.y,
                            width: secondPoint.x,
                            height: secondPoint.y
                        };
                    }
                    else {
                        this.bounds = { x: firstPoint.x, y: firstPoint.y, width: 0, height: 0 };
                    }
                }
                else {
                    this.bounds = { x: firstPoint.x, y: firstPoint.y, width: 0, height: 0 };
                }
            }
        }
        bounds = [this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height];
        var borderWidth = this.border.width;
        if (this._inkPointsCollection !== null) {
            if (this._inkPointsCollection.length > 0) {
                var termsList_1 = [];
                var inkPointsCollection = _convertPointsToNumberArrays(this._inkPointsCollection);
                inkPointsCollection.forEach(function (subList) {
                    if (subList !== null) {
                        if (subList.length % 2 === 0) {
                            termsList_1.push.apply(termsList_1, subList);
                        }
                    }
                });
                var isTwoPoints = false;
                if (!this._isLoaded && termsList_1.length === 2) {
                    isTwoPoints = true;
                    termsList_1.push((termsList_1[0] + 1));
                    termsList_1.push((termsList_1[1] + 1));
                }
                var pointCollection = new Array(termsList_1.length / 2);
                var count = 0;
                for (var j = 0; j < termsList_1.length; j = j + 2) {
                    pointCollection[count] = [termsList_1[j],
                        termsList_1[j + 1]];
                    count++;
                }
                if (this._isLoaded) {
                    if (pointCollection.length > 0) {
                        var xMin_1 = 0;
                        var yMin_1 = 0;
                        var xMax_1 = 0;
                        var yMax_1 = 0;
                        var first_1 = true;
                        pointCollection.forEach(function (point) {
                            if (first_1) {
                                xMin_1 = point[0];
                                yMin_1 = point[1];
                                first_1 = false;
                            }
                            else {
                                if (point[0] < xMin_1) {
                                    xMin_1 = point[0];
                                }
                                else if (point[0] > xMax_1) {
                                    xMax_1 = point[0];
                                }
                                if (point[1] < yMin_1) {
                                    yMin_1 = point[1];
                                }
                                else if (point[1] > yMax_1) {
                                    yMax_1 = point[1];
                                }
                            }
                        });
                        bounds = [xMin_1, yMin_1, xMax_1 - xMin_1, yMax_1 - yMin_1];
                        this.bounds = { x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] };
                        if (this._isFlatten || this._setAppearance) {
                            bounds[0] = this.bounds.x - borderWidth;
                            bounds[1] = this.bounds.y - borderWidth;
                            bounds[2] = this.bounds.width + (2 * borderWidth);
                            bounds[3] = this.bounds.height + (2 * borderWidth);
                        }
                    }
                    else {
                        if (this._points) {
                            bounds = _convertPointToNumberArray(this._points);
                        }
                        else if (pointCollection.length > 0) {
                            bounds = this._dictionary.get('Rect');
                        }
                        else {
                            bounds = [this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height];
                        }
                    }
                }
                else if (inkCollection) {
                    bounds = this._calculateInkBounds(pointCollection, bounds, borderWidth, isTwoPoints, inkCollection);
                }
                else {
                    bounds = this._calculateInkBounds(pointCollection, bounds, borderWidth, isTwoPoints);
                }
                if (Array.isArray(bounds) && bounds.length > 0) {
                    var x = typeof bounds[0] === 'number' ? bounds[0] : 0;
                    var y = typeof bounds[1] === 'number' ? bounds[1] : 0;
                    var width = typeof bounds[2] === 'number' ? bounds[2] : 0;
                    var height = typeof bounds[3] === 'number' ? bounds[3] : 0;
                    this.bounds = { x: x, y: y, width: width, height: height };
                }
            }
        }
        return bounds;
    };
    PdfInkAnnotation.prototype._calculateInkBounds = function (pointCollection, bounds, borderWidth, isTwoPoints, inkCollection) {
        if (pointCollection.length > 5) {
            var xMin_2 = 0;
            var yMin_2 = 0;
            var xMax_2 = 0;
            var yMax_2 = 0;
            var first_2 = true;
            pointCollection.forEach(function (point) {
                if (first_2) {
                    xMin_2 = point[0];
                    yMin_2 = point[1];
                    xMax_2 = point[0];
                    yMax_2 = point[1];
                    first_2 = false;
                }
                else {
                    if (point[0] < xMin_2) {
                        xMin_2 = point[0];
                    }
                    else if (point[0] > xMax_2) {
                        xMax_2 = point[0];
                    }
                    if (point[1] < yMin_2) {
                        yMin_2 = point[1];
                    }
                    else if (point[1] > yMax_2) {
                        yMax_2 = point[1];
                    }
                }
            });
            var cropOrMediaBox = this._getCropOrMediaBox();
            if (bounds[2] < xMax_2) {
                xMax_2 = bounds[2];
            }
            else if (cropOrMediaBox) {
                xMax_2 = xMax_2 - xMin_2;
            }
            if (bounds[3] < yMax_2) {
                yMax_2 = bounds[3];
            }
            else if (cropOrMediaBox) {
                yMax_2 = yMax_2 - yMin_2;
            }
            if (cropOrMediaBox) {
                xMin_2 = xMin_2 + cropOrMediaBox[0];
                yMin_2 = yMin_2 + cropOrMediaBox[1];
            }
            bounds = [xMin_2, yMin_2, xMax_2, yMax_2];
            if (this._isFlatten || this._setAppearance) {
                var factor = isTwoPoints ? 2 : 3;
                bounds[0] = bounds[0] - borderWidth;
                bounds[1] = bounds[1] - borderWidth;
                bounds[2] = bounds[2] + (factor * borderWidth);
                bounds[3] = bounds[3] + (factor * borderWidth);
            }
        }
        else {
            if (typeof this._points === 'undefined' && pointCollection.length > 0) {
                bounds = this._dictionary.get('Rect');
            }
            else {
                bounds = _convertPointToNumberArray(this._points);
            }
        }
        if (!this._isFlatten && inkCollection) {
            this._updateInkListCollection(inkCollection);
        }
        return bounds;
    };
    /**
     * Retrieves the InkList from the annotation dictionary and flattens each strokes coordinate pairs into number arrays, preserving perstroke grouping.
     *
     * @private
     * @returns {Array<number[]>} path The InkList as flat number arrays per stroke.
     */
    PdfInkAnnotation.prototype._obtainInkListCollection = function () {
        var path = [];
        if (this._dictionary.has('InkList')) {
            var inkList = this._dictionary.getArray('InkList');
            var list = [];
            for (var i = 0; i < inkList.length; i++) {
                var innerList = inkList[i];
                for (var j = 0; j < innerList.length; j++) {
                    list.push(innerList[j]);
                }
                path.push(list);
                if (list.length === innerList.length) {
                    list = [];
                }
            }
        }
        return path;
    };
    return PdfInkAnnotation;
}(PdfComment));
export { PdfInkAnnotation };
/**
 * `PdfPopupAnnotation` class represents the popup annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new popup annotation
 * const annotation: PdfPopupAnnotation = new PdfPopupAnnotation('Test popup annotation', {x: 10, y: 40, width: 30, height: 30});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfPopupAnnotation = /** @class */ (function (_super) {
    __extends(PdfPopupAnnotation, _super);
    function PdfPopupAnnotation(arg1, bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the icon used to represent the popup annotation.
         *
         * @private
         */
        _this._icon = PdfPopupIcon.note;
        _this._iconString = '';
        /**
         * Defines the state model (e.g., review status) of the annotation.
         *
         * @private
         */
        _this._stateModel = PdfAnnotationStateModel.none;
        /**
         * Indicates the current state within the state model.
         *
         * @private
         */
        _this._state = PdfAnnotationState.none;
        /**
         * Specifies whether the popup is initially open.
         *
         * @private
         */
        _this._open = false;
        /**
         * Indicates whether this popup participates in review workflows.
         *
         * @private
         */
        _this._isReview = false;
        /**
         * Flags whether this popup is a comment entry.
         *
         * @private
         */
        _this._isComment = false;
        /**
         * Stores the first half of the vector drawing commands for the comment icon.
         *
         * @private
         */
        _this._comment = 'q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J []0 d 1 0 0 1 9 5.0908 cm 7.74 12.616 m -7.74 12.616 l -8.274 12.616 -8.707 12.184 -8.707 11.649 c h f Q 0 G ';
        /**
         * Stores the second half of the vector drawing commands for the comment icon.
         *
         * @private
         */
        _this._commentSecondHalf = '0 i 0.60 w 4 M 1 j 0 J [0 100]1 d  1 0 0 1 9 5.0908 cm 4.1 1.71 m -0.54 -2.29 l  -0.54 1.71 l  -5.5 1.71 l  -5.5 14.42 l  10.5 14.42 l  10.5 1.71 l  4.1 1.71 l -2.33 9.66 m 7.34 9.66 l 7.34 8.83 l -2.33 8.83 l -2.33 9.66 l -2.33 7.28 m 5.88 7.28 l 5.88 6.46 l -2.33 6.46 l -2.33 7.28 l 14.9 23.1235 m -14.9 23.1235 l -14.9 -20.345 l 14.9 -20.345 l 14.9 23.1235 l b ';
        /**
         * Stores the vector drawing commands for the note icon.
         *
         * @private
         */
        _this._note = '0 G 0 i 0.61 w 4 M 0 j 0 J []0 d  q 1 0 0 1 16.959 1.3672 cm 0 0 m 0 -0.434 -0.352 -0.785 -0.784 -0.785 c -14.911 -0.785 l -15.345 -0.785 -15.696 -0.434 -15.696 0 c -15.696 17.266 l -15.696 17.699 -15.345 18.051 -14.911 18.051 c -0.784 18.051 l -0.352 18.051 0 17.699 0 17.266 c h b Q q 1 0 0 1 4.4023 13.9243 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4019 11.2207 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 8.5176 cm 0 0 m 9.418 0 l S Q q 1 0 0 1 4.4023 5.8135 cm 0 0 m 9.418 0 l S Q ';
        /**
         * Stores the first half of the vector path for the help icon.
         *
         * @private
         */
        _this._help = 'q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J []0 d 1 0 0 1 12.1465 10.5137 cm -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c h f Q ';
        /**
         * Stores the second half of the vector path for the help icon.
         *
         * @private
         */
        _this._helpSecondHalf = ' 0 G 0 i 0.59 w 4 M 1 j 0 J []0 d  1 0 0 1 12.1465 10.5137 cm 0 0 m -0.682 -0.756 -0.958 -1.472 -0.938 -2.302 c -0.938 -2.632 l -3.385 -2.632 l -3.403 -2.154 l -3.459 -1.216 -3.147 -0.259 -2.316 0.716 c -1.729 1.433 -1.251 2.022 -1.251 2.647 c -1.251 3.291 -1.674 3.715 -2.594 3.751 c -3.202 3.751 -3.937 3.531 -4.417 3.2 c -5.041 5.205 l -4.361 5.591 -3.274 5.959 -1.968 5.959 c 0.46 5.959 1.563 4.616 1.563 3.089 c 1.563 1.691 0.699 0.771 0 0 c -2.227 -6.863 m -2.245 -6.863 l -3.202 -6.863 -3.864 -6.146 -3.864 -5.189 c -3.864 -4.196 -3.182 -3.516 -2.227 -3.516 c -1.233 -3.516 -0.589 -4.196 -0.57 -5.189 c -0.57 -6.146 -1.233 -6.863 -2.227 -6.863 c -2.146 9.403 m -7.589 9.403 -12.001 4.99 -12.001 -0.453 c -12.001 -5.895 -7.589 -10.309 -2.146 -10.309 c 3.296 -10.309 7.709 -5.895 7.709 -0.453 c 7.709 4.99 3.296 9.403 -2.146 9.403 c b ';
        /**
         * Stores the vector path definition for the insert icon.
         *
         * @private
         */
        _this._insert = ' 0 i 0.59 w 4 M 0 j 0 J []0 d  1 0 0 1 8.5386 19.8545 cm 0 0 m -8.39 -19.719 l 8.388 -19.719 l h B ';
        /**
         * Stores the first half of the vector path for the key icon.
         *
         * @private
         */
        _this._key = 'q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J []0 d 1 0 0 1 6.5 12.6729 cm 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c -1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c f Q ';
        /**
         * Stores the second half of the vector path for the key icon.
         *
         * @private
         */
        _this._keySecondHalf = ' 0 G 0 i 0.59 w 4 M 1 j 0 J []0 d  1 0 0 1 6.5 12.6729 cm 0 0 m -1.076 0 -1.95 0.874 -1.95 1.95 c -1.95 3.028 -1.076 3.306 0 3.306 c 1.077 3.306 1.95 3.028 1.95 1.95 c 1.95 0.874 1.077 0 0 0 c 0.001 5.138 m -2.543 5.138 -4.604 3.077 -4.604 0.534 c -4.604 -1.368 -3.449 -3.001 -1.802 -3.702 c -1.802 -4.712 l -0.795 -5.719 l -1.896 -6.82 l -0.677 -8.039 l -1.595 -8.958 l -0.602 -9.949 l -1.479 -10.829 l -0.085 -12.483 l 1.728 -10.931 l 1.728 -3.732 l 1.737 -3.728 1.75 -3.724 1.76 -3.721 c 3.429 -3.03 4.604 -1.385 4.604 0.534 c 4.604 3.077 2.542 5.138 0.001 5.138 c b ';
        /**
         * Stores the first half of the vector path for the new paragraph icon.
         *
         * @private
         */
        _this._newParagraph = '1 0.819611 0 rg 0 G 0 i 0.58 w 4 M 0 j 0 J []0 d ';
        /**
         * Stores the second half of the vector path for the new paragraph icon.
         *
         * @private
         */
        _this._newParagraphSecondHalf = ' 0 G 0 i 0.59 w 4 M 1 j 0 J []0 d  q 1 0 0 1 6.4995 20 cm 0 0 m -6.205 -12.713 l 6.205 -12.713 l h b Q q 1 0 0 1 1.1909 6.2949 cm 0 0 m 1.278 0 l 1.353 0 1.362 -0.02 1.391 -0.066 c 2.128 -1.363 3.78 -4.275 3.966 -4.713 c 3.985 -4.713 l 3.976 -4.453 3.957 -3.91 3.957 -3.137 c 3.957 -0.076 l 3.957 -0.02 3.976 0 4.041 0 c 4.956 0 l 5.021 0 5.04 -0.029 5.04 -0.084 c 5.04 -6.049 l 5.04 -6.113 5.021 -6.133 4.947 -6.133 c 3.695 -6.133 l 3.621 -6.133 3.611 -6.113 3.574 -6.066 c 3.052 -4.955 1.353 -2.063 0.971 -1.186 c 0.961 -1.186 l 0.999 -1.68 0.999 -2.146 1.008 -3.025 c 1.008 -6.049 l 1.008 -6.104 0.989 -6.133 0.933 -6.133 c 0.009 -6.133 l -0.046 -6.133 -0.075 -6.123 -0.075 -6.049 c -0.075 -0.066 l -0.075 -0.02 -0.056 0 0 0 c f Q q 1 0 0 1 9.1367 3.0273 cm 0 0 m 0.075 0 0.215 -0.008 0.645 -0.008 c 1.4 -0.008 2.119 0.281 2.119 1.213 c 2.119 1.969 1.633 2.381 0.737 2.381 c 0.354 2.381 0.075 2.371 0 2.361 c h -1.146 3.201 m -1.146 3.238 -1.129 3.268 -1.082 3.268 c -0.709 3.275 0.02 3.285 0.729 3.285 c 2.613 3.285 3.248 2.314 3.258 1.232 c 3.258 -0.27 2.007 -0.914 0.607 -0.914 c 0.327 -0.914 0.057 -0.914 0 -0.904 c 0 -2.789 l 0 -2.836 -0.019 -2.865 -0.074 -2.865 c -1.082 -2.865 l -1.119 -2.865 -1.146 -2.846 -1.146 -2.799 c h f Q ';
        /**
         * Stores the first half of the vector path for the paragraph icon.
         *
         * @private
         */
        _this._paragraph = 'q 1 1 1 rg 0 i 1 w 4 M 1 j 0 J []0 d 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h f Q ';
        /**
         * Stores the second half of the vector path for the paragraph icon.
         *
         * @private
         */
        _this._paragraphSecondHalf = '0 G 0 i 0.59 w 4 M 1 j 0 J []0 d  q 1 0 0 1 19.6973 10.0005 cm 0 0 m 0 -5.336 -4.326 -9.662 -9.663 -9.662 c -14.998 -9.662 -19.324 -5.336 -19.324 0 c -19.324 5.335 -14.998 9.662 -9.663 9.662 c -4.326 9.662 0 5.335 0 0 c h S Q q 1 0 0 1 11.6787 2.6582 cm 0 0 m -1.141 0 l -1.227 0 -1.244 0.052 -1.227 0.139 c -0.656 1.157 -0.52 2.505 -0.52 3.317 c -0.52 3.594 l -2.833 3.783 -5.441 4.838 -5.441 8.309 c -5.441 10.778 -3.714 12.626 -0.57 13.024 c -0.535 13.508 -0.381 14.129 -0.242 14.389 c -0.207 14.44 -0.174 14.475 -0.104 14.475 c 1.088 14.475 l 1.156 14.475 1.191 14.458 1.175 14.372 c 1.105 14.095 0.881 13.127 0.881 12.402 c 0.881 9.431 0.932 7.324 0.95 4.06 c 0.95 2.298 0.708 0.813 0.189 0.07 c 0.155 0.034 0.103 0 0 0 c b Q ';
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Text'));
        if (arg1 !== null && typeof arg1 !== 'undefined' && typeof arg1 === 'string') {
            _this.text = arg1;
        }
        else if (arg1 && typeof arg1 === 'object') {
            properties = arg1;
        }
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.popupAnnotation;
        if (properties) {
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('icon' in properties && _isNullOrUndefined(properties.icon)) {
                _this.icon = properties.icon;
            }
            if ('open' in properties && _isNullOrUndefined(properties.open)) {
                _this.open = properties.open;
            }
            if ('state' in properties && _isNullOrUndefined(properties.state)) {
                _this.state = properties.state;
            }
            if ('stateModel' in properties && _isNullOrUndefined(properties.stateModel)) {
                _this.stateModel = properties.stateModel;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfPopupAnnotation.prototype, "open", {
        /**
         * Gets the boolean flag indicating whether annotation has open or not.
         *
         * @returns {boolean} Caption.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Gets the boolean flag indicating whether annotation has open or not.
         * let open: boolean =  annotation.open;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Open')) {
                this._open = this._dictionary.get('Open');
            }
            return this._open;
        },
        /**
         * Sets the boolean flag indicating whether annotation has open or not.
         *
         * @param {boolean} value Open.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Sets the boolean flag indicating whether annotation has open or not.
         * annotation.open = true;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._open = value;
                this._dictionary.update('Open', this._open);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPopupAnnotation.prototype, "icon", {
        /**
         * Gets the icon type of the popup annotation.
         *
         * @returns {PdfPopupIcon} Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Gets the icon type of the popup annotation.
         * let icon: PdfPopupIcon = annotation.icon;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Name')) {
                this._icon = _mapPopupIcon(this._dictionary.get('Name').name);
            }
            return this._icon;
        },
        /**
         * Sets the icon type of the popup annotation.
         *
         * @param {PdfPopupIcon} value Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Sets the icon type of the popup annotation.
         * annotation.icon = PdfPopupIcon.newParagraph;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._icon = value;
                this._dictionary.update('Name', _PdfName.get(this._obtainIconName(this._icon)));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPopupAnnotation.prototype, "stateModel", {
        /**
         * Gets the state model of the popup annotation.
         *
         * @returns {PdfAnnotationStateModel} Annotation State Model.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Gets the state model of the popup annotation.
         * let stateModel: PdfAnnotationStateModel = annotation.stateModel;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('StateModel')) {
                this._stateModel = _mapAnnotationStateModel(this._dictionary.get('StateModel'));
            }
            return this._stateModel;
        },
        /**
         * Sets the state model of the popup annotation.
         *
         * @param {PdfAnnotationStateModel} value Annotation State Model.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Sets the state model of the popup annotation.
         * annotation.stateModel = PdfAnnotationStateModel.marked;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._stateModel = value;
                this._dictionary.update('StateModel', _reverseMapAnnotationStateModel(this._stateModel));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfPopupAnnotation.prototype, "state", {
        /**
         * Gets the state of the popup annotation.
         *
         * @returns {PdfAnnotationState} Annotation State.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Gets the state of the popup annotation.
         * let state: PdfAnnotationState = annotation.state;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('State')) {
                this._state = _mapAnnotationState(this._dictionary.get('State'));
            }
            return this._state;
        },
        /**
         * Sets the state of the popup annotation.
         *
         * @param {PdfAnnotationState} value Annotation State.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfPopupAnnotation = page.annotations.at(0) as PdfPopupAnnotation;
         * // Sets the state of the popup annotation.
         * annotation.state = PdfAnnotationState.completed;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._state = value;
                this._dictionary.update('State', _reverseMapAnnotationState(this._state));
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a popup annotation from the given page and dictionary, marks it as loaded, initializes state, and sets review/comment flags from IRT.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfPopupAnnotation} annot The loaded popup annotation instance.
     */
    PdfPopupAnnotation._load = function (page, dictionary) {
        var annot = new PdfPopupAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        if (dictionary.has('IRT')) {
            annot._isReview = _checkReview(dictionary);
            if (!annot._isReview) {
                annot._isComment = _checkComment(dictionary);
            }
        }
        return annot;
    };
    /**
     * Initializes the popup annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfPopupAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Completes setup by validating bounds, ensuring BS default, updating Rect, and creating or attaching the appearance stream when required.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfPopupAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            this._bounds = { x: 0, y: 0, width: 0, height: 0 };
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        var rectangle = [this.bounds.x, this.bounds.y, (this.bounds.x + this.bounds.width),
            (this.bounds.y + this.bounds.height)];
        this._dictionary.update('Rect', rectangle);
        if (this._setAppearance || this._customTemplate.size > 0) {
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._appearanceTemplate = this._customTemplate.get('N');
                this._drawCustomAppearance(appearance);
            }
            else {
                this._appearanceTemplate = this._createPopupAppearance();
                if (this._appearanceTemplate) {
                    _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
                    this._appearanceTemplate._content.dictionary._updated = true;
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                    this._appearanceTemplate._content.reference = reference;
                    appearance.set('N', reference);
                    appearance._updated = true;
                }
            }
        }
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Builds or imports the popup appearance as needed, optionally draws it during flattening, flattens the template, and removes the annotation when done.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfPopupAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (!this._appearanceTemplate && this._isFlattenPopups && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (appearanceStream) {
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                    if (this._appearanceTemplate !== null) {
                        var state = this._page.graphics.save();
                        if (this.opacity < 1) {
                            this._page.graphics.setTransparency(this.opacity);
                        }
                        this._page.graphics.drawTemplate(this._appearanceTemplate, this.bounds);
                        this._page.graphics.restore(state);
                    }
                }
            }
        }
        else {
            this._postProcess();
            if (!this._appearanceTemplate) {
                if (isFlatten) {
                    if (!this._dictionary.has('AP')) {
                        this._appearanceTemplate = this._createPopupAppearance();
                    }
                    else {
                        var dictionary = this._dictionary.get('AP');
                        if (dictionary && dictionary.has('N')) {
                            var appearanceStream = dictionary.get('N');
                            var reference = dictionary.getRaw('N');
                            if (appearanceStream) {
                                if (reference) {
                                    appearanceStream.reference = reference;
                                }
                                this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                            }
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups && this.flatten) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten && this._appearanceTemplate) {
            var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
            this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
        }
        if (isFlatten) {
            this._removeAnnotation(this._page, this);
        }
    };
    /**
     * Creates the popup appearance template and writes the icon’s drawing commands (with optional color and opacity) based on the selected popup icon.
     *
     * @private
     * @returns {PdfTemplate} template The created appearance template.
     */
    PdfPopupAnnotation.prototype._createPopupAppearance = function () {
        var nativeRectangle = [0, 0, this.bounds.width, this.bounds.height];
        var template = new PdfTemplate(nativeRectangle, this._crossReference);
        var graphics = template.graphics;
        graphics._sw._clear();
        if (this.opacity < 1) {
            graphics.save();
            graphics.setTransparency(this.opacity);
        }
        switch (this.icon) {
            case PdfPopupIcon.comment:
                graphics._sw._write(this._comment);
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._commentSecondHalf);
                break;
            case PdfPopupIcon.paragraph:
                graphics._sw._write(this._paragraph);
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._paragraphSecondHalf);
                break;
            case PdfPopupIcon.help:
                graphics._sw._write(this._help);
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._helpSecondHalf);
                break;
            case PdfPopupIcon.note:
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._note);
                break;
            case PdfPopupIcon.insert:
                graphics._sw._write('0 G ');
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._insert);
                break;
            case PdfPopupIcon.key:
                graphics._sw._write(this._key);
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._keySecondHalf);
                break;
            case PdfPopupIcon.newParagraph:
                graphics._sw._write(this._newParagraph);
                if (this.color) {
                    graphics._sw._setColorSpace([this.color.r, this.color.g, this.color.b], _PdfColorSpace.rgb, false);
                }
                graphics._sw._write(this._newParagraphSecondHalf);
                break;
        }
        if (this.opacity < 1) {
            graphics.restore();
        }
        return template;
    };
    /**
     * Maps the popup icon enum to its canonical name string and returns it.
     *
     * @private
     * @param {PdfPopupIcon} icon The popup icon enum value.
     * @returns {string} iconName The canonical icon name.
     */
    PdfPopupAnnotation.prototype._obtainIconName = function (icon) {
        switch (icon) {
            case PdfPopupIcon.note:
                this._iconString = 'Note';
                break;
            case PdfPopupIcon.comment:
                this._iconString = 'Comment';
                break;
            case PdfPopupIcon.help:
                this._iconString = 'Help';
                break;
            case PdfPopupIcon.insert:
                this._iconString = 'Insert';
                break;
            case PdfPopupIcon.key:
                this._iconString = 'Key';
                break;
            case PdfPopupIcon.newParagraph:
                this._iconString = 'NewParagraph';
                break;
            case PdfPopupIcon.paragraph:
                this._iconString = 'Paragraph';
                break;
        }
        return this._iconString;
    };
    return PdfPopupAnnotation;
}(PdfComment));
export { PdfPopupAnnotation };
/**
 * `PdfFileLinkAnnotation` class represents the link annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new file link annotation
 * let annotation: PdfFileLinkAnnotation = new PdfFileLinkAnnotation({x: 10, y: 40, width: 30, height: 30}, "image.png");
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfFileLinkAnnotation = /** @class */ (function (_super) {
    __extends(PdfFileLinkAnnotation, _super);
    function PdfFileLinkAnnotation(bounds, fileName, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Link'));
        if (bounds) {
            _this.bounds = bounds;
        }
        if (typeof fileName !== 'undefined' && fileName !== null) {
            _this._fileName = fileName;
        }
        _this._type = _PdfAnnotationType.fileLinkAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('action' in properties && _isNullOrUndefined(properties.action)) {
                _this.action = properties.action;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfFileLinkAnnotation.prototype, "action", {
        /**
         * Gets the action of the annotation.
         *
         * @returns {string} Action.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFileLinkAnnotation = page.annotations.at(0) as PdfFileLinkAnnotation;
         * // Gets the action of the annotation.
         * let action: string = annotation.action;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            var _this = this;
            if (typeof this._action === 'undefined' && this._dictionary.has('A')) {
                var dictionary = this._dictionary.get('A');
                if (dictionary && dictionary.has('Next')) {
                    var action = dictionary.get('Next');
                    if (Array.isArray(action)) {
                        action.forEach(function (reference) {
                            if (reference && reference instanceof _PdfReference) {
                                var actionDictionary = _this._crossReference._fetch(reference);
                                if (actionDictionary.has('JS')) {
                                    _this._action = actionDictionary.get('JS');
                                }
                            }
                        });
                    }
                }
            }
            return this._action;
        },
        /**
         * Sets the action of the annotation.
         *
         * @param {string} value Action.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFileLinkAnnotation = page.annotations.at(0) as PdfFileLinkAnnotation;
         * // Sets the action of the annotation.
         * annotation.action = "app.alert('Launching file');";
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var _this = this;
            if (!this._isLoaded && typeof value === 'string') {
                this._action = value;
            }
            if (this._isLoaded && typeof value === 'string') {
                if (this.action !== value && this._dictionary.has('A')) {
                    var dictionary = this._dictionary.get('A');
                    if (dictionary && dictionary.has('Next')) {
                        var action = dictionary.get('Next');
                        if (Array.isArray(action)) {
                            action.forEach(function (reference) {
                                if (reference && reference instanceof _PdfReference) {
                                    var actionDictionary = _this._crossReference._fetch(reference);
                                    if (actionDictionary.has('JS')) {
                                        actionDictionary.update('JS', value);
                                        _this._action = value;
                                        _this._dictionary._updated = true;
                                    }
                                }
                            });
                        }
                    }
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a file link annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfFileLinkAnnotation} annot The loaded file link annotation instance.
     */
    PdfFileLinkAnnotation._load = function (page, dictionary) {
        var annot = new PdfFileLinkAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the file link annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfFileLinkAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation setup: validates bounds, ensures BS defaults, applies the launch action, and updates the Rect entry.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfFileLinkAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        this._addAction();
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Builds and assigns the annotations launch action dictionary, removes outdated references, and attaches optional JavaScript or nested actions.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfFileLinkAnnotation.prototype._addAction = function () {
        var _this = this;
        if (this._dictionary.has('A')) {
            var action = this._dictionary.get('A');
            if (action) {
                if (typeof this._action !== 'undefined' && this._action !== null && action.has('Next')) {
                    var nextAction = action.get('Next');
                    if (Array.isArray(nextAction) && nextAction.length > 0) {
                        nextAction.forEach(function (reference) {
                            if (reference && reference instanceof _PdfReference && reference._isNew) {
                                _this._crossReference._cacheMap.delete(reference);
                            }
                        });
                    }
                }
                if (action.has('F')) {
                    _removeDuplicateReference(action, this._crossReference, 'F');
                }
            }
            _removeDuplicateReference(this._dictionary, this._crossReference, 'A');
        }
        var dictionary = new _PdfDictionary();
        dictionary.set('Type', _PdfName.get('Action'));
        dictionary.set('S', _PdfName.get('Launch'));
        var fileDictionary = new _PdfDictionary();
        fileDictionary.set('Type', _PdfName.get('Filespec'));
        fileDictionary.set('UF', this._fileName);
        if (typeof this._action !== 'undefined' && this._action !== null) {
            var actionDictionary = new _PdfDictionary();
            actionDictionary.set('Type', _PdfName.get('Action'));
            actionDictionary.set('S', _PdfName.get('JavaScript'));
            actionDictionary.set('JS', this._action);
            var ref = this._crossReference._getNextReference();
            this._crossReference._cacheMap.set(ref, actionDictionary);
            actionDictionary._updated = true;
            dictionary.set('Next', [ref]);
        }
        var reference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(reference, fileDictionary);
        fileDictionary._updated = true;
        dictionary.set('F', reference);
        dictionary._updated = true;
        this._dictionary.set('A', dictionary);
    };
    /**
     * Performs post processing after load or flattening, importing or generating appearance streams and flattening or removing the annotation when required.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfFileLinkAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isLoaded) {
            this._postProcess();
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfFileLinkAnnotation;
}(PdfAnnotation));
export { PdfFileLinkAnnotation };
/**
 * `PdfUriAnnotation` class represents the URI annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new URI annotation
 * let annotation: PdfUriAnnotation = new PdfUriAnnotation({x: 100, y: 150, width: 200, height: 100}, 'http://www.google.com');
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfUriAnnotation = /** @class */ (function (_super) {
    __extends(PdfUriAnnotation, _super);
    function PdfUriAnnotation(bounds, uri, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Link'));
        if (bounds) {
            _this.bounds = bounds;
        }
        if (typeof uri !== 'undefined' && uri !== null) {
            _this._uri = uri;
        }
        _this._type = _PdfAnnotationType.uriAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfUriAnnotation.prototype, "uri", {
        /**
         * Gets the uri of the annotation.
         *
         * @returns {string} Uri.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfUriAnnotation = page.annotations.at(0) as PdfUriAnnotation;
         * // Gets the uri of the annotation.
         * let uri: string = annotation.uri;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._uri === 'undefined' && this._dictionary.has('A')) {
                var linkDict = this._dictionary.get('A');
                if (linkDict.has('URI')) {
                    this._uri = linkDict.get('URI');
                }
            }
            return this._uri;
        },
        /**
         * Sets the uri of the annotation.
         *
         * @param {string} value Uri.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Create a new URI annotation
         * let annotation: PdfUriAnnotation = new PdfUriAnnotation(100, 150, 200, 100);
         * // Sets the uri of the annotation
         * annotation.uri = 'http://www.google.com';
         * // Add annotation to the page
         * page.annotations.add(annotation);
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string') {
                if (this._isLoaded && this._dictionary.has('A') && value !== this.uri) {
                    var linkDict = this._dictionary.get('A');
                    if (linkDict.has('URI')) {
                        this._uri = value;
                        linkDict.update('URI', value);
                        this._dictionary._updated = true;
                    }
                }
                else {
                    this._uri = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a URI link annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfUriAnnotation} annot The loaded URI annotation instance.
     */
    PdfUriAnnotation._load = function (page, dictionary) {
        var annot = new PdfUriAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the URI link annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfUriAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes the annotation setup: validates bounds, ensures BS defaults, applies the URI action, and updates the Rect entry.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfUriAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        this._addAction();
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Creates and assigns the URI action dictionary (S=URI, URI value) and updates the Border array on the annotation.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfUriAnnotation.prototype._addAction = function () {
        var dictionary = new _PdfDictionary();
        dictionary.set('Type', _PdfName.get('Action'));
        dictionary.set('S', _PdfName.get('URI'));
        if (typeof this._uri !== 'undefined') {
            dictionary.set('URI', this._uri);
        }
        dictionary._updated = true;
        this._dictionary.set('A', dictionary);
        this._dictionary.update('Border', [this.border.hRadius, this.border.vRadius, this.border.width]);
    };
    /**
     * Performs post-processing after load or during flattening: imports or generates the appearance stream and flattens or removes the annotation as needed.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfUriAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isLoaded) {
            this._postProcess();
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfUriAnnotation;
}(PdfAnnotation));
export { PdfUriAnnotation };
/**
 * `PdfDocumentLinkAnnotation` class represents the document link annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new document link annotation
 * let annotation: PdfDocumentLinkAnnotation = new PdfDocumentLinkAnnotation({x: 100, y: 150, width: 40, height: 60});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfDocumentLinkAnnotation = /** @class */ (function (_super) {
    __extends(PdfDocumentLinkAnnotation, _super);
    function PdfDocumentLinkAnnotation(bounds, destination, properties) {
        var _this = _super.call(this) || this;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Link'));
        if (bounds !== null && typeof bounds !== 'undefined') {
            _this.bounds = bounds;
        }
        if (destination !== null && typeof destination !== 'undefined') {
            _this.destination = destination;
        }
        _this._type = _PdfAnnotationType.documentLinkAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfDocumentLinkAnnotation.prototype, "destination", {
        /**
         * Gets the destination of the annotation.
         *
         * @returns {PdfDestination} Destination.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfDocumentLinkAnnotation = page.annotations.at(0) as PdfDocumentLinkAnnotation;
         * // Gets the destination of the annotation.
         * let destination: PdfDestination =annotation.destination;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded && !this._destination) {
                var destinationHelper = void 0;
                if (this._dictionary.has('Dest')) {
                    destinationHelper = new _PdfDestinationHelper(this._dictionary, 'Dest');
                    this.destination = destinationHelper._obtainDestination();
                }
                else if (!this._destination && this._dictionary.has('A')) {
                    var action = this._dictionary.get('A');
                    if (action && action instanceof _PdfDictionary && action.has('D')) {
                        destinationHelper = new _PdfDestinationHelper(action, 'D');
                        this.destination = destinationHelper._obtainDestination();
                    }
                }
            }
            return this._destination;
        },
        /**
         * Sets the destination of the annotation.
         *
         * @param {PdfDestination} value Destination.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access first page
         * let page: PdfPage = document.getPage(0);
         * // Access the annotation at index 0
         * let annotation: PdfDocumentLinkAnnotation = page.annotations.at(0) as PdfDocumentLinkAnnotation;
         * // Initializes a new instance of the `PdfDestination` class.
         * let destination: PdfDestination = new PdfDestination();
         * // Sets the zoom factor.
         * destination.zoom = 20;
         * // Sets the page where the destination is situated.
         * destination.page = page;
         * // Sets the mode of the destination.
         * destination.mode = PdfDestinationMode.fitToPage;
         * // Sets the location of the destination.
         * destination.location = {x: 20, y: 20};
         * // Sets the bounds of the destination.
         * destination.destinationBounds = {x: 20, y: 20, width: 100, height: 50};
         * // Sets destination to document link annotation.
         * annotation.destination = destination;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                this._destination = value;
                if (this._isLoaded) {
                    this._destination._initializePrimitive();
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a document link annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfDocumentLinkAnnotation} annot The loaded document-link annotation instance.
     */
    PdfDocumentLinkAnnotation._load = function (page, dictionary) {
        var annot = new PdfDocumentLinkAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the document link annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfDocumentLinkAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by validating bounds, assigning the destination entry if present, and updating the Rect value.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfDocumentLinkAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        this._addDocument();
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Writes the annotations destination array into the dictionary when a destination is defined.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfDocumentLinkAnnotation.prototype._addDocument = function () {
        if (this.destination) {
            this._dictionary.set('Dest', this.destination._array);
        }
    };
    /**
     * Completes post processing after load or during flattening, updating Dest when needed and flattening or removing the annotation based on appearance availability.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfDocumentLinkAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isLoaded) {
            this._postProcess();
        }
        else if (this._destination) {
            this._dictionary.update('Dest', this._destination._array);
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfDocumentLinkAnnotation;
}(PdfAnnotation));
export { PdfDocumentLinkAnnotation };
/**
 * `PdfTextWebLinkAnnotation` class represents the link annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new PDF string format
 * const format: PdfStringFormat = new PdfStringFormat(PdfTextAlignment.left, PdfVerticalAlignment.top);
 * // Create a new standard font
 * const font: PdfStandardFont = new PdfStandardFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular);
 * // Get the text size
 * let size: number[] = font.measureString("Syncfusion Site", format, {width: 0, height: 0}, 0, 0);
 * // Create a new text web link annotation
 * let annot: PdfTextWebLinkAnnotation = new PdfTextWebLinkAnnotation({x: 50, y: 40, width: size.width, height: size.height}, {r: 0, g: 0, b: 0}, {r: 165, g: 42, b: 42}, 1);
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfTextWebLinkAnnotation = /** @class */ (function (_super) {
    __extends(PdfTextWebLinkAnnotation, _super);
    function PdfTextWebLinkAnnotation(bounds, brushColor, penColor, penWidth, properties) {
        var _this = _super.call(this) || this;
        _this._isActionAdded = false;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Link'));
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._textWebLink = (properties && typeof properties.text !== 'undefined' && properties.text !== null) ? properties.text : '';
        if (typeof brushColor !== 'undefined' && brushColor !== null) {
            _this._brush = new PdfBrush(brushColor);
        }
        if (typeof penColor !== 'undefined' && penColor !== null) {
            _this._pen = new PdfPen(penColor, penWidth ? penWidth : 1);
        }
        _this._type = _PdfAnnotationType.textWebLinkAnnotation;
        if (properties) {
            if ('url' in properties && _isNullOrUndefined(properties.url)) {
                _this.url = properties.url;
            }
            if ('font' in properties && _isNullOrUndefined(properties.font)) {
                _this.font = properties.font;
            }
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfTextWebLinkAnnotation.prototype, "font", {
        /**
         * Gets the font of the annotation.
         *
         * @returns {PdfFont} font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextWebLinkAnnotation = page.annotations.at(0) as PdfTextWebLinkAnnotation;
         * // Gets the font of the annotation.
         * let font: PdfFont = annotation.font;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._font;
        },
        /**
         * Sets the font of the annotation.
         *
         * @param {PdfFont} value font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextWebLinkAnnotation = page.annotations.at(0) as PdfTextWebLinkAnnotation;
         * // Sets the font of the annotation.
         * annotation.font = document.embedFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._font = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfTextWebLinkAnnotation.prototype, "url", {
        /**
         * Gets the url of the annotation.
         *
         * @returns {string} Url.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextWebLinkAnnotation = page.annotations.at(0) as PdfTextWebLinkAnnotation;
         * // Gets the URL of the annotation.
         * let url: string = annotation.url;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._url === 'undefined' && this._dictionary.has('A')) {
                var linkDict = this._dictionary.get('A');
                if (linkDict.has('URI')) {
                    this._url = linkDict.get('URI');
                }
            }
            return this._url;
        },
        /**
         * Sets the url of the annotation.
         *
         * @param {string} value Url.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextWebLinkAnnotation = page.annotations.at(0) as PdfTextWebLinkAnnotation;
         * // Sets the URL of the annotation.
         * annotation.url = 'http://www.syncfusion.com';
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string') {
                if (this._isLoaded && this._dictionary.has('A')) {
                    var linkSource = this._dictionary._get('A'); // eslint-disable-line
                    var linkDict = this._dictionary.get('A');
                    if (linkDict && linkDict.has('URI')) {
                        this._url = value;
                        linkDict.update('URI', value);
                        if (!(linkSource instanceof _PdfReference)) {
                            this._dictionary._updated = linkDict._updated;
                        }
                    }
                }
                else {
                    this._url = value;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a text weblink annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfTextWebLinkAnnotation} annot The loaded text web link annotation instance.
     */
    PdfTextWebLinkAnnotation._load = function (page, dictionary) {
        var annot = new PdfTextWebLinkAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the text weblink annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfTextWebLinkAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by validating bounds, adding the URI action once, and updating the annotation rectangle.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfTextWebLinkAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        if (!this._isActionAdded) {
            this._addAction();
            this._isActionAdded = true;
        }
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Draws the link text on the page using the configured font and colors, creates the URI action dictionary, and disables the visible border.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfTextWebLinkAnnotation.prototype._addAction = function () {
        var rect = [this.bounds.x, this.bounds.y, this.bounds.width, this.bounds.height];
        if (typeof this.font === 'undefined' || this.font === null) {
            this.font = this._lineCaptionFont;
        }
        var format = new PdfStringFormat(PdfTextAlignment.left, PdfVerticalAlignment.top);
        this._page.graphics.drawString(this._textWebLink, this.font, { x: rect[0], y: rect[1],
            width: rect[2], height: rect[3] }, this._pen, this._brush, format);
        var dictionary = new _PdfDictionary();
        dictionary.set('Type', _PdfName.get('Action'));
        dictionary.set('S', _PdfName.get('URI'));
        if (typeof this._url !== 'undefined') {
            dictionary.set('URI', this._url);
        }
        dictionary._updated = true;
        this._dictionary.set('A', dictionary);
        this._dictionary.update('Border', [0, 0, 0]);
    };
    /**
     * Performs final processing after load or during flattening, importing and flattening the appearance stream when available or removing the annotation if none exists.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfTextWebLinkAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isLoaded) {
            this._postProcess();
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfTextWebLinkAnnotation;
}(PdfAnnotation));
export { PdfTextWebLinkAnnotation };
/**
 * `PdfAttachmentAnnotation` class represents the attachment annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new attachment annotation
 * const annotation: PdfAttachmentAnnotation = new PdfAttachmentAnnotation({x: 300, y: 200, width: 30, height: 30}, 'Nature.jpg', imageData);
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAttachmentAnnotation = /** @class */ (function (_super) {
    __extends(PdfAttachmentAnnotation, _super);
    function PdfAttachmentAnnotation(bounds, fileName, data, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the icon used to display the file attachment.
         *
         * @private
         */
        _this._icon = PdfAttachmentIcon.pushPin;
        _this._iconString = '';
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('FileAttachment'));
        if (bounds) {
            _this.bounds = bounds;
        }
        if (typeof fileName !== 'undefined') {
            _this._fileName = fileName;
        }
        _this._stream = new _PdfStream(typeof data === 'string' ? _decode(data) : data);
        _this._type = _PdfAnnotationType.fileAttachmentAnnotation;
        if (properties) {
            if ('icon' in properties && _isNullOrUndefined(properties.icon)) {
                _this.icon = properties.icon;
            }
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfAttachmentAnnotation.prototype, "icon", {
        /**
         * Gets the icon type of the attachment annotation.
         *
         * @returns {PdfAttachmentIcon} Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfAttachmentAnnotation = page.annotations.at(0) as PdfAttachmentAnnotation;
         * // Gets the icon type of the attachment annotation.
         * let icon: PdfAttachmentIcon = annotation.icon;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Name')) {
                this._icon = _mapAttachmentIcon(this._dictionary.get('Name').name);
            }
            return this._icon;
        },
        /**
         * Sets the icon type of the attachment annotation.
         *
         * @param {PdfAttachmentIcon} value Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as  PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfAttachmentAnnotation = page.annotations.at(0) as PdfAttachmentAnnotation;
         * // Sets the icon type of the attachment annotation.
         * annotation.icon = PdfAttachmentIcon.pushPin;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._icon = value;
                this._dictionary.update('Name', _PdfName.get(this._obtainIconName(this._icon)));
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads an attachment annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {PdfAttachmentAnnotation} annot The loaded attachment annotation instance.
     */
    PdfAttachmentAnnotation._load = function (page, dictionary) {
        var annot = new PdfAttachmentAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the attachment annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    PdfAttachmentAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes annotation setup by validating bounds, updating the Rect entry, and creating or updating the embedded file attachment.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfAttachmentAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        this._dictionary.update('Rect', _updateBounds(this));
        this._addAttachment();
    };
    /**
     * Creates or updates the embedded file specification, writes the embedded file stream, assigns references, and updates the FS entry in the dictionary.
     *
     * @private
     * @returns {void} void No return value.
     */
    PdfAttachmentAnnotation.prototype._addAttachment = function () {
        if (this._dictionary.has('FS')) {
            var fileSpecification = this._dictionary.get('FS');
            if (fileSpecification && fileSpecification.has('EF')) {
                var embeddedFile = fileSpecification.get('EF');
                if (embeddedFile && embeddedFile.has('F')) {
                    _removeDuplicateReference(embeddedFile, this._crossReference, 'F');
                }
            }
            _removeDuplicateReference(this._dictionary, this._crossReference, 'FS');
        }
        var fileSpectDictionary = new _PdfDictionary();
        fileSpectDictionary.set('Type', _PdfName.get('Filespec'));
        fileSpectDictionary.set('Desc', this._fileName);
        fileSpectDictionary.set('F', this._fileName);
        fileSpectDictionary.set('UF', this._fileName);
        var fileDictionary = new _PdfDictionary();
        fileDictionary.set('Type', _PdfName.get('EmbeddedFile'));
        var paramsDictionary = new _PdfDictionary();
        var dateTime = new Date();
        paramsDictionary.set('CreationDate', dateTime.toTimeString());
        paramsDictionary.set('ModDate', new Date().toTimeString());
        paramsDictionary.set('Size', this._stream.length);
        fileDictionary.set('Params', paramsDictionary);
        this._stream.dictionary = new _PdfDictionary();
        this._stream.dictionary = fileDictionary;
        fileDictionary._crossReference = this._crossReference;
        var char1 = this._crossReference._newLine.charCodeAt(0);
        var char2 = this._crossReference._newLine.charCodeAt(1);
        var buffer = [char1, char2, 37, 80, 68, 70, 45];
        fileDictionary._crossReference._writeObject(this._stream, buffer);
        var reference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(reference, this._stream);
        fileDictionary._updated = true;
        var efileDictionary = new _PdfDictionary();
        efileDictionary.set('F', reference);
        fileSpectDictionary.set('EF', efileDictionary);
        var fsReference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(fsReference, fileSpectDictionary);
        fileSpectDictionary._updated = true;
        this._dictionary.update('FS', fsReference);
    };
    /**
     * Performs post processing after loading or during flattening by importing or generating the appearance stream and flattening or removing the annotation when needed.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    PdfAttachmentAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isLoaded) {
            this._postProcess();
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    /**
     * Maps the attachment icon enum value to its corresponding standard icon name string and returns it.
     *
     * @private
     * @param {PdfAttachmentIcon} icon The attachment icon value.
     * @returns {string} iconName The canonical icon name.
     */
    PdfAttachmentAnnotation.prototype._obtainIconName = function (icon) {
        switch (icon) {
            case PdfAttachmentIcon.pushPin:
                this._iconString = 'PushPin';
                break;
            case PdfAttachmentIcon.tag:
                this._iconString = 'Tag';
                break;
            case PdfAttachmentIcon.graph:
                this._iconString = 'Graph';
                break;
            case PdfAttachmentIcon.paperClip:
                this._iconString = 'Paperclip';
                break;
        }
        return this._iconString;
    };
    return PdfAttachmentAnnotation;
}(PdfComment));
export { PdfAttachmentAnnotation };
/**
 * `Pdf3DAnnotation` class represents the 3D annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: Pdf3DAnnotation = page.annotations.at(0) as Pdf3DAnnotation;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var Pdf3DAnnotation = /** @class */ (function (_super) {
    __extends(Pdf3DAnnotation, _super);
    /**
     * Initializes a new instance of the `Pdf3DAnnotation` class.
     *
     * @private
     */
    function Pdf3DAnnotation() {
        var _this = _super.call(this) || this;
        _this._type = _PdfAnnotationType.movieAnnotation;
        return _this;
    }
    /**
     * Loads a 3D annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary to load.
     * @returns {Pdf3DAnnotation} annot The loaded 3D annotation instance.
     */
    Pdf3DAnnotation._load = function (page, dictionary) {
        var annot = new Pdf3DAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the 3D annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with the annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary for loading.
     * @returns {void} void No return value.
     */
    Pdf3DAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Performs post processing during flattening by importing the appearance stream when available or removing the annotation when none exists.
     *
     * @private
     * @param {boolean} [isFlatten=false] Whether to flatten the annotation to page content.
     * @returns {void} void No return value.
     */
    Pdf3DAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return Pdf3DAnnotation;
}(PdfAnnotation));
export { Pdf3DAnnotation };
/**
 * `PdfTextMarkupAnnotation` class represents the text markup annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new text markup annotation
 * let annotation: PdfTextMarkupAnnotation = new PdfTextMarkupAnnotation('Text markup', {x: 50, y: 100, width: 100, height: 50});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfTextMarkupAnnotation = /** @class */ (function (_super) {
    __extends(PdfTextMarkupAnnotation, _super);
    function PdfTextMarkupAnnotation(text, bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Defines the text markup type (highlight, underline, etc.).
         *
         * @private
         */
        _this._textMarkupType = PdfTextMarkupAnnotationType.highlight;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        if (typeof text !== 'undefined') {
            _this._text = text;
        }
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.textMarkupAnnotation;
        if (properties) {
            if ('boundsCollection' in properties && _isNullOrUndefined(properties.boundsCollection)) {
                _this.boundsCollection = properties.boundsCollection;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('textMarkUpColor' in properties && _isNullOrUndefined(properties.textMarkUpColor)) {
                _this.textMarkUpColor = properties.textMarkUpColor;
            }
            if ('textMarkupType' in properties && _isNullOrUndefined(properties.textMarkupType)) {
                _this.textMarkupType = properties.textMarkupType;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfTextMarkupAnnotation.prototype, "bounds", {
        /**
         * Gets the bounds of the text markup annotation.
         *
         * @returns {Rectangle} Bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Gets the bounds of the annotation.
         * let bounds: Rectangle = annotation.bounds;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                this._bounds = _calculateBounds(this._dictionary, this._page);
            }
            return this._bounds;
        },
        /**
         * Sets the bounds of the text markup annotation.
         *
         * @param {Rectangle} value bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Sets the bounds of the annotation.
         * annotation.bounds = {x: 10, y: 10, width: 150, height: 5};
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                if (this._isLoaded) {
                    if ((value.x !== this.bounds.x) || (value.y !== this.bounds.y) ||
                        (value.width !== this.bounds.width) || (value.height !== this.bounds.height)) {
                        var size = this._page.size;
                        if (size) {
                            var y = size.height - (value.y + value.height);
                            var height = y + value.height;
                            this._dictionary.update('Rect', [value.x, y, value.x + value.width, height]);
                            this._bounds = value;
                            this._isChanged = true;
                        }
                    }
                }
                else {
                    this._bounds = value;
                    var nativeRectangle = this._obtainNativeRectangle();
                    this._dictionary.update('Rect', _fromRectangle({ x: nativeRectangle[0], y: nativeRectangle[1], width: nativeRectangle[2], height: nativeRectangle[3] }));
                    this._isChanged = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfTextMarkupAnnotation.prototype, "textMarkUpColor", {
        /**
         * Gets the text markup color of the annotation.
         *
         * @returns {PdfColor} Text markup color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Gets the textMarkUp Color type of the attachment annotation.
         * let textMarkUpColor: PdfColor = annotation.textMarkUpColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._textMarkUpColor === 'undefined' && this._dictionary.has('C')) {
                this._textMarkUpColor = _parseColor(this._dictionary.getArray('C'));
            }
            return this._textMarkUpColor;
        },
        /**
         * Sets the text markup color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Sets the textMarkUp Color type of the attachment annotation.
         * annotation.textMarkUpColor = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                var extColor = this.color;
                if (!this._isLoaded ||
                    typeof extColor === 'undefined' ||
                    (extColor.r !== value.r || extColor.g !== value.g || extColor.b !== value.b)) {
                    this._color = value;
                    this._textMarkUpColor = value;
                    this._dictionary.update('C', [Number.parseFloat((value.r / 255).toFixed(3)),
                        Number.parseFloat((value.g / 255).toFixed(3)),
                        Number.parseFloat((value.b / 255).toFixed(3))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfTextMarkupAnnotation.prototype, "textMarkupType", {
        /**
         * Gets the markup type of the annotation.
         *
         * @returns {PdfTextMarkupAnnotationType} Markup type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Gets the markup type of the annotation.
         * let textMarkupType: PdfTextMarkupAnnotationType = annotation.textMarkupType;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Subtype')) {
                var text = this._dictionary.get('Subtype');
                this._textMarkupType = _mapMarkupAnnotationType(text.name);
            }
            return this._textMarkupType;
        },
        /**
         * Sets the markup type of the annotation.
         *
         * @param {PdfTextMarkupAnnotationType} value Markup type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Sets the markup type of the annotation.
         * annotation.textMarkupType = PdfTextMarkupAnnotationType.squiggly;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._textMarkupType = value;
                this._dictionary.update('Subtype', _PdfName.get(_reverseMarkupAnnotationType(value)));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfTextMarkupAnnotation.prototype, "boundsCollection", {
        /**
         * Gets the markup bounds collection of the annotation.
         *
         * @returns {Array<Rectangle>} Markup bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as  PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation =  page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Gets the markup bounds collection of the annotation.
         * let boundsCollection : Array<Rectangle> = annotation.boundsCollection;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._isLoaded) {
                return this._boundsCollection;
            }
            var collection = [];
            if (!this._dictionary.has('QuadPoints')) {
                return collection;
            }
            var points = this._dictionary.getArray('QuadPoints');
            if (!points || points.length === 0) {
                return collection;
            }
            var cropOrMediaBox = this._getMediaOrCropBox(this._page);
            var cropX = cropOrMediaBox && cropOrMediaBox.length > 0 ? cropOrMediaBox[0] : 0;
            var cropY = cropOrMediaBox && cropOrMediaBox.length > 1 ? cropOrMediaBox[1] : 0;
            var pageHeight = this._page.size.height;
            var count = points.length / 8;
            for (var i = 0; i < count; i++) {
                var base = i * 8;
                var dx = points[base + 4] - points[base];
                var dy = points[base + 5] - points[base + 1];
                var height = Math.sqrt((dx * dx) + (dy * dy));
                dx = points[base + 6] - points[base + 4];
                dy = points[base + 7] - points[base + 5];
                var width = Math.sqrt((dx * dx) + (dy * dy));
                var x = points[base] - cropX;
                var y = pageHeight - points[base + 1] - cropY;
                collection.push({
                    x: x,
                    y: y,
                    width: width,
                    height: height
                });
            }
            return collection;
        },
        /**
         * Sets the markup bounds collection of the annotation.
         *
         * @param {Array<Rectangle>} value Markup bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfTextMarkupAnnotation = page.annotations.at(0) as PdfTextMarkupAnnotation;
         * // Sets the markup bounds collection of the  annotation.
         * annotation.boundsCollection = [{x: 50, y: 50, width: 100, height: 100}, {x: 201, y: 101, width: 61, height: 31}, {x: 101, y: 401, width: 61, height: 31}];
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var _a;
            if (!this._isLoaded && typeof value !== 'undefined') {
                if (value.length > 0) {
                    this._quadPoints = new Array((value.length * 8));
                    (_a = this._boundsCollection).push.apply(_a, value);
                }
                else {
                    this._quadPoints = new Array(8);
                    this._boundsCollection = value;
                }
                this._isChanged = true;
            }
            if (this._isLoaded && typeof value !== 'undefined') {
                var isChanged = false;
                if (this.boundsCollection.length === value.length) {
                    for (var i = 0; i < value.length; i++) {
                        var rectA = value[i];
                        var rectB = this.boundsCollection[i];
                        if (rectA.x !== rectB.x || rectA.y !== rectB.y || rectA.width !== rectB.width || rectA.height !== rectB.height) {
                            isChanged = true;
                            break;
                        }
                    }
                }
                else {
                    isChanged = true;
                }
                if (isChanged) {
                    this._quadPoints = new Array(value.length * 8);
                    var pageHeight = this._page.size.height;
                    for (var i = 0; i < value.length; i++) {
                        var rect = value[i];
                        this._quadPoints[0 + i * 8] = rect.x;
                        this._quadPoints[1 + i * 8] = pageHeight - rect.y;
                        this._quadPoints[2 + i * 8] = rect.x + rect.width;
                        this._quadPoints[3 + i * 8] = pageHeight - rect.y;
                        this._quadPoints[4 + i * 8] = rect.x;
                        this._quadPoints[5 + i * 8] = this._quadPoints[1 + i * 8] - rect.height;
                        this._quadPoints[6 + i * 8] = rect.x + rect.width;
                        this._quadPoints[7 + i * 8] = this._quadPoints[5 + i * 8];
                    }
                    this._dictionary.update('QuadPoints', this._quadPoints);
                    this._isChanged = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a textmarkup annotation from the given page and dictionary and initializes it as a loaded instance.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfTextMarkupAnnotation} The loaded text markup annotation instance.
     */
    PdfTextMarkupAnnotation._load = function (page, dictionary) {
        var annot = new PdfTextMarkupAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Computes the native rectangle adjusted for page size and Crop/MediaBox offsets, including newpage settings.
     *
     * @private
     * @returns {number[]} The native rectangle as [x, y, width, height].
     */
    PdfTextMarkupAnnotation.prototype._obtainNativeRectangle = function () {
        var nativeRectangle = [this._bounds.x, this._bounds.y + this._bounds.height, this._bounds.width, this._bounds.height];
        var cropOrMediaBox;
        if (this._page && !this._page._isNew) {
            var size = this._page.size;
            nativeRectangle[1] = size.height - nativeRectangle[1];
            cropOrMediaBox = this._getCropOrMediaBox();
        }
        else if (this._page && this._page._isNew) {
            var size = this._page._getActualBounds(this._page._pageSettings);
            nativeRectangle[0] += size[0];
            nativeRectangle[1] = this._page._pageSettings.size.height - (size[1] + nativeRectangle[1]);
            cropOrMediaBox = this._getCropOrMediaBox();
        }
        if (cropOrMediaBox) {
            if (cropOrMediaBox[3] < 0) {
                var yCrop = cropOrMediaBox[1];
                var heightCrop = cropOrMediaBox[3];
                cropOrMediaBox[1] = heightCrop;
                cropOrMediaBox[3] = yCrop;
            }
            if (cropOrMediaBox.length > 2 && (cropOrMediaBox[0] !== 0 || cropOrMediaBox[1] !== 0)) {
                nativeRectangle[0] += cropOrMediaBox[0];
                if (this._page && this._page._pageDictionary.has('MediaBox') && !this._page._pageDictionary.has('CropBox') && cropOrMediaBox[1] > 0 && cropOrMediaBox[3] === 0) {
                    nativeRectangle[1] += cropOrMediaBox[3];
                }
                else {
                    nativeRectangle[1] += cropOrMediaBox[1];
                }
            }
        }
        return nativeRectangle;
    };
    /**
     * Initializes the text markup annotation for the specified page and optional source dictionary.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfTextMarkupAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Validates bounds, ensures defaults (BS/color), sets subtype, updates QuadPoints/Rect, and creates/attaches the appearance.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfTextMarkupAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            dictionary.set('W', this.border.width);
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (!this._dictionary.has('C')) {
            this._isTransparentColor = true;
        }
        var size = this._page.size;
        this._dictionary.update('Subtype', _PdfName.get(_reverseMarkupAnnotationType(this._textMarkupType)));
        if (this._isChanged) {
            this._setQuadPoints(size);
            this._dictionary.update('Rect', _updateBounds(this));
        }
        if (this._setAppearance) {
            this._appearanceTemplate = this._createMarkupAppearance();
            if (!this._isLoaded && this._boundsCollection.length > 1 && this._isChanged) {
                var native = this._obtainNativeRectangle();
                this._dictionary.update('Rect', [native[0], native[1], native[0] + native[2], native[1] + native[3]]);
            }
            if (this._dictionary.has('AP')) {
                _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
            }
            var dictionary = new _PdfDictionary();
            this._appearanceTemplate._content.dictionary._updated = true;
            var reference = this._crossReference._getNextReference();
            this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
            this._appearanceTemplate._content.reference = reference;
            dictionary.set('N', reference);
            dictionary._updated = true;
            this._dictionary.set('AP', dictionary);
        }
        if (typeof this._text !== 'undefined' && this._text !== null) {
            this._dictionary.set('Contents', this._text);
        }
        this._isChanged = false;
    };
    /**
     * Completes post processing by creating/importing the appearance stream as needed and flattening or removing the annotation when requested.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation into page content and removes it.
     * @returns {void} No return value.
     */
    PdfTextMarkupAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createMarkupAppearance();
                if (!isFlatten) {
                    if (this._dictionary.has('AP')) {
                        _removeDuplicateReference(this._dictionary.get('AP'), this._crossReference, 'N');
                    }
                    var dictionary = new _PdfDictionary();
                    this._appearanceTemplate._content.dictionary._updated = true;
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                    this._appearanceTemplate._content.reference = reference;
                    dictionary.set('N', reference);
                    dictionary._updated = true;
                    this._dictionary.set('AP', dictionary);
                }
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    if (appearanceStream) {
                        var reference = dictionary.getRaw('N');
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess();
            if (!this._appearanceTemplate) {
                if (isFlatten) {
                    if (!this._dictionary.has('AP')) {
                        this._appearanceTemplate = this._createMarkupAppearance();
                    }
                    else {
                        var dictionary = this._dictionary.get('AP');
                        if (dictionary && dictionary.has('N')) {
                            var appearanceStream = dictionary.get('N');
                            if (appearanceStream) {
                                var reference = dictionary.getRaw('N');
                                if (reference) {
                                    appearanceStream.reference = reference;
                                }
                                this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                            }
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten && this._appearanceTemplate) {
            var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
            if (!this._appearanceTemplate._content.dictionary.has('Matrix') && !this._isLoaded) {
                var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                if (box) {
                    this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                }
            }
            if (isNormalMatrix && typeof this._page.rotation !== 'undefined' && this._page.rotation !== PdfRotationAngle.angle0) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else if (isNormalMatrix && this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary, this._appearanceTemplate)) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else if (!this._dictionary.has('AP') && this._appearanceTemplate) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
        }
        if (isFlatten) {
            this._page.annotations.remove(this);
        }
    };
    /**
     * Creates the markup appearance template using current QuadPoints/bounds and draws highlight/underline/strikeout/squiggly visuals.
     *
     * @private
     * @returns {PdfTemplate} The generated appearance template.
     */
    PdfTextMarkupAnnotation.prototype._createMarkupAppearance = function () {
        var width = 0;
        var height = 0;
        var rectangle;
        if (this.boundsCollection.length > 1) {
            var pdfPath = new PdfPath();
            for (var i = 0; i < this.boundsCollection.length; i++) {
                var bounds = [];
                bounds[0] = this.boundsCollection[i].x;
                bounds[1] = this.boundsCollection[i].y;
                bounds[2] = this.boundsCollection[i].width;
                bounds[3] = this.boundsCollection[i].height;
                pdfPath.addRectangle({ x: bounds[0], y: bounds[1], width: bounds[2], height: bounds[3] });
            }
            var rect = pdfPath._getBounds();
            rectangle = { x: rect[0], y: rect[1], width: rect[2], height: rect[3] };
            this.bounds = rectangle;
            width = rectangle.width;
            height = rectangle.height;
        }
        else {
            if (this._dictionary.has('QuadPoints')) {
                var quadPoints = this._dictionary.get('QuadPoints');
                if (this._quadPoints !== null) {
                    for (var i = 0; i < (quadPoints.length / 8); i++) {
                        if (this._isLoaded) {
                            var point = [];
                            for (var k = 0; k < quadPoints.length;) {
                                var x1 = quadPoints[k];
                                var y1 = quadPoints[k + 1];
                                point.push({ x: x1, y: y1 });
                                k += 2;
                            }
                            var path = new PdfPath();
                            path._addLines(point);
                            var rect = path._getBounds();
                            rectangle = { x: rect[0], y: rect[1], width: rect[2], height: rect[3] };
                            width = rectangle.width;
                            height = rectangle.height;
                        }
                        else {
                            var x = Math.floor(quadPoints[4 + (i * 8)]) - Math.floor(quadPoints[0 + (i * 8)]);
                            var y = Math.floor(quadPoints[5 + (i * 8)]) - Math.floor(quadPoints[1 + (i * 8)]);
                            height = Math.sqrt((x * x) + (y * y));
                            x = Math.floor(quadPoints[6 + (i * 8)]) - Math.floor(quadPoints[4 + (i * 8)]);
                            y = Math.floor(quadPoints[7 + (i * 8)]) - Math.floor(quadPoints[5 + (i * 8)]);
                            width = Math.sqrt((x * x) + (y * y));
                            this.bounds = { x: this.bounds.x, y: this.bounds.y, width: width, height: height };
                        }
                    }
                }
            }
        }
        var nativeRectangle = [0, 0, width, height];
        var template = new PdfTemplate(nativeRectangle, this._crossReference);
        _setMatrix(template, this._getRotationAngle());
        var graphics = template.graphics;
        if (typeof this.opacity !== 'undefined') {
            graphics.setTransparency(this.opacity, this.opacity, PdfBlendMode.multiply);
        }
        if (this.textMarkUpColor) {
            var pdfPen = new PdfPen(this.textMarkUpColor, this.border.width);
            var brush = new PdfBrush(this.textMarkUpColor);
            var x1 = 0;
            var y1 = 0;
            var w1 = 0;
            var h1 = 0;
            if (this.boundsCollection.length > 1) {
                for (var i = 0; i < this.boundsCollection.length; i++) {
                    var bounds = [];
                    bounds[0] = this.boundsCollection[i].x;
                    bounds[1] = this.boundsCollection[i].y;
                    bounds[2] = this.boundsCollection[i].width;
                    bounds[3] = this.boundsCollection[i].height;
                    if (this.textMarkupType === PdfTextMarkupAnnotationType.highlight) {
                        graphics.drawRectangle({ x: bounds[0] - rectangle.x, y: bounds[1] - rectangle.y,
                            width: bounds[2], height: bounds[3] }, brush);
                    }
                    else if (this.textMarkupType === PdfTextMarkupAnnotationType.underline) {
                        x1 = bounds[0] - rectangle.x;
                        y1 = (bounds[1] - rectangle.y) + (bounds[3] - ((bounds[3] / 2) / 3));
                        w1 = bounds[2] + (bounds[0] - rectangle.x);
                        h1 = (bounds[1] - rectangle.y) + (bounds[3] - ((bounds[3] / 2) / 3));
                        graphics.drawLine(pdfPen, { x: x1, y: y1 }, { x: w1, y: h1 });
                    }
                    else if (this.textMarkupType === PdfTextMarkupAnnotationType.strikeOut) {
                        x1 = bounds[0] - rectangle.x;
                        y1 = (bounds[1] - rectangle.y) + (bounds[3] - (bounds[3] / 2));
                        w1 = bounds[2] + (bounds[0] - rectangle.x);
                        h1 = (bounds[1] - rectangle.y) + (bounds[3] - (bounds[3] / 2));
                        graphics.drawLine(pdfPen, { x: x1, y: y1 }, { x: w1, y: h1 });
                    }
                    else if (this.textMarkupType === PdfTextMarkupAnnotationType.squiggly) {
                        pdfPen._width = bounds[3] * 0.02;
                        graphics.save();
                        graphics.translateTransform({ x: bounds[0] - rectangle.x, y: (bounds[1] - rectangle.y) });
                        graphics.setClip({ x: 0, y: 0, width: bounds[2], height: bounds[3] });
                        graphics.drawPath(this._drawSquiggly(bounds[2], bounds[3]), pdfPen);
                        graphics.restore();
                    }
                }
            }
            else {
                if (this.textMarkupType === PdfTextMarkupAnnotationType.highlight) {
                    graphics.drawRectangle({ x: 0, y: 0, width: width, height: height }, brush);
                }
                else if (this.textMarkupType === PdfTextMarkupAnnotationType.underline) {
                    graphics.drawLine(pdfPen, { x: 0, y: height - ((height / 2) / 3) }, { x: width, y: height - ((height / 2) / 3) });
                }
                else if (this.textMarkupType === PdfTextMarkupAnnotationType.strikeOut) {
                    graphics.drawLine(pdfPen, { x: 0, y: height / 2 }, { x: width, y: height / 2 });
                }
                else if (this.textMarkupType === PdfTextMarkupAnnotationType.squiggly) {
                    pdfPen._width = height * 0.02;
                    graphics.drawPath(this._drawSquiggly(Math.round(width), Math.round(height)), pdfPen);
                }
                if (this._isLoaded) {
                    var defaultRect = [rectangle.x, rectangle.y, rectangle.x + rectangle.width, rectangle.y + rectangle.height];
                    var rect = this._setAppearance ? _updateBounds(this) : defaultRect;
                    this._dictionary.update('Rect', rect);
                }
            }
        }
        return template;
    };
    /**
     * Generates a squiggly underline path sized to the given width and height using alternating zigzag points.
     *
     * @private
     * @param {number} width The total width available for the squiggly stroke.
     * @param {number} height The height of the squiggly area (influences amplitude/pen width).
     * @returns {PdfPath} The constructed squiggly path.
     */
    PdfTextMarkupAnnotation.prototype._drawSquiggly = function (width, height) {
        if (Math.floor(width) % 2 !== 0 || Math.round(width) > width) {
            width = Math.floor(width) + 1;
        }
        var path = new PdfPath();
        var pathPoints = [];
        var pathPointsCount = Math.ceil((width / height) * 16);
        var length = width / (pathPointsCount / 2);
        var location = parseFloat(((length + length) * 0.6).toFixed(2));
        var zigZag = location;
        var x = 0;
        for (var i = 0; i < pathPointsCount; i++) {
            var y = ((height - location) + zigZag) - (height * 0.02);
            var temp = { x: x, y: parseFloat(y.toFixed(2)) };
            pathPoints.push(temp);
            zigZag = zigZag === 0 ? location : 0;
            x += length;
        }
        path._addLines(pathPoints);
        return path;
    };
    return PdfTextMarkupAnnotation;
}(PdfComment));
export { PdfTextMarkupAnnotation };
/**
 * `PdfWatermarkAnnotation` class represents the watermark annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new water mark annotation
 * const annotation: PdfWatermarkAnnotation = new PdfWatermarkAnnotation('Water Mark', {x: 50, y: 100, width: 100, height: 50});
 * // Set the color of the annotation
 * annotation.color = {r: 0, g: 0, b: 0};
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfWatermarkAnnotation = /** @class */ (function (_super) {
    __extends(PdfWatermarkAnnotation, _super);
    function PdfWatermarkAnnotation(text, bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Holds the watermark display text.
         *
         * @private
         */
        _this._watermarkText = '';
        if (text !== null && typeof text !== 'undefined' && bounds) {
            initializeTelemetryFeature('Watermark', 'PDFLibrary');
        }
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Watermark'));
        if (typeof text !== 'undefined') {
            _this._watermarkText = text;
            _this.text = text;
        }
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.watermarkAnnotation;
        if (properties) {
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    /**
     * Loads a watermark annotation from the given page and dictionary and initializes it as a loaded instance.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfWatermarkAnnotation} The loaded watermark annotation instance.
     */
    PdfWatermarkAnnotation._load = function (page, dictionary) {
        var annot = new PdfWatermarkAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the watermark annotation for the specified page and optional source dictionary.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfWatermarkAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup: validates bounds, ensures BS/color defaults, creates the watermark appearance, updates Rect, and sets CA opacity if provided.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfWatermarkAnnotation.prototype._postProcess = function () {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (typeof this.color === 'undefined') {
            this.color = { r: 0, g: 0, b: 0 };
        }
        this._appearanceTemplate = this._createWatermarkAppearance();
        this._dictionary.update('Rect', _updateBounds(this));
        if (typeof this.opacity !== 'undefined' && this._opacity !== 1.0) {
            this._dictionary.set('CA', this._opacity);
        }
    };
    PdfWatermarkAnnotation.prototype._createWatermarkAppearance = function () {
        var font = this._obtainFont();
        if ((typeof font === 'undefined' || font === null) || ((!this._isLoaded || (this._page && this._page._isDuplicate)) && font.size === 1)) {
            font = this._lineCaptionFont;
            this._pdfFont = font;
        }
        this._rotateAngle = this._getRotationAngle();
        if (typeof this.rotationAngle !== 'undefined' && this._rotate !== PdfRotationAngle.angle0 || this._rotateAngle !== PdfRotationAngle.angle0) {
            if (this._rotateAngle === 0) {
                this._rotateAngle = this.rotationAngle * 90;
            }
            this.bounds = this._getRotatedBounds(this.bounds, this._rotateAngle);
        }
        var nativeRectangle = [0, 0, this.bounds.width, this.bounds.height];
        var appearance = new PdfAppearance({ x: 0, y: 0, width: this.bounds.width, height: this.bounds.height }, this);
        appearance.normal = new PdfTemplate(nativeRectangle, this._crossReference);
        var template = appearance.normal;
        _setMatrix(template, this._rotateAngle);
        var graphics = appearance.normal.graphics;
        var width = this.border.width / 2;
        var format = new PdfStringFormat(PdfTextAlignment.left, PdfVerticalAlignment.top);
        var borderPen = new PdfPen(this.color, width);
        var backBrush;
        if (this.innerColor) {
            backBrush = new PdfBrush(this._innerColor);
        }
        if (this._isLoaded) {
            if (this._dictionary.has('Contents')) {
                this._watermarkText = this._dictionary.get('Contents');
            }
            this._dictionary.update('Contents', this._watermarkText);
        }
        else {
            this._dictionary.update('Contents', this._watermarkText);
        }
        if (typeof this._watermarkText !== 'undefined') {
            graphics.drawString(this._watermarkText, font, { x: 0, y: 0, width: 0, height: 0 }, borderPen, backBrush, format);
        }
        if (this._dictionary.has('AP')) {
            var dictionary_1 = this._dictionary.get('AP'); // eslint-disable-line
            if (dictionary_1 && dictionary_1 instanceof _PdfDictionary) {
                _removeDuplicateReference(dictionary_1, this._crossReference, 'N');
            }
        }
        var dictionary = new _PdfDictionary();
        graphics._template._content.dictionary._updated = true;
        var reference = this._crossReference._getNextReference();
        this._crossReference._cacheMap.set(reference, graphics._template._content);
        graphics._template._content.reference = reference;
        dictionary.set('N', reference);
        dictionary._updated = true;
        this._dictionary.set('AP', dictionary);
        return template;
    };
    /**
     * Completes watermark post processing by creating/importing the appearance stream and flattening or removing the annotation as requested.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation into page content, otherwise updates AP entries.
     * @returns {void} No return value.
     */
    PdfWatermarkAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (!isFlatten) {
                this._appearanceTemplate = this._createWatermarkAppearance();
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    if (appearanceStream) {
                        var reference = dictionary.getRaw('N');
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess();
            if (!this._appearanceTemplate) {
                if (isFlatten) {
                    if (!this._dictionary.has('AP')) {
                        this._appearanceTemplate = this._createWatermarkAppearance();
                    }
                    else {
                        var dictionary = this._dictionary.get('AP');
                        if (dictionary && dictionary.has('N')) {
                            var appearanceStream = dictionary.get('N');
                            if (appearanceStream) {
                                var reference = dictionary.getRaw('N');
                                if (reference) {
                                    appearanceStream.reference = reference;
                                }
                                this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                            }
                        }
                    }
                }
            }
        }
        if (isFlatten && this._appearanceTemplate) {
            var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
            if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                if (box) {
                    this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                }
            }
            this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
        }
        else if (isFlatten) {
            this._page.annotations.remove(this);
        }
    };
    return PdfWatermarkAnnotation;
}(PdfAnnotation));
export { PdfWatermarkAnnotation };
/**
 * `PdfRubberStampAnnotation` class represents the rubber stamp annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new rubber stamp annotation
 * const annotation: PdfRubberStampAnnotation = new PdfRubberStampAnnotation ({x: 50, y: 100, width: 100, height: 50});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfRubberStampAnnotation = /** @class */ (function (_super) {
    __extends(PdfRubberStampAnnotation, _super);
    function PdfRubberStampAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Specifies the rubber stamp icon to render.
         *
         * @private
         */
        _this._icon = PdfRubberStampAnnotationIcon.draft;
        _this._stampWidth = 0;
        _this._iconString = '';
        _this.rotateAngle = 0;
        /**
         * When true, adjusts bounds to account for rotation effects.
         *
         * @private
         */
        _this._alterRotateBounds = true;
        /**
         * Font used when generating the stamp appearance content.
         *
         * @private
         */
        _this._stampAppearanceFont = new PdfStandardFont(PdfFontFamily.helvetica, 20, PdfFontStyle.italic | PdfFontStyle.bold);
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Stamp'));
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._type = _PdfAnnotationType.rubberStampAnnotation;
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('color' in properties && _isNullOrUndefined(properties.color)) {
                _this.color = properties.color;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('icon' in properties && _isNullOrUndefined(properties.icon)) {
                _this.icon = properties.icon;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfRubberStampAnnotation.prototype, "icon", {
        /**
         * Gets the icon type of the rubber stamp annotation.
         *
         * @returns {PdfRubberStampAnnotationIcon} Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRubberStampAnnotation = page.annotations.at(0) as PdfRubberStampAnnotation;
         * // Gets the icon type of the rubber stamp annotation.
         * let icon: PdfRubberStampAnnotationIcon = annotation.icon;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Name')) {
                this._icon = _mapRubberStampIcon(this._dictionary.get('Name').name);
            }
            return this._icon;
        },
        /**
         * Sets the icon type of the rubber stamp annotation.
         *
         * @param {PdfRubberStampAnnotationIcon} value Annotation icon.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRubberStampAnnotation = page.annotations.at(0) as PdfRubberStampAnnotation;
         * // Sets the icon type of the rubber stamp annotation.
         * annotation.icon = PdfRubberStampAnnotationIcon.completed;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._icon = value;
                this._dictionary.update('Name', _PdfName.get('#' + this._obtainIconName(this._icon).replace(/\s+/g, '')));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRubberStampAnnotation.prototype, "appearance", {
        /**
         * Get the appearance of the rubber stamp annotation. (Read only)
         *
         * @returns {PdfAppearance} Returns the appearance of the annotation.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Create a new rubber stamp annotation
         * const annotation: PdfRubberStampAnnotation = new PdfRubberStampAnnotation({x: 50, y: 100, width: 100, height: 50});
         * // Get the appearance of the annotation
         * let appearance: PdfAppearance = annotation.appearance;
         * // Access the normal template of the appearance
         * let template: PdfTemplate = appearance.normal;
         * // Create new image object by using JPEG image data as Base64 string format
         * let image: PdfImage = new PdfBitmap('/9j/4AAQSkZJRgABAQEAkACQAAD/4....QB//Z');
         * // Draw the image as the custom appearance for the annotation
         * template.graphics.drawImage(image, {x: 0, y: 0, width: 100, height: 50});
         * // Add annotation to the page
         * page.annotations.add(annotation);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                return null;
            }
            if (typeof this._appearance === 'undefined') {
                var nativeRectangle = { x: 0, y: 0, width: this.bounds.width, height: this.bounds.height };
                this._appearance = new PdfAppearance(nativeRectangle, this);
                this._appearance.normal = new PdfTemplate(nativeRectangle, this._crossReference);
            }
            return this._appearance;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Create an appearance template for a rubber stamp annotation.
     *
     * ```typescript
     * // Load an existing PDF document
     * let document: PdfDocument = new PdfDocument(data, password);
     * // Get the first page
     * let page: PdfPage = document.getPage(0) as PdfPage;
     * // Get the first annotation of the page
     * let annotation: PdfRubberStampAnnotation = page.annotations.at(0) as PdfRubberStampAnnotation;
     * // Gets the appearance template of the annotation.
     * let template: PdfTemplate = annotation.createTemplate();
     * // Save the document
     * document.save('output.pdf');
     * // Destroy the document
     * document.destroy();
     * ```
     *
     * @returns {PdfTemplate} Returns the appearance template of the annotation.
     */
    PdfRubberStampAnnotation.prototype.createTemplate = function () {
        var template = this._createTemplate();
        if (typeof template === 'undefined') {
            template = this._createRubberStampAppearance();
        }
        return template;
    };
    Object.defineProperty(PdfRubberStampAnnotation.prototype, "_innerTemplateBounds", {
        /**
         * Returns the inner appearance bounds for a loaded stamp, aligning its x/y with the annotations current bounds.
         *
         * @private
         * @returns {{x: number, y: number, width: number, height: number}} The inner appearance rectangle.
         */
        get: function () {
            var innerBounds;
            if (this._isLoaded) {
                innerBounds = this._obtainInnerBounds();
                innerBounds.x = this.bounds.x;
                innerBounds.y = this.bounds.y;
            }
            return innerBounds;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a rubberstamp annotation from the given page and dictionary and initializes it as a loaded instance.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfRubberStampAnnotation} The loaded rubberstamp annotation instance.
     */
    PdfRubberStampAnnotation._load = function (page, dictionary) {
        var annot = new PdfRubberStampAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the rubber stamp annotation for the specified page and optional source dictionary.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfRubberStampAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup by ensuring BS/color defaults and either parsing an existing AP stream or creating a new rubberstamp appearance.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfRubberStampAnnotation.prototype._postProcess = function () {
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (!this._dictionary.has('C')) {
            this._isTransparentColor = true;
        }
        if (this._dictionary.has('AP') && this._isLoaded) {
            this._parseStampAppearance();
        }
        else {
            this._appearanceTemplate = this._createRubberStampAppearance();
        }
    };
    /**
     * Creates, parses, or imports the stamp appearance based on export/flatten/rotation state, handles popup flattening, and flattens or removes the annotation when needed.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation into page content and removes the annotation entry.
     * @returns {void} No return value.
     */
    PdfRubberStampAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        var isTransformBBox = false;
        if (this._isLoaded && (this._setAppearance || isFlatten || this._isExport)) {
            if ((!isFlatten && !this._isExport) || this._setAppearance || this._isRotated) {
                this._appearanceTemplate = this._createRubberStampAppearance();
            }
            if (!this._appearanceTemplate && (this._isExport || isFlatten) && this._dictionary.has('AP')) {
                isTransformBBox = this._parseStampAppearance();
            }
        }
        else {
            if (!(this._isImported && this._dictionary.has('AP'))) {
                this._postProcess();
            }
            if ((!this._appearanceTemplate) && (isFlatten || this._isImported)) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createRubberStampAppearance();
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        if (appearanceStream) {
                            var reference = dictionary.getRaw('N');
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten && this._appearanceTemplate) {
            var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
            if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                if (box) {
                    this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                }
            }
            if (isTransformBBox) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isTransformBBox);
            }
            else {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
        }
        else if (isFlatten) {
            this._page.annotations.remove(this);
        }
    };
    /**
     * Parses the normal appearance stream (AP/N), resolves rotation and BBox/Matrix, updates the template size, and indicates if BBox transformation is required.
     *
     * @private
     * @returns {boolean} True when the BBox must be transformed during flattening; otherwise, false.
     */
    PdfRubberStampAnnotation.prototype._parseStampAppearance = function () {
        var isTransformBBox = false;
        var dictionary = this._dictionary.get('AP');
        if (dictionary && dictionary.has('N')) {
            var appearanceStream = dictionary.get('N');
            if (appearanceStream) {
                var reference = dictionary.getRaw('N');
                if (reference) {
                    appearanceStream.reference = reference;
                }
                var isStamp = false;
                if (this._type === _PdfAnnotationType.rubberStampAnnotation) {
                    var isRotated = false;
                    var size = void 0;
                    var rect = void 0;
                    if (appearanceStream) {
                        isRotated = (this._page.rotation === PdfRotationAngle.angle0 &&
                            this.rotationAngle === PdfRotationAngle.angle0);
                        if (!isRotated) {
                            isRotated = (this._page.rotation !== PdfRotationAngle.angle0 &&
                                this.rotationAngle === PdfRotationAngle.angle0);
                        }
                    }
                    this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    isStamp = true;
                    isTransformBBox = isRotated ? true : false;
                    if (isTransformBBox && appearanceStream instanceof _PdfBaseStream) {
                        var matrix = appearanceStream.dictionary.getArray('Matrix');
                        if (matrix) {
                            var mMatrix = matrix.slice();
                            var bounds = appearanceStream.dictionary.getArray('BBox');
                            if (bounds && bounds.length > 3) {
                                rect = _toRectangle(bounds);
                                var rectangle = this._transformBBox(rect, mMatrix);
                                size = [rectangle[2], rectangle[3]];
                                this._appearanceTemplate._size = { width: size[0], height: size[1] };
                            }
                            else {
                                size = [rect.width, rect.height];
                            }
                        }
                    }
                    else if (rect) {
                        size = [rect.width, rect.height];
                    }
                }
                if (!isStamp) {
                    this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                }
            }
        }
        return isTransformBBox;
    };
    /**
     * Builds the rubber stamp appearance (icon name, rotation, drawing), registers the AP stream/reference, updates Border and Rect, and returns the template.
     *
     * @private
     * @returns {PdfTemplate} The generated appearance template.
     */
    PdfRubberStampAnnotation.prototype._createRubberStampAppearance = function () {
        var nativeRectangle = { x: 0, y: 0, width: this.bounds.width, height: this.bounds.height };
        var appearance;
        if (this._appearance) {
            appearance = this._appearance;
            if (!this._dictionary.has('Name')) {
                this._dictionary.update('Name', _PdfName.get('#23CustomStamp'));
            }
        }
        else {
            this._iconString = this._obtainIconName(this.icon);
            this._dictionary.update('Name', _PdfName.get('#23' + this._iconString.replace(/\s+/g, '')));
            appearance = new PdfAppearance(nativeRectangle, this);
            appearance.normal = new PdfTemplate(nativeRectangle, this._crossReference);
        }
        var template = appearance.normal;
        if (this._alterRotateBounds && typeof this._rotate !== 'undefined' && (this._rotate !== PdfRotationAngle.angle0 || this._getRotationAngle() !== 0)) {
            this.rotateAngle = this._getRotationAngle();
            if (this.rotateAngle === 0) {
                this.rotateAngle = this.rotationAngle * 90;
            }
            this.bounds = this._getRotatedBounds(this.bounds, this.rotate);
        }
        else {
            this.rotateAngle = this._getRotationAngle();
        }
        _setMatrix(template, this.rotate, this);
        if (!this._appearance) {
            this._drawStampAppearance(template);
        }
        var hasAppearanceReference;
        var appearanceReference;
        if (this._dictionary && this._dictionary.has('AP')) {
            var appearance_1 = this._dictionary.get('AP');
            if (appearance_1 && appearance_1.has('N')) {
                appearanceReference = appearance_1.getRaw('N');
                if (appearanceReference instanceof _PdfReference) {
                    this._crossReference._cacheMap.delete(appearanceReference);
                    hasAppearanceReference = true;
                }
            }
        }
        var dictionary = new _PdfDictionary();
        template._content.dictionary._updated = true;
        if (!hasAppearanceReference) {
            appearanceReference = this._crossReference._getNextReference();
        }
        this._crossReference._cacheMap.set(appearanceReference, template._content);
        template._content.reference = appearanceReference;
        dictionary.set('N', appearanceReference);
        dictionary._updated = true;
        this._dictionary.set('AP', dictionary);
        this._dictionary.set('Border', [this.border.hRadius, this.border.vRadius, this.border.width]);
        this._dictionary.update('Rect', _updateBounds(this));
        return template;
    };
    /**
     * Renders the rubberstamp artwork into the provided template using scaling, transparency, and the configured appearance font.
     *
     * @private
     * @param {PdfTemplate} template The template whose graphics will receive the rendered stamp.
     * @returns {void} No return value.
     */
    PdfRubberStampAnnotation.prototype._drawStampAppearance = function (template) {
        var stringFormat = new PdfStringFormat();
        stringFormat.alignment = PdfTextAlignment.center;
        stringFormat.lineAlignment = PdfVerticalAlignment.middle;
        var backBrush = new PdfBrush(this._obtainBackGroundColor());
        var borderPen = new PdfPen(this._obtainBorderColor(), this.border.width);
        var graphics = template.graphics;
        graphics.save();
        graphics.scaleTransform(template._size.width / (this._stampWidth + 4), (template._size.height / 28));
        var rubberFont = this._stampAppearanceFont;
        if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
            graphics.setTransparency(this._opacity);
        }
        this._drawRubberStamp(graphics, borderPen, backBrush, rubberFont, stringFormat);
        graphics.restore();
    };
    /**
     * Maps the rubberstamp icon enum to its display name and updates the baseline stamp width for layout.
     *
     * @private
     * @param {PdfRubberStampAnnotationIcon} icon The icon enum value.
     * @returns {string} The human readable icon name.
     */
    PdfRubberStampAnnotation.prototype._obtainIconName = function (icon) {
        switch (icon) {
            case PdfRubberStampAnnotationIcon.approved:
                this._iconString = 'Approved';
                this._stampWidth = 126;
                break;
            case PdfRubberStampAnnotationIcon.asIs:
                this._iconString = 'As Is';
                this._stampWidth = 75;
                break;
            case PdfRubberStampAnnotationIcon.confidential:
                this._iconString = 'Confidential';
                this._stampWidth = 166;
                break;
            case PdfRubberStampAnnotationIcon.departmental:
                this._iconString = 'Departmental';
                this._stampWidth = 186;
                break;
            case PdfRubberStampAnnotationIcon.draft:
                this._iconString = 'Draft';
                this._stampWidth = 90;
                break;
            case PdfRubberStampAnnotationIcon.experimental:
                this._iconString = 'Experimental';
                this._stampWidth = 176;
                break;
            case PdfRubberStampAnnotationIcon.expired:
                this._iconString = 'Expired';
                this._stampWidth = 116;
                break;
            case PdfRubberStampAnnotationIcon.final:
                this._iconString = 'Final';
                this._stampWidth = 90;
                break;
            case PdfRubberStampAnnotationIcon.forComment:
                this._iconString = 'For Comment';
                this._stampWidth = 166;
                break;
            case PdfRubberStampAnnotationIcon.forPublicRelease:
                this._iconString = 'For Public Release';
                this._stampWidth = 240;
                break;
            case PdfRubberStampAnnotationIcon.notApproved:
                this._iconString = 'Not Approved';
                this._stampWidth = 186;
                break;
            case PdfRubberStampAnnotationIcon.notForPublicRelease:
                this._iconString = 'Not For Public Release';
                this._stampWidth = 290;
                break;
            case PdfRubberStampAnnotationIcon.sold:
                this._iconString = 'Sold';
                this._stampWidth = 75;
                break;
            case PdfRubberStampAnnotationIcon.topSecret:
                this._iconString = 'Top Secret';
                this._stampWidth = 146;
                break;
            case PdfRubberStampAnnotationIcon.completed:
                this._iconString = 'Completed';
                this._stampWidth = 136;
                break;
            case PdfRubberStampAnnotationIcon.void:
                this._iconString = 'Void';
                this._stampWidth = 75;
                break;
            case PdfRubberStampAnnotationIcon.informationOnly:
                this._iconString = 'Information Only';
                this._stampWidth = 230;
                break;
            case PdfRubberStampAnnotationIcon.preliminaryResults:
                this._iconString = 'Preliminary Results';
                this._stampWidth = 260;
                break;
        }
        return this._iconString;
    };
    /**
     * Returns the background color for the current stamp icon category (approval/warning/neutral palette).
     *
     * @private
     * @returns {PdfColor} The background color.
     */
    PdfRubberStampAnnotation.prototype._obtainBackGroundColor = function () {
        var color;
        var red;
        var green;
        var blue;
        if (this._icon === PdfRubberStampAnnotationIcon.notApproved ||
            this._icon === PdfRubberStampAnnotationIcon.void) {
            red = 251;
            green = 222;
            blue = 221;
            color = { r: red, g: green, b: blue };
        }
        else if (this._icon === PdfRubberStampAnnotationIcon.approved ||
            this._icon === PdfRubberStampAnnotationIcon.final ||
            this._icon === PdfRubberStampAnnotationIcon.completed) {
            red = 229;
            green = 238;
            blue = 222;
            color = { r: red, g: green, b: blue };
        }
        else {
            red = 219;
            green = 227;
            blue = 240;
            color = { r: red, g: green, b: blue };
        }
        return color;
    };
    /**
     * Returns the border/text color for the current stamp icon category (approval/warning/neutral palette).
     *
     * @private
     * @returns {PdfColor} The border and text color.
     */
    PdfRubberStampAnnotation.prototype._obtainBorderColor = function () {
        var color;
        var red;
        var green;
        var blue;
        if (this._icon === PdfRubberStampAnnotationIcon.notApproved ||
            this._icon === PdfRubberStampAnnotationIcon.void) {
            red = 151;
            green = 23;
            blue = 15;
            color = { r: red, g: green, b: blue };
        }
        else if (this._icon === PdfRubberStampAnnotationIcon.approved ||
            this._icon === PdfRubberStampAnnotationIcon.final ||
            this._icon === PdfRubberStampAnnotationIcon.completed) {
            red = 73;
            green = 110;
            blue = 38;
            color = { r: red, g: green, b: blue };
        }
        else {
            red = 24;
            green = 37;
            blue = 100;
            color = { r: red, g: green, b: blue };
        }
        return color;
    };
    /**
     * Draws the rounded stamp shape and centered uppercase label using the provided pen, brush, and font.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context to draw on.
     * @param {PdfPen} pen The outline pen for the rounded rectangle.
     * @param {PdfBrush} brush The fill brush for the rounded rectangle.
     * @param {PdfStandardFont} font The font used to render the stamp text.
     * @param {PdfStringFormat} format The string format for alignment.
     * @returns {void} No return value.
     */
    PdfRubberStampAnnotation.prototype._drawRubberStamp = function (graphics, pen, brush, font, format) {
        var bounds = { x: 2, y: 1, width: this._stampWidth, height: 26 };
        graphics.drawRoundedRectangle(bounds, 3, pen, brush);
        var pdfBrush = new PdfBrush(this._obtainBorderColor());
        graphics.drawString(this._iconString.toUpperCase(), font, bounds, null, pdfBrush, format);
    };
    /**
     * Extracts and returns the inner bounds from the normal appearance streams BBox if present.
     *
     * @private
     * @returns {{x: number, y: number, width: number, height: number}} The inner bounds rectangle, or zeros when unavailable.
     */
    PdfRubberStampAnnotation.prototype._obtainInnerBounds = function () {
        var bounds = { x: 0, y: 0, width: 0, height: 0 };
        if (this._dictionary && this._dictionary.has('AP')) {
            var appearanceDictionary = this._dictionary.get('AP');
            if (appearanceDictionary && appearanceDictionary.has('N')) {
                var normalAppearance = appearanceDictionary.get('N');
                if (normalAppearance && typeof normalAppearance.dictionary !== 'undefined') {
                    var normalAppearanceDictionary = normalAppearance.dictionary;
                    if (normalAppearanceDictionary.has('BBox')) {
                        var values = normalAppearanceDictionary.getArray('BBox');
                        if (values && values.length === 4) {
                            bounds = _toRectangle(values);
                        }
                    }
                }
            }
        }
        return bounds;
    };
    return PdfRubberStampAnnotation;
}(PdfComment));
export { PdfRubberStampAnnotation };
/**
 * `PdfSoundAnnotation` class represents the sound annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: PdfSoundAnnotation = page.annotations.at(0) as PdfSoundAnnotation;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfSoundAnnotation = /** @class */ (function (_super) {
    __extends(PdfSoundAnnotation, _super);
    /**
     * Initializes a new instance of the `PdfSoundAnnotation` class.
     *
     * @private
     */
    function PdfSoundAnnotation() {
        var _this = _super.call(this) || this;
        _this._type = _PdfAnnotationType.soundAnnotation;
        return _this;
    }
    /**
     * Loads a sound annotation from the given page and dictionary and initializes it as a loaded instance.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfSoundAnnotation} The loaded sound annotation instance.
     */
    PdfSoundAnnotation._load = function (page, dictionary) {
        var annot = new PdfSoundAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Loads a sound annotation from the given page and dictionary and initializes it as a loaded instance.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {void} nothing.
     */
    PdfSoundAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Performs flattening for sound annotations by importing the appearance stream when available or removing the annotation if none exists.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, attempts to flatten the annotation into the page; otherwise, no action.
     * @returns {void} No return value.
     */
    PdfSoundAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfSoundAnnotation;
}(PdfComment));
export { PdfSoundAnnotation };
/**
 * `PdfFreeTextAnnotation` class represents the free text annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new free text annotation
 * const annotation: PdfFreeTextAnnotation = new PdfFreeTextAnnotation({x: 50, y: 100, width: 100, height: 50});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfFreeTextAnnotation = /** @class */ (function (_super) {
    __extends(PdfFreeTextAnnotation, _super);
    function PdfFreeTextAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        /**
         * Stores an optional intent description string for the annotation.
         *
         * @private
         */
        _this._intentString = '';
        /**
         * Default font used for markup elements within the free text annotation.
         *
         * @private
         */
        _this._markUpFont = new PdfStandardFont(PdfFontFamily.helvetica, 7, PdfFontStyle.regular);
        _this._textAlignment = PdfTextAlignment.left;
        _this._cropBoxValueX = 0;
        _this._cropBoxValueY = 0;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('FreeText'));
        if (bounds) {
            _this.bounds = bounds;
        }
        _this._isContentUpdated = false;
        _this._type = _PdfAnnotationType.freeTextAnnotation;
        _this._parsedXMLData = [];
        if (properties) {
            if ('text' in properties && _isNullOrUndefined(properties.text)) {
                _this.text = properties.text;
            }
            if ('author' in properties && _isNullOrUndefined(properties.author)) {
                _this.author = properties.author;
            }
            if ('subject' in properties && _isNullOrUndefined(properties.subject)) {
                _this.subject = properties.subject;
            }
            if ('textMarkUpColor' in properties && _isNullOrUndefined(properties.textMarkUpColor)) {
                _this.textMarkUpColor = properties.textMarkUpColor;
            }
            if ('innerColor' in properties && _isNullOrUndefined(properties.innerColor)) {
                _this.innerColor = properties.innerColor;
            }
            if ('lineEndingStyle' in properties && _isNullOrUndefined(properties.lineEndingStyle)) {
                _this.lineEndingStyle = properties.lineEndingStyle;
            }
            if ('opacity' in properties && _isNullOrUndefined(properties.opacity)) {
                _this.opacity = properties.opacity;
            }
            if ('border' in properties && _isNullOrUndefined(properties.border)) {
                _this.border = properties.border;
            }
            if ('borderColor' in properties && _isNullOrUndefined(properties.borderColor)) {
                _this.borderColor = properties.borderColor;
            }
            if ('annotationIntent' in properties && _isNullOrUndefined(properties.annotationIntent)) {
                _this.annotationIntent = properties.annotationIntent;
            }
            if ('textAlignment' in properties && _isNullOrUndefined(properties.textAlignment)) {
                _this.textAlignment = properties.textAlignment;
            }
            if ('font' in properties && _isNullOrUndefined(properties.font)) {
                _this.font = properties.font;
            }
            if ('calloutLines' in properties && _isNullOrUndefined(properties.calloutLines)) {
                _this.calloutLines = properties.calloutLines;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "calloutLines", {
        /**
         * Gets the callout lines of the free text annotation.
         *
         * @returns {Array<Point>} Callout lines.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation= page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the callout lines of the free text annotation.
         * let calloutLines: Array<Point[]> = annotation.calloutLines;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._calloutLines === null || typeof this._calloutLines === 'undefined') {
                this._calloutLines = this._getCalloutLinePoints();
            }
            return this._calloutLines;
        },
        /**
         * Sets the callout lines of the free text annotation.
         *
         * @param {Array<Point>} value Callout lines.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the callout lines of the free text annotation.
         * annotation.calloutLines = [{x: 100, y: 450}, {x: 100, y: 200}, {x: 100, y: 150}];
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (!this._isLoaded) {
                this._calloutLines = value;
                return;
            }
            var isChanged = false;
            if (this._isLoaded && value.length >= 2) {
                if (this._calloutLines.length === value.length) {
                    for (var i = 0; i < value.length; i++) {
                        var newPoint = value[i];
                        var oldPoint = this._calloutLines[i];
                        if (newPoint.x !== oldPoint.x || newPoint.y !== oldPoint.y) {
                            isChanged = true;
                            break;
                        }
                    }
                }
                else {
                    isChanged = true;
                }
            }
            if (isChanged) {
                var pageHeight = this._page.size.height;
                var lines = [];
                for (var i = 0; i < value.length; i++) {
                    lines.push(value[i].x + this._cropBoxValueX);
                    lines.push((pageHeight + this._cropBoxValueY) - value[i].y);
                }
                this._calloutLines = value;
                this._dictionary.update('CL', lines);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "lineEndingStyle", {
        /**
         * Gets the line ending style of the annotation.
         *
         * @returns {PdfLineEndingStyle} Line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the Line ending style of the annotation.
         * let lineEndingStyle: PdfLineEndingStyle = annotation.lineEndingStyle;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                this._lineEndingStyle = this._obtainLineEndingStyle();
            }
            else if (typeof this._lineEndingStyle === 'undefined') {
                this._lineEndingStyle = PdfLineEndingStyle.none;
            }
            return this._lineEndingStyle;
        },
        /**
         * Sets the line ending style of the line annotation.
         *
         * @param {PdfLineEndingStyle} value Line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the line ending style of the line annotation.
         * annotation.lineEndingStyle = PdfLineEndingStyle.closedArrow;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._dictionary.update('LE', _PdfName.get(_reverseMapEndingStyle(value)));
            }
            this._lineEndingStyle = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "textMarkUpColor", {
        /**
         * Gets the text markup color of the annotation.
         *
         * @returns {PdfColor} Text markup color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the text markup color of the annotation.
         * let textMarkUpColor: PdfColor = annotation.textMarkUpColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._textMarkUpColor === 'undefined') {
                var color = void 0;
                if (this._dictionary.has('TextColor')) {
                    this._textMarkUpColor = _parseColor(this._dictionary.getArray('TextColor'));
                    return this._textMarkUpColor;
                }
                if (this._dictionary.has('DS')) {
                    var collections = this._dictionary.get('DS').split(';');
                    for (var i = 0; i < collections.length; i++) {
                        if (collections[i].indexOf('color') !== -1) {
                            color = collections[i].split(':')[1];
                            if (color.startsWith('#')) {
                                color = color.substring(1);
                            }
                            this._textMarkUpColor = _convertToColor(color);
                        }
                    }
                }
                if (!this._textMarkUpColor && this._dictionary.has('RC')) {
                    var rcBrush = void 0;
                    var rcColor = void 0;
                    if (this._parsedXMLData.length > 0 && this._parsedXMLData[3]) {
                        rcBrush = this._parsedXMLData[3];
                        rcColor = rcBrush._color;
                        this._textMarkUpColor = rcColor;
                    }
                }
                if (this._isLoaded && !this._textMarkUpColor && this._dictionary.has('DA')) {
                    this._textMarkUpColor = this._obtainColor();
                }
                else if (!this._isLoaded && !this._textMarkUpColor) {
                    this._textMarkUpColor = { r: 0, g: 0, b: 0 };
                }
            }
            return this._textMarkUpColor;
        },
        /**
         * Sets the text markup color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the text markup color of the annotation.
         * annotation.textMarkUpColor = {r: 200, g: 200, b: 200};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                this._textMarkUpColor = value;
                this._updateStyle(this.font, value, this.textAlignment);
            }
            this._isContentUpdated = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "textAlignment", {
        /**
         * Gets the text alignment of the annotation.
         *
         * @returns {PdfTextAlignment} Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the text alignment of the annotation.
         * let textAlignment: PdfTextAlignment = annotation.textAlignment;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Q')) {
                this._textAlignment = this._dictionary.get('Q');
            }
            else if (this._dictionary.has('RC')) {
                var rcAlignment = void 0;
                if (this._parsedXMLData.length > 0 && this._parsedXMLData[1]) {
                    rcAlignment = this._parsedXMLData[1];
                    this._textAlignment = rcAlignment;
                }
            }
            return this._textAlignment;
        },
        /**
         * Sets the text alignment of the annotation.
         *
         * @param {PdfTextAlignment} value Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the text alignment of the annotation.
         * annotation.textAlignment = PdfTextAlignment.justify;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._textAlignment !== value) {
                this._dictionary.update('Q', value);
            }
            this._textAlignment = value;
            this._isContentUpdated = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "font", {
        /**
         * Gets the font of the annotation.
         *
         * @returns {PdfFont} font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the font of the annotation.
         * let font: PdfFont = annotation.font;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._font) {
                this._font = this._obtainFont();
                if ((this._font === null || typeof this._font === 'undefined') || (!this._isLoaded && this._font.size === 1)) {
                    this._font = this._markUpFont;
                }
            }
            return this._font;
        },
        /**
         * Sets the font of the annotation.
         *
         * @param {PdfFont} value font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the font of the annotation.
         * annotation.font = document.embedFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._font = value;
            this._isContentUpdated = true;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "borderColor", {
        /**
         * Gets the border color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the border color of the annotation.
         * let borderColor: PdfColor = annotation.borderColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._borderColor === 'undefined' && this._dictionary.has('DA')) {
                this._borderColor = this._obtainColor();
            }
            return this._borderColor;
        },
        /**
         * Sets the border color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the border color of the annotation.
         * annotation.borderColor = {r: 150, g: 150, b: 150};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                this._borderColor = value;
                this._dictionary.update('DA', this._getBorderColorString(this.borderColor));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "annotationIntent", {
        /**
         * Gets the intent of the annotation.
         *
         * @returns {PdfAnnotationIntent} Annotation intent.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Gets the intent of the annotation.
         * let annotationIntent: PdfAnnotationIntent = annotation.annotationIntent;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._annotationIntent === 'undefined' || this._annotationIntent === null) {
                if (this._dictionary.has('IT')) {
                    this._annotationIntent = _mapAnnotationIntent(this._dictionary.get('IT').name);
                }
                else {
                    this._annotationIntent = PdfAnnotationIntent.none;
                }
            }
            return this._annotationIntent;
        },
        /**
         * Sets the intent of the annotation.
         *
         * @param {PdfAnnotationIntent} value Annotation intent.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfFreeTextAnnotation = page.annotations.at(0) as PdfFreeTextAnnotation;
         * // Sets the intent of the annotation.
         * annotation.annotationIntent = PdfAnnotationIntent.freeTextTypeWriter;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined') {
                this._annotationIntent = value;
                if ((typeof this.subject === 'undefined' || this.subject === 'null')
                    && value === PdfAnnotationIntent.none &&
                    (!this._calloutLines || (this._calloutLines && this._calloutLines.length === 0))) {
                    this._dictionary.update('Subj', 'Text Box');
                }
                else {
                    this._dictionary.update('IT', _PdfName.get(this._obtainAnnotationIntent(this._annotationIntent)));
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "_mkDictionary", {
        /**
         * Returns the annotations MK appearance characteristics dictionary if present.
         *
         * @private
         * @returns {_PdfDictionary} The MK dictionary or undefined when absent.
         */
        get: function () {
            var value;
            if (this._dictionary.has('MK')) {
                value = this._dictionary.get('MK');
            }
            return value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfFreeTextAnnotation.prototype, "_innerBounds", {
        /**
         * Computes and returns the inner text box bounds, aligning to the annotations position and honoring callout lines.
         *
         * @private
         * @returns {{x: number, y: number, width: number, height: number}} The inner text box rectangle.
         */
        get: function () {
            var borderWidth = this.border.width / 2;
            var nativeRectangle = this._obtainAppearanceBounds();
            var parameter = new _PaintParameter();
            var borderColor = this._obtainColor();
            var borderPen = new PdfPen(borderColor, this.border.width);
            if (this.border.width > 0) {
                parameter.borderPen = borderPen;
            }
            var rectangle = this._obtainStyle(borderPen, nativeRectangle, borderWidth, parameter);
            if (this.calloutLines && this._calloutLines.length > 0) {
                this._innerTextBoxBounds = { x: rectangle[0], y: this._page.size.height - (rectangle[1] + rectangle[3]),
                    width: rectangle[2], height: rectangle[3] };
            }
            return this._innerTextBoxBounds;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a free text annotation from the given page and dictionary, marks it as loaded, parses RC if present, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfFreeTextAnnotation} The loaded free text annotation instance.
     */
    PdfFreeTextAnnotation._load = function (page, dictionary) {
        var annot = new PdfFreeTextAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        if (dictionary.has('RC')) {
            annot._parsedXMLData = annot._parseMarkupLanguageData(dictionary.get('RC'));
        }
        return annot;
    };
    /**
     * Sets the free text internal padding values used to insert text within the annotation rectangle.
     *
     * @private
     * @param {_PdfPaddings} paddings The paddings to apply (left/top/right/bottom).
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._setPaddings = function (paddings) {
        this._paddings = paddings;
    };
    /**
     * Initializes the free text annotation for the specified page and optional source dictionary.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup: validates bounds, ensures BS/color defaults, captures Crop/MediaBox offsets, creates appearance when needed, and persists the dictionary for non flattened cases.
     *
     * @private
     * @param {boolean} isFlatten When true, prepares for flattening by generating appearance immediately.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (!this._dictionary.has('C')) {
            this._isTransparentColor = true;
        }
        var cropOrMediaBox = this._getCropOrMediaBox();
        if (cropOrMediaBox && cropOrMediaBox.length > 3 && typeof cropOrMediaBox[0] === 'number' && typeof cropOrMediaBox[1] === 'number' && (cropOrMediaBox[0] !== 0 || cropOrMediaBox[1] !== 0)) {
            this._cropBoxValueX = cropOrMediaBox[0];
            this._cropBoxValueY = cropOrMediaBox[1];
        }
        if (isFlatten || this._setAppearance || this._customTemplate.size > 0) {
            this._appearanceTemplate = this._createAppearance();
        }
        if (!isFlatten) {
            this._dictionary.update('Rect', _updateBounds(this));
            this._saveFreeTextDictionary();
        }
    };
    /**
     * Builds or imports the appearance based on state/flattening, flattens when appropriate, updates style if RC changed, and writes AP entries for non flattened output.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation into page content and removes it.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (this._isLoaded) {
            if (this._setAppearance || this._customTemplate.size > 0 || (isFlatten && !this._dictionary.has('AP'))) {
                this._appearanceTemplate = this._createAppearance();
            }
            if (!this._appearanceTemplate && isFlatten && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    var appearanceStream = dictionary.get('N');
                    if (appearanceStream) {
                        var reference = dictionary.getRaw('N');
                        if (reference) {
                            appearanceStream.reference = reference;
                        }
                        this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                    }
                }
            }
        }
        else {
            this._postProcess(isFlatten);
            if (!this._appearanceTemplate && isFlatten) {
                if (!this._dictionary.has('AP')) {
                    this._appearanceTemplate = this._createAppearance();
                }
                else {
                    var dictionary = this._dictionary.get('AP');
                    if (dictionary && dictionary.has('N')) {
                        var appearanceStream = dictionary.get('N');
                        if (appearanceStream) {
                            var reference = dictionary.getRaw('N');
                            if (reference) {
                                appearanceStream.reference = reference;
                            }
                            this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                        }
                    }
                }
            }
        }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            if (this._isLoaded) {
                this._flattenLoadedPopUp();
            }
            else {
                this._flattenPopUp();
            }
        }
        if (isFlatten && this._appearanceTemplate) {
            var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
            if (!this._appearanceTemplate._content.dictionary.has('Matrix') && !this._isLoaded) {
                var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                if (box) {
                    this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                }
            }
            if (isNormalMatrix && typeof this._page.rotation !== 'undefined' && this._page.rotation !== PdfRotationAngle.angle0) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else if (this._appearanceTemplate && !this._dictionary.has('AP')) {
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else if (this._dictionary.has('AP')) {
                if (this._isValidTemplateMatrix(this._appearanceTemplate._content.dictionary, this.bounds, this._appearanceTemplate)) {
                    this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
                }
            }
        }
        else if (isFlatten) {
            this._page.annotations.remove(this);
        }
        if (this._dictionary.has('RC') && this._isContentUpdated) {
            this._updateStyle(this.font, this._textMarkUpColor, this.textAlignment);
        }
        if (!isFlatten && (this._setAppearance || this._customTemplate.size > 0)) {
            var appearance = void 0;
            var crossReference = this._crossReference;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = crossReference._getNextReference();
                appearance = new _PdfDictionary(crossReference);
                crossReference._cacheMap.set(reference, appearance);
                appearance._updated = true;
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                this._drawCustomAppearance(appearance);
            }
            else {
                _removeDuplicateReference(appearance, crossReference, 'N');
                var reference = crossReference._getNextReference();
                crossReference._cacheMap.set(reference, this._appearanceTemplate._content);
                this._appearanceTemplate._content.dictionary._update = true;
                this._appearanceTemplate._content.reference = reference;
                appearance.update('N', reference);
            }
        }
    };
    /* eslint-disable */
    /**
     * Validates the template Matrix/BBox against target bounds; if misaligned, draws directly to page and removes the annotation.
     *
     * @private
     * @param {_PdfDictionary} dictionary The appearance stream dictionary to validate.
     * @param {any} bounds The target placement rectangle.
     * @param {PdfTemplate} appearanceTemplate The template to draw when fixing placement.
     * @returns {boolean} True if the template matrix is valid; otherwise, false.
     */
    PdfFreeTextAnnotation.prototype._isValidTemplateMatrix = function (dictionary, bounds, appearanceTemplate) {
        var isValidMatrix = true;
        var pointF = bounds;
        if (dictionary && dictionary.has('Matrix')) {
            var box = dictionary.getArray('BBox');
            var matrix = dictionary.getArray('Matrix');
            if (matrix && box && matrix.length > 3 && box.length > 2) {
                if (typeof matrix[0] !== 'undefined' &&
                    typeof matrix[1] !== 'undefined' &&
                    typeof matrix[2] !== 'undefined' &&
                    typeof matrix[3] !== 'undefined') {
                    if (matrix[0] === 1 && matrix[1] === 0 && matrix[2] === 0 && matrix[3] === 1) {
                        if (typeof box[0] !== 'undefined' &&
                            typeof box[1] !== 'undefined' &&
                            typeof box[2] !== 'undefined' &&
                            typeof box[3] !== 'undefined') {
                            if (Math.round(box[0]) !== Math.round(-(matrix[4])) && Math.round(box[1]) !== Math.round(-(matrix[5])) ||
                                box[0] === 0 && Math.round(-(matrix[4])) === 0) {
                                var graphics = this._page.graphics;
                                var state = graphics.save();
                                if (typeof this.opacity !== 'undefined' && this._opacity < 1) {
                                    graphics.setTransparency(this._opacity);
                                }
                                pointF.x -= box[0];
                                pointF.y += box[1];
                                graphics.drawTemplate(appearanceTemplate, pointF);
                                graphics.restore(state);
                                this._page.annotations.remove(this);
                                isValidMatrix = false;
                            }
                        }
                    }
                }
            }
        }
        return isValidMatrix;
    };
    /* eslint-enable */
    /**
     * Creates the free text appearance template, applies rotation/opacity, updates RD/Rect, and returns the template.
     *
     * @private
     * @returns {PdfTemplate} The generated appearance template.
     */
    PdfFreeTextAnnotation.prototype._createAppearance = function () {
        var template;
        var margins;
        if (this._page && this._page._pageSettings && this._page._pageSettings.margins) {
            margins = this._page._pageSettings.margins;
        }
        if (this._customTemplate.has('N')) {
            template = this._customTemplate.get('N');
        }
        else {
            var borderWidth = this.border.width / 2;
            var nativeRectangle = this._obtainAppearanceBounds();
            var rotationAngle = this.rotate;
            if (rotationAngle === 0 || rotationAngle === 90 || rotationAngle === 180 || rotationAngle === 270) {
                this._isAllRotation = false;
            }
            if (rotationAngle > 0 && this._isAllRotation) {
                template = new PdfTemplate([0, 0, nativeRectangle[2], nativeRectangle[3]], this._crossReference);
            }
            else {
                template = new PdfTemplate(nativeRectangle, this._crossReference);
            }
            var box = template._content.dictionary.getArray('BBox');
            var angle = this._getRotationAngle();
            if (box && angle !== null && typeof angle !== 'undefined') {
                template._content.dictionary.set('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
            }
            var parameter = new _PaintParameter();
            var text = this._obtainText();
            template._writeTransformation = false;
            var graphics = template.graphics;
            var alignment = this._obtainTextAlignment();
            var borderColor = this._obtainColor();
            var borderPen = new PdfPen(borderColor, this.border.width);
            if (this.border.width > 0) {
                parameter.borderPen = borderPen;
            }
            var rectangle = this._obtainStyle(borderPen, nativeRectangle, borderWidth, parameter);
            if (this.color) {
                parameter.foreBrush = new PdfBrush(this._color);
            }
            var textColor = this.textMarkUpColor ? this._textMarkUpColor : { r: 0, g: 0, b: 0 };
            parameter.backBrush = new PdfBrush(textColor);
            parameter.borderWidth = this.border.width;
            if (this.calloutLines && this._calloutLines.length >= 2) {
                this._drawCallOuts(graphics, borderPen);
                if (this._isLoaded && typeof this._lineEndingStyle === 'undefined') {
                    this._lineEndingStyle = this.lineEndingStyle;
                }
                if (this._lineEndingStyle !== PdfLineEndingStyle.none) {
                    var rawPoints = this._obtainLinePoints();
                    var linePoints = [];
                    for (var i = 0; i < rawPoints.length; i += 2) {
                        linePoints.push({ x: rawPoints[i], y: rawPoints[i + 1] });
                    }
                    var angle_1 = this._getAngle(linePoints);
                    var endPoint = this._getAxisValue({ x: rawPoints[2], y: rawPoints[3] }, 90, 0);
                    this._drawLineEndStyle(endPoint, graphics, angle_1, borderPen, parameter.foreBrush, this.lineEndingStyle, this.border.width, false);
                }
                if (!this._dictionary.has('RD')) {
                    rectangle = [this.bounds.x + (margins ? margins.left : 0),
                        -((this._page.size.height - (this.bounds.y + this.bounds.height + (margins ? margins.top : 0)))),
                        this.bounds.width,
                        -this.bounds.height];
                }
                else {
                    rectangle = [rectangle[0], -rectangle[1], rectangle[2], -rectangle[3]];
                }
                rectangle[0] = rectangle[0] + this._cropBoxValueX;
                rectangle[1] = rectangle[1] - this._cropBoxValueY;
                this._calculateRectangle(rectangle);
                parameter.bounds = { x: rectangle[0], y: rectangle[1], width: rectangle[2], height: rectangle[3] };
            }
            else {
                rectangle = [rectangle[0], -rectangle[1], rectangle[2], -rectangle[3]];
                parameter.bounds = { x: rectangle[0], y: rectangle[1], width: rectangle[2], height: rectangle[3] };
            }
            var outerRectangle = this._obtainAppearanceBounds();
            var value = [rectangle[0] - outerRectangle[0],
                (-(rectangle[1])) - outerRectangle[1], rectangle[2] - outerRectangle[2],
                (((-rectangle[1]) - outerRectangle[1]) + (-rectangle[3])) - outerRectangle[3]];
            for (var i = 0; i < value.length; i++) {
                if (value[i] < 0) {
                    value[i] = -value[i];
                }
            }
            this._dictionary.update('RD', value);
            if (this.opacity && this._opacity < 1) {
                graphics.save();
                graphics.setTransparency(this._opacity);
            }
            if (this.rotationAngle && this._rotate !== PdfRotationAngle.angle0) {
                graphics.save();
            }
            this._drawFreeTextRectangle(graphics, parameter, rectangle, alignment);
            if (text) {
                this._drawFreeMarkUpText(graphics, parameter, rectangle, text, alignment);
            }
            if (this.opacity && this._opacity < 1) {
                graphics.restore();
            }
            if (this.rotationAngle && this._rotate !== PdfRotationAngle.angle0) {
                graphics.restore();
            }
        }
        var bounds = this._obtainAppearanceBounds();
        if (this.flatten) {
            this._bounds = { x: bounds[0] - (margins ? margins.left : 0), y: (this._page.size.height - (bounds[1] + bounds[3]) -
                    (margins ? margins.top : 0)), width: bounds[2], height: bounds[3] };
        }
        this._dictionary.set('Rect', [bounds[0], bounds[1], bounds[0] + bounds[2], bounds[1] + bounds[3]]);
        return template;
    };
    /**
     * Calculates and updates the RD array by comparing inner and outer appearance bounds.
     *
     * @private
     * @param {number[]} innerRectangle The inner rectangle [x, y, w, h] in appearance coordinates.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._calculateRectangle = function (innerRectangle) {
        var outerRectangle = this._obtainAppearanceBounds();
        var value = [innerRectangle[0] - outerRectangle[0],
            (-(innerRectangle[1])) - outerRectangle[1], innerRectangle[2] - outerRectangle[2],
            (((-innerRectangle[1]) - outerRectangle[1]) + (-innerRectangle[3])) - outerRectangle[3]];
        for (var i = 0; i < 4; i++) {
            if (value[i] < 0) {
                value[i] = -value[i];
            }
        }
        this._dictionary.set('RD', value);
    };
    /**
     * Maps the annotation intent enum to its PDF intent name string and returns it.
     *
     * @private
     * @param {PdfAnnotationIntent} _annotationIntent The intent enum to map.
     * @returns {string} The PDF intent name (e.g., 'FreeTextCallout').
     */
    PdfFreeTextAnnotation.prototype._obtainAnnotationIntent = function (_annotationIntent) {
        switch (_annotationIntent) {
            case PdfAnnotationIntent.freeTextCallout:
                this._intentString = 'FreeTextCallout';
                break;
            case PdfAnnotationIntent.freeTextTypeWriter:
                this._intentString = 'FreeTextTypeWriter';
                break;
        }
        return this._intentString;
    };
    /**
     * Resolves the effective font including RC overrides when present and returns a mapped PdfFont instance.
     *
     * @private
     * @returns {PdfFont} The resolved font for rendering.
     */
    PdfFreeTextAnnotation.prototype._obtainFont = function () {
        var fontData = this._obtainFontDetails();
        if (this._parsedXMLData.length > 0 && this._dictionary.has('RC')) {
            var rcFont = void 0;
            if (this._parsedXMLData.length > 0 && this._parsedXMLData[0]) {
                rcFont = this._parsedXMLData[0];
            }
            if (rcFont instanceof PdfStandardFont) {
                var font = rcFont;
                fontData.size = font.size;
                fontData.style = font.style;
                fontData.name = this._getFontFamily(font._fontFamily);
            }
            else if (rcFont instanceof PdfCjkStandardFont) {
                var font = rcFont;
                fontData.size = font.size;
                fontData.style = font.style;
                fontData.name = font._fontFamily.toString();
            }
        }
        return _mapFont(fontData.name, fontData.size, fontData.style, this);
    };
    /**
     * Maps a PdfFontFamily numeric identifier to its canonical font family name.
     *
     * @private
     * @param {number} value The numeric PdfFontFamily value.
     * @returns {string} The canonical font family name.
     */
    PdfFreeTextAnnotation.prototype._getFontFamily = function (value) {
        var index = Math.floor(value);
        switch (index) {
            case PdfFontFamily.helvetica:
                return 'Helvetica';
            case PdfFontFamily.courier:
                return 'Courier';
            case PdfFontFamily.timesRoman:
                return 'TimesRoman';
            case PdfFontFamily.symbol:
                return 'Symbol';
            case PdfFontFamily.zapfDingbats:
                return 'ZapfDingbats';
            default:
                return 'Helvetica';
        }
    };
    /**
     * Updates DS and RC with font, color, alignment, and decoration styles derived from the provided font and brush.
     *
     * @private
     * @param {PdfFont} font The font to encode into DS/RC.
     * @param {PdfColor} color The RGB text color to apply.
     * @param {PdfTextAlignment} alignment The paragraph alignment for text.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._updateStyle = function (font, color, alignment) {
        var textMarkUpColor;
        if (color) {
            textMarkUpColor = [color.r, color.g, color.b];
        }
        var fontName = font._metrics._name.includes('Times') ? 'Times' : font._metrics._name;
        var ds = 'font:' +
            fontName +
            ' ' +
            font.size +
            'pt;style:' + _reverseMapPdfFontStyle(font.style) +
            ';color:' +
            this._colorToHex(textMarkUpColor);
        this._dictionary.update('DS', ds);
        var body = '<?xml version="1.0"?><body xmlns="http://www.w3.org/1999/xhtml" style="font:'
            + fontName + ' ' + font.size + 'pt;font-weight:'
            + (font.isBold ? 'bold' : 'normal') + ';color:' + this._colorToHex(textMarkUpColor) + '"><p dir="ltr">';
        var textAlignment;
        var alignmentText;
        if (alignment !== null && typeof alignment !== 'undefined') {
            switch (alignment) {
                case PdfTextAlignment.left:
                    alignmentText = 'left';
                    break;
                case PdfTextAlignment.center:
                    alignmentText = 'center';
                    break;
                case PdfTextAlignment.right:
                    alignmentText = 'right';
                    break;
                case PdfTextAlignment.justify:
                    alignmentText = 'justify';
                    break;
            }
            if (alignmentText) {
                textAlignment = 'text-align:' + alignmentText + ';';
            }
        }
        var decorationText = '';
        var textDecoration;
        var italic = 'font-style:italic';
        var bold = 'font-style:bold';
        if (font.isUnderline) {
            decorationText = font.isStrikeout ? 'text-decoration:word line-through' : 'text-decoration:word';
            if (font.isItalic) {
                decorationText += ';' + italic;
            }
            else if (font.isBold) {
                decorationText += ';' + bold;
            }
        }
        else if (font.isStrikeout) {
            decorationText = 'text-decoration:line-through';
            if (font.isItalic) {
                decorationText += ';' + italic;
            }
            else if (font.isBold) {
                decorationText += ';' + bold;
            }
        }
        else {
            if (font.isItalic) {
                decorationText += italic;
            }
            else if (font.isBold) {
                decorationText += bold;
            }
        }
        if (decorationText !== '') {
            textDecoration = '<span style = "' + textAlignment + decorationText + '">' + (this.text ? this._getXmlFormattedString(this.text) : '') + '</span>';
        }
        else {
            textDecoration = '<span style = "' + textAlignment + '">' + (this.text ? this._getXmlFormattedString(this.text) : '') + '</span>';
        }
        this._dictionary.update('RC', body + textDecoration + '</p></body>');
    };
    /**
     * Draws the free text content within the computed bounds, applying padding, rotation handling, and string formatting.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context.
     * @param {_PaintParameter} parameter Paint parameters (pens/brushes/bounds).
     * @param {number[]} rectangle The drawing rectangle [x, y, w, h] (appearance coords).
     * @param {string} text The text to render.
     * @param {PdfTextAlignment} alignment The line alignment (left/center/right/justify).
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._drawFreeMarkUpText = function (graphics, parameter, rectangle, text, alignment) {
        var isRotation = false;
        var angle = this.rotate;
        if (this.rotationAngle === PdfRotationAngle.angle90 && !this._isAllRotation) {
            rectangle = [-rectangle[1], rectangle[0], -rectangle[3], rectangle[2]];
        }
        else if (this.rotationAngle === PdfRotationAngle.angle180 && !this._isAllRotation) {
            rectangle = [-(rectangle[2] + rectangle[0]), -rectangle[1], rectangle[2], -rectangle[3]];
        }
        else if (this.rotationAngle === PdfRotationAngle.angle270 && !this._isAllRotation) {
            rectangle = [(rectangle[1] + rectangle[3]), -(rectangle[0] + rectangle[2]), -rectangle[3], rectangle[2]];
        }
        else if (angle === 0 && !this._isAllRotation) {
            rectangle = [rectangle[0], (rectangle[1] + rectangle[3]), rectangle[2], rectangle[3]];
        }
        if ((typeof this._font === 'undefined' || this._font === null) || (!this._isLoaded && this._font.size === 1)) {
            this._font = this._markUpFont;
        }
        if (angle > 0 && this._isAllRotation) {
            isRotation = true;
            var bounds_1 = this.bounds;
            var format = new PdfStringFormat(PdfTextAlignment.center, PdfVerticalAlignment.middle);
            var textSize = this._font.measureString(text, { width: 0, height: 0 }, format, 0, 0);
            if (angle > 0 && angle <= 91) {
                graphics.translateTransform({ x: textSize.height, y: -bounds_1.height });
            }
            else if (angle > 91 && angle <= 181) {
                graphics.translateTransform({ x: bounds_1.width - textSize.height, y: -(bounds_1.height - textSize.height) });
            }
            else if (angle > 181 && angle <= 271) {
                graphics.translateTransform({ x: bounds_1.width - textSize.height, y: -textSize.height });
            }
            else if (angle > 271 && angle < 360) {
                graphics.translateTransform({ x: textSize.height, y: -textSize.height });
            }
            graphics.rotateTransform(angle);
            parameter.bounds = { x: 0, y: 0, width: parameter.bounds.width, height: parameter.bounds.height };
        }
        var bounds = [rectangle[0], rectangle[1], rectangle[2], rectangle[3]]; // eslint-disable-line
        if (this._paddings && !this._isLoaded) {
            var left = this._paddings._left;
            var top_3 = this._paddings._top;
            var right = this._paddings._right + this._paddings._left;
            var bottom = this._paddings._top + this._paddings._bottom;
            if (parameter.borderWidth > 0) {
                var first = rectangle[0] + (parameter.borderWidth + left);
                var second = rectangle[1] + (parameter.borderWidth + top_3);
                var third = rectangle[2] - ((parameter.borderWidth * 2) + right);
                var forth = void 0;
                if (rectangle[3] > 0) {
                    forth = rectangle[3] - ((parameter.borderWidth * 2) + bottom);
                }
                else {
                    forth = -rectangle[3] - ((parameter.borderWidth * 2) + bottom);
                }
                rectangle = [first, second, third, forth];
            }
            else {
                var first = rectangle[0] + left;
                var second = rectangle[1] + top_3;
                var third = rectangle[2] - right;
                var forth = void 0;
                if (rectangle[3] > 0) {
                    forth = rectangle[3] - bottom;
                }
                else {
                    forth = -rectangle[3] - bottom;
                }
                rectangle = [first, second, third, forth];
            }
        }
        else if (parameter.borderWidth > 0) {
            rectangle = [rectangle[0] + (parameter.borderWidth * 1.5),
                rectangle[1] + (parameter.borderWidth * 1.5),
                rectangle[2] - (parameter.borderWidth * 3),
                (rectangle[3] > 0) ? (rectangle[3] - (parameter.borderWidth * 3)) : (-rectangle[3] - (parameter.borderWidth * 3))];
        }
        this._drawFreeTextAnnotation(graphics, parameter, text, this._font, rectangle, true, alignment, isRotation);
    };
    /**
     * Renders the text box background/border or cloud appearance with rotation handling, then delegates text rendering.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context.
     * @param {_PaintParameter} parameter Paint parameters (pens/brushes/bounds).
     * @param {number[]} rectangle The rectangle [x, y, w, h] (appearance coords).
     * @param {PdfTextAlignment} alignment Text alignment for content drawing.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._drawFreeTextRectangle = function (graphics, parameter, rectangle, alignment) {
        var isRotation = false;
        if (this._dictionary.has('BE')) {
            for (var i = 0; i < rectangle.length; i++) {
                if (rectangle[i] < 0) {
                    rectangle[i] = -rectangle[i];
                }
            }
            this._drawAppearance(graphics, parameter, rectangle);
            if (this.rotationAngle === PdfRotationAngle.angle90 && !this._isAllRotation) {
                graphics.rotateTransform(-90);
            }
            else if (this.rotationAngle === PdfRotationAngle.angle180 && !this._isAllRotation) {
                graphics.rotateTransform(-180);
            }
            else if (this.rotationAngle === PdfRotationAngle.angle270 && !this._isAllRotation) {
                graphics.rotateTransform(-270);
            }
        }
        else {
            if (this.rotationAngle === PdfRotationAngle.angle90 && !this._isAllRotation) {
                graphics.rotateTransform(-90);
                parameter.bounds = { x: -rectangle[1], y: rectangle[2] + rectangle[0], width: -rectangle[3], height: -rectangle[2] };
            }
            else if (this.rotationAngle === PdfRotationAngle.angle180 && !this._isAllRotation) {
                graphics.rotateTransform(-180);
                parameter.bounds = { x: -(rectangle[2] + rectangle[0]), y: -(rectangle[3] + rectangle[1]),
                    width: rectangle[2], height: rectangle[3] };
            }
            else if (this.rotationAngle === PdfRotationAngle.angle270 && !this._isAllRotation) {
                graphics.rotateTransform(-270);
                parameter.bounds = { x: rectangle[1] + rectangle[3], y: -rectangle[0], width: -rectangle[3], height: -rectangle[2] };
            }
            if (parameter.borderWidth > 0 && !this._isAllRotation) {
                rectangle = [parameter.bounds.x, parameter.bounds.y, parameter.bounds.width, parameter.bounds.height];
            }
            this._drawFreeTextAnnotation(graphics, parameter, '', this._font, rectangle, false, alignment, isRotation);
        }
    };
    /**
     * Draws the cloud style rectangle appearance when BE/I is set by constructing a path and invoking the cloud drawer.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context.
     * @param {_PaintParameter} parameter Paint parameters including brushes and pen.
     * @param {number[]} rectangle The rectangle [x, y, w, h] to outline/fill.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._drawAppearance = function (graphics, parameter, rectangle) {
        var graphicsPath = new PdfPath();
        graphicsPath.addRectangle({ x: rectangle[0], y: rectangle[1], width: rectangle[2], height: rectangle[3] });
        if (this._dictionary.has('BE')) {
            var dictionary = this._dictionary.get('BE');
            if (dictionary && dictionary.has('I')) {
                var value = dictionary.get('I');
                var radius = value === 1 ? 4 : 9;
                this._drawCloudStyle(graphics, parameter.foreBrush, parameter.borderPen, radius, 0.833, graphicsPath._points, true);
            }
        }
    };
    /**
     * Draws the free text annotation: either the filled rectangle or the text string using the specified font, brushes, and bounds.
     *
     * @private
     * @param {PdfGraphics} g The graphics context.
     * @param {_PaintParameter} parameter Paint parameters containing pens/brushes/bounds.
     * @param {string} text The text to render; empty to draw only background/border.
     * @param {PdfFont} font The font to use for text rendering.
     * @param {number[]} rectangle The drawing rectangle [x, y, w, h].
     * @param {boolean} isSkipDrawRectangle When true, skips drawing the rectangle and draws only text.
     * @param {PdfTextAlignment} alignment The text alignment inside the rectangle.
     * @param {boolean} isRotation When true, the text is drawn with rotation transforms applied.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._drawFreeTextAnnotation = function (g, parameter, text, font, rectangle, isSkipDrawRectangle, alignment, isRotation) {
        if (!isSkipDrawRectangle) {
            g.drawRectangle({ x: rectangle[0], y: rectangle[1], width: rectangle[2],
                height: rectangle[3] }, parameter.borderPen, parameter.foreBrush);
        }
        else {
            var format = new PdfStringFormat();
            format.lineAlignment = PdfVerticalAlignment.top;
            format.alignment = alignment;
            format.lineSpacing = 0;
            format.lineLimit = false;
            if (isRotation) {
                g.drawString(text, font, parameter.bounds, parameter.backBrush, format);
            }
            else {
                g.drawString(text, font, { x: rectangle[0], y: rectangle[1], width: rectangle[2],
                    height: rectangle[3] }, parameter.backBrush, format);
            }
        }
    };
    /**
     * Retrieves callout line points from the CL entry and converts them into page coordinates.
     *
     * @private
     * @returns {Array<Point>} The callout polyline points as page coordinates.
     */
    PdfFreeTextAnnotation.prototype._getCalloutLinePoints = function () {
        if (this._dictionary.has('CL')) {
            var calloutLinepoints = this._dictionary.getArray('CL');
            if (calloutLinepoints) {
                this._calloutLines = [];
                for (var i = 0; i < calloutLinepoints.length; i += 2) {
                    var point = { x: calloutLinepoints[i], y: this._page.size.height - calloutLinepoints[i + 1] };
                    this._calloutLines.push(point);
                }
            }
        }
        return this._calloutLines;
    };
    /**
     * Computes the appearance bounding box from callout lines and the text box and returns it as [x, y, w, h].
     *
     * @private
     * @returns {number[]} The appearance bounds [x, y, width, height].
     */
    PdfFreeTextAnnotation.prototype._obtainAppearanceBounds = function () {
        var bounds = [0, 0, 0, 0];
        if (this.calloutLines && this._calloutLines.length > 0) {
            var path = new PdfPath();
            var pointArray = [];
            var length_2 = this._calloutLines.length === 2 ? 2 : 3;
            for (var i = 0; i < length_2; i++) {
                pointArray.push({ x: 0, y: 0 });
            }
            if (this._calloutLines.length >= 2) {
                this._obtainCallOutsNative();
                for (var i = 0; i < this._calloutLines.length && i < 3; i++) {
                    pointArray[i] = {
                        x: this._calloutsClone[i][0],
                        y: this._calloutsClone[i][1]
                    };
                }
            }
            if (pointArray.length > 0) {
                if (this.lineEndingStyle !== PdfLineEndingStyle.none) {
                    this._expandAppearance(pointArray);
                }
                path._addLines(pointArray);
            }
            bounds = path._getBounds();
            var margin = void 0;
            if (this._page && this._page._pageSettings && this._page._pageSettings.margins) {
                margin = this._page._pageSettings.margins;
            }
            if (this._page && this._page._isNew) {
                path.addRectangle({ x: (this.bounds.x + this._cropBoxValueX + margin.left) - 2,
                    y: ((this._page.size.height + this._cropBoxValueY) - (this.bounds.y + this.bounds.height + margin.top)) - 2,
                    width: this.bounds.width + (2 * 2),
                    height: this.bounds.height + (2 * 2) });
            }
            else {
                path.addRectangle({ x: (this.bounds.x + this._cropBoxValueX) - 2,
                    y: ((this._page.size.height + this._cropBoxValueY) - (this.bounds.y + this.bounds.height)) - 2,
                    width: this.bounds.width + (2 * 2),
                    height: this.bounds.height + (2 * 2) });
            }
            bounds = path._getBounds();
        }
        else {
            if (this._page) {
                if (this._page._isNew) {
                    var margins = this._page._pageSettings.margins;
                    bounds = [this.bounds.x + margins.left,
                        (this._page.size.height - (this.bounds.y + this.bounds.height + margins.top)),
                        this.bounds.width,
                        this.bounds.height];
                }
                else {
                    bounds = [this.bounds.x + this._cropBoxValueX,
                        ((this._page.size.height + this._cropBoxValueY) - (this.bounds.y + this.bounds.height)),
                        this.bounds.width,
                        this.bounds.height];
                }
            }
        }
        return bounds;
    };
    /**
     * Converts callout line points to native appearance coordinates considering margins and Crop/MediaBox offsets.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._obtainCallOutsNative = function () {
        if (this.calloutLines && this._calloutLines.length > 0) {
            var size = this._page.size;
            var margin = void 0;
            if (this._page && this._page._pageSettings && this._page._pageSettings.margins) {
                margin = this._page._pageSettings.margins;
            }
            this._calloutsClone = [];
            for (var i = 0; i < this._calloutLines.length; i++) {
                this._calloutsClone.push([this._calloutLines[i].x + (margin ? margin.left : 0) + this._cropBoxValueX,
                    (size.height + this._cropBoxValueY) - (this._calloutLines[i].y + (margin ? margin.top : 0))]);
            }
        }
    };
    /**
     * Returns the two callout line endpoints as a flat [x1, y1, x2, y2] array in native coordinates.
     *
     * @private
     * @returns {number[]} The endpoints in appearance coordinates.
     */
    PdfFreeTextAnnotation.prototype._obtainLinePoints = function () {
        var pageHeight = this._page.size.height;
        return [this.calloutLines[1].x + this._cropBoxValueX,
            (pageHeight + this._cropBoxValueY) - this.calloutLines[1].y,
            this.calloutLines[0].x + this._cropBoxValueX,
            (pageHeight + this._cropBoxValueY) - this.calloutLines[0].y];
    };
    /**
     * Reads the LE entry and returns the mapped PdfLineEndingStyle for the callout line.
     *
     * @private
     * @returns {PdfLineEndingStyle} The resolved line ending style.
     */
    PdfFreeTextAnnotation.prototype._obtainLineEndingStyle = function () {
        var lineEndingStyle;
        if (this._dictionary.has('LE')) {
            var endingStyle = this._dictionary.get('LE'); // eslint-disable-line
            if (endingStyle instanceof _PdfName) {
                endingStyle = endingStyle.name;
            }
            lineEndingStyle = _mapLineEndingStyle(endingStyle);
        }
        return lineEndingStyle;
    };
    /**
     * Obtains the display text from Contents or RC backup, caching it in the instance when found.
     *
     * @private
     * @returns {string} The resolved text content (may be empty).
     */
    PdfFreeTextAnnotation.prototype._obtainText = function () {
        var text = '';
        var isContent = this._dictionary.has('Contents');
        if (isContent) {
            var markUpText = this._dictionary.get('Contents');
            if (markUpText) {
                text = markUpText;
            }
            if (text && text !== '') {
                this._text = text;
            }
            return text;
        }
        else if (this._dictionary.has('RC') && !isContent && text === null) {
            text = this._rcText;
            return text;
        }
        return text;
    };
    /**
     * Determines the text alignment from Q, RC, or DS entries and returns the resolved PdfTextAlignment.
     *
     * @private
     * @returns {PdfTextAlignment} The resolved text alignment.
     */
    PdfFreeTextAnnotation.prototype._obtainTextAlignment = function () {
        var textAlignment = PdfTextAlignment.left;
        var hasAlignment;
        if (this._dictionary.has('Q')) {
            var value = this._dictionary.get('Q');
            if (typeof value !== 'undefined') {
                textAlignment = value;
                hasAlignment = true;
            }
        }
        else if (this._dictionary.has('RC')) {
            if (this._parsedXMLData.length > 0 && this._parsedXMLData[1]) {
                var rcAlignment = this._parsedXMLData[1];
                textAlignment = rcAlignment;
                hasAlignment = true;
            }
        }
        if (!hasAlignment && this._dictionary.has('DS')) {
            var value = this._dictionary.get('DS');
            var collections = value.split(';');
            collections.forEach(function (collectionItem) {
                if (collectionItem.indexOf('text-align') !== -1) {
                    switch (collectionItem) {
                        case 'left':
                            textAlignment = PdfTextAlignment.left;
                            break;
                        case 'right':
                            textAlignment = PdfTextAlignment.right;
                            break;
                        case 'center':
                            textAlignment = PdfTextAlignment.center;
                            break;
                        case 'justify':
                            textAlignment = PdfTextAlignment.justify;
                            break;
                    }
                }
            });
        }
        return textAlignment;
    };
    /**
     * Resolves the border/text color from DA/MK/BC when loaded or from the configured border color when creating.
     *
     * @private
     * @returns {PdfColor} The resolved RGB color.
     */
    PdfFreeTextAnnotation.prototype._obtainColor = function () {
        var color;
        if (this._isLoaded) {
            if (this._dictionary.has('DA')) {
                var entry = this._dictionary.get('DA');
                if (Array.isArray(entry) && entry.length > 0) {
                    color = { r: entry[0], g: entry[1], b: entry[2] };
                }
                else if (typeof entry === 'string') {
                    this._da = new _PdfDefaultAppearance(entry);
                    color = this._da.color;
                }
            }
            else if (this._dictionary.has('MK')) {
                var mkDict = this._mkDictionary;
                if (mkDict && mkDict.has('BC')) {
                    color = _parseColor(mkDict.getArray('BC'));
                }
            }
            else {
                color = { r: 0, g: 0, b: 0 };
            }
        }
        else {
            color = this._borderColor ? this._borderColor : { r: 0, g: 0, b: 0 };
        }
        return color;
    };
    /**
     * Expands the first callout point outward to accommodate end styles and border thickness relative to the text box.
     *
     * @private
     * @param {Point[]} pointArray The callout points to adjust (mutated in place).
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._expandAppearance = function (pointArray) {
        var pointY = pointArray[0].y;
        var pointX = pointArray[0].x;
        if (!this._isLoaded) {
            pointY = this._page.size.height - pointY;
        }
        if (pointY > this.bounds.y) {
            if (this.lineEndingStyle !== PdfLineEndingStyle.openArrow) {
                pointArray[0].y -= (this.border.width * 11);
            }
        }
        else {
            pointArray[0].y += (this.border.width * 11);
        }
        if (pointX <= this.bounds.x) {
            pointArray[0].x -= (this.border.width * 11);
        }
        else {
            pointArray[0].x += (this.border.width * 11);
        }
    };
    /**
     * Draws the callout polyline path derived from the callout points using the specified border pen.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context.
     * @param {PdfPen} borderPen The pen used to draw the callout path.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._drawCallOuts = function (graphics, borderPen) {
        var path = new PdfPath();
        var pointArray = [];
        var length = this._calloutLines.length === 2 ? 2 : 3;
        for (var i = 0; i < length; i++) {
            pointArray.push({ x: 0, y: 0 });
        }
        if (this._calloutLines.length >= 2) {
            this._obtainCallOutsNative();
            for (var i = 0; i < this._calloutLines.length && i < 3; i++) {
                pointArray[i] = {
                    x: this._calloutsClone[i][0],
                    y: -this._calloutsClone[i][1]
                };
            }
        }
        if (pointArray.length > 0) {
            path._addLines(pointArray);
        }
        graphics.drawPath(path, borderPen);
    };
    /**
     * Persists the free text dictionary entries (Contents, Q, Subj/IT, DS, DA, CL, Rect) based on current state and intent.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._saveFreeTextDictionary = function () {
        if ((typeof this.font === 'undefined' || this.font === null) || (!this._isLoaded && this.font.size === 1)) {
            this.font = this._markUpFont;
        }
        if (typeof this.text === 'string' && this.text !== null) {
            this._dictionary.update('Contents', this.text);
        }
        if (this._isLoaded) {
            this._textAlignment = this.textAlignment;
        }
        this._dictionary.update('Q', this._textAlignment);
        if ((typeof this.subject === 'undefined' || this.subject === 'null')
            && this.annotationIntent === PdfAnnotationIntent.none &&
            (!this._calloutLines || (this._calloutLines && this._calloutLines.length === 0))) {
            this._dictionary.update('Subj', 'Text Box');
        }
        else {
            if ((this._calloutLines && this._calloutLines.length >= 2) &&
                this.annotationIntent === PdfAnnotationIntent.none) {
                this._annotationIntent = PdfAnnotationIntent.freeTextCallout;
            }
            this._dictionary.update('IT', _PdfName.get(this._obtainAnnotationIntent(this._annotationIntent)));
        }
        this._updateStyle(this.font, this.textMarkUpColor, this._textAlignment);
        this._dictionary.update('DA', this._getBorderColorString(this.borderColor ? this._borderColor : { r: 0, g: 0, b: 0 }));
        if (this._calloutLines && this._calloutLines.length >= 2) {
            var pageHeight = this._page.size.height;
            var lines = [];
            for (var i = 0; i < this._calloutLines.length && i < 3; i++) {
                lines.push(this._calloutLines[i].x + this._cropBoxValueX);
                lines.push((pageHeight + this._cropBoxValueY) - this._calloutLines[i].y);
            }
            this._dictionary.update('CL', lines);
        }
        if (this._setAppearance) {
            var rect = this._obtainAppearanceBounds();
            this._dictionary.update('Rect', [rect[0], rect[1], rect[0] + rect[2], rect[1] + rect[3]]);
        }
    };
    /**
     * Escapes XML sensitive characters (&, <, >) in the provided markup text for RC storage.
     *
     * @private
     * @param {string} markupText The raw markup text to escape.
     * @returns {string} The escaped XML safe string.
     */
    PdfFreeTextAnnotation.prototype._getXmlFormattedString = function (markupText) {
        markupText = markupText.replace('&', '&amp;');
        markupText = markupText.replace('<', '&lt;');
        markupText = markupText.replace('>', '&gt;');
        return markupText;
    };
    /**
     * Parses RC XHTML content to extract style directives, resolve fonts/brushes/alignment, and populate the parsed XML font collection.
     *
     * @private
     * @param {string} rcContent The RC XHTML content to parse.
     * @returns {any[]} A collection of [font, alignment, namespaceURI, brush] entries.
     */
    PdfFreeTextAnnotation.prototype._parseMarkupLanguageData = function (rcContent) {
        var _this = this;
        var fontStyle = PdfFontStyle.regular;
        var fontCollection = []; // eslint-disable-line
        var brush = null;
        var fontName = '';
        var content = rcContent;
        var contentText = this._dictionary.has('Contents') ? this._dictionary.get('Contents') : '';
        var hasSymbol = false;
        var xdocument; // eslint-disable-line
        hasSymbol = contentText.split('').some(function (char) { return _this._isSymbol(char); });
        if (!hasSymbol) {
            if (content !== null && typeof content !== 'undefined') {
                xdocument = (new DOMParser()).parseFromString(content, 'text/xml');
                var root = xdocument.documentElement;
                var nameSpaceURI = (root && root.namespaceURI) || '';
                if (root) {
                    var styleMap = this._collectStyles(root);
                    var input = void 0;
                    if (styleMap.size > 0) {
                        input = this._extractStylesToInput(styleMap);
                        var fontDetails_1 = this._getFontDetails(input, this.font.size, this.textAlignment, fontStyle, brush); // eslint-disable-line
                        var _a = this._updateFontProperties(fontDetails_1, fontName, fontStyle, brush), updatedFontName_1 = _a.fontName, updatedFontStyle_1 = _a.fontStyle, updatedBrush_1 = _a.brush;
                        var obtainFont_1 = _mapFont(updatedFontName_1, this.font._size, updatedFontStyle_1, this);
                        fontCollection = this._fontCollection(fontCollection, obtainFont_1, nameSpaceURI, this._textAlignment, updatedBrush_1);
                    }
                    else if (styleMap.size === 0 && this._dictionary.has('DS')) {
                        var stringValue = this._dictionary.get('DS');
                        input = stringValue.split(';') || [];
                    }
                    fontStyle = this.font.style;
                    var fontDetails = this._getFontDetails(input, this.font.size, this.textAlignment, fontStyle, brush); // eslint-disable-line
                    var _b = this._updateFontProperties(fontDetails, fontName, fontStyle, brush), updatedFontName = _b.fontName, updatedFontStyle = _b.fontStyle, updatedBrush = _b.brush;
                    var obtainFont = _mapFont(updatedFontName, this.font._size, updatedFontStyle, this);
                    this._font = obtainFont;
                    fontCollection = this._fontCollection(fontCollection, obtainFont, nameSpaceURI, this._textAlignment, updatedBrush);
                }
            }
        }
        this._parsedXMLData = fontCollection;
        return fontCollection;
    };
    /**
     * Traverses the XHTML DOM and collects inline style attributes per tag into a style map.
     *
     * @private
     * @param {HTMLElement} root The root element to traverse.
     * @param {Map<string, string[]>} [styleMap] Optional existing map to append into.
     * @returns {Map<string, string[]>} The populated map of tagName → style declarations.
     */
    PdfFreeTextAnnotation.prototype._collectStyles = function (root, styleMap) {
        if (styleMap === void 0) { styleMap = new Map(); }
        if (!root) {
            return styleMap;
        }
        var tagName = root.tagName.toLowerCase();
        var styleAttribute = root.getAttribute('style');
        if (styleAttribute) {
            var styleArray = styleAttribute.split(';').map(function (s) { return s.trim(); }).filter(Boolean); // eslint-disable-line
            styleMap.set(tagName, styleArray);
        }
        var childNode = root.firstElementChild;
        while (childNode) {
            this._collectStyles(childNode, styleMap);
            childNode = childNode.nextElementSibling;
        }
        return styleMap;
    };
    /**
     * Flattens the collected style map into a string array of CSS property declarations.
     *
     * @private
     * @param {Map<string, string[]>} styleMap The map of style declarations per tag.
     * @returns {string[]} The flattened CSS declarations.
     */
    PdfFreeTextAnnotation.prototype._extractStylesToInput = function (styleMap) {
        var input = [];
        styleMap.forEach(function (styleArray) {
            input.push.apply(input, styleArray);
        });
        return input;
    };
    /**
     * Returns true if the character is in common symbol Unicode ranges used for special glyphs.
     *
     * @private
     * @param {string} char The character to test.
     * @returns {boolean} True if the character is a symbol glyph; otherwise, false.
     */
    PdfFreeTextAnnotation.prototype._isSymbol = function (char) {
        var code = char.charCodeAt(0);
        if (char === '_' || char === '+' || char === '-' || char === '*' || char === '=') {
            return false;
        }
        return ((code >= 0x20A0 && code <= 0x20CF) ||
            (code >= 0x2200 && code <= 0x22FF) ||
            (code >= 0x2A00 && code <= 0x2AFF) ||
            (code >= 0x2100 && code <= 0x214F) ||
            (code >= 0x2300 && code <= 0x23FF) ||
            (code === 0x2B50));
    };
    /**
     * Applies parsed style properties to update font name/size/style, text alignment, brush, and spacerun content, returning the updated values.
     *
     * @private
     * @param {Map<string, any>} fontDetails The parsed font/style details map.
     * @param {string} fontName The current font family name.
     * @param {PdfFontStyle} fontStyle The current font style flags.
     * @param {PdfBrush} brush The current text brush (may be updated).
     * @returns {{ fontName: string, fontStyle: PdfFontStyle, brush: PdfBrush }} The updated font properties.
     */
    PdfFreeTextAnnotation.prototype._updateFontProperties = function (fontDetails, fontName, fontStyle, brush) {
        var _this = this;
        var styleValue;
        var next;
        fontDetails.forEach(function (value, property) {
            switch (property) {
                case 'font-family':
                    fontName = value;
                    break;
                case 'font-size':
                    _this.font._size = parseFloat(value);
                    break;
                case 'font-style':
                case 'font-weight':
                case 'text-decoration':
                    styleValue = parseFloat(value);
                    next = _this._getStyles(styleValue);
                    fontStyle = _this._maxStyle(fontStyle, next);
                    break;
                case 'text-align':
                    _this._textAlignment = _this._parseTextAlignment(value);
                    break;
                case 'color':
                    brush = value;
                    break;
                case 'xfa-spacerun':
                    _this._rcText = value;
                    break;
            }
        });
        return { fontName: fontName, fontStyle: fontStyle, brush: brush };
    };
    /**
     * Converts a bitmask value into a PdfFontStyle subset with regular as fallback.
     *
     * @private
     * @param {number} value The bitmask to convert.
     * @returns {PdfFontStyle} The mapped PdfFontStyle.
     */
    PdfFreeTextAnnotation.prototype._getStyles = function (value) {
        var allowedMask = PdfFontStyle.bold | PdfFontStyle.italic | PdfFontStyle.underline | PdfFontStyle.strikeout;
        var masked = value & allowedMask;
        return (masked === 0 ? PdfFontStyle.regular : masked);
    };
    /**
     * Returns the maximum PdfFontStyle value between two style flags.
     *
     * @private
     * @param {PdfFontStyle} a The first style flag.
     * @param {PdfFontStyle} b The second style flag.
     * @returns {PdfFontStyle} The dominant style flag.
     */
    PdfFreeTextAnnotation.prototype._maxStyle = function (a, b) {
        return (a >= b ? a : b);
    };
    /**
     * Parses a numeric alignment value and returns the corresponding PdfTextAlignment enum.
     *
     * @private
     * @param {string} value The numeric alignment value as a string.
     * @returns {PdfTextAlignment} The parsed alignment (left/center/right/justify).
     */
    PdfFreeTextAnnotation.prototype._parseTextAlignment = function (value) {
        var alignmentValue = parseFloat(value);
        switch (alignmentValue) {
            case 0: return PdfTextAlignment.left;
            case 1: return PdfTextAlignment.center;
            case 2: return PdfTextAlignment.right;
            case 3: return PdfTextAlignment.justify;
            default: return PdfTextAlignment.left;
        }
    };
    /**
     * Parses a list of CSS declarations into effective font details, color brush, and alignment, returning them in a detail map.
     *
     * @private
     * @param {string[]} input The CSS declarations.
     * @param {number} fontSize The current font size used as fallback.
     * @param {PdfTextAlignment} textAlignment The current text alignment used as fallback.
     * @param {PdfFontStyle} fontStyle The current font style flags used as fallback.
     * @param {PdfBrush} brush The current brush used as fallback.
     * @returns {Map<string, any>} A map containing resolved font properties and brush.
     */
    PdfFreeTextAnnotation.prototype._getFontDetails = function (input, fontSize, textAlignment, fontStyle, brush) {
        var _this = this;
        var fontDetails = new Map(); // eslint-disable-line
        input.forEach(function (element) {
            var _a = element.split(':').map(function (item) { return item.trim(); }), property = _a[0], value = _a[1];
            if (property && value) {
                switch (property.toLowerCase()) {
                    case 'font':
                        _this._parseFont(value, fontDetails);
                        break;
                    case 'font-size':
                        fontSize = _this._parseFontSize(value);
                        fontDetails.set('font-size', fontSize);
                        break;
                    case 'font-weight':
                        fontStyle = _this._parseFontWeight(value, fontStyle);
                        fontDetails.set('font-weight', fontStyle);
                        break;
                    case 'font-family':
                        fontDetails.set('font-family', _this._parseFontFamily(value));
                        break;
                    case 'color':
                        brush = new PdfBrush(_this._rgbStringToArray(value));
                        fontDetails.set('color', brush);
                        break;
                    case 'font-style':
                        fontStyle = _this._parseFontStyle(value, fontStyle);
                        fontDetails.set('font-style', fontStyle);
                        break;
                    case 'text-decoration':
                        fontStyle = _this._parseTextDecoration(value, fontStyle);
                        fontDetails.set('text-decoration', fontStyle);
                        break;
                    case 'text-align':
                        textAlignment = _this._parseTextAlign(value);
                        fontDetails.set('text-align', textAlignment);
                        break;
                    case 'xfa-spacerun':
                        _this._rcText = value.length > 1 && value.includes('yes') ? _this._rcText + ' ' : _this._rcText;
                        fontDetails.set('xfa-spacerun', _this._rcText);
                        break;
                }
            }
        });
        return fontDetails;
    };
    /**
     * Parses a composite CSS font shorthand into family and size, updating the font details map.
     *
     * @private
     * @param {string} value The CSS font shorthand value.
     * @param {Map<string, any>} fontDetails The map to receive parsed properties.
     * @returns {void} No return value.
     */
    PdfFreeTextAnnotation.prototype._parseFont = function (value, fontDetails) {
        var fontParts = value.split(' ').map(function (item) { return item.trim(); });
        var fontName = '';
        fontParts.forEach(function (part) {
            if (part && !part.endsWith('pt')) {
                fontName += part + ' ';
            }
            else if (part.endsWith('pt')) {
                fontDetails.set('font-size', parseFloat(part.replace('pt', '').replace(',', '.').trim()));
            }
        });
        fontDetails.set('font-family', fontName.trim().replace(/['",]/g, ''));
    };
    /**
     * Parses a CSS point size string (e.g., '12pt') into a numeric value.
     *
     * @private
     * @param {string} value The CSS point size string.
     * @returns {number} The parsed size in points.
     */
    PdfFreeTextAnnotation.prototype._parseFontSize = function (value) {
        if (value.endsWith('pt')) {
            return parseFloat(value.replace('pt', '').replace(',', '.').trim());
        }
        return 0;
    };
    /**
     * Updates the PdfFontStyle with bold when the font weight property indicates bold.
     *
     * @private
     * @param {string} value The CSS font weight value.
     * @param {PdfFontStyle} fontStyle The current font style flags.
     * @returns {PdfFontStyle} The updated font style flags.
     */
    PdfFreeTextAnnotation.prototype._parseFontWeight = function (value, fontStyle) {
        if (value.includes('bold')) {
            fontStyle |= PdfFontStyle.bold;
        }
        return fontStyle;
    };
    /**
     * Normalizes a CSS font family string by trimming surrounding quotes.
     *
     * @private
     * @param {string} value The CSS font-family value.
     * @returns {string} The normalized font family name.
     */
    PdfFreeTextAnnotation.prototype._parseFontFamily = function (value) {
        return value.replace(/^'+|'+$/g, '').trim();
    };
    /**
     * Applies font style flags (regular/underline/strikeout/italic/bold) based on the CSS font style value.
     *
     * @private
     * @param {string} value The CSS font style value.
     * @param {PdfFontStyle} fontStyle The current font style flags.
     * @returns {PdfFontStyle} The updated font style flags.
     */
    PdfFreeTextAnnotation.prototype._parseFontStyle = function (value, fontStyle) {
        if (value.includes('normal') || value.includes('regular')) {
            fontStyle |= PdfFontStyle.regular;
        }
        if (value.includes('underline')) {
            fontStyle |= PdfFontStyle.underline;
        }
        if (value.includes('strikeout')) {
            fontStyle |= PdfFontStyle.strikeout;
        }
        if (value.includes('italic')) {
            fontStyle |= PdfFontStyle.italic;
        }
        if (value.includes('bold')) {
            fontStyle |= PdfFontStyle.bold;
        }
        return fontStyle;
    };
    /**
     * Applies underline/strikeout flags according to the CSS text decoration value.
     *
     * @private
     * @param {string} value The CSS text decoration value.
     * @param {PdfFontStyle} fontStyle The current font style flags.
     * @returns {PdfFontStyle} The updated font style flags.
     */
    PdfFreeTextAnnotation.prototype._parseTextDecoration = function (value, fontStyle) {
        if (value.includes('word') || value.includes('underline')) {
            fontStyle |= PdfFontStyle.underline;
        }
        if (value.includes('line-through')) {
            fontStyle |= PdfFontStyle.strikeout;
        }
        return fontStyle;
    };
    /**
     * Parses a CSS text align string into a PdfTextAlignment enum value.
     *
     * @private
     * @param {string} value The CSS text align value.
     * @returns {PdfTextAlignment} The parsed alignment enum.
     */
    PdfFreeTextAnnotation.prototype._parseTextAlign = function (value) {
        switch (value.trim().toLowerCase()) {
            case 'left': return PdfTextAlignment.left;
            case 'right': return PdfTextAlignment.right;
            case 'center': return PdfTextAlignment.center;
            case 'justify': return PdfTextAlignment.justify;
            default: return PdfTextAlignment.left;
        }
    };
    /**
     * Converts a CSS color string to a PdfColor object or throws on invalid format.
     *
     * @private
     * @param {string} rgbString The CSS color string (rgb(r,g,b) or #RRGGBB).
     * @returns {PdfColor} The parsed RGB color.
     */
    PdfFreeTextAnnotation.prototype._rgbStringToArray = function (rgbString) {
        var rgbRegex = /^rgb\((\d+),\s*(\d+),\s*(\d+)\)$/;
        var rgbMatch = rgbString.match(rgbRegex);
        if (rgbMatch) {
            var r = parseInt(rgbMatch[1], 10);
            var g = parseInt(rgbMatch[2], 10);
            var b = parseInt(rgbMatch[3], 10);
            return { r: r, g: g, b: b };
        }
        var hexRegex = /^#([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})([0-9A-Fa-f]{2})$/;
        var hexMatch = rgbString.match(hexRegex);
        if (hexMatch) {
            var r = parseInt(hexMatch[1], 16);
            var g = parseInt(hexMatch[2], 16);
            var b = parseInt(hexMatch[3], 16);
            return { r: r, g: g, b: b };
        }
        throw new Error('Invalid RGB string format');
    };
    /**
     * Appends the resolved font, alignment, namespace URI, and brush to the running parsed XML font collection and returns it.
     *
     * @private
     * @param {any[]} fontCollection The existing collection to append to.
     * @param {PdfFont} font The resolved font instance.
     * @param {string} nameSpaceUri The namespace URI found in RC.
     * @param {PdfTextAlignment} alignment The text alignment value.
     * @param {PdfBrush} brush The resolved brush.
     * @returns {any[]} The updated font collection.
     */
    PdfFreeTextAnnotation.prototype._fontCollection = function (fontCollection, font, nameSpaceUri, alignment, brush) {
        return fontCollection.concat([font, alignment, nameSpaceUri, brush]);
    };
    return PdfFreeTextAnnotation;
}(PdfComment));
export { PdfFreeTextAnnotation };
/**
 * `PdfRedactionAnnotation` class represents the redaction annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Create a new redaction annotation
 * const annotation: PdfRedactionAnnotation = new PdfRedactionAnnotation({x: 50, y: 100, width: 100, height: 50});
 * // Add annotation to the page
 * page.annotations.add(annotation);
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfRedactionAnnotation = /** @class */ (function (_super) {
    __extends(PdfRedactionAnnotation, _super);
    function PdfRedactionAnnotation(bounds, properties) {
        var _this = _super.call(this) || this;
        _this._textAlignment = PdfTextAlignment.left;
        _this._dictionary = new _PdfDictionary();
        _this._dictionary.update('Type', _PdfName.get('Annot'));
        _this._dictionary.update('Subtype', _PdfName.get('Redact'));
        if (bounds) {
            _this.bounds = bounds;
            if (properties) {
                if (_isNullOrUndefined(properties.borderColor)) {
                    _this.borderColor = properties.borderColor;
                }
                if (_isNullOrUndefined(properties.repeatText)) {
                    _this.repeatText = properties.repeatText;
                }
                if (_isNullOrUndefined(properties.overlayText)) {
                    _this.overlayText = properties.overlayText;
                }
                if (properties.font) {
                    _this.font = properties.font;
                }
                if (_isNullOrUndefined(properties.textColor)) {
                    _this.textColor = properties.textColor;
                }
                if (_isNullOrUndefined(properties.appearanceFillColor)) {
                    _this.appearanceFillColor = properties.appearanceFillColor;
                }
                if (_isNullOrUndefined(properties.innerColor)) {
                    _this.innerColor = properties.innerColor;
                }
                if (_isNullOrUndefined(properties.textAlignment)) {
                    _this.textAlignment = properties.textAlignment;
                }
                if (_isNullOrUndefined(properties.text)) {
                    _this.text = properties.text;
                }
                if (_isNullOrUndefined(properties.author)) {
                    _this.author = properties.author;
                }
                if (_isNullOrUndefined(properties.subject)) {
                    _this.subject = properties.subject;
                }
                if (_isNullOrUndefined(properties.opacity)) {
                    _this.opacity = properties.opacity;
                }
                if (_isNullOrUndefined(properties.boundsCollection) &&
                    Array.isArray(properties.boundsCollection) && properties.boundsCollection.length > 0) {
                    _this.boundsCollection = properties.boundsCollection;
                }
            }
        }
        _this._type = _PdfAnnotationType.redactionAnnotation;
        return _this;
    }
    Object.defineProperty(PdfRedactionAnnotation.prototype, "repeatText", {
        /**
         * Gets the boolean flag indicating whether annotation has repeat text or not.
         *
         * @returns {boolean} repeat text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the boolean flag indicating whether annotation has repeat text or not.
         * let repeatText: boolean = annotation. repeatText;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._repeat === 'undefined' && this._dictionary.has('Repeat')) {
                this._repeat = this._dictionary.get('Repeat');
            }
            return this._repeat;
        },
        /**
         * Sets the boolean flag indicating whether annotation has repeat text or not.
         *
         * @param {boolean} value repeat text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the boolean flag indicating whether annotation has repeat text or not.
         * annotation.repeatText = false;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._repeat) {
                this._repeat = value;
                if (this._dictionary) {
                    this._dictionary.update('Repeat', value);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "textAlignment", {
        /**
         * Gets the text alignment of the annotation.
         *
         * @returns {PdfTextAlignment} Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the text alignment of the annotation.
         * let textAlignment: PdfTextAlignment = annotation.textAlignment;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._dictionary.has('Q')) {
                this._textAlignment = this._dictionary.get('Q');
            }
            return this._textAlignment;
        },
        /**
         * Sets the text alignment of the annotation.
         *
         * @param {PdfTextAlignment} value Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the text alignment of the annotation.
         * annotation.textAlignment = PdfTextAlignment.justify;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value !== 'undefined' && value !== null && this._textAlignment !== value) {
                this._dictionary.update('Q', value);
            }
            this._textAlignment = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "textColor", {
        /**
         * Gets the text color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the text color of the annotation.
         * let textColor : PdfColor = annotation.textColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._textColor === 'undefined' && this._dictionary.has('C')) {
                this._textColor = _parseColor(this._dictionary.getArray('C'));
            }
            return this._textColor;
        },
        /**
         * Sets the text color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the text color of the annotation.
         * annotation.textColor = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                var extColor = this.textColor;
                if (!this._isLoaded || typeof extColor === 'undefined' || (extColor.r !== value.r || extColor.g !== value.g || extColor.b !== value.b)) {
                    this._textColor = value;
                    this._dictionary.update('C', [Number.parseFloat((value.r / 255).toFixed(3)),
                        Number.parseFloat((value.g / 255).toFixed(3)),
                        Number.parseFloat((value.b / 255).toFixed(3))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "borderColor", {
        /**
         * Gets the border color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the border color of the annotation.
         * let borderColor: PdfColor = annotation.borderColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._borderColor === 'undefined' && this._dictionary.has('OC')) {
                this._borderColor = _parseColor(this._dictionary.getArray('OC'));
            }
            return this._borderColor;
        },
        /**
         * Sets the border color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the border color of the annotation.
         * annotation.borderColor = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                var extColor = this.borderColor;
                if (!this._isLoaded || typeof extColor === 'undefined' || (extColor.r !== value.r || extColor.g !== value.g || extColor.b !== value.b)) {
                    this._borderColor = value;
                    this._dictionary.update('OC', [Number.parseFloat((value.r / 255).toFixed(3)),
                        Number.parseFloat((value.g / 255).toFixed(3)),
                        Number.parseFloat((value.b / 255).toFixed(3))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "overlayText", {
        /**
         * Gets the overlay text of the annotation.
         *
         * @returns {string} overlay text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the overlay text of the annotation.
         * let overlayText: string = annotation.overlayText;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._overlayText === 'undefined' && this._dictionary.has('OverlayText')) {
                this._overlayText = this._dictionary.get('OverlayText');
            }
            return this._overlayText;
        },
        /**
         * Sets the overlay text of the annotation.
         *
         * @param {string} value overlay text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the overlay text of the annotation.
         * annotation.overlayText = 'syncfusion';
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string') {
                this._dictionary.update('OverlayText', value);
                this._overlayText = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "font", {
        /**
         * Gets the font of the annotation.
         *
         * @returns {PdfFont} font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the font of the annotation.
         * let font: PdfFont = annotation.font;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (!this._font) {
                this._font = this._obtainFont();
            }
            return this._font;
        },
        /**
         * Sets the font of the annotation.
         *
         * @param {PdfFont} value font.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the font of the annotation.
         * annotation.font = document.embedFont(PdfFontFamily.helvetica, 10, PdfFontStyle.regular);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._font = value;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "appearanceFillColor", {
        /**
         * Gets the appearance fill color of the annotation.
         *
         * @returns {PdfColor} R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the appearance fill color of the annotation.
         * let appearanceFillColor: PdfColor = annotation.appearanceFillColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if ((this._appearanceFillColor === null || typeof this._appearanceFillColor === 'undefined') &&
                this._dictionary.has('AFC')) {
                var fillColor = this._dictionary.getArray('AFC');
                if (fillColor) {
                    this._appearanceFillColor = _parseColor(fillColor);
                }
            }
            return this._appearanceFillColor;
        },
        /**
         * Sets the appearance fill color of the annotation.
         *
         * @param {PdfColor} value R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the appearance fill color of the annotation.
         * annotation.appearanceFillColor = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value) {
                var extColor = this.appearanceFillColor;
                if (!this._isLoaded || typeof extColor === 'undefined' || (extColor.r !== value.r ||
                    extColor.g !== value.g || extColor.b !== value.b)) {
                    this._appearanceFillColor = value;
                    this._dictionary.update('AFC', [Number.parseFloat((value.r / 255).toFixed(3)),
                        Number.parseFloat((value.g / 255).toFixed(3)),
                        Number.parseFloat((value.b / 255).toFixed(3))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRedactionAnnotation.prototype, "boundsCollection", {
        /**
         * Gets the bounds collection of the annotation.
         *
         * @returns {Array<Rectangle>} bounds collection.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as  PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Gets the bounds collection of the annotation.
         * let boundsCollection: Array<Rectangle> = annotation.boundsCollection;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                var collection = [];
                if (this._dictionary.has('QuadPoints')) {
                    var points = this._dictionary.getArray('QuadPoints');
                    if (points && points.length > 0) {
                        var cropOrMediaBox = this._getMediaOrCropBox(this._page);
                        var cropX = cropOrMediaBox && cropOrMediaBox.length > 0 ? cropOrMediaBox[0] : 0;
                        var cropY = cropOrMediaBox && cropOrMediaBox.length > 1 ? cropOrMediaBox[1] : 0;
                        var count = points.length / 8;
                        for (var i = 0; i < count; i++) {
                            var x = points[4 + (i * 8)] - points[i * 8];
                            var y = points[5 + (i * 8)] - points[1 + (i * 8)];
                            var height = Math.sqrt((x * x) + (y * y));
                            x = points[6 + (i * 8)] - points[4 + (i * 8)];
                            y = points[7 + (i * 8)] - points[5 + (i * 8)];
                            var width = Math.sqrt((x * x) + (y * y));
                            var rect = {
                                x: points[i * 8] - cropX,
                                y: this._page.size.height - points[1 + (i * 8)] - cropY,
                                width: width,
                                height: height
                            };
                            collection.push(rect);
                        }
                    }
                }
                return collection;
            }
            return this._boundsCollection;
        },
        /**
         * Sets the bounds collection of the annotation.
         *
         * @param {Array<Rectangle>} value bounds collection.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfRedactionAnnotation = page.annotations.at(0) as PdfRedactionAnnotation;
         * // Sets the bounds collection of the annotation.
         * annotation.boundsCollection = [{x: 50, y: 50, width: 100, height: 100}, {x: 201, y: 101, width: 61, height: 31}, {x: 101, y: 401, width: 61, height: 31}];
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            var _a;
            if (!this._isLoaded && typeof value !== 'undefined') {
                if (value.length > 0) {
                    this._quadPoints = new Array(value.length * 8);
                    (_a = this._boundsCollection).push.apply(_a, value);
                }
                else {
                    this._quadPoints = new Array(8);
                    this._boundsCollection = value;
                }
                this._isChanged = true;
            }
            if (this._isLoaded && typeof value !== 'undefined') {
                var isChanged = false;
                if (this.boundsCollection.length === value.length) {
                    for (var i = 0; i < value.length; i++) {
                        var rectA = value[i];
                        var rectB = this.boundsCollection[i];
                        if (rectA.x !== rectB.x || rectA.y !== rectB.y || rectA.width !== rectB.width || rectA.height !== rectB.height) {
                            isChanged = true;
                            break;
                        }
                    }
                }
                else {
                    isChanged = true;
                }
                if (isChanged) {
                    this._quadPoints = new Array(value.length * 8);
                    var pageHeight = this._page.size.height;
                    for (var i = 0; i < value.length; i++) {
                        var rect = value[i];
                        var base = i * 8;
                        this._quadPoints[base + 0] = rect.x;
                        this._quadPoints[base + 1] = pageHeight - rect.y;
                        this._quadPoints[base + 2] = rect.x + rect.width;
                        this._quadPoints[base + 3] = pageHeight - rect.y;
                        this._quadPoints[base + 4] = rect.x;
                        this._quadPoints[base + 5] = this._quadPoints[base + 1] - rect.height;
                        this._quadPoints[base + 6] = rect.x + rect.width;
                        this._quadPoints[base + 7] = this._quadPoints[base + 5];
                    }
                    this._dictionary.update('QuadPoints', this._quadPoints);
                    this._isChanged = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Loads a redaction annotation from the given page and dictionary, marks it as loaded, and initializes internal state.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfRedactionAnnotation} The loaded redaction annotation instance.
     */
    PdfRedactionAnnotation._load = function (page, dictionary) {
        var annot = new PdfRedactionAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the redaction annotation for the specified page and optional source dictionary by delegating to the base initializer.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfRedactionAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Finalizes setup: validates bounds, ensures BS defaults, updates QuadPoints when changed, optionally creates the redaction appearance, and updates the Rect entry.
     *
     * @private
     * @param {boolean} isFlatten When true, prepares for flattening by creating appearance immediately if required.
     * @returns {void} No return value.
     */
    PdfRedactionAnnotation.prototype._postProcess = function (isFlatten) {
        if (typeof this.bounds === 'undefined' || this.bounds === null) {
            throw new Error('Bounds cannot be null or undefined');
        }
        var borderWidth;
        if (this._dictionary.has('BS')) {
            borderWidth = this.border.width;
        }
        else {
            var dictionary = new _PdfDictionary(this._crossReference);
            dictionary.set('Type', _PdfName.get('Border'));
            this._dictionary.set('BS', dictionary);
        }
        if (typeof borderWidth === 'undefined') {
            borderWidth = 1;
        }
        if (this._isChanged) {
            this._setQuadPoints(this._page.size);
        }
        if (this._setAppearance || this._customTemplate.size > 0) {
            this._appearanceTemplate = this._createRedactionAppearance(isFlatten);
        }
        this._dictionary.update('Rect', _updateBounds(this));
    };
    /**
     * Builds or imports the redaction appearance based on load/flatten state and import status, applies matrix normalization when needed, and flattens or removes the annotation accordingly.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation into page content and removes it.
     * @returns {void} No return value.
     */
    PdfRedactionAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (!this._isImported) {
            if (this._isLoaded) {
                this._appearanceTemplate = this._createRedactionAppearance(isFlatten);
            }
            else {
                this._postProcess(isFlatten);
                if (!this._appearanceTemplate) {
                    if (isFlatten) {
                        if (!this._dictionary.has('AP')) {
                            this._appearanceTemplate = this._createRedactionAppearance(isFlatten);
                        }
                        else {
                            var dictionary = this._dictionary.get('AP');
                            if (dictionary && dictionary.has('N')) {
                                var appearanceStream = dictionary.get('N');
                                if (appearanceStream) {
                                    var reference = dictionary.getRaw('N');
                                    if (reference) {
                                        appearanceStream.reference = reference;
                                    }
                                    this._appearanceTemplate = new PdfTemplate(appearanceStream, this._crossReference);
                                }
                            }
                        }
                    }
                }
            }
            if (isFlatten && this._appearanceTemplate) {
                var isNormalMatrix = this._validateTemplateMatrix(this._appearanceTemplate._content.dictionary);
                if (!this._appearanceTemplate._content.dictionary.has('Matrix')) {
                    var box = this._appearanceTemplate._content.dictionary.getArray('BBox');
                    if (box) {
                        this._appearanceTemplate._content.dictionary.update('Matrix', [1, 0, 0, 1, -box[0], -box[1]]);
                    }
                }
                this._flattenAnnotationTemplate(this._appearanceTemplate, isNormalMatrix);
            }
            else if (isFlatten) {
                this._page.annotations.remove(this);
            }
        }
    };
    /**
     * Creates the redaction appearance; during non flatten flow, writes border and normal appearances to AP, or removes the annotation when flattening after creation.
     *
     * @private
     * @param {boolean} isFlatten When true, prepares for flattening and may remove the annotation after creating the appearance.
     * @returns {PdfTemplate} The normal (R) appearance template.
     */
    PdfRedactionAnnotation.prototype._createRedactionAppearance = function (isFlatten) {
        var normalTemplate = this._createNormalAppearance();
        if (isFlatten) {
            if (this._isLoaded && this._page !== null) {
                this._page.annotations.remove(this);
            }
        }
        else {
            var borderTemplate = this._createBorderAppearance();
            if (this._dictionary.has('AP')) {
                var appearance_2 = this._dictionary.get('AP');
                if (appearance_2 && appearance_2 instanceof _PdfDictionary) {
                    _removeDuplicateReference(appearance_2, this._crossReference, 'N');
                    _removeDuplicateReference(appearance_2, this._crossReference, 'R');
                }
            }
            var appearance = void 0;
            if (this._dictionary.has('AP')) {
                appearance = this._dictionary.get('AP');
            }
            else {
                var reference = this._crossReference._getNextReference();
                appearance = new _PdfDictionary(this._crossReference);
                this._crossReference._cacheMap.set(reference, appearance);
                this._dictionary.update('AP', reference);
            }
            if (this._customTemplate.size > 0) {
                normalTemplate = this._customTemplate.get('R');
                this._drawCustomAppearance(appearance);
            }
            else {
                borderTemplate._content.dictionary._updated = true;
                var reference1 = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference1, borderTemplate._content);
                borderTemplate._content.reference = reference1;
                appearance.set('N', reference1);
                normalTemplate._content.dictionary._updated = true;
                var reference = this._crossReference._getNextReference();
                this._crossReference._cacheMap.set(reference, normalTemplate._content);
                normalTemplate._content.reference = reference;
                appearance.set('R', reference);
                appearance._updated = true;
            }
        }
        return normalTemplate;
    };
    /**
     * Creates the border appearance template by drawing the redaction bounds with the configured pen/brush and optional opacity.
     *
     * @private
     * @returns {PdfTemplate} The generated border (N) appearance template.
     */
    PdfRedactionAnnotation.prototype._createBorderAppearance = function () {
        var rectangle;
        if (this.boundsCollection.length > 1) {
            var pdfPath = new PdfPath();
            for (var _i = 0, _a = this.boundsCollection; _i < _a.length; _i++) {
                var bounds = _a[_i];
                pdfPath.addRectangle(bounds);
            }
            var rect = pdfPath._getBounds();
            rectangle = { x: rect[0], y: rect[1], width: rect[2], height: rect[3] };
            this.bounds = rectangle;
        }
        else {
            var singleBound = this.boundsCollection[0];
            if (singleBound) {
                rectangle = singleBound;
            }
            else {
                rectangle = this.bounds;
            }
        }
        var nativeRectangle = [0, 0, this.bounds.width, this.bounds.height];
        var template = new PdfTemplate(nativeRectangle, this._crossReference);
        var graphics = template.graphics;
        var pen;
        var brush;
        if (this.border.width > 0 && this.borderColor) {
            pen = new PdfPen(this.borderColor, this.border.width);
        }
        if (this.appearanceFillColor) {
            brush = new PdfBrush(this.appearanceFillColor);
        }
        var effectiveBoundsCollection = (this.boundsCollection && this.boundsCollection.length > 0)
            ? this.boundsCollection
            : [{ x: this.bounds.x, y: this.bounds.y, width: this.bounds.width, height: this.bounds.height }];
        for (var _b = 0, effectiveBoundsCollection_1 = effectiveBoundsCollection; _b < effectiveBoundsCollection_1.length; _b++) {
            var bounds = effectiveBoundsCollection_1[_b];
            if (this.opacity < 1) {
                var state = graphics.save();
                graphics.setTransparency(this.opacity);
                graphics.drawRectangle({ x: bounds.x - rectangle.x, y: bounds.y - rectangle.y,
                    width: bounds.width, height: bounds.height }, pen, brush);
                graphics.restore(state);
            }
            else {
                graphics.drawRectangle({ x: bounds.x - rectangle.x, y: bounds.y - rectangle.y,
                    width: bounds.width, height: bounds.height }, pen, brush);
            }
        }
        return template;
    };
    /**
     * Renders overlay text inside the provided rectangle across single or multiple bounds, honoring alignment and repeat settings.
     *
     * @private
     * @param {PdfGraphics} graphics The graphics context used for drawing.
     * @param {Rectangle} rectangle The reference rectangle for positioning overlay text.
     * @returns {void} No return value.
     */
    PdfRedactionAnnotation.prototype._drawText = function (graphics, rectangle) {
        if (!this.overlayText) {
            return;
        }
        if (!this.font) {
            this.font = this._lineCaptionFont;
        }
        if (this._isLoaded) {
            this._textAlignment = this.textAlignment;
        }
        var textColorBrush = this.textColor ? new PdfBrush(this.textColor) : new PdfBrush({ r: 128, g: 128, b: 128 });
        var effectiveBoundsCollection = this.boundsCollection && this.boundsCollection.length > 0
            ? this.boundsCollection
            : [{ x: this.bounds.x, y: this.bounds.y, width: this.bounds.width, height: this.bounds.height }];
        var words = [];
        var splitWords = this.overlayText.trim().split(/\s+/);
        splitWords.forEach(function (w) {
            if (w.length > 0) {
                words.push(w);
            }
        });
        var wordIndex = 0;
        for (var _i = 0, effectiveBoundsCollection_2 = effectiveBoundsCollection; _i < effectiveBoundsCollection_2.length; _i++) {
            var bounds = effectiveBoundsCollection_2[_i];
            var rectX = bounds.x - rectangle.x;
            var rectY = bounds.y - rectangle.y;
            var maxWidth = bounds.width;
            var maxHeight = bounds.height;
            wordIndex = this._drawWrappedTextAligned(graphics, rectX, rectY, maxWidth, maxHeight, words, wordIndex, this._textAlignment, textColorBrush, this.repeatText);
            if (!this.repeatText && wordIndex >= words.length) {
                break;
            }
        }
    };
    PdfRedactionAnnotation.prototype._drawWrappedTextAligned = function (graphics, startX, startY, availableWidth, availableHeight, words, startIndex, alignment, brush, loopWhenExhausted) {
        var lineHeight = this._getLineHeight();
        var formatTopLeft = new PdfStringFormat(0, PdfVerticalAlignment.top);
        var isSingleWord = words.length === 1;
        var spaceChar = ' ';
        var spaceWidth = this._getSpaceWidth();
        var y = startY;
        var idx = startIndex;
        while (y + lineHeight <= startY + availableHeight) {
            var lineWords = [];
            var lineText = '';
            var repeatedThisLine = 0;
            while (true) { // eslint-disable-line
                if (idx >= words.length) {
                    if (loopWhenExhausted) {
                        idx = 0;
                        repeatedThisLine++;
                        if (repeatedThisLine > 1 && lineWords.length === 0) {
                            break;
                        }
                    }
                    else {
                        break;
                    }
                }
                if (idx >= words.length) {
                    break;
                }
                var w = words[idx];
                var candidate = lineWords.length === 0 ? w : (isSingleWord ? (lineText + w) : (lineText + spaceChar + w));
                var candidateWidth = this._measureText(candidate);
                if (candidateWidth <= availableWidth + 0.25) {
                    lineWords.push(w);
                    lineText = candidate;
                    idx++;
                    continue;
                }
                if (lineWords.length === 0) {
                    var chunk = this._breakWordToFit(w, availableWidth, this._measureText.bind(this));
                    if (chunk.text.length > 0) {
                        lineWords.push(chunk.text);
                        lineText = chunk.text;
                    }
                    if (chunk.remainder && chunk.remainder.length > 0) {
                        words[idx] = chunk.remainder;
                    }
                    else {
                        idx++;
                    }
                }
                break;
            }
            if (lineWords.length === 0) {
                break;
            }
            var isLastLine = !loopWhenExhausted && (idx >= words.length);
            if (alignment === PdfTextAlignment.right) {
                var lineWidth = this._measureText(lineText);
                var x = startX + Math.max(0, availableWidth - lineWidth);
                graphics.drawString(lineText, this.font, { x: x, y: y, width: lineWidth, height: lineHeight }, null, brush, formatTopLeft);
            }
            else if (alignment === PdfTextAlignment.center) {
                var lineWidth = this._measureText(lineText);
                var x = startX + Math.max(0, (availableWidth - lineWidth) / 2);
                graphics.drawString(lineText, this.font, { x: x, y: y, width: lineWidth, height: lineHeight }, null, brush, formatTopLeft);
            }
            else if (alignment === PdfTextAlignment.justify && !isLastLine && lineWords.length > 1 && !isSingleWord) {
                var wordsWidth = 0;
                for (var _i = 0, _a = lineWords; _i < _a.length; _i++) {
                    var w = _a[_i];
                    wordsWidth += this._measureText(w);
                }
                var extra = availableWidth - wordsWidth - (lineWords.length - 1) * spaceWidth;
                if (extra < 0) {
                    extra = 0;
                }
                var extraPerGap = extra / (lineWords.length - 1);
                var x = startX;
                for (var i = 0; i < lineWords.length; i++) {
                    var w = lineWords[i];
                    var wWidth = this._measureText(w);
                    graphics.drawString(w, this.font, { x: x, y: y, width: wWidth, height: lineHeight }, null, brush, formatTopLeft);
                    x += wWidth;
                    if (i < lineWords.length - 1) {
                        x += spaceWidth + extraPerGap;
                    }
                }
            }
            else {
                graphics.drawString(lineText, this.font, { x: startX, y: y, width: Math.min(this._measureText(lineText), availableWidth), height: lineHeight }, null, brush, formatTopLeft);
            }
            y += lineHeight;
        }
        return idx;
    };
    PdfRedactionAnnotation.prototype._breakWordToFit = function (word, availableWidth, measure) {
        if (!word) {
            return { text: '', remainder: null };
        }
        var lo = 1;
        var hLength = word.length;
        var best = 0;
        while (lo <= hLength) {
            var mid = (lo + hLength) >> 1;
            var part = word.slice(0, mid);
            if (measure(part) <= availableWidth) {
                best = mid;
                lo = mid + 1;
            }
            else {
                hLength = mid - 1;
            }
        }
        var text = word.slice(0, best);
        var remainder = best < word.length ? word.slice(best) : null;
        return { text: text, remainder: remainder };
    };
    PdfRedactionAnnotation.prototype._measureText = function (text) {
        return this.font.measureString(text, { width: 0, height: 0 }).width;
    };
    PdfRedactionAnnotation.prototype._getSpaceWidth = function () {
        return this._measureText(' ');
    };
    PdfRedactionAnnotation.prototype._getLineHeight = function () {
        return this.font._getHeight();
    };
    /**
     * Creates the normal redaction appearance by drawing the specified bounds, applying transparency and page rotation, and rendering overlay text when present.
     *
     * @private
     * @param {number} [index] Optional index of a specific bounds entry to render.
     * @param {Rectangle} [rotatedBounds] Optional pre-rotated bounds to render.
     * @param {PdfRotationAngle} [pageRotation] Optional page rotation to apply to the template.
     * @returns {PdfTemplate} The generated normal appearance template.
     */
    PdfRedactionAnnotation.prototype._createNormalAppearance = function (index, rotatedBounds, pageRotation) {
        var pdfPath = new PdfPath();
        var hasIndex = false;
        var bounds;
        if (rotatedBounds) {
            bounds = rotatedBounds;
            pdfPath.addRectangle(bounds);
            hasIndex = typeof index === 'number' && index >= 0;
        }
        else if (typeof index === 'number' && index >= 0 && index < this.boundsCollection.length) {
            bounds = this.boundsCollection[index];
            pdfPath.addRectangle(bounds);
            hasIndex = true;
        }
        else {
            for (var _i = 0, _a = this.boundsCollection; _i < _a.length; _i++) {
                var bounds_2 = _a[_i];
                pdfPath.addRectangle(bounds_2);
            }
        }
        var rect = pdfPath._getBounds();
        if (rect[2] === 0 && rect[3] === 0) {
            rect[0] = rotatedBounds ? rotatedBounds.x : this.bounds.x;
            rect[1] = rotatedBounds ? rotatedBounds.y : this.bounds.y;
            rect[2] = rotatedBounds ? rotatedBounds.width : this.bounds.width;
            rect[3] = rotatedBounds ? rotatedBounds.height : this.bounds.height;
        }
        var rectangle = { x: rect[0], y: rect[1], width: rect[2], height: rect[3] };
        this.bounds = rectangle;
        var nativeRectangle = [0, 0, rectangle.width, rectangle.height];
        var template = new PdfTemplate(nativeRectangle, this._crossReference);
        var graphics = template.graphics;
        var width = this.border.width / 2;
        var widths = this.border.width;
        var borderPen;
        var backBrush;
        if (this.borderColor && this.border.width > 0) {
            borderPen = new PdfPen(this.borderColor, this.border.width);
        }
        if (this.innerColor) {
            backBrush = new PdfBrush(this.innerColor);
        }
        var alphaState;
        var shouldSetTransparency = this.opacity < 1;
        if (shouldSetTransparency) {
            alphaState = graphics.save();
            graphics.setTransparency(this.opacity);
        }
        if (this.boundsCollection && this.boundsCollection.length > 0) {
            if (hasIndex && bounds) {
                graphics.drawRectangle({
                    x: bounds.x - rectangle.x,
                    y: bounds.y - rectangle.y,
                    width: bounds.width,
                    height: bounds.height
                }, borderPen, backBrush);
            }
            else {
                for (var _b = 0, _c = this.boundsCollection; _b < _c.length; _b++) {
                    var b = _c[_b];
                    graphics.drawRectangle({
                        x: b.x - rectangle.x,
                        y: b.y - rectangle.y,
                        width: b.width,
                        height: b.height
                    }, borderPen, backBrush);
                }
            }
        }
        else {
            graphics.drawRectangle({
                x: nativeRectangle[0] + width,
                y: nativeRectangle[1] + width,
                width: nativeRectangle[2] - widths,
                height: nativeRectangle[3] - widths
            }, borderPen, backBrush);
        }
        if (shouldSetTransparency && alphaState) {
            graphics.restore(alphaState);
        }
        if (this.overlayText) {
            var state = graphics.save();
            var width_1 = nativeRectangle[2];
            var height = nativeRectangle[3];
            switch (pageRotation) {
                case PdfRotationAngle.angle90:
                    graphics.rotateTransform(90);
                    graphics.translateTransform({ x: 0, y: -width_1 });
                    break;
                case PdfRotationAngle.angle180:
                    graphics.rotateTransform(180);
                    graphics.translateTransform({ x: -width_1, y: -height });
                    break;
                case PdfRotationAngle.angle270:
                    graphics.rotateTransform(270);
                    graphics.translateTransform({ x: -height, y: 0 });
                    break;
                case PdfRotationAngle.angle0:
                default:
                    break;
            }
            var rotatedRect = rectangle;
            if (typeof pageRotation !== 'undefined' && pageRotation !== null &&
                (pageRotation === PdfRotationAngle.angle90 ||
                    pageRotation === PdfRotationAngle.angle270)) {
                rotatedRect.width = rectangle.height;
                rotatedRect.height = rectangle.width;
            }
            this._drawText(graphics, rotatedRect);
            graphics.restore(state);
        }
        return template;
    };
    return PdfRedactionAnnotation;
}(PdfComment));
export { PdfRedactionAnnotation };
/**
 * `PdfRichMediaAnnotation` class represents the rich media annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: PdfRichMediaAnnotation = page.annotations.at(0) as PdfRichMediaAnnotation;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfRichMediaAnnotation = /** @class */ (function (_super) {
    __extends(PdfRichMediaAnnotation, _super);
    /**
     * Initializes a new instance of the `PdfRichMediaAnnotation` class.
     *
     * @private
     */
    function PdfRichMediaAnnotation() {
        var _this = _super.call(this) || this;
        _this._type = _PdfAnnotationType.richMediaAnnotation;
        return _this;
    }
    /**
     * Creates a rich media annotation from the given page and dictionary and marks it as loaded.
     *
     * @private
     * @param {PdfPage} page The page that contains the annotation.
     * @param {_PdfDictionary} dictionary The source annotation dictionary.
     * @returns {PdfRichMediaAnnotation} The loaded rich media annotation instance.
     */
    PdfRichMediaAnnotation._load = function (page, dictionary) {
        var annot = new PdfRichMediaAnnotation();
        annot._isLoaded = true;
        annot._initialize(page, dictionary);
        return annot;
    };
    /**
     * Initializes the annotation using the page and optional dictionary by invoking base initialization.
     *
     * @private
     * @param {PdfPage} page The page to associate with this annotation.
     * @param {_PdfDictionary} [dictionary] Optional source dictionary to import from.
     * @returns {void} No return value.
     */
    PdfRichMediaAnnotation.prototype._initialize = function (page, dictionary) {
        _super.prototype._initialize.call(this, page, dictionary);
    };
    /**
     * Performs post processing including flattening popups and appearance and removes the annotation if appearance is unavailable during flattening.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation using its appearance stream if present; otherwise removes it.
     * @returns {void} No return value.
     */
    PdfRichMediaAnnotation.prototype._doPostProcess = function (isFlatten) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (typeof this.flattenPopups !== 'undefined' && this.flattenPopups) {
            this._flattenPopUp();
        }
        if (isFlatten) {
            var appearanceStream = void 0;
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var template = new PdfTemplate(appearanceStream, this._crossReference);
                var isNormalMatrix = this._validateTemplateMatrix(template._content.dictionary);
                this._flattenAnnotationTemplate(template, isNormalMatrix);
            }
            else {
                this._removeAnnotation(this._page, this);
            }
        }
    };
    return PdfRichMediaAnnotation;
}(PdfAnnotation));
export { PdfRichMediaAnnotation };
/**
 * `PdfWidgetAnnotation` class represents the widget annotation objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access first page
 * let page: PdfPage = document.getPage(0);
 * // Access the annotation at index 0
 * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfWidgetAnnotation = /** @class */ (function (_super) {
    __extends(PdfWidgetAnnotation, _super);
    /**
     * Initializes a new instance of the `PdfWidgetAnnotation` class.
     *
     * @private
     */
    function PdfWidgetAnnotation() {
        var _this = _super.call(this) || this;
        /**
         * Enables automatic resizing of the widget to fit content.
         *
         * @private
         */
        _this._isAutoResize = false;
        /**
         * Controls the visibility state of the form field/widget.
         *
         * @private
         */
        _this._visibility = PdfFormFieldVisibility.visible;
        /**
         * Indicates whether a font has been explicitly set for the widget.
         *
         * @private
         */
        _this._isFont = false;
        /**
         * When true, treats the background color as transparent.
         *
         * @private
         */
        _this._isTransparentBackColor = false;
        /**
         * When true, treats the border color as transparent.
         *
         * @private
         */
        _this._isTransparentBorderColor = false;
        _this._isWidget = true;
        _this._type = _PdfAnnotationType.widgetAnnotation;
        return _this;
    }
    /**
     * Parse an existing widget annotation.
     *
     * @private
     * @param {_PdfDictionary} dictionary Widget dictionary.
     * @param {_PdfCrossReference} crossReference PDF cross reference.
     * @returns {PdfWidgetAnnotation} Widget.
     */
    PdfWidgetAnnotation._load = function (dictionary, crossReference) {
        var widget = new PdfWidgetAnnotation();
        widget._isLoaded = true;
        widget._dictionary = dictionary;
        widget._crossReference = crossReference;
        return widget;
    };
    Object.defineProperty(PdfWidgetAnnotation.prototype, "page", {
        /**
         * Gets the page object (Read only).
         *
         * @returns {PdfPage} page object.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access first item of check box field
         * let item: PdfWidgetAnnotation = field.itemAt(0);
         * // Gets the page object.
         * let page: PdfPage = item.page;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._getPage();
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "color", {
        /**
         * Gets the fore color of the annotation.
         *
         * @returns {PdfColor} Color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the fore color of the annotation.
         * let color: PdfColor = annotation.color;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._color === 'undefined' && this._defaultAppearance) {
                this._color = this._da.color;
            }
            return this._color;
        },
        /**
         * Sets the fore color of the annotation.
         *
         * @param {PdfColor} value Color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the fore color of the annotation.
         * annotation.color = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof this.color === 'undefined' || this._color !== value) {
                this._color = value;
            }
            var isNew = false;
            if (!this._defaultAppearance) {
                this._da = new _PdfDefaultAppearance('');
                isNew = true;
            }
            if (isNew || this._da.color !== value) {
                this._da.color = value;
                this._dictionary.update('DA', this._da.toString());
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "backColor", {
        /**
         * Gets the back color of the annotation.
         *
         * @returns {PdfColor} Color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the text box field at index 0
         * let field: PdfField = document.form.fieldAt(0);
         * // Gets the back color of the annotation
         * let backColor: PdfColor = field.itemAt(0).backColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._parseBackColor();
        },
        /**
         * Sets the back color of the annotation.
         *
         * @param {PdfColor} value Array with R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the text box field at index 0
         * let field: PdfField = document.form.fieldAt(0);
         * // Sets the background color of the field item
         * field.itemAt(0).backColor = {r: 255, g: 0, b: 0};
         * // Sets the background color of the field item to transparent
         * field.itemAt(1).backColor = {r: 0, g: 0, b: 0, isTransparent: true};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._updateBackColor(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "_hasBackColor", {
        /**
         * Indicates whether a background color is defined for the annotation.
         *
         * @private
         * @returns {boolean} as true or false.
         */
        get: function () {
            if (this._isLoaded) {
                var mkDictionary = this._mkDictionary;
                return (mkDictionary && mkDictionary.has('BG'));
            }
            else {
                return !this._isTransparentBackColor;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "_hasBorderColor", {
        /**
         * Indicates whether a border color is defined for the annotation.
         *
         * @private
         * @returns {boolean} as true or false.
         */
        get: function () {
            if (this._isLoaded) {
                var mkDictionary = this._mkDictionary;
                return (mkDictionary && mkDictionary.has('BC'));
            }
            else {
                return !this._isTransparentBorderColor;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "borderColor", {
        /**
         * Gets the border color of the annotation.
         *
         * @returns {PdfColor} Color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the border color of the annotation.
         * let borderColor: PdfColor = annotation.borderColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._parseBorderColor();
        },
        /**
         * Sets the border color of the annotation.
         *
         * @param {PdfColor} value Array with R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the border color of the annotation.
         * annotation.borderColor = {r: 255, g: 255, b: 255};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._updateBorderColor(value);
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "rotate", {
        /**
         * Gets the rotation angle of the annotation.
         *
         * @returns {number} Rotation angle as number.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the rotation angle of the annotation.
         * let rotate: number = annotation.rotate;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._rotationAngle === 'undefined') {
                if (this._mkDictionary && this._mkDictionary.has('R')) {
                    this._rotationAngle = this._mkDictionary.get('R');
                }
                else if (this._dictionary.has('R')) {
                    this._rotationAngle = this._dictionary.get('R');
                }
            }
            return this._rotationAngle;
        },
        /**
         * Sets the rotation angle of the annotation.
         *
         * @param {number} value Rotation angle as number.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the rotation angle of the annotation.
         * annotation.rotate = 90;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof this.rotate === 'undefined' || this._rotationAngle !== value) {
                if (typeof this._mkDictionary === 'undefined') {
                    this._dictionary.update('MK', new _PdfDictionary(this._crossReference));
                }
                this._mkDictionary.update('R', value);
                this._rotationAngle = value;
                this._dictionary._updated = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "highlightMode", {
        /**
         * Gets the highlight mode of the annotation.
         *
         * @returns {PdfHighlightMode} Highlight mode.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the highlight mode of the annotation.
         * let highlightMode: PdfHighlightMode = annotation.highlightMode;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._highlightMode === 'undefined' && this._dictionary.has('H')) {
                var mode = this._dictionary.get('H');
                this._highlightMode = _mapHighlightMode(mode.name);
            }
            return this._highlightMode;
        },
        /**
         * Sets the highlight mode of the annotation.
         *
         * @param {PdfHighlightMode} value Highlight mode.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the highlight mode of the annotation.
         * annotation.highlightMode = PdfHighlightMode.noHighlighting;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._highlightMode !== value) {
                this._dictionary.update('H', _reverseMapHighlightMode(value));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "bounds", {
        /**
         * Gets the bounds of the annotation.
         *
         * @returns {Rectangle} Bounds.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the bounds of the annotation
         * let bounds: Rectangle = annotation.bounds;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded && typeof this._bounds === 'undefined') {
                this._bounds = _calculateBounds(this._dictionary, this._getPage());
            }
            if (typeof this._bounds === 'undefined' || this._bounds === null) {
                this._bounds = { x: 0, y: 0, width: 0, height: 0 };
            }
            return this._bounds;
        },
        /**
         * Sets the bounds of the annotation.
         *
         * @param {Rectangle} value Bounds
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the bounds of the annotation
         * annotation.bounds = {x: 0, y: 0, width: 50, height: 50};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value.x === 0 && value.y === 0 && value.width === 0 && value.height === 0) {
                throw new Error('Cannot set empty bounds');
            }
            this._bounds = value;
            if (this._page && this._page._isNew && this._page._pageSettings) {
                this._dictionary.update('Rect', _updateBounds(this));
            }
            else {
                this._dictionary.update('Rect', _getUpdatedBounds([value.x, value.y, value.width, value.height], this._getPage()));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "textAlignment", {
        /**
         * Gets the text alignment of the annotation.
         *
         * @returns {PdfTextAlignment} Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the text alignment of the annotation.
         * let textAlignment: PdfTextAlignment = annotation.textAlignment;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._textAlignment === 'undefined' && this._dictionary.has('Q')) {
                this._textAlignment = this._dictionary.get('Q');
            }
            return this._textAlignment;
        },
        /**
         * Sets the text alignment of the annotation.
         *
         * @param {PdfTextAlignment} value Text alignment.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Sets the text alignment of the annotation
         * annotation.textAlignment = PdfTextAlignment.left;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof this._textAlignment === 'undefined' || this._textAlignment !== value) {
                this._dictionary.update('Q', value);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "visibility", {
        /**
         * Gets the visibility.
         *
         * @returns {PdfFormFieldVisibility} Field visibility option.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the form field at index 0
         * let field: PdfField = document.form.fieldAt(0);
         * // Gets the visibility
         * let visibility: PdfFormFieldVisibility = field.itemAt(0).visibility;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            var value;
            if (this._isLoaded) {
                value = PdfFormFieldVisibility.visible;
                var flag = PdfAnnotationFlag.default;
                if (this._hasFlags) {
                    flag = this.flags;
                    var flagValue = 3;
                    if ((flag & PdfAnnotationFlag.hidden) === PdfAnnotationFlag.hidden) {
                        flagValue = 0;
                    }
                    if ((flag & PdfAnnotationFlag.noView) === PdfAnnotationFlag.noView) {
                        flagValue = 1;
                    }
                    if ((flag & PdfAnnotationFlag.print) !== PdfAnnotationFlag.print) {
                        flagValue &= 2;
                    }
                    switch (flagValue) {
                        case 0:
                            value = PdfFormFieldVisibility.hidden;
                            break;
                        case 1:
                            value = PdfFormFieldVisibility.hiddenPrintable;
                            break;
                        case 2:
                            value = PdfFormFieldVisibility.visibleNotPrintable;
                            break;
                        case 3:
                            value = PdfFormFieldVisibility.visible;
                            break;
                    }
                }
                else {
                    value = PdfFormFieldVisibility.visibleNotPrintable;
                }
            }
            else {
                return this._visibility;
            }
            return value;
        },
        /**
         * Sets the visibility.
         *
         * @param {PdfFormFieldVisibility} value Visibility option.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the form field at index 0
         * let field: PdfField = document.form.fieldAt(0);
         * // Sets the visibility
         * let field.itemAt(0).visibility = PdfFormFieldVisibility.hiddenPrintable;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this._isLoaded) {
                _updateVisibility(this._dictionary, value);
                this._dictionary._updated = true;
            }
            else {
                switch (value) {
                    case PdfFormFieldVisibility.hidden:
                        this.flags = PdfAnnotationFlag.hidden;
                        break;
                    case PdfFormFieldVisibility.hiddenPrintable:
                        this.flags = PdfAnnotationFlag.noView | PdfAnnotationFlag.print;
                        break;
                    case PdfFormFieldVisibility.visible:
                        this.flags = PdfAnnotationFlag.print;
                        break;
                    case PdfFormFieldVisibility.visibleNotPrintable:
                        this.flags = PdfAnnotationFlag.default;
                        break;
                }
                this._visibility = value;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "font", {
        /**
         * Gets the font of the item.
         *
         * @returns {PdfFont} font.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the form field at index 0
         * let field: PdfTextBoxField = document.form.fieldAt(0) as PdfTextBoxField;
         * // Get the first item of the field
         * let item: PdfWidgetAnnotation = field.itemAt(0);
         * // Gets the font of the item
         * let font: PdfFont = item.font;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            var _this = this;
            if (!this._pdfFont) {
                var fontName = void 0;
                if (this._crossReference) {
                    var form_1 = this._crossReference._document.form;
                    var fontData = this._obtainFontDetails();
                    var cacheKey = fontData.name + "_" + fontData.size + "_" + fontData.style;
                    if (form_1 && form_1._fontCache.has(cacheKey)) {
                        return form_1._fontCache.get(cacheKey);
                    }
                    if (form_1 && form_1._dictionary.has('DR')) {
                        var resources = form_1._dictionary.get('DR');
                        if (resources.has('Font')) {
                            var fonts = resources.get('Font');
                            if (fonts.has(fontData.name)) {
                                var fontDictionary = fonts.get(fontData.name);
                                if (fontDictionary && fontData.name && fontDictionary.has('BaseFont')) {
                                    var baseFont = fontDictionary.get('BaseFont');
                                    var textFontStyle = PdfFontStyle.regular;
                                    if (baseFont) {
                                        fontName = baseFont.name;
                                        textFontStyle = _getFontStyle(baseFont.name);
                                        if (fontName.includes('-')) {
                                            fontName = fontName.substring(0, fontName.indexOf('-'));
                                        }
                                        if (this._dictionary.has('DA')) {
                                            this._pdfFont = _obtainFontDetails(form_1, this);
                                        }
                                        else {
                                            this._pdfFont = _mapFont(fontName, fontData.size, textFontStyle, this);
                                        }
                                        if (!form_1._fontCache.has(cacheKey)) {
                                            form_1._fontCache.set(cacheKey, this._pdfFont);
                                        }
                                    }
                                }
                            }
                        }
                    }
                    if ((form_1 !== null && typeof form_1 !== 'undefined') && (this._pdfFont === null || typeof this._pdfFont === 'undefined') &&
                        form_1._parsedFields && form_1._parsedFields.size > 0) {
                        form_1._parsedFields.forEach(function (field) {
                            if (field instanceof PdfTextBoxField && field._kidsCount > 0) {
                                _this._pdfFont = _obtainFontDetails(form_1, _this, field);
                            }
                        });
                        if (!form_1._fontCache.has(cacheKey)) {
                            form_1._fontCache.set(cacheKey, this._pdfFont);
                        }
                    }
                }
            }
            if ((this._pdfFont === null || typeof this._pdfFont === 'undefined') || (!this._isLoaded && this._pdfFont.size === 1)) {
                this._pdfFont = this._circleCaptionFont;
            }
            return this._pdfFont;
        },
        /**
         * Sets the font of the item.
         *
         * @param {PdfFont} value font.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the form field at index 0
         * let field: PdfTextBoxField = document.form.fieldAt(0) as PdfTextBoxField;
         * // Get the first item of the field
         * let item: PdfWidgetAnnotation = field.itemAt(0);
         * // Set the font of the item
         * item.font = new PdfStandardFont(PdfFontFamily.helvetica, 12, PdfFontStyle.bold);
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value && value instanceof PdfFont) {
                this._pdfFont = value;
                this._initializeFont(value);
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "_defaultAppearance", {
        /**
         * Gets the cached default appearance from the annotation dictionary if available.
         *
         * @private
         * @returns {_PdfDefaultAppearance} The parsed default appearance, if any.
         */
        get: function () {
            if (typeof this._da === 'undefined' && this._dictionary.has('DA')) {
                var da = this._dictionary.get('DA');
                if (da && da !== '') {
                    this._da = new _PdfDefaultAppearance(da);
                }
            }
            return this._da;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfWidgetAnnotation.prototype, "_mkDictionary", {
        /**
         * Gets the cached default appearance from the annotation dictionary if available.
         *
         * @private
         * @returns {_PdfDefaultAppearance} The parsed default appearance, if any.
         */
        get: function () {
            var value;
            if (this._dictionary.has('MK')) {
                value = this._dictionary.get('MK');
            }
            return value;
        },
        enumerable: true,
        configurable: true
    });
    /* eslint-disable */
    /**
     * Creates and initializes the widget annotation on the specified page with optional field linkage.
     *
     * @private
     * @param {PdfPage} page The page on which to create the widget.
     * @param {{x: number, y: number, width: number, height: number}} bounds The widget bounds in page coordinates. // eslint-disable-line
     * @param {PdfField} [field] Optional form field to set as this widget's parent.
     * @returns {_PdfDictionary} The created widget annotation dictionary.
     */
    PdfWidgetAnnotation.prototype._create = function (page, bounds, field) {
        this._page = page;
        this._crossReference = page._crossReference;
        this._ref = this._crossReference._getNextReference();
        this._dictionary = new _PdfDictionary(this._crossReference);
        this._crossReference._cacheMap.set(this._ref, this._dictionary);
        this._dictionary._currentObj = this;
        this._dictionary.objId = this._ref.toString();
        this._dictionary.update('Type', _PdfName.get('Annot'));
        this._dictionary.update('Subtype', _PdfName.get('Widget'));
        this.flags |= PdfAnnotationFlag.print;
        this._dictionary.update('P', page._ref);
        page._addWidget(this._ref);
        this.border = new PdfAnnotationBorder();
        if (bounds) {
            this.bounds = bounds;
        }
        if (field) {
            this._field = field;
            this._dictionary.update('Parent', this._field._ref);
        }
        return this._dictionary;
    };
    /* eslint-enable */
    /**
     * Performs post processing to recreate or use existing appearance and optionally flattens it to the page.
     *
     * @private
     * @param {boolean} [isFlatten=false] When true, flattens the annotation appearance into page content.
     * @param {boolean} [recreateAppearance=false] When true, attempts to recreate the appearance stream.
     * @returns {void} No return value.
     */
    PdfWidgetAnnotation.prototype._doPostProcess = function (isFlatten, recreateAppearance) {
        if (isFlatten === void 0) { isFlatten = false; }
        if (recreateAppearance === void 0) { recreateAppearance = false; }
        if (isFlatten || recreateAppearance) {
            var appearanceStream = void 0;
            if (recreateAppearance || (isFlatten && !this._dictionary.has('AP'))) {
                //appearanceStream = this._createAppearance();
            }
            if (!appearanceStream && this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary && dictionary.has('N')) {
                    appearanceStream = dictionary.get('N');
                    var reference = dictionary.getRaw('N');
                    if (reference && appearanceStream) {
                        appearanceStream.reference = reference;
                    }
                }
            }
            if (appearanceStream) {
                var bounds = void 0;
                if (isFlatten) {
                    var template = new PdfTemplate(appearanceStream, this._crossReference);
                    var page = this._getPage();
                    if (page) {
                        var graphics = page.graphics;
                        graphics.save();
                        if (page.rotation === PdfRotationAngle.angle90) {
                            graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                            graphics.rotateTransform(90);
                        }
                        else if (page.rotation === PdfRotationAngle.angle180) {
                            graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                            graphics.rotateTransform(-180);
                        }
                        else if (page.rotation === PdfRotationAngle.angle270) {
                            graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                            graphics.rotateTransform(270);
                        }
                        bounds = { x: this.bounds.x, y: this.bounds.y, width: template._size.width, height: template._size.height };
                        graphics.drawTemplate(template, bounds);
                        graphics.restore();
                    }
                }
                else {
                    var appearance = void 0;
                    if (this._dictionary.has('AP')) {
                        appearance = this._dictionary.get('AP');
                    }
                    else {
                        var reference_1 = this._crossReference._getNextReference();
                        appearance = new _PdfDictionary(this._crossReference);
                        this._crossReference._cacheMap.set(reference_1, appearance);
                        this._dictionary.update('AP', reference_1);
                    }
                    _removeDuplicateReference(appearance, this._crossReference, 'N');
                    var reference = this._crossReference._getNextReference();
                    this._crossReference._cacheMap.set(reference, appearanceStream);
                    appearance.update('N', reference);
                }
            }
            this._dictionary._updated = false;
        }
    };
    /**
     * Initializes and registers the font in the document resources and updates default appearance.
     *
     * @private
     * @param {PdfFont} font The font to register and apply to this widget.
     * @returns {void} No return value.
     */
    PdfWidgetAnnotation.prototype._initializeFont = function (font) {
        this._pdfFont = font;
        var document;
        if (this._crossReference) {
            document = this._crossReference._document;
            var resource = void 0;
            if (document) {
                if (document.form._dictionary.has('DR')) {
                    resource = document.form._dictionary.get('DR');
                }
                else {
                    resource = new _PdfDictionary(this._crossReference);
                }
            }
            var fontDict = void 0;
            var isReference = false;
            if (resource.has('Font')) {
                var obj = resource.getRaw('Font'); // eslint-disable-line
                if (obj && obj instanceof _PdfReference) {
                    isReference = true;
                    fontDict = this._crossReference._fetch(obj);
                }
                else if (obj instanceof _PdfDictionary) {
                    fontDict = obj;
                }
            }
            if (!fontDict) {
                fontDict = new _PdfDictionary(this._crossReference);
                resource.update('Font', fontDict);
            }
            var keyName = _PdfName.get(_getNewGuidString());
            var reference = this._crossReference._getNextReference();
            this._crossReference._cacheMap.set(reference, this._pdfFont._dictionary);
            if (font instanceof PdfTrueTypeFont) {
                if (this._pdfFont._pdfFontInternals) {
                    this._crossReference._cacheMap.set(reference, this._pdfFont._pdfFontInternals);
                }
            }
            else if (this._pdfFont._dictionary) {
                this._crossReference._cacheMap.set(reference, this._pdfFont._dictionary);
            }
            fontDict.update(keyName.name, reference);
            resource._updated = true;
            document.form._dictionary.update('DR', resource);
            document.form._dictionary._updated = true;
            this._fontName = keyName.name;
            var defaultAppearance = new _PdfDefaultAppearance();
            defaultAppearance.fontName = this._fontName;
            defaultAppearance.fontSize = this._pdfFont._size;
            defaultAppearance.color = this.color ? this.color : { r: 0, g: 0, b: 0 };
            this._dictionary.update('DA', defaultAppearance.toString());
            if (isReference) {
                resource._updated = true;
            }
            this._isFont = true;
        }
    };
    /**
     * Resolves and caches the owning page of the annotation from the document structure.
     *
     * @private
     * @returns {PdfPage} The resolved page object, if found.
     */
    PdfWidgetAnnotation.prototype._getPage = function () {
        if (!this._page) {
            var document_1;
            if (this._crossReference) {
                document_1 = this._crossReference._document;
            }
            var page = void 0;
            if (this._dictionary.has('P')) {
                var ref = this._dictionary.getRaw('P');
                if (ref && document_1) {
                    for (var i = 0; i < document_1.pageCount; i++) {
                        var entry = document_1.getPage(i);
                        if (entry && entry._ref === ref) {
                            page = entry;
                            break;
                        }
                    }
                }
            }
            if (!page && document_1 && this._ref) {
                page = _findPage(document_1, this._ref);
            }
            this._page = page;
        }
        return this._page;
    };
    /**
     * Updates the annotation rectangle before saving when bounds must be normalized to the page.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfWidgetAnnotation.prototype._beginSave = function () {
        if (!this._isLoaded && !this._page._isNew) {
            var value = this._bounds;
            this._dictionary.update('Rect', _getUpdatedBounds([value.x, value.y, value.width, value.height], this._page));
        }
    };
    /**
     * Parses and returns the background color from the appearance dictionary or defaults to white.
     *
     * @private
     * @returns {PdfColor} The resolved background color.
     */
    PdfWidgetAnnotation.prototype._parseBackColor = function () {
        var value;
        if ((this._isLoaded && this._hasBackColor) || (!this._isLoaded && !this._isTransparentBackColor)) {
            if (typeof this._backColor === 'undefined') {
                var dictionary = this._mkDictionary;
                if (dictionary && dictionary.has('BG')) {
                    var colorArray = dictionary.getArray('BG');
                    if (colorArray) {
                        this._backColor = _parseColor(colorArray);
                    }
                }
            }
            if (typeof this._backColor === 'undefined' || this._backColor === null) {
                this._backColor = { r: 255, g: 255, b: 255 };
            }
            value = this._backColor;
        }
        return value;
    };
    /**
     * Parses and returns the border color from the appearance dictionary or defaults to black.
     *
     * @private
     * @returns {PdfColor} The resolved border color.
     */
    PdfWidgetAnnotation.prototype._parseBorderColor = function () {
        var value;
        if ((this._isLoaded && this._hasBorderColor) || (!this._isLoaded && !this._isTransparentBorderColor)) {
            if (typeof this._borderColor === 'undefined') {
                var dictionary = this._mkDictionary;
                if (dictionary && dictionary.has('BC')) {
                    var colorArray = dictionary.getArray('BC');
                    if (colorArray) {
                        this._borderColor = _parseColor(colorArray);
                    }
                }
            }
            if (typeof this._borderColor === 'undefined' || this._borderColor === null) {
                this._borderColor = { r: 0, g: 0, b: 0 };
            }
            value = this._borderColor;
        }
        return value;
    };
    /**
     * Updates the background color state and appearance flags and optionally triggers field appearance regeneration.
     *
     * @private
     * @param {PdfColor} value The new background color (set isTransparent to remove).
     * @param {boolean} [setAppearance=false] When true, marks the parent field for appearance regeneration.
     * @returns {void} No return value.
     */
    PdfWidgetAnnotation.prototype._updateBackColor = function (value, setAppearance) {
        if (setAppearance === void 0) { setAppearance = false; }
        var isChanged = false;
        if (value && value.isTransparent) {
            this._isTransparentBackColor = true;
            if (this._dictionary.has('BG')) {
                delete this._dictionary._map.BG;
                isChanged = true;
            }
            var mkDictionary = this._mkDictionary;
            if (mkDictionary && mkDictionary.has('BG')) {
                delete mkDictionary._map.BG;
                this._dictionary._updated = true;
                isChanged = true;
            }
        }
        else {
            this._isTransparentBackColor = false;
            var bColor = void 0;
            if (bColor) {
                bColor = { r: this._backColor.r, g: this._backColor.g, b: this._backColor.b };
            }
            if (typeof this.backColor === 'undefined' || bColor !== value) {
                if (typeof this._mkDictionary === 'undefined') {
                    this._dictionary.update('MK', new _PdfDictionary(this._crossReference));
                }
                this._mkDictionary.update('BG', [Number.parseFloat((value.r / 255).toFixed(3)),
                    Number.parseFloat((value.g / 255).toFixed(3)),
                    Number.parseFloat((value.b / 255).toFixed(3))]);
                this._backColor = value;
                this._dictionary._updated = true;
                isChanged = true;
            }
        }
        if (setAppearance && isChanged && this._field) {
            this._field._setAppearance = true;
        }
    };
    /**
     * Updates the border color state and related border style entries in the appearance dictionary.
     *
     * @private
     * @param {PdfColor} value The new border color (set isTransparent to remove).
     * @returns {void} No return value.
     */
    PdfWidgetAnnotation.prototype._updateBorderColor = function (value) {
        if (value && value.isTransparent) {
            this._isTransparentBorderColor = true;
            if (this._dictionary.has('BC')) {
                delete this._dictionary._map.BC;
            }
            var mkDictionary = this._mkDictionary;
            if (mkDictionary && mkDictionary.has('BC')) {
                delete mkDictionary._map.BC;
                if (this._dictionary.has('BS')) {
                    var bsDictionary = this._dictionary.get('BS');
                    if (bsDictionary && bsDictionary.has('W')) {
                        delete bsDictionary._map.W;
                    }
                }
                this._dictionary._updated = true;
            }
        }
        else {
            this._isTransparentBorderColor = false;
            var bColor = void 0;
            if (this.borderColor) {
                bColor = this.borderColor;
            }
            if (typeof this.borderColor === 'undefined' || bColor !== value) {
                if (typeof this._mkDictionary === 'undefined') {
                    this._dictionary.update('MK', new _PdfDictionary(this._crossReference));
                }
                this._mkDictionary.update('BC', [Number.parseFloat((value.r / 255).toFixed(3)),
                    Number.parseFloat((value.g / 255).toFixed(3)),
                    Number.parseFloat((value.b / 255).toFixed(3))]);
                this._borderColor = value;
                this._dictionary._updated = true;
            }
        }
    };
    return PdfWidgetAnnotation;
}(PdfAnnotation));
export { PdfWidgetAnnotation };
/**
 * `PdfStateItem` class represents the check box field item objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Access check box field
 * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
 * // Access first item of check box field
 * let item: PdfStateItem = field.itemAt(0) as PdfStateItem;
 * // Sets the check box style as check
 * item.style = PdfCheckBoxStyle.check;
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfStateItem = /** @class */ (function (_super) {
    __extends(PdfStateItem, _super);
    /**
     * Initializes a new instance of the `PdfStateItem` class.
     *
     * @private
     */
    function PdfStateItem() {
        var _this = _super.call(this) || this;
        /**
         * Stores the export value associated with the selected state.
         *
         * @private
         */
        _this._exportValue = 'Yes';
        return _this;
    }
    /**
     * Parse an existing item of the field.
     *
     * @private
     * @param {_PdfDictionary} dictionary Widget dictionary.
     * @param {_PdfCrossReference} crossReference PDF cross reference.
     * @param {PdfField} field Field object.
     * @returns {PdfStateItem} Widget.
     */
    PdfStateItem._load = function (dictionary, crossReference, field) {
        var widget = new PdfStateItem();
        widget._isLoaded = true;
        widget._dictionary = dictionary;
        widget._crossReference = crossReference;
        widget._field = field;
        return widget;
    };
    Object.defineProperty(PdfStateItem.prototype, "checked", {
        /**
         * Gets the flag to indicate whether the field item is checked or not.
         *
         * @returns {boolean} Checked or not.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access first item of check box field
         * let item: PdfStateItem = field.itemAt(0) as PdfStateItem;
         * // Gets the flag to indicate whether the field item is checked or not.
         * let checked: boolean = item.checked;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return _checkField(this._dictionary);
        },
        /**
         * Sets the flag to indicate whether the field item is checked or not.
         *
         * @param {boolean} value Checked or not.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access first item of check box field
         * let item: PdfStateItem = field.itemAt(0) as PdfStateItem;
         * // Sets the style of the annotation
         * item.checked = true;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this.checked !== value) {
                if (this._field) {
                    this._setCheckedStatus(value);
                    this._field._setAppearance = true;
                }
                if (this._exportValue) {
                    this._dictionary.update('AS', _PdfName.get(value ? this._exportValue : 'Off'));
                }
                else if (this._field && this._field._exportValue !== null && typeof this._field._exportValue !== 'undefined') {
                    this._dictionary.update('AS', _PdfName.get(value ? this._field._exportValue : 'Off'));
                }
                else {
                    this._dictionary.update('AS', _PdfName.get(value ? 'Yes' : 'Off'));
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfStateItem.prototype, "style", {
        /**
         * Gets the style of annotation.
         *
         * @returns {PdfCheckBoxStyle} Style of annotation.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access first item of check box field
         * let item: PdfStateItem = field.itemAt(0) as PdfStateItem;
         * // Gets the style of the annotation
         * let style: PdfCheckBoxStyle = item.style;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded) {
                var dictionary = this._mkDictionary;
                if (dictionary && dictionary.has('CA')) {
                    this._style = _stringToStyle(dictionary.get('CA'));
                }
                else {
                    this._style = PdfCheckBoxStyle.check;
                }
            }
            return this._style;
        },
        /**
         * Sets the style of annotation.
         *
         * @param {PdfCheckBoxStyle} value Style of annotation.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access first item of check box field
         * let item: PdfStateItem = field.itemAt(0) as PdfStateItem;
         * // Sets the style of the annotation
         * item.style = PdfCheckBoxStyle.check;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (this.style !== value) {
                this._style = value;
                var dictionary = this._mkDictionary;
                if (!dictionary) {
                    dictionary = new _PdfDictionary(this._crossReference);
                    this._dictionary.update('MK', dictionary);
                }
                dictionary.update('CA', _styleToString(value));
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfStateItem.prototype, "exportValue", {
        /**
         * Gets the export value of the check box field.
         *
         * @returns {string} Export value.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access the first item of the check box field group
         * let item: PdfStateItem = field.itemAt(0);
         * // Gets the export value of the checkbox field.
         * let text: sting = item.exportValue;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._tryGetExportValue(this);
        },
        /**
         * Sets the export value of the check box item.
         *
         * @param {string} value Export value.
         *
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Access the check box field
         * let field: PdfCheckBoxField = document.form.fieldAt(0) as PdfCheckBoxField;
         * // Access the first item of the check box field group
         * let item: PdfStateItem = field.itemAt(0);
         * // Sets the export value of the checkbox field.
         * item.exportValue = 'CheckBox';
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== '') {
                this._exportValue = value;
            }
            if (this.checked) {
                this._dictionary.update('AS', _PdfName.get(value));
                this._setCheckedStatus(this.checked);
            }
            else {
                this._dictionary.update('AS', _PdfName.get('Off'));
            }
            if (this._dictionary.has('AP')) {
                var dictionary = this._dictionary.get('AP');
                if (dictionary.has('N') || dictionary.has('D')) {
                    var oldValue = this._tryGetExportValue(this);
                    var newValue = value;
                    if (dictionary.has('N')) {
                        var normalDictionary = dictionary.get('N');
                        if (normalDictionary && normalDictionary.has(oldValue)) {
                            var reference = normalDictionary.getRaw(oldValue);
                            delete normalDictionary._map[oldValue]; // eslint-disable-line
                            normalDictionary.update(newValue, reference);
                            normalDictionary._updated = true;
                        }
                    }
                    if (dictionary.has('D')) {
                        var downDictionary = dictionary.get('D');
                        if (downDictionary && downDictionary.has(oldValue)) {
                            var reference = downDictionary.getRaw(oldValue);
                            delete downDictionary._map[oldValue]; // eslint-disable-line
                            downDictionary.update(newValue, reference);
                            downDictionary._updated = true;
                        }
                    }
                }
            }
            this._dictionary._updated = true;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Sets the checked state and updates field and appearance dictionaries accordingly.
     *
     * @private
     * @param {boolean} value Checked state to apply.
     * @returns {void} No return value.
     */
    PdfStateItem.prototype._setCheckedStatus = function (value) {
        var check = value;
        var fieldValue = this._tryGetExportValue(this);
        this._unCheckOthers(this, fieldValue, value);
        if (check) {
            if (!fieldValue) {
                fieldValue = 'Yes';
            }
            else {
                this._exportValue = fieldValue;
            }
            this._field._dictionary.update('V', _PdfName.get(fieldValue));
            this._field._dictionary.update('AS', _PdfName.get(fieldValue));
            this._dictionary.update('AS', _PdfName.get(fieldValue));
            this._dictionary.update('V', _PdfName.get(fieldValue));
        }
        else if (this._field._dictionary) {
            if (this._field._dictionary.has('V')) {
                var v = this._field._dictionary.get('V');
                if (v && v.name === fieldValue) {
                    delete this._field._dictionary._map.V;
                }
            }
            this._field._dictionary.update('AS', _PdfName.get('Off'));
        }
    };
    /**
     * Unchecks sibling items in the same field and ensures the current item remains checked when needed.
     *
     * @private
     * @param {PdfStateItem} child The current item being toggled.
     * @param {string} value The export value used to match siblings.
     * @param {boolean} isChecked Whether the current item is checked.
     * @returns {void} No return value.
     */
    PdfStateItem.prototype._unCheckOthers = function (child, value, isChecked) {
        if (!this._field._isUpdating) {
            this._field._isUpdating = true;
            var count = this._field.itemsCount;
            for (var i = 0; i < count; ++i) {
                var item = this._field.itemAt(i);
                if (item) {
                    if (item !== child) {
                        var exportValue = this._tryGetExportValue(item);
                        item.checked = (exportValue === value && isChecked);
                    }
                    else if (!item.checked) {
                        item.checked = true;
                    }
                }
            }
        }
    };
    /**
     * Determines the export value of the widget from its appearance or state entries.
     *
     * @private
     * @param {PdfStateItem} item Item to inspect.
     * @returns {string} The resolved export value.
     */
    PdfStateItem.prototype._tryGetExportValue = function (item) {
        var itemValue = item._exportValue;
        if (item._dictionary && item._dictionary.has('AP')) {
            var apDictionary = item._dictionary.get('AP');
            if (apDictionary && apDictionary.has('N')) {
                var normalAppearance = apDictionary.get('N');
                var keyList_1 = [];
                normalAppearance.forEach(function (key, value) {
                    keyList_1.push(key);
                });
                if (keyList_1.length > 0) {
                    for (var i = 0; i < keyList_1.length; i++) {
                        var key = keyList_1[i];
                        if (key && key !== 'Off') {
                            itemValue = key;
                            break;
                        }
                    }
                }
            }
        }
        else if (item._dictionary && item._dictionary.has('AS')) {
            var asValue = item._dictionary.get('AS');
            if (asValue && asValue.name !== 'Off') {
                itemValue = asValue.name;
            }
        }
        return itemValue;
    };
    /**
     * Draws the current state appearance onto the page and finalizes the annotation update state.
     *
     * @private
     * @returns {void} No return value.
     */
    PdfStateItem.prototype._doPostProcess = function () {
        var style = this.checked ? _PdfCheckFieldState.checked : _PdfCheckFieldState.unchecked;
        var template = _getStateTemplate(style, this);
        if (template) {
            var page = this._getPage();
            if (page) {
                var graphics = page.graphics;
                graphics.save();
                if (page.rotation === PdfRotationAngle.angle90) {
                    graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                    graphics.rotateTransform(90);
                }
                else if (page.rotation === PdfRotationAngle.angle180) {
                    graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                    graphics.rotateTransform(-180);
                }
                else if (page.rotation === PdfRotationAngle.angle270) {
                    graphics.translateTransform({ x: graphics._size.width, y: graphics._size.height });
                    graphics.rotateTransform(270);
                }
                graphics._sw._setTextRenderingMode(_TextRenderingMode.fill);
                graphics.drawTemplate(template, this.bounds);
                graphics.restore();
            }
        }
        this._dictionary._updated = false;
    };
    /**
     * Updates the appearance state entry based on the provided or inferred value.
     *
     * @private
     * @param {string} [value] The appearance state to set; defaults to 'Yes' or 'Off'.
     * @returns {void} No return value.
     */
    PdfStateItem.prototype._postProcess = function (value) {
        var field = this._field;
        if (!value) {
            value = (field && field.checked) ? 'Yes' : 'Off';
        }
        this._dictionary.update('AS', _PdfName.get(value));
    };
    /**
     * Assigns the owning field, updates formatting, and registers this item as a kid of the field.
     *
     * @private
     * @param {PdfField} field The parent field to associate.
     * @returns {void} No return value.
     */
    PdfStateItem.prototype._setField = function (field) {
        this._field = field;
        this._field._stringFormat = new PdfStringFormat(this.textAlignment, PdfVerticalAlignment.middle);
        this._field._addToKid(this);
    };
    return PdfStateItem;
}(PdfWidgetAnnotation));
export { PdfStateItem };
/**
 * `PdfRadioButtonListItem` class represents the radio button field item objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * // Gets the first page of the document
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Access the PDF form
 * let form: PdfForm = document.form;
 * // Create a new radio button list field
 * let field: PdfRadioButtonListField = new PdfRadioButtonListField(page, 'Age');
 * // Create and add first item
 * let first: PdfRadioButtonListItem = field.add('1-9', {x: 100, y: 140, width: 20, height: 20});
 * // Create and add second item
 * let second: PdfRadioButtonListItem = new PdfRadioButtonListItem('10-49', {x: 100, y: 170, width: 20, height: 20}, page);
 * field.add(second);
 * // Create and add third item
 * let third: PdfRadioButtonListItem = new PdfRadioButtonListItem('50-59', {x: 100, y: 200, width: 20, height: 20}, field);
 * field.add(third);
 * // Sets selected index of the radio button list field
 * field.selectedIndex = 0;
 * // Add the field into PDF form
 * form.add(field);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfRadioButtonListItem = /** @class */ (function (_super) {
    __extends(PdfRadioButtonListItem, _super);
    function PdfRadioButtonListItem(value, bounds, item) {
        var _this = _super.call(this) || this;
        if (item && value && bounds) {
            if (item instanceof PdfField) {
                _this._initializeItem(value, bounds, item.page, item);
            }
            else {
                _this._initializeItem(value, bounds, item);
            }
        }
        return _this;
    }
    /**
     * Parse an existing item of the field.
     *
     * @private
     * @param {_PdfDictionary} dictionary Widget dictionary.
     * @param {_PdfCrossReference} crossReference PDF cross reference.
     * @param {PdfField} field Field object.
     * @returns {PdfRadioButtonListItem} Widget.
     */
    PdfRadioButtonListItem._load = function (dictionary, crossReference, field) {
        var widget = new PdfRadioButtonListItem();
        widget._isLoaded = true;
        widget._dictionary = dictionary;
        widget._crossReference = crossReference;
        widget._field = field;
        return widget;
    };
    Object.defineProperty(PdfRadioButtonListItem.prototype, "selected", {
        /**
         * Gets the flag to indicate whether the field item is selected or not.
         *
         * @returns {boolean} Selected or not.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfRadioButtonListField = new PdfRadioButtonListField(page, 'Age');
         * // Access first list field item
         * let item: PdfRadioButtonListItem = field.itemAt(0);
         * // Gets the flag to indicate whether the field item is selected or not.
         * let selected: boolean = item.selected;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._index === this._field.selectedIndex;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRadioButtonListItem.prototype, "value", {
        /**
         * Gets the value of the radio button list field item
         *
         * @returns {string} Value of the radio button list field item.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfRadioButtonListField = new PdfRadioButtonListField(page, 'Age');
         * // Access first list field item
         * let item: PdfRadioButtonListItem = field.itemAt(0);
         * // Gets the value of the radio button list field item
         * let value: string = item.value;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (this._isLoaded && !this._optionValue) {
                this._optionValue = _getItemValue(this._dictionary);
            }
            return this._optionValue;
        },
        /**
         * Sets the value of the radio button list field item
         *
         * @param {string} option Value of the radio button list field item.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfRadioButtonListField = new PdfRadioButtonListField(page, 'Age');
         * // Access first list field item
         * let item: PdfRadioButtonListItem = field.itemAt(0);
         * // Sets the value of the radio button list field item
         * item.value = '1-9';
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (option) {
            this._optionValue = option;
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfRadioButtonListItem.prototype, "backColor", {
        /**
         * Gets the back color of the annotation.
         *
         * @returns {PdfColor} Color as R, G, B color array in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfWidgetAnnotation = page.annotations.at(0) as PdfWidgetAnnotation;
         * // Gets the back color of the annotation
         * let backColor: PdfColor = annotation.backColor;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._parseBackColor();
        },
        /**
         * Sets the back color of the annotation.
         *
         * @param {PdfColor} value Array with R, G, B color values in between 0 to 255.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0);
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Access the radio button list field
         * let field: PdfRadioButtonListField = form.fieldAt(0) as PdfRadioButtonListField;
         * // Sets the back color of the radio button list item
         * field.itemAt(0).backColor = {r: 255, g: 255, b: 255};
         * // Sets the background color of the field item to transparent
         * field.itemAt(1).backColor = {r: 0, g: 0, b: 0, isTransparent: true};
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            this._updateBackColor(value, true);
        },
        enumerable: true,
        configurable: true
    });
    /* eslint-disable */
    /**
     * Initializes the radio button item with value, page, bounds, default styles, and optional parent field.
     *
     * @private
     * @param {string} value The option/export value for this item.
     * @param {any} bounds The item bounds on the page.
     * @param {PdfPage} page The page where the item resides.
     * @param {PdfField} [field] Optional field to register as parent.
     * @returns {void} No return value.
     */
    PdfRadioButtonListItem.prototype._initializeItem = function (value, bounds, page, field) {
        this._optionValue = value;
        this._page = page;
        this._create(this._page, bounds, this._field);
        this.textAlignment = PdfTextAlignment.left;
        this._dictionary.update('MK', new _PdfDictionary(this._crossReference));
        this._mkDictionary.update('BC', [0, 0, 0]);
        this._mkDictionary.update('BG', [1, 1, 1]);
        this.style = PdfCheckBoxStyle.circle;
        this._dictionary.update('DA', '/TiRo 0 Tf 0 0 0 rg');
        if (field) {
            this._setField(field);
            this._dictionary.update('Parent', field._ref);
        }
    };
    /* eslint-enable */
    /**
     * Updates the appearance state to the provided value or turns it off when not selected.
     *
     * @private
     * @param {string} [value] The appearance state or index string to set as selected.
     * @returns {void} No return value.
     */
    PdfRadioButtonListItem.prototype._postProcess = function (value) {
        var field = this._field;
        if (field) {
            if (this.value === value || this._index.toString() === value) {
                this._dictionary.update('AS', _PdfName.get(value));
            }
            else {
                this._dictionary.update('AS', _PdfName.get('Off'));
            }
        }
    };
    return PdfRadioButtonListItem;
}(PdfStateItem));
export { PdfRadioButtonListItem };
/**
 * `PdfListBoxItem` class represents the list and combo box field item objects.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data);
 * // Gets the first page of the document
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Access the PDF form
 * let form: PdfForm = document.form;
 * // Create a new list box field
 * let field: PdfListBoxField = new PdfListBoxField(page, 'list1', {x: 100, y: 60, width: 100, height: 50});
 * // Add list items to the field.
 * field.addItem(new PdfListFieldItem('English', 'English'));
 * field.addItem(new PdfListFieldItem('French', 'French'));
 * field.addItem(new PdfListFieldItem('German', 'German'));
 * // Sets the selected index
 * field.selectedIndex = 2;
 * // Sets the flag indicates whether the list box allows multiple selections.
 * field.multiSelect = true;
 * // Add the field into PDF form
 * form.add(field);
 * // Save the document
 * document.save('output.pdf');
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfListFieldItem = /** @class */ (function (_super) {
    __extends(PdfListFieldItem, _super);
    function PdfListFieldItem(text, value, field) {
        var _this = _super.call(this) || this;
        if (text && value) {
            _this._initializeItem(text, value, field);
        }
        return _this;
    }
    /**
     * Parse an existing item of the field.
     *
     * @private
     * @param {_PdfDictionary} dictionary Widget dictionary.
     * @param {_PdfCrossReference} crossReference PDF cross reference.
     * @param {PdfField} field Field object.
     * @returns {PdfListFieldItem} Widget.
     */
    PdfListFieldItem._load = function (dictionary, crossReference, field) {
        var widget = new PdfListFieldItem();
        widget._isLoaded = true;
        widget._dictionary = dictionary;
        widget._crossReference = crossReference;
        widget._field = field;
        return widget;
    };
    Object.defineProperty(PdfListFieldItem.prototype, "text", {
        /**
         * Gets the text of the annotation.
         *
         * @returns {string} Text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfListBoxField = form.fieldAt(0) as PdfListBoxField;
         * // Access first list field item
         * let item: PdfListFieldItem = field.itemAt(0);
         * // Gets the text of the list field item
         * let text: string = item.text;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            if (typeof this._text === 'undefined' &&
                typeof this._field !== 'undefined' &&
                (this._field instanceof PdfListBoxField || this._field instanceof PdfComboBoxField)) {
                this._text = this._field._options[this._index][1];
            }
            return this._text;
        },
        /**
         * Sets the text of the annotation.
         *
         * @param {string} value Text.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfListBoxField = form.fieldAt(0) as PdfListBoxField;
         * // Access first list field item
         * let item: PdfListFieldItem = field.itemAt(0);
         * // Sets the text of the list field item
         * item.text = '1-9';
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof value === 'string' &&
                typeof this._field !== 'undefined' &&
                (this._field instanceof PdfListBoxField || this._field instanceof PdfComboBoxField)) {
                if (value !== this._field._options[this._index][1]) {
                    this._field._options[this._index][1] = value;
                    this._text = value;
                    this._field._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfListFieldItem.prototype, "selected", {
        /**
         * Gets the flag to indicate whether the field item is selected or not (Read only).
         *
         * @returns {boolean} Selected or not.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data);
         * // Gets the first page of the document
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Access the PDF form
         * let form: PdfForm = document.form;
         * // Create a new radio button list field
         * let field: PdfListBoxField = form.fieldAt(0) as PdfListBoxField;
         * // Access first list field item
         * let item: PdfListFieldItem = field.itemAt(0);
         * // Gets the flag to indicate whether the field item is selected or not.
         * let selected: boolean = item.selected;
         * // Save the document
         * document.save('output.pdf');
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._index === this._field.selectedIndex;
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Initializes the list item with display text and value and optionally registers it with the owning list box field.
     *
     * @private
     * @param {string} text The display text.
     * @param {string} value The stored/export value.
     * @param {PdfField} [field] The owning list/combobox field (registers when provided).
     * @returns {void} No return value.
     */
    PdfListFieldItem.prototype._initializeItem = function (text, value, field) {
        this._text = text;
        this._value = value;
        if (field && field instanceof PdfListBoxField) {
            field._addToOptions(this, field);
        }
    };
    return PdfListFieldItem;
}(PdfStateItem));
export { PdfListFieldItem };
/**
 * `PdfAnnotationCaption` class represents the caption text and properties of annotations.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Get the first annotation of the page
 * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
 * // Create and set annotation caption values
 * annotation.caption = new PdfAnnotationCaption({cap: true, type: PdfLineCaptionType.inline, offset: {x: 10, y: 10}});
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAnnotationCaption = /** @class */ (function () {
    function PdfAnnotationCaption(options) {
        if (options && 'cap' in options && options.cap !== null && typeof options.cap === 'boolean') {
            this._cap = options.cap;
        }
        else {
            this._cap = false;
        }
        if (options && 'type' in options && options.type !== null && typeof options.type !== 'undefined') {
            this._type = options.type;
        }
        else {
            this._type = PdfLineCaptionType.inline;
        }
        if (options && 'offset' in options && options.offset !== null && typeof options.offset !== 'undefined') {
            this._offset = options.offset;
        }
        else {
            this._offset = { x: 0, y: 0 };
        }
    }
    Object.defineProperty(PdfAnnotationCaption.prototype, "cap", {
        /**
         * Gets the boolean flag indicating whether annotation has caption or not.
         *
         * @returns {boolean} Caption.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the boolean flag indicating whether annotation has caption or not.
         * let cap: boolean = annotation.caption.cap;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._cap;
        },
        /**
         * Sets the boolean flag indicating whether annotation has caption or not.
         *
         * @param {boolean} value Caption.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the boolean flag indicating whether annotation has caption or not.
         * annotation.caption.cap = true;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._cap) {
                this._cap = value;
                if (this._dictionary) {
                    this._dictionary.update('Cap', value);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationCaption.prototype, "type", {
        /**
         * Gets the caption type of the annotation.
         *
         * @returns {PdfLineCaptionType} Caption type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the caption type of the annotation.
         * let type: PdfLineCaptionType = annotation.caption.type;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._type;
        },
        /**
         * Sets the caption type of the annotation.
         *
         * @param {PdfLineCaptionType} value Caption type.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the caption type of the annotation.
         * annotation.caption.type = PdfLineCaptionType.inline;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._type) {
                this._type = value;
                if (this._dictionary) {
                    this._dictionary.update('CP', _PdfName.get(value === PdfLineCaptionType.top ? 'Top' : 'Inline'));
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationCaption.prototype, "offset", {
        /**
         * Gets the offset position of the annotation.
         *
         * @returns {Point} Caption offset.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the offset position of the annotation.
         * let offset: Point = annotation.caption.offset;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._offset;
        },
        /**
         * Sets the offset position of the annotation.
         *
         * @param {Point} value Caption offset.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Sets the offset position of the annotation.
         * annotation.caption.offset = {x: 10, y: 10};
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value && !this._offset) {
                this._offset = value;
                this._dictionary.update('CO', [value.x, value.y]);
            }
            else if (value && this._offset && (value.x !== this._offset.x || value.y !== this._offset.y)) {
                this._offset = value;
                if (this._dictionary) {
                    this._dictionary.update('CO', [value.x, value.y]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    return PdfAnnotationCaption;
}());
export { PdfAnnotationCaption };
/**
 * `PdfAnnotationLineEndingStyle` class represents the line ending styles of annotations.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Get the first annotation of the page
 * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
 * // Initializes a new instance of the `PdfAnnotationLineEndingStyle` class.
 * annotation.lineEndingStyle = new PdfAnnotationLineEndingStyle({begin: PdfLineEndingStyle.openArrow, end: PdfLineEndingStyle.closeArrow});
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAnnotationLineEndingStyle = /** @class */ (function () {
    function PdfAnnotationLineEndingStyle(options) {
        if (options && 'begin' in options && options.begin !== null && typeof options.begin !== 'undefined') {
            this._begin = options.begin;
        }
        else {
            this._begin = PdfLineEndingStyle.none;
        }
        if (options && 'end' in options && options.end !== null && typeof options.end !== 'undefined') {
            this._end = options.end;
        }
        else {
            this._begin = PdfLineEndingStyle.none;
        }
    }
    Object.defineProperty(PdfAnnotationLineEndingStyle.prototype, "begin", {
        /**
         * Gets the begin line ending style of the annotation.
         *
         * @returns {PdfLineEndingStyle} Begin line ending style.
         * `PdfAnnotationLineEndingStyle` class represents the line ending styles of annotations.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the begin line ending style of the annotation.
         * let begin: PdfLineEndingStyle = annotation.lineEndingStyle.begin;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._begin;
        },
        /**
         * Sets the begin line ending style of the annotation.
         *
         * @param {PdfLineEndingStyle} value Begin line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the `PdfAnnotationLineEndingStyle` class.
         * let lineEndingStyle = new PdfAnnotationLineEndingStyle();
         * // Sets the begin line ending style of the annotation.
         * lineEndingStyle.begin = PdfLineEndingStyle.openArrow;
         * // Sets the end line ending style of the annotation.
         * lineEndingStyle.end = PdfLineEndingStyle.closeArrow;
         * // Sets the line ending style to the annotation
         * annotation.lineEndingStyle = lineEndingStyle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._begin) {
                this._begin = value;
                if (this._dictionary) {
                    this._dictionary.update('LE', [_PdfName.get(_reverseMapEndingStyle(value)), _PdfName.get(_reverseMapEndingStyle(this._end))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationLineEndingStyle.prototype, "end", {
        /**
         * Gets the begin line ending style of the annotation.
         *
         * @returns {PdfLineEndingStyle} End line ending style.
         * `PdfAnnotationLineEndingStyle` class represents the line ending styles of annotations.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the end line ending style of the annotation.
         * let end: PdfLineEndingStyle = annotation.lineEndingStyle.end;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._end;
        },
        /**
         * Sets the begin line ending style of the annotation.
         *
         * @param {PdfLineEndingStyle} value End line ending style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the `PdfAnnotationLineEndingStyle` class.
         * let lineEndingStyle = new PdfAnnotationLineEndingStyle();
         * // Sets the begin line ending style of the annotation.
         * lineEndingStyle.begin = PdfLineEndingStyle.openArrow;
         * // Sets the end line ending style of the annotation.
         * lineEndingStyle.end = PdfLineEndingStyle.closeArrow;
         * // Sets the line ending style to the annotation
         * annotation.lineEndingStyle = lineEndingStyle;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._end) {
                this._end = value;
                if (this._dictionary) {
                    this._dictionary.update('LE', [_PdfName.get(_reverseMapEndingStyle(this._begin)), _PdfName.get(_reverseMapEndingStyle(value))]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    return PdfAnnotationLineEndingStyle;
}());
export { PdfAnnotationLineEndingStyle };
/**
 * `PdfInteractiveBorder` class represents the border of the field.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the PDF form field
 * let field: PdfField = document.form.fieldAt(0);
 * // Gets the width of the field border.
 * let width: number = field.border.width;
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfInteractiveBorder = /** @class */ (function () {
    function PdfInteractiveBorder(options) {
        if (options && 'width' in options && options.width !== null && typeof options.width !== 'undefined') {
            this._width = options.width;
        }
        else {
            this._width = 1;
        }
        if (options && 'style' in options && options.style !== null && typeof options.style !== 'undefined') {
            this._style = options.style;
        }
        else {
            this._style = PdfBorderStyle.solid;
        }
        if (options && 'dash' in options && options.dash !== null && Array.isArray(options.dash)) {
            this._dash = options.dash;
        }
    }
    Object.defineProperty(PdfInteractiveBorder.prototype, "width", {
        /**
         * Gets the width of the field border.
         *
         * @returns {number} border width.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Gets the width of the annotation border.
         * let width: number = field.border.width;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._width;
        },
        /**
         * Sets the width of the field border.
         *
         * @param {number} value width.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Initializes a new instance of the `PdfInteractiveBorder` class.
         * let border: PdfInteractiveBorder = new PdfInteractiveBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * field.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._width) {
                this._width = value;
                if (this._dictionary) {
                    var bs = this._dictionary.has('BS') ? this._dictionary.get('BS') : new _PdfDictionary(this._crossReference);
                    bs.update('Type', _PdfName.get('Border'));
                    bs.update('W', this._width);
                    bs.update('S', _mapBorderStyle(this._style));
                    if (this._dash) {
                        bs.update('D', this._dash);
                    }
                    this._dictionary.update('BS', bs);
                    this._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfInteractiveBorder.prototype, "style", {
        /**
         * Gets the border line style of the field border.
         *
         * @returns {PdfBorderStyle} Border style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Gets the border line style of the annotation border.
         * let style: PdfBorderStyle = field.border.style;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._style;
        },
        /**
         * Sets the border line style of the field border.
         *
         * @param {PdfBorderStyle} value Border style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Initializes a new instance of the `PdfInteractiveBorder` class.
         * let border: PdfInteractiveBorder = new PdfInteractiveBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * field.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._style) {
                this._style = value;
                if ((Array.isArray(this._dash) && this._dash.length === 0) || !this._dash) {
                    if (value === PdfBorderStyle.dot) {
                        this._dash = [1, 1];
                    }
                    else if (value === PdfBorderStyle.dashed) {
                        this._dash = [3, 1];
                    }
                }
                if (this._dictionary) {
                    var bs = this._dictionary.has('BS') ? this._dictionary.get('BS') : new _PdfDictionary(this._crossReference);
                    bs.update('Type', _PdfName.get('Border'));
                    bs.update('W', this._width);
                    bs.update('S', _mapBorderStyle(this._style));
                    if (this._dash) {
                        bs.update('D', this._dash);
                    }
                    this._dictionary.update('BS', bs);
                    this._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfInteractiveBorder.prototype, "dash", {
        /**
         * Gets the dash pattern of the field border.
         *
         * @returns {Array<number>} Dash pattern.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Gets the dash pattern of the field border.
         * let dash: Array<number>= field.border.dash;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._dash;
        },
        /**
         * Sets the dash pattern of the field border.
         *
         * @param {Array<number>} value Dash pattern.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the PDF form field
         * let field: PdfField = document.form.fieldAt(0);
         * // Initializes a new instance of the `PdfInteractiveBorder` class.
         * let border: PdfInteractiveBorder = new PdfInteractiveBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * field.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (typeof this._dash === 'undefined' || _areNotEqual(value, this._dash)) {
                this._dash = value;
                if (this._dictionary) {
                    var bs = this._dictionary.has('BS') ? this._dictionary.get('BS') : new _PdfDictionary(this._crossReference);
                    bs.update('Type', _PdfName.get('Border'));
                    bs.update('W', this._width);
                    bs.update('S', _mapBorderStyle(this._style));
                    bs.update('D', this._dash);
                    this._dictionary.update('BS', bs);
                    this._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    return PdfInteractiveBorder;
}());
export { PdfInteractiveBorder };
/**
 * `PdfAnnotationBorder` class represents the border properties of annotations.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Get the first annotation of the page
 * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
 * // Initializes a new instance of the `PdfAnnotationBorder` class.
 * let border: PdfAnnotationBorder = new PdfAnnotationBorder();
 * //Sets the width of the annotation border.
 * border.width = 10;
 * //Sets the style of the annotation border.
 * border.style = PdfBorderStyle.dashed;
 * //Sets the dash pattern of the annotation border.
 * border.dash = [1, 2, 1];
 * // Sets the border to the PDF form field
 * annotation.border = border;
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfAnnotationBorder = /** @class */ (function (_super) {
    __extends(PdfAnnotationBorder, _super);
    function PdfAnnotationBorder(options) {
        var _this = _super.call(this, options) || this;
        if (options !== null && typeof options !== 'undefined') {
            if (options && 'hRadius' in options && options.hRadius !== null && typeof options.hRadius !== 'undefined') {
                _this._hRadius = options.hRadius;
            }
            else {
                _this._hRadius = 0;
            }
            if (options && 'vRadius' in options && options.vRadius !== null && typeof options.vRadius !== 'undefined') {
                _this._vRadius = options.vRadius;
            }
            else {
                _this._vRadius = 0;
            }
        }
        return _this;
    }
    Object.defineProperty(PdfAnnotationBorder.prototype, "width", {
        /**
         * Gets the width of the annotation border.
         *
         * @returns {number} border width.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the width of the annotation border.
         * let width: number = annotation.border.width;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._width;
        },
        /**
         * Sets the width of the annotation border.
         *
         * @param {number} value width.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the ` PdfAnnotationBorder ` class.
         * let border: PdfAnnotationBorder = new PdfAnnotationBorder ();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * annotation.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._width) {
                this._width = value;
                if (this._dictionary) {
                    this._dictionary.update('Border', [this._hRadius, this._vRadius, this._width]);
                    var bs = this._dictionary.has('BS') ? this._dictionary.get('BS') : new _PdfDictionary(this._crossReference);
                    bs.update('Type', _PdfName.get('Border'));
                    bs.update('W', this._width);
                    bs.update('S', _mapBorderStyle(this._style));
                    if (this._dash) {
                        bs.update('D', this._dash);
                    }
                    this._dictionary.update('BS', bs);
                    this._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationBorder.prototype, "hRadius", {
        /**
         * Gets the horizontal radius of the annotation border.
         *
         * @returns {number} horizontal radius.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the horizontal radius of the annotation border.
         * let hRadius: number = annotation.border.hRadius;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._hRadius;
        },
        /**
         * Sets the horizontal radius of the annotation border.
         *
         * @param {number} value horizontal radius.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the `PdfAnnotationBorder` class.
         * let border: PdfAnnotationBorder = new PdfAnnotationBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * // Sets the horizontal radius of the annotation border.
         * border.hRadius = 2;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * annotation.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._hRadius) {
                this._hRadius = value;
                if (this._dictionary) {
                    this._dictionary.update('Border', [this._hRadius, this._vRadius, this._width]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfAnnotationBorder.prototype, "vRadius", {
        /**
         * Gets the vertical radius of the annotation border.
         *
         * @returns {number} vertical radius.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Gets the vertical radius of the annotation border.
         * let vRadius: number = annotation.border.vRadius;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._vRadius;
        },
        /**
         * Sets the vertical radius of the annotation border.
         *
         * @param {number} value vertical radius.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfLineAnnotation = page.annotations.at(0) as PdfLineAnnotation;
         * // Initializes a new instance of the `PdfAnnotationBorder` class.
         * let border: PdfAnnotationBorder = new PdfAnnotationBorder();
         * //Sets the width of the annotation border.
         * border.width = 10;
         * // Sets the vertical radius of the annotation border.
         * border.vRadius = 2;
         * //Sets the style of the annotation border.
         * border.style = PdfBorderStyle.dashed;
         * //Sets the dash pattern of the annotation border.
         * border.dash = [1, 2, 1];
         * // Sets the border to the PDF form field
         * annotation.border = border;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._vRadius) {
                this._vRadius = value;
                if (this._dictionary) {
                    this._dictionary.update('Border', [this._hRadius, this._vRadius, this._width]);
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    return PdfAnnotationBorder;
}(PdfInteractiveBorder));
export { PdfAnnotationBorder };
/**
 * `PdfBorderEffect` class represents the border effects of annotations.
 * ```typescript
 * // Load an existing PDF document
 * let document: PdfDocument = new PdfDocument(data, password);
 * // Get the first page
 * let page: PdfPage = document.getPage(0) as PdfPage;
 * // Get the first annotation of the page
 * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
 * // Initializes a new instance of the `PdfBorderEffect` class.
 * let borderEffect: PdfBorderEffect = new PdfBorderEffect();
 * // Sets the intensity of the annotation border.
 * borderEffect.intensity = 2;
 * // Sets the effect style of the annotation border.
 * borderEffect.style = PdfBorderEffectStyle.cloudy;
 * // Sets border effect to the annotation.
 * annotation.borderEffect = borderEffect;
 * // Destroy the document
 * document.destroy();
 * ```
 */
var PdfBorderEffect = /** @class */ (function () {
    function PdfBorderEffect(arg) {
        /**
         * Cloudiness or intensity value for the border effect.
         *
         * @private
         */
        this._intensity = 0;
        if (typeof arg !== 'undefined' && arg !== null) {
            if (arg instanceof _PdfDictionary) {
                if (arg.has('BE')) {
                    var borderEffect = this._dictionary.get('BE');
                    if (borderEffect) {
                        if (borderEffect.has('I')) {
                            this._intensity = borderEffect.get('I');
                        }
                        if (borderEffect.has('S')) {
                            this._style = this._getBorderEffect(borderEffect.get('S'));
                        }
                    }
                }
            }
            else {
                if ('intensity' in arg && arg.intensity !== null && typeof arg.intensity !== 'undefined') {
                    this._intensity = arg.intensity;
                }
                if ('style' in arg && arg.style !== null && typeof arg.style !== 'undefined') {
                    this._style = arg.style;
                }
                this._dictionary = new _PdfDictionary();
                this._dictionary.set('I', this._intensity);
                this._dictionary.set('S', this._styleToEffect(this._style));
            }
        }
        else {
            this._dictionary = new _PdfDictionary();
            this._dictionary.set('I', this._intensity);
            this._dictionary.set('S', this._styleToEffect(this._style));
        }
    }
    Object.defineProperty(PdfBorderEffect.prototype, "intensity", {
        /**
         * Gets the intensity of the annotation border.
         *
         * @returns {number} intensity.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Gets the intensity of the annotation border.
         * let intensity: number = annotation.borderEffect.intensity;
         * // Gets the effect style of the annotation border.
         * let style: PdfBorderEffectStyle = annotation.borderEffect.style;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._intensity;
        },
        /**
         * Sets the intensity of the annotation border.
         *
         * @param {number} value intensity.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Initializes a new instance of the `PdfBorderEffect` class.
         * let borderEffect: PdfBorderEffect = new PdfBorderEffect();
         * // Sets the intensity of the annotation border.
         * borderEffect.intensity = 2;
         * // Sets the effect style of the annotation border.
         * borderEffect.style = PdfBorderEffectStyle.cloudy;
         * // Sets border effect to the annotation.
         * annotation.borderEffect = borderEffect;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._intensity) {
                this._intensity = value;
                if (this._dictionary) {
                    var bs = this._dictionary.has('BE') ? this._dictionary.get('BE') : new _PdfDictionary(this._crossReference);
                    bs.update('I', this._intensity);
                    bs.update('S', this._styleToEffect(this._style));
                    this._dictionary.update('BE', bs);
                    this._dictionary._updated = true;
                }
                this._dictionary._updated = true;
            }
        },
        enumerable: true,
        configurable: true
    });
    Object.defineProperty(PdfBorderEffect.prototype, "style", {
        /**
         * Gets the effect style of the annotation border.
         *
         * @returns {PdfBorderEffectStyle} effect style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Gets the intensity of the annotation border.
         * let intensity: number = annotation.borderEffect.intensity;
         * // Gets the effect style of the annotation border.
         * let style: PdfBorderEffectStyle = annotation.borderEffect.style;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        get: function () {
            return this._style;
        },
        /**
         * Sets the effect style of the annotation border.
         *
         * @param {PdfBorderEffectStyle} value effect style.
         * ```typescript
         * // Load an existing PDF document
         * let document: PdfDocument = new PdfDocument(data, password);
         * // Get the first page
         * let page: PdfPage = document.getPage(0) as PdfPage;
         * // Get the first annotation of the page
         * let annotation: PdfSquareAnnotation = page.annotations.at(0) as PdfSquareAnnotation;
         * // Initializes a new instance of the `PdfBorderEffect` class.
         * let borderEffect: PdfBorderEffect = new PdfBorderEffect();
         * // Sets the intensity of the annotation border.
         * borderEffect.intensity = 2;
         * // Sets the effect style of the annotation border.
         * borderEffect.style = PdfBorderEffectStyle.cloudy;
         * // Sets border effect to the annotation.
         * annotation.borderEffect = borderEffect;
         * // Destroy the document
         * document.destroy();
         * ```
         */
        set: function (value) {
            if (value !== this._style) {
                this._style = value;
                if (this._dictionary) {
                    var bs = this._dictionary.has('BE') ?
                        this._dictionary.get('BE') :
                        new _PdfDictionary(this._crossReference);
                    bs.update('I', this._intensity);
                    bs.update('S', this._styleToEffect(this._style));
                    this._dictionary.update('BE', bs);
                    this._dictionary._updated = true;
                }
            }
        },
        enumerable: true,
        configurable: true
    });
    /**
     * Converts the border effect name into the corresponding border effect style.
     *
     * @private
     * @param {string} value The raw border effect string (e.g., '/C' or other values).
     * @returns {PdfBorderEffectStyle} The mapped border effect style.
     */
    PdfBorderEffect.prototype._getBorderEffect = function (value) {
        if (value === '/C') {
            return PdfBorderEffectStyle.cloudy;
        }
        else {
            return PdfBorderEffectStyle.solid;
        }
    };
    /**
     * Converts the border effect style into its corresponding string representation.
     *
     * @private
     * @param {PdfBorderEffectStyle} value The border effect style to convert.
     * @returns {string} The string representation for use in the annotation dictionary.
     */
    PdfBorderEffect.prototype._styleToEffect = function (value) {
        if (value === PdfBorderEffectStyle.cloudy) {
            return 'C';
        }
        else {
            return 'S';
        }
    };
    return PdfBorderEffect;
}());
export { PdfBorderEffect };
/**
 * Holds rendering parameters used for painting annotation appearances.
 *
 * @private
 */
var _PaintParameter = /** @class */ (function () {
    function _PaintParameter() {
        this.borderWidth = 1;
    }
    return _PaintParameter;
}());
export { _PaintParameter };
/**
 * Represents a cloud arc segment used for cloudy border rendering.
 *
 * @private
 */
var _CloudStyleArc = /** @class */ (function () {
    function _CloudStyleArc() {
        this.startAngle = 0;
        this.endAngle = 0;
    }
    return _CloudStyleArc;
}());