@a3s-lab/office 0.47.0 → 0.48.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.
@@ -1,6 +1,7 @@
1
1
  import jszip from "jszip";
2
2
  import { normalizeDocumentIndexEntryDraft, serializeUtf8Xml, directChildren, xmlNamespacePrefix, normalizeDocumentLanguageTag, parseXml, firstDescendant, decodeXmlBytes, directChild, descendants, normalizeDocumentProofingLanguages, attribute as work_ooxml_package_attribute, normalizeDocumentIndexOptions } from "./6968.js";
3
3
  import { normalizeDocumentEmphasisMark, normalizeDocumentCharacterScalePercent, documentCitationStyle, normalizeDocumentCharacterPositionHalfPoints, normalizeDocumentCharacterSpacingTwips, normalizeDocumentKerningThresholdHalfPoints, normalizeDocumentOpenTypeNumberSpacing, createDocumentBibliography, normalizeDocumentImageTransform, normalizeDocumentOpenTypeLigatures, normalizeDocumentOpenTypeNumberForm, normalizeDocumentTabStops, documentCitationStyleDetails, normalizeDocumentOpenTypeStylisticSets } from "./4174.js";
4
+ import { normalizeDocumentHref } from "./0~work-document-links.js";
4
5
  const BIBLIOGRAPHY_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/bibliography';
5
6
  const CUSTOM_XML_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/customXml';
6
7
  const OFFICE_RELATIONSHIPS_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
