tabulark 0.0.4 → 0.1.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +16 -0
  2. package/README.md +215 -110
  3. package/THIRD_PARTY_NOTICES.md +37 -0
  4. package/dist/adapters.d.ts +62 -0
  5. package/dist/arrow.d.ts +3 -0
  6. package/dist/arrow.js +2 -0
  7. package/dist/arrow.js.map +7 -0
  8. package/dist/client.d.ts +76 -0
  9. package/dist/errors.d.ts +19 -0
  10. package/dist/excel.d.ts +3 -0
  11. package/dist/excel.js +2 -0
  12. package/dist/excel.js.map +7 -0
  13. package/dist/experimental.d.ts +13 -0
  14. package/dist/experimental.js +2 -0
  15. package/dist/experimental.js.map +7 -0
  16. package/dist/index.d.ts +10 -0
  17. package/dist/index.js +2 -0
  18. package/dist/index.js.map +7 -0
  19. package/dist/model.d.ts +389 -0
  20. package/dist/official-adapter-manifest.d.ts +31 -0
  21. package/dist/parquet.d.ts +3 -0
  22. package/dist/parquet.js +2 -0
  23. package/dist/parquet.js.map +7 -0
  24. package/dist/protocol.d.ts +54 -0
  25. package/dist/range-cache.d.ts +28 -0
  26. package/dist/rpc-client.d.ts +18 -0
  27. package/dist/view/accessible-grid.d.ts +36 -0
  28. package/dist/view/canvas-painter.d.ts +91 -0
  29. package/dist/view/canvas-table-view-public.d.ts +58 -0
  30. package/dist/view/canvas-table-view.d.ts +32 -0
  31. package/dist/view/controller.d.ts +34 -0
  32. package/dist/view/layout.d.ts +34 -0
  33. package/dist/view/selection.d.ts +7 -0
  34. package/dist/view/types.d.ts +184 -0
  35. package/dist/wasm/arrow/tabulark_arrow.d.ts +126 -0
  36. package/dist/wasm/arrow/tabulark_arrow.js +771 -0
  37. package/dist/wasm/arrow/tabulark_arrow_bg.wasm +0 -0
  38. package/dist/wasm/arrow/tabulark_arrow_bg.wasm.d.ts +25 -0
  39. package/dist/wasm/delimited/tabulark_delimited.d.ts +131 -0
  40. package/dist/wasm/delimited/tabulark_delimited.js +845 -0
  41. package/dist/wasm/delimited/tabulark_delimited_bg.wasm +0 -0
  42. package/dist/wasm/delimited/tabulark_delimited_bg.wasm.d.ts +26 -0
  43. package/dist/wasm/excel/tabulark_excel.d.ts +121 -0
  44. package/dist/wasm/excel/tabulark_excel.js +766 -0
  45. package/dist/wasm/excel/tabulark_excel_bg.wasm +0 -0
  46. package/dist/wasm/excel/tabulark_excel_bg.wasm.d.ts +25 -0
  47. package/dist/wasm/parquet/tabulark_parquet.d.ts +121 -0
  48. package/dist/wasm/parquet/tabulark_parquet.js +754 -0
  49. package/dist/wasm/parquet/tabulark_parquet_bg.wasm +0 -0
  50. package/dist/wasm/parquet/tabulark_parquet_bg.wasm.d.ts +25 -0
  51. package/dist/worker/wasm-adapter.d.ts +57 -0
  52. package/dist/worker/worker-errors.d.ts +9 -0
  53. package/dist/worker.d.ts +1 -0
  54. package/dist/worker.js +2 -0
  55. package/dist/worker.js.map +7 -0
  56. package/package.json +55 -12
  57. package/js/index.d.ts +0 -18
  58. package/js/index.js +0 -26
