pdf-lite 1.3.3 → 1.4.0

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.
Files changed (100) hide show
  1. package/dist/acroform/PdfAcroForm.d.ts +63 -0
  2. package/dist/acroform/PdfAcroForm.js +279 -0
  3. package/dist/acroform/PdfFontEncodingCache.d.ts +16 -0
  4. package/dist/acroform/PdfFontEncodingCache.js +75 -0
  5. package/dist/acroform/acroform.d.ts +7 -454
  6. package/dist/acroform/acroform.js +5 -1664
  7. package/dist/acroform/appearance/PdfAppearanceStream.d.ts +15 -0
  8. package/dist/acroform/appearance/PdfAppearanceStream.js +32 -0
  9. package/dist/acroform/appearance/PdfButtonAppearanceStream.d.ts +12 -0
  10. package/dist/acroform/appearance/PdfButtonAppearanceStream.js +54 -0
  11. package/dist/acroform/appearance/PdfChoiceAppearanceStream.d.ts +15 -0
  12. package/dist/acroform/appearance/PdfChoiceAppearanceStream.js +48 -0
  13. package/dist/acroform/appearance/PdfTextAppearanceStream.d.ts +17 -0
  14. package/dist/acroform/appearance/PdfTextAppearanceStream.js +75 -0
  15. package/dist/acroform/appearance/index.d.ts +4 -0
  16. package/dist/acroform/appearance/index.js +4 -0
  17. package/dist/acroform/fields/PdfButtonFormField.d.ts +9 -0
  18. package/dist/acroform/fields/PdfButtonFormField.js +35 -0
  19. package/dist/acroform/fields/PdfChoiceFormField.d.ts +9 -0
  20. package/dist/acroform/fields/PdfChoiceFormField.js +46 -0
  21. package/dist/acroform/fields/PdfDefaultAppearance.d.ts +23 -0
  22. package/dist/acroform/fields/PdfDefaultAppearance.js +68 -0
  23. package/dist/acroform/fields/PdfFormField.d.ts +119 -0
  24. package/dist/acroform/fields/PdfFormField.js +499 -0
  25. package/dist/acroform/fields/PdfFormFieldFlags.d.ts +46 -0
  26. package/dist/acroform/fields/PdfFormFieldFlags.js +128 -0
  27. package/dist/acroform/fields/PdfSignatureFormField.d.ts +7 -0
  28. package/dist/acroform/fields/PdfSignatureFormField.js +12 -0
  29. package/dist/acroform/fields/PdfTextFormField.d.ts +10 -0
  30. package/dist/acroform/fields/PdfTextFormField.js +52 -0
  31. package/dist/acroform/fields/index.d.ts +8 -0
  32. package/dist/acroform/fields/index.js +8 -0
  33. package/dist/acroform/fields/types.d.ts +21 -0
  34. package/dist/acroform/fields/types.js +9 -0
  35. package/dist/acroform/index.d.ts +5 -1
  36. package/dist/acroform/index.js +5 -1
  37. package/dist/acroform/manager.d.ts +7 -0
  38. package/dist/acroform/manager.js +12 -0
  39. package/dist/acroform/xfa/PdfXfaData.d.ts +20 -0
  40. package/dist/acroform/xfa/PdfXfaData.js +68 -0
  41. package/dist/acroform/xfa/PdfXfaForm.d.ts +12 -0
  42. package/dist/acroform/xfa/PdfXfaForm.js +64 -0
  43. package/dist/acroform/xfa/index.d.ts +3 -0
  44. package/dist/acroform/xfa/index.js +2 -0
  45. package/dist/annotations/PdfAnnotation.d.ts +40 -0
  46. package/dist/annotations/PdfAnnotation.js +105 -0
  47. package/dist/annotations/PdfAnnotationFlags.d.ts +25 -0
  48. package/dist/annotations/PdfAnnotationFlags.js +94 -0
  49. package/dist/annotations/PdfAnnotationWriter.d.ts +20 -0
  50. package/dist/annotations/PdfAnnotationWriter.js +76 -0
  51. package/dist/annotations/PdfWidgetAnnotation.d.ts +15 -0
  52. package/dist/annotations/PdfWidgetAnnotation.js +37 -0
  53. package/dist/annotations/index.d.ts +4 -0
  54. package/dist/annotations/index.js +4 -0
  55. package/dist/core/objects/pdf-array.d.ts +1 -1
  56. package/dist/core/objects/pdf-array.js +3 -2
  57. package/dist/core/objects/pdf-boolean.d.ts +1 -1
  58. package/dist/core/objects/pdf-boolean.js +3 -2
  59. package/dist/core/objects/pdf-comment.d.ts +1 -1
  60. package/dist/core/objects/pdf-comment.js +1 -1
  61. package/dist/core/objects/pdf-dictionary.d.ts +1 -1
  62. package/dist/core/objects/pdf-dictionary.js +3 -2
  63. package/dist/core/objects/pdf-hexadecimal.d.ts +1 -1
  64. package/dist/core/objects/pdf-hexadecimal.js +3 -2
  65. package/dist/core/objects/pdf-indirect-object.d.ts +1 -1
  66. package/dist/core/objects/pdf-indirect-object.js +1 -1
  67. package/dist/core/objects/pdf-name.d.ts +1 -1
  68. package/dist/core/objects/pdf-name.js +3 -2
  69. package/dist/core/objects/pdf-null.d.ts +1 -1
  70. package/dist/core/objects/pdf-null.js +3 -2
  71. package/dist/core/objects/pdf-number.d.ts +1 -1
  72. package/dist/core/objects/pdf-number.js +3 -2
  73. package/dist/core/objects/pdf-object-reference.d.ts +1 -1
  74. package/dist/core/objects/pdf-object-reference.js +3 -2
  75. package/dist/core/objects/pdf-object.d.ts +3 -1
  76. package/dist/core/objects/pdf-object.js +6 -0
  77. package/dist/core/objects/pdf-start-xref.d.ts +1 -1
  78. package/dist/core/objects/pdf-start-xref.js +3 -2
  79. package/dist/core/objects/pdf-stream.d.ts +3 -3
  80. package/dist/core/objects/pdf-stream.js +39 -14
  81. package/dist/core/objects/pdf-string.d.ts +2 -1
  82. package/dist/core/objects/pdf-string.js +17 -2
  83. package/dist/core/objects/pdf-trailer.d.ts +1 -1
  84. package/dist/core/objects/pdf-trailer.js +3 -2
  85. package/dist/core/objects/pdf-xref-table.d.ts +3 -3
  86. package/dist/core/objects/pdf-xref-table.js +3 -3
  87. package/dist/index.d.ts +1 -0
  88. package/dist/index.js +1 -0
  89. package/dist/pdf/pdf-document.d.ts +14 -11
  90. package/dist/pdf/pdf-document.js +36 -26
  91. package/dist/pdf/pdf-revision.d.ts +1 -1
  92. package/dist/pdf/pdf-revision.js +1 -1
  93. package/dist/pdf/pdf-xref-lookup.d.ts +8 -0
  94. package/dist/pdf/pdf-xref-lookup.js +12 -0
  95. package/dist/security/handlers/base.js +3 -0
  96. package/package.json +1 -1
  97. package/dist/xfa/index.d.ts +0 -1
  98. package/dist/xfa/index.js +0 -1
  99. package/dist/xfa/manager.d.ts +0 -44
  100. package/dist/xfa/manager.js +0 -136