@@ -708,6 +709,511 @@ function isAllowedExtensionNamespace(namespace, context) {
708
709
  function isNamespacePrefix(value) {
709
710
  return /^[A-Za-z_][A-Za-z0-9_.-]*$/.test(value) && 'xml' !== value;
710
711
  }
712
+ const PACKAGE_RELATIONSHIP_NAMESPACE = 'http://schemas.openxmlformats.org/package/2006/relationships';
713
+ const TRANSITIONAL_RELATIONSHIP_NAMESPACE = 'http://schemas.openxmlformats.org/officeDocument/2006/relationships';
714
+ const STRICT_RELATIONSHIP_NAMESPACE = 'http://purl.oclc.org/ooxml/officeDocument/relationships';
715
+ const work_docx_note_comment_hyperlink_relationships_RELATIONSHIP_NAMESPACES = new Set([
716
+ TRANSITIONAL_RELATIONSHIP_NAMESPACE,
717
+ STRICT_RELATIONSHIP_NAMESPACE
718
+ ]);
719
+ const HYPERLINK_RELATIONSHIP_TYPES = new Set([
720
+ `${TRANSITIONAL_RELATIONSHIP_NAMESPACE}/hyperlink`,
721
+ `${STRICT_RELATIONSHIP_NAMESPACE}/hyperlink`
722
+ ]);
723
+ const GENERATED_HYPERLINK_RELATIONSHIP_TYPE = `${TRANSITIONAL_RELATIONSHIP_NAMESPACE}/hyperlink`;
724
+ const RELATIONSHIP_ID_PATTERN = /^[A-Za-z_][A-Za-z0-9_.-]{0,254}$/;
725
+ const MAX_RELATIONSHIPS = 65536;
726
+ async function loadDocxHyperlinkRelationshipState(generatedArchive, sourceArchive, ownerPart) {
727
+ const path = work_docx_note_comment_hyperlink_relationships_relationshipPartPath(ownerPart);
728
+ const [generated, source] = await Promise.all([
729
+ loadRelationships(generatedArchive, path, 'generated'),
730
+ loadRelationships(sourceArchive, path, 'source')
731
+ ]);
732
+ return {
733
+ archive: generatedArchive,
734
+ dirty: false,
735
+ generated: generated.document,
736
+ generatedMalformed: generated.malformed,
737
+ path,
738
+ source: source.document
739
+ };
740
+ }
741
+ function readDocxHyperlinkDestination(hyperlink, state, role) {
742
+ if (!DOCX_WORDPROCESSING_NAMESPACES.has(hyperlink.namespaceURI ?? '')) return null;
743
+ const anchor = uniqueNamespacedAttribute(hyperlink, 'anchor', DOCX_WORDPROCESSING_NAMESPACES);
744
+ const relationshipId = uniqueNamespacedAttribute(hyperlink, 'id', work_docx_note_comment_hyperlink_relationships_RELATIONSHIP_NAMESPACES);
745
+ if (void 0 === anchor || void 0 === relationshipId) return null;
746
+ const normalizedAnchor = null === anchor ? null : normalizeAnchor(anchor);
747
+ if (null !== anchor && !normalizedAnchor) return null;
748
+ if (normalizedAnchor && relationshipId) return null;
749
+ if (normalizedAnchor) return {
750
+ kind: 'internal',
751
+ target: normalizedAnchor
752
+ };
753
+ if (!relationshipId || !RELATIONSHIP_ID_PATTERN.test(relationshipId)) return null;
754
+ const relationships = 'generated' === role ? state.generated : state.source;
755
+ const relationship = relationships?.byId.get(relationshipId);
756
+ if (!relationship || !isExternalHyperlinkRelationship(relationship)) return null;
757
+ const target = normalizeDocumentHref(relationship.target);
758
+ if (!target || target.startsWith('#')) return null;
759
+ return {
760
+ kind: 'external',
761
+ relationshipId,
762
+ target
763
+ };
764
+ }
765
+ function ensureDocxExternalHyperlinkRelationships(state, requests) {
766
+ if (!requests.length) return [];
767
+ if (state.generatedMalformed) return null;
768
+ const relationships = state.generated ?? createRelationshipsDocument();
769
+ const usedIds = new Set(relationships.usedIds);
770
+ const idByTarget = new Map(Array.from(relationships.byId.values()).flatMap((item)=>{
771
+ const target = isExternalHyperlinkRelationship(item) ? normalizeDocumentHref(item.target) : null;
772
+ return target && !target.startsWith('#') ? [
773
+ [
774
+ target,
775
+ item.id
776
+ ]
777
+ ] : [];
778
+ }));
779
+ const pending = [];
780
+ const result = [];
781
+ for (const request of requests){
782
+ if (!RELATIONSHIP_ID_PATTERN.test(request.sourceId)) return null;
783
+ const target = normalizeDocumentHref(request.target);
784
+ if (!target || target.startsWith('#')) return null;
785
+ const existingId = idByTarget.get(target);
786
+ if (existingId) {
787
+ result.push(existingId);
788
+ continue;
789
+ }
790
+ if (usedIds.size >= MAX_RELATIONSHIPS) return null;
791
+ const id = usedIds.has(request.sourceId) ? work_docx_note_comment_hyperlink_relationships_nextRelationshipId(usedIds) : request.sourceId;
792
+ usedIds.add(id);
793
+ idByTarget.set(target, id);
794
+ pending.push({
795
+ id,
796
+ target
797
+ });
798
+ result.push(id);
799
+ }
800
+ if (!pending.length) return result;
801
+ state.generated = relationships;
802
+ for (const item of pending)appendExternalHyperlinkRelationship(relationships, item.id, item.target);
803
+ state.dirty = true;
804
+ return result;
805
+ }
806
+ function setDocxHyperlinkDestination(hyperlink, root, destination, relationshipId) {
807
+ removeNamespacedAttribute(hyperlink, 'anchor', DOCX_WORDPROCESSING_NAMESPACES);
808
+ removeNamespacedAttribute(hyperlink, 'id', work_docx_note_comment_hyperlink_relationships_RELATIONSHIP_NAMESPACES);
809
+ if ('internal' === destination.kind) {
810
+ const namespace = hyperlink.namespaceURI;
811
+ if (!namespace || !DOCX_WORDPROCESSING_NAMESPACES.has(namespace)) return false;
812
+ setNamespacedAttribute(hyperlink, root, namespace, 'w', 'anchor', destination.target);
813
+ return true;
814
+ }
815
+ if (!relationshipId || !RELATIONSHIP_ID_PATTERN.test(relationshipId)) return false;
816
+ setNamespacedAttribute(hyperlink, root, TRANSITIONAL_RELATIONSHIP_NAMESPACE, 'r', 'id', relationshipId);
817
+ return true;
818
+ }
819
+ function flushDocxHyperlinkRelationships(state) {
820
+ if (!state.dirty || !state.generated) return;
821
+ state.archive.file(state.path, serializeUtf8Xml(state.generated.document));
822
+ }
823
+ function normalizeAnchor(value) {
824
+ const anchor = value.trim();
825
+ return anchor.length <= 255 && normalizeDocumentHref(`#${anchor}`) ? anchor : null;
826
+ }
827
+ function isExternalHyperlinkRelationship(relationship) {
828
+ return HYPERLINK_RELATIONSHIP_TYPES.has(relationship.type) && 'external' === relationship.targetMode.toLowerCase();
829
+ }
830
+ async function loadRelationships(archive, path, role) {
831
+ const entry = archive.file(path);
832
+ if (!entry) return {
833
+ document: null,
834
+ malformed: false
835
+ };
836
+ try {
837
+ const document = parseXml(decodeXmlBytes(await entry.async('uint8array'), `${role} DOCX ${path}`), `${role} DOCX ${path}`);
838
+ const root = document.documentElement;
839
+ if ('Relationships' !== root.localName || root.namespaceURI !== PACKAGE_RELATIONSHIP_NAMESPACE) return {
840
+ document: null,
841
+ malformed: true
842
+ };
843
+ const byId = new Map();
844
+ const usedIds = new Set();
845
+ const elements = directChildren(root);
846
+ if (elements.length > MAX_RELATIONSHIPS) return {
847
+ document: null,
848
+ malformed: true
849
+ };
850
+ for (const element of elements){
851
+ if ('Relationship' !== element.localName || element.namespaceURI !== PACKAGE_RELATIONSHIP_NAMESPACE) return {
852
+ document: null,
853
+ malformed: true
854
+ };
855
+ const record = relationshipRecord(element);
856
+ if (!record || usedIds.has(record.id)) return {
857
+ document: null,
858
+ malformed: true
859
+ };
860
+ byId.set(record.id, record);
861
+ usedIds.add(record.id);
862
+ }
863
+ return {
864
+ document: {
865
+ byId,
866
+ document,
867
+ usedIds
868
+ },
869
+ malformed: false
870
+ };
871
+ } catch {
872
+ return {
873
+ document: null,
874
+ malformed: true
875
+ };
876
+ }
877
+ }
878
+ function relationshipRecord(element) {
879
+ const id = element.getAttribute('Id')?.trim() ?? '';
880
+ const target = element.getAttribute('Target')?.trim() ?? '';
881
+ const type = element.getAttribute('Type')?.trim() ?? '';
882
+ const targetMode = element.getAttribute('TargetMode')?.trim() ?? '';
883
+ if (!RELATIONSHIP_ID_PATTERN.test(id) || !target || !type) return null;
884
+ return {
885
+ id,
886
+ target,
887
+ targetMode,
888
+ type
889
+ };
890
+ }
891
+ function createRelationshipsDocument() {
892
+ const document = parseXml(`<Relationships xmlns="${PACKAGE_RELATIONSHIP_NAMESPACE}"/>`, 'generated DOCX hyperlink relationships');
893
+ return {
894
+ byId: new Map(),
895
+ document,
896
+ usedIds: new Set()
897
+ };
898
+ }
899
+ function appendExternalHyperlinkRelationship(relationships, id, target) {
900
+ const element = relationships.document.createElementNS(PACKAGE_RELATIONSHIP_NAMESPACE, 'Relationship');
901
+ element.setAttribute('Id', id);
902
+ element.setAttribute('Type', GENERATED_HYPERLINK_RELATIONSHIP_TYPE);
903
+ element.setAttribute('Target', target);
904
+ element.setAttribute('TargetMode', 'External');
905
+ relationships.document.documentElement.append(element);
906
+ relationships.byId.set(id, {
907
+ id,
908
+ target,
909
+ targetMode: 'External',
910
+ type: GENERATED_HYPERLINK_RELATIONSHIP_TYPE
911
+ });
912
+ relationships.usedIds.add(id);
913
+ }
914
+ function uniqueNamespacedAttribute(element, localName, namespaces) {
915
+ const matches = Array.from(element.attributes).filter((item)=>xmlAttributeLocalName(item) === localName && namespaces.has(xmlAttributeNamespace(element, item) ?? ''));
916
+ return matches.length <= 1 ? matches[0]?.value.trim() ?? null : void 0;
917
+ }
918
+ function removeNamespacedAttribute(element, localName, namespaces) {
919
+ for (const item of Array.from(element.attributes))if (xmlAttributeLocalName(item) === localName && namespaces.has(xmlAttributeNamespace(element, item) ?? '')) element.removeAttributeNode(item);
920
+ }
921
+ function setNamespacedAttribute(element, root, namespace, preferredPrefix, localName, value) {
922
+ let prefix = xmlDeclaredPrefix(element, namespace) ?? xmlDeclaredPrefix(root, namespace);
923
+ if (!prefix) {
924
+ prefix = availablePrefix(root, preferredPrefix);
925
+ root.setAttributeNS(XMLNS_NAMESPACE, `xmlns:${prefix}`, namespace);
926
+ }
927
+ element.setAttributeNS(namespace, `${prefix}:${localName}`, value);
928
+ }
929
+ function availablePrefix(root, preferred) {
930
+ if (!xmlNamespaceUri(root, preferred)) return preferred;
931
+ let index = 1;
932
+ while(xmlNamespaceUri(root, `${preferred}${index}`))index += 1;
933
+ return `${preferred}${index}`;
934
+ }
935
+ function work_docx_note_comment_hyperlink_relationships_nextRelationshipId(used) {
936
+ let index = 1;
937
+ while(used.has(`rId${index}`))index += 1;
938
+ return `rId${index}`;
939
+ }
940
+ function work_docx_note_comment_hyperlink_relationships_relationshipPartPath(ownerPart) {
941
+ const separator = ownerPart.lastIndexOf('/');
942
+ const directory = separator < 0 ? '' : ownerPart.slice(0, separator + 1);
943
+ const file = ownerPart.slice(separator + 1);
944
+ return `${directory}_rels/${file}.rels`;
945
+ }
946
+ const work_docx_note_comment_hyperlink_content_MARKUP_COMPATIBILITY_NAMESPACE = 'http://schemas.openxmlformats.org/markup-compatibility/2006';
947
+ const MAX_PARAGRAPHS = 65536;
948
+ const MAX_RUNS = 262144;
949
+ const MAX_COMMENT_RUN_SEGMENTS = 4096;
950
+ function noteCommentContentParagraphs(scope, role, relationships, limits) {
951
+ const paragraphs = descendants(scope, 'p').filter(isWordElement);
952
+ const paragraphKey = `${role}Paragraphs`;
953
+ limits[paragraphKey] += paragraphs.length;
954
+ if (limits[paragraphKey] > MAX_PARAGRAPHS) throw new Error(`${roleLabel(role)} DOCX exceeds the stable note/comment hyperlink paragraph limit.`);
955
+ const result = [];
956
+ for (const paragraph of paragraphs){
957
+ const runKey = `${role}Runs`;
958
+ limits[runKey] += directContentRunCount(paragraph);
959
+ if (limits[runKey] > MAX_RUNS) throw new Error(`${roleLabel(role)} DOCX exceeds the stable note/comment hyperlink run limit.`);
960
+ const content = noteCommentParagraphContent(paragraph, relationships, role);
961
+ if (!content?.text) continue;
962
+ const ancestry = paragraphAncestry(paragraph, scope);
963
+ if (ancestry) result.push({
964
+ element: paragraph,
965
+ hyperlinks: content.hyperlinks,
966
+ identity: `${ancestry}\u0000${content.text}`,
967
+ runs: content.runs,
968
+ text: content.text
969
+ });
970
+ }
971
+ return result;
972
+ }
973
+ function directContentRunCount(paragraph) {
974
+ let count = 0;
975
+ for (const child of Array.from(paragraph.children))if (isWordElement(child)) {
976
+ if ('r' === child.localName) count += 1;
977
+ if ('hyperlink' === child.localName) count += wordDirectChildren(child, 'r').length;
978
+ }
979
+ return count;
980
+ }
981
+ function noteCommentParagraphContent(paragraph, relationships, role) {
982
+ const runs = [];
983
+ const hyperlinks = [];
984
+ let offset = 0;
985
+ let paragraphProperties = 0;
986
+ for (const child of Array.from(paragraph.children)){
987
+ if (!isWordElement(child)) {
988
+ if (isContentSemanticNamespace(child.namespaceURI ?? '')) return null;
989
+ continue;
990
+ }
991
+ if ('pPr' === child.localName) {
992
+ paragraphProperties += 1;
993
+ if (paragraphProperties > 1) return null;
994
+ continue;
995
+ }
996
+ if ('r' === child.localName) {
997
+ const text = contentRunText(child);
998
+ if (null === text) return null;
999
+ const start = offset;
1000
+ offset += text.length;
1001
+ if (text) runs.push({
1002
+ container: null,
1003
+ element: child,
1004
+ start,
1005
+ end: offset,
1006
+ text
1007
+ });
1008
+ continue;
1009
+ }
1010
+ if ('hyperlink' !== child.localName) return null;
1011
+ const start = offset;
1012
+ for (const hyperlinkChild of Array.from(child.children)){
1013
+ if (!isWordElement(hyperlinkChild)) {
1014
+ if (isContentSemanticNamespace(hyperlinkChild.namespaceURI ?? '')) return null;
1015
+ continue;
1016
+ }
1017
+ if ('r' !== hyperlinkChild.localName) return null;
1018
+ const text = contentRunText(hyperlinkChild);
1019
+ if (null === text) return null;
1020
+ const runStart = offset;
1021
+ offset += text.length;
1022
+ if (text) runs.push({
1023
+ container: child,
1024
+ element: hyperlinkChild,
1025
+ start: runStart,
1026
+ end: offset,
1027
+ text
1028
+ });
1029
+ }
1030
+ if (offset > start) hyperlinks.push({
1031
+ destination: readDocxHyperlinkDestination(child, relationships, role),
1032
+ element: child,
1033
+ start,
1034
+ end: offset,
1035
+ text: runs.filter((run)=>run.container === child).map((run)=>run.text).join('')
1036
+ });
1037
+ }
1038
+ return {
1039
+ hyperlinks,
1040
+ runs,
1041
+ text: runs.map((run)=>run.text).join('')
1042
+ };
1043
+ }
1044
+ function groupNoteCommentParagraphs(paragraphs) {
1045
+ const result = new Map();
1046
+ for (const paragraph of paragraphs){
1047
+ const matches = result.get(paragraph.identity) ?? [];
1048
+ matches.push(paragraph);
1049
+ result.set(paragraph.identity, matches);
1050
+ }
1051
+ return result;
1052
+ }
1053
+ function groupNoteCommentHyperlinks(hyperlinks) {
1054
+ const result = new Map();
1055
+ for (const hyperlink of hyperlinks){
1056
+ const key = noteCommentHyperlinkSpanKey(hyperlink);
1057
+ const matches = result.get(key) ?? [];
1058
+ matches.push(hyperlink);
1059
+ result.set(key, matches);
1060
+ }
1061
+ return result;
1062
+ }
1063
+ function noteCommentHyperlinkSpanKey(item) {
1064
+ return `${item.start}:${item.end}:${item.text}`;
1065
+ }
1066
+ function noteCommentHyperlinksOverlap(left, right) {
1067
+ return left.start < right.end && right.start < left.end;
1068
+ }
1069
+ function restoreElementChildren(element, children) {
1070
+ while(element.firstChild)element.removeChild(element.firstChild);
1071
+ for (const child of children)element.append(child);
1072
+ }
1073
+ function alignCommentRunBoundaries(generated, source) {
1074
+ if (generated.hyperlinks.length || 1 !== generated.runs.length || generated.runs[0].container || source.runs.length <= 1 || source.runs.length > MAX_COMMENT_RUN_SEGMENTS || !isSimpleTextRun(generated.runs[0].element) || source.runs.some((run)=>!isSimpleTextRun(run.element))) return false;
1075
+ const original = generated.runs[0].element;
1076
+ if (!original.parentNode) return false;
1077
+ const clones = [];
1078
+ for (const sourceRun of source.runs){
1079
+ const clone = original.cloneNode(true);
1080
+ const textElement = wordDirectChildren(clone, 't')[0];
1081
+ if (!textElement) return false;
1082
+ textElement.textContent = sourceRun.text;
1083
+ setTextSpacePreservation(textElement, sourceRun.text);
1084
+ clones.push(clone);
1085
+ }
1086
+ for (const clone of clones)original.parentNode.insertBefore(clone, original);
1087
+ original.remove();
1088
+ return true;
1089
+ }
1090
+ function isKnownOoxmlNamespace(namespace) {
1091
+ if (namespace === work_docx_note_comment_hyperlink_content_MARKUP_COMPATIBILITY_NAMESPACE) return false;
1092
+ return DOCX_WORDPROCESSING_NAMESPACES.has(namespace) || namespace.startsWith('http://schemas.microsoft.com/office/') || namespace.startsWith('http://schemas.openxmlformats.org/') || namespace.startsWith('http://purl.oclc.org/ooxml/') || namespace.startsWith('urn:schemas-microsoft-com:') || namespace.startsWith('urn:microsoft-com:office:');
1093
+ }
1094
+ function contentRunText(run) {
1095
+ let text = '';
1096
+ for (const child of Array.from(run.children)){
1097
+ if (!isWordElement(child)) {
1098
+ if (isContentSemanticNamespace(child.namespaceURI ?? '')) return null;
1099
+ continue;
1100
+ }
1101
+ if ('rPr' !== child.localName) {
1102
+ if ('t' === child.localName || 'delText' === child.localName) text += child.textContent ?? '';
1103
+ else if ('tab' === child.localName) text += '\t';
1104
+ else if ('br' === child.localName || 'cr' === child.localName) text += '\n';
1105
+ else if ('noBreakHyphen' === child.localName) text += '\u2011';
1106
+ else if ('softHyphen' === child.localName) text += '\u00ad';
1107
+ else if ('footnoteRef' !== child.localName && 'endnoteRef' !== child.localName) return null;
1108
+ }
1109
+ }
1110
+ return text;
1111
+ }
1112
+ function isSimpleTextRun(run) {
1113
+ const children = Array.from(run.children).filter(isWordElement);
1114
+ return 1 === children.filter((child)=>'t' === child.localName).length && children.every((child)=>'rPr' === child.localName || 't' === child.localName);
1115
+ }
1116
+ function setTextSpacePreservation(element, text) {
1117
+ for (const item of Array.from(element.attributes))if ('space' === xmlAttributeLocalName(item) && xmlAttributeNamespace(element, item) === XML_NAMESPACE) element.removeAttributeNode(item);
1118
+ if (/^\s|\s$/u.test(text)) element.setAttributeNS(XML_NAMESPACE, 'xml:space', 'preserve');
1119
+ }
1120
+ function paragraphAncestry(paragraph, scope) {
1121
+ const path = [];
1122
+ let current = paragraph;
1123
+ while(current && current !== scope){
1124
+ if (!isWordElement(current)) return null;
1125
+ path.push(current.localName);
1126
+ current = current.parentElement;
1127
+ }
1128
+ return current === scope ? path.reverse().join('/') : null;
1129
+ }
1130
+ function isContentSemanticNamespace(namespace) {
1131
+ return namespace === work_docx_note_comment_hyperlink_content_MARKUP_COMPATIBILITY_NAMESPACE || isKnownOoxmlNamespace(namespace);
1132
+ }
1133
+ function wordDirectChildren(element, localName) {
1134
+ return Array.from(element.children).filter((child)=>child.localName === localName && isWordElement(child));
1135
+ }
1136
+ function isWordElement(element) {
1137
+ return DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '');
1138
+ }
1139
+ function roleLabel(role) {
1140
+ return 'source' === role ? 'Registered source' : 'Generated';
1141
+ }
1142
+ const CONTENT_CONTROL_MC_NAMESPACE = 'http://schemas.openxmlformats.org/markup-compatibility/2006';
1143
+ const CONTENT_CONTROL_RELATIONSHIP_NAMESPACES = new Set([
1144
+ 'http://schemas.openxmlformats.org/officeDocument/2006/relationships',
1145
+ 'http://purl.oclc.org/ooxml/officeDocument/relationships'
1146
+ ]);
1147
+ const CONTENT_CONTROL_WORD_2012_NAMESPACE = 'http://schemas.microsoft.com/office/word/2012/wordml';
1148
+ function isContentControlSemanticNamespace(namespace) {
1149
+ return namespace === CONTENT_CONTROL_MC_NAMESPACE || CONTENT_CONTROL_RELATIONSHIP_NAMESPACES.has(namespace) || isKnownOoxmlNamespace(namespace);
1150
+ }
1151
+ function isDocxWordElement(element) {
1152
+ return DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '');
1153
+ }
1154
+ function work_docx_note_comment_content_control_xml_wordDirectChildren(element, localName) {
1155
+ return Array.from(element.children).filter((child)=>child.localName === localName && isDocxWordElement(child));
1156
+ }
1157
+ function hasOnlyPassiveContentControlAttributes(element) {
1158
+ return Array.from(element.attributes).every((item)=>{
1159
+ const namespace = xmlAttributeNamespace(element, item);
1160
+ return Boolean(namespace === XMLNS_NAMESPACE || namespace === CONTENT_CONTROL_MC_NAMESPACE || namespace && !CONTENT_CONTROL_RELATIONSHIP_NAMESPACES.has(namespace) && !isKnownOoxmlNamespace(namespace));
1161
+ });
1162
+ }
1163
+ function hasUnsupportedContentControlSemanticChild(element) {
1164
+ return Array.from(element.children).some((child)=>!isDocxWordElement(child) && isContentControlSemanticNamespace(child.namespaceURI ?? ''));
1165
+ }
1166
+ function hasContentControlRelationshipReference(root) {
1167
+ return [
1168
+ root,
1169
+ ...Array.from(root.querySelectorAll('*'))
1170
+ ].some((element)=>Array.from(element.attributes).some((item)=>CONTENT_CONTROL_RELATIONSHIP_NAMESPACES.has(xmlAttributeNamespace(element, item) ?? '')));
1171
+ }
1172
+ function createWordElement(document, context, localName) {
1173
+ const namespace = context.namespaceURI ?? [
1174
+ ...DOCX_WORDPROCESSING_NAMESPACES
1175
+ ][0];
1176
+ const prefix = xmlNamespacePrefix(context, namespace) ?? 'w';
1177
+ return document.createElementNS(namespace, `${prefix}:${localName}`);
1178
+ }
1179
+ function createNamespacedElement(document, context, namespace, preferredPrefix, localName) {
1180
+ const prefix = availableNamespacePrefix(context.ownerDocument.documentElement, namespace, preferredPrefix);
1181
+ return document.createElementNS(namespace, `${prefix}:${localName}`);
1182
+ }
1183
+ function setWordContentControlAttribute(element, context, localName, value) {
1184
+ const namespace = context.namespaceURI ?? [
1185
+ ...DOCX_WORDPROCESSING_NAMESPACES
1186
+ ][0];
1187
+ const prefix = xmlNamespacePrefix(context, namespace) ?? 'w';
1188
+ element.setAttributeNS(namespace, `${prefix}:${localName}`, value);
1189
+ }
1190
+ function setNamespacedContentControlAttribute(element, context, namespace, preferredPrefix, localName, value) {
1191
+ const prefix = availableNamespacePrefix(context.ownerDocument.documentElement, namespace, preferredPrefix);
1192
+ element.setAttributeNS(namespace, `${prefix}:${localName}`, value);
1193
+ }
1194
+ function ensureIgnorableContentControlNamespace(root, namespace, preferredPrefix) {
1195
+ const prefix = availableNamespacePrefix(root, namespace, preferredPrefix);
1196
+ if (!xmlNamespacePrefix(root, namespace)) root.setAttributeNS(XMLNS_NAMESPACE, `xmlns:${prefix}`, namespace);
1197
+ const mcPrefix = availableNamespacePrefix(root, CONTENT_CONTROL_MC_NAMESPACE, 'mc');
1198
+ if (!xmlNamespacePrefix(root, CONTENT_CONTROL_MC_NAMESPACE)) root.setAttributeNS(XMLNS_NAMESPACE, `xmlns:${mcPrefix}`, CONTENT_CONTROL_MC_NAMESPACE);
1199
+ const existing = Array.from(root.attributes).find((item)=>'Ignorable' === xmlAttributeLocalName(item) && xmlAttributeNamespace(root, item) === CONTENT_CONTROL_MC_NAMESPACE);
1200
+ const prefixes = new Set((existing?.value ?? '').trim().split(/\s+/u).filter(Boolean));
1201
+ prefixes.add(prefix);
1202
+ const value = Array.from(prefixes).join(' ');
1203
+ if (existing) existing.value = value;
1204
+ else root.setAttributeNS(CONTENT_CONTROL_MC_NAMESPACE, `${mcPrefix}:Ignorable`, value);
1205
+ }
1206
+ function availableNamespacePrefix(root, namespace, preferred) {
1207
+ const existing = xmlNamespacePrefix(root, namespace);
1208
+ if (existing) return existing;
1209
+ let prefix = preferred;
1210
+ let index = 1;
1211
+ while(xmlNamespaceUri(root, prefix)){
1212
+ prefix = `${preferred}${index}`;
1213
+ index += 1;
1214
+ }
1215
+ return prefix;
1216
+ }
711
1217
  const DOCX_ROTATION_UNITS_PER_DEGREE = 60000;