package/dist/index.js ADDED
@@ -0,0 +1,2 @@
1
+ var TabularkError=class _TabularkError extends Error{code;retryable;details;constructor(code,message,options={}){super(message,{cause:options.cause});this.name="TabularkError";this.code=code;this.retryable=options.retryable??false;this.details=code==="RESOURCE_LIMIT"?normalizeResourceLimitDetails(options.details):options.details}static fromSerialized(error){return new _TabularkError(error.code,error.message,{retryable:error.retryable,details:error.details})}};function normalizeResourceLimitDetails(details){const raw=isRecord(details)?details:{};const resource=typeof raw.resource==="string"&&raw.resource.length>0?raw.resource:typeof raw.resourceCategory==="string"&&raw.resourceCategory.length>0?raw.resourceCategory:inferResource(raw);if(isQuantity(raw.requiredBytes)&&isQuantity(raw.availableBytes)){return Object.freeze({...raw,resource})}if(isQuantity(raw.required)&&isQuantity(raw.available)){return Object.freeze({...raw,resource})}const byteLimit=firstQuantity(raw,["maxDecodedBytes","maxOutputBytes","maxMetadataBytes","maxBlockBytes","maxDisplayCellBytes","maxDisplayBytes","maxSourceBytes","maxFieldBytes","maxBatchBytes","maxOperationBytes","maxZipEntryBytes","maxZipUncompressedBytes","maxCfbStreamBytes"]);if(byteLimit!==void 0){const requiredBytes=firstQuantity(raw,["decodedBytes","outputBytes","metadataBytes","blockBytes","displayCellBytes","displayBytes","sourceBytes","fieldBytes","batchBytes","operationBytes"])??byteLimit+1;return Object.freeze({...raw,resource,requiredBytes,availableBytes:byteLimit})}const available=firstQuantity(raw,["limit","maxCells","maxRangeCells","maxSources","maxActiveRanges","maxRangeWaiters","maxColumns","maxFields","maxNestingDepth","maxWorksheetRows","maxWorksheetColumns","maxStyles","maxMergedRegions"])??0;const required=firstQuantity(raw,["cells","cellCount","visibleCellCount","sources","activeRanges","rangeWaiters","columns","fields","nestingDepth","worksheetRows","worksheetColumns","styles","mergedRegions"])??available+1;return Object.freeze({...raw,resource,required,available})}function inferResource(details){const keys=Object.keys(details).join(" ").toLowerCase();if(keys.includes("source"))return keys.includes("byte")?"source-staging":"source-slots";if(keys.includes("metadata"))return"metadata";if(keys.includes("decoded")||keys.includes("decompress"))return"decompression";if(keys.includes("display"))return"display-values";if(keys.includes("field"))return"field";if(keys.includes("batch"))return"batch";if(keys.includes("range")||keys.includes("cell"))return"range-cells";if(keys.includes("column"))return"columns";if(keys.includes("nest"))return"descriptor-nesting";if(keys.includes("worksheet"))return"worksheet-dimensions";return"adapter-resource"}function firstQuantity(details,names){for(const name of names){if(isQuantity(details[name]))return details[name]}return void 0}function isQuantity(value){return typeof value==="number"&&Number.isFinite(value)&&value>=0}function isRecord(value){return typeof value==="object"&&value!==null&&!Array.isArray(value)}function cancelledError(){return new TabularkError("CANCELLED","The operation was cancelled")}function closedError(resource){return new TabularkError("HANDLE_CLOSED",`${resource} is closed`)}function invalidArgument(message,details){return new TabularkError("INVALID_ARGUMENT",message,{details})}var official_adapters_default={manifestVersion:1,adapters:[{id:"tabulark:delimited",entrypoint:".",exportName:"delimitedAdapter",wasm:{packageName:"tabulark-delimited-wasm",crateArtifact:"tabulark_delimited",outputName:"tabulark_delimited",outputDirectory:"dist/wasm/delimited",modulePath:"./wasm/delimited/tabulark_delimited.js",runtimeExport:"WasmRuntime"},options:{allowedKeys:["dialect","header","mode","delimiter","sourceName"]},resources:{sourceAccess:"streaming",supportsPresentation:false,runtimeWeight:1}},{id:"tabulark:arrow-ipc",entrypoint:"./arrow",exportName:"arrowIpcAdapter",wasm:{packageName:"tabulark-arrow-wasm",crateArtifact:"tabulark_arrow",outputName:"tabulark_arrow",outputDirectory:"dist/wasm/arrow",modulePath:"./wasm/arrow/tabulark_arrow.js",runtimeExport:"WasmRuntime"},options:{allowedKeys:["container","sourceName"]},resources:{sourceAccess:"range",supportsPresentation:false,runtimeWeight:1}},{id:"tabulark:parquet",entrypoint:"./parquet",exportName:"parquetAdapter",wasm:{packageName:"tabulark-parquet-wasm",crateArtifact:"tabulark_parquet",outputName:"tabulark_parquet",outputDirectory:"dist/wasm/parquet",modulePath:"./wasm/parquet/tabulark_parquet.js",runtimeExport:"WasmRuntime"},options:{allowedKeys:["sourceName"]},resources:{sourceAccess:"range",supportsPresentation:false,runtimeWeight:2}},{id:"tabulark:excel",entrypoint:"./excel",exportName:"excelAdapter",wasm:{packageName:"tabulark-excel-wasm",crateArtifact:"tabulark_excel",outputName:"tabulark_excel",outputDirectory:"dist/wasm/excel",modulePath:"./wasm/excel/tabulark_excel.js",runtimeExport:"WasmRuntime"},options:{allowedKeys:["format","sourceName"]},resources:{sourceAccess:"staged",supportsPresentation:true,runtimeWeight:2}}]};var manifestEntries=validateManifest(official_adapters_default);var OFFICIAL_ADAPTER_IDS=Object.freeze(manifestEntries.map(entry=>entry.id));var OFFICIAL_ADAPTER_MANIFEST=Object.freeze(manifestEntries.map(entry=>Object.freeze({...entry,wasm:Object.freeze({...entry.wasm}),options:Object.freeze({allowedKeys:Object.freeze([...entry.options.allowedKeys])}),resources:Object.freeze({...entry.resources})})));var byId=new Map(OFFICIAL_ADAPTER_MANIFEST.map(entry=>[entry.id,entry]));function isOfficialAdapterId(value){return typeof value==="string"&&byId.has(value)}function officialAdapterManifestEntry(id){const entry=byId.get(id);if(!entry){throw new TypeError(`Unknown official adapter: ${id}`)}return entry}function validateManifest(value){if(!isRecord2(value)||value.manifestVersion!==1||!Array.isArray(value.adapters)){throw new TypeError("The official adapter manifest has an unsupported shape or version")}if(value.adapters.length===0){throw new TypeError("The official adapter manifest must contain at least one adapter")}const ids=new Set;const entrypoints=new Set;const outputDirectories=new Set;return value.adapters.map((candidate,index)=>{if(!isRecord2(candidate)){throw new TypeError(`Official adapter manifest entry ${index} must be an object`)}const{id,entrypoint,exportName,wasm,options,resources}=candidate;if(!isKnownOfficialAdapterId(id)||ids.has(id)){throw new TypeError(`Official adapter manifest entry ${index} has an invalid or duplicate id`)}if(entrypoint!=="."&&entrypoint!=="./arrow"&&entrypoint!=="./parquet"&&entrypoint!=="./excel"||entrypoints.has(entrypoint)||typeof exportName!=="string"||exportName.length===0){throw new TypeError(`Official adapter manifest entry ${index} has an invalid entrypoint or export`)}if(!isRecord2(wasm)||typeof wasm.packageName!=="string"||typeof wasm.crateArtifact!=="string"||typeof wasm.outputName!=="string"||typeof wasm.outputDirectory!=="string"||!wasm.outputDirectory.startsWith("dist/wasm/")||wasm.outputDirectory.includes("..")||outputDirectories.has(wasm.outputDirectory)||typeof wasm.modulePath!=="string"||!wasm.modulePath.startsWith("./wasm/")||wasm.modulePath.includes("..")||wasm.modulePath.includes("?")||wasm.modulePath.includes("#")||wasm.runtimeExport!=="WasmRuntime"||wasm.modulePath!==`./${wasm.outputDirectory.replace(/^dist\//u,"")}/${wasm.outputName}.js`){throw new TypeError(`Official adapter manifest entry ${index} has an invalid WASM artifact`)}if(!isRecord2(options)||!Array.isArray(options.allowedKeys)||options.allowedKeys.some(key=>typeof key!=="string")||new Set(options.allowedKeys).size!==options.allowedKeys.length){throw new TypeError(`Official adapter manifest entry ${index} has invalid option keys`)}if(!isRecord2(resources)||resources.sourceAccess!=="streaming"&&resources.sourceAccess!=="range"&&resources.sourceAccess!=="staged"||typeof resources.supportsPresentation!=="boolean"||!Number.isSafeInteger(resources.runtimeWeight)||resources.runtimeWeight<=0){throw new TypeError(`Official adapter manifest entry ${index} has an invalid resource policy`)}ids.add(id);entrypoints.add(entrypoint);outputDirectories.add(wasm.outputDirectory);return candidate})}function isKnownOfficialAdapterId(value){return value==="tabulark:delimited"||value==="tabulark:arrow-ipc"||value==="tabulark:parquet"||value==="tabulark:excel"}function isRecord2(value){return typeof value==="object"&&value!==null}var OFFICIAL_ADAPTER=Symbol.for("tabulark.official-adapter.v2");function createOfficialAdapter(id){const marker=Object.freeze({id});return Object.freeze({id,kind:"official",[OFFICIAL_ADAPTER]:marker})}var delimitedAdapter=createOfficialAdapter("tabulark:delimited");function resolveOfficialAdapter(value){if(!isRecord3(value)||!Object.isFrozen(value)||!isOfficialAdapterId(value.id)||value.kind!=="official"){return void 0}const marker=value[OFFICIAL_ADAPTER];if(!isRecord3(marker)||marker.id!==value.id){return void 0}officialAdapterManifestEntry(value.id);return Object.freeze({id:value.id})}function isRecord3(value){return typeof value==="object"&&value!==null}var PROTOCOL_VERSION=3;var ADAPTER_API_VERSION=2;var BATCH_LAYOUT_VERSION=1;function isRecord4(value){return typeof value==="object"&&value!==null}var DEFAULT_MEMORY_BUDGET_BYTES=256*1024*1024;var MAX_ARRAY_BUFFER_BYTES=128*1024*1024;var MAX_RANGE_CELLS=25e4;var DEFAULT_TO_ROWS_CELL_LIMIT=1e4;var MAX_NESTING_DEPTH=64;var INDEX_BUDGET_MAX_BYTES=64*1024*1024;var WORKER_RANGE_CACHE_MAX_BYTES=96*1024*1024;var MAIN_THREAD_RANGE_CACHE_MAX_BYTES=32*1024*1024;var FIELD_AND_BATCH_MAX_BYTES=8*1024*1024;var MAX_SOURCES=2;var MAX_ACTIVE_RANGES=2;var MAX_RANGE_WAITERS=8;function deriveMemoryBudgetLimits(memoryBudgetBytes){assertPositiveSafeInteger(memoryBudgetBytes,"memoryBudgetBytes");const oneEighth=Math.floor(memoryBudgetBytes/8);const oneThirtySecond=Math.floor(memoryBudgetBytes/32);const adapterRuntimePoolBytes=Math.max(1,Math.floor(memoryBudgetBytes/2));const operationBudgetBytes=Math.max(1,Math.floor(memoryBudgetBytes/8));const workerRangeCacheBytes=Math.min(WORKER_RANGE_CACHE_MAX_BYTES,Math.floor(memoryBudgetBytes/8*3));return Object.freeze({memoryBudgetBytes,adapterRuntimePoolBytes,operationBudgetBytes,indexBudgetBytes:Math.min(INDEX_BUDGET_MAX_BYTES,oneEighth),adapterTileCacheBudgetBytes:Math.min(WORKER_RANGE_CACHE_MAX_BYTES,operationBudgetBytes),workerRangeCacheBytes,workerDatasetRangeCacheBytes:Math.floor(workerRangeCacheBytes/MAX_SOURCES),mainThreadRangeCacheBytes:Math.min(MAIN_THREAD_RANGE_CACHE_MAX_BYTES,oneEighth),maxFieldBytes:Math.min(FIELD_AND_BATCH_MAX_BYTES,oneThirtySecond),maxBatchBytes:Math.min(FIELD_AND_BATCH_MAX_BYTES,oneThirtySecond),maxArrayBufferBytes:Math.min(MAX_ARRAY_BUFFER_BYTES,Math.floor(memoryBudgetBytes/2)),maxSources:MAX_SOURCES,maxActiveRanges:MAX_ACTIVE_RANGES,maxRangeWaiters:MAX_RANGE_WAITERS})}var ColumnarTableBatch=class{tableId;revision;schemaVersion;range;columns;complete;#buffers;#wireColumns;constructor(value){if(value.layoutVersion!==BATCH_LAYOUT_VERSION){throw invalidArgument(`Batch layout ${String(value.layoutVersion)} is incompatible with layout ${BATCH_LAYOUT_VERSION}`)}this.tableId=value.tableId;this.revision=value.revision;this.schemaVersion=value.schemaVersion;this.range=Object.freeze({...value.range});this.#buffers=Object.freeze(value.buffers.map(asUint8Array));this.#wireColumns=Object.freeze(value.columns.map(column=>freezeWireColumn(column)));this.complete=value.complete;validateWireBatch(this.range,this.#buffers,this.#wireColumns);this.columns=Object.freeze(this.#wireColumns.map((column,index)=>new LogicalBatchColumn(column,this.#buffers,this.range.rowCount,this.range.columnStart+index)))}toRows(options={}){const maxCells=normalizeCellLimit(options.maxCells);assertCellLimit(this.range.rowCount,this.columns.length,maxCells);const rows=Array.from({length:this.range.rowCount},()=>Array(this.columns.length));for(let columnIndex=0;columnIndex<this.columns.length;columnIndex+=1){for(let rowIndex=0;rowIndex<this.range.rowCount;rowIndex+=1){rows[rowIndex][columnIndex]=this.columns[columnIndex].getValue(rowIndex)}}return rows}toDisplayRows(options={}){const maxCells=normalizeCellLimit(options.maxCells);assertCellLimit(this.range.rowCount,this.columns.length,maxCells);const rows=Array.from({length:this.range.rowCount},()=>Array(this.columns.length));for(let columnIndex=0;columnIndex<this.columns.length;columnIndex+=1){for(let rowIndex=0;rowIndex<this.range.rowCount;rowIndex+=1){rows[rowIndex][columnIndex]=this.columns[columnIndex].getDisplayValue(rowIndex)}}return rows}};var LogicalBatchColumn=class{columnId;columnIndex;rowCount;#wire;#buffers;constructor(wire,buffers,rowCount,columnIndex){this.columnId=wire.columnId;this.columnIndex=columnIndex;this.rowCount=rowCount;this.#wire=wire;this.#buffers=buffers;Object.freeze(this)}getValue(rowOffset){assertBatchRowOffset(rowOffset,this.rowCount);return decodeNativeValue(this.#wire.native,rowOffset,this.#buffers,0)}getDisplayValue(rowOffset){assertBatchRowOffset(rowOffset,this.rowCount);return decodeDisplayValue(this.#wire.display,rowOffset,this.#buffers,this.columnId)}toValues(options={}){const maxCells=normalizeCellLimit(options.maxCells);assertCellLimit(this.rowCount,1,maxCells);return Array.from({length:this.rowCount},(_,index)=>this.getValue(index))}toDisplayValues(options={}){const maxCells=normalizeCellLimit(options.maxCells);assertCellLimit(this.rowCount,1,maxCells);return Array.from({length:this.rowCount},(_,index)=>this.getDisplayValue(index))}};function assertBatchRowOffset(rowOffset,rowCount){if(!Number.isSafeInteger(rowOffset)||rowOffset<0||rowOffset>=rowCount){throw invalidArgument(`Batch row offset must be an integer from 0 through ${Math.max(0,rowCount-1)}`)}}function decodeDisplayValue(display,rowOffset,buffers,columnId){const physicalIndex=(display.offset??0)+rowOffset;if(!validAt(display.validity,physicalIndex,buffers)){return null}const offsets=regionView(display.offsets,buffers,"display offsets");const data=regionView(display.data,buffers,"display data");const start=readUnsignedOffset(offsets,physicalIndex,4);const end=readUnsignedOffset(offsets,physicalIndex+1,4);if(end<start||end>data.byteLength){throw invalidArgument(`Column ${columnId} has invalid display offsets`)}return new TextDecoder().decode(data.subarray(start,end))}function validateRange(request){for(const[name,value]of Object.entries(request)){assertNonNegativeSafeInteger(value,name)}if(!Number.isSafeInteger(request.rowStart+request.rowCount)||!Number.isSafeInteger(request.columnStart+request.columnCount)){throw new TabularkError("INVALID_RANGE","Range end must be a safe integer")}const cells=request.rowCount*request.columnCount;if(!Number.isSafeInteger(cells)||cells>MAX_RANGE_CELLS){throw new TabularkError("RESOURCE_LIMIT",`A range may contain at most ${MAX_RANGE_CELLS} cells`,{details:{resource:"range-cells",required:cells,available:MAX_RANGE_CELLS,cells,limit:MAX_RANGE_CELLS}})}return Object.freeze({...request})}function normalizeMetadata(value){return Object.freeze({...value,extent:Object.freeze({rows:Object.freeze({...value.extent.rows}),columns:Object.freeze({...value.extent.columns})}),schema:Object.freeze({version:value.schema.version,columns:Object.freeze(value.schema.columns.map(column=>Object.freeze({...column,dataType:freezeDataType(column.dataType),...column.metadata?{metadata:Object.freeze({...column.metadata})}:{}})))}),capabilities:Object.freeze({...value.capabilities})})}function normalizeDataType(value,depth=0){if(depth>=MAX_NESTING_DEPTH){throw invalidArgument(`Arrow data type nesting may not exceed ${MAX_NESTING_DEPTH}`)}if(!isRecord5(value)||typeof value.type!=="string"){throw invalidArgument("Column dataType must be a recursive Arrow data type descriptor")}const type={"u-int8":"uint8","u-int16":"uint16","u-int32":"uint32","u-int64":"uint64"}[value.type]??value.type;const simple=new Set(["unknown","null","boolean","int8","int16","int32","int64","uint8","uint16","uint32","uint64","float16","float32","float64","date32","date64","binary","large-binary","binary-view","utf8","large-utf8","utf8-view"]);if(simple.has(type)){return Object.freeze({type})}if(type==="timestamp"){return Object.freeze({type,unit:timeUnit(value.unit),...typeof value.timezone==="string"?{timezone:value.timezone}:{}})}if(type==="time32"||type==="time64"||type==="duration"){return Object.freeze({type,unit:timeUnit(value.unit)})}if(type==="interval"){return Object.freeze({type,unit:intervalUnit(value.unit)})}if(type==="fixed-size-binary"){return Object.freeze({type,byteWidth:positiveInteger(value.byteWidth??value.byte_width,"byteWidth")})}if(type==="decimal32"||type==="decimal64"||type==="decimal128"||type==="decimal256"){return Object.freeze({type,precision:positiveInteger(value.precision,"precision"),scale:integer(value.scale,"scale")})}if(type==="list"||type==="large-list"||type==="list-view"||type==="large-list-view"){return Object.freeze({type,field:normalizeField(value.field,depth+1)})}if(type==="fixed-size-list"){return Object.freeze({type,field:normalizeField(value.field,depth+1),listSize:positiveInteger(value.listSize??value.list_size,"listSize")})}if(type==="struct"){if(!Array.isArray(value.fields)){throw invalidArgument("Struct fields must be an array")}return Object.freeze({type,fields:Object.freeze(value.fields.map(field=>normalizeField(field,depth+1)))})}if(type==="union"){if(!Array.isArray(value.fields)||value.mode!=="sparse"&&value.mode!=="dense"){throw invalidArgument("Union dataType requires a mode and fields")}return Object.freeze({type,mode:value.mode,fields:Object.freeze(value.fields.map(entry=>{if(!isRecord5(entry)){throw invalidArgument("Union field entries must be objects")}return Object.freeze({typeId:integer(entry.typeId,"typeId"),field:normalizeField(entry.field,depth+1)})}))})}if(type==="dictionary"){return Object.freeze({type,indexType:normalizeDataType(value.indexType,depth+1),valueType:normalizeDataType(value.valueType,depth+1),...value.ordered===true?{ordered:true}:{}})}if(type==="map"){return Object.freeze({type,entries:normalizeField(value.entries,depth+1),keysSorted:value.keysSorted===true||value.keys_sorted===true})}if(type==="run-end-encoded"){return Object.freeze({type,runEnds:normalizeField(value.runEnds??value.run_ends,depth+1),values:normalizeField(value.values,depth+1)})}if(type==="extension"){if(typeof value.name!=="string"||value.name.length===0){throw invalidArgument("Arrow extension name must be a non-empty string")}return Object.freeze({type,name:value.name,...typeof value.metadata==="string"?{metadata:value.metadata}:{},storageType:normalizeDataType(value.storageType,depth+1)})}throw invalidArgument(`Unknown Arrow data type: ${type}`)}function normalizeField(value,depth){if(!isRecord5(value)){throw invalidArgument("Arrow field must be an object")}const metadata=isRecord5(value.metadata)?Object.freeze(Object.fromEntries(Object.entries(value.metadata).map(([key,entry])=>[key,String(entry)]))):void 0;return Object.freeze({name:typeof value.name==="string"?value.name:"",nullable:value.nullable!==false,dataType:normalizeDataType(value.dataType,depth),...metadata?{metadata}:{}})}function validateWireBatch(range,buffers,columns){validateRange(range);if(columns.length!==range.columnCount){throw invalidArgument(`Batch has ${columns.length} columns; expected ${range.columnCount}`)}for(const[index,column]of columns.entries()){validateDisplay(column.display,range.rowCount,buffers,column.columnId);validateNative(column.native,buffers,0,`columns[${index}].native`);if(column.native.length<range.rowCount){throw invalidArgument(`Column ${column.columnId} is shorter than the returned range`)}}}function validateDisplay(display,rows,buffers,columnId){const offset=display.offset??0;assertNonNegativeSafeInteger(offset,"display offset");const offsets=regionView(display.offsets,buffers,"display offsets");if(offsets.byteLength<(offset+rows+1)*4){throw invalidArgument(`Column ${columnId} has incomplete display offsets`)}const data=regionView(display.data,buffers,"display data");if(display.validity){const validity=regionView(display.validity,buffers,"display validity");if(validity.byteLength<Math.ceil((offset+rows)/8)){throw invalidArgument(`Column ${columnId} has an incomplete display validity bitmap`)}}let previous=0;for(let index=offset;index<=offset+rows;index+=1){const next=readUnsignedOffset(offsets,index,4);if(next<previous||next>data.byteLength){throw invalidArgument(`Column ${columnId} has invalid display offsets`)}previous=next}}function validateNative(descriptor,buffers,depth,name){if(depth>=MAX_NESTING_DEPTH){throw invalidArgument(`Native column nesting may not exceed ${MAX_NESTING_DEPTH}`)}assertNonNegativeSafeInteger(descriptor.length,`${name}.length`);assertNonNegativeSafeInteger(descriptor.offset??0,`${name}.offset`);normalizeDataType(descriptor.dataType,depth);const regions=[descriptor.validity,descriptor.values,descriptor.offsets,descriptor.sizes,descriptor.data,descriptor.typeIds,descriptor.unionOffsets,...descriptor.variadicBuffers??[]];for(const region of regions){if(region){regionView(region,buffers,name)}}for(const[index,child]of(descriptor.children??[]).entries()){validateNative(child,buffers,depth+1,`${name}.children[${index}]`)}if(descriptor.dictionary){validateNative(descriptor.dictionary,buffers,depth+1,`${name}.dictionary`)}if(descriptor.runEnds){validateNative(descriptor.runEnds,buffers,depth+1,`${name}.runEnds`)}}function decodeNativeValue(descriptor,logicalIndex,buffers,depth){if(depth>=MAX_NESTING_DEPTH){throw invalidArgument(`Native value nesting may not exceed ${MAX_NESTING_DEPTH}`)}if(logicalIndex<0||logicalIndex>=descriptor.length){throw invalidArgument("Native value index is outside its descriptor")}const physicalIndex=(descriptor.offset??0)+logicalIndex;if(!validAt(descriptor.validity,physicalIndex,buffers)){return null}const type=unwrapExtension(descriptor.dataType);switch(type.type){case"null":return null;case"unknown":{const bytes=decodeVariableBytes(descriptor,buffers,physicalIndex,4);return new TextDecoder().decode(bytes)}case"boolean":{const values=requiredRegion(descriptor.values,buffers,"boolean values");const bitIndex=(descriptor.values?.bitOffset??0)+physicalIndex;return(values[bitIndex>>>3]&1<<(bitIndex&7))!==0}case"int8":return readNumber(descriptor,buffers,physicalIndex,1,"signed");case"uint8":return readNumber(descriptor,buffers,physicalIndex,1,"unsigned");case"int16":return readNumber(descriptor,buffers,physicalIndex,2,"signed");case"uint16":return readNumber(descriptor,buffers,physicalIndex,2,"unsigned");case"int32":return readNumber(descriptor,buffers,physicalIndex,4,"signed");case"uint32":return readNumber(descriptor,buffers,physicalIndex,4,"unsigned");case"int64":return readBigInt(descriptor,buffers,physicalIndex,true);case"uint64":return readBigInt(descriptor,buffers,physicalIndex,false);case"float16":return decodeFloat16(readNumber(descriptor,buffers,physicalIndex,2,"unsigned"));case"float32":return readFloat(descriptor,buffers,physicalIndex,4);case"float64":return readFloat(descriptor,buffers,physicalIndex,8);case"utf8":case"large-utf8":{const bytes=decodeVariableBytes(descriptor,buffers,physicalIndex,type.type==="large-utf8"?8:4);return new TextDecoder().decode(bytes)}case"binary":case"large-binary":return decodeVariableBytes(descriptor,buffers,physicalIndex,type.type==="large-binary"?8:4).slice();case"utf8-view":return new TextDecoder().decode(decodeViewBytes(descriptor,buffers,physicalIndex));case"binary-view":return decodeViewBytes(descriptor,buffers,physicalIndex).slice();case"fixed-size-binary":{const data=requiredRegion(descriptor.data??descriptor.values,buffers,"fixed-size binary data");const start=physicalIndex*type.byteWidth;return checkedSlice(data,start,start+type.byteWidth,"fixed-size binary data").slice()}case"decimal32":case"decimal64":case"decimal128":case"decimal256":{const width={decimal32:4,decimal64:8,decimal128:16,decimal256:32}[type.type];return Object.freeze({kind:"decimal",unscaled:readSignedLittleEndian(requiredRegion(descriptor.values,buffers,"decimal values"),physicalIndex*width,width),precision:type.precision,scale:type.scale})}case"date32":return Object.freeze({kind:"date32",value:readNumber(descriptor,buffers,physicalIndex,4,"signed")});case"date64":return Object.freeze({kind:"date64",value:readBigInt(descriptor,buffers,physicalIndex,true),unit:"millisecond"});case"time32":return Object.freeze({kind:"time32",value:readNumber(descriptor,buffers,physicalIndex,4,"signed"),unit:type.unit});case"time64":return Object.freeze({kind:"time64",value:readBigInt(descriptor,buffers,physicalIndex,true),unit:type.unit});case"timestamp":return Object.freeze({kind:"timestamp",value:readBigInt(descriptor,buffers,physicalIndex,true),unit:type.unit,...type.timezone===void 0?{}:{timezone:type.timezone}});case"duration":return Object.freeze({kind:"duration",value:readBigInt(descriptor,buffers,physicalIndex,true),unit:type.unit});case"interval":return decodeInterval(descriptor,buffers,physicalIndex,type.unit);case"list":case"large-list":case"list-view":case"large-list-view":case"map":return decodeListLike(descriptor,buffers,physicalIndex,type,depth);case"fixed-size-list":{const child=requiredChild(descriptor,0,"fixed-size list");const start=physicalIndex*type.listSize;return Object.freeze(Array.from({length:type.listSize},(_,index)=>decodeNativeValue(child,start+index-(child.offset??0),buffers,depth+1)))}case"struct":{const result={};for(let index=0;index<type.fields.length;index+=1){const child=requiredChild(descriptor,index,"struct");result[type.fields[index].name]=decodeNativeValue(child,physicalIndex-(child.offset??0),buffers,depth+1)}return Object.freeze(result)}case"union":{const typeIds=requiredRegion(descriptor.typeIds,buffers,"union type ids");if(physicalIndex>=typeIds.byteLength){throw invalidArgument("Union type id is out of bounds")}const typeId=new DataView(typeIds.buffer,typeIds.byteOffset,typeIds.byteLength).getInt8(physicalIndex);const fieldIndex=type.fields.findIndex(entry=>entry.typeId===typeId);if(fieldIndex<0){throw invalidArgument(`Union type id ${typeId} has no child`)}const child=requiredChild(descriptor,fieldIndex,"union");const childPhysical=type.mode==="dense"?readSignedOffset(requiredRegion(descriptor.unionOffsets??descriptor.offsets,buffers,"union offsets"),physicalIndex,4):physicalIndex;return Object.freeze({kind:"union",typeId,value:decodeNativeValue(child,childPhysical-(child.offset??0),buffers,depth+1)})}case"dictionary":{const keys=descriptor.children?.[0]??descriptor;const dictionary=descriptor.dictionary??descriptor.children?.[1];if(!dictionary||!keys){throw invalidArgument("Dictionary descriptor has no dictionary values")}const index=readIndex(keys,buffers,physicalIndex,type.indexType);if(index<0||index>=dictionary.length){throw invalidArgument("Dictionary index is out of bounds")}return decodeNativeValue(dictionary,index,buffers,depth+1)}case"run-end-encoded":{const runEnds=descriptor.runEnds??descriptor.children?.[0];const values=descriptor.children?.[descriptor.runEnds?0:1];if(!runEnds||!values){throw invalidArgument("Run-end encoded descriptor is incomplete")}const logicalPosition=physicalIndex+1;let run=0;while(run<runEnds.length&&numericIndexValue(runEnds,buffers,run)<logicalPosition){run+=1}if(run>=values.length){throw invalidArgument("Run-end encoded value is out of bounds")}return decodeNativeValue(values,run,buffers,depth+1)}case"extension":throw invalidArgument("Nested extension data type could not be unwrapped")}}function decodeListLike(descriptor,buffers,physicalIndex,type,depth){const width=type.type==="large-list"||type.type==="large-list-view"?8:4;const offsets=requiredRegion(descriptor.offsets,buffers,"list offsets");const start=readSignedOffset(offsets,physicalIndex,width);const end=type.type==="list-view"||type.type==="large-list-view"?start+readSignedOffset(requiredRegion(descriptor.sizes,buffers,"list sizes"),physicalIndex,width):readSignedOffset(offsets,physicalIndex+1,width);if(start<0||end<start){throw invalidArgument("List offsets are invalid")}const child=requiredChild(descriptor,0,type.type);const values=Object.freeze(Array.from({length:end-start},(_,index)=>decodeNativeValue(child,start+index-(child.offset??0),buffers,depth+1)));if(type.type!=="map"){return values}return Object.freeze(values.map(entry=>{if(!isRecord5(entry)){throw invalidArgument("Map entries must decode from a struct")}const record=entry;const entryType=type.entries.dataType;const fields=entryType.type==="struct"?entryType.fields:[];const keyName=fields[0]?.name??"key";const valueName=fields[1]?.name??"value";return Object.freeze({key:record[keyName]??null,value:record[valueName]??null})}))}function decodeInterval(descriptor,buffers,index,unit){const values=requiredRegion(descriptor.values,buffers,"interval values");const view=new DataView(values.buffer,values.byteOffset,values.byteLength);if(unit==="year-month"){ensureViewRange(view,index*4,4,"year-month interval");return Object.freeze({kind:"interval",unit,months:view.getInt32(index*4,true)})}if(unit==="day-time"){const offset2=index*8;ensureViewRange(view,offset2,8,"day-time interval");return Object.freeze({kind:"interval",unit,days:view.getInt32(offset2,true),milliseconds:view.getInt32(offset2+4,true)})}const offset=index*16;ensureViewRange(view,offset,16,"month-day-nano interval");return Object.freeze({kind:"interval",unit,months:view.getInt32(offset,true),days:view.getInt32(offset+4,true),nanoseconds:view.getBigInt64(offset+8,true)})}function decodeVariableBytes(descriptor,buffers,index,offsetWidth){const offsets=requiredRegion(descriptor.offsets,buffers,"variable offsets");const data=requiredRegion(descriptor.data??descriptor.values,buffers,"variable data");const start=readUnsignedOffset(offsets,index,offsetWidth);const end=readUnsignedOffset(offsets,index+1,offsetWidth);return checkedSlice(data,start,end,"variable data")}function decodeViewBytes(descriptor,buffers,index){const views=requiredRegion(descriptor.values,buffers,"view values");const view=new DataView(views.buffer,views.byteOffset,views.byteLength);const offset=index*16;ensureViewRange(view,offset,16,"view value");const length=view.getInt32(offset,true);if(length<0){throw invalidArgument("View length must be non-negative")}if(length<=12){return checkedSlice(views,offset+4,offset+4+length,"inline view")}const bufferIndex=view.getInt32(offset+8,true);const dataOffset=view.getInt32(offset+12,true);const data=descriptor.variadicBuffers?.[bufferIndex];if(!data||dataOffset<0){throw invalidArgument("View references an invalid variadic buffer")}return checkedSlice(regionView(data,buffers,"view data"),dataOffset,dataOffset+length,"view data")}function readNumber(descriptor,buffers,index,width,signedness){const values=requiredRegion(descriptor.values,buffers,"numeric values");const view=new DataView(values.buffer,values.byteOffset,values.byteLength);const offset=index*width;ensureViewRange(view,offset,width,"numeric value");if(width===1)return signedness==="signed"?view.getInt8(offset):view.getUint8(offset);if(width===2)return signedness==="signed"?view.getInt16(offset,true):view.getUint16(offset,true);return signedness==="signed"?view.getInt32(offset,true):view.getUint32(offset,true)}function readFloat(descriptor,buffers,index,width){const values=requiredRegion(descriptor.values,buffers,"floating-point values");const view=new DataView(values.buffer,values.byteOffset,values.byteLength);const offset=index*width;ensureViewRange(view,offset,width,"floating-point value");return width===4?view.getFloat32(offset,true):view.getFloat64(offset,true)}function readBigInt(descriptor,buffers,index,signed){const values=requiredRegion(descriptor.values,buffers,"64-bit values");const view=new DataView(values.buffer,values.byteOffset,values.byteLength);const offset=index*8;ensureViewRange(view,offset,8,"64-bit value");return signed?view.getBigInt64(offset,true):view.getBigUint64(offset,true)}function readIndex(descriptor,buffers,index,dataType){const type=unwrapExtension(dataType).type;let value;if(type==="int8")value=readNumber(descriptor,buffers,index,1,"signed");else if(type==="uint8")value=readNumber(descriptor,buffers,index,1,"unsigned");else if(type==="int16")value=readNumber(descriptor,buffers,index,2,"signed");else if(type==="uint16")value=readNumber(descriptor,buffers,index,2,"unsigned");else if(type==="int32")value=readNumber(descriptor,buffers,index,4,"signed");else if(type==="uint32")value=readNumber(descriptor,buffers,index,4,"unsigned");else if(type==="int64")value=readBigInt(descriptor,buffers,index,true);else if(type==="uint64")value=readBigInt(descriptor,buffers,index,false);else throw invalidArgument("Dictionary index type must be an integer");const numeric2=typeof value==="bigint"?Number(value):value;if(!Number.isSafeInteger(numeric2)){throw invalidArgument("Dictionary index exceeds the JavaScript safe integer range")}return numeric2}function numericIndexValue(descriptor,buffers,index){const type=unwrapExtension(descriptor.dataType);return readIndex({...descriptor,dataType:{type:"dictionary",indexType:type,valueType:{type:"null"}}},buffers,index,type)}function readSignedLittleEndian(bytes,offset,width){const slice=checkedSlice(bytes,offset,offset+width,"signed integer");let value=0n;for(let index=slice.byteLength-1;index>=0;index-=1){value=value<<8n|BigInt(slice[index])}const sign=1n<<BigInt(width*8-1);return(value&sign)===0n?value:value-(1n<<BigInt(width*8))}function readUnsignedOffset(bytes,index,width){const value=readOffset(bytes,index,width,false);if(value<0){throw invalidArgument("Offset must be non-negative")}return value}function readSignedOffset(bytes,index,width){return readOffset(bytes,index,width,true)}function readOffset(bytes,index,width,signed){const view=new DataView(bytes.buffer,bytes.byteOffset,bytes.byteLength);const offset=index*width;ensureViewRange(view,offset,width,"offset");const value=width===4?signed?view.getInt32(offset,true):view.getUint32(offset,true):signed?view.getBigInt64(offset,true):view.getBigUint64(offset,true);const numeric2=typeof value==="bigint"?Number(value):value;if(!Number.isSafeInteger(numeric2)){throw invalidArgument("Offset exceeds the JavaScript safe integer range")}return numeric2}function validAt(validity,index,buffers){if(!validity)return true;const bitmap=regionView(validity,buffers,"validity bitmap");const bitIndex=(validity.bitOffset??0)+index;if(bitIndex<0||bitIndex>>>3>=bitmap.byteLength){throw invalidArgument("Validity bitmap index is out of bounds")}return(bitmap[bitIndex>>>3]&1<<(bitIndex&7))!==0}function requiredRegion(region,buffers,name){if(!region)throw invalidArgument(`${name} are missing`);return regionView(region,buffers,name)}function regionView(region,buffers,name){if(!isRecord5(region)||!Number.isSafeInteger(region.buffer)||region.buffer<0){throw invalidArgument(`${name} references an invalid buffer`)}const buffer=buffers[region.buffer];if(!buffer)throw invalidArgument(`${name} references a missing buffer`);const byteOffset=region.byteOffset??0;const byteLength=region.byteLength??buffer.byteLength-byteOffset;if(!Number.isSafeInteger(byteOffset)||byteOffset<0||!Number.isSafeInteger(byteLength)||byteLength<0||byteOffset+byteLength>buffer.byteLength){throw invalidArgument(`${name} region is outside its buffer`)}return buffer.subarray(byteOffset,byteOffset+byteLength)}function requiredChild(descriptor,index,name){const child=descriptor.children?.[index];if(!child)throw invalidArgument(`${name} descriptor has no child ${index}`);return child}function checkedSlice(bytes,start,end,name){if(!Number.isSafeInteger(start)||!Number.isSafeInteger(end)||start<0||end<start||end>bytes.byteLength){throw invalidArgument(`${name} slice is out of bounds`)}return bytes.subarray(start,end)}function ensureViewRange(view,offset,width,name){if(offset<0||offset+width>view.byteLength){throw invalidArgument(`${name} is out of bounds`)}}function unwrapExtension(dataType){let current=dataType;for(let depth=0;current.type==="extension";depth+=1){if(depth>=MAX_NESTING_DEPTH)throw invalidArgument("Extension nesting is too deep");current=current.storageType}return current}function freezeWireColumn(column){return Object.freeze({columnId:column.columnId,native:freezeNative(column.native),display:Object.freeze({...column.display,data:freezeRegion(column.display.data),offsets:freezeRegion(column.display.offsets),...column.display.validity?{validity:freezeRegion(column.display.validity)}:{}})})}function freezeNative(descriptor){const freezeOptionalRegion=region=>region?freezeRegion(region):void 0;return Object.freeze({...descriptor,dataType:freezeDataType(descriptor.dataType),...freezeOptionalRegion(descriptor.validity)?{validity:freezeOptionalRegion(descriptor.validity)}:{},...freezeOptionalRegion(descriptor.values)?{values:freezeOptionalRegion(descriptor.values)}:{},...freezeOptionalRegion(descriptor.offsets)?{offsets:freezeOptionalRegion(descriptor.offsets)}:{},...freezeOptionalRegion(descriptor.sizes)?{sizes:freezeOptionalRegion(descriptor.sizes)}:{},...freezeOptionalRegion(descriptor.data)?{data:freezeOptionalRegion(descriptor.data)}:{},...freezeOptionalRegion(descriptor.typeIds)?{typeIds:freezeOptionalRegion(descriptor.typeIds)}:{},...freezeOptionalRegion(descriptor.unionOffsets)?{unionOffsets:freezeOptionalRegion(descriptor.unionOffsets)}:{},...descriptor.variadicBuffers?{variadicBuffers:Object.freeze(descriptor.variadicBuffers.map(freezeRegion))}:{},...descriptor.children?{children:Object.freeze(descriptor.children.map(freezeNative))}:{},...descriptor.dictionary?{dictionary:freezeNative(descriptor.dictionary)}:{},...descriptor.runEnds?{runEnds:freezeNative(descriptor.runEnds)}:{}})}function freezeRegion(region){return Object.freeze({...region})}function freezeDataType(dataType){return normalizeDataTypeUnchecked(dataType,0)}function normalizeDataTypeUnchecked(value,depth){return normalizeDataType(value,depth)}function timeUnit(value){if(value==="second"||value==="millisecond"||value==="microsecond"||value==="nanosecond"){return value}throw invalidArgument("Arrow time unit is invalid")}function intervalUnit(value){if(value==="year-month"||value==="day-time"||value==="month-day-nano")return value;throw invalidArgument("Arrow interval unit is invalid")}function decodeFloat16(bits){const sign=(bits&32768)===0?1:-1;const exponent=bits>>>10&31;const fraction=bits&1023;if(exponent===0)return sign*2**-14*(fraction/1024);if(exponent===31)return fraction===0?sign*Infinity:Number.NaN;return sign*2**(exponent-15)*(1+fraction/1024)}function normalizeCellLimit(value){const maxCells=value??DEFAULT_TO_ROWS_CELL_LIMIT;assertPositiveSafeInteger(maxCells,"maxCells");return maxCells}function assertCellLimit(rows,columns,maxCells){const cellCount=rows*columns;if(!Number.isSafeInteger(cellCount)||cellCount>maxCells){throw new TabularkError("RESOURCE_LIMIT",`Decoding ${cellCount} cells exceeds the toRows limit of ${maxCells}`,{details:{resource:"row-materialization-cells",required:cellCount,available:maxCells,cellCount,maxCells}})}}function integer(value,name){if(!Number.isSafeInteger(value))throw invalidArgument(`${name} must be a safe integer`);return value}function positiveInteger(value,name){const result=integer(value,name);if(result<=0)throw invalidArgument(`${name} must be positive`);return result}function asUint8Array(value){if(value instanceof ArrayBuffer)return new Uint8Array(value);return new Uint8Array(value.buffer,value.byteOffset,value.byteLength)}function isRecord5(value){return typeof value==="object"&&value!==null}function assertNonNegativeSafeInteger(value,name){if(!Number.isSafeInteger(value)||value<0){throw invalidArgument(`${name} must be a non-negative safe integer`,{name,value})}}function assertPositiveSafeInteger(value,name){if(!Number.isSafeInteger(value)||value<=0){throw invalidArgument(`${name} must be a positive safe integer`,{name,value})}}var ByteLruCache=class{#maxBytes;#entries=new Map;#onRemove;#byteLength=0;constructor(maxBytes,options={}){if(!Number.isSafeInteger(maxBytes)||maxBytes<0){throw new RangeError("maxBytes must be a non-negative safe integer")}this.#maxBytes=maxBytes;this.#onRemove=options.onRemove}get maxBytes(){return this.#maxBytes}get(key){const entry=this.#entries.get(key);if(!entry){return void 0}this.#entries.delete(key);this.#entries.set(key,entry);return entry.value}set(key,value,byteLength){if(!Number.isSafeInteger(byteLength)||byteLength<0){throw new RangeError("byteLength must be a non-negative safe integer")}if(byteLength>this.#maxBytes){return}const existing=this.#entries.get(key);if(existing){this.#remove(key,existing)}while(this.#byteLength+byteLength>this.#maxBytes){const oldestKey=this.#entries.keys().next().value;if(oldestKey===void 0){break}const oldest=this.#entries.get(oldestKey);this.#remove(oldestKey,oldest)}this.#entries.set(key,{value,byteLength});this.#byteLength+=byteLength}deleteWhere(predicate){for(const[key,entry]of this.#entries){if(!predicate(key,entry.value)){continue}this.#remove(key,entry)}}clear(){for(const[key,entry]of this.#entries){this.#onRemove?.(key,entry.value,entry.byteLength)}this.#entries.clear();this.#byteLength=0}#remove(key,entry){this.#entries.delete(key);this.#byteLength-=entry.byteLength;this.#onRemove?.(key,entry.value,entry.byteLength)}};function rangeCacheKey(owner,revision,schemaVersion,range){return JSON.stringify([owner,revision,schemaVersion,range.rowStart,range.rowCount,range.columnStart,range.columnCount])}function rangeCacheKeyBelongsTo(key,owner){return key.startsWith(`[${JSON.stringify(owner)},`)}function cloneWireTableBatch(batch){return{layoutVersion:batch.layoutVersion,tableId:batch.tableId,revision:batch.revision,schemaVersion:batch.schemaVersion,range:{...batch.range},buffers:batch.buffers.map(buffer=>Uint8Array.from(asUint8Array2(buffer)).buffer),columns:batch.columns,complete:batch.complete}}function wireBatchByteLength(batch){return batch.buffers.reduce((total,buffer)=>total+buffer.byteLength,0)}function asUint8Array2(value){return value instanceof ArrayBuffer?new Uint8Array(value):new Uint8Array(value.buffer,value.byteOffset,value.byteLength)}var DEFAULT_SHUTDOWN_TIMEOUT_MS=2e3;var RESPONSE_KINDS=new Set(["hello","dataset","tables","table","metadata","presentation","presentationRange","batch","acknowledged"]);var EVENT_NAMES=new Set(["progress","metadata","warning","closed","runtimeError"]);var WorkerRpcClient=class{#worker;#pending=new Map;#onEvent;#onFailure;#nextRequestId=1;#closed=false;constructor(worker,onEvent,onFailure=()=>{}){this.#worker=worker;this.#onEvent=onEvent;this.#onFailure=onFailure;worker.addEventListener("message",this.#handleMessage);worker.addEventListener("error",this.#handleWorkerFailure);worker.addEventListener("messageerror",this.#handleWorkerFailure)}async request(op,payload,expectedKind,options={}){if(this.#closed){throw closedError("Engine")}if(options.signal?.aborted){throw cancelledError()}const requestId=`r${this.#nextRequestId++}`;return new Promise((resolve,reject)=>{const cleanups=[];const cleanup=()=>{for(const dispose of cleanups.splice(0)){dispose()}};if(options.signal){const abort=()=>{const pending=this.#pending.get(requestId);if(!pending){return}this.#pending.delete(requestId);pending.cleanup();this.#postCancel(requestId);reject(cancelledError())};options.signal.addEventListener("abort",abort,{once:true});cleanups.push(()=>options.signal?.removeEventListener("abort",abort))}if(options.timeoutMs!==void 0){const timeoutMs=Math.max(1,options.timeoutMs);const timeoutId=globalThis.setTimeout(()=>{if(!this.#pending.has(requestId)){return}this.#failRuntime(new TabularkError("RUNTIME_FAILURE",`The Tabulark Worker did not respond to ${op} within ${timeoutMs}ms`))},timeoutMs);cleanups.push(()=>globalThis.clearTimeout(timeoutId))}this.#pending.set(requestId,{resolve:value=>resolve(value),reject,expectedKind,cleanup});try{this.#worker.postMessage({protocolVersion:PROTOCOL_VERSION,requestId,op,payload},options.transfer??[])}catch(error){this.#pending.delete(requestId);cleanup();reject(new TabularkError("RUNTIME_FAILURE","Could not send a request to the Worker",{cause:error}))}})}async shutdown(timeoutMs=DEFAULT_SHUTDOWN_TIMEOUT_MS){if(this.#closed){return}try{await this.request("shutdown",{},"acknowledged",{timeoutMs})}catch{}finally{this.terminate()}}terminate(error=new TabularkError("RUNTIME_FAILURE","The Tabulark Worker was terminated"),notifyFailure=false){if(this.#stop(error)&&notifyFailure){this.#notifyFailure(error)}}#handleMessage=event=>{const value=event.data;if(isValidProtocolEvent(value)){try{this.#onEvent(value)}catch(error){this.#failRuntime(new TabularkError("PROTOCOL_INCOMPATIBLE","The Worker emitted an invalid runtime event",{cause:error}))}return}if(looksLikeProtocolEvent(value)||looksLikeProtocolResponse(value)&&!isValidProtocolResponse(value)){this.#failRuntime(new TabularkError("PROTOCOL_INCOMPATIBLE","The Worker returned a malformed or incompatible protocol message"));return}if(!isValidProtocolResponse(value)){return}const pending=this.#pending.get(value.requestId);if(!pending){return}this.#pending.delete(value.requestId);pending.cleanup();if(value.status==="failure"){pending.reject(TabularkError.fromSerialized(value.error));return}if(value.result.kind!==pending.expectedKind){const error=new TabularkError("PROTOCOL_INCOMPATIBLE",`Expected a ${pending.expectedKind} response, received ${value.result.kind}`);pending.reject(error);this.#failRuntime(error);return}pending.resolve(value.result.data)};#handleWorkerFailure=event=>{if(this.#closed){return}let message="The Tabulark Worker stopped unexpectedly";if(typeof ErrorEvent!=="undefined"&&event instanceof ErrorEvent&&event.message){message=event.message}else if(event.type==="messageerror"){message="The Tabulark Worker could not deserialize a message"}this.#failRuntime(new TabularkError("RUNTIME_FAILURE",message))};#postCancel(targetRequestId){if(this.#closed){return}try{this.#worker.postMessage({protocolVersion:PROTOCOL_VERSION,requestId:`r${this.#nextRequestId++}`,op:"cancel",payload:{targetRequestId}})}catch{}}#failPending(error){for(const pending of this.#pending.values()){pending.cleanup();pending.reject(error)}this.#pending.clear()}#failRuntime(error){if(this.#stop(error)){this.#notifyFailure(error)}}#stop(error){if(this.#closed){return false}this.#closed=true;this.#worker.removeEventListener("message",this.#handleMessage);this.#worker.removeEventListener("error",this.#handleWorkerFailure);this.#worker.removeEventListener("messageerror",this.#handleWorkerFailure);try{this.#worker.terminate()}catch{}this.#failPending(error);return true}#notifyFailure(error){try{this.#onFailure(error)}catch{}}};function isValidProtocolResponse(value){if(!isRecord4(value)||value.protocolVersion!==PROTOCOL_VERSION||typeof value.requestId!=="string"||value.requestId.length===0){return false}if(value.status==="success"){return isRecord4(value.result)&&typeof value.result.kind==="string"&&RESPONSE_KINDS.has(value.result.kind)}if(value.status==="failure"){return isSerializedError(value.error)}return false}function isValidProtocolEvent(value){if(!isRecord4(value)||value.protocolVersion!==PROTOCOL_VERSION||typeof value.event!=="string"||!EVENT_NAMES.has(value.event)||!("payload"in value)){return false}if(!optionalNonEmptyString(value.requestId)||!optionalNonEmptyString(value.datasetHandle)||!optionalNonEmptyString(value.tableHandle)||!optionalNonEmptyString(value.tableId)||!optionalNonNegativeInteger(value.revision)){return false}if(value.tableHandle!==void 0&&value.datasetHandle===void 0){return false}if(value.event==="runtimeError"){return value.datasetHandle!==void 0||value.tableHandle===void 0&&value.tableId===void 0}return value.datasetHandle!==void 0}function isSerializedError(value){return isRecord4(value)&&typeof value.code==="string"&&typeof value.message==="string"&&typeof value.retryable==="boolean"}function optionalNonEmptyString(value){return value===void 0||typeof value==="string"&&value.length>0}function optionalNonNegativeInteger(value){return value===void 0||Number.isSafeInteger(value)&&value>=0}function looksLikeProtocolResponse(value){return isRecord4(value)&&("requestId"in value||"status"in value||"result"in value||"error"in value)}function looksLikeProtocolEvent(value){return isRecord4(value)&&"event"in value}var MIN_MEMORY_BUDGET_BYTES=8*1024*1024;var LIFECYCLE_CLOSE_TIMEOUT_MS=2e3;var MAX_ORPHAN_HANDLES=32;var MAX_ORPHAN_EVENTS_PER_HANDLE=16;var MAX_ORPHAN_EVENTS=256;var Engine=class _Engine{#rpc;#rangeCache;#maxArrayBufferBytes;#adapters;#sessions=new Map;#orphanEvents=new Map;#orphanEventCount=0;#closed=false;constructor(rpc,limits,adapters){this.#rpc=rpc;this.#rangeCache=new ByteLruCache(limits.mainThreadRangeCacheBytes);this.#maxArrayBufferBytes=limits.maxArrayBufferBytes;this.#adapters=new Map(adapters.map(adapter=>[adapter.id,adapter]))}static async create(options){const normalized=normalizeEngineOptions(options);if(typeof Worker==="undefined"||typeof Blob==="undefined"||typeof URL==="undefined"){throw new TabularkError("UNSUPPORTED_RUNTIME","Tabulark createEngine() requires a browser with module Worker and Blob support")}let engine;const worker=new Worker(normalized.workerUrl,{type:"module",name:normalized.workerName});const rpc=new WorkerRpcClient(worker,event=>{if(engine!==void 0){engine.#handleEvent(event)}},error=>{if(engine!==void 0){engine.#handleRuntimeFailure(error)}});engine=new _Engine(rpc,normalized.limits,normalized.adapters);try{const hello=await rpc.request("hello",{clientName:"tabulark-js",adapters:normalized.adapters.map(({id})=>Object.freeze({id})),memoryBudgetBytes:normalized.memoryBudgetBytes},"hello");const helloAdapters=isRecord4(hello)&&Array.isArray(hello.adapters)?hello.adapters:void 0;if(!isRecord4(hello)||hello.protocolVersion!==PROTOCOL_VERSION||hello.adapterApiVersion!==ADAPTER_API_VERSION||hello.batchLayoutVersion!==BATCH_LAYOUT_VERSION||!helloAdapters||helloAdapters.length!==normalized.adapters.length||normalized.adapters.some(adapter=>!helloAdapters.includes(adapter.id))){throw new TabularkError("PROTOCOL_INCOMPATIBLE","The Worker did not accept the current Tabulark protocol version")}return engine}catch(error){rpc.terminate();throw error}}async open(source,options){this.#assertOpen();const normalizedOptions=normalizeOpenOptions(options,this.#adapters,inferSourceName(source));const transfer=[];if(source instanceof ArrayBuffer){if(source.byteLength>this.#maxArrayBufferBytes){throw new TabularkError("RESOURCE_LIMIT",`ArrayBuffer sources larger than ${this.#maxArrayBufferBytes} bytes must be supplied as a Blob`,{details:{resource:"source-staging",requiredBytes:source.byteLength,availableBytes:this.#maxArrayBufferBytes}})}if(options.transferInput===true){transfer.push(source)}}else if(!(source instanceof Blob)){throw invalidArgument("source must be a Blob, File, or ArrayBuffer")}else if(options.transferInput===true){throw invalidArgument("transferInput may only be true for an ArrayBuffer source")}const dataset=await this.#rpc.request("openSource",{source,adapterId:normalizedOptions.adapter.id,options:normalizedOptions.options},"dataset",options.signal?{transfer,signal:options.signal}:{transfer});if(!isRecord4(dataset)||typeof dataset.datasetHandle!=="string"||dataset.datasetHandle.length===0){throw this.#terminateForProtocolFailure("Worker returned an invalid dataset handle")}try{const tableResult=await this.#rpc.request("listTables",{datasetHandle:dataset.datasetHandle},"tables",options.signal?{signal:options.signal}:{});if(options.signal?.aborted){throw cancelledError()}const tableDescriptors=normalizeDescriptors(tableResult);const session=new DatasetSessionImpl(this,dataset.datasetHandle,tableDescriptors);this.#sessions.set(dataset.datasetHandle,session);this.#deliverOrphanEvents(session);if(session.closed){throw session.terminalError??closedError("Dataset session")}return session}catch(error){const terminalError=this.#orphanRuntimeError(dataset.datasetHandle);const session=this.#sessions.get(dataset.datasetHandle);if(session){session.closeLocally();this.#sessions.delete(dataset.datasetHandle)}await this.#discardOpenedDataset(dataset.datasetHandle);throw terminalError??error}}async close(){if(this.#closed){return}this.#closed=true;for(const session of this.#sessions.values()){session.closeLocally()}this.#sessions.clear();this.#rangeCache.clear();this.#clearOrphanEvents();await this.#rpc.shutdown()}dispose(){return this.close()}async openTable(session,tableId){this.#assertOpen();session.assertOpen();if(!session.tables.some(table=>table.id===tableId)){throw invalidArgument(`Unknown table: ${tableId}`)}let tableHandle;try{const table=await this.#rpc.request("openTable",{datasetHandle:session.handle,tableId},"table");if(!isRecord4(table)||typeof table.tableHandle!=="string"||table.tableHandle.length===0){throw this.#terminateForProtocolFailure("Worker returned an invalid table handle")}tableHandle=table.tableHandle;const metadata=await this.#rpc.request("getMetadata",{tableHandle},"metadata");const normalizedMetadata=normalizeMetadataWire(metadata);this.#assertOpen();session.assertOpen();const handle=new TableHandleImpl(this,session,tableHandle,normalizedMetadata);session.addTableHandle(handle);return handle}catch(error){if(tableHandle!==void 0){await this.#discardOpenedTable(tableHandle)}throw error}}async readRange(table,request,options){this.#assertOpen();table.assertOpen();const normalized=validateRange(request);if(options.signal?.aborted){throw cancelledError()}const metadata=table.metadata;const key=rangeCacheKey(table.handle,metadata.revision,metadata.schema.version,normalized);const cached=this.#rangeCache.get(key);if(cached){return new ColumnarTableBatch(cloneWireTableBatch(cached))}const batch=await this.#rpc.request("readRange",{tableHandle:table.handle,range:normalized},"batch",options.signal?{signal:options.signal}:{});this.#assertOpen();table.assertOpen();if(batch.complete){const cachedBatch=cloneWireTableBatch(batch);this.#rangeCache.set(rangeCacheKey(table.handle,batch.revision,batch.schemaVersion,normalized),cachedBatch,wireBatchByteLength(cachedBatch))}return new ColumnarTableBatch(batch)}async getPresentation(table){this.#assertOpen();table.assertOpen();const value=await this.#rpc.request("getPresentation",{tableHandle:table.handle},"presentation");this.#assertOpen();table.assertOpen();return normalizePresentationWire(value,table.metadata)}async readPresentationRange(table,request,options){this.#assertOpen();table.assertOpen();const normalized=validateRange(request);if(options.signal?.aborted){throw cancelledError()}const value=await this.#rpc.request("readPresentationRange",{tableHandle:table.handle,range:normalized},"presentationRange",options.signal?{signal:options.signal}:{});this.#assertOpen();table.assertOpen();return normalizePresentationRangeWire(value,table.metadata,normalized)}async closeTable(table){if(table.closed){return}table.closeLocally();if(this.#closed){return}await this.#requestRemoteClose("closeTable",{tableHandle:table.handle})}clearTableCache(tableHandle){this.#rangeCache.deleteWhere(key=>rangeCacheKeyBelongsTo(key,tableHandle))}async closeSession(session){if(session.closed){return}session.closeLocally();if(this.#closed){this.#sessions.delete(session.handle);return}try{await this.#requestRemoteClose("closeSource",{datasetHandle:session.handle})}finally{this.#sessions.delete(session.handle);this.#deleteOrphanEvents(session.handle)}}#assertOpen(){if(this.#closed){throw closedError("Engine")}}#handleEvent(event){const handle=event.datasetHandle;if(!handle&&event.event==="runtimeError"){this.#handleRuntimeFailure(errorFromWire(event.payload));return}if(!handle){return}const session=this.#sessions.get(handle);if(!session){this.#rememberOrphanEvent(handle,event);return}session.handleEvent(event);if(event.event==="closed"&&!event.tableHandle&&session.closed){this.#sessions.delete(handle);this.#deleteOrphanEvents(handle)}}#deliverOrphanEvents(session){const events=this.#orphanEvents.get(session.handle);if(!events){return}this.#deleteOrphanEvents(session.handle);for(const event of events){session.handleEvent(event)}}#orphanRuntimeError(handle){const event=this.#orphanEvents.get(handle)?.find(candidate=>candidate.event==="runtimeError");return event?errorFromWire(event.payload):void 0}async#discardOpenedTable(tableHandle){if(this.#closed){return}try{await this.#rpc.request("closeTable",{tableHandle},"acknowledged",{timeoutMs:LIFECYCLE_CLOSE_TIMEOUT_MS})}catch(error){if(!this.#closed){this.#rpc.terminate(asTabularkError(error,"Could not release an opened table"),true)}}}async#discardOpenedDataset(datasetHandle){this.#deleteOrphanEvents(datasetHandle);if(this.#closed){return}try{await this.#rpc.request("closeSource",{datasetHandle},"acknowledged",{timeoutMs:LIFECYCLE_CLOSE_TIMEOUT_MS})}catch(error){if(!this.#closed){this.#rpc.terminate(asTabularkError(error,"Could not release an opened dataset"),true)}}finally{this.#deleteOrphanEvents(datasetHandle)}}async#requestRemoteClose(op,payload){try{await this.#rpc.request(op,payload,"acknowledged",{timeoutMs:LIFECYCLE_CLOSE_TIMEOUT_MS})}catch(error){if(!this.#closed){this.#rpc.terminate(asTabularkError(error,`Could not complete ${op}`),true)}throw error}}#terminateForProtocolFailure(message){const error=new TabularkError("PROTOCOL_INCOMPATIBLE",message);this.#rpc.terminate(error,true);return error}#rememberOrphanEvent(handle,event){if(event.event!=="runtimeError"&&event.event!=="closed"){return}let events=this.#orphanEvents.get(handle);if(!events){while(this.#orphanEvents.size>=MAX_ORPHAN_HANDLES){this.#evictOldestOrphanHandle()}events=[];this.#orphanEvents.set(handle,events)}if(events.length>=MAX_ORPHAN_EVENTS_PER_HANDLE){events.shift();this.#orphanEventCount-=1}while(this.#orphanEventCount>=MAX_ORPHAN_EVENTS){this.#evictOldestOrphanEvent()}events.push(event);this.#orphanEventCount+=1}#evictOldestOrphanEvent(){const oldest=this.#orphanEvents.entries().next().value;if(!oldest){this.#orphanEventCount=0;return}const[handle,events]=oldest;events.shift();this.#orphanEventCount-=1;if(events.length===0){this.#orphanEvents.delete(handle)}}#evictOldestOrphanHandle(){const handle=this.#orphanEvents.keys().next().value;if(handle!==void 0){this.#deleteOrphanEvents(handle)}}#deleteOrphanEvents(handle){const events=this.#orphanEvents.get(handle);if(!events){return}this.#orphanEventCount-=events.length;this.#orphanEvents.delete(handle)}#clearOrphanEvents(){this.#orphanEvents.clear();this.#orphanEventCount=0}#handleRuntimeFailure(error){if(this.#closed){return}this.#closed=true;this.#rangeCache.clear();this.#clearOrphanEvents();for(const session of this.#sessions.values()){session.failLocally(error)}this.#sessions.clear()}};var DatasetSessionImpl=class{#engine;handle;tables;#listeners=new Set;#tableHandles=new Set;closed=false;terminalError;constructor(engine,handle,tables){this.#engine=engine;this.handle=handle;this.tables=Object.freeze(tables.map(table=>Object.freeze({...table})))}openTable(tableId){return this.#engine.openTable(this,tableId)}subscribe(listener){this.assertOpen();this.#listeners.add(listener);return()=>this.#listeners.delete(listener)}close(){return this.#engine.closeSession(this)}assertOpen(){if(this.closed){throw closedError("Dataset session")}}addTableHandle(handle){this.#tableHandles.add(handle)}removeTableHandle(handle){this.#tableHandles.delete(handle)}closeLocally(){if(this.closed){return}this.closed=true;for(const table of this.#tableHandles){table.closeLocally()}this.#tableHandles.clear();this.#emit({type:"closed"})}failLocally(error){if(this.closed){return}this.closed=true;this.terminalError=error;this.#emit({type:"runtimeError",error});for(const table of[...this.#tableHandles]){table.failLocally(error)}this.#tableHandles.clear();this.#emit({type:"closed"})}handleEvent(event){if(this.closed&&event.event!=="closed"){return}switch(event.event){case"progress":this.#emit({type:"progress",progress:normalizeProgress(event.payload,event.tableId,event.revision)});break;case"metadata":{const metadata=normalizeMetadataWire(event.payload);this.#emit({type:"metadata",metadata});if(!event.tableHandle){for(const table of this.#tableHandles){if(table.metadata.tableId===metadata.tableId){table.updateMetadata(metadata)}}}break}case"warning":{const warning=normalizeWarning(event.payload);this.#emit({type:"warning",warning});for(const table of this.#tableHandles){if(table.matchesWarning(warning)){table.emitWarning(warning)}}break}case"runtimeError":{const error=errorFromWire(event.payload);if(event.tableHandle){this.#emit({type:"runtimeError",error})}else{this.failLocally(error)}break}case"closed":if(!event.tableHandle){this.closeLocally()}break}if(event.tableHandle){for(const table of this.#tableHandles){if(table.handle===event.tableHandle){table.handleEvent(event)}}}}#emit(event){for(const listener of this.#listeners){safelyCall(listener,event)}}};var TableHandleImpl=class{#engine;#session;handle;#metadata;#listeners=new Set;closed=false;constructor(engine,session,handle,metadata){this.#engine=engine;this.#session=session;this.handle=handle;this.#metadata=metadata}get metadata(){return this.#metadata}readRange(request,options={}){return this.#engine.readRange(this,request,options)}getPresentation(){return this.#engine.getPresentation(this)}readPresentationRange(request,options={}){return this.#engine.readPresentationRange(this,request,options)}subscribe(listener){this.assertOpen();this.#listeners.add(listener);return()=>this.#listeners.delete(listener)}close(){return this.#engine.closeTable(this)}assertOpen(){if(this.closed){throw closedError("Table handle")}}closeLocally(){if(this.closed){return}this.#engine.clearTableCache(this.handle);this.closed=true;this.#session.removeTableHandle(this);this.#emit({type:"closed"})}failLocally(error){if(this.closed){return}this.#engine.clearTableCache(this.handle);this.closed=true;this.#session.removeTableHandle(this);this.#emit({type:"runtimeError",error});this.#emit({type:"closed"})}updateMetadata(metadata){if(this.closed){return}this.#metadata=metadata;this.#emit({type:"metadata",metadata})}matchesWarning(warning){return warning.handle===this.handle||warning.handle===this.#session.handle}emitWarning(warning){if(!this.closed){this.#emit({type:"warning",warning})}}handleEvent(event){if(this.closed&&event.event!=="closed"){return}switch(event.event){case"metadata":this.updateMetadata(normalizeMetadataWire(event.payload));break;case"warning":this.emitWarning(normalizeWarning(event.payload));break;case"runtimeError":this.failLocally(errorFromWire(event.payload));break;case"closed":this.closeLocally();break;case"progress":break}}#emit(event){for(const listener of this.#listeners){safelyCall(listener,event)}}};function normalizeEngineOptions(options){if(!options||typeof options!=="object"){throw invalidArgument("createEngine options are required")}if("wasmModuleUrl"in options||"workerUrl"in options){throw invalidArgument("wasmModuleUrl and workerUrl were removed; register an official adapter instead")}if(!Array.isArray(options.adapters)||options.adapters.length===0){throw invalidArgument("adapters must contain at least one official adapter descriptor")}const adapters=[];const ids=new Set;for(const[index,descriptor]of options.adapters.entries()){const registration=resolveOfficialAdapter(descriptor);if(!registration){throw invalidArgument(`adapters[${index}] is not an official frozen adapter descriptor`)}if(ids.has(registration.id)){throw invalidArgument(`Adapter ${registration.id} is registered more than once`)}ids.add(registration.id);adapters.push(Object.freeze({...registration}))}const memoryBudgetBytes=options.memoryBudgetBytes??DEFAULT_MEMORY_BUDGET_BYTES;if(!Number.isSafeInteger(memoryBudgetBytes)||memoryBudgetBytes<=0){throw invalidArgument("memoryBudgetBytes must be a positive safe integer")}if(memoryBudgetBytes<MIN_MEMORY_BUDGET_BYTES){throw invalidArgument(`memoryBudgetBytes must be at least ${MIN_MEMORY_BUDGET_BYTES} bytes`,{minimum:MIN_MEMORY_BUDGET_BYTES,memoryBudgetBytes})}return{memoryBudgetBytes,limits:deriveMemoryBudgetLimits(memoryBudgetBytes),adapters:Object.freeze(adapters),workerUrl:new URL("./worker.js",import.meta.url).href,workerName:options.workerName??"tabulark"}}function normalizeOpenOptions(options,adapters,inferredSourceName){if(!options||typeof options!=="object"){throw invalidArgument("open options are required")}if(options.transferInput!==void 0&&typeof options.transferInput!=="boolean"){throw invalidArgument("transferInput must be a boolean")}const selected=resolveOfficialAdapter(options.adapter);if(!selected){throw invalidArgument("adapter must be an official frozen adapter descriptor")}const registered=adapters.get(selected.id);if(!registered){throw invalidArgument(`Adapter ${selected.id} was not registered with this engine`)}const rawOptions=options.adapterOptions;if(rawOptions!==void 0&&(!isRecord4(rawOptions)||Array.isArray(rawOptions))){throw invalidArgument("adapterOptions must be an object")}let normalized;switch(selected.id){case"tabulark:delimited":normalized=normalizeDelimitedOptions(rawOptions,inferredSourceName);break;case"tabulark:arrow-ipc":normalized=normalizeArrowOptions(rawOptions,inferredSourceName);break;case"tabulark:parquet":normalized=normalizeParquetOptions(rawOptions,inferredSourceName);break;case"tabulark:excel":normalized=normalizeExcelOptions(rawOptions,inferredSourceName);break}return{adapter:registered,options:normalized}}function normalizeDelimitedOptions(options,inferredSourceName){const raw=options??{};assertManifestKeys("tabulark:delimited",raw);const dialect=raw.dialect??"csv";const header=raw.header??"first-row";const mode=raw.mode??"lenient";if(dialect!=="csv"&&dialect!=="tsv"){throw invalidArgument("dialect must be csv or tsv")}if(header!=="first-row"&&header!=="none"){throw invalidArgument("header must be first-row or none")}if(mode!=="lenient"&&mode!=="strict"){throw invalidArgument("mode must be lenient or strict")}const delimiter=raw.delimiter??(dialect==="csv"?",":" ");if(!isValidDelimiter(delimiter)){throw invalidArgument("delimiter must be one non-NUL ASCII byte other than CR, LF, or quote")}const sourceName=normalizeSourceName(raw.sourceName??inferredSourceName);return Object.freeze({dialect,header,mode,delimiter,...sourceName===void 0?{}:{sourceName}})}function normalizeArrowOptions(options,inferredSourceName){const raw=options??{};assertManifestKeys("tabulark:arrow-ipc",raw);const container=raw.container??"auto";if(container!=="auto"&&container!=="file"&&container!=="stream"){throw invalidArgument("container must be auto, file, or stream")}const sourceName=normalizeSourceName(raw.sourceName??inferredSourceName);return Object.freeze({container,...sourceName===void 0?{}:{sourceName}})}function normalizeParquetOptions(options,inferredSourceName){const raw=options??{};assertManifestKeys("tabulark:parquet",raw);const sourceName=normalizeSourceName(raw.sourceName??inferredSourceName);return Object.freeze(sourceName===void 0?{}:{sourceName})}function normalizeExcelOptions(options,inferredSourceName){const raw=options??{};assertManifestKeys("tabulark:excel",raw);const format=raw.format??"auto";if(format!=="auto"&&format!=="xls"&&format!=="xlsx"){throw invalidArgument("format must be auto, xls, or xlsx")}const sourceName=normalizeSourceName(raw.sourceName??inferredSourceName);return Object.freeze({format,...sourceName===void 0?{}:{sourceName}})}function normalizeSourceName(value){if(value===void 0)return void 0;if(typeof value!=="string"||value.length===0||value.length>1024){throw invalidArgument("sourceName must contain between 1 and 1024 characters")}return value}function assertManifestKeys(id,value){const allowedSet=new Set(officialAdapterManifestEntry(id).options.allowedKeys);for(const key of Object.keys(value)){if(!allowedSet.has(key)){throw invalidArgument(`Unknown adapter option: ${key}`)}}}function normalizeDescriptors(value){if(!Array.isArray(value)){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Worker returned invalid table descriptors")}return value.map((entry,index)=>{if(!isRecord4(entry)||typeof entry.id!=="string"||typeof entry.name!=="string"){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Worker returned an invalid table descriptor at index ${index}`)}return{id:entry.id,name:entry.name}})}function normalizeMetadataWire(value){if(!isRecord4(value)||typeof value.tableId!=="string"||typeof value.name!=="string"){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Worker returned invalid table metadata")}const rawExtent=isRecord4(value.extent)?value.extent:{};const rawSchema=isRecord4(value.schema)?value.schema:{};const rawCapabilities=isRecord4(value.capabilities)?value.capabilities:{};const columns=Array.isArray(rawSchema.columns)?rawSchema.columns.map((column,index)=>normalizeColumn(column,index)):[];return normalizeMetadata({tableId:value.tableId,name:value.name,revision:numeric(value.revision,0),extent:{rows:normalizeAxis(rawExtent.rows,"at-least",0),columns:normalizeAxis(rawExtent.columns,"exact",columns.length)},schema:{version:numeric(rawSchema.version,0),columns},capabilities:{...rawCapabilities,randomAccess:rawCapabilities.randomAccess==="full"?"full":"indexed-prefix",typedValues:rawCapabilities.typedValues===true,search:rawCapabilities.search===true,sort:rawCapabilities.sort===true,filter:rawCapabilities.filter===true,multiTable:rawCapabilities.multiTable===true}})}function normalizePresentationWire(value,metadata){if(value===null||value===void 0){return null}if(!isRecord4(value)||value.kind!=="spreadsheet-v1"){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Worker returned an invalid table presentation")}if(value.tableId!==metadata.tableId){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Presentation tableId does not match its table")}const visibility=value.visibility==="hidden"||value.visibility==="very-hidden"?value.visibility:"visible";return Object.freeze({kind:"spreadsheet-v1",tableId:metadata.tableId,revision:numeric(value.revision,metadata.revision),visibility,frozenRows:numeric(value.frozenRows,0),frozenColumns:numeric(value.frozenColumns,0),rows:normalizePresentationAxis(value.rows,"rows"),columns:normalizePresentationAxis(value.columns,"columns"),styles:normalizePresentationStyles(value.styles)})}function normalizePresentationRangeWire(value,metadata,requested){if(value===null||value===void 0){return null}if(!isRecord4(value)||value.kind!=="spreadsheet-v1"||value.tableId!==metadata.tableId){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Worker returned an invalid presentation range")}const range=isRecord4(value.range)?value.range:{};for(const key of["rowStart","rowCount","columnStart","columnCount"]){if(range[key]!==requested[key]){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Presentation range must be aligned with its requested range")}}if(!Array.isArray(value.styleIds)||value.styleIds.length!==requested.rowCount){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Presentation style rows do not match the range")}const styleIds=Object.freeze(value.styleIds.map((row,rowIndex)=>{if(!Array.isArray(row)||row.length!==requested.columnCount){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation style row ${rowIndex} does not match the range`)}return Object.freeze(row.map(styleId=>styleId===null||Number.isSafeInteger(styleId)&&styleId>=0?styleId:invalidPresentationStyleId()))}));const mergedCells=Array.isArray(value.mergedCells)?Object.freeze(value.mergedCells.map((region,index)=>normalizeMergedCell(region,index))):Object.freeze([]);return Object.freeze({kind:"spreadsheet-v1",tableId:metadata.tableId,revision:numeric(value.revision,metadata.revision),range:Object.freeze({...requested}),styleIds,mergedCells,rows:normalizePresentationAxis(value.rows,"rows"),columns:normalizePresentationAxis(value.columns,"columns")})}function invalidPresentationStyleId(){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Presentation style IDs must be non-negative integers or null")}function normalizePresentationAxis(value,name){if(value===void 0)return Object.freeze([]);if(!Array.isArray(value)){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation ${name} must be an array`)}const seen=new Set;return Object.freeze(value.map((entry,index)=>{if(!isRecord4(entry)||!Number.isSafeInteger(entry.index)||entry.index<0){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation ${name}[${index}] has an invalid index`)}const axisIndex=entry.index;if(seen.has(axisIndex)){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation ${name} contains duplicate index ${axisIndex}`)}seen.add(axisIndex);if(entry.size!==void 0&&(typeof entry.size!=="number"||!Number.isFinite(entry.size)||entry.size<0)){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation ${name}[${index}] has an invalid size`)}if(entry.hidden!==void 0&&typeof entry.hidden!=="boolean"){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation ${name}[${index}] has an invalid hidden flag`)}return Object.freeze({index:axisIndex,...entry.size===void 0?{}:{size:entry.size},...entry.hidden===void 0?{}:{hidden:entry.hidden}})}))}function normalizePresentationStyles(value){if(value===void 0)return Object.freeze([]);if(!Array.isArray(value)){throw new TabularkError("PROTOCOL_INCOMPATIBLE","Presentation styles must be an array")}return Object.freeze(value.map((style,index)=>{if(!isRecord4(style)){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Presentation style ${index} must be an object`)}return Object.freeze({...typeof style.numberFormat==="string"?{numberFormat:style.numberFormat}:{},...normalizePresentationFont(style.font)?{font:normalizePresentationFont(style.font)}:{},...normalizePresentationColor(style.foregroundColor)?{foregroundColor:normalizePresentationColor(style.foregroundColor)}:{},...normalizePresentationColor(style.backgroundColor)?{backgroundColor:normalizePresentationColor(style.backgroundColor)}:{},...normalizePresentationColor(style.fillColor)?{fillColor:normalizePresentationColor(style.fillColor)}:{},...normalizePresentationBorders(style.borders)?{borders:normalizePresentationBorders(style.borders)}:{},...isHorizontalAlignment(style.horizontalAlignment)?{horizontalAlignment:style.horizontalAlignment}:{},...isVerticalAlignment(style.verticalAlignment)?{verticalAlignment:style.verticalAlignment}:{},...typeof style.wrapText==="boolean"?{wrapText:style.wrapText}:{}})}))}function normalizePresentationColor(value){if(!isRecord4(value)||typeof value.css!=="string"||value.css.length===0||value.css.length>128){return void 0}return Object.freeze({css:value.css})}function normalizePresentationFont(value){if(!isRecord4(value))return void 0;const color=normalizePresentationColor(value.color);const size=typeof value.size==="number"&&Number.isFinite(value.size)&&value.size>0?value.size:void 0;const font={...typeof value.family==="string"&&value.family.length>0?{family:value.family}:{},...size===void 0?{}:{size},...typeof value.bold==="boolean"?{bold:value.bold}:{},...typeof value.italic==="boolean"?{italic:value.italic}:{},...typeof value.underline==="boolean"?{underline:value.underline}:{},...color===void 0?{}:{color}};return Object.keys(font).length===0?void 0:Object.freeze(font)}function normalizePresentationBorders(value){if(!isRecord4(value))return void 0;const sides=["top","right","bottom","left"];const result={};for(const side of sides){const raw=value[side];if(!isRecord4(raw))continue;const style=isBorderStyle(raw.style)?raw.style:void 0;const color=normalizePresentationColor(raw.color);if(style!==void 0||color!==void 0){result[side]=Object.freeze({...style===void 0?{}:{style},...color===void 0?{}:{color}})}}return Object.keys(result).length===0?void 0:Object.freeze(result)}function normalizeMergedCell(value,index){if(!isRecord4(value)){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Merged cell ${index} must be an object`)}const fields=["rowStart","rowEnd","columnStart","columnEnd"];for(const field of fields){if(!Number.isSafeInteger(value[field])||value[field]<0){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Merged cell ${index} has an invalid ${field}`)}}const region={rowStart:value.rowStart,rowEnd:value.rowEnd,columnStart:value.columnStart,columnEnd:value.columnEnd};if(region.rowEnd<=region.rowStart||region.columnEnd<=region.columnStart){throw new TabularkError("PROTOCOL_INCOMPATIBLE",`Merged cell ${index} must be non-empty`)}return Object.freeze(region)}function isBorderStyle(value){return value==="none"||value==="thin"||value==="medium"||value==="thick"||value==="dashed"||value==="dotted"||value==="double"}function isHorizontalAlignment(value){return value==="general"||value==="left"||value==="center"||value==="right"||value==="justify"}function isVerticalAlignment(value){return value==="top"||value==="center"||value==="bottom"||value==="justify"}function normalizeColumn(value,index){const raw=isRecord4(value)?value:{};return{id:typeof raw.id==="string"?raw.id:`c${index}`,name:typeof raw.name==="string"?raw.name:`column_${index+1}`,index:numeric(raw.index,index),dataType:normalizeDataType(raw.dataType??{type:"unknown"}),nullable:raw.nullable!==false,...isRecord4(raw.metadata)?{metadata:Object.freeze(Object.fromEntries(Object.entries(raw.metadata).map(([key,entry])=>[key,String(entry)])))}:{}}}function normalizeAxis(value,fallbackKind,fallbackValue){if(isRecord4(value)){if(value.kind==="unknown"){return{kind:"unknown"}}if((value.kind==="exact"||value.kind==="at-least")&&Number.isSafeInteger(value.value)&&value.value>=0){return{kind:value.kind,value:value.value}}}return{kind:fallbackKind,value:fallbackValue}}function isValidDelimiter(value){if(typeof value!=="string"||value.length!==1){return false}const byte=value.charCodeAt(0);return byte<=127&&byte!==0&&byte!==13&&byte!==10&&byte!==34}function normalizeProgress(value,tableId,revision){const raw=isRecord4(value)?value:{};return{sourceHandle:typeof raw.sourceHandle==="string"?raw.sourceHandle:"",...typeof raw.tableId==="string"&&raw.tableId.length>0?{tableId:raw.tableId}:typeof tableId==="string"&&tableId.length>0?{tableId}:{},...Number.isSafeInteger(raw.revision)&&raw.revision>=0?{revision:raw.revision}:Number.isSafeInteger(revision)&&revision>=0?{revision}:{},bytesScanned:numeric(raw.bytesScanned,0),rowsDiscovered:numeric(raw.rowsDiscovered,0),done:raw.done===true}}function normalizeWarning(value){const raw=isRecord4(value)?value:{};return{handle:typeof raw.handle==="string"?raw.handle:"",kind:typeof raw.kind==="string"?raw.kind:"warning",message:typeof raw.message==="string"?raw.message:"Source warning",...Number.isSafeInteger(raw.byteOffset)?{byteOffset:raw.byteOffset}:{},...Number.isSafeInteger(raw.row)&&raw.row>=0?{row:raw.row}:{}}}function inferSourceName(source){if(typeof File!=="undefined"&&source instanceof File&&source.name.length>0){return source.name}return void 0}function errorFromWire(value){if(isRecord4(value)&&typeof value.code==="string"&&typeof value.message==="string"){return TabularkError.fromSerialized({code:value.code,message:value.message,retryable:value.retryable===true,...value.details===void 0?{}:{details:value.details}})}return new TabularkError("RUNTIME_FAILURE","The Worker reported a runtime failure")}function asTabularkError(error,message){return error instanceof TabularkError?error:new TabularkError("RUNTIME_FAILURE",message,{cause:error})}function numeric(value,fallback){return Number.isSafeInteger(value)&&value>=0?value:fallback}function safelyCall(listener,value){try{listener(value)}catch(error){if(typeof reportError==="function"){reportError(error)}}}function createEngine(options){return Engine.create(options)}function createSelection(anchor,focus=anchor){assertCellPosition(anchor,"anchor");assertCellPosition(focus,"focus");const normalizedAnchor=Object.freeze({...anchor});const normalizedFocus=Object.freeze({...focus});return Object.freeze({anchor:normalizedAnchor,focus:normalizedFocus,range:selectionRange(normalizedAnchor,normalizedFocus)})}function selectionRange(anchor,focus){return Object.freeze({rowStart:Math.min(anchor.rowIndex,focus.rowIndex),rowEnd:Math.max(anchor.rowIndex,focus.rowIndex)+1,columnStart:Math.min(anchor.columnIndex,focus.columnIndex),columnEnd:Math.max(anchor.columnIndex,focus.columnIndex)+1})}function containsCell(range,cell){return cell.rowIndex>=range.rowStart&&cell.rowIndex<range.rowEnd&&cell.columnIndex>=range.columnStart&&cell.columnIndex<range.columnEnd}function clampCell(cell,rowCount,columnCount){if(rowCount<=0||columnCount<=0){return null}return Object.freeze({rowIndex:clampInteger(cell.rowIndex,0,rowCount-1),columnIndex:clampInteger(cell.columnIndex,0,columnCount-1)})}function moveCell(cell,command,rowCount,columnCount,pageRowCount){const current=clampCell(cell,rowCount,columnCount);if(current===null){return null}const page=Math.max(1,Math.floor(pageRowCount));switch(command){case"left":return clampCell({rowIndex:current.rowIndex,columnIndex:current.columnIndex-1},rowCount,columnCount);case"right":return clampCell({rowIndex:current.rowIndex,columnIndex:current.columnIndex+1},rowCount,columnCount);case"up":return clampCell({rowIndex:current.rowIndex-1,columnIndex:current.columnIndex},rowCount,columnCount);case"down":return clampCell({rowIndex:current.rowIndex+1,columnIndex:current.columnIndex},rowCount,columnCount);case"page-up":return clampCell({rowIndex:current.rowIndex-page,columnIndex:current.columnIndex},rowCount,columnCount);case"page-down":return clampCell({rowIndex:current.rowIndex+page,columnIndex:current.columnIndex},rowCount,columnCount);case"row-start":return Object.freeze({rowIndex:current.rowIndex,columnIndex:0});case"row-end":return Object.freeze({rowIndex:current.rowIndex,columnIndex:columnCount-1});case"table-start":return Object.freeze({rowIndex:0,columnIndex:0});case"table-end":return Object.freeze({rowIndex:rowCount-1,columnIndex:columnCount-1})}}function assertCellPosition(value,name){if(!Number.isSafeInteger(value.rowIndex)||value.rowIndex<0){throw invalidArgument(`${name}.rowIndex must be a non-negative safe integer`)}if(!Number.isSafeInteger(value.columnIndex)||value.columnIndex<0){throw invalidArgument(`${name}.columnIndex must be a non-negative safe integer`)}}function clampInteger(value,minimum,maximum){if(!Number.isFinite(value)){return minimum}return Math.min(maximum,Math.max(minimum,Math.trunc(value)))}var nextGridId=1;var AccessibleViewportGrid=class{element;statusElement;#idPrefix;#destroyed=false;constructor(ownerDocument,label="Data table"){this.#idPrefix=`tabulark-grid-${nextGridId}`;nextGridId+=1;this.element=ownerDocument.createElement("div");this.element.className="tabulark-a11y-grid";this.element.dataset.tabularkA11yGrid="";this.element.id=this.#idPrefix;this.element.setAttribute("role","grid");this.element.setAttribute("aria-label",label);this.element.tabIndex=0;visuallyHide(this.element);this.statusElement=ownerDocument.createElement("div");this.statusElement.className="tabulark-status";this.statusElement.dataset.tabularkStatus="";this.statusElement.setAttribute("role","status");this.statusElement.setAttribute("aria-live","polite");this.statusElement.setAttribute("aria-atomic","true");visuallyHide(this.statusElement)}update(snapshot){if(this.#destroyed){return}this.element.setAttribute("aria-label",snapshot.label);this.element.setAttribute("aria-colcount",String(snapshot.columnCount));setOptionalAttribute(this.element,"aria-rowcount",snapshot.exactRowCount===void 0?void 0:String(snapshot.exactRowCount+1));this.element.setAttribute("aria-busy",String(snapshot.busy));const fragment=this.element.ownerDocument.createDocumentFragment();fragment.append(this.#createHeader(snapshot.columns));let activeId;for(const row of snapshot.rows){const rowElement=this.element.ownerDocument.createElement("div");rowElement.setAttribute("role","row");rowElement.setAttribute("aria-rowindex",String(row.index+2));for(const cell of row.cells){const cellElement=this.element.ownerDocument.createElement("div");cellElement.setAttribute("role","gridcell");cellElement.setAttribute("aria-colindex",String(cell.columnIndex+1));cellElement.setAttribute("aria-selected",String(cell.selected));setOptionalAttribute(cellElement,"aria-rowspan",cell.rowSpan===void 0||cell.rowSpan<=1?void 0:String(cell.rowSpan));setOptionalAttribute(cellElement,"aria-colspan",cell.columnSpan===void 0||cell.columnSpan<=1?void 0:String(cell.columnSpan));cellElement.textContent=cell.value===void 0?"Loading":cell.value===null?"Empty":cell.value;if(cell.active){activeId=this.#cellId(cell.rowIndex,cell.columnIndex);cellElement.id=activeId}rowElement.append(cellElement)}fragment.append(rowElement)}this.element.replaceChildren(fragment);setOptionalAttribute(this.element,"aria-activedescendant",activeId);if(snapshot.status!==void 0&&snapshot.status!==this.statusElement.textContent){this.statusElement.textContent=snapshot.status}}focus(options){this.element.focus(options)}destroy(){if(this.#destroyed){return}this.#destroyed=true;this.element.remove();this.statusElement.remove()}#createHeader(columns){const row=this.element.ownerDocument.createElement("div");row.setAttribute("role","row");row.setAttribute("aria-rowindex","1");for(const column of columns){const cell=this.element.ownerDocument.createElement("div");cell.setAttribute("role","columnheader");cell.setAttribute("aria-colindex",String(column.index+1));cell.textContent=column.name;row.append(cell)}return row}#cellId(rowIndex,columnIndex){return`${this.#idPrefix}-r${rowIndex}-c${columnIndex}`}};function visuallyHide(element){Object.assign(element.style,{border:"0",clip:"rect(0 0 0 0)",clipPath:"inset(50%)",height:"1px",margin:"-1px",overflow:"hidden",padding:"0",pointerEvents:"none",position:"absolute",whiteSpace:"nowrap",width:"1px"})}function setOptionalAttribute(element,name,value){if(value===void 0){element.removeAttribute(name)}else{element.setAttribute(name,value)}}var DEFAULT_CANVAS_TABLE_THEME=Object.freeze({background:"#ffffff",foreground:"#172033",mutedForeground:"#667085",headerBackground:"#f2f4f7",headerForeground:"#344054",alternateRowBackground:"#f9fafb",gridLine:"#d0d5dd",selectionBackground:"rgba(21, 112, 239, 0.14)",selectionBorder:"#1570ef",activeCellBorder:"#175cd3",loadingBackground:"#e4e7ec",font:'13px ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif',headerFont:'600 13px ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif'});function forcedColorsCanvasTableTheme(base=DEFAULT_CANVAS_TABLE_THEME){return Object.freeze({...base,background:"Canvas",foreground:"CanvasText",mutedForeground:"GrayText",headerBackground:"Canvas",headerForeground:"CanvasText",alternateRowBackground:"Canvas",gridLine:"CanvasText",selectionBackground:"Highlight",selectionBorder:"Highlight",activeCellBorder:"CanvasText",loadingBackground:"GrayText"})}var CanvasTablePainter=class{canvas;#context;#theme;#maxDevicePixelRatio;#forcedColors;#cssWidth=0;#cssHeight=0;#devicePixelRatio=1;constructor(canvas,options={}){const context=canvas.getContext("2d",{alpha:false});if(context===null){throw new Error("Tabulark Canvas rendering requires a 2D rendering context")}this.canvas=canvas;this.#context=context;this.#theme=Object.freeze({...DEFAULT_CANVAS_TABLE_THEME,...options.theme});this.#maxDevicePixelRatio=positive(options.maxDevicePixelRatio,Number.POSITIVE_INFINITY);this.#forcedColors=options.forcedColors??false}setTheme(theme,options={}){this.#theme=Object.freeze({...theme});this.#forcedColors=options.forcedColors??false}paint(snapshot){this.#resize(snapshot.width,snapshot.height);const context=this.#context;const theme=this.#theme;context.save();context.setTransform(this.#devicePixelRatio,0,0,this.#devicePixelRatio,0,0);context.clearRect(0,0,snapshot.width,snapshot.height);context.fillStyle=theme.background;context.fillRect(0,0,snapshot.width,snapshot.height);this.#paintRows(snapshot);this.#paintHeader(snapshot);this.#paintGrid(snapshot);this.#paintMergedCells(snapshot);this.#paintSelection(snapshot);context.restore()}#resize(width,height){const view=this.canvas.ownerDocument.defaultView;const browserRatio=view?.devicePixelRatio??1;const ratio=Math.max(1,Math.min(browserRatio,this.#maxDevicePixelRatio));const cssWidth=Math.max(0,Math.floor(width));const cssHeight=Math.max(0,Math.floor(height));const pixelWidth=Math.max(1,Math.round(cssWidth*ratio));const pixelHeight=Math.max(1,Math.round(cssHeight*ratio));if(cssWidth===this.#cssWidth&&cssHeight===this.#cssHeight&&ratio===this.#devicePixelRatio&&this.canvas.width===pixelWidth&&this.canvas.height===pixelHeight){return}this.#cssWidth=cssWidth;this.#cssHeight=cssHeight;this.#devicePixelRatio=ratio;this.canvas.width=pixelWidth;this.canvas.height=pixelHeight;this.canvas.style.width=`${cssWidth}px`;this.canvas.style.height=`${cssHeight}px`}#paintRows(snapshot){const context=this.#context;const theme=this.#theme;const columnsByIndex=new Map(snapshot.columns.map(column=>[column.index,column]));context.font=theme.font;context.textBaseline="middle";const rows=[...snapshot.rows.filter(row=>row.frozen!==true),...snapshot.rows.filter(row=>row.frozen===true)];for(const row of rows){if(row.y+row.height<=snapshot.headerHeight||row.y>=snapshot.height){continue}context.fillStyle=row.index%2===0?theme.background:theme.alternateRowBackground;context.fillRect(0,row.y,snapshot.width,row.height);context.fillStyle=theme.mutedForeground;context.textAlign="right";context.fillText(String(row.index+1),snapshot.rowGutterWidth-10,row.y+row.height/2);const cells=[...row.cells.filter(cell=>columnsByIndex.get(cell.columnIndex)?.frozen!==true),...row.cells.filter(cell=>columnsByIndex.get(cell.columnIndex)?.frozen===true)];for(const cell of cells){const column=columnsByIndex.get(cell.columnIndex);if(column===void 0||column.x+column.width<=snapshot.rowGutterWidth||cell.coveredByMerge===true){continue}this.#paintCellValue(cell.value,column.x,row.y,column.width,row.height,cell.style)}}}#paintCellValue(value,x,y,width,height,style){const context=this.#context;const theme=this.#theme;const horizontalPadding=10;if(width<=horizontalPadding*2){return}context.save();context.beginPath();context.rect(x+1,y+1,Math.max(0,width-2),Math.max(0,height-2));context.clip();this.#paintCellFill(x,y,width,height,style);this.#applyCellFont(style);context.textAlign=horizontalAlignment(style);context.textBaseline=verticalBaseline(style);if(value===void 0){context.fillStyle=theme.loadingBackground;const skeletonWidth=Math.max(12,Math.min(width-horizontalPadding*2,width*.42));context.fillRect(x+horizontalPadding,y+height/2-3,skeletonWidth,6)}else{context.fillStyle=value===null?theme.mutedForeground:this.#cellForeground(style,theme.foreground);const label=value===null?"\u2205":value;const textX=horizontalTextX(context.textAlign,x,width,horizontalPadding);const textY=verticalTextY(context.textBaseline,y,height,4);context.fillText(label,textX,textY,Math.max(0,width-horizontalPadding*2));if(style?.font?.underline===true){const measured=Math.min(context.measureText(label).width,width-horizontalPadding*2);const start=underlineStart(context.textAlign,textX,measured);context.strokeStyle=String(context.fillStyle);context.lineWidth=1;context.beginPath();context.moveTo(start,Math.min(y+height-4,textY+3));context.lineTo(start+measured,Math.min(y+height-4,textY+3));context.stroke()}}this.#paintCellBorders(x,y,width,height,style);context.restore()}#paintMergedCells(snapshot){for(const merged of snapshot.mergedCells??[]){if(merged.width<=0||merged.height<=0||merged.x+merged.width<=snapshot.rowGutterWidth||merged.y+merged.height<=snapshot.headerHeight||merged.x>=snapshot.width||merged.y>=snapshot.height){continue}this.#context.fillStyle=merged.region.rowStart%2===0?this.#theme.background:this.#theme.alternateRowBackground;this.#context.fillRect(merged.x,merged.y,merged.width,merged.height);if(merged.continuation===true){this.#paintCellFill(merged.x,merged.y,merged.width,merged.height,merged.style);this.#paintCellBorders(merged.x,merged.y,merged.width,merged.height,merged.style)}else{this.#paintCellValue(merged.value,merged.x,merged.y,merged.width,merged.height,merged.style)}this.#context.strokeStyle=this.#theme.gridLine;this.#context.lineWidth=1/this.#devicePixelRatio;this.#context.strokeRect(merged.x+.5/this.#devicePixelRatio,merged.y+.5/this.#devicePixelRatio,Math.max(0,merged.width-1/this.#devicePixelRatio),Math.max(0,merged.height-1/this.#devicePixelRatio))}}#paintCellFill(x,y,width,height,style){if(this.#forcedColors||style===void 0)return;const color=cssColor(style.fillColor??style.backgroundColor);if(color===void 0)return;this.#context.fillStyle=color;this.#context.fillRect(x+1,y+1,Math.max(0,width-2),Math.max(0,height-2))}#applyCellFont(style){if(style?.font===void 0){this.#context.font=this.#theme.font;return}const font=style.font;const size=finitePositive(font.size)??13;const family=font.family&&font.family.trim().length>0?font.family:'ui-sans-serif, system-ui, -apple-system, "Segoe UI", sans-serif';this.#context.font=`${font.italic===true?"italic ":""}${font.bold===true?"700 ":"400 "}${size}px ${family}`}#cellForeground(style,fallback){if(this.#forcedColors)return fallback;return cssColor(style?.font?.color)??cssColor(style?.foregroundColor)??fallback}#paintCellBorders(x,y,width,height,style){if(style?.borders===void 0)return;const context=this.#context;const sides=style.borders;const paint=(side,startX,startY,endX,endY)=>{const border=sides[side];if(border===void 0||border.style==="none")return;context.save();const widthForStyle=borderWidth(border.style);context.lineWidth=widthForStyle;context.strokeStyle=this.#forcedColors?this.#theme.gridLine:cssColor(border.color)??this.#theme.gridLine;context.setLineDash(borderDash(border.style));context.beginPath();context.moveTo(startX,startY);context.lineTo(endX,endY);context.stroke();if(border.style==="double"){const offset=Math.max(2,widthForStyle+1);const horizontal=startY===endY;context.beginPath();context.moveTo(horizontal?startX:startX+offset,horizontal?startY+offset:startY);context.lineTo(horizontal?endX:endX+offset,horizontal?endY+offset:endY);context.stroke()}context.restore()};paint("top",x+.5,y+.5,x+width-.5,y+.5);paint("right",x+width-.5,y+.5,x+width-.5,y+height-.5);paint("bottom",x+.5,y+height-.5,x+width-.5,y+height-.5);paint("left",x+.5,y+.5,x+.5,y+height-.5)}#paintHeader(snapshot){const context=this.#context;const theme=this.#theme;context.fillStyle=theme.headerBackground;context.fillRect(0,0,snapshot.width,snapshot.headerHeight);context.font=theme.headerFont;context.fillStyle=theme.headerForeground;context.textBaseline="middle";context.textAlign="left";const columns=[...snapshot.columns.filter(column=>column.frozen!==true),...snapshot.columns.filter(column=>column.frozen===true)];for(const column of columns){if(column.x+column.width<=snapshot.rowGutterWidth||column.x>=snapshot.width){continue}context.save();context.beginPath();context.rect(column.x+1,0,Math.max(0,column.width-2),snapshot.headerHeight);context.clip();context.fillText(column.name,column.x+10,snapshot.headerHeight/2);context.restore()}context.textAlign="center";context.fillText("#",snapshot.rowGutterWidth/2,snapshot.headerHeight/2,snapshot.rowGutterWidth)}#paintGrid(snapshot){const context=this.#context;const theme=this.#theme;context.strokeStyle=theme.gridLine;context.lineWidth=1/this.#devicePixelRatio;context.beginPath();const snap=.5/this.#devicePixelRatio;context.moveTo(snapshot.rowGutterWidth+snap,0);context.lineTo(snapshot.rowGutterWidth+snap,snapshot.height);context.moveTo(0,snapshot.headerHeight+snap);context.lineTo(snapshot.width,snapshot.headerHeight+snap);for(const column of snapshot.columns){const x=column.x+column.width+snap;if(x>snapshot.rowGutterWidth&&x<snapshot.width){context.moveTo(x,0);context.lineTo(x,snapshot.height)}}for(const row of snapshot.rows){const y=row.y+row.height+snap;if(y>snapshot.headerHeight&&y<snapshot.height){context.moveTo(0,y);context.lineTo(snapshot.width,y)}}context.stroke()}#paintSelection(snapshot){const selection=snapshot.selection;const context=this.#context;const theme=this.#theme;if(selection!==void 0){const selectedColumns=snapshot.columns.filter(column=>column.index>=selection.columnStart&&column.index<selection.columnEnd);const selectedRows=snapshot.rows.filter(row=>row.index>=selection.rowStart&&row.index<selection.rowEnd);if(selectedColumns.length>0&&selectedRows.length>0){const firstColumn=selectedColumns[0];const lastColumn=selectedColumns.at(-1);const firstRow=selectedRows[0];const lastRow=selectedRows.at(-1);const x=Math.max(snapshot.rowGutterWidth,firstColumn.x);const y=Math.max(snapshot.headerHeight,firstRow.y);const right=Math.min(snapshot.width,lastColumn.x+lastColumn.width);const bottom=Math.min(snapshot.height,lastRow.y+lastRow.height);if(right>x&&bottom>y){context.save();context.fillStyle=theme.selectionBackground;if(this.#forcedColors){context.globalAlpha=.28}context.fillRect(x,y,right-x,bottom-y);context.restore();context.strokeStyle=theme.selectionBorder;context.lineWidth=this.#forcedColors?2:1;context.setLineDash(this.#forcedColors?[4,2]:[]);context.strokeRect(x+context.lineWidth/2,y+context.lineWidth/2,Math.max(0,right-x-context.lineWidth),Math.max(0,bottom-y-context.lineWidth));context.setLineDash([])}}}const activeMerges=snapshot.activeCell===void 0?[]:snapshot.mergedCells?.filter(merged=>snapshot.activeCell.rowIndex>=merged.region.rowStart&&snapshot.activeCell.rowIndex<merged.region.rowEnd&&snapshot.activeCell.columnIndex>=merged.region.columnStart&&snapshot.activeCell.columnIndex<merged.region.columnEnd)??[];const activeColumn=snapshot.activeCell===void 0?void 0:snapshot.columns.find(column=>column.index===snapshot.activeCell.columnIndex);const activeRow=snapshot.activeCell===void 0?void 0:snapshot.rows.find(row=>row.index===snapshot.activeCell.rowIndex);const activeRects=activeMerges.length>0?activeMerges:activeColumn!==void 0&&activeRow!==void 0?[{x:activeColumn.x,y:activeRow.y,width:activeColumn.width,height:activeRow.height}]:[];for(const activeRect of activeRects){const activeX=Math.max(snapshot.rowGutterWidth,activeRect.x);const activeY=Math.max(snapshot.headerHeight,activeRect.y);const activeRight=Math.min(snapshot.width,activeRect.x+activeRect.width);const activeBottom=Math.min(snapshot.height,activeRect.y+activeRect.height);context.strokeStyle=theme.activeCellBorder;context.lineWidth=this.#forcedColors?3:2;context.setLineDash([]);context.strokeRect(activeX+context.lineWidth/2,activeY+context.lineWidth/2,Math.max(0,activeRight-activeX-context.lineWidth),Math.max(0,activeBottom-activeY-context.lineWidth))}}};function cssColor(color){const value=color?.css?.trim();if(!value)return void 0;const supports=globalThis.CSS?.supports;return typeof supports!=="function"||supports("color",value)?value:void 0}function finitePositive(value){return value!==void 0&&Number.isFinite(value)&&value>0?value:void 0}function horizontalAlignment(style){switch(style?.horizontalAlignment){case"center":return"center";case"right":return"right";case"left":case"justify":case"general":default:return"left"}}function verticalBaseline(style){switch(style?.verticalAlignment){case"top":return"top";case"bottom":return"bottom";case"center":case"justify":default:return"middle"}}function horizontalTextX(alignment,x,width,padding){if(alignment==="center")return x+width/2;if(alignment==="right"||alignment==="end")return x+width-padding;return x+padding}function verticalTextY(baseline,y,height,padding){if(baseline==="top"||baseline==="hanging")return y+padding;if(baseline==="bottom"||baseline==="ideographic")return y+height-padding;return y+height/2}function underlineStart(alignment,textX,width){if(alignment==="center")return textX-width/2;if(alignment==="right"||alignment==="end")return textX-width;return textX}function borderWidth(style){switch(style){case"medium":return 2;case"thick":return 3;case"double":return 1;default:return 1}}function borderDash(style){if(style==="dashed")return[4,2];if(style==="dotted")return[1,2];return[]}function positive(value,fallback){return value!==void 0&&Number.isFinite(value)&&value>0?value:fallback}var DEFAULT_ROW_HEIGHT=28;var DEFAULT_HEADER_HEIGHT=36;var DEFAULT_ROW_HEADER_WIDTH=64;var DEFAULT_COLUMN_WIDTH=160;var DEFAULT_MIN_COLUMN_WIDTH=64;var DEFAULT_MAX_COLUMN_WIDTH=640;var DEFAULT_SCROLL_PIXEL_LIMIT=16e6;var DEFAULT_OVERSCAN_ROWS=8;var DEFAULT_OVERSCAN_COLUMNS=1;function createTableLayout(metadata,columnWidths,viewport,options={}){const rowHeight=positiveFinite(options.rowHeight??DEFAULT_ROW_HEIGHT,"rowHeight");const headerHeight=nonNegativeFinite(options.headerHeight??DEFAULT_HEADER_HEIGHT,"headerHeight");const rowHeaderWidth=nonNegativeFinite(options.rowHeaderWidth??DEFAULT_ROW_HEADER_WIDTH,"rowHeaderWidth");const scrollPixelLimit=positiveFinite(options.scrollPixelLimit??DEFAULT_SCROLL_PIXEL_LIMIT,"scrollPixelLimit");const overscanRows=nonNegativeInteger(options.overscanRows??DEFAULT_OVERSCAN_ROWS,"overscanRows");const overscanColumns=nonNegativeInteger(options.overscanColumns??DEFAULT_OVERSCAN_COLUMNS,"overscanColumns");const width=nonNegativeFinite(viewport.width,"viewport.width");const height=nonNegativeFinite(viewport.height,"viewport.height");const devicePixelRatio=positiveFinite(viewport.devicePixelRatio??1,"viewport.devicePixelRatio");const columnCount=metadata.schema.columns.length;if(columnWidths.length!==columnCount){throw invalidArgument(`columnWidths has ${columnWidths.length} entries; expected ${columnCount}`)}for(let index=0;index<columnWidths.length;index+=1){positiveFinite(columnWidths[index],`columnWidths[${index}]`)}const hiddenColumns=options.hiddenColumns??[];if(hiddenColumns.length!==0&&hiddenColumns.length!==columnCount){throw invalidArgument(`hiddenColumns has ${hiddenColumns.length} entries; expected ${columnCount}`)}const effectiveColumnWidths=Object.freeze(columnWidths.map((width2,index)=>hiddenColumns[index]===true?0:width2));const rowCount=extentValue(metadata.extent.rows);const frozenRowCount=Math.min(rowCount,nonNegativeInteger(options.frozenRows??0,"frozenRows"));const frozenColumnCount=Math.min(columnCount,nonNegativeInteger(options.frozenColumns??0,"frozenColumns"));const bodyWidth=Math.max(0,width-rowHeaderWidth);const bodyHeight=Math.max(0,height-headerHeight);const prefixes=columnOffsets(effectiveColumnWidths);const rowGeometry=createSparseAxisGeometry(rowCount,rowHeight,options.rowEntries??[]);const logicalWidth=prefixes[prefixes.length-1]??0;const logicalHeight=rowGeometry.contentSize;const horizontal=createScrollAxis(logicalWidth,bodyWidth,viewport.scrollLeft,scrollPixelLimit);const vertical=createScrollAxis(logicalHeight,bodyHeight,viewport.scrollTop,scrollPixelLimit);const visibleRows=visibleRowRange(rowGeometry,vertical.logicalOffset,bodyHeight);const visibleColumns=visibleColumnRange(prefixes,horizontal.logicalOffset,bodyWidth);const overscanRowRange=expandRange(visibleRows,overscanRows,rowCount);const overscanColumnRange=expandRange(visibleColumns,overscanColumns,columnCount);const frozenRowExtent=axisPosition(rowGeometry,frozenRowCount);const frozenColumnExtent=prefixes[frozenColumnCount]??0;const frozenRowRange=frozenRowCount===0?Object.freeze({start:0,end:0}):clampRangeEnd(visibleRowRange(rowGeometry,0,Math.min(bodyHeight,frozenRowExtent)),frozenRowCount);const frozenColumnRange=frozenColumnCount===0?Object.freeze({start:0,end:0}):clampRangeEnd(visibleColumnRange(prefixes,0,Math.min(bodyWidth,frozenColumnExtent)),frozenColumnCount);return Object.freeze({width,height,devicePixelRatio,rowHeight,headerHeight,rowHeaderWidth,bodyWidth,bodyHeight,rowCount,columnCount,rows:Object.freeze({visible:visibleRows,overscan:overscanRowRange}),columns:Object.freeze({visible:visibleColumns,overscan:overscanColumnRange}),visibleColumns:materializeColumns(metadata,effectiveColumnWidths,prefixes,visibleColumns,frozenColumnRange,rowHeaderWidth,horizontal.logicalOffset,frozenColumnCount),overscanColumns:materializeColumns(metadata,effectiveColumnWidths,prefixes,overscanColumnRange,frozenColumnRange,rowHeaderWidth,horizontal.logicalOffset,frozenColumnCount),visibleRows:materializeRows(rowGeometry,visibleRows,frozenRowRange,headerHeight,vertical.logicalOffset,frozenRowCount),overscanRows:materializeRows(rowGeometry,overscanRowRange,frozenRowRange,headerHeight,vertical.logicalOffset,frozenRowCount),effectiveColumnWidths,rowGeometry,frozenRowCount,frozenColumnCount,frozenRowExtent,frozenColumnExtent,frozenRowRange,frozenColumnRange,horizontal,vertical,spacerWidth:rowHeaderWidth+horizontal.physicalContentSize,spacerHeight:headerHeight+vertical.physicalContentSize})}function createScrollAxis(logicalContentSize,logicalViewportSize,physicalOffset,pixelLimit=DEFAULT_SCROLL_PIXEL_LIMIT){nonNegativeFinite(logicalContentSize,"logicalContentSize");nonNegativeFinite(logicalViewportSize,"logicalViewportSize");positiveFinite(pixelLimit,"pixelLimit");const logicalMaxOffset=Math.max(0,logicalContentSize-logicalViewportSize);const largestUsableSize=Math.max(pixelLimit,logicalViewportSize+1);const physicalContentSize=Math.min(logicalContentSize,largestUsableSize);const physicalMaxOffset=Math.max(0,physicalContentSize-logicalViewportSize);const normalizedPhysicalOffset=clampFinite(physicalOffset,0,physicalMaxOffset);const compressed=logicalMaxOffset>physicalMaxOffset;const logicalOffset=physicalMaxOffset===0?0:compressed?normalizedPhysicalOffset/physicalMaxOffset*logicalMaxOffset:normalizedPhysicalOffset;return Object.freeze({logicalContentSize,logicalViewportSize,logicalOffset,logicalMaxOffset,physicalContentSize,physicalOffset:normalizedPhysicalOffset,physicalMaxOffset,compressed})}function logicalToPhysicalOffset(axis,logicalOffset){const normalized=clampFinite(logicalOffset,0,axis.logicalMaxOffset);if(!axis.compressed){return Math.min(normalized,axis.physicalMaxOffset)}return axis.logicalMaxOffset===0?0:normalized/axis.logicalMaxOffset*axis.physicalMaxOffset}function hitTest(layout,x,y,_columnWidths,resizeHandleWidth=6){if(!Number.isFinite(x)||!Number.isFinite(y)||x<0||y<0||x>=layout.width||y>=layout.height){return Object.freeze({kind:"outside"})}const columnWidths=layout.effectiveColumnWidths;if(x<layout.rowHeaderWidth&&y<layout.headerHeight){return Object.freeze({kind:"corner"})}if(y<layout.headerHeight){const offsets=columnOffsets(columnWidths);const logicalX=x-layout.rowHeaderWidth+layout.horizontal.logicalOffset;const nextBoundary=lowerBound(offsets,logicalX);const handleWidth=Math.max(0,resizeHandleWidth);for(const boundaryIndex of[nextBoundary,nextBoundary-1]){if(boundaryIndex<=0||boundaryIndex>=offsets.length){continue}const boundaryX=layout.rowHeaderWidth+offsets[boundaryIndex]-layout.horizontal.logicalOffset;if(Math.abs(x-boundaryX)<=handleWidth){return Object.freeze({kind:"column-resize",columnIndex:boundaryIndex-1,boundaryX})}}const columnIndex2=columnAtViewportX(layout,x,columnWidths);if(columnIndex2===null){return Object.freeze({kind:"outside"})}return Object.freeze({kind:"column-header",columnIndex:columnIndex2})}const rowIndex=rowAtViewportY(layout,y);if(rowIndex===null){return Object.freeze({kind:"outside"})}if(x<layout.rowHeaderWidth){return Object.freeze({kind:"row-header",rowIndex})}const columnIndex=columnAtViewportX(layout,x,columnWidths);return columnIndex===null?Object.freeze({kind:"outside"}):Object.freeze({kind:"cell",rowIndex,columnIndex})}function cellRect(layout,_columnWidths,rowIndex,columnIndex){const columnWidths=layout.effectiveColumnWidths;const offsets=columnOffsets(columnWidths);const rowOffset=axisPosition(layout.rowGeometry,rowIndex);const columnOffset=offsets[columnIndex]??0;return Object.freeze({x:layout.rowHeaderWidth+columnOffset-(columnIndex<layout.frozenColumnCount?0:layout.horizontal.logicalOffset),y:layout.headerHeight+rowOffset-(rowIndex<layout.frozenRowCount?0:layout.vertical.logicalOffset),width:columnWidths[columnIndex]??0,height:axisSize(layout.rowGeometry,rowIndex)})}function selectionRect(layout,_columnWidths,range){const columnWidths=layout.effectiveColumnWidths;if(range.rowStart>=range.rowEnd||range.columnStart>=range.columnEnd){return null}const offsets=columnOffsets(columnWidths);const columnStart=clampInteger2(range.columnStart,0,columnWidths.length);const columnEnd=clampInteger2(range.columnEnd,columnStart,columnWidths.length);const rowStart=clampInteger2(range.rowStart,0,layout.rowCount);const rowEnd=clampInteger2(range.rowEnd,rowStart,layout.rowCount);if(columnStart===columnEnd||rowStart===rowEnd){return null}const frozenColumns=columnEnd<=layout.frozenColumnCount;const frozenRows=rowEnd<=layout.frozenRowCount;const rowStartOffset=axisPosition(layout.rowGeometry,rowStart);const rowEndOffset=axisPosition(layout.rowGeometry,rowEnd);return Object.freeze({x:layout.rowHeaderWidth+offsets[columnStart]-(frozenColumns?0:layout.horizontal.logicalOffset),y:layout.headerHeight+rowStartOffset-(frozenRows?0:layout.vertical.logicalOffset),width:offsets[columnEnd]-offsets[columnStart],height:rowEndOffset-rowStartOffset})}function columnOffsets(columnWidths){const offsets=new Array(columnWidths.length+1);offsets[0]=0;for(let index=0;index<columnWidths.length;index+=1){offsets[index+1]=offsets[index]+(columnWidths[index]??DEFAULT_COLUMN_WIDTH)}return offsets}function extentValue(extent){return extent.kind==="unknown"?0:extent.value}function createSparseAxisGeometry(count,defaultSize,entries=[]){nonNegativeInteger(count,"axis count");positiveFinite(defaultSize,"axis defaultSize");const byIndex=new Map;for(const entry of entries){if(!entry||!Number.isSafeInteger(entry.index)||entry.index<0||entry.index>=count){continue}if(entry.hidden===true){byIndex.set(entry.index,0);continue}if(entry.size!==void 0){if(!Number.isFinite(entry.size)||entry.size<0){continue}byIndex.set(entry.index,entry.size)}}let cumulativeDelta=0;const overrides=[...byIndex.entries()].sort(([left],[right])=>left-right).map(([index,size])=>{cumulativeDelta+=size-defaultSize;return Object.freeze({index,size,cumulativeDelta})});const contentSize=count*defaultSize+cumulativeDelta;return Object.freeze({count,defaultSize,contentSize:Math.max(0,contentSize),overrides:Object.freeze(overrides)})}function axisPosition(geometry,index){const normalized=clampInteger2(index,0,geometry.count);const overrideIndex=lowerBoundOverride(geometry.overrides,normalized);const delta=overrideIndex===0?0:geometry.overrides[overrideIndex-1].cumulativeDelta;return normalized*geometry.defaultSize+delta}function axisSize(geometry,index){if(!Number.isSafeInteger(index)||index<0||index>=geometry.count){return 0}const match=sparseOverrideAt(geometry,index);return match?.size??geometry.defaultSize}function axisIndexAtOffset(geometry,offset){if(!Number.isFinite(offset)||offset<0||offset>=geometry.contentSize||geometry.count===0){return null}let low=0;let high=geometry.count;while(low<high){const middle=Math.floor((low+high)/2);if(axisPosition(geometry,middle+1)<=offset){low=middle+1}else{high=middle}}for(let index=low;index<geometry.count;index+=1){const size=axisSize(geometry,index);const start=axisPosition(geometry,index);if(size>0&&offset>=start&&offset<start+size){return index}if(start>offset){return null}}return null}function nextVisibleAxisIndex(geometry,from,direction=1){for(let index=clampInteger2(from,0,Math.max(0,geometry.count-1));index>=0&&index<geometry.count;index+=direction){if(axisSize(geometry,index)>0){return index}}return null}function sparseOverrideAt(geometry,index){const low=lowerBoundOverride(geometry.overrides,index);const candidate=geometry.overrides[low];return candidate?.index===index?candidate:void 0}function lowerBoundOverride(entries,target){let low=0;let high=entries.length;while(low<high){const middle=Math.floor((low+high)/2);if(entries[middle].index<target)low=middle+1;else high=middle}return low}function clampRangeEnd(range,end){return Object.freeze({start:Math.min(range.start,end),end:Math.min(range.end,end)})}function visibleRowRange(geometry,scrollTop,viewportHeight){if(geometry.count===0||viewportHeight<=0||geometry.contentSize<=0){return Object.freeze({start:0,end:0})}const start=axisIndexAtOffset(geometry,scrollTop);if(start===null){return Object.freeze({start:geometry.count,end:geometry.count})}const last=axisIndexAtOffset(geometry,Math.max(scrollTop,Math.min(geometry.contentSize,scrollTop+viewportHeight)-Math.max(1e-7,Math.abs(scrollTop+viewportHeight)*Number.EPSILON*4)));return Object.freeze({start,end:last===null?start+1:Math.min(geometry.count,last+1)})}function visibleColumnRange(offsets,scrollLeft,viewportWidth){const count=Math.max(0,offsets.length-1);if(count===0||viewportWidth<=0){return Object.freeze({start:0,end:0})}const start=columnAtLogicalX(offsets,scrollLeft)??count;const end=Math.min(count,lowerBound(offsets,scrollLeft+viewportWidth));return Object.freeze({start,end:Math.max(start,end)})}function expandRange(range,amount,limit){return Object.freeze({start:Math.max(0,range.start-amount),end:Math.min(limit,range.end+amount)})}function materializeColumns(metadata,widths,offsets,range,frozenRange,rowHeaderWidth,scrollLeft,frozenColumnCount){const indexes=rangeIndexes(range,frozenRange);const columns=[];for(const index of indexes){const column=metadata.schema.columns[index];const width=widths[index]??0;if(width<=0){continue}const frozen=index<frozenColumnCount;columns.push(Object.freeze({index,id:column.id,name:column.name,x:rowHeaderWidth+offsets[index]-(frozen?0:scrollLeft),width,frozen}))}return Object.freeze(columns)}function materializeRows(geometry,range,frozenRange,headerHeight,scrollTop,frozenRowCount){const rows=[];for(const index of rangeIndexes(range,frozenRange)){const height=axisSize(geometry,index);if(height<=0){continue}const frozen=index<frozenRowCount;rows.push(Object.freeze({index,y:headerHeight+axisPosition(geometry,index)-(frozen?0:scrollTop),height,frozen}))}return Object.freeze(rows)}function rangeIndexes(primary,frozen){const indexes=new Set;for(let index=primary.start;index<primary.end;index+=1){indexes.add(index)}for(let index=frozen.start;index<frozen.end;index+=1){indexes.add(index)}return Object.freeze([...indexes].sort((left,right)=>left-right))}function columnAtViewportX(layout,x,columnWidths){if(x<layout.rowHeaderWidth){return null}const bodyX=x-layout.rowHeaderWidth;if(bodyX<Math.min(layout.bodyWidth,layout.frozenColumnExtent)){const frozen=columnAtLogicalX(columnOffsets(columnWidths),bodyX);if(frozen!==null&&frozen<layout.frozenColumnCount){return frozen}}return columnAtLogicalX(columnOffsets(columnWidths),bodyX+layout.horizontal.logicalOffset)}function columnAtLogicalX(offsets,x){const count=Math.max(0,offsets.length-1);if(x<0||count===0||x>=offsets[count]){return null}let low=0;let high=count;while(low<high){const middle=Math.floor((low+high)/2);if(offsets[middle+1]<=x){low=middle+1}else{high=middle}}return low}function rowAtViewportY(layout,y){const bodyY=y-layout.headerHeight;if(bodyY<Math.min(layout.bodyHeight,layout.frozenRowExtent)){const frozen=axisIndexAtOffset(layout.rowGeometry,bodyY);if(frozen!==null&&frozen<layout.frozenRowCount){return frozen}}return axisIndexAtOffset(layout.rowGeometry,bodyY+layout.vertical.logicalOffset)}function lowerBound(values,target){let low=0;let high=values.length;while(low<high){const middle=Math.floor((low+high)/2);if(values[middle]<target){low=middle+1}else{high=middle}}return low}function positiveFinite(value,name){if(!Number.isFinite(value)||value<=0){throw invalidArgument(`${name} must be a positive finite number`)}return value}function nonNegativeFinite(value,name){if(!Number.isFinite(value)||value<0){throw invalidArgument(`${name} must be a non-negative finite number`)}return value}function nonNegativeInteger(value,name){if(!Number.isSafeInteger(value)||value<0){throw invalidArgument(`${name} must be a non-negative safe integer`)}return value}function clampFinite(value,minimum,maximum){if(!Number.isFinite(value)){return minimum}return Math.min(maximum,Math.max(minimum,value))}function clampInteger2(value,minimum,maximum){if(!Number.isFinite(value)){return minimum}return Math.min(maximum,Math.max(minimum,Math.trunc(value)))}var DEFAULT_MAX_WINDOW_CELLS=1e5;var Controller=class{#table;#options;#listeners=new Set;#unsubscribe;#viewport={width:0,height:0,scrollLeft:0,scrollTop:0,devicePixelRatio:1};#columnWidths;#hiddenColumns;#presentationRows=[];#frozenRows=0;#frozenColumns=0;#mergedCells=[];#snapshot;#activeCell=null;#selection=null;#windows=[];#loadingRanges=[];#requestAbort=null;#generation=0;#loadQueued=false;#disposed=false;#tableClosed=false;constructor(table,options){this.#table=table;this.#options=normalizeOptions(options);this.#columnWidths=initialColumnWidths(table.metadata,this.#options);this.#hiddenColumns=Array.from({length:this.#columnWidths.length},()=>false);const layout=createTableLayout(table.metadata,this.#columnWidths,this.#viewport,this.#layoutOptions());this.#snapshot=Object.freeze({generation:this.#generation,status:"loading",metadata:table.metadata,layout,activeCell:null,selection:null});this.#unsubscribe=table.subscribe(event=>this.#handleTableEvent(event))}get metadata(){return this.#table.metadata}get columnWidths(){return Object.freeze([...this.#columnWidths])}get minColumnWidth(){return this.#options.minColumnWidth}get maxColumnWidth(){return this.#options.maxColumnWidth}getSnapshot(){return this.#snapshot}subscribe(listener){this.#assertOpen();this.#listeners.add(listener);return()=>this.#listeners.delete(listener)}updateViewport(viewport){this.#assertOpen();const normalized=normalizeViewport(viewport);if(sameViewport(normalized,this.#viewport)){return}this.#viewport=normalized;this.#advanceGeneration()}setActiveCell(cell,options={}){this.#assertOpen();assertCellPosition(cell,"cell");const clamped=clampCell(cell,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount);if(clamped===null){return}const next=this.#visibleCell(this.#mergeAnchor(clamped),1,1);if(next===null)return;const anchor=options.extendSelection&&this.#selection!==null?this.#selection.anchor:next;this.#activeCell=next;this.#selection=createMergedSelection(anchor,next,this.#mergedCells);if(options.scrollIntoView!==false&&this.#scrollCellIntoView(next)){this.#advanceGeneration();return}this.#publish()}extendSelection(cell,options={}){this.setActiveCell(cell,{...options,extendSelection:true})}setSelection(anchor,focus=anchor){this.#assertOpen();assertCellPosition(anchor,"anchor");assertCellPosition(focus,"focus");const rawAnchor=clampCell(anchor,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount);const rawFocus=clampCell(focus,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount);if(rawAnchor===null||rawFocus===null){this.clearSelection();return}const clampedAnchor=this.#visibleCell(this.#mergeAnchor(rawAnchor),1,1);const clampedFocus=this.#visibleCell(this.#mergeAnchor(rawFocus),1,1);if(clampedAnchor===null||clampedFocus===null){this.clearSelection();return}this.#activeCell=clampedFocus;this.#selection=createMergedSelection(clampedAnchor,clampedFocus,this.#mergedCells);this.#publish()}clearSelection(){this.#assertOpen();if(this.#selection===null){return}this.#selection=null;this.#publish()}moveActive(command,options={}){this.#assertOpen();const current=this.#activeCell??{rowIndex:0,columnIndex:0};const origin=navigationOrigin(current,command,this.#mergedCells);const moved=moveCell(origin,command,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount,Math.max(1,this.#snapshot.layout.visibleRows.filter(row=>!row.frozen).length));const[rowDirection,columnDirection]=navigationDirections(command);const next=moved===null?null:this.#visibleCell(this.#mergeAnchor(moved),rowDirection,columnDirection);if(next!==null){this.setActiveCell(next,options)}}ensureCellVisible(cell){this.#assertOpen();assertCellPosition(cell,"cell");const next=clampCell(cell,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount);if(next!==null&&this.#scrollCellIntoView(next)){this.#advanceGeneration()}}ensureColumnVisible(columnIndex){this.#assertOpen();assertColumnIndex(columnIndex,this.#columnWidths.length);if(this.#scrollColumnIntoView(columnIndex)){this.#advanceGeneration()}}resizeColumn(columnIndex,width){this.#assertOpen();assertColumnIndex(columnIndex,this.#columnWidths.length);const normalized=clampWidth(width,this.#options);if(this.#columnWidths[columnIndex]===normalized){return}this.#columnWidths[columnIndex]=normalized;this.#advanceGeneration()}autosizeColumn(columnIndex,measuredWidth){this.resizeColumn(columnIndex,measuredWidth)}applySpreadsheetPresentation(presentation){this.#assertOpen();if(presentation.kind!=="spreadsheet-v1"||presentation.tableId!==this.metadata.tableId){throw invalidArgument("presentation must belong to the controller table")}const nextWidths=[...this.#columnWidths];const hiddenColumns=Array.from({length:nextWidths.length},()=>false);for(const entry of presentation.columns){if(!Number.isSafeInteger(entry.index)||entry.index<0||entry.index>=nextWidths.length){continue}hiddenColumns[entry.index]=entry.hidden===true;if(entry.size!==void 0&&Number.isFinite(entry.size)&&entry.size>0){nextWidths[entry.index]=clampWidth(entry.size,this.#options)}}this.#columnWidths=nextWidths;this.#hiddenColumns=hiddenColumns;this.#presentationRows=Object.freeze(presentation.rows.map(entry=>Object.freeze({...entry})));this.#frozenRows=presentation.frozenRows;this.#frozenColumns=presentation.frozenColumns;this.#mergedCells=[];this.#advanceGeneration();this.#normalizeInteractionForPresentation();this.#publish()}setMergedCells(regions){this.#assertOpen();const normalized=normalizeMergedCells(regions,this.#snapshot.layout.rowCount,this.#snapshot.layout.columnCount);if(sameMergedCells(normalized,this.#mergedCells)){return}this.#mergedCells=normalized;this.#normalizeInteractionForPresentation();this.#advanceGeneration()}hitTest(x,y,resizeHandleWidth){const result=hitTest(this.#snapshot.layout,x,y,this.#columnWidths,resizeHandleWidth);if(result.kind!=="cell"){return result}const anchor=this.#mergeAnchor(result);return Object.freeze({kind:"cell",...anchor})}cellRect(cell){assertCellPosition(cell,"cell");if(cell.rowIndex>=this.#snapshot.layout.rowCount||cell.columnIndex>=this.#snapshot.layout.columnCount){throw invalidArgument("cell must be inside the current table extent")}return cellRect(this.#snapshot.layout,this.#columnWidths,cell.rowIndex,cell.columnIndex)}selectionRect(selection=this.#selection){return selection===null?null:selectionRect(this.#snapshot.layout,this.#columnWidths,selection.range)}getCell(rowIndex,columnIndex){if(!isValidCell(rowIndex,columnIndex,this.#snapshot.layout.rowCount,this.#columnWidths.length)){return Object.freeze({status:"unavailable"})}for(const window of this.#windows){if(rangeContains(window.range,rowIndex,columnIndex)){return Object.freeze({status:"loaded",value:window.rows[rowIndex-window.range.rowStart][columnIndex-window.range.columnStart]})}}for(const range of this.#loadingRanges){if(rangeContains(range,rowIndex,columnIndex)){return Object.freeze({status:"loading"})}}return Object.freeze({status:"unavailable"})}async copySelection(options={}){this.#assertOpen();const selection=this.#selection;if(selection===null){return""}const request=gridRangeToRequest(selection.range);assertWindowCellLimit(request,MAX_RANGE_CELLS,"selection");const batch=await this.#table.readRange(request,options.signal?{signal:options.signal}:{});return rowsToTsv(batchRows(batch))}dispose(){if(this.#disposed){return}this.#disposed=true;this.#requestAbort?.abort();this.#requestAbort=null;this.#unsubscribe();this.#listeners.clear();this.#windows=[];this.#loadingRanges=[];this.#snapshot=Object.freeze({...this.#snapshot,status:"closed",activeCell:null,selection:null})}#advanceGeneration(){this.#generation+=1;this.#requestAbort?.abort();this.#requestAbort=null;this.#loadingRanges=[];this.#rebuildSnapshot("loading");this.#queueLoad()}#queueLoad(){if(this.#loadQueued||this.#disposed){return}this.#loadQueued=true;queueMicrotask(()=>{this.#loadQueued=false;if(!this.#disposed){void this.#loadGeneration(this.#generation)}})}async#loadGeneration(generation){let visible;let overscan;try{({visible,overscan}=layoutRanges(this.#snapshot.layout,this.#options.maxWindowCells,this.#mergedCells))}catch(error){if(!this.#disposed&&generation===this.#generation){this.#loadingRanges=[];this.#rebuildSnapshot("error",error)}return}if(visible.length===0){this.#windows=[];this.#loadingRanges=[];this.#rebuildSnapshot("ready");return}const abort=new AbortController;this.#requestAbort=abort;const ranges=Object.freeze([...visible,...overscan.filter(candidate=>!visible.some(required=>rangeContainsRange(candidate,required)&&sameGridRange(candidate,required)))]);this.#loadingRanges=Object.freeze(ranges);this.#publish();let loaded=[];try{for(let index=0;index<ranges.length;index+=1){const range=ranges[index];const batch=await this.#table.readRange(gridRangeToRequest(range),{signal:abort.signal});if(this.#disposed||generation!==this.#generation||abort.signal.aborted){return}const returnedRange=batchGridRange(batch);if(returnedRange.rowStart<returnedRange.rowEnd&&returnedRange.columnStart<returnedRange.columnEnd){const window=Object.freeze({range:returnedRange,rows:batchRows(batch)});loaded=[window,...loaded.filter(candidate=>!rangeContainsRange(returnedRange,candidate.range))]}this.#windows=Object.freeze([...loaded]);this.#loadingRanges=Object.freeze(ranges.slice(index+1));this.#rebuildSnapshot("ready")}}catch(error){if(this.#disposed||generation!==this.#generation||abort.signal.aborted||error instanceof TabularkError&&error.code==="CANCELLED"){return}this.#loadingRanges=[];this.#rebuildSnapshot("error",error)}finally{if(this.#requestAbort===abort){this.#requestAbort=null}}}#scrollCellIntoView(cell){const layout=this.#snapshot.layout;const offsets=columnOffsets(layout.effectiveColumnWidths);const cellLeft=offsets[cell.columnIndex];const cellRight=offsets[cell.columnIndex+1];const cellTop=axisPosition(layout.rowGeometry,cell.rowIndex);const cellBottom=cellTop+axisSize(layout.rowGeometry,cell.rowIndex);const logicalLeft=cell.columnIndex<layout.frozenColumnCount?layout.horizontal.logicalOffset:revealOffset(layout.horizontal.logicalOffset,layout.bodyWidth,cellLeft,cellRight,layout.horizontal.logicalMaxOffset);const logicalTop=cell.rowIndex<layout.frozenRowCount?layout.vertical.logicalOffset:revealOffset(layout.vertical.logicalOffset,layout.bodyHeight,cellTop,cellBottom,layout.vertical.logicalMaxOffset);const scrollLeft=logicalToPhysicalOffset(layout.horizontal,logicalLeft);const scrollTop=logicalToPhysicalOffset(layout.vertical,logicalTop);if(scrollLeft===this.#viewport.scrollLeft&&scrollTop===this.#viewport.scrollTop){return false}this.#viewport=Object.freeze({...this.#viewport,scrollLeft,scrollTop});return true}#scrollColumnIntoView(columnIndex){const layout=this.#snapshot.layout;const offsets=columnOffsets(layout.effectiveColumnWidths);const logicalLeft=columnIndex<layout.frozenColumnCount?layout.horizontal.logicalOffset:revealOffset(layout.horizontal.logicalOffset,layout.bodyWidth,offsets[columnIndex],offsets[columnIndex+1],layout.horizontal.logicalMaxOffset);const scrollLeft=logicalToPhysicalOffset(layout.horizontal,logicalLeft);if(scrollLeft===this.#viewport.scrollLeft){return false}this.#viewport=Object.freeze({...this.#viewport,scrollLeft});return true}#handleTableEvent(event){if(this.#disposed){return}switch(event.type){case"metadata":{const previousMetadata=this.#snapshot.metadata;this.#columnWidths=reconcileColumnWidths(previousMetadata,event.metadata,this.#columnWidths,this.#options);const hiddenById=new Map(previousMetadata.schema.columns.map((column,index)=>[column.id,this.#hiddenColumns[index]===true]));this.#hiddenColumns=event.metadata.schema.columns.map(column=>hiddenById.get(column.id)===true);this.#advanceGeneration();this.#clampInteraction();this.#publish();break}case"runtimeError":this.#requestAbort?.abort();this.#requestAbort=null;this.#loadingRanges=[];this.#rebuildSnapshot("error",event.error);break;case"closed":this.#tableClosed=true;this.#requestAbort?.abort();this.#requestAbort=null;this.#loadingRanges=[];if(this.#snapshot.status!=="error"){this.#rebuildSnapshot("closed")}break;case"warning":break}}#clampInteraction(){if(this.#activeCell===null){return}const rowCount=extentValue(this.#table.metadata.extent.rows);const columnCount=this.#table.metadata.schema.columns.length;const rawActive=clampCell(this.#activeCell,rowCount,columnCount);const nextActive=rawActive===null?null:this.#visibleCell(this.#mergeAnchor(rawActive),1,1);if(nextActive===null){this.#activeCell=null;this.#selection=null;return}this.#activeCell=nextActive;if(this.#selection!==null){const rawAnchor=clampCell(this.#selection.anchor,rowCount,columnCount);const rawFocus=clampCell(this.#selection.focus,rowCount,columnCount);const anchor=this.#visibleCell(this.#mergeAnchor(rawAnchor),1,1);const focus=this.#visibleCell(this.#mergeAnchor(rawFocus),1,1);this.#selection=anchor===null||focus===null?null:createMergedSelection(anchor,focus,this.#mergedCells)}}#layoutOptions(){return Object.freeze({...this.#options,rowEntries:this.#presentationRows,hiddenColumns:this.#hiddenColumns,frozenRows:this.#frozenRows,frozenColumns:this.#frozenColumns})}#mergeAnchor(cell){const region=mergeContaining(this.#mergedCells,cell);return region===void 0?Object.freeze({rowIndex:cell.rowIndex,columnIndex:cell.columnIndex}):Object.freeze({rowIndex:region.rowStart,columnIndex:region.columnStart})}#visibleCell(cell,rowDirection,columnDirection){const layout=this.#snapshot.layout;const row=nextVisibleAxisIndex(layout.rowGeometry,cell.rowIndex,rowDirection)??nextVisibleAxisIndex(layout.rowGeometry,cell.rowIndex,rowDirection===1?-1:1);if(row===null)return null;const column=nextVisibleColumn(layout.effectiveColumnWidths,cell.columnIndex,columnDirection)??nextVisibleColumn(layout.effectiveColumnWidths,cell.columnIndex,columnDirection===1?-1:1);return column===null?null:Object.freeze({rowIndex:row,columnIndex:column})}#normalizeInteractionForPresentation(){this.#clampInteraction()}#rebuildSnapshot(status,error){const layout=createTableLayout(this.#table.metadata,this.#columnWidths,this.#viewport,this.#layoutOptions());this.#viewport=Object.freeze({...this.#viewport,scrollLeft:layout.horizontal.physicalOffset,scrollTop:layout.vertical.physicalOffset});this.#snapshot=Object.freeze({generation:this.#generation,status,metadata:this.#table.metadata,layout,activeCell:this.#activeCell,selection:this.#selection,...error===void 0?{}:{error}});this.#emit()}#publish(){this.#snapshot=Object.freeze({...this.#snapshot,activeCell:this.#activeCell,selection:this.#selection});this.#emit()}#emit(){for(const listener of this.#listeners){try{listener(this.#snapshot)}catch(error){if(typeof reportError==="function"){reportError(error)}}}}#assertOpen(){if(this.#disposed||this.#tableClosed||this.#snapshot.status==="closed"){throw closedError("Table view controller")}}};function createTableController(table,options={}){if(!table||typeof table.readRange!=="function"||typeof table.subscribe!=="function"){throw invalidArgument("table must be a TableHandle")}return new Controller(table,options)}function normalizeMergedCells(regions,rowCount,columnCount){const unique=new Map;for(const region of regions){if(!region||!Number.isSafeInteger(region.rowStart)||!Number.isSafeInteger(region.rowEnd)||!Number.isSafeInteger(region.columnStart)||!Number.isSafeInteger(region.columnEnd)||region.rowStart<0||region.columnStart<0||region.rowEnd<=region.rowStart||region.columnEnd<=region.columnStart||region.rowEnd>rowCount||region.columnEnd>columnCount){continue}const frozen=Object.freeze({...region});unique.set(mergeKey(frozen),frozen)}return Object.freeze([...unique.values()].sort((left,right)=>left.rowStart-right.rowStart||left.columnStart-right.columnStart||left.rowEnd-right.rowEnd||left.columnEnd-right.columnEnd))}function sameMergedCells(left,right){return left.length===right.length&&left.every((region,index)=>mergeKey(region)===mergeKey(right[index]))}function mergeKey(region){return`${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`}function mergeContaining(regions,cell){return regions.find(region=>cell.rowIndex>=region.rowStart&&cell.rowIndex<region.rowEnd&&cell.columnIndex>=region.columnStart&&cell.columnIndex<region.columnEnd)}function createMergedSelection(anchor,focus,regions){const selection=createSelection(anchor,focus);let range=selection.range;for(;;){let expanded=range;for(const region of regions){if(!rangesIntersect(expanded,region))continue;expanded=Object.freeze({rowStart:Math.min(expanded.rowStart,region.rowStart),rowEnd:Math.max(expanded.rowEnd,region.rowEnd),columnStart:Math.min(expanded.columnStart,region.columnStart),columnEnd:Math.max(expanded.columnEnd,region.columnEnd)})}if(sameGridRange(range,expanded))break;range=expanded}return Object.freeze({...selection,range})}function rangesIntersect(left,right){return left.rowStart<right.rowEnd&&left.rowEnd>right.rowStart&&left.columnStart<right.columnEnd&&left.columnEnd>right.columnStart}function navigationOrigin(current,command,regions){const merge=mergeContaining(regions,current);if(merge===void 0)return current;if(command==="right"){return Object.freeze({rowIndex:current.rowIndex,columnIndex:merge.columnEnd-1})}if(command==="down"||command==="page-down"){return Object.freeze({rowIndex:merge.rowEnd-1,columnIndex:current.columnIndex})}return current}function navigationDirections(command){switch(command){case"left":case"row-start":return[1,-1];case"up":case"page-up":return[-1,1];case"table-start":return[-1,-1];default:return[1,1]}}function nextVisibleColumn(widths,from,direction){for(let index=Math.min(widths.length-1,Math.max(0,from));index>=0&&index<widths.length;index+=direction){if((widths[index]??0)>0)return index}return null}function normalizeOptions(options){const minColumnWidth=positiveFinite2(options.minColumnWidth??DEFAULT_MIN_COLUMN_WIDTH,"minColumnWidth");const maxColumnWidth=positiveFinite2(options.maxColumnWidth??DEFAULT_MAX_COLUMN_WIDTH,"maxColumnWidth");if(maxColumnWidth<minColumnWidth){throw invalidArgument("maxColumnWidth must be greater than or equal to minColumnWidth")}const maxWindowCells=positiveInteger2(options.maxWindowCells??DEFAULT_MAX_WINDOW_CELLS,"maxWindowCells");if(maxWindowCells>MAX_RANGE_CELLS){throw invalidArgument(`maxWindowCells cannot exceed ${MAX_RANGE_CELLS}`)}return Object.freeze({...options.rowHeight===void 0?{}:{rowHeight:options.rowHeight},...options.headerHeight===void 0?{}:{headerHeight:options.headerHeight},...options.rowHeaderWidth===void 0?{}:{rowHeaderWidth:options.rowHeaderWidth},...options.scrollPixelLimit===void 0?{}:{scrollPixelLimit:options.scrollPixelLimit},...options.overscanRows===void 0?{}:{overscanRows:options.overscanRows},...options.overscanColumns===void 0?{}:{overscanColumns:options.overscanColumns},columnWidth:positiveFinite2(options.columnWidth??DEFAULT_COLUMN_WIDTH,"columnWidth"),minColumnWidth,maxColumnWidth,columnWidths:Object.freeze({...options.columnWidths??{}}),maxWindowCells})}function initialColumnWidths(metadata,options){return metadata.schema.columns.map(column=>clampWidth(options.columnWidths[column.id]??options.columnWidth,options))}function reconcileColumnWidths(previousMetadata,nextMetadata,previousWidths,options){const byId2=new Map(previousMetadata.schema.columns.map((column,index)=>[column.id,previousWidths[index]]));return nextMetadata.schema.columns.map(column=>clampWidth(byId2.get(column.id)??options.columnWidths[column.id]??options.columnWidth,options))}function normalizeViewport(viewport){return Object.freeze({width:nonNegativeFinite2(viewport.width,"viewport.width"),height:nonNegativeFinite2(viewport.height,"viewport.height"),scrollLeft:nonNegativeFinite2(viewport.scrollLeft,"viewport.scrollLeft"),scrollTop:nonNegativeFinite2(viewport.scrollTop,"viewport.scrollTop"),devicePixelRatio:positiveFinite2(viewport.devicePixelRatio??1,"viewport.devicePixelRatio")})}function layoutRanges(layout,maxCells,mergedCells=[]){const visible=windowRectangles(layout.rows.visible,layout.columns.visible,layout.frozenRowRange,layout.frozenColumnRange);const anchors=mergeAnchorRanges(mergedCells,visible);const visibleWithAnchors=Object.freeze([...visible,...anchors.filter(anchor=>!visible.some(range=>rangeContainsRange(range,anchor)))]);const visibleCellCount=visibleWithAnchors.reduce((total,range)=>total+rangeCellCount(range),0);if(visibleCellCount>maxCells){throw new TabularkError("RESOURCE_LIMIT",`The viewport contains ${visibleCellCount} cells; the window limit is ${maxCells}`,{details:{resource:"viewport-cells",required:visibleCellCount,available:maxCells,visibleCellCount,maxCells}})}const fullOverscan=windowRectangles(layout.rows.overscan,layout.columns.overscan,layout.frozenRowRange,layout.frozenColumnRange);const overscanCellCount=fullOverscan.reduce((total,range)=>total+rangeCellCount(range),0);const overscanWithAnchors=Object.freeze([...fullOverscan,...anchors.filter(anchor=>!fullOverscan.some(range=>rangeContainsRange(range,anchor)))]);return Object.freeze({visible:visibleWithAnchors,overscan:overscanCellCount+anchors.length<=maxCells?overscanWithAnchors:visibleWithAnchors})}function mergeAnchorRanges(mergedCells,visible){const anchors=new Map;for(const region of mergedCells){if(!visible.some(range2=>rangesIntersect(range2,region)))continue;const range=Object.freeze({rowStart:region.rowStart,rowEnd:region.rowStart+1,columnStart:region.columnStart,columnEnd:region.columnStart+1});anchors.set(`${range.rowStart}:${range.columnStart}`,range)}return Object.freeze([...anchors.values()])}function windowRectangles(rows,columns,frozenRows,frozenColumns){const rowBands=mergeIndexBands(rows,frozenRows);const columnBands=mergeIndexBands(columns,frozenColumns);const rectangles=[];for(const row of rowBands){for(const column of columnBands){rectangles.push(Object.freeze({rowStart:row.start,rowEnd:row.end,columnStart:column.start,columnEnd:column.end}))}}return Object.freeze(rectangles)}function mergeIndexBands(primary,frozen){const bands=[primary,frozen].filter(range=>range.start<range.end).sort((left,right)=>left.start-right.start);if(bands.length<=1)return Object.freeze(bands.map(range=>Object.freeze({...range})));const[first,second]=bands;return first.end>=second.start?Object.freeze([Object.freeze({start:first.start,end:Math.max(first.end,second.end)})]):Object.freeze(bands.map(range=>Object.freeze({...range})))}function gridRangeToRequest(range){return Object.freeze({rowStart:range.rowStart,rowCount:range.rowEnd-range.rowStart,columnStart:range.columnStart,columnCount:range.columnEnd-range.columnStart})}function batchGridRange(batch){return Object.freeze({rowStart:batch.range.rowStart,rowEnd:batch.range.rowStart+batch.range.rowCount,columnStart:batch.range.columnStart,columnEnd:batch.range.columnStart+batch.range.columnCount})}function batchRows(batch){return Object.freeze(batch.toDisplayRows({maxCells:Math.max(1,batch.range.rowCount*batch.range.columnCount)}).map(row=>Object.freeze(row)))}function rowsToTsv(rows){return rows.map(row=>row.map(tsvField).join(" ")).join("\n")}function tsvField(value){if(value===null){return""}return/[\t\r\n"]/.test(value)?`"${value.replaceAll('"','""')}"`:value}function revealOffset(current,viewportSize,itemStart,itemEnd,maximum){if(viewportSize<=0||itemStart<current){return Math.min(maximum,Math.max(0,itemStart))}if(itemEnd>current+viewportSize){return Math.min(maximum,Math.max(0,itemEnd-viewportSize))}return current}function rangeContains(range,rowIndex,columnIndex){return rowIndex>=range.rowStart&&rowIndex<range.rowEnd&&columnIndex>=range.columnStart&&columnIndex<range.columnEnd}function rangeContainsRange(container,candidate){return candidate.rowStart>=container.rowStart&&candidate.rowEnd<=container.rowEnd&&candidate.columnStart>=container.columnStart&&candidate.columnEnd<=container.columnEnd}function rangeCellCount(range){return(range.rowEnd-range.rowStart)*(range.columnEnd-range.columnStart)}function sameGridRange(left,right){return right!==null&&left.rowStart===right.rowStart&&left.rowEnd===right.rowEnd&&left.columnStart===right.columnStart&&left.columnEnd===right.columnEnd}function sameViewport(left,right){return left.width===right.width&&left.height===right.height&&left.scrollLeft===right.scrollLeft&&left.scrollTop===right.scrollTop&&left.devicePixelRatio===right.devicePixelRatio}function isValidCell(rowIndex,columnIndex,rowCount,columnCount){return Number.isSafeInteger(rowIndex)&&rowIndex>=0&&rowIndex<rowCount&&Number.isSafeInteger(columnIndex)&&columnIndex>=0&&columnIndex<columnCount}function assertColumnIndex(columnIndex,columnCount){if(!Number.isSafeInteger(columnIndex)||columnIndex<0||columnIndex>=columnCount){throw invalidArgument(`columnIndex must be between 0 and ${Math.max(0,columnCount-1)}`)}}function assertWindowCellLimit(request,limit,label){const cells=request.rowCount*request.columnCount;if(!Number.isSafeInteger(cells)||cells>limit){throw new TabularkError("RESOURCE_LIMIT",`The ${label} contains ${cells} cells; the limit is ${limit}`,{details:{resource:"view-window-cells",required:cells,available:limit,cells,limit}})}}function clampWidth(width,options){if(!Number.isFinite(width)){throw invalidArgument("column width must be a finite number")}return Math.min(options.maxColumnWidth,Math.max(options.minColumnWidth,width))}function positiveFinite2(value,name){if(!Number.isFinite(value)||value<=0){throw invalidArgument(`${name} must be a positive finite number`)}return value}function nonNegativeFinite2(value,name){if(!Number.isFinite(value)||value<0){throw invalidArgument(`${name} must be a non-negative finite number`)}return value}function positiveInteger2(value,name){if(!Number.isSafeInteger(value)||value<=0){throw invalidArgument(`${name} must be a positive safe integer`)}return value}var RESIZE_HANDLE_WIDTH=8;var RESIZE_TARGET_SIZE=44;var KEYBOARD_RESIZE_STEP=8;var KEYBOARD_RESIZE_COARSE_STEP=32;var AUTOSIZE_HORIZONTAL_PADDING=24;var MAX_PRESENTATION_WINDOW_CELLS=1e5;var nextViewId=1;var View=class{element;controller;#scrollHost;#spacer;#surface;#canvas;#resizeLayer;#resizeInstructions;#message;#accessibleGrid;#painter;#ownerWindow;#ownsController;#writeClipboard;#onError;#baseTheme;#presentationTable;#theme;#forcedColorsQuery;#unsubscribe;#resizeObserver;#resizeHandles=new Map;#snapshot;#frame=0;#interaction=null;#copyAbort=null;#announcementFrame=0;#forcedColors=false;#presentation=null;#presentationRanges=[];#mergedCells=[];#presentationRequestKey="";#presentationAbort=null;#destroyed=false;constructor(options){const ownerDocument=options.container.ownerDocument;const ownerWindow=ownerDocument.defaultView;if(ownerWindow===null){throw invalidArgument("container must belong to an active browser document")}this.#ownerWindow=ownerWindow;const presentation=options.presentation??"auto";if(presentation!=="auto"&&presentation!=="ignore"){throw invalidArgument("presentation must be auto or ignore")}this.#ownsController=options.table!==void 0;this.controller=options.controller??createTableController(options.table,options.controllerOptions);this.#snapshot=this.controller.getSnapshot();this.#writeClipboard=options.writeClipboard;this.#onError=options.onError;this.#presentationTable=presentation==="auto"?options.table:void 0;this.#baseTheme=Object.freeze({...DEFAULT_CANVAS_TABLE_THEME,...options.theme});this.#forcedColorsQuery=ownerWindow.matchMedia("(forced-colors: active)");this.#forcedColors=this.#forcedColorsQuery.matches;this.#theme=this.#forcedColors?forcedColorsCanvasTableTheme(this.#baseTheme):this.#baseTheme;this.element=ownerDocument.createElement("div");this.element.className="tabulark-view";this.element.dataset.tabularkView="";this.element.setAttribute("aria-label",options.ariaLabel??this.#tableLabel());Object.assign(this.element.style,{background:this.#theme.background,border:`1px solid ${this.#theme.gridLine}`,borderRadius:"6px",boxSizing:"border-box",color:this.#theme.foreground,contain:"layout paint style",height:"100%",minHeight:"120px",minWidth:"0",overflow:"hidden",position:"relative",width:"100%"});this.#scrollHost=ownerDocument.createElement("div");this.#scrollHost.className="tabulark-scroll";this.#scrollHost.dataset.tabularkScroll="";this.#scrollHost.tabIndex=-1;Object.assign(this.#scrollHost.style,{inset:"0",overflow:"auto",overscrollBehavior:"contain",position:"absolute",scrollbarGutter:"stable"});this.#spacer=ownerDocument.createElement("div");this.#spacer.className="tabulark-scroll-spacer";this.#spacer.dataset.tabularkScrollSpacer="";this.#spacer.setAttribute("aria-hidden","true");Object.assign(this.#spacer.style,{left:"0",pointerEvents:"none",position:"absolute",top:"0"});this.#surface=ownerDocument.createElement("div");this.#surface.className="tabulark-surface";this.#surface.dataset.tabularkSurface="";Object.assign(this.#surface.style,{left:"0",position:"sticky",top:"0",userSelect:"none",zIndex:"1"});this.#canvas=ownerDocument.createElement("canvas");this.#canvas.className="tabulark-canvas";this.#canvas.dataset.tabularkCanvas="";this.#canvas.setAttribute("aria-hidden","true");this.#canvas.draggable=false;Object.assign(this.#canvas.style,{cursor:"default",display:"block",touchAction:"pan-x pan-y"});this.#resizeLayer=ownerDocument.createElement("div");this.#resizeLayer.className="tabulark-resize-layer";Object.assign(this.#resizeLayer.style,{left:"0",pointerEvents:"none",position:"absolute",top:"0",width:"100%"});this.#resizeInstructions=ownerDocument.createElement("div");this.#resizeInstructions.id=`tabulark-resize-instructions-${nextViewId}`;nextViewId+=1;this.#resizeInstructions.textContent="Use Left and Right Arrow keys to resize. Hold Shift for larger steps. Home and End use the minimum and maximum widths. Enter fits the visible content.";visuallyHide2(this.#resizeInstructions);this.#message=ownerDocument.createElement("div");this.#message.className="tabulark-message";this.#message.dataset.tabularkMessage="";this.#message.setAttribute("aria-hidden","true");Object.assign(this.#message.style,{alignItems:"center",background:this.#theme.background,color:this.#theme.mutedForeground,display:"none",font:this.#theme.font,inset:"0",justifyContent:"center",padding:"24px",pointerEvents:"none",position:"absolute",textAlign:"center",zIndex:"2"});this.#accessibleGrid=new AccessibleViewportGrid(ownerDocument,options.ariaLabel??this.#tableLabel());this.#painter=new CanvasTablePainter(this.#canvas,{theme:this.#theme,forcedColors:this.#forcedColors,...options.maxDevicePixelRatio===void 0?{}:{maxDevicePixelRatio:options.maxDevicePixelRatio}});this.#applyThemeToElements();this.#surface.append(this.#canvas,this.#resizeLayer);this.#scrollHost.append(this.#spacer,this.#surface);this.element.append(this.#scrollHost,this.#message,this.#accessibleGrid.element,this.#accessibleGrid.statusElement,this.#resizeInstructions);options.container.append(this.element);this.#unsubscribe=this.controller.subscribe(snapshot=>{this.#snapshot=snapshot;if(this.#isTerminal()){if(this.#resizeLayer.contains(this.element.ownerDocument.activeElement)){this.#accessibleGrid.focus({preventScroll:true})}this.#cancelInteraction();this.#copyAbort?.abort();this.#copyAbort=null}this.#schedulePresentationRanges();this.#scheduleFrame()});this.#scrollHost.addEventListener("scroll",this.#onScroll,{passive:true});this.#surface.addEventListener("pointerdown",this.#onPointerDown);this.#surface.addEventListener("pointermove",this.#onPointerMove);this.#surface.addEventListener("pointerup",this.#onPointerUp);this.#surface.addEventListener("pointercancel",this.#onPointerUp);this.#surface.addEventListener("dblclick",this.#onDoubleClick);this.element.addEventListener("keydown",this.#onKeyDown);this.element.addEventListener("focusin",this.#onFocusIn);this.element.addEventListener("focusout",this.#onFocusOut);this.#forcedColorsQuery.addEventListener("change",this.#onForcedColorsChange);if(typeof ownerWindow.ResizeObserver==="function"){this.#resizeObserver=new ownerWindow.ResizeObserver(()=>this.#updateViewport());this.#resizeObserver.observe(this.#scrollHost)}else{ownerWindow.addEventListener("resize",this.#onWindowResize)}this.#updateViewport();this.#scheduleFrame();if(this.#presentationTable!==void 0){void this.#applyPresentation(this.#presentationTable)}}focus(options){this.#assertAlive();this.#accessibleGrid.focus(options)}destroy(){if(this.#destroyed){return}this.#destroyed=true;this.#presentationAbort?.abort();this.#presentationAbort=null;this.#copyAbort?.abort();this.#copyAbort=null;if(this.#frame!==0){this.#ownerWindow.cancelAnimationFrame(this.#frame);this.#frame=0}if(this.#announcementFrame!==0){this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame);this.#announcementFrame=0}this.#resizeObserver?.disconnect();this.#ownerWindow.removeEventListener("resize",this.#onWindowResize);this.#unsubscribe();this.#scrollHost.removeEventListener("scroll",this.#onScroll);this.#surface.removeEventListener("pointerdown",this.#onPointerDown);this.#surface.removeEventListener("pointermove",this.#onPointerMove);this.#surface.removeEventListener("pointerup",this.#onPointerUp);this.#surface.removeEventListener("pointercancel",this.#onPointerUp);this.#surface.removeEventListener("dblclick",this.#onDoubleClick);this.element.removeEventListener("keydown",this.#onKeyDown);this.element.removeEventListener("focusin",this.#onFocusIn);this.element.removeEventListener("focusout",this.#onFocusOut);this.#forcedColorsQuery.removeEventListener("change",this.#onForcedColorsChange);this.#accessibleGrid.destroy();this.element.remove();if(this.#ownsController){this.controller.dispose()}}dispose(){this.destroy()}#onScroll=()=>{this.#updateViewport()};#onWindowResize=()=>{this.#updateViewport()};#onForcedColorsChange=event=>{if(this.#destroyed){return}this.#forcedColors=event.matches;this.#theme=this.#forcedColors?forcedColorsCanvasTableTheme(this.#baseTheme):this.#baseTheme;this.#painter.setTheme(this.#theme,{forcedColors:this.#forcedColors});this.#applyThemeToElements();this.#scheduleFrame()};#onFocusIn=event=>{this.element.style.outline=`2px solid ${this.#focusColor()}`;this.element.style.outlineOffset="-2px";const resizeHandle=this.#resizeHandleFromTarget(event.target);if(resizeHandle!==null){resizeHandle.style.outline=`2px solid ${this.#focusColor()}`;resizeHandle.style.outlineOffset="-2px";return}if(!this.#isTerminal()&&this.#snapshot.activeCell===null&&this.#hasCells()&&event.target===this.#accessibleGrid.element){this.controller.setActiveCell({rowIndex:0,columnIndex:0})}};#onFocusOut=event=>{const resizeHandle=this.#resizeHandleFromTarget(event.target);if(resizeHandle!==null){resizeHandle.style.outline="none"}queueMicrotask(()=>{if(!this.#destroyed&&!this.element.contains(this.element.ownerDocument.activeElement)){this.element.style.outline="none"}})};#onPointerDown=event=>{if(event.button!==0||this.#isTerminal()){return}const position=this.#eventPosition(event);const resizeColumn=this.#resizeColumnFromTarget(event.target);const hit=resizeColumn===null?this.controller.hitTest(position.x,position.y,RESIZE_HANDLE_WIDTH/2):{kind:"column-resize",columnIndex:resizeColumn,boundaryX:position.x};if(hit.kind==="column-resize"){event.preventDefault();this.#interaction=Object.freeze({kind:"resize",pointerId:event.pointerId,columnIndex:hit.columnIndex,startClientX:event.clientX,startWidth:this.controller.columnWidths[hit.columnIndex]});this.#surface.setPointerCapture(event.pointerId);this.#surface.style.cursor="col-resize";return}const cell=this.#cellFromHit(hit);if(cell===null){return}this.focus({preventScroll:true});this.controller.setActiveCell(cell,{extendSelection:event.shiftKey,scrollIntoView:false});if(event.pointerType!=="touch"){this.#interaction=Object.freeze({kind:"select",pointerId:event.pointerId,anchor:event.shiftKey&&this.#snapshot.selection!==null?this.#snapshot.selection.anchor:cell});this.#surface.setPointerCapture(event.pointerId)}};#onPointerMove=event=>{if(this.#isTerminal()){this.#cancelInteraction();return}if(this.#interaction?.pointerId===event.pointerId){if(this.#interaction.kind==="resize"){const delta=event.clientX-this.#interaction.startClientX;this.controller.resizeColumn(this.#interaction.columnIndex,this.#interaction.startWidth+delta);return}const position2=this.#eventPosition(event);const hit2=this.controller.hitTest(position2.x,position2.y,0);if(hit2.kind==="cell"){this.controller.setSelection(this.#interaction.anchor,{rowIndex:hit2.rowIndex,columnIndex:hit2.columnIndex})}return}const position=this.#eventPosition(event);const hit=this.controller.hitTest(position.x,position.y,RESIZE_HANDLE_WIDTH/2);this.#surface.style.cursor=hit.kind==="column-resize"?"col-resize":"default"};#onPointerUp=event=>{if(this.#interaction?.pointerId!==event.pointerId){return}const resizedColumn=this.#interaction.kind==="resize"?this.#interaction.columnIndex:null;if(this.#surface.hasPointerCapture(event.pointerId)){this.#surface.releasePointerCapture(event.pointerId)}this.#interaction=null;this.#surface.style.cursor="default";if(resizedColumn!==null){this.controller.ensureColumnVisible(resizedColumn);this.#announceColumnWidth(resizedColumn,false)}};#onDoubleClick=event=>{if(this.#isTerminal()){return}const position=this.#eventPosition(event);const fromTarget=this.#resizeColumnFromTarget(event.target);const hit=fromTarget===null?this.controller.hitTest(position.x,position.y,RESIZE_HANDLE_WIDTH/2):{kind:"column-resize",columnIndex:fromTarget};if(hit.kind!=="column-resize"){return}event.preventDefault();this.controller.autosizeColumn(hit.columnIndex,this.#measureColumn(hit.columnIndex));this.controller.ensureColumnVisible(hit.columnIndex);this.#announceColumnWidth(hit.columnIndex,true)};#onKeyDown=event=>{const resizeColumn=this.#resizeColumnFromTarget(event.target);if(resizeColumn!==null){if(this.#handleResizeKeyDown(event,resizeColumn)){return}if(keyboardCommand(event)!==null){return}}if(this.#isTerminal()||event.altKey){return}if((event.ctrlKey||event.metaKey)&&event.key.toLowerCase()==="c"){event.preventDefault();void this.#copySelection();return}if(event.key==="Escape"){event.preventDefault();this.controller.clearSelection();return}const command=keyboardCommand(event);if(command===null){return}event.preventDefault();this.controller.moveActive(command,{extendSelection:event.shiftKey,scrollIntoView:true})};#handleResizeKeyDown(event,columnIndex){if(this.#isTerminal()||event.altKey||event.ctrlKey||event.metaKey){return false}const width=this.controller.columnWidths[columnIndex];if(width===void 0){return false}const step=event.shiftKey?KEYBOARD_RESIZE_COARSE_STEP:KEYBOARD_RESIZE_STEP;let nextWidth=null;switch(event.key){case"ArrowLeft":nextWidth=width-step;break;case"ArrowRight":nextWidth=width+step;break;case"Home":nextWidth=this.controller.minColumnWidth;break;case"End":nextWidth=this.controller.maxColumnWidth;break;case"Enter":nextWidth=this.#measureColumn(columnIndex);break;default:return false}event.preventDefault();event.stopPropagation();if(event.key==="Enter"){this.controller.autosizeColumn(columnIndex,nextWidth)}else{this.controller.resizeColumn(columnIndex,nextWidth)}this.controller.ensureColumnVisible(columnIndex);this.#announceColumnWidth(columnIndex,event.key==="Enter");return true}#updateViewport(){if(this.#isTerminal()){return}const width=this.#scrollHost.clientWidth;const height=this.#scrollHost.clientHeight;this.#surface.style.width=`${width}px`;this.#surface.style.height=`${height}px`;this.controller.updateViewport({width,height,scrollLeft:this.#scrollHost.scrollLeft,scrollTop:this.#scrollHost.scrollTop,devicePixelRatio:this.#ownerWindow.devicePixelRatio||1})}#scheduleFrame(){if(this.#destroyed||this.#frame!==0){return}this.#frame=this.#ownerWindow.requestAnimationFrame(()=>{this.#frame=0;this.#render()})}async#applyPresentation(table){try{const presentation=await table.getPresentation();if(this.#destroyed||presentation===null){return}this.#presentation=presentation;this.#applySpreadsheetPresentation(presentation)}catch(error){if(!this.#destroyed){this.#onError?.(error)}}}#applySpreadsheetPresentation(presentation){this.element.dataset.tabularkPresentation=presentation.kind;this.element.dataset.tabularkWorksheetVisibility=presentation.visibility;this.element.dataset.tabularkFrozenRows=String(presentation.frozenRows);this.element.dataset.tabularkFrozenColumns=String(presentation.frozenColumns);this.controller.applySpreadsheetPresentation(presentation);this.#schedulePresentationRanges();this.#scheduleFrame()}#schedulePresentationRanges(){const table=this.#presentationTable;const presentation=this.#presentation;if(this.#destroyed||table===void 0||presentation===null)return;const requests=presentationRequests(this.#snapshot.layout);const key=`${presentation.tableId}:${presentation.revision}:${requests.map(rangeKey).join("|")}`;if(key===this.#presentationRequestKey)return;this.#presentationRequestKey=key;this.#presentationAbort?.abort();this.#presentationAbort=null;if(requests.length===0){this.#presentationRanges=[];this.#mergedCells=[];this.controller.setMergedCells([]);this.#scheduleFrame();return}const abort=new AbortController;this.#presentationAbort=abort;void(async()=>{const viewportRanges=await Promise.all(requests.map(request=>table.readPresentationRange(request,{signal:abort.signal})));const currentRanges=viewportRanges.filter(range=>range!==null&&range.revision===presentation.revision);const anchorRequests=missingMergeAnchorRequests(collectMergedRegions(currentRanges),currentRanges);const anchorRanges=await Promise.all(anchorRequests.map(request=>table.readPresentationRange(request,{signal:abort.signal})));return[...viewportRanges,...anchorRanges]})().then(ranges=>{if(this.#destroyed||abort.signal.aborted||this.#presentationAbort!==abort||this.#presentationRequestKey!==key){return}this.#presentationAbort=null;this.#presentationRanges=Object.freeze(ranges.filter(range=>range!==null&&range.revision===presentation.revision));this.#mergedCells=collectMergedRegions(this.#presentationRanges);this.controller.setMergedCells(this.#mergedCells);this.#scheduleFrame()}).catch(error=>{if(this.#presentationAbort===abort)this.#presentationAbort=null;if(this.#destroyed||abort.signal.aborted||error instanceof TabularkError&&error.code==="CANCELLED"){return}this.#onError?.(error)})}#mergedRegions(){return this.#mergedCells}#render(){if(this.#destroyed){return}const snapshot=this.#snapshot;const layout=snapshot.layout;this.#spacer.style.width=`${Math.max(layout.width,layout.spacerWidth)}px`;this.#spacer.style.height=`${Math.max(layout.height,layout.spacerHeight)}px`;this.#surface.style.width=`${layout.width}px`;this.#surface.style.height=`${layout.height}px`;this.#syncNativeScroll(snapshot);const columns=layout.overscanColumns.map(column=>({index:column.index,name:column.name,x:column.x,width:column.width,frozen:column.frozen}));const rows=this.#paintRows(snapshot,columns);const mergedCells=this.#paintMergedCells();this.#painter.paint({width:layout.width,height:layout.height,headerHeight:layout.headerHeight,rowGutterWidth:layout.rowHeaderWidth,columns,rows,mergedCells,...snapshot.selection===null?{}:{selection:snapshot.selection.range},...snapshot.activeCell===null?{}:{activeCell:{rowIndex:snapshot.activeCell.rowIndex,columnIndex:snapshot.activeCell.columnIndex}},busy:snapshot.status==="loading"});this.#renderResizeHandles(snapshot);this.#renderAccessibleGrid(snapshot);this.#renderMessage(snapshot)}#paintRows(snapshot,columns){const layout=snapshot.layout;const rows=[];for(const row of layout.overscanRows){const rowIndex=row.index;rows.push({index:rowIndex,y:row.y,height:row.height,frozen:row.frozen,cells:columns.map(column=>{const cell=this.controller.getCell(rowIndex,column.index);return{columnIndex:column.index,value:cell.status==="loaded"?cell.value:void 0,...this.#styleAt(rowIndex,column.index)===void 0?{}:{style:this.#styleAt(rowIndex,column.index)},...this.#mergeContaining(rowIndex,column.index)===void 0?{}:{coveredByMerge:true}}})})}return rows}#paintMergedCells(){const result=[];const layout=this.#snapshot.layout;for(const region of this.#mergedRegions()){const cell=this.controller.getCell(region.rowStart,region.columnStart);const style=this.#styleAt(region.rowStart,region.columnStart);for(const fragment of splitMergedRegion(region,layout.frozenRowCount,layout.frozenColumnCount)){const first=this.controller.cellRect({rowIndex:fragment.rowStart,columnIndex:fragment.columnStart});const last=this.controller.cellRect({rowIndex:fragment.rowEnd-1,columnIndex:fragment.columnEnd-1});const clip=mergePaneClip(layout,fragment);const x=Math.max(first.x,clip.left);const y=Math.max(first.y,clip.top);const right=Math.min(last.x+last.width,clip.right);const bottom=Math.min(last.y+last.height,clip.bottom);if(right<=x||bottom<=y)continue;result.push(Object.freeze({region,x,y,width:right-x,height:bottom-y,value:cell.status==="loaded"?cell.value:void 0,...style===void 0?{}:{style},...fragment.rowStart===region.rowStart&&fragment.columnStart===region.columnStart?{}:{continuation:true}}))}}return Object.freeze(result)}#styleAt(rowIndex,columnIndex){const presentation=this.#presentation;if(presentation===null)return void 0;for(const window of this.#presentationRanges){const range=window.range;if(rowIndex<range.rowStart||rowIndex>=range.rowStart+range.rowCount||columnIndex<range.columnStart||columnIndex>=range.columnStart+range.columnCount){continue}const id=window.styleIds[rowIndex-range.rowStart]?.[columnIndex-range.columnStart];return id===null||id===void 0?void 0:presentation.styles[id]}return void 0}#mergeContaining(rowIndex,columnIndex){return this.#mergedRegions().find(region=>rowIndex>=region.rowStart&&rowIndex<region.rowEnd&&columnIndex>=region.columnStart&&columnIndex<region.columnEnd)}#renderResizeHandles(snapshot){const visibleIds=new Set;if(this.#isTerminal()){this.#removeStaleResizeHandles(visibleIds);return}for(const column of snapshot.layout.visibleColumns){const boundary=column.x+column.width;if(boundary<snapshot.layout.rowHeaderWidth||boundary>snapshot.layout.width){continue}visibleIds.add(column.id);let handle=this.#resizeHandles.get(column.id);if(handle===void 0){handle=this.element.ownerDocument.createElement("div");handle.setAttribute("role","separator");handle.setAttribute("aria-orientation","vertical");handle.setAttribute("aria-controls",this.#accessibleGrid.element.id);handle.setAttribute("aria-describedby",this.#resizeInstructions.id);handle.setAttribute("aria-keyshortcuts","ArrowLeft ArrowRight Home End Enter");handle.tabIndex=0;Object.assign(handle.style,{background:"transparent",boxSizing:"border-box",cursor:"col-resize",outline:"none",pointerEvents:"auto",position:"absolute",top:"0",touchAction:"none",width:`${RESIZE_TARGET_SIZE}px`});const line2=this.element.ownerDocument.createElement("div");line2.dataset.tabularkResizeLine="";line2.setAttribute("aria-hidden","true");Object.assign(line2.style,{pointerEvents:"none",position:"absolute",top:"0"});handle.append(line2);this.#resizeHandles.set(column.id,handle);this.#resizeLayer.append(handle)}handle.dataset.columnResize=String(column.index);handle.dataset.columnId=column.id;handle.setAttribute("aria-label",`Resize ${column.name} column`);handle.setAttribute("aria-valuemin",String(this.controller.minColumnWidth));handle.setAttribute("aria-valuemax",String(this.controller.maxColumnWidth));handle.setAttribute("aria-valuenow",String(column.width));handle.setAttribute("aria-valuetext",`${formatWidth(column.width)} CSS pixels`);Object.assign(handle.style,{height:`${Math.max(RESIZE_TARGET_SIZE,snapshot.layout.headerHeight)}px`,left:`${boundary-RESIZE_TARGET_SIZE/2}px`});const line=handle.firstElementChild;if(line!==null){Object.assign(line.style,{background:this.#theme.gridLine,height:`${snapshot.layout.headerHeight}px`,left:`${(RESIZE_TARGET_SIZE-(this.#forcedColors?2:1))/2}px`,width:`${this.#forcedColors?2:1}px`})}}this.#resizeLayer.style.height=`${Math.max(RESIZE_TARGET_SIZE,snapshot.layout.headerHeight)}px`;this.#removeStaleResizeHandles(visibleIds)}#removeStaleResizeHandles(visibleIds){for(const[columnId,handle]of this.#resizeHandles){if(visibleIds.has(columnId)){continue}if(handle.contains(this.element.ownerDocument.activeElement)){this.#accessibleGrid.focus({preventScroll:true})}handle.remove();this.#resizeHandles.delete(columnId)}}#renderAccessibleGrid(snapshot){const layout=snapshot.layout;const visibleRowIndexes=new Set(layout.visibleRows.map(row=>row.index));const visibleColumnIndexes=new Set(layout.visibleColumns.map(column=>column.index));const accessibleMerges=this.#mergedRegions().filter(region=>layout.visibleRows.some(row=>row.index>=region.rowStart&&row.index<region.rowEnd)&&layout.visibleColumns.some(column=>column.index>=region.columnStart&&column.index<region.columnEnd));const columnIndexes=new Set(visibleColumnIndexes);const rowIndexes=new Set(visibleRowIndexes);for(const merge of accessibleMerges){columnIndexes.add(merge.columnStart);rowIndexes.add(merge.rowStart)}const columns=[...columnIndexes].sort((left,right)=>left-right).map(index=>({index,name:snapshot.metadata.schema.columns[index]?.name??`Column ${index+1}`}));const rows=[];for(const rowIndex of[...rowIndexes].sort((left,right)=>left-right)){const candidateColumns=new Set;if(visibleRowIndexes.has(rowIndex)){for(const columnIndex of visibleColumnIndexes)candidateColumns.add(columnIndex)}for(const merge of accessibleMerges){if(merge.rowStart===rowIndex)candidateColumns.add(merge.columnStart)}rows.push({index:rowIndex,cells:[...candidateColumns].sort((left,right)=>left-right).flatMap(columnIndex=>{const merge=this.#mergeContaining(rowIndex,columnIndex);if(merge!==void 0&&(rowIndex!==merge.rowStart||columnIndex!==merge.columnStart)){return[]}const cell=this.controller.getCell(rowIndex,columnIndex);return[{rowIndex,columnIndex,value:cell.status==="loaded"?cell.value:void 0,selected:snapshot.selection!==null&&containsCell(snapshot.selection.range,{rowIndex,columnIndex}),active:snapshot.activeCell?.rowIndex===rowIndex&&snapshot.activeCell.columnIndex===columnIndex,...merge===void 0?{}:{rowSpan:merge.rowEnd-merge.rowStart,columnSpan:merge.columnEnd-merge.columnStart}}]})})}this.#accessibleGrid.update({label:this.#tableLabel(),...snapshot.metadata.extent.rows.kind==="exact"?{exactRowCount:snapshot.metadata.extent.rows.value}:{},columnCount:layout.columnCount,columns,rows,busy:snapshot.status==="loading",status:this.#statusText(snapshot)})}#renderMessage(snapshot){let message="";if(snapshot.status==="error"){message=`Unable to render table: ${errorMessage(snapshot.error)}`}else if(snapshot.status==="closed"){message="Table closed."}else if(snapshot.layout.rowCount===0&&snapshot.status==="ready"){message="No rows to display."}else if(snapshot.status==="loading"&&snapshot.layout.rows.visible.start===snapshot.layout.rows.visible.end){message="Loading data\u2026"}this.#message.textContent=message;this.#message.style.display=message===""?"none":"flex"}#syncNativeScroll(snapshot){const desiredLeft=snapshot.layout.horizontal.physicalOffset;const desiredTop=snapshot.layout.vertical.physicalOffset;if(Math.abs(this.#scrollHost.scrollLeft-desiredLeft)>.5){this.#scrollHost.scrollLeft=desiredLeft}if(Math.abs(this.#scrollHost.scrollTop-desiredTop)>.5){this.#scrollHost.scrollTop=desiredTop}}#cellFromHit(hit){if(hit.kind==="cell"){return Object.freeze({rowIndex:hit.rowIndex,columnIndex:hit.columnIndex})}if(hit.kind==="row-header"&&this.#snapshot.layout.columnCount>0){return Object.freeze({rowIndex:hit.rowIndex,columnIndex:this.#snapshot.activeCell?.columnIndex??0})}if(hit.kind==="column-header"&&this.#snapshot.layout.rowCount>0){return Object.freeze({rowIndex:this.#snapshot.activeCell?.rowIndex??0,columnIndex:hit.columnIndex})}return null}#eventPosition(event){const rect=this.#surface.getBoundingClientRect();return Object.freeze({x:event.clientX-rect.left,y:event.clientY-rect.top})}#resizeColumnFromTarget(target){const handle=this.#resizeHandleFromTarget(target);if(handle===null){return null}const value=handle.dataset.columnResize;if(value===void 0){return null}const columnIndex=Number(value);return Number.isSafeInteger(columnIndex)?columnIndex:null}#resizeHandleFromTarget(target){if(!(target instanceof this.#ownerWindow.HTMLElement)){return null}const handle=target.closest("[data-column-resize]");return handle instanceof this.#ownerWindow.HTMLDivElement&&this.#resizeLayer.contains(handle)?handle:null}#measureColumn(columnIndex){const context=this.#canvas.getContext("2d");if(context===null){return this.controller.columnWidths[columnIndex]}const column=this.#snapshot.metadata.schema.columns[columnIndex];if(column===void 0){return this.controller.columnWidths[columnIndex]}context.save();context.font=this.#theme.headerFont;let width=context.measureText(column.name).width;context.font=this.#theme.font;const visible=this.#snapshot.layout.rows.visible;for(let rowIndex=visible.start;rowIndex<visible.end;rowIndex+=1){const cell=this.controller.getCell(rowIndex,columnIndex);if(cell.status==="loaded"){width=Math.max(width,context.measureText(cell.value??"\u2205").width)}}context.restore();return Math.ceil(width+AUTOSIZE_HORIZONTAL_PADDING)}async#copySelection(){this.#copyAbort?.abort();const abort=new AbortController;this.#copyAbort=abort;try{const text=await this.controller.copySelection({signal:abort.signal});if(abort.signal.aborted||this.#destroyed||text===""){return}if(this.#writeClipboard!==void 0){await this.#writeClipboard(text)}else{const clipboard=this.#ownerWindow.navigator.clipboard;if(clipboard===void 0){throw new Error("Clipboard access is unavailable in this browser context")}await clipboard.writeText(text)}this.#accessibleGrid.statusElement.textContent="Selection copied to clipboard."}catch(error){if(!abort.signal.aborted){this.#accessibleGrid.statusElement.textContent=`Copy failed: ${errorMessage(error)}`;this.#reportError(error)}}finally{if(this.#copyAbort===abort){this.#copyAbort=null}}}#statusText(snapshot){if(snapshot.status==="error"){return`Table error: ${errorMessage(snapshot.error)}`}if(snapshot.status==="closed"){return"Table closed."}if(snapshot.status==="loading"){return"Loading visible table cells."}return`${snapshot.layout.rowCount} rows and ${snapshot.layout.columnCount} columns.`}#announceColumnWidth(columnIndex,fitted){const column=this.#snapshot.metadata.schema.columns[columnIndex];const width=this.controller.columnWidths[columnIndex];if(column===void 0||width===void 0){return}if(this.#announcementFrame!==0){this.#ownerWindow.cancelAnimationFrame(this.#announcementFrame)}const action=fitted?"fit to":"width";const qualifier=fitted?" using visible content":"";this.#announcementFrame=this.#ownerWindow.requestAnimationFrame(()=>{this.#announcementFrame=0;if(!this.#destroyed){this.#accessibleGrid.statusElement.textContent=`${column.name} column ${action} ${formatWidth(width)} CSS pixels${qualifier}.`}})}#applyThemeToElements(){this.element.dataset.tabularkForcedColors=this.#forcedColors?"active":"none";this.element.style.background=this.#theme.background;this.element.style.borderColor=this.#theme.gridLine;this.element.style.color=this.#theme.foreground;this.#message.style.background=this.#theme.background;this.#message.style.color=this.#theme.mutedForeground;this.#canvas.style.forcedColorAdjust=this.#forcedColors?"none":"auto";if(this.element.contains(this.element.ownerDocument.activeElement)){this.element.style.outline=`2px solid ${this.#focusColor()}`;const handle=this.#resizeHandleFromTarget(this.element.ownerDocument.activeElement);if(handle!==null){handle.style.outline=`2px solid ${this.#focusColor()}`}}}#focusColor(){return this.#forcedColors?"Highlight":this.#theme.activeCellBorder}#tableLabel(){return`${this.controller.metadata.name||"Data"} table`}#hasCells(){return this.#snapshot.layout.rowCount>0&&this.#snapshot.layout.columnCount>0}#isTerminal(){return this.#destroyed||this.#snapshot.status==="error"||this.#snapshot.status==="closed"}#cancelInteraction(){if(this.#interaction!==null&&this.#surface.hasPointerCapture(this.#interaction.pointerId)){this.#surface.releasePointerCapture(this.#interaction.pointerId)}this.#interaction=null;this.#surface.style.cursor="default"}#reportError(error){if(this.#onError!==void 0){this.#onError(error)}else if(typeof this.#ownerWindow.reportError==="function"){this.#ownerWindow.reportError(error)}}#assertAlive(){if(this.#destroyed){throw new Error("Canvas table view is destroyed")}}};function splitMergedRegion(region,frozenRowCount,frozenColumnCount){const rows=splitIndexRange(region.rowStart,region.rowEnd,frozenRowCount);const columns=splitIndexRange(region.columnStart,region.columnEnd,frozenColumnCount);return Object.freeze(rows.flatMap(row=>columns.map(column=>Object.freeze({rowStart:row.start,rowEnd:row.end,columnStart:column.start,columnEnd:column.end}))))}function splitIndexRange(start,end,boundary){if(boundary<=start||boundary>=end){return Object.freeze([Object.freeze({start,end})])}return Object.freeze([Object.freeze({start,end:boundary}),Object.freeze({start:boundary,end})])}function mergePaneClip(layout,fragment){const frozenRight=layout.rowHeaderWidth+Math.min(layout.bodyWidth,layout.frozenColumnExtent);const frozenBottom=layout.headerHeight+Math.min(layout.bodyHeight,layout.frozenRowExtent);const frozenColumn=fragment.columnStart<layout.frozenColumnCount;const frozenRow=fragment.rowStart<layout.frozenRowCount;return Object.freeze({left:frozenColumn?layout.rowHeaderWidth:frozenRight,right:frozenColumn?frozenRight:layout.rowHeaderWidth+layout.bodyWidth,top:frozenRow?layout.headerHeight:frozenBottom,bottom:frozenRow?frozenBottom:layout.headerHeight+layout.bodyHeight})}function presentationRequests(layout){const overscan=presentationRectangles(layout.rows.overscan,layout.columns.overscan,layout.frozenRowRange,layout.frozenColumnRange);const overscanCells=overscan.reduce((total,range)=>total+range.rowCount*range.columnCount,0);if(overscanCells<=MAX_PRESENTATION_WINDOW_CELLS)return overscan;return presentationRectangles(layout.rows.visible,layout.columns.visible,layout.frozenRowRange,layout.frozenColumnRange)}function presentationRectangles(rows,columns,frozenRows,frozenColumns){const requests=[];for(const row of presentationBands(rows,frozenRows)){for(const column of presentationBands(columns,frozenColumns)){requests.push(Object.freeze({rowStart:row.start,rowCount:row.end-row.start,columnStart:column.start,columnCount:column.end-column.start}))}}return Object.freeze(requests)}function presentationBands(primary,frozen){const bands=[primary,frozen].filter(range=>range.start<range.end).sort((left,right)=>left.start-right.start);if(bands.length<2)return Object.freeze(bands.map(range=>Object.freeze({...range})));const first=bands[0];const second=bands[1];return first.end>=second.start?Object.freeze([Object.freeze({start:first.start,end:Math.max(first.end,second.end)})]):Object.freeze(bands.map(range=>Object.freeze({...range})))}function rangeKey(range){return`${range.rowStart}:${range.rowCount}:${range.columnStart}:${range.columnCount}`}function mergeKey2(region){return`${region.rowStart}:${region.rowEnd}:${region.columnStart}:${region.columnEnd}`}function collectMergedRegions(ranges){const unique=new Map;for(const window of ranges){for(const region of window.mergedCells)unique.set(mergeKey2(region),region)}return Object.freeze([...unique.values()])}function missingMergeAnchorRequests(regions,ranges){const requests=new Map;for(const region of regions){const anchorLoaded=ranges.some(window=>region.rowStart>=window.range.rowStart&&region.rowStart<window.range.rowStart+window.range.rowCount&&region.columnStart>=window.range.columnStart&&region.columnStart<window.range.columnStart+window.range.columnCount);if(anchorLoaded)continue;const request=Object.freeze({rowStart:region.rowStart,rowCount:1,columnStart:region.columnStart,columnCount:1});requests.set(`${region.rowStart}:${region.columnStart}`,request)}return Object.freeze([...requests.values()])}function createCanvasTableView(options){if(!options||!options.container||typeof options.container.append!=="function"){throw invalidArgument("container must be an HTMLElement")}const hasTable=options.table!==void 0;const hasController=options.controller!==void 0;if(hasTable===hasController){throw invalidArgument("provide exactly one of table or controller")}return new View(options)}function keyboardCommand(event){switch(event.key){case"ArrowLeft":return"left";case"ArrowRight":return"right";case"ArrowUp":return"up";case"ArrowDown":return"down";case"PageUp":return"page-up";case"PageDown":return"page-down";case"Home":return event.ctrlKey||event.metaKey?"table-start":"row-start";case"End":return event.ctrlKey||event.metaKey?"table-end":"row-end";default:return null}}function errorMessage(error){if(error instanceof Error){return error.message}return typeof error==="string"?error:"Unknown error"}function formatWidth(width){return Number.isInteger(width)?String(width):width.toFixed(2).replace(/(?:\.0+|(?<decimal>\.\d*?)0+)$/,"$<decimal>")}function visuallyHide2(element){Object.assign(element.style,{border:"0",clip:"rect(0 0 0 0)",clipPath:"inset(50%)",height:"1px",margin:"-1px",overflow:"hidden",padding:"0",position:"absolute",whiteSpace:"nowrap",width:"1px"})}function createCanvasTableView2(options){return createCanvasTableView(options)}export{TabularkError,createCanvasTableView2 as createCanvasTableView,createEngine,delimitedAdapter};
2
+ //# sourceMappingURL=index.js.map