@kuzuma/colwork 0.0.0-stage → 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.
@@ -0,0 +1,7 @@
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,`
5
+ `).split(`
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"})}));
@@ -0,0 +1,324 @@
1
+ import { Awareness } from 'y-protocols/awareness';
2
+ import * as Y from 'yjs';
3
+
4
+ export declare type AwarenessSelection = {
5
+ anchor?: CellPosition;
6
+ focus?: CellPosition;
7
+ mode?: SelectionMode_2;
8
+ };
9
+
10
+ export declare type BuiltInCollaborationOptions = CommonOptions & {
11
+ room: string;
12
+ transport?: 'webrtc' | 'websocket';
13
+ collaboration?: never;
14
+ signalingUrl?: string;
15
+ websocketUrl?: string;
16
+ peerOpts?: Record<string, unknown>;
17
+ initializeAfterSync?: boolean;
18
+ rows?: string[][];
19
+ snapshot?: Uint8Array;
20
+ updates?: Uint8Array[];
21
+ };
22
+
23
+ export declare type CellBorder = {
24
+ top?: boolean;
25
+ right?: boolean;
26
+ bottom?: boolean;
27
+ left?: boolean;
28
+ };
29
+
30
+ export declare function cellKey(position: CellPosition): string;
31
+
32
+ export declare type CellLock = '1' | PasswordLock;
33
+
34
+ export declare type CellPosition = {
35
+ row: number;
36
+ column: number;
37
+ };
38
+
39
+ export declare type CellRange = {
40
+ start: CellPosition;
41
+ end: CellPosition;
42
+ };
43
+
44
+ export declare type CellStyle = {
45
+ bold?: boolean;
46
+ italic?: boolean;
47
+ underline?: boolean;
48
+ strike?: boolean;
49
+ wrap?: boolean;
50
+ border?: CellBorder;
51
+ fontSize?: number;
52
+ color?: string;
53
+ background?: string;
54
+ align?: 'left' | 'center' | 'right';
55
+ format?: 'general' | 'number' | 'date' | 'percent';
56
+ };
57
+
58
+ export declare const COLWORK_MAP_NAMES: Readonly<{
59
+ readonly cells: "cells";
60
+ readonly styles: "styles";
61
+ readonly rowHeights: "rowHeights";
62
+ readonly columnWidths: "columnWidths";
63
+ readonly merges: "merges";
64
+ readonly locks: "locks";
65
+ readonly metadata: "colwork-metadata";
66
+ }>;
67
+
68
+ /** The existing version-one wire format. Missing metadata is valid legacy data. */
69
+ export declare const COLWORK_SCHEMA_VERSION: 1;
70
+
71
+ export declare class ColworkTable {
72
+ private readonly session;
73
+ private readonly doc;
74
+ private readonly sheet;
75
+ private readonly cells;
76
+ private readonly styles;
77
+ private readonly rowHeights;
78
+ private readonly columnWidths;
79
+ private readonly locks;
80
+ private readonly pointer;
81
+ private readonly clipboard;
82
+ private readonly selection;
83
+ private readonly formatting;
84
+ private readonly dialogs;
85
+ private destroyed;
86
+ private editEpoch;
87
+ private frozenRows;
88
+ private frozenColumns;
89
+ private readonly merges;
90
+ private readonly undoManager;
91
+ private readonly provider?;
92
+ private readonly awareness;
93
+ private readonly root;
94
+ private readonly options;
95
+ private readonly toolbar;
96
+ private readonly table;
97
+ private readonly viewportResizeObserver;
98
+ private readonly viewport;
99
+ private readonly frozenBoundaryLayer;
100
+ private protectionMenuButton?;
101
+ private readonly menu;
102
+ private undoButton?;
103
+ private redoButton?;
104
+ private readonly dimensions;
105
+ private zoomRatio;
106
+ private showGridLines;
107
+ private bandedRows;
108
+ private readOnly;
109
+ private readonly archive;
110
+ private resizing?;
111
+ private readonly onCellsChange;
112
+ private readonly onStylesChange;
113
+ private readonly onSizesChange;
114
+ private readonly onMergesChange;
115
+ private readonly onLocksChange;
116
+ private readonly onAwarenessChange;
117
+ private renderFrame?;
118
+ private readonly onViewportScroll;
119
+ private readonly onViewportWheel;
120
+ private readonly onViewportKeyDown;
121
+ private readonly onTableMouseDown;
122
+ private readonly onDocumentMouseDown;
123
+ private readonly onWindowMouseUp;
124
+ private readonly onWindowBlur;
125
+ private readonly onWindowMouseMove;
126
+ private readonly onHistoryChange;
127
+ private readonly editing;
128
+ constructor(root: HTMLElement, options: ColworkTableOptions);
129
+ private log;
130
+ private undo;
131
+ private redo;
132
+ private refreshHistoryButtons;
133
+ /** Changes local editing affordances. Hosts enforce actual document permissions. */
134
+ setReadOnly(readOnly: boolean): void;
135
+ /** Explicitly commits the active cell draft before a host publishes or exports. */
136
+ commitEditing(): void;
137
+ /** Discards an active draft while preserving the current shared document value. */
138
+ cancelEditing(): void;
139
+ getYjsSnapshot(): YjsSnapshotFile;
140
+ getYjsUpdateLog(): YjsUpdateLogFile;
141
+ /** Freeze a leading prefix in this local view. */
142
+ setFrozenPanes(rows: number, columns: number): boolean;
143
+ private crossesFrozenBoundary;
144
+ private freezeSelection;
145
+ private selectionHasLocks;
146
+ setSelectionLocked(locked: boolean, password?: string): Promise<void>;
147
+ private get rowCount();
148
+ private get columnCount();
149
+ private get rowHeaderWidth();
150
+ private get columnHeaderHeight();
151
+ private getRowHeight;
152
+ private getColumnWidth;
153
+ private beginResize;
154
+ private addResizeHandle;
155
+ private mergeSelection;
156
+ private unmergeSelection;
157
+ private modifyAxis;
158
+ private deleteRows;
159
+ private deleteColumns;
160
+ private expandLogicalSpace;
161
+ private expandForRemoteSelections;
162
+ private clearSelectionContents;
163
+ private expandLogicalSizeFromDocument;
164
+ private render;
165
+ private refreshValues;
166
+ private refreshSelection;
167
+ private refreshCursors;
168
+ private refreshStyles;
169
+ private refreshView;
170
+ destroy(): void;
171
+ }
172
+
173
+ export declare type ColworkTableOptions = ExternalCollaborationOptions | BuiltInCollaborationOptions;
174
+
175
+ declare type CommonOptions = {
176
+ user: string;
177
+ userColor?: string;
178
+ rowCount?: number;
179
+ columnCount?: number;
180
+ onLog?: (message: string) => void;
181
+ readOnly?: boolean;
182
+ onEditingChange?: (state: EditingState) => void;
183
+ };
184
+
185
+ export declare function containsPosition(range: CellRange, position: CellPosition): boolean;
186
+
187
+ export declare type EditingState = {
188
+ editing: boolean;
189
+ dirty: boolean;
190
+ };
191
+
192
+ export declare function exportYjsSnapshot(document: Y.Doc, options?: {
193
+ room?: string;
194
+ sequence?: number;
195
+ }): YjsSnapshotFile;
196
+
197
+ export declare type ExternalCollaborationOptions = CommonOptions & {
198
+ transport: 'external';
199
+ collaboration: {
200
+ document: Y.Doc;
201
+ awareness: Awareness;
202
+ };
203
+ room?: string;
204
+ rows?: never;
205
+ snapshot?: never;
206
+ updates?: never;
207
+ initializeAfterSync?: false;
208
+ signalingUrl?: never;
209
+ websocketUrl?: never;
210
+ peerOpts?: never;
211
+ };
212
+
213
+ /** Materializes named Y.Map roots, preserving the version-one encoding. */
214
+ export declare function getSheetMaps(document: Y.Doc): SheetMaps;
215
+
216
+ /** Initializes an empty document without demo cells, headers, styles, or network access. */
217
+ export declare function initializeBlankSheet(document: Y.Doc): void;
218
+
219
+ export declare function mergeKey(range: CellRange): string;
220
+
221
+ export declare function normalizeRange(start: CellPosition, end: CellPosition): CellRange;
222
+
223
+ export declare function parseCellKey(key: string): {
224
+ row: number;
225
+ column: number;
226
+ } | undefined;
227
+
228
+ export declare function parseMergeKey(key: string): CellRange | undefined;
229
+
230
+ export declare type PasswordLock = {
231
+ version: 1;
232
+ algorithm: 'PBKDF2-SHA-256';
233
+ iterations: 600000;
234
+ salt: string;
235
+ verifier: string;
236
+ };
237
+
238
+ export declare function rangeSize(range: CellRange): {
239
+ rows: number;
240
+ columns: number;
241
+ };
242
+
243
+ /** Reads a deterministic sparse sheet without loading a renderer, browser globals, or CSS. */
244
+ export declare function readSheetSnapshot(document: Y.Doc, limits?: SheetValidationLimits): SheetSnapshot;
245
+
246
+ /** Decodes a Yjs state update and releases its temporary document after export. */
247
+ export declare function readSheetSnapshotUpdate(update: Uint8Array, limits?: SheetValidationLimits): SheetSnapshot;
248
+
249
+ export declare function rebuildYjsSnapshot(snapshotText?: string, updateLogText?: string): YjsSnapshotFile;
250
+
251
+ declare type SelectionMode_2 = 'row' | 'column' | 'all';
252
+ export { SelectionMode_2 as SelectionMode }
253
+
254
+ export declare type SheetMaps = {
255
+ cells: Y.Map<string>;
256
+ styles: Y.Map<string>;
257
+ rowHeights: Y.Map<number>;
258
+ columnWidths: Y.Map<number>;
259
+ merges: Y.Map<string>;
260
+ locks: Y.Map<string>;
261
+ };
262
+
263
+ /** Sparse, JSON-serializable logical sheet. Dimensions are derived from stored data. */
264
+ export declare type SheetSnapshot = {
265
+ schemaVersion: typeof COLWORK_SCHEMA_VERSION;
266
+ rowCount: number;
267
+ columnCount: number;
268
+ cells: Record<string, string>;
269
+ styles: Record<string, CellStyle>;
270
+ rowHeights: Record<string, number>;
271
+ columnWidths: Record<string, number>;
272
+ merges: CellRange[];
273
+ locks: Record<string, CellLock>;
274
+ };
275
+
276
+ export declare type SheetValidationIssue = {
277
+ path: string;
278
+ message: string;
279
+ };
280
+
281
+ /** Optional host policy. Omitted numeric limits impose no application-specific cap. */
282
+ export declare type SheetValidationLimits = {
283
+ maxRows?: number;
284
+ maxColumns?: number;
285
+ maxEntries?: number;
286
+ maxStringLength?: number;
287
+ maxMergeArea?: number;
288
+ maxMerges?: number;
289
+ allowUnknownRoots?: boolean;
290
+ };
291
+
292
+ export declare function validateSheetDocument(document: Y.Doc, limits?: SheetValidationLimits): SheetValidationIssue[];
293
+
294
+ export declare type YjsArchiveFile = {
295
+ format: 'colwork.archive';
296
+ version: 1;
297
+ room?: string;
298
+ snapshot?: YjsSnapshotFile;
299
+ updates: YjsUpdateRecord[];
300
+ };
301
+
302
+ export declare type YjsSnapshotFile = {
303
+ format: 'colwork.snapshot';
304
+ version: 1;
305
+ room?: string;
306
+ sequence: number;
307
+ snapshot: string;
308
+ stateVector: string;
309
+ };
310
+
311
+ export declare type YjsUpdateLogFile = {
312
+ format: 'colwork.update-log';
313
+ version: 1;
314
+ room?: string;
315
+ updates: YjsUpdateRecord[];
316
+ };
317
+
318
+ export declare type YjsUpdateRecord = {
319
+ seq: number;
320
+ update: string;
321
+ timestamp: number;
322
+ };
323
+
324
+ export { }
@@ -0,0 +1,3 @@
1
+ import { CellRange } from './range.cjs';
2
+ /** Sweep rectangles across rows with a range-add tree over compressed columns. */
3
+ export declare function hasOverlappingMerges(merges: CellRange[]): boolean;
@@ -0,0 +1,3 @@
1
+ import { CellRange } from './range.js';
2
+ /** Sweep rectangles across rows with a range-add tree over compressed columns. */
3
+ export declare function hasOverlappingMerges(merges: CellRange[]): boolean;
@@ -0,0 +1,80 @@
1
+ import { CellRange } from './range.cjs';
2
+ import type * as Y from 'yjs';
3
+ /** The existing version-one wire format. Missing metadata is valid legacy data. */
4
+ export declare const COLWORK_SCHEMA_VERSION: 1;
5
+ export declare const COLWORK_MAP_NAMES: Readonly<{
6
+ readonly cells: "cells";
7
+ readonly styles: "styles";
8
+ readonly rowHeights: "rowHeights";
9
+ readonly columnWidths: "columnWidths";
10
+ readonly merges: "merges";
11
+ readonly locks: "locks";
12
+ readonly metadata: "colwork-metadata";
13
+ }>;
14
+ export type CellBorder = {
15
+ top?: boolean;
16
+ right?: boolean;
17
+ bottom?: boolean;
18
+ left?: boolean;
19
+ };
20
+ export type CellStyle = {
21
+ bold?: boolean;
22
+ italic?: boolean;
23
+ underline?: boolean;
24
+ strike?: boolean;
25
+ wrap?: boolean;
26
+ border?: CellBorder;
27
+ fontSize?: number;
28
+ color?: string;
29
+ background?: string;
30
+ align?: 'left' | 'center' | 'right';
31
+ format?: 'general' | 'number' | 'date' | 'percent';
32
+ };
33
+ export type PasswordLock = {
34
+ version: 1;
35
+ algorithm: 'PBKDF2-SHA-256';
36
+ iterations: 600000;
37
+ salt: string;
38
+ verifier: string;
39
+ };
40
+ export type CellLock = '1' | PasswordLock;
41
+ export type SheetMaps = {
42
+ cells: Y.Map<string>;
43
+ styles: Y.Map<string>;
44
+ rowHeights: Y.Map<number>;
45
+ columnWidths: Y.Map<number>;
46
+ merges: Y.Map<string>;
47
+ locks: Y.Map<string>;
48
+ };
49
+ /** Sparse, JSON-serializable logical sheet. Dimensions are derived from stored data. */
50
+ export type SheetSnapshot = {
51
+ schemaVersion: typeof COLWORK_SCHEMA_VERSION;
52
+ rowCount: number;
53
+ columnCount: number;
54
+ cells: Record<string, string>;
55
+ styles: Record<string, CellStyle>;
56
+ rowHeights: Record<string, number>;
57
+ columnWidths: Record<string, number>;
58
+ merges: CellRange[];
59
+ locks: Record<string, CellLock>;
60
+ };
61
+ export type SheetValidationIssue = {
62
+ path: string;
63
+ message: string;
64
+ };
65
+ export declare function parseCellKey(key: string): {
66
+ row: number;
67
+ column: number;
68
+ } | undefined;
69
+ export declare function mergeKey(range: CellRange): string;
70
+ export declare function parseMergeKey(key: string): CellRange | undefined;
71
+ /** Optional host policy. Omitted numeric limits impose no application-specific cap. */
72
+ export type SheetValidationLimits = {
73
+ maxRows?: number;
74
+ maxColumns?: number;
75
+ maxEntries?: number;
76
+ maxStringLength?: number;
77
+ maxMergeArea?: number;
78
+ maxMerges?: number;
79
+ allowUnknownRoots?: boolean;
80
+ };