anyray-connect 0.2.0 → 0.5.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.
@@ -0,0 +1,233 @@
1
+ /**
2
+ * `anyray-connect __anyray-hook` — the PostToolUse hook body.
3
+ *
4
+ * Claude Code invokes this for every tool result (configured by the Claude Code
5
+ * adapter). It reads the hook payload on stdin and, for an OVERSIZED tool
6
+ * output, asks the gateway to optimize it — the real strategies run SERVER-SIDE
7
+ * (never on the dev's machine), and the gateway records the saving so
8
+ * observability follows it natively. If the gateway is unreachable it falls
9
+ * back to a local trim (cache-safe head/tail) + a content-free beacon, so the
10
+ * dev still benefits when offline. Then it prints the replacement output.
11
+ *
12
+ * Hard rule: this runs on Claude Code's hot path, so it MUST NOT throw and MUST
13
+ * NOT block for long. Any error/malformed payload/timeout degrades to a smaller
14
+ * action (local trim) or passthrough (empty stdout + exit 0 = use the original).
15
+ *
16
+ * PRIVACY: the one tool output sent to the gateway rides the same content
17
+ * boundary the optimizer already has (processed transiently, metadata-only
18
+ * logging); the fallback beacon carries only counts. The elided content is
19
+ * never logged here.
20
+ */
21
+ import { homedir } from 'node:os';
22
+ import { join } from 'node:path';
23
+ import { readFile } from 'node:fs/promises';
24
+ import { extractToolOutputBody, trimText, DEFAULT_TRIM, } from '../util/trimOutput.js';
25
+ const OPTIMIZE_TIMEOUT_MS = 1200;
26
+ const BEACON_TIMEOUT_MS = 400;
27
+ const emit = (value) => JSON.stringify({
28
+ hookSpecificOutput: {
29
+ hookEventName: 'PostToolUse',
30
+ updatedToolOutput: value,
31
+ },
32
+ });
33
+ /** Defensive: tool result may live under any of these keys across versions. */
34
+ const OUTPUT_KEYS = ['tool_output', 'tool_response', 'tool_result'];
35
+ const pickOutput = (payload) => {
36
+ for (const k of OUTPUT_KEYS)
37
+ if (k in payload)
38
+ return payload[k];
39
+ return undefined;
40
+ };
41
+ /**
42
+ * Pure orchestration core: decide what to emit for a raw PostToolUse payload,
43
+ * delegating I/O to `deps`. Returns the exact stdout (empty = passthrough).
44
+ * Never throws.
45
+ */
46
+ export const runHook = async (raw, deps) => {
47
+ const passthrough = { stdout: '' };
48
+ if (!raw.trim())
49
+ return passthrough;
50
+ let payload;
51
+ try {
52
+ const parsed = JSON.parse(raw);
53
+ if (!parsed || typeof parsed !== 'object')
54
+ return passthrough;
55
+ payload = parsed;
56
+ }
57
+ catch {
58
+ return passthrough;
59
+ }
60
+ const found = extractToolOutputBody(pickOutput(payload));
61
+ if (!found || found.body.length <= deps.sizeGate)
62
+ return passthrough;
63
+ const tool = typeof payload.tool_name === 'string' ? payload.tool_name : 'unknown';
64
+ // PRIMARY: the service optimizes (and records the saving). If it responds, it
65
+ // decides — no local trim, no beacon.
66
+ let verdict = null;
67
+ try {
68
+ verdict = await deps.optimize(tool, payload.tool_input, found.body);
69
+ }
70
+ catch {
71
+ verdict = null; // treat any failure as unreachable → fall back
72
+ }
73
+ if (verdict) {
74
+ if (verdict.optimized && verdict.output.length < found.body.length) {
75
+ return { stdout: emit(found.rebuild(verdict.output)) };
76
+ }
77
+ return passthrough; // service ran and declined
78
+ }
79
+ // FALLBACK: service unreachable → local cache-safe trim + content-free beacon.
80
+ let local;
81
+ try {
82
+ local = deps.localTrim(found.body);
83
+ }
84
+ catch {
85
+ return passthrough;
86
+ }
87
+ if (!local.trimmed)
88
+ return passthrough;
89
+ await deps.beacon(tool, {
90
+ originalChars: local.originalChars,
91
+ trimmedChars: local.trimmedChars,
92
+ estTokensSaved: local.estTokensSaved,
93
+ });
94
+ return { stdout: emit(found.rebuild(local.text)) };
95
+ };
96
+ // ---------------------------------------------------------------------------
97
+ // Real wiring (I/O). Kept thin; the logic lives in runHook above.
98
+ // ---------------------------------------------------------------------------
99
+ const readStdin = async () => {
100
+ const chunks = [];
101
+ try {
102
+ for await (const chunk of process.stdin)
103
+ chunks.push(chunk);
104
+ }
105
+ catch {
106
+ return '';
107
+ }
108
+ return Buffer.concat(chunks).toString('utf-8');
109
+ };
110
+ const trimOptionsFromEnv = () => {
111
+ const n = (k) => {
112
+ const v = process.env[k];
113
+ if (!v)
114
+ return undefined;
115
+ const parsed = Number(v);
116
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : undefined;
117
+ };
118
+ return {
119
+ maxChars: n('ANYRAY_HOOK_MAX_CHARS'),
120
+ headChars: n('ANYRAY_HOOK_HEAD_CHARS'),
121
+ tailChars: n('ANYRAY_HOOK_TAIL_CHARS'),
122
+ };
123
+ };
124
+ /**
125
+ * Recover the gateway origin + content-free attribution from the same
126
+ * `~/.claude/settings.json` the Claude Code adapter wrote — the hook is
127
+ * self-configuring (no second config file). Best-effort.
128
+ */
129
+ const readBeaconTarget = async () => {
130
+ try {
131
+ const path = join(homedir(), '.claude', 'settings.json');
132
+ const settings = JSON.parse(await readFile(path, 'utf-8'));
133
+ const env = settings?.env;
134
+ const base = env?.ANTHROPIC_BASE_URL;
135
+ if (!base)
136
+ return null;
137
+ const origin = new URL(base).origin;
138
+ const headers = env?.ANTHROPIC_CUSTOM_HEADERS ?? '';
139
+ const header = (name) => {
140
+ for (const line of headers.split('\n')) {
141
+ const idx = line.indexOf(':');
142
+ if (idx > 0 && line.slice(0, idx).trim().toLowerCase() === name) {
143
+ return line.slice(idx + 1).trim();
144
+ }
145
+ }
146
+ return undefined;
147
+ };
148
+ return {
149
+ origin,
150
+ metadata: header('x-anyray-metadata'),
151
+ apiKey: header('x-anyray-api-key'),
152
+ };
153
+ }
154
+ catch {
155
+ return null;
156
+ }
157
+ };
158
+ const authHeaders = (target) => {
159
+ const headers = { 'content-type': 'application/json' };
160
+ if (target.metadata)
161
+ headers['x-anyray-metadata'] = target.metadata;
162
+ if (target.apiKey)
163
+ headers['x-anyray-api-key'] = target.apiKey;
164
+ return headers;
165
+ };
166
+ /** POST one tool output to the gateway for server-side optimization. */
167
+ const optimizeViaGateway = async (target, tool, toolInput, body) => {
168
+ if (!target)
169
+ return null;
170
+ const controller = new AbortController();
171
+ const timer = setTimeout(() => controller.abort(), OPTIMIZE_TIMEOUT_MS);
172
+ try {
173
+ const res = await fetch(`${target.origin}/connect/optimize-output`, {
174
+ method: 'POST',
175
+ headers: authHeaders(target),
176
+ body: JSON.stringify({ tool, toolInput, output: body }),
177
+ signal: controller.signal,
178
+ });
179
+ if (!res.ok)
180
+ return null;
181
+ const data = await res.json();
182
+ return {
183
+ optimized: data?.optimized === true && typeof data?.output === 'string',
184
+ output: typeof data?.output === 'string' ? data.output : body,
185
+ };
186
+ }
187
+ catch {
188
+ return null; // unreachable / timeout → fall back to local trim
189
+ }
190
+ finally {
191
+ clearTimeout(timer);
192
+ }
193
+ };
194
+ /** Fire-and-forget content-free beacon for the fallback (local-trim) path. */
195
+ const sendBeacon = async (target, tool, metrics) => {
196
+ if (!target)
197
+ return;
198
+ const controller = new AbortController();
199
+ const timer = setTimeout(() => controller.abort(), BEACON_TIMEOUT_MS);
200
+ try {
201
+ await fetch(`${target.origin}/connect/hook-savings`, {
202
+ method: 'POST',
203
+ headers: authHeaders(target),
204
+ body: JSON.stringify({ source: 'hook', tool, ...metrics }),
205
+ signal: controller.signal,
206
+ });
207
+ }
208
+ catch {
209
+ /* telemetry is best-effort */
210
+ }
211
+ finally {
212
+ clearTimeout(timer);
213
+ }
214
+ };
215
+ /**
216
+ * Run the PostToolUse hook. Always returns exit code 0 — the hook is advisory;
217
+ * failures must never block Claude Code.
218
+ */
219
+ export const runPostToolUseHook = async () => {
220
+ const raw = await readStdin();
221
+ const opts = trimOptionsFromEnv();
222
+ const target = await readBeaconTarget();
223
+ const { stdout } = await runHook(raw, {
224
+ optimize: (tool, toolInput, body) => optimizeViaGateway(target, tool, toolInput, body),
225
+ localTrim: (body) => trimText(body, opts),
226
+ beacon: (tool, metrics) => sendBeacon(target, tool, metrics),
227
+ sizeGate: opts.maxChars ?? DEFAULT_TRIM.maxChars,
228
+ });
229
+ if (stdout)
230
+ process.stdout.write(stdout);
231
+ return 0;
232
+ };
233
+ //# sourceMappingURL=hook.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hook.js","sourceRoot":"","sources":["../../src/commands/hook.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Shared helpers for the `anyray-connect` subcommands.
3
+ *
4
+ * The apply/wizard/status/doctor/sync commands all need the same primitives:
5
+ * interactive prompts, identity resolution, and the gateway origin resolved
6
+ * from flags → env → the ~/.anyray cache. Keeping them here lets each command
7
+ * stay small and avoids cli.ts ⇄ command circular imports.
8
+ *
9
+ * PRIVACY: nothing here logs or persists prompt/response content — only the
10
+ * gateway origin and content-free identity (user/team).
11
+ */
12
+ import { createInterface } from 'node:readline/promises';
13
+ import { resolveOrigin } from '../target.js';
14
+ import { detectDisplayName } from '../util/identity.js';
15
+ import { dim, note } from '../util/log.js';
16
+ export const isInteractive = () => Boolean(process.stdin.isTTY);
17
+ export const confirm = async (question) => {
18
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
19
+ try {
20
+ const answer = (await rl.question(`${question} ${dim('[y/N]')} `)).trim();
21
+ return /^y(es)?$/i.test(answer);
22
+ }
23
+ finally {
24
+ rl.close();
25
+ }
26
+ };
27
+ export const prompt = async (question, defaultValue) => {
28
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
29
+ try {
30
+ const hint = defaultValue ? ` ${dim(`[${defaultValue}]`)}` : '';
31
+ const raw = (await rl.question(`${question}${hint}: `)).trim();
32
+ return raw || defaultValue;
33
+ }
34
+ finally {
35
+ rl.close();
36
+ }
37
+ };
38
+ /** Explicit flag wins ('' clears the cache) → cached → detected, prompted on a TTY. */
39
+ export const resolveDisplayName = async (explicit, cached, yes) => {
40
+ if (explicit !== undefined)
41
+ return explicit.trim() || undefined;
42
+ if (cached) {
43
+ note(`Your name: ${cached} ${dim('(cached — pass --user to change)')}`);
44
+ return cached;
45
+ }
46
+ const detected = detectDisplayName();
47
+ // Without a TTY, prompting would block forever on a silent pipe — behave like --yes.
48
+ if (yes || !isInteractive()) {
49
+ note(`Your name: ${detected} ${dim('(auto-detected — pass --user to change)')}`);
50
+ return detected;
51
+ }
52
+ return prompt('? Your name', detected);
53
+ };
54
+ /** Explicit flag wins ('' clears the cache) → cached → optional prompt on a TTY. */
55
+ export const resolveTeam = async (explicit, cached, yes) => {
56
+ if (explicit !== undefined)
57
+ return explicit.trim() || undefined;
58
+ if (cached) {
59
+ note(`Team: ${cached} ${dim('(cached — pass --team to change)')}`);
60
+ return cached;
61
+ }
62
+ if (yes || !isInteractive())
63
+ return undefined;
64
+ return prompt('? Team (optional)');
65
+ };
66
+ /**
67
+ * Resolve the gateway origin a read-only command should act on: explicit flag →
68
+ * `$ANYRAY_GATEWAY_URL` → the ~/.anyray cache → the default. Validated as an
69
+ * http(s) URL (throws on a bad value).
70
+ */
71
+ export const resolveGatewayOrigin = (explicit, profile) => {
72
+ const cached = !explicit && !process.env.ANYRAY_GATEWAY_URL ? profile.gateway : undefined;
73
+ return resolveOrigin(explicit ?? cached);
74
+ };
75
+ /**
76
+ * The key a read-only request to the gateway should present, in precedence
77
+ * order: an explicit `$ANYRAY_CLIENT_KEY` override, the personal key persisted
78
+ * by a prior invite redemption (`profile.clientKey`), else the shared
79
+ * placeholder. Without the persisted key, `status`/`sync` would send the
80
+ * placeholder and 401 under key enforcement.
81
+ */
82
+ export const requestKey = (storedKey, placeholder) => process.env.ANYRAY_CLIENT_KEY?.trim() || storedKey?.trim() || placeholder;
83
+ //# sourceMappingURL=shared.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared.js","sourceRoot":"","sources":["../../src/commands/shared.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,71 @@
1
+ /**
2
+ * `anyray-connect status` — read-only snapshot of the current setup.
3
+ *
4
+ * Prints which tools are pointed at Anyray (via each adapter's `pointsAt` /
5
+ * `detect`), the active gateway origin, the cached name/team from ~/.anyray, and
6
+ * the dev's content-free savings so far. Writes nothing.
7
+ *
8
+ * PRIVACY: reads metadata only (gateway origin, cached identity, content-free
9
+ * savings aggregates) — never prompt/response content.
10
+ */
11
+ import { REGISTRY } from '../tools/index.js';
12
+ import { loadProfile } from '../util/persist.js';
13
+ import { resolveGatewayOrigin, requestKey } from './shared.js';
14
+ import { fetchSavings, formatSavingsLine } from '../util/savings.js';
15
+ import { bold, cyan, dim, heading, info, note, ok } from '../util/log.js';
16
+ export const runStatus = async (args) => {
17
+ const profile = await loadProfile();
18
+ let origin;
19
+ try {
20
+ origin = resolveGatewayOrigin(args.gateway, profile);
21
+ }
22
+ catch (error) {
23
+ info(bold('Anyray connect — status'));
24
+ note(`Gateway: ${error.message}`);
25
+ return 0;
26
+ }
27
+ info(bold('Anyray connect — status'));
28
+ heading('Gateway');
29
+ info(` Origin: ${cyan(origin)}`);
30
+ if (profile.gateway) {
31
+ note(` (cached in ~/.anyray)`);
32
+ }
33
+ else if (process.env.ANYRAY_GATEWAY_URL) {
34
+ note(` (from $ANYRAY_GATEWAY_URL)`);
35
+ }
36
+ else if (!args.gateway) {
37
+ note(` (default — not yet connected; run \`anyray-connect\` to set up)`);
38
+ }
39
+ heading('Identity');
40
+ info(` Name: ${profile.name ?? dim('(not set)')}`);
41
+ info(` Team: ${profile.team ?? dim('(not set)')}`);
42
+ heading('Tools');
43
+ for (const adapter of REGISTRY) {
44
+ const detected = await adapter.detect();
45
+ if (!detected.installed) {
46
+ note(` ${adapter.title}: not installed`);
47
+ continue;
48
+ }
49
+ if (!adapter.pointsAt) {
50
+ note(` ${adapter.title}: installed ${dim('(status not introspectable)')}`);
51
+ continue;
52
+ }
53
+ const pointed = await adapter.pointsAt(origin);
54
+ if (pointed) {
55
+ ok(` ${adapter.title}: pointed at Anyray`);
56
+ }
57
+ else {
58
+ note(` ${adapter.title}: installed, not pointed at this gateway`);
59
+ }
60
+ }
61
+ // Savings: best-effort. An older gateway (404) or a network hiccup just omits
62
+ // the line — status must never fail because the endpoint is missing.
63
+ const key = requestKey(profile.clientKey, 'anyray-placeholder');
64
+ const savings = await fetchSavings(origin, key);
65
+ if (savings) {
66
+ heading('Savings');
67
+ info(` ${formatSavingsLine(savings)}`);
68
+ }
69
+ return 0;
70
+ };
71
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.js","sourceRoot":"","sources":["../../src/commands/status.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,87 @@
1
+ /**
2
+ * `anyray-connect sync` — pull the team's shared skills/instructions from the
3
+ * gateway and write them as `SKILL.md` files into each supported tool's skills
4
+ * directory. Only files whose version changed are rewritten; the per-skill
5
+ * version baseline lives in ~/.anyray.
6
+ *
7
+ * PRIVACY: skill bodies are content-free TEAM POLICY text (instructions), not
8
+ * user prompts — persisting them is intended. Nothing here logs prompt/response
9
+ * content, and ~/.anyray keeps only ids + version strings, never bodies.
10
+ */
11
+ import { REGISTRY } from '../tools/index.js';
12
+ import { loadProfile, saveProfile } from '../util/persist.js';
13
+ import { fetchTeamPolicy, syncPolicyToDirs } from '../util/policySync.js';
14
+ import { resolveGatewayOrigin, requestKey } from './shared.js';
15
+ import { bold, cyan, dim, fail, heading, info, note, ok } from '../util/log.js';
16
+ /** Skills dirs of every adapter that models one (e.g. Claude Code). */
17
+ const collectSkillsDirs = () => {
18
+ const dirs = [];
19
+ for (const adapter of REGISTRY) {
20
+ const dir = adapter.skillsDir?.();
21
+ if (dir)
22
+ dirs.push(dir);
23
+ }
24
+ return dirs;
25
+ };
26
+ export const runSync = async (args) => {
27
+ const profile = await loadProfile();
28
+ info(bold('Anyray connect — sync'));
29
+ let origin;
30
+ try {
31
+ origin = resolveGatewayOrigin(args.gateway, profile);
32
+ }
33
+ catch (error) {
34
+ fail(error.message);
35
+ return 1;
36
+ }
37
+ note(`Gateway: ${origin}`);
38
+ const skillsDirs = collectSkillsDirs();
39
+ if (skillsDirs.length === 0) {
40
+ warnNoDirs();
41
+ return 0;
42
+ }
43
+ const key = requestKey(profile.clientKey, 'anyray-placeholder');
44
+ let policy;
45
+ try {
46
+ policy = await fetchTeamPolicy(origin, key);
47
+ }
48
+ catch (error) {
49
+ // Graceful: a non-200/network error prints the reason and exits non-zero,
50
+ // but never crashes.
51
+ fail(error.message);
52
+ return 1;
53
+ }
54
+ if (policy.skills.length === 0) {
55
+ note('No team skills published yet — nothing to sync.');
56
+ return 0;
57
+ }
58
+ const summary = await syncPolicyToDirs(policy, skillsDirs, profile.syncedSkills ?? {});
59
+ heading('Skills');
60
+ for (const result of summary.results) {
61
+ if (result.written) {
62
+ ok(` ${result.name} ${dim(`(${result.id}@${result.version})`)} → ${result.files.length} file(s)`);
63
+ }
64
+ else {
65
+ note(` ${result.name} ${dim(`(${result.id}@${result.version})`)} — up to date`);
66
+ }
67
+ }
68
+ // Persist the new version baseline (preserving the rest of the profile) so
69
+ // the next sync only rewrites what changed.
70
+ try {
71
+ await saveProfile({
72
+ ...profile,
73
+ syncedSkills: summary.versions,
74
+ syncedAt: summary.updatedAt ?? new Date().toISOString(),
75
+ });
76
+ }
77
+ catch (error) {
78
+ note(`Could not record sync state: ${error instanceof Error ? error.message : String(error)}`);
79
+ }
80
+ heading('Summary');
81
+ info(` ${cyan(String(summary.changed))} updated, ${summary.unchanged} unchanged, across ${skillsDirs.length} tool dir(s).`);
82
+ return 0;
83
+ };
84
+ const warnNoDirs = () => {
85
+ note('No installed tool exposes a skills directory — nothing to sync.');
86
+ };
87
+ //# sourceMappingURL=sync.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sync.js","sourceRoot":"","sources":["../../src/commands/sync.ts"],"names":[],"mappings":"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"}
package/dist/target.js CHANGED
@@ -43,13 +43,23 @@ export const resolveTarget = (input = {}) => {
43
43
  intentLabel: pick(input.intentLabel, 'ANYRAY_METADATA_INTENT_LABEL'),
44
44
  session: pick(input.session, 'ANYRAY_METADATA_SESSION'),
45
45
  };
