@llm-dev-ops/agentics-cli 2.1.5 → 2.3.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 (76) hide show
  1. package/dist/pipeline/auto-chain.d.ts +73 -0
  2. package/dist/pipeline/auto-chain.d.ts.map +1 -1
  3. package/dist/pipeline/auto-chain.js +525 -38
  4. package/dist/pipeline/auto-chain.js.map +1 -1
  5. package/dist/pipeline/phase2/phases/prompt-generator.d.ts.map +1 -1
  6. package/dist/pipeline/phase2/phases/prompt-generator.js +53 -6
  7. package/dist/pipeline/phase2/phases/prompt-generator.js.map +1 -1
  8. package/dist/pipeline/phase2/schemas.d.ts +10 -10
  9. package/dist/pipeline/phase4/phases/http-server-generator.d.ts +12 -0
  10. package/dist/pipeline/phase4/phases/http-server-generator.d.ts.map +1 -1
  11. package/dist/pipeline/phase4/phases/http-server-generator.js +92 -25
  12. package/dist/pipeline/phase4/phases/http-server-generator.js.map +1 -1
  13. package/dist/pipeline/phase5-build/phase5-build-coordinator.d.ts.map +1 -1
  14. package/dist/pipeline/phase5-build/phase5-build-coordinator.js +44 -0
  15. package/dist/pipeline/phase5-build/phase5-build-coordinator.js.map +1 -1
  16. package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts +75 -0
  17. package/dist/pipeline/phase5-build/phases/post-generation-validator.d.ts.map +1 -0
  18. package/dist/pipeline/phase5-build/phases/post-generation-validator.js +728 -0
  19. package/dist/pipeline/phase5-build/phases/post-generation-validator.js.map +1 -0
  20. package/dist/pipeline/phase5-build/types.d.ts +1 -1
  21. package/dist/pipeline/phase5-build/types.d.ts.map +1 -1
  22. package/dist/pipeline/types.d.ts +84 -0
  23. package/dist/pipeline/types.d.ts.map +1 -1
  24. package/dist/pipeline/types.js +43 -1
  25. package/dist/pipeline/types.js.map +1 -1
  26. package/dist/synthesis/consensus-svg.d.ts +19 -0
  27. package/dist/synthesis/consensus-svg.d.ts.map +1 -0
  28. package/dist/synthesis/consensus-svg.js +95 -0
  29. package/dist/synthesis/consensus-svg.js.map +1 -0
  30. package/dist/synthesis/consensus-tiers.d.ts +99 -0
  31. package/dist/synthesis/consensus-tiers.d.ts.map +1 -0
  32. package/dist/synthesis/consensus-tiers.js +285 -0
  33. package/dist/synthesis/consensus-tiers.js.map +1 -0
  34. package/dist/synthesis/domain-labor-classifier.d.ts +101 -0
  35. package/dist/synthesis/domain-labor-classifier.d.ts.map +1 -0
  36. package/dist/synthesis/domain-labor-classifier.js +312 -0
  37. package/dist/synthesis/domain-labor-classifier.js.map +1 -0
  38. package/dist/synthesis/domain-unit-registry.d.ts +59 -0
  39. package/dist/synthesis/domain-unit-registry.d.ts.map +1 -0
  40. package/dist/synthesis/domain-unit-registry.js +294 -0
  41. package/dist/synthesis/domain-unit-registry.js.map +1 -0
  42. package/dist/synthesis/financial-claim-extractor.d.ts +52 -0
  43. package/dist/synthesis/financial-claim-extractor.d.ts.map +1 -0
  44. package/dist/synthesis/financial-claim-extractor.js +351 -0
  45. package/dist/synthesis/financial-claim-extractor.js.map +1 -0
  46. package/dist/synthesis/financial-consistency-rules.d.ts +66 -0
  47. package/dist/synthesis/financial-consistency-rules.d.ts.map +1 -0
  48. package/dist/synthesis/financial-consistency-rules.js +432 -0
  49. package/dist/synthesis/financial-consistency-rules.js.map +1 -0
  50. package/dist/synthesis/financial-consistency-runner.d.ts +73 -0
  51. package/dist/synthesis/financial-consistency-runner.d.ts.map +1 -0
  52. package/dist/synthesis/financial-consistency-runner.js +131 -0
  53. package/dist/synthesis/financial-consistency-runner.js.map +1 -0
  54. package/dist/synthesis/forbidden-spin-phrases.d.ts +32 -0
  55. package/dist/synthesis/forbidden-spin-phrases.d.ts.map +1 -0
  56. package/dist/synthesis/forbidden-spin-phrases.js +84 -0
  57. package/dist/synthesis/forbidden-spin-phrases.js.map +1 -0
  58. package/dist/synthesis/phase-gate-thresholds.d.ts +30 -0
  59. package/dist/synthesis/phase-gate-thresholds.d.ts.map +1 -0
  60. package/dist/synthesis/phase-gate-thresholds.js +34 -0
  61. package/dist/synthesis/phase-gate-thresholds.js.map +1 -0
  62. package/dist/synthesis/prompts/index.d.ts.map +1 -1
  63. package/dist/synthesis/prompts/index.js +22 -0
  64. package/dist/synthesis/prompts/index.js.map +1 -1
  65. package/dist/synthesis/simulation-artifact-generator.d.ts.map +1 -1
  66. package/dist/synthesis/simulation-artifact-generator.js +89 -1
  67. package/dist/synthesis/simulation-artifact-generator.js.map +1 -1
  68. package/dist/synthesis/simulation-renderers.d.ts +105 -2
  69. package/dist/synthesis/simulation-renderers.d.ts.map +1 -1
  70. package/dist/synthesis/simulation-renderers.js +1056 -92
  71. package/dist/synthesis/simulation-renderers.js.map +1 -1
  72. package/dist/synthesis/unit-economics-loader.d.ts +71 -0
  73. package/dist/synthesis/unit-economics-loader.d.ts.map +1 -0
  74. package/dist/synthesis/unit-economics-loader.js +200 -0
  75. package/dist/synthesis/unit-economics-loader.js.map +1 -0
  76. package/package.json +1 -1
