@alchemy.run/sigil 0.0.0-alpha.2 → 0.0.0-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (107) hide show
  1. package/README.md +2 -4
  2. package/THIRD_PARTY_NOTICES.md +31 -22
  3. package/dist/ansi.d.ts +17 -14
  4. package/dist/ansi.js +7 -2
  5. package/dist/{devtools-BhYGjb7h.js → devtools-DbthxoD1.js} +22 -23
  6. package/dist/index.d.ts +125 -288
  7. package/dist/index.js +2460 -2864
  8. package/dist/{truncate-CBiyyZzw.js → truncate-Cr6xVFMa.js} +447 -273
  9. package/package.json +3 -9
  10. package/src/ansi/chalk.ts +8 -51
  11. package/src/ansi/cursor.ts +2 -4
  12. package/src/ansi/east-asian-width.ts +44 -0
  13. package/src/ansi/escapes.ts +4 -26
  14. package/src/ansi/index.ts +12 -14
  15. package/src/ansi/sgr.ts +2 -5
  16. package/src/ansi/slice.ts +1 -1
  17. package/src/ansi/string-width.ts +91 -206
  18. package/src/ansi/strip.ts +13 -33
  19. package/src/ansi/supports-color.ts +8 -14
  20. package/src/ansi/tokenize.ts +94 -166
  21. package/src/ansi/truncate.ts +5 -3
  22. package/src/ansi/wrap.ts +13 -14
  23. package/src/ansi-tokenizer.ts +1 -1
  24. package/src/colorize.ts +1 -1
  25. package/src/components/App.tsx +14 -14
  26. package/src/components/BackgroundContext.ts +2 -2
  27. package/src/components/Box.tsx +51 -59
  28. package/src/components/CursorContext.ts +1 -1
  29. package/src/components/ErrorBoundary.tsx +2 -1
  30. package/src/components/ErrorOverview.tsx +9 -7
  31. package/src/components/Newline.tsx +1 -0
  32. package/src/components/Spacer.tsx +2 -1
  33. package/src/components/Static.tsx +2 -1
  34. package/src/components/StderrContext.ts +0 -2
  35. package/src/components/StdinContext.ts +0 -1
  36. package/src/components/StdoutContext.ts +1 -3
  37. package/src/components/Text.tsx +7 -6
  38. package/src/components/Transform.tsx +2 -1
  39. package/src/cursor-position.ts +1 -1
  40. package/src/devtools.ts +84 -24
  41. package/src/dom.ts +7 -7
  42. package/src/env.ts +12 -0
  43. package/src/get-max-width.ts +1 -1
  44. package/src/global.d.ts +3 -4
  45. package/src/{boxes.ts → glyphs.ts} +17 -18
  46. package/src/hooks/use-animation.ts +1 -1
  47. package/src/hooks/use-app.ts +1 -1
  48. package/src/hooks/use-box-metrics.ts +1 -1
  49. package/src/hooks/use-cursor.ts +2 -2
  50. package/src/hooks/use-focus-manager.ts +1 -1
  51. package/src/hooks/use-focus.ts +5 -6
  52. package/src/hooks/use-input.ts +4 -4
  53. package/src/hooks/use-is-screen-reader-enabled.ts +1 -1
  54. package/src/hooks/use-paste.ts +2 -2
  55. package/src/hooks/use-stderr.ts +1 -1
  56. package/src/hooks/use-stdin.ts +1 -1
  57. package/src/hooks/use-stdout.ts +1 -1
  58. package/src/hooks/use-window-size.ts +2 -2
  59. package/src/index.ts +44 -44
  60. package/src/ink.tsx +536 -720
  61. package/src/input-parser.ts +1 -1
  62. package/src/instances.ts +1 -1
  63. package/src/kitty-keyboard.ts +128 -0
  64. package/src/log-update.ts +4 -4
  65. package/src/measure-element.ts +1 -1
  66. package/src/measure-text.ts +2 -2
  67. package/src/output.ts +4 -4
  68. package/src/parse-keypress.ts +4 -5
  69. package/src/parse-stack-line.ts +0 -1
  70. package/src/patch-console.ts +44 -0
  71. package/src/reconciler.ts +13 -60
  72. package/src/render-background.ts +3 -3
  73. package/src/render-border.ts +6 -6
  74. package/src/render-node-to-output.ts +13 -11
  75. package/src/render-to-string.ts +4 -4
  76. package/src/render.ts +9 -10
  77. package/src/renderer.ts +3 -3
  78. package/src/sanitize-ansi.ts +1 -1
  79. package/src/signal-exit.ts +4 -5
  80. package/src/squash-text-nodes.ts +2 -2
  81. package/src/stream.ts +2 -4
  82. package/src/styles.ts +6 -6
  83. package/src/terminal-size.ts +9 -8
  84. package/src/types.ts +1 -6
  85. package/src/utils.ts +2 -2
  86. package/src/wrap-text.ts +4 -4
  87. package/src/yoga/config.ts +2 -2
  88. package/src/yoga/core/absoluteLayout.ts +15 -15
  89. package/src/yoga/core/baseline.ts +3 -3
  90. package/src/yoga/core/cache.ts +4 -4
  91. package/src/yoga/core/calculateLayout.ts +33 -27
  92. package/src/yoga/core/config.ts +1 -1
  93. package/src/yoga/core/flexLine.ts +3 -3
  94. package/src/yoga/core/helpers.ts +3 -3
  95. package/src/yoga/core/layoutResults.ts +4 -4
  96. package/src/yoga/core/node.ts +16 -16
  97. package/src/yoga/core/pixelGrid.ts +4 -4
  98. package/src/yoga/core/style.ts +11 -11
  99. package/src/yoga/core/types.ts +2 -2
  100. package/src/yoga/index.ts +6 -6
  101. package/src/yoga/node.ts +8 -8
  102. package/src/ansi/widest-line.ts +0 -12
  103. package/src/auto-bind.ts +0 -41
  104. package/src/devtools-window-polyfill.ts +0 -73
  105. package/src/indent-string.ts +0 -16
  106. package/src/is-in-ci.ts +0 -7
  107. package/src/write-synchronized.ts +0 -9
@@ -1,6 +1,4 @@
1
- import process from "node:process";
2
- import os from "node:os";
3
- import tty from "node:tty";
1
+ import { isatty } from "node:tty";
4
2
  //#region src/ansi/escapes.ts
5
3
  const ESC = "\x1B";
6
4
  const BEL = "\x07";
@@ -32,15 +30,7 @@ const eraseLines = (count) => {
32
30
  if (count) clear += cursorLeft;
33
31
  return clear;
34
32
  };
35
- const isOldWindows = () => {
36
- if (process.platform !== "win32") return false;
37
- const parts = os.release().split(".");
38
- const major = Number(parts[0]);
39
- const build = Number(parts[2] ?? 0);
40
- if (major < 10) return true;
41
- return major === 10 && build < 10586;
42
- };
43
- const clearTerminal = isOldWindows() ? `${eraseScreen}${CSI$1}0f` : `${eraseScreen}${CSI$1}3J${CSI$1}H`;
33
+ const clearTerminal = `${eraseScreen}${CSI$1}3J${CSI$1}H`;
44
34
  const enterAlternativeScreen = CSI$1 + "?1049h";
