@topogram/cli 0.3.64 → 0.3.66
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/package.json +1 -1
- package/src/adoption/plan/index.js +716 -0
- package/src/adoption/plan.js +12 -703
- package/src/adoption/reporting.js +1 -1
- package/src/agent-brief.js +7 -21
- package/src/agent-ops/query-builders/auth.js +375 -0
- package/src/agent-ops/query-builders/change-risk/change-plan.js +123 -0
- package/src/agent-ops/query-builders/change-risk/import-plan.js +49 -0
- package/src/agent-ops/query-builders/change-risk/maintained.js +286 -0
- package/src/agent-ops/query-builders/change-risk/review-packets.js +123 -0
- package/src/agent-ops/query-builders/change-risk/risk.js +189 -0
- package/src/agent-ops/query-builders/change-risk.js +25 -0
- package/src/agent-ops/query-builders/common.js +149 -0
- package/src/agent-ops/query-builders/maintained-risk.js +539 -0
- package/src/agent-ops/query-builders/maintained-shared.js +120 -0
- package/src/agent-ops/query-builders/multi-agent.js +547 -0
- package/src/agent-ops/query-builders/projection-impacts.js +514 -0
- package/src/agent-ops/query-builders/work-packets.js +417 -0
- package/src/agent-ops/query-builders/workflow-context-shared.js +300 -0
- package/src/agent-ops/query-builders/workflow-context.js +398 -0
- package/src/agent-ops/query-builders/workflow-presets-core.js +677 -0
- package/src/agent-ops/query-builders/workflow-presets.js +341 -0
- package/src/agent-ops/query-builders.d.ts +26 -26
- package/src/agent-ops/query-builders.js +42 -5021
- package/src/archive/jsonl.js +2 -2
- package/src/archive/resolver-bridge.js +1 -1
- package/src/archive/unarchive.js +2 -1
- package/src/catalog/constants.js +10 -0
- package/src/catalog/copy.js +65 -0
- package/src/catalog/diagnostics.js +15 -0
- package/src/catalog/entries.js +42 -0
- package/src/catalog/files.js +67 -0
- package/src/catalog/provenance.js +123 -0
- package/src/catalog/source.js +150 -0
- package/src/catalog/validation.js +252 -0
- package/src/catalog.d.ts +2 -0
- package/src/catalog.js +18 -746
- package/src/cli/command-parsers/project.js +3 -0
- package/src/cli/command-parsers/shared.js +1 -1
- package/src/cli/commands/agent.js +2 -2
- package/src/cli/commands/catalog/check.js +31 -0
- package/src/cli/commands/catalog/copy.js +59 -0
- package/src/cli/commands/catalog/doctor.js +248 -0
- package/src/cli/commands/catalog/help.js +21 -0
- package/src/cli/commands/catalog/list.js +52 -0
- package/src/cli/commands/catalog/runner.js +92 -0
- package/src/cli/commands/catalog/shared.js +17 -0
- package/src/cli/commands/catalog/show.js +134 -0
- package/src/cli/commands/catalog.js +30 -615
- package/src/cli/commands/check.js +3 -3
- package/src/cli/commands/doctor.js +2 -9
- package/src/cli/commands/generator-policy/package-info.js +162 -0
- package/src/cli/commands/generator-policy/payloads.js +372 -0
- package/src/cli/commands/generator-policy/printers.js +159 -0
- package/src/cli/commands/generator-policy/runner.js +81 -0
- package/src/cli/commands/generator-policy/shared.js +39 -0
- package/src/cli/commands/generator-policy.js +15 -783
- package/src/cli/commands/import/adopt.js +170 -0
- package/src/cli/commands/import/check.js +91 -0
- package/src/cli/commands/import/diff.js +84 -0
- package/src/cli/commands/import/help.js +47 -0
- package/src/cli/commands/import/paths.js +269 -0
- package/src/cli/commands/import/plan.js +292 -0
- package/src/cli/commands/import/refresh.js +471 -0
- package/src/cli/commands/import/status-history.js +196 -0
- package/src/cli/commands/import/workspace.js +233 -0
- package/src/cli/commands/import.js +33 -1732
- package/src/cli/commands/migrate.js +153 -0
- package/src/cli/commands/package/constants.js +17 -0
- package/src/cli/commands/package/doctor.js +240 -0
- package/src/cli/commands/package/help.js +27 -0
- package/src/cli/commands/package/lockfile.js +135 -0
- package/src/cli/commands/package/npm.js +97 -0
- package/src/cli/commands/package/reporting.js +35 -0
- package/src/cli/commands/package/runner.js +33 -0
- package/src/cli/commands/package/shared.js +9 -0
- package/src/cli/commands/package/update-cli.js +252 -0
- package/src/cli/commands/package/versions.js +35 -0
- package/src/cli/commands/package.js +29 -813
- package/src/cli/commands/query/change-plan.js +68 -0
- package/src/cli/commands/query/definitions.js +202 -0
- package/src/cli/commands/query/import-adopt.js +121 -0
- package/src/cli/commands/query/runner/artifacts.js +102 -0
- package/src/cli/commands/query/runner/boundaries.js +211 -0
- package/src/cli/commands/query/runner/change.js +182 -0
- package/src/cli/commands/query/runner/import-adopt.js +111 -0
- package/src/cli/commands/query/runner/index.js +31 -0
- package/src/cli/commands/query/runner/output.js +12 -0
- package/src/cli/commands/query/runner/workflow.js +241 -0
- package/src/cli/commands/query/runner.js +3 -0
- package/src/cli/commands/query/workflow-context.js +5 -0
- package/src/cli/commands/query/workspace.js +270 -0
- package/src/cli/commands/query.js +9 -1300
- package/src/cli/commands/source.js +3 -12
- package/src/cli/commands/template/baseline.js +100 -0
- package/src/cli/commands/template/check.js +467 -0
- package/src/cli/commands/template/constants.js +8 -0
- package/src/cli/commands/template/diagnostics.js +26 -0
- package/src/cli/commands/template/help.js +28 -0
- package/src/cli/commands/template/lifecycle.js +404 -0
- package/src/cli/commands/template/list-show.js +287 -0
- package/src/cli/commands/template/policy.js +422 -0
- package/src/cli/commands/template/shared.js +127 -0
- package/src/cli/commands/template/updates.js +352 -0
- package/src/cli/commands/template-runner.js +6 -6
- package/src/cli/commands/template.js +41 -2143
- package/src/cli/commands/trust.js +1 -1
- package/src/cli/commands/workflow.js +6 -1
- package/src/cli/dispatcher.js +6 -1
- package/src/cli/help.js +15 -14
- package/src/cli/migration-guidance.js +1 -1
- package/src/cli/output-safety.js +2 -1
- package/src/cli/path-normalization.js +3 -13
- package/src/generator/api/contracts.js +497 -0
- package/src/generator/api/metadata.js +221 -0
- package/src/generator/api/openapi.js +559 -0
- package/src/generator/api/schema.js +124 -0
- package/src/generator/api/types.d.ts +98 -0
- package/src/generator/api.js +3 -1195
- package/src/generator/context/domain-page.js +1 -1
- package/src/generator/context/shared/domain-sdlc.js +282 -0
- package/src/generator/context/shared/maintained-boundary.js +665 -0
- package/src/generator/context/shared/metrics.js +85 -0
- package/src/generator/context/shared/primitives.js +64 -0
- package/src/generator/context/shared/relationships.js +453 -0
- package/src/generator/context/shared/summaries.js +263 -0
- package/src/generator/context/shared/types.d.ts +207 -0
- package/src/generator/context/shared.d.ts +42 -0
- package/src/generator/context/shared.js +80 -1390
- package/src/generator/context/slice/core.js +397 -0
- package/src/generator/context/slice/sdlc.js +417 -0
- package/src/generator/context/slice/ui-packets.js +183 -0
- package/src/generator/context/slice.js +2 -859
- package/src/generator/context/task-mode.js +2 -2
- package/src/generator/registry/index.js +507 -0
- package/src/generator/registry.js +18 -504
- package/src/generator/runtime/environment/index.js +666 -0
- package/src/generator/runtime/environment.js +4 -666
- package/src/generator/runtime/runtime-check/index.js +554 -0
- package/src/generator/runtime/runtime-check.js +4 -554
- package/src/generator/runtime/shared/index.js +572 -0
- package/src/generator/runtime/shared.js +19 -570
- package/src/generator/sdlc/doc-page.js +1 -1
- package/src/generator/shared.d.ts +2 -0
- package/src/generator/surfaces/databases/lifecycle-shared.js +1 -1
- package/src/generator/surfaces/native/swiftui-templates/README.generated.md +1 -1
- package/src/generator/surfaces/shared.d.ts +3 -0
- package/src/generator/widget-conformance/behavior-report.js +258 -0
- package/src/generator/widget-conformance/checks.js +371 -0
- package/src/generator/widget-conformance/projection-context.js +200 -0
- package/src/generator/widget-conformance/report.js +166 -0
- package/src/generator/widget-conformance/types.d.ts +121 -0
- package/src/generator/widget-conformance.js +3 -824
- package/src/import/core/context.d.ts +3 -0
- package/src/import/core/context.js +5 -7
- package/src/import/core/contracts.d.ts +1 -0
- package/src/import/core/registry.d.ts +4 -0
- package/src/import/core/runner/candidates.js +337 -0
- package/src/import/core/runner/options.js +22 -0
- package/src/import/core/runner/reports.js +51 -0
- package/src/import/core/runner/run.js +79 -0
- package/src/import/core/runner/tracks.js +150 -0
- package/src/import/core/runner/ui-drafts.js +393 -0
- package/src/import/core/runner.js +3 -698
- package/src/import/core/shared/api-routes.js +221 -0
- package/src/import/core/shared/candidates.js +97 -0
- package/src/import/core/shared/files.js +177 -0
- package/src/import/core/shared/next-app.js +389 -0
- package/src/import/core/shared/types.d.ts +51 -0
- package/src/import/core/shared/ui-routes.js +230 -0
- package/src/import/core/shared.js +60 -861
- package/src/new-project/constants.js +128 -0
- package/src/new-project/create.js +90 -0
- package/src/new-project/json.js +28 -0
- package/src/new-project/metadata.js +96 -0
- package/src/new-project/package-spec.js +161 -0
- package/src/new-project/project-files.js +351 -0
- package/src/new-project/template-policy.js +269 -0
- package/src/new-project/template-resolution.js +370 -0
- package/src/new-project/template-snapshots.js +442 -0
- package/src/new-project/template-updates.js +512 -0
- package/src/new-project/types.d.ts +83 -0
- package/src/new-project.js +6 -2277
- package/src/parser.d.ts +87 -1
- package/src/parser.js +118 -0
- package/src/policy/review-boundaries.d.ts +15 -0
- package/src/project-config/index.js +591 -0
- package/src/project-config.js +19 -561
- package/src/resolver/enrich/acceptance-criterion.js +2 -0
- package/src/resolver/enrich/bug.js +2 -0
- package/src/resolver/enrich/pitch.js +2 -0
- package/src/resolver/enrich/requirement.js +2 -0
- package/src/resolver/enrich/task.js +2 -0
- package/src/resolver/index.js +19 -2089
- package/src/resolver/normalize.js +384 -1
- package/src/resolver/plans.js +168 -0
- package/src/resolver/projections-api.js +494 -0
- package/src/resolver/projections-db.js +133 -0
- package/src/resolver/projections-ui.js +317 -0
- package/src/resolver/shapes.js +251 -0
- package/src/resolver/shared.js +278 -0
- package/src/resolver/widgets.js +132 -0
- package/src/sdlc/adopt.js +6 -5
- package/src/sdlc/paths.js +3 -5
- package/src/sdlc/scaffold.js +2 -1
- package/src/template-trust/constants.js +62 -0
- package/src/template-trust/content.js +258 -0
- package/src/template-trust/diff.js +92 -0
- package/src/template-trust/policy.js +61 -0
- package/src/template-trust/record.js +90 -0
- package/src/template-trust/status.js +182 -0
- package/src/template-trust.js +24 -687
- package/src/text-helpers.d.ts +1 -0
- package/src/topogram-types.d.ts +69 -0
- package/src/validator/common.js +488 -0
- package/src/validator/data-model.js +237 -0
- package/src/validator/docs.js +167 -0
- package/src/validator/expressions.js +146 -1
- package/src/validator/index.d.ts +23 -0
- package/src/validator/index.js +32 -3585
- package/src/validator/kinds.d.ts +41 -0
- package/src/validator/kinds.js +2 -0
- package/src/validator/model-helpers.js +46 -0
- package/src/validator/per-kind/acceptance-criterion.js +5 -0
- package/src/validator/per-kind/bug.js +6 -0
- package/src/validator/per-kind/domain.js +15 -2
- package/src/validator/per-kind/pitch.js +7 -0
- package/src/validator/per-kind/requirement.js +5 -0
- package/src/validator/per-kind/task.js +7 -0
- package/src/validator/per-kind/widget.js +14 -0
- package/src/validator/projections/api-http-async.js +410 -0
- package/src/validator/projections/api-http-authz.js +88 -0
- package/src/validator/projections/api-http-core.js +205 -0
- package/src/validator/projections/api-http-policies.js +339 -0
- package/src/validator/projections/api-http-responses.js +233 -0
- package/src/validator/projections/api-http.js +44 -0
- package/src/validator/projections/db.js +353 -0
- package/src/validator/projections/generator-defaults.js +45 -0
- package/src/validator/projections/helpers.js +87 -0
- package/src/validator/projections/ui-helpers.js +214 -0
- package/src/validator/projections/ui-navigation.js +344 -0
- package/src/validator/projections/ui-structure.js +364 -0
- package/src/validator/projections/ui-widgets.js +493 -0
- package/src/validator/projections/ui.js +46 -0
- package/src/validator/registry.js +48 -1
- package/src/validator/utils.d.ts +20 -0
- package/src/validator/utils.js +115 -12
- package/src/widget-behavior.d.ts +1 -0
- package/src/workflows/import-app/api/collect.js +221 -0
- package/src/workflows/import-app/api/openapi.js +257 -0
- package/src/workflows/import-app/api/routes.js +327 -0
- package/src/workflows/import-app/api/sources.js +22 -0
- package/src/workflows/import-app/api.js +2 -797
- package/src/workflows/reconcile/adoption-plan/build.js +212 -0
- package/src/workflows/reconcile/adoption-plan/dependencies.js +75 -0
- package/src/workflows/reconcile/adoption-plan/outputs.js +153 -0
- package/src/workflows/reconcile/adoption-plan/paths.js +58 -0
- package/src/workflows/reconcile/adoption-plan/projection-patches.js +177 -0
- package/src/workflows/reconcile/adoption-plan/reasons.js +107 -0
- package/src/workflows/reconcile/adoption-plan.js +30 -740
- package/src/workflows/reconcile/auth/closures.js +115 -0
- package/src/workflows/reconcile/auth/formatters.js +142 -0
- package/src/workflows/reconcile/auth/inference.js +330 -0
- package/src/workflows/reconcile/auth/roles.js +122 -0
- package/src/workflows/reconcile/auth.js +35 -690
- package/src/workflows/reconcile/bundle-core/index.js +600 -0
- package/src/workflows/reconcile/bundle-core.js +12 -598
- package/src/workflows/reconcile/candidate-model.js +18 -2
- package/src/workflows/reconcile/canonical-surface.js +1 -1
- package/src/workflows/reconcile/impacts/adoption-plan.js +196 -0
- package/src/workflows/reconcile/impacts/indexes.js +105 -0
- package/src/workflows/reconcile/impacts/patches.js +252 -0
- package/src/workflows/reconcile/impacts/reports.js +80 -0
- package/src/workflows/reconcile/impacts.js +14 -623
- package/src/workflows/reconcile/renderers.js +41 -6
- package/src/workflows/shared.js +5 -11
- package/src/workspace-docs.d.ts +29 -0
- package/src/workspace-paths.js +328 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export const STATEMENT_KINDS: Set<string>;
|
|
2
|
+
export const IDENTIFIER_PATTERN: RegExp;
|
|
3
|
+
export const DOMAIN_IDENTIFIER_PATTERN: RegExp;
|
|
4
|
+
export const DOMAIN_TAGGABLE_KINDS: Set<string>;
|
|
5
|
+
export const PITCH_IDENTIFIER_PATTERN: RegExp;
|
|
6
|
+
export const REQUIREMENT_IDENTIFIER_PATTERN: RegExp;
|
|
7
|
+
export const ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN: RegExp;
|
|
8
|
+
export const TASK_IDENTIFIER_PATTERN: RegExp;
|
|
9
|
+
export const BUG_IDENTIFIER_PATTERN: RegExp;
|
|
10
|
+
export const DOCUMENT_IDENTIFIER_PATTERN: RegExp;
|
|
11
|
+
export const GLOBAL_STATUSES: Set<string>;
|
|
12
|
+
export const DECISION_STATUSES: Set<string>;
|
|
13
|
+
export const RULE_SEVERITIES: Set<string>;
|
|
14
|
+
export const VERIFICATION_METHODS: Set<string>;
|
|
15
|
+
export const STATUS_SETS_BY_KIND: Record<string, Set<string>>;
|
|
16
|
+
export const PITCH_STATUSES: Set<string>;
|
|
17
|
+
export const REQUIREMENT_STATUSES: Set<string>;
|
|
18
|
+
export const ACCEPTANCE_CRITERION_STATUSES: Set<string>;
|
|
19
|
+
export const TASK_STATUSES: Set<string>;
|
|
20
|
+
export const BUG_STATUSES: Set<string>;
|
|
21
|
+
export const PRIORITY_VALUES: Set<string>;
|
|
22
|
+
export const WORK_TYPES: Set<string>;
|
|
23
|
+
export const BUG_SEVERITIES: Set<string>;
|
|
24
|
+
export const DOC_TYPES: Set<string>;
|
|
25
|
+
export const AUDIENCES: Set<string>;
|
|
26
|
+
export const UI_SCREEN_KINDS: Set<string>;
|
|
27
|
+
export const UI_COLLECTION_PRESENTATIONS: Set<string>;
|
|
28
|
+
export const UI_NAVIGATION_PATTERNS: Set<string>;
|
|
29
|
+
export const UI_REGION_KINDS: Set<string>;
|
|
30
|
+
export const UI_PATTERN_KINDS: Set<string>;
|
|
31
|
+
export const UI_APP_SHELL_KINDS: Set<string>;
|
|
32
|
+
export const UI_WINDOWING_MODES: Set<string>;
|
|
33
|
+
export const UI_STATE_KINDS: Set<string>;
|
|
34
|
+
export const UI_DESIGN_DENSITIES: Set<string>;
|
|
35
|
+
export const UI_DESIGN_TONES: Set<string>;
|
|
36
|
+
export const UI_DESIGN_RADIUS_SCALES: Set<string>;
|
|
37
|
+
export const UI_DESIGN_COLOR_ROLES: Set<string>;
|
|
38
|
+
export const UI_DESIGN_TYPOGRAPHY_ROLES: Set<string>;
|
|
39
|
+
export const UI_DESIGN_ACTION_ROLES: Set<string>;
|
|
40
|
+
export const UI_DESIGN_ACCESSIBILITY_VALUES: Record<string, Set<string>>;
|
|
41
|
+
export const FIELD_SPECS: Record<string, { required: string[]; allowed: string[] }>;
|
package/src/validator/kinds.js
CHANGED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
// @ts-check
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
blockEntries,
|
|
5
|
+
getFieldValue,
|
|
6
|
+
symbolValues
|
|
7
|
+
} from "./utils.js";
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @param {TopogramStatement} statement
|
|
11
|
+
* @returns {string[]}
|
|
12
|
+
*/
|
|
13
|
+
export function statementFieldNames(statement) {
|
|
14
|
+
return blockEntries(getFieldValue(statement, "fields"))
|
|
15
|
+
.map((entry) => entry.items[0])
|
|
16
|
+
.filter((item) => item?.type === "symbol")
|
|
17
|
+
.map((item) => item.value);
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @param {TopogramStatement} statement
|
|
22
|
+
* @param {TopogramRegistry} registry
|
|
23
|
+
* @returns {string[]}
|
|
24
|
+
*/
|
|
25
|
+
export function resolveShapeBaseFieldNames(statement, registry) {
|
|
26
|
+
const explicitFieldNames = statementFieldNames(statement);
|
|
27
|
+
if (explicitFieldNames.length > 0) {
|
|
28
|
+
return explicitFieldNames;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
if (!statement.from) {
|
|
32
|
+
return [];
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
const source = registry.get(statement.from.value);
|
|
36
|
+
if (!source || source.kind !== "entity") {
|
|
37
|
+
return [];
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const sourceFieldNames = statementFieldNames(source);
|
|
41
|
+
const includeNames = symbolValues(getFieldValue(statement, "include"));
|
|
42
|
+
const excludeNames = new Set(symbolValues(getFieldValue(statement, "exclude")));
|
|
43
|
+
const selectedNames = includeNames.length > 0 ? includeNames.filter((name) => sourceFieldNames.includes(name)) : sourceFieldNames;
|
|
44
|
+
|
|
45
|
+
return selectedNames.filter((fieldName) => !excludeNames.has(fieldName));
|
|
46
|
+
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN
|
|
3
4
|
} from "../kinds.js";
|
|
@@ -7,6 +8,7 @@ import {
|
|
|
7
8
|
symbolValues
|
|
8
9
|
} from "../utils.js";
|
|
9
10
|
|
|
11
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
10
12
|
function validateAcIdentifier(errors, statement) {
|
|
11
13
|
if (!ACCEPTANCE_CRITERION_IDENTIFIER_PATTERN.test(statement.id)) {
|
|
12
14
|
pushError(
|
|
@@ -17,6 +19,7 @@ function validateAcIdentifier(errors, statement) {
|
|
|
17
19
|
}
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
20
23
|
function validateRequirementRef(errors, statement, fieldMap, registry) {
|
|
21
24
|
// Generic reference validator skips `requirement` (it's overloaded with
|
|
22
25
|
// rule.requirement which is a string condition); validate the kind=requirement
|
|
@@ -50,6 +53,7 @@ function validateRequirementRef(errors, statement, fieldMap, registry) {
|
|
|
50
53
|
}
|
|
51
54
|
}
|
|
52
55
|
|
|
56
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
53
57
|
function validateSupersedes(errors, statement, fieldMap, registry) {
|
|
54
58
|
const field = fieldMap.get("supersedes")?.[0];
|
|
55
59
|
if (!field) return;
|
|
@@ -81,6 +85,7 @@ function validateSupersedes(errors, statement, fieldMap, registry) {
|
|
|
81
85
|
}
|
|
82
86
|
}
|
|
83
87
|
|
|
88
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
84
89
|
export function validateAcceptanceCriterion(errors, statement, fieldMap, registry) {
|
|
85
90
|
if (statement.kind !== "acceptance_criterion") {
|
|
86
91
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
BUG_IDENTIFIER_PATTERN,
|
|
3
4
|
PRIORITY_VALUES,
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
symbolValues
|
|
10
11
|
} from "../utils.js";
|
|
11
12
|
|
|
13
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
12
14
|
function validateBugIdentifier(errors, statement) {
|
|
13
15
|
if (!BUG_IDENTIFIER_PATTERN.test(statement.id)) {
|
|
14
16
|
pushError(
|
|
@@ -19,6 +21,7 @@ function validateBugIdentifier(errors, statement) {
|
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
22
25
|
function validatePriority(errors, statement, fieldMap) {
|
|
23
26
|
const field = fieldMap.get("priority")?.[0];
|
|
24
27
|
if (!field) return;
|
|
@@ -35,6 +38,7 @@ function validatePriority(errors, statement, fieldMap) {
|
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
38
42
|
function validateSeverity(errors, statement, fieldMap) {
|
|
39
43
|
const field = fieldMap.get("severity")?.[0];
|
|
40
44
|
if (!field) return;
|
|
@@ -51,6 +55,7 @@ function validateSeverity(errors, statement, fieldMap) {
|
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
54
59
|
function validateFixedInVerificationOnVerified(errors, statement, fieldMap) {
|
|
55
60
|
// A bug in `verified` status must point at the verification that proved
|
|
56
61
|
// the fix; this lets release-notes assemble a closed-loop record.
|
|
@@ -66,6 +71,7 @@ function validateFixedInVerificationOnVerified(errors, statement, fieldMap) {
|
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
|
|
74
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
69
75
|
export function validateBug(errors, statement, fieldMap, registry) {
|
|
70
76
|
if (statement.kind !== "bug") {
|
|
71
77
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
DOMAIN_IDENTIFIER_PATTERN,
|
|
3
4
|
DOMAIN_TAGGABLE_KINDS
|
|
@@ -11,6 +12,7 @@ import {
|
|
|
11
12
|
valueAsArray
|
|
12
13
|
} from "../utils.js";
|
|
13
14
|
|
|
15
|
+
/** @param {TopogramToken} value @returns {boolean} */
|
|
14
16
|
function isStringOrSymbolList(value) {
|
|
15
17
|
for (const item of valueAsArray(value)) {
|
|
16
18
|
if (item.type !== "string" && item.type !== "symbol") {
|
|
@@ -20,6 +22,7 @@ function isStringOrSymbolList(value) {
|
|
|
20
22
|
return true;
|
|
21
23
|
}
|
|
22
24
|
|
|
25
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
23
26
|
function validateDomainIdentifier(errors, statement) {
|
|
24
27
|
if (statement.kind !== "domain") {
|
|
25
28
|
return;
|
|
@@ -33,6 +36,7 @@ function validateDomainIdentifier(errors, statement) {
|
|
|
33
36
|
}
|
|
34
37
|
}
|
|
35
38
|
|
|
39
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
36
40
|
function validateScopeFields(errors, statement, fieldMap) {
|
|
37
41
|
if (statement.kind !== "domain") {
|
|
38
42
|
return;
|
|
@@ -50,6 +54,7 @@ function validateScopeFields(errors, statement, fieldMap) {
|
|
|
50
54
|
}
|
|
51
55
|
}
|
|
52
56
|
|
|
57
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
53
58
|
function validateParentDomain(errors, statement, fieldMap, registry) {
|
|
54
59
|
if (statement.kind !== "domain") {
|
|
55
60
|
return;
|
|
@@ -94,6 +99,7 @@ function validateParentDomain(errors, statement, fieldMap, registry) {
|
|
|
94
99
|
}
|
|
95
100
|
}
|
|
96
101
|
|
|
102
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
97
103
|
function validateOwners(errors, statement, fieldMap, registry) {
|
|
98
104
|
if (statement.kind !== "domain") {
|
|
99
105
|
return;
|
|
@@ -121,6 +127,7 @@ function validateOwners(errors, statement, fieldMap, registry) {
|
|
|
121
127
|
}
|
|
122
128
|
}
|
|
123
129
|
|
|
130
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
124
131
|
function detectParentDomainCycle(errors, statement, fieldMap, registry) {
|
|
125
132
|
if (statement.kind !== "domain") {
|
|
126
133
|
return;
|
|
@@ -129,7 +136,9 @@ function detectParentDomainCycle(errors, statement, fieldMap, registry) {
|
|
|
129
136
|
if (!field) return;
|
|
130
137
|
|
|
131
138
|
const seen = new Set([statement.id]);
|
|
132
|
-
|
|
139
|
+
const parentId = symbolValue(field.value);
|
|
140
|
+
if (!parentId) return;
|
|
141
|
+
let cursor = registry.get(parentId);
|
|
133
142
|
while (cursor && cursor.kind === "domain") {
|
|
134
143
|
if (seen.has(cursor.id)) {
|
|
135
144
|
pushError(
|
|
@@ -142,10 +151,13 @@ function detectParentDomainCycle(errors, statement, fieldMap, registry) {
|
|
|
142
151
|
seen.add(cursor.id);
|
|
143
152
|
const parentField = cursor.fields.find((f) => f.key === "parent_domain");
|
|
144
153
|
if (!parentField) break;
|
|
145
|
-
|
|
154
|
+
const nextParentId = symbolValue(parentField.value);
|
|
155
|
+
if (!nextParentId) break;
|
|
156
|
+
cursor = registry.get(nextParentId);
|
|
146
157
|
}
|
|
147
158
|
}
|
|
148
159
|
|
|
160
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
149
161
|
export function validateDomain(errors, statement, fieldMap, registry) {
|
|
150
162
|
if (statement.kind !== "domain") {
|
|
151
163
|
return;
|
|
@@ -160,6 +172,7 @@ export function validateDomain(errors, statement, fieldMap, registry) {
|
|
|
160
172
|
// Cross-kind validator: when *any* statement carries a `domain` field, verify
|
|
161
173
|
// it resolves to kind=domain. Skipped on the `domain` kind itself (its own
|
|
162
174
|
// `parent_domain` field handles that case).
|
|
175
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
163
176
|
export function validateDomainTag(errors, statement, fieldMap, registry) {
|
|
164
177
|
if (statement.kind === "domain") {
|
|
165
178
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
PITCH_IDENTIFIER_PATTERN,
|
|
3
4
|
PRIORITY_VALUES
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
symbolValues
|
|
9
10
|
} from "../utils.js";
|
|
10
11
|
|
|
12
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
11
13
|
function validatePitchIdentifier(errors, statement) {
|
|
12
14
|
if (!PITCH_IDENTIFIER_PATTERN.test(statement.id)) {
|
|
13
15
|
pushError(
|
|
@@ -18,6 +20,7 @@ function validatePitchIdentifier(errors, statement) {
|
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
21
24
|
function validatePriority(errors, statement, fieldMap) {
|
|
22
25
|
const field = fieldMap.get("priority")?.[0];
|
|
23
26
|
if (!field) return;
|
|
@@ -34,6 +37,7 @@ function validatePriority(errors, statement, fieldMap) {
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
37
41
|
function validateAppetite(errors, statement, fieldMap) {
|
|
38
42
|
const field = fieldMap.get("appetite")?.[0];
|
|
39
43
|
if (!field) return;
|
|
@@ -46,6 +50,7 @@ function validateAppetite(errors, statement, fieldMap) {
|
|
|
46
50
|
}
|
|
47
51
|
}
|
|
48
52
|
|
|
53
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
49
54
|
function validateShapingFields(errors, statement, fieldMap) {
|
|
50
55
|
// When a pitch enters status `shaped`, the appetite, rabbit_holes, and
|
|
51
56
|
// no_go_areas sections must be filled. This mirrors the Forge pitch
|
|
@@ -66,6 +71,7 @@ function validateShapingFields(errors, statement, fieldMap) {
|
|
|
66
71
|
}
|
|
67
72
|
}
|
|
68
73
|
|
|
74
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
69
75
|
function validateDecisionRefs(errors, statement, fieldMap, registry) {
|
|
70
76
|
const field = fieldMap.get("decisions")?.[0];
|
|
71
77
|
if (!field) return;
|
|
@@ -89,6 +95,7 @@ function validateDecisionRefs(errors, statement, fieldMap, registry) {
|
|
|
89
95
|
}
|
|
90
96
|
}
|
|
91
97
|
|
|
98
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
92
99
|
export function validatePitch(errors, statement, fieldMap, registry) {
|
|
93
100
|
if (statement.kind !== "pitch") {
|
|
94
101
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
REQUIREMENT_IDENTIFIER_PATTERN,
|
|
3
4
|
PRIORITY_VALUES
|
|
@@ -8,6 +9,7 @@ import {
|
|
|
8
9
|
symbolValues
|
|
9
10
|
} from "../utils.js";
|
|
10
11
|
|
|
12
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
11
13
|
function validateRequirementIdentifier(errors, statement) {
|
|
12
14
|
if (!REQUIREMENT_IDENTIFIER_PATTERN.test(statement.id)) {
|
|
13
15
|
pushError(
|
|
@@ -18,6 +20,7 @@ function validateRequirementIdentifier(errors, statement) {
|
|
|
18
20
|
}
|
|
19
21
|
}
|
|
20
22
|
|
|
23
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
21
24
|
function validatePriority(errors, statement, fieldMap) {
|
|
22
25
|
const field = fieldMap.get("priority")?.[0];
|
|
23
26
|
if (!field) return;
|
|
@@ -34,6 +37,7 @@ function validatePriority(errors, statement, fieldMap) {
|
|
|
34
37
|
}
|
|
35
38
|
}
|
|
36
39
|
|
|
40
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
37
41
|
function validateSupersedes(errors, statement, fieldMap, registry) {
|
|
38
42
|
const field = fieldMap.get("supersedes")?.[0];
|
|
39
43
|
if (!field) return;
|
|
@@ -65,6 +69,7 @@ function validateSupersedes(errors, statement, fieldMap, registry) {
|
|
|
65
69
|
}
|
|
66
70
|
}
|
|
67
71
|
|
|
72
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
68
73
|
export function validateRequirement(errors, statement, fieldMap, registry) {
|
|
69
74
|
if (statement.kind !== "requirement") {
|
|
70
75
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
TASK_IDENTIFIER_PATTERN,
|
|
3
4
|
PRIORITY_VALUES,
|
|
@@ -9,6 +10,7 @@ import {
|
|
|
9
10
|
symbolValues
|
|
10
11
|
} from "../utils.js";
|
|
11
12
|
|
|
13
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
12
14
|
function validateTaskIdentifier(errors, statement) {
|
|
13
15
|
if (!TASK_IDENTIFIER_PATTERN.test(statement.id)) {
|
|
14
16
|
pushError(
|
|
@@ -19,6 +21,7 @@ function validateTaskIdentifier(errors, statement) {
|
|
|
19
21
|
}
|
|
20
22
|
}
|
|
21
23
|
|
|
24
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
22
25
|
function validatePriority(errors, statement, fieldMap) {
|
|
23
26
|
const field = fieldMap.get("priority")?.[0];
|
|
24
27
|
if (!field) return;
|
|
@@ -35,6 +38,7 @@ function validatePriority(errors, statement, fieldMap) {
|
|
|
35
38
|
}
|
|
36
39
|
}
|
|
37
40
|
|
|
41
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
38
42
|
function validateWorkType(errors, statement, fieldMap) {
|
|
39
43
|
const field = fieldMap.get("work_type")?.[0];
|
|
40
44
|
if (!field) return;
|
|
@@ -51,6 +55,7 @@ function validateWorkType(errors, statement, fieldMap) {
|
|
|
51
55
|
}
|
|
52
56
|
}
|
|
53
57
|
|
|
58
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
54
59
|
function validateBlockingPair(errors, statement, fieldMap, registry) {
|
|
55
60
|
// Self-block guard. Reciprocal `blocks` <-> `blocked_by` resolution is the
|
|
56
61
|
// resolver's job; here we just guard against trivial cycles.
|
|
@@ -69,6 +74,7 @@ function validateBlockingPair(errors, statement, fieldMap, registry) {
|
|
|
69
74
|
}
|
|
70
75
|
}
|
|
71
76
|
|
|
77
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
72
78
|
function validateClaimedByPresence(errors, statement, fieldMap) {
|
|
73
79
|
// claimed/in-progress/done all require a claimed_by; unclaimed/blocked do not.
|
|
74
80
|
const statusField = fieldMap.get("status")?.[0];
|
|
@@ -84,6 +90,7 @@ function validateClaimedByPresence(errors, statement, fieldMap) {
|
|
|
84
90
|
}
|
|
85
91
|
}
|
|
86
92
|
|
|
93
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
87
94
|
export function validateTask(errors, statement, fieldMap, registry) {
|
|
88
95
|
if (statement.kind !== "task") {
|
|
89
96
|
return;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
// @ts-check
|
|
1
2
|
import {
|
|
2
3
|
UI_PATTERN_KINDS,
|
|
3
4
|
UI_REGION_KINDS
|
|
@@ -36,6 +37,7 @@ const WIDGET_BEHAVIOR_KINDS = new Set([
|
|
|
36
37
|
"keyboard_navigation"
|
|
37
38
|
]);
|
|
38
39
|
|
|
40
|
+
/** @type {Record<string, Set<string>>} */
|
|
39
41
|
const WIDGET_BEHAVIOR_DIRECTIVES = {
|
|
40
42
|
selection: new Set(["mode", "state", "emits"]),
|
|
41
43
|
sorting: new Set(["fields", "default"]),
|
|
@@ -51,10 +53,12 @@ const WIDGET_BEHAVIOR_DIRECTIVES = {
|
|
|
51
53
|
keyboard_navigation: new Set(["scope", "shortcuts"])
|
|
52
54
|
};
|
|
53
55
|
|
|
56
|
+
/** @param {TopogramToken | null | undefined} token @returns {any} */
|
|
54
57
|
function tokenValue(token) {
|
|
55
58
|
return token?.value ?? null;
|
|
56
59
|
}
|
|
57
60
|
|
|
61
|
+
/** @param {TopogramToken | null | undefined} token @returns {any[]} */
|
|
58
62
|
function tokenValues(token) {
|
|
59
63
|
if (!token) {
|
|
60
64
|
return [];
|
|
@@ -66,6 +70,7 @@ function tokenValues(token) {
|
|
|
66
70
|
return value == null ? [] : [value];
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
/** @param {TopogramStatement} statement @returns {Set<any>} */
|
|
69
74
|
function widgetPropNames(statement) {
|
|
70
75
|
return new Set(blockEntries(getFieldValue(statement, "props"))
|
|
71
76
|
.map((entry) => entry.items[0])
|
|
@@ -73,6 +78,7 @@ function widgetPropNames(statement) {
|
|
|
73
78
|
.map((item) => item.value));
|
|
74
79
|
}
|
|
75
80
|
|
|
81
|
+
/** @param {TopogramStatement} statement @returns {Set<any>} */
|
|
76
82
|
function widgetEventNames(statement) {
|
|
77
83
|
return new Set(blockEntries(getFieldValue(statement, "events"))
|
|
78
84
|
.map((entry) => entry.items[0])
|
|
@@ -80,6 +86,7 @@ function widgetEventNames(statement) {
|
|
|
80
86
|
.map((item) => item.value));
|
|
81
87
|
}
|
|
82
88
|
|
|
89
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap */
|
|
83
90
|
function validateWidgetCategory(errors, statement, fieldMap) {
|
|
84
91
|
const field = fieldMap.get("category")?.[0];
|
|
85
92
|
if (!field) {
|
|
@@ -96,6 +103,7 @@ function validateWidgetCategory(errors, statement, fieldMap) {
|
|
|
96
103
|
}
|
|
97
104
|
}
|
|
98
105
|
|
|
106
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
99
107
|
function validateWidgetProps(errors, statement) {
|
|
100
108
|
for (const entry of blockEntries(getFieldValue(statement, "props"))) {
|
|
101
109
|
const [name, type, requiredness, ...rest] = entry.items;
|
|
@@ -127,6 +135,7 @@ function validateWidgetProps(errors, statement) {
|
|
|
127
135
|
}
|
|
128
136
|
}
|
|
129
137
|
|
|
138
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramRegistry} registry */
|
|
130
139
|
function validateWidgetEvents(errors, statement, registry) {
|
|
131
140
|
for (const entry of blockEntries(getFieldValue(statement, "events"))) {
|
|
132
141
|
const [eventName, shapeRef] = entry.items;
|
|
@@ -151,6 +160,7 @@ function validateWidgetEvents(errors, statement, registry) {
|
|
|
151
160
|
}
|
|
152
161
|
}
|
|
153
162
|
|
|
163
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement */
|
|
154
164
|
function validateWidgetSlots(errors, statement) {
|
|
155
165
|
for (const entry of blockEntries(getFieldValue(statement, "slots"))) {
|
|
156
166
|
const [slotName, description] = entry.items;
|
|
@@ -165,6 +175,7 @@ function validateWidgetSlots(errors, statement) {
|
|
|
165
175
|
}
|
|
166
176
|
}
|
|
167
177
|
|
|
178
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {string} key @param {Set<string>} allowed @param {string} label */
|
|
168
179
|
function validateSymbolList(errors, statement, fieldMap, key, allowed, label) {
|
|
169
180
|
const field = fieldMap.get(key)?.[0];
|
|
170
181
|
if (!field) {
|
|
@@ -178,6 +189,7 @@ function validateSymbolList(errors, statement, fieldMap, key, allowed, label) {
|
|
|
178
189
|
}
|
|
179
190
|
}
|
|
180
191
|
|
|
192
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramRegistry} registry @param {any} kind @param {any} directive @param {TopogramToken} valueToken @param {Set<any>} eventNames */
|
|
181
193
|
function validateBehaviorActionReferences(errors, statement, registry, kind, directive, valueToken, eventNames) {
|
|
182
194
|
for (const actionId of tokenValues(valueToken)) {
|
|
183
195
|
if (eventNames.has(actionId)) {
|
|
@@ -195,6 +207,7 @@ function validateBehaviorActionReferences(errors, statement, registry, kind, dir
|
|
|
195
207
|
}
|
|
196
208
|
}
|
|
197
209
|
|
|
210
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
198
211
|
function validateWidgetBehaviors(errors, statement, fieldMap, registry) {
|
|
199
212
|
validateSymbolList(errors, statement, fieldMap, "behavior", WIDGET_BEHAVIOR_KINDS, "behavior");
|
|
200
213
|
|
|
@@ -259,6 +272,7 @@ function validateWidgetBehaviors(errors, statement, fieldMap, registry) {
|
|
|
259
272
|
}
|
|
260
273
|
}
|
|
261
274
|
|
|
275
|
+
/** @param {ValidationErrors} errors @param {TopogramStatement} statement @param {TopogramFieldMap} fieldMap @param {TopogramRegistry} registry */
|
|
262
276
|
export function validateWidget(errors, statement, fieldMap, registry) {
|
|
263
277
|
if (statement.kind !== "widget") {
|
|
264
278
|
return;
|