wingfoil 0.2.1
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/LICENSE +21 -0
- package/README.md +334 -0
- package/dist/cli/error.d.ts +11 -0
- package/dist/cli/error.d.ts.map +1 -0
- package/dist/cli/error.js +27 -0
- package/dist/cli/error.js.map +1 -0
- package/dist/cli/exit.d.ts +19 -0
- package/dist/cli/exit.d.ts.map +1 -0
- package/dist/cli/exit.js +14 -0
- package/dist/cli/exit.js.map +1 -0
- package/dist/cli/index.d.ts +28 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +36 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/cli/init-command.d.ts +34 -0
- package/dist/cli/init-command.d.ts.map +1 -0
- package/dist/cli/init-command.js +100 -0
- package/dist/cli/init-command.js.map +1 -0
- package/dist/cli/mcp-command.d.ts +24 -0
- package/dist/cli/mcp-command.d.ts.map +1 -0
- package/dist/cli/mcp-command.js +42 -0
- package/dist/cli/mcp-command.js.map +1 -0
- package/dist/cli/output.d.ts +13 -0
- package/dist/cli/output.d.ts.map +1 -0
- package/dist/cli/output.js +28 -0
- package/dist/cli/output.js.map +1 -0
- package/dist/cli/program.d.ts +12 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +279 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/cli/registrar.d.ts +69 -0
- package/dist/cli/registrar.d.ts.map +1 -0
- package/dist/cli/registrar.js +82 -0
- package/dist/cli/registrar.js.map +1 -0
- package/dist/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +45 -0
- package/dist/cli.js.map +1 -0
- package/dist/core/approval-authority.d.ts +83 -0
- package/dist/core/approval-authority.d.ts.map +1 -0
- package/dist/core/approval-authority.js +112 -0
- package/dist/core/approval-authority.js.map +1 -0
- package/dist/core/builtin-asset.d.ts +71 -0
- package/dist/core/builtin-asset.d.ts.map +1 -0
- package/dist/core/builtin-asset.js +137 -0
- package/dist/core/builtin-asset.js.map +1 -0
- package/dist/core/builtin-integrity.d.ts +32 -0
- package/dist/core/builtin-integrity.d.ts.map +1 -0
- package/dist/core/builtin-integrity.js +148 -0
- package/dist/core/builtin-integrity.js.map +1 -0
- package/dist/core/confinement.d.ts +57 -0
- package/dist/core/confinement.d.ts.map +1 -0
- package/dist/core/confinement.js +108 -0
- package/dist/core/confinement.js.map +1 -0
- package/dist/core/context.d.ts +187 -0
- package/dist/core/context.d.ts.map +1 -0
- package/dist/core/context.js +192 -0
- package/dist/core/context.js.map +1 -0
- package/dist/core/directive-assign.d.ts +131 -0
- package/dist/core/directive-assign.d.ts.map +1 -0
- package/dist/core/directive-assign.js +352 -0
- package/dist/core/directive-assign.js.map +1 -0
- package/dist/core/directives-list.d.ts +80 -0
- package/dist/core/directives-list.d.ts.map +1 -0
- package/dist/core/directives-list.js +148 -0
- package/dist/core/directives-list.js.map +1 -0
- package/dist/core/exit-code.d.ts +85 -0
- package/dist/core/exit-code.d.ts.map +1 -0
- package/dist/core/exit-code.js +163 -0
- package/dist/core/exit-code.js.map +1 -0
- package/dist/core/git-identity.d.ts +32 -0
- package/dist/core/git-identity.d.ts.map +1 -0
- package/dist/core/git-identity.js +72 -0
- package/dist/core/git-identity.js.map +1 -0
- package/dist/core/index.d.ts +388 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +1331 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/init.d.ts +78 -0
- package/dist/core/init.d.ts.map +1 -0
- package/dist/core/init.js +167 -0
- package/dist/core/init.js.map +1 -0
- package/dist/core/loaders.d.ts +174 -0
- package/dist/core/loaders.d.ts.map +1 -0
- package/dist/core/loaders.js +364 -0
- package/dist/core/loaders.js.map +1 -0
- package/dist/core/memory-add-type.d.ts +43 -0
- package/dist/core/memory-add-type.d.ts.map +1 -0
- package/dist/core/memory-add-type.js +151 -0
- package/dist/core/memory-add-type.js.map +1 -0
- package/dist/core/memory-transition.d.ts +111 -0
- package/dist/core/memory-transition.d.ts.map +1 -0
- package/dist/core/memory-transition.js +269 -0
- package/dist/core/memory-transition.js.map +1 -0
- package/dist/core/registry.d.ts +189 -0
- package/dist/core/registry.d.ts.map +1 -0
- package/dist/core/registry.js +66 -0
- package/dist/core/registry.js.map +1 -0
- package/dist/core/relevance.d.ts +86 -0
- package/dist/core/relevance.d.ts.map +1 -0
- package/dist/core/relevance.js +258 -0
- package/dist/core/relevance.js.map +1 -0
- package/dist/core/require-reason.d.ts +27 -0
- package/dist/core/require-reason.d.ts.map +1 -0
- package/dist/core/require-reason.js +95 -0
- package/dist/core/require-reason.js.map +1 -0
- package/dist/core/types.d.ts +45 -0
- package/dist/core/types.d.ts.map +1 -0
- package/dist/core/types.js +22 -0
- package/dist/core/types.js.map +1 -0
- package/dist/core/usage-error.d.ts +20 -0
- package/dist/core/usage-error.d.ts.map +1 -0
- package/dist/core/usage-error.js +29 -0
- package/dist/core/usage-error.js.map +1 -0
- package/dist/core/write-guard.d.ts +99 -0
- package/dist/core/write-guard.d.ts.map +1 -0
- package/dist/core/write-guard.js +247 -0
- package/dist/core/write-guard.js.map +1 -0
- package/dist/directives/create.d.ts +47 -0
- package/dist/directives/create.d.ts.map +1 -0
- package/dist/directives/create.js +82 -0
- package/dist/directives/create.js.map +1 -0
- package/dist/directives/index.d.ts +20 -0
- package/dist/directives/index.d.ts.map +1 -0
- package/dist/directives/index.js +32 -0
- package/dist/directives/index.js.map +1 -0
- package/dist/directives/roles-edit.d.ts +53 -0
- package/dist/directives/roles-edit.d.ts.map +1 -0
- package/dist/directives/roles-edit.js +286 -0
- package/dist/directives/roles-edit.js.map +1 -0
- package/dist/directives/schema.d.ts +65 -0
- package/dist/directives/schema.d.ts.map +1 -0
- package/dist/directives/schema.js +68 -0
- package/dist/directives/schema.js.map +1 -0
- package/dist/dna/edit.d.ts +61 -0
- package/dist/dna/edit.d.ts.map +1 -0
- package/dist/dna/edit.js +429 -0
- package/dist/dna/edit.js.map +1 -0
- package/dist/dna/index.d.ts +24 -0
- package/dist/dna/index.d.ts.map +1 -0
- package/dist/dna/index.js +59 -0
- package/dist/dna/index.js.map +1 -0
- package/dist/dna/mutate.d.ts +74 -0
- package/dist/dna/mutate.d.ts.map +1 -0
- package/dist/dna/mutate.js +318 -0
- package/dist/dna/mutate.js.map +1 -0
- package/dist/dna/path.d.ts +175 -0
- package/dist/dna/path.d.ts.map +1 -0
- package/dist/dna/path.js +289 -0
- package/dist/dna/path.js.map +1 -0
- package/dist/dna/roles.d.ts +57 -0
- package/dist/dna/roles.d.ts.map +1 -0
- package/dist/dna/roles.js +50 -0
- package/dist/dna/roles.js.map +1 -0
- package/dist/dna/schema.d.ts +172 -0
- package/dist/dna/schema.d.ts.map +1 -0
- package/dist/dna/schema.js +182 -0
- package/dist/dna/schema.js.map +1 -0
- package/dist/dna/set.d.ts +145 -0
- package/dist/dna/set.d.ts.map +1 -0
- package/dist/dna/set.js +428 -0
- package/dist/dna/set.js.map +1 -0
- package/dist/mcp/dna-resource.d.ts +16 -0
- package/dist/mcp/dna-resource.d.ts.map +1 -0
- package/dist/mcp/dna-resource.js +56 -0
- package/dist/mcp/dna-resource.js.map +1 -0
- package/dist/mcp/index.d.ts +49 -0
- package/dist/mcp/index.d.ts.map +1 -0
- package/dist/mcp/index.js +60 -0
- package/dist/mcp/index.js.map +1 -0
- package/dist/mcp/memory-resource.d.ts +17 -0
- package/dist/mcp/memory-resource.d.ts.map +1 -0
- package/dist/mcp/memory-resource.js +133 -0
- package/dist/mcp/memory-resource.js.map +1 -0
- package/dist/mcp/prompt.d.ts +48 -0
- package/dist/mcp/prompt.d.ts.map +1 -0
- package/dist/mcp/prompt.js +176 -0
- package/dist/mcp/prompt.js.map +1 -0
- package/dist/mcp/read-only.d.ts +42 -0
- package/dist/mcp/read-only.d.ts.map +1 -0
- package/dist/mcp/read-only.js +93 -0
- package/dist/mcp/read-only.js.map +1 -0
- package/dist/mcp/registrar.d.ts +54 -0
- package/dist/mcp/registrar.d.ts.map +1 -0
- package/dist/mcp/registrar.js +72 -0
- package/dist/mcp/registrar.js.map +1 -0
- package/dist/mcp/server.d.ts +58 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +64 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/workflow-resource.d.ts +17 -0
- package/dist/mcp/workflow-resource.d.ts.map +1 -0
- package/dist/mcp/workflow-resource.js +63 -0
- package/dist/mcp/workflow-resource.js.map +1 -0
- package/dist/memory/add.d.ts +50 -0
- package/dist/memory/add.d.ts.map +1 -0
- package/dist/memory/add.js +131 -0
- package/dist/memory/add.js.map +1 -0
- package/dist/memory/audit.d.ts +177 -0
- package/dist/memory/audit.d.ts.map +1 -0
- package/dist/memory/audit.js +287 -0
- package/dist/memory/audit.js.map +1 -0
- package/dist/memory/commit-message.d.ts +146 -0
- package/dist/memory/commit-message.d.ts.map +1 -0
- package/dist/memory/commit-message.js +203 -0
- package/dist/memory/commit-message.js.map +1 -0
- package/dist/memory/entry.d.ts +56 -0
- package/dist/memory/entry.d.ts.map +1 -0
- package/dist/memory/entry.js +28 -0
- package/dist/memory/entry.js.map +1 -0
- package/dist/memory/frontmatter-edit.d.ts +68 -0
- package/dist/memory/frontmatter-edit.d.ts.map +1 -0
- package/dist/memory/frontmatter-edit.js +333 -0
- package/dist/memory/frontmatter-edit.js.map +1 -0
- package/dist/memory/git-log.d.ts +32 -0
- package/dist/memory/git-log.d.ts.map +1 -0
- package/dist/memory/git-log.js +100 -0
- package/dist/memory/git-log.js.map +1 -0
- package/dist/memory/history.d.ts +142 -0
- package/dist/memory/history.d.ts.map +1 -0
- package/dist/memory/history.js +250 -0
- package/dist/memory/history.js.map +1 -0
- package/dist/memory/index.d.ts +58 -0
- package/dist/memory/index.d.ts.map +1 -0
- package/dist/memory/index.js +107 -0
- package/dist/memory/index.js.map +1 -0
- package/dist/memory/query.d.ts +150 -0
- package/dist/memory/query.d.ts.map +1 -0
- package/dist/memory/query.js +307 -0
- package/dist/memory/query.js.map +1 -0
- package/dist/memory/reject.d.ts +11 -0
- package/dist/memory/reject.d.ts.map +1 -0
- package/dist/memory/reject.js +32 -0
- package/dist/memory/reject.js.map +1 -0
- package/dist/memory/schema.d.ts +104 -0
- package/dist/memory/schema.d.ts.map +1 -0
- package/dist/memory/schema.js +161 -0
- package/dist/memory/schema.js.map +1 -0
- package/dist/memory/state-machine.d.ts +166 -0
- package/dist/memory/state-machine.d.ts.map +1 -0
- package/dist/memory/state-machine.js +431 -0
- package/dist/memory/state-machine.js.map +1 -0
- package/dist/memory/submit.d.ts +11 -0
- package/dist/memory/submit.d.ts.map +1 -0
- package/dist/memory/submit.js +44 -0
- package/dist/memory/submit.js.map +1 -0
- package/dist/storage/builtin-directives.d.ts +54 -0
- package/dist/storage/builtin-directives.d.ts.map +1 -0
- package/dist/storage/builtin-directives.js +152 -0
- package/dist/storage/builtin-directives.js.map +1 -0
- package/dist/storage/commit.d.ts +92 -0
- package/dist/storage/commit.d.ts.map +1 -0
- package/dist/storage/commit.js +201 -0
- package/dist/storage/commit.js.map +1 -0
- package/dist/storage/confinement.d.ts +93 -0
- package/dist/storage/confinement.d.ts.map +1 -0
- package/dist/storage/confinement.js +164 -0
- package/dist/storage/confinement.js.map +1 -0
- package/dist/storage/document.d.ts +27 -0
- package/dist/storage/document.d.ts.map +1 -0
- package/dist/storage/document.js +52 -0
- package/dist/storage/document.js.map +1 -0
- package/dist/storage/errors.d.ts +36 -0
- package/dist/storage/errors.d.ts.map +1 -0
- package/dist/storage/errors.js +46 -0
- package/dist/storage/errors.js.map +1 -0
- package/dist/storage/frontmatter.d.ts +27 -0
- package/dist/storage/frontmatter.d.ts.map +1 -0
- package/dist/storage/frontmatter.js +37 -0
- package/dist/storage/frontmatter.js.map +1 -0
- package/dist/storage/git-root.d.ts +17 -0
- package/dist/storage/git-root.d.ts.map +1 -0
- package/dist/storage/git-root.js +49 -0
- package/dist/storage/git-root.js.map +1 -0
- package/dist/storage/index.d.ts +29 -0
- package/dist/storage/index.d.ts.map +1 -0
- package/dist/storage/index.js +66 -0
- package/dist/storage/index.js.map +1 -0
- package/dist/storage/init-state.d.ts +9 -0
- package/dist/storage/init-state.d.ts.map +1 -0
- package/dist/storage/init-state.js +24 -0
- package/dist/storage/init-state.js.map +1 -0
- package/dist/storage/layout.d.ts +51 -0
- package/dist/storage/layout.d.ts.map +1 -0
- package/dist/storage/layout.js +88 -0
- package/dist/storage/layout.js.map +1 -0
- package/dist/storage/memory-path.d.ts +72 -0
- package/dist/storage/memory-path.d.ts.map +1 -0
- package/dist/storage/memory-path.js +127 -0
- package/dist/storage/memory-path.js.map +1 -0
- package/dist/storage/snapshot.d.ts +16 -0
- package/dist/storage/snapshot.d.ts.map +1 -0
- package/dist/storage/snapshot.js +72 -0
- package/dist/storage/snapshot.js.map +1 -0
- package/dist/storage/templates.d.ts +88 -0
- package/dist/storage/templates.d.ts.map +1 -0
- package/dist/storage/templates.js +422 -0
- package/dist/storage/templates.js.map +1 -0
- package/dist/validation/error-mapper.d.ts +16 -0
- package/dist/validation/error-mapper.d.ts.map +1 -0
- package/dist/validation/error-mapper.js +18 -0
- package/dist/validation/error-mapper.js.map +1 -0
- package/dist/validation/errors.d.ts +69 -0
- package/dist/validation/errors.d.ts.map +1 -0
- package/dist/validation/errors.js +69 -0
- package/dist/validation/errors.js.map +1 -0
- package/dist/validation/id.d.ts +16 -0
- package/dist/validation/id.d.ts.map +1 -0
- package/dist/validation/id.js +177 -0
- package/dist/validation/id.js.map +1 -0
- package/dist/validation/index.d.ts +18 -0
- package/dist/validation/index.d.ts.map +1 -0
- package/dist/validation/index.js +37 -0
- package/dist/validation/index.js.map +1 -0
- package/dist/validation/secret-scan.d.ts +129 -0
- package/dist/validation/secret-scan.d.ts.map +1 -0
- package/dist/validation/secret-scan.js +367 -0
- package/dist/validation/secret-scan.js.map +1 -0
- package/dist/validation/two-pass.d.ts +24 -0
- package/dist/validation/two-pass.d.ts.map +1 -0
- package/dist/validation/two-pass.js +24 -0
- package/dist/validation/two-pass.js.map +1 -0
- package/dist/validation/warning.d.ts +31 -0
- package/dist/validation/warning.d.ts.map +1 -0
- package/dist/validation/warning.js +81 -0
- package/dist/validation/warning.js.map +1 -0
- package/dist/validation/yaml.d.ts +9 -0
- package/dist/validation/yaml.d.ts.map +1 -0
- package/dist/validation/yaml.js +30 -0
- package/dist/validation/yaml.js.map +1 -0
- package/dist/workflow/index.d.ts +10 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +16 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/schema.d.ts +89 -0
- package/dist/workflow/schema.d.ts.map +1 -0
- package/dist/workflow/schema.js +73 -0
- package/dist/workflow/schema.js.map +1 -0
- package/package.json +78 -0
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.reasonDefectMessage = reasonDefectMessage;
|
|
4
|
+
exports.normalizeReason = normalizeReason;
|
|
5
|
+
exports.reasonDefect = reasonDefect;
|
|
6
|
+
exports.parseReasonBlock = parseReasonBlock;
|
|
7
|
+
exports.parseApproverTrailerLine = parseApproverTrailerLine;
|
|
8
|
+
exports.formatMemoryCommitMessage = formatMemoryCommitMessage;
|
|
9
|
+
/** The arrow used in `[from → to]` subject brackets (U+2192), as `./audit.ts`'s `BRACKET_RE` expects. */
|
|
10
|
+
const ARROW = '→';
|
|
11
|
+
// --- The reason grammar (dl-067-reason-trailer-contract) ---------------------------------------
|
|
12
|
+
/**
|
|
13
|
+
* A git trailer line's shape (`Token: value`), as git itself recognises one. Used ONLY to identify a
|
|
14
|
+
* message's trailing trailer paragraph — the `Co-Authored-By:` block a hand-written commit ends with —
|
|
15
|
+
* which is where a `Reason:` block stops.
|
|
16
|
+
*/
|
|
17
|
+
const TRAILER_LINE_RE = /^[A-Za-z][A-Za-z0-9-]*:[ \t]\S/;
|
|
18
|
+
/**
|
|
19
|
+
* The two trailer keys THIS project's reader acts on. A reason may not contain a line starting with
|
|
20
|
+
* either, because such a line is indistinguishable from the trailer itself. Deliberately narrow: on
|
|
21
|
+
* `main`, 8 approve/reject commits carry a generic `Key: value` line inside their reason (ordinary
|
|
22
|
+
* prose — `Action: amend spec-015 §3`, `A: before the v0.2 …`) and **0** carry a reserved one, so a
|
|
23
|
+
* broader rule would outlaw the approver's own writing style (dl-067 E5).
|
|
24
|
+
*/
|
|
25
|
+
const RESERVED_TRAILER_LINE_RE = /^(?:Approver|Reason):/;
|
|
26
|
+
/** The `Reason:` key, at the start of a line. */
|
|
27
|
+
const REASON_KEY_RE = /^Reason:[ \t]*/;
|
|
28
|
+
/** The `Approver:` key, at the start of a line. */
|
|
29
|
+
const APPROVER_KEY_RE = /^Approver:/;
|
|
30
|
+
/** The exact refusal message for each defect — `spec-008-cli-grammar` §2's "invalid flag value" class (exit 2). */
|
|
31
|
+
const REASON_DEFECT_MESSAGES = {
|
|
32
|
+
blank: 'invalid flag value: --reason must not be blank',
|
|
33
|
+
'reserved-trailer-line': 'invalid flag value: --reason must not contain a line starting with "Approver:" or "Reason:"',
|
|
34
|
+
'trailing-trailer-paragraph': 'invalid flag value: --reason must not end in a paragraph of "Key: value" lines',
|
|
35
|
+
};
|
|
36
|
+
/**
|
|
37
|
+
* The refusal message for `defect` — the single source of the wording the CLI prints and
|
|
38
|
+
* `spec-008-cli-grammar` §2 pins. Deliberately distinct from `missing required argument: --reason`
|
|
39
|
+
* (`src/core/require-reason.ts`), which answers the *omitted* case that spec-008 §2 and the P1.7/P1.8
|
|
40
|
+
* BDD features already quote verbatim (dl-067 S1).
|
|
41
|
+
*/
|
|
42
|
+
function reasonDefectMessage(defect) {
|
|
43
|
+
return REASON_DEFECT_MESSAGES[defect];
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* The declared normal form of a reason (`dl-067` clause 3) — two rules, from two different sources,
|
|
47
|
+
* and it is worth keeping them apart:
|
|
48
|
+
*
|
|
49
|
+
* 1. **git's**, which applies whether or not this function exists. `commitPaths`
|
|
50
|
+
* (`src/storage/commit.ts`) commits with `-m`, so git's `cleanup=whitespace` strips per-line
|
|
51
|
+
* trailing whitespace, collapses runs of blank lines to one, and drops leading and trailing blank
|
|
52
|
+
* lines. This is why `spec-008-cli-grammar` §2's original "Recorded verbatim" was already false
|
|
53
|
+
* for any multi-line text, independently of bug-042.
|
|
54
|
+
* 2. **This module's**: the first line's leading whitespace is trimmed. git does NOT do this. It is
|
|
55
|
+
* needed because that line sits after `Reason: ` on the same physical line and
|
|
56
|
+
* {@link parseReasonBlock} consumes the key together with the whitespace that follows it — so
|
|
57
|
+
* without the trim, a reason beginning with spaces would not round-trip equally.
|
|
58
|
+
*
|
|
59
|
+
* Applying both HERE, on the way in, is what turns "approximately what you typed" into an assertable
|
|
60
|
+
* equality: what {@link parseReasonBlock} reads back out of the commit is exactly this function's
|
|
61
|
+
* output. Interior indentation is preserved by both rules — it carries meaning in real approval prose.
|
|
62
|
+
*
|
|
63
|
+
* Idempotent, and a pure function of its input (REQ-SYS-07).
|
|
64
|
+
*/
|
|
65
|
+
function normalizeReason(reason) {
|
|
66
|
+
return reason
|
|
67
|
+
.replace(/\r\n?/g, '\n')
|
|
68
|
+
.split('\n')
|
|
69
|
+
.map((line) => line.replace(/[ \t]+$/, ''))
|
|
70
|
+
.join('\n')
|
|
71
|
+
.replace(/\n{3,}/g, '\n\n')
|
|
72
|
+
.replace(/^\n+/, '')
|
|
73
|
+
.replace(/\n+$/, '')
|
|
74
|
+
.replace(/^[ \t]+/, '');
|
|
75
|
+
}
|
|
76
|
+
/** Split a normalized reason into its paragraphs, dropping the blank separators. */
|
|
77
|
+
function paragraphsOf(normalized) {
|
|
78
|
+
const paragraphs = [[]];
|
|
79
|
+
for (const line of normalized.split('\n')) {
|
|
80
|
+
if (line.trim() === '')
|
|
81
|
+
paragraphs.push([]);
|
|
82
|
+
else
|
|
83
|
+
paragraphs[paragraphs.length - 1].push(line);
|
|
84
|
+
}
|
|
85
|
+
return paragraphs.filter((paragraph) => paragraph.length > 0);
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* Why `reason` cannot be recorded in the `Reason:` trailer, or `null` when it can (`dl-067` clause 4).
|
|
89
|
+
*
|
|
90
|
+
* Judged on the NORMALIZED text ({@link normalizeReason}), because that is what would actually be
|
|
91
|
+
* stored — otherwise a defect could hide behind trailing whitespace git strips on the way in. This is
|
|
92
|
+
* the ONE place the rule is decided: `src/core/require-reason.ts` turns a non-`null` result into the
|
|
93
|
+
* `UsageError` (exit 2) the CLI boundary reports, and {@link formatMemoryCommitMessage} refuses the
|
|
94
|
+
* same values so no caller can route around that boundary.
|
|
95
|
+
*/
|
|
96
|
+
function reasonDefect(reason) {
|
|
97
|
+
const normalized = normalizeReason(reason);
|
|
98
|
+
if (normalized === '')
|
|
99
|
+
return 'blank';
|
|
100
|
+
const lines = normalized.split('\n');
|
|
101
|
+
if (lines.some((line) => RESERVED_TRAILER_LINE_RE.test(line)))
|
|
102
|
+
return 'reserved-trailer-line';
|
|
103
|
+
const paragraphs = paragraphsOf(normalized);
|
|
104
|
+
const last = paragraphs[paragraphs.length - 1];
|
|
105
|
+
if (paragraphs.length > 1 && last && last.every((line) => TRAILER_LINE_RE.test(line))) {
|
|
106
|
+
return 'trailing-trailer-paragraph';
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Where a commit body's trailing trailer paragraph begins, or `lines.length` when it has none — the
|
|
112
|
+
* `Co-Authored-By:` block a hand-written WingFoil commit ends with. Defined the way git defines a
|
|
113
|
+
* trailer block: the final paragraph of the message, every line of which is trailer-shaped.
|
|
114
|
+
*/
|
|
115
|
+
function trailerParagraphStart(lines) {
|
|
116
|
+
let end = lines.length;
|
|
117
|
+
while (end > 0 && lines[end - 1].trim() === '')
|
|
118
|
+
end -= 1;
|
|
119
|
+
let start = 0;
|
|
120
|
+
for (let index = end - 1; index >= 0; index -= 1) {
|
|
121
|
+
if (lines[index].trim() === '') {
|
|
122
|
+
start = index + 1;
|
|
123
|
+
break;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (start === 0 || start >= end)
|
|
127
|
+
return lines.length;
|
|
128
|
+
return lines.slice(start, end).every((line) => TRAILER_LINE_RE.test(line)) ? start : lines.length;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* The `Reason:` a commit body records, read as a BLOCK (`dl-067` clause 2): the remainder of the
|
|
132
|
+
* `Reason:` line plus every following body line, up to (exclusive) git's trailing trailer paragraph or
|
|
133
|
+
* the end of the body. `null` when the body records no reason, or records a bare `Reason:` with no
|
|
134
|
+
* value — the shape git's cleanup leaves behind when an empty reason is written (bug-042 F2), which
|
|
135
|
+
* `parseApprovalMetadata` degrades around rather than treating as an absent approval.
|
|
136
|
+
*
|
|
137
|
+
* This replaces the first-line capture `/^Reason:\s*(.+)$/m` that preceded it, and that is a real
|
|
138
|
+
* change to how existing history reads: 79 of `main`'s 171 approve/reject commits (46%) carry a reason
|
|
139
|
+
* continuing past line one, and every one of them was silently halved. It is a recovery, not a
|
|
140
|
+
* reinterpretation — the text was always in the commit; only the reader dropped it.
|
|
141
|
+
*
|
|
142
|
+
* A generic `Key: value` line INSIDE the block is ordinary prose and does not end it; only a trailing
|
|
143
|
+
* paragraph made entirely of trailer lines does (dl-067 E5).
|
|
144
|
+
*/
|
|
145
|
+
function parseReasonBlock(body) {
|
|
146
|
+
const lines = body.replace(/\r\n?/g, '\n').split('\n');
|
|
147
|
+
const start = lines.findIndex((line) => REASON_KEY_RE.test(line));
|
|
148
|
+
if (start === -1)
|
|
149
|
+
return null;
|
|
150
|
+
const end = Math.max(trailerParagraphStart(lines), start + 1);
|
|
151
|
+
const block = [lines[start].replace(REASON_KEY_RE, ''), ...lines.slice(start + 1, end)].join('\n');
|
|
152
|
+
const normalized = normalizeReason(block);
|
|
153
|
+
return normalized === '' ? null : normalized;
|
|
154
|
+
}
|
|
155
|
+
/**
|
|
156
|
+
* The commit body's `Approver:` trailer line, or `null` when it has none — anchored to the body's
|
|
157
|
+
* FIRST non-empty line (`dl-067` clause 5). {@link formatMemoryCommitMessage} has always emitted it
|
|
158
|
+
* there, and it is the first body line in 171 of `main`'s 171 approve/reject commits (dl-067 E4), so
|
|
159
|
+
* anchoring costs no existing commit its approver while closing bug-042 F3 on the read side: an
|
|
160
|
+
* `Approver:` line appearing anywhere else is text some reason happens to contain, never an approval
|
|
161
|
+
* record. `./audit.ts` destructures the returned line into an identity — that shape is its concern;
|
|
162
|
+
* the line's POSITION is this module's.
|
|
163
|
+
*/
|
|
164
|
+
function parseApproverTrailerLine(body) {
|
|
165
|
+
const first = body
|
|
166
|
+
.replace(/\r\n?/g, '\n')
|
|
167
|
+
.split('\n')
|
|
168
|
+
.find((line) => line.trim() !== '');
|
|
169
|
+
return first !== undefined && APPROVER_KEY_RE.test(first) ? first : null;
|
|
170
|
+
}
|
|
171
|
+
/**
|
|
172
|
+
* Format a Memory transition commit message: the subject, then — only when an approver or reason is
|
|
173
|
+
* given — a blank line and the `Approver:` / `Reason:` lines in that order.
|
|
174
|
+
*
|
|
175
|
+
* The reason is emitted in its declared normal form and, when it carries a defect
|
|
176
|
+
* ({@link reasonDefect}), refused rather than written. The CLI boundary
|
|
177
|
+
* (`src/core/require-reason.ts`) already refuses the same values with the same messages at exit 2, so
|
|
178
|
+
* reaching this throw means a caller bypassed that boundary — it exists so no *future* caller can
|
|
179
|
+
* (dl-067 clause 5; bug-042 F2/F3).
|
|
180
|
+
*
|
|
181
|
+
* @throws `Error` when `ids` is empty: a transition commit always names what it moved.
|
|
182
|
+
* @throws `Error` when `reason` cannot be recorded in the trailer, carrying that defect's message.
|
|
183
|
+
*/
|
|
184
|
+
function formatMemoryCommitMessage(input) {
|
|
185
|
+
if (input.ids.length === 0) {
|
|
186
|
+
throw new Error('a Memory transition commit must name at least one id');
|
|
187
|
+
}
|
|
188
|
+
const defect = input.reason === undefined ? null : reasonDefect(input.reason);
|
|
189
|
+
if (defect !== null) {
|
|
190
|
+
throw new Error(reasonDefectMessage(defect));
|
|
191
|
+
}
|
|
192
|
+
const bracket = input.transition ? ` [${input.transition.from} ${ARROW} ${input.transition.to}]` : '';
|
|
193
|
+
const subject = `wf(${input.type}): ${input.op} ${input.ids.join(', ')}${bracket}`;
|
|
194
|
+
const body = [];
|
|
195
|
+
if (input.approver) {
|
|
196
|
+
body.push(`Approver: ${input.approver.name} <${input.approver.email}> (${input.approver.role})`);
|
|
197
|
+
}
|
|
198
|
+
if (input.reason !== undefined) {
|
|
199
|
+
body.push(`Reason: ${normalizeReason(input.reason)}`);
|
|
200
|
+
}
|
|
201
|
+
return body.length === 0 ? subject : `${subject}\n\n${body.join('\n')}`;
|
|
202
|
+
}
|
|
203
|
+
//# sourceMappingURL=commit-message.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commit-message.js","sourceRoot":"","sources":["../../src/memory/commit-message.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The git-backed Memory-entry store primitive (task-022-implement-memory-entries, P1.11,
|
|
3
|
+
* REQ-SYS-01/REQ-SYS-03, REQ-SEC-06) — the storage foundation `wingfoil memory add` (task-020) and
|
|
4
|
+
* `wingfoil memory submit` build their CLI/CoreResult surface on top of.
|
|
5
|
+
*
|
|
6
|
+
* This module composes three primitives that already exist and are NOT re-implemented here:
|
|
7
|
+
* - `resolveConfinedMemoryPath` (task-017-storage-confinement, `../storage/memory-path` — not
|
|
8
|
+
* re-exported by the `../storage` barrel, imported directly per that module's own convention)
|
|
9
|
+
* renders a type's `path` pattern against concrete values and refuses — throwing `StorageError`
|
|
10
|
+
* `E_PATH_ESCAPES_ROOT` — any resolution that would land outside the project root, BEFORE
|
|
11
|
+
* anything is written, judging the rendered string **and** its resolution on the filesystem
|
|
12
|
+
* (`task-105`, `bug-117`: a symlinked type directory leaves the project with no traversal
|
|
13
|
+
* anywhere in the string). Its message opens with the corrected, canonical REQ-SEC-06
|
|
14
|
+
* fit-criterion sentence — `'Memory entries must reside within the project root'` — and then
|
|
15
|
+
* names both spellings of the path, what the pattern rendered and where it really lands, because
|
|
16
|
+
* on the symlink case the two differing is the finding. The BDD `.feature` file's older "must
|
|
17
|
+
* reside under .wingfoil/memory/" wording is stale (see this task's Execution Notes for the
|
|
18
|
+
* reconciliation).
|
|
19
|
+
* - `writeDocument` (`../storage`) writes bytes only (mkdir-p).
|
|
20
|
+
* - `commitPaths` (`../storage`) stages exactly the one resolved path and produces exactly one
|
|
21
|
+
* commit — so calling {@link writeMemoryEntry} twice against the SAME `pattern`/`values` (i.e.
|
|
22
|
+
* the same target file, modified) yields two DISTINCT commits, with the file's prior content
|
|
23
|
+
* retrievable from git history via that file's own commit log — the P1.11 "each Memory entry is
|
|
24
|
+
* individually versioned" contract.
|
|
25
|
+
*
|
|
26
|
+
* Deliberately a throwing **library** primitive, not a `CoreResult`-wrapped `CORE_MODULES` operation:
|
|
27
|
+
* this task's scope is the reusable store primitive, not the `wingfoil memory add` CLI command or its
|
|
28
|
+
* `StorageError` → `CoreError` mapping — both of those are task-020's scope, which wires this
|
|
29
|
+
* primitive in (see the task's Execution Notes for that scoping decision).
|
|
30
|
+
*/
|
|
31
|
+
import type { CommitOptions } from '../storage';
|
|
32
|
+
/** The result of a single {@link writeMemoryEntry} call. */
|
|
33
|
+
export interface MemoryEntryWrite {
|
|
34
|
+
/** The absolute, confinement-verified path that was written (see `resolveConfinedMemoryPath`). */
|
|
35
|
+
readonly path: string;
|
|
36
|
+
/** The 40-hex sha of the single commit this write produced. */
|
|
37
|
+
readonly sha: string;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* Render `pattern` against `values` (per `memory.yaml`'s per-type `path` pattern,
|
|
41
|
+
* spec-001-memory-yaml-schema), confining the result to `root` (REQ-SEC-06), write `content` to that
|
|
42
|
+
* path, and commit exactly that one path as a single commit with `message` (REQ-SYS-01).
|
|
43
|
+
*
|
|
44
|
+
* @throws {@link ../storage/errors.StorageError} `E_PATH_ESCAPES_ROOT` when the resolved path would
|
|
45
|
+
* escape `root` — refused before any write, so a rejected call writes and commits nothing.
|
|
46
|
+
* @throws {@link ../storage/errors.StorageError} `E_TARGET_IS_SYMLINK` when the target itself is a
|
|
47
|
+
* symbolic link, dangling or live (`task-106`, `bug-120`): `writeDocument`'s `writeFileSync`
|
|
48
|
+
* follows one, so the bytes would land at the link's destination rather than at the path this
|
|
49
|
+
* function names — and through a *dangling* link the write used to succeed and commit. Refused in
|
|
50
|
+
* the same place, before the same write.
|
|
51
|
+
* @throws whatever `commitPaths`/git raises (e.g. no configured git identity) — callers that need a
|
|
52
|
+
* pre-flight identity check must call `requireGitIdentity` (`../core/git-identity`) themselves
|
|
53
|
+
* before invoking this primitive, same as every other mutating core operation.
|
|
54
|
+
*/
|
|
55
|
+
export declare function writeMemoryEntry(root: string, pattern: string, values: Record<string, string>, content: string, message: string, options?: CommitOptions): MemoryEntryWrite;
|
|
56
|
+
//# sourceMappingURL=entry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.d.ts","sourceRoot":"","sources":["../../src/memory/entry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6BG;AACH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC;AAIhD,4DAA4D;AAC5D,MAAM,WAAW,gBAAgB;IAC/B,kGAAkG;IAClG,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,+DAA+D;IAC/D,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;CACtB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EAC9B,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,aAAkB,GAC1B,gBAAgB,CAKlB"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.writeMemoryEntry = writeMemoryEntry;
|
|
4
|
+
const storage_1 = require("../storage");
|
|
5
|
+
const memory_path_1 = require("../storage/memory-path");
|
|
6
|
+
/**
|
|
7
|
+
* Render `pattern` against `values` (per `memory.yaml`'s per-type `path` pattern,
|
|
8
|
+
* spec-001-memory-yaml-schema), confining the result to `root` (REQ-SEC-06), write `content` to that
|
|
9
|
+
* path, and commit exactly that one path as a single commit with `message` (REQ-SYS-01).
|
|
10
|
+
*
|
|
11
|
+
* @throws {@link ../storage/errors.StorageError} `E_PATH_ESCAPES_ROOT` when the resolved path would
|
|
12
|
+
* escape `root` — refused before any write, so a rejected call writes and commits nothing.
|
|
13
|
+
* @throws {@link ../storage/errors.StorageError} `E_TARGET_IS_SYMLINK` when the target itself is a
|
|
14
|
+
* symbolic link, dangling or live (`task-106`, `bug-120`): `writeDocument`'s `writeFileSync`
|
|
15
|
+
* follows one, so the bytes would land at the link's destination rather than at the path this
|
|
16
|
+
* function names — and through a *dangling* link the write used to succeed and commit. Refused in
|
|
17
|
+
* the same place, before the same write.
|
|
18
|
+
* @throws whatever `commitPaths`/git raises (e.g. no configured git identity) — callers that need a
|
|
19
|
+
* pre-flight identity check must call `requireGitIdentity` (`../core/git-identity`) themselves
|
|
20
|
+
* before invoking this primitive, same as every other mutating core operation.
|
|
21
|
+
*/
|
|
22
|
+
function writeMemoryEntry(root, pattern, values, content, message, options = {}) {
|
|
23
|
+
const path = (0, memory_path_1.resolveConfinedMemoryPath)(root, pattern, values);
|
|
24
|
+
(0, storage_1.writeDocument)(path, content);
|
|
25
|
+
const sha = (0, storage_1.commitPaths)(root, [path], message, options);
|
|
26
|
+
return { path, sha };
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=entry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"entry.js","sourceRoot":"","sources":["../../src/memory/entry.ts"],"names":[],"mappings":";;AA0DA,4CAYC;AAvCD,wCAAwD;AACxD,wDAAmE;AAUnE;;;;;;;;;;;;;;;GAeG;AACH,SAAgB,gBAAgB,CAC9B,IAAY,EACZ,OAAe,EACf,MAA8B,EAC9B,OAAe,EACf,OAAe,EACf,UAAyB,EAAE;IAE3B,MAAM,IAAI,GAAG,IAAA,uCAAyB,EAAC,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;IAC9D,IAAA,uBAAa,EAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IAC7B,MAAM,GAAG,GAAG,IAAA,qBAAW,EAAC,IAAI,EAAE,CAAC,IAAI,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACxD,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC;AACvB,CAAC"}
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Set top-level `key` to the string `value`, serialized YAML-safely. An existing entry is replaced as a
|
|
3
|
+
* whole — continuation lines, block-scalar body or multi-line quoted value included. A `# comment` on
|
|
4
|
+
* the key line is kept when the old value ended on that line; the line ending of the key line is kept.
|
|
5
|
+
* An absent key is appended after the last non-blank frontmatter line, with the document's line ending.
|
|
6
|
+
*
|
|
7
|
+
* @throws `Error` when the document has no frontmatter block.
|
|
8
|
+
*/
|
|
9
|
+
export declare function setFrontmatterField(content: string, key: string, value: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Remove top-level `key` together with every line its value spans (rules in the module doc). Blank
|
|
12
|
+
* lines and comments that follow the value belong to the parent mapping and are kept. Returns `content`
|
|
13
|
+
* unchanged when the key is absent.
|
|
14
|
+
*
|
|
15
|
+
* @throws `Error` when the document has no frontmatter block.
|
|
16
|
+
*/
|
|
17
|
+
export declare function removeFrontmatterField(content: string, key: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* The post-condition of a frontmatter edit, checked by re-parsing rather than by trusting the editor.
|
|
20
|
+
* `expected` maps each field the operation owns to its required value (`undefined` = must be absent).
|
|
21
|
+
* Returns the problems found, empty when the edit is sound:
|
|
22
|
+
*
|
|
23
|
+
* - the rendered document has no frontmatter, or it does not parse;
|
|
24
|
+
* - an owned field does not have its expected value, or is still present when it should be removed;
|
|
25
|
+
* - any **other** field's parsed value differs from `before` — an edit leaked into a field it does not own.
|
|
26
|
+
*
|
|
27
|
+
* Deterministic (REQ-SYS-07): owned fields in `expected`'s order, then other fields sorted by name.
|
|
28
|
+
*/
|
|
29
|
+
export declare function verifyFrontmatterEdit(before: string, after: string, expected: Readonly<Record<string, string | undefined>>): string[];
|
|
30
|
+
/**
|
|
31
|
+
* How much of a document an operation is entitled to change (task-088, `bug-076`), per
|
|
32
|
+
* `spec-010-memory-frontmatter-schema` § "Field-write ownership":
|
|
33
|
+
*
|
|
34
|
+
* - `declared-fields-only` — the operation owns `status` (plus `rejection_reason` on `memory.reject`)
|
|
35
|
+
* and **nothing else**: no other frontmatter field, and not one byte of the body. This is
|
|
36
|
+
* `memory.approve`, `memory.reject` and `memory.deprecate`.
|
|
37
|
+
* - `carries-content` — the operation is defined as filling content *and* moving state, so the body
|
|
38
|
+
* and the type's other frontmatter fields may legitimately change. This is `memory.submit` alone,
|
|
39
|
+
* and the asymmetry is deliberate rather than an oversight: an approval that carried a body would
|
|
40
|
+
* attest, under an approver's name, to content no commit subject mentions.
|
|
41
|
+
*/
|
|
42
|
+
export type DocumentScope = 'declared-fields-only' | 'carries-content';
|
|
43
|
+
/**
|
|
44
|
+
* The post-condition of a whole-document edit: {@link verifyFrontmatterEdit}'s frontmatter rules plus
|
|
45
|
+
* the body, gated by `scope`. Returns the problems found, empty when the edit is within scope.
|
|
46
|
+
*
|
|
47
|
+
* Under `carries-content` only the `expected` fields are checked — every other field and the body are
|
|
48
|
+
* the operation's to write. Under `declared-fields-only` an unowned field or a changed body is a
|
|
49
|
+
* problem, which is the rule `bug-076` showed nothing was enforcing.
|
|
50
|
+
*
|
|
51
|
+
* Deterministic (REQ-SYS-07): owned fields in `expected`'s order, then other fields sorted by name,
|
|
52
|
+
* then the body.
|
|
53
|
+
*/
|
|
54
|
+
export declare function verifyDocumentEdit(before: string, after: string, expected: Readonly<Record<string, string | undefined>>, scope: DocumentScope): string[];
|
|
55
|
+
/**
|
|
56
|
+
* Name, in a form a person can act on, every way `after` differs from `before` — the frontmatter
|
|
57
|
+
* fields whose parsed value moved, and whether the body moved. `before` is `null` when the document
|
|
58
|
+
* does not exist at the revision being compared against.
|
|
59
|
+
*
|
|
60
|
+
* This is the *reporting* half of {@link verifyDocumentEdit}: the verifier answers "is this edit in
|
|
61
|
+
* scope", this answers "so what exactly is in the way". A difference that changes no parsed value and
|
|
62
|
+
* no body byte — a reordered comment, a requoted scalar — is still a difference git will commit, so
|
|
63
|
+
* it is reported as such rather than dropped.
|
|
64
|
+
*
|
|
65
|
+
* Deterministic (REQ-SYS-07): fields sorted by name, then the frontmatter-text fallback, then the body.
|
|
66
|
+
*/
|
|
67
|
+
export declare function describeDocumentChanges(before: string | null, after: string): string[];
|
|
68
|
+
//# sourceMappingURL=frontmatter-edit.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-edit.d.ts","sourceRoot":"","sources":["../../src/memory/frontmatter-edit.ts"],"names":[],"mappings":"AAwKA;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAsBvF;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAK3E;AAeD;;;;;;;;;;GAUG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,GAAG,MAAM,EAAE,CAOrI;AAkCD;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,aAAa,GAAG,sBAAsB,GAAG,iBAAiB,CAAC;AAEvE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,MAAM,EAAE,MAAM,EACd,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,CAAC,EACtD,KAAK,EAAE,aAAa,GACnB,MAAM,EAAE,CAYV;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,CAqBtF"}
|