@opentui/core 0.2.6 → 0.2.7

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.
@@ -184,7 +184,7 @@ import {
184
184
  white,
185
185
  wrapWithDelegates,
186
186
  yellow
187
- } from "./index-s460mpf9.js";
187
+ } from "./index-t4yn324k.js";
188
188
 
189
189
  // src/index.ts
190
190
  var exports_src2 = {};
@@ -203,6 +203,7 @@ __export(exports_src2, {
203
203
  stripAnsiSequences: () => stripAnsiSequences,
204
204
  stringToStyledText: () => stringToStyledText,
205
205
  strikethrough: () => strikethrough,
206
+ setupAudio: () => setupAudio,
206
207
  setRenderLibPath: () => setRenderLibPath,
207
208
  rgbToHex: () => rgbToHex,
208
209
  reverse: () => reverse,
@@ -425,6 +426,7 @@ __export(exports_src2, {
425
426
  BorderCharArrays: () => BorderCharArrays,
426
427
  BloomEffect: () => BloomEffect,
427
428
  BaseRenderable: () => BaseRenderable,
429
+ Audio: () => Audio,
428
430
  ArrowRenderable: () => ArrowRenderable,
429
431
  ATTRIBUTE_BASE_MASK: () => ATTRIBUTE_BASE_MASK,
430
432
  ATTRIBUTE_BASE_BITS: () => ATTRIBUTE_BASE_BITS,
@@ -3020,6 +3022,362 @@ class NativeSpanFeed {
3020
3022
  }
3021
3023
  }
3022
3024
  }
3025
+ // src/audio.ts
3026
+ import { EventEmitter } from "events";
3027
+ import { readFile } from "fs/promises";
3028
+ function statusToError(action, status) {
3029
+ return new Error(`Audio ${action} failed: ${status}`);
3030
+ }
3031
+ function toBytes(data) {
3032
+ return data instanceof Uint8Array ? data : new Uint8Array(data);
3033
+ }
3034
+
3035
+ class Audio extends EventEmitter {
3036
+ static create(options = {}) {
3037
+ return new Audio(resolveRenderLib(), options);
3038
+ }
3039
+ lib;
3040
+ defaultStartOptions;
3041
+ engine = null;
3042
+ groups = new Map;
3043
+ playbackStarted = false;
3044
+ mixerStarted = false;
3045
+ constructor(lib, options) {
3046
+ super();
3047
+ this.lib = lib;
3048
+ this.defaultStartOptions = options.startOptions;
3049
+ const createOptions = options.sampleRate == null && options.playbackChannels == null ? undefined : {
3050
+ sampleRate: options.sampleRate == null ? undefined : Math.max(0, Math.trunc(options.sampleRate)),
3051
+ playbackChannels: options.playbackChannels == null ? undefined : Math.max(0, Math.trunc(options.playbackChannels))
3052
+ };
3053
+ this.engine = this.lib.createAudioEngine(createOptions);
3054
+ if (!this.engine) {
3055
+ this.emitError("createAudioEngine", undefined, "Audio createAudioEngine returned null");
3056
+ return;
3057
+ }
3058
+ if (options.autoStart ?? false) {
3059
+ this.start(this.defaultStartOptions);
3060
+ }
3061
+ }
3062
+ emitError(action, status, message, cause) {
3063
+ const error = message ? new Error(message) : statusToError(action, status ?? -1);
3064
+ if (cause)
3065
+ error.cause = cause;
3066
+ this.emit("error", error, { action, status });
3067
+ }
3068
+ start(options) {
3069
+ if (this.playbackStarted)
3070
+ return true;
3071
+ const engine2 = this.engine;
3072
+ if (!engine2) {
3073
+ this.emitError("start", undefined, "Audio engine unavailable during start");
3074
+ return false;
3075
+ }
3076
+ const startOptions = options ?? this.defaultStartOptions;
3077
+ const status = this.lib.audioStart(engine2, startOptions);
3078
+ if (status !== 0) {
3079
+ this.emitError("start", status);
3080
+ return false;
3081
+ }
3082
+ this.playbackStarted = true;
3083
+ this.mixerStarted = true;
3084
+ this.emit("started");
3085
+ return true;
3086
+ }
3087
+ startMixer() {
3088
+ if (this.mixerStarted)
3089
+ return true;
3090
+ const engine2 = this.engine;
3091
+ if (!engine2) {
3092
+ this.emitError("startMixer", undefined, "Audio engine unavailable during startMixer");
3093
+ return false;
3094
+ }
3095
+ const status = this.lib.audioStartMixer(engine2);
3096
+ if (status !== 0) {
3097
+ this.emitError("startMixer", status);
3098
+ return false;
3099
+ }
3100
+ this.mixerStarted = true;
3101
+ this.emit("mixerStarted");
3102
+ return true;
3103
+ }
3104
+ stop() {
3105
+ if (!this.mixerStarted)
3106
+ return true;
3107
+ const engine2 = this.engine;
3108
+ if (!engine2) {
3109
+ this.emitError("stop", undefined, "Audio engine unavailable during stop");
3110
+ return false;
3111
+ }
3112
+ const status = this.lib.audioStop(engine2);
3113
+ if (status !== 0) {
3114
+ this.emitError("stop", status);
3115
+ return false;
3116
+ }
3117
+ this.playbackStarted = false;
3118
+ this.mixerStarted = false;
3119
+ this.emit("stopped");
3120
+ return true;
3121
+ }
3122
+ isStarted() {
3123
+ return this.playbackStarted;
3124
+ }
3125
+ isMixerStarted() {
3126
+ return this.mixerStarted;
3127
+ }
3128
+ loadSound(data) {
3129
+ const engine2 = this.engine;
3130
+ if (!engine2) {
3131
+ this.emitError("loadSound", undefined, "Audio engine unavailable during loadSound");
3132
+ return null;
3133
+ }
3134
+ const result = this.lib.audioLoad(engine2, toBytes(data));
3135
+ if (result.status !== 0 || result.soundId == null) {
3136
+ this.emitError("loadSound", result.status);
3137
+ return null;
3138
+ }
3139
+ return result.soundId;
3140
+ }
3141
+ async loadSoundFile(filePath) {
3142
+ const bytes = await readFile(filePath).catch((err) => {
3143
+ this.emitError("loadSoundFile", undefined, `Failed to read file '${filePath}': ${err.message}`, err);
3144
+ return null;
3145
+ });
3146
+ if (bytes == null)
3147
+ return null;
3148
+ return this.loadSound(bytes);
3149
+ }
3150
+ unloadSound(sound) {
3151
+ const engine2 = this.engine;
3152
+ if (!engine2) {
3153
+ this.emitError("unloadSound", undefined, "Audio engine unavailable during unloadSound");
3154
+ return false;
3155
+ }
3156
+ const status = this.lib.audioUnload(engine2, sound);
3157
+ if (status !== 0) {
3158
+ this.emitError("unloadSound", status);
3159
+ return false;
3160
+ }
3161
+ return true;
3162
+ }
3163
+ group(name) {
3164
+ const existing = this.groups.get(name);
3165
+ if (existing != null) {
3166
+ return existing;
3167
+ }
3168
+ const engine2 = this.engine;
3169
+ if (!engine2) {
3170
+ this.emitError("group", undefined, "Audio engine unavailable during group");
3171
+ return null;
3172
+ }
3173
+ const result = this.lib.audioCreateGroup(engine2, name);
3174
+ if (result.status !== 0 || result.groupId == null) {
3175
+ this.emitError("group", result.status);
3176
+ return null;
3177
+ }
3178
+ this.groups.set(name, result.groupId);
3179
+ return result.groupId;
3180
+ }
3181
+ play(sound, options) {
3182
+ const rawOptions = options ? {
3183
+ volume: options.volume,
3184
+ pan: options.pan,
3185
+ loop: options.loop,
3186
+ groupId: options.groupId ?? 0
3187
+ } : undefined;
3188
+ const engine2 = this.engine;
3189
+ if (!engine2) {
3190
+ this.emitError("play", undefined, "Audio engine unavailable during play");
3191
+ return null;
3192
+ }
3193
+ const result = this.lib.audioPlay(engine2, sound, rawOptions);
3194
+ if (result.status !== 0 || result.voiceId == null) {
3195
+ this.emitError("play", result.status);
3196
+ return null;
3197
+ }
3198
+ return result.voiceId;
3199
+ }
3200
+ stopVoice(voice) {
3201
+ const engine2 = this.engine;
3202
+ if (!engine2) {
3203
+ this.emitError("stopVoice", undefined, "Audio engine unavailable during stopVoice");
3204
+ return false;
3205
+ }
3206
+ const status = this.lib.audioStopVoice(engine2, voice);
3207
+ if (status !== 0) {
3208
+ this.emitError("stopVoice", status);
3209
+ return false;
3210
+ }
3211
+ return true;
3212
+ }
3213
+ setVoiceGroup(voice, group) {
3214
+ const engine2 = this.engine;
3215
+ if (!engine2) {
3216
+ this.emitError("setVoiceGroup", undefined, "Audio engine unavailable during setVoiceGroup");
3217
+ return false;
3218
+ }
3219
+ const status = this.lib.audioSetVoiceGroup(engine2, voice, group);
3220
+ if (status !== 0) {
3221
+ this.emitError("setVoiceGroup", status);
3222
+ return false;
3223
+ }
3224
+ return true;
3225
+ }
3226
+ setGroupVolume(group, volume) {
3227
+ const engine2 = this.engine;
3228
+ if (!engine2) {
3229
+ this.emitError("setGroupVolume", undefined, "Audio engine unavailable during setGroupVolume");
3230
+ return false;
3231
+ }
3232
+ const status = this.lib.audioSetGroupVolume(engine2, group, volume);
3233
+ if (status !== 0) {
3234
+ this.emitError("setGroupVolume", status);
3235
+ return false;
3236
+ }
3237
+ return true;
3238
+ }
3239
+ setMasterVolume(volume) {
3240
+ const engine2 = this.engine;
3241
+ if (!engine2) {
3242
+ this.emitError("setMasterVolume", undefined, "Audio engine unavailable during setMasterVolume");
3243
+ return false;
3244
+ }
3245
+ const status = this.lib.audioSetMasterVolume(engine2, volume);
3246
+ if (status !== 0) {
3247
+ this.emitError("setMasterVolume", status);
3248
+ return false;
3249
+ }
3250
+ return true;
3251
+ }
3252
+ mixFrames(frameCount, channels = 2) {
3253
+ const engine2 = this.engine;
3254
+ if (!engine2) {
3255
+ this.emitError("mixFrames", undefined, "Audio engine unavailable during mixFrames");
3256
+ return null;
3257
+ }
3258
+ const output = new Float32Array(frameCount * channels);
3259
+ const status = this.lib.audioMixToBuffer(engine2, output, frameCount, channels);
3260
+ if (status !== 0) {
3261
+ this.emitError("mixFrames", status);
3262
+ return null;
3263
+ }
3264
+ return output;
3265
+ }
3266
+ enableTap(capacityFrames = 8192) {
3267
+ const engine2 = this.engine;
3268
+ if (!engine2) {
3269
+ this.emitError("enableTap", undefined, "Audio engine unavailable during enableTap");
3270
+ return false;
3271
+ }
3272
+ const status = this.lib.audioEnableTap(engine2, true, capacityFrames);
3273
+ if (status !== 0) {
3274
+ this.emitError("enableTap", status);
3275
+ return false;
3276
+ }
3277
+ return true;
3278
+ }
3279
+ disableTap() {
3280
+ const engine2 = this.engine;
3281
+ if (!engine2) {
3282
+ this.emitError("enableTap", undefined, "Audio engine unavailable during disableTap");
3283
+ return false;
3284
+ }
3285
+ const status = this.lib.audioEnableTap(engine2, false, 0);
3286
+ if (status !== 0) {
3287
+ this.emitError("enableTap", status);
3288
+ return false;
3289
+ }
3290
+ return true;
3291
+ }
3292
+ readTapFrames(frameCount, channels = 2) {
3293
+ const engine2 = this.engine;
3294
+ if (!engine2) {
3295
+ this.emitError("readTapFrames", undefined, "Audio engine unavailable during readTapFrames");
3296
+ return null;
3297
+ }
3298
+ const output = new Float32Array(frameCount * channels);
3299
+ const result = this.lib.audioReadTap(engine2, output, frameCount, channels);
3300
+ if (result.status !== 0) {
3301
+ this.emitError("readTapFrames", result.status);
3302
+ return null;
3303
+ }
3304
+ return { frames: output, framesRead: result.framesRead };
3305
+ }
3306
+ listPlaybackDevices() {
3307
+ const engine2 = this.engine;
3308
+ if (!engine2) {
3309
+ this.emitError("listPlaybackDevices", undefined, "Audio engine unavailable during listPlaybackDevices");
3310
+ return null;
3311
+ }
3312
+ const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2);
3313
+ if (refreshStatus !== 0) {
3314
+ this.emitError("listPlaybackDevices", refreshStatus);
3315
+ return null;
3316
+ }
3317
+ const count = this.lib.audioGetPlaybackDeviceCount(engine2);
3318
+ const devices = [];
3319
+ for (let index = 0;index < count; index += 1) {
3320
+ devices.push({
3321
+ index,
3322
+ name: this.lib.audioGetPlaybackDeviceName(engine2, index),
3323
+ isDefault: this.lib.audioIsPlaybackDeviceDefault(engine2, index)
3324
+ });
3325
+ }
3326
+ return devices;
3327
+ }
3328
+ selectPlaybackDevice(index) {
3329
+ const engine2 = this.engine;
3330
+ if (!engine2) {
3331
+ this.emitError("selectPlaybackDevice", undefined, "Audio engine unavailable during selectPlaybackDevice");
3332
+ return false;
3333
+ }
3334
+ const refreshStatus = this.lib.audioRefreshPlaybackDevices(engine2);
3335
+ if (refreshStatus !== 0) {
3336
+ this.emitError("selectPlaybackDevice", refreshStatus);
3337
+ return false;
3338
+ }
3339
+ const status = this.lib.audioSelectPlaybackDevice(engine2, index);
3340
+ if (status !== 0) {
3341
+ this.emitError("selectPlaybackDevice", status);
3342
+ return false;
3343
+ }
3344
+ return true;
3345
+ }
3346
+ clearPlaybackDeviceSelection() {
3347
+ const engine2 = this.engine;
3348
+ if (!engine2) {
3349
+ this.emitError("clearPlaybackDeviceSelection", undefined, "Audio engine unavailable during clearPlaybackDeviceSelection");
3350
+ return;
3351
+ }
3352
+ this.lib.audioClearPlaybackDeviceSelection(engine2);
3353
+ }
3354
+ getStats() {
3355
+ const engine2 = this.engine;
3356
+ if (!engine2) {
3357
+ this.emitError("getStats", undefined, "Audio engine unavailable during getStats");
3358
+ return null;
3359
+ }
3360
+ const stats = this.lib.audioGetStats(engine2);
3361
+ if (stats == null) {
3362
+ this.emitError("getStats", undefined, "Failed to retrieve audio stats");
3363
+ }
3364
+ return stats;
3365
+ }
3366
+ dispose() {
3367
+ if (!this.engine)
3368
+ return;
3369
+ if (this.mixerStarted) {
3370
+ this.stop();
3371
+ }
3372
+ this.groups.clear();
3373
+ this.lib.destroyAudioEngine(this.engine);
3374
+ this.engine = null;
3375
+ this.emit("disposed");
3376
+ }
3377
+ }
3378
+ function setupAudio(options = {}) {
3379
+ return Audio.create(options);
3380
+ }
3023
3381
  // src/renderables/FrameBuffer.ts
3024
3382
  class FrameBufferRenderable extends Renderable {
3025
3383
  frameBuffer;
@@ -5588,7 +5946,8 @@ class TextTableRenderable extends Renderable {
5588
5946
  _wrapMode;
5589
5947
  _columnWidthMode;
5590
5948
  _columnFitter;
5591
- _cellPadding;
5949
+ _cellPaddingX;
5950
+ _cellPaddingY;
5592
5951
  _columnGap;
5593
5952
  _showBorders;
5594
5953
  _border;
@@ -5620,6 +5979,8 @@ class TextTableRenderable extends Renderable {
5620
5979
  columnWidthMode: "full",
5621
5980
  columnFitter: "proportional",
5622
5981
  cellPadding: 0,
5982
+ cellPaddingX: undefined,
5983
+ cellPaddingY: undefined,
5623
5984
  columnGap: 0,
5624
5985
  showBorders: true,
5625
5986
  border: true,
@@ -5641,7 +6002,8 @@ class TextTableRenderable extends Renderable {
5641
6002
  this._wrapMode = options.wrapMode ?? this._defaultOptions.wrapMode;
5642
6003
  this._columnWidthMode = options.columnWidthMode ?? this._defaultOptions.columnWidthMode;
5643
6004
  this._columnFitter = this.resolveColumnFitter(options.columnFitter);
5644
- this._cellPadding = this.resolveCellPadding(options.cellPadding);
6005
+ this._cellPaddingX = this.resolveCellPadding(options.cellPaddingX ?? options.cellPadding);
6006
+ this._cellPaddingY = this.resolveCellPadding(options.cellPaddingY ?? options.cellPadding);
5645
6007
  this._columnGap = this.resolveColumnGap(options.columnGap);
5646
6008
  this._showBorders = options.showBorders ?? this._defaultOptions.showBorders;
5647
6009
  this._border = options.border ?? this._defaultOptions.border;
@@ -5701,13 +6063,34 @@ class TextTableRenderable extends Renderable {
5701
6063
  this.invalidateLayoutAndRaster();
5702
6064
  }
5703
6065
  get cellPadding() {
5704
- return this._cellPadding;
6066
+ return this._cellPaddingX === this._cellPaddingY ? this._cellPaddingX : 0;
5705
6067
  }
5706
6068
  set cellPadding(value) {
5707
6069
  const next = this.resolveCellPadding(value);
5708
- if (this._cellPadding === next)
6070
+ if (this._cellPaddingX === next && this._cellPaddingY === next)
6071
+ return;
6072
+ this._cellPaddingX = next;
6073
+ this._cellPaddingY = next;
6074
+ this.invalidateLayoutAndRaster();
6075
+ }
6076
+ get cellPaddingX() {
6077
+ return this._cellPaddingX;
6078
+ }
6079
+ set cellPaddingX(value) {
6080
+ const next = this.resolveCellPadding(value);
6081
+ if (this._cellPaddingX === next)
5709
6082
  return;
5710
- this._cellPadding = next;
6083
+ this._cellPaddingX = next;
6084
+ this.invalidateLayoutAndRaster();
6085
+ }
6086
+ get cellPaddingY() {
6087
+ return this._cellPaddingY;
6088
+ }
6089
+ set cellPaddingY(value) {
6090
+ const next = this.resolveCellPadding(value);
6091
+ if (this._cellPaddingY === next)
6092
+ return;
6093
+ this._cellPaddingY = next;
5711
6094
  this.invalidateLayoutAndRaster();
5712
6095
  }
5713
6096
  get columnGap() {
@@ -6329,14 +6712,15 @@ class TextTableRenderable extends Renderable {
6329
6712
  drawCellRange(buffer, firstRow, lastRow) {
6330
6713
  const colOffsets = this._layout.columnOffsets;
6331
6714
  const rowOffsets = this._layout.rowOffsets;
6332
- const cellPadding = this._cellPadding;
6715
+ const cellPaddingX = this._cellPaddingX;
6716
+ const cellPaddingY = this._cellPaddingY;
6333
6717
  for (let rowIdx = firstRow;rowIdx <= lastRow; rowIdx++) {
6334
- const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPadding;
6718
+ const cellY = (rowOffsets[rowIdx] ?? 0) + 1 + cellPaddingY;
6335
6719
  for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
6336
6720
  const cell = this._cells[rowIdx]?.[colIdx];
6337
6721
  if (!cell)
6338
6722
  continue;
6339
- buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPadding, cellY);
6723
+ buffer.drawTextBuffer(cell.textBufferView, (colOffsets[colIdx] ?? 0) + 1 + cellPaddingX, cellY);
6340
6724
  }
6341
6725
  }
6342
6726
  }
@@ -6431,7 +6815,7 @@ class TextTableRenderable extends Renderable {
6431
6815
  this.resetRowSelection(rowIdx);
6432
6816
  continue;
6433
6817
  }
6434
- const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPadding;
6818
+ const cellTop = (this._layout.rowOffsets[rowIdx] ?? 0) + 1 + this._cellPaddingY;
6435
6819
  for (let colIdx = 0;colIdx < this._columnCount; colIdx++) {
6436
6820
  const cell = this._cells[rowIdx]?.[colIdx];
6437
6821
  if (!cell)
@@ -6440,7 +6824,7 @@ class TextTableRenderable extends Renderable {
6440
6824
  cell.textBufferView.resetLocalSelection();
6441
6825
  continue;
6442
6826
  }
6443
- const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPadding;
6827
+ const cellLeft = (this._layout.columnOffsets[colIdx] ?? 0) + 1 + this._cellPaddingX;
6444
6828
  let coords = {
6445
6829
  anchorX: localSelection.anchorX - cellLeft,
6446
6830
  anchorY: localSelection.anchorY - cellTop,
@@ -6586,10 +6970,10 @@ class TextTableRenderable extends Renderable {
6586
6970
  return;
6587
6971
  }
6588
6972
  getHorizontalCellPadding() {
6589
- return this._cellPadding * 2;
6973
+ return this._cellPaddingX * 2;
6590
6974
  }
6591
6975
  getVerticalCellPadding() {
6592
- return this._cellPadding * 2;
6976
+ return this._cellPaddingY * 2;
6593
6977
  }
6594
6978
  resolveColumnFitter(value) {
6595
6979
  if (value === undefined) {
@@ -8078,6 +8462,28 @@ class MarkdownRenderable extends Renderable {
8078
8462
  this._tableOptions = value;
8079
8463
  this.applyTableOptionsToBlocks();
8080
8464
  }
8465
+ get renderNode() {
8466
+ return this._renderNode;
8467
+ }
8468
+ set renderNode(value) {
8469
+ if (this._renderNode === value)
8470
+ return;
8471
+ this._renderNode = value;
8472
+ this.clearBlockStates();
8473
+ this._parseState = null;
8474
+ this.updateBlocks(true);
8475
+ this.requestRender();
8476
+ }
8477
+ get internalBlockMode() {
8478
+ return this._internalBlockMode;
8479
+ }
8480
+ set internalBlockMode(value) {
8481
+ if (this._internalBlockMode === value)
8482
+ return;
8483
+ this._internalBlockMode = value;
8484
+ this.updateBlocks(true);
8485
+ this.requestRender();
8486
+ }
8081
8487
  getStyle(group) {
8082
8488
  if (!this._syntaxStyle)
8083
8489
  return;
@@ -8234,7 +8640,7 @@ class MarkdownRenderable extends Renderable {
8234
8640
  renderable.marginTop = marginTop;
8235
8641
  renderable.marginBottom = marginBottom;
8236
8642
  }
8237
- createMarkdownCodeRenderable(content, id, marginBottom = 0) {
8643
+ createMarkdownCodeRenderable(content, id, marginBottom = 0, onChunks = this._linkifyMarkdownChunks, baseHighlight) {
8238
8644
  return new CodeRenderable(this.ctx, {
8239
8645
  id,
8240
8646
  content,
@@ -8245,12 +8651,43 @@ class MarkdownRenderable extends Renderable {
8245
8651
  conceal: this._conceal,
8246
8652
  drawUnstyledText: false,
8247
8653
  streaming: true,
8248
- onChunks: this._linkifyMarkdownChunks,
8654
+ baseHighlight,
8655
+ onChunks,
8249
8656
  treeSitterClient: this._treeSitterClient,
8250
8657
  width: "100%",
8251
8658
  marginBottom
8252
8659
  });
8253
8660
  }
8661
+ getBlockquoteContent(token) {
8662
+ return "text" in token && typeof token.text === "string" && token.text ? token.text : " ";
8663
+ }
8664
+ getBlockquoteBorderColor() {
8665
+ return this.getStyle("conceal")?.fg ?? this.getStyle("default")?.fg ?? this._fg ?? "#FFFFFF";
8666
+ }
8667
+ createBlockquoteRenderable(token, id, marginBottom = 0) {
8668
+ const renderable = new BoxRenderable(this.ctx, {
8669
+ id,
8670
+ width: "100%",
8671
+ border: ["left"],
8672
+ borderColor: this.getBlockquoteBorderColor(),
8673
+ paddingLeft: 1,
8674
+ flexShrink: 0,
8675
+ marginBottom
8676
+ });
8677
+ renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote"));
8678
+ return renderable;
8679
+ }
8680
+ createHorizontalRuleRenderable(id, marginBottom = 0) {
8681
+ return new BoxRenderable(this.ctx, {
8682
+ id,
8683
+ width: "100%",
8684
+ height: 1,
8685
+ border: ["top"],
8686
+ borderColor: this.getStyle("conceal")?.fg ?? this._fg ?? "#888888",
8687
+ flexShrink: 0,
8688
+ marginBottom
8689
+ });
8690
+ }
8254
8691
  createCodeRenderable(token, id, marginBottom = 0) {
8255
8692
  return new CodeRenderable(this.ctx, {
8256
8693
  id,
@@ -8267,7 +8704,7 @@ class MarkdownRenderable extends Renderable {
8267
8704
  marginBottom
8268
8705
  });
8269
8706
  }
8270
- applyMarkdownCodeRenderable(renderable, content, marginBottom) {
8707
+ applyMarkdownCodeRenderable(renderable, content, marginBottom, baseHighlight) {
8271
8708
  renderable.content = content;
8272
8709
  renderable.filetype = "markdown";
8273
8710
  renderable.syntaxStyle = this._syntaxStyle;
@@ -8276,9 +8713,27 @@ class MarkdownRenderable extends Renderable {
8276
8713
  renderable.conceal = this._conceal;
8277
8714
  renderable.drawUnstyledText = false;
8278
8715
  renderable.streaming = true;
8716
+ renderable.baseHighlight = baseHighlight;
8279
8717
  renderable.marginBottom = marginBottom;
8280
8718
  }
8719
+ applyBlockquoteRenderable(renderable, token, marginBottom) {
8720
+ if (!(renderable instanceof BoxRenderable))
8721
+ return;
8722
+ renderable.borderColor = this.getBlockquoteBorderColor();
8723
+ renderable.marginBottom = marginBottom;
8724
+ const child = renderable.getChildren()[0];
8725
+ if (child instanceof CodeRenderable) {
8726
+ this.applyMarkdownCodeRenderable(child, this.getBlockquoteContent(token), 0, "markup.quote");
8727
+ return;
8728
+ }
8729
+ for (const existing of renderable.getChildren()) {
8730
+ existing.destroyRecursively();
8731
+ }
8732
+ renderable.add(this.createMarkdownCodeRenderable(this.getBlockquoteContent(token), `${renderable.id}-content`, 0, this._linkifyMarkdownChunks, "markup.quote"));
8733
+ }
8281
8734
  applyCodeBlockRenderable(renderable, token, marginBottom) {
8735
+ if (!(renderable instanceof CodeRenderable))
8736
+ return;
8282
8737
  renderable.content = token.text;
8283
8738
  renderable.filetype = infoStringToFiletype(token.lang ?? "");
8284
8739
  renderable.syntaxStyle = this._syntaxStyle;
@@ -8290,7 +8745,7 @@ class MarkdownRenderable extends Renderable {
8290
8745
  renderable.marginBottom = marginBottom;
8291
8746
  }
8292
8747
  shouldRenderSeparately(token) {
8293
- return token.type === "code" || token.type === "table" || token.type === "blockquote";
8748
+ return token.type === "code" || token.type === "table" || token.type === "blockquote" || token.type === "hr";
8294
8749
  }
8295
8750
  getInterBlockMargin(token, hasNextToken) {
8296
8751
  if (!hasNextToken)
@@ -8363,7 +8818,8 @@ class MarkdownRenderable extends Renderable {
8363
8818
  continue;
8364
8819
  }
8365
8820
  const prev = blocks[blocks.length - 1];
8366
- const marginTop = prev && (this.shouldRenderSeparately(prev.token) || TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.token.raw + gapBefore)) ? 1 : 0;
8821
+ const separated = prev ? TRAILING_MARKDOWN_BLOCK_BREAKS_RE.test(prev.token.raw + gapBefore) : false;
8822
+ const marginTop = prev && this.shouldAddTopLevelMargin(prev.token, token, separated) ? 1 : 0;
8367
8823
  blocks.push({
8368
8824
  token,
8369
8825
  sourceTokenEnd: i + 1,
@@ -8373,6 +8829,15 @@ class MarkdownRenderable extends Renderable {
8373
8829
  }
8374
8830
  return blocks;
8375
8831
  }
8832
+ shouldAddTopLevelMargin(prev, current, separated) {
8833
+ if (current.type === "heading" || prev.type === "heading")
8834
+ return true;
8835
+ if (current.type === "list")
8836
+ return separated;
8837
+ if (this.shouldRenderSeparately(prev) || this.shouldRenderSeparately(current))
8838
+ return true;
8839
+ return separated && prev.type === "paragraph" && current.type === "paragraph";
8840
+ }
8376
8841
  getTableRowsToRender(table) {
8377
8842
  return table.rows;
8378
8843
  }
@@ -8516,6 +8981,8 @@ class MarkdownRenderable extends Renderable {
8516
8981
  columnFitter: this._tableOptions?.columnFitter ?? "proportional",
8517
8982
  wrapMode: this._tableOptions?.wrapMode ?? "word",
8518
8983
  cellPadding: this._tableOptions?.cellPadding ?? 0,
8984
+ cellPaddingX: this._tableOptions?.cellPaddingX ?? this._tableOptions?.cellPadding ?? 0,
8985
+ cellPaddingY: this._tableOptions?.cellPaddingY ?? this._tableOptions?.cellPadding ?? 0,
8519
8986
  columnGap: this.usesBorderlessColumnSpacing() ? 2 : 0,
8520
8987
  border: borders,
8521
8988
  outerBorder: this._tableOptions?.outerBorder ?? borders,
@@ -8529,7 +8996,8 @@ class MarkdownRenderable extends Renderable {
8529
8996
  tableRenderable.columnWidthMode = options.columnWidthMode;
8530
8997
  tableRenderable.columnFitter = options.columnFitter;
8531
8998
  tableRenderable.wrapMode = options.wrapMode;
8532
- tableRenderable.cellPadding = options.cellPadding;
8999
+ tableRenderable.cellPaddingX = options.cellPaddingX;
9000
+ tableRenderable.cellPaddingY = options.cellPaddingY;
8533
9001
  tableRenderable.columnGap = options.columnGap;
8534
9002
  tableRenderable.border = options.border;
8535
9003
  tableRenderable.outerBorder = options.outerBorder;
@@ -8562,6 +9030,8 @@ class MarkdownRenderable extends Renderable {
8562
9030
  columnFitter: options.columnFitter,
8563
9031
  wrapMode: options.wrapMode,
8564
9032
  cellPadding: options.cellPadding,
9033
+ cellPaddingX: options.cellPaddingX,
9034
+ cellPaddingY: options.cellPaddingY,
8565
9035
  columnGap: options.columnGap,
8566
9036
  border: options.border,
8567
9037
  outerBorder: options.outerBorder,
@@ -8622,6 +9092,16 @@ class MarkdownRenderable extends Renderable {
8622
9092
  next.renderable.marginTop = marginTop;
8623
9093
  return next;
8624
9094
  }
9095
+ if (token.type === "blockquote") {
9096
+ const renderable2 = this.createBlockquoteRenderable(token, id);
9097
+ renderable2.marginTop = marginTop;
9098
+ return { renderable: renderable2 };
9099
+ }
9100
+ if (token.type === "hr") {
9101
+ const renderable2 = this.createHorizontalRuleRenderable(id);
9102
+ renderable2.marginTop = marginTop;
9103
+ return { renderable: renderable2 };
9104
+ }
8625
9105
  const markdownRaw = this.getTopLevelBlockRaw(token);
8626
9106
  if (!markdownRaw) {
8627
9107
  return { renderable: undefined };
@@ -8647,7 +9127,8 @@ class MarkdownRenderable extends Renderable {
8647
9127
  };
8648
9128
  const custom = this._renderNode(block.token, context);
8649
9129
  if (custom) {
8650
- this.applyMargins(custom, block.marginTop, 0);
9130
+ const marginTop = typeof custom.marginTop === "number" ? Math.max(custom.marginTop, block.marginTop) : block.marginTop;
9131
+ this.applyMargins(custom, marginTop, 0);
8651
9132
  return { renderable: custom };
8652
9133
  }
8653
9134
  return next ?? this.createTopLevelDefaultRenderable(block, index);
@@ -8658,6 +9139,12 @@ class MarkdownRenderable extends Renderable {
8658
9139
  if (token.type === "code") {
8659
9140
  return this.createCodeRenderable(token, id, marginBottom);
8660
9141
  }
9142
+ if (token.type === "blockquote") {
9143
+ return this.createBlockquoteRenderable(token, id, marginBottom);
9144
+ }
9145
+ if (token.type === "hr") {
9146
+ return this.createHorizontalRuleRenderable(id, marginBottom);
9147
+ }
8661
9148
  if (token.type === "table") {
8662
9149
  return this.createTableBlock(token, id, marginBottom).renderable;
8663
9150
  }
@@ -8675,6 +9162,14 @@ class MarkdownRenderable extends Renderable {
8675
9162
  this.applyCodeBlockRenderable(state.renderable, token, marginBottom);
8676
9163
  return;
8677
9164
  }
9165
+ if (token.type === "blockquote") {
9166
+ this.applyBlockquoteRenderable(state.renderable, token, marginBottom);
9167
+ return;
9168
+ }
9169
+ if (token.type === "hr") {
9170
+ state.renderable.marginBottom = marginBottom;
9171
+ return;
9172
+ }
8678
9173
  if (token.type === "table") {
8679
9174
  const tableToken = token;
8680
9175
  const { cache, changed } = this.buildTableContentCache(tableToken, state.tableContentCache);
@@ -8708,11 +9203,11 @@ class MarkdownRenderable extends Renderable {
8708
9203
  return;
8709
9204
  }
8710
9205
  if (state.renderable instanceof CodeRenderable) {
8711
- this.applyMarkdownCodeRenderable(state.renderable, token.raw, marginBottom);
9206
+ this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(token) ?? token.raw, marginBottom);
8712
9207
  return;
8713
9208
  }
8714
9209
  state.renderable.destroyRecursively();
8715
- const markdownRenderable = this.createMarkdownCodeRenderable(token.raw, `${this.id}-block-${index}`, marginBottom);
9210
+ const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(token) ?? token.raw, `${this.id}-block-${index}`, marginBottom);
8716
9211
  this.add(markdownRenderable);
8717
9212
  state.renderable = markdownRenderable;
8718
9213
  }
@@ -8739,6 +9234,16 @@ class MarkdownRenderable extends Renderable {
8739
9234
  blockIndex++;
8740
9235
  continue;
8741
9236
  }
9237
+ if (existing && !forceTableRefresh && !this._renderNode && existing.token.type === block.token.type && this.canUpdateBlockRenderable(existing.renderable, block.token)) {
9238
+ this.updateBlockRenderable(existing, block.token, blockIndex, blockIndex < blocks.length - 1);
9239
+ existing.renderable.marginBottom = 0;
9240
+ if (existing.marginTop !== block.marginTop) {
9241
+ this.applyMargins(existing.renderable, block.marginTop, 0);
9242
+ }
9243
+ this.syncTopLevelBlockState(existing, block);
9244
+ blockIndex++;
9245
+ continue;
9246
+ }
8742
9247
  if (existing) {
8743
9248
  existing.renderable.destroyRecursively();
8744
9249
  }
@@ -8760,6 +9265,17 @@ class MarkdownRenderable extends Renderable {
8760
9265
  removed.renderable.destroyRecursively();
8761
9266
  }
8762
9267
  }
9268
+ canUpdateBlockRenderable(renderable, token) {
9269
+ if (token.type === "code")
9270
+ return renderable instanceof CodeRenderable;
9271
+ if (token.type === "table")
9272
+ return renderable instanceof TextTableRenderable;
9273
+ if (token.type === "blockquote")
9274
+ return renderable instanceof BoxRenderable;
9275
+ if (token.type === "hr")
9276
+ return renderable instanceof BoxRenderable;
9277
+ return renderable instanceof CodeRenderable;
9278
+ }
8763
9279
  updateBlocks(forceTableRefresh = false) {
8764
9280
  if (this.isDestroyed)
8765
9281
  return;
@@ -8891,6 +9407,14 @@ class MarkdownRenderable extends Renderable {
8891
9407
  this.applyCodeBlockRenderable(state.renderable, state.token, marginBottom);
8892
9408
  continue;
8893
9409
  }
9410
+ if (state.token.type === "blockquote") {
9411
+ this.applyBlockquoteRenderable(state.renderable, state.token, marginBottom);
9412
+ continue;
9413
+ }
9414
+ if (state.token.type === "hr") {
9415
+ state.renderable.marginBottom = marginBottom;
9416
+ continue;
9417
+ }
8894
9418
  if (state.token.type === "table") {
8895
9419
  const tableToken = state.token;
8896
9420
  const { cache } = this.buildTableContentCache(tableToken, state.tableContentCache, true);
@@ -8921,11 +9445,11 @@ class MarkdownRenderable extends Renderable {
8921
9445
  continue;
8922
9446
  }
8923
9447
  if (state.renderable instanceof CodeRenderable) {
8924
- this.applyMarkdownCodeRenderable(state.renderable, state.token.raw, marginBottom);
9448
+ this.applyMarkdownCodeRenderable(state.renderable, this.getTopLevelBlockRaw(state.token) ?? state.token.raw, marginBottom);
8925
9449
  continue;
8926
9450
  }
8927
9451
  state.renderable.destroyRecursively();
8928
- const markdownRenderable = this.createMarkdownCodeRenderable(state.token.raw, `${this.id}-block-${i}`, marginBottom);
9452
+ const markdownRenderable = this.createMarkdownCodeRenderable(this.getTopLevelBlockRaw(state.token) ?? state.token.raw, `${this.id}-block-${i}`, marginBottom);
8929
9453
  this.add(markdownRenderable);
8930
9454
  state.renderable = markdownRenderable;
8931
9455
  }
@@ -10988,7 +11512,7 @@ class TimeToFirstDrawRenderable extends Renderable {
10988
11512
  return Math.max(0, Math.floor(value));
10989
11513
  }
10990
11514
  }
10991
- export { DistortionEffect, VignetteEffect, CloudsEffect, FlamesEffect, CRTRollingBarEffect, RainbowTextEffect, applyScanlines, applyInvert, applyNoise, applyChromaticAberration, applyAsciiArt, applyBrightness, applyGain, applySaturation, BloomEffect, SEPIA_MATRIX, PROTANOPIA_SIM_MATRIX, DEUTERANOPIA_SIM_MATRIX, TRITANOPIA_SIM_MATRIX, ACHROMATOPSIA_MATRIX, PROTANOPIA_COMP_MATRIX, DEUTERANOPIA_COMP_MATRIX, TRITANOPIA_COMP_MATRIX, TECHNICOLOR_MATRIX, SOLARIZATION_MATRIX, SYNTHWAVE_MATRIX, GREENSCALE_MATRIX, GRAYSCALE_MATRIX, INVERT_MATRIX, Timeline, engine, createTimeline, SlotRegistry, createSlotRegistry, createCoreSlotRegistry, registerCorePlugin, resolveCoreSlot, SlotRenderable, NativeSpanFeed, FrameBufferRenderable, ASCIIFontRenderable, Generic, Box, Text, ASCIIFont, Input, Select, TabSelect, FrameBuffer, Code, ScrollBox, vstyles, VRenderable, LineNumberRenderable, DiffRenderable, defaultTextareaKeyBindings, TextareaRenderable, InputRenderableEvents, InputRenderable, TextTableRenderable, MarkdownRenderable, SliderRenderable, ScrollBarRenderable, ArrowRenderable, ScrollBoxRenderable, SelectRenderableEvents, SelectRenderable, TabSelectRenderableEvents, TabSelectRenderable, TimeToFirstDrawRenderable, exports_src2 as exports_src };
11515
+ export { DistortionEffect, VignetteEffect, CloudsEffect, FlamesEffect, CRTRollingBarEffect, RainbowTextEffect, applyScanlines, applyInvert, applyNoise, applyChromaticAberration, applyAsciiArt, applyBrightness, applyGain, applySaturation, BloomEffect, SEPIA_MATRIX, PROTANOPIA_SIM_MATRIX, DEUTERANOPIA_SIM_MATRIX, TRITANOPIA_SIM_MATRIX, ACHROMATOPSIA_MATRIX, PROTANOPIA_COMP_MATRIX, DEUTERANOPIA_COMP_MATRIX, TRITANOPIA_COMP_MATRIX, TECHNICOLOR_MATRIX, SOLARIZATION_MATRIX, SYNTHWAVE_MATRIX, GREENSCALE_MATRIX, GRAYSCALE_MATRIX, INVERT_MATRIX, Timeline, engine, createTimeline, SlotRegistry, createSlotRegistry, createCoreSlotRegistry, registerCorePlugin, resolveCoreSlot, SlotRenderable, NativeSpanFeed, Audio, setupAudio, FrameBufferRenderable, ASCIIFontRenderable, Generic, Box, Text, ASCIIFont, Input, Select, TabSelect, FrameBuffer, Code, ScrollBox, vstyles, VRenderable, LineNumberRenderable, DiffRenderable, defaultTextareaKeyBindings, TextareaRenderable, InputRenderableEvents, InputRenderable, TextTableRenderable, MarkdownRenderable, SliderRenderable, ScrollBarRenderable, ArrowRenderable, ScrollBoxRenderable, SelectRenderableEvents, SelectRenderable, TabSelectRenderableEvents, TabSelectRenderable, TimeToFirstDrawRenderable, exports_src2 as exports_src };
10992
11516
 
10993
- //# debugId=4A8BA0B5BE8B6F0464756E2164756E21
10994
- //# sourceMappingURL=index-3hyr3wkd.js.map
11517
+ //# debugId=38C52BEFC4FA5FFE64756E2164756E21
11518
+ //# sourceMappingURL=index-tx8a4862.js.map