@qulib/core 0.7.0 → 0.9.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.
- package/README.md +30 -5
- package/bin/qulib.js +2 -3
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/orders/route.d.ts +7 -0
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/orders/route.d.ts.map +1 -0
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/orders/route.js +7 -0
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/users/route.d.ts +10 -0
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/users/route.d.ts.map +1 -0
- package/dist/__tests__/fixtures/api-fixture-repo/app/api/users/route.js +9 -0
- package/dist/__tests__/fixtures/api-fixture-repo/pages/api/health.d.ts +9 -0
- package/dist/__tests__/fixtures/api-fixture-repo/pages/api/health.d.ts.map +1 -0
- package/dist/__tests__/fixtures/api-fixture-repo/pages/api/health.js +10 -0
- package/dist/__tests__/playwright-available.d.ts +32 -0
- package/dist/__tests__/playwright-available.d.ts.map +1 -0
- package/dist/__tests__/playwright-available.js +35 -0
- package/dist/adapters/api-adapter.d.ts +26 -0
- package/dist/adapters/api-adapter.d.ts.map +1 -1
- package/dist/adapters/api-adapter.js +156 -2
- package/dist/adapters/ci-results-adapter.d.ts +67 -0
- package/dist/adapters/ci-results-adapter.d.ts.map +1 -0
- package/dist/adapters/ci-results-adapter.js +143 -0
- package/dist/adapters/cypress-e2e-adapter.d.ts.map +1 -1
- package/dist/adapters/cypress-e2e-adapter.js +25 -2
- package/dist/adapters/playwright-adapter.d.ts.map +1 -1
- package/dist/adapters/playwright-adapter.js +94 -2
- package/dist/adapters/pr-metadata-adapter.d.ts +75 -0
- package/dist/adapters/pr-metadata-adapter.d.ts.map +1 -0
- package/dist/adapters/pr-metadata-adapter.js +146 -0
- package/dist/adapters/validate-specs.d.ts +55 -0
- package/dist/adapters/validate-specs.d.ts.map +1 -0
- package/dist/adapters/validate-specs.js +67 -0
- package/dist/baseline/baseline.d.ts +54 -0
- package/dist/baseline/baseline.d.ts.map +1 -0
- package/dist/baseline/baseline.js +252 -0
- package/dist/baseline/baseline.schema.d.ts +233 -0
- package/dist/baseline/baseline.schema.d.ts.map +1 -0
- package/dist/baseline/baseline.schema.js +59 -0
- package/dist/cli/confidence-run.d.ts +16 -0
- package/dist/cli/confidence-run.d.ts.map +1 -0
- package/dist/cli/confidence-run.js +158 -0
- package/dist/cli/index.d.ts +11 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +80 -4
- package/dist/cli/scaffold-run.d.ts +86 -0
- package/dist/cli/scaffold-run.d.ts.map +1 -0
- package/dist/cli/scaffold-run.js +232 -0
- package/dist/cli/score-automation-run.d.ts +25 -0
- package/dist/cli/score-automation-run.d.ts.map +1 -0
- package/dist/cli/score-automation-run.js +123 -0
- package/dist/examples/notquality-dogfood/fixture.d.ts +166 -0
- package/dist/examples/notquality-dogfood/fixture.d.ts.map +1 -0
- package/dist/examples/notquality-dogfood/fixture.js +174 -0
- package/dist/examples/notquality-dogfood/run.d.ts +34 -0
- package/dist/examples/notquality-dogfood/run.d.ts.map +1 -0
- package/dist/examples/notquality-dogfood/run.js +139 -0
- package/dist/index.d.ts +18 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +13 -0
- package/dist/recipes/a11y.d.ts +36 -0
- package/dist/recipes/a11y.d.ts.map +1 -0
- package/dist/recipes/a11y.js +118 -0
- package/dist/recipes/auth.d.ts +38 -0
- package/dist/recipes/auth.d.ts.map +1 -0
- package/dist/recipes/auth.js +156 -0
- package/dist/recipes/index.d.ts +26 -0
- package/dist/recipes/index.d.ts.map +1 -0
- package/dist/recipes/index.js +41 -0
- package/dist/recipes/nav.d.ts +34 -0
- package/dist/recipes/nav.d.ts.map +1 -0
- package/dist/recipes/nav.js +128 -0
- package/dist/recipes/seed.d.ts +34 -0
- package/dist/recipes/seed.d.ts.map +1 -0
- package/dist/recipes/seed.js +87 -0
- package/dist/scaffold-tests.d.ts +21 -0
- package/dist/scaffold-tests.d.ts.map +1 -1
- package/dist/scaffold-tests.js +12 -2
- package/dist/schemas/automation-maturity.schema.d.ts +8 -8
- package/dist/schemas/automation-maturity.schema.d.ts.map +1 -1
- package/dist/schemas/automation-maturity.schema.js +1 -0
- package/dist/schemas/confidence.schema.d.ts +526 -0
- package/dist/schemas/confidence.schema.d.ts.map +1 -0
- package/dist/schemas/confidence.schema.js +161 -0
- package/dist/schemas/gap-analysis.schema.d.ts +8 -8
- package/dist/schemas/gap-analysis.schema.js +1 -1
- package/dist/schemas/index.d.ts +3 -0
- package/dist/schemas/index.d.ts.map +1 -1
- package/dist/schemas/index.js +3 -0
- package/dist/schemas/public-surface.schema.d.ts +5 -5
- package/dist/schemas/recipe.schema.d.ts +66 -0
- package/dist/schemas/recipe.schema.d.ts.map +1 -0
- package/dist/schemas/recipe.schema.js +45 -0
- package/dist/schemas/repo-analysis.schema.d.ts +7 -7
- package/dist/schemas/views.schema.d.ts +234 -0
- package/dist/schemas/views.schema.d.ts.map +1 -0
- package/dist/schemas/views.schema.js +82 -0
- package/dist/tools/repo/api-surface.d.ts +59 -0
- package/dist/tools/repo/api-surface.d.ts.map +1 -0
- package/dist/tools/repo/api-surface.js +414 -0
- package/dist/tools/scoring/api-coverage.d.ts +74 -0
- package/dist/tools/scoring/api-coverage.d.ts.map +1 -0
- package/dist/tools/scoring/api-coverage.js +158 -0
- package/dist/tools/scoring/automation-maturity.d.ts +11 -1
- package/dist/tools/scoring/automation-maturity.d.ts.map +1 -1
- package/dist/tools/scoring/automation-maturity.js +43 -9
- package/dist/tools/scoring/confidence-from-qulib.d.ts +34 -0
- package/dist/tools/scoring/confidence-from-qulib.d.ts.map +1 -0
- package/dist/tools/scoring/confidence-from-qulib.js +206 -0
- package/dist/tools/scoring/confidence-views.d.ts +40 -0
- package/dist/tools/scoring/confidence-views.d.ts.map +1 -0
- package/dist/tools/scoring/confidence-views.js +163 -0
- package/dist/tools/scoring/confidence.d.ts +32 -0
- package/dist/tools/scoring/confidence.d.ts.map +1 -0
- package/dist/tools/scoring/confidence.js +180 -0
- package/dist/tools/scoring/levels.d.ts +15 -0
- package/dist/tools/scoring/levels.d.ts.map +1 -0
- package/dist/tools/scoring/levels.js +21 -0
- package/package.json +15 -7
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
+
export { slugifyUrl, defaultBaselineRoot, saveBaseline, loadBaseline, listBaselines, deleteBaseline, compareBaselines, } from './baseline/baseline.js';
|
|
3
|
+
export type { BaselineGap, BaselineSnapshot, BaselineDeltaItem, BaselineDelta, } from './baseline/baseline.schema.js';
|
|
2
4
|
export { toAgentSummary } from './agent-summary.js';
|
|
3
5
|
export type { AgentSummary, AgentSummaryPolicy, AgentGate, CoverageStatus, AgentSummaryCostSummary, } from './agent-summary.js';
|
|
4
6
|
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
@@ -6,9 +8,14 @@ export type { StorageStateInvalidReason, StorageStateValidationResult, } from '.
|
|
|
6
8
|
export { exploreAuth } from './tools/auth/explore.js';
|
|
7
9
|
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/auth/custom-providers.js';
|
|
8
10
|
export { scanRepo } from './tools/repo/scan.js';
|
|
11
|
+
export { discoverApiSurface, discoverApiSurfaceWithRepo } from './tools/repo/api-surface.js';
|
|
12
|
+
export type { ApiSurface, DiscoveredEndpoint, DiscoverApiSurfaceOptions } from './tools/repo/api-surface.js';
|
|
9
13
|
export { computeAutomationMaturity } from './tools/scoring/automation-maturity.js';
|
|
14
|
+
export { computeApiCoverage } from './tools/scoring/api-coverage.js';
|
|
15
|
+
export type { ApiCoverageResult, ApiEndpointCoverage } from './tools/scoring/api-coverage.js';
|
|
10
16
|
export { scaffoldTests } from './scaffold-tests.js';
|
|
11
17
|
export type { ScaffoldOptions, ScaffoldResult, ProjectConfig } from './scaffold-tests.js';
|
|
18
|
+
export { expandRecipes, buildAuthScenarios, buildA11yScenarios, buildNavScenarios, buildSeedScenarios } from './recipes/index.js';
|
|
12
19
|
export { createProvider } from './llm/provider-registry.js';
|
|
13
20
|
export { resolveMaxOutputTokensPerLlmCall } from './schemas/config.schema.js';
|
|
14
21
|
export { resolveScanStateBaseDir, resolveReportDir } from './harness/state-manager.js';
|
|
@@ -19,5 +26,15 @@ export { NoopTelemetrySink } from './telemetry/telemetry.interface.js';
|
|
|
19
26
|
export { redactUrlForTelemetry } from './telemetry/emit.js';
|
|
20
27
|
export type { LlmCallResult, LlmProvider } from './llm/provider.interface.js';
|
|
21
28
|
export type { CallLlmConfigSlice } from './llm/provider.js';
|
|
22
|
-
export type { HarnessConfig, AuthConfig, RouteInventory, GapAnalysis, RepoAnalysis, DetectedAuth, AuthExploration, AuthPath, AuthPathRequirements, CostIntelligence, LlmUsageRecord, RepeatedAiPattern, DeterministicMaturity, PublicSurface, AutomationMaturity, AutomationMaturityDimension, FrameworkDetectionResult, DetectedFrameworkPrimary, } from './schemas/index.js';
|
|
29
|
+
export type { HarnessConfig, AuthConfig, RouteInventory, GapAnalysis, RepoAnalysis, DetectedAuth, AuthExploration, AuthPath, AuthPathRequirements, CostIntelligence, LlmUsageRecord, RepeatedAiPattern, DeterministicMaturity, PublicSurface, AutomationMaturity, AutomationMaturityDimension, FrameworkDetectionResult, DetectedFrameworkPrimary, RecipeId, RecipeConfig, } from './schemas/index.js';
|
|
30
|
+
export { RecipeIdSchema } from './schemas/index.js';
|
|
31
|
+
export { computeReleaseConfidence } from './tools/scoring/confidence.js';
|
|
32
|
+
export { ciResultsToEvidence } from './adapters/ci-results-adapter.js';
|
|
33
|
+
export type { CiRunInput } from './adapters/ci-results-adapter.js';
|
|
34
|
+
export { prMetadataToEvidence } from './adapters/pr-metadata-adapter.js';
|
|
35
|
+
export type { PrMetadataInput, StatusCheck, ReviewDecision, MergeableState } from './adapters/pr-metadata-adapter.js';
|
|
36
|
+
export { buildConfidenceInputFromQulib } from './tools/scoring/confidence-from-qulib.js';
|
|
37
|
+
export { diffConfidence, deriveInbox, buildReplay, toAuditEntry } from './tools/scoring/confidence-views.js';
|
|
38
|
+
export type { EvidenceSourceKind, EvidenceItem, ConfidenceSubject, ConfidenceInput, ConfidencePolicy, ConfidenceVerdict, ConfidenceContribution, ReleaseConfidence, DeliveryTrafficPoint, InboxItem, InboxItemKind, ReplayStep, ReplayTrace, AuditEntry, } from './schemas/index.js';
|
|
39
|
+
export { EvidenceSourceKindSchema, EvidenceItemSchema, ConfidenceSubjectSchema, ConfidenceInputSchema, ConfidencePolicySchema, ConfidenceVerdictSchema, ReleaseConfidenceSchema, } from './schemas/index.js';
|
|
23
40
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AAC1C,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AACpD,YAAY,EACV,YAAY,EACZ,kBAAkB,EAClB,SAAS,EACT,cAAc,EACd,uBAAuB,GACxB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,UAAU,EACV,oBAAoB,EACpB,4BAA4B,EAC5B,yBAAyB,EACzB,qBAAqB,GACtB,MAAM,wBAAwB,CAAC;AAChC,YAAY,EACV,yBAAyB,EACzB,4BAA4B,GAC7B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,kCAAkC,CAAC;AAC1G,OAAO,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAChD,OAAO,EAAE,yBAAyB,EAAE,MAAM,wCAAwC,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AACpD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAC1F,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gCAAgC,EAAE,MAAM,4BAA4B,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,gBAAgB,EAAE,MAAM,4BAA4B,CAAC;AACvF,YAAY,EAAE,cAAc,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AACjF,YAAY,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AACrE,YAAY,EACV,aAAa,EACb,cAAc,EACd,kBAAkB,GACnB,MAAM,oCAAoC,CAAC;AAC5C,OAAO,EAAE,iBAAiB,EAAE,MAAM,oCAAoC,CAAC;AACvE,OAAO,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAC5D,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,6BAA6B,CAAC;AAC9E,YAAY,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAC5D,YAAY,EACV,aAAa,EACb,UAAU,EACV,cAAc,EACd,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,eAAe,EACf,QAAQ,EACR,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,iBAAiB,EACjB,qBAAqB,EACrB,aAAa,EACb,kBAAkB,EAClB,2BAA2B,EAC3B,wBAAwB,EACxB,wBAAwB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,26 @@
|
|
|
1
1
|
export { analyzeApp } from './analyze.js';
|
|
2
|
+
export { slugifyUrl, defaultBaselineRoot, saveBaseline, loadBaseline, listBaselines, deleteBaseline, compareBaselines, } from './baseline/baseline.js';
|
|
2
3
|
export { toAgentSummary } from './agent-summary.js';
|
|
3
4
|
export { detectAuth, validateStorageState, evaluateStorageStateValidity, preflightStorageStateFile, waitForReturnToOrigin, } from './tools/auth/detect.js';
|
|
4
5
|
export { exploreAuth } from './tools/auth/explore.js';
|
|
5
6
|
export { addUserProvider, removeUserProvider, listUserProviders } from './tools/auth/custom-providers.js';
|
|
6
7
|
export { scanRepo } from './tools/repo/scan.js';
|
|
8
|
+
export { discoverApiSurface, discoverApiSurfaceWithRepo } from './tools/repo/api-surface.js';
|
|
7
9
|
export { computeAutomationMaturity } from './tools/scoring/automation-maturity.js';
|
|
10
|
+
export { computeApiCoverage } from './tools/scoring/api-coverage.js';
|
|
8
11
|
export { scaffoldTests } from './scaffold-tests.js';
|
|
12
|
+
export { expandRecipes, buildAuthScenarios, buildA11yScenarios, buildNavScenarios, buildSeedScenarios } from './recipes/index.js';
|
|
9
13
|
export { createProvider } from './llm/provider-registry.js';
|
|
10
14
|
export { resolveMaxOutputTokensPerLlmCall } from './schemas/config.schema.js';
|
|
11
15
|
export { resolveScanStateBaseDir, resolveReportDir } from './harness/state-manager.js';
|
|
12
16
|
export { NoopTelemetrySink } from './telemetry/telemetry.interface.js';
|
|
13
17
|
export { redactUrlForTelemetry } from './telemetry/emit.js';
|
|
18
|
+
export { RecipeIdSchema } from './schemas/index.js';
|
|
19
|
+
// P3 — Confidence Layer exports
|
|
20
|
+
export { computeReleaseConfidence } from './tools/scoring/confidence.js';
|
|
21
|
+
// P4 — Evidence adapters (CI results + PR metadata)
|
|
22
|
+
export { ciResultsToEvidence } from './adapters/ci-results-adapter.js';
|
|
23
|
+
export { prMetadataToEvidence } from './adapters/pr-metadata-adapter.js';
|
|
24
|
+
export { buildConfidenceInputFromQulib } from './tools/scoring/confidence-from-qulib.js';
|
|
25
|
+
export { diffConfidence, deriveInbox, buildReplay, toAuditEntry } from './tools/scoring/confidence-views.js';
|
|
26
|
+
export { EvidenceSourceKindSchema, EvidenceItemSchema, ConfidenceSubjectSchema, ConfidenceInputSchema, ConfidencePolicySchema, ConfidenceVerdictSchema, ReleaseConfidenceSchema, } from './schemas/index.js';
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* a11y recipe — accessibility assertion patterns.
|
|
3
|
+
*
|
|
4
|
+
* Lifted from the PROVEN NQ-2 Playwright a11y suite and qulib's own axe-core
|
|
5
|
+
* integration in src/phases/accessibility.ts. Real patterns re-derived from
|
|
6
|
+
* first principles.
|
|
7
|
+
*
|
|
8
|
+
* NQ-2 Playwright a11y reference patterns:
|
|
9
|
+
* - import AxeBuilder from '@axe-core/playwright'
|
|
10
|
+
* - const results = await new AxeBuilder({ page }).analyze()
|
|
11
|
+
* - expect(violations.filter(v => v.impact === 'serious' || v.impact === 'critical')).toHaveLength(0)
|
|
12
|
+
* - await expect(page.locator('main')).toBeVisible()
|
|
13
|
+
* - await expect(page.locator('h1')).toBeVisible()
|
|
14
|
+
* - expect(await page.title()).not.toBe('')
|
|
15
|
+
*
|
|
16
|
+
* For Cypress (no axe-core adapter in the scaffold toolchain), we use:
|
|
17
|
+
* - Structural presence checks (h1, main, nav, [role=...])
|
|
18
|
+
* - Sufficient-contrast guards via role/aria-label checks
|
|
19
|
+
* - Focus-visible checks via keyboard nav simulation
|
|
20
|
+
*/
|
|
21
|
+
import type { NeutralScenario } from '../schemas/gap-analysis.schema.js';
|
|
22
|
+
import type { RecipeConfig } from '../schemas/recipe.schema.js';
|
|
23
|
+
/**
|
|
24
|
+
* Generate NeutralScenarios for the a11y recipe.
|
|
25
|
+
*
|
|
26
|
+
* Returns 3 scenarios:
|
|
27
|
+
* 1. Page-level a11y — heading structure + landmark regions (all frameworks)
|
|
28
|
+
* 2. Interactive a11y — focus order / aria roles for primary CTA (smoke)
|
|
29
|
+
* 3. Image/text a11y — alt text presence + non-empty page title
|
|
30
|
+
*
|
|
31
|
+
* The Playwright adapter will render axe-core assertions for scenarios tagged
|
|
32
|
+
* 'a11y-axe'. The Cypress adapter renders structural/aria assertions (axe-core
|
|
33
|
+
* Cypress integration is out-of-scope for the scaffold toolchain today).
|
|
34
|
+
*/
|
|
35
|
+
export declare function buildA11yScenarios(config?: RecipeConfig): NeutralScenario[];
|
|
36
|
+
//# sourceMappingURL=a11y.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"a11y.d.ts","sourceRoot":"","sources":["../../src/recipes/a11y.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAEhE;;;;;;;;;;;GAWG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,YAAiB,GAAG,eAAe,EAAE,CA6G/E"}
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate NeutralScenarios for the a11y recipe.
|
|
3
|
+
*
|
|
4
|
+
* Returns 3 scenarios:
|
|
5
|
+
* 1. Page-level a11y — heading structure + landmark regions (all frameworks)
|
|
6
|
+
* 2. Interactive a11y — focus order / aria roles for primary CTA (smoke)
|
|
7
|
+
* 3. Image/text a11y — alt text presence + non-empty page title
|
|
8
|
+
*
|
|
9
|
+
* The Playwright adapter will render axe-core assertions for scenarios tagged
|
|
10
|
+
* 'a11y-axe'. The Cypress adapter renders structural/aria assertions (axe-core
|
|
11
|
+
* Cypress integration is out-of-scope for the scaffold toolchain today).
|
|
12
|
+
*/
|
|
13
|
+
export function buildA11yScenarios(config = {}) {
|
|
14
|
+
const impact = config.a11yImpact ?? 'serious';
|
|
15
|
+
return [
|
|
16
|
+
{
|
|
17
|
+
id: 'recipe-a11y-heading-structure',
|
|
18
|
+
title: 'Page has proper heading structure and landmark regions',
|
|
19
|
+
description: 'The root page has an H1 heading and at least one landmark region (main/nav/header/footer), providing a navigable document outline for screen-reader users',
|
|
20
|
+
targetPath: '/',
|
|
21
|
+
steps: [
|
|
22
|
+
{ action: 'navigate', target: '/', description: 'Open the root page' },
|
|
23
|
+
{
|
|
24
|
+
action: 'assert-visible',
|
|
25
|
+
target: 'h1',
|
|
26
|
+
description: 'Page has an H1 heading (document outline)',
|
|
27
|
+
},
|
|
28
|
+
{
|
|
29
|
+
action: 'assert-visible',
|
|
30
|
+
target: 'main',
|
|
31
|
+
description: 'Page has a main landmark region',
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
action: 'assert-count',
|
|
35
|
+
target: 'nav',
|
|
36
|
+
value: '1',
|
|
37
|
+
description: 'At least one navigation landmark exists',
|
|
38
|
+
},
|
|
39
|
+
],
|
|
40
|
+
tags: ['a11y', 'smoke', 'recipe-a11y', `a11y-impact-${impact}`],
|
|
41
|
+
recommendations: [
|
|
42
|
+
{
|
|
43
|
+
adapter: 'playwright',
|
|
44
|
+
reason: 'Landmark + heading assertions with Playwright locator — real NQ-2 pattern',
|
|
45
|
+
confidence: 'high',
|
|
46
|
+
},
|
|
47
|
+
{
|
|
48
|
+
adapter: 'cypress-e2e',
|
|
49
|
+
reason: 'Structural a11y assertions — cy.get on semantic elements',
|
|
50
|
+
confidence: 'high',
|
|
51
|
+
},
|
|
52
|
+
],
|
|
53
|
+
sourceGapIds: ['recipe-a11y'],
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
id: 'recipe-a11y-interactive-aria',
|
|
57
|
+
title: 'Primary interactive elements have accessible names',
|
|
58
|
+
description: 'Buttons and links visible on the page carry accessible names (aria-label or text content), ensuring assistive technologies can identify the action',
|
|
59
|
+
targetPath: '/',
|
|
60
|
+
steps: [
|
|
61
|
+
{ action: 'navigate', target: '/', description: 'Open the root page' },
|
|
62
|
+
{
|
|
63
|
+
action: 'assert-count',
|
|
64
|
+
target: 'button, a[href]',
|
|
65
|
+
value: '1',
|
|
66
|
+
description: 'At least one interactive element is present',
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
action: 'assert-visible',
|
|
70
|
+
target: 'button, [role=button]',
|
|
71
|
+
description: 'An accessible interactive element is visible on the page',
|
|
72
|
+
},
|
|
73
|
+
],
|
|
74
|
+
tags: ['a11y', 'aria', 'recipe-a11y'],
|
|
75
|
+
recommendations: [
|
|
76
|
+
{
|
|
77
|
+
adapter: 'playwright',
|
|
78
|
+
reason: 'aria-label presence check — Playwright locator + toBeVisible',
|
|
79
|
+
confidence: 'medium',
|
|
80
|
+
},
|
|
81
|
+
{
|
|
82
|
+
adapter: 'cypress-e2e',
|
|
83
|
+
reason: 'Aria attribute presence — cy.get selector chain',
|
|
84
|
+
confidence: 'medium',
|
|
85
|
+
},
|
|
86
|
+
],
|
|
87
|
+
sourceGapIds: ['recipe-a11y'],
|
|
88
|
+
},
|
|
89
|
+
{
|
|
90
|
+
id: 'recipe-a11y-page-title',
|
|
91
|
+
title: 'Page has a non-empty, descriptive document title',
|
|
92
|
+
description: 'The <title> element is non-empty — required for bookmarks, browser tabs, and screen-reader orientation',
|
|
93
|
+
targetPath: '/',
|
|
94
|
+
steps: [
|
|
95
|
+
{ action: 'navigate', target: '/', description: 'Open the root page' },
|
|
96
|
+
{
|
|
97
|
+
action: 'assert-text',
|
|
98
|
+
target: 'title',
|
|
99
|
+
description: 'Document title element is non-empty',
|
|
100
|
+
},
|
|
101
|
+
],
|
|
102
|
+
tags: ['a11y', 'seo', 'recipe-a11y'],
|
|
103
|
+
recommendations: [
|
|
104
|
+
{
|
|
105
|
+
adapter: 'playwright',
|
|
106
|
+
reason: 'page.title() !== "" — lightweight page-level a11y gate',
|
|
107
|
+
confidence: 'high',
|
|
108
|
+
},
|
|
109
|
+
{
|
|
110
|
+
adapter: 'cypress-e2e',
|
|
111
|
+
reason: 'cy.title().should("not.be.empty") — smoke a11y gate',
|
|
112
|
+
confidence: 'high',
|
|
113
|
+
},
|
|
114
|
+
],
|
|
115
|
+
sourceGapIds: ['recipe-a11y'],
|
|
116
|
+
},
|
|
117
|
+
];
|
|
118
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* auth recipe — login / logout / protected-route patterns.
|
|
3
|
+
*
|
|
4
|
+
* Lifted from the PROVEN NQ-2 Playwright specs and CaseLoom Cypress specs.
|
|
5
|
+
* These are REAL selector patterns and assertion patterns used in those test
|
|
6
|
+
* suites, re-derived from first principles (not copy-pasted).
|
|
7
|
+
*
|
|
8
|
+
* NQ-2 Playwright reference patterns:
|
|
9
|
+
* - page.goto('/login')
|
|
10
|
+
* - page.locator('[data-testid=login-email]').fill(email)
|
|
11
|
+
* - page.locator('[data-testid=login-password]').fill(password)
|
|
12
|
+
* - page.locator('[data-testid=login-submit]').click()
|
|
13
|
+
* - expect(page.locator('[data-testid=dashboard-root]')).toBeVisible()
|
|
14
|
+
* - expect(page.locator('[data-testid=login-error]')).toContainText('Invalid')
|
|
15
|
+
*
|
|
16
|
+
* CaseLoom Cypress reference patterns:
|
|
17
|
+
* - cy.visit('/login')
|
|
18
|
+
* - cy.get('[data-testid=login-email]').type(email)
|
|
19
|
+
* - cy.get('[data-testid=login-password]').type(password)
|
|
20
|
+
* - cy.get('[data-testid=login-submit]').click()
|
|
21
|
+
* - cy.get('[data-testid=dashboard-root]').should('be.visible')
|
|
22
|
+
* - cy.get('[data-testid=login-error]').should('contain.text', 'Invalid')
|
|
23
|
+
*/
|
|
24
|
+
import type { NeutralScenario } from '../schemas/gap-analysis.schema.js';
|
|
25
|
+
import type { RecipeConfig } from '../schemas/recipe.schema.js';
|
|
26
|
+
/**
|
|
27
|
+
* Generate NeutralScenarios for the auth recipe.
|
|
28
|
+
*
|
|
29
|
+
* Returns 3 scenarios:
|
|
30
|
+
* 1. Happy-path login → lands on dashboard (smoke gate)
|
|
31
|
+
* 2. Invalid-credentials → inline error message shown (negative gate)
|
|
32
|
+
* 3. Protected route redirects unauthenticated users to login (security gate)
|
|
33
|
+
*
|
|
34
|
+
* All selectors come from the proven NQ-2/CaseLoom patterns and are overridable
|
|
35
|
+
* via RecipeConfig, so the recipe works for any form-login app.
|
|
36
|
+
*/
|
|
37
|
+
export declare function buildAuthScenarios(config?: RecipeConfig): NeutralScenario[];
|
|
38
|
+
//# sourceMappingURL=auth.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/recipes/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAWhE;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,GAAE,YAAiB,GAAG,eAAe,EAAE,CA0I/E"}
|
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
/** Defaults from the proven NQ-2 data-testid convention. */
|
|
2
|
+
const DEFAULTS = {
|
|
3
|
+
loginUrl: '/login',
|
|
4
|
+
usernameSelector: '[data-testid=login-email]',
|
|
5
|
+
passwordSelector: '[data-testid=login-password]',
|
|
6
|
+
submitSelector: '[data-testid=login-submit]',
|
|
7
|
+
successSelector: '[data-testid=dashboard-root]',
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* Generate NeutralScenarios for the auth recipe.
|
|
11
|
+
*
|
|
12
|
+
* Returns 3 scenarios:
|
|
13
|
+
* 1. Happy-path login → lands on dashboard (smoke gate)
|
|
14
|
+
* 2. Invalid-credentials → inline error message shown (negative gate)
|
|
15
|
+
* 3. Protected route redirects unauthenticated users to login (security gate)
|
|
16
|
+
*
|
|
17
|
+
* All selectors come from the proven NQ-2/CaseLoom patterns and are overridable
|
|
18
|
+
* via RecipeConfig, so the recipe works for any form-login app.
|
|
19
|
+
*/
|
|
20
|
+
export function buildAuthScenarios(config = {}) {
|
|
21
|
+
const loginUrl = config.loginUrl ?? DEFAULTS.loginUrl;
|
|
22
|
+
const usernameSelector = config.usernameSelector ?? DEFAULTS.usernameSelector;
|
|
23
|
+
const passwordSelector = config.passwordSelector ?? DEFAULTS.passwordSelector;
|
|
24
|
+
const submitSelector = config.submitSelector ?? DEFAULTS.submitSelector;
|
|
25
|
+
const successSelector = config.successSelector ?? DEFAULTS.successSelector;
|
|
26
|
+
return [
|
|
27
|
+
{
|
|
28
|
+
id: 'recipe-auth-happy-path',
|
|
29
|
+
title: 'User can log in with valid credentials',
|
|
30
|
+
description: 'Submitting valid credentials navigates to the authenticated dashboard',
|
|
31
|
+
targetPath: loginUrl,
|
|
32
|
+
steps: [
|
|
33
|
+
{ action: 'navigate', target: loginUrl, description: 'Open the login page' },
|
|
34
|
+
{
|
|
35
|
+
action: 'type',
|
|
36
|
+
target: usernameSelector,
|
|
37
|
+
value: 'user@example.test',
|
|
38
|
+
description: 'Enter email address',
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
action: 'type',
|
|
42
|
+
target: passwordSelector,
|
|
43
|
+
value: 'correct-horse',
|
|
44
|
+
description: 'Enter password',
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
action: 'click',
|
|
48
|
+
target: submitSelector,
|
|
49
|
+
description: 'Submit the login form',
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
action: 'assert-visible',
|
|
53
|
+
target: successSelector,
|
|
54
|
+
description: 'Dashboard or success indicator is shown',
|
|
55
|
+
},
|
|
56
|
+
],
|
|
57
|
+
tags: ['auth', 'smoke', 'recipe-auth'],
|
|
58
|
+
recommendations: [
|
|
59
|
+
{
|
|
60
|
+
adapter: 'cypress-e2e',
|
|
61
|
+
reason: 'Proven NQ-2 / CaseLoom pattern — cy.get + type/click/should',
|
|
62
|
+
confidence: 'high',
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
adapter: 'playwright',
|
|
66
|
+
reason: 'Proven NQ-2 pattern — page.locator + fill/click/expect',
|
|
67
|
+
confidence: 'high',
|
|
68
|
+
},
|
|
69
|
+
],
|
|
70
|
+
sourceGapIds: ['recipe-auth'],
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
id: 'recipe-auth-invalid-credentials',
|
|
74
|
+
title: 'Invalid credentials show an inline error',
|
|
75
|
+
description: 'Submitting wrong credentials stays on the login page and shows an error message',
|
|
76
|
+
targetPath: loginUrl,
|
|
77
|
+
steps: [
|
|
78
|
+
{ action: 'navigate', target: loginUrl, description: 'Open the login page' },
|
|
79
|
+
{
|
|
80
|
+
action: 'type',
|
|
81
|
+
target: usernameSelector,
|
|
82
|
+
value: 'user@example.test',
|
|
83
|
+
description: 'Enter email address',
|
|
84
|
+
},
|
|
85
|
+
{
|
|
86
|
+
action: 'type',
|
|
87
|
+
target: passwordSelector,
|
|
88
|
+
value: 'wrong-password',
|
|
89
|
+
description: 'Enter an incorrect password',
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
action: 'click',
|
|
93
|
+
target: submitSelector,
|
|
94
|
+
description: 'Submit with wrong credentials',
|
|
95
|
+
},
|
|
96
|
+
{
|
|
97
|
+
action: 'assert-text',
|
|
98
|
+
target: '[data-testid=login-error]',
|
|
99
|
+
value: 'Invalid',
|
|
100
|
+
description: 'Inline error message is shown',
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
action: 'assert-visible',
|
|
104
|
+
target: submitSelector,
|
|
105
|
+
description: 'Still on the login page (submit button visible)',
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
tags: ['auth', 'negative', 'recipe-auth'],
|
|
109
|
+
recommendations: [
|
|
110
|
+
{
|
|
111
|
+
adapter: 'cypress-e2e',
|
|
112
|
+
reason: 'Proven NQ-2 negative path — assert-text on error element',
|
|
113
|
+
confidence: 'high',
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
adapter: 'playwright',
|
|
117
|
+
reason: 'Proven NQ-2 negative path — toContainText on error element',
|
|
118
|
+
confidence: 'high',
|
|
119
|
+
},
|
|
120
|
+
],
|
|
121
|
+
sourceGapIds: ['recipe-auth'],
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
id: 'recipe-auth-protected-redirect',
|
|
125
|
+
title: 'Unauthenticated access to a protected route redirects to login',
|
|
126
|
+
description: 'Visiting a protected route without a session redirects to the login page — authentication guard is wired',
|
|
127
|
+
targetPath: '/dashboard',
|
|
128
|
+
steps: [
|
|
129
|
+
{
|
|
130
|
+
action: 'navigate',
|
|
131
|
+
target: '/dashboard',
|
|
132
|
+
description: 'Navigate directly to a protected route',
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
action: 'assert-visible',
|
|
136
|
+
target: submitSelector,
|
|
137
|
+
description: 'Login form submit button is visible — we were redirected to login',
|
|
138
|
+
},
|
|
139
|
+
],
|
|
140
|
+
tags: ['auth', 'security', 'recipe-auth'],
|
|
141
|
+
recommendations: [
|
|
142
|
+
{
|
|
143
|
+
adapter: 'cypress-e2e',
|
|
144
|
+
reason: 'Guards a critical security property — protected routes must redirect',
|
|
145
|
+
confidence: 'medium',
|
|
146
|
+
},
|
|
147
|
+
{
|
|
148
|
+
adapter: 'playwright',
|
|
149
|
+
reason: 'Guards a critical security property — protected routes must redirect',
|
|
150
|
+
confidence: 'medium',
|
|
151
|
+
},
|
|
152
|
+
],
|
|
153
|
+
sourceGapIds: ['recipe-auth'],
|
|
154
|
+
},
|
|
155
|
+
];
|
|
156
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recipe toolshed — reusable NeutralScenario builders.
|
|
3
|
+
*
|
|
4
|
+
* Each recipe module exports a build* function that returns NeutralScenario[].
|
|
5
|
+
* Recipes are merged (additive) into whatever scenarios the adapter already has;
|
|
6
|
+
* they never replace existing scenarios.
|
|
7
|
+
*
|
|
8
|
+
* Available recipes:
|
|
9
|
+
* auth — login / logout / protected-route flows
|
|
10
|
+
* a11y — accessibility checks (landmark/heading/aria/title)
|
|
11
|
+
* nav — deep-link / browser-back / 404-handling
|
|
12
|
+
* seed — data-seeding and state-reset helpers
|
|
13
|
+
*/
|
|
14
|
+
import type { RecipeId, RecipeConfig } from '../schemas/recipe.schema.js';
|
|
15
|
+
import type { NeutralScenario } from '../schemas/gap-analysis.schema.js';
|
|
16
|
+
export { buildAuthScenarios } from './auth.js';
|
|
17
|
+
export { buildA11yScenarios } from './a11y.js';
|
|
18
|
+
export { buildNavScenarios } from './nav.js';
|
|
19
|
+
export { buildSeedScenarios } from './seed.js';
|
|
20
|
+
/**
|
|
21
|
+
* Expand a list of RecipeIds into their NeutralScenario arrays, applying
|
|
22
|
+
* optional per-recipe config. Returns an empty array when ids is empty or
|
|
23
|
+
* undefined — safe to call unconditionally.
|
|
24
|
+
*/
|
|
25
|
+
export declare function expandRecipes(ids: RecipeId[] | undefined, config?: RecipeConfig): NeutralScenario[];
|
|
26
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/recipes/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC1E,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AAMzE,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAC/C,OAAO,EAAE,iBAAiB,EAAE,MAAM,UAAU,CAAC;AAC7C,OAAO,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAC;AAE/C;;;;GAIG;AACH,wBAAgB,aAAa,CAC3B,GAAG,EAAE,QAAQ,EAAE,GAAG,SAAS,EAC3B,MAAM,GAAE,YAAiB,GACxB,eAAe,EAAE,CA2BnB"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import { buildAuthScenarios } from './auth.js';
|
|
2
|
+
import { buildA11yScenarios } from './a11y.js';
|
|
3
|
+
import { buildNavScenarios } from './nav.js';
|
|
4
|
+
import { buildSeedScenarios } from './seed.js';
|
|
5
|
+
export { buildAuthScenarios } from './auth.js';
|
|
6
|
+
export { buildA11yScenarios } from './a11y.js';
|
|
7
|
+
export { buildNavScenarios } from './nav.js';
|
|
8
|
+
export { buildSeedScenarios } from './seed.js';
|
|
9
|
+
/**
|
|
10
|
+
* Expand a list of RecipeIds into their NeutralScenario arrays, applying
|
|
11
|
+
* optional per-recipe config. Returns an empty array when ids is empty or
|
|
12
|
+
* undefined — safe to call unconditionally.
|
|
13
|
+
*/
|
|
14
|
+
export function expandRecipes(ids, config = {}) {
|
|
15
|
+
if (!ids || ids.length === 0)
|
|
16
|
+
return [];
|
|
17
|
+
const scenarios = [];
|
|
18
|
+
for (const id of ids) {
|
|
19
|
+
switch (id) {
|
|
20
|
+
case 'auth':
|
|
21
|
+
scenarios.push(...buildAuthScenarios(config));
|
|
22
|
+
break;
|
|
23
|
+
case 'a11y':
|
|
24
|
+
scenarios.push(...buildA11yScenarios(config));
|
|
25
|
+
break;
|
|
26
|
+
case 'nav':
|
|
27
|
+
scenarios.push(...buildNavScenarios(config));
|
|
28
|
+
break;
|
|
29
|
+
case 'seed':
|
|
30
|
+
scenarios.push(...buildSeedScenarios(config));
|
|
31
|
+
break;
|
|
32
|
+
default: {
|
|
33
|
+
// TypeScript exhaustiveness: if a new RecipeId is added without a case
|
|
34
|
+
// this will cause a compile error.
|
|
35
|
+
const _exhaustive = id;
|
|
36
|
+
throw new Error(`Unknown recipe id: ${String(_exhaustive)}`);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
return scenarios;
|
|
41
|
+
}
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* nav recipe — navigation, deep-linking, back/forward, 404 handling.
|
|
3
|
+
*
|
|
4
|
+
* Lifted from the PROVEN NQ-2 Playwright navigation suite and CaseLoom Cypress
|
|
5
|
+
* navigation specs. Real selector and navigation patterns, re-derived from
|
|
6
|
+
* first principles.
|
|
7
|
+
*
|
|
8
|
+
* NQ-2 Playwright nav reference patterns:
|
|
9
|
+
* - page.goto('/about')
|
|
10
|
+
* - expect(page).toHaveURL(/\/about/)
|
|
11
|
+
* - await page.goBack()
|
|
12
|
+
* - expect(page).toHaveURL('/')
|
|
13
|
+
* - page.goto('/nonexistent-route-that-404s')
|
|
14
|
+
* - expect(page.locator('[data-testid=not-found]')).toBeVisible() OR
|
|
15
|
+
* - expect(page.getByText('404')).toBeVisible()
|
|
16
|
+
*
|
|
17
|
+
* CaseLoom Cypress nav reference patterns:
|
|
18
|
+
* - cy.visit('/about')
|
|
19
|
+
* - cy.url().should('include', '/about')
|
|
20
|
+
* - cy.go('back')
|
|
21
|
+
* - cy.url().should('eq', Cypress.config('baseUrl') + '/')
|
|
22
|
+
*/
|
|
23
|
+
import type { NeutralScenario } from '../schemas/gap-analysis.schema.js';
|
|
24
|
+
import type { RecipeConfig } from '../schemas/recipe.schema.js';
|
|
25
|
+
/**
|
|
26
|
+
* Generate NeutralScenarios for the nav recipe.
|
|
27
|
+
*
|
|
28
|
+
* Returns 3 scenarios:
|
|
29
|
+
* 1. Deep-link routes — direct navigation lands on the correct page
|
|
30
|
+
* 2. Browser-back — back button returns to the previous route
|
|
31
|
+
* 3. 404 handling — unknown routes show a user-friendly not-found page
|
|
32
|
+
*/
|
|
33
|
+
export declare function buildNavScenarios(config?: RecipeConfig): NeutralScenario[];
|
|
34
|
+
//# sourceMappingURL=nav.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nav.d.ts","sourceRoot":"","sources":["../../src/recipes/nav.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mCAAmC,CAAC;AACzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAIhE;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,YAAiB,GAAG,eAAe,EAAE,CA2H9E"}
|