@huddle-marketplace/skills 0.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.
Files changed (86) hide show
  1. package/README.md +256 -0
  2. package/dist/adapters/openclaw.d.ts +42 -0
  3. package/dist/adapters/openclaw.d.ts.map +1 -0
  4. package/dist/adapters/openclaw.js +94 -0
  5. package/dist/adapters/openclaw.js.map +1 -0
  6. package/dist/base.d.ts +26 -0
  7. package/dist/base.d.ts.map +1 -0
  8. package/dist/base.js +97 -0
  9. package/dist/base.js.map +1 -0
  10. package/dist/compose.d.ts +87 -0
  11. package/dist/compose.d.ts.map +1 -0
  12. package/dist/compose.js +119 -0
  13. package/dist/compose.js.map +1 -0
  14. package/dist/index.d.ts +104 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +167 -0
  17. package/dist/index.js.map +1 -0
  18. package/dist/jurisdictions/ca-bc/index.d.ts +49 -0
  19. package/dist/jurisdictions/ca-bc/index.d.ts.map +1 -0
  20. package/dist/jurisdictions/ca-bc/index.js +212 -0
  21. package/dist/jurisdictions/ca-bc/index.js.map +1 -0
  22. package/dist/jurisdictions/ca-ns/index.d.ts +27 -0
  23. package/dist/jurisdictions/ca-ns/index.d.ts.map +1 -0
  24. package/dist/jurisdictions/ca-ns/index.js +127 -0
  25. package/dist/jurisdictions/ca-ns/index.js.map +1 -0
  26. package/dist/jurisdictions/ca-on/index.d.ts +26 -0
  27. package/dist/jurisdictions/ca-on/index.d.ts.map +1 -0
  28. package/dist/jurisdictions/ca-on/index.js +109 -0
  29. package/dist/jurisdictions/ca-on/index.js.map +1 -0
  30. package/dist/jurisdictions/ca-qc/index.d.ts +75 -0
  31. package/dist/jurisdictions/ca-qc/index.d.ts.map +1 -0
  32. package/dist/jurisdictions/ca-qc/index.js +232 -0
  33. package/dist/jurisdictions/ca-qc/index.js.map +1 -0
  34. package/dist/jurisdictions/canadian-template.d.ts +49 -0
  35. package/dist/jurisdictions/canadian-template.d.ts.map +1 -0
  36. package/dist/jurisdictions/canadian-template.js +228 -0
  37. package/dist/jurisdictions/canadian-template.js.map +1 -0
  38. package/dist/jurisdictions/lifecycle/active-tenancy.d.ts +55 -0
  39. package/dist/jurisdictions/lifecycle/active-tenancy.d.ts.map +1 -0
  40. package/dist/jurisdictions/lifecycle/active-tenancy.js +227 -0
  41. package/dist/jurisdictions/lifecycle/active-tenancy.js.map +1 -0
  42. package/dist/jurisdictions/lifecycle/homeownership-readiness.d.ts +60 -0
  43. package/dist/jurisdictions/lifecycle/homeownership-readiness.d.ts.map +1 -0
  44. package/dist/jurisdictions/lifecycle/homeownership-readiness.js +401 -0
  45. package/dist/jurisdictions/lifecycle/homeownership-readiness.js.map +1 -0
  46. package/dist/jurisdictions/us-ca/index.d.ts +65 -0
  47. package/dist/jurisdictions/us-ca/index.d.ts.map +1 -0
  48. package/dist/jurisdictions/us-ca/index.js +265 -0
  49. package/dist/jurisdictions/us-ca/index.js.map +1 -0
  50. package/dist/jurisdictions/us-cftc/index.d.ts +48 -0
  51. package/dist/jurisdictions/us-cftc/index.d.ts.map +1 -0
  52. package/dist/jurisdictions/us-cftc/index.js +192 -0
  53. package/dist/jurisdictions/us-cftc/index.js.map +1 -0
  54. package/dist/jurisdictions/us-fl/index.d.ts +43 -0
  55. package/dist/jurisdictions/us-fl/index.d.ts.map +1 -0
  56. package/dist/jurisdictions/us-fl/index.js +129 -0
  57. package/dist/jurisdictions/us-fl/index.js.map +1 -0
  58. package/dist/jurisdictions/us-ny/index.d.ts +77 -0
  59. package/dist/jurisdictions/us-ny/index.d.ts.map +1 -0
  60. package/dist/jurisdictions/us-ny/index.js +344 -0
  61. package/dist/jurisdictions/us-ny/index.js.map +1 -0
  62. package/dist/jurisdictions/us-state-factory.d.ts +79 -0
  63. package/dist/jurisdictions/us-state-factory.d.ts.map +1 -0
  64. package/dist/jurisdictions/us-state-factory.js +425 -0
  65. package/dist/jurisdictions/us-state-factory.js.map +1 -0
  66. package/dist/jurisdictions/us-tx/index.d.ts +43 -0
  67. package/dist/jurisdictions/us-tx/index.d.ts.map +1 -0
  68. package/dist/jurisdictions/us-tx/index.js +160 -0
  69. package/dist/jurisdictions/us-tx/index.js.map +1 -0
  70. package/dist/mcp/index.d.ts +49 -0
  71. package/dist/mcp/index.d.ts.map +1 -0
  72. package/dist/mcp/index.js +211 -0
  73. package/dist/mcp/index.js.map +1 -0
  74. package/dist/registry/index.d.ts +27 -0
  75. package/dist/registry/index.d.ts.map +1 -0
  76. package/dist/registry/index.js +47 -0
  77. package/dist/registry/index.js.map +1 -0
  78. package/dist/traiga/index.d.ts +24 -0
  79. package/dist/traiga/index.d.ts.map +1 -0
  80. package/dist/traiga/index.js +67 -0
  81. package/dist/traiga/index.js.map +1 -0
  82. package/dist/types/index.d.ts +814 -0
  83. package/dist/types/index.d.ts.map +1 -0
  84. package/dist/types/index.js +150 -0
  85. package/dist/types/index.js.map +1 -0
  86. package/package.json +77 -0
