pythonlib 0.1.0

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 (66) hide show
  1. package/README.md +183 -0
  2. package/dist/chunk-3CSEXTA7.js +376 -0
  3. package/dist/chunk-3CSEXTA7.js.map +1 -0
  4. package/dist/chunk-HA5Y7PKO.js +680 -0
  5. package/dist/chunk-HA5Y7PKO.js.map +1 -0
  6. package/dist/chunk-IVYYI2VR.js +261 -0
  7. package/dist/chunk-IVYYI2VR.js.map +1 -0
  8. package/dist/chunk-OMQNGE6T.js +245 -0
  9. package/dist/chunk-OMQNGE6T.js.map +1 -0
  10. package/dist/chunk-P3SGIF72.js +107 -0
  11. package/dist/chunk-P3SGIF72.js.map +1 -0
  12. package/dist/chunk-PZ5AY32C.js +10 -0
  13. package/dist/chunk-PZ5AY32C.js.map +1 -0
  14. package/dist/chunk-TJFGYXBJ.js +310 -0
  15. package/dist/chunk-TJFGYXBJ.js.map +1 -0
  16. package/dist/chunk-TOI6IG3T.js +337 -0
  17. package/dist/chunk-TOI6IG3T.js.map +1 -0
  18. package/dist/chunk-UFMTN4T4.js +215 -0
  19. package/dist/chunk-UFMTN4T4.js.map +1 -0
  20. package/dist/chunk-V63LKSA3.js +423 -0
  21. package/dist/chunk-V63LKSA3.js.map +1 -0
  22. package/dist/chunk-WAONBJE5.js +236 -0
  23. package/dist/chunk-WAONBJE5.js.map +1 -0
  24. package/dist/collections-xN9Gi0TA.d.ts +113 -0
  25. package/dist/collections.d.ts +1 -0
  26. package/dist/collections.js +12 -0
  27. package/dist/collections.js.map +1 -0
  28. package/dist/datetime-DRwFAiGV.d.ts +139 -0
  29. package/dist/datetime.d.ts +1 -0
  30. package/dist/datetime.js +22 -0
  31. package/dist/datetime.js.map +1 -0
  32. package/dist/functools-St5GqpKG.d.ts +125 -0
  33. package/dist/functools.d.ts +1 -0
  34. package/dist/functools.js +32 -0
  35. package/dist/functools.js.map +1 -0
  36. package/dist/index.d.ts +624 -0
  37. package/dist/index.js +1332 -0
  38. package/dist/index.js.map +1 -0
  39. package/dist/itertools-Bj8XivI6.d.ts +138 -0
  40. package/dist/itertools.d.ts +1 -0
  41. package/dist/itertools.js +44 -0
  42. package/dist/itertools.js.map +1 -0
  43. package/dist/json-Xpk0kwSd.d.ts +77 -0
  44. package/dist/json.d.ts +1 -0
  45. package/dist/json.js +14 -0
  46. package/dist/json.js.map +1 -0
  47. package/dist/math-BrT4Aw3E.d.ts +147 -0
  48. package/dist/math.d.ts +1 -0
  49. package/dist/math.js +96 -0
  50. package/dist/math.js.map +1 -0
  51. package/dist/os-FRSJbEUH.d.ts +143 -0
  52. package/dist/os.d.ts +1 -0
  53. package/dist/os.js +58 -0
  54. package/dist/os.js.map +1 -0
  55. package/dist/random-D5S5iSV3.d.ts +72 -0
  56. package/dist/random.d.ts +1 -0
  57. package/dist/random.js +42 -0
  58. package/dist/random.js.map +1 -0
  59. package/dist/re-DSxiURqN.d.ts +148 -0
  60. package/dist/re.d.ts +1 -0
  61. package/dist/re.js +52 -0
  62. package/dist/re.js.map +1 -0
  63. package/dist/string.d.ts +166 -0
  64. package/dist/string.js +30 -0
  65. package/dist/string.js.map +1 -0
  66. package/package.json +85 -0
