pythonlib 0.1.0 → 0.2.1
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.
- package/LICENSE +21 -0
- package/README.md +41 -138
- package/dist/{chunk-P3SGIF72.js → chunk-4KYJT3DR.js} +8 -6
- package/dist/chunk-4KYJT3DR.js.map +1 -0
- package/dist/{chunk-3CSEXTA7.js → chunk-4QG3772L.js} +53 -53
- package/dist/chunk-4QG3772L.js.map +1 -0
- package/dist/{chunk-IVYYI2VR.js → chunk-6POEDI34.js} +1 -1
- package/dist/chunk-6POEDI34.js.map +1 -0
- package/dist/{chunk-UFMTN4T4.js → chunk-6ZAJ37MR.js} +6 -5
- package/dist/chunk-6ZAJ37MR.js.map +1 -0
- package/dist/{chunk-V63LKSA3.js → chunk-7TH4FCVQ.js} +24 -24
- package/dist/chunk-7TH4FCVQ.js.map +1 -0
- package/dist/{chunk-TJFGYXBJ.js → chunk-CXKGPD5D.js} +64 -61
- package/dist/chunk-CXKGPD5D.js.map +1 -0
- package/dist/{chunk-OMQNGE6T.js → chunk-EE7SK2GV.js} +33 -27
- package/dist/chunk-EE7SK2GV.js.map +1 -0
- package/dist/{chunk-WAONBJE5.js → chunk-H76SKASU.js} +36 -36
- package/dist/chunk-H76SKASU.js.map +1 -0
- package/dist/{chunk-TOI6IG3T.js → chunk-HQ42WNKZ.js} +43 -16
- package/dist/chunk-HQ42WNKZ.js.map +1 -0
- package/dist/{chunk-HA5Y7PKO.js → chunk-LWO6BIAD.js} +36 -35
- package/dist/chunk-LWO6BIAD.js.map +1 -0
- package/dist/{collections-xN9Gi0TA.d.ts → collections-CJur5Wg-.d.ts} +5 -3
- package/dist/collections.d.ts +1 -1
- package/dist/collections.js +1 -1
- package/dist/{datetime-DRwFAiGV.d.ts → datetime-Bpce8gG2.d.ts} +17 -15
- package/dist/datetime.d.ts +1 -1
- package/dist/datetime.js +1 -1
- package/dist/{functools-St5GqpKG.d.ts → functools-NrsZAqJk.d.ts} +42 -26
- package/dist/functools.d.ts +1 -1
- package/dist/functools.js +19 -17
- package/dist/index.d.ts +56 -158
- package/dist/index.js +47 -137
- package/dist/index.js.map +1 -1
- package/dist/{itertools-Bj8XivI6.d.ts → itertools-Sjl1LB_0.d.ts} +35 -17
- package/dist/itertools.d.ts +1 -1
- package/dist/itertools.js +15 -11
- package/dist/{json-Xpk0kwSd.d.ts → json-DAlvCadU.d.ts} +7 -5
- package/dist/json.d.ts +1 -1
- package/dist/json.js +1 -1
- package/dist/{math-BrT4Aw3E.d.ts → math-DwEGjjQ-.d.ts} +2 -0
- package/dist/math.d.ts +1 -1
- package/dist/math.js +1 -1
- package/dist/{os-FRSJbEUH.d.ts → os-C6Nt7Ijx.d.ts} +45 -42
- package/dist/os.d.ts +1 -1
- package/dist/os.js +23 -23
- package/dist/{random-D5S5iSV3.d.ts → random-BJv_rSpL.d.ts} +24 -22
- package/dist/random.d.ts +1 -1
- package/dist/random.js +21 -21
- package/dist/{re-DSxiURqN.d.ts → re-B1CHCgyr.d.ts} +17 -15
- package/dist/re.d.ts +1 -1
- package/dist/re.js +7 -7
- package/dist/string.d.ts +51 -48
- package/dist/string.js +13 -13
- package/package.json +30 -11
- package/dist/chunk-3CSEXTA7.js.map +0 -1
- package/dist/chunk-HA5Y7PKO.js.map +0 -1
- package/dist/chunk-IVYYI2VR.js.map +0 -1
- package/dist/chunk-OMQNGE6T.js.map +0 -1
- package/dist/chunk-P3SGIF72.js.map +0 -1
- package/dist/chunk-TJFGYXBJ.js.map +0 -1
- package/dist/chunk-TOI6IG3T.js.map +0 -1
- package/dist/chunk-UFMTN4T4.js.map +0 -1
- package/dist/chunk-V63LKSA3.js.map +0 -1
- package/dist/chunk-WAONBJE5.js.map +0 -1
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Sebastian Software GmbH
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,24 +1,28 @@
|
|
|
1
1
|
# pythonlib
|
|
2
2
|
|
|
3
3
|
[](https://www.npmjs.com/package/pythonlib)
|
|
4
|
+
[](https://www.npmjs.com/package/pythonlib)
|
|
5
|
+
[](https://bundlephobia.com/package/pythonlib)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
4
7
|
[](https://github.com/sebastian-software/python2ts/blob/main/LICENSE)
|
|
5
8
|
|
|
6
|
-
**Python standard library
|
|
9
|
+
**Python's powerful standard library, TypeScript's familiar style** — itertools, functools,
|
|
10
|
+
collections, and more.
|
|
7
11
|
|
|
8
|
-
Zero dependencies
|
|
12
|
+
> Zero dependencies · Full TypeScript support · Tree-shakeable · camelCase API · Works everywhere JS
|
|
13
|
+
> runs
|
|
9
14
|
|
|
10
|
-
##
|
|
15
|
+
## Quick Start
|
|
11
16
|
|
|
12
17
|
```bash
|
|
13
18
|
npm install pythonlib
|
|
14
19
|
```
|
|
15
20
|
|
|
16
|
-
## Quick Start
|
|
17
|
-
|
|
18
21
|
```typescript
|
|
19
|
-
import { range, enumerate, sorted
|
|
22
|
+
import { range, enumerate, sorted } from "pythonlib"
|
|
20
23
|
import { combinations } from "pythonlib/itertools"
|
|
21
24
|
import { Counter } from "pythonlib/collections"
|
|
25
|
+
import { lruCache } from "pythonlib/functools"
|
|
22
26
|
|
|
23
27
|
// Python-style iteration
|
|
24
28
|
for (const i of range(10)) {
|
|
@@ -32,152 +36,51 @@ for (const combo of combinations([1, 2, 3], 2)) {
|
|
|
32
36
|
|
|
33
37
|
// Count occurrences
|
|
34
38
|
const counter = new Counter("mississippi")
|
|
35
|
-
|
|
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"
|
|
39
|
+
counter.mostCommon(2) // [["i", 4], ["s", 4]]
|
|
87
40
|
|
|
88
|
-
|
|
89
|
-
|
|
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"]]
|
|
41
|
+
// Memoization
|
|
42
|
+
const fib = lruCache((n: number): number => (n <= 1 ? n : fib(n - 1) + fib(n - 2)))
|
|
92
43
|
```
|
|
93
44
|
|
|
94
|
-
|
|
45
|
+
## Available Modules
|
|
95
46
|
|
|
96
|
-
|
|
97
|
-
|
|
47
|
+
| Import Path | Contents | API Docs |
|
|
48
|
+
| ----------------------- | -------------------------------------------------- | ------------------------------------------------------------------------ |
|
|
49
|
+
| `pythonlib` | Builtins: `len`, `range`, `sorted`, `enumerate`... | [→](https://sebastian-software.github.io/python2ts/docs/api/index) |
|
|
50
|
+
| `pythonlib/itertools` | `chain`, `combinations`, `zipLongest`, `takeWhile` | [→](https://sebastian-software.github.io/python2ts/docs/api/itertools) |
|
|
51
|
+
| `pythonlib/functools` | `partial`, `reduce`, `lruCache`, `pipe` | [→](https://sebastian-software.github.io/python2ts/docs/api/functools) |
|
|
52
|
+
| `pythonlib/collections` | `Counter`, `defaultdict`, `deque` | [→](https://sebastian-software.github.io/python2ts/docs/api/collections) |
|
|
53
|
+
| `pythonlib/math` | `sqrt`, `floor`, `ceil`, `factorial`, `pi`, `e` | [→](https://sebastian-software.github.io/python2ts/docs/api/math) |
|
|
54
|
+
| `pythonlib/random` | `randInt`, `choice`, `shuffle`, `sample` | [→](https://sebastian-software.github.io/python2ts/docs/api/random) |
|
|
55
|
+
| `pythonlib/datetime` | `datetime`, `date`, `time`, `timedelta` | [→](https://sebastian-software.github.io/python2ts/docs/api/datetime) |
|
|
56
|
+
| `pythonlib/json` | `loads`, `dumps` | [→](https://sebastian-software.github.io/python2ts/docs/api/json) |
|
|
57
|
+
| `pythonlib/re` | `search`, `match`, `findAll`, `sub`, `compile` | [→](https://sebastian-software.github.io/python2ts/docs/api/re) |
|
|
58
|
+
| `pythonlib/string` | `Template`, `capWords`, `asciiLowercase` | [→](https://sebastian-software.github.io/python2ts/docs/api/string) |
|
|
98
59
|
|
|
99
|
-
|
|
100
|
-
add5(3) // 8
|
|
60
|
+
> All function names use **camelCase** to feel native in TypeScript.
|
|
101
61
|
|
|
102
|
-
|
|
62
|
+
## Documentation
|
|
103
63
|
|
|
104
|
-
|
|
105
|
-
cached(5) // computes
|
|
106
|
-
cached(5) // returns cached result
|
|
107
|
-
```
|
|
64
|
+
**[📚 View Full Documentation](https://sebastian-software.github.io/python2ts/)**
|
|
108
65
|
|
|
109
|
-
|
|
66
|
+
| Resource | Description |
|
|
67
|
+
| ------------------------------------------------------------------------------ | ------------------------------------------- |
|
|
68
|
+
| [Homepage](https://sebastian-software.github.io/python2ts/) | Project overview, features, and quick start |
|
|
69
|
+
| [Runtime Guide](https://sebastian-software.github.io/python2ts/docs/runtime) | How to use pythonlib in your projects |
|
|
70
|
+
| [API Reference](https://sebastian-software.github.io/python2ts/docs/api) | Complete API documentation for all modules |
|
|
71
|
+
| [Syntax Reference](https://sebastian-software.github.io/python2ts/docs/syntax) | Python → TypeScript transformation rules |
|
|
110
72
|
|
|
111
|
-
|
|
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
|
-
```
|
|
73
|
+
## Runtime Support
|
|
125
74
|
|
|
126
|
-
|
|
75
|
+
Tested on every commit: **Node.js** (v22, v24) · **Bun** · **Deno** · **Browsers**
|
|
127
76
|
|
|
128
|
-
|
|
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
|
-
```
|
|
77
|
+
Also works in Cloudflare Workers, AWS Lambda, and other JS environments.
|
|
175
78
|
|
|
176
79
|
## Related
|
|
177
80
|
|
|
178
|
-
- [python2ts](https://www.npmjs.com/package/python2ts) — Transpile Python to TypeScript
|
|
179
|
-
|
|
81
|
+
- [**python2ts**](https://www.npmjs.com/package/python2ts) — Transpile Python to TypeScript
|
|
82
|
+
- [**GitHub**](https://github.com/sebastian-software/python2ts) — Source code and issue tracker
|
|
180
83
|
|
|
181
84
|
## License
|
|
182
85
|
|
|
183
|
-
MIT
|
|
86
|
+
MIT © [Sebastian Software GmbH](https://sebastian-software.de)
|
|
@@ -12,9 +12,9 @@ __export(json_exports, {
|
|
|
12
12
|
});
|
|
13
13
|
function dumps(obj, options) {
|
|
14
14
|
const indent = options?.indent;
|
|
15
|
-
const sortKeys = options?.
|
|
15
|
+
const sortKeys = options?.sortKeys ?? false;
|
|
16
16
|
const defaultFn = options?.default;
|
|
17
|
-
const ensureAscii = options?.
|
|
17
|
+
const ensureAscii = options?.ensureAscii ?? true;
|
|
18
18
|
const replacer = sortKeys ? (_key, value) => {
|
|
19
19
|
if (value && typeof value === "object" && !Array.isArray(value)) {
|
|
20
20
|
const sorted = {};
|
|
@@ -62,9 +62,9 @@ function dumps(obj, options) {
|
|
|
62
62
|
return result;
|
|
63
63
|
}
|
|
64
64
|
function loads(s, options) {
|
|
65
|
-
const objectHook = options?.
|
|
66
|
-
const parseFloat = options?.
|
|
67
|
-
const parseInt = options?.
|
|
65
|
+
const objectHook = options?.objectHook;
|
|
66
|
+
const parseFloat = options?.parseFloatFn;
|
|
67
|
+
const parseInt = options?.parseIntFn;
|
|
68
68
|
let reviver;
|
|
69
69
|
if (objectHook || parseFloat || parseInt) {
|
|
70
70
|
reviver = (key, value) => {
|
|
@@ -104,4 +104,6 @@ export {
|
|
|
104
104
|
load,
|
|
105
105
|
json_exports
|
|
106
106
|
};
|
|
107
|
-
|
|
107
|
+
/* v8 ignore start -- error handling for invalid JSON @preserve */
|
|
108
|
+
/* v8 ignore start -- advanced custom parser hooks @preserve */
|
|
109
|
+
//# sourceMappingURL=chunk-4KYJT3DR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/json.ts"],"sourcesContent":["/**\n * Python json module for TypeScript\n *\n * Provides JSON encoding and decoding functions matching Python's json module.\n * Maps directly to JavaScript's JSON object with Python-compatible options.\n *\n * @see {@link https://docs.python.org/3/library/json.html | Python json documentation}\n */\n\ntype JsonValue = string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue }\ntype JsonReplacer = (key: string, value: unknown) => unknown\ntype JsonReviver = (key: string, value: unknown) => unknown\n\ninterface DumpsOptions {\n /** If specified, use this many spaces for indentation */\n indent?: number\n /** Separators for items and key-value pairs [item_sep, key_sep] */\n separators?: [string, string]\n /** Sort dictionary keys */\n sortKeys?: boolean\n /** If false, non-ASCII characters are escaped. Default true */\n ensureAscii?: boolean\n /** Custom serialization function */\n default?: (obj: unknown) => JsonValue\n}\n\ninterface LoadsOptions {\n /** Custom deserialization function */\n objectHook?: (obj: Record<string, unknown>) => unknown\n /** Parse floats with this function */\n parseFloatFn?: (s: string) => number\n /** Parse integers with this function */\n parseIntFn?: (s: string) => number\n}\n\n/**\n * Serialize obj to a JSON formatted string.\n *\n * @param obj - The object to serialize\n * @param options - Serialization options\n * @returns JSON string\n */\nexport function dumps(obj: unknown, options?: DumpsOptions): string {\n const indent = options?.indent\n const sortKeys = options?.sortKeys ?? false\n const defaultFn = options?.default\n const ensureAscii = options?.ensureAscii ?? true\n\n const replacer: JsonReplacer | undefined = sortKeys\n ? (_key, value) => {\n if (value && typeof value === \"object\" && !Array.isArray(value)) {\n const sorted: Record<string, unknown> = {}\n for (const k of Object.keys(value as Record<string, unknown>).sort()) {\n sorted[k] = (value as Record<string, unknown>)[k]\n }\n return sorted\n }\n return value\n }\n : undefined\n\n let result: string\n\n try {\n if (defaultFn) {\n // Custom serialization with default function\n result = JSON.stringify(\n obj,\n (key, value: unknown) => {\n const processed: unknown = replacer ? replacer(key, value) : value\n try {\n // Try default serialization first\n JSON.stringify(processed)\n return processed as JsonValue\n } catch {\n // If it fails, use the default function\n return defaultFn(processed)\n }\n },\n indent\n )\n } else {\n result = JSON.stringify(obj, replacer, indent)\n }\n /* v8 ignore start -- error handling for invalid JSON @preserve */\n } catch (e) {\n const error = e as Error\n throw new Error(`Object of type ${typeof obj} is not JSON serializable: ${error.message}`)\n }\n /* v8 ignore stop */\n\n // Handle separators if specified\n if (options?.separators) {\n const [itemSep, keySep] = options.separators\n // This is a simplified implementation - full separator support would require custom serialization\n if (itemSep !== \", \" || keySep !== \": \") {\n result = result.replace(/,\\s*/g, itemSep).replace(/:\\s*/g, keySep)\n }\n }\n\n // Handle ensureAscii\n if (ensureAscii) {\n result = result.replace(/[\\u007f-\\uffff]/g, (char) => {\n return \"\\\\u\" + (\"0000\" + char.charCodeAt(0).toString(16)).slice(-4)\n })\n }\n\n return result\n}\n\n/**\n * Deserialize a JSON string to a Python object.\n *\n * @param s - JSON string to parse\n * @param options - Deserialization options\n * @returns Parsed object\n */\nexport function loads(s: string, options?: LoadsOptions): unknown {\n const objectHook = options?.objectHook\n const parseFloat = options?.parseFloatFn\n const parseInt = options?.parseIntFn\n\n let reviver: JsonReviver | undefined\n\n /* v8 ignore start -- advanced custom parser hooks @preserve */\n if (objectHook || parseFloat || parseInt) {\n reviver = (key, value) => {\n if (typeof value === \"number\") {\n const str = String(value)\n if (str.includes(\".\") || str.includes(\"e\") || str.includes(\"E\")) {\n return parseFloat ? parseFloat(str) : value\n }\n return parseInt ? parseInt(str) : value\n }\n if (objectHook && value && typeof value === \"object\" && !Array.isArray(value) && key === \"\") {\n return objectHook(value as Record<string, unknown>)\n }\n return value\n }\n }\n /* v8 ignore stop */\n\n try {\n return JSON.parse(s, reviver)\n } catch (e) {\n const error = e as Error\n throw new Error(`JSON decode error: ${error.message}`)\n }\n}\n\n/**\n * Serialize obj to a JSON formatted string and write to file.\n * Note: This is a no-op in browser environments.\n *\n * @param obj - The object to serialize\n * @param fp - File-like object with write method\n * @param options - Serialization options\n */\nexport function dump(\n obj: unknown,\n fp: { write: (s: string) => void },\n options?: DumpsOptions\n): void {\n const s = dumps(obj, options)\n fp.write(s)\n}\n\n/**\n * Deserialize a JSON string from file to a Python object.\n * Note: This is a no-op in browser environments.\n *\n * @param fp - File-like object with read method\n * @param options - Deserialization options\n * @returns Parsed object\n */\nexport function load(fp: { read: () => string }, options?: LoadsOptions): unknown {\n const s = fp.read()\n return loads(s, options)\n}\n"],"mappings":";;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA0CO,SAAS,MAAM,KAAc,SAAgC;AAClE,QAAM,SAAS,SAAS;AACxB,QAAM,WAAW,SAAS,YAAY;AACtC,QAAM,YAAY,SAAS;AAC3B,QAAM,cAAc,SAAS,eAAe;AAE5C,QAAM,WAAqC,WACvC,CAAC,MAAM,UAAU;AACf,QAAI,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,GAAG;AAC/D,YAAM,SAAkC,CAAC;AACzC,iBAAW,KAAK,OAAO,KAAK,KAAgC,EAAE,KAAK,GAAG;AACpE,eAAO,CAAC,IAAK,MAAkC,CAAC;AAAA,MAClD;AACA,aAAO;AAAA,IACT;AACA,WAAO;AAAA,EACT,IACA;AAEJ,MAAI;AAEJ,MAAI;AACF,QAAI,WAAW;AAEb,eAAS,KAAK;AAAA,QACZ;AAAA,QACA,CAAC,KAAK,UAAmB;AACvB,gBAAM,YAAqB,WAAW,SAAS,KAAK,KAAK,IAAI;AAC7D,cAAI;AAEF,iBAAK,UAAU,SAAS;AACxB,mBAAO;AAAA,UACT,QAAQ;AAEN,mBAAO,UAAU,SAAS;AAAA,UAC5B;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,IACF,OAAO;AACL,eAAS,KAAK,UAAU,KAAK,UAAU,MAAM;AAAA,IAC/C;AAAA,EAEF,SAAS,GAAG;AACV,UAAM,QAAQ;AACd,UAAM,IAAI,MAAM,kBAAkB,OAAO,GAAG,8BAA8B,MAAM,OAAO,EAAE;AAAA,EAC3F;AAIA,MAAI,SAAS,YAAY;AACvB,UAAM,CAAC,SAAS,MAAM,IAAI,QAAQ;AAElC,QAAI,YAAY,QAAQ,WAAW,MAAM;AACvC,eAAS,OAAO,QAAQ,SAAS,OAAO,EAAE,QAAQ,SAAS,MAAM;AAAA,IACnE;AAAA,EACF;AAGA,MAAI,aAAa;AACf,aAAS,OAAO,QAAQ,oBAAoB,CAAC,SAAS;AACpD,aAAO,SAAS,SAAS,KAAK,WAAW,CAAC,EAAE,SAAS,EAAE,GAAG,MAAM,EAAE;AAAA,IACpE,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AASO,SAAS,MAAM,GAAW,SAAiC;AAChE,QAAM,aAAa,SAAS;AAC5B,QAAM,aAAa,SAAS;AAC5B,QAAM,WAAW,SAAS;AAE1B,MAAI;AAGJ,MAAI,cAAc,cAAc,UAAU;AACxC,cAAU,CAAC,KAAK,UAAU;AACxB,UAAI,OAAO,UAAU,UAAU;AAC7B,cAAM,MAAM,OAAO,KAAK;AACxB,YAAI,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,KAAK,IAAI,SAAS,GAAG,GAAG;AAC/D,iBAAO,aAAa,WAAW,GAAG,IAAI;AAAA,QACxC;AACA,eAAO,WAAW,SAAS,GAAG,IAAI;AAAA,MACpC;AACA,UAAI,cAAc,SAAS,OAAO,UAAU,YAAY,CAAC,MAAM,QAAQ,KAAK,KAAK,QAAQ,IAAI;AAC3F,eAAO,WAAW,KAAgC;AAAA,MACpD;AACA,aAAO;AAAA,IACT;AAAA,EACF;AAGA,MAAI;AACF,WAAO,KAAK,MAAM,GAAG,OAAO;AAAA,EAC9B,SAAS,GAAG;AACV,UAAM,QAAQ;AACd,UAAM,IAAI,MAAM,sBAAsB,MAAM,OAAO,EAAE;AAAA,EACvD;AACF;AAUO,SAAS,KACd,KACA,IACA,SACM;AACN,QAAM,IAAI,MAAM,KAAK,OAAO;AAC5B,KAAG,MAAM,CAAC;AACZ;AAUO,SAAS,KAAK,IAA4B,SAAiC;AAChF,QAAM,IAAI,GAAG,KAAK;AAClB,SAAO,MAAM,GAAG,OAAO;AACzB;","names":[]}
|
|
@@ -2,15 +2,15 @@
|
|
|
2
2
|
function escapeRegex(str) {
|
|
3
3
|
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
4
4
|
}
|
|
5
|
-
var
|
|
6
|
-
var
|
|
7
|
-
var
|
|
5
|
+
var asciiLowercase = "abcdefghijklmnopqrstuvwxyz";
|
|
6
|
+
var asciiUppercase = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
|
|
7
|
+
var asciiLetters = asciiLowercase + asciiUppercase;
|
|
8
8
|
var digits = "0123456789";
|
|
9
|
-
var
|
|
10
|
-
var
|
|
9
|
+
var hexDigits = "0123456789abcdefABCDEF";
|
|
10
|
+
var octDigits = "01234567";
|
|
11
11
|
var punctuation = "!\"#$%&'()*+,-./:;<=>?@[\\]^_`{|}~";
|
|
12
12
|
var whitespace = " \n\r\v\f";
|
|
13
|
-
var printable = digits +
|
|
13
|
+
var printable = digits + asciiLetters + punctuation + whitespace;
|
|
14
14
|
var Template = class {
|
|
15
15
|
template;
|
|
16
16
|
constructor(template) {
|
|
@@ -32,7 +32,7 @@ var Template = class {
|
|
|
32
32
|
);
|
|
33
33
|
}
|
|
34
34
|
/** Perform substitution, returning original placeholder for missing keys */
|
|
35
|
-
|
|
35
|
+
safeSubstitute(mapping) {
|
|
36
36
|
const combined = { ...mapping };
|
|
37
37
|
return this.template.replace(
|
|
38
38
|
/\$\$|\$(\w+)|\$\{(\w+)\}/g,
|
|
@@ -47,7 +47,7 @@ var Template = class {
|
|
|
47
47
|
);
|
|
48
48
|
}
|
|
49
49
|
/** Get identifiers in template */
|
|
50
|
-
|
|
50
|
+
getIdentifiers() {
|
|
51
51
|
const identifiers = [];
|
|
52
52
|
const regex = /\$(\w+)|\$\{(\w+)\}/g;
|
|
53
53
|
let match;
|
|
@@ -60,7 +60,7 @@ var Template = class {
|
|
|
60
60
|
return identifiers;
|
|
61
61
|
}
|
|
62
62
|
};
|
|
63
|
-
function
|
|
63
|
+
function capWords(s, sep) {
|
|
64
64
|
const separator = sep ?? " ";
|
|
65
65
|
return s.split(separator).map((word) => {
|
|
66
66
|
if (!word) return "";
|
|
@@ -102,9 +102,9 @@ var string = {
|
|
|
102
102
|
return s.split(sep);
|
|
103
103
|
},
|
|
104
104
|
/**
|
|
105
|
-
* Python str.
|
|
105
|
+
* Python str.rSplit()
|
|
106
106
|
*/
|
|
107
|
-
|
|
107
|
+
rSplit(s, sep, maxsplit) {
|
|
108
108
|
if (sep === void 0) {
|
|
109
109
|
const parts2 = s.trim().split(/\s+/);
|
|
110
110
|
if (maxsplit === void 0) return parts2;
|
|
@@ -131,9 +131,9 @@ var string = {
|
|
|
131
131
|
return s.replace(regex, "");
|
|
132
132
|
},
|
|
133
133
|
/**
|
|
134
|
-
* Python str.
|
|
134
|
+
* Python str.lStrip()
|
|
135
135
|
*/
|
|
136
|
-
|
|
136
|
+
lStrip(s, chars) {
|
|
137
137
|
if (chars === void 0) {
|
|
138
138
|
return s.trimStart();
|
|
139
139
|
}
|
|
@@ -141,9 +141,9 @@ var string = {
|
|
|
141
141
|
return s.replace(regex, "");
|
|
142
142
|
},
|
|
143
143
|
/**
|
|
144
|
-
* Python str.
|
|
144
|
+
* Python str.rStrip()
|
|
145
145
|
*/
|
|
146
|
-
|
|
146
|
+
rStrip(s, chars) {
|
|
147
147
|
if (chars === void 0) {
|
|
148
148
|
return s.trimEnd();
|
|
149
149
|
}
|
|
@@ -176,22 +176,22 @@ var string = {
|
|
|
176
176
|
return s.replace(/\b\w/g, (c) => c.toUpperCase());
|
|
177
177
|
},
|
|
178
178
|
/**
|
|
179
|
-
* Python str.
|
|
179
|
+
* Python str.swapCase()
|
|
180
180
|
*/
|
|
181
|
-
|
|
181
|
+
swapCase(s) {
|
|
182
182
|
return s.split("").map((c) => c === c.toUpperCase() ? c.toLowerCase() : c.toUpperCase()).join("");
|
|
183
183
|
},
|
|
184
184
|
/**
|
|
185
|
-
* Python str.
|
|
185
|
+
* Python str.startsWith()
|
|
186
186
|
*/
|
|
187
|
-
|
|
187
|
+
startsWith(s, prefix, start, end) {
|
|
188
188
|
const substr = s.slice(start, end);
|
|
189
189
|
return substr.startsWith(prefix);
|
|
190
190
|
},
|
|
191
191
|
/**
|
|
192
|
-
* Python str.
|
|
192
|
+
* Python str.endsWith()
|
|
193
193
|
*/
|
|
194
|
-
|
|
194
|
+
endsWith(s, suffix, start, end) {
|
|
195
195
|
const substr = s.slice(start, end);
|
|
196
196
|
return substr.endsWith(suffix);
|
|
197
197
|
},
|
|
@@ -205,9 +205,9 @@ var string = {
|
|
|
205
205
|
return (start ?? 0) + index;
|
|
206
206
|
},
|
|
207
207
|
/**
|
|
208
|
-
* Python str.
|
|
208
|
+
* Python str.rFind()
|
|
209
209
|
*/
|
|
210
|
-
|
|
210
|
+
rFind(s, sub, start, end) {
|
|
211
211
|
const substr = s.slice(start, end);
|
|
212
212
|
const index = substr.lastIndexOf(sub);
|
|
213
213
|
if (index === -1) return -1;
|
|
@@ -224,10 +224,10 @@ var string = {
|
|
|
224
224
|
return result;
|
|
225
225
|
},
|
|
226
226
|
/**
|
|
227
|
-
* Python str.
|
|
227
|
+
* Python str.rIndex() - raises error if not found
|
|
228
228
|
*/
|
|
229
|
-
|
|
230
|
-
const result = string.
|
|
229
|
+
rIndex(s, sub, start, end) {
|
|
230
|
+
const result = string.rFind(s, sub, start, end);
|
|
231
231
|
if (result === -1) {
|
|
232
232
|
throw new Error("substring not found");
|
|
233
233
|
}
|
|
@@ -263,9 +263,9 @@ var string = {
|
|
|
263
263
|
return result;
|
|
264
264
|
},
|
|
265
265
|
/**
|
|
266
|
-
* Python str.
|
|
266
|
+
* Python str.zFill()
|
|
267
267
|
*/
|
|
268
|
-
|
|
268
|
+
zFill(s, width) {
|
|
269
269
|
if (s.length >= width) return s;
|
|
270
270
|
const sign = s[0] === "-" || s[0] === "+" ? s[0] : "";
|
|
271
271
|
const digits2 = sign ? s.slice(1) : s;
|
|
@@ -282,16 +282,16 @@ var string = {
|
|
|
282
282
|
return fillchar.repeat(left) + s + fillchar.repeat(right);
|
|
283
283
|
},
|
|
284
284
|
/**
|
|
285
|
-
* Python str.
|
|
285
|
+
* Python str.lJust()
|
|
286
286
|
*/
|
|
287
|
-
|
|
287
|
+
lJust(s, width, fillchar = " ") {
|
|
288
288
|
if (s.length >= width) return s;
|
|
289
289
|
return s + fillchar.repeat(width - s.length);
|
|
290
290
|
},
|
|
291
291
|
/**
|
|
292
|
-
* Python str.
|
|
292
|
+
* Python str.rJust()
|
|
293
293
|
*/
|
|
294
|
-
|
|
294
|
+
rJust(s, width, fillchar = " ") {
|
|
295
295
|
if (s.length >= width) return s;
|
|
296
296
|
return fillchar.repeat(width - s.length) + s;
|
|
297
297
|
},
|
|
@@ -304,47 +304,47 @@ var string = {
|
|
|
304
304
|
return [s.slice(0, index), sep, s.slice(index + sep.length)];
|
|
305
305
|
},
|
|
306
306
|
/**
|
|
307
|
-
* Python str.
|
|
307
|
+
* Python str.rPartition()
|
|
308
308
|
*/
|
|
309
|
-
|
|
309
|
+
rPartition(s, sep) {
|
|
310
310
|
const index = s.lastIndexOf(sep);
|
|
311
311
|
if (index === -1) return ["", "", s];
|
|
312
312
|
return [s.slice(0, index), sep, s.slice(index + sep.length)];
|
|
313
313
|
},
|
|
314
314
|
/**
|
|
315
|
-
* Python str.
|
|
315
|
+
* Python str.isAlpha()
|
|
316
316
|
*/
|
|
317
|
-
|
|
317
|
+
isAlpha(s) {
|
|
318
318
|
return s.length > 0 && /^[a-zA-Z]+$/.test(s);
|
|
319
319
|
},
|
|
320
320
|
/**
|
|
321
|
-
* Python str.
|
|
321
|
+
* Python str.isDigit()
|
|
322
322
|
*/
|
|
323
|
-
|
|
323
|
+
isDigit(s) {
|
|
324
324
|
return s.length > 0 && /^[0-9]+$/.test(s);
|
|
325
325
|
},
|
|
326
326
|
/**
|
|
327
|
-
* Python str.
|
|
327
|
+
* Python str.isAlnum()
|
|
328
328
|
*/
|
|
329
|
-
|
|
329
|
+
isAlnum(s) {
|
|
330
330
|
return s.length > 0 && /^[a-zA-Z0-9]+$/.test(s);
|
|
331
331
|
},
|
|
332
332
|
/**
|
|
333
|
-
* Python str.
|
|
333
|
+
* Python str.isSpace()
|
|
334
334
|
*/
|
|
335
|
-
|
|
335
|
+
isSpace(s) {
|
|
336
336
|
return s.length > 0 && /^\s+$/.test(s);
|
|
337
337
|
},
|
|
338
338
|
/**
|
|
339
|
-
* Python str.
|
|
339
|
+
* Python str.isUpper()
|
|
340
340
|
*/
|
|
341
|
-
|
|
341
|
+
isUpper(s) {
|
|
342
342
|
return s.length > 0 && s === s.toUpperCase() && s !== s.toLowerCase();
|
|
343
343
|
},
|
|
344
344
|
/**
|
|
345
|
-
* Python str.
|
|
345
|
+
* Python str.isLower()
|
|
346
346
|
*/
|
|
347
|
-
|
|
347
|
+
isLower(s) {
|
|
348
348
|
return s.length > 0 && s === s.toLowerCase() && s !== s.toUpperCase();
|
|
349
349
|
},
|
|
350
350
|
/**
|
|
@@ -360,17 +360,17 @@ var string = {
|
|
|
360
360
|
};
|
|
361
361
|
|
|
362
362
|
export {
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
363
|
+
asciiLowercase,
|
|
364
|
+
asciiUppercase,
|
|
365
|
+
asciiLetters,
|
|
366
366
|
digits,
|
|
367
|
-
|
|
368
|
-
|
|
367
|
+
hexDigits,
|
|
368
|
+
octDigits,
|
|
369
369
|
punctuation,
|
|
370
370
|
whitespace,
|
|
371
371
|
printable,
|
|
372
372
|
Template,
|
|
373
|
-
|
|
373
|
+
capWords,
|
|
374
374
|
string
|
|
375
375
|
};
|
|
376
|
-
//# sourceMappingURL=chunk-
|
|
376
|
+
//# sourceMappingURL=chunk-4QG3772L.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/string.ts"],"sourcesContent":["/**\n * Python string module for TypeScript\n *\n * Provides string constants and utility classes matching Python's string module.\n *\n * @see {@link https://docs.python.org/3/library/string.html | Python string documentation}\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 asciiLowercase = \"abcdefghijklmnopqrstuvwxyz\"\n\n/** The uppercase letters 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' */\nexport const asciiUppercase = \"ABCDEFGHIJKLMNOPQRSTUVWXYZ\"\n\n/** The concatenation of asciiLowercase and asciiUppercase */\nexport const asciiLetters = asciiLowercase + asciiUppercase\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 + asciiLetters + 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 safeSubstitute(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 getIdentifiers(): 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":";AAQA,SAAS,YAAY,KAAqB;AACxC,SAAO,IAAI,QAAQ,uBAAuB,MAAM;AAClD;AAOO,IAAM,iBAAiB;AAGvB,IAAM,iBAAiB;AAGvB,IAAM,eAAe,iBAAiB;AAGtC,IAAM,SAAS;AAGf,IAAM,YAAY;AAGlB,IAAM,YAAY;AAGlB,IAAM,cAAc;AAGpB,IAAM,aAAa;AAGnB,IAAM,YAAY,SAAS,eAAe,cAAc;AAMxD,IAAM,WAAN,MAAe;AAAA,EACX;AAAA,EAET,YAAY,UAAkB;AAC5B,SAAK,WAAW;AAAA,EAClB;AAAA;AAAA,EAGA,WAAW,SAA2C;AACpD,UAAM,WAAW,EAAE,GAAG,QAAQ;AAC9B,WAAO,KAAK,SAAS;AAAA,MACnB;AAAA,MACA,CAAC,OAAO,OAAe,UAAkB;AACvC,YAAI,UAAU,KAAM,QAAO;AAC3B,cAAM,OAAO,SAAS;AACtB,YAAI,EAAE,QAAQ,WAAW;AACvB,gBAAM,IAAI,MAAM,cAAc,IAAI,GAAG;AAAA,QACvC;AACA,eAAO,OAAO,SAAS,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,eAAe,SAA2C;AACxD,UAAM,WAAW,EAAE,GAAG,QAAQ;AAC9B,WAAO,KAAK,SAAS;AAAA,MACnB;AAAA,MACA,CAAC,OAAO,OAAe,UAAkB;AACvC,YAAI,UAAU,KAAM,QAAO;AAC3B,cAAM,OAAO,SAAS;AACtB,YAAI,EAAE,QAAQ,WAAW;AACvB,iBAAO;AAAA,QACT;AACA,eAAO,OAAO,SAAS,IAAI,CAAC;AAAA,MAC9B;AAAA,IACF;AAAA,EACF;AAAA;AAAA,EAGA,iBAA2B;AACzB,UAAM,cAAwB,CAAC;AAC/B,UAAM,QAAQ;AACd,QAAI;AACJ,YAAQ,QAAQ,MAAM,KAAK,KAAK,QAAQ,OAAO,MAAM;AACnD,YAAM,OAAO,MAAM,CAAC,KAAK,MAAM,CAAC;AAChC,UAAI,QAAQ,CAAC,YAAY,SAAS,IAAI,GAAG;AACvC,oBAAY,KAAK,IAAI;AAAA,MACvB;AAAA,IACF;AACA,WAAO;AAAA,EACT;AACF;AAGO,SAAS,SAAS,GAAW,KAAsB;AACxD,QAAM,YAAY,OAAO;AACzB,SAAO,EACJ,MAAM,SAAS,EACf,IAAI,CAAC,SAAS;AACb,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,QAAQ,KAAK,CAAC;AACpB,WAAO,QAAQ,MAAM,YAAY,IAAI,KAAK,MAAM,CAAC,EAAE,YAAY,IAAI;AAAA,EACrE,CAAC,EACA,KAAK,SAAS;AACnB;AAEO,IAAM,SAAS;AAAA;AAAA;AAAA;AAAA,EAIpB,KAAK,KAAa,UAAoC;AACpD,WAAO,MAAM,KAAK,QAAQ,EAAE,KAAK,GAAG;AAAA,EACtC;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,KAAc,UAA6B;AAC1D,QAAI,QAAQ,QAAW;AAErB,YAAM,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK;AACnC,UAAI,aAAa,UAAa,YAAY,GAAG;AAC3C,YAAI,OAAO,SAAS,WAAW,GAAG;AAChC,gBAAM,UAAU,OAAO,MAAM,GAAG,QAAQ;AACxC,kBAAQ,KAAK,OAAO,MAAM,QAAQ,EAAE,KAAK,GAAG,CAAC;AAC7C,iBAAO;AAAA,QACT;AAAA,MACF;AACA,aAAO;AAAA,IACT;AAEA,QAAI,aAAa,UAAa,YAAY,GAAG;AAC3C,YAAM,QAAQ,EAAE,MAAM,GAAG;AACzB,UAAI,MAAM,SAAS,WAAW,GAAG;AAC/B,cAAM,UAAU,MAAM,MAAM,GAAG,QAAQ;AACvC,gBAAQ,KAAK,MAAM,MAAM,QAAQ,EAAE,KAAK,GAAG,CAAC;AAC5C,eAAO;AAAA,MACT;AACA,aAAO;AAAA,IACT;AAEA,WAAO,EAAE,MAAM,GAAG;AAAA,EACpB;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAW,KAAc,UAA6B;AAC3D,QAAI,QAAQ,QAAW;AACrB,YAAMA,SAAQ,EAAE,KAAK,EAAE,MAAM,KAAK;AAClC,UAAI,aAAa,OAAW,QAAOA;AACnC,UAAI,YAAY,EAAG,QAAO,CAAC,CAAC;AAC5B,UAAIA,OAAM,UAAU,WAAW,EAAG,QAAOA;AACzC,YAAMC,QAAOD,OAAM,MAAM,CAAC,QAAQ;AAClC,YAAME,QAAOF,OAAM,MAAM,GAAGA,OAAM,SAAS,QAAQ,EAAE,KAAK,GAAG;AAC7D,aAAO,CAACE,OAAM,GAAGD,KAAI;AAAA,IACvB;AAEA,UAAM,QAAQ,EAAE,MAAM,GAAG;AACzB,QAAI,aAAa,UAAa,MAAM,UAAU,WAAW,EAAG,QAAO;AACnE,UAAM,OAAO,MAAM,MAAM,CAAC,QAAQ;AAClC,UAAM,OAAO,MAAM,MAAM,GAAG,MAAM,SAAS,QAAQ,EAAE,KAAK,GAAG;AAC7D,WAAO,CAAC,MAAM,GAAG,IAAI;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,OAAwB;AACvC,QAAI,UAAU,QAAW;AACvB,aAAO,EAAE,KAAK;AAAA,IAChB;AACA,UAAM,QAAQ,IAAI,OAAO,KAAK,YAAY,KAAK,CAAC,OAAO,YAAY,KAAK,CAAC,OAAO,GAAG;AACnF,WAAO,EAAE,QAAQ,OAAO,EAAE;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAW,OAAwB;AACxC,QAAI,UAAU,QAAW;AACvB,aAAO,EAAE,UAAU;AAAA,IACrB;AACA,UAAM,QAAQ,IAAI,OAAO,KAAK,YAAY,KAAK,CAAC,IAAI;AACpD,WAAO,EAAE,QAAQ,OAAO,EAAE;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAW,OAAwB;AACxC,QAAI,UAAU,QAAW;AACvB,aAAO,EAAE,QAAQ;AAAA,IACnB;AACA,UAAM,QAAQ,IAAI,OAAO,IAAI,YAAY,KAAK,CAAC,KAAK;AACpD,WAAO,EAAE,QAAQ,OAAO,EAAE;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAmB;AACvB,WAAO,EAAE,YAAY;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAmB;AACvB,WAAO,EAAE,YAAY;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,GAAmB;AAC5B,QAAI,EAAE,WAAW,EAAG,QAAO;AAC3B,WAAO,EAAE,OAAO,CAAC,EAAE,YAAY,IAAI,EAAE,MAAM,CAAC,EAAE,YAAY;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAmB;AACvB,WAAO,EAAE,QAAQ,SAAS,CAAC,MAAM,EAAE,YAAY,CAAC;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,GAAmB;AAC1B,WAAO,EACJ,MAAM,EAAE,EACR,IAAI,CAAC,MAAO,MAAM,EAAE,YAAY,IAAI,EAAE,YAAY,IAAI,EAAE,YAAY,CAAE,EACtE,KAAK,EAAE;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,GAAW,QAAgB,OAAgB,KAAuB;AAC3E,UAAM,SAAS,EAAE,MAAM,OAAO,GAAG;AACjC,WAAO,OAAO,WAAW,MAAM;AAAA,EACjC;AAAA;AAAA;AAAA;AAAA,EAKA,SAAS,GAAW,QAAgB,OAAgB,KAAuB;AACzE,UAAM,SAAS,EAAE,MAAM,OAAO,GAAG;AACjC,WAAO,OAAO,SAAS,MAAM;AAAA,EAC/B;AAAA;AAAA;AAAA;AAAA,EAKA,KAAK,GAAW,KAAa,OAAgB,KAAsB;AACjE,UAAM,SAAS,EAAE,MAAM,OAAO,GAAG;AACjC,UAAM,QAAQ,OAAO,QAAQ,GAAG;AAChC,QAAI,UAAU,GAAI,QAAO;AACzB,YAAQ,SAAS,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,KAAa,OAAgB,KAAsB;AAClE,UAAM,SAAS,EAAE,MAAM,OAAO,GAAG;AACjC,UAAM,QAAQ,OAAO,YAAY,GAAG;AACpC,QAAI,UAAU,GAAI,QAAO;AACzB,YAAQ,SAAS,KAAK;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,KAAa,OAAgB,KAAsB;AAClE,UAAM,SAAS,OAAO,KAAK,GAAG,KAAK,OAAO,GAAG;AAC7C,QAAI,WAAW,IAAI;AACjB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAW,KAAa,OAAgB,KAAsB;AACnE,UAAM,SAAS,OAAO,MAAM,GAAG,KAAK,OAAO,GAAG;AAC9C,QAAI,WAAW,IAAI;AACjB,YAAM,IAAI,MAAM,qBAAqB;AAAA,IACvC;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,KAAa,OAAgB,KAAsB;AAClE,UAAM,SAAS,EAAE,MAAM,OAAO,GAAG;AACjC,QAAI,IAAI,WAAW,EAAG,QAAO,OAAO,SAAS;AAC7C,QAAI,QAAQ;AACZ,QAAI,MAAM;AACV,YAAQ,MAAM,OAAO,QAAQ,KAAK,GAAG,OAAO,IAAI;AAC9C;AACA,aAAO,IAAI;AAAA,IACb;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAW,KAAa,QAAgB,OAAwB;AACtE,QAAI,UAAU,UAAa,QAAQ,GAAG;AACpC,aAAO,EAAE,MAAM,GAAG,EAAE,KAAK,MAAM;AAAA,IACjC;AAEA,QAAI,SAAS;AACb,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAM,QAAQ,OAAO,QAAQ,GAAG;AAChC,UAAI,UAAU,GAAI;AAClB,eAAS,OAAO,MAAM,GAAG,KAAK,IAAI,SAAS,OAAO,MAAM,QAAQ,IAAI,MAAM;AAAA,IAC5E;AACA,WAAO;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,OAAuB;AACtC,QAAI,EAAE,UAAU,MAAO,QAAO;AAC9B,UAAM,OAAO,EAAE,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,MAAM,EAAE,CAAC,IAAI;AACnD,UAAME,UAAS,OAAO,EAAE,MAAM,CAAC,IAAI;AACnC,WAAO,OAAOA,QAAO,SAAS,QAAQ,KAAK,QAAQ,GAAG;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,GAAW,OAAe,WAAW,KAAa;AACvD,QAAI,EAAE,UAAU,MAAO,QAAO;AAC9B,UAAM,QAAQ,QAAQ,EAAE;AACxB,UAAM,OAAO,KAAK,MAAM,QAAQ,CAAC;AACjC,UAAM,QAAQ,QAAQ;AACtB,WAAO,SAAS,OAAO,IAAI,IAAI,IAAI,SAAS,OAAO,KAAK;AAAA,EAC1D;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,OAAe,WAAW,KAAa;AACtD,QAAI,EAAE,UAAU,MAAO,QAAO;AAC9B,WAAO,IAAI,SAAS,OAAO,QAAQ,EAAE,MAAM;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,GAAW,OAAe,WAAW,KAAa;AACtD,QAAI,EAAE,UAAU,MAAO,QAAO;AAC9B,WAAO,SAAS,OAAO,QAAQ,EAAE,MAAM,IAAI;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,UAAU,GAAW,KAAuC;AAC1D,UAAM,QAAQ,EAAE,QAAQ,GAAG;AAC3B,QAAI,UAAU,GAAI,QAAO,CAAC,GAAG,IAAI,EAAE;AACnC,WAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,GAAW,KAAuC;AAC3D,UAAM,QAAQ,EAAE,YAAY,GAAG;AAC/B,QAAI,UAAU,GAAI,QAAO,CAAC,IAAI,IAAI,CAAC;AACnC,WAAO,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,KAAK,EAAE,MAAM,QAAQ,IAAI,MAAM,CAAC;AAAA,EAC7D;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,cAAc,KAAK,CAAC;AAAA,EAC7C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,WAAW,KAAK,CAAC;AAAA,EAC1C;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,iBAAiB,KAAK,CAAC;AAAA,EAChD;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,QAAQ,KAAK,CAAC;AAAA,EACvC;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,MAAM,EAAE,YAAY,KAAK,MAAM,EAAE,YAAY;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,QAAQ,GAAoB;AAC1B,WAAO,EAAE,SAAS,KAAK,MAAM,EAAE,YAAY,KAAK,MAAM,EAAE,YAAY;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,MAAc,MAAyB;AAC5C,QAAI,QAAQ;AACZ,WAAO,EAAE,QAAQ,cAAc,CAAC,GAAG,QAAgB;AACjD,YAAM,IAAI,QAAQ,KAAK,UAAU,SAAS,KAAK,EAAE;AACjD,aAAO,OAAO,KAAK,CAAC,CAAC;AAAA,IACvB,CAAC;AAAA,EACH;AACF;","names":["parts","keep","rest","digits"]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/math.ts"],"sourcesContent":["/**\n * Python math module for TypeScript\n *\n * Provides mathematical functions and constants matching Python's math module.\n * Most functions map directly to JavaScript's Math object.\n *\n * @see {@link https://docs.python.org/3/library/math.html | Python math documentation}\n */\n\n// ============================================================================\n// Constants\n// ============================================================================\n\n/** Mathematical constant π = 3.141592... */\nexport const pi = Math.PI\n\n/** Mathematical constant e = 2.718281... */\nexport const e = Math.E\n\n/** Mathematical constant τ = 2π = 6.283185... */\nexport const tau = 2 * Math.PI\n\n/** Positive infinity */\nexport const inf = Infinity\n\n/** Not a Number (NaN) */\nexport const nan = NaN\n\n// ============================================================================\n// Number-theoretic and representation functions\n// ============================================================================\n\n/** Return the ceiling of x, the smallest integer greater than or equal to x */\nexport function ceil(x: number): number {\n return Math.ceil(x)\n}\n\n/** Return the floor of x, the largest integer less than or equal to x */\nexport function floor(x: number): number {\n return Math.floor(x)\n}\n\n/** Return the truncated integer part of x (rounds toward zero) */\nexport function trunc(x: number): number {\n return Math.trunc(x)\n}\n\n/** Return the absolute value of x */\nexport function fabs(x: number): number {\n return Math.abs(x)\n}\n\n/** Return x with the sign of y */\nexport function copysign(x: number, y: number): number {\n const sign = y < 0 || (y === 0 && 1 / y < 0) ? -1 : 1\n return sign * Math.abs(x)\n}\n\n/** Return the fractional and integer parts of x */\nexport function modf(x: number): [number, number] {\n const intPart = Math.trunc(x)\n const fracPart = x - intPart\n return [fracPart, intPart]\n}\n\n/** Return the greatest common divisor of a and b */\nexport function gcd(a: number, b: number): number {\n a = Math.abs(Math.floor(a))\n b = Math.abs(Math.floor(b))\n while (b) {\n const t = b\n b = a % b\n a = t\n }\n return a\n}\n\n/** Return the least common multiple of a and b */\nexport function lcm(a: number, b: number): number {\n if (a === 0 || b === 0) return 0\n return Math.abs(Math.floor(a) * Math.floor(b)) / gcd(a, b)\n}\n\n/** Return True if x is neither infinity nor NaN */\nexport function isfinite(x: number): boolean {\n return Number.isFinite(x)\n}\n\n/** Return True if x is positive or negative infinity */\nexport function isinf(x: number): boolean {\n return !Number.isFinite(x) && !Number.isNaN(x)\n}\n\n/** Return True if x is NaN */\nexport function isnan(x: number): boolean {\n return Number.isNaN(x)\n}\n\n/** Return True if the values a and b are close to each other */\nexport function isclose(\n a: number,\n b: number,\n rel_tol: number = 1e-9,\n abs_tol: number = 0.0\n): boolean {\n return Math.abs(a - b) <= Math.max(rel_tol * Math.max(Math.abs(a), Math.abs(b)), abs_tol)\n}\n\n// ============================================================================\n// Power and logarithmic functions\n// ============================================================================\n\n/** Return e raised to the power x */\nexport function exp(x: number): number {\n return Math.exp(x)\n}\n\n/** Return e raised to the power x, minus 1 (more accurate for small x) */\nexport function expm1(x: number): number {\n return Math.expm1(x)\n}\n\n/** Return the natural logarithm of x */\nexport function log(x: number, base?: number): number {\n if (base === undefined) {\n return Math.log(x)\n }\n return Math.log(x) / Math.log(base)\n}\n\n/** Return the natural logarithm of 1+x (more accurate for small x) */\nexport function log1p(x: number): number {\n return Math.log1p(x)\n}\n\n/** Return the base-2 logarithm of x */\nexport function log2(x: number): number {\n return Math.log2(x)\n}\n\n/** Return the base-10 logarithm of x */\nexport function log10(x: number): number {\n return Math.log10(x)\n}\n\n/** Return x raised to the power y */\nexport function pow(x: number, y: number): number {\n return Math.pow(x, y)\n}\n\n/** Return the square root of x */\nexport function sqrt(x: number): number {\n return Math.sqrt(x)\n}\n\n/** Return the cube root of x */\nexport function cbrt(x: number): number {\n return Math.cbrt(x)\n}\n\n/** Return the Euclidean norm, sqrt(sum(x**2 for x in args)) */\nexport function hypot(...args: number[]): number {\n return Math.hypot(...args)\n}\n\n// ============================================================================\n// Trigonometric functions\n// ============================================================================\n\n/** Return the sine of x (x in radians) */\nexport function sin(x: number): number {\n return Math.sin(x)\n}\n\n/** Return the cosine of x (x in radians) */\nexport function cos(x: number): number {\n return Math.cos(x)\n}\n\n/** Return the tangent of x (x in radians) */\nexport function tan(x: number): number {\n return Math.tan(x)\n}\n\n/** Return the arc sine of x, in radians */\nexport function asin(x: number): number {\n return Math.asin(x)\n}\n\n/** Return the arc cosine of x, in radians */\nexport function acos(x: number): number {\n return Math.acos(x)\n}\n\n/** Return the arc tangent of x, in radians */\nexport function atan(x: number): number {\n return Math.atan(x)\n}\n\n/** Return atan(y / x), in radians. The result is between -π and π */\nexport function atan2(y: number, x: number): number {\n return Math.atan2(y, x)\n}\n\n// ============================================================================\n// Hyperbolic functions\n// ============================================================================\n\n/** Return the hyperbolic sine of x */\nexport function sinh(x: number): number {\n return Math.sinh(x)\n}\n\n/** Return the hyperbolic cosine of x */\nexport function cosh(x: number): number {\n return Math.cosh(x)\n}\n\n/** Return the hyperbolic tangent of x */\nexport function tanh(x: number): number {\n return Math.tanh(x)\n}\n\n/** Return the inverse hyperbolic sine of x */\nexport function asinh(x: number): number {\n return Math.asinh(x)\n}\n\n/** Return the inverse hyperbolic cosine of x */\nexport function acosh(x: number): number {\n return Math.acosh(x)\n}\n\n/** Return the inverse hyperbolic tangent of x */\nexport function atanh(x: number): number {\n return Math.atanh(x)\n}\n\n// ============================================================================\n// Angular conversion\n// ============================================================================\n\n/** Convert angle x from radians to degrees */\nexport function degrees(x: number): number {\n return (x * 180) / Math.PI\n}\n\n/** Convert angle x from degrees to radians */\nexport function radians(x: number): number {\n return (x * Math.PI) / 180\n}\n\n// ============================================================================\n// Special functions\n// ============================================================================\n\n/** Return the factorial of n as an integer */\nexport function factorial(n: number): number {\n n = Math.floor(n)\n if (n < 0) throw new Error(\"factorial() not defined for negative values\")\n if (n === 0 || n === 1) return 1\n let result = 1\n for (let i = 2; i <= n; i++) {\n result *= i\n }\n return result\n}\n\n/** Return the sum of products of values from iterables (dot product) */\nexport function fsum(iterable: Iterable<number>): number {\n // Use Kahan summation for better precision\n let sum = 0\n let c = 0\n for (const x of iterable) {\n const y = x - c\n const t = sum + y\n c = t - sum - y\n sum = t\n }\n return sum\n}\n\n/** Return the product of all elements in the iterable */\nexport function prod(iterable: Iterable<number>, start: number = 1): number {\n let result = start\n for (const x of iterable) {\n result *= x\n }\n return result\n}\n"],"mappings":"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","names":[]}
|