package/dist/index.js CHANGED
@@ -7,3 +7,4 @@ export * from './pdf/index.js';
7
7
  export * from './security/index.js';
8
8
  export * from './signing/index.js';
9
9
  export * from './utils/index.js';
10
+ export * from './annotations/index.js';
@@ -12,7 +12,6 @@ import { PdfTrailerEntries } from '../core/objects/pdf-trailer.js';
12
12
  import { PdfDocumentSecurityStoreObject } from '../signing/document-security-store.js';
13
13
  import { ByteArray } from '../types.js';
14
14
  import { PdfDocumentVerificationResult, PdfSigner } from '../signing/signer.js';
15
- import { PdfXfaManager } from '../xfa/manager.js';
16
15
  import { PdfAcroFormManager } from '../acroform/manager.js';
17
16
  import { PdfFontManager } from '../fonts/font-manager.js';
18
17
  /**
@@ -39,9 +38,9 @@ export declare class PdfDocument extends PdfObject {
39
38
  signer: PdfSigner;
40
39
  /** Security handler for encryption/decryption operations */
41
40
  securityHandler?: PdfSecurityHandler;
42
- private _xfa?;
43
- private _acroForm?;
44
- private _fonts?;
41
+ /** */
42
+ readonly acroForm: PdfAcroFormManager;
43
+ readonly fonts: PdfFontManager;
45
44
  private hasEncryptionDictionary?;
