@tacuchi/agent-workflow-cli 20.26.0 → 21.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/README.md +2 -1
  2. package/dist/adapters/node-file-system.js +3 -0
  3. package/dist/adapters/node-file-system.js.map +1 -1
  4. package/dist/application/capability/compose.js +161 -0
  5. package/dist/application/capability/compose.js.map +1 -0
  6. package/dist/application/capability/descriptor-loader.js +109 -0
  7. package/dist/application/capability/descriptor-loader.js.map +1 -0
  8. package/dist/application/capability/design-handler.js +299 -0
  9. package/dist/application/capability/design-handler.js.map +1 -0
  10. package/dist/application/capability/dispatcher.js +312 -0
  11. package/dist/application/capability/dispatcher.js.map +1 -0
  12. package/dist/application/capability/durable-effect.js +220 -0
  13. package/dist/application/capability/durable-effect.js.map +1 -0
  14. package/dist/application/capability/installed-inventory.js +168 -0
  15. package/dist/application/capability/installed-inventory.js.map +1 -0
  16. package/dist/application/capability/readiness.js +204 -0
  17. package/dist/application/capability/readiness.js.map +1 -0
  18. package/dist/application/capability/resolution.js +264 -0
  19. package/dist/application/capability/resolution.js.map +1 -0
  20. package/dist/application/capability/wrapper.js +187 -0
  21. package/dist/application/capability/wrapper.js.map +1 -0
  22. package/dist/application/context/manifest.js +11 -5
  23. package/dist/application/context/manifest.js.map +1 -1
  24. package/dist/application/context/measure.js +5 -2
  25. package/dist/application/context/measure.js.map +1 -1
  26. package/dist/application/context/plan-service.js +6 -6
  27. package/dist/application/context/plan-service.js.map +1 -1
  28. package/dist/application/design/design-bundle-service.js +148 -0
  29. package/dist/application/design/design-bundle-service.js.map +1 -0
  30. package/dist/application/design/design-gate-service.js +246 -0
  31. package/dist/application/design/design-gate-service.js.map +1 -0
  32. package/dist/application/design/design-graph-service.js +85 -0
  33. package/dist/application/design/design-graph-service.js.map +1 -0
  34. package/dist/application/design/design-index-service.js +132 -0
  35. package/dist/application/design/design-index-service.js.map +1 -0
  36. package/dist/application/design/design-proposal-service.js +69 -0
  37. package/dist/application/design/design-proposal-service.js.map +1 -0
  38. package/dist/application/design/design-publish-service.js +756 -0
  39. package/dist/application/design/design-publish-service.js.map +1 -0
  40. package/dist/application/design/design-record-service.js +100 -0
  41. package/dist/application/design/design-record-service.js.map +1 -0
  42. package/dist/application/design/design-resolver-service.js +165 -0
  43. package/dist/application/design/design-resolver-service.js.map +1 -0
  44. package/dist/application/flow/advance.js +533 -0
  45. package/dist/application/flow/advance.js.map +1 -0
  46. package/dist/application/flow/flow-service.js +65 -0
  47. package/dist/application/flow/flow-service.js.map +1 -0
  48. package/dist/application/flow/run-projection.js +80 -0
  49. package/dist/application/flow/run-projection.js.map +1 -0
  50. package/dist/application/flow/run-state-service.js +107 -0
  51. package/dist/application/flow/run-state-service.js.map +1 -0
  52. package/dist/application/flow/submit.js +423 -0
  53. package/dist/application/flow/submit.js.map +1 -0
  54. package/dist/application/resume-service.js +46 -14
  55. package/dist/application/resume-service.js.map +1 -1
  56. package/dist/application/self/install-skill.js +11 -0
  57. package/dist/application/self/install-skill.js.map +1 -1
  58. package/dist/application/self/uninstall.js +21 -0
  59. package/dist/application/self/uninstall.js.map +1 -1
  60. package/dist/application/semantic-operation/protocol.js +18 -12
  61. package/dist/application/semantic-operation/protocol.js.map +1 -1
  62. package/dist/application/semantic-operation/publish.js +56 -9
  63. package/dist/application/semantic-operation/publish.js.map +1 -1
  64. package/dist/application/skills-resolver-service.js +27 -6
  65. package/dist/application/skills-resolver-service.js.map +1 -1
  66. package/dist/application/status-service.js +5 -1
  67. package/dist/application/status-service.js.map +1 -1
  68. package/dist/application/workline-index-service.js +6 -0
  69. package/dist/application/workline-index-service.js.map +1 -1
  70. package/dist/application/workspace-init-service.js +22 -2
  71. package/dist/application/workspace-init-service.js.map +1 -1
  72. package/dist/cli/commands/capability.js +182 -0
  73. package/dist/cli/commands/capability.js.map +1 -0
  74. package/dist/cli/commands/designs.js +110 -0
  75. package/dist/cli/commands/designs.js.map +1 -0
  76. package/dist/cli/commands/flow.js +71 -0
  77. package/dist/cli/commands/flow.js.map +1 -0
  78. package/dist/cli/commands/index.js +6 -0
  79. package/dist/cli/commands/index.js.map +1 -1
  80. package/dist/cli/commands/resume.js +8 -0
  81. package/dist/cli/commands/resume.js.map +1 -1
  82. package/dist/cli/commands/skills.js +55 -2
  83. package/dist/cli/commands/skills.js.map +1 -1
  84. package/dist/cli/commands/status.js +50 -0
  85. package/dist/cli/commands/status.js.map +1 -1
  86. package/dist/cli/help-groups.js +9 -0
  87. package/dist/cli/help-groups.js.map +1 -1
  88. package/dist/cli/parser.js +7 -0
  89. package/dist/cli/parser.js.map +1 -1
  90. package/dist/cli/tui/data/workflow-content.js +5 -0
  91. package/dist/cli/tui/data/workflow-content.js.map +1 -1
  92. package/dist/cli/tui/tabs/workflow-tab.js +5 -1
  93. package/dist/cli/tui/tabs/workflow-tab.js.map +1 -1
  94. package/dist/domain/capability/descriptor.js +553 -0
  95. package/dist/domain/capability/descriptor.js.map +1 -0
  96. package/dist/domain/capability/effects.js +90 -0
  97. package/dist/domain/capability/effects.js.map +1 -0
  98. package/dist/domain/capability/protocol.js +494 -0
  99. package/dist/domain/capability/protocol.js.map +1 -0
  100. package/dist/domain/contract-reader.js +84 -0
  101. package/dist/domain/contract-reader.js.map +1 -0
  102. package/dist/domain/design/adapter.js +161 -0
  103. package/dist/domain/design/adapter.js.map +1 -0
  104. package/dist/domain/design/artifact-body.js +223 -0
  105. package/dist/domain/design/artifact-body.js.map +1 -0
  106. package/dist/domain/design/artifact.js +750 -0
  107. package/dist/domain/design/artifact.js.map +1 -0
  108. package/dist/domain/design/baseline.js +359 -0
  109. package/dist/domain/design/baseline.js.map +1 -0
  110. package/dist/domain/design/capability.js +310 -0
  111. package/dist/domain/design/capability.js.map +1 -0
  112. package/dist/domain/design/closure.js +161 -0
  113. package/dist/domain/design/closure.js.map +1 -0
  114. package/dist/domain/design/direct.js +108 -0
  115. package/dist/domain/design/direct.js.map +1 -0
  116. package/dist/domain/design/external-send.js +65 -0
  117. package/dist/domain/design/external-send.js.map +1 -0
  118. package/dist/domain/design/governance.js +298 -0
  119. package/dist/domain/design/governance.js.map +1 -0
  120. package/dist/domain/design/identity.js +145 -0
  121. package/dist/domain/design/identity.js.map +1 -0
  122. package/dist/domain/design/manifest.js +552 -0
  123. package/dist/domain/design/manifest.js.map +1 -0
  124. package/dist/domain/design/maturity.js +305 -0
  125. package/dist/domain/design/maturity.js.map +1 -0
  126. package/dist/domain/design/naming.js +117 -0
  127. package/dist/domain/design/naming.js.map +1 -0
  128. package/dist/domain/design/offline.js +92 -0
  129. package/dist/domain/design/offline.js.map +1 -0
  130. package/dist/domain/design/profiles.js +212 -0
  131. package/dist/domain/design/profiles.js.map +1 -0
  132. package/dist/domain/design/projections.js +165 -0
  133. package/dist/domain/design/projections.js.map +1 -0
  134. package/dist/domain/design/proposal.js +234 -0
  135. package/dist/domain/design/proposal.js.map +1 -0
  136. package/dist/domain/design/reference.js +234 -0
  137. package/dist/domain/design/reference.js.map +1 -0
  138. package/dist/domain/design/render-bundle.js +0 -0
  139. package/dist/domain/design/render-bundle.js.map +1 -0
  140. package/dist/domain/design/rendition.js +472 -0
  141. package/dist/domain/design/rendition.js.map +1 -0
  142. package/dist/domain/design/retired.js +61 -0
  143. package/dist/domain/design/retired.js.map +1 -0
  144. package/dist/domain/design/revision.js +219 -0
  145. package/dist/domain/design/revision.js.map +1 -0
  146. package/dist/domain/design/secrets.js +86 -0
  147. package/dist/domain/design/secrets.js.map +1 -0
  148. package/dist/domain/design/sources.js +180 -0
  149. package/dist/domain/design/sources.js.map +1 -0
  150. package/dist/domain/design/validation.js +19 -0
  151. package/dist/domain/design/validation.js.map +1 -0
  152. package/dist/domain/design/visual-evidence.js +155 -0
  153. package/dist/domain/design/visual-evidence.js.map +1 -0
  154. package/dist/domain/design/yaml-subset.js +390 -0
  155. package/dist/domain/design/yaml-subset.js.map +1 -0
  156. package/dist/domain/flow/answer.js +459 -0
  157. package/dist/domain/flow/answer.js.map +1 -0
  158. package/dist/domain/flow/authority.js +2276 -0
  159. package/dist/domain/flow/authority.js.map +1 -0
  160. package/dist/domain/flow/authorization.js +62 -0
  161. package/dist/domain/flow/authorization.js.map +1 -0
  162. package/dist/domain/flow/directive.js +421 -0
  163. package/dist/domain/flow/directive.js.map +1 -0
  164. package/dist/domain/flow/rules.js +140 -0
  165. package/dist/domain/flow/rules.js.map +1 -0
  166. package/dist/domain/flow/run-state.js +317 -0
  167. package/dist/domain/flow/run-state.js.map +1 -0
  168. package/dist/domain/harnesses.js +21 -0
  169. package/dist/domain/harnesses.js.map +1 -1
  170. package/dist/domain/safe-path.js +23 -0
  171. package/dist/domain/safe-path.js.map +1 -0
  172. package/dist/domain/skills.js +26 -3
  173. package/dist/domain/skills.js.map +1 -1
  174. package/package.json +1 -1
  175. package/skills/w/SKILL.md +15 -13
  176. package/skills/w/artifacts/README.md +3 -4
  177. package/skills/w/artifacts/artifacts-core/CHECKPOINT.md +2 -2
  178. package/skills/w/commands/plan-exec.md +11 -5
  179. package/skills/w/commands/plan-new.md +6 -2
  180. package/skills/w/commands/plan-refine.md +6 -3
  181. package/skills/w/commands/quick.md +2 -2
  182. package/skills/w/commands/spec-new.md +2 -2
  183. package/skills/w/commands/spec-refine.md +1 -0
  184. package/skills/w/context/MANIFEST.json +57 -9
  185. package/skills/w/harness/HARNESS.md +20 -0
  186. package/skills/w/loops/CHASSIS.md +11 -20
  187. package/skills/w/loops/CODE-POLICIES.md +18 -9
  188. package/skills/w/loops/README.md +1 -1
  189. package/skills/w/loops/plan-exec-loop/LOOP.md +126 -62
  190. package/skills/w/loops/plan-new-loop/LOOP.md +71 -73
  191. package/skills/w/loops/plan-refine-loop/LOOP.md +20 -10
  192. package/skills/w/loops/quick-loop/LOOP.md +18 -26
  193. package/skills/w/loops/spec-refine-loop/LOOP.md +28 -30
  194. package/skills/w/modules/COMPACTION.md +2 -6
  195. package/skills/w/modules/DB-SCRIPTS-ONLY.md +2 -0
  196. package/skills/w/modules/DESIGN-REFERENCES.md +113 -0
  197. package/skills/w/modules/IDEATION-GATE.md +3 -3
  198. package/skills/w/modules/PERSIST-ROUTING.md +1 -0
  199. package/skills/w/modules/PLAN-EXECUTION-BATCHES.md +65 -0
  200. package/skills/w/modules/PLAN-INPUT.md +5 -3
  201. package/skills/w/modules/PLAN-REFINE-SPLIT.md +3 -1
  202. package/skills/w/modules/PLAN-SPLIT-GATE.md +7 -5
  203. package/skills/w/modules/PROMPT-CONTINUITY.md +3 -1
  204. package/skills/w/modules/SPEC-CHANGE-SHAPE.md +4 -4
  205. package/skills/w/roles/README.md +9 -5
  206. package/skills/w/roles/design/CONTRACT.md +80 -0
  207. package/skills/w/roles/design/ROLE.md +224 -0
  208. package/skills/w/schemas/capability-descriptor.schema.json +260 -0
  209. package/skills/w/schemas/design/design-baseline.v1.schema.json +71 -0
  210. package/skills/w/schemas/design/design-manifest.v1.schema.json +322 -0
  211. package/skills/w/schemas/design/design-render-bundle.v1.schema.json +191 -0
  212. package/skills/w/schemas/design/design-rendition.v1.schema.json +232 -0
  213. package/skills/w/schemas/design/design-review.v1.schema.json +72 -0
  214. package/skills/w/schemas/design/design-revocation.v1.schema.json +54 -0
  215. package/skills/w/schemas/design/ui-flow.v1.schema.json +211 -0
  216. package/skills/w/schemas/design/ui-screen.v1.schema.json +242 -0
  217. package/skills/w/artifacts/artifacts-design/SPEC.md +0 -42
  218. package/skills/w/modules/PLAN-DESIGN-SPECS.md +0 -12
  219. package/skills/w/modules/PLAN-REFINE-DESIGN-SPECS.md +0 -7
  220. package/skills/w/roles/ui-spec/ROLE.md +0 -147
