From 08f85cf826778f9ff13f1e07cfa2776b00a6782f Mon Sep 17 00:00:00 2001 From: Anthony Kim Date: Thu, 5 Feb 2026 00:20:39 -0800 Subject: [PATCH] Use wasm-parts v0.3.0., remove manual sharding/leftover, update iip! --- addons/addon-image/package.json | 2 +- addons/addon-image/src/IIPHandler.ts | 34 +- .../src/kitty/KittyGraphicsHandler.ts | 313 +++++------------- .../src/kitty/KittyGraphicsTypes.ts | 14 +- package-lock.json | 295 +---------------- 5 files changed, 114 insertions(+), 544 deletions(-) diff --git a/addons/addon-image/package.json b/addons/addon-image/package.json index 10933a2e..5078a57f 100644 --- a/addons/addon-image/package.json +++ b/addons/addon-image/package.json @@ -25,6 +25,6 @@ }, "devDependencies": { "sixel": "^0.16.0", - "xterm-wasm-parts": "^0.1.0" + "xterm-wasm-parts": "^0.3.0" } } diff --git a/addons/addon-image/src/IIPHandler.ts b/addons/addon-image/src/IIPHandler.ts index cca3f2ac..17ab4c4a 100644 --- a/addons/addon-image/src/IIPHandler.ts +++ b/addons/addon-image/src/IIPHandler.ts @@ -9,8 +9,10 @@ import Base64Decoder from 'xterm-wasm-parts/lib/base64/Base64Decoder.wasm'; import { HeaderParser, IHeaderFields, HeaderState } from './IIPHeaderParser'; import { imageType, UNSUPPORTED_TYPE } from './IIPMetrics'; -// limit hold memory in base64 decoder +// limit hold memory in base64 decoder (encoded bytes) const KEEP_DATA = 4194304; +const INITIAL_DATA = 1048576; +const DECODER_SUCCESS = 0; // default IIP header values const DEFAULT_HEADER: IHeaderFields = { @@ -27,7 +29,7 @@ export class IIPHandler implements IOscHandler, IResetHandler { private _aborted = false; private _hp = new HeaderParser(); private _header: IHeaderFields = DEFAULT_HEADER; - private _dec = new Base64Decoder(KEEP_DATA); + private _dec: Base64Decoder; private _metrics = UNSUPPORTED_TYPE; constructor( @@ -35,7 +37,11 @@ export class IIPHandler implements IOscHandler, IResetHandler { private readonly _renderer: ImageRenderer, private readonly _storage: ImageStorage, private readonly _coreTerminal: ITerminalExt - ) {} + ) { + const maxEncodedBytes = Math.ceil(this._opts.iipSizeLimit * 4 / 3); + const initialBytes = Math.min(INITIAL_DATA, maxEncodedBytes); + this._dec = new Base64Decoder(KEEP_DATA, maxEncodedBytes, initialBytes); + } public reset(): void {} @@ -50,7 +56,7 @@ export class IIPHandler implements IOscHandler, IResetHandler { if (this._aborted) return; if (this._hp.state === HeaderState.END) { - if (this._dec.put(data, start, end)) { + if (this._dec.put(data.subarray(start, end)) !== DECODER_SUCCESS) { this._dec.release(); this._aborted = true; } @@ -66,8 +72,8 @@ export class IIPHandler implements IOscHandler, IResetHandler { this._aborted = true; return; } - this._dec.init(this._header.size); - if (this._dec.put(data, dataPos, end)) { + this._dec.init(); + if (this._dec.put(data.subarray(dataPos, end)) !== DECODER_SUCCESS) { this._dec.release(); this._aborted = true; } @@ -85,13 +91,15 @@ export class IIPHandler implements IOscHandler, IResetHandler { let cond: number | boolean = true; if (cond = success) { if (cond = !this._dec.end()) { - this._metrics = imageType(this._dec.data8); - if (cond = this._metrics.mime !== 'unsupported') { - w = this._metrics.width; - h = this._metrics.height; - if (cond = w && h && w * h < this._opts.pixelLimit) { - [w, h] = this._resize(w, h).map(Math.floor); - cond = w && h && w * h < this._opts.pixelLimit; + if (cond = this._dec.data8.length === this._header.size) { + this._metrics = imageType(this._dec.data8); + if (cond = this._metrics.mime !== 'unsupported') { + w = this._metrics.width; + h = this._metrics.height; + if (cond = w && h && w * h < this._opts.pixelLimit) { + [w, h] = this._resize(w, h).map(Math.floor); + cond = w && h && w * h < this._opts.pixelLimit; + } } } } diff --git a/addons/addon-image/src/kitty/KittyGraphicsHandler.ts b/addons/addon-image/src/kitty/KittyGraphicsHandler.ts index 74867cf8..2c2c4baf 100644 --- a/addons/addon-image/src/kitty/KittyGraphicsHandler.ts +++ b/addons/addon-image/src/kitty/KittyGraphicsHandler.ts @@ -22,10 +22,8 @@ import { // Memory limit for base64 decoder (4MB, same as IIPHandler) const DECODER_KEEP_DATA = 4194304; - -// Base64 alignment size -// TODO: Remove once decoder handles alignment internally -const BASE64_ALIGNMENT = 4; +const DECODER_INITIAL_DATA = 4194304; // 4MB +const DECODER_SUCCESS = 0; // Maximum control data size const MAX_CONTROL_DATA_SIZE = 512; @@ -33,9 +31,6 @@ const MAX_CONTROL_DATA_SIZE = 512; // Semicolon codepoint const SEMICOLON = 0x3B; -// Padding character '=' -const EQUALS = 0x3D; - /** * Kitty graphics protocol handler with streaming base64 decoding. */ @@ -43,8 +38,9 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { private _aborted = false; private _decodeError = false; - /** Reusable base64 decoder - avoids WASM cold-start on each chunk */ - private _decoder = new Base64Decoder(DECODER_KEEP_DATA); + private _activeDecoder: Base64Decoder | null = null; + private readonly _maxEncodedBytes: number; + private readonly _initialEncodedBytes: number; // Streaming related states @@ -55,15 +51,6 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { private _controlData = new Uint32Array(MAX_CONTROL_DATA_SIZE); private _controlLength = 0; - /** Leftover base64 bytes (0-3) to preserve 4-byte alignment across chunks. - * TODO: Remove once decoder handles alignment internally */ - private _leftover = new Uint32Array(BASE64_ALIGNMENT); - private _leftoverLength = 0; - - /** Accumulated decoded chunks. */ - private _decodedChunks: Uint8Array[] = []; - private _totalDecodedSize = 0; - /** Pre-calculated encoded size limit */ private _encodedSizeLimit = 0; private _totalEncodedSize = 0; @@ -83,10 +70,22 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { private readonly _renderer: ImageRenderer, private readonly _storage: ImageStorage, private readonly _coreTerminal: ITerminalExt - ) {} + ) { + // Convert decoded size limit -> max encoded bytes. + this._maxEncodedBytes = Math.ceil(this._opts.kittySizeLimit * 4 / 3); + // ensure we preallocate more than configured limit while using 4mb initial size. + this._initialEncodedBytes = Math.min(DECODER_INITIAL_DATA, this._maxEncodedBytes); + } public reset(): void { + for (const pending of this._pendingTransmissions.values()) { + pending.decoder.release(); + } this._pendingTransmissions.clear(); + if (this._activeDecoder) { + this._activeDecoder.release(); + this._activeDecoder = null; + } this._images.clear(); for (const bitmap of this._decodedImages.values()) { bitmap.close(); @@ -99,13 +98,11 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { this._decodeError = false; this._inControlData = true; this._controlLength = 0; - this._leftoverLength = 0; - this._decodedChunks = []; - this._totalDecodedSize = 0; this._parsedCommand = null; // Pre-calculate encoded limit once: base64 is 4 bytes encoded → 3 bytes decoded - this._encodedSizeLimit = Math.ceil(this._opts.kittySizeLimit * 4 / 3); + this._encodedSizeLimit = this._maxEncodedBytes; this._totalEncodedSize = 0; + this._activeDecoder = null; } public put(data: Uint32Array, start: number, end: number): void { @@ -159,7 +156,7 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { } /** - * Stream payload bytes, decode at 4-byte aligned boundaries. + * Stream payload bytes into the base64 decoder. */ private _streamPayload(data: Uint32Array, start: number, end: number): void { if (this._aborted) return; @@ -172,69 +169,44 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { this._totalEncodedSize += end - start; const cumulativeEncodedSize = previousEncodedSize + this._totalEncodedSize; if (cumulativeEncodedSize > this._encodedSizeLimit) { + const decoderToRelease = this._activeDecoder ?? pending?.decoder; + if (decoderToRelease) { + decoderToRelease.release(); + } + this._activeDecoder = null; + if (pending) { + this._pendingTransmissions.delete(pendingKey); + } this._aborted = true; return; } if (this._decodeError) return; - if (this._leftoverLength === 0 && pending?.leftoverLength) { - this._leftover.set(pending.leftover.subarray(0, pending.leftoverLength), 0); - this._leftoverLength = pending.leftoverLength; - pending.leftoverLength = 0; + if (pending?.decoder && !this._activeDecoder) { + this._activeDecoder = pending.decoder; + } + if (!this._activeDecoder) { + this._activeDecoder = new Base64Decoder(DECODER_KEEP_DATA, this._maxEncodedBytes, this._initialEncodedBytes); + this._activeDecoder.init(); } - const dataLength = end - start; - const totalLength = this._leftoverLength + dataLength; - const alignedLength = Math.floor(totalLength / BASE64_ALIGNMENT) * BASE64_ALIGNMENT; - - if (alignedLength === 0) { - for (let i = start; i < end; i++) { - this._leftover[this._leftoverLength++] = data[i]; + if (this._activeDecoder.put(data.subarray(start, end)) !== DECODER_SUCCESS) { + this._activeDecoder.release(); + this._activeDecoder = null; + this._decodeError = true; + if (pending) { + this._pendingTransmissions.delete(pendingKey); } - return; - } - - const alignedFromData = alignedLength - this._leftoverLength; - const padding = this._countAlignedPadding(data, start, alignedLength); - const decodedSize = Math.floor(alignedLength / 4) * 3 - padding; - - if (decodedSize > 0) { - this._decoder.init(decodedSize); - - if (this._leftoverLength > 0 && this._decoder.put(this._leftover, 0, this._leftoverLength)) { - this._decoder.release(); - this._decodeError = true; - return; - } - - if (alignedFromData > 0 && this._decoder.put(data, start, start + alignedFromData)) { - this._decoder.release(); - this._decodeError = true; - return; - } - - if (this._decoder.end()) { - this._decoder.release(); - this._decodeError = true; - return; - } - - const chunk = new Uint8Array(this._decoder.data8); - this._decodedChunks.push(chunk); - this._totalDecodedSize += chunk.length; - this._decoder.release(); - } - - this._leftoverLength = 0; - const leftoverStart = start + alignedFromData; - for (let i = leftoverStart; i < end; i++) { - this._leftover[this._leftoverLength++] = data[i]; } } public end(success: boolean): boolean | Promise { if (this._aborted || !success) { + if (this._activeDecoder) { + this._activeDecoder.release(); + this._activeDecoder = null; + } return true; } @@ -256,115 +228,45 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { const pending = this._pendingTransmissions.get(pendingKey); if (isMoreComing) { - if (this._leftoverLength > 0) { - let pendingEntry = pending; - if (!pendingEntry) { - pendingEntry = { + if (this._activeDecoder) { + if (pending) { + pending.totalEncodedSize += this._totalEncodedSize; + pending.decodeError = pending.decodeError || this._decodeError; + } else { + this._pendingTransmissions.set(pendingKey, { cmd: { ...cmd }, - chunks: [], - totalSize: 0, - totalEncodedSize: 0, - leftover: new Uint32Array(BASE64_ALIGNMENT), - leftoverLength: 0 - }; - this._pendingTransmissions.set(pendingKey, pendingEntry); + decoder: this._activeDecoder, + totalEncodedSize: this._totalEncodedSize, + decodeError: this._decodeError + }); } - pendingEntry.leftover.set(this._leftover.subarray(0, this._leftoverLength), 0); - pendingEntry.leftoverLength = this._leftoverLength; + this._activeDecoder = null; } - this._leftoverLength = 0; - } else if (this._leftoverLength > 0) { - this._decodePaddedLeftover(); - this._leftoverLength = 0; + return true; } - // Combine all decoded chunks - const imageBytes = this._combineChunks(); + let decodeError = this._decodeError; + let finalCmd = cmd; + let decoder = this._activeDecoder; - return this._handleCommandWithBytesAndCmd(cmd, imageBytes, this._decodeError); - } - - /** - * TODO: Remove once decoder handles alignment internally. - * This and related alignment helpers become unnecessary when decoder.init() - * no longer requires decoded size and decoder handles base64 padding. - */ - private _countAlignedPadding( - data: Uint32Array, - start: number, - alignedLength: number - ): number { - let padding = 0; - if (alignedLength >= 1 && this._getAlignedCharFromEnd(data, start, alignedLength, 1) === EQUALS) { - padding++; - } - if (alignedLength >= 2 && this._getAlignedCharFromEnd(data, start, alignedLength, 2) === EQUALS) { - padding++; - } - return padding; - } - - private _getAlignedCharFromEnd( - data: Uint32Array, - start: number, - alignedLength: number, - offsetFromEnd: number - ): number { - const index = alignedLength - offsetFromEnd; - if (index < this._leftoverLength) { - return this._leftover[index]; - } - return data[start + index - this._leftoverLength]; - } - - /** - * TODO: Remove once decoder handles alignment internally - */ - private _decodePaddedLeftover(): void { - if (this._decodeError) return; - if (this._leftoverLength === 0) return; - - const padded = new Uint32Array(BASE64_ALIGNMENT); - padded.set(this._leftover.subarray(0, this._leftoverLength), 0); - - const paddingNeeded = BASE64_ALIGNMENT - this._leftoverLength; - for (let i = 0; i < paddingNeeded; i++) { - padded[this._leftoverLength + i] = EQUALS; + if (pending) { + finalCmd = pending.cmd; + decoder = pending.decoder; + decodeError = decodeError || pending.decodeError; + this._pendingTransmissions.delete(pendingKey); } - const decodedSize = 3 - paddingNeeded; - if (decodedSize <= 0) return; - - this._decoder.init(decodedSize); - if (this._decoder.put(padded, 0, BASE64_ALIGNMENT)) { - this._decoder.release(); - this._decodeError = true; - return; + let imageBytes = new Uint8Array(0); + if (decoder) { + if (decoder.end() !== DECODER_SUCCESS) { + decodeError = true; + } + imageBytes = decoder.data8; + decoder.release(); } + this._activeDecoder = null; - if (this._decoder.end()) { - this._decoder.release(); - this._decodeError = true; - return; - } - - const chunk = new Uint8Array(this._decoder.data8); - this._decodedChunks.push(chunk); - this._totalDecodedSize += chunk.length; - this._decoder.release(); - } - - private _combineChunks(): Uint8Array { - if (this._decodedChunks.length === 0) return new Uint8Array(0); - if (this._decodedChunks.length === 1) return this._decodedChunks[0]; - - const result = new Uint8Array(this._totalDecodedSize); - let offset = 0; - for (const chunk of this._decodedChunks) { - result.set(chunk, offset); - offset += chunk.length; - } - return result; + return this._handleCommandWithBytesAndCmd(finalCmd, imageBytes, decodeError); } // Command handling @@ -425,62 +327,6 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { // 2. For t=f/t/s: decode bytes as UTF-8 string (the path/name), then read file contents // 3. For t=d: treat bytes as image data (current behavior) - const pendingKey = cmd.id ?? 0; - const isMoreComing = cmd.more === 1; - const pending = this._pendingTransmissions.get(pendingKey); - - - // For m=1 intermediate chunks, reject if decode error - if (decodeError && !pending && isMoreComing) return true; - - if (pending) { - // Append to existing pending transmission (even if decode error, we keep accumulated data) - if (bytes.length > 0) { - pending.chunks.push(bytes); - pending.totalSize += bytes.length; - } - // Track cumulative encoded size for size limit enforcement - pending.totalEncodedSize += this._totalEncodedSize; - - if (isMoreComing) return true; - - // Final chunk - merge all (even if the final chunk had a decode error) - const fullData = this._mergeChunks(pending.chunks, pending.totalSize); - this._pendingTransmissions.delete(pendingKey); - - - if (fullData.length === 0) return true; // Nothing to store - - const id = pending.cmd.id ?? this._nextImageId++; - const image: IKittyImageData = { - id, - data: fullData, - width: pending.cmd.width ?? 0, - height: pending.cmd.height ?? 0, - format: (pending.cmd.format ?? KittyFormat.PNG) as 24 | 32 | 100, - compression: pending.cmd.compression ?? '' - }; - this._images.set(id, image); - - // Note: Don't display here - _handleTransmitDisplay will do it - return true; - } - - if (isMoreComing) { - // Start new pending transmission (reject if decode error for first chunk) - if (decodeError) return true; - this._pendingTransmissions.set(pendingKey, { - cmd: { ...cmd }, - chunks: bytes.length > 0 ? [bytes] : [], - totalSize: bytes.length, - totalEncodedSize: this._totalEncodedSize, - leftover: new Uint32Array(4), - leftoverLength: 0 - }); - return true; - } - - // Single-chunk transmission - reject if decode error or no data if (decodeError || bytes.length === 0) return true; const id = cmd.id ?? this._nextImageId++; @@ -496,17 +342,6 @@ export class KittyGraphicsHandler implements IApcHandler, IResetHandler { return true; } - private _mergeChunks(chunks: Uint8Array[], totalSize: number): Uint8Array { - if (chunks.length === 1) return chunks[0]; - const result = new Uint8Array(totalSize); - let offset = 0; - for (const chunk of chunks) { - result.set(chunk, offset); - offset += chunk.length; - } - return result; - } - private _handleTransmitDisplay(cmd: IKittyCommand, bytes: Uint8Array, decodeError: boolean): boolean | Promise { if (decodeError) return true; diff --git a/addons/addon-image/src/kitty/KittyGraphicsTypes.ts b/addons/addon-image/src/kitty/KittyGraphicsTypes.ts index d58a51a7..d5f9c3f3 100644 --- a/addons/addon-image/src/kitty/KittyGraphicsTypes.ts +++ b/addons/addon-image/src/kitty/KittyGraphicsTypes.ts @@ -5,6 +5,8 @@ * Kitty graphics protocol types, constants, and parsing utilities. */ +import type Base64Decoder from 'xterm-wasm-parts/lib/base64/Base64Decoder.wasm'; + /** * Kitty graphics protocol action types. * See: https://sw.kovidgoyal.net/kitty/graphics-protocol/#control-data-reference under key 'a'. @@ -101,16 +103,12 @@ export interface IKittyCommand { export interface IPendingTransmission { /** The parsed command from the first chunk (contains action, format, dimensions, etc.) */ cmd: IKittyCommand; - /** Accumulated decoded payload chunks */ - chunks: Uint8Array[]; - /** Total size of accumulated decoded chunks */ - totalSize: number; + /** Decoder used across chunked payloads */ + decoder: Base64Decoder; /** Total encoded (base64) bytes received across all chunks - for size limit enforcement */ totalEncodedSize: number; - /** Leftover base64 bytes (0-3) that weren't aligned in previous chunk */ - leftover: Uint32Array; - /** Number of valid bytes in leftover */ - leftoverLength: number; + /** Whether any chunk has failed to decode */ + decodeError: boolean; } /** diff --git a/package-lock.json b/package-lock.json index 1967b9ba..de50eec7 100644 --- a/package-lock.json +++ b/package-lock.json @@ -79,12 +79,13 @@ "license": "MIT", "devDependencies": { "sixel": "^0.16.0", - "xterm-wasm-parts": "^0.1.0" + "xterm-wasm-parts": "^0.3.0" } }, "addons/addon-kitty-graphics": { "name": "@xterm/addon-kitty-graphics", "version": "0.1.0", + "extraneous": true, "license": "MIT" }, "addons/addon-ligatures": { @@ -1283,102 +1284,6 @@ "url": "https://github.com/sponsors/nzakas" } }, - "node_modules/@isaacs/cliui": { - "version": "8.0.2", - "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", - "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", - "dev": true, - "dependencies": { - "string-width": "^5.1.2", - "string-width-cjs": "npm:string-width@^4.2.0", - "strip-ansi": "^7.0.1", - "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", - "wrap-ansi": "^8.1.0", - "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-regex": { - "version": "6.2.2", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.2.2.tgz", - "integrity": "sha512-Bq3SmSpyFHaWjPk8If9yc6svM8c56dB5BAtW4Qbw5jHTwwXXcTLoRMkpDJp6VL0XzlWaCHTXrkFURMYmD0sLqg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/ansi-styles": { - "version": "6.2.3", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.3.tgz", - "integrity": "sha512-4Dj6M28JB+oAH8kFkTLUo+a2jwOFkuqb3yucU0CANcRRUbxS0cP0nZYCGjcc3BNXwRIsUVmDGgzawme7zvJHvg==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/emoji-regex": { - "version": "9.2.2", - "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-9.2.2.tgz", - "integrity": "sha512-L18DaJsXSUk2+42pv8mLs5jJT2hqFkFE4j21wOmgbUqsZ2hL72NsUU785g9RXgo3s0ZNgVl42TiHp3ZtOv/Vyg==", - "dev": true - }, - "node_modules/@isaacs/cliui/node_modules/string-width": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", - "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", - "dev": true, - "dependencies": { - "eastasianwidth": "^0.2.0", - "emoji-regex": "^9.2.2", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/@isaacs/cliui/node_modules/strip-ansi": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.2.tgz", - "integrity": "sha512-gmBGslpoQJtgnMAvOVqGZpEz9dyoKTCzy2nfz/n8aIFhN/jCE/rCmcxabB6jOOHV+0WNnylOxaxBQPSvcWklhA==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, - "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { - "version": "8.1.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", - "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", - "dev": true, - "dependencies": { - "ansi-styles": "^6.1.0", - "string-width": "^5.0.1", - "strip-ansi": "^7.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -1551,16 +1456,6 @@ "pako": "^2.0.4" } }, - "node_modules/@pkgjs/parseargs": { - "version": "0.11.0", - "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", - "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", - "dev": true, - "optional": true, - "engines": { - "node": ">=14" - } - }, "node_modules/@playwright/test": { "version": "1.57.0", "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.57.0.tgz", @@ -2279,10 +2174,6 @@ "resolved": "addons/addon-image", "link": true }, - "node_modules/@xterm/addon-kitty-graphics": { - "resolved": "addons/addon-kitty-graphics", - "link": true - }, "node_modules/@xterm/addon-ligatures": { "resolved": "addons/addon-ligatures", "link": true @@ -3520,12 +3411,6 @@ "node": ">= 0.4" } }, - "node_modules/eastasianwidth": { - "version": "0.2.0", - "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", - "integrity": "sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==", - "dev": true - }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -4877,54 +4762,12 @@ "node": ">= 0.10" } }, - "node_modules/inwasm": { - "version": "0.0.13", - "resolved": "https://registry.npmjs.org/inwasm/-/inwasm-0.0.13.tgz", - "integrity": "sha512-gmULhw1wfF3tQ19y0TvcNH6A5jN7IuTD51kbZuy+ittUU59d+ZTQMb53wbGQuciMrledgagL3/ohnjUj5qJikQ==", + "node_modules/inwasm-runtime": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/inwasm-runtime/-/inwasm-runtime-0.1.2.tgz", + "integrity": "sha512-in+Lk4d7PGwQnG1zxRe6qHB2nvvc5LUOsI9ByoJRuaDONTY8xDlaF+CvapGoPiqreJ0cMHxRzKtS0SJBccpYfA==", "dev": true, - "dependencies": { - "acorn": "^8.8.2", - "acorn-walk": "^8.2.0", - "chokidar": "^3.5.3", - "colorette": "^2.0.20", - "glob": "^10.0.0", - "wabt": "^1.0.32" - }, - "bin": { - "inwasm": "lib/cli.js" - } - }, - "node_modules/inwasm/node_modules/acorn-walk": { - "version": "8.3.4", - "resolved": "https://registry.npmjs.org/acorn-walk/-/acorn-walk-8.3.4.tgz", - "integrity": "sha512-ueEepnujpqee2o5aIYnvHU6C0A42MNdsIDeqy5BydrkuC5R1ZuUFnm27EeFJGoEHJQgn3uleRvmTXaJgfXbt4g==", - "dev": true, - "dependencies": { - "acorn": "^8.11.0" - }, - "engines": { - "node": ">=0.4.0" - } - }, - "node_modules/inwasm/node_modules/glob": { - "version": "10.5.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-10.5.0.tgz", - "integrity": "sha512-DfXN8DfhJ7NH3Oe7cFmu3NCu1wKbkReJ8TorzSAFbSKrlNaQSKfIzqYqVY8zlbs2NLBbWpRiU52GX2PbaBVNkg==", - "dev": true, - "dependencies": { - "foreground-child": "^3.1.0", - "jackspeak": "^3.1.2", - "minimatch": "^9.0.4", - "minipass": "^7.1.2", - "package-json-from-dist": "^1.0.0", - "path-scurry": "^1.11.1" - }, - "bin": { - "glob": "dist/esm/bin.mjs" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } + "license": "MIT" }, "node_modules/ipaddr.js": { "version": "1.9.1", @@ -5424,21 +5267,6 @@ "node": ">=8" } }, - "node_modules/jackspeak": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-3.4.3.tgz", - "integrity": "sha512-OGlZQpz2yfahA/Rd1Y8Cd9SIEsqvXkLVoSw/cgwhnhFMDbsQFeZYoJJ7bIZBS9BcamUW96asq/npPWugM+RQBw==", - "dev": true, - "dependencies": { - "@isaacs/cliui": "^8.0.2" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - }, - "optionalDependencies": { - "@pkgjs/parseargs": "^0.11.0" - } - }, "node_modules/javascript-natural-sort": { "version": "0.7.1", "resolved": "https://registry.npmjs.org/javascript-natural-sort/-/javascript-natural-sort-0.7.1.tgz", @@ -5887,15 +5715,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/minipass": { - "version": "7.1.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", - "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", - "dev": true, - "engines": { - "node": ">=16 || 14 >=14.17" - } - }, "node_modules/mkdirp": { "version": "0.5.5", "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.5.tgz", @@ -6433,12 +6252,6 @@ "node": ">=8" } }, - "node_modules/package-json-from-dist": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/package-json-from-dist/-/package-json-from-dist-1.0.1.tgz", - "integrity": "sha512-UEZIS3/by4OC8vL3P2dTXRETpebLI2NiI5vIrjaD/5UtrkFX/tNbwjTSRAGC/+7CAo2pIcBaRgWmcBBHcsaCIw==", - "dev": true - }, "node_modules/pako": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/pako/-/pako-2.1.0.tgz", @@ -6526,28 +6339,6 @@ "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", "dev": true }, - "node_modules/path-scurry": { - "version": "1.11.1", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.11.1.tgz", - "integrity": "sha512-Xa4Nw17FS9ApQFJ9umLiJS4orGjm7ZzwUrwamcGQuHSzDyth9boKDaycYdDcZDuqYATXw4HFXgaqWTctW/v1HA==", - "dev": true, - "dependencies": { - "lru-cache": "^10.2.0", - "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" - }, - "engines": { - "node": ">=16 || 14 >=14.18" - }, - "funding": { - "url": "https://github.com/sponsors/isaacs" - } - }, - "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.4.3", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.4.3.tgz", - "integrity": "sha512-JNAzZcXrCt42VGLuYz0zfAzDfAvJWW6AfYlDBQyDV5DClI2m5sAmK+OIO7s59XfsRsWHp02jAJrRadPRGTt6SQ==", - "dev": true - }, "node_modules/path-to-regexp": { "version": "0.1.12", "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.12.tgz", @@ -7541,21 +7332,6 @@ "node": ">=8" } }, - "node_modules/string-width-cjs": { - "name": "string-width", - "version": "4.2.3", - "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", - "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", - "dev": true, - "dependencies": { - "emoji-regex": "^8.0.0", - "is-fullwidth-code-point": "^3.0.0", - "strip-ansi": "^6.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -7568,19 +7344,6 @@ "node": ">=8" } }, - "node_modules/strip-ansi-cjs": { - "name": "strip-ansi", - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", - "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", - "dev": true, - "dependencies": { - "ansi-regex": "^5.0.1" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -8099,23 +7862,6 @@ "node": ">=18" } }, - "node_modules/wabt": { - "version": "1.0.39", - "resolved": "https://registry.npmjs.org/wabt/-/wabt-1.0.39.tgz", - "integrity": "sha512-ba+dRL/75VQQY7RkU/CgriGbkoWAfS8TDyUlJfJhJ8KhtXgMl5dhNvoPNUcQ9IWRhW8u41glMSuZeTvsYq2rRg==", - "dev": true, - "bin": { - "wasm-decompile": "bin/wasm-decompile", - "wasm-interp": "bin/wasm-interp", - "wasm-objdump": "bin/wasm-objdump", - "wasm-stats": "bin/wasm-stats", - "wasm-strip": "bin/wasm-strip", - "wasm-validate": "bin/wasm-validate", - "wasm2c": "bin/wasm2c", - "wasm2wat": "bin/wasm2wat", - "wat2wasm": "bin/wat2wasm" - } - }, "node_modules/watchpack": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.0.tgz", @@ -8459,24 +8205,6 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, - "node_modules/wrap-ansi-cjs": { - "name": "wrap-ansi", - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", - "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", - "dev": true, - "dependencies": { - "ansi-styles": "^4.0.0", - "string-width": "^4.1.0", - "strip-ansi": "^6.0.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/wrap-ansi?sponsor=1" - } - }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -8589,12 +8317,13 @@ } }, "node_modules/xterm-wasm-parts": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/xterm-wasm-parts/-/xterm-wasm-parts-0.1.0.tgz", - "integrity": "sha512-GFE8yNJfdkytGpcsOZhkL3B8XyUqkR/Du3SdxRyFbJg+BBCKm3raaaflgIM4TwNQ2AOLz01BEEuB5FZXx8aNTQ==", + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/xterm-wasm-parts/-/xterm-wasm-parts-0.3.0.tgz", + "integrity": "sha512-V/lhvDv2Scov2ukhTNmmur6jMq2DSL8QOdQdXWgfqcAYbUf7bgixwl2sB1gYPGE21NTw2OvbAw+vANRncWzR4w==", "dev": true, + "license": "MIT", "dependencies": { - "inwasm": "^0.0.13" + "inwasm-runtime": "^0.1.2" } }, "node_modules/y18n": {