46
45
  private toBeCommitted;
47
46
  /**
@@ -65,12 +64,6 @@ export declare class PdfDocument extends PdfObject {
65
64
  });
66
65
  get header(): PdfComment | undefined;
67
66
  set header(comment: PdfComment | undefined);
68
- /** XFA manager for handling XFA forms */
69
- get xfa(): PdfXfaManager;
70
- /** AcroForm manager for handling form fields */
71
- get acroForm(): PdfAcroFormManager;
72
- /** Font manager for embedding and managing fonts */
73
- get fonts(): PdfFontManager;
74
67
  /**
75
68
  * Creates a PdfDocument from an array of PDF objects.
76
69
  * Parses objects into revisions based on EOF comments.
@@ -93,6 +86,16 @@ export declare class PdfDocument extends PdfObject {
93
86
  * @param objects - PDF objects to add to the document
94
87
  */
95
88
  add(...objects: PdfObject[]): void;
89
+ /**
90
+ * Packs non-stream indirect objects into compressed ObjStm containers.
91
+ * Objects that already have an object number are left unchanged.
92
+ * Appearance streams and other PdfStream objects must NOT be passed here —
93
+ * only non-stream indirect objects (dictionaries, arrays, etc.) are eligible.
94
+ *
95
+ * @param objects - Non-stream indirect objects to compress into ObjStm
96
+ * @param batchSize - Maximum objects per ObjStm container (default 100)
97
+ */
98
+ addObjectsAsStream(objects: PdfIndirectObject[], batchSize?: number): void;
96
99
  /**
97
100
  * Gets the latest (most recent) revision of the document.
98
101
  *
@@ -284,7 +287,7 @@ export declare class PdfDocument extends PdfObject {
284
287
  *
285
288
  * @returns A cloned PdfDocument instance
286
289
  */
287
- clone(): this;
290
+ cloneImpl(): this;
288
291
  /**
289
292
  * Creates a PdfDocument from a byte stream.
290
293
  *
@@ -17,7 +17,6 @@ import { PdfStartXRef } from '../core/objects/pdf-start-xref.js';
17
17
  import { FoundCompressedObjectError } from './errors.js';
18
18
  import { PdfReader } from './pdf-reader.js';
19
19
  import { PdfSigner } from '../signing/signer.js';
20
- import { PdfXfaManager } from '../xfa/manager.js';
21
20
  import { PdfAcroFormManager } from '../acroform/manager.js';
22
21
  import { PdfFontManager } from '../fonts/font-manager.js';
23
22
  import { concatUint8Arrays } from '../utils/concatUint8Arrays.js';
@@ -45,9 +44,9 @@ export class PdfDocument extends PdfObject {
45
44
  signer;
46
45
  /** Security handler for encryption/decryption operations */
47
46
  securityHandler;
48
- _xfa;
49
- _acroForm;
50
- _fonts;
47
+ /** */
48
+ acroForm;
49
+ fonts;
51
50
  hasEncryptionDictionary = false;
52
51
  toBeCommitted = [];
