@embedpdf/core-acrojs 3.0.0-next.10 → 3.0.0-next.12

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.cjs CHANGED
@@ -8,7 +8,7 @@ function javaScriptSourcesFromActionTree(tree) {
8
8
  if (tree.incomplete) throw new Error("Refusing to execute an incomplete PDF action tree");
9
9
  const sources = [];
10
10
  const visit = (node) => {
11
- if (node.type === "javascript" && node.script !== void 0) sources.push(node.script);
11
+ if (node.type === "javascript") sources.push(node.script);
12
12
  for (const child of node.next) visit(child);
13
13
  };
14
14
  if (tree.root) visit(tree.root);
@@ -19,6 +19,324 @@ function javaScriptProgramFromActionTree(tree) {
19
19
  return javaScriptSourcesFromActionTree(tree).join("\n;\n");
20
20
  }
21
21
  //#endregion
22
+ //#region src/color.ts
23
+ /**
24
+ * Host-side Acrobat color-array conversions — the commit sinks and world
25
+ * builders cross the Acrobat-array ↔ renderer-color boundary through these.
26
+ * The PRELUDE inlines its own identical formulas (it must stay
27
+ * self-contained); `prelude.test.ts` pins the two implementations together.
28
+ *
29
+ * Conversion vectors (the documented Acrobat semantics):
30
+ * G → RGB: replicate the gray component.
31
+ * CMYK → RGB: component = 1 − min(1, channel + k).
32
+ * RGB → G: luminosity 0.3r + 0.59g + 0.11b.
33
+ * RGB → CMYK: k = 1 − max(r,g,b); channels = 1 − component − k.
34
+ * T (transparent) converts to itself only.
35
+ */
36
+ function scriptColorToRgb(color) {
37
+ switch (color[0]) {
38
+ case "T": return null;
39
+ case "G": return {
40
+ r: color[1],
41
+ g: color[1],
42
+ b: color[1]
43
+ };
44
+ case "RGB": return {
45
+ r: color[1],
46
+ g: color[2],
47
+ b: color[3]
48
+ };
49
+ case "CMYK": {
50
+ const [, c, m, y, k] = color;
51
+ return {
52
+ r: 1 - Math.min(1, c + k),
53
+ g: 1 - Math.min(1, m + k),
54
+ b: 1 - Math.min(1, y + k)
55
+ };
56
+ }
57
+ }
58
+ }
59
+ const clamp01 = (value) => Math.min(1, Math.max(0, value));
60
+ const hex = (value) => Math.round(clamp01(value) * 255).toString(16).padStart(2, "0");
61
+ /** Acrobat array → CSS hex, or null for transparent. */
62
+ function scriptColorToCss(color) {
63
+ const rgb = scriptColorToRgb(color);
64
+ return rgb === null ? null : `#${hex(rgb.r)}${hex(rgb.g)}${hex(rgb.b)}`;
65
+ }
66
+ /** CSS hex (#rgb/#rrggbb) → Acrobat RGB array; null/undefined → transparent. */
67
+ function cssToScriptColor(css) {
68
+ if (!css) return ["T"];
69
+ const raw = css.trim().replace(/^#/, "");
70
+ const long = raw.length === 3 ? raw.split("").map((ch) => ch + ch).join("") : raw;
71
+ if (!/^[0-9a-fA-F]{6}$/.test(long)) return ["T"];
72
+ const channel = (offset) => parseInt(long.slice(offset, offset + 2), 16) / 255;
73
+ return [
74
+ "RGB",
75
+ channel(0),
76
+ channel(2),
77
+ channel(4)
78
+ ];
79
+ }
80
+ /** Structural validation for values scripts assign. */
81
+ function isScriptColorArray(value) {
82
+ if (!Array.isArray(value) || value.length === 0) return false;
83
+ const [space, ...parts] = value;
84
+ const expected = {
85
+ T: 0,
86
+ G: 1,
87
+ RGB: 3,
88
+ CMYK: 4
89
+ }[String(space)];
90
+ return expected !== void 0 && parts.length === expected && parts.every((part) => typeof part === "number" && Number.isFinite(part));
91
+ }
92
+ //#endregion
93
+ //#region src/types.ts
94
+ /**
95
+ * The writable-property validity matrix, keyed by engine subtype — the ONE
96
+ * exported table (the prelude inlines an identical copy; a parity test pins
97
+ * them together, and plugin-annotation drift-guards this against the kind
98
+ * registry's PropSpecs). Flags + contents are writable everywhere
99
+ * script-addressable; appearance keys vary by kind.
100
+ */
101
+ const ANNOT_WRITABLE_KEYS = Object.freeze({
102
+ square: [
103
+ "strokeColor",
104
+ "fillColor",
105
+ "opacity",
106
+ "width",
107
+ "borderStyle",
108
+ "dash",
109
+ "rect"
110
+ ],
111
+ circle: [
112
+ "strokeColor",
113
+ "fillColor",
114
+ "opacity",
115
+ "width",
116
+ "borderStyle",
117
+ "dash",
118
+ "rect"
119
+ ],
120
+ polygon: [
121
+ "strokeColor",
122
+ "fillColor",
123
+ "opacity",
124
+ "width",
125
+ "borderStyle",
126
+ "dash",
127
+ "rect"
128
+ ],
129
+ polyline: [
130
+ "strokeColor",
131
+ "fillColor",
132
+ "opacity",
133
+ "width",
134
+ "borderStyle",
135
+ "dash",
136
+ "rect"
137
+ ],
138
+ line: [
139
+ "strokeColor",
140
+ "fillColor",
141
+ "opacity",
142
+ "width",
143
+ "borderStyle",
144
+ "dash",
145
+ "rect"
146
+ ],
147
+ ink: [
148
+ "strokeColor",
149
+ "opacity",
150
+ "width",
151
+ "rect"
152
+ ],
153
+ "free-text": [
154
+ "strokeColor",
155
+ "fillColor",
156
+ "opacity",
157
+ "rect"
158
+ ],
159
+ highlight: ["strokeColor", "opacity"],
160
+ underline: ["strokeColor", "opacity"],
161
+ squiggly: ["strokeColor", "opacity"],
162
+ strikeout: ["strokeColor", "opacity"],
163
+ caret: ["strokeColor", "opacity"],
164
+ text: [
165
+ "strokeColor",
166
+ "opacity",
167
+ "rect"
168
+ ],
169
+ stamp: ["rect"],
170
+ "file-attachment": ["strokeColor", "opacity"]
171
+ });
172
+ const DEFAULT_SCRIPT_BUDGET = Object.freeze({
173
+ maxExecutionMs: 50,
174
+ maxMemoryBytes: 16 * 1024 * 1024,
175
+ maxStackBytes: 512 * 1024,
176
+ maxEffects: 256,
177
+ maxOutputBytes: 1024 * 1024
178
+ });
179
+ const DEFAULT_SCRIPT_SECURITY_POLICY = Object.freeze({
180
+ enabled: false,
181
+ executionOwner: "originating-client-only",
182
+ nameTreeBoot: "lazy-first-transaction",
183
+ submitForm: "sink-chain",
184
+ openAction: "execute-lifecycle",
185
+ pageActions: "execute-lifecycle",
186
+ catalogLifecycleActions: "execute-on-verb",
187
+ annotationActions: "execute-full-matrix"
188
+ });
189
+ /** The shipped dispatch matrix; extracted actions outside it remain data
190
+ * only. (Historical note: v1 froze everything beyond K/V/C/F as
191
+ * preserve-only; phases 1–4 executed the rest.) */
192
+ const SCRIPT_EVENT_MATRIX = Object.freeze({
193
+ nameTree: "lazy-first-originating-field-transaction",
194
+ field: Object.freeze({
195
+ keystroke: "execute-on-commit",
196
+ validate: "execute",
197
+ calculate: "execute-in-calculation-order",
198
+ format: "execute-after-value-calculation"
199
+ }),
200
+ openAction: "execute-lifecycle",
201
+ page: "execute-lifecycle",
202
+ catalogLifecycle: "execute-on-verb",
203
+ annotation: Object.freeze({
204
+ widgetActivate: "execute-on-originating-client",
205
+ other: "execute-full-matrix"
206
+ }),
207
+ submitForm: "sink-chain"
208
+ });
209
+ //#endregion
210
+ //#region src/host.ts
211
+ /** FNV-1a over `documentId:sequence` — the deterministic default random seed
212
+ * (ported verbatim from the form controller; exported for callers building
213
+ * `ScriptHostOptions.environment`). */
214
+ function seedFrom(documentId, sequence) {
215
+ let hash = 2166136261;
216
+ for (const char of `${documentId}:${sequence}`) {
217
+ hash ^= char.charCodeAt(0);
218
+ hash = Math.imul(hash, 16777619);
219
+ }
220
+ return hash >>> 0;
221
+ }
222
+ /** Engine JWT/session identity composed under embedder overrides — the
223
+ * standard `ScriptHostOptions.identity` builder. */
224
+ function resolveScriptIdentity(doc, overrides) {
225
+ const claims = doc.security.identity;
226
+ const supplied = typeof overrides === "function" ? overrides() : overrides ?? {};
227
+ return {
228
+ name: supplied.name ?? claims?.display_name ?? claims?.user_id ?? "",
229
+ loginName: supplied.loginName ?? claims?.user_id ?? "",
230
+ corporation: supplied.corporation ?? claims?.group_id ?? "",
231
+ email: supplied.email ?? ""
232
+ };
233
+ }
234
+ function createScriptHost(options) {
235
+ const budget = options.budget ?? DEFAULT_SCRIPT_BUDGET;
236
+ let tail = Promise.resolve();
237
+ const enqueue = (operation) => {
238
+ const result = tail.then(operation, operation);
239
+ tail = result.then(() => void 0, () => void 0);
240
+ return result;
241
+ };
242
+ let sandboxPromise = null;
243
+ let booted = false;
244
+ let pendingBoot = null;
245
+ let bootSourcesCache = null;
246
+ let sequence = 0;
247
+ let disposed = false;
248
+ const ensureSandbox = () => {
249
+ sandboxPromise ?? (sandboxPromise = options.sandboxFactory());
250
+ return sandboxPromise;
251
+ };
252
+ const inputFor = (world) => ({
253
+ document: {
254
+ ...options.document(),
255
+ ...world.pageNumber !== void 0 ? { pageNumber: world.pageNumber } : {}
256
+ },
257
+ identity: options.identity(),
258
+ environment: options.environment(sequence++),
259
+ fields: world.fields,
260
+ ...world.annots ? { annots: world.annots } : {},
261
+ ...world.annotPages ? { annotPages: world.annotPages } : {},
262
+ ...world.annotsCoverDocument !== void 0 ? { annotsCoverDocument: world.annotsCoverDocument } : {},
263
+ event: world.event
264
+ });
265
+ /** A resource fault poisons the realm: rebuild + re-boot lazily NEXT time. */
266
+ const noteFault = (sandbox) => {
267
+ if (!sandbox.disposed) return;
268
+ sandboxPromise = null;
269
+ booted = false;
270
+ pendingBoot = null;
271
+ };
272
+ const bootNow = async (world, runBudget) => {
273
+ if (booted) return null;
274
+ booted = true;
275
+ const sandbox = await ensureSandbox();
276
+ bootSourcesCache ?? (bootSourcesCache = options.bootSources());
277
+ let sources = [];
278
+ try {
279
+ sources = await bootSourcesCache;
280
+ } catch (error) {
281
+ bootSourcesCache = null;
282
+ return {
283
+ event: {
284
+ rc: true,
285
+ value: null,
286
+ change: "",
287
+ selStart: 0,
288
+ selEnd: 0
289
+ },
290
+ formEffects: [],
291
+ annotEffects: [],
292
+ uiEffects: [],
293
+ diagnostics: [{
294
+ code: "script-error",
295
+ message: `Document boot script failed (continuing without it): ${error instanceof Error ? error.message : String(error)}`
296
+ }]
297
+ };
298
+ }
299
+ if (sources.length === 0) return null;
300
+ const output = sandbox.boot(sources, inputFor({
301
+ ...world,
302
+ event: { kind: "name-tree-boot" }
303
+ }), runBudget ?? budget);
304
+ noteFault(sandbox);
305
+ return output;
306
+ };
307
+ const runNow = async (program, world, runBudget) => {
308
+ if (!booted) pendingBoot = await bootNow(world, runBudget);
309
+ const sandbox = await ensureSandbox();
310
+ const output = sandbox.run(program, inputFor(world), runBudget ?? budget);
311
+ noteFault(sandbox);
312
+ return output;
313
+ };
314
+ return {
315
+ transaction(body) {
316
+ if (disposed) return Promise.reject(/* @__PURE__ */ new Error("script host is disposed"));
317
+ return enqueue(() => body({
318
+ boot: async (world, runBudget) => {
319
+ if (pendingBoot) {
320
+ const output = pendingBoot;
321
+ pendingBoot = null;
322
+ return output;
323
+ }
324
+ return bootNow(world, runBudget);
325
+ },
326
+ run: (program, world, runBudget) => runNow(program, world, runBudget)
327
+ }));
328
+ },
329
+ dispose() {
330
+ disposed = true;
331
+ const dying = sandboxPromise;
332
+ sandboxPromise = null;
333
+ booted = false;
334
+ pendingBoot = null;
335
+ dying?.then((sandbox) => sandbox.dispose()).catch(() => void 0);
336
+ }
337
+ };
338
+ }
339
+ //#endregion
22
340
  //#region src/input.ts
23
341
  function valueFromEntry(entry) {
24
342
  switch (entry.kind) {
@@ -146,6 +464,242 @@ function installAcroJs(g) {
146
464
  return wrapper;
147
465
  };
148
466
  const getField = (name) => state?.fieldsByName.get(String(name))?.wrapper ?? null;
467
+ const ANNOT_WRITABLE = {
468
+ square: [
469
+ "strokeColor",
470
+ "fillColor",
471
+ "opacity",
472
+ "width",
473
+ "borderStyle",
474
+ "dash",
475
+ "rect"
476
+ ],
477
+ circle: [
478
+ "strokeColor",
479
+ "fillColor",
480
+ "opacity",
481
+ "width",
482
+ "borderStyle",
483
+ "dash",
484
+ "rect"
485
+ ],
486
+ polygon: [
487
+ "strokeColor",
488
+ "fillColor",
489
+ "opacity",
490
+ "width",
491
+ "borderStyle",
492
+ "dash",
493
+ "rect"
494
+ ],
495
+ polyline: [
496
+ "strokeColor",
497
+ "fillColor",
498
+ "opacity",
499
+ "width",
500
+ "borderStyle",
501
+ "dash",
502
+ "rect"
503
+ ],
504
+ line: [
505
+ "strokeColor",
506
+ "fillColor",
507
+ "opacity",
508
+ "width",
509
+ "borderStyle",
510
+ "dash",
511
+ "rect"
512
+ ],
513
+ ink: [
514
+ "strokeColor",
515
+ "opacity",
516
+ "width",
517
+ "rect"
518
+ ],
519
+ "free-text": [
520
+ "strokeColor",
521
+ "fillColor",
522
+ "opacity",
523
+ "rect"
524
+ ],
525
+ highlight: ["strokeColor", "opacity"],
526
+ underline: ["strokeColor", "opacity"],
527
+ squiggly: ["strokeColor", "opacity"],
528
+ strikeout: ["strokeColor", "opacity"],
529
+ caret: ["strokeColor", "opacity"],
530
+ text: [
531
+ "strokeColor",
532
+ "opacity",
533
+ "rect"
534
+ ],
535
+ stamp: ["rect"],
536
+ "file-attachment": ["strokeColor", "opacity"]
537
+ };
538
+ const ANNOT_FLAG_KEYS = [
539
+ "hidden",
540
+ "print",
541
+ "readOnly",
542
+ "locked",
543
+ "noView",
544
+ "toggleNoView"
545
+ ];
546
+ const ACROBAT_TYPE = {
547
+ square: "Square",
548
+ circle: "Circle",
549
+ line: "Line",
550
+ polygon: "Polygon",
551
+ polyline: "PolyLine",
552
+ ink: "Ink",
553
+ "free-text": "FreeText",
554
+ highlight: "Highlight",
555
+ underline: "Underline",
556
+ squiggly: "Squiggly",
557
+ strikeout: "StrikeOut",
558
+ text: "Text",
559
+ stamp: "Stamp",
560
+ caret: "Caret",
561
+ "file-attachment": "FileAttachment"
562
+ };
563
+ const isColorArray = (value) => {
564
+ if (!Array.isArray(value) || value.length === 0) return false;
565
+ const expected = {
566
+ T: 0,
567
+ G: 1,
568
+ RGB: 3,
569
+ CMYK: 4
570
+ }[String(value[0])];
571
+ return expected !== void 0 && value.length === expected + 1 && value.slice(1).every((part) => typeof part === "number" && isFinite(Number(part)));
572
+ };
573
+ const colorToRgbTriple = (value) => {
574
+ const color = value;
575
+ const space = String(color[0]);
576
+ if (space === "T") return null;
577
+ if (space === "G") return [
578
+ Number(color[1]),
579
+ Number(color[1]),
580
+ Number(color[1])
581
+ ];
582
+ if (space === "RGB") return [
583
+ Number(color[1]),
584
+ Number(color[2]),
585
+ Number(color[3])
586
+ ];
587
+ const c = Number(color[1]);
588
+ const m = Number(color[2]);
589
+ const y = Number(color[3]);
590
+ const k = Number(color[4]);
591
+ return [
592
+ 1 - Math.min(1, c + k),
593
+ 1 - Math.min(1, m + k),
594
+ 1 - Math.min(1, y + k)
595
+ ];
596
+ };
597
+ const sameAnnotValue = (a, b) => {
598
+ if (Array.isArray(a) && Array.isArray(b)) return a.length === b.length && a.every((item, index) => item === b[index]);
599
+ return a === b;
600
+ };
601
+ const cloneAnnotValue = (value) => Array.isArray(value) ? [...value] : value;
602
+ const makeAnnot = (record) => {
603
+ const input = record.input;
604
+ const subtype = String(input.subtype);
605
+ const writable = ANNOT_WRITABLE[subtype] ?? [];
606
+ const wrapper = {};
607
+ const stage = (key, value, validate) => {
608
+ if (key !== "contents" && ANNOT_FLAG_KEYS.indexOf(key) < 0 && writable.indexOf(key) < 0) {
609
+ diagnostic("unsupported-api", `Annot.${key} is not writable on subtype '${subtype}' (write ignored)`);
610
+ return;
611
+ }
612
+ if (input.opaqueBody && ANNOT_FLAG_KEYS.indexOf(key) < 0 && key !== "contents") {
613
+ diagnostic("unsupported-api", `Annot.${key}: '${subtype}' has an opaque appearance (write ignored)`);
614
+ return;
615
+ }
616
+ if (!validate(value)) {
617
+ diagnostic("invalid-field-value", `Annot.${key}: invalid value (write ignored)`);
618
+ return;
619
+ }
620
+ record.current[key] = cloneAnnotValue(value);
621
+ };
622
+ const prop = (key, validate) => ({
623
+ enumerable: true,
624
+ get: () => cloneAnnotValue(record.current[key]),
625
+ set: (value) => stage(key, value, validate)
626
+ });
627
+ const isNum = (v) => typeof v === "number" && isFinite(v);
628
+ const isBool = (v) => typeof v === "boolean";
629
+ Object.defineProperties(wrapper, {
630
+ name: {
631
+ enumerable: true,
632
+ get: () => String(input.name ?? "")
633
+ },
634
+ type: {
635
+ enumerable: true,
636
+ get: () => ACROBAT_TYPE[subtype] ?? subtype
637
+ },
638
+ page: {
639
+ enumerable: true,
640
+ get: () => Number(input.page ?? 0)
641
+ },
642
+ author: {
643
+ enumerable: true,
644
+ get: () => String(input.author ?? "")
645
+ },
646
+ subject: {
647
+ enumerable: true,
648
+ get: () => String(input.subject ?? "")
649
+ },
650
+ strokeColor: prop("strokeColor", isColorArray),
651
+ fillColor: prop("fillColor", isColorArray),
652
+ opacity: prop("opacity", (v) => isNum(v) && Number(v) >= 0 && Number(v) <= 1),
653
+ width: prop("width", (v) => isNum(v) && Number(v) >= 0),
654
+ style: prop("borderStyle", (v) => v === "S" || v === "D"),
655
+ dash: prop("dash", (v) => Array.isArray(v) && v.every(isNum)),
656
+ rect: prop("rect", (v) => Array.isArray(v) && v.length === 4 && v.every(isNum)),
657
+ contents: prop("contents", (v) => typeof v === "string"),
658
+ hidden: prop("hidden", isBool),
659
+ print: prop("print", isBool),
660
+ readOnly: prop("readOnly", isBool),
661
+ lock: prop("locked", isBool),
662
+ noView: prop("noView", isBool),
663
+ toggleNoView: prop("toggleNoView", isBool),
664
+ doc: {
665
+ enumerable: false,
666
+ get: () => doc
667
+ }
668
+ });
669
+ wrapper.getProps = () => {
670
+ const out = {};
671
+ for (const key of Object.keys(record.current)) out[key] = cloneAnnotValue(record.current[key]);
672
+ return out;
673
+ };
674
+ wrapper.setProps = (props) => {
675
+ const source = props ?? {};
676
+ for (const key of Object.keys(source)) wrapper[key] = source[key];
677
+ };
678
+ return wrapper;
679
+ };
680
+ const getAnnots = (spec) => {
681
+ if (!state) return null;
682
+ const nPage = spec?.nPage;
683
+ if (nPage === void 0 || nPage === null) {
684
+ if (!state.annotsCoverDocument) diagnostic("unsupported-api", "getAnnots: whole-document search is limited to the prefetched pages (compatibility deviation)");
685
+ return state.annots.length ? state.annots.map((record) => record.wrapper) : null;
686
+ }
687
+ const page = Math.trunc(Number(nPage));
688
+ if (!state.annotPages.has(page)) {
689
+ diagnostic("unsupported-api", `getAnnots: page ${page} is outside the prefetched annots plane (compatibility deviation)`);
690
+ return null;
691
+ }
692
+ const records = state.annotsByPage.get(page) ?? [];
693
+ return records.length ? records.map((record) => record.wrapper) : null;
694
+ };
695
+ const getAnnot = (nPage, name) => {
696
+ const records = getAnnots({ nPage });
697
+ if (!records) return null;
698
+ for (const wrapper of records) if (String(wrapper.name) === String(name)) return wrapper;
699
+ return null;
700
+ };
701
+ doc.getAnnots = getAnnots;
702
+ doc.getAnnot = getAnnot;
149
703
  Object.defineProperties(doc, {
150
704
  documentFileName: {
151
705
  enumerable: true,
@@ -182,7 +736,26 @@ function installAcroJs(g) {
182
736
  }
183
737
  };
184
738
  doc.print = () => state?.uiEffects.push({ kind: "print" });
185
- doc.submitForm = () => blocked("submitForm");
739
+ doc.submitForm = (cUrlOrArgs, bFDF, bEmpty, aFields) => {
740
+ if (!state) return;
741
+ const args = cUrlOrArgs !== null && typeof cUrlOrArgs === "object" ? cUrlOrArgs : {
742
+ cURL: cUrlOrArgs,
743
+ bFDF,
744
+ bEmpty,
745
+ aFields
746
+ };
747
+ const names = Array.isArray(args.aFields) ? args.aFields.map((name) => String(name)) : null;
748
+ const submitAs = args.cSubmitAs === void 0 ? void 0 : String(args.cSubmitAs).toUpperCase();
749
+ const format = submitAs === "FDF" ? "fdf" : submitAs === "XFDF" ? "xfdf" : submitAs === "HTML" ? "html" : submitAs === "PDF" ? "pdf" : args.bFDF === false ? "html" : void 0;
750
+ state.uiEffects.push({
751
+ kind: "submitForm",
752
+ url: args.cURL === void 0 || args.cURL === null ? null : String(args.cURL),
753
+ fieldNames: names,
754
+ includeEmpty: Boolean(args.bEmpty),
755
+ ...format === void 0 ? {} : { format },
756
+ ...args.bGet === void 0 ? {} : { method: args.bGet ? "get" : "post" }
757
+ });
758
+ };
186
759
  doc.mailDoc = () => blocked("mailDoc");
187
760
  doc.getURL = () => blocked("getURL");
188
761
  const app = {
@@ -250,6 +823,7 @@ function installAcroJs(g) {
250
823
  const hour = local.getUTCHours();
251
824
  const minute = local.getUTCMinutes();
252
825
  const second = local.getUTCSeconds();
826
+ const hour12 = hour % 12 === 0 ? 12 : hour % 12;
253
827
  const tokens = {
254
828
  yyyy: String(year),
255
829
  yy: pad(year % 100),
@@ -260,12 +834,15 @@ function installAcroJs(g) {
260
834
  dd: pad(day),
261
835
  d: String(day),
262
836
  HH: pad(hour),
837
+ hh: pad(hour12),
838
+ h: String(hour12),
263
839
  H: String(hour),
264
840
  MM: pad(minute),
265
841
  M: String(minute),
266
- ss: pad(second)
842
+ ss: pad(second),
843
+ tt: hour < 12 ? "am" : "pm"
267
844
  };
268
- return String(format).replace(/yyyy|mmmm|mmm|yy|mm|dd|HH|MM|ss|m|d|H|M/g, (token) => tokens[token]);
845
+ return String(format).replace(/yyyy|mmmm|mmm|yy|mm|dd|HH|hh|MM|ss|tt|m|d|H|h|M/g, (token) => tokens[token]);
269
846
  };
270
847
  const util = {
271
848
  printd,
@@ -295,14 +872,53 @@ function installAcroJs(g) {
295
872
  });
296
873
  const fieldsByName = new Map(fields.map((field) => [String(field.input.name), field]));
297
874
  const fieldsByRef = new Map(fields.map((field) => [refKey(field.input.ref), field]));
875
+ const annots = (input.annots ?? []).map((annot) => {
876
+ const writableSnapshot = () => ({
877
+ strokeColor: cloneAnnotValue(annot.strokeColor ?? ["T"]),
878
+ fillColor: cloneAnnotValue(annot.fillColor ?? ["T"]),
879
+ opacity: Number(annot.opacity ?? 1),
880
+ width: Number(annot.width ?? 1),
881
+ borderStyle: String(annot.borderStyle ?? "S"),
882
+ dash: cloneAnnotValue(annot.dash ?? []),
883
+ rect: cloneAnnotValue(annot.rect ?? [
884
+ 0,
885
+ 0,
886
+ 0,
887
+ 0
888
+ ]),
889
+ contents: String(annot.contents ?? ""),
890
+ hidden: Boolean(annot.hidden),
891
+ print: Boolean(annot.print),
892
+ readOnly: Boolean(annot.readOnly),
893
+ locked: Boolean(annot.locked),
894
+ noView: Boolean(annot.noView),
895
+ toggleNoView: Boolean(annot.toggleNoView)
896
+ });
897
+ const record = {
898
+ input: annot,
899
+ original: writableSnapshot(),
900
+ current: writableSnapshot(),
901
+ wrapper: {}
902
+ };
903
+ record.wrapper = makeAnnot(record);
904
+ return record;
905
+ });
906
+ const annotsByPage = /* @__PURE__ */ new Map();
907
+ for (const record of annots) {
908
+ const page = Number(record.input.page ?? 0);
909
+ const bucket = annotsByPage.get(page);
910
+ if (bucket) bucket.push(record);
911
+ else annotsByPage.set(page, [record]);
912
+ }
298
913
  const eventInput = input.event ?? {};
299
914
  const target = fieldsByRef.get(refKey(eventInput.target));
300
915
  const source = fieldsByRef.get(refKey(eventInput.source));
301
916
  const initialValue = eventInput.value !== void 0 ? cloneValue(eventInput.value) : cloneValue(target?.value ?? null);
917
+ const eventType = eventInput.type !== void 0 ? String(eventInput.type) : eventInput.kind === "name-tree-boot" ? "Doc" : "Field";
302
918
  const event = {
303
- name: eventName(String(eventInput.kind ?? "")),
304
- type: eventInput.kind === "name-tree-boot" ? "Doc" : "Field",
305
- target: target?.wrapper ?? null,
919
+ name: eventInput.name !== void 0 ? String(eventInput.name) : eventName(String(eventInput.kind ?? "")),
920
+ type: eventType,
921
+ target: target?.wrapper ?? (eventType === "Doc" ? doc : null),
306
922
  targetName: String(target?.input.name ?? ""),
307
923
  source: source?.wrapper ?? { source: doc },
308
924
  value: initialValue,
@@ -319,6 +935,10 @@ function installAcroJs(g) {
319
935
  fields,
320
936
  fieldsByName,
321
937
  fieldsByRef,
938
+ annots,
939
+ annotsByPage,
940
+ annotPages: new Set((input.annotPages ?? []).map((page) => Math.trunc(Number(page)))),
941
+ annotsCoverDocument: Boolean(input.annotsCoverDocument),
322
942
  event,
323
943
  resetRefs: [],
324
944
  resetKeys: /* @__PURE__ */ new Set(),
@@ -391,10 +1011,26 @@ function installAcroJs(g) {
391
1011
  ref: target.input.ref,
392
1012
  text: String(state.event.value ?? "")
393
1013
  });
394
- const totalEffects = formEffects.length + state.uiEffects.length;
1014
+ const annotEffects = [];
1015
+ for (const record of state.annots) {
1016
+ const patch = {};
1017
+ const flags = {};
1018
+ for (const key of Object.keys(record.current)) {
1019
+ if (sameAnnotValue(record.current[key], record.original[key])) continue;
1020
+ if (ANNOT_FLAG_KEYS.indexOf(key) >= 0) flags[key] = record.current[key];
1021
+ else patch[key] = cloneAnnotValue(record.current[key]);
1022
+ }
1023
+ if (Object.keys(flags).length > 0) patch.flags = flags;
1024
+ if (Object.keys(patch).length > 0) annotEffects.push({
1025
+ ref: record.input.ref,
1026
+ patch
1027
+ });
1028
+ }
1029
+ const totalEffects = formEffects.length + annotEffects.length + state.uiEffects.length;
395
1030
  if (totalEffects > state.maxEffects) return {
396
1031
  event: eventOutput(),
397
1032
  formEffects: [],
1033
+ annotEffects: [],
398
1034
  uiEffects: [],
399
1035
  diagnostics: [...state.diagnostics],
400
1036
  error: {
@@ -405,6 +1041,7 @@ function installAcroJs(g) {
405
1041
  return {
406
1042
  event: eventOutput(),
407
1043
  formEffects,
1044
+ annotEffects,
408
1045
  uiEffects: [...state.uiEffects],
409
1046
  diagnostics: [...state.diagnostics]
410
1047
  };
@@ -412,6 +1049,7 @@ function installAcroJs(g) {
412
1049
  const failed = (error) => ({
413
1050
  event: eventOutput(),
414
1051
  formEffects: [],
1052
+ annotEffects: [],
415
1053
  uiEffects: [],
416
1054
  diagnostics: [...state?.diagnostics ?? []],
417
1055
  error: {
@@ -461,7 +1099,87 @@ function installAcroJs(g) {
461
1099
  noPrint: 2,
462
1100
  noView: 3
463
1101
  });
1102
+ host.color = Object.freeze({
1103
+ transparent: Object.freeze(["T"]),
1104
+ black: Object.freeze(["G", 0]),
1105
+ white: Object.freeze(["G", 1]),
1106
+ gray: Object.freeze(["G", .5]),
1107
+ ltGray: Object.freeze(["G", .75]),
1108
+ dkGray: Object.freeze(["G", .25]),
1109
+ red: Object.freeze([
1110
+ "RGB",
1111
+ 1,
1112
+ 0,
1113
+ 0
1114
+ ]),
1115
+ green: Object.freeze([
1116
+ "RGB",
1117
+ 0,
1118
+ 1,
1119
+ 0
1120
+ ]),
1121
+ blue: Object.freeze([
1122
+ "RGB",
1123
+ 0,
1124
+ 0,
1125
+ 1
1126
+ ]),
1127
+ cyan: Object.freeze([
1128
+ "CMYK",
1129
+ 1,
1130
+ 0,
1131
+ 0,
1132
+ 0
1133
+ ]),
1134
+ magenta: Object.freeze([
1135
+ "CMYK",
1136
+ 0,
1137
+ 1,
1138
+ 0,
1139
+ 0
1140
+ ]),
1141
+ yellow: Object.freeze([
1142
+ "CMYK",
1143
+ 0,
1144
+ 0,
1145
+ 1,
1146
+ 0
1147
+ ]),
1148
+ convert: (value, space) => {
1149
+ if (!isColorArray(value)) return ["T"];
1150
+ const target = String(space);
1151
+ const rgb = colorToRgbTriple(value);
1152
+ if (target === "T" || rgb === null) return ["T"];
1153
+ if (target === "G") return ["G", .3 * rgb[0] + .59 * rgb[1] + .11 * rgb[2]];
1154
+ if (target === "RGB") return [
1155
+ "RGB",
1156
+ rgb[0],
1157
+ rgb[1],
1158
+ rgb[2]
1159
+ ];
1160
+ if (target === "CMYK") {
1161
+ const k = 1 - Math.max(rgb[0], rgb[1], rgb[2]);
1162
+ return [
1163
+ "CMYK",
1164
+ 1 - rgb[0] - k,
1165
+ 1 - rgb[1] - k,
1166
+ 1 - rgb[2] - k,
1167
+ k
1168
+ ];
1169
+ }
1170
+ return ["T"];
1171
+ },
1172
+ equal: (a, b) => {
1173
+ if (!isColorArray(a) || !isColorArray(b)) return false;
1174
+ const left = colorToRgbTriple(a);
1175
+ const right = colorToRgbTriple(b);
1176
+ if (left === null || right === null) return left === right;
1177
+ return left.every((component, index) => Math.abs(component - right[index]) < 1e-6);
1178
+ }
1179
+ });
464
1180
  host.getField = getField;
1181
+ host.getAnnots = getAnnots;
1182
+ host.getAnnot = getAnnot;
465
1183
  host.resetForm = doc.resetForm;
466
1184
  host.print = doc.print;
467
1185
  host.submitForm = doc.submitForm;
@@ -523,8 +1241,226 @@ function installAcroJs(g) {
523
1241
  const places = Math.max(0, Math.min(10, Math.trunc(Number(decimals))));
524
1242
  state.event.value = `${(numberValue(state.event.value) * 100).toFixed(places)}%`;
525
1243
  };
526
- host.AFDate_FormatEx = (format) => {
527
- if (state) state.event.value = printd(format, new FixedDate(String(state.event.value ?? "")));
1244
+ const DATE_FORMATS = [
1245
+ "m/d",
1246
+ "m/d/yy",
1247
+ "mm/dd/yy",
1248
+ "mm/yy",
1249
+ "d-mmm",
1250
+ "d-mmm-yy",
1251
+ "dd-mmm-yy",
1252
+ "yy-mm-dd",
1253
+ "mmm-yy",
1254
+ "mmmm-yy",
1255
+ "mmm d, yyyy",
1256
+ "mmmm d, yyyy",
1257
+ "m/d/yy h:MM tt",
1258
+ "m/d/yy HH:MM"
1259
+ ];
1260
+ const TIME_FORMATS = [
1261
+ "HH:MM",
1262
+ "h:MM tt",
1263
+ "HH:MM:ss",
1264
+ "h:MM:ss tt"
1265
+ ];
1266
+ const rejectWithAlert = (message) => {
1267
+ if (!state) return;
1268
+ state.uiEffects.push({
1269
+ kind: "alert",
1270
+ message,
1271
+ icon: 0
1272
+ });
1273
+ state.event.rc = false;
1274
+ };
1275
+ const formatMismatch = () => rejectWithAlert(`The value entered does not match the format of the field [ ${String(state?.event.targetName ?? "")} ]`);
1276
+ const dateMismatch = (format) => rejectWithAlert(`Invalid date/time: please ensure that the date/time exists. Field [ ${String(state?.event.targetName ?? "")} ] should match format ${String(format ?? "")}`);
1277
+ const mergeChange = (eventObject) => {
1278
+ const e = eventObject ?? state?.event ?? {};
1279
+ const value = String(e.value ?? "");
1280
+ if (e.willCommit) return value;
1281
+ const start = Math.max(0, Math.trunc(Number(e.selStart ?? 0)));
1282
+ const end = Math.max(start, Math.trunc(Number(e.selEnd ?? 0)));
1283
+ return value.slice(0, start) + String(e.change ?? "") + value.slice(end);
1284
+ };
1285
+ host.AFMergeChange = mergeChange;
1286
+ const makeNumber = (value) => {
1287
+ if (typeof value === "number") return Number.isFinite(value) ? value : null;
1288
+ let text = String(value ?? "").trim();
1289
+ if (text === "") return null;
1290
+ text = text.replace(/[^0-9,.\-+eE]/g, "");
1291
+ if (text.includes(",") && text.includes(".")) text = text.lastIndexOf(",") > text.lastIndexOf(".") ? text.replace(/\./g, "").replace(",", ".") : text.replace(/,/g, "");
1292
+ else if (text.includes(",")) text = (text.match(/,/g) ?? []).length === 1 ? text.replace(",", ".") : text.replace(/,/g, "");
1293
+ const parsed = Number(text);
1294
+ return text !== "" && Number.isFinite(parsed) ? parsed : null;
1295
+ };
1296
+ host.AFMakeNumber = makeNumber;
1297
+ host.AFExtractNums = (value) => {
1298
+ const matches = String(value ?? "").match(/\d+/g);
1299
+ return matches && matches.length > 0 ? [...matches] : null;
1300
+ };
1301
+ const validNumberText = (text, separatorStyle) => {
1302
+ const trimmed = text.trim();
1303
+ if (trimmed === "") return true;
1304
+ return (separatorStyle === 2 || separatorStyle === 3 ? /^[+-]?(\d+|\d{1,3}(\.\d{3})+)?(,\d*)?$/ : /^[+-]?(\d+|\d{1,3}(,\d{3})+)?(\.\d*)?$/).test(trimmed) && /\d/.test(trimmed);
1305
+ };
1306
+ host.AFNumber_Keystroke = (_decimals, separatorStyle, _negativeStyle, _currencyStyle, currency) => {
1307
+ if (!state || !state.event.willCommit) return;
1308
+ const proposed = mergeChange(state.event);
1309
+ const cleaned = currency ? proposed.split(String(currency)).join("") : proposed;
1310
+ if (!validNumberText(cleaned, Math.trunc(Number(separatorStyle)))) formatMismatch();
1311
+ };
1312
+ host.AFPercent_Keystroke = (_decimals, separatorStyle) => {
1313
+ if (!state || !state.event.willCommit) return;
1314
+ const cleaned = mergeChange(state.event).replace(/%\s*$/, "");
1315
+ if (!validNumberText(cleaned, Math.trunc(Number(separatorStyle)))) formatMismatch();
1316
+ };
1317
+ const digitsOf = (value) => String(value ?? "").replace(/\D/g, "");
1318
+ const afSpecialFormat = (psf) => {
1319
+ if (!state) return;
1320
+ const digits = digitsOf(state.event.value);
1321
+ const kind = Math.trunc(Number(psf));
1322
+ let formatted = String(state.event.value ?? "");
1323
+ if (kind === 0) formatted = digits.slice(0, 5);
1324
+ else if (kind === 1) formatted = `${digits.slice(0, 5)}-${digits.slice(5, 9)}`;
1325
+ else if (kind === 2) formatted = digits.length >= 10 ? `(${digits.slice(0, 3)}) ${digits.slice(3, 6)}-${digits.slice(6, 10)}` : `${digits.slice(0, 3)}-${digits.slice(3, 7)}`;
1326
+ else if (kind === 3) formatted = `${digits.slice(0, 3)}-${digits.slice(3, 5)}-${digits.slice(5, 9)}`;
1327
+ state.event.value = formatted;
1328
+ };
1329
+ host.AFSpecial_Format = afSpecialFormat;
1330
+ host.AFSpecial_Keystroke = (psf) => {
1331
+ if (!state || !state.event.willCommit) return;
1332
+ const merged = mergeChange(state.event);
1333
+ if (merged.trim() === "") return;
1334
+ const digits = digitsOf(merged).length;
1335
+ const kind = Math.trunc(Number(psf));
1336
+ if (!(kind === 0 ? digits === 5 : kind === 1 ? digits === 9 : kind === 2 ? digits === 7 || digits === 10 : digits === 9)) formatMismatch();
1337
+ };
1338
+ host.AFRange_Validate = (useGreater, greaterThan, useLess, lessThan) => {
1339
+ if (!state) return;
1340
+ const value = makeNumber(state.event.value);
1341
+ if (value === null) return;
1342
+ const hasGreater = Boolean(useGreater);
1343
+ const hasLess = Boolean(useLess);
1344
+ const low = Number(greaterThan);
1345
+ const high = Number(lessThan);
1346
+ if ((!hasGreater || value >= low) && (!hasLess || value <= high)) return;
1347
+ rejectWithAlert(hasGreater && hasLess ? `Invalid value: must be greater than or equal to ${low} and less than or equal to ${high}.` : hasGreater ? `Invalid value: must be greater than or equal to ${low}.` : `Invalid value: must be less than or equal to ${high}.`);
1348
+ };
1349
+ const nowWall = () => {
1350
+ const env = state?.input.environment ?? {};
1351
+ const local = new NativeDate(Number(env.nowMs ?? 0) + Number(env.utcOffsetMinutes ?? 0) * 6e4);
1352
+ return {
1353
+ y: local.getUTCFullYear(),
1354
+ m: local.getUTCMonth() + 1,
1355
+ d: local.getUTCDate(),
1356
+ H: 0,
1357
+ M: 0,
1358
+ S: 0
1359
+ };
1360
+ };
1361
+ /** printd adds the environment offset itself, so a wall time converts back. */
1362
+ const wallDate = (parts) => {
1363
+ const env = state?.input.environment ?? {};
1364
+ return new NativeDate(NativeDate.UTC(parts.y, parts.m - 1, parts.d, parts.H, parts.M, parts.S) - Number(env.utcOffsetMinutes ?? 0) * 6e4);
1365
+ };
1366
+ /** Lenient scand-style parse: numbers mapped by the format's token order,
1367
+ * month names accepted, missing parts defaulted like Acrobat's scand. */
1368
+ const parseDateLoose = (raw, format) => {
1369
+ const text = String(raw ?? "").trim();
1370
+ if (text === "") return null;
1371
+ const lower = text.toLowerCase();
1372
+ let namedMonth = null;
1373
+ for (let index = 0; index < 12; index += 1) if (lower.indexOf(monthShort[index].toLowerCase()) >= 0) {
1374
+ namedMonth = index + 1;
1375
+ break;
1376
+ }
1377
+ const timeMatch = /(\d{1,2}):(\d{2})(?::(\d{2}))?\s*(am|pm)?/i.exec(text);
1378
+ let H = 0;
1379
+ let M = 0;
1380
+ let S = 0;
1381
+ if (timeMatch) {
1382
+ H = Number(timeMatch[1]);
1383
+ M = Number(timeMatch[2]);
1384
+ S = Number(timeMatch[3] ?? 0);
1385
+ const marker = String(timeMatch[4] ?? "").toLowerCase();
1386
+ if (marker === "pm" && H < 12) H += 12;
1387
+ if (marker === "am" && H === 12) H = 0;
1388
+ if (H > 23 || M > 59 || S > 59) return null;
1389
+ }
1390
+ const numbers = ((timeMatch ? text.slice(0, timeMatch.index) + text.slice(timeMatch.index + timeMatch[0].length) : text).match(/\d+/g) ?? []).map((token) => Number(token));
1391
+ const order = [];
1392
+ for (const token of String(format ?? "").match(/yyyy|mmmm|mmm|yy|mm|dd|m|d/g) ?? []) {
1393
+ const kind = token[0] === "y" ? "y" : token[0] === "m" ? "m" : "d";
1394
+ if (order.indexOf(kind) < 0) order.push(kind);
1395
+ }
1396
+ let y = null;
1397
+ let m = namedMonth;
1398
+ let d = null;
1399
+ let cursor = 0;
1400
+ for (const kind of order) {
1401
+ if (kind === "m" && namedMonth !== null) continue;
1402
+ if (cursor >= numbers.length) break;
1403
+ const value = numbers[cursor];
1404
+ cursor += 1;
1405
+ if (kind === "y") y = value;
1406
+ else if (kind === "m") m = value;
1407
+ else d = value;
1408
+ }
1409
+ if (y === null && m === null && d === null && !timeMatch) return null;
1410
+ const today = nowWall();
1411
+ if (y === null) y = today.y;
1412
+ else if (y < 100) y = y < 50 ? 2e3 + y : 1900 + y;
1413
+ if (m === null) m = today.m;
1414
+ if (d === null) d = 1;
1415
+ if (m < 1 || m > 12 || d < 1 || d > 31) return null;
1416
+ const probe = new NativeDate(NativeDate.UTC(y, m - 1, d));
1417
+ if (probe.getUTCFullYear() !== y || probe.getUTCMonth() !== m - 1 || probe.getUTCDate() !== d) return null;
1418
+ return {
1419
+ y,
1420
+ m,
1421
+ d,
1422
+ H,
1423
+ M,
1424
+ S
1425
+ };
1426
+ };
1427
+ const afDateFormatEx = (format) => {
1428
+ if (!state) return;
1429
+ const raw = String(state.event.value ?? "");
1430
+ if (raw.trim() === "") return;
1431
+ let date = new FixedDate(raw);
1432
+ if (Number.isNaN(date.getTime())) {
1433
+ const parts = parseDateLoose(raw, format);
1434
+ if (!parts) return;
1435
+ date = wallDate(parts);
1436
+ }
1437
+ state.event.value = printd(format, date);
1438
+ };
1439
+ host.AFDate_FormatEx = afDateFormatEx;
1440
+ host.AFDate_Format = (index) => afDateFormatEx(DATE_FORMATS[Math.trunc(Number(index))] ?? "m/d/yy");
1441
+ const afDateKeystrokeEx = (format) => {
1442
+ if (!state || !state.event.willCommit) return;
1443
+ const merged = mergeChange(state.event);
1444
+ if (merged.trim() === "") return;
1445
+ if (!parseDateLoose(merged, format)) dateMismatch(format);
1446
+ };
1447
+ host.AFDate_KeystrokeEx = afDateKeystrokeEx;
1448
+ host.AFDate_Keystroke = (index) => afDateKeystrokeEx(DATE_FORMATS[Math.trunc(Number(index))] ?? "m/d/yy");
1449
+ const afTimeFormatEx = (format) => {
1450
+ if (!state) return;
1451
+ const raw = String(state.event.value ?? "");
1452
+ if (raw.trim() === "") return;
1453
+ const parts = parseDateLoose(raw, format);
1454
+ if (!parts) return;
1455
+ state.event.value = printd(format, wallDate(parts));
1456
+ };
1457
+ host.AFTime_FormatEx = afTimeFormatEx;
1458
+ host.AFTime_Format = (index) => afTimeFormatEx(TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM");
1459
+ host.AFTime_Keystroke = (index) => {
1460
+ if (!state || !state.event.willCommit) return;
1461
+ const merged = mergeChange(state.event);
1462
+ if (merged.trim() === "") return;
1463
+ if (!parseDateLoose(merged, TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM")) dateMismatch(TIME_FORMATS[Math.trunc(Number(index))] ?? "HH:MM");
528
1464
  };
529
1465
  host.fetch = void 0;
530
1466
  host.XMLHttpRequest = void 0;
@@ -533,50 +1469,21 @@ function installAcroJs(g) {
533
1469
  /** The exact self-contained source evaluated in Node parity tests and QuickJS. */
534
1470
  const PRELUDE_SOURCE = `(${installAcroJs.toString()})(globalThis);`;
535
1471
  //#endregion
536
- //#region src/types.ts
537
- const DEFAULT_SCRIPT_BUDGET = Object.freeze({
538
- maxExecutionMs: 50,
539
- maxMemoryBytes: 16 * 1024 * 1024,
540
- maxStackBytes: 512 * 1024,
541
- maxEffects: 256,
542
- maxOutputBytes: 1024 * 1024
543
- });
544
- const DEFAULT_SCRIPT_SECURITY_POLICY = Object.freeze({
545
- enabled: false,
546
- executionOwner: "originating-client-only",
547
- nameTreeBoot: "lazy-first-transaction",
548
- submitForm: "blocked",
549
- openAction: "preserve-only",
550
- pageActions: "preserve-only",
551
- catalogLifecycleActions: "preserve-only",
552
- annotationActions: "widget-activate-only"
553
- });
554
- /** Frozen V1 dispatch matrix; extracted actions outside it remain data only. */
555
- const SCRIPT_EVENT_MATRIX = Object.freeze({
556
- nameTree: "lazy-first-originating-field-transaction",
557
- field: Object.freeze({
558
- keystroke: "execute-on-commit",
559
- validate: "execute",
560
- calculate: "execute-in-calculation-order",
561
- format: "execute-after-value-calculation"
562
- }),
563
- openAction: "preserve-only",
564
- page: "preserve-only",
565
- catalogLifecycle: "preserve-only",
566
- annotation: Object.freeze({
567
- widgetActivate: "execute-on-originating-client",
568
- other: "preserve-only"
569
- }),
570
- submitForm: "blocked"
571
- });
572
- //#endregion
1472
+ exports.ANNOT_WRITABLE_KEYS = ANNOT_WRITABLE_KEYS;
573
1473
  exports.DEFAULT_SCRIPT_BUDGET = DEFAULT_SCRIPT_BUDGET;
574
1474
  exports.DEFAULT_SCRIPT_SECURITY_POLICY = DEFAULT_SCRIPT_SECURITY_POLICY;
575
1475
  exports.PRELUDE_SOURCE = PRELUDE_SOURCE;
576
1476
  exports.SCRIPT_EVENT_MATRIX = SCRIPT_EVENT_MATRIX;
1477
+ exports.createScriptHost = createScriptHost;
1478
+ exports.cssToScriptColor = cssToScriptColor;
577
1479
  exports.installAcroJs = installAcroJs;
1480
+ exports.isScriptColorArray = isScriptColorArray;
578
1481
  exports.javaScriptProgramFromActionTree = javaScriptProgramFromActionTree;
579
1482
  exports.javaScriptSourcesFromActionTree = javaScriptSourcesFromActionTree;
1483
+ exports.resolveScriptIdentity = resolveScriptIdentity;
1484
+ exports.scriptColorToCss = scriptColorToCss;
1485
+ exports.scriptColorToRgb = scriptColorToRgb;
580
1486
  exports.scriptFieldsFromSnapshot = scriptFieldsFromSnapshot;
1487
+ exports.seedFrom = seedFrom;
581
1488
 
582
1489
  //# sourceMappingURL=index.cjs.map