Skip to content

API Reference

This generated reference is the public TypeScript contract exported by @muhammara/wasm. It is useful for finding signatures, overloads, and option fields. Behavioral guidance is covered by the curated API pages.

Recipe Methods

The high-level Recipe method reference below is generated from the runtime JSDoc. Its named parameter and result types refer to the declarations that follow it.

Recipe

Kind: global class


new Recipe([sourceOrOptions], [options])

Creates a byte-first high-level PDF Recipe. Pass PDF bytes as the first argument to modify an existing document, or pass only options to create a new document. For Blob or File input, await arrayBuffer() and pass the resulting bytes to the constructor.

Throws:

  • TypeError If Recipe options are not an object.
  • Error If password-protected input is requested or the PDF cannot be created.

Params

  • [sourceOrOptions] ByteSource | RecipeOptions = {} - Source PDF bytes or creation options.
  • [options] RecipeOptions = {} - Options used when modifying source bytes.

recipe.position ⇒ Object

The last moveTo or lineTo path position in Recipe coordinates.

Kind: instance property of Recipe
Returns: Object - A copy of the position.


recipe.readAsync(bytes) ⇒ Promise.<RecipeMetadata>

Asynchronously inspects PDF bytes without changing this Recipe's output. Blob and File inputs are accepted in addition to synchronous byte sources.

Kind: instance method of Recipe
Returns: Promise.<RecipeMetadata> - One-based page geometry and the page count.
Throws:

  • TypeError If the source cannot be normalized to bytes.
  • Error If the bytes cannot be opened as a PDF.

Params

  • bytes AsyncByteSource - PDF bytes or a blob-like source.

recipe.dispose() ⇒ void

Releases this Recipe's writer and native WebAssembly state. The instance must not be used after disposal. Registered static assets remain available until disposeAssets is called.

Kind: instance method of Recipe


recipe.register(key, [callback]) ⇒ Recipe

Adds a named extension method to all Recipe instances. The callback executes with the Recipe as this. Existing Recipe methods cannot be replaced through this API.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If no method name or callback is available.
  • Error If the method name already exists.

Params

  • key string | RecipeExtension - Method name, or a named callback.
  • [callback] RecipeExtension - Extension implementation when a name is supplied.

recipe.htmlToTextObjects(html, [options]) ⇒ Array.<RecipeHtmlTextObject>

Converts supported DOM-free HTML into styled Recipe text fragments. Ordered and unordered list fragments include their visual prefix and native-style indentation. Unlike native's nested XML-derived layout tree, Wasm returns flat visual fragments. This helper does not draw content or alter Recipe state.

Kind: instance method of Recipe
Returns: Array.<RecipeHtmlTextObject> - Styled fragments in source order.
Params

  • html string - HTML source to convert.
  • [options] Partial.<RecipeTextOptions> - Initial text options.

recipe.setPageBox(box, left, bottom, right, top) ⇒ Recipe

Sets a page boundary using native PDF bottom-left coordinates. Changing the media box also updates active Recipe page dimensions.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • RangeError If box is not a supported page-box constant.
  • Error If the underlying PDF operation fails.

Params

  • box PDFPageBoxType | PageBox - Page-box constant or PageBox name.
  • left number - Left PDF coordinate.
  • bottom number - Bottom PDF coordinate.
  • right number - Right PDF coordinate.
  • top number - Top PDF coordinate.

recipe.rotate(rotation) ⇒ Recipe

Sets the active page's rotation in degrees. The page metadata is updated so later Recipe-coordinate operations account for the rotation.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If no page is active or rotation is not a number.
  • RangeError If rotation is not a multiple of 90.
  • Error If the active page was opened with editPage(), or the underlying PDF operation fails.

Params

  • rotation number - Page rotation in degrees, a multiple of 90.

recipe.rotateContent(degrees, [x], [y]) ⇒ Recipe

Rotates subsequent content around a point in Recipe coordinates. Positive angles rotate counter-clockwise on the page, as in native Recipe; the rotation option of shapes, text, and images turns clockwise instead. The transformation remains active until the current graphics state is restored or the page ends.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no active page or the PDF operation fails.

Params

  • degrees number - Counter-clockwise rotation angle in degrees.
  • [x] number | string = 0 - Horizontal rotation origin, or center.
  • [y] number | string = 0 - Vertical rotation origin, or center.

recipe.lineStyle([options]) ⇒ Recipe

Sets defaults for subsequent line and shape drawing. When a page context is active, supplied values are applied immediately; omitted values preserve the stored style.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If a dash pattern containing non-finite values is applied to an active page context.
  • RangeError If miterLimit is not a number of at least 1.
  • Error If the underlying PDF operation fails.

Params

  • [options] RecipeLineStyleOptions - Width, cap, join, miter, and dash settings.

recipe.opacity(value) ⇒ Recipe

Sets fill and stroke opacity for subsequent drawing.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • RangeError If the value is not finite or outside 0 through 1.
  • Error If the underlying PDF operation fails.

Params

  • value number - Opacity from 0 (transparent) through 1 (opaque).

recipe.registerFont(name, bytes, [type]) ⇒ Recipe

Registers font bytes globally and makes them available to this Recipe.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If the name or bytes are invalid.

Params

  • name string - Non-empty font family name.
  • bytes ByteSource - Font bytes.
  • [type] RecipeFontStyle = "regular" - Font family style.

recipe.registerFontAsync(name, bytes, [type]) ⇒ Promise.<Recipe>

Asynchronously registers font bytes and makes them available to this Recipe.

Kind: instance method of Recipe
Returns: Promise.<Recipe> - The Recipe instance after registration.
Throws:

  • TypeError If the name or bytes are invalid.

Params

  • name string - Non-empty font family name.
  • bytes AsyncByteSource - Font bytes or a blob-like source.
  • [type] RecipeFontStyle = "regular" - Font family style.

recipe.split([prefix]) ⇒ Array.<RecipeSplitResult>

Finishes this Recipe and splits it into one-page PDF byte arrays. Calling this method ends the Recipe; result names use one-based page numbers.

Kind: instance method of Recipe
Returns: Array.<RecipeSplitResult> - One result per page in source order.
Throws:

  • Error If the Recipe cannot be finished or split.

Params

  • [prefix] string = "\"page\"" - Prefix for each output filename.

recipe.link(url, x, y, width, height) ⇒ Recipe

Adds a clickable URL link rectangle to the active page. Coordinates use Recipe's top-left origin.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no active page or the underlying PDF operation fails.
  • TypeError If the URL is not a string or the rectangle is not finite.

Params

  • url string - ASCII URL to open; percent-encode non-ASCII path or query text.
  • x number | string - Left coordinate in Recipe coordinates, or center.
  • y number | string - Top coordinate in Recipe coordinates, or center.
  • width number - Link width; a negative width extends leftward.
  • height number - Link height; a negative height extends upward.

recipe.comment(text, x, y, [options]) ⇒ Recipe

Queues a text comment annotation on the active page. Coordinates use Recipe's top-left origin.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no active page or a flag is unknown.
  • TypeError If the options cannot form a valid PDF annotation.

Params

  • text string - Comment contents.
  • x RecipeCoordinate - Left coordinate in Recipe coordinates.
  • y RecipeCoordinate - Top coordinate in Recipe coordinates. Like rectangle() and link(), (x, y) is the annotation rectangle's top-left corner, and the rectangle extends options.height down from it.
  • [options] RecipeAnnotationOptions = {} - Annotation options. The text argument supplies the contents and the default icon is Comment.

recipe.annot(x, y, subtype, [options]) ⇒ Recipe

Queues an annotation on the active page. Coordinates use Recipe's top-left origin; center centers that axis.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no active page or a flag is unknown.
  • TypeError If subtype is not a non-empty string or the options cannot form a valid PDF annotation.

Params

  • x RecipeCoordinate - Left coordinate in Recipe coordinates.
  • y RecipeCoordinate - Top coordinate in Recipe coordinates.
  • subtype string - PDF annotation subtype.
  • [options] RecipeAnnotationOptions = {} - Annotation appearance, contents, replies, dimensions, flags, and rotation handling.

recipe.chroma(name, value, [colorspace]) ⇒ Recipe

Registers a named color for later use by Recipe drawing methods.

Array components use values from 0 through 255. Hex strings may start with #, and percentage strings may start with %. An empty name is a no-op. A name registered for the separation colorspace draws as a Separation (spot) color whose alternate device color is value. WebAssembly does not support loading color files.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • TypeError If the color value has an invalid size or the color space is unknown.
  • Error If name is !load.

Params

  • name string - The name to register.
  • value RecipeColor - A gray, RGB, or CMYK color value; for a separation color, its alternate device color.
  • [colorspace] RecipeColorSpace - The color space, inferred from the value when omitted.

recipe.appendPage(name, [pages]) ⇒ Recipe

Appends selected pages from a registered PDF. Page numbers and inclusive range endpoints are one-based. Omit pages to append every page; endpoints beyond the source are clamped to its final page. Appended pages immediately become part of the output and page metadata. An active page is finished first, so appended pages follow it in the output.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If no PDF is registered under name or appending fails.
  • RangeError If a selection is not a positive integer or a two-value range in ascending order.

Params

  • name string - Registered PDF name.
  • [pages] RecipePageSelection = [] - A one-based page number or an array of page numbers and inclusive ranges. Ranges must be nested, so [1, 3] selects pages 1 and 3 while [[1, 3]] selects pages 1 through 3.

recipe.overlay(name, [x], [y], [options]) ⇒ Recipe

Draws a page from a registered PDF over the active page. Coordinates use Recipe's top-left origin. The overlay is written into the active page content.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If no PDF is registered under name or drawing fails.

Params

  • name string - Registered PDF name.
  • [x] number | RecipeOverlayOptions = 0 - Left coordinate in Recipe coordinates, or options for the two-argument form.
  • [y] number | RecipeOverlayOptions = 0 - Top coordinate in Recipe coordinates, or options when x is supplied.
  • [options] RecipeOverlayOptions = {} - Source page, scale, aspect ratio, and page-fitting options. Source page numbers are one-based.

recipe.insertPage(afterPageNumber, name, sourcePageNumber) ⇒ Recipe

Schedules a page from a registered PDF for insertion in the output. afterPageNumber is zero to insert before the first page, or a one-based output page number. sourcePageNumber is one-based. The insertion is deferred until endPDF() rebuilds the output.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If afterPageNumber is not a non-negative integer.
  • TypeError If the PDF is not registered or the source page is not a positive integer.

Params

  • afterPageNumber number - Output position after which to insert.
  • name string - Registered source PDF name.
  • sourcePageNumber number - One-based source page number.

recipe.endPDF([callback]) ⇒ Uint8Array

Finishes the Recipe and returns its PDF bytes. An active page is finished first, so a forgotten endPage does not cost that page. Deferred page insertions rebuild the document and configured encryption is applied. Repeated calls return cached finished bytes.

Kind: instance method of Recipe
Returns: Uint8Array - Finished PDF bytes.
Throws:

  • TypeError If callback is supplied but is not a function.
  • Error If a page is still active while pages are marked for deletion, or a PDF operation fails.

Params

  • [callback] function - Callback invoked with the same finished bytes that are returned.

recipe.structure([format]) ⇒ string | RecipeStructure

Reports basic structure for the finished PDF. Calling this method finishes the Recipe via endPDF().

Kind: instance method of Recipe
Returns: string | RecipeStructure - A text summary, or structured page, encryption, and indirect-object counts for JSON output.
Throws:

  • Error If the Recipe cannot be finished.

Params

  • [format] RecipeStructureFormat = "string" - Output format.

recipe.image(name, x, y, [options]) ⇒ Recipe

Places a previously registered image or PDF page on the active page.

(x, y) uses Recipe's top-left coordinate system. Width and height default to the source dimensions; scale wins over both, specifying one dimension preserves aspect ratio, and specifying both fits within that box unless disabled. A name registered with registerPdf() places the page that the one-based page selects, sized by its media box. fill, stroke, or color frame the final image box, beneath and above the image. A link option covers the final image bounds.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If the image name is unknown or no target page is available.
  • RangeError If page is not an integer from 1 to 4294967296, a size is not a finite number, or miterLimit is not a number of at least 1.
  • TypeError If the colorspace is unknown, rotation is not a finite number, or the removed zero-based index option is given.

Params

  • name string - The name used when the image or PDF bytes were registered.
  • x number | string - The horizontal placement coordinate in points, or center.
  • y number | string - The vertical placement coordinate in points, or center.
  • [options] RecipeImageOptions - Image sizing, alignment, page-index, frame, and transformation options.

recipe.info([options]) ⇒ Recipe | Record.<string, unknown>

Gets the document information dictionary or sets information entries. Array values are written as comma-and-space-separated text; custom key spelling is preserved.

Kind: instance method of Recipe
Returns: Recipe | Record.<string, unknown> - The Recipe instance when setting entries, otherwise a copy of the current information.
Params

  • [options] Record.<string, unknown> - Information entries to set. Omit this argument to return a copy of the current information.

recipe.custom(key, value) ⇒ Recipe

Sets a custom document information entry.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Params

  • key string - Information dictionary key.
  • value unknown - Value converted to text for the PDF.

recipe.createPage([width], [height], [margins]) ⇒ Recipe

Creates and activates a page, using dimensions in PDF points. Named sizes are case-insensitive and fall back to the configured default; a rotation not divisible by 180 swaps the named size's width and height. The new page uses Recipe's top-left coordinate system, with x increasing rightward and y increasing downward, and resets the cursor to (0, 0).

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If the PDF has already been ended.
  • Error If another page is still active; call endPage() first.

Params

  • [width] number | string - Page width, or a named page size.
  • [height] number - Page height, or rotation for a named size.
  • [margins] RecipeMargins - Margins for the new page.

recipe.endPage() ⇒ Recipe

Finishes the active new or edited page and flushes its annotations. Calling this method without an active page has no effect. The active page dimensions are cleared, so page drawing must resume on another active page.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.


recipe.margins([left], [right], [top], [bottom]) ⇒ Recipe | Required.<RecipeMargins>

Gets or updates the margins used by implicit positioning and layout. Margins are measured inward in PDF points from the page edges in Recipe's top-left coordinate system. Omitted values retain their current settings.

Kind: instance method of Recipe
Returns: Recipe | Required.<RecipeMargins> - The Recipe instance when a margin changes; otherwise a copy of the current margins.
Params

  • [left] number | RecipeMargins - Left margin, or margins to update.
  • [right] number - Right margin.
  • [top] number - Top margin.
  • [bottom] number - Bottom margin.

recipe.pageInfo(pageNumber) ⇒ RecipePageInfo | null

Returns geometry for a one-based page number without changing active state. Width and height follow Recipe's rotated, top-left coordinate space; mediaBox remains the page's native PDF rectangle.

Kind: instance method of Recipe
Returns: RecipePageInfo | null - A defensive copy of the page geometry, or null when the page does not exist.
Params

  • pageNumber number - One-based page number.

recipe.getPageInfo() ⇒ Record.<string, unknown> | InfoDictionary

Returns the document information dictionary without changing page state. This method reports PDF metadata, not Recipe-coordinate page geometry; use pageInfo or getCurrentPageInfo for geometry.

Kind: instance method of Recipe
Returns: Record.<string, unknown> | InfoDictionary - The current document information dictionary.


recipe.getCurrentPageInfo() ⇒ RecipePageInfo | null

Returns geometry for the active or most recently known Recipe page. Width and height follow Recipe's rotated, top-left coordinate space; mediaBox remains the page's native PDF rectangle. No state is changed.

Kind: instance method of Recipe
Returns: RecipePageInfo | null - A defensive copy of the page geometry, or null when no page is known.


recipe.read(bytes) ⇒ RecipeMetadata

Inspects a PDF without replacing or otherwise changing this Recipe's output state. Reported page width and height use Recipe's rotated, top-left coordinate space, while each mediaBox is the native PDF rectangle.

Kind: instance method of Recipe
Returns: RecipeMetadata - Page count and one-based page geometry records.
Throws:

  • Error If the bytes cannot be opened as a PDF.

Params

  • bytes ByteSource - PDF bytes to inspect synchronously.

recipe.editPage(pageNumber) ⇒ Recipe

Starts a prepend-safe content context for an existing one-based page. Drawing uses Recipe's top-left coordinates, including the page's rotation; the cursor moves to the configured left and top margins. The edit remains active until endPage is called.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If the Recipe was not constructed from PDF bytes or another page is active.
  • RangeError If pageNumber does not identify an existing page.

Params

  • pageNumber number - One-based page number to edit.

recipe.deletePage(pageNumbers, [options]) ⇒ Recipe

Deletes one or more pages from an existing PDF. Page numbers are one-based and refer to the original source document.