@@ -0,0 +1,305 @@
1
+ import { ESSENTIAL_HEADINGS, HEADINGS, conditionalKeys, headingKey, parseBody, } from "./artifact-body.js";
2
+ import { splitDesignDocument, validateDesignArtifact, } from "./artifact.js";
3
+ import { parseArtifactId, parseArtifactRef } from "./identity.js";
4
+ /**
5
+ * A reference that is only a picture. A rendition shows what a screen LOOKED
6
+ * like when someone rendered it; it is not the semantics and it is not a WCAG
7
+ * verdict. A section whose entire content is a rendition reference has answered
8
+ * with an image (AC-SEM-07).
9
+ */
10
+ const RENDITION_ONLY = /^(?:\s*(?:DES-[0-9]+\/)?VIS-[0-9]+@r[0-9]+\s*[,·.;]?\s*)+$/;
11
+ /** Sections whose closure a `handoff` must be able to demonstrate later. */
12
+ const OBLIGATION_KEYS = new Set([
13
+ "accessibility",
14
+ "data_permissions_and_validation",
15
+ "states_and_transitions",
16
+ "responsive_and_adaptation",
17
+ "localization",
18
+ "permissions_and_privacy",
19
+ "alternatives_and_recovery",
20
+ ]);
21
+ export function checkMaturity(artifact, sections, kind, file) {
22
+ const obligations = readObligations(sections, artifact.not_applicable);
23
+ const failures = [
24
+ ...checkOutlineFloor(artifact, sections, kind, file),
25
+ ...(artifact.maturity === "handoff" ? checkHandoff(artifact, sections, kind, file) : []),
26
+ ];
27
+ return {
28
+ attainable: failures.length === 0 ? artifact.maturity : "outline",
29
+ failures,
30
+ obligations,
31
+ };
32
+ }
33
+ /**
34
+ * The floor BOTH profiles stand on (AC-SEM-01).
35
+ *
36
+ * `outline` is not "anything goes": it is the minimum inventory from which the
37
+ * next revision can be planned — who, what for, on what, what screens or steps
38
+ * exist, and what it traces to. What `outline` does NOT demand is completing the
39
+ * handoff early, which is why every check here is about presence, not depth.
40
+ */
41
+ function checkOutlineFloor(artifact, sections, kind, file) {
42
+ const failures = [];
43
+ if (artifact.trace.length === 0) {
44
+ failures.push({
45
+ code: "DESIGN_MATURITY_INCOMPLETE",
46
+ artifact: file,
47
+ message: "sin trazabilidad no hay inventario: 'trace' está vacío",
48
+ action: "declará al menos el Requirement y el acceptance criterion que origina esto",
49
+ });
50
+ }
51
+ if (artifact.kind === "flow" && artifact.actors.length === 0) {
52
+ failures.push({
53
+ code: "DESIGN_MATURITY_INCOMPLETE",
54
+ artifact: file,
55
+ message: "no declara actores: el inventario mínimo incluye quién lo recorre",
56
+ action: "declará al menos un actor en 'actors'",
57
+ });
58
+ }
59
+ const inventory = artifact.kind === "flow"
60
+ ? { what: "nodos", empty: artifact.nodes.length === 0 }
61
+ : { what: "estados", empty: artifact.states.length === 0 };
62
+ if (inventory.empty) {
63
+ failures.push({
64
+ code: "DESIGN_MATURITY_INCOMPLETE",
65
+ artifact: file,
66
+ message: `el inventario mínimo está vacío: no declara ${inventory.what}`,
67
+ action: `un ${kind} en 'outline' ya enumera sus ${inventory.what}, aunque no los detalle`,
68
+ });
69
+ }
70
+ // Acá vivía un cruce `unknown` ↔ `not_applicable` por coincidencia de texto.
71
+ // Era inseguro en las dos direcciones —no veía la contradicción real escrita
72
+ // como pregunta, y bloqueaba documentos legítimos que nombraban la sección de
73
+ // paso— así que se fue: adivinar sobre prosa libre no es una guarda. Lo que
74
+ // AC-SEM-04 exige de verdad lo hace `checkBlockingUnknowns`, sobre un booleano
75
+ // que el autor declara.
76
+ failures.push(...checkPlaceholders(sections, kind, file));
77
+ return failures;
78
+ }
79
+ /** Whatever a section says, it cannot be only a picture — in either profile. */
80
+ function checkPlaceholders(sections, kind, file) {
81
+ const essential = new Set(ESSENTIAL_HEADINGS[kind]);
82
+ return sections
83
+ .filter((s) => essential.has(s.heading) && RENDITION_ONLY.test(s.prose.trim()))
84
+ .map((s) => ({
85
+ code: "DESIGN_EVIDENCE_INSUFFICIENT",
86
+ artifact: file,
87
+ message: `'${s.heading}' responde con una rendition y nada más`,
88
+ action: "una imagen aprobada no es la semántica vigente ni una conformidad WCAG: escribí lo que exige",
89
+ }));
90
+ }
91
+ /**
92
+ * `handoff` (AC-SEM-02, AC-SEM-03, AC-SEM-04, AC-PKG-09).
93
+ *
94
+ * The claim is: everything applicable is closed, and nothing open can still move
95
+ * behavior or acceptance. Every check below is a way that claim can be false.
96
+ */
97
+ function checkHandoff(artifact, sections, kind, file) {
98
+ return [
99
+ ...checkBlockingUnknowns(artifact, file),
100
+ ...checkGraph(artifact, file),
101
+ ...checkApplicableCompleteness(artifact, sections, kind, file),
102
+ ...checkExternalCustody(artifact, file),
103
+ ...checkVisualEvidence(artifact, file),
104
+ ];
105
+ }
106
+ /**
107
+ * The elevation of AC-REN-01 and AC-REN-02: a `handoff` screen is LOOKABLE.
108
+ *
109
+ * Until this existed, `handoff` meant the prose was complete. That let a screen
110
+ * be declared implementable while nobody could see it — and the visual evidence,
111
+ * when it existed at all, was somebody's habit rather than a requirement. So a
112
+ * `handoff` screen now owes two things:
113
+ *
114
+ * 1. a classification for every criterion it traces, and
115
+ * 2. a local preview of its `default_state` — the criterion that shows the base
116
+ * state has to enumerate it AND enumerate a rendition of it.
117
+ *
118
+ * Both are checked HERE, against the document alone, and only the document's own
119
+ * claims. Whether the enumerated rendition exists, was cut from this revision and
120
+ * really covers that state is the package-level cross in `visual-evidence.ts`:
121
+ * this gate cannot open another file, and a gate that pretended to would be
122
+ * reporting on evidence it never read.
123
+ *
124
+ * `outline` is untouched on purpose. A screen still being shaped legitimately has
125
+ * no picture yet, and demanding one would push the author to render a placeholder
126
+ * so the document matches a template.
127
+ */
128
+ function checkVisualEvidence(artifact, file) {
129
+ if (artifact.kind !== "screen")
130
+ return [];
131
+ const screen = artifact;
132
+ const failures = [];
133
+ for (const entry of screen.trace) {
134
+ failures.push(...checkClassified(entry, file));
135
+ }
136
+ const base = screen.trace.filter((e) => e.classification !== "not_visual" && e.states.includes(screen.default_state));
137
+ if (!base.some((e) => e.renditions.length > 0)) {
138
+ failures.push({
139
+ code: "DESIGN_EVIDENCE_INSUFFICIENT",
140
+ artifact: file,
141
+ message: `ningún criterio trazado muestra el estado base '${screen.default_state}' con una rendition`,
142
+ action: "un 'handoff' conserva una preview estática local de su default_state: creá la rendition y enumerala en el criterio que lo demuestra",
143
+ });
144
+ }
145
+ return failures;
146
+ }
147
+ /** One entry of the matrix: classified, and enumerating what its class demands. */
148
+ function checkClassified(entry, file) {
149
+ const incomplete = (message, action) => ({
150
+ code: "DESIGN_MATURITY_INCOMPLETE",
151
+ artifact: file,
152
+ message: `trace['${entry.criterion}'] ${message}`,
153
+ action,
154
+ });
155
+ if (entry.classification === null) {
156
+ return [
157
+ incomplete("no está clasificado", "clasificalo 'visual', 'interaction' o 'not_visual': un 'handoff' dice cómo se demuestra cada criterio"),
158
+ ];
159
+ }
160
+ if (entry.classification === "not_visual") {
161
+ return entry.reason === null
162
+ ? [
163
+ incomplete("está clasificado 'not_visual' y no dice por qué", "escribí en 'reason' qué hace que ese criterio no tenga nada que mirar"),
164
+ ]
165
+ : [];
166
+ }
167
+ const failures = [];
168
+ if (entry.states.length === 0) {
169
+ failures.push(incomplete(`es '${entry.classification}' y no enumera estados`, "nombrá en 'states' los anchors donde se ve"));
170
+ }
171
+ if (entry.renditions.length === 0) {
172
+ failures.push(incomplete(`es '${entry.classification}' y no enumera renditions`, "referenciá en 'renditions' la evidencia visual que lo muestra"));
173
+ }
174
+ return failures;
175
+ }
176
+ /**
177
+ * AC-SEM-02: a `handoff` flow states its TRANSITIONS, not just its steps.
178
+ *
179
+ * A flow with two or more nodes and no edges has its graph only in the prose of
180
+ * `## Main journey` — which is exactly what the machine-readable frontmatter
181
+ * exists to avoid. One node and no edges is a legitimate degenerate case.
182
+ */
183
+ function checkGraph(artifact, file) {
184
+ if (artifact.kind !== "flow" || artifact.nodes.length < 2 || artifact.edges.length > 0) {
185
+ return [];
186
+ }
187
+ return [
188
+ {
189
+ code: "DESIGN_MATURITY_INCOMPLETE",
190
+ artifact: file,
191
+ message: `declara ${artifact.nodes.length} nodos y ninguna transición entre ellos`,
192
+ action: "un 'handoff' resuelve su grafo sin interpretar prosa: declará las aristas en 'edges'",
193
+ },
194
+ ];
195
+ }
196
+ /** AC-SEM-04: an open question that can move behavior forbids the claim. */
197
+ function checkBlockingUnknowns(artifact, file) {
198
+ return artifact.unknowns
199
+ .filter((u) => u.blocking)
200
+ .map((u) => ({
201
+ code: "DESIGN_MATURITY_BLOCKED",
202
+ artifact: file,
203
+ message: `queda una incógnita bloqueante: "${u.question}"`,
204
+ action: "resolvela y volvé a declarar 'handoff', o bajá a 'outline': una incógnita no es un 'no aplica'",
205
+ }));
206
+ }
207
+ /**
208
+ * Every section either SAYS something or is justified as inapplicable.
209
+ *
210
+ * The essential sections admit neither escape — F2 already rejects a
211
+ * `not_applicable` on them — so what is left to check here is the conditional
212
+ * ones: silence is not closure.
213
+ */
214
+ function checkApplicableCompleteness(artifact, sections, kind, file) {
215
+ const byKey = new Map(sections.map((s) => [s.key, s]));
216
+ const failures = [];
217
+ for (const key of conditionalKeys(kind)) {
218
+ const waived = artifact.not_applicable[key];
219
+ if (waived !== undefined)
220
+ continue;
221
+ const section = byKey.get(key);
222
+ if (section === undefined || section.text.trim().length > 0)
223
+ continue;
224
+ failures.push({
225
+ code: "DESIGN_MATURITY_INCOMPLETE",
226
+ artifact: file,
227
+ message: `'${headingOf(kind, key)}' está vacía y no se declaró no aplicable`,
228
+ action: `completala, o declará not_applicable.${key} con su razón`,
229
+ });
230
+ }
231
+ return failures;
232
+ }
233
+ /**
234
+ * AC-PKG-09: depending on someone else's design system.
235
+ *
236
+ * A `handoff` that points at another package's rules or tokens is implementable
237
+ * only if that material is HERE — pinned by provider, revision and digest, and
238
+ * kept locally. Otherwise the artifact describes something that can change
239
+ * underneath it, which is exactly what `outline` is for.
240
+ */
241
+ function checkExternalCustody(artifact, file) {
242
+ const own = parseArtifactId(artifact.id)?.package;
243
+ // Todas las referencias, no solo `dependencies`: un flow cuyos NODOS viven en
244
+ // otro package es tan poco implementable como uno cuyas rules viven afuera, y
245
+ // la clausura ya lo declara irresoluble. Las dos mitades tienen que coincidir.
246
+ const refs = artifact.kind === "flow"
247
+ ? [artifact.entry, ...artifact.nodes, ...artifact.dependencies]
248
+ : [...artifact.flow_refs, ...artifact.dependencies.rules, ...artifact.dependencies.tokens];
249
+ const pinned = new Set(artifact.external.map((e) => e.provider));
250
+ const loose = new Map();
251
+ for (const ref of refs) {
252
+ const parsed = parseArtifactRef(ref);
253
+ if (parsed === null || parsed.package === own || pinned.has(parsed.package))
254
+ continue;
255
+ loose.set(parsed.package, [...(loose.get(parsed.package) ?? []), ref]);
256
+ }
257
+ if (loose.size === 0)
258
+ return [];
259
+ return [...loose].map(([provider, refs]) => ({
260
+ code: "DESIGN_EVIDENCE_INSUFFICIENT",
261
+ artifact: file,
262
+ message: `depende de ${provider} sin fijarlo: ${refs.join(", ")}`,
263
+ action: `agregá a 'external' el proveedor ${provider} con su revisión y su digest, y conservá localmente ese subconjunto; sin esa evidencia queda en 'outline'`,
264
+ }));
265
+ }
266
+ /**
267
+ * What the implementation will have to prove.
268
+ *
269
+ * Derived, never authored: the obligations ARE the sections that state demands
270
+ * an implementation can fail — accessibility, permissions, states, adaptation.
271
+ * The gate records them so a later phase can ask for evidence instead of taking
272
+ * a rendered picture as proof.
273
+ *
274
+ * A section the document WAIVED is not an obligation. F2 makes the heading exist
275
+ * with real prose even when it is waived — the machine-readable reason and the
276
+ * human explanation are two audiences — so filtering by prose alone would demand
277
+ * evidence for exactly what the design justified as inapplicable. And the whole
278
+ * section is the statement: cutting at the first period dropped the second half
279
+ * of every rule, which is where the testable part usually lives.
280
+ */
281
+ function readObligations(sections, waived) {
282
+ return sections
283
+ .filter((s) => OBLIGATION_KEYS.has(s.key) && s.prose.trim().length > 0 && waived[s.key] === undefined)
284
+ .map((s) => ({ key: s.key, statement: s.prose.replace(/\s+/g, " ").trim() }));
285
+ }
286
+ function headingOf(kind, key) {
287
+ return HEADINGS[kind].find((h) => headingKey(h) === key) ?? key;
288
+ }
289
+ /**
290
+ * The gate over raw document text: validate, then judge.
291
+ *
292
+ * One entry point so no caller can do half of it. A document that does not
293
+ * validate has no maturity to judge — `attainable` is `outline` because that is
294
+ * the only honest thing to say about text that is not yet a document.
295
+ */
296
+ export function gateDesignDocument(text, kind, file) {
297
+ const document = validateDesignArtifact(text, kind, file);
298
+ if (!document.ok || document.value === null) {
299
+ return { attainable: "outline", failures: document.failures, obligations: [] };
300
+ }
301
+ const split = splitDesignDocument(text);
302
+ const sections = split === null ? [] : parseBody(split.body, split.bodyLine).sections;
303
+ return checkMaturity(document.value, sections, kind, file);
304
+ }
305
+ //# sourceMappingURL=maturity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"maturity.js","sourceRoot":"","sources":["../../../src/domain/design/maturity.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * Where each normative artifact lives, and what its file is called.
3
+ *
4
+ * This is what makes immutability CHECKABLE rather than promised: the revision
5
+ * is part of the file name, so publishing `@r2` writes a new file and cannot
6
+ * overwrite `@r1` — not by policy, but because they are different paths. An
7
+ * asset goes further and carries its own digest, so different bytes can never
8
+ * occupy the same name.
9
+ *
10
+ * The directory layout is contract too (spec § *Package unit and durable
11
+ * location*): `flows/`, `screens/`, `baselines/` and `governance/` always
12
+ * exist; `design-system/`, `renditions/`, `tokens/` and `assets/` appear when
13
+ * the content requires them.
14
+ */
15
+ /** `2` → `r002`. Three digits so a directory listing sorts the way a human reads it. */
16
+ export function revisionSegment(revision) {
17
+ return `r${String(revision).padStart(3, "0")}`;
18
+ }
19
+ export const NAMING = {
20
+ flow: {
21
+ dir: "flows",
22
+ prefix: (id, revision) => `${id}-${revisionSegment(revision)}-`,
23
+ suffix: ".md",
24
+ },
25
+ screen: {
26
+ dir: "screens",
27
+ prefix: (id, revision) => `${id}-${revisionSegment(revision)}-`,
28
+ suffix: ".md",
29
+ },
30
+ rule: {
31
+ dir: "design-system/rules",
32
+ prefix: (id, revision) => `${id}-${revisionSegment(revision)}-`,
33
+ suffix: ".md",
34
+ },
35
+ token: {
36
+ dir: "tokens",
37
+ prefix: (id, revision) => `${id}-${revisionSegment(revision)}-`,
38
+ suffix: ".tokens.json",
39
+ },
40
+ rendition: {
41
+ dir: "renditions",
42
+ prefix: (id, revision) => `${id}-${revisionSegment(revision)}-`,
43
+ suffix: "/rendition.json",
44
+ },
45
+ };
46
+ /** `baselines/DES-001-r004.json` — no slug: a baseline seals a revision, not a name. */
47
+ export function baselinePath(packageId, revision) {
48
+ return `baselines/${packageId}-${revisionSegment(revision)}.json`;
49
+ }
50
+ /**
51
+ * Regenerable projections. They are NOT normative and never appear in the
52
+ * catalog: a baseline that selected them would make its digest depend on
53
+ * something derived, and re-rendering the landing page would rewrite history.
54
+ */
55
+ export const PROJECTIONS = ["PACKAGE.md", "design-system/DESIGN.md"];
56
+ /**
57
+ * Where each governance record lives (T7.1).
58
+ *
59
+ * Separate from `NAMING` on purpose: a record is not a normative artifact, is
60
+ * never selected by a baseline, and has no revision of its own — it decides ON
61
+ * one. Folding it into the same table would hand it a revision segment it must
62
+ * not have.
63
+ */
64
+ export const GOVERNANCE_NAMING = {
65
+ review: { dir: "governance/reviews", prefix: "REV-" },
66
+ revocation: { dir: "governance/revocations", prefix: "RVK-" },
67
+ };
68
+ /** `governance/reviews/REV-001.json`, or why the path does not honor the rule. */
69
+ export function checkGovernanceNaming(kind, path, id) {
70
+ const rule = GOVERNANCE_NAMING[kind];
71
+ const expected = `${rule.dir}/${id}.json`;
72
+ if (path === expected)
73
+ return { ok: true };
74
+ return {
75
+ ok: false,
76
+ why: `'${path}' no es la ubicación de ${id}`,
77
+ expected,
78
+ };
79
+ }
80
+ /** Does `path` name revision `revision` of artifact `id`, in the right place? */
81
+ export function checkNaming(kind, path, id, revision) {
82
+ const rule = NAMING[kind];
83
+ const expected = `${rule.dir}/${rule.prefix(id, revision)}<slug>${rule.suffix}`;
84
+ if (PROJECTIONS.includes(path)) {
85
+ return {
86
+ ok: false,
87
+ why: `'${path}' es una proyección regenerable y no puede catalogarse como artefacto normativo`,
88
+ expected,
89
+ };
90
+ }
91
+ if (!path.startsWith(`${rule.dir}/`)) {
92
+ return { ok: false, why: `'${path}' no vive en '${rule.dir}/'`, expected };
93
+ }
94
+ const rest = path.slice(rule.dir.length + 1);
95
+ if (!rest.startsWith(rule.prefix(id, revision))) {
96
+ // The revision in the name is the whole point: without it, publishing the
97
+ // next revision would write over the one already referenced.
98
+ return {
99
+ ok: false,
100
+ why: `'${path}' no lleva '${rule.prefix(id, revision)}' en el nombre, así que su revisión no está en el path`,
101
+ expected,
102
+ };
103
+ }
104
+ if (!rest.endsWith(rule.suffix)) {
105
+ return { ok: false, why: `'${path}' no termina en '${rule.suffix}'`, expected };
106
+ }
107
+ const slug = rest.slice(rule.prefix(id, revision).length, rest.length - (rule.suffix?.length ?? 0));
108
+ if (!/^[a-z0-9]+(-[a-z0-9]+)*$/.test(slug)) {
109
+ return {
110
+ ok: false,
111
+ why: `'${slug}' no es un slug: solo minúsculas, números y guiones`,
112
+ expected,
113
+ };
114
+ }
115
+ return { ok: true };
116
+ }
117
+ //# sourceMappingURL=naming.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"naming.js","sourceRoot":"","sources":["../../../src/domain/design/naming.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAWH,wFAAwF;AACxF,MAAM,UAAU,eAAe,CAAC,QAAgB;IAC9C,OAAO,IAAI,MAAM,CAAC,QAAQ,CAAC,CAAC,QAAQ,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC;AACjD,CAAC;AAED,MAAM,CAAC,MAAM,MAAM,GAA2E;IAC5F,IAAI,EAAE;QACJ,GAAG,EAAE,OAAO;QACZ,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG;QAC/D,MAAM,EAAE,KAAK;KACd;IACD,MAAM,EAAE;QACN,GAAG,EAAE,SAAS;QACd,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG;QAC/D,MAAM,EAAE,KAAK;KACd;IACD,IAAI,EAAE;QACJ,GAAG,EAAE,qBAAqB;QAC1B,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG;QAC/D,MAAM,EAAE,KAAK;KACd;IACD,KAAK,EAAE;QACL,GAAG,EAAE,QAAQ;QACb,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG;QAC/D,MAAM,EAAE,cAAc;KACvB;IACD,SAAS,EAAE;QACT,GAAG,EAAE,YAAY;QACjB,MAAM,EAAE,CAAC,EAAE,EAAE,QAAQ,EAAE,EAAE,CAAC,GAAG,EAAE,IAAI,eAAe,CAAC,QAAQ,CAAC,GAAG;QAC/D,MAAM,EAAE,iBAAiB;KAC1B;CACF,CAAC;AAEF,wFAAwF;AACxF,MAAM,UAAU,YAAY,CAAC,SAAiB,EAAE,QAAgB;IAC9D,OAAO,aAAa,SAAS,IAAI,eAAe,CAAC,QAAQ,CAAC,OAAO,CAAC;AACpE,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,YAAY,EAAE,yBAAyB,CAAC,CAAC;AAErE;;;;;;;GAOG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAqE;IACjG,MAAM,EAAE,EAAE,GAAG,EAAE,oBAAoB,EAAE,MAAM,EAAE,MAAM,EAAE;IACrD,UAAU,EAAE,EAAE,GAAG,EAAE,wBAAwB,EAAE,MAAM,EAAE,MAAM,EAAE;CAC9D,CAAC;AAEF,kFAAkF;AAClF,MAAM,UAAU,qBAAqB,CACnC,IAA6B,EAC7B,IAAY,EACZ,EAAU;IAEV,MAAM,IAAI,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IACrC,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,EAAE,OAAO,CAAC;IAC1C,IAAI,IAAI,KAAK,QAAQ;QAAE,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;IAC3C,OAAO;QACL,EAAE,EAAE,KAAK;QACT,GAAG,EAAE,IAAI,IAAI,2BAA2B,EAAE,EAAE;QAC5C,QAAQ;KACT,CAAC;AACJ,CAAC;AAWD,iFAAiF;AACjF,MAAM,UAAU,WAAW,CACzB,IAAe,EACf,IAAY,EACZ,EAAU,EACV,QAAgB;IAEhB,MAAM,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IAC1B,MAAM,QAAQ,GAAG,GAAG,IAAI,CAAC,GAAG,IAAI,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;IAEhF,IAAI,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,OAAO;YACL,EAAE,EAAE,KAAK;YACT,GAAG,EAAE,IAAI,IAAI,iFAAiF;YAC9F,QAAQ;SACT,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,GAAG,GAAG,CAAC,EAAE,CAAC;QACrC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,IAAI,iBAAiB,IAAI,CAAC,GAAG,IAAI,EAAE,QAAQ,EAAE,CAAC;IAC7E,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC7C,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,EAAE,CAAC;QAChD,0EAA0E;QAC1E,6DAA6D;QAC7D,OAAO;YACL,EAAE,EAAE,KAAK;YACT,GAAG,EAAE,IAAI,IAAI,eAAe,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,wDAAwD;YAC7G,QAAQ;SACT,CAAC;IACJ,CAAC;IACD,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QAChC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,IAAI,IAAI,oBAAoB,IAAI,CAAC,MAAM,GAAG,EAAE,QAAQ,EAAE,CAAC;IAClF,CAAC;IACD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CACrB,IAAI,CAAC,MAAM,CAAC,EAAE,EAAE,QAAQ,CAAC,CAAC,MAAM,EAChC,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC,CAAC,CACzC,CAAC;IACF,IAAI,CAAC,0BAA0B,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,OAAO;YACL,EAAE,EAAE,KAAK;YACT,GAAG,EAAE,IAAI,IAAI,qDAAqD;YAClE,QAAQ;SACT,CAAC;IACJ,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC;AACtB,CAAC"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * The offline guarantee of a portable export, checked as a REJECTION.
3
+ *
4
+ * AC-REN-07 is not "prefer local assets": an offline preview that loads a font,
5
+ * a script, an image or a datum from a URL shows something different the day the
6
+ * network, the CDN or the account is gone — and it fails silently, looking like a
7
+ * rendering quirk. So a remote resource here is a validation error, never a
8
+ * warning: the whole value of a local snapshot is that what you see is what the
9
+ * package contains.
10
+ *
11
+ * Two deliberate calls.
12
+ *
13
+ * **It scans text instead of parsing.** A parser would tell a reference apart
14
+ * from prose, at the cost of a dependency, and would still have to decide what a
15
+ * URL inside a `style` attribute is. Scanning over-detects at worst, and in this
16
+ * direction over-detection is the safe failure: the author moves the URL out of
17
+ * the export and the export stays self-sufficient.
18
+ *
19
+ * **A hyperlink counts too.** `<a href="https://figma.com/…">` loads nothing
20
+ * until somebody clicks it, so a stricter reading would let it through. It is
21
+ * still reported, because the package already has the right place for that
22
+ * pointer — `provider.locator` in `rendition.json`, where a locator is recorded
23
+ * as a locator and cannot be mistaken for the evidence. Keeping the export free
24
+ * of every absolute URL is also what makes this check a scan rather than a parse.
25
+ *
26
+ * What is allowed is what travels inside the file or beside it: `data:` URIs,
27
+ * fragments, and paths relative to the rendition's own directory.
28
+ */
29
+ /** A remote reference: any scheme-qualified or protocol-relative URL. */
30
+ const REMOTE_URL = /(?:\b[a-z][a-z0-9+.-]*:\/\/|(?<![a-z0-9+.:/])\/\/)[^\s"'`)<>]+/gi;
31
+ /** Schemes that carry their content inline, so they are not remote at all. */
32
+ const INLINE_SCHEMES = /^(?:data|blob|about|cid):/i;
33
+ /**
34
+ * `xmlns`/`xmlns:prefix` attributes, blanked before scanning.
35
+ *
36
+ * A namespace URI is an IDENTIFIER, not a fetch: nothing resolves
37
+ * `http://www.w3.org/2000/svg` over the network. And every inline SVG carries
38
+ * one, so treating it as a remote resource would reject exactly the format the
39
+ * static-preview requirement recommends.
40
+ */
41
+ const NAMESPACE_ATTRIBUTE = /\bxmlns(?::[A-Za-z][\w.-]*)?\s*=\s*(?:"[^"]*"|'[^']*')/gi;
42
+ /** Runtime calls that fetch at display time, whatever the URL looks like. */
43
+ const NETWORK_CALLS = [
44
+ [/\bfetch\s*\(/i, "fetch()"],
45
+ [/\bXMLHttpRequest\b/, "XMLHttpRequest"],
46
+ [/\bnew\s+WebSocket\b/, "WebSocket"],
47
+ [/\bnew\s+EventSource\b/, "EventSource"],
48
+ [/\bimportScripts\s*\(/i, "importScripts()"],
49
+ [/\bnavigator\s*\.\s*sendBeacon\b/, "navigator.sendBeacon()"],
50
+ ];
51
+ /**
52
+ * Judge an HTML export's self-sufficiency.
53
+ *
54
+ * Every finding quotes the offending text so the author can search for it: in a
55
+ * 400-line export, "there is a remote resource somewhere" is a dead end, and
56
+ * this is the one check whose fix always starts by finding that string.
57
+ */
58
+ export function checkOfflineHtml(html, artifact) {
59
+ const scannable = html.replace(NAMESPACE_ATTRIBUTE, "");
60
+ const failures = [];
61
+ for (const url of remoteUrls(scannable)) {
62
+ failures.push({
63
+ code: "DESIGN_REMOTE_RESOURCE",
64
+ artifact,
65
+ message: `el export referencia '${url}', que vive fuera del package`,
66
+ action: "un export portable es autosuficiente: incrustá el recurso (inline o como data: URI), usá una ruta relativa a la carpeta de la rendition, o registrá el locator del proveedor en 'provider.locator'",
67
+ });
68
+ }
69
+ for (const [pattern, what] of NETWORK_CALLS) {
70
+ if (!pattern.test(scannable))
71
+ continue;
72
+ failures.push({
73
+ code: "DESIGN_REMOTE_RESOURCE",
74
+ artifact,
75
+ message: `el export usa ${what}: pide datos en tiempo de visualización`,
76
+ action: "incrustá en el propio HTML los datos que la preview necesita: sin red tiene que verse igual",
77
+ });
78
+ }
79
+ return failures;
80
+ }
81
+ /** Every distinct remote URL in the text, in order of appearance. */
82
+ function remoteUrls(html) {
83
+ const out = [];
84
+ for (const match of html.matchAll(REMOTE_URL)) {
85
+ const url = match[0].replace(/[.,;:!?]+$/, "");
86
+ if (INLINE_SCHEMES.test(url) || out.includes(url))
87
+ continue;
88
+ out.push(url);
89
+ }
90
+ return out;
91
+ }
92
+ //# sourceMappingURL=offline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"offline.js","sourceRoot":"","sources":["../../../src/domain/design/offline.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,yEAAyE;AACzE,MAAM,UAAU,GAAG,kEAAkE,CAAC;AAEtF,8EAA8E;AAC9E,MAAM,cAAc,GAAG,4BAA4B,CAAC;AAEpD;;;;;;;GAOG;AACH,MAAM,mBAAmB,GAAG,0DAA0D,CAAC;AAEvF,6EAA6E;AAC7E,MAAM,aAAa,GAAoC;IACrD,CAAC,eAAe,EAAE,SAAS,CAAC;IAC5B,CAAC,oBAAoB,EAAE,gBAAgB,CAAC;IACxC,CAAC,qBAAqB,EAAE,WAAW,CAAC;IACpC,CAAC,uBAAuB,EAAE,aAAa,CAAC;IACxC,CAAC,uBAAuB,EAAE,iBAAiB,CAAC;IAC5C,CAAC,iCAAiC,EAAE,wBAAwB,CAAC;CAC9D,CAAC;AAEF;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,QAAgB;IAC7D,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,mBAAmB,EAAE,EAAE,CAAC,CAAC;IACxD,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,KAAK,MAAM,GAAG,IAAI,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QACxC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,wBAAwB;YAC9B,QAAQ;YACR,OAAO,EAAE,yBAAyB,GAAG,+BAA+B;YACpE,MAAM,EACJ,oMAAoM;SACvM,CAAC,CAAC;IACL,CAAC;IACD,KAAK,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,aAAa,EAAE,CAAC;QAC5C,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC;YAAE,SAAS;QACvC,QAAQ,CAAC,IAAI,CAAC;YACZ,IAAI,EAAE,wBAAwB;YAC9B,QAAQ;YACR,OAAO,EAAE,iBAAiB,IAAI,yCAAyC;YACvE,MAAM,EACJ,6FAA6F;SAChG,CAAC,CAAC;IACL,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,qEAAqE;AACrE,SAAS,UAAU,CAAC,IAAY;IAC9B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,EAAE,CAAC;QAC9C,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;QAC/C,IAAI,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC;YAAE,SAAS;QAC5D,GAAG,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChB,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC"}