@codyswann/lisa 3.47.4 → 3.47.6
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/all/copy-overwrite/scripts/lib/gate-failure-diagnosis.mjs +270 -0
- package/all/copy-overwrite/scripts/lisa-gates.mjs +30 -0
- package/all/copy-overwrite/scripts/lisa-run-gates.mjs +294 -34
- package/all/copy-overwrite/scripts/lisa-schema-validate.mjs +126 -32
- package/all/copy-overwrite/scripts/lisa-work-item.mjs +83 -26
- package/dist/configs/eslint/expo.d.ts +50 -1
- package/dist/configs/eslint/expo.d.ts.map +1 -1
- package/dist/configs/eslint/expo.js +86 -5
- package/dist/configs/eslint/expo.js.map +1 -1
- package/dist/core/downstream-names.d.ts +83 -0
- package/dist/core/downstream-names.d.ts.map +1 -0
- package/dist/core/downstream-names.js +289 -0
- package/dist/core/downstream-names.js.map +1 -0
- package/dist/core/downstream-references.d.ts +21 -6
- package/dist/core/downstream-references.d.ts.map +1 -1
- package/dist/core/downstream-references.js +19 -16
- package/dist/core/downstream-references.js.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.d.ts.map +1 -1
- package/dist/core/lisa-owned-hash-ledger.js +16 -0
- package/dist/core/lisa-owned-hash-ledger.js.map +1 -1
- package/dist/core/upstream-evidence-manifest.d.ts.map +1 -1
- package/dist/core/upstream-evidence-manifest.js +23 -10
- package/dist/core/upstream-evidence-manifest.js.map +1 -1
- package/dist/migrations/ensure-tsconfig-local-includes.d.ts +1 -1
- package/dist/migrations/ensure-tsconfig-local-includes.js +1 -1
- package/expo/copy-overwrite/eslint.config.ts +9 -0
- package/expo/copy-overwrite/eslint.expo.ts +92 -4
- package/package.json +5 -2
- package/plugins/lisa/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa/rules/reference/design-value-binding.md +4 -0
- package/plugins/lisa-agy/plugin.json +1 -1
- package/plugins/lisa-cdk/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-agy/plugin.json +1 -1
- package/plugins/lisa-cdk-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cdk-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-copilot/rules/reference/design-value-binding.md +4 -0
- package/plugins/lisa-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-cursor/rules/design-value-binding-reference.mdc +4 -0
- package/plugins/lisa-expo/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-agy/plugin.json +1 -1
- package/plugins/lisa-expo-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-expo-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-agy/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-harper-fabric-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-agy/plugin.json +1 -1
- package/plugins/lisa-nestjs-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-nestjs-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-agy/plugin.json +1 -1
- package/plugins/lisa-openclaw-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-openclaw-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-agy/plugin.json +1 -1
- package/plugins/lisa-phaser-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-phaser-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-agy/plugin.json +1 -1
- package/plugins/lisa-rails-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-rails-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-agy/plugin.json +1 -1
- package/plugins/lisa-typescript-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-typescript-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki/.codex-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-agy/plugin.json +1 -1
- package/plugins/lisa-wiki-copilot/.claude-plugin/plugin.json +1 -1
- package/plugins/lisa-wiki-cursor/.claude-plugin/plugin.json +1 -1
- package/plugins/src/base/rules/reference/design-value-binding.md +4 -0
- package/scripts/lisa-mutation.mjs +13 -0
- package/typescript/copy-contents/.husky/pre-push +7 -1
- package/typescript/copy-overwrite/scripts/lisa-mutation.mjs +496 -122
- package/typescript/package-lisa/package.lisa.json +1 -0
|
@@ -12,11 +12,26 @@
|
|
|
12
12
|
* keyword it does not implement**, so a schema can never silently validate less
|
|
13
13
|
* than it claims: an unsupported keyword is a validator error, not a pass.
|
|
14
14
|
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
* `additionalProperties`
|
|
18
|
-
*
|
|
19
|
-
*
|
|
15
|
+
* That promise is enforced on a keyword's FORM as well as its name. A name-only
|
|
16
|
+
* allowlist let four keywords through and then dropped them —
|
|
17
|
+
* `additionalProperties` as a subschema, siblings beside a `$ref`,
|
|
18
|
+
* `items: false`, a string `required` — each a schema validating less than it
|
|
19
|
+
* says, which is the very outcome the allowlist exists to prevent. Every
|
|
20
|
+
* supported keyword therefore declares the shape it must be written in
|
|
21
|
+
* (`KEYWORD_FORMS`), and any other shape is a validator error.
|
|
22
|
+
*
|
|
23
|
+
* Refusing an unimplemented form rather than implementing it is deliberate.
|
|
24
|
+
* Implementing subschema `additionalProperties` and `$ref` siblings would grow
|
|
25
|
+
* a dependency-free validator into a general one, which this module declines to
|
|
26
|
+
* be; refusing is both smaller and the behaviour the header already promises.
|
|
27
|
+
*
|
|
28
|
+
* Supported: `type` (a single name or a non-empty array of names), `const`,
|
|
29
|
+
* `enum` (a non-empty array), `required` (an array of names), `properties` (an
|
|
30
|
+
* object of subschemas), `additionalProperties` (a boolean), `items` (a
|
|
31
|
+
* subschema object), `minLength`, `minimum` (numbers), `pattern` (a string),
|
|
32
|
+
* `$ref` (a local `#/$defs/<name>` string, with no validating siblings),
|
|
33
|
+
* `$defs`, plus the annotation-only keywords `$schema`, `$id`, `title`,
|
|
34
|
+
* `description`.
|
|
20
35
|
* @module scripts/lisa-schema-validate
|
|
21
36
|
*/
|
|
22
37
|
|
|
@@ -31,20 +46,61 @@ const ANNOTATION_KEYWORDS = new Set([
|
|
|
31
46
|
"default",
|
|
32
47
|
]);
|
|
33
48
|
|
|
34
|
-
/**
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
49
|
+
/**
|
|
50
|
+
* Whether a value is a plain JSON object — the shape a subschema takes.
|
|
51
|
+
* @param {unknown} value - Value to test
|
|
52
|
+
* @returns {boolean} Whether it is a non-null, non-array object
|
|
53
|
+
*/
|
|
54
|
+
function isSchemaObject(value) {
|
|
55
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* The keywords this validator implements, each with the FORM it must be written
|
|
60
|
+
* in and a description of that form for the error message.
|
|
61
|
+
*
|
|
62
|
+
* The form is the load-bearing half. A name-only allowlist accepts
|
|
63
|
+
* `additionalProperties: {"type": "string"}`, `items: false` and
|
|
64
|
+
* `required: ""` and then applies none of them, which is a schema silently
|
|
65
|
+
* validating less than it claims — the exact failure the allowlist exists to
|
|
66
|
+
* prevent, reached through the one door nobody checked.
|
|
67
|
+
*
|
|
68
|
+
* `const` takes any JSON value, so its form is unconstrained; that is a real
|
|
69
|
+
* property of the keyword, not an omission.
|
|
70
|
+
*/
|
|
71
|
+
const KEYWORD_FORMS = Object.freeze({
|
|
72
|
+
type: {
|
|
73
|
+
accepts: value =>
|
|
74
|
+
typeof value === "string" ||
|
|
75
|
+
(Array.isArray(value) &&
|
|
76
|
+
value.length > 0 &&
|
|
77
|
+
value.every(entry => typeof entry === "string")),
|
|
78
|
+
form: "a type name or a non-empty array of type names",
|
|
79
|
+
},
|
|
80
|
+
const: { accepts: () => true, form: "any JSON value" },
|
|
81
|
+
enum: {
|
|
82
|
+
accepts: value => Array.isArray(value) && value.length > 0,
|
|
83
|
+
form: "a non-empty array",
|
|
84
|
+
},
|
|
85
|
+
required: {
|
|
86
|
+
accepts: value =>
|
|
87
|
+
Array.isArray(value) && value.every(entry => typeof entry === "string"),
|
|
88
|
+
form: "an array of property names",
|
|
89
|
+
},
|
|
90
|
+
properties: { accepts: isSchemaObject, form: "an object of subschemas" },
|
|
91
|
+
additionalProperties: {
|
|
92
|
+
accepts: value => typeof value === "boolean",
|
|
93
|
+
form: "a boolean (a subschema is not implemented)",
|
|
94
|
+
},
|
|
95
|
+
items: {
|
|
96
|
+
accepts: isSchemaObject,
|
|
97
|
+
form: "a subschema object (a boolean is not implemented)",
|
|
98
|
+
},
|
|
99
|
+
minLength: { accepts: value => typeof value === "number", form: "a number" },
|
|
100
|
+
minimum: { accepts: value => typeof value === "number", form: "a number" },
|
|
101
|
+
pattern: { accepts: value => typeof value === "string", form: "a string" },
|
|
102
|
+
$ref: { accepts: value => typeof value === "string", form: "a string" },
|
|
103
|
+
});
|
|
48
104
|
|
|
49
105
|
/**
|
|
50
106
|
* JSON type name for a value, using JSON Schema's vocabulary.
|
|
@@ -83,19 +139,61 @@ function resolveRef(ref, root) {
|
|
|
83
139
|
}
|
|
84
140
|
|
|
85
141
|
/**
|
|
86
|
-
* Refuse any keyword this validator does not implement.
|
|
142
|
+
* Refuse any keyword this validator does not implement, in name or in form.
|
|
87
143
|
* @param {object} schema - Subschema to inspect
|
|
88
144
|
* @param {string} instancePath - JSON-pointer-ish path for messages
|
|
89
145
|
* @returns {void}
|
|
90
|
-
* @throws {Error} When the subschema uses an unimplemented keyword
|
|
146
|
+
* @throws {Error} When the subschema uses an unimplemented keyword or form
|
|
91
147
|
*/
|
|
92
148
|
function assertSupportedKeywords(schema, instancePath) {
|
|
149
|
+
const where = instancePath || "/";
|
|
93
150
|
for (const keyword of Object.keys(schema)) {
|
|
94
|
-
if (
|
|
151
|
+
if (ANNOTATION_KEYWORDS.has(keyword)) {
|
|
152
|
+
continue;
|
|
153
|
+
}
|
|
154
|
+
const expected = KEYWORD_FORMS[keyword];
|
|
155
|
+
if (!expected) {
|
|
95
156
|
throw new Error(
|
|
96
|
-
`schema at ${
|
|
157
|
+
`schema at ${where} uses unsupported keyword "${keyword}"`
|
|
97
158
|
);
|
|
98
159
|
}
|
|
160
|
+
if (!expected.accepts(schema[keyword])) {
|
|
161
|
+
throw new Error(
|
|
162
|
+
`schema at ${where} writes "${keyword}" in an unimplemented form; expected ${expected.form}`
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
assertNoRefSiblings(schema, where);
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* Refuse a `$ref` that carries validating siblings.
|
|
171
|
+
*
|
|
172
|
+
* `validateNode` validates against the resolved target and returns, discarding
|
|
173
|
+
* every sibling keyword — so `{"$ref": ..., "enum": [...]}` applied the target
|
|
174
|
+
* and dropped the enum, reporting a violating value as valid. In JSON Schema
|
|
175
|
+
* 2020-12 siblings ARE applied, so ignoring them is a spec deviation on top of
|
|
176
|
+
* a silent under-validation.
|
|
177
|
+
*
|
|
178
|
+
* Annotation-only siblings are fine and common: `{"$ref": ..., "description":
|
|
179
|
+
* ...}` carries no validation semantics, and refusing it would be a false
|
|
180
|
+
* positive on ordinary schemas.
|
|
181
|
+
* @param {object} schema - Subschema to inspect
|
|
182
|
+
* @param {string} where - Location for the message
|
|
183
|
+
* @returns {void}
|
|
184
|
+
* @throws {Error} When a validating keyword sits beside a `$ref`
|
|
185
|
+
*/
|
|
186
|
+
function assertNoRefSiblings(schema, where) {
|
|
187
|
+
if (!("$ref" in schema)) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
const siblings = Object.keys(schema).filter(
|
|
191
|
+
keyword => keyword !== "$ref" && !ANNOTATION_KEYWORDS.has(keyword)
|
|
192
|
+
);
|
|
193
|
+
if (siblings.length > 0) {
|
|
194
|
+
throw new Error(
|
|
195
|
+
`schema at ${where} places validating keyword(s) ${siblings.map(entry => `"${entry}"`).join(", ")} beside a "$ref"; $ref siblings are not implemented`
|
|
196
|
+
);
|
|
99
197
|
}
|
|
100
198
|
}
|
|
101
199
|
|
|
@@ -120,6 +218,11 @@ function typeAccepts(declared, actualType) {
|
|
|
120
218
|
* `typeof === "string"` test entirely: the keyword passed the allowlist, so the
|
|
121
219
|
* module's central promise — an unimplemented keyword is an error, never a
|
|
122
220
|
* silent pass — was broken for the one form nobody checked.
|
|
221
|
+
*
|
|
222
|
+
* Any THIRD form is refused before this function is reached: `KEYWORD_FORMS`
|
|
223
|
+
* declares what `type` may be written as and `assertSupportedKeywords` runs
|
|
224
|
+
* first, so the two branches below are the only two that exist. Repeating the
|
|
225
|
+
* check here would be unreachable code claiming to be a guard.
|
|
123
226
|
* @param {object} schema - Subschema to apply
|
|
124
227
|
* @param {string} actualType - The observed type
|
|
125
228
|
* @param {string} where - Location for the message
|
|
@@ -133,15 +236,6 @@ function typeError(schema, actualType, where) {
|
|
|
133
236
|
: `${where}: expected type ${declared}, got ${actualType}`;
|
|
134
237
|
}
|
|
135
238
|
if (declared === undefined) return null;
|
|
136
|
-
if (
|
|
137
|
-
!Array.isArray(declared) ||
|
|
138
|
-
declared.length === 0 ||
|
|
139
|
-
!declared.every(entry => typeof entry === "string")
|
|
140
|
-
) {
|
|
141
|
-
throw new Error(
|
|
142
|
-
`schema at ${where} declares a "type" that is neither a name nor an array of names`
|
|
143
|
-
);
|
|
144
|
-
}
|
|
145
239
|
return declared.some(entry => typeAccepts(entry, actualType))
|
|
146
240
|
? null
|
|
147
241
|
: `${where}: expected type ${declared.join(" or ")}, got ${actualType}`;
|
|
@@ -1856,9 +1856,10 @@ const SCOPE_ORDER = [OUTSIDE_THIS_PR, IN_THIS_PR];
|
|
|
1856
1856
|
/**
|
|
1857
1857
|
* Validate the commits, keeping a refusal rather than aborting the run.
|
|
1858
1858
|
*
|
|
1859
|
-
* The pull-request gate checks
|
|
1859
|
+
* The pull-request gate checks several separate things and used to stop at the
|
|
1860
1860
|
* first unmet one, so each CI cycle revealed exactly one requirement. It knew
|
|
1861
|
-
* the rest at the same moment; it was simply not saying.
|
|
1861
|
+
* the rest at the same moment; it was simply not saying. See `gateSummary` for
|
|
1862
|
+
* the full count, which is five and was itself miscounted as four.
|
|
1862
1863
|
* @param {string[]} commits Commits in the pull request range.
|
|
1863
1864
|
* @returns {{result?: object, error?: Error}} Outcome, never a throw.
|
|
1864
1865
|
*/
|
|
@@ -1914,37 +1915,82 @@ function backlinkAdvice(ref, prUrl, contract) {
|
|
|
1914
1915
|
}
|
|
1915
1916
|
|
|
1916
1917
|
/**
|
|
1917
|
-
* The
|
|
1918
|
-
*
|
|
1919
|
-
* They are
|
|
1920
|
-
* different moments — so clearing
|
|
1921
|
-
* reader has no way to learn the
|
|
1922
|
-
* agents in one day each satisfied three and were surprised by
|
|
1923
|
-
*
|
|
1924
|
-
*
|
|
1925
|
-
*
|
|
1926
|
-
*
|
|
1927
|
-
*
|
|
1928
|
-
*
|
|
1929
|
-
*
|
|
1918
|
+
* The FIVE gates a work item passes on its way to merged, and when each bites.
|
|
1919
|
+
*
|
|
1920
|
+
* They are five separate checks, enforced in five different places, at five
|
|
1921
|
+
* different moments — so clearing four says nothing about the fifth, and the
|
|
1922
|
+
* reader has no way to learn the fifth exists until it goes red. Measured: two
|
|
1923
|
+
* agents in one day each satisfied three of them and were surprised by another,
|
|
1924
|
+
* on a pull request that was otherwise finished.
|
|
1925
|
+
*
|
|
1926
|
+
* This said FOUR until #2681 counted them properly. Gates 3 and 4 shared a
|
|
1927
|
+
* line — "every commit AND the pull-request body carry ONE matching trailer" —
|
|
1928
|
+
* which reads as one requirement and is two: the commit-msg hook enforces the
|
|
1929
|
+
* message, and a separate check enforces the BODY. An operator whose commits
|
|
1930
|
+
* carried the trailer read that line as cleared. Measured: an agent went
|
|
1931
|
+
* BLOCKED on "No Work-Item trailer anywhere in the pull request body" holding a
|
|
1932
|
+
* commit that carried the trailer, an item in the claimed role, and a backlink
|
|
1933
|
+
* already posted — four of the five satisfied, and the fifth invisible until CI
|
|
1934
|
+
* said so, one cycle later.
|
|
1935
|
+
*
|
|
1936
|
+
* `Closes owner/repo#N` is called out by name because it is the substitution a
|
|
1937
|
+
* reader reaches for: it closes the item on merge and satisfies nothing here.
|
|
1938
|
+
*
|
|
1939
|
+
* Listing all five in the report an operator actually reads costs six lines and
|
|
1940
|
+
* turns a sequence of surprises into one checklist. The role NAMES come from
|
|
1941
|
+
* the resolved contract rather than from Lisa's own defaults, because a project
|
|
1942
|
+
* configures its own — lifecycle is a workflow STATE on Jira and Linear and a
|
|
1943
|
+
* LABEL only on GitHub — and a summary that confidently names the wrong label
|
|
1944
|
+
* is worse than none.
|
|
1930
1945
|
* @param {object} contract Resolved tracker contract.
|
|
1931
1946
|
* @returns {string} The checklist.
|
|
1932
1947
|
*/
|
|
1933
1948
|
function gateSummary(contract) {
|
|
1934
1949
|
const backlink =
|
|
1935
1950
|
contract.verify === "full"
|
|
1936
|
-
? `
|
|
1937
|
-
: `
|
|
1951
|
+
? `5. the item carries a managed \`${MARKER}\` backlink comment to this pull request — checked at push once a pull request exists, again at CI time, and only under workItem.verify "full"`
|
|
1952
|
+
: `5. the tracker backlink is NOT required here: workItem.verify is "trailer", so this run contacted no tracker`;
|
|
1938
1953
|
return [
|
|
1939
1954
|
"",
|
|
1940
|
-
"All
|
|
1955
|
+
"All five gates, and when each one bites:",
|
|
1941
1956
|
` 1. the item carries the ready role "${contract.lifecycle.ready}" — required before the work may be created or claimed`,
|
|
1942
1957
|
` 2. the item carries the claimed role "${contract.lifecycle.claimed}" — required by the commit-msg hook, on every single commit`,
|
|
1943
|
-
" 3. every commit
|
|
1958
|
+
" 3. every commit message carries ONE matching `Work-Item:` trailer — required by the commit-msg hook, on every single commit",
|
|
1959
|
+
" 4. the pull-request BODY carries that same `Work-Item:` trailer — a SEPARATE check from gate 3, run at push once a pull request exists and again at CI time; `Closes owner/repo#N` does NOT satisfy it",
|
|
1944
1960
|
` ${backlink}`,
|
|
1945
1961
|
].join("\n");
|
|
1946
1962
|
}
|
|
1947
1963
|
|
|
1964
|
+
/**
|
|
1965
|
+
* The same refusal, with the whole checklist appended.
|
|
1966
|
+
*
|
|
1967
|
+
* Used where a check knows only its OWN gate — the commit-msg hook, and a push
|
|
1968
|
+
* with no pull request yet — so that the gates it cannot check are still named
|
|
1969
|
+
* at the earliest moment they are known, rather than at the next moment they
|
|
1970
|
+
* happen to be enforced.
|
|
1971
|
+
*
|
|
1972
|
+
* Re-resolving the contract here is safe rather than lucky, and the reason is
|
|
1973
|
+
* worth writing down because the obvious defensive try/catch around it is DEAD
|
|
1974
|
+
* CODE. Every caller reaches this only after a refusal, and both refusal paths
|
|
1975
|
+
* — `validateMessage` and `validateCommits` — call `trackerContract()` as their
|
|
1976
|
+
* first real step. So either the contract resolves, and resolving it a second
|
|
1977
|
+
* time from the same files resolves again; or it does not, in which case the
|
|
1978
|
+
* refusal being decorated IS the configuration error and re-resolving rethrows
|
|
1979
|
+
* that identical error. There is no third case, and no input reaches a branch
|
|
1980
|
+
* where the original message could be lost.
|
|
1981
|
+
*
|
|
1982
|
+
* That was established by mutation: a guard clause was written here first, with
|
|
1983
|
+
* a test for it, and deleting the guard left the test passing. An unreachable
|
|
1984
|
+
* branch and a test that cannot fail are the same defect wearing two hats.
|
|
1985
|
+
* @param {Error} error The refusal as raised.
|
|
1986
|
+
* @returns {Error} The refusal, with the checklist appended.
|
|
1987
|
+
*/
|
|
1988
|
+
function withGateSummary(error) {
|
|
1989
|
+
return new TrackingError(
|
|
1990
|
+
`${error.message}\n${gateSummary(trackerContract())}`
|
|
1991
|
+
);
|
|
1992
|
+
}
|
|
1993
|
+
|
|
1948
1994
|
/**
|
|
1949
1995
|
* One refusal naming every unmet requirement, unrecoverable ones first.
|
|
1950
1996
|
* @param {object[]} findings Unmet requirements.
|
|
@@ -2366,9 +2412,18 @@ function validateCommit(args) {
|
|
|
2366
2412
|
const file = args[0];
|
|
2367
2413
|
if (!file)
|
|
2368
2414
|
throw new TrackingError("validate-commit requires the commit message file");
|
|
2369
|
-
|
|
2370
|
-
|
|
2371
|
-
|
|
2415
|
+
let result;
|
|
2416
|
+
try {
|
|
2417
|
+
result = validateMessage(readFileSync(file, "utf8"), {
|
|
2418
|
+
allowInProgressMerge: true,
|
|
2419
|
+
});
|
|
2420
|
+
} catch (error) {
|
|
2421
|
+
// The commit-msg hook is the EARLIEST moment an operator meets any of this,
|
|
2422
|
+
// and all five gates are knowable here even though only two are enforced
|
|
2423
|
+
// here. Withholding the other three buys nothing and costs a CI cycle each.
|
|
2424
|
+
if (!(error instanceof TrackingError)) throw error;
|
|
2425
|
+
throw withGateSummary(error);
|
|
2426
|
+
}
|
|
2372
2427
|
console.log(`WORK_ITEM_TRACKING_OK ${result.exempt ?? result.ref}`);
|
|
2373
2428
|
}
|
|
2374
2429
|
|
|
@@ -2378,11 +2433,13 @@ function validatePush(args) {
|
|
|
2378
2433
|
const outcome = commitOutcome(parsePushLines(input, remote));
|
|
2379
2434
|
const pr = currentPullRequest();
|
|
2380
2435
|
if (!pr) {
|
|
2381
|
-
// No pull request means
|
|
2382
|
-
//
|
|
2383
|
-
|
|
2436
|
+
// No pull request means gates 4 and 5 cannot be CHECKED here. They are
|
|
2437
|
+
// still perfectly well KNOWN here, and this is the last local moment before
|
|
2438
|
+
// CI — so the checklist goes out either way. Saying nothing is precisely
|
|
2439
|
+
// what made those two gates separate CI-cycle surprises (#2681).
|
|
2440
|
+
if (outcome.error) throw withGateSummary(outcome.error);
|
|
2384
2441
|
console.log(
|
|
2385
|
-
`WORK_ITEM_TRACKING_OK ${outcome.result.relevant} commit(s); no pull request exists yet, CI will verify
|
|
2442
|
+
`WORK_ITEM_TRACKING_OK ${outcome.result.relevant} commit(s); no pull request exists yet, so gates 4 and 5 could not be checked here — CI will verify both${gateSummary(outcome.result.contract)}`
|
|
2386
2443
|
);
|
|
2387
2444
|
return;
|
|
2388
2445
|
}
|
|
@@ -1,5 +1,46 @@
|
|
|
1
1
|
import { defaultIgnores, defaultThresholds, getBaseConfigs, getBaseLanguageOptions, getSharedRules } from "./typescript.js";
|
|
2
2
|
export { defaultIgnores, defaultThresholds, getBaseConfigs, getBaseLanguageOptions, getSharedRules, };
|
|
3
|
+
/**
|
|
4
|
+
* Axes a project declares typed, read from its own `.lisa.config.json`.
|
|
5
|
+
*
|
|
6
|
+
* #2807: the design-value rule shipped installed, severity `"off"`, and arming
|
|
7
|
+
* it needed a severity AND a `typedAxes` option hand-written into
|
|
8
|
+
* `eslint.config.local.ts`. Nothing carried `design.tokens.axes` from
|
|
9
|
+
* `.lisa.config.json` to the rule, so a project could declare every axis,
|
|
10
|
+
* install the policy, pass every test, and enforce nothing.
|
|
11
|
+
*
|
|
12
|
+
* It is read HERE, at ESLint **config** load, rather than inside the rule at
|
|
13
|
+
* **rule** load. That distinction is what makes it unremarkable: the managed
|
|
14
|
+
* `eslint.config.ts` already reads `eslint.thresholds.json` and
|
|
15
|
+
* `eslint.ignore.config.json` from disk at exactly this moment, so this adds no
|
|
16
|
+
* new class of behaviour and gives ESLint's config cache nothing to fight. A
|
|
17
|
+
* rule reading project files on every `create()` would do both.
|
|
18
|
+
*
|
|
19
|
+
* It also needs no generation step, which is what the alternative — emitting
|
|
20
|
+
* rule options into a generated file during `lisa apply` — would have cost. A
|
|
21
|
+
* generated file can go stale against the config it was generated from; a value
|
|
22
|
+
* read at load cannot.
|
|
23
|
+
* @param projectRoot - Directory holding the project's `.lisa.config.json`.
|
|
24
|
+
* @returns The declared axes, or an empty list when none are declared.
|
|
25
|
+
* @throws {TypeError} When `design.tokens.axes` is present but is not a list of strings.
|
|
26
|
+
*/
|
|
27
|
+
export declare function readTypedAxes(projectRoot: string): string[];
|
|
28
|
+
/**
|
|
29
|
+
* The `ui-standards/no-unbound-design-value` entry for a set of typed axes.
|
|
30
|
+
*
|
|
31
|
+
* Silence-by-default is deliberate and unchanged: an axis with no published
|
|
32
|
+
* variable collection behind it has no token to bind to, and a rule that fires
|
|
33
|
+
* on every project is a rule that gets switched off. What changes is that
|
|
34
|
+
* declaring an axis is now SUFFICIENT to arm it. Previously nothing was.
|
|
35
|
+
*
|
|
36
|
+
* An axis name outside the rule's fixed vocabulary is passed through rather
|
|
37
|
+
* than filtered out, so ESLint's own schema validation rejects it by name. A
|
|
38
|
+
* filter would turn a typo into silent non-enforcement, which is the defect
|
|
39
|
+
* this function exists to remove.
|
|
40
|
+
* @param typedAxes - Axes the project declares typed.
|
|
41
|
+
* @returns `"off"` when none are declared, an armed error entry otherwise.
|
|
42
|
+
*/
|
|
43
|
+
export declare function getDesignValueBindingRule(typedAxes: readonly string[]): import("eslint").Linter.RuleEntry;
|
|
3
44
|
/**
|
|
4
45
|
* Creates the Expo ESLint configuration.
|
|
5
46
|
* @param {object} options - Configuration options
|
|
@@ -7,9 +48,10 @@ export { defaultIgnores, defaultThresholds, getBaseConfigs, getBaseLanguageOptio
|
|
|
7
48
|
* @param {string[]} [options.ignorePatterns] - Patterns to ignore
|
|
8
49
|
* @param {object} [options.thresholds] - Threshold overrides
|
|
9
50
|
* @param {string} [options.sourceRoot] - Prefix for source-relative file globs (e.g. `"src/"` for the SDK 55+/56 `/src` convention; defaults to `""`)
|
|
51
|
+
* @param {string[]} [options.typedAxes] - Axes the project declares typed, mirroring `design.tokens.axes`. Empty leaves the design-value rule off.
|
|
10
52
|
* @returns {import("eslint").Linter.Config[]} ESLint flat config array
|
|
11
53
|
*/
|
|
12
|
-
export declare function getExpoConfig({ tsconfigRootDir, ignorePatterns, thresholds, sourceRoot, }: {
|
|
54
|
+
export declare function getExpoConfig({ tsconfigRootDir, ignorePatterns, thresholds, sourceRoot, typedAxes, }: {
|
|
13
55
|
tsconfigRootDir: string;
|
|
14
56
|
ignorePatterns?: string[];
|
|
15
57
|
thresholds?: typeof defaultThresholds;
|
|
@@ -21,5 +63,12 @@ export declare function getExpoConfig({ tsconfigRootDir, ignorePatterns, thresho
|
|
|
21
63
|
* `src/features`, etc. Globs anchored with a leading globstar are unaffected.
|
|
22
64
|
*/
|
|
23
65
|
sourceRoot?: string;
|
|
66
|
+
/**
|
|
67
|
+
* Axes the project declares typed, mirroring `design.tokens.axes` in
|
|
68
|
+
* `.lisa.config.json`. Read by the managed `eslint.config.ts` via
|
|
69
|
+
* {@link readTypedAxes}. Empty — the default — leaves
|
|
70
|
+
* `ui-standards/no-unbound-design-value` off.
|
|
71
|
+
*/
|
|
72
|
+
typedAxes?: readonly string[];
|
|
24
73
|
}): import("eslint").Linter.Config[];
|
|
25
74
|
//# sourceMappingURL=expo.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expo.d.ts","sourceRoot":"","sources":["../../../src/configs/eslint/expo.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"expo.d.ts","sourceRoot":"","sources":["../../../src/configs/eslint/expo.ts"],"names":[],"mappings":"AAwBA,OAAO,EAEL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EAItB,cAAc,EAIf,MAAM,iBAAiB,CAAC;AAGzB,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,CAAC;AAwCF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,aAAa,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,EAAE,CAe3D;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,SAAS,MAAM,EAAE,GAC3B,OAAO,QAAQ,EAAE,MAAM,CAAC,SAAS,CAInC;AAED;;;;;;;;;GASG;AACH,wBAAgB,aAAa,CAAC,EAC5B,eAAe,EACf,cAA+B,EAC/B,UAA8B,EAC9B,UAAe,EACf,SAAc,GACf,EAAE;IACD,eAAe,EAAE,MAAM,CAAC;IACxB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,UAAU,CAAC,EAAE,OAAO,iBAAiB,CAAC;IACtC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;OAKG;IACH,SAAS,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC/B,GAAG,OAAO,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,CAgRnC"}
|
|
@@ -16,7 +16,9 @@
|
|
|
16
16
|
import oxlint from "eslint-plugin-oxlint";
|
|
17
17
|
import react from "eslint-plugin-react";
|
|
18
18
|
import reactCompiler from "eslint-plugin-react-compiler";
|
|
19
|
+
import { readFileSync } from "fs";
|
|
19
20
|
import { createRequire } from "module";
|
|
21
|
+
import path from "path";
|
|
20
22
|
import { fileURLToPath } from "url";
|
|
21
23
|
// Import TypeScript config and utilities
|
|
22
24
|
import { codeOrganization, defaultIgnores, defaultThresholds, getBaseConfigs, getBaseLanguageOptions, getJsFilesOverride, getScriptsFilesOverride, getSharedFilesOverride, getSharedRules, getTestFilesOverride, getTsFilesOverride, getTsTestFilesOverride, } from "./typescript.js";
|
|
@@ -32,6 +34,82 @@ const expoConfig = require("eslint-config-expo/flat");
|
|
|
32
34
|
const reactPerf = require("eslint-plugin-react-perf");
|
|
33
35
|
const jsxA11y = require("eslint-plugin-jsx-a11y");
|
|
34
36
|
const tailwind = require("eslint-plugin-tailwindcss");
|
|
37
|
+
/**
|
|
38
|
+
* A project's `.lisa.config.json`, when it has one.
|
|
39
|
+
*
|
|
40
|
+
* Absence is not an error: a project that has never run `lisa apply` has no
|
|
41
|
+
* such file and declares no axes.
|
|
42
|
+
* @param file - Absolute path to the candidate `.lisa.config.json`.
|
|
43
|
+
* @returns Its text, or undefined when the project has no such file.
|
|
44
|
+
*/
|
|
45
|
+
function readConfigText(file) {
|
|
46
|
+
try {
|
|
47
|
+
return readFileSync(file, "utf8");
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return undefined;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Axes a project declares typed, read from its own `.lisa.config.json`.
|
|
55
|
+
*
|
|
56
|
+
* #2807: the design-value rule shipped installed, severity `"off"`, and arming
|
|
57
|
+
* it needed a severity AND a `typedAxes` option hand-written into
|
|
58
|
+
* `eslint.config.local.ts`. Nothing carried `design.tokens.axes` from
|
|
59
|
+
* `.lisa.config.json` to the rule, so a project could declare every axis,
|
|
60
|
+
* install the policy, pass every test, and enforce nothing.
|
|
61
|
+
*
|
|
62
|
+
* It is read HERE, at ESLint **config** load, rather than inside the rule at
|
|
63
|
+
* **rule** load. That distinction is what makes it unremarkable: the managed
|
|
64
|
+
* `eslint.config.ts` already reads `eslint.thresholds.json` and
|
|
65
|
+
* `eslint.ignore.config.json` from disk at exactly this moment, so this adds no
|
|
66
|
+
* new class of behaviour and gives ESLint's config cache nothing to fight. A
|
|
67
|
+
* rule reading project files on every `create()` would do both.
|
|
68
|
+
*
|
|
69
|
+
* It also needs no generation step, which is what the alternative — emitting
|
|
70
|
+
* rule options into a generated file during `lisa apply` — would have cost. A
|
|
71
|
+
* generated file can go stale against the config it was generated from; a value
|
|
72
|
+
* read at load cannot.
|
|
73
|
+
* @param projectRoot - Directory holding the project's `.lisa.config.json`.
|
|
74
|
+
* @returns The declared axes, or an empty list when none are declared.
|
|
75
|
+
* @throws {TypeError} When `design.tokens.axes` is present but is not a list of strings.
|
|
76
|
+
*/
|
|
77
|
+
export function readTypedAxes(projectRoot) {
|
|
78
|
+
const file = path.join(projectRoot, ".lisa.config.json");
|
|
79
|
+
const raw = readConfigText(file);
|
|
80
|
+
if (raw === undefined)
|
|
81
|
+
return [];
|
|
82
|
+
const axes = JSON.parse(raw)
|
|
83
|
+
.design?.tokens?.axes;
|
|
84
|
+
if (axes === undefined)
|
|
85
|
+
return [];
|
|
86
|
+
if (!Array.isArray(axes) || axes.some(axis => typeof axis !== "string")) {
|
|
87
|
+
// Coercing a malformed declaration to "no axes" would disarm the rule
|
|
88
|
+
// silently — #2807 reproduced one layer down. Refuse loudly instead.
|
|
89
|
+
throw new TypeError(`${file}: design.tokens.axes must be an array of axis names, e.g. ["color"].`);
|
|
90
|
+
}
|
|
91
|
+
return axes;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* The `ui-standards/no-unbound-design-value` entry for a set of typed axes.
|
|
95
|
+
*
|
|
96
|
+
* Silence-by-default is deliberate and unchanged: an axis with no published
|
|
97
|
+
* variable collection behind it has no token to bind to, and a rule that fires
|
|
98
|
+
* on every project is a rule that gets switched off. What changes is that
|
|
99
|
+
* declaring an axis is now SUFFICIENT to arm it. Previously nothing was.
|
|
100
|
+
*
|
|
101
|
+
* An axis name outside the rule's fixed vocabulary is passed through rather
|
|
102
|
+
* than filtered out, so ESLint's own schema validation rejects it by name. A
|
|
103
|
+
* filter would turn a typo into silent non-enforcement, which is the defect
|
|
104
|
+
* this function exists to remove.
|
|
105
|
+
* @param typedAxes - Axes the project declares typed.
|
|
106
|
+
* @returns `"off"` when none are declared, an armed error entry otherwise.
|
|
107
|
+
*/
|
|
108
|
+
export function getDesignValueBindingRule(typedAxes) {
|
|
109
|
+
return typedAxes.length > 0
|
|
110
|
+
? ["error", { typedAxes: [...typedAxes] }]
|
|
111
|
+
: "off";
|
|
112
|
+
}
|
|
35
113
|
/**
|
|
36
114
|
* Creates the Expo ESLint configuration.
|
|
37
115
|
* @param {object} options - Configuration options
|
|
@@ -39,9 +117,10 @@ const tailwind = require("eslint-plugin-tailwindcss");
|
|
|
39
117
|
* @param {string[]} [options.ignorePatterns] - Patterns to ignore
|
|
40
118
|
* @param {object} [options.thresholds] - Threshold overrides
|
|
41
119
|
* @param {string} [options.sourceRoot] - Prefix for source-relative file globs (e.g. `"src/"` for the SDK 55+/56 `/src` convention; defaults to `""`)
|
|
120
|
+
* @param {string[]} [options.typedAxes] - Axes the project declares typed, mirroring `design.tokens.axes`. Empty leaves the design-value rule off.
|
|
42
121
|
* @returns {import("eslint").Linter.Config[]} ESLint flat config array
|
|
43
122
|
*/
|
|
44
|
-
export function getExpoConfig({ tsconfigRootDir, ignorePatterns = defaultIgnores, thresholds = defaultThresholds, sourceRoot = "", }) {
|
|
123
|
+
export function getExpoConfig({ tsconfigRootDir, ignorePatterns = defaultIgnores, thresholds = defaultThresholds, sourceRoot = "", typedAxes = [], }) {
|
|
45
124
|
return [
|
|
46
125
|
// Global ignores
|
|
47
126
|
{
|
|
@@ -84,10 +163,12 @@ export function getExpoConfig({ tsconfigRootDir, ignorePatterns = defaultIgnores
|
|
|
84
163
|
"ui-standards/no-classname-outside-ui": "off",
|
|
85
164
|
"ui-standards/no-direct-rn-imports": "off",
|
|
86
165
|
// Regime-aware by declaration: silent until the project names the axes
|
|
87
|
-
// it publishes design variables for.
|
|
88
|
-
//
|
|
89
|
-
//
|
|
90
|
-
|
|
166
|
+
// it publishes design variables for. Declaring `design.tokens.axes` in
|
|
167
|
+
// .lisa.config.json is what arms it — the managed eslint.config.ts
|
|
168
|
+
// reads that key and hands it here (#2807). Declaring nothing leaves
|
|
169
|
+
// the rule off, which is the correct default and was previously the
|
|
170
|
+
// ONLY reachable state.
|
|
171
|
+
"ui-standards/no-unbound-design-value": getDesignValueBindingRule(typedAxes),
|
|
91
172
|
// Tailwind
|
|
92
173
|
"tailwindcss/classnames-order": [
|
|
93
174
|
"error",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"expo.js","sourceRoot":"","sources":["../../../src/configs/eslint/expo.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E;;;;;;;;;;;;;GAaG;AACH,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,yCAAyC;AACzC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,mCAAmC;AACnC,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,CAAC;AAEF,+EAA+E;AAC/E,kFAAkF;AAClF,uFAAuF;AACvF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,kBAAkB,GAAG,OAAO,CAChC,aAAa,CACX,IAAI,GAAG,CACL,qDAAqD,EACrD,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CACF,CACF,CAAC;AACF,MAAM,WAAW,GAAG,OAAO,CACzB,aAAa,CACX,IAAI,GAAG,CAAC,8CAA8C,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACzE,CACF,CAAC;AACF,MAAM,UAAU,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AACtD,MAAM,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;AAEtD
|
|
1
|
+
{"version":3,"file":"expo.js","sourceRoot":"","sources":["../../../src/configs/eslint/expo.ts"],"names":[],"mappings":"AAAA,+EAA+E;AAC/E;;;;;;;;;;;;;GAaG;AACH,OAAO,MAAM,MAAM,sBAAsB,CAAC;AAC1C,OAAO,KAAK,MAAM,qBAAqB,CAAC;AACxC,OAAO,aAAa,MAAM,8BAA8B,CAAC;AACzD,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAC;AACvC,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,yCAAyC;AACzC,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,kBAAkB,EAClB,uBAAuB,EACvB,sBAAsB,EACtB,cAAc,EACd,oBAAoB,EACpB,kBAAkB,EAClB,sBAAsB,GACvB,MAAM,iBAAiB,CAAC;AAEzB,mCAAmC;AACnC,OAAO,EACL,cAAc,EACd,iBAAiB,EACjB,cAAc,EACd,sBAAsB,EACtB,cAAc,GACf,CAAC;AAEF,+EAA+E;AAC/E,kFAAkF;AAClF,uFAAuF;AACvF,MAAM,OAAO,GAAG,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC/C,MAAM,kBAAkB,GAAG,OAAO,CAChC,aAAa,CACX,IAAI,GAAG,CACL,qDAAqD,EACrD,MAAM,CAAC,IAAI,CAAC,GAAG,CAChB,CACF,CACF,CAAC;AACF,MAAM,WAAW,GAAG,OAAO,CACzB,aAAa,CACX,IAAI,GAAG,CAAC,8CAA8C,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CACzE,CACF,CAAC;AACF,MAAM,UAAU,GAAG,OAAO,CAAC,yBAAyB,CAAC,CAAC;AACtD,MAAM,SAAS,GAAG,OAAO,CAAC,0BAA0B,CAAC,CAAC;AACtD,MAAM,OAAO,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAAC;AAClD,MAAM,QAAQ,GAAG,OAAO,CAAC,2BAA2B,CAAC,CAAC;AAEtD;;;;;;;GAOG;AACH,SAAS,cAAc,CAAC,IAAY;IAClC,IAAI,CAAC;QACH,OAAO,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IACpC,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,SAAS,CAAC;IACnB,CAAC;AACH,CAAC;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,mBAAmB,CAAC,CAAC;IACzD,MAAM,GAAG,GAAG,cAAc,CAAC,IAAI,CAAC,CAAC;IACjC,IAAI,GAAG,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IACjC,MAAM,IAAI,GAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAkD;SAC3E,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC;IACxB,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC;IAClC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,IAAI,KAAK,QAAQ,CAAC,EAAE,CAAC;QACxE,sEAAsE;QACtE,qEAAqE;QACrE,MAAM,IAAI,SAAS,CACjB,GAAG,IAAI,sEAAsE,CAC9E,CAAC;IACJ,CAAC;IACD,OAAO,IAAgB,CAAC;AAC1B,CAAC;AAED;;;;;;;;;;;;;;GAcG;AACH,MAAM,UAAU,yBAAyB,CACvC,SAA4B;IAE5B,OAAO,SAAS,CAAC,MAAM,GAAG,CAAC;QACzB,CAAC,CAAC,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,CAAC,GAAG,SAAS,CAAC,EAAE,CAAC;QAC1C,CAAC,CAAC,KAAK,CAAC;AACZ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,aAAa,CAAC,EAC5B,eAAe,EACf,cAAc,GAAG,cAAc,EAC/B,UAAU,GAAG,iBAAiB,EAC9B,UAAU,GAAG,EAAE,EACf,SAAS,GAAG,EAAE,GAoBf;IACC,OAAO;QACL,iBAAiB;QACjB;YACE,OAAO,EAAE,cAAc;SACxB;QAED,yCAAyC;QACzC,GAAG,cAAc,EAAE;QAEnB,+BAA+B;QAC/B,GAAG,UAAU;QAEb,uBAAuB;QACvB,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;QAC9B,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC;QAEjC,gBAAgB;QAChB,OAAO,CAAC,WAAW,CAAC,MAAM;QAE1B,eAAe;QACf,GAAG,QAAQ,CAAC,OAAO,CAAC,kBAAkB,CAAC;QAEvC,cAAc;QACd,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,WAAW;QAElC,mCAAmC;QACnC;YACE,eAAe,EAAE;gBACf,GAAG,sBAAsB,EAAE;gBAC3B,aAAa,EAAE;oBACb,GAAG,sBAAsB,EAAE,CAAC,aAAa;oBACzC,YAAY,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE;iBAC5B;aACF;YACD,OAAO,EAAE;gBACP,qBAAqB,EAAE,kBAAkB;gBACzC,mBAAmB,EAAE,gBAAgB;gBACrC,gBAAgB,EAAE,aAAa;gBAC/B,cAAc,EAAE,WAAW;aAC5B;YACD,KAAK,EAAE;gBACL,yBAAyB;gBACzB,GAAG,cAAc,CAAC,UAAU,CAAC;gBAE7B,oBAAoB;gBACpB,2CAA2C,EAAE,OAAO;gBAEpD,oCAAoC;gBACpC,sCAAsC,EAAE,KAAK;gBAC7C,mCAAmC,EAAE,KAAK;gBAC1C,uEAAuE;gBACvE,uEAAuE;gBACvE,mEAAmE;gBACnE,qEAAqE;gBACrE,oEAAoE;gBACpE,wBAAwB;gBACxB,sCAAsC,EACpC,yBAAyB,CAAC,SAAS,CAAC;gBAEtC,WAAW;gBACX,8BAA8B,EAAE;oBAC9B,OAAO;oBACP;wBACE,OAAO,EAAE,CAAC,KAAK,EAAE,YAAY,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,IAAI,CAAC;qBAC3D;iBACF;gBAED,eAAe;gBACf,+DAA+D;gBAC/D,6BAA6B;gBAC7B,iBAAiB,EAAE,KAAK;gBACxB,kBAAkB,EAAE,KAAK;gBACzB,mEAAmE;gBACnE,sBAAsB,EAAE,KAAK,EAAE,wFAAwF;gBACvH,8BAA8B,EAAE,KAAK;gBACrC,sBAAsB,EAAE,OAAO;gBAE/B,oBAAoB;gBACpB,sCAAsC,EAAE,OAAO;gBAC/C,qCAAqC,EAAE,OAAO;gBAC9C,wCAAwC,EAAE,OAAO;gBAEjD,cAAc;gBACd,yCAAyC,EAAE,OAAO;gBAClD,sBAAsB,EAAE,KAAK;gBAC7B,0BAA0B,EAAE,KAAK;gBACjC,6BAA6B,EAAE,OAAO;gBACtC,4BAA4B,EAAE,OAAO;gBACrC,iCAAiC,EAAE,OAAO;gBAC1C,yCAAyC,EAAE,OAAO;gBAClD,kBAAkB,EAAE,OAAO;gBAC3B,0BAA0B,EAAE,OAAO;gBACnC,+DAA+D;gBAC/D,6BAA6B;gBAC7B,+BAA+B,EAAE,KAAK;gBACtC,+BAA+B,EAAE,KAAK;gBACtC,mEAAmE;gBACnE,6DAA6D;gBAC7D,+CAA+C;gBAC/C,sBAAsB,EAAE;oBACtB,OAAO;oBACP;wBACE,QAAQ,EACN,8DAA8D;wBAChE,OAAO,EACL,iIAAiI;qBACpI;iBACF;gBAED,4BAA4B;gBAC5B,YAAY,EAAE,MAAM;gBAEpB,oFAAoF;gBACpF,uBAAuB,EAAE,OAAO;gBAEhC,kEAAkE;gBAClE,qBAAqB,EAAE;oBACrB,OAAO;oBACP;wBACE,OAAO,EAAE;4BACP,mBAAmB,EAAE,IAAI;4BACzB,gBAAgB,EAAE,KAAK;4BACvB,gBAAgB,EAAE,KAAK;4BACvB,uBAAuB,EAAE,KAAK;4BAC9B,kBAAkB,EAAE,KAAK;yBAC1B;wBACD,QAAQ,EAAE;4BACR,wBAAwB;4BACxB,wBAAwB;4BACxB,iGAAiG;yBAClG;qBACF;iBACF;aACF;SACF;QAED,4BAA4B;QAC5B,kBAAkB,EAAE;QAEpB,8BAA8B;QAC9B,sBAAsB,EAAE;QAExB,gBAAgB;QAChB;YACE,KAAK,EAAE;gBACL,GAAG,UAAU,wBAAwB;gBACrC,GAAG,UAAU,wBAAwB;gBACrC,GAAG,UAAU,+BAA+B;gBAC5C,GAAG,UAAU,+BAA+B;aAC7C;YACD,KAAK,EAAE;gBACL,sCAAsC,EAAE,KAAK;aAC9C;SACF;QAED,gDAAgD;QAChD,oBAAoB,CAAC;YACnB,eAAe;YACf,eAAe;YACf,cAAc;YACd,cAAc;SACf,CAAC;QAEF,gEAAgE;QAChE;YACE,GAAG,kBAAkB,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,eAAe,CAAC;YAC/D,KAAK,EAAE;gBACL,GAAG,kBAAkB,CAAC,CAAC,SAAS,EAAE,UAAU,CAAC,EAAE,eAAe,CAAC,CAAC,KAAK;gBACrE,kBAAkB,EAAE,KAAK;aAC1B;SACF;QAED,qDAAqD;QACrD;YACE,KAAK,EAAE,CAAC,UAAU,CAAC;YACnB,KAAK,EAAE;gBACL,uBAAuB,EAAE,KAAK;aAC/B;SACF;QAED,qFAAqF;QACrF,sBAAsB,CAAC;YACrB,cAAc;YACd,eAAe;YACf,aAAa;YACb,cAAc;SACf,CAAC;QAEF,4BAA4B;QAC5B;YACE,KAAK,EAAE;gBACL,GAAG,UAAU,gCAAgC;gBAC7C,GAAG,UAAU,iCAAiC;gBAC9C,GAAG,UAAU,iCAAiC;gBAC9C,GAAG,UAAU,6BAA6B;gBAC1C,GAAG,UAAU,8BAA8B;gBAC3C,GAAG,UAAU,8BAA8B;gBAC3C,GAAG,UAAU,oBAAoB;gBACjC,GAAG,UAAU,qBAAqB;gBAClC,GAAG,UAAU,qBAAqB;aACnC;YACD,OAAO,EAAE;gBACP,GAAG,UAAU,kBAAkB;gBAC/B,GAAG,UAAU,sBAAsB;gBACnC,GAAG,UAAU,qBAAqB;aACnC;YACD,KAAK,EAAE;gBACL,iDAAiD,EAAE,OAAO;gBAC1D,+CAA+C,EAAE,OAAO;aACzD;SACF;QAED,uBAAuB;QACvB;YACE,KAAK,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;YACvC,KAAK,EAAE;gBACL,uCAAuC,EAAE,OAAO;aACjD;SACF;QAED,kDAAkD;QAClD;YACE,KAAK,EAAE,CAAC,cAAc,EAAE,cAAc,CAAC;YACvC,OAAO,EAAE,CAAC,GAAG,UAAU,kBAAkB,CAAC;YAC1C,KAAK,EAAE;gBACL,0CAA0C,EAAE,OAAO;aACpD;SACF;QAED,gEAAgE;QAChE,wEAAwE;QACxE,+CAA+C;QAC/C;YACE,KAAK,EAAE,CAAC,gBAAgB,EAAE,YAAY,EAAE,2BAA2B,CAAC;YACpE,KAAK,EAAE;gBACL,sBAAsB,EAAE,KAAK;aAC9B;SACF;QAED,oEAAoE;QACpE,kEAAkE;QAClE;YACE,KAAK,EAAE;gBACL,+BAA+B;gBAC/B,wBAAwB;gBACxB,2BAA2B;aAC5B;YACD,KAAK,EAAE;gBACL,sBAAsB,EAAE,KAAK;aAC9B;SACF;QAED,4DAA4D;QAC5D;YACE,KAAK,EAAE,CAAC,cAAc,EAAE,iBAAiB,EAAE,YAAY,CAAC;YACxD,KAAK,EAAE;gBACL,sBAAsB,EAAE,KAAK;aAC9B;SACF;QAED,2EAA2E;QAC3E,wEAAwE;QACxE,mCAAmC;QACnC,GAAG,MAAM,CAAC,OAAO,CAAC,YAAY,CAAC;QAC/B,GAAG,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC;QAElC,sEAAsE;QACtE,uEAAuE;QACvE,mEAAmE;QACnE,uBAAuB,EAAE;KACqB,CAAC;AACnD,CAAC;AAED,8EAA8E"}
|