@simon_he/vue-tui 1.1.3 → 1.1.5

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 (52) hide show
  1. package/README.md +18 -18
  2. package/dist/{TMermaidText-frVr8Ysb.js → TMermaidText-wLnMMvVS.js} +1 -1
  3. package/dist/{TSelect-Dx34M1pF.js → TSelect-CMBOOFwK.js} +5 -5
  4. package/dist/{TTree-DdAjCPHu.js → TTree-kk8ntrpg.js} +6 -5
  5. package/dist/agent/mermaid.d.cts +2 -2
  6. package/dist/agent/mermaid.d.ts +2 -2
  7. package/dist/agent.cjs +542 -266
  8. package/dist/agent.js +25 -82
  9. package/dist/{block-source-Crro3mxi.js → block-source-DhzajB9H.js} +299 -239
  10. package/dist/cli.cjs +57 -16
  11. package/dist/cli.js +70 -15
  12. package/dist/core.js +3 -3
  13. package/dist/{hyperlink-_1FAj7Wq.js → create-terminal-Db_-UGVQ.js} +474 -102
  14. package/dist/{dom-renderer-DXx8fWzD.js → dom-renderer-BfwAEQMf.js} +3 -2
  15. package/dist/experimental.cjs +103 -66
  16. package/dist/experimental.js +20 -74
  17. package/dist/hyperlink-clbb_ha_.js +100 -0
  18. package/dist/index.js +8 -8
  19. package/dist/{linkify-BjI4zVfY.js → linkify-CL9wwnZN.js} +3 -3
  20. package/dist/markdown.cjs +521 -212
  21. package/dist/markdown.d.cts +3 -0
  22. package/dist/markdown.d.ts +3 -0
  23. package/dist/markdown.js +75 -8
  24. package/dist/math-image-BZhmfUeu.js +308 -0
  25. package/dist/mermaid-N3kGTHFy.js +1697 -0
  26. package/dist/mermaid.cjs +1460 -6
  27. package/dist/mermaid.d.cts +4 -0
  28. package/dist/mermaid.d.ts +4 -0
  29. package/dist/mermaid.js +7 -5
  30. package/dist/{rect-DUpeDfBg.js → rect-JzWMJxxc.js} +1 -1
  31. package/dist/renderer/cli/stdout-renderer.d.ts +44 -0
  32. package/dist/renderer/terminal-graphics.d.ts +61 -0
  33. package/dist/renderer-dom.js +4 -4
  34. package/dist/{terminal-graphics-Bbe83wSr.js → terminal-graphics-2FTRg9x3.js} +90 -2
  35. package/dist/{tlog-theme-i6S_Oftd.js → tlog-theme-B91Wv7Zj.js} +5 -4
  36. package/dist/vue/components/TAgentTerminalGraphic.d.ts +1 -1
  37. package/dist/vue/components/TMarkdownText.d.ts +70 -2
  38. package/dist/vue/components/TMermaidImage.d.ts +920 -0
  39. package/dist/vue/components/TMermaidText.d.ts +2 -2
  40. package/dist/vue/components/TVirtualMarkdown.d.ts +70 -2
  41. package/dist/vue/markdown/ast.d.ts +5 -0
  42. package/dist/vue/markdown/document.d.ts +3 -0
  43. package/dist/vue/markdown/math-image.d.ts +68 -0
  44. package/dist/vue/markdown/theme.d.ts +12 -0
  45. package/dist/vue/markdown/types.d.ts +12 -2
  46. package/dist/vue/mermaid/beautiful-mermaid.d.ts +284 -240
  47. package/dist/vue/mermaid/mermaid-image.d.ts +73 -0
  48. package/dist/vue.js +9 -9
  49. package/package.json +24 -10
  50. package/dist/mermaid-BNhM1jAZ.js +0 -123
  51. package/dist/width-GqllnV8C.js +0 -474
  52. /package/dist/{ansi-palette-CH6jc2Z7.js → ansi-palette-BHF1rN7R.js} +0 -0
