ynabro 2.0.0 → 2.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/tools/index.d.ts +2 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/onboardingStatus.d.ts +10 -0
- package/dist/tools/onboardingStatus.d.ts.map +1 -0
- package/dist/tools/onboardingStatus.js +30 -0
- package/dist/tools/onboardingStatus.js.map +1 -0
- package/dist/tools/setupYnab.d.ts +15 -9
- package/dist/tools/setupYnab.d.ts.map +1 -1
- package/dist/tools/setupYnab.js +13 -67
- package/dist/tools/setupYnab.js.map +1 -1
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { YnabroClient } from "./client/YnabroClient.js";
|
|
2
|
-
export { approveTransaction, getPendingTransactions, getPlanInfo, getRecentTransactions, getSkillState, setupYnab, updateSkillState, } from "./tools/index.js";
|
|
2
|
+
export { approveTransaction, checkOnboardingStatus, getPendingTransactions, getPlanInfo, getRecentTransactions, getSkillState, type OnboardingStatus, setupYnab, TOKEN_INSTRUCTIONS, updateSkillState, type YnabroConfigAdapter, } from "./tools/index.js";
|
|
3
3
|
export type { YnabPlan, YnabTransaction } from "./types/ynab.js";
|
|
4
4
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,SAAS,EACT,gBAAgB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,aAAa,EACb,KAAK,gBAAgB,EACrB,SAAS,EACT,kBAAkB,EAClB,gBAAgB,EAChB,KAAK,mBAAmB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { YnabroClient } from "./client/YnabroClient.js";
|
|
2
|
-
export { approveTransaction, getPendingTransactions, getPlanInfo, getRecentTransactions, getSkillState, setupYnab, updateSkillState, } from "./tools/index.js";
|
|
2
|
+
export { approveTransaction, checkOnboardingStatus, getPendingTransactions, getPlanInfo, getRecentTransactions, getSkillState, setupYnab, TOKEN_INSTRUCTIONS, updateSkillState, } from "./tools/index.js";
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,aAAa,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AACxD,OAAO,EACL,kBAAkB,EAClB,qBAAqB,EACrB,sBAAsB,EACtB,WAAW,EACX,qBAAqB,EACrB,aAAa,EAEb,SAAS,EACT,kBAAkB,EAClB,gBAAgB,GAEjB,MAAM,kBAAkB,CAAC"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -3,6 +3,7 @@ export { getPendingTransactions } from "./getPendingTransactions.js";
|
|
|
3
3
|
export { getPlanInfo } from "./getPlanInfo.js";
|
|
4
4
|
export { getRecentTransactions } from "./getRecentTransactions.js";
|
|
5
5
|
export { getSkillState } from "./getSkillState.js";
|
|
6
|
-
export {
|
|
6
|
+
export { checkOnboardingStatus, type OnboardingStatus, TOKEN_INSTRUCTIONS, } from "./onboardingStatus.js";
|
|
7
|
+
export { setupYnab, type YnabroConfigAdapter } from "./setupYnab.js";
|
|
7
8
|
export { updateSkillState } from "./updateSkillState.js";
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,qBAAqB,EACrB,KAAK,gBAAgB,EACrB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAAE,KAAK,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/tools/index.js
CHANGED
|
@@ -3,6 +3,7 @@ export { getPendingTransactions } from "./getPendingTransactions.js";
|
|
|
3
3
|
export { getPlanInfo } from "./getPlanInfo.js";
|
|
4
4
|
export { getRecentTransactions } from "./getRecentTransactions.js";
|
|
5
5
|
export { getSkillState } from "./getSkillState.js";
|
|
6
|
+
export { checkOnboardingStatus, TOKEN_INSTRUCTIONS, } from "./onboardingStatus.js";
|
|
6
7
|
export { setupYnab } from "./setupYnab.js";
|
|
7
8
|
export { updateSkillState } from "./updateSkillState.js";
|
|
8
9
|
//# sourceMappingURL=index.js.map
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EAAE,SAAS,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,sBAAsB,EAAE,MAAM,6BAA6B,CAAC;AACrE,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACnD,OAAO,EACL,qBAAqB,EAErB,kBAAkB,GACnB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,SAAS,EAA4B,MAAM,gBAAgB,CAAC;AACrE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { YnabroConfigAdapter } from "./setupYnab.js";
|
|
2
|
+
export interface OnboardingStatus {
|
|
3
|
+
ready: boolean;
|
|
4
|
+
missing: ("token" | "plan")[];
|
|
5
|
+
tokenInstructions: string;
|
|
6
|
+
nextStep?: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const TOKEN_INSTRUCTIONS = "To generate a YNAB Personal Access Token:\n1. Go to https://app.ynab.com/settings/developer\n2. Click 'New Token'\n3. Enter your YNAB password\n4. Copy the token (it will only be shown once)";
|
|
9
|
+
export declare function checkOnboardingStatus(adapter: YnabroConfigAdapter): Promise<OnboardingStatus>;
|
|
10
|
+
//# sourceMappingURL=onboardingStatus.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboardingStatus.d.ts","sourceRoot":"","sources":["../../src/tools/onboardingStatus.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,gBAAgB,CAAC;AAE1D,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,OAAO,CAAC;IACf,OAAO,EAAE,CAAC,OAAO,GAAG,MAAM,CAAC,EAAE,CAAC;IAC9B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,eAAO,MAAM,kBAAkB,mMAIgB,CAAC;AAEhD,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,gBAAgB,CAAC,CA0B3B"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
export const TOKEN_INSTRUCTIONS = `To generate a YNAB Personal Access Token:
|
|
2
|
+
1. Go to https://app.ynab.com/settings/developer
|
|
3
|
+
2. Click 'New Token'
|
|
4
|
+
3. Enter your YNAB password
|
|
5
|
+
4. Copy the token (it will only be shown once)`;
|
|
6
|
+
export async function checkOnboardingStatus(adapter) {
|
|
7
|
+
const [hasToken, planId] = await Promise.all([
|
|
8
|
+
adapter.hasToken(),
|
|
9
|
+
adapter.getDefaultPlanId(),
|
|
10
|
+
]);
|
|
11
|
+
const missing = [];
|
|
12
|
+
if (!hasToken) {
|
|
13
|
+
missing.push("token");
|
|
14
|
+
}
|
|
15
|
+
if (!planId) {
|
|
16
|
+
missing.push("plan");
|
|
17
|
+
}
|
|
18
|
+
const ready = missing.length === 0;
|
|
19
|
+
return {
|
|
20
|
+
ready,
|
|
21
|
+
missing,
|
|
22
|
+
tokenInstructions: TOKEN_INSTRUCTIONS,
|
|
23
|
+
nextStep: ready
|
|
24
|
+
? undefined
|
|
25
|
+
: missing.includes("token")
|
|
26
|
+
? "Please configure your YNAB Personal Access Token."
|
|
27
|
+
: "Please select a default plan.",
|
|
28
|
+
};
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=onboardingStatus.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"onboardingStatus.js","sourceRoot":"","sources":["../../src/tools/onboardingStatus.ts"],"names":[],"mappings":"AASA,MAAM,CAAC,MAAM,kBAAkB,GAAG;;;;+CAIa,CAAC;AAEhD,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,OAA4B;IAE5B,MAAM,CAAC,QAAQ,EAAE,MAAM,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAC3C,OAAO,CAAC,QAAQ,EAAE;QAClB,OAAO,CAAC,gBAAgB,EAAE;KAC3B,CAAC,CAAC;IAEH,MAAM,OAAO,GAAyB,EAAE,CAAC;IACzC,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACxB,CAAC;IACD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;IACvB,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC;IAEnC,OAAO;QACL,KAAK;QACL,OAAO;QACP,iBAAiB,EAAE,kBAAkB;QACrC,QAAQ,EAAE,KAAK;YACb,CAAC,CAAC,SAAS;YACX,CAAC,CAAC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAC;gBACzB,CAAC,CAAC,mDAAmD;gBACrD,CAAC,CAAC,+BAA+B;KACtC,CAAC;AACJ,CAAC"}
|
|
@@ -1,12 +1,18 @@
|
|
|
1
|
+
import type { YnabroClient } from "../client/YnabroClient.js";
|
|
2
|
+
import type { YnabPlan } from "../types/ynab.js";
|
|
3
|
+
export interface YnabroConfigAdapter {
|
|
4
|
+
hasToken(): Promise<boolean>;
|
|
5
|
+
getDefaultPlanId(): Promise<string | undefined>;
|
|
6
|
+
setDefaultPlanId(planId: string): Promise<void>;
|
|
7
|
+
}
|
|
1
8
|
/**
|
|
2
|
-
* Sets up YNAB integration
|
|
3
|
-
*
|
|
9
|
+
* Sets up YNAB integration by validating and storing the selected plan ID.
|
|
10
|
+
*
|
|
11
|
+
* @param _client - YnabroClient instance (unused in this implementation)
|
|
12
|
+
* @param plans - Array of available YNAB plans
|
|
13
|
+
* @param selectedPlanId - The plan ID to set as default
|
|
14
|
+
* @param adapter - Configuration adapter for persisting the selection
|
|
15
|
+
* @throws Error if selectedPlanId is not found in plans
|
|
4
16
|
*/
|
|
5
|
-
export declare function setupYnab(): Promise<
|
|
6
|
-
message: string;
|
|
7
|
-
defaultPlanId?: undefined;
|
|
8
|
-
} | {
|
|
9
|
-
message: string;
|
|
10
|
-
defaultPlanId: string;
|
|
11
|
-
}>;
|
|
17
|
+
export declare function setupYnab(_client: YnabroClient, plans: YnabPlan[], selectedPlanId: string, adapter: YnabroConfigAdapter): Promise<void>;
|
|
12
18
|
//# sourceMappingURL=setupYnab.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupYnab.d.ts","sourceRoot":"","sources":["../../src/tools/setupYnab.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupYnab.d.ts","sourceRoot":"","sources":["../../src/tools/setupYnab.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAEjD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,IAAI,OAAO,CAAC,OAAO,CAAC,CAAC;IAC7B,gBAAgB,IAAI,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CAAC;IAChD,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACjD;AAED;;;;;;;;GAQG;AACH,wBAAsB,SAAS,CAC7B,OAAO,EAAE,YAAY,EACrB,KAAK,EAAE,QAAQ,EAAE,EACjB,cAAc,EAAE,MAAM,EACtB,OAAO,EAAE,mBAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAWf"}
|
package/dist/tools/setupYnab.js
CHANGED
|
@@ -1,72 +1,18 @@
|
|
|
1
|
-
import fs from "node:fs";
|
|
2
|
-
import path from "node:path";
|
|
3
|
-
import { YnabroClient } from "../client/YnabroClient.js";
|
|
4
|
-
const CONFIG_DIR = ".ynabro";
|
|
5
|
-
const CONFIG_FILE = path.join(CONFIG_DIR, "config.json");
|
|
6
|
-
function ensureConfigDir() {
|
|
7
|
-
if (!fs.existsSync(CONFIG_DIR)) {
|
|
8
|
-
fs.mkdirSync(CONFIG_DIR, { recursive: true });
|
|
9
|
-
}
|
|
10
|
-
}
|
|
11
|
-
function loadConfig() {
|
|
12
|
-
ensureConfigDir();
|
|
13
|
-
if (fs.existsSync(CONFIG_FILE)) {
|
|
14
|
-
return JSON.parse(fs.readFileSync(CONFIG_FILE, "utf-8"));
|
|
15
|
-
}
|
|
16
|
-
return {};
|
|
17
|
-
}
|
|
18
|
-
function saveConfig(config) {
|
|
19
|
-
ensureConfigDir();
|
|
20
|
-
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
|
|
21
|
-
}
|
|
22
1
|
/**
|
|
23
|
-
* Sets up YNAB integration
|
|
24
|
-
*
|
|
2
|
+
* Sets up YNAB integration by validating and storing the selected plan ID.
|
|
3
|
+
*
|
|
4
|
+
* @param _client - YnabroClient instance (unused in this implementation)
|
|
5
|
+
* @param plans - Array of available YNAB plans
|
|
6
|
+
* @param selectedPlanId - The plan ID to set as default
|
|
7
|
+
* @param adapter - Configuration adapter for persisting the selection
|
|
8
|
+
* @throws Error if selectedPlanId is not found in plans
|
|
25
9
|
*/
|
|
26
|
-
export async function setupYnab() {
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
}
|
|
32
|
-
if (!token) {
|
|
33
|
-
console.log(`
|
|
34
|
-
To use YNABro, you need a YNAB Personal Access Token.
|
|
35
|
-
|
|
36
|
-
1. Go to: https://app.ynab.com/settings/developer
|
|
37
|
-
2. Click "Create New Token"
|
|
38
|
-
3. Give it a name (e.g. "YNABro")
|
|
39
|
-
4. Copy the token
|
|
40
|
-
|
|
41
|
-
You can store it in one of these ways:
|
|
42
|
-
- Environment variable: export YNAB_TOKEN=your_token_here
|
|
43
|
-
- Config file: ${CONFIG_FILE}
|
|
44
|
-
- Or paste it below now
|
|
45
|
-
`);
|
|
46
|
-
// In a real implementation, we'd prompt for input here.
|
|
47
|
-
// For now, we'll just instruct the user.
|
|
48
|
-
return {
|
|
49
|
-
message: "Please set your YNAB token using one of the methods above, then run setupYnab() again.",
|
|
50
|
-
};
|
|
51
|
-
}
|
|
52
|
-
const client = new YnabroClient(token);
|
|
53
|
-
const plans = await client.getPlans();
|
|
54
|
-
if (plans.length === 0) {
|
|
55
|
-
return { message: "No plans found in your YNAB account." };
|
|
10
|
+
export async function setupYnab(_client, plans, selectedPlanId, adapter) {
|
|
11
|
+
const planExists = plans.some((plan) => plan.id === selectedPlanId);
|
|
12
|
+
if (!planExists) {
|
|
13
|
+
const validIds = plans.map((p) => p.id).join(", ");
|
|
14
|
+
throw new Error(`Plan ID "${selectedPlanId}" not found. Valid IDs: ${validIds}`);
|
|
56
15
|
}
|
|
57
|
-
|
|
58
|
-
plans.forEach((plan, index) => {
|
|
59
|
-
console.log(`${index + 1}. ${plan.name} (ID: ${plan.id})`);
|
|
60
|
-
});
|
|
61
|
-
// In a real implementation, we would prompt the user to choose.
|
|
62
|
-
// For now, we'll auto-select the first one and save it.
|
|
63
|
-
const selectedPlan = plans[0];
|
|
64
|
-
config.token = token;
|
|
65
|
-
config.defaultPlanId = selectedPlan.id;
|
|
66
|
-
saveConfig(config);
|
|
67
|
-
return {
|
|
68
|
-
message: `Setup complete! Default plan set to: ${selectedPlan.name}`,
|
|
69
|
-
defaultPlanId: selectedPlan.id,
|
|
70
|
-
};
|
|
16
|
+
await adapter.setDefaultPlanId(selectedPlanId);
|
|
71
17
|
}
|
|
72
18
|
//# sourceMappingURL=setupYnab.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"setupYnab.js","sourceRoot":"","sources":["../../src/tools/setupYnab.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"setupYnab.js","sourceRoot":"","sources":["../../src/tools/setupYnab.ts"],"names":[],"mappings":"AASA;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,SAAS,CAC7B,OAAqB,EACrB,KAAiB,EACjB,cAAsB,EACtB,OAA4B;IAE5B,MAAM,UAAU,GAAG,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,cAAc,CAAC,CAAC;IAEpE,IAAI,CAAC,UAAU,EAAE,CAAC;QAChB,MAAM,QAAQ,GAAG,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACnD,MAAM,IAAI,KAAK,CACb,YAAY,cAAc,2BAA2B,QAAQ,EAAE,CAChE,CAAC;IACJ,CAAC;IAED,MAAM,OAAO,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC;AACjD,CAAC"}
|