mastracode 0.20.1-alpha.4 → 0.21.0-alpha.8
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/CHANGELOG.md +48 -0
- package/README.md +18 -0
- package/dist/agents/instructions.d.ts.map +1 -1
- package/dist/agents/memory.d.ts.map +1 -1
- package/dist/agents/prompts/agent-instructions.d.ts +1 -1
- package/dist/agents/prompts/agent-instructions.d.ts.map +1 -1
- package/dist/agents/prompts/index.d.ts.map +1 -1
- package/dist/agents/tools.d.ts.map +1 -1
- package/dist/agents/workspace.d.ts +1 -2
- package/dist/agents/workspace.d.ts.map +1 -1
- package/dist/{chunk-BV7BQWMY.js → chunk-5FT2NNFO.js} +40 -23
- package/dist/chunk-5FT2NNFO.js.map +1 -0
- package/dist/{chunk-VSPSFM7I.cjs → chunk-5K3EX2EI.cjs} +1042 -925
- package/dist/chunk-5K3EX2EI.cjs.map +1 -0
- package/dist/{chunk-OFMG5UNQ.cjs → chunk-J3ISOP5J.cjs} +64 -25
- package/dist/chunk-J3ISOP5J.cjs.map +1 -0
- package/dist/{chunk-5SWBONRN.cjs → chunk-QJKDPMZA.cjs} +14 -14
- package/dist/{chunk-5SWBONRN.cjs.map → chunk-QJKDPMZA.cjs.map} +1 -1
- package/dist/{chunk-3FXFMD2Z.js → chunk-RTMEH24Q.js} +3 -3
- package/dist/{chunk-3FXFMD2Z.js.map → chunk-RTMEH24Q.js.map} +1 -1
- package/dist/{chunk-W365KUF7.js → chunk-UKDTDKN4.js} +127 -85
- package/dist/chunk-UKDTDKN4.js.map +1 -0
- package/dist/{chunk-VUHUFCZE.cjs → chunk-US5JFRXN.cjs} +187 -145
- package/dist/chunk-US5JFRXN.cjs.map +1 -0
- package/dist/{chunk-JMQ7TFZB.js → chunk-ZKEXPYKG.js} +144 -27
- package/dist/chunk-ZKEXPYKG.js.map +1 -0
- package/dist/cli.cjs +20 -20
- package/dist/cli.js +4 -4
- package/dist/constants.d.ts +6 -0
- package/dist/constants.d.ts.map +1 -1
- package/dist/hooks/config.d.ts +3 -3
- package/dist/hooks/config.d.ts.map +1 -1
- package/dist/hooks/manager.d.ts +2 -1
- package/dist/hooks/manager.d.ts.map +1 -1
- package/dist/index.cjs +3 -3
- package/dist/index.d.ts +9 -55
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/mcp/config.d.ts +3 -3
- package/dist/mcp/config.d.ts.map +1 -1
- package/dist/mcp/manager.d.ts +1 -1
- package/dist/mcp/manager.d.ts.map +1 -1
- package/dist/schema.d.ts +55 -0
- package/dist/schema.d.ts.map +1 -1
- package/dist/storage-LJRPYE5O.cjs +24 -0
- package/dist/{storage-AX7V35VD.cjs.map → storage-LJRPYE5O.cjs.map} +1 -1
- package/dist/storage-SJM4TJX5.js +3 -0
- package/dist/{storage-6EJTSQCI.js.map → storage-SJM4TJX5.js.map} +1 -1
- package/dist/tools/request-sandbox-access.d.ts +1 -4
- package/dist/tools/request-sandbox-access.d.ts.map +1 -1
- package/dist/tools/utils.d.ts +4 -3
- package/dist/tools/utils.d.ts.map +1 -1
- package/dist/tui/components/ask-question-inline.d.ts.map +1 -1
- package/dist/tui/components/wrapping-select-list.d.ts +28 -0
- package/dist/tui/components/wrapping-select-list.d.ts.map +1 -0
- package/dist/tui/goal-manager.d.ts.map +1 -1
- package/dist/tui/handlers/agent-lifecycle.d.ts.map +1 -1
- package/dist/tui/render-messages.d.ts.map +1 -1
- package/dist/tui/setup.d.ts.map +1 -1
- package/dist/tui/state.d.ts +3 -0
- package/dist/tui/state.d.ts.map +1 -1
- package/dist/tui.cjs +19 -19
- package/dist/tui.js +2 -2
- package/dist/utils/gateway-sync.d.ts.map +1 -1
- package/dist/utils/project.d.ts +3 -3
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/slash-command-loader.d.ts +3 -3
- package/dist/utils/slash-command-loader.d.ts.map +1 -1
- package/dist/utils/slash-command-processor.d.ts.map +1 -1
- package/package.json +9 -9
- package/dist/chunk-BV7BQWMY.js.map +0 -1
- package/dist/chunk-JMQ7TFZB.js.map +0 -1
- package/dist/chunk-OFMG5UNQ.cjs.map +0 -1
- package/dist/chunk-VSPSFM7I.cjs.map +0 -1
- package/dist/chunk-VUHUFCZE.cjs.map +0 -1
- package/dist/chunk-W365KUF7.js.map +0 -1
- package/dist/storage-6EJTSQCI.js +0 -3
- package/dist/storage-AX7V35VD.cjs +0 -24
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,53 @@
|
|
|
1
1
|
# mastracode
|
|
2
2
|
|
|
3
|
+
## 0.21.0-alpha.8
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Mastra Code's `ask_user` interactive picker now wraps long option labels across multiple rows with a `↳` continuation marker, instead of truncating them at the box edge. Arrow keys still navigate item-to-item (not row-to-row), so picking remains predictable when options span multiple lines. ([#17054](https://github.com/mastra-ai/mastra/pull/17054))
|
|
8
|
+
|
|
9
|
+
- Fixed Mastra Code type checking to avoid out-of-memory failures. ([#17070](https://github.com/mastra-ai/mastra/pull/17070))
|
|
10
|
+
|
|
11
|
+
- Updated dependencies [[`9d2c663`](https://github.com/mastra-ai/mastra/commit/9d2c663b88f5b12bc3fea1c97f40b4eeb3665df1), [`c35b962`](https://github.com/mastra-ai/mastra/commit/c35b9625c7e854fcfdeee226a3338a750d0ff211), [`4084113`](https://github.com/mastra-ai/mastra/commit/408411370fc48a822e8b616b3b63f9409774e0e9)]:
|
|
12
|
+
- @mastra/fastembed@1.1.1-alpha.0
|
|
13
|
+
- @mastra/mcp@1.8.1-alpha.0
|
|
14
|
+
- @mastra/memory@1.20.0-alpha.2
|
|
15
|
+
- @mastra/core@1.37.0-alpha.8
|
|
16
|
+
|
|
17
|
+
## 0.21.0-alpha.7
|
|
18
|
+
|
|
19
|
+
### Patch Changes
|
|
20
|
+
|
|
21
|
+
- Updated dependencies [[`168fa09`](https://github.com/mastra-ai/mastra/commit/168fa09d6b39114cb8c13bd06f1dccb9bc81c6cd)]:
|
|
22
|
+
- @mastra/core@1.37.0-alpha.7
|
|
23
|
+
|
|
24
|
+
## 0.21.0-alpha.6
|
|
25
|
+
|
|
26
|
+
### Minor Changes
|
|
27
|
+
|
|
28
|
+
- Added support for overriding Mastra Code's config directory so embedded and programmatic setups can store project configs outside the default `.mastracode` path. ([#13751](https://github.com/mastra-ai/mastra/pull/13751))
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Fixed custom slash commands so unresolved @ references remain literal instead of rendering read errors. ([#17032](https://github.com/mastra-ai/mastra/pull/17032))
|
|
33
|
+
|
|
34
|
+
- Suppressed noisy gateway fetch errors when models.dev is unreachable. The registry no longer retries or logs errors on network failure since all model data is already bundled at publish time. ([#16984](https://github.com/mastra-ai/mastra/pull/16984))
|
|
35
|
+
|
|
36
|
+
- Updated dependencies [[`0cbece9`](https://github.com/mastra-ai/mastra/commit/0cbece9d832cb134a74cdbf3682d390a058215a4), [`7dfe1bc`](https://github.com/mastra-ai/mastra/commit/7dfe1bcfe71d261a6fd6bbf29b1dec49d78fb98f), [`70cb714`](https://github.com/mastra-ai/mastra/commit/70cb7149c8f16f478e15b58498254a53181750a4), [`c86f70d`](https://github.com/mastra-ai/mastra/commit/c86f70d11170c71701daf7b49366cd04d3a3f108), [`7f9da22`](https://github.com/mastra-ai/mastra/commit/7f9da22efd5aa595e138a31de55a5f0f2f28b33d)]:
|
|
37
|
+
- @mastra/core@1.37.0-alpha.6
|
|
38
|
+
- @mastra/observability@1.14.0-alpha.1
|
|
39
|
+
|
|
40
|
+
## 0.20.1-alpha.5
|
|
41
|
+
|
|
42
|
+
### Patch Changes
|
|
43
|
+
|
|
44
|
+
- Fixed mode switching delay — Shift+Tab now updates instantly. Fixed modal lag when opening /om and /models. Fixed duplicate messages appearing when queueing with Ctrl+F. Blocked mode switching while agent is active. ([#17008](https://github.com/mastra-ai/mastra/pull/17008))
|
|
45
|
+
|
|
46
|
+
- Fix Mastra Code TUI crash when ask_user option labels are wider than the terminal — long labels now wrap inside the bordered box, matching how question text already wraps. Reported in #17002. ([#17005](https://github.com/mastra-ai/mastra/pull/17005))
|
|
47
|
+
|
|
48
|
+
- Updated dependencies [[`6096445`](https://github.com/mastra-ai/mastra/commit/60964459733f0ab384584d95e19c36607ffdf7b0), [`91cf0e0`](https://github.com/mastra-ai/mastra/commit/91cf0e027e511b871481a8576b56b7af83b15afd)]:
|
|
49
|
+
- @mastra/core@1.37.0-alpha.5
|
|
50
|
+
|
|
3
51
|
## 0.20.1-alpha.4
|
|
4
52
|
|
|
5
53
|
### Patch Changes
|
package/README.md
CHANGED
|
@@ -169,6 +169,24 @@ Run goal-enabled skills with `/goal/<skill-name>`. Skill instructions become the
|
|
|
169
169
|
|
|
170
170
|
## Configuration
|
|
171
171
|
|
|
172
|
+
### Custom config directory
|
|
173
|
+
|
|
174
|
+
By default, Mastra Code reads and writes project config from `.mastracode/` and global config from `~/.mastracode/` plus `~/.config/mastracode/`.
|
|
175
|
+
|
|
176
|
+
If you embed Mastra Code programmatically, you can override that directory name with `createMastraCode({ configDir: '.your-config-dir' })`.
|
|
177
|
+
|
|
178
|
+
This remaps the project-level and global config locations that Mastra Code uses for MCP server configs, hooks, slash commands, agent instructions, skills, and the legacy `database.json` lookup.
|
|
179
|
+
|
|
180
|
+
```ts
|
|
181
|
+
import { createMastraCode } from 'mastracode';
|
|
182
|
+
|
|
183
|
+
const mastraCode = await createMastraCode({
|
|
184
|
+
configDir: '.acme-code',
|
|
185
|
+
});
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
`configDir` must be a single directory name. Absolute paths, `.` / `..`, and names containing `/` or `\` are rejected.
|
|
189
|
+
|
|
172
190
|
### Project-based threads
|
|
173
191
|
|
|
174
192
|
Threads are automatically scoped to your project based on:
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agents/instructions.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"instructions.d.ts","sourceRoot":"","sources":["../../src/agents/instructions.ts"],"names":[],"mappings":"AAOA,wBAAsB,sBAAsB,CAAC,EAAE,cAAc,EAAE,EAAE;IAAE,cAAc,EAAE;QAAE,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CAAE,mBAuBjH"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../../src/agents/memory.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,sBAAsB,CAAC;AACjE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAC;AAoExC;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,oBAAoB,EAAE,MAAM,CAAC,EAAE,YAAY,IAC3E,oBAAoB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,YA4D/D"}
|
|
@@ -11,7 +11,7 @@ export interface InstructionSource {
|
|
|
11
11
|
* Load all agent instruction files from global and project locations.
|
|
12
12
|
* Returns an array of instruction sources, with global ones first.
|
|
13
13
|
*/
|
|
14
|
-
export declare function loadAgentInstructions(projectPath: string): InstructionSource[];
|
|
14
|
+
export declare function loadAgentInstructions(projectPath: string, configDirName?: string): InstructionSource[];
|
|
15
15
|
export declare function getStaticallyLoadedInstructionPaths(projectPath: string): string[];
|
|
16
16
|
/**
|
|
17
17
|
* Format loaded instructions into a string for the system prompt.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/agent-instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;
|
|
1
|
+
{"version":3,"file":"agent-instructions.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/agent-instructions.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAmBH,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,QAAQ,GAAG,SAAS,CAAC;CAC7B;AAgBD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,aAAa,SAAqB,GAAG,iBAAiB,EAAE,CAiDlH;AAED,wBAAgB,mCAAmC,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,iBAAiB,EAAE,GAAG,MAAM,CAS5E"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAK3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAepE,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/agents/prompts/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAC5C,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAChE,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAK3C,OAAO,KAAK,EAAE,aAAa,IAAI,iBAAiB,EAAE,MAAM,WAAW,CAAC;AAepE,MAAM,WAAW,aAAc,SAAQ,IAAI,CAAC,iBAAiB,EAAE,cAAc,CAAC;IAC5E,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,CAAC,EAAE,GAAG,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB;AAQD;;;GAGG;AACH,wBAAgB,eAAe,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAgE1D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/agents/tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;
|
|
1
|
+
{"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/agents/tools.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC5C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAIzC,4DAA4D;AAC5D,KAAK,QAAQ,GAAG;IACd,OAAO,CAAC,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,GAAG,OAAO,CAAC;CAC1D,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAmCxB,wBAAgB,kBAAkB,CAChC,UAAU,CAAC,EAAE,UAAU,EACvB,UAAU,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAC/G,WAAW,CAAC,EAAE,WAAW,EACzB,aAAa,CAAC,EAAE,MAAM,EAAE,IAEQ,oBAAoB;IAAE,cAAc,EAAE,cAAc,CAAA;CAAE,8BA+DvF"}
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import type { Mastra } from '@mastra/core/mastra';
|
|
2
2
|
import type { RequestContext } from '@mastra/core/request-context';
|
|
3
3
|
import { Workspace, LocalFilesystem, LocalSandbox } from '@mastra/core/workspace';
|
|
4
|
-
export declare
|
|
5
|
-
export declare const allowedSkillPaths: string[];
|
|
4
|
+
export declare function buildSkillPaths(projectPath: string, configDir: string): string[];
|
|
6
5
|
export declare function getDynamicWorkspace({ requestContext, mastra }: {
|
|
7
6
|
requestContext: RequestContext;
|
|
8
7
|
mastra?: Mastra;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/agents/workspace.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,8BAA8B,CAAC;AACnE,OAAO,EAAE,SAAS,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAiFlF,wBAAgB,eAAe,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,MAAM,EAAE,CAchF;AA2BD,wBAAgB,mBAAmB,CAAC,EAAE,cAAc,EAAE,MAAM,EAAE,EAAE;IAAE,cAAc,EAAE,cAAc,CAAC;IAAC,MAAM,CAAC,EAAE,MAAM,CAAA;CAAE,uDA8DlH"}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import fs, { existsSync, readFileSync, mkdirSync, writeFileSync, chmodSync } from 'fs';
|
|
2
|
-
import
|
|
2
|
+
import * as path2 from 'path';
|
|
3
|
+
import path2__default, { join, dirname } from 'path';
|
|
3
4
|
import { execFile, execSync } from 'child_process';
|
|
4
5
|
import { createHash } from 'crypto';
|
|
5
6
|
import os from 'os';
|
|
6
7
|
|
|
7
8
|
// src/auth/storage.ts
|
|
9
|
+
var DEFAULT_CONFIG_DIR = ".mastracode";
|
|
10
|
+
function validateConfigDirName(configDirName) {
|
|
11
|
+
if (configDirName.trim().length === 0) {
|
|
12
|
+
throw new Error("configDirName must be a non-empty directory name");
|
|
13
|
+
}
|
|
14
|
+
if (path2.isAbsolute(configDirName) || configDirName.includes("/") || configDirName.includes("\\") || configDirName === ".." || configDirName === ".") {
|
|
15
|
+
throw new Error(
|
|
16
|
+
`configDirName must be a single directory name without path separators or traversal components, got: "${configDirName}"`
|
|
17
|
+
);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
var DEFAULT_OM_MODEL_ID = process.env.DEFAULT_OM_MODEL_ID ?? "google/gemini-2.5-flash";
|
|
21
|
+
var DEFAULT_OBS_THRESHOLD = 3e4;
|
|
22
|
+
var DEFAULT_REF_THRESHOLD = 4e4;
|
|
23
|
+
|
|
24
|
+
// src/utils/project.ts
|
|
8
25
|
function git(args, cwd) {
|
|
9
26
|
try {
|
|
10
27
|
return execSync(`git ${args}`, {
|
|
@@ -26,7 +43,7 @@ function normalizeGitUrl(url) {
|
|
|
26
43
|
return url.replace(/\.git$/, "").replace(/^git@([^:]+):/, "https://$1/").replace(/^ssh:\/\/git@/, "https://").toLowerCase();
|
|
27
44
|
}
|
|
28
45
|
function detectProject(projectPath) {
|
|
29
|
-
const absolutePath =
|
|
46
|
+
const absolutePath = path2__default.resolve(projectPath);
|
|
30
47
|
const gitDir = git("rev-parse --git-dir", absolutePath);
|
|
31
48
|
const isGitRepo = gitDir !== void 0;
|
|
32
49
|
let rootPath = absolutePath;
|
|
@@ -39,7 +56,7 @@ function detectProject(projectPath) {
|
|
|
39
56
|
const commonDir = git("rev-parse --git-common-dir", absolutePath);
|
|
40
57
|
if (commonDir && commonDir !== ".git" && commonDir !== gitDir) {
|
|
41
58
|
isWorktree = true;
|
|
42
|
-
mainRepoPath =
|
|
59
|
+
mainRepoPath = path2__default.dirname(path2__default.resolve(rootPath, commonDir));
|
|
43
60
|
}
|
|
44
61
|
gitUrl = git("remote get-url origin", absolutePath);
|
|
45
62
|
if (!gitUrl) {
|
|
@@ -61,7 +78,7 @@ function detectProject(projectPath) {
|
|
|
61
78
|
} else {
|
|
62
79
|
resourceIdSource = rootPath;
|
|
63
80
|
}
|
|
64
|
-
const baseName = gitUrl ? gitUrl.split("/").pop()?.replace(/\.git$/, "") || "project" :
|
|
81
|
+
const baseName = gitUrl ? gitUrl.split("/").pop()?.replace(/\.git$/, "") || "project" : path2__default.basename(rootPath);
|
|
65
82
|
const resourceId = `${slugify(baseName)}-${shortHash(resourceIdSource)}`;
|
|
66
83
|
return {
|
|
67
84
|
resourceId,
|
|
@@ -89,13 +106,13 @@ function getAppDataDir() {
|
|
|
89
106
|
const platform = os.platform();
|
|
90
107
|
let baseDir;
|
|
91
108
|
if (platform === "darwin") {
|
|
92
|
-
baseDir =
|
|
109
|
+
baseDir = path2__default.join(os.homedir(), "Library", "Application Support");
|
|
93
110
|
} else if (platform === "win32") {
|
|
94
|
-
baseDir = process.env.APPDATA ||
|
|
111
|
+
baseDir = process.env.APPDATA || path2__default.join(os.homedir(), "AppData", "Roaming");
|
|
95
112
|
} else {
|
|
96
|
-
baseDir = process.env.XDG_DATA_HOME ||
|
|
113
|
+
baseDir = process.env.XDG_DATA_HOME || path2__default.join(os.homedir(), ".local", "share");
|
|
97
114
|
}
|
|
98
|
-
const appDir =
|
|
115
|
+
const appDir = path2__default.join(baseDir, "mastracode");
|
|
99
116
|
if (!fs.existsSync(appDir)) {
|
|
100
117
|
fs.mkdirSync(appDir, { recursive: true });
|
|
101
118
|
}
|
|
@@ -105,18 +122,18 @@ function getDatabasePath() {
|
|
|
105
122
|
if (process.env.MASTRA_DB_PATH) {
|
|
106
123
|
return process.env.MASTRA_DB_PATH;
|
|
107
124
|
}
|
|
108
|
-
return
|
|
125
|
+
return path2__default.join(getAppDataDir(), "mastra.db");
|
|
109
126
|
}
|
|
110
127
|
function getVectorDatabasePath() {
|
|
111
|
-
return
|
|
128
|
+
return path2__default.join(getAppDataDir(), "mastra-vectors.db");
|
|
112
129
|
}
|
|
113
130
|
function getObservabilityDatabasePath() {
|
|
114
131
|
if (process.env.MASTRA_OBSERVABILITY_DB_PATH) {
|
|
115
132
|
return process.env.MASTRA_OBSERVABILITY_DB_PATH;
|
|
116
133
|
}
|
|
117
|
-
return
|
|
134
|
+
return path2__default.join(getAppDataDir(), "observability.duckdb");
|
|
118
135
|
}
|
|
119
|
-
function getStorageConfig(projectDir, storageSettings) {
|
|
136
|
+
function getStorageConfig(projectDir, storageSettings, configDirName = DEFAULT_CONFIG_DIR) {
|
|
120
137
|
const envBackend = process.env.MASTRA_STORAGE_BACKEND;
|
|
121
138
|
if (envBackend === "pg") {
|
|
122
139
|
return resolvePgFromEnv();
|
|
@@ -136,10 +153,10 @@ function getStorageConfig(projectDir, storageSettings) {
|
|
|
136
153
|
};
|
|
137
154
|
}
|
|
138
155
|
if (projectDir) {
|
|
139
|
-
const projectConfig = loadDatabaseConfig(
|
|
156
|
+
const projectConfig = loadDatabaseConfig(path2__default.join(projectDir, configDirName, "database.json"));
|
|
140
157
|
if (projectConfig) return projectConfig;
|
|
141
158
|
}
|
|
142
|
-
const globalConfig = loadDatabaseConfig(
|
|
159
|
+
const globalConfig = loadDatabaseConfig(path2__default.join(os.homedir(), configDirName, "database.json"));
|
|
143
160
|
if (globalConfig) return globalConfig;
|
|
144
161
|
return {
|
|
145
162
|
backend: "libsql",
|
|
@@ -227,16 +244,16 @@ function getUserName(projectDir) {
|
|
|
227
244
|
}
|
|
228
245
|
return os.userInfo().username || "unknown";
|
|
229
246
|
}
|
|
230
|
-
function getOmScope(projectDir) {
|
|
247
|
+
function getOmScope(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
|
|
231
248
|
const envScope = process.env.MASTRA_OM_SCOPE;
|
|
232
249
|
if (envScope === "thread" || envScope === "resource") {
|
|
233
250
|
return envScope;
|
|
234
251
|
}
|
|
235
252
|
if (projectDir) {
|
|
236
|
-
const scope2 = loadOmScopeFromConfig(
|
|
253
|
+
const scope2 = loadOmScopeFromConfig(path2__default.join(projectDir, configDirName, "database.json"));
|
|
237
254
|
if (scope2) return scope2;
|
|
238
255
|
}
|
|
239
|
-
const scope = loadOmScopeFromConfig(
|
|
256
|
+
const scope = loadOmScopeFromConfig(path2__default.join(os.homedir(), configDirName, "database.json"));
|
|
240
257
|
if (scope) return scope;
|
|
241
258
|
return "thread";
|
|
242
259
|
}
|
|
@@ -253,15 +270,15 @@ function loadOmScopeFromConfig(filePath) {
|
|
|
253
270
|
return null;
|
|
254
271
|
}
|
|
255
272
|
}
|
|
256
|
-
function getResourceIdOverride(projectDir) {
|
|
273
|
+
function getResourceIdOverride(projectDir, configDirName = DEFAULT_CONFIG_DIR) {
|
|
257
274
|
if (process.env.MASTRA_RESOURCE_ID) {
|
|
258
275
|
return process.env.MASTRA_RESOURCE_ID;
|
|
259
276
|
}
|
|
260
277
|
if (projectDir) {
|
|
261
|
-
const rid2 = loadStringField(
|
|
278
|
+
const rid2 = loadStringField(path2__default.join(projectDir, configDirName, "database.json"), "resourceId");
|
|
262
279
|
if (rid2) return rid2;
|
|
263
280
|
}
|
|
264
|
-
const rid = loadStringField(
|
|
281
|
+
const rid = loadStringField(path2__default.join(os.homedir(), configDirName, "database.json"), "resourceId");
|
|
265
282
|
if (rid) return rid;
|
|
266
283
|
return null;
|
|
267
284
|
}
|
|
@@ -1368,6 +1385,6 @@ var AuthStorage = class {
|
|
|
1368
1385
|
}
|
|
1369
1386
|
};
|
|
1370
1387
|
|
|
1371
|
-
export { AuthStorage, COPILOT_HEADERS, PROVIDER_DEFAULT_MODELS, detectProject, fetchCopilotModels, getAppDataDir, getCurrentGitBranchAsync, getDatabasePath, getGitHubCopilotBaseUrl, getOAuthProvider, getOAuthProviders, getObservabilityDatabasePath, getOmScope, getResourceIdOverride, getStorageConfig, getUserId, getUserName, getVectorDatabasePath };
|
|
1372
|
-
//# sourceMappingURL=chunk-
|
|
1373
|
-
//# sourceMappingURL=chunk-
|
|
1388
|
+
export { AuthStorage, COPILOT_HEADERS, DEFAULT_CONFIG_DIR, DEFAULT_OBS_THRESHOLD, DEFAULT_OM_MODEL_ID, DEFAULT_REF_THRESHOLD, PROVIDER_DEFAULT_MODELS, detectProject, fetchCopilotModels, getAppDataDir, getCurrentGitBranchAsync, getDatabasePath, getGitHubCopilotBaseUrl, getOAuthProvider, getOAuthProviders, getObservabilityDatabasePath, getOmScope, getResourceIdOverride, getStorageConfig, getUserId, getUserName, getVectorDatabasePath, validateConfigDirName };
|
|
1389
|
+
//# sourceMappingURL=chunk-5FT2NNFO.js.map
|
|
1390
|
+
//# sourceMappingURL=chunk-5FT2NNFO.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/constants.ts","../src/utils/project.ts","../src/auth/pkce.ts","../src/auth/providers/anthropic.ts","../src/auth/providers/github-copilot.ts","../src/auth/providers/openai-codex.ts","../src/auth/storage.ts"],"names":["path","scope","rid","decode","CLIENT_ID","AUTHORIZE_URL","TOKEN_URL"],"mappings":";;;;;;;;AAGO,IAAM,kBAAA,GAAqB;AAM3B,SAAS,sBAAsB,aAAA,EAA6B;AACjE,EAAA,IAAI,aAAA,CAAc,IAAA,EAAK,CAAE,MAAA,KAAW,CAAA,EAAG;AACrC,IAAA,MAAM,IAAI,MAAM,kDAAkD,CAAA;AAAA,EACpE;AAEA,EAAA,IACOA,KAAA,CAAA,UAAA,CAAW,aAAa,CAAA,IAC7B,aAAA,CAAc,SAAS,GAAG,CAAA,IAC1B,aAAA,CAAc,QAAA,CAAS,IAAI,CAAA,IAC3B,aAAA,KAAkB,IAAA,IAClB,kBAAkB,GAAA,EAClB;AACA,IAAA,MAAM,IAAI,KAAA;AAAA,MACR,wGAAwG,aAAa,CAAA,CAAA;AAAA,KACvH;AAAA,EACF;AACF;AAGO,IAAM,mBAAA,GAAsB,OAAA,CAAQ,GAAA,CAAI,mBAAA,IAAuB;AAG/D,IAAM,qBAAA,GAAwB;AAC9B,IAAM,qBAAA,GAAwB;;;ACGrC,SAAS,GAAA,CAAI,MAAc,GAAA,EAAiC;AAC1D,EAAA,IAAI;AACF,IAAA,OAAO,QAAA,CAAS,CAAA,IAAA,EAAO,IAAI,CAAA,CAAA,EAAI;AAAA,MAC7B,GAAA;AAAA,MACA,QAAA,EAAU,OAAA;AAAA,MACV,KAAA,EAAO,CAAC,MAAA,EAAQ,MAAA,EAAQ,MAAM;AAAA,KAC/B,EAAE,IAAA,EAAK;AAAA,EACV,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,MAAA;AAAA,EACT;AACF;AAKA,SAAS,QAAQ,GAAA,EAAqB;AACpC,EAAA,OAAO,GAAA,CACJ,aAAY,CACZ,OAAA,CAAQ,eAAe,GAAG,CAAA,CAC1B,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA;AACzB;AAKA,SAAS,UAAU,GAAA,EAAqB;AACtC,EAAA,OAAO,UAAA,CAAW,QAAQ,CAAA,CAAE,MAAA,CAAO,GAAG,CAAA,CAAE,MAAA,CAAO,KAAK,CAAA,CAAE,KAAA,CAAM,CAAA,EAAG,EAAE,CAAA;AACnE;AAQA,SAAS,gBAAgB,GAAA,EAAqB;AAC5C,EAAA,OAAO,GAAA,CACJ,OAAA,CAAQ,QAAA,EAAU,EAAE,CAAA,CACpB,OAAA,CAAQ,eAAA,EAAiB,aAAa,CAAA,CACtC,OAAA,CAAQ,eAAA,EAAiB,UAAU,EACnC,WAAA,EAAY;AACjB;AAKO,SAAS,cAAc,WAAA,EAAkC;AAC9D,EAAA,MAAM,YAAA,GAAeA,cAAAA,CAAK,OAAA,CAAQ,WAAW,CAAA;AAG7C,EAAA,MAAM,MAAA,GAAS,GAAA,CAAI,qBAAA,EAAuB,YAAY,CAAA;AACtD,EAAA,MAAM,YAAY,MAAA,KAAW,MAAA;AAE7B,EAAA,IAAI,QAAA,GAAW,YAAA;AACf,EAAA,IAAI,MAAA;AACJ,EAAA,IAAI,SAAA;AACJ,EAAA,IAAI,UAAA,GAAa,KAAA;AACjB,EAAA,IAAI,YAAA;AAEJ,EAAA,IAAI,SAAA,EAAW;AAEb,IAAA,QAAA,GAAW,GAAA,CAAI,2BAAA,EAA6B,YAAY,CAAA,IAAK,YAAA;AAG7D,IAAA,MAAM,SAAA,GAAY,GAAA,CAAI,4BAAA,EAA8B,YAAY,CAAA;AAChE,IAAA,IAAI,SAAA,IAAa,SAAA,KAAc,MAAA,IAAU,SAAA,KAAc,MAAA,EAAQ;AAC7D,MAAA,UAAA,GAAa,IAAA;AAEb,MAAA,YAAA,GAAeA,eAAK,OAAA,CAAQA,cAAAA,CAAK,OAAA,CAAQ,QAAA,EAAU,SAAS,CAAC,CAAA;AAAA,IAC/D;AAGA,IAAA,MAAA,GAAS,GAAA,CAAI,yBAAyB,YAAY,CAAA;AAClD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,MAAM,OAAA,GAAU,GAAA,CAAI,QAAA,EAAU,YAAY,CAAA;AAC1C,MAAA,IAAI,OAAA,EAAS;AACX,QAAA,MAAM,WAAA,GAAc,OAAA,CAAQ,KAAA,CAAM,IAAI,EAAE,CAAC,CAAA;AACzC,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAA,GAAS,GAAA,CAAI,CAAA,eAAA,EAAkB,WAAW,CAAA,CAAA,EAAI,YAAY,CAAA;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AAGA,IAAA,SAAA,GAAY,GAAA,CAAI,+BAA+B,YAAY,CAAA;AAAA,EAC7D;AAIA,EAAA,IAAI,gBAAA;AACJ,EAAA,IAAI,MAAA,EAAQ;AACV,IAAA,gBAAA,GAAmB,gBAAgB,MAAM,CAAA;AAAA,EAC3C,WAAW,YAAA,EAAc;AACvB,IAAA,gBAAA,GAAmB,YAAA;AAAA,EACrB,CAAA,MAAO;AACL,IAAA,gBAAA,GAAmB,QAAA;AAAA,EACrB;AAIA,EAAA,MAAM,QAAA,GAAW,MAAA,GACb,MAAA,CACG,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,EAAI,EACH,OAAA,CAAQ,UAAU,EAAE,CAAA,IAAK,SAAA,GAC7BA,cAAAA,CAAK,SAAS,QAAQ,CAAA;AAE1B,EAAA,MAAM,UAAA,GAAa,GAAG,OAAA,CAAQ,QAAQ,CAAC,CAAA,CAAA,EAAI,SAAA,CAAU,gBAAgB,CAAC,CAAA,CAAA;AAEtE,EAAA,OAAO;AAAA,IACL,UAAA;AAAA,IACA,IAAA,EAAM,QAAA;AAAA,IACN,QAAA;AAAA,IACA,MAAA;AAAA,IACA,SAAA;AAAA,IACA,UAAA;AAAA,IACA;AAAA,GACF;AACF;AAcO,SAAS,yBAAyB,GAAA,EAA0C;AACjF,EAAA,OAAO,IAAI,QAAQ,CAAA,OAAA,KAAW;AAC5B,IAAA,QAAA,CAAS,KAAA,EAAO,CAAC,WAAA,EAAa,cAAA,EAAgB,MAAM,CAAA,EAAG,EAAE,GAAA,EAAK,QAAA,EAAU,OAAA,EAAQ,EAAG,CAAC,KAAK,MAAA,KAAW;AAClG,MAAA,IAAI,GAAA,EAAK;AACP,QAAA,OAAA,CAAQ,MAAS,CAAA;AACjB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,MAAA,GAAS,OAAO,IAAA,EAAK;AAC3B,MAAA,OAAA,CAAQ,UAAU,MAAS,CAAA;AAAA,IAC7B,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAQO,SAAS,aAAA,GAAwB;AACtC,EAAA,MAAM,QAAA,GAAW,GAAG,QAAA,EAAS;AAC7B,EAAA,IAAI,OAAA;AAEJ,EAAA,IAAI,aAAa,QAAA,EAAU;AACzB,IAAA,OAAA,GAAUA,eAAK,IAAA,CAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,WAAW,qBAAqB,CAAA;AAAA,EACpE,CAAA,MAAA,IAAW,aAAa,OAAA,EAAS;AAC/B,IAAA,OAAA,GAAU,OAAA,CAAQ,IAAI,OAAA,IAAWA,cAAAA,CAAK,KAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,SAAA,EAAW,SAAS,CAAA;AAAA,EAC/E,CAAA,MAAO;AAEL,IAAA,OAAA,GAAU,OAAA,CAAQ,IAAI,aAAA,IAAiBA,cAAAA,CAAK,KAAK,EAAA,CAAG,OAAA,EAAQ,EAAG,QAAA,EAAU,OAAO,CAAA;AAAA,EAClF;AAEA,EAAA,MAAM,MAAA,GAASA,cAAAA,CAAK,IAAA,CAAK,OAAA,EAAS,YAAY,CAAA;AAG9C,EAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,MAAM,CAAA,EAAG;AAC1B,IAAA,EAAA,CAAG,SAAA,CAAU,MAAA,EAAQ,EAAE,SAAA,EAAW,MAAM,CAAA;AAAA,EAC1C;AAEA,EAAA,OAAO,MAAA;AACT;AAKO,SAAS,eAAA,GAA0B;AACxC,EAAA,IAAI,OAAA,CAAQ,IAAI,cAAA,EAAgB;AAC9B,IAAA,OAAO,QAAQ,GAAA,CAAI,cAAA;AAAA,EACrB;AACA,EAAA,OAAOA,cAAAA,CAAK,IAAA,CAAK,aAAA,EAAc,EAAG,WAAW,CAAA;AAC/C;AAMO,SAAS,qBAAA,GAAgC;AAC9C,EAAA,OAAOA,cAAAA,CAAK,IAAA,CAAK,aAAA,EAAc,EAAG,mBAAmB,CAAA;AACvD;AAOO,SAAS,4BAAA,GAAuC;AACrD,EAAA,IAAI,OAAA,CAAQ,IAAI,4BAAA,EAA8B;AAC5C,IAAA,OAAO,QAAQ,GAAA,CAAI,4BAAA;AAAA,EACrB;AACA,EAAA,OAAOA,cAAAA,CAAK,IAAA,CAAK,aAAA,EAAc,EAAG,sBAAsB,CAAA;AAC1D;AAoDO,SAAS,gBAAA,CACd,UAAA,EACA,eAAA,EACA,aAAA,GAAgB,kBAAA,EACD;AAEf,EAAA,MAAM,UAAA,GAAa,QAAQ,GAAA,CAAI,sBAAA;AAE/B,EAAA,IAAI,eAAe,IAAA,EAAM;AACvB,IAAA,OAAO,gBAAA,EAAiB;AAAA,EAC1B;AAGA,EAAA,IAAI,UAAA,KAAe,QAAA,IAAY,OAAA,CAAQ,GAAA,CAAI,aAAA,EAAe;AACxD,IAAA,OAAO,oBAAA,EAAqB;AAAA,EAC9B;AAGA,EAAA,IAAI,eAAA,IAAmB,eAAA,CAAgB,OAAA,KAAY,IAAA,EAAM;AACvD,IAAA,OAAO,sBAAsB,eAAe,CAAA;AAAA,EAC9C;AAEA,EAAA,IAAI,mBAAmB,eAAA,CAAgB,OAAA,KAAY,QAAA,IAAY,eAAA,CAAgB,OAAO,GAAA,EAAK;AACzF,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,QAAA;AAAA,MACT,GAAA,EAAK,gBAAgB,MAAA,CAAO,GAAA;AAAA,MAC5B,SAAA,EAAW,gBAAgB,MAAA,CAAO,SAAA;AAAA,MAClC,UAAU,CAAC,eAAA,CAAgB,MAAA,CAAO,GAAA,CAAI,WAAW,OAAO;AAAA,KAC1D;AAAA,EACF;AAGA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAM,gBAAgB,kBAAA,CAAmBA,cAAAA,CAAK,KAAK,UAAA,EAAY,aAAA,EAAe,eAAe,CAAC,CAAA;AAC9F,IAAA,IAAI,eAAe,OAAO,aAAA;AAAA,EAC5B;AACA,EAAA,MAAM,YAAA,GAAe,mBAAmBA,cAAAA,CAAK,IAAA,CAAK,GAAG,OAAA,EAAQ,EAAG,aAAA,EAAe,eAAe,CAAC,CAAA;AAC/F,EAAA,IAAI,cAAc,OAAO,YAAA;AAGzB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,QAAA;AAAA,IACT,GAAA,EAAK,CAAA,KAAA,EAAQ,eAAA,EAAiB,CAAA,CAAA;AAAA,IAC9B,QAAA,EAAU;AAAA,GACZ;AACF;AAEA,SAAS,oBAAA,GAA4C;AACnD,EAAA,MAAM,GAAA,GAAM,QAAQ,GAAA,CAAI,aAAA;AACxB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,QAAA;AAAA,IACT,GAAA;AAAA,IACA,SAAA,EAAW,QAAQ,GAAA,CAAI,oBAAA;AAAA,IACvB,QAAA,EAAU,CAAC,GAAA,CAAI,UAAA,CAAW,OAAO;AAAA,GACnC;AACF;AAEA,SAAS,gBAAA,GAAoC;AAC3C,EAAA,MAAM,gBAAA,GAAmB,QAAQ,GAAA,CAAI,2BAAA;AACrC,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,OAAO;AAAA,MACL,OAAA,EAAS,IAAA;AAAA,MACT,gBAAA;AAAA,MACA,UAAA,EAAY,QAAQ,GAAA,CAAI;AAAA,KAC1B;AAAA,EACF;AAGA,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,IAAA,EAAM,QAAQ,GAAA,CAAI,cAAA;AAAA,IAClB,IAAA,EAAM,QAAQ,GAAA,CAAI,cAAA,GAAiB,SAAS,OAAA,CAAQ,GAAA,CAAI,cAAA,EAAgB,EAAE,CAAA,GAAI,MAAA;AAAA,IAC9E,QAAA,EAAU,QAAQ,GAAA,CAAI,kBAAA;AAAA,IACtB,IAAA,EAAM,QAAQ,GAAA,CAAI,cAAA;AAAA,IAClB,QAAA,EAAU,QAAQ,GAAA,CAAI,kBAAA;AAAA,IACtB,UAAA,EAAY,QAAQ,GAAA,CAAI;AAAA,GAC1B;AACF;AAEA,SAAS,sBAAsB,QAAA,EAA4C;AACzE,EAAA,MAAM,KAAK,QAAA,CAAS,EAAA;AACpB,EAAA,OAAO;AAAA,IACL,OAAA,EAAS,IAAA;AAAA,IACT,kBAAkB,EAAA,CAAG,gBAAA;AAAA,IACrB,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,MAAM,EAAA,CAAG,IAAA;AAAA,IACT,UAAU,EAAA,CAAG,QAAA;AAAA,IACb,YAAY,EAAA,CAAG,UAAA;AAAA,IACf,aAAa,EAAA,CAAG,WAAA;AAAA,IAChB,oBAAoB,EAAA,CAAG;AAAA,GACzB;AACF;AAMA,SAAS,mBAAmB,QAAA,EAA8C;AACxE,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,QAAQ,GAAG,OAAO,IAAA;AACrC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,OAAO,MAAA,EAAQ,GAAA,KAAQ,QAAA,IAAY,OAAO,GAAA,EAAK;AACjD,MAAA,OAAO;AAAA,QACL,OAAA,EAAS,QAAA;AAAA,QACT,KAAK,MAAA,CAAO,GAAA;AAAA,QACZ,WAAW,OAAO,MAAA,CAAO,SAAA,KAAc,QAAA,GAAW,OAAO,SAAA,GAAY,MAAA;AAAA,QACrE,QAAA,EAAU,CAAC,MAAA,CAAO,GAAA,CAAI,WAAW,OAAO;AAAA,OAC1C;AAAA,IACF;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAUO,SAAS,UAAU,UAAA,EAA6B;AAErD,EAAA,IAAI,OAAA,CAAQ,IAAI,cAAA,EAAgB;AAC9B,IAAA,OAAO,QAAQ,GAAA,CAAI,cAAA;AAAA,EACrB;AAGA,EAAA,MAAM,GAAA,GAAM,UAAA,IAAc,OAAA,CAAQ,GAAA,EAAI;AACtC,EAAA,MAAM,KAAA,GAAQ,GAAA,CAAI,mBAAA,EAAqB,GAAG,CAAA;AAC1C,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,OAAO,KAAA;AAAA,EACT;AAGA,EAAA,OAAO,EAAA,CAAG,QAAA,EAAS,CAAE,QAAA,IAAY,SAAA;AACnC;AASO,SAAS,YAAY,UAAA,EAA6B;AACvD,EAAA,MAAM,GAAA,GAAM,UAAA,IAAc,OAAA,CAAQ,GAAA,EAAI;AACtC,EAAA,MAAM,IAAA,GAAO,GAAA,CAAI,kBAAA,EAAoB,GAAG,CAAA;AACxC,EAAA,IAAI,IAAA,EAAM;AACR,IAAA,OAAO,IAAA;AAAA,EACT;AACA,EAAA,OAAO,EAAA,CAAG,QAAA,EAAS,CAAE,QAAA,IAAY,SAAA;AACnC;AAgBO,SAAS,UAAA,CAAW,UAAA,EAAqB,aAAA,GAAgB,kBAAA,EAA6B;AAE3F,EAAA,MAAM,QAAA,GAAW,QAAQ,GAAA,CAAI,eAAA;AAC7B,EAAA,IAAI,QAAA,KAAa,QAAA,IAAY,QAAA,KAAa,UAAA,EAAY;AACpD,IAAA,OAAO,QAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAMC,SAAQ,qBAAA,CAAsBD,cAAAA,CAAK,KAAK,UAAA,EAAY,aAAA,EAAe,eAAe,CAAC,CAAA;AACzF,IAAA,IAAIC,QAAO,OAAOA,MAAAA;AAAA,EACpB;AAGA,EAAA,MAAM,KAAA,GAAQ,sBAAsBD,cAAAA,CAAK,IAAA,CAAK,GAAG,OAAA,EAAQ,EAAG,aAAA,EAAe,eAAe,CAAC,CAAA;AAC3F,EAAA,IAAI,OAAO,OAAO,KAAA;AAGlB,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,sBAAsB,QAAA,EAAkC;AAC/D,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,QAAQ,GAAG,OAAO,IAAA;AACrC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,MAAA,EAAQ,OAAA,KAAY,QAAA,IAAY,MAAA,EAAQ,YAAY,UAAA,EAAY;AAClE,MAAA,OAAO,MAAA,CAAO,OAAA;AAAA,IAChB;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAcO,SAAS,qBAAA,CAAsB,UAAA,EAAqB,aAAA,GAAgB,kBAAA,EAAmC;AAE5G,EAAA,IAAI,OAAA,CAAQ,IAAI,kBAAA,EAAoB;AAClC,IAAA,OAAO,QAAQ,GAAA,CAAI,kBAAA;AAAA,EACrB;AAGA,EAAA,IAAI,UAAA,EAAY;AACd,IAAA,MAAME,IAAAA,GAAM,gBAAgBF,cAAAA,CAAK,IAAA,CAAK,YAAY,aAAA,EAAe,eAAe,GAAG,YAAY,CAAA;AAC/F,IAAA,IAAIE,MAAK,OAAOA,IAAAA;AAAA,EAClB;AAGA,EAAA,MAAM,GAAA,GAAM,eAAA,CAAgBF,cAAAA,CAAK,IAAA,CAAK,EAAA,CAAG,SAAQ,EAAG,aAAA,EAAe,eAAe,CAAA,EAAG,YAAY,CAAA;AACjG,EAAA,IAAI,KAAK,OAAO,GAAA;AAEhB,EAAA,OAAO,IAAA;AACT;AAEA,SAAS,eAAA,CAAgB,UAAkB,KAAA,EAA8B;AACvE,EAAA,IAAI;AACF,IAAA,IAAI,CAAC,EAAA,CAAG,UAAA,CAAW,QAAQ,GAAG,OAAO,IAAA;AACrC,IAAA,MAAM,GAAA,GAAM,EAAA,CAAG,YAAA,CAAa,QAAA,EAAU,OAAO,CAAA;AAC7C,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,MAAM,KAAA,GAAQ,SAAS,KAAK,CAAA;AAC5B,IAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,KAAA,EAAO;AACtC,MAAA,OAAO,KAAA;AAAA,IACT;AACA,IAAA,OAAO,IAAA;AAAA,EACT,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;;;ACrhBA,SAAS,gBAAgB,KAAA,EAA2B;AAClD,EAAA,IAAI,MAAA,GAAS,EAAA;AACb,EAAA,KAAA,MAAW,QAAQ,KAAA,EAAO;AACxB,IAAA,MAAA,IAAU,MAAA,CAAO,aAAa,IAAI,CAAA;AAAA,EACpC;AACA,EAAA,OAAO,IAAA,CAAK,MAAM,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,KAAA,EAAO,GAAG,CAAA,CAAE,OAAA,CAAQ,MAAM,EAAE,CAAA;AAC9E;AAMA,eAAsB,YAAA,GAGnB;AAED,EAAA,MAAM,aAAA,GAAgB,IAAI,UAAA,CAAW,EAAE,CAAA;AACvC,EAAA,MAAA,CAAO,gBAAgB,aAAa,CAAA;AACpC,EAAA,MAAM,QAAA,GAAW,gBAAgB,aAAa,CAAA;AAG9C,EAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAChC,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,MAAA,CAAO,QAAQ,CAAA;AACpC,EAAA,MAAM,aAAa,MAAM,MAAA,CAAO,MAAA,CAAO,MAAA,CAAO,WAAW,IAAI,CAAA;AAC7D,EAAA,MAAM,SAAA,GAAY,eAAA,CAAgB,IAAI,UAAA,CAAW,UAAU,CAAC,CAAA;AAE5D,EAAA,OAAO,EAAE,UAAU,SAAA,EAAU;AAC/B;;;AC1BA,IAAM,MAAA,GAAS,CAAC,CAAA,KAAc,IAAA,CAAK,CAAC,CAAA;AACpC,IAAM,SAAA,GAAY,OAAO,kDAAkD,CAAA;AAC3E,IAAM,aAAA,GAAgB,mCAAA;AACtB,IAAM,SAAA,GAAY,8CAAA;AAClB,IAAM,YAAA,GAAe,mDAAA;AACrB,IAAM,MAAA,GAAS,gDAAA;AAKf,eAAsB,cAAA,CACpB,WACA,YAAA,EAC2B;AAC3B,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,MAAM,YAAA,EAAa;AAGnD,EAAA,MAAM,UAAA,GAAa,IAAI,eAAA,CAAgB;AAAA,IACrC,IAAA,EAAM,MAAA;AAAA,IACN,SAAA,EAAW,SAAA;AAAA,IACX,aAAA,EAAe,MAAA;AAAA,IACf,YAAA,EAAc,YAAA;AAAA,IACd,KAAA,EAAO,MAAA;AAAA,IACP,cAAA,EAAgB,SAAA;AAAA,IAChB,qBAAA,EAAuB,MAAA;AAAA,IACvB,KAAA,EAAO;AAAA,GACR,CAAA;AAED,EAAA,MAAM,UAAU,CAAA,EAAG,aAAa,CAAA,CAAA,EAAI,UAAA,CAAW,UAAU,CAAA,CAAA;AAGzD,EAAA,SAAA,CAAU,OAAO,CAAA;AAGjB,EAAA,MAAM,QAAA,GAAW,MAAM,YAAA,EAAa;AACpC,EAAA,MAAM,MAAA,GAAS,QAAA,CAAS,KAAA,CAAM,GAAG,CAAA;AACjC,EAAA,MAAM,IAAA,GAAO,OAAO,CAAC,CAAA;AACrB,EAAA,MAAM,KAAA,GAAQ,OAAO,CAAC,CAAA;AAGtB,EAAA,MAAM,aAAA,GAAgB,MAAM,KAAA,CAAM,SAAA,EAAW;AAAA,IAC3C,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACP,cAAA,EAAgB;AAAA,KAClB;AAAA,IACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,MACnB,UAAA,EAAY,oBAAA;AAAA,MACZ,SAAA,EAAW,SAAA;AAAA,MACX,IAAA;AAAA,MACA,KAAA;AAAA,MACA,YAAA,EAAc,YAAA;AAAA,MACd,aAAA,EAAe;AAAA,KAChB;AAAA,GACF,CAAA;AAED,EAAA,IAAI,CAAC,cAAc,EAAA,EAAI;AACrB,IAAA,MAAM,KAAA,GAAQ,MAAM,aAAA,CAAc,IAAA,EAAK;AACvC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,uBAAA,EAA0B,KAAK,CAAA,CAAE,CAAA;AAAA,EACnD;AAEA,EAAA,MAAM,SAAA,GAAa,MAAM,aAAA,CAAc,IAAA,EAAK;AAO5C,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI,GAAI,UAAU,UAAA,GAAa,GAAA,GAAO,IAAI,EAAA,GAAK,GAAA;AAEtE,EAAA,OAAO;AAAA,IACL,SAAS,SAAA,CAAU,aAAA;AAAA,IACnB,QAAQ,SAAA,CAAU,YAAA;AAAA,IAClB,OAAA,EAAS;AAAA,GACX;AACF;AAKA,eAAsB,sBAAsB,YAAA,EAAiD;AAC3F,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,SAAA,EAAW;AAAA,IACtC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,kBAAA,EAAmB;AAAA,IAC9C,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,MACnB,UAAA,EAAY,eAAA;AAAA,MACZ,SAAA,EAAW,SAAA;AAAA,MACX,aAAA,EAAe;AAAA,KAChB;AAAA,GACF,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,KAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAClC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,KAAK,CAAA,CAAE,CAAA;AAAA,EAC5D;AAEA,EAAA,MAAM,IAAA,GAAQ,MAAM,QAAA,CAAS,IAAA,EAAK;AAMlC,EAAA,OAAO;AAAA,IACL,SAAS,IAAA,CAAK,aAAA;AAAA,IACd,QAAQ,IAAA,CAAK,YAAA;AAAA,IACb,OAAA,EAAS,KAAK,GAAA,EAAI,GAAI,KAAK,UAAA,GAAa,GAAA,GAAO,IAAI,EAAA,GAAK;AAAA,GAC1D;AACF;AAEO,IAAM,sBAAA,GAAiD;AAAA,EAC5D,EAAA,EAAI,WAAA;AAAA,EACJ,IAAA,EAAM,4BAAA;AAAA,EAEN,MAAM,MAAM,SAAA,EAA2D;AACrE,IAAA,OAAO,cAAA;AAAA,MACL,CAAA,GAAA,KAAO,SAAA,CAAU,MAAA,CAAO,EAAE,KAAK,CAAA;AAAA,MAC/B,MAAM,SAAA,CAAU,QAAA,CAAS,EAAE,OAAA,EAAS,iCAAiC;AAAA,KACvE;AAAA,EACF,CAAA;AAAA,EAEA,MAAM,aAAa,WAAA,EAA0D;AAC3E,IAAA,OAAO,qBAAA,CAAsB,YAAY,OAAO,CAAA;AAAA,EAClD,CAAA;AAAA,EAEA,UAAU,WAAA,EAAuC;AAC/C,IAAA,OAAO,WAAA,CAAY,MAAA;AAAA,EACrB;AACF,CAAA;;;ACpHA,IAAMG,OAAAA,GAAS,CAAC,CAAA,KAAsB,IAAA,CAAK,CAAC,CAAA;AAE5C,IAAMC,UAAAA,GAAYD,QAAO,8BAA8B,CAAA;AAEhD,IAAM,kBAAA,GAAqB,0BAAA;AAG3B,IAAM,eAAA,GAAkB;AAAA,EAC7B,YAAA,EAAc,kBAAA;AAAA,EACd,gBAAA,EAAkB,gBAAA;AAAA,EAClB,uBAAA,EAAyB,qBAAA;AAAA,EACzB,wBAAA,EAA0B;AAC5B;AAEA,IAAM,gCAAA,GAAmC,GAAA;AACzC,IAAM,kCAAA,GAAqC,GAAA;AA0BpC,SAAS,gBAAgB,KAAA,EAA8B;AAC5D,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,QAAA,CAAS,KAAK,CAAA,GAAI,IAAI,GAAA,CAAI,OAAO,CAAA,GAAI,IAAI,GAAA,CAAI,CAAA,QAAA,EAAW,OAAO,CAAA,CAAE,CAAA;AACrF,IAAA,OAAO,IAAI,QAAA,IAAY,IAAA;AAAA,EACzB,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,QAAQ,MAAA,EAIf;AACA,EAAA,OAAO;AAAA,IACL,aAAA,EAAe,WAAW,MAAM,CAAA,kBAAA,CAAA;AAAA,IAChC,cAAA,EAAgB,WAAW,MAAM,CAAA,yBAAA,CAAA;AAAA,IACjC,eAAA,EAAiB,eAAe,MAAM,CAAA,0BAAA;AAAA,GACxC;AACF;AAMA,SAAS,oBAAoB,KAAA,EAA8B;AACzD,EAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,kBAAkB,CAAA;AAC5C,EAAA,IAAI,CAAC,OAAO,OAAO,IAAA;AACnB,EAAA,MAAM,SAAA,GAAY,MAAM,CAAC,CAAA;AACzB,EAAA,MAAM,OAAA,GAAU,SAAA,CAAU,OAAA,CAAQ,UAAA,EAAY,MAAM,CAAA;AACpD,EAAA,OAAO,WAAW,OAAO,CAAA,CAAA;AAC3B;AAMO,SAAS,uBAAA,CAAwB,OAAgB,gBAAA,EAAmC;AACzF,EAAA,IAAI,KAAA,EAAO;AACT,IAAA,MAAM,SAAA,GAAY,oBAAoB,KAAK,CAAA;AAC3C,IAAA,IAAI,WAAW,OAAO,SAAA;AAAA,EACxB;AACA,EAAA,IAAI,gBAAA,EAAkB,OAAO,CAAA,oBAAA,EAAuB,gBAAgB,CAAA,CAAA;AACpE,EAAA,OAAO,0CAAA;AACT;AAEA,eAAe,SAAA,CAAU,GAAA,EAAa,IAAA,EAAmB,MAAA,EAAwC;AAC/F,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK,MAAA,GAAS,EAAE,GAAG,IAAA,EAAM,MAAA,EAAO,GAAI,IAAI,CAAA;AACrE,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,EAAG,QAAA,CAAS,MAAM,IAAI,QAAA,CAAS,UAAU,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,EACtE;AACA,EAAA,OAAO,SAAS,IAAA,EAAK;AACvB;AAEA,eAAe,eAAA,CAAgB,QAAgB,MAAA,EAAmD;AAChG,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,CAAA;AAC3B,EAAA,MAAM,OAAO,MAAM,SAAA;AAAA,IACjB,IAAA,CAAK,aAAA;AAAA,IACL;AAAA,MACE,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,kBAAA;AAAA,QACR,cAAA,EAAgB,mCAAA;AAAA,QAChB,YAAA,EAAc;AAAA,OAChB;AAAA,MACA,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,SAAA,EAAWC,UAAAA;AAAA,QACX,KAAA,EAAO;AAAA,OACR;AAAA,KACH;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACrC,IAAA,MAAM,IAAI,MAAM,8BAA8B,CAAA;AAAA,EAChD;AAEA,EAAA,MAAM,GAAA,GAAM,IAAA;AACZ,EAAA,MAAM,aAAa,GAAA,CAAI,WAAA;AACvB,EAAA,MAAM,WAAW,GAAA,CAAI,SAAA;AACrB,EAAA,MAAM,kBAAkB,GAAA,CAAI,gBAAA;AAC5B,EAAA,MAAM,WAAW,GAAA,CAAI,QAAA;AACrB,EAAA,MAAM,YAAY,GAAA,CAAI,UAAA;AAEtB,EAAA,IACE,OAAO,UAAA,KAAe,QAAA,IACtB,OAAO,aAAa,QAAA,IACpB,OAAO,eAAA,KAAoB,QAAA,IAC3B,OAAO,QAAA,KAAa,QAAA,IACpB,OAAO,cAAc,QAAA,EACrB;AACA,IAAA,MAAM,IAAI,MAAM,qCAAqC,CAAA;AAAA,EACvD;AAEA,EAAA,OAAO;AAAA,IACL,WAAA,EAAa,UAAA;AAAA,IACb,SAAA,EAAW,QAAA;AAAA,IACX,gBAAA,EAAkB,eAAA;AAAA,IAClB,QAAA;AAAA,IACA,UAAA,EAAY;AAAA,GACd;AACF;AAGA,SAAS,cAAA,CAAe,IAAY,MAAA,EAAqC;AACvE,EAAA,OAAO,IAAI,OAAA,CAAQ,CAAC,OAAA,EAAS,MAAA,KAAW;AACtC,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AACnC,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,OAAA;AACJ,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,YAAA,CAAa,OAAO,CAAA;AACpB,MAAA,MAAA,CAAO,IAAI,KAAA,CAAM,iBAAiB,CAAC,CAAA;AAAA,IACrC,CAAA;AAEA,IAAA,OAAA,GAAU,WAAW,MAAM;AACzB,MAAA,MAAA,EAAQ,mBAAA,CAAoB,SAAS,OAAO,CAAA;AAC5C,MAAA,OAAA,EAAQ;AAAA,IACV,GAAG,EAAE,CAAA;AAEL,IAAA,MAAA,EAAQ,iBAAiB,OAAA,EAAS,OAAA,EAAS,EAAE,IAAA,EAAM,MAAM,CAAA;AAAA,EAC3D,CAAC,CAAA;AACH;AAEA,eAAe,wBAAA,CACb,MAAA,EACA,UAAA,EACA,eAAA,EACA,WACA,MAAA,EACiB;AACjB,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,CAAA;AAC3B,EAAA,MAAM,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA,GAAY,GAAA;AAC1C,EAAA,IAAI,UAAA,GAAa,KAAK,GAAA,CAAI,GAAA,EAAM,KAAK,KAAA,CAAM,eAAA,GAAkB,GAAI,CAAC,CAAA;AAClE,EAAA,IAAI,kBAAA,GAAqB,gCAAA;AACzB,EAAA,IAAI,iBAAA,GAAoB,CAAA;AAExB,EAAA,OAAO,IAAA,CAAK,GAAA,EAAI,GAAI,QAAA,EAAU;AAC5B,IAAA,IAAI,QAAQ,OAAA,EAAS;AACnB,MAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AAAA,IACnC;AAEA,IAAA,MAAM,WAAA,GAAc,QAAA,GAAW,IAAA,CAAK,GAAA,EAAI;AACxC,IAAA,MAAM,MAAA,GAAS,KAAK,GAAA,CAAI,IAAA,CAAK,KAAK,UAAA,GAAa,kBAAkB,GAAG,WAAW,CAAA;AAC/E,IAAA,MAAM,cAAA,CAAe,QAAQ,MAAM,CAAA;AAEnC,IAAA,MAAM,MAAM,MAAM,SAAA;AAAA,MAChB,IAAA,CAAK,cAAA;AAAA,MACL;AAAA,QACE,MAAA,EAAQ,MAAA;AAAA,QACR,OAAA,EAAS;AAAA,UACP,MAAA,EAAQ,kBAAA;AAAA,UACR,cAAA,EAAgB,mCAAA;AAAA,UAChB,YAAA,EAAc;AAAA,SAChB;AAAA,QACA,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,UACxB,SAAA,EAAWA,UAAAA;AAAA,UACX,WAAA,EAAa,UAAA;AAAA,UACb,UAAA,EAAY;AAAA,SACb;AAAA,OACH;AAAA,MACA;AAAA,KACF;AAEA,IAAA,IAAI,OAAO,OAAO,GAAA,KAAQ,YAAY,OAAQ,GAAA,CAAmC,iBAAiB,QAAA,EAAU;AAC1G,MAAA,OAAQ,GAAA,CAAmC,YAAA;AAAA,IAC7C;AAEA,IAAA,IAAI,OAAO,OAAO,GAAA,KAAQ,YAAY,OAAQ,GAAA,CAAiC,UAAU,QAAA,EAAU;AACjG,MAAA,MAAM,EAAE,KAAA,EAAO,iBAAA,EAAmB,WAAA,EAAa,UAAS,GAAI,GAAA;AAC5D,MAAA,IAAI,UAAU,uBAAA,EAAyB;AACrC,QAAA;AAAA,MACF;AAEA,MAAA,IAAI,UAAU,WAAA,EAAa;AACzB,QAAA,iBAAA,IAAqB,CAAA;AACrB,QAAA,UAAA,GAAa,OAAO,QAAA,KAAa,QAAA,IAAY,QAAA,GAAW,CAAA,GAAI,QAAA,GAAW,GAAA,GAAO,IAAA,CAAK,GAAA,CAAI,GAAA,EAAM,UAAA,GAAa,GAAI,CAAA;AAC9G,QAAA,kBAAA,GAAqB,kCAAA;AACrB,QAAA;AAAA,MACF;AAEA,MAAA,MAAM,iBAAA,GAAoB,WAAA,GAAc,CAAA,EAAA,EAAK,WAAW,CAAA,CAAA,GAAK,EAAA;AAC7D,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,oBAAA,EAAuB,KAAK,CAAA,EAAG,iBAAiB,CAAA,CAAE,CAAA;AAAA,IACpE;AAAA,EACF;AAEA,EAAA,IAAI,oBAAoB,CAAA,EAAG;AACzB,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA,EACF;AAEA,EAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AACzC;AAQA,eAAsB,yBAAA,CACpB,YAAA,EACA,gBAAA,EACA,MAAA,EACmC;AACnC,EAAA,MAAM,SAAS,gBAAA,IAAoB,YAAA;AACnC,EAAA,MAAM,IAAA,GAAO,QAAQ,MAAM,CAAA;AAE3B,EAAA,MAAM,MAAM,MAAM,SAAA;AAAA,IAChB,IAAA,CAAK,eAAA;AAAA,IACL;AAAA,MACE,OAAA,EAAS;AAAA,QACP,MAAA,EAAQ,kBAAA;AAAA,QACR,aAAA,EAAe,UAAU,YAAY,CAAA,CAAA;AAAA,QACrC,GAAG;AAAA;AACL,KACF;AAAA,IACA;AAAA,GACF;AAEA,EAAA,IAAI,CAAC,GAAA,IAAO,OAAO,GAAA,KAAQ,QAAA,EAAU;AACnC,IAAA,MAAM,IAAI,MAAM,gCAAgC,CAAA;AAAA,EAClD;AAEA,EAAA,MAAM,GAAA,GAAM,GAAA;AACZ,EAAA,MAAM,QAAQ,GAAA,CAAI,KAAA;AAClB,EAAA,MAAM,YAAY,GAAA,CAAI,UAAA;AAEtB,EAAA,IAAI,OAAO,KAAA,KAAU,QAAA,IAAY,OAAO,cAAc,QAAA,EAAU;AAC9D,IAAA,MAAM,IAAI,MAAM,uCAAuC,CAAA;AAAA,EACzD;AAEA,EAAA,MAAM,WAAA,GAAwC;AAAA,IAC5C,OAAA,EAAS,YAAA;AAAA,IACT,MAAA,EAAQ,KAAA;AAAA;AAAA,IAER,OAAA,EAAS,SAAA,GAAY,GAAA,GAAO,CAAA,GAAI,EAAA,GAAK;AAAA,GACvC;AACA,EAAA,IAAI,gBAAA,EAAkB;AACpB,IAAA,WAAA,CAAY,aAAA,GAAgB,gBAAA;AAAA,EAC9B;AACA,EAAA,OAAO,WAAA;AACT;AAQA,eAAsB,mBAAmB,OAAA,EAKH;AACpC,EAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,QAAA,CAAS;AAAA,IACnC,OAAA,EAAS,qDAAA;AAAA,IACT,WAAA,EAAa,iBAAA;AAAA,IACb,UAAA,EAAY;AAAA,GACb,CAAA;AAED,EAAA,IAAI,OAAA,CAAQ,QAAQ,OAAA,EAAS;AAC3B,IAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AAAA,EACnC;AAEA,EAAA,MAAM,OAAA,GAAU,MAAM,IAAA,EAAK;AAC3B,EAAA,MAAM,gBAAA,GAAmB,gBAAgB,KAAK,CAAA;AAC9C,EAAA,IAAI,OAAA,IAAW,CAAC,gBAAA,EAAkB;AAChC,IAAA,MAAM,IAAI,MAAM,sCAAsC,CAAA;AAAA,EACxD;AACA,EAAA,MAAM,SAAS,gBAAA,IAAoB,YAAA;AAEnC,EAAA,MAAM,MAAA,GAAS,MAAM,eAAA,CAAgB,MAAA,EAAQ,QAAQ,MAAM,CAAA;AAC3D,EAAA,OAAA,CAAQ,OAAO,MAAA,CAAO,gBAAA,EAAkB,CAAA,YAAA,EAAe,MAAA,CAAO,SAAS,CAAA,CAAE,CAAA;AAEzE,EAAA,MAAM,oBAAoB,MAAM,wBAAA;AAAA,IAC9B,MAAA;AAAA,IACA,MAAA,CAAO,WAAA;AAAA,IACP,MAAA,CAAO,QAAA;AAAA,IACP,MAAA,CAAO,UAAA;AAAA,IACP,OAAA,CAAQ;AAAA,GACV;AAEA,EAAA,OAAA,CAAQ,aAAa,2BAA2B,CAAA;AAChD,EAAA,OAAO,yBAAA,CAA0B,iBAAA,EAAmB,gBAAA,IAAoB,MAAA,EAAW,QAAQ,MAAM,CAAA;AACnG;AAsCA,eAAsB,mBAAmB,IAAA,EAIR;AAC/B,EAAA,MAAM,MAAM,CAAA,EAAG,IAAA,CAAK,QAAQ,OAAA,CAAQ,KAAA,EAAO,EAAE,CAAC,CAAA,OAAA,CAAA;AAC9C,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,GAAA,EAAK;AAAA,IAChC,OAAA,EAAS;AAAA,MACP,MAAA,EAAQ,kBAAA;AAAA,MACR,aAAA,EAAe,CAAA,OAAA,EAAU,IAAA,CAAK,WAAW,CAAA,CAAA;AAAA,MACzC,GAAG;AAAA,KACL;AAAA,IACA,QAAQ,IAAA,CAAK;AAAA,GACd,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,gCAAA,EAAmC,QAAA,CAAS,MAAM,IAAI,QAAA,CAAS,UAAU,CAAA,EAAA,EAAK,IAAI,CAAA,CAAE,CAAA;AAAA,EACtG;AAEA,EAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,IAAI,CAAA;AACnD,EAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,IAAY,CAAC,KAAA,CAAM,OAAA,CAAS,IAAA,CAA4B,IAAI,CAAA,EAAG;AAC1F,IAAA,MAAM,IAAI,MAAM,uDAAuD,CAAA;AAAA,EACzE;AAEA,EAAA,MAAM,OAAQ,IAAA,CAA6B,IAAA;AAC3C,EAAA,MAAM,SAA8B,EAAC;AAErC,EAAA,KAAA,MAAW,QAAQ,IAAA,EAAM;AACvB,IAAA,IAAI,CAAC,IAAA,IAAQ,OAAO,IAAA,KAAS,QAAA,EAAU;AACvC,IAAA,MAAM,GAAA,GAAM,IAAA;AAEZ,IAAA,IAAI,GAAA,CAAI,yBAAyB,IAAA,EAAM;AAEvC,IAAA,MAAM,SAAS,GAAA,CAAI,MAAA;AACnB,IAAA,IAAI,MAAA,IAAU,MAAA,CAAO,KAAA,KAAU,UAAA,EAAY;AAE3C,IAAA,MAAM,KAAK,GAAA,CAAI,EAAA;AACf,IAAA,IAAI,OAAO,EAAA,KAAO,QAAA,IAAY,CAAC,EAAA,EAAI;AAEnC,IAAA,MAAM,OAAO,OAAO,GAAA,CAAI,IAAA,KAAS,QAAA,GAAW,IAAI,IAAA,GAAO,EAAA;AACvD,IAAA,MAAM,SAAS,OAAO,GAAA,CAAI,MAAA,KAAW,QAAA,GAAW,IAAI,MAAA,GAAS,EAAA;AAE7D,IAAA,MAAM,eAAe,GAAA,CAAI,YAAA;AACzB,IAAA,MAAM,WAAW,YAAA,EAAc,QAAA;AAC/B,IAAA,MAAM,cAAA,GAAiB,UAAU,MAAA,KAAW,IAAA;AAC5C,IAAA,MAAM,iBAAA,GAAoB,UAAU,UAAA,KAAe,IAAA;AAEnD,IAAA,MAAM,eAAe,GAAA,CAAI,mBAAA;AACzB,IAAA,MAAM,kBAAA,GAAqB,KAAA,CAAM,OAAA,CAAQ,YAAY,CAAA,GACjD,YAAA,CAAa,MAAA,CAAO,CAAC,CAAA,KAAmB,OAAO,CAAA,KAAM,QAAQ,IAC7D,EAAC;AACL,IAAA,MAAM,iBAAA,GAAoB,kBAAA,CAAmB,QAAA,CAAS,cAAc,CAAA;AAEpE,IAAA,MAAA,CAAO,IAAA,CAAK;AAAA,MACV,EAAA;AAAA,MACA,IAAA;AAAA,MACA,MAAA;AAAA,MACA,kBAAA;AAAA,MACA,iBAAA;AAAA,MACA,cAAA;AAAA,MACA;AAAA,KACD,CAAA;AAAA,EACH;AAEA,EAAA,OAAO,MAAA;AACT;AAEO,IAAM,0BAAA,GAAqD;AAAA,EAChE,EAAA,EAAI,gBAAA;AAAA,EACJ,IAAA,EAAM,gBAAA;AAAA,EAEN,MAAM,MAAM,SAAA,EAA2D;AACrE,IAAA,OAAO,kBAAA,CAAmB;AAAA,MACxB,MAAA,EAAQ,CAAC,GAAA,EAAK,YAAA,KAAiB,UAAU,MAAA,CAAO,EAAE,GAAA,EAAK,YAAA,EAAc,CAAA;AAAA,MACrE,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,YAAY,SAAA,CAAU,UAAA;AAAA,MACtB,QAAQ,SAAA,CAAU;AAAA,KACnB,CAAA;AAAA,EACH,CAAA;AAAA,EAEA,MAAM,aAAa,WAAA,EAA0D;AAC3E,IAAA,MAAM,KAAA,GAAQ,WAAA;AACd,IAAA,OAAO,yBAAA,CAA0B,KAAA,CAAM,OAAA,EAAS,KAAA,CAAM,aAAa,CAAA;AAAA,EACrE,CAAA;AAAA,EAEA,UAAU,WAAA,EAAuC;AAC/C,IAAA,OAAO,WAAA,CAAY,MAAA;AAAA,EACrB;AACF,CAAA;;;ACrdA,IAAI,YAAA,GAAkD,IAAA;AAEtD,IAAI,cAAA,GAA+D,IAAA;AAEnE,IAAI,YAAA,GAA2D,IAAA;AAE/D,IAAI,KAAA,GAA2C,IAAA;AAO/C,IAAI,OAAO,YAAY,WAAA,KAAgB,OAAA,CAAQ,UAAU,IAAA,IAAQ,OAAA,CAAQ,UAAU,GAAA,CAAA,EAAM;AACvF,EAAA,cAAA,GAAiB,OAAO,QAAa,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,KAAK;AAC/C,IAAA,YAAA,GAAe,CAAA,CAAE,WAAA;AACjB,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACD,EAAA,YAAA,GAAe,OAAO,MAAW,CAAA,CAAE,IAAA,CAAK,CAAA,CAAA,KAAK;AAC3C,IAAA,KAAA,GAAQ,CAAA;AACR,IAAA,OAAO,CAAA;AAAA,EACT,CAAC,CAAA;AACH;AAKO,IAAM,uBAAA,GAAmD;AAAA,EAC9D;AAAA,IACE,EAAA,EAAI,SAAA;AAAA,IACJ,IAAA,EAAM,0BAAA;AAAA,IACN,WAAA,EAAa;AAAA,GACf;AAAA,EACA;AAAA,IACE,EAAA,EAAI,QAAA;AAAA,IACJ,IAAA,EAAM,wBAAA;AAAA,IACN,WAAA,EAAa;AAAA;AAEjB,CAAA;AAEA,IAAMA,UAAAA,GAAY,8BAAA;AAClB,IAAM,MAAA,GAAS,yBAAA;AACf,IAAMC,cAAAA,GAAgB,GAAG,MAAM,CAAA,gBAAA,CAAA;AAC/B,IAAMC,UAAAA,GAAY,GAAG,MAAM,CAAA,YAAA,CAAA;AAC3B,IAAM,oBAAA,GAAuB,GAAG,MAAM,CAAA,iCAAA,CAAA;AACtC,IAAM,gBAAA,GAAmB,GAAG,MAAM,CAAA,8BAAA,CAAA;AAClC,IAAM,oBAAA,GAAuB,GAAG,MAAM,CAAA,aAAA,CAAA;AACtC,IAAM,mBAAA,GAAsB,GAAG,MAAM,CAAA,oBAAA,CAAA;AACrC,IAAM,qBAAA,GAAwB,IAAA;AAC9B,IAAM,sBAAA,GAAyB,IAAA;AAC/B,IAAM,gCAAA,GAAmC,IAAA;AACzC,IAAM,sBAAA,GAAyB,KAAK,EAAA,GAAK,GAAA;AACzC,IAAM,KAAA,GAAQ,+EAAA;AACd,IAAM,cAAA,GAAiB,6BAAA;AAEvB,IAAM,YAAA,GAAe,CAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,OAAA,CAAA;AA8BrB,eAAe,WAAA,GAA+B;AAC5C,EAAA,MAAM,WAAA,GAAc,MAAM,cAAA,EAAe;AACzC,EAAA,OAAO,WAAA,CAAY,EAAE,CAAA,CAAE,QAAA,CAAS,KAAK,CAAA;AACvC;AAEA,SAAS,wBAAwB,KAAA,EAG/B;AACA,EAAA,MAAM,KAAA,GAAQ,MAAM,IAAA,EAAK;AACzB,EAAA,IAAI,CAAC,KAAA,EAAO,OAAO,EAAC;AAEpB,EAAA,IAAI;AACF,IAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,KAAK,CAAA;AACzB,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA,IAAK,MAAA;AAAA,MACtC,KAAA,EAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAO,CAAA,IAAK;AAAA,KAC1C;AAAA,EACF,CAAA,CAAA,MAAQ;AAAA,EAER;AAEA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,GAAG,CAAA,EAAG;AACvB,IAAA,MAAM,CAAC,IAAA,EAAM,KAAK,IAAI,KAAA,CAAM,KAAA,CAAM,KAAK,CAAC,CAAA;AACxC,IAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AAAA,EACvB;AAEA,EAAA,IAAI,KAAA,CAAM,QAAA,CAAS,OAAO,CAAA,EAAG;AAC3B,IAAA,MAAM,MAAA,GAAS,IAAI,eAAA,CAAgB,KAAK,CAAA;AACxC,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,MAAA,CAAO,GAAA,CAAI,MAAM,CAAA,IAAK,MAAA;AAAA,MAC5B,KAAA,EAAO,MAAA,CAAO,GAAA,CAAI,OAAO,CAAA,IAAK;AAAA,KAChC;AAAA,EACF;AAEA,EAAA,OAAO,EAAE,MAAM,KAAA,EAAM;AACvB;AAEA,SAAS,UAAU,KAAA,EAAkC;AACnD,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,GAAQ,KAAA,CAAM,KAAA,CAAM,GAAG,CAAA;AAC7B,IAAA,IAAI,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG,OAAO,IAAA;AAC/B,IAAA,MAAM,OAAA,GAAU,KAAA,CAAM,CAAC,CAAA,IAAK,EAAA;AAC5B,IAAA,MAAM,SAAS,OAAA,CACZ,OAAA,CAAQ,MAAM,GAAG,CAAA,CACjB,QAAQ,IAAA,EAAM,GAAG,CAAA,CACjB,MAAA,CAAO,KAAK,IAAA,CAAK,OAAA,CAAQ,SAAS,CAAC,CAAA,GAAI,GAAG,GAAG,CAAA;AAChD,IAAA,MAAM,OAAA,GAAU,KAAK,MAAM,CAAA;AAC3B,IAAA,OAAO,IAAA,CAAK,MAAM,OAAO,CAAA;AAAA,EAC3B,CAAA,CAAA,MAAQ;AACN,IAAA,OAAO,IAAA;AAAA,EACT;AACF;AAEA,SAAS,2BAA2B,OAAA,EAAuD;AACzF,EAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AACrB,EAAA,MAAM,SAAA,GAAY,OAAA,CAAQ,kBAAA,IAAsB,OAAA,CAAQ,cAAc,CAAA,EAAG,kBAAA;AACzE,EAAA,OAAO,OAAO,SAAA,KAAc,QAAA,IAAY,SAAA,CAAU,MAAA,GAAS,IAAI,SAAA,GAAY,IAAA;AAC7E;AAEA,SAAS,YAAA,CAAa,QAA8C,QAAA,EAAuC;AACzG,EAAA,MAAM,WAAA,GAAc,OAAO,OAAA,GAAU,0BAAA,CAA2B,UAAU,MAAA,CAAO,OAAO,CAAC,CAAA,GAAI,IAAA;AAC7F,EAAA,IAAI,aAAa,OAAO,WAAA;AAExB,EAAA,MAAM,eAAA,GAAkB,0BAAA,CAA2B,SAAA,CAAU,MAAA,CAAO,MAAM,CAAC,CAAA;AAC3E,EAAA,IAAI,iBAAiB,OAAO,eAAA;AAE5B,EAAA,OAAO,QAAA;AACT;AAEA,SAAS,gBAAA,CAAiB,QAA8C,QAAA,EAA2B;AACjG,EAAA,MAAM,SAAA,GAAY,YAAA,CAAa,MAAA,EAAQ,QAAQ,CAAA;AAC/C,EAAA,IAAI,CAAC,SAAA,EAAW;AACd,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAChF;AACA,EAAA,OAAO,SAAA;AACT;AASA,SAAS,qBAAA,CAAsB,MAAyB,SAAA,EAAgC;AACtF,EAAA,IAAI,CAAC,IAAA,CAAK,YAAA,IAAgB,CAAC,KAAK,aAAA,EAAe;AAC7C,IAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,eAAA,EAAkB,SAAS,CAAA,yBAAA,CAAA,EAA6B,IAAI,CAAA;AAC1E,IAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,EAC1B;AAEA,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,SAAA;AAAA,IACN,QAAQ,IAAA,CAAK,YAAA;AAAA,IACb,SAAS,IAAA,CAAK,aAAA;AAAA,IACd,SAAS,IAAA,CAAK,GAAA,EAAI,GAAA,CAAK,IAAA,CAAK,cAAc,gCAAA,IAAoC,GAAA;AAAA,IAC9E,SAAS,IAAA,CAAK;AAAA,GAChB;AACF;AAEA,eAAe,yBAAA,CAA0B,IAAA,EAAc,QAAA,EAAkB,WAAA,EAA2C;AAClH,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAMA,UAAAA,EAAW;AAAA,IACtC,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,IAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,MACxB,UAAA,EAAY,oBAAA;AAAA,MACZ,SAAA,EAAWF,UAAAA;AAAA,MACX,IAAA;AAAA,MACA,aAAA,EAAe,QAAA;AAAA,MACf,YAAA,EAAc;AAAA,KACf;AAAA,GACF,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,IAAA,OAAA,CAAQ,KAAA,CAAM,oCAAA,EAAsC,QAAA,CAAS,MAAA,EAAQ,IAAI,CAAA;AACzE,IAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,EAC1B;AAEA,EAAA,OAAO,qBAAA,CAAuB,MAAM,QAAA,CAAS,IAAA,IAA8B,OAAO,CAAA;AACpF;AAEA,eAAe,mBAAmB,YAAA,EAA4C;AAC5E,EAAA,IAAI;AACF,IAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAME,UAAAA,EAAW;AAAA,MACtC,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS,EAAE,cAAA,EAAgB,mCAAA,EAAoC;AAAA,MAC/D,IAAA,EAAM,IAAI,eAAA,CAAgB;AAAA,QACxB,UAAA,EAAY,eAAA;AAAA,QACZ,aAAA,EAAe,YAAA;AAAA,QACf,SAAA,EAAWF;AAAA,OACZ;AAAA,KACF,CAAA;AAED,IAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,MAAA,MAAM,OAAO,MAAM,QAAA,CAAS,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACjD,MAAA,OAAA,CAAQ,KAAA,CAAM,sCAAA,EAAwC,QAAA,CAAS,MAAA,EAAQ,IAAI,CAAA;AAC3E,MAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,IAC1B;AAEA,IAAA,OAAO,qBAAA,CAAuB,MAAM,QAAA,CAAS,IAAA,IAA8B,eAAe,CAAA;AAAA,EAC5F,SAAS,KAAA,EAAO;AACd,IAAA,OAAA,CAAQ,KAAA,CAAM,uCAAuC,KAAK,CAAA;AAC1D,IAAA,OAAO,EAAE,MAAM,QAAA,EAAS;AAAA,EAC1B;AACF;AAEA,eAAe,cAAA,GAAiB;AAC9B,EAAA,IAAI,CAAC,gBAAgB,cAAA,EAAgB;AACnC,IAAA,YAAA,GAAA,CAAgB,MAAM,cAAA,EAAgB,WAAA;AAAA,EACxC;AACA,EAAA,IAAI,CAAC,YAAA,EAAc;AACjB,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAChF;AACA,EAAA,OAAO,YAAA;AACT;AAEA,eAAe,uBAAA,CACb,WAAA,EACA,KAAA,EACA,UAAA,GAAqB,YAAA,EACuB;AAC5C,EAAA,MAAM,EAAE,QAAA,EAAU,SAAA,EAAU,GAAI,MAAM,YAAA,EAAa;AAEnD,EAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAIC,cAAa,CAAA;AACjC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,eAAA,EAAiB,MAAM,CAAA;AAC5C,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,WAAA,EAAaD,UAAS,CAAA;AAC3C,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,cAAA,EAAgB,WAAW,CAAA;AAChD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,gBAAA,EAAkB,SAAS,CAAA;AAChD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,uBAAA,EAAyB,MAAM,CAAA;AACpD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACnC,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,4BAAA,EAA8B,MAAM,CAAA;AACzD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,2BAAA,EAA6B,MAAM,CAAA;AACxD,EAAA,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,YAAA,EAAc,UAAU,CAAA;AAE7C,EAAA,OAAO,EAAE,QAAA,EAAU,GAAA,EAAK,GAAA,CAAI,UAAS,EAAE;AACzC;AAeA,IAAM,oBAAA,GAAsC;AAAA,EAC1C,WAAA,EAAa,qBAAA;AAAA,EACb,YAAA,EAAc;AAChB,CAAA;AAEA,eAAe,cAAc,IAAA,EAA6B;AACxD,EAAA,IAAI;AACF,IAAA,MAAM,KAAA,CAAM,CAAA,iBAAA,EAAoB,IAAI,CAAA,OAAA,CAAA,EAAW,EAAE,QAAQ,WAAA,CAAY,OAAA,CAAQ,GAAG,CAAA,EAAG,CAAA;AAAA,EACrF,CAAA,CAAA,MAAQ;AAAA,EAER;AACF;AAEA,SAAS,MAAA,CAAO,QAAoB,IAAA,EAAgC;AAClE,EAAA,OAAO,IAAI,QAAQ,CAAA,OAAA,KAAW;AAC5B,IAAA,MAAM,UAAU,MAAM;AACpB,MAAA,MAAA,CAAO,GAAA,CAAI,aAAa,WAAW,CAAA;AACnC,MAAA,OAAA,CAAQ,KAAK,CAAA;AAAA,IACf,CAAA;AACA,IAAA,MAAM,cAAc,MAAM;AACxB,MAAA,MAAA,CAAO,GAAA,CAAI,SAAS,OAAO,CAAA;AAC3B,MAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,IACd,CAAA;AAEA,IAAA,MAAA,CAAO,IAAA,CAAK,SAAS,OAAO,CAAA;AAC5B,IAAA,MAAA,CAAO,IAAA,CAAK,aAAa,WAAW,CAAA;AACpC,IAAA,MAAA,CAAO,MAAA,CAAO,MAAM,WAAW,CAAA;AAAA,EACjC,CAAC,CAAA;AACH;AAEA,eAAe,eAAA,CAAgB,QAAoB,KAAA,EAA8C;AAC/F,EAAA,MAAM,aAAA,CAAc,MAAM,WAAW,CAAA;AACrC,EAAA,IAAI,MAAM,MAAA,CAAO,MAAA,EAAQ,MAAM,WAAW,CAAA,SAAU,KAAA,CAAM,WAAA;AAC1D,EAAA,IAAI,MAAM,MAAA,CAAO,MAAA,EAAQ,MAAM,YAAY,CAAA,SAAU,KAAA,CAAM,YAAA;AAE3D,EAAA,OAAO,IAAA;AACT;AAEA,eAAe,aAAA,GAAgB;AAC7B,EAAA,IAAI,CAAC,SAAS,YAAA,EAAc;AAC1B,IAAA,KAAA,GAAQ,MAAM,YAAA;AAAA,EAChB;AACA,EAAA,IAAI,CAAC,KAAA,EAAO;AACV,IAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,EAChF;AACA,EAAA,OAAO,KAAA;AACT;AAEA,eAAe,qBAAA,CACb,KAAA,EACA,KAAA,GAAuB,oBAAA,EACG;AAC1B,EAAA,MAAM,IAAA,GAAO,MAAM,aAAA,EAAc;AACjC,EAAA,IAAI,QAAA,GAA0B,IAAA;AAC9B,EAAA,IAAI,SAAA,GAAY,KAAA;AAChB,EAAA,MAAM,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,CAAC,KAAK,GAAA,KAAQ;AAC7C,IAAA,IAAI;AACF,MAAA,MAAM,MAAM,IAAI,GAAA,CAAI,GAAA,CAAI,GAAA,IAAO,IAAI,kBAAkB,CAAA;AACrD,MAAA,IAAI,GAAA,CAAI,aAAa,SAAA,EAAW;AAC9B,QAAA,SAAA,GAAY,IAAA;AACZ,QAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,QAAA,GAAA,CAAI,IAAI,WAAW,CAAA;AACnB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,aAAa,gBAAA,EAAkB;AACrC,QAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,QAAA,GAAA,CAAI,IAAI,WAAW,CAAA;AACnB,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,OAAO,MAAM,KAAA,EAAO;AAC3C,QAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,QAAA,GAAA,CAAI,IAAI,gBAAgB,CAAA;AACxB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,IAAA,GAAO,GAAA,CAAI,YAAA,CAAa,GAAA,CAAI,MAAM,CAAA;AACxC,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,QAAA,GAAA,CAAI,IAAI,4BAA4B,CAAA;AACpC,QAAA;AAAA,MACF;AACA,MAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,MAAA,GAAA,CAAI,SAAA,CAAU,gBAAgB,0BAA0B,CAAA;AACxD,MAAA,GAAA,CAAI,IAAI,YAAY,CAAA;AACpB,MAAA,QAAA,GAAW,IAAA;AAAA,IACb,CAAA,CAAA,MAAQ;AACN,MAAA,GAAA,CAAI,UAAA,GAAa,GAAA;AACjB,MAAA,GAAA,CAAI,IAAI,gBAAgB,CAAA;AAAA,IAC1B;AAAA,EACF,CAAC,CAAA;AAED,EAAA,OAAO,IAAI,QAAQ,CAAA,OAAA,KAAW;AAC5B,IAAA,eAAA,CAAgB,MAAA,EAAQ,KAAK,CAAA,CAAE,IAAA,CAAK,CAAA,IAAA,KAAQ;AAC1C,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,OAAA,CAAQ;AAAA,UACN,WAAA,EAAa,CAAA,iBAAA,EAAoB,KAAA,CAAM,YAAY,CAAA,cAAA,CAAA;AAAA,UACnD,SAAS,CAAA,2CAAA,EAA8C,KAAA,CAAM,WAAW,CAAA,IAAA,EAAO,MAAM,YAAY,CAAA,mFAAA,CAAA;AAAA,UACjG,OAAO,MAAM;AACX,YAAA,IAAI;AACF,cAAA,MAAA,CAAO,KAAA,EAAM;AAAA,YACf,CAAA,CAAA,MAAQ;AAAA,YAER;AAAA,UACF,CAAA;AAAA,UACA,YAAY,MAAM;AAAA,UAAC,CAAA;AAAA,UACnB,aAAa,YAAY;AAAA,SAC1B,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,OAAA,CAAQ;AAAA,QACN,WAAA,EAAa,oBAAoB,IAAI,CAAA,cAAA,CAAA;AAAA,QACrC,KAAA,EAAO,MAAM,MAAA,CAAO,KAAA,EAAM;AAAA,QAC1B,YAAY,MAAM;AAChB,UAAA,SAAA,GAAY,IAAA;AAAA,QACd,CAAA;AAAA,QACA,aAAa,YAAY;AACvB,UAAA,MAAM,KAAA,GAAQ,MAAM,IAAI,OAAA,CAAQ,OAAK,UAAA,CAAW,CAAA,EAAG,GAAG,CAAC,CAAA;AACvD,UAAA,KAAA,IAAS,CAAA,GAAI,CAAA,EAAG,CAAA,GAAI,GAAA,EAAK,KAAK,CAAA,EAAG;AAC/B,YAAA,IAAI,QAAA,EAAU,OAAO,EAAE,IAAA,EAAM,QAAA,EAAS;AACtC,YAAA,IAAI,WAAW,OAAO,IAAA;AACtB,YAAA,MAAM,KAAA,EAAM;AAAA,UACd;AACA,UAAA,OAAO,IAAA;AAAA,QACT;AAAA,OACD,CAAA;AAAA,IACH,CAAC,CAAA;AAAA,EACH,CAAC,CAAA;AACH;AAEA,eAAe,uBAAuB,OAAA,EAKR;AAC5B,EAAA,MAAM,QAAA,GAAW,MAAM,KAAA,CAAM,oBAAA,EAAsB;AAAA,IACjD,MAAA,EAAQ,MAAA;AAAA,IACR,OAAA,EAAS;AAAA,MACP,cAAA,EAAgB,kBAAA;AAAA,MAChB,YAAA,EAAc;AAAA,KAChB;AAAA,IACA,IAAA,EAAM,KAAK,SAAA,CAAU,EAAE,WAAWA,UAAAA,EAAW,UAAA,EAAY,cAAc,CAAA;AAAA,IACvE,QAAQ,OAAA,CAAQ;AAAA,GACjB,CAAA;AAED,EAAA,IAAI,CAAC,SAAS,EAAA,EAAI;AAChB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,sDAAA,EAAyD,QAAA,CAAS,MAAM,CAAA,CAAE,CAAA;AAAA,EAC5F;AAEA,EAAA,MAAM,UAAA,GAAc,MAAM,QAAA,CAAS,IAAA,EAAK;AAOxC,EAAA,MAAM,QAAA,GAAW,UAAA,CAAW,SAAA,IAAa,UAAA,CAAW,QAAA;AAEpD,EAAA,IAAI,CAAC,UAAA,CAAW,cAAA,IAAkB,CAAC,QAAA,EAAU;AAC3C,IAAA,MAAM,IAAI,MAAM,oEAAoE,CAAA;AAAA,EACtF;AAEA,EAAA,MAAM,eAAA,GACJ,OAAO,UAAA,CAAW,QAAA,KAAa,QAAA,GAAW,UAAA,CAAW,QAAA,GAAW,MAAA,CAAO,QAAA,CAAS,UAAA,CAAW,QAAA,IAAY,EAAA,EAAI,EAAE,CAAA,IAAK,CAAA;AACpH,EAAA,MAAM,WAAA,GAAc,IAAA,CAAK,GAAA,CAAI,eAAA,EAAiB,CAAC,CAAA,GAAI,GAAA;AACnD,EAAA,MAAM,KAAA,GAAQ,OAAA,CAAQ,KAAA,KAAU,CAAA,EAAA,KAAM,IAAI,QAAc,CAAA,OAAA,KAAW,UAAA,CAAW,OAAA,EAAS,EAAE,CAAC,CAAA,CAAA;AAC1F,EAAA,MAAM,SAAA,GAAY,KAAK,GAAA,EAAI;AAE3B,EAAA,OAAA,CAAQ,MAAA,CAAO;AAAA,IACb,GAAA,EAAK,oBAAA;AAAA,IACL,YAAA,EAAc,eAAe,QAAQ,CAAA;AAAA,GACtC,CAAA;AAED,EAAA,OAAO,IAAA,EAAM;AACX,IAAA,IAAI,OAAA,CAAQ,QAAQ,OAAA,EAAS;AAC3B,MAAA,MAAM,IAAI,MAAM,iBAAiB,CAAA;AAAA,IACnC;AACA,IAAA,IAAI,IAAA,CAAK,GAAA,EAAI,GAAI,SAAA,IAAa,sBAAA,EAAwB;AACpD,MAAA,MAAM,IAAI,MAAM,8DAA8D,CAAA;AAAA,IAChF;AAEA,IAAA,MAAM,YAAA,GAAe,MAAM,KAAA,CAAM,gBAAA,EAAkB;AAAA,MACjD,MAAA,EAAQ,MAAA;AAAA,MACR,OAAA,EAAS;AAAA,QACP,cAAA,EAAgB,kBAAA;AAAA,QAChB,YAAA,EAAc;AAAA,OAChB;AAAA,MACA,IAAA,EAAM,KAAK,SAAA,CAAU;AAAA,QACnB,gBAAgB,UAAA,CAAW,cAAA;AAAA,QAC3B,SAAA,EAAW;AAAA,OACZ,CAAA;AAAA,MACD,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAED,IAAA,IAAI,aAAa,EAAA,EAAI;AACnB,MAAA,MAAM,IAAA,GAAQ,MAAM,YAAA,CAAa,IAAA,EAAK;AAKtC,MAAA,IAAI,CAAC,IAAA,CAAK,kBAAA,IAAsB,CAAC,KAAK,aAAA,EAAe;AACnD,QAAA,MAAM,IAAI,MAAM,4DAA4D,CAAA;AAAA,MAC9E;AAEA,MAAA,MAAM,cAAc,MAAM,yBAAA;AAAA,QACxB,IAAA,CAAK,kBAAA;AAAA,QACL,IAAA,CAAK,aAAA;AAAA,QACL;AAAA,OACF;AACA,MAAA,IAAI,WAAA,CAAY,SAAS,SAAA,EAAW;AAClC,QAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,MACzC;AAEA,MAAA,MAAM,SAAA,GAAY,iBAAiB,WAAW,CAAA;AAC9C,MAAA,OAAO;AAAA,QACL,QAAQ,WAAA,CAAY,MAAA;AAAA,QACpB,SAAS,WAAA,CAAY,OAAA;AAAA,QACrB,SAAS,WAAA,CAAY,OAAA;AAAA,QACrB;AAAA,OACF;AAAA,IACF;AAEA,IAAA,IAAI,YAAA,CAAa,MAAA,KAAW,GAAA,IAAO,YAAA,CAAa,WAAW,GAAA,EAAK;AAC9D,MAAA,MAAM,OAAO,MAAM,YAAA,CAAa,MAAK,CAAE,KAAA,CAAM,MAAM,EAAE,CAAA;AACrD,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,0CAAA,EAA6C,YAAA,CAAa,MAAM,CAAA,EAAG,IAAA,GAAO,CAAA,CAAA,EAAI,IAAI,CAAA,CAAA,GAAK,EAAE,CAAA,CAAE,CAAA;AAAA,IAC7G;AAEA,IAAA,OAAA,CAAQ,aAAa,kDAAkD,CAAA;AACvE,IAAA,MAAM,MAAM,WAAW,CAAA;AAAA,EACzB;AACF;AAaA,eAAsB,iBAAiB,OAAA,EAQT;AAC5B,EAAA,MAAM,OAAA,GACJ,OAAO,OAAA,KAAY,WAAA,IAAe,QAAQ,GAAA,EAAK,iCAAA,KAAsC,WACjF,QAAA,GACA,MAAA;AACN,EAAA,MAAM,IAAA,GAAO,OAAA,CAAQ,IAAA,IAAQ,OAAA,IAAW,SAAA;AACxC,EAAA,IAAI,SAAS,QAAA,EAAU;AACrB,IAAA,OAAO,sBAAA,CAAuB;AAAA,MAC5B,QAAQ,OAAA,CAAQ,MAAA;AAAA,MAChB,YAAY,OAAA,CAAQ,UAAA;AAAA,MACpB,QAAQ,OAAA,CAAQ;AAAA,KACjB,CAAA;AAAA,EACH;AAEA,EAAA,MAAM,KAAA,GAAQ,MAAM,WAAA,EAAY;AAChC,EAAA,MAAM,MAAA,GAAS,MAAM,qBAAA,CAAsB,KAAK,CAAA;AAChD,EAAA,IAAI,OAAO,OAAA,EAAS;AAClB,IAAA,OAAA,CAAQ,UAAA,GAAa,OAAO,OAAO,CAAA;AAAA,EACrC;AACA,EAAA,MAAM,EAAE,QAAA,EAAU,GAAA,EAAI,GAAI,MAAM,uBAAA;AAAA,IAC9B,MAAA,CAAO,WAAA;AAAA,IACP,KAAA;AAAA,IACA,QAAQ,UAAA,IAAc;AAAA,GACxB;AAEA,EAAA,OAAA,CAAQ,MAAA,CAAO;AAAA,IACb,GAAA;AAAA,IACA,cAAc,MAAA,CAAO,OAAA,GACjB,CAAA,EAAG,MAAA,CAAO,OAAO,CAAA,0EAAA,CAAA,GACjB;AAAA,GACL,CAAA;AAED,EAAA,IAAI,IAAA;AACJ,EAAA,IAAI;AACF,IAAA,IAAI,QAAQ,iBAAA,EAAmB;AAE7B,MAAA,IAAI,UAAA;AACJ,MAAA,IAAI,WAAA;AACJ,MAAA,MAAM,aAAA,GAAgB,OAAA,CACnB,iBAAA,EAAkB,CAClB,KAAK,CAAA,KAAA,KAAS;AACb,QAAA,UAAA,GAAa,KAAA;AACb,QAAA,MAAA,CAAO,UAAA,EAAW;AAAA,MACpB,CAAC,CAAA,CACA,KAAA,CAAM,CAAA,GAAA,KAAO;AACZ,QAAA,WAAA,GAAc,eAAe,KAAA,GAAQ,GAAA,GAAM,IAAI,KAAA,CAAM,MAAA,CAAO,GAAG,CAAC,CAAA;AAChE,QAAA,MAAA,CAAO,UAAA,EAAW;AAAA,MACpB,CAAC,CAAA;AAEH,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,WAAA,EAAY;AAGxC,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,MAAM,WAAA;AAAA,MACR;AAEA,MAAA,IAAI,QAAQ,IAAA,EAAM;AAEhB,QAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,MAChB,WAAW,UAAA,EAAY;AAErB,QAAA,MAAM,MAAA,GAAS,wBAAwB,UAAU,CAAA;AACjD,QAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,KAAU,KAAA,EAAO;AAC1C,UAAA,MAAM,IAAI,MAAM,gBAAgB,CAAA;AAAA,QAClC;AACA,QAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,MAChB;AAGA,MAAA,IAAI,CAAC,IAAA,EAAM;AACT,QAAA,MAAM,aAAA;AACN,QAAA,IAAI,WAAA,EAAa;AACf,UAAA,MAAM,WAAA;AAAA,QACR;AACA,QAAA,IAAI,UAAA,EAAY;AACd,UAAA,MAAM,MAAA,GAAS,wBAAwB,UAAU,CAAA;AACjD,UAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,KAAU,KAAA,EAAO;AAC1C,YAAA,MAAM,IAAI,MAAM,gBAAgB,CAAA;AAAA,UAClC;AACA,UAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,QAChB;AAAA,MACF;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,MAAM,MAAA,GAAS,MAAM,MAAA,CAAO,WAAA,EAAY;AACxC,MAAA,IAAI,QAAQ,IAAA,EAAM;AAChB,QAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,MAChB;AAAA,IACF;AAGA,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,KAAA,GAAQ,MAAM,OAAA,CAAQ,QAAA,CAAS;AAAA,QACnC,OAAA,EAAS;AAAA,OACV,CAAA;AACD,MAAA,MAAM,MAAA,GAAS,wBAAwB,KAAK,CAAA;AAC5C,MAAA,IAAI,MAAA,CAAO,KAAA,IAAS,MAAA,CAAO,KAAA,KAAU,KAAA,EAAO;AAC1C,QAAA,MAAM,IAAI,MAAM,gBAAgB,CAAA;AAAA,MAClC;AACA,MAAA,IAAA,GAAO,MAAA,CAAO,IAAA;AAAA,IAChB;AAEA,IAAA,IAAI,CAAC,IAAA,EAAM;AACT,MAAA,MAAM,IAAI,MAAM,4BAA4B,CAAA;AAAA,IAC9C;AAEA,IAAA,MAAM,cAAc,MAAM,yBAAA,CAA0B,IAAA,EAAM,QAAA,EAAU,OAAO,WAAW,CAAA;AACtF,IAAA,IAAI,WAAA,CAAY,SAAS,SAAA,EAAW;AAClC,MAAA,MAAM,IAAI,MAAM,uBAAuB,CAAA;AAAA,IACzC;AAEA,IAAA,MAAM,SAAA,GAAY,iBAAiB,WAAW,CAAA;AAE9C,IAAA,OAAO;AAAA,MACL,QAAQ,WAAA,CAAY,MAAA;AAAA,MACpB,SAAS,WAAA,CAAY,OAAA;AAAA,MACrB,SAAS,WAAA,CAAY,OAAA;AAAA,MACrB;AAAA,KACF;AAAA,EACF,CAAA,SAAE;AACA,IAAA,MAAA,CAAO,KAAA,EAAM;AAAA,EACf;AACF;AAeA,eAAsB,uBAAA,CACpB,cACA,iBAAA,EAC2B;AAC3B,EAAA,MAAM,MAAA,GAAS,MAAM,kBAAA,CAAmB,YAAY,CAAA;AACpD,EAAA,IAAI,MAAA,CAAO,SAAS,SAAA,EAAW;AAC7B,IAAA,MAAM,IAAI,MAAM,sCAAsC,CAAA;AAAA,EACxD;AAEA,EAAA,MAAM,SAAA,GAAY,gBAAA,CAAiB,MAAA,EAAQ,iBAAiB,CAAA;AAE5D,EAAA,OAAO;AAAA,IACL,QAAQ,MAAA,CAAO,MAAA;AAAA,IACf,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB,SAAS,MAAA,CAAO,OAAA;AAAA,IAChB;AAAA,GACF;AACF;AAEO,IAAM,wBAAA,GAAmD;AAAA,EAC9D,EAAA,EAAI,cAAA;AAAA,EACJ,IAAA,EAAM,uCAAA;AAAA,EACN,kBAAA,EAAoB,IAAA;AAAA,EACpB,SAAA,EAAW,uBAAA;AAAA,EAEX,MAAM,MAAM,SAAA,EAA2D;AACrE,IAAA,MAAM,IAAA,GAAO,UAAU,QAAA,KAAa,QAAA,IAAY,UAAU,QAAA,KAAa,SAAA,GAAY,UAAU,QAAA,GAAW,MAAA;AACxG,IAAA,OAAO,gBAAA,CAAiB;AAAA,MACtB,QAAQ,SAAA,CAAU,MAAA;AAAA,MAClB,UAAU,SAAA,CAAU,QAAA;AAAA,MACpB,YAAY,SAAA,CAAU,UAAA;AAAA,MACtB,mBAAmB,SAAA,CAAU,iBAAA;AAAA,MAC7B,QAAQ,SAAA,CAAU,MAAA;AAAA,MAClB;AAAA,KACD,CAAA;AAAA,EACH,CAAA;AAAA,EAEA,MAAM,aAAa,WAAA,EAA0D;AAC3E,IAAA,OAAO,uBAAA,CAAwB,WAAA,CAAY,OAAA,EAAS,WAAA,CAAY,SAA+B,CAAA;AAAA,EACjG,CAAA;AAAA,EAEA,UAAU,WAAA,EAAuC;AAC/C,IAAA,OAAO,WAAA,CAAY,MAAA;AAAA,EACrB;AACF,CAAA;;;ACzrBO,IAAM,uBAAA,GAA2D;AAAA,EACtE,SAAA,EAAW,2BAAA;AAAA,EACX,cAAA,EAAgB,gBAAA;AAAA;AAAA;AAAA;AAAA,EAIhB,gBAAA,EAAkB;AACpB;AAGA,IAAM,qBAAA,uBAA4B,GAAA,CAAoC;AAAA,EACpE,CAAC,sBAAA,CAAuB,EAAA,EAAI,sBAAsB,CAAA;AAAA,EAClD,CAAC,wBAAA,CAAyB,EAAA,EAAI,wBAAwB,CAAA;AAAA,EACtD,CAAC,0BAAA,CAA2B,EAAA,EAAI,0BAA0B;AAC5D,CAAC,CAAA;AAKM,SAAS,iBAAiB,EAAA,EAAyD;AACxF,EAAA,OAAO,qBAAA,CAAsB,IAAI,EAAE,CAAA;AACrC;AAKO,SAAS,iBAAA,GAA8C;AAC5D,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,qBAAA,CAAsB,MAAA,EAAQ,CAAA;AAClD;AAKO,IAAM,cAAN,MAAkB;AAAA,EAGvB,YAAoB,QAAA,GAAmB,IAAA,CAAK,aAAA,EAAc,EAAG,WAAW,CAAA,EAAG;AAAvD,IAAA,IAAA,CAAA,QAAA,GAAA,QAAA;AAClB,IAAA,IAAA,CAAK,MAAA,EAAO;AAAA,EACd;AAAA,EAFoB,QAAA;AAAA,EAFZ,OAAwB,EAAC;AAAA;AAAA;AAAA;AAAA,EASjC,MAAA,GAAe;AACb,IAAA,IAAI,CAAC,UAAA,CAAW,IAAA,CAAK,QAAQ,CAAA,EAAG;AAC9B,MAAA,IAAA,CAAK,OAAO,EAAC;AACb,MAAA;AAAA,IACF;AACA,IAAA,IAAI;AACF,MAAA,IAAA,CAAK,OAAO,IAAA,CAAK,KAAA,CAAM,aAAa,IAAA,CAAK,QAAA,EAAU,OAAO,CAAC,CAAA;AAAA,IAC7D,CAAA,CAAA,MAAQ;AACN,MAAA,IAAA,CAAK,OAAO,EAAC;AAAA,IACf;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKQ,IAAA,GAAa;AACnB,IAAA,MAAM,GAAA,GAAM,OAAA,CAAQ,IAAA,CAAK,QAAQ,CAAA;AACjC,IAAA,IAAI,CAAC,UAAA,CAAW,GAAG,CAAA,EAAG;AACpB,MAAA,SAAA,CAAU,KAAK,EAAE,SAAA,EAAW,IAAA,EAAM,IAAA,EAAM,KAAO,CAAA;AAAA,IACjD;AACA,IAAA,aAAA,CAAc,IAAA,CAAK,UAAU,IAAA,CAAK,SAAA,CAAU,KAAK,IAAA,EAAM,IAAA,EAAM,CAAC,CAAA,EAAG,OAAO,CAAA;AACxE,IAAA,SAAA,CAAU,IAAA,CAAK,UAAU,GAAK,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAA,EAA8C;AAChD,IAAA,OAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,IAAK,MAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAI,UAAkB,UAAA,EAAkC;AACtD,IAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA,GAAI,UAAA;AACtB,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAAA,EAAwB;AAC7B,IAAA,OAAO,IAAA,CAAK,KAAK,QAAQ,CAAA;AACzB,IAAA,IAAA,CAAK,IAAA,EAAK;AAAA,EACZ;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,GAAiB;AACf,IAAA,OAAO,MAAA,CAAO,IAAA,CAAK,IAAA,CAAK,IAAI,CAAA;AAAA,EAC9B;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,QAAA,EAA2B;AAC7B,IAAA,OAAO,YAAY,IAAA,CAAK,IAAA;AAAA,EAC1B;AAAA;AAAA;AAAA;AAAA,EAKA,WAAW,QAAA,EAA2B;AACpC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,QAAQ,CAAA;AAC/B,IAAA,OAAO,MAAM,IAAA,KAAS,OAAA;AAAA,EACxB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,gBAAgB,QAAA,EAA2B;AACzC,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAE,CAAA;AAC3C,IAAA,OAAO,IAAA,EAAM,IAAA,KAAS,SAAA,IAAa,IAAA,CAAK,IAAI,MAAA,GAAS,CAAA;AAAA,EACvD;AAAA;AAAA;AAAA;AAAA,EAKA,gBAAgB,QAAA,EAAsC;AACpD,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,CAAA,OAAA,EAAU,QAAQ,CAAA,CAAE,CAAA;AAC3C,IAAA,OAAO,IAAA,EAAM,SAAS,SAAA,IAAa,IAAA,CAAK,IAAI,MAAA,GAAS,CAAA,GAAI,KAAK,GAAA,GAAM,MAAA;AAAA,EACtE;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,eAAA,CAAgB,QAAA,EAAkB,GAAA,EAAa,MAAA,EAAuB;AACpE,IAAA,IAAA,CAAK,GAAA,CAAI,UAAU,QAAQ,CAAA,CAAA,EAAI,EAAE,IAAA,EAAM,SAAA,EAAW,KAAK,CAAA;AACvD,IAAA,IAAI,MAAA,EAAQ;AACV,MAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,GAAI,GAAA;AAAA,IACxB;AAAA,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,yBAAyB,eAAA,EAA2D;AAClF,IAAA,KAAA,MAAW,CAAC,KAAK,IAAI,CAAA,IAAK,OAAO,OAAA,CAAQ,IAAA,CAAK,IAAI,CAAA,EAAG;AACnD,MAAA,IAAI,CAAC,GAAA,CAAI,UAAA,CAAW,SAAS,CAAA,IAAK,KAAK,IAAA,KAAS,SAAA,IAAa,CAAC,IAAA,CAAK,GAAA,EAAK;AACxE,MAAA,MAAM,QAAA,GAAW,GAAA,CAAI,SAAA,CAAU,SAAA,CAAU,MAAM,CAAA;AAC/C,MAAA,MAAM,MAAA,GAAS,gBAAgB,QAAQ,CAAA;AACvC,MAAA,IAAI,MAAA,IAAU,CAAC,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,EAAG;AAClC,QAAA,OAAA,CAAQ,GAAA,CAAI,MAAM,CAAA,GAAI,IAAA,CAAK,GAAA;AAAA,MAC7B;AAAA,IACF;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,KAAA,CAAM,UAAA,EAA6B,SAAA,EAA+C;AACtF,IAAA,MAAM,QAAA,GAAW,iBAAiB,UAAU,CAAA;AAC5C,IAAA,IAAI,CAAC,QAAA,EAAU;AACb,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,wBAAA,EAA2B,UAAU,CAAA,CAAE,CAAA;AAAA,IACzD;AAEA,IAAA,MAAM,WAAA,GAAc,MAAM,QAAA,CAAS,KAAA,CAAM,SAAS,CAAA;AAClD,IAAA,IAAA,CAAK,IAAI,UAAA,EAAY,EAAE,MAAM,OAAA,EAAS,GAAG,aAAa,CAAA;AAAA,EACxD;AAAA;AAAA;AAAA;AAAA,EAKA,OAAO,QAAA,EAAwB;AAC7B,IAAA,IAAA,CAAK,OAAO,QAAQ,CAAA;AAAA,EACtB;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAU,UAAA,EAAiD;AAC/D,IAAA,MAAM,IAAA,GAAO,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA;AAEjC,IAAA,IAAI,IAAA,EAAM,SAAS,SAAA,EAAW;AAC5B,MAAA,OAAO,IAAA,CAAK,GAAA;AAAA,IACd;AAEA,IAAA,IAAI,IAAA,EAAM,SAAS,OAAA,EAAS;AAC1B,MAAA,MAAM,QAAA,GAAW,iBAAiB,UAAU,CAAA;AAC5C,MAAA,IAAI,CAAC,QAAA,EAAU;AACb,QAAA,OAAO,MAAA;AAAA,MACT;AAGA,MAAA,IAAI,IAAA,CAAK,GAAA,EAAI,IAAK,IAAA,CAAK,OAAA,EAAS;AAC9B,QAAA,IAAI;AACF,UAAA,MAAM,QAAA,GAAW,MAAM,QAAA,CAAS,YAAA,CAAa,IAAI,CAAA;AACjD,UAAA,IAAA,CAAK,IAAI,UAAA,EAAY,EAAE,MAAM,OAAA,EAAS,GAAG,UAAU,CAAA;AACnD,UAAA,OAAO,QAAA,CAAS,UAAU,QAAQ,CAAA;AAAA,QACpC,CAAA,CAAA,MAAQ;AAEN,UAAA,OAAO,MAAA;AAAA,QACT;AAAA,MACF;AAEA,MAAA,OAAO,QAAA,CAAS,UAAU,IAAI,CAAA;AAAA,IAChC;AAEA,IAAA,OAAO,MAAA;AAAA,EACT;AACF","file":"chunk-5FT2NNFO.js","sourcesContent":["import * as path from 'node:path';\n\n// Default config directory name used for all project-level and global config paths.\nexport const DEFAULT_CONFIG_DIR = '.mastracode';\n\n/**\n * Validate that a configDirName is a safe single directory name.\n * Rejects absolute paths, path separators, and traversal components.\n */\nexport function validateConfigDirName(configDirName: string): void {\n if (configDirName.trim().length === 0) {\n throw new Error('configDirName must be a non-empty directory name');\n }\n\n if (\n path.isAbsolute(configDirName) ||\n configDirName.includes('/') ||\n configDirName.includes('\\\\') ||\n configDirName === '..' ||\n configDirName === '.'\n ) {\n throw new Error(\n `configDirName must be a single directory name without path separators or traversal components, got: \"${configDirName}\"`,\n );\n }\n}\n\n// Default OM model - using gemini-2.5-flash for efficiency\nexport const DEFAULT_OM_MODEL_ID = process.env.DEFAULT_OM_MODEL_ID ?? 'google/gemini-2.5-flash';\n\n// Default OM thresholds — per-thread overrides are loaded from thread metadata\nexport const DEFAULT_OBS_THRESHOLD = 30_000;\nexport const DEFAULT_REF_THRESHOLD = 40_000;\n","/**\n * Project detection utilities\n *\n * Detects project identity from git repo or filesystem path.\n * Handles git worktrees by finding the main repository.\n */\n\nimport { execFile, execSync } from 'node:child_process';\nimport { createHash } from 'node:crypto';\nimport fs from 'node:fs';\nimport os from 'node:os';\nimport path from 'node:path';\nimport { DEFAULT_CONFIG_DIR } from '../constants.js';\nexport interface ProjectInfo {\n /** Unique resource ID for this project (used for thread grouping) */\n resourceId: string;\n /** Human-readable project name */\n name: string;\n /** Absolute path to the project root */\n rootPath: string;\n /** Git remote URL if available */\n gitUrl?: string;\n /** Current git branch */\n gitBranch?: string;\n /** Whether this is a git worktree */\n isWorktree: boolean;\n /** Path to main git repo (different from rootPath if worktree) */\n mainRepoPath?: string;\n /** Whether the resourceId was explicitly overridden (env var or config) */\n resourceIdOverride?: boolean;\n}\n\n/**\n * Run a git command and return stdout, or undefined if it fails\n */\nfunction git(args: string, cwd: string): string | undefined {\n try {\n return execSync(`git ${args}`, {\n cwd,\n encoding: 'utf-8',\n stdio: ['pipe', 'pipe', 'pipe'],\n }).trim();\n } catch {\n return undefined;\n }\n}\n\n/**\n * Slugify a string for use in IDs\n */\nfunction slugify(str: string): string {\n return str\n .toLowerCase()\n .replace(/[^a-z0-9]+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\n/**\n * Create a short hash of a string\n */\nfunction shortHash(str: string): string {\n return createHash('sha256').update(str).digest('hex').slice(0, 12);\n}\n\n/**\n * Normalize a git URL to a canonical form for comparison\n * - Removes .git suffix\n * - Converts SSH to HTTPS format for consistency\n * - Lowercases\n */\nfunction normalizeGitUrl(url: string): string {\n return url\n .replace(/\\.git$/, '')\n .replace(/^git@([^:]+):/, 'https://$1/')\n .replace(/^ssh:\\/\\/git@/, 'https://')\n .toLowerCase();\n}\n\n/**\n * Detect project info from a directory path\n */\nexport function detectProject(projectPath: string): ProjectInfo {\n const absolutePath = path.resolve(projectPath);\n\n // Check if this is a git repo\n const gitDir = git('rev-parse --git-dir', absolutePath);\n const isGitRepo = gitDir !== undefined;\n\n let rootPath = absolutePath;\n let gitUrl: string | undefined;\n let gitBranch: string | undefined;\n let isWorktree = false;\n let mainRepoPath: string | undefined;\n\n if (isGitRepo) {\n // Get the repo root (handles being in a subdirectory)\n rootPath = git('rev-parse --show-toplevel', absolutePath) || absolutePath;\n\n // Check for worktree - git-common-dir differs from git-dir in worktrees\n const commonDir = git('rev-parse --git-common-dir', absolutePath);\n if (commonDir && commonDir !== '.git' && commonDir !== gitDir) {\n isWorktree = true;\n // The common dir is inside the main repo's .git folder\n mainRepoPath = path.dirname(path.resolve(rootPath, commonDir));\n }\n\n // Get remote URL (prefer origin, fall back to first remote)\n gitUrl = git('remote get-url origin', absolutePath);\n if (!gitUrl) {\n const remotes = git('remote', absolutePath);\n if (remotes) {\n const firstRemote = remotes.split('\\n')[0];\n if (firstRemote) {\n gitUrl = git(`remote get-url ${firstRemote}`, absolutePath);\n }\n }\n }\n\n // Get current branch\n gitBranch = git('rev-parse --abbrev-ref HEAD', absolutePath);\n }\n\n // Generate resource ID\n // Priority: normalized git URL > main repo path (for worktrees) > absolute path\n let resourceIdSource: string;\n if (gitUrl) {\n resourceIdSource = normalizeGitUrl(gitUrl);\n } else if (mainRepoPath) {\n resourceIdSource = mainRepoPath;\n } else {\n resourceIdSource = rootPath;\n }\n\n // Create a readable but unique resource ID\n // Format: slugified-name-shorthash\n const baseName = gitUrl\n ? gitUrl\n .split('/')\n .pop()\n ?.replace(/\\.git$/, '') || 'project'\n : path.basename(rootPath);\n\n const resourceId = `${slugify(baseName)}-${shortHash(resourceIdSource)}`;\n\n return {\n resourceId,\n name: baseName,\n rootPath,\n gitUrl,\n gitBranch,\n isWorktree,\n mainRepoPath,\n };\n}\n\n/**\n * Get the current git branch for a given directory.\n * Lightweight alternative to detectProject() for refreshing just the branch.\n */\nexport function getCurrentGitBranch(cwd: string): string | undefined {\n return git('rev-parse --abbrev-ref HEAD', cwd);\n}\n\n/**\n * Async version of getCurrentGitBranch — avoids blocking the event loop\n * with execSync. Falls back to undefined on any failure.\n */\nexport function getCurrentGitBranchAsync(cwd: string): Promise<string | undefined> {\n return new Promise(resolve => {\n execFile('git', ['rev-parse', '--abbrev-ref', 'HEAD'], { cwd, encoding: 'utf-8' }, (err, stdout) => {\n if (err) {\n resolve(undefined);\n return;\n }\n const branch = stdout.trim();\n resolve(branch || undefined);\n });\n });\n}\n\n/**\n * Get the application data directory for mastracode\n * - macOS: ~/Library/Application Support/mastracode\n * - Linux: ~/.local/share/mastracode\n * - Windows: %APPDATA%/mastracode\n */\nexport function getAppDataDir(): string {\n const platform = os.platform();\n let baseDir: string;\n\n if (platform === 'darwin') {\n baseDir = path.join(os.homedir(), 'Library', 'Application Support');\n } else if (platform === 'win32') {\n baseDir = process.env.APPDATA || path.join(os.homedir(), 'AppData', 'Roaming');\n } else {\n // Linux and others - follow XDG spec\n baseDir = process.env.XDG_DATA_HOME || path.join(os.homedir(), '.local', 'share');\n }\n\n const appDir = path.join(baseDir, 'mastracode');\n\n // Ensure directory exists\n if (!fs.existsSync(appDir)) {\n fs.mkdirSync(appDir, { recursive: true });\n }\n\n return appDir;\n}\n/**\n * Get the database path for mastracode\n * Can be overridden with the MASTRA_DB_PATH environment variable for debugging.\n */\nexport function getDatabasePath(): string {\n if (process.env.MASTRA_DB_PATH) {\n return process.env.MASTRA_DB_PATH;\n }\n return path.join(getAppDataDir(), 'mastra.db');\n}\n\n/**\n * Get the vector database path for mastracode.\n * Separate from the main DB to avoid bloating it with embedding data.\n */\nexport function getVectorDatabasePath(): string {\n return path.join(getAppDataDir(), 'mastra-vectors.db');\n}\n\n/**\n * Get the observability DuckDB database path for mastracode.\n * Separate from the main DB — DuckDB is used for OLAP-style trace/score/feedback queries.\n * Can be overridden with the MASTRA_OBSERVABILITY_DB_PATH environment variable.\n */\nexport function getObservabilityDatabasePath(): string {\n if (process.env.MASTRA_OBSERVABILITY_DB_PATH) {\n return process.env.MASTRA_OBSERVABILITY_DB_PATH;\n }\n return path.join(getAppDataDir(), 'observability.duckdb');\n}\n\nimport type { StorageBackend, StorageSettings } from '../onboarding/settings.js';\n\n/**\n * LibSQL storage configuration.\n */\nexport interface LibSQLStorageConfig {\n backend: 'libsql';\n url: string;\n authToken?: string;\n isRemote: boolean;\n}\n\n/**\n * PostgreSQL storage configuration.\n */\nexport interface PgStorageConfig {\n backend: 'pg';\n connectionString?: string;\n host?: string;\n port?: number;\n database?: string;\n user?: string;\n password?: string;\n schemaName?: string;\n disableInit?: boolean;\n skipDefaultIndexes?: boolean;\n}\n\n/**\n * Resolved storage configuration for either backend.\n */\nexport type StorageConfig = LibSQLStorageConfig | PgStorageConfig;\n\n/**\n * Get the resolved storage configuration.\n *\n * Priority (highest to lowest):\n * 1. Environment variables: MASTRA_STORAGE_BACKEND + backend-specific vars\n * 2. Global settings (from /settings): settings.storage\n * 3. Legacy config files: .mastracode/database.json (LibSQL only)\n * 4. Local file database (LibSQL default)\n *\n * For PG, the env vars are:\n * MASTRA_STORAGE_BACKEND=pg\n * MASTRA_PG_CONNECTION_STRING or MASTRA_PG_HOST/PORT/DATABASE/USER/PASSWORD\n * MASTRA_PG_SCHEMA_NAME (optional)\n *\n * For LibSQL, the legacy env vars still work:\n * MASTRA_DB_URL + MASTRA_DB_AUTH_TOKEN\n */\nexport function getStorageConfig(\n projectDir?: string,\n storageSettings?: StorageSettings,\n configDirName = DEFAULT_CONFIG_DIR,\n): StorageConfig {\n // 1. Environment variable — explicit backend selection\n const envBackend = process.env.MASTRA_STORAGE_BACKEND as StorageBackend | undefined;\n\n if (envBackend === 'pg') {\n return resolvePgFromEnv();\n }\n\n // Legacy LibSQL env vars (MASTRA_DB_URL) — treat as explicit libsql\n if (envBackend === 'libsql' || process.env.MASTRA_DB_URL) {\n return resolveLibSQLFromEnv();\n }\n\n // 2. Global settings (from /settings)\n if (storageSettings && storageSettings.backend === 'pg') {\n return resolvePgFromSettings(storageSettings);\n }\n\n if (storageSettings && storageSettings.backend === 'libsql' && storageSettings.libsql.url) {\n return {\n backend: 'libsql',\n url: storageSettings.libsql.url,\n authToken: storageSettings.libsql.authToken,\n isRemote: !storageSettings.libsql.url.startsWith('file:'),\n };\n }\n\n // 3. Legacy project/global config files (.mastracode/database.json)\n if (projectDir) {\n const projectConfig = loadDatabaseConfig(path.join(projectDir, configDirName, 'database.json'));\n if (projectConfig) return projectConfig;\n }\n const globalConfig = loadDatabaseConfig(path.join(os.homedir(), configDirName, 'database.json'));\n if (globalConfig) return globalConfig;\n\n // 4. Default: local LibSQL file database\n return {\n backend: 'libsql',\n url: `file:${getDatabasePath()}`,\n isRemote: false,\n };\n}\n\nfunction resolveLibSQLFromEnv(): LibSQLStorageConfig {\n const url = process.env.MASTRA_DB_URL!;\n return {\n backend: 'libsql',\n url,\n authToken: process.env.MASTRA_DB_AUTH_TOKEN,\n isRemote: !url.startsWith('file:'),\n };\n}\n\nfunction resolvePgFromEnv(): PgStorageConfig {\n const connectionString = process.env.MASTRA_PG_CONNECTION_STRING;\n if (connectionString) {\n return {\n backend: 'pg',\n connectionString,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n }\n\n // Host/port style\n return {\n backend: 'pg',\n host: process.env.MASTRA_PG_HOST,\n port: process.env.MASTRA_PG_PORT ? parseInt(process.env.MASTRA_PG_PORT, 10) : undefined,\n database: process.env.MASTRA_PG_DATABASE,\n user: process.env.MASTRA_PG_USER,\n password: process.env.MASTRA_PG_PASSWORD,\n schemaName: process.env.MASTRA_PG_SCHEMA_NAME,\n };\n}\n\nfunction resolvePgFromSettings(settings: StorageSettings): PgStorageConfig {\n const pg = settings.pg;\n return {\n backend: 'pg',\n connectionString: pg.connectionString,\n host: pg.host,\n port: pg.port,\n database: pg.database,\n user: pg.user,\n password: pg.password,\n schemaName: pg.schemaName,\n disableInit: pg.disableInit,\n skipDefaultIndexes: pg.skipDefaultIndexes,\n };\n}\n\n/**\n * Load database config from a legacy JSON file.\n * Expected format: { \"url\": \"libsql://...\", \"authToken\": \"...\" }\n */\nfunction loadDatabaseConfig(filePath: string): LibSQLStorageConfig | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (typeof parsed?.url === 'string' && parsed.url) {\n return {\n backend: 'libsql',\n url: parsed.url,\n authToken: typeof parsed.authToken === 'string' ? parsed.authToken : undefined,\n isRemote: !parsed.url.startsWith('file:'),\n };\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get the current user identity.\n *\n * Priority:\n * 1. MASTRA_USER_ID environment variable\n * 2. git config user.email (from project dir or global)\n * 3. OS username as fallback\n */\nexport function getUserId(projectDir?: string): string {\n // 1. Environment variable override\n if (process.env.MASTRA_USER_ID) {\n return process.env.MASTRA_USER_ID;\n }\n\n // 2. git user.email\n const cwd = projectDir || process.cwd();\n const email = git('config user.email', cwd);\n if (email) {\n return email;\n }\n\n // 3. OS username fallback\n return os.userInfo().username || 'unknown';\n}\n\n/**\n * Get the current user's display name.\n *\n * Priority:\n * 1. git config user.name\n * 2. OS username as fallback\n */\nexport function getUserName(projectDir?: string): string {\n const cwd = projectDir || process.cwd();\n const name = git('config user.name', cwd);\n if (name) {\n return name;\n }\n return os.userInfo().username || 'unknown';\n}\n\n/**\n * Observational memory scope: \"thread\" (per-conversation) or \"resource\" (shared across threads).\n */\nexport type OmScope = 'thread' | 'resource';\n\n/**\n * Get the configured observational memory scope.\n *\n * Priority:\n * 1. MASTRA_OM_SCOPE environment variable (\"thread\" or \"resource\")\n * 2. Project config: .mastracode/database.json → omScope\n * 3. Global config: ~/.mastracode/database.json → omScope\n * 4. Default: \"thread\"\n */\nexport function getOmScope(projectDir?: string, configDirName = DEFAULT_CONFIG_DIR): OmScope {\n // 1. Environment variable\n const envScope = process.env.MASTRA_OM_SCOPE;\n if (envScope === 'thread' || envScope === 'resource') {\n return envScope;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const scope = loadOmScopeFromConfig(path.join(projectDir, configDirName, 'database.json'));\n if (scope) return scope;\n }\n\n // 3. Global config\n const scope = loadOmScopeFromConfig(path.join(os.homedir(), configDirName, 'database.json'));\n if (scope) return scope;\n\n // 4. Default\n return 'thread';\n}\n\nfunction loadOmScopeFromConfig(filePath: string): OmScope | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n if (parsed?.omScope === 'thread' || parsed?.omScope === 'resource') {\n return parsed.omScope;\n }\n return null;\n } catch {\n return null;\n }\n}\n\n/**\n * Get an explicit resource ID override, if configured.\n *\n * Resource IDs act as shared tags — two users who set the same resourceId\n * will share threads and observations for that resource.\n *\n * Priority:\n * 1. MASTRA_RESOURCE_ID environment variable\n * 2. Project config: .mastracode/database.json → resourceId\n * 3. Global config: ~/.mastracode/database.json → resourceId\n * 4. null (use auto-detected value)\n */\nexport function getResourceIdOverride(projectDir?: string, configDirName = DEFAULT_CONFIG_DIR): string | null {\n // 1. Environment variable\n if (process.env.MASTRA_RESOURCE_ID) {\n return process.env.MASTRA_RESOURCE_ID;\n }\n\n // 2. Project-level config\n if (projectDir) {\n const rid = loadStringField(path.join(projectDir, configDirName, 'database.json'), 'resourceId');\n if (rid) return rid;\n }\n\n // 3. Global config\n const rid = loadStringField(path.join(os.homedir(), configDirName, 'database.json'), 'resourceId');\n if (rid) return rid;\n\n return null;\n}\n\nfunction loadStringField(filePath: string, field: string): string | null {\n try {\n if (!fs.existsSync(filePath)) return null;\n const raw = fs.readFileSync(filePath, 'utf-8');\n const parsed = JSON.parse(raw);\n const value = parsed?.[field];\n if (typeof value === 'string' && value) {\n return value;\n }\n return null;\n } catch {\n return null;\n }\n}\n","/**\n * PKCE utilities using Web Crypto API.\n * Works in both Node.js 20+ and browsers.\n */\n\n/**\n * Encode bytes as base64url string.\n */\nfunction base64urlEncode(bytes: Uint8Array): string {\n let binary = '';\n for (const byte of bytes) {\n binary += String.fromCharCode(byte);\n }\n return btoa(binary).replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '');\n}\n\n/**\n * Generate PKCE code verifier and challenge.\n * Uses Web Crypto API for cross-platform compatibility.\n */\nexport async function generatePKCE(): Promise<{\n verifier: string;\n challenge: string;\n}> {\n // Generate random verifier\n const verifierBytes = new Uint8Array(32);\n crypto.getRandomValues(verifierBytes);\n const verifier = base64urlEncode(verifierBytes);\n\n // Compute SHA-256 challenge\n const encoder = new TextEncoder();\n const data = encoder.encode(verifier);\n const hashBuffer = await crypto.subtle.digest('SHA-256', data);\n const challenge = base64urlEncode(new Uint8Array(hashBuffer));\n\n return { verifier, challenge };\n}\n","/**\n * Anthropic OAuth flow (Claude Pro/Max)\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/anthropic.ts\n */\n\nimport { generatePKCE } from '../pkce.js';\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nconst decode = (s: string) => atob(s);\nconst CLIENT_ID = decode('OWQxYzI1MGEtZTYxYi00NGQ5LTg4ZWQtNTk0NGQxOTYyZjVl');\nconst AUTHORIZE_URL = 'https://claude.ai/oauth/authorize';\nconst TOKEN_URL = 'https://console.anthropic.com/v1/oauth/token';\nconst REDIRECT_URI = 'https://console.anthropic.com/oauth/code/callback';\nconst SCOPES = 'org:create_api_key user:profile user:inference';\n\n/**\n * Login with Anthropic OAuth (device code flow)\n */\nexport async function loginAnthropic(\n onAuthUrl: (url: string) => void,\n onPromptCode: () => Promise<string>,\n): Promise<OAuthCredentials> {\n const { verifier, challenge } = await generatePKCE();\n\n // Build authorization URL\n const authParams = new URLSearchParams({\n code: 'true',\n client_id: CLIENT_ID,\n response_type: 'code',\n redirect_uri: REDIRECT_URI,\n scope: SCOPES,\n code_challenge: challenge,\n code_challenge_method: 'S256',\n state: verifier,\n });\n\n const authUrl = `${AUTHORIZE_URL}?${authParams.toString()}`;\n\n // Notify caller with URL to open\n onAuthUrl(authUrl);\n\n // Wait for user to paste authorization code (format: code#state)\n const authCode = await onPromptCode();\n const splits = authCode.split('#');\n const code = splits[0];\n const state = splits[1];\n\n // Exchange code for tokens\n const tokenResponse = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n },\n body: JSON.stringify({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code: code,\n state: state,\n redirect_uri: REDIRECT_URI,\n code_verifier: verifier,\n }),\n });\n\n if (!tokenResponse.ok) {\n const error = await tokenResponse.text();\n throw new Error(`Token exchange failed: ${error}`);\n }\n\n const tokenData = (await tokenResponse.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n // Calculate expiry time (current time + expires_in seconds - 5 min buffer)\n const expiresAt = Date.now() + tokenData.expires_in * 1000 - 5 * 60 * 1000;\n\n return {\n refresh: tokenData.refresh_token,\n access: tokenData.access_token,\n expires: expiresAt,\n };\n}\n\n/**\n * Refresh Anthropic OAuth token\n */\nexport async function refreshAnthropicToken(refreshToken: string): Promise<OAuthCredentials> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n grant_type: 'refresh_token',\n client_id: CLIENT_ID,\n refresh_token: refreshToken,\n }),\n });\n\n if (!response.ok) {\n const error = await response.text();\n throw new Error(`Anthropic token refresh failed: ${error}`);\n }\n\n const data = (await response.json()) as {\n access_token: string;\n refresh_token: string;\n expires_in: number;\n };\n\n return {\n refresh: data.refresh_token,\n access: data.access_token,\n expires: Date.now() + data.expires_in * 1000 - 5 * 60 * 1000,\n };\n}\n\nexport const anthropicOAuthProvider: OAuthProviderInterface = {\n id: 'anthropic',\n name: 'Anthropic (Claude Pro/Max)',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginAnthropic(\n url => callbacks.onAuth({ url }),\n () => callbacks.onPrompt({ message: 'Paste the authorization code:' }),\n );\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshAnthropicToken(credentials.refresh);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * GitHub Copilot OAuth flow\n *\n * Inspired by:\n * - pi-mono: https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/github-copilot.ts\n * - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/copilot.ts\n *\n * Storage layout in AuthStorage:\n * - `refresh` holds the long-lived GitHub OAuth access token (used to mint Copilot tokens).\n * - `access` holds the short-lived Copilot bearer token (~30 minutes).\n * - `expires` is the Copilot bearer expiry (ms epoch, with a 5-minute safety buffer).\n * - `enterpriseUrl` is the GitHub Enterprise hostname, or undefined for github.com.\n */\n\nimport type { OAuthCredentials, OAuthLoginCallbacks, OAuthProviderInterface } from '../types.js';\n\nexport type GitHubCopilotCredentials = OAuthCredentials & {\n enterpriseUrl?: string;\n};\n\nconst decode = (s: string): string => atob(s);\n// Copilot's public client ID, encoded to mirror the upstream references.\nconst CLIENT_ID = decode('SXYxLmI1MDdhMDhjODdlY2ZlOTg=');\n\nexport const COPILOT_USER_AGENT = 'GitHubCopilotChat/0.35.0';\n\n/** Headers that Copilot endpoints expect from a VS Code-like client. */\nexport const COPILOT_HEADERS = {\n 'User-Agent': COPILOT_USER_AGENT,\n 'Editor-Version': 'vscode/1.107.0',\n 'Editor-Plugin-Version': 'copilot-chat/0.35.0',\n 'Copilot-Integration-Id': 'vscode-chat',\n} as const;\n\nconst INITIAL_POLL_INTERVAL_MULTIPLIER = 1.2;\nconst SLOW_DOWN_POLL_INTERVAL_MULTIPLIER = 1.4;\n\ntype DeviceCodeResponse = {\n device_code: string;\n user_code: string;\n verification_uri: string;\n interval: number;\n expires_in: number;\n};\n\ntype DeviceTokenSuccessResponse = {\n access_token: string;\n token_type?: string;\n scope?: string;\n};\n\ntype DeviceTokenErrorResponse = {\n error: string;\n error_description?: string;\n interval?: number;\n};\n\n/**\n * Normalize a user-entered Enterprise URL/domain into a hostname (e.g. `company.ghe.com`).\n * Returns null for an empty input or an unparseable URL.\n */\nexport function normalizeDomain(input: string): string | null {\n const trimmed = input.trim();\n if (!trimmed) return null;\n try {\n const url = trimmed.includes('://') ? new URL(trimmed) : new URL(`https://${trimmed}`);\n return url.hostname || null;\n } catch {\n return null;\n }\n}\n\nfunction getUrls(domain: string): {\n deviceCodeUrl: string;\n accessTokenUrl: string;\n copilotTokenUrl: string;\n} {\n return {\n deviceCodeUrl: `https://${domain}/login/device/code`,\n accessTokenUrl: `https://${domain}/login/oauth/access_token`,\n copilotTokenUrl: `https://api.${domain}/copilot_internal/v2/token`,\n };\n}\n\n/**\n * Parse the `proxy-ep` segment from a Copilot bearer token and convert to its API base URL.\n * Token shape: `tid=...;exp=...;proxy-ep=proxy.individual.githubcopilot.com;...`\n */\nfunction getBaseUrlFromToken(token: string): string | null {\n const match = token.match(/proxy-ep=([^;]+)/);\n if (!match) return null;\n const proxyHost = match[1]!;\n const apiHost = proxyHost.replace(/^proxy\\./, 'api.');\n return `https://${apiHost}`;\n}\n\n/**\n * Resolve the Copilot API base URL.\n * Prefers the `proxy-ep` parsed from the bearer token, then falls back to enterprise/individual defaults.\n */\nexport function getGitHubCopilotBaseUrl(token?: string, enterpriseDomain?: string): string {\n if (token) {\n const fromToken = getBaseUrlFromToken(token);\n if (fromToken) return fromToken;\n }\n if (enterpriseDomain) return `https://copilot-api.${enterpriseDomain}`;\n return 'https://api.individual.githubcopilot.com';\n}\n\nasync function fetchJson(url: string, init: RequestInit, signal?: AbortSignal): Promise<unknown> {\n const response = await fetch(url, signal ? { ...init, signal } : init);\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`${response.status} ${response.statusText}: ${text}`);\n }\n return response.json();\n}\n\nasync function startDeviceFlow(domain: string, signal?: AbortSignal): Promise<DeviceCodeResponse> {\n const urls = getUrls(domain);\n const data = await fetchJson(\n urls.deviceCodeUrl,\n {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'User-Agent': COPILOT_USER_AGENT,\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n scope: 'read:user',\n }),\n },\n signal,\n );\n\n if (!data || typeof data !== 'object') {\n throw new Error('Invalid device code response');\n }\n\n const obj = data as Record<string, unknown>;\n const deviceCode = obj.device_code;\n const userCode = obj.user_code;\n const verificationUri = obj.verification_uri;\n const interval = obj.interval;\n const expiresIn = obj.expires_in;\n\n if (\n typeof deviceCode !== 'string' ||\n typeof userCode !== 'string' ||\n typeof verificationUri !== 'string' ||\n typeof interval !== 'number' ||\n typeof expiresIn !== 'number'\n ) {\n throw new Error('Invalid device code response fields');\n }\n\n return {\n device_code: deviceCode,\n user_code: userCode,\n verification_uri: verificationUri,\n interval,\n expires_in: expiresIn,\n };\n}\n\n/** Sleep that can be interrupted by an AbortSignal. */\nfunction abortableSleep(ms: number, signal?: AbortSignal): Promise<void> {\n return new Promise((resolve, reject) => {\n if (signal?.aborted) {\n reject(new Error('Login cancelled'));\n return;\n }\n\n let timeout: ReturnType<typeof setTimeout>;\n const onAbort = () => {\n clearTimeout(timeout);\n reject(new Error('Login cancelled'));\n };\n\n timeout = setTimeout(() => {\n signal?.removeEventListener('abort', onAbort);\n resolve();\n }, ms);\n\n signal?.addEventListener('abort', onAbort, { once: true });\n });\n}\n\nasync function pollForGitHubAccessToken(\n domain: string,\n deviceCode: string,\n intervalSeconds: number,\n expiresIn: number,\n signal?: AbortSignal,\n): Promise<string> {\n const urls = getUrls(domain);\n const deadline = Date.now() + expiresIn * 1000;\n let intervalMs = Math.max(1000, Math.floor(intervalSeconds * 1000));\n let intervalMultiplier = INITIAL_POLL_INTERVAL_MULTIPLIER;\n let slowDownResponses = 0;\n\n while (Date.now() < deadline) {\n if (signal?.aborted) {\n throw new Error('Login cancelled');\n }\n\n const remainingMs = deadline - Date.now();\n const waitMs = Math.min(Math.ceil(intervalMs * intervalMultiplier), remainingMs);\n await abortableSleep(waitMs, signal);\n\n const raw = await fetchJson(\n urls.accessTokenUrl,\n {\n method: 'POST',\n headers: {\n Accept: 'application/json',\n 'Content-Type': 'application/x-www-form-urlencoded',\n 'User-Agent': COPILOT_USER_AGENT,\n },\n body: new URLSearchParams({\n client_id: CLIENT_ID,\n device_code: deviceCode,\n grant_type: 'urn:ietf:params:oauth:grant-type:device_code',\n }),\n },\n signal,\n );\n\n if (raw && typeof raw === 'object' && typeof (raw as DeviceTokenSuccessResponse).access_token === 'string') {\n return (raw as DeviceTokenSuccessResponse).access_token;\n }\n\n if (raw && typeof raw === 'object' && typeof (raw as DeviceTokenErrorResponse).error === 'string') {\n const { error, error_description: description, interval } = raw as DeviceTokenErrorResponse;\n if (error === 'authorization_pending') {\n continue;\n }\n\n if (error === 'slow_down') {\n slowDownResponses += 1;\n intervalMs = typeof interval === 'number' && interval > 0 ? interval * 1000 : Math.max(1000, intervalMs + 5000);\n intervalMultiplier = SLOW_DOWN_POLL_INTERVAL_MULTIPLIER;\n continue;\n }\n\n const descriptionSuffix = description ? `: ${description}` : '';\n throw new Error(`Device flow failed: ${error}${descriptionSuffix}`);\n }\n }\n\n if (slowDownResponses > 0) {\n throw new Error(\n 'Device flow timed out after one or more slow_down responses. This is often caused by clock drift in WSL or VM environments. Please sync or restart the VM clock and try again.',\n );\n }\n\n throw new Error('Device flow timed out');\n}\n\n/**\n * Refresh the short-lived Copilot bearer token using the long-lived GitHub OAuth token.\n *\n * `refreshToken` here is the GitHub OAuth access token; the Copilot endpoint returns a\n * fresh bearer token (`token`) and absolute expiry (`expires_at`, seconds since epoch).\n */\nexport async function refreshGitHubCopilotToken(\n refreshToken: string,\n enterpriseDomain?: string,\n signal?: AbortSignal,\n): Promise<GitHubCopilotCredentials> {\n const domain = enterpriseDomain || 'github.com';\n const urls = getUrls(domain);\n\n const raw = await fetchJson(\n urls.copilotTokenUrl,\n {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${refreshToken}`,\n ...COPILOT_HEADERS,\n },\n },\n signal,\n );\n\n if (!raw || typeof raw !== 'object') {\n throw new Error('Invalid Copilot token response');\n }\n\n const obj = raw as Record<string, unknown>;\n const token = obj.token;\n const expiresAt = obj.expires_at;\n\n if (typeof token !== 'string' || typeof expiresAt !== 'number') {\n throw new Error('Invalid Copilot token response fields');\n }\n\n const credentials: GitHubCopilotCredentials = {\n refresh: refreshToken,\n access: token,\n // expires_at is seconds; subtract 5 minutes so we refresh before actual expiry.\n expires: expiresAt * 1000 - 5 * 60 * 1000,\n };\n if (enterpriseDomain) {\n credentials.enterpriseUrl = enterpriseDomain;\n }\n return credentials;\n}\n\n/**\n * Login with GitHub Copilot OAuth (device-code flow).\n *\n * Prompts for an optional GitHub Enterprise URL/domain, performs the device-code flow,\n * then exchanges the GitHub OAuth token for a Copilot bearer token.\n */\nexport async function loginGitHubCopilot(options: {\n onAuth: (url: string, instructions?: string) => void;\n onPrompt: (prompt: { message: string; placeholder?: string; allowEmpty?: boolean }) => Promise<string>;\n onProgress?: (message: string) => void;\n signal?: AbortSignal;\n}): Promise<GitHubCopilotCredentials> {\n const input = await options.onPrompt({\n message: 'GitHub Enterprise URL/domain (blank for github.com)',\n placeholder: 'company.ghe.com',\n allowEmpty: true,\n });\n\n if (options.signal?.aborted) {\n throw new Error('Login cancelled');\n }\n\n const trimmed = input.trim();\n const enterpriseDomain = normalizeDomain(input);\n if (trimmed && !enterpriseDomain) {\n throw new Error('Invalid GitHub Enterprise URL/domain');\n }\n const domain = enterpriseDomain || 'github.com';\n\n const device = await startDeviceFlow(domain, options.signal);\n options.onAuth(device.verification_uri, `Enter code: ${device.user_code}`);\n\n const githubAccessToken = await pollForGitHubAccessToken(\n domain,\n device.device_code,\n device.interval,\n device.expires_in,\n options.signal,\n );\n\n options.onProgress?.('Fetching Copilot token...');\n return refreshGitHubCopilotToken(githubAccessToken, enterpriseDomain ?? undefined, options.signal);\n}\n\n/**\n * Filtered, normalized entry from the Copilot `/models` API.\n *\n * The full API payload includes a lot of capability metadata; we only keep the bits\n * we need to expose models in `listAvailableModels()` and route requests sensibly.\n */\nexport type CopilotModelEntry = {\n /** Stable model id (e.g. `claude-sonnet-4.5`, `gpt-4.1`). */\n id: string;\n /** Human-readable display name (e.g. `Claude Sonnet 4.5`). */\n name: string;\n /** Vendor field from the API (e.g. `Anthropic`, `OpenAI`). */\n vendor: string;\n /**\n * Endpoints the model exposes (e.g. `/chat/completions`, `/responses`, `/v1/messages`).\n * Empty when the API didn't return `supported_endpoints` for this entry.\n */\n supportedEndpoints: string[];\n /** True when `supported_endpoints` includes `/v1/messages` (Anthropic-shaped Copilot model). */\n isAnthropicShaped: boolean;\n /** True when `capabilities.supports.vision` is true. */\n supportsVision: boolean;\n /** True when the model supports tool calling. */\n supportsToolCalls: boolean;\n};\n\n/**\n * Fetch the Copilot model list available to the current subscription.\n *\n * Hits `${baseURL}/models` with the Copilot bearer token, filters to\n * `model_picker_enabled === true && policy.state !== 'disabled'`, and returns\n * a normalized list. Mirrors opencode's filtering rules.\n *\n * Inspired by:\n * - opencode: https://github.com/anomalyco/opencode/blob/dev/packages/opencode/src/plugin/github-copilot/models.ts\n */\nexport async function fetchCopilotModels(opts: {\n baseUrl: string;\n bearerToken: string;\n signal?: AbortSignal;\n}): Promise<CopilotModelEntry[]> {\n const url = `${opts.baseUrl.replace(/\\/$/, '')}/models`;\n const response = await fetch(url, {\n headers: {\n Accept: 'application/json',\n Authorization: `Bearer ${opts.bearerToken}`,\n ...COPILOT_HEADERS,\n },\n signal: opts.signal,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n throw new Error(`Failed to fetch Copilot models: ${response.status} ${response.statusText}: ${text}`);\n }\n\n const json = await response.json().catch(() => null);\n if (!json || typeof json !== 'object' || !Array.isArray((json as { data?: unknown }).data)) {\n throw new Error('Invalid Copilot models response: missing `data` array');\n }\n\n const data = (json as { data: unknown[] }).data;\n const result: CopilotModelEntry[] = [];\n\n for (const item of data) {\n if (!item || typeof item !== 'object') continue;\n const obj = item as Record<string, unknown>;\n\n if (obj.model_picker_enabled !== true) continue;\n\n const policy = obj.policy as Record<string, unknown> | undefined;\n if (policy && policy.state === 'disabled') continue;\n\n const id = obj.id;\n if (typeof id !== 'string' || !id) continue;\n\n const name = typeof obj.name === 'string' ? obj.name : id;\n const vendor = typeof obj.vendor === 'string' ? obj.vendor : '';\n\n const capabilities = obj.capabilities as Record<string, unknown> | undefined;\n const supports = capabilities?.supports as Record<string, unknown> | undefined;\n const supportsVision = supports?.vision === true;\n const supportsToolCalls = supports?.tool_calls === true;\n\n const rawEndpoints = obj.supported_endpoints;\n const supportedEndpoints = Array.isArray(rawEndpoints)\n ? rawEndpoints.filter((e): e is string => typeof e === 'string')\n : [];\n const isAnthropicShaped = supportedEndpoints.includes('/v1/messages');\n\n result.push({\n id,\n name,\n vendor,\n supportedEndpoints,\n isAnthropicShaped,\n supportsVision,\n supportsToolCalls,\n });\n }\n\n return result;\n}\n\nexport const githubCopilotOAuthProvider: OAuthProviderInterface = {\n id: 'github-copilot',\n name: 'GitHub Copilot',\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n return loginGitHubCopilot({\n onAuth: (url, instructions) => callbacks.onAuth({ url, instructions }),\n onPrompt: callbacks.onPrompt,\n onProgress: callbacks.onProgress,\n signal: callbacks.signal,\n });\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n const creds = credentials as GitHubCopilotCredentials;\n return refreshGitHubCopilotToken(creds.refresh, creds.enterpriseUrl);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * OpenAI Codex (ChatGPT OAuth) flow\n *\n * Inspired by pi-mono's OAuth implementation:\n * https://github.com/badlogic/pi-mono/blob/main/packages/ai/src/utils/oauth/openai-codex.ts\n *\n * NOTE: This module uses Node.js crypto and http for the OAuth callback.\n * It is only intended for CLI use, not browser environments.\n */\n\n// NEVER convert to top-level imports - breaks browser/Vite builds (web-ui)\nlet _randomBytes: ((size: number) => Buffer) | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _cryptoPromise: Promise<typeof import('node:crypto')> | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _httpPromise: Promise<typeof import('node:http')> | null = null;\n// eslint-disable-next-line @typescript-eslint/consistent-type-imports\nlet _http: typeof import('node:http') | null = null;\ntype HttpServer = {\n off: (event: 'error' | 'listening', listener: (...args: any[]) => void) => HttpServer;\n once: (event: 'error' | 'listening', listener: (...args: any[]) => void) => HttpServer;\n listen: (port: number, hostname: string) => HttpServer;\n close: () => void;\n};\nif (typeof process !== 'undefined' && (process.versions?.node || process.versions?.bun)) {\n _cryptoPromise = import('node:crypto').then(m => {\n _randomBytes = m.randomBytes;\n return m;\n });\n _httpPromise = import('node:http').then(m => {\n _http = m;\n return m;\n });\n}\n\nimport { generatePKCE } from '../pkce.js';\nimport type { AuthMode, OAuthCredentials, OAuthLoginCallbacks, OAuthPrompt, OAuthProviderInterface } from '../types.js';\n\nexport const OPENAI_CODEX_AUTH_MODES: ReadonlyArray<AuthMode> = [\n {\n id: 'browser',\n name: 'Browser (local callback)',\n description: 'Opens the browser and waits for the OAuth callback on localhost.',\n },\n {\n id: 'device',\n name: 'Device code (headless)',\n description: 'Shows a code to enter at openai.com — for SSH, remote, or no-browser environments.',\n },\n];\n\nconst CLIENT_ID = 'app_EMoamEEZ73f0CkXaXp7hrann';\nconst ISSUER = 'https://auth.openai.com';\nconst AUTHORIZE_URL = `${ISSUER}/oauth/authorize`;\nconst TOKEN_URL = `${ISSUER}/oauth/token`;\nconst DEVICE_USER_CODE_URL = `${ISSUER}/api/accounts/deviceauth/usercode`;\nconst DEVICE_TOKEN_URL = `${ISSUER}/api/accounts/deviceauth/token`;\nconst DEVICE_AUTHORIZE_URL = `${ISSUER}/codex/device`;\nconst DEVICE_REDIRECT_URI = `${ISSUER}/deviceauth/callback`;\nconst DEFAULT_CALLBACK_PORT = 1455;\nconst FALLBACK_CALLBACK_PORT = 1457;\nconst DEFAULT_TOKEN_EXPIRES_IN_SECONDS = 3600;\nconst DEVICE_AUTH_TIMEOUT_MS = 15 * 60 * 1000;\nconst SCOPE = 'openid profile email offline_access api.connectors.read api.connectors.invoke';\nconst JWT_CLAIM_PATH = 'https://api.openai.com/auth';\n\nconst SUCCESS_HTML = `<!doctype html>\n<html lang=\"en\">\n<head>\n <meta charset=\"utf-8\" />\n <meta name=\"viewport\" content=\"width=device-width, initial-scale=1\" />\n <title>Authentication successful</title>\n</head>\n<body>\n <p>Authentication successful. Return to your terminal to continue.</p>\n</body>\n</html>`;\n\ntype TokenSuccess = {\n type: 'success';\n access: string;\n refresh: string;\n expires: number;\n idToken?: string;\n};\ntype TokenFailure = { type: 'failed' };\ntype TokenResult = TokenSuccess | TokenFailure;\n\ntype JwtPayload = {\n chatgpt_account_id?: string;\n [JWT_CLAIM_PATH]?: {\n chatgpt_account_id?: string;\n };\n [key: string]: unknown;\n};\n\nasync function createState(): Promise<string> {\n const randomBytes = await getRandomBytes();\n return randomBytes(16).toString('hex');\n}\n\nfunction parseAuthorizationInput(input: string): {\n code?: string;\n state?: string;\n} {\n const value = input.trim();\n if (!value) return {};\n\n try {\n const url = new URL(value);\n return {\n code: url.searchParams.get('code') ?? undefined,\n state: url.searchParams.get('state') ?? undefined,\n };\n } catch {\n // not a URL\n }\n\n if (value.includes('#')) {\n const [code, state] = value.split('#', 2);\n return { code, state };\n }\n\n if (value.includes('code=')) {\n const params = new URLSearchParams(value);\n return {\n code: params.get('code') ?? undefined,\n state: params.get('state') ?? undefined,\n };\n }\n\n return { code: value };\n}\n\nfunction decodeJwt(token: string): JwtPayload | null {\n try {\n const parts = token.split('.');\n if (parts.length !== 3) return null;\n const payload = parts[1] ?? '';\n const padded = payload\n .replace(/-/g, '+')\n .replace(/_/g, '/')\n .padEnd(Math.ceil(payload.length / 4) * 4, '=');\n const decoded = atob(padded);\n return JSON.parse(decoded) as JwtPayload;\n } catch {\n return null;\n }\n}\n\nfunction extractAccountIdFromClaims(payload: JwtPayload | null | undefined): string | null {\n if (!payload) return null;\n const accountId = payload.chatgpt_account_id ?? payload[JWT_CLAIM_PATH]?.chatgpt_account_id;\n return typeof accountId === 'string' && accountId.length > 0 ? accountId : null;\n}\n\nfunction getAccountId(tokens: { idToken?: string; access: string }, fallback?: string): string | undefined {\n const fromIdToken = tokens.idToken ? extractAccountIdFromClaims(decodeJwt(tokens.idToken)) : null;\n if (fromIdToken) return fromIdToken;\n\n const fromAccessToken = extractAccountIdFromClaims(decodeJwt(tokens.access));\n if (fromAccessToken) return fromAccessToken;\n\n return fallback;\n}\n\nfunction requireAccountId(tokens: { idToken?: string; access: string }, fallback?: string): string {\n const accountId = getAccountId(tokens, fallback);\n if (!accountId) {\n throw new Error('Failed to extract ChatGPT account id from OpenAI Codex token');\n }\n return accountId;\n}\n\ntype TokenResponseJson = {\n id_token?: string;\n access_token?: string;\n refresh_token?: string;\n expires_in?: number;\n};\n\nfunction tokenResponseToResult(json: TokenResponseJson, logPrefix: string): TokenResult {\n if (!json.access_token || !json.refresh_token) {\n console.error(`[openai-codex] ${logPrefix} response missing fields:`, json);\n return { type: 'failed' };\n }\n\n return {\n type: 'success',\n access: json.access_token,\n refresh: json.refresh_token,\n expires: Date.now() + (json.expires_in ?? DEFAULT_TOKEN_EXPIRES_IN_SECONDS) * 1000,\n idToken: json.id_token,\n };\n}\n\nasync function exchangeAuthorizationCode(code: string, verifier: string, redirectUri: string): Promise<TokenResult> {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'authorization_code',\n client_id: CLIENT_ID,\n code,\n code_verifier: verifier,\n redirect_uri: redirectUri,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] code->token failed:', response.status, text);\n return { type: 'failed' };\n }\n\n return tokenResponseToResult((await response.json()) as TokenResponseJson, 'token');\n}\n\nasync function refreshAccessToken(refreshToken: string): Promise<TokenResult> {\n try {\n const response = await fetch(TOKEN_URL, {\n method: 'POST',\n headers: { 'Content-Type': 'application/x-www-form-urlencoded' },\n body: new URLSearchParams({\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n client_id: CLIENT_ID,\n }),\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => '');\n console.error('[openai-codex] Token refresh failed:', response.status, text);\n return { type: 'failed' };\n }\n\n return tokenResponseToResult((await response.json()) as TokenResponseJson, 'Token refresh');\n } catch (error) {\n console.error('[openai-codex] Token refresh error:', error);\n return { type: 'failed' };\n }\n}\n\nasync function getRandomBytes() {\n if (!_randomBytes && _cryptoPromise) {\n _randomBytes = (await _cryptoPromise).randomBytes;\n }\n if (!_randomBytes) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n return _randomBytes;\n}\n\nasync function createAuthorizationFlow(\n redirectUri: string,\n state: string,\n originator: string = 'mastracode',\n): Promise<{ verifier: string; url: string }> {\n const { verifier, challenge } = await generatePKCE();\n\n const url = new URL(AUTHORIZE_URL);\n url.searchParams.set('response_type', 'code');\n url.searchParams.set('client_id', CLIENT_ID);\n url.searchParams.set('redirect_uri', redirectUri);\n url.searchParams.set('scope', SCOPE);\n url.searchParams.set('code_challenge', challenge);\n url.searchParams.set('code_challenge_method', 'S256');\n url.searchParams.set('state', state);\n url.searchParams.set('id_token_add_organizations', 'true');\n url.searchParams.set('codex_cli_simplified_flow', 'true');\n url.searchParams.set('originator', originator);\n\n return { verifier, url: url.toString() };\n}\n\ntype OAuthServerInfo = {\n redirectUri: string;\n warning?: string;\n close: () => void;\n cancelWait: () => void;\n waitForCode: () => Promise<{ code: string } | null>;\n};\n\ntype CallbackPorts = {\n defaultPort: number;\n fallbackPort: number;\n};\n\nconst CODEX_CALLBACK_PORTS: CallbackPorts = {\n defaultPort: DEFAULT_CALLBACK_PORT,\n fallbackPort: FALLBACK_CALLBACK_PORT,\n};\n\nasync function requestCancel(port: number): Promise<void> {\n try {\n await fetch(`http://127.0.0.1:${port}/cancel`, { signal: AbortSignal.timeout(200) });\n } catch {\n // The existing listener might not be a Codex auth server.\n }\n}\n\nfunction listen(server: HttpServer, port: number): Promise<boolean> {\n return new Promise(resolve => {\n const onError = () => {\n server.off('listening', onListening);\n resolve(false);\n };\n const onListening = () => {\n server.off('error', onError);\n resolve(true);\n };\n\n server.once('error', onError);\n server.once('listening', onListening);\n server.listen(port, '127.0.0.1');\n });\n}\n\nasync function bindOAuthServer(server: HttpServer, ports: CallbackPorts): Promise<number | null> {\n await requestCancel(ports.defaultPort);\n if (await listen(server, ports.defaultPort)) return ports.defaultPort;\n if (await listen(server, ports.fallbackPort)) return ports.fallbackPort;\n\n return null;\n}\n\nasync function getHttpModule() {\n if (!_http && _httpPromise) {\n _http = await _httpPromise;\n }\n if (!_http) {\n throw new Error('OpenAI Codex OAuth is only available in Node.js environments');\n }\n return _http;\n}\n\nasync function startLocalOAuthServer(\n state: string,\n ports: CallbackPorts = CODEX_CALLBACK_PORTS,\n): Promise<OAuthServerInfo> {\n const http = await getHttpModule();\n let lastCode: string | null = null;\n let cancelled = false;\n const server = http.createServer((req, res) => {\n try {\n const url = new URL(req.url || '', 'http://localhost');\n if (url.pathname === '/cancel') {\n cancelled = true;\n res.statusCode = 200;\n res.end('Cancelled');\n return;\n }\n if (url.pathname !== '/auth/callback') {\n res.statusCode = 404;\n res.end('Not found');\n return;\n }\n if (url.searchParams.get('state') !== state) {\n res.statusCode = 400;\n res.end('State mismatch');\n return;\n }\n const code = url.searchParams.get('code');\n if (!code) {\n res.statusCode = 400;\n res.end('Missing authorization code');\n return;\n }\n res.statusCode = 200;\n res.setHeader('Content-Type', 'text/html; charset=utf-8');\n res.end(SUCCESS_HTML);\n lastCode = code;\n } catch {\n res.statusCode = 500;\n res.end('Internal error');\n }\n });\n\n return new Promise(resolve => {\n bindOAuthServer(server, ports).then(port => {\n if (!port) {\n resolve({\n redirectUri: `http://localhost:${ports.fallbackPort}/auth/callback`,\n warning: `OpenAI Codex OAuth requires localhost port ${ports.defaultPort} or ${ports.fallbackPort}, but both are in use. Automatic browser callback will not work until one is freed.`,\n close: () => {\n try {\n server.close();\n } catch {\n // ignore\n }\n },\n cancelWait: () => {},\n waitForCode: async () => null,\n });\n return;\n }\n\n resolve({\n redirectUri: `http://localhost:${port}/auth/callback`,\n close: () => server.close(),\n cancelWait: () => {\n cancelled = true;\n },\n waitForCode: async () => {\n const sleep = () => new Promise(r => setTimeout(r, 100));\n for (let i = 0; i < 600; i += 1) {\n if (lastCode) return { code: lastCode };\n if (cancelled) return null;\n await sleep();\n }\n return null;\n },\n });\n });\n });\n}\n\nasync function loginOpenAICodexDevice(options: {\n onAuth: (info: { url: string; instructions?: string }) => void;\n onProgress?: (message: string) => void;\n signal?: AbortSignal;\n sleep?: (ms: number) => Promise<void>;\n}): Promise<OAuthCredentials> {\n const response = await fetch(DEVICE_USER_CODE_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'mastracode',\n },\n body: JSON.stringify({ client_id: CLIENT_ID, originator: 'mastracode' }),\n signal: options.signal,\n });\n\n if (!response.ok) {\n throw new Error(`Failed to initiate OpenAI Codex device authorization: ${response.status}`);\n }\n\n const deviceData = (await response.json()) as {\n device_auth_id?: string;\n user_code?: string;\n usercode?: string;\n interval?: string | number;\n };\n\n const userCode = deviceData.user_code ?? deviceData.usercode;\n\n if (!deviceData.device_auth_id || !userCode) {\n throw new Error('OpenAI Codex device authorization response missing required fields');\n }\n\n const intervalSeconds =\n typeof deviceData.interval === 'number' ? deviceData.interval : Number.parseInt(deviceData.interval ?? '', 10) || 5;\n const pollDelayMs = Math.max(intervalSeconds, 1) * 1000;\n const sleep = options.sleep ?? (ms => new Promise<void>(resolve => setTimeout(resolve, ms)));\n const startedAt = Date.now();\n\n options.onAuth({\n url: DEVICE_AUTHORIZE_URL,\n instructions: `Enter code: ${userCode}`,\n });\n\n while (true) {\n if (options.signal?.aborted) {\n throw new Error('Login cancelled');\n }\n if (Date.now() - startedAt >= DEVICE_AUTH_TIMEOUT_MS) {\n throw new Error('OpenAI Codex device authorization timed out after 15 minutes');\n }\n\n const pollResponse = await fetch(DEVICE_TOKEN_URL, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'User-Agent': 'mastracode',\n },\n body: JSON.stringify({\n device_auth_id: deviceData.device_auth_id,\n user_code: userCode,\n }),\n signal: options.signal,\n });\n\n if (pollResponse.ok) {\n const data = (await pollResponse.json()) as {\n authorization_code?: string;\n code_verifier?: string;\n };\n\n if (!data.authorization_code || !data.code_verifier) {\n throw new Error('OpenAI Codex device token response missing required fields');\n }\n\n const tokenResult = await exchangeAuthorizationCode(\n data.authorization_code,\n data.code_verifier,\n DEVICE_REDIRECT_URI,\n );\n if (tokenResult.type !== 'success') {\n throw new Error('Token exchange failed');\n }\n\n const accountId = requireAccountId(tokenResult);\n return {\n access: tokenResult.access,\n refresh: tokenResult.refresh,\n expires: tokenResult.expires,\n accountId,\n };\n }\n\n if (pollResponse.status !== 403 && pollResponse.status !== 404) {\n const text = await pollResponse.text().catch(() => '');\n throw new Error(`OpenAI Codex device authorization failed: ${pollResponse.status}${text ? ` ${text}` : ''}`);\n }\n\n options.onProgress?.('Waiting for OpenAI Codex device authorization...');\n await sleep(pollDelayMs);\n }\n}\n\n/**\n * Login with OpenAI Codex OAuth\n *\n * @param options.onAuth - Called with URL and instructions when auth starts\n * @param options.onPrompt - Called to prompt user for manual code paste (fallback if no onManualCodeInput)\n * @param options.onProgress - Optional progress messages\n * @param options.onManualCodeInput - Optional promise that resolves with user-pasted code.\n * Races with browser callback - whichever completes first wins.\n * Useful for showing paste input immediately alongside browser flow.\n * @param options.originator - OAuth originator parameter (defaults to \"mastracode\")\n */\nexport async function loginOpenAICodex(options: {\n onAuth: (info: { url: string; instructions?: string }) => void;\n onPrompt: (prompt: OAuthPrompt) => Promise<string>;\n onProgress?: (message: string) => void;\n onManualCodeInput?: () => Promise<string>;\n signal?: AbortSignal;\n originator?: string;\n mode?: 'browser' | 'device';\n}): Promise<OAuthCredentials> {\n const envMode =\n typeof process !== 'undefined' && process.env?.MASTRACODE_OPENAI_CODEX_AUTH_MODE === 'device'\n ? 'device'\n : undefined;\n const mode = options.mode ?? envMode ?? 'browser';\n if (mode === 'device') {\n return loginOpenAICodexDevice({\n onAuth: options.onAuth,\n onProgress: options.onProgress,\n signal: options.signal,\n });\n }\n\n const state = await createState();\n const server = await startLocalOAuthServer(state);\n if (server.warning) {\n options.onProgress?.(server.warning);\n }\n const { verifier, url } = await createAuthorizationFlow(\n server.redirectUri,\n state,\n options.originator ?? 'mastracode',\n );\n\n options.onAuth({\n url,\n instructions: server.warning\n ? `${server.warning} You can still paste the authorization code or full redirect URL manually.`\n : 'A browser window should open. Complete login to finish.',\n });\n\n let code: string | undefined;\n try {\n if (options.onManualCodeInput) {\n // Race between browser callback and manual input\n let manualCode: string | undefined;\n let manualError: Error | undefined;\n const manualPromise = options\n .onManualCodeInput()\n .then(input => {\n manualCode = input;\n server.cancelWait();\n })\n .catch(err => {\n manualError = err instanceof Error ? err : new Error(String(err));\n server.cancelWait();\n });\n\n const result = await server.waitForCode();\n\n // If manual input was cancelled, throw that error\n if (manualError) {\n throw manualError;\n }\n\n if (result?.code) {\n // Browser callback won\n code = result.code;\n } else if (manualCode) {\n // Manual input won (or callback timed out and user had entered code)\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n // If still no code, wait for manual promise to complete and try that\n if (!code) {\n await manualPromise;\n if (manualError) {\n throw manualError;\n }\n if (manualCode) {\n const parsed = parseAuthorizationInput(manualCode);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n }\n } else {\n // Original flow: wait for callback, then prompt if needed\n const result = await server.waitForCode();\n if (result?.code) {\n code = result.code;\n }\n }\n\n // Fallback to onPrompt if still no code\n if (!code) {\n const input = await options.onPrompt({\n message: 'Paste the authorization code (or full redirect URL):',\n });\n const parsed = parseAuthorizationInput(input);\n if (parsed.state && parsed.state !== state) {\n throw new Error('State mismatch');\n }\n code = parsed.code;\n }\n\n if (!code) {\n throw new Error('Missing authorization code');\n }\n\n const tokenResult = await exchangeAuthorizationCode(code, verifier, server.redirectUri);\n if (tokenResult.type !== 'success') {\n throw new Error('Token exchange failed');\n }\n\n const accountId = requireAccountId(tokenResult);\n\n return {\n access: tokenResult.access,\n refresh: tokenResult.refresh,\n expires: tokenResult.expires,\n accountId,\n };\n } finally {\n server.close();\n }\n}\n\nexport const __testing = {\n createAuthorizationFlow,\n decodeJwt,\n extractAccountIdFromClaims,\n getAccountId,\n loginOpenAICodexDevice,\n requireAccountId,\n startLocalOAuthServer,\n};\n\n/**\n * Refresh OpenAI Codex OAuth token\n */\nexport async function refreshOpenAICodexToken(\n refreshToken: string,\n previousAccountId?: string,\n): Promise<OAuthCredentials> {\n const result = await refreshAccessToken(refreshToken);\n if (result.type !== 'success') {\n throw new Error('Failed to refresh OpenAI Codex token');\n }\n\n const accountId = requireAccountId(result, previousAccountId);\n\n return {\n access: result.access,\n refresh: result.refresh,\n expires: result.expires,\n accountId,\n };\n}\n\nexport const openaiCodexOAuthProvider: OAuthProviderInterface = {\n id: 'openai-codex',\n name: 'ChatGPT Plus/Pro (Codex Subscription)',\n usesCallbackServer: true,\n authModes: OPENAI_CODEX_AUTH_MODES,\n\n async login(callbacks: OAuthLoginCallbacks): Promise<OAuthCredentials> {\n const mode = callbacks.authMode === 'device' || callbacks.authMode === 'browser' ? callbacks.authMode : undefined;\n return loginOpenAICodex({\n onAuth: callbacks.onAuth,\n onPrompt: callbacks.onPrompt,\n onProgress: callbacks.onProgress,\n onManualCodeInput: callbacks.onManualCodeInput,\n signal: callbacks.signal,\n mode,\n });\n },\n\n async refreshToken(credentials: OAuthCredentials): Promise<OAuthCredentials> {\n return refreshOpenAICodexToken(credentials.refresh, credentials.accountId as string | undefined);\n },\n\n getApiKey(credentials: OAuthCredentials): string {\n return credentials.access;\n },\n};\n","/**\n * Credential storage for API keys and OAuth tokens.\n * Handles loading, saving, and refreshing credentials from auth.json.\n */\n\nimport { existsSync, mkdirSync, readFileSync, writeFileSync, chmodSync } from 'node:fs';\nimport { dirname, join } from 'node:path';\nimport { getAppDataDir } from '../utils/project.js';\nimport { anthropicOAuthProvider } from './providers/anthropic.js';\nimport { githubCopilotOAuthProvider } from './providers/github-copilot.js';\nimport { openaiCodexOAuthProvider } from './providers/openai-codex.js';\nimport type {\n AuthCredential,\n AuthStorageData,\n OAuthLoginCallbacks,\n OAuthProviderId,\n OAuthProviderInterface,\n} from './types.js';\n\n/**\n * Best/default models for each OAuth provider.\n * Used when auto-selecting a model after login.\n */\nexport const PROVIDER_DEFAULT_MODELS: Record<OAuthProviderId, string> = {\n anthropic: 'anthropic/claude-opus-4-6',\n 'openai-codex': 'openai/gpt-5.5',\n // gpt-4.1 routes through `/chat/completions` (which our OpenAI-compatible\n // adapter handles); Anthropic-shaped Copilot models (Claude on `/v1/messages`)\n // are not yet wired up, so picking one as the post-login default would error.\n 'github-copilot': 'github-copilot/gpt-4.1',\n};\n\n// Provider registry\nconst oauthProviderRegistry = new Map<string, OAuthProviderInterface>([\n [anthropicOAuthProvider.id, anthropicOAuthProvider],\n [openaiCodexOAuthProvider.id, openaiCodexOAuthProvider],\n [githubCopilotOAuthProvider.id, githubCopilotOAuthProvider],\n]);\n\n/**\n * Get an OAuth provider by ID\n */\nexport function getOAuthProvider(id: OAuthProviderId): OAuthProviderInterface | undefined {\n return oauthProviderRegistry.get(id);\n}\n\n/**\n * Get all registered OAuth providers\n */\nexport function getOAuthProviders(): OAuthProviderInterface[] {\n return Array.from(oauthProviderRegistry.values());\n}\n\n/**\n * Credential storage backed by a JSON file.\n */\nexport class AuthStorage {\n private data: AuthStorageData = {};\n\n constructor(private authPath: string = join(getAppDataDir(), 'auth.json')) {\n this.reload();\n }\n\n /**\n * Reload credentials from disk.\n */\n reload(): void {\n if (!existsSync(this.authPath)) {\n this.data = {};\n return;\n }\n try {\n this.data = JSON.parse(readFileSync(this.authPath, 'utf-8'));\n } catch {\n this.data = {};\n }\n }\n\n /**\n * Save credentials to disk.\n */\n private save(): void {\n const dir = dirname(this.authPath);\n if (!existsSync(dir)) {\n mkdirSync(dir, { recursive: true, mode: 0o700 });\n }\n writeFileSync(this.authPath, JSON.stringify(this.data, null, 2), 'utf-8');\n chmodSync(this.authPath, 0o600);\n }\n\n /**\n * Get credential for a provider.\n */\n get(provider: string): AuthCredential | undefined {\n return this.data[provider] ?? undefined;\n }\n\n /**\n * Set credential for a provider.\n */\n set(provider: string, credential: AuthCredential): void {\n this.data[provider] = credential;\n this.save();\n }\n\n /**\n * Remove credential for a provider.\n */\n remove(provider: string): void {\n delete this.data[provider];\n this.save();\n }\n\n /**\n * List all providers with credentials.\n */\n list(): string[] {\n return Object.keys(this.data);\n }\n\n /**\n * Check if credentials exist for a provider.\n */\n has(provider: string): boolean {\n return provider in this.data;\n }\n\n /**\n * Check if logged in via OAuth for a provider.\n */\n isLoggedIn(provider: string): boolean {\n const cred = this.data[provider];\n return cred?.type === 'oauth';\n }\n\n /**\n * Check if a stored API key exists for a provider.\n * Keys are stored under `apikey:<provider>` in auth.json.\n */\n hasStoredApiKey(provider: string): boolean {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0;\n }\n\n /**\n * Get a stored API key for a provider, if any.\n */\n getStoredApiKey(provider: string): string | undefined {\n const cred = this.data[`apikey:${provider}`];\n return cred?.type === 'api_key' && cred.key.length > 0 ? cred.key : undefined;\n }\n\n /**\n * Store an API key for a provider.\n * Also sets the corresponding environment variable so model resolution can find it.\n */\n setStoredApiKey(provider: string, key: string, envVar?: string): void {\n this.set(`apikey:${provider}`, { type: 'api_key', key });\n if (envVar) {\n process.env[envVar] = key;\n }\n }\n\n /**\n * Load all stored API keys into process.env.\n * Called at startup so model resolution can find stored keys.\n * Only sets env vars that aren't already set (env vars take precedence).\n */\n loadStoredApiKeysIntoEnv(providerEnvVars: Record<string, string | undefined>): void {\n for (const [key, cred] of Object.entries(this.data)) {\n if (!key.startsWith('apikey:') || cred.type !== 'api_key' || !cred.key) continue;\n const provider = key.substring('apikey:'.length);\n const envVar = providerEnvVars[provider];\n if (envVar && !process.env[envVar]) {\n process.env[envVar] = cred.key;\n }\n }\n }\n\n /**\n * Login to an OAuth provider.\n */\n async login(providerId: OAuthProviderId, callbacks: OAuthLoginCallbacks): Promise<void> {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n throw new Error(`Unknown OAuth provider: ${providerId}`);\n }\n\n const credentials = await provider.login(callbacks);\n this.set(providerId, { type: 'oauth', ...credentials });\n }\n\n /**\n * Logout from a provider.\n */\n logout(provider: string): void {\n this.remove(provider);\n }\n\n /**\n * Get API key for a provider, auto-refreshing OAuth tokens if needed.\n */\n async getApiKey(providerId: string): Promise<string | undefined> {\n const cred = this.data[providerId];\n\n if (cred?.type === 'api_key') {\n return cred.key;\n }\n\n if (cred?.type === 'oauth') {\n const provider = getOAuthProvider(providerId);\n if (!provider) {\n return undefined;\n }\n\n // Check if token needs refresh\n if (Date.now() >= cred.expires) {\n try {\n const newCreds = await provider.refreshToken(cred);\n this.set(providerId, { type: 'oauth', ...newCreds });\n return provider.getApiKey(newCreds);\n } catch {\n // Refresh failed - user needs to re-login\n return undefined;\n }\n }\n\n return provider.getApiKey(cred);\n }\n\n return undefined;\n }\n}\n"]}
|