@rudra-js/core 0.5.0 → 0.7.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/README.md +64 -16
- package/dist/claim-screening.d.ts +10 -0
- package/dist/claim-screening.d.ts.map +1 -0
- package/dist/claim-screening.js +157 -0
- package/dist/claim-screening.js.map +1 -0
- package/dist/component-generator.d.ts +0 -70
- package/dist/component-generator.d.ts.map +1 -1
- package/dist/component-generator.js +27 -135
- package/dist/component-generator.js.map +1 -1
- package/dist/component-spec.d.ts +4 -159
- package/dist/component-spec.d.ts.map +1 -1
- package/dist/component-spec.js +0 -92
- package/dist/component-spec.js.map +1 -1
- package/dist/fallback-component.d.ts +0 -6
- package/dist/fallback-component.d.ts.map +1 -1
- package/dist/fallback-component.js +0 -21
- package/dist/fallback-component.js.map +1 -1
- package/dist/fit-to-shopper.d.ts +5 -1
- package/dist/fit-to-shopper.d.ts.map +1 -1
- package/dist/fit-to-shopper.js +5 -14
- package/dist/fit-to-shopper.js.map +1 -1
- package/dist/index.d.ts +1 -8
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -7
- package/dist/index.js.map +1 -1
- package/dist/model-prompt.d.ts +1 -30
- package/dist/model-prompt.d.ts.map +1 -1
- package/dist/model-prompt.js +19 -78
- package/dist/model-prompt.js.map +1 -1
- package/dist/product-selection.d.ts +0 -29
- package/dist/product-selection.d.ts.map +1 -1
- package/dist/product-selection.js +1 -22
- package/dist/product-selection.js.map +1 -1
- package/dist/provider.d.ts +0 -55
- package/dist/provider.d.ts.map +1 -1
- package/dist/provider.js +0 -12
- package/dist/provider.js.map +1 -1
- package/dist/reconciliation.d.ts +6 -61
- package/dist/reconciliation.d.ts.map +1 -1
- package/dist/reconciliation.js +76 -466
- package/dist/reconciliation.js.map +1 -1
- package/dist/signal-digest.d.ts +1 -18
- package/dist/signal-digest.d.ts.map +1 -1
- package/dist/signal-digest.js +27 -66
- package/dist/signal-digest.js.map +1 -1
- package/dist/spec-cache.d.ts +8 -70
- package/dist/spec-cache.d.ts.map +1 -1
- package/dist/spec-cache.js +5 -68
- package/dist/spec-cache.js.map +1 -1
- package/dist/tracking-input.d.ts +0 -49
- package/dist/tracking-input.d.ts.map +1 -1
- package/dist/tracking-input.js +5 -105
- package/dist/tracking-input.js.map +1 -1
- package/package.json +7 -6
- package/src/claim-screening.ts +190 -0
- package/src/component-generator.ts +45 -240
- package/src/component-spec.ts +17 -118
- package/src/fallback-component.ts +0 -22
- package/src/fit-to-shopper.ts +12 -16
- package/src/index.ts +1 -8
- package/src/model-prompt.ts +25 -84
- package/src/product-selection.ts +6 -52
- package/src/provider.ts +4 -60
- package/src/reconciliation.ts +104 -499
- package/src/signal-digest.ts +34 -83
- package/src/spec-cache.ts +10 -97
- package/src/tracking-input.ts +17 -111
|
@@ -1,20 +1,12 @@
|
|
|
1
1
|
import { neverRecommend } from './reconciliation.js';
|
|
2
|
-
/**
|
|
3
|
-
* How much each factor moves a product up the list. Relative sizes are what
|
|
4
|
-
* matter: category affinity dominates, a revisit is nearly as strong, and
|
|
5
|
-
* rating only separates products the signals cannot.
|
|
6
|
-
*/
|
|
7
2
|
const SCORE_WEIGHTS = {
|
|
8
3
|
category: 3,
|
|
9
4
|
revisit: 1.5,
|
|
10
5
|
rating: 1.2,
|
|
11
6
|
tagOverlap: 0.6,
|
|
12
7
|
};
|
|
13
|
-
/** Beyond this many shared tags, more overlap says nothing new. */
|
|
14
8
|
const MAX_TAG_OVERLAP = 3;
|
|
15
|
-
/** Assumed rating for a product the catalog does not rate. */
|
|
16
9
|
const UNRATED = 3.5;
|
|
17
|
-
/** Tags on the products this shopper has actually engaged with. */
|
|
18
10
|
function engagedTags(input, digest) {
|
|
19
11
|
const engagedSkus = new Set([
|
|
20
12
|
...digest.likedSkus,
|
|
@@ -31,15 +23,6 @@ function engagedTags(input, digest) {
|
|
|
31
23
|
}
|
|
32
24
|
return tags;
|
|
33
25
|
}
|
|
34
|
-
/**
|
|
35
|
-
* States why a product was picked, choosing the most specific claim the signals
|
|
36
|
-
* actually support.
|
|
37
|
-
*
|
|
38
|
-
* Every branch has to be one reconciliation can verify — the selector is held to
|
|
39
|
-
* the same standard as the model, and a basis it cannot support would be
|
|
40
|
-
* downgraded there just the same. `popular` asserts nothing and is the honest
|
|
41
|
-
* answer when nothing else holds.
|
|
42
|
-
*/
|
|
43
26
|
function basisFor(product, digest, evidence) {
|
|
44
27
|
if (evidence.revisitScore > 0) {
|
|
45
28
|
return { basis: 'most_viewed', reason: 'You looked at this recently' };
|
|
@@ -57,11 +40,9 @@ function basisFor(product, digest, evidence) {
|
|
|
57
40
|
}
|
|
58
41
|
export function selectProducts(input, digest, options = {}) {
|
|
59
42
|
const affinityByCategory = new Map(digest.categoryAffinity.map((affinity) => [affinity.category, affinity.score]));
|
|
60
|
-
// Normalised against the strongest affinity so the weights below mean the
|
|
61
|
-
// same thing whether a shopper has two signals or two hundred.
|
|
62
43
|
const strongestAffinity = Math.max(1, ...affinityByCategory.values());
|
|
63
44
|
const tags = engagedTags(input, digest);
|
|
64
|
-
const excluded = neverRecommend(
|
|
45
|
+
const excluded = neverRecommend(input);
|
|
65
46
|
const viewsBySku = new Map(digest.topViewed.map((viewed) => [viewed.sku, viewed.views]));
|
|
66
47
|
const picks = [];
|
|
67
48
|
for (const product of input.candidates) {
|
|
@@ -72,8 +53,6 @@ export function selectProducts(input, digest, options = {}) {
|
|
|
72
53
|
const categoryScore = (affinityByCategory.get(product.category) ?? 0) / strongestAffinity;
|
|
73
54
|
const tagOverlap = product.tags.filter((tag) => tags.has(tag)).length;
|
|
74
55
|
const ratingScore = (product.rating ?? UNRATED) / 5;
|
|
75
|
-
// Something viewed and not bought is a strong re-surface signal, but it
|
|
76
|
-
// saturates: the twentieth view means little more than the fifth.
|
|
77
56
|
const revisitScore = Math.min(1, Math.log2(1 + (viewsBySku.get(product.sku) ?? 0)) / 3);
|
|
78
57
|
const score = categoryScore * SCORE_WEIGHTS.category +
|
|
79
58
|
revisitScore * SCORE_WEIGHTS.revisit +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"product-selection.js","sourceRoot":"","sources":["../src/product-selection.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"product-selection.js","sourceRoot":"","sources":["../src/product-selection.ts"],"names":[],"mappings":"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"}
|
package/dist/provider.d.ts
CHANGED
|
@@ -1,14 +1,5 @@
|
|
|
1
1
|
import type { z } from 'zod';
|
|
2
2
|
import type { GeneratedSpec } from './component-spec.js';
|
|
3
|
-
/**
|
|
4
|
-
* The language-model port.
|
|
5
|
-
*
|
|
6
|
-
* `@rudra-js/core` depends on no vendor SDK. Adapters live in their own packages,
|
|
7
|
-
* so a host installs exactly one and the rest never reach its dependency tree.
|
|
8
|
-
* Anything satisfying this interface works — a hosted API, a self-hosted model,
|
|
9
|
-
* an in-tenancy deployment, or a recorded fixture.
|
|
10
|
-
*/
|
|
11
|
-
/** Reported by an adapter for cost accounting. Never used for control flow. */
|
|
12
3
|
export interface TokenUsage {
|
|
13
4
|
inputTokens?: number;
|
|
14
5
|
outputTokens?: number;
|
|
@@ -16,65 +7,19 @@ export interface TokenUsage {
|
|
|
16
7
|
cacheWriteTokens?: number;
|
|
17
8
|
}
|
|
18
9
|
export interface ProviderRequest {
|
|
19
|
-
/**
|
|
20
|
-
* Stable across every request in a deployment. Adapters that support prompt
|
|
21
|
-
* caching should mark this as the cached prefix; interpolating anything
|
|
22
|
-
* per-shopper into it would silently destroy the cache hit rate.
|
|
23
|
-
*/
|
|
24
10
|
system: string;
|
|
25
|
-
/** Per-request content. Must not be merged into the cached prefix. */
|
|
26
11
|
user: string;
|
|
27
|
-
/**
|
|
28
|
-
* The schema the response must satisfy. Adapters convert it with their own
|
|
29
|
-
* SDK helper, so there is no hand-maintained JSON Schema to drift out of
|
|
30
|
-
* sync with the one `component-spec` defines.
|
|
31
|
-
*/
|
|
32
12
|
schema: z.ZodType<GeneratedSpec>;
|
|
33
|
-
/** Fires when the caller's budget elapses. An adapter must stop work. */
|
|
34
13
|
signal: AbortSignal;
|
|
35
14
|
}
|
|
36
15
|
export interface ProviderResult {
|
|
37
16
|
spec: GeneratedSpec;
|
|
38
17
|
usage?: TokenUsage;
|
|
39
18
|
}
|
|
40
|
-
/**
|
|
41
|
-
* What an adapter promises.
|
|
42
|
-
*
|
|
43
|
-
* Three obligations, none of which the caller can verify from the outside, so
|
|
44
|
-
* they are stated here rather than assumed:
|
|
45
|
-
*
|
|
46
|
-
* 1. Return a parsed object, not a string. Turning model output into a
|
|
47
|
-
* `GeneratedSpec` is the adapter's job, because only it knows what its
|
|
48
|
-
* structured-output mode returns.
|
|
49
|
-
* 2. Throw on failure — a refusal, a transport error, an unparseable
|
|
50
|
-
* response. Never return a partial or invented spec. The caller treats a
|
|
51
|
-
* throw as "use the deterministic component", which is always safe; a
|
|
52
|
-
* fabricated spec is not.
|
|
53
|
-
* 3. Respect `signal`, in both directions: do not start work when it is
|
|
54
|
-
* already aborted, and stop when it aborts mid-flight. The caller races
|
|
55
|
-
* the call against its own timeout regardless, so ignoring it does not
|
|
56
|
-
* hold a page open — but it does leave work running and billing after
|
|
57
|
-
* nobody is waiting, and it answers a caller that has already given up.
|
|
58
|
-
*
|
|
59
|
-
* `AbortSignal.throwIfAborted()` is the whole of the first half.
|
|
60
|
-
*
|
|
61
|
-
* The caller re-validates whatever comes back. An adapter that returns
|
|
62
|
-
* something malformed is a bug, not a security hole.
|
|
63
|
-
*/
|
|
64
19
|
export interface ComponentProvider {
|
|
65
|
-
/** Short identifier recorded on every generated spec, e.g. 'anthropic'. */
|
|
66
20
|
readonly name: string;
|
|
67
|
-
/** Concrete model identifier, e.g. 'claude-opus-5'. */
|
|
68
21
|
readonly model: string;
|
|
69
22
|
generate(request: ProviderRequest): Promise<ProviderResult>;
|
|
70
23
|
}
|
|
71
|
-
/**
|
|
72
|
-
* A provider that returns a fixed spec and never touches the network.
|
|
73
|
-
*
|
|
74
|
-
* This is the benchmark's control: it isolates the cost of the framework from
|
|
75
|
-
* the latency of a model, which is the only way to report what server-side
|
|
76
|
-
* rendering itself costs. It is also what the generator's tests run against,
|
|
77
|
-
* since a test that needs an API key is a test nobody runs.
|
|
78
|
-
*/
|
|
79
24
|
export declare function createFixedSpecProvider(spec: GeneratedSpec): ComponentProvider;
|
|
80
25
|
//# sourceMappingURL=provider.d.ts.map
|
package/dist/provider.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD
|
|
1
|
+
{"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAC7B,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD,MAAM,WAAW,UAAU;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC;IAEf,IAAI,EAAE,MAAM,CAAC;IAEb,MAAM,EAAE,CAAC,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;IAEjC,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,aAAa,CAAC;IACpB,KAAK,CAAC,EAAE,UAAU,CAAC;CACpB;AAED,MAAM,WAAW,iBAAiB;IAChC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,QAAQ,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,cAAc,CAAC,CAAC;CAC7D;AAED,wBAAgB,uBAAuB,CAAC,IAAI,EAAE,aAAa,GAAG,iBAAiB,CAS9E"}
|
package/dist/provider.js
CHANGED
|
@@ -1,20 +1,8 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* A provider that returns a fixed spec and never touches the network.
|
|
3
|
-
*
|
|
4
|
-
* This is the benchmark's control: it isolates the cost of the framework from
|
|
5
|
-
* the latency of a model, which is the only way to report what server-side
|
|
6
|
-
* rendering itself costs. It is also what the generator's tests run against,
|
|
7
|
-
* since a test that needs an API key is a test nobody runs.
|
|
8
|
-
*/
|
|
9
1
|
export function createFixedSpecProvider(spec) {
|
|
10
2
|
return {
|
|
11
3
|
name: 'fixed',
|
|
12
4
|
model: 'none',
|
|
13
5
|
generate: async ({ signal }) => {
|
|
14
|
-
// Nothing here is slow enough to need cancelling, which is exactly why it
|
|
15
|
-
// is worth checking: the obligation is not "cancel your work", it is "do
|
|
16
|
-
// not answer a caller that has already given up". A reference
|
|
17
|
-
// implementation that skips the cheap half teaches the wrong lesson.
|
|
18
6
|
signal.throwIfAborted();
|
|
19
7
|
return { spec };
|
|
20
8
|
},
|
package/dist/provider.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"provider.js","sourceRoot":"","sources":["../src/provider.ts"],"names":[],"mappings":"AAgCA,MAAM,UAAU,uBAAuB,CAAC,IAAmB;IACzD,OAAO;QACL,IAAI,EAAE,OAAO;QACb,KAAK,EAAE,MAAM;QACb,QAAQ,EAAE,KAAK,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE;YAC7B,MAAM,CAAC,cAAc,EAAE,CAAC;YACxB,OAAO,EAAE,IAAI,EAAE,CAAC;QAClB,CAAC;KACF,CAAC;AACJ,CAAC"}
|
package/dist/reconciliation.d.ts
CHANGED
|
@@ -1,70 +1,15 @@
|
|
|
1
1
|
import type { Block, GeneratedSpec } from './component-spec.js';
|
|
2
|
-
import type
|
|
3
|
-
import type { Bundle,
|
|
4
|
-
/**
|
|
5
|
-
* More than this and the component stops being a component.
|
|
6
|
-
*
|
|
7
|
-
* Exported because the fill pass has to read the same blocks this module will:
|
|
8
|
-
* one past the cap never renders, so nothing is worth reserving for it.
|
|
9
|
-
*/
|
|
2
|
+
import { type SignalDigest } from './signal-digest.js';
|
|
3
|
+
import type { Bundle, TrackingInput } from './tracking-input.js';
|
|
10
4
|
export declare const MAX_BLOCKS = 4;
|
|
5
|
+
export declare function capBlocks(blocks: Block[]): Block[];
|
|
11
6
|
export interface ReconcileResult {
|
|
12
7
|
spec: GeneratedSpec;
|
|
13
|
-
/** True when something survived that is worth rendering. */
|
|
14
8
|
isUsable: boolean;
|
|
15
|
-
/** Machine-readable notes on what was removed or changed, for evaluation. */
|
|
16
9
|
violations: string[];
|
|
17
10
|
}
|
|
18
|
-
|
|
19
|
-
* SKUs that must never be recommended, whatever chose them.
|
|
20
|
-
*
|
|
21
|
-
* Exported because the deterministic selector applies the same rule when it
|
|
22
|
-
* picks. Two copies of "never recommend these" would drift, and the pair that
|
|
23
|
-
* drifted would be the model path and the fallback path — the two whose
|
|
24
|
-
* comparability the whole evaluation depends on.
|
|
25
|
-
*/
|
|
26
|
-
export declare function neverRecommend(digest: SignalDigest): Set<string>;
|
|
27
|
-
/**
|
|
28
|
-
* Wording attested bans that this project has already ruled is not a claim. An allowance
|
|
29
|
-
* forgives a banned phrase sitting inside it, so an entry ending on a preposition — "extra
|
|
30
|
-
* clearance for" — forgives whatever follows it. Exported so a test can hold the list
|
|
31
|
-
* against attested's own.
|
|
32
|
-
*/
|
|
33
|
-
export declare const ALLOWED_PHRASES: string[];
|
|
34
|
-
/**
|
|
35
|
-
* The numbers the shop published about one product: its category and tags, only the strings
|
|
36
|
-
* carrying a digit. Exported so a test can pin what never reaches attested.
|
|
37
|
-
*/
|
|
38
|
-
export declare function productFacts(product: Product): string[];
|
|
39
|
-
/**
|
|
40
|
-
* The set this shopper should get, decided before anything is placed.
|
|
41
|
-
*
|
|
42
|
-
* The generator needs the answer early, so it can keep the set's products out
|
|
43
|
-
* of the grid and keep room for them. `chooseBundle` stays private: this hands
|
|
44
|
-
* out the choice, not the machinery behind it.
|
|
45
|
-
*
|
|
46
|
-
* `spokenFor` is what the blocks above the bundle block will have placed by the
|
|
47
|
-
* time it is reached. Placing it here first is what makes the two choices agree:
|
|
48
|
-
* a set is only pre-chosen if reconciliation could still reach for it.
|
|
49
|
-
*/
|
|
11
|
+
export declare function neverRecommend(input: TrackingInput): Set<string>;
|
|
50
12
|
export declare function bundleForShopper(input: TrackingInput, digest: SignalDigest, spokenFor: readonly string[]): Bundle | undefined;
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
*
|
|
54
|
-
* A hero keeps the product the model named — its headline was written about
|
|
55
|
-
* that product — so it spends a slot of the item budget the grid cannot have.
|
|
56
|
-
* One this shopper cannot see is dropped below and spends nothing, so it is not
|
|
57
|
-
* counted here either.
|
|
58
|
-
*/
|
|
59
|
-
export declare function placeableHeroSkus(blocks: readonly Block[], input: TrackingInput, digest: SignalDigest): string[];
|
|
60
|
-
export declare function reconcileSpec(generated: GeneratedSpec, input: TrackingInput, digest: SignalDigest,
|
|
61
|
-
/**
|
|
62
|
-
* The reason this request wrote itself, by SKU: the host's own `reason` on a
|
|
63
|
-
* candidate, or the sentence the selector wrote when there was none. Neither is the
|
|
64
|
-
* model's words, and the deterministic component renders the same sentence unscreened.
|
|
65
|
-
*
|
|
66
|
-
* Only `fitToShopper` fills it, so in `per-shopper` mode it is empty and every
|
|
67
|
-
* reason is the model's, including one that happens to read the same.
|
|
68
|
-
*/
|
|
69
|
-
ourReasons?: ReadonlyMap<string, string>): ReconcileResult;
|
|
13
|
+
export declare function placeableHeroSkus(blocks: readonly Block[], input: TrackingInput): string[];
|
|
14
|
+
export declare function reconcileSpec(generated: GeneratedSpec, input: TrackingInput, digest: SignalDigest, ourReasons?: ReadonlyMap<string, string>): ReconcileResult;
|
|
70
15
|
//# sourceMappingURL=reconciliation.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciliation.d.ts","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,KAAK,
|
|
1
|
+
{"version":3,"file":"reconciliation.d.ts","sourceRoot":"","sources":["../src/reconciliation.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EACV,KAAK,EACL,aAAa,EAGd,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAqB,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAC1E,OAAO,KAAK,EAAE,MAAM,EAAW,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAgB1E,eAAO,MAAM,UAAU,IAAI,CAAC;AAE5B,wBAAgB,SAAS,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,KAAK,EAAE,CAElD;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,aAAa,CAAC;IAEpB,QAAQ,EAAE,OAAO,CAAC;IAElB,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AA2BD,wBAAgB,cAAc,CAAC,KAAK,EAAE,aAAa,GAAG,GAAG,CAAC,MAAM,CAAC,CAShE;AA0OD,wBAAgB,gBAAgB,CAC9B,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,YAAY,EACpB,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,MAAM,GAAG,SAAS,CAQpB;AAED,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,SAAS,KAAK,EAAE,EAAE,KAAK,EAAE,aAAa,GAAG,MAAM,EAAE,CAa1F;AA8ID,wBAAgB,aAAa,CAC3B,SAAS,EAAE,aAAa,EACxB,KAAK,EAAE,aAAa,EACpB,MAAM,EAAE,YAAY,EAEpB,UAAU,GAAE,WAAW,CAAC,MAAM,EAAE,MAAM,CAAa,GAClD,eAAe,CAsCjB"}
|