@kuzuma/colwork 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +140 -0
- package/dist/colwork.js +1775 -1188
- package/dist/colwork.umd.cjs +6 -7
- package/dist/index.d.ts +174 -93
- package/dist/model-merges.d.cts +3 -0
- package/dist/model-merges.d.ts +3 -0
- package/dist/model-schema.d.cts +80 -0
- package/dist/model-schema.d.ts +80 -0
- package/dist/model-validation.d.cts +7 -0
- package/dist/model-validation.d.ts +7 -0
- package/dist/model.cjs +1 -0
- package/dist/model.d.cts +18 -0
- package/dist/model.d.ts +18 -0
- package/dist/model.js +259 -0
- package/dist/range.d.cts +15 -0
- package/dist/range.d.ts +15 -0
- package/dist/yjsArchive.d.cts +28 -0
- package/dist/yjsArchive.d.ts +28 -0
- package/dist/yjsRebuild.d.cts +2 -0
- package/dist/yjsRebuild.d.ts +2 -0
- package/package.json +18 -7
package/dist/colwork.umd.cjs
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
|
-
(function(
|
|
2
|
-
|
|
3
|
-
`).replace(/\r/g,`
|
|
1
|
+
(function(z,D){typeof exports=="object"&&typeof module<"u"?D(exports,require("y-websocket"),require("yjs"),require("y-protocols/awareness"),require("y-webrtc")):typeof define=="function"&&define.amd?define(["exports","y-websocket","yjs","y-protocols/awareness","y-webrtc"],D):(z=typeof globalThis<"u"?globalThis:z||self,D(z.Colwork={},z.YWebsocket,z.Y,z.YAwareness,z.YWebrtc))})(this,(function(z,D,I,Ae,Re){"use strict";var kt=Object.defineProperty;var Ct=(z,D,I)=>D in z?kt(z,D,{enumerable:!0,configurable:!0,writable:!0,value:I}):z[D]=I;var u=(z,D,I)=>Ct(z,typeof D!="symbol"?D+"":D,I);function _e(o){const e=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(o){for(const t in o)if(t!=="default"){const s=Object.getOwnPropertyDescriptor(o,t);Object.defineProperty(e,t,s.get?s:{enumerable:!0,get:()=>o[t]})}}return e.default=o,Object.freeze(e)}const W=_e(I);function le(o,e){return{start:{row:Math.min(o.row,e.row),column:Math.min(o.column,e.column)},end:{row:Math.max(o.row,e.row),column:Math.max(o.column,e.column)}}}function F(o,e){return e.row>=o.start.row&&e.row<=o.end.row&&e.column>=o.start.column&&e.column<=o.end.column}function $e(o){return{rows:o.end.row-o.start.row+1,columns:o.end.column-o.start.column+1}}function H(o){return`${o.row}:${o.column}`}function _(o,e){const t=o??e??{row:0,column:0};return le(t,e??t)}function ce(o,e,t,s){return{row:o==="column"||o==="all"?t-1:e.row,column:o==="row"||o==="all"?s-1:e.column}}function He(o,e,t){if(!(!o.anchor||!o.focus))return _(o.anchor,ce(o.mode,o.focus,e,t))}class Ne{constructor(e){u(this,"rows");u(this,"columns");var s;for(const n of[e.rowCount,e.columnCount])if(n!==void 0&&(!Number.isSafeInteger(n)||n<1))throw new RangeError("Table dimensions must be positive safe integers");const t=e.transport==="external";this.rows=Math.max(e.rowCount??100,t?1:((s=e.rows)==null?void 0:s.length)??10),this.columns=Math.max(e.columnCount??10,t?1:6)}expandDocument(e){const t=e.getContentSize(),s=t.rows>this.rows||t.columns>this.columns;return this.rows=Math.max(this.rows,t.rows),this.columns=Math.max(this.columns,t.columns),s}expandRemote(e){const t=this.rows,s=this.columns;return e.getStates().forEach((n,r)=>{if(r===e.clientID)return;const i=n.selection;!(i!=null&&i.anchor)||!i.focus||(this.rows=Math.max(this.rows,i.anchor.row+1,i.focus.row+1),this.columns=Math.max(this.columns,i.anchor.column+1,i.focus.column+1))}),t!==this.rows||s!==this.columns}expandViewport(e,t){const s=e.scrollTop+e.clientHeight>=e.scrollHeight-280,n=e.scrollLeft+e.clientWidth>=e.scrollWidth-280;s&&(this.rows+=100),n&&(this.columns+=5),t.mode&&(s||n)&&(t.focus=ce(t.mode,t.focus??{row:0,column:0},this.rows,this.columns),t.publishSelection())}}const he=[["设计协作表格","小林","进行中","高","2026-08-07","欢迎测试"],["整理组件 API","阿南","已完成","中","2026-08-08","已补充示例"],["补充单元测试","小周","未开始","高","2026-08-09","覆盖边界输入"],["实现虚拟滚动","小林","进行中","高","2026-08-10","先支持行虚拟化"],["接入 WebSocket","阿南","已完成","中","2026-08-11","等待联调"],["增加复制粘贴","小周","进行中","中","2026-08-12","支持 TSV 格式"],["检查 Safari 兼容性","小雨","阻塞","高","2026-08-13","需要补充 ICE 日志"],["编写使用文档","阿南","未开始","低","2026-08-14","准备 API 清单"],["优化移动端布局","小雨","未开始","中","2026-08-15","检查横向滚动"],["发布 v0.1.0","小林","未开始","低","2026-08-18","等待最终验收"]];function de(o){o.doc.transact(()=>{o.cells.set("0:0",`设计协作表格
|
|
2
|
+
多人协作工作区`),o.cells.delete("0:1"),o.cells.delete("0:2"),o.merges.set("0:0-0:2","1"),o.styles.set("0:0",JSON.stringify({bold:!0,fontSize:16,color:"#0f172a",background:"#bae6fd",align:"center",wrap:!0,border:{top:!0,right:!0,bottom:!0,left:!0}})),o.styles.set("1:0",JSON.stringify({bold:!0,underline:!0,background:"#fef3c7",border:{bottom:!0}})),o.styles.set("1:1",JSON.stringify({italic:!0,color:"#7c3aed"})),o.styles.set("1:2",JSON.stringify({strike:!0,color:"#b91c1c"})),o.cells.set("2:0","125000"),o.styles.set("2:0",JSON.stringify({format:"number",fontSize:14,border:{top:!0,bottom:!0}})),o.cells.set("2:1","0.72"),o.styles.set("2:1",JSON.stringify({format:"percent",color:"#047857",align:"right"})),o.cells.set("2:2","2026-08-09"),o.styles.set("2:2",JSON.stringify({format:"date",background:"#dcfce7"})),o.cells.set("3:0",`这是一段较长的演示内容
|
|
3
|
+
可使用自动换行工具查看`),o.styles.set("3:0",JSON.stringify({wrap:!0,background:"#f1f5f9",border:{top:!0,right:!0,bottom:!0,left:!0}})),o.cells.set("4:0","删除线示例"),o.styles.set("4:0",JSON.stringify({strike:!0,color:"#64748b"})),o.cells.set("5:0","合并区域示例"),o.cells.delete("5:1"),o.cells.delete("5:2"),o.merges.set("5:0-5:2","1"),o.styles.set("5:0",JSON.stringify({bold:!0,align:"center",background:"#ede9fe",border:{top:!0,right:!0,bottom:!0,left:!0}})),o.rowHeights.set("0",72),o.rowHeights.set("3",72),o.rowHeights.set("5",44),o.columnWidths.set("0",220),o.columnWidths.set("1",130),o.columnWidths.set("2",130)})}function Oe(o,e,t,s,n){const r=o.provider;if(!(!r||e.transport==="external")){if(r instanceof D.WebsocketProvider){r.on("status",({status:i})=>n.log(i==="connected"?"signaling:connected":"signaling:disconnected")),r.on("sync",i=>{if(n.log(i?"synced":"syncing"),!i||!e.initializeAfterSync)return;const c=t.doc.getMap("colwork-metadata");n.canEdit()&&!c.get("initialized")&&(t.doc.transact(()=>{s&&t.cells.size===0&&t.locks.size===0&&(t.seed(e.rows??he),de(t)),c.set("initialized",!0)}),n.clearHistory()),n.render()}),e.initializeAfterSync&&r.connect();return}r.on("status",({connected:i})=>{n.log(i?"signaling:connected":"signaling:disconnected"),n.inspect()}),r.on("synced",({synced:i})=>n.log(i?"synced":"syncing")),r.on("peers",({added:i,removed:c,webrtcPeers:h})=>{i.length&&n.log(`peer:+${i.length}`),c.length&&n.log(`peer:-${c.length}`),n.log(`webrtc:${h.length}`),n.inspect()})}}function De(o,e){const t=o.trim().replace("#","");if(/^[\da-f]{3}$/i.test(t)){const[n,r,i]=t.split("").map(c=>Number.parseInt(c+c,16));return`rgba(${n}, ${r}, ${i}, ${e})`}if(/^[\da-f]{6}$/i.test(t)){const n=Number.parseInt(t,16);return`rgba(${n>>16}, ${n>>8&255}, ${n&255}, ${e})`}const s=o.match(/^rgba?\(\s*([\d.]+)[, ]+\s*([\d.]+)[, ]+\s*([\d.]+)/i);return s?`rgba(${s[1]}, ${s[2]}, ${s[3]}, ${e})`:`color-mix(in srgb, ${o} 12%, transparent)`}function P(o,e){let t=0;for(let s=0;s<o;s+=1)t+=e(s);return t}function X(o,e){return P(o,e)}function We(o){const e=(h,m,a,l)=>{let d=0,f=0;for(;f<a&&d+l(f)<=h;)d+=l(f),f+=1;const S=Math.max(0,f-o.overscan);let M=f,b=d;for(;M<a&&b<h+m;)b+=l(M),M+=1;return{start:S,end:Math.min(a-1,M+o.overscan-1)}},t=e(o.scrollTop,o.clientHeight,o.rowCount,o.rowSize),s=e(o.scrollLeft,o.clientWidth,o.columnCount,o.columnSize),n=t.start,r=t.end,i=s.start,c=s.end;return{top:n,bottom:r,left:i,right:c}}function ue(o,e,t,s,n){o.querySelectorAll("td[data-key]").forEach(r=>{const[i,c]=r.dataset.key.split(":").map(Number),h=Number(r.dataset.renderRow??i),m=Number(r.dataset.renderColumn??c),a=Number(r.dataset.renderBottom??h+r.rowSpan-1),l=Number(r.dataset.renderRight??m+r.colSpan-1);if(h>e.end.row||a<e.start.row||m>e.end.column||l<e.start.column)return;const d=getComputedStyle(r),f=parseFloat(d.borderTopWidth),S=parseFloat(d.borderRightWidth),M=parseFloat(d.borderBottomWidth),b=parseFloat(d.borderLeftWidth),L=(E,x,R,C,q,O,g)=>{if(E>=R&&x<=C)return[`${-O}px`,`${-g}px`];let v=0,y=0,k=0;for(let B=E;B<=x;B++){const V=o.querySelector(`th[data-selection-axis="${q}"][data-selection-index="${B}"]`),U=V==null?void 0:V.getBoundingClientRect(),ae=q==="row"?(U==null?void 0:U.height)??n("row",B):(U==null?void 0:U.width)??n("column",B);v+=ae,B<R&&(y+=ae),B>C&&(k+=ae)}const A=(B,V)=>B===0?`${-V}px`:`calc(${B/v*100}% + ${(O+g)*B/v-V}px)`;return[A(y,O),A(k,g)]},[$,N]=L(h,a,e.start.row,e.end.row,"row",f,M),[j,w]=L(m,l,e.start.column,e.end.column,"column",b,S),p=document.createElement("span");p.className=t,p.setAttribute("aria-hidden","true"),Object.assign(p.style,{top:$,right:w,bottom:N,left:j,borderTopWidth:h<=e.start.row?"2px":"0",borderRightWidth:l>=e.end.column?"2px":"0",borderBottomWidth:a>=e.end.row?"2px":"0",borderLeftWidth:m<=e.start.column?"2px":"0",borderColor:s,backgroundColor:De(s,.1)}),r.append(p)})}function me(o,e,t){var n,r;const s=document.createElement("span");s.className="colwork-table__remote-cursor",s.style.backgroundColor=((n=e.user)==null?void 0:n.color)??"#64748b",s.textContent=((r=e.user)==null?void 0:r.name)??String(t).slice(0,6),o.append(s)}function fe(o,e,t,s,n,r,i){o.replaceChildren(),o.style.width=`${e.clientWidth}px`,o.style.height=`${e.clientHeight}px`;const c=(h,m,a,l)=>{if(!m||a>=l)return;const d=document.createElement("span");d.className=`colwork-table__frozen-boundary colwork-table__frozen-boundary--${h}`,d.setAttribute("aria-hidden","true"),d.style.left=`${h==="column"?a-1:0}px`,d.style.top=`${h==="row"?a-1:0}px`,h==="column"?d.style.height=`${e.clientHeight}px`:d.style.width=`${e.clientWidth}px`,o.append(d)};c("row",t,r+P(t,h=>i("row",h)),e.clientHeight),c("column",s,n+P(s,h=>i("column",h)),e.clientWidth)}function Be(o){const e=document.activeElement;o.table.querySelectorAll("td[data-key]").forEach(t=>{const s=t.dataset.key;if(s&&t!==e&&s!==o.editingKey){const n=t.querySelector(".colwork-table__cell-value");n?n.textContent=o.formatting.displayValue(s):t.textContent=o.formatting.displayValue(s)}})}function ge(o){if(o.viewport.querySelectorAll(".colwork-table__selection").forEach(t=>t.remove()),!o.selection.focus)return;const e=o.selection.getSelectionBounds();o.table.querySelectorAll("th[data-selection-axis]").forEach(t=>{const s=t.dataset.selectionAxis,n=Number(t.dataset.selectionIndex),r=o.selection.mode==="all"||o.selection.mode===s&&(s==="row"?n>=e.top&&n<=e.bottom:n>=e.left&&n<=e.right);t.classList.toggle("is-selected-header",r)}),ue(o.table,_({row:e.top,column:e.left},{row:e.bottom,column:e.right}),"colwork-table__selection",o.userColor??"#3b82f6",(t,s)=>t==="row"?o.size("row",s):o.size("column",s))}function pe(o){o.table&&(o.table.querySelectorAll("td[data-key]").forEach(e=>{e.querySelectorAll(".colwork-table__remote-cursor").forEach(t=>t.remove())}),o.viewport.querySelectorAll(".colwork-table__remote-selection").forEach(e=>e.remove()),o.awareness.getStates().forEach((e,t)=>{var n;if(t===o.awareness.clientID)return;const s=e.selection;if(s!=null&&s.anchor&&s.focus){const r=He(s,o.rowCount,o.columnCount);r&&ue(o.table,r,"colwork-table__remote-selection",((n=e.user)==null?void 0:n.color)??"#94a3b8",(m,a)=>m==="row"?o.size("row",a):o.size("column",a));const i=Math.min(s.anchor.row,s.focus.row),c=Math.min(s.anchor.column,s.focus.column),h=o.table.querySelector(`td[data-key="${i}:${c}"]`);h&&me(h,e,t)}else{const r=e.cursor,i=r&&o.table.querySelector(`td[data-key="${r.row}:${r.column}"]`);i&&me(i,e,t)}}))}function Pe(o){o.table.querySelectorAll("td[data-key]").forEach(e=>{if(e.dataset.key){o.formatting.applyStyle(e,e.dataset.key);const t=e.querySelector(".colwork-table__cell-value");t&&(o.formatting.applyStyle(t,e.dataset.key),t.textContent=o.formatting.displayValue(e.dataset.key))}}),ge(o),pe(o)}class Fe{constructor(e){u(this,"selecting",!1);u(this,"headerSelecting");u(this,"pendingCellContext");u(this,"rightButtonReleased",!1);u(this,"rightMouseUpPoint");u(this,"rightDrag");this.host=e}cancel(){this.selecting=!1,this.headerSelecting=void 0,this.pendingCellContext=void 0,this.rightDrag=void 0}release(e){this.selecting=!1,this.headerSelecting=void 0,e.button===2&&(this.rightButtonReleased=!0,this.rightMouseUpPoint={x:e.clientX,y:e.clientY},this.pendingCellContext&&(this.pendingCellContext=void 0,this.showCellContextMenu(e.clientX,e.clientY))),this.host.selection.pendingCursor&&this.host.selection.sendAwareness(this.host.selection.pendingCursor)}blur(){this.headerSelecting&&(this.selecting=!1,this.headerSelecting=void 0,this.host.selection.pendingCursor&&this.host.selection.sendAwareness(this.host.selection.pendingCursor))}protectionActions(){return[["锁定选区",()=>this.host.dialogs.requestSelectionLock(!0)],["密码锁定选区",()=>this.host.dialogs.requestSelectionLock(!0,!0)],["解锁选区",()=>this.host.dialogs.requestSelectionLock(!1)]]}hasHeaderSelection(e,t){const s=_(this.host.selection.anchor,this.host.selection.focus);return this.host.selection.mode===e&&(e==="row"?t>=s.start.row&&t<=s.end.row:t>=s.start.column&&t<=s.end.column)}openRowContextMenu(e,t){if(!this.host.canEdit())return;e.preventDefault(),e.stopPropagation(),this.hasHeaderSelection("row",t)||this.host.selection.selectHeaderRange("row",t,!1);const s=_(this.host.selection.anchor,this.host.selection.focus),n=s.end.row-s.start.row+1;this.host.menu.show(e.clientX,e.clientY,[{label:"行操作",actions:[[`在上方插入 ${n} 行`,()=>this.host.modifyAxis("row",s.start.row,n)],[`在下方插入 ${n} 行`,()=>this.host.modifyAxis("row",s.end.row+1,n)],[`删除 ${n} 行`,()=>this.host.deleteRows()]]},{label:"固定",actions:[["固定至此行",()=>this.host.freezeSelection("row")],["取消固定",()=>this.host.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}openColumnContextMenu(e,t){if(!this.host.canEdit())return;e.preventDefault(),e.stopPropagation(),this.hasHeaderSelection("column",t)||this.host.selection.selectHeaderRange("column",t,!1);const s=_(this.host.selection.anchor,this.host.selection.focus),n=s.end.column-s.start.column+1;this.host.menu.show(e.clientX,e.clientY,[{label:"列操作",actions:[[`在左侧插入 ${n} 列`,()=>this.host.modifyAxis("column",s.start.column,n)],[`在右侧插入 ${n} 列`,()=>this.host.modifyAxis("column",s.end.column+1,n)],[`删除 ${n} 列`,()=>this.host.deleteColumns()]]},{label:"固定",actions:[["固定至此列",()=>this.host.freezeSelection("column")],["取消固定",()=>this.host.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}addHeaderSelection(e,t,s){e.dataset.selectionAxis=t,e.dataset.selectionIndex=String(s),e.addEventListener("mousedown",n=>{n.button===0&&(n.preventDefault(),n.stopPropagation(),this.host.editing.finish(!0),this.host.viewport.focus({preventScroll:!0}),this.host.menu.hide(),this.host.selection.selectHeaderRange(t,s,n.shiftKey),this.headerSelecting={axis:t,anchor:this.host.selection.anchor[t]},this.selecting=!0)}),e.addEventListener("mouseenter",n=>{if(!(!this.selecting||!this.headerSelecting||this.headerSelecting.axis!==t)){if(!(n.buttons&1)){this.blur();return}this.host.selection.selectHeaderSpan(t,this.headerSelecting.anchor,s)}}),e.addEventListener("contextmenu",n=>t==="row"?this.openRowContextMenu(n,s):this.openColumnContextMenu(n,s))}showCellContextMenu(e,t){this.host.canEdit()&&this.host.menu.show(e,t,[{label:"编辑",actions:[["复制",()=>this.host.clipboard.copySelection()],["清空内容",()=>this.host.clearSelectionContents()]]},{label:"单元格",actions:[["合并单元格",()=>this.host.mergeSelection()],["取消合并单元格",()=>this.host.unmergeSelection()]]},{label:"固定",actions:[["固定至选中行",()=>this.host.freezeSelection("row")],["固定至选中列",()=>this.host.freezeSelection("column")],["取消固定",()=>this.host.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}openCellContextMenu(e){if(this.host.canEdit()&&(e.preventDefault(),e.stopPropagation(),this.pendingCellContext={x:e.clientX,y:e.clientY},this.rightButtonReleased)){this.pendingCellContext=void 0;const t=this.rightMouseUpPoint??{x:e.clientX,y:e.clientY};this.showCellContextMenu(t.x,t.y)}}attachCellListeners(e,t,s,n){e.addEventListener("mousedown",r=>{r.target instanceof HTMLTextAreaElement||r.button!==0&&r.button!==2||(r.button===2?(this.rightButtonReleased=!1,this.rightDrag={start:{row:s,column:n},moved:!1}):this.rightDrag=void 0,r.preventDefault(),this.host.viewport.focus({preventScroll:!0}),this.selecting=!0,(r.button===0||!this.host.selection.isPositionSelected({row:s,column:n}))&&this.host.selection.selectCell(s,n,r.shiftKey),this.host.refreshSelection())}),e.addEventListener("mouseenter",()=>{if(!(!this.selecting||this.headerSelecting)){if(this.rightDrag){if(this.rightDrag.start.row===s&&this.rightDrag.start.column===n)return;this.rightDrag.moved||(this.rightDrag.moved=!0,this.host.selection.mode=void 0,this.host.selection.anchor=this.rightDrag.start,this.host.selection.selectedKey=H(this.rightDrag.start))}this.host.selection.selectCell(s,n,!0),this.host.refreshSelection()}}),this.host.canEdit()&&e.addEventListener("dblclick",()=>this.host.editing.start(e,t,!1)),e.addEventListener("contextmenu",r=>this.openCellContextMenu(r))}}class Te{constructor(e){u(this,"anchor");u(this,"focus");u(this,"mode");u(this,"selectedKey");u(this,"pendingCursor");this.host=e}selectRange(e,t,s){this.anchor=e,this.focus=t,this.mode=s,this.selectedKey=H(e),this.pendingCursor=t,this.host.refresh()}selectHeaderRange(e,t,s){var r,i;let n=t;s&&this.mode===e&&(n=e==="row"?((r=this.anchor)==null?void 0:r.row)??t:((i=this.anchor)==null?void 0:i.column)??t),this.selectHeaderSpan(e,n,t)}selectHeaderSpan(e,t,s){e==="row"?this.selectRange({row:t,column:0},{row:s,column:this.host.dimensions().columns-1},"row"):this.selectRange({row:0,column:t},{row:this.host.dimensions().rows-1,column:s},"column")}publishSelection(){this.updateAwareness()}updateAwareness(e={}){this.host.session.publish({...e,selection:{anchor:this.anchor,focus:this.focus,mode:this.mode}})}getSelectionBounds(){const e=this.anchor??this.focus??{row:0,column:0},t=this.focus??e,s=_(e,t);return{top:s.start.row,bottom:s.end.row,left:s.start.column,right:s.end.column}}selectCell(e,t,s=!1){const n={row:e,column:t};this.mode=void 0,(!s||!this.anchor)&&(this.anchor=n);const r=this.host.sheet.expandSelectionToMerges(this.anchor,n);this.anchor=r.anchor,this.focus=r.focus,this.selectedKey=`${e}:${t}`,this.pendingCursor=n}isPositionSelected(e){return F(_(this.anchor,this.focus),e)}sendAwareness(e){this.pendingCursor=void 0,this.updateAwareness({cursor:e,editing:this.host.editingKey()??null})}}function we(o){for(const e of o){const t=e.codePointAt(0);if(t>=55296&&t<=57343)return!1}return!0}function ye(o){return Array.from(o,e=>{const t=e.codePointAt(0);return t>=55296&&t<=57343?"�":e}).join("")}const Z=1,T=Object.freeze({cells:"cells",styles:"styles",rowHeights:"rowHeights",columnWidths:"columnWidths",merges:"merges",locks:"locks",metadata:"colwork-metadata"});function K(o){if(!/^(0|[1-9]\d*):(0|[1-9]\d*)$/.test(o))return;const[e,t]=o.split(":").map(Number);return Number.isSafeInteger(e)&&Number.isSafeInteger(t)?{row:e,column:t}:void 0}function qe(o){return`${o.start.row}:${o.start.column}-${o.end.row}:${o.end.column}`}function Q(o){const e=o.split("-");if(e.length!==2)return;const t=K(e[0]),s=K(e[1]);if(!(!t||!s||t.row>s.row||t.column>s.column))return{start:t,end:s}}function Ke(o){if(o.length<2)return!1;const e=[...new Set(o.flatMap(c=>[c.start.column,c.end.column+1]))].sort((c,h)=>c-h),t=new Map(e.map((c,h)=>[c,h])),s=o.flatMap(c=>[{row:c.start.row,left:t.get(c.start.column),right:t.get(c.end.column+1)-1,delta:1},{row:c.end.row+1,left:t.get(c.start.column),right:t.get(c.end.column+1)-1,delta:-1}]).sort((c,h)=>c.row-h.row||c.delta-h.delta),n=new Int32Array(e.length*4),r=new Int32Array(e.length*4),i=(c,h,m,a,l,d)=>{if(a<=h&&m<=l){n[c]+=d,r[c]+=d;return}const f=Math.floor((h+m)/2);a<=f&&i(c*2,h,f,a,l,d),l>f&&i(c*2+1,f+1,m,a,l,d),n[c]=r[c]+Math.max(n[c*2],n[c*2+1])};for(const c of s)if(i(1,0,e.length-2,c.left,c.right,c.delta),n[1]>1)return!0;return!1}const te=o=>!!o&&typeof o=="object"&&!Array.isArray(o)&&Object.getPrototypeOf(o)===Object.prototype,se=(o,e)=>Object.keys(o).every(t=>e.includes(t));function je(o){return te(o)&&se(o,["version","algorithm","iterations","salt","verifier"])&&o.version===1&&o.algorithm==="PBKDF2-SHA-256"&&o.iterations===6e5&&typeof o.salt=="string"&&/^[0-9a-f]{32}$/.test(o.salt)&&typeof o.verifier=="string"&&/^[0-9a-f]{64}$/.test(o.verifier)}function oe(o){if(!te(o)||!se(o,["bold","italic","underline","strike","wrap","border","fontSize","color","background","align","format"]))return!1;for(const e of["bold","italic","underline","strike","wrap"])if(e in o&&typeof o[e]!="boolean")return!1;for(const e of["color","background"])if(e in o&&(typeof o[e]!="string"||!we(o[e])))return!1;if("fontSize"in o&&(typeof o.fontSize!="number"||!Number.isFinite(o.fontSize)||o.fontSize<=0)||"align"in o&&(typeof o.align!="string"||!["left","center","right"].includes(o.align))||"format"in o&&(typeof o.format!="string"||!["general","number","date","percent"].includes(o.format)))return!1;if("border"in o){if(!te(o.border)||!se(o.border,["top","right","bottom","left"]))return!1;for(const e of Object.keys(o.border))if(typeof o.border[e]!="boolean")return!1}return!0}function J(o){return{cells:o.getMap(T.cells),styles:o.getMap(T.styles),rowHeights:o.getMap(T.rowHeights),columnWidths:o.getMap(T.columnWidths),merges:o.getMap(T.merges),locks:o.getMap(T.locks)}}function ne(o,e={}){for(const l of["maxRows","maxColumns","maxEntries","maxStringLength","maxMergeArea","maxMerges"]){const d=e[l];if(d!==void 0&&(!Number.isSafeInteger(d)||d<0))throw new RangeError(`${l} must be a non-negative safe integer`)}const t=[];(o.store.pendingStructs!==null||o.store.pendingDs!==null)&&t.push({path:"$",message:"Document contains unresolved Yjs update dependencies"});const s=(l,d)=>{t.push({path:l,message:d})};if(!e.allowUnknownRoots)for(const l of o.share.keys())Object.values(T).includes(l)||s(l,"Unknown document root");let n,r;try{n=J(o),r=o.getMap(T.metadata)}catch{return[...t,{path:"$",message:"Sheet roots must be Y.Map values"}]}for(const[l,d]of[...Object.entries(n),["metadata",r]])(!(d instanceof W.Map)||d._start!==null)&&s(l,"Expected map entries without sequence content");const i=Object.values(n).reduce((l,d)=>l+d.size,r.size);e.maxEntries!==void 0&&i>e.maxEntries&&s("$","Document exceeds maxEntries");const c=(l,d)=>l<Number.MAX_SAFE_INTEGER&&d<Number.MAX_SAFE_INTEGER&&(e.maxRows===void 0||l<e.maxRows)&&(e.maxColumns===void 0||d<e.maxColumns),h=(l,d)=>{if(typeof l!="string")return!1;try{return d(JSON.parse(l))}catch{return!1}},m=(l,d,f)=>{typeof f=="string"&&e.maxStringLength!==void 0&&f.length>e.maxStringLength&&s(`${l}.${d}`,"String exceeds maxStringLength")};for(const l of["cells","styles","locks"])n[l].forEach((d,f)=>{const S=K(f);(!S||!c(S.row,S.column))&&s(`${l}.${f}`,"Invalid or out-of-bounds row:column key"),m(l,f,d),l==="cells"&&(typeof d!="string"||!we(d))&&s(`${l}.${f}`,"Cell values must be strings"),l==="styles"&&!h(d,oe)&&s(`${l}.${f}`,"Expected a JSON CellStyle object"),l==="locks"&&d!=="1"&&!h(d,je)&&s(`${l}.${f}`,"Expected a plain lock or version-one password verifier")});for(const l of["rowHeights","columnWidths"])n[l].forEach((d,f)=>{const S=Number(f),M=l==="rowHeights"?e.maxRows:e.maxColumns;(!/^(0|[1-9]\d*)$/.test(f)||!Number.isSafeInteger(S)||S>=Number.MAX_SAFE_INTEGER||M!==void 0&&S>=M)&&s(`${l}.${f}`,"Invalid or out-of-bounds index"),(typeof d!="number"||!Number.isFinite(d)||d<=0)&&s(`${l}.${f}`,"Sizes must be finite positive numbers")});e.maxMerges!==void 0&&n.merges.size>e.maxMerges&&s("merges","Document exceeds maxMerges");const a=[];return n.merges.forEach((l,d)=>{const f=Q(d);!f||l!=="1"||!c(f.end.row,f.end.column)?s(`merges.${d}`,"Invalid or out-of-bounds merge range"):(e.maxMergeArea!==void 0&&f.end.row-f.start.row+1>e.maxMergeArea/(f.end.column-f.start.column+1)&&s(`merges.${d}`,"Merge exceeds maxMergeArea"),a.push(f))}),Ke(a)&&s("merges","Merge ranges must not overlap"),r.forEach((l,d)=>{d==="schemaVersion"?l!==Z&&s("metadata.schemaVersion","Unsupported schema version"):d==="initialized"?typeof l!="boolean"&&s("metadata.initialized","Expected a boolean"):s(`metadata.${d}`,"Unknown metadata field")}),t}const be="application/x-colwork-cells";function Ie(o){if(!o||typeof o!="object")return!1;const e=o;return Array.isArray(e.values)&&e.values.length>0&&e.values.every(t=>Array.isArray(t)&&t.every(s=>typeof s=="string"))&&Array.isArray(e.styles)&&e.styles.every(t=>Array.isArray(t)&&t.every(s=>s===null||oe(s)))}class Ve{constructor(e){u(this,"onCopy",e=>{if(e.target instanceof HTMLTextAreaElement)return;const t=this.payload();!t||!e.clipboardData||(e.clipboardData.setData("text/plain",t.values.map(s=>s.join(" ")).join(`
|
|
4
|
+
`)),e.clipboardData.setData(be,JSON.stringify(t)),e.preventDefault())});u(this,"onPaste",e=>{var a,l,d;if(e.target instanceof HTMLTextAreaElement)return;e.preventDefault(),e.stopPropagation();const{selection:t,sheet:s,editing:n}=this.host;if(!this.host.canEdit()||!t.focus)return;const r=(l=(a=e.clipboardData)==null?void 0:a.getData("text/plain"))==null?void 0:l.replace(/^\uFEFF/,"");if(!r)return;n.finish(!1);let i=r.replace(/\r\n?/g,`
|
|
4
5
|
`).split(`
|
|
5
|
-
`).filter((m,f,p)=>!(f===p.length-1&&m==="")).map(m=>m.split(" ")),o;const r=(c=t.clipboardData)==null?void 0:c.getData(it);if(r)try{const m=JSON.parse(r);Array.isArray(m.values)&&Array.isArray(m.styles)&&(s=m.values,o=m.styles)}catch{o=void 0}const n=this.selectionFocus,i=Math.max(...s.map(m=>m.length));s.some((m,f)=>m.some((p,M)=>this.isCellLocked(W({row:n.row+f,column:n.column+M}))))||(this.doc.transact(()=>s.forEach((m,f)=>m.forEach((p,M)=>{var U;const E=n.row+f,N=n.column+M;if(E>=this.rowCount||N>=this.columnCount)return;const H=W({row:E,column:N});if(this.cells.set(H,p),o){const B=(U=o[f])==null?void 0:U[M];B?this.styles.set(H,JSON.stringify(B)):this.styles.delete(H)}}))),this.selectionAnchor=n,this.selectionFocus={row:Math.min(this.rowCount-1,n.row+s.length-1),column:Math.min(this.columnCount-1,n.column+i-1)},this.render())});var _,ct,ht,ut;this.root=t,this.options=e,this.readOnly=e.readOnly===!0,this.doc=new V.Doc,this.cells=this.doc.getMap("cells"),this.styles=this.doc.getMap("styles"),this.rowHeights=this.doc.getMap("rowHeights"),this.columnWidths=this.doc.getMap("columnWidths"),this.merges=this.doc.getMap("merges"),this.locks=this.doc.getMap("locks"),this.rowCountValue=Math.max(e.rowCount??100,((_=e.rows)==null?void 0:_.length)??Q.length),this.columnCountValue=Math.max(e.columnCount??10,xt.length);const s=e.transport==="webrtc",o=new URL(e.websocketUrl??"ws://127.0.0.1:1234"),r=Object.fromEntries(o.searchParams);o.search="",this.readOnly?this.awareness=new J.Awareness(this.doc):(this.provider=s?new dt.WebrtcProvider(e.room,this.doc,{signaling:[e.signalingUrl??"ws://127.0.0.1:4444"],filterBcConns:!1,peerOpts:e.peerOpts??{config:{iceServers:At}}}):new tt.WebsocketProvider(o.toString().replace(/\/$/,""),encodeURIComponent(e.room),this.doc,{params:r,connect:!e.initializeAfterSync}),this.awareness=this.provider.awareness),e.snapshot&&V.applyUpdate(this.doc,e.snapshot),(ct=e.updates)==null||ct.forEach(g=>V.applyUpdate(this.doc,g)),this.log(`room:${e.room}`),this.doc.on("update",this.onDocUpdate),this.awareness.on("update",this.onAwarenessUpdate),this.awareness.on("change",this.onAwarenessChange),this.awareness.setLocalStateField("user",{name:e.user,color:e.userColor}),s&&this.provider&&this.inspectConnections();const n=document.createElement("section");n.className="colwork-table";const i=document.createElement("div");i.className="colwork-table__toolbar",this.readOnly&&(i.hidden=!0),i.setAttribute("aria-label","表格工具栏");const l=document.createElement("div");l.className="colwork-table__toolbar-row";const u=document.createElement("div");u.className="colwork-table__toolbar-row",i.append(l,u);const c=(g,S)=>{const w=document.createElement("div");w.className="colwork-table__toolbar-group",w.setAttribute("role","group"),w.setAttribute("aria-label",S);const k=document.createElement("span");return k.className="colwork-table__group-label",k.textContent=S,w.append(k),g.append(w),w},m=c(l,"历史"),f=c(l,"单元格"),p=c(l,"保护"),M=c(l,"显示"),E=c(u,"文字"),N=c(u,"对齐"),H=c(u,"格式");[["撤销","↶",()=>this.undo()],["重做","↷",()=>this.redo()]].forEach(([g,S,w],k)=>{const R=document.createElement("button");R.type="button",R.className=`colwork-table__history colwork-table__history--${k===0?"undo":"redo"}`,R.title=g,R.textContent=S,R.addEventListener("mousedown",Dt=>Dt.preventDefault()),R.addEventListener("click",w),k===0?this.undoButton=R:this.redoButton=R,m.append(R)}),[["合并单元格","合并",()=>this.mergeSelection()],["拆分单元格","拆分",()=>this.unmergeSelection()]].forEach(([g,S,w])=>{const k=document.createElement("button");k.type="button",k.className="colwork-table__format colwork-table__grid-action",k.title=g,k.textContent=S,k.addEventListener("mousedown",R=>R.preventDefault()),k.addEventListener("click",w),f.append(k)}),(ht=p.querySelector(".colwork-table__group-label"))==null||ht.remove();const z=document.createElement("button");this.protectionMenuButton=z,z.type="button",z.className="colwork-table__format colwork-table__dropdown-trigger",z.textContent="保护",z.title="锁定、密码锁定与解锁",z.setAttribute("aria-label","保护"),z.setAttribute("aria-expanded","false"),z.addEventListener("mousedown",g=>g.preventDefault()),z.addEventListener("click",()=>{if(z.getAttribute("aria-expanded")==="true"){this.hideContextMenu();return}const g=z.getBoundingClientRect();this.showContextMenu(g.left,g.bottom+4,[{label:"锁定与解锁",actions:this.protectionActions()}]),z.setAttribute("aria-expanded","true")}),z.addEventListener("keydown",g=>{g.key==="ArrowDown"&&(g.preventDefault(),z.click())}),p.append(z);const I=document.createElement("div");I.className="colwork-table__view-control";const O=document.createElement("button");O.type="button",O.className="colwork-table__format",O.textContent="视图",O.setAttribute("aria-label","视图"),O.classList.add("colwork-table__dropdown-trigger"),O.title="本地视图选项";const j=document.createElement("div");j.className="colwork-table__view-menu",[["隔行异色",()=>this.bandedRows,g=>{this.bandedRows=g}],["显示网格线",()=>this.showGridLines,g=>{this.showGridLines=g}]].forEach(([g,S,w])=>{const k=document.createElement("label"),R=document.createElement("input");R.type="checkbox",R.checked=S(),R.addEventListener("change",()=>{w(R.checked),this.render()}),k.append(R,document.createTextNode(g)),j.append(k)}),[["固定至选中行",()=>this.freezeSelection("row")],["固定至选中列",()=>this.freezeSelection("column")],["取消固定",()=>this.setFrozenPanes(0,0)]].forEach(([g,S])=>{const w=document.createElement("button");w.type="button",w.textContent=g,w.addEventListener("mousedown",k=>k.preventDefault()),w.addEventListener("click",S),j.append(w)}),I.append(O,j),M.append(I),[["bold","B","加粗"],["italic","I","斜体"],["underline","U","下划线"],["strike","S","删除线"],["wrap","换行","自动换行"],["align-left","左","左对齐"],["align-center","中","居中"],["align-right","右","右对齐"]].forEach(([g,S,w])=>{const k=document.createElement("button");k.type="button",k.className=`colwork-table__format colwork-table__format--${g}`,k.textContent=S,k.title=w,k.addEventListener("mousedown",R=>R.preventDefault()),k.addEventListener("click",()=>g.startsWith("align-")?this.setStyle("align",g.slice(6)):this.toggleFormat(g)),(g.startsWith("align-")||g==="wrap"?N:E).append(k)});const b=document.createElement("select");b.className="colwork-table__select",b.title="字体大小",[10,12,14,16,18,24].forEach(g=>{const S=document.createElement("option");S.value=String(g),S.textContent=`${g}px`,b.append(S)}),b.addEventListener("change",()=>this.setStyle("fontSize",Number(b.value))),E.append(b);const L=document.createElement("select");L.className="colwork-table__select",L.title="单元格格式",[["general","常规"],["number","数字"],["date","日期"],["percent","百分比"]].forEach(([g,S])=>{const w=document.createElement("option");w.value=g,w.textContent=S,L.append(w)}),L.addEventListener("change",()=>this.setStyle("format",L.value)),H.append(L);const C=document.createElement("button");C.type="button",C.className="colwork-table__format",C.title="清除格式",C.textContent="清除",C.addEventListener("mousedown",g=>g.preventDefault()),C.addEventListener("click",()=>this.clearFormatting()),H.append(C);const F=document.createElement("div");F.className="colwork-table__border-control";const v=document.createElement("button");v.type="button",v.className="colwork-table__format",v.title="边框选项",v.textContent="边框",v.setAttribute("aria-label","边框"),v.classList.add("colwork-table__dropdown-trigger");const A=document.createElement("div");A.className="colwork-table__border-menu",[["外围","outer"],["中间","inner"],["横线","horizontal"],["竖线","vertical"]].forEach(([g,S])=>{const w=document.createElement("button");w.type="button",w.textContent=g,w.addEventListener("click",()=>this.toggleBorder(S)),A.append(w)}),F.append(v,A),H.insertBefore(F,C),[["color","文字颜色"],["background","背景颜色"]].forEach(([g,S])=>{const w=document.createElement("input");w.type="color",w.className=`colwork-table__color colwork-table__color--${g}`,w.title=S,w.addEventListener("input",()=>this.setStyle(g,w.value)),(g==="color"?E:H).append(w)}),this.viewport=document.createElement("div"),this.viewport.className="colwork-table__viewport",this.viewport.addEventListener("scroll",this.onViewportScroll),this.viewport.addEventListener("wheel",this.onViewportWheel,{passive:!1}),this.viewport.tabIndex=0,this.viewport.addEventListener("keydown",this.onViewportKeyDown),this.viewport.addEventListener("copy",this.onCopy,!0),this.viewport.addEventListener("paste",this.onPaste,!0),window.addEventListener("mouseup",this.onWindowMouseUp),window.addEventListener("mousemove",this.onWindowMouseMove),window.addEventListener("blur",this.onWindowBlur),document.addEventListener("mousedown",this.onDocumentMouseDown),this.table=document.createElement("table"),this.table.addEventListener("mousedown",this.onTableMouseDown),this.viewport.append(this.table),this.frozenBoundaryLayer=document.createElement("div"),this.frozenBoundaryLayer.className="colwork-table__frozen-boundaries",this.frozenBoundaryLayer.setAttribute("aria-hidden","true"),n.append(i,this.viewport,this.frozenBoundaryLayer),t.replaceChildren(n);const D=!this.readOnly&&!e.snapshot&&!((ut=e.updates)!=null&&ut.length),K=D&&this.cells.size===0&&this.locks.size===0;if(D&&!e.initializeAfterSync&&this.seed(e.rows??Q),K&&!e.initializeAfterSync&&this.seedDemoFormatting(),this.expandLogicalSizeFromDocument(),this.undoManager=new V.UndoManager([this.cells,this.styles,this.rowHeights,this.columnWidths,this.merges],{captureTimeout:500}),this.undoManager.on("stack-item-added",this.onHistoryChange),this.undoManager.on("stack-item-popped",this.onHistoryChange),this.undoManager.on("stack-cleared",this.onHistoryChange),this.render(),this.refreshHistoryButtons(),this.cells.observe(this.onCellsChange),this.styles.observe(this.onStylesChange),this.rowHeights.observe(this.onSizesChange),this.columnWidths.observe(this.onSizesChange),this.merges.observe(this.onMergesChange),this.locks.observe(this.onLocksChange),this.viewportResizeObserver=new ResizeObserver(()=>this.refreshFrozenBoundaries()),this.viewportResizeObserver.observe(this.viewport),this.provider){const g=this.provider;g.on("status",({connected:S,status:w})=>{this.log(S===!0||w==="connected"?"signaling:connected":"signaling:disconnected"),s&&this.inspectConnections()}),s?g.on("synced",({synced:S})=>this.log(S?"synced":"syncing")):g.on("sync",S=>{if(this.log(S?"synced":"syncing"),!S||!e.initializeAfterSync)return;const w=this.doc.getMap("colwork-metadata");w.get("initialized")||(this.doc.transact(()=>{D&&this.cells.size===0&&this.locks.size===0&&(this.seed(e.rows??Q),this.seedDemoFormatting()),w.set("initialized",!0)}),this.undoManager.clear()),this.expandLogicalSizeFromDocument(),this.render()}),e.initializeAfterSync&&this.provider instanceof tt.WebsocketProvider&&this.provider.connect(),s&&g.on("peers",({added:S,removed:w,webrtcPeers:k})=>{S.length&&this.log(`peer:+${S.length}`),w.length&&this.log(`peer:-${w.length}`),this.log(`webrtc:${k.length}`),this.inspectConnections()})}}log(t){var e,s;(s=(e=this.options).onLog)==null||s.call(e,`${new Date().toLocaleTimeString()} ${t}`)}undo(){this.readOnly||!this.undoManager.canUndo()||(this.editor&&this.finishEdit(!0),this.undoManager.undo())}redo(){this.readOnly||!this.undoManager.canRedo()||(this.editor&&this.finishEdit(!0),this.undoManager.redo())}refreshHistoryButtons(){this.undoButton&&(this.undoButton.disabled=this.readOnly||!this.undoManager.canUndo()),this.redoButton&&(this.redoButton.disabled=this.readOnly||!this.undoManager.canRedo())}getYjsSnapshot(){return{format:"colwork.snapshot",version:1,room:this.options.room,sequence:this.updateSequence,snapshot:Y(V.encodeStateAsUpdate(this.doc)),stateVector:Y(V.encodeStateVector(this.doc))}}getYjsUpdateLog(){return{format:"colwork.update-log",version:1,room:this.options.room,updates:this.updateLog.map(t=>({...t}))}}setFrozenPanes(t,e){if(![t,e].every(r=>Number.isInteger(r)&&r>=0))throw new RangeError("Frozen row and column counts must be non-negative integers");const s=Math.min(t,this.rowCount-1),o=Math.min(e,this.columnCount-1);return this.hasPartialMerge("row",0,s-1)||this.hasPartialMerge("column",0,o-1)?(this.showLockMessage("当前选择包含不完整的合并块,无法固定,请选择完整的合并块"),!1):(this.finishEdit(!0),this.frozenRows=s,this.frozenColumns=o,this.closeLockMessage(),this.render(),!0)}hasPartialMerge(t,e,s){return e>s?!1:this.getMergeRanges().some(o=>{const r=o.start[t],n=o.end[t];return r<=s&&n>=e&&(r<e||n>s)})}crossesFrozenBoundary(t){return t.start.row<this.frozenRows&&t.end.row>=this.frozenRows||t.start.column<this.frozenColumns&&t.end.column>=this.frozenColumns}freezeSelection(t){if(!this.selectionFocus)return;const e=$(this.selectionAnchor,this.selectionFocus);if(this.hasPartialMerge(t,e.start[t],e.end[t])){this.showLockMessage("当前选择包含不完整的合并块,无法固定,请选择完整的合并块");return}this.setFrozenPanes(t==="row"?e.end.row+1:this.frozenRows,t==="column"?e.end.column+1:this.frozenColumns)}rangeHasLocks(t){return Array.from(this.locks.keys()).some(e=>{const[s,o]=e.split(":").map(Number);return T(t,{row:s,column:o})})}isCellLocked(t){if(this.locks.has(t))return!0;const[e,s]=t.split(":").map(Number),o=this.getMergeRanges().find(r=>T(r,{row:e,column:s}));return!!o&&this.rangeHasLocks(o)}isCellPasswordLocked(t){const e=n=>this.locks.has(n)&&this.locks.get(n)!=="1";if(e(t))return!0;const[s,o]=t.split(":").map(Number),r=this.getMergeRanges().find(n=>T(n,{row:s,column:o}));return!!r&&Array.from(this.locks.keys()).some(n=>{const[i,l]=n.split(":").map(Number);return e(n)&&T(r,{row:i,column:l})})}selectionHasLocks(){return this.rangeHasLocks($(this.selectionAnchor,this.selectionFocus))}isAxisLocked(t,e,s=!1){return Array.from(this.locks.keys()).some(o=>{const r=Number(o.split(":")[t==="row"?0:1]);return s?r>=e:r===e})}async setSelectionLocked(t,e){if(this.readOnly||this.destroyed||!this.selectionFocus)return;this.finishEdit(!0);const s=this.expandSelectionToMerges(this.selectionAnchor??this.selectionFocus,this.selectionFocus),o=$(s.anchor,s.focus),r=[];for(let u=o.start.row;u<=o.end.row;u+=1)for(let c=o.start.column;c<=o.end.column;c+=1)r.push(W({row:u,column:c}));const n=[...new Set(r.map(u=>this.locks.get(u)).filter(u=>u!==void 0&&u!=="1"))];if(t&&n.length)throw new Error("选区包含密码锁定单元格,请先用原密码解锁");const i=this.documentRevision;let l="1";if(t&&e!==void 0&&(l=await ft(e)),!t&&n.length){if(!e)throw new Error("请输入解锁密码");for(const u of n)if(!await gt(u,e))throw new Error("密码不正确,选区未解锁")}if(!this.destroyed){if(i!==this.documentRevision)throw new Error("表格内容或锁定状态已变化,请重试");this.doc.transact(()=>{r.forEach(u=>{t?this.locks.set(u,l):this.locks.delete(u)})})}}requestSelectionLock(t,e=!1){if(this.readOnly||this.destroyed||!this.selectionFocus||this.passwordDialog)return;this.closeLockMessage();const s=$(this.selectionAnchor,this.selectionFocus);if(!(e||!t&&Array.from(this.locks.entries()).some(([E,N])=>{const[H,U]=E.split(":").map(Number);return N!=="1"&&T(s,{row:H,column:U})}))){this.setSelectionLocked(t).catch(E=>this.showLockMessage(E instanceof Error?E.message:"操作失败"));return}const r=document.createElement("dialog");this.passwordDialog=r,r.className="colwork-table__password-dialog",r.setAttribute("aria-label",t?"密码锁定":"密码解锁");const n=document.createElement("form"),i=document.createElement("h3");i.textContent=t?"设置锁定密码":"输入解锁密码";const l=document.createElement("input");l.type="password",l.required=!0,l.placeholder=t?"设置密码":"输入密码",l.autocomplete=t?"new-password":"current-password",l.setAttribute("aria-label","密码");const u=document.createElement("input");u.type="password",u.required=t,u.placeholder="再次输入密码",u.autocomplete="new-password",u.setAttribute("aria-label","确认密码");const c=document.createElement("p");c.setAttribute("role","alert");const m=document.createElement("button");m.type="submit",m.textContent=t?"确认锁定":"确认解锁";const f=document.createElement("button");f.type="button",f.textContent="取消",f.addEventListener("click",()=>r.close()),r.addEventListener("close",()=>{l.value="",u.value="",r.remove(),this.passwordDialog===r&&(this.passwordDialog=void 0)});const p=this.selectionAnchor&&{...this.selectionAnchor},M={...this.selectionFocus};n.addEventListener("submit",async E=>{if(E.preventDefault(),!m.disabled){if(t&&l.value!==u.value){c.textContent="两次输入的密码不一致";return}m.disabled=!0,f.disabled=!0,r.oncancel=N=>N.preventDefault(),c.textContent="正在处理…";try{this.selectionAnchor=p,this.selectionFocus=M,await this.setSelectionLocked(t,l.value),r.close()}catch(N){c.textContent=N instanceof Error?N.message:"操作失败,请重试",l.value="",u.value="",l.focus()}finally{m.disabled=!1,f.disabled=!1,r.oncancel=null}}}),n.append(i,l),t&&n.append(u),n.append(c,m,f),r.append(n),this.root.append(r),r.showModal(),l.focus()}closeLockMessage(){const t=this.messageDialog;this.messageDialog=void 0,t==null||t.close(),t==null||t.remove()}showLockMessage(t){if(this.destroyed)return;this.closeLockMessage(),this.hideContextMenu();const e=document.createElement("dialog");this.messageDialog=e,e.className="colwork-table__message-dialog",e.setAttribute("role","alertdialog"),e.setAttribute("aria-label","操作提示"),e.setAttribute("aria-description",t);const s=document.createElement("h3");s.textContent="操作提示";const o=document.createElement("p");o.className="colwork-table__lock-status",o.setAttribute("role","status"),o.textContent=t;const r=document.createElement("button");r.type="button",r.textContent="确定",r.addEventListener("click",()=>e.close()),e.addEventListener("close",()=>{e.remove(),this.messageDialog===e&&(this.messageDialog=void 0)}),e.append(s,o,r),this.root.append(e),e.showModal(),r.focus()}get rowCount(){return this.rowCountValue}get columnCount(){return this.columnCountValue}get rowHeaderWidth(){return bt*this.zoomRatio}get columnHeaderHeight(){return St*this.zoomRatio}getRowHeight(t){var e;return((e=this.resizing)==null?void 0:e.axis)==="row"&&this.resizing.index===t?this.resizing.currentSize:(this.rowHeights.get(String(t))??Ct)*this.zoomRatio}getColumnWidth(t){var e;return((e=this.resizing)==null?void 0:e.axis)==="column"&&this.resizing.index===t?this.resizing.currentSize:(this.columnWidths.get(String(t))??vt)*this.zoomRatio}beginResize(t,e,s){s.preventDefault(),s.stopPropagation(),!(s.button!==0||this.readOnly||this.isAxisLocked(t,e))&&(this.finishEdit(!0),this.selecting=!1,this.headerSelecting=void 0,this.resizing={axis:t,index:e,start:t==="row"?s.clientY:s.clientX,size:t==="row"?this.getRowHeight(e):this.getColumnWidth(e),currentSize:t==="row"?this.getRowHeight(e):this.getColumnWidth(e)},this.viewport.classList.add("is-resizing"))}addResizeHandle(t,e,s){const o=document.createElement("span");o.className=`colwork-table__resize-handle colwork-table__resize-handle--${e}`,o.addEventListener("mousedown",r=>this.beginResize(e,s,r)),t.append(o)}selectRange(t,e,s){this.selectionAnchor=t,this.selectionFocus=e,this.selectionMode=s,this.selectedKey=W(t),this.pendingAwarenessCursor=e,this.refreshSelection()}hideContextMenu(){var t,e;(t=this.protectionMenuButton)==null||t.setAttribute("aria-expanded","false"),(e=this.contextMenu)==null||e.remove(),this.contextMenu=void 0}showContextMenu(t,e,s){var n;this.hideContextMenu();const o=document.createElement("div");o.className="colwork-table__context-menu",o.setAttribute("aria-label","表格操作"),s.forEach(({label:i,actions:l})=>{const u=document.createElement("div");u.className="colwork-table__context-group",u.setAttribute("role","group"),u.setAttribute("aria-label",i);const c=document.createElement("div");c.className="colwork-table__context-label",c.textContent=i,u.append(c),l.forEach(([m,f])=>{const p=document.createElement("button");p.type="button",p.textContent=m,(m.startsWith("删除")||m==="清空内容")&&(p.className="is-destructive"),p.addEventListener("click",()=>{this.hideContextMenu(),f()}),u.append(p)}),o.append(u)}),o.addEventListener("keydown",i=>{var m;if(i.key==="Escape"){i.preventDefault(),this.hideContextMenu(),this.viewport.focus({preventScroll:!0});return}const l=Array.from(o.querySelectorAll("button")),u=l.indexOf(document.activeElement);let c;if(i.key==="ArrowDown")c=(u+1)%l.length;else if(i.key==="ArrowUp")c=(u-1+l.length)%l.length;else if(i.key==="Home")c=0;else if(i.key==="End")c=l.length-1;else return;i.preventDefault(),(m=l[c])==null||m.focus()}),o.style.left=`${t}px`,o.style.top=`${e}px`,document.body.append(o);const r=o.getBoundingClientRect();o.style.left=`${Math.max(8,Math.min(t,window.innerWidth-r.width-8))}px`,o.style.top=`${Math.max(8,Math.min(e,window.innerHeight-r.height-8))}px`,this.contextMenu=o,(n=o.querySelector("button"))==null||n.focus({preventScroll:!0})}protectionActions(){return[["锁定选区",()=>this.requestSelectionLock(!0)],["密码锁定选区",()=>this.requestSelectionLock(!0,!0)],["解锁选区",()=>this.requestSelectionLock(!1)]]}hasHeaderSelection(t,e){const s=$(this.selectionAnchor,this.selectionFocus);return this.selectionMode===t&&(t==="row"?e>=s.start.row&&e<=s.end.row:e>=s.start.column&&e<=s.end.column)}openRowContextMenu(t,e){if(this.readOnly)return;t.preventDefault(),t.stopPropagation(),this.hasHeaderSelection("row",e)||this.selectHeaderRange("row",e,!1);const s=$(this.selectionAnchor,this.selectionFocus),o=s.end.row-s.start.row+1;this.showContextMenu(t.clientX,t.clientY,[{label:"行操作",actions:[[`在上方插入 ${o} 行`,()=>this.modifyAxis("row",s.start.row,o)],[`在下方插入 ${o} 行`,()=>this.modifyAxis("row",s.end.row+1,o)],[`删除 ${o} 行`,()=>this.deleteRows()]]},{label:"固定",actions:[["固定至此行",()=>this.freezeSelection("row")],["取消固定",()=>this.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}openColumnContextMenu(t,e){if(this.readOnly)return;t.preventDefault(),t.stopPropagation(),this.hasHeaderSelection("column",e)||this.selectHeaderRange("column",e,!1);const s=$(this.selectionAnchor,this.selectionFocus),o=s.end.column-s.start.column+1;this.showContextMenu(t.clientX,t.clientY,[{label:"列操作",actions:[[`在左侧插入 ${o} 列`,()=>this.modifyAxis("column",s.start.column,o)],[`在右侧插入 ${o} 列`,()=>this.modifyAxis("column",s.end.column+1,o)],[`删除 ${o} 列`,()=>this.deleteColumns()]]},{label:"固定",actions:[["固定至此列",()=>this.freezeSelection("column")],["取消固定",()=>this.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}mergeKey(t){return`${t.start.row}:${t.start.column}-${t.end.row}:${t.end.column}`}parseMergeKey(t){const e=t.match(/^(\d+):(\d+)-(\d+):(\d+)$/);if(e)return{start:{row:Number(e[1]),column:Number(e[2])},end:{row:Number(e[3]),column:Number(e[4])}}}getMergeRanges(){return Array.from(this.merges.keys()).flatMap(t=>{const e=this.parseMergeKey(t);return e?[e]:[]})}expandSelectionToMerges(t,e){let s=$(t,e);for(const n of this.getMergeRanges())n.start.row<=s.end.row&&n.end.row>=s.start.row&&n.start.column<=s.end.column&&n.end.column>=s.start.column&&(s={start:{row:Math.min(s.start.row,n.start.row),column:Math.min(s.start.column,n.start.column)},end:{row:Math.max(s.end.row,n.end.row),column:Math.max(s.end.column,n.end.column)}});const o=e.row>=t.row,r=e.column>=t.column;return{anchor:{row:o?s.start.row:s.end.row,column:r?s.start.column:s.end.column},focus:{row:o?s.end.row:s.start.row,column:r?s.end.column:s.start.column}}}getMergeStartingAt(t,e){return this.getMergeRanges().find(s=>s.start.row===t&&s.start.column===e)}isMergeCovered(t,e){return this.getMergeRanges().some(s=>T(s,{row:t,column:e})&&(s.start.row!==t||s.start.column!==e))}mergeSelection(){if(this.readOnly||this.selectionHasLocks())return;const t=$(this.selectionAnchor,this.selectionFocus);if(!(t.start.row===t.end.row&&t.start.column===t.end.column)){if(this.crossesFrozenBoundary(t)){this.showLockMessage("合并范围同时包含固定和非固定区域,无法合并,请调整选区或取消固定");return}this.closeLockMessage(),this.doc.transact(()=>{this.getMergeRanges().forEach(e=>{(T(t,e.start)||T(e,t.start))&&this.merges.delete(this.mergeKey(e))}),this.merges.set(this.mergeKey(t),"1")})}}unmergeSelection(){if(this.readOnly||this.selectionHasLocks())return;const t=$(this.selectionAnchor,this.selectionFocus);this.doc.transact(()=>this.getMergeRanges().forEach(e=>{(T(t,e.start)||T(e,t.start))&&this.merges.delete(this.mergeKey(e))}))}modifyAxis(t,e,s,o=0){if(this.readOnly||s===0||this.isAxisLocked(t,e,!0))return;const r=[this.cells,this.styles];this.doc.transact(()=>{r.forEach(i=>{const l=Array.from(i.entries());i.clear(),l.forEach(([u,c])=>{const[m,f]=u.split(":").map(Number),p=t==="row"?m:f;if(o&&p>=e&&p<e+o)return;const M=p>=e+o?p+s:p,E=W(t==="row"?{row:M,column:f}:{row:m,column:M});i.set(E,c)})});const n=this.getMergeRanges();this.merges.clear(),n.forEach(i=>{const l=t==="row"?i.start.row:i.start.column,u=t==="row"?i.end.row:i.end.column;if(o&&l<e+o&&u>=e)return;const c=l>=e+o?s:0,m=t==="row"?{start:{row:i.start.row+c,column:i.start.column},end:{row:i.end.row+c,column:i.end.column}}:{start:{row:i.start.row,column:i.start.column+c},end:{row:i.end.row,column:i.end.column+c}};this.merges.set(this.mergeKey(m),"1")})}),t==="row"?this.rowCountValue=Math.max(1,this.rowCountValue+s):this.columnCountValue=Math.max(1,this.columnCountValue+s),this.render()}deleteRows(){const t=$(this.selectionAnchor,this.selectionFocus),e=Math.min(t.end.row-t.start.row+1,this.rowCount-1);this.modifyAxis("row",t.start.row,-e,e)}deleteColumns(){const t=$(this.selectionAnchor,this.selectionFocus),e=Math.min(t.end.column-t.start.column+1,this.columnCount-1);this.modifyAxis("column",t.start.column,-e,e)}selectHeaderRange(t,e,s){var r,n;let o=e;s&&this.selectionMode===t&&(o=t==="row"?((r=this.selectionAnchor)==null?void 0:r.row)??e:((n=this.selectionAnchor)==null?void 0:n.column)??e),this.selectHeaderSpan(t,o,e)}selectHeaderSpan(t,e,s){t==="row"?this.selectRange({row:e,column:0},{row:s,column:this.columnCount-1},"row"):this.selectRange({row:0,column:e},{row:this.rowCount-1,column:s},"column")}addHeaderSelection(t,e,s){t.dataset.selectionAxis=e,t.dataset.selectionIndex=String(s),t.addEventListener("mousedown",o=>{o.button===0&&(o.preventDefault(),o.stopPropagation(),this.finishEdit(!0),this.viewport.focus({preventScroll:!0}),this.hideContextMenu(),this.selectHeaderRange(e,s,o.shiftKey),this.headerSelecting={axis:e,anchor:this.selectionAnchor[e]},this.selecting=!0)}),t.addEventListener("mouseenter",o=>{if(!(!this.selecting||!this.headerSelecting||this.headerSelecting.axis!==e)){if(!(o.buttons&1)){this.onWindowBlur();return}this.selectHeaderSpan(e,this.headerSelecting.anchor,s)}}),t.addEventListener("contextmenu",o=>e==="row"?this.openRowContextMenu(o,s):this.openColumnContextMenu(o,s))}expandLogicalSpace(){const t=this.viewport.scrollTop+this.viewport.clientHeight>=this.viewport.scrollHeight-280,e=this.viewport.scrollLeft+this.viewport.clientWidth>=this.viewport.scrollWidth-280,s=t,o=e;if(t&&(this.rowCountValue+=100),e&&(this.columnCountValue+=5),this.selectionMode&&(s||o)){const r=this.selectionFocus??{row:0,column:0};this.selectionFocus=ot(this.selectionMode,r,this.rowCount,this.columnCount),this.publishSelection()}}publishSelection(){this.updateAwareness()}updateAwareness(t={}){const e=this.awareness.getLocalState()??{};this.awareness.setLocalState({...e,...t,selection:{anchor:this.selectionAnchor,focus:this.selectionFocus,mode:this.selectionMode}})}expandForRemoteSelections(){let t=this.rowCount,e=this.columnCount;this.awareness.getStates().forEach((o,r)=>{if(r===this.awareness.clientID)return;const n=o.selection;!(n!=null&&n.anchor)||!n.focus||(t=Math.max(t,n.anchor.row+1,n.focus.row+1),e=Math.max(e,n.anchor.column+1,n.focus.column+1))});const s=t!==this.rowCount||e!==this.columnCount;return this.rowCountValue=t,this.columnCountValue=e,s}getSelectionBounds(){const t=this.selectionAnchor??this.selectionFocus??{row:0,column:0},e=this.selectionFocus??t,s=$(t,e);return{top:s.start.row,bottom:s.end.row,left:s.start.column,right:s.end.column}}selectCell(t,e,s=!1){const o={row:t,column:e};this.selectionMode=void 0,(!s||!this.selectionAnchor)&&(this.selectionAnchor=o);const r=this.expandSelectionToMerges(this.selectionAnchor,o);this.selectionAnchor=r.anchor,this.selectionFocus=r.focus,this.selectedKey=`${t}:${e}`,this.pendingAwarenessCursor=o}isPositionSelected(t){return T($(this.selectionAnchor,this.selectionFocus),t)}selectionToClipboard(){if(!this.selectionFocus)return;const t=$(this.selectionAnchor,this.selectionFocus),e=[],s=[];for(let o=t.start.row;o<=t.end.row;o+=1){const r=[],n=[];for(let i=t.start.column;i<=t.end.column;i+=1){const l=W({row:o,column:i});r.push(this.cells.get(l)??"");const u=this.readStyle(l);n.push(Object.keys(u).length?u:null)}e.push(r),s.push(n)}return{values:e,styles:s}}selectionToText(){var t;return((t=this.selectionToClipboard())==null?void 0:t.values.map(e=>e.join(" ")).join(`
|
|
6
|
-
`))??""}copySelection(){var e;const t=this.selectionToText();t&&((e=navigator.clipboard)==null||e.writeText(t))}clearSelectionContents(){if(this.readOnly||this.selectionHasLocks())return;const t=$(this.selectionAnchor,this.selectionFocus);this.doc.transact(()=>{for(let e=t.start.row;e<=t.end.row;e+=1)for(let s=t.start.column;s<=t.end.column;s+=1)this.cells.delete(W({row:e,column:s}))})}showCellContextMenu(t,e){this.readOnly||this.showContextMenu(t,e,[{label:"编辑",actions:[["复制",()=>this.copySelection()],["清空内容",()=>this.clearSelectionContents()]]},{label:"单元格",actions:[["合并单元格",()=>this.mergeSelection()],["取消合并单元格",()=>this.unmergeSelection()]]},{label:"固定",actions:[["固定至选中行",()=>this.freezeSelection("row")],["固定至选中列",()=>this.freezeSelection("column")],["取消固定",()=>this.setFrozenPanes(0,0)]]},{label:"保护",actions:this.protectionActions()}])}openCellContextMenu(t){if(!this.readOnly&&(t.preventDefault(),t.stopPropagation(),this.pendingCellContext={x:t.clientX,y:t.clientY},this.rightButtonReleased)){this.pendingCellContext=void 0;const e=this.rightMouseUpPoint??{x:t.clientX,y:t.clientY};this.showCellContextMenu(e.x,e.y)}}sendAwareness(t){this.pendingAwarenessCursor=void 0,this.updateAwareness({cursor:t,editing:this.editingKey??null})}logChunk(t,e){const s=Array.from(e,o=>o.toString(16).padStart(2,"0")).join(" ");this.log(`${t} bytes=${e.byteLength} hex=${s}`)}inspectConnections(){var e,s;const t=this.provider;(e=t.signalingConns)==null||e.forEach(o=>{if(this.loggedSignals.has(o))return;this.loggedSignals.add(o);const r=o.send.bind(o);o.send=n=>{this.log(`signal:send ${JSON.stringify(n)}`),r(n)},o.on("message",n=>this.log(`signal:recv ${JSON.stringify(n)}`)),o.on("connect",()=>this.log("signal:connect")),o.on("disconnect",()=>this.log("signal:disconnect")),o.on("error",n=>this.log(`signal:error ${String(n)}`))}),(s=t.room)==null||s.webrtcConns.forEach((o,r)=>{const n=o.peer;if(this.loggedPeers.has(n))return;this.loggedPeers.add(n);const i=n.send.bind(n);n.send=l=>{this.logChunk(`webrtc:send peer=${r}`,l),i(l)},n.on("data",l=>this.logChunk(`webrtc:recv peer=${r}`,l)),n.on("connect",()=>this.log(`webrtc:connect peer=${r}`)),n.on("close",()=>this.log(`webrtc:close peer=${r}`)),n.on("error",l=>this.log(`webrtc:error peer=${r} ${String(l)}`))})}seed(t){t.forEach((e,s)=>e.forEach((o,r)=>{const n=`${s}:${r}`;!this.cells.has(n)&&!this.isCellLocked(n)&&this.cells.set(n,o)}))}seedDemoFormatting(){this.doc.transact(()=>{this.cells.set("0:0",`设计协作表格
|
|
7
|
-
多人协作工作区`),this.cells.delete("0:1"),this.cells.delete("0:2"),this.merges.set("0:0-0:2","1"),this.styles.set("0:0",JSON.stringify({bold:!0,fontSize:16,color:"#0f172a",background:"#bae6fd",align:"center",wrap:!0,border:{top:!0,right:!0,bottom:!0,left:!0}})),this.styles.set("1:0",JSON.stringify({bold:!0,underline:!0,background:"#fef3c7",border:{bottom:!0}})),this.styles.set("1:1",JSON.stringify({italic:!0,color:"#7c3aed"})),this.styles.set("1:2",JSON.stringify({strike:!0,color:"#b91c1c"})),this.cells.set("2:0","125000"),this.styles.set("2:0",JSON.stringify({format:"number",fontSize:14,border:{top:!0,bottom:!0}})),this.cells.set("2:1","0.72"),this.styles.set("2:1",JSON.stringify({format:"percent",color:"#047857",align:"right"})),this.cells.set("2:2","2026-08-09"),this.styles.set("2:2",JSON.stringify({format:"date",background:"#dcfce7"})),this.cells.set("3:0",`这是一段较长的演示内容
|
|
8
|
-
可使用自动换行工具查看`),this.styles.set("3:0",JSON.stringify({wrap:!0,background:"#f1f5f9",border:{top:!0,right:!0,bottom:!0,left:!0}})),this.cells.set("4:0","删除线示例"),this.styles.set("4:0",JSON.stringify({strike:!0,color:"#64748b"})),this.cells.set("5:0","合并区域示例"),this.cells.delete("5:1"),this.cells.delete("5:2"),this.merges.set("5:0-5:2","1"),this.styles.set("5:0",JSON.stringify({bold:!0,align:"center",background:"#ede9fe",border:{top:!0,right:!0,bottom:!0,left:!0}})),this.rowHeights.set("0",72),this.rowHeights.set("3",72),this.rowHeights.set("5",44),this.columnWidths.set("0",220),this.columnWidths.set("1",130),this.columnWidths.set("2",130)})}expandLogicalSizeFromDocument(){const t=[...this.cells.keys(),...this.styles.keys(),...this.locks.keys(),...this.rowHeights.keys(),...this.columnWidths.keys()].map(e=>e.split(":").map(Number)).filter(([e,s])=>Number.isInteger(e)&&Number.isInteger(s));t.length&&(this.rowCountValue=Math.max(this.rowCount,...t.map(([e])=>e+1)),this.columnCountValue=Math.max(this.columnCount,...t.map(([,e])=>e+1)))}render(){this.editor&&this.finishEdit(!0);const t=this.columnCount,e=this.rowCount;this.frozenRows=Math.min(this.frozenRows,e-1),this.frozenColumns=Math.min(this.frozenColumns,t-1);const s=this.hasPartialMerge("row",0,this.frozenRows-1),o=this.hasPartialMerge("column",0,this.frozenColumns-1);(s||o)&&(s&&(this.frozenRows=0),o&&(this.frozenColumns=0),this.showLockMessage("合并区域已变化,已取消与合并块冲突的固定行列"));const r=d=>this.getRowHeight(d),n=d=>this.getColumnWidth(d),i=Lt({scrollTop:this.viewport.scrollTop,scrollLeft:this.viewport.scrollLeft,clientHeight:this.viewport.clientHeight||560,clientWidth:this.viewport.clientWidth||900,rowCount:e,columnCount:t,rowSize:r,columnSize:n,overscan:4});let l=!0;const u=this.getMergeRanges();for(;l;){l=!1;for(const d of u){const y=d.start.row<=i.bottom&&(d.end.row>=i.top||d.start.row<this.frozenRows),b=d.start.column<=i.right&&(d.end.column>=i.left||d.start.column<this.frozenColumns);!y||!b||(d.start.row>=this.frozenRows&&d.start.row<i.top&&(i.top=d.start.row,l=!0),d.start.column>=this.frozenColumns&&d.start.column<i.left&&(i.left=d.start.column,l=!0),d.end.row>i.bottom&&(i.bottom=d.end.row,l=!0),d.end.column>i.right&&(i.right=d.end.column,l=!0))}}i.bottom=Math.max(i.bottom,this.frozenRows-1),i.right=Math.max(i.right,this.frozenColumns-1);const c=Math.max(this.frozenRows,i.top),m=Math.max(this.frozenColumns,i.left),f=(d,y,b)=>[...Array.from({length:d},(L,C)=>C),-1,...Array.from({length:Math.max(0,b-y+1)},(L,C)=>y+C)],p=f(this.frozenRows,c,i.bottom),M=f(this.frozenColumns,m,i.right),E=q(m,n)-q(this.frozenColumns,n),N=q(c,r)-q(this.frozenRows,r),H=(d,y,b)=>{const L=y>=0&&y<this.frozenRows,C=b>=0&&b<this.frozenColumns;!L&&!C||(d.classList.add("is-frozen"),d.style.position="sticky",L&&(d.style.top=`${this.columnHeaderHeight+q(y,r)}px`),C&&(d.style.left=`${this.rowHeaderWidth+q(b,n)}px`),d.style.zIndex=String(y<0?10:b<0?8:L&&C?5:L?4:3))},U=document.createElement("thead"),B=document.createElement("tr"),z=document.createElement("th");z.style.width=`${this.rowHeaderWidth}px`,z.style.height=`${this.columnHeaderHeight}px`,z.addEventListener("mousedown",d=>{d.preventDefault(),d.stopPropagation(),this.selectRange({row:0,column:0},{row:e-1,column:t-1},"all")}),B.append(z);const I=d=>{const y=document.createElement("th");return y.style.width=`${d}px`,y.style.padding="0",y.style.border="0",y};for(const d of M){if(d===-1){B.append(I(E));continue}const y=document.createElement("th");y.style.width=`${n(d)}px`,y.style.height=`${this.columnHeaderHeight}px`,y.style.fontSize=`${nt*this.zoomRatio}px`;const b=document.createElement("b");b.className="colwork-table__column-letter",b.textContent=_t(d),y.append(b),this.addResizeHandle(y,"column",d),this.addHeaderSelection(y,"column",d),H(y,-1,d),B.append(y)}B.append(I(G(t,n)-q(i.right+1,n))),U.append(B);const O=document.createElement("tbody"),j=d=>{const y=document.createElement("tr");y.className="colwork-table__spacer",y.style.height=`${d}px`;const b=document.createElement("td");return b.colSpan=M.length+2,b.style.height=`${d}px`,y.append(b),y};for(const d of p){if(d===-1){O.append(j(N));continue}const y=document.createElement("tr");this.bandedRows&&d%2===1&&(y.className="is-banded-row"),y.style.height=`${r(d)}px`;const b=document.createElement("th");b.style.width=`${this.rowHeaderWidth}px`,b.style.height=`${r(d)}px`,b.style.fontSize=`${nt*this.zoomRatio}px`,b.textContent=String(d+1),this.addResizeHandle(b,"row",d),this.addHeaderSelection(b,"row",d),y.append(b),H(b,d,-1);for(const C of M){if(C===-1){const _=document.createElement("td");_.style.width=`${E}px`,_.style.padding="0",_.style.border="0",y.append(_);continue}if(this.isMergeCovered(d,C))continue;const F=W({row:d,column:C}),v=document.createElement("td");v.style.width=`${n(C)}px`,v.style.height=`${r(d)}px`,v.dataset.key=F;const A=this.getMergeStartingAt(d,C);A&&(v.rowSpan=A.end.row-A.start.row+1,v.colSpan=A.end.column-A.start.column+1);const D=document.createElement("span");D.className="colwork-table__cell-value",D.style.height=`${Math.max(0,r(d)-4)}px`,D.style.maxHeight=`${Math.max(0,r(d)-4)}px`,D.textContent=this.displayValue(F),this.applyStyle(D,F),v.append(D),this.applyStyle(v,F),H(v,d,C);const K=this.isCellLocked(F);v.classList.toggle("is-locked",K),v.classList.toggle("is-password-locked",this.isCellPasswordLocked(F)),v.setAttribute("aria-readonly",String(this.readOnly||K)),K&&(v.title=this.isCellPasswordLocked(F)?"密码锁定:验证密码后可编辑":"已锁定:解锁后可编辑"),v.addEventListener("mousedown",_=>{_.target instanceof HTMLTextAreaElement||_.button!==0&&_.button!==2||(_.button===2?(this.rightButtonReleased=!1,this.rightDrag={start:{row:d,column:C},moved:!1}):this.rightDrag=void 0,_.preventDefault(),this.viewport.focus({preventScroll:!0}),this.selecting=!0,(_.button===0||!this.isPositionSelected({row:d,column:C}))&&this.selectCell(d,C,_.shiftKey),this.refreshSelection())}),v.addEventListener("mouseenter",()=>{if(!(!this.selecting||this.headerSelecting)){if(this.rightDrag){if(this.rightDrag.start.row===d&&this.rightDrag.start.column===C)return;this.rightDrag.moved||(this.rightDrag.moved=!0,this.selectionMode=void 0,this.selectionAnchor=this.rightDrag.start,this.selectedKey=W(this.rightDrag.start))}this.selectCell(d,C,!0),this.refreshSelection()}}),this.readOnly||v.addEventListener("dblclick",()=>this.startEdit(v,F,!1)),v.addEventListener("contextmenu",_=>this.openCellContextMenu(_)),y.append(v)}const L=document.createElement("td");L.style.width=`${G(t,n)-q(i.right+1,n)}px`,L.style.padding="0",L.style.border="0",y.append(L),O.append(y)}O.append(j(G(e,r)-q(i.bottom+1,r))),this.table.style.setProperty("--colwork-zoom",String(this.zoomRatio)),this.table.style.width=`${this.rowHeaderWidth+G(t,n)}px`,this.table.classList.toggle("is-grid-hidden",!this.showGridLines),this.table.classList.toggle("is-banded-rows",this.bandedRows),this.table.style.fontSize=`${this.zoomRatio}em`,this.table.replaceChildren(U,O),this.refreshFrozenBoundaries(),this.refreshSelection(),this.refreshCursors()}refreshFrozenBoundaries(){this.frozenBoundaryLayer.replaceChildren(),this.frozenBoundaryLayer.style.width=`${this.viewport.clientWidth}px`,this.frozenBoundaryLayer.style.height=`${this.viewport.clientHeight}px`;const t=(e,s,o,r)=>{if(!s||o>=r)return;const n=document.createElement("span");n.className=`colwork-table__frozen-boundary colwork-table__frozen-boundary--${e}`,n.setAttribute("aria-hidden","true"),n.style.left=`${e==="column"?o-1:0}px`,n.style.top=`${e==="row"?o-1:0}px`,e==="column"?n.style.height=`${this.viewport.clientHeight}px`:n.style.width=`${this.viewport.clientWidth}px`,this.frozenBoundaryLayer.append(n)};t("row",this.frozenRows,this.columnHeaderHeight+q(this.frozenRows,e=>this.getRowHeight(e)),this.viewport.clientHeight),t("column",this.frozenColumns,this.rowHeaderWidth+q(this.frozenColumns,e=>this.getColumnWidth(e)),this.viewport.clientWidth)}refreshValues(){const t=document.activeElement;this.table.querySelectorAll("td[data-key]").forEach(e=>{const s=e.dataset.key;if(s&&e!==t&&s!==this.editingKey){const o=e.querySelector(".colwork-table__cell-value");o?o.textContent=this.displayValue(s):e.textContent=this.displayValue(s)}})}refreshSelection(){if(this.viewport.querySelectorAll(".colwork-table__selection").forEach(e=>e.remove()),!this.selectionFocus)return;const t=this.getSelectionBounds();this.table.querySelectorAll("th[data-selection-axis]").forEach(e=>{const s=e.dataset.selectionAxis,o=Number(e.dataset.selectionIndex),r=this.selectionMode==="all"||this.selectionMode===s&&(s==="row"?o>=t.top&&o<=t.bottom:o>=t.left&&o<=t.right);e.classList.toggle("is-selected-header",r)}),this.addSelectionOverlay($({row:t.top,column:t.left},{row:t.bottom,column:t.right}),"colwork-table__selection",this.options.userColor??"#3b82f6")}refreshCursors(){this.table&&(this.table.querySelectorAll("td[data-key]").forEach(t=>{t.querySelectorAll(".colwork-table__remote-cursor").forEach(e=>e.remove())}),this.viewport.querySelectorAll(".colwork-table__remote-selection").forEach(t=>t.remove()),this.awareness.getStates().forEach((t,e)=>{var o;if(e===this.awareness.clientID)return;const s=t.selection;if(s!=null&&s.anchor&&s.focus){const r=yt(s,this.rowCount,this.columnCount);r&&this.addSelectionOverlay(r,"colwork-table__remote-selection",((o=t.user)==null?void 0:o.color)??"#94a3b8");const n=Math.min(s.anchor.row,s.focus.row),i=Math.min(s.anchor.column,s.focus.column),l=this.table.querySelector(`td[data-key="${n}:${i}"]`);l&&this.addCursorLabel(l,t,e)}else{const r=t.cursor,n=r&&this.table.querySelector(`td[data-key="${r.row}:${r.column}"]`);n&&this.addCursorLabel(n,t,e)}}))}addSelectionOverlay(t,e,s){this.table.querySelectorAll("td[data-key]").forEach(o=>{const[r,n]=o.dataset.key.split(":").map(Number),i=r+o.rowSpan-1,l=n+o.colSpan-1;if(r>t.end.row||i<t.start.row||n>t.end.column||l<t.start.column)return;const u=getComputedStyle(o),c=parseFloat(u.borderTopWidth),m=parseFloat(u.borderRightWidth),f=parseFloat(u.borderBottomWidth),p=parseFloat(u.borderLeftWidth),M=(z,I,O,j,d,y,b)=>{if(z>=O&&I<=j)return[`${-y}px`,`${-b}px`];let L=0,C=0,F=0;for(let A=z;A<=I;A++){const D=this.table.querySelector(`th[data-selection-axis="${d}"][data-selection-index="${A}"]`),K=D==null?void 0:D.getBoundingClientRect(),_=d==="row"?(K==null?void 0:K.height)??this.getRowHeight(A):(K==null?void 0:K.width)??this.getColumnWidth(A);L+=_,A<O&&(C+=_),A>j&&(F+=_)}const v=(A,D)=>A===0?`${-D}px`:`calc(${A/L*100}% + ${(y+b)*A/L-D}px)`;return[v(C,y),v(F,b)]},[E,N]=M(r,i,t.start.row,t.end.row,"row",c,f),[H,U]=M(n,l,t.start.column,t.end.column,"column",p,m),B=document.createElement("span");B.className=e,B.setAttribute("aria-hidden","true"),Object.assign(B.style,{top:E,right:U,bottom:N,left:H,borderTopWidth:r<=t.start.row?"2px":"0",borderRightWidth:l>=t.end.column?"2px":"0",borderBottomWidth:i>=t.end.row?"2px":"0",borderLeftWidth:n<=t.start.column?"2px":"0",borderColor:s,backgroundColor:pt(s,.1)}),o.append(B)})}addCursorLabel(t,e,s){var r,n;const o=document.createElement("span");o.className="colwork-table__remote-cursor",o.style.backgroundColor=((r=e.user)==null?void 0:r.color)??"#64748b",o.textContent=((n=e.user)==null?void 0:n.name)??String(s).slice(0,6),t.append(o)}startEdit(t,e,s=!0){if(this.readOnly||this.isCellLocked(e)||this.editingKey===e)return;this.finishEdit(!0);const o=Array.from(this.table.querySelectorAll("td[data-key]")).find(n=>n.dataset.key===e);o&&(t=o),this.editingKey=e,this.editingOriginal=this.cells.get(e)??"";const r=document.createElement("textarea");r.className="colwork-table__editor",r.value=this.editingOriginal,this.applyStyle(r,e),this.editor=r,t.classList.add("is-editing"),t.append(r),s&&this.sendAwareness({...this.selectionFocus??{row:0,column:0},offset:0}),r.addEventListener("blur",()=>this.finishEdit(!0),{once:!0}),r.addEventListener("keydown",n=>{n.key==="Enter"&&!n.ctrlKey&&!n.shiftKey&&r.blur(),n.key==="Escape"&&this.finishEdit(!1)}),r.focus(),r.select()}readStyle(t){try{return JSON.parse(this.styles.get(t)??"{}")}catch{return{}}}applyStyle(t,e){var o,r,n,i;const s=this.readStyle(e);t.style.fontWeight=s.bold?"700":"",t.style.fontStyle=s.italic?"oblique":"",t.style.textDecoration=[s.underline?"underline":"",s.strike?"line-through":""].filter(Boolean).join(" "),t.style.transform=t.classList.contains("colwork-table__cell-value")&&s.italic?"skewX(-8deg)":"",t.style.fontSize=s.fontSize?`${s.fontSize*this.zoomRatio}px`:"",t.style.color=s.color??"",t.style.backgroundColor=s.background??"",t.style.textAlign=s.align??"",t.classList.contains("colwork-table__cell-value")&&(t.style.whiteSpace=s.wrap?"pre-wrap":"pre"),!t.classList.contains("colwork-table__cell-value")&&!t.classList.contains("colwork-table__editor")&&(t.style.borderTop=(o=s.border)!=null&&o.top?"2px solid #64748b":"",t.style.borderRight=(r=s.border)!=null&&r.right?"2px solid #64748b":"",t.style.borderBottom=(n=s.border)!=null&&n.bottom?"2px solid #64748b":"",t.style.borderLeft=(i=s.border)!=null&&i.left?"2px solid #64748b":"")}displayValue(t){const e=this.cells.get(t)??"",s=this.readStyle(t).format??"general";if(!e||s==="general")return e;if(s==="number"){const r=Number(e);return Number.isFinite(r)?r.toLocaleString():e}if(s==="percent"){const r=Number(e.replace(/%$/,""));return Number.isFinite(r)?`${e.endsWith("%")?r:r*100}%`:e}const o=new Date(e);return Number.isNaN(o.getTime())?e:o.toISOString().slice(0,10)}toggleFormat(t){if(this.readOnly||!this.selectedKey||this.selectionHasLocks())return;const{top:e,bottom:s,left:o,right:r}=this.getSelectionBounds(),n=this.readStyle(this.selectedKey)[t];this.doc.transact(()=>{for(let i=e;i<=s;i+=1)for(let l=o;l<=r;l+=1){const u=`${i}:${l}`,c=this.readStyle(u);c[t]=!n,this.styles.set(u,JSON.stringify(c))}}),this.render()}clearFormatting(){if(this.readOnly||!this.selectedKey||this.selectionHasLocks())return;const{top:t,bottom:e,left:s,right:o}=this.getSelectionBounds();this.doc.transact(()=>{for(let r=t;r<=e;r+=1)for(let n=s;n<=o;n+=1)this.styles.delete(W({row:r,column:n}))}),this.render()}toggleBorder(t){if(this.readOnly||!this.selectedKey||this.selectionHasLocks())return;const{top:e,bottom:s,left:o,right:r}=this.getSelectionBounds(),n=(c,m)=>{const f=[];return t==="outer"&&(c===e&&f.push("top"),c===s&&f.push("bottom"),m===o&&f.push("left"),m===r&&f.push("right")),(t==="inner"||t==="horizontal")&&c<s&&f.push("bottom"),(t==="inner"||t==="vertical")&&m<r&&f.push("right"),f},i=Array.from({length:s-e+1},(c,m)=>Array.from({length:r-o+1},(f,p)=>({row:e+m,column:o+p}))).flat();if(!i.flatMap(({row:c,column:m})=>n(c,m)).length)return;const u=!i.every(({row:c,column:m})=>n(c,m).every(f=>{var p;return(p=this.readStyle(W({row:c,column:m})).border)==null?void 0:p[f]}));this.doc.transact(()=>{for(let c=e;c<=s;c+=1)for(let m=o;m<=r;m+=1){const f=W({row:c,column:m}),p=this.readStyle(f),M={...p.border??{}};n(c,m).forEach(E=>{u?M[E]=!0:delete M[E]}),Object.keys(M).length?p.border=M:delete p.border,this.styles.set(f,JSON.stringify(p))}}),this.render()}setStyle(t,e){if(this.readOnly||!this.selectedKey||this.selectionHasLocks())return;const{top:s,bottom:o,left:r,right:n}=this.getSelectionBounds();this.doc.transact(()=>{for(let i=s;i<=o;i+=1)for(let l=r;l<=n;l+=1){const u=`${i}:${l}`,c=this.readStyle(u);t==="align"?c.align=e:t==="color"?c.color=e:t==="background"?c.background=e:t==="fontSize"?c.fontSize=e:c.format=e,this.styles.set(u,JSON.stringify(c))}}),this.render()}refreshStyles(){this.table.querySelectorAll("td[data-key]").forEach(t=>{if(t.dataset.key){this.applyStyle(t,t.dataset.key);const e=t.querySelector(".colwork-table__cell-value");e&&(this.applyStyle(e,t.dataset.key),e.textContent=this.displayValue(t.dataset.key))}}),this.refreshSelection(),this.refreshCursors()}finishEdit(t){if(!this.editor||!this.editingKey)return;const e=this.editingKey,s=this.editor,o=t?s.value:this.editingOriginal;this.editor=void 0,this.editingKey=void 0,this.editingOriginal="",!this.isCellLocked(e)&&o!==this.cells.get(e)&&this.cells.set(e,o);const r=this.awareness.getLocalState()??{};this.awareness.setLocalState({...r,editing:null}),s.remove();const n=this.table.querySelector(`td[data-key="${e}"]`);if(!n){this.render();return}this.table.querySelectorAll("td.is-editing").forEach(l=>l.classList.remove("is-editing"));const i=n.querySelector(".colwork-table__cell-value")??document.createElement("span");i.className="colwork-table__cell-value",i.textContent=this.displayValue(e),i.parentElement||n.append(i),Array.from(n.childNodes).forEach(l=>{l!==i&&l.nodeType===Node.TEXT_NODE&&l.remove()}),this.applyStyle(n,e),this.applyStyle(i,e),this.refreshSelection(),this.refreshCursors()}destroy(){var t,e;this.destroyed=!0,this.viewportResizeObserver.disconnect(),this.closeLockMessage(),(t=this.passwordDialog)==null||t.close(),this.finishEdit(!0),this.doc.off("update",this.onDocUpdate),this.awareness.off("update",this.onAwarenessUpdate),this.awareness.off("change",this.onAwarenessChange),this.cells.unobserve(this.onCellsChange),this.styles.unobserve(this.onStylesChange),this.rowHeights.unobserve(this.onSizesChange),this.columnWidths.unobserve(this.onSizesChange),this.merges.unobserve(this.onMergesChange),this.locks.unobserve(this.onLocksChange),this.undoManager.off("stack-item-added",this.onHistoryChange),this.undoManager.off("stack-item-popped",this.onHistoryChange),this.undoManager.off("stack-cleared",this.onHistoryChange),this.viewport.removeEventListener("scroll",this.onViewportScroll),this.viewport.removeEventListener("wheel",this.onViewportWheel),this.viewport.removeEventListener("keydown",this.onViewportKeyDown),this.viewport.removeEventListener("copy",this.onCopy,!0),this.viewport.removeEventListener("paste",this.onPaste,!0),this.table.removeEventListener("mousedown",this.onTableMouseDown),window.removeEventListener("mouseup",this.onWindowMouseUp),window.removeEventListener("mousemove",this.onWindowMouseMove),window.removeEventListener("blur",this.onWindowBlur),document.removeEventListener("mousedown",this.onDocumentMouseDown),this.hideContextMenu(),this.renderFrame!==void 0&&cancelAnimationFrame(this.renderFrame),(e=this.provider)==null||e.destroy(),this.undoManager.destroy(),this.doc.destroy(),this.root.replaceChildren()}}function at(a){if(a!=null&&a.trim())return JSON.parse(a)}function $t(a){if(!(!a||a.format==="colwork.update-log"))return a.format==="colwork.archive"?a.snapshot:a}function lt(a){return!a||a.format==="colwork.snapshot"?[]:a.updates??[]}function Nt(a,t){const e=at(a),s=at(t),o=$t(e),r=[...lt(e),...lt(s)],n=new V.Doc;o!=null&&o.snapshot&&V.applyUpdate(n,rt(o.snapshot));const i=Number((o==null?void 0:o.sequence)??0),l=new Set,u=new Set;let c=i;for(const m of r.sort((f,p)=>Number(f.seq)-Number(p.seq))){const f=Number(m.seq);!Number.isInteger(f)||typeof m.update!="string"||f<=i||l.has(f)||u.has(m.update)||(V.applyUpdate(n,rt(m.update)),l.add(f),u.add(m.update),c=Math.max(c,f))}return{format:"colwork.snapshot",version:1,room:o==null?void 0:o.room,sequence:c,snapshot:Y(V.encodeStateAsUpdate(n)),stateVector:Y(V.encodeStateVector(n))}}x.ColworkTable=Rt,x.cellKey=W,x.containsPosition=T,x.normalizeRange=st,x.rangeSize=wt,x.rebuildYjsSnapshot=Nt,Object.defineProperty(x,Symbol.toStringTag,{value:"Module"})}));
|
|
6
|
+
`).filter((f,S,M)=>!(S===M.length-1&&f==="")).map(f=>f.split(" ")),c;try{const f=JSON.parse(((d=e.clipboardData)==null?void 0:d.getData(be))??"");Ie(f)&&(i=f.values,c=f.styles)}catch{}const h=t.focus;if(i.some((f,S)=>f.some((M,b)=>s.isCellLocked(H({row:h.row+S,column:h.column+b})))))return;const m=this.host.dimensions();s.doc.transact(()=>i.forEach((f,S)=>f.forEach((M,b)=>{var N;const L={row:h.row+S,column:h.column+b};if(L.row>=m.rows||L.column>=m.columns)return;const $=H(L);if(s.cells.set($,ye(M)),c){const j=(N=c[S])==null?void 0:N[b];j?s.styles.set($,JSON.stringify(j)):s.styles.delete($)}})),this.host.origin),t.anchor=h,t.focus={row:Math.min(m.rows-1,h.row+i.length-1),column:Math.min(m.columns-1,h.column+Math.max(...i.map(f=>f.length))-1)},this.host.render()});this.host=e}payload(){const{sheet:e,selection:t,formatting:s}=this.host;if(!t.focus)return;const n=_(t.anchor,t.focus),r=[],i=[];for(let c=n.start.row;c<=n.end.row;c++){const h=[],m=[];for(let a=n.start.column;a<=n.end.column;a++){const l=H({row:c,column:a});h.push(e.cells.get(l)??"");const d=s.readStyle(l);m.push(Object.keys(d).length?d:null)}r.push(h),i.push(m)}return{values:r,styles:i}}copySelection(){var t,s;const e=(t=this.payload())==null?void 0:t.values.map(n=>n.join(" ")).join(`
|
|
7
|
+
`);e&&((s=navigator.clipboard)==null||s.writeText(e))}}function G(o){let e="";for(let s=0;s<o.length;s+=32768)e+=String.fromCharCode(...o.subarray(s,s+32768));return btoa(e)}function Se(o){const e=atob(o);return Uint8Array.from(e,t=>t.charCodeAt(0))}function ke(o){if(o!=null&&o.trim())return JSON.parse(o)}function Ue(o){if(!(!o||o.format==="colwork.update-log"))return o.format==="colwork.archive"?o.snapshot:o}function Ce(o){return!o||o.format==="colwork.snapshot"?[]:o.updates??[]}function Je(o,e){const t=ke(o),s=ke(e),n=Ue(t),r=[...Ce(t),...Ce(s)],i=new W.Doc;try{n!=null&&n.snapshot&&W.applyUpdate(i,Se(n.snapshot));const c=Number((n==null?void 0:n.sequence)??0),h=new Set,m=new Set;let a=c;for(const l of r.sort((d,f)=>Number(d.seq)-Number(f.seq))){const d=Number(l.seq);!Number.isInteger(d)||typeof l.update!="string"||d<=c||h.has(d)||m.has(l.update)||(W.applyUpdate(i,Se(l.update)),h.add(d),m.add(l.update),a=Math.max(a,d))}return{format:"colwork.snapshot",version:1,room:n==null?void 0:n.room,sequence:a,snapshot:G(W.encodeStateAsUpdate(i)),stateVector:G(W.encodeStateVector(i))}}finally{i.destroy()}}function Ge(o,e){const t=o.split(":").map(Number),s=e.split(":").map(Number);return t[0]-s[0]||(t[1]??0)-(s[1]??0)}function Y(o){return[...o].sort(([e],[t])=>Ge(e,t))}function Ye(o){const e={};for(const t of["bold","italic","underline","strike","wrap","fontSize","color","background","align","format"])o[t]!==void 0&&(e[t]=o[t]);if(o.border!==void 0){const t={};for(const s of["top","right","bottom","left"])o.border[s]!==void 0&&(t[s]=o.border[s]);e.border=t}return e}function Ee(o,e){const t=ne(o,e);if(t.length)throw new TypeError(`Invalid Colwork document at ${t[0].path}: ${t[0].message}`);const s=J(o),n=Object.fromEntries(Y(s.styles).map(([m,a])=>[m,Ye(JSON.parse(a))])),r=Object.fromEntries(Y(s.locks).map(([m,a])=>{if(a==="1")return[m,"1"];const l=JSON.parse(a);return[m,{version:l.version,algorithm:l.algorithm,iterations:l.iterations,salt:l.salt,verifier:l.verifier}]})),i=[...s.merges.keys()].map(m=>Q(m)).sort((m,a)=>m.start.row-a.start.row||m.start.column-a.start.column||m.end.row-a.end.row||m.end.column-a.end.column);let c=1,h=1;for(const m of[...s.cells.keys(),...s.styles.keys(),...s.locks.keys()]){const a=K(m);c=Math.max(c,a.row+1),h=Math.max(h,a.column+1)}for(const m of i)c=Math.max(c,m.end.row+1),h=Math.max(h,m.end.column+1);for(const m of s.rowHeights.keys())c=Math.max(c,Number(m)+1);for(const m of s.columnWidths.keys())h=Math.max(h,Number(m)+1);return{schemaVersion:Z,rowCount:c,columnCount:h,cells:Object.fromEntries(Y(s.cells)),styles:n,rowHeights:Object.fromEntries(Y(s.rowHeights)),columnWidths:Object.fromEntries(Y(s.columnWidths)),merges:i,locks:r}}function Xe(o){const e=ne(o);if(e.length)throw new TypeError(`Invalid Colwork document at ${e[0].path}: ${e[0].message}`);if(Object.values(J(o)).some(s=>s.size>0))throw new Error("Blank initialization requires an empty sheet");const t=o.getMap(T.metadata);o.transact(()=>{t.set("schemaVersion",Z),t.set("initialized",!0)})}function ve(o,e={}){const t=e.sequence??0;if(!Number.isSafeInteger(t)||t<0)throw new RangeError("sequence must be a non-negative safe integer");return{format:"colwork.snapshot",version:1,room:e.room,sequence:t,snapshot:G(W.encodeStateAsUpdate(o)),stateVector:G(W.encodeStateVector(o))}}function Ze(o,e){const t=new W.Doc;try{return W.applyUpdate(t,o),Ee(t,e)}finally{t.destroy()}}class Qe{constructor(e,t,s,n,r,i){u(this,"revision",0);u(this,"sequence",0);u(this,"updates",[]);u(this,"loggedPeers",new Set);u(this,"loggedSignals",new Set);u(this,"onUpdate",(e,t)=>{if(this.revision++,this.updates.push({seq:++this.sequence,update:G(e),timestamp:Date.now()}),!this.logging)return;const s=this.provider;this.logChunk(`yjs:${t===(s==null?void 0:s.room)?"recv":"send"}`,e);const{cells:n,rowHeights:r,columnWidths:i,merges:c}=this.sheet;this.log(`yjs:state ${JSON.stringify({cells:[...n],rowHeights:[...r],columnWidths:[...i],merges:[...c]})}`)});u(this,"onAwarenessUpdate",({added:e,updated:t,removed:s},n)=>{if(!this.logging)return;const r=this.provider;this.log(`awareness:${n===(r==null?void 0:r.room)?"recv":"send"} added=${e.join(",")} updated=${t.join(",")} removed=${s.join(",")}`),this.log(`awareness:state ${JSON.stringify([...this.awareness.getStates()])}`)});this.sheet=e,this.awareness=t,this.provider=s,this.room=n,this.log=r,this.logging=i,e.doc.on("update",this.onUpdate),t.on("update",this.onAwarenessUpdate)}snapshot(){return ve(this.sheet.doc,{room:this.room,sequence:this.sequence})}updateLog(){return{format:"colwork.update-log",version:1,room:this.room,updates:this.updates.map(e=>({...e}))}}destroy(){this.sheet.doc.off("update",this.onUpdate),this.awareness.off("update",this.onAwarenessUpdate)}logChunk(e,t){const s=Array.from(t,n=>n.toString(16).padStart(2,"0")).join(" ");this.log(`${e} bytes=${t.byteLength} hex=${s}`)}inspectConnections(){var t,s;if(!this.logging)return;const e=this.provider;(t=e.signalingConns)==null||t.forEach(n=>{if(this.loggedSignals.has(n))return;this.loggedSignals.add(n);const r=n.send.bind(n);n.send=i=>{this.log(`signal:send ${JSON.stringify(i)}`),r(i)},n.on("message",i=>this.log(`signal:recv ${JSON.stringify(i)}`)),n.on("connect",()=>this.log("signal:connect")),n.on("disconnect",()=>this.log("signal:disconnect")),n.on("error",i=>this.log(`signal:error ${String(i)}`))}),(s=e.room)==null||s.webrtcConns.forEach((n,r)=>{const i=n.peer;if(this.loggedPeers.has(i))return;this.loggedPeers.add(i);const c=i.send.bind(i);i.send=h=>{this.logChunk(`webrtc:send peer=${r}`,h),c(h)},i.on("data",h=>this.logChunk(`webrtc:recv peer=${r}`,h)),i.on("connect",()=>this.log(`webrtc:connect peer=${r}`)),i.on("close",()=>this.log(`webrtc:close peer=${r}`)),i.on("error",h=>this.log(`webrtc:error peer=${r} ${String(h)}`))})}}const ee=new WeakMap,et=["stun:stun.qq.com:3478","stun:stun.miwifi.com:3478","stun:stun.chat.bilibili.com:3478","stun:stun.l.google.com:19302","stun:stun1.l.google.com:19302"].map(o=>({urls:o}));class tt{constructor(e){u(this,"document");u(this,"awareness");u(this,"provider");u(this,"external");u(this,"destroyed",!1);u(this,"published",{});var s,n,r;if(this.external=e.transport==="external",e.transport==="external"){if(!((s=e.collaboration)!=null&&s.document)||!e.collaboration.awareness)throw new TypeError("External collaboration requires a document and awareness");if(e.collaboration.awareness.doc!==e.collaboration.document)throw new TypeError("Awareness must belong to the supplied document");if(e.rows!==void 0||e.snapshot!==void 0||e.updates!==void 0||e.initializeAfterSync===!0)throw new TypeError("Initialize external documents through the model API before creating a table");this.document=e.collaboration.document,this.awareness=e.collaboration.awareness}else{if(typeof e.room!="string")throw new TypeError("Built-in collaboration requires a room");this.document=new W.Doc;try{if(e.readOnly)this.awareness=new Ae.Awareness(this.document);else if(e.transport==="webrtc")this.provider=new Re.WebrtcProvider(e.room,this.document,{signaling:[e.signalingUrl??"ws://127.0.0.1:4444"],filterBcConns:!1,peerOpts:e.peerOpts??{config:{iceServers:et}}}),this.awareness=this.provider.awareness;else{const i=new URL(e.websocketUrl??"ws://127.0.0.1:1234"),c=Object.fromEntries(i.searchParams);i.search="",this.provider=new D.WebsocketProvider(i.toString().replace(/\/$/,""),encodeURIComponent(e.room),this.document,{params:c,connect:!e.initializeAfterSync}),this.awareness=this.provider.awareness}e.snapshot&&W.applyUpdate(this.document,e.snapshot),(n=e.updates)==null||n.forEach(i=>W.applyUpdate(this.document,i))}catch(i){throw(r=this.provider)==null||r.destroy(),this.document.destroy(),i}}const t=this.awareness.getLocalState();t!==null&&t.user===void 0&&this.awareness.setLocalStateField("user",{name:e.user,color:e.userColor})}publish(e){if(this.destroyed)return;const t=this.awareness.getLocalState();t!==null&&(this.published={...this.published,...e},ee.set(this.awareness,this),this.awareness.setLocalState({...t,...e}))}finishEditing(){var e;ee.get(this.awareness)===this&&((e=this.awareness.getLocalState())==null?void 0:e.editing)===this.published.editing&&this.publish({editing:null})}destroy(){var n;if(this.destroyed)return;if(this.destroyed=!0,!this.external){(n=this.provider)==null||n.destroy(),this.awareness.destroy(),this.document.destroy();return}if(ee.get(this.awareness)!==this)return;ee.delete(this.awareness);const e=this.awareness.getLocalState();if(e===null)return;const t={...e};let s=!1;for(const r of["selection","cursor","editing"])r in this.published&&t[r]===this.published[r]&&(delete t[r],s=!0);s&&this.awareness.setLocalState(t)}}class st{constructor(e){u(this,"messageDialog");u(this,"passwordDialog");this.host=e}close(){var e,t;this.closeLockMessage(),(e=this.passwordDialog)==null||e.close(),(t=this.passwordDialog)==null||t.remove(),this.passwordDialog=void 0}requestSelectionLock(e,t=!1){if(this.host.readOnly()||this.host.destroyed()||!this.host.selectionFocus()||this.passwordDialog)return;this.closeLockMessage();const s=_(this.host.selectionAnchor(),this.host.selectionFocus());if(!(t||!e&&Array.from(this.host.locks.entries()).some(([b,L])=>{const[$,N]=b.split(":").map(Number);return L!=="1"&&F(s,{row:$,column:N})}))){this.host.setSelectionLocked(e).catch(b=>this.showLockMessage(b instanceof Error?b.message:"操作失败"));return}const r=document.createElement("dialog");this.passwordDialog=r,r.className="colwork-table__password-dialog",r.setAttribute("aria-label",e?"密码锁定":"密码解锁");const i=document.createElement("form"),c=document.createElement("h3");c.textContent=e?"设置锁定密码":"输入解锁密码";const h=document.createElement("input");h.type="password",h.required=!0,h.placeholder=e?"设置密码":"输入密码",h.autocomplete=e?"new-password":"current-password",h.setAttribute("aria-label","密码");const m=document.createElement("input");m.type="password",m.required=e,m.placeholder="再次输入密码",m.autocomplete="new-password",m.setAttribute("aria-label","确认密码");const a=document.createElement("p");a.setAttribute("role","alert");const l=document.createElement("button");l.type="submit",l.textContent=e?"确认锁定":"确认解锁";const d=document.createElement("button");d.type="button",d.textContent="取消",d.addEventListener("click",()=>r.close()),r.addEventListener("close",()=>{h.value="",m.value="",r.remove(),this.passwordDialog===r&&(this.passwordDialog=void 0)});const f=this.host.selectionAnchor(),S=f&&{...f},M={...this.host.selectionFocus()};i.addEventListener("submit",async b=>{if(b.preventDefault(),!l.disabled){if(e&&h.value!==m.value){a.textContent="两次输入的密码不一致";return}l.disabled=!0,d.disabled=!0,r.oncancel=L=>L.preventDefault(),a.textContent="正在处理…";try{this.host.restoreSelection(S,M),await this.host.setSelectionLocked(e,h.value),r.close()}catch(L){a.textContent=L instanceof Error?L.message:"操作失败,请重试",h.value="",m.value="",h.focus()}finally{l.disabled=!1,d.disabled=!1,r.oncancel=null}}}),i.append(c,h),e&&i.append(m),i.append(a,l,d),r.append(i),this.host.root().append(r),r.showModal(),h.focus()}closeLockMessage(){const e=this.messageDialog;this.messageDialog=void 0,e==null||e.close(),e==null||e.remove()}showLockMessage(e){if(this.host.destroyed())return;this.closeLockMessage(),this.host.hideMenu();const t=document.createElement("dialog");this.messageDialog=t,t.className="colwork-table__message-dialog",t.setAttribute("role","alertdialog"),t.setAttribute("aria-label","操作提示"),t.setAttribute("aria-description",e);const s=document.createElement("h3");s.textContent="操作提示";const n=document.createElement("p");n.className="colwork-table__lock-status",n.setAttribute("role","status"),n.textContent=e;const r=document.createElement("button");r.type="button",r.textContent="确定",r.addEventListener("click",()=>t.close()),t.addEventListener("close",()=>{t.remove(),this.messageDialog===t&&(this.messageDialog=void 0)}),t.append(s,n,r),this.host.root().append(t),t.showModal(),r.focus()}}class ot{constructor(e){u(this,"input");u(this,"key");u(this,"original","");this.host=e}start(e,t,s=!0){if(!this.host.canEdit(t)||this.key===t)return;this.finish(!0),e=this.host.table.querySelector(`td[data-key="${t}"]`)??e,this.key=t,this.original=this.host.read(t)??"";const n=document.createElement("textarea");n.className="colwork-table__editor",n.value=this.original,this.host.applyStyle(n,t),this.input=n,e.classList.add("is-editing"),e.append(n),s&&this.host.announce({...this.host.focus()??{row:0,column:0},offset:0}),n.addEventListener("input",()=>this.host.changed({editing:!0,dirty:n.value!==this.original})),this.host.changed({editing:!0,dirty:!1}),n.addEventListener("blur",()=>this.finish(!0),{once:!0}),n.addEventListener("keydown",r=>{r.key==="Enter"&&!r.ctrlKey&&!r.shiftKey&&n.blur(),r.key==="Escape"&&this.finish(!1)}),n.focus(),n.select()}finish(e){if(!this.input||!this.key)return;const t=this.key,s=this.input;this.input=void 0,this.key=void 0,e&&this.host.canEdit(t)&&s.value!==this.host.read(t)&&this.host.write(t,ye(s.value)),this.original="",this.host.clearEditingPresence(),s.remove();const n=this.host.table.querySelector(`td[data-key="${t}"]`);if(!n){this.host.render(),this.host.changed({editing:!1,dirty:!1});return}this.host.table.querySelectorAll("td.is-editing").forEach(i=>i.classList.remove("is-editing"));const r=n.querySelector(".colwork-table__cell-value")??document.createElement("span");r.className="colwork-table__cell-value",r.textContent=this.host.displayValue(t),r.parentElement||n.append(r),Array.from(n.childNodes).forEach(i=>{i!==r&&i.nodeType===Node.TEXT_NODE&&i.remove()}),this.host.applyStyle(n,t),this.host.applyStyle(r,t),this.host.refresh(),this.host.changed({editing:!1,dirty:!1})}}class nt{constructor(e,t=null){u(this,"cells");u(this,"styles");u(this,"rowHeights");u(this,"columnWidths");u(this,"merges");u(this,"locks");u(this,"mergeCache");u(this,"onMergesChange",()=>{this.mergeCache=void 0});this.doc=e,this.origin=t;const s=J(e);this.cells=s.cells,this.styles=s.styles,this.rowHeights=s.rowHeights,this.columnWidths=s.columnWidths,this.merges=s.merges,this.locks=s.locks,this.merges.observe(this.onMergesChange)}getContentSize(){let e=1,t=1;for(const s of[...this.cells.keys(),...this.styles.keys(),...this.locks.keys()]){const n=K(s);n&&(e=Math.max(e,n.row+1),t=Math.max(t,n.column+1))}for(const s of this.getMergeRanges())e=Math.max(e,s.end.row+1),t=Math.max(t,s.end.column+1);for(const s of this.rowHeights.keys())e=Math.max(e,Number(s)+1||1);for(const s of this.columnWidths.keys())t=Math.max(t,Number(s)+1||1);return{rows:e,columns:t}}hasPartialMerge(e,t,s){return t>s?!1:this.getMergeRanges().some(n=>{const r=n.start[e],i=n.end[e];return r<=s&&i>=t&&(r<t||i>s)})}rangeHasLocks(e,t=!1){const s=r=>this.locks.has(r)&&(!t||this.locks.get(r)!=="1");if((e.end.row-e.start.row+1)*(e.end.column-e.start.column+1)<=this.locks.size){for(let r=e.start.row;r<=e.end.row;r++)for(let i=e.start.column;i<=e.end.column;i++)if(s(H({row:r,column:i})))return!0;return!1}for(const r of this.locks.keys()){const i=K(r);if(i&&s(r)&&F(e,i))return!0}return!1}isCellLocked(e,t){if(this.locks.has(e))return!0;const s=K(e);return t===void 0&&s&&(t=this.getMergeRanges().find(n=>F(n,s))),!!t&&this.rangeHasLocks(t)}isCellPasswordLocked(e,t){if(this.locks.has(e)&&this.locks.get(e)!=="1")return!0;const s=K(e);return t===void 0&&s&&(t=this.getMergeRanges().find(n=>F(n,s))),!!t&&this.rangeHasLocks(t,!0)}isAxisLocked(e,t,s=!1){return Array.from(this.locks.keys()).some(n=>{const r=Number(n.split(":")[e==="row"?0:1]);return s?r>=t:r===t})}mergeKey(e){return`${e.start.row}:${e.start.column}-${e.end.row}:${e.end.column}`}getMergeRanges(){if(this.mergeCache)return this.mergeCache;const e=Array.from(this.merges.keys()).flatMap(t=>{const s=Q(t);return s?[s]:[]});return this.doc._transaction===null&&(this.mergeCache=e),e}destroy(){this.merges.unobserve(this.onMergesChange)}expandSelectionToMerges(e,t){let s=_(e,t);for(const i of this.getMergeRanges())i.start.row<=s.end.row&&i.end.row>=s.start.row&&i.start.column<=s.end.column&&i.end.column>=s.start.column&&(s={start:{row:Math.min(s.start.row,i.start.row),column:Math.min(s.start.column,i.start.column)},end:{row:Math.max(s.end.row,i.end.row),column:Math.max(s.end.column,i.end.column)}});const n=t.row>=e.row,r=t.column>=e.column;return{anchor:{row:n?s.start.row:s.end.row,column:r?s.start.column:s.end.column},focus:{row:n?s.end.row:s.start.row,column:r?s.end.column:s.start.column}}}seed(e){e.forEach((t,s)=>t.forEach((n,r)=>{const i=`${s}:${r}`;!this.cells.has(i)&&!this.isCellLocked(i)&&this.cells.set(i,n)}))}modifyAxis(e,t,s,n=0){const r=[this.cells,this.styles];this.doc.transact(()=>{r.forEach(c=>{const h=Array.from(c.entries());c.clear(),h.forEach(([m,a])=>{const[l,d]=m.split(":").map(Number),f=e==="row"?l:d;if(n&&f>=t&&f<t+n)return;const S=f>=t+n?f+s:f,M=H(e==="row"?{row:S,column:d}:{row:l,column:S});c.set(M,a)})});const i=this.getMergeRanges();this.merges.clear(),i.forEach(c=>{const h=e==="row"?c.start.row:c.start.column,m=e==="row"?c.end.row:c.end.column;if(n&&h<t+n&&m>=t)return;const a=h>=t+n?s:0,l=e==="row"?{start:{row:c.start.row+a,column:c.start.column},end:{row:c.end.row+a,column:c.end.column}}:{start:{row:c.start.row,column:c.start.column+a},end:{row:c.end.row,column:c.end.column+a}};this.merges.set(this.mergeKey(l),"1")})},this.origin)}}class rt{constructor(e,t){u(this,"menu");this.viewport=e,this.onHide=t}contains(e){var t;return((t=this.menu)==null?void 0:t.contains(e))??!1}hide(){var e;this.onHide(),(e=this.menu)==null||e.remove(),this.menu=void 0}show(e,t,s){var i;this.hide();const n=document.createElement("div");n.className="colwork-table__context-menu",n.setAttribute("aria-label","表格操作"),s.forEach(({label:c,actions:h})=>{const m=document.createElement("div");m.className="colwork-table__context-group",m.setAttribute("role","group"),m.setAttribute("aria-label",c);const a=document.createElement("div");a.className="colwork-table__context-label",a.textContent=c,m.append(a),h.forEach(([l,d])=>{const f=document.createElement("button");f.type="button",f.textContent=l,(l.startsWith("删除")||l==="清空内容")&&(f.className="is-destructive"),f.addEventListener("click",()=>{this.hide(),d()}),m.append(f)}),n.append(m)}),n.addEventListener("keydown",c=>{var l;if(c.key==="Escape"){c.preventDefault(),this.hide(),this.viewport.focus({preventScroll:!0});return}const h=Array.from(n.querySelectorAll("button")),m=h.indexOf(document.activeElement);let a;if(c.key==="ArrowDown")a=(m+1)%h.length;else if(c.key==="ArrowUp")a=(m-1+h.length)%h.length;else if(c.key==="Home")a=0;else if(c.key==="End")a=h.length-1;else return;c.preventDefault(),(l=h[a])==null||l.focus()}),n.style.left=`${e}px`,n.style.top=`${t}px`,document.body.append(n);const r=n.getBoundingClientRect();n.style.left=`${Math.max(8,Math.min(e,window.innerWidth-r.width-8))}px`,n.style.top=`${Math.max(8,Math.min(t,window.innerHeight-r.height-8))}px`,this.menu=n,(i=n.querySelector("button"))==null||i.focus({preventScroll:!0})}}function it(o){var O;let e,t;const s=document.createElement("div");s.className="colwork-table__toolbar",o.readOnly&&(s.hidden=!0),s.setAttribute("aria-label","表格工具栏");const n=document.createElement("div");n.className="colwork-table__toolbar-row";const r=document.createElement("div");r.className="colwork-table__toolbar-row",s.append(n,r);const i=(g,v)=>{const y=document.createElement("div");y.className="colwork-table__toolbar-group",y.setAttribute("role","group"),y.setAttribute("aria-label",v);const k=document.createElement("span");return k.className="colwork-table__group-label",k.textContent=v,y.append(k),g.append(y),y},c=i(n,"历史"),h=i(n,"单元格"),m=i(n,"保护"),a=i(n,"显示"),l=i(r,"文字"),d=i(r,"对齐"),f=i(r,"格式");[["撤销","↶",()=>o.undo()],["重做","↷",()=>o.redo()]].forEach(([g,v,y],k)=>{const A=document.createElement("button");A.type="button",A.className=`colwork-table__history colwork-table__history--${k===0?"undo":"redo"}`,A.title=g,A.textContent=v,A.addEventListener("mousedown",B=>B.preventDefault()),A.addEventListener("click",y),k===0?e=A:t=A,c.append(A)}),[["合并单元格","合并",()=>o.mergeSelection()],["拆分单元格","拆分",()=>o.unmergeSelection()]].forEach(([g,v,y])=>{const k=document.createElement("button");k.type="button",k.className="colwork-table__format colwork-table__grid-action",k.title=g,k.textContent=v,k.addEventListener("mousedown",A=>A.preventDefault()),k.addEventListener("click",y),h.append(k)}),(O=m.querySelector(".colwork-table__group-label"))==null||O.remove();const b=document.createElement("button");b.type="button",b.className="colwork-table__format colwork-table__dropdown-trigger",b.textContent="保护",b.title="锁定、密码锁定与解锁",b.setAttribute("aria-label","保护"),b.setAttribute("aria-expanded","false"),b.addEventListener("mousedown",g=>g.preventDefault()),b.addEventListener("click",()=>{if(b.getAttribute("aria-expanded")==="true"){o.hideContextMenu();return}const g=b.getBoundingClientRect();o.showContextMenu(g.left,g.bottom+4,[{label:"锁定与解锁",actions:o.protectionActions()}]),b.setAttribute("aria-expanded","true")}),b.addEventListener("keydown",g=>{g.key==="ArrowDown"&&(g.preventDefault(),b.click())}),m.append(b);const L=document.createElement("div");L.className="colwork-table__view-control";const $=document.createElement("button");$.type="button",$.className="colwork-table__format",$.textContent="视图",$.setAttribute("aria-label","视图"),$.classList.add("colwork-table__dropdown-trigger"),$.title="本地视图选项";const N=document.createElement("div");N.className="colwork-table__view-menu",[["隔行异色",()=>o.view.bandedRows,g=>{o.view.bandedRows=g}],["显示网格线",()=>o.view.showGridLines,g=>{o.view.showGridLines=g}]].forEach(([g,v,y])=>{const k=document.createElement("label"),A=document.createElement("input");A.type="checkbox",A.checked=v(),A.addEventListener("change",()=>{y(A.checked),o.render()}),k.append(A,document.createTextNode(g)),N.append(k)}),[["固定至选中行",()=>o.freezeSelection("row")],["固定至选中列",()=>o.freezeSelection("column")],["取消固定",()=>o.setFrozenPanes(0,0)]].forEach(([g,v])=>{const y=document.createElement("button");y.type="button",y.textContent=g,y.addEventListener("mousedown",k=>k.preventDefault()),y.addEventListener("click",v),N.append(y)}),L.append($,N),a.append(L),[["bold","B","加粗"],["italic","I","斜体"],["underline","U","下划线"],["strike","S","删除线"],["wrap","换行","自动换行"],["align-left","左","左对齐"],["align-center","中","居中"],["align-right","右","右对齐"]].forEach(([g,v,y])=>{const k=document.createElement("button");k.type="button",k.className=`colwork-table__format colwork-table__format--${g}`,k.textContent=v,k.title=y,k.addEventListener("mousedown",A=>A.preventDefault()),k.addEventListener("click",()=>g.startsWith("align-")?o.setStyle("align",g.slice(6)):o.toggleFormat(g)),(g.startsWith("align-")||g==="wrap"?d:l).append(k)});const p=document.createElement("select");p.className="colwork-table__select",p.title="字体大小",[10,12,14,16,18,24].forEach(g=>{const v=document.createElement("option");v.value=String(g),v.textContent=`${g}px`,p.append(v)}),p.addEventListener("change",()=>o.setStyle("fontSize",Number(p.value))),l.append(p);const E=document.createElement("select");E.className="colwork-table__select",E.title="单元格格式",[["general","常规"],["number","数字"],["date","日期"],["percent","百分比"]].forEach(([g,v])=>{const y=document.createElement("option");y.value=g,y.textContent=v,E.append(y)}),E.addEventListener("change",()=>o.setStyle("format",E.value)),f.append(E);const x=document.createElement("button");x.type="button",x.className="colwork-table__format",x.title="清除格式",x.textContent="清除",x.addEventListener("mousedown",g=>g.preventDefault()),x.addEventListener("click",()=>o.clearFormatting()),f.append(x);const R=document.createElement("div");R.className="colwork-table__border-control";const C=document.createElement("button");C.type="button",C.className="colwork-table__format",C.title="边框选项",C.textContent="边框",C.setAttribute("aria-label","边框"),C.classList.add("colwork-table__dropdown-trigger");const q=document.createElement("div");return q.className="colwork-table__border-menu",[["外围","outer"],["中间","inner"],["横线","horizontal"],["竖线","vertical"]].forEach(([g,v])=>{const y=document.createElement("button");y.type="button",y.textContent=g,y.addEventListener("click",()=>o.toggleBorder(v)),q.append(y)}),R.append(C,q),f.insertBefore(R,x),[["color","文字颜色"],["background","背景颜色"]].forEach(([g,v])=>{const y=document.createElement("input");y.type="color",y.className=`colwork-table__color colwork-table__color--${g}`,y.title=v,y.addEventListener("input",()=>o.setStyle(g,y.value)),(g==="color"?l:f).append(y)}),{toolbar:s,undoButton:e,redoButton:t,protectionButton:b}}function at(o,e,t,s){const n=new Map,r=(i,c,h,m,a)=>{const l=[];h>0&&i<h&&l.push([i,Math.min(c,h-1)]);const d=Math.max(i,h,m),f=Math.min(c,a);return d<=f&&l.push([d,f]),l};for(const i of o){const c=r(i.start.row,i.end.row,t,e.top,e.bottom),h=r(i.start.column,i.end.column,s,e.left,e.right);for(const[m,a]of c)for(const[l,d]of h){const f={source:i,start:{row:m,column:l},end:{row:a,column:d}};for(let S=m;S<=a;S++)for(let M=l;M<=d;M++)n.set(H({row:S,column:M}),f)}}return n}function lt(o,e){return o.start.row===e.row&&o.start.column===e.column}const ct=54,ht=42,ze=12,dt=56,ut=150,Me=28,xe=64,mt=.25,ft=2;function gt(o){let e=o+1,t="";for(;e>0;)e-=1,t=String.fromCharCode(65+e%26)+t,e=Math.floor(e/26);return t}function pt(o){const{rowCount:e,columnCount:t}=o,s=w=>o.getRowHeight(w),n=w=>o.getColumnWidth(w),r=We({scrollTop:o.viewport.scrollTop,scrollLeft:o.viewport.scrollLeft,clientHeight:o.viewport.clientHeight||560,clientWidth:o.viewport.clientWidth||900,rowCount:e,columnCount:t,rowSize:s,columnSize:n,overscan:4}),i=at(o.getMergeRanges(),r,o.frozenRows,o.frozenColumns);r.bottom=Math.max(r.bottom,o.frozenRows-1),r.right=Math.max(r.right,o.frozenColumns-1);const c=Math.max(o.frozenRows,r.top),h=Math.max(o.frozenColumns,r.left),m=(w,p,E)=>[...Array.from({length:w},(x,R)=>R),-1,...Array.from({length:Math.max(0,E-p+1)},(x,R)=>p+R)],a=m(o.frozenRows,c,r.bottom),l=m(o.frozenColumns,h,r.right),d=P(h,n)-P(o.frozenColumns,n),f=P(c,s)-P(o.frozenRows,s),S=(w,p,E)=>{const x=p>=0&&p<o.frozenRows,R=E>=0&&E<o.frozenColumns;!x&&!R||(w.classList.add("is-frozen"),w.style.position="sticky",x&&(w.style.top=`${o.columnHeaderHeight+P(p,s)}px`),R&&(w.style.left=`${o.rowHeaderWidth+P(E,n)}px`),w.style.zIndex=String(p<0?10:E<0?8:x&&R?5:x?4:3))},M=document.createElement("thead"),b=document.createElement("tr"),L=document.createElement("th");L.style.width=`${o.rowHeaderWidth}px`,L.style.height=`${o.columnHeaderHeight}px`,L.addEventListener("mousedown",w=>{w.preventDefault(),w.stopPropagation(),o.selectRange({row:0,column:0},{row:e-1,column:t-1},"all")}),b.append(L);const $=w=>{const p=document.createElement("th");return p.style.width=`${w}px`,p.style.padding="0",p.style.border="0",p};for(const w of l){if(w===-1){b.append($(d));continue}const p=document.createElement("th");p.style.width=`${n(w)}px`,p.style.height=`${o.columnHeaderHeight}px`,p.style.fontSize=`${ze*o.zoomRatio}px`;const E=document.createElement("b");E.className="colwork-table__column-letter",E.textContent=gt(w),p.append(E),o.addResizeHandle(p,"column",w),o.addHeaderSelection(p,"column",w),S(p,-1,w),b.append(p)}b.append($(X(t,n)-P(r.right+1,n))),M.append(b);const N=document.createElement("tbody"),j=w=>{const p=document.createElement("tr");p.className="colwork-table__spacer",p.style.height=`${w}px`;const E=document.createElement("td");return E.colSpan=l.length+2,E.style.height=`${w}px`,p.append(E),p};for(const w of a){if(w===-1){N.append(j(f));continue}const p=document.createElement("tr");o.bandedRows&&w%2===1&&(p.className="is-banded-row"),p.style.height=`${s(w)}px`;const E=document.createElement("th");E.style.width=`${o.rowHeaderWidth}px`,E.style.height=`${s(w)}px`,E.style.fontSize=`${ze*o.zoomRatio}px`,E.textContent=String(w+1),o.addResizeHandle(E,"row",w),o.addHeaderSelection(E,"row",w),p.append(E),S(E,w,-1);for(const R of l){if(R===-1){const k=document.createElement("td");k.style.width=`${d}px`,k.style.padding="0",k.style.border="0",p.append(k);continue}const C=i.get(H({row:w,column:R}));if(C&&!lt(C,{row:w,column:R}))continue;const q=(C==null?void 0:C.source.start)??{row:w,column:R},O=H(q),g=document.createElement("td");g.style.width=`${n(R)}px`,g.style.height=`${s(w)}px`,g.dataset.key=O,C&&(g.rowSpan=C.end.row-C.start.row+1,g.colSpan=C.end.column-C.start.column+1,g.dataset.renderRow=String(C.start.row),g.dataset.renderColumn=String(C.start.column),g.dataset.renderBottom=String(C.end.row),g.dataset.renderRight=String(C.end.column));const v=document.createElement("span");v.className="colwork-table__cell-value",v.style.height=`${Math.max(0,s(w)-4)}px`,v.style.maxHeight=`${Math.max(0,s(w)-4)}px`,v.textContent=o.displayValue(O),o.applyStyle(v,O),g.append(v),o.applyStyle(g,O),S(g,w,R);const y=o.isCellLocked(O,(C==null?void 0:C.source)??null);g.classList.toggle("is-locked",y),g.classList.toggle("is-password-locked",o.isCellPasswordLocked(O,(C==null?void 0:C.source)??null)),g.setAttribute("aria-readonly",String(o.readOnly||y)),y&&(g.title=o.isCellPasswordLocked(O,(C==null?void 0:C.source)??null)?"密码锁定:验证密码后可编辑":"已锁定:解锁后可编辑"),o.attachCellListeners(g,O,q.row,q.column),p.append(g)}const x=document.createElement("td");x.style.width=`${X(t,n)-P(r.right+1,n)}px`,x.style.padding="0",x.style.border="0",p.append(x),N.append(p)}N.append(j(X(e,s)-P(r.bottom+1,s))),o.table.style.setProperty("--colwork-zoom",String(o.zoomRatio)),o.table.style.width=`${o.rowHeaderWidth+X(t,n)}px`,o.table.classList.toggle("is-grid-hidden",!o.showGridLines),o.table.classList.toggle("is-banded-rows",o.bandedRows),o.table.style.fontSize=`${o.zoomRatio}em`,o.table.replaceChildren(M,N)}class wt{constructor(e,t,s,n){this.doc=e,this.cells=t,this.styles=s,this.host=n}readStyle(e){try{const t=JSON.parse(this.styles.get(e)??"{}");return oe(t)?t:{}}catch{return{}}}applyStyle(e,t){var n,r,i,c;const s=this.readStyle(t);e.style.fontWeight=s.bold?"700":"",e.style.fontStyle=s.italic?"oblique":"",e.style.textDecoration=[s.underline?"underline":"",s.strike?"line-through":""].filter(Boolean).join(" "),e.style.transform=e.classList.contains("colwork-table__cell-value")&&s.italic?"skewX(-8deg)":"",e.style.fontSize=s.fontSize?`${s.fontSize*this.host.zoom()}px`:"",e.style.color=s.color??"",e.style.backgroundColor=s.background??"",e.style.textAlign=s.align??"",e.classList.contains("colwork-table__cell-value")&&(e.style.whiteSpace=s.wrap?"pre-wrap":"pre"),!e.classList.contains("colwork-table__cell-value")&&!e.classList.contains("colwork-table__editor")&&(e.style.borderTop=(n=s.border)!=null&&n.top?"2px solid #64748b":"",e.style.borderRight=(r=s.border)!=null&&r.right?"2px solid #64748b":"",e.style.borderBottom=(i=s.border)!=null&&i.bottom?"2px solid #64748b":"",e.style.borderLeft=(c=s.border)!=null&&c.left?"2px solid #64748b":"")}displayValue(e){const t=this.cells.get(e)??"",s=this.readStyle(e).format??"general";if(!t||s==="general")return t;if(s==="number"){const r=Number(t);return Number.isFinite(r)?r.toLocaleString():t}if(s==="percent"){const r=Number(t.replace(/%$/,""));return Number.isFinite(r)?`${t.endsWith("%")?r:r*100}%`:t}const n=new Date(t);return Number.isNaN(n.getTime())?t:n.toISOString().slice(0,10)}toggleFormat(e){if(!this.host.canEdit()||!this.host.selectedKey())return;const{top:t,bottom:s,left:n,right:r}=this.host.bounds(),i=this.readStyle(this.host.selectedKey())[e];this.doc.transact(()=>{for(let c=t;c<=s;c+=1)for(let h=n;h<=r;h+=1){const m=`${c}:${h}`,a=this.readStyle(m);a[e]=!i,this.styles.set(m,JSON.stringify(a))}},this.host.origin),this.host.render()}clearFormatting(){if(!this.host.canEdit()||!this.host.selectedKey())return;const{top:e,bottom:t,left:s,right:n}=this.host.bounds();this.doc.transact(()=>{for(let r=e;r<=t;r+=1)for(let i=s;i<=n;i+=1)this.styles.delete(H({row:r,column:i}))},this.host.origin),this.host.render()}toggleBorder(e){if(!this.host.canEdit()||!this.host.selectedKey())return;const{top:t,bottom:s,left:n,right:r}=this.host.bounds(),i=(a,l)=>{const d=[];return e==="outer"&&(a===t&&d.push("top"),a===s&&d.push("bottom"),l===n&&d.push("left"),l===r&&d.push("right")),(e==="inner"||e==="horizontal")&&a<s&&d.push("bottom"),(e==="inner"||e==="vertical")&&l<r&&d.push("right"),d},c=Array.from({length:s-t+1},(a,l)=>Array.from({length:r-n+1},(d,f)=>({row:t+l,column:n+f}))).flat();if(!c.flatMap(({row:a,column:l})=>i(a,l)).length)return;const m=!c.every(({row:a,column:l})=>i(a,l).every(d=>{var f;return(f=this.readStyle(H({row:a,column:l})).border)==null?void 0:f[d]}));this.doc.transact(()=>{for(let a=t;a<=s;a+=1)for(let l=n;l<=r;l+=1){const d=H({row:a,column:l}),f=this.readStyle(d),S={...f.border??{}};i(a,l).forEach(M=>{m?S[M]=!0:delete S[M]}),Object.keys(S).length?f.border=S:delete f.border,this.styles.set(d,JSON.stringify(f))}},this.host.origin),this.host.render()}setStyle(e,t){if(!this.host.canEdit()||!this.host.selectedKey())return;const{top:s,bottom:n,left:r,right:i}=this.host.bounds();this.doc.transact(()=>{for(let c=s;c<=n;c+=1)for(let h=r;h<=i;h+=1){const m=`${c}:${h}`,a=this.readStyle(m);e==="align"?a.align=t:e==="color"?a.color=t:e==="background"?a.background=t:e==="fontSize"?a.fontSize=t:a.format=t,this.styles.set(m,JSON.stringify(a))}},this.host.origin),this.host.render()}}const re=6e5,ie=o=>Array.from(o,e=>e.toString(16).padStart(2,"0")).join("");async function Le(o,e){var s;if(!((s=globalThis.crypto)!=null&&s.subtle))throw new Error("密码锁定需要 HTTPS 或 localhost 环境");const t=await crypto.subtle.importKey("raw",new TextEncoder().encode(o),"PBKDF2",!1,["deriveBits"]);return new Uint8Array(await crypto.subtle.deriveBits({name:"PBKDF2",hash:"SHA-256",salt:e,iterations:re},t,256))}async function yt(o){var s;if(!o.length)throw new Error("密码不能为空");if(!((s=globalThis.crypto)!=null&&s.subtle))throw new Error("密码锁定需要 HTTPS 或 localhost 环境");const e=crypto.getRandomValues(new Uint8Array(16)),t={version:1,algorithm:"PBKDF2-SHA-256",iterations:re,salt:ie(e),verifier:ie(await Le(o,e))};return JSON.stringify(t)}async function bt(o,e){let t;try{t=JSON.parse(o)}catch{throw new Error("锁定数据无效,无法解锁")}if(!t||t.version!==1||t.algorithm!=="PBKDF2-SHA-256"||t.iterations!==re||typeof t.salt!="string"||!/^[0-9a-f]{32}$/.test(t.salt)||typeof t.verifier!="string"||!/^[0-9a-f]{64}$/.test(t.verifier))throw new Error("锁定数据无效或版本不受支持,无法解锁");const s=Uint8Array.from(t.salt.match(/../g),i=>parseInt(i,16)),n=ie(await Le(e,s));let r=0;for(let i=0;i<n.length;i+=1)r|=n.charCodeAt(i)^t.verifier.charCodeAt(i);return r===0}class St{constructor(e,t){u(this,"session");u(this,"doc");u(this,"sheet");u(this,"cells");u(this,"styles");u(this,"rowHeights");u(this,"columnWidths");u(this,"locks");u(this,"pointer");u(this,"clipboard");u(this,"selection");u(this,"formatting");u(this,"dialogs");u(this,"destroyed",!1);u(this,"editEpoch",0);u(this,"frozenRows",0);u(this,"frozenColumns",0);u(this,"merges");u(this,"undoManager");u(this,"provider");u(this,"awareness");u(this,"root");u(this,"options");u(this,"toolbar");u(this,"table");u(this,"viewportResizeObserver");u(this,"viewport");u(this,"frozenBoundaryLayer");u(this,"protectionMenuButton");u(this,"menu");u(this,"undoButton");u(this,"redoButton");u(this,"dimensions");u(this,"zoomRatio",1);u(this,"showGridLines",!0);u(this,"bandedRows",!1);u(this,"readOnly");u(this,"archive");u(this,"resizing");u(this,"onCellsChange",()=>{this.expandLogicalSizeFromDocument()?this.render():this.refreshValues()});u(this,"onStylesChange",()=>{this.expandLogicalSizeFromDocument()?this.render():this.refreshStyles()});u(this,"onSizesChange",()=>this.render());u(this,"onMergesChange",()=>this.render());u(this,"onLocksChange",()=>{this.undoManager.clear(),this.editing.key&&this.sheet.isCellLocked(this.editing.key)&&this.editing.finish(!1),this.resizing&&this.sheet.isAxisLocked(this.resizing.axis,this.resizing.index)&&(this.resizing=void 0,this.viewport.classList.remove("is-resizing")),this.render()});u(this,"onAwarenessChange",()=>{this.table&&(this.expandForRemoteSelections()?this.render():this.refreshCursors())});u(this,"renderFrame");u(this,"onViewportScroll",()=>{this.renderFrame===void 0&&(this.renderFrame=requestAnimationFrame(()=>{this.renderFrame=void 0,this.expandLogicalSpace(),this.render()}))});u(this,"onViewportWheel",e=>{if(!e.ctrlKey)return;e.preventDefault();const t=e.deltaY<0?1.1:.9;this.zoomRatio=Math.max(mt,Math.min(ft,this.zoomRatio*t)),this.expandLogicalSpace(),this.render()});u(this,"onViewportKeyDown",e=>{if(this.readOnly||this.editing.input)return;const t=e.ctrlKey||e.metaKey;if(t&&e.key.toLowerCase()==="z"){e.preventDefault(),e.shiftKey?this.redo():this.undo();return}if(t&&e.key.toLowerCase()==="y"){e.preventDefault(),this.redo();return}if(e.key!==" "||!this.selection.focus)return;const s=`${this.selection.focus.row}:${this.selection.focus.column}`,n=this.table.querySelector(`td[data-key="${s}"]`);n&&(e.preventDefault(),this.editing.start(n,s))});u(this,"onTableMouseDown",e=>{e.target.closest("th")&&e.preventDefault()});u(this,"onDocumentMouseDown",e=>{var t;!this.menu.contains(e.target)&&!((t=this.protectionMenuButton)!=null&&t.contains(e.target))&&this.menu.hide()});u(this,"onWindowMouseUp",e=>{if(this.resizing){const t=this.resizing;this.doc.transact(()=>{(t.axis==="row"?this.rowHeights:this.columnWidths).set(String(t.index),t.currentSize/this.zoomRatio)},this),this.resizing=void 0,this.viewport.classList.remove("is-resizing");return}this.pointer.release(e)});u(this,"onWindowBlur",()=>this.pointer.blur());u(this,"onWindowMouseMove",e=>{if(this.pointer.headerSelecting&&!(e.buttons&1)&&this.onWindowBlur(),!this.resizing)return;const t=this.resizing.axis==="row"?e.clientY-this.resizing.start:e.clientX-this.resizing.start,s=(this.resizing.axis==="row"?Me:xe)*this.zoomRatio,n=Math.max(s,this.resizing.size+t);this.resizing.currentSize=n,this.render()});u(this,"onHistoryChange",()=>this.refreshHistoryButtons());u(this,"editing");var m;this.root=e,this.options=t,this.readOnly=t.readOnly===!0,this.dimensions=new Ne(t),this.session=new tt(t),this.doc=this.session.document,this.awareness=this.session.awareness,this.provider=this.session.provider,this.sheet=new nt(this.doc,this),this.cells=this.sheet.cells,this.styles=this.sheet.styles,this.rowHeights=this.sheet.rowHeights,this.columnWidths=this.sheet.columnWidths,this.merges=this.sheet.merges,this.locks=this.sheet.locks,this.selection=new Te({sheet:this.sheet,session:this.session,dimensions:()=>({rows:this.rowCount,columns:this.columnCount}),editingKey:()=>{var a;return(a=this.editing)==null?void 0:a.key},refresh:()=>this.refreshSelection()}),this.formatting=new wt(this.doc,this.cells,this.styles,{origin:this,zoom:()=>this.zoomRatio,canEdit:()=>!this.readOnly&&!this.destroyed&&!this.selectionHasLocks(),selectedKey:()=>this.selection.selectedKey,bounds:()=>this.selection.getSelectionBounds(),render:()=>this.render()}),this.dialogs=new st({readOnly:()=>this.readOnly,destroyed:()=>this.destroyed,selectionFocus:()=>this.selection.focus,selectionAnchor:()=>this.selection.anchor,restoreSelection:(a,l)=>{this.selection.anchor=a,this.selection.focus=l},root:()=>this.root,locks:this.locks,hideMenu:()=>this.menu.hide(),setSelectionLocked:(a,l)=>this.setSelectionLocked(a,l)});const s=t.transport==="webrtc";this.log(`room:${t.room}`),this.archive=new Qe(this.sheet,this.awareness,this.provider,t.room,a=>this.log(a),!!t.onLog),this.awareness.on("change",this.onAwarenessChange),s&&this.provider&&this.archive.inspectConnections();const n=document.createElement("section");n.className="colwork-table",this.viewport=document.createElement("div"),this.viewport.className="colwork-table__viewport",this.menu=new rt(this.viewport,()=>{var a;return(a=this.protectionMenuButton)==null?void 0:a.setAttribute("aria-expanded","false")}),this.viewport.addEventListener("scroll",this.onViewportScroll),this.viewport.addEventListener("wheel",this.onViewportWheel,{passive:!1}),this.viewport.tabIndex=0,this.viewport.addEventListener("keydown",this.onViewportKeyDown),window.addEventListener("mouseup",this.onWindowMouseUp),window.addEventListener("mousemove",this.onWindowMouseMove),window.addEventListener("blur",this.onWindowBlur),document.addEventListener("mousedown",this.onDocumentMouseDown),this.table=document.createElement("table"),this.editing=new ot({table:this.table,canEdit:a=>!this.readOnly&&!this.destroyed&&!this.sheet.isCellLocked(a),read:a=>this.cells.get(a),write:(a,l)=>this.doc.transact(()=>this.cells.set(a,l),this),applyStyle:(a,l)=>this.formatting.applyStyle(a,l),displayValue:a=>this.formatting.displayValue(a),announce:a=>this.selection.sendAwareness(a),focus:()=>this.selection.focus,clearEditingPresence:()=>{this.destroyed||this.session.finishEditing()},changed:a=>{var l,d;return(d=(l=this.options).onEditingChange)==null?void 0:d.call(l,a)},refresh:()=>{this.refreshSelection(),this.refreshCursors()},render:()=>{this.destroyed||this.render()}}),this.clipboard=new Ve({sheet:this.sheet,selection:this.selection,editing:this.editing,formatting:this.formatting,canEdit:()=>!this.readOnly&&!this.destroyed,dimensions:()=>({rows:this.rowCount,columns:this.columnCount}),render:()=>this.render(),origin:this}),this.pointer=new Fe({selection:this.selection,menu:this.menu,viewport:this.viewport,editing:this.editing,dialogs:this.dialogs,clipboard:this.clipboard,canEdit:()=>!this.readOnly&&!this.destroyed,freezeSelection:a=>this.freezeSelection(a),setFrozenPanes:(a,l)=>this.setFrozenPanes(a,l),modifyAxis:(a,l,d)=>this.modifyAxis(a,l,d),deleteRows:()=>this.deleteRows(),deleteColumns:()=>this.deleteColumns(),mergeSelection:()=>this.mergeSelection(),unmergeSelection:()=>this.unmergeSelection(),clearSelectionContents:()=>this.clearSelectionContents(),refreshSelection:()=>this.refreshSelection()}),this.table.addEventListener("mousedown",this.onTableMouseDown),this.viewport.addEventListener("copy",this.clipboard.onCopy,!0),this.viewport.addEventListener("paste",this.clipboard.onPaste,!0),this.viewport.append(this.table),this.frozenBoundaryLayer=document.createElement("div"),this.frozenBoundaryLayer.className="colwork-table__frozen-boundaries",this.frozenBoundaryLayer.setAttribute("aria-hidden","true");const r=this,i=it({readOnly:this.readOnly,view:{get bandedRows(){return r.bandedRows},set bandedRows(a){r.bandedRows=a},get showGridLines(){return r.showGridLines},set showGridLines(a){r.showGridLines=a}},undo:()=>this.undo(),redo:()=>this.redo(),mergeSelection:()=>this.mergeSelection(),unmergeSelection:()=>this.unmergeSelection(),hideContextMenu:()=>this.menu.hide(),showContextMenu:(a,l,d)=>this.menu.show(a,l,d),protectionActions:()=>this.pointer.protectionActions(),freezeSelection:a=>this.freezeSelection(a),setFrozenPanes:(a,l)=>this.setFrozenPanes(a,l),render:()=>this.render(),setStyle:(a,l)=>this.formatting.setStyle(a,l),toggleFormat:a=>this.formatting.toggleFormat(a),clearFormatting:()=>this.formatting.clearFormatting(),toggleBorder:a=>this.formatting.toggleBorder(a)});this.toolbar=i.toolbar,this.undoButton=i.undoButton,this.redoButton=i.redoButton,this.protectionMenuButton=i.protectionButton,n.append(this.toolbar,this.viewport,this.frozenBoundaryLayer),e.replaceChildren(n);const c=!this.session.external&&!this.readOnly&&!t.snapshot&&!((m=t.updates)!=null&&m.length),h=c&&this.cells.size===0&&this.locks.size===0;c&&!t.initializeAfterSync&&this.sheet.seed(t.rows??he),h&&!t.initializeAfterSync&&de(this.sheet),this.expandLogicalSizeFromDocument(),this.undoManager=new W.UndoManager([this.cells,this.styles,this.rowHeights,this.columnWidths,this.merges],{captureTimeout:500,trackedOrigins:this.session.external?new Set([this]):new Set([null,this])}),this.undoManager.on("stack-item-added",this.onHistoryChange),this.undoManager.on("stack-item-popped",this.onHistoryChange),this.undoManager.on("stack-cleared",this.onHistoryChange),this.render(),this.refreshHistoryButtons(),this.cells.observe(this.onCellsChange),this.styles.observe(this.onStylesChange),this.rowHeights.observe(this.onSizesChange),this.columnWidths.observe(this.onSizesChange),this.merges.observe(this.onMergesChange),this.locks.observe(this.onLocksChange),this.viewportResizeObserver=new ResizeObserver(()=>fe(this.frozenBoundaryLayer,this.viewport,this.frozenRows,this.frozenColumns,this.rowHeaderWidth,this.columnHeaderHeight,(a,l)=>a==="row"?this.getRowHeight(l):this.getColumnWidth(l))),this.viewportResizeObserver.observe(this.viewport),Oe(this.session,t,this.sheet,c,{canEdit:()=>!this.readOnly&&!this.destroyed,log:a=>this.log(a),inspect:()=>this.archive.inspectConnections(),clearHistory:()=>this.undoManager.clear(),render:()=>this.render()})}log(e){var t,s;(s=(t=this.options).onLog)==null||s.call(t,`${new Date().toLocaleTimeString()} ${e}`)}undo(){this.readOnly||!this.undoManager.canUndo()||(this.editing.input&&this.editing.finish(!0),this.undoManager.undo())}redo(){this.readOnly||!this.undoManager.canRedo()||(this.editing.input&&this.editing.finish(!0),this.undoManager.redo())}refreshHistoryButtons(){this.undoButton&&(this.undoButton.disabled=this.readOnly||!this.undoManager.canUndo()),this.redoButton&&(this.redoButton.disabled=this.readOnly||!this.undoManager.canRedo())}setReadOnly(e){this.destroyed||this.readOnly===e||(this.readOnly=e,this.editEpoch++,this.editing.finish(!1),this.resizing=void 0,this.viewport.classList.remove("is-resizing"),this.pointer.cancel(),this.dialogs.close(),this.menu.hide(),this.toolbar.hidden=e,this.undoManager.clear(),this.refreshHistoryButtons(),this.render())}commitEditing(){this.destroyed||this.editing.finish(!0)}cancelEditing(){this.destroyed||this.editing.finish(!1)}getYjsSnapshot(){return this.archive.snapshot()}getYjsUpdateLog(){return this.archive.updateLog()}setFrozenPanes(e,t){if(this.destroyed)return!1;if(![e,t].every(r=>Number.isInteger(r)&&r>=0))throw new RangeError("Frozen row and column counts must be non-negative integers");const s=Math.min(e,this.rowCount-1),n=Math.min(t,this.columnCount-1);return this.sheet.hasPartialMerge("row",0,s-1)||this.sheet.hasPartialMerge("column",0,n-1)?(this.dialogs.showLockMessage("当前选择包含不完整的合并块,无法固定,请选择完整的合并块"),!1):(this.editing.finish(!0),this.frozenRows=s,this.frozenColumns=n,this.dialogs.closeLockMessage(),this.render(),!0)}crossesFrozenBoundary(e){return e.start.row<this.frozenRows&&e.end.row>=this.frozenRows||e.start.column<this.frozenColumns&&e.end.column>=this.frozenColumns}freezeSelection(e){if(!this.selection.focus)return;const t=_(this.selection.anchor,this.selection.focus);if(this.sheet.hasPartialMerge(e,t.start[e],t.end[e])){this.dialogs.showLockMessage("当前选择包含不完整的合并块,无法固定,请选择完整的合并块");return}this.setFrozenPanes(e==="row"?t.end.row+1:this.frozenRows,e==="column"?t.end.column+1:this.frozenColumns)}selectionHasLocks(){return this.sheet.rangeHasLocks(_(this.selection.anchor,this.selection.focus))}async setSelectionLocked(e,t){if(this.readOnly||this.destroyed||!this.selection.focus)return;this.editing.finish(!0);const s=this.sheet.expandSelectionToMerges(this.selection.anchor??this.selection.focus,this.selection.focus),n=_(s.anchor,s.focus),r=[];for(let a=n.start.row;a<=n.end.row;a+=1)for(let l=n.start.column;l<=n.end.column;l+=1)r.push(H({row:a,column:l}));const i=[...new Set(r.map(a=>this.locks.get(a)).filter(a=>a!==void 0&&a!=="1"))];if(e&&i.length)throw new Error("选区包含密码锁定单元格,请先用原密码解锁");const c=this.archive.revision,h=this.editEpoch;let m="1";if(e&&t!==void 0&&(m=await yt(t)),!e&&i.length){if(!t)throw new Error("请输入解锁密码");for(const a of i)if(!await bt(a,t))throw new Error("密码不正确,选区未解锁")}if(!(this.destroyed||this.readOnly||h!==this.editEpoch)){if(c!==this.archive.revision)throw new Error("表格内容或锁定状态已变化,请重试");this.doc.transact(()=>{r.forEach(a=>{e?this.locks.set(a,m):this.locks.delete(a)})},this)}}get rowCount(){return this.dimensions.rows}get columnCount(){return this.dimensions.columns}get rowHeaderWidth(){return ct*this.zoomRatio}get columnHeaderHeight(){return ht*this.zoomRatio}getRowHeight(e){var t;return((t=this.resizing)==null?void 0:t.axis)==="row"&&this.resizing.index===e?this.resizing.currentSize:Math.max(Me,this.rowHeights.get(String(e))??dt)*this.zoomRatio}getColumnWidth(e){var t;return((t=this.resizing)==null?void 0:t.axis)==="column"&&this.resizing.index===e?this.resizing.currentSize:Math.max(xe,this.columnWidths.get(String(e))??ut)*this.zoomRatio}beginResize(e,t,s){s.preventDefault(),s.stopPropagation(),!(s.button!==0||this.readOnly||this.sheet.isAxisLocked(e,t))&&(this.editing.finish(!0),this.pointer.selecting=!1,this.pointer.headerSelecting=void 0,this.resizing={axis:e,index:t,start:e==="row"?s.clientY:s.clientX,size:e==="row"?this.getRowHeight(t):this.getColumnWidth(t),currentSize:e==="row"?this.getRowHeight(t):this.getColumnWidth(t)},this.viewport.classList.add("is-resizing"))}addResizeHandle(e,t,s){const n=document.createElement("span");n.className=`colwork-table__resize-handle colwork-table__resize-handle--${t}`,n.addEventListener("mousedown",r=>this.beginResize(t,s,r)),e.append(n)}mergeSelection(){if(this.readOnly||this.selectionHasLocks())return;const e=_(this.selection.anchor,this.selection.focus);if(!(e.start.row===e.end.row&&e.start.column===e.end.column)){if(this.crossesFrozenBoundary(e)){this.dialogs.showLockMessage("合并范围同时包含固定和非固定区域,无法合并,请调整选区或取消固定");return}this.dialogs.closeLockMessage(),this.doc.transact(()=>{this.sheet.getMergeRanges().forEach(t=>{(F(e,t.start)||F(t,e.start))&&this.merges.delete(this.sheet.mergeKey(t))}),this.merges.set(this.sheet.mergeKey(e),"1")},this)}}unmergeSelection(){if(this.readOnly||this.selectionHasLocks())return;const e=_(this.selection.anchor,this.selection.focus);this.doc.transact(()=>this.sheet.getMergeRanges().forEach(t=>{(F(e,t.start)||F(t,e.start))&&this.merges.delete(this.sheet.mergeKey(t))}),this)}modifyAxis(e,t,s,n=0){this.readOnly||s===0||this.sheet.isAxisLocked(e,t,!0)||(this.sheet.modifyAxis(e,t,s,n),e==="row"?this.dimensions.rows=Math.max(1,this.dimensions.rows+s):this.dimensions.columns=Math.max(1,this.dimensions.columns+s),this.render())}deleteRows(){const e=_(this.selection.anchor,this.selection.focus),t=Math.min(e.end.row-e.start.row+1,this.rowCount-1);this.modifyAxis("row",e.start.row,-t,t)}deleteColumns(){const e=_(this.selection.anchor,this.selection.focus),t=Math.min(e.end.column-e.start.column+1,this.columnCount-1);this.modifyAxis("column",e.start.column,-t,t)}expandLogicalSpace(){return this.dimensions.expandViewport(this.viewport,this.selection)}expandForRemoteSelections(){return this.dimensions.expandRemote(this.awareness)}clearSelectionContents(){if(this.readOnly||this.selectionHasLocks())return;const e=_(this.selection.anchor,this.selection.focus);this.doc.transact(()=>{for(let t=e.start.row;t<=e.end.row;t+=1)for(let s=e.start.column;s<=e.end.column;s+=1)this.cells.delete(H({row:t,column:s}))},this)}expandLogicalSizeFromDocument(){return this.dimensions.expandDocument(this.sheet)}render(){this.editing.input&&this.editing.finish(!0),this.expandLogicalSizeFromDocument(),this.frozenRows=Math.min(this.frozenRows,this.rowCount-1),this.frozenColumns=Math.min(this.frozenColumns,this.columnCount-1);const e=this.sheet.hasPartialMerge("row",0,this.frozenRows-1),t=this.sheet.hasPartialMerge("column",0,this.frozenColumns-1);(e||t)&&(e&&(this.frozenRows=0),t&&(this.frozenColumns=0),this.dialogs.showLockMessage("合并区域已变化,已取消与合并块冲突的固定行列")),pt({table:this.table,viewport:this.viewport,rowCount:this.rowCount,columnCount:this.columnCount,frozenRows:this.frozenRows,frozenColumns:this.frozenColumns,zoomRatio:this.zoomRatio,rowHeaderWidth:this.rowHeaderWidth,columnHeaderHeight:this.columnHeaderHeight,bandedRows:this.bandedRows,showGridLines:this.showGridLines,readOnly:this.readOnly,getRowHeight:s=>this.getRowHeight(s),getColumnWidth:s=>this.getColumnWidth(s),getMergeRanges:()=>this.sheet.getMergeRanges(),isCellLocked:(s,n)=>this.sheet.isCellLocked(s,n),isCellPasswordLocked:(s,n)=>this.sheet.isCellPasswordLocked(s,n),displayValue:s=>this.formatting.displayValue(s),applyStyle:(s,n)=>this.formatting.applyStyle(s,n),addResizeHandle:(s,n,r)=>this.addResizeHandle(s,n,r),addHeaderSelection:(s,n,r)=>this.pointer.addHeaderSelection(s,n,r),selectRange:(s,n,r)=>this.selection.selectRange(s,n,r),attachCellListeners:(s,n,r,i)=>this.pointer.attachCellListeners(s,n,r,i)}),fe(this.frozenBoundaryLayer,this.viewport,this.frozenRows,this.frozenColumns,this.rowHeaderWidth,this.columnHeaderHeight,(s,n)=>s==="row"?this.getRowHeight(n):this.getColumnWidth(n)),this.refreshSelection(),this.refreshCursors()}refreshValues(){Be(this.refreshView())}refreshSelection(){ge(this.refreshView())}refreshCursors(){pe(this.refreshView())}refreshStyles(){Pe(this.refreshView())}refreshView(){var e;return{table:this.table,viewport:this.viewport,editingKey:(e=this.editing)==null?void 0:e.key,formatting:this.formatting,selection:this.selection,awareness:this.awareness,userColor:this.options.userColor,rowCount:this.rowCount,columnCount:this.columnCount,size:(t,s)=>t==="row"?this.getRowHeight(s):this.getColumnWidth(s)}}destroy(){this.destroyed||(this.session.external||this.editing.finish(!0),this.destroyed=!0,this.viewportResizeObserver.disconnect(),this.dialogs.close(),this.editing.finish(!1),this.archive.destroy(),this.awareness.off("change",this.onAwarenessChange),this.cells.unobserve(this.onCellsChange),this.styles.unobserve(this.onStylesChange),this.rowHeights.unobserve(this.onSizesChange),this.columnWidths.unobserve(this.onSizesChange),this.merges.unobserve(this.onMergesChange),this.locks.unobserve(this.onLocksChange),this.undoManager.off("stack-item-added",this.onHistoryChange),this.undoManager.off("stack-item-popped",this.onHistoryChange),this.undoManager.off("stack-cleared",this.onHistoryChange),this.viewport.removeEventListener("scroll",this.onViewportScroll),this.viewport.removeEventListener("wheel",this.onViewportWheel),this.viewport.removeEventListener("keydown",this.onViewportKeyDown),this.viewport.removeEventListener("copy",this.clipboard.onCopy,!0),this.viewport.removeEventListener("paste",this.clipboard.onPaste,!0),this.table.removeEventListener("mousedown",this.onTableMouseDown),window.removeEventListener("mouseup",this.onWindowMouseUp),window.removeEventListener("mousemove",this.onWindowMouseMove),window.removeEventListener("blur",this.onWindowBlur),document.removeEventListener("mousedown",this.onDocumentMouseDown),this.menu.hide(),this.renderFrame!==void 0&&cancelAnimationFrame(this.renderFrame),this.undoManager.destroy(),this.sheet.destroy(),this.session.destroy(),this.root.replaceChildren())}}z.COLWORK_MAP_NAMES=T,z.COLWORK_SCHEMA_VERSION=Z,z.ColworkTable=St,z.cellKey=H,z.containsPosition=F,z.exportYjsSnapshot=ve,z.getSheetMaps=J,z.initializeBlankSheet=Xe,z.mergeKey=qe,z.normalizeRange=le,z.parseCellKey=K,z.parseMergeKey=Q,z.rangeSize=$e,z.readSheetSnapshot=Ee,z.readSheetSnapshotUpdate=Ze,z.rebuildYjsSnapshot=Je,z.validateSheetDocument=ne,Object.defineProperty(z,Symbol.toStringTag,{value:"Module"})}));
|