(s: any)
| 192 | * (e.g. `{...}\n[use offset=120 to see more]`), so strict JSON.parse fails. |
| 193 | * Extract the leading {...}/[...] by brace-matching, keep the rest as a note. */ |
| 194 | export function parseLeadingJSON(s: any): { value: any; rest: string } | null { |
| 195 | if (typeof s !== "string") return null; |
| 196 | let i = 0; |
| 197 | while (i < s.length && /\s/.test(s[i])) i++; |
| 198 | const open = s[i]; |
| 199 | if (open !== "{" && open !== "[") { |
| 200 | try { return { value: JSON.parse(s), rest: "" }; } catch (e) { return null; } |
| 201 | } |
| 202 | const close = open === "{" ? "}" : "]"; |
| 203 | let depth = 0, inStr = false, esc = false, end = -1; |
| 204 | for (let j = i; j < s.length; j++) { |
| 205 | const ch = s[j]; |
| 206 | if (inStr) { |
| 207 | if (esc) esc = false; |
| 208 | else if (ch === "\\") esc = true; |
| 209 | else if (ch === '"') inStr = false; |
| 210 | continue; |
| 211 | } |
| 212 | if (ch === '"') inStr = true; |
| 213 | else if (ch === open) depth++; |
| 214 | else if (ch === close) { depth--; if (depth === 0) { end = j + 1; break; } } |
| 215 | } |
| 216 | if (end === -1) return null; |
| 217 | try { return { value: JSON.parse(s.slice(i, end)), rest: s.slice(end).trim() }; } |
| 218 | catch (e) { return null; } |
| 219 | } |
| 220 | |
| 221 | export function clampText(s: any, n: number): string { |
| 222 | const t = String(s == null ? "" : s); |
no test coverage detected