@visulima/string 2.0.3 → 2.0.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 (55) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/dist/align-text.js +32 -2
  3. package/dist/case/camel-case.js +55 -1
  4. package/dist/case/capital-case.js +47 -1
  5. package/dist/case/constant-case.js +7 -1
  6. package/dist/case/dot-case.js +7 -1
  7. package/dist/case/flat-case.js +7 -1
  8. package/dist/case/flip-case.js +76 -1
  9. package/dist/case/identify-case.js +65 -1
  10. package/dist/case/index.js +20 -1
  11. package/dist/case/kebab-case.js +55 -1
  12. package/dist/case/lower-first.js +9 -1
  13. package/dist/case/no-case.js +7 -1
  14. package/dist/case/pascal-case.js +48 -1
  15. package/dist/case/pascal-snake-case.js +28 -1
  16. package/dist/case/path-case.js +7 -1
  17. package/dist/case/sentence-case.js +54 -1
  18. package/dist/case/snake-case.js +7 -1
  19. package/dist/case/split-by-case.js +644 -1
  20. package/dist/case/title-case.js +42 -1
  21. package/dist/case/train-case.js +40 -1
  22. package/dist/case/upper-first.js +9 -1
  23. package/dist/closest-string.js +25 -1
  24. package/dist/compare-similarity.js +12 -1
  25. package/dist/get-string-truncated-width.js +363 -1
  26. package/dist/get-string-width.js +5 -1
  27. package/dist/index.js +36 -1
  28. package/dist/outdent.js +118 -1
  29. package/dist/packem_shared/LRUCache-3r3SovvR.js +46 -0
  30. package/dist/packem_shared/closest-IHuSvnSn.js +139 -0
  31. package/dist/packem_shared/closestN-BREy4E7C.js +19 -0
  32. package/dist/packem_shared/constants-CTzC6Gjg.js +95 -0
  33. package/dist/packem_shared/generate-cache-key-DdayDfjV.js +6 -0
  34. package/dist/packem_shared/joinSegments-CuU8RGpP.js +44 -0
  35. package/dist/packem_shared/normalize-german-eszett-DEB8-ZPT.js +7 -0
  36. package/dist/packem_shared/replaceString-vYvRBMfC.js +190 -0
  37. package/dist/packem_shared/transliterate-CUF6Ggy_.js +47776 -0
  38. package/dist/slice.js +413 -1
  39. package/dist/slugify.js +46 -1
  40. package/dist/test/utils.js +88 -13
  41. package/dist/test/vitest.js +5 -1
  42. package/dist/truncate.js +89 -1
  43. package/dist/utilities.js +54 -1
  44. package/dist/word-similarity-sort.js +22 -1
  45. package/dist/word-wrap.js +637 -8
  46. package/package.json +1 -1
  47. package/dist/packem_shared/LRUCache-Bjo6gsbC.js +0 -1
  48. package/dist/packem_shared/closest-uarbVSbs.js +0 -1
  49. package/dist/packem_shared/closestN-DjNxwK0t.js +0 -1
  50. package/dist/packem_shared/constants-CDcaCZKC.js +0 -1
  51. package/dist/packem_shared/generate-cache-key-DPByFaMH.js +0 -1
  52. package/dist/packem_shared/joinSegments-DTGeJBZG.js +0 -1
  53. package/dist/packem_shared/normalize-german-eszett-4k1qRtEP.js +0 -1
  54. package/dist/packem_shared/replaceString-DwIZyvoL.js +0 -1
  55. package/dist/packem_shared/transliterate-CxVHmZUa.js +0 -5
