@metyatech/ai-quota 1.2.0 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/claude.d.ts +2 -2
- package/dist/claude.d.ts.map +1 -1
- package/dist/claude.js +147 -28
- package/dist/claude.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -113,6 +113,8 @@ ai-quota --json
|
|
|
113
113
|
| Copilot | `GITHUB_TOKEN` env var, `gh auth token` CLI, or `hosts.yml` |
|
|
114
114
|
| Codex | `~/.codex/auth.json` |
|
|
115
115
|
|
|
116
|
+
Claude token behavior: `ai-quota` automatically refreshes Claude OAuth tokens using `refreshToken` when needed (including stale-token `401/403/429` retries).
|
|
117
|
+
|
|
116
118
|
Exit code is `0` on success. Exit code `1` if any agent fetch fails.
|
|
117
119
|
|
|
118
120
|
### Advanced usage (SDK)
|
package/dist/claude.d.ts
CHANGED
|
@@ -5,10 +5,10 @@ export type { ClaudeUsageData, ClaudeUsageBucket } from "./types.js";
|
|
|
5
5
|
*
|
|
6
6
|
* This function attempts to read credentials from the Claude desktop application's
|
|
7
7
|
* local storage (`~/.claude/.credentials.json`) and calls the Anthropic usage API.
|
|
8
|
+
* If the access token is stale or rejected, it attempts one OAuth refresh and retries.
|
|
8
9
|
*
|
|
9
10
|
* @param timeoutMs - Request timeout in milliseconds (default: 5000ms)
|
|
10
|
-
* @returns A promise resolving to ClaudeUsageData
|
|
11
|
-
* missing, expired, or the API request fails.
|
|
11
|
+
* @returns A promise resolving to ClaudeUsageData.
|
|
12
12
|
*/
|
|
13
13
|
export declare function fetchClaudeRateLimits(timeoutMs?: number): Promise<ClaudeUsageData>;
|
|
14
14
|
//# sourceMappingURL=claude.d.ts.map
|
package/dist/claude.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"claude.d.ts","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAGlD,YAAY,EAAE,eAAe,EAAE,iBAAiB,EAAE,MAAM,YAAY,CAAC;AAmMrE;;;;;;;;;GASG;AACH,wBAAsB,qBAAqB,CAAC,SAAS,GAAE,MAAa,GAAG,OAAO,CAAC,eAAe,CAAC,CA4F9F"}
|
package/dist/claude.js
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { QuotaFetchError } from "./errors.js";
|
|
4
|
+
const CLAUDE_OAUTH_TOKEN_URL = process.env.CLAUDE_CODE_OAUTH_TOKEN_URL ?? "https://platform.claude.com/v1/oauth/token";
|
|
5
|
+
const CLAUDE_OAUTH_CLIENT_ID = process.env.CLAUDE_CODE_OAUTH_CLIENT_ID ?? "9d1c250a-e61b-44d9-88ed-5944d1962f5e";
|
|
6
|
+
const CLAUDE_OAUTH_SCOPES = process.env.CLAUDE_CODE_OAUTH_SCOPES ??
|
|
7
|
+
"user:profile user:inference user:sessions:claude_code user:mcp_servers";
|
|
4
8
|
function getClaudeConfigDir() {
|
|
5
9
|
const home = process.env.USERPROFILE ?? process.env.HOME ?? "";
|
|
6
10
|
return path.join(home, ".claude");
|
|
7
11
|
}
|
|
12
|
+
function getClaudeCredentialsPath() {
|
|
13
|
+
return path.join(getClaudeConfigDir(), ".credentials.json");
|
|
14
|
+
}
|
|
8
15
|
function readClaudeCredentials() {
|
|
9
|
-
const credsPath =
|
|
16
|
+
const credsPath = getClaudeCredentialsPath();
|
|
10
17
|
try {
|
|
11
18
|
if (!fs.existsSync(credsPath)) {
|
|
12
19
|
throw new QuotaFetchError("no_credentials", `Claude credentials not found at ${credsPath}`);
|
|
@@ -34,9 +41,12 @@ function readClaudeCredentials() {
|
|
|
34
41
|
const expiresAt = typeof oauthRecord.expiresAt === "number" && Number.isFinite(oauthRecord.expiresAt)
|
|
35
42
|
? oauthRecord.expiresAt
|
|
36
43
|
: null;
|
|
44
|
+
const refreshToken = typeof oauthRecord.refreshToken === "string" && oauthRecord.refreshToken.length > 0
|
|
45
|
+
? oauthRecord.refreshToken
|
|
46
|
+
: null;
|
|
37
47
|
if (!accessToken || expiresAt === null)
|
|
38
48
|
return null;
|
|
39
|
-
return { accessToken, expiresAt };
|
|
49
|
+
return { accessToken, expiresAt, refreshToken };
|
|
40
50
|
}
|
|
41
51
|
catch (e) {
|
|
42
52
|
if (e instanceof QuotaFetchError)
|
|
@@ -44,15 +54,124 @@ function readClaudeCredentials() {
|
|
|
44
54
|
throw new QuotaFetchError("api_error", "Failed to read Claude credentials.", { cause: e });
|
|
45
55
|
}
|
|
46
56
|
}
|
|
57
|
+
function persistClaudeCredentialsUpdate(creds) {
|
|
58
|
+
const credsPath = getClaudeCredentialsPath();
|
|
59
|
+
try {
|
|
60
|
+
if (!fs.existsSync(credsPath))
|
|
61
|
+
return;
|
|
62
|
+
const raw = fs.readFileSync(credsPath, "utf8");
|
|
63
|
+
const parsed = JSON.parse(raw);
|
|
64
|
+
if (!parsed || typeof parsed !== "object")
|
|
65
|
+
return;
|
|
66
|
+
const record = parsed;
|
|
67
|
+
if (!record.claudeAiOauth || typeof record.claudeAiOauth !== "object")
|
|
68
|
+
return;
|
|
69
|
+
const oauthRecord = record.claudeAiOauth;
|
|
70
|
+
oauthRecord.accessToken = creds.accessToken;
|
|
71
|
+
oauthRecord.expiresAt = creds.expiresAt;
|
|
72
|
+
if (creds.refreshToken) {
|
|
73
|
+
oauthRecord.refreshToken = creds.refreshToken;
|
|
74
|
+
}
|
|
75
|
+
fs.writeFileSync(credsPath, JSON.stringify(record));
|
|
76
|
+
}
|
|
77
|
+
catch {
|
|
78
|
+
// Refresh succeeded; a local persistence failure should not fail quota fetch.
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
async function requestClaudeUsage(accessToken, timeoutMs) {
|
|
82
|
+
const controller = new AbortController();
|
|
83
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
84
|
+
try {
|
|
85
|
+
return await fetch("https://api.anthropic.com/api/oauth/usage", {
|
|
86
|
+
method: "GET",
|
|
87
|
+
headers: {
|
|
88
|
+
Authorization: `Bearer ${accessToken}`,
|
|
89
|
+
"Content-Type": "application/json",
|
|
90
|
+
"anthropic-beta": "oauth-2025-04-20"
|
|
91
|
+
},
|
|
92
|
+
signal: controller.signal
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
catch (e) {
|
|
96
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
97
|
+
throw new QuotaFetchError("timeout", "Claude usage request timed out.", { cause: e });
|
|
98
|
+
}
|
|
99
|
+
throw new QuotaFetchError("network_error", "Claude usage request failed.", { cause: e });
|
|
100
|
+
}
|
|
101
|
+
finally {
|
|
102
|
+
clearTimeout(timer);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
async function refreshClaudeAccessToken(refreshToken, timeoutMs) {
|
|
106
|
+
const controller = new AbortController();
|
|
107
|
+
const timer = setTimeout(() => controller.abort(), timeoutMs);
|
|
108
|
+
let res;
|
|
109
|
+
try {
|
|
110
|
+
res = await fetch(CLAUDE_OAUTH_TOKEN_URL, {
|
|
111
|
+
method: "POST",
|
|
112
|
+
headers: { "Content-Type": "application/json" },
|
|
113
|
+
body: JSON.stringify({
|
|
114
|
+
grant_type: "refresh_token",
|
|
115
|
+
refresh_token: refreshToken,
|
|
116
|
+
client_id: CLAUDE_OAUTH_CLIENT_ID,
|
|
117
|
+
scope: CLAUDE_OAUTH_SCOPES
|
|
118
|
+
}),
|
|
119
|
+
signal: controller.signal
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
catch (e) {
|
|
123
|
+
if (e instanceof Error && e.name === "AbortError") {
|
|
124
|
+
throw new QuotaFetchError("timeout", "Claude OAuth token refresh timed out.", { cause: e });
|
|
125
|
+
}
|
|
126
|
+
throw new QuotaFetchError("network_error", "Claude OAuth token refresh failed.", { cause: e });
|
|
127
|
+
}
|
|
128
|
+
finally {
|
|
129
|
+
clearTimeout(timer);
|
|
130
|
+
}
|
|
131
|
+
if (!res.ok) {
|
|
132
|
+
const reason = res.status >= 400 && res.status < 500 ? "auth_failed" : "api_error";
|
|
133
|
+
throw new QuotaFetchError(reason, `Claude OAuth token refresh failed (${res.status} ${res.statusText}).`, { httpStatus: res.status });
|
|
134
|
+
}
|
|
135
|
+
let data;
|
|
136
|
+
try {
|
|
137
|
+
data = (await res.json());
|
|
138
|
+
}
|
|
139
|
+
catch (e) {
|
|
140
|
+
throw new QuotaFetchError("parse_error", "Claude OAuth token refresh response was invalid.", {
|
|
141
|
+
cause: e
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
if (!data || typeof data !== "object") {
|
|
145
|
+
throw new QuotaFetchError("parse_error", "Claude OAuth token refresh response was invalid.");
|
|
146
|
+
}
|
|
147
|
+
const record = data;
|
|
148
|
+
const accessToken = typeof record.access_token === "string" && record.access_token.length > 0
|
|
149
|
+
? record.access_token
|
|
150
|
+
: null;
|
|
151
|
+
const expiresIn = typeof record.expires_in === "number" && Number.isFinite(record.expires_in)
|
|
152
|
+
? record.expires_in
|
|
153
|
+
: null;
|
|
154
|
+
const nextRefreshToken = typeof record.refresh_token === "string" && record.refresh_token.length > 0
|
|
155
|
+
? record.refresh_token
|
|
156
|
+
: refreshToken;
|
|
157
|
+
if (!accessToken || expiresIn === null) {
|
|
158
|
+
throw new QuotaFetchError("parse_error", "Claude OAuth token refresh response missing required fields.");
|
|
159
|
+
}
|
|
160
|
+
return {
|
|
161
|
+
accessToken,
|
|
162
|
+
refreshToken: nextRefreshToken,
|
|
163
|
+
expiresAt: Date.now() + expiresIn * 1000
|
|
164
|
+
};
|
|
165
|
+
}
|
|
47
166
|
/**
|
|
48
167
|
* Fetches Claude usage data from the Anthropic OAuth usage API.
|
|
49
168
|
*
|
|
50
169
|
* This function attempts to read credentials from the Claude desktop application's
|
|
51
170
|
* local storage (`~/.claude/.credentials.json`) and calls the Anthropic usage API.
|
|
171
|
+
* If the access token is stale or rejected, it attempts one OAuth refresh and retries.
|
|
52
172
|
*
|
|
53
173
|
* @param timeoutMs - Request timeout in milliseconds (default: 5000ms)
|
|
54
|
-
* @returns A promise resolving to ClaudeUsageData
|
|
55
|
-
* missing, expired, or the API request fails.
|
|
174
|
+
* @returns A promise resolving to ClaudeUsageData.
|
|
56
175
|
*/
|
|
57
176
|
export async function fetchClaudeRateLimits(timeoutMs = 5000) {
|
|
58
177
|
try {
|
|
@@ -60,32 +179,32 @@ export async function fetchClaudeRateLimits(timeoutMs = 5000) {
|
|
|
60
179
|
if (!creds) {
|
|
61
180
|
throw new QuotaFetchError("no_credentials", "Claude credentials missing.");
|
|
62
181
|
}
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
let res;
|
|
70
|
-
try {
|
|
71
|
-
res = await fetch("https://api.anthropic.com/api/oauth/usage", {
|
|
72
|
-
method: "GET",
|
|
73
|
-
headers: {
|
|
74
|
-
Authorization: `Bearer ${creds.accessToken}`,
|
|
75
|
-
"Content-Type": "application/json",
|
|
76
|
-
"anthropic-beta": "oauth-2025-04-20"
|
|
77
|
-
},
|
|
78
|
-
signal: controller.signal
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
catch (e) {
|
|
82
|
-
if (e instanceof Error && e.name === "AbortError") {
|
|
83
|
-
throw new QuotaFetchError("timeout", "Claude usage request timed out.", { cause: e });
|
|
182
|
+
let accessToken = creds.accessToken;
|
|
183
|
+
let refreshToken = creds.refreshToken;
|
|
184
|
+
let didRefresh = false;
|
|
185
|
+
const refreshAndPersist = async () => {
|
|
186
|
+
if (!refreshToken) {
|
|
187
|
+
throw new QuotaFetchError("token_expired", "Claude access token is expired.");
|
|
84
188
|
}
|
|
85
|
-
|
|
189
|
+
const refreshed = await refreshClaudeAccessToken(refreshToken, timeoutMs);
|
|
190
|
+
accessToken = refreshed.accessToken;
|
|
191
|
+
refreshToken = refreshed.refreshToken;
|
|
192
|
+
persistClaudeCredentialsUpdate(refreshed);
|
|
193
|
+
didRefresh = true;
|
|
194
|
+
};
|
|
195
|
+
// Check token expiry with 5-minute buffer.
|
|
196
|
+
if (Date.now() + 300_000 >= creds.expiresAt) {
|
|
197
|
+
await refreshAndPersist();
|
|
86
198
|
}
|
|
87
|
-
|
|
88
|
-
|
|
199
|
+
let res = await requestClaudeUsage(accessToken, timeoutMs);
|
|
200
|
+
// Claude sometimes returns 429 for stale/revoked tokens while normal model calls still work.
|
|
201
|
+
// Retry once with a fresh OAuth token before failing.
|
|
202
|
+
if (!res.ok &&
|
|
203
|
+
(res.status === 401 || res.status === 403 || res.status === 429) &&
|
|
204
|
+
!didRefresh &&
|
|
205
|
+
refreshToken) {
|
|
206
|
+
await refreshAndPersist();
|
|
207
|
+
res = await requestClaudeUsage(accessToken, timeoutMs);
|
|
89
208
|
}
|
|
90
209
|
if (!res.ok) {
|
|
91
210
|
const reason = res.status === 401 || res.status === 403 ? "auth_failed" : "api_error";
|
package/dist/claude.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,
|
|
1
|
+
{"version":3,"file":"claude.js","sourceRoot":"","sources":["../src/claude.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAI9C,MAAM,sBAAsB,GAC1B,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,4CAA4C,CAAC;AAC1F,MAAM,sBAAsB,GAC1B,OAAO,CAAC,GAAG,CAAC,2BAA2B,IAAI,sCAAsC,CAAC;AACpF,MAAM,mBAAmB,GACvB,OAAO,CAAC,GAAG,CAAC,wBAAwB;IACpC,wEAAwE,CAAC;AAQ3E,SAAS,kBAAkB;IACzB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;AACpC,CAAC;AAED,SAAS,wBAAwB;IAC/B,OAAO,IAAI,CAAC,IAAI,CAAC,kBAAkB,EAAE,EAAE,mBAAmB,CAAC,CAAC;AAC9D,CAAC;AAED,SAAS,qBAAqB;IAC5B,MAAM,SAAS,GAAG,wBAAwB,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;YAC9B,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,mCAAmC,SAAS,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC/C,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QACtC,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,MAAM,IAAI,eAAe,CACvB,aAAa,EACb,yCAAyC,SAAS,EAAE,EACpD;gBACE,KAAK,EAAE,CAAC;aACT,CACF,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACvD,MAAM,MAAM,GAAG,MAAiC,CAAC;QACjD,MAAM,KAAK,GAAG,MAAM,CAAC,aAAa,CAAC;QACnC,IAAI,CAAC,KAAK,IAAI,OAAO,KAAK,KAAK,QAAQ;YAAE,OAAO,IAAI,CAAC;QACrD,MAAM,WAAW,GAAG,KAAgC,CAAC;QACrD,MAAM,WAAW,GACf,OAAO,WAAW,CAAC,WAAW,KAAK,QAAQ,IAAI,WAAW,CAAC,WAAW,CAAC,MAAM,GAAG,CAAC;YAC/E,CAAC,CAAC,WAAW,CAAC,WAAW;YACzB,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,SAAS,GACb,OAAO,WAAW,CAAC,SAAS,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC;YACjF,CAAC,CAAC,WAAW,CAAC,SAAS;YACvB,CAAC,CAAC,IAAI,CAAC;QACX,MAAM,YAAY,GAChB,OAAO,WAAW,CAAC,YAAY,KAAK,QAAQ,IAAI,WAAW,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;YACjF,CAAC,CAAC,WAAW,CAAC,YAAY;YAC1B,CAAC,CAAC,IAAI,CAAC;QACX,IAAI,CAAC,WAAW,IAAI,SAAS,KAAK,IAAI;YAAE,OAAO,IAAI,CAAC;QACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,YAAY,EAAE,CAAC;IAClD,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,eAAe;YAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,IAAI,eAAe,CAAC,WAAW,EAAE,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC7F,CAAC;AACH,CAAC;AAED,SAAS,8BAA8B,CACrC,KAA4E;IAE5E,MAAM,SAAS,GAAG,wBAAwB,EAAE,CAAC;IAC7C,IAAI,CAAC;QACH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;YAAE,OAAO;QACtC,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC;QAC/C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAY,CAAC;QAC1C,IAAI,CAAC,MAAM,IAAI,OAAO,MAAM,KAAK,QAAQ;YAAE,OAAO;QAClD,MAAM,MAAM,GAAG,MAAiC,CAAC;QACjD,IAAI,CAAC,MAAM,CAAC,aAAa,IAAI,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ;YAAE,OAAO;QAE9E,MAAM,WAAW,GAAG,MAAM,CAAC,aAAwC,CAAC;QACpE,WAAW,CAAC,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QAC5C,WAAW,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,CAAC;QACxC,IAAI,KAAK,CAAC,YAAY,EAAE,CAAC;YACvB,WAAW,CAAC,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QAChD,CAAC;QAED,EAAE,CAAC,aAAa,CAAC,SAAS,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC;IACtD,CAAC;IAAC,MAAM,CAAC;QACP,8EAA8E;IAChF,CAAC;AACH,CAAC;AAED,KAAK,UAAU,kBAAkB,CAAC,WAAmB,EAAE,SAAiB;IACtE,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,CAAC;QACH,OAAO,MAAM,KAAK,CAAC,2CAA2C,EAAE;YAC9D,MAAM,EAAE,KAAK;YACb,OAAO,EAAE;gBACP,aAAa,EAAE,UAAU,WAAW,EAAE;gBACtC,cAAc,EAAE,kBAAkB;gBAClC,gBAAgB,EAAE,kBAAkB;aACrC;YACD,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAClD,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,iCAAiC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,eAAe,EAAE,8BAA8B,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IAC3F,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;AACH,CAAC;AAED,KAAK,UAAU,wBAAwB,CACrC,YAAoB,EACpB,SAAiB;IAEjB,MAAM,UAAU,GAAG,IAAI,eAAe,EAAE,CAAC;IACzC,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9D,IAAI,GAAa,CAAC;IAClB,IAAI,CAAC;QACH,GAAG,GAAG,MAAM,KAAK,CAAC,sBAAsB,EAAE;YACxC,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;YAC/C,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC;gBACnB,UAAU,EAAE,eAAe;gBAC3B,aAAa,EAAE,YAAY;gBAC3B,SAAS,EAAE,sBAAsB;gBACjC,KAAK,EAAE,mBAAmB;aAC3B,CAAC;YACF,MAAM,EAAE,UAAU,CAAC,MAAM;SAC1B,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,KAAK,IAAI,CAAC,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAClD,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,uCAAuC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;QAC9F,CAAC;QACD,MAAM,IAAI,eAAe,CAAC,eAAe,EAAE,oCAAoC,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IACjG,CAAC;YAAS,CAAC;QACT,YAAY,CAAC,KAAK,CAAC,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;QACZ,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,GAAG,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;QACnF,MAAM,IAAI,eAAe,CACvB,MAAM,EACN,sCAAsC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,EACtE,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,CAC3B,CAAC;IACJ,CAAC;IAED,IAAI,IAAa,CAAC;IAClB,IAAI,CAAC;QACH,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAY,CAAC;IACvC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,MAAM,IAAI,eAAe,CAAC,aAAa,EAAE,kDAAkD,EAAE;YAC3F,KAAK,EAAE,CAAC;SACT,CAAC,CAAC;IACL,CAAC;IAED,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,MAAM,IAAI,eAAe,CAAC,aAAa,EAAE,kDAAkD,CAAC,CAAC;IAC/F,CAAC;IAED,MAAM,MAAM,GAAG,IAA+B,CAAC;IAC/C,MAAM,WAAW,GACf,OAAO,MAAM,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,YAAY,CAAC,MAAM,GAAG,CAAC;QACvE,CAAC,CAAC,MAAM,CAAC,YAAY;QACrB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,SAAS,GACb,OAAO,MAAM,CAAC,UAAU,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC;QACzE,CAAC,CAAC,MAAM,CAAC,UAAU;QACnB,CAAC,CAAC,IAAI,CAAC;IACX,MAAM,gBAAgB,GACpB,OAAO,MAAM,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,aAAa,CAAC,MAAM,GAAG,CAAC;QACzE,CAAC,CAAC,MAAM,CAAC,aAAa;QACtB,CAAC,CAAC,YAAY,CAAC;IAEnB,IAAI,CAAC,WAAW,IAAI,SAAS,KAAK,IAAI,EAAE,CAAC;QACvC,MAAM,IAAI,eAAe,CACvB,aAAa,EACb,8DAA8D,CAC/D,CAAC;IACJ,CAAC;IAED,OAAO;QACL,WAAW;QACX,YAAY,EAAE,gBAAgB;QAC9B,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,SAAS,GAAG,IAAI;KACzC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,YAAoB,IAAI;IAClE,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,qBAAqB,EAAE,CAAC;QACtC,IAAI,CAAC,KAAK,EAAE,CAAC;YACX,MAAM,IAAI,eAAe,CAAC,gBAAgB,EAAE,6BAA6B,CAAC,CAAC;QAC7E,CAAC;QAED,IAAI,WAAW,GAAG,KAAK,CAAC,WAAW,CAAC;QACpC,IAAI,YAAY,GAAG,KAAK,CAAC,YAAY,CAAC;QACtC,IAAI,UAAU,GAAG,KAAK,CAAC;QAEvB,MAAM,iBAAiB,GAAG,KAAK,IAAI,EAAE;YACnC,IAAI,CAAC,YAAY,EAAE,CAAC;gBAClB,MAAM,IAAI,eAAe,CAAC,eAAe,EAAE,iCAAiC,CAAC,CAAC;YAChF,CAAC;YACD,MAAM,SAAS,GAAG,MAAM,wBAAwB,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC;YAC1E,WAAW,GAAG,SAAS,CAAC,WAAW,CAAC;YACpC,YAAY,GAAG,SAAS,CAAC,YAAY,CAAC;YACtC,8BAA8B,CAAC,SAAS,CAAC,CAAC;YAC1C,UAAU,GAAG,IAAI,CAAC;QACpB,CAAC,CAAC;QAEF,2CAA2C;QAC3C,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,OAAO,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YAC5C,MAAM,iBAAiB,EAAE,CAAC;QAC5B,CAAC;QAED,IAAI,GAAG,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAE3D,6FAA6F;QAC7F,sDAAsD;QACtD,IACE,CAAC,GAAG,CAAC,EAAE;YACP,CAAC,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC;YAChE,CAAC,UAAU;YACX,YAAY,EACZ,CAAC;YACD,MAAM,iBAAiB,EAAE,CAAC;YAC1B,GAAG,GAAG,MAAM,kBAAkB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QACzD,CAAC;QAED,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;YACZ,MAAM,MAAM,GAAG,GAAG,CAAC,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,CAAC,CAAC,CAAC,aAAa,CAAC,CAAC,CAAC,WAAW,CAAC;YACtF,MAAM,IAAI,eAAe,CACvB,MAAM,EACN,gCAAgC,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,UAAU,IAAI,EAChE,EAAE,UAAU,EAAE,GAAG,CAAC,MAAM,EAAE,CAC3B,CAAC;QACJ,CAAC;QAED,MAAM,IAAI,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAY,CAAC;QAC3C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;YACtC,MAAM,IAAI,eAAe,CAAC,aAAa,EAAE,8CAA8C,CAAC,CAAC;QAC3F,CAAC;QACD,MAAM,MAAM,GAAG,IAA+B,CAAC;QAE/C,MAAM,WAAW,GAAG,CAAC,GAAY,EAAE,EAAE;YACnC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACjD,MAAM,CAAC,GAAG,GAA8B,CAAC;YACzC,MAAM,WAAW,GACf,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC;YAC7F,MAAM,SAAS,GAAG,OAAO,CAAC,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC;YACvE,IAAI,WAAW,KAAK,IAAI,IAAI,CAAC,SAAS;gBAAE,OAAO,IAAI,CAAC;YACpD,OAAO,EAAE,WAAW,EAAE,SAAS,EAAE,CAAC;QACpC,CAAC,CAAC;QAEF,MAAM,eAAe,GAAG,CAAC,GAAY,EAAE,EAAE;YACvC,IAAI,CAAC,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ;gBAAE,OAAO,IAAI,CAAC;YACjD,MAAM,CAAC,GAAG,GAA8B,CAAC;YACzC,MAAM,UAAU,GAAG,OAAO,CAAC,CAAC,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,KAAK,CAAC;YAC5E,MAAM,aAAa,GACjB,OAAO,CAAC,CAAC,aAAa,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC;gBACrE,CAAC,CAAC,CAAC,CAAC,aAAa;gBACjB,CAAC,CAAC,IAAI,CAAC;YACX,MAAM,YAAY,GAChB,OAAO,CAAC,CAAC,YAAY,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7F,MAAM,WAAW,GACf,OAAO,CAAC,CAAC,WAAW,KAAK,QAAQ,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAAC;YAC1F,OAAO,EAAE,UAAU,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,EAAE,CAAC;QAClE,CAAC,CAAC;QAEF,MAAM,GAAG,GAAoB;YAC3B,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC;YACxC,SAAS,EAAE,WAAW,CAAC,MAAM,CAAC,SAAS,CAAC;YACxC,gBAAgB,EAAE,WAAW,CAAC,MAAM,CAAC,gBAAgB,CAAC;YACtD,WAAW,EAAE,eAAe,CAAC,MAAM,CAAC,WAAW,CAAC;SACjD,CAAC;QACF,OAAO,GAAG,CAAC;IACb,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,IAAI,CAAC,YAAY,eAAe;YAAE,MAAM,CAAC,CAAC;QAC1C,MAAM,IAAI,eAAe,CAAC,SAAS,EAAE,4BAA4B,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC,CAAC;IACnF,CAAC;AACH,CAAC"}
|