By default a page that retained structures still reference - outline items, link annotations and named destinations, form widgets, tagged-PDF structure elements or the open action - cannot be deleted. With pruneReferences, those references are removed instead: a destination that targets a deleted page becomes null (so outline items keep their title and children, and links do nothing), and every other direct reference to a deleted page is dropped. Pruning applies to every queued deletion once any deletePage() call enables it.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If options is not an object or pruneReferences is not a boolean.
  • RangeError If a page number does not identify an original page.
  • Error If the Recipe has no existing source, has ended or was disposed, would delete every page, combines deletion with page composition, or the page tree, page labels or retained references cannot be rewritten. A failed call leaves the queued deletions unchanged.

Params

  • pageNumbers number | Array.<number> - Page number or page numbers to delete.
  • [options] object - Deletion options.
  • [.pruneReferences] boolean = false - Remove references to the deleted pages from retained structures instead of refusing the deletion.

recipe.pauseContext() ⇒ Recipe

Pauses the active created-page or edited-page content context. Page editing remains active, and a later resume restores the page's rotated, top-left Recipe coordinate transform.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no active page content context.

recipe.resumeContext() ⇒ Recipe

Resumes a paused created-page or edited-page content context. The page rotation transform is reapplied so subsequent drawing continues in Recipe's top-left coordinate system.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If there is no paused page content context.

recipe.replaceText(text, replacement, pageNumber) ⇒ Recipe

Replaces text shown with Tj in a page's single content stream. Each operand is decoded through the font selected by Tf (its /ToUnicode CMap, then its /Encoding and /Differences), and a match is compared with text. The replacement is encoded through the same font and written back as a literal or hex string, like the original operand. Only whole Tj operands match; TJ, ', and " operands and text split across operators are left unchanged. No match leaves the page unchanged.

The replacement can only use glyphs the font already has. Embedded subset fonts usually carry just the glyphs of their original text.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If text or replacement is not a string, or if the page number is not a positive integer.
  • RangeError If the source document has no such page.
  • Error If the page does not have one indirect content stream, or the matched font cannot be read, has a malformed /Widths array, or has no glyph for a replacement character.

Params

  • text string - Text to replace.
  • replacement string - Replacement text.
  • pageNumber number - One-based page number.

recipe.removeText(pageNumber, [options]) ⇒ Recipe