53
52
  /**
@@ -81,6 +80,8 @@ export class PdfDocument extends PdfObject {
81
80
  this.calculateOffsets();
82
81
  this.securityHandler =
83
82
  options?.securityHandler ?? this.getSecurityHandler();
83
+ this.acroForm = new PdfAcroFormManager(this);
84
+ this.fonts = new PdfFontManager(this);
84
85
  }
85
86
  get header() {
86
87
  return this.revisions[0].header;
@@ -89,27 +90,6 @@ export class PdfDocument extends PdfObject {
89
90
  if (comment)
90
91
  this.revisions[0].header = comment;
91
92
  }
92
- /** XFA manager for handling XFA forms */
93
- get xfa() {
94
- if (!this._xfa) {
95
- this._xfa = new PdfXfaManager(this);
96
- }
97
- return this._xfa;
98
- }
99
- /** AcroForm manager for handling form fields */
100
- get acroForm() {
101
- if (!this._acroForm) {
102
- this._acroForm = new PdfAcroFormManager(this);
103
- }
104
- return this._acroForm;
105
- }
106
- /** Font manager for embedding and managing fonts */
107
- get fonts() {
108
- if (!this._fonts) {
109
- this._fonts = new PdfFontManager(this);
110
- }
111
- return this._fonts;
112
- }
113
93
  /**
114
94
  * Creates a PdfDocument from an array of PDF objects.
115
95
  * Parses objects into revisions based on EOF comments.
@@ -170,6 +150,36 @@ export class PdfDocument extends PdfObject {
170
150
  this.latestRevision.addObject(obj);
171
151
  }
172
152
  }
153
+ /**
154
+ * Packs non-stream indirect objects into compressed ObjStm containers.
155
+ * Objects that already have an object number are left unchanged.
156
+ * Appearance streams and other PdfStream objects must NOT be passed here —
157
+ * only non-stream indirect objects (dictionaries, arrays, etc.) are eligible.
158
+ *
159
+ * @param objects - Non-stream indirect objects to compress into ObjStm
160
+ * @param batchSize - Maximum objects per ObjStm container (default 100)
161
+ */
162
+ addObjectsAsStream(objects, batchSize = 100) {
163
+ if (objects.length === 0)
164
+ return;
165
+ for (let start = 0; start < objects.length; start += batchSize) {
166
+ const batch = objects.slice(start, Math.min(start + batchSize, objects.length));
167
+ // Pre-assign a contiguous block of object numbers for the batch
168
+ const xref = this.latestRevision.xref;
169
+ const startNum = xref.reserveObjectNumbers(batch.length);
170
+ for (let i = 0; i < batch.length; i++) {
171
+ if (!batch[i].inPdf()) {
172
+ batch[i].objectNumber = startNum + i;
173
+ }
174
+ }
175
+ // Build the ObjStm and apply FlateDecode compression
176
+ const objStream = PdfObjStream.fromObjects(batch);
177
+ objStream.addFilter('FlateDecode');
178
+ // Add the container — xref.addObject() auto-registers children as type-2 entries
179
+ const container = new PdfIndirectObject({ content: objStream });
180
+ this.add(container);
181
+ }
182
+ }
173
183
  /**
174
184
  * Gets the latest (most recent) revision of the document.
175
185
  *
@@ -729,7 +739,7 @@ export class PdfDocument extends PdfObject {
729
739
  *
730
740
  * @returns A cloned PdfDocument instance
731
741
  */