45
35
  const exitAlternativeScreen = CSI$1 + "?1049l";
46
36
  const cursorShow = CSI$1 + "?25h";
@@ -206,7 +196,7 @@ const hexToRgb = (hex) => {
206
196
  0
207
197
  ];
208
198
  let [colorString] = matches;
209
- if (colorString.length === 3) colorString = colorString.split("").map((character) => character + character).join("");
199
+ if (colorString.length === 3) colorString = colorString.replaceAll(/./g, "$&$&");
210
200
  const integer = Number.parseInt(colorString, 16);
211
201
  return [
212
202
  integer >> 16 & 255,
@@ -962,119 +952,96 @@ function eastAsianWidth(codePoint, { ambiguousAsWide = false } = {}) {
962
952
  if (isFullWidth(codePoint) || isWide(codePoint) || ambiguousAsWide && isAmbiguous(codePoint)) return 2;
963
953
  return 1;
964
954
  }
955
+ /**
956
+ Grapheme-cluster width test shared by the tokenizer (slice/clip path): the
957
+ base code point's East Asian Width, plus emoji presentation rules.
958
+ */
959
+ function isFullwidthGrapheme(grapheme, baseCodePoint) {
960
+ if (isFullwidthCodePoint(baseCodePoint)) return true;
961
+ if (grapheme.includes("️")) return true;
962
+ if (baseCodePoint >= 127462 && baseCodePoint <= 127487) return true;
963
+ return false;
964
+ }
965
+ /**
966
+ Wide code points not covered by string-width's CJKT script regex or emoji
967
+ regex — the fallback bucket of its block parser. A disjoint decomposition of
968
+ the `wide` table above, kept alongside it so the width data lives in one
969
+ module.
970
+ */
971
+ const isWideNotCJKTNotEmoji = (x) => {
972
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
973
+ };
965
974
  function isFullwidthCodePoint(codePoint) {
966
975
  if (!Number.isInteger(codePoint)) return false;
967
976
  return isFullWidth(codePoint) || isWide(codePoint);
968
977
  }
969
978
  //#endregion
970
- //#region src/ansi/strip.ts
971
- function ansiRegex({ onlyFirst = false } = {}) {
972
- return new RegExp(`(?:\\][^œ]*(?:|\\\\|œ))|[›][[\\]()#;?]*(?:\\d{1,4}(?:[;:]\\d{0,4})*)?[\\dA-PR-TZcf-nq-uy=><~]`, onlyFirst ? void 0 : "g");
973
- }
974
- const regex = ansiRegex();
975
- function stripAnsi(string) {
976
- if (!string.includes("\x1B") && !string.includes("›")) return string;
977
- return string.replace(regex, "");
978
- }
979
- //#endregion
980
979
  //#region src/ansi/string-width.ts
981
- const segmenter$2 = new Intl.Segmenter();
982
- const zeroWidthClusterRegex = /^(?:\p{Default_Ignorable_Code_Point}|\p{Control}|\p{Format}|\p{Nonspacing_Mark}|\p{Enclosing_Mark}|\p{Surrogate})+$/v;
983
- const leadingNonPrintingRegex = /^[\p{Default_Ignorable_Code_Point}\p{Control}\p{Format}\p{Nonspacing_Mark}\p{Enclosing_Mark}\p{Surrogate}]+/v;
984
- const spacingMarkRegex = /\p{Spacing_Mark}/v;
985
- const rgiEmojiRegex = /^\p{RGI_Emoji}$/v;
986
- const unqualifiedKeycapRegex = /^[\d#*]\u20E3$/;
987
- const extendedPictographicRegex = /\p{Extended_Pictographic}/gu;
988
- function isDoubleWidthNonRgiEmojiSequence(segment) {
989
- if (segment.length > 50) return false;
990
- if (unqualifiedKeycapRegex.test(segment)) return true;
991
- if (segment.includes("‍")) {
992
- const pictographics = segment.match(extendedPictographicRegex);
993
- return pictographics !== null && pictographics.length >= 2;
994
- }
995
- return false;
996
- }
997
- function baseVisible(segment) {
998
- return segment.replace(leadingNonPrintingRegex, "");
999
- }
1000
- function isZeroWidthCluster(segment) {
1001
- return zeroWidthClusterRegex.test(segment);
1002
- }
1003
- function isHangulLeadingJamo(codePoint) {
1004
- return codePoint !== void 0 && (codePoint >= 4352 && codePoint <= 4447 || codePoint >= 43360 && codePoint <= 43388);
1005
- }
1006
- function isHangulVowelJamo(codePoint) {
1007
- return codePoint !== void 0 && (codePoint >= 4448 && codePoint <= 4519 || codePoint >= 55216 && codePoint <= 55238);
1008
- }
1009
- function isHangulTrailingJamo(codePoint) {
1010
- return codePoint !== void 0 && (codePoint >= 4520 && codePoint <= 4607 || codePoint >= 55243 && codePoint <= 55291);
1011
- }
1012
- function isHangulJamo(codePoint) {
1013
- return isHangulLeadingJamo(codePoint) || isHangulVowelJamo(codePoint) || isHangulTrailingJamo(codePoint);
1014
- }
1015
- function hangulClusterWidth(visibleSegment, eastAsianWidthOptions) {
1016
- const codePoints = [];
1017
- for (const character of visibleSegment) {
1018
- if (zeroWidthClusterRegex.test(character)) continue;
1019
- codePoints.push(character.codePointAt(0));
1020
- }
1021
- if (codePoints.length === 0) return;
1022
- let width = 0;
1023
- for (let index = 0; index < codePoints.length; index++) {
1024
- const codePoint = codePoints[index];
1025
- if (!isHangulJamo(codePoint)) {
1026
- if (width === 0) return;
1027
- for (let remaining = index; remaining < codePoints.length; remaining++) width += eastAsianWidth(codePoints[remaining], eastAsianWidthOptions);
1028
- return width;
1029
- }
1030
- if (isHangulLeadingJamo(codePoint) && isHangulVowelJamo(codePoints[index + 1])) {
1031
- width += 2;
1032
- index += isHangulTrailingJamo(codePoints[index + 2]) ? 2 : 1;
1033
- continue;
1034
- }
1035
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1036
- }
1037
- return width;
1038
- }
1039
- function trailingWidth(visibleSegment, eastAsianWidthOptions) {
1040
- let extra = 0;
1041
- let first = true;
1042
- for (const character of visibleSegment) {
1043
- if (first) {
1044
- first = false;
1045
- continue;
1046
- }
1047
- if (spacingMarkRegex.test(character) || character >= "＀" && character <= "￯") extra += eastAsianWidth(character.codePointAt(0), eastAsianWidthOptions);
1048
- }
1049
- return extra;
1050
- }
1051
- function stringWidth(input, options = {}) {
1052
- if (typeof input !== "string" || input.length === 0) return 0;
1053
- const { ambiguousIsNarrow = true, countAnsiEscapeCodes = false } = options;
1054
- let string = input;
1055
- if (!countAnsiEscapeCodes && (string.includes("\x1B") || string.includes("›"))) string = stripAnsi(string);
1056
- if (string.length === 0) return 0;
1057
- if (/^[ -~]*$/.test(string)) return string.length;
980
+ const getCodePointsLength = (input) => {
981
+ let length = 0;
982
+ for (const _ of input) length += 1;
983
+ return length;
984
+ };
985
+ const ANSI_RE = /[\u001b\u009b][[()#;?]*[0-9;:]*[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
986
+ const CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
987
+ const CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/uy;
988
+ const TAB_RE = /\t{1,1000}/y;
989
+ const EMOJI_RE = /[\u{1F1E6}-\u{1F1FF}]{2}|\u{1F3F4}[\u{E0061}-\u{E007A}]{2}[\u{E0030}-\u{E0039}\u{E0061}-\u{E007A}]{1,3}\u{E007F}|(?:\p{Emoji}\uFE0F\u20E3?|\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation})(?:\u200D(?:\p{Emoji_Modifier_Base}\p{Emoji_Modifier}?|\p{Emoji_Presentation}|\p{Emoji}\uFE0F\u20E3?))*/uy;
990
+ const LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
991
+ const MODIFIER_RE = /\p{M}+/gu;
992
+ const ANSI_WIDTH = 0;
993
+ const CONTROL_WIDTH = 0;
994
+ const TAB_WIDTH = 8;
995
+ const EMOJI_WIDTH = 2;
996
+ const FULL_WIDTH_WIDTH = 2;
997
+ const REGULAR_WIDTH = 1;
998
+ const WIDE_WIDTH = 2;
999
+ const PARSE_BLOCKS = [
1000
+ [LATIN_RE, REGULAR_WIDTH],
1001
+ [ANSI_RE, ANSI_WIDTH],
1002
+ [CONTROL_RE, CONTROL_WIDTH],
1003
+ [TAB_RE, TAB_WIDTH],
1004
+ [EMOJI_RE, EMOJI_WIDTH],
1005
+ [CJKT_WIDE_RE, WIDE_WIDTH]
1006
+ ];
1007
+ const stringWidth = (input) => {
1008
+ let indexPrev = 0;
1009
+ let index = 0;
1010
+ const length = input.length;
1011
+ let unmatchedStart = 0;
1012
+ let unmatchedEnd = 0;
1058
1013
  let width = 0;
1059
- const eastAsianWidthOptions = { ambiguousAsWide: !ambiguousIsNarrow };
1060
- for (const { segment } of segmenter$2.segment(string)) {
1061
- if (isZeroWidthCluster(segment)) continue;
1062
- if (rgiEmojiRegex.test(segment) || isDoubleWidthNonRgiEmojiSequence(segment)) {
1063
- width += 2;
1064
- continue;
1014
+ outer: while (true) {
1015
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
1016
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
1017
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
1018
+ const codePoint = char.codePointAt(0) || 0;
1019
+ width += isFullWidth(codePoint) ? FULL_WIDTH_WIDTH : isWideNotCJKTNotEmoji(codePoint) ? WIDE_WIDTH : REGULAR_WIDTH;
1020
+ }
1021
+ unmatchedStart = unmatchedEnd = 0;
1065
1022
  }
1066
- const visibleSegment = baseVisible(segment);
1067
- const hangulWidth = hangulClusterWidth(visibleSegment, eastAsianWidthOptions);
1068
- if (hangulWidth !== void 0) {
1069
- width += hangulWidth;
1070
- continue;
1023
+ if (index >= length) break;
1024
+ for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
1025
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
1026
+ BLOCK_RE.lastIndex = index;
1027
+ if (BLOCK_RE.test(input)) {
1028
+ const lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
1029
+ width += lengthExtra * BLOCK_WIDTH;
1030
+ unmatchedStart = indexPrev;
1031
+ unmatchedEnd = index;
1032
+ index = indexPrev = BLOCK_RE.lastIndex;
1033
+ continue outer;
1034
+ }
1071
1035
  }
1072
- const codePoint = visibleSegment.codePointAt(0);
1073
- width += eastAsianWidth(codePoint, eastAsianWidthOptions);
1074
- width += trailingWidth(visibleSegment, eastAsianWidthOptions);
1036
+ index += 1;
1075
1037
  }
1076
1038
  return width;
1077
- }
1039
+ };
1040
+ const widestLine = (text) => {
1041
+ let lineWidth = 0;
1042
+ for (const line of text.split("\n")) lineWidth = Math.max(lineWidth, stringWidth(line));
1043
+ return lineWidth;
1044
+ };
1078
1045
  //#endregion
1079
1046
  //#region src/ansi/wrap.ts
1080
1047
  const ANSI_ESCAPE = "\x1B";
@@ -1092,8 +1059,8 @@ const ANSI_SGR_UNDERLINE_COLOR_EXTENDED = 58;
1092
1059
  const ANSI_SGR_COLOR_MODE_RGB = 2;
1093
1060
  const ANSI_SGR_COLOR_MODE_256 = 5;
1094
1061
  const ANSI_ESCAPE_LINK = `${ANSI_OSC}8;`;
1095
- const ESCAPES$1 = /* @__PURE__ */ new Set([ANSI_ESCAPE, "›"]);
1096
- const ESCAPE_CHARACTERS = [...ESCAPES$1].join("");
1062
+ const ESCAPES = /* @__PURE__ */ new Set([ANSI_ESCAPE, "›"]);
1063
+ const ESCAPE_CHARACTERS = [...ESCAPES].join("");
1097
1064
  const CSI_INTRODUCER = `(?:${ANSI_ESCAPE}\\${ANSI_CSI}|›)`;
1098
1065
  const CSI_PARAMETERS = "[0-?]*[ -/]*[@-~]";
1099
1066
  const SGR_PARAMETERS = `(?<sgr>[0-9;:]*)${ANSI_SGR_TERMINATOR}`;
@@ -1105,7 +1072,7 @@ const ANSI_ESCAPE_REGEX = new RegExp(`${CSI_INTRODUCER}(?:${SGR_PARAMETERS}|${CS
1105
1072
  const ANSI_SGR_MODIFIER_CLOSE_CODES = new Set(codes.values());
1106
1073
  ANSI_SGR_MODIFIER_CLOSE_CODES.delete(ANSI_SGR_RESET);
1107
1074
  const segmenter$1 = new Intl.Segmenter();
1108
- const getStringWidth = (string) => stringWidth(string, { countAnsiEscapeCodes: true });
1075
+ const getStringWidth = (string) => stringWidth(string);
1109
1076
  const TAB_SIZE = 8;
1110
1077
  const ESCAPE_INTRODUCER_REGEX = new RegExp(`[${ESCAPE_CHARACTERS}]`, "g");
1111
1078
  const ROW_BOUNDARY_REGEX = new RegExp(`[\\n${ESCAPE_CHARACTERS}]`, "g");
@@ -1113,7 +1080,7 @@ const ASCII_PRINTABLE_REGEX = /^[ -~]*$/;
1113
1080
  const wrapAnsiCode = (code) => `${ANSI_ESCAPE}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
1114
1081
  const wrapAnsiHyperlink = (url, parameters = "") => `${ANSI_ESCAPE}${ANSI_ESCAPE_LINK}${parameters};${url}${ANSI_ESCAPE_BELL}`;
1115
1082
  const matchAnsiEscape = (string, index) => {
1116
- if (!ESCAPES$1.has(string[index])) return;
1083
+ if (!ESCAPES.has(string[index])) return;
1117
1084
  ANSI_ESCAPE_REGEX.lastIndex = index;
1118
1085
  return ANSI_ESCAPE_REGEX.exec(string) ?? void 0;
1119
1086
  };
@@ -1190,15 +1157,16 @@ const splitWords = (string) => {
1190
1157
  for (const word of words) word.width = getStringWidth(word.plainText);
1191
1158
  return words;
1192
1159
  };
1160
+ const EXTENDED_COLOR_CODES = /* @__PURE__ */ new Set([
1161
+ ANSI_SGR_FOREGROUND_EXTENDED,
1162
+ ANSI_SGR_BACKGROUND_EXTENDED,
1163
+ ANSI_SGR_UNDERLINE_COLOR_EXTENDED
1164
+ ]);
1193
1165
  const getColonColorToken = (parameter) => {
1194
1166
  const parts = parameter.split(":");
1195
1167
  const code = Number.parseInt(parts[0], 10);
1196
1168
  const mode = Number.parseInt(parts[1], 10);
1197
- if (![
1198
- ANSI_SGR_FOREGROUND_EXTENDED,
1199
- ANSI_SGR_BACKGROUND_EXTENDED,
1200
- ANSI_SGR_UNDERLINE_COLOR_EXTENDED
1201
- ].includes(code)) return;
1169
+ if (!EXTENDED_COLOR_CODES.has(code)) return;
1202
1170
  if (mode === ANSI_SGR_COLOR_MODE_256 && parts.length === 3 && /^\d+$/.test(parts[2])) return {
1203
1171
  code,
1204
1172
  open: parameter,
@@ -1355,7 +1323,7 @@ const applyLeadingSgrResets = (string, startIndex, activeStyles) => {
1355
1323
  index += match[0].length;
1356
1324
  }
1357
1325
  };
1358
- const getClosingSgrSequence = (activeStyles) => [...activeStyles].reverse().map((activeStyle) => wrapAnsiCode(activeStyle.close)).join("");
1326
+ const getClosingSgrSequence = (activeStyles) => activeStyles.toReversed().map((activeStyle) => wrapAnsiCode(activeStyle.close)).join("");
1359
1327
  const getOpeningSgrSequence = (activeStyles) => activeStyles.map((activeStyle) => wrapAnsiCode(activeStyle.open)).join("");
1360
1328
  const wrapWord = (rows, word, columns, rowWidth) => {
1361
1329
  const tokens = getTokens(word);
@@ -1531,8 +1499,16 @@ function wrapAnsi(string, columns, options) {
1531
1499
  return string.normalize().replaceAll("\r\n", "\n").split("\n").map((line) => exec(expandTabs(line), columns, options)).join("\n");
1532
1500
  }
1533
1501
  //#endregion
1502
+ //#region src/env.ts
1503
+ const isInCi = Boolean(process.env.CI);
1504
+ const isSigilDev = process.env.SIGIL_DEV === "true";
1505
+ const isScreenReader = process.env.SIGIL_SCREEN_READER === "true";
1506
+ const isWindows = process.platform === "win32";
1507
+ const isMacos = process.platform === "darwin";
1508
+ const isTty = (stream) => "isTTY" in stream && stream.isTTY === true;
1509
+ //#endregion
1534
1510
  //#region src/signal-exit.ts
1535
- const signals = process.platform === "win32" ? [
1511
+ const signals = isWindows ? [
1536
1512
  "SIGHUP",
1537
1513
  "SIGINT",
1538
1514
  "SIGTERM",
@@ -1655,11 +1631,7 @@ function supportsColorLevel(haveStream, { streamIsTTY, sniffFlags = true } = {})
1655
1631
  if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
1656
1632
  const min = forceColor ?? 0;
1657
1633
  if (env["TERM"] === "dumb") return min;
1658
- if (process.platform === "win32") {
1659
- const osRelease = os.release().split(".");
1660
- if (Number(osRelease[0]) >= 10 && Number(osRelease[2]) >= 10586) return Number(osRelease[2]) >= 14931 ? 3 : 2;
1661
- return 1;
1662
- }
1634
+ if (isWindows) return 3;
1663
1635
  if ("CI" in env) {
1664
1636
  if ([
1665
1637
  "GITHUB_ACTIONS",
@@ -1699,8 +1671,8 @@ function createSupportsColor(stream, options = {}) {
1699
1671
  }));
1700
1672
  }
1701
1673
  const supportsColor = {
1702
- stdout: createSupportsColor({ isTTY: tty.isatty(1) }),
1703
- stderr: createSupportsColor({ isTTY: tty.isatty(2) })
1674
+ stdout: createSupportsColor({ isTTY: isatty(1) }),
1675
+ stderr: createSupportsColor({ isTTY: isatty(2) })
1704
1676
  };
1705
1677
  //#endregion
1706
1678
  //#region src/ansi/chalk.ts
@@ -1712,38 +1684,11 @@ const levelMapping = [
1712
1684
  "ansi16m"
1713
1685
  ];
1714
1686
  const state = { level: stdoutColor ? stdoutColor.level : 0 };
1715
- const stringReplaceAll = (string, substring, replacer) => {
1716
- let index = string.indexOf(substring);
1717
- if (index === -1) return string;
1718
- const substringLength = substring.length;
1719
- let endIndex = 0;
1720
- let returnValue = "";
1721
- do {
1722
- returnValue += string.slice(endIndex, index) + substring + replacer;
1723
- endIndex = index + substringLength;
1724
- index = string.indexOf(substring, endIndex);
1725
- } while (index !== -1);
1726
- returnValue += string.slice(endIndex);
1727
- return returnValue;
1728
- };
1729
- const stringEncaseCRLFWithFirstIndex = (string, prefix, postfix, index) => {
1730
- let endIndex = 0;
1731
- let returnValue = "";
1732
- do {
1733
- const gotCR = string[index - 1] === "\r";
1734
- returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
1735
- endIndex = index + 1;
1736
- index = string.indexOf("\n", endIndex);
1737
- } while (index !== -1);
1738
- returnValue += string.slice(endIndex);
1739
- return returnValue;
1740
- };
1741
1687
  const applyStyle = (open, close, text) => {
1742
1688
  if (state.level <= 0 || !text) return text;
1743
1689
  let string = text;
1744
- if (string.includes("\x1B")) string = stringReplaceAll(string, close, open);
1745
- const lfIndex = string.indexOf("\n");
1746
- if (lfIndex !== -1) string = stringEncaseCRLFWithFirstIndex(string, close, open, lfIndex);
1690
+ if (string.includes("\x1B")) string = string.replaceAll(close, close + open);
1691
+ if (string.includes("\n")) string = string.replaceAll(/\r?\n/g, `${close}$&${open}`);
1747
1692
  return open + string + close;
1748
1693
  };
1749
1694
  const styleFunction = (open, close) => {
@@ -1791,30 +1736,307 @@ const chalk = {
1791
1736
  bgAnsi256: (code) => styleFunction(background.ansi256(code), background.close)
1792
1737
  };
1793
1738
  //#endregion
1794
- //#region src/ansi/widest-line.ts
1795
- const widestLine = (string) => {
1796
- let lineWidth = 0;
1797
- for (const line of string.split("\n")) lineWidth = Math.max(lineWidth, stringWidth(line));
1798
- return lineWidth;
1739
+ //#region src/ansi-tokenizer.ts
1740
+ const bellCharacter = "\x07";
1741
+ const escapeCharacter = "\x1B";
1742
+ const stringTerminatorCharacter = "œ";
1743
+ const csiCharacter = "›";
1744
+ const oscCharacter = "";
1745
+ const dcsCharacter = "";
1746
+ const pmCharacter = "ž";
1747
+ const apcCharacter = "Ÿ";
1748
+ const sosCharacter = "˜";
1749
+ const isCsiParameterCharacter = (character) => {
1750
+ const codePoint = character.codePointAt(0);
1751
+ return codePoint !== void 0 && codePoint >= 48 && codePoint <= 63;
1752
+ };
1753
+ const isCsiIntermediateCharacter = (character) => {
1754
+ const codePoint = character.codePointAt(0);
1755
+ return codePoint !== void 0 && codePoint >= 32 && codePoint <= 47;
1756
+ };
1757
+ const isCsiFinalCharacter = (character) => {
1758
+ const codePoint = character.codePointAt(0);
1759
+ return codePoint !== void 0 && codePoint >= 64 && codePoint <= 126;
1760
+ };
1761
+ const isEscapeIntermediateCharacter = (character) => {
1762
+ const codePoint = character.codePointAt(0);
1763
+ return codePoint !== void 0 && codePoint >= 32 && codePoint <= 47;
1764
+ };
1765
+ const isEscapeFinalCharacter = (character) => {
1766
+ const codePoint = character.codePointAt(0);
1767
+ return codePoint !== void 0 && codePoint >= 48 && codePoint <= 126;
1768
+ };
1769
+ const isC1ControlCharacter = (character) => {
1770
+ const codePoint = character.codePointAt(0);
1771
+ return codePoint !== void 0 && codePoint >= 128 && codePoint <= 159;
1772
+ };
1773
+ const readCsiSequence = (text, fromIndex) => {
1774
+ let index = fromIndex;
1775
+ while (index < text.length) {
1776
+ const character = text[index];
1777
+ if (!isCsiParameterCharacter(character)) break;
1778
+ index++;
1779
+ }
1780
+ const parameterString = text.slice(fromIndex, index);
1781
+ const intermediateStartIndex = index;
1782
+ while (index < text.length) {
1783
+ const character = text[index];
1784
+ if (!isCsiIntermediateCharacter(character)) break;
1785
+ index++;
1786
+ }
1787
+ const intermediateString = text.slice(intermediateStartIndex, index);
1788
+ const finalCharacter = text[index];
1789
+ if (finalCharacter === void 0 || !isCsiFinalCharacter(finalCharacter)) return;
1790
+ return {
1791
+ endIndex: index + 1,
1792
+ parameterString,
1793
+ intermediateString,
1794
+ finalCharacter
1795
+ };
1796
+ };
1797
+ const findControlStringTerminatorIndex = (text, fromIndex, allowBellTerminator) => {
1798
+ for (let index = fromIndex; index < text.length; index++) {
1799
+ const character = text[index];
1800
+ if (allowBellTerminator && character === bellCharacter) return index + 1;
1801
+ if (character === stringTerminatorCharacter) return index + 1;
1802
+ if (character === escapeCharacter) {
1803
+ const followingCharacter = text[index + 1];
1804
+ if (followingCharacter === escapeCharacter) {
1805
+ index++;
1806
+ continue;
1807
+ }
1808
+ if (followingCharacter === "\\") return index + 2;
1809
+ }
1810
+ }
1811
+ };
1812
+ const readEscapeSequence = (text, fromIndex) => {
1813
+ let index = fromIndex;
1814
+ while (index < text.length) {
1815
+ const character = text[index];
1816
+ if (!isEscapeIntermediateCharacter(character)) break;
1817
+ index++;
1818
+ }
1819
+ const intermediateString = text.slice(fromIndex, index);
1820
+ const finalCharacter = text[index];
1821
+ if (finalCharacter === void 0 || !isEscapeFinalCharacter(finalCharacter)) return;
1822
+ return {
1823
+ endIndex: index + 1,
1824
+ intermediateString,
1825
+ finalCharacter
1826
+ };
1827
+ };
1828
+ const getControlStringFromEscapeIntroducer = (character) => {
1829
+ switch (character) {
1830
+ case "]": return {
1831
+ type: "osc",
1832
+ allowBellTerminator: true
1833
+ };
1834
+ case "P": return {
1835
+ type: "dcs",
1836
+ allowBellTerminator: false
1837
+ };
1838
+ case "^": return {
1839
+ type: "pm",
1840
+ allowBellTerminator: false
1841
+ };
1842
+ case "_": return {
1843
+ type: "apc",
1844
+ allowBellTerminator: false
1845
+ };
1846
+ case "X": return {
1847
+ type: "sos",
1848
+ allowBellTerminator: false
1849
+ };
1850
+ default: return;
1851
+ }
1852
+ };
1853
+ const getControlStringFromC1Introducer = (character) => {
1854
+ switch (character) {
1855
+ case oscCharacter: return {
1856
+ type: "osc",
1857
+ allowBellTerminator: true
1858
+ };
1859
+ case dcsCharacter: return {
1860
+ type: "dcs",
1861
+ allowBellTerminator: false
1862
+ };
1863
+ case pmCharacter: return {
1864
+ type: "pm",
1865
+ allowBellTerminator: false
1866
+ };
1867
+ case apcCharacter: return {
1868
+ type: "apc",
1869
+ allowBellTerminator: false
1870
+ };
1871
+ case sosCharacter: return {
1872
+ type: "sos",
1873
+ allowBellTerminator: false
1874
+ };
1875
+ default: return;
1876
+ }
1877
+ };
1878
+ const hasAnsiControlCharacters = (text) => {
1879
+ if (text.includes(escapeCharacter)) return true;
1880
+ for (const character of text) if (isC1ControlCharacter(character)) return true;
1881
+ return false;
1882
+ };
1883
+ const malformedFromIndex = (tokens, text, textStartIndex, fromIndex) => {
1884
+ if (fromIndex > textStartIndex) tokens.push({
1885
+ type: "text",
1886
+ value: text.slice(textStartIndex, fromIndex)
1887
+ });
1888
+ tokens.push({
1889
+ type: "invalid",
1890
+ value: text.slice(fromIndex)
1891
+ });
1892
+ return tokens;
1893
+ };
1894
+ const tokenizeAnsi = (text) => {
1895
+ if (!hasAnsiControlCharacters(text)) return [{
1896
+ type: "text",
1897
+ value: text
1898
+ }];
1899
+ const tokens = [];
1900
+ let textStartIndex = 0;
1901
+ for (let index = 0; index < text.length;) {
1902
+ const character = text[index];
1903
+ if (character === void 0) break;
1904
+ if (character === escapeCharacter) {
1905
+ const followingCharacter = text[index + 1];
1906
+ if (followingCharacter === void 0) return malformedFromIndex(tokens, text, textStartIndex, index);
1907
+ if (followingCharacter === "[") {
1908
+ const csiSequence = readCsiSequence(text, index + 2);
1909
+ if (csiSequence === void 0) return malformedFromIndex(tokens, text, textStartIndex, index);
1910
+ if (index > textStartIndex) tokens.push({
1911
+ type: "text",
1912
+ value: text.slice(textStartIndex, index)
1913
+ });
1914
+ tokens.push({
1915
+ type: "csi",
1916
+ value: text.slice(index, csiSequence.endIndex),
1917
+ parameterString: csiSequence.parameterString,
1918
+ intermediateString: csiSequence.intermediateString,
1919
+ finalCharacter: csiSequence.finalCharacter
1920
+ });
1921
+ index = csiSequence.endIndex;
1922
+ textStartIndex = index;
1923
+ continue;
1924
+ }
1925
+ const escapeControlString = getControlStringFromEscapeIntroducer(followingCharacter);
1926
+ if (escapeControlString !== void 0) {
1927
+ const controlStringTerminatorIndex = findControlStringTerminatorIndex(text, index + 2, escapeControlString.allowBellTerminator);
1928
+ if (controlStringTerminatorIndex === void 0) return malformedFromIndex(tokens, text, textStartIndex, index);
1929
+ if (index > textStartIndex) tokens.push({
1930
+ type: "text",
1931
+ value: text.slice(textStartIndex, index)
1932
+ });
1933
+ tokens.push({
1934
+ type: escapeControlString.type,
1935
+ value: text.slice(index, controlStringTerminatorIndex)
1936
+ });
1937
+ index = controlStringTerminatorIndex;
1938
+ textStartIndex = index;
1939
+ continue;
1940
+ }
1941
+ const escapeSequence = readEscapeSequence(text, index + 1);
1942
+ if (escapeSequence === void 0) {
1943
+ if (isEscapeIntermediateCharacter(followingCharacter)) return malformedFromIndex(tokens, text, textStartIndex, index);
1944
+ if (index > textStartIndex) tokens.push({
1945
+ type: "text",
1946
+ value: text.slice(textStartIndex, index)
1947
+ });
1948
+ index++;
1949
+ textStartIndex = index;
1950
+ continue;
1951
+ }
1952
+ if (index > textStartIndex) tokens.push({
1953
+ type: "text",
1954
+ value: text.slice(textStartIndex, index)
1955
+ });
1956
+ tokens.push({
1957
+ type: "esc",
1958
+ value: text.slice(index, escapeSequence.endIndex),
1959
+ intermediateString: escapeSequence.intermediateString,
1960
+ finalCharacter: escapeSequence.finalCharacter
1961
+ });
1962
+ index = escapeSequence.endIndex;
1963
+ textStartIndex = index;
1964
+ continue;
1965
+ }
1966
+ if (character === csiCharacter) {
1967
+ const csiSequence = readCsiSequence(text, index + 1);
1968
+ if (csiSequence === void 0) return malformedFromIndex(tokens, text, textStartIndex, index);
1969
+ if (index > textStartIndex) tokens.push({
1970
+ type: "text",
1971
+ value: text.slice(textStartIndex, index)
1972
+ });
1973
+ tokens.push({
1974
+ type: "csi",
1975
+ value: text.slice(index, csiSequence.endIndex),
1976
+ parameterString: csiSequence.parameterString,
1977
+ intermediateString: csiSequence.intermediateString,
1978
+ finalCharacter: csiSequence.finalCharacter
1979
+ });
1980
+ index = csiSequence.endIndex;
1981
+ textStartIndex = index;
1982
+ continue;
1983
+ }
1984
+ const c1ControlString = getControlStringFromC1Introducer(character);
1985
+ if (c1ControlString !== void 0) {
1986
+ const controlStringTerminatorIndex = findControlStringTerminatorIndex(text, index + 1, c1ControlString.allowBellTerminator);
1987
+ if (controlStringTerminatorIndex === void 0) return malformedFromIndex(tokens, text, textStartIndex, index);
1988
+ if (index > textStartIndex) tokens.push({
1989
+ type: "text",
1990
+ value: text.slice(textStartIndex, index)
1991
+ });
1992
+ tokens.push({
1993
+ type: c1ControlString.type,
1994
+ value: text.slice(index, controlStringTerminatorIndex)
1995
+ });
1996
+ index = controlStringTerminatorIndex;
1997
+ textStartIndex = index;
1998
+ continue;
1999
+ }
2000
+ if (character === stringTerminatorCharacter) {
2001
+ if (index > textStartIndex) tokens.push({
2002
+ type: "text",
2003
+ value: text.slice(textStartIndex, index)
2004
+ });
2005
+ tokens.push({
2006
+ type: "st",
2007
+ value: character
2008
+ });
2009
+ index++;
2010
+ textStartIndex = index;
2011
+ continue;
2012
+ }
2013
+ if (isC1ControlCharacter(character)) {
2014
+ if (index > textStartIndex) tokens.push({
2015
+ type: "text",
2016
+ value: text.slice(textStartIndex, index)
2017
+ });
2018
+ tokens.push({
2019
+ type: "c1",
2020
+ value: character
2021
+ });
2022
+ index++;
2023
+ textStartIndex = index;
2024
+ continue;
2025
+ }
2026
+ index++;
2027
+ }
2028
+ if (textStartIndex < text.length) tokens.push({
2029
+ type: "text",
2030
+ value: text.slice(textStartIndex)
2031
+ });
2032
+ return tokens;
1799
2033
  };
1800
2034
  //#endregion
1801
2035
  //#region src/ansi/tokenize.ts
1802
2036
  const BACKSLASH = "\\";
1803
2037
  const CSI = "[";
1804
2038
  const OSC = "]";
1805
- const CC_BEL = "\x07".charCodeAt(0);
1806
- const CC_ESC = "\x1B".charCodeAt(0);
1807
- const CC_BACKSLASH = BACKSLASH.charCodeAt(0);
1808
- const CC_CSI = CSI.charCodeAt(0);
1809
- const CC_OSC = OSC.charCodeAt(0);
1810
- const CC_C1_ST = "œ".charCodeAt(0);
1811
- const CC_0 = "0".charCodeAt(0);
1812
- const CC_9 = "9".charCodeAt(0);
1813
- const CC_SEMI = ";".charCodeAt(0);
1814
- const CC_M = "m".charCodeAt(0);
1815
- const ESCAPES = /* @__PURE__ */ new Set([CC_ESC, 155]);
1816
2039
  const linkCodePrefix = `${OSC}8;`;
1817
- const linkCodePrefixCharCodes = linkCodePrefix.split("").map((char) => char.charCodeAt(0));
1818
2040
  const linkCodeSuffix = "\x07";
1819
2041
  const linkEndCode = `${OSC}8;;`;
1820
2042
  const linkEndCodeST = `${OSC}8;;${BACKSLASH}`;
@@ -1840,6 +2062,7 @@ function getEndCode(code) {
1840
2062
  code = code.slice(2);
1841
2063
  if (code.startsWith("38")) return foreground.close;
1842
2064
  if (code.startsWith("48")) return background.close;
2065
+ if (code.startsWith("58")) return ``;
1843
2066
  const endCode = codes.get(Number.parseInt(code, 10));
1844
2067
  if (endCode !== void 0) return foreground.ansi(endCode);
1845
2068
  return styles.reset.open;
@@ -1855,63 +2078,6 @@ function isIntensityCode(code) {
1855
2078
  return code.code === styles.bold.open || code.code === styles.dim.open;
1856
2079
  }
1857
2080
  const segmenter = new Intl.Segmenter(void 0, { granularity: "grapheme" });
1858
- function isFullwidthGrapheme(grapheme, baseCodePoint) {
1859
- if (isFullwidthCodePoint(baseCodePoint)) return true;
1860
- if (grapheme.includes("️")) return true;
1861
- if (baseCodePoint >= 127462 && baseCodePoint <= 127487) return true;
1862
- return false;
1863
- }
1864
- function parseLinkCode(string, offset) {
1865
- string = string.slice(offset);
1866
- for (let index = 1; index < linkCodePrefixCharCodes.length; index++) if (string.charCodeAt(index) !== linkCodePrefixCharCodes[index]) return;
1867
- const paramsEndIndex = string.indexOf(";", linkCodePrefix.length);
1868
- if (paramsEndIndex === -1) return;
1869
- const endIndex = findOscTerminatorIndex(string, paramsEndIndex + 1);
1870
- if (endIndex === -1) return;
1871
- return string.slice(0, endIndex + 1);
1872
- }
1873
- function parseOscSequence(string, offset) {
1874
- string = string.slice(offset);
1875
- const endIndex = findOscTerminatorIndex(string, 2);
1876
- if (endIndex === -1) return;
1877
- return string.slice(0, endIndex + 1);
1878
- }
1879
- /**
1880
- Finds the index of the last character of the first OSC terminator at or after
1881
- `startIndex`. Recognizes BEL (\u0007), C1 ST (\u009C), and ESC+backslash.
1882
- Returns -1 if no terminator is found.
1883
- */
1884
- function findOscTerminatorIndex(string, startIndex) {
1885
- for (let index = startIndex; index < string.length; index++) {
1886
- const charCode = string.charCodeAt(index);
1887
- if (charCode === CC_BEL) return index;
1888
- if (charCode === CC_C1_ST) return index;
1889
- if (charCode === CC_ESC && index + 1 < string.length && string.charCodeAt(index + 1) === CC_BACKSLASH) return index + 1;
1890
- }
1891
- return -1;
1892
- }
1893
- /**
1894
- Scans through the given string and finds the index of the last character of an
1895
- SGR sequence like `\u001B[38;2;123;123;123m`. This assumes that the string has
1896
- been checked to start with `\u001B[`. Returns -1 if no valid SGR sequence is
1897
- found.
1898
- */
1899
- function findSgrSequenceEndIndex(string) {
1900
- for (let index = 2; index < string.length; index++) {
1901
- const charCode = string.charCodeAt(index);
1902
- if (charCode === CC_M) return index;
1903
- if (charCode === CC_SEMI) continue;
1904
- if (charCode >= CC_0 && charCode <= CC_9) continue;
1905
- break;
1906
- }
1907
- return -1;
1908
- }
1909
- function parseSgrSequence(string, offset) {
1910
- string = string.slice(offset);
1911
- const endIndex = findSgrSequenceEndIndex(string);
1912
- if (endIndex === -1) return;
1913
- return string.slice(0, endIndex + 1);
1914
- }
1915
2081
  /**
1916
2082
  Splits compound SGR sequences like `\u001B[1;3;31m` into individual components.
1917
2083
  */
@@ -1936,51 +2102,59 @@ function splitCompoundSgrSequences(code) {
1936
2102
  }
1937
2103
  return result.map((part) => `[${part}m`);
1938
2104
  }
2105
+ const SGR_PARAMETERS_RE = /^[\d;:]*$/;
2106
+ const c1LinkCodePrefix = "8;";
1939
2107
  function tokenize(string, endChar = Number.POSITIVE_INFINITY) {
1940
2108
  const result = [];
1941
2109
  let visible = 0;
1942
- let codeEndIndex = 0;
1943
- for (const { segment, index } of segmenter.segment(string)) {
1944
- if (index < codeEndIndex) continue;
1945
- const codePoint = segment.codePointAt(0);
1946
- if (ESCAPES.has(codePoint)) {
1947
- let code;
1948
- const nextCodePoint = string.codePointAt(index + 1);
1949
- if (nextCodePoint === CC_OSC) {
1950
- code = parseLinkCode(string, index);
1951
- if (code) result.push({
1952
- type: "ansi",
1953
- code,
1954
- endCode: getEndCode(code)
2110
+ outer: for (const ansiToken of tokenizeAnsi(string)) {
2111
+ if (ansiToken.type === "text") {
2112
+ for (const { segment } of segmenter.segment(ansiToken.value)) {
2113
+ const fullWidth = isFullwidthGrapheme(segment, segment.codePointAt(0));
2114
+ result.push({
2115
+ type: "char",
2116
+ value: segment,
2117
+ fullWidth
1955
2118
  });
1956
- else {
1957
- code = parseOscSequence(string, index);
1958
- if (code) result.push({
1959
- type: "control",
1960
- code
1961
- });
1962
- }
1963
- } else if (nextCodePoint === CC_CSI) {
1964
- code = parseSgrSequence(string, index);
1965
- if (code) for (const individualCode of splitCompoundSgrSequences(code)) result.push({
2119
+ visible += fullWidth ? 2 : 1;
2120
+ if (visible >= endChar) break outer;
2121
+ }
2122
+ continue;
2123
+ }
2124
+ if (ansiToken.type === "csi") {
2125
+ if (ansiToken.finalCharacter === "m" && ansiToken.intermediateString === "" && SGR_PARAMETERS_RE.test(ansiToken.parameterString)) {
2126
+ const code = `${CSI}${ansiToken.parameterString}m`;
2127
+ for (const individualCode of splitCompoundSgrSequences(code)) result.push({
1966
2128
  type: "ansi",
1967
2129
  code: individualCode,
1968
2130
  endCode: getEndCode(individualCode)
1969
2131
  });
1970
- }
1971
- if (code) {
1972
- codeEndIndex = index + code.length;
1973
- continue;
1974
- }
2132
+ } else result.push({
2133
+ type: "control",
2134
+ code: ansiToken.value
2135
+ });
2136
+ continue;
2137
+ }
2138
+ if (ansiToken.type === "osc") {
2139
+ const { value } = ansiToken;
2140
+ const prefix = value.startsWith(linkCodePrefix) ? linkCodePrefix : value.startsWith(c1LinkCodePrefix) ? c1LinkCodePrefix : void 0;
2141
+ if (prefix !== void 0 && value.includes(";", prefix.length)) {
2142
+ const code = prefix === linkCodePrefix ? value : `${linkCodePrefix}${value.slice(prefix.length)}`;
2143
+ result.push({
2144
+ type: "ansi",
2145
+ code,
2146
+ endCode: getEndCode(code)
2147
+ });
2148
+ } else result.push({
2149
+ type: "control",
2150
+ code: value
2151
+ });
2152
+ continue;
1975
2153
  }
1976
- const fullWidth = isFullwidthGrapheme(segment, codePoint);
1977
2154
  result.push({
1978
- type: "char",
1979
- value: segment,
1980
- fullWidth
2155
+ type: "control",
2156
+ code: ansiToken.value
1981
2157
  });
1982
- visible += fullWidth ? 2 : 1;
1983
- if (visible >= endChar) break;
1984
2158
  }
1985
2159
  return result;
1986
2160
  }
@@ -2011,7 +2185,7 @@ function reduceAnsiCodesIncremental(codes, newCodes) {
2011
2185
  Returns the combination of ANSI codes needed to undo the given ANSI codes.
2012
2186
  */
2013
2187
  function undoAnsiCodes(codes) {
2014
- return reduceAnsiCodes(codes).reverse().map((code) => ({
2188
+ return reduceAnsiCodes(codes).toReversed().map((code) => ({
2015
2189
  ...code,
2016
2190
  code: code.endCode
2017
2191
  }));
@@ -2081,7 +2255,7 @@ function getIndexOfNearestSpace(string, wantedIndex, shouldSearchRight = false)
2081
2255
  const ANSI_ESC = 27;
2082
2256
  const ANSI_LEFT_BRACKET = 91;
2083
2257
  const ANSI_LETTER_M = 109;
2084
- const isSgrParameter = (code) => code >= 48 && code <= 57 || code === 59;
2258
+ const isSgrParameter = (code) => code >= 48 && code <= 57 || code === 59 || code === 58;
2085
2259
  function leadingSgrSpanEndIndex(string) {
2086
2260
  let index = 0;
2087
2261
  while (index + 2 < string.length && string.codePointAt(index) === ANSI_ESC && string.codePointAt(index + 1) === ANSI_LEFT_BRACKET) {
@@ -2153,4 +2327,4 @@ function cliTruncate(text, columns, options = {}) {
2153
2327
  return appendWithInheritedStyleFromEnd(sliceAnsi(text, 0, columns - stringWidth(truncationCharacter)), truncationCharacter);
2154
2328
  }
2155
2329
  //#endregion
2156
- export { hexToAnsi256 as $, fullwidthMinimalCodePoint as A, esu as At, narrowMaximumCodePoint as B, stripAnsi as C, disableBracketedPaste as Ct, eastAsianWidth as D, eraseLine as Dt, ambiguousRanges as E, eraseEndLine as Et, halfwidthRanges as F, pasteStart as Ft, wideRanges as G, narrowRanges as H, isAmbiguous as I, popKittyKeyboard as It, backgroundColorNames as J, ansi256ToAnsi as K, isFullWidth as L, pushKittyKeyboard as Lt, getCategory as M, kittyQuery as Mt, halfwidthMaximumCodePoint as N, link as Nt, eastAsianWidthType as O, eraseLines as Ot, halfwidthMinimalCodePoint as P, pasteEnd as Pt, hexToAnsi as Q, isFullwidthCodePoint as R, ansiRegex as S, cursorUp as St, ambiguousMinimalCodePoint as T, enterAlternativeScreen as Tt, wideMaximumCodePoint as U, narrowMinimalCodePoint as V, wideMinimalCodePoint as W, foreground as X, codes as Y, foregroundColorNames as Z, supportsColor as _, cursorHide as _t, endCodesSet as a, BEL as at, wrapAnsi as b, cursorShow as bt, isIntensityCode as c, CSI$1 as ct, styledCharsFromTokens as d, OSC$1 as dt, hexToRgb as et, styledCharsToString as f, ST as ft, chalk as g, cursorDown as gt, widestLine as h, clearTerminal as ht, diffAnsiCodes as i, styles as it, fullwidthRanges as j, exitAlternativeScreen as jt, fullwidthMaximumCodePoint as k, eraseScreen as kt, reduceAnsiCodes as l, DEL as lt, undoAnsiCodes as m, bsu as mt, sliceAnsi as n, rgbToAnsi as nt, getEndCode as o, C1_CSI as ot, tokenize as p, ansiEscapes as pt, background as q, ansiCodesToString as r, rgbToAnsi256 as rt, getLinkStartCode as s, C1_ST as st, cliTruncate as t, modifierNames as tt, reduceAnsiCodesIncremental as u, ESC as ut, cliCursor as v, cursorLeft as vt, ambiguousMaximumCodePoint as w, enableBracketedPaste as wt, stringWidth as x, cursorTo as xt, signalExit as y, cursorNextLine as yt, isWide as z };
2330
+ export { wideRanges as $, ambiguousMaximumCodePoint as A, cursorUp as At, halfwidthMinimalCodePoint as B, kittyQuery as Bt, isScreenReader as C, clearTerminal as Ct, wrapAnsi as D, cursorNextLine as Dt, isWindows as E, cursorLeft as Et, fullwidthMaximumCodePoint as F, eraseLine as Ft, isFullwidthGrapheme as G, pushKittyKeyboard as Gt, isAmbiguous as H, pasteEnd as Ht, fullwidthMinimalCodePoint as I, eraseLines as It, narrowMaximumCodePoint as J, isWide as K, fullwidthRanges as L, eraseScreen as Lt, ambiguousRanges as M, enableBracketedPaste as Mt, eastAsianWidth as N, enterAlternativeScreen as Nt, stringWidth as O, cursorShow as Ot, eastAsianWidthType as P, eraseEndLine as Pt, wideMinimalCodePoint as Q, getCategory as R, esu as Rt, isMacos as S, bsu as St, isTty as T, cursorHide as Tt, isFullWidth as U, pasteStart as Ut, halfwidthRanges as V, link as Vt, isFullwidthCodePoint as W, popKittyKeyboard as Wt, narrowRanges as X, narrowMinimalCodePoint as Y, wideMaximumCodePoint as Z, chalk as _, DEL as _t, endCodesSet as a, foregroundColorNames as at, signalExit as b, ST as bt, isIntensityCode as c, hexToRgb as ct, styledCharsFromTokens as d, rgbToAnsi256 as dt, ansi256ToAnsi as et, styledCharsToString as f, styles as ft, tokenizeAnsi as g, CSI$1 as gt, hasAnsiControlCharacters as h, C1_ST as ht, diffAnsiCodes as i, foreground as it, ambiguousMinimalCodePoint as j, disableBracketedPaste as jt, widestLine as k, cursorTo as kt, reduceAnsiCodes as l, modifierNames as lt, undoAnsiCodes as m, C1_CSI as mt, sliceAnsi as n, backgroundColorNames as nt, getEndCode as o, hexToAnsi as ot, tokenize as p, BEL as pt, isWideNotCJKTNotEmoji as q, ansiCodesToString as r, codes as rt, getLinkStartCode as s, hexToAnsi256 as st, cliTruncate as t, background as tt, reduceAnsiCodesIncremental as u, rgbToAnsi as ut, supportsColor as v, ESC as vt, isSigilDev as w, cursorDown as wt, isInCi as x, ansiEscapes as xt, cliCursor as y, OSC$1 as yt, halfwidthMaximumCodePoint as z, exitAlternativeScreen as zt };