@arbidocs/coedit 0.4.158 → 0.4.159

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.
@@ -204,6 +204,11 @@ type UndoRecord = {
204
204
  index: number;
205
205
  text: string;
206
206
  }[];
207
+ }
208
+ /** A signature field ARBI inserted (by its tag, which its key makes unique): undo removes it. */
209
+ | {
210
+ kind: 'signatureField';
211
+ tag: string;
207
212
  };
208
213
  /** Every paragraph of a part, by `w14:paraId`, and the body's own paragraphs in order. */
209
214
  declare function paragraphIndex(root: OoxmlNodeLike): {
@@ -470,6 +475,84 @@ declare function applyTermEverywhere(port: DefinitionsPort, spec: TermSpec & {
470
475
  accept?: (paragraph: DocParagraph) => boolean;
471
476
  }): TermEverywhereResult;
472
477
 
478
+ /**
479
+ * Signature fields in a Word document (ARBI `docs/signature-anchor-fields.md`).
480
+ *
481
+ * A field is a content control tagged `arbi-signature:<kind>[:<key>]` whose text is a chip
482
+ * ("Signature — Priya Shah"), locked against typing. A keyed field carries a hidden payload in a
483
+ * customXml part (`SIGNATURE_FIELDS_NAMESPACE`) naming its signer: their email and name, and
484
+ * whether the field is required. When a version is rendered to PDF, ARBI's parser turns each
485
+ * field into an invisible anchor, and a signature request places the field exactly there, for
486
+ * that signer. A field with no key has no signer yet: it is assigned when the request is made.
487
+ *
488
+ * The collaboration service (ARBI's `insert_signature_field`) writes the same control.
489
+ */
490
+
491
+ declare const SIGNATURE_FIELDS_NAMESPACE = "urn:arbi:signature-fields";
492
+ declare const SIGNATURE_FIELD_TAG_PREFIX = "arbi-signature:";
493
+ declare const SIGNATURE_FIELD_KINDS: readonly ["signature", "initials", "date", "name"];
494
+ type SignatureFieldKind = (typeof SIGNATURE_FIELD_KINDS)[number];
495
+ /** The labels a signature request uses for the same kinds (`FIELD_TYPE_LABELS`). */
496
+ declare const SIGNATURE_FIELD_LABELS: Record<SignatureFieldKind, string>;
497
+ interface SignatureFieldSpec {
498
+ kind: SignatureFieldKind;
499
+ /** The signer's email; omitted for a field whose signer is chosen when the request is made. */
500
+ email?: string | null;
501
+ name?: string | null;
502
+ required?: boolean;
503
+ }
504
+ /** What the payload of a keyed field holds. */
505
+ interface SignatureFieldPayload {
506
+ key: string;
507
+ kind: SignatureFieldKind;
508
+ email: string;
509
+ name: string | null;
510
+ required: boolean;
511
+ }
512
+ declare const isSignerEmail: (value: string) => boolean;
513
+ /** 8 random hex digits: the key the field and its PDF anchor share. */
514
+ declare function newSignatureFieldKey(): string;
515
+ declare const signatureFieldTag: (kind: SignatureFieldKind, key?: string | null) => string;
516
+ /** The chip's text: what the field is, and for whom ("Signature — Priya Shah"). */
517
+ declare const signatureFieldLabel: (kind: SignatureFieldKind, who?: string | null) => string;
518
+ declare function parseSignatureFieldTag(tag: string | null | undefined): {
519
+ kind: SignatureFieldKind;
520
+ key: string | null;
521
+ } | null;
522
+ /**
523
+ * The engine's custom-node write for a field at `at` (the store's `insertCustomNode`): the
524
+ * control, and for a field with a signer its payload, in one transaction.
525
+ */
526
+ declare function signatureFieldWrite(spec: SignatureFieldSpec, at: {
527
+ paragraphId: string;
528
+ offset: number;
529
+ }, key?: string): {
530
+ key: string | null;
531
+ tag: string;
532
+ write: {
533
+ payload?: {
534
+ namespaceUri: string;
535
+ rootLocalName: string;
536
+ nodeId: string;
537
+ label: string;
538
+ data: string;
539
+ } | undefined;
540
+ paragraphId: string;
541
+ offset: number;
542
+ tag: string;
543
+ text: string;
544
+ alias: string;
545
+ lock: "contentLocked";
546
+ };
547
+ };
548
+ /** Every signature field control in a part's tree, in document order. */
549
+ declare function signatureFieldControls(root: OoxmlNodeLike): {
550
+ nodeId: string;
551
+ tag: string;
552
+ kind: SignatureFieldKind;
553
+ key: string | null;
554
+ }[];
555
+
473
556
  /** A document's parts as trees: a live editor's session or a headless view (`openHeadlessDocument`). */
474
557
  interface DocumentTrees {
475
558
  part(): {
@@ -497,4 +580,4 @@ declare function documentReader(view: DocumentTrees): DocumentReader;
497
580
  /** Read a document from its bytes (a collaboration room's `readRoom`). Throws on a bad package. */
498
581
  declare function readDocument(bytes: Uint8Array): DocumentReader;
499
582
 
500
- export { AGENT_UNDO_MAP, type BrokenReference, CHARACTER_STYLES, type CrossReference, type CrossReferenceMode, CrossReferenceTarget, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, type DefinitionText, DefinitionsPort, type DefinitionsSection, DocParagraph, DocPoint, DocumentNumbering, type DocumentReader, type DocumentTrees, type InsertTermResult, LevelOf, ListItemInfo, OoxmlNodeLike, type ParagraphState, type ParsedDefinition, REF_BOOKMARK_PREFIX, ReferencesPort, type ReferencesReader, type RefreshResult, type ReplacedSpan, type SectionState, type StaleReference, type TermChange, TermEverywhereError, type TermEverywhereResult, type TermSkip, type TermSkipReason, type TermSpec, type TermUse, type UndoRecord, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, ensureTargetBookmark, esc, fieldNodeIds, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, markCrossReferenceTarget, newRefBookmark, paragraphIndex, paragraphRunsXml, paragraphState, parseDefinition, readDocument, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, staleCrossReferences, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
583
+ export { AGENT_UNDO_MAP, type BrokenReference, CHARACTER_STYLES, type CrossReference, type CrossReferenceMode, CrossReferenceTarget, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, type DefinitionText, DefinitionsPort, type DefinitionsSection, DocParagraph, DocPoint, DocumentNumbering, type DocumentReader, type DocumentTrees, type InsertTermResult, LevelOf, ListItemInfo, OoxmlNodeLike, type ParagraphState, type ParsedDefinition, REF_BOOKMARK_PREFIX, ReferencesPort, type ReferencesReader, type RefreshResult, type ReplacedSpan, SIGNATURE_FIELDS_NAMESPACE, SIGNATURE_FIELD_KINDS, SIGNATURE_FIELD_LABELS, SIGNATURE_FIELD_TAG_PREFIX, type SectionState, type SignatureFieldKind, type SignatureFieldPayload, type SignatureFieldSpec, type StaleReference, type TermChange, TermEverywhereError, type TermEverywhereResult, type TermSkip, type TermSkipReason, type TermSpec, type TermUse, type UndoRecord, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, ensureTargetBookmark, esc, fieldNodeIds, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, isSignerEmail, markCrossReferenceTarget, newRefBookmark, newSignatureFieldKey, paragraphIndex, paragraphRunsXml, paragraphState, parseDefinition, parseSignatureFieldTag, readDocument, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, signatureFieldControls, signatureFieldLabel, signatureFieldTag, signatureFieldWrite, staleCrossReferences, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
@@ -204,6 +204,11 @@ type UndoRecord = {
204
204
  index: number;
205
205
  text: string;
206
206
  }[];
207
+ }
208
+ /** A signature field ARBI inserted (by its tag, which its key makes unique): undo removes it. */
209
+ | {
210
+ kind: 'signatureField';
211
+ tag: string;
207
212
  };
208
213
  /** Every paragraph of a part, by `w14:paraId`, and the body's own paragraphs in order. */
209
214
  declare function paragraphIndex(root: OoxmlNodeLike): {
@@ -470,6 +475,84 @@ declare function applyTermEverywhere(port: DefinitionsPort, spec: TermSpec & {
470
475
  accept?: (paragraph: DocParagraph) => boolean;
471
476
  }): TermEverywhereResult;
472
477
 
478
+ /**
479
+ * Signature fields in a Word document (ARBI `docs/signature-anchor-fields.md`).
480
+ *
481
+ * A field is a content control tagged `arbi-signature:<kind>[:<key>]` whose text is a chip
482
+ * ("Signature — Priya Shah"), locked against typing. A keyed field carries a hidden payload in a
483
+ * customXml part (`SIGNATURE_FIELDS_NAMESPACE`) naming its signer: their email and name, and
484
+ * whether the field is required. When a version is rendered to PDF, ARBI's parser turns each
485
+ * field into an invisible anchor, and a signature request places the field exactly there, for
486
+ * that signer. A field with no key has no signer yet: it is assigned when the request is made.
487
+ *
488
+ * The collaboration service (ARBI's `insert_signature_field`) writes the same control.
489
+ */
490
+
491
+ declare const SIGNATURE_FIELDS_NAMESPACE = "urn:arbi:signature-fields";
492
+ declare const SIGNATURE_FIELD_TAG_PREFIX = "arbi-signature:";
493
+ declare const SIGNATURE_FIELD_KINDS: readonly ["signature", "initials", "date", "name"];
494
+ type SignatureFieldKind = (typeof SIGNATURE_FIELD_KINDS)[number];
495
+ /** The labels a signature request uses for the same kinds (`FIELD_TYPE_LABELS`). */
496
+ declare const SIGNATURE_FIELD_LABELS: Record<SignatureFieldKind, string>;
497
+ interface SignatureFieldSpec {
498
+ kind: SignatureFieldKind;
499
+ /** The signer's email; omitted for a field whose signer is chosen when the request is made. */
500
+ email?: string | null;
501
+ name?: string | null;
502
+ required?: boolean;
503
+ }
504
+ /** What the payload of a keyed field holds. */
505
+ interface SignatureFieldPayload {
506
+ key: string;
507
+ kind: SignatureFieldKind;
508
+ email: string;
509
+ name: string | null;
510
+ required: boolean;
511
+ }
512
+ declare const isSignerEmail: (value: string) => boolean;
513
+ /** 8 random hex digits: the key the field and its PDF anchor share. */
514
+ declare function newSignatureFieldKey(): string;
515
+ declare const signatureFieldTag: (kind: SignatureFieldKind, key?: string | null) => string;
516
+ /** The chip's text: what the field is, and for whom ("Signature — Priya Shah"). */
517
+ declare const signatureFieldLabel: (kind: SignatureFieldKind, who?: string | null) => string;
518
+ declare function parseSignatureFieldTag(tag: string | null | undefined): {
519
+ kind: SignatureFieldKind;
520
+ key: string | null;
521
+ } | null;
522
+ /**
523
+ * The engine's custom-node write for a field at `at` (the store's `insertCustomNode`): the
524
+ * control, and for a field with a signer its payload, in one transaction.
525
+ */
526
+ declare function signatureFieldWrite(spec: SignatureFieldSpec, at: {
527
+ paragraphId: string;
528
+ offset: number;
529
+ }, key?: string): {
530
+ key: string | null;
531
+ tag: string;
532
+ write: {
533
+ payload?: {
534
+ namespaceUri: string;
535
+ rootLocalName: string;
536
+ nodeId: string;
537
+ label: string;
538
+ data: string;
539
+ } | undefined;
540
+ paragraphId: string;
541
+ offset: number;
542
+ tag: string;
543
+ text: string;
544
+ alias: string;
545
+ lock: "contentLocked";
546
+ };
547
+ };
548
+ /** Every signature field control in a part's tree, in document order. */
549
+ declare function signatureFieldControls(root: OoxmlNodeLike): {
550
+ nodeId: string;
551
+ tag: string;
552
+ kind: SignatureFieldKind;
553
+ key: string | null;
554
+ }[];
555
+
473
556
  /** A document's parts as trees: a live editor's session or a headless view (`openHeadlessDocument`). */
474
557
  interface DocumentTrees {
475
558
  part(): {
@@ -497,4 +580,4 @@ declare function documentReader(view: DocumentTrees): DocumentReader;
497
580
  /** Read a document from its bytes (a collaboration room's `readRoom`). Throws on a bad package. */
498
581
  declare function readDocument(bytes: Uint8Array): DocumentReader;
499
582
 
500
- export { AGENT_UNDO_MAP, type BrokenReference, CHARACTER_STYLES, type CrossReference, type CrossReferenceMode, CrossReferenceTarget, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, type DefinitionText, DefinitionsPort, type DefinitionsSection, DocParagraph, DocPoint, DocumentNumbering, type DocumentReader, type DocumentTrees, type InsertTermResult, LevelOf, ListItemInfo, OoxmlNodeLike, type ParagraphState, type ParsedDefinition, REF_BOOKMARK_PREFIX, ReferencesPort, type ReferencesReader, type RefreshResult, type ReplacedSpan, type SectionState, type StaleReference, type TermChange, TermEverywhereError, type TermEverywhereResult, type TermSkip, type TermSkipReason, type TermSpec, type TermUse, type UndoRecord, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, ensureTargetBookmark, esc, fieldNodeIds, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, markCrossReferenceTarget, newRefBookmark, paragraphIndex, paragraphRunsXml, paragraphState, parseDefinition, readDocument, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, staleCrossReferences, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
583
+ export { AGENT_UNDO_MAP, type BrokenReference, CHARACTER_STYLES, type CrossReference, type CrossReferenceMode, CrossReferenceTarget, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, type DefinitionText, DefinitionsPort, type DefinitionsSection, DocParagraph, DocPoint, DocumentNumbering, type DocumentReader, type DocumentTrees, type InsertTermResult, LevelOf, ListItemInfo, OoxmlNodeLike, type ParagraphState, type ParsedDefinition, REF_BOOKMARK_PREFIX, ReferencesPort, type ReferencesReader, type RefreshResult, type ReplacedSpan, SIGNATURE_FIELDS_NAMESPACE, SIGNATURE_FIELD_KINDS, SIGNATURE_FIELD_LABELS, SIGNATURE_FIELD_TAG_PREFIX, type SectionState, type SignatureFieldKind, type SignatureFieldPayload, type SignatureFieldSpec, type StaleReference, type TermChange, TermEverywhereError, type TermEverywhereResult, type TermSkip, type TermSkipReason, type TermSpec, type TermUse, type UndoRecord, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, ensureTargetBookmark, esc, fieldNodeIds, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, isSignerEmail, markCrossReferenceTarget, newRefBookmark, newSignatureFieldKey, paragraphIndex, paragraphRunsXml, paragraphState, parseDefinition, parseSignatureFieldTag, readDocument, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, signatureFieldControls, signatureFieldLabel, signatureFieldTag, signatureFieldWrite, staleCrossReferences, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
package/dist/commands.js CHANGED
@@ -506,11 +506,84 @@ function paragraphRunsXml(paragraph) {
506
506
  }
507
507
  return runs.length ? runs.join("") : null;
508
508
  }
509
+
510
+ // src/commands/signatureFields.ts
511
+ var SIGNATURE_FIELDS_NAMESPACE = "urn:arbi:signature-fields";
512
+ var SIGNATURE_FIELD_TAG_PREFIX = "arbi-signature:";
513
+ var SIGNATURE_FIELD_KINDS = ["signature", "initials", "date", "name"];
514
+ var SIGNATURE_FIELD_LABELS = {
515
+ signature: "Signature",
516
+ initials: "Initials",
517
+ date: "Date signed",
518
+ name: "Name"
519
+ };
520
+ var TAG = /^arbi-signature:(signature|initials|date|name)(?::([0-9a-f]{8}))?$/;
521
+ var EMAIL = /^[^@\s<>,;]{1,64}@[^@\s<>,;]{1,255}\.[^@\s<>,;]{1,63}$/;
522
+ var isSignerEmail = (value) => EMAIL.test(value.trim());
523
+ function newSignatureFieldKey() {
524
+ const bytes = new Uint8Array(4);
525
+ globalThis.crypto.getRandomValues(bytes);
526
+ return [...bytes].map((b) => b.toString(16).padStart(2, "0")).join("");
527
+ }
528
+ var signatureFieldTag = (kind, key) => `${SIGNATURE_FIELD_TAG_PREFIX}${kind}${key ? `:${key}` : ""}`;
529
+ var signatureFieldLabel = (kind, who) => who?.trim() ? `${SIGNATURE_FIELD_LABELS[kind]} \u2014 ${who.trim()}` : SIGNATURE_FIELD_LABELS[kind];
530
+ function parseSignatureFieldTag(tag) {
531
+ const m = TAG.exec(tag ?? "");
532
+ return m ? { kind: m[1], key: m[2] ?? null } : null;
533
+ }
534
+ function signatureFieldWrite(spec, at, key = newSignatureFieldKey()) {
535
+ const email = spec.email?.trim().toLowerCase() || null;
536
+ if (email && !isSignerEmail(email)) throw new Error("Enter the signer\u2019s email address.");
537
+ const name = spec.name?.trim().slice(0, 200) || null;
538
+ const text = signatureFieldLabel(spec.kind, name || email);
539
+ const payload = email ? { key, kind: spec.kind, email, name, required: spec.required !== false } : null;
540
+ return {
541
+ key: payload ? key : null,
542
+ tag: signatureFieldTag(spec.kind, payload ? key : null),
543
+ write: {
544
+ paragraphId: at.paragraphId,
545
+ offset: at.offset,
546
+ tag: signatureFieldTag(spec.kind, payload ? key : null),
547
+ text,
548
+ alias: text,
549
+ lock: "contentLocked",
550
+ ...payload ? {
551
+ payload: {
552
+ namespaceUri: SIGNATURE_FIELDS_NAMESPACE,
553
+ rootLocalName: "fields",
554
+ nodeId: `sig-${key}`,
555
+ label: text,
556
+ data: JSON.stringify(payload)
557
+ }
558
+ } : {}
559
+ }
560
+ };
561
+ }
562
+ var attr2 = (node, name) => node?.attributes?.find((a) => a.localName === name)?.value;
563
+ function signatureFieldControls(root) {
564
+ const out = [];
565
+ const visit = (node) => {
566
+ if (node.localName === "sdt") {
567
+ const props = node.children?.find((c) => c.localName === "sdtPr");
568
+ const tag = attr2(
569
+ props?.children?.find((c) => c.localName === "tag"),
570
+ "val"
571
+ );
572
+ const parsed = parseSignatureFieldTag(tag);
573
+ if (parsed && tag) out.push({ nodeId: node.id, tag, ...parsed });
574
+ }
575
+ if (node.kind !== "textValue") for (const child2 of node.children ?? []) visit(child2);
576
+ };
577
+ visit(root);
578
+ return out;
579
+ }
580
+
581
+ // src/commands/undo.ts
509
582
  var AGENT_UNDO_MAP = "agentUndo";
510
- var attr2 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
583
+ var attr3 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
511
584
  var child = (node, name) => node?.children?.find((c) => c.localName === name);
512
585
  var twips = (node, name) => {
513
- const value = node && attr2(node, name);
586
+ const value = node && attr3(node, name);
514
587
  return value === void 0 ? void 0 : Number(value);
515
588
  };
516
589
  var FLAT = new Set(
@@ -523,7 +596,7 @@ function paragraphIndex(root) {
523
596
  for (const c of node.children ?? []) {
524
597
  parentOf.set(c, node);
525
598
  if (c.kind === "paragraph") {
526
- const id = attr2(c, "paraId");
599
+ const id = attr3(c, "paraId");
527
600
  if (id) byParaId.set(id, c);
528
601
  }
529
602
  if (c.kind !== "textValue") visit(c);
@@ -545,28 +618,28 @@ function paragraphState(paragraph) {
545
618
  attributes: Object.fromEntries((p.attributes ?? []).map((a) => [a.localName, a.value]))
546
619
  });
547
620
  } else if (p.localName === "numPr") {
548
- const numId = attr2(child(p, "numId") ?? p, "val");
549
- if (numId) numbering = { numId, level: Number(attr2(child(p, "ilvl") ?? p, "val") ?? 0) };
621
+ const numId = attr3(child(p, "numId") ?? p, "val");
622
+ if (numId) numbering = { numId, level: Number(attr3(child(p, "ilvl") ?? p, "val") ?? 0) };
550
623
  } else if (p.localName === "tabs") {
551
624
  for (const tab of p.children ?? []) {
552
- const val = attr2(tab, "val");
625
+ const val = attr3(tab, "val");
553
626
  if (!val || val === "clear") continue;
554
627
  tabs.push({
555
- positionTwips: Number(attr2(tab, "pos") ?? 0),
628
+ positionTwips: Number(attr3(tab, "pos") ?? 0),
556
629
  alignment: val === "start" ? "left" : val === "end" ? "right" : val,
557
- ...attr2(tab, "leader") ? { leader: attr2(tab, "leader") } : {}
630
+ ...attr3(tab, "leader") ? { leader: attr3(tab, "leader") } : {}
558
631
  });
559
632
  }
560
633
  }
561
634
  }
562
- return { paraId: attr2(paragraph, "paraId") ?? "", properties, numbering, tabs };
635
+ return { paraId: attr3(paragraph, "paraId") ?? "", properties, numbering, tabs };
563
636
  }
564
637
  function sectionStates(root) {
565
638
  const { body } = paragraphIndex(root);
566
639
  const state = (sectPr, paraId) => {
567
640
  const size = child(sectPr, "pgSz");
568
641
  const margin = child(sectPr, "pgMar");
569
- const orient = size && attr2(size, "orient");
642
+ const orient = size && attr3(size, "orient");
570
643
  return {
571
644
  paraId,
572
645
  pageWidthTwips: twips(size, "w"),
@@ -581,7 +654,7 @@ function sectionStates(root) {
581
654
  const out = [];
582
655
  for (const block of body.children ?? []) {
583
656
  const sectPr = block.kind === "paragraph" ? child(child(block, "pPr"), "sectPr") : void 0;
584
- if (sectPr) out.push(state(sectPr, attr2(block, "paraId") ?? null));
657
+ if (sectPr) out.push(state(sectPr, attr3(block, "paraId") ?? null));
585
658
  else if (block.localName === "sectPr") out.push(state(block, null));
586
659
  }
587
660
  return out;
@@ -600,10 +673,10 @@ function tableState(root, paraId) {
600
673
  for (const row of table.children ?? []) {
601
674
  if (row.localName !== "tr") continue;
602
675
  const header = child(child(row, "trPr"), "tblHeader");
603
- if (!header || ["0", "false", "off"].includes(attr2(header, "val") ?? "")) break;
676
+ if (!header || ["0", "false", "off"].includes(attr3(header, "val") ?? "")) break;
604
677
  headerRowCount++;
605
678
  }
606
- return { kind: "table", paraId, styleId: (style && attr2(style, "val")) ?? null, headerRowCount };
679
+ return { kind: "table", paraId, styleId: (style && attr3(style, "val")) ?? null, headerRowCount };
607
680
  }
608
681
  function fieldNodeIds(paragraph) {
609
682
  const out = [];
@@ -612,7 +685,7 @@ function fieldNodeIds(paragraph) {
612
685
  for (const c of node.children ?? []) {
613
686
  if (c.localName === "del") continue;
614
687
  if (c.localName === "fldChar") {
615
- const type = attr2(c, "fldCharType");
688
+ const type = attr3(c, "fldCharType");
616
689
  if (type === "begin" && depth++ === 0) out.push(c.id);
617
690
  else if (type === "end") depth = Math.max(0, depth - 1);
618
691
  } else if (c.kind !== "textValue") walk(c);
@@ -656,6 +729,15 @@ function undoOps(root, record) {
656
729
  styleId: record.styleId ?? "",
657
730
  headerRowCount: record.headerRowCount
658
731
  });
732
+ } else if (record.kind === "signatureField") {
733
+ const controls = signatureFieldControls(root).filter((c) => c.tag === record.tag);
734
+ if (!controls.length) return null;
735
+ for (const control of controls) {
736
+ ops.push(
737
+ { op: "setContentControlProperties", controlId: control.nodeId, lock: "unlocked" },
738
+ { op: "removeContentControl", controlId: control.nodeId, keepContent: false }
739
+ );
740
+ }
659
741
  } else {
660
742
  const updates = [];
661
743
  for (const { paraId, index, text } of record.fields) {
@@ -1036,12 +1118,12 @@ function fragmentPackage(body, covered, {
1036
1118
  });
1037
1119
  return revision ? trackInsertion(untracked, revision, covered) : untracked;
1038
1120
  }
1039
- var attr3 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1121
+ var attr4 = (node, name) => node.attributes?.find((a) => a.localName === name)?.value;
1040
1122
  function documentStyleIds(root) {
1041
1123
  const ids = /* @__PURE__ */ new Set();
1042
1124
  for (const style of root?.children ?? [])
1043
1125
  if (style.localName === "style") {
1044
- const id = attr3(style, "styleId");
1126
+ const id = attr4(style, "styleId");
1045
1127
  if (id) ids.add(id);
1046
1128
  }
1047
1129
  return ids;
@@ -1354,6 +1436,6 @@ function readDocument(bytes) {
1354
1436
  return documentReader(opened.view);
1355
1437
  }
1356
1438
 
1357
- export { AGENT_UNDO_MAP, BROKEN_CROSS_REFERENCE_STYLE, CHARACTER_STYLES, CROSS_REFERENCE_STYLE, DEFINED_TERM_STYLE, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, FIELD_ATOM, REF_BOOKMARK_PREFIX, TermEverywhereError, WATCHED_STYLES, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentNumbering, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, engineLength, engineOffset, ensureTargetBookmark, esc, fieldNodeIds, filterTargets, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, listTargets, markCrossReferenceTarget, newRefBookmark, paragraphIndex, paragraphNumber, paragraphRunsXml, paragraphState, parseDefinition, readDocument, readParagraphs, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, staleCrossReferences, styleNames, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
1439
+ export { AGENT_UNDO_MAP, BROKEN_CROSS_REFERENCE_STYLE, CHARACTER_STYLES, CROSS_REFERENCE_STYLE, DEFINED_TERM_STYLE, DEFINITIONS_HEADING, DEFINITION_BOOKMARK_PREFIX, FIELD_ATOM, REF_BOOKMARK_PREFIX, SIGNATURE_FIELDS_NAMESPACE, SIGNATURE_FIELD_KINDS, SIGNATURE_FIELD_LABELS, SIGNATURE_FIELD_TAG_PREFIX, TermEverywhereError, WATCHED_STYLES, W_NAMESPACES, addDefinition, applyTermEverywhere, brokenCrossReferences, compareTerms, crossReferenceXml, crossReferences, definitionBookmark, definitionIdOfBookmark, definitionOfAnchor, definitionParagraphText, definitionParagraphXml, definitionTooltip, definitionsById, documentNumbering, documentReader, documentReferenceTooltip, documentStyleIds, documentXml, docxPackage, engineLength, engineOffset, ensureTargetBookmark, esc, fieldNodeIds, filterTargets, findDefinitionsSection, findTermUses, fragmentPackage, headingParagraphXml, hyperlinkRelationship, insertCrossReference, insertCrossReferenceField, insertDefinedTerm, insertDocumentReference, insertionIndex, isDefinitionsTitle, isSignerEmail, listTargets, markCrossReferenceTarget, newRefBookmark, newSignatureFieldKey, paragraphIndex, paragraphNumber, paragraphRunsXml, paragraphState, parseDefinition, parseSignatureFieldTag, readDocument, readParagraphs, refFieldXml, refInstruction, refResult, refTooltip, refreshCrossReferences, replaceSpan, sectionStates, signatureFieldControls, signatureFieldLabel, signatureFieldTag, signatureFieldWrite, staleCrossReferences, styleNames, stylesUsed, stylesXml, tableOf, tableState, termKey, termLinkXml, undoOps, withoutArticle };
1358
1440
  //# sourceMappingURL=commands.js.map
1359
1441
  //# sourceMappingURL=commands.js.map