@cj-tech-master/excelts 8.0.0 → 8.1.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.
- package/README.md +14 -1
- package/README_zh.md +6 -0
- package/dist/browser/modules/archive/zip/stream.d.ts +4 -0
- package/dist/browser/modules/archive/zip/stream.js +53 -0
- package/dist/browser/modules/pdf/core/crypto.d.ts +65 -0
- package/dist/browser/modules/pdf/core/crypto.js +637 -0
- package/dist/browser/modules/pdf/core/encryption.d.ts +23 -20
- package/dist/browser/modules/pdf/core/encryption.js +88 -261
- package/dist/browser/modules/pdf/core/pdf-writer.d.ts +6 -4
- package/dist/browser/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/browser/modules/pdf/index.d.ts +23 -2
- package/dist/browser/modules/pdf/index.js +21 -3
- package/dist/browser/modules/pdf/reader/annotation-extractor.d.ts +63 -0
- package/dist/browser/modules/pdf/reader/annotation-extractor.js +155 -0
- package/dist/browser/modules/pdf/reader/cmap-parser.d.ts +70 -0
- package/dist/browser/modules/pdf/reader/cmap-parser.js +321 -0
- package/dist/browser/modules/pdf/reader/content-interpreter.d.ts +57 -0
- package/dist/browser/modules/pdf/reader/content-interpreter.js +715 -0
- package/dist/browser/modules/pdf/reader/font-decoder.d.ts +58 -0
- package/dist/browser/modules/pdf/reader/font-decoder.js +1513 -0
- package/dist/browser/modules/pdf/reader/form-extractor.d.ts +48 -0
- package/dist/browser/modules/pdf/reader/form-extractor.js +355 -0
- package/dist/browser/modules/pdf/reader/image-extractor.d.ts +55 -0
- package/dist/browser/modules/pdf/reader/image-extractor.js +220 -0
- package/dist/browser/modules/pdf/reader/metadata-reader.d.ts +56 -0
- package/dist/browser/modules/pdf/reader/metadata-reader.js +275 -0
- package/dist/browser/modules/pdf/reader/pdf-decrypt.d.ts +26 -0
- package/dist/browser/modules/pdf/reader/pdf-decrypt.js +443 -0
- package/dist/browser/modules/pdf/reader/pdf-document.d.ts +191 -0
- package/dist/browser/modules/pdf/reader/pdf-document.js +818 -0
- package/dist/browser/modules/pdf/reader/pdf-parser.d.ts +65 -0
- package/dist/browser/modules/pdf/reader/pdf-parser.js +285 -0
- package/dist/browser/modules/pdf/reader/pdf-reader.d.ts +143 -0
- package/dist/browser/modules/pdf/reader/pdf-reader.js +200 -0
- package/dist/browser/modules/pdf/reader/pdf-tokenizer.d.ts +101 -0
- package/dist/browser/modules/pdf/reader/pdf-tokenizer.js +543 -0
- package/dist/browser/modules/pdf/reader/reader-utils.d.ts +15 -0
- package/dist/browser/modules/pdf/reader/reader-utils.js +27 -0
- package/dist/browser/modules/pdf/reader/stream-filters.d.ts +20 -0
- package/dist/browser/modules/pdf/reader/stream-filters.js +456 -0
- package/dist/browser/modules/pdf/reader/text-reconstruction.d.ts +44 -0
- package/dist/browser/modules/pdf/reader/text-reconstruction.js +463 -0
- package/dist/cjs/modules/archive/zip/stream.js +53 -0
- package/dist/cjs/modules/pdf/core/crypto.js +649 -0
- package/dist/cjs/modules/pdf/core/encryption.js +88 -263
- package/dist/cjs/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/cjs/modules/pdf/index.js +23 -4
- package/dist/cjs/modules/pdf/reader/annotation-extractor.js +158 -0
- package/dist/cjs/modules/pdf/reader/cmap-parser.js +326 -0
- package/dist/cjs/modules/pdf/reader/content-interpreter.js +718 -0
- package/dist/cjs/modules/pdf/reader/font-decoder.js +1518 -0
- package/dist/cjs/modules/pdf/reader/form-extractor.js +358 -0
- package/dist/cjs/modules/pdf/reader/image-extractor.js +223 -0
- package/dist/cjs/modules/pdf/reader/metadata-reader.js +278 -0
- package/dist/cjs/modules/pdf/reader/pdf-decrypt.js +447 -0
- package/dist/cjs/modules/pdf/reader/pdf-document.js +822 -0
- package/dist/cjs/modules/pdf/reader/pdf-parser.js +301 -0
- package/dist/cjs/modules/pdf/reader/pdf-reader.js +203 -0
- package/dist/cjs/modules/pdf/reader/pdf-tokenizer.js +517 -0
- package/dist/cjs/modules/pdf/reader/reader-utils.js +30 -0
- package/dist/cjs/modules/pdf/reader/stream-filters.js +459 -0
- package/dist/cjs/modules/pdf/reader/text-reconstruction.js +467 -0
- package/dist/esm/modules/archive/zip/stream.js +53 -0
- package/dist/esm/modules/pdf/core/crypto.js +637 -0
- package/dist/esm/modules/pdf/core/encryption.js +88 -261
- package/dist/esm/modules/pdf/core/pdf-writer.js +19 -10
- package/dist/esm/modules/pdf/index.js +21 -3
- package/dist/esm/modules/pdf/reader/annotation-extractor.js +155 -0
- package/dist/esm/modules/pdf/reader/cmap-parser.js +321 -0
- package/dist/esm/modules/pdf/reader/content-interpreter.js +715 -0
- package/dist/esm/modules/pdf/reader/font-decoder.js +1513 -0
- package/dist/esm/modules/pdf/reader/form-extractor.js +355 -0
- package/dist/esm/modules/pdf/reader/image-extractor.js +220 -0
- package/dist/esm/modules/pdf/reader/metadata-reader.js +275 -0
- package/dist/esm/modules/pdf/reader/pdf-decrypt.js +443 -0
- package/dist/esm/modules/pdf/reader/pdf-document.js +818 -0
- package/dist/esm/modules/pdf/reader/pdf-parser.js +285 -0
- package/dist/esm/modules/pdf/reader/pdf-reader.js +200 -0
- package/dist/esm/modules/pdf/reader/pdf-tokenizer.js +543 -0
- package/dist/esm/modules/pdf/reader/reader-utils.js +27 -0
- package/dist/esm/modules/pdf/reader/stream-filters.js +456 -0
- package/dist/esm/modules/pdf/reader/text-reconstruction.js +463 -0
- package/dist/iife/excelts.iife.js +703 -267
- package/dist/iife/excelts.iife.js.map +1 -1
- package/dist/iife/excelts.iife.min.js +35 -35
- package/dist/types/modules/archive/zip/stream.d.ts +4 -0
- package/dist/types/modules/pdf/core/crypto.d.ts +65 -0
- package/dist/types/modules/pdf/core/encryption.d.ts +23 -20
- package/dist/types/modules/pdf/core/pdf-writer.d.ts +6 -4
- package/dist/types/modules/pdf/index.d.ts +23 -2
- package/dist/types/modules/pdf/reader/annotation-extractor.d.ts +63 -0
- package/dist/types/modules/pdf/reader/cmap-parser.d.ts +70 -0
- package/dist/types/modules/pdf/reader/content-interpreter.d.ts +57 -0
- package/dist/types/modules/pdf/reader/font-decoder.d.ts +58 -0
- package/dist/types/modules/pdf/reader/form-extractor.d.ts +48 -0
- package/dist/types/modules/pdf/reader/image-extractor.d.ts +55 -0
- package/dist/types/modules/pdf/reader/metadata-reader.d.ts +56 -0
- package/dist/types/modules/pdf/reader/pdf-decrypt.d.ts +26 -0
- package/dist/types/modules/pdf/reader/pdf-document.d.ts +191 -0
- package/dist/types/modules/pdf/reader/pdf-parser.d.ts +65 -0
- package/dist/types/modules/pdf/reader/pdf-reader.d.ts +143 -0
- package/dist/types/modules/pdf/reader/pdf-tokenizer.d.ts +101 -0
- package/dist/types/modules/pdf/reader/reader-utils.d.ts +15 -0
- package/dist/types/modules/pdf/reader/stream-filters.d.ts +20 -0
- package/dist/types/modules/pdf/reader/text-reconstruction.d.ts +44 -0
- package/package.json +1 -1
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF metadata reader.
|
|
3
|
+
*
|
|
4
|
+
* Extracts document metadata from:
|
|
5
|
+
* 1. Info Dictionary (traditional metadata)
|
|
6
|
+
* - Title, Author, Subject, Keywords, Creator, Producer
|
|
7
|
+
* - CreationDate, ModDate
|
|
8
|
+
*
|
|
9
|
+
* 2. XMP Metadata Stream (XML-based, more comprehensive)
|
|
10
|
+
* - All of the above plus:
|
|
11
|
+
* - Dublin Core metadata, custom properties
|
|
12
|
+
*
|
|
13
|
+
* @see PDF Reference 1.7, §10.2 - Metadata
|
|
14
|
+
* @see XMP Specification Part 1
|
|
15
|
+
*/
|
|
16
|
+
import type { PdfDocument } from "./pdf-document.js";
|
|
17
|
+
/**
|
|
18
|
+
* PDF document metadata.
|
|
19
|
+
*/
|
|
20
|
+
export interface PdfMetadata {
|
|
21
|
+
/** Document title */
|
|
22
|
+
title: string;
|
|
23
|
+
/** Document author */
|
|
24
|
+
author: string;
|
|
25
|
+
/** Document subject */
|
|
26
|
+
subject: string;
|
|
27
|
+
/** Document keywords */
|
|
28
|
+
keywords: string;
|
|
29
|
+
/** Application that created the original document */
|
|
30
|
+
creator: string;
|
|
31
|
+
/** Application that produced the PDF */
|
|
32
|
+
producer: string;
|
|
33
|
+
/** Date the document was created */
|
|
34
|
+
creationDate: Date | null;
|
|
35
|
+
/** Date the document was last modified */
|
|
36
|
+
modDate: Date | null;
|
|
37
|
+
/** PDF version */
|
|
38
|
+
pdfVersion: string;
|
|
39
|
+
/** Number of pages */
|
|
40
|
+
pageCount: number;
|
|
41
|
+
/** Whether the document is encrypted */
|
|
42
|
+
encrypted: boolean;
|
|
43
|
+
/** Page size of the first page (in points) */
|
|
44
|
+
pageSize: {
|
|
45
|
+
width: number;
|
|
46
|
+
height: number;
|
|
47
|
+
} | null;
|
|
48
|
+
/** Raw XMP metadata XML (if available) */
|
|
49
|
+
xmpXml: string | null;
|
|
50
|
+
/** Additional custom metadata from Info dictionary */
|
|
51
|
+
custom: Record<string, string>;
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Extract metadata from a PDF document.
|
|
55
|
+
*/
|
|
56
|
+
export declare function extractMetadata(doc: PdfDocument): PdfMetadata;
|
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF metadata reader.
|
|
3
|
+
*
|
|
4
|
+
* Extracts document metadata from:
|
|
5
|
+
* 1. Info Dictionary (traditional metadata)
|
|
6
|
+
* - Title, Author, Subject, Keywords, Creator, Producer
|
|
7
|
+
* - CreationDate, ModDate
|
|
8
|
+
*
|
|
9
|
+
* 2. XMP Metadata Stream (XML-based, more comprehensive)
|
|
10
|
+
* - All of the above plus:
|
|
11
|
+
* - Dublin Core metadata, custom properties
|
|
12
|
+
*
|
|
13
|
+
* @see PDF Reference 1.7, §10.2 - Metadata
|
|
14
|
+
* @see XMP Specification Part 1
|
|
15
|
+
*/
|
|
16
|
+
import { dictGetRef, decodePdfStringBytes } from "./pdf-parser.js";
|
|
17
|
+
// =============================================================================
|
|
18
|
+
// Public API
|
|
19
|
+
// =============================================================================
|
|
20
|
+
/**
|
|
21
|
+
* Extract metadata from a PDF document.
|
|
22
|
+
*/
|
|
23
|
+
export function extractMetadata(doc) {
|
|
24
|
+
const metadata = {
|
|
25
|
+
title: "",
|
|
26
|
+
author: "",
|
|
27
|
+
subject: "",
|
|
28
|
+
keywords: "",
|
|
29
|
+
creator: "",
|
|
30
|
+
producer: "",
|
|
31
|
+
creationDate: null,
|
|
32
|
+
modDate: null,
|
|
33
|
+
pdfVersion: extractPdfVersion(doc),
|
|
34
|
+
pageCount: 0,
|
|
35
|
+
encrypted: doc.trailer.has("Encrypt"),
|
|
36
|
+
pageSize: null,
|
|
37
|
+
xmpXml: null,
|
|
38
|
+
custom: {}
|
|
39
|
+
};
|
|
40
|
+
// Extract from Info dictionary
|
|
41
|
+
extractInfoDict(doc, metadata);
|
|
42
|
+
// Extract from XMP metadata stream
|
|
43
|
+
extractXmpMetadata(doc, metadata);
|
|
44
|
+
// Get page count and first page size
|
|
45
|
+
try {
|
|
46
|
+
const pages = doc.getPages();
|
|
47
|
+
metadata.pageCount = pages.length;
|
|
48
|
+
if (pages.length > 0) {
|
|
49
|
+
metadata.pageSize = extractPageSize(pages[0], doc);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
// Ignore page tree errors
|
|
54
|
+
}
|
|
55
|
+
return metadata;
|
|
56
|
+
}
|
|
57
|
+
// =============================================================================
|
|
58
|
+
// PDF Version
|
|
59
|
+
// =============================================================================
|
|
60
|
+
function extractPdfVersion(doc) {
|
|
61
|
+
const data = doc.data;
|
|
62
|
+
// First line: %PDF-X.Y
|
|
63
|
+
if (data[0] === 0x25 &&
|
|
64
|
+
data[1] === 0x50 &&
|
|
65
|
+
data[2] === 0x44 &&
|
|
66
|
+
data[3] === 0x46 &&
|
|
67
|
+
data[4] === 0x2d) {
|
|
68
|
+
let version = "";
|
|
69
|
+
for (let i = 5; i < Math.min(data.length, 15); i++) {
|
|
70
|
+
const b = data[i];
|
|
71
|
+
if (b === 0x0a || b === 0x0d || b === 0x20) {
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
version += String.fromCharCode(b);
|
|
75
|
+
}
|
|
76
|
+
return version;
|
|
77
|
+
}
|
|
78
|
+
// Check catalog /Version
|
|
79
|
+
try {
|
|
80
|
+
const catalog = doc.getCatalog();
|
|
81
|
+
const version = catalog.get("Version");
|
|
82
|
+
if (typeof version === "string") {
|
|
83
|
+
return version;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// Ignore
|
|
88
|
+
}
|
|
89
|
+
return "1.0";
|
|
90
|
+
}
|
|
91
|
+
// =============================================================================
|
|
92
|
+
// Info Dictionary
|
|
93
|
+
// =============================================================================
|
|
94
|
+
function extractInfoDict(doc, metadata) {
|
|
95
|
+
const infoRef = dictGetRef(doc.trailer, "Info");
|
|
96
|
+
if (!infoRef) {
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const infoDict = doc.derefDict(infoRef);
|
|
100
|
+
if (!infoDict) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const knownKeys = new Set([
|
|
104
|
+
"Title",
|
|
105
|
+
"Author",
|
|
106
|
+
"Subject",
|
|
107
|
+
"Keywords",
|
|
108
|
+
"Creator",
|
|
109
|
+
"Producer",
|
|
110
|
+
"CreationDate",
|
|
111
|
+
"ModDate"
|
|
112
|
+
]);
|
|
113
|
+
for (const [key, value] of infoDict) {
|
|
114
|
+
const strValue = value instanceof Uint8Array ? decodePdfStringBytes(value) : String(value ?? "");
|
|
115
|
+
switch (key) {
|
|
116
|
+
case "Title":
|
|
117
|
+
metadata.title = strValue;
|
|
118
|
+
break;
|
|
119
|
+
case "Author":
|
|
120
|
+
metadata.author = strValue;
|
|
121
|
+
break;
|
|
122
|
+
case "Subject":
|
|
123
|
+
metadata.subject = strValue;
|
|
124
|
+
break;
|
|
125
|
+
case "Keywords":
|
|
126
|
+
metadata.keywords = strValue;
|
|
127
|
+
break;
|
|
128
|
+
case "Creator":
|
|
129
|
+
metadata.creator = strValue;
|
|
130
|
+
break;
|
|
131
|
+
case "Producer":
|
|
132
|
+
metadata.producer = strValue;
|
|
133
|
+
break;
|
|
134
|
+
case "CreationDate":
|
|
135
|
+
metadata.creationDate = parsePdfDate(strValue);
|
|
136
|
+
break;
|
|
137
|
+
case "ModDate":
|
|
138
|
+
metadata.modDate = parsePdfDate(strValue);
|
|
139
|
+
break;
|
|
140
|
+
default:
|
|
141
|
+
if (!knownKeys.has(key)) {
|
|
142
|
+
metadata.custom[key] = strValue;
|
|
143
|
+
}
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
// =============================================================================
|
|
149
|
+
// XMP Metadata
|
|
150
|
+
// =============================================================================
|
|
151
|
+
function extractXmpMetadata(doc, metadata) {
|
|
152
|
+
try {
|
|
153
|
+
const catalog = doc.getCatalog();
|
|
154
|
+
const metadataRef = catalog.get("Metadata");
|
|
155
|
+
if (!metadataRef) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
const result = doc.derefStreamWithObjNum(metadataRef);
|
|
159
|
+
if (!result) {
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
const data = doc.getStreamData(result.stream, result.objNum, result.gen);
|
|
163
|
+
const xml = new TextDecoder("utf-8").decode(data);
|
|
164
|
+
metadata.xmpXml = xml;
|
|
165
|
+
// Parse key fields from XMP
|
|
166
|
+
if (!metadata.title) {
|
|
167
|
+
metadata.title = extractXmpField(xml, "dc:title") ?? "";
|
|
168
|
+
}
|
|
169
|
+
if (!metadata.author) {
|
|
170
|
+
metadata.author = extractXmpField(xml, "dc:creator") ?? "";
|
|
171
|
+
}
|
|
172
|
+
if (!metadata.subject) {
|
|
173
|
+
metadata.subject = extractXmpField(xml, "dc:description") ?? "";
|
|
174
|
+
}
|
|
175
|
+
if (!metadata.keywords) {
|
|
176
|
+
metadata.keywords = extractXmpField(xml, "pdf:Keywords") ?? "";
|
|
177
|
+
}
|
|
178
|
+
if (!metadata.creator) {
|
|
179
|
+
metadata.creator = extractXmpField(xml, "xmp:CreatorTool") ?? "";
|
|
180
|
+
}
|
|
181
|
+
if (!metadata.producer) {
|
|
182
|
+
metadata.producer = extractXmpField(xml, "pdf:Producer") ?? "";
|
|
183
|
+
}
|
|
184
|
+
if (!metadata.creationDate) {
|
|
185
|
+
const dateStr = extractXmpField(xml, "xmp:CreateDate");
|
|
186
|
+
if (dateStr) {
|
|
187
|
+
metadata.creationDate = new Date(dateStr);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
if (!metadata.modDate) {
|
|
191
|
+
const dateStr = extractXmpField(xml, "xmp:ModifyDate");
|
|
192
|
+
if (dateStr) {
|
|
193
|
+
metadata.modDate = new Date(dateStr);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
catch {
|
|
198
|
+
// Ignore XMP errors
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Extract a field value from XMP XML using simple regex.
|
|
203
|
+
* Handles both simple elements and rdf:Alt/rdf:Bag/rdf:Seq containers.
|
|
204
|
+
*/
|
|
205
|
+
function extractXmpField(xml, field) {
|
|
206
|
+
// Try simple element: <field>value</field>
|
|
207
|
+
const simpleRegex = new RegExp(`<${field}[^>]*>([^<]+)</${field}>`, "i");
|
|
208
|
+
const simpleMatch = simpleRegex.exec(xml);
|
|
209
|
+
if (simpleMatch) {
|
|
210
|
+
return decodeXmlEntities(simpleMatch[1].trim());
|
|
211
|
+
}
|
|
212
|
+
// Try rdf:Alt/rdf:Bag/rdf:Seq container: <field>...<rdf:li>value</rdf:li>...</field>
|
|
213
|
+
const containerRegex = new RegExp(`<${field}[^>]*>.*?<rdf:li[^>]*>([^<]+)</rdf:li>`, "is");
|
|
214
|
+
const containerMatch = containerRegex.exec(xml);
|
|
215
|
+
if (containerMatch) {
|
|
216
|
+
return decodeXmlEntities(containerMatch[1].trim());
|
|
217
|
+
}
|
|
218
|
+
return null;
|
|
219
|
+
}
|
|
220
|
+
function decodeXmlEntities(text) {
|
|
221
|
+
return text
|
|
222
|
+
.replace(/&/g, "&")
|
|
223
|
+
.replace(/</g, "<")
|
|
224
|
+
.replace(/>/g, ">")
|
|
225
|
+
.replace(/"/g, '"')
|
|
226
|
+
.replace(/'/g, "'");
|
|
227
|
+
}
|
|
228
|
+
// =============================================================================
|
|
229
|
+
// Page Size
|
|
230
|
+
// =============================================================================
|
|
231
|
+
function extractPageSize(pageDict, doc) {
|
|
232
|
+
return doc.resolvePageBox(pageDict);
|
|
233
|
+
}
|
|
234
|
+
// =============================================================================
|
|
235
|
+
// PDF Date Parsing
|
|
236
|
+
// =============================================================================
|
|
237
|
+
/**
|
|
238
|
+
* Parse a PDF date string to a Date object.
|
|
239
|
+
* Format: D:YYYYMMDDHHmmSSOHH'mm
|
|
240
|
+
*/
|
|
241
|
+
function parsePdfDate(dateStr) {
|
|
242
|
+
if (!dateStr) {
|
|
243
|
+
return null;
|
|
244
|
+
}
|
|
245
|
+
// Remove leading "D:" if present
|
|
246
|
+
let s = dateStr;
|
|
247
|
+
if (s.startsWith("D:")) {
|
|
248
|
+
s = s.substring(2);
|
|
249
|
+
}
|
|
250
|
+
// Parse components
|
|
251
|
+
const year = parseInt(s.substring(0, 4), 10);
|
|
252
|
+
if (isNaN(year)) {
|
|
253
|
+
return null;
|
|
254
|
+
}
|
|
255
|
+
const month = parseInt(s.substring(4, 6), 10) || 1;
|
|
256
|
+
const day = parseInt(s.substring(6, 8), 10) || 1;
|
|
257
|
+
const hour = parseInt(s.substring(8, 10), 10) || 0;
|
|
258
|
+
const minute = parseInt(s.substring(10, 12), 10) || 0;
|
|
259
|
+
const second = parseInt(s.substring(12, 14), 10) || 0;
|
|
260
|
+
// Parse timezone
|
|
261
|
+
const tzChar = s.charAt(14);
|
|
262
|
+
let offsetMinutes = 0;
|
|
263
|
+
if (tzChar === "+" || tzChar === "-") {
|
|
264
|
+
const tzHour = parseInt(s.substring(15, 17), 10) || 0;
|
|
265
|
+
const tzMin = parseInt(s.substring(18, 20), 10) || 0;
|
|
266
|
+
offsetMinutes = (tzHour * 60 + tzMin) * (tzChar === "-" ? -1 : 1);
|
|
267
|
+
}
|
|
268
|
+
// Create Date in UTC
|
|
269
|
+
const date = new Date(Date.UTC(year, month - 1, day, hour, minute, second));
|
|
270
|
+
// Apply timezone offset
|
|
271
|
+
if (offsetMinutes !== 0 && tzChar !== "Z") {
|
|
272
|
+
date.setUTCMinutes(date.getUTCMinutes() - offsetMinutes);
|
|
273
|
+
}
|
|
274
|
+
return isNaN(date.getTime()) ? null : date;
|
|
275
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PDF decryption for reading encrypted PDFs.
|
|
3
|
+
*
|
|
4
|
+
* Supports:
|
|
5
|
+
* - Standard Security Handler (V1/V2/V4/V5, R2/R3/R4/R5)
|
|
6
|
+
* - RC4 encryption (40-bit and 128-bit)
|
|
7
|
+
* - AES-128 encryption (PDF 1.6+)
|
|
8
|
+
* - AES-256 encryption (PDF 2.0, V=5, R=5)
|
|
9
|
+
*
|
|
10
|
+
* @see PDF Reference 1.7, §3.5 - Encryption
|
|
11
|
+
* @see PDF 2.0 (ISO 32000-2), §7.6 - Encryption
|
|
12
|
+
*/
|
|
13
|
+
import type { PdfDocument } from "./pdf-document.js";
|
|
14
|
+
/**
|
|
15
|
+
* Initialize decryption for a PDF document.
|
|
16
|
+
* Returns true if decryption was successfully initialized, false if
|
|
17
|
+
* the password was incorrect.
|
|
18
|
+
*
|
|
19
|
+
* @param doc - The PDF document
|
|
20
|
+
* @param password - User or owner password (empty string for no password)
|
|
21
|
+
*/
|
|
22
|
+
export declare function initDecryption(doc: PdfDocument, password?: string): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Check if the document is encrypted.
|
|
25
|
+
*/
|
|
26
|
+
export declare function isEncrypted(doc: PdfDocument): boolean;
|