package/README.md ADDED
@@ -0,0 +1,183 @@
1
+ # pythonlib
2
+
3
+ [![npm version](https://img.shields.io/npm/v/pythonlib.svg)](https://www.npmjs.com/package/pythonlib)
4
+ [![License](https://img.shields.io/npm/l/pythonlib.svg)](https://github.com/sebastian-software/python2ts/blob/main/LICENSE)
5
+
6
+ **Python standard library for TypeScript** — itertools, functools, collections, and more.
7
+
8
+ Zero dependencies. Full TypeScript support. Tree-shakeable.
9
+
10
+ ## Installation
11
+
12
+ ```bash
13
+ npm install pythonlib
14
+ ```
15
+
16
+ ## Quick Start
17
+
18
+ ```typescript
19
+ import { range, enumerate, sorted, len } from "pythonlib"
20
+ import { combinations } from "pythonlib/itertools"
21
+ import { Counter } from "pythonlib/collections"
22
+
23
+ // Python-style iteration
24
+ for (const i of range(10)) {
25
+ console.log(i)
26
+ }
27
+
28
+ // Combinatorics
29
+ for (const combo of combinations([1, 2, 3], 2)) {
30
+ console.log(combo) // [1,2], [1,3], [2,3]
31
+ }
32
+
33
+ // Count occurrences
34
+ const counter = new Counter("mississippi")
35
+ console.log(counter.mostCommon(2)) // [["i", 4], ["s", 4]]
36
+ ```
37
+
38
+ ## Import Structure
39
+
40
+ pythonlib uses subpath exports for tree-shakeable imports:
41
+
42
+ | Import Path | Contents |
43
+ | ----------------------- | -------------------------------------------------- |
44
+ | `pythonlib` | Builtins: `len`, `range`, `sorted`, `enumerate` |
45
+ | `pythonlib/itertools` | `chain`, `combinations`, `permutations`, `product` |
46
+ | `pythonlib/functools` | `partial`, `reduce`, `lru_cache`, `cache` |
47
+ | `pythonlib/collections` | `Counter`, `defaultdict`, `deque` |
48
+ | `pythonlib/math` | `sqrt`, `floor`, `ceil`, `factorial`, `pi`, `e` |
49
+ | `pythonlib/random` | `randint`, `choice`, `shuffle`, `sample` |
50
+ | `pythonlib/datetime` | `datetime`, `date`, `time`, `timedelta` |
51
+ | `pythonlib/json` | `loads`, `dumps`, `load`, `dump` |
52
+ | `pythonlib/re` | `search`, `match`, `findall`, `sub`, `compile` |
53
+ | `pythonlib/os` | `path`, `getcwd`, `sep` |
54
+ | `pythonlib/string` | `Template`, `capwords`, `ascii_lowercase` |
55
+
56
+ ## Modules
57
+
58
+ ### Builtins
59
+
60
+ ```typescript
61
+ import { range, enumerate, zip, len, sorted, reversed, sum, min, max } from "pythonlib"
62
+
63
+ for (const i of range(5)) {
64
+ } // 0, 1, 2, 3, 4
65
+ for (const i of range(1, 5)) {
66
+ } // 1, 2, 3, 4
67
+ for (const i of range(0, 10, 2)) {
68
+ } // 0, 2, 4, 6, 8
69
+
70
+ for (const [i, v] of enumerate(["a", "b", "c"])) {
71
+ } // [0,"a"], [1,"b"], [2,"c"]
72
+ for (const [a, b] of zip([1, 2], ["x", "y"])) {
73
+ } // [1,"x"], [2,"y"]
74
+
75
+ len([1, 2, 3]) // 3
76
+ sorted([3, 1, 2]) // [1, 2, 3]
77
+ reversed([1, 2, 3]) // [3, 2, 1]
78
+ sum([1, 2, 3]) // 6
79
+ min([1, 2, 3]) // 1
80
+ max([1, 2, 3]) // 3
81
+ ```
82
+
83
+ ### itertools
84
+
85
+ ```typescript
86
+ import { chain, combinations, permutations, product, groupby } from "pythonlib/itertools"
87
+
88
+ chain([1, 2], [3, 4]) // [1, 2, 3, 4]
89
+ combinations([1, 2, 3], 2) // [[1,2], [1,3], [2,3]]
90
+ permutations([1, 2, 3], 2) // [[1,2], [1,3], [2,1], [2,3], [3,1], [3,2]]
91
+ product([1, 2], ["a", "b"]) // [[1,"a"], [1,"b"], [2,"a"], [2,"b"]]
92
+ ```
93
+
94
+ ### functools
95
+
96
+ ```typescript
97
+ import { partial, reduce, lru_cache } from "pythonlib/functools"
98
+
99
+ const add5 = partial((a, b) => a + b, 5)
100
+ add5(3) // 8
101
+
102
+ reduce((a, b) => a + b, [1, 2, 3, 4, 5]) // 15
103
+
104
+ const cached = lru_cache((n: number) => expensiveComputation(n))
105
+ cached(5) // computes
106
+ cached(5) // returns cached result
107
+ ```
108
+
109
+ ### collections
110
+
111
+ ```typescript
112
+ import { Counter, defaultdict, deque } from "pythonlib/collections"
113
+
114
+ const counter = new Counter("abracadabra")
115
+ counter.get("a") // 5
116
+ counter.mostCommon(2) // [["a", 5], ["b", 2]]
117
+
118
+ const dd = defaultdict(() => [])
119
+ dd.get("key").push(1) // auto-creates array
120
+
121
+ const d = new deque([1, 2, 3])
122
+ d.appendleft(0) // [0, 1, 2, 3]
123
+ d.pop() // 3
124
+ ```
125
+
126
+ ### datetime
127
+
128
+ ```typescript
129
+ import { datetime, date, timedelta } from "pythonlib/datetime"
130
+
131
+ const now = datetime.now()
132
+ now.strftime("%Y-%m-%d %H:%M:%S")
133
+
134
+ const d = new date(2024, 6, 15)
135
+ d.isoformat() // "2024-06-15"
136
+
137
+ const delta = new timedelta({ days: 7 })
138
+ delta.total_seconds() // 604800
139
+ ```
140
+
141
+ ### re
142
+
143
+ ```typescript
144
+ import { search, findall, sub, compile } from "pythonlib/re"
145
+
146
+ const m = search("(?P<name>\\w+)@(?P<domain>\\w+)", "user@example")
147
+ m?.group("name") // "user"
148
+ m?.groupdict() // { name: "user", domain: "example" }
149
+
150
+ findall("\\d+", "a1b2c3") // ["1", "2", "3"]
151
+ sub("\\d", "X", "a1b2") // "aXbX"
152
+ ```
153
+
154
+ ### math
155
+
156
+ ```typescript
157
+ import { sqrt, factorial, gcd, lcm, pi, e } from "pythonlib/math"
158
+
159
+ sqrt(16) // 4
160
+ factorial(5) // 120
161
+ gcd(12, 8) // 4
162
+ lcm(4, 6) // 12
163
+ ```
164
+
165
+ ### random
166
+
167
+ ```typescript
168
+ import { randint, choice, shuffle, sample } from "pythonlib/random"
169
+
170
+ randint(1, 10) // random integer 1-10
171
+ choice(["a", "b", "c"]) // random element
172
+ shuffle([1, 2, 3]) // shuffles in place
173
+ sample([1, 2, 3, 4, 5], 3) // 3 unique random elements
174
+ ```
175
+
176
+ ## Related
177
+
178
+ - [python2ts](https://www.npmjs.com/package/python2ts) — Transpile Python to TypeScript (uses
179
+ pythonlib as runtime)
180
+
181
+ ## License
182
+
183
+ MIT
@@ -0,0 +1,376 @@
1
+ // src/string.ts
2
+ function escapeRegex(str) {
3
+ return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
4
+ }
5
+ var ascii_lowercase = "abcdefghijklmnopqrstuvwxyz";
6
+ var ascii_uppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
7
+ var ascii_letters = ascii_lowercase + ascii_uppercase;
8
+ var digits = "0123456789";
9
+ var hexdigits = "0123456789abcdefABCDEF";
10
+ var octdigits = "01234567";
11
+ var punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
12
+ var whitespace = " \n\r\v\f";
13
+ var printable = digits + ascii_letters + punctuation + whitespace;
14
+ var Template = class {
15
+ template;
16
+ constructor(template) {
17
+ this.template = template;
18
+ }
19
+ /** Perform substitution, raising KeyError for missing keys */
20
+ substitute(mapping) {
21
+ const combined = { ...mapping };
22
+ return this.template.replace(
23
+ /\$\$|\$(\w+)|\$\{(\w+)\}/g,
24
+ (match, name1, name2) => {
25
+ if (match === "$$") return "$";
26
+ const name = name1 || name2;
27
+ if (!(name in combined)) {
28
+ throw new Error(`KeyError: '${name}'`);
29
+ }
30
+ return String(combined[name]);
31
+ }
32
+ );
33
+ }
34
+ /** Perform substitution, returning original placeholder for missing keys */
35
+ safe_substitute(mapping) {
36
+ const combined = { ...mapping };
37
+ return this.template.replace(
38
+ /\$\$|\$(\w+)|\$\{(\w+)\}/g,
39
+ (match, name1, name2) => {
40
+ if (match === "$$") return "$";
41
+ const name = name1 || name2;
42
+ if (!(name in combined)) {
43
+ return match;
44
+ }
45
+ return String(combined[name]);
46
+ }
47
+ );
48
+ }
49
+ /** Get identifiers in template */
50
+ get_identifiers() {
51
+ const identifiers = [];
52
+ const regex = /\$(\w+)|\$\{(\w+)\}/g;
53
+ let match;
54
+ while ((match = regex.exec(this.template)) !== null) {
55
+ const name = match[1] || match[2];
56
+ if (name && !identifiers.includes(name)) {
57
+ identifiers.push(name);
58
+ }
59
+ }
60
+ return identifiers;
61
+ }
62
+ };
63
+ function capwords(s, sep) {
64
+ const separator = sep ?? " ";
65
+ return s.split(separator).map((word) => {
66
+ if (!word) return "";
67
+ const first = word[0];
68
+ return first ? first.toUpperCase() + word.slice(1).toLowerCase() : word;
69
+ }).join(separator);
70
+ }
71
+ var string = {
72
+ /**
73
+ * Python str.join()
74
+ */
75
+ join(sep, iterable) {
76
+ return Array.from(iterable).join(sep);
77
+ },
78
+ /**
79
+ * Python str.split()
80
+ */
81
+ split(s, sep, maxsplit) {
82
+ if (sep === void 0) {
83
+ const result = s.trim().split(/\s+/);
84
+ if (maxsplit !== void 0 && maxsplit >= 0) {
85
+ if (result.length > maxsplit + 1) {
86
+ const limited = result.slice(0, maxsplit);
87
+ limited.push(result.slice(maxsplit).join(" "));
88
+ return limited;
89
+ }
90
+ }
91
+ return result;
92
+ }
93
+ if (maxsplit !== void 0 && maxsplit >= 0) {
94
+ const parts = s.split(sep);
95
+ if (parts.length > maxsplit + 1) {
96
+ const limited = parts.slice(0, maxsplit);
97
+ limited.push(parts.slice(maxsplit).join(sep));
98
+ return limited;
99
+ }
100
+ return parts;
101
+ }
102
+ return s.split(sep);
103
+ },
104
+ /**
105
+ * Python str.rsplit()
106
+ */
107
+ rsplit(s, sep, maxsplit) {
108
+ if (sep === void 0) {
109
+ const parts2 = s.trim().split(/\s+/);
110
+ if (maxsplit === void 0) return parts2;
111
+ if (maxsplit <= 0) return [s];
112
+ if (parts2.length <= maxsplit + 1) return parts2;
113
+ const keep2 = parts2.slice(-maxsplit);
114
+ const rest2 = parts2.slice(0, parts2.length - maxsplit).join(" ");
115
+ return [rest2, ...keep2];
116
+ }
117
+ const parts = s.split(sep);
118
+ if (maxsplit === void 0 || parts.length <= maxsplit + 1) return parts;
119
+ const keep = parts.slice(-maxsplit);
120
+ const rest = parts.slice(0, parts.length - maxsplit).join(sep);
121
+ return [rest, ...keep];
122
+ },
123
+ /**
124
+ * Python str.strip()
125
+ */
126
+ strip(s, chars) {
127
+ if (chars === void 0) {
128
+ return s.trim();
129
+ }
130
+ const regex = new RegExp(`^[${escapeRegex(chars)}]+|[${escapeRegex(chars)}]+$`, "g");
131
+ return s.replace(regex, "");
132
+ },
133
+ /**
134
+ * Python str.lstrip()
135
+ */
136
+ lstrip(s, chars) {
137
+ if (chars === void 0) {
138
+ return s.trimStart();
139
+ }
140
+ const regex = new RegExp(`^[${escapeRegex(chars)}]+`);
141
+ return s.replace(regex, "");
142
+ },
143
+ /**
144
+ * Python str.rstrip()
145
+ */
146
+ rstrip(s, chars) {
147
+ if (chars === void 0) {
148
+ return s.trimEnd();
149
+ }
150
+ const regex = new RegExp(`[${escapeRegex(chars)}]+$`);
151
+ return s.replace(regex, "");
152
+ },
153
+ /**
154
+ * Python str.upper()
155
+ */
156
+ upper(s) {
157
+ return s.toUpperCase();
158
+ },
159
+ /**
160
+ * Python str.lower()
161
+ */
162
+ lower(s) {
163
+ return s.toLowerCase();
164
+ },
165
+ /**
166
+ * Python str.capitalize()
167
+ */
168
+ capitalize(s) {
169
+ if (s.length === 0) return s;
170
+ return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase();
171
+ },
172
+ /**
173
+ * Python str.title()
174
+ */
175
+ title(s) {
176
+ return s.replace(/\b\w/g, (c) => c.toUpperCase());
177
+ },
178
+ /**
179
+ * Python str.swapcase()
180
+ */
181
+ swapcase(s) {
182
+ return s.split("").map((c) => c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()).join("");
183
+ },
184
+ /**
185
+ * Python str.startswith()
186
+ */
187
+ startswith(s, prefix, start, end) {
188
+ const substr = s.slice(start, end);
189
+ return substr.startsWith(prefix);
190
+ },
191
+ /**
192
+ * Python str.endswith()
193
+ */
194
+ endswith(s, suffix, start, end) {
195
+ const substr = s.slice(start, end);
196
+ return substr.endsWith(suffix);
197
+ },
198
+ /**
199
+ * Python str.find()
200
+ */
201
+ find(s, sub, start, end) {
202
+ const substr = s.slice(start, end);
203
+ const index = substr.indexOf(sub);
204
+ if (index === -1) return -1;
205
+ return (start ?? 0) + index;
206
+ },
207
+ /**
208
+ * Python str.rfind()
209
+ */
210
+ rfind(s, sub, start, end) {
211
+ const substr = s.slice(start, end);
212
+ const index = substr.lastIndexOf(sub);
213
+ if (index === -1) return -1;
214
+ return (start ?? 0) + index;
215
+ },
216
+ /**
217
+ * Python str.index() - raises error if not found
218
+ */
219
+ index(s, sub, start, end) {
220
+ const result = string.find(s, sub, start, end);
221
+ if (result === -1) {
222
+ throw new Error("substring not found");
223
+ }
224
+ return result;
225
+ },
226
+ /**
227
+ * Python str.rindex() - raises error if not found
228
+ */
229
+ rindex(s, sub, start, end) {
230
+ const result = string.rfind(s, sub, start, end);
231
+ if (result === -1) {
232
+ throw new Error("substring not found");
233
+ }
234
+ return result;
235
+ },
236
+ /**
237
+ * Python str.count()
238
+ */
239
+ count(s, sub, start, end) {
240
+ const substr = s.slice(start, end);
241
+ if (sub.length === 0) return substr.length + 1;
242
+ let count = 0;
243
+ let pos = 0;
244
+ while ((pos = substr.indexOf(sub, pos)) !== -1) {
245
+ count++;
246
+ pos += sub.length;
247
+ }
248
+ return count;
249
+ },
250
+ /**
251
+ * Python str.replace()
252
+ */
253
+ replace(s, old, newStr, count) {
254
+ if (count === void 0 || count < 0) {
255
+ return s.split(old).join(newStr);
256
+ }
257
+ let result = s;
258
+ for (let i = 0; i < count; i++) {
259
+ const index = result.indexOf(old);
260
+ if (index === -1) break;
261
+ result = result.slice(0, index) + newStr + result.slice(index + old.length);
262
+ }
263
+ return result;
264
+ },
265
+ /**
266
+ * Python str.zfill()
267
+ */
268
+ zfill(s, width) {
269
+ if (s.length >= width) return s;
270
+ const sign = s[0] === "-" || s[0] === "+" ? s[0] : "";
271
+ const digits2 = sign ? s.slice(1) : s;
272
+ return sign + digits2.padStart(width - sign.length, "0");
273
+ },
274
+ /**
275
+ * Python str.center()
276
+ */
277
+ center(s, width, fillchar = " ") {
278
+ if (s.length >= width) return s;
279
+ const total = width - s.length;
280
+ const left = Math.floor(total / 2);
281
+ const right = total - left;
282
+ return fillchar.repeat(left) + s + fillchar.repeat(right);
283
+ },
284
+ /**
285
+ * Python str.ljust()
286
+ */
287
+ ljust(s, width, fillchar = " ") {
288
+ if (s.length >= width) return s;
289
+ return s + fillchar.repeat(width - s.length);
290
+ },
291
+ /**
292
+ * Python str.rjust()
293
+ */
294
+ rjust(s, width, fillchar = " ") {
295
+ if (s.length >= width) return s;
296
+ return fillchar.repeat(width - s.length) + s;
297
+ },
298
+ /**
299
+ * Python str.partition()
300
+ */
301
+ partition(s, sep) {
302
+ const index = s.indexOf(sep);
303
+ if (index === -1) return [s, "", ""];
304
+ return [s.slice(0, index), sep, s.slice(index + sep.length)];
305
+ },
306
+ /**
307
+ * Python str.rpartition()
308
+ */
309
+ rpartition(s, sep) {
310
+ const index = s.lastIndexOf(sep);
311
+ if (index === -1) return ["", "", s];
312
+ return [s.slice(0, index), sep, s.slice(index + sep.length)];
313
+ },
314
+ /**
315
+ * Python str.isalpha()
316
+ */
317
+ isalpha(s) {
318
+ return s.length > 0 && /^[a-zA-Z]+$/.test(s);
319
+ },
320
+ /**
321
+ * Python str.isdigit()
322
+ */
323
+ isdigit(s) {
324
+ return s.length > 0 && /^[0-9]+$/.test(s);
325
+ },
326
+ /**
327
+ * Python str.isalnum()
328
+ */
329
+ isalnum(s) {
330
+ return s.length > 0 && /^[a-zA-Z0-9]+$/.test(s);
331
+ },
332
+ /**
333
+ * Python str.isspace()
334
+ */
335
+ isspace(s) {
336
+ return s.length > 0 && /^\s+$/.test(s);
337
+ },
338
+ /**
339
+ * Python str.isupper()
340
+ */
341
+ isupper(s) {
342
+ return s.length > 0 && s === s.toUpperCase() && s !== s.toLowerCase();
343
+ },
344
+ /**
345
+ * Python str.islower()
346
+ */
347
+ islower(s) {
348
+ return s.length > 0 && s === s.toLowerCase() && s !== s.toUpperCase();
349
+ },
350
+ /**
351
+ * Python str.format() - basic implementation
352
+ */
353
+ format(s, ...args) {
354
+ let index = 0;
355
+ return s.replace(/\{(\d*)\}/g, (_, num) => {
356
+ const i = num === "" ? index++ : parseInt(num, 10);
357
+ return String(args[i]);
358
+ });
359
+ }
360
+ };
361
+
362
+ export {
363
+ ascii_lowercase,
364
+ ascii_uppercase,
365
+ ascii_letters,
366
+ digits,
367
+ hexdigits,
368
+ octdigits,
369
+ punctuation,
370
+ whitespace,
371
+ printable,
372
+ Template,
373
+ capwords,
374
+ string
375
+ };
376
+ //# sourceMappingURL=chunk-3CSEXTA7.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/string.ts"],"sourcesContent":["/**\n * Python string methods and constants for TypeScript\n * Usage: py.string.join(), py.string.split(), py.string.ascii_lowercase, etc.\n */\n\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\")\n}\n\n// ============================================================================\n// String constants (Python string module)\n// ============================================================================\n\n/** The lowercase letters 'abcdefghijklmnopqrstuvwxyz' */\nexport const ascii_lowercase = \"abcdefghijklmnopqrstuvwxyz\"\n\n/** The uppercase letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' */\nexport const ascii_uppercase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\n/** The concatenation of ascii_lowercase and ascii_uppercase */\nexport const ascii_letters = ascii_lowercase + ascii_uppercase\n\n/** The string '0123456789' */\nexport const digits = \"0123456789\"\n\n/** The string '0123456789abcdefABCDEF' */\nexport const hexdigits = \"0123456789abcdefABCDEF\"\n\n/** The string '01234567' */\nexport const octdigits = \"01234567\"\n\n/** String of ASCII characters which are considered punctuation */\nexport const punctuation = \"!\\\"#$%&'()*+,-./:;<=>?@[\\\\]^_`{|}~\"\n\n/** String of ASCII characters which are considered whitespace */\nexport const whitespace = \" \\t\\n\\r\\x0b\\x0c\"\n\n/** String of ASCII characters which are considered printable */\nexport const printable = digits + ascii_letters + punctuation + whitespace\n\n// ============================================================================\n// Template class\n// ============================================================================\n\nexport class Template {\n readonly template: string\n\n constructor(template: string) {\n this.template = template\n }\n\n /** Perform substitution, raising KeyError for missing keys */\n substitute(mapping?: Record<string, unknown>): string {\n const combined = { ...mapping }\n return this.template.replace(\n /\\$\\$|\\$(\\w+)|\\$\\{(\\w+)\\}/g,\n (match, name1: string, name2: string) => {\n if (match === \"$$\") return \"$\"\n const name = name1 || name2\n if (!(name in combined)) {\n throw new Error(`KeyError: '${name}'`)\n }\n return String(combined[name])\n }\n )\n }\n\n /** Perform substitution, returning original placeholder for missing keys */\n safe_substitute(mapping?: Record<string, unknown>): string {\n const combined = { ...mapping }\n return this.template.replace(\n /\\$\\$|\\$(\\w+)|\\$\\{(\\w+)\\}/g,\n (match, name1: string, name2: string) => {\n if (match === \"$$\") return \"$\"\n const name = name1 || name2\n if (!(name in combined)) {\n return match\n }\n return String(combined[name])\n }\n )\n }\n\n /** Get identifiers in template */\n get_identifiers(): string[] {\n const identifiers: string[] = []\n const regex = /\\$(\\w+)|\\$\\{(\\w+)\\}/g\n let match: RegExpExecArray | null\n while ((match = regex.exec(this.template)) !== null) {\n const name = match[1] || match[2]\n if (name && !identifiers.includes(name)) {\n identifiers.push(name)\n }\n }\n return identifiers\n }\n}\n\n/** Capitalize words in string */\nexport function capwords(s: string, sep?: string): string {\n const separator = sep ?? \" \"\n return s\n .split(separator)\n .map((word) => {\n if (!word) return \"\"\n const first = word[0]\n return first ? first.toUpperCase() + word.slice(1).toLowerCase() : word\n })\n .join(separator)\n}\n\nexport const string = {\n /**\n * Python str.join()\n */\n join(sep: string, iterable: Iterable<string>): string {\n return Array.from(iterable).join(sep)\n },\n\n /**\n * Python str.split()\n */\n split(s: string, sep?: string, maxsplit?: number): string[] {\n if (sep === undefined) {\n // Split on whitespace\n const result = s.trim().split(/\\s+/)\n if (maxsplit !== undefined && maxsplit >= 0) {\n if (result.length > maxsplit + 1) {\n const limited = result.slice(0, maxsplit)\n limited.push(result.slice(maxsplit).join(\" \"))\n return limited\n }\n }\n return result\n }\n\n if (maxsplit !== undefined && maxsplit >= 0) {\n const parts = s.split(sep)\n if (parts.length > maxsplit + 1) {\n const limited = parts.slice(0, maxsplit)\n limited.push(parts.slice(maxsplit).join(sep))\n return limited\n }\n return parts\n }\n\n return s.split(sep)\n },\n\n /**\n * Python str.rsplit()\n */\n rsplit(s: string, sep?: string, maxsplit?: number): string[] {\n if (sep === undefined) {\n const parts = s.trim().split(/\\s+/)\n if (maxsplit === undefined) return parts\n if (maxsplit <= 0) return [s]\n if (parts.length <= maxsplit + 1) return parts\n const keep = parts.slice(-maxsplit)\n const rest = parts.slice(0, parts.length - maxsplit).join(\" \")\n return [rest, ...keep]\n }\n\n const parts = s.split(sep)\n if (maxsplit === undefined || parts.length <= maxsplit + 1) return parts\n const keep = parts.slice(-maxsplit)\n const rest = parts.slice(0, parts.length - maxsplit).join(sep)\n return [rest, ...keep]\n },\n\n /**\n * Python str.strip()\n */\n strip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trim()\n }\n const regex = new RegExp(`^[${escapeRegex(chars)}]+|[${escapeRegex(chars)}]+$`, \"g\")\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.lstrip()\n */\n lstrip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trimStart()\n }\n const regex = new RegExp(`^[${escapeRegex(chars)}]+`)\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.rstrip()\n */\n rstrip(s: string, chars?: string): string {\n if (chars === undefined) {\n return s.trimEnd()\n }\n const regex = new RegExp(`[${escapeRegex(chars)}]+$`)\n return s.replace(regex, \"\")\n },\n\n /**\n * Python str.upper()\n */\n upper(s: string): string {\n return s.toUpperCase()\n },\n\n /**\n * Python str.lower()\n */\n lower(s: string): string {\n return s.toLowerCase()\n },\n\n /**\n * Python str.capitalize()\n */\n capitalize(s: string): string {\n if (s.length === 0) return s\n return s.charAt(0).toUpperCase() + s.slice(1).toLowerCase()\n },\n\n /**\n * Python str.title()\n */\n title(s: string): string {\n return s.replace(/\\b\\w/g, (c) => c.toUpperCase())\n },\n\n /**\n * Python str.swapcase()\n */\n swapcase(s: string): string {\n return s\n .split(\"\")\n .map((c) => (c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()))\n .join(\"\")\n },\n\n /**\n * Python str.startswith()\n */\n startswith(s: string, prefix: string, start?: number, end?: number): boolean {\n const substr = s.slice(start, end)\n return substr.startsWith(prefix)\n },\n\n /**\n * Python str.endswith()\n */\n endswith(s: string, suffix: string, start?: number, end?: number): boolean {\n const substr = s.slice(start, end)\n return substr.endsWith(suffix)\n },\n\n /**\n * Python str.find()\n */\n find(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n const index = substr.indexOf(sub)\n if (index === -1) return -1\n return (start ?? 0) + index\n },\n\n /**\n * Python str.rfind()\n */\n rfind(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n const index = substr.lastIndexOf(sub)\n if (index === -1) return -1\n return (start ?? 0) + index\n },\n\n /**\n * Python str.index() - raises error if not found\n */\n index(s: string, sub: string, start?: number, end?: number): number {\n const result = string.find(s, sub, start, end)\n if (result === -1) {\n throw new Error(\"substring not found\")\n }\n return result\n },\n\n /**\n * Python str.rindex() - raises error if not found\n */\n rindex(s: string, sub: string, start?: number, end?: number): number {\n const result = string.rfind(s, sub, start, end)\n if (result === -1) {\n throw new Error(\"substring not found\")\n }\n return result\n },\n\n /**\n * Python str.count()\n */\n count(s: string, sub: string, start?: number, end?: number): number {\n const substr = s.slice(start, end)\n if (sub.length === 0) return substr.length + 1\n let count = 0\n let pos = 0\n while ((pos = substr.indexOf(sub, pos)) !== -1) {\n count++\n pos += sub.length\n }\n return count\n },\n\n /**\n * Python str.replace()\n */\n replace(s: string, old: string, newStr: string, count?: number): string {\n if (count === undefined || count < 0) {\n return s.split(old).join(newStr)\n }\n\n let result = s\n for (let i = 0; i < count; i++) {\n const index = result.indexOf(old)\n if (index === -1) break\n result = result.slice(0, index) + newStr + result.slice(index + old.length)\n }\n return result\n },\n\n /**\n * Python str.zfill()\n */\n zfill(s: string, width: number): string {\n if (s.length >= width) return s\n const sign = s[0] === \"-\" || s[0] === \"+\" ? s[0] : \"\"\n const digits = sign ? s.slice(1) : s\n return sign + digits.padStart(width - sign.length, \"0\")\n },\n\n /**\n * Python str.center()\n */\n center(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n const total = width - s.length\n const left = Math.floor(total / 2)\n const right = total - left\n return fillchar.repeat(left) + s + fillchar.repeat(right)\n },\n\n /**\n * Python str.ljust()\n */\n ljust(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n return s + fillchar.repeat(width - s.length)\n },\n\n /**\n * Python str.rjust()\n */\n rjust(s: string, width: number, fillchar = \" \"): string {\n if (s.length >= width) return s\n return fillchar.repeat(width - s.length) + s\n },\n\n /**\n * Python str.partition()\n */\n partition(s: string, sep: string): [string, string, string] {\n const index = s.indexOf(sep)\n if (index === -1) return [s, \"\", \"\"]\n return [s.slice(0, index), sep, s.slice(index + sep.length)]\n },\n\n /**\n * Python str.rpartition()\n */\n rpartition(s: string, sep: string): [string, string, string] {\n const index = s.lastIndexOf(sep)\n if (index === -1) return [\"\", \"\", s]\n return [s.slice(0, index), sep, s.slice(index + sep.length)]\n },\n\n /**\n * Python str.isalpha()\n */\n isalpha(s: string): boolean {\n return s.length > 0 && /^[a-zA-Z]+$/.test(s)\n },\n\n /**\n * Python str.isdigit()\n */\n isdigit(s: string): boolean {\n return s.length > 0 && /^[0-9]+$/.test(s)\n },\n\n /**\n * Python str.isalnum()\n */\n isalnum(s: string): boolean {\n return s.length > 0 && /^[a-zA-Z0-9]+$/.test(s)\n },\n\n /**\n * Python str.isspace()\n */\n isspace(s: string): boolean {\n return s.length > 0 && /^\\s+$/.test(s)\n },\n\n /**\n * Python str.isupper()\n */\n isupper(s: string): boolean {\n return s.length > 0 && s === s.toUpperCase() && s !== s.toLowerCase()\n },\n\n /**\n * Python str.islower()\n */\n islower(s: string): boolean {\n return s.length > 0 && s === s.toLowerCase() && s !== s.toUpperCase()\n },\n\n /**\n * Python str.format() - basic implementation\n */\n format(s: string, ...args: unknown[]): string {\n let index = 0\n return s.replace(/\\{(\\d*)\\}/g, (_, num: string) => {\n const i = num === \"\" ? index++ : parseInt(num, 10)\n return String(args[i])\n })\n }\n}\n"],"mappings":"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","names":["parts","keep","rest","digits"]}