@@ -2578,6 +2578,95 @@ function formatItermDimension(value) {
2578
2578
  let raw = String(value ?? "").trim();
2579
2579
  return validateIterm2Dimension(raw) ? raw : "auto";
2580
2580
  }
2581
+ function resolveKittyPngSourceCrop(rect, fullRect, sourceWidth, sourceHeight) {
2582
+ if (fullRect.w <= 0 || fullRect.h <= 0)
2583
+ return null;
2584
+ let offsetX = Math.max(0, rect.x - fullRect.x), offsetY = Math.max(0, rect.y - fullRect.y), visibleW = Math.max(0, Math.min(rect.w, fullRect.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, fullRect.h - offsetY));
2585
+ if (offsetX <= 0 && offsetY <= 0 && visibleW >= fullRect.w && visibleH >= fullRect.h)
2586
+ return null;
2587
+ let sourceX = Math.max(
2588
+ 0,
2589
+ Math.min(sourceWidth - 1, Math.floor(offsetX * sourceWidth / fullRect.w))
2590
+ ), sourceY = Math.max(
2591
+ 0,
2592
+ Math.min(sourceHeight - 1, Math.floor(offsetY * sourceHeight / fullRect.h))
2593
+ ), sourceRight = Math.max(
2594
+ sourceX + 1,
2595
+ Math.min(sourceWidth, Math.ceil((offsetX + visibleW) * sourceWidth / fullRect.w))
2596
+ ), sourceBottom = Math.max(
2597
+ sourceY + 1,
2598
+ Math.min(sourceHeight, Math.ceil((offsetY + visibleH) * sourceHeight / fullRect.h))
2599
+ );
2600
+ return {
2601
+ sourceX,
2602
+ sourceY,
2603
+ sourceWidth: sourceRight - sourceX,
2604
+ sourceHeight: sourceBottom - sourceY
2605
+ };
2606
+ }
2607
+ function createTerminalGraphicPngSequence(options) {
2608
+ if (options.protocol === "kitty") {
2609
+ let placement = {
2610
+ columns: options.placementColumns,
2611
+ rows: options.placementRows
2612
+ };
2613
+ if (options.rect && options.fullRect && options.sourceWidth && options.sourceHeight) {
2614
+ let crop = resolveKittyPngSourceCrop(
2615
+ options.rect,
2616
+ options.fullRect,
2617
+ options.sourceWidth,
2618
+ options.sourceHeight
2619
+ );
2620
+ crop && (placement = { ...placement, ...crop });
2621
+ }
2622
+ let transmissionPlacement = options.cropTransmission !== !1 ? placement : {
2623
+ columns: options.transmissionColumns ?? options.placementColumns,
2624
+ rows: options.transmissionRows ?? options.placementRows
2625
+ };
2626
+ return {
2627
+ type: "sequence",
2628
+ protocol: "kitty",
2629
+ sequence: createKittyGraphicsSequence(options.base64, {
2630
+ imageId: options.imageId,
2631
+ placementId: options.placementId,
2632
+ zIndex: options.zIndex,
2633
+ ...transmissionPlacement
2634
+ }),
2635
+ resizeSequence: createKittyPlacementSequence({
2636
+ imageId: options.imageId,
2637
+ placementId: options.placementId,
2638
+ zIndex: options.zIndex,
2639
+ ...placement
2640
+ }),
2641
+ clearSequence: createKittyDeleteGraphicsSequence({
2642
+ imageId: options.imageId,
2643
+ placementId: options.placementId,
2644
+ freeImageData: options.freeImageData
2645
+ }),
2646
+ ...options.fallback != null ? { fallback: options.fallback } : {},
2647
+ ...options.cols != null ? { cols: options.cols } : {},
2648
+ ...options.rows != null ? { rows: options.rows } : {},
2649
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
2650
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {},
2651
+ ...options.zIndex != null ? { zIndex: options.zIndex } : {}
2652
+ };
2653
+ }
2654
+ return options.protocol === "iterm2" ? {
2655
+ type: "sequence",
2656
+ protocol: "iterm2",
2657
+ sequence: createIterm2InlineImageSequence(options.base64, {
2658
+ width: options.cols,
2659
+ height: options.rows,
2660
+ preserveAspectRatio: !0,
2661
+ doNotMoveCursor: !0
2662
+ }),
2663
+ ...options.fallback != null ? { fallback: options.fallback } : {},
2664
+ ...options.cols != null ? { cols: options.cols } : {},
2665
+ ...options.rows != null ? { rows: options.rows } : {},
2666
+ ...options.sourceWidth != null ? { sourceWidth: options.sourceWidth } : {},
2667
+ ...options.sourceHeight != null ? { sourceHeight: options.sourceHeight } : {}
2668
+ } : null;
2669
+ }
2581
2670
 
