@libpdf/core 0.0.1-beta.6 → 0.0.1-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { deflate, inflate } from "pako";
1
+ import pako, { deflate, inflate } from "pako";
2
2
  import { z } from "zod";
3
3
  import { cbc, ecb } from "@noble/ciphers/aes.js";
4
4
  import { randomBytes } from "@noble/ciphers/utils.js";
@@ -9,7 +9,7 @@ import * as pkijs from "pkijs";
9
9
  import { base64 } from "@scure/base";
10
10
 
11
11
  //#region package.json
12
- var version = "0.0.1-beta.6";
12
+ var version = "0.0.1-beta.7";
13
13
 
14
14
  //#endregion
15
15
  //#region src/objects/pdf-array.ts
@@ -906,7 +906,7 @@ var ASCIIHexFilter = class ASCIIHexFilter {
906
906
  name = "ASCIIHexDecode";
907
907
  static END_MARKER = 62;
908
908
  static NIBBLE_MASK = 15;
909
- async decode(data, _params) {
909
+ decode(data, _params) {
910
910
  const output = new ByteWriter();
911
911
  let high = null;
912
912
  for (const byte of data) {
@@ -923,7 +923,7 @@ var ASCIIHexFilter = class ASCIIHexFilter {
923
923
  if (high !== null) output.writeByte(high << 4);
924
924
  return output.toBytes();
925
925
  }
926
- async encode(data, _params) {
926
+ encode(data, _params) {
927
927
  const hexChars = "0123456789ABCDEF";
928
928
  const result = new Uint8Array(data.length * 2 + 1);
929
929
  let i = 0;
@@ -956,7 +956,7 @@ var ASCII85Filter = class ASCII85Filter {
956
956
  static END_MARKER = 126;
957
957
  static END_MARKER_FOLLOWING = 62;
958
958
  static ZERO_SHORTCUT = 122;
959
- async decode(data, _params) {
959
+ decode(data, _params) {
960
960
  const output = new ByteWriter();
961
961
  let buffer = 0;
962
962
  let count = 0;
@@ -994,7 +994,7 @@ var ASCII85Filter = class ASCII85Filter {
994
994
  }
995
995
  return output.toBytes();
996
996
  }
997
- async encode(data, _params) {
997
+ encode(data, _params) {
998
998
  const output = new ByteWriter();
999
999
  let i = 0;
1000
1000
  while (i < data.length) {
@@ -1051,7 +1051,7 @@ var ASCII85Filter = class ASCII85Filter {
1051
1051
  */
1052
1052
  var CCITTFaxFilter = class {
1053
1053
  name = "CCITTFaxDecode";
1054
- async decode(data, params) {
1054
+ decode(data, params) {
1055
1055
  const k = params?.getNumber("K")?.value ?? 0;
1056
1056
  const columns = params?.getNumber("Columns")?.value ?? 1728;
1057
1057
  const rows = params?.getNumber("Rows")?.value ?? 0;
@@ -1065,7 +1065,7 @@ var CCITTFaxFilter = class {
1065
1065
  if (!blackIs1) for (let i = 0; i < result.length; i++) result[i] = ~result[i] & SINGLE_BYTE_MASK;
1066
1066
  return result;
1067
1067
  }
1068
- async encode(_data, _params) {
1068
+ encode(_data, _params) {
1069
1069
  throw new Error("CCITTFaxDecode: Encoding not implemented");
1070
1070
  }
1071
1071
  /**
@@ -1374,7 +1374,7 @@ var DCTFilter = class {
1374
1374
  * - Decoded by canvas.drawImage()
1375
1375
  * - Passed to an external JPEG library for pixel access
1376
1376
  */
1377
- async decode(data, _params) {
1377
+ decode(data, _params) {
1378
1378
  if (data.length >= 2) {
1379
1379
  if (data[0] !== 255 || data[1] !== 216) console.warn("DCTDecode: Data does not appear to be valid JPEG");
1380
1380
  }
@@ -1385,7 +1385,7 @@ var DCTFilter = class {
1385
1385
  *
1386
1386
  * For actual JPEG encoding from raw pixels, use an external library.
1387
1387
  */
1388
- async encode(data, _params) {
1388
+ encode(data, _params) {
1389
1389
  return data;
1390
1390
  }
1391
1391
  };
@@ -1572,15 +1572,15 @@ function paethPredictor$1(a, b, c) {
1572
1572
  */
1573
1573
  var FlateFilter = class {
1574
1574
  name = "FlateDecode";
1575
- async decode(data, params) {
1576
- const decompressed = (await import("pako")).inflate(data);
1575
+ decode(data, params) {
1576
+ const decompressed = pako.inflate(data);
1577
1577
  if (params) {
1578
1578
  if ((params.getNumber("Predictor")?.value ?? 1) > 1) return applyPredictor(decompressed, params);
1579
1579
  }
1580
1580
  return decompressed;
1581
1581
  }
1582
- async encode(data, _params) {
1583
- return (await import("pako")).deflate(data);
1582
+ encode(data, _params) {
1583
+ return pako.deflate(data);
1584
1584
  }
1585
1585
  };
1586
1586
 
@@ -1606,11 +1606,11 @@ var FlateFilter = class {
1606
1606
  */
1607
1607
  var JBIG2Filter = class {
1608
1608
  name = "JBIG2Decode";
1609
- async decode(data, params) {
1609
+ decode(data, params) {
1610
1610
  if (params?.get("JBIG2Globals")) throw new Error("JBIG2Decode: Decoding not implemented. This stream uses JBIG2 compression with global symbols. Consider using an external JBIG2 decoder library.");
1611
1611
  throw new Error(`JBIG2Decode: Decoding not implemented. Stream contains ${data.length} bytes of JBIG2 data. Consider using an external JBIG2 decoder library (e.g., jbig2dec).`);
1612
1612
  }
1613
- async encode(_data, _params) {
1613
+ encode(_data, _params) {
1614
1614
  throw new Error("JBIG2Decode: Encoding not implemented");
1615
1615
  }
1616
1616
  /**
@@ -1643,11 +1643,11 @@ var JBIG2Filter = class {
1643
1643
  */
1644
1644
  var JPXFilter = class {
1645
1645
  name = "JPXDecode";
1646
- async decode(data, _params) {
1646
+ decode(data, _params) {
1647
1647
  const isValidJP2 = this.isJPEG2000(data);
1648
1648
  throw new Error(`JPXDecode: Decoding not implemented. Stream contains ${data.length} bytes of ${isValidJP2 ? "valid" : "possible"} JPEG 2000 data. Consider using an external JPEG 2000 decoder library (e.g., OpenJPEG).`);
1649
1649
  }
1650
- async encode(_data, _params) {
1650
+ encode(_data, _params) {
1651
1651
  throw new Error("JPXDecode: Encoding not implemented");
1652
1652
  }
1653
1653
  /**
@@ -1701,7 +1701,7 @@ var LZWFilter = class LZWFilter {
1701
1701
  name = "LZWDecode";
1702
1702
  static CLEAR_CODE = 256;
1703
1703
  static EOD_CODE = 257;
1704
- async decode(data, params) {
1704
+ decode(data, params) {
1705
1705
  const earlyChange = params?.getNumber("EarlyChange")?.value ?? 1;
1706
1706
  const result = this.lzwDecode(data, earlyChange);
1707
1707
  if (params) {
@@ -1709,7 +1709,7 @@ var LZWFilter = class LZWFilter {
1709
1709
  }
1710
1710
  return result;
1711
1711
  }
1712
- async encode(_data, _params) {
1712
+ encode(_data, _params) {
1713
1713
  throw new Error("LZW encoding not implemented");
1714
1714
  }
1715
1715
  lzwDecode(data, earlyChange) {
@@ -1793,7 +1793,7 @@ var LZWFilter = class LZWFilter {
1793
1793
  */
1794
1794
  var RunLengthFilter = class {
1795
1795
  name = "RunLengthDecode";
1796
- async decode(data, _params) {
1796
+ decode(data, _params) {
1797
1797
  const output = new ByteWriter();
1798
1798
  let i = 0;
1799
1799
  while (i < data.length) {
@@ -1810,7 +1810,7 @@ var RunLengthFilter = class {
1810
1810
  }
1811
1811
  return output.toBytes();
1812
1812
  }
1813
- async encode(data, _params) {
1813
+ encode(data, _params) {
1814
1814
  const output = new ByteWriter();
1815
1815
  let i = 0;
1816
1816
  while (i < data.length) {
@@ -1898,14 +1898,14 @@ var FilterPipeline = class FilterPipeline {
1898
1898
  * @returns Decoded data
1899
1899
  * @throws {Error} if a filter is not registered
1900
1900
  */
1901
- static async decode(data, filters) {
1901
+ static decode(data, filters) {
1902
1902
  const filterList = Array.isArray(filters) ? filters : [filters];
1903
1903
  if (filterList.length === 0) return data;
1904
1904
  let result = data;
1905
1905
  for (const spec of filterList) {
1906
1906
  const filter = FilterPipeline.filters.get(spec.name);
1907
1907
  if (!filter) throw new Error(`Unknown filter: ${spec.name}`);
1908
- result = await filter.decode(result, spec.params);
1908
+ result = filter.decode(result, spec.params);
1909
1909
  }
1910
1910
  return result;
1911
1911
  }
@@ -1921,14 +1921,14 @@ var FilterPipeline = class FilterPipeline {
1921
1921
  * @returns Encoded data
1922
1922
  * @throws {Error} if a filter is not registered
1923
1923
  */
1924
- static async encode(data, filters) {
1924
+ static encode(data, filters) {
1925
1925
  const filterList = Array.isArray(filters) ? filters : [filters];
1926
1926
  if (filterList.length === 0) return data;
1927
1927
  let result = data;
1928
1928
  for (const spec of filterList.toReversed()) {
1929
1929
  const filter = FilterPipeline.filters.get(spec.name);
1930
1930
  if (!filter) throw new Error(`Unknown filter: ${spec.name}`);
1931
- result = await filter.encode(result, spec.params);
1931
+ result = filter.encode(result, spec.params);
1932
1932
  }
1933
1933
  return result;
1934
1934
  }
@@ -2033,7 +2033,7 @@ var PdfStream = class PdfStream extends PdfDict {
2033
2033
  * @returns Decoded data
2034
2034
  * @throws {Error} if a filter fails or is unknown
2035
2035
  */
2036
- async getDecodedData() {
2036
+ getDecodedData() {
2037
2037
  const filterEntry = this.get("Filter");
2038
2038
  if (!filterEntry) return this._data;
2039
2039
  const filterSpecs = this.buildFilterSpecs(filterEntry);
@@ -2055,7 +2055,7 @@ var PdfStream = class PdfStream extends PdfDict {
2055
2055
  *
2056
2056
  * @returns Encoded data (compressed if filters are specified)
2057
2057
  */
2058
- async getEncodedData() {
2058
+ getEncodedData() {
2059
2059
  const filterEntry = this.get("Filter");
2060
2060
  if (!filterEntry) return this._data;
2061
2061
  const filterSpecs = this.buildFilterSpecs(filterEntry);
@@ -2154,11 +2154,11 @@ var ObjectCopier = class {
2154
2154
  * @returns Reference to the copied page in destination document
2155
2155
  */
2156
2156
  async copyPage(srcPageRef) {
2157
- const srcPage = await this.source.getObject(srcPageRef);
2158
- if (!(srcPage instanceof PdfDict)) throw new Error(`Page object not found or not a dictionary: ${srcPageRef}`);
2157
+ const srcPage = this.source.getObject(srcPageRef);
2158
+ if (!(srcPage instanceof PdfDict)) throw new Error(`Page object not found or not a dictionary: ${srcPageRef.objectNumber} ${srcPageRef.generation} R`);
2159
2159
  const cloned = srcPage.clone();
2160
2160
  for (const key$1 of INHERITABLE_PAGE_ATTRS) if (!cloned.has(key$1)) {
2161
- const inherited = await this.getInheritedAttribute(srcPage, key$1);
2161
+ const inherited = this.getInheritedAttribute(srcPage, key$1);
2162
2162
  if (inherited) {
2163
2163
  const copied = await this.copyObject(inherited);
2164
2164
  cloned.set(key$1, copied);
@@ -2176,10 +2176,10 @@ var ObjectCopier = class {
2176
2176
  * Deep copy any PDF object, remapping references to destination.
2177
2177
  */
2178
2178
  async copyObject(obj) {
2179
- if (obj instanceof PdfRef) return this.copyRef(obj);
2180
- if (obj instanceof PdfStream) return this.copyStream(obj);
2181
- if (obj instanceof PdfDict) return this.copyDict(obj);
2182
- if (obj instanceof PdfArray) return this.copyArray(obj);
2179
+ if (obj instanceof PdfRef) return await this.copyRef(obj);
2180
+ if (obj instanceof PdfStream) return await this.copyStream(obj);
2181
+ if (obj instanceof PdfDict) return await this.copyDict(obj);
2182
+ if (obj instanceof PdfArray) return await this.copyArray(obj);
2183
2183
  return obj;
2184
2184
  }
2185
2185
  /**
@@ -2192,7 +2192,7 @@ var ObjectCopier = class {
2192
2192
  const key$1 = `${ref.objectNumber}:${ref.generation}`;
2193
2193
  const existing = this.refMap.get(key$1);
2194
2194
  if (existing) return existing;
2195
- const srcObj = await this.source.getObject(ref);
2195
+ const srcObj = this.source.getObject(ref);
2196
2196
  if (srcObj === null) {
2197
2197
  const nullRef = this.dest.register(new PdfDict());
2198
2198
  this.refMap.set(key$1, nullRef);
@@ -2231,10 +2231,10 @@ var ObjectCopier = class {
2231
2231
  let streamData;
2232
2232
  if (!sourceWasEncrypted) streamData = srcStream.data;
2233
2233
  else try {
2234
- const decodedData = await srcStream.getDecodedData();
2234
+ const decodedData = srcStream.getDecodedData();
2235
2235
  if (srcStream.get("Filter")) try {
2236
2236
  const filterSpecs = this.buildFilterSpecs(srcStream);
2237
- streamData = await FilterPipeline.encode(decodedData, filterSpecs);
2237
+ streamData = FilterPipeline.encode(decodedData, filterSpecs);
2238
2238
  clonedDict.set("Length", PdfNumber.of(streamData.length));
2239
2239
  } catch (error) {
2240
2240
  console.warn(`Could not re-encode stream ${key$1}, will use uncompressed data`);
@@ -2303,10 +2303,10 @@ var ObjectCopier = class {
2303
2303
  await this.copyDictValues(clonedDict);
2304
2304
  if (!sourceWasEncrypted) return new PdfStream(clonedDict, stream.data);
2305
2305
  try {
2306
- const decodedData = await stream.getDecodedData();
2306
+ const decodedData = stream.getDecodedData();
2307
2307
  if (stream.get("Filter")) try {
2308
2308
  const filterSpecs = this.buildFilterSpecs(stream);
2309
- const encodedData = await FilterPipeline.encode(decodedData, filterSpecs);
2309
+ const encodedData = FilterPipeline.encode(decodedData, filterSpecs);
2310
2310
  clonedDict.set("Length", PdfNumber.of(encodedData.length));
2311
2311
  return new PdfStream(clonedDict, encodedData);
2312
2312
  } catch (error) {
@@ -2351,14 +2351,14 @@ var ObjectCopier = class {
2351
2351
  /**
2352
2352
  * Walk up the page tree to find an inherited attribute.
2353
2353
  */
2354
- async getInheritedAttribute(page, key$1) {
2354
+ getInheritedAttribute(page, key$1) {
2355
2355
  let current = page;
2356
2356
  while (current) {
2357
2357
  const value = current.get(key$1);
2358
2358
  if (value) return value;
2359
2359
  const parentRef = current.getRef("Parent");
2360
2360
  if (!parentRef) break;
2361
- const parent = await this.source.getObject(parentRef);
2361
+ const parent = this.source.getObject(parentRef);
2362
2362
  current = parent instanceof PdfDict ? parent : null;
2363
2363
  }
2364
2364
  return null;
@@ -2486,11 +2486,11 @@ var ObjectRegistry = class {
2486
2486
  * @param ref - The reference to resolve
2487
2487
  * @returns The object, or null if not found
2488
2488
  */
2489
- async resolve(ref) {
2489
+ resolve(ref) {
2490
2490
  const existing = this.getObject(ref);
2491
2491
  if (existing !== null) return existing;
2492
2492
  if (this.resolver) {
2493
- const obj = await this.resolver(ref);
2493
+ const obj = this.resolver(ref);
2494
2494
  if (obj !== null) this.addLoaded(ref, obj);
2495
2495
  return obj;
2496
2496
  }
@@ -3597,7 +3597,7 @@ function refKey(ref) {
3597
3597
  /**
3598
3598
  * Parse the default configuration from OCProperties.D
3599
3599
  */
3600
- async function parseDefaultConfig(dDict, resolve) {
3600
+ function parseDefaultConfig(dDict, resolve) {
3601
3601
  const result = {
3602
3602
  baseState: "ON",
3603
3603
  onRefs: /* @__PURE__ */ new Set(),
@@ -3606,10 +3606,9 @@ async function parseDefaultConfig(dDict, resolve) {
3606
3606
  };
3607
3607
  if (!dDict) return result;
3608
3608
  let dict = null;
3609
- if (dDict instanceof PdfRef) {
3610
- const resolved = await resolve(dDict);
3611
- if (resolved instanceof PdfDict) dict = resolved;
3612
- } else if (dDict instanceof PdfDict) dict = dDict;
3609
+ let resolved = dDict;
3610
+ if (resolved instanceof PdfRef) resolved = resolve(resolved) ?? void 0;
3611
+ if (resolved instanceof PdfDict) dict = resolved;
3613
3612
  if (!dict) return result;
3614
3613
  const baseState = dict.get("BaseState");
3615
3614
  if (baseState instanceof PdfName) {
@@ -3636,19 +3635,19 @@ async function parseDefaultConfig(dDict, resolve) {
3636
3635
  * Performs a thorough check that verifies OCProperties exists and
3637
3636
  * contains at least one valid OCG entry.
3638
3637
  */
3639
- async function hasLayers(ctx) {
3638
+ function hasLayers(ctx) {
3640
3639
  const catalog = ctx.catalog.getDict();
3641
3640
  if (!catalog) return false;
3642
3641
  let ocProperties = catalog.get("OCProperties");
3643
3642
  if (!ocProperties) return false;
3644
3643
  let ocPropsDict = null;
3645
- if (ocProperties instanceof PdfRef) ocProperties = await ctx.resolve(ocProperties) ?? void 0;
3644
+ if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
3646
3645
  if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
3647
3646
  if (!ocPropsDict) return false;
3648
3647
  let ocgs = ocPropsDict.get("OCGs");
3649
3648
  if (!ocgs) return false;
3650
3649
  let ocgsArray = null;
3651
- if (ocgs instanceof PdfRef) ocgs = await ctx.resolve(ocgs) ?? void 0;
3650
+ if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
3652
3651
  if (ocgs instanceof PdfArray) ocgsArray = ocgs;
3653
3652
  if (!ocgsArray || ocgsArray.length === 0) return false;
3654
3653
  return true;
@@ -3659,32 +3658,32 @@ async function hasLayers(ctx) {
3659
3658
  * Returns layer metadata including name, visibility state,
3660
3659
  * intent, and locked status based on the default configuration.
3661
3660
  */
3662
- async function getLayers(ctx) {
3661
+ function getLayers(ctx) {
3663
3662
  const catalog = ctx.catalog.getDict();
3664
3663
  if (!catalog) return [];
3665
3664
  let ocProperties = catalog.get("OCProperties");
3666
3665
  if (!ocProperties) return [];
3667
3666
  let ocPropsDict = null;
3668
- if (ocProperties instanceof PdfRef) ocProperties = await ctx.resolve(ocProperties) ?? void 0;
3667
+ if (ocProperties instanceof PdfRef) ocProperties = ctx.resolve(ocProperties) ?? void 0;
3669
3668
  if (ocProperties instanceof PdfDict) ocPropsDict = ocProperties;
3670
3669
  if (!ocPropsDict) return [];
3671
3670
  let ocgs = ocPropsDict.get("OCGs");
3672
3671
  if (!ocgs) return [];
3673
3672
  let ocgsArray = null;
3674
- if (ocgs instanceof PdfRef) ocgs = await ctx.resolve(ocgs) ?? void 0;
3673
+ if (ocgs instanceof PdfRef) ocgs = ctx.resolve(ocgs) ?? void 0;
3675
3674
  if (ocgs instanceof PdfArray) ocgsArray = ocgs;
3676
3675
  if (!ocgsArray) return [];
3677
- const defaultConfig = await parseDefaultConfig(ocPropsDict.get("D"), (ref) => ctx.resolve(ref));
3676
+ const defaultConfig = parseDefaultConfig(ocPropsDict.get("D"), (ref) => ctx.resolve(ref));
3678
3677
  const layers = [];
3679
3678
  for (const item of ocgsArray) {
3680
3679
  if (!(item instanceof PdfRef)) continue;
3681
- const ocg = await ctx.resolve(item);
3680
+ const ocg = ctx.resolve(item);
3682
3681
  if (!(ocg instanceof PdfDict)) continue;
3683
3682
  const nameObj = ocg.get("Name");
3684
3683
  let name = "Unnamed";
3685
3684
  if (nameObj instanceof PdfString) name = nameObj.asString();
3686
3685
  else if (nameObj instanceof PdfName) name = nameObj.value;
3687
- else if (nameObj) name = String(nameObj);
3686
+ else if (nameObj) name = `[${nameObj.type}]`;
3688
3687
  const intentObj = ocg.get("Intent");
3689
3688
  let intent;
3690
3689
  if (intentObj instanceof PdfName) intent = intentObj.value;
@@ -3715,7 +3714,7 @@ async function getLayers(ctx) {
3715
3714
  * content unconditionally visible and removes the layer toggle UI from
3716
3715
  * PDF viewers. No content is deleted - layers that were OFF become visible.
3717
3716
  */
3718
- async function flattenLayers(ctx) {
3717
+ function flattenLayers(ctx) {
3719
3718
  const catalog = ctx.catalog.getDict();
3720
3719
  if (!catalog) return {
3721
3720
  flattened: false,
@@ -3725,7 +3724,7 @@ async function flattenLayers(ctx) {
3725
3724
  flattened: false,
3726
3725
  layerCount: 0
3727
3726
  };
3728
- const layerCount = (await getLayers(ctx)).length;
3727
+ const layerCount = getLayers(ctx).length;
3729
3728
  catalog.delete("OCProperties");
3730
3729
  return {
3731
3730
  flattened: true,
@@ -6271,9 +6270,9 @@ var ObjectStreamParser = class {
6271
6270
  * Decompress and parse the stream index.
6272
6271
  * Called automatically by getObject/getAllObjects if needed.
6273
6272
  */
6274
- async parse() {
6273
+ parse() {
6275
6274
  if (this.index !== null) return;
6276
- this.decodedData = await this.stream.getDecodedData();
6275
+ this.decodedData = this.stream.getDecodedData();
6277
6276
  this.index = this.parseIndex();
6278
6277
  }
6279
6278
  /**
@@ -6302,8 +6301,8 @@ var ObjectStreamParser = class {
6302
6301
  * @param index - 0-based index from XRef entry's indexInStream
6303
6302
  * @returns The parsed object, or null if index is out of range
6304
6303
  */
6305
- async getObject(index) {
6306
- await this.parse();
6304
+ getObject(index) {
6305
+ this.parse();
6307
6306
  if (this.index === null) throw new ObjectParseError("Index not parsed");
6308
6307
  if (index < 0 || index >= this.index.length) return null;
6309
6308
  const entry = this.index[index];
@@ -6317,12 +6316,12 @@ var ObjectStreamParser = class {
6317
6316
  *
6318
6317
  * @returns Map of object number → parsed object
6319
6318
  */
6320
- async getAllObjects() {
6321
- await this.parse();
6319
+ getAllObjects() {
6320
+ this.parse();
6322
6321
  if (this.index === null) throw new ObjectParseError("Index not parsed");
6323
6322
  const result = /* @__PURE__ */ new Map();
6324
6323
  for (let i = 0; i < this.index.length; i++) {
6325
- const obj = await this.getObject(i);
6324
+ const obj = this.getObject(i);
6326
6325
  if (obj !== null) result.set(this.index[i].objNum, obj);
6327
6326
  }
6328
6327
  return result;
@@ -6408,7 +6407,7 @@ var BruteForceParser = class {
6408
6407
  * Scan file and build recovered xref.
6409
6408
  * Returns null if no objects found or no valid root.
6410
6409
  */
6411
- async recover() {
6410
+ recover() {
6412
6411
  const entries = this.scanForObjects();
6413
6412
  if (entries.length === 0) return null;
6414
6413
  const xref = new RecoveredXRef();
@@ -6417,7 +6416,7 @@ var BruteForceParser = class {
6417
6416
  xref.set(entry.objNum, entry.genNum, entry.offset);
6418
6417
  maxObjNum = Math.max(maxObjNum, entry.objNum);
6419
6418
  }
6420
- const compressedEntries = await this.extractFromObjectStreams(entries);
6419
+ const compressedEntries = this.extractFromObjectStreams(entries);
6421
6420
  for (const entry of compressedEntries) {
6422
6421
  xref.setCompressed(entry.objNum, entry.streamObjNum, entry.indexInStream);
6423
6422
  maxObjNum = Math.max(maxObjNum, entry.objNum);
@@ -6594,8 +6593,8 @@ var BruteForceParser = class {
6594
6593
  parseFullObjectAt(offset, objNum, genNum) {
6595
6594
  try {
6596
6595
  const result = new IndirectObjectParser(this.scanner).parseObjectAt(offset);
6597
- if (result.value.type !== "stream") return null;
6598
- return result.value;
6596
+ if (result.value instanceof PdfStream) return result.value;
6597
+ return null;
6599
6598
  } catch (error) {
6600
6599
  const message = error instanceof Error ? error.message : String(error);
6601
6600
  this.warnings.push(`Failed to parse object ${objNum} ${genNum} as stream: ${message}`);
@@ -6606,18 +6605,18 @@ var BruteForceParser = class {
6606
6605
  * Find object streams among the scanned entries and extract their contents.
6607
6606
  * This is crucial for PDFs where Catalog/Pages are stored inside object streams.
6608
6607
  */
6609
- async extractFromObjectStreams(entries) {
6608
+ extractFromObjectStreams(entries) {
6610
6609
  const compressed = [];
6611
6610
  for (const entry of entries) try {
6612
6611
  const stream = this.parseFullObjectAt(entry.offset, entry.objNum, entry.genNum);
6613
6612
  if (stream === null) continue;
6614
6613
  if (stream.getName("Type")?.value !== "ObjStm") continue;
6615
6614
  const objectStreamParser = new ObjectStreamParser(stream);
6616
- await objectStreamParser.parse();
6615
+ objectStreamParser.parse();
6617
6616
  const count = objectStreamParser.objectCount;
6618
6617
  for (let i = 0; i < count; i++) try {
6619
6618
  const objNum = objectStreamParser.getObjectNumber(i);
6620
- const obj = await objectStreamParser.getObject(i);
6619
+ const obj = objectStreamParser.getObject(i);
6621
6620
  if (objNum === null) continue;
6622
6621
  compressed.push({
6623
6622
  objNum,
@@ -6672,7 +6671,7 @@ var XRefParser = class {
6672
6671
  * Parse xref at given byte offset.
6673
6672
  * Auto-detects table vs stream format.
6674
6673
  */
6675
- async parseAt(offset) {
6674
+ parseAt(offset) {
6676
6675
  this.scanner.moveTo(offset);
6677
6676
  const firstByte = this.scanner.peek();
6678
6677
  if (firstByte === 120) return this.parseTable();
@@ -6722,7 +6721,7 @@ var XRefParser = class {
6722
6721
  * - /W [w1 w2 w3] - byte widths for type, offset, generation fields
6723
6722
  * - /Index [first count ...] - object number ranges (optional, defaults to [0 Size])
6724
6723
  */
6725
- async parseStream() {
6724
+ parseStream() {
6726
6725
  const indirectObj = new IndirectObjectParser(this.scanner).parseObject();
6727
6726
  if (!(indirectObj.value instanceof PdfStream)) throw new XRefParseError("Expected XRef stream object");
6728
6727
  const stream = indirectObj.value;
@@ -6758,7 +6757,7 @@ var XRefParser = class {
6758
6757
  first: 0,
6759
6758
  count: size
6760
6759
  });
6761
- const decodedData = await stream.getDecodedData();
6760
+ const decodedData = stream.getDecodedData();
6762
6761
  const entries = /* @__PURE__ */ new Map();
6763
6762
  let dataOffset = 0;
6764
6763
  for (const range of ranges) for (let i = 0; i < range.count; i++) {
@@ -7009,9 +7008,9 @@ var DocumentParser = class {
7009
7008
  /**
7010
7009
  * Parse the PDF document.
7011
7010
  */
7012
- async parse() {
7011
+ parse() {
7013
7012
  try {
7014
- return await this.parseNormal();
7013
+ return this.parseNormal();
7015
7014
  } catch (error) {
7016
7015
  if (this.options.lenient && error instanceof RecoverableParseError) {
7017
7016
  this.warnings.push(`Normal parsing failed: ${error.message}`);
@@ -7023,24 +7022,24 @@ var DocumentParser = class {
7023
7022
  /**
7024
7023
  * Normal parsing path.
7025
7024
  */
7026
- async parseNormal() {
7025
+ parseNormal() {
7027
7026
  const version$1 = this.parseHeader();
7028
7027
  const xrefParser = new XRefParser(this.scanner);
7029
7028
  const startXRef = xrefParser.findStartXRef();
7030
- const { xref, trailer } = await this.parseXRefChain(xrefParser, startXRef);
7029
+ const { xref, trailer } = this.parseXRefChain(xrefParser, startXRef);
7031
7030
  return this.buildDocument(version$1, xref, trailer, false);
7032
7031
  }
7033
7032
  /**
7034
7033
  * Recovery parsing using brute-force when normal parsing fails.
7035
7034
  */
7036
- async parseWithRecovery() {
7035
+ parseWithRecovery() {
7037
7036
  let version$1 = DEFAULT_VERSION;
7038
7037
  try {
7039
7038
  version$1 = this.parseHeader();
7040
7039
  } catch {
7041
7040
  this.warnings.push("Could not parse header, using default version");
7042
7041
  }
7043
- const result = await new BruteForceParser(this.scanner).recover();
7042
+ const result = new BruteForceParser(this.scanner).recover();
7044
7043
  if (result === null) throw new UnrecoverableParseError("Could not recover PDF structure: no objects found");
7045
7044
  this.warnings.push(...result.warnings);
7046
7045
  const xref = /* @__PURE__ */ new Map();
@@ -7108,7 +7107,7 @@ var DocumentParser = class {
7108
7107
  /**
7109
7108
  * Parse the XRef chain, following /Prev links for incremental updates.
7110
7109
  */
7111
- async parseXRefChain(xrefParser, startOffset) {
7110
+ parseXRefChain(xrefParser, startOffset) {
7112
7111
  const combinedXRef = /* @__PURE__ */ new Map();
7113
7112
  let firstTrailer = null;
7114
7113
  const visited = /* @__PURE__ */ new Set();
@@ -7122,7 +7121,7 @@ var DocumentParser = class {
7122
7121
  }
7123
7122
  visited.add(offset);
7124
7123
  try {
7125
- const xrefData = await xrefParser.parseAt(offset);
7124
+ const xrefData = xrefParser.parseAt(offset);
7126
7125
  for (const [objNum, entry] of xrefData.entries) if (!combinedXRef.has(objNum)) combinedXRef.set(objNum, entry);
7127
7126
  if (!firstTrailer) firstTrailer = xrefData.trailer;
7128
7127
  if (xrefData.prev !== void 0) queue.push(xrefData.prev);
@@ -7223,7 +7222,7 @@ var DocumentParser = class {
7223
7222
  }
7224
7223
  return obj;
7225
7224
  };
7226
- const getObject = async (ref) => {
7225
+ const getObject = (ref) => {
7227
7226
  const key$1 = `${ref.objectNumber} ${ref.generation}`;
7228
7227
  if (cache.has(key$1)) return cache.get(key$1);
7229
7228
  const entry = xref.get(ref.objectNumber);
@@ -7241,25 +7240,25 @@ var DocumentParser = class {
7241
7240
  case "compressed": {
7242
7241
  let streamParser = objectStreamCache.get(entry.streamObjNum);
7243
7242
  if (!streamParser) {
7244
- const streamObj = await getObject(PdfRef.of(entry.streamObjNum, 0));
7245
- if (!streamObj || streamObj.type !== "stream") {
7243
+ const streamObj = getObject(PdfRef.of(entry.streamObjNum, 0));
7244
+ if (!streamObj || !(streamObj instanceof PdfStream)) {
7246
7245
  this.warnings.push(`Object stream ${entry.streamObjNum} not found or invalid`);
7247
7246
  return null;
7248
7247
  }
7249
7248
  streamParser = new ObjectStreamParser(streamObj);
7250
7249
  objectStreamCache.set(entry.streamObjNum, streamParser);
7251
7250
  }
7252
- obj = await streamParser.getObject(entry.indexInStream);
7251
+ obj = streamParser.getObject(entry.indexInStream);
7253
7252
  break;
7254
7253
  }
7255
7254
  }
7256
7255
  if (obj !== null) cache.set(key$1, obj);
7257
7256
  return obj;
7258
7257
  };
7259
- const getCatalog = async () => {
7258
+ const getCatalog = () => {
7260
7259
  const rootRef = trailer.getRef("Root");
7261
7260
  if (!rootRef) return null;
7262
- const root = await getObject(rootRef);
7261
+ const root = getObject(rootRef);
7263
7262
  if (!root || root.type !== "dict" && root.type !== "stream") return null;
7264
7263
  return root;
7265
7264
  };
@@ -7267,10 +7266,10 @@ var DocumentParser = class {
7267
7266
  * Walk the page tree and collect all page references.
7268
7267
  * Handles circular references and missing objects gracefully.
7269
7268
  */
7270
- const getPages = async () => {
7269
+ const getPages = () => {
7271
7270
  const pages = [];
7272
7271
  const visited = /* @__PURE__ */ new Set();
7273
- const walkNode = async (nodeOrRef, currentRef) => {
7272
+ const walkNode = (nodeOrRef, currentRef) => {
7274
7273
  if (nodeOrRef instanceof PdfRef) {
7275
7274
  const key$1 = `${nodeOrRef.objectNumber} ${nodeOrRef.generation}`;
7276
7275
  if (visited.has(key$1)) {
@@ -7278,7 +7277,7 @@ var DocumentParser = class {
7278
7277
  return;
7279
7278
  }
7280
7279
  visited.add(key$1);
7281
- await walkNode(await getObject(nodeOrRef), nodeOrRef);
7280
+ walkNode(getObject(nodeOrRef), nodeOrRef);
7282
7281
  return;
7283
7282
  }
7284
7283
  if (!(nodeOrRef instanceof PdfDict)) return;
@@ -7289,19 +7288,19 @@ var DocumentParser = class {
7289
7288
  const kids = nodeOrRef.getArray("Kids");
7290
7289
  if (kids) for (let i = 0; i < kids.length; i++) {
7291
7290
  const kid = kids.at(i);
7292
- if (kid instanceof PdfRef) await walkNode(kid);
7293
- else if (kid instanceof PdfDict) await walkNode(kid);
7291
+ if (kid instanceof PdfRef) walkNode(kid);
7292
+ else if (kid instanceof PdfDict) walkNode(kid);
7294
7293
  }
7295
7294
  }
7296
7295
  };
7297
- const catalog = await getCatalog();
7296
+ const catalog = getCatalog();
7298
7297
  if (!catalog) return pages;
7299
7298
  const pagesRef = catalog.getRef("Pages");
7300
- if (pagesRef) await walkNode(pagesRef);
7299
+ if (pagesRef) walkNode(pagesRef);
7301
7300
  return pages;
7302
7301
  };
7303
- const getPageCount = async () => {
7304
- return (await getPages()).length;
7302
+ const getPageCount = () => {
7303
+ return getPages().length;
7305
7304
  };
7306
7305
  const authenticate = (password) => {
7307
7306
  if (!securityHandler) return false;
@@ -7695,12 +7694,12 @@ function writeIndirectObject(writer, ref, obj) {
7695
7694
  * Streams that already have filters are returned unchanged - this includes
7696
7695
  * image formats (DCTDecode, JPXDecode, etc.) that are already compressed.
7697
7696
  */
7698
- async function prepareObjectForWrite(obj, compress) {
7697
+ function prepareObjectForWrite(obj, compress) {
7699
7698
  if (!(obj instanceof PdfStream)) return obj;
7700
7699
  if (obj.has("Filter")) return obj;
7701
7700
  if (!compress) return obj;
7702
7701
  if (obj.data.length === 0) return obj;
7703
- const compressed = await FilterPipeline.encode(obj.data, { name: "FlateDecode" });
7702
+ const compressed = FilterPipeline.encode(obj.data, { name: "FlateDecode" });
7704
7703
  if (compressed.length >= obj.data.length) return obj;
7705
7704
  const compressedStream = new PdfStream(obj, compressed);
7706
7705
  compressedStream.set("Filter", PdfName.of("FlateDecode"));
@@ -7773,7 +7772,7 @@ function encryptStreamDict(stream, ctx) {
7773
7772
  * %%EOF
7774
7773
  * ```
7775
7774
  */
7776
- async function writeComplete(registry, options) {
7775
+ function writeComplete(registry, options) {
7777
7776
  const writer = new ByteWriter();
7778
7777
  const compress = options.compressStreams ?? true;
7779
7778
  const version$1 = options.version ?? "1.7";
@@ -7790,7 +7789,7 @@ async function writeComplete(registry, options) {
7790
7789
  const allObjects = /* @__PURE__ */ new Map();
7791
7790
  for (const [ref, obj] of registry.entries()) allObjects.set(ref, obj);
7792
7791
  for (const [ref, obj] of allObjects) {
7793
- let prepared = await prepareObjectForWrite(obj, compress);
7792
+ let prepared = prepareObjectForWrite(obj, compress);
7794
7793
  if (options.securityHandler && options.encrypt && ref !== options.encrypt) prepared = encryptObject(prepared, {
7795
7794
  handler: options.securityHandler,
7796
7795
  objectNumber: ref.objectNumber,
@@ -7863,7 +7862,7 @@ async function writeComplete(registry, options) {
7863
7862
  * %%EOF
7864
7863
  * ```
7865
7864
  */
7866
- async function writeIncremental(registry, options) {
7865
+ function writeIncremental(registry, options) {
7867
7866
  const changes = collectChanges(registry);
7868
7867
  if (changes.modified.size === 0 && changes.created.size === 0) return {
7869
7868
  bytes: options.originalBytes,
@@ -7875,7 +7874,7 @@ async function writeIncremental(registry, options) {
7875
7874
  if (lastByte !== LF && lastByte !== CR) writer.writeByte(10);
7876
7875
  const offsets = /* @__PURE__ */ new Map();
7877
7876
  for (const [ref, obj] of changes.modified) {
7878
- let prepared = await prepareObjectForWrite(obj, compress);
7877
+ let prepared = prepareObjectForWrite(obj, compress);
7879
7878
  if (options.securityHandler && options.encrypt && ref !== options.encrypt) prepared = encryptObject(prepared, {
7880
7879
  handler: options.securityHandler,
7881
7880
  objectNumber: ref.objectNumber,
@@ -7888,7 +7887,7 @@ async function writeIncremental(registry, options) {
7888
7887
  writeIndirectObject(writer, ref, prepared);
7889
7888
  }
7890
7889
  for (const [ref, obj] of changes.created) {
7891
- let prepared = await prepareObjectForWrite(obj, compress);
7890
+ let prepared = prepareObjectForWrite(obj, compress);
7892
7891
  if (options.securityHandler && options.encrypt && ref !== options.encrypt) prepared = encryptObject(prepared, {
7893
7892
  handler: options.securityHandler,
7894
7893
  objectNumber: ref.objectNumber,
@@ -8035,17 +8034,17 @@ function decodeFilename(str) {
8035
8034
  *
8036
8035
  * @returns The stream if found, null if external reference or missing
8037
8036
  */
8038
- async function getEmbeddedFileStream(fileSpec, resolver) {
8037
+ function getEmbeddedFileStream(fileSpec, resolver) {
8039
8038
  const efEntry = fileSpec.get("EF");
8040
8039
  let ef = null;
8041
8040
  if (efEntry instanceof PdfRef) {
8042
- const resolved = await resolver(efEntry);
8041
+ const resolved = resolver(efEntry);
8043
8042
  if (resolved instanceof PdfDict) ef = resolved;
8044
8043
  } else if (efEntry instanceof PdfDict) ef = efEntry;
8045
8044
  if (!ef) return null;
8046
8045
  const streamRef = ef.getRef("F") ?? ef.getRef("UF");
8047
8046
  if (!streamRef) return null;
8048
- const stream = await resolver(streamRef);
8047
+ const stream = resolver(streamRef);
8049
8048
  if (stream instanceof PdfStream) return stream;
8050
8049
  return null;
8051
8050
  }
@@ -8057,8 +8056,8 @@ async function getEmbeddedFileStream(fileSpec, resolver) {
8057
8056
  * @param resolver Function to resolve references
8058
8057
  * @returns AttachmentInfo or null if external file reference
8059
8058
  */
8060
- async function parseFileSpec(fileSpec, name, resolver) {
8061
- const stream = await getEmbeddedFileStream(fileSpec, resolver);
8059
+ function parseFileSpec(fileSpec, name, resolver) {
8060
+ const stream = getEmbeddedFileStream(fileSpec, resolver);
8062
8061
  if (!stream) return null;
8063
8062
  const info = {
8064
8063
  name,
@@ -8071,7 +8070,7 @@ async function parseFileSpec(fileSpec, name, resolver) {
8071
8070
  const paramsEntry = stream.get("Params");
8072
8071
  let params = null;
8073
8072
  if (paramsEntry instanceof PdfRef) {
8074
- const resolved = await resolver(paramsEntry);
8073
+ const resolved = resolver(paramsEntry);
8075
8074
  if (resolved instanceof PdfDict) params = resolved;
8076
8075
  } else if (paramsEntry instanceof PdfDict) params = paramsEntry;
8077
8076
  if (params) {
@@ -8082,7 +8081,7 @@ async function parseFileSpec(fileSpec, name, resolver) {
8082
8081
  const modDate = params.getString("ModDate");
8083
8082
  if (modDate) info.modifiedAt = parsePdfDate(modDate.asString());
8084
8083
  }
8085
- if (info.size === void 0) info.size = (await stream.getDecodedData()).length;
8084
+ if (info.size === void 0) info.size = stream.getDecodedData().length;
8086
8085
  return info;
8087
8086
  }
8088
8087
  /**
@@ -8185,7 +8184,7 @@ var NameTree = class {
8185
8184
  *
8186
8185
  * @returns The value if found, null otherwise
8187
8186
  */
8188
- async get(key$1) {
8187
+ get(key$1) {
8189
8188
  let node = this.root;
8190
8189
  let depth = 0;
8191
8190
  while (node.has("Kids")) {
@@ -8205,7 +8204,7 @@ var NameTree = class {
8205
8204
  lo$1 = mid + 1;
8206
8205
  continue;
8207
8206
  }
8208
- const kid = await this.resolver(kidRef);
8207
+ const kid = this.resolver(kidRef);
8209
8208
  if (!(kid instanceof PdfDict)) {
8210
8209
  lo$1 = mid + 1;
8211
8210
  continue;
@@ -8263,14 +8262,14 @@ var NameTree = class {
8263
8262
  /**
8264
8263
  * Check if a key exists in the tree.
8265
8264
  */
8266
- async has(key$1) {
8267
- return await this.get(key$1) !== null;
8265
+ has(key$1) {
8266
+ return this.get(key$1) !== null;
8268
8267
  }
8269
8268
  /**
8270
8269
  * Iterate all entries (lazy, yields [key, value] pairs).
8271
8270
  * Uses BFS traversal with cycle detection.
8272
8271
  */
8273
- async *entries() {
8272
+ *entries() {
8274
8273
  const visited = /* @__PURE__ */ new Set();
8275
8274
  const queue = [{
8276
8275
  node: this.root,
@@ -8292,7 +8291,7 @@ var NameTree = class {
8292
8291
  continue;
8293
8292
  }
8294
8293
  visited.add(refKey$1);
8295
- const kid = await this.resolver(kidRef);
8294
+ const kid = this.resolver(kidRef);
8296
8295
  if (kid instanceof PdfDict) queue.push({
8297
8296
  node: kid,
8298
8297
  depth: depth + 1
@@ -8304,7 +8303,7 @@ var NameTree = class {
8304
8303
  const key$1 = extractKey(names.at(i));
8305
8304
  if (key$1 === null) continue;
8306
8305
  let value = names.at(i + 1) ?? null;
8307
- if (value instanceof PdfRef) value = await this.resolver(value);
8306
+ if (value instanceof PdfRef) value = this.resolver(value);
8308
8307
  if (value !== null && value !== void 0) yield [key$1, value];
8309
8308
  }
8310
8309
  }
@@ -8313,10 +8312,10 @@ var NameTree = class {
8313
8312
  /**
8314
8313
  * Load all entries into a Map (cached after first call).
8315
8314
  */
8316
- async getAll() {
8315
+ getAll() {
8317
8316
  if (this.cache) return this.cache;
8318
8317
  const result = /* @__PURE__ */ new Map();
8319
- for await (const [key$1, value] of this.entries()) result.set(key$1, value);
8318
+ for (const [key$1, value] of this.entries()) result.set(key$1, value);
8320
8319
  this.cache = result;
8321
8320
  return result;
8322
8321
  }
@@ -8404,13 +8403,13 @@ var PDFAttachments = class {
8404
8403
  * }
8405
8404
  * ```
8406
8405
  */
8407
- async list() {
8406
+ list() {
8408
8407
  const result = /* @__PURE__ */ new Map();
8409
- const tree = await this.ctx.catalog.getEmbeddedFilesTree();
8408
+ const tree = this.ctx.catalog.getEmbeddedFilesTree();
8410
8409
  if (!tree) return result;
8411
- for await (const [name, value] of tree.entries()) {
8410
+ for (const [name, value] of tree.entries()) {
8412
8411
  if (!(value instanceof PdfDict)) continue;
8413
- const info = await parseFileSpec(value, name, (ref) => this.ctx.registry.resolve(ref));
8412
+ const info = parseFileSpec(value, name, (ref) => this.ctx.registry.resolve(ref));
8414
8413
  if (info) result.set(name, info);
8415
8414
  else this.ctx.registry.addWarning(`Attachment "${name}" is an external file reference (not embedded)`);
8416
8415
  }
@@ -8431,12 +8430,12 @@ var PDFAttachments = class {
8431
8430
  * }
8432
8431
  * ```
8433
8432
  */
8434
- async get(name) {
8435
- const tree = await this.ctx.catalog.getEmbeddedFilesTree();
8433
+ get(name) {
8434
+ const tree = this.ctx.catalog.getEmbeddedFilesTree();
8436
8435
  if (!tree) return null;
8437
- const fileSpec = await tree.get(name);
8436
+ const fileSpec = tree.get(name);
8438
8437
  if (!(fileSpec instanceof PdfDict)) return null;
8439
- const stream = await getEmbeddedFileStream(fileSpec, (ref) => this.ctx.registry.resolve(ref));
8438
+ const stream = getEmbeddedFileStream(fileSpec, (ref) => this.ctx.registry.resolve(ref));
8440
8439
  if (!stream) return null;
8441
8440
  return stream.getDecodedData();
8442
8441
  }
@@ -8453,8 +8452,8 @@ var PDFAttachments = class {
8453
8452
  * }
8454
8453
  * ```
8455
8454
  */
8456
- async has(name) {
8457
- const tree = await this.ctx.catalog.getEmbeddedFilesTree();
8455
+ has(name) {
8456
+ const tree = this.ctx.catalog.getEmbeddedFilesTree();
8458
8457
  if (!tree) return false;
8459
8458
  return tree.has(name);
8460
8459
  }
@@ -8481,21 +8480,21 @@ var PDFAttachments = class {
8481
8480
  * await pdf.attachments.add("report.pdf", newBytes, { overwrite: true });
8482
8481
  * ```
8483
8482
  */
8484
- async add(name, data, options = {}) {
8485
- if (!options.overwrite && await this.has(name)) throw new Error(`Attachment "${name}" already exists. Use { overwrite: true } to replace.`);
8483
+ add(name, data, options = {}) {
8484
+ if (!options.overwrite && this.has(name)) throw new Error(`Attachment "${name}" already exists. Use { overwrite: true } to replace.`);
8486
8485
  const embeddedFileStream = createEmbeddedFileStream(data, name, options);
8487
8486
  const fileSpec = createFileSpec(name, this.ctx.registry.register(embeddedFileStream), options);
8488
8487
  const fileSpecRef = this.ctx.registry.register(fileSpec);
8489
8488
  const existingAttachments = [];
8490
- const tree = await this.ctx.catalog.getEmbeddedFilesTree();
8491
- if (tree) for await (const [key$1, value] of tree.entries()) {
8489
+ const tree = this.ctx.catalog.getEmbeddedFilesTree();
8490
+ if (tree) for (const [key$1, value] of tree.entries()) {
8492
8491
  if (key$1 === name && options.overwrite) continue;
8493
8492
  const ref = this.ctx.registry.getRef(value);
8494
8493
  if (ref) existingAttachments.push([key$1, ref]);
8495
8494
  }
8496
8495
  existingAttachments.push([name, fileSpecRef]);
8497
8496
  const newNameTree = buildNameTree(existingAttachments);
8498
- await this.ctx.catalog.setEmbeddedFilesTree(newNameTree);
8497
+ this.ctx.catalog.setEmbeddedFilesTree(newNameTree);
8499
8498
  }
8500
8499
  /**
8501
8500
  * Remove an attachment from the document.
@@ -8511,20 +8510,20 @@ var PDFAttachments = class {
8511
8510
  * }
8512
8511
  * ```
8513
8512
  */
8514
- async remove(name) {
8515
- const tree = await this.ctx.catalog.getEmbeddedFilesTree();
8513
+ remove(name) {
8514
+ const tree = this.ctx.catalog.getEmbeddedFilesTree();
8516
8515
  if (!tree) return false;
8517
- if (!await tree.has(name)) return false;
8516
+ if (!tree.has(name)) return false;
8518
8517
  const remainingAttachments = [];
8519
- for await (const [key$1, value] of tree.entries()) {
8518
+ for (const [key$1, value] of tree.entries()) {
8520
8519
  if (key$1 === name) continue;
8521
8520
  const ref = this.ctx.registry.getRef(value);
8522
8521
  if (ref) remainingAttachments.push([key$1, ref]);
8523
8522
  }
8524
- if (remainingAttachments.length === 0) await this.ctx.catalog.removeEmbeddedFilesTree();
8523
+ if (remainingAttachments.length === 0) this.ctx.catalog.removeEmbeddedFilesTree();
8525
8524
  else {
8526
8525
  const newNameTree = buildNameTree(remainingAttachments);
8527
- await this.ctx.catalog.setEmbeddedFilesTree(newNameTree);
8526
+ this.ctx.catalog.setEmbeddedFilesTree(newNameTree);
8528
8527
  }
8529
8528
  return true;
8530
8529
  }
@@ -8571,19 +8570,16 @@ var PDFCatalog = class {
8571
8570
  /**
8572
8571
  * Get the /Names dictionary.
8573
8572
  */
8574
- async getNames() {
8575
- const namesEntry = this.dict.get("Names");
8576
- if (namesEntry instanceof PdfRef) {
8577
- const resolved = await this.registry.resolve(namesEntry);
8578
- return resolved instanceof PdfDict ? resolved : null;
8579
- }
8573
+ getNames() {
8574
+ let namesEntry = this.dict.get("Names");
8575
+ if (namesEntry instanceof PdfRef) namesEntry = this.registry.resolve(namesEntry) ?? void 0;
8580
8576
  return namesEntry instanceof PdfDict ? namesEntry : null;
8581
8577
  }
8582
8578
  /**
8583
8579
  * Get or create the /Names dictionary.
8584
8580
  */
8585
- async getOrCreateNames() {
8586
- let names = await this.getNames();
8581
+ getOrCreateNames() {
8582
+ let names = this.getNames();
8587
8583
  if (!names) {
8588
8584
  names = new PdfDict();
8589
8585
  this.dict.set("Names", this.registry.register(names));
@@ -8594,9 +8590,9 @@ var PDFCatalog = class {
8594
8590
  * Get the EmbeddedFiles name tree.
8595
8591
  * Caches the result for repeated access.
8596
8592
  */
8597
- async getEmbeddedFilesTree() {
8593
+ getEmbeddedFilesTree() {
8598
8594
  if (this._embeddedFilesTree !== void 0) return this._embeddedFilesTree;
8599
- const names = await this.getNames();
8595
+ const names = this.getNames();
8600
8596
  if (!names) {
8601
8597
  this._embeddedFilesTree = null;
8602
8598
  return null;
@@ -8604,7 +8600,7 @@ var PDFCatalog = class {
8604
8600
  const embeddedFilesEntry = names.get("EmbeddedFiles");
8605
8601
  let embeddedFiles = null;
8606
8602
  if (embeddedFilesEntry instanceof PdfRef) {
8607
- const resolved = await this.registry.resolve(embeddedFilesEntry);
8603
+ const resolved = this.registry.resolve(embeddedFilesEntry);
8608
8604
  if (resolved instanceof PdfDict) embeddedFiles = resolved;
8609
8605
  } else if (embeddedFilesEntry instanceof PdfDict) embeddedFiles = embeddedFilesEntry;
8610
8606
  if (!embeddedFiles) {
@@ -8617,8 +8613,8 @@ var PDFCatalog = class {
8617
8613
  /**
8618
8614
  * Set the EmbeddedFiles name tree.
8619
8615
  */
8620
- async setEmbeddedFilesTree(treeDict) {
8621
- const names = await this.getOrCreateNames();
8616
+ setEmbeddedFilesTree(treeDict) {
8617
+ const names = this.getOrCreateNames();
8622
8618
  const treeRef = this.registry.register(treeDict);
8623
8619
  names.set("EmbeddedFiles", treeRef);
8624
8620
  this._embeddedFilesTree = void 0;
@@ -8626,8 +8622,8 @@ var PDFCatalog = class {
8626
8622
  /**
8627
8623
  * Remove the EmbeddedFiles entry from /Names.
8628
8624
  */
8629
- async removeEmbeddedFilesTree() {
8630
- const names = await this.getNames();
8625
+ removeEmbeddedFilesTree() {
8626
+ const names = this.getNames();
8631
8627
  if (names) names.delete("EmbeddedFiles");
8632
8628
  this._embeddedFilesTree = void 0;
8633
8629
  }
@@ -8692,7 +8688,11 @@ var PDFContext = class {
8692
8688
  return this.registry.register(obj);
8693
8689
  }
8694
8690
  /**
8695
- * Resolve an object by reference (async, fetches if needed).
8691
+ * Resolve an object by reference.
8692
+ *
8693
+ * Synchronously resolves the reference, parsing from the in-memory
8694
+ * buffer if not already cached. All PDF data is loaded at parse time,
8695
+ * so this operation never requires I/O.
8696
8696
  */
8697
8697
  resolve(ref) {
8698
8698
  return this.registry.resolve(ref);
@@ -13516,7 +13516,7 @@ var Type1Parser = class {
13516
13516
  const token = value[i];
13517
13517
  if (token.kind === TokenKind.REAL) numbers.push(token.floatValue());
13518
13518
  else if (token.kind === TokenKind.INTEGER) numbers.push(token.intValue());
13519
- else throw new Error(`Expected INTEGER or REAL but got ${token} at array position ${i}`);
13519
+ else throw new Error(`Expected INTEGER or REAL but got ${token.kind} at array position ${i}`);
13520
13520
  }
13521
13521
  return numbers;
13522
13522
  }
@@ -13874,7 +13874,7 @@ var Type1Parser = class {
13874
13874
  break;
13875
13875
  }
13876
13876
  if (token.text === "def") return;
13877
- throw new Error(`Found ${token} but expected ND`);
13877
+ throw new Error(`Found ${token.kind}:${token.text} but expected ND`);
13878
13878
  }
13879
13879
  /**
13880
13880
  * Reads the sequence "noaccess put" or equivalent.
@@ -13890,7 +13890,7 @@ var Type1Parser = class {
13890
13890
  break;
13891
13891
  }
13892
13892
  if (token.text === "put") return;
13893
- throw new Error(`Found ${token} but expected NP`);
13893
+ throw new Error(`Found ${token.kind}:${token.text} but expected NP`);
13894
13894
  }
13895
13895
  /**
13896
13896
  * Reads the next token and throws an exception if it is not of the given kind.
@@ -13898,8 +13898,8 @@ var Type1Parser = class {
13898
13898
  */
13899
13899
  read(kind, name) {
13900
13900
  const token = this.lexer.nextToken();
13901
- if (token === null || token.kind !== kind) throw new Error(`Found ${token} but expected ${kind}`);
13902
- if (name !== void 0 && token.text !== name) throw new Error(`Found ${token} but expected ${name}`);
13901
+ if (token === null || token.kind !== kind) throw new Error(`Found ${token?.kind ?? "null"}:${token?.text ?? ""} but expected ${kind}`);
13902
+ if (name !== void 0 && token.text !== name) throw new Error(`Found ${token.kind}:${token.text} but expected ${name}`);
13903
13903
  return token;
13904
13904
  }
13905
13905
  /**
@@ -14210,6 +14210,7 @@ var CFFType1FontProgram = class {
14210
14210
  return this.data;
14211
14211
  }
14212
14212
  };
14213
+ const isCFFType1FontProgram = (program) => program.type === "cff";
14213
14214
 
14214
14215
  //#endregion
14215
14216
  //#region src/fonts/font-program/cff-cid.ts
@@ -14296,6 +14297,7 @@ var CFFCIDFontProgram = class {
14296
14297
  return this.data;
14297
14298
  }
14298
14299
  };
14300
+ const isCFFCIDFontProgram = (program) => program.type === "cff-cid";
14299
14301
 
14300
14302
  //#endregion
14301
14303
  //#region src/fonts/font-program/truetype.ts
@@ -14364,6 +14366,7 @@ var TrueTypeFontProgram = class {
14364
14366
  return this.data;
14365
14367
  }
14366
14368
  };
14369
+ const isTrueTypeFontProgram = (program) => program.type === "truetype";
14367
14370
 
14368
14371
  //#endregion
14369
14372
  //#region src/fonts/font-program/type1.ts
@@ -14575,7 +14578,7 @@ function tryAutoDetectFontFile3(data) {
14575
14578
  * Get the /Subtype from a stream dictionary.
14576
14579
  */
14577
14580
  function getStreamSubtype(stream) {
14578
- if (stream && stream instanceof PdfStream) return stream.get("Subtype")?.value;
14581
+ if (stream && stream instanceof PdfStream) return stream.getName("Subtype")?.value;
14579
14582
  }
14580
14583
  /**
14581
14584
  * Resolve a value through indirect references.
@@ -15664,7 +15667,7 @@ var TTFSubsetter = class {
15664
15667
  /**
15665
15668
  * Write the subset font to a byte array.
15666
15669
  */
15667
- async write() {
15670
+ write() {
15668
15671
  if (this.glyphIds.size === 0 && this.uniToGID.size === 0) console.warn("Font subset is empty");
15669
15672
  this.addCompoundReferences();
15670
15673
  const sortedGids = [...this.glyphIds].sort((a, b) => a - b);
@@ -16629,13 +16632,13 @@ function generateSubsetTag() {
16629
16632
  * @param options - Embedding options
16630
16633
  * @returns All PDF objects that need to be registered
16631
16634
  */
16632
- async function createFontObjects(font, options = {}) {
16635
+ function createFontObjects(font, options = {}) {
16633
16636
  const program = font.program;
16634
16637
  const subsetTag = options.subsetTag ?? generateSubsetTag();
16635
16638
  font.setSubsetTag(subsetTag);
16636
16639
  const fontName = `${subsetTag}+${program.postScriptName ?? "Unknown"}`;
16637
16640
  const gidToCodePoint = font.getGidToCodePointMap();
16638
- const subsetResult = await subsetFont(program, font.getUsedGlyphIds(), font.getCodePointToGidMap());
16641
+ const subsetResult = subsetFont(program, font.getUsedGlyphIds(), font.getCodePointToGidMap());
16639
16642
  const toUnicodeData = buildToUnicodeCMapFromGids(gidToCodePoint);
16640
16643
  const widthsArray = widthEntriesToPdfArray(buildWidthsArrayFromGids(gidToCodePoint, program));
16641
16644
  const fontStreamDict = new PdfDict();
@@ -16667,7 +16670,7 @@ async function createFontObjects(font, options = {}) {
16667
16670
  * @param font - The EmbeddedFont
16668
16671
  * @returns All PDF objects that need to be registered
16669
16672
  */
16670
- async function createFontObjectsFull(font) {
16673
+ function createFontObjectsFull(font) {
16671
16674
  const program = font.program;
16672
16675
  const fontName = program.postScriptName ?? "Unknown";
16673
16676
  const fontTypeResult = getFontFileType(program);
@@ -16723,8 +16726,8 @@ function registerFontObjects(result, register, preAllocatedRef, registerAt) {
16723
16726
  * @param usedGlyphIds - GIDs to include
16724
16727
  * @param usedCodePoints - Code points that were used (for TTF subsetter)
16725
16728
  */
16726
- async function subsetFont(program, usedGlyphIds, usedCodePoints) {
16727
- if (program.type === "cff" || program.type === "cff-cid") {
16729
+ function subsetFont(program, usedGlyphIds, usedCodePoints) {
16730
+ if (isCFFType1FontProgram(program) || isCFFCIDFontProgram(program)) {
16728
16731
  const subsetter = new CFFSubsetter(program.font);
16729
16732
  for (const gid of usedGlyphIds) subsetter.addGlyph(gid);
16730
16733
  return {
@@ -16733,7 +16736,7 @@ async function subsetFont(program, usedGlyphIds, usedCodePoints) {
16733
16736
  fontFileSubtype: "CIDFontType0C"
16734
16737
  };
16735
16738
  }
16736
- if (program.type === "truetype") {
16739
+ if (isTrueTypeFontProgram(program)) {
16737
16740
  const ttf = program.font;
16738
16741
  if (!ttf.getTableBytes("glyf")) return {
16739
16742
  data: program.getData(),
@@ -16759,7 +16762,7 @@ async function subsetFont(program, usedGlyphIds, usedCodePoints) {
16759
16762
  for (const codePoint of usedCodePoints.keys()) subsetter.add(codePoint);
16760
16763
  const oldToNewGidMap = subsetter.getOldToNewGIDMap();
16761
16764
  return {
16762
- data: await subsetter.write(),
16765
+ data: subsetter.write(),
16763
16766
  fontFileKey: "FontFile2",
16764
16767
  oldToNewGidMap
16765
16768
  };
@@ -16774,11 +16777,11 @@ async function subsetFont(program, usedGlyphIds, usedCodePoints) {
16774
16777
  * Get font file type without subsetting.
16775
16778
  */
16776
16779
  function getFontFileType(program) {
16777
- if (program.type === "cff" || program.type === "cff-cid") return {
16780
+ if (isCFFType1FontProgram(program) || isCFFCIDFontProgram(program)) return {
16778
16781
  fontFileKey: "FontFile3",
16779
16782
  fontFileSubtype: "CIDFontType0C"
16780
16783
  };
16781
- if (program.type === "truetype") {
16784
+ if (isTrueTypeFontProgram(program)) {
16782
16785
  if (!program.font.getTableBytes("glyf")) return {
16783
16786
  fontFileKey: "FontFile3",
16784
16787
  fontFileSubtype: "OpenType"
@@ -17033,16 +17036,16 @@ var PDFFonts = class {
17033
17036
  *
17034
17037
  * @param subsetFonts - Whether to subset fonts (only include used glyphs)
17035
17038
  */
17036
- async finalize(subsetFonts) {
17039
+ finalize(subsetFonts) {
17037
17040
  if (this.finalized) return;
17038
- for (const [font, ref] of this.embeddedFonts) registerFontObjects(subsetFonts && font.canSubset() ? await createFontObjects(font) : await createFontObjectsFull(font), (obj) => this.ctx.register(obj), ref, (allocatedRef, obj) => this.ctx.registry.registerAt(allocatedRef, obj));
17041
+ for (const [font, ref] of this.embeddedFonts) registerFontObjects(subsetFonts && font.canSubset() ? createFontObjects(font) : createFontObjectsFull(font), (obj) => this.ctx.register(obj), ref, (allocatedRef, obj) => this.ctx.registry.registerAt(allocatedRef, obj));
17039
17042
  this.finalized = true;
17040
17043
  }
17041
17044
  /**
17042
17045
  * @deprecated Use `finalize()` instead. This method exists for backwards compatibility.
17043
17046
  */
17044
- async prepare() {
17045
- return this.finalize(true);
17047
+ prepare() {
17048
+ this.finalize(true);
17046
17049
  }
17047
17050
  };
17048
17051
 
@@ -22852,6 +22855,9 @@ const FONT_GLYPH_WIDTHS = {
22852
22855
  * /ToUnicode 11 0 R
22853
22856
  * >>
22854
22857
  */
22858
+ const isSimpleFontSubtype = (subtype) => {
22859
+ return subtype === "TrueType" || subtype === "Type1" || subtype === "Type3" || subtype === "MMType1";
22860
+ };
22855
22861
  /**
22856
22862
  * SimpleFont handles single-byte encoded fonts (TrueType, Type1, Type3).
22857
22863
  */
@@ -22985,7 +22991,8 @@ var SimpleFont = class extends PdfFont {
22985
22991
  * Parse a SimpleFont from a PDF font dictionary.
22986
22992
  */
22987
22993
  function parseSimpleFont(dict, options = {}) {
22988
- const subtype = dict.getName("Subtype")?.value ?? "TrueType";
22994
+ const subtypeName = dict.getName("Subtype");
22995
+ const subtype = isSimpleFontSubtype(subtypeName?.value) ? subtypeName.value : "TrueType";
22989
22996
  const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
22990
22997
  const firstChar = dict.getNumber("FirstChar")?.value ?? 0;
22991
22998
  const lastChar = dict.getNumber("LastChar")?.value ?? 255;
@@ -23252,10 +23259,10 @@ const DEFAULT_HIGHLIGHT_COLOR = {
23252
23259
  * Parses the content stream to find colors, fonts, and border widths
23253
23260
  * so they can be reused when regenerating the appearance.
23254
23261
  */
23255
- async function extractAppearanceStyle(stream) {
23262
+ function extractAppearanceStyle(stream) {
23256
23263
  const style = {};
23257
23264
  try {
23258
- const data = await stream.getDecodedData();
23265
+ const data = stream.getDecodedData();
23259
23266
  const content = new TextDecoder().decode(data);
23260
23267
  const btIndex = content.indexOf("BT");
23261
23268
  const preBT = btIndex > 0 ? content.slice(0, btIndex) : content;
@@ -24617,11 +24624,12 @@ var WidgetAnnotation = class {
24617
24624
  0,
24618
24625
  0
24619
24626
  ];
24627
+ const [x1, y1, x2, y2] = arr.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
24620
24628
  return [
24621
- arr.at(0)?.value ?? 0,
24622
- arr.at(1)?.value ?? 0,
24623
- arr.at(2)?.value ?? 0,
24624
- arr.at(3)?.value ?? 0
24629
+ x1 ?? 0,
24630
+ y1 ?? 0,
24631
+ x2 ?? 0,
24632
+ y2 ?? 0
24625
24633
  ];
24626
24634
  }
24627
24635
  /**
@@ -24751,57 +24759,60 @@ var WidgetAnnotation = class {
24751
24759
  * Get normal appearance stream.
24752
24760
  * For stateful widgets (checkbox/radio), pass the state name.
24753
24761
  */
24754
- async getNormalAppearance(state) {
24762
+ getNormalAppearance(state) {
24755
24763
  const ap = this.dict.getDict("AP");
24756
24764
  if (!ap) return null;
24757
- const n = ap.get("N");
24765
+ let n = ap.get("N");
24758
24766
  if (!n) return null;
24759
- const resolved = n.type === "ref" ? await this.registry.resolve(n) : n;
24760
- if (resolved instanceof PdfStream) return resolved;
24761
- if (resolved instanceof PdfDict) {
24767
+ if (n instanceof PdfRef) n = this.registry.resolve(n) ?? void 0;
24768
+ if (n instanceof PdfStream) return n;
24769
+ if (n instanceof PdfDict) {
24762
24770
  const stateKey = state ?? this.appearanceState ?? "Off";
24763
- const stateEntry = resolved.get(stateKey);
24771
+ let stateEntry = n.get(stateKey);
24764
24772
  if (!stateEntry) return null;
24765
- const stateStream = stateEntry.type === "ref" ? await this.registry.resolve(stateEntry) : stateEntry;
24766
- return stateStream instanceof PdfStream ? stateStream : null;
24773
+ if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
24774
+ if (stateEntry instanceof PdfStream) return stateEntry;
24775
+ return null;
24767
24776
  }
24768
24777
  return null;
24769
24778
  }
24770
24779
  /**
24771
24780
  * Get rollover appearance stream (shown on mouse hover).
24772
24781
  */
24773
- async getRolloverAppearance(state) {
24782
+ getRolloverAppearance(state) {
24774
24783
  const ap = this.dict.getDict("AP");
24775
24784
  if (!ap) return null;
24776
- const r = ap.get("R");
24785
+ let r = ap.get("R");
24777
24786
  if (!r) return null;
24778
- const resolved = r.type === "ref" ? await this.registry.resolve(r) : r;
24779
- if (resolved instanceof PdfStream) return resolved;
24780
- if (resolved instanceof PdfDict) {
24787
+ if (r instanceof PdfRef) r = this.registry.resolve(r) ?? void 0;
24788
+ if (r instanceof PdfStream) return r;
24789
+ if (r instanceof PdfDict) {
24781
24790
  const stateKey = state ?? this.appearanceState ?? "Off";
24782
- const stateEntry = resolved.get(stateKey);
24791
+ let stateEntry = r.get(stateKey);
24783
24792
  if (!stateEntry) return null;
24784
- const stateStream = stateEntry.type === "ref" ? await this.registry.resolve(stateEntry) : stateEntry;
24785
- return stateStream instanceof PdfStream ? stateStream : null;
24793
+ if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
24794
+ if (stateEntry instanceof PdfStream) return stateEntry;
24795
+ return null;
24786
24796
  }
24787
24797
  return null;
24788
24798
  }
24789
24799
  /**
24790
24800
  * Get down appearance stream (shown when clicked).
24791
24801
  */
24792
- async getDownAppearance(state) {
24802
+ getDownAppearance(state) {
24793
24803
  const ap = this.dict.getDict("AP");
24794
24804
  if (!ap) return null;
24795
- const d = ap.get("D");
24805
+ let d = ap.get("D");
24796
24806
  if (!d) return null;
24797
- const resolved = d.type === "ref" ? await this.registry.resolve(d) : d;
24798
- if (resolved instanceof PdfStream) return resolved;
24799
- if (resolved instanceof PdfDict) {
24807
+ if (d instanceof PdfRef) d = this.registry.resolve(d) ?? void 0;
24808
+ if (d instanceof PdfStream) return d;
24809
+ if (d instanceof PdfDict) {
24800
24810
  const stateKey = state ?? this.appearanceState ?? "Off";
24801
- const stateEntry = resolved.get(stateKey);
24811
+ let stateEntry = d.get(stateKey);
24802
24812
  if (!stateEntry) return null;
24803
- const stateStream = stateEntry.type === "ref" ? await this.registry.resolve(stateEntry) : stateEntry;
24804
- return stateStream instanceof PdfStream ? stateStream : null;
24813
+ if (stateEntry instanceof PdfRef) stateEntry = this.registry.resolve(stateEntry) ?? void 0;
24814
+ if (stateEntry instanceof PdfStream) return stateEntry;
24815
+ return null;
24805
24816
  }
24806
24817
  return null;
24807
24818
  }
@@ -24982,7 +24993,8 @@ var FormField = class {
24982
24993
  }
24983
24994
  const parentRef = current.getRef("Parent");
24984
24995
  if (!parentRef) break;
24985
- current = this.registry.getObject(parentRef);
24996
+ const obj = this.registry.getObject(parentRef);
24997
+ current = obj instanceof PdfDict ? obj : null;
24986
24998
  }
24987
24999
  return null;
24988
25000
  }
@@ -25189,9 +25201,9 @@ var TerminalField = class extends FormField {
25189
25201
  *
25190
25202
  * @internal
25191
25203
  */
25192
- async resolveWidgets() {
25204
+ resolveWidgets() {
25193
25205
  if (this.dict.has("Rect")) {
25194
- await this.resolveMK(this.dict);
25206
+ this.resolveMK(this.dict);
25195
25207
  this._widgets = [new WidgetAnnotation(this.dict, this.ref, this.registry)];
25196
25208
  return;
25197
25209
  }
@@ -25205,10 +25217,10 @@ var TerminalField = class extends FormField {
25205
25217
  const item = kids.at(i);
25206
25218
  const ref = item instanceof PdfRef ? item : null;
25207
25219
  let widgetDict = null;
25208
- if (ref) widgetDict = await this.registry.resolve(ref);
25220
+ if (ref) widgetDict = this.registry.resolve(ref);
25209
25221
  else if (item instanceof PdfDict) widgetDict = item;
25210
25222
  if (widgetDict instanceof PdfDict) {
25211
- await this.resolveMK(widgetDict);
25223
+ this.resolveMK(widgetDict);
25212
25224
  widgets.push(new WidgetAnnotation(widgetDict, ref, this.registry));
25213
25225
  }
25214
25226
  }
@@ -25218,9 +25230,9 @@ var TerminalField = class extends FormField {
25218
25230
  * Resolve MK dictionary if it's a reference.
25219
25231
  * This ensures getAppearanceCharacteristics() can work synchronously.
25220
25232
  */
25221
- async resolveMK(dict) {
25233
+ resolveMK(dict) {
25222
25234
  const mkEntry = dict.get("MK");
25223
- if (mkEntry instanceof PdfRef) await this.registry.resolve(mkEntry);
25235
+ if (mkEntry instanceof PdfRef) this.registry.resolve(mkEntry);
25224
25236
  }
25225
25237
  /**
25226
25238
  * Add a widget to this field's /Kids array.
@@ -25250,12 +25262,12 @@ var TerminalField = class extends FormField {
25250
25262
  * This method is async because it regenerates the field's appearance
25251
25263
  * stream after resetting the value.
25252
25264
  */
25253
- async resetValue() {
25265
+ resetValue() {
25254
25266
  const dv = this.getInheritable("DV");
25255
25267
  if (dv) this.dict.set("V", dv);
25256
25268
  else this.dict.delete("V");
25257
25269
  this.needsAppearanceUpdate = true;
25258
- await this.applyChange();
25270
+ this.applyChange();
25259
25271
  }
25260
25272
  /**
25261
25273
  * Check read-only and throw if set.
@@ -25271,8 +25283,8 @@ var TerminalField = class extends FormField {
25271
25283
  *
25272
25284
  * @internal
25273
25285
  */
25274
- async applyChange() {
25275
- if (this.acroForm.updateFieldAppearance) await this.acroForm.updateFieldAppearance(this);
25286
+ applyChange() {
25287
+ if (this.acroForm.updateFieldAppearance) this.acroForm.updateFieldAppearance(this);
25276
25288
  this.needsAppearanceUpdate = false;
25277
25289
  }
25278
25290
  };
@@ -25333,14 +25345,14 @@ var CheckboxField = class extends TerminalField {
25333
25345
  /**
25334
25346
  * Check the checkbox (sets to the on-value).
25335
25347
  */
25336
- async check() {
25337
- await this.setValue(this.getOnValue());
25348
+ check() {
25349
+ this.setValue(this.getOnValue());
25338
25350
  }
25339
25351
  /**
25340
25352
  * Uncheck the checkbox (sets to "Off").
25341
25353
  */
25342
- async uncheck() {
25343
- await this.setValue("Off");
25354
+ uncheck() {
25355
+ this.setValue("Off");
25344
25356
  }
25345
25357
  /**
25346
25358
  * Set the checkbox value.
@@ -25351,7 +25363,7 @@ var CheckboxField = class extends TerminalField {
25351
25363
  * @param value "Off" or one of the on-values
25352
25364
  * @throws {Error} if field is read-only or value is invalid
25353
25365
  */
25354
- async setValue(value) {
25366
+ setValue(value) {
25355
25367
  this.assertWritable();
25356
25368
  if (value !== "Off" && !this.getOnValues().includes(value)) throw new Error(`Invalid value "${value}" for checkbox "${this.name}"`);
25357
25369
  this.dict.set("V", PdfName.of(value));
@@ -25360,7 +25372,7 @@ var CheckboxField = class extends TerminalField {
25360
25372
  widget.setAppearanceState(state);
25361
25373
  }
25362
25374
  this.needsAppearanceUpdate = true;
25363
- await this.applyChange();
25375
+ this.applyChange();
25364
25376
  }
25365
25377
  };
25366
25378
 
@@ -25460,14 +25472,14 @@ var DropdownField = class extends TerminalField {
25460
25472
  * @param value The value to select
25461
25473
  * @throws {Error} if field is read-only or value is invalid (for non-editable dropdowns)
25462
25474
  */
25463
- async setValue(value) {
25475
+ setValue(value) {
25464
25476
  this.assertWritable();
25465
25477
  if (!this.isEditable) {
25466
25478
  if (!this.getOptions().some((o) => o.value === value)) throw new Error(`Invalid value "${value}" for dropdown "${this.name}"`);
25467
25479
  }
25468
25480
  this.dict.set("V", PdfString.fromString(value));
25469
25481
  this.needsAppearanceUpdate = true;
25470
- await this.applyChange();
25482
+ this.applyChange();
25471
25483
  }
25472
25484
  };
25473
25485
  /**
@@ -25549,7 +25561,7 @@ var ListBoxField = class extends TerminalField {
25549
25561
  * @param values Array of values to select
25550
25562
  * @throws {Error} if field is read-only, multiple selection not allowed, or values are invalid
25551
25563
  */
25552
- async setValue(values) {
25564
+ setValue(values) {
25553
25565
  this.assertWritable();
25554
25566
  if (!this.isMultiSelect && values.length > 1) throw new Error(`Field "${this.name}" does not allow multiple selection`);
25555
25567
  const options = this.getOptions();
@@ -25563,7 +25575,7 @@ var ListBoxField = class extends TerminalField {
25563
25575
  else this.dict.delete("I");
25564
25576
  }
25565
25577
  this.needsAppearanceUpdate = true;
25566
- await this.applyChange();
25578
+ this.applyChange();
25567
25579
  }
25568
25580
  };
25569
25581
 
@@ -25701,7 +25713,7 @@ var RadioField = class extends TerminalField {
25701
25713
  * @param option One of getOptions() or null to deselect
25702
25714
  * @throws {Error} if field is read-only, option is invalid, or deselection not allowed
25703
25715
  */
25704
- async setValue(option) {
25716
+ setValue(option) {
25705
25717
  this.assertWritable();
25706
25718
  let value;
25707
25719
  if (option === null) {
@@ -25717,7 +25729,7 @@ var RadioField = class extends TerminalField {
25717
25729
  widget.setAppearanceState(state);
25718
25730
  }
25719
25731
  this.needsAppearanceUpdate = true;
25720
- await this.applyChange();
25732
+ this.applyChange();
25721
25733
  }
25722
25734
  };
25723
25735
 
@@ -25789,12 +25801,12 @@ var TextField = class extends TerminalField {
25789
25801
  * @param value The new text value
25790
25802
  * @throws {Error} if field is read-only
25791
25803
  */
25792
- async setValue(value) {
25804
+ setValue(value) {
25793
25805
  this.assertWritable();
25794
25806
  const finalValue = this.maxLength > 0 ? value.slice(0, this.maxLength) : value;
25795
25807
  this.dict.set("V", PdfString.fromString(finalValue));
25796
25808
  this.needsAppearanceUpdate = true;
25797
- await this.applyChange();
25809
+ this.applyChange();
25798
25810
  }
25799
25811
  };
25800
25812
 
@@ -25855,10 +25867,11 @@ function getInheritableFieldNumber(dict, key$1, registry) {
25855
25867
  if (visited.has(current)) break;
25856
25868
  visited.add(current);
25857
25869
  const value = current.get(key$1);
25858
- if (value?.type === "number") return value.value;
25870
+ if (value instanceof PdfNumber) return value.value;
25859
25871
  const parentRef = current.getRef("Parent");
25860
25872
  if (!parentRef) break;
25861
- current = registry.getObject(parentRef);
25873
+ const obj = registry.getObject(parentRef);
25874
+ current = obj instanceof PdfDict ? obj : null;
25862
25875
  }
25863
25876
  return 0;
25864
25877
  }
@@ -25912,7 +25925,7 @@ var FieldTree = class FieldTree {
25912
25925
  * @param registry The object registry for resolving references
25913
25926
  * @returns A fully-loaded FieldTree
25914
25927
  */
25915
- static async load(acroForm, registry) {
25928
+ static load(acroForm, registry) {
25916
25929
  const fieldsArray = acroForm.getDict().getArray("Fields");
25917
25930
  if (!fieldsArray) return new FieldTree([]);
25918
25931
  const visited = /* @__PURE__ */ new Set();
@@ -25926,7 +25939,8 @@ var FieldTree = class FieldTree {
25926
25939
  while (queue.length > 0) {
25927
25940
  const entry = queue.shift();
25928
25941
  if (!entry) continue;
25929
- const { item, parentName, parent } = entry;
25942
+ const { parentName, parent } = entry;
25943
+ let { item } = entry;
25930
25944
  const ref = item instanceof PdfRef ? item : null;
25931
25945
  const refKey$1 = ref ? `${ref.objectNumber}:${ref.generation}` : "";
25932
25946
  if (refKey$1 && visited.has(refKey$1)) {
@@ -25935,16 +25949,14 @@ var FieldTree = class FieldTree {
25935
25949
  }
25936
25950
  if (refKey$1) visited.add(refKey$1);
25937
25951
  let fieldDict = null;
25938
- if (item instanceof PdfRef) {
25939
- const resolved = await registry.resolve(item);
25940
- if (resolved instanceof PdfDict) fieldDict = resolved;
25941
- } else if (item instanceof PdfDict) fieldDict = item;
25952
+ if (item instanceof PdfRef) item = registry.resolve(item) ?? void 0;
25953
+ if (item instanceof PdfDict) fieldDict = item;
25942
25954
  if (!fieldDict) continue;
25943
25955
  const partialName = fieldDict.getString("T")?.asString() ?? "";
25944
25956
  const fullName = parentName ? partialName ? `${parentName}.${partialName}` : parentName : partialName;
25945
- if (await checkIsTerminalField(fieldDict, registry)) {
25957
+ if (checkIsTerminalField(fieldDict, registry)) {
25946
25958
  const field = createFormField(fieldDict, ref, registry, acroForm, fullName);
25947
- await field.resolveWidgets();
25959
+ field.resolveWidgets();
25948
25960
  field.parent = parent;
25949
25961
  fields.push(field);
25950
25962
  if (parent instanceof NonTerminalField) parent.addChild(field);
@@ -25974,7 +25986,7 @@ var FieldTree = class FieldTree {
25974
25986
  * Iterate over only terminal fields (those that hold values).
25975
25987
  */
25976
25988
  *terminalFields() {
25977
- for (const field of this.fields) if (!(field instanceof NonTerminalField)) yield field;
25989
+ for (const field of this.fields) if (field instanceof TerminalField) yield field;
25978
25990
  }
25979
25991
  /**
25980
25992
  * Get all fields as an array.
@@ -25986,7 +25998,7 @@ var FieldTree = class FieldTree {
25986
25998
  * Get all terminal fields as an array.
25987
25999
  */
25988
26000
  getTerminalFields() {
25989
- return this.fields.filter((f) => !(f instanceof NonTerminalField));
26001
+ return this.fields.filter((f) => f instanceof TerminalField);
25990
26002
  }
25991
26003
  /**
25992
26004
  * Find a field by fully-qualified name.
@@ -25999,7 +26011,7 @@ var FieldTree = class FieldTree {
25999
26011
  */
26000
26012
  findTerminalField(name) {
26001
26013
  const field = this.findField(name);
26002
- if (field && !(field instanceof NonTerminalField)) return field;
26014
+ if (field && field instanceof TerminalField) return field;
26003
26015
  return null;
26004
26016
  }
26005
26017
  /**
@@ -26022,16 +26034,14 @@ var FieldTree = class FieldTree {
26022
26034
  * - It has no /Kids, OR
26023
26035
  * - Its /Kids contain widgets (no /T) rather than child fields (have /T)
26024
26036
  */
26025
- async function checkIsTerminalField(dict, registry) {
26037
+ function checkIsTerminalField(dict, registry) {
26026
26038
  const kids = dict.getArray("Kids");
26027
26039
  if (!kids || kids.length === 0) return true;
26028
- const firstKid = kids.at(0);
26040
+ let firstKid = kids.at(0);
26029
26041
  if (!firstKid) return true;
26030
26042
  let firstKidDict = null;
26031
- if (firstKid instanceof PdfRef) {
26032
- const resolved = await registry.resolve(firstKid);
26033
- if (resolved instanceof PdfDict) firstKidDict = resolved;
26034
- } else if (firstKid instanceof PdfDict) firstKidDict = firstKid;
26043
+ if (firstKid instanceof PdfRef) firstKid = registry.resolve(firstKid) ?? void 0;
26044
+ if (firstKid instanceof PdfDict) firstKidDict = firstKid;
26035
26045
  if (!firstKidDict) return true;
26036
26046
  return !firstKidDict.has("T");
26037
26047
  }
@@ -26225,18 +26235,18 @@ var FormFlattener = class {
26225
26235
  /**
26226
26236
  * Flatten all form fields into static page content.
26227
26237
  */
26228
- async flatten(options = {}) {
26238
+ flatten(options = {}) {
26229
26239
  if (options.font || options.fontSize !== void 0) {
26230
- const fields = await this.form.getFields();
26240
+ const fields = this.form.getFields();
26231
26241
  for (const field of fields) {
26232
26242
  if (field.isReadOnly()) continue;
26233
26243
  if (options.font) field.setFont(options.font);
26234
26244
  if (options.fontSize !== void 0) field.setFontSize(options.fontSize);
26235
26245
  }
26236
26246
  }
26237
- if (!options.skipAppearanceUpdate) await this.form.updateAppearances({ forceRegenerate: options.regenerateAppearances });
26238
- const pageWidgets = await this.collectWidgetsByPage();
26239
- for (const { pageRef, widgets } of pageWidgets.values()) await this.flattenWidgetsOnPage(pageRef, widgets);
26247
+ if (!options.skipAppearanceUpdate) this.form.updateAppearances({ forceRegenerate: options.regenerateAppearances });
26248
+ const pageWidgets = this.collectWidgetsByPage();
26249
+ for (const { pageRef, widgets } of pageWidgets.values()) this.flattenWidgetsOnPage(pageRef, widgets);
26240
26250
  const dict = this.form.getDict();
26241
26251
  dict.set("Fields", new PdfArray([]));
26242
26252
  dict.delete("NeedAppearances");
@@ -26246,12 +26256,12 @@ var FormFlattener = class {
26246
26256
  /**
26247
26257
  * Collect all widgets grouped by their containing page.
26248
26258
  */
26249
- async collectWidgetsByPage() {
26259
+ collectWidgetsByPage() {
26250
26260
  const result = /* @__PURE__ */ new Map();
26251
- const fields = await this.form.getFields();
26261
+ const fields = this.form.getFields();
26252
26262
  for (const field of fields) for (const widget of field.getWidgets()) {
26253
26263
  let pageRef = widget.pageRef;
26254
- if (!pageRef) pageRef = await this.findPageForWidget(widget);
26264
+ if (!pageRef) pageRef = this.findPageForWidget(widget);
26255
26265
  if (!pageRef) {
26256
26266
  this.registry.addWarning(`Widget without page reference for field "${field.name}"`);
26257
26267
  continue;
@@ -26275,7 +26285,7 @@ var FormFlattener = class {
26275
26285
  *
26276
26286
  * Uses the PageTree if available for efficient page iteration.
26277
26287
  */
26278
- async findPageForWidget(widget) {
26288
+ findPageForWidget(widget) {
26279
26289
  if (!widget.ref) return null;
26280
26290
  if (!this.pageTree) {
26281
26291
  this.registry.addWarning("No page tree available; cannot find page for widget without /P");
@@ -26283,7 +26293,7 @@ var FormFlattener = class {
26283
26293
  }
26284
26294
  const pageRefs = this.pageTree.getPages();
26285
26295
  for (const pageRef of pageRefs) {
26286
- const pageDict = await this.registry.resolve(pageRef);
26296
+ const pageDict = this.registry.resolve(pageRef);
26287
26297
  if (!(pageDict instanceof PdfDict)) continue;
26288
26298
  const annots = pageDict.getArray("Annots");
26289
26299
  if (!annots) continue;
@@ -26303,8 +26313,8 @@ var FormFlattener = class {
26303
26313
  *
26304
26314
  * This isolates the original page's graphics state from our flattened fields.
26305
26315
  */
26306
- async flattenWidgetsOnPage(pageRef, widgets) {
26307
- const pageDict = await this.registry.resolve(pageRef);
26316
+ flattenWidgetsOnPage(pageRef, widgets) {
26317
+ const pageDict = this.registry.resolve(pageRef);
26308
26318
  if (!(pageDict instanceof PdfDict)) return;
26309
26319
  let resources = pageDict.getDict("Resources");
26310
26320
  if (!resources) {
@@ -26322,7 +26332,7 @@ var FormFlattener = class {
26322
26332
  let hasVisibleWidgets = false;
26323
26333
  for (const widget of widgets) {
26324
26334
  if (this.isWidgetHidden(widget)) continue;
26325
- const appearance = await widget.getNormalAppearance(widget.appearanceState ?? void 0);
26335
+ const appearance = widget.getNormalAppearance(widget.appearanceState ?? void 0);
26326
26336
  if (!appearance) {
26327
26337
  this.registry.addWarning("Widget without appearance stream skipped during flatten");
26328
26338
  continue;
@@ -26338,7 +26348,7 @@ var FormFlattener = class {
26338
26348
  if (widget.ref) widgetRefs.add(`${widget.ref.objectNumber} ${widget.ref.generation}`);
26339
26349
  }
26340
26350
  if (hasVisibleWidgets && !content.isEmpty()) this.wrapAndAppendContent(pageDict, content.toBytes());
26341
- await this.removeAnnotations(pageDict, widgetRefs);
26351
+ this.removeAnnotations(pageDict, widgetRefs);
26342
26352
  }
26343
26353
  /**
26344
26354
  * Check if appearance stream has valid dimensions.
@@ -26347,12 +26357,9 @@ var FormFlattener = class {
26347
26357
  isVisibleAppearance(appearance) {
26348
26358
  const bbox = appearance.getArray("BBox");
26349
26359
  if (!bbox || bbox.length < 4) return false;
26350
- const x1 = bbox.at(0)?.value ?? 0;
26351
- const y1 = bbox.at(1)?.value ?? 0;
26352
- const x2 = bbox.at(2)?.value ?? 0;
26353
- const y2 = bbox.at(3)?.value ?? 0;
26354
- const width = Math.abs(x2 - x1);
26355
- const height = Math.abs(y2 - y1);
26360
+ const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
26361
+ const width = Math.abs((x2 ?? 0) - (x1 ?? 0));
26362
+ const height = Math.abs((y2 ?? 0) - (y1 ?? 0));
26356
26363
  return width > 0 && height > 0;
26357
26364
  }
26358
26365
  /**
@@ -26452,7 +26459,8 @@ var FormFlattener = class {
26452
26459
  getAppearanceMatrix(appearance) {
26453
26460
  const matrixArray = appearance.getArray("Matrix");
26454
26461
  if (!matrixArray || matrixArray.length < 6) return Matrix.identity();
26455
- return new Matrix(matrixArray.at(0)?.value ?? 1, matrixArray.at(1)?.value ?? 0, matrixArray.at(2)?.value ?? 0, matrixArray.at(3)?.value ?? 1, matrixArray.at(4)?.value ?? 0, matrixArray.at(5)?.value ?? 0);
26462
+ const [a, b, c, d, e, f] = matrixArray.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
26463
+ return new Matrix(a ?? 0, b ?? 0, c ?? 0, d ?? 0, e ?? 0, f ?? 0);
26456
26464
  }
26457
26465
  /**
26458
26466
  * Get appearance BBox, with fallback.
@@ -26465,23 +26473,24 @@ var FormFlattener = class {
26465
26473
  1,
26466
26474
  1
26467
26475
  ];
26476
+ const [x1, y1, x2, y2] = bbox.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
26468
26477
  return [
26469
- bbox.at(0)?.value ?? 0,
26470
- bbox.at(1)?.value ?? 0,
26471
- bbox.at(2)?.value ?? 0,
26472
- bbox.at(3)?.value ?? 0
26478
+ x1 ?? 0,
26479
+ y1 ?? 0,
26480
+ x2 ?? 0,
26481
+ y2 ?? 0
26473
26482
  ];
26474
26483
  }
26475
26484
  /**
26476
26485
  * Remove specific annotations from page.
26477
26486
  */
26478
- async removeAnnotations(page, toRemove) {
26487
+ removeAnnotations(page, toRemove) {
26479
26488
  const annotsEntry = page.get("Annots");
26480
26489
  if (!annotsEntry) return;
26481
26490
  let annots = null;
26482
26491
  if (annotsEntry instanceof PdfArray) annots = annotsEntry;
26483
26492
  else if (annotsEntry instanceof PdfRef) {
26484
- const resolved = await this.registry.resolve(annotsEntry);
26493
+ const resolved = this.registry.resolve(annotsEntry);
26485
26494
  if (resolved instanceof PdfArray) annots = resolved;
26486
26495
  }
26487
26496
  if (!annots) return;
@@ -26548,28 +26557,24 @@ var AcroForm = class AcroForm {
26548
26557
  * @param registry The object registry for resolving references
26549
26558
  * @param pageTree Optional page tree for efficient page lookups during flattening
26550
26559
  */
26551
- static async load(catalog, registry, pageTree) {
26552
- const acroFormEntry = catalog.get("AcroForm");
26560
+ static load(catalog, registry, pageTree) {
26561
+ let acroFormEntry = catalog.get("AcroForm");
26553
26562
  if (!acroFormEntry) return null;
26554
26563
  let dict = null;
26555
- if (acroFormEntry instanceof PdfRef) {
26556
- const resolved = await registry.resolve(acroFormEntry);
26557
- if (resolved instanceof PdfDict) dict = resolved;
26558
- } else if (acroFormEntry instanceof PdfDict) dict = acroFormEntry;
26564
+ if (acroFormEntry instanceof PdfRef) acroFormEntry = registry.resolve(acroFormEntry) ?? void 0;
26565
+ if (acroFormEntry instanceof PdfDict) dict = acroFormEntry;
26559
26566
  if (!dict) return null;
26560
26567
  return new AcroForm(dict, registry, pageTree ?? null);
26561
26568
  }
26562
26569
  /**
26563
26570
  * Default resources dictionary (fonts, etc.).
26564
26571
  */
26565
- async getDefaultResources() {
26566
- const dr = this.dict.get("DR");
26572
+ getDefaultResources() {
26573
+ let dr = this.dict.get("DR");
26567
26574
  if (!dr) return null;
26568
- if (dr instanceof PdfRef) {
26569
- const resolved = await this.registry.resolve(dr);
26570
- return resolved instanceof PdfDict ? resolved : null;
26571
- }
26572
- return dr instanceof PdfDict ? dr : null;
26575
+ if (dr instanceof PdfRef) dr = this.registry.resolve(dr) ?? void 0;
26576
+ if (dr instanceof PdfDict) return dr;
26577
+ return null;
26573
26578
  }
26574
26579
  /**
26575
26580
  * Default appearance string.
@@ -26615,12 +26620,12 @@ var AcroForm = class AcroForm {
26615
26620
  * Get all terminal fields (flattened).
26616
26621
  * Non-terminal fields (containers) are not included.
26617
26622
  */
26618
- async getFields() {
26623
+ getFields() {
26619
26624
  if (this.fieldsCache) return this.fieldsCache;
26620
26625
  const fieldsArray = this.dict.getArray("Fields");
26621
26626
  if (!fieldsArray) return [];
26622
26627
  const visited = /* @__PURE__ */ new Set();
26623
- const fields = await this.collectFields(fieldsArray, visited, "");
26628
+ const fields = this.collectFields(fieldsArray, visited, "");
26624
26629
  this.fieldsCache = fields;
26625
26630
  return fields;
26626
26631
  }
@@ -26628,14 +26633,14 @@ var AcroForm = class AcroForm {
26628
26633
  * Get field by fully-qualified name.
26629
26634
  * Returns null if not found.
26630
26635
  */
26631
- async getField(name) {
26632
- return (await this.getFields()).find((f) => f.name === name) ?? null;
26636
+ getField(name) {
26637
+ return this.getFields().find((f) => f.name === name) ?? null;
26633
26638
  }
26634
26639
  /**
26635
26640
  * Get all fields of a specific type.
26636
26641
  */
26637
- async getFieldsOfType(type) {
26638
- return (await this.getFields()).filter((f) => f.type === type);
26642
+ getFieldsOfType(type) {
26643
+ return this.getFields().filter((f) => f.type === type);
26639
26644
  }
26640
26645
  /**
26641
26646
  * Get the underlying dictionary.
@@ -26667,7 +26672,7 @@ var AcroForm = class AcroForm {
26667
26672
  * }
26668
26673
  * ```
26669
26674
  */
26670
- async getFieldTree() {
26675
+ getFieldTree() {
26671
26676
  return FieldTree.load(this, this.registry);
26672
26677
  }
26673
26678
  /**
@@ -26741,8 +26746,10 @@ var AcroForm = class AcroForm {
26741
26746
  const fontName = key$1.value;
26742
26747
  const fontObj = fonts.get(fontName);
26743
26748
  if (fontObj) {
26744
- const existingFont = parseExistingFont(fontName, fontObj, this.registry);
26745
- this.existingFontsCache.set(fontName, existingFont);
26749
+ if (fontObj instanceof PdfDict || fontObj instanceof PdfRef) {
26750
+ const existingFont = parseExistingFont(fontName, fontObj, this.registry);
26751
+ this.existingFontsCache.set(fontName, existingFont);
26752
+ }
26746
26753
  }
26747
26754
  }
26748
26755
  }
@@ -26754,60 +26761,38 @@ var AcroForm = class AcroForm {
26754
26761
  *
26755
26762
  * @internal
26756
26763
  */
26757
- async updateFieldAppearance(field) {
26764
+ updateFieldAppearance(field) {
26758
26765
  if (field.isReadOnly()) return;
26759
26766
  const generator = new AppearanceGenerator(this, this.registry);
26760
- switch (field.type) {
26761
- case "text": {
26762
- const textField = field;
26763
- for (const widget of textField.getWidgets()) {
26764
- const existingAppearance = await widget.getNormalAppearance();
26765
- const existingStyle = existingAppearance ? await extractAppearanceStyle(existingAppearance) : void 0;
26766
- const stream = generator.generateTextAppearance(textField, widget, existingStyle);
26767
- widget.setNormalAppearance(stream);
26768
- }
26769
- break;
26770
- }
26771
- case "checkbox": {
26772
- const checkboxField = field;
26773
- for (const widget of checkboxField.getWidgets()) {
26774
- const onValue = widget.getOnValue() ?? "Yes";
26775
- if (widget.hasAppearancesForStates([onValue, "Off"])) continue;
26776
- const { on, off } = generator.generateCheckboxAppearance(checkboxField, widget, onValue);
26777
- widget.setNormalAppearance(on, onValue);
26778
- widget.setNormalAppearance(off, "Off");
26779
- }
26780
- break;
26781
- }
26782
- case "radio": {
26783
- const radioField = field;
26784
- for (const widget of radioField.getWidgets()) {
26785
- const value = widget.getOnValue() ?? "Choice";
26786
- if (widget.hasAppearancesForStates([value, "Off"])) continue;
26787
- const { selected, off } = generator.generateRadioAppearance(radioField, widget, value);
26788
- widget.setNormalAppearance(selected, value);
26789
- widget.setNormalAppearance(off, "Off");
26790
- }
26791
- break;
26792
- }
26793
- case "dropdown": {
26794
- const dropdownField = field;
26795
- for (const widget of dropdownField.getWidgets()) {
26796
- const stream = generator.generateDropdownAppearance(dropdownField, widget);
26797
- widget.setNormalAppearance(stream);
26798
- }
26799
- break;
26800
- }
26801
- case "listbox": {
26802
- const listboxField = field;
26803
- for (const widget of listboxField.getWidgets()) {
26804
- const stream = generator.generateListBoxAppearance(listboxField, widget);
26805
- widget.setNormalAppearance(stream);
26806
- }
26807
- break;
26808
- }
26809
- case "button": break;
26810
- }
26767
+ if (field instanceof TextField) for (const widget of field.getWidgets()) {
26768
+ const existingAppearance = widget.getNormalAppearance();
26769
+ const existingStyle = existingAppearance ? extractAppearanceStyle(existingAppearance) : void 0;
26770
+ const stream = generator.generateTextAppearance(field, widget, existingStyle);
26771
+ widget.setNormalAppearance(stream);
26772
+ }
26773
+ if (field instanceof CheckboxField) for (const widget of field.getWidgets()) {
26774
+ const onValue = widget.getOnValue() ?? "Yes";
26775
+ if (widget.hasAppearancesForStates([onValue, "Off"])) continue;
26776
+ const { on, off } = generator.generateCheckboxAppearance(field, widget, onValue);
26777
+ widget.setNormalAppearance(on, onValue);
26778
+ widget.setNormalAppearance(off, "Off");
26779
+ }
26780
+ if (field instanceof RadioField) for (const widget of field.getWidgets()) {
26781
+ const value = widget.getOnValue() ?? "Choice";
26782
+ if (widget.hasAppearancesForStates([value, "Off"])) continue;
26783
+ const { selected, off } = generator.generateRadioAppearance(field, widget, value);
26784
+ widget.setNormalAppearance(selected, value);
26785
+ widget.setNormalAppearance(off, "Off");
26786
+ }
26787
+ if (field instanceof DropdownField) for (const widget of field.getWidgets()) {
26788
+ const stream = generator.generateDropdownAppearance(field, widget);
26789
+ widget.setNormalAppearance(stream);
26790
+ }
26791
+ if (field instanceof ListBoxField) for (const widget of field.getWidgets()) {
26792
+ const stream = generator.generateListBoxAppearance(field, widget);
26793
+ widget.setNormalAppearance(stream);
26794
+ }
26795
+ if (field instanceof ButtonField) {}
26811
26796
  this.dict.delete("NeedAppearances");
26812
26797
  }
26813
26798
  /**
@@ -26818,9 +26803,9 @@ var AcroForm = class AcroForm {
26818
26803
  *
26819
26804
  * @param options.forceRegenerate Force regeneration even if appearances exist
26820
26805
  */
26821
- async updateAppearances(options = {}) {
26806
+ updateAppearances(options = {}) {
26822
26807
  const generator = new AppearanceGenerator(this, this.registry);
26823
- const fields = await this.getFields();
26808
+ const fields = this.getFields();
26824
26809
  for (const field of fields) {
26825
26810
  if (!field.needsAppearanceUpdate) continue;
26826
26811
  if (field.isReadOnly()) {
@@ -26828,59 +26813,37 @@ var AcroForm = class AcroForm {
26828
26813
  continue;
26829
26814
  }
26830
26815
  const forceRegen = options.forceRegenerate ?? false;
26831
- switch (field.type) {
26832
- case "text": {
26833
- const textField = field;
26834
- for (const widget of textField.getWidgets()) {
26835
- const existingAppearance = await widget.getNormalAppearance();
26836
- const existingStyle = existingAppearance ? await extractAppearanceStyle(existingAppearance) : void 0;
26837
- const stream = generator.generateTextAppearance(textField, widget, existingStyle);
26838
- widget.setNormalAppearance(stream);
26839
- }
26840
- break;
26841
- }
26842
- case "checkbox": {
26843
- const checkboxField = field;
26844
- for (const widget of checkboxField.getWidgets()) {
26845
- const onValue = widget.getOnValue() ?? "Yes";
26846
- if (!forceRegen && widget.hasAppearancesForStates([onValue, "Off"])) continue;
26847
- const { on, off } = generator.generateCheckboxAppearance(checkboxField, widget, onValue);
26848
- widget.setNormalAppearance(on, onValue);
26849
- widget.setNormalAppearance(off, "Off");
26850
- }
26851
- break;
26852
- }
26853
- case "radio": {
26854
- const radioField = field;
26855
- for (const widget of radioField.getWidgets()) {
26856
- const value = widget.getOnValue() ?? "Choice";
26857
- if (!forceRegen && widget.hasAppearancesForStates([value, "Off"])) continue;
26858
- const { selected, off } = generator.generateRadioAppearance(radioField, widget, value);
26859
- widget.setNormalAppearance(selected, value);
26860
- widget.setNormalAppearance(off, "Off");
26861
- }
26862
- break;
26863
- }
26864
- case "dropdown": {
26865
- const dropdownField = field;
26866
- for (const widget of dropdownField.getWidgets()) {
26867
- if (!forceRegen && widget.hasNormalAppearance()) continue;
26868
- const stream = generator.generateDropdownAppearance(dropdownField, widget);
26869
- widget.setNormalAppearance(stream);
26870
- }
26871
- break;
26872
- }
26873
- case "listbox": {
26874
- const listboxField = field;
26875
- for (const widget of listboxField.getWidgets()) {
26876
- if (!forceRegen && widget.hasNormalAppearance()) continue;
26877
- const stream = generator.generateListBoxAppearance(listboxField, widget);
26878
- widget.setNormalAppearance(stream);
26879
- }
26880
- break;
26881
- }
26882
- case "button": break;
26816
+ if (field instanceof TextField) for (const widget of field.getWidgets()) {
26817
+ const existingAppearance = widget.getNormalAppearance();
26818
+ const existingStyle = existingAppearance ? extractAppearanceStyle(existingAppearance) : void 0;
26819
+ const stream = generator.generateTextAppearance(field, widget, existingStyle);
26820
+ widget.setNormalAppearance(stream);
26821
+ }
26822
+ if (field instanceof CheckboxField) for (const widget of field.getWidgets()) {
26823
+ const onValue = widget.getOnValue() ?? "Yes";
26824
+ if (!forceRegen && widget.hasAppearancesForStates([onValue, "Off"])) continue;
26825
+ const { on, off } = generator.generateCheckboxAppearance(field, widget, onValue);
26826
+ widget.setNormalAppearance(on, onValue);
26827
+ widget.setNormalAppearance(off, "Off");
26828
+ }
26829
+ if (field instanceof RadioField) for (const widget of field.getWidgets()) {
26830
+ const value = widget.getOnValue() ?? "Choice";
26831
+ if (!forceRegen && widget.hasAppearancesForStates([value, "Off"])) continue;
26832
+ const { selected, off } = generator.generateRadioAppearance(field, widget, value);
26833
+ widget.setNormalAppearance(selected, value);
26834
+ widget.setNormalAppearance(off, "Off");
26883
26835
  }
26836
+ if (field instanceof DropdownField) for (const widget of field.getWidgets()) {
26837
+ if (!forceRegen && widget.hasNormalAppearance()) continue;
26838
+ const stream = generator.generateDropdownAppearance(field, widget);
26839
+ widget.setNormalAppearance(stream);
26840
+ }
26841
+ if (field instanceof ListBoxField) for (const widget of field.getWidgets()) {
26842
+ if (!forceRegen && widget.hasNormalAppearance()) continue;
26843
+ const stream = generator.generateListBoxAppearance(field, widget);
26844
+ widget.setNormalAppearance(stream);
26845
+ }
26846
+ if (field instanceof ButtonField) {}
26884
26847
  field.needsAppearanceUpdate = false;
26885
26848
  }
26886
26849
  this.dict.delete("NeedAppearances");
@@ -26888,17 +26851,17 @@ var AcroForm = class AcroForm {
26888
26851
  /**
26889
26852
  * Mark all fields as needing appearance update.
26890
26853
  */
26891
- async markAllNeedAppearanceUpdate() {
26892
- const fields = await this.getFields();
26854
+ markAllNeedAppearanceUpdate() {
26855
+ const fields = this.getFields();
26893
26856
  for (const field of fields) field.needsAppearanceUpdate = true;
26894
26857
  }
26895
26858
  /**
26896
26859
  * Collect all terminal fields from a /Kids or /Fields array.
26897
26860
  */
26898
- async collectFields(kids, visited, parentName) {
26861
+ collectFields(kids, visited, parentName) {
26899
26862
  const fields = [];
26900
26863
  for (let i = 0; i < kids.length; i++) {
26901
- const item = kids.at(i);
26864
+ let item = kids.at(i);
26902
26865
  const ref = item instanceof PdfRef ? item : null;
26903
26866
  const refKey$1 = ref ? `${ref.objectNumber} ${ref.generation}` : "";
26904
26867
  if (refKey$1 && visited.has(refKey$1)) {
@@ -26907,20 +26870,18 @@ var AcroForm = class AcroForm {
26907
26870
  }
26908
26871
  if (refKey$1) visited.add(refKey$1);
26909
26872
  let dict = null;
26910
- if (item instanceof PdfRef) {
26911
- const resolved = await this.registry.resolve(item);
26912
- if (resolved instanceof PdfDict) dict = resolved;
26913
- } else if (item instanceof PdfDict) dict = item;
26873
+ if (item instanceof PdfRef) item = this.registry.resolve(item) ?? void 0;
26874
+ if (item instanceof PdfDict) dict = item;
26914
26875
  if (!dict) continue;
26915
26876
  const partialName = dict.getString("T")?.asString() ?? "";
26916
26877
  const fullName = parentName ? partialName ? `${parentName}.${partialName}` : parentName : partialName;
26917
- if (await this.isTerminalField(dict)) {
26878
+ if (this.isTerminalField(dict)) {
26918
26879
  const field = createFormField(dict, ref, this.registry, this, fullName);
26919
- await field.resolveWidgets();
26880
+ field.resolveWidgets();
26920
26881
  fields.push(field);
26921
26882
  } else {
26922
26883
  const childKids = dict.getArray("Kids");
26923
- if (childKids) fields.push(...await this.collectFields(childKids, visited, fullName));
26884
+ if (childKids) fields.push(...this.collectFields(childKids, visited, fullName));
26924
26885
  }
26925
26886
  }
26926
26887
  return fields;
@@ -26932,16 +26893,14 @@ var AcroForm = class AcroForm {
26932
26893
  * - It has no /Kids, OR
26933
26894
  * - Its /Kids contain widgets (no /T) rather than child fields (have /T)
26934
26895
  */
26935
- async isTerminalField(dict) {
26896
+ isTerminalField(dict) {
26936
26897
  const kids = dict.getArray("Kids");
26937
26898
  if (!kids || kids.length === 0) return true;
26938
- const firstKid = kids.at(0);
26899
+ let firstKid = kids.at(0);
26939
26900
  if (!firstKid) return true;
26940
26901
  let firstKidDict = null;
26941
- if (firstKid instanceof PdfRef) {
26942
- const resolved = await this.registry.resolve(firstKid);
26943
- if (resolved instanceof PdfDict) firstKidDict = resolved;
26944
- } else if (firstKid instanceof PdfDict) firstKidDict = firstKid;
26902
+ if (firstKid instanceof PdfRef) firstKid = this.registry.resolve(firstKid) ?? void 0;
26903
+ if (firstKid instanceof PdfDict) firstKidDict = firstKid;
26945
26904
  if (!firstKidDict) return true;
26946
26905
  return !firstKidDict.has("T");
26947
26906
  }
@@ -27003,6 +26962,28 @@ var AcroForm = class AcroForm {
27003
26962
  this.clearCache();
27004
26963
  }
27005
26964
  /**
26965
+ * Remove a field reference from the Fields array.
26966
+ *
26967
+ * This only removes the field from the AcroForm's /Fields array.
26968
+ * Widget removal from pages must be handled separately.
26969
+ *
26970
+ * @param fieldRef Reference to the field dictionary to remove
26971
+ * @returns true if the field was found and removed, false otherwise
26972
+ */
26973
+ removeField(fieldRef) {
26974
+ const fieldsArray = this.dict.getArray("Fields");
26975
+ if (!fieldsArray) return false;
26976
+ for (let i = 0; i < fieldsArray.length; i++) {
26977
+ const item = fieldsArray.at(i);
26978
+ if (item instanceof PdfRef && item === fieldRef) {
26979
+ fieldsArray.remove(i);
26980
+ this.clearCache();
26981
+ return true;
26982
+ }
26983
+ }
26984
+ return false;
26985
+ }
26986
+ /**
27006
26987
  * Flatten all form fields into static page content.
27007
26988
  *
27008
26989
  * This converts interactive form fields into static graphics. After flattening:
@@ -27017,8 +26998,8 @@ var AcroForm = class AcroForm {
27017
26998
  *
27018
26999
  * @param options Flattening options
27019
27000
  */
27020
- async flatten(options = {}) {
27021
- await new FormFlattener(this, this.registry, this.pageTree).flatten(options);
27001
+ flatten(options = {}) {
27002
+ new FormFlattener(this, this.registry, this.pageTree).flatten(options);
27022
27003
  this.fieldsCache = null;
27023
27004
  }
27024
27005
  };
@@ -27196,10 +27177,10 @@ var PDFForm = class PDFForm {
27196
27177
  * @param ctx The PDF context
27197
27178
  * @returns PDFForm instance, or null if no form exists
27198
27179
  */
27199
- static async load(ctx) {
27200
- const acroForm = await AcroForm.load(ctx.catalog.getDict(), ctx.registry, ctx.pages);
27180
+ static load(ctx) {
27181
+ const acroForm = AcroForm.load(ctx.catalog.getDict(), ctx.registry, ctx.pages);
27201
27182
  if (!acroForm) return null;
27202
- return new PDFForm(acroForm, ctx, await acroForm.getFields());
27183
+ return new PDFForm(acroForm, ctx, acroForm.getFields());
27203
27184
  }
27204
27185
  /**
27205
27186
  * Get all form fields.
@@ -27228,7 +27209,7 @@ var PDFForm = class PDFForm {
27228
27209
  */
27229
27210
  getTextField(name) {
27230
27211
  const field = this.fieldsByName.get(name);
27231
- return field?.type === "text" ? field : void 0;
27212
+ return field instanceof TextField ? field : void 0;
27232
27213
  }
27233
27214
  /**
27234
27215
  * Get a checkbox field by name.
@@ -27237,7 +27218,7 @@ var PDFForm = class PDFForm {
27237
27218
  */
27238
27219
  getCheckbox(name) {
27239
27220
  const field = this.fieldsByName.get(name);
27240
- return field?.type === "checkbox" ? field : void 0;
27221
+ return field instanceof CheckboxField ? field : void 0;
27241
27222
  }
27242
27223
  /**
27243
27224
  * Get a radio button group by name.
@@ -27246,7 +27227,7 @@ var PDFForm = class PDFForm {
27246
27227
  */
27247
27228
  getRadioGroup(name) {
27248
27229
  const field = this.fieldsByName.get(name);
27249
- return field?.type === "radio" ? field : void 0;
27230
+ return field instanceof RadioField ? field : void 0;
27250
27231
  }
27251
27232
  /**
27252
27233
  * Get a dropdown (combo box) field by name.
@@ -27255,7 +27236,7 @@ var PDFForm = class PDFForm {
27255
27236
  */
27256
27237
  getDropdown(name) {
27257
27238
  const field = this.fieldsByName.get(name);
27258
- return field?.type === "dropdown" ? field : void 0;
27239
+ return field instanceof DropdownField ? field : void 0;
27259
27240
  }
27260
27241
  /**
27261
27242
  * Get a list box field by name.
@@ -27264,7 +27245,7 @@ var PDFForm = class PDFForm {
27264
27245
  */
27265
27246
  getListBox(name) {
27266
27247
  const field = this.fieldsByName.get(name);
27267
- return field?.type === "listbox" ? field : void 0;
27248
+ return field instanceof ListBoxField ? field : void 0;
27268
27249
  }
27269
27250
  /**
27270
27251
  * Get a signature field by name.
@@ -27273,7 +27254,7 @@ var PDFForm = class PDFForm {
27273
27254
  */
27274
27255
  getSignatureField(name) {
27275
27256
  const field = this.fieldsByName.get(name);
27276
- return field?.type === "signature" ? field : void 0;
27257
+ return field instanceof SignatureField ? field : void 0;
27277
27258
  }
27278
27259
  /**
27279
27260
  * Get a button field by name.
@@ -27282,7 +27263,7 @@ var PDFForm = class PDFForm {
27282
27263
  */
27283
27264
  getButton(name) {
27284
27265
  const field = this.fieldsByName.get(name);
27285
- return field?.type === "button" ? field : void 0;
27266
+ return field instanceof ButtonField ? field : void 0;
27286
27267
  }
27287
27268
  /**
27288
27269
  * Check if a field exists.
@@ -27294,43 +27275,43 @@ var PDFForm = class PDFForm {
27294
27275
  * Get all text fields.
27295
27276
  */
27296
27277
  getTextFields() {
27297
- return this.allFields.filter((f) => f.type === "text");
27278
+ return this.allFields.filter((f) => f instanceof TextField);
27298
27279
  }
27299
27280
  /**
27300
27281
  * Get all checkboxes.
27301
27282
  */
27302
27283
  getCheckboxes() {
27303
- return this.allFields.filter((f) => f.type === "checkbox");
27284
+ return this.allFields.filter((f) => f instanceof CheckboxField);
27304
27285
  }
27305
27286
  /**
27306
27287
  * Get all radio button groups.
27307
27288
  */
27308
27289
  getRadioGroups() {
27309
- return this.allFields.filter((f) => f.type === "radio");
27290
+ return this.allFields.filter((f) => f instanceof RadioField);
27310
27291
  }
27311
27292
  /**
27312
27293
  * Get all dropdowns.
27313
27294
  */
27314
27295
  getDropdowns() {
27315
- return this.allFields.filter((f) => f.type === "dropdown");
27296
+ return this.allFields.filter((f) => f instanceof DropdownField);
27316
27297
  }
27317
27298
  /**
27318
27299
  * Get all list boxes.
27319
27300
  */
27320
27301
  getListBoxes() {
27321
- return this.allFields.filter((f) => f.type === "listbox");
27302
+ return this.allFields.filter((f) => f instanceof ListBoxField);
27322
27303
  }
27323
27304
  /**
27324
27305
  * Get all signature fields.
27325
27306
  */
27326
27307
  getSignatureFields() {
27327
- return this.allFields.filter((f) => f.type === "signature");
27308
+ return this.allFields.filter((f) => f instanceof SignatureField);
27328
27309
  }
27329
27310
  /**
27330
27311
  * Get all buttons.
27331
27312
  */
27332
27313
  getButtons() {
27333
- return this.allFields.filter((f) => f.type === "button");
27314
+ return this.allFields.filter((f) => f instanceof ButtonField);
27334
27315
  }
27335
27316
  /**
27336
27317
  * Create a new signature field.
@@ -27627,6 +27608,69 @@ var PDFForm = class PDFForm {
27627
27608
  return field;
27628
27609
  }
27629
27610
  /**
27611
+ * Remove a form field from the document.
27612
+ *
27613
+ * This removes the field from the AcroForm and all its widget annotations
27614
+ * from their respective pages.
27615
+ *
27616
+ * @param fieldOrName - The field instance or field name to remove
27617
+ * @returns true if the field was found and removed, false otherwise
27618
+ *
27619
+ * @example
27620
+ * ```typescript
27621
+ * // Remove by field instance
27622
+ * const nameField = form.getTextField("name");
27623
+ * form.removeField(nameField);
27624
+ *
27625
+ * // Remove by name
27626
+ * form.removeField("email");
27627
+ * ```
27628
+ */
27629
+ removeField(fieldOrName) {
27630
+ const field = typeof fieldOrName === "string" ? this.fieldsByName.get(fieldOrName) : fieldOrName;
27631
+ if (!field) return false;
27632
+ const fieldRef = field.getRef();
27633
+ if (!fieldRef) return false;
27634
+ this.removeWidgetsFromPages(field);
27635
+ const removed = this._acroForm.removeField(fieldRef);
27636
+ if (removed) {
27637
+ this.allFields = this.allFields.filter((f) => f !== field);
27638
+ this.fieldsByName.delete(field.name);
27639
+ }
27640
+ return removed;
27641
+ }
27642
+ /**
27643
+ * Remove all widgets of a field from their respective pages.
27644
+ */
27645
+ removeWidgetsFromPages(field) {
27646
+ const widgets = field.getWidgets();
27647
+ const pageRefs = this._ctx.pages.getPages();
27648
+ const widgetRefKeys = /* @__PURE__ */ new Set();
27649
+ for (const widget of widgets) if (widget.ref) widgetRefKeys.add(`${widget.ref.objectNumber} ${widget.ref.generation}`);
27650
+ if (widgetRefKeys.size === 0) return;
27651
+ for (const pageRef of pageRefs) {
27652
+ const pageDict = this._ctx.registry.resolve(pageRef);
27653
+ if (!(pageDict instanceof PdfDict)) continue;
27654
+ const annotsEntry = pageDict.get("Annots");
27655
+ if (!annotsEntry) continue;
27656
+ let annots = null;
27657
+ if (annotsEntry instanceof PdfArray) annots = annotsEntry;
27658
+ else if (annotsEntry instanceof PdfRef) {
27659
+ const resolved = this._ctx.registry.resolve(annotsEntry);
27660
+ if (resolved instanceof PdfArray) annots = resolved;
27661
+ }
27662
+ if (!annots) continue;
27663
+ for (let i = annots.length - 1; i >= 0; i--) {
27664
+ const item = annots.at(i);
27665
+ if (item instanceof PdfRef) {
27666
+ const key$1 = `${item.objectNumber} ${item.generation}`;
27667
+ if (widgetRefKeys.has(key$1)) annots.remove(i);
27668
+ }
27669
+ }
27670
+ if (annots.length === 0) pageDict.delete("Annots");
27671
+ }
27672
+ }
27673
+ /**
27630
27674
  * Validate that a field name is unique.
27631
27675
  */
27632
27676
  validateUniqueName(name) {
@@ -27696,7 +27740,7 @@ var PDFForm = class PDFForm {
27696
27740
  * // result.skipped: ["nonexistent"]
27697
27741
  * ```
27698
27742
  */
27699
- async fill(values) {
27743
+ fill(values) {
27700
27744
  const filled = [];
27701
27745
  const skipped = [];
27702
27746
  for (const [name, value] of Object.entries(values)) {
@@ -27705,7 +27749,7 @@ var PDFForm = class PDFForm {
27705
27749
  skipped.push(name);
27706
27750
  continue;
27707
27751
  }
27708
- await this.setFieldValue(field, value);
27752
+ this.setFieldValue(field, value);
27709
27753
  filled.push(name);
27710
27754
  }
27711
27755
  return {
@@ -27716,8 +27760,8 @@ var PDFForm = class PDFForm {
27716
27760
  /**
27717
27761
  * Reset all fields to their default values.
27718
27762
  */
27719
- async resetAll() {
27720
- for (const field of this.allFields) if (field instanceof TerminalField) await field.resetValue();
27763
+ resetAll() {
27764
+ for (const field of this.allFields) if (field instanceof TerminalField) field.resetValue();
27721
27765
  }
27722
27766
  /**
27723
27767
  * Get form-level properties.
@@ -27762,8 +27806,8 @@ var PDFForm = class PDFForm {
27762
27806
  * Call this if the form structure has been modified externally
27763
27807
  * (e.g., fields added or removed via low-level API).
27764
27808
  */
27765
- async reloadFields() {
27766
- const fields = await this._acroForm.getFields();
27809
+ reloadFields() {
27810
+ const fields = this._acroForm.getFields();
27767
27811
  this.allFields = fields;
27768
27812
  this.fieldsByName = new Map(fields.map((f) => [f.name, f]));
27769
27813
  }
@@ -27773,8 +27817,8 @@ var PDFForm = class PDFForm {
27773
27817
  * This regenerates the visual appearance of fields whose values have changed.
27774
27818
  * Called automatically during `flatten()`.
27775
27819
  */
27776
- async updateAppearances() {
27777
- await this._acroForm.updateAppearances();
27820
+ updateAppearances() {
27821
+ this._acroForm.updateAppearances();
27778
27822
  }
27779
27823
  /**
27780
27824
  * Flatten all form fields into static page content.
@@ -27795,8 +27839,8 @@ var PDFForm = class PDFForm {
27795
27839
  * const bytes = await pdf.save();
27796
27840
  * ```
27797
27841
  */
27798
- async flatten(options = {}) {
27799
- await this._acroForm.flatten(options);
27842
+ flatten(options = {}) {
27843
+ this._acroForm.flatten(options);
27800
27844
  this._ctx.catalog.removeAcroForm();
27801
27845
  this.allFields = [];
27802
27846
  this.fieldsByName.clear();
@@ -27820,39 +27864,49 @@ var PDFForm = class PDFForm {
27820
27864
  /**
27821
27865
  * Set a field's value with type checking.
27822
27866
  */
27823
- async setFieldValue(field, value) {
27824
- switch (field.type) {
27825
- case "text":
27826
- if (typeof value !== "string") throw new TypeError(`Text field "${field.name}" requires string value, got ${typeof value}`);
27827
- await field.setValue(value);
27828
- break;
27829
- case "checkbox":
27830
- if (typeof value === "boolean") if (value) await field.check();
27831
- else await field.uncheck();
27832
- else if (typeof value === "string") await field.setValue(value);
27833
- else throw new TypeError(`Checkbox "${field.name}" requires boolean or string value`);
27834
- break;
27835
- case "radio":
27836
- if (typeof value !== "string" && value !== null) throw new TypeError(`Radio field "${field.name}" requires string or null value`);
27837
- await field.setValue(value);
27838
- break;
27839
- case "dropdown":
27840
- if (typeof value !== "string") throw new TypeError(`Dropdown "${field.name}" requires string value`);
27841
- await field.setValue(value);
27842
- break;
27843
- case "listbox":
27844
- if (!Array.isArray(value)) throw new TypeError(`Listbox "${field.name}" requires string[] value`);
27845
- await field.setValue(value);
27846
- break;
27847
- case "signature":
27848
- case "button": throw new Error(`Cannot set value on ${field.type} field "${field.name}"`);
27849
- default: throw new Error(`Unknown field type for "${field.name}"`);
27867
+ setFieldValue(field, value) {
27868
+ if (field instanceof TextField) {
27869
+ if (typeof value !== "string") throw new TypeError(`Text field "${field.name}" requires string value, got ${typeof value}`);
27870
+ field.setValue(value);
27871
+ return;
27872
+ }
27873
+ if (field instanceof CheckboxField) {
27874
+ if (typeof value === "boolean") {
27875
+ if (value) field.check();
27876
+ else field.uncheck();
27877
+ return;
27878
+ }
27879
+ if (typeof value === "string") {
27880
+ field.setValue(value);
27881
+ return;
27882
+ }
27883
+ throw new TypeError(`Checkbox "${field.name}" requires boolean or string value`);
27884
+ }
27885
+ if (field instanceof RadioField) {
27886
+ if (typeof value !== "string" && value !== null) throw new TypeError(`Radio field "${field.name}" requires string or null value`);
27887
+ field.setValue(value);
27888
+ return;
27850
27889
  }
27890
+ if (field instanceof DropdownField) {
27891
+ if (typeof value !== "string") throw new TypeError(`Dropdown "${field.name}" requires string value`);
27892
+ field.setValue(value);
27893
+ return;
27894
+ }
27895
+ if (field instanceof ListBoxField) {
27896
+ if (!Array.isArray(value)) throw new TypeError(`Listbox "${field.name}" requires string[] value`);
27897
+ field.setValue(value);
27898
+ return;
27899
+ }
27900
+ if (field instanceof SignatureField || field instanceof ButtonField) throw new Error(`Cannot set value on ${field.type} field "${field.name}"`);
27901
+ throw new Error(`Unknown field type for "${field.name}"`);
27851
27902
  }
27852
27903
  };
27853
27904
 
27854
27905
  //#endregion
27855
27906
  //#region src/annotations/types.ts
27907
+ const isAnnotationSubtype = (subtype) => {
27908
+ return subtype === "Text" || subtype === "Link" || subtype === "FreeText" || subtype === "Line" || subtype === "Square" || subtype === "Circle" || subtype === "Polygon" || subtype === "PolyLine" || subtype === "Highlight" || subtype === "Underline" || subtype === "Squiggly" || subtype === "StrikeOut" || subtype === "Stamp" || subtype === "Caret" || subtype === "Ink" || subtype === "Popup" || subtype === "FileAttachment" || subtype === "Widget";
27909
+ };
27856
27910
  /**
27857
27911
  * Annotation flags (PDF spec Table 165).
27858
27912
  */
@@ -27879,6 +27933,15 @@ let AnnotationFlags = /* @__PURE__ */ function(AnnotationFlags$1) {
27879
27933
  AnnotationFlags$1[AnnotationFlags$1["LockedContents"] = 512] = "LockedContents";
27880
27934
  return AnnotationFlags$1;
27881
27935
  }({});
27936
+ const isTextAnnotationIcon = (icon) => {
27937
+ return icon === "Comment" || icon === "Key" || icon === "Note" || icon === "Help" || icon === "NewParagraph" || icon === "Paragraph" || icon === "Insert";
27938
+ };
27939
+ const isFileAttachmentIcon = (icon) => {
27940
+ return icon === "Graph" || icon === "Paperclip" || icon === "PushPin" || icon === "Tag";
27941
+ };
27942
+ const isDestinationType = (type) => {
27943
+ return type === "Fit" || type === "FitH" || type === "FitV" || type === "FitB" || type === "FitBH" || type === "FitBV" || type === "XYZ" || type === "FitR";
27944
+ };
27882
27945
 
27883
27946
  //#endregion
27884
27947
  //#region src/annotations/base.ts
@@ -27923,7 +27986,8 @@ var PDFAnnotation = class {
27923
27986
  * Annotation subtype (e.g., "Text", "Highlight", "Link").
27924
27987
  */
27925
27988
  get type() {
27926
- return this.dict.getName("Subtype")?.value ?? "Text";
27989
+ const subtype = this.dict.getName("Subtype")?.value;
27990
+ return isAnnotationSubtype(subtype) ? subtype : "Text";
27927
27991
  }
27928
27992
  /**
27929
27993
  * Annotation rectangle in page coordinates.
@@ -27936,15 +28000,12 @@ var PDFAnnotation = class {
27936
28000
  width: 0,
27937
28001
  height: 0
27938
28002
  };
27939
- const x1 = arr.at(0)?.value ?? 0;
27940
- const y1 = arr.at(1)?.value ?? 0;
27941
- const x2 = arr.at(2)?.value ?? 0;
27942
- const y2 = arr.at(3)?.value ?? 0;
28003
+ const [x1, y1, x2, y2] = arr.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
27943
28004
  return {
27944
- x: Math.min(x1, x2),
27945
- y: Math.min(y1, y2),
27946
- width: Math.abs(x2 - x1),
27947
- height: Math.abs(y2 - y1)
28005
+ x: Math.min(x1 ?? 0, x2 ?? 0),
28006
+ y: Math.min(y1 ?? 0, y2 ?? 0),
28007
+ width: Math.abs((x2 ?? 0) - (x1 ?? 0)),
28008
+ height: Math.abs((y2 ?? 0) - (y1 ?? 0))
27948
28009
  };
27949
28010
  }
27950
28011
  /**
@@ -28061,7 +28122,7 @@ var PDFAnnotation = class {
28061
28122
  */
28062
28123
  setColor(color) {
28063
28124
  const components = colorToArray(color);
28064
- this.dict.set("C", new PdfArray(components.map(PdfNumber.of)));
28125
+ this.dict.set("C", new PdfArray(components.map((n) => PdfNumber.of(n))));
28065
28126
  this.markModified();
28066
28127
  }
28067
28128
  /**
@@ -28091,7 +28152,7 @@ var PDFAnnotation = class {
28091
28152
  const bs = new PdfDict();
28092
28153
  bs.set("W", PdfNumber.of(style.width ?? 1));
28093
28154
  bs.set("S", PdfName.of(BORDER_STYLE_REVERSE_MAP[style.style ?? "solid"]));
28094
- if (style.dashArray && style.dashArray.length > 0) bs.set("D", new PdfArray(style.dashArray.map(PdfNumber.of)));
28155
+ if (style.dashArray && style.dashArray.length > 0) bs.set("D", new PdfArray(style.dashArray.map((n) => PdfNumber.of(n))));
28095
28156
  this.dict.set("BS", bs);
28096
28157
  this.markModified();
28097
28158
  }
@@ -28106,19 +28167,19 @@ var PDFAnnotation = class {
28106
28167
  /**
28107
28168
  * Get the normal appearance stream.
28108
28169
  */
28109
- async getNormalAppearance() {
28170
+ getNormalAppearance() {
28110
28171
  return this.getAppearance("N");
28111
28172
  }
28112
28173
  /**
28113
28174
  * Get the rollover appearance stream.
28114
28175
  */
28115
- async getRolloverAppearance() {
28176
+ getRolloverAppearance() {
28116
28177
  return this.getAppearance("R");
28117
28178
  }
28118
28179
  /**
28119
28180
  * Get the down appearance stream.
28120
28181
  */
28121
- async getDownAppearance() {
28182
+ getDownAppearance() {
28122
28183
  return this.getAppearance("D");
28123
28184
  }
28124
28185
  /**
@@ -28142,13 +28203,13 @@ var PDFAnnotation = class {
28142
28203
  /**
28143
28204
  * Get an appearance stream by type.
28144
28205
  */
28145
- async getAppearance(type) {
28206
+ getAppearance(type) {
28146
28207
  const ap = this.dict.getDict("AP");
28147
28208
  if (!ap) return null;
28148
- const entry = ap.get(type);
28209
+ let entry = ap.get(type);
28149
28210
  if (!entry) return null;
28150
- const resolved = entry.type === "ref" ? await this.registry.resolve(entry) : entry;
28151
- if (resolved instanceof PdfStream) return resolved;
28211
+ if (entry instanceof PdfRef) entry = this.registry.resolve(entry) ?? void 0;
28212
+ if (entry instanceof PdfStream) return entry;
28152
28213
  return null;
28153
28214
  }
28154
28215
  /**
@@ -28326,15 +28387,15 @@ var PDFMarkupAnnotation = class extends PDFAnnotation {
28326
28387
  /**
28327
28388
  * Get the associated popup annotation, if any.
28328
28389
  */
28329
- async getPopup() {
28390
+ getPopup() {
28330
28391
  if (this._popup !== void 0) return this._popup;
28331
28392
  const popupRef = this.popupRef;
28332
28393
  if (!popupRef) {
28333
28394
  this._popup = null;
28334
28395
  return null;
28335
28396
  }
28336
- const popupDict = await this.registry.resolve(popupRef);
28337
- if (popupDict && popupDict.type === "dict") {
28397
+ const popupDict = this.registry.resolve(popupRef);
28398
+ if (popupDict instanceof PdfDict) {
28338
28399
  this._popup = new PDFPopupAnnotation(popupDict, popupRef, this.registry);
28339
28400
  return this._popup;
28340
28401
  }
@@ -28419,12 +28480,7 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
28419
28480
  get icon() {
28420
28481
  const name = this.dict.getName("Name");
28421
28482
  if (!name) return "PushPin";
28422
- if ([
28423
- "Graph",
28424
- "Paperclip",
28425
- "PushPin",
28426
- "Tag"
28427
- ].includes(name.value)) return name.value;
28483
+ if (isFileAttachmentIcon(name.value)) return name.value;
28428
28484
  return "PushPin";
28429
28485
  }
28430
28486
  /**
@@ -28444,18 +28500,18 @@ var PDFFileAttachmentAnnotation = class extends PDFMarkupAnnotation {
28444
28500
  /**
28445
28501
  * Get the file specification dictionary.
28446
28502
  */
28447
- async getFileSpec() {
28503
+ getFileSpec() {
28448
28504
  const fsRef = this.fileSpecRef;
28449
28505
  if (!fsRef) return this.dict.getDict("FS") ?? null;
28450
- const resolved = await this.registry.resolve(fsRef);
28506
+ const resolved = this.registry.resolve(fsRef);
28451
28507
  if (resolved && resolved.type === "dict") return resolved;
28452
28508
  return null;
28453
28509
  }
28454
28510
  /**
28455
28511
  * Get the file name from the file specification.
28456
28512
  */
28457
- async getFileName() {
28458
- const fs = await this.getFileSpec();
28513
+ getFileName() {
28514
+ const fs = this.getFileSpec();
28459
28515
  if (!fs) return null;
28460
28516
  const uf = fs.getString("UF");
28461
28517
  if (uf) return uf.asString();
@@ -28592,7 +28648,7 @@ var PDFInkAnnotation = class extends PDFMarkupAnnotation {
28592
28648
  PdfNumber.of(maxY)
28593
28649
  ]),
28594
28650
  InkList: inkList,
28595
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
28651
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
28596
28652
  F: PdfNumber.of(4)
28597
28653
  });
28598
28654
  if (options.width !== void 0) {
@@ -28614,7 +28670,7 @@ var PDFInkAnnotation = class extends PDFMarkupAnnotation {
28614
28670
  const paths = [];
28615
28671
  for (let i = 0; i < inkList.length; i++) {
28616
28672
  const pathEntry = inkList.at(i);
28617
- if (pathEntry && pathEntry.type === "array") {
28673
+ if (pathEntry && pathEntry instanceof PdfArray) {
28618
28674
  const pathArr = pathEntry;
28619
28675
  const points = [];
28620
28676
  for (let j = 0; j < pathArr.length; j += 2) {
@@ -28693,7 +28749,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
28693
28749
  PdfNumber.of(end.x),
28694
28750
  PdfNumber.of(end.y)
28695
28751
  ]),
28696
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
28752
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
28697
28753
  F: PdfNumber.of(4)
28698
28754
  });
28699
28755
  if (options.width !== void 0) {
@@ -28705,7 +28761,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
28705
28761
  if (options.startStyle || options.endStyle) annotDict.set("LE", new PdfArray([PdfName.of(options.startStyle ?? "None"), PdfName.of(options.endStyle ?? "None")]));
28706
28762
  if (options.interiorColor) {
28707
28763
  const icComponents = colorToArray(options.interiorColor);
28708
- annotDict.set("IC", new PdfArray(icComponents.map(PdfNumber.of)));
28764
+ annotDict.set("IC", new PdfArray(icComponents.map((n) => PdfNumber.of(n))));
28709
28765
  }
28710
28766
  if (options.contents) annotDict.set("Contents", PdfString.fromString(options.contents));
28711
28767
  return annotDict;
@@ -28725,14 +28781,15 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
28725
28781
  y: 0
28726
28782
  }
28727
28783
  };
28784
+ const [x1, y1, x2, y2] = l.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
28728
28785
  return {
28729
28786
  start: {
28730
- x: l.at(0)?.value ?? 0,
28731
- y: l.at(1)?.value ?? 0
28787
+ x: x1 ?? 0,
28788
+ y: y1 ?? 0
28732
28789
  },
28733
28790
  end: {
28734
- x: l.at(2)?.value ?? 0,
28735
- y: l.at(3)?.value ?? 0
28791
+ x: x2 ?? 0,
28792
+ y: y2 ?? 0
28736
28793
  }
28737
28794
  };
28738
28795
  }
@@ -28772,7 +28829,8 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
28772
28829
  get lineEndingStyles() {
28773
28830
  const le = this.dict.getArray("LE");
28774
28831
  if (!le || le.length < 2) return ["None", "None"];
28775
- return [le.at(0)?.value ?? "None", le.at(1)?.value ?? "None"];
28832
+ const [startStyle, endStyle] = le.toArray().map((item) => item instanceof PdfName ? item.value : "None");
28833
+ return [startStyle ?? "None", endStyle ?? "None"];
28776
28834
  }
28777
28835
  /**
28778
28836
  * Set the line ending styles.
@@ -28792,7 +28850,7 @@ var PDFLineAnnotation = class extends PDFMarkupAnnotation {
28792
28850
  */
28793
28851
  setInteriorColor(color) {
28794
28852
  const components = colorToArray(color);
28795
- this.dict.set("IC", new PdfArray(components.map(PdfNumber.of)));
28853
+ this.dict.set("IC", new PdfArray(components.map((n) => PdfNumber.of(n))));
28796
28854
  this.markModified();
28797
28855
  }
28798
28856
  /**
@@ -28862,7 +28920,7 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
28862
28920
  }
28863
28921
  if (options.borderColor) {
28864
28922
  const components = colorToArray(options.borderColor);
28865
- annotDict.set("C", new PdfArray(components.map(PdfNumber.of)));
28923
+ annotDict.set("C", new PdfArray(components.map((n) => PdfNumber.of(n))));
28866
28924
  }
28867
28925
  if (options.uri) {
28868
28926
  const action = PdfDict.of({
@@ -28917,7 +28975,7 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
28917
28975
  /**
28918
28976
  * Get the parsed link action.
28919
28977
  */
28920
- async getAction() {
28978
+ getAction() {
28921
28979
  const uri = this.uri;
28922
28980
  if (uri) return {
28923
28981
  type: "uri",
@@ -28960,8 +29018,8 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
28960
29018
  * Parse a destination value.
28961
29019
  */
28962
29020
  parseDestination(dest) {
28963
- if (Array.isArray(dest) || dest && dest.type === "array") {
28964
- const arr = dest;
29021
+ if (Array.isArray(dest) || dest instanceof PdfArray) {
29022
+ const arr = dest instanceof PdfArray ? dest : new PdfArray(dest);
28965
29023
  if (arr.length < 2) return null;
28966
29024
  const pageEntry = arr.at(0);
28967
29025
  let pageNum = 0;
@@ -28972,7 +29030,7 @@ var PDFLinkAnnotation = class extends PDFAnnotation {
28972
29030
  const typeName = typeEntry instanceof PdfName ? typeEntry.value : "Fit";
28973
29031
  const result = {
28974
29032
  page: pageRef ?? pageNum,
28975
- type: typeName
29033
+ type: isDestinationType(typeName) ? typeName : "Fit"
28976
29034
  };
28977
29035
  switch (typeName) {
28978
29036
  case "XYZ": {
@@ -29082,7 +29140,7 @@ var PDFPolygonAnnotation = class extends PDFPolyAnnotation {
29082
29140
  */
29083
29141
  setInteriorColor(color) {
29084
29142
  const components = colorToArray(color);
29085
- this.dict.set("IC", new PdfArray(components.map(PdfNumber.of)));
29143
+ this.dict.set("IC", new PdfArray(components.map((n) => PdfNumber.of(n))));
29086
29144
  this.markModified();
29087
29145
  }
29088
29146
  /**
@@ -29103,7 +29161,8 @@ var PDFPolylineAnnotation = class extends PDFPolyAnnotation {
29103
29161
  get lineEndingStyles() {
29104
29162
  const le = this.dict.getArray("LE");
29105
29163
  if (!le || le.length < 2) return ["None", "None"];
29106
- return [le.at(0)?.value ?? "None", le.at(1)?.value ?? "None"];
29164
+ const [startStyle, endStyle] = le.toArray().map((item) => item instanceof PdfName ? item.value : "None");
29165
+ return [startStyle ?? "None", endStyle ?? "None"];
29107
29166
  }
29108
29167
  /**
29109
29168
  * Set the line ending styles.
@@ -29146,7 +29205,7 @@ var PDFShapeAnnotation = class extends PDFMarkupAnnotation {
29146
29205
  */
29147
29206
  setInteriorColor(color) {
29148
29207
  const components = colorToArray(color);
29149
- this.dict.set("IC", new PdfArray(components.map(PdfNumber.of)));
29208
+ this.dict.set("IC", new PdfArray(components.map((n) => PdfNumber.of(n))));
29150
29209
  this.markModified();
29151
29210
  }
29152
29211
  /**
@@ -29156,11 +29215,12 @@ var PDFShapeAnnotation = class extends PDFMarkupAnnotation {
29156
29215
  get rectDifference() {
29157
29216
  const rd = this.dict.getArray("RD");
29158
29217
  if (!rd || rd.length < 4) return null;
29218
+ const [x1, y1, x2, y2] = rd.toArray().map((item) => item instanceof PdfNumber ? item.value : 0);
29159
29219
  return [
29160
- rd.at(0)?.value ?? 0,
29161
- rd.at(1)?.value ?? 0,
29162
- rd.at(2)?.value ?? 0,
29163
- rd.at(3)?.value ?? 0
29220
+ x1 ?? 0,
29221
+ y1 ?? 0,
29222
+ x2 ?? 0,
29223
+ y2 ?? 0
29164
29224
  ];
29165
29225
  }
29166
29226
  /**
@@ -29198,7 +29258,7 @@ var PDFSquareAnnotation = class extends PDFShapeAnnotation {
29198
29258
  Type: PdfName.of("Annot"),
29199
29259
  Subtype: PdfName.of("Square"),
29200
29260
  Rect: new PdfArray(rectToArray(rect)),
29201
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
29261
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
29202
29262
  F: PdfNumber.of(4)
29203
29263
  });
29204
29264
  if (options.borderWidth !== void 0) {
@@ -29209,7 +29269,7 @@ var PDFSquareAnnotation = class extends PDFShapeAnnotation {
29209
29269
  }
29210
29270
  if (options.fillColor) {
29211
29271
  const icComponents = colorToArray(options.fillColor);
29212
- annotDict.set("IC", new PdfArray(icComponents.map(PdfNumber.of)));
29272
+ annotDict.set("IC", new PdfArray(icComponents.map((n) => PdfNumber.of(n))));
29213
29273
  }
29214
29274
  if (options.contents) annotDict.set("Contents", PdfString.fromString(options.contents));
29215
29275
  return annotDict;
@@ -29229,7 +29289,7 @@ var PDFCircleAnnotation = class extends PDFShapeAnnotation {
29229
29289
  Type: PdfName.of("Annot"),
29230
29290
  Subtype: PdfName.of("Circle"),
29231
29291
  Rect: new PdfArray(rectToArray(rect)),
29232
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
29292
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
29233
29293
  F: PdfNumber.of(4)
29234
29294
  });
29235
29295
  if (options.borderWidth !== void 0) {
@@ -29240,7 +29300,7 @@ var PDFCircleAnnotation = class extends PDFShapeAnnotation {
29240
29300
  }
29241
29301
  if (options.fillColor) {
29242
29302
  const icComponents = colorToArray(options.fillColor);
29243
- annotDict.set("IC", new PdfArray(icComponents.map(PdfNumber.of)));
29303
+ annotDict.set("IC", new PdfArray(icComponents.map((n) => PdfNumber.of(n))));
29244
29304
  }
29245
29305
  if (options.contents) annotDict.set("Contents", PdfString.fromString(options.contents));
29246
29306
  return annotDict;
@@ -29326,6 +29386,12 @@ var PDFStampAnnotation = class extends PDFMarkupAnnotation {
29326
29386
  *
29327
29387
  * PDF Reference: Section 12.5.6.4 "Text Annotations"
29328
29388
  */
29389
+ const isTextAnnotationState = (state) => {
29390
+ return state === "Marked" || state === "Unmarked" || state === "Accepted" || state === "Rejected" || state === "Cancelled" || state === "Completed" || state === "None";
29391
+ };
29392
+ const isTextAnnotationStateModel = (model) => {
29393
+ return model === "Marked" || model === "Review";
29394
+ };
29329
29395
  /**
29330
29396
  * Text annotation - sticky note/comment.
29331
29397
  */
@@ -29340,7 +29406,7 @@ var PDFTextAnnotation = class extends PDFMarkupAnnotation {
29340
29406
  Type: PdfName.of("Annot"),
29341
29407
  Subtype: PdfName.of("Text"),
29342
29408
  Rect: new PdfArray(rectToArray(rect)),
29343
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
29409
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
29344
29410
  F: PdfNumber.of(4)
29345
29411
  });
29346
29412
  if (options.contents) annotDict.set("Contents", PdfString.fromString(options.contents));
@@ -29368,15 +29434,7 @@ var PDFTextAnnotation = class extends PDFMarkupAnnotation {
29368
29434
  get icon() {
29369
29435
  const name = this.dict.getName("Name");
29370
29436
  if (!name) return "Note";
29371
- if ([
29372
- "Comment",
29373
- "Key",
29374
- "Note",
29375
- "Help",
29376
- "NewParagraph",
29377
- "Paragraph",
29378
- "Insert"
29379
- ].includes(name.value)) return name.value;
29437
+ if (isTextAnnotationIcon(name.value)) return name.value;
29380
29438
  return "Note";
29381
29439
  }
29382
29440
  /**
@@ -29390,7 +29448,8 @@ var PDFTextAnnotation = class extends PDFMarkupAnnotation {
29390
29448
  * State of the annotation (for review workflows).
29391
29449
  */
29392
29450
  get state() {
29393
- return this.dict.getName("State")?.value ?? null;
29451
+ const state = this.dict.getName("State")?.value;
29452
+ return isTextAnnotationState(state) ? state : null;
29394
29453
  }
29395
29454
  /**
29396
29455
  * Set the annotation state.
@@ -29403,7 +29462,8 @@ var PDFTextAnnotation = class extends PDFMarkupAnnotation {
29403
29462
  * State model for the annotation.
29404
29463
  */
29405
29464
  get stateModel() {
29406
- return this.dict.getName("StateModel")?.value ?? null;
29465
+ const model = this.dict.getName("StateModel")?.value;
29466
+ return isTextAnnotationStateModel(model) ? model : null;
29407
29467
  }
29408
29468
  /**
29409
29469
  * Set the state model.
@@ -29585,7 +29645,7 @@ function createTextMarkupDict(subtype, options) {
29585
29645
  PdfNumber.of(maxY)
29586
29646
  ]),
29587
29647
  QuadPoints: new PdfArray(flatQuadPoints),
29588
- C: new PdfArray(colorComponents.map(PdfNumber.of)),
29648
+ C: new PdfArray(colorComponents.map((n) => PdfNumber.of(n))),
29589
29649
  F: PdfNumber.of(4)
29590
29650
  });
29591
29651
  if (options.opacity !== void 0) annotDict.set("CA", PdfNumber.of(options.opacity));
@@ -29632,7 +29692,8 @@ var PDFUnknownAnnotation = class extends PDFAnnotation {};
29632
29692
  * @returns The appropriate annotation class instance
29633
29693
  */
29634
29694
  function createAnnotation(dict, ref, registry) {
29635
- switch (dict.getName("Subtype")?.value) {
29695
+ const subtypeName = dict.getName("Subtype")?.value;
29696
+ switch (isAnnotationSubtype(subtypeName) ? subtypeName : "Text") {
29636
29697
  case "Text": return new PDFTextAnnotation(dict, ref, registry);
29637
29698
  case "Link": return new PDFLinkAnnotation(dict, ref, registry);
29638
29699
  case "FreeText": return new PDFFreeTextAnnotation(dict, ref, registry);
@@ -29688,6 +29749,9 @@ function isPopupAnnotation(dict) {
29688
29749
  * /CIDToGIDMap /Identity
29689
29750
  * >>
29690
29751
  */
29752
+ const isCIDFontSubtype = (subtype) => {
29753
+ return subtype === "CIDFontType0" || subtype === "CIDFontType2";
29754
+ };
29691
29755
  /**
29692
29756
  * CIDFont handles CID-keyed fonts (descendants of Type0).
29693
29757
  */
@@ -29841,7 +29905,8 @@ function parseCIDWidths(wArray) {
29841
29905
  * Parse a CIDFont from a PDF font dictionary.
29842
29906
  */
29843
29907
  function parseCIDFont(dict, options = {}) {
29844
- const subtype = dict.getName("Subtype")?.value ?? "CIDFontType2";
29908
+ const subtypeName = dict.getName("Subtype");
29909
+ const subtype = isCIDFontSubtype(subtypeName?.value) ? subtypeName.value : "CIDFontType2";
29845
29910
  const baseFontName = dict.getName("BaseFont")?.value ?? "Unknown";
29846
29911
  let cidSystemInfo = {
29847
29912
  registry: "Adobe",
@@ -31812,7 +31877,7 @@ var TextExtractor = class {
31812
31877
  * Process a single content stream operation.
31813
31878
  */
31814
31879
  processOperation(op) {
31815
- if (op.operator === "BI") return;
31880
+ if (isInlineImageOperation(op)) return;
31816
31881
  const { operator, operands } = op;
31817
31882
  switch (operator) {
31818
31883
  case "q":
@@ -32981,11 +33046,11 @@ var PDFPage = class PDFPage {
32981
33046
  * await page.drawField(paymentRadio, { x: 100, y: 520, width: 16, height: 16, option: "PayPal" });
32982
33047
  * ```
32983
33048
  */
32984
- async drawField(field, options) {
33049
+ drawField(field, options) {
32985
33050
  if (!this.ctx) throw new Error("Cannot draw field on page without context");
32986
33051
  if (!(field instanceof TerminalField)) throw new Error(`Cannot draw non-terminal field "${field.name}"`);
32987
- if (field.type === "signature") throw new Error("Signature fields cannot be drawn with drawField. Use form.createSignatureField() which creates the widget automatically.");
32988
- if (field.type === "radio") {
33052
+ if (field instanceof SignatureField) throw new Error("Signature fields cannot be drawn with drawField. Use form.createSignatureField() which creates the widget automatically.");
33053
+ if (field instanceof RadioField) {
32989
33054
  if (!options.option) throw new Error(`Radio group "${field.name}" requires option parameter in drawField`);
32990
33055
  const availableOptions = field.getOptions();
32991
33056
  const optArray = field.acroField().getArray("Opt");
@@ -32993,7 +33058,7 @@ var PDFPage = class PDFPage {
32993
33058
  const optValues = [];
32994
33059
  for (let i = 0; i < optArray.length; i++) {
32995
33060
  const item = optArray.at(i);
32996
- if (item?.type === "string") optValues.push(item.asString());
33061
+ if (item instanceof PdfString) optValues.push(item.asString());
32997
33062
  }
32998
33063
  if (!optValues.includes(options.option)) throw new Error(`Invalid option "${options.option}" for radio group "${field.name}". Available: ${optValues.join(", ")}`);
32999
33064
  } else if (availableOptions.length > 0 && !availableOptions.includes(options.option)) throw new Error(`Invalid option "${options.option}" for radio group "${field.name}". Available: ${availableOptions.join(", ")}`);
@@ -33002,7 +33067,7 @@ var PDFPage = class PDFPage {
33002
33067
  const widget = field.addWidget(widgetDict);
33003
33068
  if (!widget.ref) throw new Error("Widget annotation must have a reference");
33004
33069
  this.addAnnotationRef(widget.ref);
33005
- await this.generateWidgetAppearance(field, widget, options);
33070
+ this.generateWidgetAppearance(field, widget, options);
33006
33071
  }
33007
33072
  /**
33008
33073
  * Build a widget annotation dictionary for a field.
@@ -33051,11 +33116,11 @@ var PDFPage = class PDFPage {
33051
33116
  });
33052
33117
  widgetDict.set("BS", bs);
33053
33118
  }
33054
- if (field.type === "radio" && options.option) {
33119
+ if (field instanceof RadioField && options.option) {
33055
33120
  const currentValue = field.getValue();
33056
33121
  widgetDict.set("AS", PdfName.of(currentValue === options.option ? options.option : "Off"));
33057
33122
  }
33058
- if (field.type === "checkbox") {
33123
+ if (field instanceof CheckboxField) {
33059
33124
  const checkboxField = field;
33060
33125
  const isChecked = checkboxField.isChecked();
33061
33126
  const onValue = checkboxField.getOnValue();
@@ -33066,47 +33131,45 @@ var PDFPage = class PDFPage {
33066
33131
  /**
33067
33132
  * Generate appearance stream for a widget.
33068
33133
  */
33069
- async generateWidgetAppearance(field, widget, options) {
33134
+ generateWidgetAppearance(field, widget, options) {
33070
33135
  if (!this.ctx) return;
33071
33136
  const catalogDict = this.ctx.catalog.getDict();
33072
- const acroForm = await AcroForm.load(catalogDict, this.ctx.registry);
33137
+ const acroForm = AcroForm.load(catalogDict, this.ctx.registry);
33073
33138
  if (!acroForm) return;
33074
33139
  const generator = new AppearanceGenerator(acroForm, this.ctx.registry);
33075
- switch (field.type) {
33076
- case "text": {
33077
- const textField = field;
33078
- const stream = generator.generateTextAppearance(textField, widget);
33079
- widget.setNormalAppearance(stream);
33080
- break;
33081
- }
33082
- case "checkbox": {
33083
- const checkboxField = field;
33084
- const onValue = checkboxField.getOnValue();
33085
- const { on, off } = generator.generateCheckboxAppearance(checkboxField, widget, onValue);
33086
- widget.setNormalAppearance(on, onValue);
33087
- widget.setNormalAppearance(off, "Off");
33088
- break;
33089
- }
33090
- case "radio": {
33091
- const radioField = field;
33092
- if (!options.option) throw new Error("Radio field requires an option value");
33093
- const { selected, off } = generator.generateRadioAppearance(radioField, widget, options.option);
33094
- widget.setNormalAppearance(selected, options.option);
33095
- widget.setNormalAppearance(off, "Off");
33096
- break;
33097
- }
33098
- case "dropdown": {
33099
- const dropdownField = field;
33100
- const stream = generator.generateDropdownAppearance(dropdownField, widget);
33101
- widget.setNormalAppearance(stream);
33102
- break;
33103
- }
33104
- case "listbox": {
33105
- const listboxField = field;
33106
- const stream = generator.generateListBoxAppearance(listboxField, widget);
33107
- widget.setNormalAppearance(stream);
33108
- break;
33109
- }
33140
+ if (field instanceof TextField) {
33141
+ const textField = field;
33142
+ const stream = generator.generateTextAppearance(textField, widget);
33143
+ widget.setNormalAppearance(stream);
33144
+ return;
33145
+ }
33146
+ if (field instanceof CheckboxField) {
33147
+ const checkboxField = field;
33148
+ const onValue = checkboxField.getOnValue();
33149
+ const { on, off } = generator.generateCheckboxAppearance(checkboxField, widget, onValue);
33150
+ widget.setNormalAppearance(on, onValue);
33151
+ widget.setNormalAppearance(off, "Off");
33152
+ return;
33153
+ }
33154
+ if (field instanceof RadioField) {
33155
+ const radioField = field;
33156
+ if (!options.option) throw new Error("Radio field requires an option value");
33157
+ const { selected, off } = generator.generateRadioAppearance(radioField, widget, options.option);
33158
+ widget.setNormalAppearance(selected, options.option);
33159
+ widget.setNormalAppearance(off, "Off");
33160
+ return;
33161
+ }
33162
+ if (field instanceof DropdownField) {
33163
+ const dropdownField = field;
33164
+ const stream = generator.generateDropdownAppearance(dropdownField, widget);
33165
+ widget.setNormalAppearance(stream);
33166
+ return;
33167
+ }
33168
+ if (field instanceof ListBoxField) {
33169
+ const listboxField = field;
33170
+ const stream = generator.generateListBoxAppearance(listboxField, widget);
33171
+ widget.setNormalAppearance(stream);
33172
+ return;
33110
33173
  }
33111
33174
  }
33112
33175
  /**
@@ -33467,13 +33530,13 @@ var PDFPage = class PDFPage {
33467
33530
  *
33468
33531
  * @example
33469
33532
  * ```typescript
33470
- * const annotations = await page.getAnnotations();
33533
+ * const annotations = page.getAnnotations();
33471
33534
  * for (const annot of annotations) {
33472
33535
  * console.log(annot.type, annot.contents);
33473
33536
  * }
33474
33537
  * ```
33475
33538
  */
33476
- async getAnnotations() {
33539
+ getAnnotations() {
33477
33540
  if (this._annotationCache) return this._annotationCache;
33478
33541
  const annotations = [];
33479
33542
  const annotsArray = this.dict.getArray("Annots");
@@ -33488,7 +33551,7 @@ var PDFPage = class PDFPage {
33488
33551
  let annotRef = null;
33489
33552
  if (entry instanceof PdfRef) {
33490
33553
  annotRef = entry;
33491
- const resolved = await this.ctx.resolve(entry);
33554
+ const resolved = this.ctx.resolve(entry);
33492
33555
  if (resolved instanceof PdfDict) annotDict = resolved;
33493
33556
  } else if (entry instanceof PdfDict) annotDict = entry;
33494
33557
  if (!annotDict) continue;
@@ -33505,20 +33568,20 @@ var PDFPage = class PDFPage {
33505
33568
  * Popups are typically accessed via their parent markup annotation
33506
33569
  * using `annotation.getPopup()`, but this method allows direct access.
33507
33570
  */
33508
- async getPopupAnnotations() {
33571
+ getPopupAnnotations() {
33509
33572
  const popups = [];
33510
33573
  const annotsArray = this.dict.getArray("Annots");
33511
33574
  if (!annotsArray || !this.ctx) return popups;
33512
33575
  for (let i = 0; i < annotsArray.length; i++) {
33513
- const entry = annotsArray.at(i);
33576
+ let entry = annotsArray.at(i);
33514
33577
  if (!entry) continue;
33515
33578
  let annotDict = null;
33516
33579
  let annotRef = null;
33517
33580
  if (entry instanceof PdfRef) {
33518
33581
  annotRef = entry;
33519
- const resolved = await this.ctx.resolve(entry);
33520
- if (resolved instanceof PdfDict) annotDict = resolved;
33521
- } else if (entry instanceof PdfDict) annotDict = entry;
33582
+ entry = this.ctx.resolve(entry) ?? void 0;
33583
+ }
33584
+ if (entry instanceof PdfDict) annotDict = entry;
33522
33585
  if (!annotDict || !isPopupAnnotation(annotDict)) continue;
33523
33586
  popups.push(new PDFPopupAnnotation(annotDict, annotRef, this.ctx.registry));
33524
33587
  }
@@ -33527,98 +33590,98 @@ var PDFPage = class PDFPage {
33527
33590
  /**
33528
33591
  * Get all highlight annotations on this page.
33529
33592
  */
33530
- async getHighlightAnnotations() {
33531
- return (await this.getAnnotations()).filter((a) => a.type === "Highlight");
33593
+ getHighlightAnnotations() {
33594
+ return this.getAnnotations().filter((a) => a.type === "Highlight");
33532
33595
  }
33533
33596
  /**
33534
33597
  * Get all underline annotations on this page.
33535
33598
  */
33536
- async getUnderlineAnnotations() {
33537
- return (await this.getAnnotations()).filter((a) => a.type === "Underline");
33599
+ getUnderlineAnnotations() {
33600
+ return this.getAnnotations().filter((a) => a.type === "Underline");
33538
33601
  }
33539
33602
  /**
33540
33603
  * Get all strikeout annotations on this page.
33541
33604
  */
33542
- async getStrikeOutAnnotations() {
33543
- return (await this.getAnnotations()).filter((a) => a.type === "StrikeOut");
33605
+ getStrikeOutAnnotations() {
33606
+ return this.getAnnotations().filter((a) => a.type === "StrikeOut");
33544
33607
  }
33545
33608
  /**
33546
33609
  * Get all squiggly annotations on this page.
33547
33610
  */
33548
- async getSquigglyAnnotations() {
33549
- return (await this.getAnnotations()).filter((a) => a.type === "Squiggly");
33611
+ getSquigglyAnnotations() {
33612
+ return this.getAnnotations().filter((a) => a.type === "Squiggly");
33550
33613
  }
33551
33614
  /**
33552
33615
  * Get all link annotations on this page.
33553
33616
  */
33554
- async getLinkAnnotations() {
33555
- return (await this.getAnnotations()).filter((a) => a.type === "Link");
33617
+ getLinkAnnotations() {
33618
+ return this.getAnnotations().filter((a) => a.type === "Link");
33556
33619
  }
33557
33620
  /**
33558
33621
  * Get all text annotations (sticky notes) on this page.
33559
33622
  */
33560
- async getTextAnnotations() {
33561
- return (await this.getAnnotations()).filter((a) => a.type === "Text");
33623
+ getTextAnnotations() {
33624
+ return this.getAnnotations().filter((a) => a.type === "Text");
33562
33625
  }
33563
33626
  /**
33564
33627
  * Get all free text annotations on this page.
33565
33628
  */
33566
- async getFreeTextAnnotations() {
33567
- return (await this.getAnnotations()).filter((a) => a.type === "FreeText");
33629
+ getFreeTextAnnotations() {
33630
+ return this.getAnnotations().filter((a) => a.type === "FreeText");
33568
33631
  }
33569
33632
  /**
33570
33633
  * Get all line annotations on this page.
33571
33634
  */
33572
- async getLineAnnotations() {
33573
- return (await this.getAnnotations()).filter((a) => a.type === "Line");
33635
+ getLineAnnotations() {
33636
+ return this.getAnnotations().filter((a) => a.type === "Line");
33574
33637
  }
33575
33638
  /**
33576
33639
  * Get all square annotations on this page.
33577
33640
  */
33578
- async getSquareAnnotations() {
33579
- return (await this.getAnnotations()).filter((a) => a.type === "Square");
33641
+ getSquareAnnotations() {
33642
+ return this.getAnnotations().filter((a) => a.type === "Square");
33580
33643
  }
33581
33644
  /**
33582
33645
  * Get all circle annotations on this page.
33583
33646
  */
33584
- async getCircleAnnotations() {
33585
- return (await this.getAnnotations()).filter((a) => a.type === "Circle");
33647
+ getCircleAnnotations() {
33648
+ return this.getAnnotations().filter((a) => a.type === "Circle");
33586
33649
  }
33587
33650
  /**
33588
33651
  * Get all stamp annotations on this page.
33589
33652
  */
33590
- async getStampAnnotations() {
33591
- return (await this.getAnnotations()).filter((a) => a.type === "Stamp");
33653
+ getStampAnnotations() {
33654
+ return this.getAnnotations().filter((a) => a.type === "Stamp");
33592
33655
  }
33593
33656
  /**
33594
33657
  * Get all ink annotations on this page.
33595
33658
  */
33596
- async getInkAnnotations() {
33597
- return (await this.getAnnotations()).filter((a) => a.type === "Ink");
33659
+ getInkAnnotations() {
33660
+ return this.getAnnotations().filter((a) => a.type === "Ink");
33598
33661
  }
33599
33662
  /**
33600
33663
  * Get all polygon annotations on this page.
33601
33664
  */
33602
- async getPolygonAnnotations() {
33603
- return (await this.getAnnotations()).filter((a) => a.type === "Polygon");
33665
+ getPolygonAnnotations() {
33666
+ return this.getAnnotations().filter((a) => a.type === "Polygon");
33604
33667
  }
33605
33668
  /**
33606
33669
  * Get all polyline annotations on this page.
33607
33670
  */
33608
- async getPolylineAnnotations() {
33609
- return (await this.getAnnotations()).filter((a) => a.type === "PolyLine");
33671
+ getPolylineAnnotations() {
33672
+ return this.getAnnotations().filter((a) => a.type === "PolyLine");
33610
33673
  }
33611
33674
  /**
33612
33675
  * Get all caret annotations on this page.
33613
33676
  */
33614
- async getCaretAnnotations() {
33615
- return (await this.getAnnotations()).filter((a) => a.type === "Caret");
33677
+ getCaretAnnotations() {
33678
+ return this.getAnnotations().filter((a) => a.type === "Caret");
33616
33679
  }
33617
33680
  /**
33618
33681
  * Get all file attachment annotations on this page.
33619
33682
  */
33620
- async getFileAttachmentAnnotations() {
33621
- return (await this.getAnnotations()).filter((a) => a.type === "FileAttachment");
33683
+ getFileAttachmentAnnotations() {
33684
+ return this.getAnnotations().filter((a) => a.type === "FileAttachment");
33622
33685
  }
33623
33686
  /**
33624
33687
  * Add a highlight annotation.
@@ -33818,11 +33881,11 @@ var PDFPage = class PDFPage {
33818
33881
  *
33819
33882
  * @example
33820
33883
  * ```typescript
33821
- * const highlights = await page.getHighlightAnnotations();
33822
- * await page.removeAnnotation(highlights[0]);
33884
+ * const highlights = page.getHighlightAnnotations();
33885
+ * page.removeAnnotation(highlights[0]);
33823
33886
  * ```
33824
33887
  */
33825
- async removeAnnotation(annotation) {
33888
+ removeAnnotation(annotation) {
33826
33889
  if (!this.ctx) return;
33827
33890
  const annots = this.dict.getArray("Annots");
33828
33891
  if (!annots) return;
@@ -33851,17 +33914,17 @@ var PDFPage = class PDFPage {
33851
33914
  * @example
33852
33915
  * ```typescript
33853
33916
  * // Remove all highlights
33854
- * await page.removeAnnotations({ type: "Highlight" });
33917
+ * page.removeAnnotations({ type: "Highlight" });
33855
33918
  *
33856
33919
  * // Remove all annotations
33857
- * await page.removeAnnotations();
33920
+ * page.removeAnnotations();
33858
33921
  * ```
33859
33922
  */
33860
- async removeAnnotations(options) {
33861
- const annotations = await this.getAnnotations();
33923
+ removeAnnotations(options) {
33924
+ const annotations = this.getAnnotations();
33862
33925
  let toRemove = annotations;
33863
33926
  if (options?.type) toRemove = annotations.filter((a) => a.type === options.type);
33864
- for (const annotation of toRemove) await this.removeAnnotation(annotation);
33927
+ for (const annotation of toRemove) this.removeAnnotation(annotation);
33865
33928
  }
33866
33929
  /**
33867
33930
  * Add an annotation reference to the page's /Annots array.
@@ -34007,7 +34070,7 @@ var PDFPage = class PDFPage {
34007
34070
  } else {
34008
34071
  const contents = this.dict.get("Contents");
34009
34072
  if (contents instanceof PdfArray) contents.push(newContent);
34010
- else this.dict.set("Contents", new PdfArray([contents, newContent]));
34073
+ else if (contents !== void 0) this.dict.set("Contents", new PdfArray([contents, newContent]));
34011
34074
  }
34012
34075
  }
34013
34076
  /**
@@ -34106,7 +34169,7 @@ var PDFPage = class PDFPage {
34106
34169
  *
34107
34170
  * @example
34108
34171
  * ```typescript
34109
- * const pageText = await page.extractText();
34172
+ * const pageText = page.extractText();
34110
34173
  * console.log(pageText.text); // Plain text
34111
34174
  *
34112
34175
  * // Access structured content
@@ -34115,9 +34178,9 @@ var PDFPage = class PDFPage {
34115
34178
  * }
34116
34179
  * ```
34117
34180
  */
34118
- async extractText(_options = {}) {
34119
- const contentBytes = await this.getContentBytes();
34120
- const lines = groupCharsIntoLines(new TextExtractor({ resolveFont: await this.createFontResolver() }).extract(contentBytes));
34181
+ extractText(_options = {}) {
34182
+ const contentBytes = this.getContentBytes();
34183
+ const lines = groupCharsIntoLines(new TextExtractor({ resolveFont: this.createFontResolver() }).extract(contentBytes));
34121
34184
  const text = getPlainText(lines);
34122
34185
  return {
34123
34186
  pageIndex: this.index,
@@ -34137,37 +34200,37 @@ var PDFPage = class PDFPage {
34137
34200
  * @example
34138
34201
  * ```typescript
34139
34202
  * // String search
34140
- * const matches = await page.findText("{{ name }}");
34203
+ * const matches = page.findText("{{ name }}");
34141
34204
  * for (const match of matches) {
34142
34205
  * console.log(`Found at:`, match.bbox);
34143
34206
  * }
34144
34207
  *
34145
34208
  * // Regex search
34146
- * const placeholders = await page.findText(/\{\{\s*\w+\s*\}\}/g);
34209
+ * const placeholders = page.findText(/\{\{\s*\w+\s*\}\}/g);
34147
34210
  * ```
34148
34211
  */
34149
- async findText(query, options = {}) {
34150
- return searchPage(await this.extractText(), query, options);
34212
+ findText(query, options = {}) {
34213
+ return searchPage(this.extractText(), query, options);
34151
34214
  }
34152
34215
  /**
34153
34216
  * Get the concatenated content stream bytes.
34154
34217
  */
34155
- async getContentBytes() {
34218
+ getContentBytes() {
34156
34219
  const contents = this.dict.get("Contents");
34157
34220
  if (!contents) return new Uint8Array(0);
34158
34221
  if (contents instanceof PdfRef && this.ctx) {
34159
- const stream = await this.ctx.resolve(contents);
34160
- if (stream instanceof PdfStream) return await stream.getDecodedData();
34222
+ const stream = this.ctx.resolve(contents);
34223
+ if (stream instanceof PdfStream) return stream.getDecodedData();
34161
34224
  }
34162
- if (contents instanceof PdfStream) return await contents.getDecodedData();
34225
+ if (contents instanceof PdfStream) return contents.getDecodedData();
34163
34226
  if (contents instanceof PdfArray) {
34164
34227
  const chunks = [];
34165
34228
  for (let i = 0; i < contents.length; i++) {
34166
34229
  const item = contents.at(i);
34167
34230
  if (item instanceof PdfRef && this.ctx) {
34168
- const stream = await this.ctx.resolve(item);
34169
- if (stream instanceof PdfStream) chunks.push(await stream.getDecodedData());
34170
- } else if (item instanceof PdfStream) chunks.push(await item.getDecodedData());
34231
+ const stream = this.ctx.resolve(item);
34232
+ if (stream instanceof PdfStream) chunks.push(stream.getDecodedData());
34233
+ } else if (item instanceof PdfStream) chunks.push(item.getDecodedData());
34171
34234
  }
34172
34235
  return this.concatenateChunks(chunks);
34173
34236
  }
@@ -34195,18 +34258,18 @@ var PDFPage = class PDFPage {
34195
34258
  * PDF pages can inherit Resources from parent Pages nodes (see PDF spec 7.7.3.4).
34196
34259
  * This method checks the page first, then walks up the Parent chain.
34197
34260
  */
34198
- async resolveInheritedResources() {
34261
+ resolveInheritedResources() {
34199
34262
  if (!this.ctx) return null;
34200
34263
  let currentDict = this.dict;
34201
34264
  while (currentDict) {
34202
34265
  const resourcesEntry = currentDict.get("Resources");
34203
34266
  if (resourcesEntry instanceof PdfRef) {
34204
- const resolved = await this.ctx.resolve(resourcesEntry);
34267
+ const resolved = this.ctx.resolve(resourcesEntry);
34205
34268
  if (resolved instanceof PdfDict) return resolved;
34206
34269
  } else if (resourcesEntry instanceof PdfDict) return resourcesEntry;
34207
34270
  const parentEntry = currentDict.get("Parent");
34208
34271
  if (parentEntry instanceof PdfRef) {
34209
- const parent = await this.ctx.resolve(parentEntry);
34272
+ const parent = this.ctx.resolve(parentEntry);
34210
34273
  if (parent instanceof PdfDict) currentDict = parent;
34211
34274
  else break;
34212
34275
  } else break;
@@ -34216,13 +34279,13 @@ var PDFPage = class PDFPage {
34216
34279
  /**
34217
34280
  * Create a font resolver function for text extraction.
34218
34281
  */
34219
- async createFontResolver() {
34220
- const resourcesDict = await this.resolveInheritedResources();
34282
+ createFontResolver() {
34283
+ const resourcesDict = this.resolveInheritedResources();
34221
34284
  if (!resourcesDict) return () => null;
34222
34285
  let fontDict = null;
34223
34286
  const fontEntry = resourcesDict.get("Font");
34224
34287
  if (fontEntry instanceof PdfRef && this.ctx) {
34225
- const resolved = await this.ctx.resolve(fontEntry);
34288
+ const resolved = this.ctx.resolve(fontEntry);
34226
34289
  if (resolved instanceof PdfDict) fontDict = resolved;
34227
34290
  } else if (fontEntry instanceof PdfDict) fontDict = fontEntry;
34228
34291
  if (!fontDict) return () => null;
@@ -34231,7 +34294,7 @@ var PDFPage = class PDFPage {
34231
34294
  const name = nameObj.value;
34232
34295
  let fontDictEntry = null;
34233
34296
  if (fontEntry$1 instanceof PdfRef && this.ctx) {
34234
- const resolved = await this.ctx.resolve(fontEntry$1);
34297
+ const resolved = this.ctx.resolve(fontEntry$1);
34235
34298
  if (resolved instanceof PdfDict) fontDictEntry = resolved;
34236
34299
  } else if (fontEntry$1 instanceof PdfDict) fontDictEntry = fontEntry$1;
34237
34300
  if (!fontDictEntry) continue;
@@ -34240,36 +34303,36 @@ var PDFPage = class PDFPage {
34240
34303
  if (toUnicodeEntry && this.ctx) {
34241
34304
  let toUnicodeStream = null;
34242
34305
  if (toUnicodeEntry instanceof PdfRef) {
34243
- const resolved = await this.ctx.resolve(toUnicodeEntry);
34306
+ const resolved = this.ctx.resolve(toUnicodeEntry);
34244
34307
  if (resolved instanceof PdfStream) toUnicodeStream = resolved;
34245
34308
  } else if (toUnicodeEntry instanceof PdfStream) toUnicodeStream = toUnicodeEntry;
34246
34309
  if (toUnicodeStream) try {
34247
- toUnicodeMap = parseToUnicode(await toUnicodeStream.getDecodedData());
34310
+ toUnicodeMap = parseToUnicode(toUnicodeStream.getDecodedData());
34248
34311
  } catch {}
34249
34312
  }
34250
34313
  const resolvedRefs = /* @__PURE__ */ new Map();
34251
34314
  const decodedStreams = /* @__PURE__ */ new Map();
34252
- const preResolveValue = async (value) => {
34315
+ const preResolveValue = (value) => {
34253
34316
  if (!this.ctx) return;
34254
34317
  if (value instanceof PdfRef) {
34255
34318
  const key$1 = `${value.objectNumber} ${value.generation} R`;
34256
34319
  if (resolvedRefs.has(key$1)) return;
34257
- const resolved = await this.ctx.resolve(value);
34320
+ const resolved = this.ctx.resolve(value);
34258
34321
  if (resolved instanceof PdfDict || resolved instanceof PdfArray || resolved instanceof PdfStream) {
34259
34322
  resolvedRefs.set(key$1, resolved);
34260
34323
  if (resolved instanceof PdfStream) try {
34261
- const decoded = await resolved.getDecodedData();
34324
+ const decoded = resolved.getDecodedData();
34262
34325
  decodedStreams.set(key$1, decoded);
34263
34326
  } catch {}
34264
- await preResolveValue(resolved);
34327
+ preResolveValue(resolved);
34265
34328
  }
34266
- } else if (value instanceof PdfDict) for (const [, v] of value) await preResolveValue(v);
34267
- else if (value instanceof PdfArray) for (let i = 0; i < value.length; i++) await preResolveValue(value.at(i));
34329
+ } else if (value instanceof PdfDict) for (const [, v] of value) preResolveValue(v);
34330
+ else if (value instanceof PdfArray) for (let i = 0; i < value.length; i++) preResolveValue(value.at(i));
34268
34331
  };
34269
- await preResolveValue(fontDictEntry.get("DescendantFonts"));
34270
- await preResolveValue(fontDictEntry.get("FontDescriptor"));
34271
- await preResolveValue(fontDictEntry.get("Encoding"));
34272
- await preResolveValue(fontDictEntry.get("Widths"));
34332
+ preResolveValue(fontDictEntry.get("DescendantFonts"));
34333
+ preResolveValue(fontDictEntry.get("FontDescriptor"));
34334
+ preResolveValue(fontDictEntry.get("Encoding"));
34335
+ preResolveValue(fontDictEntry.get("Widths"));
34273
34336
  const pdfFont = parseFont(fontDictEntry, {
34274
34337
  resolveRef: (ref) => {
34275
34338
  if (ref instanceof PdfRef && this.ctx) {
@@ -34340,17 +34403,16 @@ var PDFPageTree = class PDFPageTree {
34340
34403
  }
34341
34404
  /**
34342
34405
  * Load and build the page tree by walking from the root.
34343
- * This is the only async operation.
34344
34406
  */
34345
- static async load(pagesRef, getObject) {
34407
+ static load(pagesRef, getObject) {
34346
34408
  const pages = [];
34347
34409
  const visited = /* @__PURE__ */ new Set();
34348
34410
  const loadedPages = /* @__PURE__ */ new Map();
34349
- const walk = async (ref) => {
34411
+ const walk = (ref) => {
34350
34412
  const key$1 = `${ref.objectNumber} ${ref.generation}`;
34351
34413
  if (visited.has(key$1)) return;
34352
34414
  visited.add(key$1);
34353
- const node = await getObject(ref);
34415
+ const node = getObject(ref);
34354
34416
  if (!(node instanceof PdfDict)) return;
34355
34417
  const type = node.getName("Type")?.value;
34356
34418
  if (type === "Page") {
@@ -34360,12 +34422,12 @@ var PDFPageTree = class PDFPageTree {
34360
34422
  const kids = node.getArray("Kids");
34361
34423
  if (kids) for (let i = 0; i < kids.length; i++) {
34362
34424
  const kid = kids.at(i);
34363
- if (kid instanceof PdfRef) await walk(kid);
34425
+ if (kid instanceof PdfRef) walk(kid);
34364
34426
  }
34365
34427
  }
34366
34428
  };
34367
- await walk(pagesRef);
34368
- const root = await getObject(pagesRef);
34429
+ walk(pagesRef);
34430
+ const root = getObject(pagesRef);
34369
34431
  if (!(root instanceof PdfDict)) throw new Error("Root Pages object is not a dictionary");
34370
34432
  const getPageDict = (ref) => {
34371
34433
  const key$1 = `${ref.objectNumber} ${ref.generation}`;
@@ -34976,7 +35038,7 @@ async function computeSha1Hex(data) {
34976
35038
  * ```typescript
34977
35039
  * const dssBuilder = await DSSBuilder.fromCatalog(catalog, registry);
34978
35040
  * await dssBuilder.addLtvData(ltvData);
34979
- * const dssRef = await dssBuilder.build();
35041
+ * const dssRef = dssBuilder.build();
34980
35042
  * catalog.set("DSS", dssRef);
34981
35043
  * ```
34982
35044
  */
@@ -35018,7 +35080,7 @@ var DSSBuilder = class DSSBuilder {
35018
35080
  let dss;
35019
35081
  if (dssVal instanceof PdfDict) dss = dssVal;
35020
35082
  else if (dssVal instanceof PdfRef) {
35021
- const resolved = await registry.resolve(dssVal);
35083
+ const resolved = registry.resolve(dssVal);
35022
35084
  if (!(resolved instanceof PdfDict)) return builder;
35023
35085
  dss = resolved;
35024
35086
  } else return builder;
@@ -35030,7 +35092,7 @@ var DSSBuilder = class DSSBuilder {
35030
35092
  let vri;
35031
35093
  if (vriVal instanceof PdfDict) vri = vriVal;
35032
35094
  else if (vriVal instanceof PdfRef) {
35033
- const resolved = await registry.resolve(vriVal);
35095
+ const resolved = registry.resolve(vriVal);
35034
35096
  if (!(resolved instanceof PdfDict)) return builder;
35035
35097
  vri = resolved;
35036
35098
  } else return builder;
@@ -35040,7 +35102,7 @@ var DSSBuilder = class DSSBuilder {
35040
35102
  let entry;
35041
35103
  if (entryVal instanceof PdfDict) entry = entryVal;
35042
35104
  else if (entryVal instanceof PdfRef) {
35043
- const resolved = await registry.resolve(entryVal);
35105
+ const resolved = registry.resolve(entryVal);
35044
35106
  if (!(resolved instanceof PdfDict)) continue;
35045
35107
  entry = resolved;
35046
35108
  } else continue;
@@ -35106,12 +35168,12 @@ var DSSBuilder = class DSSBuilder {
35106
35168
  *
35107
35169
  * Merges with any existing data loaded via fromCatalog().
35108
35170
  */
35109
- async build() {
35171
+ build() {
35110
35172
  const dss = new PdfDict();
35111
35173
  dss.set("Type", PdfName.of("DSS"));
35112
- const certRefs = await this.buildStreamRefs(this.certMap, this.existingCertRefs);
35113
- const ocspRefs = await this.buildStreamRefs(this.ocspMap, this.existingOcspRefs);
35114
- const crlRefs = await this.buildStreamRefs(this.crlMap, this.existingCrlRefs);
35174
+ const certRefs = this.buildStreamRefs(this.certMap, this.existingCertRefs);
35175
+ const ocspRefs = this.buildStreamRefs(this.ocspMap, this.existingOcspRefs);
35176
+ const crlRefs = this.buildStreamRefs(this.crlMap, this.existingCrlRefs);
35115
35177
  if (certRefs.length > 0) dss.set("Certs", new PdfArray(certRefs));
35116
35178
  if (ocspRefs.length > 0) dss.set("OCSPs", new PdfArray(ocspRefs));
35117
35179
  if (crlRefs.length > 0) dss.set("CRLs", new PdfArray(crlRefs));
@@ -35139,13 +35201,13 @@ var DSSBuilder = class DSSBuilder {
35139
35201
  let arrayVal = dss.get(key$1);
35140
35202
  if (!arrayVal) return;
35141
35203
  let array;
35142
- if (arrayVal instanceof PdfRef) arrayVal = await this.registry.resolve(arrayVal) ?? void 0;
35204
+ if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
35143
35205
  if (arrayVal instanceof PdfArray) array = arrayVal;
35144
35206
  if (!array) return;
35145
35207
  for (const item of array) if (item instanceof PdfRef) {
35146
- const stream = await this.registry.resolve(item);
35208
+ const stream = this.registry.resolve(item);
35147
35209
  if (stream instanceof PdfStream) {
35148
- const data = await stream.getDecodedData();
35210
+ const data = stream.getDecodedData();
35149
35211
  const hash = await computeSha1Hex(data);
35150
35212
  dataMap.set(hash, {
35151
35213
  data,
@@ -35162,13 +35224,13 @@ var DSSBuilder = class DSSBuilder {
35162
35224
  const hashes = [];
35163
35225
  let arrayVal = entry.get(key$1);
35164
35226
  if (!arrayVal) return hashes;
35165
- if (arrayVal instanceof PdfRef) arrayVal = await this.registry.resolve(arrayVal) ?? void 0;
35227
+ if (arrayVal instanceof PdfRef) arrayVal = this.registry.resolve(arrayVal) ?? void 0;
35166
35228
  const array = arrayVal instanceof PdfArray ? arrayVal : null;
35167
35229
  if (!array) return hashes;
35168
35230
  for (const item of array) if (item instanceof PdfRef) {
35169
- const stream = await this.registry.resolve(item);
35231
+ const stream = this.registry.resolve(item);
35170
35232
  if (stream instanceof PdfStream) {
35171
- const data = await stream.getDecodedData();
35233
+ const data = stream.getDecodedData();
35172
35234
  const hash = await computeSha1Hex(data);
35173
35235
  hashes.push(hash);
35174
35236
  if (!dataMap.has(hash)) dataMap.set(hash, {
@@ -35182,7 +35244,7 @@ var DSSBuilder = class DSSBuilder {
35182
35244
  /**
35183
35245
  * Build stream refs, reusing existing refs where possible.
35184
35246
  */
35185
- async buildStreamRefs(dataMap, existingRefs) {
35247
+ buildStreamRefs(dataMap, existingRefs) {
35186
35248
  const refs = [];
35187
35249
  for (const [hash, entry] of dataMap) {
35188
35250
  let ref = entry.ref ?? existingRefs.get(hash);
@@ -36258,7 +36320,7 @@ var PDFSignature = class {
36258
36320
  async sign(options) {
36259
36321
  const warnings = [];
36260
36322
  const resolved = this.resolveOptions(options);
36261
- const mdpWarning = await this.checkMdpViolation();
36323
+ const mdpWarning = this.checkMdpViolation();
36262
36324
  if (mdpWarning) warnings.push(mdpWarning);
36263
36325
  const firstPageRef = this.pdf.context.pages.getPage(0);
36264
36326
  if (!firstPageRef) throw new Error("Document has no pages - cannot create signature field");
@@ -36274,7 +36336,7 @@ var PDFSignature = class {
36274
36336
  if (resolved.location) signatureDict.set("Location", PdfString.fromString(escapePdfString(resolved.location)));
36275
36337
  if (resolved.contactInfo) signatureDict.set("ContactInfo", PdfString.fromString(escapePdfString(resolved.contactInfo)));
36276
36338
  const signatureRef = this.pdf.context.registry.register(signatureDict);
36277
- await this.findOrCreateSignatureField({
36339
+ this.findOrCreateSignatureField({
36278
36340
  fieldName: resolved.fieldName,
36279
36341
  pageRef: firstPageRef,
36280
36342
  signatureRef
@@ -36323,9 +36385,9 @@ var PDFSignature = class {
36323
36385
  /**
36324
36386
  * Find or create a signature field.
36325
36387
  */
36326
- async findOrCreateSignatureField(options) {
36388
+ findOrCreateSignatureField(options) {
36327
36389
  const { fieldName, pageRef, signatureRef } = options;
36328
- const form = await this.pdf.getOrCreateForm();
36390
+ const form = this.pdf.getOrCreateForm();
36329
36391
  const existingNames = /* @__PURE__ */ new Set();
36330
36392
  let fieldDict;
36331
36393
  const fields = form.getFields();
@@ -36361,8 +36423,8 @@ var PDFSignature = class {
36361
36423
  /**
36362
36424
  * Check for MDP (certification signature) violations.
36363
36425
  */
36364
- async checkMdpViolation() {
36365
- const form = await this.pdf.getForm();
36426
+ checkMdpViolation() {
36427
+ const form = this.pdf.getForm();
36366
36428
  if (!form) return null;
36367
36429
  const fields = form.getFields();
36368
36430
  for (const field of fields) if (field instanceof SignatureField && field.isSigned()) {
@@ -36388,11 +36450,11 @@ var PDFSignature = class {
36388
36450
  */
36389
36451
  async addDss(ltvData) {
36390
36452
  const registry = this.pdf.context.registry;
36391
- const catalogDict = await this.pdf.getCatalog();
36453
+ const catalogDict = this.pdf.getCatalog();
36392
36454
  if (!catalogDict) throw new Error("Document has no catalog");
36393
36455
  const dssBuilder = await DSSBuilder.fromCatalog(catalogDict, registry);
36394
36456
  await dssBuilder.addLtvData(ltvData);
36395
- const dssRef = await dssBuilder.build();
36457
+ const dssRef = dssBuilder.build();
36396
36458
  catalogDict.set("DSS", dssRef);
36397
36459
  const savedBytes = await this.pdf.save({ incremental: true });
36398
36460
  await this.pdf.reload(savedBytes);
@@ -36619,13 +36681,13 @@ var PDF = class PDF {
36619
36681
  */
36620
36682
  static async load(bytes, options) {
36621
36683
  const scanner = new Scanner(bytes);
36622
- const parsed = await new DocumentParser(scanner, options).parse();
36684
+ const parsed = new DocumentParser(scanner, options).parse();
36623
36685
  const registry = new ObjectRegistry(parsed.xref);
36624
36686
  let isLinearized = false;
36625
36687
  try {
36626
36688
  const firstObjNum = Math.min(...parsed.xref.keys());
36627
36689
  if (firstObjNum > 0) {
36628
- const firstObj = await parsed.getObject(PdfRef.of(firstObjNum, 0));
36690
+ const firstObj = parsed.getObject(PdfRef.of(firstObjNum, 0));
36629
36691
  if (firstObj instanceof PdfDict && isLinearizationDict(firstObj)) isLinearized = true;
36630
36692
  }
36631
36693
  } catch {}
@@ -36641,13 +36703,13 @@ var PDF = class PDF {
36641
36703
  registry.setResolver((ref) => parsed.getObject(ref));
36642
36704
  const rootRef = parsed.trailer.getRef("Root");
36643
36705
  if (!rootRef) throw new Error("Document has no catalog (missing /Root in trailer)");
36644
- const catalogDict = await registry.resolve(rootRef);
36706
+ const catalogDict = registry.resolve(rootRef);
36645
36707
  if (!catalogDict || !(catalogDict instanceof PdfDict)) throw new Error("Document has no catalog");
36646
36708
  const pdfCatalog = new PDFCatalog(catalogDict, registry);
36647
36709
  const pagesRef = catalogDict.getRef("Pages");
36648
- const pages = pagesRef ? await PDFPageTree.load(pagesRef, parsed.getObject.bind(parsed)) : PDFPageTree.empty();
36710
+ const pages = pagesRef ? PDFPageTree.load(pagesRef, parsed.getObject.bind(parsed)) : PDFPageTree.empty();
36649
36711
  const infoRef = parsed.trailer.getRef("Info");
36650
- if (infoRef) await registry.resolve(infoRef);
36712
+ if (infoRef) registry.resolve(infoRef);
36651
36713
  return new PDF(new PDFContext(registry, pdfCatalog, pages, {
36652
36714
  version: parsed.version,
36653
36715
  securityHandler: parsed.securityHandler,
@@ -36672,7 +36734,7 @@ var PDF = class PDF {
36672
36734
  */
36673
36735
  async reload(bytes) {
36674
36736
  const scanner = new Scanner(bytes);
36675
- const parsed = await new DocumentParser(scanner).parse();
36737
+ const parsed = new DocumentParser(scanner).parse();
36676
36738
  const registry = new ObjectRegistry(parsed.xref);
36677
36739
  registry.setResolver((ref) => parsed.getObject(ref));
36678
36740
  const xrefParser = new XRefParser(scanner);
@@ -36684,11 +36746,11 @@ var PDF = class PDF {
36684
36746
  }
36685
36747
  const rootRef = parsed.trailer.getRef("Root");
36686
36748
  if (!rootRef) throw new Error("Document has no catalog");
36687
- const catalogDict = await registry.resolve(rootRef);
36749
+ const catalogDict = registry.resolve(rootRef);
36688
36750
  if (!(catalogDict instanceof PdfDict)) throw new Error("Document has no catalog");
36689
36751
  const pdfCatalog = new PDFCatalog(catalogDict, registry);
36690
36752
  const pagesRef = catalogDict.getRef("Pages");
36691
- this.ctx = new PDFContext(registry, pdfCatalog, pagesRef ? await PDFPageTree.load(pagesRef, parsed.getObject.bind(parsed)) : PDFPageTree.empty(), {
36753
+ this.ctx = new PDFContext(registry, pdfCatalog, pagesRef ? PDFPageTree.load(pagesRef, parsed.getObject.bind(parsed)) : PDFPageTree.empty(), {
36692
36754
  version: parsed.version,
36693
36755
  securityHandler: parsed.securityHandler,
36694
36756
  isEncrypted: parsed.isEncrypted,
@@ -36727,8 +36789,12 @@ var PDF = class PDF {
36727
36789
  });
36728
36790
  const catalogRef = registry.register(catalogDict);
36729
36791
  const trailer = PdfDict.of({ Root: catalogRef });
36730
- registry.setResolver(async (ref) => registry.getObject(ref));
36731
- const pdf = new PDF(new PDFContext(registry, new PDFCatalog(catalogDict, registry), PDFPageTree.fromRoot(pagesRef, pagesDict, (ref) => registry.getObject(ref)), {
36792
+ registry.setResolver((ref) => registry.getObject(ref));
36793
+ const pdf = new PDF(new PDFContext(registry, new PDFCatalog(catalogDict, registry), PDFPageTree.fromRoot(pagesRef, pagesDict, (ref) => {
36794
+ const obj = registry.getObject(ref);
36795
+ if (obj instanceof PdfDict) return obj;
36796
+ return null;
36797
+ }), {
36732
36798
  version: "1.7",
36733
36799
  securityHandler: null,
36734
36800
  isEncrypted: false,
@@ -37336,7 +37402,7 @@ var PDF = class PDF {
37336
37402
  *
37337
37403
  * Objects are cached and tracked for modifications.
37338
37404
  */
37339
- async getObject(ref) {
37405
+ getObject(ref) {
37340
37406
  return this.ctx.resolve(ref);
37341
37407
  }
37342
37408
  /**
@@ -37345,18 +37411,18 @@ var PDF = class PDF {
37345
37411
  * Note: For internal use, prefer accessing the catalog via context which
37346
37412
  * provides higher-level methods for working with catalog structures.
37347
37413
  */
37348
- async getCatalog() {
37414
+ getCatalog() {
37349
37415
  return this.ctx.catalog.getDict();
37350
37416
  }
37351
37417
  /**
37352
37418
  * Get all pages in document order.
37353
37419
  */
37354
- async getPages() {
37420
+ getPages() {
37355
37421
  const refs = this.ctx.pages.getPages();
37356
37422
  const pages = [];
37357
37423
  for (let i = 0; i < refs.length; i++) {
37358
37424
  const ref = refs[i];
37359
- const dict = await this.ctx.resolve(ref);
37425
+ const dict = this.ctx.resolve(ref);
37360
37426
  if (!(dict instanceof PdfDict)) throw new Error(`Page ${i} is not a dictionary`);
37361
37427
  pages.push(new PDFPage(ref, dict, i, this.ctx));
37362
37428
  }
@@ -37372,14 +37438,29 @@ var PDF = class PDF {
37372
37438
  * Get a single page by index (0-based).
37373
37439
  * Returns null if index out of bounds.
37374
37440
  */
37375
- async getPage(index) {
37441
+ getPage(index) {
37376
37442
  const ref = this.ctx.pages.getPage(index);
37377
37443
  if (!ref) return null;
37378
- const dict = await this.ctx.resolve(ref);
37444
+ const dict = this.ctx.resolve(ref);
37379
37445
  if (!(dict instanceof PdfDict)) return null;
37446
+ this.ensurePageResourcesResolved(dict);
37380
37447
  return new PDFPage(ref, dict, index, this.ctx);
37381
37448
  }
37382
37449
  /**
37450
+ * Ensure page resources are resolved (not a reference).
37451
+ *
37452
+ * Pages may have Resources as a PdfRef pointing to a shared resources dict.
37453
+ * The sync getResources() method on PDFPage needs the actual dict, not a ref.
37454
+ * This resolves the reference and replaces it in the page dict.
37455
+ */
37456
+ ensurePageResourcesResolved(pageDict) {
37457
+ const resources = pageDict.get("Resources");
37458
+ if (resources instanceof PdfRef) {
37459
+ const resolved = this.ctx.resolve(resources);
37460
+ if (resolved instanceof PdfDict) pageDict.set("Resources", resolved.clone());
37461
+ }
37462
+ }
37463
+ /**
37383
37464
  * Add a new blank page.
37384
37465
  *
37385
37466
  * @param options - Page size, rotation, and insertion position
@@ -37489,14 +37570,14 @@ var PDF = class PDF {
37489
37570
  for (const index of indices) if (index < 0 || index >= source.getPageCount()) throw new RangeError(`Page index ${index} out of bounds (0-${source.getPageCount() - 1})`);
37490
37571
  const copiedRefs = [];
37491
37572
  for (const index of indices) {
37492
- const srcPage = await source.getPage(index);
37573
+ const srcPage = source.getPage(index);
37493
37574
  if (!srcPage) throw new Error(`Source page ${index} not found`);
37494
37575
  const copiedPageRef = await copier.copyPage(srcPage.ref);
37495
37576
  copiedRefs.push(copiedPageRef);
37496
37577
  }
37497
37578
  let insertIndex = options.insertAt ?? this.getPageCount();
37498
37579
  for (const copiedRef of copiedRefs) {
37499
- const copiedDict = await this.getObject(copiedRef);
37580
+ const copiedDict = this.getObject(copiedRef);
37500
37581
  if (!(copiedDict instanceof PdfDict)) throw new Error("Copied page is not a dictionary");
37501
37582
  this.ctx.pages.insertPage(insertIndex, copiedRef, copiedDict);
37502
37583
  const page = new PDFPage(copiedRef, copiedDict, insertIndex, this.ctx);
@@ -37560,18 +37641,18 @@ var PDF = class PDF {
37560
37641
  * ```
37561
37642
  */
37562
37643
  async embedPage(source, pageIndex) {
37563
- const srcPage = await source.getPage(pageIndex);
37644
+ const srcPage = source.getPage(pageIndex);
37564
37645
  if (!srcPage) throw new RangeError(`Page index ${pageIndex} out of bounds`);
37565
- const contentData = await this.getPageContentData(source, srcPage);
37646
+ const contentData = this.getPageContentData(source, srcPage);
37566
37647
  const copier = new ObjectCopier(source, this, { includeAnnotations: false });
37567
- const srcResources = srcPage.dict.get("Resources");
37568
- let resources;
37569
- if (srcResources instanceof PdfDict) resources = await copier.copyObject(srcResources);
37570
- else if (srcResources instanceof PdfRef) {
37571
- const resolved = await source.getObject(srcResources);
37572
- if (resolved instanceof PdfDict) resources = await copier.copyObject(resolved);
37573
- else resources = new PdfDict();
37574
- } else resources = new PdfDict();
37648
+ let srcResources = srcPage.dict.get("Resources");
37649
+ let resources = void 0;
37650
+ if (srcResources instanceof PdfRef) srcResources = source.getObject(srcResources) ?? void 0;
37651
+ if (srcResources instanceof PdfDict) {
37652
+ const copied = await copier.copyObject(srcResources);
37653
+ if (copied instanceof PdfDict) resources = copied;
37654
+ }
37655
+ if (!resources) resources = new PdfDict();
37575
37656
  const mediaBox = srcPage.getMediaBox();
37576
37657
  const formXObject = PdfStream.fromDict({
37577
37658
  Type: PdfName.of("XObject"),
@@ -37590,12 +37671,12 @@ var PDF = class PDF {
37590
37671
  /**
37591
37672
  * Get the concatenated content stream data from a page.
37592
37673
  */
37593
- async getPageContentData(source, page) {
37674
+ getPageContentData(source, page) {
37594
37675
  const contents = page.dict.get("Contents");
37595
37676
  if (!contents) return new Uint8Array(0);
37596
37677
  if (contents instanceof PdfRef) {
37597
- const stream = await source.getObject(contents);
37598
- if (stream instanceof PdfStream) return await stream.getDecodedData();
37678
+ const stream = source.getObject(contents);
37679
+ if (stream instanceof PdfStream) return stream.getDecodedData();
37599
37680
  return new Uint8Array(0);
37600
37681
  }
37601
37682
  if (contents instanceof PdfArray) {
@@ -37603,10 +37684,10 @@ var PDF = class PDF {
37603
37684
  for (let i = 0; i < contents.length; i++) {
37604
37685
  const ref = contents.at(i);
37605
37686
  if (ref instanceof PdfRef) {
37606
- const stream = await source.getObject(ref);
37687
+ const stream = source.getObject(ref);
37607
37688
  if (stream instanceof PdfStream) {
37608
37689
  if (chunks.length > 0) chunks.push(new Uint8Array([10]));
37609
- chunks.push(await stream.getDecodedData());
37690
+ chunks.push(stream.getDecodedData());
37610
37691
  }
37611
37692
  }
37612
37693
  }
@@ -37619,7 +37700,7 @@ var PDF = class PDF {
37619
37700
  }
37620
37701
  return result;
37621
37702
  }
37622
- if (contents instanceof PdfStream) return await contents.getDecodedData();
37703
+ if (contents instanceof PdfStream) return contents.getDecodedData();
37623
37704
  return new Uint8Array(0);
37624
37705
  }
37625
37706
  /**
@@ -37719,7 +37800,7 @@ var PDF = class PDF {
37719
37800
  * page.drawImage(image, { x: 50, y: 500 });
37720
37801
  * ```
37721
37802
  */
37722
- async embedImage(bytes) {
37803
+ embedImage(bytes) {
37723
37804
  if (isJpeg(bytes)) return this.embedJpeg(bytes);
37724
37805
  if (isPng(bytes)) return this.embedPng(bytes);
37725
37806
  throw new Error("Unsupported image format. Only JPEG and PNG are supported.");
@@ -37744,7 +37825,7 @@ var PDF = class PDF {
37744
37825
  * });
37745
37826
  * ```
37746
37827
  */
37747
- async embedJpeg(bytes) {
37828
+ embedJpeg(bytes) {
37748
37829
  const info = parseJpegHeader(bytes);
37749
37830
  const stream = PdfStream.fromDict({
37750
37831
  Type: PdfName.of("XObject"),
@@ -37775,7 +37856,7 @@ var PDF = class PDF {
37775
37856
  * page.drawImage(logo, { x: 100, y: 700, width: 150 });
37776
37857
  * ```
37777
37858
  */
37778
- async embedPng(bytes) {
37859
+ embedPng(bytes) {
37779
37860
  const { info, pixels, alpha } = parsePng(bytes);
37780
37861
  const compressedPixels = deflate(pixels);
37781
37862
  const dictEntries = {
@@ -37834,7 +37915,7 @@ var PDF = class PDF {
37834
37915
  *
37835
37916
  * @returns Map of attachment name to attachment info
37836
37917
  */
37837
- async getAttachments() {
37918
+ getAttachments() {
37838
37919
  return this.attachments.list();
37839
37920
  }
37840
37921
  /**
@@ -37845,7 +37926,7 @@ var PDF = class PDF {
37845
37926
  * @param name The attachment name (key in the EmbeddedFiles tree)
37846
37927
  * @returns The attachment bytes, or null if not found
37847
37928
  */
37848
- async getAttachment(name) {
37929
+ getAttachment(name) {
37849
37930
  return this.attachments.get(name);
37850
37931
  }
37851
37932
  /**
@@ -37856,7 +37937,7 @@ var PDF = class PDF {
37856
37937
  * @param name The attachment name
37857
37938
  * @returns True if the attachment exists
37858
37939
  */
37859
- async hasAttachment(name) {
37940
+ hasAttachment(name) {
37860
37941
  return this.attachments.has(name);
37861
37942
  }
37862
37943
  /**
@@ -37869,7 +37950,7 @@ var PDF = class PDF {
37869
37950
  * @param options - Attachment options (description, MIME type, dates)
37870
37951
  * @throws {Error} If name already exists and overwrite !== true
37871
37952
  */
37872
- async addAttachment(name, data, options = {}) {
37953
+ addAttachment(name, data, options = {}) {
37873
37954
  return this.attachments.add(name, data, options);
37874
37955
  }
37875
37956
  /**
@@ -37880,7 +37961,7 @@ var PDF = class PDF {
37880
37961
  * @param name The attachment name
37881
37962
  * @returns True if the attachment was removed, false if not found
37882
37963
  */
37883
- async removeAttachment(name) {
37964
+ removeAttachment(name) {
37884
37965
  return this.attachments.remove(name);
37885
37966
  }
37886
37967
  /**
@@ -37932,8 +38013,8 @@ var PDF = class PDF {
37932
38013
  * await pdf.save({ incremental: true });
37933
38014
  * ```
37934
38015
  */
37935
- async getForm() {
37936
- if (this._form === void 0) this._form = await PDFForm.load(this.ctx);
38016
+ getForm() {
38017
+ if (this._form === void 0) this._form = PDFForm.load(this.ctx);
37937
38018
  return this._form;
37938
38019
  }
37939
38020
  /**
@@ -37951,8 +38032,8 @@ var PDF = class PDF {
37951
38032
  * const nameField = form.createTextField("name", { fontSize: 12 });
37952
38033
  * ```
37953
38034
  */
37954
- async getOrCreateForm() {
37955
- const existing = await this.getForm();
38035
+ getOrCreateForm() {
38036
+ const existing = this.getForm();
37956
38037
  if (existing) return existing;
37957
38038
  const helveticaDict = PdfDict.of({
37958
38039
  Type: PdfName.of("Font"),
@@ -37976,9 +38057,8 @@ var PDF = class PDF {
37976
38057
  NeedAppearances: PdfBool.of(false)
37977
38058
  });
37978
38059
  const acroFormRef = this.ctx.registry.register(acroFormDict);
37979
- const catalog = await this.getCatalog();
37980
- if (catalog) catalog.set("AcroForm", acroFormRef);
37981
- this._form = await PDFForm.load(this.ctx);
38060
+ this.getCatalog().set("AcroForm", acroFormRef);
38061
+ this._form = PDFForm.load(this.ctx);
37982
38062
  if (!this._form) throw new Error("Failed to create form");
37983
38063
  return this._form;
37984
38064
  }
@@ -38033,7 +38113,7 @@ var PDF = class PDF {
38033
38113
  * }
38034
38114
  * ```
38035
38115
  */
38036
- async hasLayers() {
38116
+ hasLayers() {
38037
38117
  return hasLayers(this.ctx);
38038
38118
  }
38039
38119
  /**
@@ -38052,7 +38132,7 @@ var PDF = class PDF {
38052
38132
  * }
38053
38133
  * ```
38054
38134
  */
38055
- async getLayers() {
38135
+ getLayers() {
38056
38136
  return getLayers(this.ctx);
38057
38137
  }
38058
38138
  /**
@@ -38084,7 +38164,7 @@ var PDF = class PDF {
38084
38164
  * await pdf.sign({ signer });
38085
38165
  * ```
38086
38166
  */
38087
- async flattenLayers() {
38167
+ flattenLayers() {
38088
38168
  return flattenLayers(this.ctx);
38089
38169
  }
38090
38170
  /**
@@ -38103,10 +38183,10 @@ var PDF = class PDF {
38103
38183
  * }
38104
38184
  * ```
38105
38185
  */
38106
- async extractText() {
38107
- const pages = await this.getPages();
38186
+ extractText() {
38187
+ const pages = this.getPages();
38108
38188
  const results = [];
38109
- for (const page of pages) results.push(await page.extractText());
38189
+ for (const page of pages) results.push(page.extractText());
38110
38190
  return results;
38111
38191
  }
38112
38192
  /**
@@ -38131,12 +38211,12 @@ var PDF = class PDF {
38131
38211
  * const placeholders = await pdf.findText(/\{\{\s*\w+\s*\}\}/g);
38132
38212
  * ```
38133
38213
  */
38134
- async findText(query, options = {}) {
38135
- const pages = await this.getPages();
38214
+ findText(query, options = {}) {
38215
+ const pages = this.getPages();
38136
38216
  const pagesToSearch = options.pages ?? Array.from({ length: pages.length }, (_, i) => i);
38137
38217
  const results = [];
38138
38218
  for (const pageIndex of pagesToSearch) if (pageIndex >= 0 && pageIndex < pages.length) {
38139
- const matches = await pages[pageIndex].findText(query, options);
38219
+ const matches = pages[pageIndex].findText(query, options);
38140
38220
  results.push(...matches);
38141
38221
  }
38142
38222
  return results;
@@ -38171,14 +38251,14 @@ var PDF = class PDF {
38171
38251
  * @throws {Error} If document has no catalog (missing /Root in trailer)
38172
38252
  */
38173
38253
  async save(options = {}) {
38174
- return (await this.saveInternal(options)).bytes;
38254
+ return this.saveInternal(options).bytes;
38175
38255
  }
38176
38256
  /**
38177
38257
  * Internal save that returns full result including xref offset.
38178
38258
  * Used by signing to chain incremental updates.
38179
38259
  */
38180
- async saveInternal(options = {}) {
38181
- await this.fonts.finalize(options.subsetFonts ?? false);
38260
+ saveInternal(options = {}) {
38261
+ this.fonts.finalize(options.subsetFonts ?? false);
38182
38262
  const wantsIncremental = options.incremental ?? false;
38183
38263
  const blocker = this.canSaveIncrementally();
38184
38264
  if (wantsIncremental && blocker !== null) this.ctx.registry.addWarning(`Incremental save not possible (${blocker}), performing full save`);
@@ -38215,7 +38295,7 @@ var PDF = class PDF {
38215
38295
  }
38216
38296
  const useXRefStream = options.useXRefStream ?? (useIncremental ? this.usesXRefStreams : false);
38217
38297
  if (useIncremental) {
38218
- const result$1 = await writeIncremental(this.ctx.registry, {
38298
+ const result$1 = writeIncremental(this.ctx.registry, {
38219
38299
  originalBytes: this.originalBytes,
38220
38300
  originalXRefOffset: this.originalXRefOffset,
38221
38301
  root,
@@ -38228,8 +38308,8 @@ var PDF = class PDF {
38228
38308
  this._pendingSecurity = { action: "none" };
38229
38309
  return result$1;
38230
38310
  }
38231
- await this.ensureObjectsLoaded();
38232
- const result = await writeComplete(this.ctx.registry, {
38311
+ this.ensureObjectsLoaded();
38312
+ const result = writeComplete(this.ctx.registry, {
38233
38313
  version: this.ctx.info.version,
38234
38314
  root,
38235
38315
  info: infoRef ?? void 0,
@@ -38246,22 +38326,22 @@ var PDF = class PDF {
38246
38326
  *
38247
38327
  * Walks from the catalog to load all referenced objects.
38248
38328
  */
38249
- async ensureObjectsLoaded() {
38329
+ ensureObjectsLoaded() {
38250
38330
  const visited = /* @__PURE__ */ new Set();
38251
- const walk = async (obj) => {
38331
+ const walk = (obj) => {
38252
38332
  if (obj === null) return;
38253
38333
  if (obj instanceof PdfRef) {
38254
38334
  const key$1 = `${obj.objectNumber} ${obj.generation}`;
38255
38335
  if (visited.has(key$1)) return;
38256
38336
  visited.add(key$1);
38257
- await walk(await this.getObject(obj));
38258
- } else if (obj instanceof PdfDict) for (const [, value] of obj) await walk(value);
38259
- else if (obj instanceof PdfArray) for (const item of obj) await walk(item);
38337
+ walk(this.getObject(obj));
38338
+ } else if (obj instanceof PdfDict) for (const [, value] of obj) walk(value);
38339
+ else if (obj instanceof PdfArray) for (const item of obj) walk(item);
38260
38340
  };
38261
38341
  const root = this.ctx.info.trailer.getRef("Root");
38262
- if (root) await walk(root);
38342
+ if (root) walk(root);
38263
38343
  const infoRef = this.ctx.info.trailer.getRef("Info");
38264
- if (infoRef) await walk(infoRef);
38344
+ if (infoRef) walk(infoRef);
38265
38345
  }
38266
38346
  };
38267
38347
 
@@ -38645,7 +38725,8 @@ const GrpcStatus = {
38645
38725
  * Type guard for gRPC errors from Google Cloud libraries.
38646
38726
  */
38647
38727
  function isGrpcError(error) {
38648
- return error instanceof Error && typeof error.code === "number" && error.code >= 0 && error.code <= 16;
38728
+ const grpcError = error;
38729
+ return grpcError instanceof Error && typeof grpcError.code === "number" && grpcError.code >= 0 && grpcError.code <= 16;
38649
38730
  }
38650
38731
  /**
38651
38732
  * Signer that uses Google Cloud KMS for signing operations.
@@ -38813,6 +38894,7 @@ var GoogleKmsSigner = class GoogleKmsSigner {
38813
38894
  digest: { [digestKey]: digest }
38814
38895
  });
38815
38896
  if (!response.signature) throw new KmsSignerError("KMS did not return a signature");
38897
+ if (typeof response.signature === "string") return new TextEncoder().encode(response.signature);
38816
38898
  return new Uint8Array(response.signature);
38817
38899
  } catch (error) {
38818
38900
  if (error instanceof KmsSignerError) throw error;