package/README.md ADDED
@@ -0,0 +1,256 @@
1
+ # @huddle-marketplace/skills
2
+
3
+ **63-jurisdiction rental compliance skills for autonomous AI agents.**
4
+
5
+ Validates security deposits, rent payments, late fees, and deposit returns against real statutes across 50 US states, 13 Canadian provinces, and federal overlays. OpenClaw, MCP, LangChain, and CrewAI compatible.
6
+
7
+ ```bash
8
+ npm install @huddle-marketplace/skills
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Quick Start
14
+
15
+ ```typescript
16
+ import { validate, composeSkills, registry } from "@huddle-marketplace/skills";
17
+
18
+ // Single jurisdiction — wBTC bond in Texas
19
+ const result = await validate("US-TX", {
20
+ type: "deposit-validation",
21
+ depositAmountCents: 200000, // $2,000 — always in CENTS
22
+ monthlyRentCents: 200000, // $2,000
23
+ currency: "USDC",
24
+ collateralType: "wbtc",
25
+ instrumentType: "collateralized_lease_guarantee",
26
+ });
27
+
28
+ console.log(result.compliant); // true
29
+ console.log(result.confidence); // 0.9
30
+ console.log(result.citations); // [{ statute: "Texas SB-38", section: "Section 3", ... }]
31
+
32
+ // Stacked validation — CFTC federal preemption + state rules
33
+ const composed = await composeSkills(["US-CFTC", "US-TX"], {
34
+ type: "deposit-validation",
35
+ depositAmountCents: 200000,
36
+ monthlyRentCents: 200000,
37
+ currency: "USDC",
38
+ collateralType: "wbtc",
39
+ instrumentType: "collateralized_lease_guarantee",
40
+ wbtcUsdcRatio: 1.05,
41
+ custodyType: "smart_contract",
42
+ sentinelMonitoring: true,
43
+ sentinelMode: "CO_PILOT",
44
+ lastSentinelCheckMs: Date.now() - 60000,
45
+ auditLogEnabled: true,
46
+ lastDecisionReasoning: "LTV nominal",
47
+ });
48
+
49
+ console.log(composed.compliant); // true
50
+ console.log(composed.layers.length); // 2
51
+ console.log(composed.checks[0].name); // "[US-CFTC] federal-preemption"
52
+ console.log(composed.citations.length); // merged + deduplicated
53
+ ```
54
+
55
+ ---
56
+
57
+ ## API Reference
58
+
59
+ ### `validate(jurisdiction, input)`
60
+
61
+ Run a single jurisdiction's skill against the input.
62
+
63
+ ```typescript
64
+ const result = await validate("US-CA", input);
65
+ // result: SkillResult
66
+ ```
67
+
68
+ ### `composeSkills(jurisdictions, input, options?)`
69
+
70
+ Stack multiple jurisdictions into one layered compliance proof. Layers run in parallel.
71
+
72
+ ```typescript
73
+ const result = await composeSkills(["US-CFTC", "US-IL"], input);
74
+ // result: ComposedResult — { compliant, confidence, layers[], checks[], citations[], remediation[] }
75
+
76
+ // Advisory mode: only US-CFTC determines overall compliance
77
+ const result = await composeSkills(["US-CFTC", "US-TX"], input, {
78
+ mode: "advisory",
79
+ criticalJurisdictions: ["US-CFTC"],
80
+ });
81
+ ```
82
+
83
+ ### `registry`
84
+
85
+ Pre-loaded registry with all 64 jurisdictions.
86
+
87
+ ```typescript
88
+ registry.get("US-TX") // HuddleSkill | undefined
89
+ registry.jurisdictions() // JurisdictionCode[]
90
+ registry.isSupported("US-TX") // boolean
91
+ registry.search(["deposit-validation"]) // HuddleSkill[]
92
+ ```
93
+
94
+ ### `explain(jurisdiction, result)`
95
+
96
+ Human-readable explanation of a validation result.
97
+
98
+ ```typescript
99
+ const text = explain("US-TX", result);
100
+ // "This transaction PASSES Texas SB-38 & Property Code §92 compliance (confidence: 90%)..."
101
+ ```
102
+
103
+ ---
104
+
105
+ ## Jurisdictions
106
+
107
+ ### US States (50)
108
+
109
+ | Tier | States | Capabilities |
110
+ |---|---|---|
111
+ | **Tier 1 — Full statute logic** | TX, FL, CA, NY | deposit-validation, deposit-return, federal-preemption |
112
+ | **Tier 2 — Real rules** | IL, WA, CO, MA, PA, OH, GA, NC, VA, MI | deposit-validation, payment-compliance, deposit-return, deposit-interest |
113
+ | **Tier 3 — Capped states** | 26 states with statutory caps | deposit-validation, federal-preemption |
114
+ | **Tier 4 — No-cap states** | Remaining states | deposit-validation, federal-preemption |
115
+
116
+ ### Canadian Provinces (13)
117
+
118
+ | Tier | Provinces |
119
+ |---|---|
120
+ | **Full statute** | BC, ON, QC (bilingual), NS |
121
+ | **Template** | AB, MB, SK, NB, PE, NL, NT, YT, NU |
122
+
123
+ ### Federal Overlays
124
+
125
+ | Code | Coverage |
126
+ |---|---|
127
+ | `US-CFTC` | CFTC 9180-26: wBTC bond federal preemption, 1:1 reserve ratio, Sentinel monitoring, TRAIGA |
128
+ | `CA-QC` | CCQ art. 1904 deposit prohibition, TAL jurisdiction, bilingual FR/EN citations |
129
+
130
+ ---
131
+
132
+ ## Web3-Native Features
133
+
134
+ ### wBTC Bond Recognition
135
+
136
+ When `collateralType: "wbtc"` is set, skills recognize that `HuddleDepositVaultV3`'s on-chain Golden Rule (wBTC value ≥ original principal, enforced by Solidity) structurally satisfies — and exceeds — statutory interest requirements:
137
+
138
+ ```typescript
139
+ // IL requires 5% annual interest on deposits
140
+ // wBTC bond → interest check returns confidence: 0.98 (higher than legacy 0.75)
141
+ const result = await validate("US-IL", {
142
+ type: "deposit-validation",
143
+ collateralType: "wbtc", // ← Web3 path
144
+ ...
145
+ });
146
+ // check "deposit-interest-requirement": passed: true, confidence: 0.98
147
+ // note: "SATISFIED: wBTC bond appreciation via HuddleDepositVaultV3 structurally exceeds..."
148
+ ```
149
+
150
+ ### Composition Engine
151
+
152
+ Federal + state validation in one call:
153
+
154
+ ```typescript
155
+ const result = await composeSkills(["US-CFTC", "US-TX", "US-IL"], input);
156
+ // Runs all 3 in parallel, merges checks, deduplicates citations
157
+ ```
158
+
159
+ ---
160
+
161
+ ## Framework Adapters
162
+
163
+ ### MCP (Model Context Protocol)
164
+
165
+ ```typescript
166
+ import { getMCPToolDefinitions, handleMCPRequest } from "@huddle-marketplace/skills/mcp";
167
+
168
+ const tools = getMCPToolDefinitions(); // Ready for Claude Desktop
169
+ const response = await handleMCPRequest(mcpRequest, registry);
170
+ ```
171
+
172
+ ### OpenClaw
173
+
174
+ ```typescript
175
+ import { toOpenClawSkill } from "@huddle-marketplace/skills/openclaw";
176
+
177
+ const openClawTool = toOpenClawSkill(usTxSkill);
178
+ ```
179
+
180
+ ### LangChain
181
+
182
+ ```typescript
183
+ import { registry } from "@huddle-marketplace/skills/langchain";
184
+ // DynamicStructuredTool instances for every jurisdiction
185
+ ```
186
+
187
+ ### TRAIGA Audit Logging
188
+
189
+ ```typescript
190
+ import { withTraiga, ConsoleTraigaAdapter } from "@huddle-marketplace/skills/traiga";
191
+
192
+ const auditedSkill = withTraiga(usTxSkill, new ConsoleTraigaAdapter());
193
+ // Every validation is logged with inputHash, outputHash, decision, confidence
194
+ ```
195
+
196
+ ---
197
+
198
+ ## Input Types
199
+
200
+ All monetary amounts are in **cents** (integer).
201
+
202
+ ```typescript
203
+ // Deposit validation
204
+ { type: "deposit-validation", depositAmountCents, monthlyRentCents, currency, ... }
205
+
206
+ // Payment compliance
207
+ { type: "payment-compliance", paymentAmountCents, monthlyRentCents, dueDate, paymentDate, ... }
208
+
209
+ // Rent increase
210
+ { type: "rent-increase-validation", currentRentCents, proposedRentCents, noticeDateDays, ... }
211
+
212
+ // Deposit return
213
+ { type: "deposit-return", originalDepositCents, proposedReturnCents, leaseEndDate, returnDate, ... }
214
+
215
+ // Homeownership readiness
216
+ { type: "homeownership-readiness", annualIncomeCents, monthlyDebtCents, creditScore, ... }
217
+ ```
218
+
219
+ ---
220
+
221
+ ## Publishing (Maintainers)
222
+
223
+ The CI/CD pipeline automatically publishes to npm when a commit on `main` starts with `release:`.
224
+
225
+ ### Steps
226
+
227
+ 1. Bump version in [package.json](./package.json)
228
+ 2. Run prepublish gate locally:
229
+ ```bash
230
+ npm run prepublishOnly # lint + test (146 tests) + build
231
+ ```
232
+ 3. Commit and push:
233
+ ```bash
234
+ git add packages/huddle-skills/
235
+ git commit -m "release: v0.2.0"
236
+ git push origin main
237
+ ```
238
+ 4. GitHub Actions triggers `.github/workflows/huddle-skills-ci.yml`:
239
+ - `test` job: lint → 146 tests → build → verify dist
240
+ - `publish` job (only on `release:` prefix + `NPM_TOKEN` secret): `npm publish --access public`
241
+
242
+ ### Required GitHub Secret
243
+
244
+ `NPM_TOKEN` — create at [npmjs.com/settings/tokens](https://www.npmjs.com/settings/tokens) (Automation token, read+write), add to repo secrets at Settings → Secrets → Actions.
245
+
246
+ ### Package Size Budget
247
+
248
+ Target: < 500KB, tree-shakeable per jurisdiction via named exports.
249
+
250
+ ---
251
+
252
+ ## License
253
+
254
+ MIT — see [LICENSE](./LICENSE)
255
+
256
+ Built by [Huddle Protocol](https://github.com/huddle-protocol)
@@ -0,0 +1,42 @@
1
+ /**
2
+ * OpenClaw Adapter
3
+ *
4
+ * Wraps Huddle skills in OpenClaw-compatible format.
5
+ * Each skill becomes an OpenClaw skill with SKILL.md metadata.
6
+ */
7
+ import type { HuddleSkill, SkillResult, SkillMetadata } from "../types/index.js";
8
+ /** OpenClaw skill manifest (SKILL.md frontmatter) */
9
+ export interface OpenClawManifest {
10
+ name: string;
11
+ version: string;
12
+ description: string;
13
+ author: string;
14
+ capabilities: string[];
15
+ inputs: {
16
+ schema: string;
17
+ };
18
+ outputs: {
19
+ schema: string;
20
+ };
21
+ permissions: string[];
22
+ tags: string[];
23
+ }
24
+ /** OpenClaw-compatible skill wrapper */
25
+ export interface OpenClawSkill {
26
+ manifest: OpenClawManifest;
27
+ execute(input: Record<string, unknown>): Promise<SkillResult>;
28
+ metadata(): SkillMetadata;
29
+ }
30
+ /**
31
+ * Convert a HuddleSkill to an OpenClaw-compatible skill
32
+ */
33
+ export declare function toOpenClawSkill(skill: HuddleSkill): OpenClawSkill;
34
+ /**
35
+ * Convert all skills to OpenClaw format
36
+ */
37
+ export declare function toOpenClawSkills(skills: HuddleSkill[]): OpenClawSkill[];
38
+ /**
39
+ * Generate SKILL.md content for a skill (YAML frontmatter + markdown body)
40
+ */
41
+ export declare function generateSkillMd(skill: HuddleSkill): string;
42
+ //# sourceMappingURL=openclaw.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.d.ts","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,WAAW,EAAc,WAAW,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAE7F,qDAAqD;AACrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,YAAY,EAAE,MAAM,EAAE,CAAC;IACvB,MAAM,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3B,OAAO,EAAE;QAAE,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,wCAAwC;AACxC,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,OAAO,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9D,QAAQ,IAAI,aAAa,CAAC;CAC3B;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,aAAa,CAwBjE;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,WAAW,EAAE,GAAG,aAAa,EAAE,CAEvE;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAsD1D"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * OpenClaw Adapter
3
+ *
4
+ * Wraps Huddle skills in OpenClaw-compatible format.
5
+ * Each skill becomes an OpenClaw skill with SKILL.md metadata.
6
+ */
7
+ /**
8
+ * Convert a HuddleSkill to an OpenClaw-compatible skill
9
+ */
10
+ export function toOpenClawSkill(skill) {
11
+ const meta = skill.getMetadata();
12
+ return {
13
+ manifest: {
14
+ name: meta.id,
15
+ version: meta.version,
16
+ description: meta.description,
17
+ author: meta.author,
18
+ capabilities: meta.capabilities,
19
+ inputs: { schema: "./schemas/input.json" },
20
+ outputs: { schema: "./schemas/output.json" },
21
+ permissions: meta.permissions,
22
+ tags: meta.tags,
23
+ },
24
+ async execute(input) {
25
+ return skill.validate(input);
26
+ },
27
+ metadata() {
28
+ return skill.getMetadata();
29
+ },
30
+ };
31
+ }
32
+ /**
33
+ * Convert all skills to OpenClaw format
34
+ */
35
+ export function toOpenClawSkills(skills) {
36
+ return skills.map(toOpenClawSkill);
37
+ }
38
+ /**
39
+ * Generate SKILL.md content for a skill (YAML frontmatter + markdown body)
40
+ */
41
+ export function generateSkillMd(skill) {
42
+ const meta = skill.getMetadata();
43
+ const yaml = [
44
+ "---",
45
+ `name: ${meta.id}`,
46
+ `version: ${meta.version}`,
47
+ `description: ${meta.description}`,
48
+ `author: ${meta.author}`,
49
+ `jurisdiction: ${meta.jurisdiction}`,
50
+ `capabilities: [${meta.capabilities.join(", ")}]`,
51
+ `permissions: [${meta.permissions.join(", ")}]`,
52
+ `tags: [${meta.tags.join(", ")}]`,
53
+ meta.federalPreemption ? `federal_preemption: true` : null,
54
+ meta.effectiveDate ? `effective_date: ${meta.effectiveDate}` : null,
55
+ "---",
56
+ ].filter(Boolean).join("\n");
57
+ const body = [
58
+ "",
59
+ `# ${meta.name}`,
60
+ "",
61
+ `## Jurisdiction: ${meta.jurisdiction}`,
62
+ "",
63
+ meta.description,
64
+ "",
65
+ "## Capabilities",
66
+ "",
67
+ ...meta.capabilities.map((c) => `- ${c}`),
68
+ "",
69
+ "## Usage",
70
+ "",
71
+ "```typescript",
72
+ `import { registry } from "@huddle-marketplace/skills";`,
73
+ "",
74
+ `const skill = registry.get("${meta.jurisdiction}");`,
75
+ `const result = await skill.validate({`,
76
+ ` type: "deposit-validation",`,
77
+ ` depositAmountCents: 150000,`,
78
+ ` monthlyRentCents: 200000,`,
79
+ ` currency: "USD",`,
80
+ `});`,
81
+ "",
82
+ `console.log(result.compliant); // true/false`,
83
+ `console.log(skill.explain(result)); // human-readable explanation`,
84
+ "```",
85
+ "",
86
+ "## Permissions",
87
+ "",
88
+ "This skill requires **no network access** and **no filesystem access**.",
89
+ "It is a pure computation skill that evaluates inputs against legal rules.",
90
+ "",
91
+ ].join("\n");
92
+ return yaml + body;
93
+ }
94
+ //# sourceMappingURL=openclaw.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"openclaw.js","sourceRoot":"","sources":["../../src/adapters/openclaw.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwBH;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IAEjC,OAAO;QACL,QAAQ,EAAE;YACR,IAAI,EAAE,IAAI,CAAC,EAAE;YACb,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,MAAM,EAAE,IAAI,CAAC,MAAM;YACnB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,MAAM,EAAE,EAAE,MAAM,EAAE,sBAAsB,EAAE;YAC1C,OAAO,EAAE,EAAE,MAAM,EAAE,uBAAuB,EAAE;YAC5C,WAAW,EAAE,IAAI,CAAC,WAAW;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;SAChB;QAED,KAAK,CAAC,OAAO,CAAC,KAA8B;YAC1C,OAAO,KAAK,CAAC,QAAQ,CAAC,KAA8B,CAAC,CAAC;QACxD,CAAC;QAED,QAAQ;YACN,OAAO,KAAK,CAAC,WAAW,EAAE,CAAC;QAC7B,CAAC;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAAC,MAAqB;IACpD,OAAO,MAAM,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AACrC,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,KAAkB;IAChD,MAAM,IAAI,GAAG,KAAK,CAAC,WAAW,EAAE,CAAC;IACjC,MAAM,IAAI,GAAG;QACX,KAAK;QACL,SAAS,IAAI,CAAC,EAAE,EAAE;QAClB,YAAY,IAAI,CAAC,OAAO,EAAE;QAC1B,gBAAgB,IAAI,CAAC,WAAW,EAAE;QAClC,WAAW,IAAI,CAAC,MAAM,EAAE;QACxB,iBAAiB,IAAI,CAAC,YAAY,EAAE;QACpC,kBAAkB,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACjD,iBAAiB,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QAC/C,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG;QACjC,IAAI,CAAC,iBAAiB,CAAC,CAAC,CAAC,0BAA0B,CAAC,CAAC,CAAC,IAAI;QAC1D,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,mBAAmB,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,IAAI;QACnE,KAAK;KACN,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAE7B,MAAM,IAAI,GAAG;QACX,EAAE;QACF,KAAK,IAAI,CAAC,IAAI,EAAE;QAChB,EAAE;QACF,oBAAoB,IAAI,CAAC,YAAY,EAAE;QACvC,EAAE;QACF,IAAI,CAAC,WAAW;QAChB,EAAE;QACF,iBAAiB;QACjB,EAAE;QACF,GAAG,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAC,EAAE,CAAC;QACzC,EAAE;QACF,UAAU;QACV,EAAE;QACF,eAAe;QACf,wDAAwD;QACxD,EAAE;QACF,+BAA+B,IAAI,CAAC,YAAY,KAAK;QACrD,uCAAuC;QACvC,+BAA+B;QAC/B,+BAA+B;QAC/B,6BAA6B;QAC7B,oBAAoB;QACpB,KAAK;QACL,EAAE;QACF,8CAA8C;QAC9C,mEAAmE;QACnE,KAAK;QACL,EAAE;QACF,gBAAgB;QAChB,EAAE;QACF,yEAAyE;QACzE,2EAA2E;QAC3E,EAAE;KACH,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;IAEb,OAAO,IAAI,GAAG,IAAI,CAAC;AACrB,CAAC"}
package/dist/base.d.ts ADDED
@@ -0,0 +1,26 @@
1
+ /**
2
+ * BaseSkill — Abstract base class for all Huddle compliance skills.
3
+ *
4
+ * Provides default implementations for explain() and remediate(),
5
+ * so jurisdiction skills only need to implement validate().
6
+ */
7
+ import type { HuddleSkill, SkillInput, SkillResult, SkillMetadata, SkillCapability, JurisdictionCode, RemediationStep, SkillCheck } from "./types/index.js";
8
+ export declare abstract class BaseSkill implements HuddleSkill {
9
+ abstract readonly id: string;
10
+ abstract readonly name: string;
11
+ abstract readonly jurisdiction: JurisdictionCode;
12
+ abstract readonly version: string;
13
+ abstract readonly capabilities: SkillCapability[];
14
+ /** Subclasses implement this to run jurisdiction-specific rules */
15
+ abstract validate(input: SkillInput): Promise<SkillResult>;
16
+ /** Default explainability: build a human-readable summary from checks */
17
+ explain(result: SkillResult): string;
18
+ /** Default remediation: generate steps for each failed check */
19
+ remediate(result: SkillResult): RemediationStep[];
20
+ /** Convert a failed check into a remediation step. Override for custom logic. */
21
+ protected checkToRemediation(check: SkillCheck): RemediationStep;
22
+ /** Build a SkillResult from individual checks */
23
+ protected buildResult(checks: SkillCheck[], input: SkillInput): SkillResult;
24
+ getMetadata(): SkillMetadata;
25
+ }
26
+ //# sourceMappingURL=base.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,UAAU,EACV,WAAW,EACX,aAAa,EACb,eAAe,EACf,gBAAgB,EAChB,eAAe,EACf,UAAU,EACX,MAAM,kBAAkB,CAAC;AAE1B,8BAAsB,SAAU,YAAW,WAAW;IACpD,QAAQ,CAAC,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IAC7B,QAAQ,CAAC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAC/B,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,gBAAgB,CAAC;IACjD,QAAQ,CAAC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IAClC,QAAQ,CAAC,QAAQ,CAAC,YAAY,EAAE,eAAe,EAAE,CAAC;IAElD,mEAAmE;IACnE,QAAQ,CAAC,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC;IAE1D,yEAAyE;IACzE,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IA4BpC,gEAAgE;IAChE,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,eAAe,EAAE;IAMjD,iFAAiF;IACjF,SAAS,CAAC,kBAAkB,CAAC,KAAK,EAAE,UAAU,GAAG,eAAe;IAShE,iDAAiD;IACjD,SAAS,CAAC,WAAW,CACnB,MAAM,EAAE,UAAU,EAAE,EACpB,KAAK,EAAE,UAAU,GAChB,WAAW;IAmCd,WAAW,IAAI,aAAa;CAiB7B"}
package/dist/base.js ADDED
@@ -0,0 +1,97 @@
1
+ /**
2
+ * BaseSkill — Abstract base class for all Huddle compliance skills.
3
+ *
4
+ * Provides default implementations for explain() and remediate(),
5
+ * so jurisdiction skills only need to implement validate().
6
+ */
7
+ export class BaseSkill {
8
+ /** Default explainability: build a human-readable summary from checks */
9
+ explain(result) {
10
+ const status = result.compliant ? "PASSES" : "FAILS";
11
+ const failedChecks = result.checks.filter((c) => !c.passed);
12
+ const passedChecks = result.checks.filter((c) => c.passed);
13
+ let explanation = `This transaction ${status} ${this.name} compliance (confidence: ${(result.confidence * 100).toFixed(0)}%).\n\n`;
14
+ if (failedChecks.length > 0) {
15
+ explanation += "Failed checks:\n";
16
+ for (const check of failedChecks) {
17
+ explanation += ` - ${check.name}: ${check.note}`;
18
+ if (check.citation) {
19
+ explanation += ` (${check.citation.statute} ${check.citation.section})`;
20
+ }
21
+ explanation += "\n";
22
+ }
23
+ }
24
+ if (passedChecks.length > 0) {
25
+ explanation += "\nPassed checks:\n";
26
+ for (const check of passedChecks) {
27
+ explanation += ` - ${check.name}: ${check.note}\n`;
28
+ }
29
+ }
30
+ return explanation;
31
+ }
32
+ /** Default remediation: generate steps for each failed check */
33
+ remediate(result) {
34
+ return result.checks
35
+ .filter((c) => !c.passed)
36
+ .map((check) => this.checkToRemediation(check));
37
+ }
38
+ /** Convert a failed check into a remediation step. Override for custom logic. */
39
+ checkToRemediation(check) {
40
+ return {
41
+ action: `fix_${check.name.toLowerCase().replace(/\s+/g, "_")}`,
42
+ description: `Address failed check: ${check.note}`,
43
+ urgency: "required",
44
+ automatable: false,
45
+ };
46
+ }
47
+ /** Build a SkillResult from individual checks */
48
+ buildResult(checks, input) {
49
+ const compliant = checks.every((c) => c.passed);
50
+ const confidence = checks.length > 0
51
+ ? Math.min(...checks.map((c) => c.confidence))
52
+ : 0;
53
+ const citations = checks
54
+ .filter((c) => c.citation)
55
+ .map((c) => c.citation);
56
+ const remediation = compliant ? undefined : this.remediate({
57
+ compliant,
58
+ confidence,
59
+ jurisdiction: this.jurisdiction,
60
+ skillId: this.id,
61
+ skillVersion: this.version,
62
+ checks,
63
+ timestamp: Date.now(),
64
+ citations,
65
+ });
66
+ return {
67
+ compliant,
68
+ confidence,
69
+ jurisdiction: this.jurisdiction,
70
+ skillId: this.id,
71
+ skillVersion: this.version,
72
+ checks,
73
+ explanation: undefined, // Filled by caller if needed
74
+ remediation,
75
+ citations: citations.length > 0 ? citations : undefined,
76
+ timestamp: Date.now(),
77
+ };
78
+ }
79
+ getMetadata() {
80
+ return {
81
+ id: this.id,
82
+ name: this.name,
83
+ description: `${this.name} compliance skill for ${this.jurisdiction}`,
84
+ jurisdiction: this.jurisdiction,
85
+ version: this.version,
86
+ capabilities: this.capabilities,
87
+ permissions: ["network:none", "filesystem:none"],
88
+ tags: [
89
+ "rental",
90
+ "compliance",
91
+ this.jurisdiction.toLowerCase(),
92
+ ],
93
+ author: "huddle-protocol",
94
+ };
95
+ }
96
+ }
97
+ //# sourceMappingURL=base.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base.js","sourceRoot":"","sources":["../src/base.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAaH,MAAM,OAAgB,SAAS;IAU7B,yEAAyE;IACzE,OAAO,CAAC,MAAmB;QACzB,MAAM,MAAM,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC;QACrD,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAC5D,MAAM,YAAY,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAE3D,IAAI,WAAW,GAAG,oBAAoB,MAAM,IAAI,IAAI,CAAC,IAAI,4BAA4B,CAAC,MAAM,CAAC,UAAU,GAAG,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC;QAEnI,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,WAAW,IAAI,kBAAkB,CAAC;YAClC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,WAAW,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,EAAE,CAAC;gBAClD,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;oBACnB,WAAW,IAAI,KAAK,KAAK,CAAC,QAAQ,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,GAAG,CAAC;gBAC1E,CAAC;gBACD,WAAW,IAAI,IAAI,CAAC;YACtB,CAAC;QACH,CAAC;QAED,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,WAAW,IAAI,oBAAoB,CAAC;YACpC,KAAK,MAAM,KAAK,IAAI,YAAY,EAAE,CAAC;gBACjC,WAAW,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,KAAK,CAAC,IAAI,IAAI,CAAC;YACtD,CAAC;QACH,CAAC;QAED,OAAO,WAAW,CAAC;IACrB,CAAC;IAED,gEAAgE;IAChE,SAAS,CAAC,MAAmB;QAC3B,OAAO,MAAM,CAAC,MAAM;aACjB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;aACxB,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,IAAI,CAAC,kBAAkB,CAAC,KAAK,CAAC,CAAC,CAAC;IACpD,CAAC;IAED,iFAAiF;IACvE,kBAAkB,CAAC,KAAiB;QAC5C,OAAO;YACL,MAAM,EAAE,OAAO,KAAK,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE;YAC9D,WAAW,EAAE,yBAAyB,KAAK,CAAC,IAAI,EAAE;YAClD,OAAO,EAAE,UAAU;YACnB,WAAW,EAAE,KAAK;SACnB,CAAC;IACJ,CAAC;IAED,iDAAiD;IACvC,WAAW,CACnB,MAAoB,EACpB,KAAiB;QAEjB,MAAM,SAAS,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;QAChD,MAAM,UAAU,GAAG,MAAM,CAAC,MAAM,GAAG,CAAC;YAClC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC;YAC9C,CAAC,CAAC,CAAC,CAAC;QAEN,MAAM,SAAS,GAAG,MAAM;aACrB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC;aACzB,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAS,CAAC,CAAC;QAE3B,MAAM,WAAW,GAAG,SAAS,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC;YACzD,SAAS;YACT,UAAU;YACV,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,YAAY,EAAE,IAAI,CAAC,OAAO;YAC1B,MAAM;YACN,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;YACrB,SAAS;SACV,CAAC,CAAC;QAEH,OAAO;YACL,SAAS;YACT,UAAU;YACV,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,OAAO,EAAE,IAAI,CAAC,EAAE;YAChB,YAAY,EAAE,IAAI,CAAC,OAAO;YAC1B,MAAM;YACN,WAAW,EAAE,SAAS,EAAE,6BAA6B;YACrD,WAAW;YACX,SAAS,EAAE,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS;YACvD,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE;SACtB,CAAC;IACJ,CAAC;IAED,WAAW;QACT,OAAO;YACL,EAAE,EAAE,IAAI,CAAC,EAAE;YACX,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,WAAW,EAAE,GAAG,IAAI,CAAC,IAAI,yBAAyB,IAAI,CAAC,YAAY,EAAE;YACrE,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,OAAO,EAAE,IAAI,CAAC,OAAO;YACrB,YAAY,EAAE,IAAI,CAAC,YAAY;YAC/B,WAAW,EAAE,CAAC,cAAc,EAAE,iBAAiB,CAAC;YAChD,IAAI,EAAE;gBACJ,QAAQ;gBACR,YAAY;gBACZ,IAAI,CAAC,YAAY,CAAC,WAAW,EAAE;aAChC;YACD,MAAM,EAAE,iBAAiB;SAC1B,CAAC;IACJ,CAAC;CACF"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * @huddle-marketplace/skills — Composition Engine
3
+ *
4
+ * Stack multiple jurisdiction skills for layered validation.
5
+ *
6
+ * Typical patterns:
7
+ * Federal + State: composeSkills(["US-CFTC", "US-TX"], input, registry)
8
+ * Multi-state: composeSkills(["US-CA", "US-NY"], input, registry)
9
+ * Cross-border: composeSkills(["US-CFTC", "CA-FINTRAC", "CA-ON"], input, registry)
10
+ *
11
+ * Architecture:
12
+ * - Layers run in PARALLEL (Promise.all) — O(1) latency regardless of layer count
13
+ * - Federal checks first in output by convention (pass them first in the array)
14
+ * - Each check is prefixed with its source jurisdiction for full traceability
15
+ * - Citations are deduplicated by statute+section across layers
16
+ * - compliant = ALL layers compliant (strict mode, default)
17
+ *
18
+ * Web3-native: When US-CFTC is composed with a state skill, the federal layer validates
19
+ * bond structure (wBTC reserve ratio, non-custodial architecture, TRAIGA logging).
20
+ * The state layer adds local statutory rules (deposit cap, return timeline, late fee limits).
21
+ * Together they form a complete, TRAIGA-ready compliance proof for any Huddle transaction.
22
+ */
23
+ import type { SkillInput, SkillResult, SkillCheck, LegalCitation, RemediationStep, JurisdictionCode } from "./types/index.js";
24
+ /**
25
+ * The merged result of running multiple jurisdiction skills in sequence.
26
+ * Each layer's result is preserved in `layers[]` for full TRAIGA auditability.
27
+ */
28
+ export interface ComposedResult {
29
+ /** true only when ALL jurisdiction layers are compliant (strict mode) */
30
+ compliant: boolean;
31
+ /** Minimum confidence across all layers — the weakest link determines overall confidence */
32
+ confidence: number;
33
+ /** Jurisdiction codes validated, in the order provided */
34
+ jurisdictions: string[];
35
+ /** Individual SkillResult per jurisdiction — full detail for TRAIGA logging */
36
+ layers: SkillResult[];
37
+ /** All checks from all layers, prefixed with source jurisdiction for traceability */
38
+ checks: SkillCheck[];
39
+ /** All citations merged and deduplicated by statute+section */
40
+ citations: LegalCitation[];
41
+ /** All remediation steps from all layers, consolidated */
42
+ remediation: RemediationStep[];
43
+ /** Unix timestamp (ms) when composition completed */
44
+ timestamp: number;
45
+ }
46
+ /**
47
+ * Minimal registry interface — avoids circular import from index.ts.
48
+ * The full SkillRegistry satisfies this interface automatically.
49
+ */
50
+ export interface MinimalRegistry {
51
+ get(jurisdiction: JurisdictionCode): {
52
+ validate(input: SkillInput): Promise<SkillResult>;
53
+ } | undefined;
54
+ }
55
+ export interface ComposeOptions {
56
+ /**
57
+ * "strict" (default): ALL layers must be compliant for `compliant: true`.
58
+ * Use for production validation where every layer must pass.
59
+ *
60
+ * "advisory": only layers listed in `criticalJurisdictions` affect `compliant`.
61
+ * Use when some layers are informational overlays.
62
+ */
63
+ mode?: "strict" | "advisory";
64
+ /**
65
+ * In "advisory" mode: only these jurisdictions determine `compliant`.
66
+ * Defaults to all jurisdictions when not provided (equivalent to strict mode).
67
+ */
68
+ criticalJurisdictions?: string[];
69
+ }
70
+ /**
71
+ * Compose multiple jurisdiction skills into a single layered validation result.
72
+ *
73
+ * Designed for Web3-native use: the federal CFTC layer validates the bond structure,
74
+ * the state layer validates local statutory rules — together they form a complete
75
+ * compliance proof anchored on-chain via TRAIGA.
76
+ *
77
+ * NOTE: This is the low-level function that requires an explicit registry.
78
+ * Use the `composeSkills()` export from the main package entry which uses the
79
+ * default registry automatically.
80
+ *
81
+ * @param jurisdictions - Ordered list of jurisdiction codes (federal first by convention)
82
+ * @param input - Skill input shared across all layers (amounts in CENTS)
83
+ * @param registry - Registry instance to resolve skills from
84
+ * @param options - Composition options
85
+ */
86
+ export declare function composeSkillsWithRegistry(jurisdictions: (JurisdictionCode | string)[], input: SkillInput, registry: MinimalRegistry, options?: ComposeOptions): Promise<ComposedResult>;
87
+ //# sourceMappingURL=compose.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compose.d.ts","sourceRoot":"","sources":["../src/compose.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EACV,UAAU,EACV,WAAW,EACX,UAAU,EACV,aAAa,EACb,eAAe,EACf,gBAAgB,EACjB,MAAM,kBAAkB,CAAC;AAM1B;;;GAGG;AACH,MAAM,WAAW,cAAc;IAC7B,yEAAyE;IACzE,SAAS,EAAE,OAAO,CAAC;IAEnB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,CAAC;IAEnB,0DAA0D;IAC1D,aAAa,EAAE,MAAM,EAAE,CAAC;IAExB,+EAA+E;IAC/E,MAAM,EAAE,WAAW,EAAE,CAAC;IAEtB,qFAAqF;IACrF,MAAM,EAAE,UAAU,EAAE,CAAC;IAErB,+DAA+D;IAC/D,SAAS,EAAE,aAAa,EAAE,CAAC;IAE3B,0DAA0D;IAC1D,WAAW,EAAE,eAAe,EAAE,CAAC;IAE/B,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,YAAY,EAAE,gBAAgB,GAAG;QAAE,QAAQ,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAAA;KAAE,GAAG,SAAS,CAAC;CACxG;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;;OAMG;IACH,IAAI,CAAC,EAAE,QAAQ,GAAG,UAAU,CAAC;IAE7B;;;OAGG;IACH,qBAAqB,CAAC,EAAE,MAAM,EAAE,CAAC;CAClC;AAMD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,yBAAyB,CAC7C,aAAa,EAAE,CAAC,gBAAgB,GAAG,MAAM,CAAC,EAAE,EAC5C,KAAK,EAAE,UAAU,EACjB,QAAQ,EAAE,eAAe,EACzB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,cAAc,CAAC,CAsFzB"}