732
- clone() {
742
+ cloneImpl() {
733
743
  const clonedRevisions = this.revisions.map((rev) => rev.clone());
734
744
  return new PdfDocument({
735
745
  revisions: clonedRevisions,
@@ -124,7 +124,7 @@ export declare class PdfRevision extends PdfObject {
124
124
  *
125
125
  * @returns A cloned PdfRevision instance
126
126
  */
127
- clone(): this;
127
+ cloneImpl(): this;
128
128
  protected tokenize(): PdfToken[];
129
129
  toBytes(): ByteArray;
130
130
  }
@@ -250,7 +250,7 @@ export class PdfRevision extends PdfObject {
250
250
  *
251
251
  * @returns A cloned PdfRevision instance
252
252
  */
253
- clone() {
253
+ cloneImpl() {
254
254
  const clonedObjects = this.objects.map((obj) => obj.clone());
255
255
  return new PdfRevision({ objects: clonedObjects });
256
256
  }
@@ -110,6 +110,14 @@ export declare class PdfXrefLookup {
110
110
  * @returns The updated xref object
111
111
  */
112
112
  update(): PdfIndirectObject<PdfXRefStream> | PdfXRefTable;
113
+ /**
114
+ * Reserves a contiguous block of object numbers without registering objects.
115
+ * Use this to pre-assign numbers to objects that will live inside an ObjStm.
116
+ *
117
+ * @param count - Number of object numbers to reserve
118
+ * @returns The first reserved object number
119
+ */
120
+ reserveObjectNumbers(count: number): number;
113
121
  /**
114
122
  * Adds an indirect object to the xref lookup.
115
123
  * Assigns an object number if not already set.
@@ -305,6 +305,18 @@ export class PdfXrefLookup {
305
305
  this.object = newObject;
306
306
  return this.object;
307
307
  }
308
+ /**
309
+ * Reserves a contiguous block of object numbers without registering objects.
310
+ * Use this to pre-assign numbers to objects that will live inside an ObjStm.
311
+ *
312
+ * @param count - Number of object numbers to reserve
313
+ * @returns The first reserved object number
314
+ */
315
+ reserveObjectNumbers(count) {
316
+ const startNum = this.size;
317
+ this.size += count;
318
+ return startNum;
319
+ }
308
320
  /**
309
321
  * Adds an indirect object to the xref lookup.
310
322
  * Assigns an object number if not already set.
@@ -87,11 +87,14 @@ export class PdfSecurityHandler {
87
87
  else if (obj instanceof PdfString) {
88
88
  const decryptedData = await this.decrypt('string', obj.raw, objectNumber, generationNumber);
89
89
  obj.raw = decryptedData;
90
+ obj.setModified(false);
90
91
  }
91
92
  else if (obj instanceof PdfStream) {
92
93
  const decryptedData = await this.decrypt('stream', obj.raw, objectNumber, generationNumber);
93
94
  obj.raw = decryptedData;
94
95
  await decryptObject(obj.header);
96
+ obj.setModified(false);
97
+ obj.header.setModified(false);
95
98
  }
96
99
  else if (obj instanceof PdfDictionary) {
97
100
  const values = obj.values;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "pdf-lite",
3
- "version": "1.3.3",
3
+ "version": "1.4.0",
4
4
  "main": "dist/index.js",
5
5
  "type": "module",
6
6
  "exports": {
@@ -1 +0,0 @@
1
- export { PdfXfaManager } from './manager.js';
package/dist/xfa/index.js DELETED
@@ -1 +0,0 @@
1
- export { PdfXfaManager } from './manager.js';
@@ -1,44 +0,0 @@
1
- import { PdfDocument } from '../pdf/pdf-document.js';
2
- /**
3
- * Manages XFA (XML Forms Architecture) forms in PDF documents.
4
- * Provides methods to read and write XFA form data as XML.
5
- */
6
- export declare class PdfXfaManager {
7
- private document;
8
- private _datasetsStream?;
9
- constructor(document: PdfDocument);
10
- /**
11
- * Checks if the document contains XFA forms.
12
- * @returns True if the document has XFA forms, false otherwise
13
- */
14
- hasXfaForms(): Promise<boolean>;
15
- /**
16
- * Reads the XFA form data as XML string.
17
- * @returns The XFA datasets XML content, or null if no XFA form exists
18
- */
19
- readXml(): Promise<string | null>;
20
- /**
21
- * Writes XML content to the XFA datasets stream.
22
- * @param xml The XML content to write
23
- * @throws Error if the document doesn't have XFA forms
24
- */
25
- writeXml(xml: string): Promise<void>;
26
- /**
27
- * Gets the AcroForm dictionary from the document catalog.
28
- * @returns The AcroForm dictionary or null if not found
29
- */
30
- private getAcroForm;
31
- /**
32
- * Gets the XFA datasets stream.
33
- * Caches the stream for subsequent calls to preserve modifications.
34
- * @returns The datasets stream or null if not found
35
- */
36
- private getDatasetsStream;
37
- /**
38
- * Finds the XFA dataset object reference from the XFA array.
39
- * XFA array structure: [(name1) ref1 (name2) ref2 ...]
40
- * @param xfaArray The XFA array from the AcroForm
41
- * @returns The object reference to the datasets stream, or null if not found
42
- */
43
- private findXfaDatasetReference;
44
- }
@@ -1,136 +0,0 @@
1
- import { PdfStream } from '../core/objects/pdf-stream.js';
2
- import { PdfDictionary } from '../core/objects/pdf-dictionary.js';
3
- import { PdfArray } from '../core/objects/pdf-array.js';
4
- import { PdfString } from '../core/objects/pdf-string.js';
5
- import { PdfObjectReference } from '../core/objects/pdf-object-reference.js';
6
- import { PdfIndirectObject } from '../core/index.js';
7
- /**
8
- * Manages XFA (XML Forms Architecture) forms in PDF documents.
9
- * Provides methods to read and write XFA form data as XML.
10
- */
11
- export class PdfXfaManager {
12
- document;
13
- _datasetsStream;
14
- constructor(document) {
15
- this.document = document;
16
- }
17
- /**
18
- * Checks if the document contains XFA forms.
19
- * @returns True if the document has XFA forms, false otherwise
20
- */
21
- async hasXfaForms() {
22
- try {
23
- const stream = await this.getDatasetsStream();
24
- return stream !== null;
25
- }
26
- catch {
27
- return false;
28
- }
29
- }
30
- /**
31
- * Reads the XFA form data as XML string.
32
- * @returns The XFA datasets XML content, or null if no XFA form exists
33
- */
34
- async readXml() {
35
- const stream = await this.getDatasetsStream();
36
- if (!stream)
37
- return null;
38
- // Get decompressed data without modifying the original stream
39
- const decompressed = stream.content.decode();
40
- // Return the raw XML content as string
41
- const decoder = new TextDecoder();
42
- return decoder.decode(decompressed);
43
- }
44
- /**
45
- * Writes XML content to the XFA datasets stream.
46
- * @param xml The XML content to write
47
- * @throws Error if the document doesn't have XFA forms
48
- */
49
- async writeXml(xml) {
50
- const stream = await this.getDatasetsStream();
51
- if (!stream) {
52
- throw new Error('Document does not contain XFA forms');
53
- }
54
- // Update the cached stream directly with the new XML content
55
- const datasetsIndirect = new PdfIndirectObject({
56
- ...stream,
57
- content: PdfStream.fromString(xml),
58
- });
59
- const isIncremental = this.document.isIncremental();
60
- this.document.setIncremental(true);
61
- await this.document.commit(datasetsIndirect);
62
- this.document.setIncremental(isIncremental);
63
- // Reset cached stream to force re-fetch if needed
64
- this._datasetsStream = undefined;
65
- }
66
- /**
67
- * Gets the AcroForm dictionary from the document catalog.
68
- * @returns The AcroForm dictionary or null if not found
69
- */
70
- async getAcroForm() {
71
- const catalog = this.document.root;
72
- const acroFormRef = catalog.content.get('AcroForm');
73
- if (!acroFormRef)
74
- return null;
75
- if (acroFormRef instanceof PdfObjectReference) {
76
- const acroFormObject = await this.document.readObject({
77
- objectNumber: acroFormRef.objectNumber,
78
- generationNumber: acroFormRef.generationNumber,
79
- });
80
- if (!acroFormObject)
81
- return null;
82
- return acroFormObject.content.as(PdfDictionary);
83
- }
84
- else if (acroFormRef instanceof PdfDictionary) {
85
- return acroFormRef;
86
- }
87
- return null;
88
- }
89
- /**
90
- * Gets the XFA datasets stream.
91
- * Caches the stream for subsequent calls to preserve modifications.
92
- * @returns The datasets stream or null if not found
93
- */
94
- async getDatasetsStream() {
95
- if (this._datasetsStream) {
96
- return this._datasetsStream;
97
- }
98
- const acroForm = await this.getAcroForm();
99
- if (!acroForm)
100
- return null;
101
- const xfaArray = acroForm.get('XFA');
102
- if (!(xfaArray instanceof PdfArray))
103
- return null;
104
- const datasetsRef = this.findXfaDatasetReference(xfaArray);
105
- if (!datasetsRef)
106
- return null;
107
- const datasetObject = await this.document.readObject({
108
- objectNumber: datasetsRef.objectNumber,
109
- generationNumber: datasetsRef.generationNumber,
110
- allowUnindexed: true,
111
- });
112
- if (!datasetObject)
113
- return null;
114
- return datasetObject;
115
- }
116
- /**
117
- * Finds the XFA dataset object reference from the XFA array.
118
- * XFA array structure: [(name1) ref1 (name2) ref2 ...]
119
- * @param xfaArray The XFA array from the AcroForm
120
- * @returns The object reference to the datasets stream, or null if not found
121
- */
122
- findXfaDatasetReference(xfaArray) {
123
- const items = xfaArray.items;
124
- // XFA array alternates between name strings and object references
125
- for (let i = 0; i < items.length - 1; i += 2) {
126
- const name = items[i];
127
- const ref = items[i + 1];
128
- if (name instanceof PdfString && name.value === 'datasets') {
129
- if (ref instanceof PdfObjectReference) {
130
- return ref;
131
- }
132
- }
133
- }
134
- return null;
135
- }
136
- }