Removes all shown text from a page, for example before placing a fresh OCR text layer. Text-showing operators (Tj, TJ, ', ") are dropped; graphics, images, and text state are kept. Annotation appearances are not changed.

The page's source content streams are rewritten in place, so a stream shared with another page loses its text there too. Content added with editPage() in the same Recipe is kept.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If the page number is not a positive integer, or the options are not an object.
  • RangeError If the source document has no such page.
  • Error If the page's Contents holds a direct stream.

Params

  • pageNumber number - One-based page number.
  • [options] RemoveTextOptions - Removal options.
  • [.forms] boolean = false - Also remove text from the Form XObjects the page paints, including nested forms. Other pages that paint the same form lose that text too.

recipe.permission([flags]) ⇒ number

Converts comma-separated PDF permission names to a user-protection bitmask.

Kind: instance method of Recipe
Returns: number - Numeric PDF user-protection flags.
Throws:

  • Error If a permission name is unknown.

Params

  • [flags] RecipePermission = "print" - Permission names separated by commas.

recipe.encrypt([options]) ⇒ Recipe

Configures encryption for the finished PDF.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • TypeError If options is not a non-array object.
  • Error If the Recipe has already been finished.

Params

  • [options] RecipeEncryptOptions = {} - Owner and user passwords and numeric user-protection flags. Supplying only an owner password permits printing by default.

recipe.n_gon(cx, cy, radius, [sides], [options]) ⇒ Recipe

Draws a regular polygon centered at (cx, cy).

Coordinates use Recipe's top-left origin and require an active page. The side count is clamped to at least three. Passing options in place of sides draws a triangle.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.
  • RangeError If sides is not a finite number or exceeds 100000.

Params

  • cx number - The center X coordinate in points.
  • cy number - The center Y coordinate in points.
  • radius number - The center-to-vertex radius in points.
  • [sides] number | RecipeNGonOptions = 3 - The side count, or options for a triangle.
  • [options] RecipeNGonOptions - Polygon and rotation-vertex options.

recipe.star(cx, cy, radius, [points], [options]) ⇒ Recipe

Draws a star centered at (cx, cy).

Coordinates use Recipe's top-left origin and require an active page. The point count is clamped to at least five. Passing options in place of points draws a five-pointed star.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.
  • RangeError If points is not a finite number or exceeds 100000.

Params

  • cx number - The center X coordinate in points.
  • cy number - The center Y coordinate in points.
  • radius number - The center-to-point radius in points.
  • [points] number | RecipePathOptions = 5 - The point count, or path options for a five-pointed star.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.arrow(x, y, [options]) ⇒ Recipe

Draws an arrow positioned at (x, y).

Coordinates use Recipe's top-left origin and require an active page. By default the position identifies the arrow's center; at can anchor it at its head or tail. Rotation uses (x, y) as its origin when anchored.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number - The horizontal anchor coordinate in points.
  • y number - The vertical anchor coordinate in points.
  • [options] RecipeArrowOptions - Arrow geometry and path options.

recipe.triangle(x, y, traits, [options]) ⇒ Recipe

Draws a triangle from three defining traits.

Coordinates use Recipe's top-left origin and require an active page. Traits can describe three sides, side-angle-side, angle-side-angle, or three vertices as selected by traitID. Angles are expressed in degrees.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If traits do not contain three values or do not define a valid triangle.
  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number - The horizontal position coordinate in points.
  • y number - The vertical position coordinate in points.
  • traits Array.<number> | Array.<Array.<number>> - Three side/angle values or three coordinate pairs.
  • [options] RecipeTriangleOptions - Triangle definition, positioning, and path options.

recipe.table(x, y, contents, [options]) ⇒ Recipe

Draws records as a table on the active page. x and y are PDF points in Recipe's top-left coordinate system, where x increases rightward and y increases downward. Columns follow order, then the configured columns, then every field found in any record. Missing and nullish values render as empty cells. Rows are measured with their final cell options, including renderer results, before drawing; each renderer runs once per cell. Optional overflow handling can continue at another Recipe position, and the cursor finishes at the table's left edge and bottom. Empty contents or no selected columns leave the Recipe unchanged. Array-form order preserves exact field names. Measurements include padding, minimum heights, fixed heights, and HTML layout. Overflow callbacks receive the Recipe as this and the first argument; rows are not split across continuation areas. Header text styles are independent of body styles: column header options (or defaults) are overridden by table header options, then alignToData and column hcell box overrides are applied, matching native Recipe.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • Error If table text cannot be measured or drawn, including when a requested font cannot be loaded.
  • RangeError If an overflow callback continues into an area too small for the pending row and its repeated header. Return true to stop, or provide enough space; the callback is called once per overflow.
  • Error If an overflow callback continues after ending the page without starting another one.

Params

  • x number - Left table coordinate.
  • y number - Top table coordinate.
  • contents Array.<RecipeTableRow> - Records to render as rows.
  • [options] RecipeTableOptions - Column, row, header, border, text, and overflow options.

recipe.textDimensions(value, [options]) ⇒ TextDimensions

Measures text in PDF points using the selected font and character spacing. The configured Recipe font is used when options.font is omitted. This method does not draw text or change the cursor; returned bounds use font metric coordinates rather than Recipe page coordinates.

Kind: instance method of Recipe
Returns: TextDimensions - Text bounds and dimensions in PDF points.
Throws:

  • RangeError If fontSize, or its size alias, is given and is not greater than zero.
  • Error If the requested font is not registered or cannot be loaded.

Params

  • value string - Text to measure.
  • [options] RecipeTextOptions - Font and measurement options.

recipe.layout(id, [x], [y], [width], [height], [options]) ⇒ Recipe

Defines named columns for flowing text or table placement. Coordinates and dimensions are PDF points in Recipe's top-left coordinate system, where x increases rightward and y increases downward. Zero values use the corresponding page margin or available page extent. The layout is stored under id; options.reset discards columns previously stored there.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Params

  • id string | number - Layout identifier used by text flow.
  • [x] number = 0 - Left position; zero uses the left margin.
  • [y] number = 0 - Top position; zero uses the top margin.
  • [width] number = 0 - Layout width; zero uses the available width.
  • [height] number = 0 - Layout height; zero uses the available height.
  • [options] RecipeLayoutOptions - Column definitions and reset behavior.

recipe.movedown([count], [returnCoords]) ⇒ Recipe | RecipePosition

Moves the text cursor downward by a number of line heights. Movement is in Recipe's top-left coordinate system and resets x to the current text box origin when one exists. The current line height defaults to 14 points until text has established another value.

Inside an open flow it ends the current line instead, even for a count of 0, and leaves count - 1 empty lines; the flow continues below them. The cursor does not move until the flow is drawn, so the coordinates are the flow's origin, as in native.

Kind: instance method of Recipe
Returns: Recipe | RecipePosition - The Recipe instance, or the new [x, y] coordinates; inside a flow, the flow's origin.
Params

  • [count] number = 1 - Number of line heights to move.
  • [returnCoords] boolean = false - Return the new coordinates instead of the Recipe instance.

recipe.text([value], [x], [y], [options]) ⇒ Recipe

Draws text on the active page and advances the Recipe text cursor. Explicit x and y values are PDF points in Recipe's top-left coordinate system, where x increases rightward and y increases downward. When they are omitted, drawing starts at the cursor or margins. Text boxes, flow, HTML styling, links, highlighting, clipping, and named layouts are controlled by RecipeTextOptions.

With flow: true, later calls without coordinates continue the line where the previous run ended and wrap with it in one text box, as in native. A call without coordinates flows unless it passes flow: false. The flow is laid out when a call passes flow: false, or when a call with coordinates, table(), or endPage() follows.

Kind: instance method of Recipe
Returns: Recipe - The Recipe instance.
Throws:

  • RangeError If fontSize, or its size alias, is given and is not greater than zero, or miterLimit is not a number of at least 1.
  • TypeError If rotation or charSpace is not a finite number.
  • Error If a requested overflow layout is undefined, text clipping cannot be applied, or a requested font cannot be loaded.
  • Error If a flow is started without an active page.

Params

  • [value] string = "''" - Text or supported HTML source to draw.
  • [x] number | RecipeTextOptions - Left coordinate, or options when coordinates are omitted.
  • [y] number - Top coordinate.
  • [options] RecipeTextOptions - Text and layout options.

recipe.moveTo(x, y) ⇒ Recipe

Moves the current path position without drawing.

Coordinates use Recipe's top-left origin and require an active page.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available.

Params

  • x number - The horizontal coordinate in points.
  • y number - The vertical coordinate in points.

recipe.lineTo(x, y, [options]) ⇒ Recipe

Adds a line from the current path position to a point.

Coordinates use Recipe's top-left origin and require an active page. If options are supplied, the line is painted immediately; otherwise it is appended to the current path. The current path position becomes (x, y).

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number - The destination horizontal coordinate in points.
  • y number - The destination vertical coordinate in points.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.line(startX, startY, [endX], [endY], [options]) ⇒ Recipe

Draws a line through two or more points.

Pass either an array of coordinate pairs followed by options, or four coordinates followed by options. Coordinates use Recipe's top-left origin and require an active page. Lines are always stroked, never filled.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance. With fewer than two coordinate pairs nothing is drawn, as in native; a single pair only moves the current position.
Throws:

  • TypeError If the color space is unknown.
  • Error If no target page is available or an unsupported color is requested.

Params

  • startX number | Array.<Array.<number>> - The start X coordinate, or all coordinate pairs.
  • startY number | RecipePathOptions - The start Y coordinate, or options for the array form.
  • [endX] number - The end X coordinate in the numeric form.
  • [endY] number - The end Y coordinate in the numeric form.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.polygon(coordinates, [options]) ⇒ Recipe

Draws a closed polygon through the supplied points.

Coordinates use Recipe's top-left origin and require an active page. A link option creates an annotation over the polygon's bounding rectangle.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • TypeError If fewer than two coordinate pairs are supplied or the color space is unknown.
  • Error If no target page is available or an unsupported color is requested.

Params

  • coordinates Array.<Array.<number>> - Two or more [x, y] coordinate pairs.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.rectangle(x, y, width, height, [options]) ⇒ Recipe

Draws a rectangle.

(x, y) is the top-left corner in Recipe coordinates. Set useGivenCoords to use native PDF bottom-left coordinates instead. An active page is required.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number | string - The horizontal corner coordinate in points, or center.
  • y number | string - The vertical corner coordinate in points, or center.
  • width number - The rectangle width in points.
  • height number - The rectangle height in points.
  • [options] RecipeRectangleOptions - Rectangle path, rounded-corner, and transformation options.

recipe.circle(x, y, radius, [options]) ⇒ Recipe

Draws a circle centered at (x, y) in Recipe's top-left coordinate system.

An active page is required. A link option covers the circle's bounding box.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number | string - The center X coordinate in points, or center for the page center.
  • y number | string - The center Y coordinate in points, or center for the page center.
  • radius number - The radius in points.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.ellipse(cx, cy, rx, ry, [options]) ⇒ Recipe

Draws an ellipse centered at (cx, cy) in Recipe's top-left coordinate system.

An active page is required. A link option covers the ellipse's bounding box.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • cx number | string - The center X coordinate in points, or center for the page center.
  • cy number | string - The center Y coordinate in points, or center for the page center.
  • rx number - The horizontal radius in points.
  • ry number - The vertical radius in points.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.arc(x, y, radius, [startAngle], [endAngle], [options]) ⇒ Recipe

Draws a circular arc centered at (x, y).

Coordinates use Recipe's top-left origin. Angles are degrees measured clockwise; negative values run counterclockwise. An active page is required.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number | string - The center X coordinate in points, or center for the page center.
  • y number | string - The center Y coordinate in points, or center for the page center.
  • radius number - The radius in points.
  • [startAngle] number = 0 - The starting angle in degrees.
  • [endAngle] number = 360 - The ending angle in degrees.
  • [options] RecipeArcOptions - Arc path, sector, and transformation options.

recipe.pie(x, y, radius, [startAngle], [endAngle], [options]) ⇒ Recipe

Draws a closed circular sector centered at (x, y).

Coordinates use Recipe's top-left origin. Angles are degrees measured clockwise; negative values run counterclockwise. An active page is required.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Throws:

  • Error If no target page is available or an unsupported color is requested.
  • TypeError If the requested color space is unknown.

Params

  • x number | string - The center X coordinate in points, or center for the page center.
  • y number | string - The center Y coordinate in points, or center for the page center.
  • radius number - The radius in points.
  • [startAngle] number = 0 - The starting angle in degrees.
  • [endAngle] number = 360 - The ending angle in degrees.
  • [options] RecipePathOptions - Path painting and transformation options.

recipe.lineWidth(width) ⇒ Recipe

Sets the default line width for subsequent Recipe paths.

This updates the stored graphics state and applies it immediately when a page context is active.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.
Params

  • width number - The line width in points.

recipe.fill() ⇒ Recipe

Compatibility method for filling the current path; currently a no-op.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.


recipe.stroke() ⇒ Recipe

Compatibility method for stroking the current path; currently a no-op.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.


recipe.fillAndStroke() ⇒ Recipe

Compatibility method for filling and stroking the current path; currently a no-op.

Kind: instance method of Recipe
Returns: Recipe - The recipe instance.


Recipe.splitPdf(name, [prefix]) ⇒ Array.<RecipeSplitResult>

Splits a registered PDF into one-page PDF byte arrays. Output names and source page traversal use one-based page numbers. This does not modify an existing Recipe; each result is separately built and finished.

Kind: static method of Recipe
Returns: Array.<RecipeSplitResult> - One result per source page, in page order.
Throws:

  • Error If no PDF is registered under name, the PDF cannot be parsed, or an output PDF cannot be created.

Params

  • name string - Registered PDF name.
  • [prefix] string = "\"page\"" - Prefix used for each output filename.

Recipe.inspectPdf(name) ⇒ RecipePdfInspection

Inspects metadata and page geometry for a registered PDF. Numeric page records are keyed by one-based page numbers. Page dimensions use Recipe's top-left coordinate orientation and account for page rotation. Inspection does not change any Recipe output state.

Kind: static method of Recipe
Returns: RecipePdfInspection - PDF level, encryption status, page count, and one-based page records.
Throws:

  • Error If no PDF is registered under name, the PDF cannot be parsed, or page information cannot be read.

Params

  • name string - Registered PDF name.

Recipe.thirdPartyLicenses(source) ⇒ Promise.<string>

Returns the third-party license notices embedded in a muhammara-wasm.wasm as its license custom section. The runtime does not keep the binary it was loaded from, so pass the same binary: a URL, which is fetched, or its bytes or a Blob/File. The section is read from the bytes without compiling them.

Kind: static method of Recipe
Returns: Promise.<string> - The notices, Markdown, identical to @muhammara/wasm/THIRD_PARTY_LICENSES.md.
Throws:

  • TypeError If source is not a URL, bytes, or a Blob/File, or a file: URL cannot be fetched.
  • Error If the URL cannot be loaded, the bytes are not a WebAssembly module, or it has no license section (for example after wasm-strip).

Params

  • source ThirdPartyLicensesSource - The binary whose notices to return.

Recipe.registerFont(name, bytes, [type]) ⇒ void

Registers font bytes under a name and style for future Recipe instances. Registering the same name and style replaces and removes the prior asset.

Kind: static method of Recipe
Throws:

  • TypeError If the name is empty or the bytes are unsupported.

Params

  • name string - Non-empty font family name used by Recipe text.
  • bytes ByteSource - Font bytes.
  • [type] RecipeFontStyle = "regular" - Font family style.

Recipe.registerFontAsync(name, bytes, [type]) ⇒ Promise.<void>

Asynchronously registers a font for future Recipe instances. Registering the same name and style replaces and removes the prior asset.

Kind: static method of Recipe
Returns: Promise.<void> - Resolves after the font is registered.
Throws:

  • TypeError If the name is empty or the bytes are unsupported.

Params

  • name string - Non-empty font family name used by Recipe text.
  • bytes AsyncByteSource - Font bytes or an asynchronous byte source.
  • [type] RecipeFontStyle = "regular" - Font family style.

Recipe.registerImage(name, bytes, extension) ⇒ void

Registers image bytes under a name for future Recipe instances. Registering the same name replaces and removes the prior asset.

Kind: static method of Recipe
Throws:

  • TypeError If the bytes are unsupported or the extension is not a supported JPEG, PNG, or TIFF extension.

Params

  • name string - Image name used by Recipe#image.
  • bytes ByteSource - Image bytes.
  • extension string - Image filename extension.

Recipe.registerImageAsync(name, bytes, extension) ⇒ Promise.<void>

Asynchronously registers an image for future Recipe instances. Registering the same name replaces and removes the prior asset.

Kind: static method of Recipe
Returns: Promise.<void> - Resolves after the image is registered.
Throws:

  • TypeError If the bytes are unsupported or the extension is not a supported JPEG, PNG, or TIFF extension.

Params

  • name string - Image name used by Recipe#image.
  • bytes AsyncByteSource - Image bytes or an asynchronous byte source.
  • extension string - Image filename extension.

Recipe.registerPdf(name, bytes) ⇒ void

Registers PDF bytes under a name for composition, inspection, and image(). Registering the same name replaces and removes the prior asset.

Kind: static method of Recipe
Throws:

  • TypeError If the bytes are unsupported.

Params

  • name string - PDF name used by composition, inspection, and image().
  • bytes ByteSource - PDF bytes.

Recipe.registerPdfAsync(name, bytes) ⇒ Promise.<void>

Asynchronously registers a PDF for composition and inspection. Registering the same name replaces and removes the prior asset.

Kind: static method of Recipe
Returns: Promise.<void> - Resolves after the PDF is registered.
Throws:

  • TypeError If the bytes are unsupported.

Params

  • name string - PDF name used by composition and inspection methods.
  • bytes AsyncByteSource - PDF bytes or an asynchronous byte source.

Recipe.unregisterFont(name, [type]) ⇒ boolean

Removes one registered font style.

Kind: static method of Recipe
Returns: boolean - Whether a matching registered style was removed.
Params

  • name string - Registered font family name.
  • [type] RecipeFontStyle = "regular" - Font family style to remove.

Recipe.unregisterImage(name) ⇒ boolean

Removes a registered image.

Kind: static method of Recipe
Returns: boolean - Whether a matching image was removed.
Params

  • name string - Registered image name.

Recipe.unregisterPdf(name) ⇒ boolean

Removes a registered PDF.

Kind: static method of Recipe
Returns: boolean - Whether a matching PDF was removed.
Params

  • name string - Registered PDF name.

Recipe.disposeAssets() ⇒ void

Removes all globally registered Recipe assets.

Kind: static method of Recipe


Recipe.permission([flags]) ⇒ number

Converts comma-separated PDF permission names to a user-protection bitmask.

Kind: static method of Recipe
Returns: number - Numeric PDF user-protection flags.
Throws:

  • Error If a permission name is unknown.

Params

  • [flags] RecipePermission = "print" - Permission names separated by commas.

TypeScript Declarations

/** Browser-only, byte-first WebAssembly API. It intentionally excludes Node paths and streams. */
export interface BlobLike {
  readonly size: number;
  readonly type: string;
  arrayBuffer(): Promise<ArrayBuffer>;
  slice(start?: number, end?: number, contentType?: string): BlobLike;
}
export type ByteSource = Uint8Array | ArrayBuffer | PDFRStreamForBuffer;
export type AsyncByteSource = ByteSource | BlobLike;
/** A `muhammara-wasm.wasm` to read the third-party license notices from. */
export type ThirdPartyLicensesSource = string | URL | AsyncByteSource;
export type PDFRectangle = [
  lowerLeftX: number,
  lowerLeftY: number,
  upperRightX: number,
  upperRightY: number,
];
export type PDFMatrix = [number, number, number, number, number, number];
/** Glyph entries shown without text encoding: `[glyphId, unicodeCodePoint]` pairs. */
export type Glyph = Array<[number, number]>;
/** How text-showing operators encode string text: the `EEncoding` values. */
export type EEncoding = "text" | "code" | "hex";
export declare const EEncoding: {
  readonly TEXT: "text";
  readonly CODE: "code";
  readonly HEX: "hex";
};
/** @deprecated Use `EEncoding`, the native name. */
export type TextEncoding = EEncoding;
export type PageBox = "media" | "crop" | "bleed" | "trim" | "art";
export declare const PageBox: {
  readonly MEDIA: "media";
  readonly CROP: "crop";
  readonly BLEED: "bleed";
  readonly TRIM: "trim";
  readonly ART: "art";
};
export type PDFPageBoxType = 0 | 1 | 2 | 3 | 4;
export type PDFVersion = 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 20;
export type RecryptPDFVersion = 0 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17;
export type RecipePDFVersion =
  | 1
  | 1.1
  | 1.2
  | 1.3
  | 1.4
  | 1.5
  | 1.6
  | 1.7
  | 2
  | 10
  | 11
  | 12
  | 13
  | 14
  | 15
  | 16
  | 17
  | 20;

export interface WriterOptions {
  version?: PDFVersion;
  /** Enables Flate compression for streams. Defaults to true. */
  compress?: boolean;
}
/** `createReader()` options, as in native. */
export interface PDFReaderOptions {
  /** User or owner password that opens an encrypted PDF. */
  password?: string;
}
/** `createWriter()` options, including native's encryption options. */
export interface CreateWriterOptions extends WriterOptions {
  /** Encrypts the PDF with this user password, as in native. PDF 2.0 throws. */
  userPassword?: string;
  /** Owner password of an encrypted PDF; ignored without `userPassword`. */
  ownerPassword?: string;
  /** Permission flags of an encrypted PDF; 4 (print) by default. */
  userProtectionFlag?: number;
}
/** Options accepted by the byte-first equivalent of native `recrypt`. */
export interface PDFRecryptOptions {
  password?: string;
  /** PDF 1.0 through 1.7 encryption version. PDF 2.0/AES-256 is unavailable. */
  version?: RecryptPDFVersion;
  /** Enables Flate compression for streams. Defaults to true. */
  compress?: boolean;
  /** Unsupported filesystem logging option. */
  log?: string;
  userPassword?: string;
  ownerPassword?: string;
  userProtectionFlag?: number;
}
export type RecipeFontStyle =
  "regular" | "bold" | "italic" | "bold-italic" | "r" | "b" | "i" | "bi";
export type RecipeCoordinate = number | "center";
export type RecipePosition = [number, number];
/** Device color space of a drawing or Recipe color option. */
export type DeviceColorSpace = "rgb" | "gray" | "cmyk";
export declare const DeviceColorSpace: {
  readonly RGB: "rgb";
  readonly GRAY: "gray";
  readonly CMYK: "cmyk";
};
/** Device color spaces Recipe draws with in WebAssembly. */
export type RecipeDeviceColorSpace = DeviceColorSpace;
/** How `drawImage()` fits an image: always scale, or only shrink when it overflows. */
export type ImageFit = "always" | "overflow";
export declare const ImageFit: {
  readonly ALWAYS: "always";
  readonly OVERFLOW: "overflow";
};
/**
 * Every Recipe color space. `"separation"` draws a registered name, or a color
 * with `colorName`, as a Separation (spot) color.
 */
export type RecipeColorSpace = RecipeDeviceColorSpace | "separation";
export type RecipePermissionName =
  | "print"
  | "modify"
  | "copy"
  | "edit"
  | "fillform"
  | "extract"
  | "assemble"
  | "printbest";
/** Known permission names with string compatibility for composed flag lists. */
export type RecipePermission = RecipePermissionName | (string & {});
export interface RecipeMargins {
  left?: number;
  right?: number;
  top?: number;
  bottom?: number;
}
export interface RecipeOptions {
  /** PDF version; canonical decimal levels 1.0 through 1.7 and 2.0, and integer enums 10 through 17 and 20, are accepted. */
  version?: RecipePDFVersion;
  /** Enables stream compression. Defaults to true. */
  compress?: boolean;
  author?: string;
  title?: string;
  subject?: string;
  keywords?: string | string[];
  colorspace?: RecipeColorSpace;
  password?: string;
  ownerPassword?: string;
  userPassword?: string;
  userProtectionFlag?: number;
}
export interface RecipeEncryptOptions {
  password?: string;
  ownerPassword?: string;
  userPassword?: string;
  userProtectionFlag?: number;
}
export type RecipeColor = string | readonly number[];
export type RecipeKnownColors = Record<
  RecipeColorSpace,
  Record<string, string>
>;
/** A Recipe extension method; `this` is the Recipe it is called on. */
export type RecipeExtension<
  Arguments extends unknown[] = never[],
  Result = unknown,
> = (this: Recipe, ...args: Arguments) => Result;
export interface RecipePathOptions {
  /** Make the rendered path's bounding rectangle open this URL. */
  link?: string;
  color?: RecipeColor;
  stroke?: RecipeColor;
  fill?: RecipeColor;
  colorspace?: RecipeColorSpace;
  /** The Separation ink name of a `"separation"` color given by value. */
  colorName?: string;
  width?: number;
  lineWidth?: number;
  opacity?: number;
  dash?: readonly number[];
  dashPhase?: number;
  lineCap?: Recipe.LineCap;
  lineJoin?: Recipe.LineJoin;
  miterLimit?: number;
  /** Clockwise rotation in degrees, around `rotationOrigin`, as on native. */
  rotation?: number;
  rotationOrigin?: readonly [number, number];
  skewX?: number;
  skewY?: number;
  /** Draw shape-specific diagnostic geometry. */
  debug?: boolean | number;
}
/**
 * Options of `image()`. `fill`, `stroke`, or `color` frame the drawn image box:
 * the fill beneath the image, the outline above it and inside the box, as a
 * `rectangle()` stroke. The line options style that outline, and `debug`
 * outlines the box in green and marks the placement point in red.
 */
export interface RecipeImageOptions extends RecipePathOptions {
  /** The drawn image width. `lineWidth` sets the frame outline width. */
  width?: number;
  height?: number;
  /** Scale the source size; wins over `width` and `height`. */
  scale?: number;
  keepAspectRatio?: boolean;
  align?: Recipe.ImageAlign;
  /** The one-based page of a registered PDF, or image of a multi-image TIFF, as in `overlay()`; defaults to 1. */
  page?: number;
}
export interface RecipeRectangleOptions extends RecipePathOptions {
  /** Read `x` and `y` as native PDF bottom-left coordinates. */
  useGivenCoords?: boolean;
  borderRadius?:
    | number
    | readonly [number]
    | readonly [number, number]
    | readonly [number, number, number]
    | readonly [number, number, number, number];
}
export interface RecipeArcOptions extends RecipePathOptions {
  sector?: boolean;
}
export interface RecipeNGonOptions extends RecipePathOptions {
  rotationVertice?: number;
}
export type RecipeArrowType = 0 | 1 | 2 | "triangle" | "dart" | "kite";
export type RecipeArrowAnchor = "head" | "tail";
export interface RecipeArrowOptions extends RecipePathOptions {
  head?:
    | number
    | readonly [number]
    | readonly [number, number]
    | readonly [number, number, number];
  shaft?: number | readonly [number] | readonly [number, number];
  double?: boolean;
  type?: RecipeArrowType;
  at?: RecipeArrowAnchor;
}
/**
 * Matches known runtime values in lower case, UPPER CASE, and Capitalized
 * form. The runtime lowercases the whole value, so any casing works there.
 */
export type RecipeCaseInsensitive<Value extends string> =
  Lowercase<Value> | Uppercase<Value> | Capitalize<Lowercase<Value>>;
export type RecipeTriangleTrait = RecipeCaseInsensitive<
  "sss" | "sas" | "asa" | "vtx"
>;
export type RecipeTriangleMeasurementTrait = RecipeCaseInsensitive<
  "sss" | "sas" | "asa"
>;
export type RecipeTriangleVertexTrait = RecipeCaseInsensitive<"vtx">;
export type RecipeTrianglePosition = RecipeCaseInsensitive<
  "a" | "b" | "c" | "centroid" | "circumcenter" | "incenter"
>;
/** Three sides, or sides and angles in degrees, selected by the trait. */
export type RecipeTriangleMeasurements = readonly [number, number, number];
export type RecipeTriangleVertices = readonly [
  readonly [number, number],
  readonly [number, number],
  readonly [number, number],
];
export type RecipeMutableTriangleVertices = [
  [number, number],
  [number, number],
  [number, number],
];
export interface RecipeTriangleBaseOptions extends RecipePathOptions {
  position?: RecipeTrianglePosition;
  flipX?: boolean;
  flipY?: boolean;
}
export type RecipeTriangleMeasurementOptions = RecipeTriangleBaseOptions &
  (
    | {
        traitID: RecipeTriangleMeasurementTrait;
        traitsID?: RecipeTriangleTrait;
      }
    | { traitID?: undefined; traitsID?: RecipeTriangleMeasurementTrait }
  );
export type RecipeTriangleVertexIdentifier =
  | { traitID: RecipeTriangleVertexTrait; traitsID?: RecipeTriangleTrait }
  | { traitID?: undefined; traitsID: RecipeTriangleVertexTrait };
export type RecipeTriangleVertexOptions = RecipeTriangleBaseOptions &
  RecipeTriangleVertexIdentifier;
/** Vertex options for readonly vertices, which cannot be repositioned or flipped. */
export type RecipeTriangleUnpositionedVertexOptions = Omit<
  RecipeTriangleBaseOptions,
  "position" | "flipX" | "flipY"
> & {
  position?: undefined;
  flipX?: false;
  flipY?: false;
} & RecipeTriangleVertexIdentifier;
export type RecipeTriangleOptions =
  RecipeTriangleMeasurementOptions | RecipeTriangleVertexOptions;
export interface RecipeLineStyleOptions {
  width?: number;
  lineWidth?: number;
  cap?: number;
  join?: number;
  miterLimit?: number;
  dash?: readonly number[];
  dashPhase?: number;
}
export interface RecipeAnnotationOptions {
  text?: string;
  contents?: string;
  title?: string;
  subject?: string;
  date?: string | Date;
  icon?: Recipe.AnnotIcon;
  name?: string;
  /** `#rrggbb`, `%r,g,b`, a color registered with `chroma()`, a CSS color name, or one (gray), three (RGB), or four (CMYK) numbers from 0 to 255. Other values throw a `TypeError`. */
  color?: RecipeColor;
  border?: number | { width?: number; dash?: readonly number[] };
  borderWidth?: number;
  borderDash?: readonly number[];
  quadPoints?: readonly number[];
  flag?: Recipe.AnnotFlag | number;
  flags?: number;
  open?: boolean;
  opacity?: number;
  richText?: boolean;
  /** Replies inherit parent metadata; opacity defaults to 1 and richText to false independently. */
  replies?: readonly RecipeAnnotationOptions[];
  followOriginalPageRotation?: boolean;
  width?: number;
  height?: number;
}
export interface RecipeOverlayOptions {
  page?: number;
  scale?: number;
  keepAspectRatio?: boolean;
  fitWidth?: boolean;
  fitHeight?: boolean;
}
/** How a Recipe text box handles text that does not fit its width. */
export interface RecipeTextBox {
  width?: number;
  height?: number;
  minHeight?: number;
  padding?: number | readonly [number, number?, number?, number?];
  lineHeight?: number;
  /** `clip` retains and clips the source, `trim` omits its non-fitting suffix, and `ellipsis` replaces it with `…`. */
  wrap?: boolean | Recipe.TextWrap;
  textAlign?: Recipe.TextBoxAlign;
  /** Render only complete lines that fit within this fixed-height text box. */
  clipIfExceedsBox?: boolean;
  /** Called after clipping leaves source text unrendered. */
  onClip?: (recipe: Recipe, result: RecipeTextBoxClipResult) => void;
  /** `borderRadius: true` rounds the corners by 5, as in native. */
  style?: RecipePathOptions & {
    borderRadius?:
      boolean | NonNullable<RecipeRectangleOptions["borderRadius"]>;
  };
}
export interface RecipeTextBoxClipResult {
  remainder: string;
  linesWritten: number;
  clipped: true;
  bounds: { x: number; y: number; width: number; height: number };
}
/** Text-markup annotation options for `highlight`, `underline`, `strikeOut`, and `squiggly`, as in native Recipe. */
export interface RecipeTextMarkupOptions extends Pick<
  RecipeAnnotationOptions,
  "opacity" | "replies"
> {
  /** Annotation contents. */
  text?: string;
  /** Annotation color; defaults to yellow for highlight, red for strikeOut, and green otherwise. */
  color?: RecipeColor;
}
export interface RecipeTextOptions
  extends
    RecipePathOptions,
    Pick<
      RecipeAnnotationOptions,
      "title" | "open" | "richText" | "flag" | "icon" | "date" | "subject"
    > {
  /** Text fill color: `#gg`, `#rrggbb`, `#ccmmyykk`, `%r,g,b` percentages, a 0-255 component array, or a name registered with `chroma()`. Missing or unknown colors use `#1777d1`. */
  color?: RecipeColor;
  /** Font family; uses createRecipe's default font when omitted (bundled Roboto unless configured). */
  font?: string;
  /** Font size in points for text() and textDimensions(); defaults to 14 when both fontSize and size are omitted. A size that is not a finite number greater than zero throws RangeError. */
  fontSize?: number;
  /** Alternative font size in points; defaults to 14 when both size and fontSize are omitted. A size that is not a finite number greater than zero throws RangeError. */
  size?: number;
  bold?: boolean;
  italic?: boolean;
  charSpace?: number;
  html?: boolean;
  /**
   * Builds one text box from several text() calls. Later calls without
   * coordinates continue the line where the previous run ended; `false` adds
   * that call's text and ends the flow. Defaults to `true` for a call without
   * coordinates and `false` for a call with them.
   */
  flow?: boolean;
  align?: Recipe.ImageAlign;
  layout?: string | number;
  /** Adds a Highlight annotation over each drawn run. */
  highlight?: boolean | RecipeTextMarkupOptions;
  /** Visual text background, distinct from the Highlight annotation option. */
  hilite?: boolean | RecipePathOptions;
  /** Adds an Underline annotation; HTML `<u>` draws a line instead. */
  underline?: boolean | RecipeTextMarkupOptions;
  /** Adds a StrikeOut annotation; HTML `<del>`, `<s>`, and `<strike>` draw a line instead. */
  strikeOut?: boolean | RecipeTextMarkupOptions;
  /** Adds a Squiggly annotation. */
  squiggly?: boolean | RecipeTextMarkupOptions;
  textBox?: RecipeTextBox;
  cell?: RecipeTextBox;
  /** Called with the Recipe as `this` when a layout runs out of columns. */
  overflow?: (
    this: Recipe,
    recipe: Recipe,
  ) =>
    | boolean
    | {
        column?: number | readonly [number, number];
        layout?: string | number;
      }
    | void;
}
/** Per-annotation options for `highlight`, `underline`, `strikeOut`, and `squiggly`. */
export interface RecipeTextMarkupOptions extends Pick<
  RecipeAnnotationOptions,
  "opacity" | "replies"
> {
  /** Annotation contents. */
  text?: string;
  /** Annotation color; defaults to yellow for Highlight, red for StrikeOut, and green otherwise. */
  color?: RecipeColor;
}
export interface RecipeHtmlTextObject {
  value: string;
  styles: Partial<RecipeTextOptions>;
  /** Leading-space count for the lines of this flat visual fragment; `0` ends list indentation. */
  indent?: number;
}
/** Record field names a table column can name, including numeric keys as strings. */
export type RecipeTableField<RecordType extends object> =
  RecordType extends unknown
    ? RecordType extends readonly unknown[]
      ? number extends RecordType["length"]
        ? `${number}`
        : Extract<keyof RecordType, `${number}`>
      : | Extract<keyof RecordType, string>
        | `${Extract<keyof RecordType, number>}`
    : never;
export type RecipeTableColumnField<RecordType extends object> = Exclude<
  RecipeTableField<RecordType>,
  ""
>;
export type RecipeTableFieldValue<
  RecordType extends object,
  Field extends RecipeTableField<RecordType>,
> = RecordType extends unknown
  ? Field extends keyof RecordType
    ? RecordType[Field]
    : Field extends `${infer NumericField extends number}`
      ? NumericField extends keyof RecordType
        ? RecordType[NumericField]
        : undefined
      : undefined
  : never;
/** Table column options. `cell` is the column's only body text box, as in native Recipe. */
export interface RecipeTableColumn<
  RecordType extends object = RecipeTableRow,
  Field extends RecipeTableColumnField<RecordType> =
    RecipeTableColumnField<RecordType>,
> extends Omit<RecipeTextOptions, "font" | "textBox"> {
  name: Field;
  font?: string;
  text?: string;
  width?: number;
  /** Cell text-box options, including onClip callbacks preserved during table layout. */
  cell?: RecipeTextBox;
  /** Header text styles, independent of body styles; booleans use the default header style. Table-level header options take precedence. */
  header?: boolean | RecipeTextOptions;
  /** Final header text-box overrides, applied after header styles and alignToData. */
  hcell?: RecipeTextBox;
  /** Returns cell text options, or a falsy value to keep the defaults. */
  renderer?: (
    this: void,
    /** The own cell value; missing, inherited, and nullish values arrive as `""`. */
    text: undefined extends RecipeTableFieldValue<RecordType, Field>
      ? Exclude<RecipeTableFieldValue<RecordType, Field>, null | undefined> | ""
      : null extends RecipeTableFieldValue<RecordType, Field>
        ? | Exclude<RecipeTableFieldValue<RecordType, Field>, null | undefined>
          | ""
        : RecipeTableFieldValue<RecordType, Field>,
    record: RecordType,
    field: Field,
    row: number,
  ) => RecipeTextOptions | false | null | "" | 0 | void;
}
/**
 * One column definition per record field, so each `renderer` receives the
 * value type of its own `name` rather than the union of every field's type.
 */
export type RecipeTableColumnOptions<
  RecordType extends object = RecipeTableRow,
> = {
  [Field in RecipeTableColumnField<RecordType>]: RecipeTableColumn<
    RecordType,
    Field
  >;
}[RecipeTableColumnField<RecordType>];
export type RecipeTableRow = Record<string, unknown>;
/** Table options. Like native Recipe, a table-level `cell` is not accepted; style cells per column or row. */
export interface RecipeTableOptions<
  RecordType extends object = RecipeTableRow,
> extends Omit<RecipeTextOptions, "overflow" | "cell"> {
  /** Per-segment height, bounded by the page bottom margin. Measurements include padding and minimum/fixed cell heights. */
  height?: number;
  /** Comma-separated names are trimmed; array entries preserve exact keys. */
  order?:
    | string
    | RecipeTableField<RecordType>[]
    | readonly [
        RecipeTableField<RecordType>,
        ...RecipeTableField<RecordType>[],
      ];
  columns?: readonly RecipeTableColumnOptions<RecordType>[];
  /** Enables headers and overrides column header styles; body text styles are not inherited. */
  header?:
    | boolean
    | (RecipeTextOptions & { alignToData?: boolean; cell?: RecipeTextBox });
  border?: boolean | RecipePathOptions;
  row?: RecipeTextOptions & {
    nth?: Recipe.TableRowNth;
    cell?: RecipeTextBox;
  };
  /** Called once per overflow. A continuing destination must fit the row and repeated header or table() throws RangeError; ending the page without starting another throws Error. */
  overflow?: (
    this: Recipe,
    recipe: Recipe,
    row: number,
  ) => boolean | { position?: readonly [number, number] } | void;
}
export interface RecipeLayoutOptions {
  /** Number of equal-width columns to divide the layout width into. */
  columns?: number;
  /** Space between columns in points. Defaults to 18. */
  gap?: number;
  reset?: boolean;
}
export type RecipePageSelection = number | (number | [number, number])[];
export interface RecipeSplitResult {
  name: string;
  bytes: Uint8Array<ArrayBuffer>;
}
export interface RecipeStructure {
  pages: number;
  encrypted: boolean;
  objects: number;
}
export type RecipeStructureFormat = "string" | "json" | { json?: boolean };
export interface RemoveTextOptions {
  /** Also remove text from the Form XObjects the page paints, including nested forms. Defaults to `false`. */
  forms?: boolean;
}
export interface DeletePageOptions {
  /**
   * Remove references to the deleted pages from retained structures -
   * outlines, link annotations, named destinations, form widgets, tagged-PDF
   * structure elements and the open action - instead of refusing the
   * deletion. Defaults to `false`. Once enabled, it applies to every queued
   * deletion.
   */
  pruneReferences?: boolean;
}
export interface RecipePageInfo {
  pageNumber: number;
  mediaBox: PDFRectangle;
  rotate: number;
  /** Recipe-coordinate width, with MediaBox axes swapped for 90/270-degree rotation. */
  width: number;
  /** Recipe-coordinate height, with MediaBox axes swapped for 90/270-degree rotation. */
  height: number;
  layout: Recipe.PageLayout;
  size: [number, number];
  offsetX: number;
  offsetY: number;
}
export interface RecipeMetadata {
  pages: number;
  [page: number]: RecipePageInfo;
}
export interface RecipePdfInspection {
  pages: number;
  level: number;
  encrypted: boolean;
  [page: number]: RecipePageInfo;
}
export interface Recipe {
  readonly options: RecipeOptions;
  readonly default: {
    pageSize: [number, number];
    pageMargin: Required<RecipeMargins>;
    mediumSizes: Record<string, [number, number]>;
  };
  /** The last moveTo or lineTo path position in Recipe coordinates. */
  readonly position: { x: number; y: number };
  /** Page metadata of the source PDF; undefined for a new PDF. */
  readonly metadata: RecipeMetadata | undefined;
  /** A per-Recipe copy of the built-in named device colors. */
  readonly knownColors: RecipeKnownColors;
  register<Arguments extends unknown[], Result>(
    key: string,
    callback: RecipeExtension<Arguments, Result>,
  ): this;
  /** Registers a named function under its `name`. */
  register<Arguments extends unknown[], Result>(
    callback: RecipeExtension<Arguments, Result>,
  ): this;
  registerFont(name: string, bytes: ByteSource, type?: RecipeFontStyle): this;
  registerFontAsync(
    name: string,
    bytes: AsyncByteSource,
    type?: RecipeFontStyle,
  ): Promise<this>;
  htmlToTextObjects(
    html: string,
    options?: Partial<RecipeTextOptions>,
  ): RecipeHtmlTextObject[];
  createPage(width?: number, height?: number, margins?: RecipeMargins): this;
  createPage(
    size: Recipe.PageSize,
    rotation?: number,
    margins?: RecipeMargins,
  ): this;
  endPage(): this;
  margins(): Required<RecipeMargins>;
  margins(margins: RecipeMargins): this;
  margins(left?: number, right?: number, top?: number, bottom?: number): this;
  pageInfo(pageNumber: number): RecipePageInfo | null;
  /** Returns document Info metadata, matching the Node Recipe API. */
  getPageInfo(): Record<string, unknown> | InfoDictionary;
  /** Returns geometry for the current Recipe page. */
  getCurrentPageInfo(): RecipePageInfo | null;
  /** Inspects PDF metadata without changing this Recipe's output state. Blob/File input requires readAsync. */
  read(source: ByteSource): RecipeMetadata;
  readAsync(source: AsyncByteSource): Promise<RecipeMetadata>;
  /** Starts a prepend-safe editing context for an existing one-based page number. */
  editPage(pageNumber: number): this;
  /**
   * Replaces text shown with `Tj` in an existing page's single content stream.
   * Each operand is decoded through the font selected by `Tf` and compared
   * with `text`; a match is rewritten with `replacement`, encoded through the
   * same font in the operand's original literal or hex form. `TJ`, `'`, and
   * `"` operands and text split across operators are not replaced.
   *
   * @param text - Text to replace, as any Unicode string.
   * @param replacement - Replacement text. It can only use glyphs the font
   * already has; embedded subset fonts usually carry just their original
   * text's glyphs.
   * @param pageNumber - One-based page number.
   * @throws {TypeError} If text or replacement is not a string, or if the
   * page number is not a positive integer.
   * @throws {RangeError} If the source document has no such page.
   * @throws {Error} If the page does not have one indirect content stream, or
   * the matched font cannot be read, has a malformed `/Widths` array, or has no
   * glyph for a replacement character.
   */
  replaceText(text: string, replacement: string, pageNumber: number): this;
  /** Removes shown text from an existing page's content streams, and optionally its Form XObjects. */
  removeText(pageNumber: number, options?: RemoveTextOptions): this;
  /**
   * Deletes one or more original source pages. Validation runs here: a page
   * that retained structures still reference is refused unless
   * `pruneReferences` is set, and a failed call leaves the queued deletions
   * unchanged.
   * @throws {TypeError} If options is not an object or pruneReferences is
   * not a boolean.
   * @throws {RangeError} If a page number does not identify an original page.
   * @throws {Error} If the deletion cannot be applied.
   */
  deletePage(pageNumbers: number | number[], options?: DeletePageOptions): this;
  pauseContext(): this;
  resumeContext(): this;
  setPageBox(
    box: PDFPageBoxType | PageBox,
    left: number,
    bottom: number,
    right: number,
    top: number,
  ): this;
  rotate(rotation: number): this;
  /**
   * Rotates subsequent content around a point in Recipe coordinates.
   * @param degrees - Counter-clockwise rotation in degrees, as on native. The
   *   `rotation` option of shapes, text, and images turns clockwise instead.
   * @param x - Rotation origin x coordinate; defaults to 0.
   * @param y - Rotation origin y coordinate; defaults to 0.
   */
  rotateContent(
    degrees: number,
    x?: RecipeCoordinate,
    y?: RecipeCoordinate,
  ): this;
  chroma(
    name: string,
    value: RecipeColor,
    colorspace?: RecipeColorSpace | "",
  ): this;
  line(coordinates: [number, number][], options?: RecipePathOptions): this;
  line(
    startX: number,
    startY: number,
    endX: number,
    endY: number,
    options?: RecipePathOptions,
  ): this;
  moveTo(x: number, y: number): this;
  lineTo(x: number, y: number, options?: RecipePathOptions): this;
  polygon(coordinates: [number, number][], options?: RecipePathOptions): this;
  rectangle(
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    width: number,
    height: number,
    options?: RecipeRectangleOptions,
  ): this;
  circle(
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    radius: number,
    options?: RecipePathOptions,
  ): this;
  ellipse(
    cx: RecipeCoordinate,
    cy: RecipeCoordinate,
    rx: number,
    ry: number,
    options?: RecipePathOptions,
  ): this;
  arc(
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    radius: number,
    startAngle?: number,
    endAngle?: number,
    options?: RecipeArcOptions,
  ): this;
  pie(
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    radius: number,
    startAngle?: number,
    endAngle?: number,
    options?: RecipePathOptions,
  ): this;
  n_gon(
    cx: number,
    cy: number,
    radius: number,
    options?: RecipeNGonOptions,
  ): this;
  n_gon(
    cx: number,
    cy: number,
    radius: number,
    sides?: number | RecipeNGonOptions,
    options?: RecipeNGonOptions,
  ): this;
  star(
    cx: number,
    cy: number,
    radius: number,
    options?: RecipePathOptions,
  ): this;
  star(
    cx: number,
    cy: number,
    radius: number,
    points?: number | RecipePathOptions,
    options?: RecipePathOptions,
  ): this;
  arrow(x: number, y: number, options?: RecipeArrowOptions): this;
  triangle(
    x: number,
    y: number,
    traits: RecipeTriangleMeasurements,
    options?: RecipeTriangleMeasurementOptions,
  ): this;
  triangle(
    x: number,
    y: number,
    traits: RecipeTriangleVertices,
    options: RecipeTriangleUnpositionedVertexOptions,
  ): this;
  triangle(
    x: number,
    y: number,
    traits: RecipeMutableTriangleVertices,
    options: RecipeTriangleVertexOptions,
  ): this;
  lineStyle(options?: RecipeLineStyleOptions): this;
  lineWidth(width: number): this;
  opacity(value: number): this;
  fill(): this;
  stroke(): this;
  fillAndStroke(): this;
  text(value?: string, options?: RecipeTextOptions): this;
  text(
    value: string,
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    options?: RecipeTextOptions,
  ): this;
  textDimensions(value: string, options?: RecipeTextOptions): TextDimensions;
  movedown(lines?: number, returnCoords?: false): this;
  movedown(lines: number, returnCoords: true): RecipePosition;
  movedown(lines?: number, returnCoords?: boolean): this | RecipePosition;
  layout(
    id: string | number,
    x?: number,
    y?: number,
    width?: number,
    height?: number,
    options?: RecipeLayoutOptions,
  ): this;
  table<RecordType extends object>(
    x: number,
    y: number,
    contents: readonly RecordType[],
    options?: RecipeTableOptions<RecordType>,
  ): this;
  image(
    name: string,
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    options?: RecipeImageOptions,
  ): this;
  appendPage(name: string, pages?: RecipePageSelection): this;
  overlay(name: string, options?: RecipeOverlayOptions): this;
  overlay(name: string, x: number, options?: RecipeOverlayOptions): this;
  overlay(
    name: string,
    x?: number,
    y?: number,
    options?: RecipeOverlayOptions,
  ): this;
  /** Adds an ASCII URL link; coordinates and dimensions must be finite. */
  link(
    url: string,
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    width: number,
    height: number,
  ): this;
  comment(
    text: string,
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    options?: RecipeAnnotationOptions,
  ): this;
  /**
   * Queues an annotation on the active page. Like `rectangle()` and `link()`,
   * (x, y) is the annotation rectangle's top-left corner in Recipe
   * coordinates, and the rectangle extends `options.height` down from it.
   */
  annot(
    x: RecipeCoordinate,
    y: RecipeCoordinate,
    subtype: Recipe.AnnotSubtype,
    options?: RecipeAnnotationOptions,
  ): this;
  info(): Record<string, unknown>;
  info(options: Record<string, unknown>): this;
  custom(key: string, value: unknown): this;
  insertPage(
    afterPageNumber: number,
    name: string,
    sourcePageNumber: number,
  ): this;
  split(prefix?: string): RecipeSplitResult[];
  structure(format: "json" | { json: true }): RecipeStructure;
  structure(format?: "string" | { json?: false }): string;
  structure(format?: RecipeStructureFormat): string | RecipeStructure;
  permission(flags?: RecipePermission): number;
  encrypt(options?: RecipeEncryptOptions): this;
  endPDF(
    callback?: (bytes: Uint8Array<ArrayBuffer>) => void,
  ): Uint8Array<ArrayBuffer>;
  dispose(): void;
}
// Low-level types under their native names, for code shared with
// @muhammara/native. Native path, stream, and password options have no alias.
export type EPDFVersion = PDFVersion;
export type eRangeType = ERangeType;
export type PDFBox = PDFRectangle;
export type TransformationMatrix = PDFMatrix;
export type TextDimension = TextDimensions;
export type JPEGInformation = JPGImageInformation;
export type TIFFUsageOptions = TIFFOptions;
export type TIFFColor = NonNullable<
  NonNullable<TIFFOptions["bwTreatment"]>["oneColor"]
>;
export type TextRenderOptions = TextOptions;
export type UsedFont = PDFUsedFont;
export type FontOptions = Pick<WriteTextOptions, "size" | "font">;
export type ColorOptions = Pick<DrawPathOptions, "color" | "colorspace">;
export type GraphicOptions = DrawPathOptions;
export type TransformationObject = Exclude<
  NonNullable<DrawImageOptions["transformation"]>,
  PDFMatrix
>;
export type ImageOptions = DrawImageOptions;
export type MergeOptions = PageRangeOptions;
export type AppendOptions = PageRangeOptions;
export type PDFWriterOptions = CreateWriterOptions;
export type PDFWriterToModifyOptions = WriterOptions;
export type AbstractContentContext = ContentContext;
export type PageContentContext = ContentContext;
export type XObjectContentContext = ContentContext;
export type FormObject = FormXObject;
export type PDFPageModifier = PageModifier;
/**
 * Recipe types under the native names, one per `Recipe` value set, for example
 * `Recipe.TextWrap` for the values of the `Recipe.TextWrap` constants.
 */
export declare namespace Recipe {
  type TextWrap = "auto" | "clip" | "trim" | "ellipsis";
  /** Horizontal alignment of the lines inside a Recipe text box. */
  type TextAlign = Recipe.HorizontalAlign | "justify";
  /** Horizontal placement keyword for Recipe text and images. */
  type HorizontalAlign = "left" | "center" | "right";
  /** Vertical placement keyword for Recipe text, images, and text boxes. */
  type VerticalAlign = "top" | "center" | "bottom";
  /** Text-box alignment: a `Recipe.TextAlign` value, optionally followed by a space and a `Recipe.VerticalAlign` value. */
  type TextBoxAlign =
    Recipe.TextAlign | `${Recipe.TextAlign} ${Recipe.VerticalAlign}`;
  /** Image and text alignment: a `Recipe.HorizontalAlign` value, optionally followed by a `Recipe.VerticalAlign` value. */
  type ImageAlign =
    | Recipe.HorizontalAlign
    | `${Recipe.HorizontalAlign} ${Recipe.VerticalAlign}`;
  /** Which Recipe table rows a `row` style applies to. */
  type TableRowNth = "even" | "odd";
  /** Recipe path line cap: butt, round, or projecting square. */
  type LineCap = "butt" | "round" | "square";
  /** Recipe path line join: miter, round, or bevel. */
  type LineJoin = "miter" | "round" | "bevel";
  type ArrowAt = RecipeArrowAnchor;
  type ArrowType = Exclude<RecipeArrowType, number>;
  type TriangleTrait = RecipeTriangleTrait;
  type TrianglePosition = RecipeTrianglePosition;
  /** Orientation of a Recipe page, from its rotated width and height. */
  type PageLayout = "portrait" | "landscape";
  /** Named page size for `createPage()`, case-insensitive; other names use the default size. */
  type PageSize =
    | "executive"
    | "folio"
    | "legal"
    | "letter"
    | "ledger"
    | "tabloid"
    | "a0"
    | "a1"
    | "a2"
    | "a3"
    | "a4"
    | "a5"
    | "a6"
    | "a7"
    | "a8"
    | "a9"
    | "a10"
    | "b0"
    | "b1"
    | "b2"
    | "b3"
    | "b4"
    | "b5"
    | "b6"
    | "b7"
    | "b8"
    | "b9"
    | "b10"
    | "c0"
    | "c1"
    | "c2"
    | "c3"
    | "c4"
    | "c5"
    | "c6"
    | "c7"
    | "c8"
    | "c9"
    | "c10"
    | "ra0"
    | "ra1"
    | "ra2"
    | "ra3"
    | "ra4"
    | "sra0"
    | "sra1"
    | "sra2"
    | "sra3"
    | "sra4"
    | (string & {});
  type FontStyle = Exclude<RecipeFontStyle, "r" | "b" | "i" | "bi">;
  type RecipeFontStyle = import("./index.js").RecipeFontStyle;
  type Permission = RecipePermissionName;
  type PermissionName = RecipePermissionName;
  type PermissionList = RecipePermission;
  type Coordinate = "center";
  type RecipeCoordinate = import("./index.js").RecipeCoordinate;
  type Color = RecipeColor;
  type DeviceColorspace = RecipeDeviceColorSpace;
  type DeviceColorSpace = RecipeDeviceColorSpace;
  type Colorspace = RecipeColorSpace;
  /** Annotation subtype for `annot()`; known subtypes match case-insensitively. */
  type AnnotSubtype =
    | "Text"
    | "Link"
    | "FreeText"
    | "Line"
    | "Square"
    | "Circle"
    | "Polygon"
    | "PolyLine"
    | "Highlight"
    | "Underline"
    | "Squiggly"
    | "StrikeOut"
    | "Caret"
    | "Stamp"
    | "Ink"
    | "Popup"
    | "FileAttachment"
    | "Sound"
    | "Movie"
    | "Screen"
    | "Widget"
    | "PrinterMark"
    | "TrapNet"
    | "Watermark"
    | "3D"
    | "Redact"
    | "Projection"
    | "RichMedia";
  /** Annotation flag name for Recipe annotation `flag`; letter case is ignored. */
  type AnnotFlag =
    | "invisible"
    | "hidden"
    | "print"
    | "nozoom"
    | "norotate"
    | "noview"
    | "readonly"
    | "locked"
    | "togglenoview"
    | "lockedcontents";
  type AnnotOptionsFlag = Recipe.AnnotFlag;
  /** Standard icon name for Recipe text annotations. */
  type AnnotIcon =
    | "Comment"
    | "Key"
    | "Note"
    | "Help"
    | "NewParagraph"
    | "Paragraph"
    | "Insert";
  type AnnotOptionsIcon = Recipe.AnnotIcon;
  type ChromaCommand = "!load";
  /** Wasm-only: the `Recipe.StructureFormat` values. */
  type StructureFormat = "string" | "json";
  // Option and helper types under their native names.
  type RecipeOptions = import("./index.js").RecipeOptions;
  type RecipeMargins = import("./index.js").RecipeMargins;
  type CaseInsensitive<Value extends string> = RecipeCaseInsensitive<Value>;
  type ExtensionCallback<
    Arguments extends unknown[] = never[],
    Result = unknown,
  > = RecipeExtension<Arguments, Result>;
  type EndPDFCallback = (bytes: Uint8Array<ArrayBuffer>) => void;
  type InfoOptions = Record<string, unknown>;
  type Metadata = RecipeMetadata;
  type ReadMetadata = RecipeMetadata;
  type MetadataPage = RecipePageInfo;
  type ReadMetadataPage = RecipePageInfo;
  type EncryptOptions = RecipeEncryptOptions;
  type OverlayOptions = RecipeOverlayOptions;
  type LayoutOptions = RecipeLayoutOptions;
  type ImageOptions = RecipeImageOptions;
  type HtmlTextObject = RecipeHtmlTextObject;
  type TextOptions = RecipeTextOptions;
  type TextMarkupOptions = RecipeTextMarkupOptions;
  type TextBox = RecipeTextBox;
  type TextBoxStyle = NonNullable<RecipeTextBox["style"]>;
  type TextBoxClipResult = RecipeTextBoxClipResult;
  type TextOverflowCallback = Extract<
    NonNullable<RecipeTextOptions["overflow"]>,
    (...args: never[]) => unknown
  >;
  type TextOverflowInstructions = Exclude<
    ReturnType<TextOverflowCallback>,
    boolean
  >;
  type AnnotOptions = RecipeAnnotationOptions;
  type CommentOptions = RecipeAnnotationOptions;
  type AnnotReply = RecipeAnnotationOptions;
  /** @deprecated Use `AnnotFlag`; comments accept the same flags. */
  type CommentOptionsFlag = Recipe.AnnotFlag;
  type PathOptions = RecipePathOptions;
  type DrawingOptions = RecipePathOptions;
  type SkewOptions = Pick<RecipePathOptions, "skewX" | "skewY">;
  type TransformOptions = Pick<
    RecipePathOptions,
    "skewX" | "skewY" | "rotation" | "rotationOrigin"
  >;
  type TransformedPathOptions = RecipePathOptions;
  type LinkFillOptions = Pick<RecipePathOptions, "link" | "fill">;
  type LineOptions = RecipePathOptions;
  type LineToOptions = RecipePathOptions;
  type LineStyleOptions = RecipeLineStyleOptions;
  type PolygonOptions = RecipePathOptions;
  type ShapeOptions = RecipePathOptions;
  type CircleOptions = RecipePathOptions;
  type EllipseOptions = RecipePathOptions;
  type RectangleOptions = RecipeRectangleOptions;
  type BorderRadius = NonNullable<RecipeRectangleOptions["borderRadius"]>;
  type NGonOptions = RecipeNGonOptions;
  type ArrowOptions = RecipeArrowOptions;
  type TriangleOptions = RecipeTriangleOptions;
  type TriangleBaseOptions = RecipeTriangleBaseOptions;
  type TriangleMeasurementOptions = RecipeTriangleMeasurementOptions;
  type TriangleVertexOptions = RecipeTriangleVertexOptions;
  type TriangleUnpositionedVertexOptions =
    RecipeTriangleUnpositionedVertexOptions;
  type TriangleVertexIdentifier = RecipeTriangleVertexIdentifier;
  type TriangleMeasurements = RecipeTriangleMeasurements;
  type TriangleVertices = RecipeTriangleVertices;
  type MutableTriangleVertices = RecipeMutableTriangleVertices;
  type TriangleMeasurementTrait = RecipeTriangleMeasurementTrait;
  type TriangleVertexTrait = RecipeTriangleVertexTrait;
  type TableOptions<RecordType extends object = RecipeTableRow> =
    RecipeTableOptions<RecordType>;
  type TableColumnDefinition = RecipeTableColumn;
  type TableColumnOptions = RecipeTableColumnOptions;
  type TableField<RecordType extends object> = RecipeTableField<RecordType>;
  type TableColumnField<RecordType extends object> =
    RecipeTableColumnField<RecordType>;
  type TableFieldValue<
    RecordType extends object,
    Field extends RecipeTableField<RecordType>,
  > = RecipeTableFieldValue<RecordType, Field>;
}
export interface RecipeConstructor {
  /** How text that does not fit a text-box line is handled. */
  readonly TextWrap: {
    readonly AUTO: "auto";
    readonly CLIP: "clip";
    readonly TRIM: "trim";
    readonly ELLIPSIS: "ellipsis";
  };
  /** Horizontal alignments of text inside a text box. */
  readonly TextAlign: {
    readonly LEFT: "left";
    readonly CENTER: "center";
    readonly RIGHT: "right";
    readonly JUSTIFY: "justify";
  };
  /** Which table rows the `row` options apply to. */
  readonly TableRowNth: {
    readonly EVEN: "even";
    readonly ODD: "odd";
  };
  /** Line cap styles for the `lineCap` options. */
  readonly LineCap: {
    readonly BUTT: "butt";
    readonly ROUND: "round";
    readonly SQUARE: "square";
  };
  /** Line join styles for the `lineJoin` options. */
  readonly LineJoin: {
    readonly MITER: "miter";
    readonly ROUND: "round";
    readonly BEVEL: "bevel";
  };
  /** The arrow point placed at the `arrow()` coordinates. */
  readonly ArrowAt: {
    readonly HEAD: "head";
    readonly TAIL: "tail";
  };
  /** Arrow head shapes for the `arrow()` type option. */
  readonly ArrowType: {
    readonly TRIANGLE: "triangle";
    readonly DART: "dart";
    readonly KITE: "kite";
  };
  /** How `triangle()` traits define the triangle. */
  readonly TriangleTrait: {
    readonly SSS: "sss";
    readonly SAS: "sas";
    readonly ASA: "asa";
    readonly VTX: "vtx";
  };
  /** The triangle point placed at the `triangle()` coordinates. */
  readonly TrianglePosition: {
    readonly A: "a";
    readonly B: "b";
    readonly C: "c";
    readonly CENTROID: "centroid";
    readonly CIRCUMCENTER: "circumcenter";
    readonly INCENTER: "incenter";
  };
  /** Page orientations reported in page metadata. */
  readonly PageLayout: {
    readonly PORTRAIT: "portrait";
    readonly LANDSCAPE: "landscape";
  };
  /** Named page sizes for `createPage()`. */
  readonly PageSize: {
    readonly EXECUTIVE: "executive";
    readonly FOLIO: "folio";
    readonly LEGAL: "legal";
    readonly LETTER: "letter";
    readonly LEDGER: "ledger";
    readonly TABLOID: "tabloid";
    readonly A0: "a0";
    readonly A1: "a1";
    readonly A2: "a2";
    readonly A3: "a3";
    readonly A4: "a4";
    readonly A5: "a5";
    readonly A6: "a6";
    readonly A7: "a7";
    readonly A8: "a8";
    readonly A9: "a9";
    readonly A10: "a10";
    readonly B0: "b0";
    readonly B1: "b1";
    readonly B2: "b2";
    readonly B3: "b3";
    readonly B4: "b4";
    readonly B5: "b5";
    readonly B6: "b6";
    readonly B7: "b7";
    readonly B8: "b8";
    readonly B9: "b9";
    readonly B10: "b10";
    readonly C0: "c0";
    readonly C1: "c1";
    readonly C2: "c2";
    readonly C3: "c3";
    readonly C4: "c4";
    readonly C5: "c5";
    readonly C6: "c6";
    readonly C7: "c7";
    readonly C8: "c8";
    readonly C9: "c9";
    readonly C10: "c10";
    readonly RA0: "ra0";
    readonly RA1: "ra1";
    readonly RA2: "ra2";
    readonly RA3: "ra3";
    readonly RA4: "ra4";
    readonly SRA0: "sra0";
    readonly SRA1: "sra1";
    readonly SRA2: "sra2";
    readonly SRA3: "sra3";
    readonly SRA4: "sra4";
  };
  /** Horizontal alignments. */
  readonly HorizontalAlign: {
    readonly LEFT: "left";
    readonly CENTER: "center";
    readonly RIGHT: "right";
  };
  /** Vertical alignments. */
  readonly VerticalAlign: {
    readonly TOP: "top";
    readonly CENTER: "center";
    readonly BOTTOM: "bottom";
  };
  /** Font styles for `registerFont()`. */
  readonly FontStyle: {
    readonly REGULAR: "regular";
    readonly BOLD: "bold";
    readonly ITALIC: "italic";
    readonly BOLD_ITALIC: "bold-italic";
  };
  /** User access permission names for `permission()`. */
  readonly Permission: {
    readonly PRINT: "print";
    readonly MODIFY: "modify";
    readonly COPY: "copy";
    readonly EDIT: "edit";
    readonly FILL_FORM: "fillform";
    readonly EXTRACT: "extract";
    readonly ASSEMBLE: "assemble";
    readonly PRINT_BEST: "printbest";
  };
  /** Named coordinates, accepted wherever a `RecipeCoordinate` is. */
  readonly Coordinate: {
    readonly CENTER: "center";
  };
  /** Colorspaces accepted by the `colorspace` options. */
  readonly Colorspace: {
    readonly RGB: "rgb";
    readonly CMYK: "cmyk";
    readonly GRAY: "gray";
    readonly SEPARATION: "separation";
  };
  /** Annotation subtypes for `annot()`. */
  readonly AnnotSubtype: {
    readonly TEXT: "Text";
    readonly LINK: "Link";
    readonly FREE_TEXT: "FreeText";
    readonly LINE: "Line";
    readonly SQUARE: "Square";
    readonly CIRCLE: "Circle";
    readonly POLYGON: "Polygon";
    readonly POLY_LINE: "PolyLine";
    readonly HIGHLIGHT: "Highlight";
    readonly UNDERLINE: "Underline";
    readonly SQUIGGLY: "Squiggly";
    readonly STRIKE_OUT: "StrikeOut";
    readonly CARET: "Caret";
    readonly STAMP: "Stamp";
    readonly INK: "Ink";
    readonly POPUP: "Popup";
    readonly FILE_ATTACHMENT: "FileAttachment";
    readonly SOUND: "Sound";
    readonly MOVIE: "Movie";
    readonly SCREEN: "Screen";
    readonly WIDGET: "Widget";
    readonly PRINTER_MARK: "PrinterMark";
    readonly TRAP_NET: "TrapNet";
    readonly WATERMARK: "Watermark";
    readonly THREE_D: "3D";
    readonly REDACT: "Redact";
    readonly PROJECTION: "Projection";
    readonly RICH_MEDIA: "RichMedia";
  };
  /** Annotation flag names for the `flag` options. */
  readonly AnnotFlag: {
    readonly INVISIBLE: "invisible";
    readonly HIDDEN: "hidden";
    readonly PRINT: "print";
    readonly NO_ZOOM: "nozoom";
    readonly NO_ROTATE: "norotate";
    readonly NO_VIEW: "noview";
    readonly READ_ONLY: "readonly";
    readonly LOCKED: "locked";
    readonly TOGGLE_NO_VIEW: "togglenoview";
    readonly LOCKED_CONTENTS: "lockedcontents";
  };
  /** Special `chroma()` names that run a command instead of naming a color. */
  readonly ChromaCommand: {
    readonly LOAD: "!load";
  };
  /** Text annotation icons for the `icon` option. */
  readonly AnnotIcon: {
    readonly COMMENT: "Comment";
    readonly KEY: "Key";
    readonly NOTE: "Note";
    readonly HELP: "Help";
    readonly NEW_PARAGRAPH: "NewParagraph";
    readonly PARAGRAPH: "Paragraph";
    readonly INSERT: "Insert";
  };
  /** Output formats of `structure()`; Wasm-only. */
  readonly StructureFormat: {
    readonly STRING: "string";
    readonly JSON: "json";
  };
  new (options?: RecipeOptions): Recipe;
  new (source: ByteSource, options?: RecipeOptions): Recipe;
  registerFont(name: string, bytes: ByteSource, style?: RecipeFontStyle): void;
  registerFontAsync(
    name: string,
    bytes: AsyncByteSource,
    style?: RecipeFontStyle,
  ): Promise<void>;
  registerImage(name: string, bytes: ByteSource, extension: string): void;
  registerImageAsync(
    name: string,
    bytes: AsyncByteSource,
    extension: string,
  ): Promise<void>;
  registerPdf(name: string, bytes: ByteSource): void;
  registerPdfAsync(name: string, bytes: AsyncByteSource): Promise<void>;
  unregisterFont(name: string, style?: RecipeFontStyle): boolean;
  unregisterImage(name: string): boolean;
  unregisterPdf(name: string): boolean;
  disposeAssets(): void;
  splitPdf(name: string, prefix?: string): RecipeSplitResult[];
  inspectPdf(name: string): RecipePdfInspection;
  permission(flags?: RecipePermission): number;
  /**
   * Resolves to the third-party license notices (Markdown) embedded in a
   * `muhammara-wasm.wasm` as its `license` custom section. They equal
   * `@muhammara/wasm/THIRD_PARTY_LICENSES.md`.
   *
   * The runtime does not keep the binary it was loaded from, so pass that
   * binary: a URL, which is fetched, or its bytes or a Blob/File. The section
   * is read from the bytes without compiling them.
   *
   * Rejects when the URL cannot be loaded, the bytes are not a WebAssembly
   * module, or the module has no `license` section, for example after
   * `wasm-strip`.
   */
  thirdPartyLicenses(source: ThirdPartyLicensesSource): Promise<string>;
}
export interface TextOptions {
  encoding?: EEncoding;
}
export type PageRange = [start: number, end: number];
export type PageRangeOptions =
  | { type?: 0; specificRanges?: never }
  | { type: 1; specificRanges: [PageRange, ...PageRange[]] };
export interface ImageDimensions {
  width: number;
  height: number;
}
export interface TextDimensions {
  xMin: number;
  yMin: number;
  xMax: number;
  yMax: number;
  width: number;
  height: number;
}
export interface FontMetrics {
  pixelsPerEm: { x: number; y: number; xScale: number; yScale: number };
  ascender: number;
  descender: number;
  height: number;
  max_advance: number;
}
export interface AnnotationOptions {
  contents?: string;
  title?: string;
  name?: string;
  color?:
    [] | [number] | [number, number, number] | [number, number, number, number];
  borderWidth?: number;
  borderDash?: number[];
  border?: { width?: number; dash?: number[] };
  quadPoints?: number[];
  flags?: number;
  open?: boolean;
  opacity?: number;
}
/**
 * Paint operation a drawing helper finishes its path with. `"stroke"` is the
 * default when `type` is omitted, `"fill"` fills the path, and `"clip"`
 * intersects the clipping region without painting; scope it with q()/Q().
 * `null` selects no paint operation and ends the path unpainted.
 */
export type DrawingPathType = "stroke" | "fill" | "clip" | null;
export declare const DrawingPathType: {
  readonly STROKE: "stroke";
  readonly FILL: "fill";
  readonly CLIP: "clip";
};
/** PDF line cap style for `J()`: 0 butt, 1 round, 2 projecting square. */
export type LineCapStyle = 0 | 1 | 2;
export declare const LineCapStyle: {
  readonly LINECAP_BUTT: 0;
  readonly LINECAP_ROUND: 1;
  readonly LINECAP_SQUARE: 2;
};
/** Info dictionary `/Trapped` state: the `EInfoTrapped*` constants. */
export type EInfoTrapped = 0 | 1 | 2;
/** Token written after an array by `endArray()`: the `eTokenSeparator*` constants. */
export type ETokenSeparator = 0 | 1 | 2;
export declare const ETokenSeparator: {
  readonly eTokenSeparatorSpace: 0;
  readonly eTokenSeparatorEndLine: 1;
  readonly eTokenSeparatorNone: 2;
};
/** Parsed PDF object type: the `ePDFObject*` constants. */
export type PDFObjectType = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11;
/** Cross-reference entry kind: the `eXrefEntry*` constants. */
export type XrefEntryType = 0 | 1 | 2 | 3;
/** Procedure set name for `addProcsetResource()`: the `KProcset*`/`kProcset*` constants. */
export type ProcsetName = "ImageB" | "ImageC" | "ImageI" | "PDF" | "Text";
/** Page range selection kind: the `eRangeType*` constants. */
export type ERangeType = 0 | 1;
/** Image or document format reported by `getImageType()`. */
export type PDFImageType = "PDF" | "JPG" | "TIFF" | "PNG";
export declare const PDFImageType: {
  readonly PDF: "PDF";
  readonly JPG: "JPG";
  readonly TIFF: "TIFF";
  readonly PNG: "PNG";
};
/** PDF line join style for `j()`: 0 miter, 1 round, 2 bevel. */
export type LineJoinStyle = 0 | 1 | 2;
/**
 * PDF text rendering mode for `Tr()`: 0 fill, 1 stroke, 2 fill and stroke,
 * 3 invisible, 4 to 6 the same plus clipping, 7 clip only.
 */
export type TextRenderingMode = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;

export interface DrawPathOptions {
  color?: ColorValue;
  /**
   * A DeviceColorSpace value. A `gray` or `cmyk` color must be a number; a
   * color name, `#rrggbb` string, or `[r, g, b]` array is RGB and throws a
   * `TypeError` with them.
   */
  colorspace?: DeviceColorSpace;
  type?: DrawingPathType;
  width?: number;
  close?: boolean;
}
export interface WriteTextOptions extends DrawPathOptions {
  font: PDFUsedFont;
  size?: number;
  underline?: boolean;
}
export interface DrawImageOptions {
  index?: number;
  transformation?:
    | PDFMatrix
    | {
        width: number;
        height: number;
        proportional?: boolean;
        fit?: ImageFit;
      };
}
export interface TIFFOptions {
  pageIndex?: number;
  objectId?: number;
  bwTreatment?: {
    asImageMask?: boolean;
    oneColor?: [number, number, number] | [number, number, number, number];
  };
  grayscaleTreatment?: {
    asColorMap?: boolean;
    oneColor?: [number, number, number] | [number, number, number, number];
    zeroColor?: [number, number, number] | [number, number, number, number];
  };
}
export type PDFFormOptions = PageRangeOptions & {
  transformation?: PDFMatrix;
  additionalObjectIds?: number[];
};
export interface JPGImageInformation {
  samplesWidth: number;
  samplesHeight: number;
  colorComponentsCount: number;
  JFIFInformationExists: boolean;
  ExifInformationExists: boolean;
  PhotoshopInformationExists: boolean;
  JFIFUnit?: number;
  JFIFXDensity?: number;
  JFIFYDensity?: number;
  ExifUnit?: number;
  ExifXDensity?: number;
  ExifYDensity?: number;
  PhotoshopXDensity?: number;
  PhotoshopYDensity?: number;
}

export class PDFRStreamForBuffer {
  constructor(bytes: ByteSource);
  /** Returns a copy of at most `amount` bytes from the current position. */
  read(amount: number): Uint8Array<ArrayBuffer>;
  notEnded(): boolean;
  setPosition(position: number): void;
  setPositionFromEnd(position: number): void;
  skip(amount: number): void;
  getCurrentPosition(): number;
  moveStartPosition(position: number): void;
}
export class PDFWStreamForBuffer {
  constructor();
  buffer: Uint8Array<ArrayBuffer>;
  /** An array of byte values (integers from 0 to 255) is accepted, as in native. */
  write(bytes: ByteSource | readonly number[]): number;
  getCurrentPosition(): number;
  toUint8Array(): Uint8Array<ArrayBuffer>;
  toArrayBuffer(): ArrayBuffer;
  toBlob(type?: string): BlobLike;
}
export class ByteReader extends PDFRStreamForBuffer {}
export class ByteReaderWithPosition extends PDFRStreamForBuffer {}
export class ByteWriter extends PDFWStreamForBuffer {}
export class ByteWriterWithPosition extends PDFWStreamForBuffer {}

declare class PDFPage {
  constructor(left?: number, bottom?: number, right?: number, top?: number);
  mediaBox: PDFRectangle;
  cropBox?: PDFRectangle;
  bleedBox?: PDFRectangle;
  trimBox?: PDFRectangle;
  artBox?: PDFRectangle;
  rotate?: number;
  getResourcesDictionary(): ResourcesDictionary;
}
declare class PDFTextString {
  constructor(value?: string | ByteSource | number[]);
  toBytesArray(): number[];
  toString(): string;
  fromString(value: string): this;
}
declare class PDFDate {
  constructor(value?: string | Date);
  toString(): string;
  setToCurrentTime(): this;
}
export type { PDFDate, PDFPage, PDFTextString };
export interface PDFUsedFont {
  /** Measure a string, or a list of glyph ids. */
  calculateTextDimensions(
    text: string | number[],
    size?: number,
  ): TextDimensions;
  getFontMetrics(size?: number): FontMetrics;
}
export interface ByteWriteStream {
  write(bytes: ByteSource): number;
  getCurrentPosition?(): number;
}
export interface PDFStream {
  getWriteStream(): ByteWriteStream;
}
export interface ResourcesDictionary {
  addProcsetResource(name: ProcsetName): void;
  addExtGStateMapping(id: number): string;
  addFontMapping(id: number): string;
  addColorSpaceMapping(id: number): string;
  addPatternMapping(id: number): string;
  addPropertyMapping(id: number): string;
  addXObjectMapping(id: number): string;
  addFormXObjectMapping(id: number): string;
  /** Pass an object ID, or an image XObject created by a writer or modifier, as in native. */
  addImageXObjectMapping(
    image: number | ImageXObject | ModifierImageXObject,
  ): string;
  addShadingMapping(id: number): string;
}
export interface DictionaryContext {
  writeKey(key: string): this;
  writeNameValue(value: string): this;
  writeLiteralStringValue(
    value: string | Uint8Array | ArrayBuffer | readonly number[],
  ): this;
  writeHexStringValue(
    value: string | Uint8Array | ArrayBuffer | readonly number[],
  ): this;
  writeNumberValue(value: number): this;
  writeBooleanValue(value: boolean): this;
  writeObjectReferenceValue(id: number): this;
  writeNullValue(): this;
  writeRectangleValue(value: PDFRectangle): this;
  writeRectangleValue(
    left: number,
    bottom: number,
    right: number,
    top: number,
  ): this;
}
export interface ObjectsContext {
  allocateNewObjectID(): number;
  startNewIndirectObject(): number;
  startNewIndirectObject(id: number): this;
  endIndirectObject(): this;
  startModifiedIndirectObject(id: number): this;
  deleteObject(id: number): this;
  startDictionary(): DictionaryContext;
  endDictionary(dictionary: DictionaryContext): this;
  startArray(): this;
  endArray(separator?: ETokenSeparator): this;
  writeNumber(value: number): this;
  writeIndirectObjectReference(id: number, generation?: number): this;
  writeBoolean(value: boolean): this;
  writeName(value: string): this;
  writeLiteralString(
    value: string | Uint8Array | ArrayBuffer | readonly number[],
  ): this;
  writeHexString(
    value: string | Uint8Array | ArrayBuffer | readonly number[],
  ): this;
  writeKeyword(value: string): this;
  writeComment(value: string): this;
  endLine(): this;
  setCompressStreams(value: boolean): this;
  startPDFStream(dictionary?: DictionaryContext): PDFStream;
  startUnfilteredPDFStream(dictionary?: DictionaryContext): PDFStream;
  endPDFStream(stream: PDFStream): this;
  startFreeContext(): ByteWriteStream;
  endFreeContext(): this;
}

export interface ContentContext {
  getAssociatedPage?(): PDFPage;
  getCurrentPageContentStream?(): PDFStream;
  writeFreeCode(code: string): this;
  setOpacity(opacity: number): this;
  b(): this;
  B(): this;
  bStar(): this;
  BStar(): this;
  s(): this;
  S(): this;
  f(): this;
  F(): this;
  fStar(): this;
  n(): this;
  m(x: number, y: number): this;
  l(x: number, y: number): this;
  c(
    x1: number,
    y1: number,
    x2: number,
    y2: number,
    x3: number,
    y3: number,
  ): this;
  v(x2: number, y2: number, x3: number, y3: number): this;
  y(x1: number, y1: number, x3: number, y3: number): this;
  h(): this;
  re(x: number, y: number, width: number, height: number): this;
  q(): this;
  Q(): this;
  cm(...matrix: PDFMatrix): this;
  w(lineWidth: number): this;
  J(value: LineCapStyle): this;
  j(value: LineJoinStyle): this;
  M(value: number): this;
  d(dash: number[], phase?: number): this;
  g(value: number): this;
  G(gray: number): this;
  rg(red: number, green: number, blue: number): this;
  RG(red: number, green: number, blue: number): this;
  k(cyan: number, magenta: number, yellow: number, black: number): this;
  K(cyan: number, magenta: number, yellow: number, black: number): this;
  W(): this;
  WStar(): this;
  BT(): this;
  ET(): this;
  Tm(...matrix: PDFMatrix): this;
  Td(x: number, y: number): this;
  TD(x: number, y: number): this;
  TStar(): this;
  Tc(value: number): this;
  Tw(value: number): this;
  Tz(value: number): this;
  TL(value: number): this;
  Tr(value: TextRenderingMode): this;
  Ts(value: number): this;
  Tf(font: PDFUsedFont | string, size: number): this;
  Tj(text: string, options?: TextOptions): this;
  Tj(glyphs: Glyph): this;
  Tj(text: string | Glyph): this;
  Quote(text: string, options?: TextOptions): this;
  Quote(glyphs: Glyph): this;
  Quote(text: string | Glyph): this;
  DoubleQuote(
    wordSpace: number,
    characterSpace: number,
    text: string,
    options?: TextOptions,
  ): this;
  DoubleQuote(wordSpace: number, characterSpace: number, glyphs: Glyph): this;
  DoubleQuote(
    wordSpace: number,
    characterSpace: number,
    text: string | Glyph,
  ): this;
  /** Pass at least one item; an empty call throws a `TypeError`. */
  TJ(...items: (string | number | Glyph)[]): this;
  TJ(
    ...items: [
      string | number | Glyph,
      ...(string | number | Glyph)[],
      TextOptions,
    ]
  ): this;
  ri(name: string): this;
  i(value: number): this;
  gs(name: string): this;
  CS(name: string): this;
  cs(name: string): this;
  SC(...components: number[]): this;
  /** Color components, optionally followed by a pattern name. */
  SCN(...components: [number, ...number[]]): this;
  SCN(...componentsAndPattern: [number, ...number[], string]): this;
  SCN(components: number[], pattern?: string): this;
  /** A pattern name alone selects a colored (PaintType 1) pattern. */
  SCN(pattern: string): this;
  sc(...components: number[]): this;
  /** Color components, optionally followed by a pattern name. */
  scn(...components: [number, ...number[]]): this;
  scn(...componentsAndPattern: [number, ...number[], string]): this;
  scn(components: number[], pattern?: string): this;
  /** A pattern name alone selects a colored (PaintType 1) pattern. */
  scn(pattern: string): this;
  doXObject(xObject: string | number | FormXObject | ImageXObject): this;
  /** Require at least two complete finite coordinate pairs; invalid input emits no operators. */
  drawPath(points: [number, number][], options?: DrawPathOptions): this;
  /** Require complete finite coordinate pairs, optionally followed by an options object. */
  drawPath(
    x1: number,
    y1: number,
    x2: number,
    y2: number,
    ...coordinatesAndOptions: [...number[], DrawPathOptions] | number[]
  ): this;
  /** Coordinates, radius, and calculated circle geometry must remain finite. */
  drawCircle(
    x: number,
    y: number,
    radius: number,
    options?: DrawPathOptions,
  ): this;
  /** Coordinates and edge length must be finite. */
  drawSquare(
    x: number,
    y: number,
    edge: number,
    options?: DrawPathOptions,
  ): this;
  /** Coordinates and dimensions must be finite. */
  drawRectangle(
    x: number,
    y: number,
    width: number,
    height: number,
    options?: DrawPathOptions,
  ): this;
  /** Coordinates and calculated underline geometry must be finite; font size must be positive and finite. */
  writeText(
    text: string,
    x: number,
    y: number,
    options: WriteTextOptions,
  ): this;
  drawImage(
    x: number,
    y: number,
    image: string | ByteSource,
    options?: DrawImageOptions,
  ): this;
  drawImageAsync(
    x: number,
    y: number,
    image: AsyncByteSource,
    options?: DrawImageOptions,
  ): Promise<this>;
}
export interface ImageXObject {
  readonly id: number;
}
export interface CompletedFormXObject {
  readonly id: number;
}
export interface FormXObject {
  readonly id: number;
  getContentContext(): ContentContext;
  getContentStream(): PDFStream;
  getResourcesDictionary(): ResourcesDictionary;
  getResourcesDictinary(): ResourcesDictionary;
}
export interface DocumentContext {
  getInfoDictionary(): InfoDictionary;
}
export interface InfoDictionary {
  title: string;
  author: string;
  subject: string;
  keywords: string;
  creator: string;
  producer: string;
  trapped: EInfoTrapped;
  addAdditionalInfoEntry(key: string, value: string): void;
  removeAdditionalInfoEntry(key: string): void;
  clearAdditionalInfoEntries(): void;
  getAdditionalInfoEntry(key: string): string;
  getAdditionalInfoEntries(): Record<string, string>;
  setCreationDate(value: string | Date | PDFDate): void;
  setModDate(value: string | Date | PDFDate): void;
}

export interface PDFByteReader {
  /** Returns a copy of at most `amount` decoded or raw stream bytes. */
  read(amount: number): Uint8Array<ArrayBuffer>;
  notEnded(): boolean;
  /** Immediately releases this Wasm stream reader without ending its parent PDF reader. */
  dispose(): this;
}
export interface PositionedPDFByteReader extends PDFByteReader {
  setPosition(position: number): this;
  setPositionFromEnd(position: number): this;
  skip(amount: number): this;
  getCurrentPosition(): number;
}
export interface PDFObjectParser {
  parseNewObject(): PDFObject | undefined;
  end(): void;
}
export interface PDFObject {
  getType(): PDFObjectType;
  value: string | number | boolean | undefined;
  toString(): string;
  toNumber(): number | undefined;
  toPDFArray(): PDFArray | undefined;
  toPDFDictionary(): PDFDictionary | undefined;
  toPDFStream(): PDFStreamInput | undefined;
  toPDFIndirectObjectReference(): PDFIndirectObjectReference | undefined;
  toPDFBoolean(): PDFObject | undefined;
  toPDFLiteralString(): PDFStringObject | undefined;
  toPDFHexString(): PDFStringObject | undefined;
  toPDFNull(): PDFObject | undefined;
  toPDFName(): PDFObject | undefined;
  toPDFInteger(): PDFObject | undefined;
  toPDFReal(): PDFObject | undefined;
  toPDFSymbol(): PDFObject | undefined;
}
export interface PDFArray extends PDFObject {
  getLength(): number;
  queryObject(index: number): PDFObject | undefined;
  toJSArray(): PDFObject[];
}
export interface PDFDictionary extends PDFObject {
  exists(key: string): boolean;
  queryObject(key: string): PDFObject;
  toJSObject(): Record<string, PDFObject>;
}
export interface PDFStreamInput extends PDFObject {
  getDictionary(): PDFDictionary;
  getStreamContentStart(): number;
}
export interface PDFIndirectObjectReference extends PDFObject {
  getObjectID(): number;
  getVersion(): number;
}
export interface PDFStringObject extends PDFObject {
  toBytesArray(): Uint8Array<ArrayBuffer>;
  toText(): string;
}
export interface PDFPageInput {
  getDictionary(): PDFDictionary;
  getMediaBox(): PDFRectangle;
  getCropBox(): PDFRectangle;
  getTrimBox(): PDFRectangle;
  getBleedBox(): PDFRectangle;
  getArtBox(): PDFRectangle;
  getRotate(): number;
}
/**
 * A text-showing operation in page content-stream drawing order, as returned
 * when `extractPageText()` is called with `{ decodeText: false }`.
 */
export interface PDFRawTextElement {
  /** Raw content-string bytes represented as one-byte JavaScript code units. */
  content: string;
  fontResource: string;
  fontSize: number;
  /** The text-to-page matrix after applying the active graphics CTM. */
  textMatrix: [number, number, number, number, number, number];
}
/** A text-showing operation in drawing order, with its decoded text. */
export interface PDFTextElement extends PDFRawTextElement {
  /**
   * `content` decoded to Unicode through the active font: its `/ToUnicode`
   * CMap, then its simple-font `/Encoding` and `/Differences`. Codes the font
   * does not map become U+FFFD, as do codes of fonts whose built-in encoding
   * cannot be read, the Symbol and ZapfDingbats standard fonts, embedded Type 1
   * fonts without `/Encoding`, and Type 3 fonts, unless `/ToUnicode` or
   * `/Differences` maps them, and every byte shown without a font or with a
   * font that cannot be resolved or read.
   */
  text: string;
}
/** Options for `PDFReader#extractPageText()`. */
export interface PDFTextExtractionOptions {
  /**
   * Decode each element's `text` through its font. Defaults to true; false
   * leaves `text` out and skips reading the page's fonts.
   */
  decodeText?: boolean;
}
export type PDFPageContentItemType = 0 | 1 | 2 | 3;

/** A content-stream operation that produces a page mark. */
export interface PDFPageContentItem {
  type: PDFPageContentItemType;
  operation: string;
}

/**
 * Per-call extraction budget. Every field is clamped to a built-in ceiling,
 * so a caller may tighten a limit but never raise it above the default.
 * Omitted fields keep the ceiling. Independent of these, an extraction reads
 * at most 64 MiB of decoded content and throws past it.
 */
export interface PDFExtractionLimits {
  /** Extracted elements or items. Default and ceiling: 100000. */
  maxElements?: number;
  /** Pending operands per operator. Default and ceiling: 1024. */
  maxOperands?: number;
  /** Total extracted text. Default and ceiling: 16777216 (16 MiB). */
  maxTextBytes?: number;
  /** Content-stream objects parsed. Default and ceiling: 1000000. */
  maxParsedObjects?: number;
}
/** @deprecated Renamed to PDFExtractionLimits, which both extractors share. */
export type PDFTextExtractionLimits = PDFExtractionLimits;
/** A cross-reference entry read by `PDFReader#getXrefEntry()`. */
export interface PDFXrefEntry {
  objectPosition: number;
  revision: number;
  type: XrefEntryType;
}
/** Media box, rotation, and unrotated size read by `PDFReader#getPageInfo()`. */
export interface PDFPageGeometry {
  mediaBox: PDFRectangle;
  rotate: number;
  width: number;
  height: number;
}
export interface PDFReader {
  getPagesCount(): number;
  getPageObjectID(index: number): number;
  getPDFLevel(): number;
  getObjectsCount(): number;
  isEncrypted(): boolean;
  getXrefSize(): number;
  getXrefPosition(): number;
  getXrefEntry(id: number): PDFXrefEntry;
  getTrailerEntryType(key: string): PDFObjectType | null;
  getTrailer(): PDFDictionary;
  queryDictionaryObject(
    dictionary: PDFDictionary,
    key: string,
  ): PDFObject | undefined;
  queryArrayObject(array: PDFArray, index: number): PDFObject | undefined;
  parseNewObject(id: number): PDFObject;
  parsePageDictionary(index: number): PDFDictionary;
  parsePage(index: number): PDFPageInput;
  /**
   * Returns text-showing operations in PDF content-stream drawing order. Each
   * element's `text` is decoded through the active font and `content` keeps the
   * raw character codes. Glyph bounds are not calculated. Font decoding caches
   * each font per reader but charges every call the font's cost: it ignores a
   * `/ToUnicode` CMap over 4 MiB or beyond 32 MiB per call, and counts the PDF
   * objects it reads against `maxParsedObjects` on their own, so results never
   * depend on earlier calls.
   *
   * Throws when the page exceeds the extraction budget. `limits` may only
   * tighten the defaults: higher values are clamped to the built-in ceilings
   * of 1,000,000 content objects, 100,000 text operations, 1024 operands, and
   * 16 MiB of text. Pass `{ decodeText: false }` as `options` to skip font
   * decoding and leave `text` out.
   */
  extractPageText(
    pageIndex: number,
    limits?: PDFExtractionLimits,
    options?: PDFTextExtractionOptions & { decodeText?: true },
  ): PDFTextElement[];
  extractPageText(
    pageIndex: number,
    limits: PDFExtractionLimits | undefined,
    options: PDFTextExtractionOptions & { decodeText: false },
  ): PDFRawTextElement[];
  extractPageText(
    pageIndex: number,
    limits?: PDFExtractionLimits,
    options?: PDFTextExtractionOptions,
  ): PDFRawTextElement[];
  /**
   * Returns every direct content-stream operation that produces a page mark.
   * White-on-white content is included; non-painting operations are excluded.
   *
   * Shares `extractPageText`'s budget and clamping. `limits.maxTextBytes` is
   * accepted for signature parity but has no effect here, because items carry
   * an operator name rather than extracted text.
   */
  extractPageContentItems(
    pageIndex: number,
    limits?: PDFExtractionLimits,
  ): PDFPageContentItem[];
  startReadingObjectsFromStream(stream: PDFStreamInput): PDFObjectParser;
  startReadingObjectsFromStreams(streams: PDFArray): PDFObjectParser;
  startReadingFromStream(stream: PDFStreamInput): PDFByteReader;
  startReadingFromStreamForPlainCopying(stream: PDFStreamInput): PDFByteReader;
  getParserStream(): PositionedPDFByteReader;
  /** Available on readers obtained from a document copying context. */
  getSourceDocumentStream(): PositionedPDFByteReader;
  getPageInfo(index: number): PDFPageGeometry;
  getPageBox(index: number, box?: PageBox): PDFRectangle;
  end(): this;
}
export interface CopyingObjectOperations {
  copyObject(id: number): number;
  copyDirectObjectWithDeepCopy(object: PDFObject): number[];
  copyNewObjectsForDirectObject(ids: number[]): this;
  getCopiedObjectID(id: number): number;
  getCopiedObjects(): Record<string, number>;
  replaceSourceObjects(mapping: Record<string, number>): this;
}
export interface DocumentCopyingContext extends CopyingObjectOperations {
  getSourceDocumentParser(): PDFReader;
  getSourceDocumentStream(): PositionedPDFByteReader;
  copyDirectObjectAsIs(object: PDFObject): this;
  appendPDFPageFromPDF(index: number): number;
  appendPDFPagesFromPDF(start: number, end: number): this;
  mergePDFPageToPage(page: PDFPage, index: number): this;
  createFormXObjectFromPDFPage(
    index: number,
    pageBox?: PDFPageBoxType | PDFRectangle,
    transformation?: PDFMatrix,
  ): number;
  mergePDFPageToFormXObject(
    form: FormXObject | ModifierFormXObject,
    index: number,
  ): this;
  end(): this;
}
/** Stateful methods require an active writer and throw Error("PDF writer has ended") after cleanup. Async methods reject instead. */
export interface PDFWriter {
  appendPDFPagesFromPDF(
    source: ByteSource,
    options?: PageRangeOptions,
  ): number[];
  appendPDFPagesFromPDFAsync(
    source: AsyncByteSource,
    options?: PageRangeOptions,
  ): Promise<number[]>;
  /** Calls the optional callback with no arguments and globalThis as its receiver. */
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    options?: PageRangeOptions,
  ): this;
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    callback: (this: typeof globalThis) => void,
  ): this;
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    options: PageRangeOptions,
    callback: (this: typeof globalThis) => void,
  ): this;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    options?: PageRangeOptions,
  ): Promise<this>;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    callback: (this: typeof globalThis) => void,
  ): Promise<this>;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    options: PageRangeOptions,
    callback: (this: typeof globalThis) => void,
  ): Promise<this>;
  getDocumentContext(): DocumentContext;
  createPDFTextString(value?: string | ByteSource | number[]): PDFTextString;
  createPDFDate(value?: string | Date): PDFDate;
  getObjectsContext(): ObjectsContext;
  attachURLLinktoCurrentPage(
    url: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
  ): this;
  createAnnotation(
    subtype: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
    options?: AnnotationOptions,
  ): number;
  registerAnnotationReferenceForNextPageWrite(id: number): this;
  getFontForBytes(name: string, index?: number): PDFUsedFont;
  getFontForBytes(
    name: string,
    metricsName: string,
    index?: number,
  ): PDFUsedFont;
  requireCatalogUpdate(): void;
  getImageDimensions(
    image: string | ByteSource,
    imageIndex?: number,
  ): ImageDimensions;
  getImageDimensionsAsync(
    image: AsyncByteSource,
    imageIndex?: number,
  ): Promise<ImageDimensions>;
  getImageType(image: string | ByteSource): PDFImageType | undefined;
  getImageTypeAsync(image: AsyncByteSource): Promise<PDFImageType | undefined>;
  getImagePagesCount(image: string | ByteSource): number;
  getImagePagesCountAsync(image: AsyncByteSource): Promise<number>;
  retrieveJPGImageInformation(image: string | ByteSource): JPGImageInformation;
  retrieveJPGImageInformationAsync(
    image: AsyncByteSource,
  ): Promise<JPGImageInformation>;
  createImageXObjectFromJPGBytes(name: string, objectId?: number): ImageXObject;
  createFormXObjectFromJPGBytes(
    name: string,
    objectId?: number,
  ): CompletedFormXObject;
  createFormXObjectFromPNGBytes(
    name: string,
    objectId?: number,
  ): CompletedFormXObject;
  createFormXObjectFromTIFF(
    image: string | ByteSource,
    options?: TIFFOptions,
  ): CompletedFormXObject;
  createFormXObjectFromTIFFBytes(
    image: string | ByteSource,
    options?: TIFFOptions,
  ): CompletedFormXObject;
  createFormXObjectFromTIFFAsync(
    image: AsyncByteSource,
    options?: TIFFOptions,
  ): Promise<CompletedFormXObject>;
  createFormXObjectFromTIFFBytesAsync(
    image: AsyncByteSource,
    options?: TIFFOptions,
  ): Promise<CompletedFormXObject>;
  createFormXObject(
    left: number,
    bottom: number,
    right: number,
    top: number,
    objectId?: number,
  ): FormXObject;
  endFormXObject(form: FormXObject): this;
  createFormXObjectsFromPDF(
    source: string | ByteSource,
    pageBox?: PDFPageBoxType | PDFRectangle,
    options?: PDFFormOptions,
  ): number[];
  createFormXObjectsFromPDFAsync(
    source: AsyncByteSource,
    pageBox?: PDFPageBoxType | PDFRectangle,
    options?: PDFFormOptions,
  ): Promise<number[]>;
  /** A source `password` throws; decrypt the source with `recrypt()` first. */
  createPDFCopyingContext(
    source: ByteSource,
    options?: PDFReaderOptions,
  ): DocumentCopyingContext;
  createPDFCopyingContextAsync(
    source: AsyncByteSource,
    options?: PDFReaderOptions,
  ): Promise<DocumentCopyingContext>;
  createPage(
    left?: number,
    bottom?: number,
    right?: number,
    top?: number,
  ): PDFPage;
  startPageContentContext(page: PDFPage): ContentContext;
  pausePageContentContext(context: ContentContext): this;
  writePage(page: PDFPage): this;
  writePageAndReturnID(page: PDFPage): number;
  end(): Uint8Array<ArrayBuffer>;
  dispose(): void;
}
export interface PageModifier {
  startContext(): this;
  getContext(): ContentContext;
  getResourcesDictionary(): ResourcesDictionary;
  attachURLLinktoCurrentPage(
    url: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
  ): this;
  createAnnotation(
    subtype: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
    options?: AnnotationOptions,
  ): number;
  endContext(): this;
  writePage(): this;
}
/** An open modifier-owned form may be ended directly or through the modifier. */
export interface ModifierFormXObject extends FormXObject {
  end(): this;
}
export interface ModifierImageXObject {
  readonly id: number;
}
export interface ModifierCompletedFormXObject {
  readonly id: number;
}
/** Where `replaceObject()` replaces references: `global` means every page. */
export type ObjectReplacementScope = "global";
export declare const ObjectReplacementScope: {
  readonly GLOBAL: "global";
};
export interface ObjectReplacementOptions {
  scope?: ObjectReplacementScope;
}
export interface PDFModifier {
  createFormXObject(
    left: number,
    bottom: number,
    right: number,
    top: number,
    objectId?: number,
  ): ModifierFormXObject;
  endFormXObject(form: ModifierFormXObject): this;
  createFormXObjectFromTIFF(
    image: string | ByteSource,
    options?: TIFFOptions,
  ): ModifierCompletedFormXObject;
  createFormXObjectFromTIFFBytes(
    image: string | ByteSource,
    options?: TIFFOptions,
  ): ModifierCompletedFormXObject;
  createFormXObjectFromTIFFAsync(
    image: AsyncByteSource,
    options?: TIFFOptions,
  ): Promise<ModifierCompletedFormXObject>;
  createFormXObjectFromTIFFBytesAsync(
    image: AsyncByteSource,
    options?: TIFFOptions,
  ): Promise<ModifierCompletedFormXObject>;
  createPage(
    left?: number,
    bottom?: number,
    right?: number,
    top?: number,
  ): PDFPage;
  getFontForBytes(name: string, index?: number): PDFUsedFont;
  getFontForBytes(
    name: string,
    metricsName: string,
    index?: number,
  ): PDFUsedFont;
  requireCatalogUpdate(): void;
  /**
   * Replaces matching direct references in one original page dictionary.
   * Set `scope` to `global` to replace matching references on every page.
   * All IDs must be positive unsigned 32-bit IDs from this modified PDF.
   */
  replaceObject(
    pageIndex: number,
    sourceObjectId: number,
    replacementObjectId: number,
    options?: ObjectReplacementOptions,
  ): this;
  getObjectsContext(): ObjectsContext;
  getModifiedFileParser(): PDFReader;
  getDocumentContext(): DocumentContext;
  createPDFTextString(value?: string | ByteSource | number[]): PDFTextString;
  createPDFDate(value?: string | Date): PDFDate;
  startPageContentContext(page: PDFPage): ContentContext;
  pausePageContentContext(context: ContentContext): this;
  createPageModifier(
    index?: number,
    ensureContentEncapsulation?: boolean,
  ): PageModifier;
  writePage(page: PDFPage): this;
  writePageAndReturnID(page: PDFPage): number;
  attachURLLinktoCurrentPage(
    url: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
  ): this;
  createAnnotation(
    subtype: string,
    left: number,
    bottom: number,
    right: number,
    top: number,
    options?: AnnotationOptions,
  ): number;
  registerAnnotationReferenceForNextPageWrite(id: number): this;
  appendPDFPagesFromPDF(
    source: ByteSource,
    options?: PageRangeOptions,
  ): number[];
  appendPDFPagesFromPDFAsync(
    source: AsyncByteSource,
    options?: PageRangeOptions,
  ): Promise<number[]>;
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    options?: PageRangeOptions,
  ): this;
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    callback: (this: typeof globalThis) => void,
  ): this;
  mergePDFPagesToPage(
    page: PDFPage,
    source: ByteSource,
    options: PageRangeOptions,
    callback: (this: typeof globalThis) => void,
  ): this;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    options?: PageRangeOptions,
  ): Promise<this>;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    callback: (this: typeof globalThis) => void,
  ): Promise<this>;
  mergePDFPagesToPageAsync(
    page: PDFPage,
    source: AsyncByteSource,
    options: PageRangeOptions,
    callback: (this: typeof globalThis) => void,
  ): Promise<this>;
  getImageDimensions(
    image: string | ByteSource,
    imageIndex?: number,
  ): ImageDimensions;
  getImageDimensionsAsync(
    image: AsyncByteSource,
    imageIndex?: number,
  ): Promise<ImageDimensions>;
  getImageType(image: string | ByteSource): PDFImageType | undefined;
  getImageTypeAsync(image: AsyncByteSource): Promise<PDFImageType | undefined>;
  getImagePagesCount(image: string | ByteSource): number;
  getImagePagesCountAsync(image: AsyncByteSource): Promise<number>;
  retrieveJPGImageInformation(image: string | ByteSource): JPGImageInformation;
  retrieveJPGImageInformationAsync(
    image: AsyncByteSource,
  ): Promise<JPGImageInformation>;
  createImageXObjectFromJPGBytes(
    name: string,
    objectId?: number,
  ): ModifierImageXObject;
  createFormXObjectFromJPGBytes(
    name: string,
    objectId?: number,
  ): ModifierCompletedFormXObject;
  createFormXObjectFromPNGBytes(
    name: string,
    objectId?: number,
  ): ModifierCompletedFormXObject;
  createFormXObjectsFromPDF(
    source: string | ByteSource,
    pageBox?: PDFPageBoxType | PDFRectangle,
    options?: PDFFormOptions,
  ): number[];
  createFormXObjectsFromPDFAsync(
    source: AsyncByteSource,
    pageBox?: PDFPageBoxType | PDFRectangle,
    options?: PDFFormOptions,
  ): Promise<number[]>;
  /** A source `password` throws; decrypt the source with `recrypt()` first. */
  createPDFCopyingContext(
    source: ByteSource,
    options?: PDFReaderOptions,
  ): DocumentCopyingContext;
  createPDFCopyingContextAsync(
    source: AsyncByteSource,
    options?: PDFReaderOptions,
  ): Promise<DocumentCopyingContext>;
  createPDFCopyingContextForModifiedFile(): DocumentCopyingContext;
  end(): Uint8Array<ArrayBuffer>;
  dispose(): void;
}
/** Low-level color: a 24-bit RGB number, `#rrggbb`, a CSS color name in any case, or three 0-255 components. Other strings throw a `TypeError`. */
export type ColorValue = number | string | [number, number, number];
/** Colors for CompactModifier rectangles and circles; `fill` wins over `stroke` and `color`. */
export interface CompactModifierShapeOptions {
  color?: ColorValue;
  fill?: ColorValue;
  stroke?: ColorValue;
}
/** Line color and width for CompactModifier.line(); `stroke` wins over `color`. */
export interface CompactModifierLineOptions {
  color?: ColorValue;
  stroke?: ColorValue;
  lineWidth?: number;
}
/** Font and color for CompactModifier.text(); `font` names a registered font. */
export interface CompactModifierTextOptions {
  font: string;
  fontSize?: number;
  color?: ColorValue;
}
export interface CompactModifier {
  startPage(index: number): this;
  rectangle(
    x: number,
    y: number,
    width: number,
    height: number,
    options?: CompactModifierShapeOptions,
  ): this;
  circle(
    x: number,
    y: number,
    radius: number,
    options?: CompactModifierShapeOptions,
  ): this;
  line(
    startX: number,
    startY: number,
    endX: number,
    endY: number,
    options?: CompactModifierLineOptions,
  ): this;
  text(
    value: string,
    x: number,
    y: number,
    options: CompactModifierTextOptions,
  ): this;
  image(
    name: string,
    x: number,
    y: number,
    width: number,
    height: number,
  ): this;
  endPage(): this;
  end(): Uint8Array<ArrayBuffer>;
  dispose(): void;
}
export interface MuhammaraWasm {
  PDFPage: typeof PDFPage;
  PDFDate: typeof PDFDate;
  PDFTextString: typeof PDFTextString;
  PDFRStreamForBuffer: typeof PDFRStreamForBuffer;
  PDFWStreamForBuffer: typeof PDFWStreamForBuffer;
  ByteReader: typeof ByteReader;
  ByteReaderWithPosition: typeof ByteReaderWithPosition;
  ByteWriter: typeof ByteWriter;
  ByteWriterWithPosition: typeof ByteWriterWithPosition;
  createWriter(options?: CreateWriterOptions): PDFWriter;
  /**
   * Decrypts, re-encrypts, or rewrites a PDF, like native `recrypt()`.
   * `null` options mean no options.
   */
  recrypt(
    source: ByteSource,
    options?: PDFRecryptOptions | null,
  ): Uint8Array<ArrayBuffer>;
  /**
   * Like `recrypt()`, after reading a Blob, File, or bytes. Recrypting runs in
   * a worker, so the calling thread stays free; see
   * `MuhammaraWasmOptions.recryptWorker` for when it runs on the calling
   * thread instead.
   */
  recryptAsync(
    source: AsyncByteSource,
    options?: PDFRecryptOptions | null,
  ): Promise<Uint8Array<ArrayBuffer>>;
  createWriterToModify(
    source: ByteSource,
    options?: WriterOptions,
  ): PDFModifier;
  createWriterToModifyAsync(
    source: AsyncByteSource,
    options?: WriterOptions,
  ): Promise<PDFModifier>;
  createReader(source: ByteSource, options?: PDFReaderOptions): PDFReader;
  createReaderAsync(
    source: AsyncByteSource,
    options?: PDFReaderOptions,
  ): Promise<PDFReader>;
  createModifier(source: ByteSource): CompactModifier;
  createModifierAsync(source: AsyncByteSource): Promise<CompactModifier>;
  registerFont(name: string, bytes: ByteSource): string;
  registerFontAsync(name: string, bytes: AsyncByteSource): Promise<string>;
  registerImage(name: string, bytes: ByteSource, extension: string): void;
  registerImageAsync(
    name: string,
    bytes: AsyncByteSource,
    extension: string,
  ): Promise<void>;
  registerPdf(name: string, bytes: ByteSource): void;
  registerPdfAsync(name: string, bytes: AsyncByteSource): Promise<void>;
  unregisterFont(name: string): boolean;
  unregisterImage(name: string): boolean;
  unregisterPdf(name: string): boolean;
  disposeAssets(): void;
  createBlankPdf(width: number, height: number): Uint8Array<ArrayBuffer>;
  readonly ePDFVersionUndefined: 0;
  readonly ePDFVersion10: 10;
  readonly ePDFVersion11: 11;
  readonly ePDFVersion12: 12;
  readonly ePDFVersion13: 13;
  readonly ePDFVersion14: 14;
  readonly ePDFVersion15: 15;
  readonly ePDFVersion16: 16;
  readonly ePDFVersion17: 17;
  readonly ePDFVersion20: 20;
  readonly KProcsetImageB: "ImageB";
  readonly KProcsetImageC: "ImageC";
  readonly KProcsetImageI: "ImageI";
  readonly kProcsetPDF: "PDF";
  readonly kProcsetText: "Text";
  readonly eRangeTypeAll: 0;
  readonly eRangeTypeSpecific: 1;
  readonly ePDFPageBoxMediaBox: 0;
  readonly ePDFPageBoxCropBox: 1;
  readonly ePDFPageBoxBleedBox: 2;
  readonly ePDFPageBoxTrimBox: 3;
  readonly ePDFPageBoxArtBox: 4;
  readonly ePDFObjectBoolean: 0;
  readonly ePDFObjectLiteralString: 1;
  readonly ePDFObjectHexString: 2;
  readonly ePDFObjectNull: 3;
  readonly ePDFObjectName: 4;
  readonly ePDFObjectInteger: 5;
  readonly ePDFObjectReal: 6;
  readonly ePDFObjectArray: 7;
  readonly ePDFObjectDictionary: 8;
  readonly ePDFObjectIndirectObjectReference: 9;
  readonly ePDFObjectStream: 10;
  readonly ePDFObjectSymbol: 11;
  readonly ePDFPageContentItemText: 0;
  readonly ePDFPageContentItemPath: 1;
  readonly ePDFPageContentItemXObject: 2;
  readonly ePDFPageContentItemShading: 3;
  readonly eTokenSeparatorSpace: 0;
  readonly eTokenSeparatorEndLine: 1;
  readonly eTokenSeparatorNone: 2;
  readonly eXrefEntryExisting: 0;
  readonly eXrefEntryDelete: 1;
  readonly eXrefEntryStreamObject: 2;
  readonly eXrefEntryUndefined: 3;
  readonly EInfoTrappedTrue: 0;
  readonly EInfoTrappedFalse: 1;
  readonly EInfoTrappedUnknown: 2;
  getTypeLabel(type: PDFObjectType): string;
}
export interface MuhammaraWasmOptions {
  /**
   * Maps the requested file name (`muhammara-wasm.wasm`) to the URL, or under
   * Node the path or `file:` URL, to load it from. When `wasmBinary` is
   * supplied, the returned location is not loaded.
   */
  locateFile?: (path: string, prefix: string) => string;
  /**
   * Bytes of `muhammara-wasm.wasm` obtained by the caller, for example with
   * `fetch()` or `File.arrayBuffer()`. When supplied, the binary is not
   * fetched or read and `limits` does not apply to it. Other typed arrays,
   * `DataView`, and `Blob` are rejected with a `TypeError`.
   */
  wasmBinary?: Uint8Array | ArrayBuffer;
  limits?: {
    maxInputBytes?: number;
    maxOutputBytes?: number;
  };
  /**
   * Whether `recryptAsync()` recrypts in a worker: `worker_threads` in
   * Node, Deno, and Bun, a module `Worker` in browsers. Defaults to `true`.
   * The worker loads the binary from `wasmBinary` or from the location
   * `locateFile` returned. With `false`, inside a worker, where no worker can
   * start, or with module options other than `wasmBinary`, `locateFile`, and
   * `limits`, it recrypts on the calling thread.
   */
  recryptWorker?: boolean;
  [key: string]: unknown;
}
export function createMuhammaraWasm(
  options?: MuhammaraWasmOptions,
): Promise<MuhammaraWasm>;

export interface CreateRecipeOptions extends MuhammaraWasmOptions {
  /**
   * Omit to load bundled Roboto Regular. Supply font bytes/Blob/File to use a
   * custom default (family "default"), or false to require named registered fonts.
   * Custom bytes and false both skip importing the bundled font module.
   */
  defaultFont?: AsyncByteSource | false;
}

/** Loads the byte-first Recipe constructor and its optional default font. */
export function createRecipe(
  options?: CreateRecipeOptions,
): Promise<RecipeConstructor>;