46
+ // Forced modes win; otherwise detected seats select `auto`; otherwise the
47
+ // legacy placeholder default (e.g. direct callers that pass no seat state).
48
+ const authMode = input.subscription
49
+ ? 'subscription'
50
+ : input.placeholder
51
+ ? 'placeholder'
52
+ : input.seat
53
+ ? 'auto'
54
+ : 'placeholder';
46
55
  return {
47
56
  origin,
48
57
  anthropicBaseUrl: origin,
49
58
  openaiBaseUrl: `${origin}/v1`,
50
59
  placeholderKey,
51
60
  clientKey,
52
- authMode: input.subscription ? 'subscription' : 'placeholder',
61
+ authMode,
62
+ seat: authMode === 'auto' ? input.seat : undefined,
53
63
  metadata,
54
64
  };
55
65
  };
@@ -1 +1 @@
1
- {"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAIH,MAAM,cAAc,GAAG,uBAAuB,CAAC;AAC/C,MAAM,uBAAuB,GAAG,oBAAoB,CAAC;AAErD,+EAA+E;AAC/E,MAAM,CAAC,MAAM,eAAe,GAAG,CAAC,GAAW,EAAU,EAAE;IACrD,IAAI,MAAM,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC5C,MAAM,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IACrC,OAAO,MAAM,CAAC;AAChB,CAAC,CAAC;AAeF,iFAAiF;AACjF,MAAM,IAAI,GAAG,CAAC,IAAwB,EAAE,MAAc,EAAsB,EAAE,CAC5E,IAAI,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;AAE3D,sFAAsF;AACtF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,MAAe,EAAU,EAAE;IACvD,MAAM,QAAQ,GAAG,eAAe,CAC9B,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,cAAc,CAC3D,CAAC;IACF,IAAI,MAAW,CAAC;IAChB,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,yCAAyC,CAC3E,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,OAAO,IAAI,MAAM,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAChE,MAAM,IAAI,KAAK,CACb,yBAAyB,QAAQ,yCAAyC,CAC3E,CAAC;IACJ,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,QAAqB,EAAE,EAAiB,EAAE;IACtE,MAAM,MAAM,GAAG,aAAa,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,MAAM,cAAc,GAClB,KAAK,CAAC,cAAc,EAAE,IAAI,EAAE,IAAI,uBAAuB,CAAC;IAC1D,MAAM,SAAS,GACb,KAAK,CAAC,SAAS,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,EAAE,IAAI,EAAE,IAAI,SAAS,CAAC;IAEhF,MAAM,QAAQ,GAAwB;QACpC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;QACrC,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,SAAS;QACrC,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,wBAAwB,CAAC;QACpD,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,WAAW,EAAE,8BAA8B,CAAC;QACpE,OAAO,EAAE,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,yBAAyB,CAAC;KACxD,CAAC;IAEF,OAAO;QACL,MAAM;QACN,gBAAgB,EAAE,MAAM;QACxB,aAAa,EAAE,GAAG,MAAM,KAAK;QAC7B,cAAc;QACd,SAAS;QACT,QAAQ,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAC,cAAc,CAAC,CAAC,CAAC,aAAa;QAC7D,QAAQ;KACT,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"target.js","sourceRoot":"","sources":["../src/target.ts"],"names":[],"mappings":"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"}