| 72 | |
| 73 | // Strip common leading-whitespace from non-empty lines so a snippet pasted from deeper context lands flush. |
| 74 | const dedentCommon = (s) => { |
| 75 | const lines = s.split('\n'); |
| 76 | const nonEmpty = lines.filter(l => l.trim().length > 0); |
| 77 | if (nonEmpty.length === 0) return s; |
| 78 | const min = Math.min(...nonEmpty.map(l => l.match(/^[ \t]*/)[0].length)); |
| 79 | return min ? lines.map(l => l.slice(Math.min(l.length, min))).join('\n') : s; |
| 80 | }; |
| 81 | |
| 82 | // Round-trip helper for paste: strip our own ```python fence transparently. |
| 83 | const unwrapFence = (s) => { |