@cratylus/canon 0.12.2 → 0.12.3
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/guard-shell.d.ts +43 -0
- package/dist/guard-shell.js +85 -0
- package/dist/guard-shell.js.map +1 -0
- package/dist/hooks/purview-guardrail.js +63 -175
- package/dist/hooks/purview-guardrail.js.map +1 -1
- package/dist/hooks/stance-guardrail-pre.js +46 -146
- package/dist/hooks/stance-guardrail-pre.js.map +1 -1
- package/dist/hooks/stance-guardrail.d.ts +0 -2
- package/dist/hooks/stance-guardrail.js +90 -612
- package/dist/hooks/stance-guardrail.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,31 +1,15 @@
|
|
|
1
1
|
import { anchorOf } from '@cratylus/schema';
|
|
2
2
|
import { handoff } from '../dimensions/autonomy/handoff.js';
|
|
3
|
-
import {
|
|
4
|
-
// stance-guardrail-pre — the
|
|
5
|
-
//
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
//
|
|
10
|
-
// Neither act fires turn-end, so the Stop guard is blind to them (the closed blind spot).
|
|
11
|
-
// It SHARES the deployed judge backend + rubric of the sibling `stance-guardrail` hook
|
|
12
|
-
// (one rubric, one judge — no duplication); only this worker is new.
|
|
13
|
-
//
|
|
14
|
-
// IT BINDS TWO ACTS, NOT ONE EVENT PLUS A REGEX. This cell used to read
|
|
15
|
-
// `events: ['tool.use.pre']` + `matcher: 'AskUserQuestion|Agent|SendMessage'` — three
|
|
16
|
-
// claude tool names on a harness-agnostic shape, which an adapter that could not
|
|
17
|
-
// narrow by tool name dropped without a word, so the hook there fired on EVERY tool
|
|
18
|
-
// call and only the worker's own `*) allow ;;` branch kept it correct. The two acts
|
|
19
|
-
// below were already latent in the residue (`permission-menu` · `dispatch-echo`);
|
|
20
|
-
// naming them moves the narrowing to the adapter, which alone knows which of its
|
|
21
|
-
// tools performs the act. Each adapter computes its own ⟨native event, native
|
|
22
|
-
// selector⟩ pair, and one that can fire an act but not narrow it now SAYS SO through
|
|
23
|
-
// the projection's warnings.
|
|
24
|
-
// `test/hook-rule-boundary.test.ts` byte-locks the worker;
|
|
25
|
-
// `test/hook-act-selector.test.ts` holds the seam.
|
|
3
|
+
import { contestShell, judgeClipShell } from '../guard-shell.js';
|
|
4
|
+
// stance-guardrail-pre — the before-the-call twin of `stance-guardrail`. It denies a mid-turn
|
|
5
|
+
// call that collapses out of the intent-driven-expert stance, and binds the two acts that
|
|
6
|
+
// never fire the turn end: operator.consult.pre (a menu on an in-remit reversible call) and
|
|
7
|
+
// subagent.dispatch.pre (a dispatch that transcribes literal words). It shares the judge
|
|
8
|
+
// backend and rubric of the sibling cell. `test/hook-rule-boundary.test.ts` byte-locks the
|
|
9
|
+
// worker; `test/hook-act-selector.test.ts` holds the act selectors.
|
|
26
10
|
export const stanceGuardrailPre = {
|
|
27
11
|
id: 'stance-guardrail-pre',
|
|
28
|
-
residue: 'structural-refusal ↾ mid-turn tool-call · deny-before-fire ⟨intent-driven-expert-collapse⟩ ⟨permission-menu · dispatch-echo ⟨literal-transcription ∄ extracted-intent⟩⟩ · pass ⟨reserved · irreversible-outward-consent · substantive-dispatch · intent-ambiguity ↦ elicit⟩ · shared judge-backend ⟨sibling⟩ · refusal-
|
|
12
|
+
residue: 'structural-refusal ↾ mid-turn tool-call · deny-before-fire ⟨intent-driven-expert-collapse⟩ ⟨permission-menu · dispatch-echo ⟨literal-transcription ∄ extracted-intent⟩⟩ · pass ⟨reserved · irreversible-outward-consent · substantive-dispatch · intent-ambiguity ↦ elicit⟩ · shared judge-backend ⟨sibling⟩ · refusal ↦ way-forward ⟨act on reason ∨ contest ≜ state why ↦ contested call proceeds unjudged ∧ contest logged ↦ operator review · a retry ¬ contested ↦ judged again⟩',
|
|
29
13
|
substrate: 'harness',
|
|
30
14
|
// Bound by the same composition as its turn-end twin: the stance it enforces is the
|
|
31
15
|
// one `handoff` declares.
|
|
@@ -41,52 +25,13 @@ export const stanceGuardrailPre = {
|
|
|
41
25
|
targetPath: 'packages/canon/targets/guardrail/stance-guardrail-pre.sh',
|
|
42
26
|
executable: true,
|
|
43
27
|
content: `#!/usr/bin/env sh
|
|
44
|
-
# stance-guardrail-pre
|
|
45
|
-
#
|
|
46
|
-
#
|
|
47
|
-
#
|
|
48
|
-
#
|
|
49
|
-
# WHAT IT DENIES (see stance-judge-prompt.md — the SHARED rubric):
|
|
50
|
-
# - AskUserQuestion : a permission / option-menu on an in-remit reversible call
|
|
51
|
-
# - Agent/SendMessage : a dispatch transcribing literal words without extracted intent
|
|
52
|
-
# WHAT IT DOES NOT DENY (reserved): an irreversible-outward consent menu, a true INTENT
|
|
53
|
-
# ambiguity, a substantive intent-extracted dispatch, a unit or a closed plan routed by name (the
|
|
54
|
-
# intent lives in the spec at that address).
|
|
55
|
-
#
|
|
56
|
-
# SAFETY MODEL (mirrors stance-guardrail):
|
|
57
|
-
# - SCOPE-ENROLLED, exactly as its twin: a scope carrying a stance manifest is judged and
|
|
58
|
-
# every other scope is silent. No repo opt-in, no allowlist — the projection that places a
|
|
59
|
-
# persona also enrolls it, and declining the guard means declining the persona.
|
|
60
|
-
# - FAILS OPEN, NEVER SILENTLY. Any error (no jq, no input, judge failure, unparseable verdict,
|
|
61
|
-
# unexpected error) -> exit 0 (allow the call), and the call goes through WITH A NOTICE the
|
|
62
|
-
# operator reads (\`say\`: Claude Code's JSON \`systemMessage\`, omp's relayed line) naming this
|
|
63
|
-
# guard and why it could not judge. Silence is reserved for "judged, pass" and "not enrolled".
|
|
64
|
-
# - A REFUSAL HOLDS. Every call is judged, a repeat of a refused call included: an identical
|
|
65
|
-
# tool_input retried is judged again and, when the judge blocks it, denied again, however
|
|
66
|
-
# often it comes. Nothing remembers a prior denial, so no retry is waved through unjudged.
|
|
67
|
-
# - OBSERVABLE. Every notice is also a line in the miss log.
|
|
68
|
-
#
|
|
69
|
-
# INPUT : Claude Code PreToolUse hook JSON on stdin (tool_name, tool_input, agent_type,
|
|
70
|
-
# session_id, cwd, ...).
|
|
71
|
-
# OUTPUT : on collapse -> stdout
|
|
72
|
-
# {"hookSpecificOutput":{"hookEventName":"PreToolUse","permissionDecision":"deny",
|
|
73
|
-
# "permissionDecisionReason":"..."}} + exit 0.
|
|
74
|
-
# judged, pass -> no stdout + exit 0 (allow the call).
|
|
75
|
-
# let through with no verdict -> the notice \`say\` prints + exit 0 (allow the call).
|
|
76
|
-
#
|
|
77
|
-
# POSIX sh. Depends on: jq. Missing jq -> the guard says so and allows the call.
|
|
78
|
-
|
|
28
|
+
# stance-guardrail-pre: denies, before it fires, an AskUserQuestion menu on an in-remit call or an
|
|
29
|
+
# Agent/SendMessage dispatch that echoes literal words. Every call is judged, a retry included, unless
|
|
30
|
+
# the agent contested its refusal.
|
|
31
|
+
# Fails open, never silently: what stops it judging lets the call through with a notice and a log line.
|
|
79
32
|
set -eu
|
|
80
33
|
|
|
81
|
-
#
|
|
82
|
-
# command: the first thing that can be missing is \`jq\`, and a worker run with a PATH holding
|
|
83
|
-
# little beyond \`sh\` and \`cat\` must still say it did not judge, so \`esc\`, \`say\` and \`open\`
|
|
84
|
-
# are builtins only and nothing external runs above the jq check.
|
|
85
|
-
#
|
|
86
|
-
# Claude Code shows the operator a hook's JSON \`systemMessage\` and NOT its plain stdout on
|
|
87
|
-
# exit 0. omp's extension bridge reads the worker's plain stdout and relays a line naming this
|
|
88
|
-
# guard and DARK to the session, and would relay a JSON object as raw JSON — hence one form per
|
|
89
|
-
# harness, chosen at projection by the harness's own name.
|
|
34
|
+
# esc, say and open are builtins only, so they work before the jq check can fail.
|
|
90
35
|
esc() {
|
|
91
36
|
_in="$1"
|
|
92
37
|
_out=""
|
|
@@ -109,80 +54,45 @@ esc() {
|
|
|
109
54
|
done
|
|
110
55
|
printf '%s' "$_out"
|
|
111
56
|
}
|
|
57
|
+
# Claude Code shows the operator a JSON systemMessage; omp relays a plain line.
|
|
112
58
|
say() {
|
|
113
59
|
case "{{fact:harness-name}}" in
|
|
114
60
|
claude) printf '{"systemMessage":"%s"}\\n' "$(esc "$1")" ;;
|
|
115
61
|
*) printf '%s\\n' "$1" ;;
|
|
116
62
|
esac
|
|
117
63
|
}
|
|
118
|
-
|
|
119
|
-
allow() { exit 0; } # emit nothing; the tool call proceeds.
|
|
120
|
-
|
|
121
|
-
# A verdict and a failure are different facts and silence carries only one of them: \`allow\`
|
|
122
|
-
# means "judged, pass" or "not this guard's call", \`open\` means "could not judge" — the call
|
|
123
|
-
# still proceeds, and the operator is told.
|
|
64
|
+
allow() { exit 0; }
|
|
124
65
|
open() {
|
|
125
66
|
[ -z "\${LOG:-}" ] || printf '%s\\n' "open: $1 tool=\${tool_name:-?} agent=\${agent_type:-?}" >> "$LOG" 2>/dev/null || true
|
|
126
67
|
say "STANCE GUARDRAIL (pre) — DARK: $1. This call was NOT judged; the absence of a deny is an absence of a verdict, not a clean one."
|
|
127
68
|
exit 0
|
|
128
69
|
}
|
|
129
|
-
|
|
130
|
-
# A PreToolUse hook must never break a session. An unexpected error (a nonzero status reaching
|
|
131
|
-
# the trap) is let through AND SAID; every deliberate \`exit 0\` arrives with status 0.
|
|
132
70
|
trap 'rc=$?; [ "$rc" -eq 0 ] || open "an unexpected error stopped it (exit status $rc)"; exit 0' EXIT
|
|
133
71
|
|
|
134
|
-
# --- read hook input ------------------------------------------------------------------------
|
|
135
72
|
input="$(cat)"
|
|
136
73
|
[ -n "$input" ] || open "the hook received no input"
|
|
137
74
|
command -v jq >/dev/null 2>&1 || open "jq is not installed, so the hook payload cannot be read"
|
|
75
|
+
field() { printf '%s' "$input" | jq -r "$1" 2>/dev/null || true; }
|
|
138
76
|
|
|
139
|
-
#
|
|
140
|
-
|
|
141
|
-
# session. Claude Code fires this hook inside a subagent too (settings hooks and the subagent's
|
|
142
|
-
# own front-matter hooks), and there the payload carries \`agent_id\` — present only inside a
|
|
143
|
-
# subagent. A guard that does not bind there is not dark: it exits before it judges and says
|
|
144
|
-
# nothing.
|
|
145
|
-
[ -z "$(printf '%s' "$input" | jq -r '.agent_id // empty' 2>/dev/null || true)" ] || allow
|
|
77
|
+
# Only a subagent's payload carries agent_id; the guard binds main sessions.
|
|
78
|
+
[ -z "$(field '.agent_id // empty')" ] || allow
|
|
146
79
|
|
|
147
|
-
#
|
|
148
|
-
# together, as siblings under the SAME hooks root).
|
|
149
|
-
#
|
|
150
|
-
# RESOLVED FROM THIS SCRIPT'S OWN LOCATION, never from a harness's home. These four
|
|
151
|
-
# lines named \`$HOME/.claude/...\` outright, so the copy deployed under
|
|
152
|
-
# \`~/.omp/hooks/\` reached across into the CLAUDE tree for its judge — and on a host
|
|
153
|
-
# with no claude deployment it found nothing, failed open, and logged its misses to
|
|
154
|
-
# a directory that does not exist. Every hooks root holds both hook dirs as
|
|
155
|
-
# siblings, so \`../stance-guardrail\` is true at every site this file can land; the
|
|
156
|
-
# sibling Stop worker already derives its own dir this way and this is the same
|
|
157
|
-
# derivation, one level up. The env overrides are unchanged and still win.
|
|
80
|
+
# Sibling paths come from this script's own location, never from a harness home.
|
|
158
81
|
SELF_DIR="$(CDPATH= cd -- "$(dirname -- "$0")" && pwd)"
|
|
159
82
|
HOOKS_ROOT="$(dirname -- "$SELF_DIR")"
|
|
160
|
-
JUDGE_DIR="\${STANCE_GUARD_DIR:-$HOOKS_ROOT/stance-guardrail}"
|
|
161
|
-
# The RUBRIC is not in either hook dir: it is harness-invariant and deploys once
|
|
162
|
-
# to the neutral \`.agents\` root, the sibling of every harness home. Same
|
|
163
|
-
# derivation as the sibling Stop worker, one level further out.
|
|
164
83
|
NEUTRAL_ROOT="$(dirname -- "$(dirname -- "$HOOKS_ROOT")")/.agents"
|
|
165
84
|
RUBRIC="\${STANCE_RUBRIC:-$NEUTRAL_ROOT/stance-guardrail/stance-judge-prompt.md}"
|
|
166
|
-
JUDGE_CMD="\${STANCE_JUDGE_CMD:-sh
|
|
85
|
+
JUDGE_CMD="\${STANCE_JUDGE_CMD:-sh \${STANCE_GUARD_DIR:-$HOOKS_ROOT/stance-guardrail}/stance-judge.sh}"
|
|
167
86
|
LOG="\${STANCE_GUARD_LOG:-$SELF_DIR/misses.log}"
|
|
168
87
|
|
|
169
|
-
|
|
170
|
-
# a DIRECTORY, and a stance belongs to the agent, not the checkout. \`cwd\` survives it — the worker
|
|
171
|
-
# still runs where the session runs.
|
|
172
|
-
cwd="$(printf '%s' "$input" | jq -r '.cwd // empty' 2>/dev/null || true)"
|
|
88
|
+
cwd="$(field '.cwd // empty')"
|
|
173
89
|
[ -n "$cwd" ] && cd "$cwd" 2>/dev/null || true
|
|
174
90
|
|
|
175
|
-
#
|
|
176
|
-
#
|
|
177
|
-
|
|
178
|
-
# such a list always drifts. Presence of a manifest in this persona's own scope IS enrollment.
|
|
179
|
-
# Absent → silence, never an error, so an unenrolled launch is untouched. The scope is the one
|
|
180
|
-
# the harness hands over: \`stance_scope\` where a dispatcher sits in the persona's own scope (omp),
|
|
181
|
-
# else the persona directory of the agent the payload NAMES (\`agent_type\`, Claude Code — none on a
|
|
182
|
-
# bare session) under this harness's home, one hop above the hooks root. No agent list here.
|
|
183
|
-
stance_scope="$(printf '%s' "$input" | jq -r '.stance_scope // empty' 2>/dev/null || true)"
|
|
91
|
+
# A stance manifest in the persona's scope is the enrollment: omp hands the scope over as
|
|
92
|
+
# stance_scope, Claude Code names the agent as agent_type. No manifest, no judgement.
|
|
93
|
+
stance_scope="$(field '.stance_scope // empty')"
|
|
184
94
|
if [ -z "$stance_scope" ]; then
|
|
185
|
-
named="$(
|
|
95
|
+
named="$(field '.agent_type // empty')"
|
|
186
96
|
case "$named" in '' | */* | . | ..) allow ;; esac
|
|
187
97
|
stance_scope="$(dirname -- "$HOOKS_ROOT")/{{fact:harness-persona-root}}/$named"
|
|
188
98
|
fi
|
|
@@ -190,45 +100,40 @@ manifest="$stance_scope/{{fact:stance-manifest}}"
|
|
|
190
100
|
[ -f "$manifest" ] || allow
|
|
191
101
|
agent_type="$(jq -r '.agent // empty' "$manifest" 2>/dev/null || true)"
|
|
192
102
|
|
|
193
|
-
${
|
|
103
|
+
${judgeClipShell}
|
|
194
104
|
|
|
195
|
-
|
|
196
|
-
tool_name="$(printf '%s' "$input" | jq -r '.tool_name // empty' 2>/dev/null || true)"
|
|
105
|
+
tool_name="$(field '.tool_name // empty')"
|
|
197
106
|
[ -n "$tool_name" ] || open "the payload names no tool, so there is no call to judge"
|
|
198
107
|
|
|
199
108
|
case "$tool_name" in
|
|
200
109
|
AskUserQuestion)
|
|
201
|
-
|
|
202
|
-
body="$(printf '%s' "$input" | jq -r '
|
|
110
|
+
body="$(field '
|
|
203
111
|
(.tool_input.questions // [])
|
|
204
112
|
| map("Q: " + (.question // "")
|
|
205
113
|
+ " OPTIONS: " + ((.options // []) | map(.label // "") | join(" | ")))
|
|
206
114
|
| join(" ;; ")
|
|
207
|
-
'
|
|
115
|
+
')"
|
|
208
116
|
prefix="AskUserQuestion menu (a question/option menu handed to the operator): " ;;
|
|
209
117
|
Agent|SendMessage)
|
|
210
|
-
|
|
211
|
-
body="$(printf '%s' "$input" | jq -r '.tool_input.prompt // .tool_input.message // .tool_input.description // ""' 2>/dev/null || true)"
|
|
118
|
+
body="$(field '.tool_input.prompt // .tool_input.message // .tool_input.description // ""')"
|
|
212
119
|
prefix="$tool_name dispatch (the delegate prompt/message): " ;;
|
|
213
|
-
*)
|
|
214
|
-
allow ;; # DEFENCE IN DEPTH: every supported adapter computes a selector from the
|
|
215
|
-
# act, so this never fires there. A harness that could fire the act but
|
|
216
|
-
# not narrow it would WARN in projection, and this branch is what would
|
|
217
|
-
# keep the guard off every other tool call.
|
|
120
|
+
*) allow ;;
|
|
218
121
|
esac
|
|
219
122
|
|
|
220
|
-
[ -n "\${body:-}" ] || allow
|
|
123
|
+
[ -n "\${body:-}" ] || allow
|
|
124
|
+
|
|
125
|
+
GUARD_ID=stance-guardrail-pre
|
|
126
|
+
GUARD_NAME="STANCE GUARDRAIL (pre)"
|
|
127
|
+
GUARD_SESSION="$(field '.session_id // empty')"
|
|
128
|
+
GUARD_AGENT="$agent_type"
|
|
129
|
+
GUARD_ACT="$tool_name"
|
|
130
|
+
GUARD_CALL="$(printf '%s' "$input" | jq -c '.tool_input' 2>/dev/null || true)"
|
|
131
|
+
${contestShell}
|
|
132
|
+
contest_heard
|
|
221
133
|
|
|
222
|
-
# THE JUDGE IS SENT AT MOST JUDGE_PAYLOAD_CAP BYTES, prefix included: a menu or a dispatch prompt
|
|
223
|
-
# has no bound of its own, and a judgement has to fit the time the harness allows a guard. The
|
|
224
|
-
# instruction of a prompt may sit at either end, so both ends are kept and the seam is marked.
|
|
225
134
|
body="$(printf '%s' "$body" | judge_ends "$((JUDGE_PAYLOAD_CAP - $(judge_bytes "$prefix")))")"
|
|
226
135
|
payload="$prefix$body"
|
|
227
136
|
|
|
228
|
-
# --- judge (SHARED backend + rubric) --------------------------------------------------------
|
|
229
|
-
# The same out-of-process seam the Stop worker carries, and for the same reason: a
|
|
230
|
-
# host that already holds a model must not be made to spawn another vendor's CLI.
|
|
231
|
-
# No marker is written anywhere: the emit pass and the verdict pass mutate nothing.
|
|
232
137
|
if [ -n "\${STANCE_EMIT_PAYLOAD:-}" ]; then
|
|
233
138
|
jq -cn --arg r "$RUBRIC" --arg p "$payload" '{rubric:$r, payload:$p}'
|
|
234
139
|
exit 0
|
|
@@ -240,23 +145,18 @@ else
|
|
|
240
145
|
verdict="$(printf '%s' "$payload" | $JUDGE_CMD "$RUBRIC" 2>/dev/null)" || open "the judge did not answer"
|
|
241
146
|
fi
|
|
242
147
|
|
|
243
|
-
|
|
148
|
+
tag() { printf '%s\\n' "$verdict" | sed -n "s/^$1:[[:space:]]*//p" | head -1; }
|
|
149
|
+
decision="$(tag VERDICT | sed 's/[[:space:]]*$//')"
|
|
244
150
|
case "$decision" in
|
|
245
|
-
PASS) allow ;;
|
|
151
|
+
PASS) allow ;;
|
|
246
152
|
BLOCK) ;;
|
|
247
153
|
*) open "the judge's verdict was unparseable (no VERDICT: PASS or VERDICT: BLOCK line)" ;;
|
|
248
154
|
esac
|
|
249
155
|
|
|
250
|
-
reason="$(
|
|
156
|
+
reason="$(tag REASON)"
|
|
251
157
|
[ -n "$reason" ] || reason="This tool call collapsed out of the intent-driven-expert stance."
|
|
252
158
|
|
|
253
|
-
|
|
254
|
-
feedback="STANCE GUARDRAIL (pre) — denied this $tool_name call: it collapses out of the \\
|
|
255
|
-
intent-driven-expert stance. $reason Own the in-remit reversible call yourself instead of handing the \\
|
|
256
|
-
operator a menu; extract and serve the underlying INTENT instead of transcribing literal words into a \\
|
|
257
|
-
dispatch. Decide, note the call for review, and proceed. (Legitimate exceptions that should NOT be a menu \\
|
|
258
|
-
here: a genuine irreversible-outward consent choice, a true INTENT ambiguity for /elicit, a substantive \\
|
|
259
|
-
intent-extracted dispatch, or a unit or a closed plan routed by name, whose intent lives in its spec.)"
|
|
159
|
+
feedback="STANCE GUARDRAIL (pre) — denied this $tool_name call: $reason Own the in-remit call, or serve the intent in a dispatch, instead. $(contest_refused "$reason")"
|
|
260
160
|
|
|
261
161
|
jq -cn --arg r "$feedback" '{hookSpecificOutput:{hookEventName:"PreToolUse",permissionDecision:"deny",permissionDecisionReason:$r}}'
|
|
262
162
|
exit 0
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"stance-guardrail-pre.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail-pre.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;
|
|
1
|
+
{"version":3,"file":"stance-guardrail-pre.js","sourceRoot":"","sources":["../../src/hooks/stance-guardrail-pre.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,mCAAmC,CAAC;AAC5D,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAGjE,8FAA8F;AAC9F,0FAA0F;AAC1F,4FAA4F;AAC5F,yFAAyF;AACzF,2FAA2F;AAC3F,oEAAoE;AAEpE,MAAM,CAAC,MAAM,kBAAkB,GAAa;IAC1C,EAAE,EAAE,sBAAsB;IAC1B,OAAO,EACL,udAAud;IACzd,SAAS,EAAE,SAAS;IACpB,oFAAoF;IACpF,0BAA0B;IAC1B,KAAK,EAAE,EAAE,SAAS,EAAE,UAAU,EAAE,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,EAAE;IAC1D,KAAK,EAAE,CAAC;IACR,MAAM,EAAE,CAAC,sBAAsB,EAAE,uBAAuB,CAAC;IACzD,KAAK,EAAE,yBAAyB;IAChC,OAAO,EAAE,EAAE;IACX,IAAI,EAAE,EAAE;IACR,OAAO,EAAE;QACP;YACE,QAAQ,EAAE,yBAAyB;YACnC,UAAU,EAAE,0DAA0D;YACtE,UAAU,EAAE,IAAI;YAChB,OAAO,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4Eb,cAAc;;;;;;;;;;;;;;;;;;;;;;;;;;;;EA4Bd,YAAY;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgCb;SACI;KACF;CACF,CAAC"}
|