@@ -0,0 +1,312 @@
1
+ /**
2
+ * ADR-PIPELINE-070: Domain Labor-Intensity Classifier
3
+ *
4
+ * Pure rules-based classifier. Maps the detected sector + free-text query
5
+ * keywords to a LaborProfile that downstream renderers consume:
6
+ *
7
+ * - Risk register injects a Workforce Impact section
8
+ * - Financial analysis adds a workforce exposure block
9
+ * - Decision memo RACI gains HR + Legal rows
10
+ * - Sensitivity table gains a change-management variable
11
+ *
12
+ * The classifier is intentionally coarse — it answers "is this sector
13
+ * labor-intensive enough that workforce risk MUST appear in the
14
+ * deliverables?" not "what specific labor risks does this engagement
15
+ * have?". The Workforce Impact rows it produces are templates labelled
16
+ * `*Template risk — refine with HR during pilot scoping*`.
17
+ */
18
+ import { classifySector } from './domain-unit-registry.js';
19
+ const SECTOR_PROFILES = [
20
+ {
21
+ sector: 'hospitality',
22
+ intensity: 'high',
23
+ unionizationRisk: 'high',
24
+ roleTypes: ['housekeeper', 'F&B server', 'front-desk associate', 'maintenance technician'],
25
+ regionMultipliers: { NA: 1.0, EMEA: 1.5, APAC: 0.9 },
26
+ notes: 'Housekeeping/F&B is labor-intensive; EMEA carries works-council obligations.',
27
+ },
28
+ {
29
+ sector: 'retail',
30
+ intensity: 'high',
31
+ unionizationRisk: 'medium',
32
+ roleTypes: ['floor associate', 'cashier', 'stockroom staff', 'shift supervisor'],
33
+ regionMultipliers: { NA: 1.0, EMEA: 1.3, APAC: 0.95 },
34
+ notes: 'Floor staff and stock teams scale with store count.',
35
+ },
36
+ {
37
+ sector: 'fleet',
38
+ intensity: 'high',
39
+ unionizationRisk: 'high',
40
+ roleTypes: ['driver', 'dispatcher', 'fleet mechanic'],
41
+ regionMultipliers: { NA: 1.0, EMEA: 1.4, APAC: 0.9 },
42
+ notes: 'Driver workforce is heavily regulated and frequently unionized in NA/EMEA.',
43
+ },
44
+ {
45
+ sector: 'healthcare',
46
+ intensity: 'high',
47
+ unionizationRisk: 'high',
48
+ roleTypes: ['registered nurse', 'allied health professional', 'clinical aide'],
49
+ regionMultipliers: { NA: 1.0, EMEA: 1.4, APAC: 0.95 },
50
+ notes: 'Nursing and allied health are protected categories with strong representation.',
51
+ },
52
+ {
53
+ sector: 'call-center',
54
+ intensity: 'high',
55
+ unionizationRisk: 'medium',
56
+ roleTypes: ['contact-center agent', 'team lead', 'workforce planner'],
57
+ regionMultipliers: { NA: 1.0, EMEA: 1.3, APAC: 1.0 },
58
+ notes: 'Performance-metric changes have direct labor implications.',
59
+ },
60
+ {
61
+ sector: 'manufacturing',
62
+ intensity: 'high',
63
+ unionizationRisk: 'high',
64
+ roleTypes: ['line operator', 'machinist', 'shift lead', 'maintenance technician'],
65
+ regionMultipliers: { NA: 1.0, EMEA: 1.4, APAC: 1.0 },
66
+ notes: 'Production-floor headcount scales with line count and shift coverage.',
67
+ },
68
+ {
69
+ sector: 'commercial-real-estate',
70
+ intensity: 'medium',
71
+ unionizationRisk: 'low',
72
+ roleTypes: ['facility operator', 'security officer', 'janitorial staff'],
73
+ regionMultipliers: { NA: 1.0, EMEA: 1.2, APAC: 0.95 },
74
+ notes: 'Facility ops and security are smaller per-property but still material to change-management.',
75
+ },
76
+ {
77
+ sector: 'data-center',
78
+ intensity: 'medium',
79
+ unionizationRisk: 'low',
80
+ roleTypes: ['site reliability engineer', 'data-center technician'],
81
+ regionMultipliers: { NA: 1.0, EMEA: 1.1, APAC: 1.0 },
82
+ notes: 'DC ops headcount is smaller but training cost on new processes is real.',
83
+ },
84
+ ];
85
+ const PROFILE_BY_SECTOR = new Map(SECTOR_PROFILES.map(p => [p.sector, p]));
86
+ const OVERRIDE_PATTERNS = [
87
+ {
88
+ direction: 'down',
89
+ target: 'low',
90
+ pattern: /\b(?:internal\s+(?:dev\s+tool|tooling|dashboard)|developer\s+productivity|engineering\s+velocity)\b/i,
91
+ reason: 'Internal developer tooling — knowledge workers only, no operational labor exposure.',
92
+ },
93
+ {
94
+ direction: 'down',
95
+ target: 'low',
96
+ pattern: /\b(?:saas|api\s+gateway|micro[-\s]?service|library|sdk|cli\s+tool)\b/i,
97
+ reason: 'Pure-software engagement — labor exposure limited to engineering team.',
98
+ },
99
+ {
100
+ direction: 'up',
101
+ target: 'high',
102
+ pattern: /\b(?:contact\s*center|call\s*center|warehouse\s+pickers?|housekeep|union(?:ized)?|works\s+council)\b/i,
103
+ reason: 'Query explicitly references operational labor — workforce impact required.',
104
+ },
105
+ ];
106
+ // ============================================================================
107
+ // Public API
108
+ // ============================================================================
109
+ const LOW_DEFAULT = {
110
+ intensity: 'low',
111
+ sector: 'unknown',
112
+ roleTypes: [],
113
+ unionizationRisk: 'low',
114
+ regionMultipliers: { NA: 1.0, EMEA: 1.0, APAC: 1.0 },
115
+ reasoning: 'No labor-intensive sector detected and no override pattern matched.',
116
+ };
117
+ /**
118
+ * ADR-PIPELINE-070: classify the labor intensity of an engagement.
119
+ *
120
+ * Inputs:
121
+ * - `domainAnalysis` — when present, its `domain` field is treated as the
122
+ * authoritative sector hint (from ADR-PIPELINE-041's pipeline output).
123
+ * - `query` — free-text query, used both for sector detection and for
124
+ * intensity-override patterns.
125
+ *
126
+ * The function never throws. Unknown sectors return the LOW_DEFAULT profile.
127
+ */
128
+ export function classifyLaborIntensity(domainAnalysis, query) {
129
+ const sectorHint = domainAnalysis?.domain ?? null;
130
+ const sector = classifySector(query, sectorHint);
131
+ const template = PROFILE_BY_SECTOR.get(sector);
132
+ let profile = template
133
+ ? {
134
+ intensity: template.intensity,
135
+ sector,
136
+ roleTypes: template.roleTypes,
137
+ unionizationRisk: template.unionizationRisk,
138
+ regionMultipliers: template.regionMultipliers,
139
+ reasoning: `Sector "${sector}" → ${template.intensity} labor intensity. ${template.notes}`,
140
+ }
141
+ : { ...LOW_DEFAULT, sector };
142
+ // Apply override patterns. Down-overrides win over up-overrides for
143
+ // genuinely soft engagements (a SaaS-for-hoteliers query should be low,
144
+ // not high, even though "hotel" matches the sector classifier).
145
+ for (const ov of OVERRIDE_PATTERNS) {
146
+ if (!ov.pattern.test(query))
147
+ continue;
148
+ if (ov.direction === 'down' && intensityRank(profile.intensity) > intensityRank(ov.target)) {
149
+ profile = { ...profile, intensity: ov.target, reasoning: ov.reason };
150
+ break;
151
+ }
152
+ if (ov.direction === 'up' && intensityRank(profile.intensity) < intensityRank(ov.target)) {
153
+ profile = { ...profile, intensity: ov.target, reasoning: ov.reason };
154
+ // Don't break — a later down-override should still win.
155
+ }
156
+ }
157
+ return profile;
158
+ }
159
+ function intensityRank(i) {
160
+ return i === 'high' ? 2 : i === 'medium' ? 1 : 0;
161
+ }
162
+ /** True when the renderer must inject workforce content. */
163
+ export function isLaborIntensive(profile) {
164
+ return profile.intensity !== 'low';
165
+ }
166
+ export function workforceRiskTemplate(profile) {
167
+ const rows = [
168
+ {
169
+ category: 'workforce',
170
+ risk: 'Labor reallocation disputes',
171
+ likelihood: 'Medium',
172
+ severity: 'High',
173
+ owner: 'HR + Ops',
174
+ mitigation: 'Joint labor/ops working group convened before pilot start.',
175
+ template: true,
176
+ },
177
+ {
178
+ category: 'workforce',
179
+ risk: 'EMEA works-council consultation obligation',
180
+ likelihood: profile.unionizationRisk === 'high' ? 'High' : 'Medium',
181
+ severity: 'Medium',
182
+ owner: 'Legal + Regional HR',
183
+ mitigation: 'CSRD-aligned notice period; minimum 30 days before EMEA rollout.',
184
+ template: true,
185
+ },
186
+ {
187
+ category: 'workforce',
188
+ risk: 'Change-management cost underestimated',
189
+ likelihood: 'Medium',
190
+ severity: 'Medium',
191
+ owner: 'Pilot PM',
192
+ mitigation: 'Dedicated change budget = 12% of pilot investment, tracked separately.',
193
+ template: true,
194
+ },
195
+ {
196
+ category: 'workforce',
197
+ risk: 'Role attrition from perceived job loss',
198
+ likelihood: 'Medium',
199
+ severity: 'High',
200
+ owner: 'HR',
201
+ mitigation: 'Explicit no-reduction commitment communicated for the pilot window.',
202
+ template: true,
203
+ },
204
+ {
205
+ category: 'workforce',
206
+ risk: 'Training burden on line managers',
207
+ likelihood: 'High',
208
+ severity: 'Low',
209
+ owner: 'Ops',
210
+ mitigation: 'Train-the-trainer model; cap at 4 hours per manager.',
211
+ template: true,
212
+ },
213
+ ];
214
+ return rows;
215
+ }
216
+ const ROLES_PER_OPERATIONAL_UNIT = {
217
+ hospitality: 0.085, // ~1 housekeeper per 12 rooms
218
+ retail: 18, // ~18 floor staff per store
219
+ fleet: 1.05, // driver + relief + occasional mechanic per vehicle
220
+ healthcare: 1.6, // nurses + aides per bed
221
+ 'call-center': 1.0, // 1 role per agent
222
+ manufacturing: 35, // line workers per plant
223
+ 'commercial-real-estate': 0.0006, // ~6 facility ops per 10K sqft
224
+ 'data-center': 0.0008,
225
+ };
226
+ const ROLE_LABEL = {
227
+ hospitality: 'housekeepers',
228
+ retail: 'floor associates',
229
+ fleet: 'drivers',
230
+ healthcare: 'nurses',
231
+ 'call-center': 'contact-center agents',
232
+ manufacturing: 'line operators',
233
+ 'commercial-real-estate': 'facility ops',
234
+ 'data-center': 'data-center technicians',
235
+ };
236
+ export function estimateWorkforceExposure(profile, inputs) {
237
+ if (!isLaborIntensive(profile))
238
+ return null;
239
+ const sector = profile.sector;
240
+ const ratio = ROLES_PER_OPERATIONAL_UNIT[sector] ?? 0;
241
+ // Prefer operational-unit math when available; fall back to a coarse
242
+ // headcount fraction so the block is never zero.
243
+ let rolesAffected = 0;
244
+ if (inputs.operationalUnits && ratio > 0) {
245
+ rolesAffected = Math.round(inputs.operationalUnits * ratio);
246
+ }
247
+ if (rolesAffected <= 0 && inputs.employees > 0) {
248
+ // Coarse fallback: assume 5–15% of headcount when sector is high intensity.
249
+ const frac = profile.intensity === 'high' ? 0.1 : 0.04;
250
+ rolesAffected = Math.round(inputs.employees * frac);
251
+ }
252
+ rolesAffected = Math.max(rolesAffected, 1);
253
+ const emeaShare = profile.regionMultipliers.EMEA / Object.values(profile.regionMultipliers).reduce((s, v) => s + v, 0);
254
+ const emeaUnionExposure = profile.unionizationRisk === 'low'
255
+ ? 0
256
+ : Math.round(rolesAffected * emeaShare);
257
+ const changeMgmtPct = 0.12;
258
+ const pilot = inputs.pilotInvestmentUsd ?? 1_000_000;
259
+ const changeMgmtBudgetLowUsd = Math.round(pilot * changeMgmtPct);
260
+ const changeMgmtBudgetHighUsd = Math.round(pilot * changeMgmtPct * 1.4);
261
+ return {
262
+ rolesAffected,
263
+ emeaUnionExposure,
264
+ changeMgmtBudgetLowUsd,
265
+ changeMgmtBudgetHighUsd,
266
+ changeMgmtPct,
267
+ reallocationNeutral: true,
268
+ primaryRoleLabel: ROLE_LABEL[sector] ?? 'operational staff',
269
+ };
270
+ }
271
+ export function workforceRaciTemplate(profile) {
272
+ if (!isLaborIntensive(profile))
273
+ return [];
274
+ return [
275
+ { role: 'HR', responsibility: 'Consulted', cadence: 'Every phase gate', template: true },
276
+ {
277
+ role: 'Legal',
278
+ responsibility: 'Consulted',
279
+ cadence: profile.unionizationRisk === 'high'
280
+ ? 'Required before EMEA rollout (works-council obligations)'
281
+ : 'Required before any cross-region rollout',
282
+ template: true,
283
+ },
284
+ {
285
+ role: 'Regional HR leads',
286
+ responsibility: 'Informed',
287
+ cadence: 'Weekly cadence during pilot',
288
+ template: true,
289
+ },
290
+ ];
291
+ }
292
+ export function workforceSensitivityRow(profile) {
293
+ if (!isLaborIntensive(profile))
294
+ return null;
295
+ return {
296
+ variable: 'Change management budget overrun',
297
+ range: '+20% / +50%',
298
+ impactPctOfPilot: 0.18,
299
+ reasoning: profile.intensity === 'high'
300
+ ? 'High labor intensity — change-management overruns dominate pilot risk.'
301
+ : 'Moderate labor exposure — overruns affect ROI but not direction.',
302
+ };
303
+ }
304
+ export function buildLaborProfileArtifact(profile, exposure) {
305
+ return {
306
+ version: '1.0',
307
+ generated_at: new Date().toISOString(),
308
+ profile,
309
+ exposure,
310
+ };
311
+ }
312
+ //# sourceMappingURL=domain-labor-classifier.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-labor-classifier.js","sourceRoot":"","sources":["../../src/synthesis/domain-labor-classifier.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,59 @@
1
+ /**
2
+ * ADR-PIPELINE-066: Domain Unit Registry
3
+ *
4
+ * Maps a detected sector to its domain unit (the thing savings actually scale
5
+ * with) and a savings-base formula. Replaces per-employee heuristics whenever
6
+ * a sector in this registry is detected.
7
+ *
8
+ * Pure functions — no I/O.
9
+ */
10
+ import type { DomainUnit } from '../pipeline/types.js';
11
+ export type Sector = 'hospitality' | 'commercial-real-estate' | 'fleet' | 'retail' | 'manufacturing' | 'healthcare' | 'data-center' | 'call-center' | 'unknown';
12
+ export interface SectorRegistryEntry {
13
+ readonly sector: Exclude<Sector, 'unknown'>;
14
+ readonly domainUnit: DomainUnit;
15
+ /** Keys this sector expects in UnitEconomicsScope (primary first). */
16
+ readonly scopeKeys: readonly string[];
17
+ /**
18
+ * Formula description for rendering. e.g. "rooms × occupancy × $/orn".
19
+ * Not evaluated — just displayed so reviewers see the unit economics.
20
+ */
21
+ readonly savingsFormula: string;
22
+ /** Unit savings key expected in UnitEconomics.unit_savings. */
23
+ readonly unitSavingsKey: string;
24
+ }
25
+ /**
26
+ * The eight sectors called out in ADR-PIPELINE-066 §3.
27
+ * Order matters for classification — more specific patterns first.
28
+ */
29
+ export declare const SECTOR_REGISTRY: readonly SectorRegistryEntry[];
30
+ export declare function getSectorEntry(sector: Sector): SectorRegistryEntry | null;
31
+ /**
32
+ * Classify a query into a sector from the registry, or 'unknown'.
33
+ * Prefers an explicit sector hint (from domain_analysis.sector) when provided.
34
+ */
35
+ export declare function classifySector(query: string, sectorHint?: string | null): Sector;
36
+ export interface DomainScale {
37
+ /** Employees — still available for context, NOT as a savings multiplicand. */
38
+ readonly employees: number;
39
+ /** Primary operational units (rooms, sqft, vehicles, etc.). */
40
+ readonly operationalUnits: number;
41
+ /** Human-readable label for the operational unit. */
42
+ readonly unitLabel: string;
43
+ /** Short form for display. */
44
+ readonly unitAbbrev: string;
45
+ /** Detected sector or 'unknown'. */
46
+ readonly sector: Sector;
47
+ /** Where the operational count came from. */
48
+ readonly source: 'prototype' | 'query-regex' | 'default';
49
+ }
50
+ /** Extract employee count from free text. Used for context only. */
51
+ export declare function extractEmployeeCountFromText(query: string): number;
52
+ /**
53
+ * ADR-PIPELINE-066 §4: Replace `extractEmployeeCount` with a richer shape that
54
+ * carries the operational unit *and* its source. Savings math that used to
55
+ * multiply `employees * ratio` must now multiply `operationalUnits * ratio`
56
+ * whenever `source !== 'default'`.
57
+ */
58
+ export declare function extractDomainScale(query: string, sectorHint?: string | null): DomainScale;
59
+ //# sourceMappingURL=domain-unit-registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"domain-unit-registry.d.ts","sourceRoot":"","sources":["../../src/synthesis/domain-unit-registry.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,MAAM,MAAM,MAAM,GACd,aAAa,GACb,wBAAwB,GACxB,OAAO,GACP,QAAQ,GACR,eAAe,GACf,YAAY,GACZ,aAAa,GACb,aAAa,GACb,SAAS,CAAC;AAEd,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;IAC5C,QAAQ,CAAC,UAAU,EAAE,UAAU,CAAC;IAChC,sEAAsE;IACtE,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;IAChC,+DAA+D;IAC/D,QAAQ,CAAC,cAAc,EAAE,MAAM,CAAC;CACjC;AAED;;;GAGG;AACH,eAAO,MAAM,eAAe,EAAE,SAAS,mBAAmB,EAyDzD,CAAC;AAMF,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,mBAAmB,GAAG,IAAI,CAEzE;AAwGD;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,MAAM,CASR;AAmBD,MAAM,WAAW,WAAW;IAC1B,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,+DAA+D;IAC/D,QAAQ,CAAC,gBAAgB,EAAE,MAAM,CAAC;IAClC,qDAAqD;IACrD,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,8BAA8B;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,oCAAoC;IACpC,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,6CAA6C;IAC7C,QAAQ,CAAC,MAAM,EAAE,WAAW,GAAG,aAAa,GAAG,SAAS,CAAC;CAC1D;AAED,oEAAoE;AACpE,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAmBlE;AAoBD;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,MAAM,EACb,UAAU,CAAC,EAAE,MAAM,GAAG,IAAI,GACzB,WAAW,CA2Db"}