2582
2671
  // src/vue/components/TAgentTerminalGraphic.ts
2583
2672
  var import_vue10 = require("vue");
@@ -3725,35 +3814,6 @@ function bytesToBase64(bytes) {
3725
3814
  }
3726
3815
  return chunk && chunks.push(chunk), chunks.join("");
3727
3816
  }
3728
- function resolveKittyPlacement(frame, context) {
3729
- let rect = context.viewport.rect, full = context.viewport.fullRect, columns = Math.max(1, Math.floor(rect.w)), rows = Math.max(1, Math.floor(rect.h));
3730
- if (full.w <= 0 || full.h <= 0)
3731
- return { columns, rows };
3732
- let offsetX = Math.max(0, rect.x - full.x), offsetY = Math.max(0, rect.y - full.y), visibleW = Math.max(0, Math.min(rect.w, full.w - offsetX)), visibleH = Math.max(0, Math.min(rect.h, full.h - offsetY));
3733
- if (offsetX <= 0 && offsetY <= 0 && visibleW >= full.w && visibleH >= full.h)
3734
- return { columns, rows };
3735
- let sourceX = Math.max(
3736
- 0,
3737
- Math.min(frame.pixelWidth - 1, Math.floor(offsetX * frame.pixelWidth / full.w))
3738
- ), sourceY = Math.max(
3739
- 0,
3740
- Math.min(frame.pixelHeight - 1, Math.floor(offsetY * frame.pixelHeight / full.h))
3741
- ), sourceRight = Math.max(
3742
- sourceX + 1,
3743
- Math.min(frame.pixelWidth, Math.ceil((offsetX + visibleW) * frame.pixelWidth / full.w))
3744
- ), sourceBottom = Math.max(
3745
- sourceY + 1,
3746
- Math.min(frame.pixelHeight, Math.ceil((offsetY + visibleH) * frame.pixelHeight / full.h))
3747
- );
3748
- return {
3749
- columns,
3750
- rows,
3751
- sourceX,
3752
- sourceY,
3753
- sourceWidth: sourceRight - sourceX,
3754
- sourceHeight: sourceBottom - sourceY
3755
- };
3756
- }
3757
3817
  function createFrameRenderer(frame, cellWidth) {
3758
3818
  if (frame.format === "gray8") {
3759
3819
  let text = gray8ToAscii(frame, cellWidth);
@@ -3763,46 +3823,23 @@ function createFrameRenderer(frame, cellWidth) {
3763
3823
  return (_content, context) => {
3764
3824
  if (!context.visible || !context.rawVisible)
3765
3825
  return null;
3766
- if (base64 ?? (base64 = bytesToBase64(frame.png)), context.protocol === "kitty") {
3767
- let placement = resolveKittyPlacement(frame, context);
3768
- return {
3769
- type: "sequence",
3770
- protocol: "kitty",
3771
- sequence: createKittyGraphicsSequence(base64, {
3772
- imageId: context.imageId,
3773
- placementId: context.placementId,
3774
- ...placement
3775
- }),
3776
- resizeSequence: createKittyPlacementSequence({
3777
- imageId: context.imageId,
3778
- placementId: context.placementId,
3779
- ...placement
3780
- }),
3781
- clearSequence: createKittyDeleteGraphicsSequence({
3782
- imageId: context.imageId,
3783
- placementId: context.placementId,
3784
- freeImageData: !0
3785
- }),
3786
- cols: context.width,
3787
- rows: context.height,
3788
- sourceWidth: frame.pixelWidth,
3789
- sourceHeight: frame.pixelHeight
3790
- };
3791
- }
3792
- return context.protocol === "iterm2" ? {
3793
- type: "sequence",
3794
- protocol: "iterm2",
3795
- sequence: createIterm2InlineImageSequence(base64, {
3796
- width: context.width,
3797
- height: context.height,
3798
- preserveAspectRatio: !0,
3799
- doNotMoveCursor: !0
3800
- }),
3826
+ base64 ?? (base64 = bytesToBase64(frame.png));
3827
+ let protocol = context.protocol;
3828
+ return protocol !== "kitty" && protocol !== "iterm2" ? null : createTerminalGraphicPngSequence({
3829
+ protocol,
3830
+ base64,
3831
+ imageId: context.imageId,
3832
+ placementId: context.placementId,
3801
3833
  cols: context.width,
3802
3834
  rows: context.height,
3803
3835
  sourceWidth: frame.pixelWidth,
3804
- sourceHeight: frame.pixelHeight
3805
- } : null;
3836
+ sourceHeight: frame.pixelHeight,
3837
+ placementColumns: Math.max(1, Math.floor(context.viewport.rect.w)),
3838
+ placementRows: Math.max(1, Math.floor(context.viewport.rect.h)),
3839
+ rect: context.viewport.rect,
3840
+ fullRect: context.viewport.fullRect,
3841
+ freeImageData: !0
3842
+ });
3806
3843
  };
3807
3844
  }
3808
3845
  function errorMessage2(error) {
@@ -1,12 +1,12 @@
1
- import { sanitizeTerminalHref } from "./hyperlink-_1FAj7Wq.js";
2
- import "./width-GqllnV8C.js";
3
- import { EventZIndexContextKey, TerminalGraphicsActivityKey, forEachTextCellSegment, intersectRect, sanitizeInlineText, sliceByCells, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility } from "./rect-DUpeDfBg.js";
4
- import { TText, TView, createFrameMailbox, mergeStyle } from "./linkify-BjI4zVfY.js";
1
+ import "./create-terminal-Db_-UGVQ.js";
2
+ import { sanitizeTerminalHref } from "./hyperlink-clbb_ha_.js";
3
+ import { EventZIndexContextKey, TerminalGraphicsActivityKey, forEachTextCellSegment, intersectRect, sanitizeInlineText, sliceByCells, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useTerminal, useTerminalNode, useVisibility } from "./rect-JzWMJxxc.js";
4
+ import { TText, TView, createFrameMailbox, mergeStyle } from "./linkify-CL9wwnZN.js";
5
5
  import "./frame-perf-CHpWhbC4.js";
6
6
  import "./terminal-selection-4W1SJj4c.js";
7
7
  import "./wheel-scroll-DASkEZr-.js";
8
- import { createIterm2InlineImageSequence, createKittyDeleteGraphicsSequence, createKittyGraphicsSequence, createKittyPlacementSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, subscribeTerminalGraphicsOutput } from "./terminal-graphics-Bbe83wSr.js";
9
- import { TAgentTerminalGraphic, TLogLinksPanel, TLogMinimap, TLogScrollbar, TLogSearchBar, TLogSearchPager, TLogSearchResults, TLogView, TLogVirtualLinksPanel, TLogVirtualSearchResults, TTranscriptView, TVirtualList, createAppendOnlyLogStore, createTLogDensityBucketsFromMarkers, createTLogLevelPlugin, createTLogLineMatcherPlugin, createTLogLinkActionPlugin, createTLogOsc8LinkPlugin, createTLogUrlPlugin, detectTLogUrls, dispatchTLogPluginLinkAction, getTLogPluginMetadata, handleTLogKeymapEvent, matchesTLogKeyBinding, parseTLogAnnotatedText, resolveTLogLinksPanelTheme, resolveTLogMinimapTheme, resolveTLogScrollbarTheme, resolveTLogSearchBarTheme, resolveTLogSearchPagerTheme, resolveTLogSearchResultsTheme, resolveTLogViewTheme, stripTLogAnsiText, tlogDarkPreset, tlogDarkTheme, tlogDefaultKeymap, tlogDefaultPreset, tlogDefaultTheme, tlogHighContrastKeymap, tlogHighContrastPreset, tlogHighContrastTheme, toTLogExternalLinkFromVisibleLink, useTLogLinkController, useTLogRetainedIndex, useTLogSearchController, useTLogSearchResultsPage, useTLogVirtualSearchResults } from "./tlog-theme-i6S_Oftd.js";
8
+ import { createTerminalGraphicPngSequence, getTerminalGraphicsOutput, getTerminalGraphicsOutputVersion, subscribeTerminalGraphicsOutput } from "./terminal-graphics-2FTRg9x3.js";
9
+ import { TAgentTerminalGraphic, TLogLinksPanel, TLogMinimap, TLogScrollbar, TLogSearchBar, TLogSearchPager, TLogSearchResults, TLogView, TLogVirtualLinksPanel, TLogVirtualSearchResults, TTranscriptView, TVirtualList, createAppendOnlyLogStore, createTLogDensityBucketsFromMarkers, createTLogLevelPlugin, createTLogLineMatcherPlugin, createTLogLinkActionPlugin, createTLogOsc8LinkPlugin, createTLogUrlPlugin, detectTLogUrls, dispatchTLogPluginLinkAction, getTLogPluginMetadata, handleTLogKeymapEvent, matchesTLogKeyBinding, parseTLogAnnotatedText, resolveTLogLinksPanelTheme, resolveTLogMinimapTheme, resolveTLogScrollbarTheme, resolveTLogSearchBarTheme, resolveTLogSearchPagerTheme, resolveTLogSearchResultsTheme, resolveTLogViewTheme, stripTLogAnsiText, tlogDarkPreset, tlogDarkTheme, tlogDefaultKeymap, tlogDefaultPreset, tlogDefaultTheme, tlogHighContrastKeymap, tlogHighContrastPreset, tlogHighContrastTheme, toTLogExternalLinkFromVisibleLink, useTLogLinkController, useTLogRetainedIndex, useTLogSearchController, useTLogSearchResultsPage, useTLogVirtualSearchResults } from "./tlog-theme-B91Wv7Zj.js";
10
10
  import { computed, defineComponent, getCurrentInstance, h, inject, markRaw, onBeforeUnmount, onUnmounted, ref, shallowRef, watch } from "vue";
11
11
 
12
12
  //#region src/vue/components/TVideo.ts
@@ -128,36 +128,6 @@ function bytesToBase64(bytes) {
128
128
  if (chunk) chunks.push(chunk);
129
129
  return chunks.join("");
130
130
  }
131
- function resolveKittyPlacement(frame, context) {
132
- const rect = context.viewport.rect;
133
- const full = context.viewport.fullRect;
134
- const columns = Math.max(1, Math.floor(rect.w));
135
- const rows = Math.max(1, Math.floor(rect.h));
136
- if (full.w <= 0 || full.h <= 0) return {
137
- columns,
138
- rows
139
- };
140
- const offsetX = Math.max(0, rect.x - full.x);
141
- const offsetY = Math.max(0, rect.y - full.y);
142
- const visibleW = Math.max(0, Math.min(rect.w, full.w - offsetX));
143
- const visibleH = Math.max(0, Math.min(rect.h, full.h - offsetY));
144
- if (offsetX <= 0 && offsetY <= 0 && visibleW >= full.w && visibleH >= full.h) return {
145
- columns,
146
- rows
147
- };
148
- const sourceX = Math.max(0, Math.min(frame.pixelWidth - 1, Math.floor(offsetX * frame.pixelWidth / full.w)));
149
- const sourceY = Math.max(0, Math.min(frame.pixelHeight - 1, Math.floor(offsetY * frame.pixelHeight / full.h)));
150
- const sourceRight = Math.max(sourceX + 1, Math.min(frame.pixelWidth, Math.ceil((offsetX + visibleW) * frame.pixelWidth / full.w)));
151
- const sourceBottom = Math.max(sourceY + 1, Math.min(frame.pixelHeight, Math.ceil((offsetY + visibleH) * frame.pixelHeight / full.h)));
152
- return {
153
- columns,
154
- rows,
155
- sourceX,
156
- sourceY,
157
- sourceWidth: sourceRight - sourceX,
158
- sourceHeight: sourceBottom - sourceY
159
- };
160
- }
161
131
  function createFrameRenderer(frame, cellWidth) {
162
132
  if (frame.format === "gray8") {
163
133
  const text = gray8ToAscii(frame, cellWidth);
@@ -170,47 +140,23 @@ function createFrameRenderer(frame, cellWidth) {
170
140
  return (_content, context) => {
171
141
  if (!context.visible || !context.rawVisible) return null;
172
142
  base64 ?? (base64 = bytesToBase64(frame.png));
173
- if (context.protocol === "kitty") {
174
- const placement = resolveKittyPlacement(frame, context);
175
- return {
176
- type: "sequence",
177
- protocol: "kitty",
178
- sequence: createKittyGraphicsSequence(base64, {
179
- imageId: context.imageId,
180
- placementId: context.placementId,
181
- ...placement
182
- }),
183
- resizeSequence: createKittyPlacementSequence({
184
- imageId: context.imageId,
185
- placementId: context.placementId,
186
- ...placement
187
- }),
188
- clearSequence: createKittyDeleteGraphicsSequence({
189
- imageId: context.imageId,
190
- placementId: context.placementId,
191
- freeImageData: true
192
- }),
193
- cols: context.width,
194
- rows: context.height,
195
- sourceWidth: frame.pixelWidth,
196
- sourceHeight: frame.pixelHeight
197
- };
198
- }
199
- if (context.protocol === "iterm2") return {
200
- type: "sequence",
201
- protocol: "iterm2",
202
- sequence: createIterm2InlineImageSequence(base64, {
203
- width: context.width,
204
- height: context.height,
205
- preserveAspectRatio: true,
206
- doNotMoveCursor: true
207
- }),
143
+ const protocol = context.protocol;
144
+ if (protocol !== "kitty" && protocol !== "iterm2") return null;
145
+ return createTerminalGraphicPngSequence({
146
+ protocol,
147
+ base64,
148
+ imageId: context.imageId,
149
+ placementId: context.placementId,
208
150
  cols: context.width,
209
151
  rows: context.height,
210
152
  sourceWidth: frame.pixelWidth,
211
- sourceHeight: frame.pixelHeight
212
- };
213
- return null;
153
+ sourceHeight: frame.pixelHeight,
154
+ placementColumns: Math.max(1, Math.floor(context.viewport.rect.w)),
155
+ placementRows: Math.max(1, Math.floor(context.viewport.rect.h)),
156
+ rect: context.viewport.rect,
157
+ fullRect: context.viewport.fullRect,
158
+ freeImageData: true
159
+ });
214
160
  };
215
161
  }
216
162
  function errorMessage(error) {
@@ -0,0 +1,100 @@
1
+ //#region src/utils/url-safety.ts
2
+ const ENCODED_ASCII_CONTROL_RE = /%(?:0[0-9a-f]|1[0-9a-f]|7f)/i;
3
+ function hasControlCodePoint(value) {
4
+ for (let i = 0; i < value.length; i++) {
5
+ const code = value.charCodeAt(i);
6
+ if (code <= 31 || code >= 127 && code <= 159) return true;
7
+ }
8
+ return false;
9
+ }
10
+ function hasEncodedControl(value) {
11
+ let current = String(value ?? "");
12
+ for (let depth = 0; depth < 3; depth++) {
13
+ if (ENCODED_ASCII_CONTROL_RE.test(current)) return true;
14
+ let decoded;
15
+ try {
16
+ decoded = decodeURIComponent(current);
17
+ } catch {
18
+ return true;
19
+ }
20
+ if (hasControlCodePoint(decoded)) return true;
21
+ if (decoded === current) return false;
22
+ current = decoded;
23
+ }
24
+ return ENCODED_ASCII_CONTROL_RE.test(current) || hasControlCodePoint(current);
25
+ }
26
+
27
+ //#endregion
28
+ //#region src/core/hyperlink.ts
29
+ const SCHEME_RE = /^[a-z][a-z0-9+.-]*:/i;
30
+ const BLOCKED_SCHEME_RE = /^(?:javascript|data|vbscript):/i;
31
+ const SAFE_RELATIVE_HREF_RE = /^(?:[A-Za-z0-9._~!$&()*+,;=:@/?#-]|%[0-9A-Fa-f]{2})+$/u;
32
+ function normalizeRawHref(value) {
33
+ if (typeof value !== "string") return null;
34
+ const raw = value.trim();
35
+ if (!raw) return null;
36
+ if (raw !== value) return null;
37
+ for (let i = 0; i < value.length; i++) {
38
+ const code = value.charCodeAt(i);
39
+ if (code <= 31 || code >= 127 && code <= 159) return null;
40
+ }
41
+ if (/\s/u.test(raw)) return null;
42
+ if (raw.startsWith("//")) return null;
43
+ if (BLOCKED_SCHEME_RE.test(raw)) return null;
44
+ if (hasEncodedControl(raw)) return null;
45
+ return raw;
46
+ }
47
+ function hrefScheme(raw) {
48
+ return raw.match(SCHEME_RE)?.[0].toLowerCase() ?? null;
49
+ }
50
+ function parseSafeAbsoluteUrl(raw) {
51
+ if (raw.includes("\\")) return null;
52
+ try {
53
+ return new URL(raw);
54
+ } catch {
55
+ return null;
56
+ }
57
+ }
58
+ function sanitizeAbsoluteHref(raw, options = {}) {
59
+ const url = parseSafeAbsoluteUrl(raw);
60
+ if (!url) return null;
61
+ if (url.protocol === "http:" || url.protocol === "https:") {
62
+ if (!/^https?:\/\//i.test(raw)) return null;
63
+ return options.preserveHttpHref ? raw : url.toString();
64
+ }
65
+ if (url.protocol === "mailto:") return raw;
66
+ return null;
67
+ }
68
+ function isSafeNormalizedRelativeHref(raw) {
69
+ if (raw.includes("\\")) return false;
70
+ if (raw.startsWith("//")) return false;
71
+ if (SCHEME_RE.test(raw)) return false;
72
+ if (hasEncodedControl(raw)) return false;
73
+ if (!SAFE_RELATIVE_HREF_RE.test(raw)) return false;
74
+ return raw.startsWith("#") || raw.startsWith("?") || raw.startsWith("/") || raw.startsWith("./") || raw.startsWith("../") || /^[A-Za-z0-9._~-]/u.test(raw);
75
+ }
76
+ function isSafeRelativeHref(value) {
77
+ const raw = normalizeRawHref(value);
78
+ return raw != null && isSafeNormalizedRelativeHref(raw);
79
+ }
80
+ function sanitizeTerminalHref(value, options = {}) {
81
+ const raw = normalizeRawHref(value);
82
+ if (!raw) return null;
83
+ const sanitized = sanitizeAbsoluteHref(raw, { preserveHttpHref: true });
84
+ if (sanitized) return sanitized;
85
+ if (options.allowFileUrls) {
86
+ const url = parseSafeAbsoluteUrl(raw);
87
+ if (url?.protocol === "file:") return url.toString();
88
+ }
89
+ return null;
90
+ }
91
+ function sanitizeDomHref(value, options = {}) {
92
+ const raw = normalizeRawHref(value);
93
+ if (!raw) return null;
94
+ const scheme = hrefScheme(raw);
95
+ if (!scheme) return options.allowRelative !== false && isSafeNormalizedRelativeHref(raw) ? raw : null;
96
+ return sanitizeAbsoluteHref(raw);
97
+ }
98
+
99
+ //#endregion
100
+ export { hasEncodedControl, isSafeRelativeHref, sanitizeDomHref, sanitizeTerminalHref };
package/dist/index.js CHANGED
@@ -1,17 +1,17 @@
1
- import { createTerminal } from "./hyperlink-_1FAj7Wq.js";
2
- import "./width-GqllnV8C.js";
3
- import "./ansi-palette-CH6jc2Z7.js";
4
- import { createDomRenderer } from "./dom-renderer-DXx8fWzD.js";
5
- import "./rect-DUpeDfBg.js";
6
- import { TText, TView, createTheme, linkifyTextSegments, tuiDefaultTheme } from "./linkify-BjI4zVfY.js";
1
+ import { createTerminal } from "./create-terminal-Db_-UGVQ.js";
2
+ import "./ansi-palette-BHF1rN7R.js";
3
+ import "./hyperlink-clbb_ha_.js";
4
+ import { createDomRenderer } from "./dom-renderer-BfwAEQMf.js";
5
+ import "./rect-JzWMJxxc.js";
6
+ import { TText, TView, createTheme, linkifyTextSegments, tuiDefaultTheme } from "./linkify-CL9wwnZN.js";
7
7
  import "./runtime-Byf8XXOT.js";
8
8
  import "./frame-perf-CHpWhbC4.js";
9
9
  import "./trace-Bh8WnoMo.js";
10
10
  import "./env-Cl8qmNFN.js";
11
- import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TRadioGroup, TSlider, TSwitch, TTable, TTag, TTree, TerminalProvider, createTInputHostPlugin } from "./TTree-DdAjCPHu.js";
11
+ import { TAutocompleteInput, TBadge, TCheckbox, TCode, TDataTable, TDivider, TFormField, TLink, TLinkifyText, TList, TPasswordInput, TRadioGroup, TSlider, TSwitch, TTable, TTag, TTree, TerminalProvider, createTInputHostPlugin } from "./TTree-kk8ntrpg.js";
12
12
  import "./terminal-selection-4W1SJj4c.js";
13
13
  import "./debug-logger-CmsGI4of.js";
14
- import { TBox, TCommandPalette, TDialog, TInput, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-Dx34M1pF.js";
14
+ import { TBox, TCommandPalette, TDialog, TInput, TSelect, computeCommandPaletteMatchRanges } from "./TSelect-CMBOOFwK.js";
15
15
  import "./path-mnSgEpCm.js";
16
16
  import "./wheel-scroll-DASkEZr-.js";
17
17
 
@@ -1,5 +1,5 @@
1
- import { sanitizeDomHref } from "./hyperlink-_1FAj7Wq.js";
2
- import { EventZIndexContextKey, LayoutContextKey, RenderStackKey, injectionKey, intersectRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, wrapByCells } from "./rect-DUpeDfBg.js";
1
+ import { sanitizeDomHref } from "./hyperlink-clbb_ha_.js";
2
+ import { EventZIndexContextKey, LayoutContextKey, RenderStackKey, injectionKey, intersectRect, padEndByCells$1 as padEndByCells, sanitizeInlineText, sanitizeTextBlock, sliceByCells, sliceByCellsRange, spaces, textCellWidth$1 as textCellWidth, translateRect, useLayout, useRenderNode, useRenderStack, useTerminal, useTerminalNode, useVisibility, wrapByCells } from "./rect-JzWMJxxc.js";
3
3
  import { computed, defineComponent, h, inject, provide, shallowReactive, watchEffect } from "vue";
4
4
 
5
5
  //#region src/vue/theme.ts
@@ -749,4 +749,4 @@ function linkifyTextSegments(text, options = {}) {
749
749
  }
750
750
 
751
751
  //#endregion
752
- export { TText, TView, TuiThemeContextKey, clamp as clamp$1, createFrameMailbox, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme };
752
+ export { TText, TView, TuiThemeContextKey, clamp, createFrameMailbox, createTheme, defaultActiveStyle, defaultDimStyle, fitCellText, linkifyTextSegments, mergeStyle, repeatToCells, tuiDefaultTheme };