diff --git a/.gitattributes b/.gitattributes index 070850ea4a9..cc784984976 100644 --- a/.gitattributes +++ b/.gitattributes @@ -40,6 +40,7 @@ # these carry real CR and CRLF bytes as the terminal emitted them, and line-ending # normalisation on a Windows checkout would rewrite the evidence the fixture exists to be. /src/main/runtime/__fixtures__/*.txt -text +/src/main/daemon/__fixtures__/pty-transcripts/*.txt -text # Generated runtime English subset: compared byte-for-byte by # verify:localization-runtime-catalog, so a CRLF checkout would fail the gate. /src/renderer/src/i18n/en-runtime-required.json linguist-generated=true text eol=lf diff --git a/config/patches/@xterm__addon-serialize@0.15.0-beta.300.patch b/config/patches/@xterm__addon-serialize@0.15.0-beta.300.patch index 1e2c857f931..c20f2b2864b 100644 --- a/config/patches/@xterm__addon-serialize@0.15.0-beta.300.patch +++ b/config/patches/@xterm__addon-serialize@0.15.0-beta.300.patch @@ -1,23 +1,23 @@ diff --git a/lib/addon-serialize.js b/lib/addon-serialize.js -index d669293d06d801ef472d5c2454ce86876e5c321f..b4f77e4976dbe5179d93a44ef919730a828d3331 100644 +index d669293d06d801ef472d5c2454ce86876e5c321f..717f05510e4da07f8acb81097ca1bcee90aac472 100644 --- a/lib/addon-serialize.js +++ b/lib/addon-serialize.js @@ -1,2 +1,2 @@ -!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=f;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function f(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,f=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,f=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(f(i,n)>8));if(of(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=f(i,u.relativeLuminance(o>>8));if(af(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t,e,r){return Math.max(e,Math.min(t,r))}class n{constructor(t){this._buffer=t}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,o=t.end.y,l=t.start.x,a=t.end.x;this._beforeSerialize(o-n,n,o);for(let e=n;e<=o;e++){const n=this._buffer.getLine(e);if(n){const o=e===t.start.y?l:0,u=e===t.end.y?a:n.length;for(let t=o;t0&&!l(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=e.getCell(e.length-1,this._thisRowLastChar),n=e.getCell(e.length-2,this._thisRowLastSecondChar),o=s.getCell(0,this._nextRowFirstChar),a=o.getWidth()>1;let u=!1;(o.getChars()&&a?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||0===i.getWidth())&&l(i,o)&&(u=!0),a&&(n.getChars()||0===n.getWidth())&&l(i,o)&&l(n,o)&&(u=!0)),u||(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0&&(r+="",r+=`[${e.length-this._nullCellCount}C`,r+=`[${this._nullCellCount}X`,r+=`[${e.length-this._nullCellCount}D`,r+=""),this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0)}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(h(t,e))return r;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){if(t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27),t.isBold()!==e.isBold()&&r.push(t.isBold()?1:22),a(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isDim()!==e.isDim()&&r.push(t.isDim()?2:22),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,this._cursorStyle);if(i?!l(this._cursorStyle,t):n.length>0){this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${n.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}i?this._nullCellCount+=t.getWidth():(this._nullCellCount>0&&(l(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._currentRow+=t.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth())}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(e=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let t=0;t{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,n=void 0===r?s:i(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-n,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new c(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new f(r,t,e),n=e.onlySelection??!1,o=e.range;if(o)return s.serialize({start:{x:o.startCol,y:(o.startLine,o.startLine)},end:{x:t.cols,y:(o.endLine,o.endLine)}});if(!n){const n=r.length,o=e.scrollback,l=void 0===o?n:i(o+t.rows,0,n);return s.serialize({start:{x:0,y:n-l},end:{x:t.cols,y:n-1}})}const l=this._terminal?.getSelectionPosition();return void 0!==l?s.serialize({start:{x:l.start.x,y:l.start.y},end:{x:l.end.x,y:l.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class f extends n{constructor(t,r,s){super(t),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(h(t,e))return;const s=!o(t,e),i=!l(t,e),n=!u(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=f})(),s})()); -+!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=f;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function f(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,f=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=f(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,f=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=f+Math.round((u-f)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(f(i,n)>8));if(of(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=f(i,u.relativeLuminance(o>>8));if(af(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t){return t.extended?.urlId??0}function n(t,e){if(!e)return"";const r=t._core?._oscLinkService?.getLinkData(e);return r?`]8;${void 0===r.id?"":`id=${r.id}`};${r.uri}\\`:""}function o(t,e,r){return Math.max(e,Math.min(t,r))}class l{constructor(t){this._buffer=t}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,o=t.end.y,l=t.start.x,a=t.end.x;this._beforeSerialize(o-n,n,o);for(let e=n;e<=o;e++){const n=this._buffer.getLine(e);if(n){const o=e===t.start.y?l:0,u=e===t.end.y?a:n.length;for(let t=o;t0&&!u(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=e.getCell(e.length-1,this._thisRowLastChar),n=e.getCell(e.length-2,this._thisRowLastSecondChar),o=s.getCell(0,this._nextRowFirstChar),l=o.getWidth()>1;let a=!1;if(o.getChars()&&(l?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||0===i.getWidth())&&u(i,o)&&(a=!0),l&&(n.getChars()||0===n.getWidth())&&u(i,o)&&u(n,o)&&(a=!0)),!a){if(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0){r+="";const t=e.length-this._nullCellCount;t>0&&(r+=`[${t}C`),r+=`[${this._nullCellCount}X`,t>0&&(r+=`[${t}D`),r+=""}this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0}}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(f(t,e))return r;const s=!a(t,e),i=!u(t,e),n=!c(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27);const s=t.isBold()!==e.isBold(),i=t.isDim()!==e.isDim();if(s||i){const e=s&&!t.isBold()||i&&!t.isDim();e&&r.push(22),t.isBold()&&(s||e)&&r.push(1),t.isDim()&&(i||e)&&r.push(2)}if(h(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_setOscLink(t){if(t===this._activeOscLinkId)return"";let e=this._activeOscLinkId?"]8;;\\":"";this._activeOscLinkId=0;const r=n(this._terminal,t);return r&&(this._activeOscLinkId=t,e+=r),e}_nextCell(t,e,r,s){if(0===t.getWidth())return;const n=""===t.getChars(),o=n&&t.isInverse()?this._buffer.getLine(r+1):void 0,l=o?.getCell(0,this._nextRowFirstChar),a=s===this._terminal.cols-1&&o?.isWrapped&&(l?.getWidth()??0)>1&&!!l&&f(t,l),h=n&&!!t.isInverse()&&!a,c=this._diffStyle(t,this._cursorStyle);if(n?h?c.length>0:!u(this._cursorStyle,t):c.length>0){this._nullCellCount>0&&(u(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${c.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}if(n&&!h)this._nullCellCount+=t.getWidth();else{if(this._nullCellCount>0&&(u(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._currentRow+=this._setOscLink(i(t)),h){const e=!!t.isUnderline()||!!t.isStrikethrough()||!!t.isOverline();if(e&&(this._currentRow+=""),this._currentRow+=" ".repeat(t.getWidth()),e){const e=this._diffStyle(t,this._defaultCell);this._currentRow+=`[${e.join(";")}m`}}else this._currentRow+=t.getChars();this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth()}}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(e=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let t=0;t{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,i=void 0===r?s:o(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-i,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new _(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new d(r,t,e),i=e.onlySelection??!1,n=e.range;if(n)return s.serialize({start:{x:n.startCol,y:(n.startLine,n.startLine)},end:{x:t.cols,y:(n.endLine,n.endLine)}});if(!i){const i=r.length,n=e.scrollback,l=void 0===n?i:o(n+t.rows,0,i);return s.serialize({start:{x:0,y:i-l},end:{x:t.cols,y:i-1}})}const l=this._terminal?.getSelectionPosition();return void 0!==l?s.serialize({start:{x:l.start.x,y:l.start.y},end:{x:l.end.x,y:l.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e+=function(t){const e=t._core?._inputHandler?._curAttrData;return e?n(t,i(e)):""}(this._terminal),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class d extends l{constructor(t,r,s){super(t),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(f(t,e))return;const s=!a(t,e),i=!u(t,e),n=!c(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"
":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=d})(),s})()); ++!function(t,e){"object"==typeof exports&&"object"==typeof module?module.exports=e():"function"==typeof define&&define.amd?define([],e):"object"==typeof exports?exports.SerializeAddon=e():t.SerializeAddon=e()}(globalThis,()=>(()=>{"use strict";var t={992(t,e,r){Object.defineProperty(e,"__esModule",{value:!0}),e.DEFAULT_ANSI_COLORS=void 0;const s=r(993);e.DEFAULT_ANSI_COLORS=Object.freeze((()=>{const t=[s.css.toColor("#2e3436"),s.css.toColor("#cc0000"),s.css.toColor("#4e9a06"),s.css.toColor("#c4a000"),s.css.toColor("#3465a4"),s.css.toColor("#75507b"),s.css.toColor("#06989a"),s.css.toColor("#d3d7cf"),s.css.toColor("#555753"),s.css.toColor("#ef2929"),s.css.toColor("#8ae234"),s.css.toColor("#fce94f"),s.css.toColor("#729fcf"),s.css.toColor("#ad7fa8"),s.css.toColor("#34e2e2"),s.css.toColor("#eeeeec")],e=[0,95,135,175,215,255];for(let r=0;r<216;r++){const i=e[r/36%6|0],n=e[r/6%6|0],o=e[r%6];t.push({css:s.channels.toCss(i,n,o),rgba:s.channels.toRgba(i,n,o)})}for(let e=0;e<24;e++){const r=8+10*e;t.push({css:s.channels.toCss(r,r,r),rgba:s.channels.toRgba(r,r,r)})}return t})())},993(t,e){Object.defineProperty(e,"__esModule",{value:!0}),e.rgba=e.rgb=e.css=e.color=e.channels=e.NULL_COLOR=void 0,e.toPaddedHex=c,e.contrastRatio=_;let r=0,s=0,i=0,n=0;var o,l,a,u,h;function c(t){const e=t.toString(16);return e.length<2?"0"+e:e}function _(t,e){return t>>0},t.toColor=function(e,r,s,i){return{css:t.toCss(e,r,s,i),rgba:t.toRgba(e,r,s,i)}}}(o||(e.channels=o={})),function(t){function e(t,e){return n=Math.round(255*e),[r,s,i]=h.toChannels(t.rgba),{css:o.toCss(r,s,i,n),rgba:o.toRgba(r,s,i,n)}}t.blend=function(t,e){if(n=(255&e.rgba)/255,1===n)return{css:e.css,rgba:e.rgba};const l=e.rgba>>24&255,a=e.rgba>>16&255,u=e.rgba>>8&255,h=t.rgba>>24&255,c=t.rgba>>16&255,_=t.rgba>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=_+Math.round((u-_)*n),{css:o.toCss(r,s,i),rgba:o.toRgba(r,s,i)}},t.isOpaque=function(t){return!(255&~t.rgba)},t.ensureContrastRatio=function(t,e,r){const s=h.ensureContrastRatio(t.rgba,e.rgba,r);if(s)return o.toColor(s>>24&255,s>>16&255,s>>8&255)},t.opaque=function(t){const e=(255|t.rgba)>>>0;return[r,s,i]=h.toChannels(e),{css:o.toCss(r,s,i),rgba:e}},t.opacity=e,t.multiplyOpacity=function(t,r){return n=255&t.rgba,e(t,n*r/255)},t.toColorRGB=function(t){return[t.rgba>>24&255,t.rgba>>16&255,t.rgba>>8&255]}}(l||(e.color=l={})),function(t){let e,l;try{const t=document.createElement("canvas");t.width=1,t.height=1;const r=t.getContext("2d",{willReadFrequently:!0});r&&(e=r,e.globalCompositeOperation="copy",l=e.createLinearGradient(0,0,1,1))}catch{}t.toColor=function(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),o.toColor(r,s,i);case 5:return r=parseInt(t.slice(1,2).repeat(2),16),s=parseInt(t.slice(2,3).repeat(2),16),i=parseInt(t.slice(3,4).repeat(2),16),n=parseInt(t.slice(4,5).repeat(2),16),o.toColor(r,s,i,n);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}const a=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(a)return r=parseInt(a[1],10),s=parseInt(a[2],10),i=parseInt(a[3],10),n=Math.round(255*(void 0===a[5]?1:parseFloat(a[5]))),o.toColor(r,s,i,n);if("transparent"===t)return{css:"transparent",rgba:0};if(!e||!l)throw new Error("css.toColor: Unsupported css format");if(e.fillStyle=l,e.fillStyle=t,"string"!=typeof e.fillStyle)throw new Error("css.toColor: Unsupported css format");if(e.fillRect(0,0,1,1),[r,s,i,n]=e.getImageData(0,0,1,1).data,255!==n)throw new Error("css.toColor: Unsupported css format");return{rgba:o.toRgba(r,s,i,n),css:t}}}(a||(e.css=a={})),function(t){function e(t,e,r){const s=t/255,i=e/255,n=r/255;return.2126*(s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4))+.7152*(i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4))+.0722*(n<=.03928?n/12.92:Math.pow((n+.055)/1.055,2.4))}t.relativeLuminance=function(t){return e(t>>16&255,t>>8&255,255&t)},t.relativeLuminance2=e}(u||(e.rgb=u={})),function(t){function e(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=_(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h0||l>0||a>0);)o-=Math.max(0,Math.ceil(.1*o)),l-=Math.max(0,Math.ceil(.1*l)),a-=Math.max(0,Math.ceil(.1*a)),h=_(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));return(o<<24|l<<16|a<<8|255)>>>0}function l(t,e,r){const s=t>>24&255,i=t>>16&255,n=t>>8&255;let o=e>>24&255,l=e>>16&255,a=e>>8&255,h=_(u.relativeLuminance2(o,l,a),u.relativeLuminance2(s,i,n));for(;h>>0}t.blend=function(t,e){if(n=(255&e)/255,1===n)return e;const l=e>>24&255,a=e>>16&255,u=e>>8&255,h=t>>24&255,c=t>>16&255,_=t>>8&255;return r=h+Math.round((l-h)*n),s=c+Math.round((a-c)*n),i=_+Math.round((u-_)*n),o.toRgba(r,s,i)},t.ensureContrastRatio=function(t,r,s){const i=u.relativeLuminance(t>>8),n=u.relativeLuminance(r>>8);if(_(i,n)>8));if(o_(i,u.relativeLuminance(e>>8))?n:e}return n}const o=l(t,r,s),a=_(i,u.relativeLuminance(o>>8));if(a_(i,u.relativeLuminance(n>>8))?o:n}return o}},t.reduceLuminance=e,t.increaseLuminance=l,t.toChannels=function(t){return[t>>24&255,t>>16&255,t>>8&255,255&t]}}(h||(e.rgba=h={}))}},e={};function r(s){var i=e[s];if(void 0!==i)return i.exports;var n=e[s]={exports:{}};return t[s](n,n.exports,r),n.exports}var s={};return(()=>{var t=s;Object.defineProperty(t,"__esModule",{value:!0}),t.HTMLSerializeHandler=t.SerializeAddon=void 0;const e=r(992);function i(t){return t.extended?.urlId??0}function n(t,e){if(!e)return"";const r=t._core?._oscLinkService?.getLinkData(e);return r?`]8;${void 0===r.id?"":`id=${r.id}`};${r.uri}\\`:""}function o(t,e){return Math.min(t.length,e)}function l(t,e,r,s){return e===r-1&&t.length>r&&s.getWidth()>1}function a(t){return t.content=4194304,t}function u(t,e,r){return Math.max(e,Math.min(t,r))}class h{constructor(t,e){this._buffer=t,this._cols=e}serialize(t,e){const r=this._buffer.getNullCell(),s=this._buffer.getNullCell();let i=r;const n=t.start.y,u=t.end.y,h=t.start.x,c=t.end.x;this._beforeSerialize(u-n,n,u);for(let e=n;e<=u;e++){const n=this._buffer.getLine(e);if(n){const u=e===t.start.y?h:0,_=e===t.end.y?c:o(n,this._cols);for(let t=u;t<_;t++){let o=n.getCell(t,i===r?s:r);o?(l(n,t,this._cols,o)&&(o=a(o)),this._nextCell(o,i,e,t),i=o):console.warn(`Can't get cell at row=${e}, col=${t}`)}}this._rowEnd(e,e===u)}return this._afterSerialize(),this._serializeString(e)}_nextCell(t,e,r,s){}_rowEnd(t,e){}_beforeSerialize(t,e,r){}_afterSerialize(){}_serializeString(t){return""}}function c(t,e){return t.getFgColorMode()===e.getFgColorMode()&&t.getFgColor()===e.getFgColor()}function _(t,e){return t.getBgColorMode()===e.getBgColorMode()&&t.getBgColor()===e.getBgColor()}function f(t,e){if(!t.isUnderline()&&!e.isUnderline())return!0;if(t.getUnderlineStyle()!==e.getUnderlineStyle())return!1;const r=t.isUnderlineColorDefault(),s=e.isUnderlineColorDefault();return!(!r||!s)||r===s&&t.getUnderlineColor()===e.getUnderlineColor()&&t.getUnderlineColorMode()===e.getUnderlineColorMode()}function C(t,e){return t.isInverse()===e.isInverse()&&t.isBold()===e.isBold()&&t.isUnderline()===e.isUnderline()&&f(t,e)&&t.isOverline()===e.isOverline()&&t.isBlink()===e.isBlink()&&t.isInvisible()===e.isInvisible()&&t.isItalic()===e.isItalic()&&t.isDim()===e.isDim()&&t.isStrikethrough()===e.isStrikethrough()}function d(t,e){const r=t;return"function"==typeof r.attributesEquals?r.attributesEquals(e):c(t,e)&&_(t,e)&&C(t,e)}class g extends h{constructor(t,e){super(t,e.cols),this._terminal=e,this._rowIndex=0,this._allRows=new Array,this._allRowSeparators=new Array,this._currentRow="",this._nullCellCount=0,this._cursorStyle=this._buffer.getNullCell(),this._cursorStyleRow=0,this._cursorStyleCol=0,this._backgroundCell=this._buffer.getNullCell(),this._defaultCell=this._buffer.getNullCell(),this._firstRow=0,this._lastCursorRow=0,this._lastCursorCol=0,this._lastContentCursorRow=0,this._lastContentCursorCol=0,this._activeOscLinkId=0,this._lastBackgroundCursorRow=-1,this._lastBackgroundCursorCol=0,this._thisRowLastChar=this._buffer.getNullCell(),this._thisRowLastSecondChar=this._buffer.getNullCell(),this._nextRowFirstChar=this._buffer.getNullCell()}_beforeSerialize(t,e,r){this._allRows=new Array(t),this._lastContentCursorRow=e,this._lastCursorRow=e,this._firstRow=e}_rowEnd(t,e){this._nullCellCount>0&&!_(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`[${this._nullCellCount}X`,this._lastBackgroundCursorRow=this._lastCursorRow,this._lastBackgroundCursorCol=this._lastCursorCol);let r="";if(!e){t-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);const e=this._buffer.getLine(t),s=this._buffer.getLine(t+1);if(s.isWrapped){r="";const i=o(e,this._terminal.cols);let n=e.getCell(i-1,this._thisRowLastChar);l(e,i-1,this._terminal.cols,n)&&(n=a(n));const u=e.getCell(i-2,this._thisRowLastSecondChar),h=s.getCell(0,this._nextRowFirstChar),c=h.getWidth()>1;let f=!1;if(h.getChars()&&(c?this._nullCellCount<=1:this._nullCellCount<=0)&&((n.getChars()||0===n.getWidth())&&_(n,h)&&(f=!0),c&&(u.getChars()||0===u.getWidth())&&_(n,h)&&_(u,h)&&(f=!0)),!f){if(r="-".repeat(this._nullCellCount+1),r+="",this._nullCellCount>0){r+="";const t=i-this._nullCellCount;t>0&&(r+=`[${t}C`),r+=`[${this._nullCellCount}X`,t>0&&(r+=`[${t}D`),r+=""}this._lastContentCursorRow=t+1,this._lastContentCursorCol=0,this._lastCursorRow=t+1,this._lastCursorCol=0}}else r="\r\n",this._lastCursorRow=t+1,this._lastCursorCol=0}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(t,e){const r=[];if(d(t,e))return r;const s=!c(t,e),i=!_(t,e),n=!C(t,e);if(s||i||n)if(t.isAttributeDefault())e.isAttributeDefault()||r.push(0);else{if(s){const e=t.getFgColor();t.isFgRGB()?r.push(38,2,e>>>16&255,e>>>8&255,255&e):t.isFgPalette()?e>=16?r.push(38,5,e):r.push(8&e?90+(7&e):30+(7&e)):r.push(39)}if(i){const e=t.getBgColor();t.isBgRGB()?r.push(48,2,e>>>16&255,e>>>8&255,255&e):t.isBgPalette()?e>=16?r.push(48,5,e):r.push(8&e?100+(7&e):40+(7&e)):r.push(49)}if(n){t.isInverse()!==e.isInverse()&&r.push(t.isInverse()?7:27);const s=t.isBold()!==e.isBold(),i=t.isDim()!==e.isDim();if(s||i){const e=s&&!t.isBold()||i&&!t.isDim();e&&r.push(22),t.isBold()&&(s||e)&&r.push(1),t.isDim()&&(i||e)&&r.push(2)}if(f(t,e))t.isUnderline()!==e.isUnderline()&&r.push(t.isUnderline()?4:24);else{const e=t.getUnderlineStyle();if(0===e)r.push(24);else if(1===e&&t.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+e),!t.isUnderlineColorDefault()){const e=t.getUnderlineColor();t.isUnderlineColorRGB()?r.push("58:2::"+(e>>>16&255)+":"+(e>>>8&255)+":"+(255&e)):r.push("58:5:"+e)}}t.isOverline()!==e.isOverline()&&r.push(t.isOverline()?53:55),t.isBlink()!==e.isBlink()&&r.push(t.isBlink()?5:25),t.isInvisible()!==e.isInvisible()&&r.push(t.isInvisible()?8:28),t.isItalic()!==e.isItalic()&&r.push(t.isItalic()?3:23),t.isStrikethrough()!==e.isStrikethrough()&&r.push(t.isStrikethrough()?9:29)}}return r}_setOscLink(t){if(t===this._activeOscLinkId)return"";let e=this._activeOscLinkId?"]8;;\\":"";this._activeOscLinkId=0;const r=n(this._terminal,t);return r&&(this._activeOscLinkId=t,e+=r),e}_nextCell(t,e,r,s){if(0===t.getWidth())return;const n=""===t.getChars(),o=n&&t.isInverse()?this._buffer.getLine(r+1):void 0,l=o?.getCell(0,this._nextRowFirstChar),a=s===this._terminal.cols-1&&o?.isWrapped&&(l?.getWidth()??0)>1&&!!l&&d(t,l),u=n&&!!t.isInverse()&&!a,h=this._diffStyle(t,this._cursorStyle);if(n?u?h.length>0:!_(this._cursorStyle,t):h.length>0){this._nullCellCount>0&&(_(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s,this._currentRow+=`[${h.join(";")}m`;const t=this._buffer.getLine(r);void 0!==t&&(t.getCell(s,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=s)}if(n&&!u)this._nullCellCount+=t.getWidth();else{if(this._nullCellCount>0&&(_(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`[${this._nullCellCount}X`),this._currentRow+=`[${this._nullCellCount}C`,this._nullCellCount=0),this._currentRow+=this._setOscLink(i(t)),u){const e=!!t.isUnderline()||!!t.isStrikethrough()||!!t.isOverline();if(e&&(this._currentRow+=""),this._currentRow+=" ".repeat(t.getWidth()),e){const e=this._diffStyle(t,this._defaultCell);this._currentRow+=`[${e.join(";")}m`}}else this._currentRow+=t.getChars();this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=s+t.getWidth()}}_serializeString(t){let e=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(this._lastBackgroundCursorRow>this._lastContentCursorRow&&this._buffer.cursorX{t>0?r+=`[${t}C`:t<0&&(r+=`[${-t}D`)};(t!==this._lastCursorRow||e!==this._lastCursorCol)&&((s=t-this._lastCursorRow)>0?r+=`[${s}B`:s<0&&(r+=`[${-s}A`),i(e-this._lastCursorCol))}var s;const i=this._terminal._core._inputHandler._curAttrData,n=this._diffStyle(i,this._cursorStyle);return n.length>0&&(r+=`[${n.join(";")}m`),r}}t.SerializeAddon=class{activate(t){this._terminal=t}_serializeBufferByScrollback(t,e,r){const s=e.length,i=void 0===r?s:u(r+t.rows,0,s);return this._serializeBufferByRange(t,e,{start:s-i,end:s-1},!1)}_serializeBufferByRange(t,e,r,s){return new g(e,t).serialize({start:{x:0,y:"number"==typeof r.start?r.start:r.start.line},end:{x:t.cols,y:"number"==typeof r.end?r.end:r.end.line}},s)}_serializeBufferAsHTML(t,e){const r=t.buffer.active,s=new p(r,t,e),i=e.onlySelection??!1,n=e.range;if(n)return s.serialize({start:{x:n.startCol,y:(n.startLine,n.startLine)},end:{x:t.cols,y:(n.endLine,n.endLine)}});if(!i){const i=r.length,n=e.scrollback,o=void 0===n?i:u(n+t.rows,0,i);return s.serialize({start:{x:0,y:i-o},end:{x:t.cols,y:i-1}})}const o=this._terminal?.getSelectionPosition();return void 0!==o?s.serialize({start:{x:o.start.x,y:o.start.y},end:{x:o.end.x,y:o.end.y}}):""}_serializeScrollRegion(t){const e=t._core.buffer,r=e.scrollTop,s=e.scrollBottom;return 0!==r||s!==t.rows-1?`[${r+1};${s+1}r`:""}_serializeModes(t){let e="";const r=t.modes;if(r.applicationCursorKeysMode&&(e+="[?1h"),r.applicationKeypadMode&&(e+="[?66h"),r.bracketedPasteMode&&(e+="[?2004h"),r.insertMode&&(e+=""),r.originMode&&(e+="[?6h"),r.reverseWraparoundMode&&(e+="[?45h"),r.sendFocusMode&&(e+="[?1004h"),!1===r.wraparoundMode&&(e+="[?7l"),"none"!==r.mouseTrackingMode)switch(r.mouseTrackingMode){case"x10":e+="[?9h";break;case"vt200":e+="[?1000h";break;case"drag":e+="[?1002h";break;case"any":e+="[?1003h"}return r.showCursor||(e+="[?25l"),e}serialize(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=t?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,t.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,t?.scrollback);return t?.excludeAltBuffer||"alternate"!==this._terminal.buffer.active.type||(e+=`[?1049h${this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0)}`),t?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e+=function(t){const e=t._core?._inputHandler?._curAttrData;return e?n(t,i(e)):""}(this._terminal),e}serializeAsHTML(t){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,t??{})}dispose(){}};class p extends h{constructor(t,r,s){super(t,r.cols),this._terminal=r,this._options=s,this._currentRow="",this._htmlContent="",r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=e.DEFAULT_ANSI_COLORS}_beforeSerialize(t,e,r){this._htmlContent+="\x3c!--StartFragment--\x3e
";let s="#000000",i="#ffffff";this._options.includeGlobalBackground&&(s=this._terminal.options.theme?.foreground??"#ffffff",i=this._terminal.options.theme?.background??"#000000");const n=[];n.push("color: "+s+";"),n.push("background-color: "+i+";"),n.push("font-family: "+this._terminal.options.fontFamily+";"),n.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
\x3c!--EndFragment--\x3e"}_rowEnd(t,e){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(t,e){const r=e?t.getFgColor():t.getBgColor();return(e?t.isFgRGB():t.isBgRGB())?"#"+[r>>16&255,r>>8&255,255&r].map(t=>t.toString(16).padStart(2,"0")).join(""):(e?t.isFgPalette():t.isBgPalette())?this._ansiColors[r].css:void 0}_getUnderlineColor(t){if(t.isUnderlineColorDefault())return;const e=t.getUnderlineColor();return t.isUnderlineColorRGB()?"#"+[e>>16&255,e>>8&255,255&e].map(t=>t.toString(16).padStart(2,"0")).join(""):this._ansiColors[e].css}_getUnderlineStyle(t){switch(t.getUnderlineStyle()){case 1:default:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed"}}_diffStyle(t,e){const r=[];if(d(t,e))return;const s=!c(t,e),i=!_(t,e),n=!C(t,e);if(s||i||n){const e=this._getHexColor(t,!0);e&&r.push("color: "+e+";");const s=this._getHexColor(t,!1);s&&r.push("background-color: "+s+";"),t.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),t.isBold()&&r.push("font-weight: bold;");const i=[];if(t.isUnderline()&&i.push(this._getUnderlineStyle(t)),t.isOverline()&&i.push("overline"),t.isStrikethrough()&&i.push("line-through"),t.isBlink()&&i.push("blink"),i.length>0&&r.push("text-decoration: "+i.join(" ")+";"),t.isUnderline()){const e=this._getUnderlineColor(t);e&&r.push("text-decoration-color: "+e+";")}return t.isInvisible()&&r.push("visibility: hidden;"),t.isItalic()&&r.push("font-style: italic;"),t.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(t,e,r,s){if(0===t.getWidth())return;const i=""===t.getChars(),n=this._diffStyle(t,e);n&&(this._currentRow+=0===n.length?"
":""),this._currentRow+=i?" ":function(t){switch(t){case"&":return"&";case"<":return"<"}return t}(t.getChars())}_serializeString(){return this._htmlContent}}t.HTMLSerializeHandler=p})(),s})()); //# sourceMappingURL=addon-serialize.js.map \ No newline at end of file diff --git a/lib/addon-serialize.js.map b/lib/addon-serialize.js.map -index bac96176091146ab7eb07d1d7b280286e047278c..54a78516a87fe7fe3ea2c61bc6d778b1f29acc6c 100644 +index bac96176091146ab7eb07d1d7b280286e047278c..5a26191e7b17a6d7ae2b380b7eb7721a789fccb6 100644 --- a/lib/addon-serialize.js.map +++ b/lib/addon-serialize.js.map @@ -1 +1 @@ -{"version":3,"file":"addon-serialize.js","mappings":"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","sources":["webpack://SerializeAddon/webpack/universalModuleDefinition","webpack://SerializeAddon/../src/browser/Types.ts","webpack://SerializeAddon/../src/common/Color.ts","webpack://SerializeAddon/webpack/bootstrap","webpack://SerializeAddon/./src/SerializeAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SerializeAddon\"] = factory();\n\telse\n\t\troot[\"SerializeAddon\"] = factory();\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: line.length;\n for (let col = startLineColumn; col < endLineColumn; col++) {\n const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!;\n const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n rowSeparator += `\\u001b[${currentLine.length - this._nullCellCount}C`;\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n rowSeparator += `\\u001b[${currentLine.length - this._nullCellCount}D`;\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n if (cell.isBold() !== oldCell.isBold()) { sgrSeq.push(cell.isBold() ? 1 : 22); }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n if (cell.isDim() !== oldCell.isDim()) { sgrSeq.push(cell.isDim() ? 2 : 22); }\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n // the empty cell style is only assumed to be changed when background changed, because\n // foreground is always 0.\n const styleChanged = isEmptyCell ? !equalBg(this._cursorStyle, cell) : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n this._currentRow += cell.getChars();\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","Color_1","__webpack_require__","DEFAULT_ANSI_COLORS","Object","freeze","colors","css","toColor","v","i","r","g","b","push","channels","toCss","rgba","toRgba","c","$r","$g","$b","$a","color","rgb","toPaddedHex","s","toString","length","contrastRatio","l1","l2","NULL_COLOR","a","undefined","color_1","opacity","Math","round","toChannels","blend","bg","fg","fgR","fgG","fgB","bgR","bgG","bgB","isOpaque","ensureContrastRatio","ratio","result","opaque","rgbaColor","multiplyOpacity","factor","toColorRGB","css_1","$ctx","$litmusColor","canvas","document","createElement","width","height","ctx","getContext","willReadFrequently","globalCompositeOperation","createLinearGradient","match","parseInt","slice","repeat","rgbaMatch","parseFloat","Error","fillStyle","fillRect","getImageData","data","rgb_1","relativeLuminance2","rs","gs","bs","pow","relativeLuminance","reduceLuminance","bgRgba","fgRgba","cr","max","ceil","increaseLuminance","min","bgL","fgL","resultA","resultARatio","resultB","value","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","Types_1","constrain","low","high","BaseSerializeHandler","constructor","_buffer","serialize","range","excludeFinalCursorPosition","cell1","this","getNullCell","cell2","oldCell","startRow","start","y","endRow","end","startColumn","x","endColumn","_beforeSerialize","row","line","getLine","startLineColumn","endLineColumn","col","getCell","_nextCell","console","warn","_rowEnd","_afterSerialize","_serializeString","cell","isLastRow","rows","equalFg","getFgColorMode","getFgColor","equalBg","getBgColorMode","getBgColor","equalUnderline","isUnderline","getUnderlineStyle","cell1Default","isUnderlineColorDefault","cell2Default","getUnderlineColor","getUnderlineColorMode","equalFlags","isInverse","isBold","isOverline","isBlink","isInvisible","isItalic","isDim","isStrikethrough","attributesEquals","cell1AsBufferCell","StringSerializeHandler","buffer","_terminal","super","_rowIndex","_allRows","Array","_allRowSeparators","_currentRow","_nullCellCount","_cursorStyle","_cursorStyleRow","_cursorStyleCol","_backgroundCell","_firstRow","_lastCursorRow","_lastCursorCol","_lastContentCursorRow","_lastContentCursorCol","_thisRowLastChar","_thisRowLastSecondChar","_nextRowFirstChar","rowSeparator","currentLine","nextLine","isWrapped","thisRowLastChar","thisRowLastSecondChar","nextRowFirstChar","isNextRowFirstCharDoubleWidth","getWidth","isValid","getChars","_diffStyle","sgrSeq","fgChanged","bgChanged","flagsChanged","isAttributeDefault","isFgRGB","isFgPalette","isBgRGB","isBgPalette","style","isUnderlineColorRGB","isEmptyCell","join","rowEnd","content","realCursorRow","baseY","cursorY","realCursorCol","cursorX","moveRight","offset","curAttrData","_core","_inputHandler","_curAttrData","activate","terminal","_serializeBufferByScrollback","scrollback","maxRows","correctRows","_serializeBufferByRange","cols","_serializeBufferAsHTML","options","active","handler","HTMLSerializeHandler","onlySelection","startCol","startLine","endLine","selection","getSelectionPosition","_serializeScrollRegion","scrollTop","scrollBottom","_serializeModes","modes","applicationCursorKeysMode","applicationKeypadMode","bracketedPasteMode","insertMode","originMode","reverseWraparoundMode","sendFocusMode","wraparoundMode","mouseTrackingMode","showCursor","normal","excludeAltBuffer","type","alternate","excludeModes","serializeAsHTML","dispose","_options","_htmlContent","_themeService","_ansiColors","ansi","foreground","background","includeGlobalBackground","theme","globalStyleDefinitions","fontFamily","fontSize","_getHexColor","isFg","map","padStart","_getUnderlineColor","_getUnderlineStyle","fgHexColor","bgHexColor","decorations","underlineColor","styleDefinitions","escapeHTMLChar"],"sourceRoot":""} \ No newline at end of file -+{"version":3,"file":"addon-serialize.js","mappings":"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","sources":["webpack://SerializeAddon/webpack/universalModuleDefinition","webpack://SerializeAddon/../src/browser/Types.ts","webpack://SerializeAddon/../src/common/Color.ts","webpack://SerializeAddon/webpack/bootstrap","webpack://SerializeAddon/./src/SerializeAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SerializeAddon\"] = factory();\n\telse\n\t\troot[\"SerializeAddon\"] = factory();\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\ntype OscLinkData = { id?: string; uri: string };\ntype OscLinkedCell = { extended?: { urlId?: number } };\ntype TerminalWithOscLinks = Terminal & {\n _core?: {\n _inputHandler?: { _curAttrData?: IAttributeData & OscLinkedCell };\n _oscLinkService?: { getLinkData: (linkId: number) => OscLinkData | undefined };\n };\n};\n\nfunction getOscLinkId(cell: IBufferCell | IAttributeData): number {\n return (cell as typeof cell & OscLinkedCell).extended?.urlId ?? 0;\n}\n\nfunction getOscLinkOpenSequence(terminal: Terminal, linkId: number): string {\n if (!linkId) {\n return '';\n }\n const data = (terminal as TerminalWithOscLinks)._core?._oscLinkService?.getLinkData(linkId);\n if (!data) {\n return '';\n }\n const params = data.id === undefined ? '' : `id=${data.id}`;\n return `\\u001b]8;${params};${data.uri}\\u001b\\\\`;\n}\n\nfunction getActiveOscLinkSequence(terminal: Terminal): string {\n const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData;\n return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : '';\n}\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: line.length;\n for (let col = startLineColumn; col < endLineColumn; col++) {\n const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n private _defaultCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n private _activeOscLinkId: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!;\n const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n (isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0)\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n const contentCellCount = currentLine.length - this._nullCellCount;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}C`;\n }\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}D`;\n }\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n // PATCH(orca): bold (1) and dim (2) share the single reset param 22, so\n // they must be diffed as one intensity group with the clearing 22 emitted\n // BEFORE any re-set. Upstream's independent per-flag diff could emit\n // \"1;22\" (bold set, then wiped by dim's clear โ€” \\x1b[2mA\\x1b[22m\\x1b[1mB\n // loses B's bold on round-trip) or a bare \"22\" that drops a still-set\n // bold/dim, garbling Orca's hidden-terminal snapshot restores.\n const boldChanged = cell.isBold() !== oldCell.isBold();\n const dimChanged = cell.isDim() !== oldCell.isDim();\n if (boldChanged || dimChanged) {\n const clearsIntensity = (boldChanged && !cell.isBold()) || (dimChanged && !cell.isDim());\n if (clearsIntensity) { sgrSeq.push(22); }\n if (cell.isBold() && (boldChanged || clearsIntensity)) { sgrSeq.push(1); }\n if (cell.isDim() && (dimChanged || clearsIntensity)) { sgrSeq.push(2); }\n }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n // PATCH(orca): dim handled in the intensity group above.\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n private _setOscLink(linkId: number): string {\n if (linkId === this._activeOscLinkId) {\n return '';\n }\n let sequence = this._activeOscLinkId ? '\\u001b]8;;\\u001b\\\\' : '';\n this._activeOscLinkId = 0;\n const openSequence = getOscLinkOpenSequence(this._terminal, linkId);\n if (openSequence) {\n this._activeOscLinkId = linkId;\n sequence += openSequence;\n }\n return sequence;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n const nextLine = isEmptyCell && cell.isInverse() ? this._buffer.getLine(row + 1) : undefined;\n const nextRowFirstCell = nextLine?.getCell(0, this._nextRowFirstChar);\n // A pending wide glyph recreates its own final-column padding during replay.\n const isWideWrapPadding = col === this._terminal.cols - 1 &&\n nextLine?.isWrapped &&\n (nextRowFirstCell?.getWidth() ?? 0) > 1 &&\n !!nextRowFirstCell && attributesEquals(cell, nextRowFirstCell);\n // Cursor movement cannot reproduce an inverse cell's visible background.\n const materializeEmptyCell = isEmptyCell && !!cell.isInverse() && !isWideWrapPadding;\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n const styleChanged = isEmptyCell\n ? materializeEmptyCell ? sgrSeq.length > 0 : !equalBg(this._cursorStyle, cell)\n : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell && !materializeEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n // PATCH(orca): styling alone leaves restored OSC 8 links looking live but unclickable.\n this._currentRow += this._setOscLink(getOscLinkId(cell));\n\n if (materializeEmptyCell) {\n const hasDecoration = !!cell.isUnderline() || !!cell.isStrikethrough() || !!cell.isOverline();\n if (hasDecoration) {\n this._currentRow += '\\u001b[24;29;55m';\n }\n this._currentRow += ' '.repeat(cell.getWidth());\n if (hasDecoration) {\n const restoreSgrSeq = this._diffStyle(cell, this._defaultCell);\n this._currentRow += `\\u001b[0m\\u001b[${restoreSgrSeq.join(';')}m`;\n }\n } else {\n this._currentRow += cell.getChars();\n }\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // Each buffer is self-contained so links cannot leak into a following buffer.\n content += this._setOscLink(0);\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n // Restore the source terminal's live OSC pen only after all buffers are complete.\n content += getActiveOscLinkSequence(this._terminal);\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","Color_1","__webpack_require__","DEFAULT_ANSI_COLORS","Object","freeze","colors","css","toColor","v","i","r","g","b","push","channels","toCss","rgba","toRgba","c","$r","$g","$b","$a","color","rgb","toPaddedHex","s","toString","length","contrastRatio","l1","l2","NULL_COLOR","a","undefined","color_1","opacity","Math","round","toChannels","blend","bg","fg","fgR","fgG","fgB","bgR","bgG","bgB","isOpaque","ensureContrastRatio","ratio","result","opaque","rgbaColor","multiplyOpacity","factor","toColorRGB","css_1","$ctx","$litmusColor","canvas","document","createElement","width","height","ctx","getContext","willReadFrequently","globalCompositeOperation","createLinearGradient","match","parseInt","slice","repeat","rgbaMatch","parseFloat","Error","fillStyle","fillRect","getImageData","data","rgb_1","relativeLuminance2","rs","gs","bs","pow","relativeLuminance","reduceLuminance","bgRgba","fgRgba","cr","max","ceil","increaseLuminance","min","bgL","fgL","resultA","resultARatio","resultB","value","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","Types_1","getOscLinkId","cell","extended","urlId","getOscLinkOpenSequence","terminal","linkId","_core","_oscLinkService","getLinkData","id","uri","constrain","low","high","BaseSerializeHandler","constructor","_buffer","serialize","range","excludeFinalCursorPosition","cell1","this","getNullCell","cell2","oldCell","startRow","start","y","endRow","end","startColumn","x","endColumn","_beforeSerialize","row","line","getLine","startLineColumn","endLineColumn","col","getCell","_nextCell","console","warn","_rowEnd","_afterSerialize","_serializeString","isLastRow","rows","equalFg","getFgColorMode","getFgColor","equalBg","getBgColorMode","getBgColor","equalUnderline","isUnderline","getUnderlineStyle","cell1Default","isUnderlineColorDefault","cell2Default","getUnderlineColor","getUnderlineColorMode","equalFlags","isInverse","isBold","isOverline","isBlink","isInvisible","isItalic","isDim","isStrikethrough","attributesEquals","cell1AsBufferCell","StringSerializeHandler","buffer","_terminal","super","_rowIndex","_allRows","Array","_allRowSeparators","_currentRow","_nullCellCount","_cursorStyle","_cursorStyleRow","_cursorStyleCol","_backgroundCell","_defaultCell","_firstRow","_lastCursorRow","_lastCursorCol","_lastContentCursorRow","_lastContentCursorCol","_activeOscLinkId","_thisRowLastChar","_thisRowLastSecondChar","_nextRowFirstChar","rowSeparator","currentLine","nextLine","isWrapped","thisRowLastChar","thisRowLastSecondChar","nextRowFirstChar","isNextRowFirstCharDoubleWidth","getWidth","isValid","getChars","contentCellCount","_diffStyle","sgrSeq","fgChanged","bgChanged","flagsChanged","isAttributeDefault","isFgRGB","isFgPalette","isBgRGB","isBgPalette","boldChanged","dimChanged","clearsIntensity","style","isUnderlineColorRGB","_setOscLink","sequence","openSequence","isEmptyCell","nextRowFirstCell","isWideWrapPadding","cols","materializeEmptyCell","join","hasDecoration","restoreSgrSeq","rowEnd","content","realCursorRow","baseY","cursorY","realCursorCol","cursorX","moveRight","offset","curAttrData","_inputHandler","_curAttrData","activate","_serializeBufferByScrollback","scrollback","maxRows","correctRows","_serializeBufferByRange","_serializeBufferAsHTML","options","active","handler","HTMLSerializeHandler","onlySelection","startCol","startLine","endLine","selection","getSelectionPosition","_serializeScrollRegion","scrollTop","scrollBottom","_serializeModes","modes","applicationCursorKeysMode","applicationKeypadMode","bracketedPasteMode","insertMode","originMode","reverseWraparoundMode","sendFocusMode","wraparoundMode","mouseTrackingMode","showCursor","normal","excludeAltBuffer","type","alternate","excludeModes","attrs","getActiveOscLinkSequence","serializeAsHTML","dispose","_options","_htmlContent","_themeService","_ansiColors","ansi","foreground","background","includeGlobalBackground","theme","globalStyleDefinitions","fontFamily","fontSize","_getHexColor","isFg","map","padStart","_getUnderlineColor","_getUnderlineStyle","fgHexColor","bgHexColor","decorations","underlineColor","styleDefinitions","escapeHTMLChar"],"sourceRoot":""} ++{"version":3,"file":"addon-serialize.js","mappings":"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","sources":["webpack://SerializeAddon/webpack/universalModuleDefinition","webpack://SerializeAddon/../src/browser/Types.ts","webpack://SerializeAddon/../src/common/Color.ts","webpack://SerializeAddon/webpack/bootstrap","webpack://SerializeAddon/./src/SerializeAddon.ts"],"sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory();\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"SerializeAddon\"] = factory();\n\telse\n\t\troot[\"SerializeAddon\"] = factory();\n})(globalThis, () => {\nreturn ","/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId](module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferLine, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\ntype OscLinkData = { id?: string; uri: string };\ntype OscLinkedCell = { extended?: { urlId?: number } };\ntype TerminalWithOscLinks = Terminal & {\n _core?: {\n _inputHandler?: { _curAttrData?: IAttributeData & OscLinkedCell };\n _oscLinkService?: { getLinkData: (linkId: number) => OscLinkData | undefined };\n };\n};\n\nfunction getOscLinkId(cell: IBufferCell | IAttributeData): number {\n return (cell as typeof cell & OscLinkedCell).extended?.urlId ?? 0;\n}\n\nfunction getOscLinkOpenSequence(terminal: Terminal, linkId: number): string {\n if (!linkId) {\n return '';\n }\n const data = (terminal as TerminalWithOscLinks)._core?._oscLinkService?.getLinkData(linkId);\n if (!data) {\n return '';\n }\n const params = data.id === undefined ? '' : `id=${data.id}`;\n return `\\u001b]8;${params};${data.uri}\\u001b\\\\`;\n}\n\nfunction getActiveOscLinkSequence(terminal: Terminal): string {\n const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData;\n return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : '';\n}\n\n// PATCH(orca): a non-reflowing shrink (always the alternate buffer) leaves each\n// line at its old length; cells past the grid are not on screen and would wrap\n// into extra rows on replay, so serialize only the terminal's width.\nfunction visibleCellCount(line: IBufferLine, cols: number): number {\n return Math.min(line.length, cols);\n}\n\n// PATCH(orca): a wide glyph whose trailing half fell past the grid cannot be\n// replayed in the last column (it would wrap and shift every row below), so it\n// is serialized as a blank that keeps the row exactly the grid's width.\nfunction isClippedWideCell(line: IBufferLine, col: number, cols: number, cell: IBufferCell): boolean {\n return col === cols - 1 && line.length > cols && cell.getWidth() > 1;\n}\n\n// Width 1 with no codepoint (CellData.content layout). A width-0 stand-in would read as a\n// wide glyph's trailer: skipped by _nextCell and treated as content by the wrap check.\nconst BLANK_CELL_CONTENT = 1 << 22;\n\nfunction blankClippedWideCell(cell: IBufferCell): IBufferCell {\n (cell as IBufferCell & { content: number }).content = BLANK_CELL_CONTENT;\n return cell;\n}\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer,\n private readonly _cols: number\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: visibleCellCount(line, this._cols);\n for (let col = startLineColumn; col < endLineColumn; col++) {\n let c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n if (isClippedWideCell(line, col, this._cols, c)) {\n c = blankClippedWideCell(c);\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n private _defaultCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n private _activeOscLinkId: number = 0;\n private _lastBackgroundCursorRow: number = -1;\n private _lastBackgroundCursorCol: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer, _terminal.cols);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n // PATCH(orca): the erase paints this row, so _serializeString must not trim it as trailing blank.\n this._lastBackgroundCursorRow = this._lastCursorRow;\n this._lastBackgroundCursorCol = this._lastCursorCol;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const currentLineCells = visibleCellCount(currentLine, this._terminal.cols);\n let thisRowLastChar = currentLine.getCell(currentLineCells - 1, this._thisRowLastChar)!;\n if (isClippedWideCell(currentLine, currentLineCells - 1, this._terminal.cols, thisRowLastChar)) {\n thisRowLastChar = blankClippedWideCell(thisRowLastChar);\n }\n const thisRowLastSecondChar = currentLine.getCell(currentLineCells - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n (isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0)\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n const contentCellCount = currentLineCells - this._nullCellCount;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}C`;\n }\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}D`;\n }\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n // PATCH(orca): bold (1) and dim (2) share the single reset param 22, so\n // they must be diffed as one intensity group with the clearing 22 emitted\n // BEFORE any re-set. Upstream's independent per-flag diff could emit\n // \"1;22\" (bold set, then wiped by dim's clear โ€” \\x1b[2mA\\x1b[22m\\x1b[1mB\n // loses B's bold on round-trip) or a bare \"22\" that drops a still-set\n // bold/dim, garbling Orca's hidden-terminal snapshot restores.\n const boldChanged = cell.isBold() !== oldCell.isBold();\n const dimChanged = cell.isDim() !== oldCell.isDim();\n if (boldChanged || dimChanged) {\n const clearsIntensity = (boldChanged && !cell.isBold()) || (dimChanged && !cell.isDim());\n if (clearsIntensity) { sgrSeq.push(22); }\n if (cell.isBold() && (boldChanged || clearsIntensity)) { sgrSeq.push(1); }\n if (cell.isDim() && (dimChanged || clearsIntensity)) { sgrSeq.push(2); }\n }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n // PATCH(orca): dim handled in the intensity group above.\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n private _setOscLink(linkId: number): string {\n if (linkId === this._activeOscLinkId) {\n return '';\n }\n let sequence = this._activeOscLinkId ? '\\u001b]8;;\\u001b\\\\' : '';\n this._activeOscLinkId = 0;\n const openSequence = getOscLinkOpenSequence(this._terminal, linkId);\n if (openSequence) {\n this._activeOscLinkId = linkId;\n sequence += openSequence;\n }\n return sequence;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n const nextLine = isEmptyCell && cell.isInverse() ? this._buffer.getLine(row + 1) : undefined;\n const nextRowFirstCell = nextLine?.getCell(0, this._nextRowFirstChar);\n // A pending wide glyph recreates its own final-column padding during replay.\n const isWideWrapPadding = col === this._terminal.cols - 1 &&\n nextLine?.isWrapped &&\n (nextRowFirstCell?.getWidth() ?? 0) > 1 &&\n !!nextRowFirstCell && attributesEquals(cell, nextRowFirstCell);\n // Cursor movement cannot reproduce an inverse cell's visible background.\n const materializeEmptyCell = isEmptyCell && !!cell.isInverse() && !isWideWrapPadding;\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n const styleChanged = isEmptyCell\n ? materializeEmptyCell ? sgrSeq.length > 0 : !equalBg(this._cursorStyle, cell)\n : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell && !materializeEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n // PATCH(orca): styling alone leaves restored OSC 8 links looking live but unclickable.\n this._currentRow += this._setOscLink(getOscLinkId(cell));\n\n if (materializeEmptyCell) {\n const hasDecoration = !!cell.isUnderline() || !!cell.isStrikethrough() || !!cell.isOverline();\n if (hasDecoration) {\n this._currentRow += '\\u001b[24;29;55m';\n }\n this._currentRow += ' '.repeat(cell.getWidth());\n if (hasDecoration) {\n const restoreSgrSeq = this._diffStyle(cell, this._defaultCell);\n this._currentRow += `\\u001b[0m\\u001b[${restoreSgrSeq.join(';')}m`;\n }\n } else {\n this._currentRow += cell.getChars();\n }\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n // PATCH(orca): keep trailing background-only rows, unless the cursor is wrap-pending:\n // relative moves back from those rows cannot re-create that state.\n if (\n this._lastBackgroundCursorRow > this._lastContentCursorRow &&\n this._buffer.cursorX < this._terminal.cols\n ) {\n this._lastContentCursorRow = this._lastBackgroundCursorRow;\n this._lastContentCursorCol = this._lastBackgroundCursorCol;\n }\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // Each buffer is self-contained so links cannot leak into a following buffer.\n content += this._setOscLink(0);\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n // Restore the source terminal's live OSC pen only after all buffers are complete.\n content += getActiveOscLinkSequence(this._terminal);\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer, _terminal.cols);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"],"names":["root","factory","exports","module","define","amd","globalThis","Color_1","__webpack_require__","DEFAULT_ANSI_COLORS","Object","freeze","colors","css","toColor","v","i","r","g","b","push","channels","toCss","rgba","toRgba","c","$r","$g","$b","$a","color","rgb","toPaddedHex","s","toString","length","contrastRatio","l1","l2","NULL_COLOR","a","undefined","color_1","opacity","Math","round","toChannels","blend","bg","fg","fgR","fgG","fgB","bgR","bgG","bgB","isOpaque","ensureContrastRatio","ratio","result","opaque","rgbaColor","multiplyOpacity","factor","toColorRGB","css_1","$ctx","$litmusColor","canvas","document","createElement","width","height","ctx","getContext","willReadFrequently","globalCompositeOperation","createLinearGradient","match","parseInt","slice","repeat","rgbaMatch","parseFloat","Error","fillStyle","fillRect","getImageData","data","rgb_1","relativeLuminance2","rs","gs","bs","pow","relativeLuminance","reduceLuminance","bgRgba","fgRgba","cr","max","ceil","increaseLuminance","min","bgL","fgL","resultA","resultARatio","resultB","value","__webpack_module_cache__","moduleId","cachedModule","__webpack_modules__","Types_1","getOscLinkId","cell","extended","urlId","getOscLinkOpenSequence","terminal","linkId","_core","_oscLinkService","getLinkData","id","uri","visibleCellCount","line","cols","isClippedWideCell","col","getWidth","blankClippedWideCell","content","constrain","low","high","BaseSerializeHandler","constructor","_buffer","_cols","serialize","range","excludeFinalCursorPosition","cell1","this","getNullCell","cell2","oldCell","startRow","start","y","endRow","end","startColumn","x","endColumn","_beforeSerialize","row","getLine","startLineColumn","endLineColumn","getCell","_nextCell","console","warn","_rowEnd","_afterSerialize","_serializeString","isLastRow","rows","equalFg","getFgColorMode","getFgColor","equalBg","getBgColorMode","getBgColor","equalUnderline","isUnderline","getUnderlineStyle","cell1Default","isUnderlineColorDefault","cell2Default","getUnderlineColor","getUnderlineColorMode","equalFlags","isInverse","isBold","isOverline","isBlink","isInvisible","isItalic","isDim","isStrikethrough","attributesEquals","cell1AsBufferCell","StringSerializeHandler","buffer","_terminal","super","_rowIndex","_allRows","Array","_allRowSeparators","_currentRow","_nullCellCount","_cursorStyle","_cursorStyleRow","_cursorStyleCol","_backgroundCell","_defaultCell","_firstRow","_lastCursorRow","_lastCursorCol","_lastContentCursorRow","_lastContentCursorCol","_activeOscLinkId","_lastBackgroundCursorRow","_lastBackgroundCursorCol","_thisRowLastChar","_thisRowLastSecondChar","_nextRowFirstChar","rowSeparator","currentLine","nextLine","isWrapped","currentLineCells","thisRowLastChar","thisRowLastSecondChar","nextRowFirstChar","isNextRowFirstCharDoubleWidth","isValid","getChars","contentCellCount","_diffStyle","sgrSeq","fgChanged","bgChanged","flagsChanged","isAttributeDefault","isFgRGB","isFgPalette","isBgRGB","isBgPalette","boldChanged","dimChanged","clearsIntensity","style","isUnderlineColorRGB","_setOscLink","sequence","openSequence","isEmptyCell","nextRowFirstCell","isWideWrapPadding","materializeEmptyCell","join","hasDecoration","restoreSgrSeq","rowEnd","cursorX","realCursorRow","baseY","cursorY","realCursorCol","moveRight","offset","curAttrData","_inputHandler","_curAttrData","activate","_serializeBufferByScrollback","scrollback","maxRows","correctRows","_serializeBufferByRange","_serializeBufferAsHTML","options","active","handler","HTMLSerializeHandler","onlySelection","startCol","startLine","endLine","selection","getSelectionPosition","_serializeScrollRegion","scrollTop","scrollBottom","_serializeModes","modes","applicationCursorKeysMode","applicationKeypadMode","bracketedPasteMode","insertMode","originMode","reverseWraparoundMode","sendFocusMode","wraparoundMode","mouseTrackingMode","showCursor","normal","excludeAltBuffer","type","alternate","excludeModes","attrs","getActiveOscLinkSequence","serializeAsHTML","dispose","_options","_htmlContent","_themeService","_ansiColors","ansi","foreground","background","includeGlobalBackground","theme","globalStyleDefinitions","fontFamily","fontSize","_getHexColor","isFg","map","padStart","_getUnderlineColor","_getUnderlineStyle","fgHexColor","bgHexColor","decorations","underlineColor","styleDefinitions","escapeHTMLChar"],"sourceRoot":""} \ No newline at end of file diff --git a/lib/addon-serialize.mjs b/lib/addon-serialize.mjs -index a5c4c4dd05b7efcc23d0e45661ffd4e42da80f21..b9bb467ab8a701c6d31a0f7a539010fad828e6da 100644 +index a5c4c4dd05b7efcc23d0e45661ffd4e42da80f21..55479a99d4b419e5e5e071ed04a656e892c27c15 100644 --- a/lib/addon-serialize.mjs +++ b/lib/addon-serialize.mjs @@ -14,6 +14,6 @@ @@ -26,11 +26,11 @@ index a5c4c4dd05b7efcc23d0e45661ffd4e42da80f21..b9bb467ab8a701c6d31a0f7a539010fa *--------------------------------------------------------------------------------------------*/ -var m=0,b=0,_=0,p=0;var g;(t=>{function a(r,l,s,i){return i!==void 0?`#${w(r)}${w(l)}${w(s)}${w(i)}`:`#${w(r)}${w(l)}${w(s)}`}t.toCss=a;function n(r,l,s,i=255){return(r<<24|l<<16|s<<8|i)>>>0}t.toRgba=n;function e(r,l,s,i){return{css:t.toCss(r,l,s,i),rgba:t.toRgba(r,l,s,i)}}t.toColor=e})(g||={});var N;(i=>{function a(o,u){if(p=(u.rgba&255)/255,p===1)return{css:u.css,rgba:u.rgba};let f=u.rgba>>24&255,C=u.rgba>>16&255,c=u.rgba>>8&255,h=o.rgba>>24&255,d=o.rgba>>16&255,I=o.rgba>>8&255;m=h+Math.round((f-h)*p),b=d+Math.round((C-d)*p),_=I+Math.round((c-I)*p);let L=g.toCss(m,b,_),E=g.toRgba(m,b,_);return{css:L,rgba:E}}i.blend=a;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,u,f){let C=B.ensureContrastRatio(o.rgba,u.rgba,f);if(C)return g.toColor(C>>24&255,C>>16&255,C>>8&255)}i.ensureContrastRatio=e;function t(o){let u=(o.rgba|255)>>>0;return[m,b,_]=B.toChannels(u),{css:g.toCss(m,b,_),rgba:u}}i.opaque=t;function r(o,u){return p=Math.round(u*255),[m,b,_]=B.toChannels(o.rgba),{css:g.toCss(m,b,_,p),rgba:g.toRgba(m,b,_,p)}}i.opacity=r;function l(o,u){return p=o.rgba&255,r(o,p*u/255)}i.multiplyOpacity=l;function s(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=s})(N||={});var x;(t=>{let a,n;try{let r=document.createElement("canvas");r.width=1,r.height=1;let l=r.getContext("2d",{willReadFrequently:!0});l&&(a=l,a.globalCompositeOperation="copy",n=a.createLinearGradient(0,0,1,1))}catch{}function e(r){if(r.match(/#[\da-f]{3,8}/i))switch(r.length){case 4:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),g.toColor(m,b,_);case 5:return m=parseInt(r.slice(1,2).repeat(2),16),b=parseInt(r.slice(2,3).repeat(2),16),_=parseInt(r.slice(3,4).repeat(2),16),p=parseInt(r.slice(4,5).repeat(2),16),g.toColor(m,b,_,p);case 7:return{css:r,rgba:(parseInt(r.slice(1),16)<<8|255)>>>0};case 9:return{css:r,rgba:parseInt(r.slice(1),16)>>>0}}let l=r.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(l)return m=parseInt(l[1],10),b=parseInt(l[2],10),_=parseInt(l[3],10),p=Math.round((l[5]===void 0?1:parseFloat(l[5]))*255),g.toColor(m,b,_,p);if(r==="transparent")return{css:"transparent",rgba:0};if(!a||!n)throw new Error("css.toColor: Unsupported css format");if(a.fillStyle=n,a.fillStyle=r,typeof a.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(a.fillRect(0,0,1,1),[m,b,_,p]=a.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(m,b,_,p),css:r}}t.toColor=e})(x||={});var v;(e=>{function a(t){return n(t>>16&255,t>>8&255,t&255)}e.relativeLuminance=a;function n(t,r,l){let s=t/255,i=r/255,o=l/255,u=s<=.03928?s/12.92:Math.pow((s+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),C=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return u*.2126+f*.7152+C*.0722}e.relativeLuminance2=n})(v||={});var B;(l=>{function a(s,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,u=i>>16&255,f=i>>8&255,C=s>>24&255,c=s>>16&255,h=s>>8&255;return m=C+Math.round((o-C)*p),b=c+Math.round((u-c)*p),_=h+Math.round((f-h)*p),g.toRgba(m,b,_)}l.blend=a;function n(s,i,o){let u=v.relativeLuminance(s>>8),f=v.relativeLuminance(i>>8);if(R(u,f)>8));if(I>8));return I>E?d:L}return d}let c=t(s,i,o),h=R(u,v.relativeLuminance(c>>8));if(h>8));return h>I?c:d}return c}}l.ensureContrastRatio=n;function e(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I0||h>0||d>0);)c-=Math.max(0,Math.ceil(c*.1)),h-=Math.max(0,Math.ceil(h*.1)),d-=Math.max(0,Math.ceil(d*.1)),I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));return(c<<24|h<<16|d<<8|255)>>>0}l.reduceLuminance=e;function t(s,i,o){let u=s>>24&255,f=s>>16&255,C=s>>8&255,c=i>>24&255,h=i>>16&255,d=i>>8&255,I=R(v.relativeLuminance2(c,h,d),v.relativeLuminance2(u,f,C));for(;I>>0}l.increaseLuminance=t;function r(s){return[s>>24&255,s>>16&255,s>>8&255,s&255]}l.toChannels=r})(B||={});function w(a){let n=a.toString(16);return n.length<2?"0"+n:n}function R(a,n){return a{let a=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let t=n[e/36%6|0],r=n[e/6%6|0],l=n[e%6];a.push({css:g.toCss(t,r,l),rgba:g.toRgba(t,r,l)})}for(let e=0;e<24;e++){let t=8+e*10;a.push({css:g.toCss(t,t,t),rgba:g.toRgba(t,t,t)})}return a})());function A(a,n,e){return Math.max(n,Math.min(a,e))}function z(a){switch(a){case"&":return"&";case"<":return"<"}return a}var S=class{constructor(n){this._buffer=n}serialize(n,e){let t=this._buffer.getNullCell(),r=this._buffer.getNullCell(),l=t,s=n.start.y,i=n.end.y,o=n.start.x,u=n.end.x;this._beforeSerialize(i-s,s,i);for(let f=s;f<=i;f++){let C=this._buffer.getLine(f);if(C){let c=f===n.start.y?o:0,h=f===n.end.y?u:C.length;for(let d=c;d0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`);let r="";if(!t){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let l=this._buffer.getLine(e),s=this._buffer.getLine(e+1);if(!s.isWrapped)r=`\r -`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{r="";let i=l.getCell(l.length-1,this._thisRowLastChar),o=l.getCell(l.length-2,this._thisRowLastSecondChar),u=s.getCell(0,this._nextRowFirstChar),f=u.getWidth()>1,C=!1;(u.getChars()&&f?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||i.getWidth()===0)&&F(i,u)&&(C=!0),f&&(o.getChars()||o.getWidth()===0)&&F(i,u)&&F(o,u)&&(C=!0)),C||(r="-".repeat(this._nullCellCount+1),r+="\x1B[1D\x1B[1X",this._nullCellCount>0&&(r+="\x1B[A",r+=`\x1B[${l.length-this._nullCellCount}C`,r+=`\x1B[${this._nullCellCount}X`,r+=`\x1B[${l.length-this._nullCellCount}D`,r+="\x1B[B"),this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0)}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=r,this._currentRow="",this._nullCellCount=0}_diffStyle(e,t){let r=[];if(U(e,t))return r;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i)if(e.isAttributeDefault())t.isAttributeDefault()||r.push(0);else{if(l){let o=e.getFgColor();e.isFgRGB()?r.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?r.push(38,5,o):r.push(o&8?90+(o&7):30+(o&7)):r.push(39)}if(s){let o=e.getBgColor();e.isBgRGB()?r.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?r.push(48,5,o):r.push(o&8?100+(o&7):40+(o&7)):r.push(49)}if(i){if(e.isInverse()!==t.isInverse()&&r.push(e.isInverse()?7:27),e.isBold()!==t.isBold()&&r.push(e.isBold()?1:22),O(e,t))e.isUnderline()!==t.isUnderline()&&r.push(e.isUnderline()?4:24);else{let o=e.getUnderlineStyle();if(o===0)r.push(24);else if(o===1&&e.isUnderlineColorDefault())r.push(4);else if(r.push("4:"+o),!e.isUnderlineColorDefault()){let u=e.getUnderlineColor();e.isUnderlineColorRGB()?r.push("58:2::"+(u>>>16&255)+":"+(u>>>8&255)+":"+(u&255)):r.push("58:5:"+u)}}e.isOverline()!==t.isOverline()&&r.push(e.isOverline()?53:55),e.isBlink()!==t.isBlink()&&r.push(e.isBlink()?5:25),e.isInvisible()!==t.isInvisible()&&r.push(e.isInvisible()?8:28),e.isItalic()!==t.isItalic()&&r.push(e.isItalic()?3:23),e.isDim()!==t.isDim()&&r.push(e.isDim()?2:22),e.isStrikethrough()!==t.isStrikethrough()&&r.push(e.isStrikethrough()?9:29)}}return r}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,this._cursorStyle);if(i?!F(this._cursorStyle,e):o.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l,this._currentRow+=`\x1B[${o.join(";")}m`;let f=this._buffer.getLine(r);f!==void 0&&(f.getCell(l,this._cursorStyle),this._cursorStyleRow=r,this._cursorStyleCol=l)}i?this._nullCellCount+=e.getWidth():(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),this._currentRow+=e.getChars(),this._lastContentCursorRow=this._lastCursorRow=r,this._lastContentCursorCol=this._lastCursorCol=l+e.getWidth())}_serializeString(e){let t=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(t=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let r="";for(let i=0;i{c>0?r+=`\x1B[${c}C`:c<0&&(r+=`\x1B[${-c}D`)};u&&((c=>{c>0?r+=`\x1B[${c}B`:c<0&&(r+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let l=this._terminal._core._inputHandler._curAttrData,s=this._diffStyle(l,this._cursorStyle);return s.length>0&&(r+=`\x1B[${s.join(";")}m`),r}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,t){let r=e.length,l=t===void 0?r:A(t+n.rows,0,r);return this._serializeBufferByRange(n,e,{start:r-l,end:r-1},!1)}_serializeBufferByRange(n,e,t,r){return new y(e,n).serialize({start:{x:0,y:typeof t.start=="number"?t.start:t.start.line},end:{x:n.cols,y:typeof t.end=="number"?t.end:t.end.line}},r)}_serializeBufferAsHTML(n,e){let t=n.buffer.active,r=new D(t,n,e),l=e.onlySelection??!1,s=e.range;if(s)return r.serialize({start:{x:s.startCol,y:(typeof s.startLine=="number",s.startLine)},end:{x:n.cols,y:(typeof s.endLine=="number",s.endLine)}});if(!l){let o=t.length,u=e.scrollback,f=u===void 0?o:A(u+n.rows,0,o);return r.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?r.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,t=e.scrollTop,r=e.scrollBottom;return t!==0||r!==n.rows-1?`\x1B[${t+1};${r+1}r`:""}_serializeModes(n){let e="",t=n.modes;if(t.applicationCursorKeysMode&&(e+="\x1B[?1h"),t.applicationKeypadMode&&(e+="\x1B[?66h"),t.bracketedPasteMode&&(e+="\x1B[?2004h"),t.insertMode&&(e+="\x1B[4h"),t.originMode&&(e+="\x1B[?6h"),t.reverseWraparoundMode&&(e+="\x1B[?45h"),t.sendFocusMode&&(e+="\x1B[?1004h"),t.wraparoundMode===!1&&(e+="\x1B[?7l"),t.mouseTrackingMode!=="none")switch(t.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return t.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let t=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${t}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},D=class extends S{constructor(e,t,r){super(e);this._terminal=t;this._options=r;this._currentRow="";this._htmlContent="";t._core._themeService?this._ansiColors=t._core._themeService.colors.ansi:this._ansiColors=k}_beforeSerialize(e,t,r){this._htmlContent+="
";let l="#000000",s="#ffffff";(this._options.includeGlobalBackground??!1)&&(l=this._terminal.options.theme?.foreground??"#ffffff",s=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+l+";"),i.push("background-color: "+s+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,t){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,t){let r=t?e.getFgColor():e.getBgColor();if(t?e.isFgRGB():e.isBgRGB())return"#"+[r>>16&255,r>>8&255,r&255].map(s=>s.toString(16).padStart(2,"0")).join("");if(t?e.isFgPalette():e.isBgPalette())return this._ansiColors[r].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let t=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[t>>16&255,t>>8&255,t&255].map(l=>l.toString(16).padStart(2,"0")).join(""):this._ansiColors[t].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,t){let r=[];if(U(e,t))return;let l=!T(e,t),s=!F(e,t),i=!M(e,t);if(l||s||i){let o=this._getHexColor(e,!0);o&&r.push("color: "+o+";");let u=this._getHexColor(e,!1);u&&r.push("background-color: "+u+";"),e.isInverse()&&r.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&r.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&r.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let C=this._getUnderlineColor(e);C&&r.push("text-decoration-color: "+C+";")}return e.isInvisible()&&r.push("visibility: hidden;"),e.isItalic()&&r.push("font-style: italic;"),e.isDim()&&r.push("opacity: 0.5;"),r}}_nextCell(e,t,r,l){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,t);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=z(e.getChars())}_serializeString(){return this._htmlContent}};export{D as HTMLSerializeHandler,H as SerializeAddon}; -+var b=0,_=0,I=0,p=0;var g;(r=>{function s(t,u,a,i){return i!==void 0?`#${L(t)}${L(u)}${L(a)}${L(i)}`:`#${L(t)}${L(u)}${L(a)}`}r.toCss=s;function n(t,u,a,i=255){return(t<<24|u<<16|a<<8|i)>>>0}r.toRgba=n;function e(t,u,a,i){return{css:r.toCss(t,u,a,i),rgba:r.toRgba(t,u,a,i)}}r.toColor=e})(g||={});var W;(i=>{function s(o,l){if(p=(l.rgba&255)/255,p===1)return{css:l.css,rgba:l.rgba};let f=l.rgba>>24&255,d=l.rgba>>16&255,c=l.rgba>>8&255,C=o.rgba>>24&255,h=o.rgba>>16&255,m=o.rgba>>8&255;b=C+Math.round((f-C)*p),_=h+Math.round((d-h)*p),I=m+Math.round((c-m)*p);let w=g.toCss(b,_,I),E=g.toRgba(b,_,I);return{css:w,rgba:E}}i.blend=s;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,l,f){let d=S.ensureContrastRatio(o.rgba,l.rgba,f);if(d)return g.toColor(d>>24&255,d>>16&255,d>>8&255)}i.ensureContrastRatio=e;function r(o){let l=(o.rgba|255)>>>0;return[b,_,I]=S.toChannels(l),{css:g.toCss(b,_,I),rgba:l}}i.opaque=r;function t(o,l){return p=Math.round(l*255),[b,_,I]=S.toChannels(o.rgba),{css:g.toCss(b,_,I,p),rgba:g.toRgba(b,_,I,p)}}i.opacity=t;function u(o,l){return p=o.rgba&255,t(o,p*l/255)}i.multiplyOpacity=u;function a(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=a})(W||={});var x;(r=>{let s,n;try{let t=document.createElement("canvas");t.width=1,t.height=1;let u=t.getContext("2d",{willReadFrequently:!0});u&&(s=u,s.globalCompositeOperation="copy",n=s.createLinearGradient(0,0,1,1))}catch{}function e(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return b=parseInt(t.slice(1,2).repeat(2),16),_=parseInt(t.slice(2,3).repeat(2),16),I=parseInt(t.slice(3,4).repeat(2),16),g.toColor(b,_,I);case 5:return b=parseInt(t.slice(1,2).repeat(2),16),_=parseInt(t.slice(2,3).repeat(2),16),I=parseInt(t.slice(3,4).repeat(2),16),p=parseInt(t.slice(4,5).repeat(2),16),g.toColor(b,_,I,p);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}let u=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(u)return b=parseInt(u[1],10),_=parseInt(u[2],10),I=parseInt(u[3],10),p=Math.round((u[5]===void 0?1:parseFloat(u[5]))*255),g.toColor(b,_,I,p);if(t==="transparent")return{css:"transparent",rgba:0};if(!s||!n)throw new Error("css.toColor: Unsupported css format");if(s.fillStyle=n,s.fillStyle=t,typeof s.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(s.fillRect(0,0,1,1),[b,_,I,p]=s.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(b,_,I,p),css:t}}r.toColor=e})(x||={});var v;(e=>{function s(r){return n(r>>16&255,r>>8&255,r&255)}e.relativeLuminance=s;function n(r,t,u){let a=r/255,i=t/255,o=u/255,l=a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),d=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return l*.2126+f*.7152+d*.0722}e.relativeLuminance2=n})(v||={});var S;(u=>{function s(a,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,l=i>>16&255,f=i>>8&255,d=a>>24&255,c=a>>16&255,C=a>>8&255;return b=d+Math.round((o-d)*p),_=c+Math.round((l-c)*p),I=C+Math.round((f-C)*p),g.toRgba(b,_,I)}u.blend=s;function n(a,i,o){let l=v.relativeLuminance(a>>8),f=v.relativeLuminance(i>>8);if(R(l,f)>8));if(m>8));return m>E?h:w}return h}let c=r(a,i,o),C=R(l,v.relativeLuminance(c>>8));if(C>8));return C>m?c:h}return c}}u.ensureContrastRatio=n;function e(a,i,o){let l=a>>24&255,f=a>>16&255,d=a>>8&255,c=i>>24&255,C=i>>16&255,h=i>>8&255,m=R(v.relativeLuminance2(c,C,h),v.relativeLuminance2(l,f,d));for(;m0||C>0||h>0);)c-=Math.max(0,Math.ceil(c*.1)),C-=Math.max(0,Math.ceil(C*.1)),h-=Math.max(0,Math.ceil(h*.1)),m=R(v.relativeLuminance2(c,C,h),v.relativeLuminance2(l,f,d));return(c<<24|C<<16|h<<8|255)>>>0}u.reduceLuminance=e;function r(a,i,o){let l=a>>24&255,f=a>>16&255,d=a>>8&255,c=i>>24&255,C=i>>16&255,h=i>>8&255,m=R(v.relativeLuminance2(c,C,h),v.relativeLuminance2(l,f,d));for(;m>>0}u.increaseLuminance=r;function t(a){return[a>>24&255,a>>16&255,a>>8&255,a&255]}u.toChannels=t})(S||={});function L(s){let n=s.toString(16);return n.length<2?"0"+n:n}function R(s,n){return s{let s=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let r=n[e/36%6|0],t=n[e/6%6|0],u=n[e%6];s.push({css:g.toCss(r,t,u),rgba:g.toRgba(r,t,u)})}for(let e=0;e<24;e++){let r=8+e*10;s.push({css:g.toCss(r,r,r),rgba:g.toRgba(r,r,r)})}return s})());function U(s){return s.extended?.urlId??0}function N(s,n){if(!n)return"";let e=s._core?._oscLinkService?.getLinkData(n);return e?`\x1B]8;${e.id===void 0?"":`id=${e.id}`};${e.uri}\x1B\\`:""}function $(s){let n=s._core?._inputHandler?._curAttrData;return n?N(s,U(n)):""}function A(s,n,e){return Math.max(n,Math.min(s,e))}function P(s){switch(s){case"&":return"&";case"<":return"<"}return s}var B=class{constructor(n){this._buffer=n}serialize(n,e){let r=this._buffer.getNullCell(),t=this._buffer.getNullCell(),u=r,a=n.start.y,i=n.end.y,o=n.start.x,l=n.end.x;this._beforeSerialize(i-a,a,i);for(let f=a;f<=i;f++){let d=this._buffer.getLine(f);if(d){let c=f===n.start.y?o:0,C=f===n.end.y?l:d.length;for(let h=c;h0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`);let t="";if(!r){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let u=this._buffer.getLine(e),a=this._buffer.getLine(e+1);if(!a.isWrapped)t=`\r -+`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{t="";let i=u.getCell(u.length-1,this._thisRowLastChar),o=u.getCell(u.length-2,this._thisRowLastSecondChar),l=a.getCell(0,this._nextRowFirstChar),f=l.getWidth()>1,d=!1;if(l.getChars()&&(f?this._nullCellCount<=1:this._nullCellCount<=0)&&((i.getChars()||i.getWidth()===0)&&F(i,l)&&(d=!0),f&&(o.getChars()||o.getWidth()===0)&&F(i,l)&&F(o,l)&&(d=!0)),!d){if(t="-".repeat(this._nullCellCount+1),t+="\x1B[1D\x1B[1X",this._nullCellCount>0){t+="\x1B[A";let c=u.length-this._nullCellCount;c>0&&(t+=`\x1B[${c}C`),t+=`\x1B[${this._nullCellCount}X`,c>0&&(t+=`\x1B[${c}D`),t+="\x1B[B"}this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0}}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=t,this._currentRow="",this._nullCellCount=0}_diffStyle(e,r){let t=[];if(y(e,r))return t;let u=!T(e,r),a=!F(e,r),i=!M(e,r);if(u||a||i)if(e.isAttributeDefault())r.isAttributeDefault()||t.push(0);else{if(u){let o=e.getFgColor();e.isFgRGB()?t.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?t.push(38,5,o):t.push(o&8?90+(o&7):30+(o&7)):t.push(39)}if(a){let o=e.getBgColor();e.isBgRGB()?t.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?t.push(48,5,o):t.push(o&8?100+(o&7):40+(o&7)):t.push(49)}if(i){e.isInverse()!==r.isInverse()&&t.push(e.isInverse()?7:27);let o=e.isBold()!==r.isBold(),l=e.isDim()!==r.isDim();if(o||l){let f=o&&!e.isBold()||l&&!e.isDim();f&&t.push(22),e.isBold()&&(o||f)&&t.push(1),e.isDim()&&(l||f)&&t.push(2)}if(z(e,r))e.isUnderline()!==r.isUnderline()&&t.push(e.isUnderline()?4:24);else{let f=e.getUnderlineStyle();if(f===0)t.push(24);else if(f===1&&e.isUnderlineColorDefault())t.push(4);else if(t.push("4:"+f),!e.isUnderlineColorDefault()){let d=e.getUnderlineColor();e.isUnderlineColorRGB()?t.push("58:2::"+(d>>>16&255)+":"+(d>>>8&255)+":"+(d&255)):t.push("58:5:"+d)}}e.isOverline()!==r.isOverline()&&t.push(e.isOverline()?53:55),e.isBlink()!==r.isBlink()&&t.push(e.isBlink()?5:25),e.isInvisible()!==r.isInvisible()&&t.push(e.isInvisible()?8:28),e.isItalic()!==r.isItalic()&&t.push(e.isItalic()?3:23),e.isStrikethrough()!==r.isStrikethrough()&&t.push(e.isStrikethrough()?9:29)}}return t}_setOscLink(e){if(e===this._activeOscLinkId)return"";let r=this._activeOscLinkId?"\x1B]8;;\x1B\\":"";this._activeOscLinkId=0;let t=N(this._terminal,e);return t&&(this._activeOscLinkId=e,r+=t),r}_nextCell(e,r,t,u){if(e.getWidth()===0)return;let i=e.getChars()==="",o=i&&e.isInverse()?this._buffer.getLine(t+1):void 0,l=o?.getCell(0,this._nextRowFirstChar),f=u===this._terminal.cols-1&&o?.isWrapped&&(l?.getWidth()??0)>1&&!!l&&y(e,l),d=i&&!!e.isInverse()&&!f,c=this._diffStyle(e,this._cursorStyle);if(i?d?c.length>0:!F(this._cursorStyle,e):c.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=t,this._lastContentCursorCol=this._lastCursorCol=u,this._currentRow+=`\x1B[${c.join(";")}m`;let h=this._buffer.getLine(t);h!==void 0&&(h.getCell(u,this._cursorStyle),this._cursorStyleRow=t,this._cursorStyleCol=u)}if(i&&!d)this._nullCellCount+=e.getWidth();else{if(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),this._currentRow+=this._setOscLink(U(e)),d){let h=!!e.isUnderline()||!!e.isStrikethrough()||!!e.isOverline();if(h&&(this._currentRow+="\x1B[24;29;55m"),this._currentRow+=" ".repeat(e.getWidth()),h){let m=this._diffStyle(e,this._defaultCell);this._currentRow+=`\x1B[0m\x1B[${m.join(";")}m`}}else this._currentRow+=e.getChars();this._lastContentCursorRow=this._lastCursorRow=t,this._lastContentCursorCol=this._lastCursorCol=u+e.getWidth()}}_serializeString(e){let r=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(r=this._lastContentCursorRow+1-this._firstRow,this._lastCursorCol=this._lastContentCursorCol,this._lastCursorRow=this._lastContentCursorRow);let t="";for(let i=0;i{c>0?t+=`\x1B[${c}C`:c<0&&(t+=`\x1B[${-c}D`)};l&&((c=>{c>0?t+=`\x1B[${c}B`:c<0&&(t+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let u=this._terminal._core._inputHandler._curAttrData,a=this._diffStyle(u,this._cursorStyle);return a.length>0&&(t+=`\x1B[${a.join(";")}m`),t}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,r){let t=e.length,u=r===void 0?t:A(r+n.rows,0,t);return this._serializeBufferByRange(n,e,{start:t-u,end:t-1},!1)}_serializeBufferByRange(n,e,r,t){return new D(e,n).serialize({start:{x:0,y:typeof r.start=="number"?r.start:r.start.line},end:{x:n.cols,y:typeof r.end=="number"?r.end:r.end.line}},t)}_serializeBufferAsHTML(n,e){let r=n.buffer.active,t=new k(r,n,e),u=e.onlySelection??!1,a=e.range;if(a)return t.serialize({start:{x:a.startCol,y:(typeof a.startLine=="number",a.startLine)},end:{x:n.cols,y:(typeof a.endLine=="number",a.endLine)}});if(!u){let o=r.length,l=e.scrollback,f=l===void 0?o:A(l+n.rows,0,o);return t.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?t.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,r=e.scrollTop,t=e.scrollBottom;return r!==0||t!==n.rows-1?`\x1B[${r+1};${t+1}r`:""}_serializeModes(n){let e="",r=n.modes;if(r.applicationCursorKeysMode&&(e+="\x1B[?1h"),r.applicationKeypadMode&&(e+="\x1B[?66h"),r.bracketedPasteMode&&(e+="\x1B[?2004h"),r.insertMode&&(e+="\x1B[4h"),r.originMode&&(e+="\x1B[?6h"),r.reverseWraparoundMode&&(e+="\x1B[?45h"),r.sendFocusMode&&(e+="\x1B[?1004h"),r.wraparoundMode===!1&&(e+="\x1B[?7l"),r.mouseTrackingMode!=="none")switch(r.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return r.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let r=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${r}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e+=$(this._terminal),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},k=class extends B{constructor(e,r,t){super(e);this._terminal=r;this._options=t;this._currentRow="";this._htmlContent="";r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=O}_beforeSerialize(e,r,t){this._htmlContent+="
";let u="#000000",a="#ffffff";(this._options.includeGlobalBackground??!1)&&(u=this._terminal.options.theme?.foreground??"#ffffff",a=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+u+";"),i.push("background-color: "+a+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,r){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,r){let t=r?e.getFgColor():e.getBgColor();if(r?e.isFgRGB():e.isBgRGB())return"#"+[t>>16&255,t>>8&255,t&255].map(a=>a.toString(16).padStart(2,"0")).join("");if(r?e.isFgPalette():e.isBgPalette())return this._ansiColors[t].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let r=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[r>>16&255,r>>8&255,r&255].map(u=>u.toString(16).padStart(2,"0")).join(""):this._ansiColors[r].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,r){let t=[];if(y(e,r))return;let u=!T(e,r),a=!F(e,r),i=!M(e,r);if(u||a||i){let o=this._getHexColor(e,!0);o&&t.push("color: "+o+";");let l=this._getHexColor(e,!1);l&&t.push("background-color: "+l+";"),e.isInverse()&&t.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&t.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&t.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let d=this._getUnderlineColor(e);d&&t.push("text-decoration-color: "+d+";")}return e.isInvisible()&&t.push("visibility: hidden;"),e.isItalic()&&t.push("font-style: italic;"),e.isDim()&&t.push("opacity: 0.5;"),t}}_nextCell(e,r,t,u){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,r);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=P(e.getChars())}_serializeString(){return this._htmlContent}};export{k as HTMLSerializeHandler,H as SerializeAddon}; ++var b=0,_=0,I=0,p=0;var g;(r=>{function s(t,u,a,i){return i!==void 0?`#${L(t)}${L(u)}${L(a)}${L(i)}`:`#${L(t)}${L(u)}${L(a)}`}r.toCss=s;function n(t,u,a,i=255){return(t<<24|u<<16|a<<8|i)>>>0}r.toRgba=n;function e(t,u,a,i){return{css:r.toCss(t,u,a,i),rgba:r.toRgba(t,u,a,i)}}r.toColor=e})(g||={});var G;(i=>{function s(o,l){if(p=(l.rgba&255)/255,p===1)return{css:l.css,rgba:l.rgba};let f=l.rgba>>24&255,d=l.rgba>>16&255,c=l.rgba>>8&255,h=o.rgba>>24&255,C=o.rgba>>16&255,m=o.rgba>>8&255;b=h+Math.round((f-h)*p),_=C+Math.round((d-C)*p),I=m+Math.round((c-m)*p);let B=g.toCss(b,_,I),E=g.toRgba(b,_,I);return{css:B,rgba:E}}i.blend=s;function n(o){return(o.rgba&255)===255}i.isOpaque=n;function e(o,l,f){let d=w.ensureContrastRatio(o.rgba,l.rgba,f);if(d)return g.toColor(d>>24&255,d>>16&255,d>>8&255)}i.ensureContrastRatio=e;function r(o){let l=(o.rgba|255)>>>0;return[b,_,I]=w.toChannels(l),{css:g.toCss(b,_,I),rgba:l}}i.opaque=r;function t(o,l){return p=Math.round(l*255),[b,_,I]=w.toChannels(o.rgba),{css:g.toCss(b,_,I,p),rgba:g.toRgba(b,_,I,p)}}i.opacity=t;function u(o,l){return p=o.rgba&255,t(o,p*l/255)}i.multiplyOpacity=u;function a(o){return[o.rgba>>24&255,o.rgba>>16&255,o.rgba>>8&255]}i.toColorRGB=a})(G||={});var x;(r=>{let s,n;try{let t=document.createElement("canvas");t.width=1,t.height=1;let u=t.getContext("2d",{willReadFrequently:!0});u&&(s=u,s.globalCompositeOperation="copy",n=s.createLinearGradient(0,0,1,1))}catch{}function e(t){if(t.match(/#[\da-f]{3,8}/i))switch(t.length){case 4:return b=parseInt(t.slice(1,2).repeat(2),16),_=parseInt(t.slice(2,3).repeat(2),16),I=parseInt(t.slice(3,4).repeat(2),16),g.toColor(b,_,I);case 5:return b=parseInt(t.slice(1,2).repeat(2),16),_=parseInt(t.slice(2,3).repeat(2),16),I=parseInt(t.slice(3,4).repeat(2),16),p=parseInt(t.slice(4,5).repeat(2),16),g.toColor(b,_,I,p);case 7:return{css:t,rgba:(parseInt(t.slice(1),16)<<8|255)>>>0};case 9:return{css:t,rgba:parseInt(t.slice(1),16)>>>0}}let u=t.match(/rgba?\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*(,\s*(0|1|\d?\.(\d+))\s*)?\)/);if(u)return b=parseInt(u[1],10),_=parseInt(u[2],10),I=parseInt(u[3],10),p=Math.round((u[5]===void 0?1:parseFloat(u[5]))*255),g.toColor(b,_,I,p);if(t==="transparent")return{css:"transparent",rgba:0};if(!s||!n)throw new Error("css.toColor: Unsupported css format");if(s.fillStyle=n,s.fillStyle=t,typeof s.fillStyle!="string")throw new Error("css.toColor: Unsupported css format");if(s.fillRect(0,0,1,1),[b,_,I,p]=s.getImageData(0,0,1,1).data,p!==255)throw new Error("css.toColor: Unsupported css format");return{rgba:g.toRgba(b,_,I,p),css:t}}r.toColor=e})(x||={});var v;(e=>{function s(r){return n(r>>16&255,r>>8&255,r&255)}e.relativeLuminance=s;function n(r,t,u){let a=r/255,i=t/255,o=u/255,l=a<=.03928?a/12.92:Math.pow((a+.055)/1.055,2.4),f=i<=.03928?i/12.92:Math.pow((i+.055)/1.055,2.4),d=o<=.03928?o/12.92:Math.pow((o+.055)/1.055,2.4);return l*.2126+f*.7152+d*.0722}e.relativeLuminance2=n})(v||={});var w;(u=>{function s(a,i){if(p=(i&255)/255,p===1)return i;let o=i>>24&255,l=i>>16&255,f=i>>8&255,d=a>>24&255,c=a>>16&255,h=a>>8&255;return b=d+Math.round((o-d)*p),_=c+Math.round((l-c)*p),I=h+Math.round((f-h)*p),g.toRgba(b,_,I)}u.blend=s;function n(a,i,o){let l=v.relativeLuminance(a>>8),f=v.relativeLuminance(i>>8);if(R(l,f)>8));if(m>8));return m>E?C:B}return C}let c=r(a,i,o),h=R(l,v.relativeLuminance(c>>8));if(h>8));return h>m?c:C}return c}}u.ensureContrastRatio=n;function e(a,i,o){let l=a>>24&255,f=a>>16&255,d=a>>8&255,c=i>>24&255,h=i>>16&255,C=i>>8&255,m=R(v.relativeLuminance2(c,h,C),v.relativeLuminance2(l,f,d));for(;m0||h>0||C>0);)c-=Math.max(0,Math.ceil(c*.1)),h-=Math.max(0,Math.ceil(h*.1)),C-=Math.max(0,Math.ceil(C*.1)),m=R(v.relativeLuminance2(c,h,C),v.relativeLuminance2(l,f,d));return(c<<24|h<<16|C<<8|255)>>>0}u.reduceLuminance=e;function r(a,i,o){let l=a>>24&255,f=a>>16&255,d=a>>8&255,c=i>>24&255,h=i>>16&255,C=i>>8&255,m=R(v.relativeLuminance2(c,h,C),v.relativeLuminance2(l,f,d));for(;m>>0}u.increaseLuminance=r;function t(a){return[a>>24&255,a>>16&255,a>>8&255,a&255]}u.toChannels=t})(w||={});function L(s){let n=s.toString(16);return n.length<2?"0"+n:n}function R(s,n){return s{let s=[x.toColor("#2e3436"),x.toColor("#cc0000"),x.toColor("#4e9a06"),x.toColor("#c4a000"),x.toColor("#3465a4"),x.toColor("#75507b"),x.toColor("#06989a"),x.toColor("#d3d7cf"),x.toColor("#555753"),x.toColor("#ef2929"),x.toColor("#8ae234"),x.toColor("#fce94f"),x.toColor("#729fcf"),x.toColor("#ad7fa8"),x.toColor("#34e2e2"),x.toColor("#eeeeec")],n=[0,95,135,175,215,255];for(let e=0;e<216;e++){let r=n[e/36%6|0],t=n[e/6%6|0],u=n[e%6];s.push({css:g.toCss(r,t,u),rgba:g.toRgba(r,t,u)})}for(let e=0;e<24;e++){let r=8+e*10;s.push({css:g.toCss(r,r,r),rgba:g.toRgba(r,r,r)})}return s})());function N(s){return s.extended?.urlId??0}function U(s,n){if(!n)return"";let e=s._core?._oscLinkService?.getLinkData(n);return e?`\x1B]8;${e.id===void 0?"":`id=${e.id}`};${e.uri}\x1B\\`:""}function q(s){let n=s._core?._inputHandler?._curAttrData;return n?U(s,N(n)):""}function z(s,n){return Math.min(s.length,n)}function W(s,n,e,r){return n===e-1&&s.length>e&&r.getWidth()>1}var K=1<<22;function $(s){return s.content=K,s}function A(s,n,e){return Math.max(n,Math.min(s,e))}function X(s){switch(s){case"&":return"&";case"<":return"<"}return s}var S=class{constructor(n,e){this._buffer=n;this._cols=e}serialize(n,e){let r=this._buffer.getNullCell(),t=this._buffer.getNullCell(),u=r,a=n.start.y,i=n.end.y,o=n.start.x,l=n.end.x;this._beforeSerialize(i-a,a,i);for(let f=a;f<=i;f++){let d=this._buffer.getLine(f);if(d){let c=f===n.start.y?o:0,h=f===n.end.y?l:z(d,this._cols);for(let C=c;C0&&!F(this._cursorStyle,this._backgroundCell)&&(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._lastBackgroundCursorRow=this._lastCursorRow,this._lastBackgroundCursorCol=this._lastCursorCol);let t="";if(!r){e-this._firstRow>=this._terminal.rows&&this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol,this._backgroundCell);let u=this._buffer.getLine(e),a=this._buffer.getLine(e+1);if(!a.isWrapped)t=`\r ++`,this._lastCursorRow=e+1,this._lastCursorCol=0;else{t="";let i=z(u,this._terminal.cols),o=u.getCell(i-1,this._thisRowLastChar);W(u,i-1,this._terminal.cols,o)&&(o=$(o));let l=u.getCell(i-2,this._thisRowLastSecondChar),f=a.getCell(0,this._nextRowFirstChar),d=f.getWidth()>1,c=!1;if(f.getChars()&&(d?this._nullCellCount<=1:this._nullCellCount<=0)&&((o.getChars()||o.getWidth()===0)&&F(o,f)&&(c=!0),d&&(l.getChars()||l.getWidth()===0)&&F(o,f)&&F(l,f)&&(c=!0)),!c){if(t="-".repeat(this._nullCellCount+1),t+="\x1B[1D\x1B[1X",this._nullCellCount>0){t+="\x1B[A";let h=i-this._nullCellCount;h>0&&(t+=`\x1B[${h}C`),t+=`\x1B[${this._nullCellCount}X`,h>0&&(t+=`\x1B[${h}D`),t+="\x1B[B"}this._lastContentCursorRow=e+1,this._lastContentCursorCol=0,this._lastCursorRow=e+1,this._lastCursorCol=0}}}this._allRows[this._rowIndex]=this._currentRow,this._allRowSeparators[this._rowIndex++]=t,this._currentRow="",this._nullCellCount=0}_diffStyle(e,r){let t=[];if(y(e,r))return t;let u=!T(e,r),a=!F(e,r),i=!M(e,r);if(u||a||i)if(e.isAttributeDefault())r.isAttributeDefault()||t.push(0);else{if(u){let o=e.getFgColor();e.isFgRGB()?t.push(38,2,o>>>16&255,o>>>8&255,o&255):e.isFgPalette()?o>=16?t.push(38,5,o):t.push(o&8?90+(o&7):30+(o&7)):t.push(39)}if(a){let o=e.getBgColor();e.isBgRGB()?t.push(48,2,o>>>16&255,o>>>8&255,o&255):e.isBgPalette()?o>=16?t.push(48,5,o):t.push(o&8?100+(o&7):40+(o&7)):t.push(49)}if(i){e.isInverse()!==r.isInverse()&&t.push(e.isInverse()?7:27);let o=e.isBold()!==r.isBold(),l=e.isDim()!==r.isDim();if(o||l){let f=o&&!e.isBold()||l&&!e.isDim();f&&t.push(22),e.isBold()&&(o||f)&&t.push(1),e.isDim()&&(l||f)&&t.push(2)}if(P(e,r))e.isUnderline()!==r.isUnderline()&&t.push(e.isUnderline()?4:24);else{let f=e.getUnderlineStyle();if(f===0)t.push(24);else if(f===1&&e.isUnderlineColorDefault())t.push(4);else if(t.push("4:"+f),!e.isUnderlineColorDefault()){let d=e.getUnderlineColor();e.isUnderlineColorRGB()?t.push("58:2::"+(d>>>16&255)+":"+(d>>>8&255)+":"+(d&255)):t.push("58:5:"+d)}}e.isOverline()!==r.isOverline()&&t.push(e.isOverline()?53:55),e.isBlink()!==r.isBlink()&&t.push(e.isBlink()?5:25),e.isInvisible()!==r.isInvisible()&&t.push(e.isInvisible()?8:28),e.isItalic()!==r.isItalic()&&t.push(e.isItalic()?3:23),e.isStrikethrough()!==r.isStrikethrough()&&t.push(e.isStrikethrough()?9:29)}}return t}_setOscLink(e){if(e===this._activeOscLinkId)return"";let r=this._activeOscLinkId?"\x1B]8;;\x1B\\":"";this._activeOscLinkId=0;let t=U(this._terminal,e);return t&&(this._activeOscLinkId=e,r+=t),r}_nextCell(e,r,t,u){if(e.getWidth()===0)return;let i=e.getChars()==="",o=i&&e.isInverse()?this._buffer.getLine(t+1):void 0,l=o?.getCell(0,this._nextRowFirstChar),f=u===this._terminal.cols-1&&o?.isWrapped&&(l?.getWidth()??0)>1&&!!l&&y(e,l),d=i&&!!e.isInverse()&&!f,c=this._diffStyle(e,this._cursorStyle);if(i?d?c.length>0:!F(this._cursorStyle,e):c.length>0){this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)||(this._currentRow+=`\x1B[${this._nullCellCount}X`),this._currentRow+=`\x1B[${this._nullCellCount}C`,this._nullCellCount=0),this._lastContentCursorRow=this._lastCursorRow=t,this._lastContentCursorCol=this._lastCursorCol=u,this._currentRow+=`\x1B[${c.join(";")}m`;let C=this._buffer.getLine(t);C!==void 0&&(C.getCell(u,this._cursorStyle),this._cursorStyleRow=t,this._cursorStyleCol=u)}if(i&&!d)this._nullCellCount+=e.getWidth();else{if(this._nullCellCount>0&&(F(this._cursorStyle,this._backgroundCell)?this._currentRow+=`\x1B[${this._nullCellCount}C`:(this._currentRow+=`\x1B[${this._nullCellCount}X`,this._currentRow+=`\x1B[${this._nullCellCount}C`),this._nullCellCount=0),this._currentRow+=this._setOscLink(N(e)),d){let C=!!e.isUnderline()||!!e.isStrikethrough()||!!e.isOverline();if(C&&(this._currentRow+="\x1B[24;29;55m"),this._currentRow+=" ".repeat(e.getWidth()),C){let m=this._diffStyle(e,this._defaultCell);this._currentRow+=`\x1B[0m\x1B[${m.join(";")}m`}}else this._currentRow+=e.getChars();this._lastContentCursorRow=this._lastCursorRow=t,this._lastContentCursorCol=this._lastCursorCol=u+e.getWidth()}}_serializeString(e){let r=this._allRows.length;this._buffer.length-this._firstRow<=this._terminal.rows&&(this._lastBackgroundCursorRow>this._lastContentCursorRow&&this._buffer.cursorX{c>0?t+=`\x1B[${c}C`:c<0&&(t+=`\x1B[${-c}D`)};l&&((c=>{c>0?t+=`\x1B[${c}B`:c<0&&(t+=`\x1B[${-c}A`)})(i-this._lastCursorRow),f(o-this._lastCursorCol))}let u=this._terminal._core._inputHandler._curAttrData,a=this._diffStyle(u,this._cursorStyle);return a.length>0&&(t+=`\x1B[${a.join(";")}m`),t}},H=class{activate(n){this._terminal=n}_serializeBufferByScrollback(n,e,r){let t=e.length,u=r===void 0?t:A(r+n.rows,0,t);return this._serializeBufferByRange(n,e,{start:t-u,end:t-1},!1)}_serializeBufferByRange(n,e,r,t){return new D(e,n).serialize({start:{x:0,y:typeof r.start=="number"?r.start:r.start.line},end:{x:n.cols,y:typeof r.end=="number"?r.end:r.end.line}},t)}_serializeBufferAsHTML(n,e){let r=n.buffer.active,t=new k(r,n,e),u=e.onlySelection??!1,a=e.range;if(a)return t.serialize({start:{x:a.startCol,y:(typeof a.startLine=="number",a.startLine)},end:{x:n.cols,y:(typeof a.endLine=="number",a.endLine)}});if(!u){let o=r.length,l=e.scrollback,f=l===void 0?o:A(l+n.rows,0,o);return t.serialize({start:{x:0,y:o-f},end:{x:n.cols,y:o-1}})}let i=this._terminal?.getSelectionPosition();return i!==void 0?t.serialize({start:{x:i.start.x,y:i.start.y},end:{x:i.end.x,y:i.end.y}}):""}_serializeScrollRegion(n){let e=n._core.buffer,r=e.scrollTop,t=e.scrollBottom;return r!==0||t!==n.rows-1?`\x1B[${r+1};${t+1}r`:""}_serializeModes(n){let e="",r=n.modes;if(r.applicationCursorKeysMode&&(e+="\x1B[?1h"),r.applicationKeypadMode&&(e+="\x1B[?66h"),r.bracketedPasteMode&&(e+="\x1B[?2004h"),r.insertMode&&(e+="\x1B[4h"),r.originMode&&(e+="\x1B[?6h"),r.reverseWraparoundMode&&(e+="\x1B[?45h"),r.sendFocusMode&&(e+="\x1B[?1004h"),r.wraparoundMode===!1&&(e+="\x1B[?7l"),r.mouseTrackingMode!=="none")switch(r.mouseTrackingMode){case"x10":e+="\x1B[?9h";break;case"vt200":e+="\x1B[?1000h";break;case"drag":e+="\x1B[?1002h";break;case"any":e+="\x1B[?1003h";break}return r.showCursor||(e+="\x1B[?25l"),e}serialize(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");let e=n?.range?this._serializeBufferByRange(this._terminal,this._terminal.buffer.normal,n.range,!0):this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.normal,n?.scrollback);if(!n?.excludeAltBuffer&&this._terminal.buffer.active.type==="alternate"){let r=this._serializeBufferByScrollback(this._terminal,this._terminal.buffer.alternate,void 0);e+=`\x1B[?1049h\x1B[H${r}`}return n?.excludeModes||(e+=this._serializeModes(this._terminal),e+=this._serializeScrollRegion(this._terminal)),e+=q(this._terminal),e}serializeAsHTML(n){if(!this._terminal)throw new Error("Cannot use addon until it has been loaded");return this._serializeBufferAsHTML(this._terminal,n??{})}dispose(){}},k=class extends S{constructor(e,r,t){super(e,r.cols);this._terminal=r;this._options=t;this._currentRow="";this._htmlContent="";r._core._themeService?this._ansiColors=r._core._themeService.colors.ansi:this._ansiColors=O}_beforeSerialize(e,r,t){this._htmlContent+="
";let u="#000000",a="#ffffff";(this._options.includeGlobalBackground??!1)&&(u=this._terminal.options.theme?.foreground??"#ffffff",a=this._terminal.options.theme?.background??"#000000");let i=[];i.push("color: "+u+";"),i.push("background-color: "+a+";"),i.push("font-family: "+this._terminal.options.fontFamily+";"),i.push("font-size: "+this._terminal.options.fontSize+"px;"),this._htmlContent+="
"}_afterSerialize(){this._htmlContent+="
",this._htmlContent+="
"}_rowEnd(e,r){this._htmlContent+="
"+this._currentRow+"
",this._currentRow=""}_getHexColor(e,r){let t=r?e.getFgColor():e.getBgColor();if(r?e.isFgRGB():e.isBgRGB())return"#"+[t>>16&255,t>>8&255,t&255].map(a=>a.toString(16).padStart(2,"0")).join("");if(r?e.isFgPalette():e.isBgPalette())return this._ansiColors[t].css}_getUnderlineColor(e){if(e.isUnderlineColorDefault())return;let r=e.getUnderlineColor();return e.isUnderlineColorRGB()?"#"+[r>>16&255,r>>8&255,r&255].map(u=>u.toString(16).padStart(2,"0")).join(""):this._ansiColors[r].css}_getUnderlineStyle(e){switch(e.getUnderlineStyle()){case 1:return"underline";case 2:return"underline double";case 3:return"underline wavy";case 4:return"underline dotted";case 5:return"underline dashed";default:return"underline"}}_diffStyle(e,r){let t=[];if(y(e,r))return;let u=!T(e,r),a=!F(e,r),i=!M(e,r);if(u||a||i){let o=this._getHexColor(e,!0);o&&t.push("color: "+o+";");let l=this._getHexColor(e,!1);l&&t.push("background-color: "+l+";"),e.isInverse()&&t.push("color: #000000; background-color: #BFBFBF;"),e.isBold()&&t.push("font-weight: bold;");let f=[];if(e.isUnderline()&&f.push(this._getUnderlineStyle(e)),e.isOverline()&&f.push("overline"),e.isStrikethrough()&&f.push("line-through"),e.isBlink()&&f.push("blink"),f.length>0&&t.push("text-decoration: "+f.join(" ")+";"),e.isUnderline()){let d=this._getUnderlineColor(e);d&&t.push("text-decoration-color: "+d+";")}return e.isInvisible()&&t.push("visibility: hidden;"),e.isItalic()&&t.push("font-style: italic;"),e.isDim()&&t.push("opacity: 0.5;"),t}}_nextCell(e,r,t,u){if(e.getWidth()===0)return;let i=e.getChars()==="",o=this._diffStyle(e,r);o&&(this._currentRow+=o.length===0?"
":""),i?this._currentRow+=" ":this._currentRow+=X(e.getChars())}_serializeString(){return this._htmlContent}};export{k as HTMLSerializeHandler,H as SerializeAddon}; //# sourceMappingURL=addon-serialize.mjs.map diff --git a/lib/addon-serialize.mjs.map b/lib/addon-serialize.mjs.map -index e9357c67686de63dd29db518781758345aacdd0f..ea0eb0dac817d0d691fd3b1d5b4a58187430efac 100644 +index e9357c67686de63dd29db518781758345aacdd0f..5eadddd8600fcb33252dfa582a3bd0120b822d44 100644 --- a/lib/addon-serialize.mjs.map +++ b/lib/addon-serialize.mjs.map @@ -1,7 +1,7 @@ @@ -40,15 +40,23 @@ index e9357c67686de63dd29db518781758345aacdd0f..ea0eb0dac817d0d691fd3b1d5b4a5818 - "sourcesContent": ["/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: line.length;\n for (let col = startLineColumn; col < endLineColumn; col++) {\n const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!;\n const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n rowSeparator += `\\u001b[${currentLine.length - this._nullCellCount}C`;\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n rowSeparator += `\\u001b[${currentLine.length - this._nullCellCount}D`;\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n if (cell.isBold() !== oldCell.isBold()) { sgrSeq.push(cell.isBold() ? 1 : 22); }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n if (cell.isDim() !== oldCell.isDim()) { sgrSeq.push(cell.isDim() ? 2 : 22); }\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n // the empty cell style is only assumed to be changed when background changed, because\n // foreground is always 0.\n const styleChanged = isEmptyCell ? !equalBg(this._cursorStyle, cell) : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n this._currentRow += cell.getChars();\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"], - "mappings": ";;;;;;;;;;;;;;;;AAOA,IAAIA,EAAK,EACLC,EAAK,EACLC,EAAK,EACLC,EAAK,EAUF,IAAUC,MAAV,CACE,SAASC,EAAM,EAAWC,EAAWC,EAAWC,EAAoB,CACzE,OAAIA,IAAM,OACD,IAAIC,EAAY,CAAC,CAAC,GAAGA,EAAYH,CAAC,CAAC,GAAGG,EAAYF,CAAC,CAAC,GAAGE,EAAYD,CAAC,CAAC,GAEvE,IAAIC,EAAY,CAAC,CAAC,GAAGA,EAAYH,CAAC,CAAC,GAAGG,EAAYF,CAAC,CAAC,EAC7D,CALOH,EAAS,MAAAC,EAOT,SAASK,EAAO,EAAWJ,EAAWC,EAAWC,EAAY,IAAc,CAIhF,OAAQ,GAAK,GAAKF,GAAK,GAAKC,GAAK,EAAIC,KAAO,CAC9C,CALOJ,EAAS,OAAAM,EAOT,SAASC,EAAQ,EAAWL,EAAWC,EAAWC,EAAoB,CAC3E,MAAO,CACL,IAAKJ,EAAS,MAAM,EAAGE,EAAGC,EAAGC,CAAC,EAC9B,KAAMJ,EAAS,OAAO,EAAGE,EAAGC,EAAGC,CAAC,CAClC,CACF,CALOJ,EAAS,QAAAO,IAfDP,IAAA,IA0BV,IAAUQ,MAAV,CACE,SAASC,EAAMC,EAAYC,EAAoB,CAEpD,GADAC,GAAMD,EAAG,KAAO,KAAQ,IACpBC,IAAO,EACT,MAAO,CACL,IAAKD,EAAG,IACR,KAAMA,EAAG,IACX,EAEF,IAAME,EAAOF,EAAG,MAAQ,GAAM,IACxBG,EAAOH,EAAG,MAAQ,GAAM,IACxBI,EAAOJ,EAAG,MAAQ,EAAK,IACvBK,EAAON,EAAG,MAAQ,GAAM,IACxBO,EAAOP,EAAG,MAAQ,GAAM,IACxBQ,EAAOR,EAAG,MAAQ,EAAK,IAC7BS,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAOJ,CAAE,EACtCQ,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAOL,CAAE,EACtCS,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAON,CAAE,EACtC,IAAMU,EAAMtB,EAAS,MAAMmB,EAAIC,EAAIC,CAAE,EAC/BE,EAAOvB,EAAS,OAAOmB,EAAIC,EAAIC,CAAE,EACvC,MAAO,CAAE,IAAAC,EAAK,KAAAC,CAAK,CACrB,CApBOf,EAAS,MAAAC,EAsBT,SAASe,EAAShB,EAAwB,CAC/C,OAAQA,EAAM,KAAO,OAAU,GACjC,CAFOA,EAAS,SAAAgB,EAIT,SAASC,EAAoBf,EAAYC,EAAYe,EAAmC,CAC7F,IAAMC,EAASJ,EAAK,oBAAoBb,EAAG,KAAMC,EAAG,KAAMe,CAAK,EAC/D,GAAKC,EAGL,OAAO3B,EAAS,QACb2B,GAAU,GAAK,IACfA,GAAU,GAAK,IACfA,GAAU,EAAK,GAClB,CACF,CAVOnB,EAAS,oBAAAiB,EAYT,SAASG,EAAOpB,EAAuB,CAC5C,IAAMqB,GAAarB,EAAM,KAAO,OAAU,EAC1C,OAACW,EAAIC,EAAIC,CAAE,EAAIE,EAAK,WAAWM,CAAS,EACjC,CACL,IAAK7B,EAAS,MAAMmB,EAAIC,EAAIC,CAAE,EAC9B,KAAMQ,CACR,CACF,CAPOrB,EAAS,OAAAoB,EAST,SAASE,EAAQtB,EAAesB,EAAyB,CAC9D,OAAAlB,EAAK,KAAK,MAAMkB,EAAU,GAAI,EAC9B,CAACX,EAAIC,EAAIC,CAAE,EAAIE,EAAK,WAAWf,EAAM,IAAI,EAClC,CACL,IAAKR,EAAS,MAAMmB,EAAIC,EAAIC,EAAIT,CAAE,EAClC,KAAMZ,EAAS,OAAOmB,EAAIC,EAAIC,EAAIT,CAAE,CACtC,CACF,CAPOJ,EAAS,QAAAsB,EAST,SAASC,EAAgBvB,EAAewB,EAAwB,CACrE,OAAApB,EAAKJ,EAAM,KAAO,IACXsB,EAAQtB,EAAQI,EAAKoB,EAAU,GAAI,CAC5C,CAHOxB,EAAS,gBAAAuB,EAKT,SAASE,EAAWzB,EAA0B,CACnD,MAAO,CAAEA,EAAM,MAAQ,GAAM,IAAOA,EAAM,MAAQ,GAAM,IAAOA,EAAM,MAAQ,EAAK,GAAI,CACxF,CAFOA,EAAS,WAAAyB,IA9DDzB,IAAA,IAuEV,IAAUc,MAAV,CAEL,IAAIY,EACAC,EACJ,GAAI,CAEF,IAAMC,EAAS,SAAS,cAAc,QAAQ,EAC9CA,EAAO,MAAQ,EACfA,EAAO,OAAS,EAChB,IAAMC,EAAMD,EAAO,WAAW,KAAM,CAClC,mBAAoB,EACtB,CAAC,EACGC,IACFH,EAAOG,EACPH,EAAK,yBAA2B,OAChCC,EAAeD,EAAK,qBAAqB,EAAG,EAAG,EAAG,CAAC,EAEvD,MACM,CAEN,CASO,SAAS3B,EAAQe,EAAqB,CAE3C,GAAIA,EAAI,MAAM,gBAAgB,EAC5B,OAAQA,EAAI,OAAQ,CAClB,IAAK,GACH,OAAAH,EAAK,SAASG,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EAC3CF,EAAK,SAASE,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EAC3CD,EAAK,SAASC,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EACpCtB,EAAS,QAAQmB,EAAIC,EAAIC,CAAE,EAEpC,IAAK,GACH,OAAAF,EAAK,SAASG,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EAC3CF,EAAK,SAASE,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EAC3CD,EAAK,SAASC,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EAC3CV,EAAK,SAASU,EAAI,MAAM,EAAG,CAAC,EAAE,OAAO,CAAC,EAAG,EAAE,EACpCtB,EAAS,QAAQmB,EAAIC,EAAIC,EAAIT,CAAE,EAExC,IAAK,GACH,MAAO,CACL,IAAAU,EACA,MAAO,SAASA,EAAI,MAAM,CAAC,EAAG,EAAE,GAAK,EAAI,OAAU,CACrD,EACF,IAAK,GACH,MAAO,CACL,IAAAA,EACA,KAAM,SAASA,EAAI,MAAM,CAAC,EAAG,EAAE,IAAM,CACvC,CACJ,CAIF,IAAMgB,EAAYhB,EAAI,MAAM,oFAAoF,EAChH,GAAIgB,EACF,OAAAnB,EAAK,SAASmB,EAAU,CAAC,EAAG,EAAE,EAC9BlB,EAAK,SAASkB,EAAU,CAAC,EAAG,EAAE,EAC9BjB,EAAK,SAASiB,EAAU,CAAC,EAAG,EAAE,EAC9B1B,EAAK,KAAK,OAAO0B,EAAU,CAAC,IAAM,OAAY,EAAI,WAAWA,EAAU,CAAC,CAAC,GAAK,GAAI,EAC3EtC,EAAS,QAAQmB,EAAIC,EAAIC,EAAIT,CAAE,EAIxC,GAAIU,IAAQ,cACV,MAAO,CACL,IAAK,cACL,KAAM,CACR,EAIF,GAAI,CAACY,GAAQ,CAACC,EACZ,MAAM,IAAI,MAAM,qCAAqC,EAOvD,GAFAD,EAAK,UAAYC,EACjBD,EAAK,UAAYZ,EACb,OAAOY,EAAK,WAAc,SAC5B,MAAM,IAAI,MAAM,qCAAqC,EAOvD,GAJAA,EAAK,SAAS,EAAG,EAAG,EAAG,CAAC,EACxB,CAACf,EAAIC,EAAIC,EAAIT,CAAE,EAAIsB,EAAK,aAAa,EAAG,EAAG,EAAG,CAAC,EAAE,KAG7CtB,IAAO,IACT,MAAM,IAAI,MAAM,qCAAqC,EAMvD,MAAO,CACL,KAAMZ,EAAS,OAAOmB,EAAIC,EAAIC,EAAIT,CAAE,EACpC,IAAAU,CACF,CACF,CA5EOA,EAAS,QAAAf,IA7BDe,IAAA,IA+GV,IAAUiB,MAAV,CAOE,SAASC,EAAkBD,EAAqB,CACrD,OAAOE,EACJF,GAAO,GAAM,IACbA,GAAO,EAAM,IACbA,EAAa,GAAI,CACtB,CALOA,EAAS,kBAAAC,EAeT,SAASC,EAAmBC,EAAWxC,EAAWC,EAAmB,CAC1E,IAAMwC,EAAKD,EAAI,IACTE,EAAK1C,EAAI,IACT2C,EAAK1C,EAAI,IACT2C,EAAKH,GAAM,OAAUA,EAAK,MAAQ,KAAK,KAAKA,EAAK,MAAS,MAAO,GAAG,EACpEI,EAAKH,GAAM,OAAUA,EAAK,MAAQ,KAAK,KAAKA,EAAK,MAAS,MAAO,GAAG,EACpEI,EAAKH,GAAM,OAAUA,EAAK,MAAQ,KAAK,KAAKA,EAAK,MAAS,MAAO,GAAG,EAC1E,OAAOC,EAAK,MAASC,EAAK,MAASC,EAAK,KAC1C,CAROT,EAAS,mBAAAE,IAtBDF,IAAA,IAoCV,IAAUhB,MAAV,CACE,SAASd,EAAMC,EAAYC,EAAoB,CAEpD,GADAC,GAAMD,EAAK,KAAQ,IACfC,IAAO,EACT,OAAOD,EAET,IAAME,EAAOF,GAAM,GAAM,IACnBG,EAAOH,GAAM,GAAM,IACnBI,EAAOJ,GAAM,EAAK,IAClBK,EAAON,GAAM,GAAM,IACnBO,EAAOP,GAAM,GAAM,IACnBQ,EAAOR,GAAM,EAAK,IACxB,OAAAS,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAOJ,CAAE,EACtCQ,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAOL,CAAE,EACtCS,EAAKH,EAAM,KAAK,OAAOH,EAAMG,GAAON,CAAE,EAC/BZ,EAAS,OAAOmB,EAAIC,EAAIC,CAAE,CACnC,CAfOE,EAAS,MAAAd,EA8BT,SAASgB,EAAoBwB,EAAgBC,EAAgBxB,EAAmC,CACrG,IAAMyB,EAAMZ,EAAI,kBAAkBU,GAAU,CAAC,EACvCG,EAAMb,EAAI,kBAAkBW,GAAU,CAAC,EAE7C,GADWG,EAAcF,EAAKC,CAAG,EACxB1B,EAAO,CACd,GAAI0B,EAAMD,EAAK,CACb,IAAMG,EAAUC,EAAgBN,EAAQC,EAAQxB,CAAK,EAC/C8B,EAAeH,EAAcF,EAAKZ,EAAI,kBAAkBe,GAAW,CAAC,CAAC,EAC3E,GAAIE,EAAe9B,EAAO,CACxB,IAAM+B,EAAUC,EAAkBT,EAAQC,EAAQxB,CAAK,EACjDiC,EAAeN,EAAcF,EAAKZ,EAAI,kBAAkBkB,GAAW,CAAC,CAAC,EAC3E,OAAOD,EAAeG,EAAeL,EAAUG,CACjD,CACA,OAAOH,CACT,CACA,IAAMA,EAAUI,EAAkBT,EAAQC,EAAQxB,CAAK,EACjD8B,EAAeH,EAAcF,EAAKZ,EAAI,kBAAkBe,GAAW,CAAC,CAAC,EAC3E,GAAIE,EAAe9B,EAAO,CACxB,IAAM+B,EAAUF,EAAgBN,EAAQC,EAAQxB,CAAK,EAC/CiC,EAAeN,EAAcF,EAAKZ,EAAI,kBAAkBkB,GAAW,CAAC,CAAC,EAC3E,OAAOD,EAAeG,EAAeL,EAAUG,CACjD,CACA,OAAOH,CACT,CAEF,CAzBO/B,EAAS,oBAAAE,EA2BT,SAAS8B,EAAgBN,EAAgBC,EAAgBxB,EAAuB,CAGrF,IAAMV,EAAOiC,GAAU,GAAM,IACvBhC,EAAOgC,GAAU,GAAM,IACvB/B,EAAO+B,GAAW,EAAK,IACzBpC,EAAOqC,GAAU,GAAM,IACvBpC,EAAOoC,GAAU,GAAM,IACvBnC,EAAOmC,GAAW,EAAK,IACvBU,EAAKP,EAAcd,EAAI,mBAAmB1B,EAAKC,EAAKC,CAAG,EAAGwB,EAAI,mBAAmBvB,EAAKC,EAAKC,CAAG,CAAC,EACnG,KAAO0C,EAAKlC,IAAUb,EAAM,GAAKC,EAAM,GAAKC,EAAM,IAEhDF,GAAO,KAAK,IAAI,EAAG,KAAK,KAAKA,EAAM,EAAG,CAAC,EACvCC,GAAO,KAAK,IAAI,EAAG,KAAK,KAAKA,EAAM,EAAG,CAAC,EACvCC,GAAO,KAAK,IAAI,EAAG,KAAK,KAAKA,EAAM,EAAG,CAAC,EACvC6C,EAAKP,EAAcd,EAAI,mBAAmB1B,EAAKC,EAAKC,CAAG,EAAGwB,EAAI,mBAAmBvB,EAAKC,EAAKC,CAAG,CAAC,EAEjG,OAAQL,GAAO,GAAKC,GAAO,GAAKC,GAAO,EAAI,OAAU,CACvD,CAlBOQ,EAAS,gBAAAgC,EAoBT,SAASG,EAAkBT,EAAgBC,EAAgBxB,EAAuB,CAGvF,IAAMV,EAAOiC,GAAU,GAAM,IACvBhC,EAAOgC,GAAU,GAAM,IACvB/B,EAAO+B,GAAW,EAAK,IACzBpC,EAAOqC,GAAU,GAAM,IACvBpC,EAAOoC,GAAU,GAAM,IACvBnC,EAAOmC,GAAW,EAAK,IACvBU,EAAKP,EAAcd,EAAI,mBAAmB1B,EAAKC,EAAKC,CAAG,EAAGwB,EAAI,mBAAmBvB,EAAKC,EAAKC,CAAG,CAAC,EACnG,KAAO0C,EAAKlC,IAAUb,EAAM,KAAQC,EAAM,KAAQC,EAAM,MAEtDF,EAAM,KAAK,IAAI,IAAMA,EAAM,KAAK,MAAM,IAAMA,GAAO,EAAG,CAAC,EACvDC,EAAM,KAAK,IAAI,IAAMA,EAAM,KAAK,MAAM,IAAMA,GAAO,EAAG,CAAC,EACvDC,EAAM,KAAK,IAAI,IAAMA,EAAM,KAAK,MAAM,IAAMA,GAAO,EAAG,CAAC,EACvD6C,EAAKP,EAAcd,EAAI,mBAAmB1B,EAAKC,EAAKC,CAAG,EAAGwB,EAAI,mBAAmBvB,EAAKC,EAAKC,CAAG,CAAC,EAEjG,OAAQL,GAAO,GAAKC,GAAO,GAAKC,GAAO,EAAI,OAAU,CACvD,CAlBOQ,EAAS,kBAAAmC,EAoBT,SAASG,EAAWC,EAAiD,CAC1E,MAAO,CAAEA,GAAS,GAAM,IAAOA,GAAS,GAAM,IAAOA,GAAS,EAAK,IAAMA,EAAQ,GAAI,CACvF,CAFOvC,EAAS,WAAAsC,IAlGDtC,IAAA,IAuGV,SAASlB,EAAY0D,EAAmB,CAC7C,IAAMC,EAAID,EAAE,SAAS,EAAE,EACvB,OAAOC,EAAE,OAAS,EAAI,IAAMA,EAAIA,CAClC,CAQO,SAASX,EAAcY,EAAYC,EAAoB,CAC5D,OAAID,EAAKC,GACCA,EAAK,MAASD,EAAK,MAErBA,EAAK,MAASC,EAAK,IAC7B,CCzMO,IAAMC,EAAsB,OAAO,QAAQ,IAAM,CACtD,IAAMC,EAAS,CAEbC,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EAErBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,EACrBA,EAAI,QAAQ,SAAS,CACvB,EAIMC,EAAI,CAAC,EAAM,GAAM,IAAM,IAAM,IAAM,GAAI,EAC7C,QAASC,EAAI,EAAGA,EAAI,IAAKA,IAAK,CAC5B,IAAMC,EAAIF,EAAGC,EAAI,GAAM,EAAI,CAAC,EACtBE,EAAIH,EAAGC,EAAI,EAAK,EAAI,CAAC,EACrBG,EAAIJ,EAAEC,EAAI,CAAC,EACjBH,EAAO,KAAK,CACV,IAAKO,EAAS,MAAMH,EAAGC,EAAGC,CAAC,EAC3B,KAAMC,EAAS,OAAOH,EAAGC,EAAGC,CAAC,CAC/B,CAAC,CACH,CAGA,QAASH,EAAI,EAAGA,EAAI,GAAIA,IAAK,CAC3B,IAAMK,EAAI,EAAIL,EAAI,GAClBH,EAAO,KAAK,CACV,IAAKO,EAAS,MAAMC,EAAGA,EAAGA,CAAC,EAC3B,KAAMD,EAAS,OAAOC,EAAGA,EAAGA,CAAC,CAC/B,CAAC,CACH,CAEA,OAAOR,CACT,GAAG,CAAC,ECrNJ,SAASS,EAAUC,EAAeC,EAAaC,EAAsB,CACnE,OAAO,KAAK,IAAID,EAAK,KAAK,IAAID,EAAOE,CAAI,CAAC,CAC5C,CAEA,SAASC,EAAeC,EAAmB,CACzC,OAAQA,EAAG,CACT,IAAK,IAAK,MAAO,QACjB,IAAK,IAAK,MAAO,MACnB,CACA,OAAOA,CACT,CAGA,IAAeC,EAAf,KAAoC,CAClC,YACqBC,EACnB,CADmB,aAAAA,CAErB,CAEO,UAAUC,EAAqBC,EAA8C,CAElF,IAAMC,EAAQ,KAAK,QAAQ,YAAY,EACjCC,EAAQ,KAAK,QAAQ,YAAY,EACnCC,EAAUF,EAERG,EAAWL,EAAM,MAAM,EACvBM,EAASN,EAAM,IAAI,EACnBO,EAAcP,EAAM,MAAM,EAC1BQ,EAAYR,EAAM,IAAI,EAE5B,KAAK,iBAAiBM,EAASD,EAAUA,EAAUC,CAAM,EAEzD,QAASG,EAAMJ,EAAUI,GAAOH,EAAQG,IAAO,CAC7C,IAAMC,EAAO,KAAK,QAAQ,QAAQD,CAAG,EACrC,GAAIC,EAAM,CACR,IAAMC,EAAkBF,IAAQT,EAAM,MAAM,EAAIO,EAAc,EACxDK,EAAgBH,IAAQT,EAAM,IAAI,EAAIQ,EAAWE,EAAK,OAC5D,QAASG,EAAMF,EAAiBE,EAAMD,EAAeC,IAAO,CAC1D,IAAMhB,EAAIa,EAAK,QAAQG,EAAKT,IAAYF,EAAQC,EAAQD,CAAK,EAC7D,GAAI,CAACL,EAAG,CACN,QAAQ,KAAK,yBAAyBY,CAAG,SAASI,CAAG,EAAE,EACvD,QACF,CACA,KAAK,UAAUhB,EAAGO,EAASK,EAAKI,CAAG,EACnCT,EAAUP,CACZ,CACF,CACA,KAAK,QAAQY,EAAKA,IAAQH,CAAM,CAClC,CAEA,YAAK,gBAAgB,EAEd,KAAK,iBAAiBL,CAA0B,CACzD,CAEU,UAAUa,EAAmBV,EAAsBK,EAAaI,EAAmB,CAAE,CACrF,QAAQJ,EAAaM,EAA0B,CAAE,CACjD,iBAAiBC,EAAcX,EAAkBC,EAAsB,CAAE,CACzE,iBAAwB,CAAE,CAC1B,iBAAiBL,EAA8C,CAAE,MAAO,EAAI,CACxF,EAEA,SAASgB,EAAQf,EAAqCC,EAA6B,CACjF,OAAOD,EAAM,eAAe,IAAMC,EAAM,eAAe,GAClDD,EAAM,WAAW,IAAMC,EAAM,WAAW,CAC/C,CAEA,SAASe,EAAQhB,EAAqCC,EAA6B,CACjF,OAAOD,EAAM,eAAe,IAAMC,EAAM,eAAe,GAClDD,EAAM,WAAW,IAAMC,EAAM,WAAW,CAC/C,CAEA,SAASgB,EAAejB,EAAqCC,EAA6B,CAGxF,GAAI,CAACD,EAAM,YAAY,GAAK,CAACC,EAAM,YAAY,EAC7C,MAAO,GAET,GAAID,EAAM,kBAAkB,IAAMC,EAAM,kBAAkB,EACxD,MAAO,GAET,IAAMiB,EAAelB,EAAM,wBAAwB,EAC7CmB,EAAelB,EAAM,wBAAwB,EACnD,OAAIiB,GAAgBC,EACX,GAELD,IAAiBC,EACZ,GAEFnB,EAAM,kBAAkB,IAAMC,EAAM,kBAAkB,GACxDD,EAAM,sBAAsB,IAAMC,EAAM,sBAAsB,CACrE,CAEA,SAASmB,EAAWpB,EAAqCC,EAA6B,CACpF,OAAOD,EAAM,UAAU,IAAMC,EAAM,UAAU,GACxCD,EAAM,OAAO,IAAMC,EAAM,OAAO,GAChCD,EAAM,YAAY,IAAMC,EAAM,YAAY,GAC1CgB,EAAejB,EAAOC,CAAK,GAC3BD,EAAM,WAAW,IAAMC,EAAM,WAAW,GACxCD,EAAM,QAAQ,IAAMC,EAAM,QAAQ,GAClCD,EAAM,YAAY,IAAMC,EAAM,YAAY,GAC1CD,EAAM,SAAS,IAAMC,EAAM,SAAS,GACpCD,EAAM,MAAM,IAAMC,EAAM,MAAM,GAC9BD,EAAM,gBAAgB,IAAMC,EAAM,gBAAgB,CACzD,CAEA,SAASoB,EAAiBrB,EAAqCC,EAA6B,CAC1F,IAAMqB,EAAoBtB,EAC1B,OAAI,OAAOsB,EAAkB,kBAAqB,WACzCA,EAAkB,iBAAiBrB,CAAK,EAE1Cc,EAAQf,EAAOC,CAAK,GACtBe,EAAQhB,EAAOC,CAAK,GACpBmB,EAAWpB,EAAOC,CAAK,CAC9B,CAEA,IAAMsB,EAAN,cAAqC3B,CAAqB,CA2BxD,YACE4B,EACiBC,EACjB,CACA,MAAMD,CAAM,EAFK,eAAAC,EA5BnB,KAAQ,UAAoB,EAC5B,KAAQ,SAAqB,IAAI,MACjC,KAAQ,kBAA8B,IAAI,MAC1C,KAAQ,YAAsB,GAC9B,KAAQ,eAAyB,EAKjC,KAAQ,aAA4B,KAAK,QAAQ,YAAY,EAK7D,KAAQ,gBAA0B,EAClC,KAAQ,gBAA0B,EAGlC,KAAQ,gBAA+B,KAAK,QAAQ,YAAY,EAEhE,KAAQ,UAAoB,EAC5B,KAAQ,eAAyB,EACjC,KAAQ,eAAyB,EACjC,KAAQ,sBAAgC,EACxC,KAAQ,sBAAgC,EAgBxC,KAAQ,iBAAgC,KAAK,QAAQ,YAAY,EACjE,KAAQ,uBAAsC,KAAK,QAAQ,YAAY,EACvE,KAAQ,kBAAiC,KAAK,QAAQ,YAAY,CAXlE,CAEU,iBAAiBX,EAAcY,EAAeC,EAAmB,CACzE,KAAK,SAAW,IAAI,MAAcb,CAAI,EACtC,KAAK,sBAAwBY,EAC7B,KAAK,eAAiBA,EACtB,KAAK,UAAYA,CACnB,CAKU,QAAQnB,EAAaM,EAA0B,CAGnD,KAAK,eAAiB,GAAK,CAACG,EAAQ,KAAK,aAAc,KAAK,eAAe,IAE7E,KAAK,aAAe,QAAU,KAAK,cAAc,KAGnD,IAAIY,EAAe,GAGnB,GAAI,CAACf,EAAW,CAEVN,EAAM,KAAK,WAAa,KAAK,UAAU,MACzC,KAAK,QAAQ,QAAQ,KAAK,eAAe,GAAG,QAAQ,KAAK,gBAAiB,KAAK,eAAe,EAIhG,IAAMsB,EAAc,KAAK,QAAQ,QAAQtB,CAAG,EAEtCuB,EAAW,KAAK,QAAQ,QAAQvB,EAAM,CAAC,EAE7C,GAAI,CAACuB,EAAS,UAEZF,EAAe;AAAA,EAEf,KAAK,eAAiBrB,EAAM,EAC5B,KAAK,eAAiB,MACjB,CACLqB,EAAe,GACf,IAAMG,EAAkBF,EAAY,QAAQA,EAAY,OAAS,EAAG,KAAK,gBAAgB,EACnFG,EAAwBH,EAAY,QAAQA,EAAY,OAAS,EAAG,KAAK,sBAAsB,EAC/FI,EAAmBH,EAAS,QAAQ,EAAG,KAAK,iBAAiB,EAC7DI,EAAgCD,EAAiB,SAAS,EAAI,EAIhEE,EAAU,IAIZF,EAAiB,SAAS,GACxBC,EAAgC,KAAK,gBAAkB,EAAI,KAAK,gBAAkB,MAKjFH,EAAgB,SAAS,GAAKA,EAAgB,SAAS,IAAM,IAG9Df,EAAQe,EAAiBE,CAAgB,IAEzCE,EAAU,IAMVD,IACCF,EAAsB,SAAS,GAAKA,EAAsB,SAAS,IAAM,IAG1EhB,EAAQe,EAAiBE,CAAgB,GACzCjB,EAAQgB,EAAuBC,CAAgB,IAE/CE,EAAU,KAITA,IAGHP,EAAe,IAAI,OAAO,KAAK,eAAiB,CAAC,EAEjDA,GAAgB,iBAEZ,KAAK,eAAiB,IAExBA,GAAgB,SAChBA,GAAgB,QAAUC,EAAY,OAAS,KAAK,cAAc,IAClED,GAAgB,QAAU,KAAK,cAAc,IAC7CA,GAAgB,QAAUC,EAAY,OAAS,KAAK,cAAc,IAClED,GAAgB,UAKlB,KAAK,sBAAwBrB,EAAM,EACnC,KAAK,sBAAwB,EAG7B,KAAK,eAAiBA,EAAM,EAC5B,KAAK,eAAiB,EAE1B,CACF,CAEA,KAAK,SAAS,KAAK,SAAS,EAAI,KAAK,YACrC,KAAK,kBAAkB,KAAK,WAAW,EAAIqB,EAC3C,KAAK,YAAc,GACnB,KAAK,eAAiB,CACxB,CAEQ,WAAWhB,EAAoCV,EAAgC,CACrF,IAAMkC,EAAmB,CAAC,EAC1B,GAAIf,EAAiBT,EAAMV,CAAO,EAChC,OAAOkC,EAET,IAAMC,EAAY,CAACtB,EAAQH,EAAMV,CAAO,EAClCoC,EAAY,CAACtB,EAAQJ,EAAMV,CAAO,EAClCqC,EAAe,CAACnB,EAAWR,EAAMV,CAAO,EAE9C,GAAImC,GAAaC,GAAaC,EAC5B,GAAI3B,EAAK,mBAAmB,EACrBV,EAAQ,mBAAmB,GAC9BkC,EAAO,KAAK,CAAC,MAEV,CACL,GAAIC,EAAW,CACb,IAAMG,EAAQ5B,EAAK,WAAW,EAC1BA,EAAK,QAAQ,EAAKwB,EAAO,KAAK,GAAI,EAAII,IAAU,GAAM,IAAOA,IAAU,EAAK,IAAMA,EAAQ,GAAI,EACzF5B,EAAK,YAAY,EACpB4B,GAAS,GAAMJ,EAAO,KAAK,GAAI,EAAGI,CAAK,EACpCJ,EAAO,KAAKI,EAAQ,EAAI,IAAMA,EAAQ,GAAK,IAAMA,EAAQ,EAAE,EAE7DJ,EAAO,KAAK,EAAE,CACvB,CACA,GAAIE,EAAW,CACb,IAAME,EAAQ5B,EAAK,WAAW,EAC1BA,EAAK,QAAQ,EAAKwB,EAAO,KAAK,GAAI,EAAII,IAAU,GAAM,IAAOA,IAAU,EAAK,IAAMA,EAAQ,GAAI,EACzF5B,EAAK,YAAY,EACpB4B,GAAS,GAAMJ,EAAO,KAAK,GAAI,EAAGI,CAAK,EACpCJ,EAAO,KAAKI,EAAQ,EAAI,KAAOA,EAAQ,GAAK,IAAMA,EAAQ,EAAE,EAE9DJ,EAAO,KAAK,EAAE,CACvB,CACA,GAAIG,EAAc,CAGhB,GAFI3B,EAAK,UAAU,IAAMV,EAAQ,UAAU,GAAKkC,EAAO,KAAKxB,EAAK,UAAU,EAAI,EAAI,EAAE,EACjFA,EAAK,OAAO,IAAMV,EAAQ,OAAO,GAAKkC,EAAO,KAAKxB,EAAK,OAAO,EAAI,EAAI,EAAE,EACvEK,EAAeL,EAAMV,CAAO,EAmBtBU,EAAK,YAAY,IAAMV,EAAQ,YAAY,GACpDkC,EAAO,KAAKxB,EAAK,YAAY,EAAI,EAAI,EAAE,MApBL,CAClC,IAAM6B,EAAQ7B,EAAK,kBAAkB,EACrC,GAAI6B,IAAU,EACZL,EAAO,KAAK,EAAE,UACLK,IAAU,GAAyB7B,EAAK,wBAAwB,EACzEwB,EAAO,KAAK,CAAC,UAGbA,EAAO,KAAK,KAAOK,CAA0B,EAEzC,CAAC7B,EAAK,wBAAwB,EAAG,CACnC,IAAM4B,EAAQ5B,EAAK,kBAAkB,EACjCA,EAAK,oBAAoB,EAC3BwB,EAAO,KAAK,UAAaI,IAAU,GAAM,KAAQ,KAAQA,IAAU,EAAK,KAAQ,KAAOA,EAAQ,IAA0B,EAEzHJ,EAAO,KAAK,QAAUI,CAA0B,CAEpD,CAEJ,CAGI5B,EAAK,WAAW,IAAMV,EAAQ,WAAW,GAAKkC,EAAO,KAAKxB,EAAK,WAAW,EAAI,GAAK,EAAE,EACrFA,EAAK,QAAQ,IAAMV,EAAQ,QAAQ,GAAKkC,EAAO,KAAKxB,EAAK,QAAQ,EAAI,EAAI,EAAE,EAC3EA,EAAK,YAAY,IAAMV,EAAQ,YAAY,GAAKkC,EAAO,KAAKxB,EAAK,YAAY,EAAI,EAAI,EAAE,EACvFA,EAAK,SAAS,IAAMV,EAAQ,SAAS,GAAKkC,EAAO,KAAKxB,EAAK,SAAS,EAAI,EAAI,EAAE,EAC9EA,EAAK,MAAM,IAAMV,EAAQ,MAAM,GAAKkC,EAAO,KAAKxB,EAAK,MAAM,EAAI,EAAI,EAAE,EACrEA,EAAK,gBAAgB,IAAMV,EAAQ,gBAAgB,GAAKkC,EAAO,KAAKxB,EAAK,gBAAgB,EAAI,EAAI,EAAE,CACzG,CACF,CAGF,OAAOwB,CACT,CAEU,UAAUxB,EAAmBV,EAAsBK,EAAaI,EAAmB,CAI3F,GAF0BC,EAAK,SAAS,IAAM,EAG5C,OAIF,IAAM8B,EAAc9B,EAAK,SAAS,IAAM,GAElCwB,EAAS,KAAK,WAAWxB,EAAM,KAAK,YAAY,EAStD,GALqB8B,EAAc,CAAC1B,EAAQ,KAAK,aAAcJ,CAAI,EAAIwB,EAAO,OAAS,EAKrE,CAEZ,KAAK,eAAiB,IAEnBpB,EAAQ,KAAK,aAAc,KAAK,eAAe,IAClD,KAAK,aAAe,QAAU,KAAK,cAAc,KAGnD,KAAK,aAAe,QAAU,KAAK,cAAc,IACjD,KAAK,eAAiB,GAGxB,KAAK,sBAAwB,KAAK,eAAiBT,EACnD,KAAK,sBAAwB,KAAK,eAAiBI,EAEnD,KAAK,aAAe,QAAUyB,EAAO,KAAK,GAAG,CAAC,IAG9C,IAAM5B,EAAO,KAAK,QAAQ,QAAQD,CAAG,EACjCC,IAAS,SACXA,EAAK,QAAQG,EAAK,KAAK,YAAY,EACnC,KAAK,gBAAkBJ,EACvB,KAAK,gBAAkBI,EAE3B,CAKI+B,EACF,KAAK,gBAAkB9B,EAAK,SAAS,GAEjC,KAAK,eAAiB,IAIpBI,EAAQ,KAAK,aAAc,KAAK,eAAe,EACjD,KAAK,aAAe,QAAU,KAAK,cAAc,KAEjD,KAAK,aAAe,QAAU,KAAK,cAAc,IACjD,KAAK,aAAe,QAAU,KAAK,cAAc,KAEnD,KAAK,eAAiB,GAGxB,KAAK,aAAeJ,EAAK,SAAS,EAGlC,KAAK,sBAAwB,KAAK,eAAiBL,EACnD,KAAK,sBAAwB,KAAK,eAAiBI,EAAMC,EAAK,SAAS,EAE3E,CAEU,iBAAiBb,EAA6C,CACtE,IAAI4C,EAAS,KAAK,SAAS,OAIvB,KAAK,QAAQ,OAAS,KAAK,WAAa,KAAK,UAAU,OACzDA,EAAS,KAAK,sBAAwB,EAAI,KAAK,UAC/C,KAAK,eAAiB,KAAK,sBAC3B,KAAK,eAAiB,KAAK,uBAG7B,IAAIC,EAAU,GAEd,QAAS,EAAI,EAAG,EAAID,EAAQ,IAC1BC,GAAW,KAAK,SAAS,CAAC,EACtB,EAAI,EAAID,IACVC,GAAW,KAAK,kBAAkB,CAAC,GAKvC,GAAI,CAAC7C,EAA4B,CAC/B,IAAM8C,EAAgB,KAAK,QAAQ,MAAQ,KAAK,QAAQ,QAClDC,EAAgB,KAAK,QAAQ,QAE7BC,EAAeF,IAAkB,KAAK,gBAAkBC,IAAkB,KAAK,eAE/EE,EAAaC,GAAyB,CACtCA,EAAS,EACXL,GAAW,QAAUK,CAAM,IAClBA,EAAS,IAClBL,GAAW,QAAU,CAACK,CAAM,IAEhC,EASIF,KARcE,GAAyB,CACrCA,EAAS,EACXL,GAAW,QAAUK,CAAM,IAClBA,EAAS,IAClBL,GAAW,QAAU,CAACK,CAAM,IAEhC,GAGWJ,EAAgB,KAAK,cAAc,EAC5CG,EAAUF,EAAgB,KAAK,cAAc,EAEjD,CAKA,IAAMI,EAA+B,KAAK,UAAkB,MAAM,cAAc,aAC1Ed,EAAS,KAAK,WAAWc,EAAa,KAAK,YAAY,EAC7D,OAAId,EAAO,OAAS,IAClBQ,GAAW,QAAUR,EAAO,KAAK,GAAG,CAAC,KAGhCQ,CACT,CACF,EAEaO,EAAN,KAA8D,CAG5D,SAASC,EAA0B,CACxC,KAAK,UAAYA,CACnB,CAEQ,6BAA6BA,EAAoB5B,EAAiB6B,EAA6B,CACrG,IAAMC,EAAU9B,EAAO,OACjB+B,EAAeF,IAAe,OAAaC,EAAUhE,EAAU+D,EAAaD,EAAS,KAAM,EAAGE,CAAO,EAC3G,OAAO,KAAK,wBAAwBF,EAAU5B,EAAQ,CACpD,MAAO8B,EAAUC,EACjB,IAAKD,EAAU,CACjB,EAAG,EAAK,CACV,CAEQ,wBAAwBF,EAAoB5B,EAAiB1B,EAAwBC,EAA6C,CAExI,OADgB,IAAIwB,EAAuBC,EAAQ4B,CAAQ,EAC5C,UAAU,CACvB,MAAO,CAAE,EAAG,EAAe,EAAG,OAAOtD,EAAM,OAAU,SAAWA,EAAM,MAAQA,EAAM,MAAM,IAAK,EAC/F,IAAO,CAAE,EAAGsD,EAAS,KAAM,EAAG,OAAOtD,EAAM,KAAU,SAAWA,EAAM,IAAQA,EAAM,IAAI,IAAO,CACjG,EAAGC,CAA0B,CAC/B,CAEQ,uBAAuBqD,EAAoBI,EAAiD,CAClG,IAAMhC,EAAS4B,EAAS,OAAO,OACzBK,EAAU,IAAIC,EAAqBlC,EAAQ4B,EAAUI,CAAO,EAC5DG,EAAgBH,EAAQ,eAAiB,GACzC1D,EAAQ0D,EAAQ,MACtB,GAAI1D,EACF,OAAO2D,EAAQ,UAAU,CACvB,MAAO,CAAE,EAAG3D,EAAM,SAAsB,GAAG,OAAOA,EAAM,WAAc,SAAWA,EAAM,UAA4B,EACnH,IAAO,CAAE,EAAGsD,EAAS,KAAM,GAAG,OAAOtD,EAAM,SAAc,SAAWA,EAAM,QAA4B,CACxG,CAAC,EAEH,GAAI,CAAC6D,EAAe,CAClB,IAAML,EAAU9B,EAAO,OACjB6B,EAAaG,EAAQ,WACrBD,EAAeF,IAAe,OAAaC,EAAUhE,EAAU+D,EAAaD,EAAS,KAAM,EAAGE,CAAO,EAC3G,OAAOG,EAAQ,UAAU,CACvB,MAAO,CAAE,EAAG,EAAe,EAAGH,EAAUC,CAAY,EACpD,IAAO,CAAE,EAAGH,EAAS,KAAM,EAAGE,EAAU,CAAY,CACtD,CAAC,CACH,CAEA,IAAMM,EAAY,KAAK,WAAW,qBAAqB,EACvD,OAAIA,IAAc,OACTH,EAAQ,UAAU,CACvB,MAAO,CAAE,EAAGG,EAAU,MAAM,EAAG,EAAGA,EAAU,MAAM,CAAE,EACpD,IAAO,CAAE,EAAGA,EAAU,IAAI,EAAK,EAAGA,EAAU,IAAI,CAAI,CACtD,CAAC,EAGI,EACT,CAMQ,uBAAuBR,EAA4B,CAEzD,IAAM5B,EAAU4B,EAAiB,MAAM,OACjCS,EAAoBrC,EAAO,UAC3BsC,EAAuBtC,EAAO,aAGpC,OAAIqC,IAAc,GAAKC,IAAiBV,EAAS,KAAO,EAE/C,QAAQS,EAAY,CAAC,IAAIC,EAAe,CAAC,IAG3C,EACT,CAEQ,gBAAgBV,EAA4B,CAClD,IAAIR,EAAU,GACRmB,EAAQX,EAAS,MAgBvB,GAbIW,EAAM,4BAA2BnB,GAAW,YAC5CmB,EAAM,wBAAuBnB,GAAW,aACxCmB,EAAM,qBAAoBnB,GAAW,eACrCmB,EAAM,aAAYnB,GAAW,WAC7BmB,EAAM,aAAYnB,GAAW,YAC7BmB,EAAM,wBAAuBnB,GAAW,aACxCmB,EAAM,gBAAenB,GAAW,eAIhCmB,EAAM,iBAAmB,KAAOnB,GAAW,YAG3CmB,EAAM,oBAAsB,OAC9B,OAAQA,EAAM,kBAAmB,CAC/B,IAAK,MAAOnB,GAAW,WAAY,MACnC,IAAK,QAASA,GAAW,cAAe,MACxC,IAAK,OAAQA,GAAW,cAAe,MACvC,IAAK,MAAOA,GAAW,cAAe,KACxC,CAKF,OAAKmB,EAAM,aACTnB,GAAW,aAGNA,CACT,CAEO,UAAUY,EAAqC,CAEpD,GAAI,CAAC,KAAK,UACR,MAAM,IAAI,MAAM,2CAA2C,EAI7D,IAAIZ,EAAUY,GAAS,MACnB,KAAK,wBAAwB,KAAK,UAAW,KAAK,UAAU,OAAO,OAAQA,EAAQ,MAAO,EAAI,EAC9F,KAAK,6BAA6B,KAAK,UAAW,KAAK,UAAU,OAAO,OAAQA,GAAS,UAAU,EAGvG,GAAI,CAACA,GAAS,kBACR,KAAK,UAAU,OAAO,OAAO,OAAS,YAAa,CACrD,IAAMQ,EAA2B,KAAK,6BAA6B,KAAK,UAAW,KAAK,UAAU,OAAO,UAAW,MAAS,EAC7HpB,GAAW,oBAAwBoB,CAAwB,EAC7D,CAIF,OAAKR,GAAS,eACZZ,GAAW,KAAK,gBAAgB,KAAK,SAAS,EAC9CA,GAAW,KAAK,uBAAuB,KAAK,SAAS,GAGhDA,CACT,CAEO,gBAAgBY,EAAkD,CACvE,GAAI,CAAC,KAAK,UACR,MAAM,IAAI,MAAM,2CAA2C,EAG7D,OAAO,KAAK,uBAAuB,KAAK,UAAWA,GAAW,CAAC,CAAC,CAClE,CAEO,SAAgB,CAAE,CAC3B,EAEaE,EAAN,cAAmC9D,CAAqB,CAO7D,YACE4B,EACiBC,EACAwC,EACjB,CACA,MAAMzC,CAAM,EAHK,eAAAC,EACA,cAAAwC,EATnB,KAAQ,YAAsB,GAE9B,KAAQ,aAAe,GAYhBxC,EAAkB,MAAM,cAC3B,KAAK,YAAeA,EAAkB,MAAM,cAAc,OAAO,KAGjE,KAAK,YAAcyC,CAEvB,CAEU,iBAAiBpD,EAAcY,EAAeC,EAAmB,CACzE,KAAK,cAAgB,wCAErB,IAAIwC,EAAa,UACbC,EAAa,WACb,KAAK,SAAS,yBAA2B,MAC3CD,EAAa,KAAK,UAAU,QAAQ,OAAO,YAAc,UACzDC,EAAa,KAAK,UAAU,QAAQ,OAAO,YAAc,WAG3D,IAAMC,EAAyB,CAAC,EAChCA,EAAuB,KAAK,UAAYF,EAAa,GAAG,EACxDE,EAAuB,KAAK,qBAAuBD,EAAa,GAAG,EACnEC,EAAuB,KAAK,gBAAkB,KAAK,UAAU,QAAQ,WAAa,GAAG,EACrFA,EAAuB,KAAK,cAAgB,KAAK,UAAU,QAAQ,SAAW,KAAK,EACnF,KAAK,cAAgB,eAAkBA,EAAuB,KAAK,GAAG,EAAI,IAC5E,CAEU,iBAAwB,CAChC,KAAK,cAAgB,SACrB,KAAK,cAAgB,wCACvB,CAEU,QAAQ9D,EAAaM,EAA0B,CACvD,KAAK,cAAgB,cAAgB,KAAK,YAAc,gBACxD,KAAK,YAAc,EACrB,CAEQ,aAAaD,EAAmB0D,EAAmC,CACzE,IAAM9B,EAAQ8B,EAAO1D,EAAK,WAAW,EAAIA,EAAK,WAAW,EACzD,GAAI0D,EAAO1D,EAAK,QAAQ,EAAIA,EAAK,QAAQ,EAMvC,MAAO,IALK,CACT4B,GAAS,GAAM,IACfA,GAAU,EAAK,IACfA,EAAe,GAClB,EACiB,IAAI+B,GAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,EAEpE,GAAID,EAAO1D,EAAK,YAAY,EAAIA,EAAK,YAAY,EAC/C,OAAO,KAAK,YAAY4B,CAAK,EAAE,GAGnC,CAEQ,mBAAmB5B,EAAuC,CAChE,GAAIA,EAAK,wBAAwB,EAC/B,OAEF,IAAM4B,EAAQ5B,EAAK,kBAAkB,EACrC,OAAIA,EAAK,oBAAoB,EAMpB,IALK,CACT4B,GAAS,GAAM,IACfA,GAAU,EAAK,IACfA,EAAe,GAClB,EACiB,IAAI+B,GAAKA,EAAE,SAAS,EAAE,EAAE,SAAS,EAAG,GAAG,CAAC,EAAE,KAAK,EAAE,EAG7D,KAAK,YAAY/B,CAAK,EAAE,GACjC,CAEQ,mBAAmB5B,EAA2B,CACpD,OAAQA,EAAK,kBAAkB,EAAG,CAChC,OACE,MAAO,YACT,OACE,MAAO,mBACT,OACE,MAAO,iBACT,OACE,MAAO,mBACT,OACE,MAAO,mBACT,QACE,MAAO,WACX,CACF,CAEQ,WAAWA,EAAmBV,EAA4C,CAChF,IAAM0C,EAAoB,CAAC,EAE3B,GAAIvB,EAAiBT,EAAMV,CAAO,EAChC,OAGF,IAAMmC,EAAY,CAACtB,EAAQH,EAAMV,CAAO,EAClCoC,EAAY,CAACtB,EAAQJ,EAAMV,CAAO,EAClCqC,EAAe,CAACnB,EAAWR,EAAMV,CAAO,EAE9C,GAAImC,GAAaC,GAAaC,EAAc,CAC1C,IAAMiC,EAAa,KAAK,aAAa5D,EAAM,EAAI,EAC3C4D,GACF5B,EAAQ,KAAK,UAAY4B,EAAa,GAAG,EAG3C,IAAMC,EAAa,KAAK,aAAa7D,EAAM,EAAK,EAC5C6D,GACF7B,EAAQ,KAAK,qBAAuB6B,EAAa,GAAG,EAGlD7D,EAAK,UAAU,GAAKgC,EAAQ,KAAK,4CAA4C,EAC7EhC,EAAK,OAAO,GAAKgC,EAAQ,KAAK,oBAAoB,EAGtD,IAAM8B,EAAwB,CAAC,EAkB/B,GAjBI9D,EAAK,YAAY,GACnB8D,EAAY,KAAK,KAAK,mBAAmB9D,CAAI,CAAC,EAE5CA,EAAK,WAAW,GAClB8D,EAAY,KAAK,UAAU,EAEzB9D,EAAK,gBAAgB,GACvB8D,EAAY,KAAK,cAAc,EAE7B9D,EAAK,QAAQ,GACf8D,EAAY,KAAK,OAAO,EAEtBA,EAAY,OAAS,GACvB9B,EAAQ,KAAK,oBAAsB8B,EAAY,KAAK,GAAG,EAAI,GAAG,EAI5D9D,EAAK,YAAY,EAAG,CACtB,IAAM+D,EAAiB,KAAK,mBAAmB/D,CAAI,EAC/C+D,GACF/B,EAAQ,KAAK,0BAA4B+B,EAAiB,GAAG,CAEjE,CAEA,OAAI/D,EAAK,YAAY,GAAKgC,EAAQ,KAAK,qBAAqB,EACxDhC,EAAK,SAAS,GAAKgC,EAAQ,KAAK,qBAAqB,EACrDhC,EAAK,MAAM,GAAKgC,EAAQ,KAAK,eAAe,EAEzCA,CACT,CAGF,CAEU,UAAUhC,EAAmBV,EAAsBK,EAAaI,EAAmB,CAG3F,GAD0BC,EAAK,SAAS,IAAM,EAE5C,OAIF,IAAM8B,EAAc9B,EAAK,SAAS,IAAM,GAElCgE,EAAmB,KAAK,WAAWhE,EAAMV,CAAO,EAGlD0E,IACF,KAAK,aAAeA,EAAiB,SAAW,EAC9C,gBACA,uBAA0BA,EAAiB,KAAK,GAAG,EAAI,MAIvDlC,EACF,KAAK,aAAe,IAEpB,KAAK,aAAehD,EAAekB,EAAK,SAAS,CAAC,CAEtD,CAEU,kBAA2B,CACnC,OAAO,KAAK,YACd,CACF", - "names": ["$r", "$g", "$b", "$a", "channels", "toCss", "g", "b", "a", "toPaddedHex", "toRgba", "toColor", "color", "blend", "bg", "fg", "$a", "fgR", "fgG", "fgB", "bgR", "bgG", "bgB", "$r", "$g", "$b", "css", "rgba", "isOpaque", "ensureContrastRatio", "ratio", "result", "opaque", "rgbaColor", "opacity", "multiplyOpacity", "factor", "toColorRGB", "$ctx", "$litmusColor", "canvas", "ctx", "rgbaMatch", "rgb", "relativeLuminance", "relativeLuminance2", "r", "rs", "gs", "bs", "rr", "rg", "rb", "bgRgba", "fgRgba", "bgL", "fgL", "contrastRatio", "resultA", "reduceLuminance", "resultARatio", "resultB", "increaseLuminance", "resultBRatio", "cr", "toChannels", "value", "c", "s", "l1", "l2", "DEFAULT_ANSI_COLORS", "colors", "css", "v", "i", "r", "g", "b", "channels", "c", "constrain", "value", "low", "high", "escapeHTMLChar", "c", "BaseSerializeHandler", "_buffer", "range", "excludeFinalCursorPosition", "cell1", "cell2", "oldCell", "startRow", "endRow", "startColumn", "endColumn", "row", "line", "startLineColumn", "endLineColumn", "col", "cell", "isLastRow", "rows", "equalFg", "equalBg", "equalUnderline", "cell1Default", "cell2Default", "equalFlags", "attributesEquals", "cell1AsBufferCell", "StringSerializeHandler", "buffer", "_terminal", "start", "end", "rowSeparator", "currentLine", "nextLine", "thisRowLastChar", "thisRowLastSecondChar", "nextRowFirstChar", "isNextRowFirstCharDoubleWidth", "isValid", "sgrSeq", "fgChanged", "bgChanged", "flagsChanged", "color", "style", "isEmptyCell", "rowEnd", "content", "realCursorRow", "realCursorCol", "cursorMoved", "moveRight", "offset", "curAttrData", "SerializeAddon", "terminal", "scrollback", "maxRows", "correctRows", "options", "handler", "HTMLSerializeHandler", "onlySelection", "selection", "scrollTop", "scrollBottom", "modes", "alternativeScreenContent", "_options", "DEFAULT_ANSI_COLORS", "foreground", "background", "globalStyleDefinitions", "isFg", "x", "fgHexColor", "bgHexColor", "decorations", "underlineColor", "styleDefinitions"] -+ "sourcesContent": ["/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\ntype OscLinkData = { id?: string; uri: string };\ntype OscLinkedCell = { extended?: { urlId?: number } };\ntype TerminalWithOscLinks = Terminal & {\n _core?: {\n _inputHandler?: { _curAttrData?: IAttributeData & OscLinkedCell };\n _oscLinkService?: { getLinkData: (linkId: number) => OscLinkData | undefined };\n };\n};\n\nfunction getOscLinkId(cell: IBufferCell | IAttributeData): number {\n return (cell as typeof cell & OscLinkedCell).extended?.urlId ?? 0;\n}\n\nfunction getOscLinkOpenSequence(terminal: Terminal, linkId: number): string {\n if (!linkId) {\n return '';\n }\n const data = (terminal as TerminalWithOscLinks)._core?._oscLinkService?.getLinkData(linkId);\n if (!data) {\n return '';\n }\n const params = data.id === undefined ? '' : `id=${data.id}`;\n return `\\u001b]8;${params};${data.uri}\\u001b\\\\`;\n}\n\nfunction getActiveOscLinkSequence(terminal: Terminal): string {\n const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData;\n return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : '';\n}\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: line.length;\n for (let col = startLineColumn; col < endLineColumn; col++) {\n const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n private _defaultCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n private _activeOscLinkId: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!;\n const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n (isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0)\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n const contentCellCount = currentLine.length - this._nullCellCount;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}C`;\n }\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}D`;\n }\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n // PATCH(orca): bold (1) and dim (2) share the single reset param 22, so\n // they must be diffed as one intensity group with the clearing 22 emitted\n // BEFORE any re-set. Upstream's independent per-flag diff could emit\n // \"1;22\" (bold set, then wiped by dim's clear \u2014 \\x1b[2mA\\x1b[22m\\x1b[1mB\n // loses B's bold on round-trip) or a bare \"22\" that drops a still-set\n // bold/dim, garbling Orca's hidden-terminal snapshot restores.\n const boldChanged = cell.isBold() !== oldCell.isBold();\n const dimChanged = cell.isDim() !== oldCell.isDim();\n if (boldChanged || dimChanged) {\n const clearsIntensity = (boldChanged && !cell.isBold()) || (dimChanged && !cell.isDim());\n if (clearsIntensity) { sgrSeq.push(22); }\n if (cell.isBold() && (boldChanged || clearsIntensity)) { sgrSeq.push(1); }\n if (cell.isDim() && (dimChanged || clearsIntensity)) { sgrSeq.push(2); }\n }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n // PATCH(orca): dim handled in the intensity group above.\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n private _setOscLink(linkId: number): string {\n if (linkId === this._activeOscLinkId) {\n return '';\n }\n let sequence = this._activeOscLinkId ? '\\u001b]8;;\\u001b\\\\' : '';\n this._activeOscLinkId = 0;\n const openSequence = getOscLinkOpenSequence(this._terminal, linkId);\n if (openSequence) {\n this._activeOscLinkId = linkId;\n sequence += openSequence;\n }\n return sequence;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n const nextLine = isEmptyCell && cell.isInverse() ? this._buffer.getLine(row + 1) : undefined;\n const nextRowFirstCell = nextLine?.getCell(0, this._nextRowFirstChar);\n // A pending wide glyph recreates its own final-column padding during replay.\n const isWideWrapPadding = col === this._terminal.cols - 1 &&\n nextLine?.isWrapped &&\n (nextRowFirstCell?.getWidth() ?? 0) > 1 &&\n !!nextRowFirstCell && attributesEquals(cell, nextRowFirstCell);\n // Cursor movement cannot reproduce an inverse cell's visible background.\n const materializeEmptyCell = isEmptyCell && !!cell.isInverse() && !isWideWrapPadding;\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n const styleChanged = isEmptyCell\n ? materializeEmptyCell ? sgrSeq.length > 0 : !equalBg(this._cursorStyle, cell)\n : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell && !materializeEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n // PATCH(orca): styling alone leaves restored OSC 8 links looking live but unclickable.\n this._currentRow += this._setOscLink(getOscLinkId(cell));\n\n if (materializeEmptyCell) {\n const hasDecoration = !!cell.isUnderline() || !!cell.isStrikethrough() || !!cell.isOverline();\n if (hasDecoration) {\n this._currentRow += '\\u001b[24;29;55m';\n }\n this._currentRow += ' '.repeat(cell.getWidth());\n if (hasDecoration) {\n const restoreSgrSeq = this._diffStyle(cell, this._defaultCell);\n this._currentRow += `\\u001b[0m\\u001b[${restoreSgrSeq.join(';')}m`;\n }\n } else {\n this._currentRow += cell.getChars();\n }\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // Each buffer is self-contained so links cannot leak into a following buffer.\n content += this._setOscLink(0);\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n // Restore the source terminal's live OSC pen only after all buffers are complete.\n content += getActiveOscLinkSequence(this._terminal);\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"], -+ "mappings": "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", -+ "names": ["$r", "$g", "$b", "$a", "channels", "toCss", "r", "g", "b", "a", "toPaddedHex", "toRgba", "toColor", "color", "blend", "bg", "fg", "$a", "fgR", "fgG", "fgB", "bgR", "bgG", "bgB", "$r", "$g", "$b", "css", "rgba", "isOpaque", "ensureContrastRatio", "ratio", "result", "opaque", "rgbaColor", "opacity", "multiplyOpacity", "factor", "toColorRGB", "$ctx", "$litmusColor", "canvas", "ctx", "rgbaMatch", "rgb", "relativeLuminance", "relativeLuminance2", "rs", "gs", "bs", "rr", "rg", "rb", "bgRgba", "fgRgba", "bgL", "fgL", "contrastRatio", "resultA", "reduceLuminance", "resultARatio", "resultB", "increaseLuminance", "resultBRatio", "cr", "toChannels", "value", "c", "s", "l1", "l2", "DEFAULT_ANSI_COLORS", "colors", "css", "v", "i", "g", "b", "channels", "c", "getOscLinkId", "cell", "getOscLinkOpenSequence", "terminal", "linkId", "data", "getActiveOscLinkSequence", "attrs", "constrain", "value", "low", "high", "escapeHTMLChar", "c", "BaseSerializeHandler", "_buffer", "range", "excludeFinalCursorPosition", "cell1", "cell2", "oldCell", "startRow", "endRow", "startColumn", "endColumn", "row", "line", "startLineColumn", "endLineColumn", "col", "isLastRow", "rows", "equalFg", "equalBg", "equalUnderline", "cell1Default", "cell2Default", "equalFlags", "attributesEquals", "cell1AsBufferCell", "StringSerializeHandler", "buffer", "_terminal", "start", "end", "rowSeparator", "currentLine", "nextLine", "thisRowLastChar", "thisRowLastSecondChar", "nextRowFirstChar", "isNextRowFirstCharDoubleWidth", "isValid", "contentCellCount", "sgrSeq", "fgChanged", "bgChanged", "flagsChanged", "color", "boldChanged", "dimChanged", "clearsIntensity", "style", "sequence", "openSequence", "isEmptyCell", "nextRowFirstCell", "isWideWrapPadding", "materializeEmptyCell", "hasDecoration", "restoreSgrSeq", "rowEnd", "content", "realCursorRow", "realCursorCol", "cursorMoved", "moveRight", "offset", "curAttrData", "SerializeAddon", "scrollback", "maxRows", "correctRows", "options", "handler", "HTMLSerializeHandler", "onlySelection", "selection", "scrollTop", "scrollBottom", "modes", "alternativeScreenContent", "_options", "DEFAULT_ANSI_COLORS", "foreground", "background", "globalStyleDefinitions", "isFg", "x", "fgHexColor", "bgHexColor", "decorations", "underlineColor", "styleDefinitions"] ++ "sourcesContent": ["/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, IColorRGB } from './Types';\n\nlet $r = 0;\nlet $g = 0;\nlet $b = 0;\nlet $a = 0;\n\nexport const NULL_COLOR: IColor = {\n css: '#00000000',\n rgba: 0\n};\n\n/**\n * Helper functions where the source type is \"channels\" (individual color channels as numbers).\n */\nexport namespace channels {\n export function toCss(r: number, g: number, b: number, a?: number): string {\n if (a !== undefined) {\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}${toPaddedHex(a)}`;\n }\n return `#${toPaddedHex(r)}${toPaddedHex(g)}${toPaddedHex(b)}`;\n }\n\n export function toRgba(r: number, g: number, b: number, a: number = 0xFF): number {\n // Note: The aggregated number is RGBA32 (BE), thus needs to be converted to ABGR32\n // on LE systems, before it can be used for direct 32-bit buffer writes.\n // >>> 0 forces an unsigned int\n return (r << 24 | g << 16 | b << 8 | a) >>> 0;\n }\n\n export function toColor(r: number, g: number, b: number, a?: number): IColor {\n return {\n css: channels.toCss(r, g, b, a),\n rgba: channels.toRgba(r, g, b, a)\n };\n }\n}\n\n/**\n * Helper functions where the source type is `IColor`.\n */\nexport namespace color {\n export function blend(bg: IColor, fg: IColor): IColor {\n $a = (fg.rgba & 0xFF) / 255;\n if ($a === 1) {\n return {\n css: fg.css,\n rgba: fg.rgba\n };\n }\n const fgR = (fg.rgba >> 24) & 0xFF;\n const fgG = (fg.rgba >> 16) & 0xFF;\n const fgB = (fg.rgba >> 8) & 0xFF;\n const bgR = (bg.rgba >> 24) & 0xFF;\n const bgG = (bg.rgba >> 16) & 0xFF;\n const bgB = (bg.rgba >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n const css = channels.toCss($r, $g, $b);\n const rgba = channels.toRgba($r, $g, $b);\n return { css, rgba };\n }\n\n export function isOpaque(color: IColor): boolean {\n return (color.rgba & 0xFF) === 0xFF;\n }\n\n export function ensureContrastRatio(bg: IColor, fg: IColor, ratio: number): IColor | undefined {\n const result = rgba.ensureContrastRatio(bg.rgba, fg.rgba, ratio);\n if (!result) {\n return undefined;\n }\n return channels.toColor(\n (result >> 24 & 0xFF),\n (result >> 16 & 0xFF),\n (result >> 8 & 0xFF)\n );\n }\n\n export function opaque(color: IColor): IColor {\n const rgbaColor = (color.rgba | 0xFF) >>> 0;\n [$r, $g, $b] = rgba.toChannels(rgbaColor);\n return {\n css: channels.toCss($r, $g, $b),\n rgba: rgbaColor\n };\n }\n\n export function opacity(color: IColor, opacity: number): IColor {\n $a = Math.round(opacity * 0xFF);\n [$r, $g, $b] = rgba.toChannels(color.rgba);\n return {\n css: channels.toCss($r, $g, $b, $a),\n rgba: channels.toRgba($r, $g, $b, $a)\n };\n }\n\n export function multiplyOpacity(color: IColor, factor: number): IColor {\n $a = color.rgba & 0xFF;\n return opacity(color, ($a * factor) / 0xFF);\n }\n\n export function toColorRGB(color: IColor): IColorRGB {\n return [(color.rgba >> 24) & 0xFF, (color.rgba >> 16) & 0xFF, (color.rgba >> 8) & 0xFF];\n }\n}\n\n/**\n * Helper functions where the source type is \"css\" (string: '#rgb', '#rgba', '#rrggbb',\n * '#rrggbbaa').\n */\nexport namespace css {\n // Attempt to set get the shared canvas context\n let $ctx: CanvasRenderingContext2D | undefined;\n let $litmusColor: CanvasGradient | undefined;\n try {\n // This is guaranteed to run in the first window, so document should be correct\n const canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n const ctx = canvas.getContext('2d', {\n willReadFrequently: true\n });\n if (ctx) {\n $ctx = ctx;\n $ctx.globalCompositeOperation = 'copy';\n $litmusColor = $ctx.createLinearGradient(0, 0, 1, 1);\n }\n }\n catch {\n // noop\n }\n\n /**\n * Converts a css string to an IColor, this should handle all valid CSS color strings and will\n * throw if it's invalid. The ideal format to use is `#rrggbb[aa]` as it's the fastest to parse.\n *\n * Only `#rgb[a]`, `#rrggbb[aa]`, `rgb()` and `rgba()` formats are supported when run in a Node\n * environment.\n */\n export function toColor(css: string): IColor {\n // Formats: #rgb[a] and #rrggbb[aa]\n if (css.match(/#[\\da-f]{3,8}/i)) {\n switch (css.length) {\n case 4: { // #rgb\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n return channels.toColor($r, $g, $b);\n }\n case 5: { // #rgba\n $r = parseInt(css.slice(1, 2).repeat(2), 16);\n $g = parseInt(css.slice(2, 3).repeat(2), 16);\n $b = parseInt(css.slice(3, 4).repeat(2), 16);\n $a = parseInt(css.slice(4, 5).repeat(2), 16);\n return channels.toColor($r, $g, $b, $a);\n }\n case 7: // #rrggbb\n return {\n css,\n rgba: (parseInt(css.slice(1), 16) << 8 | 0xFF) >>> 0\n };\n case 9: // #rrggbbaa\n return {\n css,\n rgba: parseInt(css.slice(1), 16) >>> 0\n };\n }\n }\n\n // Formats: rgb() or rgba()\n const rgbaMatch = css.match(/rgba?\\(\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*,\\s*(\\d{1,3})\\s*(,\\s*(0|1|\\d?\\.(\\d+))\\s*)?\\)/);\n if (rgbaMatch) {\n $r = parseInt(rgbaMatch[1], 10);\n $g = parseInt(rgbaMatch[2], 10);\n $b = parseInt(rgbaMatch[3], 10);\n $a = Math.round((rgbaMatch[5] === undefined ? 1 : parseFloat(rgbaMatch[5])) * 0xFF);\n return channels.toColor($r, $g, $b, $a);\n }\n\n // Handle the \"transparent\" keyword\n if (css === 'transparent') {\n return {\n css: 'transparent',\n rgba: 0x00000000\n };\n }\n\n // Validate the context is available for canvas-based color parsing\n if (!$ctx || !$litmusColor) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Validate the color using canvas fillStyle\n // See https://html.spec.whatwg.org/multipage/canvas.html#fill-and-stroke-styles\n $ctx.fillStyle = $litmusColor;\n $ctx.fillStyle = css;\n if (typeof $ctx.fillStyle !== 'string') {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n $ctx.fillRect(0, 0, 1, 1);\n [$r, $g, $b, $a] = $ctx.getImageData(0, 0, 1, 1).data;\n\n // Validate the color is non-transparent as color hue gets lost when drawn to the canvas\n if ($a !== 0xFF) {\n throw new Error('css.toColor: Unsupported css format');\n }\n\n // Extract the color from the canvas' fillStyle property which exposes the color value in rgba()\n // format\n // See https://html.spec.whatwg.org/multipage/canvas.html#serialisation-of-a-color\n return {\n rgba: channels.toRgba($r, $g, $b, $a),\n css\n };\n }\n}\n\n/**\n * Helper functions where the source type is \"rgb\" (number: 0xrrggbb).\n */\nexport namespace rgb {\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param rgb The color to use.\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance(rgb: number): number {\n return relativeLuminance2(\n (rgb >> 16) & 0xFF,\n (rgb >> 8 ) & 0xFF,\n (rgb ) & 0xFF);\n }\n\n /**\n * Gets the relative luminance of an RGB color, this is useful in determining the contrast ratio\n * between two colors.\n * @param r The red channel (0x00 to 0xFF).\n * @param g The green channel (0x00 to 0xFF).\n * @param b The blue channel (0x00 to 0xFF).\n * @see https://www.w3.org/TR/WCAG20/#relativeluminancedef\n */\n export function relativeLuminance2(r: number, g: number, b: number): number {\n const rs = r / 255;\n const gs = g / 255;\n const bs = b / 255;\n const rr = rs <= 0.03928 ? rs / 12.92 : Math.pow((rs + 0.055) / 1.055, 2.4);\n const rg = gs <= 0.03928 ? gs / 12.92 : Math.pow((gs + 0.055) / 1.055, 2.4);\n const rb = bs <= 0.03928 ? bs / 12.92 : Math.pow((bs + 0.055) / 1.055, 2.4);\n return rr * 0.2126 + rg * 0.7152 + rb * 0.0722;\n }\n}\n\n/**\n * Helper functions where the source type is \"rgba\" (number: 0xrrggbbaa).\n */\nexport namespace rgba {\n export function blend(bg: number, fg: number): number {\n $a = (fg & 0xFF) / 0xFF;\n if ($a === 1) {\n return fg;\n }\n const fgR = (fg >> 24) & 0xFF;\n const fgG = (fg >> 16) & 0xFF;\n const fgB = (fg >> 8) & 0xFF;\n const bgR = (bg >> 24) & 0xFF;\n const bgG = (bg >> 16) & 0xFF;\n const bgB = (bg >> 8) & 0xFF;\n $r = bgR + Math.round((fgR - bgR) * $a);\n $g = bgG + Math.round((fgG - bgG) * $a);\n $b = bgB + Math.round((fgB - bgB) * $a);\n return channels.toRgba($r, $g, $b);\n }\n\n /**\n * Given a foreground color and a background color, either increase or reduce the luminance of the\n * foreground color until the specified contrast ratio is met. If pure white or black is hit\n * without the contrast ratio being met, go the other direction using the background color as the\n * foreground color and take either the first or second result depending on which has the higher\n * contrast ratio.\n *\n * `undefined` will be returned if the contrast ratio is already met.\n *\n * @param bgRgba The background color in rgba format.\n * @param fgRgba The foreground color in rgba format.\n * @param ratio The contrast ratio to achieve.\n */\n export function ensureContrastRatio(bgRgba: number, fgRgba: number, ratio: number): number | undefined {\n const bgL = rgb.relativeLuminance(bgRgba >> 8);\n const fgL = rgb.relativeLuminance(fgRgba >> 8);\n const cr = contrastRatio(bgL, fgL);\n if (cr < ratio) {\n if (fgL < bgL) {\n const resultA = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n const resultA = increaseLuminance(bgRgba, fgRgba, ratio);\n const resultARatio = contrastRatio(bgL, rgb.relativeLuminance(resultA >> 8));\n if (resultARatio < ratio) {\n const resultB = reduceLuminance(bgRgba, fgRgba, ratio);\n const resultBRatio = contrastRatio(bgL, rgb.relativeLuminance(resultB >> 8));\n return resultARatio > resultBRatio ? resultA : resultB;\n }\n return resultA;\n }\n return undefined;\n }\n\n export function reduceLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to reducing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR > 0 || fgG > 0 || fgB > 0)) {\n // Reduce by 10% until the ratio is hit\n fgR -= Math.max(0, Math.ceil(fgR * 0.1));\n fgG -= Math.max(0, Math.ceil(fgG * 0.1));\n fgB -= Math.max(0, Math.ceil(fgB * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function increaseLuminance(bgRgba: number, fgRgba: number, ratio: number): number {\n // This is a naive but fast approach to increasing luminance as converting to\n // HSL and back is expensive\n const bgR = (bgRgba >> 24) & 0xFF;\n const bgG = (bgRgba >> 16) & 0xFF;\n const bgB = (bgRgba >> 8) & 0xFF;\n let fgR = (fgRgba >> 24) & 0xFF;\n let fgG = (fgRgba >> 16) & 0xFF;\n let fgB = (fgRgba >> 8) & 0xFF;\n let cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n while (cr < ratio && (fgR < 0xFF || fgG < 0xFF || fgB < 0xFF)) {\n // Increase by 10% until the ratio is hit\n fgR = Math.min(0xFF, fgR + Math.ceil((255 - fgR) * 0.1));\n fgG = Math.min(0xFF, fgG + Math.ceil((255 - fgG) * 0.1));\n fgB = Math.min(0xFF, fgB + Math.ceil((255 - fgB) * 0.1));\n cr = contrastRatio(rgb.relativeLuminance2(fgR, fgG, fgB), rgb.relativeLuminance2(bgR, bgG, bgB));\n }\n return (fgR << 24 | fgG << 16 | fgB << 8 | 0xFF) >>> 0;\n }\n\n export function toChannels(value: number): [number, number, number, number] {\n return [(value >> 24) & 0xFF, (value >> 16) & 0xFF, (value >> 8) & 0xFF, value & 0xFF];\n }\n}\n\nexport function toPaddedHex(c: number): string {\n const s = c.toString(16);\n return s.length < 2 ? '0' + s : s;\n}\n\n/**\n * Gets the contrast ratio between two relative luminance values.\n * @param l1 The first relative luminance.\n * @param l2 The second relative luminance.\n * @see https://www.w3.org/TR/WCAG20/#contrast-ratiodef\n */\nexport function contrastRatio(l1: number, l2: number): number {\n if (l1 < l2) {\n return (l2 + 0.05) / (l1 + 0.05);\n }\n return (l1 + 0.05) / (l2 + 0.05);\n}\n", "/**\n * Copyright (c) 2017 The xterm.js authors. All rights reserved.\n * @license MIT\n */\n\nimport { IColor, ITerminalOptions } from '../common/Types';\nimport { CharData, IBuffer } from '../common/buffer/Types';\nimport { ICoreTerminal } from '../common/CoreTerminal';\nimport { IDisposable, IRenderDimensions as IRenderDimensionsApi, Terminal as ITerminalApi } from '@xterm/xterm';\nimport { channels, css } from '../common/Color';\nimport type { IEvent } from '../common/Event';\n\n/**\n * A portion of the public API that are implemented identially internally and simply passed through.\n */\ntype InternalPassthroughApis = Omit;\n\nexport interface ITerminal extends InternalPassthroughApis, ICoreTerminal {\n screenElement: HTMLElement | undefined;\n browser: IBrowser;\n buffer: IBuffer;\n linkifier: ILinkifier2 | undefined;\n options: Required;\n\n readonly dimensions: IRenderDimensionsApi | undefined;\n\n onBlur: IEvent;\n onFocus: IEvent;\n onDimensionsChange: IEvent;\n onA11yChar: IEvent;\n onA11yTab: IEvent;\n onWillOpen: IEvent;\n}\n\nexport type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;\nexport type CustomWheelEventHandler = (event: WheelEvent) => boolean;\n\nexport type LineData = CharData[];\n\nexport interface ICompositionHelper {\n readonly isComposing: boolean;\n compositionstart(): void;\n compositionupdate(ev: CompositionEvent): void;\n compositionend(): void;\n updateCompositionElements(dontRecurse?: boolean): void;\n keydown(ev: KeyboardEvent): boolean;\n}\n\nexport interface IBrowser {\n isNode: boolean;\n userAgent: string;\n platform: string;\n isFirefox: boolean;\n isMac: boolean;\n isIpad: boolean;\n isIphone: boolean;\n isWindows: boolean;\n}\n\nexport interface IColorSet {\n foreground: IColor;\n background: IColor;\n cursor: IColor;\n cursorAccent: IColor;\n selectionForeground: IColor | undefined;\n selectionBackgroundTransparent: IColor;\n /** The selection blended on top of background. */\n selectionBackgroundOpaque: IColor;\n selectionInactiveBackgroundTransparent: IColor;\n selectionInactiveBackgroundOpaque: IColor;\n scrollbarSliderBackground: IColor;\n scrollbarSliderHoverBackground: IColor;\n scrollbarSliderActiveBackground: IColor;\n overviewRulerBorder: IColor;\n ansi: IColor[];\n /** Maps original colors to colors that respect minimum contrast ratio. */\n contrastCache: IColorContrastCache;\n /** Maps original colors to colors that respect _half_ of the minimum contrast ratio. */\n halfContrastCache: IColorContrastCache;\n}\n\nexport type ReadonlyColorSet = Readonly> & { ansi: Readonly['ansi']> };\n\nexport interface IColorContrastCache {\n clear(): void;\n setCss(bg: number, fg: number, value: string | null): void;\n getCss(bg: number, fg: number): string | null | undefined;\n setColor(bg: number, fg: number, value: IColor | null): void;\n getColor(bg: number, fg: number): IColor | null | undefined;\n}\n\nexport interface IPartialColorSet {\n foreground: IColor;\n background: IColor;\n cursor?: IColor;\n cursorAccent?: IColor;\n selectionBackground?: IColor;\n ansi: IColor[];\n}\n\nexport interface IViewport extends IDisposable {\n scrollBarWidth: number;\n readonly onRequestScrollLines: IEvent<{ amount: number, suppressScrollEvent: boolean }>;\n syncScrollArea(immediate?: boolean, force?: boolean): void;\n getLinesScrolled(ev: WheelEvent): number;\n getBufferElements(startLine: number, endLine?: number): { bufferElements: HTMLElement[], cursorElement?: HTMLElement };\n handleWheel(ev: WheelEvent): boolean;\n handleTouchStart(ev: TouchEvent): void;\n handleTouchMove(ev: TouchEvent): boolean;\n scrollLines(disp: number): void; // todo api name?\n reset(): void;\n}\n\nexport interface ILinkifierEvent {\n x1: number;\n y1: number;\n x2: number;\n y2: number;\n cols: number;\n fg: number | undefined;\n}\n\ninterface ILinkState {\n decorations: ILinkDecorations;\n isHovered: boolean;\n}\nexport interface ILinkWithState {\n link: ILink;\n state?: ILinkState;\n}\n\nexport interface ILinkifier2 extends IDisposable {\n onShowLinkUnderline: IEvent;\n onHideLinkUnderline: IEvent;\n readonly currentLink: ILinkWithState | undefined;\n}\n\nexport interface ILink {\n range: IBufferRange;\n text: string;\n decorations?: ILinkDecorations;\n activate(event: MouseEvent, text: string): void;\n hover?(event: MouseEvent, text: string): void;\n leave?(event: MouseEvent, text: string): void;\n dispose?(): void;\n}\n\nexport interface ILinkDecorations {\n pointerCursor: boolean;\n underline: boolean;\n}\n\nexport interface IBufferRange {\n start: IBufferCellPosition;\n end: IBufferCellPosition;\n}\n\nexport interface IBufferCellPosition {\n x: number;\n y: number;\n}\n\nexport type CharacterJoinerHandler = (text: string) => [number, number][];\n\nexport interface ICharacterJoiner {\n id: number;\n handler: CharacterJoinerHandler;\n}\n\nexport interface IRenderDebouncer extends IDisposable {\n refresh(rowStart: number | undefined, rowEnd: number | undefined, rowCount: number): void;\n}\n\nexport interface IRenderDebouncerWithCallback extends IRenderDebouncer {\n addRefreshCallback(callback: FrameRequestCallback): number;\n}\n\nexport interface IBufferElementProvider {\n provideBufferElements(): DocumentFragment | HTMLElement;\n}\n\n// An IIFE to generate DEFAULT_ANSI_COLORS.\nexport const DEFAULT_ANSI_COLORS = Object.freeze((() => {\n const colors = [\n // dark:\n css.toColor('#2e3436'),\n css.toColor('#cc0000'),\n css.toColor('#4e9a06'),\n css.toColor('#c4a000'),\n css.toColor('#3465a4'),\n css.toColor('#75507b'),\n css.toColor('#06989a'),\n css.toColor('#d3d7cf'),\n // bright:\n css.toColor('#555753'),\n css.toColor('#ef2929'),\n css.toColor('#8ae234'),\n css.toColor('#fce94f'),\n css.toColor('#729fcf'),\n css.toColor('#ad7fa8'),\n css.toColor('#34e2e2'),\n css.toColor('#eeeeec')\n ];\n\n // Fill in the remaining 240 ANSI colors.\n // Generate colors (16-231)\n const v = [0x00, 0x5f, 0x87, 0xaf, 0xd7, 0xff];\n for (let i = 0; i < 216; i++) {\n const r = v[(i / 36) % 6 | 0];\n const g = v[(i / 6) % 6 | 0];\n const b = v[i % 6];\n colors.push({\n css: channels.toCss(r, g, b),\n rgba: channels.toRgba(r, g, b)\n });\n }\n\n // Generate greys (232-255)\n for (let i = 0; i < 24; i++) {\n const c = 8 + i * 10;\n colors.push({\n css: channels.toCss(c, c, c),\n rgba: channels.toRgba(c, c, c)\n });\n }\n\n return colors;\n})());\n", "/**\n * Copyright (c) 2019 The xterm.js authors. All rights reserved.\n * @license MIT\n *\n * (EXPERIMENTAL) This Addon is still under development\n */\n\nimport type { IBuffer, IBufferCell, IBufferLine, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm';\nimport type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize';\nimport { IColor } from 'common/Types';\nimport { IAttributeData } from 'common/buffer/Types';\nimport { DEFAULT_ANSI_COLORS } from 'browser/Types';\nimport { UnderlineStyle } from 'common/buffer/Constants';\n\ntype OscLinkData = { id?: string; uri: string };\ntype OscLinkedCell = { extended?: { urlId?: number } };\ntype TerminalWithOscLinks = Terminal & {\n _core?: {\n _inputHandler?: { _curAttrData?: IAttributeData & OscLinkedCell };\n _oscLinkService?: { getLinkData: (linkId: number) => OscLinkData | undefined };\n };\n};\n\nfunction getOscLinkId(cell: IBufferCell | IAttributeData): number {\n return (cell as typeof cell & OscLinkedCell).extended?.urlId ?? 0;\n}\n\nfunction getOscLinkOpenSequence(terminal: Terminal, linkId: number): string {\n if (!linkId) {\n return '';\n }\n const data = (terminal as TerminalWithOscLinks)._core?._oscLinkService?.getLinkData(linkId);\n if (!data) {\n return '';\n }\n const params = data.id === undefined ? '' : `id=${data.id}`;\n return `\\u001b]8;${params};${data.uri}\\u001b\\\\`;\n}\n\nfunction getActiveOscLinkSequence(terminal: Terminal): string {\n const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData;\n return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : '';\n}\n\n// PATCH(orca): a non-reflowing shrink (always the alternate buffer) leaves each\n// line at its old length; cells past the grid are not on screen and would wrap\n// into extra rows on replay, so serialize only the terminal's width.\nfunction visibleCellCount(line: IBufferLine, cols: number): number {\n return Math.min(line.length, cols);\n}\n\n// PATCH(orca): a wide glyph whose trailing half fell past the grid cannot be\n// replayed in the last column (it would wrap and shift every row below), so it\n// is serialized as a blank that keeps the row exactly the grid's width.\nfunction isClippedWideCell(line: IBufferLine, col: number, cols: number, cell: IBufferCell): boolean {\n return col === cols - 1 && line.length > cols && cell.getWidth() > 1;\n}\n\n// Width 1 with no codepoint (CellData.content layout). A width-0 stand-in would read as a\n// wide glyph's trailer: skipped by _nextCell and treated as content by the wrap check.\nconst BLANK_CELL_CONTENT = 1 << 22;\n\nfunction blankClippedWideCell(cell: IBufferCell): IBufferCell {\n (cell as IBufferCell & { content: number }).content = BLANK_CELL_CONTENT;\n return cell;\n}\n\nfunction constrain(value: number, low: number, high: number): number {\n return Math.max(low, Math.min(value, high));\n}\n\nfunction escapeHTMLChar(c: string): string {\n switch (c) {\n case '&': return '&';\n case '<': return '<';\n }\n return c;\n}\n\n// TODO: Refine this template class later\nabstract class BaseSerializeHandler {\n constructor(\n protected readonly _buffer: IBuffer,\n private readonly _cols: number\n ) {\n }\n\n public serialize(range: IBufferRange, excludeFinalCursorPosition?: boolean): string {\n // we need two of them to flip between old and new cell\n const cell1 = this._buffer.getNullCell();\n const cell2 = this._buffer.getNullCell();\n let oldCell = cell1;\n\n const startRow = range.start.y;\n const endRow = range.end.y;\n const startColumn = range.start.x;\n const endColumn = range.end.x;\n\n this._beforeSerialize(endRow - startRow, startRow, endRow);\n\n for (let row = startRow; row <= endRow; row++) {\n const line = this._buffer.getLine(row);\n if (line) {\n const startLineColumn = row === range.start.y ? startColumn : 0;\n const endLineColumn = row === range.end.y ? endColumn: visibleCellCount(line, this._cols);\n for (let col = startLineColumn; col < endLineColumn; col++) {\n let c = line.getCell(col, oldCell === cell1 ? cell2 : cell1);\n if (!c) {\n console.warn(`Can't get cell at row=${row}, col=${col}`);\n continue;\n }\n if (isClippedWideCell(line, col, this._cols, c)) {\n c = blankClippedWideCell(c);\n }\n this._nextCell(c, oldCell, row, col);\n oldCell = c;\n }\n }\n this._rowEnd(row, row === endRow);\n }\n\n this._afterSerialize();\n\n return this._serializeString(excludeFinalCursorPosition);\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { }\n protected _rowEnd(row: number, isLastRow: boolean): void { }\n protected _beforeSerialize(rows: number, startRow: number, endRow: number): void { }\n protected _afterSerialize(): void { }\n protected _serializeString(excludeFinalCursorPosition?: boolean): string { return ''; }\n}\n\nfunction equalFg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getFgColorMode() === cell2.getFgColorMode()\n && cell1.getFgColor() === cell2.getFgColor();\n}\n\nfunction equalBg(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.getBgColorMode() === cell2.getBgColorMode()\n && cell1.getBgColor() === cell2.getBgColor();\n}\n\nfunction equalUnderline(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n // If neither cell has underline, consider them equal regardless of internal underline color\n // values\n if (!cell1.isUnderline() && !cell2.isUnderline()) {\n return true;\n }\n if (cell1.getUnderlineStyle() !== cell2.getUnderlineStyle()) {\n return false;\n }\n const cell1Default = cell1.isUnderlineColorDefault();\n const cell2Default = cell2.isUnderlineColorDefault();\n if (cell1Default && cell2Default) {\n return true;\n }\n if (cell1Default !== cell2Default) {\n return false;\n }\n return cell1.getUnderlineColor() === cell2.getUnderlineColor()\n && cell1.getUnderlineColorMode() === cell2.getUnderlineColorMode();\n}\n\nfunction equalFlags(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n return cell1.isInverse() === cell2.isInverse()\n && cell1.isBold() === cell2.isBold()\n && cell1.isUnderline() === cell2.isUnderline()\n && equalUnderline(cell1, cell2)\n && cell1.isOverline() === cell2.isOverline()\n && cell1.isBlink() === cell2.isBlink()\n && cell1.isInvisible() === cell2.isInvisible()\n && cell1.isItalic() === cell2.isItalic()\n && cell1.isDim() === cell2.isDim()\n && cell1.isStrikethrough() === cell2.isStrikethrough();\n}\n\nfunction attributesEquals(cell1: IBufferCell | IAttributeData, cell2: IBufferCell): boolean {\n const cell1AsBufferCell = cell1 as IBufferCell;\n if (typeof cell1AsBufferCell.attributesEquals === 'function') {\n return cell1AsBufferCell.attributesEquals(cell2);\n }\n return equalFg(cell1, cell2)\n && equalBg(cell1, cell2)\n && equalFlags(cell1, cell2);\n}\n\nclass StringSerializeHandler extends BaseSerializeHandler {\n private _rowIndex: number = 0;\n private _allRows: string[] = new Array();\n private _allRowSeparators: string[] = new Array();\n private _currentRow: string = '';\n private _nullCellCount: number = 0;\n\n // we can see a full colored cell and a null cell that only have background the same style\n // but the information isn't preserved by null cell itself\n // so wee need to record it when required.\n private _cursorStyle: IBufferCell = this._buffer.getNullCell();\n\n // where exact the cursor styles comes from\n // because we can't copy the cell directly\n // so we remember where the content comes from instead\n private _cursorStyleRow: number = 0;\n private _cursorStyleCol: number = 0;\n\n // this is a null cell for reference for checking whether background is empty or not\n private _backgroundCell: IBufferCell = this._buffer.getNullCell();\n private _defaultCell: IBufferCell = this._buffer.getNullCell();\n\n private _firstRow: number = 0;\n private _lastCursorRow: number = 0;\n private _lastCursorCol: number = 0;\n private _lastContentCursorRow: number = 0;\n private _lastContentCursorCol: number = 0;\n private _activeOscLinkId: number = 0;\n private _lastBackgroundCursorRow: number = -1;\n private _lastBackgroundCursorCol: number = 0;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal\n ) {\n super(buffer, _terminal.cols);\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._allRows = new Array(rows);\n this._lastContentCursorRow = start;\n this._lastCursorRow = start;\n this._firstRow = start;\n }\n\n private _thisRowLastChar: IBufferCell = this._buffer.getNullCell();\n private _thisRowLastSecondChar: IBufferCell = this._buffer.getNullCell();\n private _nextRowFirstChar: IBufferCell = this._buffer.getNullCell();\n protected _rowEnd(row: number, isLastRow: boolean): void {\n // if there is colorful empty cell at line end, we must pad it back, or the color block\n // will missing\n if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) {\n // use clear right to set background.\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n // PATCH(orca): the erase paints this row, so _serializeString must not trim it as trailing blank.\n this._lastBackgroundCursorRow = this._lastCursorRow;\n this._lastBackgroundCursorCol = this._lastCursorCol;\n }\n\n let rowSeparator = '';\n\n // handle row separator\n if (!isLastRow) {\n // Enable BCE\n if (row - this._firstRow >= this._terminal.rows) {\n this._buffer.getLine(this._cursorStyleRow)?.getCell(this._cursorStyleCol, this._backgroundCell);\n }\n\n // Fetch current line\n const currentLine = this._buffer.getLine(row)!;\n // Fetch next line\n const nextLine = this._buffer.getLine(row + 1)!;\n\n if (!nextLine.isWrapped) {\n // just insert the line break\n rowSeparator = '\\r\\n';\n // we sended the enter\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n } else {\n rowSeparator = '';\n const currentLineCells = visibleCellCount(currentLine, this._terminal.cols);\n let thisRowLastChar = currentLine.getCell(currentLineCells - 1, this._thisRowLastChar)!;\n if (isClippedWideCell(currentLine, currentLineCells - 1, this._terminal.cols, thisRowLastChar)) {\n thisRowLastChar = blankClippedWideCell(thisRowLastChar);\n }\n const thisRowLastSecondChar = currentLine.getCell(currentLineCells - 2, this._thisRowLastSecondChar)!;\n const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!;\n const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1;\n\n // validate whether this line wrap is ever possible\n // which mean whether cursor can placed at a overflow position (x === row) naturally\n let isValid = false;\n\n if (\n // you must output character to cause overflow, control sequence can't do this\n nextRowFirstChar.getChars() &&\n (isNextRowFirstCharDoubleWidth ? this._nullCellCount <= 1 : this._nullCellCount <= 0)\n ) {\n if (\n // the last character can't be null,\n // you can't use control sequence to move cursor to (x === row)\n (thisRowLastChar.getChars() || thisRowLastChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n\n if (\n // the second to last character can't be null if the next line starts with CJK,\n // you can't use control sequence to move cursor to (x === row)\n isNextRowFirstCharDoubleWidth &&\n (thisRowLastSecondChar.getChars() || thisRowLastSecondChar.getWidth() === 0) &&\n // change background of the first wrapped cell also affects BCE\n // so we mark it as invalid to simplify the process to determine line separator\n equalBg(thisRowLastChar, nextRowFirstChar) &&\n equalBg(thisRowLastSecondChar, nextRowFirstChar)\n ) {\n isValid = true;\n }\n }\n\n if (!isValid) {\n // force the wrap with magic\n // insert enough character to force the wrap\n rowSeparator = '-'.repeat(this._nullCellCount + 1);\n // move back and erase next line head\n rowSeparator += '\\u001b[1D\\u001b[1X';\n\n if (this._nullCellCount > 0) {\n // do these because we filled the last several null slot, which we shouldn't\n rowSeparator += '\\u001b[A';\n const contentCellCount = currentLineCells - this._nullCellCount;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}C`;\n }\n rowSeparator += `\\u001b[${this._nullCellCount}X`;\n if (contentCellCount > 0) {\n rowSeparator += `\\u001b[${contentCellCount}D`;\n }\n rowSeparator += '\\u001b[B';\n }\n\n // This is content and need the be serialized even it is invisible.\n // without this, wrap will be missing from outputs.\n this._lastContentCursorRow = row + 1;\n this._lastContentCursorCol = 0;\n\n // force commit the cursor position\n this._lastCursorRow = row + 1;\n this._lastCursorCol = 0;\n }\n }\n }\n\n this._allRows[this._rowIndex] = this._currentRow;\n this._allRowSeparators[this._rowIndex++] = rowSeparator;\n this._currentRow = '';\n this._nullCellCount = 0;\n }\n\n private _diffStyle(cell: IBufferCell | IAttributeData, oldCell: IBufferCell): number[] {\n const sgrSeq: number[] = [];\n if (attributesEquals(cell, oldCell)) {\n return sgrSeq;\n }\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n if (cell.isAttributeDefault()) {\n if (!oldCell.isAttributeDefault()) {\n sgrSeq.push(0);\n }\n } else {\n if (fgChanged) {\n const color = cell.getFgColor();\n if (cell.isFgRGB()) { sgrSeq.push(38, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isFgPalette()) {\n if (color >= 16) { sgrSeq.push(38, 5, color); }\n else { sgrSeq.push(color & 8 ? 90 + (color & 7) : 30 + (color & 7)); }\n }\n else { sgrSeq.push(39); }\n }\n if (bgChanged) {\n const color = cell.getBgColor();\n if (cell.isBgRGB()) { sgrSeq.push(48, 2, (color >>> 16) & 0xFF, (color >>> 8) & 0xFF, color & 0xFF); }\n else if (cell.isBgPalette()) {\n if (color >= 16) { sgrSeq.push(48, 5, color); }\n else { sgrSeq.push(color & 8 ? 100 + (color & 7) : 40 + (color & 7)); }\n }\n else { sgrSeq.push(49); }\n }\n if (flagsChanged) {\n if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); }\n // PATCH(orca): bold (1) and dim (2) share the single reset param 22, so\n // they must be diffed as one intensity group with the clearing 22 emitted\n // BEFORE any re-set. Upstream's independent per-flag diff could emit\n // \"1;22\" (bold set, then wiped by dim's clear \u2014 \\x1b[2mA\\x1b[22m\\x1b[1mB\n // loses B's bold on round-trip) or a bare \"22\" that drops a still-set\n // bold/dim, garbling Orca's hidden-terminal snapshot restores.\n const boldChanged = cell.isBold() !== oldCell.isBold();\n const dimChanged = cell.isDim() !== oldCell.isDim();\n if (boldChanged || dimChanged) {\n const clearsIntensity = (boldChanged && !cell.isBold()) || (dimChanged && !cell.isDim());\n if (clearsIntensity) { sgrSeq.push(22); }\n if (cell.isBold() && (boldChanged || clearsIntensity)) { sgrSeq.push(1); }\n if (cell.isDim() && (dimChanged || clearsIntensity)) { sgrSeq.push(2); }\n }\n if (!equalUnderline(cell, oldCell)) {\n const style = cell.getUnderlineStyle();\n if (style === UnderlineStyle.NONE) {\n sgrSeq.push(24);\n } else if (style === UnderlineStyle.SINGLE && cell.isUnderlineColorDefault()) {\n sgrSeq.push(4);\n } else {\n // Use SGR 4:X format for underline styles\n sgrSeq.push('4:' + style as unknown as number);\n // Handle underline color\n if (!cell.isUnderlineColorDefault()) {\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n sgrSeq.push('58:2::' + ((color >>> 16) & 0xFF) + ':' + ((color >>> 8) & 0xFF) + ':' + (color & 0xFF) as unknown as number);\n } else {\n sgrSeq.push('58:5:' + color as unknown as number);\n }\n }\n }\n } else if (cell.isUnderline() !== oldCell.isUnderline()) {\n sgrSeq.push(cell.isUnderline() ? 4 : 24);\n }\n if (cell.isOverline() !== oldCell.isOverline()) { sgrSeq.push(cell.isOverline() ? 53 : 55); }\n if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); }\n if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); }\n if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); }\n // PATCH(orca): dim handled in the intensity group above.\n if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); }\n }\n }\n }\n\n return sgrSeq;\n }\n\n private _setOscLink(linkId: number): string {\n if (linkId === this._activeOscLinkId) {\n return '';\n }\n let sequence = this._activeOscLinkId ? '\\u001b]8;;\\u001b\\\\' : '';\n this._activeOscLinkId = 0;\n const openSequence = getOscLinkOpenSequence(this._terminal, linkId);\n if (openSequence) {\n this._activeOscLinkId = linkId;\n sequence += openSequence;\n }\n return sequence;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n const nextLine = isEmptyCell && cell.isInverse() ? this._buffer.getLine(row + 1) : undefined;\n const nextRowFirstCell = nextLine?.getCell(0, this._nextRowFirstChar);\n // A pending wide glyph recreates its own final-column padding during replay.\n const isWideWrapPadding = col === this._terminal.cols - 1 &&\n nextLine?.isWrapped &&\n (nextRowFirstCell?.getWidth() ?? 0) > 1 &&\n !!nextRowFirstCell && attributesEquals(cell, nextRowFirstCell);\n // Cursor movement cannot reproduce an inverse cell's visible background.\n const materializeEmptyCell = isEmptyCell && !!cell.isInverse() && !isWideWrapPadding;\n\n const sgrSeq = this._diffStyle(cell, this._cursorStyle);\n\n const styleChanged = isEmptyCell\n ? materializeEmptyCell ? sgrSeq.length > 0 : !equalBg(this._cursorStyle, cell)\n : sgrSeq.length > 0;\n\n /**\n * handles style change\n */\n if (styleChanged) {\n // before update the style, we need to fill empty cell back\n if (this._nullCellCount > 0) {\n // use clear right to set background.\n if (!equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n }\n // use move right to move cursor.\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n this._nullCellCount = 0;\n }\n\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col;\n\n this._currentRow += `\\u001b[${sgrSeq.join(';')}m`;\n\n // update the last cursor style\n const line = this._buffer.getLine(row);\n if (line !== undefined) {\n line.getCell(col, this._cursorStyle);\n this._cursorStyleRow = row;\n this._cursorStyleCol = col;\n }\n }\n\n /**\n * handles actual content\n */\n if (isEmptyCell && !materializeEmptyCell) {\n this._nullCellCount += cell.getWidth();\n } else {\n if (this._nullCellCount > 0) {\n // we can just assume we have same style with previous one here\n // because style change is handled by previous stage\n // use move right when background is empty, use clear right when there is background.\n if (equalBg(this._cursorStyle, this._backgroundCell)) {\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n } else {\n this._currentRow += `\\u001b[${this._nullCellCount}X`;\n this._currentRow += `\\u001b[${this._nullCellCount}C`;\n }\n this._nullCellCount = 0;\n }\n\n // PATCH(orca): styling alone leaves restored OSC 8 links looking live but unclickable.\n this._currentRow += this._setOscLink(getOscLinkId(cell));\n\n if (materializeEmptyCell) {\n const hasDecoration = !!cell.isUnderline() || !!cell.isStrikethrough() || !!cell.isOverline();\n if (hasDecoration) {\n this._currentRow += '\\u001b[24;29;55m';\n }\n this._currentRow += ' '.repeat(cell.getWidth());\n if (hasDecoration) {\n const restoreSgrSeq = this._diffStyle(cell, this._defaultCell);\n this._currentRow += `\\u001b[0m\\u001b[${restoreSgrSeq.join(';')}m`;\n }\n } else {\n this._currentRow += cell.getChars();\n }\n\n // update cursor\n this._lastContentCursorRow = this._lastCursorRow = row;\n this._lastContentCursorCol = this._lastCursorCol = col + cell.getWidth();\n }\n }\n\n protected _serializeString(excludeFinalCursorPosition: boolean): string {\n let rowEnd = this._allRows.length;\n\n // the fixup is only required for data without scrollback\n // because it will always be placed at last line otherwise\n if (this._buffer.length - this._firstRow <= this._terminal.rows) {\n // PATCH(orca): keep trailing background-only rows, unless the cursor is wrap-pending:\n // relative moves back from those rows cannot re-create that state.\n if (\n this._lastBackgroundCursorRow > this._lastContentCursorRow &&\n this._buffer.cursorX < this._terminal.cols\n ) {\n this._lastContentCursorRow = this._lastBackgroundCursorRow;\n this._lastContentCursorCol = this._lastBackgroundCursorCol;\n }\n rowEnd = this._lastContentCursorRow + 1 - this._firstRow;\n this._lastCursorCol = this._lastContentCursorCol;\n this._lastCursorRow = this._lastContentCursorRow;\n }\n\n let content = '';\n\n for (let i = 0; i < rowEnd; i++) {\n content += this._allRows[i];\n if (i + 1 < rowEnd) {\n content += this._allRowSeparators[i];\n }\n }\n\n // Each buffer is self-contained so links cannot leak into a following buffer.\n content += this._setOscLink(0);\n\n // restore the cursor\n if (!excludeFinalCursorPosition) {\n const realCursorRow = this._buffer.baseY + this._buffer.cursorY;\n const realCursorCol = this._buffer.cursorX;\n\n const cursorMoved = (realCursorRow !== this._lastCursorRow || realCursorCol !== this._lastCursorCol);\n\n const moveRight = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}C`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}D`;\n }\n };\n const moveDown = (offset: number): void => {\n if (offset > 0) {\n content += `\\u001b[${offset}B`;\n } else if (offset < 0) {\n content += `\\u001b[${-offset}A`;\n }\n };\n\n if (cursorMoved) {\n moveDown(realCursorRow - this._lastCursorRow);\n moveRight(realCursorCol - this._lastCursorCol);\n }\n }\n\n // Restore the cursor's current style, see https://github.com/xtermjs/xterm.js/issues/3677\n // HACK: Internal API access since it's awkward to expose this in the API and serialize will\n // likely be the only consumer\n const curAttrData: IAttributeData = (this._terminal as any)._core._inputHandler._curAttrData;\n const sgrSeq = this._diffStyle(curAttrData, this._cursorStyle);\n if (sgrSeq.length > 0) {\n content += `\\u001b[${sgrSeq.join(';')}m`;\n }\n\n return content;\n }\n}\n\nexport class SerializeAddon implements ITerminalAddon, ISerializeApi {\n private _terminal: Terminal | undefined;\n\n public activate(terminal: Terminal): void {\n this._terminal = terminal;\n }\n\n private _serializeBufferByScrollback(terminal: Terminal, buffer: IBuffer, scrollback?: number): string {\n const maxRows = buffer.length;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return this._serializeBufferByRange(terminal, buffer, {\n start: maxRows - correctRows,\n end: maxRows - 1\n }, false);\n }\n\n private _serializeBufferByRange(terminal: Terminal, buffer: IBuffer, range: ISerializeRange, excludeFinalCursorPosition: boolean): string {\n const handler = new StringSerializeHandler(buffer, terminal);\n return handler.serialize({\n start: { x: 0, y: typeof range.start === 'number' ? range.start : range.start.line },\n end: { x: terminal.cols, y: typeof range.end === 'number' ? range.end : range.end.line }\n }, excludeFinalCursorPosition);\n }\n\n private _serializeBufferAsHTML(terminal: Terminal, options: Partial): string {\n const buffer = terminal.buffer.active;\n const handler = new HTMLSerializeHandler(buffer, terminal, options);\n const onlySelection = options.onlySelection ?? false;\n const range = options.range;\n if (range) {\n return handler.serialize({\n start: { x: range.startCol, y: typeof range.startLine === 'number' ? range.startLine : range.startLine },\n end: { x: terminal.cols, y: typeof range.endLine === 'number' ? range.endLine : range.endLine }\n });\n }\n if (!onlySelection) {\n const maxRows = buffer.length;\n const scrollback = options.scrollback;\n const correctRows = (scrollback === undefined) ? maxRows : constrain(scrollback + terminal.rows, 0, maxRows);\n return handler.serialize({\n start: { x: 0, y: maxRows - correctRows },\n end: { x: terminal.cols, y: maxRows - 1 }\n });\n }\n\n const selection = this._terminal?.getSelectionPosition();\n if (selection !== undefined) {\n return handler.serialize({\n start: { x: selection.start.x, y: selection.start.y },\n end: { x: selection.end.x, y: selection.end.y }\n });\n }\n\n return '';\n }\n\n /**\n * Serializes the scroll region (DECSTBM) if it's not set to the full terminal size.\n * Uses internal API access since scroll region is not exposed in the public API.\n */\n private _serializeScrollRegion(terminal: Terminal): string {\n // HACK: Internal API access since scroll region is not exposed in the public API\n const buffer = (terminal as any)._core.buffer;\n const scrollTop: number = buffer.scrollTop;\n const scrollBottom: number = buffer.scrollBottom;\n\n // Only serialize if scroll region is not the default (full terminal size)\n if (scrollTop !== 0 || scrollBottom !== terminal.rows - 1) {\n // DECSTBM uses 1-based indices: CSI Ps ; Ps r\n return `\\x1b[${scrollTop + 1};${scrollBottom + 1}r`;\n }\n\n return '';\n }\n\n private _serializeModes(terminal: Terminal): string {\n let content = '';\n const modes = terminal.modes;\n\n // Default: false\n if (modes.applicationCursorKeysMode) content += '\\x1b[?1h';\n if (modes.applicationKeypadMode) content += '\\x1b[?66h';\n if (modes.bracketedPasteMode) content += '\\x1b[?2004h';\n if (modes.insertMode) content += '\\x1b[4h';\n if (modes.originMode) content += '\\x1b[?6h';\n if (modes.reverseWraparoundMode) content += '\\x1b[?45h';\n if (modes.sendFocusMode) content += '\\x1b[?1004h';\n // synchronizedOutputMode doesn't need to be serialized as it's a temporary mode\n\n // Default: true\n if (modes.wraparoundMode === false) content += '\\x1b[?7l';\n\n // Default: 'none'\n if (modes.mouseTrackingMode !== 'none') {\n switch (modes.mouseTrackingMode) {\n case 'x10': content += '\\x1b[?9h'; break;\n case 'vt200': content += '\\x1b[?1000h'; break;\n case 'drag': content += '\\x1b[?1002h'; break;\n case 'any': content += '\\x1b[?1003h'; break;\n }\n }\n\n // Cursor visibility (DECTCEM)\n // Default: visible\n if (!modes.showCursor) {\n content += '\\x1b[?25l';\n }\n\n return content;\n }\n\n public serialize(options?: ISerializeOptions): string {\n // TODO: Add combinedData support\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n // Normal buffer\n let content = options?.range\n ? this._serializeBufferByRange(this._terminal, this._terminal.buffer.normal, options.range, true)\n : this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.normal, options?.scrollback);\n\n // Alternate buffer\n if (!options?.excludeAltBuffer) {\n if (this._terminal.buffer.active.type === 'alternate') {\n const alternativeScreenContent = this._serializeBufferByScrollback(this._terminal, this._terminal.buffer.alternate, undefined);\n content += `\\u001b[?1049h\\u001b[H${alternativeScreenContent}`;\n }\n }\n\n // Modes and scroll region\n if (!options?.excludeModes) {\n content += this._serializeModes(this._terminal);\n content += this._serializeScrollRegion(this._terminal);\n }\n\n // Restore the source terminal's live OSC pen only after all buffers are complete.\n content += getActiveOscLinkSequence(this._terminal);\n\n return content;\n }\n\n public serializeAsHTML(options?: Partial): string {\n if (!this._terminal) {\n throw new Error('Cannot use addon until it has been loaded');\n }\n\n return this._serializeBufferAsHTML(this._terminal, options ?? {});\n }\n\n public dispose(): void { }\n}\n\nexport class HTMLSerializeHandler extends BaseSerializeHandler {\n private _currentRow: string = '';\n\n private _htmlContent = '';\n\n private _ansiColors: Readonly;\n\n constructor(\n buffer: IBuffer,\n private readonly _terminal: Terminal,\n private readonly _options: Partial\n ) {\n super(buffer, _terminal.cols);\n\n // For xterm headless: fallback to ansi colors\n if ((_terminal as any)._core._themeService) {\n this._ansiColors = (_terminal as any)._core._themeService.colors.ansi;\n }\n else {\n this._ansiColors = DEFAULT_ANSI_COLORS;\n }\n }\n\n protected _beforeSerialize(rows: number, start: number, end: number): void {\n this._htmlContent += '
';\n\n    let foreground = '#000000';\n    let background = '#ffffff';\n    if (this._options.includeGlobalBackground ?? false) {\n      foreground = this._terminal.options.theme?.foreground ?? '#ffffff';\n      background = this._terminal.options.theme?.background ?? '#000000';\n    }\n\n    const globalStyleDefinitions = [];\n    globalStyleDefinitions.push('color: ' + foreground + ';');\n    globalStyleDefinitions.push('background-color: ' + background + ';');\n    globalStyleDefinitions.push('font-family: ' + this._terminal.options.fontFamily + ';');\n    globalStyleDefinitions.push('font-size: ' + this._terminal.options.fontSize + 'px;');\n    this._htmlContent += '
';\n }\n\n protected _afterSerialize(): void {\n this._htmlContent += '
';\n this._htmlContent += '
';\n }\n\n protected _rowEnd(row: number, isLastRow: boolean): void {\n this._htmlContent += '
' + this._currentRow + '
';\n this._currentRow = '';\n }\n\n private _getHexColor(cell: IBufferCell, isFg: boolean): string | undefined {\n const color = isFg ? cell.getFgColor() : cell.getBgColor();\n if (isFg ? cell.isFgRGB() : cell.isBgRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n if (isFg ? cell.isFgPalette() : cell.isBgPalette()) {\n return this._ansiColors[color].css;\n }\n return undefined;\n }\n\n private _getUnderlineColor(cell: IBufferCell): string | undefined {\n if (cell.isUnderlineColorDefault()) {\n return undefined;\n }\n const color = cell.getUnderlineColor();\n if (cell.isUnderlineColorRGB()) {\n const rgb = [\n (color >> 16) & 255,\n (color >> 8) & 255,\n (color ) & 255\n ];\n return '#' + rgb.map(x => x.toString(16).padStart(2, '0')).join('');\n }\n // Palette color\n return this._ansiColors[color].css;\n }\n\n private _getUnderlineStyle(cell: IBufferCell): string {\n switch (cell.getUnderlineStyle()) {\n case UnderlineStyle.SINGLE:\n return 'underline';\n case UnderlineStyle.DOUBLE:\n return 'underline double';\n case UnderlineStyle.CURLY:\n return 'underline wavy';\n case UnderlineStyle.DOTTED:\n return 'underline dotted';\n case UnderlineStyle.DASHED:\n return 'underline dashed';\n default:\n return 'underline';\n }\n }\n\n private _diffStyle(cell: IBufferCell, oldCell: IBufferCell): string[] | undefined {\n const content: string[] = [];\n\n if (attributesEquals(cell, oldCell)) {\n return undefined;\n }\n\n const fgChanged = !equalFg(cell, oldCell);\n const bgChanged = !equalBg(cell, oldCell);\n const flagsChanged = !equalFlags(cell, oldCell);\n\n if (fgChanged || bgChanged || flagsChanged) {\n const fgHexColor = this._getHexColor(cell, true);\n if (fgHexColor) {\n content.push('color: ' + fgHexColor + ';');\n }\n\n const bgHexColor = this._getHexColor(cell, false);\n if (bgHexColor) {\n content.push('background-color: ' + bgHexColor + ';');\n }\n\n if (cell.isInverse()) { content.push('color: #000000; background-color: #BFBFBF;'); }\n if (cell.isBold()) { content.push('font-weight: bold;'); }\n\n // Handle text-decoration (underline, overline, strikethrough, blink)\n const decorations: string[] = [];\n if (cell.isUnderline()) {\n decorations.push(this._getUnderlineStyle(cell));\n }\n if (cell.isOverline()) {\n decorations.push('overline');\n }\n if (cell.isStrikethrough()) {\n decorations.push('line-through');\n }\n if (cell.isBlink()) {\n decorations.push('blink');\n }\n if (decorations.length > 0) {\n content.push('text-decoration: ' + decorations.join(' ') + ';');\n }\n\n // Handle underline color\n if (cell.isUnderline()) {\n const underlineColor = this._getUnderlineColor(cell);\n if (underlineColor) {\n content.push('text-decoration-color: ' + underlineColor + ';');\n }\n }\n\n if (cell.isInvisible()) { content.push('visibility: hidden;'); }\n if (cell.isItalic()) { content.push('font-style: italic;'); }\n if (cell.isDim()) { content.push('opacity: 0.5;'); }\n\n return content;\n }\n\n return undefined;\n }\n\n protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void {\n // a width 0 cell don't need to be count because it is just a placeholder after a CJK character;\n const isPlaceHolderCell = cell.getWidth() === 0;\n if (isPlaceHolderCell) {\n return;\n }\n\n // this cell don't have content\n const isEmptyCell = cell.getChars() === '';\n\n const styleDefinitions = this._diffStyle(cell, oldCell);\n\n // handles style change\n if (styleDefinitions) {\n this._currentRow += styleDefinitions.length === 0 ?\n '
' :\n '';\n }\n\n // handles actual content\n if (isEmptyCell) {\n this._currentRow += ' ';\n } else {\n this._currentRow += escapeHTMLChar(cell.getChars());\n }\n }\n\n protected _serializeString(): string {\n return this._htmlContent;\n }\n}\n"], ++ "mappings": "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", ++ "names": ["$r", "$g", "$b", "$a", "channels", "toCss", "r", "g", "b", "a", "toPaddedHex", "toRgba", "toColor", "color", "blend", "bg", "fg", "$a", "fgR", "fgG", "fgB", "bgR", "bgG", "bgB", "$r", "$g", "$b", "css", "rgba", "isOpaque", "ensureContrastRatio", "ratio", "result", "opaque", "rgbaColor", "opacity", "multiplyOpacity", "factor", "toColorRGB", "$ctx", "$litmusColor", "canvas", "ctx", "rgbaMatch", "rgb", "relativeLuminance", "relativeLuminance2", "rs", "gs", "bs", "rr", "rg", "rb", "bgRgba", "fgRgba", "bgL", "fgL", "contrastRatio", "resultA", "reduceLuminance", "resultARatio", "resultB", "increaseLuminance", "resultBRatio", "cr", "toChannels", "value", "c", "s", "l1", "l2", "DEFAULT_ANSI_COLORS", "colors", "css", "v", "i", "g", "b", "channels", "c", "getOscLinkId", "cell", "getOscLinkOpenSequence", "terminal", "linkId", "data", "getActiveOscLinkSequence", "attrs", "visibleCellCount", "line", "cols", "isClippedWideCell", "col", "BLANK_CELL_CONTENT", "blankClippedWideCell", "constrain", "value", "low", "high", "escapeHTMLChar", "c", "BaseSerializeHandler", "_buffer", "_cols", "range", "excludeFinalCursorPosition", "cell1", "cell2", "oldCell", "startRow", "endRow", "startColumn", "endColumn", "row", "startLineColumn", "endLineColumn", "isLastRow", "rows", "equalFg", "equalBg", "equalUnderline", "cell1Default", "cell2Default", "equalFlags", "attributesEquals", "cell1AsBufferCell", "StringSerializeHandler", "buffer", "_terminal", "start", "end", "rowSeparator", "currentLine", "nextLine", "currentLineCells", "thisRowLastChar", "thisRowLastSecondChar", "nextRowFirstChar", "isNextRowFirstCharDoubleWidth", "isValid", "contentCellCount", "sgrSeq", "fgChanged", "bgChanged", "flagsChanged", "color", "boldChanged", "dimChanged", "clearsIntensity", "style", "sequence", "openSequence", "isEmptyCell", "nextRowFirstCell", "isWideWrapPadding", "materializeEmptyCell", "hasDecoration", "restoreSgrSeq", "rowEnd", "content", "realCursorRow", "realCursorCol", "cursorMoved", "moveRight", "offset", "curAttrData", "SerializeAddon", "scrollback", "maxRows", "correctRows", "options", "handler", "HTMLSerializeHandler", "onlySelection", "selection", "scrollTop", "scrollBottom", "modes", "alternativeScreenContent", "_options", "DEFAULT_ANSI_COLORS", "foreground", "background", "globalStyleDefinitions", "isFg", "x", "fgHexColor", "bgHexColor", "decorations", "underlineColor", "styleDefinitions"] } diff --git a/src/SerializeAddon.ts b/src/SerializeAddon.ts -index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b01fdff0a 100644 +index e1728feb219c362dfa2ecb602ff99f830d520757..265b9792403601c286bc341f9d046dcd3062e1be 100644 --- a/src/SerializeAddon.ts +++ b/src/SerializeAddon.ts -@@ -12,6 +12,36 @@ import { IAttributeData } from 'common/buffer/Types'; +@@ -5,13 +5,66 @@ + * (EXPERIMENTAL) This Addon is still under development + */ + +-import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; ++import type { IBuffer, IBufferCell, IBufferLine, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; + import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize'; + import { IColor } from 'common/Types'; + import { IAttributeData } from 'common/buffer/Types'; import { DEFAULT_ANSI_COLORS } from 'browser/Types'; import { UnderlineStyle } from 'common/buffer/Constants'; @@ -81,11 +89,63 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b + const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData; + return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : ''; +} ++ ++// PATCH(orca): a non-reflowing shrink (always the alternate buffer) leaves each ++// line at its old length; cells past the grid are not on screen and would wrap ++// into extra rows on replay, so serialize only the terminal's width. ++function visibleCellCount(line: IBufferLine, cols: number): number { ++ return Math.min(line.length, cols); ++} ++ ++// PATCH(orca): a wide glyph whose trailing half fell past the grid cannot be ++// replayed in the last column (it would wrap and shift every row below), so it ++// is serialized as a blank that keeps the row exactly the grid's width. ++function isClippedWideCell(line: IBufferLine, col: number, cols: number, cell: IBufferCell): boolean { ++ return col === cols - 1 && line.length > cols && cell.getWidth() > 1; ++} ++ ++// Width 1 with no codepoint (CellData.content layout). A width-0 stand-in would read as a ++// wide glyph's trailer: skipped by _nextCell and treated as content by the wrap check. ++const BLANK_CELL_CONTENT = 1 << 22; ++ ++function blankClippedWideCell(cell: IBufferCell): IBufferCell { ++ (cell as IBufferCell & { content: number }).content = BLANK_CELL_CONTENT; ++ return cell; ++} + function constrain(value: number, low: number, high: number): number { return Math.max(low, Math.min(value, high)); } -@@ -148,12 +178,14 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -27,7 +80,8 @@ function escapeHTMLChar(c: string): string { + // TODO: Refine this template class later + abstract class BaseSerializeHandler { + constructor( +- protected readonly _buffer: IBuffer ++ protected readonly _buffer: IBuffer, ++ private readonly _cols: number + ) { + } + +@@ -48,13 +102,16 @@ abstract class BaseSerializeHandler { + const line = this._buffer.getLine(row); + if (line) { + const startLineColumn = row === range.start.y ? startColumn : 0; +- const endLineColumn = row === range.end.y ? endColumn: line.length; ++ const endLineColumn = row === range.end.y ? endColumn: visibleCellCount(line, this._cols); + for (let col = startLineColumn; col < endLineColumn; col++) { +- const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1); ++ let c = line.getCell(col, oldCell === cell1 ? cell2 : cell1); + if (!c) { + console.warn(`Can't get cell at row=${row}, col=${col}`); + continue; + } ++ if (isClippedWideCell(line, col, this._cols, c)) { ++ c = blankClippedWideCell(c); ++ } + this._nextCell(c, oldCell, row, col); + oldCell = c; + } +@@ -148,18 +205,22 @@ class StringSerializeHandler extends BaseSerializeHandler { // this is a null cell for reference for checking whether background is empty or not private _backgroundCell: IBufferCell = this._buffer.getNullCell(); @@ -97,10 +157,44 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b private _lastContentCursorRow: number = 0; private _lastContentCursorCol: number = 0; + private _activeOscLinkId: number = 0; ++ private _lastBackgroundCursorRow: number = -1; ++ private _lastBackgroundCursorCol: number = 0; constructor( buffer: IBuffer, -@@ -214,7 +246,7 @@ class StringSerializeHandler extends BaseSerializeHandler { + private readonly _terminal: Terminal + ) { +- super(buffer); ++ super(buffer, _terminal.cols); + } + + protected _beforeSerialize(rows: number, start: number, end: number): void { +@@ -178,6 +239,9 @@ class StringSerializeHandler extends BaseSerializeHandler { + if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) { + // use clear right to set background. + this._currentRow += `\u001b[${this._nullCellCount}X`; ++ // PATCH(orca): the erase paints this row, so _serializeString must not trim it as trailing blank. ++ this._lastBackgroundCursorRow = this._lastCursorRow; ++ this._lastBackgroundCursorCol = this._lastCursorCol; + } + + let rowSeparator = ''; +@@ -202,8 +266,12 @@ class StringSerializeHandler extends BaseSerializeHandler { + this._lastCursorCol = 0; + } else { + rowSeparator = ''; +- const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!; +- const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!; ++ const currentLineCells = visibleCellCount(currentLine, this._terminal.cols); ++ let thisRowLastChar = currentLine.getCell(currentLineCells - 1, this._thisRowLastChar)!; ++ if (isClippedWideCell(currentLine, currentLineCells - 1, this._terminal.cols, thisRowLastChar)) { ++ thisRowLastChar = blankClippedWideCell(thisRowLastChar); ++ } ++ const thisRowLastSecondChar = currentLine.getCell(currentLineCells - 2, this._thisRowLastSecondChar)!; + const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!; + const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1; + +@@ -214,7 +282,7 @@ class StringSerializeHandler extends BaseSerializeHandler { if ( // you must output character to cause overflow, control sequence can't do this nextRowFirstChar.getChars() && @@ -109,12 +203,12 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b ) { if ( // the last character can't be null, -@@ -251,9 +283,14 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -251,9 +319,14 @@ class StringSerializeHandler extends BaseSerializeHandler { if (this._nullCellCount > 0) { // do these because we filled the last several null slot, which we shouldn't rowSeparator += '\u001b[A'; - rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}C`; -+ const contentCellCount = currentLine.length - this._nullCellCount; ++ const contentCellCount = currentLineCells - this._nullCellCount; + if (contentCellCount > 0) { + rowSeparator += `\u001b[${contentCellCount}C`; + } @@ -126,7 +220,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b rowSeparator += '\u001b[B'; } -@@ -310,7 +347,20 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -310,7 +383,20 @@ class StringSerializeHandler extends BaseSerializeHandler { } if (flagsChanged) { if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); } @@ -148,7 +242,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b if (!equalUnderline(cell, oldCell)) { const style = cell.getUnderlineStyle(); if (style === UnderlineStyle.NONE) { -@@ -337,7 +387,7 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -337,7 +423,7 @@ class StringSerializeHandler extends BaseSerializeHandler { if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); } if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); } if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); } @@ -157,7 +251,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); } } } -@@ -346,6 +396,20 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -346,6 +432,20 @@ class StringSerializeHandler extends BaseSerializeHandler { return sgrSeq; } @@ -178,7 +272,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { // a width 0 cell don't need to be count because it is just a placeholder after a CJK character; const isPlaceHolderCell = cell.getWidth() === 0; -@@ -356,12 +420,21 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -356,12 +456,21 @@ class StringSerializeHandler extends BaseSerializeHandler { // this cell don't have content const isEmptyCell = cell.getChars() === ''; @@ -203,7 +297,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b /** * handles style change -@@ -395,7 +468,7 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -395,7 +504,7 @@ class StringSerializeHandler extends BaseSerializeHandler { /** * handles actual content */ @@ -212,7 +306,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b this._nullCellCount += cell.getWidth(); } else { if (this._nullCellCount > 0) { -@@ -411,7 +484,22 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -411,7 +520,22 @@ class StringSerializeHandler extends BaseSerializeHandler { this._nullCellCount = 0; } @@ -236,7 +330,23 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b // update cursor this._lastContentCursorRow = this._lastCursorRow = row; -@@ -439,6 +527,9 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -425,6 +549,15 @@ class StringSerializeHandler extends BaseSerializeHandler { + // the fixup is only required for data without scrollback + // because it will always be placed at last line otherwise + if (this._buffer.length - this._firstRow <= this._terminal.rows) { ++ // PATCH(orca): keep trailing background-only rows, unless the cursor is wrap-pending: ++ // relative moves back from those rows cannot re-create that state. ++ if ( ++ this._lastBackgroundCursorRow > this._lastContentCursorRow && ++ this._buffer.cursorX < this._terminal.cols ++ ) { ++ this._lastContentCursorRow = this._lastBackgroundCursorRow; ++ this._lastContentCursorCol = this._lastBackgroundCursorCol; ++ } + rowEnd = this._lastContentCursorRow + 1 - this._firstRow; + this._lastCursorCol = this._lastContentCursorCol; + this._lastCursorRow = this._lastContentCursorRow; +@@ -439,6 +572,9 @@ class StringSerializeHandler extends BaseSerializeHandler { } } @@ -246,7 +356,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b // restore the cursor if (!excludeFinalCursorPosition) { const realCursorRow = this._buffer.baseY + this._buffer.cursorY; -@@ -616,6 +707,9 @@ export class SerializeAddon implements ITerminalAddon, ISerializeApi { +@@ -616,6 +752,9 @@ export class SerializeAddon implements ITerminalAddon, ISerializeApi { content += this._serializeScrollRegion(this._terminal); } @@ -256,3 +366,12 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b return content; } +@@ -642,7 +781,7 @@ export class HTMLSerializeHandler extends BaseSerializeHandler { + private readonly _terminal: Terminal, + private readonly _options: Partial + ) { +- super(buffer); ++ super(buffer, _terminal.cols); + + // For xterm headless: fallback to ansi colors + if ((_terminal as any)._core._themeService) { diff --git a/config/patches/xterm-src/@xterm__addon-serialize@0.15.0-beta.300.src.patch b/config/patches/xterm-src/@xterm__addon-serialize@0.15.0-beta.300.src.patch index 00e8abcfa1d..c975ff07410 100644 --- a/config/patches/xterm-src/@xterm__addon-serialize@0.15.0-beta.300.src.patch +++ b/config/patches/xterm-src/@xterm__addon-serialize@0.15.0-beta.300.src.patch @@ -1,8 +1,16 @@ diff --git a/src/SerializeAddon.ts b/src/SerializeAddon.ts -index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b01fdff0a 100644 +index e1728feb219c362dfa2ecb602ff99f830d520757..265b9792403601c286bc341f9d046dcd3062e1be 100644 --- a/src/SerializeAddon.ts +++ b/src/SerializeAddon.ts -@@ -12,6 +12,36 @@ import { IAttributeData } from 'common/buffer/Types'; +@@ -5,13 +5,66 @@ + * (EXPERIMENTAL) This Addon is still under development + */ + +-import type { IBuffer, IBufferCell, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; ++import type { IBuffer, IBufferCell, IBufferLine, IBufferRange, ITerminalAddon, Terminal } from '@xterm/xterm'; + import type { IHTMLSerializeOptions, SerializeAddon as ISerializeApi, ISerializeOptions, ISerializeRange } from '@xterm/addon-serialize'; + import { IColor } from 'common/Types'; + import { IAttributeData } from 'common/buffer/Types'; import { DEFAULT_ANSI_COLORS } from 'browser/Types'; import { UnderlineStyle } from 'common/buffer/Constants'; @@ -35,11 +43,63 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b + const attrs = (terminal as TerminalWithOscLinks)._core?._inputHandler?._curAttrData; + return attrs ? getOscLinkOpenSequence(terminal, getOscLinkId(attrs)) : ''; +} ++ ++// PATCH(orca): a non-reflowing shrink (always the alternate buffer) leaves each ++// line at its old length; cells past the grid are not on screen and would wrap ++// into extra rows on replay, so serialize only the terminal's width. ++function visibleCellCount(line: IBufferLine, cols: number): number { ++ return Math.min(line.length, cols); ++} ++ ++// PATCH(orca): a wide glyph whose trailing half fell past the grid cannot be ++// replayed in the last column (it would wrap and shift every row below), so it ++// is serialized as a blank that keeps the row exactly the grid's width. ++function isClippedWideCell(line: IBufferLine, col: number, cols: number, cell: IBufferCell): boolean { ++ return col === cols - 1 && line.length > cols && cell.getWidth() > 1; ++} ++ ++// Width 1 with no codepoint (CellData.content layout). A width-0 stand-in would read as a ++// wide glyph's trailer: skipped by _nextCell and treated as content by the wrap check. ++const BLANK_CELL_CONTENT = 1 << 22; ++ ++function blankClippedWideCell(cell: IBufferCell): IBufferCell { ++ (cell as IBufferCell & { content: number }).content = BLANK_CELL_CONTENT; ++ return cell; ++} + function constrain(value: number, low: number, high: number): number { return Math.max(low, Math.min(value, high)); } -@@ -148,12 +178,14 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -27,7 +80,8 @@ function escapeHTMLChar(c: string): string { + // TODO: Refine this template class later + abstract class BaseSerializeHandler { + constructor( +- protected readonly _buffer: IBuffer ++ protected readonly _buffer: IBuffer, ++ private readonly _cols: number + ) { + } + +@@ -48,13 +102,16 @@ abstract class BaseSerializeHandler { + const line = this._buffer.getLine(row); + if (line) { + const startLineColumn = row === range.start.y ? startColumn : 0; +- const endLineColumn = row === range.end.y ? endColumn: line.length; ++ const endLineColumn = row === range.end.y ? endColumn: visibleCellCount(line, this._cols); + for (let col = startLineColumn; col < endLineColumn; col++) { +- const c = line.getCell(col, oldCell === cell1 ? cell2 : cell1); ++ let c = line.getCell(col, oldCell === cell1 ? cell2 : cell1); + if (!c) { + console.warn(`Can't get cell at row=${row}, col=${col}`); + continue; + } ++ if (isClippedWideCell(line, col, this._cols, c)) { ++ c = blankClippedWideCell(c); ++ } + this._nextCell(c, oldCell, row, col); + oldCell = c; + } +@@ -148,18 +205,22 @@ class StringSerializeHandler extends BaseSerializeHandler { // this is a null cell for reference for checking whether background is empty or not private _backgroundCell: IBufferCell = this._buffer.getNullCell(); @@ -51,10 +111,44 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b private _lastContentCursorRow: number = 0; private _lastContentCursorCol: number = 0; + private _activeOscLinkId: number = 0; ++ private _lastBackgroundCursorRow: number = -1; ++ private _lastBackgroundCursorCol: number = 0; constructor( buffer: IBuffer, -@@ -214,7 +246,7 @@ class StringSerializeHandler extends BaseSerializeHandler { + private readonly _terminal: Terminal + ) { +- super(buffer); ++ super(buffer, _terminal.cols); + } + + protected _beforeSerialize(rows: number, start: number, end: number): void { +@@ -178,6 +239,9 @@ class StringSerializeHandler extends BaseSerializeHandler { + if (this._nullCellCount > 0 && !equalBg(this._cursorStyle, this._backgroundCell)) { + // use clear right to set background. + this._currentRow += `\u001b[${this._nullCellCount}X`; ++ // PATCH(orca): the erase paints this row, so _serializeString must not trim it as trailing blank. ++ this._lastBackgroundCursorRow = this._lastCursorRow; ++ this._lastBackgroundCursorCol = this._lastCursorCol; + } + + let rowSeparator = ''; +@@ -202,8 +266,12 @@ class StringSerializeHandler extends BaseSerializeHandler { + this._lastCursorCol = 0; + } else { + rowSeparator = ''; +- const thisRowLastChar = currentLine.getCell(currentLine.length - 1, this._thisRowLastChar)!; +- const thisRowLastSecondChar = currentLine.getCell(currentLine.length - 2, this._thisRowLastSecondChar)!; ++ const currentLineCells = visibleCellCount(currentLine, this._terminal.cols); ++ let thisRowLastChar = currentLine.getCell(currentLineCells - 1, this._thisRowLastChar)!; ++ if (isClippedWideCell(currentLine, currentLineCells - 1, this._terminal.cols, thisRowLastChar)) { ++ thisRowLastChar = blankClippedWideCell(thisRowLastChar); ++ } ++ const thisRowLastSecondChar = currentLine.getCell(currentLineCells - 2, this._thisRowLastSecondChar)!; + const nextRowFirstChar = nextLine.getCell(0, this._nextRowFirstChar)!; + const isNextRowFirstCharDoubleWidth = nextRowFirstChar.getWidth() > 1; + +@@ -214,7 +282,7 @@ class StringSerializeHandler extends BaseSerializeHandler { if ( // you must output character to cause overflow, control sequence can't do this nextRowFirstChar.getChars() && @@ -63,12 +157,12 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b ) { if ( // the last character can't be null, -@@ -251,9 +283,14 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -251,9 +319,14 @@ class StringSerializeHandler extends BaseSerializeHandler { if (this._nullCellCount > 0) { // do these because we filled the last several null slot, which we shouldn't rowSeparator += '\u001b[A'; - rowSeparator += `\u001b[${currentLine.length - this._nullCellCount}C`; -+ const contentCellCount = currentLine.length - this._nullCellCount; ++ const contentCellCount = currentLineCells - this._nullCellCount; + if (contentCellCount > 0) { + rowSeparator += `\u001b[${contentCellCount}C`; + } @@ -80,7 +174,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b rowSeparator += '\u001b[B'; } -@@ -310,7 +347,20 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -310,7 +383,20 @@ class StringSerializeHandler extends BaseSerializeHandler { } if (flagsChanged) { if (cell.isInverse() !== oldCell.isInverse()) { sgrSeq.push(cell.isInverse() ? 7 : 27); } @@ -102,7 +196,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b if (!equalUnderline(cell, oldCell)) { const style = cell.getUnderlineStyle(); if (style === UnderlineStyle.NONE) { -@@ -337,7 +387,7 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -337,7 +423,7 @@ class StringSerializeHandler extends BaseSerializeHandler { if (cell.isBlink() !== oldCell.isBlink()) { sgrSeq.push(cell.isBlink() ? 5 : 25); } if (cell.isInvisible() !== oldCell.isInvisible()) { sgrSeq.push(cell.isInvisible() ? 8 : 28); } if (cell.isItalic() !== oldCell.isItalic()) { sgrSeq.push(cell.isItalic() ? 3 : 23); } @@ -111,7 +205,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b if (cell.isStrikethrough() !== oldCell.isStrikethrough()) { sgrSeq.push(cell.isStrikethrough() ? 9 : 29); } } } -@@ -346,6 +396,20 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -346,6 +432,20 @@ class StringSerializeHandler extends BaseSerializeHandler { return sgrSeq; } @@ -132,7 +226,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b protected _nextCell(cell: IBufferCell, oldCell: IBufferCell, row: number, col: number): void { // a width 0 cell don't need to be count because it is just a placeholder after a CJK character; const isPlaceHolderCell = cell.getWidth() === 0; -@@ -356,12 +420,21 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -356,12 +456,21 @@ class StringSerializeHandler extends BaseSerializeHandler { // this cell don't have content const isEmptyCell = cell.getChars() === ''; @@ -157,7 +251,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b /** * handles style change -@@ -395,7 +468,7 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -395,7 +504,7 @@ class StringSerializeHandler extends BaseSerializeHandler { /** * handles actual content */ @@ -166,7 +260,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b this._nullCellCount += cell.getWidth(); } else { if (this._nullCellCount > 0) { -@@ -411,7 +484,22 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -411,7 +520,22 @@ class StringSerializeHandler extends BaseSerializeHandler { this._nullCellCount = 0; } @@ -190,7 +284,23 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b // update cursor this._lastContentCursorRow = this._lastCursorRow = row; -@@ -439,6 +527,9 @@ class StringSerializeHandler extends BaseSerializeHandler { +@@ -425,6 +549,15 @@ class StringSerializeHandler extends BaseSerializeHandler { + // the fixup is only required for data without scrollback + // because it will always be placed at last line otherwise + if (this._buffer.length - this._firstRow <= this._terminal.rows) { ++ // PATCH(orca): keep trailing background-only rows, unless the cursor is wrap-pending: ++ // relative moves back from those rows cannot re-create that state. ++ if ( ++ this._lastBackgroundCursorRow > this._lastContentCursorRow && ++ this._buffer.cursorX < this._terminal.cols ++ ) { ++ this._lastContentCursorRow = this._lastBackgroundCursorRow; ++ this._lastContentCursorCol = this._lastBackgroundCursorCol; ++ } + rowEnd = this._lastContentCursorRow + 1 - this._firstRow; + this._lastCursorCol = this._lastContentCursorCol; + this._lastCursorRow = this._lastContentCursorRow; +@@ -439,6 +572,9 @@ class StringSerializeHandler extends BaseSerializeHandler { } } @@ -200,7 +310,7 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b // restore the cursor if (!excludeFinalCursorPosition) { const realCursorRow = this._buffer.baseY + this._buffer.cursorY; -@@ -616,6 +707,9 @@ export class SerializeAddon implements ITerminalAddon, ISerializeApi { +@@ -616,6 +752,9 @@ export class SerializeAddon implements ITerminalAddon, ISerializeApi { content += this._serializeScrollRegion(this._terminal); } @@ -210,3 +320,12 @@ index e1728feb219c362dfa2ecb602ff99f830d520757..957da98c8b30835cc2d114b4b66b228b return content; } +@@ -642,7 +781,7 @@ export class HTMLSerializeHandler extends BaseSerializeHandler { + private readonly _terminal: Terminal, + private readonly _options: Partial + ) { +- super(buffer); ++ super(buffer, _terminal.cols); + + // For xterm headless: fallback to ansi colors + if ((_terminal as any)._core._themeService) { diff --git a/config/scripts/build-serialize-addon-at-ref.mjs b/config/scripts/build-serialize-addon-at-ref.mjs new file mode 100644 index 00000000000..d318882b62e --- /dev/null +++ b/config/scripts/build-serialize-addon-at-ref.mjs @@ -0,0 +1,123 @@ +#!/usr/bin/env node +// Materializes the patched @xterm/addon-serialize dist of any git ref, for the +// differential serialize fuzz (src/main/daemon/serialize-grid.differential.fuzz.test.ts): +// +// node config/scripts/build-serialize-addon-at-ref.mjs --ref origin/main --out-dir /tmp/serialize-old +// ORCA_OLD_SERIALIZE_ADDON= pnpm exec vitest run --config config/vitest.config.ts src/main/daemon/serialize-grid.differential.fuzz.test.ts +// +// It recovers the pristine dist by reverse-applying whichever patch produced the +// installed node_modules copy, applies the ref's patch, and checks every step +// against the blob hashes in the patches' index lines. + +import { execFileSync } from 'node:child_process' +import { createHash } from 'node:crypto' +import { + cpSync, + existsSync, + mkdirSync, + readFileSync, + readdirSync, + rmSync, + writeFileSync +} from 'node:fs' +import path from 'node:path' + +const REPO_ROOT = path.resolve(import.meta.dirname, '..', '..') +const PACKAGE = '@xterm/addon-serialize' +const DIST_FILE = 'lib/addon-serialize.js' + +function parseArgs(argv) { + const args = {} + for (let i = 0; i < argv.length; i += 2) { + args[argv[i].replace(/^--/, '')] = argv[i + 1] + } + if (!args.ref || !args['out-dir']) { + throw new Error('usage: build-serialize-addon-at-ref.mjs --ref --out-dir ') + } + return args +} + +function git(args, options = {}) { + return execFileSync('git', args, { encoding: 'utf8', maxBuffer: 64 * 1024 * 1024, ...options }) +} + +function blobHash(content) { + return createHash('sha1').update(`blob ${content.length}\0`).update(content).digest('hex') +} + +function patchFileName() { + const name = readdirSync(path.join(REPO_ROOT, 'config', 'patches')).find( + (file) => file.startsWith('@xterm__addon-serialize@') && file.endsWith('.patch') + ) + if (!name) { + throw new Error('no @xterm/addon-serialize dist patch under config/patches') + } + return name +} + +/** Pre- and post-image blob hashes the patch records for the dist file. */ +function distHashes(patchText) { + const match = patchText.match( + new RegExp(`diff --git a/${DIST_FILE} b/${DIST_FILE}\\nindex ([0-9a-f]+)\\.\\.([0-9a-f]+)`) + ) + if (!match) { + throw new Error(`patch does not touch ${DIST_FILE}`) + } + return { pristine: match[1], patched: match[2] } +} + +function applyPatch(packageDir, patchPath, reverse) { + // Ceiling stops git from discovering an enclosing repository, so paths stay package-relative. + git(['apply', ...(reverse ? ['-R'] : []), `--include=${DIST_FILE}`, patchPath], { + cwd: packageDir, + env: { ...process.env, GIT_CEILING_DIRECTORIES: path.dirname(packageDir) } + }) +} + +function main() { + const args = parseArgs(process.argv.slice(2)) + const outDir = path.resolve(args['out-dir']) + const name = patchFileName() + const relativePatch = path.posix.join('config', 'patches', name) + const refPatch = git(['show', `${args.ref}:${relativePatch}`], { cwd: REPO_ROOT }) + const target = distHashes(refPatch) + + const packageDir = path.join(outDir, 'package') + rmSync(outDir, { recursive: true, force: true }) + mkdirSync(path.join(packageDir, 'lib'), { recursive: true }) + const installed = path.join(REPO_ROOT, 'node_modules', PACKAGE, DIST_FILE) + cpSync(installed, path.join(packageDir, DIST_FILE)) + const distPath = path.join(packageDir, DIST_FILE) + const installedHash = blobHash(readFileSync(distPath)) + + if (installedHash !== target.patched) { + const candidates = [ + readFileSync(path.join(REPO_ROOT, relativePatch), 'utf8'), + git(['show', `HEAD:${relativePatch}`], { cwd: REPO_ROOT }) + ] + const source = candidates.find((text) => distHashes(text).patched === installedHash) + if (!source) { + throw new Error( + `installed ${DIST_FILE} (${installedHash}) matches neither the working-tree nor the HEAD patch; run pnpm install` + ) + } + const sourcePath = path.join(outDir, 'installed.patch') + writeFileSync(sourcePath, source) + applyPatch(packageDir, sourcePath, true) + if (blobHash(readFileSync(distPath)) !== target.pristine) { + throw new Error(`reverse-applied dist is not the pristine ${target.pristine} the ref patches`) + } + const refPatchPath = path.join(outDir, 'ref.patch') + writeFileSync(refPatchPath, refPatch) + applyPatch(packageDir, refPatchPath, false) + } + const finalHash = blobHash(readFileSync(distPath)) + if (finalHash !== target.patched || !existsSync(distPath)) { + throw new Error( + `built ${DIST_FILE} hashes to ${finalHash}, the ref patch expects ${target.patched}` + ) + } + process.stdout.write(`${distPath}\n`) +} + +main() diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 7ba1cc7f4f5..e1b0edbfae6 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -113,7 +113,7 @@ patchedDependencies: '@xterm/addon-image@0.10.0-beta.300': 5fc280019957573eefe8daa2969534d6090ddb29c6b5842b8f22e99dc1ce3146 '@xterm/addon-ligatures@0.11.0-beta.300': 47405b9994b5acf1b4e90b49250358c1ca03649854d59560e7732b72fe336920 '@xterm/addon-search@0.17.0-beta.300': eee5338dd2621ece46e79c61ec06766cd7fadaf79ffdb24e2a8ab68e97ef31f0 - '@xterm/addon-serialize@0.15.0-beta.300': 851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294 + '@xterm/addon-serialize@0.15.0-beta.300': b35533fe252e7e45433150170348889f4e08a6c17f7017ac34ea694d831fec7f '@xterm/addon-webgl@0.20.0-beta.299': 94687e89a0115e6e6aa102837f986debdc029c091527ee5eb4a4e17ceaf9473e '@xterm/xterm@6.1.0-beta.303': dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393 lint-staged@16.4.0: 7333b3837f80a7fbd045964db6d76ba4fc118e49134bdbabb00585b6b7b60673 @@ -143,7 +143,7 @@ importers: version: 0.0.26 '@xterm/addon-serialize': specifier: 0.15.0-beta.300 - version: 0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393)) + version: 0.15.0-beta.300(patch_hash=b35533fe252e7e45433150170348889f4e08a6c17f7017ac34ea694d831fec7f)(@xterm/xterm@6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393)) '@xterm/headless': specifier: 6.1.0-beta.302 version: 6.1.0-beta.302 @@ -10504,7 +10504,7 @@ snapshots: dependencies: '@xterm/xterm': 6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393) - '@xterm/addon-serialize@0.15.0-beta.300(patch_hash=851eac3d75e6d8c013b9f4c053e61d824b23965cb19ecc28e335e05059f3a294)(@xterm/xterm@6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393))': + '@xterm/addon-serialize@0.15.0-beta.300(patch_hash=b35533fe252e7e45433150170348889f4e08a6c17f7017ac34ea694d831fec7f)(@xterm/xterm@6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393))': dependencies: '@xterm/xterm': 6.1.0-beta.303(patch_hash=dd0ccc59cd1ccf99f4d76e5aa2456da165fa0804dce19a833d7638bd07ffa393) diff --git a/src/main/daemon/__fixtures__/pty-transcripts/less.meta.json b/src/main/daemon/__fixtures__/pty-transcripts/less.meta.json new file mode 100644 index 00000000000..be632a6ae32 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/less.meta.json @@ -0,0 +1,9 @@ +{ + "capturedAt": "2026-09-24T04:11:32.894Z", + "platform": "darwin", + "command": ["less", "-R", "sample.ts"], + "cols": 90, + "rows": 25, + "note": "file: a copy of src/main/daemon/headless-emulator.ts plus CJK/emoji lines", + "exitCode": 0 +} diff --git a/src/main/daemon/__fixtures__/pty-transcripts/less.txt b/src/main/daemon/__fixtures__/pty-transcripts/less.txt new file mode 100644 index 00000000000..10b857b5665 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/less.txt @@ -0,0 +1,164 @@ +[?1049h[?1h= import './xterm-env-polyfill' +import { Terminal } from '@xterm/headless' +import { SerializeAddon } from '@xterm/addon-serialize' +import { Unicode11Addon } from '@xterm/addon-unicode11' +import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provide r' +import { + readSavedCursorRegister, + serializeWithAbsoluteCursor +} from '../../shared/terminal-serialize-absolute-cursor' +import { advancePartialEscapeTail } from '../../shared/terminal-partial-escape-tail' +import type { TerminalViewAttributes } from '../../shared/terminal-view-attributes' +import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges' +import { readTerminalModes } from './headless-emulator-modes' +import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences' +import { TerminalMouseModeMirror } from './terminal-mouse-mode-mirror' +import { TerminalOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner' +import { buildFrameRestoreSnapshotFields } from './terminal-frame-restore-sequences' +import { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers' +import { + installTerminalViewAttributeResponder, + type TerminalViewAttributeResponder +} from './terminal-view-attribute-responder' +import { installDeviceAttributesResponder } from './startup-device-attributes-responder' +sample.ts import type { TerminalSnapshot, TerminalModes } from './types' +import type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges' +import type { TerminalCursorContext } from '../../shared/terminal-composer-draft' +import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context' + +export type HeadlessEmulatorOptions = { + cols: number + rows: number + scrollback?: number + /** Query reply sink (terminal-query-authority.md); only `forwardQueryReplies` writes em it here. The daemon Session must never pass this. */ + onQueryReply?: (reply: string) => void + pathFlavor?: 'posix' | 'win32' + remotePosixFileUriAuthority?: boolean + wslDistro?: string +} + +export type HeadlessEmulatorWriteOptions = { + /** Reply ownership for this exact chunk; default false so seed/hydration/snapshot write s never forward (main-side replay guard; twin of renderer replay-guard.ts). */ + forwardQueryReplies?: boolean +} + +type TerminalWithSynchronousWrite = Terminal & { +: /wwiiddee import type { TerminalSnapshot, TerminalModes } from './types' +import type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges' +import type { TerminalCursorContext } from '../../shared/terminal-composer-draft' +import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context' + +export type HeadlessEmulatorOptions = { + cols: number + rows: number + scrollback?: number + /** Query reply sink (terminal-query-authority.md); only `forwardQueryReplies` writes em it here. The daemon Session must never pass this. */ + onQueryReply?: (reply: string) => void + pathFlavor?: 'posix' | 'win32' + remotePosixFileUriAuthority?: boolean + wslDistro?: string +} + +export type HeadlessEmulatorWriteOptions = { + /** Reply ownership for this exact chunk; default false so seed/hydration/snapshot write s never forward (main-side replay guard; twin of renderer replay-guard.ts). */ + forwardQueryReplies?: boolean +} + +type TerminalWithSynchronousWrite = Terminal & { +import type { TerminalSnapshot, TerminalModes } from './types' +import type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges' +import type { TerminalCursorContext } from '../../shared/terminal-composer-draft' +import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context' + +export type HeadlessEmulatorOptions = { + cols: number + rows: number + scrollback?: number + /** Query reply sink (terminal-query-authority.md); only `forwardQueryReplies` writes em it here. The daemon Session must never pass this. */ + onQueryReply?: (reply: string) => void + pathFlavor?: 'posix' | 'win32' + remotePosixFileUriAuthority?: boolean + wslDistro?: string +} + +export type HeadlessEmulatorWriteOptions = { + /** Reply ownership for this exact chunk; default false so seed/hydration/snapshot write s never forward (main-side replay guard; twin of renderer replay-guard.ts). */ + forwardQueryReplies?: boolean +} + +type TerminalWithSynchronousWrite = Terminal & { +...skipping... +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +~ +(END) / ~ +(END) ...skipping... + + setRestoredOscLinks(links: TerminalOscLinkRange[] | undefined): void { + this.restoredOscLinks = links?.slice() ?? [] + } + + clearScrollback(): void { + this.restoredOscLinks = [] + this.terminal.clear() + } + + dispose(): void { + this.disposed = true + this.terminal.dispose() + } + + private getModes(): TerminalModes { + return readTerminalModes(this.terminal, this.mouseModes) + } +} +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji +(END) Mimport { installDeviceAttributesResponder } from './startup-device-attributes-responder' +M} from './terminal-view-attribute-responder' +M type TerminalViewAttributeResponder +M installTerminalViewAttributeResponder, +Mimport { +Mimport { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers' +Mimport { buildFrameRestoreSnapshotFields } from './terminal-frame-restore-sequences' +Mimport { TerminalOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner' +Mimport { TerminalMouseModeMirror } from './terminal-mouse-mode-mirror' +Mimport { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences' +Mimport { readTerminalModes } from './headless-emulator-modes' +Mimport { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges' +Mimport type { TerminalViewAttributes } from '../../shared/terminal-view-attributes' +Mimport { advancePartialEscapeTail } from '../../shared/terminal-partial-escape-tail' +M} from '../../shared/terminal-serialize-absolute-cursor' +M serializeWithAbsoluteCursor +M readSavedCursorRegister, +Mimport { +Mr' +Mimport { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provideMimport { Unicode11Addon } from '@xterm/addon-unicode11' +Mimport { SerializeAddon } from '@xterm/addon-serialize' +Mimport { Terminal } from '@xterm/headless' +Mimport './xterm-env-polyfill' + : [?1l>[?1049l \ No newline at end of file diff --git a/src/main/daemon/__fixtures__/pty-transcripts/nano.meta.json b/src/main/daemon/__fixtures__/pty-transcripts/nano.meta.json new file mode 100644 index 00000000000..922302f837a --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/nano.meta.json @@ -0,0 +1,9 @@ +{ + "capturedAt": "2026-09-24T04:11:42.610Z", + "platform": "darwin", + "command": ["nano", "sample.ts"], + "cols": 80, + "rows": 24, + "note": "macOS /usr/bin/nano is UW PICO 5.09; file: a copy of src/main/daemon/headless-emulator.ts plus CJK/emoji lines", + "exitCode": 1 +} diff --git a/src/main/daemon/__fixtures__/pty-transcripts/nano.txt b/src/main/daemon/__fixtures__/pty-transcripts/nano.txt new file mode 100644 index 00000000000..63358fc7982 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/nano.txt @@ -0,0 +1 @@ +[?1049h UW PICO 5.09 New Buffer ^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos ^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text^T To Spell  [ Reading file ] [ Read 374 lines ] UW PICO 5.09 File: sample.ts import './xterm-env-polyfill'import { Terminal } from '@xterm/headless'import { SerializeAddon } from '@xterm/addon-serialize'import { Unicode11Addon } from '@xterm/addon-unicode11'import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unic$import {readSavedCursorRegister,serializeWithAbsoluteCursor} from '../../shared/terminal-serialize-absolute-cursor'import { advancePartialEscapeTail } from '../../shared/terminal-partial-escape-$import type { TerminalViewAttributes } from '../../shared/terminal-view-attribu$import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges'import { readTerminalModes } from './headless-emulator-modes'import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences'import { TerminalMouseModeMirror } from './terminal-mouse-mode-mirror'import { TerminalOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner'import { buildFrameRestoreSnapshotFields } from './terminal-frame-restore-seque$import { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers'import {^G Get Help ^O WriteOut ^R Read File ^Y Prev Pg ^K Cut Text ^C Cur Pos ^X Exit ^J Justify ^W Where is ^V Next Pg ^U UnCut Text^T To Spell File: sample.ts Modified\x16typed ไธญimport './xterm-env-polyfill'ๆ–‡import './xterm-env-polyfill' text\x18n \ No newline at end of file diff --git a/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.meta.json b/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.meta.json new file mode 100644 index 00000000000..55bdfbf6e4e --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.meta.json @@ -0,0 +1,15 @@ +{ + "capturedAt": "2026-09-24T04:13:47.267Z", + "platform": "darwin", + "command": [ + "opencode", + "run", + "--model", + "opencode/muse-spark-1.3-contributor-free", + "Write a 40-line bash script with comments that prints a colored progress bar using ANSI escapes; include some \u4e2d\u6587 comments. No tools." + ], + "cols": 100, + "rows": 30, + "note": "opencode 1.18.32 run (inline, normal buffer); free Zen model, no account", + "exitCode": 0 +} diff --git a/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.txt b/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.txt new file mode 100644 index 00000000000..d96c9353955 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/opencode-run.txt @@ -0,0 +1,47 @@ + +> build ยท muse-spark-1.3-contributor-free + +Here is a 40-line script: +```bash +#!/bin/bash +# Colored progress bar demo using ANSI escapes +# ๅฝฉ่‰ฒ่ฟ›ๅบฆๆกๆผ”็คบ - ไฝฟ็”จ ANSI ่ฝฌไน‰ๅบๅˆ— +# Usage: ./progress.sh - ็”จๆณ•็คบไพ‹ +set -euo pipefail +# Total steps for simulation - ๆจกๆ‹Ÿๆ€ปๆญฅๆ•ฐ +TOTAL=50 +# Bar width in characters - ่ฟ›ๅบฆๆกๅฎฝๅบฆ +WIDTH=40 +# ANSI color codes - ๅฎšไน‰้ขœ่‰ฒ +GREEN="\033[32m" +YELLOW="\033[33m" +CYAN="\033[36m" +GRAY="\033[90m" +RESET="\033[0m" +# Hide cursor for smooth animation - ้š่—ๅ…‰ๆ ‡ไฝฟๅŠจ็”ปๆ›ดๅนณๆป‘ +hide_cursor() { printf "\033[?25l"; } +# Restore cursor - ๆขๅคๅ…‰ๆ ‡ๆ˜พ็คบ +show_cursor() { printf "\033[?25h"; } +# Always restore cursor on exit - ้€€ๅ‡บๆ—ถ่‡ชๅŠจๆขๅคๅ…‰ๆ ‡ +trap show_cursor EXIT +hide_cursor +# Draw bar: $1 = percent 0-100 - ็ป˜ๅˆถๅ‡ฝๆ•ฐ๏ผŒๅ‚ๆ•ฐไธบ็™พๅˆ†ๆฏ” +draw_bar() { +local percent=$1 +local filled=$(( percent * WIDTH / 100 )) +local empty=$(( WIDTH - filled )) +local color="$GREEN" +# Change color by stage - ๆ นๆฎ้˜ถๆฎตๅ˜ๆข้ขœ่‰ฒ +if [ "$percent" -lt 30 ]; then color="$CYAN"; fi +if [ "$percent" -ge 70 ]; then color="$YELLOW"; fi +local bar="" space="" +printf -v bar '%*s' "$filled" "" +printf -v space '%*s' "$empty" "" +bar=${bar// /โ–ˆ}; space=${space// /โ–‘} +# Print single line with carriage return - ๅ›ž่ฝฆ่ฆ†็›–ๆœฌ่กŒๆ‰“ๅฐ +printf "\r${color}[%s${GRAY}%s${color}]${RESET} %3d%%" "$bar" "$space" "$percent" +} +# Main loop - ไธปๅพช็Žฏๆจกๆ‹Ÿ่ฟ›ๅบฆ +for ((i=0; i<=TOTAL; i++)); do draw_bar $(( i*100/TOTAL )); sleep 0.05; done; echo; echo -e "${GREEN}Done! ๅฎŒๆˆ!${RESET}" +``` + diff --git a/src/main/daemon/__fixtures__/pty-transcripts/opencode.meta.json b/src/main/daemon/__fixtures__/pty-transcripts/opencode.meta.json new file mode 100644 index 00000000000..f69bf8397f4 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/opencode.meta.json @@ -0,0 +1,9 @@ +{ + "capturedAt": "2026-09-24T04:12:53.472Z", + "platform": "darwin", + "command": ["opencode", "--model", "opencode/muse-spark-1.3-contributor-free"], + "cols": 110, + "rows": 32, + "note": "opencode 1.18.32 TUI (alt screen); free Zen model, no account; cwd path redacted", + "exitCode": 0 +} diff --git a/src/main/daemon/__fixtures__/pty-transcripts/opencode.txt b/src/main/daemon/__fixtures__/pty-transcripts/opencode.txt new file mode 100644 index 00000000000..778e4e0c563 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/opencode.txt @@ -0,0 +1 @@ +[?2031h]10;?]11;?[>0q[?25lP+q4d73\[?1016$p[?2027$p[?2031$p[?1004$p[?2004$p[?2026$p[?u]99;i=opentui-notifications:p=?;\]1337;Capabilities\]66;w=1; \]66;s=2; \[?1049h[>4;1m[?2027h[?2004h[?1000h[?1002h[?1003h[?1006h]4;0;?[?2026h[?25l                                [?2026l]0;OpenCode[?2026h[?25l  โ–„ โ–ˆโ–€โ–€โ–ˆ โ–ˆโ–€โ–€โ–ˆ โ–ˆโ–€โ–€โ–ˆ โ–ˆโ–€โ–€โ–„โ–ˆโ–€โ–€โ–€ โ–ˆโ–€โ–€โ–ˆ โ–ˆโ–€โ–€โ–ˆ โ–ˆโ–€โ–€โ–ˆโ–ˆ โ–ˆ โ–ˆ โ–ˆ โ–ˆโ–€โ–€โ–€ โ–ˆ โ–ˆโ–ˆ  โ–ˆ โ–ˆ โ–ˆ โ–ˆ โ–ˆโ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–ˆโ–€โ–€โ–€ โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€ โ–€โ–€โ–€โ–€โ”ƒ โ”ƒ Ask anythingโ€ฆ "Fix broken tests" โ”ƒ โ”ƒ Build ยท Muse Spark 1.3 Free OpenCode Zen โ•นโ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€tab agentsctrl+p commands~/projects/opencode-transcript-demo-1/app1.18.32]12;#eeeeee[1 q[?25h[?2026l[?2026h[?25lPrint a markdown table of 5 CJK words (ไธญๆ–‡, ๆ—ฅๆœฌ่ชž, ํ•œ๊ตญ์–ด) with emoji and their meanings. Do not use tools.    โ”ƒ Build ยท Muse Spark 1.3 Free OpenCode Zen โ•นโ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€tab agentsctrl+p commands[?25h[?2026l[?2026h[?25lAsk anythingโ€ฆ "Fix broken tests"  BuildยทMuse Spark 1.3 FreeOpenCode Zenโ•นโ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ tab agents ctrl+p commands  โ— Tip Comment /oc on PR code lines for targeted code reviews[?25h[?2026l]0;OpenCode[?2026h[?25lโ”ƒ โ”ƒ Print a markdown table of 5 CJK words (ไธญๆ–‡, ๆ—ฅๆœฌ่ชž, ํ•œ๊ตญ์–ด) with emoji and their meanings. Do not use โ”ƒ tools. โ”ƒ โ–ฃ Build ยท Muse Spark 1.3 Free                โ”ƒ โ”ƒ โ”ƒ โ”ƒ Build ยท Muse Spark 1.3 Free OpenCode Zen โ•นโ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€โ–€ โ– โฌโฌโฌโฌโฌโฌโฌ esc interrupt tab agentsctrl+p commands[?25h[?2026l[?2026h[?25l  Print a markdown table of 5 CJK words (ไธญๆ–‡, ๆ—ฅๆœฌ่ชž, ํ•œ๊ตญ์–ด) with emoji and their meanings. Do not use tools.โ”ƒ   โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l]0;OpenCode[?2026h[?25lโ– โ– โฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โ– โฌโฌ[?25h[?2026l[?2026h[?25lโฌโ– โ– โ– โ– โ– โ– โฌ[?25h[?2026l[?2026h[?25lโฌโฌโ– โ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโ– โ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโ– โ– โ– โ– โ– โ– โฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โ– โฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ‹ Thinking โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโ– โ– โฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ™[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ น[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ธ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ผ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ด[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ฆ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ง[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l]0;OC | CJK words emoji meanings table[?2026h[?25lโ ‡[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ ‹[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lThought ยท 877ms[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25l  โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25l| Word | Language | Pronโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lunciation | Emoji | Meaning ||------|  โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”โ”‚Word โ”‚Languageโ”‚Pronunciationโ”‚Emojiโ”‚Meaningโ”‚โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”คโ”‚็ˆฑ โ”‚ไธญ โ”‚ โ”‚ โ”‚ โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lๆ–‡[?25h[?2026l[?2026h[?25lโ– โฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lร i[?25h[?2026l[?2026h[?25lโ– โ– โฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโค๏ธlove[?25h[?2026l[?2026h[?25lโ– โ– โ– โฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโ”œโ”ผโ”ผโ”ผโ”ผโ”คโ”‚ๆฐดโ”‚ โ”‚ โ”‚ โ”‚ โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โฌโฌโฌ[?25h[?2026l[?2026h[?25lๆ—ฅๆœฌ่ชž[?25h[?2026l[?2026h[?25lโ– โ– โ– โ– โ– โ– โฌโฌ[?25h[?2026l[?2026h[?25lใฟ[?25h[?2026l[?2026h[?25lโฌโ– โ– โ– โ– โ– โ– โฌ[?25h[?2026l[?2026h[?25lโฌโฌโ– โ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lใš ([?25h[?2026l[?2026h[?25lmizu)๐Ÿ’งwaterโ”œโ”ผโ”ผโ”ผโ”ผโ”คโ”‚์‚ฌ๋ž‘โ”‚ โ”‚ โ”‚ โ”‚ โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโฌโฌโฌโ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25lํ•œ๊ตญ์–ดsar[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโ– โ– โ– [?25h[?2026l[?2026h[?25lang[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโ– โ– [?25h[?2026l[?2026h[?25l๐Ÿฅฐloveโ”œโ”ผโ”ผโ”ผโ”ผโ”คโ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25l้พไธญๆ–‡lโฌโฌโฌโฌโฌโฌโฌโ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lรณng๐Ÿ‰dragonโ”œโ”ผโ”ผโ”ผโ”ผโ”คโ”‚ โ”‚ โ”‚ โ”‚ โ”‚ โ”‚โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜โ–ฃ Build ยท Muse Spark 1.3 Free[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโฌโฌ[?25h[?2026l[?2026h[?25lๆกœๆ—ฅๆœฌ่ชžใ•[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโฌโ– โ– [?25h[?2026l[?2026h[?25lโ”ฌโ”€โ”ฌโ”€โ”ฌโ”€โ”ฌโ”€โ”‚Language โ”‚Pronunciaton โ”‚Emoji โ”‚Meaning โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”‚ไธญๆ–‡ โ”‚ร i โ”‚โค๏ธ โ”‚love โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”‚ๆ—ฅๆœฌ่ชž โ”‚ใฟใš (mizu) โ”‚๐Ÿ’ง โ”‚water โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”‚ํ•œ๊ตญ์–ด โ”‚sarang โ”‚๐Ÿฅฐ โ”‚love โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”‚ไธญๆ–‡ โ”‚lรณng โ”‚๐Ÿ‰ โ”‚dragon โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”ผโ”€โ”‚ๆ—ฅๆœฌ่ชž โ”‚ใ•ใใ‚‰ (sakura)โ”‚๐ŸŒธ โ”‚cherry blossomโ”ดโ”€โ”ดโ”€โ”ดโ”€โ”ดโ”€[?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโฌโ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโฌโ– โ– โ– โ– [?25h[?2026l[?2026h[?25lโฌโฌโฌโ– โ– โ– โ– โ– [?25h[?2026l[?2026h[?25l ยท 3.2s/home/user/projects/opencode-transcript-fixture-1/app12.9K (1%)[?25h[?2026l \ No newline at end of file diff --git a/src/main/daemon/__fixtures__/pty-transcripts/vim.meta.json b/src/main/daemon/__fixtures__/pty-transcripts/vim.meta.json new file mode 100644 index 00000000000..29ec6c3d90e --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/vim.meta.json @@ -0,0 +1,19 @@ +{ + "capturedAt": "2026-09-24T04:11:27.821Z", + "platform": "darwin", + "command": [ + "vim", + "-u", + "NONE", + "-N", + "-c", + "syntax on", + "-c", + "set number ruler laststatus=2", + "sample.ts" + ], + "cols": 100, + "rows": 30, + "note": "file: a copy of src/main/daemon/headless-emulator.ts plus CJK/emoji lines", + "exitCode": 0 +} diff --git a/src/main/daemon/__fixtures__/pty-transcripts/vim.txt b/src/main/daemon/__fixtures__/pty-transcripts/vim.txt new file mode 100644 index 00000000000..d6e4adeacf9 --- /dev/null +++ b/src/main/daemon/__fixtures__/pty-transcripts/vim.txt @@ -0,0 +1,79 @@ +[?1049h[>4;2m[?1h=[?2004h[?1004h[?12h[?12l[?25l"sample.ts" 374L, 14852Bโ–ฝ Pzz\[0%m [>c 1 import './xterm-env-polyfill' + 2 import { Terminal } from '@xterm/headless' 3 import { SerializeAddon } from '@xterm/addon-serialize' 4 import { Unicode11Addon } from '@xterm/addon-unicode11' + 5 import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provider' + 6 import { + 7  readSavedCursorRegister, + 8  serializeWithAbsoluteCursor + 9 } from '../../shared/terminal-serialize-absolute-cursor' + 10 import { advancePartialEscapeTail } from '../../shared/terminal-partial-escape-tail' + 11 import type { TerminalViewAttributes } from '../../shared/terminal-view-attributes' + 12 import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges' + 13 import { readTerminalModes } from './headless-emulator-modes' + 14 import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences' + 15 import { TerminalMouseModeMirror } from './terminal-mouse-mode-mirror' + 16 import { TerminalOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner' + 17 import { buildFrameRestoreSnapshotFields } from './terminal-frame-restore-sequences' + 18 import { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers' + 19 import { + 20  installTerminalViewAttributeResponder, + 21  type TerminalViewAttributeResponder + 22 } from './terminal-view-attribute-responder' + 23 import { installDeviceAttributesResponder } from './startup-device-attributes-responder' + 24 import type { TerminalSnapshot, TerminalModes } from './types' + 25 import type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges' + 26 import type { TerminalCursorContext } from '../../shared/terminal-composer-draft' + 27 import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context' + 28  +sample.ts 1,1 Top[?25h[?4m[?25lG  + +'redrawtime' exceeded, syntax highlighting disabled347348 setLastTitle(title: string): void {349 this.oscText.lastTitle = title350 }351352 setRestoredOscLinks(links: TerminalOscLinkRange[] | undefined): void { +353 this.restoredOscLinks = links?.slice() ?? [] +354}355356 clearScrollback(): void {357 this.restoredOscLinks = []358 this.terminal.clear()359 }360361 dispose(): void {362 this.disposed = true363 this.terminal.dispose()364 }365366private getModes(): TerminalModes {367 return readTerminalModes(this.terminal, this.mouseModes) +368 }369}370ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji371ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoj372ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji373ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€ emoji374ไธญๆ–‡ๅญ—็ฌฆ wide line ๐Ÿ˜€emoji374,1Bot[?25h[?25l/wide 4-10[?25h[?25lide line ๐Ÿ˜€ emoji[+][?25h[?25l [?25h[?25l6[?25h[?25l  1import './xterm-env-polyfill' + 2import { Terminal } from '@xterm/headless' + 3import { SerializeAddon } from '@xterm/addon-serialize' + 4import { Unicode11Addon } from '@xterm/addon-unicode11' + 5import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provider' + 6import { 7readSavedCursorRegister, 8serializeWithAbsoluteCursor + 9} from '../../shared/terminal-serialize-absolute-cursor' + 10import { advancePartialEscapeTail } from '../../shared/terminal-partial-escape-tail' + 11import type { TerminalViewAttributes } from '../../shared/terminal-view-attributes' + 12import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges' + 13import { readTerminalModes } from './headless-emulator-modes' + 14import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences' + 15import { TerminalMouseModeMirror } from './terminal-mouse-mode-mirror' + 16import { TerminalOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner' + 17import { buildFrameRestoreSnapshotFields } from './terminal-frame-restore-sequences' + 18import { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers' + 19import { + 20installTerminalViewAttributeResponder, + 21type TerminalViewAttributeRespond 22} from './terminal-view-attribute-responder' + 23import { installDeviceAttributesResponder } from './startup-device-attributes-responder' + 24import type { TerminalSnapshot, TerminalModes } from './types' + 25import type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges' + 26import type { TerminalCursorContext } from '../../shared/terminal-composer-draft' + 27import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context' + 286,1 Top[?25h[?25l-- INSERT -- 6 ไธญๆ–‡ inserted ๐Ÿ˜€line7 + 8 + 9 + 10 + 11 + 12 + 13 + 14 + 15 + 16 + 17 + 18 + 19 + 20 + 21 + 22 + 23 + 24 + 25 + 26 + 27 + 28 + +-- INSERT --^[[?25h[?25l 25-21[?25h[?25l:vsplit ||| erialize' |4Unicode11Addon } from '@xterm/addon-u| nicode11' |5activateOrcaTerminalUnicodeProvider }| from '../../shared/terminal-unicode-provider'|6ไธญๆ–‡ inserted ๐Ÿ˜€ line | 7import { | 8 readSavedCursorRegister, | 9 serializeWithAbsoluteCursor |0} from '../../shared/terminal-serialize-absolu| te-cursor' |1advancePartialEscapeTail } from '../.| ./shared/t-partial-escape-tail' |2type { TerminalViewAttributes } from '.| ./../shared/terminal-view-attributes' |3collectHeadlessOscLinkRanges } from '| ./headless-osc-link-ranges'|14import { readTerminalModes } from './headless-| emulator-modes' |15import { buildRehydrateSequences } from './ter| minal-mode-rehydrate-sequences' |16{ TerminalMouseModeMirror } from './ter| minal-mouse-mode-mirror' |1{ TerminalOscCwdTitleScanner/| terminal-osc-cwd-title-scanner' |6,25-21Top 1 import './xterm-env-polyfill' 2 import { Terminal } from '@xterm/headless' 3 import { SerializeAddon } from '@xterm/addon- serialize' 4 import { Unicode11Addon } from '@xterm/addon- unicode11' 5 import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provide r' 6 ไธญๆ–‡ inserted ๐Ÿ˜€line 7 import { 8  readSavedCursorRegister, 9  serializeWithAbsoluteCursor 10 } from '../../shared/terminal-serialize-absol ute-cursor' 11 import { advancePartialEscapeTail } from '../ ../shared/terminal-partial-escape-tail' 12 import type { TerminalViewAttributes } from ' ../../shared/terminal-view-attributes' 13 import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges' 14 import { readTerminalModes } from './headless -emulator-modes' 15 import { buildRehydrateSequences } from './te rminal-mode-rehydrate-sequences' 16 import { TerminalMouseModeMirror } from './te rminal-mouse-mode-mirror' 17 import { TOscCwdTitleScanner } from '. @ sample.ts [+] 6,25-21 Top[?25h[?25l:set list $$$$ $ 6ไธญๆ–‡ inserted ๐Ÿ˜€line$7import {$ 8readSavedCursorRegister,$  9 serializeWithAbsoluteCursor$ 10} from '../../shared/terminal-serialize-absolu te-cursor'$ 11import { advancePartialEscapeTail } from '../. ./shared/terminal-partial-escape-tail'$ 12import type { TerminalViewA } from '. ./../shared/terminal-view-attributes'$ 13import { collectHeadlessOscLinkRanges } from ' ./headless-osc-link-ranges'$ 14import { readTerminalModes } from './headless- emulator-modes'$ 15import { buildRehydrateSequences } from './ter minal-mode-rehydrate-sequences'$ 16import { TerminalMouseModeMirror } from './ter minal-mouse-mode-mirror'$ 17import { TerminalOscCwdTitleScanner } from './ @ [?25h[?25l:q! erialize'4import { Unicode11Addon } from '@xterm/addon-unicode11'5activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provider'6ไธญๆ–‡ inserted ๐Ÿ˜€line78 readSavedCursorRegister,9 serializeWithAbsoluteCursor10} from '../../shared/terminal-serialize-absolute-cursor'11 advancePartialEscapeTail } from '../../shared/terminal-partial-escape-tail'12import type { TerminalViewAttributes } from '../../shared/terminal-view-attributes'13import { collectHeadlessOscLinkRanges } from './headless-osc-link-ranges'4import { readTerminalModes } from './headless-emulator-modes'15import { buildRehydrateSequences } from './terminal-mode-rehydrate-sequences'6TerminalMouseModeMirror } from './terminal-mouse-mode-mirror'17import { TOscCwdTitleScanner } from './terminal-osc-cwd-title-scanner'8{ buildFrameRestoreSnapshotFields } from './terminal-frame-restore-sequences'19import { splitTerminalSnapshotAnsi } from './terminal-snapshot-ansi-buffers'2021 installTerminalViewAttributeResponder,22 type TerminalViewAttributeResponder23} from './terminal-view-attribute-responder'24installDeviceAttributesResponder } from './startup-device-attributes-responder'25import type { TerminalSnapshot, TerminalModes } from './types'2type { TerminalOscLinkRange } from '../../shared/terminal-osc-link-ranges'27import type { TerminalCursorContext } from '../../shared/terminal-composer-draft'28import { readTerminalCursorLineContext } from '../../shared/terminal-cursor-line-context'  6,25-21 Top[?25h[?25l:q! [?2004l[>4;m[?1004l[?2004l[?1l>[?1049l[?25h[>4;m \ No newline at end of file diff --git a/src/main/daemon/headless-emulator-shrink-snapshot.test.ts b/src/main/daemon/headless-emulator-shrink-snapshot.test.ts new file mode 100644 index 00000000000..07efdd8f2c2 --- /dev/null +++ b/src/main/daemon/headless-emulator-shrink-snapshot.test.ts @@ -0,0 +1,134 @@ +/** + * xterm keeps a line's old length after a column shrink whenever it does not + * reflow (the alternate buffer always; the normal buffer on pre-21376 ConPTY). + * The snapshot must still describe only the visible grid, or the stale + * right-hand cells wrap into garbage rows when a restore replays it. + */ +import { describe, expect, it } from 'vitest' +import { Terminal } from '@xterm/headless' +import { SerializeAddon } from '@xterm/addon-serialize' +import { Unicode11Addon } from '@xterm/addon-unicode11' +import { HeadlessEmulator } from './headless-emulator' +import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provider' + +const WIDE = 135 +const NARROW = 48 +const ROWS = 6 +const NARROW_GRID = Array.from({ length: ROWS }, (_, y) => `narrow${y + 1}`.padEnd(NARROW, ' ')) + +type Writable = { + write(data: string): Promise | void + resize(cols: number, rows: number): void +} + +function writeTerminal(terminal: Terminal, data: string): Promise { + return new Promise((resolve) => terminal.write(data, resolve)) +} + +function visibleRows(terminal: Terminal): string[] { + const buffer = terminal.buffer.active + return Array.from( + { length: terminal.rows }, + (_, y) => buffer.getLine(buffer.viewportY + y)?.translateToString(true, 0, terminal.cols) ?? '' + ) +} + +async function replayAtNarrowGrid(ansi: string): Promise { + const restored = new Terminal({ cols: NARROW, rows: ROWS, allowProposedApi: true }) + await writeTerminal(restored, ansi) + return restored +} + +async function paintShrinkRepaint(target: Writable, prefix: string): Promise { + await target.write(`${prefix}\x1b[48;5;236m`) + for (let y = 1; y <= ROWS; y++) { + await target.write(`\x1b[${y};1H${`WIDE${y}`.padEnd(WIDE, '.')}`) + } + target.resize(NARROW, ROWS) + // Differential repaint of the narrow grid: no clear, like OpenTUI after SIGWINCH. + for (let y = 1; y <= ROWS; y++) { + await target.write(`\x1b[${y};1H${`narrow${y}`.padEnd(NARROW, ' ')}`) + } +} + +describe('snapshot after a column shrink', () => { + it('restores the visible alternate-screen grid, not the stale pre-shrink cells', async () => { + const emu = new HeadlessEmulator({ cols: WIDE, rows: ROWS }) + await paintShrinkRepaint(emu, '\x1b[?1049h') + expect(emu.getVisibleLines()[0]).toMatch(/^narrow1/) + const snapshot = emu.getSnapshot() + + // The restorer owns the alt-screen transition that the snapshot split strips. + const restored = await replayAtNarrowGrid( + `${snapshot.scrollbackAnsi ?? ''}\x1b[?1049h${snapshot.snapshotAnsi}` + ) + + expect(snapshot.modes.alternateScreen).toBe(true) + expect(visibleRows(restored)).toEqual(NARROW_GRID) + emu.dispose() + }) + + it('restores the visible normal-buffer grid when the shrink did not reflow', async () => { + const terminal = new Terminal({ + cols: WIDE, + rows: ROWS, + allowProposedApi: true, + windowsPty: { backend: 'conpty', buildNumber: 19041 } + }) + const serializer = new SerializeAddon() + terminal.loadAddon(serializer) + await paintShrinkRepaint( + { write: (data) => writeTerminal(terminal, data), resize: (c, r) => terminal.resize(c, r) }, + '' + ) + expect(visibleRows(terminal)).toEqual(NARROW_GRID) + + const restored = await replayAtNarrowGrid(serializer.serialize()) + + expect(visibleRows(restored)).toEqual(NARROW_GRID) + }) + + it.each([ + ['CJK', 'ไธญ'], + ['emoji', '๐Ÿ˜€'] + ])('blanks a %s cell whose trailing half fell past the grid', async (_kind, glyph) => { + const emu = new HeadlessEmulator({ cols: 10, rows: 3 }) + await emu.write(`\x1b[?1049h\x1b[1;1Habcdefgh${glyph}\x1b[2;1Hrow2\x1b[3;1Hrow3`) + emu.resize(9, 3) + + const rows = await replayEmulatorAt(emu, 9, 3) + + expect(rows).toEqual(['abcdefgh', 'row2', 'row3']) + emu.dispose() + }) + + it.each([ + ['CJK', 'ไธญ'], + ['emoji', '๐Ÿ˜€'] + ])('keeps a %s cell that ends exactly at the grid edge', async (_kind, glyph) => { + const emu = new HeadlessEmulator({ cols: 10, rows: 3 }) + await emu.write(`\x1b[?1049h\x1b[1;1Habcdefg${glyph}x\x1b[2;1Hrow2\x1b[3;1Hrow3`) + emu.resize(9, 3) + + const rows = await replayEmulatorAt(emu, 9, 3) + + expect(rows).toEqual([`abcdefg${glyph}`, 'row2', 'row3']) + emu.dispose() + }) +}) + +async function replayEmulatorAt( + emu: HeadlessEmulator, + cols: number, + rows: number +): Promise { + const snapshot = emu.getSnapshot() + const restored = new Terminal({ cols, rows, allowProposedApi: true }) + restored.loadAddon(new Unicode11Addon()) + activateOrcaTerminalUnicodeProvider(restored) + await writeTerminal( + restored, + `${snapshot.scrollbackAnsi ?? ''}\x1b[?1049h${snapshot.snapshotAnsi}` + ) + return visibleRows(restored) +} diff --git a/src/main/daemon/serialize-addon-edge-cases.test.ts b/src/main/daemon/serialize-addon-edge-cases.test.ts new file mode 100644 index 00000000000..d20d31c901d --- /dev/null +++ b/src/main/daemon/serialize-addon-edge-cases.test.ts @@ -0,0 +1,63 @@ +/** + * Minimal repros for serializer round-trip faults the differential fuzz found + * (serialize-grid.differential.fuzz.test.ts): each replays a SerializeAddon + * snapshot at the source grid and expects the same cells and cursor. + */ +import { describe, expect, it } from 'vitest' +import type { Terminal } from '@xterm/headless' +import { SerializeAddon } from '@xterm/addon-serialize' +import { createFuzzTerminal, writeTerminal } from './serialize-grid-roundtrip' + +function paintedGrid(terminal: Terminal): string[] { + const buffer = terminal.buffer.active + return Array.from({ length: terminal.rows }, (_, y) => { + const line = buffer.getLine(buffer.viewportY + y) + return Array.from({ length: terminal.cols }, (_, x) => { + const cell = line?.getCell(x) + return `${cell?.getChars() || ' '}${cell?.isBgDefault() ? '' : '*'}` + }).join('') + }) +} + +function snapshotState(terminal: Terminal): { grid: string[]; cursor: string; type: string } { + const buffer = terminal.buffer.active + return { + grid: paintedGrid(terminal), + cursor: `${buffer.cursorX},${buffer.cursorY},${buffer.baseY}`, + type: buffer.type + } +} + +function roundTrip(source: Terminal): ReturnType { + const serializer = new SerializeAddon() + source.loadAddon(serializer) + const replay = createFuzzTerminal({ cols: source.cols, rows: source.rows, scrollback: 1000 }) + writeTerminal(replay, serializer.serialize()) + return snapshotState(replay) +} + +describe('SerializeAddon round-trip edge cases', () => { + it('keeps a soft wrap after a clipped wide glyph on its own row (conpty seed 1149)', () => { + const source = createFuzzTerminal({ cols: 12, rows: 3, scrollback: 1000, conpty: true }) + writeTerminal(source, 'abcdefghiไธญWRAPPED') + source.resize(10, 3) + const expected = snapshotState(source) + // The glyph's trailing half is past the grid, so the serializer blanks its last column. + expected.grid[0] = expected.grid[0].replace('ไธญ', ' ') + + expect(roundTrip(source)).toEqual(expected) + }) + + it.each([ + ['normal', ''], + ['alternate', '\x1b[?1049h'] + ])( + 'keeps trailing background-only rows on the %s buffer (seeds 4681/1674)', + (_buffer, prefix) => { + const source = createFuzzTerminal({ cols: 4, rows: 3, scrollback: 1000 }) + writeTerminal(source, `${prefix}r1\r\n\x1b[48;5;157m\x1b[J\x1b[0m\x1b[3;1H`) + + expect(roundTrip(source)).toEqual(snapshotState(source)) + } + ) +}) diff --git a/src/main/daemon/serialize-grid-cell-descriptors.ts b/src/main/daemon/serialize-grid-cell-descriptors.ts new file mode 100644 index 00000000000..391990de741 --- /dev/null +++ b/src/main/daemon/serialize-grid-cell-descriptors.ts @@ -0,0 +1,99 @@ +// Per-cell grid descriptors for the serialize round-trip oracle +// (serialize-grid-roundtrip.ts): visually effective state only, so a replay +// is compared on what a user would see, not on internal attribute encoding. +import type { Terminal } from '@xterm/headless' + +export type GridDiff = { stage: string; row?: number; expected: unknown; actual: unknown } + +type BufferLine = NonNullable> +type Buffer = Terminal['buffer']['active'] + +const COLOR_MODE_P16 = 16777216 +const COLOR_MODE_P256 = 33554432 +const DEFAULT_BLANK = 'โ–ฏยทw1ยทb0:-1ยท000' +export const CLIPPED = 'CLIPPED' + +// SerializeAddon re-emits palette 0-15 set via 38;5;N as SGR 30-37/90-97; same theme slot. +function canonicalColorMode(mode: number, colorValue: number): number { + return mode === COLOR_MODE_P256 && colorValue >= 0 && colorValue < 16 ? COLOR_MODE_P16 : mode +} + +function flags(values: boolean[]): string { + return values.map((flag) => (flag ? '1' : '0')).join('') +} + +/** Visually effective cell state, same blank-cell policy as terminal-restore-parity-fixture. */ +export function cellDescriptor(line: BufferLine | undefined, x: number, cols: number): string { + if (!line || x >= line.length) { + return DEFAULT_BLANK + } + const cell = line.getCell(x) + if (!cell) { + return DEFAULT_BLANK + } + if (x === cols - 1 && line.length > cols && cell.getWidth() > 1) { + return CLIPPED + } + const chars = cell.getChars() + const fgMode = canonicalColorMode(cell.getFgColorMode(), cell.getFgColor()) + const bgMode = canonicalColorMode(cell.getBgColorMode(), cell.getBgColor()) + if (chars === '' || chars === ' ') { + const blank = chars === ' ' + const inverseFg = cell.isInverse() ? `ยทif${fgMode}:${cell.getFgColor()}` : '' + return `โ–ฏยทw${cell.getWidth()}ยทb${bgMode}:${cell.getBgColor()}ยท${flags([ + blank && cell.isUnderline() !== 0, + blank && cell.isStrikethrough() !== 0, + blank && cell.isOverline() !== 0 + ])}${inverseFg}` + } + const cellFlags = flags([ + cell.isBold() !== 0, + cell.isDim() !== 0, + cell.isItalic() !== 0, + cell.isUnderline() !== 0, + cell.isInverse() !== 0, + cell.isInvisible() !== 0, + cell.isStrikethrough() !== 0 + ]) + return `${chars}ยทw${cell.getWidth()}ยทf${fgMode}:${cell.getFgColor()}ยทb${bgMode}:${cell.getBgColor()}ยท${cellFlags}` +} + +function rowCells(line: BufferLine | undefined, cols: number): string[] { + return Array.from({ length: cols }, (_, x) => cellDescriptor(line, x, cols)) +} + +// A wide glyph whose trailing half lies past the grid cannot be replayed; any blank is faithful. +function cellsMatch(expected: string, actual: string): boolean { + return expected === actual || (expected === CLIPPED && actual.startsWith('โ–ฏ')) +} + +function rowsMatch(expected: string[], actual: string[]): boolean { + return expected.length === actual.length && expected.every((e, i) => cellsMatch(e, actual[i]!)) +} + +export function bufferRows(buffer: Buffer, start: number, end: number, cols: number): string[][] { + const rows: string[][] = [] + for (let y = start; y < end; y++) { + rows.push(rowCells(buffer.getLine(y), cols)) + } + while (rows.length > 0 && rows.at(-1)!.every((c) => c === DEFAULT_BLANK)) { + rows.pop() + } + return rows +} + +export function compareRowSets( + stage: string, + expected: string[][], + actual: string[][] +): GridDiff | null { + const length = Math.max(expected.length, actual.length) + for (let y = 0; y < length; y++) { + const e = expected[y] + const a = actual[y] + if (!e || !a || !rowsMatch(e, a)) { + return { stage, row: y, expected: e?.join('|'), actual: a?.join('|') } + } + } + return null +} diff --git a/src/main/daemon/serialize-grid-fuzz-stream.ts b/src/main/daemon/serialize-grid-fuzz-stream.ts new file mode 100644 index 00000000000..ad65e2ad3a7 --- /dev/null +++ b/src/main/daemon/serialize-grid-fuzz-stream.ts @@ -0,0 +1,289 @@ +// Seeded VT stream generator for the serialize round-trip differential fuzz +// (serialize-grid.differential.fuzz.test.ts). Unlike agent-tui-ansi-fuzz-stream +// it deliberately covers everything SerializeAddon must carry, including the +// ops that leave xterm lines longer than the grid: column shrinks in the +// alternate buffer and in a non-reflowing (pre-21376 ConPTY) normal buffer. +import { mulberry32 } from '../../shared/agent-tui-ansi-fuzz-stream' + +export type SerializeFuzzCategory = 'normal' | 'alt' | 'conpty' + +export type SerializeFuzzStep = + | { kind: 'write'; data: string } + | { kind: 'resize'; cols: number; rows: number } + | { kind: 'check'; scrollback: number | undefined } + +export type SerializeFuzzCase = { + seed: number + category: SerializeFuzzCategory + cols: number + rows: number + sourceScrollback: number + steps: SerializeFuzzStep[] +} + +type Rng = () => number + +function int(rng: Rng, min: number, max: number): number { + return min + Math.floor(rng() * (max - min + 1)) +} + +function pick(rng: Rng, values: readonly T[]): T { + return values[Math.floor(rng() * values.length)]! +} + +const WIDE = ['ไธญ', 'ๆ–‡ๅญ—', 'ํ•œ๊ธ€', 'ๆ—ฅๆœฌ่ชž', '๐Ÿ˜€', '๐ŸŸข', '๐Ÿ‘๐Ÿฝ', '๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘ง', '๐Ÿ‡ฐ๐Ÿ‡ท', 'โœ…'] as const +const COMBINING = ['eฬ', 'aฬˆฬฃ', 'nฬƒ', 'ฬ', 'oฬถ'] as const +const ASCII = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789 .,:;!?-_/|#' + +function asciiRun(rng: Rng, maxLen: number): string { + let out = '' + for (let i = int(rng, 1, maxLen); i > 0; i--) { + out += ASCII[int(rng, 0, ASCII.length - 1)] + } + return out +} + +function textRun(rng: Rng, cols: number): string { + const parts: string[] = [] + for (let i = int(rng, 1, 4); i > 0; i--) { + const roll = rng() + parts.push( + roll < 0.55 + ? asciiRun(rng, Math.max(2, cols)) + : roll < 0.85 + ? pick(rng, WIDE).repeat(int(rng, 1, 4)) + : pick(rng, COMBINING) + ) + } + return parts.join('') +} + +function color(rng: Rng, base: 30 | 40): string { + const roll = rng() + if (roll < 0.35) { + return String(base + int(rng, 0, 7) + (rng() < 0.4 ? 60 : 0)) + } + if (roll < 0.65) { + return `${base + 8};5;${int(rng, 0, 255)}` + } + if (roll < 0.9) { + return `${base + 8};2;${int(rng, 0, 255)};${int(rng, 0, 255)};${int(rng, 0, 255)}` + } + return String(base + 9) +} + +const SGR_FLAGS = [ + '0', + '1', + '2', + '3', + '4', + '4:2', + '4:3', + '4:5', + '5', + '7', + '8', + '9', + '21', + '22', + '23', + '24', + '25', + '27', + '28', + '29', + '53', + '55' +] as const + +function sgr(rng: Rng): string { + const parts: string[] = [] + for (let i = int(rng, 1, 3); i > 0; i--) { + const roll = rng() + parts.push( + roll < 0.45 + ? pick(rng, SGR_FLAGS) + : roll < 0.75 + ? color(rng, 30) + : roll < 0.95 + ? color(rng, 40) + : `58;5;${int(rng, 0, 255)}` + ) + } + return `\x1b[${parts.join(';')}m` +} + +function cursorOp(rng: Rng, cols: number, rows: number): string { + // Coordinates sometimes exceed the grid on purpose: xterm clamps them. + const r = int(rng, 1, rows + 2) + const c = int(rng, 1, cols + 3) + return pick(rng, [ + `\x1b[${r};${c}H`, + `\x1b[${r};${c}f`, + `\x1b[${int(rng, 1, 5)}A`, + `\x1b[${int(rng, 1, 5)}B`, + `\x1b[${int(rng, 1, 8)}C`, + `\x1b[${int(rng, 1, 8)}D`, + `\x1b[${c}G`, + `\x1b[${r}d`, + '\r', + '\b', + '\t', + '\x1b[2I', + '\x1b[Z' + ]) +} + +function editOp(rng: Rng): string { + const n = int(rng, 1, 6) + return pick(rng, [ + '\x1b[J', + '\x1b[1J', + '\x1b[2J', + '\x1b[3J', + '\x1b[K', + '\x1b[1K', + '\x1b[2K', + `\x1b[${n}X`, + `\x1b[${n}@`, + `\x1b[${n}P`, + `\x1b[${n}L`, + `\x1b[${n}M`, + `\x1b[${n}S`, + `\x1b[${n}T`, + '\x1bM', + '\x1bD', + '\x1bE' + ]) +} + +function scrollRegionOp(rng: Rng, rows: number): string { + if (rng() < 0.35) { + return '\x1b[r' + } + const top = int(rng, 1, Math.max(1, rows - 1)) + return `\x1b[${top};${int(rng, top + 1, rows + 1)}r` +} + +const MODE_TOGGLES = [ + '\x1b[?7l', + '\x1b[?7h', + '\x1b[4h', + '\x1b[4l', + '\x1b[?6h', + '\x1b[?6l', + '\x1b[?1h', + '\x1b[?1l', + '\x1b[?2004h', + '\x1b[?2004l', + '\x1b[?25l', + '\x1b[?25h', + '\x1b[?1000h', + '\x1b[?1003h', + '\x1b[?1000l', + '\x1b[?45h', + '\x1b[?45l', + '\x1b=', + '\x1b>', + '\x1b[?1004h' +] as const + +const SCREEN_TOGGLES = [ + '\x1b[?1049h', + '\x1b[?1049l', + '\x1b[?47h', + '\x1b[?47l', + '\x1b[?1047h', + '\x1b[?1047l', + '\x1b7', + '\x1b8', + '\x1b[s', + '\x1b[u' +] as const + +type Dims = { cols: number; rows: number } + +function resizeStep(rng: Rng, dims: Dims): SerializeFuzzStep { + const roll = rng() + // Shrink-heavy: a column shrink is what leaves lines wider than the grid. + const cols = + roll < 0.55 + ? int(rng, Math.max(2, dims.cols - 30), Math.max(2, dims.cols - 1)) + : roll < 0.9 + ? int(rng, dims.cols + 1, Math.min(140, dims.cols + 30)) + : dims.cols + const rows = rng() < 0.4 ? int(rng, 2, 16) : dims.rows + dims.cols = cols + dims.rows = rows + return { kind: 'resize', cols, rows } +} + +function checkStep(rng: Rng): SerializeFuzzStep { + return { kind: 'check', scrollback: pick(rng, [undefined, 0, int(rng, 1, 30), 5000]) } +} + +function nextStep(rng: Rng, dims: Dims, category: SerializeFuzzCategory): SerializeFuzzStep { + const roll = rng() + const write = (data: string): SerializeFuzzStep => ({ kind: 'write', data }) + if (roll < 0.3) { + return write(textRun(rng, dims.cols)) + } + if (roll < 0.42) { + return write(sgr(rng)) + } + if (roll < 0.54) { + return write(cursorOp(rng, dims.cols, dims.rows)) + } + if (roll < 0.64) { + return write(editOp(rng)) + } + if (roll < 0.71) { + return write(pick(rng, ['\r\n', '\n', '\r\n\r\n', '\x1b[0m\r\n'])) + } + if (roll < 0.75) { + return write(scrollRegionOp(rng, dims.rows)) + } + if (roll < 0.8) { + return write(pick(rng, MODE_TOGGLES)) + } + if (roll < (category === 'normal' ? 0.83 : 0.82)) { + return write(pick(rng, SCREEN_TOGGLES)) + } + if (roll < 0.95) { + return resizeStep(rng, dims) + } + return checkStep(rng) +} + +const START_DIMS: readonly Dims[] = [ + { cols: 10, rows: 4 }, + { cols: 20, rows: 6 }, + { cols: 40, rows: 8 }, + { cols: 80, rows: 12 } +] + +export function buildSerializeFuzzCase( + seed: number, + category: SerializeFuzzCategory +): SerializeFuzzCase { + const rng = mulberry32(seed) + const start = pick(rng, START_DIMS) + const dims = { ...start } + const steps: SerializeFuzzStep[] = [] + if (category === 'alt') { + steps.push({ kind: 'write', data: pick(rng, ['\x1b[?1049h', '\x1b[?47h', '\x1b[?1047h']) }) + } + for (let i = int(rng, 8, 60); i > 0; i--) { + steps.push(nextStep(rng, dims, category)) + } + steps.push(checkStep(rng)) + return { + seed, + category, + cols: start.cols, + rows: start.rows, + sourceScrollback: pick(rng, [0, 10, 200]), + steps + } +} diff --git a/src/main/daemon/serialize-grid-roundtrip.ts b/src/main/daemon/serialize-grid-roundtrip.ts new file mode 100644 index 00000000000..d22bee6e511 --- /dev/null +++ b/src/main/daemon/serialize-grid-roundtrip.ts @@ -0,0 +1,328 @@ +// Round-trip oracle for serialize-grid.differential.fuzz.test.ts: drives one +// source terminal through a fuzz case, serializes it with every supplied +// SerializeAddon build at each checkpoint, replays each output into a fresh +// terminal of the source's size and reports the first cell/cursor/mode diff. +import { Terminal } from '@xterm/headless' +import { createRequire } from 'node:module' +import { SerializeAddon } from '@xterm/addon-serialize' +import { Unicode11Addon } from '@xterm/addon-unicode11' +import { activateOrcaTerminalUnicodeProvider } from '../../shared/terminal-unicode-provider' +import { + readSavedCursorRegister, + serializeWithAbsoluteCursor +} from '../../shared/terminal-serialize-absolute-cursor' +import type { SerializeFuzzCase } from './serialize-grid-fuzz-stream' +import { + serializedNormalStart, + variantOverlong, + variantTrailingBackgroundRows +} from './serialize-grid-variant-scope' +import type { GridDiff } from './serialize-grid-cell-descriptors' +import { + bufferRows, + cellDescriptor, + CLIPPED, + compareRowSets +} from './serialize-grid-cell-descriptors' + +export type NamedSerializer = { name: string; create: () => SerializeAddon } + +/** Loads a patched build's lib/addon-serialize.js (see config/scripts/build-serialize-addon-at-ref.mjs). */ +function loadSerializerBuild(name: string, path: string): NamedSerializer { + const loaded: { SerializeAddon: typeof SerializeAddon } = createRequire(import.meta.url)(path) + return { name, create: () => new loaded.SerializeAddon() } +} + +export function loadOldSerializer(path: string): NamedSerializer { + return loadSerializerBuild('old', path) +} + +// ORCA_NEW_SERIALIZE_ADDON compares two arbitrary refs without reinstalling node_modules. +export const NEW_SERIALIZER: NamedSerializer = process.env.ORCA_NEW_SERIALIZE_ADDON + ? loadSerializerBuild('new', process.env.ORCA_NEW_SERIALIZE_ADDON) + : { name: 'new', create: () => new SerializeAddon() } + +export type { GridDiff } from './serialize-grid-cell-descriptors' + +export type SerializeCheckResult = { + stepIndex: number + /** Per serialize variant: some line in the serialized range is wider than the grid. */ + overlong: boolean[] + /** Per serialize variant: a blank background-colored row follows the last row with text. */ + trailingBackgroundRows: boolean[] + /** outputs[serializerName][variant] */ + outputs: Record + /** First I2 diff per serializer (cells, cursor, buffer, modes); null = faithful. */ + gridDiff: Record + /** isWrapped diffs are reported apart: they never change what is painted. */ + wrapDiff: Record + clippedWideCells: number +} + +const REPLAY_SCROLLBACK = 20_000 + +export function createFuzzTerminal(opts: { + cols: number + rows: number + scrollback: number + conpty?: boolean +}): Terminal { + const terminal = new Terminal({ + cols: opts.cols, + rows: opts.rows, + scrollback: opts.scrollback, + allowProposedApi: true, + logLevel: 'off', + vtExtensions: { kittyKeyboard: true }, + ...(opts.conpty ? { windowsPty: { backend: 'conpty', buildNumber: 19041 } } : {}) + }) + terminal.loadAddon(new Unicode11Addon()) + activateOrcaTerminalUnicodeProvider(terminal) + return terminal +} + +/** Thrown when xterm itself crashes on a fuzz stream; unrelated to serialization. */ +export class XtermWriteCrash extends Error {} + +/** The private xterm core members the oracle needs: sync writes and the active DECSTBM region. */ +type XtermCoreInternals = { + writeSync: (data: string) => void + region: { top: number; bottom: number } +} + +function readRegion(buffer: unknown): { top: number; bottom: number } { + if (typeof buffer !== 'object' || buffer === null) { + return { top: -1, bottom: -1 } + } + const top = 'scrollTop' in buffer && typeof buffer.scrollTop === 'number' ? buffer.scrollTop : -1 + const bottom = + 'scrollBottom' in buffer && typeof buffer.scrollBottom === 'number' ? buffer.scrollBottom : -1 + return { top, bottom } +} + +function readXtermCore(terminal: Terminal): XtermCoreInternals { + const core: unknown = '_core' in terminal ? terminal._core : undefined + if (typeof core !== 'object' || core === null || !('writeSync' in core)) { + throw new Error('headless xterm core without writeSync') + } + const { writeSync } = core + if (typeof writeSync !== 'function') { + throw new Error('headless xterm core without writeSync') + } + return { + writeSync: (data) => writeSync.call(core, data), + region: readRegion('buffer' in core ? core.buffer : undefined) + } +} + +// Why sync: an xterm parser exception inside async write() never resolves its callback and hangs the sweep. +export function writeTerminal(terminal: Terminal, data: string): void { + // Headless Terminal's core exposes writeSync(data); the public API only has async write(). + const { writeSync } = readXtermCore(terminal) + try { + writeSync(data) + } catch (error) { + throw new XtermWriteCrash(String(error)) + } +} + +function coreRegion(terminal: Terminal): { top: number; bottom: number } { + // xterm keeps DECSTBM on the private _core.buffer. + return readXtermCore(terminal).region +} + +function modeState(terminal: Terminal): string { + const { synchronizedOutputMode: _sync, ...modes } = terminal.modes + return JSON.stringify({ ...modes, region: coreRegion(terminal) }) +} + +async function compareReplay( + source: Terminal, + output: string, + scrollback: number | undefined +): Promise<{ grid: GridDiff | null; wrap: GridDiff | null }> { + const { cols, rows } = source + const replay = createFuzzTerminal({ cols, rows, scrollback: REPLAY_SCROLLBACK }) + try { + try { + writeTerminal(replay, output) + } catch (error) { + return { grid: { stage: 'replay-crash', expected: null, actual: String(error) }, wrap: null } + } + const src = source.buffer.active + const dst = replay.buffer.active + const normalStart = serializedNormalStart(source, scrollback) + const grid = + (src.type === dst.type + ? null + : { stage: 'active-buffer', expected: src.type, actual: dst.type }) ?? + compareRowSets( + 'visible-grid', + bufferRows(src, src.baseY, src.baseY + rows, cols), + bufferRows(dst, dst.baseY, dst.baseY + rows, cols) + ) ?? + compareRowSets( + 'normal-buffer', + bufferRows(source.buffer.normal, normalStart, source.buffer.normal.length, cols), + bufferRows(replay.buffer.normal, 0, replay.buffer.normal.length, cols) + ) ?? + (src.cursorX === dst.cursorX && src.cursorY === dst.cursorY + ? null + : { + stage: 'cursor', + expected: [src.cursorX, src.cursorY], + actual: [dst.cursorX, dst.cursorY] + }) ?? + (modeState(source) === modeState(replay) + ? null + : { stage: 'modes', expected: modeState(source), actual: modeState(replay) }) + const srcWraps = Array.from({ length: rows }, (_, y) => + Boolean(src.getLine(src.baseY + y)?.isWrapped) + ) + const dstWraps = Array.from({ length: rows }, (_, y) => + Boolean(dst.getLine(dst.baseY + y)?.isWrapped) + ) + const wrap = + JSON.stringify(srcWraps) === JSON.stringify(dstWraps) + ? null + : { stage: 'visible-wraps', expected: srcWraps, actual: dstWraps } + return { grid, wrap } + } finally { + replay.dispose() + } +} + +function countClippedWideCells(terminal: Terminal): number { + const buffer = terminal.buffer.active + let count = 0 + for (let y = 0; y < buffer.length; y++) { + if (cellDescriptor(buffer.getLine(y), terminal.cols - 1, terminal.cols) === CLIPPED) { + count++ + } + } + return count +} + +/** Variant 0 is the production snapshot path; the others pin byte identity of the raw API. */ +function serializeVariants( + addon: SerializeAddon, + source: Terminal, + scrollback: number | undefined, + rangeRow: number +): string[] { + return [ + serializeWithAbsoluteCursor(addon, source, { scrollback }, readSavedCursorRegister(source)), + addon.serialize(), + addon.serialize({ + range: { start: rangeRow, end: Math.min(rangeRow + 2, source.buffer.normal.length - 1) }, + excludeAltBuffer: true, + excludeModes: true + }) + ] +} + +export type SerializeCaseRun = { + checks: SerializeCheckResult[] + /** xterm threw while the SOURCE parsed the stream; later checkpoints are skipped. */ + sourceCrash: string | null +} + +export async function runSerializeFuzzCase( + testCase: SerializeFuzzCase, + serializers: readonly NamedSerializer[] +): Promise { + const source = createFuzzTerminal({ + cols: testCase.cols, + rows: testCase.rows, + scrollback: testCase.sourceScrollback, + conpty: testCase.category === 'conpty' + }) + const addons = serializers.map((s) => ({ name: s.name, addon: s.create() })) + for (const { addon } of addons) { + source.loadAddon(addon) + } + const results: SerializeCheckResult[] = [] + try { + for (const [stepIndex, step] of testCase.steps.entries()) { + if (step.kind !== 'check') { + try { + if (step.kind === 'write') { + writeTerminal(source, step.data) + } else { + source.resize(step.cols, step.rows) + } + } catch (error) { + return { checks: results, sourceCrash: String(error) } + } + continue + } + const rangeRow = Math.floor(source.buffer.normal.length / 2) + const result: SerializeCheckResult = { + stepIndex, + overlong: variantOverlong(source, step.scrollback, rangeRow), + trailingBackgroundRows: variantTrailingBackgroundRows(source, step.scrollback, rangeRow), + outputs: {}, + gridDiff: {}, + wrapDiff: {}, + clippedWideCells: countClippedWideCells(source) + } + for (const { name, addon } of addons) { + let outputs: string[] + try { + outputs = serializeVariants(addon, source, step.scrollback, rangeRow) + } catch (error) { + result.outputs[name] = [`throw:${String(error)}`] + result.gridDiff[name] = { + stage: 'serialize-throws', + expected: null, + actual: String(error) + } + result.wrapDiff[name] = null + continue + } + const { grid, wrap } = await compareReplay(source, outputs[0]!, step.scrollback) + result.outputs[name] = outputs + result.gridDiff[name] = grid + result.wrapDiff[name] = wrap + } + results.push(result) + } + } finally { + source.dispose() + } + return { checks: results, sourceCrash: null } +} + +export type Verdict = 'i1-bytes-differ' | 'regression' | 'fixed' | 'both-fail' | 'new-fail' + +/** I1 byte identity, then I2/I3 classification; single-serializer runs only report new-fail. */ +export function i1Applies(check: SerializeCheckResult): boolean[] { + return check.overlong.map((overlong, v) => !overlong && !check.trailingBackgroundRows[v]) +} + +/** Per variant: I1 applies, yet the bytes changed. */ +export function i1BytesDifferByVariant(check: SerializeCheckResult): boolean[] { + return i1Applies(check).map( + (applies, v) => applies && check.outputs.old![v] !== check.outputs.new![v] + ) +} + +export function verdicts(check: SerializeCheckResult, differential: boolean): Verdict[] { + const out: Verdict[] = [] + const newFail = check.gridDiff.new !== null + if (!differential) { + return newFail ? ['new-fail'] : [] + } + const oldFail = check.gridDiff.old !== null + if (i1BytesDifferByVariant(check).some(Boolean)) { + out.push('i1-bytes-differ') + } + if (newFail && !oldFail) { + out.push('regression') + } else if (!newFail && oldFail) { + out.push('fixed') + } else if (newFail && oldFail) { + out.push('both-fail') + } + return out +} diff --git a/src/main/daemon/serialize-grid-transcript-replay.test.ts b/src/main/daemon/serialize-grid-transcript-replay.test.ts new file mode 100644 index 00000000000..7bd60cf0205 --- /dev/null +++ b/src/main/daemon/serialize-grid-transcript-replay.test.ts @@ -0,0 +1,161 @@ +import { existsSync, readdirSync, readFileSync } from 'node:fs' +import { basename, join } from 'node:path' +import { describe, expect, it } from 'vitest' +import { mulberry32 } from '../../shared/agent-tui-ansi-fuzz-stream' +import type { SerializeFuzzCase, SerializeFuzzStep } from './serialize-grid-fuzz-stream' +import { + loadOldSerializer, + NEW_SERIALIZER, + runSerializeFuzzCase, + verdicts, + type Verdict +} from './serialize-grid-roundtrip' + +// Replays captured agent/TUI PTY transcripts through the serialize round trip +// under resize schedules the app never saw (a pane resized while hidden), and +// serializes at random chunk boundaries. With ORCA_OLD_SERIALIZE_ADDON set it +// also checks I1/I3 against the previous build; see serialize-grid.differential.fuzz.test.ts. +// SERIALIZE_TRANSCRIPT_DIR= also replay local, uncommitted captures (.txt + .meta.json) +// SERIALIZE_TRANSCRIPT_SEEDS=20 seeds per transcript ร— schedule (default 2) + +const FIXTURE_DIRS = [ + join(__dirname, '../runtime/__fixtures__'), + join(__dirname, '__fixtures__/pty-transcripts') +] +const EXTRA_DIR = process.env.SERIALIZE_TRANSCRIPT_DIR +const OLD_ADDON_PATH = process.env.ORCA_OLD_SERIALIZE_ADDON +const SEEDS = Math.max(1, Number(process.env.SERIALIZE_TRANSCRIPT_SEEDS) || 2) + +// Checkpoints (default seeds) whose new replay diverges exactly as the previous +// build's did โ€” pre-existing upstream limitations, not regressions (verified +// with ORCA_OLD_SERIALIZE_ADDON). Shrink when one is fixed. +const KNOWN_PREEXISTING_I2_FAILURES: Record = { less: 6, nano: 2, opencode: 5 } + +type Transcript = { name: string; data: string; cols: number; rows: number } +type Schedule = 'none' | 'shrink' | 'shrink-grow' | 'jitter' +const SCHEDULES: readonly Schedule[] = ['none', 'shrink', 'shrink-grow', 'jitter'] + +function readTranscripts(dir: string): Transcript[] { + return readdirSync(dir) + .filter((file) => file.endsWith('.txt')) + .map((file) => { + const metaPath = join(dir, file.replace(/\.txt$/, '.meta.json')) + const meta: { cols?: number; rows?: number } = existsSync(metaPath) + ? JSON.parse(readFileSync(metaPath, 'utf8')) + : {} + return { + name: basename(file, '.txt'), + data: readFileSync(join(dir, file), 'utf8'), + cols: meta.cols ?? 120, + rows: meta.rows ?? 40 + } + }) +} + +// Never splits a surrogate pair: PTY bytes reach JS as whole code points. +function chunk(data: string, rng: () => number, count: number): string[] { + const chunks: string[] = [] + let start = 0 + while (start < data.length) { + let end = Math.min(data.length, start + 1 + Math.floor(rng() * ((2 * data.length) / count))) + const code = data.charCodeAt(end - 1) + end += end < data.length && code >= 0xd800 && code <= 0xdbff ? 1 : 0 + chunks.push(data.slice(start, end)) + start = end + } + return chunks +} + +function buildReplayCase( + transcript: Transcript, + schedule: Schedule, + conpty: boolean, + seed: number +): SerializeFuzzCase { + const rng = mulberry32(seed) + const chunks = chunk(transcript.data, rng, 24) + const { cols, rows } = transcript + const narrow = Math.max(8, Math.floor(cols * (0.4 + rng() * 0.4))) + const steps: SerializeFuzzStep[] = [] + chunks.forEach((data, i) => { + const at = i / chunks.length + const next = (i + 1) / chunks.length + if (schedule === 'shrink' && at <= 0.5 && next > 0.5) { + steps.push({ kind: 'resize', cols: narrow, rows }) + } + if (schedule === 'shrink-grow' && at <= 0.3 && next > 0.3) { + steps.push({ kind: 'resize', cols: narrow, rows: Math.max(4, rows - 6) }) + } + if (schedule === 'shrink-grow' && at <= 0.7 && next > 0.7) { + steps.push({ kind: 'resize', cols, rows }) + } + if (schedule === 'jitter' && rng() < 0.25) { + steps.push({ kind: 'resize', cols: Math.max(8, cols + Math.floor(rng() * 21) - 14), rows }) + } + steps.push({ kind: 'write', data }) + if (rng() < 0.15) { + steps.push({ kind: 'check', scrollback: rng() < 0.5 ? 5000 : 0 }) + } + }) + steps.push({ kind: 'check', scrollback: 5000 }) + return { + seed, + category: conpty ? 'conpty' : 'normal', + cols, + rows, + sourceScrollback: 1000, + steps + } +} + +describe('serialize round trip over captured PTY transcripts', () => { + const transcripts = [ + ...FIXTURE_DIRS.flatMap(readTranscripts), + ...(EXTRA_DIR ? readTranscripts(EXTRA_DIR) : []) + ] + const serializers = OLD_ADDON_PATH + ? [loadOldSerializer(OLD_ADDON_PATH), NEW_SERIALIZER] + : [NEW_SERIALIZER] + + it.each(transcripts.map((t) => [t.name, t] as const))( + '%s: no I1 byte diff and no I3 regression under resize schedules', + async (_name, transcript) => { + const counts: Partial> = {} + const blocking: string[] = [] + for (const schedule of SCHEDULES) { + for (const conpty of [false, true]) { + for (let seed = 1; seed <= SEEDS; seed++) { + const testCase = buildReplayCase(transcript, schedule, conpty, seed) + const run = await runSerializeFuzzCase(testCase, serializers) + expect(run.sourceCrash).toBeNull() + for (const check of run.checks) { + counts.checks = (counts.checks ?? 0) + 1 + if (process.env.SERIALIZE_FUZZ_REPORT === '1' && check.gridDiff.new) { + const d = check.gridDiff.new + console.log( + ` ${transcript.name} ${schedule} conpty=${conpty} seed=${seed}: ${d.stage} row=${d.row} ${JSON.stringify(d.expected)?.slice(0, 160)} -> ${JSON.stringify(d.actual)?.slice(0, 160)}` + ) + } + for (const verdict of verdicts(check, serializers.length > 1)) { + counts[verdict] = (counts[verdict] ?? 0) + 1 + if (verdict === 'i1-bytes-differ' || verdict === 'regression') { + blocking.push( + `${verdict} schedule=${schedule} conpty=${conpty} seed=${seed} step=${check.stepIndex} new=${JSON.stringify(check.gridDiff.new)?.slice(0, 400)}` + ) + } + } + } + } + } + } + if (process.env.SERIALIZE_FUZZ_REPORT === '1') { + console.log(`${transcript.name} ${JSON.stringify(counts)}`) + } + expect(blocking).toEqual([]) + if (!OLD_ADDON_PATH && SEEDS === 2) { + expect(counts['new-fail'] ?? 0).toBe(KNOWN_PREEXISTING_I2_FAILURES[transcript.name] ?? 0) + } + }, + 600_000 + ) +}) diff --git a/src/main/daemon/serialize-grid-variant-scope.ts b/src/main/daemon/serialize-grid-variant-scope.ts new file mode 100644 index 00000000000..63b78af1bec --- /dev/null +++ b/src/main/daemon/serialize-grid-variant-scope.ts @@ -0,0 +1,99 @@ +// Which serialized ranges each serialize variant covers, and what they hold, for the +// I1 scope in serialize-grid-roundtrip.ts: a range with an overlong line or a trailing +// background-only row is where the Orca patch changes bytes on purpose. +import type { Terminal } from '@xterm/headless' + +type Buffer = Terminal['buffer']['active'] + +export function serializedNormalStart(terminal: Terminal, scrollback: number | undefined): number { + const length = terminal.buffer.normal.length + return scrollback === undefined ? 0 : length - Math.min(length, scrollback + terminal.rows) +} + +function hasOverlongLine(buffer: Buffer, start: number, end: number, cols: number): boolean { + for (let y = start; y < end; y++) { + if ((buffer.getLine(y)?.length ?? 0) > cols) { + return true + } + } + return false +} + +export function variantOverlong( + source: Terminal, + scrollback: number | undefined, + rangeRow: number +): boolean[] { + const { cols } = source + const normal = source.buffer.normal + const alt = source.buffer.active.type === 'alternate' + const altOverlong = + alt && hasOverlongLine(source.buffer.alternate, 0, source.buffer.alternate.length, cols) + return [ + altOverlong || + hasOverlongLine(normal, serializedNormalStart(source, scrollback), normal.length, cols), + altOverlong || hasOverlongLine(normal, 0, normal.length, cols), + hasOverlongLine(normal, rangeRow, Math.min(rangeRow + 2, normal.length - 1) + 1, cols) + ] +} + +// The patch keeps such rows only when the serializer trims (no scrollback in the range) +// and the cursor is not wrap-pending; anywhere else its bytes must match the old build. +function hasTrailingBackgroundRow( + buffer: Buffer, + start: number, + end: number, + { cols, rows }: { cols: number; rows: number } +): boolean { + if (buffer.length - start > rows || buffer.cursorX >= cols) { + return false + } + // Text as the serializer counts it: width-0 cells (e.g. an orphan combining mark) never are. + let lastTextRow = start - 1 + for (let y = start; y < end; y++) { + const line = buffer.getLine(y) + for (let x = 0; x < cols; x++) { + const cell = line?.getCell(x) + if (cell && cell.getWidth() > 0 && cell.getChars() !== '') { + lastTextRow = y + break + } + } + } + for (let y = lastTextRow + 1; y < end; y++) { + const line = buffer.getLine(y) + for (let x = 0; x < cols; x++) { + if (line?.getCell(x)?.isBgDefault() === false) { + return true + } + } + } + return false +} + +export function variantTrailingBackgroundRows( + source: Terminal, + scrollback: number | undefined, + rangeRow: number +): boolean[] { + const normal = source.buffer.normal + const altTrailing = + source.buffer.active.type === 'alternate' && + hasTrailingBackgroundRow(source.buffer.alternate, 0, source.buffer.alternate.length, source) + return [ + altTrailing || + hasTrailingBackgroundRow( + normal, + serializedNormalStart(source, scrollback), + normal.length, + source + ), + altTrailing || hasTrailingBackgroundRow(normal, 0, normal.length, source), + hasTrailingBackgroundRow( + normal, + rangeRow, + Math.min(rangeRow + 2, normal.length - 1) + 1, + source + ) + ] +} diff --git a/src/main/daemon/serialize-grid.differential.fuzz.test.ts b/src/main/daemon/serialize-grid.differential.fuzz.test.ts new file mode 100644 index 00000000000..c5d0dfdac0b --- /dev/null +++ b/src/main/daemon/serialize-grid.differential.fuzz.test.ts @@ -0,0 +1,289 @@ +import { appendFileSync } from 'node:fs' +import { describe, expect, it } from 'vitest' +import { + buildSerializeFuzzCase, + type SerializeFuzzCase, + type SerializeFuzzCategory +} from './serialize-grid-fuzz-stream' +import { + i1Applies, + i1BytesDifferByVariant, + loadOldSerializer, + NEW_SERIALIZER, + runSerializeFuzzCase, + verdicts, + type NamedSerializer, + type SerializeCheckResult, + type Verdict +} from './serialize-grid-roundtrip' + +// Serializeโ†’replay round-trip fuzz for the addon-serialize patch. Invariants: +// I1 no line in the serialized range is wider than the grid, and no blank background-colored +// row follows its last text row (the old build trimmed those) โ‡’ new bytes === old bytes +// I2 replaying the new bytes reproduces the source grid, cursor, buffer and modes +// I3 every checkpoint the old build replayed faithfully, the new one does too +// I1/I3 need a baseline build: ORCA_OLD_SERIALIZE_ADDON=$(node +// config/scripts/build-serialize-addon-at-ref.mjs --ref origin/main --out-dir ). +// ORCA_NEW_SERIALIZE_ADDON likewise replaces the installed build under test. +// +// SERIALIZE_FUZZ_ITERATIONS=7000 cases per category (default 40) +// SERIALIZE_FUZZ_SEED=1234 re-run exactly one seed (all categories) +// SERIALIZE_FUZZ_CATEGORY=alt run one of normal | alt | conpty +// SERIALIZE_FUZZ_REPORT=1 print tallies and minimized failures + +const ALL_CATEGORIES: readonly SerializeFuzzCategory[] = ['normal', 'alt', 'conpty'] +const CATEGORIES = ALL_CATEGORIES.filter( + (category) => + !process.env.SERIALIZE_FUZZ_CATEGORY || process.env.SERIALIZE_FUZZ_CATEGORY === category +) +const FIXED_SEED = readPositiveIntEnv('SERIALIZE_FUZZ_SEED') +const ITERATIONS = FIXED_SEED !== null ? 1 : (readPositiveIntEnv('SERIALIZE_FUZZ_ITERATIONS') ?? 40) +const OLD_ADDON_PATH = process.env.ORCA_OLD_SERIALIZE_ADDON +const REPORT = process.env.SERIALIZE_FUZZ_REPORT === '1' + +function readPositiveIntEnv(name: string): number | null { + const raw = Number(process.env[name]) + return Number.isFinite(raw) && raw > 0 ? Math.floor(raw) : null +} + +async function caseVerdicts( + testCase: SerializeFuzzCase, + serializers: readonly NamedSerializer[] +): Promise> { + const { checks } = await runSerializeFuzzCase(testCase, serializers) + return new Set(checks.flatMap((check) => verdicts(check, serializers.length > 1))) +} + +/** Greedy step-drop minimizer that keeps the given verdict reproducing. */ +async function minimize( + testCase: SerializeFuzzCase, + verdict: Verdict, + serializers: readonly NamedSerializer[] +): Promise { + let current = testCase + let shrunk = true + while (shrunk) { + shrunk = false + for (let i = current.steps.length - 2; i >= 0; i--) { + const candidate = { ...current, steps: current.steps.toSpliced(i, 1) } + if ((await caseVerdicts(candidate, serializers)).has(verdict)) { + current = candidate + shrunk = true + } + } + } + return current +} + +type Tally = { + cases: number + xtermCrash: number + checks: number + overlongChecks: number + clippedWideChecks: number + i1Applicable: number + i1Fail: number + newI2Fail: number + oldI2Fail: number + regression: number + fixed: number + bothFail: number + wrapDiffNew: number + wrapRegression: number + stages: Record +} + +function emptyTally(): Tally { + return { + cases: 0, + xtermCrash: 0, + checks: 0, + overlongChecks: 0, + clippedWideChecks: 0, + i1Applicable: 0, + i1Fail: 0, + newI2Fail: 0, + oldI2Fail: 0, + regression: 0, + fixed: 0, + bothFail: 0, + wrapDiffNew: 0, + wrapRegression: 0, + stages: {} + } +} + +function addToTally(tally: Tally, check: SerializeCheckResult, differential: boolean): void { + tally.checks++ + tally.overlongChecks += check.overlong[0] ? 1 : 0 + tally.clippedWideChecks += check.clippedWideCells > 0 ? 1 : 0 + tally.newI2Fail += check.gridDiff.new ? 1 : 0 + tally.wrapDiffNew += check.wrapDiff.new ? 1 : 0 + for (const [name, diff] of Object.entries(check.gridDiff)) { + if (diff) { + const key = `${name}:${diff.stage}` + tally.stages[key] = (tally.stages[key] ?? 0) + 1 + } + } + if (!differential) { + return + } + tally.oldI2Fail += check.gridDiff.old ? 1 : 0 + const oldFaithful = !check.gridDiff.old && !check.wrapDiff.old + tally.wrapRegression += oldFaithful && check.wrapDiff.new ? 1 : 0 + const differs = i1BytesDifferByVariant(check) + i1Applies(check).forEach((applies, v) => { + if (applies) { + tally.i1Applicable++ + tally.i1Fail += differs[v] ? 1 : 0 + } + }) + const v = verdicts(check, true) + tally.regression += v.includes('regression') ? 1 : 0 + tally.fixed += v.includes('fixed') ? 1 : 0 + tally.bothFail += v.includes('both-fail') ? 1 : 0 +} + +type Failure = { seed: number; category: SerializeFuzzCategory; verdict: Verdict } + +const DUMP_PATH = process.env.SERIALIZE_FUZZ_DUMP + +async function runSweep(serializers: readonly NamedSerializer[]): Promise<{ + tallies: Record + failures: Failure[] +}> { + const differential = serializers.length > 1 + const tallies = { normal: emptyTally(), alt: emptyTally(), conpty: emptyTally() } + const failures: Failure[] = [] + for (const category of CATEGORIES) { + for (let i = 0; i < ITERATIONS; i++) { + const seed = FIXED_SEED ?? 1 + i + const run = await runSerializeFuzzCase(buildSerializeFuzzCase(seed, category), serializers) + const checks = run.checks + tallies[category].cases++ + tallies[category].xtermCrash += run.sourceCrash ? 1 : 0 + const seen = new Set() + for (const check of checks) { + if (DUMP_PATH) { + appendFileSync( + DUMP_PATH, + `${JSON.stringify({ seed, category, stepIndex: check.stepIndex, overlong: check.overlong, clipped: check.clippedWideCells, verdicts: verdicts(check, differential), grid: check.gridDiff, wrap: check.wrapDiff })}\n` + ) + } + addToTally(tallies[category], check, differential) + for (const verdict of verdicts(check, differential)) { + if (verdict !== 'fixed' && !seen.has(verdict)) { + seen.add(verdict) + failures.push({ seed, category, verdict }) + } + } + } + } + } + return { tallies, failures } +} + +async function describeFailures( + failures: Failure[], + serializers: readonly NamedSerializer[] +): Promise { + const lines: string[] = [] + for (const failure of failures.slice(0, 12)) { + const minimized = await minimize( + buildSerializeFuzzCase(failure.seed, failure.category), + failure.verdict, + serializers + ) + const { checks } = await runSerializeFuzzCase(minimized, serializers) + const failing = checks.find((c) => + verdicts(c, serializers.length > 1).includes(failure.verdict) + ) + lines.push( + `${failure.verdict} seed=${failure.seed} category=${failure.category} (SERIALIZE_FUZZ_SEED=${failure.seed})`, + ` start ${minimized.cols}x${minimized.rows} scrollback=${minimized.sourceScrollback} steps=${JSON.stringify(minimized.steps)}`, + ` new: ${JSON.stringify(failing?.gridDiff.new)}`, + ` old: ${JSON.stringify(failing?.gridDiff.old)}` + ) + } + return lines.join('\n') +} + +// Seeds 1-25 whose NEW replay already diverges and whose OLD replay diverges +// the same way (verified with ORCA_OLD_SERIALIZE_ADDON): upstream limitations +// such as orphan combining marks in column 0 and wide glyphs reflowed into the +// last column. Shrink this list when one is fixed. +const CI_SEEDS = 25 +const KNOWN_PREEXISTING_I2_FAILURES: Record = { + normal: [4, 5, 8, 9, 14, 19, 25], + alt: [1, 2, 3, 4, 6, 7, 8, 11, 12, 14, 17, 19, 20, 21, 22, 23], + conpty: [4, 8, 9, 11, 19] +} + +// I3 regressions found at 7000 seeds per mode against origin/main (#22586), kept as guards +// now that both are fixed: 1149 = clipped-wide blank had width 0; the rest = trailing +// background-only rows were trimmed. +const FOUND_I3_REGRESSIONS: Record = { + normal: [4681], + alt: [1674], + conpty: [130, 1149, 2590, 3827, 4012, 4841, 6461] +} + +describe('serialize grid round-trip fuzz', () => { + it.skipIf(!OLD_ADDON_PATH)('previously found I3 regression seeds do not regress', async () => { + const serializers = [loadOldSerializer(OLD_ADDON_PATH!), NEW_SERIALIZER] + const regressed: string[] = [] + for (const category of ALL_CATEGORIES) { + for (const seed of FOUND_I3_REGRESSIONS[category]) { + if ( + (await caseVerdicts(buildSerializeFuzzCase(seed, category), serializers)).has( + 'regression' + ) + ) { + regressed.push(`${category}:${seed}`) + } + } + } + expect(regressed).toEqual([]) + }) + + // The pin describes the installed build; an ORCA_NEW_SERIALIZE_ADDON override is judged by I3 instead. + it.skipIf(Boolean(process.env.ORCA_NEW_SERIALIZE_ADDON))( + 'I2 on a fixed seed range: only the pinned pre-existing divergences remain', + async () => { + const failing: Record = { normal: [], alt: [], conpty: [] } + for (const category of ALL_CATEGORIES) { + for (let seed = 1; seed <= CI_SEEDS; seed++) { + const run = await runSerializeFuzzCase(buildSerializeFuzzCase(seed, category), [ + NEW_SERIALIZER + ]) + if (run.checks.some((check) => check.gridDiff.new !== null)) { + failing[category].push(seed) + } + } + } + expect(failing).toEqual(KNOWN_PREEXISTING_I2_FAILURES) + }, + 120_000 + ) + + it.skipIf(!OLD_ADDON_PATH)( + 'I1/I3 against the previous serialize build: identical bytes when nothing is wider than the grid, and no checkpoint gets worse', + async () => { + const serializers = [loadOldSerializer(OLD_ADDON_PATH!), NEW_SERIALIZER] + const { tallies, failures } = await runSweep(serializers) + const blocking = failures.filter( + (f) => f.verdict === 'i1-bytes-differ' || f.verdict === 'regression' + ) + if (REPORT) { + console.log(JSON.stringify(tallies, null, 1)) + const preexisting = failures.filter((f) => f.verdict === 'both-fail') + console.log(`blocking:\n${await describeFailures(blocking, serializers)}`) + console.log( + `pre-existing (${preexisting.length}):\n${await describeFailures(preexisting, serializers)}` + ) + } + expect(blocking.length ? await describeFailures(blocking, serializers) : '').toBe('') + }, + 3_600_000 + ) +}) diff --git a/src/renderer/src/components/native-chat/serialized-screen-background-rows.test.ts b/src/renderer/src/components/native-chat/serialized-screen-background-rows.test.ts new file mode 100644 index 00000000000..20b0c7e163d --- /dev/null +++ b/src/renderer/src/components/native-chat/serialized-screen-background-rows.test.ts @@ -0,0 +1,53 @@ +/** + * The serializer keeps trailing background-only rows (a TUI that paints its + * whole screen, e.g. OpenCode), so screens read as text end in `\r\n\x1b[NX` + * rows. Every text reader of `serialize({ scrollback: 0 })` must read the same + * thing with and without them. + */ +import { describe, expect, it } from 'vitest' +import { Terminal } from '@xterm/headless' +import { SerializeAddon } from '@xterm/addon-serialize' +import { readClaudeSessionOptionsFromTerminalScreen } from './claude-terminal-session-options' +import { agentInputLineCleared } from './native-chat-launch-draft-send' +import { buildBoundedSessionTranscript } from '@/lib/agent-session-fork-context' + +const CLAUDE_FRAME = [ + 'โ•ญโ”€ Claude Code โ”€โ”€โ”€โ•ฎ', + 'โ”‚Haiku 4.5โ”‚', + 'โ”‚API Usage Billingโ”‚', + 'โ”‚C:\\work\\repoโ”‚', + 'โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ', + 'โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€', + 'โฏ ', + 'โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€' +].join('\r\n') + +async function serializedScreen(paintBackgroundBelow: boolean): Promise { + const terminal = new Terminal({ cols: 40, rows: 14, allowProposedApi: true }) + const serializer = new SerializeAddon() + terminal.loadAddon(serializer) + const below = paintBackgroundBelow ? '\x1b[s\x1b[9;1H\x1b[48;5;236m\x1b[J\x1b[0m\x1b[u' : '' + await new Promise((resolve) => + terminal.write(`\x1b[?1049h\x1b[H${CLAUDE_FRAME}\x1b[7;3H${below}`, resolve) + ) + const screen = serializer.serialize({ scrollback: 0 }) + terminal.dispose() + return screen +} + +describe('text readers of a serialized screen with trailing background rows', () => { + it('read the same model, prompt state and transcript as without them', async () => { + const plain = await serializedScreen(false) + const painted = await serializedScreen(true) + // Precondition: the painted screen really carries the kept background rows. + expect(painted).toContain(`\r\n\x1b[48;5;236m\x1b[40X${'\r\n\x1b[40X'.repeat(5)}`) + + expect(readClaudeSessionOptionsFromTerminalScreen(painted)).toEqual({ model: 'haiku' }) + expect(readClaudeSessionOptionsFromTerminalScreen(painted)).toEqual( + readClaudeSessionOptionsFromTerminalScreen(plain) + ) + expect(agentInputLineCleared(painted)).toBe(true) + expect(agentInputLineCleared(painted)).toBe(agentInputLineCleared(plain)) + expect(buildBoundedSessionTranscript(painted)).toBe(buildBoundedSessionTranscript(plain)) + }) +})