@courtifyai/docx-render 1.0.0 → 1.0.2

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.
@@ -0,0 +1,27 @@
1
+ (function(b,C){typeof exports=="object"&&typeof module<"u"?C(exports,require("jszip")):typeof define=="function"&&define.amd?define(["exports","jszip"],C):(b=typeof globalThis<"u"?globalThis:b||self,C(b.DocxRenderEnhanced={},b.JSZip))})(this,function(b,C){"use strict";var $e=Object.defineProperty;var Ae=(b,C,h)=>C in b?$e(b,C,{enumerable:!0,configurable:!0,writable:!0,value:h}):b[C]=h;var g=(b,C,h)=>Ae(b,typeof C!="symbol"?C+"":C,h);var h=(i=>(i.Document="document",i.Paragraph="paragraph",i.Run="run",i.Text="text",i.Break="break",i.Table="table",i.TableRow="tableRow",i.TableCell="tableCell",i.Hyperlink="hyperlink",i.Drawing="drawing",i.Image="image",i.BookmarkStart="bookmarkStart",i.BookmarkEnd="bookmarkEnd",i.Comment="comment",i.CommentRangeStart="commentRangeStart",i.CommentRangeEnd="commentRangeEnd",i.CommentReference="commentReference",i.Section="section",i.Header="header",i.Footer="footer",i.Tab="tab",i.Symbol="symbol",i.SimpleField="simpleField",i.ComplexField="complexField",i.FieldInstruction="fieldInstruction",i.Footnote="footnote",i.Endnote="endnote",i.FootnoteReference="footnoteReference",i.EndnoteReference="endnoteReference",i))(h||{});const B={W:"http://schemas.openxmlformats.org/wordprocessingml/2006/main",W14:"http://schemas.microsoft.com/office/word/2010/wordml",W15:"http://schemas.microsoft.com/office/word/2012/wordml",R:"http://schemas.openxmlformats.org/officeDocument/2006/relationships",A:"http://schemas.openxmlformats.org/drawingml/2006/main",WP:"http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing",PIC:"http://schemas.openxmlformats.org/drawingml/2006/picture"},k={DOCUMENT:"word/document.xml",COMMENTS:"word/comments.xml",COMMENTS_EXTENDED:"word/commentsExtended.xml",STYLES:"word/styles.xml",NUMBERING:"word/numbering.xml",THEME:"word/theme/theme1.xml",FOOTNOTES:"word/footnotes.xml",ENDNOTES:"word/endnotes.xml",FONT_TABLE:"word/fontTable.xml",FONT_TABLE_RELS:"word/_rels/fontTable.xml.rels",RELS:"word/_rels/document.xml.rels",CONTENT_TYPES:"[Content_Types].xml",HEADER_PREFIX:"word/header",FOOTER_PREFIX:"word/footer"},N={IMAGE:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/image",HEADER:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/header",FOOTER:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/footer",FONT:"http://schemas.openxmlformats.org/officeDocument/2006/relationships/font"};class J{elements(e,t){const n=[];for(let r=0;r<e.childNodes.length;r++){const o=e.childNodes[r];o.nodeType===Node.ELEMENT_NODE&&(!t||o.localName===t)&&n.push(o)}return n}element(e,t){for(let n=0;n<e.childNodes.length;n++){const r=e.childNodes[n];if(r.nodeType===Node.ELEMENT_NODE&&r.localName===t)return r}return null}attr(e,t){if(!e)return;for(const r of Object.values(B)){const o=e.getAttributeNS(r,t);if(o)return o}const n=e.getAttribute(`w:${t}`);return n||e.getAttribute(t)||void 0}boolAttr(e,t,n=!1){if(!e)return n;const r=this.attr(e,t);return r===void 0?n:r==="1"||r==="true"||r==="on"}intAttr(e,t){if(!e)return;const n=this.attr(e,t);if(n)return parseInt(n,10)}lengthAttr(e,t,n=P.Dxa){if(!e)return;const r=this.attr(e,t);return this.convertLength(r,n)}convertLength(e,t=P.Dxa){return e?/[a-z%]+$/i.test(e)?e:`${(parseFloat(e)*t.mul).toFixed(2)}${t.unit}`:void 0}textContent(e){return e&&e.textContent||""}}const P={Dxa:{mul:.05,unit:"pt"},Emu:{mul:1/12700,unit:"pt"},FontSize:{mul:.5,unit:"pt"},Border:{mul:.125,unit:"pt"}};function x(i){i.charCodeAt(0)===65279&&(i=i.substring(1)),i=i.replace(/<\?xml[^?]*\?>/g,"");const t=new DOMParser().parseFromString(i,"application/xml"),n=t.getElementsByTagName("parsererror")[0];if(n)throw new Error(`XML 解析错误: ${n.textContent}`);return t}const s=new J;function L(i){const e={colorScheme:{name:"",colors:{}},fontScheme:{name:"",majorFont:{},minorFont:{}}},t=A(i,"themeElements");if(!t)return e;for(const n of $(t)){const r=n.localName;r==="clrScheme"?e.colorScheme=Q(n):r==="fontScheme"&&(e.fontScheme=te(n))}return e}function Q(i){const e={name:i.getAttribute("name")||"",colors:{}};for(const t of $(i)){const n=t.localName,r=ee(t);r&&(e.colors[n]=r)}return e}function ee(i){const e=A(i,"srgbClr");if(e){const n=e.getAttribute("val");return n?`#${n}`:null}const t=A(i,"sysClr");if(t){const n=t.getAttribute("lastClr");return n?`#${n}`:null}return null}function te(i){const e={name:i.getAttribute("name")||"",majorFont:{},minorFont:{}};for(const t of $(i)){const n=t.localName;n==="majorFont"?e.majorFont=D(t):n==="minorFont"&&(e.minorFont=D(t))}return e}function D(i){const e={};for(const t of $(i)){const n=t.localName,r=t.getAttribute("typeface");r&&(n==="latin"?e.latin=r:n==="ea"?e.ea=r:n==="cs"&&(e.cs=r))}return e}function A(i,e){for(let t=0;t<i.childNodes.length;t++){const n=i.childNodes[t];if(n.nodeType===Node.ELEMENT_NODE){const r=n;if(r.localName===e)return r}}return null}function $(i){const e=[];for(let t=0;t<i.childNodes.length;t++){const n=i.childNodes[t];n.nodeType===Node.ELEMENT_NODE&&e.push(n)}return e}const ne={dark1:"dk1",dark2:"dk2",light1:"lt1",light2:"lt2",accent1:"accent1",accent2:"accent2",accent3:"accent3",accent4:"accent4",accent5:"accent5",accent6:"accent6",hyperlink:"hlink",followedHyperlink:"folHlink",dk1:"dk1",dk2:"dk2",lt1:"lt1",lt2:"lt2",hlink:"hlink",folHlink:"folHlink",text1:"dk1",text2:"dk2",background1:"lt1",background2:"lt2"};function H(i,e){var o;if(!((o=i==null?void 0:i.colorScheme)!=null&&o.colors))return;const t=e.themeColor,n=ne[t]||t,r=i.colorScheme.colors[n];if(r)return e.themeTint!==void 0||e.themeShade!==void 0?z(r,e.themeTint,e.themeShade):r}function z(i,e,t){const n=i.replace("#",""),r=parseInt(n.substr(0,2),16),o=parseInt(n.substr(2,2),16),a=parseInt(n.substr(4,2),16);let c=r,l=o,m=a;if(e!==void 0&&e>0){const d=e/255;c=Math.round(r+(255-r)*d),l=Math.round(o+(255-o)*d),m=Math.round(a+(255-a)*d)}if(t!==void 0&&t>0){const d=1-t/255;c=Math.round(c*d),l=Math.round(l*d),m=Math.round(m*d)}return c=Math.max(0,Math.min(255,c)),l=Math.max(0,Math.min(255,l)),m=Math.max(0,Math.min(255,m)),`#${M(c)}${M(l)}${M(m)}`}function M(i){const e=i.toString(16);return e.length===1?"0"+e:e}function re(i,e,t="latin"){return i!=null&&i.fontScheme?(e==="major"?i.fontScheme.majorFont:i.fontScheme.minorFont)[t]:void 0}const se={embedRegular:"regular",embedBold:"bold",embedItalic:"italic",embedBoldItalic:"boldItalic"};function O(i){const t=x(i).documentElement,n=oe(t),r=new Map(n.map(a=>[a.name,a])),o=le(n);return{fonts:n,fontMap:r,substitutionMap:o}}function oe(i){return s.elements(i,"font").map(e=>ie(e))}function ie(i){const e={name:s.attr(i,"name")||"",embedFontRefs:[]};for(const t of s.elements(i))switch(t.localName){case"family":e.family=s.attr(t,"val");break;case"altName":e.altName=s.attr(t,"val");break;case"charset":e.charset=s.attr(t,"val");break;case"panose1":e.panose1=s.attr(t,"val");break;case"sig":e.sig=ae(t);break;case"embedRegular":case"embedBold":case"embedItalic":case"embedBoldItalic":const n=ce(t);n&&e.embedFontRefs.push(n);break}return e}function ae(i){return{usb0:s.attr(i,"usb0"),usb1:s.attr(i,"usb1"),usb2:s.attr(i,"usb2"),usb3:s.attr(i,"usb3"),csb0:s.attr(i,"csb0"),csb1:s.attr(i,"csb1")}}function ce(i){const e=s.attr(i,"id");if(!e)return null;const t=se[i.localName];return t?{id:e,key:s.attr(i,"fontKey"),subsetted:s.boolAttr(i,"subsetted"),type:t}:null}function le(i){const e=new Map;for(const t of i)t.altName&&e.set(t.name,t.altName);return e}function de(i,e){return i.substitutionMap.get(e)||e}function he(i,e){return i.fontMap.get(e)}function me(i,e){const t=i.fontMap.get(e);return t?t.embedFontRefs.length>0:!1}function ue(i,e,t){const n=i.fontMap.get(e);return n?t?n.embedFontRefs.filter(r=>r.type===t):n.embedFontRefs:[]}function fe(i,e){const t=[],n=i.fontMap.get(e);if(t.push(G(e)),n!=null&&n.altName&&t.push(G(n.altName)),n!=null&&n.family){const r=pe(n.family);r&&t.push(r)}return t.join(", ")}function G(i){return/[\s,'"()]/.test(i)?`"${i.replace(/"/g,'\\"')}"`:i}function pe(i){switch(i.toLowerCase()){case"roman":return"serif";case"swiss":return"sans-serif";case"modern":return"monospace";case"script":return"cursive";case"decorative":return"fantasy";default:return null}}const j={injectStyles:!0,timeout:1e4};async function U(i,e,t,n={}){const r={...j,...n},o=[];for(const a of e.fonts)if(a.embedFontRefs.length!==0)for(const c of a.embedFontRefs)try{const l=await ge(i,a,c,t,r.timeout||j.timeout);l&&o.push(l)}catch(l){console.warn(`加载嵌入字体失败: ${a.name} (${c.type})`,l)}return r.injectStyles&&o.length>0&&we(o,r.styleContainer),o}async function ge(i,e,t,n,r){const o=n.find(y=>y.id===t.id);if(!o)return console.warn(`找不到嵌入字体关系: ${t.id}`),null;const a=`word/${o.target}`,c=i.file(a);if(!c)return console.warn(`找不到嵌入字体文件: ${a}`),null;const l=await Promise.race([c.async("arraybuffer"),new Promise((y,E)=>setTimeout(()=>E(new Error("字体加载超时")),r))]);let m=l;t.key&&(m=be(l,t.key));const d=ye(new Uint8Array(m)),p=Ee(d),u=new Blob([m],{type:p}),f=await Ce(u);return{fontName:e.name,type:t.type,dataUrl:f,format:d}}function be(i,e){const t=e.replace(/[{}-]/g,"");if(t.length!==32)return console.warn("无效的字体密钥格式:",e),i;const n=new Uint8Array(16);for(let c=0;c<4;c++)n[3-c]=parseInt(t.substr(c*2,2),16);for(let c=0;c<2;c++)n[5-c]=parseInt(t.substr(8+c*2,2),16);for(let c=0;c<2;c++)n[7-c]=parseInt(t.substr(12+c*2,2),16);for(let c=0;c<8;c++)n[8+c]=parseInt(t.substr(16+c*2,2),16);const r=new Uint8Array(i),o=new Uint8Array(r.length),a=Math.min(32,r.length);for(let c=0;c<a;c++)o[c]=r[c]^n[c%16];for(let c=a;c<r.length;c++)o[c]=r[c];return o.buffer}function ye(i){return i.length<4?"truetype":i[0]===79&&i[1]===84&&i[2]===84&&i[3]===79?"opentype":i[0]===0&&i[1]===1&&i[2]===0&&i[3]===0||i[0]===116&&i[1]===114&&i[2]===117&&i[3]===101?"truetype":i[0]===0&&i[1]===0&&i[2]===1?"embedded-opentype":"truetype"}function Ee(i){switch(i){case"opentype":return"font/otf";case"truetype":return"font/ttf";case"embedded-opentype":return"application/vnd.ms-fontobject";default:return"font/ttf"}}function Ce(i){return new Promise((e,t)=>{const n=new FileReader;n.onloadend=()=>e(n.result),n.onerror=t,n.readAsDataURL(i)})}function we(i,e){const t=document.createElement("style");t.setAttribute("data-docx-fonts","true");const n=i.map(a=>ke(a)).join(`
2
+ `);t.textContent=n;const r=e||document.head,o=r.querySelector("style[data-docx-fonts]");o&&o.remove(),r.appendChild(t)}function ke(i){const e=xe(i.type),t=Se(i.type),n=Te(i.format);return`@font-face {
3
+ font-family: "${ve(i.fontName)}";
4
+ src: url("${i.dataUrl}") format("${n}");
5
+ font-weight: ${e};
6
+ font-style: ${t};
7
+ font-display: swap;
8
+ }`}function xe(i){switch(i){case"bold":case"boldItalic":return"700";default:return"400"}}function Se(i){switch(i){case"italic":case"boldItalic":return"italic";default:return"normal"}}function Te(i){switch(i){case"opentype":return"opentype";case"truetype":return"truetype";case"embedded-opentype":return"embedded-opentype";default:return"truetype"}}function ve(i){return i.replace(/"/g,'\\"')}function Pe(i){const t=(i||document.head).querySelector("style[data-docx-fonts]");t&&t.remove()}function Fe(i){const n=new DOMParser().parseFromString(i,"application/xml").documentElement,r=[],o=n.getElementsByTagName("Relationship");for(let a=0;a<o.length;a++){const c=o[a],l=c.getAttribute("Type")||"";l===N.FONT&&r.push({id:c.getAttribute("Id")||"",type:l,target:c.getAttribute("Target")||"",targetMode:c.getAttribute("TargetMode")||void 0})}return r}const _="http://schemas.microsoft.com/office/word/2012/wordml";function V(i){const e=new Map;if(!i)return e;try{const n=x(i).documentElement,r=n.getElementsByTagNameNS(_,"commentEx"),o=r.length>0?Array.from(r):Array.from(n.getElementsByTagName("commentEx"));for(const a of o){const c=I(a,"paraId");if(!c)continue;const l={paraId:c,paraIdParent:I(a,"paraIdParent"),done:Re(a,"done")};e.set(c,l)}console.log("[DEBUG] parseCommentsExtended: found",e.size,"extended comments")}catch(t){console.warn("解析 commentsExtended.xml 失败:",t)}return e}function W(i,e){const t=new Map;for(const r of i)r.paraId&&t.set(r.paraId,r);for(const r of i)r.replies=[];for(const[r,o]of e){const a=t.get(r);if(a&&(a.done=o.done,o.paraIdParent)){const c=t.get(o.paraIdParent);c&&(a.parentId=c.id,c.replies.push(a))}}const n=i.filter(r=>!r.parentId);return n.sort((r,o)=>{const a=new Date(r.date).getTime(),c=new Date(o.date).getTime();return a-c}),X(n),console.log("[DEBUG] buildCommentTree: root comments:",n.length,"total comments:",i.length),n}function X(i){for(const e of i)e.replies&&e.replies.length>0&&(e.replies.sort((t,n)=>{const r=new Date(t.date).getTime(),o=new Date(n.date).getTime();return r-o}),X(e.replies))}function I(i,e){let t=i.getAttributeNS(_,e);return t||(t=i.getAttribute(e),t)?t:(t=i.getAttribute(`w15:${e}`),t||void 0)}function Re(i,e){const t=I(i,e);return t?t==="1"||t==="true":!1}class q{constructor(){g(this,"zip",null);g(this,"relationships",[]);g(this,"images",new Map);g(this,"theme");g(this,"fontTable");g(this,"embeddedFonts",[]);g(this,"bookmarks",new Map)}async parse(e){const t=e instanceof ArrayBuffer?e:await e.arrayBuffer();this.zip=await C.loadAsync(t),this.bookmarks=new Map,await this.parseRelationships(),await this.loadImages();const n=await this.parseStyles(),r=new Map(n.map(S=>[S.id,S])),o=await this.parseComments(),a=new Map(o.map(S=>[S.id,S])),c=await this.parseCommentsExtended(),l=W(o,c),{numberings:m,abstractNumberings:d,numberingMap:p}=await this.parseNumberings();this.theme=await this.parseTheme();const u=await this.parseHeadersFooters("header"),f=await this.parseHeadersFooters("footer"),y=await this.parseFootnotes(),E=await this.parseEndnotes();return this.fontTable=await this.parseFontTable(),this.embeddedFonts=await this.loadEmbeddedFonts(),{body:await this.parseDocument(),comments:o,commentMap:a,rootComments:l,commentsExtendedMap:c,styles:n,styleMap:r,numberings:m,numberingMap:p,abstractNumberings:d,images:this.images,relationships:this.relationships,headers:u,footers:f,theme:this.theme,footnotes:y,endnotes:E,fontTable:this.fontTable,embeddedFonts:this.embeddedFonts,bookmarks:this.bookmarks}}getZip(){return this.zip}async parseRelationships(){var r,o;const e=await((o=(r=this.zip)==null?void 0:r.file(k.RELS))==null?void 0:o.async("string"));if(!e)return;const n=x(e).documentElement;this.relationships=s.elements(n,"Relationship").map(a=>({id:s.attr(a,"Id")||"",type:s.attr(a,"Type")||"",target:s.attr(a,"Target")||"",targetMode:s.attr(a,"TargetMode")}))}async loadImages(){var e;for(const t of this.relationships)if(t.type===N.IMAGE){const n=`word/${t.target}`,r=(e=this.zip)==null?void 0:e.file(n);if(r){const o=await r.async("blob"),a=await this.blobToBase64(o);this.images.set(t.id,a)}}}blobToBase64(e){return new Promise((t,n)=>{const r=new FileReader;r.onloadend=()=>t(r.result),r.onerror=n,r.readAsDataURL(e)})}async parseStyles(){var o,a;const e=await((a=(o=this.zip)==null?void 0:o.file(k.STYLES))==null?void 0:a.async("string"));if(!e)return[];const t=x(e),n=[],r=t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main","style");for(let c=0;c<r.length;c++){const l=r[c],m=s.element(l,"name"),d=s.element(l,"basedOn"),p={id:s.attr(l,"styleId")||"",name:m?s.attr(m,"val"):void 0,type:s.attr(l,"type")||"paragraph",basedOn:d?s.attr(d,"val"):void 0},u=s.element(l,"pPr");u&&(p.paragraphProps=this.parseParagraphProperties(u));const f=s.element(l,"rPr");f&&(p.runProps=this.parseRunProperties(f)),n.push(p)}return n}async parseTheme(){var t,n;const e=await((n=(t=this.zip)==null?void 0:t.file(k.THEME))==null?void 0:n.async("string"));if(e)try{const r=x(e);return L(r.documentElement)}catch(r){console.warn("主题解析失败:",r);return}}async parseFontTable(){var t,n;const e=await((n=(t=this.zip)==null?void 0:t.file(k.FONT_TABLE))==null?void 0:n.async("string"));if(e)try{return O(e)}catch(r){console.warn("字体表解析失败:",r);return}}async loadEmbeddedFonts(){var t;if(!this.fontTable||!this.zip)return[];if(!this.fontTable.fonts.some(n=>n.embedFontRefs.length>0))return[];try{const n=await((t=this.zip.file(k.FONT_TABLE_RELS))==null?void 0:t.async("string"));if(!n)return console.warn("找不到字体表关系文件"),[];const r=Fe(n);return await U(this.zip,this.fontTable,r,{injectStyles:!0})}catch(n){return console.warn("嵌入字体加载失败:",n),[]}}async parseFootnotes(){var t,n;const e=await((n=(t=this.zip)==null?void 0:t.file(k.FOOTNOTES))==null?void 0:n.async("string"));if(!e)return new Map;try{const r=x(e);return this.parseNotes(r.documentElement,"footnote",h.Footnote)}catch(r){return console.warn("脚注解析失败:",r),new Map}}async parseEndnotes(){var t,n;const e=await((n=(t=this.zip)==null?void 0:t.file(k.ENDNOTES))==null?void 0:n.async("string"));if(!e)return new Map;try{const r=x(e);return this.parseNotes(r.documentElement,"endnote",h.Endnote)}catch(r){return console.warn("尾注解析失败:",r),new Map}}parseNotes(e,t,n){const r=new Map,o=e.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main",t);for(let a=0;a<o.length;a++){const c=o[a],l=s.attr(c,"id")||"",m=s.attr(c,"type");if(m==="separator"||m==="continuationSeparator")continue;const d={type:n,id:l,noteType:m,children:this.parseChildren(c)};r.set(l,d)}return r}async parseNumberings(){var l,m;const e=await((m=(l=this.zip)==null?void 0:l.file(k.NUMBERING))==null?void 0:m.async("string"));if(!e)return{numberings:[],abstractNumberings:[],numberingMap:new Map};const n=x(e).documentElement,r=[],o=new Map;for(const d of s.elements(n))switch(d.localName){case"abstractNum":r.push(this.parseAbstractNumbering(d));break;case"num":const p=s.attr(d,"numId")||"",u=s.element(d,"abstractNumId");if(u){const f=s.attr(u,"val")||"";o.set(p,f)}break}const a=[],c=new Map;for(const[d,p]of o){const u=r.find(f=>f.id===p);if(u){const f={id:d,abstractNumId:p,levels:u.levels.map(y=>({...y}))};a.push(f),c.set(d,f)}}return{numberings:a,abstractNumberings:r,numberingMap:c}}parseAbstractNumbering(e){const t={id:s.attr(e,"abstractNumId")||"",levels:[]};for(const n of s.elements(e))switch(n.localName){case"name":t.name=s.attr(n,"val");break;case"multiLevelType":t.multiLevelType=s.attr(n,"val");break;case"numStyleLink":t.numberingStyleLink=s.attr(n,"val");break;case"styleLink":t.styleLink=s.attr(n,"val");break;case"lvl":t.levels.push(this.parseNumberingLevel(n));break}return t}parseNumberingLevel(e){const t={level:s.intAttr(e,"ilvl")??0,format:"decimal",text:"",start:1,suffix:"tab"};for(const n of s.elements(e))switch(n.localName){case"start":t.start=s.intAttr(n,"val")??1;break;case"numFmt":t.format=s.attr(n,"val")||"decimal";break;case"lvlText":t.text=s.attr(n,"val")||"";break;case"suff":t.suffix=s.attr(n,"val")||"tab";break;case"pStyle":t.pStyleName=s.attr(n,"val");break;case"pPr":t.paragraphProps=this.parseParagraphProperties(n);break;case"rPr":t.runProps=this.parseRunProperties(n);break}return t}async parseComments(){var a,c,l;const e=await((c=(a=this.zip)==null?void 0:a.file(k.COMMENTS))==null?void 0:c.async("string"));if(!e)return[];const t=x(e),n=[],r=t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main","comment"),o="http://schemas.microsoft.com/office/word/2010/wordml";for(let m=0;m<r.length;m++){const d=r[m],p=((l=d.textContent)==null?void 0:l.trim())||"";let u=d.getAttributeNS(o,"paraId");u||(u=d.getAttribute("w14:paraId")||null);const f={type:h.Comment,id:s.attr(d,"id")||"",author:s.attr(d,"author")||"未知",date:s.attr(d,"date")||new Date().toISOString(),initials:s.attr(d,"initials"),children:this.parseChildren(d),rawText:p,paraId:u||void 0};n.push(f)}return console.log("[DEBUG] parseComments: found",n.length,"comments"),n}async parseCommentsExtended(){var t,n;const e=await((n=(t=this.zip)==null?void 0:t.file(k.COMMENTS_EXTENDED))==null?void 0:n.async("string"));return e?(console.log("[DEBUG] commentsExtended.xml found, length:",e.length),V(e)):(console.log("[DEBUG] commentsExtended.xml not found"),new Map)}async parseDocument(){var m,d;const e=await((d=(m=this.zip)==null?void 0:m.file(k.DOCUMENT))==null?void 0:d.async("string"));if(!e)return{type:h.Document,children:[]};const t=x(e),n=t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main","body")[0];if(!n)return{type:h.Document,children:[]};const r=s.element(n,"sectPr"),o=r?this.parseSectionProperties(r):void 0,a=t.getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main","document")[0],c=a?s.element(a,"background"):null,l=c?this.parseBackground(c):void 0;return{type:h.Document,children:this.parseChildren(n),sectionProps:o,background:l}}async parseHeadersFooters(e){var r,o;const t=new Map,n=e==="header"?N.HEADER:N.FOOTER;for(const a of this.relationships)if(a.type===n){const c=`word/${a.target}`,l=await((o=(r=this.zip)==null?void 0:r.file(c))==null?void 0:o.async("string"));if(l){const d=x(l).getElementsByTagNameNS("http://schemas.openxmlformats.org/wordprocessingml/2006/main",e==="header"?"hdr":"ftr")[0];if(d){const p={type:e==="header"?h.Header:h.Footer,children:this.parseChildren(d)};t.set(a.id,p)}}}return t}parseBackground(e){const t={},n=s.attr(e,"color");return n&&n!=="auto"&&(t["background-color"]=`#${n}`),t}parseSectionProperties(e){const t={};for(const n of s.elements(e))switch(n.localName){case"pgSz":t.pageSize=this.parsePageSize(n);break;case"pgMar":t.pageMargins=this.parsePageMargins(n);break;case"type":t.type=s.attr(n,"val")||"nextPage";break;case"cols":t.columns=this.parseColumns(n);break;case"pgBorders":t.pageBorders=this.parseBorders(n);break;case"pgNumType":t.pageNumber={start:s.intAttr(n,"start"),format:s.attr(n,"fmt"),chapSep:s.attr(n,"chapSep"),chapStyle:s.attr(n,"chapStyle")};break;case"headerReference":t.headerRefs||(t.headerRefs=[]),t.headerRefs.push({id:s.attr(n,"id")||"",type:s.attr(n,"type")||"default"});break;case"footerReference":t.footerRefs||(t.footerRefs=[]),t.footerRefs.push({id:s.attr(n,"id")||"",type:s.attr(n,"type")||"default"});break;case"titlePg":t.titlePage=s.boolAttr(n,"val")!==!1;break}return t}parsePageSize(e){return{width:s.lengthAttr(e,"w"),height:s.lengthAttr(e,"h"),orientation:s.attr(e,"orient")}}parsePageMargins(e){return{top:s.lengthAttr(e,"top"),right:s.lengthAttr(e,"right"),bottom:s.lengthAttr(e,"bottom"),left:s.lengthAttr(e,"left"),header:s.lengthAttr(e,"header"),footer:s.lengthAttr(e,"footer"),gutter:s.lengthAttr(e,"gutter")}}parseColumns(e){const t={numberOfColumns:s.intAttr(e,"num"),space:s.lengthAttr(e,"space"),separator:s.boolAttr(e,"sep"),equalWidth:s.boolAttr(e,"equalWidth")!==!1,columns:[]};for(const n of s.elements(e,"col"))t.columns.push({width:s.lengthAttr(n,"w"),space:s.lengthAttr(n,"space")});return t}parseBorders(e){const t={};for(const n of s.elements(e)){const r=this.parseBorder(n);switch(n.localName){case"top":t.top=r;break;case"bottom":t.bottom=r;break;case"left":case"start":t.left=r;break;case"right":case"end":t.right=r;break}}return t}parseBorder(e){const t=s.attr(e,"color");return{style:s.attr(e,"val"),width:s.lengthAttr(e,"sz",P.Border),color:t&&t!=="auto"?`#${t}`:void 0}}parseChildren(e,t=!1){const n=[];for(const r of s.elements(e)){const o=this.parseElement(r);o&&n.push(o)}return t&&n.length===0&&console.log("[DEBUG] parseChildren: no children parsed from",e.localName,"childNodes:",e.childNodes.length,"elements:",s.elements(e).map(r=>r.localName)),n}parseElement(e){var n;const t=e.localName;switch(t){case"p":return this.parseParagraph(e);case"r":return this.parseRun(e);case"t":return this.parseText(e);case"br":return this.parseBreak(e);case"tab":return this.parseTab();case"sym":return this.parseSymbol(e);case"lastRenderedPageBreak":return{type:h.Break,breakType:"lastRenderedPageBreak"};case"fldSimple":return this.parseSimpleField(e);case"fldChar":return this.parseComplexField(e);case"instrText":return this.parseFieldInstruction(e);case"tbl":return this.parseTable(e);case"tr":return this.parseTableRow(e);case"tc":return this.parseTableCell(e);case"hyperlink":return this.parseHyperlink(e);case"drawing":return this.parseDrawing(e);case"commentRangeStart":return this.parseCommentRangeStart(e);case"commentRangeEnd":return this.parseCommentRangeEnd(e);case"commentReference":return this.parseCommentReference(e);case"footnoteReference":return this.parseFootnoteReference(e);case"endnoteReference":return this.parseEndnoteReference(e);case"bookmarkStart":return this.parseBookmarkStart(e);case"bookmarkEnd":return this.parseBookmarkEnd(e);default:console.log("[DEBUG] parseElement default branch for:",t);const r=this.parseChildren(e);if(r.length>0)return console.log("[DEBUG] -> found children:",r.length),r.length===1?r[0]:{type:h.Run,children:r};const o=(n=e.textContent)==null?void 0:n.trim();return o?(console.log("[DEBUG] -> using textContent:",o.substring(0,50)),{type:h.Text,text:o}):null}}parseParagraph(e){const t=s.element(e,"pPr");return{type:h.Paragraph,props:t?this.parseParagraphProperties(t):void 0,children:this.parseChildren(e).filter(n=>n.type!==h.Paragraph)}}parseParagraphProperties(e){const t={},n=s.element(e,"pStyle");n&&(t.styleId=s.attr(n,"val"));const r=s.element(e,"jc");if(r){const p=s.attr(r,"val");(p==="left"||p==="center"||p==="right"||p==="both")&&(t.justification=p)}const o=s.element(e,"ind");o&&(t.indentation={left:s.lengthAttr(o,"left"),right:s.lengthAttr(o,"right"),firstLine:s.lengthAttr(o,"firstLine"),hanging:s.lengthAttr(o,"hanging")});const a=s.element(e,"spacing");a&&(t.spacing={before:s.lengthAttr(a,"before"),after:s.lengthAttr(a,"after"),line:s.intAttr(a,"line"),lineRule:s.attr(a,"lineRule")});const c=s.element(e,"pageBreakBefore");c&&(t.pageBreakBefore=s.boolAttr(c,"val")!==!1);const l=s.element(e,"pBdr");l&&(t.borders=this.parseBorders(l));const m=s.element(e,"sectPr");m&&(t.sectionProps=this.parseSectionProperties(m));const d=s.element(e,"numPr");return d&&(t.numbering=this.parseParagraphNumbering(d)),t}parseParagraphNumbering(e){const t={id:"",level:0};for(const n of s.elements(e))switch(n.localName){case"numId":t.id=s.attr(n,"val")||"";break;case"ilvl":t.level=s.intAttr(n,"val")??0;break}if(t.id)return t}parseRun(e){const t=s.element(e,"rPr");return{type:h.Run,props:t?this.parseRunProperties(t):void 0,children:this.parseChildren(e)}}parseRunProperties(e){var y,E,F,S;const t={},n=s.element(e,"rStyle");n&&(t.styleId=s.attr(n,"val"));const r=s.element(e,"b");r&&(t.bold=s.attr(r,"val")!=="0");const o=s.element(e,"i");o&&(t.italic=s.attr(o,"val")!=="0");const a=s.element(e,"u");a&&(t.underline=s.attr(a,"val")||"single");const c=s.element(e,"strike");c&&(t.strike=s.attr(c,"val")!=="0");const l=s.element(e,"dstrike");l&&(t.dstrike=s.attr(l,"val")!=="0");const m=s.element(e,"vertAlign");if(m){const w=s.attr(m,"val");(w==="superscript"||w==="subscript")&&(t.vertAlign=w)}const d=s.element(e,"color");if(d){const w=s.attr(d,"val"),R=s.attr(d,"themeColor");if(R){const v=s.attr(d,"themeTint"),T=s.attr(d,"themeShade");if(t.themeColor={themeColor:R,themeTint:v?parseInt(v,16):void 0,themeShade:T?parseInt(T,16):void 0},this.theme){const Z=H(this.theme,t.themeColor);Z&&(t.color=Z)}}else w&&w!=="auto"&&(t.color=`#${w}`)}const p=s.element(e,"sz");p&&(t.fontSize=s.lengthAttr(p,"val",P.FontSize));const u=s.element(e,"rFonts");if(u){const w=s.attr(u,"asciiTheme"),R=s.attr(u,"eastAsiaTheme");if(w||R){const v=w||R||"";if(v.startsWith("major")){if(t.themeFontFamily="major",(E=(y=this.theme)==null?void 0:y.fontScheme)!=null&&E.majorFont){const T=v.includes("EastAsia")?this.theme.fontScheme.majorFont.ea:this.theme.fontScheme.majorFont.latin;T&&(t.fontFamily=T)}}else if(v.startsWith("minor")&&(t.themeFontFamily="minor",(S=(F=this.theme)==null?void 0:F.fontScheme)!=null&&S.minorFont)){const T=v.includes("EastAsia")?this.theme.fontScheme.minorFont.ea:this.theme.fontScheme.minorFont.latin;T&&(t.fontFamily=T)}}t.fontFamily||(t.fontFamily=s.attr(u,"ascii")||s.attr(u,"eastAsia")||s.attr(u,"hAnsi"))}const f=s.element(e,"highlight");return f&&(t.highlight=s.attr(f,"val")),t}parseText(e){return{type:h.Text,text:e.textContent||""}}parseBreak(e){const t=s.attr(e,"type");return{type:h.Break,breakType:t||"textWrapping"}}parseTab(){return{type:h.Tab}}parseSymbol(e){const t=s.attr(e,"font"),n=s.attr(e,"char");let r;if(n){const o=parseInt(n,16);isNaN(o)||(r=String.fromCharCode(o))}return{type:h.Symbol,font:t,char:r}}parseSimpleField(e){return{type:h.SimpleField,instruction:s.attr(e,"instr")||"",children:this.parseChildren(e)}}parseComplexField(e){return{type:h.ComplexField,charType:s.attr(e,"fldCharType")||""}}parseFieldInstruction(e){return{type:h.FieldInstruction,text:e.textContent||""}}parseTable(e){const t={type:h.Table,children:[]};for(const n of s.elements(e))switch(n.localName){case"tr":t.children.push(this.parseTableRow(n));break;case"tblGrid":t.columns=this.parseTableGrid(n);break;case"tblPr":t.props=this.parseTableProperties(n);break}return t}parseTableGrid(e){const t=[];for(const n of s.elements(e))n.localName==="gridCol"&&t.push({width:s.lengthAttr(n,"w")});return t}parseTableProperties(e){const t={};for(const n of s.elements(e))switch(n.localName){case"tblW":t.width=s.lengthAttr(n,"w");const r=s.attr(n,"type");(r==="auto"||r==="dxa"||r==="pct")&&(t.widthType=r);break;case"jc":t.justification=s.attr(n,"val");break;case"tblBorders":t.borders=this.parseTableBorders(n);break;case"tblCellSpacing":t.cellSpacing=s.lengthAttr(n,"w");break;case"tblCellMar":t.cellMargin={top:s.lengthAttr(s.element(n,"top"),"w"),bottom:s.lengthAttr(s.element(n,"bottom"),"w"),left:s.lengthAttr(s.element(n,"left"),"w")||s.lengthAttr(s.element(n,"start"),"w"),right:s.lengthAttr(s.element(n,"right"),"w")||s.lengthAttr(s.element(n,"end"),"w")};break}return t}parseTableBorders(e){const t={};for(const n of s.elements(e)){const r=this.parseBorder(n);switch(n.localName){case"top":t.top=r;break;case"bottom":t.bottom=r;break;case"left":case"start":t.left=r;break;case"right":case"end":t.right=r;break;case"insideH":t.insideH=r;break;case"insideV":t.insideV=r;break}}return t}parseTableRow(e){return{type:h.TableRow,children:s.elements(e).filter(t=>t.localName==="tc").map(t=>this.parseTableCell(t))}}parseTableCell(e){const t={type:h.TableCell,children:[]};for(const n of s.elements(e))if(n.localName==="tcPr")t.props=this.parseTableCellProperties(n);else{const r=this.parseElement(n);r&&t.children.push(r)}return t}parseTableCellProperties(e){const t={};for(const n of s.elements(e))switch(n.localName){case"tcW":t.width=s.lengthAttr(n,"w");break;case"gridSpan":t.gridSpan=s.intAttr(n,"val");break;case"vMerge":const r=s.attr(n,"val");t.verticalMerge=r==="restart"?"restart":"continue";break;case"vAlign":t.verticalAlign=s.attr(n,"val");break;case"shd":const o=s.attr(n,"fill");o&&o!=="auto"&&(t.shading=`#${o}`);break;case"tcBorders":t.borders=this.parseBorders(n);break}return t}parseHyperlink(e){const t=s.attr(e,"id");let n;if(t){const r=this.relationships.find(o=>o.id===t);r&&(n=r.target)}return{type:h.Hyperlink,href:n,anchor:s.attr(e,"anchor"),children:this.parseChildren(e)}}parseDrawing(e){const t=[],n=e.getElementsByTagNameNS("http://schemas.openxmlformats.org/drawingml/2006/main","blip");for(let r=0;r<n.length;r++){const a=n[r].getAttributeNS("http://schemas.openxmlformats.org/officeDocument/2006/relationships","embed");if(a&&this.images.has(a)){const c=e.getElementsByTagNameNS("http://schemas.openxmlformats.org/drawingml/2006/wordprocessingDrawing","extent")[0];let l,m;if(c){const d=c.getAttribute("cx"),p=c.getAttribute("cy");d&&(l=s.convertLength(d,P.Emu)),p&&(m=s.convertLength(p,P.Emu))}t.push({type:h.Image,src:this.images.get(a),width:l,height:m})}}return{type:h.Drawing,children:t}}parseCommentRangeStart(e){return{type:h.CommentRangeStart,id:s.attr(e,"id")||""}}parseCommentRangeEnd(e){return{type:h.CommentRangeEnd,id:s.attr(e,"id")||""}}parseCommentReference(e){return{type:h.CommentReference,id:s.attr(e,"id")||""}}parseFootnoteReference(e){return{type:h.FootnoteReference,id:s.attr(e,"id")||""}}parseEndnoteReference(e){return{type:h.EndnoteReference,id:s.attr(e,"id")||""}}parseBookmarkStart(e){const t={type:h.BookmarkStart,id:s.attr(e,"id")||"",name:s.attr(e,"name")||"",colFirst:s.intAttr(e,"colFirst"),colLast:s.intAttr(e,"colLast")};return t.name&&!t.name.startsWith("_")&&this.bookmarks.set(t.name,t),t}parseBookmarkEnd(e){return{type:h.BookmarkEnd,id:s.attr(e,"id")||""}}}class Y{constructor(e){g(this,"document",null);g(this,"container");g(this,"options");g(this,"classPrefix");g(this,"commentRanges",new Map);g(this,"activeCommentId",null);g(this,"svgLayer",null);g(this,"currentCommentIds",new Set);g(this,"commentStartInParagraph",new Set);g(this,"currentPageNumber",1);g(this,"totalPages",1);g(this,"inComplexField",!1);g(this,"currentFieldInstruction","");g(this,"skipFieldContent",!1);g(this,"numberingCounters",new Map);g(this,"currentFootnoteIds",[]);g(this,"currentEndnoteIds",[]);g(this,"footnoteCounter",0);g(this,"endnoteCounter",0);g(this,"tableVerticalMerges",[]);g(this,"currentVerticalMerge",new Map);g(this,"currentCellCol",0);g(this,"currentTableBorders");g(this,"tableBordersStack",[]);g(this,"currentTableRowIndex",0);g(this,"currentTableRowCount",0);g(this,"currentTableColCount",0);const t=typeof e.container=="string"?document.querySelector(e.container):e.container;if(!t)throw new Error("容器元素不存在");this.container=t,this.classPrefix=e.classNamePrefix||"docx",this.options={container:this.container,renderComments:e.renderComments??!0,enableCommentEdit:e.enableCommentEdit??!0,showCommentLines:e.showCommentLines??!0,breakPages:e.breakPages??!0,classNamePrefix:this.classPrefix,onCommentClick:e.onCommentClick||(()=>{}),onCommentChange:e.onCommentChange||(()=>{})}}render(e){this.document=e,this.commentRanges.clear(),this.currentCommentIds.clear(),this.numberingCounters.clear(),this.currentFootnoteIds=[],this.currentEndnoteIds=[],this.footnoteCounter=0,this.endnoteCounter=0;for(const o of e.comments)this.commentRanges.set(o.id,{id:o.id,startElement:null,endElement:null,highlightElements:[],panelElement:null});this.container.innerHTML="",this.container.className=`${this.classPrefix}-container`;const t=this.createElement("div",`${this.classPrefix}-wrapper`);this.options.breakPages?this.renderWithPages(t,e):this.renderSinglePage(t,e),this.container.appendChild(t),this.options.showCommentLines&&(this.svgLayer=this.createSvgLayer(),this.container.appendChild(this.svgLayer)),this.options.renderComments&&this.renderAllCommentBubbles();let n=!1;const r=()=>{n||(requestAnimationFrame(()=>{this.positionCommentBubbles(),this.updateLines(),n=!1}),n=!0)};t.addEventListener("scroll",()=>{this.positionCommentBubbles(),this.updateLines()},{passive:!0}),window.addEventListener("resize",r),requestAnimationFrame(()=>{this.positionCommentBubbles(),this.updateLines()})}renderSinglePage(e,t){const n=this.createElement("div",`${this.classPrefix}-document`),r=this.createElement("div",`${this.classPrefix}-page`),o=this.renderElement(t.body);o&&r.appendChild(o),this.renderPageFootnotes(this.currentFootnoteIds,r),n.appendChild(r),e.appendChild(n),this.renderDocumentEndnotes(e)}renderWithPages(e,t){const n=t.body,r=n.sectionProps,o=this.splitBySection(n.children||[],r),a=this.groupByPageBreaks(o);this.totalPages=a.length;let c;for(let l=0;l<a.length;l++){this.currentPageNumber=l+1;const m=this.currentFootnoteIds.length,d=a[l];if(d.length===0)continue;let u=d[0].sectProps||r;const f=this.createPageElement(u);u!=null&&u.headerRefs&&this.renderHeaderFooter(u.headerRefs,u,l,c!==u,f,"header");for(const E of d){const F=this.createSectionContent(E.sectProps);for(const S of E.elements){const w=this.renderElement(S);w&&F.appendChild(w)}f.appendChild(F),u=E.sectProps||u}const y=this.currentFootnoteIds.slice(m);this.renderPageFootnotes(y,f),u!=null&&u.footerRefs&&this.renderHeaderFooter(u.footerRefs,u,l,c!==u,f,"footer"),e.appendChild(f),c=u}this.renderDocumentEndnotes(e)}splitBySection(e,t){var a,c;const n=[];let r={sectProps:null,elements:[],pageBreak:!1};n.push(r);for(const l of e)if(l.type===h.Paragraph&&(a=l.props)!=null&&a.pageBreakBefore&&(r.pageBreak=!0,r={sectProps:null,elements:[],pageBreak:!1},n.push(r)),r.elements.push(l),l.type===h.Paragraph){const m=l,d=(c=m.props)==null?void 0:c.sectionProps;let p=!1;const u=f=>{for(const y of f){if(y.type===h.Break){const E=y;if(E.breakType==="page"||E.breakType==="lastRenderedPageBreak"){p=!0;return}}y.type===h.Run&&y.children&&u(y.children)}};this.options.breakPages&&m.children&&u(m.children),(d||p)&&(r.sectProps=d||null,r.pageBreak=p,r={sectProps:null,elements:[],pageBreak:!1},n.push(r))}let o=null;for(let l=n.length-1;l>=0;l--)n[l].sectProps===null?n[l].sectProps=o||t||null:o=n[l].sectProps;return n}groupByPageBreaks(e){const t=[];let n=[];t.push(n);let r=null;for(const o of e)n.push(o),(o.pageBreak||this.isPageBreakSection(r,o.sectProps))&&(n=[],t.push(n)),r=o.sectProps;return t.filter(o=>o.length>0)}isPageBreakSection(e,t){if(!e||!t)return!1;const n=e.pageSize,r=t.pageSize;return!n||!r?!1:n.orientation!==r.orientation||n.width!==r.width||n.height!==r.height}createPageElement(e){const t=this.createElement("section",`${this.classPrefix}-page`);if(e&&(e.pageSize&&(e.pageSize.width&&(t.style.width=e.pageSize.width),e.pageSize.height&&(t.style.minHeight=e.pageSize.height)),e.pageMargins)){const n=e.pageMargins;n.top&&(t.style.paddingTop=n.top),n.right&&(t.style.paddingRight=n.right),n.bottom&&(t.style.paddingBottom=n.bottom),n.left&&(t.style.paddingLeft=n.left)}return t}createSectionContent(e){const t=this.createElement("article",`${this.classPrefix}-section-content`);if(e!=null&&e.columns){const n=e.columns;n.numberOfColumns&&n.numberOfColumns>1&&(t.style.columnCount=String(n.numberOfColumns),n.space&&(t.style.columnGap=n.space),n.separator&&(t.style.columnRule="1px solid #ccc"))}return t}renderHeaderFooter(e,t,n,r,o,a){var p,u;if(!e||e.length===0)return;let c=null;if(t.titlePage&&r&&(c=e.find(f=>f.type==="first")),c||n%2===1&&(c=e.find(f=>f.type==="even")),c||(c=e.find(f=>f.type==="default")),!c)return;const l=a==="header"?(p=this.document)==null?void 0:p.headers:(u=this.document)==null?void 0:u.footers,m=l==null?void 0:l.get(c.id);if(!m)return;const d=this.createElement("div",`${this.classPrefix}-${a}`);for(const f of m.children||[]){const y=this.renderElement(f);y&&d.appendChild(y)}if(t.pageMargins){const f=t.pageMargins;a==="header"&&f.header&&f.top?(d.style.marginTop=`calc(${f.header} - ${f.top})`,d.style.minHeight=`calc(${f.top} - ${f.header})`):a==="footer"&&f.footer&&f.bottom&&(d.style.marginBottom=`calc(${f.footer} - ${f.bottom})`,d.style.minHeight=`calc(${f.bottom} - ${f.footer})`)}a==="header"?o.insertBefore(d,o.firstChild):o.appendChild(d)}renderAllCommentBubbles(){var n;const e=this.createElement("div",`${this.classPrefix}-comments-layer`);this.container.appendChild(e);const t=((n=this.document)==null?void 0:n.comments)||[];console.log("[DEBUG] renderAllCommentBubbles - Total comments:",t.length),t.forEach(r=>{var o;console.log("[DEBUG] Comment:",{id:r.id,author:r.author,date:r.date,childrenCount:((o=r.children)==null?void 0:o.length)||0,text:this.getCommentText(r)})}),console.log("[DEBUG] Comment ranges count:",this.commentRanges.size);for(const r of t){const o=this.commentRanges.get(r.id);if(o&&o.highlightElements.length>0){const a=this.createCommentBubble(r);o.panelElement=a,e.appendChild(a)}}}positionCommentBubbles(){const e=[],n=window.innerHeight-40;for(const[,o]of this.commentRanges){if(!o.panelElement||o.highlightElements.length===0)continue;const c=o.highlightElements[0].getBoundingClientRect(),l=c.top+c.height/2;l>60&&l<n?(e.push({range:o,top:c.top}),o.panelElement.style.display="block"):o.panelElement.style.display="none"}e.sort((o,a)=>o.top-a.top);let r=60;for(const{range:o,top:a}of e){let c=Math.max(a,r+8);c=Math.min(c,n-100),o.panelElement.style.top=`${c}px`,r=c+o.panelElement.offsetHeight}}createSvgLayer(){const e=document.createElementNS("http://www.w3.org/2000/svg","svg");return e.classList.add(`${this.classPrefix}-lines`),e}updateLines(){if(this.svgLayer){this.svgLayer.innerHTML="";for(const[e]of this.commentRanges){const t=e===this.activeCommentId;this.drawCommentLine(e,t)}}}drawCommentLine(e,t){const n=this.commentRanges.get(e);if(!n||!n.highlightElements.length||!n.panelElement||!this.svgLayer||n.panelElement.style.display==="none")return;const r=n.highlightElements[0].getBoundingClientRect(),o=n.panelElement.getBoundingClientRect(),a=r.right,c=r.top+r.height/2,l=o.left,m=o.top+16,d=document.createElementNS("http://www.w3.org/2000/svg","line");d.setAttribute("x1",String(a)),d.setAttribute("y1",String(c)),d.setAttribute("x2",String(l)),d.setAttribute("y2",String(m)),d.setAttribute("stroke","#ef4444"),d.setAttribute("stroke-width",t?"2":"1"),this.svgLayer.appendChild(d)}renderElement(e){switch(e.type){case h.Document:return this.renderDocument(e);case h.Paragraph:return this.renderParagraph(e);case h.Run:return this.renderRun(e);case h.Text:return this.renderText(e);case h.Break:return this.renderBreak(e);case h.Tab:return this.renderTab();case h.Symbol:return this.renderSymbol(e);case h.SimpleField:return this.renderSimpleField(e);case h.ComplexField:return this.renderComplexField(e);case h.FieldInstruction:return this.renderFieldInstruction(e);case h.Table:return this.renderTable(e);case h.TableRow:return this.renderTableRow(e);case h.TableCell:return this.renderTableCell(e);case h.Hyperlink:return this.renderHyperlink(e);case h.Drawing:return this.renderDrawing(e);case h.Image:return this.renderImage(e);case h.CommentRangeStart:return this.renderCommentRangeStart(e);case h.CommentRangeEnd:return this.renderCommentRangeEnd(e);case h.CommentReference:return this.renderCommentReference(e);case h.FootnoteReference:return this.renderFootnoteReference(e);case h.EndnoteReference:return this.renderEndnoteReference(e);case h.Footnote:return this.renderFootnote(e);case h.Endnote:return this.renderEndnote(e);case h.BookmarkStart:return this.renderBookmarkStart(e);case h.BookmarkEnd:return this.renderBookmarkEnd(e);default:return null}}renderDocument(e){const t=this.createElement("article",`${this.classPrefix}-body`);return this.renderChildren(e.children||[],t),t}renderParagraph(e){const t=this.createElement("p",`${this.classPrefix}-p`);this.commentStartInParagraph.clear(),e.props&&this.applyParagraphStyles(t,e.props);const n=this.renderNumbering(e.props);return n&&(t.insertBefore(n,t.firstChild),t.classList.add(`${this.classPrefix}-list-item`)),this.renderChildren(e.children||[],t),(t.childNodes.length===0||t.childNodes.length===1&&n)&&t.appendChild(document.createElement("br")),this.commentStartInParagraph.size>0&&this.options.renderComments&&(t.dataset.commentIds=Array.from(this.commentStartInParagraph).join(",")),t}renderNumbering(e){var d,p;if(!(e!=null&&e.numbering)||!((d=this.document)!=null&&d.numberingMap))return null;const{id:t,level:n}=e.numbering,r=this.document.numberingMap.get(t);if(!r)return null;const o=r.levels.find(u=>u.level===n);if(!o)return null;const a=this.getNumberingContent(r,o,t,n),c=this.createElement("span",`${this.classPrefix}-numbering`);c.textContent=a,o.runProps&&this.applyRunStyles(c,o.runProps);const l=this.createElement("span",`${this.classPrefix}-numbering-suffix`);switch(o.suffix){case"tab":l.innerHTML="&emsp;";break;case"space":l.innerHTML="&nbsp;";break}const m=this.createElement("span",`${this.classPrefix}-numbering-wrapper`);if(m.appendChild(c),m.appendChild(l),(p=o.paragraphProps)!=null&&p.indentation){const u=o.paragraphProps.indentation;u.left&&(m.style.marginLeft=u.left),u.hanging&&(m.style.textIndent=`-${u.hanging}`,m.style.paddingLeft=u.hanging)}return m}getNumberingContent(e,t,n,r){const o=t.format,a=t.text;if(o==="bullet")return a||"•";const c=`${n}-${r}`;let l=this.numberingCounters.get(c)??t.start-1;l++,this.numberingCounters.set(c,l);for(let d=r+1;d<=8;d++)this.numberingCounters.delete(`${n}-${d}`);let m=a;for(let d=0;d<=r;d++){const p=this.numberingCounters.get(`${n}-${d}`)??1,u=e.levels.find(E=>E.level===d),f=(u==null?void 0:u.format)||"decimal",y=this.formatNumber(p,f);m=m.replace(`%${d+1}`,y)}return m}formatNumber(e,t){switch(t){case"decimal":return String(e);case"decimalZero":return e<10?`0${e}`:String(e);case"lowerLetter":return this.toLetters(e,!1);case"upperLetter":return this.toLetters(e,!0);case"lowerRoman":return this.toRoman(e).toLowerCase();case"upperRoman":return this.toRoman(e);case"chineseCountingThousand":case"chineseCounting":return this.toChinese(e);case"ideographTraditional":return this.toChineseTraditional(e);case"bullet":return"•";default:return String(e)}}toLetters(e,t){const n=t?65:97;let r="";for(;e>0;)e--,r=String.fromCharCode(n+e%26)+r,e=Math.floor(e/26);return r}toRoman(e){const t=[[1e3,"M"],[900,"CM"],[500,"D"],[400,"CD"],[100,"C"],[90,"XC"],[50,"L"],[40,"XL"],[10,"X"],[9,"IX"],[5,"V"],[4,"IV"],[1,"I"]];let n="";for(const[r,o]of t)for(;e>=r;)n+=o,e-=r;return n}toChinese(e){const t=["零","一","二","三","四","五","六","七","八","九"],n=["","十","百","千","万"];if(e<=10)return e===10?"十":t[e];let r="",o=0;for(;e>0;){const a=e%10;a!==0?r=t[a]+n[o]+r:r&&!r.startsWith("零")&&(r="零"+r),e=Math.floor(e/10),o++}return r.startsWith("一十")&&(r=r.substring(1)),r}toChineseTraditional(e){const t=["甲","乙","丙","丁","戊","己","庚","辛","壬","癸"];return e>=1&&e<=10?t[e-1]:String(e)}createCommentBubble(e){const t=this.createElement("div",`${this.classPrefix}-comment-bubble`);t.dataset.commentId=e.id;const n=e.initials||e.author.charAt(0).toUpperCase(),r=this.formatDate(e.date),o=this.getCommentText(e);t.innerHTML=`
9
+ <div class="${this.classPrefix}-comment-header">
10
+ <div class="${this.classPrefix}-comment-avatar">${this.escapeHtml(n)}</div>
11
+ <div class="${this.classPrefix}-comment-meta">
12
+ <span class="${this.classPrefix}-comment-author">${this.escapeHtml(e.author)}</span>
13
+ <span class="${this.classPrefix}-comment-date">${r}</span>
14
+ </div>
15
+ </div>
16
+ <div class="${this.classPrefix}-comment-content">${this.escapeHtml(o)}</div>
17
+ ${this.options.enableCommentEdit?`
18
+ <div class="${this.classPrefix}-comment-actions">
19
+ <button class="${this.classPrefix}-comment-btn edit" title="编辑">
20
+ <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M3 17.25V21h3.75L17.81 9.94l-3.75-3.75L3 17.25zM20.71 7.04c.39-.39.39-1.02 0-1.41l-2.34-2.34c-.39-.39-1.02-.39-1.41 0l-1.83 1.83 3.75 3.75 1.83-1.83z"/></svg>
21
+ </button>
22
+ <button class="${this.classPrefix}-comment-btn delete" title="删除">
23
+ <svg viewBox="0 0 24 24" width="14" height="14"><path fill="currentColor" d="M6 19c0 1.1.9 2 2 2h8c1.1 0 2-.9 2-2V7H6v12zM19 4h-3.5l-1-1h-5l-1 1H5v2h14V4z"/></svg>
24
+ </button>
25
+ </div>
26
+ `:""}
27
+ `,t.addEventListener("mouseenter",()=>this.highlightComment(e.id)),t.addEventListener("mouseleave",()=>this.unhighlightComment(e.id)),t.addEventListener("click",()=>{this.selectComment(e.id),this.options.onCommentClick(e)});const a=t.querySelector(".edit");a==null||a.addEventListener("click",l=>{l.stopPropagation(),this.editComment(e)});const c=t.querySelector(".delete");return c==null||c.addEventListener("click",l=>{l.stopPropagation(),this.deleteComment(e.id)}),t}getCommentText(e){const t=[],n=o=>{for(const a of o)a.type===h.Text&&t.push(a.text),a.children&&n(a.children)};n(e.children||[]);const r=t.join("");return!r&&e.rawText?(console.log("[DEBUG] Comment",e.id,"using rawText:",e.rawText),e.rawText):(console.log("[DEBUG] Comment",e.id,"text result:",r),r||"")}highlightComment(e){var n;this.activeCommentId=e;const t=this.commentRanges.get(e);t&&(t.highlightElements.forEach(r=>{r.classList.add(`${this.classPrefix}-highlight--active`)}),(n=t.panelElement)==null||n.classList.add(`${this.classPrefix}-comment-bubble--active`)),this.updateLines()}unhighlightComment(e){var n;this.activeCommentId===e&&(this.activeCommentId=null);const t=this.commentRanges.get(e);t&&(t.highlightElements.forEach(r=>{r.classList.remove(`${this.classPrefix}-highlight--active`)}),(n=t.panelElement)==null||n.classList.remove(`${this.classPrefix}-comment-bubble--active`)),this.updateLines()}selectComment(e){this.activeCommentId=e,this.updateLines()}editComment(e){const t=this.getCommentText(e),n=prompt("编辑评论:",t);if(n!==null&&n!==t){const r={type:h.Text,text:n},o={type:h.Run,children:[r]},a={type:h.Paragraph,children:[o]};e.children=[a];const c=this.commentRanges.get(e.id);if(c!=null&&c.panelElement){const l=c.panelElement.querySelector(`.${this.classPrefix}-comment-content`);l&&(l.textContent=n)}this.options.onCommentChange(e,"update")}}deleteComment(e){var r,o;if(!confirm("确定要删除这条评论吗?"))return;const t=(r=this.document)==null?void 0:r.commentMap.get(e);if(!t)return;const n=this.commentRanges.get(e);if(n&&(n.highlightElements.forEach(a=>{a.classList.remove(`${this.classPrefix}-highlight`),a.classList.remove(`${this.classPrefix}-highlight--active`)}),(o=n.panelElement)==null||o.remove()),this.document){const a=this.document.comments.indexOf(t);a>-1&&this.document.comments.splice(a,1),this.document.commentMap.delete(e)}this.commentRanges.delete(e),this.options.onCommentChange(t,"delete"),this.updateLines()}applyParagraphStyles(e,t){const n=[];if(t.justification){const r={left:"left",center:"center",right:"right",both:"justify"};n.push(`text-align: ${r[t.justification]||"left"}`)}if(t.indentation&&(t.indentation.left&&n.push(`padding-left: ${t.indentation.left}`),t.indentation.right&&n.push(`padding-right: ${t.indentation.right}`),t.indentation.firstLine&&n.push(`text-indent: ${t.indentation.firstLine}`)),t.spacing&&(t.spacing.before&&n.push(`margin-top: ${t.spacing.before}`),t.spacing.after&&n.push(`margin-bottom: ${t.spacing.after}`),t.spacing.line!==void 0)){const r=t.spacing.line;switch(t.spacing.lineRule){case"auto":n.push(`line-height: ${(r/240).toFixed(2)}`);break;case"atLeast":n.push(`line-height: calc(100% + ${r/20}pt)`);break;case"exact":default:n.push(`line-height: ${r/20}pt`);break}}n.length>0&&(e.style.cssText=n.join("; "))}renderRun(e){if(this.skipFieldContent&&!(e.children||[]).some(r=>r.type===h.ComplexField&&r.charType==="end"))return null;const t=this.createElement("span",`${this.classPrefix}-run`);if(this.currentCommentIds.size>0){t.classList.add(`${this.classPrefix}-highlight`);for(const n of this.currentCommentIds){t.classList.add(`${this.classPrefix}-highlight-${n}`),t.dataset.commentId=n;const r=this.commentRanges.get(n);r&&r.highlightElements.push(t)}t.addEventListener("click",()=>{const n=t.dataset.commentId;n&&this.highlightComment(n)})}return e.props&&this.applyRunStyles(t,e.props),this.renderChildren(e.children||[],t),t.childNodes.length===0?null:t}applyRunStyles(e,t){const n=[];t.bold&&n.push("font-weight: bold"),t.italic&&n.push("font-style: italic");const r=[];if(t.underline&&t.underline!=="none"&&(e.classList.add(`${this.classPrefix}-underline-${t.underline}`),this.isComplexUnderline(t.underline)||r.push("underline")),t.strike&&r.push("line-through"),t.dstrike&&e.classList.add(`${this.classPrefix}-dstrike`),r.length>0&&n.push(`text-decoration: ${r.join(" ")}`),t.vertAlign&&e.classList.add(`${this.classPrefix}-${t.vertAlign}`),t.color&&n.push(`color: ${t.color}`),t.fontSize&&n.push(`font-size: ${t.fontSize}`),t.fontFamily&&n.push(`font-family: "${t.fontFamily}"`),t.highlight){const o={yellow:"#ffff00",green:"#00ff00",cyan:"#00ffff",magenta:"#ff00ff",blue:"#0000ff",red:"#ff0000",darkBlue:"#000080",darkCyan:"#008080",darkGreen:"#008000",darkMagenta:"#800080",darkRed:"#800000",darkYellow:"#808000",darkGray:"#808080",lightGray:"#c0c0c0",black:"#000000"};n.push(`background-color: ${o[t.highlight]||t.highlight}`)}n.length>0&&(e.style.cssText=n.join("; "))}isComplexUnderline(e){return["double","thick","dotted","dottedHeavy","dash","dashedHeavy","dashLong","dashLongHeavy","dotDash","dashDotHeavy","dotDotDash","dashDotDotHeavy","wave","wavyHeavy","wavyDouble"].includes(e)}renderText(e){if(this.skipFieldContent)return null;const t=document.createElement("span");return t.textContent=e.text,t}renderBreak(e){switch(e.breakType){case"page":case"lastRenderedPageBreak":const t=this.createElement("div",`${this.classPrefix}-page-break`);return t.style.pageBreakAfter="always",t;case"column":const n=this.createElement("span",`${this.classPrefix}-column-break`);return n.style.breakAfter="column",n;default:return document.createElement("br")}}renderTab(){const e=this.createElement("span",`${this.classPrefix}-tab`);return e.innerHTML="&emsp;",e}renderSymbol(e){const t=this.createElement("span",`${this.classPrefix}-symbol`);return e.font&&(t.style.fontFamily=`"${e.font}", "Segoe UI Symbol", "Apple Symbols", sans-serif`),e.char?t.textContent=e.char:t.textContent="□",t}renderSimpleField(e){const t=e.instruction.trim().toUpperCase(),n=this.evaluateFieldInstruction(t);if(n!==null){const o=this.createElement("span",`${this.classPrefix}-field`);return o.textContent=n,o}const r=this.createElement("span",`${this.classPrefix}-field`);return this.renderChildren(e.children||[],r),r}renderComplexField(e){switch(e.charType){case"begin":return this.inComplexField=!0,this.skipFieldContent=!1,this.currentFieldInstruction="",null;case"separate":const t=this.evaluateFieldInstruction(this.currentFieldInstruction.trim().toUpperCase());if(t!==null){this.skipFieldContent=!0;const n=this.createElement("span",`${this.classPrefix}-field`);return n.textContent=t,n}return null;case"end":return this.inComplexField=!1,this.skipFieldContent=!1,this.currentFieldInstruction="",null;default:return null}}renderFieldInstruction(e){return this.inComplexField&&(this.currentFieldInstruction+=e.text),null}evaluateFieldInstruction(e){switch(e.split(/\s+/)[0]){case"PAGE":return String(this.currentPageNumber);case"NUMPAGES":return String(this.totalPages);case"DATE":return new Date().toLocaleDateString("zh-CN");case"TIME":return new Date().toLocaleTimeString("zh-CN");default:return null}}renderTable(e){var r,o,a;const t=this.createElement("table",`${this.classPrefix}-table`);if(this.tableVerticalMerges.push(this.currentVerticalMerge),this.currentVerticalMerge=new Map,this.tableBordersStack.push(this.currentTableBorders),this.currentTableBorders=(r=e.props)==null?void 0:r.borders,this.currentTableRowCount=((o=e.children)==null?void 0:o.length)||0,this.currentTableColCount=((a=e.columns)==null?void 0:a.length)||0,this.currentTableRowIndex=0,e.columns&&e.columns.length>0){const c=document.createElement("colgroup");for(const l of e.columns){const m=document.createElement("col");l.width&&(m.style.width=l.width),c.appendChild(m)}t.appendChild(c)}e.props&&this.applyTableStyles(t,e.props);const n=document.createElement("tbody");for(const c of e.children||[]){this.currentCellCol=0;const l=this.renderTableRow(c);n.appendChild(l),this.currentTableRowIndex++}return t.appendChild(n),this.currentVerticalMerge=this.tableVerticalMerges.pop()||new Map,this.currentTableBorders=this.tableBordersStack.pop(),t}applyTableStyles(e,t){t.width&&(t.widthType,e.style.width=t.width),t.justification==="center"&&(e.style.marginLeft="auto",e.style.marginRight="auto"),t.cellSpacing&&(e.style.borderSpacing=t.cellSpacing,e.style.borderCollapse="separate")}borderToCss(e){if(!e||!e.style)return"none";const t=this.parseBorderType(e.style);if(t==="none")return"none";const n=e.width||"1px",r=e.color||"black";return`${n} ${t} ${r}`}parseBorderType(e){switch(e){case"single":return"solid";case"dashDotStroked":return"solid";case"dashed":return"dashed";case"dashSmallGap":return"dashed";case"dotDash":return"dotted";case"dotDotDash":return"dotted";case"dotted":return"dotted";case"double":return"double";case"doubleWave":return"double";case"inset":return"inset";case"nil":return"none";case"none":return"none";case"outset":return"outset";case"thick":return"solid";case"thickThinLargeGap":return"solid";case"thickThinMediumGap":return"solid";case"thickThinSmallGap":return"solid";case"thinThickLargeGap":return"solid";case"thinThickMediumGap":return"solid";case"thinThickSmallGap":return"solid";case"thinThickThinLargeGap":return"solid";case"thinThickThinMediumGap":return"solid";case"thinThickThinSmallGap":return"solid";case"threeDEmboss":return"solid";case"threeDEngrave":return"solid";case"triple":return"double";case"wave":return"solid";default:return"solid"}}applyCellBorders(e,t,n,r,o){const a=this.currentTableBorders,c=n===0,l=n===this.currentTableRowCount-1,m=r===0,d=r+o>=this.currentTableColCount;let p=t==null?void 0:t.top;p||(c?p=a==null?void 0:a.top:p=a==null?void 0:a.insideH),p&&(e.style.borderTop=this.borderToCss(p));let u=t==null?void 0:t.bottom;u||(l?u=a==null?void 0:a.bottom:u=a==null?void 0:a.insideH),u&&(e.style.borderBottom=this.borderToCss(u));let f=t==null?void 0:t.left;f||(m?f=a==null?void 0:a.left:f=a==null?void 0:a.insideV),f&&(e.style.borderLeft=this.borderToCss(f));let y=t==null?void 0:t.right;y||(d?y=a==null?void 0:a.right:y=a==null?void 0:a.insideV),y&&(e.style.borderRight=this.borderToCss(y))}renderTableRow(e){const t=this.createElement("tr",`${this.classPrefix}-tr`);this.currentCellCol=0;for(const n of e.children||[]){const r=this.renderTableCell(n);r&&t.appendChild(r)}return t}renderTableCell(e){const t=this.createElement("td",`${this.classPrefix}-td`),n=e.props,r=this.currentCellCol,o=(n==null?void 0:n.gridSpan)||1;if(n!=null&&n.verticalMerge)if(n.verticalMerge==="restart")this.currentVerticalMerge.set(r,t),t.rowSpan=1;else{const a=this.currentVerticalMerge.get(r);if(a)return a.rowSpan+=1,this.currentCellCol+=o,null}else this.currentVerticalMerge.delete(r);return n&&(n.width&&(t.style.width=n.width),n.verticalAlign&&(t.style.verticalAlign=n.verticalAlign),n.shading&&(t.style.backgroundColor=n.shading),o>1&&(t.colSpan=o)),this.applyCellBorders(t,n==null?void 0:n.borders,this.currentTableRowIndex,r,o),this.renderChildren(e.children||[],t),this.currentCellCol+=o,t}renderHyperlink(e){const t=document.createElement("a");return t.className=`${this.classPrefix}-link`,e.href?(t.href=e.href,t.target="_blank",t.rel="noopener noreferrer"):e.anchor&&(t.href=`#${e.anchor}`),this.renderChildren(e.children||[],t),t}renderDrawing(e){const t=this.createElement("span",`${this.classPrefix}-drawing`);return this.renderChildren(e.children||[],t),t}renderImage(e){const t=document.createElement("img");return t.className=`${this.classPrefix}-image`,t.src=e.src,e.width&&(t.style.width=e.width),e.height&&(t.style.height=e.height),e.alt&&(t.alt=e.alt),t}renderCommentRangeStart(e){this.currentCommentIds.add(e.id),this.commentStartInParagraph.add(e.id);const t=this.createElement("span",`${this.classPrefix}-comment-start`);t.dataset.commentId=e.id;const n=this.commentRanges.get(e.id);return n&&(n.startElement=t),t}renderCommentRangeEnd(e){this.currentCommentIds.delete(e.id);const t=this.createElement("span",`${this.classPrefix}-comment-end`);t.dataset.commentId=e.id;const n=this.commentRanges.get(e.id);return n&&(n.endElement=t),t}renderCommentReference(e){const t=this.createElement("span",`${this.classPrefix}-comment-ref`);return t.dataset.commentId=e.id,t.textContent="📝",t.title="查看评论",t.addEventListener("click",()=>{this.highlightComment(e.id)}),t}renderBookmarkStart(e){if(e.name.startsWith("_"))return this.createElement("span");const t=this.createElement("span",`${this.classPrefix}-bookmark`);return t.id=e.name,t.dataset.bookmarkId=e.id,t.dataset.bookmarkName=e.name,t}renderBookmarkEnd(e){return this.createElement("span")}renderFootnoteReference(e){this.footnoteCounter++,this.currentFootnoteIds.push(e.id);const t=this.createElement("sup",`${this.classPrefix}-footnote-ref`);return t.dataset.footnoteId=e.id,t.textContent=String(this.footnoteCounter),t.title="脚注",t.addEventListener("click",()=>{const n=document.getElementById(`${this.classPrefix}-footnote-${e.id}`);n==null||n.scrollIntoView({behavior:"smooth",block:"center"})}),t}renderEndnoteReference(e){this.endnoteCounter++,this.currentEndnoteIds.push(e.id);const t=this.createElement("sup",`${this.classPrefix}-endnote-ref`);return t.dataset.endnoteId=e.id,t.textContent=String(this.endnoteCounter),t.title="尾注",t.addEventListener("click",()=>{const n=document.getElementById(`${this.classPrefix}-endnote-${e.id}`);n==null||n.scrollIntoView({behavior:"smooth",block:"center"})}),t}renderFootnote(e){const t=this.createElement("li",`${this.classPrefix}-footnote`);return t.id=`${this.classPrefix}-footnote-${e.id}`,t.dataset.footnoteId=e.id,this.renderChildren(e.children||[],t),t}renderEndnote(e){const t=this.createElement("li",`${this.classPrefix}-endnote`);return t.id=`${this.classPrefix}-endnote-${e.id}`,t.dataset.endnoteId=e.id,this.renderChildren(e.children||[],t),t}renderPageFootnotes(e,t){var a;if(e.length===0||!((a=this.document)!=null&&a.footnotes))return;const n=this.createElement("div",`${this.classPrefix}-footnotes-section`),r=this.createElement("hr",`${this.classPrefix}-footnotes-separator`);n.appendChild(r);const o=this.createElement("ol",`${this.classPrefix}-footnotes-list`);for(const c of e){const l=this.document.footnotes.get(c);if(l){const m=this.renderFootnote(l);o.appendChild(m)}}n.appendChild(o),t.appendChild(n)}renderDocumentEndnotes(e){var o;if(this.currentEndnoteIds.length===0||!((o=this.document)!=null&&o.endnotes))return;const t=this.createElement("div",`${this.classPrefix}-endnotes-section`),n=this.createElement("h3",`${this.classPrefix}-endnotes-title`);n.textContent="尾注",t.appendChild(n);const r=this.createElement("ol",`${this.classPrefix}-endnotes-list`);for(const a of this.currentEndnoteIds){const c=this.document.endnotes.get(a);if(c){const l=this.renderEndnote(c);r.appendChild(l)}}t.appendChild(r),e.appendChild(t)}renderChildren(e,t){for(const n of e){const r=this.renderElement(n);r&&t.appendChild(r)}}createElement(e,t){const n=document.createElement(e);return t&&(n.className=t),n}formatDate(e){try{return new Date(e).toLocaleDateString("zh-CN",{year:"numeric",month:"2-digit",day:"2-digit"})}catch{return e}}escapeHtml(e){const t=document.createElement("div");return t.textContent=e,t.innerHTML}getDocument(){return this.document}}class K{constructor(e){g(this,"parser");g(this,"renderer");g(this,"document",null);this.parser=new q,this.renderer=new Y(e)}async render(e){this.document=await this.parser.parse(e),this.renderer.render(this.document)}getDocument(){return this.document}getComments(){var e;return((e=this.document)==null?void 0:e.comments)||[]}getParser(){return this.parser}}async function Ne(i,e,t){const n=new K({container:e,...t});return await n.render(i),n}b.DOCX_PARTS=k,b.DocumentParser=q,b.DocumentRenderer=Y,b.DocxRender=K,b.DomType=h,b.XML_NS=B,b.applyTintShade=z,b.buildCommentTree=W,b.buildFontFamily=fe,b.cleanupFontStyles=Pe,b.getEmbedFontRefs=ue,b.getFontDeclaration=he,b.getSubstituteFontName=de,b.hasEmbeddedFont=me,b.loadEmbeddedFonts=U,b.parseCommentsExtended=V,b.parseFontTable=O,b.parseTheme=L,b.renderDocx=Ne,b.resolveThemeColor=H,b.resolveThemeFont=re,Object.defineProperty(b,Symbol.toStringTag,{value:"Module"})});
package/dist/style.css ADDED
@@ -0,0 +1 @@
1
+ .docx-container{width:100%;height:100%;overflow:hidden;background-color:#525659;font-family:Segoe UI,-apple-system,BlinkMacSystemFont,PingFang SC,Microsoft YaHei,sans-serif}.docx-wrapper{position:relative;width:100%;height:100%;overflow:auto;padding:30px;display:flex;flex-direction:column;align-items:center;gap:30px}.docx-page{background:#fff;box-shadow:0 0 10px #00000080;box-sizing:border-box;display:flex;flex-direction:column;position:relative;overflow:hidden;flex-shrink:0;width:595.3pt;min-height:841.9pt;padding:72pt 90pt}.docx-section-content{flex:1;z-index:1}.docx-header,.docx-footer{z-index:1;color:#666;font-size:10pt}.docx-header{padding-bottom:12pt;border-bottom:1px solid #eee;margin-bottom:12pt}.docx-footer{padding-top:12pt;border-top:1px solid #eee;margin-top:auto}.docx-body{line-height:1.5;color:#000}.docx-p{margin:0;min-height:1em}.docx-run{white-space:pre-wrap;overflow-wrap:break-word}.docx-superscript{vertical-align:super;font-size:.75em;line-height:0}.docx-subscript{vertical-align:sub;font-size:.75em;line-height:0}.docx-dstrike{text-decoration:line-through;text-decoration-style:double}.docx-symbol{display:inline}.docx-underline-single{text-decoration:underline;text-decoration-style:solid}.docx-underline-words{text-decoration:underline;text-decoration-skip-ink:none}.docx-underline-double{text-decoration:underline;text-decoration-style:double}.docx-underline-thick{text-decoration:underline;text-decoration-style:solid;text-decoration-thickness:2px}.docx-underline-dotted{text-decoration:underline;text-decoration-style:dotted}.docx-underline-dottedHeavy{text-decoration:underline;text-decoration-style:dotted;text-decoration-thickness:2px}.docx-underline-dash{text-decoration:underline;text-decoration-style:dashed}.docx-underline-dashedHeavy{text-decoration:underline;text-decoration-style:dashed;text-decoration-thickness:2px}.docx-underline-dashLong{text-decoration:underline;text-decoration-style:dashed}.docx-underline-dashLongHeavy{text-decoration:underline;text-decoration-style:dashed;text-decoration-thickness:2px}.docx-underline-dotDash{text-decoration:none;border-bottom:1px dashed currentColor;background-image:linear-gradient(90deg,currentColor 1px,transparent 1px);background-size:4px 1px;background-repeat:repeat-x;background-position:0 100%}.docx-underline-dashDotHeavy{text-decoration:none;border-bottom:2px dashed currentColor}.docx-underline-dotDotDash{text-decoration:none;border-bottom:1px dotted currentColor}.docx-underline-dashDotDotHeavy{text-decoration:none;border-bottom:2px dotted currentColor}.docx-underline-wave{text-decoration:underline;text-decoration-style:wavy}.docx-underline-wavyHeavy{text-decoration:underline;text-decoration-style:wavy;text-decoration-thickness:2px}.docx-underline-wavyDouble{text-decoration:underline;text-decoration-style:wavy;position:relative}.docx-underline-wavyDouble:after{content:"";position:absolute;left:0;right:0;bottom:-3px;border-bottom:1px wavy currentColor;text-decoration:underline wavy}.docx-tab{display:inline-block;min-width:36pt}.docx-list-item{display:flex;align-items:baseline}.docx-numbering-wrapper{display:inline-block;flex-shrink:0;min-width:24pt;text-align:right;margin-right:6pt}.docx-numbering{white-space:nowrap}.docx-numbering-suffix{display:inline-block}.docx-highlight{background-color:#fbbf2440;border-bottom:2px solid #fbbf24;cursor:pointer;transition:all .2s ease;border-radius:2px;padding:1px 2px;margin:-1px -2px}.docx-highlight:hover{background-color:#fbbf2466}.docx-highlight--active{background-color:#f59e0b80;border-bottom-color:#f59e0b}.docx-comments-layer{position:fixed;right:20px;top:0;bottom:0;width:260px;z-index:1000;pointer-events:none}.docx-comment-bubble{pointer-events:auto}.docx-comment-bubble{position:relative;width:100%;background:#fffbeb;border:1px solid #fcd34d;border-left:4px solid #f59e0b;border-radius:8px;padding:12px 14px;font-size:13px;cursor:pointer;transition:all .2s ease;box-shadow:0 2px 8px #00000014;margin-bottom:12px}.docx-comment-bubble:hover{box-shadow:0 4px 12px #f59e0b33;transform:translate(-2px)}.docx-comment-bubble--active{background:#fef3c7;border-color:#f59e0b;box-shadow:0 4px 16px #f59e0b4d}.docx-comment-header{display:flex;align-items:center;gap:10px;margin-bottom:8px}.docx-comment-avatar{width:28px;height:28px;background:linear-gradient(135deg,#f59e0b,#d97706);border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:12px;font-weight:600;flex-shrink:0}.docx-comment-meta{flex:1;min-width:0}.docx-comment-author{display:block;font-weight:600;color:#92400e;font-size:13px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.docx-comment-date{display:block;font-size:11px;color:#b45309;margin-top:1px}.docx-comment-content{color:#78350f;line-height:1.5;word-wrap:break-word}.docx-comment-actions{display:flex;gap:6px;margin-top:10px;padding-top:10px;border-top:1px solid #fcd34d;opacity:0;transition:opacity .2s ease}.docx-comment-bubble:hover .docx-comment-actions{opacity:1}.docx-comment-btn{display:flex;align-items:center;justify-content:center;width:26px;height:26px;padding:0;border:none;background:#fff;border-radius:4px;cursor:pointer;color:#92400e;transition:all .15s ease}.docx-comment-btn:hover{background:#fef3c7}.docx-comment-btn.delete:hover{background:#fef2f2;color:#dc2626}.docx-comment-ref{cursor:pointer;font-size:12px;vertical-align:super;margin-left:2px;opacity:.7;transition:opacity .2s}.docx-comment-ref:hover{opacity:1}.docx-comment-start,.docx-comment-end{display:none}.docx-table{border-collapse:collapse;margin:6pt 0;font-size:inherit;table-layout:fixed;width:100%}.docx-td{padding:4pt 6pt;vertical-align:top;word-wrap:break-word;overflow-wrap:break-word}.docx-table .docx-p{margin:0;min-height:auto}.docx-bookmark{display:inline;position:relative}.docx-link{color:#0563c1;text-decoration:underline}.docx-link:hover{color:#954f72}.docx-link[href^="#"]{cursor:pointer}.docx-image{max-width:100%;height:auto}.docx-drawing{display:inline-block}.docx-footnote-ref,.docx-endnote-ref{color:#06c;cursor:pointer;font-size:.8em;vertical-align:super;line-height:0;padding:0 2px;transition:color .2s}.docx-footnote-ref:hover,.docx-endnote-ref:hover{color:#003d99;text-decoration:underline}.docx-footnotes-section{margin-top:auto;padding-top:12pt;font-size:9pt;color:#333}.docx-footnotes-separator{border:none;border-top:1px solid #ccc;margin:0 0 8pt;width:33%}.docx-footnotes-list{margin:0;padding-left:20pt;list-style-type:decimal}.docx-footnote{margin-bottom:4pt;line-height:1.4}.docx-footnote .docx-p{display:inline;margin:0;min-height:auto}.docx-endnotes-section{background:#fff;box-shadow:0 0 10px #00000080;box-sizing:border-box;width:595.3pt;padding:40pt 90pt;margin-top:30px}.docx-endnotes-title{font-size:14pt;font-weight:700;margin:0 0 12pt;padding-bottom:8pt;border-bottom:2px solid #333}.docx-endnotes-list{margin:0;padding-left:20pt;list-style-type:decimal;font-size:10pt}.docx-endnote{margin-bottom:8pt;line-height:1.5}.docx-endnote .docx-p{display:inline;margin:0;min-height:auto}.docx-page-break{height:40px;border-bottom:2px dashed #ccc;margin:20px 0;position:relative}.docx-page-break:after{content:"分页";position:absolute;left:50%;bottom:-10px;transform:translate(-50%);background:#fff;padding:0 12px;font-size:12px;color:#999}.docx-column-break{display:block;break-after:column}.docx-lines{position:fixed;top:0;left:0;width:100vw;height:100vh;pointer-events:none;z-index:999}.docx-wrapper::-webkit-scrollbar{width:12px;height:12px}.docx-wrapper::-webkit-scrollbar-track{background:#3d3d3d}.docx-wrapper::-webkit-scrollbar-thumb{background:#666;border-radius:6px}.docx-wrapper::-webkit-scrollbar-thumb:hover{background:#888}@media (max-width: 900px){.docx-wrapper{padding:16px}.docx-page{width:100%;min-height:auto;padding:40px 30px}.docx-comments-layer,.docx-lines{display:none}}@media print{.docx-container{background:#fff}.docx-wrapper{padding:0;overflow:visible;display:block;background:#fff}.docx-page{box-shadow:none;margin:0;page-break-after:always;width:100%;min-height:100vh}.docx-page:last-child{page-break-after:auto}.docx-comments-layer{display:none}.docx-highlight{background:none;border-bottom:none}.docx-lines,.docx-page-break{display:none}}
package/package.json CHANGED
@@ -1,10 +1,14 @@
1
1
  {
2
2
  "name": "@courtifyai/docx-render",
3
- "version": "1.0.0",
3
+ "version": "1.0.2",
4
4
  "description": " DOCX render library",
5
- "main": "dist/index.js",
6
- "module": "dist/index.esm.js",
5
+ "main": "dist/index.umd.js",
6
+ "module": "dist/index.es.js",
7
7
  "types": "dist/index.d.ts",
8
+ "files": [
9
+ "dist",
10
+ "README.md"
11
+ ],
8
12
  "scripts": {
9
13
  "dev": "vite",
10
14
  "build": "tsc && vite build",
@@ -1,19 +0,0 @@
1
- const fs = require('fs');
2
- const JSZip = require('jszip');
3
-
4
- async function readComments() {
5
- const data = fs.readFileSync('contract.docx');
6
- const zip = await JSZip.loadAsync(data);
7
- const commentsXml = await zip.file('word/comments.xml')?.async('string');
8
-
9
- if (commentsXml) {
10
- console.log('Comments XML length:', commentsXml.length);
11
- console.log('Content:', commentsXml);
12
- } else {
13
- console.log('comments.xml not found');
14
- }
15
- }
16
-
17
- readComments().catch(err => {
18
- console.error('Error:', err.message);
19
- });
package/index.html DELETED
@@ -1,312 +0,0 @@
1
- <!DOCTYPE html>
2
- <html lang="zh-CN">
3
- <head>
4
- <meta charset="UTF-8">
5
- <meta name="viewport" content="width=device-width, initial-scale=1.0">
6
- <title>DOCX Render - 文档预览与评论</title>
7
- <style>
8
- * {
9
- margin: 0;
10
- padding: 0;
11
- box-sizing: border-box;
12
- }
13
-
14
- html, body {
15
- height: 100%;
16
- }
17
-
18
- body {
19
- font-family: 'SF Pro Display', -apple-system, BlinkMacSystemFont, 'Segoe UI', sans-serif;
20
- background: #0f172a;
21
- }
22
-
23
- .app {
24
- display: flex;
25
- flex-direction: column;
26
- height: 100%;
27
- }
28
-
29
- /* 顶部工具栏 */
30
- .toolbar {
31
- display: flex;
32
- align-items: center;
33
- justify-content: space-between;
34
- padding: 12px 24px;
35
- background: linear-gradient(135deg, #1e293b 0%, #334155 100%);
36
- border-bottom: 1px solid #475569;
37
- }
38
-
39
- .toolbar__brand {
40
- display: flex;
41
- align-items: center;
42
- gap: 12px;
43
- }
44
-
45
- .toolbar__logo {
46
- width: 36px;
47
- height: 36px;
48
- background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
49
- border-radius: 8px;
50
- display: flex;
51
- align-items: center;
52
- justify-content: center;
53
- color: white;
54
- font-weight: 700;
55
- font-size: 18px;
56
- }
57
-
58
- .toolbar__title {
59
- font-size: 18px;
60
- font-weight: 600;
61
- color: white;
62
- }
63
-
64
- .toolbar__subtitle {
65
- font-size: 12px;
66
- color: #94a3b8;
67
- margin-top: 2px;
68
- }
69
-
70
- .toolbar__actions {
71
- display: flex;
72
- gap: 12px;
73
- }
74
-
75
- .btn {
76
- display: inline-flex;
77
- align-items: center;
78
- gap: 8px;
79
- padding: 10px 18px;
80
- font-size: 14px;
81
- font-weight: 500;
82
- border: none;
83
- border-radius: 8px;
84
- cursor: pointer;
85
- transition: all 0.2s;
86
- font-family: inherit;
87
- }
88
-
89
- .btn--primary {
90
- background: linear-gradient(135deg, #f59e0b 0%, #d97706 100%);
91
- color: white;
92
- }
93
-
94
- .btn--primary:hover {
95
- transform: translateY(-1px);
96
- box-shadow: 0 4px 12px rgba(245, 158, 11, 0.4);
97
- }
98
-
99
- .btn svg {
100
- width: 18px;
101
- height: 18px;
102
- }
103
-
104
- /* 主内容区 */
105
- .main {
106
- flex: 1;
107
- overflow: hidden;
108
- }
109
-
110
- #viewer {
111
- width: 100%;
112
- height: 100%;
113
- }
114
-
115
- /* 加载状态 */
116
- .loading {
117
- display: flex;
118
- flex-direction: column;
119
- align-items: center;
120
- justify-content: center;
121
- height: 100%;
122
- color: #64748b;
123
- gap: 16px;
124
- }
125
-
126
- .loading__spinner {
127
- width: 40px;
128
- height: 40px;
129
- border: 3px solid #334155;
130
- border-top-color: #f59e0b;
131
- border-radius: 50%;
132
- animation: spin 0.8s linear infinite;
133
- }
134
-
135
- @keyframes spin {
136
- to { transform: rotate(360deg); }
137
- }
138
-
139
- /* 文件输入 */
140
- .file-input {
141
- display: none;
142
- }
143
-
144
- /* 底部状态栏 */
145
- .status-bar {
146
- display: flex;
147
- align-items: center;
148
- justify-content: space-between;
149
- padding: 8px 24px;
150
- background: #1e293b;
151
- border-top: 1px solid #334155;
152
- font-size: 12px;
153
- color: #64748b;
154
- }
155
-
156
- .status-bar__item {
157
- display: flex;
158
- align-items: center;
159
- gap: 6px;
160
- }
161
-
162
- .status-bar__dot {
163
- width: 8px;
164
- height: 8px;
165
- border-radius: 50%;
166
- background: #22c55e;
167
- }
168
- </style>
169
- </head>
170
- <body>
171
- <div class="app">
172
- <header class="toolbar">
173
- <div class="toolbar__brand">
174
- <div class="toolbar__logo">D</div>
175
- <div>
176
- <h1 class="toolbar__title">DOCX Render</h1>
177
- <p class="toolbar__subtitle">自研渲染引擎 · 支持评论显示与编辑</p>
178
- </div>
179
- </div>
180
- <div class="toolbar__actions">
181
- <input type="file" id="file-input" class="file-input" accept=".docx">
182
- <button class="btn btn--primary" onclick="document.getElementById('file-input').click()">
183
- <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
184
- <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"/>
185
- <polyline points="17,8 12,3 7,8"/>
186
- <line x1="12" y1="3" x2="12" y2="15"/>
187
- </svg>
188
- 打开其他文件
189
- </button>
190
- </div>
191
- </header>
192
-
193
- <main class="main">
194
- <div id="viewer">
195
- <div class="loading" id="loading">
196
- <div class="loading__spinner"></div>
197
- <span>正在加载文档...</span>
198
- </div>
199
- </div>
200
- </main>
201
-
202
- <footer class="status-bar">
203
- <div class="status-bar__item">
204
- <span class="status-bar__dot"></span>
205
- <span id="status-text">就绪</span>
206
- </div>
207
- <div class="status-bar__item">
208
- <span id="comment-count">评论: 0</span>
209
- </div>
210
- </footer>
211
- </div>
212
-
213
- <script type="module">
214
- import { DocxRender } from './src/index.ts'
215
-
216
- let docxRender = null
217
-
218
- const viewer = document.getElementById('viewer')
219
- const loading = document.getElementById('loading')
220
- const fileInput = document.getElementById('file-input')
221
- const statusText = document.getElementById('status-text')
222
- const commentCount = document.getElementById('comment-count')
223
-
224
- // 更新状态
225
- function updateStatus(text) {
226
- statusText.textContent = text
227
- }
228
-
229
- // 更新评论计数
230
- function updateCommentCount(count) {
231
- commentCount.textContent = `评论: ${count}`
232
- }
233
-
234
- // 加载文件
235
- async function loadFile(file) {
236
- loading.style.display = 'flex'
237
- updateStatus('正在加载...')
238
-
239
- try {
240
- // 清空之前的内容
241
- viewer.innerHTML = ''
242
- viewer.appendChild(loading)
243
-
244
- // 创建渲染器
245
- docxRender = new DocxRender({
246
- container: viewer,
247
- renderComments: true,
248
- enableCommentEdit: true,
249
- showCommentLines: true,
250
- onCommentClick: (comment) => {
251
- console.log('点击评论:', comment)
252
- },
253
- onCommentChange: (comment, action) => {
254
- console.log('评论变更:', action, comment)
255
- updateCommentCount(docxRender.getComments().length)
256
- }
257
- })
258
-
259
- await docxRender.render(file)
260
-
261
- const comments = docxRender.getComments()
262
- updateCommentCount(comments.length)
263
- updateStatus(`已加载: ${file.name || 'contract.docx'}`)
264
-
265
- console.log('文档加载完成,评论数:', comments.length)
266
- } catch (error) {
267
- console.error('加载失败:', error)
268
- updateStatus('加载失败')
269
- viewer.innerHTML = `
270
- <div class="loading">
271
- <span style="color: #ef4444;">加载失败: ${error.message}</span>
272
- </div>
273
- `
274
- }
275
- }
276
-
277
- // 文件选择
278
- fileInput.addEventListener('change', (e) => {
279
- const file = e.target.files[0]
280
- if (file) {
281
- loadFile(file)
282
- }
283
- })
284
-
285
- // 自动加载 contract.docx
286
- async function loadDefaultFile() {
287
- try {
288
- const response = await fetch('./contract.docx')
289
- if (response.ok) {
290
- const blob = await response.blob()
291
- const file = new File([blob], 'contract.docx', {
292
- type: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
293
- })
294
- await loadFile(file)
295
- } else {
296
- loading.innerHTML = `
297
- <span>请点击上方按钮选择 .docx 文件</span>
298
- `
299
- updateStatus('等待文件')
300
- }
301
- } catch (error) {
302
- loading.innerHTML = `
303
- <span>请点击上方按钮选择 .docx 文件</span>
304
- `
305
- updateStatus('等待文件')
306
- }
307
- }
308
-
309
- loadDefaultFile()
310
- </script>
311
- </body>
312
- </html>