package/dist/slice.js CHANGED
@@ -1 +1,413 @@
1
- var R=Object.defineProperty;var k=(t,l)=>R(t,"name",{value:l,configurable:!0});import{a as v,b as L,c as O}from"./packem_shared/constants-CDcaCZKC.js";import{getStringWidth as I}from"./get-string-width.js";import N from"./packem_shared/LRUCache-Bjo6gsbC.js";var j=Object.defineProperty,b=k((t,l)=>j(t,"name",{value:l,configurable:!0}),"y");const _=new N(100),F=new Intl.Segmenter("en",{granularity:"grapheme"}),M=new Set(["0","22","23","24","27","28","29","39","49"]),P=new Set(["1","3","4","7","8","9"]),y=new Map([["22","1"],["23","3"],["24","4"],["27","7"],["28","8"],["29","9"]]),S=b(t=>t>="30"&&t<="37"||t>="90"&&t<="97"||t.startsWith("38;"),"isForegroundColor"),w=b(t=>t>="40"&&t<="47"||t>="100"&&t<="107"||t.startsWith("48;"),"isBackgroundColor"),V=[{close:"\x1B[22m",open:"\x1B[1m"},{close:"\x1B[23m",open:"\x1B[3m"},{close:"\x1B[24m",open:"\x1B[4m"},{close:"\x1B[27m",open:"\x1B[7m"},{close:"\x1B[28m",open:"\x1B[8m"},{close:"\x1B[29m",open:"\x1B[9m"}],A=b((t,l)=>{let c=-1;for(const d of l){const h=t.indexOf(d);h!==-1&&(c===-1||h<c)&&(c=h)}return c},"findFirstPositionOfAny"),$=b((t,l)=>{if(!t.includes("\x1B"))return[{after:"",before:"",content:t,visibleLength:I(t,l.width)}];const c=_.get(t);if(c)return c;const d=[],h=[];let g=0,m;for(O.lastIndex=0;(m=O.exec(t))!==null;){const f=m[0];d.push(t.slice(g,m.index)),h.push(f),g=m.index+f.length}g<t.length&&d.push(t.slice(g));const a=[];for(const f of h){if(f==="\x1B[0m"||f==="\x1B]8;;\x07"){a.push(f);continue}if(f.startsWith("\x1B[")&&f.endsWith("m")){const x=f.slice(2,-1);if(M.has(x)){a.push(f);continue}}}const s=new Set,B=[];for(const[f,x]of d.entries()){if(f>0&&h[f-1]){const n=h[f-1];if(n==="\x1B[0m")s.clear();else if(n==="\x1B]8;;\x07"){for(const i of s)if(i.startsWith("\x1B]8;;")&&!i.endsWith("\x1B]8;;\x07")){s.delete(i);break}}else if(n.startsWith("\x1B[")&&n.endsWith("m")){const i=n.slice(2,-1);if(i==="39"){for(const e of s)if(e.startsWith("\x1B[")&&e.endsWith("m")){const o=e.slice(2,-1);if(S(o)){s.delete(e);break}}}else if(i==="49"){for(const e of s)if(e.startsWith("\x1B[")&&e.endsWith("m")){const o=e.slice(2,-1);if(w(o)){s.delete(e);break}}}else if(y.has(i)){const e=y.get(i);for(const o of s)if(o===`\x1B[${e}m`){s.delete(o);break}}else{if(S(i)){for(const e of s)if(e.startsWith("\x1B[")&&e.endsWith("m")){const o=e.slice(2,-1);if(S(o)){s.delete(e);break}}}else if(w(i)){for(const e of s)if(e.startsWith("\x1B[")&&e.endsWith("m")){const o=e.slice(2,-1);if(w(o)){s.delete(e);break}}}else if(P.has(i)){const e=`\x1B[${i}m`;s.has(e)&&s.delete(e)}s.add(n)}}else if(n.startsWith("\x1B]8;;")&&!n.endsWith("\x1B]8;;\x07")){for(const i of s)if(i.startsWith("\x1B]8;;")&&!i.endsWith("\x1B]8;;\x07")){s.delete(i);break}s.add(n)}}if(x==="")continue;let u="";if(s.size>0)if(a.includes("\x1B[0m"))u="\x1B[0m";else{const n=[];let i=!1;for(const r of s)if(r.startsWith("\x1B]8;;")&&!r.endsWith("\x1B]8;;\x07")){i=!0;break}i&&a.includes("\x1B]8;;\x07")&&n.push("\x1B]8;;\x07");let e=!1,o=!1;for(const r of s)if(r.startsWith("\x1B[")&&r.endsWith("m")){const W=r.slice(2,-1);S(W)?e=!0:w(W)&&(o=!0)}if(e&&o){const r=A(t,["\x1B[3","\x1B[9","\x1B[38;"]),W=A(t,["\x1B[4","\x1B[10","\x1B[48;"]);r>=0&&W>=0?r>W?n.push("\x1B[39m","\x1B[49m"):n.push("\x1B[49m","\x1B[39m"):n.push("\x1B[39m","\x1B[49m")}else e&&n.push("\x1B[39m"),o&&n.push("\x1B[49m");e&&o&&t.includes("\x1B[39m")&&t.includes("\x1B[49m")&&(t.indexOf("\x1B[39m")<t.indexOf("\x1B[49m")?(n.length-=e&&o?2:e||o?1:0,n.push("\x1B[39m","\x1B[49m")):t.indexOf("\x1B[49m")<t.indexOf("\x1B[39m")&&(n.length-=e&&o?2:e||o?1:0,n.push("\x1B[49m","\x1B[39m")));const E=V.filter(r=>s.has(r.open)).map(r=>({position:t.indexOf(r.open),style:r})).filter(r=>r.position>=0).sort((r,W)=>W.position-r.position);for(const r of E)a.includes(r.style.close)&&n.push(r.style.close);u=n.join("")}const p=[...s].join("");B.push({after:u,before:p,content:x,visibleLength:I(x,{fullWidth:1,wideWidth:1})})}return _.set(t,B),B},"processIntoStyledSegments"),C=b((t,l,c,d)=>{const h=[...d.segmenter.segment(t)],g=[];let m=0,a=!1;for(const s of h){const B=I(s.segment,d.width),f=m,x=m+B;if(!a)if(f<l){m=x;continue}else a=!0;if(f>=c||x>c)break;g.push(s.segment),m=x}return g.join("")},"fastSlice"),H=b((t,l=0,c=Number.MAX_SAFE_INTEGER,d={})=>{const h={segmenter:F,...d};if(l>=c||t==="")return"";const g=I(t,h.width);if(l===0&&c>=g)return t;if(l<0||c<0)throw new RangeError("Negative indices aren't supported");if(!t.includes("\x1B"))return/^[\u0000-\u007F]*$/.test(t)?t.slice(l,c):C(t,l,c,h);if(v.lastIndex=0,L.lastIndex=0,!v.test(t)&&!L.test(t))return t;const m=$(t,h);if(m.length===0)return"";let a=0;const s=[];for(const[x,u]of m.entries()){const p=a,n=a+u.visibleLength;if(n>l&&p<c){const i=Math.max(0,l-p),e=Math.min(u.visibleLength,c-p);s.push({end:e,index:x,segment:u,start:i})}a=n}if(s.length===0)return"";const B=[],f=s[0].segment;B.push(f.before);for(let x=0;x<s.length;x++){const{end:u,segment:p,start:n}=s[x];if(n===0&&u===p.visibleLength)B.push(p.content);else{const i=[...h.segmenter.segment(p.content)];B.push(i.slice(n,u).map(e=>e.segment).join(""))}if(x<s.length-1){const i=s[x+1].segment,e=p.after,o=i.before;e!==o&&(e||o)&&B.push(e,o)}}return B.push(s.at(-1).segment.after),B.join("")},"slice");export{H as slice};
1
+ import { a as RE_VALID_ANSI_PAIRS, b as RE_VALID_HYPERLINKS, c as RE_ANSI } from './packem_shared/constants-CTzC6Gjg.js';
2
+ import { getStringWidth } from './get-string-width.js';
3
+ import LRUCache from './packem_shared/LRUCache-3r3SovvR.js';
4
+
5
+ const segmentCache = new LRUCache(100);
6
+ const defaultSegmenter = new Intl.Segmenter("en", { granularity: "grapheme" });
7
+ const ANSI_RESET_CODES = /* @__PURE__ */ new Set([
8
+ "0",
9
+ // Full reset
10
+ "22",
11
+ // Bold reset
12
+ "23",
13
+ // Italic reset
14
+ "24",
15
+ // Underline reset
16
+ "27",
17
+ // Inverse reset
18
+ "28",
19
+ // Hidden reset
20
+ "29",
21
+ // Strikethrough reset
22
+ "39",
23
+ // Foreground color reset
24
+ "49"
25
+ // Background color reset
26
+ ]);
27
+ const STYLE_CODES = /* @__PURE__ */ new Set([
28
+ "1",
29
+ // Bold
30
+ "3",
31
+ // Italic
32
+ "4",
33
+ // Underline
34
+ "7",
35
+ // Inverse
36
+ "8",
37
+ // Hidden
38
+ "9"
39
+ // Strikethrough
40
+ ]);
41
+ const FORMAT_RESET_CODES = /* @__PURE__ */ new Map([
42
+ ["22", "1"],
43
+ // Bold reset
44
+ ["23", "3"],
45
+ // Italic reset
46
+ ["24", "4"],
47
+ // Underline reset
48
+ ["27", "7"],
49
+ // Inverse reset
50
+ ["28", "8"],
51
+ // Hidden reset
52
+ ["29", "9"]
53
+ // Strikethrough reset
54
+ ]);
55
+ const isForegroundColor = (code) => code >= "30" && code <= "37" || code >= "90" && code <= "97" || code.startsWith("38;");
56
+ const isBackgroundColor = (code) => code >= "40" && code <= "47" || code >= "100" && code <= "107" || code.startsWith("48;");
57
+ const FORMAT_STYLES = [
58
+ { close: "\x1B[22m", open: "\x1B[1m" },
59
+ // Bold
60
+ { close: "\x1B[23m", open: "\x1B[3m" },
61
+ // Italic
62
+ { close: "\x1B[24m", open: "\x1B[4m" },
63
+ // Underline
64
+ { close: "\x1B[27m", open: "\x1B[7m" },
65
+ // Inverse
66
+ { close: "\x1B[28m", open: "\x1B[8m" },
67
+ // Hidden
68
+ { close: "\x1B[29m", open: "\x1B[9m" }
69
+ // Strikethrough
70
+ ];
71
+ const findFirstPositionOfAny = (input, substrings) => {
72
+ let firstPos = -1;
73
+ for (const substring of substrings) {
74
+ const pos = input.indexOf(substring);
75
+ if (pos !== -1 && (firstPos === -1 || pos < firstPos)) {
76
+ firstPos = pos;
77
+ }
78
+ }
79
+ return firstPos;
80
+ };
81
+ const processIntoStyledSegments = (input, options) => {
82
+ if (!input.includes("\x1B")) {
83
+ return [
84
+ {
85
+ after: "",
86
+ before: "",
87
+ content: input,
88
+ visibleLength: getStringWidth(input, options.width)
89
+ }
90
+ ];
91
+ }
92
+ const cachedResult = segmentCache.get(input);
93
+ if (cachedResult) {
94
+ return cachedResult;
95
+ }
96
+ const parts = [];
97
+ const matches = [];
98
+ let lastIndex = 0;
99
+ let match;
100
+ RE_ANSI.lastIndex = 0;
101
+ while ((match = RE_ANSI.exec(input)) !== null) {
102
+ const matchedText = match[0];
103
+ parts.push(input.slice(lastIndex, match.index));
104
+ matches.push(matchedText);
105
+ lastIndex = match.index + matchedText.length;
106
+ }
107
+ if (lastIndex < input.length) {
108
+ parts.push(input.slice(lastIndex));
109
+ }
110
+ const closingSequences = [];
111
+ for (const ansi of matches) {
112
+ if (ansi === "\x1B[0m" || ansi === "\x1B]8;;\x07") {
113
+ closingSequences.push(ansi);
114
+ continue;
115
+ }
116
+ if (ansi.startsWith("\x1B[") && ansi.endsWith("m")) {
117
+ const code = ansi.slice(2, -1);
118
+ if (ANSI_RESET_CODES.has(code)) {
119
+ closingSequences.push(ansi);
120
+ continue;
121
+ }
122
+ }
123
+ }
124
+ const activeStylesSet = /* @__PURE__ */ new Set();
125
+ const segments = [];
126
+ for (const [index, text] of parts.entries()) {
127
+ if (index > 0 && matches[index - 1]) {
128
+ const ansi = matches[index - 1];
129
+ if (ansi === "\x1B[0m") {
130
+ activeStylesSet.clear();
131
+ } else if (ansi === "\x1B]8;;\x07") {
132
+ for (const style of activeStylesSet) {
133
+ if (style.startsWith("\x1B]8;;") && !style.endsWith("\x1B]8;;\x07")) {
134
+ activeStylesSet.delete(style);
135
+ break;
136
+ }
137
+ }
138
+ } else if (ansi.startsWith("\x1B[") && ansi.endsWith("m")) {
139
+ const code = ansi.slice(2, -1);
140
+ if (code === "39") {
141
+ for (const style of activeStylesSet) {
142
+ if (style.startsWith("\x1B[") && style.endsWith("m")) {
143
+ const styleCode = style.slice(2, -1);
144
+ if (isForegroundColor(styleCode)) {
145
+ activeStylesSet.delete(style);
146
+ break;
147
+ }
148
+ }
149
+ }
150
+ } else if (code === "49") {
151
+ for (const style of activeStylesSet) {
152
+ if (style.startsWith("\x1B[") && style.endsWith("m")) {
153
+ const styleCode = style.slice(2, -1);
154
+ if (isBackgroundColor(styleCode)) {
155
+ activeStylesSet.delete(style);
156
+ break;
157
+ }
158
+ }
159
+ }
160
+ } else if (FORMAT_RESET_CODES.has(code)) {
161
+ const targetCode = FORMAT_RESET_CODES.get(code);
162
+ for (const style of activeStylesSet) {
163
+ if (style === `\x1B[${targetCode}m`) {
164
+ activeStylesSet.delete(style);
165
+ break;
166
+ }
167
+ }
168
+ } else {
169
+ if (isForegroundColor(code)) {
170
+ for (const style of activeStylesSet) {
171
+ if (style.startsWith("\x1B[") && style.endsWith("m")) {
172
+ const styleCode = style.slice(2, -1);
173
+ if (isForegroundColor(styleCode)) {
174
+ activeStylesSet.delete(style);
175
+ break;
176
+ }
177
+ }
178
+ }
179
+ } else if (isBackgroundColor(code)) {
180
+ for (const style of activeStylesSet) {
181
+ if (style.startsWith("\x1B[") && style.endsWith("m")) {
182
+ const styleCode = style.slice(2, -1);
183
+ if (isBackgroundColor(styleCode)) {
184
+ activeStylesSet.delete(style);
185
+ break;
186
+ }
187
+ }
188
+ }
189
+ } else if (STYLE_CODES.has(code)) {
190
+ const targetStyle = `\x1B[${code}m`;
191
+ if (activeStylesSet.has(targetStyle)) {
192
+ activeStylesSet.delete(targetStyle);
193
+ }
194
+ }
195
+ activeStylesSet.add(ansi);
196
+ }
197
+ } else if (ansi.startsWith("\x1B]8;;") && !ansi.endsWith("\x1B]8;;\x07")) {
198
+ for (const style of activeStylesSet) {
199
+ if (style.startsWith("\x1B]8;;") && !style.endsWith("\x1B]8;;\x07")) {
200
+ activeStylesSet.delete(style);
201
+ break;
202
+ }
203
+ }
204
+ activeStylesSet.add(ansi);
205
+ }
206
+ }
207
+ if (text === "") {
208
+ continue;
209
+ }
210
+ let closingSequence = "";
211
+ if (activeStylesSet.size > 0) {
212
+ if (closingSequences.includes("\x1B[0m")) {
213
+ closingSequence = "\x1B[0m";
214
+ } else {
215
+ const closingParts = [];
216
+ let needsHyperlinkClose = false;
217
+ for (const style of activeStylesSet) {
218
+ if (style.startsWith("\x1B]8;;") && !style.endsWith("\x1B]8;;\x07")) {
219
+ needsHyperlinkClose = true;
220
+ break;
221
+ }
222
+ }
223
+ if (needsHyperlinkClose && closingSequences.includes("\x1B]8;;\x07")) {
224
+ closingParts.push("\x1B]8;;\x07");
225
+ }
226
+ let needsForegroundClose = false;
227
+ let needsBackgroundClose = false;
228
+ for (const style of activeStylesSet) {
229
+ if (style.startsWith("\x1B[") && style.endsWith("m")) {
230
+ const styleCode = style.slice(2, -1);
231
+ if (isForegroundColor(styleCode)) {
232
+ needsForegroundClose = true;
233
+ } else if (isBackgroundColor(styleCode)) {
234
+ needsBackgroundClose = true;
235
+ }
236
+ }
237
+ }
238
+ if (needsForegroundClose && needsBackgroundClose) {
239
+ const fgOpenPos = findFirstPositionOfAny(input, [
240
+ "\x1B[3",
241
+ // Basic colors 30-37
242
+ "\x1B[9",
243
+ // Bright colors 90-97
244
+ "\x1B[38;"
245
+ // RGB/256 colors
246
+ ]);
247
+ const bgOpenPos = findFirstPositionOfAny(input, [
248
+ "\x1B[4",
249
+ // Basic colors 40-47
250
+ "\x1B[10",
251
+ // Bright colors 100-107
252
+ "\x1B[48;"
253
+ // RGB/256 colors
254
+ ]);
255
+ if (fgOpenPos >= 0 && bgOpenPos >= 0) {
256
+ if (fgOpenPos > bgOpenPos) {
257
+ closingParts.push("\x1B[39m", "\x1B[49m");
258
+ } else {
259
+ closingParts.push("\x1B[49m", "\x1B[39m");
260
+ }
261
+ } else {
262
+ closingParts.push("\x1B[39m", "\x1B[49m");
263
+ }
264
+ } else {
265
+ if (needsForegroundClose) {
266
+ closingParts.push("\x1B[39m");
267
+ }
268
+ if (needsBackgroundClose) {
269
+ closingParts.push("\x1B[49m");
270
+ }
271
+ }
272
+ if (needsForegroundClose && needsBackgroundClose && input.includes("\x1B[39m") && input.includes("\x1B[49m")) {
273
+ if (input.indexOf("\x1B[39m") < input.indexOf("\x1B[49m")) {
274
+ closingParts.length -= needsForegroundClose && needsBackgroundClose ? 2 : needsForegroundClose || needsBackgroundClose ? 1 : 0;
275
+ closingParts.push("\x1B[39m", "\x1B[49m");
276
+ } else if (input.indexOf("\x1B[49m") < input.indexOf("\x1B[39m")) {
277
+ closingParts.length -= needsForegroundClose && needsBackgroundClose ? 2 : needsForegroundClose || needsBackgroundClose ? 1 : 0;
278
+ closingParts.push("\x1B[49m", "\x1B[39m");
279
+ }
280
+ }
281
+ const activeFormatStyles = FORMAT_STYLES.filter((style) => activeStylesSet.has(style.open)).map((style) => {
282
+ return {
283
+ position: input.indexOf(style.open),
284
+ style
285
+ };
286
+ }).filter((item) => item.position >= 0).sort((a, b) => b.position - a.position);
287
+ for (const item of activeFormatStyles) {
288
+ if (closingSequences.includes(item.style.close)) {
289
+ closingParts.push(item.style.close);
290
+ }
291
+ }
292
+ closingSequence = closingParts.join("");
293
+ }
294
+ }
295
+ const activeStylesString = [...activeStylesSet].join("");
296
+ segments.push({
297
+ after: closingSequence,
298
+ before: activeStylesString,
299
+ content: text,
300
+ visibleLength: getStringWidth(text, {
301
+ fullWidth: 1,
302
+ wideWidth: 1
303
+ })
304
+ });
305
+ }
306
+ segmentCache.set(input, segments);
307
+ return segments;
308
+ };
309
+ const fastSlice = (inputString, startIndex, endIndex, options) => {
310
+ const graphemes = [...options.segmenter.segment(inputString)];
311
+ const result = [];
312
+ let currentWidth = 0;
313
+ let startFound = false;
314
+ for (const grapheme of graphemes) {
315
+ const graphemeWidth = getStringWidth(grapheme.segment, options.width);
316
+ const positionBefore = currentWidth;
317
+ const positionAfter = currentWidth + graphemeWidth;
318
+ if (!startFound) {
319
+ if (positionBefore < startIndex) {
320
+ currentWidth = positionAfter;
321
+ continue;
322
+ } else {
323
+ startFound = true;
324
+ }
325
+ }
326
+ if (positionBefore >= endIndex) {
327
+ break;
328
+ }
329
+ if (positionAfter > endIndex) {
330
+ break;
331
+ }
332
+ result.push(grapheme.segment);
333
+ currentWidth = positionAfter;
334
+ }
335
+ return result.join("");
336
+ };
337
+ const slice = (inputString, startIndex = 0, endIndex = Number.MAX_SAFE_INTEGER, options = {}) => {
338
+ const config = {
339
+ segmenter: defaultSegmenter,
340
+ ...options
341
+ };
342
+ if (startIndex >= endIndex || inputString === "") {
343
+ return "";
344
+ }
345
+ const inputStringWidth = getStringWidth(inputString, config.width);
346
+ if (startIndex === 0 && endIndex >= inputStringWidth) {
347
+ return inputString;
348
+ }
349
+ if (startIndex < 0 || endIndex < 0) {
350
+ throw new RangeError("Negative indices aren't supported");
351
+ }
352
+ if (!inputString.includes("\x1B")) {
353
+ if (/^[\u0000-\u007F]*$/.test(inputString)) {
354
+ return inputString.slice(startIndex, endIndex);
355
+ }
356
+ return fastSlice(inputString, startIndex, endIndex, config);
357
+ }
358
+ RE_VALID_ANSI_PAIRS.lastIndex = 0;
359
+ RE_VALID_HYPERLINKS.lastIndex = 0;
360
+ if (!RE_VALID_ANSI_PAIRS.test(inputString) && !RE_VALID_HYPERLINKS.test(inputString)) {
361
+ return inputString;
362
+ }
363
+ const segments = processIntoStyledSegments(inputString, config);
364
+ if (segments.length === 0) {
365
+ return "";
366
+ }
367
+ let currentPos = 0;
368
+ const visibleSegments = [];
369
+ for (const [index, segment] of segments.entries()) {
370
+ const segmentStart = currentPos;
371
+ const segmentEnd = currentPos + segment.visibleLength;
372
+ if (segmentEnd > startIndex && segmentStart < endIndex) {
373
+ const visibleStart = Math.max(0, startIndex - segmentStart);
374
+ const visibleEnd = Math.min(segment.visibleLength, endIndex - segmentStart);
375
+ visibleSegments.push({
376
+ end: visibleEnd,
377
+ index,
378
+ segment,
379
+ start: visibleStart
380
+ });
381
+ }
382
+ currentPos = segmentEnd;
383
+ }
384
+ if (visibleSegments.length === 0) {
385
+ return "";
386
+ }
387
+ const resultParts = [];
388
+ const firstSegment = visibleSegments[0].segment;
389
+ resultParts.push(firstSegment.before);
390
+ for (let index = 0; index < visibleSegments.length; index++) {
391
+ const { end, segment, start } = visibleSegments[index];
392
+ if (start === 0 && end === segment.visibleLength) {
393
+ resultParts.push(segment.content);
394
+ } else {
395
+ const graphemes = [...config.segmenter.segment(segment.content)];
396
+ resultParts.push(
397
+ graphemes.slice(start, end).map((entry) => entry.segment).join("")
398
+ );
399
+ }
400
+ if (index < visibleSegments.length - 1) {
401
+ const nextSegment = visibleSegments[index + 1].segment;
402
+ const segmentAfter = segment.after;
403
+ const nextBefore = nextSegment.before;
404
+ if (segmentAfter !== nextBefore && (segmentAfter || nextBefore)) {
405
+ resultParts.push(segmentAfter, nextBefore);
406
+ }
407
+ }
408
+ }
409
+ resultParts.push(visibleSegments.at(-1).segment.after);
410
+ return resultParts.join("");
411
+ };
412
+
413
+ export { slice };
package/dist/slugify.js CHANGED
@@ -1 +1,46 @@
1
- var c=Object.defineProperty;var s=(a,o)=>c(a,"name",{value:o,configurable:!0});import i from"./packem_shared/transliterate-CxVHmZUa.js";import{escapeRegExp as t}from"./utilities.js";var u=Object.defineProperty,p=s((a,o)=>u(a,"name",{value:o,configurable:!0}),"o");const f=p((a,o,e)=>{const r=t(o).replaceAll(String.raw`\-`,"-"),l=new RegExp(`[^${r}]`,"g");return a.replaceAll(l,e)},"removeDisallowedChars"),C=p((a,o)=>{const e={allowedChars:"a-zA-Z0-9-_.~",fixChineseSpacing:!0,ignore:[],lowercase:!0,replaceAfter:[],replaceBefore:[],separator:"-",transliterate:!0,trim:!1,unknown:"",uppercase:!1,...o};e.lowercase&&e.uppercase&&(console.warn("slugify: Both lowercase and uppercase options are true. Defaulting to lowercase."),e.uppercase=!1);let r=e.transliterate?i(a,e):a.normalize("NFC");e.lowercase?r=r.toLowerCase():e.uppercase&&(r=r.toUpperCase()),r=f(r,e.allowedChars,e.separator);const l=t(e.separator);if(l){const n=new RegExp(`${l}+`,"g");r=r.replace(n,e.separator)}return l?r.replaceAll(new RegExp(`^${l}+|${l}+$`,"g"),""):r},"slugify");export{C as default};
1
+ import transliterate from './packem_shared/transliterate-CUF6Ggy_.js';
2
+ import { escapeRegExp } from './utilities.js';
3
+
4
+ const removeDisallowedChars = (input, allowedChars, separator) => {
5
+ const escapedChars = escapeRegExp(allowedChars).replaceAll(String.raw`\-`, "-");
6
+ const pattern = new RegExp(`[^${escapedChars}]`, "g");
7
+ return input.replaceAll(pattern, separator);
8
+ };
9
+ const slugify = (input, options) => {
10
+ const config = {
11
+ allowedChars: "a-zA-Z0-9-_.~",
12
+ fixChineseSpacing: true,
13
+ ignore: [],
14
+ lowercase: true,
15
+ replaceAfter: [],
16
+ replaceBefore: [],
17
+ separator: "-",
18
+ transliterate: true,
19
+ trim: false,
20
+ unknown: "",
21
+ uppercase: false,
22
+ ...options
23
+ };
24
+ if (config.lowercase && config.uppercase) {
25
+ console.warn("slugify: Both lowercase and uppercase options are true. Defaulting to lowercase.");
26
+ config.uppercase = false;
27
+ }
28
+ let slug = config.transliterate ? transliterate(input, config) : input.normalize("NFC");
29
+ if (config.lowercase) {
30
+ slug = slug.toLowerCase();
31
+ } else if (config.uppercase) {
32
+ slug = slug.toUpperCase();
33
+ }
34
+ slug = removeDisallowedChars(slug, config.allowedChars, config.separator);
35
+ const escapedSeparator = escapeRegExp(config.separator);
36
+ if (escapedSeparator) {
37
+ const separatorRegex = new RegExp(`${escapedSeparator}+`, "g");
38
+ slug = slug.replace(separatorRegex, config.separator);
39
+ }
40
+ if (escapedSeparator) {
41
+ return slug.replaceAll(new RegExp(`^${escapedSeparator}+|${escapedSeparator}+$`, "g"), "");
42
+ }
43
+ return slug;
44
+ };
45
+
46
+ export { slugify as default };
@@ -1,16 +1,91 @@
1
- var d=Object.defineProperty;var a=(e,t)=>d(e,"name",{value:t,configurable:!0});import{createRequire as g}from"node:module";import{getStringWidth as l}from"../get-string-width.js";const u=g(import.meta.url),n=typeof globalThis<"u"&&typeof globalThis.process<"u"?globalThis.process:process,f=a(e=>{if(typeof n<"u"&&n.versions&&n.versions.node){const[t,s]=n.versions.node.split(".").map(Number);if(t>22||t===22&&s>=3||t===20&&s>=16)return n.getBuiltinModule(e)}return u(e)},"__cjs_getBuiltinModule"),{stripVTControlCharacters:h,format:m}=f("node:util");var S=Object.defineProperty,o=a((e,t)=>S(e,"name",{value:t,configurable:!0}),"r");const p=o(e=>{const t=h(e);return{ansi:e,json:JSON.stringify(e),lengthDifference:e.length-t.length,stripped:t,visible:e.replaceAll("\x1B",String.raw`\u001B`)}},"formatAnsiString"),j=o((e,t)=>{const s=p(e),i=p(t);return{message:o(()=>{if(e===t)return"ANSI strings are identical";const r=s.stripped===i.stripped;return m(`ANSI string comparison failed:
1
+ import { createRequire as __cjs_createRequire } from "node:module";
2
2
 
3
- Actual:
4
- - Visible content: %s
5
- - With escape codes: %s
6
- - JSON: %s
7
- - Length: %d
3
+ const __cjs_require = __cjs_createRequire(import.meta.url);
8
4
 
9
- Expected:
10
- - Visible content: %s
11
- - With escape codes: %s
12
- - JSON: %s
13
- - Length: %d
5
+ const __cjs_getProcess = typeof globalThis !== "undefined" && typeof globalThis.process !== "undefined" ? globalThis.process : process;
14
6
 
15
- %s
16
- `,s.stripped,s.visible,s.json,l(s.ansi),i.stripped,i.visible,i.json,l(i.ansi),r?"✓ Visible content is identical, but escape codes differ":"✗ Visible content differs")},"message"),pass:e===t}},"expectAnsiStrings"),v=o((e,t)=>{const s=p(e),i=p(t),r=s.stripped===i.stripped,c=e===t;return{actual:s,ansiEqual:c,expected:i,strippedEqual:r,summary:{actualLength:e.length,actualStrippedLength:s.stripped.length,ansiEqual:c,expectedLength:t.length,expectedStrippedLength:i.stripped.length,strippedEqual:r}}},"compareAnsiStrings");export{v as compareAnsiStrings,j as expectAnsiStrings,p as formatAnsiString};
7
+ const __cjs_getBuiltinModule = (module) => {
8
+ // Check if we're in Node.js and version supports getBuiltinModule
9
+ if (typeof __cjs_getProcess !== "undefined" && __cjs_getProcess.versions && __cjs_getProcess.versions.node) {
10
+ const [major, minor] = __cjs_getProcess.versions.node.split(".").map(Number);
11
+ // Node.js 20.16.0+ and 22.3.0+
12
+ if (major > 22 || (major === 22 && minor >= 3) || (major === 20 && minor >= 16)) {
13
+ return __cjs_getProcess.getBuiltinModule(module);
14
+ }
15
+ }
16
+ // Fallback to createRequire
17
+ return __cjs_require(module);
18
+ };
19
+
20
+ const {
21
+ stripVTControlCharacters,
22
+ format
23
+ } = __cjs_getBuiltinModule("node:util");
24
+ import { getStringWidth } from '../get-string-width.js';
25
+
26
+ const formatAnsiString = (ansiString) => {
27
+ const stripped = stripVTControlCharacters(ansiString);
28
+ return {
29
+ // Original ANSI string
30
+ ansi: ansiString,
31
+ // JSON stringified version to see all escape codes
32
+ json: JSON.stringify(ansiString),
33
+ // Length difference between ANSI and stripped string
34
+ lengthDifference: ansiString.length - stripped.length,
35
+ // String with ANSI codes stripped
36
+ stripped,
37
+ // String with ANSI escape codes shown as visible characters
38
+ visible: ansiString.replaceAll("\x1B", String.raw`\u001B`)
39
+ };
40
+ };
41
+ const expectAnsiStrings = (actual, expected) => {
42
+ const actualFormatted = formatAnsiString(actual);
43
+ const expectedFormatted = formatAnsiString(expected);
44
+ return {
45
+ message: () => {
46
+ if (actual === expected) {
47
+ return "ANSI strings are identical";
48
+ }
49
+ const strippedEqual = actualFormatted.stripped === expectedFormatted.stripped;
50
+ return format(
51
+ "ANSI string comparison failed:\n\nActual:\n - Visible content: %s\n - With escape codes: %s\n - JSON: %s\n - Length: %d\n\nExpected:\n - Visible content: %s\n - With escape codes: %s\n - JSON: %s\n - Length: %d\n\n%s\n",
52
+ actualFormatted.stripped,
53
+ actualFormatted.visible,
54
+ actualFormatted.json,
55
+ getStringWidth(actualFormatted.ansi),
56
+ expectedFormatted.stripped,
57
+ expectedFormatted.visible,
58
+ expectedFormatted.json,
59
+ getStringWidth(expectedFormatted.ansi),
60
+ strippedEqual ? "✓ Visible content is identical, but escape codes differ" : "✗ Visible content differs"
61
+ );
62
+ },
63
+ pass: actual === expected
64
+ };
65
+ };
66
+ const compareAnsiStrings = (actual, expected) => {
67
+ const actualFormatted = formatAnsiString(actual);
68
+ const expectedFormatted = formatAnsiString(expected);
69
+ const strippedEqual = actualFormatted.stripped === expectedFormatted.stripped;
70
+ const ansiEqual = actual === expected;
71
+ return {
72
+ // Format information for both strings
73
+ actual: actualFormatted,
74
+ // Are the strings identical including ANSI codes?
75
+ ansiEqual,
76
+ expected: expectedFormatted,
77
+ // Are the strings identical when ANSI codes are stripped?
78
+ strippedEqual,
79
+ // Summary information
80
+ summary: {
81
+ actualLength: actual.length,
82
+ actualStrippedLength: actualFormatted.stripped.length,
83
+ ansiEqual,
84
+ expectedLength: expected.length,
85
+ expectedStrippedLength: expectedFormatted.stripped.length,
86
+ strippedEqual
87
+ }
88
+ };
89
+ };
90
+
91
+ export { compareAnsiStrings, expectAnsiStrings, formatAnsiString };
@@ -1 +1,5 @@
1
- var i=Object.defineProperty;var t=(e,r)=>i(e,"name",{value:r,configurable:!0});import{expectAnsiStrings as n}from"./utils.js";var o=Object.defineProperty,a=t((e,r)=>o(e,"name",{value:r,configurable:!0}),"i");const c=a((e,r)=>n(e,r),"toEqualAnsi");export{c as toEqualAnsi};
1
+ import { expectAnsiStrings } from './utils.js';
2
+
3
+ const toEqualAnsi = (actual, expected) => expectAnsiStrings(actual, expected);
4
+
5
+ export { toEqualAnsi };
package/dist/truncate.js CHANGED
@@ -1 +1,89 @@
1
- var g=Object.defineProperty;var l=(t,i)=>g(t,"name",{value:i,configurable:!0});import{getStringTruncatedWidth as p}from"./get-string-truncated-width.js";import{slice as d}from"./slice.js";var b=Object.defineProperty,f=l((t,i)=>b(t,"name",{value:i,configurable:!0}),"h");const u="…",y=3,h=f((t,i,e=!1)=>{if(t.charAt(i)===" ")return i;const r=e?1:-1,c=Math.min(y,e?t.length-i:i);for(let a=1;a<=c;a++){const n=i+a*r;if(t.charAt(n)===" ")return n}return i},"findNearestSpace"),T=f((t,i,e={})=>{if(typeof t!="string")throw new TypeError(`Expected \`input\` to be a string, got ${typeof t}`);if(typeof i!="number")throw new TypeError(`Expected \`limit\` to be a number, got ${typeof i}`);if(t===""||i<=0)return"";t=t.normalize("NFC");const{ellipsis:r=u,position:c="end",preferTruncationOnSpace:a=!1}=e;let n=e.ellipsisWidth??r===u?1:void 0;n===void 0&&(n=p(r,{...e.width,ellipsis:"",ellipsisWidth:0,limit:Number.POSITIVE_INFINITY}).width);const{width:o}=p(t,{...e.width,ellipsis:r,ellipsisWidth:n});if(o<=i)return t;switch(c){case"end":{if(a){const s=h(t,i-1);return d(t,0,s,{width:e.width})+r}return d(t,0,i-n,{width:e.width})+r}case"middle":{const s=Math.floor(i/2);if(a){const w=h(t,s),m=h(t,o-(i-s)+1,!0);return d(t,0,w)+r+d(t,m,o).trim()}return d(t,0,s,{width:e.width})+r+d(t,o-(i-s)+n,o,{width:e.width})}case"start":{if(a){const s=h(t,o-i+1,!0);return r+d(t,s,o).trim()}return r+d(t,o-i+n,o,{width:e.width})}default:throw new Error(`Invalid position: expected 'start', 'middle' or 'end', got '${c}'`)}},"truncate");export{T as truncate};
1
+ import { getStringTruncatedWidth } from './get-string-truncated-width.js';
2
+ import { slice } from './slice.js';
3
+
4
+ const DEFAULT_ELLIPSIS = "…";
5
+ const MAX_SPACE_SEARCH_DISTANCE = 3;
6
+ const findNearestSpace = (string_, startIndex, searchRight = false) => {
7
+ if (string_.charAt(startIndex) === " ") {
8
+ return startIndex;
9
+ }
10
+ const direction = searchRight ? 1 : -1;
11
+ const limit = Math.min(MAX_SPACE_SEARCH_DISTANCE, searchRight ? string_.length - startIndex : startIndex);
12
+ for (let offset = 1; offset <= limit; offset++) {
13
+ const index = startIndex + offset * direction;
14
+ if (string_.charAt(index) === " ") {
15
+ return index;
16
+ }
17
+ }
18
+ return startIndex;
19
+ };
20
+ const truncate = (input, limit, options = {}) => {
21
+ if (typeof input !== "string") {
22
+ throw new TypeError(`Expected \`input\` to be a string, got ${typeof input}`);
23
+ }
24
+ if (typeof limit !== "number") {
25
+ throw new TypeError(`Expected \`limit\` to be a number, got ${typeof limit}`);
26
+ }
27
+ if (input === "" || limit <= 0) {
28
+ return "";
29
+ }
30
+ input = input.normalize("NFC");
31
+ const { ellipsis = DEFAULT_ELLIPSIS, position = "end", preferTruncationOnSpace = false } = options;
32
+ let ellipsisWidth = options.ellipsisWidth ?? ellipsis === DEFAULT_ELLIPSIS ? 1 : void 0;
33
+ if (ellipsisWidth === void 0) {
34
+ ellipsisWidth = getStringTruncatedWidth(ellipsis, {
35
+ ...options.width,
36
+ ellipsis: "",
37
+ ellipsisWidth: 0,
38
+ limit: Number.POSITIVE_INFINITY
39
+ }).width;
40
+ }
41
+ const { width } = getStringTruncatedWidth(input, {
42
+ ...options.width,
43
+ ellipsis,
44
+ ellipsisWidth
45
+ });
46
+ if (width <= limit) {
47
+ return input;
48
+ }
49
+ switch (position) {
50
+ case "end": {
51
+ if (preferTruncationOnSpace) {
52
+ const nearestSpace = findNearestSpace(input, limit - 1);
53
+ return slice(input, 0, nearestSpace, {
54
+ width: options.width
55
+ }) + ellipsis;
56
+ }
57
+ return slice(input, 0, limit - ellipsisWidth, {
58
+ width: options.width
59
+ }) + ellipsis;
60
+ }
61
+ case "middle": {
62
+ const half = Math.floor(limit / 2);
63
+ if (preferTruncationOnSpace) {
64
+ const firstBreak = findNearestSpace(input, half);
65
+ const secondBreak = findNearestSpace(input, width - (limit - half) + 1, true);
66
+ return slice(input, 0, firstBreak) + ellipsis + slice(input, secondBreak, width).trim();
67
+ }
68
+ return slice(input, 0, half, {
69
+ width: options.width
70
+ }) + ellipsis + slice(input, width - (limit - half) + ellipsisWidth, width, {
71
+ width: options.width
72
+ });
73
+ }
74
+ case "start": {
75
+ if (preferTruncationOnSpace) {
76
+ const nearestSpace = findNearestSpace(input, width - limit + 1, true);
77
+ return ellipsis + slice(input, nearestSpace, width).trim();
78
+ }
79
+ return ellipsis + slice(input, width - limit + ellipsisWidth, width, {
80
+ width: options.width
81
+ });
82
+ }
83
+ default: {
84
+ throw new Error(`Invalid position: expected 'start', 'middle' or 'end', got '${position}'`);
85
+ }
86
+ }
87
+ };
88
+
89
+ export { truncate };