712
1218
  const DOCX_QUADRANT_ROTATION_UNITS = 5400000;
713
1219
  function readDocxImageTransform(drawing) {
@@ -1718,7 +2224,7 @@ function inspectDocxProofingLanguages(properties) {
1718
2224
  status: 'absent',
1719
2225
  spoofedCount: 0
1720
2226
  };
1721
- const native = matches.filter((element)=>isWordElement(element));
2227
+ const native = matches.filter((element)=>work_docx_proofing_isWordElement(element));
1722
2228
  const spoofedCount = matches.length - native.length;
1723
2229
  if (1 !== matches.length || 1 !== native.length) return {
1724
2230
  status: 'invalid',
@@ -1764,7 +2270,7 @@ function inspectDocxNoProof(properties) {
1764
2270
  status: 'absent',
1765
2271
  spoofedCount: 0
1766
2272
  };
1767
- const native = matches.filter((element)=>isWordElement(element));
2273
+ const native = matches.filter((element)=>work_docx_proofing_isWordElement(element));
1768
2274
  const spoofedCount = matches.length - native.length;
1769
2275
  if (1 !== matches.length || 1 !== native.length) return {
1770
2276
  status: 'invalid',
@@ -1835,7 +2341,7 @@ function documentProofingLanguageDocxOptions(source) {
1835
2341
  } : {}
1836
2342
  };
1837
2343
  }
1838
- function isWordElement(element) {
2344
+ function work_docx_proofing_isWordElement(element) {
1839
2345
  return DOCX_WORDPROCESSING_NAMESPACES.has(element.namespaceURI ?? '');
1840
2346
  }
1841
2347
  function work_docx_proofing_isNamespaceDeclaration(attribute) {
@@ -2180,4 +2686,4 @@ function isParagraphPartRoot(root, path) {
2180
2686
  const expected = /^word\/header\d*\.xml$/i.test(path) ? 'hdr' : /^word\/footer\d*\.xml$/i.test(path) ? 'ftr' : /^word\/footnotes\.xml$/i.test(path) ? 'footnotes' : /^word\/endnotes\.xml$/i.test(path) ? 'endnotes' : 'document';
2181
2687
  return root.localName === expected && DOCX_WORDPROCESSING_NAMESPACES.has(root.namespaceURI ?? '');
2182
2688
  }
2183
- export { DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxImageTransformPatchCollector, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, hasNonWhitespaceXmlText, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxImageTransforms, patchDocxParagraphDefaultCollapsed, readDocxBibliography, readDocxImageTransform, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };
2689
+ export { CONTENT_CONTROL_MC_NAMESPACE, CONTENT_CONTROL_RELATIONSHIP_NAMESPACES, CONTENT_CONTROL_WORD_2012_NAMESPACE, DOCX_COLOR_SCHEME_MAPPING_ATTRIBUTES, DOCX_WORDPROCESSING_NAMESPACES, DOCX_WORD_2010_NAMESPACE, DocxImageTransformPatchCollector, DocxParagraphDefaultCollapsedPatchCollector, STRICT_WORDPROCESSING_NAMESPACE, XMLNS_NAMESPACE, XML_NAMESPACE, alignCommentRunBoundaries, assertXmlRoot, cloneXmlElement, createDocxThemeResolver, createNamespacedElement, createWordElement, cssColorToHex, cssFontFamily, cssFontSize, dataBoolean, documentIndexEntryInstruction, documentIndexInstruction, documentProofingLanguageDocxOptions, docxCharacterPositionHalfPointsFromProperties, docxCharacterPositionValue, docxCharacterScalePercentFromProperties, docxCharacterScaleValue, docxCharacterSpacingTwipsFromProperties, docxCharacterSpacingValue, docxEmphasisMarkRunOptions, docxKerningThresholdValue, docxThemeColor, docxThemeFont, domDirection, ensureDocxExternalHyperlinkRelationships, ensureIgnorableContentControlNamespace, flushDocxHyperlinkRelationships, groupNoteCommentHyperlinks, groupNoteCommentParagraphs, hasContentControlRelationshipReference, hasNonWhitespaceXmlText, hasOnlyPassiveContentControlAttributes, hasUnsupportedContentControlSemanticChild, inspectDocxEmphasisMark, inspectDocxKerningThresholdHalfPoints, inspectDocxNoProof, inspectDocxProofingLanguages, isContentControlSemanticNamespace, isDocxWordElement, isKnownOoxmlNamespace, loadDocxHyperlinkRelationshipState, mergeDocxIgnorableExtensions, mergeDocxIgnorableExtensionsAtPairs, noteCommentContentParagraphs, noteCommentHyperlinkSpanKey, noteCommentHyperlinksOverlap, noteCommentParagraphContent, paragraphAlignment, paragraphBidirectional, paragraphDirectionOptions, paragraphIndent, paragraphPaginationOptions, paragraphSpacingOptions, paragraphTabStops, parseBoundedDocxInteger, parseDocumentIndexEntryInstruction, parseDocumentIndexInstruction, parseDocxColorSchemeMappingElement, parseDocxParagraphDefaultCollapsed, parseDocxTwipsMeasure, patchDocxBibliography, patchDocxExplicitZeroCharacterSpacing, patchDocxExplicitZeroKerningThresholds, patchDocxImageTransforms, patchDocxParagraphDefaultCollapsed, readDocxBibliography, readDocxImageTransform, resolveDocxEmphasisMark, resolveDocxKerningThresholdHalfPoints, resolveDocxOpenTypeFeatures, resolveDocxProofing, resolveDocxThemeResolver, restoreElementChildren, setDocxHyperlinkDestination, setNamespacedContentControlAttribute, setWordContentControlAttribute, work_docx_note_comment_content_control_xml_wordDirectChildren, xmlAttributeLocalName, xmlAttributeNamespace, xmlDeclaredPrefix, xmlNamespaceUri };