@intentius/plywood 0.0.0-stage → 0.0.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.
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["../src/config/types.ts", "../src/config/agents.ts", "../src/config/apply.ts", "../src/config/approval.ts", "../src/config/chant-keys.ts", "../src/words.ts", "../src/config/control.ts", "../package.json", "../src/image-digests.json", "../src/images.ts", "../src/config/images.ts", "../src/config/stacks.ts", "../src/config/drift.ts", "../src/config/engine.ts", "../src/config/identity.ts", "../src/config/jobs.ts", "../src/config/later.ts", "../src/config/locks.ts", "../src/config/observe.ts", "../src/config/policy.ts", "../src/config/review-stacks.ts", "../src/config/routing.ts", "../src/config/index.ts", "../src/chant-config.ts", "../src/config-check.ts", "../src/init/detect.ts", "../src/chant-product.ts", "../src/chant-next.ts", "../src/init/own-jobs.ts", "../src/init/note-control.ts", "../src/init/workflow.ts", "../src/review-stacks.ts", "../src/waves-workflow.ts", "../src/agent-jobs.ts", "../src/drift-notify.ts", "../src/jobs.ts", "../src/refusals.ts", "../src/up.ts", "../src/drift.ts", "../src/tips.ts", "../src/agents.ts", "../src/policy-presets.ts", "../src/init/backend.ts", "../src/init/adopt.ts", "../src/init/engine.ts", "../src/init/presets.ts", "../src/templates.ts", "../src/init/render.ts", "../src/stack-order.ts", "../src/import/types.ts", "../src/import/deployments.ts", "../src/import/env0.ts", "../src/import/pulumi-actions.ts", "../src/import/spacelift.ts", "../src/import/index.ts", "../src/init.ts", "../src/control.ts", "../src/stages.ts", "../src/cli.ts", "../src/exit-codes.ts", "../src/audit.ts", "../src/estate.ts", "../src/notify.ts", "../src/guard.ts", "../src/identities.ts", "../src/telemetry.ts", "../src/upgrade.ts", "../src/stack-ops.ts", "../src/bin.ts"],
4
+ "sourcesContent": ["/**\n * The shapes every config group shares. plywood.yml is read in groups, one\n * module per group of keys under src/config/, and src/config/index.ts lists\n * them. A unit that adds keys adds a group file and one line in the index.\n *\n * Each group owns its keys four ways: the JSON schema for them (composed into\n * plywood.schema.json by scripts/build-schema.mjs), the checks the schema\n * cannot make, the defaults, and the translation into chant's settings\n * (src/chant-config.ts). plywood holds the words and the defaults; chant\n * runs every stage with the settings (CONTRIBUTING.md).\n */\nimport type { ChantSettings } from \"../chant-config\";\n\n/** A JSON schema fragment, as the group writes it. */\nexport type JsonSchema = Record<string, unknown>;\n\n/** plywood.yml as parsed, before any check. */\nexport type RawConfig = Record<string, unknown>;\n\nexport interface ConfigProblem {\n /** The key path, as plywood.yml spells it (`locks.grain`, `stacks.shop/dev.gate`). */\n key: string;\n message: string;\n /** `error` fails `plywood config check`; `warning` is printed and the check passes. */\n severity: \"error\" | \"warning\";\n}\n\nexport interface ConfigGroup {\n /** The group's name, for messages and the schema's comment. */\n name: string;\n /** The top-level keys the group owns. */\n keys: readonly string[];\n /** The JSON schema of each key the group owns. */\n schema: Readonly<Record<string, JsonSchema>>;\n /** The checks the schema cannot make. `doc` is the whole file, so a group can read a key another group owns. */\n check(doc: RawConfig): ConfigProblem[];\n /** Writes the group's part of chant's settings from a config that checked clean. */\n translate(doc: RawConfig, out: ChantSettings): void;\n}\n\nexport function isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\nexport function error(key: string, message: string): ConfigProblem {\n return { key, message, severity: \"error\" };\n}\n\nexport function warning(key: string, message: string): ConfigProblem {\n return { key, message, severity: \"warning\" };\n}\n\n/** A problem when `v` is set and is none of `allowed`. */\nexport function oneOf(v: unknown, allowed: readonly string[], key: string): ConfigProblem[] {\n if (v === undefined || (typeof v === \"string\" && allowed.includes(v))) return [];\n return [error(key, `is ${JSON.stringify(v)}; give one of ${allowed.join(\", \")}`)];\n}\n\n/** Problems for keys of `v` outside `allowed`. */\nexport function onlyKeys(v: Record<string, unknown>, allowed: readonly string[], key: string): ConfigProblem[] {\n return Object.keys(v)\n .filter((k) => !allowed.includes(k))\n .map((k) => error(`${key}.${k}`, `is not a key of ${key}; its keys are ${allowed.join(\", \")}`));\n}\n\n/** A problem when `v` is set and is not a mapping. */\nexport function mapping(v: unknown, key: string): ConfigProblem[] {\n return v === undefined || isObject(v) ? [] : [error(key, \"must be a mapping\")];\n}\n\n/** Problems when `v` is set and is not a list of strings. */\nexport function stringList(v: unknown, key: string): ConfigProblem[] {\n if (v === undefined) return [];\n if (!Array.isArray(v) || v.some((s) => typeof s !== \"string\")) return [error(key, \"must be a list of strings\")];\n return [];\n}\n\n/** A backend URL, at the top level or per stack. */\nexport const BACKEND_SCHEMA: JsonSchema = {\n type: \"string\",\n description: \"The backend URL. A plunge+ URL (plunge+file://, plunge+s3://) picks the plunge engine.\",\n};\n", "/**\n * `review` and `agent`: the model that reviews a pull request, and the\n * agents that act on a request (plywood#19).\n *\n * review true, or a mapping; off when absent\n * review.instructions the instructions file on the base branch (chant's\n * default, .chant/review.md)\n * review.command the model command, prompt on stdin and review on\n * stdout (chant's default: Claude Code in print\n * mode with no tools)\n * review.key_env the variable holding the model's key, the one\n * secret the command sees (default ANTHROPIC_API_KEY)\n * review.timeout minutes the command may run (chant's default, 10)\n * -> chant's reviewAgent step in handoff mode, in a pull request Op\n * `plywood ci` writes (src/agents.ts); the model's job holds no forge\n * write token, and a second job posts the note\n *\n * agent.comment true answers `/plywood agent <ask>`\n * agent.drift true has the drift agent open a pull request for a\n * drifted stack (respond.drift: pull-request)\n * agent.command, agent.key_env, agent.timeout as for review\n * agent.max_runs the most agent runs per day, the spend limit\n * agent.token_env the secret (GitHub, Forgejo) or protected variable\n * (GitLab) holding the token the push job pushes\n * the agent's branch with. A GitHub push with the\n * job token starts no workflow, so the agent's\n * commit is not previewed until a token of a user\n * or app pushes it\n * -> pipeline.agent, and chant's agent job (chant#4616, src/agent-jobs.ts):\n * `plywood ci` writes the comment agent's jobs and puts the drift\n * agent on each scheduled drift Op, on a chant that has the job\n */\nimport { error, isObject, onlyKeys, warning, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\nexport const DEFAULT_KEY_ENV = \"ANTHROPIC_API_KEY\";\nconst VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\nconst REVIEW_KEYS = [\"instructions\", \"command\", \"key_env\", \"timeout\"] as const;\nconst AGENT_KEYS = [\"comment\", \"drift\", \"command\", \"key_env\", \"timeout\", \"max_runs\", \"token_env\"] as const;\n\n/** What the review Op's step takes (chant `ReviewAgentArgs`). */\nexport interface ReviewSettings {\n instructions?: string;\n command?: string;\n keyEnv: string;\n timeout?: number;\n}\n\nexport interface AgentSettings {\n comment: boolean;\n drift: boolean;\n command?: string;\n keyEnv: string;\n timeout?: number;\n maxRuns?: number;\n /** The push job's token variable (chant `OpAgentSpec.tokenEnv`). Absent: chant's default, the job token on GitHub and Forgejo. */\n tokenEnv?: string;\n}\n\n/** The review settings, or undefined when `review` is off. */\nexport function reviewOf(doc: RawConfig): ReviewSettings | undefined {\n const r = doc.review;\n if (r === undefined || r === false) return undefined;\n const m = isObject(r) ? r : {};\n return {\n ...(typeof m.instructions === \"string\" ? { instructions: m.instructions } : {}),\n ...(typeof m.command === \"string\" ? { command: m.command } : {}),\n keyEnv: typeof m.key_env === \"string\" ? m.key_env : DEFAULT_KEY_ENV,\n ...(typeof m.timeout === \"number\" ? { timeout: m.timeout } : {}),\n };\n}\n\nexport function agentOf(doc: RawConfig): AgentSettings | undefined {\n const a = doc.agent;\n if (!isObject(a)) return undefined;\n return {\n comment: a.comment === true,\n drift: a.drift === true,\n ...(typeof a.command === \"string\" ? { command: a.command } : {}),\n keyEnv: typeof a.key_env === \"string\" ? a.key_env : DEFAULT_KEY_ENV,\n ...(typeof a.timeout === \"number\" ? { timeout: a.timeout } : {}),\n ...(typeof a.max_runs === \"number\" ? { maxRuns: a.max_runs } : {}),\n ...(typeof a.token_env === \"string\" ? { tokenEnv: a.token_env } : {}),\n };\n}\n\nfunction modelKeys(m: Record<string, unknown>, key: string): ConfigProblem[] {\n const out: ConfigProblem[] = [];\n if (m.instructions !== undefined && (typeof m.instructions !== \"string\" || m.instructions.trim() === \"\")) out.push(error(`${key}.instructions`, \"is a path on the base branch, such as .chant/review.md\"));\n if (m.command !== undefined && (typeof m.command !== \"string\" || m.command.trim() === \"\")) out.push(error(`${key}.command`, \"is a command line that reads the prompt on stdin\"));\n if (m.key_env !== undefined && (typeof m.key_env !== \"string\" || !VARIABLE.test(m.key_env))) out.push(error(`${key}.key_env`, \"names an environment variable, such as ANTHROPIC_API_KEY; the key itself never goes in plywood.yml\"));\n if (m.timeout !== undefined && (typeof m.timeout !== \"number\" || !Number.isInteger(m.timeout) || m.timeout < 1)) out.push(error(`${key}.timeout`, \"is a whole number of minutes, 1 or more\"));\n return out;\n}\n\nconst modelSchema = {\n command: { type: \"string\", description: \"The model command: the prompt on stdin, the answer on stdout.\" },\n key_env: { type: \"string\", default: DEFAULT_KEY_ENV, description: \"The variable holding the model's key, the one secret the command sees.\" },\n timeout: { type: \"integer\", minimum: 1, description: \"Minutes the command may run.\" },\n};\n\nexport const agents: ConfigGroup = {\n name: \"agents\",\n keys: [\"review\", \"agent\"],\n schema: {\n review: {\n description: \"A model reviews each pull request and posts one note. It approves and gates nothing. Off when absent.\",\n oneOf: [\n { type: \"boolean\" },\n {\n type: \"object\",\n additionalProperties: false,\n properties: { instructions: { type: \"string\", description: \"The instructions file, read from the base branch. Default .chant/review.md.\" }, ...modelSchema },\n },\n ],\n },\n agent: {\n type: \"object\",\n additionalProperties: false,\n description: \"Agents that act on a request: /plywood agent <ask>, and the drift agent's pull request.\",\n properties: {\n comment: { type: \"boolean\", default: false, description: \"Answer /plywood agent <ask> on a pull request.\" },\n drift: { type: \"boolean\", default: false, description: \"Open a pull request that fixes a drifted stack (respond.drift: pull-request).\" },\n ...modelSchema,\n max_runs: { type: \"integer\", minimum: 1, description: \"The most agent runs per day.\" },\n token_env: {\n type: \"string\",\n description: \"The secret (GitHub, Forgejo) or protected variable (GitLab) holding the token the push job pushes the agent's branch with. Default: the job token on GitHub and Forgejo, CHANT_FORGE_TOKEN on GitLab. A GitHub push with the job token starts no workflow, so the agent's commit gets no preview.\",\n },\n },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [];\n const r = doc.review;\n if (r !== undefined && typeof r !== \"boolean\") {\n if (!isObject(r)) out.push(error(\"review\", \"is true, or a mapping of instructions, command, key_env and timeout\"));\n else out.push(...onlyKeys(r, REVIEW_KEYS, \"review\"), ...modelKeys(r, \"review\"));\n }\n const a = doc.agent;\n if (a !== undefined) {\n if (!isObject(a)) out.push(error(\"agent\", \"must be a mapping\"));\n else {\n out.push(...onlyKeys(a, AGENT_KEYS, \"agent\"), ...modelKeys(a, \"agent\"));\n for (const k of [\"comment\", \"drift\"] as const) if (a[k] !== undefined && typeof a[k] !== \"boolean\") out.push(error(`agent.${k}`, \"is true or false\"));\n if (a.token_env !== undefined && (typeof a.token_env !== \"string\" || !VARIABLE.test(a.token_env))) out.push(error(\"agent.token_env\", \"names the secret holding the push token, such as PLYWOOD_AGENT_TOKEN; the token itself never goes in plywood.yml\"));\n if (a.max_runs !== undefined && (typeof a.max_runs !== \"number\" || !Number.isInteger(a.max_runs) || a.max_runs < 1)) out.push(error(\"agent.max_runs\", \"is a whole number of runs per day, 1 or more\"));\n if ((a.comment === true || a.drift === true) && a.max_runs === undefined) out.push(warning(\"agent.max_runs\", \"is not set, so nothing limits how often an agent runs\"));\n if (a.drift === true && !(isObject(doc.respond) && doc.respond.drift === \"pull-request\")) out.push(warning(\"agent.drift\", \"is true and respond.drift is not pull-request, so no drift run starts the agent\"));\n }\n }\n const respond = isObject(doc.respond) ? doc.respond.drift : undefined;\n if (respond === \"pull-request\" && !(isObject(a) && a.drift === true)) out.push(warning(\"respond.drift\", \"is pull-request and agent.drift is not true, so a drift run keeps the issue only\"));\n return out;\n },\n translate(doc, out) {\n const review = reviewOf(doc);\n if (review) out.pipeline.review = review;\n const agent = agentOf(doc);\n if (agent) out.pipeline.agent = agent;\n },\n};\n", "/**\n * `apply`: when a change updates its stacks. `when: merge` (the default)\n * updates after the merge; `when: pull-request` updates an open pull request\n * on `/plywood up`, and `requires` lists what it needs first (all four by\n * default). Values follow terragucci's `apply` key.\n *\n * apply.when merge ci.workflow trunk-curated+apply-on-merge\n * apply.when pull-request ci.workflow apply-before-merge\n *\n * `merge: auto` merges the pull request once its update before merge\n * applied and its record is on the ledger, with the head checked again\n * first (chant#4636 `applyMerge`). The merge uses the token in the variable\n * `merge_token_env` names, never the job's: a secret of that name on GitHub\n * and Forgejo, a protected variable on GitLab. `merge_method` is merge,\n * squash or rebase (the forge's default when absent). A refused merge\n * leaves the update recorded and says why on the pull request.\n */\nimport { error, isObject, oneOf, onlyKeys, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\nimport type { ChantCiWorkflow } from \"../chant-config\";\n\nexport const APPLY_WHEN = [\"merge\", \"pull-request\"] as const;\nexport type ApplyWhen = (typeof APPLY_WHEN)[number];\nexport const DEFAULT_APPLY_WHEN: ApplyWhen = \"merge\";\n\n/** What an open pull request needs before `/plywood up`: an approval of its head, a forge that says it can merge, a head containing the default branch, and every check passed. */\nexport const APPLY_REQUIRES = [\"approved\", \"mergeable\", \"undiverged\", \"checks\"] as const;\n\nexport const APPLY_MERGE = [\"manual\", \"auto\"] as const;\nexport const MERGE_METHODS = [\"merge\", \"squash\", \"rebase\"] as const;\nconst VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/** `apply.merge: auto` as chant's `applyMerge`, or undefined. */\nexport function applyMergeOf(doc: RawConfig): { tokenEnv: string; method?: (typeof MERGE_METHODS)[number] } | undefined {\n const a = isObject(doc.apply) ? doc.apply : {};\n if (a.merge !== \"auto\" || typeof a.merge_token_env !== \"string\") return undefined;\n const method = (MERGE_METHODS as readonly unknown[]).includes(a.merge_method) ? (a.merge_method as (typeof MERGE_METHODS)[number]) : undefined;\n return { tokenEnv: a.merge_token_env, ...(method ? { method } : {}) };\n}\n\nexport const WORKFLOW_OF: Readonly<Record<ApplyWhen, ChantCiWorkflow>> = {\n merge: \"trunk-curated+apply-on-merge\",\n \"pull-request\": \"apply-before-merge\",\n};\n\nexport function applyWhenOf(doc: RawConfig): ApplyWhen {\n const a = isObject(doc.apply) ? doc.apply : {};\n return a.when === \"pull-request\" ? \"pull-request\" : DEFAULT_APPLY_WHEN;\n}\n\n/** The checks apply.requires lists, in plywood.yml's order; all four when it lists none. */\nexport function applyRequiresOf(doc: RawConfig): string[] {\n const a = isObject(doc.apply) ? doc.apply : {};\n return Array.isArray(a.requires) ? (a.requires as unknown[]).filter((r): r is string => typeof r === \"string\") : [...APPLY_REQUIRES];\n}\n\nexport const apply: ConfigGroup = {\n name: \"apply\",\n keys: [\"apply\"],\n schema: {\n apply: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n when: { type: \"string\", enum: [...APPLY_WHEN], default: DEFAULT_APPLY_WHEN, description: \"merge, or pull-request for /plywood up before merge.\" },\n requires: {\n type: \"array\",\n items: { type: \"string\", enum: [...APPLY_REQUIRES] },\n uniqueItems: true,\n description: \"What an open pull request needs before /plywood up updates it. All four when absent. Only with when: pull-request.\",\n },\n merge: { type: \"string\", enum: [...APPLY_MERGE], default: \"manual\", description: \"auto merges the pull request once its update before merge applied. Only with when: pull-request.\" },\n merge_token_env: { type: \"string\", description: \"The variable holding the token the merge uses: a secret on GitHub and Forgejo, a protected variable on GitLab. Needed with merge: auto.\" },\n merge_method: { type: \"string\", enum: [...MERGE_METHODS], description: \"merge, squash or rebase. The forge's default when absent.\" },\n },\n },\n },\n check(doc) {\n if (doc.apply === undefined) return [];\n if (!isObject(doc.apply)) return [error(\"apply\", \"must be a mapping\")];\n const a = doc.apply;\n const out: ConfigProblem[] = [\n ...onlyKeys(a, [\"when\", \"requires\", \"merge\", \"merge_token_env\", \"merge_method\"], \"apply\"),\n ...oneOf(a.when, APPLY_WHEN, \"apply.when\"),\n ...oneOf(a.merge, APPLY_MERGE, \"apply.merge\"),\n ...oneOf(a.merge_method, MERGE_METHODS, \"apply.merge_method\"),\n ];\n if (a.merge === \"auto\") {\n if (a.when !== \"pull-request\") out.push(error(\"apply.merge\", \"auto merges after an update before merge; set apply.when: pull-request, or drop it\"));\n if (typeof a.merge_token_env !== \"string\" || !VARIABLE.test(a.merge_token_env)) out.push(error(\"apply.merge_token_env\", \"names the variable holding the merge's token, such as PLYWOOD_MERGE_TOKEN; merge: auto never merges with the job's token\"));\n } else if (a.merge_token_env !== undefined || a.merge_method !== undefined) {\n out.push(error(a.merge_token_env !== undefined ? \"apply.merge_token_env\" : \"apply.merge_method\", \"goes with apply.merge: auto\"));\n }\n if (a.requires !== undefined) {\n if (!Array.isArray(a.requires)) out.push(error(\"apply.requires\", `must be a list of ${APPLY_REQUIRES.join(\", \")}`));\n else {\n for (const r of a.requires) out.push(...oneOf(r, APPLY_REQUIRES, \"apply.requires\"));\n if (a.when !== \"pull-request\") out.push(error(\"apply.requires\", \"applies only to an update before merge; set apply.when: pull-request, or drop it\"));\n }\n }\n return out;\n },\n translate(doc, out) {\n const when = applyWhenOf(doc);\n out.ci.workflow = WORKFLOW_OF[when];\n if (when === \"pull-request\") {\n const a = doc.apply as Record<string, unknown>;\n out.pipeline.applyRequires = Array.isArray(a.requires) ? [...(a.requires as string[])] : [...APPLY_REQUIRES];\n const merge = applyMergeOf(doc);\n if (merge) out.pipeline.applyMerge = merge;\n }\n },\n};\n", "/**\n * `gate`, `approval` and `approval_rules`: when a wave waits for people,\n * which approvals count, and how many of whom.\n *\n * gate always, on-destructive (default) or never; a stack may set its own\n * approval ledger (default), sealed or pr-review, chant's approval sources\n * approval_rules stack glob to { role | roles, quorum }, as chant's quorum rules\n *\n * The author of a pull request never counts toward its own quorum, so every\n * rule carries `notAuthor` and the pipeline excludes the author's approval.\n * A rule that names a role is met only by a proven approval, which an\n * unsigned ledger approval is not: check warns about that pairing.\n */\nimport { error, isObject, oneOf, onlyKeys, warning, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\nimport type { ChantApprovalSource, ChantGatePolicy, ChantQuorumRule } from \"../chant-config\";\n\nexport const GATES = [\"always\", \"on-destructive\", \"never\"] as const;\nexport const DEFAULT_GATE: ChantGatePolicy = \"on-destructive\";\nexport const APPROVALS = [\"ledger\", \"sealed\", \"pr-review\"] as const;\nexport const DEFAULT_APPROVAL: ChantApprovalSource = \"ledger\";\nexport const APPROVAL_RULE_KEYS = [\"role\", \"roles\", \"quorum\"] as const;\n\nexport interface ApprovalRuleSettings {\n role?: string;\n roles?: string[];\n quorum?: number;\n}\n\nexport function approvalOf(doc: RawConfig): ChantApprovalSource {\n return typeof doc.approval === \"string\" && (APPROVALS as readonly string[]).includes(doc.approval) ? (doc.approval as ChantApprovalSource) : DEFAULT_APPROVAL;\n}\n\nexport function gateOf(doc: RawConfig): ChantGatePolicy {\n return typeof doc.gate === \"string\" && (GATES as readonly string[]).includes(doc.gate) ? (doc.gate as ChantGatePolicy) : DEFAULT_GATE;\n}\n\n/** `approval_rules` as chant's quorum rules, in the order plywood.yml lists them. */\nexport function quorumOf(rules: Record<string, ApprovalRuleSettings>): ChantQuorumRule[] {\n return Object.entries(rules).map(([glob, r]) => {\n const roles = [...(r.role !== undefined ? [r.role] : []), ...(r.roles ?? [])];\n return { targets: [glob], count: r.quorum ?? 1, ...(roles.length ? { roles } : {}), notAuthor: true };\n });\n}\n\nexport const approval: ConfigGroup = {\n name: \"approval\",\n keys: [\"gate\", \"approval\", \"approval_rules\"],\n schema: {\n gate: { type: \"string\", enum: [...GATES], default: DEFAULT_GATE, description: \"always, on-destructive or never.\" },\n approval: { type: \"string\", enum: [...APPROVALS], default: DEFAULT_APPROVAL, description: \"ledger, sealed or pr-review.\" },\n approval_rules: {\n type: \"object\",\n description: \"Role and quorum per stack glob. Read at base.\",\n additionalProperties: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n role: { type: \"string\", description: \"A role .chant/trust.json gives the approvers.\" },\n roles: { type: \"array\", items: { type: \"string\" }, description: \"Roles, any of which counts.\" },\n quorum: { type: \"integer\", minimum: 1, default: 1, description: \"Distinct approvers the stacks need.\" },\n },\n },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [...oneOf(doc.gate, GATES, \"gate\"), ...oneOf(doc.approval, APPROVALS, \"approval\")];\n const rules = doc.approval_rules;\n if (rules === undefined) return out;\n if (!isObject(rules)) return [...out, error(\"approval_rules\", \"must map a stack glob to { role, quorum }\")];\n let namesRole = false;\n for (const [glob, r] of Object.entries(rules)) {\n const key = `approval_rules.${glob}`;\n if (!isObject(r)) {\n out.push(error(key, \"must be a mapping of role, roles and quorum\"));\n continue;\n }\n out.push(...onlyKeys(r, APPROVAL_RULE_KEYS, key));\n if (r.role !== undefined && typeof r.role !== \"string\") out.push(error(`${key}.role`, \"must be a string\"));\n if (r.roles !== undefined && (!Array.isArray(r.roles) || r.roles.some((x) => typeof x !== \"string\"))) out.push(error(`${key}.roles`, \"must be a list of strings\"));\n if (r.quorum !== undefined && (!Number.isInteger(r.quorum) || (r.quorum as number) < 1)) out.push(error(`${key}.quorum`, \"must be a whole number, 1 or more\"));\n if (r.role !== undefined || (Array.isArray(r.roles) && r.roles.length)) namesRole = true;\n }\n if (namesRole && approvalOf(doc) === \"ledger\") {\n out.push(warning(\"approval_rules\", \"names a role and approval is ledger: only a proven approval counts toward a role, so set approval: sealed or pr-review\"));\n }\n return out;\n },\n translate(doc, out) {\n out.pipeline.gate = gateOf(doc);\n out.pipeline.approval = approvalOf(doc);\n out.pipeline.excludeAuthor = true;\n if (isObject(doc.approval_rules)) out.pipeline.quorum = quorumOf(doc.approval_rules as Record<string, ApprovalRuleSettings>);\n },\n};\n", "/**\n * chant keys in plywood.yml are refused. plywood turns its own keys into\n * chant's settings (src/chant-config.ts), so a `ci:` block, or a dotted\n * `ci.<key>` written as one key, is refused with the plywood key that sets\n * the same thing.\n */\nimport { error, isObject, type ConfigGroup, type ConfigProblem } from \"./types\";\n\n/** chant's `ci.<key>` to the plywood key that sets it; null where plywood sets it itself. */\nexport const PLYWOOD_KEY_FOR: Readonly<Record<string, string | null>> = {\n workflow: \"apply.when\",\n locks: \"locks.when\",\n lockGrain: \"locks.grain\",\n prEnvironment: \"review_stacks\",\n branches: \"branches\",\n labels: \"labels\",\n policy: \"policy\",\n identity: \"identity\",\n reportUrl: \"reports\",\n hooks: null,\n green: null,\n};\n\n/** Why `ci.<sub>` is refused, naming the plywood key that sets it. */\nexport function chantKeyMessage(sub: string | undefined): string {\n if (sub === undefined) return \"is chant's block, and plywood.yml holds no chant key; set plywood's keys (apply, locks, review_stacks, branches, labels) and plywood sets chant's\";\n const plywood = PLYWOOD_KEY_FOR[sub];\n if (plywood) return `is chant's key; set ${plywood} in plywood.yml, and plywood sets ci.${sub} from it`;\n if (plywood === null) return `is chant's key, and plywood sets ci.${sub} itself`;\n return `is chant's key, and plywood.yml has no key for ci.${sub}`;\n}\n\nexport const chantKeys: ConfigGroup = {\n name: \"chant keys\",\n keys: [],\n schema: {},\n check(doc) {\n const out: ConfigProblem[] = [];\n for (const [key, v] of Object.entries(doc)) {\n if (key === \"ci\") {\n if (isObject(v) && Object.keys(v).length) for (const sub of Object.keys(v)) out.push(error(`ci.${sub}`, chantKeyMessage(sub)));\n else out.push(error(\"ci\", chantKeyMessage(undefined)));\n } else if (key.startsWith(\"ci.\")) {\n const sub = key.slice(3).split(\".\")[0];\n out.push(error(key, chantKeyMessage(sub)));\n }\n }\n return out;\n },\n translate() {},\n};\n", "/**\n * plywood's words: the names chant's product pipeline fills into its\n * statuses, comments and gates (chant#4550, rulings C, D and E). plywood\n * holds words only; chant runs every stage in process with them.\n */\n\nexport const PRODUCT = \"plywood\";\n\nexport const TAGLINE = \"CI Automation for Pulumi\";\n\n/** The op that applies a merged change, and the gates it passes (chant#4550 ruling E). */\nexport const OP_NAME = \"pulumi-up\";\nexport const PR_GATE = \"up\";\nexport const waveGate = (k: number): string => `wave-${k}`;\n\nexport type Verb = \"check\" | \"preview\" | \"up\" | \"drift\" | \"approve\" | \"override\";\n\nexport interface VerbWords {\n verb: Verb;\n summary: string;\n}\n\n/** The verbs, in the order `plywood --help` lists them. */\nexport const VERBS: readonly VerbWords[] = [\n { verb: \"check\", summary: \"Check plywood.yml and run the check hooks at the base commit\" },\n { verb: \"preview\", summary: \"Preview the stacks a pull request reaches, with one note and a status per stack\" },\n { verb: \"up\", summary: \"Update the stacks a merged pull request changes, in gated waves\" },\n { verb: \"drift\", summary: \"Find stacks whose resources differ from their state\" },\n { verb: \"approve\", summary: \"Approve a pull request's previews for up\" },\n { verb: \"override\", summary: \"Override a policy denial on a pull request\" },\n];\n\n/** The command a generated job runs in place of `chant`; the bin passes the rest to chant in process. */\nexport const BIN = \"npx --no-install plywood\";\n\n/** chant's comment commands, by the word typed after `/plywood` (chant `CiProductCommand`). */\nexport type ChantCommand = \"plan\" | \"apply\" | \"lock\" | \"unlock\" | \"agent\";\n\n/**\n * plywood's words in the shape chant's `assertProductWords` takes\n * (`@intentius/chant/ci-product`, chant#4550). chant fills them into its own\n * sentences: the status `plywood/preview/<stack>`, the note heading, the\n * \"may register at up\" rows (chant#4548), and the approve and override lines.\n */\nexport interface ProductWordsInput {\n product: string;\n stages: { plan: string; apply: string };\n verbs: { plan: [string, string]; apply: [string, string] };\n noun: [string, string];\n commands: Record<string, ChantCommand>;\n approve: string;\n override: string;\n op: string;\n prGate: string;\n gateName: string;\n approval: \"pull-request\" | \"per-wave\";\n bin: string;\n /**\n * What chant's notify sends under these words (chant#4610): the event's\n * `source`, the wave label in its summary and the signed webhook's header\n * prefix. A chant before chant#4610 reads none of it and sends chant's.\n */\n notify?: { source: string; wave: string; headers: string };\n}\n\n/** plywood's notify words: receivers route on `plywood` and verify `x-plywood-*` headers. */\nexport const NOTIFY_WORDS = Object.freeze({ source: PRODUCT, wave: \"wave {k} ({name}) of {spec}\", headers: `x-${PRODUCT}` });\n\nexport const PRODUCT_WORDS: Readonly<ProductWordsInput> = Object.freeze({\n product: PRODUCT,\n stages: { plan: \"preview\", apply: \"up\" },\n verbs: { plan: [\"preview\", \"previewed\"], apply: [\"update\", \"updated\"] },\n noun: [\"stack\", \"stacks\"],\n commands: { preview: \"plan\", up: \"apply\", lock: \"lock\", unlock: \"unlock\" },\n approve: \"plywood approve {gate} --plan {digest} {sign}\",\n override: \"plywood override {gate} --rule {rule} --reason <text>\",\n op: OP_NAME,\n prGate: PR_GATE,\n gateName: \"wave-{k}\",\n approval: \"pull-request\",\n bin: BIN,\n notify: NOTIFY_WORDS,\n} satisfies ProductWordsInput);\n\n/**\n * The words for a pipeline that has jobs for `jobs` only. chant refuses a\n * comment command with no job to answer it, so `/plywood up` is left out\n * until a pipeline applies, and `/plywood lock` until it locks at preview.\n */\nexport function wordsForJobs(jobs: readonly ChantCommand[]): ProductWordsInput {\n const commands = Object.fromEntries(Object.entries(PRODUCT_WORDS.commands).filter(([, c]) => jobs.includes(c)));\n return { ...PRODUCT_WORDS, commands };\n}\n\n/**\n * Policy in plywood's words (plywood#13). chant's gate reads Rego rules\n * (`ci.policy`) and the CrossGuard packs each stack's preview runs, and\n * renders every finding under its stack in the note; these are the words\n * plywood prints around them.\n */\nexport const POLICY_OUTCOMES = {\n deny: \"denies the preview; it updates only under a plywood override\",\n hold: \"holds the preview for a person's approval, even where the gate would not ask\",\n advisory: \"is a note line under the stack and blocks nothing\",\n} as const;\n\n/** The rule id chant gives a CrossGuard policy (`crossGuardRule`, chant's pulumi lexicon), as `plywood override --rule` takes it. */\nexport function crossGuardRuleId(pack: string, policy: string): string {\n return `crossguard.${pack}.${policy}`;\n}\n\n/** How a denial's rule ids read, for the line after a denied preview or update. */\nexport const POLICY_RULE_FORMS = \"a CrossGuard rule is crossguard.<pack>.<policy>, a Rego rule <package>.<rule>\";\n\n/**\n * Identity in plywood's words (plywood#14): the two stages that hold one,\n * and what each may do. chant's `ci.identity` trades the forge's OIDC token\n * for them before the program is checked out.\n */\nexport const IDENTITY_STAGES = {\n preview: \"the preview job, which runs the pull request's program: read-only, and never the up identity\",\n up: \"the update job, which runs the merged program\",\n} as const;\n\n/** The clouds' names in plywood's lines. */\nexport const CLOUD_NAMES = { aws: \"AWS\", gcp: \"GCP\", azure: \"Azure\", pulumi: \"Pulumi Cloud\" } as const;\n\n/** What a stack with no identity for a cloud runs as, for `plywood config identities`. */\nexport const NO_IDENTITY = \"the job's own credentials (no OIDC trade)\";\n\n/**\n * The stack operations' words (plywood#16). They are commands beside the\n * ruled verbs, listed under their own heading in --help. Each is a gated request on the\n * workspace ledger, run by chant's pulumi lexicon once a second person\n * approves it (src/stack-ops.ts).\n */\nexport const STACK_OP_WORDS = {\n usage: {\n export: `${PRODUCT} export <project/stack> --out <file>`,\n cancel: `${PRODUCT} cancel <project/stack> [--lock <id>]`,\n move: `${PRODUCT} move <urn>... --from <project/stack> --to <project/stack>, or ${PRODUCT} move <project/stack> --onto plunge`,\n rollback: `${PRODUCT} rollback <project/stack> [--digest <sha256:...>], or ${PRODUCT} rollback --release <name> --env <env>`,\n },\n waiting: (verb: \"export\" | \"cancel\" | \"move\", approve: string): string =>\n `The ${verb} waits for a second person's approval, and your own does not count. They run '${approve}', then you run this command again to carry it out.`,\n spent: (verb: \"export\" | \"cancel\" | \"move\"): string =>\n `This ${verb} ran once already under its approval, and a request runs once. Run the command again to ask for a new one.`,\n exported: (stack: string, r: { file: string; sha256: string; bytes: number; resources: number }): string =>\n `Exported ${stack} to ${r.file} (${r.resources} resources, ${r.bytes} bytes, sha256 ${r.sha256}). The file is readable by you alone; the ledger keeps its digest and size, never its content.`,\n cancelled: (stack: string, lock: string, checked: boolean): string =>\n `Released lock ${lock} on ${stack}.${checked ? \"\" : \" The backend's lock could not be read, so it was not checked against the approved one first.\"}`,\n moved: (from: string, to: string, r: { engine: string; moved: string[] }): string =>\n `Moved ${r.moved.length} resource${r.moved.length === 1 ? \"\" : \"s\"} from ${from} to ${to} on ${r.engine}. Both stacks preview no change.`,\n needsLock:\n \"cancel needs --lock <id>, the lock the stack holds: the id pulumi printed when it refused the update, or the file name under .pulumi/locks/ on a file:// backend\",\n lockNotListed: (backend: string | undefined): string =>\n `cancel needs --lock <id> here: chant reads a stack's lock from a file:// backend only, and this stack's backend is ${backend ?? \"not one plywood can find\"}. Use the id pulumi printed when it refused the update`,\n noLock: (stack: string): string => `${stack} holds no lock now, so there is nothing to cancel`,\n manyLocks: (stack: string, ids: readonly string[]): string =>\n `${stack} holds ${ids.length} locks (${ids.join(\", \")}); name the one to release with --lock <id>`,\n noAdoptOp: (file: string): string =>\n `no ${file}. '${PRODUCT} init --engine plunge' writes it with each stack's adopt preview; run that first.`,\n adoptAll: (stack: string): string =>\n `${PRODUCT} move --onto plunge runs the adopt Op over every stack it lists, ${stack} among them. Each stack waits at its own gate.`,\n adoptWaiting: `Each stack's adoption waits for an approval of its preview's digest. Approve it with the line chant printed (${PRODUCT} approve <gate> --op plywood-adopt --plan <digest>), then run this command again.`,\n rollbackWaiting: `The rollback's preview waits at the release gate. Approve its digest with the line chant printed, then run this command again.`,\n releaseIsEnvWide: (stack: string, env: string): string =>\n `--release rolls back every stack the release records in an environment, so it takes --env, not a stack. Run '${PRODUCT} rollback --release <name> --env ${env}', or '${PRODUCT} rollback ${stack}' for this stack's previous release.`,\n} as const;\n\n/**\n * Drift in plywood's words (plywood#8). chant reads each stack's drift\n * (`chant workspace drift`) and keeps one tracking issue per stack through\n * its forge client (`trackIssue`); these are the issue's marker, title and\n * body, and the name of each stack's scheduled drift Op.\n */\nexport const DRIFT_OP_PREFIX = \"plywood-drift-\";\n\n/** The scheduled Op that reads `stack`'s drift: `plywood-drift-<project>-<stack>`, kebab-case. */\nexport function driftOpName(stack: string): string {\n return DRIFT_OP_PREFIX + stack.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\");\n}\n\n/** The hidden first line that finds a stack's drift issue again. */\nexport function driftIssueMarker(stack: string): string {\n return `<!-- plywood:drift ${stack} -->`;\n}\n\nexport function driftIssueTitle(stack: string): string {\n return `plywood: ${stack} has drifted`;\n}\n\n/** One drifted or missing resource, as the issue lists it. */\nexport interface DriftRow {\n urn: string;\n status: string;\n attributes: string[];\n}\n\n/** A cell that keeps the table's shape. */\nfunction cell(s: string): string {\n return s.replace(/\\|/g, \"\\\\|\").replace(/\\n/g, \" \");\n}\n\n/**\n * The issue's body. `fingerprint` names the finding, so a run that finds the\n * same drift leaves the issue as it is (`sameWhen`).\n */\nexport function driftIssueBody(input: { stack: string; rows: readonly DriftRow[]; observedAt: string; fingerprint: string; runUrl?: string; respond?: string; attribution?: readonly string[] }): string {\n const { stack, rows } = input;\n const lines = [\n driftIssueMarker(stack),\n `plywood's drift check read ${stack} against the cloud at ${input.observedAt} and found ${rows.length} resource${rows.length === 1 ? \"\" : \"s\"} that differ from the stack's state.`,\n \"\",\n \"| URN | Status | Attributes |\",\n \"|---|---|---|\",\n ...rows.map((r) => `| \\`${cell(r.urn)}\\` | ${r.status} | ${r.attributes.length ? r.attributes.map((a) => `\\`${cell(a)}\\``).join(\", \") : \"\"} |`),\n \"\",\n ...(input.attribution?.length ? [\"Who changed each attribute, from the known writes and the audit log:\", \"\", ...input.attribution, \"\"] : []),\n `To put the cloud back to the program, merge a change to ${stack} or run \\`${PRODUCT} up\\`. To keep the cloud's values, change the program to match and let its preview show no changes.`,\n ...(input.respond === \"up\" ? [\"\", `respond.drift is up, so this run also asked for an update of ${stack}'s wave; its gate decides.`] : []),\n ...(input.runUrl ? [\"\", `Read by ${input.runUrl}.`] : []),\n \"\",\n `<!-- plywood:drift-fingerprint ${input.fingerprint} -->`,\n ];\n return lines.join(\"\\n\");\n}\n\n/** Posted on the issue when a clean run closes it. */\nexport function driftClearedComment(stack: string, observedAt: string): string {\n return `plywood's drift check at ${observedAt} found ${stack} matching its state, so this issue is closed.`;\n}\n\n/**\n * The engines in plywood's words (plywood#17): what each does at each stage,\n * as `plywood config check` and the site's engine table say it. chant's\n * pulumi lexicon does all of it; these are the sentences.\n */\nexport const ENGINE_WORDS = {\n pulumi: {\n lock: \"the backend's stack lock orders updates to a stack, so plywood locks per stack\",\n up: \"up previews again and checks the fresh preview against the approved one\",\n moved: \"a preview that moved since its approval is refused with chant's moved code\",\n progress: \"each stack's span in the up job's trace\",\n },\n plunge: {\n lock: \"no stack lock: each record write is conditional, so plywood locks per resource and two updates to different resources of one stack run side by side\",\n up: \"up applies the preview job's saved plan, stamped with the version of each record it read\",\n moved: \"a saved plan whose records moved is refused with chant's moved code, the same code as a stock stack's moved preview\",\n progress: \"a span per resource in the up job's trace and run record, with its provider and record times\",\n },\n} as const;\n\n/** The lock grain in plywood's words, for `plywood config check`. */\nexport const LOCK_GRAIN_WORDS = {\n perEngine: (engine: \"pulumi\" | \"plunge\" | undefined): string =>\n engine === \"plunge\"\n ? \"resource, plunge's default (no ci.lockGrain; chant's pulumi lexicon sets it)\"\n : engine === \"pulumi\"\n ? \"stack, stock Pulumi's default (no ci.lockGrain; chant's pulumi lexicon sets it)\"\n : \"per engine: resource on plunge, stack on stock Pulumi (no ci.lockGrain; chant's pulumi lexicon sets it)\",\n} as const;\n\n/**\n * The span attributes chant writes for a plunge update's timings\n * (chant#4579, `plungeTimingTotals` and `plungeTimingSpans`), under\n * plywood's prefix. The dashboard preset reads them.\n */\nexport const PLUNGE_TIMING_ATTRIBUTES = {\n resources: `${PRODUCT}.plunge.resources`,\n calls: `${PRODUCT}.plunge.calls`,\n providerMs: `${PRODUCT}.plunge.provider_ms`,\n recordMs: `${PRODUCT}.plunge.record_ms`,\n failedCalls: `${PRODUCT}.plunge.failed_calls`,\n slowestUrn: `${PRODUCT}.plunge.slowest.urn`,\n slowestMs: `${PRODUCT}.plunge.slowest.ms`,\n} as const;\n", "/**\n * `control`: the control repo this repository answers to (plywood#18, on\n * chant#4568). After an update on merge, the workflow tells the control repo\n * which stack applied, and the control repo runs the repositories that\n * depend on it. The approvers and pins the control repo sets for each\n * repository are entries on its ledger (src/control.ts), never keys here.\n *\n * control: github.com/acme/infra-control\n *\n * or the mapping, each key chant's `ControlSettingsInput` in snake_case:\n *\n * control:\n * repo: github.com/acme/infra-control project key or https URL\n * op: pulumi-up the Op run on the dependents\n * member: shop this repo's name there\n * forge: github when the host does not say\n * token_secret: CHANT_CONTROL_TOKEN\n * read_token_secret: CHANT_CONTROL_READ_TOKEN\n * ref: main\n * api_base: http://127.0.0.1:3000/api/v1\n *\n * The checks here are the shape; chant's `controlSettingsProblems` checks\n * the rest when `plywood ci` resolves the target.\n */\nimport type { ChantControlSettings } from \"../chant-config\";\nimport { OP_NAME } from \"../words\";\nimport { error, isObject, oneOf, onlyKeys, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\n/** plywood.yml's `control` keys, to chant's `ControlSettingsInput` names. */\nexport const CONTROL_KEYS = {\n repo: \"repo\",\n op: \"op\",\n member: \"member\",\n forge: \"forge\",\n token_secret: \"tokenSecret\",\n read_token_secret: \"readTokenSecret\",\n ref: \"ref\",\n api_base: \"apiBase\",\n} as const satisfies Record<string, keyof ChantControlSettings>;\n\nconst CONTROL_FORGES = [\"github\", \"gitlab\", \"forgejo\"] as const;\n\n/** A repo as the project key chant takes: `https://github.com/acme/x.git` becomes `github.com/acme/x`. */\nexport function controlRepoKey(repo: string): string {\n return repo\n .trim()\n .replace(/^[a-z]+:\\/\\//i, \"\")\n .replace(/^[^@/]+@/, \"\")\n .replace(/^([^/:]+):(?!\\d)/, \"$1/\")\n .replace(/\\.git$/, \"\")\n .replace(/\\/+$/, \"\");\n}\n\n/** `control` as chant's settings, or undefined when plywood.yml has none. */\nexport function controlOf(doc: RawConfig): ChantControlSettings | undefined {\n const c = doc.control;\n if (typeof c === \"string\") return { repo: controlRepoKey(c), op: OP_NAME };\n if (!isObject(c) || typeof c.repo !== \"string\") return undefined;\n const out: Record<string, unknown> = { repo: controlRepoKey(c.repo), op: typeof c.op === \"string\" ? c.op : OP_NAME };\n for (const [key, chant] of Object.entries(CONTROL_KEYS)) {\n if (key === \"repo\" || key === \"op\") continue;\n if (typeof c[key] === \"string\") out[chant] = c[key];\n }\n return out as unknown as ChantControlSettings;\n}\n\nexport const control: ConfigGroup = {\n name: \"control\",\n keys: [\"control\"],\n schema: {\n control: {\n description: \"The control repo this repository tells after each update on merge: its project key or URL, or a mapping.\",\n oneOf: [\n { type: \"string\" },\n {\n type: \"object\",\n additionalProperties: false,\n required: [\"repo\"],\n properties: {\n repo: { type: \"string\", description: \"The control repo, as host/owner/name or its https URL.\" },\n op: { type: \"string\", description: `The Op the control repo runs on this repository's dependents. Default ${OP_NAME}.` },\n member: { type: \"string\", description: \"This repository's name in the control repo's workspace. Default the repository's name.\" },\n forge: { type: \"string\", enum: [...CONTROL_FORGES], description: \"The control repo's forge, when its host does not say.\" },\n token_secret: { type: \"string\", description: \"The secret holding the dispatch token. Default CHANT_CONTROL_TOKEN.\" },\n read_token_secret: { type: \"string\", description: \"The secret holding a read-only token for the control repo. Default CHANT_CONTROL_READ_TOKEN.\" },\n ref: { type: \"string\", description: \"The branch a GitLab or Forgejo dispatch runs on. Default main.\" },\n api_base: { type: \"string\", description: \"The forge's REST base, when the host's usual one is not it.\" },\n },\n },\n ],\n },\n },\n check(doc) {\n const c = doc.control;\n if (c === undefined) return [];\n if (typeof c === \"string\") return controlRepoKey(c).split(\"/\").length >= 3 ? [] : [error(\"control\", `${c} names no host/owner/name`)];\n if (!isObject(c)) return [error(\"control\", \"must be the control repo's project key, or a mapping with repo\")];\n const out: ConfigProblem[] = [...onlyKeys(c, Object.keys(CONTROL_KEYS), \"control\")];\n if (typeof c.repo !== \"string\") out.push(error(\"control.repo\", \"must name the control repo, such as github.com/acme/infra-control\"));\n else if (controlRepoKey(c.repo).split(\"/\").length < 3) out.push(error(\"control.repo\", `${c.repo} names no host/owner/name`));\n for (const key of Object.keys(CONTROL_KEYS)) {\n if (key !== \"repo\" && c[key] !== undefined && typeof c[key] !== \"string\") out.push(error(`control.${key}`, \"must be a string\"));\n }\n out.push(...oneOf(c.forge, CONTROL_FORGES, \"control.forge\"));\n if (typeof c.token_secret === \"string\" && c.token_secret === c.read_token_secret) {\n out.push(error(\"control.read_token_secret\", \"must not be the dispatch token's secret: the preview job runs the change's code\"));\n }\n return out;\n },\n translate(doc, out) {\n const c = controlOf(doc);\n if (c) out.pipeline.control = c;\n },\n};\n", "{\n \"name\": \"@intentius/plywood\",\n \"version\": \"0.0.0\",\n \"description\": \"CI Automation for Pulumi\",\n \"license\": \"Apache-2.0\",\n \"type\": \"module\",\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git+https://github.com/INTENTIUS/plywood.git\",\n \"directory\": \"packages/plywood\"\n },\n \"homepage\": \"https://intentius.io/plywood/\",\n \"bin\": {\n \"plywood\": \"dist/plywood.mjs\"\n },\n \"files\": [\n \"dist\",\n \"plywood.schema.json\",\n \"templates\",\n \"presets\",\n \"LICENSE\"\n ],\n \"engines\": {\n \"node\": \">=22\"\n },\n \"publishConfig\": {\n \"access\": \"public\"\n },\n \"scripts\": {\n \"build\": \"node scripts/build-cli.mjs\",\n \"schema\": \"node scripts/build-schema.mjs\",\n \"images\": \"node scripts/build-images.mjs\",\n \"bundle-check\": \"node scripts/build-schema.mjs --check && node scripts/build-images.mjs --check && node scripts/bundle-check.mjs\",\n \"prepack\": \"node scripts/build-cli.mjs\"\n },\n \"dependencies\": {\n \"@intentius/chant\": \"0.124.55\",\n \"@intentius/chant-lexicon-pulumi\": \"0.124.55\"\n },\n \"devDependencies\": {\n \"@intentius/chant-lexicon-forgejo\": \"0.124.55\",\n \"@intentius/chant-lexicon-github\": \"0.124.55\",\n \"@intentius/chant-lexicon-gitlab\": \"0.124.55\"\n }\n}\n", "{}\n", "/**\n * Engine pins, verified installs and the CI images (plywood#12).\n *\n * plywood pins one stock Pulumi release and one plunge release. The two\n * images, `plywood-pulumi` and `plywood-plunge`, each carry one engine at its\n * pin plus the plywood bundle; scripts/build-images.mjs renders their\n * Dockerfiles from this module into images/<name>/Dockerfile. A job runs in\n * the image for its engine, by digest once the image is published\n * (image-digests.json), and runs the install lines for any pin the image\n * does not carry: a `pulumi:` or `plunge:` version in plywood.yml, per stack\n * glob.\n *\n * Every install checks the release's own checksums file (plunge's\n * `plunge-v<ver>-checksums.txt`, Pulumi's `pulumi-<ver>-checksums.txt`), and\n * for the pinned releases also that the file lists the sha256 plywood\n * recorded, so a tampered checksums file fails the install as a tampered\n * archive does.\n *\n * Each engine lives in /opt/plywood/<engine>-<version>/ with its language\n * hosts beside it, the default one linked into /usr/local/bin. An install\n * line skips when that directory already holds the binary, so a job in\n * plywood's image, or in an image built FROM it, installs nothing.\n *\n * chant's pulumi lexicon renders the same verified lines\n * (`@intentius/chant-lexicon-pulumi/ci-setup`, chant#4592):\n * `pulumiInstallLine` and `plungeInstallLine` take the version, the root and\n * the recorded sums. Once {@link useChantInstallLines} finds them in the\n * installed lexicon, the line for each engine's linked release is chant's,\n * given the root /opt/plywood and plywood's sums, so plywood's images still\n * skip the download. A pin that is not linked keeps plywood's line: chant's\n * always links onto PATH, and its Pulumi line skips when the `pulumi` on PATH\n * is that version without checking the versioned directory, which a step\n * pinned with `engineVersion` runs from. The lexicon at plywood's pin\n * (0.124.54) has no ci-setup, and every line is plywood's.\n *\n * plywood hands the lines to chant's `prLoop.engineSetup` when the installed\n * chant reads that option and the job runs in chant's default image\n * ({@link chantPipelineOptions}). A stack pinned to a release that is not\n * linked gets `engineVersion` and `engineRoot` on its `pulumi-up` step\n * (src/config/images.ts, src/init/render.ts `stepInput`), and the step runs\n * `<root>/<engine>-<version>/<engine>`.\n */\n// A named import, so the bundle carries the version and not the whole package.json.\nimport { version as PLYWOOD_VERSION } from \"../package.json\";\nimport digests from \"./image-digests.json\" with { type: \"json\" };\nimport type { ChantRunner } from \"./chant-config\";\n\nexport type EngineName = \"pulumi\" | \"plunge\";\n\nexport const REGISTRY = \"ghcr.io/intentius\";\n\n/**\n * The engine releases the images carry, and the version a job installs when\n * plywood.yml pins none. Pulumi matches the plunge corpus (3.272.0), which\n * plunge 0.1.0 is built from.\n */\nexport const TOOL_VERSIONS: Readonly<Record<EngineName, string>> = {\n pulumi: \"3.272.0\",\n /** A plunge release (INTENTIUS/plunge, tag plunge-v<ver>), not the Pulumi version it is built from. */\n plunge: \"0.1.0\",\n};\n\n/** The archive's architecture word, as both projects name their Linux builds. */\nexport type Arch = \"x64\" | \"arm64\";\nexport const ARCHES: readonly Arch[] = [\"x64\", \"arm64\"];\n\n/**\n * The sha256 of each pinned Linux archive, copied from the release's\n * checksums file. A checksums file that lists another sum for one of these\n * fails the install.\n */\nexport const PINNED_SHA256: Readonly<Record<string, string>> = {\n \"pulumi-v3.272.0-linux-x64.tar.gz\": \"58d545f2b98761051922008ebd381ecef95484d7f7a5ff7faa15d7a780ea84f6\",\n \"pulumi-v3.272.0-linux-arm64.tar.gz\": \"4f0741901b8982c4326b702dabf483c63d2cf77c88ac42dd752b72541284a534\",\n \"plunge-v0.1.0-linux-x64.tar.gz\": \"22b89da39ab7dc11268c7b625fec3d99c0793c9c47bf8d031fa94e6967ee8187\",\n \"plunge-v0.1.0-linux-arm64.tar.gz\": \"6855611b8cf8381d73f5ddf0b5c0a0d83bdc2a5bd8c50d415e52bb05a4574f83\",\n};\n\n/** Where plywood's images and install lines keep each release: the `engineRoot` a pinned step names. */\nexport const ENGINE_ROOT = \"/opt/plywood\";\n\n/** Where one release of one engine lives, in the images and after an install line. */\nexport function engineDir(engine: EngineName, version: string): string {\n return `${ENGINE_ROOT}/${engine}-${version}`;\n}\n\n/** The engine's binary at `version`. */\nexport function engineBin(engine: EngineName, version: string): string {\n return `${engineDir(engine, version)}/${engine}`;\n}\n\n/** One release's download: the base URL, the archive per architecture, and its checksums file. */\nexport interface Release {\n base: string;\n archive(arch: Arch): string;\n checksums: string;\n}\n\nexport function release(engine: EngineName, version: string): Release {\n if (engine === \"pulumi\") {\n return {\n base: `https://github.com/pulumi/pulumi/releases/download/v${version}`,\n archive: (arch) => `pulumi-v${version}-linux-${arch}.tar.gz`,\n checksums: `pulumi-${version}-checksums.txt`,\n };\n }\n return {\n base: `https://github.com/INTENTIUS/plunge/releases/download/plunge-v${version}`,\n archive: (arch) => `plunge-v${version}-linux-${arch}.tar.gz`,\n checksums: `plunge-v${version}-checksums.txt`,\n };\n}\n\n/** The pinned sums for `version`, by architecture, when plywood recorded them. */\nexport function pinnedSums(engine: EngineName, version: string): Partial<Record<Arch, string>> {\n const r = release(engine, version);\n const out: Partial<Record<Arch, string>> = {};\n for (const arch of ARCHES) {\n const sum = PINNED_SHA256[r.archive(arch)];\n if (sum) out[arch] = sum;\n }\n return out;\n}\n\n/**\n * Shell that downloads one engine release into `dir` and checks it: the\n * archive's line in the release's checksums file must match the archive\n * (sha256sum -c), and for a pinned release the line must hold plywood's sum.\n * `arch` is a shell expression giving x64 or arm64; `checksumsUrl` a shell\n * word for the checksums file's URL. Both archives unpack a top directory\n * named after the engine, which `--strip-components=1` drops.\n */\nfunction fetchScript(engine: EngineName, version: string, dir: string, arch: string, checksumsUrl?: string): string {\n const r = release(engine, version);\n const sums = pinnedSums(engine, version);\n const pinCase = Object.keys(sums).length\n ? `case \"$a\" in ${ARCHES.filter((x) => sums[x]).map((x) => `${x}) want=${sums[x]} ;;`).join(\" \")} *) want= ;; esac`\n : \"want=\";\n const file = `${r.archive(\"x64\").replace(\"-x64.\", \"-$a.\")}`;\n return [\n `a=${arch}`,\n `f=\"${file}\"`,\n `t=\"$(mktemp -d)\"`,\n `curl -fsSLo \"$t/$f\" \"${r.base}/$f\"`,\n `curl -fsSLo \"$t/sums\" ${checksumsUrl ?? `\"${r.base}/${r.checksums}\"`}`,\n // The archive's line, with any ./ or * before the name taken off.\n `line=\"$(sed -n \"s#^\\\\([0-9a-f]\\\\{64\\\\}\\\\) *[*.]*/*$f\\\\$#\\\\1#p\" \"$t/sums\")\"`,\n `{ [ -n \"$line\" ] || { echo \"${engine} ${version}: $f is not in ${r.checksums}\" >&2; exit 1; }; }`,\n pinCase,\n `{ [ -z \"$want\" ] || [ \"$line\" = \"$want\" ] || { echo \"${engine} ${version}: ${r.checksums} lists $line for $f; plywood pins $want\" >&2; exit 1; }; }`,\n `echo \"$line $t/$f\" | sha256sum -c - >/dev/null`,\n `mkdir -p \"${dir}\"`,\n `tar -xzf \"$t/$f\" -C \"${dir}\" --strip-components=1`,\n ].join(\" && \");\n}\n\n/** The machine's architecture as x64 or arm64, in a job. */\nconst JOB_ARCH = `\"$(uname -m | sed 's/x86_64/x64/;s/aarch64/arm64/')\"`;\n\n/**\n * The job line that installs `engine` at `version`, checked against the\n * release checksums. It skips when the binary is already in place, as in\n * plywood's image or one built FROM it. With `link`, the binary is also\n * linked into /usr/local/bin, as the stack's default engine.\n */\nexport function installLine(engine: EngineName, version: string, link = true): string {\n const chant = chantLines;\n if (link && chant) {\n const sums = pinnedSums(engine, version);\n const options = { root: ENGINE_ROOT, ...(Object.keys(sums).length ? { sha256: sums } : {}) };\n return engine === \"pulumi\" ? chant.pulumiInstallLine(version, options) : chant.plungeInstallLine(version, options);\n }\n return plywoodInstallLine(engine, version, link);\n}\n\n/** plywood's own line, used when the installed lexicon has no ci-setup and for a pin that is not linked. */\nexport function plywoodInstallLine(engine: EngineName, version: string, link = true): string {\n const dir = engineDir(engine, version);\n const linkCmd = `ln -sf \"${dir}/${engine}\" /usr/local/bin/${engine}`;\n const install = `(set -e; ${fetchScript(engine, version, dir, JOB_ARCH)})`;\n return link ? `{ [ -x \"${dir}/${engine}\" ] || ${install}; } && ${linkCmd}` : `[ -x \"${dir}/${engine}\" ] || ${install}`;\n}\n\n/** What plywood calls from `@intentius/chant-lexicon-pulumi/ci-setup` (chant#4592). */\nexport interface ChantInstallLines {\n pulumiInstallLine(version: string, options: { root?: string; sha256?: Partial<Record<Arch, string>> }): string;\n plungeInstallLine(version: string, options: { root?: string; sha256?: Partial<Record<Arch, string>> }): string;\n}\n\nlet chantLines: ChantInstallLines | undefined;\nlet loading: Promise<boolean> | undefined;\n\n/**\n * Loads chant's install lines when the installed pulumi lexicon has them\n * (`ciRelease`, `PINNED_SHA256` and both install lines on its ci-setup\n * subpath), so {@link installLine} uses them from then on. The config\n * translation is synchronous, so the CLI awaits this once before a command.\n * True when chant's lines are in use.\n */\nexport function useChantInstallLines(): Promise<boolean> {\n loading ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from the lexicon at 0.124.54 (chant#4592).\n const m: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi/ci-setup\");\n const ok =\n typeof m.ciRelease === \"function\" &&\n typeof m.PINNED_SHA256 === \"object\" &&\n typeof m.pulumiInstallLine === \"function\" &&\n typeof m.plungeInstallLine === \"function\";\n chantLines = ok ? (m as unknown as ChantInstallLines) : undefined;\n } catch {\n chantLines = undefined;\n }\n return chantLines !== undefined;\n })();\n return loading;\n}\n\n/** Tests stand in chant's lines (or none). `reset` forgets them and the import. */\nexport function setChantInstallLinesForTests(fake: ChantInstallLines | undefined | \"reset\"): void {\n chantLines = fake === \"reset\" ? undefined : fake;\n loading = fake === \"reset\" ? undefined : Promise.resolve(fake !== undefined);\n}\n\n/** One engine at one version a job needs, and whether it is the one on PATH. */\nexport interface EnginePin {\n engine: EngineName;\n version: string;\n /** Linked into /usr/local/bin: the version most stacks use. */\n linked: boolean;\n}\n\n/** The install lines for `pins`, the linked one of each engine last so it wins the link. */\nexport function installLines(pins: readonly EnginePin[]): string[] {\n const seen = new Set<string>();\n const ordered = [...pins.filter((p) => !p.linked), ...pins.filter((p) => p.linked)];\n const out: string[] = [];\n for (const p of ordered) {\n const k = `${p.engine}@${p.version}`;\n if (seen.has(k)) continue;\n seen.add(k);\n out.push(installLine(p.engine, p.version, p.linked));\n }\n return out;\n}\n\nexport interface ImageRef {\n repository: string;\n tag: string;\n /** The registry digest, known once the image is published. */\n digest?: string;\n}\n\n/** The image name for an engine. */\nexport function imageName(engine: EngineName): string {\n return `plywood-${engine}`;\n}\n\n/** The tag: plywood's version and the engine release it carries. */\nexport function imageTag(engine: EngineName, version = PLYWOOD_VERSION): string {\n return `${version}-${engine}${TOOL_VERSIONS[engine]}`;\n}\n\n/** The image a job for `engine` runs in. */\nexport function imageFor(engine: EngineName, table: Record<string, string> = digests as Record<string, string>): ImageRef {\n const repository = `${REGISTRY}/${imageName(engine)}`;\n const tag = imageTag(engine);\n const digest = table[`${repository}:${tag}`];\n return { repository, tag, ...(digest ? { digest } : {}) };\n}\n\n/** How a pipeline names the image: by digest when it is known, with the tag kept beside it. */\nexport function imageReference(ref: ImageRef): string {\n return ref.digest ? `${ref.repository}:${ref.tag}@${ref.digest}` : `${ref.repository}:${ref.tag}`;\n}\n\n/** A full image digest, as a pipeline pins one. */\nexport const DIGEST = /@sha256:[0-9a-f]{64}$/;\n\n// ---------------------------------------------------------------------------\n// The images' Dockerfiles, rendered by scripts/build-images.mjs.\n\n/**\n * Base images by index digest, so a rebuild cannot change underneath a tag:\n * the same two terragucci's images use. NODE carries Node 22, which a\n * TypeScript Pulumi program's language host runs on.\n */\nexport const BASE_IMAGES = {\n node: \"node:22-bookworm-slim@sha256:c3de60bf2f9dd0ac6370e6117950ff62d6e339527e7472301c9c78a017978392\",\n debian: \"debian:bookworm-slim@sha256:3783cc01769c7b2b1b83a5c5ad96c815348e28ed7da68e2e3687004faa906251\",\n} as const;\n\n/** Where the images keep Pulumi's home, so plugins a derived image installs serve every uid. */\nexport const IMAGE_PULUMI_HOME = \"/opt/plywood/pulumi-home\";\n\n/** Where npm pack leaves the package tarball the images install, from the repository root. */\nexport const PACK_DIR = \"images/pack\";\n\n/** The tarball name npm pack gives the package at this version. */\nexport function packName(version = PLYWOOD_VERSION): string {\n return `intentius-plywood-${version}.tgz`;\n}\n\n/**\n * One image's Dockerfile. The fetch stage downloads the engine and checks\n * it; the build argument `CHECKSUMS_URL` names another checksums file, which\n * is how a tampered one is shown to fail the build. curl never reaches the\n * final stage.\n */\nexport function dockerfile(engine: EngineName): string {\n const version = TOOL_VERSIONS[engine];\n const r = release(engine, version);\n const dir = engineDir(engine, version);\n const name = imageName(engine);\n const engineTitle = engine === \"pulumi\" ? `Pulumi ${version}` : `plunge ${version}`;\n return [\n `# Rendered from packages/plywood/src/images.ts by packages/plywood/scripts/build-images.mjs.`,\n `# Edit the module, then run npm run images -w @intentius/plywood. Build from the repository root`,\n `# after npm pack -w @intentius/plywood --pack-destination ${PACK_DIR} (just images); nothing pushes it.`,\n `FROM ${BASE_IMAGES.debian} AS fetch`,\n `ARG TARGETARCH`,\n `ARG CHECKSUMS_URL=${r.base}/${r.checksums}`,\n `RUN apt-get update && apt-get install -y --no-install-recommends ca-certificates curl && rm -rf /var/lib/apt/lists/*`,\n // Each case pattern opens with \"(\": bash 3.2 (macOS sh) cannot parse a bare \"arm64)\" inside $(...).\n `RUN set -e; ${fetchScript(engine, version, `/out${dir}`, `\"$(case \"$TARGETARCH\" in (arm64) echo arm64 ;; (*) echo x64 ;; esac)\"`, `\"$CHECKSUMS_URL\"`)}`,\n `FROM ${BASE_IMAGES.node}`,\n // A forge may run the job as a uid with no passwd entry; Go then reads $USER and $HOME.\n `ENV USER=plywood HOME=/tmp PULUMI_HOME=${IMAGE_PULUMI_HOME} PULUMI_SKIP_UPDATE_CHECK=true`,\n `RUN apt-get update && apt-get install -y --no-install-recommends git ca-certificates && rm -rf /var/lib/apt/lists/*`,\n // A job often runs as another user than the one who owns its checkout.\n `RUN git config --system --add safe.directory '*' && mkdir -p ${IMAGE_PULUMI_HOME} && chmod 1777 ${IMAGE_PULUMI_HOME}`,\n `COPY --from=fetch /out/opt/plywood/ /opt/plywood/`,\n `RUN ln -s ${dir}/${engine} /usr/local/bin/${engine} && ${engine} version`,\n // The bundle leaves @intentius/chant* external, so the image installs the packed package and npm\n // fetches its exact-pinned runtime dependencies. The tarball is made by npm pack (just images).\n `COPY ${PACK_DIR}/${packName()} /tmp/${packName()}`,\n `RUN npm install -g --omit=dev --no-audit --no-fund /tmp/${packName()} && rm -f /tmp/${packName()} && npm cache clean --force && plywood --version`,\n `LABEL org.opencontainers.image.title=\"${name}\"`,\n `LABEL org.opencontainers.image.description=\"${engineTitle} and the plywood CLI\"`,\n `LABEL org.opencontainers.image.version=\"${PLYWOOD_VERSION}\"`,\n `LABEL org.opencontainers.image.source=\"https://github.com/INTENTIUS/plywood\"`,\n `LABEL org.opencontainers.image.licenses=\"Apache-2.0\"`,\n `CMD [\"bash\"]`,\n \"\",\n ].join(\"\\n\");\n}\n\n/** Each image's Dockerfile, by its path from the repository root. */\nexport function dockerfiles(): Record<string, string> {\n return Object.fromEntries(([\"pulumi\", \"plunge\"] as const).map((e) => [`images/${imageName(e)}/Dockerfile`, dockerfile(e)]));\n}\n\n// ---------------------------------------------------------------------------\n// A user's prepared image: FROM plywood's, with plugins preinstalled.\n\n/** One plugin `image.plugins` names: `aws@7.4.0`, or `resource:aws@7.4.0`. */\nexport interface PluginPin {\n kind: string;\n name: string;\n version: string;\n}\n\nexport const PLUGIN_KINDS = [\"resource\", \"converter\", \"language\", \"analyzer\", \"tool\"] as const;\nexport const PLUGIN = /^(?:(resource|converter|language|analyzer|tool):)?([a-z0-9][a-z0-9-]*)@(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/;\n\nexport function parsePlugin(s: string): PluginPin | undefined {\n const m = PLUGIN.exec(s);\n return m ? { kind: m[1] ?? \"resource\", name: m[2]!, version: m[3]! } : undefined;\n}\n\n/**\n * The Dockerfile of a prepared image: FROM plywood's image for `engine`,\n * with each plugin installed into the image's Pulumi home, so the job's\n * engine finds them without a download. The user builds and pushes it in\n * their own CI and names it in `image`.\n */\nexport function imageRecipe(engine: EngineName, plugins: readonly PluginPin[], from: ImageRef = imageFor(engine)): string {\n return [\n `# A prepared image for plywood's jobs: ${engine} and the plugins below, so a job downloads none.`,\n `# Build and push it in your own CI, then name it by digest in plywood.yml's image.`,\n `FROM ${imageReference(from)}`,\n ...plugins.map((p) => `RUN ${engine} plugin install ${p.kind} ${p.name} ${p.version}`),\n `RUN chmod -R a+rX ${IMAGE_PULUMI_HOME}`,\n \"\",\n ].join(\"\\n\");\n}\n\n// ---------------------------------------------------------------------------\n// Handing the image and the lines to chant.\n\n/** The subset of chant's pipeline options the image and setup lines fill. */\nexport interface ChantEngineOptions {\n /** `ComponentPipelineOptions.image`. Absent: chant's default image. */\n image?: string;\n /** `ComponentPipelineOptions.beforeScript`: lines every job runs first, in any image. */\n beforeScript?: string[];\n /** `PrLoopPipelineOptions.engineSetup` (chant#4550): run in chant's default image in place of its OpenTofu install. */\n prLoop?: { engineSetup: string[] };\n /** `runners`, as plywood.yml gives it; the waves spec takes the `up` stage's (src/init/render.ts `waveRunner`). */\n runner?: ChantRunner;\n}\n\n/**\n * chant's build line for the image and the lines (`chant build --image`,\n * `--before-script`), for a pipeline generated over argv. The build takes\n * no product engine lines over argv, so they go to `--before-script` there.\n */\nexport function chantBuildFlags(o: ChantEngineOptions): string[] {\n const lines = [...(o.beforeScript ?? []), ...(o.prLoop?.engineSetup ?? [])];\n return [...(o.image ? [\"--image\", o.image] : []), ...lines.flatMap((l) => [\"--before-script\", l])];\n}\n\n/**\n * The options chant's pipeline takes for plywood's image and lines. In\n * chant's default image, with a chant that reads `engineSetup`, the lines\n * replace chant's OpenTofu install; otherwise every job runs them first,\n * where each skips the engines the image already carries.\n */\nexport function chantPipelineOptions(p: { image?: string; engineSetup?: string[]; runner?: ChantRunner }, chantReadsEngineSetup: boolean): ChantEngineOptions {\n const lines = p.engineSetup ?? [];\n const out: ChantEngineOptions = { ...(p.image ? { image: p.image } : {}), ...(p.runner !== undefined ? { runner: p.runner } : {}) };\n if (lines.length === 0) return out;\n if (!p.image && chantReadsEngineSetup) out.prLoop = { engineSetup: [...lines] };\n else out.beforeScript = [...lines];\n return out;\n}\n\nlet hook: Promise<boolean> | undefined;\n\n/**\n * Whether the installed chant takes a product's engine lines: chant#4550's\n * `@intentius/chant/ci-product` with `prLoopSetup`. chant 0.124.54 has\n * neither; scripts/build-cli.mjs stands in a module that throws for the\n * missing subpath, and the answer is false.\n */\nexport function chantReadsEngineSetup(): Promise<boolean> {\n hook ??= (async () => {\n try {\n // @ts-ignore the pinned chant has no such subpath yet\n const m: Record<string, unknown> = await import(\"@intentius/chant/ci-product\");\n return typeof m.prLoopSetup === \"function\" && typeof m.engineSetupLines === \"function\";\n } catch {\n return false;\n }\n })();\n return hook;\n}\n", "/**\n * `pulumi`, `plunge`, `image` and `runners`: the engine release each stack\n * runs, the image every job runs in, and the runners the jobs land on\n * (plywood#12).\n *\n * pulumi a version, or stack glob to version member engineVersion, pipeline engineSetup\n * plunge the same, for plunge stacks member engineVersion, pipeline engineSetup\n * image a reference, or { name, plugins } pipeline image\n * runners a label, labels, a GitHub group, or pipeline runner\n * default/preview/up/drift to one of those\n *\n * Each stack's engine comes from the engine group, which runs first; a stack\n * with none set installs Pulumi, the engine chant picks without a plunge\n * backend. The version most stacks of an engine run is linked onto PATH; a\n * stack pinned to another gets its binary's path as `engineBin`, and\n * `engineVersion` with `engineRoot` for its pulumi-up step (chant#4592). The\n * install lines are src/images.ts's (chant's when the installed lexicon has\n * them) and check the release checksums.\n */\nimport { DIGEST, ENGINE_ROOT, imageFor, imageReference, installLines, engineBin, parsePlugin, PLUGIN, TOOL_VERSIONS, type EngineName, type EnginePin } from \"../images\";\nimport type { ChantRunner } from \"../chant-config\";\nimport { error, isObject, onlyKeys, warning, type ConfigGroup, type ConfigProblem, type JsonSchema, type RawConfig } from \"./types\";\n\nconst VERSION = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/;\nconst LABEL = /^[^\\s,]+$/;\nexport const RUNNER_STAGES = [\"default\", \"preview\", \"up\", \"drift\"] as const;\nexport const IMAGE_KEYS = [\"name\", \"plugins\"] as const;\n\nconst versionSchema = (engine: string, example: string): JsonSchema => ({\n description: `The ${engine} release the jobs run, such as ${example}: one for every stack, or a map of stack glob to release. plywood's image's release when absent.`,\n anyOf: [\n { type: \"string\", pattern: VERSION.source },\n { type: \"object\", minProperties: 1, additionalProperties: { type: \"string\", pattern: VERSION.source } },\n ],\n});\n\nconst runnerSpecSchema: JsonSchema = {\n anyOf: [\n { type: \"string\", pattern: LABEL.source },\n { type: \"array\", items: { type: \"string\", pattern: LABEL.source }, minItems: 1, uniqueItems: true },\n {\n type: \"object\",\n additionalProperties: false,\n required: [\"group\"],\n properties: { group: { type: \"string\", minLength: 1 }, labels: { type: \"array\", items: { type: \"string\", pattern: LABEL.source }, minItems: 1, uniqueItems: true } },\n },\n ],\n};\n\n/** `*` matches any run of characters, `/` included. */\nexport function globMatches(glob: string, name: string): boolean {\n const re = new RegExp(`^${glob.split(\"*\").map((p) => p.replace(/[.+?^${}()|[\\]\\\\]/g, \"\\\\$&\")).join(\".*\")}$`);\n return re.test(name);\n}\n\n/** The release `pin` gives `stack`, or undefined when a map names no glob that matches it. */\nexport function pinFor(pin: unknown, stack: string | undefined): string | undefined {\n if (typeof pin === \"string\") return pin;\n if (!isObject(pin)) return undefined;\n if (stack !== undefined) {\n if (typeof pin[stack] === \"string\") return pin[stack] as string;\n for (const [glob, v] of Object.entries(pin)) if (typeof v === \"string\" && globMatches(glob, stack)) return v;\n }\n return typeof pin[\"*\"] === \"string\" ? (pin[\"*\"] as string) : undefined;\n}\n\nfunction versionProblems(v: unknown, key: string): ConfigProblem[] {\n if (v === undefined) return [];\n if (typeof v === \"string\") return VERSION.test(v) ? [] : [error(key, `is ${JSON.stringify(v)}; give a release such as ${key === \"plunge\" ? TOOL_VERSIONS.plunge : TOOL_VERSIONS.pulumi}`)];\n if (!isObject(v) || Object.keys(v).length === 0) return [error(key, \"must be a release, or a map of stack glob to release\")];\n return Object.entries(v)\n .filter(([, r]) => typeof r !== \"string\" || !VERSION.test(r))\n .map(([g]) => error(`${key}.${g}`, \"must be a release such as 1.2.3\"));\n}\n\nfunction runnerSpecProblems(v: unknown, key: string, forge: unknown): ConfigProblem[] {\n const label = (x: unknown): boolean => typeof x === \"string\" && LABEL.test(x);\n const labels = (x: unknown): boolean => Array.isArray(x) && x.length > 0 && x.every(label) && new Set(x).size === x.length;\n if (typeof v === \"string\") return label(v) ? [] : [error(key, \"must be a runner label, such as self-hosted, with no spaces or commas\")];\n if (Array.isArray(v)) return labels(v) ? [] : [error(key, \"must be a list of distinct runner labels, such as [self-hosted, linux]\")];\n if (!isObject(v) || !(\"group\" in v)) return [error(key, \"must be a runner label, a list of labels, or a map with group\")];\n const out = onlyKeys(v, [\"group\", \"labels\"], key);\n if (typeof v.group !== \"string\" || v.group.trim() === \"\") out.push(error(`${key}.group`, \"must name a GitHub runner group\"));\n if (v.labels !== undefined && !labels(v.labels)) out.push(error(`${key}.labels`, \"must be a list of distinct runner labels\"));\n if (forge !== undefined && forge !== \"github\") out.push(error(`${key}.group`, `runner groups are GitHub's; on ${String(forge)} give a label or a list of labels`));\n return out;\n}\n\n/** Whether `runners` maps stages to runners, rather than naming one runner. */\nfunction byStage(v: unknown): v is Record<string, unknown> {\n return isObject(v) && !(\"group\" in v);\n}\n\nfunction runnersProblems(v: unknown, forge: unknown): ConfigProblem[] {\n if (v === undefined) return [];\n if (!byStage(v)) return runnerSpecProblems(v, \"runners\", forge);\n if (Object.keys(v).length === 0) return [error(\"runners\", `must name a runner, or map ${RUNNER_STAGES.join(\", \")} to one`)];\n return Object.entries(v).flatMap(([k, spec]) =>\n (RUNNER_STAGES as readonly string[]).includes(k) ? runnerSpecProblems(spec, `runners.${k}`, forge) : [error(`runners.${k}`, `is not a stage; the stages are ${RUNNER_STAGES.join(\", \")}`)],\n );\n}\n\nfunction imageProblems(v: unknown): ConfigProblem[] {\n if (v === undefined) return [];\n const unpinned = (name: string): ConfigProblem[] =>\n DIGEST.test(name) ? [] : [warning(\"image\", `${name} is not pinned by digest, so a push to its tag changes what the jobs run; name it as <image>@sha256:<digest>`)];\n if (typeof v === \"string\") return v.trim() === \"\" ? [error(\"image\", \"must be an image reference\")] : unpinned(v);\n if (!isObject(v)) return [error(\"image\", `must be an image reference, or a map of ${IMAGE_KEYS.join(\", \")}`)];\n const out = onlyKeys(v, IMAGE_KEYS, \"image\");\n if (v.name !== undefined && (typeof v.name !== \"string\" || v.name.trim() === \"\")) out.push(error(\"image.name\", \"must be an image reference\"));\n else if (typeof v.name === \"string\") out.push(...unpinned(v.name));\n if (v.plugins !== undefined) {\n if (!Array.isArray(v.plugins)) out.push(error(\"image.plugins\", \"must be a list of plugins such as aws@7.4.0\"));\n else v.plugins.forEach((p, i) => {\n if (typeof p !== \"string\" || !parsePlugin(p)) out.push(error(`image.plugins[${i}]`, `is ${JSON.stringify(p)}; give name@version, or kind:name@version`));\n });\n if (v.name === undefined) out.push(warning(\"image.plugins\", \"lists plugins with no image.name, so the jobs keep plywood's image; build the prepared image and name it in image.name\"));\n }\n return out;\n}\n\n/** The image reference `image` names, in either form. */\nexport function userImage(doc: RawConfig): string | undefined {\n if (typeof doc.image === \"string\") return doc.image;\n return isObject(doc.image) && typeof doc.image.name === \"string\" ? doc.image.name : undefined;\n}\n\n/** The plugins `image.plugins` lists, parsed. */\nexport function imagePlugins(doc: RawConfig) {\n const list = isObject(doc.image) && Array.isArray(doc.image.plugins) ? (doc.image.plugins as unknown[]) : [];\n return list.flatMap((p) => (typeof p === \"string\" && parsePlugin(p) ? [parsePlugin(p)!] : []));\n}\n\n/** The release of `engine` most of `stacks` run: the linked one. Ties go to the top-level pin, then plywood's. */\nfunction linkedVersion(engine: EngineName, doc: RawConfig, versions: string[]): string {\n const top = pinFor(doc[engine], undefined) ?? TOOL_VERSIONS[engine];\n if (versions.length === 0) return top;\n const count = new Map<string, number>();\n for (const v of versions) count.set(v, (count.get(v) ?? 0) + 1);\n const best = Math.max(...count.values());\n return count.get(top) === best ? top : [...count].find(([, n]) => n === best)![0];\n}\n\nexport const images: ConfigGroup = {\n name: \"images\",\n keys: [\"pulumi\", \"plunge\", \"image\", \"runners\"],\n schema: {\n pulumi: versionSchema(\"Pulumi CLI\", TOOL_VERSIONS.pulumi),\n plunge: versionSchema(\"plunge\", TOOL_VERSIONS.plunge),\n image: {\n description: \"The image every job runs in, in place of plywood's: a reference pinned by digest, or a map with name and the plugins a prepared image carries.\",\n anyOf: [\n { type: \"string\" },\n {\n type: \"object\",\n additionalProperties: false,\n properties: {\n name: { type: \"string\", description: \"The image reference, built FROM plywood-pulumi or plywood-plunge, pinned by digest.\" },\n plugins: { type: \"array\", items: { type: \"string\", pattern: PLUGIN.source }, description: \"Plugins the prepared image installs, as name@version or kind:name@version.\" },\n },\n },\n ],\n },\n runners: {\n description: \"The runner every job runs on: a label, a list of labels, or a GitHub runner group; or default, preview, up and drift each mapped to one. runs-on on GitHub and Forgejo, tags on GitLab.\",\n anyOf: [runnerSpecSchema, { type: \"object\", minProperties: 1, not: { required: [\"group\"] }, propertyNames: { enum: [...RUNNER_STAGES] }, additionalProperties: runnerSpecSchema }],\n },\n },\n check(doc) {\n const forge = isObject(doc.forge) ? doc.forge.kind : undefined;\n const out: ConfigProblem[] = [...versionProblems(doc.pulumi, \"pulumi\"), ...versionProblems(doc.plunge, \"plunge\"), ...imageProblems(doc.image), ...runnersProblems(doc.runners, forge)];\n const listed = isObject(doc.stacks) ? Object.keys(doc.stacks) : [];\n for (const key of [\"pulumi\", \"plunge\"] as const) {\n const pin = doc[key];\n if (!isObject(pin) || listed.length === 0) continue;\n for (const glob of Object.keys(pin)) {\n if (glob !== \"*\" && !listed.some((s) => globMatches(glob, s))) out.push(warning(`${key}.${glob}`, \"matches no stack under stacks\"));\n }\n }\n return out;\n },\n translate(doc, out) {\n const engineOfMember = (e: EngineName | undefined): EngineName => e ?? out.memberDefaults.engine ?? \"pulumi\";\n const per: Record<EngineName, string[]> = { pulumi: [], plunge: [] };\n const chosen = out.members.map((m) => {\n const engine = engineOfMember(m.engine);\n const version = pinFor(doc[engine], m.name) ?? pinFor(doc[engine], undefined) ?? TOOL_VERSIONS[engine];\n per[engine].push(version);\n return { m, engine, version };\n });\n const engines = new Set<EngineName>(chosen.map((c) => c.engine));\n engines.add(engineOfMember(undefined));\n if (doc.plunge !== undefined) engines.add(\"plunge\");\n const linked = Object.fromEntries([...engines].map((e) => [e, linkedVersion(e, doc, per[e])])) as Partial<Record<EngineName, string>>;\n\n const pins: EnginePin[] = [...engines].map((engine) => ({ engine, version: linked[engine]!, linked: true }));\n for (const { m, engine, version } of chosen) {\n if (doc[engine] !== undefined) m.engineVersion = version;\n if (version !== linked[engine]) {\n m.engineBin = engineBin(engine, version);\n m.engineRoot = ENGINE_ROOT;\n pins.push({ engine, version, linked: false });\n }\n }\n out.pipeline.engineSetup = installLines(pins);\n\n const own = userImage(doc);\n if (own) out.pipeline.image = own;\n else {\n // plunge's image when every stack runs plunge, else Pulumi's; by digest only, so an unpublished image is never named.\n const ref = imageFor(engines.size === 1 && engines.has(\"plunge\") ? \"plunge\" : \"pulumi\");\n if (ref.digest) out.pipeline.image = imageReference(ref);\n }\n if (doc.runners !== undefined) out.pipeline.runner = structuredClone(doc.runners) as ChantRunner;\n },\n};\n\n", "/**\n * `stacks` and `waves`: each stack as `project/stack` with its directory,\n * extra paths, gate and backend, and the waves they update in. The stacks\n * become chant's Pulumi members; the waves go to chant's product pipeline.\n * Runs before the engine group, which fills each member's engine.\n *\n * `waves` is a list of waves, or a mapping (plywood#18):\n *\n * canary the stacks that update first, in a wave of their own\n * after stack to the stacks it updates after, for an order the stacks'\n * StackReferences do not show (src/stack-order.ts adds those)\n *\n * With the mapping, the rest of the stacks wave by environment as when\n * `waves` is absent, and a wave whose stacks read each other is cut so the\n * stack read updates first.\n */\nimport { GATES } from \"./approval\";\nimport { BACKEND_SCHEMA, error, isObject, mapping, oneOf, onlyKeys, stringList, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\nimport type { ChantGatePolicy } from \"../chant-config\";\n\nexport const STACK_KEYS = [\"dir\", \"paths\", \"gate\", \"backend\"] as const;\nexport const WAVES_KEYS = [\"canary\", \"after\"] as const;\nconst STACK_NAME = /^[^/\\s]+\\/[^/\\s]+$/;\n\nexport interface StackSettings {\n dir?: string;\n paths?: string[];\n gate?: ChantGatePolicy;\n backend?: string;\n}\n\n/** `waves` as a mapping: the canary stacks and the hand-written order. */\nexport interface WavesMapping {\n canary?: string[];\n after?: Record<string, string[]>;\n}\n\n/** The mapping form of `waves`, or an empty one for the list form or none. */\nexport function wavesMappingOf(doc: RawConfig): WavesMapping {\n return isObject(doc.waves) ? (doc.waves as WavesMapping) : {};\n}\n\n/** The stacks plywood.yml lists, by name. */\nexport function stacksOf(doc: RawConfig): Record<string, StackSettings> {\n return isObject(doc.stacks) ? (doc.stacks as Record<string, StackSettings>) : {};\n}\n\nexport const stacks: ConfigGroup = {\n name: \"stacks\",\n keys: [\"stacks\", \"waves\"],\n schema: {\n stacks: {\n type: \"object\",\n description: \"Each stack as project/stack. plywood init finds them when the key is absent.\",\n propertyNames: { pattern: STACK_NAME.source },\n additionalProperties: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n dir: { type: \"string\", description: \"The directory holding the stack's Pulumi.yaml.\" },\n paths: { type: \"array\", items: { type: \"string\" }, description: \"Paths whose change previews the stack, beside its directory.\" },\n gate: { type: \"string\", enum: [\"always\", \"on-destructive\", \"never\"], description: \"The stack's gate, in place of the top-level gate.\" },\n backend: BACKEND_SCHEMA,\n },\n },\n },\n waves: {\n description: \"Lists of stacks, updated in order, the first wave the canary; or canary and after. One wave per environment when absent.\",\n oneOf: [\n { type: \"array\", items: { type: \"array\", items: { type: \"string\" }, minItems: 1 } },\n {\n type: \"object\",\n additionalProperties: false,\n properties: {\n canary: { type: \"array\", items: { type: \"string\" }, minItems: 1, description: \"The stacks that update first, in a wave of their own.\" },\n after: {\n type: \"object\",\n description: \"Each stack to the stacks it updates after, beside the order its StackReferences give.\",\n additionalProperties: { type: \"array\", items: { type: \"string\" } },\n },\n },\n },\n ],\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [...mapping(doc.stacks, \"stacks\")];\n const listed = stacksOf(doc);\n for (const [name, s] of Object.entries(listed)) {\n const key = `stacks.${name}`;\n if (!STACK_NAME.test(name)) out.push(error(key, \"names a stack as project/stack\"));\n if (s === null || s === undefined) continue;\n if (!isObject(s)) {\n out.push(error(key, \"must be a mapping\"));\n continue;\n }\n out.push(...onlyKeys(s, STACK_KEYS, key));\n if (s.dir !== undefined && typeof s.dir !== \"string\") out.push(error(`${key}.dir`, \"must be a string\"));\n if (s.backend !== undefined && typeof s.backend !== \"string\") out.push(error(`${key}.backend`, \"must be a URL string\"));\n out.push(...stringList(s.paths, `${key}.paths`), ...oneOf(s.gate, GATES, `${key}.gate`));\n }\n if (isObject(doc.waves)) {\n out.push(...wavesMappingProblems(doc.waves, isObject(doc.stacks) ? listed : undefined));\n } else if (doc.waves !== undefined) {\n if (!Array.isArray(doc.waves) || doc.waves.some((w) => !Array.isArray(w) || w.length === 0 || w.some((s) => typeof s !== \"string\"))) {\n out.push(error(\"waves\", \"must be a list of waves, each a list of stack names\"));\n } else {\n const seen = new Set<string>();\n doc.waves.forEach((w: string[], i) => {\n for (const s of w) {\n if (seen.has(s)) out.push(error(`waves[${i}]`, `${s} is in more than one wave`));\n seen.add(s);\n if (isObject(doc.stacks) && !(s in listed)) out.push(error(`waves[${i}]`, `${s} is not under stacks`));\n }\n });\n }\n }\n return out;\n },\n translate(doc, out) {\n for (const [name, s] of Object.entries(stacksOf(doc))) {\n const st = s ?? {};\n out.members.push({\n name,\n ...(st.dir !== undefined ? { dir: st.dir } : {}),\n ...(st.paths?.length ? { paths: [...st.paths] } : {}),\n ...(st.gate !== undefined ? { gate: st.gate } : {}),\n ...(st.backend !== undefined ? { backend: st.backend } : {}),\n });\n }\n if (Array.isArray(doc.waves)) out.pipeline.waves = (doc.waves as string[][]).map((w) => [...w]);\n const { canary, after } = wavesMappingOf(doc);\n if (canary?.length) out.pipeline.canary = [...canary];\n if (after && Object.keys(after).length) out.pipeline.after = Object.fromEntries(Object.entries(after).map(([k, v]) => [k, [...v]]));\n },\n};\n\n/** The problems with `waves` as a mapping. `listed` is set when plywood.yml lists its stacks, so each name can be checked. */\nfunction wavesMappingProblems(w: Record<string, unknown>, listed: Record<string, StackSettings> | undefined): ConfigProblem[] {\n const out: ConfigProblem[] = [...onlyKeys(w, WAVES_KEYS, \"waves\")];\n const known = (s: string, key: string): void => {\n if (!STACK_NAME.test(s)) out.push(error(key, `${s} is not a stack name (project/stack)`));\n else if (listed && !(s in listed)) out.push(error(key, `${s} is not under stacks`));\n };\n if (w.canary !== undefined) {\n if (!Array.isArray(w.canary) || w.canary.length === 0 || w.canary.some((s) => typeof s !== \"string\")) out.push(error(\"waves.canary\", \"must be a list of stack names\"));\n else for (const s of w.canary as string[]) known(s, \"waves.canary\");\n }\n if (w.after !== undefined) {\n if (!isObject(w.after)) out.push(error(\"waves.after\", \"must map a stack to the stacks it updates after\"));\n else {\n for (const [stack, ups] of Object.entries(w.after)) {\n const key = `waves.after.${stack}`;\n known(stack, key);\n if (!Array.isArray(ups) || ups.some((u) => typeof u !== \"string\")) {\n out.push(error(key, \"must be a list of stack names\"));\n continue;\n }\n for (const u of ups as string[]) {\n if (u === stack) out.push(error(key, `${stack} cannot update after itself`));\n else known(u, key);\n }\n }\n const cycle = afterCycle(w.after as Record<string, string[]>);\n if (cycle) out.push(error(\"waves.after\", `goes round in a circle: ${cycle.join(\" after \")}`));\n }\n }\n return out;\n}\n\n/** A circle in the hand-written order, as the stacks on it, or undefined. */\nexport function afterCycle(after: Readonly<Record<string, readonly string[]>>): string[] | undefined {\n const state = new Map<string, \"open\" | \"done\">();\n const path: string[] = [];\n const visit = (s: string): string[] | undefined => {\n if (state.get(s) === \"done\") return undefined;\n if (state.get(s) === \"open\") return [...path.slice(path.indexOf(s)), s];\n state.set(s, \"open\");\n path.push(s);\n for (const u of Array.isArray(after[s]) ? after[s]! : []) {\n const found = visit(u);\n if (found) return found;\n }\n path.pop();\n state.set(s, \"done\");\n return undefined;\n };\n for (const s of Object.keys(after)) {\n const found = visit(s);\n if (found) return found;\n }\n return undefined;\n}\n", "/**\n * `drift` and `respond`: the scheduled drift check and what it does when a\n * stack has drifted (plywood#8).\n *\n * drift.schedule a five-field cron line; the scheduled drift job runs on it\n * drift.stacks the stacks (or project/* globs) the job reads; every stack when absent\n * respond.drift issue (default): one issue per drifted stack, edited on\n * each run and closed by a clean one;\n * pull-request: the issue, and the drift agent's pull\n * request that brings the program in line (plywood#19);\n * up: the issue, and an update of the waves holding the\n * drifted stacks, through each wave's gate;\n * none: the job's exit code only\n * -> pipeline.drift, which `plywood ci` writes as chant's scheduled Op\n * jobs (one PulumiWatchOp per stack) and `plywood drift` reads\n * drift.audit_log aws or aws:<region>, or a stack glob to one: the\n * CloudTrail `plywood drift` reads to name who changed\n * each drifted attribute (chant#4632's ci-audit)\n *\n * respond.wave_refused diff (default) or off: a wave refused because its\n * preview moved, a hold or a decline posts the diff\n * against the approved preview (chant#4629)\n * respond.apply_failed triage (default) or off: a failed update posts the\n * stacks and resources that failed, with the error\n * respond.description off (default) or check: a pull request whose\n * description leaves out what its preview deletes or\n * replaces is flagged; it asks the `decide` service\n * decide.backend the chant.config `decide.backends` entry the\n * description check asks, read at the target branch\n * decide.model the pinned model id\n * -> pipeline.respond and pipeline.decide, chant's `respond` and\n * `decide` options of the product pipeline (src/stages.ts)\n *\n * The read itself is chant's (`chant workspace drift`, the pulumi lexicon's\n * `readDrift`): `pulumi refresh --preview-only` per resource on stock\n * Pulumi, `plunge drift --resource <urn> --stream` on plunge, over the\n * export the last update stored under refs/chant/snapshots (chant#4546).\n */\nimport { globMatches } from \"./images\";\nimport { stacksOf } from \"./stacks\";\nimport { error, isObject, oneOf, onlyKeys, stringList, warning, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\nexport const DRIFT_RESPONSES = [\"issue\", \"pull-request\", \"up\", \"none\"] as const;\nexport type DriftResponse = (typeof DRIFT_RESPONSES)[number];\nexport const DEFAULT_DRIFT_RESPONSE: DriftResponse = \"issue\";\n\n/** The pipeline events plywood.yml's respond names beside drift, plywood's key to chant's event and its modes, default first (chant `CI_RESPONSES`). */\nexport const EVENT_RESPONSES = {\n wave_refused: { event: \"wave-refused\", modes: [\"diff\", \"off\"] },\n apply_failed: { event: \"apply-failed\", modes: [\"triage\", \"off\"] },\n description: { event: \"description\", modes: [\"off\", \"check\"] },\n} as const;\nexport type EventKey = keyof typeof EVENT_RESPONSES;\nconst EVENT_KEYS = Object.keys(EVENT_RESPONSES) as EventKey[];\nexport const RESPOND_KEYS = [\"drift\", ...EVENT_KEYS] as const;\nexport const DECIDE_KEYS = [\"backend\", \"model\"] as const;\n\n/** The responses plywood.yml sets, by chant's event name; an event left out takes chant's default. */\nexport function eventResponsesOf(doc: RawConfig): Record<string, string> {\n const r = isObject(doc.respond) ? doc.respond : {};\n const out: Record<string, string> = {};\n for (const k of EVENT_KEYS) {\n const v = r[k];\n if (typeof v === \"string\" && (EVENT_RESPONSES[k].modes as readonly string[]).includes(v)) out[EVENT_RESPONSES[k].event] = v;\n }\n return out;\n}\n\n/** `decide`, when it names both a backend and a model. */\nexport function decideOf(doc: RawConfig): { backend: string; model: string } | undefined {\n const d = isObject(doc.decide) ? doc.decide : {};\n return typeof d.backend === \"string\" && d.backend !== \"\" && typeof d.model === \"string\" && d.model !== \"\" ? { backend: d.backend, model: d.model } : undefined;\n}\n\n/** `drift.audit_log` as stack glob to chant's `--audit-log` text (`*` for every stack). */\nexport function auditLogsOf(doc: RawConfig): Record<string, string> | undefined {\n const d = isObject(doc.drift) ? doc.drift : {};\n if (typeof d.audit_log === \"string\") return { \"*\": d.audit_log };\n if (isObject(d.audit_log)) return Object.fromEntries(Object.entries(d.audit_log).filter((e): e is [string, string] => typeof e[1] === \"string\"));\n return undefined;\n}\n\n/** `aws`, or `aws:<region>`. */\nconst AUDIT_LOG = /^aws(?::[a-z0-9-]+)?$/;\n\n/** Five cron fields, each a number, a range, a list, a step or `*`. */\nconst CRON_FIELD = /^(?:\\*|\\d+(?:-\\d+)?)(?:\\/\\d+)?(?:,(?:\\*|\\d+(?:-\\d+)?)(?:\\/\\d+)?)*$/;\n\nexport function isCron(v: unknown): v is string {\n if (typeof v !== \"string\") return false;\n const fields = v.trim().split(/\\s+/);\n return fields.length === 5 && fields.every((f) => CRON_FIELD.test(f));\n}\n\n/** What plywood hands the drift job and `plywood drift`. */\nexport interface DriftSettings {\n schedule?: string;\n /** The stacks the scheduled job reads, by name. */\n stacks: string[];\n respond: DriftResponse;\n /** `drift.audit_log`: stack glob to the audit log (`aws[:<region>]`) the attribution reads. */\n auditLogs?: Record<string, string>;\n}\n\n/** `respond.drift`, or the default. */\nexport function driftResponseOf(doc: RawConfig): DriftResponse {\n const r = isObject(doc.respond) ? doc.respond.drift : undefined;\n return typeof r === \"string\" && (DRIFT_RESPONSES as readonly string[]).includes(r) ? (r as DriftResponse) : DEFAULT_DRIFT_RESPONSE;\n}\n\n/** The stacks `drift.stacks` picks from those plywood.yml lists; all of them when absent. */\nexport function driftStacksOf(doc: RawConfig): string[] {\n const listed = Object.keys(stacksOf(doc));\n const d = isObject(doc.drift) ? doc.drift : {};\n if (!Array.isArray(d.stacks)) return listed;\n const globs = d.stacks.filter((s): s is string => typeof s === \"string\");\n return listed.filter((name) => globs.some((g) => globMatches(g, name)));\n}\n\nexport function driftSettingsOf(doc: RawConfig): DriftSettings {\n const d = isObject(doc.drift) ? doc.drift : {};\n return {\n ...(isCron(d.schedule) ? { schedule: d.schedule.trim() } : {}),\n stacks: driftStacksOf(doc),\n respond: driftResponseOf(doc),\n ...(auditLogsOf(doc) ? { auditLogs: auditLogsOf(doc) } : {}),\n };\n}\n\nexport const drift: ConfigGroup = {\n name: \"drift\",\n keys: [\"drift\", \"respond\", \"decide\"],\n schema: {\n drift: {\n type: \"object\",\n additionalProperties: false,\n description: \"The scheduled drift check. Off when absent.\",\n properties: {\n schedule: { type: \"string\", description: \"A five-field cron line, such as \\\"0 6 * * *\\\"; the drift job runs on it.\" },\n stacks: { type: \"array\", items: { type: \"string\" }, description: \"The stacks the job reads, by name or project/* glob. Every stack when absent.\" },\n audit_log: {\n description: \"aws or aws:<region>, or a stack glob to one: the CloudTrail plywood drift reads to name who changed each drifted attribute.\",\n oneOf: [\n { type: \"string\", pattern: AUDIT_LOG.source },\n { type: \"object\", additionalProperties: { type: \"string\", pattern: AUDIT_LOG.source } },\n ],\n },\n },\n },\n respond: {\n type: \"object\",\n additionalProperties: false,\n description: \"What plywood does about a finding.\",\n properties: {\n drift: {\n type: \"string\",\n enum: [...DRIFT_RESPONSES],\n default: DEFAULT_DRIFT_RESPONSE,\n description: \"issue: one issue per drifted stack; pull-request: the issue and the drift agent's pull request; up: the issue and a gated update; none: the exit code only.\",\n },\n wave_refused: { type: \"string\", enum: [...EVENT_RESPONSES.wave_refused.modes], default: \"diff\", description: \"diff: a refused wave posts the diff against the approved preview; off: nothing.\" },\n apply_failed: { type: \"string\", enum: [...EVENT_RESPONSES.apply_failed.modes], default: \"triage\", description: \"triage: a failed update posts the stacks and resources that failed, with the error; off: nothing.\" },\n description: { type: \"string\", enum: [...EVENT_RESPONSES.description.modes], default: \"off\", description: \"check: flag a pull request whose description leaves out what its preview deletes or replaces. Needs decide.\" },\n },\n },\n decide: {\n type: \"object\",\n additionalProperties: false,\n description: \"The decide service respond.description: check asks.\",\n properties: {\n backend: { type: \"string\", description: \"A decide.backends entry of chant.config, read at the target branch.\" },\n model: { type: \"string\", description: \"The pinned model id.\" },\n },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [];\n if (doc.drift !== undefined) {\n if (!isObject(doc.drift)) out.push(error(\"drift\", \"must be a mapping with a schedule\"));\n else {\n const d = doc.drift;\n out.push(...onlyKeys(d, [\"schedule\", \"stacks\", \"audit_log\"], \"drift\"), ...stringList(d.stacks, \"drift.stacks\"));\n if (d.audit_log !== undefined) {\n const values = typeof d.audit_log === \"string\" ? [d.audit_log] : isObject(d.audit_log) ? Object.values(d.audit_log) : undefined;\n if (!values) out.push(error(\"drift.audit_log\", \"is aws, aws:<region>, or a stack glob to one\"));\n else for (const v of values) if (typeof v !== \"string\" || !AUDIT_LOG.test(v)) out.push(error(\"drift.audit_log\", `is ${JSON.stringify(v)}; give aws or aws:<region>, the CloudTrail the attribution reads`));\n }\n if (d.schedule === undefined) out.push(warning(\"drift\", \"has no schedule, so no job reads drift; plywood drift still runs by hand\"));\n else if (!isCron(d.schedule)) out.push(error(\"drift.schedule\", \"is a five-field cron line, such as \\\"0 6 * * *\\\"\"));\n if (Array.isArray(d.stacks) && isObject(doc.stacks) && driftStacksOf(doc).length === 0) {\n out.push(error(\"drift.stacks\", \"names none of the stacks under stacks\"));\n }\n }\n }\n if (doc.respond !== undefined) {\n if (!isObject(doc.respond)) out.push(error(\"respond\", \"must be a mapping, such as respond: { drift: issue }\"));\n else {\n out.push(...onlyKeys(doc.respond, RESPOND_KEYS, \"respond\"), ...oneOf(doc.respond.drift, DRIFT_RESPONSES, \"respond.drift\"));\n for (const k of EVENT_KEYS) out.push(...oneOf(doc.respond[k], EVENT_RESPONSES[k].modes, `respond.${k}`));\n if (doc.respond.description === \"check\" && !decideOf(doc)) out.push(error(\"respond.description\", \"is check, which asks a decide service; set decide.backend and decide.model\"));\n if (doc.respond.drift === \"up\" && doc.gate === \"never\") {\n out.push(warning(\"respond.drift\", \"is up and gate is never, so a drifted stack updates with nobody approving\"));\n }\n }\n }\n if (doc.decide !== undefined) {\n if (!isObject(doc.decide)) out.push(error(\"decide\", \"must be a mapping of backend and model\"));\n else {\n out.push(...onlyKeys(doc.decide, DECIDE_KEYS, \"decide\"));\n for (const k of DECIDE_KEYS) if (typeof doc.decide[k] !== \"string\" || doc.decide[k] === \"\") out.push(error(`decide.${k}`, k === \"backend\" ? \"names a decide.backends entry of chant.config\" : \"names the pinned model id\"));\n if (!(isObject(doc.respond) && doc.respond.description === \"check\")) out.push(warning(\"decide\", \"is set and respond.description is not check, so nothing asks it and plywood ci leaves it off the jobs\"));\n }\n }\n return out;\n },\n translate(doc, out) {\n const events = eventResponsesOf(doc);\n if (Object.keys(events).length) out.pipeline.respond = events;\n const decide = decideOf(doc);\n // Kept without the check too: plywood ci leaves it off the jobs and says so (src/stages.ts respondOptions).\n if (decide) out.pipeline.decide = decide;\n if (doc.drift === undefined && !(isObject(doc.respond) && doc.respond.drift !== undefined)) return;\n out.pipeline.drift = driftSettingsOf(doc);\n },\n};\n", "/**\n * `engine` and `backend`, the two keys chant's pulumi lexicon reads from\n * plywood.yml itself (chant#4559, `readPlywoodEngine`): `engine` is\n * `pulumi` or `plunge`, `backend` a URL string, and a `plunge+` or `plunge:`\n * backend means plunge. plywood keeps them top-level strings so chant reads\n * them as plywood does, and also hands each member its engine and backend\n * as the member's config, the rule chant asks first.\n *\n * Engine detection stays in chant: with neither key set, plywood names no\n * engine and chant decides from PULUMI_BACKEND_URL and Pulumi.yaml.\n */\nimport { stacksOf } from \"./stacks\";\nimport { BACKEND_SCHEMA, error, oneOf, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\nexport const ENGINES = [\"pulumi\", \"plunge\"] as const;\nexport type Engine = (typeof ENGINES)[number];\n\n/** The backend URL forms chant's pulumi lexicon takes as plunge (member-engine.ts `PLUNGE_URL`). */\nexport const PLUNGE_URL = /^plunge[+:]/;\n\n/** The engine plywood.yml names for a stack's backend, or for all stacks, and why; undefined leaves it to chant. */\nexport function engineOf(doc: RawConfig, backend?: string): { engine: Engine; because: string } | undefined {\n if (doc.engine === \"pulumi\" || doc.engine === \"plunge\") return { engine: doc.engine, because: `plywood.yml says engine: ${doc.engine}` };\n const url = backend ?? (typeof doc.backend === \"string\" ? doc.backend : undefined);\n if (url && PLUNGE_URL.test(url)) return { engine: \"plunge\", because: `the backend ${url} is plunge's` };\n return undefined;\n}\n\nexport const engine: ConfigGroup = {\n name: \"engine\",\n keys: [\"engine\", \"backend\"],\n schema: {\n engine: { type: \"string\", enum: [...ENGINES], description: \"pulumi or plunge. Absent, a plunge+ backend picks plunge, else chant reads PULUMI_BACKEND_URL and Pulumi.yaml.\" },\n backend: BACKEND_SCHEMA,\n },\n check(doc) {\n const out: ConfigProblem[] = [...oneOf(doc.engine, ENGINES, \"engine\")];\n if (doc.backend !== undefined && typeof doc.backend !== \"string\") out.push(error(\"backend\", \"must be a URL string\"));\n if (doc.engine === \"pulumi\") {\n const backends: [string, unknown][] = [[\"backend\", doc.backend], ...Object.entries(stacksOf(doc)).map(([n, s]): [string, unknown] => [`stacks.${n}.backend`, s?.backend])];\n for (const [key, url] of backends) {\n if (typeof url === \"string\" && PLUNGE_URL.test(url)) {\n out.push(error(key, `${url} is a plunge backend and engine is pulumi; set engine: plunge, or give a stock backend URL`));\n }\n }\n }\n return out;\n },\n translate(doc, out) {\n const all = engineOf(doc);\n if (all) out.memberDefaults.engine = all.engine;\n if (typeof doc.backend === \"string\") out.memberDefaults.backend = doc.backend;\n for (const m of out.members) {\n if (m.backend === undefined && typeof doc.backend === \"string\") m.backend = doc.backend;\n const e = engineOf(doc, m.backend);\n if (e) m.engine = e.engine;\n }\n },\n};\n", "/**\n * `identity` and `pulumi_cloud`: who the preview job and the update job are,\n * per cloud and stack glob, rendered as chant's `ci.identity.cloud`\n * (chant#4296, #4332, and #4549 for Pulumi Cloud).\n *\n * identity.preview cloud to identity, for every stack\n * identity.up cloud to identity, for every stack\n * identity.stacks stack glob to { preview, up, environments },\n * each a cloud-to-identity map, over the two above\n * identity.aws region, audience, endpoint\n * identity.gcp provider, audience, sts_endpoint, iam_endpoint\n * identity.azure tenant_id, subscription_id, audience, authority\n * pulumi_cloud.org ci.identity.cloud.pulumi.organization\n * pulumi_cloud.api_url its apiUrl: a self-hosted Pulumi Cloud, or a\n * loopback fake in tests (default https://api.pulumi.com)\n * pulumi_cloud.audience its audience (default urn:pulumi:org:<org>)\n *\n * The clouds are aws (a role ARN), gcp (a service account), azure (a client\n * id) and pulumi (a Pulumi Cloud token: team:<name>, user:<login>,\n * organization or organization:admin). Each cloud's rules are the stack\n * globs in plywood.yml's order, then the every-stack pair; chant takes the\n * first that matches, with preview as the rule's plan identity and up as\n * its apply identity.\n *\n * The preview job trades its forge OIDC token before the program is checked\n * out, and every later step starts without the token request variables, so\n * a pull request's program never holds a forge token or the up identity.\n * On Pulumi Cloud the trade gives the preview job one access token and the\n * update job another (chant#4549); stock Pulumi opens a stack's ESC\n * environments with that token (ruling H). plywood passes the token and\n * nothing else. One identity for both stages is refused.\n *\n * A stack glob is chant's target glob over `project/stack`: `*` stays within\n * one segment, so `shop/*` is every shop stack and `**` every stack.\n */\nimport { error, isObject, onlyKeys, warning, type ConfigGroup, type ConfigProblem, type JsonSchema, type RawConfig } from \"./types\";\n\nexport const IDENTITY_CLOUDS = [\"aws\", \"gcp\", \"azure\", \"pulumi\"] as const;\nexport type IdentityCloud = (typeof IDENTITY_CLOUDS)[number];\nexport const STAGES = [\"preview\", \"up\"] as const;\nexport type Stage = (typeof STAGES)[number];\n\n/** Each cloud's own settings under identity.<cloud>: plywood's snake_case key to chant's. Pulumi Cloud's are under pulumi_cloud. */\nexport const CLOUD_SETTINGS = {\n aws: { region: \"region\", audience: \"audience\", endpoint: \"endpoint\" },\n gcp: { provider: \"provider\", audience: \"audience\", sts_endpoint: \"stsEndpoint\", iam_endpoint: \"iamEndpoint\" },\n azure: { tenant_id: \"tenantId\", subscription_id: \"subscriptionId\", audience: \"audience\", authority: \"authority\" },\n} as const satisfies Record<Exclude<IdentityCloud, \"pulumi\">, Record<string, string>>;\ntype SettingsCloud = keyof typeof CLOUD_SETTINGS;\nconst SETTINGS_CLOUDS = Object.keys(CLOUD_SETTINGS) as SettingsCloud[];\n\n/** Settings a cloud cannot trade without. */\nconst REQUIRED: Readonly<Record<IdentityCloud, readonly string[]>> = { aws: [], gcp: [\"identity.gcp.provider\"], azure: [\"identity.azure.tenant_id\"], pulumi: [\"pulumi_cloud.org\"] };\n\nexport const IDENTITY_KEYS = [\"preview\", \"up\", \"stacks\", ...SETTINGS_CLOUDS] as const;\nexport const STACK_RULE_KEYS = [\"preview\", \"up\", \"environments\"] as const;\nexport const PULUMI_CLOUD_KEYS = [\"org\", \"api_url\", \"audience\"] as const;\n\n/** A glob that covers every stack, written as no target glob in chant's rule. */\nconst EVERY_STACK = new Set([\"*\", \"**\"]);\n\n/** One rule for one cloud, as plywood.yml names it. `glob` is undefined for the every-stack pair. */\nexport interface StageIdentityRule {\n glob?: string;\n preview: string;\n up: string;\n environments?: string[];\n}\n\n/** One rule of chant's `ci.identity.cloud.<cloud>.rules` (`CloudIdentityRule`). */\nexport interface ChantIdentityRule {\n environments?: string[];\n targets?: string[];\n plan: string;\n apply: string;\n}\n\n/** chant's `ci.identity` as plywood writes it. */\nexport interface ChantIdentitySettings {\n cloud: Partial<Record<IdentityCloud, Record<string, unknown> & { rules: ChantIdentityRule[] }>>;\n}\n\nconst PULUMI_TOKEN = /^(?:(?:team|user):[^\\s:]+|organization|organization:admin)$/;\n\n/** Why `v` is no Pulumi Cloud token chant can trade for, or undefined. */\nexport function pulumiTokenProblem(v: string): string | undefined {\n return PULUMI_TOKEN.test(v) ? undefined : `is ${JSON.stringify(v)}; a Pulumi Cloud token is team:<name>, user:<login>, organization or organization:admin`;\n}\n\nconst stageMap = (v: unknown): Record<string, unknown> => (isObject(v) ? v : {});\n\n/** The rules plywood.yml gives `cloud`: the stack globs in order, then the every-stack pair. */\nexport function identityRules(doc: RawConfig, cloud: IdentityCloud): StageIdentityRule[] {\n const block = isObject(doc.identity) ? doc.identity : {};\n const out: StageIdentityRule[] = [];\n for (const [glob, r] of Object.entries(stageMap(block.stacks))) {\n if (!isObject(r)) continue;\n const preview = stageMap(r.preview)[cloud];\n const up = stageMap(r.up)[cloud];\n if (typeof preview !== \"string\" || typeof up !== \"string\") continue;\n out.push({ glob, preview, up, ...(Array.isArray(r.environments) ? { environments: r.environments as string[] } : {}) });\n }\n const preview = stageMap(block.preview)[cloud];\n const up = stageMap(block.up)[cloud];\n if (typeof preview === \"string\" && typeof up === \"string\") out.push({ preview, up });\n return out;\n}\n\n/** The clouds plywood.yml names identities for. */\nexport function identityClouds(doc: RawConfig): IdentityCloud[] {\n return IDENTITY_CLOUDS.filter((c) => identityRules(doc, c).length > 0);\n}\n\n/** One plywood rule as chant's. */\nexport function chantRule(r: StageIdentityRule): ChantIdentityRule {\n return {\n ...(r.environments?.length ? { environments: [...r.environments] } : {}),\n ...(r.glob === undefined || EVERY_STACK.has(r.glob) ? {} : { targets: [r.glob] }),\n plan: r.preview,\n apply: r.up,\n };\n}\n\n/** `pulumi_cloud` as read: the organization, and where its API is. */\nexport function pulumiCloudOf(doc: RawConfig): { org?: string; apiUrl?: string; audience?: string } {\n const p = isObject(doc.pulumi_cloud) ? doc.pulumi_cloud : {};\n return {\n ...(typeof p.org === \"string\" ? { org: p.org } : {}),\n ...(typeof p.api_url === \"string\" ? { apiUrl: p.api_url.replace(/\\/+$/, \"\") } : {}),\n ...(typeof p.audience === \"string\" ? { audience: p.audience } : {}),\n };\n}\n\n/** chant's `ci.identity` for plywood.yml, or undefined when it names no identity. */\nexport function chantIdentityOf(doc: RawConfig): ChantIdentitySettings | undefined {\n const clouds = identityClouds(doc);\n if (clouds.length === 0) return undefined;\n const block = isObject(doc.identity) ? doc.identity : {};\n const cloud: ChantIdentitySettings[\"cloud\"] = {};\n for (const c of clouds) {\n const settings: Record<string, unknown> = {};\n if (c === \"pulumi\") {\n const p = pulumiCloudOf(doc);\n settings.organization = p.org;\n if (p.audience) settings.audience = p.audience;\n if (p.apiUrl) settings.apiUrl = p.apiUrl;\n } else {\n const own = stageMap(block[c]);\n for (const [plywood, chant] of Object.entries(CLOUD_SETTINGS[c])) if (own[plywood] !== undefined) settings[chant] = own[plywood];\n }\n cloud[c] = { ...settings, rules: identityRules(doc, c).map(chantRule) };\n }\n return { cloud };\n}\n\n/** The identity `stack` takes for each cloud and stage, first match wins as chant reads it. `match` is chant's target glob. */\nexport function stackIdentities(doc: RawConfig, stack: string, env: string, match: (glob: string, target: string) => boolean): Partial<Record<IdentityCloud, Record<Stage, string> & { rule: string }>> {\n const envMatch = (globs: string[] | undefined): boolean => !globs?.length || globs.some((g) => (g.startsWith(\"!\") ? !match(g.slice(1), env) : match(g, env)));\n const out: Partial<Record<IdentityCloud, Record<Stage, string> & { rule: string }>> = {};\n for (const c of IDENTITY_CLOUDS) {\n const r = identityRules(doc, c).find((x) => envMatch(x.environments) && (x.glob === undefined || EVERY_STACK.has(x.glob) || match(x.glob, stack)));\n if (r) out[c] = { preview: r.preview, up: r.up, rule: r.glob === undefined ? \"identity.preview and identity.up\" : `identity.stacks.${r.glob}` };\n }\n return out;\n}\n\nconst CLOUD_MAP: JsonSchema = {\n type: \"object\",\n additionalProperties: false,\n properties: {\n aws: { type: \"string\", description: \"An IAM role ARN.\" },\n gcp: { type: \"string\", description: \"A service account email.\" },\n azure: { type: \"string\", description: \"An Entra app's client id.\" },\n pulumi: { type: \"string\", pattern: PULUMI_TOKEN.source, description: \"A Pulumi Cloud token: team:<name>, user:<login>, organization or organization:admin.\" },\n },\n};\n\nfunction stageMapProblems(v: unknown, key: string): ConfigProblem[] {\n if (v === undefined) return [];\n if (!isObject(v)) return [error(key, `maps a cloud (${IDENTITY_CLOUDS.join(\", \")}) to an identity`)];\n const out = [...onlyKeys(v, IDENTITY_CLOUDS, key)];\n for (const [c, id] of Object.entries(v)) {\n if (!(IDENTITY_CLOUDS as readonly string[]).includes(c)) continue;\n if (typeof id !== \"string\" || id === \"\") out.push(error(`${key}.${c}`, \"names the identity\"));\n else if (c === \"pulumi\") {\n const why = pulumiTokenProblem(id);\n if (why) out.push(error(`${key}.${c}`, why));\n }\n }\n return out;\n}\n\n/** A preview and up pair, `where` naming them: each cloud on both sides, and never one identity for both. */\nfunction pairProblems(preview: unknown, up: unknown, where: string): ConfigProblem[] {\n const p = stageMap(preview);\n const u = stageMap(up);\n const out: ConfigProblem[] = [];\n for (const c of IDENTITY_CLOUDS) {\n if ((p[c] === undefined) !== (u[c] === undefined)) out.push(error(`${where}.${p[c] === undefined ? \"preview\" : \"up\"}.${c}`, `is missing: ${c} names a ${p[c] === undefined ? \"preview\" : \"up\"} identity beside the ${p[c] === undefined ? \"up\" : \"preview\"} one`));\n else if (typeof p[c] === \"string\" && p[c] === u[c]) out.push(error(where, `gives ${c} one identity for preview and up, so a pull request's program could update with it; give each stage its own`));\n }\n return out;\n}\n\nexport const identity: ConfigGroup = {\n name: \"identity\",\n keys: [\"identity\", \"pulumi_cloud\"],\n schema: {\n identity: {\n type: \"object\",\n additionalProperties: false,\n description: \"The preview and up identities per cloud, for every stack and per stack glob. The preview job trades its OIDC token before the program is checked out.\",\n properties: {\n preview: { ...CLOUD_MAP, description: \"The preview job's identity per cloud, for every stack.\" },\n up: { ...CLOUD_MAP, description: \"The update job's identity per cloud, for every stack.\" },\n stacks: {\n type: \"object\",\n description: \"Stack glob (project/stack; * stays within one segment) to its own preview and up identities. The first glob that matches a stack is its.\",\n additionalProperties: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n preview: CLOUD_MAP,\n up: CLOUD_MAP,\n environments: { type: \"array\", items: { type: \"string\" }, description: \"Environment globs the rule covers. Absent: every environment.\" },\n },\n },\n },\n ...Object.fromEntries(SETTINGS_CLOUDS.map((c) => [c, { type: \"object\", additionalProperties: false, properties: Object.fromEntries(Object.keys(CLOUD_SETTINGS[c]).map((k) => [k, { type: \"string\" }])) }])),\n },\n },\n pulumi_cloud: {\n type: \"object\",\n additionalProperties: false,\n required: [\"org\"],\n description: \"The Pulumi Cloud organization the stacks' state is in. With identity's pulumi tokens, each job trades for its own access token.\",\n properties: {\n org: { type: \"string\", description: \"The organization.\" },\n api_url: { type: \"string\", description: \"The Pulumi Cloud API, for a self-hosted one. Default https://api.pulumi.com.\" },\n audience: { type: \"string\", description: \"The OIDC token's audience. Default urn:pulumi:org:<org>.\" },\n },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [];\n const p = doc.pulumi_cloud;\n if (p !== undefined) {\n if (!isObject(p)) out.push(error(\"pulumi_cloud\", \"must be a mapping with org\"));\n else {\n out.push(...onlyKeys(p, PULUMI_CLOUD_KEYS, \"pulumi_cloud\"));\n if (typeof p.org !== \"string\" || !/^[A-Za-z0-9][A-Za-z0-9_.-]*$/.test(p.org)) out.push(error(\"pulumi_cloud.org\", \"names the Pulumi Cloud organization\"));\n if (p.api_url !== undefined && (typeof p.api_url !== \"string\" || !/^https?:\\/\\/\\S+$/.test(p.api_url))) out.push(error(\"pulumi_cloud.api_url\", \"must be an http or https URL\"));\n if (p.audience !== undefined && (typeof p.audience !== \"string\" || p.audience === \"\")) out.push(error(\"pulumi_cloud.audience\", \"must be a string\"));\n }\n }\n const block = doc.identity;\n if (block === undefined) {\n if (isObject(p)) out.push(warning(\"pulumi_cloud\", \"has no pulumi identities, so the jobs need long-lived tokens in the forge's secrets; set identity.preview.pulumi and identity.up.pulumi and each job trades its OIDC token for its own\"));\n return out;\n }\n if (!isObject(block)) return [...out, error(\"identity\", \"must be a mapping of preview, up and stacks\")];\n out.push(...onlyKeys(block, IDENTITY_KEYS, \"identity\"));\n out.push(...stageMapProblems(block.preview, \"identity.preview\"), ...stageMapProblems(block.up, \"identity.up\"), ...pairProblems(block.preview, block.up, \"identity\"));\n if (block.stacks !== undefined) {\n if (!isObject(block.stacks)) out.push(error(\"identity.stacks\", \"maps a stack glob to { preview, up }\"));\n else {\n for (const [glob, r] of Object.entries(block.stacks)) {\n const key = `identity.stacks.${glob}`;\n if (!isObject(r)) {\n out.push(error(key, \"must be { preview, up }\"));\n continue;\n }\n out.push(...onlyKeys(r, STACK_RULE_KEYS, key), ...stageMapProblems(r.preview, `${key}.preview`), ...stageMapProblems(r.up, `${key}.up`), ...pairProblems(r.preview, r.up, key));\n if (r.environments !== undefined && (!Array.isArray(r.environments) || r.environments.some((e) => typeof e !== \"string\"))) out.push(error(`${key}.environments`, \"must be a list of environment globs\"));\n }\n }\n }\n for (const c of SETTINGS_CLOUDS) {\n const s = block[c];\n if (s === undefined) continue;\n if (!isObject(s)) {\n out.push(error(`identity.${c}`, `must be a mapping of ${Object.keys(CLOUD_SETTINGS[c]).join(\", \")}`));\n continue;\n }\n out.push(...onlyKeys(s, Object.keys(CLOUD_SETTINGS[c]), `identity.${c}`));\n for (const [k, v] of Object.entries(s)) if (typeof v !== \"string\" || v === \"\") out.push(error(`identity.${c}.${k}`, \"must be a string\"));\n }\n for (const c of identityClouds(doc)) {\n for (const req of REQUIRED[c]) {\n const [top, ...path] = req.split(\".\");\n let v: unknown = doc[top!];\n for (const seg of path) v = isObject(v) ? v[seg] : undefined;\n if (v === undefined) out.push(error(req, `is required: identity names ${c} identities`));\n }\n }\n return out;\n },\n translate(doc, out) {\n const id = chantIdentityOf(doc);\n if (id) out.ci.identity = id;\n },\n};\n", "/**\n * `env`, `pass`, `parallelism` and `environments`: what the jobs run with\n * (plywood#29).\n *\n * env variable to value each job's variables: the waves,\n * the drift Ops and, with chant#4625,\n * the pull request jobs\n * pass secret names, or secrets passed as variables, by\n * variable to secret name, never a value\n * parallelism a whole number stacks previewed at once in a wave\n * and runs updated at once in a wave\n * (chant#4625)\n * environments stack glob to a forge each update job's deployment\n * environment environment, and the forge check's\n *\n * The translation is in src/jobs.ts, which puts the settings on the waves\n * spec, the drift Ops and the pull request pipeline.\n */\nimport type { JsonSchema } from \"./types\";\nimport { error, isObject, warning, type ConfigGroup, type ConfigProblem } from \"./types\";\nimport { globMatches } from \"./images\";\n\n/** A variable name, as every forge reads one. */\nexport const VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\n\n/** Names the jobs set or drop themselves, which `env` and `pass` cannot take (chant's `prLoopPassedEnv` refuses them too). */\nexport const RESERVED_VARIABLES: readonly string[] = [\n \"GITHUB_TOKEN\", \"GITEA_TOKEN\", \"FORGEJO_TOKEN\", \"CI_JOB_TOKEN\", \"GITLAB_TOKEN\", \"CHANT_FORGE_TOKEN\",\n \"ACTIONS_ID_TOKEN_REQUEST_URL\", \"ACTIONS_ID_TOKEN_REQUEST_TOKEN\",\n \"BASE_SHA\", \"PR_NUMBER\", \"HEAD_SHA\", \"GREEN_SHA\", \"CHANT_RUN_EVENTS_DIR\", \"CHANT_RUNNER_KEY\",\n];\n\n/** One forge environment: its name as the forge spells it, and the URL its deployments show. */\nexport interface ForgeEnvironment {\n name: string;\n url?: string;\n}\n\n/** What the group hands src/jobs.ts. */\nexport interface JobSettings {\n /** `env`: plain variables. */\n variables: Record<string, string>;\n /** `pass`: variable to the forge secret it is read from. */\n secrets: Record<string, string>;\n parallelism?: number;\n /** `environments`, in file order: the first glob that matches a stack wins. */\n environments: Array<{ glob: string; environment: ForgeEnvironment }>;\n}\n\nconst environmentSchema: JsonSchema = {\n anyOf: [\n { type: \"string\", minLength: 1 },\n { type: \"object\", additionalProperties: false, required: [\"name\"], properties: { name: { type: \"string\", minLength: 1 }, url: { type: \"string\" } } },\n ],\n};\n\nfunction variableProblems(name: string, key: string): ConfigProblem[] {\n if (!VARIABLE.test(name)) return [error(key, `${JSON.stringify(name)} is not a variable name: letters, digits and _, not starting with a digit`)];\n if (RESERVED_VARIABLES.includes(name)) return [error(key, `${name} is a name the jobs set or drop themselves, and a forge token never reaches the code a preview runs; use another name`)];\n return [];\n}\n\n/** `pass` as variable to secret: a list passes each secret under its own name. */\nexport function passedSecrets(v: unknown): Record<string, string> {\n if (Array.isArray(v)) return Object.fromEntries(v.filter((s): s is string => typeof s === \"string\").map((s) => [s, s]));\n if (isObject(v)) return Object.fromEntries(Object.entries(v).filter((e): e is [string, string] => typeof e[1] === \"string\"));\n return {};\n}\n\n/** `environments` in file order. */\nexport function environmentsOf(v: unknown): JobSettings[\"environments\"] {\n if (!isObject(v)) return [];\n return Object.entries(v).flatMap(([glob, e]) => {\n if (typeof e === \"string\") return [{ glob, environment: { name: e } }];\n if (isObject(e) && typeof e.name === \"string\") return [{ glob, environment: { name: e.name, ...(typeof e.url === \"string\" ? { url: e.url } : {}) } }];\n return [];\n });\n}\n\n/** The group's settings, from a config that checked clean. */\nexport function jobSettingsOf(doc: Record<string, unknown>): JobSettings {\n const variables = isObject(doc.env) ? Object.fromEntries(Object.entries(doc.env).map(([k, v]) => [k, String(v)])) : {};\n return {\n variables,\n secrets: passedSecrets(doc.pass),\n ...(typeof doc.parallelism === \"number\" ? { parallelism: doc.parallelism } : {}),\n environments: environmentsOf(doc.environments),\n };\n}\n\nexport const jobs: ConfigGroup = {\n name: \"jobs\",\n keys: [\"env\", \"pass\", \"parallelism\", \"environments\"],\n schema: {\n env: {\n description: \"Variables every job runs with: the waves, the drift jobs and the pull request jobs. Values are written into the workflow, so put a secret under pass.\",\n type: \"object\",\n propertyNames: { pattern: VARIABLE.source },\n additionalProperties: { type: [\"string\", \"number\", \"boolean\"] },\n },\n pass: {\n description: \"Secrets the jobs read as variables, named and never written: a list of secret names, each passed under its own name, or a map of variable to secret.\",\n anyOf: [\n { type: \"array\", items: { type: \"string\", pattern: VARIABLE.source }, uniqueItems: true },\n { type: \"object\", propertyNames: { pattern: VARIABLE.source }, additionalProperties: { type: \"string\", pattern: VARIABLE.source } },\n ],\n },\n parallelism: {\n description: \"The most stacks a pull request previews at once in a wave, and the most a wave updates at once. Default: every stack of a wave at once in a preview, one at a time in an update.\",\n type: \"integer\",\n minimum: 1,\n },\n environments: {\n description: \"Stack glob to the forge deployment environment its update jobs run in (GitHub and GitLab): a name, or a map with name and url. The first glob that matches a stack wins; stacks of one wave in different environments run in one job each.\",\n type: \"object\",\n additionalProperties: environmentSchema,\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [];\n if (doc.env !== undefined) {\n if (!isObject(doc.env)) out.push(error(\"env\", \"must be a mapping of variable to value\"));\n else\n for (const [k, v] of Object.entries(doc.env)) {\n out.push(...variableProblems(k, `env.${k}`));\n if (![\"string\", \"number\", \"boolean\"].includes(typeof v)) out.push(error(`env.${k}`, \"must be a string, a number or true or false\"));\n }\n }\n if (doc.pass !== undefined) {\n if (!Array.isArray(doc.pass) && !isObject(doc.pass)) out.push(error(\"pass\", \"must be a list of secret names, or a mapping of variable to secret\"));\n else if (Array.isArray(doc.pass) && doc.pass.some((s) => typeof s !== \"string\")) out.push(error(\"pass\", \"must be a list of secret names\"));\n else if (isObject(doc.pass) && Object.values(doc.pass).some((s) => typeof s !== \"string\")) out.push(error(\"pass\", \"maps each variable to the name of a secret, never its value\"));\n else\n for (const [k, secret] of Object.entries(passedSecrets(doc.pass))) {\n out.push(...variableProblems(k, `pass.${k}`));\n if (!VARIABLE.test(secret)) out.push(error(`pass.${k}`, `${JSON.stringify(secret)} is not a secret name`));\n if (isObject(doc.env) && k in doc.env) out.push(error(`pass.${k}`, `${k} is under env too; a variable is a value or a passed secret, not both`));\n }\n }\n if (doc.parallelism !== undefined && !(typeof doc.parallelism === \"number\" && Number.isInteger(doc.parallelism) && doc.parallelism >= 1)) {\n out.push(error(\"parallelism\", \"must be a whole number of 1 or more\"));\n }\n if (doc.environments !== undefined) {\n if (!isObject(doc.environments)) out.push(error(\"environments\", \"must be a mapping of stack glob to environment\"));\n else {\n const forge = isObject(doc.forge) ? doc.forge.kind : undefined;\n if (forge === \"forgejo\") out.push(error(\"environments\", \"Forgejo has no deployment environments; leave environments out, or give forge.kind github or gitlab\"));\n const listed = isObject(doc.stacks) ? Object.keys(doc.stacks) : [];\n for (const [glob, e] of Object.entries(doc.environments)) {\n const named = typeof e === \"string\" ? e : isObject(e) ? e.name : undefined;\n if (typeof named !== \"string\" || named.trim() === \"\") out.push(error(`environments.${glob}`, \"must name the environment, as the forge spells it, or be a mapping with name and url\"));\n else if (isObject(e) && Object.keys(e).some((k) => k !== \"name\" && k !== \"url\")) out.push(error(`environments.${glob}`, \"takes name and url\"));\n if (listed.length > 0 && !listed.some((s) => globMatches(glob, s))) out.push(warning(`environments.${glob}`, \"matches no stack under stacks\"));\n }\n }\n }\n return out;\n },\n translate(doc, out) {\n const s = jobSettingsOf(doc);\n if (Object.keys(s.variables).length || Object.keys(s.secrets).length || s.parallelism !== undefined || s.environments.length) out.pipeline.jobs = s;\n },\n};\n", "/**\n * Keys reference/config.md lists whose groups land in later plywood units.\n * Each is accepted as written and not yet turned into chant's settings, so\n * a plywood.yml that sets one checks clean today and keeps working once the\n * group lands. A unit that builds one of these adds its group file under\n * src/config/ and takes the key out of LATER_KEYS.\n */\nimport type { ConfigGroup } from \"./types\";\n\nexport const LATER_KEYS: Readonly<Record<string, string>> = {};\n\nexport const later: ConfigGroup = {\n name: \"later\",\n keys: Object.keys(LATER_KEYS),\n schema: Object.fromEntries(Object.keys(LATER_KEYS).map((k) => [k, { description: \"Read by a later plywood; accepted as written.\" }])),\n check: () => [],\n translate() {},\n};\n", "/**\n * `locks`: when a pull request takes its locks and what one lock covers.\n *\n * locks.when preview (default) ci.locks plan from the first preview (plywood#2 ruling)\n * locks.when up ci.locks apply from an update before merge or a /plywood lock comment\n * locks.grain resource ci.lockGrain resource one lock per resource URN\n * locks.grain stack ci.lockGrain target one lock per stack\n * locks.grain absent (default) no ci.lockGrain each stack's engine decides:\n * resource on plunge, stack on\n * stock Pulumi (plywood#17)\n *\n * `ci.lockGrain` is chant#4552's key (ruling A). Under the resource grain a\n * pull request's target locks are its URN rows too (ruling D), so\n * `locks.when` and `locks.grain` together say what a pull request holds.\n * chant's `repo` grain has no plywood value.\n *\n * The default is per engine, and chant's pulumi lexicon holds it\n * (`pulumiDefaultLockGrain`): plunge keeps a record per resource, so two\n * updates to different resources of one stack run side by side, while stock\n * Pulumi's backend locks the whole stack and chant refuses the resource\n * grain on it by name. plywood therefore writes `ci.lockGrain` only when\n * plywood.yml sets `locks.grain`, and refuses `resource` on a stack it knows\n * runs stock Pulumi.\n */\nimport { engineOf, type Engine } from \"./engine\";\nimport { stacksOf } from \"./stacks\";\nimport { error, isObject, oneOf, onlyKeys, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\nimport type { ChantCiLocks, ChantLockGrain } from \"../chant-config\";\n\nexport const LOCKS_WHEN = [\"preview\", \"up\"] as const;\nexport type LocksWhen = (typeof LOCKS_WHEN)[number];\nexport const DEFAULT_LOCKS_WHEN: LocksWhen = \"preview\";\n\nexport const LOCK_GRAINS = [\"resource\", \"stack\"] as const;\nexport type LockGrain = (typeof LOCK_GRAINS)[number];\n/** The grain each engine takes when plywood.yml sets none, as chant's pulumi lexicon defaults it. */\nexport const DEFAULT_LOCK_GRAIN: Readonly<Record<Engine, LockGrain>> = { plunge: \"resource\", pulumi: \"stack\" };\n\n/** The grain a stack on `engine` takes; `undefined` engine is chant's to detect, so the grain follows it. */\nexport function lockGrainFor(doc: RawConfig, engine: Engine | undefined): LockGrain | \"per-engine\" {\n const set = locksOf(doc).grain;\n if (set) return set;\n return engine ? DEFAULT_LOCK_GRAIN[engine] : \"per-engine\";\n}\n\nexport const CI_LOCKS_OF: Readonly<Record<LocksWhen, ChantCiLocks>> = { preview: \"plan\", up: \"apply\" };\nexport const LOCK_GRAIN_OF: Readonly<Record<LockGrain, ChantLockGrain>> = { resource: \"resource\", stack: \"target\" };\n\n/** `locks` as read; `grain` is undefined when plywood.yml leaves it to each stack's engine. */\nexport function locksOf(doc: RawConfig): { when: LocksWhen; grain?: LockGrain } {\n const l = isObject(doc.locks) ? doc.locks : {};\n return {\n when: l.when === \"up\" ? \"up\" : DEFAULT_LOCKS_WHEN,\n ...(l.grain === \"stack\" || l.grain === \"resource\" ? { grain: l.grain } : {}),\n };\n}\n\n/** The stacks plywood.yml puts on stock Pulumi: `engine: pulumi`, with no plunge backend of their own. */\nfunction stockStacks(doc: RawConfig): string[] {\n if (doc.engine !== \"pulumi\") return [];\n const named = Object.keys(stacksOf(doc)).filter((n) => engineOf(doc, stacksOf(doc)[n]?.backend)?.engine === \"pulumi\");\n return named.length ? named : [\"every stack\"];\n}\n\nexport const locks: ConfigGroup = {\n name: \"locks\",\n keys: [\"locks\"],\n schema: {\n locks: {\n type: \"object\",\n additionalProperties: false,\n properties: {\n when: { type: \"string\", enum: [...LOCKS_WHEN], default: DEFAULT_LOCKS_WHEN, description: \"preview, from the first preview, or up, from an update before merge or a /plywood lock comment.\" },\n grain: { type: \"string\", enum: [...LOCK_GRAINS], description: \"resource, one lock per resource, or stack, one lock per stack. Absent, resource on plunge and stack on stock Pulumi.\" },\n },\n },\n },\n check(doc) {\n if (doc.locks === undefined) return [];\n if (!isObject(doc.locks)) return [error(\"locks\", \"must be a mapping\")];\n const out: ConfigProblem[] = [...onlyKeys(doc.locks, [\"when\", \"grain\"], \"locks\"), ...oneOf(doc.locks.when, LOCKS_WHEN, \"locks.when\"), ...oneOf(doc.locks.grain, LOCK_GRAINS, \"locks.grain\")];\n if (doc.locks.grain === \"resource\") {\n const stock = stockStacks(doc);\n if (stock.length) {\n out.push(error(\"locks.grain\", `is resource and engine is pulumi (${stock.join(\", \")}): stock Pulumi's backend locks the whole stack, so chant locks it per stack. Leave locks.grain out, or set engine: plunge`));\n }\n }\n return out;\n },\n translate(doc, out) {\n const { when, grain } = locksOf(doc);\n out.ci.locks = CI_LOCKS_OF[when];\n if (grain) out.ci.lockGrain = LOCK_GRAIN_OF[grain];\n },\n};\n", "/**\n * `notify`, `telemetry` and `reports`: who hears about a run, where its trace\n * goes, and where its report is kept (plywood#20).\n *\n * notify.slack.webhook the variable holding a Slack incoming webhook URL\n * notify.teams.webhook the same for Microsoft Teams\n * notify.webhook { url, key }: the variables holding a generic\n * webhook's URL and the key its events are signed with\n * notify.on wave-waiting, up-refused, up-failed, drift\n * (default: all four)\n * notify.relay the variable holding the relay key: a waiting\n * wave's Slack message gets Approve and Decline\n * buttons, and its Teams card the reply that\n * approves, which `plywood notify relay` receives\n * and records on the ledger (chant#4611)\n * -> the waves spec's `notify` (chant `NotifyConfig`, chant#3761): each\n * event is a `chant.notify/v1` message, signed for the generic webhook,\n * with `source: plywood` and plywood's summary (the words' `notify`\n * slot, chant#4610)\n *\n * telemetry.endpoint the OTLP/HTTP base URL; chant adds /v1/traces\n * telemetry.headers_env the variable holding OTLP headers (k=v,k2=v2)\n * telemetry.service_name OTEL_SERVICE_NAME, default plywood\n * telemetry.traces false turns traces off\n * -> the OTEL_* variables chant's exporter reads (chant#4555), set by\n * plywood's bin before it calls chant (src/telemetry.ts); a variable\n * the job already sets wins. Span attributes carry the `plywood.`\n * prefix from plywood's words.\n *\n * reports.url ci.reportUrl: s3://, gs://, az:// or file://, where\n * chant keeps each run's HTML report (chant#4554)\n *\n * Every secret is named by its variable, never written in plywood.yml.\n */\nimport { error, isObject, onlyKeys, warning, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\n/** plywood's notify event words and chant's (`NOTIFY_EVENTS`). */\nexport const NOTIFY_EVENTS = { \"wave-waiting\": \"waiting\", \"up-refused\": \"refused\", \"up-failed\": \"failed\", drift: \"drift\" } as const;\nexport type NotifyWord = keyof typeof NOTIFY_EVENTS;\nexport type ChantNotifyEvent = (typeof NOTIFY_EVENTS)[NotifyWord];\n\n/** chant's `NotifyConfig`: every value names a variable. */\nexport interface ChantNotifyConfig {\n webhook?: string;\n key?: string;\n slack?: string;\n teams?: string;\n events?: ChantNotifyEvent[];\n /** The variable holding the relay key (chant#4611). A chant before it refuses the setting, so plywood init leaves it out there ({@link notifyForChant}). */\n relay?: string;\n}\n\n/**\n * The notify config for the installed chant: `relay` only when chant has\n * the relay (`NOTIFY_RELAY_FLOOR` on @intentius/chant/ci-product), since an\n * older chant refuses a setting it does not know.\n */\nexport function notifyForChant(notify: ChantNotifyConfig, chant: { NOTIFY_RELAY_FLOOR?: string } | undefined): ChantNotifyConfig {\n if (notify.relay === undefined || typeof chant?.NOTIFY_RELAY_FLOOR === \"string\") return { ...notify };\n const { relay: _relay, ...rest } = notify;\n return rest;\n}\n\nexport interface TelemetrySettings {\n endpoint?: string;\n headersEnv?: string;\n serviceName: string;\n traces: boolean;\n}\n\nconst VARIABLE = /^[A-Za-z_][A-Za-z0-9_]*$/;\nexport const DEFAULT_SERVICE_NAME = \"plywood\";\n\n/** The report URL schemes chant reads (`pr-report-url`); gs:// and az:// need chant#4554. */\nexport const REPORT_SCHEMES = [\"s3\", \"gs\", \"az\", \"file\"] as const;\nconst NEWER_SCHEMES = new Set([\"gs\", \"az\"]);\n\nfunction variable(v: unknown, key: string): ConfigProblem[] {\n if (v === undefined) return [];\n return typeof v === \"string\" && VARIABLE.test(v) ? [] : [error(key, \"names an environment variable, such as SLACK_WEBHOOK_URL; the URL or key itself never goes in plywood.yml\")];\n}\n\n/** chant's notify config for plywood.yml, or undefined when it sets none. */\nexport function chantNotifyOf(doc: RawConfig): ChantNotifyConfig | undefined {\n const n = doc.notify;\n if (!isObject(n)) return undefined;\n const slack = isObject(n.slack) ? n.slack.webhook : undefined;\n const teams = isObject(n.teams) ? n.teams.webhook : undefined;\n const hook = isObject(n.webhook) ? n.webhook : {};\n const on = Array.isArray(n.on) ? (n.on as string[]).filter((w): w is NotifyWord => w in NOTIFY_EVENTS) : undefined;\n const out: ChantNotifyConfig = {\n ...(typeof hook.url === \"string\" ? { webhook: hook.url } : {}),\n ...(typeof hook.key === \"string\" ? { key: hook.key } : {}),\n ...(typeof slack === \"string\" ? { slack } : {}),\n ...(typeof teams === \"string\" ? { teams } : {}),\n ...(on ? { events: [...new Set(on.map((w) => NOTIFY_EVENTS[w]))] } : {}),\n ...(typeof n.relay === \"string\" ? { relay: n.relay } : {}),\n };\n return out.webhook || out.slack || out.teams ? out : undefined;\n}\n\n/** plywood.yml's telemetry, with its defaults. */\nexport function telemetryOf(doc: RawConfig): TelemetrySettings {\n const t = isObject(doc.telemetry) ? doc.telemetry : {};\n return {\n ...(typeof t.endpoint === \"string\" ? { endpoint: t.endpoint.replace(/\\/+$/, \"\") } : {}),\n ...(typeof t.headers_env === \"string\" ? { headersEnv: t.headers_env } : {}),\n serviceName: typeof t.service_name === \"string\" ? t.service_name : DEFAULT_SERVICE_NAME,\n traces: t.traces !== false,\n };\n}\n\nconst WEBHOOK_VAR = { type: \"object\", additionalProperties: false, required: [\"webhook\"], properties: { webhook: { type: \"string\", pattern: VARIABLE.source, description: \"The variable holding the incoming webhook's URL.\" } } };\n\nexport const observe: ConfigGroup = {\n name: \"notify, telemetry and reports\",\n keys: [\"notify\", \"telemetry\", \"reports\"],\n schema: {\n notify: {\n type: \"object\",\n additionalProperties: false,\n description: \"Chat and webhook messages when a wave waits, an update is refused or fails, or drift is found. Each value names a variable.\",\n properties: {\n slack: WEBHOOK_VAR,\n teams: WEBHOOK_VAR,\n webhook: {\n type: \"object\",\n additionalProperties: false,\n required: [\"url\", \"key\"],\n description: \"A generic webhook; each chant.notify/v1 event is signed with the key.\",\n properties: {\n url: { type: \"string\", pattern: VARIABLE.source, description: \"The variable holding the webhook's URL.\" },\n key: { type: \"string\", pattern: VARIABLE.source, description: \"The variable holding the signing key.\" },\n },\n },\n on: { type: \"array\", items: { type: \"string\", enum: Object.keys(NOTIFY_EVENTS) }, description: \"The events to send. Default: all of them.\" },\n relay: { type: \"string\", pattern: VARIABLE.source, description: \"The variable holding the relay key. A waiting wave's Slack and Teams messages then carry the approval that plywood notify relay records.\" },\n },\n },\n telemetry: {\n type: \"object\",\n additionalProperties: false,\n description: \"One OpenTelemetry trace per run over OTLP/HTTP, with a span per stack. OTEL_* variables in the job win over these.\",\n properties: {\n endpoint: { type: \"string\", description: \"The OTLP/HTTP base URL; /v1/traces is added.\" },\n headers_env: { type: \"string\", pattern: VARIABLE.source, description: \"The variable holding the OTLP headers, k=v,k2=v2.\" },\n service_name: { type: \"string\", default: DEFAULT_SERVICE_NAME, description: \"The trace's service.name.\" },\n traces: { type: \"boolean\", default: true, description: \"false turns traces off.\" },\n },\n },\n reports: {\n type: \"object\",\n additionalProperties: false,\n required: [\"url\"],\n description: \"Where each run's HTML report is kept.\",\n properties: { url: { type: \"string\", description: \"s3://<bucket>/<prefix>, gs://<bucket>/<prefix>, az://<account>/<container>/<prefix> or file://<dir>.\" } },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [];\n const n = doc.notify;\n if (n !== undefined) {\n if (!isObject(n)) out.push(error(\"notify\", \"must be a mapping of slack, teams, webhook and on\"));\n else {\n out.push(...onlyKeys(n, [\"slack\", \"teams\", \"webhook\", \"on\", \"relay\"], \"notify\"));\n if (n.relay !== undefined) {\n out.push(...variable(n.relay, \"notify.relay\"));\n // The relay answers a click in Slack or a reply in Teams; the generic webhook has neither.\n if (n.slack === undefined && n.teams === undefined) out.push(error(\"notify.relay\", \"needs notify.slack or notify.teams: approvals come back from a chat message\"));\n else out.push(warning(\"notify.relay\", \"needs chant >= the release after 0.124.54 (chant#4611); plywood init leaves it out of the waves spec on a chant without the relay\"));\n }\n for (const chat of [\"slack\", \"teams\"] as const) {\n const c = n[chat];\n if (c === undefined) continue;\n if (!isObject(c)) out.push(error(`notify.${chat}`, \"is { webhook: <variable> }\"));\n else out.push(...onlyKeys(c, [\"webhook\"], `notify.${chat}`), ...(c.webhook === undefined ? [error(`notify.${chat}.webhook`, \"is required\")] : variable(c.webhook, `notify.${chat}.webhook`)));\n }\n if (n.webhook !== undefined) {\n if (!isObject(n.webhook)) out.push(error(\"notify.webhook\", \"is { url: <variable>, key: <variable> }\"));\n else {\n out.push(...onlyKeys(n.webhook, [\"url\", \"key\"], \"notify.webhook\"), ...variable(n.webhook.url, \"notify.webhook.url\"), ...variable(n.webhook.key, \"notify.webhook.key\"));\n // chant never posts an unsigned event to a generic webhook.\n for (const k of [\"url\", \"key\"] as const) if (n.webhook[k] === undefined) out.push(error(`notify.webhook.${k}`, \"is required: the generic webhook's events are always signed\"));\n }\n }\n if (n.on !== undefined) {\n if (!Array.isArray(n.on) || n.on.length === 0) out.push(error(\"notify.on\", `is a list of ${Object.keys(NOTIFY_EVENTS).join(\", \")}`));\n else for (const w of n.on) if (typeof w !== \"string\" || !(w in NOTIFY_EVENTS)) out.push(error(\"notify.on\", `has ${JSON.stringify(w)}; the events are ${Object.keys(NOTIFY_EVENTS).join(\", \")}`));\n }\n if (isObject(n) && n.slack === undefined && n.teams === undefined && n.webhook === undefined) out.push(error(\"notify\", \"names no slack, teams or webhook\"));\n }\n }\n const t = doc.telemetry;\n if (t !== undefined) {\n if (!isObject(t)) out.push(error(\"telemetry\", \"must be a mapping of endpoint, headers_env, service_name and traces\"));\n else {\n out.push(...onlyKeys(t, [\"endpoint\", \"headers_env\", \"service_name\", \"traces\"], \"telemetry\"), ...variable(t.headers_env, \"telemetry.headers_env\"));\n if (t.endpoint !== undefined && (typeof t.endpoint !== \"string\" || !/^https?:\\/\\/\\S+$/.test(t.endpoint))) out.push(error(\"telemetry.endpoint\", \"must be an http or https URL\"));\n if (typeof t.endpoint === \"string\" && /@|[?&](?:token|key)=/i.test(t.endpoint)) out.push(error(\"telemetry.endpoint\", \"carries a credential; put it in the variable telemetry.headers_env names\"));\n if (t.service_name !== undefined && (typeof t.service_name !== \"string\" || t.service_name === \"\")) out.push(error(\"telemetry.service_name\", \"must be a string\"));\n if (t.traces !== undefined && typeof t.traces !== \"boolean\") out.push(error(\"telemetry.traces\", \"is true or false\"));\n }\n }\n const r = doc.reports;\n if (r !== undefined) {\n if (!isObject(r)) out.push(error(\"reports\", \"is { url }\"));\n else {\n out.push(...onlyKeys(r, [\"url\"], \"reports\"));\n const scheme = typeof r.url === \"string\" ? /^([a-z0-9]+):\\/\\/\\S+$/.exec(r.url)?.[1] : undefined;\n if (!scheme || !(REPORT_SCHEMES as readonly string[]).includes(scheme)) out.push(error(\"reports.url\", `is a ${REPORT_SCHEMES.map((s) => `${s}://`).join(\", \")} URL`));\n else if (NEWER_SCHEMES.has(scheme)) out.push(warning(\"reports.url\", `${scheme}:// reports need chant >= the release after 0.124.54 (chant#4554); the pinned chant takes s3:// and file://`));\n }\n }\n return out;\n },\n translate(doc, out) {\n const notify = chantNotifyOf(doc);\n if (notify) out.pipeline.notify = notify;\n if (isObject(doc.reports) && typeof doc.reports.url === \"string\") out.ci.reportUrl = doc.reports.url;\n },\n};\n", "/**\n * `policy`: Rego rules over the change set and CrossGuard policy packs, both\n * in the preview job and both feeding chant's gate (plywood#13, ruling 7).\n *\n * policy.rego ci.policy.path a directory of Rego rules, read at base\n * policy.engine ci.policy.engine conftest (default) or opa, the result shape\n * policy.namespace ci.policy.namespace\n * policy.command ci.policy.command argv in place of the engine's own\n * policy.packs each stack's pulumi-up step `policyPacks` (chant#4541):\n * the preview and the update run `--policy-pack <dir>`;\n * on a chant with chant#4613 also ci.policy.packs, read\n * at base, so a pull request cannot drop or edit a pack\n * policy.source ci.policy.source { repo, ref, path } (chant#4613): a\n * shared rule set from a git ref, fetched by the job at\n * the ref the base names. `path` is the Rego directory\n * inside it; `packs` are then paths inside it too.\n *\n * chant reads the Rego rules from the declaration at base (chant#4294), so a\n * rule changed on the head branch does nothing to its own pull request. A\n * `deny` rule denies the preview and a `hold` rule waits for a person; there\n * is no unattended outcome, since a non-empty change always waits for one.\n *\n * A CrossGuard pack's `mandatory` violations deny and its `advisory` ones are\n * note lines: chant's pulumi lexicon reads both from the streamed preview\n * (`pulumiPolicyFindings`, chant#4541) and names each rule\n * `crossguard.<pack>.<policy>`, the id `plywood override --rule` takes.\n * Either kind of denial exits with chant's `denied` code, 7.\n *\n * `source` and `ci.policy.packs` need chant's policy source\n * (`@intentius/chant/policy-source`, `CI_POLICY_SOURCE_FLOOR`). The config\n * translation is synchronous, so the CLI awaits {@link useChantPolicySource}\n * once before a command. On a chant without it (the 0.124.54 pin) `source`\n * is refused as before and packs ride in the step input alone.\n */\nimport { posix } from \"node:path\";\nimport { error, isObject, oneOf, onlyKeys, type ConfigGroup, type ConfigProblem, type RawConfig } from \"./types\";\n\n/** chant's result shapes (`GATE_POLICY_ENGINES`, @intentius/chant/gate-policy). */\nexport const POLICY_ENGINES = [\"conftest\", \"opa\"] as const;\nexport type PolicyEngine = (typeof POLICY_ENGINES)[number];\n\nexport const POLICY_KEYS = [\"rego\", \"engine\", \"namespace\", \"command\", \"packs\", \"source\", \"providers\"] as const;\nexport const PACK_KEYS = [\"dir\", \"config\"] as const;\nexport const SOURCE_KEYS = [\"repo\", \"ref\", \"path\"] as const;\n\n/** chant's accepted repository forms for `ci.policy.source.repo` (policy-source.ts). */\nconst SOURCE_REPO = /^(https?:\\/\\/[^\\s/]+\\/\\S+|ssh:\\/\\/[^\\s/]+\\/\\S+|file:\\/\\/\\/?\\S+|[A-Za-z0-9._-]+@[A-Za-z0-9.-]+:\\S+)$/;\nconst SOURCE_REF = /^[A-Za-z0-9][A-Za-z0-9._/-]*$/;\n\nlet policySource = false;\nlet policySourceLoading: Promise<boolean> | undefined;\n\n/** True when the installed chant reads `ci.policy.source` and `ci.policy.packs` (chant#4613). */\nexport function useChantPolicySource(): Promise<boolean> {\n policySourceLoading ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4613).\n const m: Record<string, unknown> = await import(\"@intentius/chant/policy-source\");\n policySource = typeof m.CI_POLICY_SOURCE_FLOOR === \"string\" && typeof m.assertGatePolicySource === \"function\";\n } catch {\n policySource = false;\n }\n return policySource;\n })();\n return policySourceLoading;\n}\n\n/** Whether {@link useChantPolicySource} found chant's policy source. */\nexport function chantHasPolicySource(): boolean {\n return policySource;\n}\n\n/** Tests say whether chant has the policy source. `reset` forgets it and the import. */\nexport function setChantPolicySourceForTests(has: boolean | \"reset\"): void {\n policySource = has === true;\n policySourceLoading = has === \"reset\" ? undefined : Promise.resolve(has === true);\n}\n\n/** Keys a reader of terragucci's `policy` or Pulumi Deployments may reach for, and why plywood has none. */\nconst NO_SUCH_KEY: Readonly<Record<string, string>> = {\n allow_unattended: \"chant's gate denies and holds only; a non-empty change always waits for a person, so there is no unattended outcome\",\n outcomes: \"a Rego rule's name sets its outcome: deny_* denies, hold_* holds, warn_* is a note line\",\n};\n\n/** Why `policy.source` is refused on a chant without chant#4613. */\nconst SOURCE_NEEDS_CHANT =\n \"is a shared policy source from a git ref, which needs chant >= the release after 0.124.54 (chant#4613's ci.policy.source); on this chant, vendor the rules into the repository, where they are read at base\";\n\n/** chant's `ci.policy.source` (`GatePolicySource`, chant#4613). */\nexport interface ChantPolicySource {\n repo: string;\n ref: string;\n path?: string;\n}\n\n/** chant's `ci.policy` (`GatePolicySettings`). */\nexport interface ChantPolicySettings {\n engine?: PolicyEngine;\n path?: string;\n namespace?: string;\n command?: string[];\n /** The shared source, read at the ref the base names (chant#4613). */\n source?: ChantPolicySource;\n /** CrossGuard packs every preview runs, read at base or from `source` (chant#4613). */\n packs?: PolicyPack[];\n}\n\n/** One CrossGuard pack, as the pulumi-up step takes it (chant `PulumiPolicyPack`). */\nexport interface PolicyPack {\n dir: string;\n config?: string;\n}\n\n/** A path inside the repository, relative to its root: no leading `/`, no `..`, not a flag. */\nfunction repoPath(v: unknown, key: string): ConfigProblem[] {\n if (typeof v !== \"string\" || v.trim() === \"\") return [error(key, \"is a path inside the repository\")];\n if (v.startsWith(\"/\") || v.startsWith(\"-\") || v.split(\"/\").includes(\"..\")) return [error(key, `is ${JSON.stringify(v)}; give a path relative to the repository root, inside it`)];\n return [];\n}\n\n/** A path with `./` and trailing slashes taken off, as chant compares paths. */\nexport function cleanPath(p: string): string {\n const out = posix.normalize(p).replace(/\\/+$/, \"\");\n return out === \"\" ? \".\" : out;\n}\n\n/** The packs plywood.yml lists, each as `{ dir, config? }`. */\nexport function policyPacksOf(doc: RawConfig): PolicyPack[] {\n const packs = isObject(doc.policy) && Array.isArray(doc.policy.packs) ? doc.policy.packs : [];\n return packs.flatMap((p): PolicyPack[] => {\n if (typeof p === \"string\") return [{ dir: cleanPath(p) }];\n if (isObject(p) && typeof p.dir === \"string\") return [{ dir: cleanPath(p.dir), ...(typeof p.config === \"string\" ? { config: cleanPath(p.config) } : {}) }];\n return [];\n });\n}\n\n/**\n * A stack's packs with each path relative to the stack's directory, since\n * the engine runs there: `policy/guard` for a stack in `infra` is\n * `../policy/guard`.\n */\nexport function packsForStack(packs: readonly PolicyPack[], stackDir: string): PolicyPack[] {\n const from = cleanPath(stackDir);\n const rel = (p: string): string => {\n const r = posix.relative(from === \".\" ? \"\" : from, p);\n // A path the engine reads as a flag never reaches it; ./ keeps it a path.\n return r === \"\" ? \".\" : r.startsWith(\"-\") ? `./${r}` : r;\n };\n return packs.map((p) => ({ dir: rel(p.dir), ...(p.config ? { config: rel(p.config) } : {}) }));\n}\n\n/** plywood.yml's `policy.providers`: the provider packages the preset allows, or undefined when it sets none. */\nexport function policyProvidersOf(doc: RawConfig): string[] | undefined {\n const list = isObject(doc.policy) ? doc.policy.providers : undefined;\n return Array.isArray(list) && list.length > 0 ? list.filter((s): s is string => typeof s === \"string\") : undefined;\n}\n\n/** plywood.yml's `policy.source` as chant's, or undefined. */\nexport function policySourceOf(doc: RawConfig): ChantPolicySource | undefined {\n const src = isObject(doc.policy) ? doc.policy.source : undefined;\n if (!isObject(src) || typeof src.repo !== \"string\" || typeof src.ref !== \"string\") return undefined;\n return { repo: src.repo, ref: src.ref, ...(typeof src.path === \"string\" ? { path: cleanPath(src.path) } : {}) };\n}\n\n/**\n * chant's `ci.policy` for plywood.yml's policy keys, or undefined when it\n * sets none. `chantReadsSource` (default: what {@link useChantPolicySource}\n * found) adds `source` and lists the packs in `packs`; without it the packs\n * ride in each step's input alone.\n */\nexport function chantPolicyOf(doc: RawConfig, chantReadsSource = chantHasPolicySource()): ChantPolicySettings | undefined {\n const p = doc.policy;\n if (!isObject(p)) return undefined;\n const rego = typeof p.rego === \"string\" ? cleanPath(p.rego) : undefined;\n const command = Array.isArray(p.command) ? (p.command as string[]) : undefined;\n const source = chantReadsSource ? policySourceOf(doc) : undefined;\n const packs = chantReadsSource ? policyPacksOf(doc) : [];\n if (rego === undefined && command === undefined && p.engine === undefined && p.namespace === undefined && !source && packs.length === 0) return undefined;\n return {\n ...(typeof p.engine === \"string\" ? { engine: p.engine as PolicyEngine } : {}),\n ...(rego !== undefined ? { path: rego } : {}),\n ...(typeof p.namespace === \"string\" ? { namespace: p.namespace } : {}),\n ...(command ? { command } : {}),\n ...(source ? { source } : {}),\n ...(packs.length ? { packs } : {}),\n };\n}\n\n/**\n * The packs each stack's step input carries. With a shared source the packs\n * are paths inside that repository, which chant reads from `ci.policy.packs`\n * alone; otherwise the step carries them too (chant reads a pack listed in\n * both once, from base).\n */\nexport function stepPolicyPacksOf(doc: RawConfig, chantReadsSource = chantHasPolicySource()): PolicyPack[] {\n return chantReadsSource && policySourceOf(doc) ? [] : policyPacksOf(doc);\n}\n\nexport const policy: ConfigGroup = {\n name: \"policy\",\n keys: [\"policy\"],\n schema: {\n policy: {\n type: \"object\",\n additionalProperties: false,\n description: \"Rego rules and CrossGuard policy packs in the preview job, feeding chant's gate. Read at base.\",\n properties: {\n rego: { type: \"string\", description: \"The directory of Rego rules, relative to the repository root. deny_* denies, hold_* waits for a person, warn_* is a note line.\" },\n engine: { type: \"string\", enum: [...POLICY_ENGINES], default: \"conftest\", description: \"The result shape the rules' engine prints: conftest or opa. A hold needs opa.\" },\n namespace: { type: \"string\", description: \"The Rego package to read. conftest: every package; opa: main.\" },\n command: { type: \"array\", items: { type: \"string\" }, minItems: 1, description: \"argv in place of the engine's own; {policy} is the rules' directory at base, {input} the change set.\" },\n source: {\n type: \"object\",\n additionalProperties: false,\n required: [\"repo\", \"ref\"],\n description: \"A shared rule set from a git ref, fetched by the job at the ref the base names (chant >= the release after 0.124.54). packs are then paths inside it.\",\n properties: {\n repo: { type: \"string\", description: \"The repository: https://, ssh:// or file:// URL, or git@<host>:<path>.\" },\n ref: { type: \"string\", description: \"A tag, a branch or a full commit.\" },\n path: { type: \"string\", default: \"policy\", description: \"The Rego directory inside the repository.\" },\n },\n },\n providers: {\n type: \"array\",\n items: { type: \"string\", pattern: \"^[a-z][a-z0-9-]*$\" },\n uniqueItems: true,\n description: \"The provider packages a stack may use, such as aws and random; component packages too. plywood init writes the allowlist as a Rego rule into policy.rego and as the CrossGuard pack policy/plywood-providers.\",\n },\n packs: {\n type: \"array\",\n description: \"CrossGuard packs the preview and the update run with --policy-pack. Mandatory violations deny; advisory ones are note lines.\",\n items: {\n oneOf: [\n { type: \"string\", description: \"The pack's directory, relative to the repository root.\" },\n {\n type: \"object\",\n additionalProperties: false,\n required: [\"dir\"],\n properties: {\n dir: { type: \"string\", description: \"The pack's directory, relative to the repository root.\" },\n config: { type: \"string\", description: \"Its --policy-pack-config file.\" },\n },\n },\n ],\n },\n },\n },\n },\n },\n check(doc) {\n const p = doc.policy;\n if (p === undefined) return [];\n if (!isObject(p)) return [error(\"policy\", \"must be a mapping of rego and packs\")];\n const out: ConfigProblem[] = [];\n for (const k of Object.keys(p)) if (k in NO_SUCH_KEY) out.push(error(`policy.${k}`, `is not a plywood key: ${NO_SUCH_KEY[k]}`));\n if (p.source !== undefined) {\n if (!chantHasPolicySource()) out.push(error(\"policy.source\", SOURCE_NEEDS_CHANT));\n else if (!isObject(p.source)) out.push(error(\"policy.source\", \"is { repo, ref, path }\"));\n else {\n const src = p.source;\n out.push(...onlyKeys(src, SOURCE_KEYS, \"policy.source\"));\n if (typeof src.repo !== \"string\" || !SOURCE_REPO.test(src.repo) || src.repo.startsWith(\"-\")) out.push(error(\"policy.source.repo\", \"is a git URL: https://, ssh://, file:// or git@<host>:<path>\"));\n if (typeof src.ref !== \"string\" || !SOURCE_REF.test(src.ref) || src.ref.includes(\"..\") || src.ref.endsWith(\"/\")) out.push(error(\"policy.source.ref\", \"is a tag, a branch or a commit\"));\n if (src.path !== undefined) out.push(...repoPath(src.path, \"policy.source.path\"));\n // chant takes the Rego directory from the source's path, so a workspace directory beside it would be read nowhere.\n if (p.rego !== undefined) out.push(error(\"policy.rego\", \"goes with no policy.source: with a source, policy.source.path names the Rego directory inside it\"));\n }\n }\n out.push(...onlyKeys(Object.fromEntries(Object.entries(p).filter(([k]) => !(k in NO_SUCH_KEY))), POLICY_KEYS, \"policy\"));\n if (p.rego !== undefined) out.push(...repoPath(p.rego, \"policy.rego\"));\n out.push(...oneOf(p.engine, POLICY_ENGINES, \"policy.engine\"));\n if (p.namespace !== undefined && (typeof p.namespace !== \"string\" || p.namespace.trim() === \"\")) out.push(error(\"policy.namespace\", \"is a Rego package name\"));\n if (p.command !== undefined) {\n if (!Array.isArray(p.command) || p.command.length === 0 || p.command.some((a) => typeof a !== \"string\" || a === \"\")) out.push(error(\"policy.command\", \"is argv, a list of strings\"));\n else if (!p.command.some((a: string) => a.includes(\"{input}\"))) out.push(error(\"policy.command\", \"must pass the change set as {input}\"));\n }\n if (p.providers !== undefined) {\n if (!Array.isArray(p.providers) || p.providers.length === 0) out.push(error(\"policy.providers\", \"is a list of provider packages, such as [aws, random]\"));\n else\n p.providers.forEach((name, i) => {\n if (typeof name !== \"string\" || !/^[a-z][a-z0-9-]*$/.test(name)) out.push(error(`policy.providers.${i}`, `is ${JSON.stringify(name)}; a provider package is a Pulumi type's first segment, such as aws`));\n });\n }\n if (p.packs !== undefined) {\n if (!Array.isArray(p.packs)) out.push(error(\"policy.packs\", \"is a list of pack directories\"));\n else {\n p.packs.forEach((pack, i) => {\n const key = `policy.packs.${i}`;\n if (typeof pack === \"string\") out.push(...repoPath(pack, key));\n else if (isObject(pack)) {\n out.push(...onlyKeys(pack, PACK_KEYS, key), ...repoPath(pack.dir, `${key}.dir`));\n if (pack.config !== undefined) out.push(...repoPath(pack.config, `${key}.config`));\n } else out.push(error(key, \"is a pack directory, or { dir, config }\"));\n });\n const dirs = policyPacksOf(doc).map((x) => x.dir);\n const twice = dirs.filter((d, i) => dirs.indexOf(d) !== i);\n if (twice.length) out.push(error(\"policy.packs\", `lists ${[...new Set(twice)].join(\", \")} more than once`));\n }\n }\n return out;\n },\n translate(doc, out) {\n const rego = chantPolicyOf(doc);\n if (rego) out.ci.policy = rego;\n const packs = stepPolicyPacksOf(doc);\n if (packs.length) out.pipeline.policyPacks = packs;\n },\n};\n", "/**\n * `review_stacks`: a stack per open pull request, made from a template\n * stack's config and destroyed when the pull request closes or its TTL\n * passes. It becomes chant's `ci.prEnvironment` (template, ttl); the name\n * pattern goes to the pipeline. Only stacks the pattern names are destroyed,\n * and the pattern is chant's review stack name, `pr-{number}` with an\n * optional suffix, so chant's pulumi lexicon runs `destroy` and `stack rm`\n * on no other stack (src/review-stacks.ts).\n */\nimport { error, isObject, onlyKeys, warning, type ConfigGroup, type ConfigProblem } from \"./types\";\n\nexport const DEFAULT_REVIEW_STACK_NAME = \"pr-{number}\";\nconst TTL = /^\\d+[mhd]$/;\n/** The names chant creates and removes (`REVIEW_STACK_NAME`, chant's pulumi lexicon): pr-{number}, or pr-{number}-<suffix>. */\nexport const REVIEW_STACK_NAME = /^pr-\\{number\\}(?:-[a-z0-9][a-z0-9-]*)?$/;\nconst STACK_KEY = /^[^/\\s]+\\/[^/\\s]+$/;\n\n/** The review stack's name for pull request `pr`, from plywood.yml's pattern. */\nexport function reviewStackName(pattern: string, pr: number | string): string {\n return pattern.replace(\"{number}\", String(pr));\n}\n\nexport const reviewStacks: ConfigGroup = {\n name: \"review_stacks\",\n keys: [\"review_stacks\"],\n schema: {\n review_stacks: {\n type: \"object\",\n additionalProperties: false,\n required: [\"template\"],\n description: \"A stack per open pull request. Off when absent.\",\n properties: {\n template: { type: \"string\", description: \"The stack whose config a review stack starts from, as project/stack.\" },\n name: { type: \"string\", pattern: REVIEW_STACK_NAME.source, default: DEFAULT_REVIEW_STACK_NAME, description: \"The review stack's name: pr-{number}, or pr-{number}-<suffix>. Only stacks named so are destroyed.\" },\n ttl: { type: \"string\", pattern: TTL.source, description: \"How long a review stack lives after its last update, such as 72h. chant's default when absent.\" },\n },\n },\n },\n check(doc) {\n const r = doc.review_stacks;\n if (r === undefined) return [];\n if (!isObject(r)) return [error(\"review_stacks\", \"must be a mapping with a template\")];\n const out: ConfigProblem[] = [...onlyKeys(r, [\"template\", \"name\", \"ttl\"], \"review_stacks\")];\n if (typeof r.template !== \"string\" || !STACK_KEY.test(r.template)) out.push(error(\"review_stacks.template\", \"names the template stack as project/stack\"));\n else if (isObject(doc.stacks) && !(r.template in doc.stacks)) out.push(warning(\"review_stacks.template\", `is ${r.template}, which stacks does not list; its config is copied from the backend as it stands`));\n if (r.name !== undefined && (typeof r.name !== \"string\" || !REVIEW_STACK_NAME.test(r.name))) {\n out.push(error(\"review_stacks.name\", \"is pr-{number} or pr-{number}-<suffix>: chant creates, destroys and removes stacks named so and no others\"));\n }\n if (r.ttl !== undefined && (typeof r.ttl !== \"string\" || !TTL.test(r.ttl))) out.push(error(\"review_stacks.ttl\", \"is a duration such as 30m, 72h or 7d\"));\n return out;\n },\n translate(doc, out) {\n const r = doc.review_stacks;\n if (!isObject(r)) return;\n out.ci.prEnvironment = { template: r.template as string, ...(typeof r.ttl === \"string\" ? { ttl: r.ttl } : {}) };\n out.pipeline.reviewStackName = typeof r.name === \"string\" ? r.name : DEFAULT_REVIEW_STACK_NAME;\n },\n};\n", "/**\n * `branches`, `labels` and `forge`: which branch updates which stacks, which\n * label narrows a pull request's previews, and the forge the jobs talk to.\n *\n * branches branch to stack globs ci.branches\n * labels label to stack globs ci.labels (never a gate)\n * forge kind and url the pipeline's forge\n */\nimport { error, isObject, oneOf, onlyKeys, type ConfigGroup, type ConfigProblem } from \"./types\";\n\nexport const FORGES = [\"github\", \"gitlab\", \"forgejo\"] as const;\n\nconst GLOB_MAP = {\n type: \"object\",\n additionalProperties: { type: \"array\", items: { type: \"string\" } },\n};\n\nfunction globMapProblems(v: unknown, key: string): ConfigProblem[] {\n if (v === undefined) return [];\n if (!isObject(v)) return [error(key, \"must map a name to a list of stack globs\")];\n return Object.entries(v)\n .filter(([, globs]) => !Array.isArray(globs) || globs.some((g) => typeof g !== \"string\"))\n .map(([k]) => error(`${key}.${k}`, \"must be a list of stack globs\"));\n}\n\nconst copy = (v: Record<string, string[]>): Record<string, string[]> => Object.fromEntries(Object.entries(v).map(([k, g]) => [k, [...g]]));\n\nexport const routing: ConfigGroup = {\n name: \"routing\",\n keys: [\"branches\", \"labels\", \"forge\"],\n schema: {\n branches: { ...GLOB_MAP, description: \"Branch name to stack globs. A stack a glob matches updates from that branch alone.\" },\n labels: { ...GLOB_MAP, description: \"Pull request label to stack globs. A labelled pull request previews only the stacks its labels match.\" },\n forge: {\n type: \"object\",\n additionalProperties: false,\n description: \"The forge the jobs talk to. Read from the repository's remote when absent.\",\n properties: {\n kind: { type: \"string\", enum: [...FORGES] },\n url: { type: \"string\", description: \"The forge's base URL, for a self-hosted forge.\" },\n },\n },\n },\n check(doc) {\n const out: ConfigProblem[] = [...globMapProblems(doc.branches, \"branches\"), ...globMapProblems(doc.labels, \"labels\")];\n const f = doc.forge;\n if (f !== undefined) {\n if (!isObject(f)) out.push(error(\"forge\", \"must be a mapping of kind and url\"));\n else {\n out.push(...onlyKeys(f, [\"kind\", \"url\"], \"forge\"), ...oneOf(f.kind, FORGES, \"forge.kind\"));\n if (f.url !== undefined && (typeof f.url !== \"string\" || !/^https?:\\/\\//.test(f.url))) out.push(error(\"forge.url\", \"must be an http or https URL\"));\n }\n }\n return out;\n },\n translate(doc, out) {\n if (isObject(doc.branches)) out.ci.branches = copy(doc.branches as Record<string, string[]>);\n if (isObject(doc.labels)) out.ci.labels = copy(doc.labels as Record<string, string[]>);\n if (isObject(doc.forge)) {\n const f = doc.forge as { kind?: string; url?: string };\n out.pipeline.forge = { ...(f.kind ? { kind: f.kind } : {}), ...(f.url ? { url: f.url } : {}) };\n }\n },\n};\n", "/**\n * plywood.yml: plywood's keys in snake_case, each wrapping chant's\n * (plywood#2 ruling A). This module finds and parses the file, runs every\n * group's checks, and composes the JSON schema. src/chant-config.ts turns a\n * clean config into chant's settings.\n *\n * Each group of keys has its own module; GROUPS lists them in the order\n * they translate (stacks before engine, which fills each stack's engine;\n * images after routing, since it reads each stack's engine and the forge).\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\nimport { parseYAML } from \"@intentius/chant/yaml\";\nimport { agents } from \"./agents\";\nimport { apply } from \"./apply\";\nimport { approval } from \"./approval\";\nimport { chantKeys } from \"./chant-keys\";\nimport { control } from \"./control\";\nimport { drift } from \"./drift\";\nimport { engine } from \"./engine\";\nimport { identity } from \"./identity\";\nimport { images } from \"./images\";\nimport { jobs } from \"./jobs\";\nimport { later } from \"./later\";\nimport { locks } from \"./locks\";\nimport { observe } from \"./observe\";\nimport { policy } from \"./policy\";\nimport { reviewStacks } from \"./review-stacks\";\nimport { routing } from \"./routing\";\nimport { stacks } from \"./stacks\";\nimport { error, isObject, type ConfigGroup, type ConfigProblem, type JsonSchema, type RawConfig } from \"./types\";\n\nexport type { ConfigGroup, ConfigProblem, RawConfig } from \"./types\";\n\nexport const GROUPS: readonly ConfigGroup[] = [chantKeys, stacks, engine, apply, locks, approval, policy, identity, reviewStacks, observe, drift, agents, routing, images, jobs, control, later];\n\n/** The names chant's pulumi lexicon also looks for (chant#4559, member-engine.ts `PLYWOOD_FILES`). */\nexport const CONFIG_NAMES = [\"plywood.yml\", \"plywood.yaml\"] as const;\n\nexport interface PlywoodConfig {\n /** The file read, or undefined for a config given as text. */\n file?: string;\n doc: RawConfig;\n}\n\nexport class ConfigError extends Error {\n constructor(\n message: string,\n readonly problems: ConfigProblem[] = [],\n ) {\n super(message);\n this.name = \"ConfigError\";\n }\n}\n\n/** Every top-level key some group owns. */\nexport function knownKeys(): Set<string> {\n return new Set(GROUPS.flatMap((g) => g.keys));\n}\n\n/**\n * The nearest plywood.yml from `dir` up to the repository root (the first\n * directory holding `.git`), as chant's pulumi lexicon searches.\n */\nexport function findConfig(dir: string): string | undefined {\n let cur = resolve(dir);\n for (let depth = 0; depth < 32; depth++) {\n for (const name of CONFIG_NAMES) {\n const file = join(cur, name);\n if (existsSync(file)) return file;\n }\n const parent = dirname(cur);\n if (existsSync(join(cur, \".git\")) || parent === cur) return undefined;\n cur = parent;\n }\n return undefined;\n}\n\n/** Parses plywood.yml text. An empty file is an empty config; a file that is not a mapping is refused. */\nexport function parseConfig(text: string, file?: string): PlywoodConfig {\n let doc: unknown;\n try {\n doc = text.trim() === \"\" ? {} : parseYAML(text);\n } catch (e) {\n throw new ConfigError(`${file ?? \"plywood.yml\"}: ${(e as Error).message}`);\n }\n if (doc === null || doc === undefined) doc = {};\n if (!isObject(doc)) throw new ConfigError(`${file ?? \"plywood.yml\"}: the file must be a mapping of plywood keys`);\n return { ...(file ? { file } : {}), doc };\n}\n\n/** Reads plywood.yml at `file`. */\nexport function loadConfig(file: string): PlywoodConfig {\n return parseConfig(readFileSync(file, \"utf8\"), file);\n}\n\n/** Every problem in the config: unknown keys, then each group's checks. */\nexport function checkConfig(config: PlywoodConfig): ConfigProblem[] {\n const known = knownKeys();\n const out: ConfigProblem[] = [];\n for (const key of Object.keys(config.doc)) {\n if (key === \"ci\" || key.startsWith(\"ci.\")) continue;\n if (!known.has(key)) out.push(error(key, `is not a plywood key; the keys are ${[...known].sort().join(\", \")}`));\n }\n for (const g of GROUPS) out.push(...g.check(config.doc));\n return out;\n}\n\n/** The JSON schema of plywood.yml, composed from every group's keys. */\nexport function plywoodSchema(): JsonSchema {\n const properties: Record<string, JsonSchema> = {};\n for (const g of GROUPS) Object.assign(properties, g.schema);\n return {\n $schema: \"https://json-schema.org/draft/2020-12/schema\",\n $id: \"https://intentius.io/plywood/plywood.schema.json\",\n title: \"plywood.yml\",\n description: \"plywood's config. Each key wraps a chant setting; plywood sets chant's keys from it, so a ci. key is refused.\",\n $comment: \"Generated from packages/plywood/src/config by scripts/build-schema.mjs; edit the group modules, then run npm run schema.\",\n type: \"object\",\n additionalProperties: false,\n properties,\n };\n}\n", "/**\n * plywood.yml turned into chant's settings. plywood's keys wrap chant's\n * (plywood#2 ruling A), so plywood.yml never holds a chant key and this\n * module is the one place a plywood key meets chant's name for it.\n *\n * The settings come in three parts:\n *\n * ci chant's workspace `ci` block, under chant's own key names\n * (`ci.workflow`, `ci.locks`, `ci.lockGrain`, `ci.prEnvironment`,\n * `ci.policy`, `ci.identity`, `ci.reportUrl`, `ci.branches`, `ci.labels`).\n * members one entry per stack, as a Pulumi member: its directory, and the\n * engine and backend chant's pulumi lexicon takes as the member's\n * config (chant#4559, the first rule `pulumiMemberEngine` asks);\n * `memberDefaults` for a stack plywood.yml does not list.\n * pipeline what plywood hands chant's product pipeline in process\n * (chant#4550 ruling C): gate policy, approval source and rules,\n * waves, what an open pull request needs before `/plywood up`,\n * and the image, engine install lines and runners (plywood#12).\n *\n * `ci.lockGrain` is chant#4552's key (ruling A: target, resource or repo).\n * A chant without the lock grain build ignores it; plywood writes it, and\n * nothing more, until that build lands.\n *\n * Each config group writes its own part (src/config/<group>.ts).\n */\nimport { GROUPS, type PlywoodConfig } from \"./config/index\";\nimport type { AgentSettings, ReviewSettings } from \"./config/agents\";\nimport type { DriftSettings } from \"./config/drift\";\nimport type { JobSettings } from \"./config/jobs\";\nimport type { ChantIdentitySettings } from \"./config/identity\";\nimport type { ChantNotifyConfig } from \"./config/observe\";\nimport type { ChantPolicySettings, PolicyPack } from \"./config/policy\";\n\n/** chant's `ci.workflow` values plywood sets (chant `CiWorkflow`). */\nexport type ChantCiWorkflow = \"trunk-curated+apply-on-merge\" | \"apply-before-merge\";\n/** chant's `ci.locks` (chant `CiLocks`). */\nexport type ChantCiLocks = \"plan\" | \"apply\";\n/** chant's `ci.lockGrain` (chant#4552 ruling A). */\nexport type ChantLockGrain = \"target\" | \"resource\" | \"repo\";\n/** The approval sources chant's gate decision reads. */\nexport type ChantApprovalSource = \"ledger\" | \"sealed\" | \"pr-review\";\nexport type ChantGatePolicy = \"always\" | \"on-destructive\" | \"never\";\n\n/** One approval rule, in the shape of chant's `GateQuorumRule` (op/gate-quorum.ts). */\nexport interface ChantQuorumRule {\n targets?: string[];\n count: number;\n roles?: string[];\n notAuthor?: boolean;\n}\n\nexport interface ChantCiSettings {\n workflow?: ChantCiWorkflow;\n locks?: ChantCiLocks;\n lockGrain?: ChantLockGrain;\n prEnvironment?: { template: string; ttl?: string };\n /** chant's gate policy over the change set, read at base (chant#4294). */\n policy?: ChantPolicySettings;\n /** chant's plan and apply identities per cloud, Pulumi Cloud's included (chant#4296, #4549). */\n identity?: ChantIdentitySettings;\n /** Where chant keeps each run's HTML report (chant#4554). */\n reportUrl?: string;\n branches?: Record<string, string[]>;\n labels?: Record<string, string[]>;\n}\n\nexport interface ChantMemberSettings {\n /** The stack, as `project/stack`. */\n name: string;\n dir?: string;\n /** Paths whose change plans the stack, beside its directory. */\n paths?: string[];\n /** Set only when plywood.yml names the engine, or a `plunge+` backend names it; otherwise chant's pulumi lexicon decides. */\n engine?: \"pulumi\" | \"plunge\";\n backend?: string;\n gate?: ChantGatePolicy;\n /** The engine release plywood.yml's `pulumi:` or `plunge:` pins for the stack. */\n engineVersion?: string;\n /** The engine binary for a stack pinned to a release other than the one on PATH (src/images.ts `engineBin`). */\n engineBin?: string;\n /** Where that release is installed (src/images.ts `ENGINE_ROOT`), the pulumi-up step's `engineRoot` (chant#4592). */\n engineRoot?: string;\n}\n\n/** One runner: a label, every label of a list, or a GitHub runner group with labels its runners also carry. */\nexport type ChantRunnerSpec = string | string[] | { group: string; labels?: string[] };\n/** The jobs' runner: one for all, or one per stage over a default. */\nexport type ChantRunner = ChantRunnerSpec | Partial<Record<\"default\" | \"preview\" | \"up\" | \"drift\", ChantRunnerSpec>>;\n\nexport interface ChantPipelineSettings {\n gate?: ChantGatePolicy;\n approval?: ChantApprovalSource;\n /** The rules a gate's approvals must meet. */\n quorum?: ChantQuorumRule[];\n /** An approval by the pull request's author never counts. */\n excludeAuthor?: boolean;\n waves?: string[][];\n /** The stacks that update first, in a wave of their own (plywood.yml `waves.canary`, plywood#18). */\n canary?: string[];\n /** Each stack to the stacks it updates after, beside its StackReferences (plywood.yml `waves.after`). */\n after?: Record<string, string[]>;\n /** The control repo this repository tells after each update on merge (plywood.yml `control`, chant#4568's `ControlSettingsInput`). */\n control?: ChantControlSettings;\n /** What an open pull request needs before `/plywood up` updates it. */\n applyRequires?: string[];\n /** The review stack name pattern; `{number}` is the pull request's number. */\n reviewStackName?: string;\n forge?: { kind?: string; url?: string };\n /** The image every job runs in, by digest. Absent: chant's default image (src/images.ts `chantPipelineOptions`). */\n image?: string;\n /** The verified engine install lines; each skips an engine the image already carries. */\n engineSetup?: string[];\n /** The runner the jobs run on. */\n runner?: ChantRunner;\n /** CrossGuard packs every stack's pulumi-up step runs, relative to the repository root (chant#4541). */\n policyPacks?: PolicyPack[];\n /** The waves spec's notify (chant `NotifyConfig`): the variables holding each webhook. */\n notify?: ChantNotifyConfig;\n /** The scheduled drift check and its response (plywood#8): chant's scheduled Op jobs and `plywood drift`. */\n drift?: DriftSettings;\n /** The review agent's step (plywood#19): a reviewAgent in handoff mode, in the pull request Op plywood ci writes. */\n review?: ReviewSettings;\n /** The agents' settings and spend limit (plywood#19). */\n agent?: AgentSettings;\n /** `env`, `pass`, `parallelism` and `environments` (plywood#29): src/jobs.ts puts them on the jobs. */\n jobs?: JobSettings;\n /** `respond.wave_refused`, `apply_failed` and `description` by chant's event names (chant#4629 `CiResponses`). */\n respond?: Record<string, string>;\n /** `decide`, for `respond.description: check` (chant#4629). */\n decide?: { backend: string; model: string };\n /** `apply.merge: auto` with its token variable and method (chant#4636 `applyMerge`). */\n applyMerge?: { tokenEnv: string; method?: \"merge\" | \"squash\" | \"rebase\" };\n}\n\n/** chant's `ControlSettingsInput` (`@intentius/chant/ci-control`, chant#4568). */\nexport interface ChantControlSettings {\n /** The control repo as a project key, `<host>/<owner>/<name>`. */\n repo: string;\n forge?: \"github\" | \"gitlab\" | \"forgejo\";\n /** The Op the control repo runs on this repository's dependents. */\n op: string;\n member?: string;\n tokenSecret?: string;\n readTokenSecret?: string;\n ref?: string;\n apiBase?: string;\n}\n\nexport interface ChantSettings {\n ci: ChantCiSettings;\n members: ChantMemberSettings[];\n /** The engine and backend for a stack plywood.yml does not list (one `plywood init` finds later). */\n memberDefaults: Pick<ChantMemberSettings, \"engine\" | \"backend\">;\n pipeline: ChantPipelineSettings;\n}\n\n/** chant's settings for a config that checked clean (`checkConfig` reports no error). */\nexport function toChantSettings(config: PlywoodConfig): ChantSettings {\n const out: ChantSettings = { ci: {}, members: [], memberDefaults: {}, pipeline: {} };\n for (const group of GROUPS) group.translate(config.doc, out);\n return out;\n}\n", "/**\n * `plywood config check`: reads the nearest plywood.yml (or `--file`),\n * prints each problem, and for a clean config the settings in force: the\n * engine plywood.yml names, when an update runs, the gate, the approval mode,\n * and when locks are taken at which grain. `--json` prints the chant\n * settings plywood would hand chant as well.\n */\nimport { toChantSettings } from \"./chant-config\";\nimport { applyWhenOf } from \"./config/apply\";\nimport { approvalOf, gateOf } from \"./config/approval\";\nimport { engineOf } from \"./config/engine\";\nimport { checkConfig, ConfigError, findConfig, loadConfig, type PlywoodConfig } from \"./config/index\";\nimport { LATER_KEYS } from \"./config/later\";\nimport { LOCK_GRAIN_OF, CI_LOCKS_OF, lockGrainFor, locksOf } from \"./config/locks\";\nimport { LOCK_GRAIN_WORDS } from \"./words\";\nimport { chantPolicyOf, policyPacksOf } from \"./config/policy\";\nimport type { RawConfig } from \"./config/types\";\nimport { PRODUCT } from \"./words\";\n\nexport interface ConfigCheckResult {\n ok: boolean;\n /** The text lines to print; problems go to stderr when not ok. */\n lines: string[];\n envelope: Record<string, unknown>;\n}\n\n/** Runs the check from `cwd`, or on `file` when given. */\nexport function configCheck(cwd: string, file?: string): ConfigCheckResult {\n const path = file ?? findConfig(cwd);\n if (!path) {\n const message = `no plywood.yml in ${cwd} or above it up to the repository root; run '${PRODUCT} init', or pass --file`;\n return { ok: false, lines: [message], envelope: { error: message } };\n }\n let config: PlywoodConfig;\n try {\n config = loadConfig(path);\n } catch (e) {\n const message = e instanceof ConfigError ? e.message : `${path}: ${(e as Error).message}`;\n return { ok: false, lines: [message], envelope: { file: path, error: message } };\n }\n const problems = checkConfig(config);\n const errors = problems.filter((p) => p.severity === \"error\");\n const lines = problems.map((p) => `${path}: ${p.key} ${p.message}${p.severity === \"warning\" ? \" (warning)\" : \"\"}`);\n if (errors.length) return { ok: false, lines, envelope: { file: path, problems } };\n\n const doc = config.doc;\n const engine = engineOf(doc);\n const locks = locksOf(doc);\n const later = Object.keys(doc).filter((k) => k in LATER_KEYS);\n const settings = {\n engine: engine?.engine ?? null,\n applyWhen: applyWhenOf(doc),\n gate: gateOf(doc),\n approval: approvalOf(doc),\n locksWhen: locks.when,\n lockGrain: lockGrainFor(doc, engine?.engine),\n };\n lines.push(\n `${path}: ok`,\n ` engine ${engine ? `${engine.engine} (${engine.because})` : \"not set here; chant reads PULUMI_BACKEND_URL, then Pulumi.yaml\"}`,\n ` apply.when ${settings.applyWhen}`,\n ` gate ${settings.gate}`,\n ` approval ${settings.approval}`,\n ` locks.when ${locks.when} (ci.locks ${CI_LOCKS_OF[locks.when]})`,\n ` locks.grain ${locks.grain ? `${locks.grain} (ci.lockGrain ${LOCK_GRAIN_OF[locks.grain]})` : LOCK_GRAIN_WORDS.perEngine(engine?.engine)}`,\n ` policy ${policyLine(doc)}`,\n ...(later.length ? [` read as written, not yet passed to chant: ${later.join(\", \")}`] : []),\n );\n return { ok: true, lines, envelope: { file: path, problems, settings, chant: toChantSettings(config) } };\n}\n\n/** What plywood.yml's policy key switches on, for the settings line. */\nfunction policyLine(doc: RawConfig): string {\n const rego = chantPolicyOf(doc);\n const packs = policyPacksOf(doc);\n const src = rego?.source;\n const regoDir = src ? `${src.path ?? \"policy\"} of ${src.repo}@${src.ref}` : (rego?.path ?? \"policy\");\n const hasRego = rego !== undefined && (src !== undefined || rego.path !== undefined || rego.command !== undefined || rego.engine !== undefined || rego.namespace !== undefined);\n const parts = [\n ...(hasRego ? [`Rego in ${regoDir} (${rego!.engine ?? \"conftest\"}), read at ${src ? \"the ref the base names\" : \"base\"}`] : []),\n ...(packs.length ? [`CrossGuard ${packs.map((p) => p.dir).join(\", \")}${src ? ` from ${src.repo}@${src.ref}` : \"\"} in each preview${rego?.packs ? \", read at base (ci.policy.packs)\" : \"\"}`] : []),\n ];\n return parts.length ? parts.join(\"; \") : \"none\";\n}\n", "/**\n * What `plywood init` reads from the repository before it writes anything:\n * each Pulumi project (a `Pulumi.yaml`), its stacks (the\n * `Pulumi.<stack>.yaml` files beside it, or under its `stackConfigDir`),\n * each stack's backend, the forge the `origin` remote names, the default\n * branch, and the files a team already has that plywood should know about\n * (a pulumi/actions workflow, a pre-commit config).\n *\n * Everything here reads files. Nothing runs pulumi, plunge or git: the\n * remote and the branch come from `.git/config` and `.git/refs`, as git\n * itself writes them.\n */\nimport { existsSync, readdirSync, readFileSync, statSync } from \"node:fs\";\nimport { basename, dirname, join, relative, sep } from \"node:path\";\nimport { parseYAML } from \"@intentius/chant/yaml\";\nimport type { ForgeKind } from \"../chant-product\";\n\n/** One Pulumi project: the directory holding its `Pulumi.yaml`. */\nexport interface DetectedProject {\n /** `name` in Pulumi.yaml. */\n name: string;\n /** The directory, relative to the repository root, `\".\"` for the root. */\n dir: string;\n /** `runtime` in Pulumi.yaml, as written (a string, or `{ name }`). */\n runtime?: string;\n /** `backend.url` in Pulumi.yaml. */\n backendUrl?: string;\n /** The stack names, from the `Pulumi.<stack>.yaml` files. */\n stacks: string[];\n}\n\n/** One stack, keyed as plywood.yml keys it: `project/stack`. */\nexport interface DetectedStack {\n key: string;\n project: string;\n stack: string;\n dir: string;\n}\n\n/** Where a backend URL came from, first that answers. */\nexport type BackendSource = \"plywood.yml\" | \"PULUMI_BACKEND_URL\" | \"Pulumi.yaml\" | \"none\";\n\nexport interface DetectedForge {\n kind: ForgeKind;\n /** How the kind was found. */\n because: string;\n /** A self-hosted forge's base URL (GitLab or Forgejo not on their public hosts). */\n url?: string;\n}\n\nexport interface Detected {\n root: string;\n projects: DetectedProject[];\n stacks: DetectedStack[];\n forge?: DetectedForge;\n defaultBranch: string;\n /** Workflow files that run pulumi/actions, relative to the root. */\n pulumiActions: string[];\n /** `.pre-commit-config.yaml` (or `.yml`) at the root. */\n preCommit?: string;\n}\n\n/** Directories the search never enters. */\nconst SKIP = new Set([\"node_modules\", \".git\", \"dist\", \"build\", \"vendor\", \"venv\", \".venv\", \"__pycache__\", \"target\", \"bin\", \"obj\"]);\nconst MAX_DEPTH = 8;\n\n/** The repository root: the nearest directory at or above `dir` holding `.git`, else `dir`. */\nexport function repoRoot(dir: string): string {\n let cur = dir;\n for (let i = 0; i < 64; i++) {\n if (existsSync(join(cur, \".git\"))) return cur;\n const parent = dirname(cur);\n if (parent === cur) return dir;\n cur = parent;\n }\n return dir;\n}\n\n/** Path with forward slashes, `\".\"` for the root itself. */\nexport function posixRel(root: string, path: string): string {\n const rel = relative(root, path);\n return rel === \"\" ? \".\" : rel.split(sep).join(\"/\");\n}\n\nfunction readYamlFile(file: string): Record<string, unknown> | undefined {\n try {\n const doc: unknown = parseYAML(readFileSync(file, \"utf8\"));\n return doc && typeof doc === \"object\" && !Array.isArray(doc) ? (doc as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Every `Pulumi.yaml` (or `Pulumi.yml`) under `root`, skipping dependency and build directories. */\nexport function findPulumiProjects(root: string): DetectedProject[] {\n const out: DetectedProject[] = [];\n const walk = (dir: string, depth: number): void => {\n let entries: string[];\n try {\n entries = readdirSync(dir).sort();\n } catch {\n return;\n }\n const file = [\"Pulumi.yaml\", \"Pulumi.yml\"].find((n) => entries.includes(n));\n if (file) {\n const project = readProject(root, dir, join(dir, file));\n if (project) out.push(project);\n }\n if (depth >= MAX_DEPTH) return;\n for (const name of entries) {\n if (SKIP.has(name) || name.startsWith(\".\")) continue;\n const path = join(dir, name);\n try {\n if (statSync(path).isDirectory()) walk(path, depth + 1);\n } catch {\n // unreadable: skipped\n }\n }\n };\n walk(root, 0);\n return out;\n}\n\nfunction readProject(root: string, dir: string, file: string): DetectedProject | undefined {\n const doc = readYamlFile(file);\n if (!doc || typeof doc.name !== \"string\" || doc.name === \"\") return undefined;\n const runtime = typeof doc.runtime === \"string\" ? doc.runtime : (doc.runtime as { name?: unknown } | undefined)?.name;\n const backend = doc.backend as { url?: unknown } | undefined;\n const configDir = typeof doc.stackConfigDir === \"string\" ? join(dir, doc.stackConfigDir) : dir;\n return {\n name: doc.name,\n dir: posixRel(root, dir),\n ...(typeof runtime === \"string\" ? { runtime } : {}),\n ...(backend && typeof backend.url === \"string\" ? { backendUrl: backend.url } : {}),\n stacks: stackNames(configDir),\n };\n}\n\n/** The stacks of a project: `Pulumi.<stack>.yaml` beside Pulumi.yaml (or in its stackConfigDir). */\nexport function stackNames(configDir: string): string[] {\n let entries: string[];\n try {\n entries = readdirSync(configDir);\n } catch {\n return [];\n }\n const names = entries\n .map((n) => /^Pulumi\\.(.+)\\.ya?ml$/.exec(n)?.[1])\n .filter((s): s is string => s !== undefined && s !== \"\");\n return [...new Set(names)].sort(byEnvironment);\n}\n\n/** Environments in the order a change usually goes through them; others sort between staging and prod. */\nconst ENV_ORDER = [\"local\", \"dev\", \"development\", \"sandbox\", \"test\", \"testing\", \"qa\", \"ci\", \"stage\", \"staging\", \"preprod\", \"uat\", \"prod\", \"production\"];\nconst PROD_RANK = ENV_ORDER.indexOf(\"prod\");\n\n/** The environment a stack name is for: its last segment before a region suffix, such as `prod` of `prod-east`. */\nexport function environmentOf(stack: string): string {\n const last = stack.split(\"/\").pop()!.toLowerCase();\n const head = last.split(/[-_.]/)[0]!;\n return ENV_ORDER.includes(head) ? head : last;\n}\n\nfunction rank(stack: string): number {\n const env = environmentOf(stack);\n const at = ENV_ORDER.indexOf(env);\n return at >= 0 ? at : PROD_RANK - 0.5;\n}\n\n/** Orders stack names dev before staging before prod, then by name. */\nexport function byEnvironment(a: string, b: string): number {\n return rank(a) - rank(b) || a.localeCompare(b);\n}\n\n/** Every stack of every project, keyed `project/stack`. Two projects of one name get the directory in the key's project part. */\nexport function stacksOf(projects: readonly DetectedProject[]): DetectedStack[] {\n const names = new Map<string, number>();\n for (const p of projects) names.set(p.name, (names.get(p.name) ?? 0) + 1);\n const out: DetectedStack[] = [];\n for (const p of projects) {\n const project = (names.get(p.name) ?? 0) > 1 ? `${p.name}-${slug(p.dir)}` : p.name;\n for (const stack of p.stacks) out.push({ key: `${project}/${stack}`, project: p.name, stack, dir: p.dir });\n }\n return out.sort((x, y) => byEnvironment(x.stack, y.stack) || x.key.localeCompare(y.key));\n}\n\n/** Lowercase letters, digits and `-`, as chant's names take them. */\nexport function slug(s: string): string {\n const out = s.toLowerCase().replace(/[^a-z0-9]+/g, \"-\").replace(/^-+|-+$/g, \"\");\n return out === \"\" ? \"root\" : out;\n}\n\n/** The `[remote \"origin\"]` url in `.git/config`, or undefined. */\nexport function originUrl(root: string): string | undefined {\n const config = gitFile(root, \"config\");\n if (!config) return undefined;\n let inOrigin = false;\n for (const raw of config.split(/\\r?\\n/)) {\n const line = raw.trim();\n if (line.startsWith(\"[\")) {\n inOrigin = /^\\[remote\\s+\"origin\"\\]$/.test(line);\n continue;\n }\n const m = inOrigin ? /^url\\s*=\\s*(.+)$/.exec(line) : null;\n if (m) return m[1]!.trim();\n }\n return undefined;\n}\n\n/** A file under the git directory, which is `.git` itself or the directory a `.git` file names (a worktree). */\nfunction gitFile(root: string, name: string): string | undefined {\n const dotGit = join(root, \".git\");\n let gitDir = dotGit;\n try {\n if (statSync(dotGit).isFile()) {\n const m = /^gitdir:\\s*(.+)$/m.exec(readFileSync(dotGit, \"utf8\"));\n if (!m) return undefined;\n gitDir = join(root, m[1]!.trim());\n // A worktree keeps config and refs/remotes in the common directory.\n const common = join(gitDir, \"commondir\");\n if (existsSync(common) && !existsSync(join(gitDir, name))) gitDir = join(gitDir, readFileSync(common, \"utf8\").trim());\n }\n const path = join(gitDir, name);\n return existsSync(path) ? readFileSync(path, \"utf8\") : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The host of a remote URL: `https://host/...`, `ssh://git@host:22/...` or `git@host:owner/repo`. */\nexport function remoteHost(url: string): string | undefined {\n const scp = /^[^@/\\s]+@([^:/\\s]+):/.exec(url);\n if (scp) return scp[1]!.toLowerCase();\n try {\n return new URL(url).hostname.toLowerCase() || undefined;\n } catch {\n return undefined;\n }\n}\n\n/** The forge a remote URL names, from its host. */\nexport function forgeOfRemote(url: string): DetectedForge | undefined {\n const host = remoteHost(url);\n if (!host) return undefined;\n if (host === \"github.com\" || host.endsWith(\".github.com\") || host.startsWith(\"github.\")) return { kind: \"github\", because: `origin is on ${host}` };\n if (host === \"gitlab.com\") return { kind: \"gitlab\", because: `origin is on ${host}` };\n if (host === \"codeberg.org\") return { kind: \"forgejo\", because: `origin is on ${host}` };\n if (/(^|[.-])gitlab([.-]|$)/.test(host)) return { kind: \"gitlab\", because: `origin is on ${host}`, url: `https://${host}` };\n if (/(^|[.-])(forgejo|gitea)([.-]|$)/.test(host)) return { kind: \"forgejo\", because: `origin is on ${host}`, url: `https://${host}` };\n return undefined;\n}\n\n/** The forge: from the origin remote's host, else from the CI files the repository has. */\nexport function detectForge(root: string): DetectedForge | undefined {\n const url = originUrl(root);\n const byRemote = url ? forgeOfRemote(url) : undefined;\n if (byRemote) return byRemote;\n if (existsSync(join(root, \".forgejo\"))) return { kind: \"forgejo\", because: \"the repository has .forgejo/\" };\n if (existsSync(join(root, \".gitlab-ci.yml\"))) return { kind: \"gitlab\", because: \"the repository has .gitlab-ci.yml\" };\n if (existsSync(join(root, \".github\", \"workflows\"))) return { kind: \"github\", because: \"the repository has .github/workflows/\" };\n return undefined;\n}\n\n/** The branch `origin/HEAD` points at, else the checked-out branch, else `main`. */\nexport function defaultBranch(root: string): string {\n const head = gitFile(root, \"refs/remotes/origin/HEAD\");\n const remote = head && /ref:\\s*refs\\/remotes\\/origin\\/(.+)/.exec(head)?.[1];\n if (remote) return remote.trim();\n const local = gitFile(root, \"HEAD\");\n const branch = local && /ref:\\s*refs\\/heads\\/(.+)/.exec(local)?.[1];\n return branch ? branch.trim() : \"main\";\n}\n\n/** The workflow directories a forge reads. */\nconst WORKFLOW_DIRS = [\".github/workflows\", \".forgejo/workflows\", \".gitea/workflows\"];\n\n/** Workflow files that use pulumi/actions, relative to the root. */\nexport function findPulumiActions(root: string): string[] {\n const out: string[] = [];\n for (const d of WORKFLOW_DIRS) {\n let names: string[];\n try {\n names = readdirSync(join(root, d)).sort();\n } catch {\n continue;\n }\n for (const n of names) {\n if (!/\\.ya?ml$/.test(n)) continue;\n try {\n if (/uses:\\s*[\"']?pulumi\\/actions@/.test(readFileSync(join(root, d, n), \"utf8\"))) out.push(`${d}/${n}`);\n } catch {\n // unreadable: skipped\n }\n }\n }\n return out;\n}\n\n/** Everything init reads, from `cwd`'s repository. */\nexport function detect(cwd: string): Detected {\n const root = repoRoot(cwd);\n const projects = findPulumiProjects(root);\n const forge = detectForge(root);\n const preCommit = [\".pre-commit-config.yaml\", \".pre-commit-config.yml\"].find((n) => existsSync(join(root, n)));\n return {\n root,\n projects,\n stacks: stacksOf(projects),\n ...(forge ? { forge } : {}),\n defaultBranch: defaultBranch(root),\n pulumiActions: findPulumiActions(root),\n ...(preCommit ? { preCommit } : {}),\n };\n}\n\n/** The repository's name, for the workspace declaration: the root directory's name. */\nexport function repoName(root: string): string {\n return slug(basename(root)).slice(0, 40).replace(/-+$/, \"\") || \"plywood\";\n}\n", "/**\n * chant's product pipeline (`@intentius/chant/ci-product`, chant#4550),\n * reached through a feature-detect. plywood's pin is chant 0.124.54, which\n * has no such entry; the release after it does (its `CI_PRODUCT_FLOOR`).\n *\n * The entry is imported on first use. When it is missing, or lacks any of\n * `assertProductWords`, `productPipelineJobs`, `approveLine` and\n * `runChantInProcess` (chant#4550 names the first three as the check), the\n * verbs that need it say so and exit with chant's `failed` code, and\n * everything else keeps working on the pin.\n *\n * The `import()` carries a `@ts-ignore` so this compiles against a chant\n * without the subpath; scripts/build-cli.mjs stands in a module that throws\n * for a subpath the installed chant lacks, so the bundle builds either way.\n */\nimport type { ChantCommand, ProductWordsInput } from \"./words\";\n\nexport type ForgeKind = \"github\" | \"gitlab\" | \"forgejo\";\n\n/** The words as chant resolves them; plywood reads only these slots. */\nexport interface ProductWords {\n product: string;\n stages: Record<string, string>;\n commands: Record<string, ChantCommand>;\n prGate: string;\n op?: string;\n bin?: string;\n}\n\n/** The part of `ProductPipelineJobs` plywood reads (chant components/product-pipeline.ts). */\nexport interface ProductPipelineJobs {\n words: ProductWords;\n plan: { jobName: string; command: string };\n /** `control`: the note job's read of the control repo (chant#4619), when the options name one; a chant before it gives none. */\n post: { command: string; control?: { stepName: string; env: Record<string, string>; script: string } };\n record?: { jobName: string; command: string };\n applyBeforeMerge?: { jobName: string; command: string };\n comments: Partial<Record<ChantCommand, string>>;\n waves?: { spec: unknown; specFile: string; jobs: Array<{ command: string[] }> };\n /** The agent's Op spec for `/plywood agent` (chant#4616), when the options ask for the agent. */\n agent?: { comment: string; name: string; spec: Record<string, unknown> };\n /** The `/plywood preview` comment's jobs (chant#4620), with `previewComment`. */\n preview?: { jobName: string; noteJobName: string; comment: string };\n /** The stale marking's job (chant#4628), with `staleNotes`. */\n stale?: { command: string; env: Record<string, string> };\n}\n\n/** The options plywood passes to `productPipelineJobs`. */\nexport interface ProductPipelineOptions {\n words: ProductWordsInput | ProductWords;\n applyBeforeMerge?: boolean;\n locks?: \"plan\";\n branch?: string;\n waves?: unknown;\n /** The checks the apply-before-merge job asks (chant#4607); a chant before it ignores the option. */\n applyRequires?: string[];\n /** The agent's settings (chant#4616 `ProductAgentOptions`); a chant before it ignores the option. */\n agent?: boolean | Record<string, unknown>;\n /** The control repo (chant#4568's `ControlTarget`); with chant#4619 `post.control` reads it. */\n control?: { target: unknown };\n /** The `/plywood preview` comment's jobs (chant#4620); a chant before it ignores the option. */\n previewComment?: boolean;\n /** The pull request jobs' runner by stage, variables, passed secrets and parallelism (chant#4625); src/jobs.ts gives them only to a chant with it. */\n runners?: unknown;\n variables?: Record<string, string>;\n secrets?: Record<string, string>;\n parallelism?: number;\n /** The note carries its target commit, and a push to the target branch marks older notes stale (chant#4628); a chant before it ignores the option. */\n staleNotes?: boolean;\n /** The responses to a refused wave, a failed apply and the description (chant#4629), by chant's event names; a chant before it ignores the option. */\n respond?: Record<string, string>;\n /** The decide service the description check asks (chant#4629). */\n decide?: { backend: string; model: string };\n /** Merge the pull request once its update before merge applied (chant#4636); a chant before it ignores the option. */\n applyMerge?: { tokenEnv: string; method?: string };\n}\n\n/** What plywood calls from `@intentius/chant/ci-product`. */\nexport interface ChantProduct {\n assertProductWords(input: ProductWordsInput | ProductWords, options?: { jobs?: readonly ChantCommand[] }): ProductWords;\n productPipelineJobs(forge: ForgeKind, env: string, options: ProductPipelineOptions): ProductPipelineJobs;\n approveLine(words: ProductWords, input: { op: string; gate: string; digest: string }): string;\n /** `options.mcp` is chant#4555's product tool hook, for `serve mcp`; a chant before it ignores the option. */\n runChantInProcess(argv: string[], words: ProductWordsInput | ProductWords, options?: { mcp?: unknown }): Promise<number>;\n /** Present when `runChantInProcess` takes the product tool hook (chant#4555). */\n PRODUCT_MCP_HOOK_FLOOR?: string;\n /** The waves spec with the words' op, gate pattern and approval preset (chant#4550); plywood init writes its output. */\n productWavesSpec?(spec: Record<string, unknown>, words: ProductWordsInput | ProductWords): Record<string, unknown>;\n CI_PRODUCT_FLOOR?: string;\n /** Present when chant has the agent job and the scheduled Op spec's `agent` and `runner` (chant#4616). */\n CI_AGENT_FLOOR?: string;\n /** The `agent` of a scheduled drift Op (chant#4616). */\n productDriftAgent?(words: ProductWordsInput | ProductWords, op: string, options?: Record<string, unknown>): Record<string, unknown>;\n /** Present when chant's notify has the relay and `chant notify relay` (chant#4611). */\n NOTIFY_RELAY_FLOOR?: string;\n /** chant's relay server (chant#4611); its presence says `notify relay` runs in process. */\n startRelayServer?: (...args: unknown[]) => unknown;\n /** The standing pending gates waiting on a plan digest, with the pull request a `pr-<n>` op names (chant#4607). */\n pendingGatesByPlan?(digest: string, options?: { op?: string; pullRequestsOnly?: boolean; cwd?: string }): Promise<PendingGateByPlan[]>;\n /** Checks a `--requires` list for `pr-apply --before-merge` (chant#4607). */\n parseRequiresList?(values: readonly string[]): { checks: string[] } | { error: string };\n /** The comment preview's jobs (chant#4620); with {@link PR_PREVIEW_FLOOR} it says `pr-plan` takes `--target`. */\n prCommentPreviewJob?: (...args: unknown[]) => unknown;\n /** Present when chant has the comment preview and `pr-plan --target` (chant#4620). */\n PR_PREVIEW_FLOOR?: string;\n /** Present when chant has the responses to pipeline events (chant#4629). */\n CI_RESPOND_FLOOR?: string;\n /**\n * Present when `chant build --pr-loop` writes `--respond`, `--decide-backend`\n * and `--decide-model` into the pull request jobs, and refuses the decide\n * flags without `--respond description=check` (chant#4629, #4636).\n */\n PR_LOOP_BUILD_FLAGS_FLOOR?: string;\n /** Present when chant's op-waves generators post `<product>/approval` under a pr-review wave (chant#4630). */\n APPROVAL_STATUS_FLOOR?: string;\n /** Present when that status also follows `pull-request` waves, the pull request's own approval (chant#4630 ruling). */\n APPROVAL_STATUS_PULL_REQUEST_FLOOR?: string;\n /** Whether an op waves spec gets the approval status jobs: a `pr-review` or `pull-request` wave (chant#4630). */\n opWavesPostsApprovalStatus?(spec: unknown): boolean;\n}\n\n/**\n * Whether the installed chant has chant#4620: the product pipeline's\n * comment preview job (`build --pr-loop --preview-comment`) and `pr-plan\n * --target`, which landed together.\n */\nexport function hasChant4620(chant: ChantProduct): boolean {\n return typeof chant.prCommentPreviewJob === \"function\" && typeof chant.PR_PREVIEW_FLOOR === \"string\";\n}\n\n/** One standing pending gate a digest matched (chant's `PendingGateByPlan`, chant#4607). */\nexport interface PendingGateByPlan {\n op: string;\n gate: string;\n pr?: number;\n member?: string;\n matched: \"planDigest\" | \"changeSet\";\n timestamp: string;\n url?: string;\n}\n\n/**\n * Whether the installed chant has chant#4607: the op-wave generators write\n * the product's bin in each wave job, `pr-apply --before-merge` takes\n * `--requires`, and pending gates are read by plan digest. All three landed\n * together, and `pendingGatesByPlan` with `parseRequiresList` on the\n * ci-product entry is the check.\n */\nexport function hasChant4607(chant: ChantProduct): boolean {\n return typeof chant.pendingGatesByPlan === \"function\" && typeof chant.parseRequiresList === \"function\";\n}\n\n/** The functions whose presence says the installed chant has the product pipeline. */\nexport const REQUIRED = [\"assertProductWords\", \"productPipelineJobs\", \"approveLine\", \"runChantInProcess\"] as const;\n\ndeclare const __PLYWOOD_CHANT__: string | undefined;\n\n/** The chant version this bundle was built with, set by scripts/build-cli.mjs. */\nexport const BUILT_CHANT = typeof __PLYWOOD_CHANT__ === \"string\" ? __PLYWOOD_CHANT__ : \"unknown\";\n\n/** The message a verb prints when the installed chant has no product pipeline. */\nexport function needsChantMessage(what: string): string {\n return (\n `${what} needs chant >= the release after 0.124.54, which carries @intentius/chant/ci-product (chant#4550). ` +\n `This plywood was built with chant ${BUILT_CHANT}, which lacks it. ` +\n \"Upgrade plywood once that chant is out, or build against a local chant with 'just chant-local'.\"\n );\n}\n\n/** True when `m` has every function plywood calls. */\nexport function isChantProduct(m: unknown): m is ChantProduct {\n if (!m || typeof m !== \"object\") return false;\n const r = m as Record<string, unknown>;\n return REQUIRED.every((name) => typeof r[name] === \"function\");\n}\n\nlet cached: Promise<ChantProduct | undefined> | undefined;\n\n/** chant's product pipeline, or undefined when the installed chant lacks it. */\nexport function chantProduct(): Promise<ChantProduct | undefined> {\n cached ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4550).\n const m: unknown = await import(\"@intentius/chant/ci-product\");\n return isChantProduct(m) ? m : undefined;\n } catch {\n return undefined;\n }\n })();\n return cached;\n}\n\n/** Tests stand in a fake chant (or none, for the fallback). `reset` goes back to the real import. */\nexport function setChantProductForTests(fake: ChantProduct | undefined | \"reset\"): void {\n cached = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n", "/**\n * The chant parity features newer than the pin (chant#4624 to #4636), each\n * reached through a feature-detect with a fallback, as AGENTS.md asks:\n *\n * checkJob chant#4624 `@intentius/chant/ci-job-guard`: the\n * apply-job guard chant's op-wave generators\n * write first in each job, and `chant ci\n * check-job` (`plywood ci check-job`)\n * planFlags chant#4627 `pr-plan --refresh` and\n * `--target-dependents` (`PLAN_FLAG_ARGS`\n * on `@intentius/chant/components/capability`)\n * staleNotes chant#4628 the stale marking of a note when the\n * target branch moves (`markStaleNotes` on\n * `@intentius/chant/pr-post`)\n * scheduledOpCloud chant#4631 cloud identities, and an update job, on\n * a scheduled Op (`@intentius/chant/scheduled-op-cloud`)\n * updateContentsWrite chant#4631 ruling: `update.permissions` may raise\n * `contents` to write; detected by handing\n * `assertScheduledOpCloud` a probe spec that\n * asks for it\n * applyMerge chant#4636 `pr-apply --merge auto` (`@intentius/chant/pr-merge`)\n *\n * The responses (chant#4629), the build's flags for them and the merge\n * (`PR_LOOP_BUILD_FLAGS_FLOOR`) and the approval status (chant#4630) are read\n * off the ci-product entry plywood already loads (`CI_RESPOND_FLOOR`,\n * `APPROVAL_STATUS_FLOOR` on {@link ChantProduct}), and the audit log\n * (chant#4632) is {@link chantAudit}, since plywood calls into it.\n *\n * Each subpath the 0.124.55 pin lacks is in `CHANT_NEXT`\n * (scripts/chant-exports.mjs), so the bundle builds on the pin and the\n * import throws there; `pr-post` and `components/capability` are in the pin\n * without the new export, and the check reads the export.\n */\nimport type { ChantProduct } from \"./chant-product\";\n\nexport interface ChantNext {\n checkJob: boolean;\n planFlags: boolean;\n staleNotes: boolean;\n scheduledOpCloud: boolean;\n updateContentsWrite: boolean;\n applyMerge: boolean;\n}\n\nconst NONE: ChantNext = { checkJob: false, planFlags: false, staleNotes: false, scheduledOpCloud: false, updateContentsWrite: false, applyMerge: false };\n\n/** A drift Op whose update asks for `contents: write`; a chant before the chant#4631 ruling refuses it. */\nexport const CONTENTS_WRITE_PROBE = {\n name: \"plywood-probe\",\n trigger: { kind: \"cron\", schedule: \"0 6 * * *\" },\n findingMode: \"issue\",\n update: { command: \"true\", permissions: { contents: \"write\" } },\n} as const;\n\n/** Whether `assertScheduledOpCloud` passes the probe; false when it refuses it or is missing. */\nexport async function acceptsContentsWrite(load: () => Promise<unknown>): Promise<boolean> {\n try {\n const m = (await load()) as { assertScheduledOpCloud?: (spec: unknown) => void };\n if (typeof m.assertScheduledOpCloud !== \"function\") return false;\n m.assertScheduledOpCloud(structuredClone(CONTENTS_WRITE_PROBE));\n return true;\n } catch {\n return false;\n }\n}\n\nasync function has(load: () => Promise<unknown>, name: string, type: \"function\" | \"object\" = \"function\"): Promise<boolean> {\n try {\n const m = (await load()) as Record<string, unknown>;\n return typeof m[name] === type;\n } catch {\n return false;\n }\n}\n\nlet detected: Promise<ChantNext> | undefined;\n\n/** Which of the parity features the installed chant has. */\nexport function chantNext(): Promise<ChantNext> {\n detected ??= (async () => ({\n // @ts-ignore: the subpath is missing from chant 0.124.55 (chant#4624).\n checkJob: await has(() => import(\"@intentius/chant/ci-job-guard\"), \"checkJob\"),\n planFlags: await has(() => import(\"@intentius/chant/components/capability\"), \"PLAN_FLAG_ARGS\", \"object\"),\n staleNotes: await has(() => import(\"@intentius/chant/pr-post\"), \"markStaleNotes\"),\n // @ts-ignore: the subpath is missing from chant 0.124.55 (chant#4631).\n scheduledOpCloud: await has(() => import(\"@intentius/chant/scheduled-op-cloud\"), \"assertScheduledOpCloud\"),\n // @ts-ignore: the subpath is missing from chant 0.124.55 (chant#4631).\n updateContentsWrite: await acceptsContentsWrite(() => import(\"@intentius/chant/scheduled-op-cloud\")),\n // @ts-ignore: the subpath is missing from chant 0.124.55 (chant#4636).\n applyMerge: await has(() => import(\"@intentius/chant/pr-merge\"), \"mergeAfterApply\"),\n }))();\n return detected;\n}\n\n/**\n * Tests say which features chant has; a key left out is missing, so a\n * test reads the same against the pin and a local chant. `reset` goes back\n * to the real imports.\n */\nexport function setChantNextForTests(has: Partial<ChantNext> | \"reset\"): void {\n detected = has === \"reset\" ? undefined : Promise.resolve({ ...NONE, ...has });\n}\n\n/** Whether the installed chant has chant#4629's responses: a refused wave's diff, a failed apply's triage, the description check. */\nexport function hasChantRespond(chant: Pick<ChantProduct, \"CI_RESPOND_FLOOR\"> | undefined): boolean {\n return typeof chant?.CI_RESPOND_FLOOR === \"string\";\n}\n\n/** Whether the installed chant's `build --pr-loop` takes the responses and the decide service (`PR_LOOP_BUILD_FLAGS_FLOOR`). */\nexport function hasChantPrLoopFlags(chant: Pick<ChantProduct, \"PR_LOOP_BUILD_FLAGS_FLOOR\"> | undefined): boolean {\n return typeof chant?.PR_LOOP_BUILD_FLAGS_FLOOR === \"string\";\n}\n\n/** Whether the installed chant has chant#4630's approval status, `<product>/approval` on a pull request's head. */\nexport function hasChantApprovalStatus(chant: Pick<ChantProduct, \"APPROVAL_STATUS_FLOOR\"> | undefined): boolean {\n return typeof chant?.APPROVAL_STATUS_FLOOR === \"string\";\n}\n\n/** Whether the installed chant posts that status for `pull-request` waves too, which are plywood's (chant#4630 ruling). */\nexport function hasChantPullRequestApprovalStatus(chant: Pick<ChantProduct, \"APPROVAL_STATUS_PULL_REQUEST_FLOOR\"> | undefined): boolean {\n return typeof chant?.APPROVAL_STATUS_PULL_REQUEST_FLOOR === \"string\";\n}\n\n/** One drifted attribute and who changed it (chant `Attribution`, `@intentius/chant/ci-audit`). */\nexport interface ChantAttribution {\n member: string;\n address: string;\n path: string;\n actor?: string;\n source: string;\n detail: string;\n}\n\n/** The part of `@intentius/chant/ci-audit` (chant#4632) `plywood drift` calls. */\nexport interface ChantAudit {\n parseAuditLogSetting(text: string): { cloud: string; region?: string } | { error: string };\n attributeDrift(doc: { records: unknown[] }, options?: { auditLogs?: Record<string, unknown> }): Promise<{ attributions: ChantAttribution[]; notes: string[] }>;\n routeAttributions(attributions: readonly ChantAttribution[]): { lines: string[] };\n}\n\nlet audit: Promise<ChantAudit | undefined> | undefined;\n\n/** chant's audit-log reads (chant#4632), or undefined when the installed chant lacks them. */\nexport function chantAudit(): Promise<ChantAudit | undefined> {\n audit ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.55 (chant#4632).\n const m = (await import(\"@intentius/chant/ci-audit\")) as Record<string, unknown>;\n return typeof m.attributeDrift === \"function\" && typeof m.routeAttributions === \"function\" && typeof m.parseAuditLogSetting === \"function\" ? (m as unknown as ChantAudit) : undefined;\n } catch {\n return undefined;\n }\n })();\n return audit;\n}\n\n/** Tests stand in chant's audit-log reads, or none; `reset` goes back to the real import. */\nexport function setChantAuditForTests(fake: ChantAudit | undefined | \"reset\"): void {\n audit = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n", "/**\n * Jobs of the team's own in the workflow file plywood writes. chant's\n * generator writes the whole file, so before it does, plywood takes each job\n * of the old file that the new one does not have and that runs no plywood\n * line, and puts it back after chant's jobs, as it was written, comments\n * and all. A second `plywood init` or `plywood ci` then keeps a job someone\n * added by hand and changes nothing else.\n *\n * The blocks are read as text by their indentation, so a job keeps its\n * formatting: under `jobs:` at two spaces on GitHub and Forgejo, and at the\n * top level on GitLab, where the keywords that are not jobs stay chant's.\n */\nimport type { ForgeKind } from \"../chant-product\";\n\n/** The line above the jobs kept, which says where they come from. */\nexport const OWN_JOBS_LINE = \"# Your own jobs, kept as they are by plywood init and plywood ci.\";\n\n/** GitLab's top-level keys that are not jobs. */\nconst GITLAB_KEYWORDS = new Set([\"default\", \"include\", \"stages\", \"variables\", \"workflow\", \"image\", \"services\", \"cache\", \"before_script\", \"after_script\", \"spec\"]);\n\n/** The bin a generated job runs; a job that runs it is plywood's. */\nconst PLYWOOD_LINE = /\\bplywood\\b\\s+(components|ci|run|lock|unlock|check|preview|up|drift)\\b/;\n\nconst KEY = /^([A-Za-z0-9_.-]+|\"[^\"]+\"|'[^']+'):(\\s|$)/;\n\nfunction indentOf(line: string): number {\n return line.length - line.trimStart().length;\n}\n\nfunction isContent(line: string): boolean {\n const t = line.trim();\n return t !== \"\" && !t.startsWith(\"#\");\n}\n\n/** Each job's block of lines, by name, in file order. */\nexport function jobBlocks(text: string, forge: ForgeKind): Map<string, string> {\n const lines = text.split(\"\\n\");\n const out = new Map<string, string>();\n let start = 0;\n let end = lines.length;\n let depth = 0;\n if (forge !== \"gitlab\") {\n const at = lines.findIndex((l) => /^jobs:\\s*(#.*)?$/.test(l));\n if (at < 0) return out;\n start = at + 1;\n const next = lines.findIndex((l, i) => i > at && indentOf(l) === 0 && isContent(l));\n end = next < 0 ? lines.length : next;\n depth = 2;\n }\n let name: string | undefined;\n let body: string[] = [];\n const flush = (): void => {\n if (name !== undefined) {\n while (body.length > 0 && body[body.length - 1]!.trim() === \"\") body.pop();\n out.set(name, body.join(\"\\n\"));\n }\n name = undefined;\n body = [];\n };\n for (let i = start; i < end; i++) {\n const line = lines[i]!;\n if (isContent(line) && indentOf(line) === depth) {\n const m = KEY.exec(line.slice(depth));\n flush();\n if (m) {\n name = m[1]!.replace(/^[\"']|[\"']$/g, \"\");\n body = [line];\n }\n continue;\n }\n if (isContent(line) && indentOf(line) < depth) {\n flush();\n continue;\n }\n if (name !== undefined) body.push(line);\n }\n flush();\n if (forge === \"gitlab\") for (const k of [...out.keys()]) if (GITLAB_KEYWORDS.has(k)) out.delete(k);\n return out;\n}\n\n/** The jobs of `previous` that `generated` lacks and that run no plywood line: the team's own. */\nexport function ownJobs(previous: string, generated: string, forge: ForgeKind): Map<string, string> {\n const ours = jobBlocks(generated, forge);\n const out = new Map<string, string>();\n for (const [name, block] of jobBlocks(previous, forge)) {\n if (ours.has(name) || PLYWOOD_LINE.test(block)) continue;\n out.set(name, block);\n }\n return out;\n}\n\n/** `generated` with `own` put back after chant's jobs, under {@link OWN_JOBS_LINE}. */\nexport function withOwnJobs(generated: string, own: Map<string, string>, forge: ForgeKind): string {\n if (own.size === 0) return generated;\n const indent = forge === \"gitlab\" ? \"\" : \" \";\n const block = [`${indent}${OWN_JOBS_LINE}`, ...own.values()].join(\"\\n\");\n const lines = generated.replace(/\\n+$/, \"\").split(\"\\n\");\n if (forge !== \"gitlab\") {\n const at = lines.findIndex((l) => /^jobs:\\s*(#.*)?$/.test(l));\n if (at >= 0) {\n const next = lines.findIndex((l, i) => i > at && indentOf(l) === 0 && isContent(l));\n if (next >= 0) {\n let cut = next;\n while (cut > at + 1 && lines[cut - 1]!.trim() === \"\") cut--;\n return [...lines.slice(0, cut), block, ...lines.slice(cut)].join(\"\\n\") + \"\\n\";\n }\n }\n }\n return [...lines, block].join(\"\\n\") + \"\\n\";\n}\n\n/** The old file's own jobs carried into the new one; `previous` undefined means there was no file. */\nexport function keepOwnJobs(previous: string | undefined, generated: string, forge: ForgeKind): { text: string; kept: string[] } {\n if (previous === undefined) return { text: generated, kept: [] };\n const own = ownJobs(previous, generated, forge);\n return { text: withOwnJobs(generated, own, forge), kept: [...own.keys()] };\n}\n", "/**\n * The note job's read of the control repo (plywood#28, chant#4619). With a\n * control repo in plywood.yml, the note marks each cross-stack edge `stale`\n * or `current` from the control repo's apply records, and for that the note\n * job reads the control repo's `chant/lifecycle` before `pr-post`. chant's\n * generator writes that step itself when its loop names a control repo, but\n * `plywood ci` runs the generator over argv, which carries no control repo.\n * So plywood takes the step chant hands back as `productPipelineJobs(...).post.control`\n * and puts it into the generated note job, just before the post. The step is\n * chant's: its name, its environment and its script. plywood places it and\n * adds nothing.\n *\n * A chant before chant#4619 hands back no step, and the file stays as\n * chant wrote it: every edge then reads `unknown`. A note job that already\n * has the step, from a chant whose generator reads the control repo itself,\n * is left alone.\n */\nimport { emitYAML } from \"@intentius/chant/yaml\";\nimport type { ForgeKind } from \"../chant-product\";\n\n/** chant's `ControlNoteCheckout` (control/dispatch.ts): the step that reads the control repo's records. */\nexport interface NoteControlStep {\n stepName: string;\n env: Record<string, string>;\n script: string;\n}\n\n/** The note job chant's pull request generator writes (`PR_PLAN_NOTE_JOB`). */\nexport const NOTE_JOB = \"plan-note\";\n\nfunction indentOf(line: string): number {\n return line.length - line.trimStart().length;\n}\n\n/** The lines of the job `name` in `lines`: [start, end), or undefined. Jobs sit at `depth` spaces. */\nfunction jobRange(lines: readonly string[], name: string, depth: number): [number, number] | undefined {\n const head = new RegExp(`^${\" \".repeat(depth)}${name}:\\\\s*(#.*)?$`);\n const start = lines.findIndex((l) => head.test(l));\n if (start < 0) return undefined;\n let end = lines.length;\n for (let i = start + 1; i < lines.length; i++) {\n const l = lines[i]!;\n if (l.trim() === \"\" || l.trimStart().startsWith(\"#\")) continue;\n if (indentOf(l) <= depth) {\n end = i;\n break;\n }\n }\n return [start, end];\n}\n\n/**\n * `text` with `step` in the note job, before the line that posts the note.\n * Unchanged when there is no step, no note job, no post line, or the job\n * already reads the control repo.\n */\nexport function withNoteControl(text: string, forge: ForgeKind, step: NoteControlStep | undefined): string {\n if (!step) return text;\n const lines = text.split(\"\\n\");\n const range = jobRange(lines, NOTE_JOB, forge === \"gitlab\" ? 0 : 2);\n if (!range) return text;\n const [start, end] = range;\n const job = lines.slice(start, end);\n if (job.some((l) => l.includes(step.stepName)) || job.some((l) => l.includes(\"CHANT_CONTROL_DIR=\"))) return text;\n if (forge === \"gitlab\") {\n // The script's items sit at four spaces; the step's script goes in as one more item, before pr-post's.\n const at = job.findIndex((l) => /^ {4}- /.test(l) && l.includes(\"components pr-post\"));\n if (at < 0) return text;\n const item = emitYAML([step.script], 2).replace(/^\\n/, \"\");\n return [...lines.slice(0, start + at), ...item.split(\"\\n\"), ...lines.slice(start + at)].join(\"\\n\");\n }\n // GitHub and Forgejo: steps at six spaces; the post step's name starts with \"Post the plan note\".\n const at = job.findIndex((l) => /^ {6}- name: Post the plan note\\b/.test(l));\n if (at < 0) return text;\n const item = emitYAML([{ name: step.stepName, if: \"always()\", ...(Object.keys(step.env).length ? { env: step.env } : {}), run: step.script }], 3).replace(/^\\n/, \"\");\n return [...lines.slice(0, start + at), ...item.split(\"\\n\"), ...lines.slice(start + at)].join(\"\\n\");\n}\n", "/**\n * Writing the workflow file, for `plywood init` and `plywood ci` alike.\n * chant's generator writes the file in process with plywood's words\n * (chant#4550 ruling C); plywood holds no job YAML of its own. Around that\n * call this module keeps the team's own jobs from the old file\n * (./own-jobs.ts), puts the old file back when chant fails, and says whether\n * anything changed.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, isAbsolute, join } from \"node:path\";\nimport type { ChantProduct, ForgeKind } from \"../chant-product\";\nimport type { ProductWordsInput } from \"../words\";\nimport { keepOwnJobs } from \"./own-jobs\";\nimport { withNoteControl, type NoteControlStep } from \"./note-control\";\n\nexport interface WriteWorkflowInput {\n /** Where the build runs: the repository root. */\n root: string;\n forge: ForgeKind;\n /** The file, relative to `root` or absolute. */\n output: string;\n /** chant's build argv without `--output`. */\n argv: string[];\n words: ProductWordsInput;\n /** chant's `post.control` (chant#4619): the note job's read of the control repo, placed before the post. */\n noteControl?: NoteControlStep;\n}\n\nexport interface WriteWorkflowResult {\n code: number;\n file: string;\n status: \"written\" | \"unchanged\" | \"failed\";\n /** The team's own jobs carried over from the old file. */\n kept: string[];\n}\n\nexport async function writeWorkflow(chant: Pick<ChantProduct, \"runChantInProcess\">, input: WriteWorkflowInput): Promise<WriteWorkflowResult> {\n const file = isAbsolute(input.output) ? input.output : join(input.root, input.output);\n const previous = existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n mkdirSync(dirname(file), { recursive: true });\n const code = await chant.runChantInProcess([...input.argv, \"--output\", file], input.words);\n if (code !== 0 || !existsSync(file)) {\n if (previous !== undefined) writeFileSync(file, previous);\n return { code: code !== 0 ? code : 1, file, status: \"failed\", kept: [] };\n }\n const generated = withNoteControl(readFileSync(file, \"utf8\"), input.forge, input.noteControl);\n const { text, kept } = keepOwnJobs(previous, generated, input.forge);\n writeFileSync(file, text);\n return { code, file, status: text === previous ? \"unchanged\" : \"written\", kept };\n}\n", "/**\n * Review stacks (plywood#15): a stack per open pull request, `pr-<n>`, made\n * from the template stack's config, updated from each push, and destroyed\n * and removed when the pull request closes or its TTL passes. plywood holds\n * the words and the config (src/config/review-stacks.ts); chant runs them:\n *\n * chant core `ci.prEnvironment`: the `components pr-env up`,\n * `down` and `sweep` jobs, the gate `pr-env` on a\n * non-empty plan, the records on the workspace ledger\n * (`_pr-envs/records.jsonl`, chant#4551's\n * `appendPrEnvRecord`) and the TTL sweep\n * chant pulumi lexicon the three review stack argv, `stack init`,\n * `destroy --yes` and `stack rm --yes`, on `pr-*`\n * names alone (`initReviewStack`, `removeReviewStack`);\n * under `pr-<n>`, pulumi-up applies `<project>/pr-<n>`\n * (`pr-<n>-<reviewSuffix>`), `pr-env down` tears it\n * down through the plugin's `prEnvTeardown`, and the\n * plugin claims the `project/stack` template\n * (`prEnvTemplate`, chant#4609)\n *\n * `plywood ci` and `plywood init` add the review stack jobs (`--pr-env` on\n * chant's build) only when plywood.yml sets `review_stacks` and the\n * installed pulumi lexicon has those argv, so a chant that cannot remove a\n * review stack never gets jobs that make one.\n *\n * A pull request's review stack update waits for an approval of its digest\n * under gate `pr-env`, which a person gives with\n * `plywood approve review --pr <n> --plan <digest>`.\n */\n\n/** chant's gate a review stack's update waits at (`PR_ENV_GATE`). */\nexport const REVIEW_GATE = \"pr-env\";\n\n/** The gate word a person types after `plywood approve`. */\nexport const REVIEW_GATE_WORD = \"review\";\n\n/** chant's op a pull request's review stack is recorded under. */\nexport const reviewOp = (pr: string): string => `pr-${pr}`;\n\nlet cached: Promise<boolean> | undefined;\n\n/**\n * Whether the installed pulumi lexicon runs review stacks end to end: it\n * creates and removes them (`initReviewStack`, `removeReviewStack`), and its\n * plugin claims a `project/stack` template (`pulumiPlugin.prEnvTemplate`,\n * chant#4609), so `ci.prEnvironment.template` needs no chant.config.ts\n * environment and `pr-env down` destroys what `pr-env up` made through the\n * plugin's `prEnvTeardown`. Without all of it, plywood writes neither\n * `ci.prEnvironment` nor the review stack jobs.\n */\nexport function chantReviewStacks(): Promise<boolean> {\n cached ??= (async () => {\n try {\n // @ts-ignore: initReviewStack, removeReviewStack and the plugin's prEnvTemplate are newer than the lexicon at 0.124.54.\n const m: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n const plugin = m.pulumiPlugin as { prEnvTemplate?: unknown; prEnvTeardown?: unknown } | undefined;\n return (\n typeof m.initReviewStack === \"function\" &&\n typeof m.removeReviewStack === \"function\" &&\n typeof plugin?.prEnvTemplate === \"function\" &&\n typeof plugin?.prEnvTeardown === \"function\"\n );\n } catch {\n return false;\n }\n })();\n return cached;\n}\n\n/**\n * The `reviewSuffix` a review stack's pulumi-up step takes (chant#4609):\n * `shop` of `review_stacks.name: pr-{number}-shop`, or undefined for the\n * default `pr-{number}`.\n */\nexport function reviewSuffixOf(pattern: string | undefined): string | undefined {\n const m = pattern ? /^pr-\\{number\\}-([a-z0-9][a-z0-9-]*)$/.exec(pattern) : null;\n return m ? m[1] : undefined;\n}\n\n/** Tests stand in an answer; `reset` goes back to the real import. */\nexport function setChantReviewStacksForTests(v: boolean | \"reset\"): void {\n cached = v === \"reset\" ? undefined : Promise.resolve(v);\n}\n\n/** Why the review stack jobs were left out, for `plywood ci` and `plywood init`. */\nexport const REVIEW_STACKS_NEED_CHANT =\n \"review_stacks is set, and the installed @intentius/chant-lexicon-pulumi cannot run a review stack end to end (initReviewStack, removeReviewStack, and the plugin's prEnvTemplate and prEnvTeardown from chant#4609), so plywood writes no ci.prEnvironment and the workflow has no review stack jobs yet\";\n", "/**\n * The update on merge in the generated workflow: one job per wave of\n * `.chant/op-waves/pulumi-up.spec.json`, from productPipelineJobs' `waves`\n * (chant#4550). Each job runs `plywood run wave --spec <file> --wave <k>`,\n * chant's op-wave job through plywood's bin, so each run applies through the\n * spec's pulumi-up step (chant#4541) and records on chant's ledger.\n *\n * `plywood ci` calls this after the pull request workflow is written:\n * 1. The spec file gets plywood's names (op pulumi-up, gates wave-{k}, and\n * each wave's approval taken from the pull request's `up` gate), as\n * productPipelineJobs returns it. The wave jobs read the file at base,\n * so it is written beside the workflow and committed with it.\n * 2. chant's op-waves generator (`run --generate <forge> --spec <file>`)\n * writes the waves workflow.\n * 3. On a chant before chant#4607, each job line chant wrote as\n * `chant run wave ...` becomes the line productPipelineJobs gave, with\n * plywood's bin. From chant#4607 the generator writes the words' bin in\n * the wave, resume and plans jobs itself (`OpWavesPipelineOptions.bin`),\n * so the file is left as chant wrote it.\n */\nimport { existsSync, readdirSync, readFileSync, writeFileSync, mkdirSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { hasChant4607, type ChantProduct, type ForgeKind, type ProductPipelineJobs } from \"./chant-product\";\nimport type { ExitTable } from \"./exit-codes\";\nimport type { StageIo } from \"./stages\";\nimport { PRODUCT, type ProductWordsInput } from \"./words\";\n\n/** Where chant's op-waves generator writes for each forge (chant run-generate.ts `DEFAULT_OP_PIPELINE_DIRS`). */\nexport const WAVES_OUTPUT_DIR: Readonly<Record<ForgeKind, string>> = {\n github: \".github/workflows\",\n forgejo: \".forgejo/workflows\",\n gitlab: \".\",\n};\n\n/** The waves part of productPipelineJobs: the spec with plywood's names, its file, and a job per wave. */\nexport type WaveJobs = NonNullable<ProductPipelineJobs[\"waves\"]>;\n\n/** Each wave job's line as chant's generator writes it, and the line with plywood's bin. */\nexport function binLines(waves: Pick<WaveJobs, \"jobs\">, bin: string): Array<{ chant: string; product: string }> {\n const binArgs = bin.split(/\\s+/).filter(Boolean);\n return waves.jobs.map((job) => {\n const own = job.command.slice(0, binArgs.length).join(\" \") === binArgs.join(\" \");\n const rest = own ? job.command.slice(binArgs.length) : job.command.slice(1);\n return { chant: [\"chant\", ...rest].join(\" \"), product: [...binArgs, ...rest].join(\" \") };\n });\n}\n\n/** `text` with every chant wave line in place of plywood's. */\nexport function withBinLines(text: string, lines: ReadonlyArray<{ chant: string; product: string }>): string {\n // Longest first, so `... --wave 1` does not eat into `... --wave 1 --share 2`.\n const sorted = [...lines].sort((a, b) => b.chant.length - a.chant.length);\n return text.replace(/chant run wave [^\\n\"']*/g, (found) => {\n const hit = sorted.find((l) => found.trimEnd() === l.chant);\n return hit ? hit.product : found;\n });\n}\n\n/** The files chant's generator wrote for `specFile`: those whose header names `--spec <specFile>`. */\nfunction generatedFor(dir: string, specFile: string): string[] {\n if (!existsSync(dir)) return [];\n return readdirSync(dir)\n .filter((f) => /\\.ya?ml$/.test(f))\n .map((f) => join(dir, f))\n .filter((p) => (readFileSync(p, \"utf8\").split(\"\\n\", 1)[0] ?? \"\").includes(`--spec ${specFile}`));\n}\n\n/**\n * Write the spec with plywood's names, have chant generate the waves\n * workflow, and put plywood's bin in its job lines. Returns chant's exit\n * code, or `failed` when no file came out.\n */\nexport async function writeWaveJobs(\n chant: ChantProduct,\n forge: ForgeKind,\n waves: WaveJobs,\n words: ProductWordsInput,\n table: ExitTable,\n io: StageIo,\n): Promise<number> {\n const specPath = join(io.cwd, waves.specFile);\n const specText = JSON.stringify(waves.spec, null, 2) + \"\\n\";\n const before = existsSync(specPath) ? readFileSync(specPath, \"utf8\") : undefined;\n if (before !== specText) {\n mkdirSync(dirname(specPath), { recursive: true });\n writeFileSync(specPath, specText);\n io.err(`${PRODUCT} ci: wrote ${waves.specFile} with plywood's op and gates; commit it with the workflow`);\n }\n const outDir = WAVES_OUTPUT_DIR[forge];\n const code = await chant.runChantInProcess([\"run\", \"--generate\", forge, \"--spec\", waves.specFile, \"--output\", outDir], words);\n if (code !== table.done) return code;\n const files = generatedFor(join(io.cwd, outDir), waves.specFile);\n if (files.length === 0) {\n io.err(`${PRODUCT} ci: chant wrote no waves workflow for ${waves.specFile} under ${outDir}`);\n return table.failed;\n }\n // chant#4607: the generator writes plywood's bin itself; before it, plywood swaps the lines.\n const lines = hasChant4607(chant) ? undefined : binLines(waves, words.bin);\n for (const file of files) {\n if (lines) {\n const text = readFileSync(file, \"utf8\");\n const next = withBinLines(text, lines);\n if (next !== text) writeFileSync(file, next);\n }\n io.err(`${PRODUCT} ci: waves workflow at ${file.slice(io.cwd.length + 1)}`);\n }\n if (forge === \"gitlab\") {\n io.err(`${PRODUCT} ci: GitLab reads one root file; include the waves file from .gitlab-ci.yml (include: local: <file>)`);\n }\n return table.done;\n}\n", "/**\n * plywood.yml's `agent` on chant's agent job (chant#4616). The job is\n * chant's: plywood maps its keys onto chant's agent settings and writes the\n * Op specs chant's generator reads.\n *\n * agent.comment true answers `/plywood agent <ask>`: productPipelineJobs\n * returns the agent's Op spec, written to\n * .chant/ops/plywood-agent.spec.json and generated with\n * `run --generate`, as the review and drift jobs are\n * agent.drift true, with respond.drift: pull-request, puts chant's\n * drift agent on each scheduled drift Op (src/drift.ts):\n * after a drift run, the agent opens or updates a pull\n * request from plywood/agent/<op>\n * agent.command, agent.key_env, agent.timeout, agent.max_runs, agent.token_env\n * chant's command, keyEnv, timeout, maxRuns and tokenEnv\n *\n * The agent may not change plywood.yml or the policy directory, beside\n * chant's own guarded paths.\n *\n * Everything here is behind a feature-detect: a chant without\n * `CI_AGENT_FLOOR` on its ci-product entry gets no agent jobs, and plywood\n * says so.\n */\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { toChantSettings, type ChantRunner, type ChantRunnerSpec } from \"./chant-config\";\nimport type { ChantProduct, ForgeKind } from \"./chant-product\";\nimport { agentOf, type AgentSettings } from \"./config/agents\";\nimport { CONFIG_NAMES, type RawConfig } from \"./config/index\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { chantPipelineOptions } from \"./images\";\nimport type { StageIo } from \"./stages\";\nimport { PRODUCT, PRODUCT_WORDS, type ProductWordsInput } from \"./words\";\n\n/** The agent's Op name: its workflow, its jobs and its runs on the ledger. */\nexport const AGENT_OP = \"plywood-agent\";\nexport const AGENT_SPEC_FILE = \".chant/ops/plywood-agent.spec.json\";\n\n/** The message when the installed chant has no agent job. */\nexport const AGENT_NEEDS_CHANT = \"agent needs a chant with the agent job (chant#4616), and the installed one has none, so no agent job was written\";\n\n/** Whether the installed chant has the agent job: `CI_AGENT_FLOOR` on its ci-product entry. */\nexport function hasChantAgent(chant: ChantProduct | undefined): boolean {\n return typeof chant?.CI_AGENT_FLOOR === \"string\";\n}\n\n/** A stage's runner from plywood's `runners`: one for all, or the stage's over the default. */\nexport function stageRunner(runner: ChantRunner | undefined, stage: \"preview\" | \"up\" | \"drift\"): ChantRunnerSpec | undefined {\n if (runner === undefined) return undefined;\n if (typeof runner === \"string\" || Array.isArray(runner) || \"group\" in runner) return runner as ChantRunnerSpec;\n const staged = runner as Partial<Record<string, ChantRunnerSpec>>;\n return staged[stage] ?? staged.default;\n}\n\n/** Paths the agent may not change beside chant's: plywood.yml and the Rego directory. */\nexport function agentGuarded(doc: RawConfig): string[] {\n const policy = (toChantSettings({ doc }).ci.policy as { path?: unknown } | undefined)?.path;\n return [...CONFIG_NAMES, ...(typeof policy === \"string\" && policy.trim() !== \"\" ? [`${policy.replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\")}/`] : [])];\n}\n\n/** chant's agent settings from plywood.yml's `agent` (chant `OpAgentSpec` without the trigger). */\nexport function chantAgentOptions(a: AgentSettings, doc: RawConfig): Record<string, unknown> {\n return {\n ...(a.command ? { command: a.command } : {}),\n keyEnv: a.keyEnv,\n ...(a.timeout !== undefined ? { timeout: a.timeout } : {}),\n ...(a.maxRuns !== undefined ? { maxRuns: a.maxRuns } : {}),\n // chant#4616's push token; without it the push job uses the job token, whose GitHub push starts no workflow.\n ...(a.tokenEnv !== undefined ? { tokenEnv: a.tokenEnv } : {}),\n guarded: agentGuarded(doc),\n };\n}\n\n/**\n * The `agent` and `runner` fields of each scheduled drift Op (chant#4616),\n * or nothing when the installed chant lacks them. The runner is\n * `runners.drift`, else `runners.default`, else the one runner; the agent\n * rides on respond.drift: pull-request with agent.drift true.\n */\nexport function driftOpFields(chant: ChantProduct | undefined, doc: RawConfig, op: string, respond: string): Record<string, unknown> {\n if (!hasChantAgent(chant)) return {};\n const runner = stageRunner(toChantSettings({ doc }).pipeline.runner, \"drift\");\n const a = agentOf(doc);\n const wantsAgent = respond === \"pull-request\" && a?.drift === true;\n const agent = wantsAgent\n ? chant!.productDriftAgent\n ? chant!.productDriftAgent(PRODUCT_WORDS, op, chantAgentOptions(a!, doc))\n : { on: \"drift\", ...chantAgentOptions(a!, doc) }\n : undefined;\n return { ...(runner !== undefined ? { runner } : {}), ...(agent ? { agent } : {}) };\n}\n\n/** The agent's spec file: productPipelineJobs' Op spec, with plywood's image and lines. */\nexport function agentOpSpec(spec: Record<string, unknown>, doc: RawConfig): { ops: unknown[]; options: Record<string, unknown> } {\n const p = toChantSettings({ doc }).pipeline;\n const engine = chantPipelineOptions({ ...(p.image ? { image: p.image } : {}), ...(p.engineSetup ? { engineSetup: p.engineSetup } : {}) }, false);\n const runner = stageRunner(p.runner, \"preview\");\n return {\n ops: [{ ...spec, ...(runner !== undefined && spec.runner === undefined ? { runner } : {}) }],\n options: {\n ...(engine.beforeScript ? { beforeScript: engine.beforeScript } : {}),\n ...(engine.image ? { image: engine.image } : {}),\n },\n };\n}\n\nconst OP_OUTPUT_DIR: Readonly<Record<ForgeKind, string>> = { github: \".github/workflows\", forgejo: \".forgejo/workflows\", gitlab: \".\" };\n\nfunction writeIfChanged(cwd: string, file: string, text: string): boolean {\n const path = join(cwd, file);\n if (existsSync(path) && readFileSync(path, \"utf8\") === text) return false;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, text);\n return true;\n}\n\n/**\n * The comment agent's jobs, for `plywood ci`, when plywood.yml sets\n * agent.comment. productPipelineJobs names the comment and builds the spec;\n * chant's generator writes the agent job and the push job.\n */\nexport async function writeAgentJobs(chant: ChantProduct, forge: ForgeKind, env: string, doc: RawConfig, words: ProductWordsInput, table: ExitTable, io: StageIo): Promise<number> {\n const a = agentOf(doc);\n if (!a?.comment) return table.done;\n if (!hasChantAgent(chant)) {\n io.err(`${PRODUCT} ci: ${AGENT_NEEDS_CHANT}`);\n return table.done;\n }\n const agentWords: ProductWordsInput = { ...words, commands: { ...words.commands, agent: \"agent\" } };\n let spec: Record<string, unknown> | undefined;\n try {\n spec = chant.productPipelineJobs(forge, env, { words: agentWords, agent: { name: AGENT_OP, ...chantAgentOptions(a, doc) } }).agent?.spec;\n } catch (e) {\n io.err(`${PRODUCT} ci: agent: ${(e as Error).message}`);\n return table.failed;\n }\n if (!spec) {\n io.err(`${PRODUCT} ci: chant returned no agent spec for /${PRODUCT} agent, so no agent job was written`);\n return table.done;\n }\n if (writeIfChanged(io.cwd, AGENT_SPEC_FILE, JSON.stringify(agentOpSpec(spec, doc), null, 2) + \"\\n\")) io.err(`${PRODUCT} ci: wrote ${AGENT_SPEC_FILE}`);\n const outDir = OP_OUTPUT_DIR[forge];\n const code = await chant.runChantInProcess([\"run\", \"--generate\", forge, \"--spec\", AGENT_SPEC_FILE, \"--output\", outDir], agentWords);\n if (code !== table.done) return code;\n const dir = join(io.cwd, outDir);\n const files = existsSync(dir)\n ? readdirSync(dir).filter((f) => /\\.ya?ml$/.test(f) && (readFileSync(join(dir, f), \"utf8\").split(\"\\n\", 1)[0] ?? \"\").includes(`--spec ${AGENT_SPEC_FILE}`))\n : [];\n for (const f of files) io.err(`${PRODUCT} ci: agent jobs at ${join(outDir, f).replace(/^\\.\\//, \"\")}, answering /${PRODUCT} agent <ask>`);\n io.err(`${PRODUCT} ci: the agent job reads the model's key from ${a.keyEnv}; set it from a secret${a.maxRuns === undefined ? \", and set agent.max_runs to limit how often it runs\" : \"\"}`);\n if (forge === \"github\" && a.tokenEnv === undefined) io.err(`${PRODUCT} ci: the push job pushes with the job token, which starts no workflow on GitHub, so the agent's commit gets no preview; set agent.token_env to a secret holding a user's or app's token`);\n else if (a.tokenEnv !== undefined) io.err(`${PRODUCT} ci: the push job pushes with ${a.tokenEnv}; set it from a secret`);\n if (forge === \"gitlab\") io.err(`${PRODUCT} ci: on GitLab a pipeline of the default branch started with CHANT_AGENT_PR and CHANT_AGENT_ASK runs the agent; scope CHANT_FORGE_TOKEN to environment ${AGENT_OP}-push`);\n return table.done;\n}\n", "/**\n * The drift event `plywood drift` sends (plywood#30). When plywood.yml's\n * `notify.on` takes `drift` (or `notify.on` is left out, which takes every\n * event) and a run finds drift, the run sends one signed event through\n * chant's notify with plywood's words: chant's `driftNotifyFields` and\n * `productSendOptions` on `@intentius/chant/ci-product` (chant#4610), and\n * `makeNotifyEvent` and `sendNotify` on `@intentius/chant/notify`. The\n * event names the drifted stacks, the ones whose read failed, and the run's\n * fingerprint (each drifted stack's finding fingerprint, hashed together).\n *\n * A run whose finding is the last run's sends nothing. The last finding is\n * the drift issues: each drifted stack's issue carries its fingerprint, and\n * chant's `trackIssue` answers `unchanged` when the finding is the same. So\n * a run with `--forge` whose every drifted stack's issue is unchanged sends\n * nothing; a run without issues (no `--forge`, or `respond.drift: none`)\n * has no last finding and sends on every drift.\n *\n * On a chant without `driftNotifyFields` the run says no event was sent.\n * A failed delivery is a line on stderr and never changes the exit code.\n */\nimport { createHash } from \"node:crypto\";\nimport type { ChantNotifyConfig } from \"./config/observe\";\nimport type { DriftRow } from \"./words\";\n\n/** One stack's read, as the notice reads it. */\nexport interface DriftNoticeStack {\n stack: string;\n ok: boolean;\n drifted: number;\n rows: DriftRow[];\n issue?: { action: string };\n}\n\n/** The part of chant plywood calls to send the event. */\nexport interface ChantDriftNotify {\n driftNotifyFields(words: unknown, input: { changed: string[]; failed?: string[]; fingerprint?: string; project?: string; environment?: string }): unknown;\n productSendOptions(words: unknown, options?: Record<string, unknown>): Record<string, unknown>;\n makeNotifyEvent(fields: unknown, options?: { env?: NodeJS.ProcessEnv }): unknown;\n sendNotify(config: unknown, event: unknown, options?: Record<string, unknown>): Promise<Array<{ target: string; ok: boolean; detail: string }>>;\n /** chant's resolved words for plywood (`assertProductWords`). */\n words: unknown;\n}\n\n/** What the run did about the event, for the output. */\nexport interface DriftNotice {\n sent: boolean;\n /** Why nothing was sent, when nothing was. */\n reason?: string;\n fingerprint?: string;\n deliveries?: Array<{ target: string; ok: boolean; detail: string }>;\n}\n\n/** What a run on a chant without chant#4610's drift fields says. */\nexport const DRIFT_NOTIFY_NEEDS_CHANT = \"no drift event was sent: the installed chant has no driftNotifyFields (chant#4610)\";\n\n/** The run's fingerprint: each drifted stack and its finding's, sorted, hashed. */\nexport function runFingerprint(results: readonly DriftNoticeStack[], stackFingerprint: (rows: readonly DriftRow[]) => string): string {\n const parts = results.filter((r) => r.ok && r.drifted > 0).map((r) => `${r.stack}\\t${stackFingerprint(r.rows)}`).sort();\n return createHash(\"sha256\").update(parts.join(\"\\n\")).digest(\"hex\").slice(0, 16);\n}\n\n/** Whether `notify` takes the drift event. */\nexport function notifiesDrift(notify: ChantNotifyConfig | undefined): boolean {\n return notify !== undefined && (notify.events === undefined || notify.events.includes(\"drift\"));\n}\n\n/**\n * Send the run's drift event, or say why not. `chant` is undefined on a\n * chant without the drift fields.\n */\nexport async function sendDriftNotice(input: {\n notify: ChantNotifyConfig | undefined;\n results: readonly DriftNoticeStack[];\n stackFingerprint: (rows: readonly DriftRow[]) => string;\n chant: ChantDriftNotify | undefined;\n env: NodeJS.ProcessEnv;\n environment?: string;\n log: (line: string) => void;\n /** Tests pass a loopback fetch. */\n fetch?: unknown;\n}): Promise<DriftNotice | undefined> {\n if (!notifiesDrift(input.notify)) return undefined;\n const drifted = input.results.filter((r) => r.ok && r.drifted > 0);\n if (drifted.length === 0) return undefined;\n const fingerprint = runFingerprint(input.results, input.stackFingerprint);\n if (!input.chant) return { sent: false, reason: DRIFT_NOTIFY_NEEDS_CHANT, fingerprint };\n if (drifted.every((r) => r.issue?.action === \"unchanged\")) {\n return { sent: false, reason: \"no drift event was sent: every drifted stack's finding is the one its issue already holds\", fingerprint };\n }\n const failed = input.results.filter((r) => !r.ok).map((r) => r.stack);\n const c = input.chant;\n const fields = c.driftNotifyFields(c.words, {\n changed: drifted.map((r) => r.stack),\n ...(failed.length ? { failed } : {}),\n fingerprint,\n ...(input.environment ? { environment: input.environment } : {}),\n });\n const event = c.makeNotifyEvent(fields, { env: input.env });\n const deliveries = await c.sendNotify(input.notify, event, c.productSendOptions(c.words, { env: input.env, log: input.log, ...(input.fetch ? { fetch: input.fetch } : {}) }));\n return { sent: deliveries.some((d) => d.ok), fingerprint, deliveries, ...(deliveries.some((d) => d.ok) ? {} : { reason: \"no drift event was delivered\" }) };\n}\n\nlet loaded: Promise<Omit<ChantDriftNotify, \"words\"> | undefined> | undefined;\n\n/** chant's drift fields and notify, or undefined when the installed chant lacks them. */\nexport function chantDriftNotify(): Promise<Omit<ChantDriftNotify, \"words\"> | undefined> {\n loaded ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4550, #4610).\n const product: Record<string, unknown> = await import(\"@intentius/chant/ci-product\");\n const notify: Record<string, unknown> = await import(\"@intentius/chant/notify\");\n const fns = [product.driftNotifyFields, product.productSendOptions, notify.makeNotifyEvent, notify.sendNotify];\n if (!fns.every((f) => typeof f === \"function\")) return undefined;\n return {\n driftNotifyFields: product.driftNotifyFields as ChantDriftNotify[\"driftNotifyFields\"],\n productSendOptions: product.productSendOptions as ChantDriftNotify[\"productSendOptions\"],\n makeNotifyEvent: notify.makeNotifyEvent as ChantDriftNotify[\"makeNotifyEvent\"],\n sendNotify: notify.sendNotify as ChantDriftNotify[\"sendNotify\"],\n };\n } catch {\n return undefined;\n }\n })();\n return loaded;\n}\n\n/** Tests stand in chant's notify (or none); `reset` goes back to the real imports. */\nexport function setChantDriftNotifyForTests(fake: Omit<ChantDriftNotify, \"words\"> | undefined | \"reset\"): void {\n loaded = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n", "/**\n * plywood.yml's `env`, `pass`, `parallelism` and `environments` on the jobs\n * (plywood#29, src/config/jobs.ts):\n *\n * waves spec each wave's `variables`; its forge `environment` when all\n * its stacks share one, else one job group per environment;\n * `parallelism` on the spec (chant#4625)\n * drift Ops each Op's `variables` and its stack's `environment`\n * pull request `runners`, `variables`, `secrets` and `parallelism` for\n * chant's product pipeline and `build --pr-loop` (chant#4625)\n * forge check each pipeline's `forgeEnvironment`\n *\n * A passed secret is written as the forge's reference to it\n * (`${{ secrets.<name> }}` on GitHub and Forgejo, `$<name>` on GitLab),\n * never as a value. chant#4625 is feature-detected through\n * `@intentius/chant/parallelism`, a module it added; without it the waves\n * and drift jobs still get the variables and environments, which chant had\n * already, and the pull request jobs and `parallelism` say they need it.\n */\nimport type { ChantRunner, ChantRunnerSpec } from \"./chant-config\";\nimport type { ForgeKind } from \"./chant-product\";\nimport type { ForgeEnvironment, JobSettings } from \"./config/jobs\";\nimport { globMatches } from \"./config/images\";\n\nlet detected: Promise<boolean> | undefined;\n\n/** Whether the installed chant has chant#4625: runners, variables, secrets and parallelism on the pull request jobs, parallelism on op waves. */\nexport function hasChant4625(): Promise<boolean> {\n detected ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4625).\n const m: Record<string, unknown> = await import(\"@intentius/chant/parallelism\");\n return typeof m.mapLimited === \"function\" && typeof m.parallelismProblem === \"function\";\n } catch {\n return false;\n }\n })();\n return detected;\n}\n\n/** Tests say whether chant#4625 is there; `reset` goes back to the real import. */\nexport function setChant4625ForTests(has: boolean | \"reset\"): void {\n detected = has === \"reset\" ? undefined : Promise.resolve(has);\n}\n\n/** What `plywood ci` says when plywood.yml asks for something only chant#4625 does. */\nexport const JOBS_NEED_CHANT = \"needs chant's runners, variables, passed secrets and parallelism on the pull request jobs (chant#4625), which this chant lacks\";\n\n/** The forge's reference to a secret, as a job's variable value. */\nexport function secretReference(forge: ForgeKind, secret: string): string {\n return forge === \"gitlab\" ? `$${secret}` : `\\${{ secrets.${secret} }}`;\n}\n\n/** `env` and `pass` as one job's variables on `forge`. */\nexport function jobVariables(forge: ForgeKind, s: Pick<JobSettings, \"variables\" | \"secrets\">): Record<string, string> {\n const out: Record<string, string> = { ...s.variables };\n for (const [name, secret] of Object.entries(s.secrets)) {\n // On GitLab every CI/CD variable is in the job already; a secret under its own name needs no line.\n if (forge === \"gitlab\" && name === secret) continue;\n out[name] = secretReference(forge, secret);\n }\n return out;\n}\n\n/** The forge environment `environments` gives `stack`: the first glob that matches it. */\nexport function environmentFor(stack: string, s: Pick<JobSettings, \"environments\">): ForgeEnvironment | undefined {\n return s.environments.find((e) => globMatches(e.glob, stack))?.environment;\n}\n\nconst GROUP_NAME = /[^a-z0-9_-]+/g;\n\n/** A job group's name for an environment: lowercase letters, digits, `-` and `_`. */\nexport function groupName(environment: ForgeEnvironment | undefined, taken: Set<string>): string {\n let base = environment ? environment.name.toLowerCase().replace(GROUP_NAME, \"-\").replace(/^-+|-+$/g, \"\") || \"env\" : \"default\";\n if (!/^[a-z0-9]/.test(base)) base = `env-${base}`;\n let name = base;\n for (let i = 2; taken.has(name); i++) name = `${base}-${i}`;\n taken.add(name);\n return name;\n}\n\ninterface Wave {\n name: string;\n runs?: Array<{ target: string }>;\n shares?: number;\n groups?: unknown[];\n [k: string]: unknown;\n}\n\n/**\n * The waves spec with the jobs' settings on it. A wave whose stacks share\n * an environment runs in it; one whose stacks are in different environments\n * gets a job group per environment (stacks with none in `default`), so each\n * update job holds one environment's protection. A wave already split into\n * shares cannot also split by environment, and is refused by name.\n * `parallelism` goes on the spec only with chant#4625.\n */\nexport function withJobSettings(spec: Record<string, unknown>, s: JobSettings, forge: ForgeKind, opts: { parallelism: boolean }): Record<string, unknown> {\n const variables = jobVariables(forge, s);\n const waves = (Array.isArray(spec.waves) ? (spec.waves as Wave[]) : []).map((wave) => {\n const out: Wave = { ...wave };\n if (Object.keys(variables).length) out.variables = { ...((wave.variables as Record<string, string> | undefined) ?? {}), ...variables };\n if (s.environments.length === 0) return out;\n const runs = (wave.runs ?? []).map((r) => r.target);\n const byEnv = new Map<string, { environment: ForgeEnvironment | undefined; runs: string[] }>();\n for (const target of runs) {\n const environment = environmentFor(target, s);\n const key = environment ? JSON.stringify(environment) : \"\";\n const at = byEnv.get(key) ?? { environment, runs: [] };\n at.runs.push(target);\n byEnv.set(key, at);\n }\n delete out.environment;\n delete out.groups;\n if (byEnv.size === 1) {\n const [only] = byEnv.values();\n if (only!.environment) out.environment = { ...only!.environment };\n return out;\n }\n if (wave.shares !== undefined && wave.shares > 1) {\n throw new Error(`wave ${wave.name} holds stacks in ${byEnv.size} environments and is split into ${wave.shares} shares; a wave splits by one or the other, so give its stacks one environment or move them to waves of their own`);\n }\n const taken = new Set<string>();\n out.groups = [...byEnv.values()].map((g) => ({ name: groupName(g.environment, taken), runs: g.runs, ...(g.environment ? { environment: { ...g.environment } } : {}) }));\n return out;\n });\n return { ...spec, waves, ...(opts.parallelism && s.parallelism !== undefined && spec.step !== undefined ? { parallelism: s.parallelism } : {}) };\n}\n\n/** chant#4625's runner stages from plywood's: preview is plan, up is apply. */\nexport function prLoopRunners(runner: ChantRunner | undefined): { plan?: ChantRunnerSpec; apply?: ChantRunnerSpec; default?: ChantRunnerSpec } | undefined {\n if (runner === undefined) return undefined;\n if (typeof runner === \"string\" || Array.isArray(runner) || \"group\" in runner) return { default: runner as ChantRunnerSpec };\n const staged = runner as Partial<Record<\"default\" | \"preview\" | \"up\" | \"drift\", ChantRunnerSpec>>;\n const out = { ...(staged.preview ? { plan: staged.preview } : {}), ...(staged.up ? { apply: staged.up } : {}), ...(staged.default ? { default: staged.default } : {}) };\n return Object.keys(out).length ? out : undefined;\n}\n\n/** The pull request pipeline's options from chant#4625, for `productPipelineJobs`. */\nexport function prLoopJobOptions(s: JobSettings | undefined, runner: ChantRunner | undefined): Record<string, unknown> {\n const runners = prLoopRunners(runner);\n return {\n ...(runners ? { runners } : {}),\n ...(s && Object.keys(s.variables).length ? { variables: { ...s.variables } } : {}),\n ...(s && Object.keys(s.secrets).length ? { secrets: { ...s.secrets } } : {}),\n ...(s?.parallelism !== undefined ? { parallelism: s.parallelism } : {}),\n };\n}\n\n/**\n * The same as `chant build --pr-loop` flags (chant#4625). `--pr-runner` takes\n * labels, so a GitHub runner group reaches the pull request jobs only\n * through `productPipelineJobs`; `notes` says so.\n */\nexport function prLoopJobFlags(s: JobSettings | undefined, runner: ChantRunner | undefined): { flags: string[]; notes: string[] } {\n const flags: string[] = [];\n const notes: string[] = [];\n for (const [stage, spec] of Object.entries(prLoopRunners(runner) ?? {})) {\n if (typeof spec === \"string\") flags.push(\"--pr-runner\", `${stage}=${spec}`);\n else if (Array.isArray(spec)) flags.push(\"--pr-runner\", `${stage}=${spec.join(\",\")}`);\n else notes.push(`runners: the ${stage === \"plan\" ? \"preview\" : stage === \"apply\" ? \"up\" : \"default\"} runner group ${spec.group} is GitHub's, and chant's pull request generator takes labels; its jobs keep the forge's default runner`);\n }\n for (const [name, value] of Object.entries(s?.variables ?? {})) flags.push(\"--pr-variable\", `${name}=${value}`);\n for (const [name, secret] of Object.entries(s?.secrets ?? {})) flags.push(\"--pr-secret\", `${name}=${secret}`);\n if (s?.parallelism !== undefined) flags.push(\"--parallelism\", String(s.parallelism));\n return { flags, notes };\n}\n\n/** Whether plywood.yml asks the pull request jobs for anything only chant#4625 gives them. */\nexport function wantsChant4625(s: JobSettings | undefined, runner: ChantRunner | undefined): boolean {\n return runner !== undefined || (s !== undefined && (Object.keys(s.variables).length > 0 || Object.keys(s.secrets).length > 0 || s.parallelism !== undefined));\n}\n\n/** The pull request jobs' part of the settings, for `plywood init` and `plywood ci`: chant's options and build flags with chant#4625, else a note when plywood.yml asks for them. */\nexport async function prJobsFor(pipeline: { jobs?: JobSettings; runner?: ChantRunner }): Promise<{ options: Record<string, unknown>; flags: string[]; notes: string[] }> {\n if (!wantsChant4625(pipeline.jobs, pipeline.runner)) return { options: {}, flags: [], notes: [] };\n if (!(await hasChant4625())) {\n const asked = [\n ...(pipeline.runner !== undefined ? [\"runners\"] : []),\n ...(pipeline.jobs && Object.keys(pipeline.jobs.variables).length ? [\"env\"] : []),\n ...(pipeline.jobs && Object.keys(pipeline.jobs.secrets).length ? [\"pass\"] : []),\n ...(pipeline.jobs?.parallelism !== undefined ? [\"parallelism\"] : []),\n ];\n return { options: {}, flags: [], notes: [`${asked.join(\", \")} on the pull request jobs ${JOBS_NEED_CHANT}; the waves and drift jobs have ${asked.filter((k) => k !== \"parallelism\").join(\", \") || \"none of them\"}`] };\n }\n const { flags, notes } = prLoopJobFlags(pipeline.jobs, pipeline.runner);\n return { options: prLoopJobOptions(pipeline.jobs, pipeline.runner), flags, notes };\n}\n", "/**\n * What plywood prints after chant refuses an update, approval or override:\n * one line per exit code chant#4553 gives a meaning, naming the command that\n * clears it. chant has already printed its own reason (and, for a waiting\n * gate, the approve line in plywood's words); these lines say what to do next\n * in plywood's verbs. The code itself is chant's, passed through unchanged.\n */\nimport type { ExitName, ExitTable } from \"./exit-codes\";\nimport { POLICY_RULE_FORMS, PR_GATE, PRODUCT } from \"./words\";\n\n/** Where the refusal happened, so the line names the right next command. */\nexport interface RefusalContext {\n /** The wave that refused, when `plywood up` ran one. */\n wave?: number;\n /** The pull request, for an update before merge. */\n pr?: string;\n}\n\n/** The refused outcomes plywood explains; `done`, `failed` and `drift` carry chant's own message. */\nexport const REFUSALS = [\"waiting\", \"moved\", \"held\", \"superseded\", \"denied\", \"declined\", \"misplaced\"] as const satisfies readonly ExitName[];\n\nexport type Refusal = (typeof REFUSALS)[number];\n\n/** The exit name `code` stands for in `table`, when it is one plywood explains. */\nexport function refusalOf(code: number, table: ExitTable): Refusal | undefined {\n return REFUSALS.find((name) => table[name] === code);\n}\n\n/** The line for `refusal`, with the command that clears it. */\nexport function refusalLine(refusal: Refusal, ctx: RefusalContext = {}): string {\n const gate = ctx.wave !== undefined ? `wave-${ctx.wave}` : PR_GATE;\n const again = ctx.pr !== undefined ? `/${PRODUCT} up on pull request ${ctx.pr}` : `${PRODUCT} up${ctx.wave !== undefined ? ` --wave ${ctx.wave}` : \"\"}`;\n switch (refusal) {\n case \"waiting\":\n return `${gate} waits for an approval. Approve the digest chant printed with '${PRODUCT} approve ${gate} --plan <digest>', then run ${again} again.`;\n case \"moved\":\n return `The preview moved after it was approved (on plunge, a record the saved plan read was written by another update), so nothing was updated. Preview again ('${PRODUCT} preview' or /${PRODUCT} preview), read the new change, and approve its digest with '${PRODUCT} approve ${PR_GATE} --plan <digest>'.`;\n case \"held\":\n return `Another update or pull request holds a lock on a resource this update touches, and chant named it above. A running update lets go when it ends; a pull request's lock goes with /${PRODUCT} unlock on that pull request. Then run ${again} again.`;\n case \"superseded\":\n return `A newer push stands in for this one, which stood down. Nothing needs doing: the newer run updates the stacks.`;\n case \"denied\":\n return `A policy denied the change. Fix it and preview again, or override it with '${PRODUCT} override <stack> --rule <id> --reason <text>' naming exactly the rules chant listed (${POLICY_RULE_FORMS}). An override is spent once its update runs.`;\n case \"declined\":\n return `An approver declined the change, so nothing was updated. Push a new change and preview it again.`;\n case \"misplaced\":\n return `The job ran outside the forge environment, branch or runner plywood.yml gives this stack, and chant's job guard named the difference above, so nothing ran. Run it from that branch on that runner, or change environments and runners in plywood.yml and run '${PRODUCT} ci' again.`;\n }\n}\n\n/** Print the line for `code` when it is a refusal; returns `code` unchanged. */\nexport function explainRefusal(code: number, table: ExitTable, err: (s: string) => void, ctx: RefusalContext = {}): number {\n const refusal = refusalOf(code, table);\n if (refusal) err(`${PRODUCT}: ${refusalLine(refusal, ctx)}`);\n return code;\n}\n", "/**\n * `plywood approve`, `plywood override` and `plywood up`, on chant's gates\n * and op waves (chant#4550, #4541, #4545, #4551, #4552, #4553). Each maps\n * onto one chant command line run in process with plywood's words, so every\n * approval, override and update is a row on chant's workspace ledger and\n * plywood writes nothing to git itself.\n *\n * plywood approve <gate> --plan <digest>\n * chant approve <op> <gate> --plan <digest>. The gate `up` is the pull\n * request's, recorded under op pr-<n> (pr-<n>-<stack> for one stack);\n * a wave gate `wave-<k>` is recorded under op pulumi-up, and the gate\n * `review` is a review stack's (plywood#15), chant's pr-env under op\n * pr-<n>. At a terminal\n * chant shows the plan and asks for the target's name before it\n * records anything (chant#4575); --yes skips the question.\n * plywood override <stack> --rule <id>... --reason <text>\n * chant approve policy-override <stack> --rule <id>... --reason <text>,\n * an approval of the denial's override digest, spent once the update\n * it lets through runs.\n * plywood up [--wave <k>] [--decide | --share <i> | --group <name>]\n * chant run wave --spec .chant/op-waves/pulumi-up.spec.json --wave <k>,\n * the command each generated wave job runs. Each run applies through\n * the spec's pulumi-up step (chant#4541). With no --wave, the waves run\n * in order and stop at the first that does not finish.\n * plywood up --pr <n>\n * an update before merge, as /plywood up runs it: chant components\n * pr-apply --before-merge, only under apply.when: pull-request.\n *\n * A refusal keeps chant's exit code and adds the plywood command that\n * clears it (./refusals.ts).\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { applyMergeOf, applyWhenOf } from \"./config/apply\";\nimport { chantNext, hasChantPullRequestApprovalStatus } from \"./chant-next\";\nimport type { RawConfig } from \"./config/types\";\nimport { checkConfig, findConfig, loadConfig } from \"./config/index\";\nimport { FORGES } from \"./config/routing\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { explainRefusal } from \"./refusals\";\nimport { hasChant4607, type ChantProduct, type PendingGateByPlan } from \"./chant-product\";\nimport { REVIEW_GATE, REVIEW_GATE_WORD, reviewOp } from \"./review-stacks\";\nimport { APPLY_MERGE_NEEDS_CHANT, applyMergeArgv, positionals, requiresArgv, requiresNotHonoured, takeFlag, usage, withChant, type StageIo } from \"./stages\";\nimport { OP_NAME, PR_GATE, PRODUCT, PRODUCT_WORDS } from \"./words\";\n\n/** chant's op for policy overrides (`OVERRIDE_GATE_OP`, chant op/gate-name.ts). */\nexport const OVERRIDE_OP = \"policy-override\";\n\n/** The waves spec `plywood up` runs: `.chant/op-waves/pulumi-up.spec.json`, as chant's `productWavesSpecFile` names it. */\nexport const WAVES_SPEC_FILE = `.chant/op-waves/${OP_NAME}.spec.json`;\n\n/** The capability step every run of a plywood wave applies through (chant#4541, #4545). */\nexport const UP_STEP_KIND = \"pulumi-up\";\n\nconst PR_OP = /^pr-(\\d+)(?:-([a-z0-9][a-z0-9-]*))?$/;\n\n/** chant's op and gate for what a person typed after `plywood approve`. */\nexport function approveTarget(\n gate: string,\n opts: { pr?: string; stack?: string; op?: string },\n): { op: string; gate: string } | { error: string } {\n if (opts.op) return { op: opts.op, gate };\n // `plywood approve pr-12` names the pull request's op; its gate is `up`.\n if (PR_OP.test(gate)) return { op: gate, gate: PR_GATE };\n // `plywood approve review --pr 12`: the review stack's update, chant's gate pr-env under op pr-12 (plywood#15).\n if (gate === REVIEW_GATE_WORD || gate === REVIEW_GATE) {\n if (!opts.pr) return { error: `a review stack is a pull request's: name it with --pr <n> (or PR_NUMBER)` };\n if (!/^\\d+$/.test(opts.pr)) return { error: `--pr takes a pull request number, not '${opts.pr}'` };\n return { op: reviewOp(opts.pr), gate: REVIEW_GATE };\n }\n if (gate === PR_GATE) {\n if (!opts.pr) return { error: `the ${PR_GATE} gate is a pull request's: name it with --pr <n> (or PR_NUMBER), or approve pr-<n>` };\n if (!/^\\d+$/.test(opts.pr)) return { error: `--pr takes a pull request number, not '${opts.pr}'` };\n return { op: opts.stack ? `pr-${opts.pr}-${opts.stack}` : `pr-${opts.pr}`, gate };\n }\n // A wave gate, wave-<k>, and any other gate of the merge's waves are recorded under the op.\n return { op: OP_NAME, gate };\n}\n\n/** Flags chant's approve takes, passed through as typed. */\nconst APPROVE_PASS = [\"--plan\", \"--approver\", \"--actor\", \"--note\", \"--url\", \"--env\", \"--roles\", \"--relayed-by\"] as const;\nconst APPROVE_SWITCHES = [\"--sign\", \"--yes\", \"--expire\", \"--allow-same-origin\", \"--resume\"] as const;\n\nfunction passFlags(args: string[], valued: readonly string[], switches: readonly string[]): { argv: string[]; rest: string[]; missing?: string } {\n const argv: string[] = [];\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n const a = args[i]!;\n if (valued.includes(a)) {\n const v = args[i + 1];\n if (v === undefined || v.startsWith(\"--\")) return { argv, rest, missing: a };\n argv.push(a, v);\n i++;\n } else if (switches.includes(a)) argv.push(a);\n else rest.push(a);\n }\n return { argv, rest };\n}\n\n/**\n * `plywood approve <gate> [--plan <digest>] [--pr <n>] [--stack <stack>]\n * [--op <op>] [--approver <name>] [--note <text>] [--sign] [--yes]\n * [--expire] [--json]`.\n */\nexport async function approve(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const pr = takeFlag(args, \"--pr\");\n const stack = takeFlag(pr.rest, \"--stack\");\n const op = takeFlag(stack.rest, \"--op\");\n const forgeFlag = takeFlag(op.rest, \"--forge\");\n const branchFlag = takeFlag(forgeFlag.rest, \"--branch\");\n for (const [flag, f] of [[\"--pr\", pr], [\"--stack\", stack], [\"--op\", op], [\"--forge\", forgeFlag], [\"--branch\", branchFlag]] as const) {\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n }\n if (forgeFlag.value !== undefined && !(FORGES as readonly string[]).includes(forgeFlag.value)) return usage(`--forge ${forgeFlag.value} is not one of ${FORGES.join(\", \")}`, table, io);\n const passed = passFlags(branchFlag.rest, APPROVE_PASS, APPROVE_SWITCHES);\n if (passed.missing) return usage(`${passed.missing} takes a value`, table, io);\n const named = positionals(passed.rest);\n const unknown = passed.rest.filter((a) => a.startsWith(\"-\"));\n if (unknown.length) return usage(`approve does not take ${unknown.join(\" \")}`, table, io);\n if (named.length !== 1) return usage(`approve takes one gate: '${PRODUCT} approve ${PR_GATE} --pr <n> --plan <digest>' or '${PRODUCT} approve wave-<k> --plan <digest>'`, table, io);\n const prNumber = pr.value ?? io.env.PR_NUMBER;\n const gate = named[0]!;\n const plan = passed.argv[passed.argv.indexOf(\"--plan\") + 1];\n // chant#4607: `approve up --plan <digest>` finds its pull request from the digest, when chant reads pending gates by plan.\n const byPlan = gate === PR_GATE && !prNumber && !op.value && passed.argv.includes(\"--plan\");\n const target = byPlan ? undefined : approveTarget(gate, { pr: prNumber, stack: stack.value, op: op.value });\n if (target && \"error\" in target) return usage(target.error, table, io);\n if (!passed.argv.includes(\"--plan\") && !passed.argv.includes(\"--expire\")) {\n return usage(`approve needs --plan <digest>, the digest the preview printed, so a change that moved since is never approved in its place`, table, io);\n }\n return withChant(`${PRODUCT} approve`, table, io, async (chant) => {\n let to = target;\n if (!to) {\n const found = await upTargetByPlan(chant, plan!, { stack: stack.value, cwd: io.cwd });\n if (\"error\" in found) return usage(found.error, table, io);\n if (!json) io.err(`${PRODUCT} approve: ${plan} waits at pull request ${found.pr}'s ${PR_GATE} gate (op ${found.op})`);\n to = { op: found.op, gate: PR_GATE };\n }\n const argv = [\"approve\", to.op, to.gate, ...passed.argv, ...(json ? [\"--json\"] : [])];\n const code = explainRefusal(await chant.runChantInProcess(argv, PRODUCT_WORDS), table, io.err);\n // Only a recorded approval of a pull request's up gate goes further; --expire records none.\n if (code !== table.done || to.gate !== PR_GATE || !PR_OP.test(to.op) || !passed.argv.includes(\"--plan\") || passed.argv.includes(\"--expire\")) return code;\n const spec = wavesSpecAt(io.cwd);\n if (spec && wavesTakePullRequestApproval(spec)) {\n const carried = await chant.runChantInProcess(carryArgv(passed.argv), PRODUCT_WORDS);\n if (carried !== table.done) {\n io.err(`${PRODUCT} approve: ${to.op} is approved, and recording the same approval under ${OP_NAME} failed (exit ${carried}), so the waves after the merge still wait at ${PR_GATE}. Run '${PRODUCT} approve ${PR_GATE} --op ${OP_NAME} --plan ${plan} --yes' to record it there.`);\n return explainRefusal(carried, table, io.err);\n }\n if (!json) io.err(`${PRODUCT} approve: recorded the same approval under ${OP_NAME}, where the waves after the merge read the pull request's ${PR_GATE} gate`);\n }\n if (spec) await refreshApprovalStatus(chant, spec, { forge: forgeFlag.value, branch: branchFlag.value, json }, io);\n return code;\n });\n}\n\n/** The waves spec at `cwd` as JSON, or undefined when it is missing or does not parse. */\nfunction wavesSpecAt(cwd: string, file = WAVES_SPEC_FILE): Record<string, unknown> | undefined {\n const path = join(cwd, file);\n if (!existsSync(path)) return undefined;\n try {\n const spec: unknown = JSON.parse(readFileSync(path, \"utf8\"));\n return spec && typeof spec === \"object\" && !Array.isArray(spec) ? (spec as Record<string, unknown>) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/**\n * Whether the waves after the merge take the pull request's approval: a\n * wave with `approval: \"pull-request\"` and `approvals.pullRequest.gate` set\n * to `up` (chant#4550, ruling B), as productWavesSpec writes plywood's spec.\n * Such a wave reads that approval under the spec's op, pulumi-up, and never\n * under pr-<n>, so `plywood approve up` records it under both.\n */\nexport function wavesTakePullRequestApproval(spec: Record<string, unknown>): boolean {\n const gate = (spec.approvals as { pullRequest?: { gate?: unknown } } | undefined)?.pullRequest?.gate;\n const waves = Array.isArray(spec.waves) ? (spec.waves as Array<{ approval?: unknown } | null>) : [];\n return gate === PR_GATE && waves.some((w) => w?.approval === \"pull-request\");\n}\n\n/**\n * chant's approve line for the same approval under pulumi-up's `up` gate.\n * The person confirmed the digest on the first line, so `--yes` skips the\n * second question; `--resume` belongs to the pull request's own gate.\n */\nexport function carryArgv(passed: readonly string[]): string[] {\n const kept = passed.filter((a) => a !== \"--resume\");\n return [\"approve\", OP_NAME, PR_GATE, ...kept, ...(kept.includes(\"--yes\") ? [] : [\"--yes\"])];\n}\n\n/**\n * The forge and target branch the approval status is posted for: `--forge`\n * and `--branch` first, then plywood.yml's forge.kind, then the CI job's\n * variables. Undefined parts are not known.\n */\nexport function approvalStatusTarget(opts: { forge?: string; branch?: string }, doc: RawConfig | undefined, env: NodeJS.ProcessEnv): { forge?: string; branch?: string } {\n const configured = (doc?.forge as { kind?: string } | undefined)?.kind;\n const ci = env.GITLAB_CI === \"true\" ? \"gitlab\" : env.FORGEJO_ACTIONS === \"true\" || env.GITEA_ACTIONS === \"true\" ? \"forgejo\" : env.GITHUB_ACTIONS === \"true\" ? \"github\" : undefined;\n const forge = opts.forge ?? configured ?? ci;\n const branch = opts.branch ?? (env.GITHUB_BASE_REF || env.CI_MERGE_REQUEST_TARGET_BRANCH_NAME || env.CI_DEFAULT_BRANCH || (env.GITHUB_ACTIONS === \"true\" ? env.GITHUB_REF_NAME : undefined) || undefined);\n return { ...(forge ? { forge } : {}), ...(branch ? { branch } : {}) };\n}\n\n/**\n * After an approval of a pull request's `up` gate, post plywood/approval\n * again on the open pull requests (`run wave --approval-status --open`,\n * chant#4630), since a ledger approval starts no run on any forge. Only on\n * a chant that posts the status for pull-request waves. A refresh that\n * cannot run or fails is a line on stderr and leaves the approval's exit\n * code alone.\n */\nasync function refreshApprovalStatus(chant: ChantProduct, spec: Record<string, unknown>, opts: { forge?: string; branch?: string; json: boolean }, io: StageIo): Promise<void> {\n if (!hasChantPullRequestApprovalStatus(chant)) return;\n const posts = chant.opWavesPostsApprovalStatus ? chant.opWavesPostsApprovalStatus(spec) : wavesTakePullRequestApproval(spec);\n if (!posts) return;\n const path = findConfig(io.cwd);\n const doc = path ? loadConfig(path).doc : undefined;\n const at = approvalStatusTarget(opts, doc, io.env);\n const line = (branch: string, forge: string) => `${PRODUCT} run wave --spec ${WAVES_SPEC_FILE} --approval-status --open --branch ${branch} --forge ${forge}`;\n if (!at.forge || !at.branch) {\n io.err(`${PRODUCT} approve: ${PRODUCT}/approval moves at the next push or review; to post it now, run '${line(at.branch ?? \"<target branch>\", at.forge ?? \"<forge>\")}' with a forge token`);\n return;\n }\n const code = await chant.runChantInProcess([\"run\", \"wave\", \"--spec\", WAVES_SPEC_FILE, \"--approval-status\", \"--open\", \"--branch\", at.branch, \"--forge\", at.forge], PRODUCT_WORDS);\n if (code !== 0) io.err(`${PRODUCT} approve: the approval is recorded, and ${PRODUCT}/approval was not posted again (exit ${code}); it moves at the next push or review, or run '${line(at.branch, at.forge)}'`);\n else if (!opts.json) io.err(`${PRODUCT} approve: posted ${PRODUCT}/approval again on the open pull requests into ${at.branch}`);\n}\n\n/**\n * The pull request op whose `up` gate waits on `digest` (chant#4607's\n * `pendingGatesByPlan`). With `stack`, the op of that stack's gate\n * (`pr-<n>-<stack>`). Without chant#4607, `--pr` or PR_NUMBER stays required.\n */\nexport async function upTargetByPlan(chant: ChantProduct, digest: string, opts: { stack?: string; cwd?: string } = {}): Promise<{ op: string; pr: number } | { error: string }> {\n const needsPr = `the ${PR_GATE} gate is a pull request's: name it with --pr <n> (or PR_NUMBER), or approve pr-<n>`;\n if (!hasChant4607(chant)) return { error: `${needsPr}. The installed chant cannot find a pull request from a plan digest (chant#4607)` };\n let gates: PendingGateByPlan[];\n try {\n gates = await chant.pendingGatesByPlan!(digest, { pullRequestsOnly: true, ...(opts.cwd ? { cwd: opts.cwd } : {}) });\n } catch (e) {\n return { error: `${needsPr}. Reading the pending gates for ${digest} failed: ${(e as Error).message}` };\n }\n let up = gates.filter((g) => g.gate === PR_GATE && g.pr !== undefined);\n if (opts.stack) up = up.filter((g) => g.member === opts.stack);\n const ops = [...new Set(up.map((g) => g.op))];\n if (ops.length === 0) return { error: `no pull request's ${PR_GATE} gate waits on ${digest}${opts.stack ? ` for ${opts.stack}` : \"\"}. Check the digest the preview printed and fetch chant/lifecycle, or name the pull request with --pr <n>` };\n const prs = [...new Set(up.map((g) => g.pr!))];\n if (prs.length > 1) return { error: `${digest} waits at the ${PR_GATE} gate of pull requests ${prs.sort((a, b) => a - b).join(\", \")}; name one with --pr <n>` };\n // One pull request: its own op, unless only stack ops wait and there is more than one.\n const whole = up.find((g) => g.member === undefined);\n if (whole) return { op: whole.op, pr: whole.pr! };\n if (ops.length > 1) return { error: `${digest} waits at the ${PR_GATE} gate of ${ops.join(\", \")}; name the stack with --stack <stack>` };\n return { op: ops[0]!, pr: prs[0]! };\n}\n\n/**\n * `plywood override <stack> --rule <id>... --reason <text> [--plan <digest>]\n * [--approver <name>] [--sign] [--json]`: chant's override of a policy\n * denial, recorded as an approval on policy-override.\n */\nexport async function override(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const rules: string[] = [];\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--rule\") {\n const v = args[i + 1];\n if (v === undefined || v.startsWith(\"--\")) return usage(\"--rule takes a rule id\", table, io);\n rules.push(v);\n i++;\n } else rest.push(args[i]!);\n }\n const reason = takeFlag(rest, \"--reason\");\n if (reason.missing) return usage(\"--reason takes a text\", table, io);\n const passed = passFlags(reason.rest, [\"--plan\", \"--approver\", \"--actor\", \"--url\", \"--relayed-by\"], [\"--sign\", \"--allow-same-origin\"]);\n if (passed.missing) return usage(`${passed.missing} takes a value`, table, io);\n const unknown = passed.rest.filter((a) => a.startsWith(\"-\"));\n if (unknown.length) return usage(`override does not take ${unknown.join(\" \")}`, table, io);\n const named = positionals(passed.rest);\n const line = `${PRODUCT} override <stack> --rule <id> --reason <text>`;\n if (named.length !== 1) return usage(`override takes the stack the policy denied: ${line}`, table, io);\n if (rules.length === 0) return usage(`an override names each rule it overrides: ${line}`, table, io);\n if (!reason.value?.trim()) return usage(`an override needs --reason <text>: why this change goes out although the policy denies it`, table, io);\n const argv = [\"approve\", OVERRIDE_OP, named[0]!, ...rules.flatMap((r) => [\"--rule\", r]), \"--reason\", reason.value, ...passed.argv, ...(json ? [\"--json\"] : [])];\n return withChant(`${PRODUCT} override`, table, io, async (chant) => explainRefusal(await chant.runChantInProcess(argv, PRODUCT_WORDS), table, io.err));\n}\n\n/** The parts of the waves spec `plywood up` reads before handing it to chant. */\nexport interface UpSpec {\n waves: Array<{ name: string }>;\n step?: { kind?: string };\n}\n\n/** Read and check the waves spec: it must apply each run through the pulumi-up step. */\nexport function readUpSpec(cwd: string, file = WAVES_SPEC_FILE): UpSpec | { error: string } {\n const path = join(cwd, file);\n if (!existsSync(path)) return { error: `no ${file}; '${PRODUCT} init' writes it from plywood.yml's waves` };\n let spec: unknown;\n try {\n spec = JSON.parse(readFileSync(path, \"utf8\"));\n } catch (e) {\n return { error: `${file}: ${(e as Error).message}` };\n }\n const s = spec as Partial<UpSpec> | null;\n if (!s || !Array.isArray(s.waves) || s.waves.length === 0) return { error: `${file} has no waves` };\n if (s.step?.kind !== UP_STEP_KIND) {\n return { error: `${file} applies through ${s.step?.kind ? `the ${s.step.kind} step` : \"no capability step\"}; ${PRODUCT} up runs each stack through the ${UP_STEP_KIND} step (\"step\": { \"kind\": \"${UP_STEP_KIND}\" }). Run '${PRODUCT} init' to write it again.` };\n }\n return s as UpSpec;\n}\n\n/**\n * `plywood up [--wave <k>] [--decide | --share <i> | --group <name>]\n * [--base <rev>] [--spec <file>] [--no-record] [--events-json] [--json]`,\n * or `plywood up --pr <n> [--base <rev>] [--forge <kind>] [--env <env>]`\n * for an update before merge.\n */\nexport async function up(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const pr = takeFlag(args, \"--pr\");\n if (pr.missing) return usage(\"--pr takes a pull request number\", table, io);\n if (pr.value !== undefined) return upBeforeMerge(pr.value, pr.rest, json, table, io);\n\n const specFlag = takeFlag(pr.rest, \"--spec\");\n const wave = takeFlag(specFlag.rest, \"--wave\");\n const share = takeFlag(wave.rest, \"--share\");\n const group = takeFlag(share.rest, \"--group\");\n const base = takeFlag(group.rest, \"--base\");\n for (const [flag, f] of [[\"--spec\", specFlag], [\"--wave\", wave], [\"--share\", share], [\"--group\", group], [\"--base\", base]] as const) {\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n }\n const switches = base.rest.filter((a) => [\"--decide\", \"--no-record\", \"--events-json\"].includes(a));\n const extra = base.rest.filter((a) => !switches.includes(a));\n if (extra.length) return usage(`up does not take ${extra.join(\" \")}`, table, io);\n if (wave.value !== undefined && !/^[1-9]\\d*$/.test(wave.value)) return usage(`--wave takes a wave number, 1 or more, not '${wave.value}'`, table, io);\n if ((share.value !== undefined || group.value !== undefined || switches.includes(\"--decide\")) && wave.value === undefined) {\n return usage(\"--decide, --share and --group are one wave's jobs; name the wave with --wave <k>\", table, io);\n }\n\n const file = specFlag.value ?? WAVES_SPEC_FILE;\n const spec = readUpSpec(io.cwd, file);\n if (\"error\" in spec) return usage(spec.error, table, io);\n const waves = wave.value !== undefined ? [Number(wave.value)] : spec.waves.map((_, i) => i + 1);\n if (waves.some((k) => k > spec.waves.length)) return usage(`${file} has ${spec.waves.length} wave${spec.waves.length === 1 ? \"\" : \"s\"}, so there is no wave ${wave.value}`, table, io);\n\n return withChant(`${PRODUCT} up`, table, io, async (chant) => {\n for (const k of waves) {\n const argv = [\n \"run\", \"wave\", \"--spec\", file, \"--wave\", String(k),\n ...(base.value ? [\"--base\", base.value] : []),\n ...(share.value ? [\"--share\", share.value] : []),\n ...(group.value ? [\"--group\", group.value] : []),\n ...switches,\n ...(json ? [\"--json\"] : []),\n ];\n if (!json && waves.length > 1) io.err(`${PRODUCT} up: wave ${k} (${spec.waves[k - 1]!.name})`);\n const code = await chant.runChantInProcess(argv, PRODUCT_WORDS);\n // A wave that waits, holds or fails stops the ones after it, as the generated jobs' needs: do.\n if (code !== table.done) return explainRefusal(code, table, io.err, { wave: k });\n }\n return table.done;\n });\n}\n\n/** `plywood up --pr <n>`: the update before merge `/plywood up` runs, only under apply.when: pull-request. */\nasync function upBeforeMerge(number: string, args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n if (!/^\\d+$/.test(number)) return usage(`--pr takes a pull request number, not '${number}'`, table, io);\n const base = takeFlag(args, \"--base\");\n const forgeFlag = takeFlag(base.rest, \"--forge\");\n const envFlag = takeFlag(forgeFlag.rest, \"--env\");\n if (base.missing || forgeFlag.missing || envFlag.missing) return usage(\"--base, --forge and --env each take a value\", table, io);\n const extra = envFlag.rest;\n if (extra.length) return usage(`up --pr does not take ${extra.join(\" \")}`, table, io);\n\n const path = findConfig(io.cwd);\n if (!path) return usage(`no plywood.yml in ${io.cwd} or above it; run '${PRODUCT} init' first`, table, io);\n const config = loadConfig(path);\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n return table.failed;\n }\n if (applyWhenOf(config.doc) !== \"pull-request\") {\n return usage(`/${PRODUCT} up updates an open pull request only under apply.when: pull-request, and ${path} updates after the merge. Set apply.when: pull-request, or merge and let the waves run.`, table, io);\n }\n const at = base.value ?? io.env.BASE_SHA;\n if (!at) return usage(\"up --pr needs --base <rev>, the target branch's commit (or BASE_SHA)\", table, io);\n const configured = (config.doc.forge as { kind?: string } | undefined)?.kind;\n const forge = forgeFlag.value ?? configured ?? \"github\";\n if (!(FORGES as readonly string[]).includes(forge)) return usage(`--forge ${forge} is not one of ${FORGES.join(\", \")}`, table, io);\n return withChant(`/${PRODUCT} up`, table, io, async (chant) => {\n // chant#4607: apply.requires as --requires; a chant before it asks all four, and plywood says so.\n const note = requiresNotHonoured(chant, config.doc);\n if (note) io.err(`${PRODUCT}: ${note}`);\n const argv = [\n \"components\", \"pr-apply\", \"--before-merge\", \"--base\", at, \"--pr\", number,\n \"--env\", envFlag.value ?? \"production\", \"--gate\", PR_GATE, \"--forge\", forge,\n ...requiresArgv(chant, config.doc),\n ...(await mergeArgv(config.doc, io)),\n ...(json ? [\"--json\"] : []),\n ];\n return explainRefusal(await chant.runChantInProcess(argv, PRODUCT_WORDS), table, io.err, { pr: number });\n });\n}\n\n/** `--merge auto` for `apply.merge: auto` on a chant with chant#4636; on one without it, a line that a person merges. */\nasync function mergeArgv(doc: RawConfig, io: StageIo): Promise<string[]> {\n const merge = applyMergeOf(doc);\n if (!merge) return [];\n if (!(await chantNext()).applyMerge) {\n io.err(`${PRODUCT}: ${APPLY_MERGE_NEEDS_CHANT}`);\n return [];\n }\n return applyMergeArgv(merge);\n}\n\n/**\n * `plywood resume [--op <op>] [--wave <k>] [--dry-run] [--json]`: chant's\n * `run resume --op pulumi-up`, in process with plywood's words. It starts\n * the wave jobs whose gate an approval has since cleared, from the gate\n * ledgers (chant#3683). `--wave <k>` names the gate `wave-<k>`; `--op` reads\n * another op's gates, such as `plywood-adopt`. A refusal gets the line\n * `plywood up` adds.\n */\nexport async function resume(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const op = takeFlag(args, \"--op\");\n const wave = takeFlag(op.rest, \"--wave\");\n if (op.missing || wave.missing) return usage(`${op.missing ? \"--op takes an op, such as pulumi-up\" : \"--wave takes a wave number\"}`, table, io);\n const switches: string[] = wave.rest.filter((a) => a === \"--dry-run\");\n const extra = wave.rest.filter((a) => !switches.includes(a));\n if (extra.length) return usage(`resume does not take ${extra.join(\" \")}`, table, io);\n if (wave.value !== undefined && !/^[1-9]\\d*$/.test(wave.value)) return usage(`--wave takes a wave number, 1 or more, not '${wave.value}'`, table, io);\n const k = wave.value !== undefined ? Number(wave.value) : undefined;\n const argv = [\n \"run\", \"resume\", \"--op\", op.value ?? OP_NAME,\n ...(k !== undefined ? [\"--gate\", PRODUCT_WORDS.gateName.replace(\"{k}\", String(k))] : []),\n ...switches,\n ...(json ? [\"--json\"] : []),\n ];\n return withChant(`${PRODUCT} resume`, table, io, async (chant) => explainRefusal(await chant.runChantInProcess(argv, PRODUCT_WORDS), table, io.err, k !== undefined ? { wave: k } : {}));\n}\n", "/**\n * `plywood drift` and the scheduled drift jobs (plywood#8). The read is\n * chant's, run in process with plywood's words; plywood holds the words of\n * the issue and the defaults.\n *\n * plywood drift [<stack>...] [--op <name>] [--resource <urn>] [--env <env>]\n * [--forge github|gitlab|forgejo] [--respond issue|pull-request|up|none] [--json]\n * For each stack, chant's `workspace drift --member <stack>`: the\n * pulumi lexicon's drift read, `pulumi refresh --preview-only --json\n * --target <urn>` per resource on stock Pulumi and `plunge drift\n * --resource <urn> --stream` on plunge, over the export the last\n * update stored under refs/chant/snapshots (chant#4546) or a\n * checked-in stack-export.json. A drifted or missing resource is\n * drift, as PulumiWatchOp counts it. With --forge, each stack keeps\n * one issue through chant's forge client (`trackIssue`): opened on the\n * first finding, edited when the finding changes, closed by a clean\n * run. respond.drift up then runs the waves holding the drifted\n * stacks through `plywood up`, each through its gate. The run exits\n * with chant's `drift` code when any stack drifted, as pulumi/actions'\n * expect-no-changes does, and `failed` when a read could not run.\n *\n * With drift.audit_log and chant's audit-log reads (chant#4632), each\n * drifted attribute is attributed to its writer (a known write, the\n * CloudTrail entry, or unattributed), in the output and the issue.\n *\n * plywood ci, with drift.schedule set\n * writes ops/plywood-drift.op.ts, one chant PulumiWatchOp per stack on\n * the schedule, and .chant/ops/plywood-drift.spec.json, then has\n * chant's Op pipeline generator (`run --generate <forge> --spec`)\n * write the scheduled jobs. Each job runs `plywood drift --op <name>\n * --forge <forge>` (the spec's `runCommand`), after fetching\n * refs/chant/snapshots, and gets the issue permission chant's\n * `findingMode` grants. `chant run plywood-drift-<stack>` runs the\n * same stack's PulumiWatchOp by hand. With chant#4631 each Op trades\n * for its stack's preview identity before the checkout, and under\n * respond.drift up the update runs in a job of its own after the\n * read, holding the stack's up identity (the spec's `update`), so the\n * read never holds the up identity and `plywood drift --op` leaves\n * the update to that job.\n *\n * Nothing here runs pulumi, plunge or git: chant does.\n */\nimport { createHash } from \"node:crypto\";\nimport { resolveTargetCloudIdentity } from \"@intentius/chant/ci-identity\";\nimport { chantAudit, chantNext, type ChantAudit } from \"./chant-next\";\nimport { globMatches } from \"./config/images\";\nimport { existsSync, mkdirSync, mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport { toChantSettings } from \"./chant-config\";\nimport { driftOpFields, hasChantAgent } from \"./agent-jobs\";\nimport type { JobSettings } from \"./config/jobs\";\nimport { chantNotifyOf, type ChantNotifyConfig } from \"./config/observe\";\nimport { chantDriftNotify, notifiesDrift, sendDriftNotice, type DriftNotice } from \"./drift-notify\";\nimport { environmentFor, jobVariables, secretReference } from \"./jobs\";\nimport type { ChantProduct, ForgeKind } from \"./chant-product\";\nimport { driftResponseOf, driftSettingsOf, driftStacksOf, DRIFT_RESPONSES, type DriftResponse } from \"./config/drift\";\nimport { checkConfig, findConfig, loadConfig, type RawConfig } from \"./config/index\";\nimport { stacksOf } from \"./config/stacks\";\nimport { FORGES } from \"./config/routing\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { chantPipelineOptions } from \"./images\";\nimport { positionals, takeFlag, usage, withChant, type StageIo } from \"./stages\";\nimport { up } from \"./up\";\nimport {\n BIN,\n driftClearedComment,\n driftIssueBody,\n driftIssueMarker,\n driftIssueTitle,\n driftOpName,\n PRODUCT,\n PRODUCT_WORDS,\n type DriftRow,\n type ProductWordsInput,\n} from \"./words\";\n\n/** The Op file `plywood ci` writes; chant discovers `*.op.ts` beside chant.config.ts. */\nexport const DRIFT_OP_FILE = \"ops/plywood-drift.op.ts\";\n/** The scheduled Op spec chant's generator reads. */\nexport const DRIFT_SPEC_FILE = \".chant/ops/plywood-drift.spec.json\";\n/** The ref chant's pulumi apply stores each stack's export under (chant#4546, #4519). */\nexport const SNAPSHOTS_REF = \"refs/chant/snapshots\";\n/** The line a drift job runs before the read, so chant finds the stored export; a repository with none yet reads the checked-in file. */\nexport const SNAPSHOTS_FETCH = `git fetch --no-tags origin '+${SNAPSHOTS_REF}:${SNAPSHOTS_REF}' || true`;\n\n/** The statuses that count as drift, as PulumiWatchOp's `drifted` counts them. */\nexport const DRIFT_STATUSES = [\"drifted\", \"missing\"] as const;\n\n/** The parts of chant's drift document plywood reads (`@intentius/chant/drift-record`). */\nexport interface DriftDoc {\n records?: Array<{ address: string; status: string; observedAt?: string; attributes?: Array<{ path: string }> }>;\n counts?: Record<string, number>;\n error?: { code: string; message: string };\n}\n\n/** The drifted and missing resources in a drift document, sorted by URN. */\nexport function driftRows(doc: DriftDoc): DriftRow[] {\n return (doc.records ?? [])\n .filter((r) => (DRIFT_STATUSES as readonly string[]).includes(r.status))\n .map((r) => ({ urn: r.address, status: r.status, attributes: (r.attributes ?? []).map((a) => a.path).sort() }))\n .sort((a, b) => (a.urn < b.urn ? -1 : a.urn > b.urn ? 1 : 0));\n}\n\n/** A finding's fingerprint: the same rows give the same one, whenever they are read. */\nexport function driftFingerprint(rows: readonly DriftRow[]): string {\n const text = rows.map((r) => `${r.urn}\\t${r.status}\\t${r.attributes.join(\",\")}`).join(\"\\n\");\n return createHash(\"sha256\").update(text).digest(\"hex\").slice(0, 16);\n}\n\n/** The latest observation time in the document, else now. */\nfunction observedAt(doc: DriftDoc): string {\n const times = (doc.records ?? []).map((r) => r.observedAt).filter((t): t is string => typeof t === \"string\").sort();\n return times[times.length - 1] ?? new Date().toISOString();\n}\n\n/** The part of chant's forge client (`PrForge`, `@intentius/chant/pr-forge`) `plywood drift` calls. */\nexport interface DriftForge {\n runUrl?: string;\n trackIssue(\n marker: string,\n finding: { title: string; body: string } | null,\n opts?: { closeOnClear?: boolean; clearComment?: string; sameWhen?: string },\n ): Promise<{ action: string; number?: number; url?: string }>;\n}\n\nlet forgeOverride: ((kind: ForgeKind, env: NodeJS.ProcessEnv) => Promise<DriftForge>) | undefined;\n\n/** Tests stand in a fake forge client; `reset` goes back to chant's. */\nexport function setDriftForgeForTests(fake: ((kind: ForgeKind, env: NodeJS.ProcessEnv) => Promise<DriftForge>) | \"reset\"): void {\n forgeOverride = fake === \"reset\" ? undefined : fake;\n}\n\n/** chant's forge client for the job's forge, from the job's own variables. */\nasync function forgeFor(kind: ForgeKind, env: NodeJS.ProcessEnv): Promise<DriftForge> {\n if (forgeOverride) return forgeOverride(kind, env);\n const m = (await import(\"@intentius/chant/pr-forge\")) as unknown as {\n forgeTargetFromEnv(env: Record<string, string | undefined>, opts: { kind: ForgeKind }): unknown;\n forgeClient(target: unknown): DriftForge;\n };\n return m.forgeClient(m.forgeTargetFromEnv(env, { kind }));\n}\n\nexport interface StackDrift {\n stack: string;\n ok: boolean;\n drifted: number;\n rows: DriftRow[];\n /** When chant read the stack, from the records. */\n observedAt?: string;\n error?: string;\n issue?: { action: string; number?: number; url?: string };\n /** Who changed each drifted attribute (chant#4632), one line each, with drift.audit_log. */\n attribution?: string[];\n}\n\n/** The waves (1-based) that hold any of `stacks`; every wave when plywood.yml lists none. */\nexport function wavesHolding(doc: RawConfig, stacks: readonly string[]): number[] | \"all\" {\n if (!Array.isArray(doc.waves)) return \"all\";\n return (doc.waves as string[][]).flatMap((w, i) => (w.some((s) => stacks.includes(s)) ? [i + 1] : []));\n}\n\n/** `plywood drift`; see the module comment. */\nexport async function drift(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const opFlag = takeFlag(args, \"--op\");\n const resource = takeFlag(opFlag.rest, \"--resource\");\n const envFlag = takeFlag(resource.rest, \"--env\");\n const forgeFlag = takeFlag(envFlag.rest, \"--forge\");\n const respondFlag = takeFlag(forgeFlag.rest, \"--respond\");\n const stackFlag = takeFlag(respondFlag.rest, \"--stack\");\n for (const [flag, f] of [[\"--op\", opFlag], [\"--resource\", resource], [\"--env\", envFlag], [\"--forge\", forgeFlag], [\"--respond\", respondFlag], [\"--stack\", stackFlag]] as const) {\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n }\n const unknown = stackFlag.rest.filter((a) => a.startsWith(\"-\"));\n if (unknown.length) return usage(`drift does not take ${unknown.join(\" \")}`, table, io);\n if (forgeFlag.value !== undefined && !(FORGES as readonly string[]).includes(forgeFlag.value)) return usage(`--forge ${forgeFlag.value} is not one of ${FORGES.join(\", \")}`, table, io);\n if (respondFlag.value !== undefined && !(DRIFT_RESPONSES as readonly string[]).includes(respondFlag.value)) return usage(`--respond takes one of ${DRIFT_RESPONSES.join(\", \")}`, table, io);\n\n const path = findConfig(io.cwd);\n if (!path) return usage(`no plywood.yml in ${io.cwd} or above it; run '${PRODUCT} init' first`, table, io);\n const config = loadConfig(path);\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n return table.failed;\n }\n const doc = config.doc;\n const listed = Object.keys(stacksOf(doc));\n const named = [...positionals(stackFlag.rest), ...(stackFlag.value ? [stackFlag.value] : [])];\n let stacks: string[];\n if (opFlag.value !== undefined) {\n const hit = listed.find((s) => driftOpName(s) === opFlag.value);\n if (!hit) return usage(`--op ${opFlag.value} names no stack in ${path}; run '${PRODUCT} ci' to write the drift jobs again`, table, io);\n stacks = [hit];\n } else stacks = named.length ? named : driftStacksOf(doc);\n if (stacks.length === 0) return usage(`${path} lists no stacks to read; name one, or list them under stacks`, table, io);\n const strangers = listed.length ? stacks.filter((s) => !listed.includes(s)) : [];\n if (strangers.length) return usage(`${strangers.join(\", \")} ${strangers.length === 1 ? \"is\" : \"are\"} not under stacks in ${path}`, table, io);\n if (resource.value !== undefined && stacks.length !== 1) return usage(\"--resource reads one resource of one stack; name the stack\", table, io);\n const respond: DriftResponse = (respondFlag.value as DriftResponse | undefined) ?? driftResponseOf(doc);\n const forge = forgeFlag.value as ForgeKind | undefined;\n\n return withChant(`${PRODUCT} drift`, table, io, async (chant) => {\n const dir = mkdtempSync(join(tmpdir(), \"plywood-drift-\"));\n const results: StackDrift[] = [];\n try {\n const attribute = await attributionFor(doc, io);\n for (const stack of stacks) results.push(await readStack(chant, stack, dir, { resource: resource.value, env: envFlag.value, ...(attribute ? { attribute } : {}) }));\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n\n let upkeepFailed = false;\n if (forge && respond !== \"none\") {\n let client: DriftForge | undefined;\n try {\n client = await forgeFor(forge, io.env);\n } catch (e) {\n io.err(`${PRODUCT} drift: no ${forge} client for the drift issues: ${(e as Error).message}`);\n upkeepFailed = true;\n }\n for (const r of client ? results.filter((x) => x.ok) : []) {\n try {\n r.issue = await keepIssue(client!, r, respond);\n } catch (e) {\n io.err(`${PRODUCT} drift: ${r.stack}'s issue: ${(e as Error).message}`);\n upkeepFailed = true;\n }\n }\n }\n if (respond === \"pull-request\" && results.some((r) => r.drifted > 0)) {\n // chant#4616: the drift agent is a job of its own after this one, which runs on the drift exit code.\n io.err(\n hasChantAgent(chant)\n ? `${PRODUCT} drift: respond.drift is pull-request; in CI the agent job after this one opens or updates the pull request (agent.drift)`\n : `${PRODUCT} drift: respond.drift is pull-request; this chant has no agent job (chant#4616), so this run kept the issue only`,\n );\n }\n\n // plywood#30: one signed drift event per run through chant's notify, unless the finding is the last run's.\n const notice = await driftNotice(chant, doc, results, envFlag.value, io);\n\n const drifted = results.filter((r) => r.drifted > 0).map((r) => r.stack);\n let upCode: number | undefined;\n const updateJob = respond === \"up\" && drifted.length && opFlag.value !== undefined && specHasUpdate(io.cwd, opFlag.value);\n if (updateJob) io.err(`${PRODUCT} drift: respond.drift is up; the update job after this one updates ${drifted.join(\", \")} with the up identity, through each wave's gate`);\n else if (respond === \"up\" && drifted.length) {\n const waves = wavesHolding(doc, drifted);\n io.err(`${PRODUCT} drift: respond.drift is up; updating ${waves === \"all\" ? \"every wave\" : `wave ${waves.join(\", \")}`} for ${drifted.join(\", \")}, each through its gate`);\n if (waves === \"all\") upCode = await up([], false, table, io);\n else\n for (const k of waves) {\n upCode = await up([\"--wave\", String(k)], false, table, io);\n if (upCode !== table.done) break;\n }\n }\n\n const failed = results.some((r) => !r.ok) || upkeepFailed;\n const code = failed ? table.failed : upCode !== undefined && upCode !== table.done ? upCode : drifted.length ? table.drift : table.done;\n if (json) {\n io.out(JSON.stringify({ command: \"drift\", ok: code === table.done, exitCode: code, respond, stacks: results, ...(notice ? { notify: notice } : {}) }));\n } else {\n if (notice) io.err(`${PRODUCT} drift: ${notice.sent ? `sent the drift event, fingerprint ${notice.fingerprint}` : notice.reason}`);\n for (const r of results) {\n if (!r.ok) io.out(`${r.stack}: the drift read failed: ${r.error}`);\n else if (r.drifted === 0) io.out(`${r.stack}: matches its state${r.issue && r.issue.action === \"closed\" ? `; closed issue #${r.issue.number}` : \"\"}`);\n else {\n io.out(`${r.stack}: ${r.drifted} resource${r.drifted === 1 ? \"\" : \"s\"} drifted${r.issue ? ` (issue #${r.issue.number ?? \"?\"} ${r.issue.action})` : \"\"}`);\n for (const row of r.rows) io.out(` ${row.status.padEnd(8)} ${row.urn}${row.attributes.length ? ` ${row.attributes.join(\", \")}` : \"\"}`);\n for (const line of r.attribution ?? []) io.out(` ${line}`);\n }\n }\n }\n return code;\n });\n}\n\n/** The run's drift event (src/drift-notify.ts): sent through chant's notify with plywood's words, or why not. */\nasync function driftNotice(chant: ChantProduct, doc: RawConfig, results: StackDrift[], environment: string | undefined, io: StageIo): Promise<DriftNotice | undefined> {\n const notify = chantNotifyOf(doc);\n const loaded = notifiesDrift(notify) ? await chantDriftNotify() : undefined;\n return sendDriftNotice({\n notify,\n results,\n stackFingerprint: driftFingerprint,\n chant: loaded ? { ...loaded, words: chant.assertProductWords(PRODUCT_WORDS) } : undefined,\n env: io.env,\n ...(environment ? { environment } : {}),\n log: io.err,\n ...(notifyFetch ? { fetch: notifyFetch } : {}),\n });\n}\n\nlet notifyFetch: unknown;\n\n/** Tests send the drift event to a loopback webhook through this fetch; `reset` goes back to the global one. */\nexport function setDriftNotifyFetchForTests(fetch: unknown): void {\n notifyFetch = fetch === \"reset\" ? undefined : fetch;\n}\n\n/** One stack's read: chant's `workspace drift`, written to a file plywood reads back. */\nasync function readStack(chant: ChantProduct, stack: string, dir: string, opts: { resource?: string; env?: string; attribute?: Attribute }): Promise<StackDrift> {\n const file = join(dir, `${driftOpName(stack)}.json`);\n const argv = [\"workspace\", \"drift\", \"--member\", stack, ...(opts.resource ? [\"--resource\", opts.resource] : []), ...(opts.env ? [\"--env\", opts.env] : []), \"-o\", file];\n const code = await chant.runChantInProcess(argv, PRODUCT_WORDS);\n let doc: DriftDoc | undefined;\n try {\n if (existsSync(file)) doc = JSON.parse(readFileSync(file, \"utf8\")) as DriftDoc;\n } catch (e) {\n return { stack, ok: false, drifted: 0, rows: [], error: `chant wrote a drift document plywood cannot read: ${(e as Error).message}` };\n }\n if (code !== 0 || !doc || doc.error) {\n return { stack, ok: false, drifted: 0, rows: [], error: doc?.error ? `${doc.error.code}: ${doc.error.message}` : `chant workspace drift exited ${code}` };\n }\n const rows = driftRows(doc);\n const attribution = rows.length && opts.attribute ? await attributeStack(opts.attribute, stack, doc) : undefined;\n return { stack, ok: true, drifted: rows.length, rows, observedAt: observedAt(doc), ...(attribution ? { attribution } : {}) };\n}\n\n/** chant's audit-log reads and drift.audit_log, for the attribution. */\nexport interface Attribute {\n audit: ChantAudit;\n logs: Record<string, string>;\n}\n\n/** The attribution's reads, when plywood.yml sets drift.audit_log; on a chant without chant#4632 a line says none ran. */\nasync function attributionFor(doc: RawConfig, io: StageIo): Promise<Attribute | undefined> {\n const logs = driftSettingsOf(doc).auditLogs;\n if (!logs) return undefined;\n const audit = await chantAudit();\n if (!audit) {\n io.err(`${PRODUCT} drift: ${ATTRIBUTION_NEEDS_CHANT}`);\n return undefined;\n }\n return { audit, logs };\n}\n\n/** What `plywood drift` says under drift.audit_log on a chant without chant#4632. */\nexport const ATTRIBUTION_NEEDS_CHANT = \"drift.audit_log is set, and the installed chant has no audit-log reads (chant#4632), so no drifted attribute was attributed\";\n\n/** The audit log drift.audit_log gives `stack`: the first glob that matches it. */\nexport function auditLogFor(logs: Record<string, string>, stack: string): string | undefined {\n return Object.entries(logs).find(([glob]) => glob === \"*\" || glob === \"**\" || globMatches(glob, stack))?.[1];\n}\n\n/** One line per drifted attribute of `stack`: who changed it, as chant routes it, then chant's notes. */\nexport async function attributeStack(a: Attribute, stack: string, doc: DriftDoc): Promise<string[] | undefined> {\n const text = auditLogFor(a.logs, stack);\n if (!text) return undefined;\n const setting = a.audit.parseAuditLogSetting(text);\n if (\"error\" in setting) return [`no attribution: ${setting.error}`];\n try {\n const attributed = await a.audit.attributeDrift({ records: doc.records ?? [] }, { auditLogs: { \"*\": setting } });\n return [...a.audit.routeAttributions(attributed.attributions).lines, ...attributed.notes];\n } catch (e) {\n return [`no attribution: ${(e as Error).message}`];\n }\n}\n\n/** Whether the drift spec gives Op `op` an update job (chant#4631), so the read leaves the update to it. */\nexport function specHasUpdate(cwd: string, op: string): boolean {\n try {\n const spec = JSON.parse(readFileSync(join(cwd, DRIFT_SPEC_FILE), \"utf8\")) as { ops?: Array<{ name?: string; update?: unknown }> };\n return (spec.ops ?? []).some((o) => o.name === op && o.update !== undefined);\n } catch {\n return false;\n }\n}\n\n/** Keep the stack's one issue in line with its read. */\nasync function keepIssue(client: DriftForge, r: StackDrift, respond: DriftResponse): Promise<{ action: string; number?: number; url?: string }> {\n const at = r.observedAt ?? new Date().toISOString();\n const marker = driftIssueMarker(r.stack);\n if (r.drifted === 0) return client.trackIssue(marker, null, { closeOnClear: true, clearComment: driftClearedComment(r.stack, at) });\n const fingerprint = driftFingerprint(r.rows);\n const body = driftIssueBody({ stack: r.stack, rows: r.rows, observedAt: at, fingerprint, ...(client.runUrl ? { runUrl: client.runUrl } : {}), respond, ...(r.attribution?.length ? { attribution: r.attribution } : {}) });\n return client.trackIssue(marker, { title: driftIssueTitle(r.stack), body }, { sameWhen: fingerprint });\n}\n\n/** The PulumiWatchOp file for the stacks, one Op per stack on `schedule`. */\nexport function driftOpFile(doc: RawConfig, stacks: readonly string[], schedule: string): string {\n const listed = stacksOf(doc);\n const lines = [\n `// Written by '${PRODUCT} ci' from plywood.yml's drift key, and written again on each run: edit plywood.yml, not this file.`,\n `// One chant PulumiWatchOp per stack; the scheduled jobs run '${PRODUCT} drift --op <name>', and 'chant run <name>' runs one by hand.`,\n `import { PulumiWatchOp } from \"@intentius/chant-lexicon-pulumi\";`,\n \"\",\n ];\n for (const stack of stacks) {\n const name = driftOpName(stack);\n const pulumiStack = stack.slice(stack.indexOf(\"/\") + 1);\n const dir = listed[stack]?.dir ?? \".\";\n const config = { name, member: stack, dir, stack: pulumiStack, schedule };\n const fields = Object.entries(config).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(\", \");\n lines.push(`export const ${name.replace(/-/g, \"_\")} = PulumiWatchOp({ ${fields} }).op;`);\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\n/** chant's scheduled Op spec (`ScheduledOpSpec[]` and `ComponentPipelineOptions`) for the drift jobs. */\nexport function driftOpSpec(\n doc: RawConfig,\n forge: ForgeKind,\n stacks: readonly string[],\n schedule: string,\n chant?: ChantProduct,\n opts: { cloud?: boolean; contentsWrite?: boolean; env?: string } = {},\n): { ops: unknown[]; options: Record<string, unknown> } {\n const respond = driftResponseOf(doc);\n // With chant's agent job (chant#4616) the drift run keeps the issue and the agent job opens the pull request.\n const agentJob = hasChantAgent(chant) && respond === \"pull-request\";\n const findingMode = respond === \"none\" ? \"report\" : respond === \"pull-request\" && !agentJob ? (forge === \"gitlab\" ? \"merge-request\" : \"pull-request\") : \"issue\";\n const pipeline = toChantSettings({ doc }).pipeline;\n const engine = chantPipelineOptions({ ...(pipeline.image ? { image: pipeline.image } : {}), ...(pipeline.engineSetup ? { engineSetup: pipeline.engineSetup } : {}) }, false);\n return {\n ops: stacks.map((s) => ({ name: driftOpName(s), trigger: { kind: \"cron\", schedule }, findingMode, ...driftOpFields(chant, doc, driftOpName(s), respond), ...withNotifyVariables(driftJobFields(forge, pipeline.jobs, s), driftNotifyVariables(forge, chantNotifyOf(doc))), ...(opts.cloud ? driftCloudFields(doc, forge, s, respond, opts.env ?? \"production\", { contentsWrite: opts.contentsWrite === true }) : {}) })),\n options: {\n runCommand: [...BIN.split(/\\s+/), \"drift\", \"--op\", \"{name}\", \"--forge\", forge],\n beforeScript: [SNAPSHOTS_FETCH, ...(engine.beforeScript ?? [])],\n ...(engine.image ? { image: engine.image } : {}),\n },\n };\n}\n\n/**\n * chant#4631 on one stack's drift Op: `cloud`, the stack's preview identity,\n * which the read trades for before the checkout; and under respond.drift up,\n * `update`, a job after the read that runs `plywood up` for the waves\n * holding the stack with the stack's up identity, its forge environment and\n * plywood.yml's env and pass. The read itself never holds the up identity.\n * With `contentsWrite` (a chant that takes the chant#4631 ruling) the update\n * job on GitHub and Forgejo gets `contents: write`, so its records reach\n * chant/lifecycle with the job token.\n */\nexport function driftCloudFields(doc: RawConfig, forge: ForgeKind, stack: string, respond: DriftResponse, env: string, opts: { contentsWrite?: boolean } = {}): Record<string, unknown> {\n const settings = toChantSettings({ doc });\n const decl = settings.ci.identity?.cloud;\n const ids = decl ? resolveTargetCloudIdentity(decl as never, env, stack, stack) : undefined;\n const out: Record<string, unknown> = ids?.plan ? { cloud: ids.plan } : {};\n if (respond !== \"up\") return out;\n const waves = wavesHolding(doc, [stack]);\n const command = waves === \"all\" ? `${BIN} up` : waves.map((k) => `${BIN} up --wave ${k}`).join(\" && \");\n const fields = driftJobFields(forge, settings.pipeline.jobs, stack);\n // chant#4631 ruling: the update job may raise contents to write, so `plywood up` there records on chant/lifecycle.\n // GitLab has no per-job token scopes and refuses update.permissions; whether its job token may push is a project setting.\n const permissions = opts.contentsWrite && forge !== \"gitlab\" ? { permissions: { contents: \"write\" } } : {};\n out.update = { command, ...(ids?.apply ? { cloud: ids.apply } : {}), ...fields, ...permissions };\n return out;\n}\n\n/** plywood.yml's env, pass and environments on one stack's drift Op (plywood#29): its variables and forge environment. */\nexport function driftJobFields(forge: ForgeKind, jobs: JobSettings | undefined, stack: string): Record<string, unknown> {\n if (!jobs) return {};\n const variables = jobVariables(forge, jobs);\n const environment = forge === \"forgejo\" ? undefined : environmentFor(stack, jobs);\n return { ...(Object.keys(variables).length ? { variables } : {}), ...(environment ? { environment: { ...environment } } : {}) };\n}\n\n/**\n * The variables the drift job reads its notify webhooks and keys from\n * (plywood#30), each mapped from the forge secret of the same name, as the\n * waves workflow maps them. GitLab jobs have every CI/CD variable already.\n * None unless plywood.yml's notify takes the drift event.\n */\nexport function driftNotifyVariables(forge: ForgeKind, notify: ChantNotifyConfig | undefined): Record<string, string> {\n if (!notifiesDrift(notify) || forge === \"gitlab\") return {};\n const names = [notify!.webhook, notify!.key, notify!.slack, notify!.teams].filter((n): n is string => typeof n === \"string\");\n return Object.fromEntries(names.map((n) => [n, secretReference(forge, n)]));\n}\n\n/** `fields` with `notify` added to its variables; a variable plywood.yml's env or pass already sets stays. */\nfunction withNotifyVariables(fields: Record<string, unknown>, notify: Record<string, string>): Record<string, unknown> {\n if (Object.keys(notify).length === 0) return fields;\n return { ...fields, variables: { ...notify, ...((fields.variables as Record<string, string> | undefined) ?? {}) } };\n}\n\n/** Where chant's Op generator writes for each forge (chant run-generate.ts `DEFAULT_OP_PIPELINE_DIRS`). */\nconst OP_OUTPUT_DIR: Readonly<Record<ForgeKind, string>> = { github: \".github/workflows\", forgejo: \".forgejo/workflows\", gitlab: \".\" };\n\n/** Write `text` at `file` under `cwd` when it differs; true when it was written. */\nfunction writeIfChanged(cwd: string, file: string, text: string): boolean {\n const path = join(cwd, file);\n if (existsSync(path) && readFileSync(path, \"utf8\") === text) return false;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, text);\n return true;\n}\n\n/**\n * The scheduled drift jobs, for `plywood ci`: the Op file, the spec, and\n * chant's generator over them. Nothing when plywood.yml has no\n * drift.schedule.\n */\nexport async function writeDriftJobs(chant: ChantProduct, forge: ForgeKind, doc: RawConfig, words: ProductWordsInput, table: ExitTable, io: StageIo, env = \"production\"): Promise<number> {\n const settings = driftSettingsOf(doc);\n if (!settings.schedule) return table.done;\n if (settings.stacks.length === 0) {\n io.err(`${PRODUCT} ci: drift.schedule is set and plywood.yml lists no stacks, so no drift job was written`);\n return table.done;\n }\n const next = await chantNext();\n if (writeIfChanged(io.cwd, DRIFT_OP_FILE, driftOpFile(doc, settings.stacks, settings.schedule))) io.err(`${PRODUCT} ci: wrote ${DRIFT_OP_FILE}; commit it with the workflow`);\n if (writeIfChanged(io.cwd, DRIFT_SPEC_FILE, JSON.stringify(driftOpSpec(doc, forge, settings.stacks, settings.schedule, chant, { cloud: next.scheduledOpCloud, contentsWrite: next.updateContentsWrite, env }), null, 2) + \"\\n\")) io.err(`${PRODUCT} ci: wrote ${DRIFT_SPEC_FILE}`);\n const outDir = OP_OUTPUT_DIR[forge];\n const code = await chant.runChantInProcess([\"run\", \"--generate\", forge, \"--spec\", DRIFT_SPEC_FILE, \"--output\", outDir], words);\n if (code !== table.done) return code;\n const dir = join(io.cwd, outDir);\n const files = existsSync(dir)\n ? readdirSync(dir).filter((f) => /\\.ya?ml$/.test(f) && (readFileSync(join(dir, f), \"utf8\").split(\"\\n\", 1)[0] ?? \"\").includes(`--spec ${DRIFT_SPEC_FILE}`))\n : [];\n for (const f of files) io.err(`${PRODUCT} ci: drift job at ${join(outDir, f).replace(/^\\.\\//, \"\")} on ${settings.schedule}`);\n if (files.length && forge === \"gitlab\") io.err(`${PRODUCT} ci: GitLab runs the drift job from a pipeline schedule; include the file from .gitlab-ci.yml and add a schedule`);\n return table.done;\n}\n", "/**\n * Tip ids and their words, as reference/tips.md lists them. A tip names a\n * pattern in a preview and the fix for it. plywood holds the words; finding\n * the pattern in a change set belongs to chant's pulumi lexicon, which reads\n * the preview (CONTRIBUTING.md). `plywood tips [<id>]` prints them.\n */\n\nexport interface Tip {\n id: string;\n /** What the preview shows. */\n means: string;\n /** What to do about it. */\n fix: string;\n}\n\nexport const TIPS: readonly Tip[] = [\n {\n id: \"rename-without-aliases\",\n means: \"a resource is deleted and one of the same type is created under a new name or parent, with no `aliases` linking them\",\n fix: \"add `aliases: [{ name: \\\"<old name>\\\" }]` (or the old parent) so the update renames it in place\",\n },\n {\n id: \"replace-on-name\",\n means: \"a property change replaces a named resource\",\n fix: \"check the replacement is wanted, or add `deleteBeforeReplace`\",\n },\n {\n id: \"unknown-in-apply\",\n means: \"a resource registers inside `apply()`, so the preview cannot list it and the note shows it as may register at up\",\n fix: \"register it outside `apply()` where you can, or review the row in the note\",\n },\n {\n id: \"secret-in-plain-config\",\n means: \"a config value looks like a secret\",\n fix: \"set it with `pulumi config set --secret`\",\n },\n {\n id: \"no-protect-on-data\",\n means: \"a database or bucket has no `protect`\",\n fix: \"add `protect: true`\",\n },\n];\n\n/** The tip with `id`, if plywood knows it. */\nexport function tipById(id: string): Tip | undefined {\n return TIPS.find((t) => t.id === id);\n}\n\n/** The lines `plywood tips` prints: every tip, or the one named. */\nexport function tipLines(tips: readonly Tip[] = TIPS): string[] {\n return tips.flatMap((t) => [`${t.id}`, ` means ${t.means}`, ` fix ${t.fix}`]);\n}\n", "/**\n * Agents (plywood#19): plywood's tools on chant's read-only MCP server, and\n * the review agent's jobs.\n *\n * plywood mcp [--report-url <url>]\n * chant's `serve mcp --read-only` (chant#4543) in process, with\n * plywood's tools through chant's product tool hook (chant#4555,\n * `runChantInProcess(argv, words, { mcp })`). The server serves chant's\n * read tools (the ledger, the reports, the workspace graph) and\n * plywood's, `plywood:stacks`, `plywood:settings`, `plywood:tips` and\n * `plywood:verbs`, each declared read-only. It refuses every run tool:\n * chant leaves op-run and op-approve out, and will not start with a\n * product tool named as a write.\n *\n * plywood ci, with `review` set\n * writes ops/plywood-review.op.ts, a pull request Op that previews\n * the change (writing .chant/pr/change-set.json) and runs chant's\n * reviewAgent step in handoff mode, and .chant/ops/plywood-review.spec.json\n * with `reviewAgent: true`, then has chant's Op pipeline generator\n * write the two jobs: the review, with no forge write token, and the\n * note job that posts its one note. On GitLab the note job runs from a\n * default-branch schedule (chant#4544).\n */\nimport { existsSync, mkdirSync, readdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { toChantSettings } from \"./chant-config\";\nimport type { ChantProduct, ForgeKind } from \"./chant-product\";\nimport { configCheck } from \"./config-check\";\nimport { reviewOf } from \"./config/agents\";\nimport { findConfig, loadConfig, type RawConfig } from \"./config/index\";\nimport { stacksOf } from \"./config/stacks\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { chantPipelineOptions } from \"./images\";\nimport { takeFlag, usage, withChant, type StageIo } from \"./stages\";\nimport { tipLines, TIPS } from \"./tips\";\nimport { BIN, PR_GATE, PRODUCT, PRODUCT_WORDS, TAGLINE, VERBS, type ProductWordsInput } from \"./words\";\n\n/** chant's `McpToolContribution`, as plywood fills it. */\nexport interface PlywoodMcpTool {\n name: string;\n description: string;\n inputSchema: { type: \"object\"; properties: Record<string, unknown>; required?: string[] };\n handler: (params: Record<string, unknown>) => Promise<unknown>;\n readOnly: true;\n}\n\n/** chant's `ProductMcpHook` (chant#4555), as plywood fills it. */\nexport interface PlywoodMcpHook {\n product: string;\n tools(ctx: { cwd: string; readOnly: boolean }): PlywoodMcpTool[];\n reportUrl?: string;\n readOnly: true;\n instructions: string;\n}\n\n/** The verbs that need a person, for `plywood:verbs`: an agent opens a pull request and leaves these to a person. */\nexport const PERSON_VERBS = [\"up\", \"approve\", \"override\"] as const;\n\n/** plywood's read tools. Each reads plywood.yml or plywood's own words, and changes nothing. */\nexport function plywoodMcpTools(ctx: { cwd: string }): PlywoodMcpTool[] {\n const none = { type: \"object\" as const, properties: {} };\n const doc = (): RawConfig => {\n const file = findConfig(ctx.cwd);\n return file ? loadConfig(file).doc : {};\n };\n return [\n {\n name: \"stacks\",\n description: \"The stacks plywood.yml lists, each with its directory, gate and backend, and the waves they update in.\",\n inputSchema: none,\n readOnly: true,\n handler: async () => {\n const d = doc();\n return { stacks: stacksOf(d), waves: Array.isArray(d.waves) ? d.waves : null };\n },\n },\n {\n name: \"settings\",\n description: \"plywood.yml checked, with every problem and the settings in force, as `plywood config check --json` prints them.\",\n inputSchema: none,\n readOnly: true,\n handler: async () => {\n const r = configCheck(ctx.cwd);\n return { ok: r.ok, ...r.envelope };\n },\n },\n {\n name: \"tips\",\n description: \"The tips a plywood preview can name, such as a rename with no aliases.\",\n inputSchema: none,\n readOnly: true,\n handler: async () => ({ tips: TIPS, text: tipLines().join(\"\\n\") }),\n },\n {\n name: \"verbs\",\n description: \"plywood's commands, and which of them a person runs: an agent opens a pull request, and the update, approvals and overrides stay with people.\",\n inputSchema: none,\n readOnly: true,\n handler: async () => ({ verbs: VERBS, person: PERSON_VERBS }),\n },\n ];\n}\n\n/** The hook `plywood mcp` hands chant. */\nexport function plywoodMcpHook(reportUrl?: string): PlywoodMcpHook {\n return {\n product: PRODUCT,\n tools: (ctx) => plywoodMcpTools(ctx),\n readOnly: true,\n ...(reportUrl ? { reportUrl } : {}),\n instructions: `${PRODUCT} (${TAGLINE}) serves read tools only. To change a stack, open a pull request: ${PRODUCT} previews it, and its update runs after a person approves the digest.`,\n };\n}\n\n/** `plywood mcp [--report-url <url>]`: chant's read-only MCP server over stdio, with plywood's tools. */\nexport async function mcp(args: string[], _json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const report = takeFlag(args, \"--report-url\");\n if (report.missing) return usage(\"--report-url takes a URL\", table, io);\n if (report.rest.length) return usage(`mcp does not take ${report.rest.join(\" \")}`, table, io);\n return withChant(`${PRODUCT} mcp`, table, io, (chant) => {\n // stdout is the protocol's: every word of plywood's goes to stderr.\n if (typeof chant.PRODUCT_MCP_HOOK_FLOOR !== \"string\") {\n io.err(`${PRODUCT} mcp: this chant has no product tool hook (chant#4555), so the server serves chant's read tools and none of ${PRODUCT}'s`);\n }\n return chant.runChantInProcess([\"serve\", \"mcp\", \"--read-only\"], PRODUCT_WORDS, { mcp: plywoodMcpHook(report.value) });\n });\n}\n\n/** The pull request Op `plywood ci` writes for the review agent. */\nexport const REVIEW_OP = \"plywood-review\";\nexport const REVIEW_OP_FILE = \"ops/plywood-review.op.ts\";\nexport const REVIEW_SPEC_FILE = \".chant/ops/plywood-review.spec.json\";\n/** Where the preview in the review job writes the change set the model reads. */\nexport const REVIEW_CHANGE_SET = \".chant/pr/change-set.json\";\n\n/**\n * The preview the review job runs before the model: chant's pr-plan through\n * plywood's bin, with the base branch and the pull request's number read\n * from the forge's variables, and nothing posted.\n */\nexport const REVIEW_PREVIEW_LINE =\n `${BIN} components pr-plan --base \"origin/\\${GITHUB_BASE_REF:-$CI_MERGE_REQUEST_TARGET_BRANCH_NAME}\" ` +\n `--pr \"\\${CI_MERGE_REQUEST_IID:-$(node -p 'require(process.env.GITHUB_EVENT_PATH).pull_request.number')}\" --gate ${PR_GATE} --no-status`;\n\n/** The review Op's file: a preview, then chant's reviewAgent in handoff mode. */\nexport function reviewOpFile(doc: RawConfig): string {\n const r = reviewOf(doc) ?? { keyEnv: \"ANTHROPIC_API_KEY\" };\n const step: Record<string, unknown> = {\n op: REVIEW_OP,\n changeSetFile: REVIEW_CHANGE_SET,\n mode: \"handoff\",\n ...(r.instructions ? { instructions: r.instructions } : {}),\n ...(r.command ? { command: r.command } : {}),\n keyEnv: r.keyEnv,\n ...(r.timeout ? { timeout: r.timeout } : {}),\n };\n const fields = Object.entries(step).map(([k, v]) => `${k}: ${JSON.stringify(v)}`).join(\", \");\n return [\n `// Written by '${PRODUCT} ci' from plywood.yml's review key, and written again on each run: edit plywood.yml, not this file.`,\n `// The model reviews the pull request against its stacks' previews and posts one note. It approves and gates nothing.`,\n `import { Op, phase, reviewAgent, shell } from \"@intentius/chant/op\";`,\n \"\",\n \"export default Op({\",\n ` name: ${JSON.stringify(REVIEW_OP)},`,\n ` overview: \"A model reviews the pull request against its stacks' previews\",`,\n \" phases: [\",\n ` phase(\"Preview\", [shell(${JSON.stringify(REVIEW_PREVIEW_LINE)})]),`,\n ` phase(\"Review\", [reviewAgent({ ${fields} })]),`,\n \" ],\",\n \"});\",\n \"\",\n ].join(\"\\n\");\n}\n\n/** chant's scheduled Op spec for the review jobs. */\nexport function reviewOpSpec(doc: RawConfig): { ops: unknown[]; options: Record<string, unknown> } {\n const settings = toChantSettings({ doc });\n const p = settings.pipeline;\n const engine = chantPipelineOptions({ ...(p.image ? { image: p.image } : {}), ...(p.engineSetup ? { engineSetup: p.engineSetup } : {}) }, false);\n return {\n ops: [\n {\n name: REVIEW_OP,\n trigger: { kind: \"pull_request\" },\n reviewAgent: true,\n // The preview in the review job takes the preview identity; id-token is the one write the review job may hold.\n ...(settings.ci.identity ? { permissions: { \"id-token\": \"write\" } } : {}),\n },\n ],\n options: {\n ...(engine.beforeScript ? { beforeScript: engine.beforeScript } : {}),\n ...(engine.image ? { image: engine.image } : {}),\n },\n };\n}\n\nconst OP_OUTPUT_DIR: Readonly<Record<ForgeKind, string>> = { github: \".github/workflows\", forgejo: \".forgejo/workflows\", gitlab: \".\" };\n\nfunction writeIfChanged(cwd: string, file: string, text: string): boolean {\n const path = join(cwd, file);\n if (existsSync(path) && readFileSync(path, \"utf8\") === text) return false;\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, text);\n return true;\n}\n\n/** The review agent's jobs, for `plywood ci`. Nothing when plywood.yml has no `review`. */\nexport async function writeReviewJobs(chant: ChantProduct, forge: ForgeKind, doc: RawConfig, words: ProductWordsInput, table: ExitTable, io: StageIo): Promise<number> {\n if (!reviewOf(doc)) return table.done;\n if (writeIfChanged(io.cwd, REVIEW_OP_FILE, reviewOpFile(doc))) io.err(`${PRODUCT} ci: wrote ${REVIEW_OP_FILE}; commit it with the workflow`);\n if (writeIfChanged(io.cwd, REVIEW_SPEC_FILE, JSON.stringify(reviewOpSpec(doc), null, 2) + \"\\n\")) io.err(`${PRODUCT} ci: wrote ${REVIEW_SPEC_FILE}`);\n const outDir = OP_OUTPUT_DIR[forge];\n const code = await chant.runChantInProcess([\"run\", \"--generate\", forge, \"--spec\", REVIEW_SPEC_FILE, \"--output\", outDir], words);\n if (code !== table.done) return code;\n const dir = join(io.cwd, outDir);\n const files = existsSync(dir)\n ? readdirSync(dir).filter((f) => /\\.ya?ml$/.test(f) && (readFileSync(join(dir, f), \"utf8\").split(\"\\n\", 1)[0] ?? \"\").includes(`--spec ${REVIEW_SPEC_FILE}`))\n : [];\n for (const f of files) io.err(`${PRODUCT} ci: review jobs at ${join(outDir, f).replace(/^\\.\\//, \"\")}`);\n const r = reviewOf(doc)!;\n io.err(`${PRODUCT} ci: the review job reads the model's key from ${r.keyEnv}; set it from a secret`);\n if (forge === \"gitlab\") io.err(`${PRODUCT} ci: on GitLab the note job runs on the default branch with CHANT_REVIEW_NOTES=1 from a pipeline schedule, and posts with a protected CHANT_FORGE_TOKEN`);\n return table.done;\n}\n", "/**\n * The provider allowlist preset (plywood#31): plywood.yml's\n * `policy.providers` lists the provider packages a stack may use, and\n * `plywood init` writes the same check twice, from `presets/policy/` in the\n * package (this module sits under `src/` so `../presets/` resolves from the\n * source and from the bundle):\n *\n * <policy.rego>/plywood_providers.rego a deny_provider_package rule\n * over chant's change set, the\n * list written into the rule\n * policy/plywood-providers/ a CrossGuard pack, mandatory,\n * policy/plywood-providers.json its config: the list\n *\n * Both read a resource's provider package from its type: `aws` for\n * `aws:s3/bucket:Bucket`, the provided package for a provider resource\n * (`pulumi:providers:aws`), and none for the engine's own `pulumi:` types.\n * A component's package is its own namespace, so list it too. The Rego rule\n * judges what the change creates, updates or replaces; a delete or an\n * unchanged resource never denies. {@link providerDenials} is the same rule\n * in TypeScript, for the tests and for `plywood init` to say what the\n * preset would deny.\n */\nimport { readFileSync } from \"node:fs\";\n\n/** A provider package name, as a Pulumi type's first segment spells it. */\nexport const PROVIDER_PACKAGE = /^[a-z][a-z0-9-]*$/;\n\n/** Where `plywood init` writes the pack and its config, relative to the repository root. */\nexport const PROVIDERS_PACK_DIR = \"policy/plywood-providers\";\nexport const PROVIDERS_PACK_CONFIG = \"policy/plywood-providers.json\";\n/** The Rego file's name inside policy.rego. */\nexport const PROVIDERS_REGO_FILE = \"plywood_providers.rego\";\n/** The pack's policy name, which its config keys and its rule id (`crossguard.plywood-providers.provider-allowlist`) carry. */\nexport const PROVIDERS_POLICY = \"provider-allowlist\";\n\n/** The provider package of a Pulumi type, or undefined for the engine's own types. */\nexport function providerPackageOf(type: string): string | undefined {\n if (type.startsWith(\"pulumi:providers:\")) return type.slice(\"pulumi:providers:\".length);\n if (type.startsWith(\"pulumi:\") || type === \"unknown\") return undefined;\n return type.split(\":\")[0];\n}\n\n/** What the change set entries the rule reads hold. */\nexport interface PolicyEntry {\n lexicon: string;\n address: string;\n type: string;\n action: string;\n}\n\nconst JUDGED = new Set([\"create\", \"update\", \"replace\"]);\n\n/** The Rego rule's messages for `entries`, in order: one per created, updated or replaced resource whose package is not allowed. */\nexport function providerDenials(entries: readonly PolicyEntry[], allowed: readonly string[]): string[] {\n const ok = new Set(allowed);\n return entries.flatMap((e) => {\n if (e.lexicon !== \"pulumi\" || !JUDGED.has(e.action)) return [];\n const pkg = providerPackageOf(e.type);\n return pkg !== undefined && !ok.has(pkg) ? [`${e.address} uses the provider package ${pkg}, which policy.providers does not list`] : [];\n });\n}\n\nconst preset = (rel: string): string => readFileSync(new URL(`../presets/policy/${rel}`, import.meta.url), \"utf8\");\n\n/** The Rego rule with `allowed` written in, in `namespace` (default `main`, which conftest and opa read by default). */\nexport function providersRego(allowed: readonly string[], namespace = \"main\"): string {\n const set = allowed.length ? `{${[...new Set(allowed)].sort().map((p) => JSON.stringify(p)).join(\", \")}}` : \"set()\";\n return preset(\"plywood_providers.rego.tmpl\").replace(\"{{namespace}}\", namespace).replace(\"{{allowed}}\", set);\n}\n\n/** The CrossGuard pack's files, relative to {@link PROVIDERS_PACK_DIR}. */\nexport function providersPackFiles(): Record<string, string> {\n return Object.fromEntries([\"index.ts\", \"PulumiPolicy.yaml\", \"package.json\"].map((f) => [f, preset(`plywood-providers/${f}`)]));\n}\n\n/** The pack's `--policy-pack-config` file: the list under the policy's name. */\nexport function providersPackConfig(allowed: readonly string[]): string {\n return JSON.stringify({ [PROVIDERS_POLICY]: { allowed: [...new Set(allowed)].sort() } }, null, 2) + \"\\n\";\n}\n", "/**\n * Each stack's backend, and the bucket check on a self-managed one.\n *\n * The backend is the first that answers: the stack's own `backend` in\n * plywood.yml, plywood.yml's `backend`, `PULUMI_BACKEND_URL` in init's\n * environment, `backend.url` in the project's Pulumi.yaml. None of them\n * means Pulumi Cloud (or whatever `pulumi login` holds on the machine that\n * runs the job). A URL that only the environment gave is written into\n * plywood.yml, since the jobs do not see init's environment.\n *\n * An `s3://`, `gs://` or `azblob://` backend (with or without `plunge+`)\n * gets chant's shared bucket check (`@intentius/chant/bucket-check`,\n * chant#4558): versioning, a lifecycle rule that expires noncurrent\n * versions, and the public access block. The check only reads. It is\n * reached through a feature-detect, since plywood's pinned chant (0.124.54)\n * lacks it; scripts/build-cli.mjs stands in a throwing module there.\n */\nimport type { DetectedProject } from \"./detect\";\n\nexport type BucketStore = \"s3\" | \"gcs\" | \"azblob\";\n\n/** The part of chant's `BucketReport` init prints. */\nexport interface BucketReport {\n store: BucketStore;\n bucket: string;\n namespaces: string[];\n correct: boolean;\n settings: Array<{ setting: string; verdict: \"ok\" | \"fail\" | \"unreadable\"; found: string; unwaivable: boolean; fix?: string }>;\n}\n\n/** What plywood calls from `@intentius/chant/bucket-check`. */\nexport interface ChantBucketCheck {\n checkBucket(target: Record<string, unknown>, options?: { namespaces?: readonly string[] }): Promise<BucketReport>;\n}\n\n/** A backend URL's bucket, as chant's check takes it, or why it cannot be checked. */\nexport type BucketTarget =\n | { ok: true; target: Record<string, unknown>; namespaces: string[]; label: string }\n | { ok: false; reason: string; label: string };\n\nexport interface StackBackend {\n url?: string;\n source: \"plywood.yml\" | \"PULUMI_BACKEND_URL\" | \"Pulumi.yaml\" | \"none\";\n}\n\n/** The backend a stack opens, first that answers. */\nexport function backendOf(\n project: Pick<DetectedProject, \"backendUrl\">,\n plywood: { stack?: string; all?: string },\n env: NodeJS.ProcessEnv,\n): StackBackend {\n if (plywood.stack) return { url: plywood.stack, source: \"plywood.yml\" };\n if (plywood.all) return { url: plywood.all, source: \"plywood.yml\" };\n const fromEnv = env.PULUMI_BACKEND_URL?.trim();\n if (fromEnv) return { url: fromEnv, source: \"PULUMI_BACKEND_URL\" };\n if (project.backendUrl) return { url: project.backendUrl, source: \"Pulumi.yaml\" };\n return { source: \"none\" };\n}\n\n/** True for Pulumi Cloud: no URL, or an https:// URL (the hosted service or a self-hosted Pulumi Cloud). */\nexport function isPulumiCloud(url: string | undefined): boolean {\n return url === undefined || /^https?:\\/\\//.test(url);\n}\n\n/** The URL without plunge's `plunge+` or `plunge:` prefix. */\nexport function stockUrl(url: string): string {\n return url.replace(/^plunge[+:]/, \"\");\n}\n\n/** Pulumi's state lives under `<prefix>/.pulumi/` in the bucket; the lifecycle rule must cover it. */\nfunction namespaceOf(prefix: string): string {\n const p = prefix.replace(/^\\/+|\\/+$/g, \"\");\n return p === \"\" ? \".pulumi\" : `${p}/.pulumi`;\n}\n\n/**\n * chant's bucket target for a backend URL, with the credentials an emulator\n * needs taken from the environment. A real store's credentials come from\n * chant's default chains, never from here.\n */\nexport function bucketTarget(url: string, env: NodeJS.ProcessEnv): BucketTarget | undefined {\n const stock = stockUrl(url);\n let u: URL;\n try {\n u = new URL(stock);\n } catch {\n return undefined;\n }\n const label = stock;\n if (u.protocol === \"s3:\") {\n const q = u.searchParams;\n const region = q.get(\"region\") ?? env.AWS_REGION ?? env.AWS_DEFAULT_REGION ?? \"us-east-1\";\n const rawEndpoint = q.get(\"endpoint\") ?? env.AWS_ENDPOINT_URL_S3 ?? env.AWS_ENDPOINT_URL;\n const target: Record<string, unknown> = { store: \"s3\", bucket: u.hostname, region };\n if (rawEndpoint) {\n const endpoint = /^https?:\\/\\//.test(rawEndpoint) ? rawEndpoint : `${q.get(\"disableSSL\") === \"true\" ? \"http\" : \"https\"}://${rawEndpoint}`;\n if (!env.AWS_ACCESS_KEY_ID || !env.AWS_SECRET_ACCESS_KEY) {\n return { ok: false, label, reason: `the bucket is on ${endpoint}, and checking it needs AWS_ACCESS_KEY_ID and AWS_SECRET_ACCESS_KEY in the environment` };\n }\n target.endpoint = endpoint;\n target.credentials = {\n accessKeyId: env.AWS_ACCESS_KEY_ID,\n secretAccessKey: env.AWS_SECRET_ACCESS_KEY,\n ...(env.AWS_SESSION_TOKEN ? { sessionToken: env.AWS_SESSION_TOKEN } : {}),\n };\n }\n return { ok: true, target, namespaces: [namespaceOf(u.pathname)], label };\n }\n if (u.protocol === \"gs:\") {\n const target: Record<string, unknown> = { store: \"gcs\", bucket: u.hostname };\n const emulator = env.STORAGE_EMULATOR_HOST;\n if (emulator) {\n target.endpoint = /^https?:\\/\\//.test(emulator) ? emulator : `http://${emulator}`;\n target.token = env.GOOGLE_OAUTH_ACCESS_TOKEN ?? null;\n }\n return { ok: true, target, namespaces: [namespaceOf(u.pathname)], label };\n }\n if (u.protocol === \"azblob:\") {\n const account = u.searchParams.get(\"storage_account\") ?? env.AZURE_STORAGE_ACCOUNT;\n const subscriptionId = env.AZURE_SUBSCRIPTION_ID;\n const resourceGroup = env.AZURE_RESOURCE_GROUP;\n if (!account || !subscriptionId || !resourceGroup) {\n return { ok: false, label, reason: \"checking an Azure container needs its storage account (storage_account= in the URL, or AZURE_STORAGE_ACCOUNT), AZURE_SUBSCRIPTION_ID and AZURE_RESOURCE_GROUP\" };\n }\n const target: Record<string, unknown> = { store: \"azblob\", subscriptionId, resourceGroup, account, container: u.hostname };\n if (env.AZURE_ARM_ENDPOINT) {\n if (!env.AZURE_ARM_TOKEN) return { ok: false, label, reason: `the account is on ${env.AZURE_ARM_ENDPOINT}, and checking it needs AZURE_ARM_TOKEN` };\n target.endpoint = env.AZURE_ARM_ENDPOINT;\n target.token = env.AZURE_ARM_TOKEN;\n }\n return { ok: true, target, namespaces: [namespaceOf(u.pathname)], label };\n }\n return undefined;\n}\n\n/** The message init prints when the installed chant has no bucket check. */\nexport function needsBucketCheckMessage(builtChant: string): string {\n return (\n \"the bucket check needs chant >= the release after 0.124.54, which carries @intentius/chant/bucket-check (chant#4558). \" +\n `This plywood was built with chant ${builtChant}, which lacks it, so the bucket was not checked.`\n );\n}\n\nlet cached: Promise<ChantBucketCheck | undefined> | undefined;\n\n/** chant's bucket check, or undefined when the installed chant lacks it. */\nexport function chantBucketCheck(): Promise<ChantBucketCheck | undefined> {\n cached ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4558).\n const m: Record<string, unknown> = await import(\"@intentius/chant/bucket-check\");\n return typeof m.checkBucket === \"function\" ? (m as unknown as ChantBucketCheck) : undefined;\n } catch {\n return undefined;\n }\n })();\n return cached;\n}\n\n/** Tests stand in a fake check (or none). `reset` goes back to the real import. */\nexport function setBucketCheckForTests(fake: ChantBucketCheck | undefined | \"reset\"): void {\n cached = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The lines init prints for one report: the headline, then each failing setting with its fix. */\nexport function bucketLines(report: BucketReport): string[] {\n const where = `${report.store === \"azblob\" ? \"container\" : \"bucket\"} ${report.bucket}`;\n if (report.correct) return [` ${where}: versioning, the noncurrent-version rule and the public access block are in place`];\n const out = [` ${where} is missing settings plunge refuses to open without, and stock Pulumi's history relies on:`];\n for (const f of report.settings) {\n if (f.verdict === \"ok\") continue;\n out.push(` ${f.setting}: ${f.found}${f.verdict === \"unreadable\" ? \" (could not be read)\" : \"\"}`);\n if (f.fix) out.push(...f.fix.split(\"\\n\").map((l) => ` ${l}`));\n }\n return out;\n}\n", "/**\n * The adopt previews `plywood init` prints for each stack on a `plunge+`\n * backend, and the adopt Op it writes for the step after (chant#4562).\n *\n * plunge refuses a stock checkpoint with no records, so a stack moves onto\n * plunge by `plunge stack adopt`. init runs only the preview form, `plunge\n * stack adopt --json --stack <s>`, which classifies every resource and\n * writes nothing. It runs through chant's pulumi lexicon (`runAllowedPlunge`\n * and its allowlist in lexicons/pulumi/src/run.ts) with PULUMI_BACKEND_URL\n * set to the stack's plunge URL for that run, and plywood runs no plunge\n * process of its own. A refused preview, or plunge missing from PATH, is\n * printed and init still exits 0, as for the bucket check.\n *\n * The adoption itself is `plywood.adopt.op.ts`, chant's `PulumiAdoptOp`:\n * the bucket check, the stock export kept as the back-out copy, then per\n * stack the preview, a gate on the workspace ledger bound to the preview's\n * digest, and `plunge stack adopt --json --yes`. `chant run plywood-adopt`\n * stops at each gate and `chant approve plywood-adopt <gate>` opens it.\n *\n * Both are reached through a feature-detect: the pulumi lexicon at plywood's\n * pin (0.124.54) has no adopt argv, adopt document parser or Op. Then init\n * prints the preview command for each stack and skips the Op file.\n */\nimport type { PlungeStack } from \"./engine\";\nimport { slug } from \"./detect\";\n\n/** The adopt Op init writes, and its file. */\nexport const ADOPT_OP = \"plywood-adopt\";\nexport const ADOPT_OP_FILE = \"plywood.adopt.op.ts\";\n\n/** The parts of plunge's adopt document (chant `PlungeAdoptView`) init prints. */\nexport interface AdoptView {\n stack: string;\n status: \"would-adopt\" | \"adopted\" | \"already-adopted\" | \"refused\";\n checkpoint: { source?: string; digest?: string };\n resources: Array<{ urn: string; type: string; id: string; fate: string }>;\n refusals: Array<{ code: string; urn?: string; reason: string }>;\n}\n\n/** One stack's preview as init reports it. */\nexport interface AdoptPreview {\n key: string;\n backend: string;\n /** The command, for the person to run by hand. */\n command: string;\n view?: AdoptView;\n /** Why there is no document: plunge missing, a failed run, no adopt support in the installed lexicon. */\n error?: string;\n}\n\n/** What plywood calls from chant's pulumi lexicon. */\nexport interface ChantAdopt {\n /** `plunge stack adopt --json --stack <stack>` in `dir` with PULUMI_BACKEND_URL=`backend`, through chant's allowlist. */\n preview(input: { dir: string; stack: string; backend: string }): Promise<AdoptView>;\n /** True when the lexicon exports `PulumiAdoptOp`. */\n hasOp: boolean;\n}\n\ntype Runner = (args: string[], opts: { cwd: string; env?: Record<string, string> }) => Promise<{ stdout: string }>;\n\nlet cached: Promise<ChantAdopt | undefined> | undefined;\n\n/** chant's adopt pieces, or undefined when the installed pulumi lexicon lacks them. */\nexport function chantAdopt(): Promise<ChantAdopt | undefined> {\n cached ??= (async () => {\n try {\n // @ts-ignore: plungeAdoptArgs and runAllowedPlunge's env are missing from the lexicon at 0.124.54 (chant#4562).\n const run: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi/run\");\n // @ts-ignore: parsePlungeAdoptView and PulumiAdoptOp are missing from the lexicon at 0.124.54 (chant#4562).\n const lexicon: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n const args = run.plungeAdoptArgs as ((o: { stack: string }) => string[]) | undefined;\n const allowed = run.runAllowedPlunge as ((r: Runner, a: string[], cwd: string, env?: Record<string, string>) => Promise<{ stdout: string }>) | undefined;\n const runner = run.defaultPlungeRunner as Runner | undefined;\n const parse = lexicon.parsePlungeAdoptView as ((t: string | undefined) => AdoptView | undefined) | undefined;\n const failure = run.pulumiRunFailure as ((e: unknown) => { stdout?: string; stderr?: string; message: string; missingBinary?: boolean }) | undefined;\n if (typeof args !== \"function\" || typeof allowed !== \"function\" || typeof runner !== \"function\" || typeof parse !== \"function\") return undefined;\n return {\n hasOp: typeof lexicon.PulumiAdoptOp === \"function\",\n async preview({ dir, stack, backend }) {\n try {\n const { stdout } = await allowed(runner, args({ stack }), dir, { PULUMI_BACKEND_URL: backend });\n const view = parse(stdout);\n if (!view) throw new Error(\"plunge printed no adopt document\");\n return view;\n } catch (err) {\n const f = failure ? failure(err) : { message: (err as Error).message };\n const view = parse(f.stdout);\n if (view) return view;\n if (f.missingBinary) throw new Error(\"the plunge binary was not found on PATH\");\n throw new Error((f.stderr?.trim() || f.message).split(\"\\n\").slice(-3).join(\"\\n\"));\n }\n },\n };\n } catch {\n return undefined;\n }\n })();\n return cached;\n}\n\n/** Tests stand in a fake (or none). `reset` goes back to the real import. */\nexport function setChantAdoptForTests(fake: ChantAdopt | undefined | \"reset\"): void {\n cached = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The preview command for one stack, as the person would type it. */\nexport function adoptCommand(s: Pick<PlungeStack, \"dir\" | \"stack\">, backend: string): string {\n const cd = s.dir === \".\" ? \"\" : `cd ${s.dir} && `;\n return `${cd}PULUMI_BACKEND_URL='${backend}' plunge stack adopt --json --stack ${s.stack}`;\n}\n\n/** The message when the installed pulumi lexicon has no adopt support. */\nexport const NEEDS_ADOPT_MESSAGE =\n \"the adopt previews and the adopt Op need @intentius/chant-lexicon-pulumi >= the release after 0.124.54 (chant#4562); run each preview by hand:\";\n\n/** Each stack's adopt preview. Runs nothing when `chant` is undefined. */\nexport async function adoptPreviews(\n stacks: ReadonlyArray<Pick<PlungeStack, \"key\" | \"dir\" | \"stack\"> & { url: string }>,\n chant: ChantAdopt | undefined,\n root: string,\n): Promise<AdoptPreview[]> {\n const out: AdoptPreview[] = [];\n for (const s of stacks) {\n const command = adoptCommand(s, s.url);\n if (!chant) {\n out.push({ key: s.key, backend: s.url, command, error: \"not run\" });\n continue;\n }\n try {\n const view = await chant.preview({ dir: s.dir === \".\" ? root : `${root}/${s.dir}`, stack: s.stack, backend: s.url });\n out.push({ key: s.key, backend: s.url, command, view });\n } catch (e) {\n out.push({ key: s.key, backend: s.url, command, error: (e as Error).message });\n }\n }\n return out;\n}\n\n/** Counts by fate, as `record 10, marker 2`. */\nfunction fates(view: AdoptView): string {\n const n: Record<string, number> = {};\n for (const r of view.resources) n[r.fate] = (n[r.fate] ?? 0) + 1;\n return Object.entries(n)\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([f, c]) => `${f} ${c}`)\n .join(\", \");\n}\n\n/** The lines init prints for the previews. */\nexport function adoptLines(previews: readonly AdoptPreview[], chant: ChantAdopt | undefined): string[] {\n if (previews.length === 0) return [];\n if (!chant) return [NEEDS_ADOPT_MESSAGE, ...previews.map((p) => ` ${p.key}: ${p.command}`)];\n const out = [\"Adopt previews (plunge stack adopt --json, which writes nothing):\"];\n for (const p of previews) {\n const v = p.view;\n if (!v) {\n out.push(` ${p.key}: not previewed; ${p.error}. Run it by hand: ${p.command}`);\n continue;\n }\n const count = `${v.resources.length} resource${v.resources.length === 1 ? \"\" : \"s\"}`;\n if (v.status === \"refused\") {\n out.push(` ${p.key}: plunge refuses to adopt it:`);\n for (const r of v.refusals) out.push(` ${r.code}: ${r.reason}${r.urn ? ` (${r.urn})` : \"\"}`);\n } else if (v.status === \"already-adopted\") {\n out.push(` ${p.key}: already on plunge's records (${count})`);\n } else if (v.status === \"adopted\") {\n out.push(` ${p.key}: adopted (${count})`);\n } else {\n out.push(` ${p.key}: would adopt ${count}${v.resources.length ? ` (${fates(v)})` : \"\"}`);\n }\n }\n return out;\n}\n\n/** The stacks the Op adopts: those with a plunge URL whose preview did not say they are adopted already. */\nexport function stacksToAdopt<T extends { key: string }>(stacks: readonly T[], previews: readonly AdoptPreview[]): T[] {\n return stacks.filter((s) => previews.find((p) => p.key === s.key)?.view?.status !== \"already-adopted\");\n}\n\n/** The gate chant's PulumiAdoptOp names for a stack (`approve-<op>`, or `approve-<op>-<member>-<stack>` with several). */\nexport function adoptGate(member: string, stack: string, single: boolean): string {\n return single ? `approve-${ADOPT_OP}` : `approve-${ADOPT_OP}-${member}-${stack}`;\n}\n\n/** `plywood.adopt.op.ts`: chant's PulumiAdoptOp over the stacks, each with its plunge URL. */\nexport function adoptOpFile(stacks: ReadonlyArray<{ member: string; dir: string; stack: string; url: string }>): string {\n const rows = stacks.map(\n (s) => ` { member: ${JSON.stringify(s.member)}, dir: ${JSON.stringify(s.dir)}, stack: ${JSON.stringify(s.stack)}, backend: ${JSON.stringify(s.url)} },`,\n );\n return [\n 'import { PulumiAdoptOp } from \"@intentius/chant-lexicon-pulumi\";',\n \"\",\n \"/**\",\n \" * Written by plywood init --engine plunge. Adopts each stack onto plunge's\",\n \" * per-resource records: the bucket check, the stock export kept as the\",\n \" * back-out copy, then per stack the adopt preview, a gate bound to it, and\",\n \" * plunge stack adopt --yes.\",\n \" *\",\n ` * npx chant run ${ADOPT_OP} stops at each stack's gate`,\n ` * npx chant approve ${ADOPT_OP} <gate> after reading that stack's preview`,\n ` * npx chant run ${ADOPT_OP} adopts the approved stacks`,\n \" *\",\n \" * Delete this file once every stack is adopted.\",\n \" */\",\n \"export const { op } = PulumiAdoptOp({\",\n ` name: ${JSON.stringify(ADOPT_OP)},`,\n \" stacks: [\",\n ...rows,\n \" ],\",\n \"});\",\n \"\",\n ].join(\"\\n\");\n}\n\n/** The todo lines for running the Op. */\nexport function adoptTodo(stacks: ReadonlyArray<{ member: string; stack: string }>): string[] {\n const single = stacks.length === 1;\n const gates = stacks.map((s) => adoptGate(slug(s.member), slug(s.stack), single));\n return [\n `Adopt the stacks onto plunge before their first plunge update: npx chant run ${ADOPT_OP}, then npx chant approve ${ADOPT_OP} <gate> for each of ${gates.join(\", \")} after reading its preview, then npx chant run ${ADOPT_OP} again`,\n ];\n}\n", "/**\n * `plywood init --engine`: the engine step of init.\n *\n * With no flag the step writes nothing, and chant's pulumi lexicon decides\n * per stack from a `plunge+` backend, PULUMI_BACKEND_URL or Pulumi.yaml\n * (chant#4559). `--engine pulumi` writes `engine: pulumi`.\n *\n * `--engine plunge` reads each stack's current backend (PULUMI_BACKEND_URL,\n * then Pulumi.yaml's backend.url, src/init/backend.ts) and gives it\n * `plunge+<same url>` in plywood.yml. plunge keeps its records beside the\n * stock state at the same root, so Pulumi.yaml and Pulumi.<stack>.yaml stay\n * as they are, and chant reports engine plunge for the stack from\n * plywood.yml alone. plunge has a `plunge+` form for file, s3, azblob and gs\n * (plunge pkg/backend/plunge/url.go); a Pulumi Cloud stack, or one on a\n * backend with no such form (Postgres), gets the guide that moves it in\n * place of a URL. init never picks plunge without the flag.\n *\n * When every stack can move and they share one backend, plywood.yml gets\n * `engine: plunge` and that `backend`. When they differ, each stack gets its\n * own `stacks.<project/stack>.backend`, and `engine: plunge` is written only\n * when every stack has one; a stack left on Pulumi Cloud stays on stock\n * Pulumi. The bucket check (src/init.ts bucketStep) and the adopt previews\n * (src/init/adopt.ts) then run on the URLs plywood.yml names.\n */\nimport type { RawConfig } from \"../config/types\";\nimport { PLUNGE_URL } from \"../config/engine\";\nimport { backendOf, isPulumiCloud, type StackBackend } from \"./backend\";\nimport type { Detected } from \"./detect\";\n\nexport const INIT_ENGINES = [\"pulumi\", \"plunge\"] as const;\nexport type InitEngine = (typeof INIT_ENGINES)[number];\n\n/** The site page that moves a Pulumi Cloud stack onto a bucket, then onto plunge with `adopt --file`. */\nexport const MOVE_A_STACK_GUIDE = \"https://intentius.io/plywood/guides/move-a-stack-backend/\";\n\n/** The DIY backend schemes plunge opens as `plunge+<url>` (plunge url.go). */\nconst PLUNGE_FORMS = /^(?:file|s3|azblob|gs):\\/\\//;\n\n/** What the engine step hands back to init. */\nexport interface EngineStep {\n /** Keys for a new plywood.yml. */\n keys: RawConfig;\n /** Lines init prints under the files it wrote. */\n notes: string[];\n /** Each stack's move onto plunge, with `--engine plunge`. */\n plunge?: PlungeStack[];\n}\n\nexport interface EngineStepInput {\n engine: InitEngine | undefined;\n detected: Detected;\n env: NodeJS.ProcessEnv;\n}\n\n/** One stack under `--engine plunge`: its backend now, and its plunge URL or why it has none. */\nexport interface PlungeStack {\n key: string;\n project: string;\n stack: string;\n dir: string;\n /** The backend the stack opens today, absent for Pulumi Cloud by login. */\n current?: string;\n source: StackBackend[\"source\"];\n /** `plunge+<current>`, when plunge can open the stack's backend. */\n url?: string;\n /** Why the stack gets no plunge URL. */\n pointer?: string;\n}\n\n/** The plunge URL for a backend URL, or why there is none. */\nexport function plungeUrlOf(url: string | undefined): { url: string } | { pointer: string } {\n if (url !== undefined && PLUNGE_URL.test(url)) return { url };\n if (isPulumiCloud(url)) {\n return {\n pointer:\n `is on Pulumi Cloud${url ? ` (${url})` : \"\"}, which plunge does not open. Export the stack, move it to a bucket, ` +\n `and adopt the export with plunge stack adopt --file: ${MOVE_A_STACK_GUIDE}`,\n };\n }\n if (PLUNGE_FORMS.test(url!)) return { url: `plunge+${url}` };\n const scheme = url!.split(\"://\")[0];\n return { pointer: `is on ${url}, and plunge has no plunge+ form for ${scheme}. Move it to a file, s3, azblob or gs backend first: ${MOVE_A_STACK_GUIDE}` };\n}\n\n/** Each found stack's plunge move, from the backend it opens today. */\nexport function plungeStacks(detected: Detected, env: NodeJS.ProcessEnv): PlungeStack[] {\n return detected.stacks.map((s) => {\n const project = detected.projects.find((p) => p.dir === s.dir && p.name === s.project) ?? { backendUrl: undefined };\n const b = backendOf(project, {}, env);\n const to = plungeUrlOf(b.url);\n return {\n key: s.key,\n project: s.project,\n stack: s.stack,\n dir: s.dir,\n ...(b.url !== undefined ? { current: b.url } : {}),\n source: b.source,\n ...(\"url\" in to ? { url: to.url } : { pointer: to.pointer }),\n };\n });\n}\n\n/** plywood.yml's keys for the stacks that move: one shared `backend`, else one per stack. */\nexport function plungeKeys(stacks: readonly PlungeStack[]): RawConfig {\n const moving = stacks.filter((s) => s.url !== undefined);\n if (moving.length === 0) return {};\n const all = moving.length === stacks.length;\n const urls = new Set(moving.map((s) => s.url));\n if (all && urls.size === 1) return { engine: \"plunge\", backend: moving[0]!.url };\n const per: Record<string, RawConfig> = {};\n for (const s of moving) per[s.key] = { ...(s.dir !== \".\" ? { dir: s.dir } : {}), backend: s.url };\n return { ...(all ? { engine: \"plunge\" } : {}), stacks: per };\n}\n\n/** The lines init prints for the plunge move. */\nexport function plungeLines(stacks: readonly PlungeStack[]): string[] {\n if (stacks.length === 0) return [\"--engine plunge: no stack was found, so no plunge backend is written\"];\n const out = [\"plunge backends (Pulumi.yaml and Pulumi.<stack>.yaml are unchanged; plunge keeps its records beside the stock state):\"];\n for (const s of stacks) {\n if (s.url) out.push(` ${s.key}: ${s.url}${s.current && s.current !== s.url ? `, the same root as ${s.current} (${s.source})` : \"\"}`);\n else out.push(` ${s.key} ${s.pointer}`);\n }\n if (stacks.every((s) => !s.url)) out.push(\" No stack can move yet, so plywood.yml names no engine and the stacks stay on stock Pulumi.\");\n else if (stacks.some((s) => !s.url)) out.push(\" The stacks without a plunge URL stay on stock Pulumi until they move.\");\n return out;\n}\n\n/** The engine step for a new plywood.yml. */\nexport function engineStep(input: EngineStepInput): EngineStep {\n if (input.engine === undefined) return { keys: {}, notes: [] };\n if (input.engine === \"pulumi\") return { keys: { engine: \"pulumi\" }, notes: [] };\n const stacks = plungeStacks(input.detected, input.env);\n return { keys: plungeKeys(stacks), notes: plungeLines(stacks), plunge: stacks };\n}\n", "/**\n * The presets `plywood init` offers: a few starting points for plywood.yml,\n * each a small set of plywood keys. Approval binds to the pull request's\n * preview in every preset (chant#4550 ruling B, plywood's `pull-request`\n * preset), so a preset chooses when updates run and when a wave waits, and\n * never per-wave approval.\n *\n * Beside them, init switches on what the repository already uses:\n * `.pre-commit-config.yaml` becomes a check hook (chant#4556's\n * `ci.hooks.check`), so `plywood check` runs the team's own hooks.\n */\nimport type { RawConfig } from \"../config/types\";\n\nexport interface Preset {\n name: PresetName;\n summary: string;\n /** The plywood.yml keys the preset writes; empty means plywood's defaults. */\n keys: RawConfig;\n}\n\nexport const PRESET_NAMES = [\"merge\", \"before-merge\", \"approve-all\"] as const;\nexport type PresetName = (typeof PRESET_NAMES)[number];\nexport const DEFAULT_PRESET: PresetName = \"merge\";\n\nexport const PRESETS: readonly Preset[] = [\n {\n name: \"merge\",\n summary: \"preview on every pull request, update on merge; a wave waits for an approval when its preview deletes or replaces\",\n keys: {},\n },\n {\n name: \"before-merge\",\n summary: \"preview on every pull request, update from a /plywood up comment before merge, once the pull request is approved and mergeable\",\n keys: { apply: { when: \"pull-request\" } },\n },\n {\n name: \"approve-all\",\n summary: \"preview on every pull request, update on merge; every wave that changes something waits for an approval\",\n keys: { gate: \"always\" },\n },\n];\n\nexport function presetByName(name: string): Preset | undefined {\n return PRESETS.find((p) => p.name === name);\n}\n\n/** `--gate` values: plywood.yml's, plus `destroy`, which the pages also use for `on-destructive`. */\nexport function gateFlag(v: string): \"always\" | \"on-destructive\" | \"never\" | undefined {\n if (v === \"destroy\") return \"on-destructive\";\n return v === \"always\" || v === \"on-destructive\" || v === \"never\" ? v : undefined;\n}\n\n/** The check hook a `.pre-commit-config.yaml` turns into (chant `OpWaveHook`). */\nexport function preCommitHook(): { name: string; command: string[] } {\n return { name: \"pre-commit\", command: [\"pre-commit\", \"run\", \"--all-files\", \"--show-diff-on-failure\"] };\n}\n", "/**\n * plywood's init templates, in `packages/plywood/templates/` (shipped in the\n * package). This module sits directly under `src/` so `../templates/`\n * resolves to the same directory from the source (`src/templates.ts`) and\n * from the bundle (`dist/plywood.mjs`).\n *\n * plywood.yml the file init writes; `{{keys}}` takes the keys\n * chant.config.ts.tmpl the chant project beside the stacks\n * agent-prompt.md the paste-in prompt for a coding agent\n */\nimport { readFileSync } from \"node:fs\";\n\nexport type TemplateName = \"plywood.yml\" | \"chant.config.ts.tmpl\" | \"agent-prompt.md\";\n\n/** A template's text. */\nexport function template(name: TemplateName): string {\n return readFileSync(new URL(`../templates/${name}`, import.meta.url), \"utf8\");\n}\n\n/** `text` with each `{{key}}` replaced by its value. */\nexport function fill(text: string, values: Record<string, string>): string {\n return text.replace(/\\{\\{(\\w+)\\}\\}/g, (all, key: string) => (key in values ? values[key]! : all));\n}\n", "/**\n * The files `plywood init` writes besides the workflow, as text or JSON:\n *\n * plywood.yml only the keys detection could not settle\n * chant.workspace.json the member picture: one member of chant's\n * `pulumi` kind per Pulumi.yaml, which\n * `chant workspace graph` and behold read,\n * and the `ci` block plywood.yml sets\n * chant.config.ts the chant project, with the pulumi lexicon\n * plywood.component.ts one chant component per stack, whose\n * `pulumi-up` step previews and updates it\n * .chant/op-waves/pulumi-up.spec.json the waves a merge updates in, read at base\n *\n * Each is a pure function of what init detected and plywood.yml, so a\n * second run gives the same bytes and writes nothing.\n */\nimport { emitYAMLEntry } from \"@intentius/chant/yaml\";\nimport type { ChantCiSettings, ChantGatePolicy, ChantRunner, ChantRunnerSpec } from \"../chant-config\";\nimport type { PolicyPack } from \"../config/policy\";\nimport type { RawConfig } from \"../config/types\";\nimport { fill, template } from \"../templates\";\nimport { OP_NAME, PR_GATE } from \"../words\";\nimport { environmentOf, slug, type DetectedProject } from \"./detect\";\n\n/** One stack as init settles it. */\nexport interface InitStack {\n /** `project/stack`, plywood.yml's key. */\n key: string;\n project: string;\n stack: string;\n dir: string;\n engine?: \"pulumi\" | \"plunge\";\n gate?: ChantGatePolicy;\n /** A release that is not the one on PATH, and where it is installed (chant#4592 `engineVersion`, `engineRoot`). */\n engineVersion?: string;\n engineRoot?: string;\n /** chant's lock grain (chant#4552): `resource`, or `target` for plywood's `stack`. */\n lockGrain?: \"resource\" | \"target\";\n /** CrossGuard packs the stack's preview and update run, relative to its directory (plywood.yml `policy.packs`). */\n policyPacks?: PolicyPack[];\n}\n\n/** plywood.yml's text: the template's header and the keys, in the order given. */\nexport function plywoodYml(keys: RawConfig): string {\n const body = Object.entries(keys)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => emitYAMLEntry(k, v))\n .join(\"\\n\");\n const text = fill(template(\"plywood.yml\"), { keys: body });\n return text.endsWith(\"\\n\") ? text : text + \"\\n\";\n}\n\n/** The chant project's config, from the template. */\nexport function chantConfigTs(): string {\n return template(\"chant.config.ts.tmpl\");\n}\n\n/** A component name chant takes: lowercase letters, digits and `-`. */\nexport function componentName(stack: Pick<InitStack, \"key\">): string {\n return slug(stack.key);\n}\n\n/** A TypeScript identifier for a stack's export. */\nfunction exportName(stack: Pick<InitStack, \"key\">, taken: Set<string>): string {\n let base = stack.key.replace(/[^A-Za-z0-9]+/g, \"_\").replace(/^_+|_+$/g, \"\");\n if (base === \"\" || /^\\d/.test(base)) base = `stack_${base}`;\n let name = base;\n for (let i = 2; taken.has(name); i++) name = `${base}_${i}`;\n taken.add(name);\n return name;\n}\n\n/** The `pulumi-up` step input for a stack (chant pulumi lexicon `PulumiUpStepInput`). */\nexport function stepInput(s: InitStack): Record<string, unknown> {\n return {\n dir: s.dir,\n stack: s.stack,\n member: s.project,\n ...(s.engine ? { engine: s.engine } : {}),\n ...(s.engineVersion ? { engineVersion: s.engineVersion, ...(s.engineRoot ? { engineRoot: s.engineRoot } : {}) } : {}),\n ...(s.lockGrain ? { lockGrain: s.lockGrain } : {}),\n ...(s.policyPacks?.length ? { policyPacks: s.policyPacks } : {}),\n };\n}\n\n/**\n * plywood.component.ts: one chant component per stack, each a plain object\n * (chant discovers any exported component-shaped value in a\n * `*.component.ts` file), so the file imports nothing.\n */\nexport function componentsFile(stacks: readonly InitStack[], after: Readonly<Record<string, readonly string[]>> = {}, opts: { reviewSuffix?: string } = {}): string {\n const taken = new Set<string>();\n const lines = [\n \"// Written by plywood init from the stacks it found; running it again rewrites\",\n \"// this file. Each stack is a chant component whose pulumi-up step previews it\",\n \"// on a pull request and updates it in its wave.\",\n \"\",\n ];\n for (const s of stacks) {\n // plywood.yml's waves.after (plywood#18); chant adds each StackReference itself (chant#4547).\n const dependsOn = (after[s.key] ?? []).filter((u) => stacks.some((x) => x.key === u)).map((u) => componentName({ key: u }));\n // review_stacks.name's suffix (chant#4609): under pr-<n> the step applies <project>/pr-<n>-<suffix>.\n const step = { kind: \"pulumi-up\", ...stepInput(s), ...(opts.reviewSuffix ? { reviewSuffix: opts.reviewSuffix } : {}) };\n const component = { name: componentName(s), dependsOn, deploy: [{ phase: \"up\", steps: [step] }] };\n lines.push(`export const ${exportName(s, taken)} = ${JSON.stringify(component)};`);\n }\n return lines.join(\"\\n\") + \"\\n\";\n}\n\nconst WAVE_NAME = /^[a-z0-9][a-z0-9_-]*$/;\nconst STRICTNESS: Record<ChantGatePolicy, number> = { never: 0, \"on-destructive\": 1, always: 2 };\n\n/** The waves: plywood.yml's `waves`, else one per environment in dev-to-prod order. The first is the canary. */\nexport function wavesOf(stacks: readonly InitStack[], configured?: string[][]): Array<{ name: string; stacks: InitStack[] }> {\n const byKey = new Map(stacks.map((s) => [s.key, s]));\n if (configured && configured.length > 0) {\n return configured.map((keys, i) => ({ name: `wave-${i + 1}`, stacks: keys.map((k) => byKey.get(k)).filter((s): s is InitStack => s !== undefined) }));\n }\n const out: Array<{ name: string; stacks: InitStack[] }> = [];\n for (const s of stacks) {\n const env = environmentOf(s.stack);\n let name = slug(env);\n if (!WAVE_NAME.test(name)) name = `wave-${out.length + 1}`;\n const wave = out.find((w) => w.name === name);\n if (wave) wave.stacks.push(s);\n else out.push({ name, stacks: [s] });\n }\n return out;\n}\n\n/** OpWavesSpec's runner (a label, labels, or a GitHub group) from plywood's `runners`: the `up` stage's, else the default. */\nexport function waveRunner(runner: ChantRunner | undefined): ChantRunnerSpec | undefined {\n if (runner === undefined) return undefined;\n if (typeof runner === \"string\" || Array.isArray(runner) || \"group\" in runner) return runner as ChantRunnerSpec;\n const staged = runner as Partial<Record<string, ChantRunnerSpec>>;\n return staged.up ?? staged.default;\n}\n\nexport interface WavesSpecInput {\n stacks: readonly InitStack[];\n waves?: string[][];\n /** The waves already settled (src/stack-order.ts: canary first, each wave cut by the stacks' order); in place of `waves`. */\n ordered?: ReadonlyArray<{ name: string; stacks: InitStack[] }>;\n gate: ChantGatePolicy;\n branch: string;\n runner?: ChantRunnerSpec;\n quorum?: unknown[];\n /** chant's `NotifyConfig` (plywood.yml `notify`): who hears when a wave waits or fails. */\n notify?: Record<string, unknown>;\n}\n\n/**\n * The waves spec before chant fills its product names (`productWavesSpec`,\n * chant#4550): op `pulumi-up`, a `pulumi-up` step per run through the\n * pulumi lexicon's capability (chant#4541, #4545), and each wave's gate the\n * strictest of its stacks'.\n */\nexport function wavesSpec(input: WavesSpecInput): Record<string, unknown> {\n const waves = (input.ordered ?? wavesOf(input.stacks, input.waves)).filter((w) => w.stacks.length > 0);\n return {\n name: OP_NAME,\n op: OP_NAME,\n gate: PR_GATE,\n branches: [input.branch],\n ...(input.runner !== undefined ? { runner: input.runner } : {}),\n step: { kind: \"pulumi-up\" },\n ...(input.quorum && input.quorum.length > 0 ? { approvals: { quorum: input.quorum } } : {}),\n ...(input.notify ? { notify: input.notify } : {}),\n waves: waves.map((w) => {\n const gate = w.stacks.map((s) => s.gate ?? input.gate).reduce((a, b) => (STRICTNESS[b] > STRICTNESS[a] ? b : a));\n return { name: w.name, gate, runs: w.stacks.map((s) => ({ target: s.key, input: stepInput(s) })) };\n }),\n };\n}\n\n/** JSON as init writes it: two-space indent, a newline at the end. */\nexport function jsonText(v: unknown): string {\n return JSON.stringify(v, null, 2) + \"\\n\";\n}\n\nexport interface DeclarationInput {\n name: string;\n projects: readonly DetectedProject[];\n ci: ChantCiSettings;\n /** The pulumi lexicon's version, pinned like chant itself. */\n lexiconVersion: string;\n}\n\nconst MEMBER_NAME = /^[a-z0-9][a-z0-9-]{0,39}$/;\nexport const PULUMI_LEXICON = \"@intentius/chant-lexicon-pulumi\";\n\n/** A member name for a project, unique among `taken`. */\nfunction memberName(project: DetectedProject, taken: Set<string>): string {\n let base = slug(project.name).slice(0, 36).replace(/-+$/, \"\");\n if (!MEMBER_NAME.test(base)) base = \"stack\";\n let name = base;\n for (let i = 2; taken.has(name); i++) name = `${base}-${i}`;\n taken.add(name);\n return name;\n}\n\n/**\n * The workspace declaration: `existing` (parsed chant.workspace.json) with a\n * `pulumi` member for each project it lacks, the pulumi lexicon's pin, and\n * the `ci` keys plywood.yml sets. Every other key is kept as it is.\n */\nexport function workspaceDeclaration(existing: Record<string, unknown> | undefined, input: DeclarationInput): Record<string, unknown> {\n const doc: Record<string, unknown> = existing ? structuredClone(existing) : { name: input.name, schema: 1 };\n const members = Array.isArray(doc.members) ? (doc.members as Array<Record<string, unknown>>) : [];\n const taken = new Set(members.map((m) => String(m.name)));\n for (const p of input.projects) {\n if (members.some((m) => m.dir === p.dir || (p.dir === \".\" && m.dir === undefined))) continue;\n members.push({ name: memberName(p, taken), dir: p.dir, kind: \"pulumi\" });\n }\n doc.members = members;\n const pins = Array.isArray(doc.pins) ? (doc.pins as Array<Record<string, unknown>>) : [];\n if (!pins.some((p) => p.package === PULUMI_LEXICON)) pins.push({ package: PULUMI_LEXICON, version: input.lexiconVersion });\n doc.pins = pins;\n const ci = doc.ci && typeof doc.ci === \"object\" && !Array.isArray(doc.ci) ? (doc.ci as Record<string, unknown>) : {};\n for (const [k, v] of Object.entries(input.ci)) if (v !== undefined) ci[k] = v;\n if (Object.keys(ci).length > 0) doc.ci = ci;\n return doc;\n}\n\n/** The member a workspace declaration gives the project in `dir`. */\nexport function memberOfDir(doc: Record<string, unknown> | undefined, dir: string): string | undefined {\n const members = doc && Array.isArray(doc.members) ? (doc.members as Array<Record<string, unknown>>) : [];\n const m = members.find((x) => x.dir === dir || (dir === \".\" && x.dir === undefined));\n return typeof m?.name === \"string\" ? m.name : undefined;\n}\n", "/**\n * The order stacks update in on merge (plywood#18). Two things order them:\n *\n * StackReferences read by chant's pulumi lexicon (chant#4547) from each\n * stack's last export: the one the pulumi-up step kept in\n * the index store, else a checked-in stack-export.json.\n * The pull request's previews already follow them, since\n * chant turns each reference into a read between the\n * stacks' components; this module gives the merge's\n * waves the same order.\n * waves.after plywood.yml's hand-written order, for a reference chant\n * cannot see yet (a stack's first update, outputs that are\n * all secret). It also becomes the components' dependsOn.\n *\n * `waves.canary` puts its stacks in a first wave of their own. Each wave is\n * then cut into as many waves as its stacks' order needs, the stack read\n * first. A reference that points at a later wave cannot be met by cutting\n * and is named, as is a reference to a stack this repository does not list.\n *\n * The reader is a feature-detect: a pulumi lexicon without\n * `pulumiStackReferences` gives no edges, and the waves follow\n * `waves.after` alone.\n */\nimport { join } from \"node:path\";\nimport type { InitStack } from \"./init/render\";\n\n/** One stack that updates after another: `reader` reads `upstream`'s outputs, or plywood.yml says so. */\nexport interface StackEdge {\n reader: string;\n upstream: string;\n because: \"stack-reference\" | \"waves.after\";\n}\n\nexport interface StackOrder {\n edges: StackEdge[];\n /** References that add no edge, each with the reason. */\n outside: Array<{ stack: string; reference: string; why: string }>;\n /** True when the installed pulumi lexicon reads StackReferences. */\n reads: boolean;\n}\n\n/** What plywood calls from `@intentius/chant-lexicon-pulumi` (chant#4547) and its `/run` (chant#4546). */\ninterface PulumiReferenceReader {\n pulumiStackReferences(exported: unknown): Array<{ name: string; project?: string; stack: string }>;\n stackReferenceOwner(\n ref: { name: string; project?: string; stack: string },\n reader: { component: string; project: string },\n owners: ReadonlyArray<{ component: string; project: string; stack: string }>,\n ): { owner: { component: string } } | { outside: string };\n memberExportOf?(dir: string, opts?: { stack?: string }): Promise<unknown>;\n readMemberExport?(dir: string): unknown;\n}\n\nlet cached: Promise<PulumiReferenceReader | undefined> | undefined;\n\n/** chant's StackReference reader, or undefined when the installed pulumi lexicon lacks it. */\nexport function chantReferenceReader(): Promise<PulumiReferenceReader | undefined> {\n cached ??= (async () => {\n try {\n const lexicon: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n if (typeof lexicon.pulumiStackReferences !== \"function\" || typeof lexicon.stackReferenceOwner !== \"function\") return undefined;\n let run: Record<string, unknown> = {};\n try {\n run = await import(\"@intentius/chant-lexicon-pulumi/run\");\n } catch {\n // The index store's export needs /run; the checked-in one is read through the lexicon's readMemberExport.\n }\n return {\n pulumiStackReferences: lexicon.pulumiStackReferences as PulumiReferenceReader[\"pulumiStackReferences\"],\n stackReferenceOwner: lexicon.stackReferenceOwner as PulumiReferenceReader[\"stackReferenceOwner\"],\n ...(typeof run.memberExportOf === \"function\" ? { memberExportOf: run.memberExportOf as PulumiReferenceReader[\"memberExportOf\"] } : {}),\n ...(typeof lexicon.readMemberExport === \"function\" ? { readMemberExport: lexicon.readMemberExport as PulumiReferenceReader[\"readMemberExport\"] } : {}),\n };\n } catch {\n return undefined;\n }\n })();\n return cached;\n}\n\n/** Tests stand in a reader (or none). `reset` goes back to the real import. */\nexport function setReferenceReaderForTests(fake: PulumiReferenceReader | undefined | \"reset\"): void {\n cached = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The stack's last export, as chant reads it for the stack's own reads. */\nasync function exportOf(reader: PulumiReferenceReader, root: string, s: Pick<InitStack, \"dir\" | \"stack\">): Promise<unknown> {\n const dir = join(root, s.dir);\n if (reader.memberExportOf) {\n try {\n const found = await reader.memberExportOf(dir, { stack: s.stack });\n if (found !== undefined) return found;\n } catch {\n // No index store reachable from here: the checked-in export below.\n }\n }\n return reader.readMemberExport?.(dir);\n}\n\n/** Every edge between `stacks`: their StackReferences, read from each export, and `after`. */\nexport async function stackOrder(root: string, stacks: readonly InitStack[], after: Readonly<Record<string, readonly string[]>> = {}): Promise<StackOrder> {\n const edges: StackEdge[] = [];\n const outside: StackOrder[\"outside\"] = [];\n const keys = new Set(stacks.map((s) => s.key));\n const add = (e: StackEdge): void => {\n if (!edges.some((x) => x.reader === e.reader && x.upstream === e.upstream)) edges.push(e);\n };\n for (const [reader, ups] of Object.entries(after)) {\n for (const upstream of ups) if (keys.has(reader) && keys.has(upstream)) add({ reader, upstream, because: \"waves.after\" });\n }\n const reader = await chantReferenceReader();\n if (!reader) return { edges, outside, reads: false };\n const owners = stacks.map((s) => ({ component: s.key, project: s.project, stack: s.stack }));\n for (const s of stacks) {\n const exported = await exportOf(reader, root, s);\n if (exported === undefined) continue;\n for (const ref of reader.pulumiStackReferences(exported)) {\n const found = reader.stackReferenceOwner(ref, { component: s.key, project: s.project }, owners);\n if (\"owner\" in found) add({ reader: s.key, upstream: found.owner.component, because: \"stack-reference\" });\n else outside.push({ stack: s.key, reference: ref.name, why: found.outside });\n }\n }\n return { edges, outside, reads: true };\n}\n\nexport interface OrderedWave<S> {\n name: string;\n stacks: S[];\n}\n\n/**\n * The waves with the canary first and each wave cut by `edges`: a stack\n * goes in the first cut after every stack it reads within its wave. Returns\n * the waves and the edges no cut can meet (the stack read updates in a\n * later wave, or the stacks read each other).\n */\nexport function orderWaves<S extends { key: string }>(\n waves: ReadonlyArray<OrderedWave<S>>,\n edges: readonly StackEdge[],\n canary: readonly string[] = [],\n): { waves: OrderedWave<S>[]; unmet: Array<StackEdge & { why: string }> } {\n const unmet: Array<StackEdge & { why: string }> = [];\n const firsts = canary.length ? waves.flatMap((w) => w.stacks.filter((s) => canary.includes(s.key))) : [];\n const rest = waves.map((w) => ({ name: w.name, stacks: w.stacks.filter((s) => !canary.includes(s.key)) })).filter((w) => w.stacks.length > 0);\n const listed: OrderedWave<S>[] = [...(firsts.length ? [{ name: \"canary\", stacks: firsts }] : []), ...rest];\n\n const waveOf = new Map<string, number>();\n listed.forEach((w, i) => w.stacks.forEach((s) => waveOf.set(s.key, i)));\n for (const e of edges) {\n const r = waveOf.get(e.reader);\n const u = waveOf.get(e.upstream);\n if (r !== undefined && u !== undefined && u > r) unmet.push({ ...e, why: `${e.upstream} updates in ${listed[u]!.name}, after ${e.reader}'s wave ${listed[r]!.name}` });\n }\n\n const out: OrderedWave<S>[] = [];\n for (const w of listed) {\n const inWave = new Set(w.stacks.map((s) => s.key));\n const ups = new Map<string, string[]>(w.stacks.map((s) => [s.key, edges.filter((e) => e.reader === s.key && inWave.has(e.upstream)).map((e) => e.upstream)]));\n const layer = new Map<string, number>();\n const open = new Set<string>();\n const depth = (k: string): number => {\n const known = layer.get(k);\n if (known !== undefined) return known;\n if (open.has(k)) return 0;\n open.add(k);\n let d = 0;\n for (const u of ups.get(k) ?? []) {\n if (open.has(u)) {\n const e = edges.find((x) => x.reader === k && x.upstream === u)!;\n unmet.push({ ...e, why: `${k} and ${u} read each other` });\n continue;\n }\n d = Math.max(d, depth(u) + 1);\n }\n open.delete(k);\n layer.set(k, d);\n return d;\n };\n for (const s of w.stacks) depth(s.key);\n const count = Math.max(0, ...layer.values()) + 1;\n for (let i = 0; i < count; i++) {\n const stacks = w.stacks.filter((s) => layer.get(s.key) === i);\n if (stacks.length) out.push({ name: i === 0 ? w.name : `${w.name}-${i + 1}`, stacks });\n }\n }\n return { waves: out, unmet };\n}\n\n/** The lines init prints for the order: each edge that cut a wave, each reference left out, each edge unmet. */\nexport function orderLines(order: StackOrder, unmet: ReadonlyArray<StackEdge & { why: string }>): string[] {\n const out: string[] = [];\n if (!order.reads) out.push(\"the installed @intentius/chant-lexicon-pulumi reads no StackReferences (chant#4547), so the waves follow waves.after alone\");\n for (const e of order.edges) out.push(`${e.reader} updates after ${e.upstream} (${e.because === \"stack-reference\" ? \"its StackReference\" : \"waves.after\"})`);\n for (const o of order.outside) out.push(`${o.stack}'s StackReference ${o.reference} orders nothing: ${o.why}`);\n for (const u of unmet) out.push(`${u.reader} should update after ${u.upstream}, and cannot: ${u.why}; list them in one wave, or reorder waves`);\n return out;\n}\n", "/**\n * What each importer gives `plywood init --from` (plywood#21): plywood.yml\n * keys, and every setting of the source it could not carry, by name.\n * Importers read files in the repository and nothing else: no API call,\n * no engine, no git.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join, posix } from \"node:path\";\nimport { parseYAML } from \"@intentius/chant/yaml\";\nimport type { Detected, DetectedProject } from \"../init/detect\";\nimport { isObject, type RawConfig } from \"../config/types\";\n\nexport const IMPORT_SOURCES = [\"pulumi-actions\", \"deployments\", \"spacelift\", \"env0\"] as const;\nexport type ImportSource = (typeof IMPORT_SOURCES)[number];\n\n/** One setting the importer could not carry. */\nexport interface Unsupported {\n /** The file it is in, relative to the repository root. */\n file: string;\n /** The setting's name as the source spells it (`refresh`, `operationContext.preRunCommands`). */\n setting: string;\n /** Why, and what to do instead. */\n why: string;\n}\n\nexport interface ImportResult {\n source: ImportSource;\n /** The files read, relative to the repository root. */\n files: string[];\n /** plywood.yml keys. `stacks` holds only what the source says beyond init's own detection. */\n keys: RawConfig;\n unsupported: Unsupported[];\n /** What carried over without a key, or needs a person (secrets to copy). */\n notes: string[];\n}\n\n/** An importer: the repository, what init detected, and the files `--from` named (empty: the source's usual places). */\nexport type Importer = (root: string, detected: Detected, files: readonly string[]) => ImportResult;\n\n/** A YAML or JSON file in the repository, parsed. */\nexport function readDoc(root: string, file: string): unknown {\n return parseYAML(readFileSync(join(root, file), \"utf8\"));\n}\n\n/** The first of `names` present under `root`. */\nexport function firstPresent(root: string, names: readonly string[]): string | undefined {\n return names.find((n) => existsSync(join(root, n)));\n}\n\n/** A path joined and normalized as plywood.yml spells paths (`.` for the root). */\nexport function repoJoin(...parts: string[]): string {\n const out = posix.normalize(parts.filter((p) => p !== \"\" && p !== \".\").join(\"/\") || \".\").replace(/^\\.\\//, \"\").replace(/\\/+$/, \"\");\n return out === \"\" ? \".\" : out;\n}\n\n/** The project whose directory is `dir`. */\nexport function projectAt(detected: Detected, dir: string): DetectedProject | undefined {\n const want = repoJoin(dir);\n return detected.projects.find((p) => repoJoin(p.dir) === want);\n}\n\n/** A stack's plywood.yml settings, made on first use. */\nexport function stackEntry(keys: RawConfig, key: string): Record<string, unknown> {\n const stacks = (isObject(keys.stacks) ? keys.stacks : (keys.stacks = {})) as Record<string, Record<string, unknown>>;\n return (stacks[key] ??= {});\n}\n\n/** Adds stacks to `branches.<branch>`, without repeats. */\nexport function addBranch(keys: RawConfig, branch: string, stack: string): void {\n const branches = (isObject(keys.branches) ? keys.branches : (keys.branches = {})) as Record<string, string[]>;\n const list = (branches[branch] ??= []);\n if (!list.includes(stack)) list.push(stack);\n}\n\n/** A git ref as a branch name: `refs/heads/main` is `main`. */\nexport function branchOf(ref: string): string {\n return ref.replace(/^refs\\/heads\\//, \"\");\n}\n\n/** Each key of `v` outside `known` as an unsupported setting under `prefix`. */\nexport function unknownSettings(v: Record<string, unknown>, known: readonly string[], file: string, prefix: string, why: string): Unsupported[] {\n return Object.keys(v)\n .filter((k) => !known.includes(k))\n .map((k) => ({ file, setting: prefix ? `${prefix}.${k}` : k, why }));\n}\n\n/** Lays one importer's keys over another's: mappings merge, the rest is replaced. */\nexport function mergeKeys(base: RawConfig, over: RawConfig): RawConfig {\n const out: RawConfig = structuredClone(base);\n for (const [k, v] of Object.entries(over)) {\n out[k] = isObject(v) && isObject(out[k]) ? mergeKeys(out[k] as RawConfig, v) : structuredClone(v);\n }\n return out;\n}\n\n/** The lines init prints for an import. */\nexport function importLines(r: ImportResult): string[] {\n const out = [`--from ${r.source}: read ${r.files.length ? r.files.join(\", \") : \"no file\"}`];\n for (const n of r.notes) out.push(` ${n}`);\n if (r.unsupported.length) out.push(` ${r.unsupported.length} setting${r.unsupported.length === 1 ? \"\" : \"s\"} not carried:`);\n for (const u of r.unsupported) out.push(` ${u.file}: ${u.setting}: ${u.why}`);\n return out;\n}\n", "/**\n * `plywood init --from deployments`: Pulumi Deployments settings the user\n * exported, read from the repository. No API call is made. The file is\n * `Pulumi.<stack>.deploy.yaml` beside the project's Pulumi.yaml (as\n * `pulumi deployment settings pull` writes it, under `settings:`), or the\n * same name with `.json` for the REST API's response body; `--from\n * deployments=<file>` names one.\n *\n * sourceContext.git.repoDir stacks.<key>.dir\n * sourceContext.git.branch branches.<branch>\n * gitHub.paths stacks.<key>.paths\n * gitHub.previewPullRequests plywood previews every pull request\n * gitHub.deployCommits plywood updates on merge\n * gitHub.pullRequestTemplate review_stacks.template\n * operationContext.oidc listed with the identity it names, for\n * identity.stacks.<key>.up: plywood needs a\n * preview identity beside it\n * executorContext.executorImage image\n *\n * Pre-run commands, environment variables, options, cache and agent pool\n * settings are listed as not carried, each by name.\n */\nimport { readdirSync } from \"node:fs\";\nimport { basename, dirname, join } from \"node:path\";\nimport { isObject, type RawConfig } from \"../config/types\";\nimport { posixRel, type Detected } from \"../init/detect\";\nimport { addBranch, branchOf, mergeKeys, projectAt, readDoc, repoJoin, stackEntry, unknownSettings, type Importer, type Unsupported } from \"./types\";\n\nconst SETTINGS_FILE = /^Pulumi\\.([^.]+)\\.deploy\\.(?:ya?ml|json)$/;\n\n/** The settings files: those named, else each `Pulumi.<stack>.deploy.*` in a project's directory. */\nexport function deploymentFiles(root: string, detected: Detected, named: readonly string[]): string[] {\n if (named.length) return [...named];\n const out: string[] = [];\n for (const p of detected.projects) {\n let names: string[];\n try {\n names = readdirSync(join(root, p.dir)).sort();\n } catch {\n continue;\n }\n for (const n of names) if (SETTINGS_FILE.test(n)) out.push(repoJoin(p.dir, n));\n }\n return out;\n}\n\nconst NOT_CARRIED: Readonly<Record<string, string>> = {\n \"operationContext.preRunCommands\": \"put each command in the stack's program or the job's image\",\n \"operationContext.environmentVariables\": \"set each one as a forge variable or secret\",\n \"operationContext.options\": \"plywood runs the stack's program as Pulumi does, through chant\",\n cacheOptions: \"the jobs install with the image's tools; cache with your forge's cache\",\n agentPoolID: \"set runners in plywood.yml for self-hosted runners\",\n \"sourceContext.git.gitAuth\": \"the jobs check out the repository with the forge's own token\",\n \"sourceContext.git.commit\": \"plywood previews each pull request's commit\",\n \"gitHub.deployPullRequest\": \"set apply.when: pull-request and update with /plywood up\",\n \"gitHub.repository\": \"plywood runs in the repository it is set up in\",\n};\n\nexport const importDeployments: Importer = (root, detected, named) => {\n let keys: RawConfig = {};\n const unsupported: Unsupported[] = [];\n const notes: string[] = [];\n const files: string[] = [];\n const not = (file: string, setting: string, why?: string): void => {\n unsupported.push({ file, setting, why: why ?? NOT_CARRIED[setting] ?? \"plywood has no setting for it\" });\n };\n for (const file of deploymentFiles(root, detected, named)) {\n const m = SETTINGS_FILE.exec(basename(file));\n if (!m) {\n not(file, \"(file)\", \"names no stack: call it Pulumi.<stack>.deploy.yaml (or .json) beside the project's Pulumi.yaml\");\n continue;\n }\n let doc: unknown;\n try {\n doc = readDoc(root, file);\n } catch (e) {\n not(file, \"(file)\", `does not read: ${(e as Error).message}`);\n continue;\n }\n const settings = isObject(doc) && isObject(doc.settings) ? doc.settings : isObject(doc) ? doc : undefined;\n if (!settings) continue;\n files.push(file);\n const fileDir = repoJoin(posixRel(root, dirname(join(root, file))));\n const source = isObject(settings.sourceContext) && isObject(settings.sourceContext.git) ? settings.sourceContext.git : {};\n const dir = typeof source.repoDir === \"string\" ? repoJoin(source.repoDir) : fileDir;\n const project = projectAt(detected, dir)?.name ?? projectAt(detected, fileDir)?.name;\n if (!project) {\n not(file, \"sourceContext.git.repoDir\", `${dir} holds no Pulumi.yaml`);\n continue;\n }\n const key = `${project}/${m[1]}`;\n const entry = stackEntry(keys, key);\n if (dir !== \".\") entry.dir = dir;\n if (typeof source.branch === \"string\") addBranch(keys, branchOf(source.branch), key);\n for (const k of Object.keys(source).filter((x) => ![\"repoDir\", \"branch\", \"repoURL\", \"repoUrl\"].includes(x))) not(file, `sourceContext.git.${k}`);\n\n const gh = isObject(settings.gitHub) ? settings.gitHub : {};\n const included = Array.isArray(gh.paths) ? gh.paths.map(String).filter((p) => !p.startsWith(\"!\")) : [];\n if (included.length) entry.paths = included;\n if (Array.isArray(gh.paths) && gh.paths.some((p) => String(p).startsWith(\"!\"))) not(file, \"gitHub.paths\", \"an exclusion (!path) has no plywood form; list only the paths that preview the stack\");\n if (gh.previewPullRequests === false) not(file, \"gitHub.previewPullRequests\", \"plywood previews every pull request that touches the stack; leave the stack out of plywood.yml to skip it\");\n if (gh.deployCommits === false) not(file, \"gitHub.deployCommits\", \"plywood updates the stack on merge; set gate: always to hold each update for an approval\");\n if (gh.pullRequestTemplate === true) keys = mergeKeys(keys, { review_stacks: { template: key } });\n for (const k of Object.keys(gh).filter((x) => ![\"paths\", \"previewPullRequests\", \"deployCommits\", \"pullRequestTemplate\"].includes(x))) not(file, `gitHub.${k}`);\n\n const op = isObject(settings.operationContext) ? settings.operationContext : {};\n if (Array.isArray(op.preRunCommands) && op.preRunCommands.length) not(file, \"operationContext.preRunCommands\");\n if (isObject(op.environmentVariables) && Object.keys(op.environmentVariables).length) {\n not(file, \"operationContext.environmentVariables\", `${NOT_CARRIED[\"operationContext.environmentVariables\"]}: ${Object.keys(op.environmentVariables).sort().join(\", \")}`);\n }\n if (isObject(op.options) && Object.keys(op.options).length) for (const k of Object.keys(op.options)) not(file, `operationContext.options.${k}`, NOT_CARRIED[\"operationContext.options\"]);\n if (isObject(op.oidc)) {\n // Deployments runs with one identity; plywood needs a preview identity beside it, so the key is left for a person to finish.\n const ids: Array<[string, string, unknown]> = [\n [\"aws\", \"roleArn\", isObject(op.oidc.aws) ? op.oidc.aws.roleArn : undefined],\n [\"gcp\", \"serviceAccount\", isObject(op.oidc.gcp) ? op.oidc.gcp.serviceAccount : undefined],\n [\"azure\", \"clientId\", isObject(op.oidc.azure) ? op.oidc.azure.clientId : undefined],\n ];\n for (const [cloud, field, id] of ids) {\n if (!isObject(op.oidc[cloud])) continue;\n not(\n file,\n `operationContext.oidc.${cloud}`,\n typeof id === \"string\"\n ? `Deployments runs both stages as ${id}; set identity.stacks.${key}.up.${cloud}: ${id} beside a preview identity of its own, and identity.${cloud}'s settings`\n : `has no ${field}; set identity.stacks.${key} by hand`,\n );\n }\n for (const cloud of Object.keys(op.oidc).filter((c) => ![\"aws\", \"gcp\", \"azure\"].includes(c))) not(file, `operationContext.oidc.${cloud}`);\n }\n for (const k of Object.keys(op).filter((x) => ![\"preRunCommands\", \"environmentVariables\", \"options\", \"oidc\"].includes(x))) not(file, `operationContext.${k}`);\n\n const exec = isObject(settings.executorContext) ? settings.executorContext : {};\n if (typeof exec.executorImage === \"string\") keys.image = exec.executorImage;\n else if (isObject(exec.executorImage) && typeof exec.executorImage.reference === \"string\") keys.image = exec.executorImage.reference;\n unsupported.push(...unknownSettings(settings, [\"sourceContext\", \"gitHub\", \"operationContext\", \"executorContext\", \"cacheOptions\", \"agentPoolID\", \"version\", \"source\"], file, \"\", \"plywood has no setting for it\"));\n if (isObject(settings.cacheOptions) && settings.cacheOptions.enable === true) not(file, \"cacheOptions\");\n if (typeof settings.agentPoolID === \"string\" && settings.agentPoolID) not(file, \"agentPoolID\");\n }\n if (files.length) notes.push(\"turn off each stack's Deployments triggers once plywood runs it, so a push starts one update\");\n return { source: \"deployments\", files, keys, unsupported, notes };\n};\n", "/**\n * `plywood init --from env0`: env0's files in the repository.\n *\n * env0.workflow.yml a workflow's environments and their `needs`: each\n * environment whose name, or `templateName`, matches a\n * stack (its `project/stack`, stack or project name)\n * is that stack, and `needs` becomes waves.after\n * env0.yml custom flow hooks (`deploy.steps.<step>.before` and\n * `after`, the same under `destroy`): listed as not\n * carried, each by step\n *\n * Templates, environment variables and approval policies live in env0\n * itself, so they are not here to read.\n */\nimport { isObject, type RawConfig } from \"../config/types\";\nimport type { Detected } from \"../init/detect\";\nimport { firstPresent, readDoc, type Importer, type Unsupported } from \"./types\";\n\nexport const ENV0_WORKFLOW_FILES = [\"env0.workflow.yml\", \"env0.workflow.yaml\"];\nexport const ENV0_FLOW_FILES = [\"env0.yml\", \"env0.yaml\"];\n\n/** The stack an env0 environment names, if exactly one matches. */\nfunction stackFor(detected: Detected, names: readonly string[]): string | undefined {\n for (const n of names) {\n const hits = detected.stacks.filter((s) => s.key === n || s.stack === n || (detected.stacks.filter((x) => x.project === s.project).length === 1 && s.project === n));\n if (hits.length === 1) return hits[0]!.key;\n }\n return undefined;\n}\n\nexport const importEnv0: Importer = (root, detected, named) => {\n const keys: RawConfig = {};\n const unsupported: Unsupported[] = [];\n const notes: string[] = [];\n const files: string[] = [];\n const pick = (choices: readonly string[]): string | undefined => named.find((f) => choices.some((c) => f.endsWith(c))) ?? (named.length ? undefined : firstPresent(root, choices));\n for (const f of named.filter((x) => ![...ENV0_WORKFLOW_FILES, ...ENV0_FLOW_FILES].some((c) => x.endsWith(c)))) {\n unsupported.push({ file: f, setting: \"(file)\", why: `is neither ${ENV0_WORKFLOW_FILES[0]} nor ${ENV0_FLOW_FILES[0]}` });\n }\n\n const workflow = pick(ENV0_WORKFLOW_FILES);\n if (workflow) {\n files.push(workflow);\n const doc = readDoc(root, workflow);\n const envs = isObject(doc) && isObject(doc.environments) ? doc.environments : {};\n const stackOf = new Map<string, string>();\n for (const [id, raw] of Object.entries(envs)) {\n const e = isObject(raw) ? raw : {};\n const names = [id, ...(typeof e.name === \"string\" ? [e.name] : []), ...(typeof e.templateName === \"string\" ? [e.templateName] : [])];\n const key = stackFor(detected, names);\n if (key) stackOf.set(id, key);\n else unsupported.push({ file: workflow, setting: `environments.${id}`, why: `names no stack of this repository (${names.join(\", \")}); list it under stacks and waves.after by hand` });\n for (const k of Object.keys(e).filter((x) => ![\"name\", \"templateName\", \"needs\"].includes(x))) {\n unsupported.push({ file: workflow, setting: `environments.${id}.${k}`, why: \"plywood has no setting for it\" });\n }\n }\n const after: Record<string, string[]> = {};\n for (const [id, raw] of Object.entries(envs)) {\n const reader = stackOf.get(id);\n const needs = isObject(raw) && Array.isArray(raw.needs) ? raw.needs.map(String) : [];\n if (!reader) continue;\n for (const n of needs) {\n const up = stackOf.get(n);\n if (up) (after[reader] ??= []).push(up);\n else unsupported.push({ file: workflow, setting: `environments.${id}.needs`, why: `${n} names no stack of this repository` });\n }\n }\n if (Object.keys(after).length) keys.waves = { after };\n for (const k of Object.keys(isObject(doc) ? doc : {}).filter((x) => x !== \"environments\")) {\n unsupported.push({ file: workflow, setting: k, why: \"plywood has no setting for it\" });\n }\n }\n\n const flow = pick(ENV0_FLOW_FILES);\n if (flow) {\n files.push(flow);\n const doc = readDoc(root, flow);\n for (const phase of [\"deploy\", \"destroy\"]) {\n const steps = isObject(doc) && isObject(doc[phase]) && isObject((doc[phase] as Record<string, unknown>).steps) ? ((doc[phase] as Record<string, unknown>).steps as Record<string, unknown>) : {};\n for (const [step, hooks] of Object.entries(steps)) {\n for (const when of Object.keys(isObject(hooks) ? hooks : {})) {\n unsupported.push({ file: flow, setting: `${phase}.steps.${step}.${when}`, why: \"plywood runs no hook around chant's stages; put the commands in the job's image or the stack's program\" });\n }\n }\n }\n for (const k of Object.keys(isObject(doc) ? doc : {}).filter((x) => ![\"version\", \"deploy\", \"destroy\"].includes(x))) {\n unsupported.push({ file: flow, setting: k, why: \"plywood has no setting for it\" });\n }\n }\n if (!files.length) notes.push(`no ${ENV0_WORKFLOW_FILES[0]} or ${ENV0_FLOW_FILES[0]} in the repository`);\n else notes.push(\"templates, variables and approval policies are env0 settings outside the repository; set stacks, gate and approval_rules in plywood.yml\");\n return { source: \"env0\", files, keys, unsupported, notes };\n};\n", "/**\n * `plywood init --from pulumi-actions`: GitHub Actions workflows that use\n * `pulumi/actions`. Each step's inputs, as the action names them:\n *\n * stack-name the stack, `org/stack` or `stack`; the project comes from\n * the Pulumi.yaml in work-dir, the org goes to pulumi_cloud.org\n * work-dir stacks.<key>.dir\n * command preview: the pull request's preview, as plywood does;\n * up on a push: branches.<branch>; up on a pull request:\n * apply.when pull-request\n * comment-on-pr plywood posts one note per pull request already\n * policyPacks policy.packs, relative to the repository root, with\n * policyPackConfigs paired in order\n * cloud-url stacks.<key>.backend, unless it is Pulumi Cloud's own\n * pulumi-version pulumi, when it is one release\n *\n * `refresh`, `target` and every other input are listed as not carried.\n */\nimport { readdirSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { isObject, type RawConfig } from \"../config/types\";\nimport type { Detected } from \"../init/detect\";\nimport { addBranch, mergeKeys, projectAt, readDoc, repoJoin, stackEntry, type Importer, type Unsupported } from \"./types\";\n\nexport const WORKFLOW_DIRS = [\".github/workflows\", \".forgejo/workflows\", \".gitea/workflows\"];\nconst CARRIED = [\"stack-name\", \"work-dir\", \"command\", \"comment-on-pr\", \"policyPacks\", \"policyPackConfigs\", \"cloud-url\", \"pulumi-version\", \"github-token\", \"edit-pr-comment\", \"always-include-summary\"];\nconst WHY: Readonly<Record<string, string>> = {\n refresh: \"plywood previews against the stack's state as it is; run plywood drift on a schedule to catch changes made outside it\",\n target: \"plywood previews and updates whole stacks; narrow a pull request with labels\",\n \"target-dependents\": \"plywood previews and updates whole stacks\",\n \"config-map\": \"keep the config in Pulumi.<stack>.yaml, which plywood reads at the pull request's commit\",\n upsert: \"plywood updates stacks that exist; create a stack with pulumi stack init before plywood init\",\n \"expect-no-changes\": \"a drift check (drift.schedule) reports changes rather than failing a job\",\n \"secrets-provider\": \"set secretsprovider in Pulumi.<stack>.yaml\",\n diff: \"the note shows each change already\",\n plan: \"plywood's update applies the preview its approval names, through chant\",\n};\n\n/** The pulumi/actions workflow files: those `--from` named, else every one in the forge workflow directories. */\nexport function pulumiActionsFiles(root: string, named: readonly string[]): string[] {\n if (named.length) return [...named];\n const out: string[] = [];\n for (const d of WORKFLOW_DIRS) {\n let names: string[];\n try {\n names = readdirSync(join(root, d)).sort();\n } catch {\n continue;\n }\n for (const n of names) if (/\\.ya?ml$/.test(n)) out.push(`${d}/${n}`);\n }\n return out;\n}\n\n/** The workflow's triggers: `on` as written, or as a YAML 1.1 reader keys it. */\nfunction triggers(doc: Record<string, unknown>): { pullRequest: boolean; pushBranches: string[] } {\n const on = doc.on ?? doc[\"true\"];\n const names = typeof on === \"string\" ? [on] : Array.isArray(on) ? on.map(String) : isObject(on) ? Object.keys(on) : [];\n const push = isObject(on) && isObject(on.push) ? on.push : undefined;\n const branches = push && Array.isArray(push.branches) ? push.branches.map(String) : names.includes(\"push\") ? [\"main\"] : [];\n return { pullRequest: names.includes(\"pull_request\") || names.includes(\"pull_request_target\"), pushBranches: branches };\n}\n\n/** A multi-line action input as its lines. */\nfunction lines(v: unknown): string[] {\n if (Array.isArray(v)) return v.map(String).filter(Boolean);\n return typeof v === \"string\" ? v.split(/\\r?\\n/).map((s) => s.trim()).filter(Boolean) : [];\n}\n\nconst PULUMI_CLOUD = /^https:\\/\\/(?:app|api)\\.pulumi\\.com\\/?$/;\n\nexport const importPulumiActions: Importer = (root, detected: Detected, named) => {\n let keys: RawConfig = {};\n const unsupported: Unsupported[] = [];\n const notes: string[] = [];\n const files: string[] = [];\n const secrets = new Set<string>();\n for (const file of pulumiActionsFiles(root, named)) {\n let doc: unknown;\n try {\n doc = readDoc(root, file);\n } catch (e) {\n unsupported.push({ file, setting: \"(file)\", why: `does not read as YAML: ${(e as Error).message}` });\n continue;\n }\n if (!isObject(doc) || !isObject(doc.jobs)) continue;\n const on = triggers(doc);\n let used = false;\n for (const [jobName, job] of Object.entries(doc.jobs)) {\n if (!isObject(job) || !Array.isArray(job.steps)) continue;\n // A job's `if` on the event narrows the workflow's triggers to its own.\n const cond = typeof job.if === \"string\" ? job.if : \"\";\n const jobOn = /event_name\\s*==\\s*'push'|\"push\"/.test(cond)\n ? { pullRequest: false, pushBranches: on.pushBranches }\n : /event_name\\s*==\\s*'pull_request/.test(cond)\n ? { pullRequest: on.pullRequest, pushBranches: [] }\n : on;\n job.steps.forEach((step, i) => {\n if (!isObject(step) || typeof step.uses !== \"string\" || !/^pulumi\\/actions@/.test(step.uses)) return;\n used = true;\n const where = `jobs.${jobName}.steps[${i}]`;\n const w = isObject(step.with) ? step.with : {};\n for (const m of JSON.stringify(step.env ?? {}).matchAll(/secrets\\.([A-Za-z_][A-Za-z0-9_]*)/g)) secrets.add(m[1]!);\n for (const m of JSON.stringify(job.env ?? {}).matchAll(/secrets\\.([A-Za-z_][A-Za-z0-9_]*)/g)) secrets.add(m[1]!);\n const stackName = typeof w[\"stack-name\"] === \"string\" ? w[\"stack-name\"] : undefined;\n if (!stackName) {\n unsupported.push({ file, setting: `${where}.with.stack-name`, why: \"is missing or an expression; list the stack under stacks in plywood.yml\" });\n return;\n }\n const dir = repoJoin(typeof w[\"work-dir\"] === \"string\" ? w[\"work-dir\"] : \".\");\n const parts = stackName.split(\"/\");\n const stack = parts[parts.length - 1]!;\n const project = projectAt(detected, dir)?.name ?? (parts.length === 3 ? parts[1]! : undefined);\n if (!project) {\n unsupported.push({ file, setting: `${where}.with.stack-name`, why: `${dir} holds no Pulumi.yaml, so ${stackName} names no project` });\n return;\n }\n const key = `${project}/${stack}`;\n const entry = stackEntry(keys, key);\n if (dir !== \".\") entry.dir = dir;\n // pulumi/actions reads org/stack and org/project/stack.\n if (parts.length === 2 || parts.length === 3) keys = mergeKeys(keys, { pulumi_cloud: { org: parts[0] } });\n\n const command = typeof w.command === \"string\" ? w.command : \"\";\n if (command === \"up\" || command === \"update\") {\n if (jobOn.pullRequest) keys = mergeKeys(keys, { apply: { when: \"pull-request\" } });\n for (const b of jobOn.pushBranches) addBranch(keys, b, key);\n if (!jobOn.pullRequest && jobOn.pushBranches.length === 0) unsupported.push({ file, setting: `${where}.with.command`, why: \"up runs on a trigger other than a push or a pull request; plywood updates on merge\" });\n } else if (command !== \"preview\") {\n unsupported.push({ file, setting: `${where}.with.command`, why: `${command || \"(none)\"} is not preview or up; plywood runs those two, and plywood drift for refresh` });\n }\n\n const packs = lines(w.policyPacks);\n const configs = lines(w.policyPackConfigs);\n if (packs.length) {\n const listed = packs.map((p, n) => (configs[n] ? { dir: repoJoin(dir, p), config: repoJoin(dir, configs[n]!) } : repoJoin(dir, p)));\n const have = (isObject(keys.policy) && Array.isArray(keys.policy.packs) ? keys.policy.packs : []) as unknown[];\n keys = mergeKeys(keys, { policy: { packs: [...have, ...listed.filter((p) => !have.some((h) => JSON.stringify(h) === JSON.stringify(p)))] } });\n }\n const cloud = typeof w[\"cloud-url\"] === \"string\" ? w[\"cloud-url\"] : undefined;\n if (cloud && !PULUMI_CLOUD.test(cloud)) {\n if (/^https:\\/\\//.test(cloud)) keys = mergeKeys(keys, { pulumi_cloud: { api_url: cloud } });\n else entry.backend = cloud;\n }\n const version = typeof w[\"pulumi-version\"] === \"string\" ? w[\"pulumi-version\"].replace(/^v/, \"\") : undefined;\n if (version) {\n if (/^\\d+\\.\\d+\\.\\d+$/.test(version)) keys.pulumi = version;\n else unsupported.push({ file, setting: `${where}.with.pulumi-version`, why: `${version} is a range; plywood pins one release, so set pulumi: <x.y.z>` });\n }\n for (const input of Object.keys(w).filter((k) => !CARRIED.includes(k))) {\n unsupported.push({ file, setting: `${where}.with.${input}`, why: WHY[input] ?? \"plywood has no setting for it\" });\n }\n });\n }\n if (used) files.push(file);\n }\n if (files.length && secrets.size) notes.push(`the workflow reads the secrets ${[...secrets].sort().join(\", \")}; plywood's jobs read them under the same names`);\n if (files.length) notes.push(\"comment-on-pr carries over: plywood posts one note per pull request\");\n return { source: \"pulumi-actions\", files, keys, unsupported, notes };\n};\n", "/**\n * `plywood init --from spacelift`: `.spacelift/config.yml` (version 1),\n * the stack settings Spacelift reads from the repository. A stack's branch,\n * autodeploy and policies live in Spacelift itself, so they are not here to\n * read. Each stack, with `stack_defaults` laid under it:\n *\n * project_root stacks.<key>.dir; the project is the Pulumi.yaml's name\n * there, and the stack is the Spacelift stack's id when a\n * Pulumi.<id>.yaml is beside it, else that directory's one stack\n * runner_image image\n *\n * `environment`, the `before_*` and `after_*` hooks and every other key are\n * listed as not carried, by name.\n */\nimport { isObject, type RawConfig } from \"../config/types\";\nimport { firstPresent, projectAt, readDoc, repoJoin, stackEntry, type Importer, type Unsupported } from \"./types\";\n\nexport const SPACELIFT_FILES = [\".spacelift/config.yml\", \".spacelift/config.yaml\"];\nconst CARRIED = [\"project_root\", \"runner_image\"];\n\nexport const importSpacelift: Importer = (root, detected, named) => {\n const keys: RawConfig = {};\n const unsupported: Unsupported[] = [];\n const notes: string[] = [];\n const file = named[0] ?? firstPresent(root, SPACELIFT_FILES);\n if (!file) return { source: \"spacelift\", files: [], keys, unsupported, notes: [`no ${SPACELIFT_FILES[0]} in the repository`] };\n for (const extra of named.slice(1)) unsupported.push({ file: extra, setting: \"(file)\", why: \"Spacelift reads one config file; this one was not read\" });\n const doc = readDoc(root, file);\n if (!isObject(doc)) return { source: \"spacelift\", files: [file], keys, unsupported: [{ file, setting: \"(file)\", why: \"is not a mapping\" }], notes };\n const defaults = isObject(doc.stack_defaults) ? doc.stack_defaults : {};\n const stacks = isObject(doc.stacks) ? doc.stacks : {};\n for (const k of Object.keys(doc).filter((x) => ![\"version\", \"stack_defaults\", \"stacks\"].includes(x))) {\n unsupported.push({ file, setting: k, why: k === \"module_version\" || k === \"tests\" ? \"Spacelift module settings; plywood runs stacks\" : \"plywood has no setting for it\" });\n }\n const images = new Set<string>();\n const listOthers = (s: Record<string, unknown>, prefix: string): void => {\n for (const [k, v] of Object.entries(s)) {\n if (CARRIED.includes(k)) continue;\n const why =\n k === \"environment\"\n ? `set each one as a forge variable or secret: ${isObject(v) ? Object.keys(v).sort().join(\", \") : \"(none)\"}`\n : /^(before|after)_/.test(k)\n ? \"plywood runs no hook around chant's stages; put the commands in the job's image or the stack's program\"\n : \"plywood has no setting for it\";\n unsupported.push({ file, setting: `${prefix}.${k}`, why });\n }\n };\n listOthers(defaults, \"stack_defaults\");\n for (const [id, raw] of Object.entries(stacks)) {\n const own = isObject(raw) ? raw : {};\n const s = { ...defaults, ...own };\n const dir = repoJoin(typeof s.project_root === \"string\" ? s.project_root : \".\");\n const project = projectAt(detected, dir);\n if (!project) {\n unsupported.push({ file, setting: `stacks.${id}.project_root`, why: `${dir} holds no Pulumi.yaml` });\n continue;\n }\n let stack = id;\n if (!project.stacks.includes(id)) {\n if (project.stacks.length === 1) {\n stack = project.stacks[0]!;\n notes.push(`Spacelift stack ${id} is ${project.name}/${stack}, the one stack in ${dir}`);\n } else notes.push(`Spacelift stack ${id} has no Pulumi.${id}.yaml in ${dir}; it is listed as ${project.name}/${id}, so run pulumi stack init ${id} there or rename it in plywood.yml`);\n }\n const key = `${project.name}/${stack}`;\n const entry = stackEntry(keys, key);\n if (dir !== \".\") entry.dir = dir;\n if (typeof s.runner_image === \"string\") images.add(s.runner_image);\n listOthers(own, `stacks.${id}`);\n }\n if (images.size === 1) keys.image = [...images][0];\n else if (images.size > 1) unsupported.push({ file, setting: \"runner_image\", why: `the stacks run in ${images.size} images; plywood runs every job in one, so set image to the one that has every tool` });\n notes.push(\"a stack's branch, autodeploy and policies are Spacelift settings outside the repository; set branches, gate and policy in plywood.yml\");\n return { source: \"spacelift\", files: [file], keys, unsupported, notes };\n};\n", "/**\n * The importers behind `plywood init --from` (plywood#21), one per source:\n *\n * pulumi-actions GitHub Actions workflows using pulumi/actions (./pulumi-actions.ts)\n * deployments Pulumi Deployments settings files the user exported (./deployments.ts)\n * spacelift .spacelift/config.yml (./spacelift.ts)\n * env0 env0.workflow.yml and env0.yml (./env0.ts)\n *\n * `--from` takes a source's name (its files are found where the source keeps\n * them), `<source>=<file>[,<file>]`, or a file, whose source its path says.\n * Each importer reads files in the repository only and returns plywood.yml\n * keys and the settings it could not carry, by name.\n */\nimport { basename } from \"node:path\";\nimport type { Detected } from \"../init/detect\";\nimport { importDeployments } from \"./deployments\";\nimport { importEnv0 } from \"./env0\";\nimport { importPulumiActions } from \"./pulumi-actions\";\nimport { importSpacelift } from \"./spacelift\";\nimport { IMPORT_SOURCES, type ImportResult, type ImportSource, type Importer } from \"./types\";\n\nexport { IMPORT_SOURCES, importLines, mergeKeys, type ImportResult, type ImportSource, type Unsupported } from \"./types\";\n\nexport const IMPORTERS: Readonly<Record<ImportSource, Importer>> = {\n \"pulumi-actions\": importPulumiActions,\n deployments: importDeployments,\n spacelift: importSpacelift,\n env0: importEnv0,\n};\n\nexport interface FromFlag {\n source: ImportSource;\n files: string[];\n}\n\n/** The source a file's path names, if any. */\nexport function sourceOfFile(file: string): ImportSource | undefined {\n const name = basename(file);\n if (/(^|\\/)\\.(github|forgejo|gitea)\\/workflows\\//.test(file)) return \"pulumi-actions\";\n if (/^Pulumi\\.[^.]+\\.deploy\\.(ya?ml|json)$/.test(name)) return \"deployments\";\n if (/(^|\\/)\\.spacelift\\//.test(file)) return \"spacelift\";\n if (/^env0(\\.workflow)?\\.ya?ml$/.test(name)) return \"env0\";\n return undefined;\n}\n\n/** `--from`'s value, or why it is not one. */\nexport function parseFrom(value: string): FromFlag | { error: string } {\n const eq = value.indexOf(\"=\");\n const head = eq >= 0 ? value.slice(0, eq) : value;\n if ((IMPORT_SOURCES as readonly string[]).includes(head)) {\n const files = eq >= 0 ? value.slice(eq + 1).split(\",\").map((f) => f.trim().replace(/^\\.\\//, \"\")).filter(Boolean) : [];\n if (eq >= 0 && files.length === 0) return { error: `--from ${head}= names no file` };\n return { source: head as ImportSource, files };\n }\n const file = value.replace(/^\\.\\//, \"\");\n const source = sourceOfFile(file);\n if (!source) return { error: `--from ${value} is not one of ${IMPORT_SOURCES.join(\", \")}, and its path names none; give <source>=${value}` };\n return { source, files: [file] };\n}\n\n/** Runs the importer `--from` names. */\nexport function runImport(root: string, detected: Detected, from: FromFlag): ImportResult {\n try {\n return IMPORTERS[from.source](root, detected, from.files);\n } catch (e) {\n const file = from.files[0] ?? \"(its files)\";\n return { source: from.source, files: [], keys: {}, unsupported: [{ file, setting: \"(file)\", why: `could not be read: ${(e as Error).message}` }], notes: [] };\n }\n}\n", "/**\n * `plywood init`: sets plywood up from what the repository already has.\n *\n * plywood init [--preset merge|before-merge|approve-all]\n * [--gate always|on-destructive|never] [--engine pulumi|plunge]\n * [--forge github|gitlab|forgejo] [--env <env>]\n * [--no-bucket-check] [--dry-run] [--yes] [--json]\n * plywood init --print-prompt\n *\n * It reads each Pulumi.yaml and its Pulumi.<stack>.yaml files, each\n * stack's backend (plywood.yml, PULUMI_BACKEND_URL, Pulumi.yaml's\n * backend.url), the forge from the origin remote and the default branch\n * (src/init/detect.ts). Then it writes, each only when its content changes:\n *\n * plywood.yml only what detection could not settle, and the\n * preset's keys; a plywood.yml already there is kept\n * chant.workspace.json a member of chant's pulumi kind per project (the\n * picture `chant workspace graph` and behold read),\n * the pulumi lexicon's pin, and plywood.yml's ci keys\n * chant.config.ts the chant project, with the pulumi lexicon\n * plywood.component.ts one component per stack, through pulumi-up\n * .chant/op-waves/pulumi-up.spec.json\n * the waves a merge updates in (chant#4550)\n * the workflow chant's generator output with plywood's words,\n * keeping the team's own jobs (src/init/workflow.ts)\n * plywood.adopt.op.ts with a plunge+ backend, chant's PulumiAdoptOp over\n * the stacks not adopted yet (src/init/adopt.ts)\n *\n * A `.pre-commit-config.yaml` becomes a check hook (chant#4556). An S3, GCS\n * or Azure backend gets chant's bucket check (chant#4558), and each missing\n * setting's fix is printed. `--engine plunge` gives each stack\n * `plunge+<same url>` in plywood.yml (src/init/engine.ts), and each stack on\n * a plunge+ backend gets its `plunge stack adopt` preview printed, which\n * writes nothing (chant#4562). A workflow that runs pulumi/actions is named,\n * and left alone. Approval is always the pull request's preview (plywood's\n * `pull-request` preset of chant#4550 ruling B); a preset picks when updates\n * run and when a wave waits.\n *\n * Everything new in chant is reached through a feature-detect: on a chant\n * without the product pipeline, init writes the config files and says the\n * waves spec and the workflow need a newer chant.\n *\n * The steps are separate functions so `--engine plunge` (src/init/engine.ts)\n * and `--from <workflow>` add a step rather than change one.\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { emitYAMLEntry } from \"@intentius/chant/yaml\";\nimport { dirname, join, posix } from \"node:path\";\nimport { dependencies as PLYWOOD_DEPENDENCIES } from \"../package.json\";\nimport { BUILT_CHANT, chantProduct, needsChantMessage, type ChantProduct, type ForgeKind } from \"./chant-product\";\nimport { toChantSettings, type ChantSettings } from \"./chant-config\";\nimport { identityClouds, pulumiCloudOf } from \"./config/identity\";\nimport { notifyForChant } from \"./config/observe\";\nimport { cleanPath, packsForStack, policyPacksOf, policyProvidersOf, stepPolicyPacksOf } from \"./config/policy\";\nimport { providersPackConfig, providersPackFiles, providersRego, PROVIDERS_PACK_CONFIG, PROVIDERS_PACK_DIR, PROVIDERS_REGO_FILE } from \"./policy-presets\";\nimport { gateOf } from \"./config/approval\";\nimport { engineOf } from \"./config/engine\";\nimport { checkConfig, CONFIG_NAMES, loadConfig, parseConfig, type PlywoodConfig } from \"./config/index\";\nimport { FORGES } from \"./config/routing\";\nimport { stacksOf as configuredStacks } from \"./config/stacks\";\nimport { isObject, type RawConfig } from \"./config/types\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { chantBuildFlags, chantPipelineOptions } from \"./images\";\nimport { hasChant4625, prJobsFor, withJobSettings } from \"./jobs\";\nimport { backendOf, bucketLines, bucketTarget, chantBucketCheck, isPulumiCloud, needsBucketCheckMessage, type BucketReport } from \"./init/backend\";\nimport { ADOPT_OP_FILE, adoptLines, adoptOpFile, adoptPreviews, adoptTodo, chantAdopt, stacksToAdopt, type AdoptPreview } from \"./init/adopt\";\nimport { detect, repoName, slug, type Detected } from \"./init/detect\";\nimport { engineStep, INIT_ENGINES, type InitEngine } from \"./init/engine\";\nimport { DEFAULT_PRESET, gateFlag, PRESETS, PRESET_NAMES, preCommitHook, presetByName, type PresetName } from \"./init/presets\";\nimport {\n chantConfigTs,\n componentsFile,\n jsonText,\n memberOfDir,\n plywoodYml,\n PULUMI_LEXICON,\n waveRunner,\n wavesOf,\n wavesSpec,\n workspaceDeclaration,\n type InitStack,\n} from \"./init/render\";\nimport { writeWorkflow } from \"./init/workflow\";\nimport { chantReviewStacks, REVIEW_STACKS_NEED_CHANT, reviewSuffixOf } from \"./review-stacks\";\nimport { WAVES_OUTPUT_DIR, writeWaveJobs } from \"./waves-workflow\";\nimport { takeFlag, WORKFLOW_FILE, workflowPlan, writtenNotes, type StageIo } from \"./stages\";\nimport { chantNext } from \"./chant-next\";\nimport { orderLines, orderWaves, stackOrder } from \"./stack-order\";\nimport { importLines, mergeKeys, parseFrom, runImport, type FromFlag, type ImportResult } from \"./import/index\";\nimport { template } from \"./templates\";\nimport { OP_NAME, PRODUCT, PRODUCT_WORDS } from \"./words\";\n\n/** init's io: the stage io, and a question asked of the person running it (absent when nobody can answer). */\nexport interface InitIo extends StageIo {\n ask?: (question: string, choices: readonly string[], fallback: string) => Promise<string>;\n}\n\nexport interface InitOptions {\n preset?: PresetName;\n gate?: \"always\" | \"on-destructive\" | \"never\";\n engine?: InitEngine;\n forge?: ForgeKind;\n env: string;\n bucketCheck: boolean;\n dryRun: boolean;\n yes: boolean;\n /** `--from`: the pipeline to read settings from (plywood#21). */\n from?: FromFlag;\n}\n\n/** One file init looked at. */\nexport interface InitFile {\n file: string;\n status: \"written\" | \"unchanged\" | \"kept\" | \"skipped\" | \"failed\";\n note?: string;\n}\n\nexport interface InitResult {\n ok: boolean;\n exitCode: number;\n files: InitFile[];\n stacks: string[];\n waves: Array<{ name: string; stacks: string[] }>;\n forge: { kind: ForgeKind; because: string };\n /** What the person still has to do: secrets, settings, installs. */\n todo: string[];\n notes: string[];\n buckets: BucketReport[];\n /** Each `plunge+` stack's adopt preview (src/init/adopt.ts). */\n adopt: AdoptPreview[];\n /** What `--from` read, and each setting it could not carry. */\n imported?: ImportResult;\n}\n\n/** The workspace declaration file, the chant project and the component file init writes. */\nexport const DECLARATION_FILE = \"chant.workspace.json\";\nexport const CHANT_CONFIG_FILE = \"chant.config.ts\";\nexport const COMPONENTS_FILE = \"plywood.component.ts\";\nexport const WAVES_SPEC_FILE = `.chant/op-waves/${OP_NAME}.spec.json`;\n\n/** The chant pin plywood ships with: the pulumi lexicon is pinned to the same release. */\nexport const CHANT_PIN: string = (PLYWOOD_DEPENDENCIES as Record<string, string>)[\"@intentius/chant\"] ?? \"0.124.54\";\n\n/** Parses init's flags. A bad flag is a message. */\nexport function parseInitArgs(args: string[]): InitOptions | { error: string } | { printPrompt: true } {\n if (args.includes(\"--print-prompt\")) return { printPrompt: true };\n let rest = args;\n const take = (flag: string): { value?: string; error?: string } => {\n const t = takeFlag(rest, flag);\n if (t.missing) return { error: `${flag} takes a value` };\n rest = t.rest;\n return t.value !== undefined ? { value: t.value } : {};\n };\n const preset = take(\"--preset\");\n const gate = take(\"--gate\");\n const engine = take(\"--engine\");\n const forge = take(\"--forge\");\n const env = take(\"--env\");\n const fromFlag = take(\"--from\");\n const bad = [preset, gate, engine, forge, env, fromFlag].find((t) => t.error);\n if (bad) return { error: bad.error! };\n const flags = new Set([\"--no-bucket-check\", \"--dry-run\", \"--yes\", \"-y\"]);\n const extra = rest.filter((a) => !flags.has(a));\n if (extra.length) return { error: `init does not take ${extra.join(\" \")}` };\n if (preset.value !== undefined && !presetByName(preset.value)) return { error: `--preset ${preset.value} is not one of ${PRESET_NAMES.join(\", \")}` };\n const g = gate.value !== undefined ? gateFlag(gate.value) : undefined;\n if (gate.value !== undefined && !g) return { error: `--gate ${gate.value} is not one of always, on-destructive (or destroy), never` };\n if (engine.value !== undefined && !(INIT_ENGINES as readonly string[]).includes(engine.value)) return { error: `--engine ${engine.value} is not one of ${INIT_ENGINES.join(\", \")}` };\n if (forge.value !== undefined && !(FORGES as readonly string[]).includes(forge.value)) return { error: `--forge ${forge.value} is not one of ${FORGES.join(\", \")}` };\n const from = fromFlag.value !== undefined ? parseFrom(fromFlag.value) : undefined;\n if (from && \"error\" in from) return { error: from.error };\n return {\n ...(from ? { from } : {}),\n ...(preset.value ? { preset: preset.value as PresetName } : {}),\n ...(g ? { gate: g } : {}),\n ...(engine.value ? { engine: engine.value as InitEngine } : {}),\n ...(forge.value ? { forge: forge.value as ForgeKind } : {}),\n env: env.value ?? \"production\",\n bucketCheck: !rest.includes(\"--no-bucket-check\"),\n dryRun: rest.includes(\"--dry-run\"),\n yes: rest.includes(\"--yes\") || rest.includes(\"-y\"),\n };\n}\n\n/** Writes `text` to `root/rel` when it differs, creating directories; with dryRun, writes nothing. */\nfunction put(root: string, rel: string, text: string, dryRun: boolean, note?: string): InitFile {\n const file = join(root, rel);\n const before = existsSync(file) ? readFileSync(file, \"utf8\") : undefined;\n if (before === text) return { file: rel, status: \"unchanged\", ...(note ? { note } : {}) };\n if (!dryRun) {\n mkdirSync(dirname(file), { recursive: true });\n writeFileSync(file, text);\n }\n return { file: rel, status: \"written\", ...(note ? { note } : {}) };\n}\n\n/** The plywood.yml there already, if any. */\nfunction existingConfig(root: string): string | undefined {\n return CONFIG_NAMES.find((n) => existsSync(join(root, n)));\n}\n\n/**\n * The keys of a new plywood.yml: the preset's, the gate and engine flags,\n * the forge when the remote does not settle it (or names a self-hosted one),\n * and a backend the jobs cannot read from the repository.\n */\nexport async function newConfigKeys(detected: Detected, opts: InitOptions, io: InitIo): Promise<{ keys: RawConfig; notes: string[]; forge: { kind: ForgeKind; because: string } }> {\n const notes: string[] = [];\n let presetName = opts.preset;\n if (!presetName && io.ask && !opts.yes) {\n for (const p of PRESETS) io.err(` ${p.name.padEnd(13)} ${p.summary}`);\n presetName = (await io.ask(\"Preset\", PRESET_NAMES, DEFAULT_PRESET)) as PresetName;\n }\n const preset = presetByName(presetName ?? DEFAULT_PRESET)!;\n const keys: RawConfig = structuredClone(preset.keys);\n if (opts.gate) keys.gate = opts.gate;\n const engine = engineStep({ engine: opts.engine, detected, env: io.env });\n Object.assign(keys, engine.keys);\n notes.push(...engine.notes);\n const engineBackends = engine.keys.backend !== undefined || engine.keys.stacks !== undefined;\n\n let forge: { kind: ForgeKind; because: string };\n if (opts.forge) {\n forge = { kind: opts.forge, because: \"--forge\" };\n if (detected.forge?.kind !== opts.forge) keys.forge = { kind: opts.forge };\n else if (detected.forge.url) keys.forge = { kind: opts.forge, url: detected.forge.url };\n } else if (detected.forge) {\n forge = { kind: detected.forge.kind, because: detected.forge.because };\n if (detected.forge.url) keys.forge = { kind: detected.forge.kind, url: detected.forge.url };\n } else {\n const kind = (io.ask && !opts.yes ? await io.ask(\"Forge\", FORGES, \"github\") : \"github\") as ForgeKind;\n forge = { kind, because: io.ask && !opts.yes ? \"you chose it\" : \"origin names no forge init knows, so github; change forge.kind in plywood.yml\" };\n keys.forge = { kind };\n }\n\n // A backend only init's environment names: the jobs do not see that environment.\n const fromEnv = io.env.PULUMI_BACKEND_URL?.trim();\n if (fromEnv && !engineBackends && detected.projects.some((p) => !p.backendUrl)) {\n keys.backend = fromEnv;\n notes.push(`backend ${fromEnv} came from PULUMI_BACKEND_URL; it is in plywood.yml so the jobs use it too`);\n }\n return { keys, notes, forge };\n}\n\n/**\n * The stacks init settles: each one found, with plywood.yml's settings for it\n * laid over, then any plywood.yml lists that init did not find. A member of\n * chant's settings pinned to a release off PATH gives its stack\n * `engineVersion` and `engineRoot` (src/config/images.ts), so the step runs\n * the release its install line put there.\n */\nexport function initStacks(detected: Detected, doc: RawConfig, members: readonly ChantSettings[\"members\"][number][] = []): InitStack[] {\n const listed = configuredStacks(doc);\n const pinned = new Map(members.filter((m) => m.engineBin && m.engineVersion).map((m) => [m.name, m]));\n const out: InitStack[] = [];\n const seen = new Set<string>();\n const add = (key: string, project: string, stack: string, dir: string): void => {\n const own = listed[key] ?? {};\n const backend = own.backend ?? (typeof doc.backend === \"string\" ? doc.backend : undefined);\n const engine = engineOf(doc, backend)?.engine;\n const stackDir = own.dir ?? dir;\n const packs = packsForStack(stepPolicyPacksOf(doc), stackDir);\n const pin = pinned.get(key);\n out.push({\n key,\n project,\n stack,\n dir: stackDir,\n ...(engine ? { engine } : {}),\n ...(pin ? { engineVersion: pin.engineVersion!, ...(pin.engineRoot ? { engineRoot: pin.engineRoot } : {}) } : {}),\n ...(own.gate ? { gate: own.gate } : {}),\n ...(packs.length ? { policyPacks: packs } : {}),\n });\n seen.add(key);\n };\n for (const s of detected.stacks) add(s.key, s.project, s.stack, s.dir);\n for (const [key, own] of Object.entries(listed)) {\n if (seen.has(key)) continue;\n const [project, stack] = key.split(\"/\") as [string, string];\n add(key, project, stack, own?.dir ?? \".\");\n }\n return out;\n}\n\n/** The forge for a kept plywood.yml: its forge.kind, the flag, or detection. */\nfunction forgeFor(doc: RawConfig, detected: Detected, opts: InitOptions): { kind: ForgeKind; because: string } {\n if (opts.forge) return { kind: opts.forge, because: \"--forge\" };\n const kind = isObject(doc.forge) ? (doc.forge.kind as ForgeKind | undefined) : undefined;\n if (kind) return { kind, because: \"plywood.yml says forge.kind\" };\n if (detected.forge) return { kind: detected.forge.kind, because: detected.forge.because };\n return { kind: \"github\", because: \"origin names no forge init knows, so github\" };\n}\n\n/** chant's `writeCiHook` (chant#4556), reached through a feature-detect. */\nasync function chantWriteCiHook(): Promise<((root: string, moment: \"check\", hook: { name: string; command: string[] }) => { file: string; replaced: boolean }) | undefined> {\n try {\n // @ts-ignore: the subpath's writeCiHook is missing from chant 0.124.54 (chant#4556).\n const m: Record<string, unknown> = await import(\"@intentius/chant/components/check-hooks\");\n return typeof m.writeCiHook === \"function\" ? (m.writeCiHook as never) : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** Runs init. Writes nothing when the config has an error; with dryRun, writes nothing at all. */\nexport async function runInit(opts: InitOptions, table: ExitTable, io: InitIo): Promise<InitResult> {\n const detected = detect(io.cwd);\n const { root } = detected;\n const files: InitFile[] = [];\n const notes: string[] = [];\n const todo: string[] = [];\n const buckets: BucketReport[] = [];\n const adopt: AdoptPreview[] = [];\n // --from: the other pipeline's settings, read from the repository's files (plywood#21).\n const imported = opts.from ? runImport(root, detected, opts.from) : undefined;\n if (imported && imported.files.length === 0) notes.push(`--from ${imported.source} found no file to read${imported.notes.length ? `: ${imported.notes.join(\"; \")}` : \"\"}`);\n const fail = (message: string, forge = { kind: \"github\" as ForgeKind, because: \"\" }): InitResult => ({\n ok: false, exitCode: table.failed, files, stacks: [], waves: [], forge, todo, notes: [...notes, message], buckets, adopt, ...(imported ? { imported } : {}),\n });\n\n if (detected.projects.length === 0) return fail(`no Pulumi.yaml under ${root}; plywood init sets up a repository that has a Pulumi program`);\n if (detected.stacks.length === 0) notes.push(\"no Pulumi.<stack>.yaml beside any Pulumi.yaml, so no stack is set up; run pulumi stack init, then plywood init again\");\n\n // plywood.yml: kept when there, else written with only what detection could not settle.\n let config: PlywoodConfig;\n let forge: { kind: ForgeKind; because: string };\n const kept = existingConfig(root);\n if (kept) {\n try {\n config = loadConfig(join(root, kept));\n } catch (e) {\n return fail((e as Error).message);\n }\n files.push({ file: kept, status: \"kept\" });\n const onPlunge = opts.engine === \"plunge\" && engineOf(config.doc)?.engine === \"plunge\";\n const ignored = [opts.preset && \"--preset\", opts.gate && \"--gate\", opts.engine && !onPlunge && \"--engine\", imported && \"--from\"].filter(Boolean);\n if (ignored.length) notes.push(`${kept} is kept as it is, so ${ignored.join(\", \")} changed nothing; set the keys there`);\n if (opts.engine === \"plunge\" && !onPlunge) notes.push(...keptPlungeLines(kept, detected, io.env));\n forge = forgeFor(config.doc, detected, opts);\n } else {\n const made = await newConfigKeys(detected, opts, io);\n notes.push(...made.notes);\n forge = made.forge;\n const text = plywoodYml(imported ? mergeKeys(made.keys, imported.keys) : made.keys);\n config = parseConfig(text, \"plywood.yml\");\n const problems = checkConfig(config).filter((p) => p.severity === \"error\");\n if (problems.length) return fail(problems.map((p) => `plywood.yml: ${p.key} ${p.message}`).join(\"\\n\"), forge);\n files.push(put(root, \"plywood.yml\", text, opts.dryRun));\n }\n const problems = checkConfig(config).filter((p) => p.severity === \"error\");\n if (problems.length) return fail(problems.map((p) => `${kept}: ${p.key} ${p.message}`).join(\"\\n\"), forge);\n const doc = config.doc;\n const settings: ChantSettings = toChantSettings(config);\n // Review stacks (plywood#15, chant#4609): ci.prEnvironment's project/stack template and the step's reviewSuffix only on a lexicon that runs them end to end.\n const reviewStacks = config.doc.review_stacks !== undefined ? await chantReviewStacks() : false;\n if (settings.ci.prEnvironment && !reviewStacks) delete settings.ci.prEnvironment;\n const reviewSuffix = reviewStacks ? reviewSuffixOf(settings.pipeline.reviewStackName) : undefined;\n const stacks = initStacks(detected, doc, settings.members);\n // The merge's waves: the canary first, each wave cut by StackReferences and waves.after (plywood#18).\n const order = await stackOrder(root, stacks, settings.pipeline.after);\n const ordered = orderWaves(wavesOf(stacks, settings.pipeline.waves), order.edges, settings.pipeline.canary);\n const waves = ordered.waves;\n if (order.edges.length || order.outside.length || ordered.unmet.length || (!order.reads && stacks.length > 1)) notes.push(...orderLines(order, ordered.unmet));\n\n // The member picture and the chant project.\n const declaration = declarationStep(root, detected, settings, opts.dryRun);\n files.push(declaration.file);\n if (existsSync(join(root, CHANT_CONFIG_FILE))) {\n const text = readFileSync(join(root, CHANT_CONFIG_FILE), \"utf8\");\n if (!/[\"']pulumi[\"']/.test(text)) {\n files.push({ file: CHANT_CONFIG_FILE, status: \"kept\", note: 'add \"pulumi\" to its lexicons so chant previews and updates the stacks' });\n } else files.push({ file: CHANT_CONFIG_FILE, status: \"kept\" });\n } else files.push(put(root, CHANT_CONFIG_FILE, chantConfigTs(), opts.dryRun));\n files.push(put(root, COMPONENTS_FILE, componentsFile(stacks, settings.pipeline.after, reviewSuffix ? { reviewSuffix } : {}), opts.dryRun));\n\n // plywood#31: the provider allowlist, as a Rego rule in policy.rego and as a CrossGuard pack.\n files.push(...providersPresetStep(root, doc, opts.dryRun, notes));\n\n // What the repository already runs.\n if (detected.preCommit) files.push(await preCommitStep(root, detected.preCommit, opts.dryRun));\n for (const wf of detected.pulumiActions) {\n notes.push(`${wf} runs pulumi/actions. init leaves it as it is; once plywood's previews and updates replace it, remove it, or keep it for the stacks plywood does not run`);\n }\n\n // The waves spec and the workflow come from chant's product pipeline.\n const chant = await chantProduct();\n if (!chant) {\n const message = needsChantMessage(\"Writing the waves spec and the workflow\");\n files.push({ file: WAVES_SPEC_FILE, status: \"skipped\", note: message }, { file: WORKFLOW_FILE[forge.kind], status: \"skipped\", note: \"needs the same chant\" });\n } else {\n let spec: Record<string, unknown> | undefined = wavesSpecStep(chant, stacks, doc, settings, detected.defaultBranch, waves);\n // plywood#29: env, pass, parallelism and environments on each wave (src/jobs.ts).\n if (settings.pipeline.jobs) {\n try {\n spec = withJobSettings(spec, settings.pipeline.jobs, forge.kind, { parallelism: await hasChant4625() });\n } catch (e) {\n files.push({ file: WAVES_SPEC_FILE, status: \"failed\", note: (e as Error).message });\n spec = undefined;\n }\n }\n if (spec && stacks.length > 0) files.push(put(root, WAVES_SPEC_FILE, jsonText(spec), opts.dryRun));\n if (spec) files.push(...(await workflowStep(chant, root, doc, settings, forge.kind, opts, stacks.length > 0 ? spec : undefined, table, io)));\n }\n\n // The bucket each self-managed stack keeps its state in.\n if (opts.bucketCheck) notes.push(...(await bucketStep(detected, doc, io.env, buckets)));\n\n // The adopt preview for each stack on a plunge+ backend, and the Op that adopts them.\n adopt.push(...(await adoptStep(root, detected, doc, io.env, declaration.doc, opts.dryRun, files, notes, todo)));\n\n todo.push(...todoLines(detected, doc, forge.kind, io.env));\n const failed = files.find((f) => f.status === \"failed\");\n return {\n ok: !failed,\n exitCode: failed ? table.failed : table.done,\n files,\n stacks: stacks.map((s) => s.key),\n waves: waves.map((w) => ({ name: w.name, stacks: w.stacks.map((s) => s.key) })),\n forge,\n todo,\n notes,\n buckets,\n adopt,\n ...(imported ? { imported } : {}),\n };\n}\n\n/** chant.workspace.json: written when absent, merged when there, left alone as .jsonc (it is the person's). */\nfunction declarationStep(root: string, detected: Detected, settings: ChantSettings, dryRun: boolean): { file: InitFile; doc?: Record<string, unknown> } {\n if (existsSync(join(root, \"chant.workspace.jsonc\"))) {\n return { file: { file: \"chant.workspace.jsonc\", status: \"kept\", note: `add a member of kind pulumi for each of ${detected.projects.map((p) => p.dir).join(\", \")}, and pin ${PULUMI_LEXICON}@${CHANT_PIN}` } };\n }\n let existing: Record<string, unknown> | undefined;\n const file = join(root, DECLARATION_FILE);\n if (existsSync(file)) {\n try {\n const parsed: unknown = JSON.parse(readFileSync(file, \"utf8\"));\n if (!isObject(parsed)) throw new Error(\"not an object\");\n existing = parsed;\n } catch (e) {\n return { file: { file: DECLARATION_FILE, status: \"failed\", note: `is not JSON init can merge into (${(e as Error).message})` } };\n }\n }\n const doc = workspaceDeclaration(existing, { name: repoName(root), projects: detected.projects, ci: settings.ci, lexiconVersion: CHANT_PIN });\n if (existing && JSON.stringify(existing) === JSON.stringify(doc)) return { file: { file: DECLARATION_FILE, status: \"unchanged\" }, doc };\n return { file: put(root, DECLARATION_FILE, jsonText(doc), dryRun), doc };\n}\n\n/**\n * The provider allowlist preset (src/policy-presets.ts), when plywood.yml\n * sets policy.providers: the Rego rule into policy.rego (or not, with a note,\n * when no Rego directory is set or the rules come from policy.source), and\n * the CrossGuard pack with its config, which runs once policy.packs lists it.\n */\nfunction providersPresetStep(root: string, doc: RawConfig, dryRun: boolean, notes: string[]): InitFile[] {\n const allowed = policyProvidersOf(doc);\n if (!allowed) return [];\n const p = isObject(doc.policy) ? doc.policy : {};\n const out: InitFile[] = [];\n if (typeof p.rego === \"string\" && p.source === undefined) {\n const namespace = typeof p.namespace === \"string\" ? p.namespace : \"main\";\n out.push(put(root, posix.join(cleanPath(p.rego), PROVIDERS_REGO_FILE), providersRego(allowed, namespace), dryRun, \"deny_provider_package, read at base\"));\n } else notes.push(`policy.providers: no Rego rule was written; set policy.rego to a directory and run '${PRODUCT} init' again for one, or use the CrossGuard pack`);\n for (const [file, text] of Object.entries(providersPackFiles())) out.push(put(root, posix.join(PROVIDERS_PACK_DIR, file), text, dryRun));\n out.push(put(root, PROVIDERS_PACK_CONFIG, providersPackConfig(allowed), dryRun));\n const listed = policyPacksOf(doc).some((pack) => pack.dir === PROVIDERS_PACK_DIR);\n if (!listed) notes.push(`policy.providers: add { dir: ${PROVIDERS_PACK_DIR}, config: ${PROVIDERS_PACK_CONFIG} } to policy.packs to run the CrossGuard pack in each preview and update; it needs @pulumi/policy installed in ${PROVIDERS_PACK_DIR}`);\n return out;\n}\n\n/** `.pre-commit-config.yaml` as a check hook, so plywood check runs the team's hooks at the base commit. */\nasync function preCommitStep(root: string, config: string, dryRun: boolean): Promise<InitFile> {\n const write = await chantWriteCiHook();\n if (!write) {\n return { file: DECLARATION_FILE, status: \"skipped\", note: `${config} found; running it as a check hook needs chant >= the release after 0.124.54 (chant#4556's writeCiHook). This plywood was built with chant ${BUILT_CHANT}` };\n }\n if (dryRun || !existsSync(join(root, DECLARATION_FILE))) return { file: DECLARATION_FILE, status: \"skipped\", note: `${config} would run as the check hook pre-commit` };\n const before = readFileSync(join(root, DECLARATION_FILE), \"utf8\");\n try {\n write(root, \"check\", preCommitHook());\n } catch (e) {\n return { file: DECLARATION_FILE, status: \"failed\", note: `the pre-commit check hook: ${(e as Error).message}` };\n }\n const after = readFileSync(join(root, DECLARATION_FILE), \"utf8\");\n return { file: DECLARATION_FILE, status: after === before ? \"unchanged\" : \"written\", note: `${config} runs as the check hook pre-commit; the check job's image needs pre-commit` };\n}\n\n/** The waves spec with chant's names filled (chant `productWavesSpec`), else as plywood builds it. */\nfunction wavesSpecStep(chant: ChantProduct, stacks: readonly InitStack[], doc: RawConfig, settings: ChantSettings, branch: string, ordered: ReadonlyArray<{ name: string; stacks: InitStack[] }>): Record<string, unknown> {\n const runner = waveRunner(chantPipelineOptions(settings.pipeline, false).runner);\n const base = wavesSpec({\n stacks,\n ordered,\n gate: gateOf(doc),\n branch,\n ...(runner !== undefined ? { runner } : {}),\n ...(settings.pipeline.quorum?.length ? { quorum: settings.pipeline.quorum } : {}),\n // notify.relay only on a chant with the relay (chant#4611); an older chant refuses the setting.\n ...(settings.pipeline.notify ? { notify: { ...notifyForChant(settings.pipeline.notify, chant) } } : {}),\n });\n return chant.productWavesSpec ? chant.productWavesSpec(base, PRODUCT_WORDS) : base;\n}\n\n/**\n * The pull request workflow, through chant's generator with plywood's words\n * and the image and install lines (src/images.ts), then the waves workflow\n * the merge updates in (src/waves-workflow.ts), as `plywood ci` writes them.\n */\nasync function workflowStep(\n chant: ChantProduct,\n root: string,\n doc: RawConfig,\n settings: ChantSettings,\n forge: ForgeKind,\n opts: InitOptions,\n spec: unknown,\n table: ExitTable,\n io: InitIo,\n): Promise<InitFile[]> {\n const output = WORKFLOW_FILE[forge];\n const prJobs = await prJobsFor(settings.pipeline);\n let plan;\n try {\n // The build takes no product engine lines over argv, so they go to --before-script.\n // plywood#28: with a control repo, the note job reads its records for the cross-stack edges (chant#4619).\n const { noteControlTarget } = await import(\"./control\");\n const control = await noteControlTarget(doc, root);\n plan = workflowPlan(chant, doc, forge, opts.env, spec, chantBuildFlags(chantPipelineOptions(settings.pipeline, false)), { reviewStacks: await chantReviewStacks(), prJobs, next: await chantNext(), ...(control ? { control } : {}) });\n } catch (e) {\n return [{ file: output, status: \"failed\", note: (e as Error).message }];\n }\n if (opts.dryRun) return [{ file: output, status: \"skipped\", note: \"--dry-run: chant's generator was not run\" }];\n const argv = plan.argv.map((a, i) => (i === 1 && a === \".\" ? root : a));\n const written = await writeWorkflow(chant, { root, forge, output, argv, words: plan.prWords, noteControl: plan.jobs.post.control });\n if (written.status === \"failed\") return [{ file: output, status: \"failed\", note: `chant's generator exited ${written.code}; the old file is back as it was` }];\n const notes = [\n ...(written.kept.length ? [`kept your own jobs: ${written.kept.join(\", \")}`] : []),\n ...(doc.review_stacks !== undefined && !plan.argv.includes(\"--pr-env\") ? [REVIEW_STACKS_NEED_CHANT] : []),\n ...prJobs.notes,\n ...plan.notes,\n ...writtenNotes(plan, written.file),\n ];\n const out: InitFile[] = [{ file: output, status: written.status, ...(notes.length ? { note: notes.join(\"; \") } : {}) }];\n if (plan.jobs.waves) {\n const code = await writeWaveJobs(chant, forge, plan.jobs.waves, plan.words, table, { ...io, cwd: root });\n if (code !== table.done) out.push({ file: WAVES_OUTPUT_DIR[forge], status: \"failed\", note: `the waves workflow: chant exited ${code}` });\n }\n return out;\n}\n\n/** The bucket check for each distinct self-managed backend; the lines to print. */\nasync function bucketStep(detected: Detected, doc: RawConfig, env: NodeJS.ProcessEnv, reports: BucketReport[]): Promise<string[]> {\n const listed = configuredStacks(doc);\n const urls = new Set<string>();\n for (const s of detected.stacks) {\n const project = detected.projects.find((p) => p.dir === s.dir && p.name === s.project) ?? { backendUrl: undefined };\n const b = backendOf(project, { ...(listed[s.key]?.backend ? { stack: listed[s.key]!.backend } : {}), ...(typeof doc.backend === \"string\" ? { all: doc.backend } : {}) }, env);\n if (b.url && !isPulumiCloud(b.url)) urls.add(b.url);\n }\n const targets = [...urls].map((u) => bucketTarget(u, env)).filter((t) => t !== undefined);\n if (targets.length === 0) return [];\n const check = await chantBucketCheck();\n if (!check) return [needsBucketCheckMessage(BUILT_CHANT)];\n const lines: string[] = [\"State buckets:\"];\n for (const t of targets) {\n if (!t.ok) {\n lines.push(` ${t.label}: not checked; ${t.reason}`);\n continue;\n }\n try {\n const report = await check.checkBucket(t.target, { namespaces: t.namespaces });\n reports.push(report);\n lines.push(...bucketLines(report));\n } catch (e) {\n lines.push(` ${t.label}: not checked; ${(e as Error).message}`);\n }\n }\n return lines;\n}\n\n/**\n * The adopt previews for the stacks plywood.yml puts on a `plunge+` backend,\n * and plywood.adopt.op.ts for the ones not adopted yet (src/init/adopt.ts).\n */\nasync function adoptStep(\n root: string,\n detected: Detected,\n doc: RawConfig,\n env: NodeJS.ProcessEnv,\n declaration: Record<string, unknown> | undefined,\n dryRun: boolean,\n files: InitFile[],\n notes: string[],\n todo: string[],\n): Promise<AdoptPreview[]> {\n const listed = configuredStacks(doc);\n const all = typeof doc.backend === \"string\" ? doc.backend : undefined;\n const targets: Array<{ key: string; project: string; projectDir: string; dir: string; stack: string; url: string }> = [];\n for (const s of detected.stacks) {\n const project = detected.projects.find((p) => p.dir === s.dir && p.name === s.project) ?? { backendUrl: undefined };\n const own = listed[s.key];\n const b = backendOf(project, { ...(own?.backend ? { stack: own.backend } : {}), ...(all ? { all } : {}) }, env);\n if (b.url && /^plunge\\+/.test(b.url)) targets.push({ key: s.key, project: s.project, projectDir: s.dir, dir: own?.dir ?? s.dir, stack: s.stack, url: b.url });\n }\n if (targets.length === 0) return [];\n const chant = await chantAdopt();\n const previews = await adoptPreviews(targets, chant, root);\n notes.push(...adoptLines(previews, chant));\n if (!chant?.hasOp) {\n files.push({ file: ADOPT_OP_FILE, status: \"skipped\", note: `the adopt Op needs @intentius/chant-lexicon-pulumi >= the release after 0.124.54 (chant#4562's PulumiAdoptOp). This plywood was built with chant ${BUILT_CHANT}` });\n return previews;\n }\n const left = stacksToAdopt(targets, previews);\n if (left.length === 0) {\n if (existsSync(join(root, ADOPT_OP_FILE))) files.push({ file: ADOPT_OP_FILE, status: \"kept\", note: \"every stack is adopted; delete it\" });\n return previews;\n }\n const rows = left.map((t) => ({ member: memberOfDir(declaration, t.projectDir) ?? slug(t.project), dir: t.dir, stack: t.stack, url: t.url }));\n files.push(put(root, ADOPT_OP_FILE, adoptOpFile(rows), dryRun));\n todo.push(...adoptTodo(rows));\n return previews;\n}\n\n/** With a kept plywood.yml, the keys `--engine plunge` would set, for the person to add. */\nfunction keptPlungeLines(kept: string, detected: Detected, env: NodeJS.ProcessEnv): string[] {\n const step = engineStep({ engine: \"plunge\", detected, env });\n const entries = Object.entries(step.keys);\n if (entries.length === 0) return step.notes;\n const yaml = entries.map(([k, v]) => emitYAMLEntry(k, v)).join(\"\\n\").split(\"\\n\").filter((l) => l !== \"\");\n return [...step.notes, `To move to plunge, set these keys in ${kept}:`, ...yaml.map((l) => ` ${l}`)];\n}\n\n/** The secrets and settings left for the person. */\nfunction todoLines(detected: Detected, doc: RawConfig, forge: ForgeKind, env: NodeJS.ProcessEnv): string[] {\n // The pulumi lexicon comes with plywood: it is plywood's second runtime dependency, at the chant pin (plywood#9, ruling A1).\n const out: string[] = [];\n const all = typeof doc.backend === \"string\" ? doc.backend : undefined;\n const cloud = detected.projects.some((p) => isPulumiCloud(backendOf(p, all ? { all } : {}, env).url));\n const where = forge === \"gitlab\" ? \"CI/CD variables\" : \"repository secrets\";\n const traded = identityClouds(doc);\n if (cloud && traded.includes(\"pulumi\")) {\n out.push(`Add an OIDC issuer for this ${forge} repository in Pulumi Cloud organization ${pulumiCloudOf(doc).org}, with a policy for each token identity names; no Pulumi token goes in the ${where}`);\n } else if (cloud) {\n out.push(`Set pulumi_cloud.org and identity.preview.pulumi and identity.up.pulumi in plywood.yml, so each job trades its OIDC token for its own Pulumi Cloud token, or add PULUMI_ACCESS_TOKEN_PREVIEW and PULUMI_ACCESS_TOKEN_UP to the ${where}`);\n }\n if (traded.some((c) => c !== \"pulumi\")) out.push(`Let each role identity names trust this repository's OIDC tokens: the preview role for pull requests, the up role for ${detected.defaultBranch} only`);\n else if (!cloud) out.push(\"Give the preview job and the update job their cloud access, each its own role through OIDC (identity in plywood.yml); the backend bucket's read and write go with them\");\n out.push(`Make ${PRODUCT}/preview a required status on ${detected.defaultBranch}`);\n return out;\n}\n\n/** The text init prints for a result. */\nexport function initLines(r: InitResult): string[] {\n const out: string[] = [];\n out.push(`${PRODUCT} init: ${r.stacks.length} stack${r.stacks.length === 1 ? \"\" : \"s\"} on ${r.forge.kind} (${r.forge.because})`);\n for (const w of r.waves) out.push(` wave ${w.name}: ${w.stacks.join(\", \")}`);\n if (r.waves.length > 1) out.push(` the first wave, ${r.waves[0]!.name}, is the canary`);\n if (r.imported) out.push(...importLines(r.imported));\n out.push(\"Files:\");\n for (const f of r.files) out.push(` ${f.status.padEnd(9)} ${f.file}${f.note ? `: ${f.note}` : \"\"}`);\n if (r.notes.length) out.push(...r.notes.map((n) => (n.startsWith(\" \") || n.endsWith(\":\") ? n : `- ${n}`)));\n if (r.todo.length) out.push(\"Left for you:\", ...r.todo.map((t) => ` - ${t}`));\n return out;\n}\n\n/** `plywood init`, from the CLI. */\nexport async function init(args: string[], json: boolean, table: ExitTable, io: InitIo): Promise<number> {\n const parsed = parseInitArgs(args);\n if (\"printPrompt\" in parsed) {\n const prompt = template(\"agent-prompt.md\").trimEnd();\n io.out(json ? JSON.stringify({ command: \"init\", ok: true, exitCode: table.done, prompt }) : prompt);\n return table.done;\n }\n if (\"error\" in parsed) {\n io.err(`${PRODUCT}: ${parsed.error}`);\n if (json) io.out(JSON.stringify({ command: \"init\", ok: false, exitCode: table.failed, error: parsed.error }));\n return table.failed;\n }\n const r = await runInit(parsed, table, json ? { ...io, ask: undefined } : io);\n if (json) io.out(JSON.stringify({ command: \"init\", ...r }));\n else for (const line of initLines(r)) (r.ok ? io.out : io.err)(line);\n return r.exitCode;\n}\n", "/**\n * `plywood control`: the control repo (plywood#18), on chant's\n * `@intentius/chant/ci-control` (chant#4568). plywood holds the words, the\n * keys a control repo may set for a repository, their check, and the\n * generator reconcile runs; chant holds the dispatch, the entries on the\n * ledger and reconcile itself.\n *\n * control init [--forge <kind>] [--dry-run]\n * in the control repo: its own workflow, which runs a repository's\n * dependents once that repository tells it a stack applied (the forge\n * lexicon's generateControlPipeline, installed in the control repo)\n * control put <host/owner/name>|defaults [--file <yml>] [--approver <glob>=<role>[:<quorum>]]...\n * [--pin pulumi=<v>|plunge=<v>|image=<ref>]... [--estate <name>]... [--by <who>] [--dry-run]\n * in the control repo: one entry's settings, laid over its current\n * ones, as a new version on the ledger (putControlEntry)\n * control import <yml> [--by <who>] [--dry-run]\n * in the control repo: a reviewed file of `defaults` and `projects`\n * as entries (importControlConfig), for a pipeline on the control\n * repo's default branch, so each change is a merged pull request\n * control list | control retire <host/owner/name>\n * control reconcile [--apply] [--project <host/owner/name>]\n * each repository's plywood.yml and files from its entry, through\n * plywood init; --apply opens a pull request on each one that changes\n * control dispatch [--sha <sha>]\n * in a repository: tell plywood.yml's control repo that this commit\n * applied (dispatchControl), for a job of the repository's own\n *\n * With a chant that has chant#4617, `plywood ci` puts plywood.yml's\n * `control` into the waves spec ({@link wavesControl}), and chant's op-wave\n * generator adds the job that tells the control repo how the waves ended,\n * so the repository needs no dispatch job of its own.\n *\n * An entry's settings are plywood.yml keys, only those in CONTROLLED_KEYS:\n * the gate, the approvers (approval, approval_rules) and the pins (pulumi,\n * plunge, image). Entries are records on the control repo's ledger; nothing\n * here writes git, and nothing pushes: the commands say what to push.\n */\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { createRequire } from \"node:module\";\nimport { dirname, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\nimport { emitYAMLEntry, parseYAML } from \"@intentius/chant/yaml\";\nimport type { ChantControlSettings } from \"./chant-config\";\nimport { checkConfig, CONFIG_NAMES, findConfig, loadConfig, parseConfig, type RawConfig } from \"./config/index\";\nimport { controlOf } from \"./config/control\";\nimport { FORGES } from \"./config/routing\";\nimport { isObject } from \"./config/types\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { repoName } from \"./init/detect\";\nimport { positionals, takeFlag, usage, type StageIo } from \"./stages\";\nimport { PRODUCT, PRODUCT_WORDS } from \"./words\";\nimport type { ForgeKind } from \"./chant-product\";\n\n/** The plywood.yml keys a control repo sets for a repository. */\nexport const CONTROLLED_KEYS = [\"gate\", \"approval\", \"approval_rules\", \"pulumi\", \"plunge\", \"image\"] as const;\n\n/** The message when the installed chant has no control repo. */\nexport const CONTROL_NEEDS_CHANT =\n \"the control repo needs chant >= the release after 0.124.54, which carries @intentius/chant/ci-control (chant#4568)\";\n\ntype Settings = Record<string, unknown>;\ninterface Entry {\n id: string;\n entry: \"project\" | \"defaults\";\n project?: string;\n settings: Settings;\n estates: string[];\n digest: string;\n at: string;\n by?: string;\n}\ninterface Port {\n read(): Promise<string | null>;\n append(line: string, message: string): Promise<string>;\n}\ntype Validator = (entry: \"project\" | \"defaults\", project: string | undefined, settings: Settings) => string[];\ninterface WriteOptions {\n product: string;\n by?: string;\n validate?: Validator;\n expect?: string;\n dryRun?: boolean;\n}\ninterface PutResult {\n id: string;\n status: \"created\" | \"updated\" | \"unchanged\" | \"retired\";\n commit?: string;\n}\ninterface FileChange {\n path: string;\n status: \"created\" | \"updated\" | \"unchanged\" | \"removed\";\n}\ninterface ReconcileTarget {\n key: string;\n name: string;\n forge: ForgeKind;\n settings: Settings;\n dryRun: boolean;\n}\ninterface Outcome {\n key: string;\n status: \"unchanged\" | \"would-change\" | \"pull-request\" | \"failed\";\n changes: FileChange[];\n pullRequest?: string;\n error?: string;\n}\ninterface Target {\n repo: string;\n forge: ForgeKind;\n member: string;\n op: string;\n tokenSecret: string;\n}\n\n/** What plywood calls from `@intentius/chant/ci-control`. */\nexport interface ChantControl {\n controlSettingsProblems(input: unknown, where?: string): string[];\n resolveControlTarget(input: ChantControlSettings, fallbackMember: string): Target;\n dispatchControl(target: Target, d: { member: string; op: string; sha: string }, opts?: { env?: Record<string, string | undefined>; words?: unknown }): Promise<{ status: number }>;\n controlPipelinePath(forge: ForgeKind, words?: unknown): string;\n gitControlLedger(opts?: { cwd?: string }): Port;\n readControlEntries(port: Port, opts?: { validate?: Validator; lenient?: boolean }): Promise<Entry[]>;\n putControlEntry(port: Port, want: { entry: \"project\" | \"defaults\"; project?: string; settings: Settings; estates?: string[] }, opts: WriteOptions): Promise<PutResult>;\n retireControlEntry(port: Port, project: string, opts: WriteOptions): Promise<PutResult>;\n importControlConfig(port: Port, config: { defaults?: Settings; projects: Record<string, Settings>; estates?: Record<string, string[]> }, opts: WriteOptions): Promise<Array<PutResult & { entry: string }>>;\n controlConfig(entries: readonly Entry[]): { defaults?: Settings; projects: Record<string, Settings> };\n reconcileProjects(\n projects: ReadonlyArray<{ key: string; settings: Settings }>,\n options: { mode: \"dry-run\" | \"apply\"; project?: string; words?: unknown; generate: (dir: string, target: ReconcileTarget) => Promise<FileChange[]>; env?: Record<string, string | undefined> },\n ): Promise<Outcome[]>;\n describeReconcile(outcomes: readonly Outcome[], mode: \"dry-run\" | \"apply\"): string;\n /** Present when the op-waves spec takes `control` and its dispatch carries the outcome (chant#4617). */\n recordControlAppliedFromEnv?: (...args: unknown[]) => unknown;\n CONTROL_APPLIED_FLOOR?: string;\n}\n\n/**\n * Whether the installed chant's op waves take `control` (chant#4617). It\n * landed with the control repo's apply records on `ci-control`, so\n * `recordControlAppliedFromEnv` there is the check, and plywood needs no\n * import of chant's op-waves module.\n */\nexport function hasWavesControl(chant: ChantControl): boolean {\n return typeof chant.recordControlAppliedFromEnv === \"function\";\n}\n\n/** The `ControlSettingsInput` keys an op waves spec's `control` carries, with `member`. */\nconst WAVES_CONTROL_KEYS = [\"repo\", \"op\", \"forge\", \"member\", \"tokenSecret\", \"readTokenSecret\", \"ref\", \"apiBase\"] as const;\n\n/**\n * plywood.yml's `control` as the waves spec's `control` (chant#4617): its\n * settings with `member` resolved, since a spec has no repository name to\n * default it to. `none` when plywood.yml has no control key, `missing` when\n * the installed chant's op waves take no `control`.\n */\nexport async function wavesControl(cwd: string): Promise<{ control: Record<string, unknown>; repo: string } | { none: true } | { missing: string } | { error: string }> {\n const file = findConfig(cwd);\n if (!file || controlOf(loadConfig(file).doc) === undefined) return { none: true };\n const chant = await chantControl();\n if (!chant) return { missing: CONTROL_NEEDS_CHANT };\n if (!hasWavesControl(chant)) return { missing: \"the waves workflow tells the control repo with a chant that has chant#4617\" };\n const target = await controlTarget(chant, cwd);\n if (\"error\" in target) return target;\n const settings: Record<string, unknown> = { ...(controlOf(loadConfig(file).doc) as unknown as Record<string, unknown>), member: target.member };\n const control: Record<string, unknown> = {};\n for (const key of WAVES_CONTROL_KEYS) if (settings[key] !== undefined) control[key] = settings[key];\n return { control, repo: target.repo };\n}\n\n/**\n * The control repo the note job reads (plywood#28, chant#4619): plywood.yml's\n * `control` resolved to chant's target, or undefined when plywood.yml has\n * none, the installed chant has no control repo, or the settings do not\n * check. `plywood ci` and `plywood init` pass it to productPipelineJobs,\n * which hands back the note job's read step as `post.control`.\n */\nexport async function noteControlTarget(doc: RawConfig, root: string): Promise<Target | undefined> {\n const settings = controlOf(doc);\n if (!settings) return undefined;\n const chant = await chantControl();\n if (!chant || chant.controlSettingsProblems(settings).length > 0) return undefined;\n try {\n return chant.resolveControlTarget(settings, repoName(root));\n } catch {\n return undefined;\n }\n}\n\n/** chant#4568's presence check: these three present means the rest is too. */\nconst REQUIRED = [\"controlDispatchRequest\", \"putControlEntry\", \"reconcileProjects\"] as const;\n\nlet cached: Promise<ChantControl | undefined> | undefined;\n\n/** chant's control repo, or undefined when the installed chant lacks it. */\nexport function chantControl(): Promise<ChantControl | undefined> {\n cached ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4568).\n const m: Record<string, unknown> = await import(\"@intentius/chant/ci-control\");\n return REQUIRED.every((n) => typeof m[n] === \"function\") ? (m as unknown as ChantControl) : undefined;\n } catch {\n return undefined;\n }\n })();\n return cached;\n}\n\n/** Tests stand in a fake chant (or none). `reset` goes back to the real import. */\nexport function setChantControlForTests(fake: ChantControl | undefined | \"reset\"): void {\n cached = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The problems with an entry's settings, as plywood.yml's checks see those keys. */\nexport const validateControlSettings: Validator = (_entry, _project, settings) => {\n const out: string[] = [];\n for (const key of Object.keys(settings)) {\n if (!(CONTROLLED_KEYS as readonly string[]).includes(key)) out.push(`${key} is not a key a control repo sets; it sets ${CONTROLLED_KEYS.join(\", \")}`);\n }\n for (const p of checkConfig({ doc: settings })) if (p.severity === \"error\") out.push(`${p.key} ${p.message}`);\n return out;\n};\n\n/** The settings for a repository: the defaults, with its own entry laid over. */\nexport function projectSettings(defaults: Settings | undefined, own: Settings): Settings {\n return { ...(defaults ?? {}), ...own };\n}\n\n/** `--approver <glob>=<role>[:<quorum>]` and `--pin <tool>=<version>` laid over `base`. */\nexport function settingsFromFlags(base: Settings, approvers: readonly string[], pins: readonly string[]): { settings: Settings } | { error: string } {\n const out: Settings = structuredClone(base);\n for (const a of approvers) {\n const m = /^([^=]+)=([^:=]+)(?::(\\d+))?$/.exec(a);\n if (!m) return { error: `--approver takes <stack glob>=<role>[:<quorum>], such as 'shop/prod-*=sre:2', not '${a}'` };\n const rules = isObject(out.approval_rules) ? { ...(out.approval_rules as Settings) } : {};\n rules[m[1]!] = { role: m[2]!, ...(m[3] ? { quorum: Number(m[3]) } : {}) };\n out.approval_rules = rules;\n }\n for (const p of pins) {\n const m = /^(pulumi|plunge|image)=(.+)$/.exec(p);\n if (!m) return { error: `--pin takes pulumi=<version>, plunge=<version> or image=<ref>, not '${p}'` };\n out[m[1]!] = m[2]!;\n }\n return { settings: out };\n}\n\n/** Every value of a repeated flag, and the arguments without them. */\nfunction takeAll(args: string[], flag: string): { values: string[]; rest: string[]; missing: boolean } {\n const values: string[] = [];\n const rest: string[] = [];\n for (let i = 0; i < args.length; i++) {\n if (args[i] !== flag) {\n rest.push(args[i]!);\n continue;\n }\n const v = args[i + 1];\n if (v === undefined || v.startsWith(\"--\")) return { values, rest: args, missing: true };\n values.push(v);\n i++;\n }\n return { values, rest, missing: false };\n}\n\nfunction readYamlFile(cwd: string, file: string): Settings {\n const doc = parseYAML(readFileSync(join(cwd, file), \"utf8\"));\n if (!isObject(doc)) throw new Error(`${file} must be a mapping`);\n return doc;\n}\n\n/** `plywood control <sub> ...`. */\nexport async function control(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const [sub, ...rest] = args;\n const subs = [\"init\", \"put\", \"import\", \"list\", \"retire\", \"reconcile\", \"dispatch\"];\n if (!sub || !subs.includes(sub)) return usage(`control takes one of ${subs.join(\", \")}`, table, io);\n const chant = await chantControl();\n if (!chant) return usage(`${CONTROL_NEEDS_CHANT}. Upgrade plywood once that chant is out, or build against a local chant with 'just chant-local'.`, table, io);\n const emit = (envelope: Record<string, unknown>, lines: string[]): void => {\n if (json) io.out(JSON.stringify({ command: `control ${sub}`, ...envelope }));\n else for (const l of lines) io.out(l);\n };\n try {\n switch (sub) {\n case \"init\":\n return await controlInit(chant, rest, emit, table, io);\n case \"dispatch\":\n return await controlDispatch(chant, rest, emit, table, io);\n case \"reconcile\":\n return await controlReconcile(chant, rest, emit, table, io);\n default:\n return await controlEntries(chant, sub, rest, emit, table, io);\n }\n } catch (e) {\n io.err(`${PRODUCT} control ${sub}: ${(e as Error).message}`);\n return table.failed;\n }\n}\n\ntype Emit = (envelope: Record<string, unknown>, lines: string[]) => void;\n\n/** The forge lexicon's generateControlPipeline, from the control repo's own install. */\nasync function forgeControlPipeline(cwd: string, forge: ForgeKind): Promise<((options: { words: unknown }) => { path: string; content: string; notes: string[] }) | undefined> {\n const name = `@intentius/chant-lexicon-${forge}/components/control-pipeline`;\n try {\n const require = createRequire(join(cwd, \"package.json\"));\n const m: Record<string, unknown> = await import(pathToFileURL(require.resolve(name)).href);\n return typeof m.generateControlPipeline === \"function\" ? (m.generateControlPipeline as never) : undefined;\n } catch {\n return undefined;\n }\n}\n\nasync function controlInit(chant: ChantControl, args: string[], emit: Emit, table: ExitTable, io: StageIo): Promise<number> {\n const forgeFlag = takeFlag(args, \"--forge\");\n if (forgeFlag.missing) return usage(\"--forge takes github, gitlab or forgejo\", table, io);\n const extra = forgeFlag.rest.filter((a) => a !== \"--dry-run\");\n if (extra.length) return usage(`control init does not take ${extra.join(\" \")}`, table, io);\n const dryRun = forgeFlag.rest.includes(\"--dry-run\");\n const forge = (forgeFlag.value ?? \"github\") as ForgeKind;\n if (!(FORGES as readonly string[]).includes(forge)) return usage(`--forge ${forge} is not one of ${FORGES.join(\", \")}`, table, io);\n const generate = await forgeControlPipeline(io.cwd, forge);\n if (!generate) {\n return usage(`control init writes the control repo's workflow with @intentius/chant-lexicon-${forge}'s generateControlPipeline (chant#4568); install it in the control repo at the chant release that has it`, table, io);\n }\n const file = generate({ words: PRODUCT_WORDS });\n const path = join(io.cwd, file.path);\n const before = existsSync(path) ? readFileSync(path, \"utf8\") : undefined;\n const status = before === file.content ? \"unchanged\" : \"written\";\n if (!dryRun && status === \"written\") {\n const { mkdirSync } = await import(\"node:fs\");\n mkdirSync(dirname(path), { recursive: true });\n writeFileSync(path, file.content);\n }\n emit({ ok: true, exitCode: table.done, forge, file: file.path, status, dryRun, notes: file.notes }, [\n `${PRODUCT} control init: ${file.path} ${dryRun && status === \"written\" ? \"would be written\" : status}`,\n ...file.notes.map((n) => ` to do: ${n}`),\n ]);\n return table.done;\n}\n\nasync function controlDispatch(chant: ChantControl, args: string[], emit: Emit, table: ExitTable, io: StageIo): Promise<number> {\n const shaFlag = takeFlag(args, \"--sha\");\n if (shaFlag.missing || shaFlag.rest.length) return usage(\"control dispatch takes only --sha <commit>\", table, io);\n const sha = shaFlag.value ?? io.env.GITHUB_SHA ?? io.env.CI_COMMIT_SHA;\n if (!sha) return usage(\"control dispatch needs --sha, or GITHUB_SHA or CI_COMMIT_SHA set\", table, io);\n const target = await controlTarget(chant, io.cwd);\n if (\"error\" in target) return usage(target.error, table, io);\n const r = await chant.dispatchControl(target, { member: target.member, op: target.op, sha }, { env: io.env, words: PRODUCT_WORDS });\n emit({ ok: true, exitCode: table.done, repo: target.repo, member: target.member, op: target.op, sha, status: r.status }, [\n `${PRODUCT} control dispatch: told ${target.repo} that ${target.member} applied ${sha.slice(0, 8)} (HTTP ${r.status})`,\n ]);\n return table.done;\n}\n\n/** plywood.yml's control repo, resolved and checked by chant. */\nexport async function controlTarget(chant: ChantControl, cwd: string): Promise<Target | { error: string }> {\n const file = findConfig(cwd);\n if (!file) return { error: `no plywood.yml in ${cwd} or above it` };\n const settings = controlOf(loadConfig(file).doc);\n if (!settings) return { error: `${file} has no control key` };\n const problems = chant.controlSettingsProblems(settings);\n if (problems.length) return { error: problems.join(\"; \") };\n return chant.resolveControlTarget(settings, repoName(dirname(file)));\n}\n\nasync function controlEntries(chant: ChantControl, sub: string, args: string[], emit: Emit, table: ExitTable, io: StageIo): Promise<number> {\n const port = chant.gitControlLedger({ cwd: io.cwd });\n const byFlag = takeFlag(args, \"--by\");\n if (byFlag.missing) return usage(\"--by takes a name\", table, io);\n const dryRun = byFlag.rest.includes(\"--dry-run\");\n const opts: WriteOptions = { product: PRODUCT, validate: validateControlSettings, ...(byFlag.value ? { by: byFlag.value } : {}), ...(dryRun ? { dryRun } : {}) };\n const pushLine = dryRun ? [] : [` push it: git push origin chant/lifecycle (the control repo's ledger)`];\n let rest = byFlag.rest.filter((a) => a !== \"--dry-run\");\n\n if (sub === \"list\") {\n if (rest.length) return usage(`control list does not take ${rest.join(\" \")}`, table, io);\n const entries = await chant.readControlEntries(port, { validate: validateControlSettings });\n emit({ ok: true, exitCode: table.done, entries }, entries.length ? entries.map((e) => `${e.id} ${e.project ?? \"defaults\"} ${JSON.stringify(e.settings)}${e.estates.length ? ` estates ${e.estates.join(\", \")}` : \"\"}`) : [\"the control repo has no entries\"]);\n return table.done;\n }\n if (sub === \"retire\") {\n if (rest.length !== 1) return usage(\"control retire takes one host/owner/name\", table, io);\n const r = await chant.retireControlEntry(port, rest[0]!, opts);\n emit({ ok: true, exitCode: table.done, ...r, dryRun }, [`${PRODUCT} control retire: ${rest[0]} ${r.status} (${r.id})`, ...pushLine]);\n return table.done;\n }\n if (sub === \"import\") {\n if (rest.length !== 1) return usage(\"control import takes one file of defaults and projects\", table, io);\n const doc = readYamlFile(io.cwd, rest[0]!);\n const projects = isObject(doc.projects) ? (doc.projects as Record<string, Settings>) : {};\n const estates = isObject(doc.estates) ? (doc.estates as Record<string, string[]>) : undefined;\n const results = await chant.importControlConfig(port, { ...(isObject(doc.defaults) ? { defaults: doc.defaults } : {}), projects, ...(estates ? { estates } : {}) }, opts);\n emit({ ok: true, exitCode: table.done, results, dryRun }, [...results.map((r) => `${PRODUCT} control import: ${r.entry} ${r.status} (${r.id})`), ...pushLine]);\n return table.done;\n }\n // put\n const file = takeFlag(rest, \"--file\");\n const approvers = takeAll(file.rest, \"--approver\");\n const pins = takeAll(approvers.rest, \"--pin\");\n const estates = takeAll(pins.rest, \"--estate\");\n if (file.missing || approvers.missing || pins.missing || estates.missing) return usage(\"--file, --approver, --pin and --estate each take a value\", table, io);\n rest = positionals(estates.rest);\n if (rest.length !== 1 || estates.rest.length !== 1) return usage(\"control put takes one host/owner/name, or defaults, and its flags\", table, io);\n const which = rest[0]!;\n const entry = which === \"defaults\" ? (\"defaults\" as const) : (\"project\" as const);\n const current = (await chant.readControlEntries(port, { lenient: true })).find((e) => (entry === \"defaults\" ? e.entry === \"defaults\" : e.project === which));\n const fromFile = file.value ? readYamlFile(io.cwd, file.value) : {};\n const made = settingsFromFlags({ ...(current?.settings ?? {}), ...fromFile }, approvers.values, pins.values);\n if (\"error\" in made) return usage(made.error, table, io);\n const { settings } = made;\n const r = await chant.putControlEntry(\n port,\n { entry, ...(entry === \"project\" ? { project: which } : {}), settings, ...(estates.values.length ? { estates: estates.values } : {}) },\n { ...opts, expect: current?.digest ?? \"\" },\n );\n emit({ ok: true, exitCode: table.done, ...r, settings, dryRun }, [`${PRODUCT} control put: ${which} ${r.status} (${r.id})`, ...(r.status === \"unchanged\" ? [] : pushLine)]);\n return table.done;\n}\n\n/**\n * plywood.yml in `dir` with the control repo's keys laid over, as text, or\n * undefined when it already holds them. A plywood.yml with no other key is\n * written from those keys alone, so init fills the rest.\n */\nexport function controlledConfigText(existing: string | undefined, settings: Settings): string | undefined {\n const doc: RawConfig = existing ? parseConfig(existing).doc : {};\n const changed = CONTROLLED_KEYS.some((k) => k in settings && JSON.stringify(doc[k]) !== JSON.stringify(settings[k]));\n if (!changed && existing !== undefined) return undefined;\n const next: RawConfig = { ...doc };\n for (const k of CONTROLLED_KEYS) if (k in settings) next[k] = settings[k];\n return (\n Object.entries(next)\n .filter(([, v]) => v !== undefined)\n .map(([k, v]) => emitYAMLEntry(k, v as never))\n .join(\"\\n\") + \"\\n\"\n );\n}\n\n/** reconcile's generator: the repository's plywood.yml from its entry, then plywood init over it. */\nexport function controlGenerator(table: ExitTable, env: NodeJS.ProcessEnv): (dir: string, target: ReconcileTarget) => Promise<FileChange[]> {\n return async (dir, target) => {\n const name = CONFIG_NAMES.find((n) => existsSync(join(dir, n))) ?? \"plywood.yml\";\n const path = join(dir, name);\n const existing = existsSync(path) ? readFileSync(path, \"utf8\") : undefined;\n const text = controlledConfigText(existing, target.settings);\n const changes: FileChange[] = [];\n if (text !== undefined) {\n changes.push({ path: name, status: existing === undefined ? \"created\" : \"updated\" });\n if (!target.dryRun) writeFileSync(path, text);\n }\n if (target.dryRun && text !== undefined) return changes;\n // init over the new plywood.yml: the waves spec, the workflow and the rest follow it.\n const { runInit } = await import(\"./init\");\n const r = await runInit({ env: \"production\", bucketCheck: false, dryRun: target.dryRun, yes: true }, table, { out: () => {}, err: () => {}, cwd: dir, env });\n for (const f of r.files) {\n if (f.status === \"written\" && !changes.some((c) => c.path === f.file)) changes.push({ path: f.file, status: existsSync(join(dir, f.file)) ? \"updated\" : \"created\" });\n if (f.status === \"failed\") throw new Error(`plywood init in ${target.key}: ${f.file} ${f.note ?? \"failed\"}`);\n }\n if (!r.ok) throw new Error(`plywood init in ${target.key}: ${r.notes.at(-1) ?? \"failed\"}`);\n return changes;\n };\n}\n\nasync function controlReconcile(chant: ChantControl, args: string[], emit: Emit, table: ExitTable, io: StageIo): Promise<number> {\n const projectFlag = takeFlag(args, \"--project\");\n if (projectFlag.missing) return usage(\"--project takes host/owner/name\", table, io);\n const extra = projectFlag.rest.filter((a) => a !== \"--apply\");\n if (extra.length) return usage(`control reconcile does not take ${extra.join(\" \")}`, table, io);\n const mode = projectFlag.rest.includes(\"--apply\") ? (\"apply\" as const) : (\"dry-run\" as const);\n const entries = await chant.readControlEntries(chant.gitControlLedger({ cwd: io.cwd }), { validate: validateControlSettings });\n const { defaults, projects } = chant.controlConfig(entries);\n const list = Object.entries(projects).map(([key, own]) => ({ key, settings: projectSettings(defaults, own) }));\n const outcomes = await chant.reconcileProjects(list, {\n mode,\n words: PRODUCT_WORDS,\n generate: controlGenerator(table, io.env),\n env: io.env,\n ...(projectFlag.value ? { project: projectFlag.value } : {}),\n });\n const failed = outcomes.some((o) => o.status === \"failed\");\n const code = failed ? table.failed : table.done;\n emit({ ok: !failed, exitCode: code, mode, outcomes }, chant.describeReconcile(outcomes, mode).split(\"\\n\"));\n return code;\n}\n", "/**\n * The check and preview stages, and the workflow that runs them, on chant's\n * product pipeline (chant#4550). Every stage is chant's, run in process with\n * plywood's words (`runChantInProcess`, ruling C), so the statuses read\n * `plywood/preview/<stack>`, the note reads in stacks and previews, and an\n * exit code is chant's (chant#4553), passed through unchanged.\n *\n * plywood check plywood.yml, then chant's check stage: the\n * `ci.hooks.check` hooks at the base commit (chant#4556)\n * plywood preview chant's `components pr-plan` over the stacks the change\n * reaches, through the pulumi-up capability (chant#4541);\n * with --forge it posts the note and the statuses\n * plywood ci the workflow: productPipelineJobs checks the words\n * against the jobs, and chant's generator writes the file\n * with plywood's bin in every line\n * plywood components|ci <sub>|run|lock|unlock ...\n * chant's own verbs, for the lines the generated jobs run\n *\n * Nothing here runs pulumi, plunge or git: chant does.\n */\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { chantProduct, hasChant4607, hasChant4620, needsChantMessage, type ChantProduct, type ForgeKind, type ProductPipelineJobs } from \"./chant-product\";\nimport { toChantSettings } from \"./chant-config\";\nimport { chantNext, hasChantApprovalStatus, hasChantPullRequestApprovalStatus, hasChantPrLoopFlags, hasChantRespond, type ChantNext } from \"./chant-next\";\nimport { approvalOf } from \"./config/approval\";\nimport { configCheck } from \"./config-check\";\nimport { APPLY_REQUIRES, applyRequiresOf, applyWhenOf } from \"./config/apply\";\nimport { checkConfig, findConfig, loadConfig, type RawConfig } from \"./config/index\";\nimport { locksOf } from \"./config/locks\";\nimport { FORGES } from \"./config/routing\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { writeWorkflow } from \"./init/workflow\";\nimport { chantReviewStacks, REVIEW_STACKS_NEED_CHANT } from \"./review-stacks\";\nimport { writeWaveJobs } from \"./waves-workflow\";\nimport { writeDriftJobs } from \"./drift\";\nimport { writeReviewJobs } from \"./agents\";\nimport { writeAgentJobs } from \"./agent-jobs\";\nimport { OP_NAME, PR_GATE, PRODUCT, PRODUCT_WORDS, wordsForJobs, type ChantCommand, type ProductWordsInput } from \"./words\";\n\nexport interface StageIo {\n out: (s: string) => void;\n err: (s: string) => void;\n cwd: string;\n env: NodeJS.ProcessEnv;\n}\n\n/**\n * chant's verbs the generated jobs run through plywood's bin, `query` and\n * `ledger` for reading the ledger (plywood#20), and `audit-log` for chant's\n * audit-log reads (chant#4632: `audit-log unrecorded` lists the cloud writes\n * no recorded update made). `ci` is chant's only with a subcommand, such as\n * `ci check-job`, the apply-job guard (chant#4624).\n */\nexport const CHANT_PASSTHROUGH = [\"components\", \"run\", \"lock\", \"unlock\", \"query\", \"ledger\", \"audit-log\"] as const;\n\n/** Flags whose next argument is a value, for splitting a command line. */\nconst VALUED = new Set([\"--base\", \"--pr\", \"--forge\", \"--env\", \"--output\", \"-o\", \"--stack\", \"--file\", \"--head\", \"--gate\", \"--branch\", \"--report-url\", \"--target\"]);\n\n/** One flag's value, and the arguments without the flag. */\nexport function takeFlag(args: string[], flag: string): { value?: string; rest: string[]; missing: boolean } {\n const at = args.indexOf(flag);\n if (at < 0) return { rest: args, missing: false };\n const value = args[at + 1];\n if (value === undefined || value.startsWith(\"--\")) return { rest: args, missing: true };\n return { value, rest: [...args.slice(0, at), ...args.slice(at + 2)], missing: false };\n}\n\n/** Positional arguments: those that are neither a flag nor a flag's value. */\nexport function positionals(args: string[]): string[] {\n const out: string[] = [];\n for (let i = 0; i < args.length; i++) {\n const a = args[i]!;\n if (a.startsWith(\"-\")) {\n if (VALUED.has(a)) i++;\n continue;\n }\n out.push(a);\n }\n return out;\n}\n\nexport async function withChant(what: string, table: ExitTable, io: StageIo, run: (chant: ChantProduct) => Promise<number>): Promise<number> {\n const chant = await chantProduct();\n if (!chant) {\n io.err(`${PRODUCT}: ${needsChantMessage(what)}`);\n return table.failed;\n }\n return run(chant);\n}\n\n/** A chant verb a generated job runs through the bin: passed to chant unchanged, with plywood's words. */\nexport function passthrough(argv: string[], table: ExitTable, io: StageIo): Promise<number> {\n return withChant(`${PRODUCT} ${argv[0]}`, table, io, (chant) => chant.runChantInProcess(argv, PRODUCT_WORDS));\n}\n\n/**\n * `plywood check [--base <rev>] [<target>...] [--file <plywood.yml>] [--json]`.\n * plywood.yml first, then chant's check stage (`chant ci check`), which runs\n * the `ci.hooks.check` hooks the declaration at base names: the user's own\n * tools, such as a linter or pre-commit. A hook that fails exits with\n * chant's code. --base defaults to $BASE_SHA, as in a generated job.\n */\nexport async function check(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const file = takeFlag(args, \"--file\");\n if (file.missing) return usage(\"--file takes a path\", table, io);\n const base = takeFlag(file.rest, \"--base\");\n if (base.missing) return usage(\"--base takes a commit\", table, io);\n const r = configCheck(io.cwd, file.value);\n if (!r.ok) {\n for (const line of r.lines) io.err(line);\n return table.failed;\n }\n if (!json) for (const line of r.lines) io.err(line);\n const at = base.value ?? io.env.BASE_SHA;\n if (!at) return usage(\"check needs --base <rev>, the commit the change is measured from (or BASE_SHA); the hooks are read there, so a change cannot remove its own check\", table, io);\n const targets = positionals(base.rest);\n const output = takeFlag(base.rest, \"--output\");\n const argv = [\"ci\", \"check\", \"--base\", at, ...targets, ...(output.value ? [\"--output\", output.value] : []), ...(json ? [\"--json\"] : [])];\n return withChant(`${PRODUCT} check's hooks`, table, io, (chant) => chant.runChantInProcess(argv, PRODUCT_WORDS));\n}\n\n/**\n * `plywood preview [<stack>] [--stack <stack>] [--base <rev>] [--pr <n>]\n * [--forge github|gitlab|forgejo] [--env <env>] [--no-status] [--json]`.\n * chant's `components pr-plan` with plywood's words: it previews the stacks\n * the change reaches and the ones that depend on them, writes the report\n * and the grouped note, and with --forge posts the note and one status per\n * stack (`plywood/preview/<stack>`). A stack narrows it to that workspace\n * member. --base and --pr default to $BASE_SHA and $PR_NUMBER.\n */\nexport async function preview(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n // --target <urn> goes to pr-plan as it is (chant#4620), repeatable; a chant before it refuses it below.\n const targeted = args.includes(\"--target\");\n // --refresh and --target-dependents go to pr-plan as they are (chant#4627); a chant before it refuses them below.\n const planFlags = [\"--refresh\", \"--target-dependents\"].filter((f) => args.includes(f));\n if (args.includes(\"--target-dependents\") && !targeted) return usage(\"--target-dependents widens a --target preview to the resources that depend on the targets; give a --target\", table, io);\n for (let i = 0; i < args.length; i++) {\n if (args[i] === \"--target\" && (args[i + 1] === undefined || args[i + 1]!.startsWith(\"-\"))) return usage(\"--target takes a resource's URN\", table, io);\n }\n const stackFlag = takeFlag(args, \"--stack\");\n if (stackFlag.missing) return usage(\"--stack takes a stack name\", table, io);\n const base = takeFlag(stackFlag.rest, \"--base\");\n const pr = takeFlag(base.rest, \"--pr\");\n if (base.missing || pr.missing) return usage(`${base.missing ? \"--base\" : \"--pr\"} takes a value`, table, io);\n const named = positionals(pr.rest);\n if (named.length > 1 || (named.length === 1 && stackFlag.value)) return usage(\"preview takes one stack\", table, io);\n const stack = stackFlag.value ?? named[0];\n const at = base.value ?? io.env.BASE_SHA;\n const number = pr.value ?? io.env.PR_NUMBER;\n if (!at) return usage(\"preview needs --base <rev>, the target branch's commit (or BASE_SHA)\", table, io);\n if (!number) return usage(\"preview needs --pr <n>, the pull request its approval is recorded under (or PR_NUMBER)\", table, io);\n // A --target value is an address, never the stack: keep it out of the positionals.\n const targetValues = new Set(pr.rest.filter((_, i) => pr.rest[i - 1] === \"--target\"));\n const rest = pr.rest.filter((a) => a !== stack || targetValues.has(a));\n const gate = rest.includes(\"--gate\") ? [] : [\"--gate\", PR_GATE];\n const argv = [\"components\", \"pr-plan\", \"--base\", at, \"--pr\", number, ...gate, ...(stack ? [\"--member\", stack] : []), ...rest, ...(json ? [\"--json\"] : [])];\n return withChant(`${PRODUCT} preview`, table, io, async (chant) => {\n if (targeted && !hasChant4620(chant)) return usage(PREVIEW_TARGET_NEEDS_CHANT, table, io);\n if (planFlags.length && !(await chantNext()).planFlags) return usage(previewFlagsNeedChant(planFlags), table, io);\n return chant.runChantInProcess(argv, PRODUCT_WORDS);\n });\n}\n\n/** What `plywood preview --refresh` or `--target-dependents` says on a chant without chant#4627. */\nexport function previewFlagsNeedChant(flags: readonly string[]): string {\n return `${flags.join(\" and \")} ${flags.length === 1 ? \"needs\" : \"need\"} a chant whose pr-plan passes ${flags.length === 1 ? \"it\" : \"them\"} to the pulumi-up step (chant#4627), which this chant lacks`;\n}\n\n/** What `plywood preview --target` says on a chant without chant#4620. */\nexport const PREVIEW_TARGET_NEEDS_CHANT = \"--target needs a chant whose pr-plan passes it to the pulumi-up step (chant#4620), which this chant lacks\";\n\n/** Where `plywood ci` writes the workflow for each forge. */\nexport const WORKFLOW_FILE: Readonly<Record<ForgeKind, string>> = {\n github: \".github/workflows/plywood.yml\",\n forgejo: \".forgejo/workflows/plywood.yml\",\n gitlab: \".gitlab-ci.yml\",\n};\n\n/** The waves spec the merge applies, `.chant/op-waves/pulumi-up.spec.json`, when the repository has one. */\nexport function readWavesSpec(cwd: string): unknown {\n const file = join(cwd, \".chant/op-waves\", `${OP_NAME}.spec.json`);\n return existsSync(file) ? JSON.parse(readFileSync(file, \"utf8\")) : undefined;\n}\n\n/** What the pipeline has jobs for, from plywood.yml and the forge. */\nexport function pipelineShape(doc: RawConfig, forge: ForgeKind, waves: unknown): { jobs: ChantCommand[]; applyBeforeMerge: boolean; waves: boolean; locks?: \"plan\" } {\n const applyBeforeMerge = applyWhenOf(doc) === \"pull-request\";\n // chant's lock and unlock jobs are GitHub and Forgejo only.\n const locks = locksOf(doc).when === \"preview\" && forge !== \"gitlab\" ? (\"plan\" as const) : undefined;\n // An update before merge applies the pull request's preview in one job, so nothing applies on merge.\n const onMerge = !applyBeforeMerge && waves !== undefined;\n const jobs: ChantCommand[] = [\"plan\"];\n if (applyBeforeMerge || onMerge) jobs.push(\"apply\");\n if (locks) jobs.push(\"lock\", \"unlock\");\n return { jobs, applyBeforeMerge, waves: onMerge, ...(locks ? { locks } : {}) };\n}\n\n/**\n * `plywood ci [--forge github|gitlab|forgejo] [--env <env>] [--output <file>]\n * [--dry-run] [--json]`: the pull request workflow. productPipelineJobs\n * (chant#4550) checks plywood's words against the jobs the pipeline has\n * and names them; chant's generator (`build --components --generate\n * <forge> --pr-loop`) writes the file, run in process with the words, so\n * every line runs `npx --no-install plywood` and answers `/plywood`\n * comments. --dry-run prints the jobs and writes nothing.\n */\nexport async function ci(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const forgeFlag = takeFlag(args, \"--forge\");\n const envFlag = takeFlag(forgeFlag.rest, \"--env\");\n const outFlag = takeFlag(envFlag.rest, \"--output\");\n if (forgeFlag.missing || envFlag.missing || outFlag.missing) return usage(\"--forge, --env and --output each take a value\", table, io);\n const extra = outFlag.rest.filter((a) => a !== \"--dry-run\");\n if (extra.length) return usage(`ci does not take ${extra.join(\" \")}`, table, io);\n const dryRun = outFlag.rest.includes(\"--dry-run\");\n\n const path = findConfig(io.cwd);\n if (!path) return usage(`no plywood.yml in ${io.cwd} or above it; run '${PRODUCT} init' first`, table, io);\n const config = loadConfig(path);\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n return table.failed;\n }\n const configured = (config.doc.forge as { kind?: string } | undefined)?.kind;\n const forge = (forgeFlag.value ?? configured ?? \"github\") as ForgeKind;\n if (!(FORGES as readonly string[]).includes(forge)) return usage(`--forge ${forge} is not one of ${FORGES.join(\", \")}`, table, io);\n const env = envFlag.value ?? \"production\";\n const output = outFlag.value ?? WORKFLOW_FILE[forge];\n\n return withChant(`${PRODUCT} ci`, table, io, async (chant) => {\n const reviewStacks = await chantReviewStacks();\n if (config.doc.review_stacks !== undefined && !reviewStacks) io.err(`${PRODUCT}: ${REVIEW_STACKS_NEED_CHANT}`);\n if (applyWhenOf(config.doc) === \"pull-request\") {\n const note = requiresNotHonoured(chant, config.doc);\n if (note) io.err(`${PRODUCT}: ${note}`);\n }\n let waves: unknown;\n try {\n waves = readWavesSpec(io.cwd);\n } catch (e) {\n return usage(`.chant/op-waves/${OP_NAME}.spec.json: ${(e as Error).message}`, table, io);\n }\n // plywood#29: env, pass, parallelism and environments on the waves, and on the pull request jobs with chant#4625.\n const pipeline = toChantSettings(config).pipeline;\n const { prJobsFor, hasChant4625, withJobSettings } = await import(\"./jobs\");\n const prJobs = await prJobsFor(pipeline);\n for (const note of prJobs.notes) io.err(`${PRODUCT}: ${note}`);\n if (waves !== undefined && pipeline.jobs) {\n try {\n waves = withJobSettings(waves as Record<string, unknown>, pipeline.jobs, forge, { parallelism: await hasChant4625() });\n } catch (e) {\n io.err(`${PRODUCT}: ${(e as Error).message}`);\n return table.failed;\n }\n }\n // plywood#28: with a control repo, the note job reads its records for the cross-stack edges (chant#4619).\n const { noteControlTarget } = await import(\"./control\");\n const noteControl = await noteControlTarget(config.doc, io.cwd);\n let plan: WorkflowPlan;\n try {\n plan = workflowPlan(chant, config.doc, forge, env, waves, [], { reviewStacks, prJobs, next: await chantNext(), ...(noteControl ? { control: noteControl } : {}) });\n } catch (e) {\n io.err(`${PRODUCT}: ${(e as Error).message}`);\n return table.failed;\n }\n const { jobs } = plan;\n for (const note of plan.notes) io.err(`${PRODUCT}: ${note}`);\n // The control repo (plywood#18): with chant#4617 the waves spec takes plywood.yml's control, and chant's\n // generator adds the job that tells the control repo how the waves ended. Before it, a job of your own does.\n const { wavesControl } = await import(\"./control\");\n const control = jobs.waves ? await wavesControl(io.cwd) : ({ none: true } as const);\n if (\"error\" in control) {\n io.err(`${PRODUCT}: control: ${control.error}`);\n return table.failed;\n }\n const waveJobs = jobs.waves && \"control\" in control ? { ...jobs.waves, spec: { ...(jobs.waves.spec as Record<string, unknown>), control: control.control } } : jobs.waves;\n const summary = {\n forge,\n env,\n output,\n plan: jobs.plan.command,\n post: jobs.post.command,\n ...(jobs.record ? { record: jobs.record.command } : {}),\n ...(jobs.applyBeforeMerge ? { applyBeforeMerge: jobs.applyBeforeMerge.command } : {}),\n comments: jobs.comments,\n ...(jobs.waves ? { waves: { specFile: jobs.waves.specFile, jobs: jobs.waves.jobs.map((j) => j.command.join(\" \")) } } : {}),\n ...(\"control\" in control ? { control: control.repo } : {}),\n };\n if (json && dryRun) io.out(JSON.stringify({ command: \"ci\", ok: true, exitCode: table.done, dryRun, ...summary }));\n else if (!json) {\n io.err(`${PRODUCT} ci: ${forge} workflow at ${output}, env ${env}`);\n io.err(` preview ${summary.plan}`);\n io.err(` note ${summary.post}`);\n if (summary.record) io.err(` record ${summary.record}`);\n if (summary.applyBeforeMerge) io.err(` up ${summary.applyBeforeMerge}`);\n if (plan.jobs.post.control) io.err(` note reads the control repo's records first, for the cross-stack edges`);\n for (const [command, line] of Object.entries(jobs.comments)) io.err(` comment ${line} (${command})`);\n for (const job of summary.waves?.jobs ?? []) io.err(` wave ${job}`);\n if (jobs.stale) io.err(` stale ${jobs.stale.command} (on each push to the target branch)`);\n }\n if (!json && \"control\" in control) io.err(` control after the last wave, tells ${control.repo} how the waves ended`);\n else if (!json && \"missing\" in control) io.err(` control the waves workflow sends no dispatch: ${control.missing}; a job of your own after the last wave runs '${PRODUCT} control dispatch'`);\n if (dryRun) return table.done;\n // The pull request workflow answers /plywood up only when it updates before merge; the waves run on merge in their own workflow.\n const written = await writeWorkflow(chant, { root: io.cwd, forge, output, argv: plan.argv, words: plan.prWords, noteControl: plan.jobs.post.control });\n if (!json && written.kept.length) io.err(` kept your own jobs: ${written.kept.join(\", \")}`);\n if (written.code === table.done) for (const note of writtenNotes(plan, written.file)) io.err(`${PRODUCT}: ${note}`);\n if (json) io.out(JSON.stringify({ command: \"ci\", ok: written.code === 0, exitCode: written.code, dryRun, ...summary, status: written.status, kept: written.kept }));\n if (written.code !== table.done) {\n if (!json) io.err(`${PRODUCT} ci: chant's generator exited ${written.code} and wrote no ${output}; any file there before is back as it was`);\n return written.code;\n }\n const wavesCode = waveJobs ? await writeWaveJobs(chant, forge, waveJobs, plan.words, table, io) : table.done;\n if (wavesCode !== table.done) return wavesCode;\n // The scheduled drift jobs, when plywood.yml sets drift.schedule (plywood#8).\n const driftCode = await writeDriftJobs(chant, forge, config.doc, plan.words, table, io, env);\n if (driftCode !== table.done) return driftCode;\n // The review agent's jobs, when plywood.yml sets review (plywood#19).\n const reviewCode = await writeReviewJobs(chant, forge, config.doc, plan.words, table, io);\n if (reviewCode !== table.done) return reviewCode;\n // The agent's jobs, when plywood.yml sets agent.comment (plywood#19, chant#4616).\n return writeAgentJobs(chant, forge, env, config.doc, plan.words, table, io);\n });\n}\n\n/** What a workflow is generated from: the jobs chant names for the words, and the build argv (without --output). */\nexport interface WorkflowPlan {\n jobs: ProductPipelineJobs;\n /** The words for every job, the waves' included. */\n words: ProductWordsInput;\n /** The words of the pull request workflow: without `/plywood up` unless it updates before merge. */\n prWords: ProductWordsInput;\n argv: string[];\n /** What plywood.yml asks that this chant does not give the jobs, one line each. */\n notes: string[];\n /** The merge after an update before merge plywood asked chant's generator for (chant#4636). */\n applyMerge?: { tokenEnv: string; method?: string };\n}\n\n/**\n * Lines about the file chant's generator wrote: the merge after an update\n * before merge when `apply.merge: auto` asked for it and the file carries\n * none, since chant's `build --pr-loop` maps no merge flags before it does.\n */\nexport function writtenNotes(plan: Pick<WorkflowPlan, \"applyMerge\">, file: string): string[] {\n if (!plan.applyMerge || !existsSync(file) || readFileSync(file, \"utf8\").includes(\"--merge-token-env\")) return [];\n return [`apply.merge is auto, and chant's generator wrote the update before merge without the merge, so a person still merges after /${PRODUCT} up in CI; '${PRODUCT} up --pr <n>' run by hand merges`];\n}\n\n/**\n * The jobs and chant's build argv for plywood.yml on `forge`, shared by\n * `plywood ci` and `plywood init`. productPipelineJobs checks the words\n * against the jobs and throws when they disagree. `extra` goes on the build\n * line (`--image`, `--before-script`, from src/images.ts).\n */\nexport function workflowPlan(\n chant: ChantProduct,\n doc: RawConfig,\n forge: ForgeKind,\n env: string,\n waves: unknown,\n extra: string[] = [],\n opts: { reviewStacks?: boolean; control?: unknown; prJobs?: { options: Record<string, unknown>; flags: string[] }; next?: ChantNext } = {},\n): WorkflowPlan {\n const shape = pipelineShape(doc, forge, waves);\n const next = opts.next;\n const notes: string[] = [];\n const pipeline = toChantSettings({ doc }).pipeline;\n // chant#4628: the note names the target commit it was previewed against, and a push marks older notes stale.\n const staleNotes = next?.staleNotes === true;\n // chant#4629: the responses to a refused wave, a failed update and the description.\n const respond = respondOptions(chant, pipeline, shape.applyBeforeMerge, notes);\n // chant#4636: apply.merge: auto merges after the update before merge.\n const applyMerge = shape.applyBeforeMerge && pipeline.applyMerge ? (next?.applyMerge ? pipeline.applyMerge : (notes.push(APPLY_MERGE_NEEDS_CHANT), undefined)) : undefined;\n // chant#4630: a chant that posts plywood/approval only for pr-review waves gets the note, since plywood's waves approve\n // through the pull request (ruling B). From APPROVAL_STATUS_PULL_REQUEST_FLOOR chant posts it for those waves too.\n if (approvalOf(doc) === \"pr-review\" && shape.waves && hasChantApprovalStatus(chant) && !hasChantPullRequestApprovalStatus(chant)) notes.push(APPROVAL_STATUS_NOTE);\n const words = wordsForJobs(shape.jobs);\n // chant#4607: apply.requires reaches pr-apply --before-merge as --requires; before it, all four checks are asked.\n const requires = shape.applyBeforeMerge ? requiresArgv(chant, doc) : [];\n // chant#4620: `/plywood preview` previews the pull request again, once the installed chant has the job.\n const previewComment = hasChant4620(chant);\n const jobs = chant.productPipelineJobs(forge, env, {\n words,\n ...(shape.applyBeforeMerge ? { applyBeforeMerge: true } : {}),\n ...(shape.locks ? { locks: shape.locks } : {}),\n ...(shape.waves ? { waves } : {}),\n ...(requires.length ? { applyRequires: requires[1]!.split(\",\") } : {}),\n ...(previewComment ? { previewComment: true } : {}),\n // chant#4619: the note job's read of the control repo comes back as post.control.\n ...(opts.control !== undefined ? { control: { target: opts.control } } : {}),\n // plywood#29: runners, env, pass and parallelism on the pull request jobs, with chant#4625 (src/jobs.ts).\n ...(opts.prJobs?.options ?? {}),\n ...(staleNotes ? { staleNotes: true } : {}),\n ...respond.options,\n ...(applyMerge ? { applyMerge } : {}),\n });\n const prWords = shape.applyBeforeMerge ? words : wordsForJobs(shape.jobs.filter((j) => j !== \"apply\"));\n const argv = [\n \"build\", \".\", \"--components\", \"--generate\", forge, \"--pr-loop\", \"--env\", env, \"--gate\", jobs.words.prGate,\n ...(shape.applyBeforeMerge ? [\"--apply-before-merge\", ...requires] : []),\n ...(applyMerge ? applyMergeArgv(applyMerge) : []),\n ...respond.argv,\n ...(previewComment ? [\"--preview-comment\"] : []),\n ...(staleNotes ? [\"--stale-notes\"] : []),\n // Review stacks (plywood#15): chant's pr-env jobs, only once the pulumi lexicon can remove what they create.\n ...(doc.review_stacks !== undefined && opts.reviewStacks ? [\"--pr-env\"] : []),\n ...(opts.prJobs?.flags ?? []),\n ...extra,\n ];\n return { jobs, words, prWords, argv, notes, ...(applyMerge ? { applyMerge } : {}) };\n}\n\n/** What plywood ci says under apply.merge: auto on a chant without chant#4636. */\nexport const APPLY_MERGE_NEEDS_CHANT = \"apply.merge is auto, and the installed chant has no pr-apply --merge auto (chant#4636), so a person merges after each update before merge\";\n\n/** What plywood ci says under approval: pr-review on a chant with chant#4630 and without its pull-request floor. */\nexport const APPROVAL_STATUS_NOTE =\n `approval is pr-review, and chant posts its approval status only for waves that wait on pr-review; plywood's waves wait on the pull request's own approval, so no ${PRODUCT}/approval status is posted before merge`;\n\n/** `pr-apply --merge auto` and its token variable and method (chant#4636). */\nexport function applyMergeArgv(m: { tokenEnv: string; method?: string }): string[] {\n return [\"--merge\", \"auto\", \"--merge-token-env\", m.tokenEnv, ...(m.method ? [\"--merge-method\", m.method] : [])];\n}\n\n/** chant's responses at their defaults (`CI_RESPOND_DEFAULTS`), in chant's event order; `--respond` lists only the others. */\nexport const CHANT_RESPOND_DEFAULTS: Readonly<Record<string, string>> = Object.freeze({ \"wave-refused\": \"diff\", \"apply-failed\": \"triage\", description: \"off\" });\n\n/** What plywood ci says when the decide service is set and respond.description is not check. */\nexport const DECIDE_LEFT_OFF = \"decide is set and respond.description is not check, so plywood leaves the decide service off the pull request jobs\";\n\n/**\n * chant's `respond` and `decide` for plywood.yml's respond keys (chant#4629),\n * on a chant that has them, and the `build --pr-loop` flags that carry them\n * into the pull request jobs. chant puts the waves' part on the waves spec,\n * which plywood writes. With `PR_LOOP_BUILD_FLAGS_FLOOR` the build takes\n * `--respond <list>` and, only with `description=check`, `--decide-backend`\n * and `--decide-model`; chant refuses the decide flags without the check, so\n * plywood leaves them off then and says so, as its config check warns.\n * Before the floor the pull request jobs keep chant's defaults, and `notes`\n * says which keys that leaves out.\n */\nexport function respondOptions(\n chant: ChantProduct,\n pipeline: { respond?: Record<string, string>; decide?: { backend: string; model: string } },\n applyBeforeMerge: boolean,\n notes: string[],\n): { options: { respond?: Record<string, string>; decide?: { backend: string; model: string } }; argv: string[] } {\n const r = pipeline.respond;\n if (pipeline.decide && r?.description !== \"check\") notes.push(DECIDE_LEFT_OFF);\n if (!r || Object.keys(r).length === 0) return { options: {}, argv: [] };\n const keys = Object.keys(r).map((e) => e.replace(\"-\", \"_\"));\n if (!hasChantRespond(chant)) {\n notes.push(`respond.${keys.join(\", respond.\")} ${keys.length === 1 ? \"needs\" : \"need\"} chant's responses to pipeline events (chant#4629), which this chant lacks; chant's defaults hold`);\n return { options: {}, argv: [] };\n }\n const responses = { ...r };\n const check = responses.description === \"check\";\n const decide = check ? pipeline.decide : undefined;\n if (check && !decide) {\n // chant refuses description=check without its service; plywood's config check makes this an error first.\n delete responses.description;\n notes.push(\"respond.description is check and decide names no backend and model, so the description check is left off\");\n }\n const options = { respond: responses, ...(decide ? { decide: { ...decide } } : {}) };\n if (hasChantPrLoopFlags(chant)) return { options, argv: respondArgv(responses, decide) };\n const prSide = [\n ...(responses.description === \"check\" ? [\"respond.description\"] : []),\n ...(applyBeforeMerge && responses[\"apply-failed\"] === \"off\" ? [\"respond.apply_failed\"] : []),\n ...(applyBeforeMerge && responses[\"wave-refused\"] === \"off\" ? [\"respond.wave_refused\"] : []),\n ];\n if (prSide.length) notes.push(`${prSide.join(\", \")} ${prSide.length === 1 ? \"reaches\" : \"reach\"} no pull request job yet: chant's build --pr-loop writes no responses into them, so the note and the update before merge keep chant's defaults; the waves workflow takes wave_refused and apply_failed`);\n return { options, argv: [] };\n}\n\n/**\n * `--respond <list>` for the responses away from chant's defaults, and the\n * decide flags with `description=check` only (chant's `prLoopFlagsProblem`\n * refuses them otherwise).\n */\nexport function respondArgv(responses: Readonly<Record<string, string>>, decide: { backend: string; model: string } | undefined): string[] {\n const list = Object.keys(CHANT_RESPOND_DEFAULTS)\n .filter((e) => responses[e] !== undefined && responses[e] !== CHANT_RESPOND_DEFAULTS[e])\n .map((e) => `${e}=${responses[e]}`)\n .join(\",\");\n const check = responses.description === \"check\" && decide !== undefined;\n return [...(list ? [\"--respond\", list] : []), ...(check ? [\"--decide-backend\", decide.backend, \"--decide-model\", decide.model] : [])];\n}\n\n/**\n * `--requires <list>` for `pr-apply --before-merge` and the build that writes\n * its job (chant#4607), when plywood.yml's apply.requires names fewer than\n * the four checks and the installed chant takes the flag. Empty otherwise:\n * all four are chant's default, and a chant before chant#4607 asks all four\n * whatever plywood.yml lists ({@link requiresNotHonoured} says so).\n */\nexport function requiresArgv(chant: ChantProduct, doc: RawConfig): string[] {\n const listed = applyRequiresOf(doc);\n if (listed.length === APPLY_REQUIRES.length || !hasChant4607(chant)) return [];\n const parsed = chant.parseRequiresList!(listed);\n return \"checks\" in parsed ? [\"--requires\", parsed.checks.join(\",\")] : [];\n}\n\n/** The line a chant without `--requires` gets when plywood.yml lists fewer checks, or undefined. */\nexport function requiresNotHonoured(chant: ChantProduct, doc: RawConfig): string | undefined {\n const listed = applyRequiresOf(doc);\n if (listed.length === APPLY_REQUIRES.length || hasChant4607(chant)) return undefined;\n return `apply.requires lists ${listed.join(\", \")}, and the installed chant has no pr-apply --requires (chant#4607), so the update before merge asks all four checks: ${APPLY_REQUIRES.join(\", \")}`;\n}\n\nexport function usage(message: string, table: ExitTable, io: StageIo): number {\n // A usage error is chant's `failed`, 1 (chant#4553 ruling C).\n io.err(`${PRODUCT}: ${message}`);\n return table.failed;\n}\n", "/**\n * The plywood CLI. Each verb hands plywood's words to chant, which runs the\n * stage in process (chant#4550 ruling C). `check`, `preview` and `ci` are\n * built (src/stages.ts), and `up`, `approve` and `override` (src/up.ts);\n * and `drift` (src/drift.ts). `config check` reads plywood.yml\n * (src/config-check.ts), and `config identities` and `forge check` the\n * identities (src/identities.ts). `estate` (src/estate.ts) and `notify\n * relay` (src/notify.ts) are chant's estate and relay with plywood's words.\n * `upgrade` (src/upgrade.ts) moves the repository's plywood and chant pins\n * and writes the workflow again with the new release. chant's own verbs (`components`, `ci <sub>`, `run`,\n * `lock`, `unlock`) pass to chant unchanged with plywood's words, for the\n * lines the generated jobs run through the bin.\n *\n * Every command takes `--json`, which prints one JSON object on stdout in\n * place of the text.\n */\nimport { configCheck } from \"./config-check\";\nimport { exitCodes, type ExitTable } from \"./exit-codes\";\nimport { audit } from \"./audit\";\nimport { mcp } from \"./agents\";\nimport { drift } from \"./drift\";\nimport { estate } from \"./estate\";\nimport { notify } from \"./notify\";\nimport { useChantPolicySource } from \"./config/policy\";\nimport { guard } from \"./guard\";\nimport { configIdentities, forgeCheck } from \"./identities\";\nimport { control } from \"./control\";\nimport { applyTelemetry } from \"./telemetry\";\nimport { init, type InitIo } from \"./init\";\nimport { CHANT_PASSTHROUGH, check, ci, passthrough, preview, type StageIo } from \"./stages\";\nimport { tipById, tipLines, TIPS } from \"./tips\";\nimport { useChantInstallLines } from \"./images\";\nimport { approve, override, resume, up } from \"./up\";\nimport { upgrade } from \"./upgrade\";\nimport { cancelStack, exportStack, moveStack, rollbackStack } from \"./stack-ops\";\nimport { PRODUCT, TAGLINE, VERBS, type Verb } from \"./words\";\n\ndeclare const __PLYWOOD_VERSION__: string | undefined;\n\n/** The package version, set by scripts/build-cli.mjs. */\nexport const VERSION = typeof __PLYWOOD_VERSION__ === \"string\" ? __PLYWOOD_VERSION__ : \"0.0.0-dev\";\n\nexport interface Io {\n out: (s: string) => void;\n err: (s: string) => void;\n}\n\nconst stdio: Io = {\n out: (s) => process.stdout.write(s + \"\\n\"),\n err: (s) => process.stderr.write(s + \"\\n\"),\n};\n\nexport function helpText(): string {\n const width = Math.max(...VERBS.map((v) => v.verb.length));\n return [\n `${PRODUCT}: ${TAGLINE}`,\n \"\",\n `Usage: ${PRODUCT} <command> [--json]`,\n \"\",\n \"Commands:\",\n ...VERBS.map((v) => ` ${v.verb.padEnd(width)} ${v.summary}`),\n \"\",\n \"Setup:\",\n \" init [--preset <name>] [--gate <when>] [--engine pulumi|plunge] [--forge <kind>]\",\n \" [--env <env>] [--from <source>[=<file>]] [--no-bucket-check] [--dry-run] [--yes]\",\n \" plywood.yml, the stacks and the workflow, from the repository\",\n \" --from reads pulumi-actions, deployments, spacelift or env0 settings\",\n \" init --print-prompt the prompt that has a coding agent set plywood up\",\n \" upgrade [<version>] [--chant <version>] [--forge <kind>] [--env <env>] [--no-install] [--dry-run]\",\n \" move plywood and chant to a release, install, and write the workflow again\",\n \"\",\n \"Stages:\",\n \" check [--base <rev>] [<target>...] plywood.yml, then the check hooks at base\",\n \" preview [<stack>] [--base <rev>] [--pr <n>] [--forge <kind>] [--target <urn>]... [--target-dependents] [--refresh]\",\n \" preview the stacks the change reaches; --forge posts the note\",\n \" ci [--forge <kind>] [--env <env>] [--output <file>] [--dry-run]\",\n \" write the pull request workflow\",\n \" tips [<id>] the tips a preview can name\",\n \" up [--wave <k>] [--decide | --share <i> | --group <name>]\",\n \" run the merge's waves through the pulumi-up step\",\n \" up --pr <n> [--base <rev>] update an open pull request (apply.when: pull-request)\",\n \" resume [--op <op>] [--wave <k>] [--dry-run] start the wave jobs an approval has since cleared\",\n \" drift [<stack>...] [--resource <urn>] [--forge <kind>] [--respond issue|pull-request|up|none]\",\n \" read each stack against the cloud; --forge keeps one issue per stack\",\n \"\",\n \"Approvals:\",\n \" approve <gate> --plan <digest> [--pr <n>] [--yes] approve up (a pull request), review (its review stack) or wave-<k>;\",\n \" up finds its pull request from the digest when --pr is left out\",\n \" [--forge <kind>] [--branch <b>] then post plywood/approval again on the open pull requests into <b>\",\n \" override <stack> --rule <id>... --reason <text> override a policy denial, spent once its update runs\",\n \"\",\n \"Stack operations (each waits for a second person's approval):\",\n \" export <stack> --out <file> the stack's export, to a file on your machine\",\n \" cancel <stack> [--lock <id>] release a stuck stack lock; on file:// it reads the id\",\n \" move <urn>... --from <stack> --to <stack> move resources; both stacks preview no change\",\n \" move <stack> --onto plunge adopt the stacks onto plunge (plywood.adopt.op.ts)\",\n \" rollback <stack> [--digest <d>] | --release <name> --env <env>\",\n \" preview a release's program, then update behind its gate\",\n \"\",\n \"Ledger:\",\n \" audit [approvals|updates|runs|review-stacks] [--stack <s>] [--since <t>] [--where <f>=<v>]...\",\n \" the workspace ledger's rows, as chant ledger reads them\",\n \" query \\\"<sql>\\\" SQL over the ledger's tables (chant query)\",\n \" audit-log unrecorded --audit-log aws[:<region>] --op pulumi-up --since <time>\",\n \" the cloud writes no recorded update made (chant's audit-log)\",\n \" estate [--report-url <url>] [--prefix <p>] [--fail-overdue]\",\n \" the estate page, overdue drift checks and delivery metrics\",\n \" notify relay receive Approve clicks from Slack and Teams and record them\",\n \"\",\n \"Control repo:\",\n \" control init [--forge <kind>] in the control repo: the workflow that runs each repository's dependents\",\n \" control put <host/owner/name>|defaults [--approver <glob>=<role>[:<n>]]... [--pin <tool>=<v>]... [--file <yml>]\",\n \" one entry's approvers and pins, on the control repo's ledger\",\n \" control import <yml> | list | retire <host/owner/name>\",\n \" control reconcile [--apply] [--project <key>] each repository's plywood.yml from its entry, as a pull request\",\n \" control dispatch [--sha <sha>] tell plywood.yml's control repo this commit applied\",\n \"\",\n \"Agents:\",\n \" mcp [--report-url <url>] chant's read-only MCP server over stdio, with plywood's read tools\",\n \" guard check <command line> whether the agent guard refuses a command\",\n \" guard install [--dir <d>] the Claude Code hook and the pulumi and plunge wrappers\",\n \"\",\n \"Config:\",\n \" config check [--file <path>] check plywood.yml and print the settings in force\",\n \" config identities [--file <path>] [--env <env>]\",\n \" the preview and up identity each stack takes, per cloud\",\n \" forge check [--env <env>] [--forge <kind>] [--repo <owner/name>] [--branch <b>] [--require-clouds]\",\n \" the identities next to the forge, cloud and Pulumi Cloud setup\",\n \"\",\n \"Options:\",\n \" --json print one JSON object on stdout\",\n \" --help show this help\",\n \" --version print the version\",\n ].join(\"\\n\");\n}\n\n/** Runs one command line (without the node and script arguments) and returns its exit code. */\nexport async function main(argv: string[], io: Io = stdio): Promise<number> {\n const { table, source } = await exitCodes();\n const json = argv.includes(\"--json\");\n const args = argv.filter((a) => a !== \"--json\");\n const verb = args[0];\n const emit = (envelope: Record<string, unknown>, text: string, toErr = false): void => {\n if (json) io.out(JSON.stringify(envelope));\n else (toErr ? io.err : io.out)(text);\n };\n\n if (verb === undefined || verb === \"--help\" || verb === \"-h\" || verb === \"help\") {\n emit({ command: \"help\", ok: true, exitCode: table.done, verbs: VERBS }, helpText());\n return table.done;\n }\n if (verb === \"--version\" || verb === \"-v\") {\n emit({ command: \"version\", ok: true, exitCode: table.done, version: VERSION, exitCodes: source }, VERSION);\n return table.done;\n }\n // chant's verified install lines, when the installed pulumi lexicon has them (chant#4592); the config translation is synchronous.\n await useChantInstallLines();\n // Whether chant reads ci.policy.source and ci.policy.packs (chant#4613); the config check and translation read it.\n await useChantPolicySource();\n const stageIo: StageIo = { out: io.out, err: io.err, cwd: process.cwd(), env: process.env };\n // plywood.yml's telemetry as chant's OTEL_* variables, before the first call into chant (plywood#20).\n if (verb !== \"config\" && verb !== \"init\" && verb !== \"tips\" && verb !== \"upgrade\") await applyTelemetry(stageIo.cwd, stageIo.env);\n if (verb === \"audit\") return audit(args.slice(1), json, table, stageIo);\n if (verb === \"config\" && args[1] === \"identities\") return configIdentities(args.slice(2), json, table, stageIo);\n if (verb === \"config\") return config(args.slice(1), table, emit);\n if (verb === \"forge\") return forgeCheck(args.slice(1), json, table, stageIo);\n if (verb === \"estate\") return estate(args.slice(1), json, table, stageIo);\n if (verb === \"notify\") return notify(args.slice(1), json, table, stageIo);\n if (verb === \"control\") return control(args.slice(1), json, table, stageIo);\n if (verb === \"init\") {\n const interactive = !json && !args.includes(\"--yes\") && !args.includes(\"-y\") && process.stdin.isTTY === true && process.stderr.isTTY === true;\n const initIo: InitIo = interactive ? { ...stageIo, ask: askOnTerminal } : stageIo;\n return init(args.slice(1), json, table, initIo);\n }\n if (verb === \"upgrade\") return upgrade(args.slice(1), json, table, stageIo);\n if (verb === \"check\") return check(args.slice(1), json, table, stageIo);\n if (verb === \"preview\") return preview(args.slice(1), json, table, stageIo);\n if (verb === \"up\") return up(args.slice(1), json, table, stageIo);\n if (verb === \"resume\") return resume(args.slice(1), json, table, stageIo);\n if (verb === \"approve\") return approve(args.slice(1), json, table, stageIo);\n if (verb === \"override\") return override(args.slice(1), json, table, stageIo);\n if (verb === \"export\") return exportStack(args.slice(1), json, table, stageIo);\n if (verb === \"cancel\") return cancelStack(args.slice(1), json, table, stageIo);\n if (verb === \"move\") return moveStack(args.slice(1), json, table, stageIo);\n if (verb === \"rollback\") return rollbackStack(args.slice(1), json, table, stageIo);\n if (verb === \"drift\") return drift(args.slice(1), json, table, stageIo);\n if (verb === \"mcp\") return mcp(args.slice(1), json, table, stageIo);\n if (verb === \"guard\") return guard(args.slice(1), json, table, stageIo);\n // `plywood ci` writes the workflow; `plywood ci <sub>` is chant's `ci <sub>`, as a generated job runs it.\n if (verb === \"ci\") {\n const sub = args[1];\n return sub === undefined || sub.startsWith(\"-\") ? ci(args.slice(1), json, table, stageIo) : passthrough(argv, table, stageIo);\n }\n if ((CHANT_PASSTHROUGH as readonly string[]).includes(verb)) return passthrough(argv, table, stageIo);\n if (verb === \"tips\") return tips(args[1], table, emit);\n const known = VERBS.find((v) => v.verb === verb);\n if (!known) {\n // A usage error is chant's `failed`, 1 (chant#4553 ruling C).\n const message = `unknown command '${verb}'. Run '${PRODUCT} --help' for the commands.`;\n emit({ command: verb, ok: false, exitCode: table.failed, error: message }, `${PRODUCT}: ${message}`, true);\n return table.failed;\n }\n return notBuilt(known.verb, table.failed, emit);\n}\n\n/** A question on the terminal, answered by name or by number; Enter takes the fallback. */\nasync function askOnTerminal(question: string, choices: readonly string[], fallback: string): Promise<string> {\n const { createInterface } = await import(\"node:readline/promises\");\n const rl = createInterface({ input: process.stdin, output: process.stderr });\n try {\n for (;;) {\n const answer = (await rl.question(`${question} (${choices.map((c, i) => `${i + 1}. ${c}`).join(\", \")}) [${fallback}]: `)).trim();\n if (answer === \"\") return fallback;\n const byNumber = choices[Number(answer) - 1];\n if (byNumber) return byNumber;\n if (choices.includes(answer)) return answer;\n }\n } finally {\n rl.close();\n }\n}\n\nfunction notBuilt(\n verb: Verb,\n code: number,\n emit: (envelope: Record<string, unknown>, text: string, toErr?: boolean) => void,\n): number {\n const message = `${PRODUCT} ${verb} is not built yet.`;\n emit({ command: verb, ok: false, exitCode: code, error: message }, `${PRODUCT}: ${message}`, true);\n return code;\n}\n\n/** `plywood tips [<id>]`: every tip, or the one named. */\nfunction tips(id: string | undefined, table: ExitTable, emit: Emit): number {\n const chosen = id === undefined ? TIPS : [tipById(id)].filter((t) => t !== undefined);\n if (chosen.length === 0) {\n const message = `no tip '${id}'. The tips are ${TIPS.map((t) => t.id).join(\", \")}.`;\n emit({ command: \"tips\", ok: false, exitCode: table.failed, error: message }, `${PRODUCT}: ${message}`, true);\n return table.failed;\n }\n emit({ command: \"tips\", ok: true, exitCode: table.done, tips: chosen }, tipLines(chosen).join(\"\\n\"));\n return table.done;\n}\n\ntype Emit = (envelope: Record<string, unknown>, text: string, toErr?: boolean) => void;\n\n/** `plywood config check [--file <path>]`. A config with an error exits with chant's `failed`. */\nfunction config(args: string[], table: ExitTable, emit: Emit): number {\n const [sub, ...rest] = args;\n const command = `config ${sub ?? \"\"}`.trim();\n const fileAt = rest.indexOf(\"--file\");\n const file = fileAt >= 0 ? rest[fileAt + 1] : undefined;\n if (sub !== \"check\" || (fileAt >= 0 && !file)) {\n const message = sub !== \"check\" ? `unknown config command '${sub ?? \"\"}'. Run '${PRODUCT} config check' or '${PRODUCT} config identities'.` : \"--file takes a path\";\n emit({ command, ok: false, exitCode: table.failed, error: message }, `${PRODUCT}: ${message}`, true);\n return table.failed;\n }\n const r = configCheck(process.cwd(), file);\n const code = r.ok ? table.done : table.failed;\n emit({ command, ok: r.ok, exitCode: code, ...r.envelope }, r.lines.join(\"\\n\"), !r.ok);\n return code;\n}\n", "/**\n * The exit codes plywood leaves with. plywood owns no table: every code is\n * chant's (INTENTIUS/chant#4553), passed through unchanged.\n *\n * chant 0.124.54, the pinned release, has no exported table yet. The table\n * is imported on first use and checked for the codes plywood reads; when the\n * installed chant lacks it, FALLBACK_EXIT stands in. Its numbers are the ones\n * ruled on chant#4553 (moved is 4, a policy denial is 7, a usage or config\n * error is 1), so a chant that carries the table changes nothing a caller\n * sees. chant#4624 added 9, `misplaced`: a job guard refused a job that ran\n * outside its forge environment, branch or runner. A table from a chant\n * before it has no `misplaced`, and 9 stands in, so plywood passes the code\n * through on either.\n *\n * The `import()` carries a `@ts-ignore` so this compiles against a chant\n * without the subpath; scripts/build-cli.mjs stands in a module that throws\n * for a subpath the installed chant lacks, so the bundle builds either way.\n */\n\nexport type ExitName =\n | \"done\"\n | \"failed\"\n | \"drift\"\n | \"waiting\"\n | \"moved\"\n | \"held\"\n | \"superseded\"\n | \"denied\"\n | \"declined\"\n | \"misplaced\";\n\nexport type ExitTable = Readonly<Record<ExitName, number>>;\n\nexport const FALLBACK_EXIT: ExitTable = Object.freeze({\n done: 0,\n failed: 1,\n drift: 2,\n waiting: 3,\n moved: 4,\n held: 5,\n superseded: 6,\n denied: 7,\n declined: 8,\n misplaced: 9,\n});\n\n/** The names chant's table has carried since chant#4553; `misplaced` came later (chant#4624). */\nconst NAMES = (Object.keys(FALLBACK_EXIT) as ExitName[]).filter((n) => n !== \"misplaced\");\n\n/** True when `t` has a whole-number code for every name plywood reads; `misplaced` may be left out. */\nexport function isExitTable(t: unknown): t is ExitTable {\n if (!t || typeof t !== \"object\") return false;\n const r = t as Record<string, unknown>;\n return NAMES.every((n) => Number.isInteger(r[n])) && (r.misplaced === undefined || Number.isInteger(r.misplaced));\n}\n\n/** `t` with chant#4624's `misplaced` filled from FALLBACK_EXIT when a chant before it left it out. */\nexport function withMisplaced(t: ExitTable): ExitTable {\n return Number.isInteger((t as Partial<ExitTable>).misplaced) ? t : Object.freeze({ ...t, misplaced: FALLBACK_EXIT.misplaced });\n}\n\nlet cached: Promise<{ table: ExitTable; source: \"chant\" | \"fallback\" }> | undefined;\n\n/**\n * chant's exit-code table when the installed chant exports one as\n * `CHANT_EXIT` from `@intentius/chant/exit-codes`, else FALLBACK_EXIT.\n * `source` says which, for `plywood --version --json`.\n */\nexport function exitCodes(): Promise<{ table: ExitTable; source: \"chant\" | \"fallback\" }> {\n cached ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4553).\n const m: unknown = await import(\"@intentius/chant/exit-codes\");\n const table = (m as { CHANT_EXIT?: unknown }).CHANT_EXIT;\n if (isExitTable(table)) return { table: withMisplaced(table), source: \"chant\" as const };\n } catch {\n // The installed chant has no table: use the fallback.\n }\n return { table: FALLBACK_EXIT, source: \"fallback\" as const };\n })();\n return cached;\n}\n", "/**\n * `plywood audit [<table>] [--stack <project/stack>] [--since <time>]\n * [--where <field><op><value>]... [--at <rev>] [--json]`: one table of the\n * chant workspace ledger on `chant/lifecycle`, read by `chant ledger` in\n * process with plywood's words (chant#4551, #4363). plywood keeps no copy\n * of any row: approvals, updates, runs and review stacks are chant's\n * records, so `plywood audit --json` prints exactly what `chant ledger\n * <table> --json` prints.\n *\n * The tables, in plywood's words:\n *\n * approvals gates: each pending gate and each approval, with the\n * actor, the time and the plan digest (the default)\n * updates applies: each update under an approval, and how it ended\n * runs runs: each wave's run record\n * review-stacks pr_envs: each review stack made and removed\n *\n * Any other chant table name (`deploys`, `snapshots`, `resources`) passes as\n * written. `--stack shop/prod-east` reads the stack's project member, the\n * workspace member `plywood init` names after the project, since the ledger\n * keeps rows per member.\n */\nimport type { ExitTable } from \"./exit-codes\";\nimport { slug } from \"./init/detect\";\nimport { takeFlag, usage, withChant, type StageIo } from \"./stages\";\nimport { PRODUCT, PRODUCT_WORDS } from \"./words\";\n\n/** plywood's table words to chant's ledger tables. */\nexport const AUDIT_TABLES = { approvals: \"gates\", updates: \"applies\", runs: \"runs\", \"review-stacks\": \"pr_envs\" } as const;\nexport const DEFAULT_AUDIT_TABLE = \"approvals\";\n\n/** chant's ledger table for what a person typed. */\nexport function auditTable(word: string | undefined): string {\n const w = word ?? DEFAULT_AUDIT_TABLE;\n return (AUDIT_TABLES as Record<string, string>)[w] ?? w;\n}\n\n/** The workspace member a stack's rows are under: the slug of its project. */\nexport function auditMember(stack: string): string | undefined {\n const [project, name] = stack.split(\"/\");\n // As plywood init names the member (src/init/render.ts memberName).\n return project && name ? slug(project).slice(0, 36).replace(/-+$/, \"\") : undefined;\n}\n\n/** chant's `ledger` argv for `plywood audit`'s arguments, or the usage error. */\nexport function auditArgv(args: string[], json: boolean): string[] | { error: string } {\n const stack = takeFlag(args, \"--stack\");\n const since = takeFlag(stack.rest, \"--since\");\n const at = takeFlag(since.rest, \"--at\");\n for (const [flag, f] of [[\"--stack\", stack], [\"--since\", since], [\"--at\", at]] as const) if (f.missing) return { error: `${flag} takes a value` };\n const wheres: string[] = [];\n const rest: string[] = [];\n for (let i = 0; i < at.rest.length; i++) {\n const a = at.rest[i]!;\n if (a === \"--where\") {\n const v = at.rest[i + 1];\n if (v === undefined || v.startsWith(\"--\")) return { error: \"--where takes <field><op><value>, such as gate=wave-2\" };\n wheres.push(\"--where\", v);\n i++;\n } else rest.push(a);\n }\n const flags = rest.filter((a) => a.startsWith(\"-\"));\n if (flags.length) return { error: `audit does not take ${flags.join(\" \")}` };\n if (rest.length > 1) return { error: `audit reads one table: ${Object.keys(AUDIT_TABLES).join(\", \")}, or a chant ledger table` };\n let member: string | undefined;\n if (stack.value !== undefined) {\n member = auditMember(stack.value);\n if (!member) return { error: `--stack takes project/stack, not '${stack.value}'` };\n }\n return [\n \"ledger\", auditTable(rest[0]),\n ...(member ? [\"--member\", member] : []),\n ...(since.value ? [\"--since\", since.value] : []),\n ...wheres,\n ...(at.value ? [\"--at\", at.value] : []),\n ...(json ? [\"--json\"] : []),\n ];\n}\n\nexport async function audit(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const argv = auditArgv(args, json);\n if (\"error\" in argv) return usage(argv.error, table, io);\n return withChant(`${PRODUCT} audit`, table, io, (chant) => chant.runChantInProcess(argv, PRODUCT_WORDS));\n}\n", "/**\n * `plywood estate [--report-url <url>] [--prefix <p>] [--file <plywood.yml>]\n * [--fail-overdue] [--json]`: the estate page, the overdue drift checks and\n * the delivery metrics, read from the workspace ledger by chant\n * (`@intentius/chant/ci-estate`, chant#4612). plywood keeps no row and no\n * copy of the code: it passes its words, and its drift schedule as the\n * schedules to judge (one `plywood-drift-<stack>` Op per stack on\n * `drift.schedule`).\n *\n * With a report URL (`--report-url`, else plywood.yml's `reports.url`, chant's\n * `ci.reportUrl`) chant writes `estate.json`, `estate.html` and `dora.json`\n * under `<prefix>/` (default `estate`) through the report store\n * (chant#4554), and sends the delivery gauges (`plywood_dora_*`) when an OTLP\n * metrics endpoint is set. Without one it prints the estate and writes\n * nothing.\n *\n * The subpath is imported on first use. A chant without it (the 0.124.54\n * pin) says so and exits with chant's `failed` code; `plywood audit` reads\n * the same ledger tables there.\n */\nimport { dirname } from \"node:path\";\nimport { chantProduct } from \"./chant-product\";\nimport { toChantSettings } from \"./chant-config\";\nimport { checkConfig, ConfigError, findConfig, loadConfig, type PlywoodConfig } from \"./config/index\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { takeFlag, usage, type StageIo } from \"./stages\";\nimport { driftOpName, PRODUCT, PRODUCT_WORDS } from \"./words\";\n\n/** One schedule chant judges (`DriftSchedule`). */\nexport interface EstateSchedule {\n op: string;\n cron: string;\n}\n\n/** The part of chant's `LedgerEstate` plywood reads. */\nexport interface ChantLedgerEstate {\n estate: { totals?: Record<string, number> } & Record<string, unknown>;\n dora: Record<string, unknown>;\n overdue: Array<{ op: string; member: string; message: string }>;\n}\n\n/** What plywood calls from `@intentius/chant/ci-estate` and the report store. */\nexport interface ChantEstate {\n readEstateLedger(cwd: string, members?: readonly string[]): Promise<unknown>;\n buildLedgerEstate(input: { load: unknown; words?: unknown; schedules?: readonly EstateSchedule[]; driftOps?: readonly string[] }): ChantLedgerEstate;\n writeEstate(e: ChantLedgerEstate, options: { put: unknown; prefix?: string; words?: unknown; env?: NodeJS.ProcessEnv }): Promise<{ keys: string[]; metrics?: unknown }>;\n parseReportUrl(raw: string, name?: string): unknown;\n reportPut(target: unknown): unknown;\n}\n\nlet estateModule: Promise<ChantEstate | undefined> | undefined;\n\n/** chant's estate, or undefined when the installed chant lacks `@intentius/chant/ci-estate`. */\nexport function chantEstate(): Promise<ChantEstate | undefined> {\n estateModule ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4612).\n const m: Record<string, unknown> = await import(\"@intentius/chant/ci-estate\");\n const r: Record<string, unknown> = await import(\"@intentius/chant/pr-report-url\");\n if (![\"readEstateLedger\", \"buildLedgerEstate\", \"writeEstate\"].every((f) => typeof m[f] === \"function\")) return undefined;\n if (typeof r.parseReportUrl !== \"function\" || typeof r.reportPut !== \"function\") return undefined;\n return { ...m, parseReportUrl: r.parseReportUrl, reportPut: r.reportPut } as unknown as ChantEstate;\n } catch {\n return undefined;\n }\n })();\n return estateModule;\n}\n\n/** Tests stand in a fake chant estate (or none, for the fallback). `reset` goes back to the real import. */\nexport function setChantEstateForTests(fake: ChantEstate | undefined | \"reset\"): void {\n estateModule = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The message `plywood estate` prints on a chant without the estate. */\nexport const ESTATE_NEEDS_CHANT =\n `${PRODUCT} estate needs chant >= the release after 0.124.54, which carries @intentius/chant/ci-estate (chant#4612). ` +\n `Run '${PRODUCT} audit' for the ledger's rows on this chant.`;\n\n/** The drift Ops plywood ci writes, and their schedule, for chant to judge. */\nexport function estateSchedules(config: PlywoodConfig): { schedules: EstateSchedule[]; driftOps: string[] } {\n const drift = toChantSettings(config).pipeline.drift;\n const driftOps = (drift?.stacks ?? []).map(driftOpName);\n const schedules = drift?.schedule ? driftOps.map((op) => ({ op, cron: drift.schedule! })) : [];\n return { schedules, driftOps };\n}\n\n/** `plywood estate`. */\nexport async function estate(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const failOverdue = args.includes(\"--fail-overdue\");\n let rest = args.filter((a) => a !== \"--fail-overdue\");\n const flags: Record<string, string | undefined> = {};\n for (const flag of [\"--file\", \"--report-url\", \"--prefix\"]) {\n const f = takeFlag(rest, flag);\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n flags[flag] = f.value;\n rest = f.rest;\n }\n if (rest.length) return usage(`estate does not take ${rest.join(\" \")}`, table, io);\n const chant = await chantEstate();\n if (!chant) {\n if (json) io.out(JSON.stringify({ command: \"estate\", ok: false, exitCode: table.failed, error: ESTATE_NEEDS_CHANT }));\n else io.err(`${PRODUCT}: ${ESTATE_NEEDS_CHANT}`);\n return table.failed;\n }\n const path = flags[\"--file\"] ?? findConfig(io.cwd);\n let config: PlywoodConfig | undefined;\n if (path) {\n try {\n config = loadConfig(path);\n } catch (e) {\n return usage(e instanceof ConfigError ? e.message : `${path}: ${(e as Error).message}`, table, io);\n }\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n return table.failed;\n }\n }\n const { schedules, driftOps } = config ? estateSchedules(config) : { schedules: [], driftOps: [] };\n // chant's resolved words when it has the product pipeline; the ledger read takes the words' product, stages and noun.\n const product = await chantProduct();\n const words = product ? product.assertProductWords(PRODUCT_WORDS) : PRODUCT_WORDS;\n const root = path ? dirname(path) : io.cwd;\n const load = await chant.readEstateLedger(root);\n const built = chant.buildLedgerEstate({ load, words, schedules, ...(driftOps.length ? { driftOps } : {}) });\n\n const url = flags[\"--report-url\"] ?? (config ? toChantSettings(config).ci.reportUrl : undefined);\n let written: { keys: string[]; metrics?: unknown } | undefined;\n if (url) {\n const target = chant.parseReportUrl(url, flags[\"--report-url\"] ? \"--report-url\" : \"reports.url\");\n if (target && typeof target === \"object\" && \"error\" in target) return usage(String((target as { error: unknown }).error), table, io);\n written = await chant.writeEstate(built, { put: chant.reportPut(target), words, env: io.env, ...(flags[\"--prefix\"] ? { prefix: flags[\"--prefix\"] } : {}) });\n }\n\n const code = failOverdue && built.overdue.length > 0 ? table.failed : table.done;\n if (json) {\n io.out(JSON.stringify({ command: \"estate\", ok: code === table.done, exitCode: code, estate: built.estate, dora: built.dora, overdue: built.overdue, ...(written ? { written } : {}) }));\n return code;\n }\n const totals = built.estate.totals ?? {};\n io.out(`${PRODUCT} estate: ${Object.entries(totals).map(([k, v]) => `${v} ${k}`).join(\", \") || \"nothing on the ledger yet\"}`);\n for (const o of built.overdue) io.out(` ${o.message}`);\n if (written) io.out(` wrote ${written.keys.join(\", \")} under ${url}`);\n else io.out(` no report URL (reports.url or --report-url), so nothing was written`);\n return code;\n}\n", "/**\n * `plywood notify relay`: chant's relay (`chant notify relay`, chant#4611)\n * run in process with plywood's words. It receives an Approve click from\n * Slack or a reply in Teams on a waiting wave's message, checks the\n * platform's signature, the button's signature under the relay key, the\n * clicker against the signers file at base and the digest against the\n * standing pending gate, then records the approval on the workspace ledger\n * with `relayedBy` (`plywood-relay` unless CHANT_RELAY_PRINCIPAL says\n * otherwise). plywood.yml's `notify.relay` names the variable holding the\n * key; the relay reads it as CHANT_RELAY_KEY, with SLACK_SIGNING_SECRET or\n * TEAMS_WEBHOOK_SECRET.\n *\n * On a chant without the relay the command says so and exits with chant's\n * `failed` code.\n */\nimport type { ExitTable } from \"./exit-codes\";\nimport { usage, withChant, type StageIo } from \"./stages\";\nimport { PRODUCT, PRODUCT_WORDS } from \"./words\";\n\nexport const RELAY_NEEDS_CHANT = `${PRODUCT} notify relay needs chant >= the release after 0.124.54, which carries chant notify relay (chant#4611).`;\n\nexport async function notify(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n if (args[0] !== \"relay\") return usage(`unknown notify command '${args[0] ?? \"\"}'. Run '${PRODUCT} notify relay'.`, table, io);\n return withChant(`${PRODUCT} notify relay`, table, io, (chant) => {\n if (typeof chant.startRelayServer !== \"function\") {\n if (json) io.out(JSON.stringify({ command: \"notify relay\", ok: false, exitCode: table.failed, error: RELAY_NEEDS_CHANT }));\n else io.err(`${PRODUCT}: ${RELAY_NEEDS_CHANT}`);\n return Promise.resolve(table.failed);\n }\n return chant.runChantInProcess([\"notify\", ...args], PRODUCT_WORDS);\n });\n}\n", "/**\n * The agent guard (plywood#19): an agent session never runs `pulumi up`,\n * `plunge up` or `pulumi destroy` itself. Updates go through a pull request\n * and plywood's gates, where a person approves the digest.\n *\n * Two layers, both in packages/plywood/templates/agent-guard/:\n *\n * plywood-guard.mjs a Claude Code PreToolUse hook on Bash: it reads the\n * tool call on stdin and blocks (exit 2, Claude Code's\n * block code) a command line that would update or\n * destroy a stack\n * bin/pulumi, bin/plunge\n * wrappers put first on PATH in an agent session; with\n * PLYWOOD_AGENT_GUARD=1 (or CLAUDECODE=1) they refuse\n * the same subcommands and pass everything else to the\n * real binary further down PATH\n *\n * plywood guard check <command line> says whether the guard refuses it\n * plywood guard install [--dir <d>] writes .claude/hooks/plywood-guard.mjs\n * and its PreToolUse entry in\n * .claude/settings.json, and copies the\n * wrappers to .plywood/agent-bin\n *\n * `guardVerdict` here and `verdict` in the hook template hold one rule;\n * test/guard.test.ts holds them to the same answers.\n */\nimport { chmodSync, copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { takeFlag, usage, type StageIo } from \"./stages\";\nimport { PRODUCT } from \"./words\";\n\n/** The engines and the subcommands the guard refuses in an agent session. */\nexport const GUARDED: Readonly<Record<string, readonly string[]>> = {\n pulumi: [\"up\", \"update\", \"destroy\"],\n plunge: [\"up\", \"update\", \"destroy\"],\n};\n\n/** Global flags that take a value before the subcommand (`pulumi -C dir up`). */\nconst VALUED_GLOBALS = new Set([\"-C\", \"--cwd\", \"-s\", \"--stack\", \"--color\", \"--config-file\", \"--logflow\", \"-v\", \"--verbose\", \"--tracing\", \"--profiling\", \"--memprofilerate\"]);\n/** Words that run the next word as the command. */\nconst LAUNCHERS = new Set([\"env\", \"npx\", \"sudo\", \"command\", \"exec\", \"nohup\", \"time\", \"xargs\"]);\n\n/** Split a shell line into the simple commands it runs, roughly: on ;, &&, ||, |, newlines, $( and backticks. */\nfunction segments(line: string): string[][] {\n return line\n .split(/\\|\\||&&|[;|\\n`]|\\$\\(|\\)/)\n .map((seg) => (seg.match(/'[^']*'|\"[^\"]*\"|\\S+/g) ?? []).map((t) => t.replace(/^['\"]|['\"]$/g, \"\")))\n .filter((t) => t.length > 0);\n}\n\n/** The refusal for a command line, or undefined when the guard lets it run. */\nexport function guardVerdict(line: string): { engine: string; subcommand: string; message: string } | undefined {\n for (const words of segments(line)) {\n let i = 0;\n while (i < words.length && (LAUNCHERS.has(words[i]!) || /^[A-Za-z_][A-Za-z0-9_]*=/.test(words[i]!) || (words[i - 1] === \"env\" && words[i]!.startsWith(\"-\")))) i++;\n const bin = (words[i] ?? \"\").split(\"/\").pop()!;\n const refused = GUARDED[bin];\n if (!refused) continue;\n for (let j = i + 1; j < words.length; j++) {\n const w = words[j]!;\n if (w.startsWith(\"-\")) {\n if (VALUED_GLOBALS.has(w)) j++;\n continue;\n }\n if (refused.includes(w)) {\n return {\n engine: bin,\n subcommand: w,\n message: `${PRODUCT} guard: an agent session does not run '${bin} ${w}'. Open a pull request; ${PRODUCT} previews it, and the update runs after a person approves the digest.`,\n };\n }\n break;\n }\n }\n return undefined;\n}\n\n/** The guard's templates, shipped in the package beside dist/. */\nexport const GUARD_TEMPLATES = new URL(\"../templates/agent-guard/\", import.meta.url);\n\n/** The PreToolUse entry `plywood guard install` adds to .claude/settings.json. */\nexport const HOOK_COMMAND = 'node \"$CLAUDE_PROJECT_DIR/.claude/hooks/plywood-guard.mjs\"';\n\n/** `settings` with the guard's PreToolUse hook on Bash, added once. */\nexport function withGuardHook(settings: Record<string, unknown>): Record<string, unknown> {\n const hooks = (typeof settings.hooks === \"object\" && settings.hooks !== null ? settings.hooks : {}) as Record<string, unknown>;\n const pre = Array.isArray(hooks.PreToolUse) ? [...(hooks.PreToolUse as unknown[])] : [];\n const has = JSON.stringify(pre).includes(\"plywood-guard.mjs\");\n if (!has) pre.push({ matcher: \"Bash\", hooks: [{ type: \"command\", command: HOOK_COMMAND }] });\n return { ...settings, hooks: { ...hooks, PreToolUse: pre } };\n}\n\n/** `plywood guard check <command line>` or `plywood guard install [--dir <d>]`. */\nexport async function guard(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const [sub, ...rest] = args;\n if (sub === \"check\") {\n const line = (rest[0] === \"--\" ? rest.slice(1) : rest).join(\" \");\n if (!line.trim()) return usage(\"guard check takes the command line to check\", table, io);\n const v = guardVerdict(line);\n if (json) io.out(JSON.stringify({ command: \"guard check\", ok: !v, exitCode: v ? table.denied : table.done, refused: v ?? null }));\n else io.out(v ? v.message : `${PRODUCT} guard: '${line}' runs`);\n return v ? table.denied : table.done;\n }\n if (sub === \"install\") {\n const dirFlag = takeFlag(rest, \"--dir\");\n if (dirFlag.missing) return usage(\"--dir takes a directory\", table, io);\n if (dirFlag.rest.length) return usage(`guard install does not take ${dirFlag.rest.join(\" \")}`, table, io);\n const root = dirFlag.value ? join(io.cwd, dirFlag.value) : io.cwd;\n const written: string[] = [];\n const hookDir = join(root, \".claude/hooks\");\n mkdirSync(hookDir, { recursive: true });\n copyFileSync(new URL(\"plywood-guard.mjs\", GUARD_TEMPLATES), join(hookDir, \"plywood-guard.mjs\"));\n written.push(\".claude/hooks/plywood-guard.mjs\");\n const settingsFile = join(root, \".claude/settings.json\");\n let settings: Record<string, unknown> = {};\n if (existsSync(settingsFile)) {\n try {\n settings = JSON.parse(readFileSync(settingsFile, \"utf8\")) as Record<string, unknown>;\n } catch (e) {\n return usage(`.claude/settings.json is not JSON (${(e as Error).message}); fix it, then run this again`, table, io);\n }\n }\n writeFileSync(settingsFile, JSON.stringify(withGuardHook(settings), null, 2) + \"\\n\");\n written.push(\".claude/settings.json\");\n const binDir = join(root, \".plywood/agent-bin\");\n mkdirSync(binDir, { recursive: true });\n for (const name of Object.keys(GUARDED)) {\n const to = join(binDir, name);\n copyFileSync(new URL(`bin/${name}`, GUARD_TEMPLATES), to);\n chmodSync(to, 0o755);\n written.push(`.plywood/agent-bin/${name}`);\n }\n if (json) io.out(JSON.stringify({ command: \"guard install\", ok: true, exitCode: table.done, written }));\n else {\n for (const f of written) io.err(`${PRODUCT} guard: wrote ${f}`);\n io.err(`${PRODUCT} guard: an agent session that runs outside Claude Code puts .plywood/agent-bin first on PATH and sets PLYWOOD_AGENT_GUARD=1`);\n }\n return table.done;\n }\n return usage(`guard takes check <command line> or install [--dir <d>]`, table, io);\n}\n", "/**\n * `plywood config identities [--file <plywood.yml>] [--env <env>]` and\n * `plywood forge check`.\n *\n * `config identities` reads plywood.yml as chant will: the `ci.identity`\n * block it renders (src/config/identity.ts), and for each stack plywood.yml\n * lists, the preview and up identity each cloud gives it, first match wins,\n * with chant's own target glob (`targetGlobMatch`, @intentius/chant/ci-identity).\n * It reads nothing from a forge or a cloud.\n *\n * `forge check` holds the identities next to the forge's environments,\n * protected branches, required statuses and each cloud's trust policy,\n * Pulumi Cloud's OIDC issuer among them. The read is chant's\n * (`@intentius/chant/forge-check`, chant#4608), shared with terragucci:\n * plywood renders `ci.identity` from plywood.yml, chant's\n * `resolveCloudIdentity` gives each workspace member's trades, and\n * `pipelineContract` turns them into the jobs plywood's pipeline runs, named\n * in plywood's words (`plywood/preview/<member>` is the required status).\n * Every request is a read. plywood keeps no copy of the check.\n *\n * The subpath is imported on first use. A chant without it (the 0.124.54\n * pin) gets the message the command printed before chant#4608 and chant's\n * `failed` code.\n */\nimport type { JobSettings } from \"./config/jobs\";\nimport { environmentFor } from \"./jobs\";\nimport { existsSync, readFileSync } from \"node:fs\";\nimport { dirname, join } from \"node:path\";\nimport { targetGlobMatch } from \"@intentius/chant/ci-identity\";\nimport { toChantSettings } from \"./chant-config\";\nimport { chantIdentityOf, IDENTITY_CLOUDS, pulumiCloudOf, stackIdentities, type IdentityCloud } from \"./config/identity\";\nimport { checkConfig, ConfigError, findConfig, loadConfig, type PlywoodConfig } from \"./config/index\";\nimport { stacksOf } from \"./config/stacks\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { takeFlag, usage, type StageIo } from \"./stages\";\nimport { CLOUD_NAMES, NO_IDENTITY, PRODUCT, PRODUCT_WORDS } from \"./words\";\nimport type { ChantRunner } from \"./chant-config\";\n\nexport interface StackIdentityRow {\n stack: string;\n cloud: IdentityCloud;\n preview: string;\n up: string;\n rule: string;\n}\n\n/** Each listed stack's identities for `env`, one row per cloud that names one. */\nexport function identityRows(config: PlywoodConfig, env: string): StackIdentityRow[] {\n const doc = config.doc;\n const out: StackIdentityRow[] = [];\n for (const stack of Object.keys(stacksOf(doc))) {\n const ids = stackIdentities(doc, stack, env, targetGlobMatch);\n for (const cloud of IDENTITY_CLOUDS) {\n const id = ids[cloud];\n if (id) out.push({ stack, cloud, preview: id.preview, up: id.up, rule: id.rule });\n }\n }\n return out;\n}\n\n/** The text lines for `rows`. */\nexport function identityLines(config: PlywoodConfig, env: string, rows: readonly StackIdentityRow[]): string[] {\n const doc = config.doc;\n const block = chantIdentityOf(doc);\n if (!block) return [`${config.file ?? \"plywood.yml\"}: no identity; every job runs as ${NO_IDENTITY}`];\n const lines = [`${config.file ?? \"plywood.yml\"}: identities in environment ${env}`];\n const clouds = Object.keys(block.cloud) as IdentityCloud[];\n lines.push(` clouds ${clouds.map((c) => CLOUD_NAMES[c]).join(\", \")}`);\n if (clouds.includes(\"pulumi\")) {\n const p = pulumiCloudOf(doc);\n lines.push(` Pulumi Cloud ${p.org}${p.apiUrl ? ` at ${p.apiUrl}` : \"\"}; ESC environments open with each job's own token`);\n }\n const stacks = Object.keys(stacksOf(doc));\n if (stacks.length === 0) lines.push(\" plywood.yml lists no stacks; the rules apply to each stack plywood init finds\");\n for (const stack of stacks) {\n lines.push(` ${stack}`);\n for (const cloud of clouds) {\n const r = rows.find((x) => x.stack === stack && x.cloud === cloud);\n lines.push(r ? ` ${CLOUD_NAMES[cloud].padEnd(12)} preview ${r.preview}, up ${r.up} (${r.rule})` : ` ${CLOUD_NAMES[cloud].padEnd(12)} ${NO_IDENTITY}`);\n }\n }\n lines.push(\" The preview job trades its OIDC token before checkout, and no later step holds a forge token.\");\n return lines;\n}\n\n/** `plywood config identities [--file <path>] [--env <env>]`. */\nexport function configIdentities(args: string[], json: boolean, table: ExitTable, io: StageIo): number {\n const file = takeFlag(args, \"--file\");\n const env = takeFlag(file.rest, \"--env\");\n if (file.missing || env.missing) return usage(`${file.missing ? \"--file\" : \"--env\"} takes a value`, table, io);\n if (env.rest.length) return usage(`config identities does not take ${env.rest.join(\" \")}`, table, io);\n const path = file.value ?? findConfig(io.cwd);\n if (!path) return usage(`no plywood.yml in ${io.cwd} or above it; run '${PRODUCT} init', or pass --file`, table, io);\n let config: PlywoodConfig;\n try {\n config = loadConfig(path);\n } catch (e) {\n return usage(e instanceof ConfigError ? e.message : `${path}: ${(e as Error).message}`, table, io);\n }\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n if (json) io.out(JSON.stringify({ command: \"config identities\", ok: false, exitCode: table.failed, file: path, problems: errors }));\n return table.failed;\n }\n const environment = env.value ?? \"production\";\n const rows = identityRows(config, environment);\n if (json) io.out(JSON.stringify({ command: \"config identities\", ok: true, exitCode: table.done, file: path, env: environment, identity: toChantSettings(config).ci.identity ?? null, stacks: rows }));\n else for (const line of identityLines(config, environment, rows)) io.out(line);\n return table.done;\n}\n\n/** The message `plywood forge check` prints when the installed chant has no forge check. */\nexport const FORGE_CHECK_MESSAGE =\n `${PRODUCT} forge check holds the identities next to the forge's environments, protected branches and each cloud's trust policy. ` +\n `The read is chant's (@intentius/chant/forge-check, chant#4608), and the installed chant lacks it; it comes with the chant release after 0.124.54. Run '${PRODUCT} config identities' for what the jobs will hold.`;\n\n/** The forge plywood's jobs run on. */\ntype Forge = \"github\" | \"gitlab\" | \"forgejo\";\nconst FORGES: readonly Forge[] = [\"github\", \"gitlab\", \"forgejo\"];\n\n/** The part of chant's `ForgeTarget` plywood reads. */\nexport interface ChantForgeTarget {\n kind: Forge;\n host: string;\n repo: string;\n}\n\n/** What the forge read adds to the contract (chant `LiveRepository`). */\nexport interface ChantLiveRepository {\n defaultBranch?: string;\n path?: string;\n ownerId?: string;\n repoId?: string;\n}\n\n/** The part of chant's `ForgeCheckResult` plywood reads. */\nexport interface ChantForgeCheckResult {\n ok: boolean;\n rows: Array<{ status: string; where?: string }>;\n}\n\n/** One pipeline of chant's `pipelineContract` (`ContractPipeline`). */\nexport interface ChantContractPipeline {\n name: string;\n identity: unknown;\n member?: string;\n applyRunner?: { labels: string[]; group?: string };\n /** The forge environment the up jobs run in (plywood.yml `environments`, plywood#29). */\n forgeEnvironment?: string;\n}\n\n/** What plywood calls from `@intentius/chant/forge-check` and `resolveCloudIdentity` from ci-identity. */\nexport interface ChantForgeCheck {\n forgeCheck(\n input: { target: ChantForgeTarget; contract: (live: ChantLiveRepository) => unknown; words?: unknown; file?: string; requireClouds?: boolean },\n deps: { fetch: typeof fetch; env: NodeJS.ProcessEnv },\n ): Promise<ChantForgeCheckResult>;\n forgeCheckExit(r: ChantForgeCheckResult): number;\n describeForgeCheck(r: ChantForgeCheckResult): string;\n forgeCheckTarget(env: Record<string, string | undefined>, opts?: { kind?: Forge; repo?: string; tokenEnv?: string }): ChantForgeTarget;\n pipelineContract(input: {\n forge: Forge;\n repository: { host: string; path: string; defaultBranch: string; ownerId?: string; repoId?: string };\n pipelines: ChantContractPipeline[];\n words?: unknown;\n }): unknown;\n resolveCloudIdentity(decl: unknown, env: string, member?: string): unknown;\n}\n\nconst FORGE_CHECK_FUNCTIONS = [\"forgeCheck\", \"forgeCheckExit\", \"describeForgeCheck\", \"forgeCheckTarget\", \"pipelineContract\"] as const;\n\nlet forgeCheckModule: Promise<ChantForgeCheck | undefined> | undefined;\n\n/** chant's forge check, or undefined when the installed chant lacks it. */\nexport function chantForgeCheck(): Promise<ChantForgeCheck | undefined> {\n forgeCheckModule ??= (async () => {\n try {\n // @ts-ignore: the subpath is missing from chant 0.124.54 (chant#4608).\n const fc: Record<string, unknown> = await import(\"@intentius/chant/forge-check\");\n const id: Record<string, unknown> = await import(\"@intentius/chant/ci-identity\");\n if (!FORGE_CHECK_FUNCTIONS.every((f) => typeof fc[f] === \"function\") || typeof id.resolveCloudIdentity !== \"function\") return undefined;\n return { ...fc, resolveCloudIdentity: id.resolveCloudIdentity } as unknown as ChantForgeCheck;\n } catch {\n return undefined;\n }\n })();\n return forgeCheckModule;\n}\n\n/** Tests stand in a fake chant forge check (or none, for the fallback). `reset` goes back to the real import. */\nexport function setChantForgeCheckForTests(fake: ChantForgeCheck | undefined | \"reset\"): void {\n forgeCheckModule = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/** The workspace members `plywood init` wrote to chant.workspace.json beside plywood.yml, in order. */\nexport function workspaceMembers(root: string): string[] {\n const file = join(root, \"chant.workspace.json\");\n if (!existsSync(file)) return [];\n try {\n const doc = JSON.parse(readFileSync(file, \"utf8\")) as { members?: Array<{ name?: unknown }> };\n return (doc.members ?? []).map((m) => m.name).filter((n): n is string => typeof n === \"string\");\n } catch {\n return [];\n }\n}\n\n/** The up jobs' runner as chant's contract names it, from plywood.yml's `runner`. */\nexport function upRunner(runner: ChantRunner | undefined): { labels: string[]; group?: string } | undefined {\n if (runner === undefined) return undefined;\n const staged = typeof runner === \"object\" && !Array.isArray(runner) && !(\"group\" in runner);\n const spec = staged ? ((runner as Record<string, unknown>).up ?? (runner as Record<string, unknown>).default) : runner;\n if (spec === undefined) return undefined;\n if (typeof spec === \"string\") return { labels: [spec] };\n if (Array.isArray(spec)) return { labels: spec.filter((l): l is string => typeof l === \"string\") };\n const g = spec as { group?: unknown; labels?: unknown };\n return typeof g.group === \"string\" ? { labels: Array.isArray(g.labels) ? (g.labels as string[]) : [], group: g.group } : undefined;\n}\n\n/** One pipeline per workspace member that some rule covers in `env`, as chant's generated pipelines name them. */\nexport function contractPipelines(\n fc: Pick<ChantForgeCheck, \"resolveCloudIdentity\">,\n cloud: unknown,\n env: string,\n members: readonly string[],\n runner?: ChantRunner,\n jobs?: Pick<JobSettings, \"environments\">,\n): ChantContractPipeline[] {\n const applyRunner = upRunner(runner);\n const list: (string | undefined)[] = members.length ? [...members] : [undefined];\n return list.flatMap((member) => {\n const identity = fc.resolveCloudIdentity(cloud, env, member);\n const name = member ? `${member}/${env}` : env;\n // plywood#29: the up job's forge environment, from plywood.yml's environments, matched on <member>/<env>.\n const forgeEnvironment = jobs ? environmentFor(name, jobs)?.name : undefined;\n return identity ? [{ name, identity, ...(member ? { member } : {}), ...(applyRunner ? { applyRunner } : {}), ...(forgeEnvironment ? { forgeEnvironment } : {}) }] : [];\n });\n}\n\n/**\n * `plywood forge check [--file <path>] [--env <env>] [--forge <kind>]\n * [--repo <owner/name>] [--branch <default>] [--require-clouds]`: chant's\n * forge check over plywood.yml's identities. Exits chant's `failed` on a\n * mismatch (or, with --require-clouds, on a cloud left unchecked), `done`\n * otherwise.\n */\nexport async function forgeCheck(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n if (args[0] !== \"check\") return usage(`unknown forge command '${args[0] ?? \"\"}'. Run '${PRODUCT} forge check'.`, table, io);\n const fc = await chantForgeCheck();\n if (!fc) {\n if (json) io.out(JSON.stringify({ command: \"forge check\", ok: false, exitCode: table.failed, error: FORGE_CHECK_MESSAGE }));\n else io.err(`${PRODUCT}: ${FORGE_CHECK_MESSAGE}`);\n return table.failed;\n }\n const requireClouds = args.includes(\"--require-clouds\");\n let rest = args.slice(1).filter((a) => a !== \"--require-clouds\");\n const flags: Record<string, string | undefined> = {};\n for (const flag of [\"--file\", \"--env\", \"--forge\", \"--repo\", \"--branch\"]) {\n const f = takeFlag(rest, flag);\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n flags[flag] = f.value;\n rest = f.rest;\n }\n if (rest.length) return usage(`forge check does not take ${rest.join(\" \")}`, table, io);\n const forgeFlag = flags[\"--forge\"];\n if (forgeFlag !== undefined && !(FORGES as readonly string[]).includes(forgeFlag)) return usage(`--forge is ${forgeFlag}; give github, gitlab or forgejo`, table, io);\n const path = flags[\"--file\"] ?? findConfig(io.cwd);\n if (!path) return usage(`no plywood.yml in ${io.cwd} or above it; run '${PRODUCT} init', or pass --file`, table, io);\n let config: PlywoodConfig;\n try {\n config = loadConfig(path);\n } catch (e) {\n return usage(e instanceof ConfigError ? e.message : `${path}: ${(e as Error).message}`, table, io);\n }\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) {\n for (const p of errors) io.err(`${path}: ${p.key} ${p.message}`);\n if (json) io.out(JSON.stringify({ command: \"forge check\", ok: false, exitCode: table.failed, file: path, problems: errors }));\n return table.failed;\n }\n const settings = toChantSettings(config);\n const kind = (forgeFlag ?? settings.pipeline.forge?.kind) as Forge | undefined;\n let target: ChantForgeTarget;\n try {\n target = fc.forgeCheckTarget(io.env, { ...(kind && (FORGES as readonly string[]).includes(kind) ? { kind } : {}), ...(flags[\"--repo\"] ? { repo: flags[\"--repo\"] } : {}) });\n } catch (e) {\n return usage((e as Error).message, table, io);\n }\n const env = flags[\"--env\"] ?? \"production\";\n const cloud = settings.ci.identity?.cloud;\n const pipelines = contractPipelines(fc, cloud, env, workspaceMembers(dirname(path)), settings.pipeline.runner, settings.pipeline.jobs);\n const result = await fc.forgeCheck(\n {\n target,\n words: PRODUCT_WORDS,\n file: path,\n ...(requireClouds ? { requireClouds: true } : {}),\n contract: (live) =>\n fc.pipelineContract({\n forge: target.kind,\n repository: {\n host: target.host,\n path: live.path ?? target.repo,\n defaultBranch: flags[\"--branch\"] ?? live.defaultBranch ?? \"main\",\n ...(live.ownerId ? { ownerId: live.ownerId } : {}),\n ...(live.repoId ? { repoId: live.repoId } : {}),\n },\n pipelines,\n words: PRODUCT_WORDS,\n }),\n },\n { fetch: globalThis.fetch, env: io.env },\n );\n if (json) io.out(JSON.stringify(result));\n else io.out(fc.describeForgeCheck(result));\n if (!cloud) io.err(`${PRODUCT} forge check: ${path} sets no identity, so no trust was checked`);\n else if (pipelines.length === 0) io.err(`${PRODUCT} forge check: no identity rule covers environment ${env}, so no trust was checked`);\n return fc.forgeCheckExit(result);\n}\n", "/**\n * plywood.yml's `telemetry` as the variables chant's OTLP exporter reads\n * (chant#4555): plywood's bin sets them before its first call into chant,\n * and a variable the job already sets wins. The exporter names every span\n * attribute with plywood's words' prefix (`plywood.stack`,\n * `plywood.up.result`); when the installed chant exports `configureOtlp`,\n * the bin passes the prefix too.\n *\n * A config that cannot be read sets nothing: the command that reads it\n * reports the problem itself.\n */\nimport { chantProduct } from \"./chant-product\";\nimport { telemetryOf } from \"./config/observe\";\nimport { findConfig, loadConfig } from \"./config/index\";\nimport { PRODUCT } from \"./words\";\n\n/** The OTEL_* variables plywood.yml's telemetry adds to `env`, leaving any the job set. */\nexport function telemetryEnv(doc: Record<string, unknown>, env: NodeJS.ProcessEnv): Record<string, string> {\n const t = telemetryOf(doc);\n const out: Record<string, string> = {};\n const set = (k: string, v: string | undefined): void => {\n if (v !== undefined && v !== \"\" && env[k] === undefined) out[k] = v;\n };\n if (!t.traces) {\n set(\"OTEL_TRACES_EXPORTER\", \"none\");\n return out;\n }\n if (env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT === undefined) set(\"OTEL_EXPORTER_OTLP_ENDPOINT\", t.endpoint);\n if (t.headersEnv) set(\"OTEL_EXPORTER_OTLP_HEADERS\", env[t.headersEnv]);\n if (t.endpoint !== undefined || env.OTEL_EXPORTER_OTLP_ENDPOINT !== undefined || env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT !== undefined) set(\"OTEL_SERVICE_NAME\", t.serviceName);\n return out;\n}\n\n/** Sets plywood.yml's telemetry variables in `env` (the process's, in the bin) and configures chant's exporter with plywood's prefix. */\nexport async function applyTelemetry(cwd: string, env: NodeJS.ProcessEnv = process.env): Promise<Record<string, string>> {\n let added: Record<string, string> = {};\n try {\n const file = findConfig(cwd);\n if (file) added = telemetryEnv(loadConfig(file).doc, env);\n } catch {\n return {};\n }\n Object.assign(env, added);\n const chant = (await chantProduct()) as unknown as { configureOtlp?: (o: { prefix?: string; env?: NodeJS.ProcessEnv }) => unknown } | undefined;\n if (chant && typeof chant.configureOtlp === \"function\") chant.configureOtlp({ prefix: PRODUCT, env });\n return added;\n}\n", "/**\n * `plywood upgrade [<version>] [--chant <version>] [--no-install] [--dry-run]`\n * (plywood#23): moves a repository to another plywood release in one change\n * for one pull request.\n *\n * It reads the release from npm (the latest when no version is given) and the\n * chant that release pins, then:\n *\n * package.json @intentius/plywood to the release, and every\n * @intentius/chant and @intentius/chant-lexicon-*\n * dependency to its chant, keeping a ^ or ~ in front\n * chant.workspace.json each @intentius/chant* entry of `pins` to that chant\n * npm install so the lock file and node_modules hold both\n * plywood ci run from the new install, so the workflow names the\n * new release's image and the jobs its commands\n *\n * It writes no commit, branch or pull request: the person opens one pull\n * request with the files it lists. `--no-install` stops after the two files\n * and prints the commands left to run; `--dry-run` prints the moves and\n * writes and runs nothing but `npm view`.\n *\n * No step runs pulumi, plunge or git. npm and the new plywood run as child\n * processes through `UpgradeIo.exec`, which the tests replace.\n */\nimport { execFile } from \"node:child_process\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, relative, resolve } from \"node:path\";\nimport { findConfig, loadConfig } from \"./config/index\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { REGISTRY } from \"./images\";\nimport { takeFlag, type StageIo } from \"./stages\";\nimport { PRODUCT } from \"./words\";\n\nexport const PLYWOOD_PACKAGE = \"@intentius/plywood\";\nexport const CHANT_PACKAGE = \"@intentius/chant\";\nconst CHANT_FAMILY = /^@intentius\\/chant(?:-lexicon-[a-z0-9-]+)?$/;\nconst VERSION = /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?$/;\nconst DEP_FIELDS = [\"dependencies\", \"devDependencies\", \"optionalDependencies\"] as const;\n\nexport interface ExecResult {\n code: number;\n stdout: string;\n stderr: string;\n}\n\nexport type Exec = (bin: string, args: string[], opts: { cwd: string; env: NodeJS.ProcessEnv }) => Promise<ExecResult>;\n\nexport interface UpgradeIo extends StageIo {\n exec?: Exec;\n}\n\n/** One pin moved, as the summary and the JSON list it. */\nexport interface PinMove {\n file: string;\n name: string;\n from: string;\n to: string;\n}\n\n/** The release `npm view` describes: its version and the chant it pins. */\nexport interface ReleaseManifest {\n version: string;\n chant: string;\n}\n\nexport interface UpgradeOptions {\n version?: string;\n chant?: string;\n install: boolean;\n dryRun: boolean;\n forge?: string;\n env?: string;\n}\n\n/** Parses upgrade's flags. A bad flag is a message. */\nexport function parseUpgradeArgs(args: string[]): UpgradeOptions | { error: string } {\n const chant = takeFlag(args, \"--chant\");\n const forge = takeFlag(chant.rest, \"--forge\");\n const env = takeFlag(forge.rest, \"--env\");\n if (chant.missing || forge.missing || env.missing) return { error: \"--chant, --forge and --env each take a value\" };\n const flags = new Set([\"--no-install\", \"--dry-run\"]);\n const unknown = env.rest.filter((a) => a.startsWith(\"-\") && !flags.has(a));\n if (unknown.length) return { error: `upgrade does not take ${unknown.join(\" \")}` };\n const words = env.rest.filter((a) => !a.startsWith(\"-\"));\n if (words.length > 1) return { error: `upgrade takes one version, not ${words.join(\" \")}` };\n const version = words[0]?.replace(/^v/, \"\");\n if (version !== undefined && !VERSION.test(version)) return { error: `${words[0]} is not a version: give it as MAJOR.MINOR.PATCH` };\n if (chant.value !== undefined && !VERSION.test(chant.value)) return { error: `--chant ${chant.value} is not a version: give it as MAJOR.MINOR.PATCH` };\n return {\n ...(version ? { version } : {}),\n ...(chant.value ? { chant: chant.value } : {}),\n ...(forge.value ? { forge: forge.value } : {}),\n ...(env.value ? { env: env.value } : {}),\n install: !env.rest.includes(\"--no-install\"),\n dryRun: env.rest.includes(\"--dry-run\"),\n };\n}\n\n/** The nearest package.json at or above `dir` that depends on plywood. */\nexport function findPlywoodPackage(dir: string): string | undefined {\n let cur = resolve(dir);\n for (let depth = 0; depth < 32; depth++) {\n const file = join(cur, \"package.json\");\n if (existsSync(file)) {\n try {\n const pkg = JSON.parse(readFileSync(file, \"utf8\")) as Record<string, unknown>;\n if (DEP_FIELDS.some((f) => isObject(pkg[f]) && typeof (pkg[f] as Record<string, unknown>)[PLYWOOD_PACKAGE] === \"string\")) return file;\n } catch {\n // A package.json that is not JSON is not the one; keep looking up.\n }\n }\n const up = dirname(cur);\n if (up === cur) return undefined;\n cur = up;\n }\n return undefined;\n}\n\n/** A range with its ^ or ~ kept, moved to `version`. A tag, path or URL is left to the person. */\nexport function movedRange(range: string, version: string): string | undefined {\n const m = /^([~^]?)(\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z.-]+)?)$/.exec(range.trim());\n if (!m) return undefined;\n return `${m[1]}${version}`;\n}\n\n/** package.json with plywood and the chant family moved; the moves, and the ranges it left alone. */\nexport function movePackagePins(text: string, file: string, plywood: string, chant: string): { text: string; moves: PinMove[]; left: string[] } {\n const pkg = JSON.parse(text) as Record<string, unknown>;\n const moves: PinMove[] = [];\n const left: string[] = [];\n for (const field of DEP_FIELDS) {\n const deps = pkg[field];\n if (!isObject(deps)) continue;\n for (const [name, range] of Object.entries(deps)) {\n if (typeof range !== \"string\") continue;\n const target = name === PLYWOOD_PACKAGE ? plywood : CHANT_FAMILY.test(name) ? chant : undefined;\n if (target === undefined) continue;\n const next = movedRange(range, target);\n if (next === undefined) {\n left.push(`${field}.${name} is '${range}'; move it to ${target} by hand`);\n continue;\n }\n if (next === range) continue;\n deps[name] = next;\n moves.push({ file, name, from: range, to: next });\n }\n }\n return { text: moves.length ? jsonText(pkg, text) : text, moves, left };\n}\n\n/** chant.workspace.json with each @intentius/chant* pin moved to `chant`. */\nexport function moveDeclarationPins(text: string, file: string, chant: string): { text: string; moves: PinMove[] } {\n const doc = JSON.parse(text) as Record<string, unknown>;\n const moves: PinMove[] = [];\n const pins = Array.isArray(doc.pins) ? (doc.pins as Array<Record<string, unknown>>) : [];\n for (const pin of pins) {\n if (typeof pin.package !== \"string\" || !CHANT_FAMILY.test(pin.package) || typeof pin.version !== \"string\") continue;\n if (pin.version === chant) continue;\n moves.push({ file, name: pin.package, from: pin.version, to: chant });\n pin.version = chant;\n }\n return { text: moves.length ? jsonText(doc, text) : text, moves };\n}\n\n/** plywood.yml's `image` when it names one of plywood's own images: the release that image carries is not moved here. */\nexport function imageNote(doc: Record<string, unknown>, version: string): string | undefined {\n const image = doc.image;\n const name = typeof image === \"string\" ? image : isObject(image) && typeof image.name === \"string\" ? image.name : undefined;\n if (name === undefined) return undefined;\n const m = new RegExp(`^${REGISTRY.replace(/[.]/g, \"\\\\.\")}/plywood-(pulumi|plunge):([^@]+)`).exec(name);\n if (m && m[2].startsWith(`${version}-`)) return undefined;\n if (m) return `plywood.yml's image is plywood's ${m[1]} image at ${m[2]}; name the ${version} image in it (its tag starts ${version}-), or drop the key to take the release's own`;\n return `plywood.yml's image is your own (${name}); rebuild it FROM plywood's ${version} image and name the new digest in it`;\n}\n\n/** Reads a release, or the latest, from npm. */\nexport async function viewRelease(exec: Exec, cwd: string, env: NodeJS.ProcessEnv, version?: string): Promise<ReleaseManifest | { error: string }> {\n const spec = `${PLYWOOD_PACKAGE}@${version ?? \"latest\"}`;\n const r = await exec(\"npm\", [\"view\", spec, \"version\", \"dependencies\", \"--json\"], { cwd, env });\n if (r.code !== 0) {\n const notFound = /E404/.test(r.stderr + r.stdout);\n return { error: notFound ? `npm has no ${spec}` : `npm view ${spec} failed: ${(r.stderr || r.stdout).trim().split(\"\\n\")[0] ?? \"\"}` };\n }\n let parsed: unknown;\n try {\n parsed = JSON.parse(r.stdout);\n } catch {\n return { error: `npm view ${spec} printed no JSON` };\n }\n const doc = Array.isArray(parsed) ? parsed[parsed.length - 1] : parsed;\n if (!isObject(doc) || typeof doc.version !== \"string\") return { error: `npm view ${spec} named no version` };\n const deps = isObject(doc.dependencies) ? doc.dependencies : {};\n const chant = deps[CHANT_PACKAGE];\n if (typeof chant !== \"string\" || !VERSION.test(chant)) return { error: `${PLYWOOD_PACKAGE}@${doc.version} pins no exact ${CHANT_PACKAGE}` };\n return { version: doc.version, chant };\n}\n\n/** `plywood upgrade`. */\nexport async function upgrade(args: string[], json: boolean, table: ExitTable, io: UpgradeIo): Promise<number> {\n const opts = parseUpgradeArgs(args);\n const fail = (message: string): number => {\n if (json) io.out(JSON.stringify({ command: \"upgrade\", ok: false, exitCode: table.failed, error: message }));\n else io.err(`${PRODUCT}: ${message}`);\n return table.failed;\n };\n if (\"error\" in opts) return fail(opts.error);\n const exec = io.exec ?? execChild;\n\n const pkgFile = findPlywoodPackage(io.cwd);\n if (!pkgFile) return fail(`no package.json in ${io.cwd} or above it depends on ${PLYWOOD_PACKAGE}; install it with 'npm i -D ${PLYWOOD_PACKAGE}', then run '${PRODUCT} init'`);\n const pkgDir = dirname(pkgFile);\n const configFile = findConfig(io.cwd);\n const configDir = configFile ? dirname(configFile) : pkgDir;\n const rel = (f: string): string => relative(io.cwd, f) || f;\n\n const release = await viewRelease(exec, pkgDir, io.env, opts.version);\n if (\"error\" in release) return fail(release.error);\n const chant = opts.chant ?? release.chant;\n\n const pkgText = readFileSync(pkgFile, \"utf8\");\n const pkgMove = movePackagePins(pkgText, rel(pkgFile), release.version, chant);\n const declFile = join(configDir, \"chant.workspace.json\");\n const declText = existsSync(declFile) ? readFileSync(declFile, \"utf8\") : undefined;\n let declMove: { text: string; moves: PinMove[] } | undefined;\n if (declText !== undefined) {\n try {\n declMove = moveDeclarationPins(declText, rel(declFile), chant);\n } catch (e) {\n return fail(`${rel(declFile)} is not JSON upgrade can move pins in (${(e as Error).message})`);\n }\n }\n const notes = [...pkgMove.left];\n if (existsSync(join(configDir, \"chant.workspace.jsonc\"))) notes.push(`chant.workspace.jsonc is yours: move its @intentius/chant* pins to ${chant} by hand`);\n if (configFile) {\n try {\n const note = imageNote(loadConfig(configFile).doc as Record<string, unknown>, release.version);\n if (note) notes.push(note);\n } catch {\n // plywood ci reports a plywood.yml it cannot read.\n }\n } else {\n notes.push(`no plywood.yml, so there is no workflow to write again; run '${PRODUCT} init' after the install`);\n }\n const moves = [...pkgMove.moves, ...(declMove?.moves ?? [])];\n const ciArgs = [\"--no-install\", PRODUCT, \"ci\", ...(opts.forge ? [\"--forge\", opts.forge] : []), ...(opts.env ? [\"--env\", opts.env] : [])];\n const steps = {\n install: { cwd: rel(pkgDir) || \".\", command: \"npm install --no-audit --no-fund\" },\n ci: { cwd: rel(configDir) || \".\", command: `npx ${ciArgs.join(\" \")}` },\n };\n const envelope = { command: \"upgrade\", plywood: release.version, chant, moves, notes, dryRun: opts.dryRun };\n const say = (line: string): void => {\n if (!json) io.err(line);\n };\n\n say(`${PRODUCT} upgrade: ${PLYWOOD_PACKAGE} ${release.version}, ${CHANT_PACKAGE} ${chant}`);\n for (const m of moves) say(` ${m.file} ${m.name} ${m.from} -> ${m.to}`);\n if (moves.length === 0) say(\" every pin is already there\");\n\n if (opts.dryRun) {\n say(` then: ${steps.install.command} (in ${steps.install.cwd}), then ${steps.ci.command} (in ${steps.ci.cwd})`);\n for (const n of notes) say(` note: ${n}`);\n if (json) io.out(JSON.stringify({ ...envelope, ok: true, exitCode: table.done, steps }));\n return table.done;\n }\n\n if (pkgMove.text !== pkgText) writeFileSync(pkgFile, pkgMove.text);\n if (declMove && declText !== undefined && declMove.text !== declText) writeFileSync(declFile, declMove.text);\n const files = [...new Set(moves.map((m) => m.file))];\n\n if (!opts.install) {\n say(` left to run: ${steps.install.command} (in ${steps.install.cwd}), then ${steps.ci.command} (in ${steps.ci.cwd})`);\n for (const n of notes) say(` note: ${n}`);\n if (json) io.out(JSON.stringify({ ...envelope, ok: true, exitCode: table.done, files, steps }));\n return table.done;\n }\n\n say(` $ ${steps.install.command}`);\n const installed = await exec(\"npm\", [\"install\", \"--no-audit\", \"--no-fund\"], { cwd: pkgDir, env: io.env });\n if (installed.code !== 0) {\n for (const n of notes) say(` note: ${n}`);\n return fail(`npm install failed (exit ${installed.code}); package.json is moved, so fix the install and run '${steps.ci.command}'\\n${installed.stderr.trim()}`);\n }\n // The re-render runs the plywood npm just installed, so the workflow is the new release's.\n const got = installedVersion(pkgDir);\n if (got !== undefined && got !== release.version) notes.push(`node_modules holds ${PLYWOOD_PACKAGE} ${got}, not ${release.version}; check the install`);\n let ci: ExecResult | undefined;\n if (configFile) {\n say(` $ ${steps.ci.command}`);\n ci = await exec(\"npx\", ciArgs, { cwd: configDir, env: io.env });\n if (!json && ci.stderr.trim()) io.err(ci.stderr.trimEnd());\n }\n for (const n of notes) say(` note: ${n}`);\n const ok = ci === undefined || ci.code === 0;\n const lockFile = join(pkgDir, \"package-lock.json\");\n const changed = [...files, ...(existsSync(lockFile) ? [rel(lockFile)] : [])];\n if (ok) say(` Open one pull request with ${changed.join(\", \")} and the files ${PRODUCT} ci wrote.`);\n else say(` ${PRODUCT} ci failed (exit ${ci?.code}); the pins are moved and installed, so fix plywood.yml and run '${steps.ci.command}'`);\n const code = ok ? table.done : (ci?.code ?? table.failed);\n if (json) io.out(JSON.stringify({ ...envelope, ok, exitCode: code, files: changed, ...(ci ? { ci: { exitCode: ci.code } } : {}) }));\n return code;\n}\n\n/** The version of plywood under `dir`'s node_modules, when there is one. */\nfunction installedVersion(dir: string): string | undefined {\n try {\n const pkg = JSON.parse(readFileSync(join(dir, \"node_modules\", PLYWOOD_PACKAGE, \"package.json\"), \"utf8\")) as { version?: unknown };\n return typeof pkg.version === \"string\" ? pkg.version : undefined;\n } catch {\n return undefined;\n }\n}\n\n/** JSON as the file had it: its indent (two spaces when it has none) and a trailing newline. */\nfunction jsonText(value: unknown, original: string): string {\n const indent = /^[{[]\\r?\\n([ \\t]+)/.exec(original)?.[1] ?? \" \";\n return `${JSON.stringify(value, null, indent)}\\n`;\n}\n\nfunction isObject(v: unknown): v is Record<string, unknown> {\n return typeof v === \"object\" && v !== null && !Array.isArray(v);\n}\n\n/** Runs a child with its output captured; npm's progress goes nowhere. */\nconst execChild: Exec = (bin, args, opts) =>\n new Promise((done) => {\n execFile(bin, args, { cwd: opts.cwd, env: opts.env, maxBuffer: 64 * 1024 * 1024, shell: process.platform === \"win32\" }, (error, stdout, stderr) => {\n const code = error ? (typeof (error as { code?: unknown }).code === \"number\" ? ((error as { code: number }).code) : 1) : 0;\n done({ code, stdout: String(stdout), stderr: String(stderr) });\n });\n });\n", "/**\n * Stack operations behind a gate (plywood#16): `plywood export`, `cancel`,\n * `move` and `rollback`. plywood holds the verbs and the text; chant's\n * pulumi lexicon runs each one (chant#4578, #4542, #4562):\n *\n * plywood export <stack> --out <file>\n * gatedStackExport: a gated request `stack-export` on the workspace\n * ledger. Once a second person approves it, `stack export` runs and\n * the file lands mode 600 at --out on the requester's machine. chant\n * refuses it in CI, inside a git working tree, and over a file that\n * exists, before anything is asked.\n * plywood cancel <stack> --lock <id>\n * gatedStackCancel: `stack-cancel` of that lock id. After the approval\n * chant checks the stack still holds that lock, then runs `pulumi\n * cancel --yes`. A plunge stack is refused: plunge keeps no stack lock.\n * plywood move <urn>... --from <stack> --to <stack>\n * gatedStackMove: `stack-move`. Both stacks preview first, and the\n * move runs only when the previews change nothing but the moved\n * resources; then `pulumi state move`, or `plunge stack move` by\n * markers on plunge (plunge#56), and both stacks preview again.\n * plywood move <stack> --onto plunge\n * chant's PulumiAdoptOp (chant#4562) as `plywood init --engine plunge`\n * writes it (plywood.adopt.op.ts): `chant run plywood-adopt`, which\n * stops at each stack's gate.\n * plywood rollback <stack> [--digest <sha256:...>]\n * plywood rollback --release <name> --env <env>\n * chant components rollback (chant#4542): the release's recorded\n * program previews against the stack, the release gate binds that\n * preview, and the update runs once it is approved.\n *\n * Each request is approved with `plywood approve <gate> --op\n * pulumi-stack-ops --plan <digest>`, the line a waiting request prints, and\n * the requester runs the same command again to carry it out. The requester's\n * own approval never counts.\n *\n * Everything chant runs here is reached through a feature-detect: the pulumi\n * lexicon at plywood's pin (0.124.54) has none of it, and then each verb\n * says so and exits with chant's `failed` code.\n */\nimport { existsSync } from \"node:fs\";\nimport { dirname, isAbsolute, join, resolve } from \"node:path\";\nimport { toChantSettings, type ChantMemberSettings, type ChantQuorumRule } from \"./chant-config\";\nimport { pulumiCloudOf } from \"./config/identity\";\nimport { checkConfig, findConfig, loadConfig, type PlywoodConfig } from \"./config/index\";\nimport { stacksOf } from \"./config/stacks\";\nimport type { ExitTable } from \"./exit-codes\";\nimport { ADOPT_OP, ADOPT_OP_FILE } from \"./init/adopt\";\nimport { environmentOf, slug } from \"./init/detect\";\nimport { explainRefusal } from \"./refusals\";\nimport { positionals, takeFlag, usage, withChant, type StageIo } from \"./stages\";\nimport { BUILT_CHANT } from \"./chant-product\";\nimport { PRODUCT, PRODUCT_WORDS, STACK_OP_WORDS } from \"./words\";\n\n/** chant's op the requests are recorded under (`PULUMI_STACK_OPS_OP`). */\nexport const STACK_OPS_OP = \"pulumi-stack-ops\";\n\n/** How a gated request ended, as chant's lexicon answers (`PulumiStackOpOutcome`). */\nexport type StackOpOutcome<T> =\n | { status: \"waiting\"; digest: string; command: string }\n | { status: \"refused\"; digest: string; by: string; reason: string; command: string }\n | { status: \"spent\"; digest: string }\n | { status: \"done\"; digest: string; result: T }\n | { status: \"failed\"; digest: string; error: string };\n\n/** What every request takes (`PulumiStackOpCommon`); plywood leaves the runners to chant. */\nexport interface StackOpCommon {\n by: string;\n rules: { mode: string; quorum?: ChantQuorumRule[] };\n op?: string;\n ledgerCwd?: string;\n env?: Record<string, string | undefined>;\n}\n\nexport interface ExportResult {\n file: string;\n sha256: string;\n bytes: number;\n resources: number;\n}\n\nexport interface MoveResult {\n engine: string;\n moved: string[];\n}\n\n/** The part of chant's pulumi lexicon these verbs call (lexicons/pulumi/src/stack-ops.ts). */\nexport interface ChantStackOps {\n gatedStackExport(opts: StackOpCommon & { dir: string; stack: string; engine?: string; out: string }): Promise<StackOpOutcome<ExportResult>>;\n gatedStackCancel(opts: StackOpCommon & { dir: string; stack: string; engine?: string; lockId: string; project?: string }): Promise<StackOpOutcome<{ lockChecked: boolean }>>;\n gatedStackMove(opts: StackOpCommon & { source: { member: string; dir: string; stack: string }; dest: { member: string; dir: string; stack: string }; urns: string[]; engine?: string }): Promise<StackOpOutcome<MoveResult>>;\n}\n\nconst REQUIRED = [\"gatedStackExport\", \"gatedStackCancel\", \"gatedStackMove\"] as const;\n\n/** chant's stack lock reader (`pulumiStackLockIds`, chant#4615): the lock ids a stack holds now, read from a `file://` backend. */\nexport type ChantStackLockReader = (opts: { dir: string; stack: string; project?: string; engine?: string; env?: Record<string, string | undefined> }) => Promise<{ checked: boolean; backend?: string; ids: string[] }>;\n\nlet cachedLocks: Promise<ChantStackLockReader | undefined> | undefined;\n\n/** chant's lock reader, or undefined when the installed pulumi lexicon lacks it; `cancel` then takes the id from `--lock` alone. */\nexport function chantStackLockReader(): Promise<ChantStackLockReader | undefined> {\n cachedLocks ??= (async () => {\n try {\n // @ts-ignore: pulumiStackLockIds is newer than the lexicon at 0.124.54 (chant#4615).\n const m: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n return typeof m.pulumiStackLockIds === \"function\" ? (m.pulumiStackLockIds as ChantStackLockReader) : undefined;\n } catch {\n return undefined;\n }\n })();\n return cachedLocks;\n}\n\n/** Tests stand in a lock reader (or none, for the fallback). `reset` goes back to the real import. */\nexport function setChantStackLockReaderForTests(fake: ChantStackLockReader | undefined | \"reset\"): void {\n cachedLocks = fake === \"reset\" ? undefined : Promise.resolve(fake);\n}\n\n/**\n * The lock id `cancel` asks to release: `--lock`, else the one lock chant's\n * reader finds on the stack's `file://` backend (chant#4615). No lock, two\n * locks, or a backend the reader cannot list is an error that says which.\n */\nexport async function lockToCancel(given: string | undefined, stack: { dir: string; stack: string; project?: string; engine?: string }, env: Record<string, string | undefined>): Promise<{ lockId: string; read: boolean } | { error: string }> {\n if (given) return { lockId: given, read: false };\n const reader = await chantStackLockReader();\n if (!reader) return { error: STACK_OP_WORDS.needsLock };\n let locks: Awaited<ReturnType<ChantStackLockReader>>;\n try {\n locks = await reader({ dir: stack.dir, stack: stack.stack, ...(stack.project ? { project: stack.project } : {}), ...(stack.engine ? { engine: stack.engine } : {}), env });\n } catch (e) {\n return { error: `${STACK_OP_WORDS.needsLock}. Reading the stack's lock failed: ${(e as Error).message}` };\n }\n if (!locks.checked) return { error: STACK_OP_WORDS.lockNotListed(locks.backend) };\n if (locks.ids.length === 0) return { error: STACK_OP_WORDS.noLock(stack.stack) };\n if (locks.ids.length > 1) return { error: STACK_OP_WORDS.manyLocks(stack.stack, locks.ids) };\n return { lockId: locks.ids[0]!, read: true };\n}\n\nlet cachedOps: Promise<ChantStackOps | undefined> | undefined;\nlet cachedRollback: Promise<boolean> | undefined;\n\n/** chant's gated stack operations, or undefined when the installed pulumi lexicon lacks them. */\nexport function chantStackOps(): Promise<ChantStackOps | undefined> {\n cachedOps ??= (async () => {\n try {\n // @ts-ignore: the gated stack operations are newer than the lexicon at 0.124.54 (chant#4578).\n const m: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n return REQUIRED.every((name) => typeof m[name] === \"function\") ? (m as unknown as ChantStackOps) : undefined;\n } catch {\n return undefined;\n }\n })();\n return cachedOps;\n}\n\n/**\n * Whether the installed pulumi lexicon rolls a stack back by release: the\n * `pulumi-up` step answers `releaseInputs` (chant#4541) and a release copy\n * gets its dependencies installed before its preview (chant#4542 item 3).\n */\nexport function chantStackRollback(): Promise<boolean> {\n cachedRollback ??= (async () => {\n try {\n // @ts-ignore: pulumiReleaseInputs is newer than the lexicon at 0.124.54.\n const m: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi\");\n if (typeof m.pulumiReleaseInputs !== \"function\") return false;\n // @ts-ignore: the subpath is missing from the lexicon at 0.124.54 (chant#4542).\n const copy: Record<string, unknown> = await import(\"@intentius/chant-lexicon-pulumi/release-copy\");\n return typeof copy.prepareReleaseCopy === \"function\";\n } catch {\n return false;\n }\n })();\n return cachedRollback;\n}\n\n/** Tests stand in a fake lexicon (or none, for the fallback). `reset` goes back to the real import. */\nexport function setChantStackOpsForTests(fake: ChantStackOps | undefined | \"reset\", rollback?: boolean): void {\n cachedOps = fake === \"reset\" ? undefined : Promise.resolve(fake);\n cachedRollback = fake === \"reset\" ? undefined : Promise.resolve(rollback ?? fake !== undefined);\n}\n\n/** The message a stack operation prints when the installed lexicon lacks it. */\nexport function needsStackOpsMessage(what: string, feature: string): string {\n return (\n `${what} needs @intentius/chant-lexicon-pulumi >= the release after 0.124.54, which carries ${feature}. ` +\n `This plywood was built with chant ${BUILT_CHANT}, which lacks it. ` +\n \"Upgrade plywood once that chant is out, or build against a local chant with 'just chant-local'.\"\n );\n}\n\n/** A stack as a request names it: plywood.yml's key, its directory, and the `--stack` the engine takes. */\nexport interface ResolvedStack {\n key: string;\n project: string;\n stack: string;\n dir: string;\n engine?: \"pulumi\" | \"plunge\";\n backend?: string;\n}\n\n/** The config around `cwd`, checked; an error names the first problem. */\nexport function readConfig(cwd: string): { config: PlywoodConfig; path: string } | { error: string } {\n const path = findConfig(cwd);\n if (!path) return { error: `no plywood.yml in ${cwd} or above it; run '${PRODUCT} init' first` };\n const config = loadConfig(path);\n const errors = checkConfig(config).filter((p) => p.severity === \"error\");\n if (errors.length) return { error: errors.map((p) => `${path}: ${p.key} ${p.message}`).join(\"\\n\") };\n return { config, path };\n}\n\n/** The stack `key` names (`project/stack`), from plywood.yml's stacks, or `dir` when given. */\nexport function resolveStack(config: PlywoodConfig, path: string, key: string, dir?: string): ResolvedStack | { error: string } {\n const [project, stack, extra] = key.split(\"/\");\n if (!project || !stack || extra !== undefined) return { error: `a stack is project/stack, as plywood.yml lists it, not '${key}'` };\n const settings = toChantSettings(config);\n const listed = stacksOf(config.doc);\n const root = dirname(path);\n const member: Partial<ChantMemberSettings> = settings.members.find((m) => m.name === key) ?? settings.memberDefaults;\n if (dir === undefined && Object.keys(listed).length > 0 && !(key in listed)) {\n return { error: `${key} is not under stacks in ${path}; the stacks are ${Object.keys(listed).join(\", \")} (or name its directory with --dir)` };\n }\n const at = dir ?? listed[key]?.dir ?? \".\";\n return {\n key,\n project,\n stack,\n dir: isAbsolute(at) ? at : resolve(root, at),\n ...(member.engine ? { engine: member.engine } : {}),\n ...(member.backend ? { backend: member.backend } : {}),\n };\n}\n\n/** Which approvals count for a request: plywood.yml's `approval` and `approval_rules`, as chant reads them. */\nexport function requestRules(config: PlywoodConfig): StackOpCommon[\"rules\"] {\n const p = toChantSettings(config).pipeline;\n return { mode: p.approval ?? \"ledger\", ...(p.quorum?.length ? { quorum: p.quorum } : {}) };\n}\n\n/** Who asks: --by, else the name chant's approve would record (the forge's actor, else the user). */\nexport function requesterOf(by: string | undefined, env: NodeJS.ProcessEnv): string {\n return by ?? env.GITHUB_ACTOR ?? env.GITLAB_USER_LOGIN ?? env.USER ?? \"unknown\";\n}\n\n/**\n * The destination as `pulumi state move --dest` takes it: the bare stack in\n * the same project, else fully qualified. A DIY backend's organization is\n * always `organization`; on Pulumi Cloud it is plywood.yml's pulumi_cloud.org.\n */\nexport function destStackName(source: ResolvedStack, dest: ResolvedStack, config: PlywoodConfig): string {\n if (dest.project === source.project) return dest.stack;\n const cloud = !dest.backend || /^https?:\\/\\//.test(dest.backend);\n const org = cloud ? pulumiCloudOf(config.doc).org : undefined;\n return `${org ?? \"organization\"}/${dest.project}/${dest.stack}`;\n}\n\n/** The line that approves a waiting request, in plywood's words. */\nexport function approveRequestLine(gate: string, digest: string, mode: string): string {\n return `${PRODUCT} approve ${gate} --op ${STACK_OPS_OP} --plan ${digest}${mode === \"sealed\" ? \" --sign\" : \"\"}`;\n}\n\n/** The backend a stack names, for the engine's run, when the environment names none. */\nfunction useBackend(stacks: ResolvedStack[], env: NodeJS.ProcessEnv): string | undefined {\n const named = [...new Set(stacks.map((s) => s.backend).filter((b): b is string => b !== undefined))];\n if (named.length > 1) return `the stacks are on different backends (${named.join(\", \")}); a move needs both on one backend`;\n if (named[0] && !env.PULUMI_BACKEND_URL) env.PULUMI_BACKEND_URL = named[0];\n return undefined;\n}\n\ntype Verb = \"export\" | \"cancel\" | \"move\";\n\n/** Print what a request's outcome means, and return chant's code for it. */\nexport function reportOutcome<T>(\n verb: Verb,\n outcome: StackOpOutcome<T>,\n gate: string,\n rules: StackOpCommon[\"rules\"],\n done: (result: T) => string,\n json: boolean,\n table: ExitTable,\n io: StageIo,\n): number {\n const approveLine = outcome.status === \"waiting\" || outcome.status === \"refused\" ? approveRequestLine(gate, outcome.digest, rules.mode) : undefined;\n let code: number;\n let text: string;\n switch (outcome.status) {\n case \"waiting\":\n code = table.waiting;\n text = STACK_OP_WORDS.waiting(verb, approveLine!);\n break;\n case \"refused\":\n code = table.waiting;\n text = `${outcome.reason}. ${STACK_OP_WORDS.waiting(verb, approveLine!)}`;\n break;\n case \"spent\":\n code = table.failed;\n text = STACK_OP_WORDS.spent(verb);\n break;\n case \"done\":\n code = table.done;\n text = done(outcome.result);\n break;\n case \"failed\":\n code = table.failed;\n text = `${PRODUCT} ${verb}: ${outcome.error}`;\n break;\n }\n if (json) {\n io.out(JSON.stringify({\n command: verb, ok: code === table.done, exitCode: code, status: outcome.status, op: STACK_OPS_OP, gate, digest: outcome.digest,\n ...(approveLine ? { approve: approveLine } : {}),\n ...(outcome.status === \"done\" ? { result: outcome.result } : {}),\n ...(outcome.status === \"failed\" ? { error: outcome.error } : {}),\n ...(outcome.status === \"refused\" ? { refusedBy: outcome.by, reason: outcome.reason } : {}),\n }));\n } else (code === table.done ? io.out : io.err)(text);\n return code;\n}\n\n/** Run one request, turning a refusal chant throws before asking into chant's `failed`. */\nasync function runRequest(verb: Verb, json: boolean, table: ExitTable, io: StageIo, call: (ops: ChantStackOps) => Promise<number>): Promise<number> {\n const ops = await chantStackOps();\n if (!ops) {\n io.err(`${PRODUCT}: ${needsStackOpsMessage(`${PRODUCT} ${verb}`, \"the gated stack operations (chant#4578)\")}`);\n return table.failed;\n }\n try {\n return await call(ops);\n } catch (e) {\n const message = (e as Error).message;\n if (json) io.out(JSON.stringify({ command: verb, ok: false, exitCode: table.failed, error: message }));\n else io.err(`${PRODUCT} ${verb}: ${message}`);\n return table.failed;\n }\n}\n\n/** --by, --dir: the flags every request takes. */\nfunction commonFlags(args: string[]): { by?: string; dir?: string; rest: string[]; missing?: string } {\n const by = takeFlag(args, \"--by\");\n const dir = takeFlag(by.rest, \"--dir\");\n if (by.missing) return { rest: args, missing: \"--by\" };\n if (dir.missing) return { rest: args, missing: \"--dir\" };\n return { by: by.value, dir: dir.value, rest: dir.rest };\n}\n\n/** `plywood export <stack> --out <file> [--by <name>] [--dir <path>] [--json]`. */\nexport async function exportStack(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const common = commonFlags(args);\n if (common.missing) return usage(`${common.missing} takes a value`, table, io);\n const out = takeFlag(common.rest, \"--out\");\n if (out.missing) return usage(\"--out takes a file path outside the repository\", table, io);\n const extra = out.rest.filter((a) => a.startsWith(\"-\"));\n if (extra.length) return usage(`export does not take ${extra.join(\" \")}`, table, io);\n const named = positionals(out.rest);\n if (named.length !== 1) return usage(`export takes one stack: ${STACK_OP_WORDS.usage.export}`, table, io);\n if (!out.value) return usage(`export needs --out <file>, a path on your machine outside every git working tree: ${STACK_OP_WORDS.usage.export}`, table, io);\n const read = readConfig(io.cwd);\n if (\"error\" in read) return usage(read.error, table, io);\n const stack = resolveStack(read.config, read.path, named[0]!, common.dir);\n if (\"error\" in stack) return usage(stack.error, table, io);\n useBackend([stack], io.env);\n const rules = requestRules(read.config);\n const outFile = resolve(io.cwd, out.value);\n return runRequest(\"export\", json, table, io, async (ops) => {\n const outcome = await ops.gatedStackExport({\n by: requesterOf(common.by, io.env), rules, op: STACK_OPS_OP, ledgerCwd: io.cwd, env: io.env,\n dir: stack.dir, stack: stack.stack, out: outFile, ...(stack.engine ? { engine: stack.engine } : {}),\n });\n return reportOutcome(\"export\", outcome, stack.stack, rules, (r) => STACK_OP_WORDS.exported(stack.key, r), json, table, io);\n });\n}\n\n/** `plywood cancel <stack> --lock <id> [--by <name>] [--dir <path>] [--json]`. */\nexport async function cancelStack(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const common = commonFlags(args);\n if (common.missing) return usage(`${common.missing} takes a value`, table, io);\n const lock = takeFlag(common.rest, \"--lock\");\n if (lock.missing) return usage(\"--lock takes the lock id\", table, io);\n const extra = lock.rest.filter((a) => a.startsWith(\"-\"));\n if (extra.length) return usage(`cancel does not take ${extra.join(\" \")}`, table, io);\n const named = positionals(lock.rest);\n if (named.length !== 1) return usage(`cancel takes one stack: ${STACK_OP_WORDS.usage.cancel}`, table, io);\n const read = readConfig(io.cwd);\n if (\"error\" in read) return usage(read.error, table, io);\n const stack = resolveStack(read.config, read.path, named[0]!, common.dir);\n if (\"error\" in stack) return usage(stack.error, table, io);\n useBackend([stack], io.env);\n // chant#4615: with no --lock, the one lock a file:// backend holds for the stack.\n const lockId = await lockToCancel(lock.value, stack, io.env);\n if (\"error\" in lockId) return usage(lockId.error, table, io);\n if (lockId.read && !json) io.err(`${PRODUCT} cancel: ${stack.key} holds lock ${lockId.lockId}`);\n const rules = requestRules(read.config);\n return runRequest(\"cancel\", json, table, io, async (ops) => {\n const outcome = await ops.gatedStackCancel({\n by: requesterOf(common.by, io.env), rules, op: STACK_OPS_OP, ledgerCwd: io.cwd, env: io.env,\n dir: stack.dir, stack: stack.stack, lockId: lockId.lockId, project: stack.project, ...(stack.engine ? { engine: stack.engine } : {}),\n });\n return reportOutcome(\"cancel\", outcome, stack.stack, rules, (r) => STACK_OP_WORDS.cancelled(stack.key, lockId.lockId, r.lockChecked), json, table, io);\n });\n}\n\n/**\n * `plywood move <urn>... --from <stack> --to <stack> [--by <name>] [--json]`,\n * or `plywood move <stack> --onto plunge`.\n */\nexport async function moveStack(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const onto = takeFlag(args, \"--onto\");\n if (onto.missing) return usage(\"--onto takes plunge\", table, io);\n if (onto.value !== undefined) return moveOntoPlunge(onto.value, onto.rest, json, table, io);\n\n const common = commonFlags(onto.rest);\n if (common.missing) return usage(`${common.missing} takes a value`, table, io);\n const from = takeFlag(common.rest, \"--from\");\n const to = takeFlag(from.rest, \"--to\");\n if (from.missing || to.missing) return usage(`${from.missing ? \"--from\" : \"--to\"} takes a stack, as project/stack`, table, io);\n const extra = to.rest.filter((a) => a.startsWith(\"-\"));\n if (extra.length) return usage(`move does not take ${extra.join(\" \")}`, table, io);\n if (common.dir !== undefined) return usage(\"move reads each stack's directory from plywood.yml's stacks, so it does not take --dir\", table, io);\n const urns = positionals(to.rest);\n if (!from.value || !to.value) return usage(`move needs --from and --to: ${STACK_OP_WORDS.usage.move}`, table, io);\n if (urns.length === 0) return usage(`move names each resource it moves by URN: ${STACK_OP_WORDS.usage.move}`, table, io);\n const bad = urns.filter((u) => !u.startsWith(\"urn:pulumi:\"));\n if (bad.length) return usage(`move takes URNs (urn:pulumi:...), not ${bad.join(\", \")}; 'pulumi stack --show-urns' lists them`, table, io);\n if (from.value === to.value) return usage(`--from and --to are both ${from.value}; a move is between two stacks`, table, io);\n\n const read = readConfig(io.cwd);\n if (\"error\" in read) return usage(read.error, table, io);\n const source = resolveStack(read.config, read.path, from.value, undefined);\n if (\"error\" in source) return usage(source.error, table, io);\n const dest = resolveStack(read.config, read.path, to.value, undefined);\n if (\"error\" in dest) return usage(dest.error, table, io);\n const backend = useBackend([source, dest], io.env);\n if (backend) return usage(backend, table, io);\n const rules = requestRules(read.config);\n const destName = destStackName(source, dest, read.config);\n const engine = source.engine ?? dest.engine;\n return runRequest(\"move\", json, table, io, async (ops) => {\n const outcome = await ops.gatedStackMove({\n by: requesterOf(common.by, io.env), rules, op: STACK_OPS_OP, ledgerCwd: io.cwd, env: io.env,\n source: { member: source.key, dir: source.dir, stack: source.stack },\n dest: { member: dest.key, dir: dest.dir, stack: destName },\n urns,\n ...(engine ? { engine } : {}),\n });\n return reportOutcome(\"move\", outcome, `move:${source.stack}:${destName}`, rules, (r) => STACK_OP_WORDS.moved(source.key, dest.key, r), json, table, io);\n });\n}\n\n/** `plywood move <stack> --onto plunge`: chant's adopt Op, as plywood init wrote it (chant#4562). */\nasync function moveOntoPlunge(engine: string, args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n if (engine !== \"plunge\") return usage(`--onto takes plunge, not '${engine}'; a move between backends is an export and an import (see '${PRODUCT} export')`, table, io);\n const extra = args.filter((a) => a.startsWith(\"-\"));\n if (extra.length) return usage(`move --onto does not take ${extra.join(\" \")}`, table, io);\n const named = positionals(args);\n if (named.length > 1) return usage(`move --onto plunge takes at most one stack`, table, io);\n const read = readConfig(io.cwd);\n if (\"error\" in read) return usage(read.error, table, io);\n const opFile = join(dirname(read.path), ADOPT_OP_FILE);\n if (!existsSync(opFile)) return usage(STACK_OP_WORDS.noAdoptOp(opFile), table, io);\n if (named[0]) {\n const stack = resolveStack(read.config, read.path, named[0], undefined);\n if (\"error\" in stack) return usage(stack.error, table, io);\n if (!json) io.err(STACK_OP_WORDS.adoptAll(stack.key));\n }\n const argv = [\"run\", ADOPT_OP, ...(json ? [\"--json\"] : [])];\n return withChant(`${PRODUCT} move --onto plunge`, table, io, async (chant) => {\n const code = await chant.runChantInProcess(argv, PRODUCT_WORDS);\n if (code === table.waiting && !json) io.err(STACK_OP_WORDS.adoptWaiting);\n return code === table.waiting ? code : explainRefusal(code, table, io.err);\n });\n}\n\n/**\n * `plywood rollback <stack> [--digest <sha256:...>] [--env <env>]` or\n * `plywood rollback --release <name> --env <env>`, each with `[--dry-run]\n * [--actor <name>] [--events-json] [--json]`: chant components rollback\n * (chant#4542) with plywood's words.\n */\nexport async function rollbackStack(args: string[], json: boolean, table: ExitTable, io: StageIo): Promise<number> {\n const release = takeFlag(args, \"--release\");\n const env = takeFlag(release.rest, \"--env\");\n const digest = takeFlag(env.rest, \"--digest\");\n const actor = takeFlag(digest.rest, \"--actor\");\n for (const [flag, f] of [[\"--release\", release], [\"--env\", env], [\"--digest\", digest], [\"--actor\", actor]] as const) {\n if (f.missing) return usage(`${flag} takes a value`, table, io);\n }\n const switches: string[] = actor.rest.filter((a) => a === \"--dry-run\" || a === \"--events-json\");\n const rest = actor.rest.filter((a) => !switches.includes(a));\n const extra = rest.filter((a) => a.startsWith(\"-\"));\n if (extra.length) return usage(`rollback does not take ${extra.join(\" \")}`, table, io);\n const named = positionals(rest);\n if (named.length > 1) return usage(`rollback takes one stack: ${STACK_OP_WORDS.usage.rollback}`, table, io);\n\n let argv: string[];\n if (release.value !== undefined) {\n if (named.length) return usage(STACK_OP_WORDS.releaseIsEnvWide(named[0]!, environmentOf(named[0]!)), table, io);\n if (digest.value !== undefined) return usage(\"--release takes no --digest: the release names what each stack goes back to\", table, io);\n if (!env.value) return usage(`rollback --release needs --env <env>, the environment whose stacks go back: ${STACK_OP_WORDS.usage.rollback}`, table, io);\n argv = [\"components\", \"rollback\", env.value, \"--release\", release.value];\n } else {\n if (named.length !== 1) return usage(`rollback takes a stack, or --release <name> --env <env>: ${STACK_OP_WORDS.usage.rollback}`, table, io);\n const read = readConfig(io.cwd);\n if (\"error\" in read) return usage(read.error, table, io);\n const stack = resolveStack(read.config, read.path, named[0]!, undefined);\n if (\"error\" in stack) return usage(stack.error, table, io);\n // plywood init names each stack's component after its key (src/init/render.ts componentName).\n argv = [\"components\", \"rollback\", env.value ?? environmentOf(stack.stack), \"--component\", slug(stack.key), ...(digest.value ? [\"--digest\", digest.value] : [])];\n }\n argv.push(...(actor.value ? [\"--actor\", actor.value] : []), ...switches, ...(json ? [\"--json\"] : []));\n\n if (!(await chantStackRollback())) {\n io.err(`${PRODUCT}: ${needsStackOpsMessage(`${PRODUCT} rollback`, \"rollback by release for stacks (chant#4542)\")}`);\n return table.failed;\n }\n return withChant(`${PRODUCT} rollback`, table, io, async (chant) => {\n const code = await chant.runChantInProcess(argv, PRODUCT_WORDS);\n if (code === table.waiting && !json) io.err(STACK_OP_WORDS.rollbackWaiting);\n return code === table.waiting ? code : explainRefusal(code, table, io.err);\n });\n}\n", "/** The bundle's entry: runs the command line and exits with its code. */\nimport { main } from \"./cli\";\n\nprocess.exitCode = await main(process.argv.slice(2));\n"],
5
+ "mappings": ";;;;;;;;;;;;;;;;;;;AAwCO,SAAS,SAAS,GAA0C;AACjE,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAEO,SAAS,MAAM,KAAa,SAAgC;AACjE,SAAO,EAAE,KAAK,SAAS,UAAU,QAAQ;AAC3C;AAEO,SAAS,QAAQ,KAAa,SAAgC;AACnE,SAAO,EAAE,KAAK,SAAS,UAAU,UAAU;AAC7C;AAGO,SAAS,MAAM,GAAY,SAA4B,KAA8B;AAC1F,MAAI,MAAM,UAAc,OAAO,MAAM,YAAY,QAAQ,SAAS,CAAC,EAAI,QAAO,CAAC;AAC/E,SAAO,CAAC,MAAM,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,iBAAiB,QAAQ,KAAK,IAAI,CAAC,EAAE,CAAC;AAClF;AAGO,SAAS,SAAS,GAA4B,SAA4B,KAA8B;AAC7G,SAAO,OAAO,KAAK,CAAC,EACjB,OAAO,CAAC,MAAM,CAAC,QAAQ,SAAS,CAAC,CAAC,EAClC,IAAI,CAAC,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,mBAAmB,GAAG,kBAAkB,QAAQ,KAAK,IAAI,CAAC,EAAE,CAAC;AAClG;AAGO,SAAS,QAAQ,GAAY,KAA8B;AAChE,SAAO,MAAM,UAAa,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,mBAAmB,CAAC;AAC/E;AAGO,SAAS,WAAW,GAAY,KAA8B;AACnE,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,MAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAG,QAAO,CAAC,MAAM,KAAK,2BAA2B,CAAC;AAC9G,SAAO,CAAC;AACV;AA3EA,IA8Ea;AA9Eb;AAAA;AAAA;AA8EO,IAAM,iBAA6B;AAAA,MACxC,MAAM;AAAA,MACN,aAAa;AAAA,IACf;AAAA;AAAA;;;ACtBO,SAAS,SAAS,KAA4C;AACnE,QAAM,IAAI,IAAI;AACd,MAAI,MAAM,UAAa,MAAM,MAAO,QAAO;AAC3C,QAAM,IAAI,SAAS,CAAC,IAAI,IAAI,CAAC;AAC7B,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,iBAAiB,WAAW,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,IAC7E,GAAI,OAAO,EAAE,YAAY,WAAW,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC9D,QAAQ,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,IACpD,GAAI,OAAO,EAAE,YAAY,WAAW,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,EAChE;AACF;AAEO,SAAS,QAAQ,KAA2C;AACjE,QAAM,IAAI,IAAI;AACd,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO;AACzB,SAAO;AAAA,IACL,SAAS,EAAE,YAAY;AAAA,IACvB,OAAO,EAAE,UAAU;AAAA,IACnB,GAAI,OAAO,EAAE,YAAY,WAAW,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC9D,QAAQ,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAAA,IACpD,GAAI,OAAO,EAAE,YAAY,WAAW,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC9D,GAAI,OAAO,EAAE,aAAa,WAAW,EAAE,SAAS,EAAE,SAAS,IAAI,CAAC;AAAA,IAChE,GAAI,OAAO,EAAE,cAAc,WAAW,EAAE,UAAU,EAAE,UAAU,IAAI,CAAC;AAAA,EACrE;AACF;AAEA,SAAS,UAAU,GAA4B,KAA8B;AAC3E,QAAM,MAAuB,CAAC;AAC9B,MAAI,EAAE,iBAAiB,WAAc,OAAO,EAAE,iBAAiB,YAAY,EAAE,aAAa,KAAK,MAAM,IAAK,KAAI,KAAK,MAAM,GAAG,GAAG,iBAAiB,wDAAwD,CAAC;AACzM,MAAI,EAAE,YAAY,WAAc,OAAO,EAAE,YAAY,YAAY,EAAE,QAAQ,KAAK,MAAM,IAAK,KAAI,KAAK,MAAM,GAAG,GAAG,YAAY,kDAAkD,CAAC;AAC/K,MAAI,EAAE,YAAY,WAAc,OAAO,EAAE,YAAY,YAAY,CAAC,SAAS,KAAK,EAAE,OAAO,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,YAAY,oGAAoG,CAAC;AACnO,MAAI,EAAE,YAAY,WAAc,OAAO,EAAE,YAAY,YAAY,CAAC,OAAO,UAAU,EAAE,OAAO,KAAK,EAAE,UAAU,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,YAAY,yCAAyC,CAAC;AAC5L,SAAO;AACT;AA5FA,IAkCa,iBACP,UACA,aACA,YAyDA,aAMO;AApGb;AAAA;AAAA;AAgCA;AAEO,IAAM,kBAAkB;AAC/B,IAAM,WAAW;AACjB,IAAM,cAAc,CAAC,gBAAgB,WAAW,WAAW,SAAS;AACpE,IAAM,aAAa,CAAC,WAAW,SAAS,WAAW,WAAW,WAAW,YAAY,WAAW;AAyDhG,IAAM,cAAc;AAAA,MAClB,SAAS,EAAE,MAAM,UAAU,aAAa,gEAAgE;AAAA,MACxG,SAAS,EAAE,MAAM,UAAU,SAAS,iBAAiB,aAAa,yEAAyE;AAAA,MAC3I,SAAS,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,+BAA+B;AAAA,IACtF;AAEO,IAAM,SAAsB;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,UAAU,OAAO;AAAA,MACxB,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,aAAa;AAAA,UACb,OAAO;AAAA,YACL,EAAE,MAAM,UAAU;AAAA,YAClB;AAAA,cACE,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,YAAY,EAAE,cAAc,EAAE,MAAM,UAAU,aAAa,8EAA8E,GAAG,GAAG,YAAY;AAAA,YAC7J;AAAA,UACF;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,SAAS,EAAE,MAAM,WAAW,SAAS,OAAO,aAAa,iDAAiD;AAAA,YAC1G,OAAO,EAAE,MAAM,WAAW,SAAS,OAAO,aAAa,gFAAgF;AAAA,YACvI,GAAG;AAAA,YACH,UAAU,EAAE,MAAM,WAAW,SAAS,GAAG,aAAa,+BAA+B;AAAA,YACrF,WAAW;AAAA,cACT,MAAM;AAAA,cACN,aAAa;AAAA,YACf;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,UAAa,OAAO,MAAM,WAAW;AAC7C,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,UAAU,qEAAqE,CAAC;AAAA,cAC5G,KAAI,KAAK,GAAG,SAAS,GAAG,aAAa,QAAQ,GAAG,GAAG,UAAU,GAAG,QAAQ,CAAC;AAAA,QAChF;AACA,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,SAAS,mBAAmB,CAAC;AAAA,eACzD;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,YAAY,OAAO,GAAG,GAAG,UAAU,GAAG,OAAO,CAAC;AACtE,uBAAW,KAAK,CAAC,WAAW,OAAO,EAAY,KAAI,EAAE,CAAC,MAAM,UAAa,OAAO,EAAE,CAAC,MAAM,UAAW,KAAI,KAAK,MAAM,SAAS,CAAC,IAAI,kBAAkB,CAAC;AACpJ,gBAAI,EAAE,cAAc,WAAc,OAAO,EAAE,cAAc,YAAY,CAAC,SAAS,KAAK,EAAE,SAAS,GAAI,KAAI,KAAK,MAAM,mBAAmB,kHAAkH,CAAC;AACxP,gBAAI,EAAE,aAAa,WAAc,OAAO,EAAE,aAAa,YAAY,CAAC,OAAO,UAAU,EAAE,QAAQ,KAAK,EAAE,WAAW,GAAI,KAAI,KAAK,MAAM,kBAAkB,8CAA8C,CAAC;AACrM,iBAAK,EAAE,YAAY,QAAQ,EAAE,UAAU,SAAS,EAAE,aAAa,OAAW,KAAI,KAAK,QAAQ,kBAAkB,uDAAuD,CAAC;AACrK,gBAAI,EAAE,UAAU,QAAQ,EAAE,SAAS,IAAI,OAAO,KAAK,IAAI,QAAQ,UAAU,gBAAiB,KAAI,KAAK,QAAQ,eAAe,iFAAiF,CAAC;AAAA,UAC9M;AAAA,QACF;AACA,cAAM,UAAU,SAAS,IAAI,OAAO,IAAI,IAAI,QAAQ,QAAQ;AAC5D,YAAI,YAAY,kBAAkB,EAAE,SAAS,CAAC,KAAK,EAAE,UAAU,MAAO,KAAI,KAAK,QAAQ,iBAAiB,kFAAkF,CAAC;AAC3L,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,SAAS,SAAS,GAAG;AAC3B,YAAI,OAAQ,KAAI,SAAS,SAAS;AAClC,cAAM,QAAQ,QAAQ,GAAG;AACzB,YAAI,MAAO,KAAI,SAAS,QAAQ;AAAA,MAClC;AAAA,IACF;AAAA;AAAA;;;AChIO,SAAS,aAAa,KAA2F;AACtH,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,MAAI,EAAE,UAAU,UAAU,OAAO,EAAE,oBAAoB,SAAU,QAAO;AACxE,QAAM,SAAU,cAAqC,SAAS,EAAE,YAAY,IAAK,EAAE,eAAkD;AACrI,SAAO,EAAE,UAAU,EAAE,iBAAiB,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AACtE;AAOO,SAAS,YAAY,KAA2B;AACrD,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,SAAO,EAAE,SAAS,iBAAiB,iBAAiB;AACtD;AAGO,SAAS,gBAAgB,KAA0B;AACxD,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,SAAO,MAAM,QAAQ,EAAE,QAAQ,IAAK,EAAE,SAAuB,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI,CAAC,GAAG,cAAc;AACrI;AArDA,IAoBa,YAEA,oBAGA,gBAEA,aACA,eACPA,WAUO,aAgBA;AAvDb;AAAA;AAAA;AAiBA;AAGO,IAAM,aAAa,CAAC,SAAS,cAAc;AAE3C,IAAM,qBAAgC;AAGtC,IAAM,iBAAiB,CAAC,YAAY,aAAa,cAAc,QAAQ;AAEvE,IAAM,cAAc,CAAC,UAAU,MAAM;AACrC,IAAM,gBAAgB,CAAC,SAAS,UAAU,QAAQ;AACzD,IAAMA,YAAW;AAUV,IAAM,cAA4D;AAAA,MACvE,OAAO;AAAA,MACP,gBAAgB;AAAA,IAClB;AAaO,IAAM,QAAqB;AAAA,MAChC,MAAM;AAAA,MACN,MAAM,CAAC,OAAO;AAAA,MACd,QAAQ;AAAA,QACN,OAAO;AAAA,UACL,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,YAAY;AAAA,YACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,UAAU,GAAG,SAAS,oBAAoB,aAAa,uDAAuD;AAAA,YAChJ,UAAU;AAAA,cACR,MAAM;AAAA,cACN,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,cAAc,EAAE;AAAA,cACnD,aAAa;AAAA,cACb,aAAa;AAAA,YACf;AAAA,YACA,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,WAAW,GAAG,SAAS,UAAU,aAAa,mGAAmG;AAAA,YACpL,iBAAiB,EAAE,MAAM,UAAU,aAAa,0IAA0I;AAAA,YAC1L,cAAc,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,aAAa,GAAG,aAAa,4DAA4D;AAAA,UACrI;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,YAAI,IAAI,UAAU,OAAW,QAAO,CAAC;AACrC,YAAI,CAAC,SAAS,IAAI,KAAK,EAAG,QAAO,CAAC,MAAM,SAAS,mBAAmB,CAAC;AACrE,cAAM,IAAI,IAAI;AACd,cAAM,MAAuB;AAAA,UAC3B,GAAG,SAAS,GAAG,CAAC,QAAQ,YAAY,SAAS,mBAAmB,cAAc,GAAG,OAAO;AAAA,UACxF,GAAG,MAAM,EAAE,MAAM,YAAY,YAAY;AAAA,UACzC,GAAG,MAAM,EAAE,OAAO,aAAa,aAAa;AAAA,UAC5C,GAAG,MAAM,EAAE,cAAc,eAAe,oBAAoB;AAAA,QAC9D;AACA,YAAI,EAAE,UAAU,QAAQ;AACtB,cAAI,EAAE,SAAS,eAAgB,KAAI,KAAK,MAAM,eAAe,oFAAoF,CAAC;AAClJ,cAAI,OAAO,EAAE,oBAAoB,YAAY,CAACA,UAAS,KAAK,EAAE,eAAe,EAAG,KAAI,KAAK,MAAM,yBAAyB,0HAA0H,CAAC;AAAA,QACrP,WAAW,EAAE,oBAAoB,UAAa,EAAE,iBAAiB,QAAW;AAC1E,cAAI,KAAK,MAAM,EAAE,oBAAoB,SAAY,0BAA0B,sBAAsB,6BAA6B,CAAC;AAAA,QACjI;AACA,YAAI,EAAE,aAAa,QAAW;AAC5B,cAAI,CAAC,MAAM,QAAQ,EAAE,QAAQ,EAAG,KAAI,KAAK,MAAM,kBAAkB,qBAAqB,eAAe,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,eAC7G;AACH,uBAAW,KAAK,EAAE,SAAU,KAAI,KAAK,GAAG,MAAM,GAAG,gBAAgB,gBAAgB,CAAC;AAClF,gBAAI,EAAE,SAAS,eAAgB,KAAI,KAAK,MAAM,kBAAkB,kFAAkF,CAAC;AAAA,UACrJ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,OAAO,YAAY,GAAG;AAC5B,YAAI,GAAG,WAAW,YAAY,IAAI;AAClC,YAAI,SAAS,gBAAgB;AAC3B,gBAAM,IAAI,IAAI;AACd,cAAI,SAAS,gBAAgB,MAAM,QAAQ,EAAE,QAAQ,IAAI,CAAC,GAAI,EAAE,QAAqB,IAAI,CAAC,GAAG,cAAc;AAC3G,gBAAM,QAAQ,aAAa,GAAG;AAC9B,cAAI,MAAO,KAAI,SAAS,aAAa;AAAA,QACvC;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACnFO,SAAS,WAAW,KAAqC;AAC9D,SAAO,OAAO,IAAI,aAAa,YAAa,UAAgC,SAAS,IAAI,QAAQ,IAAK,IAAI,WAAmC;AAC/I;AAEO,SAAS,OAAO,KAAiC;AACtD,SAAO,OAAO,IAAI,SAAS,YAAa,MAA4B,SAAS,IAAI,IAAI,IAAK,IAAI,OAA2B;AAC3H;AAGO,SAAS,SAAS,OAAgE;AACvF,SAAO,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,MAAM,CAAC,MAAM;AAC9C,UAAM,QAAQ,CAAC,GAAI,EAAE,SAAS,SAAY,CAAC,EAAE,IAAI,IAAI,CAAC,GAAI,GAAI,EAAE,SAAS,CAAC,CAAE;AAC5E,WAAO,EAAE,SAAS,CAAC,IAAI,GAAG,OAAO,EAAE,UAAU,GAAG,GAAI,MAAM,SAAS,EAAE,MAAM,IAAI,CAAC,GAAI,WAAW,KAAK;AAAA,EACtG,CAAC;AACH;AA1CA,IAgBa,OACA,cACA,WACA,kBACA,oBAwBA;AA5Cb;AAAA;AAAA;AAaA;AAGO,IAAM,QAAQ,CAAC,UAAU,kBAAkB,OAAO;AAClD,IAAM,eAAgC;AACtC,IAAM,YAAY,CAAC,UAAU,UAAU,WAAW;AAClD,IAAM,mBAAwC;AAC9C,IAAM,qBAAqB,CAAC,QAAQ,SAAS,QAAQ;AAwBrD,IAAM,WAAwB;AAAA,MACnC,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ,YAAY,gBAAgB;AAAA,MAC3C,QAAQ;AAAA,QACN,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,KAAK,GAAG,SAAS,cAAc,aAAa,mCAAmC;AAAA,QACjH,UAAU,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,SAAS,GAAG,SAAS,kBAAkB,aAAa,+BAA+B;AAAA,QACzH,gBAAgB;AAAA,UACd,MAAM;AAAA,UACN,aAAa;AAAA,UACb,sBAAsB;AAAA,YACpB,MAAM;AAAA,YACN,sBAAsB;AAAA,YACtB,YAAY;AAAA,cACV,MAAM,EAAE,MAAM,UAAU,aAAa,gDAAgD;AAAA,cACrF,OAAO,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,8BAA8B;AAAA,cAC9F,QAAQ,EAAE,MAAM,WAAW,SAAS,GAAG,SAAS,GAAG,aAAa,sCAAsC;AAAA,YACxG;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC,GAAG,MAAM,IAAI,MAAM,OAAO,MAAM,GAAG,GAAG,MAAM,IAAI,UAAU,WAAW,UAAU,CAAC;AAC9G,cAAM,QAAQ,IAAI;AAClB,YAAI,UAAU,OAAW,QAAO;AAChC,YAAI,CAAC,SAAS,KAAK,EAAG,QAAO,CAAC,GAAG,KAAK,MAAM,kBAAkB,2CAA2C,CAAC;AAC1G,YAAI,YAAY;AAChB,mBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC7C,gBAAM,MAAM,kBAAkB,IAAI;AAClC,cAAI,CAAC,SAAS,CAAC,GAAG;AAChB,gBAAI,KAAK,MAAM,KAAK,6CAA6C,CAAC;AAClE;AAAA,UACF;AACA,cAAI,KAAK,GAAG,SAAS,GAAG,oBAAoB,GAAG,CAAC;AAChD,cAAI,EAAE,SAAS,UAAa,OAAO,EAAE,SAAS,SAAU,KAAI,KAAK,MAAM,GAAG,GAAG,SAAS,kBAAkB,CAAC;AACzG,cAAI,EAAE,UAAU,WAAc,CAAC,MAAM,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,UAAU,2BAA2B,CAAC;AACjK,cAAI,EAAE,WAAW,WAAc,CAAC,OAAO,UAAU,EAAE,MAAM,KAAM,EAAE,SAAoB,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,WAAW,mCAAmC,CAAC;AAC7J,cAAI,EAAE,SAAS,UAAc,MAAM,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,OAAS,aAAY;AAAA,QACtF;AACA,YAAI,aAAa,WAAW,GAAG,MAAM,UAAU;AAC7C,cAAI,KAAK,QAAQ,kBAAkB,wHAAwH,CAAC;AAAA,QAC9J;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,YAAI,SAAS,OAAO,OAAO,GAAG;AAC9B,YAAI,SAAS,WAAW,WAAW,GAAG;AACtC,YAAI,SAAS,gBAAgB;AAC7B,YAAI,SAAS,IAAI,cAAc,EAAG,KAAI,SAAS,SAAS,SAAS,IAAI,cAAsD;AAAA,MAC7H;AAAA,IACF;AAAA;AAAA;;;ACrEO,SAAS,gBAAgB,KAAiC;AAC/D,MAAI,QAAQ,OAAW,QAAO;AAC9B,QAAM,UAAU,gBAAgB,GAAG;AACnC,MAAI,QAAS,QAAO,uBAAuB,OAAO,wCAAwC,GAAG;AAC7F,MAAI,YAAY,KAAM,QAAO,uCAAuC,GAAG;AACvE,SAAO,qDAAqD,GAAG;AACjE;AA9BA,IASa,iBAuBA;AAhCb;AAAA;AAAA;AAMA;AAGO,IAAM,kBAA2D;AAAA,MACtE,UAAU;AAAA,MACV,OAAO;AAAA,MACP,WAAW;AAAA,MACX,eAAe;AAAA,MACf,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,WAAW;AAAA,MACX,OAAO;AAAA,MACP,OAAO;AAAA,IACT;AAWO,IAAM,YAAyB;AAAA,MACpC,MAAM;AAAA,MACN,MAAM,CAAC;AAAA,MACP,QAAQ,CAAC;AAAA,MACT,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,mBAAW,CAAC,KAAK,CAAC,KAAK,OAAO,QAAQ,GAAG,GAAG;AAC1C,cAAI,QAAQ,MAAM;AAChB,gBAAI,SAAS,CAAC,KAAK,OAAO,KAAK,CAAC,EAAE,OAAQ,YAAW,OAAO,OAAO,KAAK,CAAC,EAAG,KAAI,KAAK,MAAM,MAAM,GAAG,IAAI,gBAAgB,GAAG,CAAC,CAAC;AAAA,gBACxH,KAAI,KAAK,MAAM,MAAM,gBAAgB,MAAS,CAAC,CAAC;AAAA,UACvD,WAAW,IAAI,WAAW,KAAK,GAAG;AAChC,kBAAM,MAAM,IAAI,MAAM,CAAC,EAAE,MAAM,GAAG,EAAE,CAAC;AACrC,gBAAI,KAAK,MAAM,KAAK,gBAAgB,GAAG,CAAC,CAAC;AAAA,UAC3C;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,YAAY;AAAA,MAAC;AAAA,IACf;AAAA;AAAA;;;ACuCO,SAAS,aAAaC,OAAkD;AAC7E,QAAM,WAAW,OAAO,YAAY,OAAO,QAAQ,cAAc,QAAQ,EAAE,OAAO,CAAC,CAAC,EAAE,CAAC,MAAMA,MAAK,SAAS,CAAC,CAAC,CAAC;AAC9G,SAAO,EAAE,GAAG,eAAe,SAAS;AACtC;AAuFO,SAAS,YAAY,OAAuB;AACjD,SAAO,kBAAkB,MAAM,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,YAAY,EAAE;AACjG;AAGO,SAAS,iBAAiB,OAAuB;AACtD,SAAO,sBAAsB,KAAK;AACpC;AAEO,SAAS,gBAAgB,OAAuB;AACrD,SAAO,YAAY,KAAK;AAC1B;AAUA,SAAS,KAAK,GAAmB;AAC/B,SAAO,EAAE,QAAQ,OAAO,KAAK,EAAE,QAAQ,OAAO,GAAG;AACnD;AAMO,SAAS,eAAe,OAA0K;AACvM,QAAM,EAAE,OAAO,KAAK,IAAI;AACxB,QAAMC,SAAQ;AAAA,IACZ,iBAAiB,KAAK;AAAA,IACtB,8BAA8B,KAAK,yBAAyB,MAAM,UAAU,cAAc,KAAK,MAAM,YAAY,KAAK,WAAW,IAAI,KAAK,GAAG;AAAA,IAC7I;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAG,KAAK,IAAI,CAAC,MAAM,OAAO,KAAK,EAAE,GAAG,CAAC,QAAQ,EAAE,MAAM,MAAM,EAAE,WAAW,SAAS,EAAE,WAAW,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,IAAI,EAAE,KAAK,IAAI,IAAI,EAAE,IAAI;AAAA,IAC9I;AAAA,IACA,GAAI,MAAM,aAAa,SAAS,CAAC,wEAAwE,IAAI,GAAG,MAAM,aAAa,EAAE,IAAI,CAAC;AAAA,IAC1I,2DAA2D,KAAK,aAAa,OAAO;AAAA,IACpF,GAAI,MAAM,YAAY,OAAO,CAAC,IAAI,gEAAgE,KAAK,4BAA4B,IAAI,CAAC;AAAA,IACxI,GAAI,MAAM,SAAS,CAAC,IAAI,WAAW,MAAM,MAAM,GAAG,IAAI,CAAC;AAAA,IACvD;AAAA,IACA,kCAAkC,MAAM,WAAW;AAAA,EACrD;AACA,SAAOA,OAAM,KAAK,IAAI;AACxB;AAGO,SAAS,oBAAoB,OAAeC,aAA4B;AAC7E,SAAO,4BAA4BA,WAAU,UAAU,KAAK;AAC9D;AAvOA,IAMa,SAEA,SAGA,SACA,SAWA,OAUA,KAiCA,cAEA,eA4CA,mBAaA,aAGA,aAQA,gBAwCA,iBA8EA,kBAcA;AA5Qb;AAAA;AAAA;AAMO,IAAM,UAAU;AAEhB,IAAM,UAAU;AAGhB,IAAM,UAAU;AAChB,IAAM,UAAU;AAWhB,IAAM,QAA8B;AAAA,MACzC,EAAE,MAAM,SAAS,SAAS,+DAA+D;AAAA,MACzF,EAAE,MAAM,WAAW,SAAS,kFAAkF;AAAA,MAC9G,EAAE,MAAM,MAAM,SAAS,kEAAkE;AAAA,MACzF,EAAE,MAAM,SAAS,SAAS,sDAAsD;AAAA,MAChF,EAAE,MAAM,WAAW,SAAS,2CAA2C;AAAA,MACvE,EAAE,MAAM,YAAY,SAAS,6CAA6C;AAAA,IAC5E;AAGO,IAAM,MAAM;AAiCZ,IAAM,eAAe,OAAO,OAAO,EAAE,QAAQ,SAAS,MAAM,+BAA+B,SAAS,KAAK,OAAO,GAAG,CAAC;AAEpH,IAAM,gBAA6C,OAAO,OAAO;AAAA,MACtE,SAAS;AAAA,MACT,QAAQ,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,MACvC,OAAO,EAAE,MAAM,CAAC,WAAW,WAAW,GAAG,OAAO,CAAC,UAAU,SAAS,EAAE;AAAA,MACtE,MAAM,CAAC,SAAS,QAAQ;AAAA,MACxB,UAAU,EAAE,SAAS,QAAQ,IAAI,SAAS,MAAM,QAAQ,QAAQ,SAAS;AAAA,MACzE,SAAS;AAAA,MACT,UAAU;AAAA,MACV,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,UAAU;AAAA,MACV,UAAU;AAAA,MACV,KAAK;AAAA,MACL,QAAQ;AAAA,IACV,CAA6B;AA8BtB,IAAM,oBAAoB;AAa1B,IAAM,cAAc,EAAE,KAAK,OAAO,KAAK,OAAO,OAAO,SAAS,QAAQ,eAAe;AAGrF,IAAM,cAAc;AAQpB,IAAM,iBAAiB;AAAA,MAC5B,OAAO;AAAA,QACL,QAAQ,GAAG,OAAO;AAAA,QAClB,QAAQ,GAAG,OAAO;AAAA,QAClB,MAAM,GAAG,OAAO,kEAAkE,OAAO;AAAA,QACzF,UAAU,GAAG,OAAO,yDAAyD,OAAO;AAAA,MACtF;AAAA,MACA,SAAS,CAAC,MAAoCC,aAC5C,OAAO,IAAI,iFAAiFA,QAAO;AAAA,MACrG,OAAO,CAAC,SACN,QAAQ,IAAI;AAAA,MACd,UAAU,CAAC,OAAe,MACxB,YAAY,KAAK,OAAO,EAAE,IAAI,KAAK,EAAE,SAAS,eAAe,EAAE,KAAK,kBAAkB,EAAE,MAAM;AAAA,MAChG,WAAW,CAAC,OAAe,MAAc,YACvC,iBAAiB,IAAI,OAAO,KAAK,IAAI,UAAU,KAAK,8FAA8F;AAAA,MACpJ,OAAO,CAAC,MAAc,IAAY,MAChC,SAAS,EAAE,MAAM,MAAM,YAAY,EAAE,MAAM,WAAW,IAAI,KAAK,GAAG,SAAS,IAAI,OAAO,EAAE,OAAO,EAAE,MAAM;AAAA,MACzG,WACE;AAAA,MACF,eAAe,CAAC,YACd,sHAAsH,WAAW,0BAA0B;AAAA,MAC7J,QAAQ,CAAC,UAA0B,GAAG,KAAK;AAAA,MAC3C,WAAW,CAAC,OAAe,QACzB,GAAG,KAAK,UAAU,IAAI,MAAM,WAAW,IAAI,KAAK,IAAI,CAAC;AAAA,MACvD,WAAW,CAAC,SACV,MAAM,IAAI,MAAM,OAAO;AAAA,MACzB,UAAU,CAAC,UACT,GAAG,OAAO,oEAAoE,KAAK;AAAA,MACrF,cAAc,gHAAgH,OAAO;AAAA,MACrI,iBAAiB;AAAA,MACjB,kBAAkB,CAAC,OAAe,QAChC,gHAAgH,OAAO,oCAAoC,GAAG,UAAU,OAAO,aAAa,KAAK;AAAA,IACrM;AAQO,IAAM,kBAAkB;AA8ExB,IAAM,mBAAmB;AAAA,MAC9B,WAAW,CAACC,YACVA,YAAW,WACP,iFACAA,YAAW,WACT,oFACA;AAAA,IACV;AAOO,IAAM,2BAA2B;AAAA,MACtC,WAAW,GAAG,OAAO;AAAA,MACrB,OAAO,GAAG,OAAO;AAAA,MACjB,YAAY,GAAG,OAAO;AAAA,MACtB,UAAU,GAAG,OAAO;AAAA,MACpB,aAAa,GAAG,OAAO;AAAA,MACvB,YAAY,GAAG,OAAO;AAAA,MACtB,WAAW,GAAG,OAAO;AAAA,IACvB;AAAA;AAAA;;;ACzOO,SAAS,eAAe,MAAsB;AACnD,SAAO,KACJ,KAAK,EACL,QAAQ,iBAAiB,EAAE,EAC3B,QAAQ,YAAY,EAAE,EACtB,QAAQ,oBAAoB,KAAK,EACjC,QAAQ,UAAU,EAAE,EACpB,QAAQ,QAAQ,EAAE;AACvB;AAGO,SAAS,UAAU,KAAkD;AAC1E,QAAM,IAAI,IAAI;AACd,MAAI,OAAO,MAAM,SAAU,QAAO,EAAE,MAAM,eAAe,CAAC,GAAG,IAAI,QAAQ;AACzE,MAAI,CAAC,SAAS,CAAC,KAAK,OAAO,EAAE,SAAS,SAAU,QAAO;AACvD,QAAM,MAA+B,EAAE,MAAM,eAAe,EAAE,IAAI,GAAG,IAAI,OAAO,EAAE,OAAO,WAAW,EAAE,KAAK,QAAQ;AACnH,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,YAAY,GAAG;AACvD,QAAI,QAAQ,UAAU,QAAQ,KAAM;AACpC,QAAI,OAAO,EAAE,GAAG,MAAM,SAAU,KAAI,KAAK,IAAI,EAAE,GAAG;AAAA,EACpD;AACA,SAAO;AACT;AAhEA,IA6Ba,cAWP,gBA0BO;AAlEb;AAAA;AAAA;AAyBA;AACA;AAGO,IAAM,eAAe;AAAA,MAC1B,MAAM;AAAA,MACN,IAAI;AAAA,MACJ,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,KAAK;AAAA,MACL,UAAU;AAAA,IACZ;AAEA,IAAM,iBAAiB,CAAC,UAAU,UAAU,SAAS;AA0B9C,IAAM,UAAuB;AAAA,MAClC,MAAM;AAAA,MACN,MAAM,CAAC,SAAS;AAAA,MAChB,QAAQ;AAAA,QACN,SAAS;AAAA,UACP,aAAa;AAAA,UACb,OAAO;AAAA,YACL,EAAE,MAAM,SAAS;AAAA,YACjB;AAAA,cACE,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,UAAU,CAAC,MAAM;AAAA,cACjB,YAAY;AAAA,gBACV,MAAM,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,gBAC9F,IAAI,EAAE,MAAM,UAAU,aAAa,yEAAyE,OAAO,IAAI;AAAA,gBACvH,QAAQ,EAAE,MAAM,UAAU,aAAa,yFAAyF;AAAA,gBAChI,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,cAAc,GAAG,aAAa,wDAAwD;AAAA,gBACzH,cAAc,EAAE,MAAM,UAAU,aAAa,sEAAsE;AAAA,gBACnH,mBAAmB,EAAE,MAAM,UAAU,aAAa,+FAA+F;AAAA,gBACjJ,KAAK,EAAE,MAAM,UAAU,aAAa,iEAAiE;AAAA,gBACrG,UAAU,EAAE,MAAM,UAAU,aAAa,8DAA8D;AAAA,cACzG;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,YAAI,OAAO,MAAM,SAAU,QAAO,eAAe,CAAC,EAAE,MAAM,GAAG,EAAE,UAAU,IAAI,CAAC,IAAI,CAAC,MAAM,WAAW,GAAG,CAAC,2BAA2B,CAAC;AACpI,YAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,WAAW,gEAAgE,CAAC;AAC5G,cAAM,MAAuB,CAAC,GAAG,SAAS,GAAG,OAAO,KAAK,YAAY,GAAG,SAAS,CAAC;AAClF,YAAI,OAAO,EAAE,SAAS,SAAU,KAAI,KAAK,MAAM,gBAAgB,mEAAmE,CAAC;AAAA,iBAC1H,eAAe,EAAE,IAAI,EAAE,MAAM,GAAG,EAAE,SAAS,EAAG,KAAI,KAAK,MAAM,gBAAgB,GAAG,EAAE,IAAI,2BAA2B,CAAC;AAC3H,mBAAW,OAAO,OAAO,KAAK,YAAY,GAAG;AAC3C,cAAI,QAAQ,UAAU,EAAE,GAAG,MAAM,UAAa,OAAO,EAAE,GAAG,MAAM,SAAU,KAAI,KAAK,MAAM,WAAW,GAAG,IAAI,kBAAkB,CAAC;AAAA,QAChI;AACA,YAAI,KAAK,GAAG,MAAM,EAAE,OAAO,gBAAgB,eAAe,CAAC;AAC3D,YAAI,OAAO,EAAE,iBAAiB,YAAY,EAAE,iBAAiB,EAAE,mBAAmB;AAChF,cAAI,KAAK,MAAM,6BAA6B,iFAAiF,CAAC;AAAA,QAChI;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,IAAI,UAAU,GAAG;AACvB,YAAI,EAAG,KAAI,SAAS,UAAU;AAAA,MAChC;AAAA,IACF;AAAA;AAAA;;;ACjHA,IAEE,SAiCA;AAnCF;AAAA;AAEE,cAAW;AAiCX,mBAAgB;AAAA,MACd,oBAAoB;AAAA,MACpB,mCAAmC;AAAA,IACrC;AAAA;AAAA;;;ACtCF;AAAA;AAAA;AAAA,6BAAC;AAAA;AAAA;;;ACkFM,SAAS,UAAUC,SAAoBC,UAAyB;AACrE,SAAO,GAAG,WAAW,IAAID,OAAM,IAAIC,QAAO;AAC5C;AAGO,SAAS,UAAUD,SAAoBC,UAAyB;AACrE,SAAO,GAAG,UAAUD,SAAQC,QAAO,CAAC,IAAID,OAAM;AAChD;AASO,SAAS,QAAQA,SAAoBC,UAA0B;AACpE,MAAID,YAAW,UAAU;AACvB,WAAO;AAAA,MACL,MAAM,uDAAuDC,QAAO;AAAA,MACpE,SAAS,CAAC,SAAS,WAAWA,QAAO,UAAU,IAAI;AAAA,MACnD,WAAW,UAAUA,QAAO;AAAA,IAC9B;AAAA,EACF;AACA,SAAO;AAAA,IACL,MAAM,iEAAiEA,QAAO;AAAA,IAC9E,SAAS,CAAC,SAAS,WAAWA,QAAO,UAAU,IAAI;AAAA,IACnD,WAAW,WAAWA,QAAO;AAAA,EAC/B;AACF;AAGO,SAAS,WAAWD,SAAoBC,UAAgD;AAC7F,QAAM,IAAI,QAAQD,SAAQC,QAAO;AACjC,QAAM,MAAqC,CAAC;AAC5C,aAAW,QAAQ,QAAQ;AACzB,UAAM,MAAM,cAAc,EAAE,QAAQ,IAAI,CAAC;AACzC,QAAI,IAAK,KAAI,IAAI,IAAI;AAAA,EACvB;AACA,SAAO;AACT;AAUA,SAAS,YAAYD,SAAoBC,UAAiB,KAAa,MAAc,cAA+B;AAClH,QAAM,IAAI,QAAQD,SAAQC,QAAO;AACjC,QAAM,OAAO,WAAWD,SAAQC,QAAO;AACvC,QAAM,UAAU,OAAO,KAAK,IAAI,EAAE,SAC9B,gBAAgB,OAAO,OAAO,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,UAAU,KAAK,CAAC,CAAC,KAAK,EAAE,KAAK,GAAG,CAAC,sBAC9F;AACJ,QAAM,OAAO,GAAG,EAAE,QAAQ,KAAK,EAAE,QAAQ,SAAS,MAAM,CAAC;AACzD,SAAO;AAAA,IACL,KAAK,IAAI;AAAA,IACT,MAAM,IAAI;AAAA,IACV;AAAA,IACA,wBAAwB,EAAE,IAAI;AAAA,IAC9B,yBAAyB,gBAAgB,IAAI,EAAE,IAAI,IAAI,EAAE,SAAS,GAAG;AAAA;AAAA,IAErE;AAAA,IACA,+BAA+BD,OAAM,IAAIC,QAAO,kBAAkB,EAAE,SAAS;AAAA,IAC7E;AAAA,IACA,wDAAwDD,OAAM,IAAIC,QAAO,KAAK,EAAE,SAAS;AAAA,IACzF;AAAA,IACA,aAAa,GAAG;AAAA,IAChB,wBAAwB,GAAG;AAAA,EAC7B,EAAE,KAAK,MAAM;AACf;AAWO,SAAS,YAAYD,SAAoBC,UAAiB,OAAO,MAAc;AACpF,QAAM,QAAQ;AACd,MAAI,QAAQ,OAAO;AACjB,UAAM,OAAO,WAAWD,SAAQC,QAAO;AACvC,UAAM,UAAU,EAAE,MAAM,aAAa,GAAI,OAAO,KAAK,IAAI,EAAE,SAAS,EAAE,QAAQ,KAAK,IAAI,CAAC,EAAG;AAC3F,WAAOD,YAAW,WAAW,MAAM,kBAAkBC,UAAS,OAAO,IAAI,MAAM,kBAAkBA,UAAS,OAAO;AAAA,EACnH;AACA,SAAO,mBAAmBD,SAAQC,UAAS,IAAI;AACjD;AAGO,SAAS,mBAAmBD,SAAoBC,UAAiB,OAAO,MAAc;AAC3F,QAAM,MAAM,UAAUD,SAAQC,QAAO;AACrC,QAAM,UAAU,WAAW,GAAG,IAAID,OAAM,oBAAoBA,OAAM;AAClE,QAAM,UAAU,YAAY,YAAYA,SAAQC,UAAS,KAAK,QAAQ,CAAC;AACvE,SAAO,OAAO,WAAW,GAAG,IAAID,OAAM,UAAU,OAAO,UAAU,OAAO,KAAK,SAAS,GAAG,IAAIA,OAAM,UAAU,OAAO;AACtH;AAkBO,SAAS,uBAAyC;AACvD,eAAa,YAAY;AACvB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,0CAA0C;AAC1F,YAAM,KACJ,OAAO,EAAE,cAAc,cACvB,OAAO,EAAE,kBAAkB,YAC3B,OAAO,EAAE,sBAAsB,cAC/B,OAAO,EAAE,sBAAsB;AACjC,mBAAa,KAAM,IAAqC;AAAA,IAC1D,QAAQ;AACN,mBAAa;AAAA,IACf;AACA,WAAO,eAAe;AAAA,EACxB,GAAG;AACH,SAAO;AACT;AAiBO,SAAS,aAAa,MAAsC;AACjE,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,UAAU,CAAC,GAAG,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC;AAClF,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,SAAS;AACvB,UAAM,IAAI,GAAG,EAAE,MAAM,IAAI,EAAE,OAAO;AAClC,QAAI,KAAK,IAAI,CAAC,EAAG;AACjB,SAAK,IAAI,CAAC;AACV,QAAI,KAAK,YAAY,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,CAAC;AAAA,EACrD;AACA,SAAO;AACT;AAUO,SAAS,UAAUA,SAA4B;AACpD,SAAO,WAAWA,OAAM;AAC1B;AAGO,SAAS,SAASA,SAAoBC,WAAU,SAAyB;AAC9E,SAAO,GAAGA,QAAO,IAAID,OAAM,GAAG,cAAcA,OAAM,CAAC;AACrD;AAGO,SAAS,SAASA,SAAoB,QAAgC,uBAA6C;AACxH,QAAM,aAAa,GAAG,QAAQ,IAAI,UAAUA,OAAM,CAAC;AACnD,QAAM,MAAM,SAASA,OAAM;AAC3B,QAAM,SAAS,MAAM,GAAG,UAAU,IAAI,GAAG,EAAE;AAC3C,SAAO,EAAE,YAAY,KAAK,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AAC1D;AAGO,SAAS,eAAe,KAAuB;AACpD,SAAO,IAAI,SAAS,GAAG,IAAI,UAAU,IAAI,IAAI,GAAG,IAAI,IAAI,MAAM,KAAK,GAAG,IAAI,UAAU,IAAI,IAAI,GAAG;AACjG;AA2FO,SAAS,YAAY,GAAkC;AAC5D,QAAM,IAAI,OAAO,KAAK,CAAC;AACvB,SAAO,IAAI,EAAE,MAAM,EAAE,CAAC,KAAK,YAAY,MAAM,EAAE,CAAC,GAAI,SAAS,EAAE,CAAC,EAAG,IAAI;AACzE;AAuCO,SAAS,gBAAgB,GAAiC;AAC/D,QAAME,SAAQ,CAAC,GAAI,EAAE,gBAAgB,CAAC,GAAI,GAAI,EAAE,QAAQ,eAAe,CAAC,CAAE;AAC1E,SAAO,CAAC,GAAI,EAAE,QAAQ,CAAC,WAAW,EAAE,KAAK,IAAI,CAAC,GAAI,GAAGA,OAAM,QAAQ,CAAC,MAAM,CAAC,mBAAmB,CAAC,CAAC,CAAC;AACnG;AAQO,SAAS,qBAAqB,GAAqE,uBAAoD;AAC5J,QAAMA,SAAQ,EAAE,eAAe,CAAC;AAChC,QAAM,MAA0B,EAAE,GAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,GAAI,GAAI,EAAE,WAAW,SAAY,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAG;AAClI,MAAIA,OAAM,WAAW,EAAG,QAAO;AAC/B,MAAI,CAAC,EAAE,SAAS,sBAAuB,KAAI,SAAS,EAAE,aAAa,CAAC,GAAGA,MAAK,EAAE;AAAA,MACzE,KAAI,eAAe,CAAC,GAAGA,MAAK;AACjC,SAAO;AACT;AAzaA,IAiDa,UAOA,eAQA,QAOA,eAQA,aA8EP,UAgCF,YACA,SAuFS,QAsFA;AA3Wb;AAAA;AAAA;AA2CA;AACA;AAKO,IAAM,WAAW;AAOjB,IAAM,gBAAsD;AAAA,MACjE,QAAQ;AAAA;AAAA,MAER,QAAQ;AAAA,IACV;AAIO,IAAM,SAA0B,CAAC,OAAO,OAAO;AAO/C,IAAM,gBAAkD;AAAA,MAC7D,oCAAoC;AAAA,MACpC,sCAAsC;AAAA,MACtC,kCAAkC;AAAA,MAClC,oCAAoC;AAAA,IACtC;AAGO,IAAM,cAAc;AA8E3B,IAAM,WAAW;AAwHV,IAAM,SAAS;AAsFf,IAAM,SAAS;AAAA;AAAA;;;ACzTf,SAAS,YAAY,MAAc,MAAuB;AAC/D,QAAM,KAAK,IAAI,OAAO,IAAI,KAAK,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,sBAAsB,MAAM,CAAC,EAAE,KAAK,IAAI,CAAC,GAAG;AAC3G,SAAO,GAAG,KAAK,IAAI;AACrB;AAGO,SAAS,OAAO,KAAc,OAA+C;AAClF,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO;AAC3B,MAAI,UAAU,QAAW;AACvB,QAAI,OAAO,IAAI,KAAK,MAAM,SAAU,QAAO,IAAI,KAAK;AACpD,eAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,GAAG,EAAG,KAAI,OAAO,MAAM,YAAY,YAAY,MAAM,KAAK,EAAG,QAAO;AAAA,EAC7G;AACA,SAAO,OAAO,IAAI,GAAG,MAAM,WAAY,IAAI,GAAG,IAAe;AAC/D;AAEA,SAAS,gBAAgB,GAAY,KAA8B;AACjE,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,MAAI,OAAO,MAAM,SAAU,QAAO,QAAQ,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,4BAA4B,QAAQ,WAAW,cAAc,SAAS,cAAc,MAAM,EAAE,CAAC;AACzL,MAAI,CAAC,SAAS,CAAC,KAAK,OAAO,KAAK,CAAC,EAAE,WAAW,EAAG,QAAO,CAAC,MAAM,KAAK,sDAAsD,CAAC;AAC3H,SAAO,OAAO,QAAQ,CAAC,EACpB,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,OAAO,MAAM,YAAY,CAAC,QAAQ,KAAK,CAAC,CAAC,EAC3D,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,iCAAiC,CAAC;AACzE;AAEA,SAAS,mBAAmB,GAAY,KAAa,OAAiC;AACpF,QAAM,QAAQ,CAAC,MAAwB,OAAO,MAAM,YAAY,MAAM,KAAK,CAAC;AAC5E,QAAM,SAAS,CAAC,MAAwB,MAAM,QAAQ,CAAC,KAAK,EAAE,SAAS,KAAK,EAAE,MAAM,KAAK,KAAK,IAAI,IAAI,CAAC,EAAE,SAAS,EAAE;AACpH,MAAI,OAAO,MAAM,SAAU,QAAO,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,uEAAuE,CAAC;AACtI,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,wEAAwE,CAAC;AACnI,MAAI,CAAC,SAAS,CAAC,KAAK,EAAE,WAAW,GAAI,QAAO,CAAC,MAAM,KAAK,+DAA+D,CAAC;AACxH,QAAM,MAAM,SAAS,GAAG,CAAC,SAAS,QAAQ,GAAG,GAAG;AAChD,MAAI,OAAO,EAAE,UAAU,YAAY,EAAE,MAAM,KAAK,MAAM,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,UAAU,iCAAiC,CAAC;AAC3H,MAAI,EAAE,WAAW,UAAa,CAAC,OAAO,EAAE,MAAM,EAAG,KAAI,KAAK,MAAM,GAAG,GAAG,WAAW,0CAA0C,CAAC;AAC5H,MAAI,UAAU,UAAa,UAAU,SAAU,KAAI,KAAK,MAAM,GAAG,GAAG,UAAU,kCAAkC,OAAO,KAAK,CAAC,mCAAmC,CAAC;AACjK,SAAO;AACT;AAGA,SAAS,QAAQ,GAA0C;AACzD,SAAO,SAAS,CAAC,KAAK,EAAE,WAAW;AACrC;AAEA,SAAS,gBAAgB,GAAY,OAAiC;AACpE,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,MAAI,CAAC,QAAQ,CAAC,EAAG,QAAO,mBAAmB,GAAG,WAAW,KAAK;AAC9D,MAAI,OAAO,KAAK,CAAC,EAAE,WAAW,EAAG,QAAO,CAAC,MAAM,WAAW,8BAA8B,cAAc,KAAK,IAAI,CAAC,SAAS,CAAC;AAC1H,SAAO,OAAO,QAAQ,CAAC,EAAE;AAAA,IAAQ,CAAC,CAAC,GAAG,IAAI,MACvC,cAAoC,SAAS,CAAC,IAAI,mBAAmB,MAAM,WAAW,CAAC,IAAI,KAAK,IAAI,CAAC,MAAM,WAAW,CAAC,IAAI,kCAAkC,cAAc,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,EAC3L;AACF;AAEA,SAAS,cAAc,GAA6B;AAClD,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,QAAM,WAAW,CAAC,SAChB,OAAO,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,SAAS,GAAG,IAAI,8GAA8G,CAAC;AACnK,MAAI,OAAO,MAAM,SAAU,QAAO,EAAE,KAAK,MAAM,KAAK,CAAC,MAAM,SAAS,4BAA4B,CAAC,IAAI,SAAS,CAAC;AAC/G,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,SAAS,2CAA2C,WAAW,KAAK,IAAI,CAAC,EAAE,CAAC;AAC5G,QAAM,MAAM,SAAS,GAAG,YAAY,OAAO;AAC3C,MAAI,EAAE,SAAS,WAAc,OAAO,EAAE,SAAS,YAAY,EAAE,KAAK,KAAK,MAAM,IAAK,KAAI,KAAK,MAAM,cAAc,4BAA4B,CAAC;AAAA,WACnI,OAAO,EAAE,SAAS,SAAU,KAAI,KAAK,GAAG,SAAS,EAAE,IAAI,CAAC;AACjE,MAAI,EAAE,YAAY,QAAW;AAC3B,QAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,EAAG,KAAI,KAAK,MAAM,iBAAiB,6CAA6C,CAAC;AAAA,QACxG,GAAE,QAAQ,QAAQ,CAAC,GAAG,MAAM;AAC/B,UAAI,OAAO,MAAM,YAAY,CAAC,YAAY,CAAC,EAAG,KAAI,KAAK,MAAM,iBAAiB,CAAC,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,2CAA2C,CAAC;AAAA,IACzJ,CAAC;AACD,QAAI,EAAE,SAAS,OAAW,KAAI,KAAK,QAAQ,iBAAiB,wHAAwH,CAAC;AAAA,EACvL;AACA,SAAO;AACT;AAGO,SAAS,UAAU,KAAoC;AAC5D,MAAI,OAAO,IAAI,UAAU,SAAU,QAAO,IAAI;AAC9C,SAAO,SAAS,IAAI,KAAK,KAAK,OAAO,IAAI,MAAM,SAAS,WAAW,IAAI,MAAM,OAAO;AACtF;AASA,SAAS,cAAcC,SAAoB,KAAgB,UAA4B;AACrF,QAAM,MAAM,OAAO,IAAIA,OAAM,GAAG,MAAS,KAAK,cAAcA,OAAM;AAClE,MAAI,SAAS,WAAW,EAAG,QAAO;AAClC,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,KAAK,SAAU,OAAM,IAAI,IAAI,MAAM,IAAI,CAAC,KAAK,KAAK,CAAC;AAC9D,QAAM,OAAO,KAAK,IAAI,GAAG,MAAM,OAAO,CAAC;AACvC,SAAO,MAAM,IAAI,GAAG,MAAM,OAAO,MAAM,CAAC,GAAG,KAAK,EAAE,KAAK,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,IAAI,EAAG,CAAC;AAClF;AA7IA,IAuBM,SACA,OACO,eACA,YAEP,eAQA,kBA2GO;AA/Ib,IAAAC,eAAA;AAAA;AAAA;AAmBA;AAEA;AAEA,IAAM,UAAU;AAChB,IAAM,QAAQ;AACP,IAAM,gBAAgB,CAAC,WAAW,WAAW,MAAM,OAAO;AAC1D,IAAM,aAAa,CAAC,QAAQ,SAAS;AAE5C,IAAM,gBAAgB,CAACD,SAAgB,aAAiC;AAAA,MACtE,aAAa,OAAOA,OAAM,kCAAkC,OAAO;AAAA,MACnE,OAAO;AAAA,QACL,EAAE,MAAM,UAAU,SAAS,QAAQ,OAAO;AAAA,QAC1C,EAAE,MAAM,UAAU,eAAe,GAAG,sBAAsB,EAAE,MAAM,UAAU,SAAS,QAAQ,OAAO,EAAE;AAAA,MACxG;AAAA,IACF;AAEA,IAAM,mBAA+B;AAAA,MACnC,OAAO;AAAA,QACL,EAAE,MAAM,UAAU,SAAS,MAAM,OAAO;AAAA,QACxC,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,SAAS,MAAM,OAAO,GAAG,UAAU,GAAG,aAAa,KAAK;AAAA,QAClG;AAAA,UACE,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,UAAU,CAAC,OAAO;AAAA,UAClB,YAAY,EAAE,OAAO,EAAE,MAAM,UAAU,WAAW,EAAE,GAAG,QAAQ,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,SAAS,MAAM,OAAO,GAAG,UAAU,GAAG,aAAa,KAAK,EAAE;AAAA,QACrK;AAAA,MACF;AAAA,IACF;AAgGO,IAAM,SAAsB;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,UAAU,UAAU,SAAS,SAAS;AAAA,MAC7C,QAAQ;AAAA,QACN,QAAQ,cAAc,cAAc,cAAc,MAAM;AAAA,QACxD,QAAQ,cAAc,UAAU,cAAc,MAAM;AAAA,QACpD,OAAO;AAAA,UACL,aAAa;AAAA,UACb,OAAO;AAAA,YACL,EAAE,MAAM,SAAS;AAAA,YACjB;AAAA,cACE,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,YAAY;AAAA,gBACV,MAAM,EAAE,MAAM,UAAU,aAAa,sFAAsF;AAAA,gBAC3H,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,SAAS,OAAO,OAAO,GAAG,aAAa,6EAA6E;AAAA,cACzK;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,aAAa;AAAA,UACb,OAAO,CAAC,kBAAkB,EAAE,MAAM,UAAU,eAAe,GAAG,KAAK,EAAE,UAAU,CAAC,OAAO,EAAE,GAAG,eAAe,EAAE,MAAM,CAAC,GAAG,aAAa,EAAE,GAAG,sBAAsB,iBAAiB,CAAC;AAAA,QACnL;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,QAAQ,SAAS,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO;AACrD,cAAM,MAAuB,CAAC,GAAG,gBAAgB,IAAI,QAAQ,QAAQ,GAAG,GAAG,gBAAgB,IAAI,QAAQ,QAAQ,GAAG,GAAG,cAAc,IAAI,KAAK,GAAG,GAAG,gBAAgB,IAAI,SAAS,KAAK,CAAC;AACrL,cAAM,SAAS,SAAS,IAAI,MAAM,IAAI,OAAO,KAAK,IAAI,MAAM,IAAI,CAAC;AACjE,mBAAW,OAAO,CAAC,UAAU,QAAQ,GAAY;AAC/C,gBAAM,MAAM,IAAI,GAAG;AACnB,cAAI,CAAC,SAAS,GAAG,KAAK,OAAO,WAAW,EAAG;AAC3C,qBAAW,QAAQ,OAAO,KAAK,GAAG,GAAG;AACnC,gBAAI,SAAS,OAAO,CAAC,OAAO,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,CAAC,EAAG,KAAI,KAAK,QAAQ,GAAG,GAAG,IAAI,IAAI,IAAI,+BAA+B,CAAC;AAAA,UACpI;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,iBAAiB,CAAC,MAA0C,KAAK,IAAI,eAAe,UAAU;AACpG,cAAM,MAAoC,EAAE,QAAQ,CAAC,GAAG,QAAQ,CAAC,EAAE;AACnE,cAAM,SAAS,IAAI,QAAQ,IAAI,CAAC,MAAM;AACpC,gBAAMA,UAAS,eAAe,EAAE,MAAM;AACtC,gBAAME,WAAU,OAAO,IAAIF,OAAM,GAAG,EAAE,IAAI,KAAK,OAAO,IAAIA,OAAM,GAAG,MAAS,KAAK,cAAcA,OAAM;AACrG,cAAIA,OAAM,EAAE,KAAKE,QAAO;AACxB,iBAAO,EAAE,GAAG,QAAAF,SAAQ,SAAAE,SAAQ;AAAA,QAC9B,CAAC;AACD,cAAM,UAAU,IAAI,IAAgB,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC;AAC/D,gBAAQ,IAAI,eAAe,MAAS,CAAC;AACrC,YAAI,IAAI,WAAW,OAAW,SAAQ,IAAI,QAAQ;AAClD,cAAM,SAAS,OAAO,YAAY,CAAC,GAAG,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,cAAc,GAAG,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AAE7F,cAAM,OAAoB,CAAC,GAAG,OAAO,EAAE,IAAI,CAACF,aAAY,EAAE,QAAAA,SAAQ,SAAS,OAAOA,OAAM,GAAI,QAAQ,KAAK,EAAE;AAC3G,mBAAW,EAAE,GAAG,QAAAA,SAAQ,SAAAE,SAAQ,KAAK,QAAQ;AAC3C,cAAI,IAAIF,OAAM,MAAM,OAAW,GAAE,gBAAgBE;AACjD,cAAIA,aAAY,OAAOF,OAAM,GAAG;AAC9B,cAAE,YAAY,UAAUA,SAAQE,QAAO;AACvC,cAAE,aAAa;AACf,iBAAK,KAAK,EAAE,QAAAF,SAAQ,SAAAE,UAAS,QAAQ,MAAM,CAAC;AAAA,UAC9C;AAAA,QACF;AACA,YAAI,SAAS,cAAc,aAAa,IAAI;AAE5C,cAAM,MAAM,UAAU,GAAG;AACzB,YAAI,IAAK,KAAI,SAAS,QAAQ;AAAA,aACzB;AAEH,gBAAM,MAAM,SAAS,QAAQ,SAAS,KAAK,QAAQ,IAAI,QAAQ,IAAI,WAAW,QAAQ;AACtF,cAAI,IAAI,OAAQ,KAAI,SAAS,QAAQ,eAAe,GAAG;AAAA,QACzD;AACA,YAAI,IAAI,YAAY,OAAW,KAAI,SAAS,SAAS,gBAAgB,IAAI,OAAO;AAAA,MAClF;AAAA,IACF;AAAA;AAAA;;;ACjLO,SAAS,eAAe,KAA8B;AAC3D,SAAO,SAAS,IAAI,KAAK,IAAK,IAAI,QAAyB,CAAC;AAC9D;AAGO,SAAS,SAAS,KAA+C;AACtE,SAAO,SAAS,IAAI,MAAM,IAAK,IAAI,SAA2C,CAAC;AACjF;AA6FA,SAAS,qBAAqB,GAA4B,QAAoE;AAC5H,QAAM,MAAuB,CAAC,GAAG,SAAS,GAAG,YAAY,OAAO,CAAC;AACjE,QAAM,QAAQ,CAAC,GAAW,QAAsB;AAC9C,QAAI,CAAC,WAAW,KAAK,CAAC,EAAG,KAAI,KAAK,MAAM,KAAK,GAAG,CAAC,sCAAsC,CAAC;AAAA,aAC/E,UAAU,EAAE,KAAK,QAAS,KAAI,KAAK,MAAM,KAAK,GAAG,CAAC,sBAAsB,CAAC;AAAA,EACpF;AACA,MAAI,EAAE,WAAW,QAAW;AAC1B,QAAI,CAAC,MAAM,QAAQ,EAAE,MAAM,KAAK,EAAE,OAAO,WAAW,KAAK,EAAE,OAAO,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAG,KAAI,KAAK,MAAM,gBAAgB,+BAA+B,CAAC;AAAA,QAChK,YAAW,KAAK,EAAE,OAAoB,OAAM,GAAG,cAAc;AAAA,EACpE;AACA,MAAI,EAAE,UAAU,QAAW;AACzB,QAAI,CAAC,SAAS,EAAE,KAAK,EAAG,KAAI,KAAK,MAAM,eAAe,iDAAiD,CAAC;AAAA,SACnG;AACH,iBAAW,CAAC,OAAO,GAAG,KAAK,OAAO,QAAQ,EAAE,KAAK,GAAG;AAClD,cAAM,MAAM,eAAe,KAAK;AAChC,cAAM,OAAO,GAAG;AAChB,YAAI,CAAC,MAAM,QAAQ,GAAG,KAAK,IAAI,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AACjE,cAAI,KAAK,MAAM,KAAK,+BAA+B,CAAC;AACpD;AAAA,QACF;AACA,mBAAW,KAAK,KAAiB;AAC/B,cAAI,MAAM,MAAO,KAAI,KAAK,MAAM,KAAK,GAAG,KAAK,6BAA6B,CAAC;AAAA,cACtE,OAAM,GAAG,GAAG;AAAA,QACnB;AAAA,MACF;AACA,YAAM,QAAQ,WAAW,EAAE,KAAiC;AAC5D,UAAI,MAAO,KAAI,KAAK,MAAM,eAAe,2BAA2B,MAAM,KAAK,SAAS,CAAC,EAAE,CAAC;AAAA,IAC9F;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,WAAW,OAA0E;AACnG,QAAM,QAAQ,oBAAI,IAA6B;AAC/C,QAAM,OAAiB,CAAC;AACxB,QAAM,QAAQ,CAAC,MAAoC;AACjD,QAAI,MAAM,IAAI,CAAC,MAAM,OAAQ,QAAO;AACpC,QAAI,MAAM,IAAI,CAAC,MAAM,OAAQ,QAAO,CAAC,GAAG,KAAK,MAAM,KAAK,QAAQ,CAAC,CAAC,GAAG,CAAC;AACtE,UAAM,IAAI,GAAG,MAAM;AACnB,SAAK,KAAK,CAAC;AACX,eAAW,KAAK,MAAM,QAAQ,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,IAAK,CAAC,GAAG;AACxD,YAAM,QAAQ,MAAM,CAAC;AACrB,UAAI,MAAO,QAAO;AAAA,IACpB;AACA,SAAK,IAAI;AACT,UAAM,IAAI,GAAG,MAAM;AACnB,WAAO;AAAA,EACT;AACA,aAAW,KAAK,OAAO,KAAK,KAAK,GAAG;AAClC,UAAM,QAAQ,MAAM,CAAC;AACrB,QAAI,MAAO,QAAO;AAAA,EACpB;AACA,SAAO;AACT;AAhMA,IAoBa,YACA,YACP,YAyBO;AA/Cb;AAAA;AAAA;AAgBA;AACA;AAGO,IAAM,aAAa,CAAC,OAAO,SAAS,QAAQ,SAAS;AACrD,IAAM,aAAa,CAAC,UAAU,OAAO;AAC5C,IAAM,aAAa;AAyBZ,IAAM,SAAsB;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,UAAU,OAAO;AAAA,MACxB,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,aAAa;AAAA,UACb,eAAe,EAAE,SAAS,WAAW,OAAO;AAAA,UAC5C,sBAAsB;AAAA,YACpB,MAAM;AAAA,YACN,sBAAsB;AAAA,YACtB,YAAY;AAAA,cACV,KAAK,EAAE,MAAM,UAAU,aAAa,iDAAiD;AAAA,cACrF,OAAO,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,+DAA+D;AAAA,cAC/H,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,UAAU,kBAAkB,OAAO,GAAG,aAAa,oDAAoD;AAAA,cACtI,SAAS;AAAA,YACX;AAAA,UACF;AAAA,QACF;AAAA,QACA,OAAO;AAAA,UACL,aAAa;AAAA,UACb,OAAO;AAAA,YACL,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,UAAU,EAAE,EAAE;AAAA,YAClF;AAAA,cACE,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,YAAY;AAAA,gBACV,QAAQ,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,wDAAwD;AAAA,gBACtI,OAAO;AAAA,kBACL,MAAM;AAAA,kBACN,aAAa;AAAA,kBACb,sBAAsB,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,gBACnE;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC,GAAG,QAAQ,IAAI,QAAQ,QAAQ,CAAC;AAC9D,cAAM,SAAS,SAAS,GAAG;AAC3B,mBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC9C,gBAAM,MAAM,UAAU,IAAI;AAC1B,cAAI,CAAC,WAAW,KAAK,IAAI,EAAG,KAAI,KAAK,MAAM,KAAK,gCAAgC,CAAC;AACjF,cAAI,MAAM,QAAQ,MAAM,OAAW;AACnC,cAAI,CAAC,SAAS,CAAC,GAAG;AAChB,gBAAI,KAAK,MAAM,KAAK,mBAAmB,CAAC;AACxC;AAAA,UACF;AACA,cAAI,KAAK,GAAG,SAAS,GAAG,YAAY,GAAG,CAAC;AACxC,cAAI,EAAE,QAAQ,UAAa,OAAO,EAAE,QAAQ,SAAU,KAAI,KAAK,MAAM,GAAG,GAAG,QAAQ,kBAAkB,CAAC;AACtG,cAAI,EAAE,YAAY,UAAa,OAAO,EAAE,YAAY,SAAU,KAAI,KAAK,MAAM,GAAG,GAAG,YAAY,sBAAsB,CAAC;AACtH,cAAI,KAAK,GAAG,WAAW,EAAE,OAAO,GAAG,GAAG,QAAQ,GAAG,GAAG,MAAM,EAAE,MAAM,OAAO,GAAG,GAAG,OAAO,CAAC;AAAA,QACzF;AACA,YAAI,SAAS,IAAI,KAAK,GAAG;AACvB,cAAI,KAAK,GAAG,qBAAqB,IAAI,OAAO,SAAS,IAAI,MAAM,IAAI,SAAS,MAAS,CAAC;AAAA,QACxF,WAAW,IAAI,UAAU,QAAW;AAClC,cAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,KAAK,IAAI,MAAM,KAAK,CAAC,MAAM,CAAC,MAAM,QAAQ,CAAC,KAAK,EAAE,WAAW,KAAK,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,CAAC,GAAG;AACnI,gBAAI,KAAK,MAAM,SAAS,qDAAqD,CAAC;AAAA,UAChF,OAAO;AACL,kBAAM,OAAO,oBAAI,IAAY;AAC7B,gBAAI,MAAM,QAAQ,CAAC,GAAa,MAAM;AACpC,yBAAW,KAAK,GAAG;AACjB,oBAAI,KAAK,IAAI,CAAC,EAAG,KAAI,KAAK,MAAM,SAAS,CAAC,KAAK,GAAG,CAAC,2BAA2B,CAAC;AAC/E,qBAAK,IAAI,CAAC;AACV,oBAAI,SAAS,IAAI,MAAM,KAAK,EAAE,KAAK,QAAS,KAAI,KAAK,MAAM,SAAS,CAAC,KAAK,GAAG,CAAC,sBAAsB,CAAC;AAAA,cACvG;AAAA,YACF,CAAC;AAAA,UACH;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,mBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,SAAS,GAAG,CAAC,GAAG;AACrD,gBAAM,KAAK,KAAK,CAAC;AACjB,cAAI,QAAQ,KAAK;AAAA,YACf;AAAA,YACA,GAAI,GAAG,QAAQ,SAAY,EAAE,KAAK,GAAG,IAAI,IAAI,CAAC;AAAA,YAC9C,GAAI,GAAG,OAAO,SAAS,EAAE,OAAO,CAAC,GAAG,GAAG,KAAK,EAAE,IAAI,CAAC;AAAA,YACnD,GAAI,GAAG,SAAS,SAAY,EAAE,MAAM,GAAG,KAAK,IAAI,CAAC;AAAA,YACjD,GAAI,GAAG,YAAY,SAAY,EAAE,SAAS,GAAG,QAAQ,IAAI,CAAC;AAAA,UAC5D,CAAC;AAAA,QACH;AACA,YAAI,MAAM,QAAQ,IAAI,KAAK,EAAG,KAAI,SAAS,QAAS,IAAI,MAAqB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;AAC9F,cAAM,EAAE,QAAQ,MAAM,IAAI,eAAe,GAAG;AAC5C,YAAI,QAAQ,OAAQ,KAAI,SAAS,SAAS,CAAC,GAAG,MAAM;AACpD,YAAI,SAAS,OAAO,KAAK,KAAK,EAAE,OAAQ,KAAI,SAAS,QAAQ,OAAO,YAAY,OAAO,QAAQ,KAAK,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAAA,MACpI;AAAA,IACF;AAAA;AAAA;;;AC7EO,SAAS,iBAAiB,KAAwC;AACvE,QAAM,IAAI,SAAS,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC;AACjD,QAAM,MAA8B,CAAC;AACrC,aAAW,KAAK,YAAY;AAC1B,UAAM,IAAI,EAAE,CAAC;AACb,QAAI,OAAO,MAAM,YAAa,gBAAgB,CAAC,EAAE,MAA4B,SAAS,CAAC,EAAG,KAAI,gBAAgB,CAAC,EAAE,KAAK,IAAI;AAAA,EAC5H;AACA,SAAO;AACT;AAGO,SAAS,SAAS,KAAgE;AACvF,QAAM,IAAI,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AAC/C,SAAO,OAAO,EAAE,YAAY,YAAY,EAAE,YAAY,MAAM,OAAO,EAAE,UAAU,YAAY,EAAE,UAAU,KAAK,EAAE,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM,IAAI;AACvJ;AAGO,SAAS,YAAY,KAAoD;AAC9E,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,MAAI,OAAO,EAAE,cAAc,SAAU,QAAO,EAAE,KAAK,EAAE,UAAU;AAC/D,MAAI,SAAS,EAAE,SAAS,EAAG,QAAO,OAAO,YAAY,OAAO,QAAQ,EAAE,SAAS,EAAE,OAAO,CAAC,MAA6B,OAAO,EAAE,CAAC,MAAM,QAAQ,CAAC;AAC/I,SAAO;AACT;AAQO,SAAS,OAAO,GAAyB;AAC9C,MAAI,OAAO,MAAM,SAAU,QAAO;AAClC,QAAM,SAAS,EAAE,KAAK,EAAE,MAAM,KAAK;AACnC,SAAO,OAAO,WAAW,KAAK,OAAO,MAAM,CAAC,MAAM,WAAW,KAAK,CAAC,CAAC;AACtE;AAaO,SAAS,gBAAgB,KAA+B;AAC7D,QAAM,IAAI,SAAS,IAAI,OAAO,IAAI,IAAI,QAAQ,QAAQ;AACtD,SAAO,OAAO,MAAM,YAAa,gBAAsC,SAAS,CAAC,IAAK,IAAsB;AAC9G;AAGO,SAAS,cAAc,KAA0B;AACtD,QAAM,SAAS,OAAO,KAAK,SAAS,GAAG,CAAC;AACxC,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,MAAI,CAAC,MAAM,QAAQ,EAAE,MAAM,EAAG,QAAO;AACrC,QAAM,QAAQ,EAAE,OAAO,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AACvE,SAAO,OAAO,OAAO,CAAC,SAAS,MAAM,KAAK,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,CAAC;AACxE;AAEO,SAAS,gBAAgB,KAA+B;AAC7D,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,QAAQ,IAAI,EAAE,UAAU,EAAE,SAAS,KAAK,EAAE,IAAI,CAAC;AAAA,IAC5D,QAAQ,cAAc,GAAG;AAAA,IACzB,SAAS,gBAAgB,GAAG;AAAA,IAC5B,GAAI,YAAY,GAAG,IAAI,EAAE,WAAW,YAAY,GAAG,EAAE,IAAI,CAAC;AAAA,EAC5D;AACF;AA/HA,IA0Ca,iBAEA,wBAGA,iBAMP,YACO,cACA,aA4BP,WAGA,YA2CO;AAjIb;AAAA;AAAA;AAsCA,IAAAC;AACA;AACA;AAEO,IAAM,kBAAkB,CAAC,SAAS,gBAAgB,MAAM,MAAM;AAE9D,IAAM,yBAAwC;AAG9C,IAAM,kBAAkB;AAAA,MAC7B,cAAc,EAAE,OAAO,gBAAgB,OAAO,CAAC,QAAQ,KAAK,EAAE;AAAA,MAC9D,cAAc,EAAE,OAAO,gBAAgB,OAAO,CAAC,UAAU,KAAK,EAAE;AAAA,MAChE,aAAa,EAAE,OAAO,eAAe,OAAO,CAAC,OAAO,OAAO,EAAE;AAAA,IAC/D;AAEA,IAAM,aAAa,OAAO,KAAK,eAAe;AACvC,IAAM,eAAe,CAAC,SAAS,GAAG,UAAU;AAC5C,IAAM,cAAc,CAAC,WAAW,OAAO;AA4B9C,IAAM,YAAY;AAGlB,IAAM,aAAa;AA2CZ,IAAM,QAAqB;AAAA,MAChC,MAAM;AAAA,MACN,MAAM,CAAC,SAAS,WAAW,QAAQ;AAAA,MACnC,QAAQ;AAAA,QACN,OAAO;AAAA,UACL,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,UAAU,EAAE,MAAM,UAAU,aAAa,yEAA2E;AAAA,YACpH,QAAQ,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,gFAAgF;AAAA,YACjJ,WAAW;AAAA,cACT,aAAa;AAAA,cACb,OAAO;AAAA,gBACL,EAAE,MAAM,UAAU,SAAS,UAAU,OAAO;AAAA,gBAC5C,EAAE,MAAM,UAAU,sBAAsB,EAAE,MAAM,UAAU,SAAS,UAAU,OAAO,EAAE;AAAA,cACxF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,OAAO;AAAA,cACL,MAAM;AAAA,cACN,MAAM,CAAC,GAAG,eAAe;AAAA,cACzB,SAAS;AAAA,cACT,aAAa;AAAA,YACf;AAAA,YACA,cAAc,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,gBAAgB,aAAa,KAAK,GAAG,SAAS,QAAQ,aAAa,kFAAkF;AAAA,YAC/L,cAAc,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,gBAAgB,aAAa,KAAK,GAAG,SAAS,UAAU,aAAa,oGAAoG;AAAA,YACnN,aAAa,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,gBAAgB,YAAY,KAAK,GAAG,SAAS,OAAO,aAAa,8GAA8G;AAAA,UAC1N;AAAA,QACF;AAAA,QACA,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,SAAS,EAAE,MAAM,UAAU,aAAa,sEAAsE;AAAA,YAC9G,OAAO,EAAE,MAAM,UAAU,aAAa,uBAAuB;AAAA,UAC/D;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,YAAI,IAAI,UAAU,QAAW;AAC3B,cAAI,CAAC,SAAS,IAAI,KAAK,EAAG,KAAI,KAAK,MAAM,SAAS,mCAAmC,CAAC;AAAA,eACjF;AACH,kBAAM,IAAI,IAAI;AACd,gBAAI,KAAK,GAAG,SAAS,GAAG,CAAC,YAAY,UAAU,WAAW,GAAG,OAAO,GAAG,GAAG,WAAW,EAAE,QAAQ,cAAc,CAAC;AAC9G,gBAAI,EAAE,cAAc,QAAW;AAC7B,oBAAM,SAAS,OAAO,EAAE,cAAc,WAAW,CAAC,EAAE,SAAS,IAAI,SAAS,EAAE,SAAS,IAAI,OAAO,OAAO,EAAE,SAAS,IAAI;AACtH,kBAAI,CAAC,OAAQ,KAAI,KAAK,MAAM,mBAAmB,8CAA8C,CAAC;AAAA,kBACzF,YAAW,KAAK,OAAQ,KAAI,OAAO,MAAM,YAAY,CAAC,UAAU,KAAK,CAAC,EAAG,KAAI,KAAK,MAAM,mBAAmB,MAAM,KAAK,UAAU,CAAC,CAAC,kEAAkE,CAAC;AAAA,YAC5M;AACA,gBAAI,EAAE,aAAa,OAAW,KAAI,KAAK,QAAQ,SAAS,0EAA0E,CAAC;AAAA,qBAC1H,CAAC,OAAO,EAAE,QAAQ,EAAG,KAAI,KAAK,MAAM,kBAAkB,gDAAkD,CAAC;AAClH,gBAAI,MAAM,QAAQ,EAAE,MAAM,KAAK,SAAS,IAAI,MAAM,KAAK,cAAc,GAAG,EAAE,WAAW,GAAG;AACtF,kBAAI,KAAK,MAAM,gBAAgB,uCAAuC,CAAC;AAAA,YACzE;AAAA,UACF;AAAA,QACF;AACA,YAAI,IAAI,YAAY,QAAW;AAC7B,cAAI,CAAC,SAAS,IAAI,OAAO,EAAG,KAAI,KAAK,MAAM,WAAW,sDAAsD,CAAC;AAAA,eACxG;AACH,gBAAI,KAAK,GAAG,SAAS,IAAI,SAAS,cAAc,SAAS,GAAG,GAAG,MAAM,IAAI,QAAQ,OAAO,iBAAiB,eAAe,CAAC;AACzH,uBAAW,KAAK,WAAY,KAAI,KAAK,GAAG,MAAM,IAAI,QAAQ,CAAC,GAAG,gBAAgB,CAAC,EAAE,OAAO,WAAW,CAAC,EAAE,CAAC;AACvG,gBAAI,IAAI,QAAQ,gBAAgB,WAAW,CAAC,SAAS,GAAG,EAAG,KAAI,KAAK,MAAM,uBAAuB,4EAA4E,CAAC;AAC9K,gBAAI,IAAI,QAAQ,UAAU,QAAQ,IAAI,SAAS,SAAS;AACtD,kBAAI,KAAK,QAAQ,iBAAiB,2EAA2E,CAAC;AAAA,YAChH;AAAA,UACF;AAAA,QACF;AACA,YAAI,IAAI,WAAW,QAAW;AAC5B,cAAI,CAAC,SAAS,IAAI,MAAM,EAAG,KAAI,KAAK,MAAM,UAAU,wCAAwC,CAAC;AAAA,eACxF;AACH,gBAAI,KAAK,GAAG,SAAS,IAAI,QAAQ,aAAa,QAAQ,CAAC;AACvD,uBAAW,KAAK,YAAa,KAAI,OAAO,IAAI,OAAO,CAAC,MAAM,YAAY,IAAI,OAAO,CAAC,MAAM,GAAI,KAAI,KAAK,MAAM,UAAU,CAAC,IAAI,MAAM,YAAY,kDAAkD,2BAA2B,CAAC;AAC1N,gBAAI,EAAE,SAAS,IAAI,OAAO,KAAK,IAAI,QAAQ,gBAAgB,SAAU,KAAI,KAAK,QAAQ,UAAU,uGAAuG,CAAC;AAAA,UAC1M;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,SAAS,iBAAiB,GAAG;AACnC,YAAI,OAAO,KAAK,MAAM,EAAE,OAAQ,KAAI,SAAS,UAAU;AACvD,cAAM,SAAS,SAAS,GAAG;AAE3B,YAAI,OAAQ,KAAI,SAAS,SAAS;AAClC,YAAI,IAAI,UAAU,UAAa,EAAE,SAAS,IAAI,OAAO,KAAK,IAAI,QAAQ,UAAU,QAAY;AAC5F,YAAI,SAAS,QAAQ,gBAAgB,GAAG;AAAA,MAC1C;AAAA,IACF;AAAA;AAAA;;;AC3MO,SAAS,SAAS,KAAgB,SAAmE;AAC1G,MAAI,IAAI,WAAW,YAAY,IAAI,WAAW,SAAU,QAAO,EAAE,QAAQ,IAAI,QAAQ,SAAS,4BAA4B,IAAI,MAAM,GAAG;AACvI,QAAM,MAAM,YAAY,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AACxE,MAAI,OAAO,WAAW,KAAK,GAAG,EAAG,QAAO,EAAE,QAAQ,UAAU,SAAS,eAAe,GAAG,eAAe;AACtG,SAAO;AACT;AA1BA,IAca,SAIA,YAUA;AA5Bb;AAAA;AAAA;AAWA;AACA;AAEO,IAAM,UAAU,CAAC,UAAU,QAAQ;AAInC,IAAM,aAAa;AAUnB,IAAM,SAAsB;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,UAAU,SAAS;AAAA,MAC1B,QAAQ;AAAA,QACN,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,OAAO,GAAG,aAAa,iHAAiH;AAAA,QAC5K,SAAS;AAAA,MACX;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC,GAAG,MAAM,IAAI,QAAQ,SAAS,QAAQ,CAAC;AACrE,YAAI,IAAI,YAAY,UAAa,OAAO,IAAI,YAAY,SAAU,KAAI,KAAK,MAAM,WAAW,sBAAsB,CAAC;AACnH,YAAI,IAAI,WAAW,UAAU;AAC3B,gBAAM,WAAgC,CAAC,CAAC,WAAW,IAAI,OAAO,GAAG,GAAG,OAAO,QAAQ,SAAS,GAAG,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAyB,CAAC,UAAU,CAAC,YAAY,GAAG,OAAO,CAAC,CAAC;AACzK,qBAAW,CAAC,KAAK,GAAG,KAAK,UAAU;AACjC,gBAAI,OAAO,QAAQ,YAAY,WAAW,KAAK,GAAG,GAAG;AACnD,kBAAI,KAAK,MAAM,KAAK,GAAG,GAAG,4FAA4F,CAAC;AAAA,YACzH;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,MAAM,SAAS,GAAG;AACxB,YAAI,IAAK,KAAI,eAAe,SAAS,IAAI;AACzC,YAAI,OAAO,IAAI,YAAY,SAAU,KAAI,eAAe,UAAU,IAAI;AACtE,mBAAW,KAAK,IAAI,SAAS;AAC3B,cAAI,EAAE,YAAY,UAAa,OAAO,IAAI,YAAY,SAAU,GAAE,UAAU,IAAI;AAChF,gBAAM,IAAI,SAAS,KAAK,EAAE,OAAO;AACjC,cAAI,EAAG,GAAE,SAAS,EAAE;AAAA,QACtB;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;AC2BO,SAAS,mBAAmB,GAA+B;AAChE,SAAO,aAAa,KAAK,CAAC,IAAI,SAAY,MAAM,KAAK,UAAU,CAAC,CAAC;AACnE;AAKO,SAAS,cAAc,KAAgB,OAA2C;AACvF,QAAM,QAAQ,SAAS,IAAI,QAAQ,IAAI,IAAI,WAAW,CAAC;AACvD,QAAM,MAA2B,CAAC;AAClC,aAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,SAAS,MAAM,MAAM,CAAC,GAAG;AAC9D,QAAI,CAAC,SAAS,CAAC,EAAG;AAClB,UAAMC,WAAU,SAAS,EAAE,OAAO,EAAE,KAAK;AACzC,UAAMC,MAAK,SAAS,EAAE,EAAE,EAAE,KAAK;AAC/B,QAAI,OAAOD,aAAY,YAAY,OAAOC,QAAO,SAAU;AAC3D,QAAI,KAAK,EAAE,MAAM,SAAAD,UAAS,IAAAC,KAAI,GAAI,MAAM,QAAQ,EAAE,YAAY,IAAI,EAAE,cAAc,EAAE,aAAyB,IAAI,CAAC,EAAG,CAAC;AAAA,EACxH;AACA,QAAMD,WAAU,SAAS,MAAM,OAAO,EAAE,KAAK;AAC7C,QAAMC,MAAK,SAAS,MAAM,EAAE,EAAE,KAAK;AACnC,MAAI,OAAOD,aAAY,YAAY,OAAOC,QAAO,SAAU,KAAI,KAAK,EAAE,SAAAD,UAAS,IAAAC,IAAG,CAAC;AACnF,SAAO;AACT;AAGO,SAAS,eAAe,KAAiC;AAC9D,SAAO,gBAAgB,OAAO,CAAC,MAAM,cAAc,KAAK,CAAC,EAAE,SAAS,CAAC;AACvE;AAGO,SAAS,UAAU,GAAyC;AACjE,SAAO;AAAA,IACL,GAAI,EAAE,cAAc,SAAS,EAAE,cAAc,CAAC,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC;AAAA,IACtE,GAAI,EAAE,SAAS,UAAa,YAAY,IAAI,EAAE,IAAI,IAAI,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,IAAI,EAAE;AAAA,IAC/E,MAAM,EAAE;AAAA,IACR,OAAO,EAAE;AAAA,EACX;AACF;AAGO,SAAS,cAAc,KAAsE;AAClG,QAAM,IAAI,SAAS,IAAI,YAAY,IAAI,IAAI,eAAe,CAAC;AAC3D,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,QAAQ,WAAW,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC;AAAA,IAClD,GAAI,OAAO,EAAE,YAAY,WAAW,EAAE,QAAQ,EAAE,QAAQ,QAAQ,QAAQ,EAAE,EAAE,IAAI,CAAC;AAAA,IACjF,GAAI,OAAO,EAAE,aAAa,WAAW,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,EACnE;AACF;AAGO,SAAS,gBAAgB,KAAmD;AACjF,QAAM,SAAS,eAAe,GAAG;AACjC,MAAI,OAAO,WAAW,EAAG,QAAO;AAChC,QAAM,QAAQ,SAAS,IAAI,QAAQ,IAAI,IAAI,WAAW,CAAC;AACvD,QAAM,QAAwC,CAAC;AAC/C,aAAW,KAAK,QAAQ;AACtB,UAAM,WAAoC,CAAC;AAC3C,QAAI,MAAM,UAAU;AAClB,YAAM,IAAI,cAAc,GAAG;AAC3B,eAAS,eAAe,EAAE;AAC1B,UAAI,EAAE,SAAU,UAAS,WAAW,EAAE;AACtC,UAAI,EAAE,OAAQ,UAAS,SAAS,EAAE;AAAA,IACpC,OAAO;AACL,YAAM,MAAM,SAAS,MAAM,CAAC,CAAC;AAC7B,iBAAW,CAAC,SAAS,KAAK,KAAK,OAAO,QAAQ,eAAe,CAAC,CAAC,EAAG,KAAI,IAAI,OAAO,MAAM,OAAW,UAAS,KAAK,IAAI,IAAI,OAAO;AAAA,IACjI;AACA,UAAM,CAAC,IAAI,EAAE,GAAG,UAAU,OAAO,cAAc,KAAK,CAAC,EAAE,IAAI,SAAS,EAAE;AAAA,EACxE;AACA,SAAO,EAAE,MAAM;AACjB;AAGO,SAAS,gBAAgB,KAAgB,OAAe,KAAa,OAA4H;AACtM,QAAM,WAAW,CAAC,UAAyC,CAAC,OAAO,UAAU,MAAM,KAAK,CAAC,MAAO,EAAE,WAAW,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,GAAG,IAAI,MAAM,GAAG,GAAG,CAAE;AAC5J,QAAM,MAAgF,CAAC;AACvF,aAAW,KAAK,iBAAiB;AAC/B,UAAM,IAAI,cAAc,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,SAAS,EAAE,YAAY,MAAM,EAAE,SAAS,UAAa,YAAY,IAAI,EAAE,IAAI,KAAK,MAAM,EAAE,MAAM,KAAK,EAAE;AACjJ,QAAI,EAAG,KAAI,CAAC,IAAI,EAAE,SAAS,EAAE,SAAS,IAAI,EAAE,IAAI,MAAM,EAAE,SAAS,SAAY,qCAAqC,mBAAmB,EAAE,IAAI,GAAG;AAAA,EAChJ;AACA,SAAO;AACT;AAaA,SAAS,iBAAiB,GAAY,KAA8B;AAClE,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,KAAK,iBAAiB,gBAAgB,KAAK,IAAI,CAAC,kBAAkB,CAAC;AACnG,QAAM,MAAM,CAAC,GAAG,SAAS,GAAG,iBAAiB,GAAG,CAAC;AACjD,aAAW,CAAC,GAAG,EAAE,KAAK,OAAO,QAAQ,CAAC,GAAG;AACvC,QAAI,CAAE,gBAAsC,SAAS,CAAC,EAAG;AACzD,QAAI,OAAO,OAAO,YAAY,OAAO,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,oBAAoB,CAAC;AAAA,aACnF,MAAM,UAAU;AACvB,YAAM,MAAM,mBAAmB,EAAE;AACjC,UAAI,IAAK,KAAI,KAAK,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,GAAG,CAAC;AAAA,IAC7C;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,aAAaD,UAAkBC,KAAa,OAAgC;AACnF,QAAM,IAAI,SAASD,QAAO;AAC1B,QAAM,IAAI,SAASC,GAAE;AACrB,QAAM,MAAuB,CAAC;AAC9B,aAAW,KAAK,iBAAiB;AAC/B,QAAK,EAAE,CAAC,MAAM,YAAgB,EAAE,CAAC,MAAM,QAAY,KAAI,KAAK,MAAM,GAAG,KAAK,IAAI,EAAE,CAAC,MAAM,SAAY,YAAY,IAAI,IAAI,CAAC,IAAI,eAAe,CAAC,YAAY,EAAE,CAAC,MAAM,SAAY,YAAY,IAAI,wBAAwB,EAAE,CAAC,MAAM,SAAY,OAAO,SAAS,MAAM,CAAC;AAAA,aACxP,OAAO,EAAE,CAAC,MAAM,YAAY,EAAE,CAAC,MAAM,EAAE,CAAC,EAAG,KAAI,KAAK,MAAM,OAAO,SAAS,CAAC,6GAA6G,CAAC;AAAA,EACpM;AACA,SAAO;AACT;AA1MA,IAqCa,iBAMA,gBAMP,iBAGA,UAEO,eACA,iBACA,mBAGP,aAuBA,cAOA,UA6EA,WAsCO;AA5Mb;AAAA;AAAA;AAmCA;AAEO,IAAM,kBAAkB,CAAC,OAAO,OAAO,SAAS,QAAQ;AAMxD,IAAM,iBAAiB;AAAA,MAC5B,KAAK,EAAE,QAAQ,UAAU,UAAU,YAAY,UAAU,WAAW;AAAA,MACpE,KAAK,EAAE,UAAU,YAAY,UAAU,YAAY,cAAc,eAAe,cAAc,cAAc;AAAA,MAC5G,OAAO,EAAE,WAAW,YAAY,iBAAiB,kBAAkB,UAAU,YAAY,WAAW,YAAY;AAAA,IAClH;AAEA,IAAM,kBAAkB,OAAO,KAAK,cAAc;AAGlD,IAAM,WAA+D,EAAE,KAAK,CAAC,GAAG,KAAK,CAAC,uBAAuB,GAAG,OAAO,CAAC,0BAA0B,GAAG,QAAQ,CAAC,kBAAkB,EAAE;AAE3K,IAAM,gBAAgB,CAAC,WAAW,MAAM,UAAU,GAAG,eAAe;AACpE,IAAM,kBAAkB,CAAC,WAAW,MAAM,cAAc;AACxD,IAAM,oBAAoB,CAAC,OAAO,WAAW,UAAU;AAG9D,IAAM,cAAc,oBAAI,IAAI,CAAC,KAAK,IAAI,CAAC;AAuBvC,IAAM,eAAe;AAOrB,IAAM,WAAW,CAAC,MAAyC,SAAS,CAAC,IAAI,IAAI,CAAC;AA6E9E,IAAM,YAAwB;AAAA,MAC5B,MAAM;AAAA,MACN,sBAAsB;AAAA,MACtB,YAAY;AAAA,QACV,KAAK,EAAE,MAAM,UAAU,aAAa,mBAAmB;AAAA,QACvD,KAAK,EAAE,MAAM,UAAU,aAAa,2BAA2B;AAAA,QAC/D,OAAO,EAAE,MAAM,UAAU,aAAa,4BAA4B;AAAA,QAClE,QAAQ,EAAE,MAAM,UAAU,SAAS,aAAa,QAAQ,aAAa,uFAAuF;AAAA,MAC9J;AAAA,IACF;AA6BO,IAAM,WAAwB;AAAA,MACnC,MAAM;AAAA,MACN,MAAM,CAAC,YAAY,cAAc;AAAA,MACjC,QAAQ;AAAA,QACN,UAAU;AAAA,UACR,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,SAAS,EAAE,GAAG,WAAW,aAAa,yDAAyD;AAAA,YAC/F,IAAI,EAAE,GAAG,WAAW,aAAa,wDAAwD;AAAA,YACzF,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,aAAa;AAAA,cACb,sBAAsB;AAAA,gBACpB,MAAM;AAAA,gBACN,sBAAsB;AAAA,gBACtB,YAAY;AAAA,kBACV,SAAS;AAAA,kBACT,IAAI;AAAA,kBACJ,cAAc,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,aAAa,gEAAgE;AAAA,gBACzI;AAAA,cACF;AAAA,YACF;AAAA,YACA,GAAG,OAAO,YAAY,gBAAgB,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,UAAU,sBAAsB,OAAO,YAAY,OAAO,YAAY,OAAO,KAAK,eAAe,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;AAAA,UAC5M;AAAA,QACF;AAAA,QACA,cAAc;AAAA,UACZ,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,UAAU,CAAC,KAAK;AAAA,UAChB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,KAAK,EAAE,MAAM,UAAU,aAAa,oBAAoB;AAAA,YACxD,SAAS,EAAE,MAAM,UAAU,aAAa,+EAA+E;AAAA,YACvH,UAAU,EAAE,MAAM,UAAU,aAAa,2DAA2D;AAAA,UACtG;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,gBAAgB,4BAA4B,CAAC;AAAA,eACzE;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,mBAAmB,cAAc,CAAC;AAC1D,gBAAI,OAAO,EAAE,QAAQ,YAAY,CAAC,+BAA+B,KAAK,EAAE,GAAG,EAAG,KAAI,KAAK,MAAM,oBAAoB,qCAAqC,CAAC;AACvJ,gBAAI,EAAE,YAAY,WAAc,OAAO,EAAE,YAAY,YAAY,CAAC,mBAAmB,KAAK,EAAE,OAAO,GAAI,KAAI,KAAK,MAAM,wBAAwB,8BAA8B,CAAC;AAC7K,gBAAI,EAAE,aAAa,WAAc,OAAO,EAAE,aAAa,YAAY,EAAE,aAAa,IAAK,KAAI,KAAK,MAAM,yBAAyB,kBAAkB,CAAC;AAAA,UACpJ;AAAA,QACF;AACA,cAAM,QAAQ,IAAI;AAClB,YAAI,UAAU,QAAW;AACvB,cAAI,SAAS,CAAC,EAAG,KAAI,KAAK,QAAQ,gBAAgB,wLAAwL,CAAC;AAC3O,iBAAO;AAAA,QACT;AACA,YAAI,CAAC,SAAS,KAAK,EAAG,QAAO,CAAC,GAAG,KAAK,MAAM,YAAY,6CAA6C,CAAC;AACtG,YAAI,KAAK,GAAG,SAAS,OAAO,eAAe,UAAU,CAAC;AACtD,YAAI,KAAK,GAAG,iBAAiB,MAAM,SAAS,kBAAkB,GAAG,GAAG,iBAAiB,MAAM,IAAI,aAAa,GAAG,GAAG,aAAa,MAAM,SAAS,MAAM,IAAI,UAAU,CAAC;AACnK,YAAI,MAAM,WAAW,QAAW;AAC9B,cAAI,CAAC,SAAS,MAAM,MAAM,EAAG,KAAI,KAAK,MAAM,mBAAmB,sCAAsC,CAAC;AAAA,eACjG;AACH,uBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,MAAM,MAAM,GAAG;AACpD,oBAAM,MAAM,mBAAmB,IAAI;AACnC,kBAAI,CAAC,SAAS,CAAC,GAAG;AAChB,oBAAI,KAAK,MAAM,KAAK,yBAAyB,CAAC;AAC9C;AAAA,cACF;AACA,kBAAI,KAAK,GAAG,SAAS,GAAG,iBAAiB,GAAG,GAAG,GAAG,iBAAiB,EAAE,SAAS,GAAG,GAAG,UAAU,GAAG,GAAG,iBAAiB,EAAE,IAAI,GAAG,GAAG,KAAK,GAAG,GAAG,aAAa,EAAE,SAAS,EAAE,IAAI,GAAG,CAAC;AAC9K,kBAAI,EAAE,iBAAiB,WAAc,CAAC,MAAM,QAAQ,EAAE,YAAY,KAAK,EAAE,aAAa,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAI,KAAI,KAAK,MAAM,GAAG,GAAG,iBAAiB,qCAAqC,CAAC;AAAA,YACzM;AAAA,UACF;AAAA,QACF;AACA,mBAAW,KAAK,iBAAiB;AAC/B,gBAAM,IAAI,MAAM,CAAC;AACjB,cAAI,MAAM,OAAW;AACrB,cAAI,CAAC,SAAS,CAAC,GAAG;AAChB,gBAAI,KAAK,MAAM,YAAY,CAAC,IAAI,wBAAwB,OAAO,KAAK,eAAe,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AACpG;AAAA,UACF;AACA,cAAI,KAAK,GAAG,SAAS,GAAG,OAAO,KAAK,eAAe,CAAC,CAAC,GAAG,YAAY,CAAC,EAAE,CAAC;AACxE,qBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,CAAC,EAAG,KAAI,OAAO,MAAM,YAAY,MAAM,GAAI,KAAI,KAAK,MAAM,YAAY,CAAC,IAAI,CAAC,IAAI,kBAAkB,CAAC;AAAA,QACzI;AACA,mBAAW,KAAK,eAAe,GAAG,GAAG;AACnC,qBAAW,OAAO,SAAS,CAAC,GAAG;AAC7B,kBAAM,CAAC,KAAK,GAAG,IAAI,IAAI,IAAI,MAAM,GAAG;AACpC,gBAAI,IAAa,IAAI,GAAI;AACzB,uBAAW,OAAO,KAAM,KAAI,SAAS,CAAC,IAAI,EAAE,GAAG,IAAI;AACnD,gBAAI,MAAM,OAAW,KAAI,KAAK,MAAM,KAAK,+BAA+B,CAAC,aAAa,CAAC;AAAA,UACzF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,KAAK,gBAAgB,GAAG;AAC9B,YAAI,GAAI,KAAI,GAAG,WAAW;AAAA,MAC5B;AAAA,IACF;AAAA;AAAA;;;ACrPA,SAAS,iBAAiB,MAAc,KAA8B;AACpE,MAAI,CAACC,UAAS,KAAK,IAAI,EAAG,QAAO,CAAC,MAAM,KAAK,GAAG,KAAK,UAAU,IAAI,CAAC,2EAA2E,CAAC;AAChJ,MAAI,mBAAmB,SAAS,IAAI,EAAG,QAAO,CAAC,MAAM,KAAK,GAAG,IAAI,uHAAuH,CAAC;AACzL,SAAO,CAAC;AACV;AAGO,SAAS,cAAc,GAAoC;AAChE,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,OAAO,YAAY,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC;AACtH,MAAI,SAAS,CAAC,EAAG,QAAO,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE,OAAO,CAAC,MAA6B,OAAO,EAAE,CAAC,MAAM,QAAQ,CAAC;AAC3H,SAAO,CAAC;AACV;AAGO,SAAS,eAAe,GAAyC;AACtE,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC;AAC1B,SAAO,OAAO,QAAQ,CAAC,EAAE,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM;AAC9C,QAAI,OAAO,MAAM,SAAU,QAAO,CAAC,EAAE,MAAM,aAAa,EAAE,MAAM,EAAE,EAAE,CAAC;AACrE,QAAI,SAAS,CAAC,KAAK,OAAO,EAAE,SAAS,SAAU,QAAO,CAAC,EAAE,MAAM,aAAa,EAAE,MAAM,EAAE,MAAM,GAAI,OAAO,EAAE,QAAQ,WAAW,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,EAAG,EAAE,CAAC;AACpJ,WAAO,CAAC;AAAA,EACV,CAAC;AACH;AAGO,SAAS,cAAc,KAA2C;AACvE,QAAM,YAAY,SAAS,IAAI,GAAG,IAAI,OAAO,YAAY,OAAO,QAAQ,IAAI,GAAG,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;AACrH,SAAO;AAAA,IACL;AAAA,IACA,SAAS,cAAc,IAAI,IAAI;AAAA,IAC/B,GAAI,OAAO,IAAI,gBAAgB,WAAW,EAAE,aAAa,IAAI,YAAY,IAAI,CAAC;AAAA,IAC9E,cAAc,eAAe,IAAI,YAAY;AAAA,EAC/C;AACF;AAxFA,IAuBaA,WAGA,oBAuBP,mBAyCO;AA1Fb;AAAA;AAAA;AAmBA;AACA,IAAAC;AAGO,IAAMD,YAAW;AAGjB,IAAM,qBAAwC;AAAA,MACnD;AAAA,MAAgB;AAAA,MAAe;AAAA,MAAiB;AAAA,MAAgB;AAAA,MAAgB;AAAA,MAChF;AAAA,MAAgC;AAAA,MAChC;AAAA,MAAY;AAAA,MAAa;AAAA,MAAY;AAAA,MAAa;AAAA,MAAwB;AAAA,IAC5E;AAmBA,IAAM,oBAAgC;AAAA,MACpC,OAAO;AAAA,QACL,EAAE,MAAM,UAAU,WAAW,EAAE;AAAA,QAC/B,EAAE,MAAM,UAAU,sBAAsB,OAAO,UAAU,CAAC,MAAM,GAAG,YAAY,EAAE,MAAM,EAAE,MAAM,UAAU,WAAW,EAAE,GAAG,KAAK,EAAE,MAAM,SAAS,EAAE,EAAE;AAAA,MACrJ;AAAA,IACF;AAoCO,IAAM,OAAoB;AAAA,MAC/B,MAAM;AAAA,MACN,MAAM,CAAC,OAAO,QAAQ,eAAe,cAAc;AAAA,MACnD,QAAQ;AAAA,QACN,KAAK;AAAA,UACH,aAAa;AAAA,UACb,MAAM;AAAA,UACN,eAAe,EAAE,SAASA,UAAS,OAAO;AAAA,UAC1C,sBAAsB,EAAE,MAAM,CAAC,UAAU,UAAU,SAAS,EAAE;AAAA,QAChE;AAAA,QACA,MAAM;AAAA,UACJ,aAAa;AAAA,UACb,OAAO;AAAA,YACL,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,SAASA,UAAS,OAAO,GAAG,aAAa,KAAK;AAAA,YACxF,EAAE,MAAM,UAAU,eAAe,EAAE,SAASA,UAAS,OAAO,GAAG,sBAAsB,EAAE,MAAM,UAAU,SAASA,UAAS,OAAO,EAAE;AAAA,UACpI;AAAA,QACF;AAAA,QACA,aAAa;AAAA,UACX,aAAa;AAAA,UACb,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,QACA,cAAc;AAAA,UACZ,aAAa;AAAA,UACb,MAAM;AAAA,UACN,sBAAsB;AAAA,QACxB;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,YAAI,IAAI,QAAQ,QAAW;AACzB,cAAI,CAAC,SAAS,IAAI,GAAG,EAAG,KAAI,KAAK,MAAM,OAAO,wCAAwC,CAAC;AAAA;AAErF,uBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG,GAAG;AAC5C,kBAAI,KAAK,GAAG,iBAAiB,GAAG,OAAO,CAAC,EAAE,CAAC;AAC3C,kBAAI,CAAC,CAAC,UAAU,UAAU,SAAS,EAAE,SAAS,OAAO,CAAC,EAAG,KAAI,KAAK,MAAM,OAAO,CAAC,IAAI,6CAA6C,CAAC;AAAA,YACpI;AAAA,QACJ;AACA,YAAI,IAAI,SAAS,QAAW;AAC1B,cAAI,CAAC,MAAM,QAAQ,IAAI,IAAI,KAAK,CAAC,SAAS,IAAI,IAAI,EAAG,KAAI,KAAK,MAAM,QAAQ,oEAAoE,CAAC;AAAA,mBACxI,MAAM,QAAQ,IAAI,IAAI,KAAK,IAAI,KAAK,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAG,KAAI,KAAK,MAAM,QAAQ,gCAAgC,CAAC;AAAA,mBAChI,SAAS,IAAI,IAAI,KAAK,OAAO,OAAO,IAAI,IAAI,EAAE,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,EAAG,KAAI,KAAK,MAAM,QAAQ,6DAA6D,CAAC;AAAA;AAE9K,uBAAW,CAAC,GAAG,MAAM,KAAK,OAAO,QAAQ,cAAc,IAAI,IAAI,CAAC,GAAG;AACjE,kBAAI,KAAK,GAAG,iBAAiB,GAAG,QAAQ,CAAC,EAAE,CAAC;AAC5C,kBAAI,CAACA,UAAS,KAAK,MAAM,EAAG,KAAI,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,KAAK,UAAU,MAAM,CAAC,uBAAuB,CAAC;AACzG,kBAAI,SAAS,IAAI,GAAG,KAAK,KAAK,IAAI,IAAK,KAAI,KAAK,MAAM,QAAQ,CAAC,IAAI,GAAG,CAAC,uEAAuE,CAAC;AAAA,YACjJ;AAAA,QACJ;AACA,YAAI,IAAI,gBAAgB,UAAa,EAAE,OAAO,IAAI,gBAAgB,YAAY,OAAO,UAAU,IAAI,WAAW,KAAK,IAAI,eAAe,IAAI;AACxI,cAAI,KAAK,MAAM,eAAe,qCAAqC,CAAC;AAAA,QACtE;AACA,YAAI,IAAI,iBAAiB,QAAW;AAClC,cAAI,CAAC,SAAS,IAAI,YAAY,EAAG,KAAI,KAAK,MAAM,gBAAgB,gDAAgD,CAAC;AAAA,eAC5G;AACH,kBAAM,QAAQ,SAAS,IAAI,KAAK,IAAI,IAAI,MAAM,OAAO;AACrD,gBAAI,UAAU,UAAW,KAAI,KAAK,MAAM,gBAAgB,qGAAqG,CAAC;AAC9J,kBAAM,SAAS,SAAS,IAAI,MAAM,IAAI,OAAO,KAAK,IAAI,MAAM,IAAI,CAAC;AACjE,uBAAW,CAAC,MAAM,CAAC,KAAK,OAAO,QAAQ,IAAI,YAAY,GAAG;AACxD,oBAAM,QAAQ,OAAO,MAAM,WAAW,IAAI,SAAS,CAAC,IAAI,EAAE,OAAO;AACjE,kBAAI,OAAO,UAAU,YAAY,MAAM,KAAK,MAAM,GAAI,KAAI,KAAK,MAAM,gBAAgB,IAAI,IAAI,sFAAsF,CAAC;AAAA,uBAC3K,SAAS,CAAC,KAAK,OAAO,KAAK,CAAC,EAAE,KAAK,CAAC,MAAM,MAAM,UAAU,MAAM,KAAK,EAAG,KAAI,KAAK,MAAM,gBAAgB,IAAI,IAAI,oBAAoB,CAAC;AAC7I,kBAAI,OAAO,SAAS,KAAK,CAAC,OAAO,KAAK,CAAC,MAAM,YAAY,MAAM,CAAC,CAAC,EAAG,KAAI,KAAK,QAAQ,gBAAgB,IAAI,IAAI,+BAA+B,CAAC;AAAA,YAC/I;AAAA,UACF;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,IAAI,cAAc,GAAG;AAC3B,YAAI,OAAO,KAAK,EAAE,SAAS,EAAE,UAAU,OAAO,KAAK,EAAE,OAAO,EAAE,UAAU,EAAE,gBAAgB,UAAa,EAAE,aAAa,OAAQ,KAAI,SAAS,OAAO;AAAA,MACpJ;AAAA,IACF;AAAA;AAAA;;;AClKA,IASa,YAEA;AAXb;AAAA;AAAA;AASO,IAAM,aAA+C,CAAC;AAEtD,IAAM,QAAqB;AAAA,MAChC,MAAM;AAAA,MACN,MAAM,OAAO,KAAK,UAAU;AAAA,MAC5B,QAAQ,OAAO,YAAY,OAAO,KAAK,UAAU,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,EAAE,aAAa,gDAAgD,CAAC,CAAC,CAAC;AAAA,MACpI,OAAO,MAAM,CAAC;AAAA,MACd,YAAY;AAAA,MAAC;AAAA,IACf;AAAA;AAAA;;;ACsBO,SAAS,aAAa,KAAgBE,SAAsD;AACjG,QAAM,MAAM,QAAQ,GAAG,EAAE;AACzB,MAAI,IAAK,QAAO;AAChB,SAAOA,UAAS,mBAAmBA,OAAM,IAAI;AAC/C;AAMO,SAAS,QAAQ,KAAwD;AAC9E,QAAM,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,QAAQ,CAAC;AAC7C,SAAO;AAAA,IACL,MAAM,EAAE,SAAS,OAAO,OAAO;AAAA,IAC/B,GAAI,EAAE,UAAU,WAAW,EAAE,UAAU,aAAa,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,EAC5E;AACF;AAGA,SAAS,YAAY,KAA0B;AAC7C,MAAI,IAAI,WAAW,SAAU,QAAO,CAAC;AACrC,QAAM,QAAQ,OAAO,KAAK,SAAS,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,SAAS,KAAK,SAAS,GAAG,EAAE,CAAC,GAAG,OAAO,GAAG,WAAW,QAAQ;AACpH,SAAO,MAAM,SAAS,QAAQ,CAAC,aAAa;AAC9C;AA9DA,IA6Ba,YAEA,oBAEA,aAGA,oBASA,aACA,eAkBA;AAhEb;AAAA;AAAA;AAwBA;AACA;AACA;AAGO,IAAM,aAAa,CAAC,WAAW,IAAI;AAEnC,IAAM,qBAAgC;AAEtC,IAAM,cAAc,CAAC,YAAY,OAAO;AAGxC,IAAM,qBAA0D,EAAE,QAAQ,YAAY,QAAQ,QAAQ;AAStG,IAAM,cAAyD,EAAE,SAAS,QAAQ,IAAI,QAAQ;AAC9F,IAAM,gBAA6D,EAAE,UAAU,YAAY,OAAO,SAAS;AAkB3G,IAAM,QAAqB;AAAA,MAChC,MAAM;AAAA,MACN,MAAM,CAAC,OAAO;AAAA,MACd,QAAQ;AAAA,QACN,OAAO;AAAA,UACL,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,YAAY;AAAA,YACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,UAAU,GAAG,SAAS,oBAAoB,aAAa,kGAAkG;AAAA,YAC3L,OAAO,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,WAAW,GAAG,aAAa,uHAAuH;AAAA,UACvL;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,YAAI,IAAI,UAAU,OAAW,QAAO,CAAC;AACrC,YAAI,CAAC,SAAS,IAAI,KAAK,EAAG,QAAO,CAAC,MAAM,SAAS,mBAAmB,CAAC;AACrE,cAAM,MAAuB,CAAC,GAAG,SAAS,IAAI,OAAO,CAAC,QAAQ,OAAO,GAAG,OAAO,GAAG,GAAG,MAAM,IAAI,MAAM,MAAM,YAAY,YAAY,GAAG,GAAG,MAAM,IAAI,MAAM,OAAO,aAAa,aAAa,CAAC;AAC3L,YAAI,IAAI,MAAM,UAAU,YAAY;AAClC,gBAAM,QAAQ,YAAY,GAAG;AAC7B,cAAI,MAAM,QAAQ;AAChB,gBAAI,KAAK,MAAM,eAAe,qCAAqC,MAAM,KAAK,IAAI,CAAC,4HAA4H,CAAC;AAAA,UAClN;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,EAAE,MAAM,MAAM,IAAI,QAAQ,GAAG;AACnC,YAAI,GAAG,QAAQ,YAAY,IAAI;AAC/B,YAAI,MAAO,KAAI,GAAG,YAAY,cAAc,KAAK;AAAA,MACnD;AAAA,IACF;AAAA;AAAA;;;ACrCO,SAAS,eAAeC,SAA2B,OAAuE;AAC/H,MAAIA,QAAO,UAAU,UAAa,OAAO,OAAO,uBAAuB,SAAU,QAAO,EAAE,GAAGA,QAAO;AACpG,QAAM,EAAE,OAAO,QAAQ,GAAG,KAAK,IAAIA;AACnC,SAAO;AACT;AAgBA,SAAS,SAAS,GAAY,KAA8B;AAC1D,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,SAAO,OAAO,MAAM,YAAYC,UAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,KAAK,2GAA2G,CAAC;AAClL;AAGO,SAAS,cAAc,KAA+C;AAC3E,QAAM,IAAI,IAAI;AACd,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO;AACzB,QAAM,QAAQ,SAAS,EAAE,KAAK,IAAI,EAAE,MAAM,UAAU;AACpD,QAAM,QAAQ,SAAS,EAAE,KAAK,IAAI,EAAE,MAAM,UAAU;AACpD,QAAM,OAAO,SAAS,EAAE,OAAO,IAAI,EAAE,UAAU,CAAC;AAChD,QAAM,KAAK,MAAM,QAAQ,EAAE,EAAE,IAAK,EAAE,GAAgB,OAAO,CAAC,MAAuB,KAAK,aAAa,IAAI;AACzG,QAAM,MAAyB;AAAA,IAC7B,GAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,SAAS,KAAK,IAAI,IAAI,CAAC;AAAA,IAC5D,GAAI,OAAO,KAAK,QAAQ,WAAW,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC;AAAA,IACxD,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;AAAA,IAC7C,GAAI,OAAO,UAAU,WAAW,EAAE,MAAM,IAAI,CAAC;AAAA,IAC7C,GAAI,KAAK,EAAE,QAAQ,CAAC,GAAG,IAAI,IAAI,GAAG,IAAI,CAAC,MAAM,cAAc,CAAC,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;AAAA,IACtE,GAAI,OAAO,EAAE,UAAU,WAAW,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,EAC1D;AACA,SAAO,IAAI,WAAW,IAAI,SAAS,IAAI,QAAQ,MAAM;AACvD;AAGO,SAAS,YAAY,KAAmC;AAC7D,QAAM,IAAI,SAAS,IAAI,SAAS,IAAI,IAAI,YAAY,CAAC;AACrD,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,aAAa,WAAW,EAAE,UAAU,EAAE,SAAS,QAAQ,QAAQ,EAAE,EAAE,IAAI,CAAC;AAAA,IACrF,GAAI,OAAO,EAAE,gBAAgB,WAAW,EAAE,YAAY,EAAE,YAAY,IAAI,CAAC;AAAA,IACzE,aAAa,OAAO,EAAE,iBAAiB,WAAW,EAAE,eAAe;AAAA,IACnE,QAAQ,EAAE,WAAW;AAAA,EACvB;AACF;AA9GA,IAqCa,eAiCPA,WACO,sBAGA,gBACP,eAqCA,aAEO;AAlHb;AAAA;AAAA;AAkCA;AAGO,IAAM,gBAAgB,EAAE,gBAAgB,WAAW,cAAc,WAAW,aAAa,UAAU,OAAO,QAAQ;AAiCzH,IAAMA,YAAW;AACV,IAAM,uBAAuB;AAG7B,IAAM,iBAAiB,CAAC,MAAM,MAAM,MAAM,MAAM;AACvD,IAAM,gBAAgB,oBAAI,IAAI,CAAC,MAAM,IAAI,CAAC;AAqC1C,IAAM,cAAc,EAAE,MAAM,UAAU,sBAAsB,OAAO,UAAU,CAAC,SAAS,GAAG,YAAY,EAAE,SAAS,EAAE,MAAM,UAAU,SAASA,UAAS,QAAQ,aAAa,mDAAmD,EAAE,EAAE;AAE1N,IAAM,UAAuB;AAAA,MAClC,MAAM;AAAA,MACN,MAAM,CAAC,UAAU,aAAa,SAAS;AAAA,MACvC,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,OAAO;AAAA,YACP,OAAO;AAAA,YACP,SAAS;AAAA,cACP,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,UAAU,CAAC,OAAO,KAAK;AAAA,cACvB,aAAa;AAAA,cACb,YAAY;AAAA,gBACV,KAAK,EAAE,MAAM,UAAU,SAASA,UAAS,QAAQ,aAAa,0CAA0C;AAAA,gBACxG,KAAK,EAAE,MAAM,UAAU,SAASA,UAAS,QAAQ,aAAa,wCAAwC;AAAA,cACxG;AAAA,YACF;AAAA,YACA,IAAI,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,UAAU,MAAM,OAAO,KAAK,aAAa,EAAE,GAAG,aAAa,4CAA4C;AAAA,YAC3I,OAAO,EAAE,MAAM,UAAU,SAASA,UAAS,QAAQ,aAAa,2IAA2I;AAAA,UAC7M;AAAA,QACF;AAAA,QACA,WAAW;AAAA,UACT,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,UAAU,EAAE,MAAM,UAAU,aAAa,+CAA+C;AAAA,YACxF,aAAa,EAAE,MAAM,UAAU,SAASA,UAAS,QAAQ,aAAa,oDAAoD;AAAA,YAC1H,cAAc,EAAE,MAAM,UAAU,SAAS,sBAAsB,aAAa,4BAA4B;AAAA,YACxG,QAAQ,EAAE,MAAM,WAAW,SAAS,MAAM,aAAa,0BAA0B;AAAA,UACnF;AAAA,QACF;AAAA,QACA,SAAS;AAAA,UACP,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,UAAU,CAAC,KAAK;AAAA,UAChB,aAAa;AAAA,UACb,YAAY,EAAE,KAAK,EAAE,MAAM,UAAU,aAAa,uGAAuG,EAAE;AAAA,QAC7J;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC;AAC9B,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,UAAU,mDAAmD,CAAC;AAAA,eAC1F;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,CAAC,SAAS,SAAS,WAAW,MAAM,OAAO,GAAG,QAAQ,CAAC;AAC/E,gBAAI,EAAE,UAAU,QAAW;AACzB,kBAAI,KAAK,GAAG,SAAS,EAAE,OAAO,cAAc,CAAC;AAE7C,kBAAI,EAAE,UAAU,UAAa,EAAE,UAAU,OAAW,KAAI,KAAK,MAAM,gBAAgB,6EAA6E,CAAC;AAAA,kBAC5J,KAAI,KAAK,QAAQ,gBAAgB,mIAAmI,CAAC;AAAA,YAC5K;AACA,uBAAW,QAAQ,CAAC,SAAS,OAAO,GAAY;AAC9C,oBAAM,IAAI,EAAE,IAAI;AAChB,kBAAI,MAAM,OAAW;AACrB,kBAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,UAAU,IAAI,IAAI,4BAA4B,CAAC;AAAA,kBAC3E,KAAI,KAAK,GAAG,SAAS,GAAG,CAAC,SAAS,GAAG,UAAU,IAAI,EAAE,GAAG,GAAI,EAAE,YAAY,SAAY,CAAC,MAAM,UAAU,IAAI,YAAY,aAAa,CAAC,IAAI,SAAS,EAAE,SAAS,UAAU,IAAI,UAAU,CAAE;AAAA,YAC9L;AACA,gBAAI,EAAE,YAAY,QAAW;AAC3B,kBAAI,CAAC,SAAS,EAAE,OAAO,EAAG,KAAI,KAAK,MAAM,kBAAkB,yCAAyC,CAAC;AAAA,mBAChG;AACH,oBAAI,KAAK,GAAG,SAAS,EAAE,SAAS,CAAC,OAAO,KAAK,GAAG,gBAAgB,GAAG,GAAG,SAAS,EAAE,QAAQ,KAAK,oBAAoB,GAAG,GAAG,SAAS,EAAE,QAAQ,KAAK,oBAAoB,CAAC;AAErK,2BAAW,KAAK,CAAC,OAAO,KAAK,EAAY,KAAI,EAAE,QAAQ,CAAC,MAAM,OAAW,KAAI,KAAK,MAAM,kBAAkB,CAAC,IAAI,6DAA6D,CAAC;AAAA,cAC/K;AAAA,YACF;AACA,gBAAI,EAAE,OAAO,QAAW;AACtB,kBAAI,CAAC,MAAM,QAAQ,EAAE,EAAE,KAAK,EAAE,GAAG,WAAW,EAAG,KAAI,KAAK,MAAM,aAAa,gBAAgB,OAAO,KAAK,aAAa,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,kBAC9H,YAAW,KAAK,EAAE,GAAI,KAAI,OAAO,MAAM,YAAY,EAAE,KAAK,eAAgB,KAAI,KAAK,MAAM,aAAa,OAAO,KAAK,UAAU,CAAC,CAAC,oBAAoB,OAAO,KAAK,aAAa,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,YACjM;AACA,gBAAI,SAAS,CAAC,KAAK,EAAE,UAAU,UAAa,EAAE,UAAU,UAAa,EAAE,YAAY,OAAW,KAAI,KAAK,MAAM,UAAU,kCAAkC,CAAC;AAAA,UAC5J;AAAA,QACF;AACA,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,aAAa,qEAAqE,CAAC;AAAA,eAC/G;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,CAAC,YAAY,eAAe,gBAAgB,QAAQ,GAAG,WAAW,GAAG,GAAG,SAAS,EAAE,aAAa,uBAAuB,CAAC;AAChJ,gBAAI,EAAE,aAAa,WAAc,OAAO,EAAE,aAAa,YAAY,CAAC,mBAAmB,KAAK,EAAE,QAAQ,GAAI,KAAI,KAAK,MAAM,sBAAsB,8BAA8B,CAAC;AAC9K,gBAAI,OAAO,EAAE,aAAa,YAAY,wBAAwB,KAAK,EAAE,QAAQ,EAAG,KAAI,KAAK,MAAM,sBAAsB,0EAA0E,CAAC;AAChM,gBAAI,EAAE,iBAAiB,WAAc,OAAO,EAAE,iBAAiB,YAAY,EAAE,iBAAiB,IAAK,KAAI,KAAK,MAAM,0BAA0B,kBAAkB,CAAC;AAC/J,gBAAI,EAAE,WAAW,UAAa,OAAO,EAAE,WAAW,UAAW,KAAI,KAAK,MAAM,oBAAoB,kBAAkB,CAAC;AAAA,UACrH;AAAA,QACF;AACA,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,WAAW,YAAY,CAAC;AAAA,eACpD;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,CAAC,KAAK,GAAG,SAAS,CAAC;AAC3C,kBAAM,SAAS,OAAO,EAAE,QAAQ,WAAW,wBAAwB,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI;AACtF,gBAAI,CAAC,UAAU,CAAE,eAAqC,SAAS,MAAM,EAAG,KAAI,KAAK,MAAM,eAAe,QAAQ,eAAe,IAAI,CAAC,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,IAAI,CAAC,MAAM,CAAC;AAAA,qBAC3J,cAAc,IAAI,MAAM,EAAG,KAAI,KAAK,QAAQ,eAAe,GAAG,MAAM,6GAA6G,CAAC;AAAA,UAC7L;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAMD,UAAS,cAAc,GAAG;AAChC,YAAIA,QAAQ,KAAI,SAAS,SAASA;AAClC,YAAI,SAAS,IAAI,OAAO,KAAK,OAAO,IAAI,QAAQ,QAAQ,SAAU,KAAI,GAAG,YAAY,IAAI,QAAQ;AAAA,MACnG;AAAA,IACF;AAAA;AAAA;;;AC1LA,SAAS,aAAa;AAmBf,SAAS,uBAAyC;AACvD,2BAAyB,YAAY;AACnC,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,gCAAgC;AAChF,qBAAe,OAAO,EAAE,2BAA2B,YAAY,OAAO,EAAE,2BAA2B;AAAA,IACrG,QAAQ;AACN,qBAAe;AAAA,IACjB;AACA,WAAO;AAAA,EACT,GAAG;AACH,SAAO;AACT;AAGO,SAAS,uBAAgC;AAC9C,SAAO;AACT;AA4CA,SAAS,SAAS,GAAY,KAA8B;AAC1D,MAAI,OAAO,MAAM,YAAY,EAAE,KAAK,MAAM,GAAI,QAAO,CAAC,MAAM,KAAK,iCAAiC,CAAC;AACnG,MAAI,EAAE,WAAW,GAAG,KAAK,EAAE,WAAW,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,SAAS,IAAI,EAAG,QAAO,CAAC,MAAM,KAAK,MAAM,KAAK,UAAU,CAAC,CAAC,0DAA0D,CAAC;AAChL,SAAO,CAAC;AACV;AAGO,SAAS,UAAU,GAAmB;AAC3C,QAAM,MAAM,MAAM,UAAU,CAAC,EAAE,QAAQ,QAAQ,EAAE;AACjD,SAAO,QAAQ,KAAK,MAAM;AAC5B;AAGO,SAAS,cAAc,KAA8B;AAC1D,QAAM,QAAQ,SAAS,IAAI,MAAM,KAAK,MAAM,QAAQ,IAAI,OAAO,KAAK,IAAI,IAAI,OAAO,QAAQ,CAAC;AAC5F,SAAO,MAAM,QAAQ,CAAC,MAAoB;AACxC,QAAI,OAAO,MAAM,SAAU,QAAO,CAAC,EAAE,KAAK,UAAU,CAAC,EAAE,CAAC;AACxD,QAAI,SAAS,CAAC,KAAK,OAAO,EAAE,QAAQ,SAAU,QAAO,CAAC,EAAE,KAAK,UAAU,EAAE,GAAG,GAAG,GAAI,OAAO,EAAE,WAAW,WAAW,EAAE,QAAQ,UAAU,EAAE,MAAM,EAAE,IAAI,CAAC,EAAG,CAAC;AACzJ,WAAO,CAAC;AAAA,EACV,CAAC;AACH;AAOO,SAAS,cAAc,OAA8B,UAAgC;AAC1F,QAAM,OAAO,UAAU,QAAQ;AAC/B,QAAM,MAAM,CAAC,MAAsB;AACjC,UAAM,IAAI,MAAM,SAAS,SAAS,MAAM,KAAK,MAAM,CAAC;AAEpD,WAAO,MAAM,KAAK,MAAM,EAAE,WAAW,GAAG,IAAI,KAAK,CAAC,KAAK;AAAA,EACzD;AACA,SAAO,MAAM,IAAI,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE,GAAG,GAAG,GAAI,EAAE,SAAS,EAAE,QAAQ,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,EAAG,EAAE;AAC/F;AAGO,SAAS,kBAAkB,KAAsC;AACtE,QAAM,OAAO,SAAS,IAAI,MAAM,IAAI,IAAI,OAAO,YAAY;AAC3D,SAAO,MAAM,QAAQ,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,IAAI;AAC3G;AAGO,SAAS,eAAe,KAA+C;AAC5E,QAAM,MAAM,SAAS,IAAI,MAAM,IAAI,IAAI,OAAO,SAAS;AACvD,MAAI,CAAC,SAAS,GAAG,KAAK,OAAO,IAAI,SAAS,YAAY,OAAO,IAAI,QAAQ,SAAU,QAAO;AAC1F,SAAO,EAAE,MAAM,IAAI,MAAM,KAAK,IAAI,KAAK,GAAI,OAAO,IAAI,SAAS,WAAW,EAAE,MAAM,UAAU,IAAI,IAAI,EAAE,IAAI,CAAC,EAAG;AAChH;AAQO,SAAS,cAAc,KAAgB,mBAAmB,qBAAqB,GAAoC;AACxH,QAAM,IAAI,IAAI;AACd,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO;AACzB,QAAM,OAAO,OAAO,EAAE,SAAS,WAAW,UAAU,EAAE,IAAI,IAAI;AAC9D,QAAM,UAAU,MAAM,QAAQ,EAAE,OAAO,IAAK,EAAE,UAAuB;AACrE,QAAM,SAAS,mBAAmB,eAAe,GAAG,IAAI;AACxD,QAAM,QAAQ,mBAAmB,cAAc,GAAG,IAAI,CAAC;AACvD,MAAI,SAAS,UAAa,YAAY,UAAa,EAAE,WAAW,UAAa,EAAE,cAAc,UAAa,CAAC,UAAU,MAAM,WAAW,EAAG,QAAO;AAChJ,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,WAAW,WAAW,EAAE,QAAQ,EAAE,OAAuB,IAAI,CAAC;AAAA,IAC3E,GAAI,SAAS,SAAY,EAAE,MAAM,KAAK,IAAI,CAAC;AAAA,IAC3C,GAAI,OAAO,EAAE,cAAc,WAAW,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IACpE,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7B,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAC3B,GAAI,MAAM,SAAS,EAAE,MAAM,IAAI,CAAC;AAAA,EAClC;AACF;AAQO,SAAS,kBAAkB,KAAgB,mBAAmB,qBAAqB,GAAiB;AACzG,SAAO,oBAAoB,eAAe,GAAG,IAAI,CAAC,IAAI,cAAc,GAAG;AACzE;AApMA,IAsCa,gBAGA,aACA,WACA,aAGP,aACA,YAEF,cACA,qBA6BE,aAMA,oBAiHO;AAtMb;AAAA;AAAA;AAmCA;AAGO,IAAM,iBAAiB,CAAC,YAAY,KAAK;AAGzC,IAAM,cAAc,CAAC,QAAQ,UAAU,aAAa,WAAW,SAAS,UAAU,WAAW;AAC7F,IAAM,YAAY,CAAC,OAAO,QAAQ;AAClC,IAAM,cAAc,CAAC,QAAQ,OAAO,MAAM;AAGjD,IAAM,cAAc;AACpB,IAAM,aAAa;AAEnB,IAAI,eAAe;AA8BnB,IAAM,cAAgD;AAAA,MACpD,kBAAkB;AAAA,MAClB,UAAU;AAAA,IACZ;AAGA,IAAM,qBACJ;AAgHK,IAAM,SAAsB;AAAA,MACjC,MAAM;AAAA,MACN,MAAM,CAAC,QAAQ;AAAA,MACf,QAAQ;AAAA,QACN,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,MAAM,EAAE,MAAM,UAAU,aAAa,iIAAiI;AAAA,YACtK,QAAQ,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,cAAc,GAAG,SAAS,YAAY,aAAa,gFAAgF;AAAA,YACvK,WAAW,EAAE,MAAM,UAAU,aAAa,gEAAgE;AAAA,YAC1G,SAAS,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,GAAG,UAAU,GAAG,aAAa,uGAAuG;AAAA,YACtL,QAAQ;AAAA,cACN,MAAM;AAAA,cACN,sBAAsB;AAAA,cACtB,UAAU,CAAC,QAAQ,KAAK;AAAA,cACxB,aAAa;AAAA,cACb,YAAY;AAAA,gBACV,MAAM,EAAE,MAAM,UAAU,aAAa,yEAAyE;AAAA,gBAC9G,KAAK,EAAE,MAAM,UAAU,aAAa,oCAAoC;AAAA,gBACxE,MAAM,EAAE,MAAM,UAAU,SAAS,UAAU,aAAa,4CAA4C;AAAA,cACtG;AAAA,YACF;AAAA,YACA,WAAW;AAAA,cACT,MAAM;AAAA,cACN,OAAO,EAAE,MAAM,UAAU,SAAS,oBAAoB;AAAA,cACtD,aAAa;AAAA,cACb,aAAa;AAAA,YACf;AAAA,YACA,OAAO;AAAA,cACL,MAAM;AAAA,cACN,aAAa;AAAA,cACb,OAAO;AAAA,gBACL,OAAO;AAAA,kBACL,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,kBACxF;AAAA,oBACE,MAAM;AAAA,oBACN,sBAAsB;AAAA,oBACtB,UAAU,CAAC,KAAK;AAAA,oBAChB,YAAY;AAAA,sBACV,KAAK,EAAE,MAAM,UAAU,aAAa,yDAAyD;AAAA,sBAC7F,QAAQ,EAAE,MAAM,UAAU,aAAa,iCAAiC;AAAA,oBAC1E;AAAA,kBACF;AAAA,gBACF;AAAA,cACF;AAAA,YACF;AAAA,UACF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,YAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,UAAU,qCAAqC,CAAC;AAChF,cAAM,MAAuB,CAAC;AAC9B,mBAAW,KAAK,OAAO,KAAK,CAAC,EAAG,KAAI,KAAK,YAAa,KAAI,KAAK,MAAM,UAAU,CAAC,IAAI,yBAAyB,YAAY,CAAC,CAAC,EAAE,CAAC;AAC9H,YAAI,EAAE,WAAW,QAAW;AAC1B,cAAI,CAAC,qBAAqB,EAAG,KAAI,KAAK,MAAM,iBAAiB,kBAAkB,CAAC;AAAA,mBACvE,CAAC,SAAS,EAAE,MAAM,EAAG,KAAI,KAAK,MAAM,iBAAiB,wBAAwB,CAAC;AAAA,eAClF;AACH,kBAAM,MAAM,EAAE;AACd,gBAAI,KAAK,GAAG,SAAS,KAAK,aAAa,eAAe,CAAC;AACvD,gBAAI,OAAO,IAAI,SAAS,YAAY,CAAC,YAAY,KAAK,IAAI,IAAI,KAAK,IAAI,KAAK,WAAW,GAAG,EAAG,KAAI,KAAK,MAAM,sBAAsB,8DAA8D,CAAC;AACjM,gBAAI,OAAO,IAAI,QAAQ,YAAY,CAAC,WAAW,KAAK,IAAI,GAAG,KAAK,IAAI,IAAI,SAAS,IAAI,KAAK,IAAI,IAAI,SAAS,GAAG,EAAG,KAAI,KAAK,MAAM,qBAAqB,gCAAgC,CAAC;AACtL,gBAAI,IAAI,SAAS,OAAW,KAAI,KAAK,GAAG,SAAS,IAAI,MAAM,oBAAoB,CAAC;AAEhF,gBAAI,EAAE,SAAS,OAAW,KAAI,KAAK,MAAM,eAAe,kGAAkG,CAAC;AAAA,UAC7J;AAAA,QACF;AACA,YAAI,KAAK,GAAG,SAAS,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,YAAY,CAAC,GAAG,aAAa,QAAQ,CAAC;AACvH,YAAI,EAAE,SAAS,OAAW,KAAI,KAAK,GAAG,SAAS,EAAE,MAAM,aAAa,CAAC;AACrE,YAAI,KAAK,GAAG,MAAM,EAAE,QAAQ,gBAAgB,eAAe,CAAC;AAC5D,YAAI,EAAE,cAAc,WAAc,OAAO,EAAE,cAAc,YAAY,EAAE,UAAU,KAAK,MAAM,IAAK,KAAI,KAAK,MAAM,oBAAoB,wBAAwB,CAAC;AAC7J,YAAI,EAAE,YAAY,QAAW;AAC3B,cAAI,CAAC,MAAM,QAAQ,EAAE,OAAO,KAAK,EAAE,QAAQ,WAAW,KAAK,EAAE,QAAQ,KAAK,CAAC,MAAM,OAAO,MAAM,YAAY,MAAM,EAAE,EAAG,KAAI,KAAK,MAAM,kBAAkB,4BAA4B,CAAC;AAAA,mBAC1K,CAAC,EAAE,QAAQ,KAAK,CAAC,MAAc,EAAE,SAAS,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,kBAAkB,qCAAqC,CAAC;AAAA,QACzI;AACA,YAAI,EAAE,cAAc,QAAW;AAC7B,cAAI,CAAC,MAAM,QAAQ,EAAE,SAAS,KAAK,EAAE,UAAU,WAAW,EAAG,KAAI,KAAK,MAAM,oBAAoB,uDAAuD,CAAC;AAAA;AAEtJ,cAAE,UAAU,QAAQ,CAAC,MAAM,MAAM;AAC/B,kBAAI,OAAO,SAAS,YAAY,CAAC,oBAAoB,KAAK,IAAI,EAAG,KAAI,KAAK,MAAM,oBAAoB,CAAC,IAAI,MAAM,KAAK,UAAU,IAAI,CAAC,oEAAoE,CAAC;AAAA,YAC1M,CAAC;AAAA,QACL;AACA,YAAI,EAAE,UAAU,QAAW;AACzB,cAAI,CAAC,MAAM,QAAQ,EAAE,KAAK,EAAG,KAAI,KAAK,MAAM,gBAAgB,+BAA+B,CAAC;AAAA,eACvF;AACH,cAAE,MAAM,QAAQ,CAAC,MAAM,MAAM;AAC3B,oBAAM,MAAM,gBAAgB,CAAC;AAC7B,kBAAI,OAAO,SAAS,SAAU,KAAI,KAAK,GAAG,SAAS,MAAM,GAAG,CAAC;AAAA,uBACpD,SAAS,IAAI,GAAG;AACvB,oBAAI,KAAK,GAAG,SAAS,MAAM,WAAW,GAAG,GAAG,GAAG,SAAS,KAAK,KAAK,GAAG,GAAG,MAAM,CAAC;AAC/E,oBAAI,KAAK,WAAW,OAAW,KAAI,KAAK,GAAG,SAAS,KAAK,QAAQ,GAAG,GAAG,SAAS,CAAC;AAAA,cACnF,MAAO,KAAI,KAAK,MAAM,KAAK,yCAAyC,CAAC;AAAA,YACvE,CAAC;AACD,kBAAM,OAAO,cAAc,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,GAAG;AAChD,kBAAM,QAAQ,KAAK,OAAO,CAAC,GAAG,MAAM,KAAK,QAAQ,CAAC,MAAM,CAAC;AACzD,gBAAI,MAAM,OAAQ,KAAI,KAAK,MAAM,gBAAgB,SAAS,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,KAAK,IAAI,CAAC,iBAAiB,CAAC;AAAA,UAC5G;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,OAAO,cAAc,GAAG;AAC9B,YAAI,KAAM,KAAI,GAAG,SAAS;AAC1B,cAAM,QAAQ,kBAAkB,GAAG;AACnC,YAAI,MAAM,OAAQ,KAAI,SAAS,cAAc;AAAA,MAC/C;AAAA,IACF;AAAA;AAAA;;;ACnTA,IAWa,2BACP,KAEO,mBACP,WAOO;AAtBb;AAAA;AAAA;AASA;AAEO,IAAM,4BAA4B;AACzC,IAAM,MAAM;AAEL,IAAM,oBAAoB;AACjC,IAAM,YAAY;AAOX,IAAM,eAA4B;AAAA,MACvC,MAAM;AAAA,MACN,MAAM,CAAC,eAAe;AAAA,MACtB,QAAQ;AAAA,QACN,eAAe;AAAA,UACb,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,UAAU,CAAC,UAAU;AAAA,UACrB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,UAAU,EAAE,MAAM,UAAU,aAAa,uEAAuE;AAAA,YAChH,MAAM,EAAE,MAAM,UAAU,SAAS,kBAAkB,QAAQ,SAAS,2BAA2B,aAAa,qGAAqG;AAAA,YACjN,KAAK,EAAE,MAAM,UAAU,SAAS,IAAI,QAAQ,aAAa,iGAAiG;AAAA,UAC5J;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,YAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,iBAAiB,mCAAmC,CAAC;AACrF,cAAM,MAAuB,CAAC,GAAG,SAAS,GAAG,CAAC,YAAY,QAAQ,KAAK,GAAG,eAAe,CAAC;AAC1F,YAAI,OAAO,EAAE,aAAa,YAAY,CAAC,UAAU,KAAK,EAAE,QAAQ,EAAG,KAAI,KAAK,MAAM,0BAA0B,2CAA2C,CAAC;AAAA,iBAC/I,SAAS,IAAI,MAAM,KAAK,EAAE,EAAE,YAAY,IAAI,QAAS,KAAI,KAAK,QAAQ,0BAA0B,MAAM,EAAE,QAAQ,kFAAkF,CAAC;AAC5M,YAAI,EAAE,SAAS,WAAc,OAAO,EAAE,SAAS,YAAY,CAAC,kBAAkB,KAAK,EAAE,IAAI,IAAI;AAC3F,cAAI,KAAK,MAAM,sBAAsB,2GAA2G,CAAC;AAAA,QACnJ;AACA,YAAI,EAAE,QAAQ,WAAc,OAAO,EAAE,QAAQ,YAAY,CAAC,IAAI,KAAK,EAAE,GAAG,GAAI,KAAI,KAAK,MAAM,qBAAqB,sCAAsC,CAAC;AACvJ,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,cAAM,IAAI,IAAI;AACd,YAAI,CAAC,SAAS,CAAC,EAAG;AAClB,YAAI,GAAG,gBAAgB,EAAE,UAAU,EAAE,UAAoB,GAAI,OAAO,EAAE,QAAQ,WAAW,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,EAAG;AAC9G,YAAI,SAAS,kBAAkB,OAAO,EAAE,SAAS,WAAW,EAAE,OAAO;AAAA,MACvE;AAAA,IACF;AAAA;AAAA;;;ACxCA,SAAS,gBAAgB,GAAY,KAA8B;AACjE,MAAI,MAAM,OAAW,QAAO,CAAC;AAC7B,MAAI,CAAC,SAAS,CAAC,EAAG,QAAO,CAAC,MAAM,KAAK,0CAA0C,CAAC;AAChF,SAAO,OAAO,QAAQ,CAAC,EACpB,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,CAAC,MAAM,QAAQ,KAAK,KAAK,MAAM,KAAK,CAAC,MAAM,OAAO,MAAM,QAAQ,CAAC,EACvF,IAAI,CAAC,CAAC,CAAC,MAAM,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,+BAA+B,CAAC;AACvE;AAvBA,IAUa,QAEP,UAaA,MAEO;AA3Bb;AAAA;AAAA;AAQA;AAEO,IAAM,SAAS,CAAC,UAAU,UAAU,SAAS;AAEpD,IAAM,WAAW;AAAA,MACf,MAAM;AAAA,MACN,sBAAsB,EAAE,MAAM,SAAS,OAAO,EAAE,MAAM,SAAS,EAAE;AAAA,IACnE;AAUA,IAAM,OAAO,CAAC,MAA0D,OAAO,YAAY,OAAO,QAAQ,CAAC,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;AAElI,IAAM,UAAuB;AAAA,MAClC,MAAM;AAAA,MACN,MAAM,CAAC,YAAY,UAAU,OAAO;AAAA,MACpC,QAAQ;AAAA,QACN,UAAU,EAAE,GAAG,UAAU,aAAa,qFAAqF;AAAA,QAC3H,QAAQ,EAAE,GAAG,UAAU,aAAa,wGAAwG;AAAA,QAC5I,OAAO;AAAA,UACL,MAAM;AAAA,UACN,sBAAsB;AAAA,UACtB,aAAa;AAAA,UACb,YAAY;AAAA,YACV,MAAM,EAAE,MAAM,UAAU,MAAM,CAAC,GAAG,MAAM,EAAE;AAAA,YAC1C,KAAK,EAAE,MAAM,UAAU,aAAa,iDAAiD;AAAA,UACvF;AAAA,QACF;AAAA,MACF;AAAA,MACA,MAAM,KAAK;AACT,cAAM,MAAuB,CAAC,GAAG,gBAAgB,IAAI,UAAU,UAAU,GAAG,GAAG,gBAAgB,IAAI,QAAQ,QAAQ,CAAC;AACpH,cAAM,IAAI,IAAI;AACd,YAAI,MAAM,QAAW;AACnB,cAAI,CAAC,SAAS,CAAC,EAAG,KAAI,KAAK,MAAM,SAAS,mCAAmC,CAAC;AAAA,eACzE;AACH,gBAAI,KAAK,GAAG,SAAS,GAAG,CAAC,QAAQ,KAAK,GAAG,OAAO,GAAG,GAAG,MAAM,EAAE,MAAM,QAAQ,YAAY,CAAC;AACzF,gBAAI,EAAE,QAAQ,WAAc,OAAO,EAAE,QAAQ,YAAY,CAAC,eAAe,KAAK,EAAE,GAAG,GAAI,KAAI,KAAK,MAAM,aAAa,8BAA8B,CAAC;AAAA,UACpJ;AAAA,QACF;AACA,eAAO;AAAA,MACT;AAAA,MACA,UAAU,KAAK,KAAK;AAClB,YAAI,SAAS,IAAI,QAAQ,EAAG,KAAI,GAAG,WAAW,KAAK,IAAI,QAAoC;AAC3F,YAAI,SAAS,IAAI,MAAM,EAAG,KAAI,GAAG,SAAS,KAAK,IAAI,MAAkC;AACrF,YAAI,SAAS,IAAI,KAAK,GAAG;AACvB,gBAAM,IAAI,IAAI;AACd,cAAI,SAAS,QAAQ,EAAE,GAAI,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,IAAI,CAAC,GAAI,GAAI,EAAE,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,EAAG;AAAA,QAC/F;AAAA,MACF;AAAA,IACF;AAAA;AAAA;;;ACrDA,SAAS,YAAY,oBAAoB;AACzC,SAAS,SAAS,MAAM,eAAe;AACvC,SAAS,iBAAiB;AA4CnB,SAAS,YAAyB;AACvC,SAAO,IAAI,IAAI,OAAO,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC;AAC9C;AAMO,SAAS,WAAW,KAAiC;AAC1D,MAAI,MAAM,QAAQ,GAAG;AACrB,WAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,eAAW,QAAQ,cAAc;AAC/B,YAAM,OAAO,KAAK,KAAK,IAAI;AAC3B,UAAI,WAAW,IAAI,EAAG,QAAO;AAAA,IAC/B;AACA,UAAM,SAAS,QAAQ,GAAG;AAC1B,QAAI,WAAW,KAAK,KAAK,MAAM,CAAC,KAAK,WAAW,IAAK,QAAO;AAC5D,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAGO,SAAS,YAAY,MAAc,MAA8B;AACtE,MAAI;AACJ,MAAI;AACF,UAAM,KAAK,KAAK,MAAM,KAAK,CAAC,IAAI,UAAU,IAAI;AAAA,EAChD,SAAS,GAAG;AACV,UAAM,IAAI,YAAY,GAAG,QAAQ,aAAa,KAAM,EAAY,OAAO,EAAE;AAAA,EAC3E;AACA,MAAI,QAAQ,QAAQ,QAAQ,OAAW,OAAM,CAAC;AAC9C,MAAI,CAAC,SAAS,GAAG,EAAG,OAAM,IAAI,YAAY,GAAG,QAAQ,aAAa,8CAA8C;AAChH,SAAO,EAAE,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,GAAI,IAAI;AAC1C;AAGO,SAAS,WAAW,MAA6B;AACtD,SAAO,YAAY,aAAa,MAAM,MAAM,GAAG,IAAI;AACrD;AAGO,SAAS,YAAYE,SAAwC;AAClE,QAAM,QAAQ,UAAU;AACxB,QAAM,MAAuB,CAAC;AAC9B,aAAW,OAAO,OAAO,KAAKA,QAAO,GAAG,GAAG;AACzC,QAAI,QAAQ,QAAQ,IAAI,WAAW,KAAK,EAAG;AAC3C,QAAI,CAAC,MAAM,IAAI,GAAG,EAAG,KAAI,KAAK,MAAM,KAAK,sCAAsC,CAAC,GAAG,KAAK,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE,CAAC;AAAA,EAChH;AACA,aAAW,KAAK,OAAQ,KAAI,KAAK,GAAG,EAAE,MAAMA,QAAO,GAAG,CAAC;AACvD,SAAO;AACT;AA1GA,IAkCa,QAGA,cAQA;AA7Cb;AAAA;AAAA;AAaA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA,IAAAC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAIO,IAAM,SAAiC,CAAC,WAAW,QAAQ,QAAQ,OAAO,OAAO,UAAU,QAAQ,UAAU,cAAc,SAAS,OAAO,QAAQ,SAAS,QAAQ,MAAM,SAAS,KAAK;AAGxL,IAAM,eAAe,CAAC,eAAe,cAAc;AAQnD,IAAM,cAAN,cAA0B,MAAM;AAAA,MACrC,YACE,SACS,WAA4B,CAAC,GACtC;AACA,cAAM,OAAO;AAFJ;AAGT,aAAK,OAAO;AAAA,MACd;AAAA,MAJW;AAAA,IAKb;AAAA;AAAA;;;ACwGO,SAAS,gBAAgBC,SAAsC;AACpE,QAAM,MAAqB,EAAE,IAAI,CAAC,GAAG,SAAS,CAAC,GAAG,gBAAgB,CAAC,GAAG,UAAU,CAAC,EAAE;AACnF,aAAW,SAAS,OAAQ,OAAM,UAAUA,QAAO,KAAK,GAAG;AAC3D,SAAO;AACT;AAjKA;AAAA;AAAA;AAyBA;AAAA;AAAA;;;ACEO,SAAS,YAAY,KAAa,MAAkC;AACzE,QAAM,OAAO,QAAQ,WAAW,GAAG;AACnC,MAAI,CAAC,MAAM;AACT,UAAM,UAAU,qBAAqB,GAAG,gDAAgD,OAAO;AAC/F,WAAO,EAAE,IAAI,OAAO,OAAO,CAAC,OAAO,GAAG,UAAU,EAAE,OAAO,QAAQ,EAAE;AAAA,EACrE;AACA,MAAIC;AACJ,MAAI;AACF,IAAAA,UAAS,WAAW,IAAI;AAAA,EAC1B,SAAS,GAAG;AACV,UAAM,UAAU,aAAa,cAAc,EAAE,UAAU,GAAG,IAAI,KAAM,EAAY,OAAO;AACvF,WAAO,EAAE,IAAI,OAAO,OAAO,CAAC,OAAO,GAAG,UAAU,EAAE,MAAM,MAAM,OAAO,QAAQ,EAAE;AAAA,EACjF;AACA,QAAM,WAAW,YAAYA,OAAM;AACnC,QAAM,SAAS,SAAS,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AAC5D,QAAMC,SAAQ,SAAS,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,GAAG,EAAE,aAAa,YAAY,eAAe,EAAE,EAAE;AACjH,MAAI,OAAO,OAAQ,QAAO,EAAE,IAAI,OAAO,OAAAA,QAAO,UAAU,EAAE,MAAM,MAAM,SAAS,EAAE;AAEjF,QAAM,MAAMD,QAAO;AACnB,QAAME,UAAS,SAAS,GAAG;AAC3B,QAAMC,SAAQ,QAAQ,GAAG;AACzB,QAAMC,SAAQ,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,MAAM,KAAK,UAAU;AAC5D,QAAM,WAAW;AAAA,IACf,QAAQF,SAAQ,UAAU;AAAA,IAC1B,WAAW,YAAY,GAAG;AAAA,IAC1B,MAAM,OAAO,GAAG;AAAA,IAChB,UAAU,WAAW,GAAG;AAAA,IACxB,WAAWC,OAAM;AAAA,IACjB,WAAW,aAAa,KAAKD,SAAQ,MAAM;AAAA,EAC7C;AACA,EAAAD,OAAM;AAAA,IACJ,GAAG,IAAI;AAAA,IACP,kBAAkBC,UAAS,GAAGA,QAAO,MAAM,KAAKA,QAAO,OAAO,MAAM,gEAAgE;AAAA,IACpI,kBAAkB,SAAS,SAAS;AAAA,IACpC,kBAAkB,SAAS,IAAI;AAAA,IAC/B,kBAAkB,SAAS,QAAQ;AAAA,IACnC,kBAAkBC,OAAM,IAAI,cAAc,YAAYA,OAAM,IAAI,CAAC;AAAA,IACjE,kBAAkBA,OAAM,QAAQ,GAAGA,OAAM,KAAK,kBAAkB,cAAcA,OAAM,KAAK,CAAC,MAAM,iBAAiB,UAAUD,SAAQ,MAAM,CAAC;AAAA,IAC1I,kBAAkB,WAAW,GAAG,CAAC;AAAA,IACjC,GAAIE,OAAM,SAAS,CAAC,+CAA+CA,OAAM,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,EAC5F;AACA,SAAO,EAAE,IAAI,MAAM,OAAAH,QAAO,UAAU,EAAE,MAAM,MAAM,UAAU,UAAU,OAAO,gBAAgBD,OAAM,EAAE,EAAE;AACzG;AAGA,SAAS,WAAW,KAAwB;AAC1C,QAAM,OAAO,cAAc,GAAG;AAC9B,QAAM,QAAQ,cAAc,GAAG;AAC/B,QAAM,MAAM,MAAM;AAClB,QAAM,UAAU,MAAM,GAAG,IAAI,QAAQ,QAAQ,OAAO,IAAI,IAAI,IAAI,IAAI,GAAG,KAAM,MAAM,QAAQ;AAC3F,QAAM,UAAU,SAAS,WAAc,QAAQ,UAAa,KAAK,SAAS,UAAa,KAAK,YAAY,UAAa,KAAK,WAAW,UAAa,KAAK,cAAc;AACrK,QAAM,QAAQ;AAAA,IACZ,GAAI,UAAU,CAAC,WAAW,OAAO,KAAK,KAAM,UAAU,UAAU,cAAc,MAAM,2BAA2B,MAAM,EAAE,IAAI,CAAC;AAAA,IAC5H,GAAI,MAAM,SAAS,CAAC,cAAc,MAAM,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,GAAG,MAAM,SAAS,IAAI,IAAI,IAAI,IAAI,GAAG,KAAK,EAAE,mBAAmB,MAAM,QAAQ,qCAAqC,EAAE,EAAE,IAAI,CAAC;AAAA,EACjM;AACA,SAAO,MAAM,SAAS,MAAM,KAAK,IAAI,IAAI;AAC3C;AAnFA;AAAA;AAAA;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AAAA;AAAA;;;ACLA,SAAS,cAAAK,aAAY,aAAa,gBAAAC,eAAc,gBAAgB;AAChE,SAAS,UAAU,WAAAC,UAAS,QAAAC,OAAM,UAAU,WAAW;AACvD,SAAS,aAAAC,kBAAiB;AAqDnB,SAAS,SAAS,KAAqB;AAC5C,MAAI,MAAM;AACV,WAAS,IAAI,GAAG,IAAI,IAAI,KAAK;AAC3B,QAAIJ,YAAWG,MAAK,KAAK,MAAM,CAAC,EAAG,QAAO;AAC1C,UAAM,SAASD,SAAQ,GAAG;AAC1B,QAAI,WAAW,IAAK,QAAO;AAC3B,UAAM;AAAA,EACR;AACA,SAAO;AACT;AAGO,SAAS,SAAS,MAAc,MAAsB;AAC3D,QAAM,MAAM,SAAS,MAAM,IAAI;AAC/B,SAAO,QAAQ,KAAK,MAAM,IAAI,MAAM,GAAG,EAAE,KAAK,GAAG;AACnD;AAEA,SAAS,aAAa,MAAmD;AACvE,MAAI;AACF,UAAM,MAAeE,WAAUH,cAAa,MAAM,MAAM,CAAC;AACzD,WAAO,OAAO,OAAO,QAAQ,YAAY,CAAC,MAAM,QAAQ,GAAG,IAAK,MAAkC;AAAA,EACpG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,mBAAmB,MAAiC;AAClE,QAAM,MAAyB,CAAC;AAChC,QAAM,OAAO,CAAC,KAAa,UAAwB;AACjD,QAAI;AACJ,QAAI;AACF,gBAAU,YAAY,GAAG,EAAE,KAAK;AAAA,IAClC,QAAQ;AACN;AAAA,IACF;AACA,UAAM,OAAO,CAAC,eAAe,YAAY,EAAE,KAAK,CAAC,MAAM,QAAQ,SAAS,CAAC,CAAC;AAC1E,QAAI,MAAM;AACR,YAAM,UAAU,YAAY,MAAM,KAAKE,MAAK,KAAK,IAAI,CAAC;AACtD,UAAI,QAAS,KAAI,KAAK,OAAO;AAAA,IAC/B;AACA,QAAI,SAAS,UAAW;AACxB,eAAW,QAAQ,SAAS;AAC1B,UAAI,KAAK,IAAI,IAAI,KAAK,KAAK,WAAW,GAAG,EAAG;AAC5C,YAAM,OAAOA,MAAK,KAAK,IAAI;AAC3B,UAAI;AACF,YAAI,SAAS,IAAI,EAAE,YAAY,EAAG,MAAK,MAAM,QAAQ,CAAC;AAAA,MACxD,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,OAAK,MAAM,CAAC;AACZ,SAAO;AACT;AAEA,SAAS,YAAY,MAAc,KAAa,MAA2C;AACzF,QAAM,MAAM,aAAa,IAAI;AAC7B,MAAI,CAAC,OAAO,OAAO,IAAI,SAAS,YAAY,IAAI,SAAS,GAAI,QAAO;AACpE,QAAM,UAAU,OAAO,IAAI,YAAY,WAAW,IAAI,UAAW,IAAI,SAA4C;AACjH,QAAM,UAAU,IAAI;AACpB,QAAM,YAAY,OAAO,IAAI,mBAAmB,WAAWA,MAAK,KAAK,IAAI,cAAc,IAAI;AAC3F,SAAO;AAAA,IACL,MAAM,IAAI;AAAA,IACV,KAAK,SAAS,MAAM,GAAG;AAAA,IACvB,GAAI,OAAO,YAAY,WAAW,EAAE,QAAQ,IAAI,CAAC;AAAA,IACjD,GAAI,WAAW,OAAO,QAAQ,QAAQ,WAAW,EAAE,YAAY,QAAQ,IAAI,IAAI,CAAC;AAAA,IAChF,QAAQ,WAAW,SAAS;AAAA,EAC9B;AACF;AAGO,SAAS,WAAW,WAA6B;AACtD,MAAI;AACJ,MAAI;AACF,cAAU,YAAY,SAAS;AAAA,EACjC,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,QAAM,QAAQ,QACX,IAAI,CAAC,MAAM,wBAAwB,KAAK,CAAC,IAAI,CAAC,CAAC,EAC/C,OAAO,CAAC,MAAmB,MAAM,UAAa,MAAM,EAAE;AACzD,SAAO,CAAC,GAAG,IAAI,IAAI,KAAK,CAAC,EAAE,KAAK,aAAa;AAC/C;AAOO,SAAS,cAAc,OAAuB;AACnD,QAAM,OAAO,MAAM,MAAM,GAAG,EAAE,IAAI,EAAG,YAAY;AACjD,QAAM,OAAO,KAAK,MAAM,OAAO,EAAE,CAAC;AAClC,SAAO,UAAU,SAAS,IAAI,IAAI,OAAO;AAC3C;AAEA,SAAS,KAAK,OAAuB;AACnC,QAAM,MAAM,cAAc,KAAK;AAC/B,QAAM,KAAK,UAAU,QAAQ,GAAG;AAChC,SAAO,MAAM,IAAI,KAAK,YAAY;AACpC;AAGO,SAAS,cAAc,GAAW,GAAmB;AAC1D,SAAO,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC;AAC/C;AAGO,SAASE,UAAS,UAAuD;AAC9E,QAAM,QAAQ,oBAAI,IAAoB;AACtC,aAAW,KAAK,SAAU,OAAM,IAAI,EAAE,OAAO,MAAM,IAAI,EAAE,IAAI,KAAK,KAAK,CAAC;AACxE,QAAM,MAAuB,CAAC;AAC9B,aAAW,KAAK,UAAU;AACxB,UAAM,WAAW,MAAM,IAAI,EAAE,IAAI,KAAK,KAAK,IAAI,GAAG,EAAE,IAAI,IAAI,KAAK,EAAE,GAAG,CAAC,KAAK,EAAE;AAC9E,eAAW,SAAS,EAAE,OAAQ,KAAI,KAAK,EAAE,KAAK,GAAG,OAAO,IAAI,KAAK,IAAI,SAAS,EAAE,MAAM,OAAO,KAAK,EAAE,IAAI,CAAC;AAAA,EAC3G;AACA,SAAO,IAAI,KAAK,CAAC,GAAG,MAAM,cAAc,EAAE,OAAO,EAAE,KAAK,KAAK,EAAE,IAAI,cAAc,EAAE,GAAG,CAAC;AACzF;AAGO,SAAS,KAAK,GAAmB;AACtC,QAAM,MAAM,EAAE,YAAY,EAAE,QAAQ,eAAe,GAAG,EAAE,QAAQ,YAAY,EAAE;AAC9E,SAAO,QAAQ,KAAK,SAAS;AAC/B;AAGO,SAAS,UAAU,MAAkC;AAC1D,QAAMC,UAAS,QAAQ,MAAM,QAAQ;AACrC,MAAI,CAACA,QAAQ,QAAO;AACpB,MAAI,WAAW;AACf,aAAW,OAAOA,QAAO,MAAM,OAAO,GAAG;AACvC,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,KAAK,WAAW,GAAG,GAAG;AACxB,iBAAW,0BAA0B,KAAK,IAAI;AAC9C;AAAA,IACF;AACA,UAAM,IAAI,WAAW,mBAAmB,KAAK,IAAI,IAAI;AACrD,QAAI,EAAG,QAAO,EAAE,CAAC,EAAG,KAAK;AAAA,EAC3B;AACA,SAAO;AACT;AAGA,SAAS,QAAQ,MAAc,MAAkC;AAC/D,QAAM,SAASH,MAAK,MAAM,MAAM;AAChC,MAAI,SAAS;AACb,MAAI;AACF,QAAI,SAAS,MAAM,EAAE,OAAO,GAAG;AAC7B,YAAM,IAAI,oBAAoB,KAAKF,cAAa,QAAQ,MAAM,CAAC;AAC/D,UAAI,CAAC,EAAG,QAAO;AACf,eAASE,MAAK,MAAM,EAAE,CAAC,EAAG,KAAK,CAAC;AAEhC,YAAM,SAASA,MAAK,QAAQ,WAAW;AACvC,UAAIH,YAAW,MAAM,KAAK,CAACA,YAAWG,MAAK,QAAQ,IAAI,CAAC,EAAG,UAASA,MAAK,QAAQF,cAAa,QAAQ,MAAM,EAAE,KAAK,CAAC;AAAA,IACtH;AACA,UAAM,OAAOE,MAAK,QAAQ,IAAI;AAC9B,WAAOH,YAAW,IAAI,IAAIC,cAAa,MAAM,MAAM,IAAI;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,WAAW,KAAiC;AAC1D,QAAM,MAAM,wBAAwB,KAAK,GAAG;AAC5C,MAAI,IAAK,QAAO,IAAI,CAAC,EAAG,YAAY;AACpC,MAAI;AACF,WAAO,IAAI,IAAI,GAAG,EAAE,SAAS,YAAY,KAAK;AAAA,EAChD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGO,SAAS,cAAc,KAAwC;AACpE,QAAM,OAAO,WAAW,GAAG;AAC3B,MAAI,CAAC,KAAM,QAAO;AAClB,MAAI,SAAS,gBAAgB,KAAK,SAAS,aAAa,KAAK,KAAK,WAAW,SAAS,EAAG,QAAO,EAAE,MAAM,UAAU,SAAS,gBAAgB,IAAI,GAAG;AAClJ,MAAI,SAAS,aAAc,QAAO,EAAE,MAAM,UAAU,SAAS,gBAAgB,IAAI,GAAG;AACpF,MAAI,SAAS,eAAgB,QAAO,EAAE,MAAM,WAAW,SAAS,gBAAgB,IAAI,GAAG;AACvF,MAAI,yBAAyB,KAAK,IAAI,EAAG,QAAO,EAAE,MAAM,UAAU,SAAS,gBAAgB,IAAI,IAAI,KAAK,WAAW,IAAI,GAAG;AAC1H,MAAI,kCAAkC,KAAK,IAAI,EAAG,QAAO,EAAE,MAAM,WAAW,SAAS,gBAAgB,IAAI,IAAI,KAAK,WAAW,IAAI,GAAG;AACpI,SAAO;AACT;AAGO,SAAS,YAAY,MAAyC;AACnE,QAAM,MAAM,UAAU,IAAI;AAC1B,QAAM,WAAW,MAAM,cAAc,GAAG,IAAI;AAC5C,MAAI,SAAU,QAAO;AACrB,MAAID,YAAWG,MAAK,MAAM,UAAU,CAAC,EAAG,QAAO,EAAE,MAAM,WAAW,SAAS,+BAA+B;AAC1G,MAAIH,YAAWG,MAAK,MAAM,gBAAgB,CAAC,EAAG,QAAO,EAAE,MAAM,UAAU,SAAS,oCAAoC;AACpH,MAAIH,YAAWG,MAAK,MAAM,WAAW,WAAW,CAAC,EAAG,QAAO,EAAE,MAAM,UAAU,SAAS,wCAAwC;AAC9H,SAAO;AACT;AAGO,SAAS,cAAc,MAAsB;AAClD,QAAM,OAAO,QAAQ,MAAM,0BAA0B;AACrD,QAAM,SAAS,QAAQ,qCAAqC,KAAK,IAAI,IAAI,CAAC;AAC1E,MAAI,OAAQ,QAAO,OAAO,KAAK;AAC/B,QAAM,QAAQ,QAAQ,MAAM,MAAM;AAClC,QAAM,SAAS,SAAS,2BAA2B,KAAK,KAAK,IAAI,CAAC;AAClE,SAAO,SAAS,OAAO,KAAK,IAAI;AAClC;AAMO,SAAS,kBAAkB,MAAwB;AACxD,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAK,eAAe;AAC7B,QAAI;AACJ,QAAI;AACF,cAAQ,YAAYA,MAAK,MAAM,CAAC,CAAC,EAAE,KAAK;AAAA,IAC1C,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,OAAO;AACrB,UAAI,CAAC,WAAW,KAAK,CAAC,EAAG;AACzB,UAAI;AACF,YAAI,gCAAgC,KAAKF,cAAaE,MAAK,MAAM,GAAG,CAAC,GAAG,MAAM,CAAC,EAAG,KAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;AAAA,MACxG,QAAQ;AAAA,MAER;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,OAAO,KAAuB;AAC5C,QAAM,OAAO,SAAS,GAAG;AACzB,QAAM,WAAW,mBAAmB,IAAI;AACxC,QAAM,QAAQ,YAAY,IAAI;AAC9B,QAAM,YAAY,CAAC,2BAA2B,wBAAwB,EAAE,KAAK,CAAC,MAAMH,YAAWG,MAAK,MAAM,CAAC,CAAC,CAAC;AAC7G,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,QAAQE,UAAS,QAAQ;AAAA,IACzB,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IACzB,eAAe,cAAc,IAAI;AAAA,IACjC,eAAe,kBAAkB,IAAI;AAAA,IACrC,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,EACnC;AACF;AAGO,SAAS,SAAS,MAAsB;AAC7C,SAAO,KAAK,SAAS,IAAI,CAAC,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,OAAO,EAAE,KAAK;AACjE;AA9TA,IA+DM,MACA,WAyFA,WACA,WAwHA;AAlRN;AAAA;AAAA;AA+DA,IAAM,OAAO,oBAAI,IAAI,CAAC,gBAAgB,QAAQ,QAAQ,SAAS,UAAU,QAAQ,SAAS,eAAe,UAAU,OAAO,KAAK,CAAC;AAChI,IAAM,YAAY;AAyFlB,IAAM,YAAY,CAAC,SAAS,OAAO,eAAe,WAAW,QAAQ,WAAW,MAAM,MAAM,SAAS,WAAW,WAAW,OAAO,QAAQ,YAAY;AACtJ,IAAM,YAAY,UAAU,QAAQ,MAAM;AAwH1C,IAAM,gBAAgB,CAAC,qBAAqB,sBAAsB,kBAAkB;AAAA;AAAA;;;ACpJ7E,SAAS,aAAa,OAA8B;AACzD,SAAO,OAAO,MAAM,wBAAwB,cAAc,OAAO,MAAM,qBAAqB;AAC9F;AAoBO,SAAS,aAAa,OAA8B;AACzD,SAAO,OAAO,MAAM,uBAAuB,cAAc,OAAO,MAAM,sBAAsB;AAC9F;AAWO,SAAS,kBAAkB,MAAsB;AACtD,SACE,GAAG,IAAI,yIAC8B,WAAW;AAGpD;AAGO,SAAS,eAAe,GAA+B;AAC5D,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAM,IAAI;AACV,SAAOE,UAAS,MAAM,CAAC,SAAS,OAAO,EAAE,IAAI,MAAM,UAAU;AAC/D;AAKO,SAAS,eAAkD;AAChE,EAAAC,aAAY,YAAY;AACtB,QAAI;AAEF,YAAM,IAAa,MAAM,OAAO,6BAA6B;AAC7D,aAAO,eAAe,CAAC,IAAI,IAAI;AAAA,IACjC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AA9LA,IAyJaD,WAKA,aAkBTC;AAhLJ;AAAA;AAAA;AAyJO,IAAMD,YAAW,CAAC,sBAAsB,uBAAuB,eAAe,mBAAmB;AAKjG,IAAM,cAAc,OAAwC,aAAoB;AAAA;AAAA;;;ACvGvF,eAAsB,qBAAqB,MAAgD;AACzF,MAAI;AACF,UAAM,IAAK,MAAM,KAAK;AACtB,QAAI,OAAO,EAAE,2BAA2B,WAAY,QAAO;AAC3D,MAAE,uBAAuB,gBAAgB,oBAAoB,CAAC;AAC9D,WAAO;AAAA,EACT,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,IAAI,MAA8B,MAAc,OAA8B,YAA8B;AACzH,MAAI;AACF,UAAM,IAAK,MAAM,KAAK;AACtB,WAAO,OAAO,EAAE,IAAI,MAAM;AAAA,EAC5B,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAKO,SAAS,YAAgC;AAC9C,gBAAc,aAAa;AAAA;AAAA,IAEzB,UAAU,MAAM,IAAI,MAAM,OAAO,+BAA+B,GAAG,UAAU;AAAA,IAC7E,WAAW,MAAM,IAAI,MAAM,OAAO,wCAAwC,GAAG,kBAAkB,QAAQ;AAAA,IACvG,YAAY,MAAM,IAAI,MAAM,OAAO,0BAA0B,GAAG,gBAAgB;AAAA;AAAA,IAEhF,kBAAkB,MAAM,IAAI,MAAM,OAAO,qCAAqC,GAAG,wBAAwB;AAAA;AAAA,IAEzG,qBAAqB,MAAM,qBAAqB,MAAM,OAAO,qCAAqC,CAAC;AAAA;AAAA,IAEnG,YAAY,MAAM,IAAI,MAAM,OAAO,2BAA2B,GAAG,iBAAiB;AAAA,EACpF,IAAI;AACJ,SAAO;AACT;AAYO,SAAS,gBAAgB,OAAoE;AAClG,SAAO,OAAO,OAAO,qBAAqB;AAC5C;AAGO,SAAS,oBAAoB,OAA6E;AAC/G,SAAO,OAAO,OAAO,8BAA8B;AACrD;AAGO,SAAS,uBAAuB,OAAyE;AAC9G,SAAO,OAAO,OAAO,0BAA0B;AACjD;AAGO,SAAS,kCAAkC,OAAsF;AACtI,SAAO,OAAO,OAAO,uCAAuC;AAC9D;AAsBO,SAAS,aAA8C;AAC5D,aAAW,YAAY;AACrB,QAAI;AAEF,YAAM,IAAK,MAAM,OAAO,2BAA2B;AACnD,aAAO,OAAO,EAAE,mBAAmB,cAAc,OAAO,EAAE,sBAAsB,cAAc,OAAO,EAAE,yBAAyB,aAAc,IAA8B;AAAA,IAC9K,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AA1JA,IA+Ca,sBA4BT,UAiEA;AA5IJ;AAAA;AAAA;AA+CO,IAAM,uBAAuB;AAAA,MAClC,MAAM;AAAA,MACN,SAAS,EAAE,MAAM,QAAQ,UAAU,YAAY;AAAA,MAC/C,aAAa;AAAA,MACb,QAAQ,EAAE,SAAS,QAAQ,aAAa,EAAE,UAAU,QAAQ,EAAE;AAAA,IAChE;AAAA;AAAA;;;AC3BA,SAAS,SAAS,MAAsB;AACtC,SAAO,KAAK,SAAS,KAAK,UAAU,EAAE;AACxC;AAEA,SAAS,UAAU,MAAuB;AACxC,QAAM,IAAI,KAAK,KAAK;AACpB,SAAO,MAAM,MAAM,CAAC,EAAE,WAAW,GAAG;AACtC;AAGO,SAAS,UAAU,MAAc,OAAuC;AAC7E,QAAME,SAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,MAAM,oBAAI,IAAoB;AACpC,MAAI,QAAQ;AACZ,MAAI,MAAMA,OAAM;AAChB,MAAI,QAAQ;AACZ,MAAI,UAAU,UAAU;AACtB,UAAM,KAAKA,OAAM,UAAU,CAAC,MAAM,mBAAmB,KAAK,CAAC,CAAC;AAC5D,QAAI,KAAK,EAAG,QAAO;AACnB,YAAQ,KAAK;AACb,UAAM,OAAOA,OAAM,UAAU,CAAC,GAAG,MAAM,IAAI,MAAM,SAAS,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAClF,UAAM,OAAO,IAAIA,OAAM,SAAS;AAChC,YAAQ;AAAA,EACV;AACA,MAAI;AACJ,MAAI,OAAiB,CAAC;AACtB,QAAM,QAAQ,MAAY;AACxB,QAAI,SAAS,QAAW;AACtB,aAAO,KAAK,SAAS,KAAK,KAAK,KAAK,SAAS,CAAC,EAAG,KAAK,MAAM,GAAI,MAAK,IAAI;AACzE,UAAI,IAAI,MAAM,KAAK,KAAK,IAAI,CAAC;AAAA,IAC/B;AACA,WAAO;AACP,WAAO,CAAC;AAAA,EACV;AACA,WAAS,IAAI,OAAO,IAAI,KAAK,KAAK;AAChC,UAAM,OAAOA,OAAM,CAAC;AACpB,QAAI,UAAU,IAAI,KAAK,SAAS,IAAI,MAAM,OAAO;AAC/C,YAAM,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC;AACpC,YAAM;AACN,UAAI,GAAG;AACL,eAAO,EAAE,CAAC,EAAG,QAAQ,gBAAgB,EAAE;AACvC,eAAO,CAAC,IAAI;AAAA,MACd;AACA;AAAA,IACF;AACA,QAAI,UAAU,IAAI,KAAK,SAAS,IAAI,IAAI,OAAO;AAC7C,YAAM;AACN;AAAA,IACF;AACA,QAAI,SAAS,OAAW,MAAK,KAAK,IAAI;AAAA,EACxC;AACA,QAAM;AACN,MAAI,UAAU;AAAU,eAAW,KAAK,CAAC,GAAG,IAAI,KAAK,CAAC,EAAG,KAAI,gBAAgB,IAAI,CAAC,EAAG,KAAI,OAAO,CAAC;AAAA;AACjG,SAAO;AACT;AAGO,SAAS,QAAQ,UAAkB,WAAmB,OAAuC;AAClG,QAAM,OAAO,UAAU,WAAW,KAAK;AACvC,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,CAAC,MAAM,KAAK,KAAK,UAAU,UAAU,KAAK,GAAG;AACtD,QAAI,KAAK,IAAI,IAAI,KAAK,aAAa,KAAK,KAAK,EAAG;AAChD,QAAI,IAAI,MAAM,KAAK;AAAA,EACrB;AACA,SAAO;AACT;AAGO,SAAS,YAAY,WAAmB,KAA0B,OAA0B;AACjG,MAAI,IAAI,SAAS,EAAG,QAAO;AAC3B,QAAM,SAAS,UAAU,WAAW,KAAK;AACzC,QAAM,QAAQ,CAAC,GAAG,MAAM,GAAG,aAAa,IAAI,GAAG,IAAI,OAAO,CAAC,EAAE,KAAK,IAAI;AACtE,QAAMA,SAAQ,UAAU,QAAQ,QAAQ,EAAE,EAAE,MAAM,IAAI;AACtD,MAAI,UAAU,UAAU;AACtB,UAAM,KAAKA,OAAM,UAAU,CAAC,MAAM,mBAAmB,KAAK,CAAC,CAAC;AAC5D,QAAI,MAAM,GAAG;AACX,YAAM,OAAOA,OAAM,UAAU,CAAC,GAAG,MAAM,IAAI,MAAM,SAAS,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC;AAClF,UAAI,QAAQ,GAAG;AACb,YAAI,MAAM;AACV,eAAO,MAAM,KAAK,KAAKA,OAAM,MAAM,CAAC,EAAG,KAAK,MAAM,GAAI;AACtD,eAAO,CAAC,GAAGA,OAAM,MAAM,GAAG,GAAG,GAAG,OAAO,GAAGA,OAAM,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,IAAI;AAAA,MAC3E;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,GAAGA,QAAO,KAAK,EAAE,KAAK,IAAI,IAAI;AACxC;AAGO,SAAS,YAAY,UAA8B,WAAmB,OAAoD;AAC/H,MAAI,aAAa,OAAW,QAAO,EAAE,MAAM,WAAW,MAAM,CAAC,EAAE;AAC/D,QAAM,MAAM,QAAQ,UAAU,WAAW,KAAK;AAC9C,SAAO,EAAE,MAAM,YAAY,WAAW,KAAK,KAAK,GAAG,MAAM,CAAC,GAAG,IAAI,KAAK,CAAC,EAAE;AAC3E;AArHA,IAea,eAGP,iBAGA,cAEA;AAvBN;AAAA;AAAA;AAeO,IAAM,gBAAgB;AAG7B,IAAM,kBAAkB,oBAAI,IAAI,CAAC,WAAW,WAAW,UAAU,aAAa,YAAY,SAAS,YAAY,SAAS,iBAAiB,gBAAgB,MAAM,CAAC;AAGhK,IAAM,eAAe;AAErB,IAAM,MAAM;AAAA;AAAA;;;ACNZ,SAAS,gBAAgB;AAazB,SAASC,UAAS,MAAsB;AACtC,SAAO,KAAK,SAAS,KAAK,UAAU,EAAE;AACxC;AAGA,SAAS,SAASC,QAA0B,MAAc,OAA6C;AACrG,QAAM,OAAO,IAAI,OAAO,IAAI,IAAI,OAAO,KAAK,CAAC,GAAG,IAAI,cAAc;AAClE,QAAM,QAAQA,OAAM,UAAU,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC;AACjD,MAAI,QAAQ,EAAG,QAAO;AACtB,MAAI,MAAMA,OAAM;AAChB,WAAS,IAAI,QAAQ,GAAG,IAAIA,OAAM,QAAQ,KAAK;AAC7C,UAAM,IAAIA,OAAM,CAAC;AACjB,QAAI,EAAE,KAAK,MAAM,MAAM,EAAE,UAAU,EAAE,WAAW,GAAG,EAAG;AACtD,QAAID,UAAS,CAAC,KAAK,OAAO;AACxB,YAAM;AACN;AAAA,IACF;AAAA,EACF;AACA,SAAO,CAAC,OAAO,GAAG;AACpB;AAOO,SAAS,gBAAgB,MAAc,OAAkB,MAA2C;AACzG,MAAI,CAAC,KAAM,QAAO;AAClB,QAAMC,SAAQ,KAAK,MAAM,IAAI;AAC7B,QAAM,QAAQ,SAASA,QAAO,UAAU,UAAU,WAAW,IAAI,CAAC;AAClE,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,CAAC,OAAO,GAAG,IAAI;AACrB,QAAM,MAAMA,OAAM,MAAM,OAAO,GAAG;AAClC,MAAI,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,KAAK,QAAQ,CAAC,KAAK,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,oBAAoB,CAAC,EAAG,QAAO;AAC5G,MAAI,UAAU,UAAU;AAEtB,UAAMC,MAAK,IAAI,UAAU,CAAC,MAAM,UAAU,KAAK,CAAC,KAAK,EAAE,SAAS,oBAAoB,CAAC;AACrF,QAAIA,MAAK,EAAG,QAAO;AACnB,UAAMC,QAAO,SAAS,CAAC,KAAK,MAAM,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACzD,WAAO,CAAC,GAAGF,OAAM,MAAM,GAAG,QAAQC,GAAE,GAAG,GAAGC,MAAK,MAAM,IAAI,GAAG,GAAGF,OAAM,MAAM,QAAQC,GAAE,CAAC,EAAE,KAAK,IAAI;AAAA,EACnG;AAEA,QAAM,KAAK,IAAI,UAAU,CAAC,MAAM,oCAAoC,KAAK,CAAC,CAAC;AAC3E,MAAI,KAAK,EAAG,QAAO;AACnB,QAAM,OAAO,SAAS,CAAC,EAAE,MAAM,KAAK,UAAU,IAAI,YAAY,GAAI,OAAO,KAAK,KAAK,GAAG,EAAE,SAAS,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC,GAAI,KAAK,KAAK,OAAO,CAAC,GAAG,CAAC,EAAE,QAAQ,OAAO,EAAE;AACnK,SAAO,CAAC,GAAGD,OAAM,MAAM,GAAG,QAAQ,EAAE,GAAG,GAAG,KAAK,MAAM,IAAI,GAAG,GAAGA,OAAM,MAAM,QAAQ,EAAE,CAAC,EAAE,KAAK,IAAI;AACnG;AA5EA,IA4Ba;AA5Bb;AAAA;AAAA;AA4BO,IAAM,WAAW;AAAA;AAAA;;;ACpBxB,SAAS,cAAAG,aAAY,WAAW,gBAAAC,eAAc,qBAAqB;AACnE,SAAS,WAAAC,UAAS,YAAY,QAAAC,aAAY;AA2B1C,eAAsB,cAAc,OAAgD,OAAyD;AAC3I,QAAM,OAAO,WAAW,MAAM,MAAM,IAAI,MAAM,SAASA,MAAK,MAAM,MAAM,MAAM,MAAM;AACpF,QAAM,WAAWH,YAAW,IAAI,IAAIC,cAAa,MAAM,MAAM,IAAI;AACjE,YAAUC,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,GAAG,MAAM,MAAM,YAAY,IAAI,GAAG,MAAM,KAAK;AACzF,MAAI,SAAS,KAAK,CAACF,YAAW,IAAI,GAAG;AACnC,QAAI,aAAa,OAAW,eAAc,MAAM,QAAQ;AACxD,WAAO,EAAE,MAAM,SAAS,IAAI,OAAO,GAAG,MAAM,QAAQ,UAAU,MAAM,CAAC,EAAE;AAAA,EACzE;AACA,QAAM,YAAY,gBAAgBC,cAAa,MAAM,MAAM,GAAG,MAAM,OAAO,MAAM,WAAW;AAC5F,QAAM,EAAE,MAAM,KAAK,IAAI,YAAY,UAAU,WAAW,MAAM,KAAK;AACnE,gBAAc,MAAM,IAAI;AACxB,SAAO,EAAE,MAAM,MAAM,QAAQ,SAAS,WAAW,cAAc,WAAW,KAAK;AACjF;AAjDA;AAAA;AAAA;AAYA;AACA;AAAA;AAAA;;;ACqCO,SAAS,oBAAsC;AACpD,EAAAG,aAAY,YAAY;AACtB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,iCAAiC;AACjF,YAAM,SAAS,EAAE;AACjB,aACE,OAAO,EAAE,oBAAoB,cAC7B,OAAO,EAAE,sBAAsB,cAC/B,OAAO,QAAQ,kBAAkB,cACjC,OAAO,QAAQ,kBAAkB;AAAA,IAErC,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AAOO,SAAS,eAAe,SAAiD;AAC9E,QAAM,IAAI,UAAU,uCAAuC,KAAK,OAAO,IAAI;AAC3E,SAAO,IAAI,EAAE,CAAC,IAAI;AACpB;AA7EA,IA+Ba,aAGA,kBAGA,UAETA,SA8CS;AArFb,IAAAC,sBAAA;AAAA;AAAA;AA+BO,IAAM,cAAc;AAGpB,IAAM,mBAAmB;AAGzB,IAAM,WAAW,CAAC,OAAuB,MAAM,EAAE;AAgDjD,IAAM,2BACX;AAAA;AAAA;;;AClEF,SAAS,cAAAC,aAAY,eAAAC,cAAa,gBAAAC,eAAc,iBAAAC,gBAAe,aAAAC,kBAAiB;AAChF,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAiBvB,SAAS,SAAS,OAA+B,KAAwD;AAC9G,QAAM,UAAU,IAAI,MAAM,KAAK,EAAE,OAAO,OAAO;AAC/C,SAAO,MAAM,KAAK,IAAI,CAAC,QAAQ;AAC7B,UAAM,MAAM,IAAI,QAAQ,MAAM,GAAG,QAAQ,MAAM,EAAE,KAAK,GAAG,MAAM,QAAQ,KAAK,GAAG;AAC/E,UAAM,OAAO,MAAM,IAAI,QAAQ,MAAM,QAAQ,MAAM,IAAI,IAAI,QAAQ,MAAM,CAAC;AAC1E,WAAO,EAAE,OAAO,CAAC,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG,GAAG,SAAS,CAAC,GAAG,SAAS,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE;AAAA,EACzF,CAAC;AACH;AAGO,SAAS,aAAa,MAAcC,QAAkE;AAE3G,QAAM,SAAS,CAAC,GAAGA,MAAK,EAAE,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,SAAS,EAAE,MAAM,MAAM;AACxE,SAAO,KAAK,QAAQ,4BAA4B,CAAC,UAAU;AACzD,UAAM,MAAM,OAAO,KAAK,CAAC,MAAM,MAAM,QAAQ,MAAM,EAAE,KAAK;AAC1D,WAAO,MAAM,IAAI,UAAU;AAAA,EAC7B,CAAC;AACH;AAGA,SAAS,aAAa,KAAa,UAA4B;AAC7D,MAAI,CAACP,YAAW,GAAG,EAAG,QAAO,CAAC;AAC9B,SAAOC,aAAY,GAAG,EACnB,OAAO,CAAC,MAAM,WAAW,KAAK,CAAC,CAAC,EAChC,IAAI,CAAC,MAAMK,MAAK,KAAK,CAAC,CAAC,EACvB,OAAO,CAAC,OAAOJ,cAAa,GAAG,MAAM,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,SAAS,UAAU,QAAQ,EAAE,CAAC;AACnG;AAOA,eAAsB,cACpB,OACA,OACA,OACA,OACA,OACA,IACiB;AACjB,QAAM,WAAWI,MAAK,GAAG,KAAK,MAAM,QAAQ;AAC5C,QAAM,WAAW,KAAK,UAAU,MAAM,MAAM,MAAM,CAAC,IAAI;AACvD,QAAM,SAASN,YAAW,QAAQ,IAAIE,cAAa,UAAU,MAAM,IAAI;AACvE,MAAI,WAAW,UAAU;AACvB,IAAAE,WAAUC,SAAQ,QAAQ,GAAG,EAAE,WAAW,KAAK,CAAC;AAChD,IAAAF,eAAc,UAAU,QAAQ;AAChC,OAAG,IAAI,GAAG,OAAO,cAAc,MAAM,QAAQ,2DAA2D;AAAA,EAC1G;AACA,QAAM,SAAS,iBAAiB,KAAK;AACrC,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,OAAO,cAAc,OAAO,UAAU,MAAM,UAAU,YAAY,MAAM,GAAG,KAAK;AAC5H,MAAI,SAAS,MAAM,KAAM,QAAO;AAChC,QAAM,QAAQ,aAAaG,MAAK,GAAG,KAAK,MAAM,GAAG,MAAM,QAAQ;AAC/D,MAAI,MAAM,WAAW,GAAG;AACtB,OAAG,IAAI,GAAG,OAAO,0CAA0C,MAAM,QAAQ,UAAU,MAAM,EAAE;AAC3F,WAAO,MAAM;AAAA,EACf;AAEA,QAAMC,SAAQ,aAAa,KAAK,IAAI,SAAY,SAAS,OAAO,MAAM,GAAG;AACzE,aAAW,QAAQ,OAAO;AACxB,QAAIA,QAAO;AACT,YAAM,OAAOL,cAAa,MAAM,MAAM;AACtC,YAAM,OAAO,aAAa,MAAMK,MAAK;AACrC,UAAI,SAAS,KAAM,CAAAJ,eAAc,MAAM,IAAI;AAAA,IAC7C;AACA,OAAG,IAAI,GAAG,OAAO,0BAA0B,KAAK,MAAM,GAAG,IAAI,SAAS,CAAC,CAAC,EAAE;AAAA,EAC5E;AACA,MAAI,UAAU,UAAU;AACtB,OAAG,IAAI,GAAG,OAAO,sGAAsG;AAAA,EACzH;AACA,SAAO,MAAM;AACf;AA7GA,IA4Ba;AA5Bb;AAAA;AAAA;AAsBA;AAGA;AAGO,IAAM,mBAAwD;AAAA,MACnE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AAAA;AAAA;;;ACTA,SAAS,cAAAK,aAAY,aAAAC,YAAW,eAAAC,cAAa,gBAAAC,eAAc,iBAAAC,sBAAqB;AAChF,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAkBvB,SAAS,cAAc,OAA0C;AACtE,SAAO,OAAO,OAAO,mBAAmB;AAC1C;AAGO,SAAS,YAAY,QAAiC,OAAgE;AAC3H,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,KAAK,WAAW,OAAQ,QAAO;AACrF,QAAM,SAAS;AACf,SAAO,OAAO,KAAK,KAAK,OAAO;AACjC;AAGO,SAAS,aAAa,KAA0B;AACrD,QAAMC,UAAU,gBAAgB,EAAE,IAAI,CAAC,EAAE,GAAG,QAA2C;AACvF,SAAO,CAAC,GAAG,cAAc,GAAI,OAAOA,YAAW,YAAYA,QAAO,KAAK,MAAM,KAAK,CAAC,GAAGA,QAAO,QAAQ,SAAS,EAAE,EAAE,QAAQ,QAAQ,EAAE,CAAC,GAAG,IAAI,CAAC,CAAE;AACjJ;AAGO,SAAS,kBAAkB,GAAkB,KAAyC;AAC3F,SAAO;AAAA,IACL,GAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1C,QAAQ,EAAE;AAAA,IACV,GAAI,EAAE,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IACxD,GAAI,EAAE,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA;AAAA,IAExD,GAAI,EAAE,aAAa,SAAY,EAAE,UAAU,EAAE,SAAS,IAAI,CAAC;AAAA,IAC3D,SAAS,aAAa,GAAG;AAAA,EAC3B;AACF;AAQO,SAAS,cAAc,OAAiC,KAAgB,IAAY,SAA0C;AACnI,MAAI,CAAC,cAAc,KAAK,EAAG,QAAO,CAAC;AACnC,QAAM,SAAS,YAAY,gBAAgB,EAAE,IAAI,CAAC,EAAE,SAAS,QAAQ,OAAO;AAC5E,QAAM,IAAI,QAAQ,GAAG;AACrB,QAAM,aAAa,YAAY,kBAAkB,GAAG,UAAU;AAC9D,QAAM,QAAQ,aACV,MAAO,oBACL,MAAO,kBAAkB,eAAe,IAAI,kBAAkB,GAAI,GAAG,CAAC,IACtE,EAAE,IAAI,SAAS,GAAG,kBAAkB,GAAI,GAAG,EAAE,IAC/C;AACJ,SAAO,EAAE,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC,GAAI,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,EAAG;AACpF;AAGO,SAAS,YAAY,MAA+B,KAAsE;AAC/H,QAAM,IAAI,gBAAgB,EAAE,IAAI,CAAC,EAAE;AACnC,QAAMC,UAAS,qBAAqB,EAAE,GAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,GAAI,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC,EAAG,GAAG,KAAK;AAC/I,QAAM,SAAS,YAAY,EAAE,QAAQ,SAAS;AAC9C,SAAO;AAAA,IACL,KAAK,CAAC,EAAE,GAAG,MAAM,GAAI,WAAW,UAAa,KAAK,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC,EAAG,CAAC;AAAA,IAC3F,SAAS;AAAA,MACP,GAAIA,QAAO,eAAe,EAAE,cAAcA,QAAO,aAAa,IAAI,CAAC;AAAA,MACnE,GAAIA,QAAO,QAAQ,EAAE,OAAOA,QAAO,MAAM,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AACF;AAIA,SAAS,eAAe,KAAa,MAAc,MAAuB;AACxE,QAAM,OAAOF,MAAK,KAAK,IAAI;AAC3B,MAAIN,YAAW,IAAI,KAAKG,cAAa,MAAM,MAAM,MAAM,KAAM,QAAO;AACpE,EAAAF,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,EAAAD,eAAc,MAAM,IAAI;AACxB,SAAO;AACT;AAOA,eAAsB,eAAe,OAAqB,OAAkB,KAAa,KAAgB,OAA0B,OAAkB,IAA8B;AACjL,QAAM,IAAI,QAAQ,GAAG;AACrB,MAAI,CAAC,GAAG,QAAS,QAAO,MAAM;AAC9B,MAAI,CAAC,cAAc,KAAK,GAAG;AACzB,OAAG,IAAI,GAAG,OAAO,QAAQ,iBAAiB,EAAE;AAC5C,WAAO,MAAM;AAAA,EACf;AACA,QAAM,aAAgC,EAAE,GAAG,OAAO,UAAU,EAAE,GAAG,MAAM,UAAU,OAAO,QAAQ,EAAE;AAClG,MAAI;AACJ,MAAI;AACF,WAAO,MAAM,oBAAoB,OAAO,KAAK,EAAE,OAAO,YAAY,OAAO,EAAE,MAAM,UAAU,GAAG,kBAAkB,GAAG,GAAG,EAAE,EAAE,CAAC,EAAE,OAAO;AAAA,EACtI,SAAS,GAAG;AACV,OAAG,IAAI,GAAG,OAAO,eAAgB,EAAY,OAAO,EAAE;AACtD,WAAO,MAAM;AAAA,EACf;AACA,MAAI,CAAC,MAAM;AACT,OAAG,IAAI,GAAG,OAAO,0CAA0C,OAAO,qCAAqC;AACvG,WAAO,MAAM;AAAA,EACf;AACA,MAAI,eAAe,GAAG,KAAK,iBAAiB,KAAK,UAAU,YAAY,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,EAAG,IAAG,IAAI,GAAG,OAAO,cAAc,eAAe,EAAE;AACrJ,QAAM,SAAS,cAAc,KAAK;AAClC,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,OAAO,cAAc,OAAO,UAAU,iBAAiB,YAAY,MAAM,GAAG,UAAU;AAClI,MAAI,SAAS,MAAM,KAAM,QAAO;AAChC,QAAM,MAAME,MAAK,GAAG,KAAK,MAAM;AAC/B,QAAM,QAAQN,YAAW,GAAG,IACxBE,aAAY,GAAG,EAAE,OAAO,CAAC,MAAM,WAAW,KAAK,CAAC,MAAMC,cAAaG,MAAK,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,SAAS,UAAU,eAAe,EAAE,CAAC,IACvJ,CAAC;AACL,aAAW,KAAK,MAAO,IAAG,IAAI,GAAG,OAAO,sBAAsBA,MAAK,QAAQ,CAAC,EAAE,QAAQ,SAAS,EAAE,CAAC,gBAAgB,OAAO,cAAc;AACvI,KAAG,IAAI,GAAG,OAAO,iDAAiD,EAAE,MAAM,yBAAyB,EAAE,YAAY,SAAY,wDAAwD,EAAE,EAAE;AACzL,MAAI,UAAU,YAAY,EAAE,aAAa,OAAW,IAAG,IAAI,GAAG,OAAO,yLAAyL;AAAA,WACrP,EAAE,aAAa,OAAW,IAAG,IAAI,GAAG,OAAO,iCAAiC,EAAE,QAAQ,wBAAwB;AACvH,MAAI,UAAU,SAAU,IAAG,IAAI,GAAG,OAAO,0JAA0J,QAAQ,OAAO;AAClN,SAAO,MAAM;AACf;AA1JA,IAmCa,UACA,iBAGA,mBAmEP;AA1GN;AAAA;AAAA;AAyBA;AAEA;AACA;AAEA;AAEA;AAGO,IAAM,WAAW;AACjB,IAAM,kBAAkB;AAGxB,IAAM,oBAAoB;AAmEjC,IAAM,gBAAqD,EAAE,QAAQ,qBAAqB,SAAS,sBAAsB,QAAQ,IAAI;AAAA;AAAA;;;ACtFrI,SAAS,kBAAkB;AAoCpB,SAAS,eAAe,SAAsC,kBAAiE;AACpI,QAAM,QAAQ,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,MAAM,GAAG,EAAE,KAAK,IAAK,iBAAiB,EAAE,IAAI,CAAC,EAAE,EAAE,KAAK;AACtH,SAAO,WAAW,QAAQ,EAAE,OAAO,MAAM,KAAK,IAAI,CAAC,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AAChF;AAGO,SAAS,cAAcG,SAAgD;AAC5E,SAAOA,YAAW,WAAcA,QAAO,WAAW,UAAaA,QAAO,OAAO,SAAS,OAAO;AAC/F;AAMA,eAAsB,gBAAgB,OAUD;AACnC,MAAI,CAAC,cAAc,MAAM,MAAM,EAAG,QAAO;AACzC,QAAM,UAAU,MAAM,QAAQ,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC;AACjE,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,QAAM,cAAc,eAAe,MAAM,SAAS,MAAM,gBAAgB;AACxE,MAAI,CAAC,MAAM,MAAO,QAAO,EAAE,MAAM,OAAO,QAAQ,0BAA0B,YAAY;AACtF,MAAI,QAAQ,MAAM,CAAC,MAAM,EAAE,OAAO,WAAW,WAAW,GAAG;AACzD,WAAO,EAAE,MAAM,OAAO,QAAQ,6FAA6F,YAAY;AAAA,EACzI;AACA,QAAM,SAAS,MAAM,QAAQ,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK;AACpE,QAAM,IAAI,MAAM;AAChB,QAAM,SAAS,EAAE,kBAAkB,EAAE,OAAO;AAAA,IAC1C,SAAS,QAAQ,IAAI,CAAC,MAAM,EAAE,KAAK;AAAA,IACnC,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IAClC;AAAA,IACA,GAAI,MAAM,cAAc,EAAE,aAAa,MAAM,YAAY,IAAI,CAAC;AAAA,EAChE,CAAC;AACD,QAAM,QAAQ,EAAE,gBAAgB,QAAQ,EAAE,KAAK,MAAM,IAAI,CAAC;AAC1D,QAAM,aAAa,MAAM,EAAE,WAAW,MAAM,QAAQ,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,KAAK,MAAM,KAAK,KAAK,MAAM,KAAK,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC,EAAG,CAAC,CAAC;AAC5K,SAAO,EAAE,MAAM,WAAW,KAAK,CAAC,MAAM,EAAE,EAAE,GAAG,aAAa,YAAY,GAAI,WAAW,KAAK,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,IAAI,EAAE,QAAQ,+BAA+B,EAAG;AAC5J;AAKO,SAAS,mBAAyE;AACvF,cAAY,YAAY;AACtB,QAAI;AAEF,YAAM,UAAmC,MAAM,OAAO,6BAA6B;AACnF,YAAMA,UAAkC,MAAM,OAAO,yBAAyB;AAC9E,YAAM,MAAM,CAAC,QAAQ,mBAAmB,QAAQ,oBAAoBA,QAAO,iBAAiBA,QAAO,UAAU;AAC7G,UAAI,CAAC,IAAI,MAAM,CAAC,MAAM,OAAO,MAAM,UAAU,EAAG,QAAO;AACvD,aAAO;AAAA,QACL,mBAAmB,QAAQ;AAAA,QAC3B,oBAAoB,QAAQ;AAAA,QAC5B,iBAAiBA,QAAO;AAAA,QACxB,YAAYA,QAAO;AAAA,MACrB;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AA5HA,IAqDa,0BAiDT;AAtGJ;AAAA;AAAA;AAqDO,IAAM,2BAA2B;AAAA;AAAA;;;ACrDxC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA2BO,SAAS,eAAiC;AAC/C,EAAAC,eAAc,YAAY;AACxB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,8BAA8B;AAC9E,aAAO,OAAO,EAAE,eAAe,cAAc,OAAO,EAAE,uBAAuB;AAAA,IAC/E,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AAGO,SAAS,qBAAqBC,MAA8B;AACjE,EAAAD,YAAWC,SAAQ,UAAU,SAAY,QAAQ,QAAQA,IAAG;AAC9D;AAMO,SAAS,gBAAgB,OAAkB,QAAwB;AACxE,SAAO,UAAU,WAAW,IAAI,MAAM,KAAK,gBAAgB,MAAM;AACnE;AAGO,SAAS,aAAa,OAAkB,GAAuE;AACpH,QAAM,MAA8B,EAAE,GAAG,EAAE,UAAU;AACrD,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,EAAE,OAAO,GAAG;AAEtD,QAAI,UAAU,YAAY,SAAS,OAAQ;AAC3C,QAAI,IAAI,IAAI,gBAAgB,OAAO,MAAM;AAAA,EAC3C;AACA,SAAO;AACT;AAGO,SAAS,eAAe,OAAe,GAAoE;AAChH,SAAO,EAAE,aAAa,KAAK,CAAC,MAAM,YAAY,EAAE,MAAM,KAAK,CAAC,GAAG;AACjE;AAKO,SAAS,UAAU,aAA2C,OAA4B;AAC/F,MAAI,OAAO,cAAc,YAAY,KAAK,YAAY,EAAE,QAAQ,YAAY,GAAG,EAAE,QAAQ,YAAY,EAAE,KAAK,QAAQ;AACpH,MAAI,CAAC,YAAY,KAAK,IAAI,EAAG,QAAO,OAAO,IAAI;AAC/C,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,MAAM,IAAI,IAAI,GAAG,IAAK,QAAO,GAAG,IAAI,IAAI,CAAC;AACzD,QAAM,IAAI,IAAI;AACd,SAAO;AACT;AAkBO,SAAS,gBAAgB,MAA+B,GAAgB,OAAkB,MAAyD;AACxJ,QAAM,YAAY,aAAa,OAAO,CAAC;AACvC,QAAM,SAAS,MAAM,QAAQ,KAAK,KAAK,IAAK,KAAK,QAAmB,CAAC,GAAG,IAAI,CAAC,SAAS;AACpF,UAAM,MAAY,EAAE,GAAG,KAAK;AAC5B,QAAI,OAAO,KAAK,SAAS,EAAE,OAAQ,KAAI,YAAY,EAAE,GAAK,KAAK,aAAoD,CAAC,GAAI,GAAG,UAAU;AACrI,QAAI,EAAE,aAAa,WAAW,EAAG,QAAO;AACxC,UAAM,QAAQ,KAAK,QAAQ,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,MAAM;AAClD,UAAM,QAAQ,oBAAI,IAA2E;AAC7F,eAAW,UAAU,MAAM;AACzB,YAAM,cAAc,eAAe,QAAQ,CAAC;AAC5C,YAAM,MAAM,cAAc,KAAK,UAAU,WAAW,IAAI;AACxD,YAAM,KAAK,MAAM,IAAI,GAAG,KAAK,EAAE,aAAa,MAAM,CAAC,EAAE;AACrD,SAAG,KAAK,KAAK,MAAM;AACnB,YAAM,IAAI,KAAK,EAAE;AAAA,IACnB;AACA,WAAO,IAAI;AACX,WAAO,IAAI;AACX,QAAI,MAAM,SAAS,GAAG;AACpB,YAAM,CAAC,IAAI,IAAI,MAAM,OAAO;AAC5B,UAAI,KAAM,YAAa,KAAI,cAAc,EAAE,GAAG,KAAM,YAAY;AAChE,aAAO;AAAA,IACT;AACA,QAAI,KAAK,WAAW,UAAa,KAAK,SAAS,GAAG;AAChD,YAAM,IAAI,MAAM,QAAQ,KAAK,IAAI,oBAAoB,MAAM,IAAI,mCAAmC,KAAK,MAAM,mHAAmH;AAAA,IAClO;AACA,UAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAI,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,EAAE,IAAI,CAAC,OAAO,EAAE,MAAM,UAAU,EAAE,aAAa,KAAK,GAAG,MAAM,EAAE,MAAM,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,GAAG,EAAE,YAAY,EAAE,IAAI,CAAC,EAAG,EAAE;AACtK,WAAO;AAAA,EACT,CAAC;AACD,SAAO,EAAE,GAAG,MAAM,OAAO,GAAI,KAAK,eAAe,EAAE,gBAAgB,UAAa,KAAK,SAAS,SAAY,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC,EAAG;AACjJ;AAGO,SAAS,cAAc,QAA6H;AACzJ,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,KAAK,WAAW,OAAQ,QAAO,EAAE,SAAS,OAA0B;AAC1H,QAAM,SAAS;AACf,QAAM,MAAM,EAAE,GAAI,OAAO,UAAU,EAAE,MAAM,OAAO,QAAQ,IAAI,CAAC,GAAI,GAAI,OAAO,KAAK,EAAE,OAAO,OAAO,GAAG,IAAI,CAAC,GAAI,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC,EAAG;AACtK,SAAO,OAAO,KAAK,GAAG,EAAE,SAAS,MAAM;AACzC;AAGO,SAAS,iBAAiB,GAA4B,QAA0D;AACrH,QAAM,UAAU,cAAc,MAAM;AACpC,SAAO;AAAA,IACL,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC7B,GAAI,KAAK,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,WAAW,EAAE,GAAG,EAAE,UAAU,EAAE,IAAI,CAAC;AAAA,IAChF,GAAI,KAAK,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,SAAS,EAAE,GAAG,EAAE,QAAQ,EAAE,IAAI,CAAC;AAAA,IAC1E,GAAI,GAAG,gBAAgB,SAAY,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,EACvE;AACF;AAOO,SAAS,eAAe,GAA4B,QAAuE;AAChI,QAAM,QAAkB,CAAC;AACzB,QAAM,QAAkB,CAAC;AACzB,aAAW,CAAC,OAAO,IAAI,KAAK,OAAO,QAAQ,cAAc,MAAM,KAAK,CAAC,CAAC,GAAG;AACvE,QAAI,OAAO,SAAS,SAAU,OAAM,KAAK,eAAe,GAAG,KAAK,IAAI,IAAI,EAAE;AAAA,aACjE,MAAM,QAAQ,IAAI,EAAG,OAAM,KAAK,eAAe,GAAG,KAAK,IAAI,KAAK,KAAK,GAAG,CAAC,EAAE;AAAA,QAC/E,OAAM,KAAK,gBAAgB,UAAU,SAAS,YAAY,UAAU,UAAU,OAAO,SAAS,iBAAiB,KAAK,KAAK,yGAAyG;AAAA,EACzO;AACA,aAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,GAAG,aAAa,CAAC,CAAC,EAAG,OAAM,KAAK,iBAAiB,GAAG,IAAI,IAAI,KAAK,EAAE;AAC9G,aAAW,CAAC,MAAM,MAAM,KAAK,OAAO,QAAQ,GAAG,WAAW,CAAC,CAAC,EAAG,OAAM,KAAK,eAAe,GAAG,IAAI,IAAI,MAAM,EAAE;AAC5G,MAAI,GAAG,gBAAgB,OAAW,OAAM,KAAK,iBAAiB,OAAO,EAAE,WAAW,CAAC;AACnF,SAAO,EAAE,OAAO,MAAM;AACxB;AAGO,SAAS,eAAe,GAA4B,QAA0C;AACnG,SAAO,WAAW,UAAc,MAAM,WAAc,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,KAAK,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,KAAK,EAAE,gBAAgB;AACpJ;AAGA,eAAsB,UAAU,UAAyI;AACvK,MAAI,CAAC,eAAe,SAAS,MAAM,SAAS,MAAM,EAAG,QAAO,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,EAAE;AAChG,MAAI,CAAE,MAAM,aAAa,GAAI;AAC3B,UAAM,QAAQ;AAAA,MACZ,GAAI,SAAS,WAAW,SAAY,CAAC,SAAS,IAAI,CAAC;AAAA,MACnD,GAAI,SAAS,QAAQ,OAAO,KAAK,SAAS,KAAK,SAAS,EAAE,SAAS,CAAC,KAAK,IAAI,CAAC;AAAA,MAC9E,GAAI,SAAS,QAAQ,OAAO,KAAK,SAAS,KAAK,OAAO,EAAE,SAAS,CAAC,MAAM,IAAI,CAAC;AAAA,MAC7E,GAAI,SAAS,MAAM,gBAAgB,SAAY,CAAC,aAAa,IAAI,CAAC;AAAA,IACpE;AACA,WAAO,EAAE,SAAS,CAAC,GAAG,OAAO,CAAC,GAAG,OAAO,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,6BAA6B,eAAe,mCAAmC,MAAM,OAAO,CAAC,MAAM,MAAM,aAAa,EAAE,KAAK,IAAI,KAAK,cAAc,EAAE,EAAE;AAAA,EACtN;AACA,QAAM,EAAE,OAAO,MAAM,IAAI,eAAe,SAAS,MAAM,SAAS,MAAM;AACtE,SAAO,EAAE,SAAS,iBAAiB,SAAS,MAAM,SAAS,MAAM,GAAG,OAAO,MAAM;AACnF;AA3LA,IAwBID,WAsBS,iBAuBP;AArEN,IAAAE,aAAA;AAAA;AAAA;AAsBA,IAAAC;AAwBO,IAAM,kBAAkB;AAuB/B,IAAM,aAAa;AAAA;AAAA;;;AC7CZ,SAAS,UAAU,MAAc,OAAuC;AAC7E,SAAO,SAAS,KAAK,CAAC,SAAS,MAAM,IAAI,MAAM,IAAI;AACrD;AAGO,SAAS,YAAY,SAAkB,MAAsB,CAAC,GAAW;AAC9E,QAAM,OAAO,IAAI,SAAS,SAAY,QAAQ,IAAI,IAAI,KAAK;AAC3D,QAAM,QAAQ,IAAI,OAAO,SAAY,IAAI,OAAO,uBAAuB,IAAI,EAAE,KAAK,GAAG,OAAO,MAAM,IAAI,SAAS,SAAY,WAAW,IAAI,IAAI,KAAK,EAAE;AACrJ,UAAQ,SAAS;AAAA,IACf,KAAK;AACH,aAAO,GAAG,IAAI,kEAAkE,OAAO,YAAY,IAAI,+BAA+B,KAAK;AAAA,IAC7I,KAAK;AACH,aAAO,4JAA4J,OAAO,iBAAiB,OAAO,gEAAgE,OAAO,YAAY,OAAO;AAAA,IAC9R,KAAK;AACH,aAAO,oLAAoL,OAAO,0CAA0C,KAAK;AAAA,IACnP,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,8EAA8E,OAAO,yFAAyF,iBAAiB;AAAA,IACxM,KAAK;AACH,aAAO;AAAA,IACT,KAAK;AACH,aAAO,kQAAkQ,OAAO;AAAA,EACpR;AACF;AAGO,SAAS,eAAe,MAAc,OAAkB,KAA0B,MAAsB,CAAC,GAAW;AACzH,QAAM,UAAU,UAAU,MAAM,KAAK;AACrC,MAAI,QAAS,KAAI,GAAG,OAAO,KAAK,YAAY,SAAS,GAAG,CAAC,EAAE;AAC3D,SAAO;AACT;AAvDA,IAmBa;AAnBb;AAAA;AAAA;AAQA;AAWO,IAAM,WAAW,CAAC,WAAW,SAAS,QAAQ,cAAc,UAAU,YAAY,WAAW;AAAA;AAAA;;;ACYpG,SAAS,cAAAC,aAAY,gBAAAC,qBAAoB;AACzC,SAAS,QAAAC,aAAY;AAyBd,SAAS,cACd,MACA,MACkD;AAClD,MAAI,KAAK,GAAI,QAAO,EAAE,IAAI,KAAK,IAAI,KAAK;AAExC,MAAI,MAAM,KAAK,IAAI,EAAG,QAAO,EAAE,IAAI,MAAM,MAAM,QAAQ;AAEvD,MAAI,SAAS,oBAAoB,SAAS,aAAa;AACrD,QAAI,CAAC,KAAK,GAAI,QAAO,EAAE,OAAO,2EAA2E;AACzG,QAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,EAAG,QAAO,EAAE,OAAO,0CAA0C,KAAK,EAAE,IAAI;AACjG,WAAO,EAAE,IAAI,SAAS,KAAK,EAAE,GAAG,MAAM,YAAY;AAAA,EACpD;AACA,MAAI,SAAS,SAAS;AACpB,QAAI,CAAC,KAAK,GAAI,QAAO,EAAE,OAAO,OAAO,OAAO,qFAAqF;AACjI,QAAI,CAAC,QAAQ,KAAK,KAAK,EAAE,EAAG,QAAO,EAAE,OAAO,0CAA0C,KAAK,EAAE,IAAI;AACjG,WAAO,EAAE,IAAI,KAAK,QAAQ,MAAM,KAAK,EAAE,IAAI,KAAK,KAAK,KAAK,MAAM,KAAK,EAAE,IAAI,KAAK;AAAA,EAClF;AAEA,SAAO,EAAE,IAAI,SAAS,KAAK;AAC7B;AAMA,SAAS,UAAU,MAAgB,QAA2B,UAAmF;AAC/I,QAAM,OAAiB,CAAC;AACxB,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,OAAO,SAAS,CAAC,GAAG;AACtB,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,UAAI,MAAM,UAAa,EAAE,WAAW,IAAI,EAAG,QAAO,EAAE,MAAM,MAAM,SAAS,EAAE;AAC3E,WAAK,KAAK,GAAG,CAAC;AACd;AAAA,IACF,WAAW,SAAS,SAAS,CAAC,EAAG,MAAK,KAAK,CAAC;AAAA,QACvC,MAAK,KAAK,CAAC;AAAA,EAClB;AACA,SAAO,EAAE,MAAM,KAAK;AACtB;AAOA,eAAsB,QAAQ,MAAgB,MAAe,OAAkB,IAA8B;AAC3G,QAAM,KAAK,SAAS,MAAM,MAAM;AAChC,QAAM,QAAQ,SAAS,GAAG,MAAM,SAAS;AACzC,QAAM,KAAK,SAAS,MAAM,MAAM,MAAM;AACtC,QAAM,YAAY,SAAS,GAAG,MAAM,SAAS;AAC7C,QAAM,aAAa,SAAS,UAAU,MAAM,UAAU;AACtD,aAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,WAAW,SAAS,GAAG,CAAC,YAAY,UAAU,CAAC,GAAY;AACnI,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAAA,EAChE;AACA,MAAI,UAAU,UAAU,UAAa,CAAE,OAA6B,SAAS,UAAU,KAAK,EAAG,QAAO,MAAM,WAAW,UAAU,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACtL,QAAM,SAAS,UAAU,WAAW,MAAM,cAAc,gBAAgB;AACxE,MAAI,OAAO,QAAS,QAAO,MAAM,GAAG,OAAO,OAAO,kBAAkB,OAAO,EAAE;AAC7E,QAAM,QAAQ,YAAY,OAAO,IAAI;AACrC,QAAM,UAAU,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAC3D,MAAI,QAAQ,OAAQ,QAAO,MAAM,yBAAyB,QAAQ,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACxF,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,4BAA4B,OAAO,YAAY,OAAO,kCAAkC,OAAO,sCAAsC,OAAO,EAAE;AACnL,QAAM,WAAW,GAAG,SAAS,GAAG,IAAI;AACpC,QAAM,OAAO,MAAM,CAAC;AACpB,QAAM,OAAO,OAAO,KAAK,OAAO,KAAK,QAAQ,QAAQ,IAAI,CAAC;AAE1D,QAAM,SAAS,SAAS,WAAW,CAAC,YAAY,CAAC,GAAG,SAAS,OAAO,KAAK,SAAS,QAAQ;AAC1F,QAAM,SAAS,SAAS,SAAY,cAAc,MAAM,EAAE,IAAI,UAAU,OAAO,MAAM,OAAO,IAAI,GAAG,MAAM,CAAC;AAC1G,MAAI,UAAU,WAAW,OAAQ,QAAO,MAAM,OAAO,OAAO,OAAO,EAAE;AACrE,MAAI,CAAC,OAAO,KAAK,SAAS,QAAQ,KAAK,CAAC,OAAO,KAAK,SAAS,UAAU,GAAG;AACxE,WAAO,MAAM,8HAA8H,OAAO,EAAE;AAAA,EACtJ;AACA,SAAO,UAAU,GAAG,OAAO,YAAY,OAAO,IAAI,OAAO,UAAU;AACjE,QAAI,KAAK;AACT,QAAI,CAAC,IAAI;AACP,YAAM,QAAQ,MAAM,eAAe,OAAO,MAAO,EAAE,OAAO,MAAM,OAAO,KAAK,GAAG,IAAI,CAAC;AACpF,UAAI,WAAW,MAAO,QAAO,MAAM,MAAM,OAAO,OAAO,EAAE;AACzD,UAAI,CAAC,KAAM,IAAG,IAAI,GAAG,OAAO,aAAa,IAAI,0BAA0B,MAAM,EAAE,MAAM,OAAO,aAAa,MAAM,EAAE,GAAG;AACpH,WAAK,EAAE,IAAI,MAAM,IAAI,MAAM,QAAQ;AAAA,IACrC;AACA,UAAM,OAAO,CAAC,WAAW,GAAG,IAAI,GAAG,MAAM,GAAG,OAAO,MAAM,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AACpF,UAAM,OAAO,eAAe,MAAM,MAAM,kBAAkB,MAAM,aAAa,GAAG,OAAO,GAAG,GAAG;AAE7F,QAAI,SAAS,MAAM,QAAQ,GAAG,SAAS,WAAW,CAAC,MAAM,KAAK,GAAG,EAAE,KAAK,CAAC,OAAO,KAAK,SAAS,QAAQ,KAAK,OAAO,KAAK,SAAS,UAAU,EAAG,QAAO;AACpJ,UAAM,OAAO,YAAY,GAAG,GAAG;AAC/B,QAAI,QAAQ,6BAA6B,IAAI,GAAG;AAC9C,YAAM,UAAU,MAAM,MAAM,kBAAkB,UAAU,OAAO,IAAI,GAAG,aAAa;AACnF,UAAI,YAAY,MAAM,MAAM;AAC1B,WAAG,IAAI,GAAG,OAAO,aAAa,GAAG,EAAE,uDAAuD,OAAO,iBAAiB,OAAO,iDAAiD,OAAO,UAAU,OAAO,YAAY,OAAO,SAAS,OAAO,WAAW,IAAI,6BAA6B;AACjR,eAAO,eAAe,SAAS,OAAO,GAAG,GAAG;AAAA,MAC9C;AACA,UAAI,CAAC,KAAM,IAAG,IAAI,GAAG,OAAO,8CAA8C,OAAO,6DAA6D,OAAO,OAAO;AAAA,IAC9J;AACA,QAAI,KAAM,OAAM,sBAAsB,OAAO,MAAM,EAAE,OAAO,UAAU,OAAO,QAAQ,WAAW,OAAO,KAAK,GAAG,EAAE;AACjH,WAAO;AAAA,EACT,CAAC;AACH;AAGA,SAAS,YAAY,KAAa,OAAO,iBAAsD;AAC7F,QAAM,OAAOA,MAAK,KAAK,IAAI;AAC3B,MAAI,CAACF,YAAW,IAAI,EAAG,QAAO;AAC9B,MAAI;AACF,UAAM,OAAgB,KAAK,MAAMC,cAAa,MAAM,MAAM,CAAC;AAC3D,WAAO,QAAQ,OAAO,SAAS,YAAY,CAAC,MAAM,QAAQ,IAAI,IAAK,OAAmC;AAAA,EACxG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AASO,SAAS,6BAA6B,MAAwC;AACnF,QAAM,OAAQ,KAAK,WAAgE,aAAa;AAChG,QAAM,QAAQ,MAAM,QAAQ,KAAK,KAAK,IAAK,KAAK,QAAiD,CAAC;AAClG,SAAO,SAAS,WAAW,MAAM,KAAK,CAAC,MAAM,GAAG,aAAa,cAAc;AAC7E;AAOO,SAAS,UAAU,QAAqC;AAC7D,QAAM,OAAO,OAAO,OAAO,CAAC,MAAM,MAAM,UAAU;AAClD,SAAO,CAAC,WAAW,SAAS,SAAS,GAAG,MAAM,GAAI,KAAK,SAAS,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,CAAE;AAC5F;AAOO,SAAS,qBAAqB,MAA2C,KAA4B,KAA6D;AACvK,QAAM,aAAc,KAAK,OAAyC;AAClE,QAAME,MAAK,IAAI,cAAc,SAAS,WAAW,IAAI,oBAAoB,UAAU,IAAI,kBAAkB,SAAS,YAAY,IAAI,mBAAmB,SAAS,WAAW;AACzK,QAAM,QAAQ,KAAK,SAAS,cAAcA;AAC1C,QAAM,SAAS,KAAK,WAAW,IAAI,mBAAmB,IAAI,uCAAuC,IAAI,sBAAsB,IAAI,mBAAmB,SAAS,IAAI,kBAAkB,WAAc;AAC/L,SAAO,EAAE,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC,GAAI,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AACtE;AAUA,eAAe,sBAAsB,OAAqB,MAA+B,MAA0D,IAA4B;AAC7K,MAAI,CAAC,kCAAkC,KAAK,EAAG;AAC/C,QAAM,QAAQ,MAAM,6BAA6B,MAAM,2BAA2B,IAAI,IAAI,6BAA6B,IAAI;AAC3H,MAAI,CAAC,MAAO;AACZ,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,QAAM,MAAM,OAAO,WAAW,IAAI,EAAE,MAAM;AAC1C,QAAM,KAAK,qBAAqB,MAAM,KAAK,GAAG,GAAG;AACjD,QAAM,OAAO,CAAC,QAAgB,UAAkB,GAAG,OAAO,oBAAoB,eAAe,sCAAsC,MAAM,YAAY,KAAK;AAC1J,MAAI,CAAC,GAAG,SAAS,CAAC,GAAG,QAAQ;AAC3B,OAAG,IAAI,GAAG,OAAO,aAAa,OAAO,oEAAoE,KAAK,GAAG,UAAU,mBAAmB,GAAG,SAAS,SAAS,CAAC,sBAAsB;AAC1L;AAAA,EACF;AACA,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,OAAO,QAAQ,UAAU,iBAAiB,qBAAqB,UAAU,YAAY,GAAG,QAAQ,WAAW,GAAG,KAAK,GAAG,aAAa;AAC/K,MAAI,SAAS,EAAG,IAAG,IAAI,GAAG,OAAO,2CAA2C,OAAO,wCAAwC,IAAI,mDAAmD,KAAK,GAAG,QAAQ,GAAG,KAAK,CAAC,GAAG;AAAA,WACrM,CAAC,KAAK,KAAM,IAAG,IAAI,GAAG,OAAO,oBAAoB,OAAO,kDAAkD,GAAG,MAAM,EAAE;AAChI;AAOA,eAAsB,eAAe,OAAqB,QAAgB,OAAyC,CAAC,GAA4D;AAC9K,QAAM,UAAU,OAAO,OAAO;AAC9B,MAAI,CAAC,aAAa,KAAK,EAAG,QAAO,EAAE,OAAO,GAAG,OAAO,mFAAmF;AACvI,MAAI;AACJ,MAAI;AACF,YAAQ,MAAM,MAAM,mBAAoB,QAAQ,EAAE,kBAAkB,MAAM,GAAI,KAAK,MAAM,EAAE,KAAK,KAAK,IAAI,IAAI,CAAC,EAAG,CAAC;AAAA,EACpH,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,GAAG,OAAO,mCAAmC,MAAM,YAAa,EAAY,OAAO,GAAG;AAAA,EACxG;AACA,MAAIC,MAAK,MAAM,OAAO,CAAC,MAAM,EAAE,SAAS,WAAW,EAAE,OAAO,MAAS;AACrE,MAAI,KAAK,MAAO,CAAAA,MAAKA,IAAG,OAAO,CAAC,MAAM,EAAE,WAAW,KAAK,KAAK;AAC7D,QAAM,MAAM,CAAC,GAAG,IAAI,IAAIA,IAAG,IAAI,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AAC5C,MAAI,IAAI,WAAW,EAAG,QAAO,EAAE,OAAO,qBAAqB,OAAO,kBAAkB,MAAM,GAAG,KAAK,QAAQ,QAAQ,KAAK,KAAK,KAAK,EAAE,2GAA2G;AAC9O,QAAM,MAAM,CAAC,GAAG,IAAI,IAAIA,IAAG,IAAI,CAAC,MAAM,EAAE,EAAG,CAAC,CAAC;AAC7C,MAAI,IAAI,SAAS,EAAG,QAAO,EAAE,OAAO,GAAG,MAAM,iBAAiB,OAAO,0BAA0B,IAAI,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,KAAK,IAAI,CAAC,2BAA2B;AAE9J,QAAM,QAAQA,IAAG,KAAK,CAAC,MAAM,EAAE,WAAW,MAAS;AACnD,MAAI,MAAO,QAAO,EAAE,IAAI,MAAM,IAAI,IAAI,MAAM,GAAI;AAChD,MAAI,IAAI,SAAS,EAAG,QAAO,EAAE,OAAO,GAAG,MAAM,iBAAiB,OAAO,YAAY,IAAI,KAAK,IAAI,CAAC,wCAAwC;AACvI,SAAO,EAAE,IAAI,IAAI,CAAC,GAAI,IAAI,IAAI,CAAC,EAAG;AACpC;AAOA,eAAsB,SAAS,MAAgB,MAAe,OAAkB,IAA8B;AAC5G,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,UAAU;AACxB,YAAM,IAAI,KAAK,IAAI,CAAC;AACpB,UAAI,MAAM,UAAa,EAAE,WAAW,IAAI,EAAG,QAAO,MAAM,0BAA0B,OAAO,EAAE;AAC3F,YAAM,KAAK,CAAC;AACZ;AAAA,IACF,MAAO,MAAK,KAAK,KAAK,CAAC,CAAE;AAAA,EAC3B;AACA,QAAM,SAAS,SAAS,MAAM,UAAU;AACxC,MAAI,OAAO,QAAS,QAAO,MAAM,yBAAyB,OAAO,EAAE;AACnE,QAAM,SAAS,UAAU,OAAO,MAAM,CAAC,UAAU,cAAc,WAAW,SAAS,cAAc,GAAG,CAAC,UAAU,qBAAqB,CAAC;AACrI,MAAI,OAAO,QAAS,QAAO,MAAM,GAAG,OAAO,OAAO,kBAAkB,OAAO,EAAE;AAC7E,QAAM,UAAU,OAAO,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAC3D,MAAI,QAAQ,OAAQ,QAAO,MAAM,0BAA0B,QAAQ,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACzF,QAAM,QAAQ,YAAY,OAAO,IAAI;AACrC,QAAM,OAAO,GAAG,OAAO;AACvB,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,+CAA+C,IAAI,IAAI,OAAO,EAAE;AACrG,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,6CAA6C,IAAI,IAAI,OAAO,EAAE;AACnG,MAAI,CAAC,OAAO,OAAO,KAAK,EAAG,QAAO,MAAM,6FAA6F,OAAO,EAAE;AAC9I,QAAM,OAAO,CAAC,WAAW,aAAa,MAAM,CAAC,GAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,CAAC,UAAU,CAAC,CAAC,GAAG,YAAY,OAAO,OAAO,GAAG,OAAO,MAAM,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AAC9J,SAAO,UAAU,GAAG,OAAO,aAAa,OAAO,IAAI,OAAO,UAAU,eAAe,MAAM,MAAM,kBAAkB,MAAM,aAAa,GAAG,OAAO,GAAG,GAAG,CAAC;AACvJ;AASO,SAAS,WAAW,KAAa,OAAO,iBAA6C;AAC1F,QAAM,OAAOF,MAAK,KAAK,IAAI;AAC3B,MAAI,CAACF,YAAW,IAAI,EAAG,QAAO,EAAE,OAAO,MAAM,IAAI,MAAM,OAAO,4CAA4C;AAC1G,MAAI;AACJ,MAAI;AACF,WAAO,KAAK,MAAMC,cAAa,MAAM,MAAM,CAAC;AAAA,EAC9C,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,GAAG,IAAI,KAAM,EAAY,OAAO,GAAG;AAAA,EACrD;AACA,QAAM,IAAI;AACV,MAAI,CAAC,KAAK,CAAC,MAAM,QAAQ,EAAE,KAAK,KAAK,EAAE,MAAM,WAAW,EAAG,QAAO,EAAE,OAAO,GAAG,IAAI,gBAAgB;AAClG,MAAI,EAAE,MAAM,SAAS,cAAc;AACjC,WAAO,EAAE,OAAO,GAAG,IAAI,oBAAoB,EAAE,MAAM,OAAO,OAAO,EAAE,KAAK,IAAI,UAAU,oBAAoB,KAAK,OAAO,mCAAmC,YAAY,6BAA6B,YAAY,cAAc,OAAO,4BAA4B;AAAA,EACjQ;AACA,SAAO;AACT;AAQA,eAAsB,GAAG,MAAgB,MAAe,OAAkB,IAA8B;AACtG,QAAM,KAAK,SAAS,MAAM,MAAM;AAChC,MAAI,GAAG,QAAS,QAAO,MAAM,oCAAoC,OAAO,EAAE;AAC1E,MAAI,GAAG,UAAU,OAAW,QAAO,cAAc,GAAG,OAAO,GAAG,MAAM,MAAM,OAAO,EAAE;AAEnF,QAAM,WAAW,SAAS,GAAG,MAAM,QAAQ;AAC3C,QAAM,OAAO,SAAS,SAAS,MAAM,QAAQ;AAC7C,QAAM,QAAQ,SAAS,KAAK,MAAM,SAAS;AAC3C,QAAM,QAAQ,SAAS,MAAM,MAAM,SAAS;AAC5C,QAAM,OAAO,SAAS,MAAM,MAAM,QAAQ;AAC1C,aAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,UAAU,QAAQ,GAAG,CAAC,UAAU,IAAI,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,UAAU,IAAI,CAAC,GAAY;AACnI,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAAA,EAChE;AACA,QAAM,WAAW,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,YAAY,eAAe,eAAe,EAAE,SAAS,CAAC,CAAC;AACjG,QAAM,QAAQ,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC;AAC3D,MAAI,MAAM,OAAQ,QAAO,MAAM,oBAAoB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AAC/E,MAAI,KAAK,UAAU,UAAa,CAAC,aAAa,KAAK,KAAK,KAAK,EAAG,QAAO,MAAM,+CAA+C,KAAK,KAAK,KAAK,OAAO,EAAE;AACpJ,OAAK,MAAM,UAAU,UAAa,MAAM,UAAU,UAAa,SAAS,SAAS,UAAU,MAAM,KAAK,UAAU,QAAW;AACzH,WAAO,MAAM,oFAAoF,OAAO,EAAE;AAAA,EAC5G;AAEA,QAAM,OAAO,SAAS,SAAS;AAC/B,QAAM,OAAO,WAAW,GAAG,KAAK,IAAI;AACpC,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,QAAQ,KAAK,UAAU,SAAY,CAAC,OAAO,KAAK,KAAK,CAAC,IAAI,KAAK,MAAM,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC;AAC9F,MAAI,MAAM,KAAK,CAAC,MAAM,IAAI,KAAK,MAAM,MAAM,EAAG,QAAO,MAAM,GAAG,IAAI,QAAQ,KAAK,MAAM,MAAM,QAAQ,KAAK,MAAM,WAAW,IAAI,KAAK,GAAG,yBAAyB,KAAK,KAAK,IAAI,OAAO,EAAE;AAErL,SAAO,UAAU,GAAG,OAAO,OAAO,OAAO,IAAI,OAAO,UAAU;AAC5D,eAAW,KAAK,OAAO;AACrB,YAAM,OAAO;AAAA,QACX;AAAA,QAAO;AAAA,QAAQ;AAAA,QAAU;AAAA,QAAM;AAAA,QAAU,OAAO,CAAC;AAAA,QACjD,GAAI,KAAK,QAAQ,CAAC,UAAU,KAAK,KAAK,IAAI,CAAC;AAAA,QAC3C,GAAI,MAAM,QAAQ,CAAC,WAAW,MAAM,KAAK,IAAI,CAAC;AAAA,QAC9C,GAAI,MAAM,QAAQ,CAAC,WAAW,MAAM,KAAK,IAAI,CAAC;AAAA,QAC9C,GAAG;AAAA,QACH,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC;AAAA,MAC3B;AACA,UAAI,CAAC,QAAQ,MAAM,SAAS,EAAG,IAAG,IAAI,GAAG,OAAO,aAAa,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,EAAG,IAAI,GAAG;AAC7F,YAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM,aAAa;AAE9D,UAAI,SAAS,MAAM,KAAM,QAAO,eAAe,MAAM,OAAO,GAAG,KAAK,EAAE,MAAM,EAAE,CAAC;AAAA,IACjF;AACA,WAAO,MAAM;AAAA,EACf,CAAC;AACH;AAGA,eAAe,cAAc,QAAgB,MAAgB,MAAe,OAAkB,IAA8B;AAC1H,MAAI,CAAC,QAAQ,KAAK,MAAM,EAAG,QAAO,MAAM,0CAA0C,MAAM,KAAK,OAAO,EAAE;AACtG,QAAM,OAAO,SAAS,MAAM,QAAQ;AACpC,QAAM,YAAY,SAAS,KAAK,MAAM,SAAS;AAC/C,QAAM,UAAU,SAAS,UAAU,MAAM,OAAO;AAChD,MAAI,KAAK,WAAW,UAAU,WAAW,QAAQ,QAAS,QAAO,MAAM,+CAA+C,OAAO,EAAE;AAC/H,QAAM,QAAQ,QAAQ;AACtB,MAAI,MAAM,OAAQ,QAAO,MAAM,yBAAyB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AAEpF,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,CAAC,KAAM,QAAO,MAAM,qBAAqB,GAAG,GAAG,sBAAsB,OAAO,gBAAgB,OAAO,EAAE;AACzG,QAAMI,UAAS,WAAW,IAAI;AAC9B,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,WAAO,MAAM;AAAA,EACf;AACA,MAAI,YAAYA,QAAO,GAAG,MAAM,gBAAgB;AAC9C,WAAO,MAAM,IAAI,OAAO,6EAA6E,IAAI,2FAA2F,OAAO,EAAE;AAAA,EAC/M;AACA,QAAM,KAAK,KAAK,SAAS,GAAG,IAAI;AAChC,MAAI,CAAC,GAAI,QAAO,MAAM,wEAAwE,OAAO,EAAE;AACvG,QAAM,aAAcA,QAAO,IAAI,OAAyC;AACxE,QAAM,QAAQ,UAAU,SAAS,cAAc;AAC/C,MAAI,CAAE,OAA6B,SAAS,KAAK,EAAG,QAAO,MAAM,WAAW,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACjI,SAAO,UAAU,IAAI,OAAO,OAAO,OAAO,IAAI,OAAO,UAAU;AAE7D,UAAM,OAAO,oBAAoB,OAAOA,QAAO,GAAG;AAClD,QAAI,KAAM,IAAG,IAAI,GAAG,OAAO,KAAK,IAAI,EAAE;AACtC,UAAM,OAAO;AAAA,MACX;AAAA,MAAc;AAAA,MAAY;AAAA,MAAkB;AAAA,MAAU;AAAA,MAAI;AAAA,MAAQ;AAAA,MAClE;AAAA,MAAS,QAAQ,SAAS;AAAA,MAAc;AAAA,MAAU;AAAA,MAAS;AAAA,MAAW;AAAA,MACtE,GAAG,aAAa,OAAOA,QAAO,GAAG;AAAA,MACjC,GAAI,MAAM,UAAUA,QAAO,KAAK,EAAE;AAAA,MAClC,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC;AAAA,IAC3B;AACA,WAAO,eAAe,MAAM,MAAM,kBAAkB,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,EAAE,IAAI,OAAO,CAAC;AAAA,EACzG,CAAC;AACH;AAGA,eAAe,UAAU,KAAgB,IAAgC;AACvE,QAAM,QAAQ,aAAa,GAAG;AAC9B,MAAI,CAAC,MAAO,QAAO,CAAC;AACpB,MAAI,EAAE,MAAM,UAAU,GAAG,YAAY;AACnC,OAAG,IAAI,GAAG,OAAO,KAAK,uBAAuB,EAAE;AAC/C,WAAO,CAAC;AAAA,EACV;AACA,SAAO,eAAe,KAAK;AAC7B;AAUA,eAAsB,OAAO,MAAgB,MAAe,OAAkB,IAA8B;AAC1G,QAAM,KAAK,SAAS,MAAM,MAAM;AAChC,QAAM,OAAO,SAAS,GAAG,MAAM,QAAQ;AACvC,MAAI,GAAG,WAAW,KAAK,QAAS,QAAO,MAAM,GAAG,GAAG,UAAU,wCAAwC,4BAA4B,IAAI,OAAO,EAAE;AAC9I,QAAM,WAAqB,KAAK,KAAK,OAAO,CAAC,MAAM,MAAM,WAAW;AACpE,QAAM,QAAQ,KAAK,KAAK,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC;AAC3D,MAAI,MAAM,OAAQ,QAAO,MAAM,wBAAwB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACnF,MAAI,KAAK,UAAU,UAAa,CAAC,aAAa,KAAK,KAAK,KAAK,EAAG,QAAO,MAAM,+CAA+C,KAAK,KAAK,KAAK,OAAO,EAAE;AACpJ,QAAM,IAAI,KAAK,UAAU,SAAY,OAAO,KAAK,KAAK,IAAI;AAC1D,QAAM,OAAO;AAAA,IACX;AAAA,IAAO;AAAA,IAAU;AAAA,IAAQ,GAAG,SAAS;AAAA,IACrC,GAAI,MAAM,SAAY,CAAC,UAAU,cAAc,SAAS,QAAQ,OAAO,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC;AAAA,IACtF,GAAG;AAAA,IACH,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC;AAAA,EAC3B;AACA,SAAO,UAAU,GAAG,OAAO,WAAW,OAAO,IAAI,OAAO,UAAU,eAAe,MAAM,MAAM,kBAAkB,MAAM,aAAa,GAAG,OAAO,GAAG,KAAK,MAAM,SAAY,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC,CAAC;AACzL;AAvbA,IA8Ca,aAGA,iBAGA,cAEP,OA0BA,cACA;AAjFN;AAAA;AAAA;AAiCA;AACA;AAEA;AACA;AAEA;AACA;AACA,IAAAC;AACA;AACA;AAGO,IAAM,cAAc;AAGpB,IAAM,kBAAkB,mBAAmB,OAAO;AAGlD,IAAM,eAAe;AAE5B,IAAM,QAAQ;AA0Bd,IAAM,eAAe,CAAC,UAAU,cAAc,WAAW,UAAU,SAAS,SAAS,WAAW,cAAc;AAC9G,IAAM,mBAAmB,CAAC,UAAU,SAAS,YAAY,uBAAuB,UAAU;AAAA;AAAA;;;ACvC1F,SAAS,cAAAC,mBAAkB;AAC3B,SAAS,kCAAkC;AAG3C,SAAS,cAAAC,aAAY,aAAAC,YAAW,aAAa,eAAAC,cAAa,gBAAAC,eAAc,QAAQ,iBAAAC,sBAAqB;AACrG,SAAS,cAAc;AACvB,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAiDvB,SAAS,UAAU,KAA2B;AACnD,UAAQ,IAAI,WAAW,CAAC,GACrB,OAAO,CAAC,MAAO,eAAqC,SAAS,EAAE,MAAM,CAAC,EACtE,IAAI,CAAC,OAAO,EAAE,KAAK,EAAE,SAAS,QAAQ,EAAE,QAAQ,aAAa,EAAE,cAAc,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,EAAE,EAC7G,KAAK,CAAC,GAAG,MAAO,EAAE,MAAM,EAAE,MAAM,KAAK,EAAE,MAAM,EAAE,MAAM,IAAI,CAAE;AAChE;AAGO,SAAS,iBAAiB,MAAmC;AAClE,QAAM,OAAO,KAAK,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAK,EAAE,MAAM,IAAK,EAAE,WAAW,KAAK,GAAG,CAAC,EAAE,EAAE,KAAK,IAAI;AAC1F,SAAOP,YAAW,QAAQ,EAAE,OAAO,IAAI,EAAE,OAAO,KAAK,EAAE,MAAM,GAAG,EAAE;AACpE;AAGA,SAAS,WAAW,KAAuB;AACzC,QAAM,SAAS,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE,KAAK;AAClH,SAAO,MAAM,MAAM,SAAS,CAAC,MAAK,oBAAI,KAAK,GAAE,YAAY;AAC3D;AAoBA,eAAe,SAAS,MAAiB,KAA6C;AACpF,MAAI,cAAe,QAAO,cAAc,MAAM,GAAG;AACjD,QAAM,IAAK,MAAM,OAAO,2BAA2B;AAInD,SAAO,EAAE,YAAY,EAAE,mBAAmB,KAAK,EAAE,KAAK,CAAC,CAAC;AAC1D;AAgBO,SAAS,aAAa,KAAgBQ,SAA6C;AACxF,MAAI,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG,QAAO;AACtC,SAAQ,IAAI,MAAqB,QAAQ,CAAC,GAAG,MAAO,EAAE,KAAK,CAAC,MAAMA,QAAO,SAAS,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,CAAE;AACvG;AAGA,eAAsBC,OAAM,MAAgB,MAAe,OAAkB,IAA8B;AACzG,QAAM,SAAS,SAAS,MAAM,MAAM;AACpC,QAAM,WAAW,SAAS,OAAO,MAAM,YAAY;AACnD,QAAM,UAAU,SAAS,SAAS,MAAM,OAAO;AAC/C,QAAM,YAAY,SAAS,QAAQ,MAAM,SAAS;AAClD,QAAM,cAAc,SAAS,UAAU,MAAM,WAAW;AACxD,QAAM,YAAY,SAAS,YAAY,MAAM,SAAS;AACtD,aAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,QAAQ,MAAM,GAAG,CAAC,cAAc,QAAQ,GAAG,CAAC,SAAS,OAAO,GAAG,CAAC,WAAW,SAAS,GAAG,CAAC,aAAa,WAAW,GAAG,CAAC,WAAW,SAAS,CAAC,GAAY;AAC7K,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAAA,EAChE;AACA,QAAM,UAAU,UAAU,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAC9D,MAAI,QAAQ,OAAQ,QAAO,MAAM,uBAAuB,QAAQ,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACtF,MAAI,UAAU,UAAU,UAAa,CAAE,OAA6B,SAAS,UAAU,KAAK,EAAG,QAAO,MAAM,WAAW,UAAU,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACtL,MAAI,YAAY,UAAU,UAAa,CAAE,gBAAsC,SAAS,YAAY,KAAK,EAAG,QAAO,MAAM,0BAA0B,gBAAgB,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AAE1L,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,CAAC,KAAM,QAAO,MAAM,qBAAqB,GAAG,GAAG,sBAAsB,OAAO,gBAAgB,OAAO,EAAE;AACzG,QAAMC,UAAS,WAAW,IAAI;AAC9B,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,WAAO,MAAM;AAAA,EACf;AACA,QAAM,MAAMA,QAAO;AACnB,QAAM,SAAS,OAAO,KAAK,SAAS,GAAG,CAAC;AACxC,QAAM,QAAQ,CAAC,GAAG,YAAY,UAAU,IAAI,GAAG,GAAI,UAAU,QAAQ,CAAC,UAAU,KAAK,IAAI,CAAC,CAAE;AAC5F,MAAIF;AACJ,MAAI,OAAO,UAAU,QAAW;AAC9B,UAAM,MAAM,OAAO,KAAK,CAAC,MAAM,YAAY,CAAC,MAAM,OAAO,KAAK;AAC9D,QAAI,CAAC,IAAK,QAAO,MAAM,QAAQ,OAAO,KAAK,sBAAsB,IAAI,UAAU,OAAO,sCAAsC,OAAO,EAAE;AACrI,IAAAA,UAAS,CAAC,GAAG;AAAA,EACf,MAAO,CAAAA,UAAS,MAAM,SAAS,QAAQ,cAAc,GAAG;AACxD,MAAIA,QAAO,WAAW,EAAG,QAAO,MAAM,GAAG,IAAI,iEAAiE,OAAO,EAAE;AACvH,QAAM,YAAY,OAAO,SAASA,QAAO,OAAO,CAAC,MAAM,CAAC,OAAO,SAAS,CAAC,CAAC,IAAI,CAAC;AAC/E,MAAI,UAAU,OAAQ,QAAO,MAAM,GAAG,UAAU,KAAK,IAAI,CAAC,IAAI,UAAU,WAAW,IAAI,OAAO,KAAK,wBAAwB,IAAI,IAAI,OAAO,EAAE;AAC5I,MAAI,SAAS,UAAU,UAAaA,QAAO,WAAW,EAAG,QAAO,MAAM,8DAA8D,OAAO,EAAE;AAC7I,QAAM,UAA0B,YAAY,SAAuC,gBAAgB,GAAG;AACtG,QAAM,QAAQ,UAAU;AAExB,SAAO,UAAU,GAAG,OAAO,UAAU,OAAO,IAAI,OAAO,UAAU;AAC/D,UAAM,MAAM,YAAYD,MAAK,OAAO,GAAG,gBAAgB,CAAC;AACxD,UAAM,UAAwB,CAAC;AAC/B,QAAI;AACF,YAAM,YAAY,MAAM,eAAe,KAAK,EAAE;AAC9C,iBAAW,SAASC,QAAQ,SAAQ,KAAK,MAAM,UAAU,OAAO,OAAO,KAAK,EAAE,UAAU,SAAS,OAAO,KAAK,QAAQ,OAAO,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC,EAAG,CAAC,CAAC;AAAA,IACpK,UAAE;AACA,aAAO,KAAK,EAAE,WAAW,MAAM,OAAO,KAAK,CAAC;AAAA,IAC9C;AAEA,QAAI,eAAe;AACnB,QAAI,SAAS,YAAY,QAAQ;AAC/B,UAAI;AACJ,UAAI;AACF,iBAAS,MAAM,SAAS,OAAO,GAAG,GAAG;AAAA,MACvC,SAAS,GAAG;AACV,WAAG,IAAI,GAAG,OAAO,cAAc,KAAK,iCAAkC,EAAY,OAAO,EAAE;AAC3F,uBAAe;AAAA,MACjB;AACA,iBAAW,KAAK,SAAS,QAAQ,OAAO,CAAC,MAAM,EAAE,EAAE,IAAI,CAAC,GAAG;AACzD,YAAI;AACF,YAAE,QAAQ,MAAM,UAAU,QAAS,GAAG,OAAO;AAAA,QAC/C,SAAS,GAAG;AACV,aAAG,IAAI,GAAG,OAAO,WAAW,EAAE,KAAK,aAAc,EAAY,OAAO,EAAE;AACtE,yBAAe;AAAA,QACjB;AAAA,MACF;AAAA,IACF;AACA,QAAI,YAAY,kBAAkB,QAAQ,KAAK,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG;AAEpE,SAAG;AAAA,QACD,cAAc,KAAK,IACf,GAAG,OAAO,8HACV,GAAG,OAAO;AAAA,MAChB;AAAA,IACF;AAGA,UAAM,SAAS,MAAM,YAAY,OAAO,KAAK,SAAS,QAAQ,OAAO,EAAE;AAEvE,UAAM,UAAU,QAAQ,OAAO,CAAC,MAAM,EAAE,UAAU,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK;AACvE,QAAI;AACJ,UAAM,YAAY,YAAY,QAAQ,QAAQ,UAAU,OAAO,UAAU,UAAa,cAAc,GAAG,KAAK,OAAO,KAAK;AACxH,QAAI,UAAW,IAAG,IAAI,GAAG,OAAO,sEAAsE,QAAQ,KAAK,IAAI,CAAC,iDAAiD;AAAA,aAChK,YAAY,QAAQ,QAAQ,QAAQ;AAC3C,YAAM,QAAQ,aAAa,KAAK,OAAO;AACvC,SAAG,IAAI,GAAG,OAAO,yCAAyC,UAAU,QAAQ,eAAe,QAAQ,MAAM,KAAK,IAAI,CAAC,EAAE,QAAQ,QAAQ,KAAK,IAAI,CAAC,yBAAyB;AACxK,UAAI,UAAU,MAAO,UAAS,MAAM,GAAG,CAAC,GAAG,OAAO,OAAO,EAAE;AAAA;AAEzD,mBAAW,KAAK,OAAO;AACrB,mBAAS,MAAM,GAAG,CAAC,UAAU,OAAO,CAAC,CAAC,GAAG,OAAO,OAAO,EAAE;AACzD,cAAI,WAAW,MAAM,KAAM;AAAA,QAC7B;AAAA,IACJ;AAEA,UAAM,SAAS,QAAQ,KAAK,CAAC,MAAM,CAAC,EAAE,EAAE,KAAK;AAC7C,UAAM,OAAO,SAAS,MAAM,SAAS,WAAW,UAAa,WAAW,MAAM,OAAO,SAAS,QAAQ,SAAS,MAAM,QAAQ,MAAM;AACnI,QAAI,MAAM;AACR,SAAG,IAAI,KAAK,UAAU,EAAE,SAAS,SAAS,IAAI,SAAS,MAAM,MAAM,UAAU,MAAM,SAAS,QAAQ,SAAS,GAAI,SAAS,EAAE,QAAQ,OAAO,IAAI,CAAC,EAAG,CAAC,CAAC;AAAA,IACvJ,OAAO;AACL,UAAI,OAAQ,IAAG,IAAI,GAAG,OAAO,WAAW,OAAO,OAAO,qCAAqC,OAAO,WAAW,KAAK,OAAO,MAAM,EAAE;AACjI,iBAAW,KAAK,SAAS;AACvB,YAAI,CAAC,EAAE,GAAI,IAAG,IAAI,GAAG,EAAE,KAAK,4BAA4B,EAAE,KAAK,EAAE;AAAA,iBACxD,EAAE,YAAY,EAAG,IAAG,IAAI,GAAG,EAAE,KAAK,sBAAsB,EAAE,SAAS,EAAE,MAAM,WAAW,WAAW,mBAAmB,EAAE,MAAM,MAAM,KAAK,EAAE,EAAE;AAAA,aAC/I;AACH,aAAG,IAAI,GAAG,EAAE,KAAK,KAAK,EAAE,OAAO,YAAY,EAAE,YAAY,IAAI,KAAK,GAAG,WAAW,EAAE,QAAQ,YAAY,EAAE,MAAM,UAAU,GAAG,IAAI,EAAE,MAAM,MAAM,MAAM,EAAE,EAAE;AACvJ,qBAAW,OAAO,EAAE,KAAM,IAAG,IAAI,KAAK,IAAI,OAAO,OAAO,CAAC,CAAC,IAAI,IAAI,GAAG,GAAG,IAAI,WAAW,SAAS,KAAK,IAAI,WAAW,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;AACvI,qBAAW,QAAQ,EAAE,eAAe,CAAC,EAAG,IAAG,IAAI,KAAK,IAAI,EAAE;AAAA,QAC5D;AAAA,MACF;AAAA,IACF;AACA,WAAO;AAAA,EACT,CAAC;AACH;AAGA,eAAe,YAAY,OAAqB,KAAgB,SAAuB,aAAiC,IAA+C;AACrK,QAAMG,UAAS,cAAc,GAAG;AAChC,QAAMC,UAAS,cAAcD,OAAM,IAAI,MAAM,iBAAiB,IAAI;AAClE,SAAO,gBAAgB;AAAA,IACrB,QAAAA;AAAA,IACA;AAAA,IACA,kBAAkB;AAAA,IAClB,OAAOC,UAAS,EAAE,GAAGA,SAAQ,OAAO,MAAM,mBAAmB,aAAa,EAAE,IAAI;AAAA,IAChF,KAAK,GAAG;AAAA,IACR,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC;AAAA,IACrC,KAAK,GAAG;AAAA,IACR,GAAI,cAAc,EAAE,OAAO,YAAY,IAAI,CAAC;AAAA,EAC9C,CAAC;AACH;AAUA,eAAe,UAAU,OAAqB,OAAe,KAAa,MAAuF;AAC/J,QAAM,OAAOL,MAAK,KAAK,GAAG,YAAY,KAAK,CAAC,OAAO;AACnD,QAAM,OAAO,CAAC,aAAa,SAAS,YAAY,OAAO,GAAI,KAAK,WAAW,CAAC,cAAc,KAAK,QAAQ,IAAI,CAAC,GAAI,GAAI,KAAK,MAAM,CAAC,SAAS,KAAK,GAAG,IAAI,CAAC,GAAI,MAAM,IAAI;AACpK,QAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM,aAAa;AAC9D,MAAI;AACJ,MAAI;AACF,QAAIN,YAAW,IAAI,EAAG,OAAM,KAAK,MAAMG,cAAa,MAAM,MAAM,CAAC;AAAA,EACnE,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,IAAI,OAAO,SAAS,GAAG,MAAM,CAAC,GAAG,OAAO,qDAAsD,EAAY,OAAO,GAAG;AAAA,EACtI;AACA,MAAI,SAAS,KAAK,CAAC,OAAO,IAAI,OAAO;AACnC,WAAO,EAAE,OAAO,IAAI,OAAO,SAAS,GAAG,MAAM,CAAC,GAAG,OAAO,KAAK,QAAQ,GAAG,IAAI,MAAM,IAAI,KAAK,IAAI,MAAM,OAAO,KAAK,gCAAgC,IAAI,GAAG;AAAA,EAC1J;AACA,QAAM,OAAO,UAAU,GAAG;AAC1B,QAAM,cAAc,KAAK,UAAU,KAAK,YAAY,MAAM,eAAe,KAAK,WAAW,OAAO,GAAG,IAAI;AACvG,SAAO,EAAE,OAAO,IAAI,MAAM,SAAS,KAAK,QAAQ,MAAM,YAAY,WAAW,GAAG,GAAG,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC,EAAG;AAC7H;AASA,eAAe,eAAe,KAAgB,IAA6C;AACzF,QAAM,OAAO,gBAAgB,GAAG,EAAE;AAClC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAMS,SAAQ,MAAM,WAAW;AAC/B,MAAI,CAACA,QAAO;AACV,OAAG,IAAI,GAAG,OAAO,WAAW,uBAAuB,EAAE;AACrD,WAAO;AAAA,EACT;AACA,SAAO,EAAE,OAAAA,QAAO,KAAK;AACvB;AAMO,SAAS,YAAY,MAA8B,OAAmC;AAC3F,SAAO,OAAO,QAAQ,IAAI,EAAE,KAAK,CAAC,CAAC,IAAI,MAAM,SAAS,OAAO,SAAS,QAAQ,YAAY,MAAM,KAAK,CAAC,IAAI,CAAC;AAC7G;AAGA,eAAsB,eAAe,GAAc,OAAe,KAA8C;AAC9G,QAAM,OAAO,YAAY,EAAE,MAAM,KAAK;AACtC,MAAI,CAAC,KAAM,QAAO;AAClB,QAAM,UAAU,EAAE,MAAM,qBAAqB,IAAI;AACjD,MAAI,WAAW,QAAS,QAAO,CAAC,mBAAmB,QAAQ,KAAK,EAAE;AAClE,MAAI;AACF,UAAM,aAAa,MAAM,EAAE,MAAM,eAAe,EAAE,SAAS,IAAI,WAAW,CAAC,EAAE,GAAG,EAAE,WAAW,EAAE,KAAK,QAAQ,EAAE,CAAC;AAC/G,WAAO,CAAC,GAAG,EAAE,MAAM,kBAAkB,WAAW,YAAY,EAAE,OAAO,GAAG,WAAW,KAAK;AAAA,EAC1F,SAAS,GAAG;AACV,WAAO,CAAC,mBAAoB,EAAY,OAAO,EAAE;AAAA,EACnD;AACF;AAGO,SAAS,cAAc,KAAa,IAAqB;AAC9D,MAAI;AACF,UAAM,OAAO,KAAK,MAAMT,cAAaG,MAAK,KAAK,eAAe,GAAG,MAAM,CAAC;AACxE,YAAQ,KAAK,OAAO,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,WAAW,MAAS;AAAA,EAC7E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAe,UAAU,QAAoB,GAAe,SAAoF;AAC9I,QAAM,KAAK,EAAE,eAAc,oBAAI,KAAK,GAAE,YAAY;AAClD,QAAM,SAAS,iBAAiB,EAAE,KAAK;AACvC,MAAI,EAAE,YAAY,EAAG,QAAO,OAAO,WAAW,QAAQ,MAAM,EAAE,cAAc,MAAM,cAAc,oBAAoB,EAAE,OAAO,EAAE,EAAE,CAAC;AAClI,QAAM,cAAc,iBAAiB,EAAE,IAAI;AAC3C,QAAM,OAAO,eAAe,EAAE,OAAO,EAAE,OAAO,MAAM,EAAE,MAAM,YAAY,IAAI,aAAa,GAAI,OAAO,SAAS,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC,GAAI,SAAS,GAAI,EAAE,aAAa,SAAS,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC,EAAG,CAAC;AACzN,SAAO,OAAO,WAAW,QAAQ,EAAE,OAAO,gBAAgB,EAAE,KAAK,GAAG,KAAK,GAAG,EAAE,UAAU,YAAY,CAAC;AACvG;AAGO,SAAS,YAAY,KAAgBC,SAA2B,UAA0B;AAC/F,QAAM,SAAS,SAAS,GAAG;AAC3B,QAAMM,SAAQ;AAAA,IACZ,kBAAkB,OAAO;AAAA,IACzB,iEAAiE,OAAO;AAAA,IACxE;AAAA,IACA;AAAA,EACF;AACA,aAAW,SAASN,SAAQ;AAC1B,UAAM,OAAO,YAAY,KAAK;AAC9B,UAAM,cAAc,MAAM,MAAM,MAAM,QAAQ,GAAG,IAAI,CAAC;AACtD,UAAM,MAAM,OAAO,KAAK,GAAG,OAAO;AAClC,UAAME,UAAS,EAAE,MAAM,QAAQ,OAAO,KAAK,OAAO,aAAa,SAAS;AACxE,UAAM,SAAS,OAAO,QAAQA,OAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI;AAC7F,IAAAI,OAAM,KAAK,gBAAgB,KAAK,QAAQ,MAAM,GAAG,CAAC,sBAAsB,MAAM,SAAS;AAAA,EACzF;AACA,SAAOA,OAAM,KAAK,IAAI,IAAI;AAC5B;AAGO,SAAS,YACd,KACA,OACAN,SACA,UACA,OACA,OAAmE,CAAC,GACd;AACtD,QAAM,UAAU,gBAAgB,GAAG;AAEnC,QAAM,WAAW,cAAc,KAAK,KAAK,YAAY;AACrD,QAAM,cAAc,YAAY,SAAS,WAAW,YAAY,kBAAkB,CAAC,WAAY,UAAU,WAAW,kBAAkB,iBAAkB;AACxJ,QAAM,WAAW,gBAAgB,EAAE,IAAI,CAAC,EAAE;AAC1C,QAAMO,UAAS,qBAAqB,EAAE,GAAI,SAAS,QAAQ,EAAE,OAAO,SAAS,MAAM,IAAI,CAAC,GAAI,GAAI,SAAS,cAAc,EAAE,aAAa,SAAS,YAAY,IAAI,CAAC,EAAG,GAAG,KAAK;AAC3K,SAAO;AAAA,IACL,KAAKP,QAAO,IAAI,CAAC,OAAO,EAAE,MAAM,YAAY,CAAC,GAAG,SAAS,EAAE,MAAM,QAAQ,SAAS,GAAG,aAAa,GAAG,cAAc,OAAO,KAAK,YAAY,CAAC,GAAG,OAAO,GAAG,GAAG,oBAAoB,eAAe,OAAO,SAAS,MAAM,CAAC,GAAG,qBAAqB,OAAO,cAAc,GAAG,CAAC,CAAC,GAAG,GAAI,KAAK,QAAQ,iBAAiB,KAAK,OAAO,GAAG,SAAS,KAAK,OAAO,cAAc,EAAE,eAAe,KAAK,kBAAkB,KAAK,CAAC,IAAI,CAAC,EAAG,EAAE;AAAA,IACvZ,SAAS;AAAA,MACP,YAAY,CAAC,GAAG,IAAI,MAAM,KAAK,GAAG,SAAS,QAAQ,UAAU,WAAW,KAAK;AAAA,MAC7E,cAAc,CAAC,iBAAiB,GAAIO,QAAO,gBAAgB,CAAC,CAAE;AAAA,MAC9D,GAAIA,QAAO,QAAQ,EAAE,OAAOA,QAAO,MAAM,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AACF;AAYO,SAAS,iBAAiB,KAAgB,OAAkB,OAAe,SAAwB,KAAa,OAAoC,CAAC,GAA4B;AACtL,QAAM,WAAW,gBAAgB,EAAE,IAAI,CAAC;AACxC,QAAM,OAAO,SAAS,GAAG,UAAU;AACnC,QAAM,MAAM,OAAO,2BAA2B,MAAe,KAAK,OAAO,KAAK,IAAI;AAClF,QAAM,MAA+B,KAAK,OAAO,EAAE,OAAO,IAAI,KAAK,IAAI,CAAC;AACxE,MAAI,YAAY,KAAM,QAAO;AAC7B,QAAM,QAAQ,aAAa,KAAK,CAAC,KAAK,CAAC;AACvC,QAAM,UAAU,UAAU,QAAQ,GAAG,GAAG,QAAQ,MAAM,IAAI,CAAC,MAAM,GAAG,GAAG,cAAc,CAAC,EAAE,EAAE,KAAK,MAAM;AACrG,QAAM,SAAS,eAAe,OAAO,SAAS,SAAS,MAAM,KAAK;AAGlE,QAAM,cAAc,KAAK,iBAAiB,UAAU,WAAW,EAAE,aAAa,EAAE,UAAU,QAAQ,EAAE,IAAI,CAAC;AACzG,MAAI,SAAS,EAAE,SAAS,GAAI,KAAK,QAAQ,EAAE,OAAO,IAAI,MAAM,IAAI,CAAC,GAAI,GAAG,QAAQ,GAAG,YAAY;AAC/F,SAAO;AACT;AAGO,SAAS,eAAe,OAAkBC,OAA+B,OAAwC;AACtH,MAAI,CAACA,MAAM,QAAO,CAAC;AACnB,QAAM,YAAY,aAAa,OAAOA,KAAI;AAC1C,QAAM,cAAc,UAAU,YAAY,SAAY,eAAe,OAAOA,KAAI;AAChF,SAAO,EAAE,GAAI,OAAO,KAAK,SAAS,EAAE,SAAS,EAAE,UAAU,IAAI,CAAC,GAAI,GAAI,cAAc,EAAE,aAAa,EAAE,GAAG,YAAY,EAAE,IAAI,CAAC,EAAG;AAChI;AAQO,SAAS,qBAAqB,OAAkBL,SAA+D;AACpH,MAAI,CAAC,cAAcA,OAAM,KAAK,UAAU,SAAU,QAAO,CAAC;AAC1D,QAAM,QAAQ,CAACA,QAAQ,SAASA,QAAQ,KAAKA,QAAQ,OAAOA,QAAQ,KAAK,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAC3H,SAAO,OAAO,YAAY,MAAM,IAAI,CAAC,MAAM,CAAC,GAAG,gBAAgB,OAAO,CAAC,CAAC,CAAC,CAAC;AAC5E;AAGA,SAAS,oBAAoB,QAAiCA,SAAyD;AACrH,MAAI,OAAO,KAAKA,OAAM,EAAE,WAAW,EAAG,QAAO;AAC7C,SAAO,EAAE,GAAG,QAAQ,WAAW,EAAE,GAAGA,SAAQ,GAAK,OAAO,aAAoD,CAAC,EAAG,EAAE;AACpH;AAMA,SAASM,gBAAe,KAAa,MAAc,MAAuB;AACxE,QAAM,OAAOV,MAAK,KAAK,IAAI;AAC3B,MAAIN,YAAW,IAAI,KAAKG,cAAa,MAAM,MAAM,MAAM,KAAM,QAAO;AACpE,EAAAF,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,EAAAD,eAAc,MAAM,IAAI;AACxB,SAAO;AACT;AAOA,eAAsB,eAAe,OAAqB,OAAkB,KAAgB,OAA0B,OAAkB,IAAa,MAAM,cAA+B;AACxL,QAAM,WAAW,gBAAgB,GAAG;AACpC,MAAI,CAAC,SAAS,SAAU,QAAO,MAAM;AACrC,MAAI,SAAS,OAAO,WAAW,GAAG;AAChC,OAAG,IAAI,GAAG,OAAO,yFAAyF;AAC1G,WAAO,MAAM;AAAA,EACf;AACA,QAAM,OAAO,MAAM,UAAU;AAC7B,MAAIY,gBAAe,GAAG,KAAK,eAAe,YAAY,KAAK,SAAS,QAAQ,SAAS,QAAQ,CAAC,EAAG,IAAG,IAAI,GAAG,OAAO,cAAc,aAAa,+BAA+B;AAC5K,MAAIA,gBAAe,GAAG,KAAK,iBAAiB,KAAK,UAAU,YAAY,KAAK,OAAO,SAAS,QAAQ,SAAS,UAAU,OAAO,EAAE,OAAO,KAAK,kBAAkB,eAAe,KAAK,qBAAqB,IAAI,CAAC,GAAG,MAAM,CAAC,IAAI,IAAI,EAAG,IAAG,IAAI,GAAG,OAAO,cAAc,eAAe,EAAE;AACjR,QAAM,SAASC,eAAc,KAAK;AAClC,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,OAAO,cAAc,OAAO,UAAU,iBAAiB,YAAY,MAAM,GAAG,KAAK;AAC7H,MAAI,SAAS,MAAM,KAAM,QAAO;AAChC,QAAM,MAAMX,MAAK,GAAG,KAAK,MAAM;AAC/B,QAAM,QAAQN,YAAW,GAAG,IACxBE,aAAY,GAAG,EAAE,OAAO,CAAC,MAAM,WAAW,KAAK,CAAC,MAAMC,cAAaG,MAAK,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,SAAS,UAAU,eAAe,EAAE,CAAC,IACvJ,CAAC;AACL,aAAW,KAAK,MAAO,IAAG,IAAI,GAAG,OAAO,qBAAqBA,MAAK,QAAQ,CAAC,EAAE,QAAQ,SAAS,EAAE,CAAC,OAAO,SAAS,QAAQ,EAAE;AAC3H,MAAI,MAAM,UAAU,UAAU,SAAU,IAAG,IAAI,GAAG,OAAO,kHAAkH;AAC3K,SAAO,MAAM;AACf;AAjgBA,IA8Ea,eAEA,iBAEA,eAEA,iBAGA,gBAuCT,eAuKA,aA6CS,yBA2IPW;AA7dN,IAAAC,cAAA;AAAA;AAAA;AA4CA;AACA,IAAAC;AAIA;AACA;AAEA;AACA;AACA,IAAAC;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAcO,IAAM,gBAAgB;AAEtB,IAAM,kBAAkB;AAExB,IAAM,gBAAgB;AAEtB,IAAM,kBAAkB,gCAAgC,aAAa,IAAI,aAAa;AAGtF,IAAM,iBAAiB,CAAC,WAAW,SAAS;AA2P5C,IAAM,0BAA0B;AA2IvC,IAAMH,iBAAqD,EAAE,QAAQ,qBAAqB,SAAS,sBAAsB,QAAQ,IAAI;AAAA;AAAA;;;ACjb9H,SAAS,QAAQ,IAA6B;AACnD,SAAO,KAAK,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE;AACrC;AAGO,SAAS,SAASI,QAAuB,MAAgB;AAC9D,SAAOA,MAAK,QAAQ,CAAC,MAAM,CAAC,GAAG,EAAE,EAAE,IAAI,YAAY,EAAE,KAAK,IAAI,YAAY,EAAE,GAAG,EAAE,CAAC;AACpF;AAnDA,IAea;AAfb;AAAA;AAAA;AAeO,IAAM,OAAuB;AAAA,MAClC;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AAAA,MACA;AAAA,QACE,IAAI;AAAA,QACJ,OAAO;AAAA,QACP,KAAK;AAAA,MACP;AAAA,IACF;AAAA;AAAA;;;AClBA,SAAS,cAAAC,aAAY,aAAAC,YAAW,eAAAC,cAAa,gBAAAC,eAAc,iBAAAC,sBAAqB;AAChF,SAAS,WAAAC,UAAS,QAAAC,aAAY;AAmCvB,SAAS,gBAAgB,KAAwC;AACtE,QAAM,OAAO,EAAE,MAAM,UAAmB,YAAY,CAAC,EAAE;AACvD,QAAM,MAAM,MAAiB;AAC3B,UAAM,OAAO,WAAW,IAAI,GAAG;AAC/B,WAAO,OAAO,WAAW,IAAI,EAAE,MAAM,CAAC;AAAA,EACxC;AACA,SAAO;AAAA,IACL;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS,YAAY;AACnB,cAAM,IAAI,IAAI;AACd,eAAO,EAAE,QAAQ,SAAS,CAAC,GAAG,OAAO,MAAM,QAAQ,EAAE,KAAK,IAAI,EAAE,QAAQ,KAAK;AAAA,MAC/E;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS,YAAY;AACnB,cAAM,IAAI,YAAY,IAAI,GAAG;AAC7B,eAAO,EAAE,IAAI,EAAE,IAAI,GAAG,EAAE,SAAS;AAAA,MACnC;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS,aAAa,EAAE,MAAM,MAAM,MAAM,SAAS,EAAE,KAAK,IAAI,EAAE;AAAA,IAClE;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,aAAa;AAAA,MACb,aAAa;AAAA,MACb,UAAU;AAAA,MACV,SAAS,aAAa,EAAE,OAAO,OAAO,QAAQ,aAAa;AAAA,IAC7D;AAAA,EACF;AACF;AAGO,SAAS,eAAe,WAAoC;AACjE,SAAO;AAAA,IACL,SAAS;AAAA,IACT,OAAO,CAAC,QAAQ,gBAAgB,GAAG;AAAA,IACnC,UAAU;AAAA,IACV,GAAI,YAAY,EAAE,UAAU,IAAI,CAAC;AAAA,IACjC,cAAc,GAAG,OAAO,KAAK,OAAO,qEAAqE,OAAO;AAAA,EAClH;AACF;AAGA,eAAsB,IAAI,MAAgB,OAAgB,OAAkB,IAA8B;AACxG,QAAM,SAAS,SAAS,MAAM,cAAc;AAC5C,MAAI,OAAO,QAAS,QAAO,MAAM,4BAA4B,OAAO,EAAE;AACtE,MAAI,OAAO,KAAK,OAAQ,QAAO,MAAM,qBAAqB,OAAO,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AAC5F,SAAO,UAAU,GAAG,OAAO,QAAQ,OAAO,IAAI,CAAC,UAAU;AAEvD,QAAI,OAAO,MAAM,2BAA2B,UAAU;AACpD,SAAG,IAAI,GAAG,OAAO,+GAA+G,OAAO,IAAI;AAAA,IAC7I;AACA,WAAO,MAAM,kBAAkB,CAAC,SAAS,OAAO,aAAa,GAAG,eAAe,EAAE,KAAK,eAAe,OAAO,KAAK,EAAE,CAAC;AAAA,EACtH,CAAC;AACH;AAmBO,SAAS,aAAa,KAAwB;AACnD,QAAM,IAAI,SAAS,GAAG,KAAK,EAAE,QAAQ,oBAAoB;AACzD,QAAM,OAAgC;AAAA,IACpC,IAAI;AAAA,IACJ,eAAe;AAAA,IACf,MAAM;AAAA,IACN,GAAI,EAAE,eAAe,EAAE,cAAc,EAAE,aAAa,IAAI,CAAC;AAAA,IACzD,GAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,IAC1C,QAAQ,EAAE;AAAA,IACV,GAAI,EAAE,UAAU,EAAE,SAAS,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC5C;AACA,QAAM,SAAS,OAAO,QAAQ,IAAI,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,KAAK,KAAK,UAAU,CAAC,CAAC,EAAE,EAAE,KAAK,IAAI;AAC3F,SAAO;AAAA,IACL,kBAAkB,OAAO;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,UAAU,SAAS,CAAC;AAAA,IACpC;AAAA,IACA;AAAA,IACA,+BAA+B,KAAK,UAAU,mBAAmB,CAAC;AAAA,IAClE,sCAAsC,MAAM;AAAA,IAC5C;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGO,SAAS,aAAa,KAAsE;AACjG,QAAM,WAAW,gBAAgB,EAAE,IAAI,CAAC;AACxC,QAAM,IAAI,SAAS;AACnB,QAAMC,UAAS,qBAAqB,EAAE,GAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC,GAAI,GAAI,EAAE,cAAc,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC,EAAG,GAAG,KAAK;AAC/I,SAAO;AAAA,IACL,KAAK;AAAA,MACH;AAAA,QACE,MAAM;AAAA,QACN,SAAS,EAAE,MAAM,eAAe;AAAA,QAChC,aAAa;AAAA;AAAA,QAEb,GAAI,SAAS,GAAG,WAAW,EAAE,aAAa,EAAE,YAAY,QAAQ,EAAE,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AAAA,IACA,SAAS;AAAA,MACP,GAAIA,QAAO,eAAe,EAAE,cAAcA,QAAO,aAAa,IAAI,CAAC;AAAA,MACnE,GAAIA,QAAO,QAAQ,EAAE,OAAOA,QAAO,MAAM,IAAI,CAAC;AAAA,IAChD;AAAA,EACF;AACF;AAIA,SAASC,gBAAe,KAAa,MAAc,MAAuB;AACxE,QAAM,OAAOF,MAAK,KAAK,IAAI;AAC3B,MAAIN,YAAW,IAAI,KAAKG,cAAa,MAAM,MAAM,MAAM,KAAM,QAAO;AACpE,EAAAF,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,EAAAD,eAAc,MAAM,IAAI;AACxB,SAAO;AACT;AAGA,eAAsB,gBAAgB,OAAqB,OAAkB,KAAgB,OAA0B,OAAkB,IAA8B;AACrK,MAAI,CAAC,SAAS,GAAG,EAAG,QAAO,MAAM;AACjC,MAAII,gBAAe,GAAG,KAAK,gBAAgB,aAAa,GAAG,CAAC,EAAG,IAAG,IAAI,GAAG,OAAO,cAAc,cAAc,+BAA+B;AAC3I,MAAIA,gBAAe,GAAG,KAAK,kBAAkB,KAAK,UAAU,aAAa,GAAG,GAAG,MAAM,CAAC,IAAI,IAAI,EAAG,IAAG,IAAI,GAAG,OAAO,cAAc,gBAAgB,EAAE;AAClJ,QAAM,SAASC,eAAc,KAAK;AAClC,QAAM,OAAO,MAAM,MAAM,kBAAkB,CAAC,OAAO,cAAc,OAAO,UAAU,kBAAkB,YAAY,MAAM,GAAG,KAAK;AAC9H,MAAI,SAAS,MAAM,KAAM,QAAO;AAChC,QAAM,MAAMH,MAAK,GAAG,KAAK,MAAM;AAC/B,QAAM,QAAQN,YAAW,GAAG,IACxBE,aAAY,GAAG,EAAE,OAAO,CAAC,MAAM,WAAW,KAAK,CAAC,MAAMC,cAAaG,MAAK,KAAK,CAAC,GAAG,MAAM,EAAE,MAAM,MAAM,CAAC,EAAE,CAAC,KAAK,IAAI,SAAS,UAAU,gBAAgB,EAAE,CAAC,IACxJ,CAAC;AACL,aAAW,KAAK,MAAO,IAAG,IAAI,GAAG,OAAO,uBAAuBA,MAAK,QAAQ,CAAC,EAAE,QAAQ,SAAS,EAAE,CAAC,EAAE;AACrG,QAAM,IAAI,SAAS,GAAG;AACtB,KAAG,IAAI,GAAG,OAAO,kDAAkD,EAAE,MAAM,wBAAwB;AACnG,MAAI,UAAU,SAAU,IAAG,IAAI,GAAG,OAAO,yJAAyJ;AAClM,SAAO,MAAM;AACf;AA/NA,IAwDa,cAyEA,WACA,gBACA,kBAEA,mBAOA,qBAwDPG;AApMN,IAAAC,eAAA;AAAA;AAAA;AAyBA;AAEA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AAqBO,IAAM,eAAe,CAAC,MAAM,WAAW,UAAU;AAyEjD,IAAM,YAAY;AAClB,IAAM,iBAAiB;AACvB,IAAM,mBAAmB;AAEzB,IAAM,oBAAoB;AAO1B,IAAM,sBACX,GAAG,GAAG,iNAC6G,OAAO;AAsD5H,IAAMD,iBAAqD,EAAE,QAAQ,qBAAqB,SAAS,sBAAsB,QAAQ,IAAI;AAAA;AAAA;;;AC9KrI,SAAS,gBAAAE,qBAAoB;AA2CtB,SAAS,cAAc,SAA4B,YAAY,QAAgB;AACpF,QAAM,MAAM,QAAQ,SAAS,IAAI,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,MAAM;AAC5G,SAAO,OAAO,6BAA6B,EAAE,QAAQ,iBAAiB,SAAS,EAAE,QAAQ,eAAe,GAAG;AAC7G;AAGO,SAAS,qBAA6C;AAC3D,SAAO,OAAO,YAAY,CAAC,YAAY,qBAAqB,cAAc,EAAE,IAAI,CAAC,MAAM,CAAC,GAAG,OAAO,qBAAqB,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/H;AAGO,SAAS,oBAAoB,SAAoC;AACtE,SAAO,KAAK,UAAU,EAAE,CAAC,gBAAgB,GAAG,EAAE,SAAS,CAAC,GAAG,IAAI,IAAI,OAAO,CAAC,EAAE,KAAK,EAAE,EAAE,GAAG,MAAM,CAAC,IAAI;AACtG;AA9EA,IA4Ba,oBACA,uBAEA,qBAEA,kBA6BP;AA9DN;AAAA;AAAA;AA4BO,IAAM,qBAAqB;AAC3B,IAAM,wBAAwB;AAE9B,IAAM,sBAAsB;AAE5B,IAAM,mBAAmB;AA6BhC,IAAM,SAAS,CAAC,QAAwBA,cAAa,IAAI,IAAI,qBAAqB,GAAG,IAAI,YAAY,GAAG,GAAG,MAAM;AAAA;AAAA;;;AChB1G,SAAS,UACd,SACA,SACA,KACc;AACd,MAAI,QAAQ,MAAO,QAAO,EAAE,KAAK,QAAQ,OAAO,QAAQ,cAAc;AACtE,MAAI,QAAQ,IAAK,QAAO,EAAE,KAAK,QAAQ,KAAK,QAAQ,cAAc;AAClE,QAAM,UAAU,IAAI,oBAAoB,KAAK;AAC7C,MAAI,QAAS,QAAO,EAAE,KAAK,SAAS,QAAQ,qBAAqB;AACjE,MAAI,QAAQ,WAAY,QAAO,EAAE,KAAK,QAAQ,YAAY,QAAQ,cAAc;AAChF,SAAO,EAAE,QAAQ,OAAO;AAC1B;AAGO,SAAS,cAAc,KAAkC;AAC9D,SAAO,QAAQ,UAAa,eAAe,KAAK,GAAG;AACrD;AAGO,SAAS,SAAS,KAAqB;AAC5C,SAAO,IAAI,QAAQ,eAAe,EAAE;AACtC;AAGA,SAAS,YAAY,QAAwB;AAC3C,QAAM,IAAI,OAAO,QAAQ,cAAc,EAAE;AACzC,SAAO,MAAM,KAAK,YAAY,GAAG,CAAC;AACpC;AAOO,SAAS,aAAa,KAAa,KAAkD;AAC1F,QAAM,QAAQ,SAAS,GAAG;AAC1B,MAAI;AACJ,MAAI;AACF,QAAI,IAAI,IAAI,KAAK;AAAA,EACnB,QAAQ;AACN,WAAO;AAAA,EACT;AACA,QAAM,QAAQ;AACd,MAAI,EAAE,aAAa,OAAO;AACxB,UAAM,IAAI,EAAE;AACZ,UAAM,SAAS,EAAE,IAAI,QAAQ,KAAK,IAAI,cAAc,IAAI,sBAAsB;AAC9E,UAAM,cAAc,EAAE,IAAI,UAAU,KAAK,IAAI,uBAAuB,IAAI;AACxE,UAAM,SAAkC,EAAE,OAAO,MAAM,QAAQ,EAAE,UAAU,OAAO;AAClF,QAAI,aAAa;AACf,YAAM,WAAW,eAAe,KAAK,WAAW,IAAI,cAAc,GAAG,EAAE,IAAI,YAAY,MAAM,SAAS,SAAS,OAAO,MAAM,WAAW;AACvI,UAAI,CAAC,IAAI,qBAAqB,CAAC,IAAI,uBAAuB;AACxD,eAAO,EAAE,IAAI,OAAO,OAAO,QAAQ,oBAAoB,QAAQ,yFAAyF;AAAA,MAC1J;AACA,aAAO,WAAW;AAClB,aAAO,cAAc;AAAA,QACnB,aAAa,IAAI;AAAA,QACjB,iBAAiB,IAAI;AAAA,QACrB,GAAI,IAAI,oBAAoB,EAAE,cAAc,IAAI,kBAAkB,IAAI,CAAC;AAAA,MACzE;AAAA,IACF;AACA,WAAO,EAAE,IAAI,MAAM,QAAQ,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,MAAM;AAAA,EAC1E;AACA,MAAI,EAAE,aAAa,OAAO;AACxB,UAAM,SAAkC,EAAE,OAAO,OAAO,QAAQ,EAAE,SAAS;AAC3E,UAAM,WAAW,IAAI;AACrB,QAAI,UAAU;AACZ,aAAO,WAAW,eAAe,KAAK,QAAQ,IAAI,WAAW,UAAU,QAAQ;AAC/E,aAAO,QAAQ,IAAI,6BAA6B;AAAA,IAClD;AACA,WAAO,EAAE,IAAI,MAAM,QAAQ,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,MAAM;AAAA,EAC1E;AACA,MAAI,EAAE,aAAa,WAAW;AAC5B,UAAM,UAAU,EAAE,aAAa,IAAI,iBAAiB,KAAK,IAAI;AAC7D,UAAM,iBAAiB,IAAI;AAC3B,UAAM,gBAAgB,IAAI;AAC1B,QAAI,CAAC,WAAW,CAAC,kBAAkB,CAAC,eAAe;AACjD,aAAO,EAAE,IAAI,OAAO,OAAO,QAAQ,gKAAgK;AAAA,IACrM;AACA,UAAM,SAAkC,EAAE,OAAO,UAAU,gBAAgB,eAAe,SAAS,WAAW,EAAE,SAAS;AACzH,QAAI,IAAI,oBAAoB;AAC1B,UAAI,CAAC,IAAI,gBAAiB,QAAO,EAAE,IAAI,OAAO,OAAO,QAAQ,qBAAqB,IAAI,kBAAkB,0CAA0C;AAClJ,aAAO,WAAW,IAAI;AACtB,aAAO,QAAQ,IAAI;AAAA,IACrB;AACA,WAAO,EAAE,IAAI,MAAM,QAAQ,YAAY,CAAC,YAAY,EAAE,QAAQ,CAAC,GAAG,MAAM;AAAA,EAC1E;AACA,SAAO;AACT;AAGO,SAAS,wBAAwB,YAA4B;AAClE,SACE,2JACqC,UAAU;AAEnD;AAKO,SAAS,mBAA0D;AACxE,EAAAC,aAAY,YAAY;AACtB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,+BAA+B;AAC/E,aAAO,OAAO,EAAE,gBAAgB,aAAc,IAAoC;AAAA,IACpF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AAQO,SAAS,YAAY,QAAgC;AAC1D,QAAM,QAAQ,GAAG,OAAO,UAAU,WAAW,cAAc,QAAQ,IAAI,OAAO,MAAM;AACpF,MAAI,OAAO,QAAS,QAAO,CAAC,KAAK,KAAK,oFAAoF;AAC1H,QAAM,MAAM,CAAC,KAAK,KAAK,4FAA4F;AACnH,aAAW,KAAK,OAAO,UAAU;AAC/B,QAAI,EAAE,YAAY,KAAM;AACxB,QAAI,KAAK,OAAO,EAAE,OAAO,KAAK,EAAE,KAAK,GAAG,EAAE,YAAY,eAAe,yBAAyB,EAAE,EAAE;AAClG,QAAI,EAAE,IAAK,KAAI,KAAK,GAAG,EAAE,IAAI,MAAM,IAAI,EAAE,IAAI,CAAC,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,EACnE;AACA,SAAO;AACT;AA/KA,IA+IIA;AA/IJ;AAAA;AAAA;AAAA;AAAA;;;AC+DO,SAAS,aAA8C;AAC5D,EAAAC,aAAY,YAAY;AACtB,QAAI;AAEF,YAAM,MAA+B,MAAM,OAAO,qCAAqC;AAEvF,YAAM,UAAmC,MAAM,OAAO,iCAAiC;AACvF,YAAM,OAAO,IAAI;AACjB,YAAM,UAAU,IAAI;AACpB,YAAM,SAAS,IAAI;AACnB,YAAM,QAAQ,QAAQ;AACtB,YAAM,UAAU,IAAI;AACpB,UAAI,OAAO,SAAS,cAAc,OAAO,YAAY,cAAc,OAAO,WAAW,cAAc,OAAO,UAAU,WAAY,QAAO;AACvI,aAAO;AAAA,QACL,OAAO,OAAO,QAAQ,kBAAkB;AAAA,QACxC,MAAM,QAAQ,EAAE,KAAK,OAAO,QAAQ,GAAG;AACrC,cAAI;AACF,kBAAM,EAAE,OAAO,IAAI,MAAM,QAAQ,QAAQ,KAAK,EAAE,MAAM,CAAC,GAAG,KAAK,EAAE,oBAAoB,QAAQ,CAAC;AAC9F,kBAAM,OAAO,MAAM,MAAM;AACzB,gBAAI,CAAC,KAAM,OAAM,IAAI,MAAM,kCAAkC;AAC7D,mBAAO;AAAA,UACT,SAAS,KAAK;AACZ,kBAAM,IAAI,UAAU,QAAQ,GAAG,IAAI,EAAE,SAAU,IAAc,QAAQ;AACrE,kBAAM,OAAO,MAAM,EAAE,MAAM;AAC3B,gBAAI,KAAM,QAAO;AACjB,gBAAI,EAAE,cAAe,OAAM,IAAI,MAAM,yCAAyC;AAC9E,kBAAM,IAAI,OAAO,EAAE,QAAQ,KAAK,KAAK,EAAE,SAAS,MAAM,IAAI,EAAE,MAAM,EAAE,EAAE,KAAK,IAAI,CAAC;AAAA,UAClF;AAAA,QACF;AAAA,MACF;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AAQO,SAAS,aAAa,GAAuC,SAAyB;AAC3F,QAAM,KAAK,EAAE,QAAQ,MAAM,KAAK,MAAM,EAAE,GAAG;AAC3C,SAAO,GAAG,EAAE,uBAAuB,OAAO,uCAAuC,EAAE,KAAK;AAC1F;AAOA,eAAsB,cACpBC,SACA,OACA,MACyB;AACzB,QAAM,MAAsB,CAAC;AAC7B,aAAW,KAAKA,SAAQ;AACtB,UAAM,UAAU,aAAa,GAAG,EAAE,GAAG;AACrC,QAAI,CAAC,OAAO;AACV,UAAI,KAAK,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,OAAO,UAAU,CAAC;AAClE;AAAA,IACF;AACA,QAAI;AACF,YAAM,OAAO,MAAM,MAAM,QAAQ,EAAE,KAAK,EAAE,QAAQ,MAAM,OAAO,GAAG,IAAI,IAAI,EAAE,GAAG,IAAI,OAAO,EAAE,OAAO,SAAS,EAAE,IAAI,CAAC;AACnH,UAAI,KAAK,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,KAAK,CAAC;AAAA,IACxD,SAAS,GAAG;AACV,UAAI,KAAK,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,KAAK,SAAS,OAAQ,EAAY,QAAQ,CAAC;AAAA,IAC/E;AAAA,EACF;AACA,SAAO;AACT;AAGA,SAAS,MAAM,MAAyB;AACtC,QAAM,IAA4B,CAAC;AACnC,aAAW,KAAK,KAAK,UAAW,GAAE,EAAE,IAAI,KAAK,EAAE,EAAE,IAAI,KAAK,KAAK;AAC/D,SAAO,OAAO,QAAQ,CAAC,EACpB,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,MAAO,IAAI,IAAI,KAAK,IAAI,IAAI,IAAI,CAAE,EAC/C,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,EAC3B,KAAK,IAAI;AACd;AAGO,SAAS,WAAW,UAAmC,OAAyC;AACrG,MAAI,SAAS,WAAW,EAAG,QAAO,CAAC;AACnC,MAAI,CAAC,MAAO,QAAO,CAAC,qBAAqB,GAAG,SAAS,IAAI,CAAC,MAAM,KAAK,EAAE,GAAG,KAAK,EAAE,OAAO,EAAE,CAAC;AAC3F,QAAM,MAAM,CAAC,mEAAmE;AAChF,aAAW,KAAK,UAAU;AACxB,UAAM,IAAI,EAAE;AACZ,QAAI,CAAC,GAAG;AACN,UAAI,KAAK,KAAK,EAAE,GAAG,oBAAoB,EAAE,KAAK,qBAAqB,EAAE,OAAO,EAAE;AAC9E;AAAA,IACF;AACA,UAAM,QAAQ,GAAG,EAAE,UAAU,MAAM,YAAY,EAAE,UAAU,WAAW,IAAI,KAAK,GAAG;AAClF,QAAI,EAAE,WAAW,WAAW;AAC1B,UAAI,KAAK,KAAK,EAAE,GAAG,+BAA+B;AAClD,iBAAW,KAAK,EAAE,SAAU,KAAI,KAAK,OAAO,EAAE,IAAI,KAAK,EAAE,MAAM,GAAG,EAAE,MAAM,KAAK,EAAE,GAAG,MAAM,EAAE,EAAE;AAAA,IAChG,WAAW,EAAE,WAAW,mBAAmB;AACzC,UAAI,KAAK,KAAK,EAAE,GAAG,kCAAkC,KAAK,GAAG;AAAA,IAC/D,WAAW,EAAE,WAAW,WAAW;AACjC,UAAI,KAAK,KAAK,EAAE,GAAG,cAAc,KAAK,GAAG;AAAA,IAC3C,OAAO;AACL,UAAI,KAAK,KAAK,EAAE,GAAG,iBAAiB,KAAK,GAAG,EAAE,UAAU,SAAS,KAAK,MAAM,CAAC,CAAC,MAAM,EAAE,EAAE;AAAA,IAC1F;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,cAAyCA,SAAsB,UAAwC;AACrH,SAAOA,QAAO,OAAO,CAAC,MAAM,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,GAAG,GAAG,MAAM,WAAW,iBAAiB;AACvG;AAGO,SAAS,UAAU,QAAgB,OAAe,QAAyB;AAChF,SAAO,SAAS,WAAW,QAAQ,KAAK,WAAW,QAAQ,IAAI,MAAM,IAAI,KAAK;AAChF;AAGO,SAAS,YAAYA,SAA4F;AACtH,QAAM,OAAOA,QAAO;AAAA,IAClB,CAAC,MAAM,iBAAiB,KAAK,UAAU,EAAE,MAAM,CAAC,UAAU,KAAK,UAAU,EAAE,GAAG,CAAC,YAAY,KAAK,UAAU,EAAE,KAAK,CAAC,cAAc,KAAK,UAAU,EAAE,GAAG,CAAC;AAAA,EACvJ;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,sBAAsB,QAAQ;AAAA,IAC9B,0BAA0B,QAAQ;AAAA,IAClC,sBAAsB,QAAQ;AAAA,IAC9B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,WAAW,KAAK,UAAU,QAAQ,CAAC;AAAA,IACnC;AAAA,IACA,GAAG;AAAA,IACH;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGO,SAAS,UAAUA,SAAoE;AAC5F,QAAM,SAASA,QAAO,WAAW;AACjC,QAAM,QAAQA,QAAO,IAAI,CAAC,MAAM,UAAU,KAAK,EAAE,MAAM,GAAG,KAAK,EAAE,KAAK,GAAG,MAAM,CAAC;AAChF,SAAO;AAAA,IACL,gFAAgF,QAAQ,4BAA4B,QAAQ,uBAAuB,MAAM,KAAK,IAAI,CAAC,kDAAkD,QAAQ;AAAA,EAC/N;AACF;AA7NA,IA2Ba,UACA,eAgCTD,SAoDS;AAhHb;AAAA;AAAA;AAwBA;AAGO,IAAM,WAAW;AACjB,IAAM,gBAAgB;AAoFtB,IAAM,sBACX;AAAA;AAAA;;;AC3CK,SAAS,YAAY,KAAgE;AAC1F,MAAI,QAAQ,UAAa,WAAW,KAAK,GAAG,EAAG,QAAO,EAAE,IAAI;AAC5D,MAAI,cAAc,GAAG,GAAG;AACtB,WAAO;AAAA,MACL,SACE,qBAAqB,MAAM,KAAK,GAAG,MAAM,EAAE,6HACa,kBAAkB;AAAA,IAC9E;AAAA,EACF;AACA,MAAI,aAAa,KAAK,GAAI,EAAG,QAAO,EAAE,KAAK,UAAU,GAAG,GAAG;AAC3D,QAAM,SAAS,IAAK,MAAM,KAAK,EAAE,CAAC;AAClC,SAAO,EAAE,SAAS,SAAS,GAAG,wCAAwC,MAAM,wDAAwD,kBAAkB,GAAG;AAC3J;AAGO,SAAS,aAAaE,WAAoB,KAAuC;AACtF,SAAOA,UAAS,OAAO,IAAI,CAAC,MAAM;AAChC,UAAM,UAAUA,UAAS,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,EAAE,YAAY,OAAU;AAClH,UAAM,IAAI,UAAU,SAAS,CAAC,GAAG,GAAG;AACpC,UAAM,KAAK,YAAY,EAAE,GAAG;AAC5B,WAAO;AAAA,MACL,KAAK,EAAE;AAAA,MACP,SAAS,EAAE;AAAA,MACX,OAAO,EAAE;AAAA,MACT,KAAK,EAAE;AAAA,MACP,GAAI,EAAE,QAAQ,SAAY,EAAE,SAAS,EAAE,IAAI,IAAI,CAAC;AAAA,MAChD,QAAQ,EAAE;AAAA,MACV,GAAI,SAAS,KAAK,EAAE,KAAK,GAAG,IAAI,IAAI,EAAE,SAAS,GAAG,QAAQ;AAAA,IAC5D;AAAA,EACF,CAAC;AACH;AAGO,SAAS,WAAWC,SAA2C;AACpE,QAAM,SAASA,QAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,MAAS;AACvD,MAAI,OAAO,WAAW,EAAG,QAAO,CAAC;AACjC,QAAM,MAAM,OAAO,WAAWA,QAAO;AACrC,QAAM,OAAO,IAAI,IAAI,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAC7C,MAAI,OAAO,KAAK,SAAS,EAAG,QAAO,EAAE,QAAQ,UAAU,SAAS,OAAO,CAAC,EAAG,IAAI;AAC/E,QAAM,MAAiC,CAAC;AACxC,aAAW,KAAK,OAAQ,KAAI,EAAE,GAAG,IAAI,EAAE,GAAI,EAAE,QAAQ,MAAM,EAAE,KAAK,EAAE,IAAI,IAAI,CAAC,GAAI,SAAS,EAAE,IAAI;AAChG,SAAO,EAAE,GAAI,MAAM,EAAE,QAAQ,SAAS,IAAI,CAAC,GAAI,QAAQ,IAAI;AAC7D;AAGO,SAAS,YAAYA,SAA0C;AACpE,MAAIA,QAAO,WAAW,EAAG,QAAO,CAAC,sEAAsE;AACvG,QAAM,MAAM,CAAC,uHAAuH;AACpI,aAAW,KAAKA,SAAQ;AACtB,QAAI,EAAE,IAAK,KAAI,KAAK,KAAK,EAAE,GAAG,KAAK,EAAE,GAAG,GAAG,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,sBAAsB,EAAE,OAAO,KAAK,EAAE,MAAM,MAAM,EAAE,EAAE;AAAA,QAC/H,KAAI,KAAK,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAAA,EACzC;AACA,MAAIA,QAAO,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,EAAG,KAAI,KAAK,8FAA8F;AAAA,WAC/HA,QAAO,KAAK,CAAC,MAAM,CAAC,EAAE,GAAG,EAAG,KAAI,KAAK,yEAAyE;AACvH,SAAO;AACT;AAGO,SAAS,WAAW,OAAoC;AAC7D,MAAI,MAAM,WAAW,OAAW,QAAO,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,EAAE;AAC7D,MAAI,MAAM,WAAW,SAAU,QAAO,EAAE,MAAM,EAAE,QAAQ,SAAS,GAAG,OAAO,CAAC,EAAE;AAC9E,QAAMA,UAAS,aAAa,MAAM,UAAU,MAAM,GAAG;AACrD,SAAO,EAAE,MAAM,WAAWA,OAAM,GAAG,OAAO,YAAYA,OAAM,GAAG,QAAQA,QAAO;AAChF;AArIA,IA6Ba,cAIA,oBAGP;AApCN,IAAAC,eAAA;AAAA;AAAA;AAyBA;AACA;AAGO,IAAM,eAAe,CAAC,UAAU,QAAQ;AAIxC,IAAM,qBAAqB;AAGlC,IAAM,eAAe;AAAA;AAAA;;;ACMd,SAAS,aAAa,MAAkC;AAC7D,SAAO,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC5C;AAGO,SAAS,SAAS,GAA8D;AACrF,MAAI,MAAM,UAAW,QAAO;AAC5B,SAAO,MAAM,YAAY,MAAM,oBAAoB,MAAM,UAAU,IAAI;AACzE;AAGO,SAAS,gBAAqD;AACnE,SAAO,EAAE,MAAM,cAAc,SAAS,CAAC,cAAc,OAAO,eAAe,wBAAwB,EAAE;AACvG;AAvDA,IAoBa,cAEA,gBAEA;AAxBb;AAAA;AAAA;AAoBO,IAAM,eAAe,CAAC,SAAS,gBAAgB,aAAa;AAE5D,IAAM,iBAA6B;AAEnC,IAAM,UAA6B;AAAA,MACxC;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,CAAC;AAAA,MACT;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,EAAE;AAAA,MAC1C;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,SAAS;AAAA,QACT,MAAM,EAAE,MAAM,SAAS;AAAA,MACzB;AAAA,IACF;AAAA;AAAA;;;AC9BA,SAAS,gBAAAC,sBAAoB;AAKtB,SAAS,SAAS,MAA4B;AACnD,SAAOA,eAAa,IAAI,IAAI,gBAAgB,IAAI,IAAI,YAAY,GAAG,GAAG,MAAM;AAC9E;AAGO,SAAS,KAAK,MAAc,QAAwC;AACzE,SAAO,KAAK,QAAQ,kBAAkB,CAAC,KAAK,QAAiB,OAAO,SAAS,OAAO,GAAG,IAAK,GAAI;AAClG;AAtBA;AAAA;AAAA;AAAA;AAAA;;;ACgBA,SAAS,qBAAqB;AA2BvB,SAAS,WAAW,MAAyB;AAClD,QAAM,OAAO,OAAO,QAAQ,IAAI,EAC7B,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,cAAc,GAAG,CAAC,CAAC,EACnC,KAAK,IAAI;AACZ,QAAM,OAAO,KAAK,SAAS,aAAa,GAAG,EAAE,MAAM,KAAK,CAAC;AACzD,SAAO,KAAK,SAAS,IAAI,IAAI,OAAO,OAAO;AAC7C;AAGO,SAAS,gBAAwB;AACtC,SAAO,SAAS,sBAAsB;AACxC;AAGO,SAAS,cAAc,OAAuC;AACnE,SAAO,KAAK,MAAM,GAAG;AACvB;AAGA,SAAS,WAAW,OAA+B,OAA4B;AAC7E,MAAI,OAAO,MAAM,IAAI,QAAQ,kBAAkB,GAAG,EAAE,QAAQ,YAAY,EAAE;AAC1E,MAAI,SAAS,MAAM,MAAM,KAAK,IAAI,EAAG,QAAO,SAAS,IAAI;AACzD,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,MAAM,IAAI,IAAI,GAAG,IAAK,QAAO,GAAG,IAAI,IAAI,CAAC;AACzD,QAAM,IAAI,IAAI;AACd,SAAO;AACT;AAGO,SAAS,UAAU,GAAuC;AAC/D,SAAO;AAAA,IACL,KAAK,EAAE;AAAA,IACP,OAAO,EAAE;AAAA,IACT,QAAQ,EAAE;AAAA,IACV,GAAI,EAAE,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC;AAAA,IACvC,GAAI,EAAE,gBAAgB,EAAE,eAAe,EAAE,eAAe,GAAI,EAAE,aAAa,EAAE,YAAY,EAAE,WAAW,IAAI,CAAC,EAAG,IAAI,CAAC;AAAA,IACnH,GAAI,EAAE,YAAY,EAAE,WAAW,EAAE,UAAU,IAAI,CAAC;AAAA,IAChD,GAAI,EAAE,aAAa,SAAS,EAAE,aAAa,EAAE,YAAY,IAAI,CAAC;AAAA,EAChE;AACF;AAOO,SAAS,eAAeC,SAA8B,QAAqD,CAAC,GAAG,OAAkC,CAAC,GAAW;AAClK,QAAM,QAAQ,oBAAI,IAAY;AAC9B,QAAMC,SAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AACA,aAAW,KAAKD,SAAQ;AAEtB,UAAM,aAAa,MAAM,EAAE,GAAG,KAAK,CAAC,GAAG,OAAO,CAAC,MAAMA,QAAO,KAAK,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,EAAE,IAAI,CAAC,MAAM,cAAc,EAAE,KAAK,EAAE,CAAC,CAAC;AAE1H,UAAM,OAAO,EAAE,MAAM,aAAa,GAAG,UAAU,CAAC,GAAG,GAAI,KAAK,eAAe,EAAE,cAAc,KAAK,aAAa,IAAI,CAAC,EAAG;AACrH,UAAM,YAAY,EAAE,MAAM,cAAc,CAAC,GAAG,WAAW,QAAQ,CAAC,EAAE,OAAO,MAAM,OAAO,CAAC,IAAI,EAAE,CAAC,EAAE;AAChG,IAAAC,OAAM,KAAK,gBAAgB,WAAW,GAAG,KAAK,CAAC,MAAM,KAAK,UAAU,SAAS,CAAC,GAAG;AAAA,EACnF;AACA,SAAOA,OAAM,KAAK,IAAI,IAAI;AAC5B;AAMO,SAAS,QAAQD,SAA8B,YAAuE;AAC3H,QAAM,QAAQ,IAAI,IAAIA,QAAO,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC;AACnD,MAAI,cAAc,WAAW,SAAS,GAAG;AACvC,WAAO,WAAW,IAAI,CAAC,MAAM,OAAO,EAAE,MAAM,QAAQ,IAAI,CAAC,IAAI,QAAQ,KAAK,IAAI,CAAC,MAAM,MAAM,IAAI,CAAC,CAAC,EAAE,OAAO,CAAC,MAAsB,MAAM,MAAS,EAAE,EAAE;AAAA,EACtJ;AACA,QAAM,MAAoD,CAAC;AAC3D,aAAW,KAAKA,SAAQ;AACtB,UAAM,MAAM,cAAc,EAAE,KAAK;AACjC,QAAI,OAAO,KAAK,GAAG;AACnB,QAAI,CAAC,UAAU,KAAK,IAAI,EAAG,QAAO,QAAQ,IAAI,SAAS,CAAC;AACxD,UAAM,OAAO,IAAI,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC5C,QAAI,KAAM,MAAK,OAAO,KAAK,CAAC;AAAA,QACvB,KAAI,KAAK,EAAE,MAAM,QAAQ,CAAC,CAAC,EAAE,CAAC;AAAA,EACrC;AACA,SAAO;AACT;AAGO,SAAS,WAAW,QAA8D;AACvF,MAAI,WAAW,OAAW,QAAO;AACjC,MAAI,OAAO,WAAW,YAAY,MAAM,QAAQ,MAAM,KAAK,WAAW,OAAQ,QAAO;AACrF,QAAM,SAAS;AACf,SAAO,OAAO,MAAM,OAAO;AAC7B;AAqBO,SAAS,UAAU,OAAgD;AACxE,QAAM,SAAS,MAAM,WAAW,QAAQ,MAAM,QAAQ,MAAM,KAAK,GAAG,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC;AACrG,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,MAAM;AAAA,IACN,UAAU,CAAC,MAAM,MAAM;AAAA,IACvB,GAAI,MAAM,WAAW,SAAY,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC7D,MAAM,EAAE,MAAM,YAAY;AAAA,IAC1B,GAAI,MAAM,UAAU,MAAM,OAAO,SAAS,IAAI,EAAE,WAAW,EAAE,QAAQ,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,IACzF,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IAC/C,OAAO,MAAM,IAAI,CAAC,MAAM;AACtB,YAAM,OAAO,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,QAAQ,MAAM,IAAI,EAAE,OAAO,CAAC,GAAG,MAAO,WAAW,CAAC,IAAI,WAAW,CAAC,IAAI,IAAI,CAAE;AAC/G,aAAO,EAAE,MAAM,EAAE,MAAM,MAAM,MAAM,EAAE,OAAO,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,OAAO,UAAU,CAAC,EAAE,EAAE,EAAE;AAAA,IACnG,CAAC;AAAA,EACH;AACF;AAGO,SAAS,SAAS,GAAoB;AAC3C,SAAO,KAAK,UAAU,GAAG,MAAM,CAAC,IAAI;AACtC;AAcA,SAAS,WAAW,SAA0B,OAA4B;AACxE,MAAI,OAAO,KAAK,QAAQ,IAAI,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,OAAO,EAAE;AAC5D,MAAI,CAAC,YAAY,KAAK,IAAI,EAAG,QAAO;AACpC,MAAI,OAAO;AACX,WAAS,IAAI,GAAG,MAAM,IAAI,IAAI,GAAG,IAAK,QAAO,GAAG,IAAI,IAAI,CAAC;AACzD,QAAM,IAAI,IAAI;AACd,SAAO;AACT;AAOO,SAAS,qBAAqB,UAA+C,OAAkD;AACpI,QAAM,MAA+B,WAAW,gBAAgB,QAAQ,IAAI,EAAE,MAAM,MAAM,MAAM,QAAQ,EAAE;AAC1G,QAAM,UAAU,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA6C,CAAC;AAChG,QAAM,QAAQ,IAAI,IAAI,QAAQ,IAAI,CAAC,MAAM,OAAO,EAAE,IAAI,CAAC,CAAC;AACxD,aAAW,KAAK,MAAM,UAAU;AAC9B,QAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAQ,EAAE,QAAQ,OAAO,EAAE,QAAQ,MAAU,EAAG;AACpF,YAAQ,KAAK,EAAE,MAAM,WAAW,GAAG,KAAK,GAAG,KAAK,EAAE,KAAK,MAAM,SAAS,CAAC;AAAA,EACzE;AACA,MAAI,UAAU;AACd,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAK,IAAI,OAA0C,CAAC;AACvF,MAAI,CAAC,KAAK,KAAK,CAAC,MAAM,EAAE,YAAY,cAAc,EAAG,MAAK,KAAK,EAAE,SAAS,gBAAgB,SAAS,MAAM,eAAe,CAAC;AACzH,MAAI,OAAO;AACX,QAAME,MAAK,IAAI,MAAM,OAAO,IAAI,OAAO,YAAY,CAAC,MAAM,QAAQ,IAAI,EAAE,IAAK,IAAI,KAAiC,CAAC;AACnH,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,MAAM,EAAE,EAAG,KAAI,MAAM,OAAW,CAAAA,IAAG,CAAC,IAAI;AAC5E,MAAI,OAAO,KAAKA,GAAE,EAAE,SAAS,EAAG,KAAI,KAAKA;AACzC,SAAO;AACT;AAGO,SAAS,YAAY,KAA0C,KAAiC;AACrG,QAAM,UAAU,OAAO,MAAM,QAAQ,IAAI,OAAO,IAAK,IAAI,UAA6C,CAAC;AACvG,QAAM,IAAI,QAAQ,KAAK,CAAC,MAAM,EAAE,QAAQ,OAAQ,QAAQ,OAAO,EAAE,QAAQ,MAAU;AACnF,SAAO,OAAO,GAAG,SAAS,WAAW,EAAE,OAAO;AAChD;AArOA,IA6GM,WACA,YA8EA,aACO;AA7Lb;AAAA;AAAA;AAoBA;AACA;AACA;AAuFA,IAAM,YAAY;AAClB,IAAM,aAA8C,EAAE,OAAO,GAAG,kBAAkB,GAAG,QAAQ,EAAE;AA8E/F,IAAM,cAAc;AACb,IAAM,iBAAiB;AAAA;AAAA;;;ACtK9B,SAAS,QAAAC,aAAY;AAiCd,SAAS,uBAAmE;AACjF,EAAAC,aAAY,YAAY;AACtB,QAAI;AACF,YAAM,UAAmC,MAAM,OAAO,iCAAiC;AACvF,UAAI,OAAO,QAAQ,0BAA0B,cAAc,OAAO,QAAQ,wBAAwB,WAAY,QAAO;AACrH,UAAI,MAA+B,CAAC;AACpC,UAAI;AACF,cAAM,MAAM,OAAO,qCAAqC;AAAA,MAC1D,QAAQ;AAAA,MAER;AACA,aAAO;AAAA,QACL,uBAAuB,QAAQ;AAAA,QAC/B,qBAAqB,QAAQ;AAAA,QAC7B,GAAI,OAAO,IAAI,mBAAmB,aAAa,EAAE,gBAAgB,IAAI,eAA0D,IAAI,CAAC;AAAA,QACpI,GAAI,OAAO,QAAQ,qBAAqB,aAAa,EAAE,kBAAkB,QAAQ,iBAA8D,IAAI,CAAC;AAAA,MACtJ;AAAA,IACF,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOA;AACT;AAQA,eAAe,SAAS,QAA+B,MAAc,GAAuD;AAC1H,QAAM,MAAMD,MAAK,MAAM,EAAE,GAAG;AAC5B,MAAI,OAAO,gBAAgB;AACzB,QAAI;AACF,YAAM,QAAQ,MAAM,OAAO,eAAe,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC;AACjE,UAAI,UAAU,OAAW,QAAO;AAAA,IAClC,QAAQ;AAAA,IAER;AAAA,EACF;AACA,SAAO,OAAO,mBAAmB,GAAG;AACtC;AAGA,eAAsB,WAAW,MAAcE,SAA8B,QAAqD,CAAC,GAAwB;AACzJ,QAAM,QAAqB,CAAC;AAC5B,QAAM,UAAiC,CAAC;AACxC,QAAM,OAAO,IAAI,IAAIA,QAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AAC7C,QAAM,MAAM,CAAC,MAAuB;AAClC,QAAI,CAAC,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,EAAE,UAAU,EAAE,aAAa,EAAE,QAAQ,EAAG,OAAM,KAAK,CAAC;AAAA,EAC1F;AACA,aAAW,CAACC,SAAQ,GAAG,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,eAAW,YAAY,IAAK,KAAI,KAAK,IAAIA,OAAM,KAAK,KAAK,IAAI,QAAQ,EAAG,KAAI,EAAE,QAAAA,SAAQ,UAAU,SAAS,cAAc,CAAC;AAAA,EAC1H;AACA,QAAM,SAAS,MAAM,qBAAqB;AAC1C,MAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,SAAS,OAAO,MAAM;AACnD,QAAM,SAASD,QAAO,IAAI,CAAC,OAAO,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,SAAS,OAAO,EAAE,MAAM,EAAE;AAC3F,aAAW,KAAKA,SAAQ;AACtB,UAAM,WAAW,MAAM,SAAS,QAAQ,MAAM,CAAC;AAC/C,QAAI,aAAa,OAAW;AAC5B,eAAW,OAAO,OAAO,sBAAsB,QAAQ,GAAG;AACxD,YAAM,QAAQ,OAAO,oBAAoB,KAAK,EAAE,WAAW,EAAE,KAAK,SAAS,EAAE,QAAQ,GAAG,MAAM;AAC9F,UAAI,WAAW,MAAO,KAAI,EAAE,QAAQ,EAAE,KAAK,UAAU,MAAM,MAAM,WAAW,SAAS,kBAAkB,CAAC;AAAA,UACnG,SAAQ,KAAK,EAAE,OAAO,EAAE,KAAK,WAAW,IAAI,MAAM,KAAK,MAAM,QAAQ,CAAC;AAAA,IAC7E;AAAA,EACF;AACA,SAAO,EAAE,OAAO,SAAS,OAAO,KAAK;AACvC;AAaO,SAAS,WACd,OACA,OACA,SAA4B,CAAC,GAC2C;AACxE,QAAM,QAA4C,CAAC;AACnD,QAAM,SAAS,OAAO,SAAS,MAAM,QAAQ,CAAC,MAAM,EAAE,OAAO,OAAO,CAAC,MAAM,OAAO,SAAS,EAAE,GAAG,CAAC,CAAC,IAAI,CAAC;AACvG,QAAM,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,OAAO,OAAO,CAAC,MAAM,CAAC,OAAO,SAAS,EAAE,GAAG,CAAC,EAAE,EAAE,EAAE,OAAO,CAAC,MAAM,EAAE,OAAO,SAAS,CAAC;AAC5I,QAAM,SAA2B,CAAC,GAAI,OAAO,SAAS,CAAC,EAAE,MAAM,UAAU,QAAQ,OAAO,CAAC,IAAI,CAAC,GAAI,GAAG,IAAI;AAEzG,QAAM,SAAS,oBAAI,IAAoB;AACvC,SAAO,QAAQ,CAAC,GAAG,MAAM,EAAE,OAAO,QAAQ,CAAC,MAAM,OAAO,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC;AACtE,aAAW,KAAK,OAAO;AACrB,UAAM,IAAI,OAAO,IAAI,EAAE,MAAM;AAC7B,UAAM,IAAI,OAAO,IAAI,EAAE,QAAQ;AAC/B,QAAI,MAAM,UAAa,MAAM,UAAa,IAAI,EAAG,OAAM,KAAK,EAAE,GAAG,GAAG,KAAK,GAAG,EAAE,QAAQ,eAAe,OAAO,CAAC,EAAG,IAAI,WAAW,EAAE,MAAM,WAAW,OAAO,CAAC,EAAG,IAAI,GAAG,CAAC;AAAA,EACvK;AAEA,QAAM,MAAwB,CAAC;AAC/B,aAAW,KAAK,QAAQ;AACtB,UAAM,SAAS,IAAI,IAAI,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,CAAC;AACjD,UAAM,MAAM,IAAI,IAAsB,EAAE,OAAO,IAAI,CAAC,MAAM,CAAC,EAAE,KAAK,MAAM,OAAO,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,OAAO,IAAI,EAAE,QAAQ,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC;AAC5J,UAAM,QAAQ,oBAAI,IAAoB;AACtC,UAAM,OAAO,oBAAI,IAAY;AAC7B,UAAM,QAAQ,CAAC,MAAsB;AACnC,YAAM,QAAQ,MAAM,IAAI,CAAC;AACzB,UAAI,UAAU,OAAW,QAAO;AAChC,UAAI,KAAK,IAAI,CAAC,EAAG,QAAO;AACxB,WAAK,IAAI,CAAC;AACV,UAAI,IAAI;AACR,iBAAW,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG;AAChC,YAAI,KAAK,IAAI,CAAC,GAAG;AACf,gBAAM,IAAI,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,KAAK,EAAE,aAAa,CAAC;AAC9D,gBAAM,KAAK,EAAE,GAAG,GAAG,KAAK,GAAG,CAAC,QAAQ,CAAC,mBAAmB,CAAC;AACzD;AAAA,QACF;AACA,YAAI,KAAK,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC;AAAA,MAC9B;AACA,WAAK,OAAO,CAAC;AACb,YAAM,IAAI,GAAG,CAAC;AACd,aAAO;AAAA,IACT;AACA,eAAW,KAAK,EAAE,OAAQ,OAAM,EAAE,GAAG;AACrC,UAAM,QAAQ,KAAK,IAAI,GAAG,GAAG,MAAM,OAAO,CAAC,IAAI;AAC/C,aAAS,IAAI,GAAG,IAAI,OAAO,KAAK;AAC9B,YAAMA,UAAS,EAAE,OAAO,OAAO,CAAC,MAAM,MAAM,IAAI,EAAE,GAAG,MAAM,CAAC;AAC5D,UAAIA,QAAO,OAAQ,KAAI,KAAK,EAAE,MAAM,MAAM,IAAI,EAAE,OAAO,GAAG,EAAE,IAAI,IAAI,IAAI,CAAC,IAAI,QAAAA,QAAO,CAAC;AAAA,IACvF;AAAA,EACF;AACA,SAAO,EAAE,OAAO,KAAK,MAAM;AAC7B;AAGO,SAAS,WAAW,OAAmB,OAA6D;AACzG,QAAM,MAAgB,CAAC;AACvB,MAAI,CAAC,MAAM,MAAO,KAAI,KAAK,4HAA4H;AACvJ,aAAW,KAAK,MAAM,MAAO,KAAI,KAAK,GAAG,EAAE,MAAM,kBAAkB,EAAE,QAAQ,KAAK,EAAE,YAAY,oBAAoB,uBAAuB,aAAa,GAAG;AAC3J,aAAW,KAAK,MAAM,QAAS,KAAI,KAAK,GAAG,EAAE,KAAK,qBAAqB,EAAE,SAAS,oBAAoB,EAAE,GAAG,EAAE;AAC7G,aAAW,KAAK,MAAO,KAAI,KAAK,GAAG,EAAE,MAAM,wBAAwB,EAAE,QAAQ,iBAAiB,EAAE,GAAG,2CAA2C;AAC9I,SAAO;AACT;AApMA,IAqDID;AArDJ;AAAA;AAAA;AAAA;AAAA;;;ACMA,SAAS,cAAAG,aAAY,gBAAAC,sBAAoB;AACzC,SAAS,QAAAC,QAAM,SAAAC,cAAa;AAC5B,SAAS,aAAAC,kBAAiB;AAgCnB,SAAS,QAAQ,MAAc,MAAuB;AAC3D,SAAOA,WAAUH,eAAaC,OAAK,MAAM,IAAI,GAAG,MAAM,CAAC;AACzD;AAGO,SAAS,aAAa,MAAc,OAA8C;AACvF,SAAO,MAAM,KAAK,CAAC,MAAMF,YAAWE,OAAK,MAAM,CAAC,CAAC,CAAC;AACpD;AAGO,SAAS,YAAY,OAAyB;AACnD,QAAM,MAAMC,OAAM,UAAU,MAAM,OAAO,CAAC,MAAM,MAAM,MAAM,MAAM,GAAG,EAAE,KAAK,GAAG,KAAK,GAAG,EAAE,QAAQ,SAAS,EAAE,EAAE,QAAQ,QAAQ,EAAE;AAChI,SAAO,QAAQ,KAAK,MAAM;AAC5B;AAGO,SAAS,UAAUE,WAAoB,KAA0C;AACtF,QAAM,OAAO,SAAS,GAAG;AACzB,SAAOA,UAAS,SAAS,KAAK,CAAC,MAAM,SAAS,EAAE,GAAG,MAAM,IAAI;AAC/D;AAGO,SAAS,WAAW,MAAiB,KAAsC;AAChF,QAAMC,UAAU,SAAS,KAAK,MAAM,IAAI,KAAK,SAAU,KAAK,SAAS,CAAC;AACtE,SAAQA,QAAO,GAAG,MAAM,CAAC;AAC3B;AAGO,SAAS,UAAU,MAAiB,QAAgB,OAAqB;AAC9E,QAAM,WAAY,SAAS,KAAK,QAAQ,IAAI,KAAK,WAAY,KAAK,WAAW,CAAC;AAC9E,QAAM,OAAQ,SAAS,MAAM,MAAM,CAAC;AACpC,MAAI,CAAC,KAAK,SAAS,KAAK,EAAG,MAAK,KAAK,KAAK;AAC5C;AAGO,SAAS,SAAS,KAAqB;AAC5C,SAAO,IAAI,QAAQ,kBAAkB,EAAE;AACzC;AAGO,SAAS,gBAAgB,GAA4B,OAA0B,MAAc,QAAgB,KAA4B;AAC9I,SAAO,OAAO,KAAK,CAAC,EACjB,OAAO,CAAC,MAAM,CAAC,MAAM,SAAS,CAAC,CAAC,EAChC,IAAI,CAAC,OAAO,EAAE,MAAM,SAAS,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,GAAG,IAAI,EAAE;AACvE;AAGO,SAAS,UAAU,MAAiB,MAA4B;AACrE,QAAM,MAAiB,gBAAgB,IAAI;AAC3C,aAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,IAAI,GAAG;AACzC,QAAI,CAAC,IAAI,SAAS,CAAC,KAAK,SAAS,IAAI,CAAC,CAAC,IAAI,UAAU,IAAI,CAAC,GAAgB,CAAC,IAAI,gBAAgB,CAAC;AAAA,EAClG;AACA,SAAO;AACT;AAGO,SAAS,YAAY,GAA2B;AACrD,QAAM,MAAM,CAAC,UAAU,EAAE,MAAM,UAAU,EAAE,MAAM,SAAS,EAAE,MAAM,KAAK,IAAI,IAAI,SAAS,EAAE;AAC1F,aAAW,KAAK,EAAE,MAAO,KAAI,KAAK,KAAK,CAAC,EAAE;AAC1C,MAAI,EAAE,YAAY,OAAQ,KAAI,KAAK,KAAK,EAAE,YAAY,MAAM,WAAW,EAAE,YAAY,WAAW,IAAI,KAAK,GAAG,eAAe;AAC3H,aAAW,KAAK,EAAE,YAAa,KAAI,KAAK,OAAO,EAAE,IAAI,KAAK,EAAE,OAAO,KAAK,EAAE,GAAG,EAAE;AAC/E,SAAO;AACT;AAtGA,IAYa;AAZb,IAAAC,cAAA;AAAA;AAAA;AAUA;AAEO,IAAM,iBAAiB,CAAC,kBAAkB,eAAe,aAAa,MAAM;AAAA;AAAA;;;ACUnF,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,YAAAC,WAAU,WAAAC,UAAS,QAAAC,cAAY;AAQjC,SAAS,gBAAgB,MAAcC,WAAoB,OAAoC;AACpG,MAAI,MAAM,OAAQ,QAAO,CAAC,GAAG,KAAK;AAClC,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAKA,UAAS,UAAU;AACjC,QAAI;AACJ,QAAI;AACF,cAAQJ,aAAYG,OAAK,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK;AAAA,IAC9C,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,MAAO,KAAI,cAAc,KAAK,CAAC,EAAG,KAAI,KAAK,SAAS,EAAE,KAAK,CAAC,CAAC;AAAA,EAC/E;AACA,SAAO;AACT;AA5CA,IA4BM,eAkBA,aAYO;AA1Db;AAAA;AAAA;AAwBA;AACA;AACA,IAAAE;AAEA,IAAM,gBAAgB;AAkBtB,IAAM,cAAgD;AAAA,MACpD,mCAAmC;AAAA,MACnC,yCAAyC;AAAA,MACzC,4BAA4B;AAAA,MAC5B,cAAc;AAAA,MACd,aAAa;AAAA,MACb,6BAA6B;AAAA,MAC7B,4BAA4B;AAAA,MAC5B,4BAA4B;AAAA,MAC5B,qBAAqB;AAAA,IACvB;AAEO,IAAM,oBAA8B,CAAC,MAAMD,WAAU,UAAU;AACpE,UAAI,OAAkB,CAAC;AACvB,YAAM,cAA6B,CAAC;AACpC,YAAM,QAAkB,CAAC;AACzB,YAAM,QAAkB,CAAC;AACzB,YAAM,MAAM,CAAC,MAAc,SAAiB,QAAuB;AACjE,oBAAY,KAAK,EAAE,MAAM,SAAS,KAAK,OAAO,YAAY,OAAO,KAAK,gCAAgC,CAAC;AAAA,MACzG;AACA,iBAAW,QAAQ,gBAAgB,MAAMA,WAAU,KAAK,GAAG;AACzD,cAAM,IAAI,cAAc,KAAKH,UAAS,IAAI,CAAC;AAC3C,YAAI,CAAC,GAAG;AACN,cAAI,MAAM,UAAU,gGAAgG;AACpH;AAAA,QACF;AACA,YAAI;AACJ,YAAI;AACF,gBAAM,QAAQ,MAAM,IAAI;AAAA,QAC1B,SAAS,GAAG;AACV,cAAI,MAAM,UAAU,kBAAmB,EAAY,OAAO,EAAE;AAC5D;AAAA,QACF;AACA,cAAM,WAAW,SAAS,GAAG,KAAK,SAAS,IAAI,QAAQ,IAAI,IAAI,WAAW,SAAS,GAAG,IAAI,MAAM;AAChG,YAAI,CAAC,SAAU;AACf,cAAM,KAAK,IAAI;AACf,cAAM,UAAU,SAAS,SAAS,MAAMC,SAAQC,OAAK,MAAM,IAAI,CAAC,CAAC,CAAC;AAClE,cAAM,SAAS,SAAS,SAAS,aAAa,KAAK,SAAS,SAAS,cAAc,GAAG,IAAI,SAAS,cAAc,MAAM,CAAC;AACxH,cAAM,MAAM,OAAO,OAAO,YAAY,WAAW,SAAS,OAAO,OAAO,IAAI;AAC5E,cAAM,UAAU,UAAUC,WAAU,GAAG,GAAG,QAAQ,UAAUA,WAAU,OAAO,GAAG;AAChF,YAAI,CAAC,SAAS;AACZ,cAAI,MAAM,6BAA6B,GAAG,GAAG,uBAAuB;AACpE;AAAA,QACF;AACA,cAAM,MAAM,GAAG,OAAO,IAAI,EAAE,CAAC,CAAC;AAC9B,cAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,YAAI,QAAQ,IAAK,OAAM,MAAM;AAC7B,YAAI,OAAO,OAAO,WAAW,SAAU,WAAU,MAAM,SAAS,OAAO,MAAM,GAAG,GAAG;AACnF,mBAAW,KAAK,OAAO,KAAK,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,UAAU,WAAW,SAAS,EAAE,SAAS,CAAC,CAAC,EAAG,KAAI,MAAM,qBAAqB,CAAC,EAAE;AAE/I,cAAM,KAAK,SAAS,SAAS,MAAM,IAAI,SAAS,SAAS,CAAC;AAC1D,cAAM,WAAW,MAAM,QAAQ,GAAG,KAAK,IAAI,GAAG,MAAM,IAAI,MAAM,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC,IAAI,CAAC;AACrG,YAAI,SAAS,OAAQ,OAAM,QAAQ;AACnC,YAAI,MAAM,QAAQ,GAAG,KAAK,KAAK,GAAG,MAAM,KAAK,CAAC,MAAM,OAAO,CAAC,EAAE,WAAW,GAAG,CAAC,EAAG,KAAI,MAAM,gBAAgB,sFAAsF;AAChM,YAAI,GAAG,wBAAwB,MAAO,KAAI,MAAM,8BAA8B,2GAA2G;AACzL,YAAI,GAAG,kBAAkB,MAAO,KAAI,MAAM,wBAAwB,0FAA0F;AAC5J,YAAI,GAAG,wBAAwB,KAAM,QAAO,UAAU,MAAM,EAAE,eAAe,EAAE,UAAU,IAAI,EAAE,CAAC;AAChG,mBAAW,KAAK,OAAO,KAAK,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,SAAS,uBAAuB,iBAAiB,qBAAqB,EAAE,SAAS,CAAC,CAAC,EAAG,KAAI,MAAM,UAAU,CAAC,EAAE;AAE7J,cAAM,KAAK,SAAS,SAAS,gBAAgB,IAAI,SAAS,mBAAmB,CAAC;AAC9E,YAAI,MAAM,QAAQ,GAAG,cAAc,KAAK,GAAG,eAAe,OAAQ,KAAI,MAAM,iCAAiC;AAC7G,YAAI,SAAS,GAAG,oBAAoB,KAAK,OAAO,KAAK,GAAG,oBAAoB,EAAE,QAAQ;AACpF,cAAI,MAAM,yCAAyC,GAAG,YAAY,uCAAuC,CAAC,KAAK,OAAO,KAAK,GAAG,oBAAoB,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,EAAE;AAAA,QACzK;AACA,YAAI,SAAS,GAAG,OAAO,KAAK,OAAO,KAAK,GAAG,OAAO,EAAE,OAAQ,YAAW,KAAK,OAAO,KAAK,GAAG,OAAO,EAAG,KAAI,MAAM,4BAA4B,CAAC,IAAI,YAAY,0BAA0B,CAAC;AACvL,YAAI,SAAS,GAAG,IAAI,GAAG;AAErB,gBAAM,MAAwC;AAAA,YAC5C,CAAC,OAAO,WAAW,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,IAAI,UAAU,MAAS;AAAA,YAC1E,CAAC,OAAO,kBAAkB,SAAS,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,IAAI,iBAAiB,MAAS;AAAA,YACxF,CAAC,SAAS,YAAY,SAAS,GAAG,KAAK,KAAK,IAAI,GAAG,KAAK,MAAM,WAAW,MAAS;AAAA,UACpF;AACA,qBAAW,CAAC,OAAO,OAAO,EAAE,KAAK,KAAK;AACpC,gBAAI,CAAC,SAAS,GAAG,KAAK,KAAK,CAAC,EAAG;AAC/B;AAAA,cACE;AAAA,cACA,yBAAyB,KAAK;AAAA,cAC9B,OAAO,OAAO,WACV,mCAAmC,EAAE,yBAAyB,GAAG,OAAO,KAAK,KAAK,EAAE,uDAAuD,KAAK,gBAChJ,UAAU,KAAK,yBAAyB,GAAG;AAAA,YACjD;AAAA,UACF;AACA,qBAAW,SAAS,OAAO,KAAK,GAAG,IAAI,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,OAAO,OAAO,OAAO,EAAE,SAAS,CAAC,CAAC,EAAG,KAAI,MAAM,yBAAyB,KAAK,EAAE;AAAA,QAC1I;AACA,mBAAW,KAAK,OAAO,KAAK,EAAE,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,kBAAkB,wBAAwB,WAAW,MAAM,EAAE,SAAS,CAAC,CAAC,EAAG,KAAI,MAAM,oBAAoB,CAAC,EAAE;AAE5J,cAAM,OAAO,SAAS,SAAS,eAAe,IAAI,SAAS,kBAAkB,CAAC;AAC9E,YAAI,OAAO,KAAK,kBAAkB,SAAU,MAAK,QAAQ,KAAK;AAAA,iBACrD,SAAS,KAAK,aAAa,KAAK,OAAO,KAAK,cAAc,cAAc,SAAU,MAAK,QAAQ,KAAK,cAAc;AAC3H,oBAAY,KAAK,GAAG,gBAAgB,UAAU,CAAC,iBAAiB,UAAU,oBAAoB,mBAAmB,gBAAgB,eAAe,WAAW,QAAQ,GAAG,MAAM,IAAI,+BAA+B,CAAC;AAChN,YAAI,SAAS,SAAS,YAAY,KAAK,SAAS,aAAa,WAAW,KAAM,KAAI,MAAM,cAAc;AACtG,YAAI,OAAO,SAAS,gBAAgB,YAAY,SAAS,YAAa,KAAI,MAAM,aAAa;AAAA,MAC/F;AACA,UAAI,MAAM,OAAQ,OAAM,KAAK,8FAA8F;AAC3H,aAAO,EAAE,QAAQ,eAAe,OAAO,MAAM,aAAa,MAAM;AAAA,IAClE;AAAA;AAAA;;;ACvHA,SAAS,SAASE,WAAoB,OAA8C;AAClF,aAAW,KAAK,OAAO;AACrB,UAAM,OAAOA,UAAS,OAAO,OAAO,CAAC,MAAM,EAAE,QAAQ,KAAK,EAAE,UAAU,KAAMA,UAAS,OAAO,OAAO,CAAC,MAAM,EAAE,YAAY,EAAE,OAAO,EAAE,WAAW,KAAK,EAAE,YAAY,CAAE;AACnK,QAAI,KAAK,WAAW,EAAG,QAAO,KAAK,CAAC,EAAG;AAAA,EACzC;AACA,SAAO;AACT;AA5BA,IAkBa,qBACA,iBAWA;AA9Bb;AAAA;AAAA;AAcA;AAEA,IAAAC;AAEO,IAAM,sBAAsB,CAAC,qBAAqB,oBAAoB;AACtE,IAAM,kBAAkB,CAAC,YAAY,WAAW;AAWhD,IAAM,aAAuB,CAAC,MAAMD,WAAU,UAAU;AAC7D,YAAM,OAAkB,CAAC;AACzB,YAAM,cAA6B,CAAC;AACpC,YAAM,QAAkB,CAAC;AACzB,YAAM,QAAkB,CAAC;AACzB,YAAM,OAAO,CAAC,YAAmD,MAAM,KAAK,CAAC,MAAM,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,MAAM,MAAM,SAAS,SAAY,aAAa,MAAM,OAAO;AAChL,iBAAW,KAAK,MAAM,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,qBAAqB,GAAG,eAAe,EAAE,KAAK,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,GAAG;AAC7G,oBAAY,KAAK,EAAE,MAAM,GAAG,SAAS,UAAU,KAAK,cAAc,oBAAoB,CAAC,CAAC,QAAQ,gBAAgB,CAAC,CAAC,GAAG,CAAC;AAAA,MACxH;AAEA,YAAM,WAAW,KAAK,mBAAmB;AACzC,UAAI,UAAU;AACZ,cAAM,KAAK,QAAQ;AACnB,cAAM,MAAM,QAAQ,MAAM,QAAQ;AAClC,cAAM,OAAO,SAAS,GAAG,KAAK,SAAS,IAAI,YAAY,IAAI,IAAI,eAAe,CAAC;AAC/E,cAAM,UAAU,oBAAI,IAAoB;AACxC,mBAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC5C,gBAAM,IAAI,SAAS,GAAG,IAAI,MAAM,CAAC;AACjC,gBAAM,QAAQ,CAAC,IAAI,GAAI,OAAO,EAAE,SAAS,WAAW,CAAC,EAAE,IAAI,IAAI,CAAC,GAAI,GAAI,OAAO,EAAE,iBAAiB,WAAW,CAAC,EAAE,YAAY,IAAI,CAAC,CAAE;AACnI,gBAAM,MAAM,SAASA,WAAU,KAAK;AACpC,cAAI,IAAK,SAAQ,IAAI,IAAI,GAAG;AAAA,cACvB,aAAY,KAAK,EAAE,MAAM,UAAU,SAAS,gBAAgB,EAAE,IAAI,KAAK,sCAAsC,MAAM,KAAK,IAAI,CAAC,kDAAkD,CAAC;AACrL,qBAAW,KAAK,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,QAAQ,gBAAgB,OAAO,EAAE,SAAS,CAAC,CAAC,GAAG;AAC5F,wBAAY,KAAK,EAAE,MAAM,UAAU,SAAS,gBAAgB,EAAE,IAAI,CAAC,IAAI,KAAK,gCAAgC,CAAC;AAAA,UAC/G;AAAA,QACF;AACA,cAAM,QAAkC,CAAC;AACzC,mBAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQ,IAAI,GAAG;AAC5C,gBAAM,SAAS,QAAQ,IAAI,EAAE;AAC7B,gBAAM,QAAQ,SAAS,GAAG,KAAK,MAAM,QAAQ,IAAI,KAAK,IAAI,IAAI,MAAM,IAAI,MAAM,IAAI,CAAC;AACnF,cAAI,CAAC,OAAQ;AACb,qBAAW,KAAK,OAAO;AACrB,kBAAME,MAAK,QAAQ,IAAI,CAAC;AACxB,gBAAIA,IAAI,EAAC,MAAM,MAAM,MAAM,CAAC,GAAG,KAAKA,GAAE;AAAA,gBACjC,aAAY,KAAK,EAAE,MAAM,UAAU,SAAS,gBAAgB,EAAE,UAAU,KAAK,GAAG,CAAC,qCAAqC,CAAC;AAAA,UAC9H;AAAA,QACF;AACA,YAAI,OAAO,KAAK,KAAK,EAAE,OAAQ,MAAK,QAAQ,EAAE,MAAM;AACpD,mBAAW,KAAK,OAAO,KAAK,SAAS,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,cAAc,GAAG;AACzF,sBAAY,KAAK,EAAE,MAAM,UAAU,SAAS,GAAG,KAAK,gCAAgC,CAAC;AAAA,QACvF;AAAA,MACF;AAEA,YAAM,OAAO,KAAK,eAAe;AACjC,UAAI,MAAM;AACR,cAAM,KAAK,IAAI;AACf,cAAM,MAAM,QAAQ,MAAM,IAAI;AAC9B,mBAAW,SAAS,CAAC,UAAU,SAAS,GAAG;AACzC,gBAAM,QAAQ,SAAS,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,SAAU,IAAI,KAAK,EAA8B,KAAK,IAAM,IAAI,KAAK,EAA8B,QAAoC,CAAC;AAC/L,qBAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,KAAK,GAAG;AACjD,uBAAW,QAAQ,OAAO,KAAK,SAAS,KAAK,IAAI,QAAQ,CAAC,CAAC,GAAG;AAC5D,0BAAY,KAAK,EAAE,MAAM,MAAM,SAAS,GAAG,KAAK,UAAU,IAAI,IAAI,IAAI,IAAI,KAAK,yGAAyG,CAAC;AAAA,YAC3L;AAAA,UACF;AAAA,QACF;AACA,mBAAW,KAAK,OAAO,KAAK,SAAS,GAAG,IAAI,MAAM,CAAC,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,UAAU,SAAS,EAAE,SAAS,CAAC,CAAC,GAAG;AAClH,sBAAY,KAAK,EAAE,MAAM,MAAM,SAAS,GAAG,KAAK,gCAAgC,CAAC;AAAA,QACnF;AAAA,MACF;AACA,UAAI,CAAC,MAAM,OAAQ,OAAM,KAAK,MAAM,oBAAoB,CAAC,CAAC,OAAO,gBAAgB,CAAC,CAAC,oBAAoB;AAAA,UAClG,OAAM,KAAK,yIAAyI;AACzJ,aAAO,EAAE,QAAQ,QAAQ,OAAO,MAAM,aAAa,MAAM;AAAA,IAC3D;AAAA;AAAA;;;AC1EA,SAAS,eAAAC,oBAAmB;AAC5B,SAAS,QAAAC,cAAY;AAoBd,SAAS,mBAAmB,MAAc,OAAoC;AACnF,MAAI,MAAM,OAAQ,QAAO,CAAC,GAAG,KAAK;AAClC,QAAM,MAAgB,CAAC;AACvB,aAAW,KAAKC,gBAAe;AAC7B,QAAI;AACJ,QAAI;AACF,cAAQF,aAAYC,OAAK,MAAM,CAAC,CAAC,EAAE,KAAK;AAAA,IAC1C,QAAQ;AACN;AAAA,IACF;AACA,eAAW,KAAK,MAAO,KAAI,WAAW,KAAK,CAAC,EAAG,KAAI,KAAK,GAAG,CAAC,IAAI,CAAC,EAAE;AAAA,EACrE;AACA,SAAO;AACT;AAGA,SAAS,SAAS,KAAgF;AAChG,QAAM,KAAK,IAAI,MAAM,IAAI,MAAM;AAC/B,QAAM,QAAQ,OAAO,OAAO,WAAW,CAAC,EAAE,IAAI,MAAM,QAAQ,EAAE,IAAI,GAAG,IAAI,MAAM,IAAI,SAAS,EAAE,IAAI,OAAO,KAAK,EAAE,IAAI,CAAC;AACrH,QAAM,OAAO,SAAS,EAAE,KAAK,SAAS,GAAG,IAAI,IAAI,GAAG,OAAO;AAC3D,QAAM,WAAW,QAAQ,MAAM,QAAQ,KAAK,QAAQ,IAAI,KAAK,SAAS,IAAI,MAAM,IAAI,MAAM,SAAS,MAAM,IAAI,CAAC,MAAM,IAAI,CAAC;AACzH,SAAO,EAAE,aAAa,MAAM,SAAS,cAAc,KAAK,MAAM,SAAS,qBAAqB,GAAG,cAAc,SAAS;AACxH;AAGA,SAAS,MAAM,GAAsB;AACnC,MAAI,MAAM,QAAQ,CAAC,EAAG,QAAO,EAAE,IAAI,MAAM,EAAE,OAAO,OAAO;AACzD,SAAO,OAAO,MAAM,WAAW,EAAE,MAAM,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,CAAC,EAAE,OAAO,OAAO,IAAI,CAAC;AAC1F;AAnEA,IAwBaC,gBACP,SACA,KA2CA,cAEO;AAvEb;AAAA;AAAA;AAoBA;AAEA,IAAAC;AAEO,IAAMD,iBAAgB,CAAC,qBAAqB,sBAAsB,kBAAkB;AAC3F,IAAM,UAAU,CAAC,cAAc,YAAY,WAAW,iBAAiB,eAAe,qBAAqB,aAAa,kBAAkB,gBAAgB,mBAAmB,wBAAwB;AACrM,IAAM,MAAwC;AAAA,MAC5C,SAAS;AAAA,MACT,QAAQ;AAAA,MACR,qBAAqB;AAAA,MACrB,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,qBAAqB;AAAA,MACrB,oBAAoB;AAAA,MACpB,MAAM;AAAA,MACN,MAAM;AAAA,IACR;AAiCA,IAAM,eAAe;AAEd,IAAM,sBAAgC,CAAC,MAAME,WAAoB,UAAU;AAChF,UAAI,OAAkB,CAAC;AACvB,YAAM,cAA6B,CAAC;AACpC,YAAM,QAAkB,CAAC;AACzB,YAAM,QAAkB,CAAC;AACzB,YAAM,UAAU,oBAAI,IAAY;AAChC,iBAAW,QAAQ,mBAAmB,MAAM,KAAK,GAAG;AAClD,YAAI;AACJ,YAAI;AACF,gBAAM,QAAQ,MAAM,IAAI;AAAA,QAC1B,SAAS,GAAG;AACV,sBAAY,KAAK,EAAE,MAAM,SAAS,UAAU,KAAK,0BAA2B,EAAY,OAAO,GAAG,CAAC;AACnG;AAAA,QACF;AACA,YAAI,CAAC,SAAS,GAAG,KAAK,CAAC,SAAS,IAAI,IAAI,EAAG;AAC3C,cAAM,KAAK,SAAS,GAAG;AACvB,YAAI,OAAO;AACX,mBAAW,CAAC,SAAS,GAAG,KAAK,OAAO,QAAQ,IAAI,IAAI,GAAG;AACrD,cAAI,CAAC,SAAS,GAAG,KAAK,CAAC,MAAM,QAAQ,IAAI,KAAK,EAAG;AAEjD,gBAAM,OAAO,OAAO,IAAI,OAAO,WAAW,IAAI,KAAK;AACnD,gBAAM,QAAQ,kCAAkC,KAAK,IAAI,IACrD,EAAE,aAAa,OAAO,cAAc,GAAG,aAAa,IACpD,kCAAkC,KAAK,IAAI,IACzC,EAAE,aAAa,GAAG,aAAa,cAAc,CAAC,EAAE,IAChD;AACN,cAAI,MAAM,QAAQ,CAAC,MAAM,MAAM;AAC7B,gBAAI,CAAC,SAAS,IAAI,KAAK,OAAO,KAAK,SAAS,YAAY,CAAC,oBAAoB,KAAK,KAAK,IAAI,EAAG;AAC9F,mBAAO;AACP,kBAAM,QAAQ,QAAQ,OAAO,UAAU,CAAC;AACxC,kBAAM,IAAI,SAAS,KAAK,IAAI,IAAI,KAAK,OAAO,CAAC;AAC7C,uBAAW,KAAK,KAAK,UAAU,KAAK,OAAO,CAAC,CAAC,EAAE,SAAS,oCAAoC,EAAG,SAAQ,IAAI,EAAE,CAAC,CAAE;AAChH,uBAAW,KAAK,KAAK,UAAU,IAAI,OAAO,CAAC,CAAC,EAAE,SAAS,oCAAoC,EAAG,SAAQ,IAAI,EAAE,CAAC,CAAE;AAC/G,kBAAM,YAAY,OAAO,EAAE,YAAY,MAAM,WAAW,EAAE,YAAY,IAAI;AAC1E,gBAAI,CAAC,WAAW;AACd,0BAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,oBAAoB,KAAK,0EAA0E,CAAC;AAC9I;AAAA,YACF;AACA,kBAAM,MAAM,SAAS,OAAO,EAAE,UAAU,MAAM,WAAW,EAAE,UAAU,IAAI,GAAG;AAC5E,kBAAM,QAAQ,UAAU,MAAM,GAAG;AACjC,kBAAM,QAAQ,MAAM,MAAM,SAAS,CAAC;AACpC,kBAAM,UAAU,UAAUA,WAAU,GAAG,GAAG,SAAS,MAAM,WAAW,IAAI,MAAM,CAAC,IAAK;AACpF,gBAAI,CAAC,SAAS;AACZ,0BAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,oBAAoB,KAAK,GAAG,GAAG,6BAA6B,SAAS,oBAAoB,CAAC;AACpI;AAAA,YACF;AACA,kBAAM,MAAM,GAAG,OAAO,IAAI,KAAK;AAC/B,kBAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,gBAAI,QAAQ,IAAK,OAAM,MAAM;AAE7B,gBAAI,MAAM,WAAW,KAAK,MAAM,WAAW,EAAG,QAAO,UAAU,MAAM,EAAE,cAAc,EAAE,KAAK,MAAM,CAAC,EAAE,EAAE,CAAC;AAExG,kBAAM,UAAU,OAAO,EAAE,YAAY,WAAW,EAAE,UAAU;AAC5D,gBAAI,YAAY,QAAQ,YAAY,UAAU;AAC5C,kBAAI,MAAM,YAAa,QAAO,UAAU,MAAM,EAAE,OAAO,EAAE,MAAM,eAAe,EAAE,CAAC;AACjF,yBAAW,KAAK,MAAM,aAAc,WAAU,MAAM,GAAG,GAAG;AAC1D,kBAAI,CAAC,MAAM,eAAe,MAAM,aAAa,WAAW,EAAG,aAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,iBAAiB,KAAK,qFAAqF,CAAC;AAAA,YACnN,WAAW,YAAY,WAAW;AAChC,0BAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,iBAAiB,KAAK,GAAG,WAAW,QAAQ,+EAA+E,CAAC;AAAA,YACxK;AAEA,kBAAM,QAAQ,MAAM,EAAE,WAAW;AACjC,kBAAM,UAAU,MAAM,EAAE,iBAAiB;AACzC,gBAAI,MAAM,QAAQ;AAChB,oBAAM,SAAS,MAAM,IAAI,CAAC,GAAG,MAAO,QAAQ,CAAC,IAAI,EAAE,KAAK,SAAS,KAAK,CAAC,GAAG,QAAQ,SAAS,KAAK,QAAQ,CAAC,CAAE,EAAE,IAAI,SAAS,KAAK,CAAC,CAAE;AAClI,oBAAM,OAAQ,SAAS,KAAK,MAAM,KAAK,MAAM,QAAQ,KAAK,OAAO,KAAK,IAAI,KAAK,OAAO,QAAQ,CAAC;AAC/F,qBAAO,UAAU,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,OAAO,OAAO,CAAC,MAAM,CAAC,KAAK,KAAK,CAAC,MAAM,KAAK,UAAU,CAAC,MAAM,KAAK,UAAU,CAAC,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AAAA,YAC9I;AACA,kBAAM,QAAQ,OAAO,EAAE,WAAW,MAAM,WAAW,EAAE,WAAW,IAAI;AACpE,gBAAI,SAAS,CAAC,aAAa,KAAK,KAAK,GAAG;AACtC,kBAAI,cAAc,KAAK,KAAK,EAAG,QAAO,UAAU,MAAM,EAAE,cAAc,EAAE,SAAS,MAAM,EAAE,CAAC;AAAA,kBACrF,OAAM,UAAU;AAAA,YACvB;AACA,kBAAMC,WAAU,OAAO,EAAE,gBAAgB,MAAM,WAAW,EAAE,gBAAgB,EAAE,QAAQ,MAAM,EAAE,IAAI;AAClG,gBAAIA,UAAS;AACX,kBAAI,kBAAkB,KAAKA,QAAO,EAAG,MAAK,SAASA;AAAA,kBAC9C,aAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,wBAAwB,KAAK,GAAGA,QAAO,gEAAgE,CAAC;AAAA,YACzJ;AACA,uBAAW,SAAS,OAAO,KAAK,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,QAAQ,SAAS,CAAC,CAAC,GAAG;AACtE,0BAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,SAAS,KAAK,IAAI,KAAK,IAAI,KAAK,KAAK,gCAAgC,CAAC;AAAA,YAClH;AAAA,UACF,CAAC;AAAA,QACH;AACA,YAAI,KAAM,OAAM,KAAK,IAAI;AAAA,MAC3B;AACA,UAAI,MAAM,UAAU,QAAQ,KAAM,OAAM,KAAK,kCAAkC,CAAC,GAAG,OAAO,EAAE,KAAK,EAAE,KAAK,IAAI,CAAC,iDAAiD;AAC9J,UAAI,MAAM,OAAQ,OAAM,KAAK,qEAAqE;AAClG,aAAO,EAAE,QAAQ,kBAAkB,OAAO,MAAM,aAAa,MAAM;AAAA,IACrE;AAAA;AAAA;;;AC/JA,IAiBa,iBACPC,UAEO;AApBb;AAAA;AAAA;AAcA;AACA,IAAAC;AAEO,IAAM,kBAAkB,CAAC,yBAAyB,wBAAwB;AACjF,IAAMD,WAAU,CAAC,gBAAgB,cAAc;AAExC,IAAM,kBAA4B,CAAC,MAAME,WAAU,UAAU;AAClE,YAAM,OAAkB,CAAC;AACzB,YAAM,cAA6B,CAAC;AACpC,YAAM,QAAkB,CAAC;AACzB,YAAM,OAAO,MAAM,CAAC,KAAK,aAAa,MAAM,eAAe;AAC3D,UAAI,CAAC,KAAM,QAAO,EAAE,QAAQ,aAAa,OAAO,CAAC,GAAG,MAAM,aAAa,OAAO,CAAC,MAAM,gBAAgB,CAAC,CAAC,oBAAoB,EAAE;AAC7H,iBAAW,SAAS,MAAM,MAAM,CAAC,EAAG,aAAY,KAAK,EAAE,MAAM,OAAO,SAAS,UAAU,KAAK,yDAAyD,CAAC;AACtJ,YAAM,MAAM,QAAQ,MAAM,IAAI;AAC9B,UAAI,CAAC,SAAS,GAAG,EAAG,QAAO,EAAE,QAAQ,aAAa,OAAO,CAAC,IAAI,GAAG,MAAM,aAAa,CAAC,EAAE,MAAM,SAAS,UAAU,KAAK,mBAAmB,CAAC,GAAG,MAAM;AAClJ,YAAM,WAAW,SAAS,IAAI,cAAc,IAAI,IAAI,iBAAiB,CAAC;AACtE,YAAMC,UAAS,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AACpD,iBAAW,KAAK,OAAO,KAAK,GAAG,EAAE,OAAO,CAAC,MAAM,CAAC,CAAC,WAAW,kBAAkB,QAAQ,EAAE,SAAS,CAAC,CAAC,GAAG;AACpG,oBAAY,KAAK,EAAE,MAAM,SAAS,GAAG,KAAK,MAAM,oBAAoB,MAAM,UAAU,mDAAmD,gCAAgC,CAAC;AAAA,MAC1K;AACA,YAAMC,UAAS,oBAAI,IAAY;AAC/B,YAAM,aAAa,CAAC,GAA4B,WAAyB;AACvE,mBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,CAAC,GAAG;AACtC,cAAIJ,SAAQ,SAAS,CAAC,EAAG;AACzB,gBAAM,MACJ,MAAM,gBACF,+CAA+C,SAAS,CAAC,IAAI,OAAO,KAAK,CAAC,EAAE,KAAK,EAAE,KAAK,IAAI,IAAI,QAAQ,KACxG,mBAAmB,KAAK,CAAC,IACvB,2GACA;AACR,sBAAY,KAAK,EAAE,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,IAAI,IAAI,CAAC;AAAA,QAC3D;AAAA,MACF;AACA,iBAAW,UAAU,gBAAgB;AACrC,iBAAW,CAAC,IAAI,GAAG,KAAK,OAAO,QAAQG,OAAM,GAAG;AAC9C,cAAM,MAAM,SAAS,GAAG,IAAI,MAAM,CAAC;AACnC,cAAM,IAAI,EAAE,GAAG,UAAU,GAAG,IAAI;AAChC,cAAM,MAAM,SAAS,OAAO,EAAE,iBAAiB,WAAW,EAAE,eAAe,GAAG;AAC9E,cAAM,UAAU,UAAUD,WAAU,GAAG;AACvC,YAAI,CAAC,SAAS;AACZ,sBAAY,KAAK,EAAE,MAAM,SAAS,UAAU,EAAE,iBAAiB,KAAK,GAAG,GAAG,wBAAwB,CAAC;AACnG;AAAA,QACF;AACA,YAAI,QAAQ;AACZ,YAAI,CAAC,QAAQ,OAAO,SAAS,EAAE,GAAG;AAChC,cAAI,QAAQ,OAAO,WAAW,GAAG;AAC/B,oBAAQ,QAAQ,OAAO,CAAC;AACxB,kBAAM,KAAK,mBAAmB,EAAE,OAAO,QAAQ,IAAI,IAAI,KAAK,sBAAsB,GAAG,EAAE;AAAA,UACzF,MAAO,OAAM,KAAK,mBAAmB,EAAE,kBAAkB,EAAE,YAAY,GAAG,qBAAqB,QAAQ,IAAI,IAAI,EAAE,8BAA8B,EAAE,oCAAoC;AAAA,QACvL;AACA,cAAM,MAAM,GAAG,QAAQ,IAAI,IAAI,KAAK;AACpC,cAAM,QAAQ,WAAW,MAAM,GAAG;AAClC,YAAI,QAAQ,IAAK,OAAM,MAAM;AAC7B,YAAI,OAAO,EAAE,iBAAiB,SAAU,CAAAE,QAAO,IAAI,EAAE,YAAY;AACjE,mBAAW,KAAK,UAAU,EAAE,EAAE;AAAA,MAChC;AACA,UAAIA,QAAO,SAAS,EAAG,MAAK,QAAQ,CAAC,GAAGA,OAAM,EAAE,CAAC;AAAA,eACxCA,QAAO,OAAO,EAAG,aAAY,KAAK,EAAE,MAAM,SAAS,gBAAgB,KAAK,qBAAqBA,QAAO,IAAI,sFAAsF,CAAC;AACxM,YAAM,KAAK,uIAAuI;AAClJ,aAAO,EAAE,QAAQ,aAAa,OAAO,CAAC,IAAI,GAAG,MAAM,aAAa,MAAM;AAAA,IACxE;AAAA;AAAA;;;AC7DA,SAAS,YAAAC,iBAAgB;AAuBlB,SAAS,aAAa,MAAwC;AACnE,QAAM,OAAOA,UAAS,IAAI;AAC1B,MAAI,8CAA8C,KAAK,IAAI,EAAG,QAAO;AACrE,MAAI,wCAAwC,KAAK,IAAI,EAAG,QAAO;AAC/D,MAAI,sBAAsB,KAAK,IAAI,EAAG,QAAO;AAC7C,MAAI,6BAA6B,KAAK,IAAI,EAAG,QAAO;AACpD,SAAO;AACT;AAGO,SAAS,UAAU,OAA6C;AACrE,QAAM,KAAK,MAAM,QAAQ,GAAG;AAC5B,QAAM,OAAO,MAAM,IAAI,MAAM,MAAM,GAAG,EAAE,IAAI;AAC5C,MAAK,eAAqC,SAAS,IAAI,GAAG;AACxD,UAAM,QAAQ,MAAM,IAAI,MAAM,MAAM,KAAK,CAAC,EAAE,MAAM,GAAG,EAAE,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,QAAQ,SAAS,EAAE,CAAC,EAAE,OAAO,OAAO,IAAI,CAAC;AACpH,QAAI,MAAM,KAAK,MAAM,WAAW,EAAG,QAAO,EAAE,OAAO,UAAU,IAAI,kBAAkB;AACnF,WAAO,EAAE,QAAQ,MAAsB,MAAM;AAAA,EAC/C;AACA,QAAM,OAAO,MAAM,QAAQ,SAAS,EAAE;AACtC,QAAM,SAAS,aAAa,IAAI;AAChC,MAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,UAAU,KAAK,kBAAkB,eAAe,KAAK,IAAI,CAAC,4CAA4C,KAAK,GAAG;AAC3I,SAAO,EAAE,QAAQ,OAAO,CAAC,IAAI,EAAE;AACjC;AAGO,SAAS,UAAU,MAAcC,WAAoB,MAA8B;AACxF,MAAI;AACF,WAAO,UAAU,KAAK,MAAM,EAAE,MAAMA,WAAU,KAAK,KAAK;AAAA,EAC1D,SAAS,GAAG;AACV,UAAM,OAAO,KAAK,MAAM,CAAC,KAAK;AAC9B,WAAO,EAAE,QAAQ,KAAK,QAAQ,OAAO,CAAC,GAAG,MAAM,CAAC,GAAG,aAAa,CAAC,EAAE,MAAM,SAAS,UAAU,KAAK,sBAAuB,EAAY,OAAO,GAAG,CAAC,GAAG,OAAO,CAAC,EAAE;AAAA,EAC9J;AACF;AApEA,IAuBa;AAvBb;AAAA;AAAA;AAeA;AACA;AACA;AACA;AACA,IAAAC;AAEA,IAAAA;AAEO,IAAM,YAAsD;AAAA,MACjE,kBAAkB;AAAA,MAClB,aAAa;AAAA,MACb,WAAW;AAAA,MACX,MAAM;AAAA,IACR;AAAA;AAAA;;;AC5BA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,yBAAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AA6CA,SAAS,cAAAC,cAAY,aAAAC,YAAW,gBAAAC,gBAAc,iBAAAC,sBAAqB;AACnE,SAAS,iBAAAC,sBAAqB;AAC9B,SAAS,WAAAC,UAAS,QAAAC,QAAM,SAAAC,cAAa;AAiG9B,SAAS,cAAc,MAAyE;AACrG,MAAI,KAAK,SAAS,gBAAgB,EAAG,QAAO,EAAE,aAAa,KAAK;AAChE,MAAI,OAAO;AACX,QAAM,OAAO,CAAC,SAAqD;AACjE,UAAM,IAAI,SAAS,MAAM,IAAI;AAC7B,QAAI,EAAE,QAAS,QAAO,EAAE,OAAO,GAAG,IAAI,iBAAiB;AACvD,WAAO,EAAE;AACT,WAAO,EAAE,UAAU,SAAY,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAAA,EACvD;AACA,QAAMC,UAAS,KAAK,UAAU;AAC9B,QAAM,OAAO,KAAK,QAAQ;AAC1B,QAAMC,UAAS,KAAK,UAAU;AAC9B,QAAM,QAAQ,KAAK,SAAS;AAC5B,QAAM,MAAM,KAAK,OAAO;AACxB,QAAM,WAAW,KAAK,QAAQ;AAC9B,QAAM,MAAM,CAACD,SAAQ,MAAMC,SAAQ,OAAO,KAAK,QAAQ,EAAE,KAAK,CAAC,MAAM,EAAE,KAAK;AAC5E,MAAI,IAAK,QAAO,EAAE,OAAO,IAAI,MAAO;AACpC,QAAM,QAAQ,oBAAI,IAAI,CAAC,qBAAqB,aAAa,SAAS,IAAI,CAAC;AACvE,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;AAC9C,MAAI,MAAM,OAAQ,QAAO,EAAE,OAAO,sBAAsB,MAAM,KAAK,GAAG,CAAC,GAAG;AAC1E,MAAID,QAAO,UAAU,UAAa,CAAC,aAAaA,QAAO,KAAK,EAAG,QAAO,EAAE,OAAO,YAAYA,QAAO,KAAK,kBAAkB,aAAa,KAAK,IAAI,CAAC,GAAG;AACnJ,QAAM,IAAI,KAAK,UAAU,SAAY,SAAS,KAAK,KAAK,IAAI;AAC5D,MAAI,KAAK,UAAU,UAAa,CAAC,EAAG,QAAO,EAAE,OAAO,UAAU,KAAK,KAAK,4DAA4D;AACpI,MAAIC,QAAO,UAAU,UAAa,CAAE,aAAmC,SAASA,QAAO,KAAK,EAAG,QAAO,EAAE,OAAO,YAAYA,QAAO,KAAK,kBAAkB,aAAa,KAAK,IAAI,CAAC,GAAG;AACnL,MAAI,MAAM,UAAU,UAAa,CAAE,OAA6B,SAAS,MAAM,KAAK,EAAG,QAAO,EAAE,OAAO,WAAW,MAAM,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,GAAG;AACnK,QAAM,OAAO,SAAS,UAAU,SAAY,UAAU,SAAS,KAAK,IAAI;AACxE,MAAI,QAAQ,WAAW,KAAM,QAAO,EAAE,OAAO,KAAK,MAAM;AACxD,SAAO;AAAA,IACL,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC;AAAA,IACvB,GAAID,QAAO,QAAQ,EAAE,QAAQA,QAAO,MAAoB,IAAI,CAAC;AAAA,IAC7D,GAAI,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC;AAAA,IACvB,GAAIC,QAAO,QAAQ,EAAE,QAAQA,QAAO,MAAoB,IAAI,CAAC;AAAA,IAC7D,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAmB,IAAI,CAAC;AAAA,IACzD,KAAK,IAAI,SAAS;AAAA,IAClB,aAAa,CAAC,KAAK,SAAS,mBAAmB;AAAA,IAC/C,QAAQ,KAAK,SAAS,WAAW;AAAA,IACjC,KAAK,KAAK,SAAS,OAAO,KAAK,KAAK,SAAS,IAAI;AAAA,EACnD;AACF;AAGA,SAAS,IAAI,MAAc,KAAa,MAAc,QAAiB,MAAyB;AAC9F,QAAM,OAAOH,OAAK,MAAM,GAAG;AAC3B,QAAM,SAASN,aAAW,IAAI,IAAIE,eAAa,MAAM,MAAM,IAAI;AAC/D,MAAI,WAAW,KAAM,QAAO,EAAE,MAAM,KAAK,QAAQ,aAAa,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAG;AACxF,MAAI,CAAC,QAAQ;AACX,IAAAD,WAAUI,SAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,IAAAF,eAAc,MAAM,IAAI;AAAA,EAC1B;AACA,SAAO,EAAE,MAAM,KAAK,QAAQ,WAAW,GAAI,OAAO,EAAE,KAAK,IAAI,CAAC,EAAG;AACnE;AAGA,SAAS,eAAe,MAAkC;AACxD,SAAO,aAAa,KAAK,CAAC,MAAMH,aAAWM,OAAK,MAAM,CAAC,CAAC,CAAC;AAC3D;AAOA,eAAsB,cAAcI,WAAoB,MAAmB,IAAwG;AACjL,QAAM,QAAkB,CAAC;AACzB,MAAI,aAAa,KAAK;AACtB,MAAI,CAAC,cAAc,GAAG,OAAO,CAAC,KAAK,KAAK;AACtC,eAAW,KAAK,QAAS,IAAG,IAAI,KAAK,EAAE,KAAK,OAAO,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE;AACrE,iBAAc,MAAM,GAAG,IAAI,UAAU,cAAc,cAAc;AAAA,EACnE;AACA,QAAMF,UAAS,aAAa,cAAc,cAAc;AACxD,QAAM,OAAkB,gBAAgBA,QAAO,IAAI;AACnD,MAAI,KAAK,KAAM,MAAK,OAAO,KAAK;AAChC,QAAMC,UAAS,WAAW,EAAE,QAAQ,KAAK,QAAQ,UAAAC,WAAU,KAAK,GAAG,IAAI,CAAC;AACxE,SAAO,OAAO,MAAMD,QAAO,IAAI;AAC/B,QAAM,KAAK,GAAGA,QAAO,KAAK;AAC1B,QAAM,iBAAiBA,QAAO,KAAK,YAAY,UAAaA,QAAO,KAAK,WAAW;AAEnF,MAAI;AACJ,MAAI,KAAK,OAAO;AACd,YAAQ,EAAE,MAAM,KAAK,OAAO,SAAS,UAAU;AAC/C,QAAIC,UAAS,OAAO,SAAS,KAAK,MAAO,MAAK,QAAQ,EAAE,MAAM,KAAK,MAAM;AAAA,aAChEA,UAAS,MAAM,IAAK,MAAK,QAAQ,EAAE,MAAM,KAAK,OAAO,KAAKA,UAAS,MAAM,IAAI;AAAA,EACxF,WAAWA,UAAS,OAAO;AACzB,YAAQ,EAAE,MAAMA,UAAS,MAAM,MAAM,SAASA,UAAS,MAAM,QAAQ;AACrE,QAAIA,UAAS,MAAM,IAAK,MAAK,QAAQ,EAAE,MAAMA,UAAS,MAAM,MAAM,KAAKA,UAAS,MAAM,IAAI;AAAA,EAC5F,OAAO;AACL,UAAM,OAAQ,GAAG,OAAO,CAAC,KAAK,MAAM,MAAM,GAAG,IAAI,SAAS,QAAQ,QAAQ,IAAI;AAC9E,YAAQ,EAAE,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,MAAM,iBAAiB,gFAAgF;AAChJ,SAAK,QAAQ,EAAE,KAAK;AAAA,EACtB;AAGA,QAAM,UAAU,GAAG,IAAI,oBAAoB,KAAK;AAChD,MAAI,WAAW,CAAC,kBAAkBA,UAAS,SAAS,KAAK,CAAC,MAAM,CAAC,EAAE,UAAU,GAAG;AAC9E,SAAK,UAAU;AACf,UAAM,KAAK,WAAW,OAAO,4EAA4E;AAAA,EAC3G;AACA,SAAO,EAAE,MAAM,OAAO,MAAM;AAC9B;AASO,SAAS,WAAWA,WAAoB,KAAgB,UAAuD,CAAC,GAAgB;AACrI,QAAM,SAAS,SAAiB,GAAG;AACnC,QAAM,SAAS,IAAI,IAAI,QAAQ,OAAO,CAAC,MAAM,EAAE,aAAa,EAAE,aAAa,EAAE,IAAI,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC;AACpG,QAAM,MAAmB,CAAC;AAC1B,QAAM,OAAO,oBAAI,IAAY;AAC7B,QAAM,MAAM,CAAC,KAAa,SAAiB,OAAe,QAAsB;AAC9E,UAAM,MAAM,OAAO,GAAG,KAAK,CAAC;AAC5B,UAAM,UAAU,IAAI,YAAY,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAChF,UAAMD,UAAS,SAAS,KAAK,OAAO,GAAG;AACvC,UAAM,WAAW,IAAI,OAAO;AAC5B,UAAM,QAAQ,cAAc,kBAAkB,GAAG,GAAG,QAAQ;AAC5D,UAAM,MAAM,OAAO,IAAI,GAAG;AAC1B,QAAI,KAAK;AAAA,MACP;AAAA,MACA;AAAA,MACA;AAAA,MACA,KAAK;AAAA,MACL,GAAIA,UAAS,EAAE,QAAAA,QAAO,IAAI,CAAC;AAAA,MAC3B,GAAI,MAAM,EAAE,eAAe,IAAI,eAAgB,GAAI,IAAI,aAAa,EAAE,YAAY,IAAI,WAAW,IAAI,CAAC,EAAG,IAAI,CAAC;AAAA,MAC9G,GAAI,IAAI,OAAO,EAAE,MAAM,IAAI,KAAK,IAAI,CAAC;AAAA,MACrC,GAAI,MAAM,SAAS,EAAE,aAAa,MAAM,IAAI,CAAC;AAAA,IAC/C,CAAC;AACD,SAAK,IAAI,GAAG;AAAA,EACd;AACA,aAAW,KAAKC,UAAS,OAAQ,KAAI,EAAE,KAAK,EAAE,SAAS,EAAE,OAAO,EAAE,GAAG;AACrE,aAAW,CAAC,KAAK,GAAG,KAAK,OAAO,QAAQ,MAAM,GAAG;AAC/C,QAAI,KAAK,IAAI,GAAG,EAAG;AACnB,UAAM,CAAC,SAAS,KAAK,IAAI,IAAI,MAAM,GAAG;AACtC,QAAI,KAAK,SAAS,OAAO,KAAK,OAAO,GAAG;AAAA,EAC1C;AACA,SAAO;AACT;AAGA,SAASC,UAAS,KAAgBD,WAAoB,MAAyD;AAC7G,MAAI,KAAK,MAAO,QAAO,EAAE,MAAM,KAAK,OAAO,SAAS,UAAU;AAC9D,QAAM,OAAO,SAAS,IAAI,KAAK,IAAK,IAAI,MAAM,OAAiC;AAC/E,MAAI,KAAM,QAAO,EAAE,MAAM,SAAS,8BAA8B;AAChE,MAAIA,UAAS,MAAO,QAAO,EAAE,MAAMA,UAAS,MAAM,MAAM,SAASA,UAAS,MAAM,QAAQ;AACxF,SAAO,EAAE,MAAM,UAAU,SAAS,8CAA8C;AAClF;AAGA,eAAe,mBAA6J;AAC1K,MAAI;AAEF,UAAM,IAA6B,MAAM,OAAO,yCAAyC;AACzF,WAAO,OAAO,EAAE,gBAAgB,aAAc,EAAE,cAAwB;AAAA,EAC1E,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,eAAsB,QAAQ,MAAmB,OAAkB,IAAiC;AAClG,QAAMA,YAAW,OAAO,GAAG,GAAG;AAC9B,QAAM,EAAE,KAAK,IAAIA;AACjB,QAAM,QAAoB,CAAC;AAC3B,QAAM,QAAkB,CAAC;AACzB,QAAM,OAAiB,CAAC;AACxB,QAAM,UAA0B,CAAC;AACjC,QAAM,QAAwB,CAAC;AAE/B,QAAM,WAAW,KAAK,OAAO,UAAU,MAAMA,WAAU,KAAK,IAAI,IAAI;AACpE,MAAI,YAAY,SAAS,MAAM,WAAW,EAAG,OAAM,KAAK,UAAU,SAAS,MAAM,yBAAyB,SAAS,MAAM,SAAS,KAAK,SAAS,MAAM,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE;AACzK,QAAM,OAAO,CAAC,SAAiBE,SAAQ,EAAE,MAAM,UAAuB,SAAS,GAAG,OAAmB;AAAA,IACnG,IAAI;AAAA,IAAO,UAAU,MAAM;AAAA,IAAQ;AAAA,IAAO,QAAQ,CAAC;AAAA,IAAG,OAAO,CAAC;AAAA,IAAG,OAAAA;AAAA,IAAO;AAAA,IAAM,OAAO,CAAC,GAAG,OAAO,OAAO;AAAA,IAAG;AAAA,IAAS;AAAA,IAAO,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EAC3J;AAEA,MAAIF,UAAS,SAAS,WAAW,EAAG,QAAO,KAAK,wBAAwB,IAAI,+DAA+D;AAC3I,MAAIA,UAAS,OAAO,WAAW,EAAG,OAAM,KAAK,sHAAsH;AAGnK,MAAIG;AACJ,MAAI;AACJ,QAAM,OAAO,eAAe,IAAI;AAChC,MAAI,MAAM;AACR,QAAI;AACF,MAAAA,UAAS,WAAWP,OAAK,MAAM,IAAI,CAAC;AAAA,IACtC,SAAS,GAAG;AACV,aAAO,KAAM,EAAY,OAAO;AAAA,IAClC;AACA,UAAM,KAAK,EAAE,MAAM,MAAM,QAAQ,OAAO,CAAC;AACzC,UAAM,WAAW,KAAK,WAAW,YAAY,SAASO,QAAO,GAAG,GAAG,WAAW;AAC9E,UAAM,UAAU,CAAC,KAAK,UAAU,YAAY,KAAK,QAAQ,UAAU,KAAK,UAAU,CAAC,YAAY,YAAY,YAAY,QAAQ,EAAE,OAAO,OAAO;AAC/I,QAAI,QAAQ,OAAQ,OAAM,KAAK,GAAG,IAAI,yBAAyB,QAAQ,KAAK,IAAI,CAAC,sCAAsC;AACvH,QAAI,KAAK,WAAW,YAAY,CAAC,SAAU,OAAM,KAAK,GAAG,gBAAgB,MAAMH,WAAU,GAAG,GAAG,CAAC;AAChG,YAAQC,UAASE,QAAO,KAAKH,WAAU,IAAI;AAAA,EAC7C,OAAO;AACL,UAAM,OAAO,MAAM,cAAcA,WAAU,MAAM,EAAE;AACnD,UAAM,KAAK,GAAG,KAAK,KAAK;AACxB,YAAQ,KAAK;AACb,UAAM,OAAO,WAAW,WAAW,UAAU,KAAK,MAAM,SAAS,IAAI,IAAI,KAAK,IAAI;AAClF,IAAAG,UAAS,YAAY,MAAM,aAAa;AACxC,UAAMC,YAAW,YAAYD,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACzE,QAAIC,UAAS,OAAQ,QAAO,KAAKA,UAAS,IAAI,CAAC,MAAM,gBAAgB,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK;AAC5G,UAAM,KAAK,IAAI,MAAM,eAAe,MAAM,KAAK,MAAM,CAAC;AAAA,EACxD;AACA,QAAM,WAAW,YAAYD,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACzE,MAAI,SAAS,OAAQ,QAAO,KAAK,SAAS,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,GAAG,KAAK;AACxG,QAAM,MAAMA,QAAO;AACnB,QAAM,WAA0B,gBAAgBA,OAAM;AAEtD,QAAME,gBAAeF,QAAO,IAAI,kBAAkB,SAAY,MAAM,kBAAkB,IAAI;AAC1F,MAAI,SAAS,GAAG,iBAAiB,CAACE,cAAc,QAAO,SAAS,GAAG;AACnE,QAAM,eAAeA,gBAAe,eAAe,SAAS,SAAS,eAAe,IAAI;AACxF,QAAMC,UAAS,WAAWN,WAAU,KAAK,SAAS,OAAO;AAEzD,QAAM,QAAQ,MAAM,WAAW,MAAMM,SAAQ,SAAS,SAAS,KAAK;AACpE,QAAM,UAAU,WAAW,QAAQA,SAAQ,SAAS,SAAS,KAAK,GAAG,MAAM,OAAO,SAAS,SAAS,MAAM;AAC1G,QAAM,QAAQ,QAAQ;AACtB,MAAI,MAAM,MAAM,UAAU,MAAM,QAAQ,UAAU,QAAQ,MAAM,UAAW,CAAC,MAAM,SAASA,QAAO,SAAS,EAAI,OAAM,KAAK,GAAG,WAAW,OAAO,QAAQ,KAAK,CAAC;AAG7J,QAAM,cAAc,gBAAgB,MAAMN,WAAU,UAAU,KAAK,MAAM;AACzE,QAAM,KAAK,YAAY,IAAI;AAC3B,MAAIV,aAAWM,OAAK,MAAM,iBAAiB,CAAC,GAAG;AAC7C,UAAM,OAAOJ,eAAaI,OAAK,MAAM,iBAAiB,GAAG,MAAM;AAC/D,QAAI,CAAC,iBAAiB,KAAK,IAAI,GAAG;AAChC,YAAM,KAAK,EAAE,MAAM,mBAAmB,QAAQ,QAAQ,MAAM,wEAAwE,CAAC;AAAA,IACvI,MAAO,OAAM,KAAK,EAAE,MAAM,mBAAmB,QAAQ,OAAO,CAAC;AAAA,EAC/D,MAAO,OAAM,KAAK,IAAI,MAAM,mBAAmB,cAAc,GAAG,KAAK,MAAM,CAAC;AAC5E,QAAM,KAAK,IAAI,MAAM,iBAAiB,eAAeU,SAAQ,SAAS,SAAS,OAAO,eAAe,EAAE,aAAa,IAAI,CAAC,CAAC,GAAG,KAAK,MAAM,CAAC;AAGzI,QAAM,KAAK,GAAG,oBAAoB,MAAM,KAAK,KAAK,QAAQ,KAAK,CAAC;AAGhE,MAAIN,UAAS,UAAW,OAAM,KAAK,MAAM,cAAc,MAAMA,UAAS,WAAW,KAAK,MAAM,CAAC;AAC7F,aAAW,MAAMA,UAAS,eAAe;AACvC,UAAM,KAAK,GAAG,EAAE,0JAA0J;AAAA,EAC5K;AAGA,QAAM,QAAQ,MAAM,aAAa;AACjC,MAAI,CAAC,OAAO;AACV,UAAM,UAAU,kBAAkB,yCAAyC;AAC3E,UAAM,KAAK,EAAE,MAAMX,kBAAiB,QAAQ,WAAW,MAAM,QAAQ,GAAG,EAAE,MAAM,cAAc,MAAM,IAAI,GAAG,QAAQ,WAAW,MAAM,uBAAuB,CAAC;AAAA,EAC9J,OAAO;AACL,QAAI,OAA4C,cAAc,OAAOiB,SAAQ,KAAK,UAAUN,UAAS,eAAe,KAAK;AAEzH,QAAI,SAAS,SAAS,MAAM;AAC1B,UAAI;AACF,eAAO,gBAAgB,MAAM,SAAS,SAAS,MAAM,MAAM,MAAM,EAAE,aAAa,MAAM,aAAa,EAAE,CAAC;AAAA,MACxG,SAAS,GAAG;AACV,cAAM,KAAK,EAAE,MAAMX,kBAAiB,QAAQ,UAAU,MAAO,EAAY,QAAQ,CAAC;AAClF,eAAO;AAAA,MACT;AAAA,IACF;AACA,QAAI,QAAQiB,QAAO,SAAS,EAAG,OAAM,KAAK,IAAI,MAAMjB,kBAAiB,SAAS,IAAI,GAAG,KAAK,MAAM,CAAC;AACjG,QAAI,KAAM,OAAM,KAAK,GAAI,MAAM,aAAa,OAAO,MAAM,KAAK,UAAU,MAAM,MAAM,MAAMiB,QAAO,SAAS,IAAI,OAAO,QAAW,OAAO,EAAE,CAAE;AAAA,EAC7I;AAGA,MAAI,KAAK,YAAa,OAAM,KAAK,GAAI,MAAM,WAAWN,WAAU,KAAK,GAAG,KAAK,OAAO,CAAE;AAGtF,QAAM,KAAK,GAAI,MAAM,UAAU,MAAMA,WAAU,KAAK,GAAG,KAAK,YAAY,KAAK,KAAK,QAAQ,OAAO,OAAO,IAAI,CAAE;AAE9G,OAAK,KAAK,GAAG,UAAUA,WAAU,KAAK,MAAM,MAAM,GAAG,GAAG,CAAC;AACzD,QAAM,SAAS,MAAM,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ;AACtD,SAAO;AAAA,IACL,IAAI,CAAC;AAAA,IACL,UAAU,SAAS,MAAM,SAAS,MAAM;AAAA,IACxC;AAAA,IACA,QAAQM,QAAO,IAAI,CAAC,MAAM,EAAE,GAAG;AAAA,IAC/B,OAAO,MAAM,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,EAAE,OAAO,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;AAAA,IAC9E;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,EACjC;AACF;AAGA,SAAS,gBAAgB,MAAcN,WAAoB,UAAyB,QAAoE;AACtJ,MAAIV,aAAWM,OAAK,MAAM,uBAAuB,CAAC,GAAG;AACnD,WAAO,EAAE,MAAM,EAAE,MAAM,yBAAyB,QAAQ,QAAQ,MAAM,2CAA2CI,UAAS,SAAS,IAAI,CAAC,MAAM,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC,aAAa,cAAc,IAAI,SAAS,GAAG,EAAE;AAAA,EAC9M;AACA,MAAI;AACJ,QAAM,OAAOJ,OAAK,MAAM,gBAAgB;AACxC,MAAIN,aAAW,IAAI,GAAG;AACpB,QAAI;AACF,YAAM,SAAkB,KAAK,MAAME,eAAa,MAAM,MAAM,CAAC;AAC7D,UAAI,CAAC,SAAS,MAAM,EAAG,OAAM,IAAI,MAAM,eAAe;AACtD,iBAAW;AAAA,IACb,SAAS,GAAG;AACV,aAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,QAAQ,UAAU,MAAM,oCAAqC,EAAY,OAAO,IAAI,EAAE;AAAA,IACjI;AAAA,EACF;AACA,QAAM,MAAM,qBAAqB,UAAU,EAAE,MAAM,SAAS,IAAI,GAAG,UAAUQ,UAAS,UAAU,IAAI,SAAS,IAAI,gBAAgB,UAAU,CAAC;AAC5I,MAAI,YAAY,KAAK,UAAU,QAAQ,MAAM,KAAK,UAAU,GAAG,EAAG,QAAO,EAAE,MAAM,EAAE,MAAM,kBAAkB,QAAQ,YAAY,GAAG,IAAI;AACtI,SAAO,EAAE,MAAM,IAAI,MAAM,kBAAkB,SAAS,GAAG,GAAG,MAAM,GAAG,IAAI;AACzE;AAQA,SAAS,oBAAoB,MAAc,KAAgB,QAAiB,OAA6B;AACvG,QAAM,UAAU,kBAAkB,GAAG;AACrC,MAAI,CAAC,QAAS,QAAO,CAAC;AACtB,QAAM,IAAI,SAAS,IAAI,MAAM,IAAI,IAAI,SAAS,CAAC;AAC/C,QAAM,MAAkB,CAAC;AACzB,MAAI,OAAO,EAAE,SAAS,YAAY,EAAE,WAAW,QAAW;AACxD,UAAM,YAAY,OAAO,EAAE,cAAc,WAAW,EAAE,YAAY;AAClE,QAAI,KAAK,IAAI,MAAMH,OAAM,KAAK,UAAU,EAAE,IAAI,GAAG,mBAAmB,GAAG,cAAc,SAAS,SAAS,GAAG,QAAQ,qCAAqC,CAAC;AAAA,EAC1J,MAAO,OAAM,KAAK,uFAAuF,OAAO,kDAAkD;AAClK,aAAW,CAAC,MAAM,IAAI,KAAK,OAAO,QAAQ,mBAAmB,CAAC,EAAG,KAAI,KAAK,IAAI,MAAMA,OAAM,KAAK,oBAAoB,IAAI,GAAG,MAAM,MAAM,CAAC;AACvI,MAAI,KAAK,IAAI,MAAM,uBAAuB,oBAAoB,OAAO,GAAG,MAAM,CAAC;AAC/E,QAAM,SAAS,cAAc,GAAG,EAAE,KAAK,CAAC,SAAS,KAAK,QAAQ,kBAAkB;AAChF,MAAI,CAAC,OAAQ,OAAM,KAAK,gCAAgC,kBAAkB,aAAa,qBAAqB,kHAAkH,kBAAkB,EAAE;AAClP,SAAO;AACT;AAGA,eAAe,cAAc,MAAcM,SAAgB,QAAoC;AAC7F,QAAM,QAAQ,MAAM,iBAAiB;AACrC,MAAI,CAAC,OAAO;AACV,WAAO,EAAE,MAAM,kBAAkB,QAAQ,WAAW,MAAM,GAAGA,OAAM,8IAA8I,WAAW,GAAG;AAAA,EACjO;AACA,MAAI,UAAU,CAACb,aAAWM,OAAK,MAAM,gBAAgB,CAAC,EAAG,QAAO,EAAE,MAAM,kBAAkB,QAAQ,WAAW,MAAM,GAAGO,OAAM,0CAA0C;AACtK,QAAM,SAASX,eAAaI,OAAK,MAAM,gBAAgB,GAAG,MAAM;AAChE,MAAI;AACF,UAAM,MAAM,SAAS,cAAc,CAAC;AAAA,EACtC,SAAS,GAAG;AACV,WAAO,EAAE,MAAM,kBAAkB,QAAQ,UAAU,MAAM,8BAA+B,EAAY,OAAO,GAAG;AAAA,EAChH;AACA,QAAM,QAAQJ,eAAaI,OAAK,MAAM,gBAAgB,GAAG,MAAM;AAC/D,SAAO,EAAE,MAAM,kBAAkB,QAAQ,UAAU,SAAS,cAAc,WAAW,MAAM,GAAGO,OAAM,6EAA6E;AACnL;AAGA,SAAS,cAAc,OAAqBG,SAA8B,KAAgB,UAAyB,QAAgB,SAAwF;AACzN,QAAM,SAAS,WAAW,qBAAqB,SAAS,UAAU,KAAK,EAAE,MAAM;AAC/E,QAAM,OAAO,UAAU;AAAA,IACrB,QAAAA;AAAA,IACA;AAAA,IACA,MAAM,OAAO,GAAG;AAAA,IAChB;AAAA,IACA,GAAI,WAAW,SAAY,EAAE,OAAO,IAAI,CAAC;AAAA,IACzC,GAAI,SAAS,SAAS,QAAQ,SAAS,EAAE,QAAQ,SAAS,SAAS,OAAO,IAAI,CAAC;AAAA;AAAA,IAE/E,GAAI,SAAS,SAAS,SAAS,EAAE,QAAQ,EAAE,GAAG,eAAe,SAAS,SAAS,QAAQ,KAAK,EAAE,EAAE,IAAI,CAAC;AAAA,EACvG,CAAC;AACD,SAAO,MAAM,mBAAmB,MAAM,iBAAiB,MAAM,aAAa,IAAI;AAChF;AAOA,eAAe,aACb,OACA,MACA,KACA,UACA,OACA,MACA,MACA,OACA,IACqB;AACrB,QAAM,SAAS,cAAc,KAAK;AAClC,QAAM,SAAS,MAAM,UAAU,SAAS,QAAQ;AAChD,MAAI;AACJ,MAAI;AAGF,UAAM,EAAE,mBAAAC,mBAAkB,IAAI,MAAM;AACpC,UAAMC,WAAU,MAAMD,mBAAkB,KAAK,IAAI;AACjD,WAAO,aAAa,OAAO,KAAK,OAAO,KAAK,KAAK,MAAM,gBAAgB,qBAAqB,SAAS,UAAU,KAAK,CAAC,GAAG,EAAE,cAAc,MAAM,kBAAkB,GAAG,QAAQ,MAAM,MAAM,UAAU,GAAG,GAAIC,WAAU,EAAE,SAAAA,SAAQ,IAAI,CAAC,EAAG,CAAC;AAAA,EACvO,SAAS,GAAG;AACV,WAAO,CAAC,EAAE,MAAM,QAAQ,QAAQ,UAAU,MAAO,EAAY,QAAQ,CAAC;AAAA,EACxE;AACA,MAAI,KAAK,OAAQ,QAAO,CAAC,EAAE,MAAM,QAAQ,QAAQ,WAAW,MAAM,2CAA2C,CAAC;AAC9G,QAAM,OAAO,KAAK,KAAK,IAAI,CAAC,GAAG,MAAO,MAAM,KAAK,MAAM,MAAM,OAAO,CAAE;AACtE,QAAM,UAAU,MAAM,cAAc,OAAO,EAAE,MAAM,OAAO,QAAQ,MAAM,OAAO,KAAK,SAAS,aAAa,KAAK,KAAK,KAAK,QAAQ,CAAC;AAClI,MAAI,QAAQ,WAAW,SAAU,QAAO,CAAC,EAAE,MAAM,QAAQ,QAAQ,UAAU,MAAM,4BAA4B,QAAQ,IAAI,mCAAmC,CAAC;AAC7J,QAAM,QAAQ;AAAA,IACZ,GAAI,QAAQ,KAAK,SAAS,CAAC,uBAAuB,QAAQ,KAAK,KAAK,IAAI,CAAC,EAAE,IAAI,CAAC;AAAA,IAChF,GAAI,IAAI,kBAAkB,UAAa,CAAC,KAAK,KAAK,SAAS,UAAU,IAAI,CAAC,wBAAwB,IAAI,CAAC;AAAA,IACvG,GAAG,OAAO;AAAA,IACV,GAAG,KAAK;AAAA,IACR,GAAG,aAAa,MAAM,QAAQ,IAAI;AAAA,EACpC;AACA,QAAM,MAAkB,CAAC,EAAE,MAAM,QAAQ,QAAQ,QAAQ,QAAQ,GAAI,MAAM,SAAS,EAAE,MAAM,MAAM,KAAK,IAAI,EAAE,IAAI,CAAC,EAAG,CAAC;AACtH,MAAI,KAAK,KAAK,OAAO;AACnB,UAAM,OAAO,MAAM,cAAc,OAAO,OAAO,KAAK,KAAK,OAAO,KAAK,OAAO,OAAO,EAAE,GAAG,IAAI,KAAK,KAAK,CAAC;AACvG,QAAI,SAAS,MAAM,KAAM,KAAI,KAAK,EAAE,MAAM,iBAAiB,KAAK,GAAG,QAAQ,UAAU,MAAM,oCAAoC,IAAI,GAAG,CAAC;AAAA,EACzI;AACA,SAAO;AACT;AAGA,eAAe,WAAWR,WAAoB,KAAgB,KAAwB,SAA4C;AAChI,QAAM,SAAS,SAAiB,GAAG;AACnC,QAAM,OAAO,oBAAI,IAAY;AAC7B,aAAW,KAAKA,UAAS,QAAQ;AAC/B,UAAM,UAAUA,UAAS,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,EAAE,YAAY,OAAU;AAClH,UAAM,IAAI,UAAU,SAAS,EAAE,GAAI,OAAO,EAAE,GAAG,GAAG,UAAU,EAAE,OAAO,OAAO,EAAE,GAAG,EAAG,QAAQ,IAAI,CAAC,GAAI,GAAI,OAAO,IAAI,YAAY,WAAW,EAAE,KAAK,IAAI,QAAQ,IAAI,CAAC,EAAG,GAAG,GAAG;AAC5K,QAAI,EAAE,OAAO,CAAC,cAAc,EAAE,GAAG,EAAG,MAAK,IAAI,EAAE,GAAG;AAAA,EACpD;AACA,QAAM,UAAU,CAAC,GAAG,IAAI,EAAE,IAAI,CAAC,MAAM,aAAa,GAAG,GAAG,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,MAAS;AACxF,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,QAAMS,SAAQ,MAAM,iBAAiB;AACrC,MAAI,CAACA,OAAO,QAAO,CAAC,wBAAwB,WAAW,CAAC;AACxD,QAAMC,SAAkB,CAAC,gBAAgB;AACzC,aAAW,KAAK,SAAS;AACvB,QAAI,CAAC,EAAE,IAAI;AACT,MAAAA,OAAM,KAAK,KAAK,EAAE,KAAK,kBAAkB,EAAE,MAAM,EAAE;AACnD;AAAA,IACF;AACA,QAAI;AACF,YAAM,SAAS,MAAMD,OAAM,YAAY,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,CAAC;AAC7E,cAAQ,KAAK,MAAM;AACnB,MAAAC,OAAM,KAAK,GAAG,YAAY,MAAM,CAAC;AAAA,IACnC,SAAS,GAAG;AACV,MAAAA,OAAM,KAAK,KAAK,EAAE,KAAK,kBAAmB,EAAY,OAAO,EAAE;AAAA,IACjE;AAAA,EACF;AACA,SAAOA;AACT;AAMA,eAAe,UACb,MACAV,WACA,KACA,KACA,aACA,QACA,OACA,OACA,MACyB;AACzB,QAAM,SAAS,SAAiB,GAAG;AACnC,QAAM,MAAM,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAC5D,QAAM,UAAgH,CAAC;AACvH,aAAW,KAAKA,UAAS,QAAQ;AAC/B,UAAM,UAAUA,UAAS,SAAS,KAAK,CAAC,MAAM,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE,OAAO,KAAK,EAAE,YAAY,OAAU;AAClH,UAAM,MAAM,OAAO,EAAE,GAAG;AACxB,UAAM,IAAI,UAAU,SAAS,EAAE,GAAI,KAAK,UAAU,EAAE,OAAO,IAAI,QAAQ,IAAI,CAAC,GAAI,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC,EAAG,GAAG,GAAG;AAC9G,QAAI,EAAE,OAAO,YAAY,KAAK,EAAE,GAAG,EAAG,SAAQ,KAAK,EAAE,KAAK,EAAE,KAAK,SAAS,EAAE,SAAS,YAAY,EAAE,KAAK,KAAK,KAAK,OAAO,EAAE,KAAK,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI,CAAC;AAAA,EAC9J;AACA,MAAI,QAAQ,WAAW,EAAG,QAAO,CAAC;AAClC,QAAM,QAAQ,MAAM,WAAW;AAC/B,QAAM,WAAW,MAAM,cAAc,SAAS,OAAO,IAAI;AACzD,QAAM,KAAK,GAAG,WAAW,UAAU,KAAK,CAAC;AACzC,MAAI,CAAC,OAAO,OAAO;AACjB,UAAM,KAAK,EAAE,MAAM,eAAe,QAAQ,WAAW,MAAM,oJAAoJ,WAAW,GAAG,CAAC;AAC9N,WAAO;AAAA,EACT;AACA,QAAM,OAAO,cAAc,SAAS,QAAQ;AAC5C,MAAI,KAAK,WAAW,GAAG;AACrB,QAAIV,aAAWM,OAAK,MAAM,aAAa,CAAC,EAAG,OAAM,KAAK,EAAE,MAAM,eAAe,QAAQ,QAAQ,MAAM,oCAAoC,CAAC;AACxI,WAAO;AAAA,EACT;AACA,QAAM,OAAO,KAAK,IAAI,CAAC,OAAO,EAAE,QAAQ,YAAY,aAAa,EAAE,UAAU,KAAK,KAAK,EAAE,OAAO,GAAG,KAAK,EAAE,KAAK,OAAO,EAAE,OAAO,KAAK,EAAE,IAAI,EAAE;AAC5I,QAAM,KAAK,IAAI,MAAM,eAAe,YAAY,IAAI,GAAG,MAAM,CAAC;AAC9D,OAAK,KAAK,GAAG,UAAU,IAAI,CAAC;AAC5B,SAAO;AACT;AAGA,SAAS,gBAAgB,MAAcI,WAAoB,KAAkC;AAC3F,QAAM,OAAO,WAAW,EAAE,QAAQ,UAAU,UAAAA,WAAU,IAAI,CAAC;AAC3D,QAAM,UAAU,OAAO,QAAQ,KAAK,IAAI;AACxC,MAAI,QAAQ,WAAW,EAAG,QAAO,KAAK;AACtC,QAAM,OAAO,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,MAAMN,eAAc,GAAG,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,MAAM,IAAI,EAAE,OAAO,CAAC,MAAM,MAAM,EAAE;AACvG,SAAO,CAAC,GAAG,KAAK,OAAO,wCAAwC,IAAI,KAAK,GAAG,KAAK,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;AACxG;AAGA,SAAS,UAAUM,WAAoB,KAAgB,OAAkB,KAAkC;AAEzG,QAAM,MAAgB,CAAC;AACvB,QAAM,MAAM,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAC5D,QAAM,QAAQA,UAAS,SAAS,KAAK,CAAC,MAAM,cAAc,UAAU,GAAG,MAAM,EAAE,IAAI,IAAI,CAAC,GAAG,GAAG,EAAE,GAAG,CAAC;AACpG,QAAM,QAAQ,UAAU,WAAW,oBAAoB;AACvD,QAAM,SAAS,eAAe,GAAG;AACjC,MAAI,SAAS,OAAO,SAAS,QAAQ,GAAG;AACtC,QAAI,KAAK,+BAA+B,KAAK,4CAA4C,cAAc,GAAG,EAAE,GAAG,8EAA8E,KAAK,EAAE;AAAA,EACtM,WAAW,OAAO;AAChB,QAAI,KAAK,kOAAkO,KAAK,EAAE;AAAA,EACpP;AACA,MAAI,OAAO,KAAK,CAAC,MAAM,MAAM,QAAQ,EAAG,KAAI,KAAK,yHAAyHA,UAAS,aAAa,OAAO;AAAA,WAC9L,CAAC,MAAO,KAAI,KAAK,wKAAwK;AAClM,MAAI,KAAK,QAAQ,OAAO,iCAAiCA,UAAS,aAAa,EAAE;AACjF,SAAO;AACT;AAGO,SAAS,UAAU,GAAyB;AACjD,QAAM,MAAgB,CAAC;AACvB,MAAI,KAAK,GAAG,OAAO,UAAU,EAAE,OAAO,MAAM,SAAS,EAAE,OAAO,WAAW,IAAI,KAAK,GAAG,OAAO,EAAE,MAAM,IAAI,KAAK,EAAE,MAAM,OAAO,GAAG;AAC/H,aAAW,KAAK,EAAE,MAAO,KAAI,KAAK,UAAU,EAAE,IAAI,KAAK,EAAE,OAAO,KAAK,IAAI,CAAC,EAAE;AAC5E,MAAI,EAAE,MAAM,SAAS,EAAG,KAAI,KAAK,qBAAqB,EAAE,MAAM,CAAC,EAAG,IAAI,iBAAiB;AACvF,MAAI,EAAE,SAAU,KAAI,KAAK,GAAG,YAAY,EAAE,QAAQ,CAAC;AACnD,MAAI,KAAK,QAAQ;AACjB,aAAW,KAAK,EAAE,MAAO,KAAI,KAAK,KAAK,EAAE,OAAO,OAAO,CAAC,CAAC,IAAI,EAAE,IAAI,GAAG,EAAE,OAAO,KAAK,EAAE,IAAI,KAAK,EAAE,EAAE;AACnG,MAAI,EAAE,MAAM,OAAQ,KAAI,KAAK,GAAG,EAAE,MAAM,IAAI,CAAC,MAAO,EAAE,WAAW,IAAI,KAAK,EAAE,SAAS,GAAG,IAAI,IAAI,KAAK,CAAC,EAAG,CAAC;AAC1G,MAAI,EAAE,KAAK,OAAQ,KAAI,KAAK,iBAAiB,GAAG,EAAE,KAAK,IAAI,CAAC,MAAM,OAAO,CAAC,EAAE,CAAC;AAC7E,SAAO;AACT;AAGA,eAAsB,KAAK,MAAgB,MAAe,OAAkB,IAA6B;AACvG,QAAM,SAAS,cAAc,IAAI;AACjC,MAAI,iBAAiB,QAAQ;AAC3B,UAAM,SAAS,SAAS,iBAAiB,EAAE,QAAQ;AACnD,OAAG,IAAI,OAAO,KAAK,UAAU,EAAE,SAAS,QAAQ,IAAI,MAAM,UAAU,MAAM,MAAM,OAAO,CAAC,IAAI,MAAM;AAClG,WAAO,MAAM;AAAA,EACf;AACA,MAAI,WAAW,QAAQ;AACrB,OAAG,IAAI,GAAG,OAAO,KAAK,OAAO,KAAK,EAAE;AACpC,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,QAAQ,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,OAAO,MAAM,CAAC,CAAC;AAC5G,WAAO,MAAM;AAAA,EACf;AACA,QAAM,IAAI,MAAM,QAAQ,QAAQ,OAAO,OAAO,EAAE,GAAG,IAAI,KAAK,OAAU,IAAI,EAAE;AAC5E,MAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,QAAQ,GAAG,EAAE,CAAC,CAAC;AAAA,MACrD,YAAW,QAAQ,UAAU,CAAC,EAAG,EAAC,EAAE,KAAK,GAAG,MAAM,GAAG,KAAK,IAAI;AACnE,SAAO,EAAE;AACX;AA1qBA,IAuIa,kBACA,mBACA,iBACAX,kBAGA;AA7Ib;AAAA;AAAA;AAgDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA,IAAAsB;AACA;AACA;AACA;AACA,IAAAC;AACA;AACA;AAaA;AACA,IAAAC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AA6CO,IAAM,mBAAmB;AACzB,IAAM,oBAAoB;AAC1B,IAAM,kBAAkB;AACxB,IAAMxB,mBAAkB,mBAAmB,OAAO;AAGlD,IAAM,YAAqB,aAAgD,kBAAkB,KAAK;AAAA;AAAA;;;AC7IzG;AAAA;AAAA;AAAA;AAAA;AAAA,iBAAAyB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAqCA,SAAS,cAAAC,cAAY,gBAAAC,gBAAc,iBAAAC,sBAAqB;AACxD,SAAS,qBAAqB;AAC9B,SAAS,WAAAC,WAAS,QAAAC,cAAY;AAC9B,SAAS,qBAAqB;AAC9B,SAAS,iBAAAC,gBAAe,aAAAC,kBAAiB;AAqGlC,SAAS,gBAAgB,OAA8B;AAC5D,SAAO,OAAO,MAAM,gCAAgC;AACtD;AAWA,eAAsB,aAAa,KAAqI;AACtK,QAAM,OAAO,WAAW,GAAG;AAC3B,MAAI,CAAC,QAAQ,UAAU,WAAW,IAAI,EAAE,GAAG,MAAM,OAAW,QAAO,EAAE,MAAM,KAAK;AAChF,QAAM,QAAQ,MAAM,aAAa;AACjC,MAAI,CAAC,MAAO,QAAO,EAAE,SAAS,oBAAoB;AAClD,MAAI,CAAC,gBAAgB,KAAK,EAAG,QAAO,EAAE,SAAS,6EAA6E;AAC5H,QAAM,SAAS,MAAM,cAAc,OAAO,GAAG;AAC7C,MAAI,WAAW,OAAQ,QAAO;AAC9B,QAAM,WAAoC,EAAE,GAAI,UAAU,WAAW,IAAI,EAAE,GAAG,GAA0C,QAAQ,OAAO,OAAO;AAC9I,QAAMP,WAAmC,CAAC;AAC1C,aAAW,OAAO,mBAAoB,KAAI,SAAS,GAAG,MAAM,OAAW,CAAAA,SAAQ,GAAG,IAAI,SAAS,GAAG;AAClG,SAAO,EAAE,SAAAA,UAAS,MAAM,OAAO,KAAK;AACtC;AASA,eAAsB,kBAAkB,KAAgB,MAA2C;AACjG,QAAM,WAAW,UAAU,GAAG;AAC9B,MAAI,CAAC,SAAU,QAAO;AACtB,QAAM,QAAQ,MAAM,aAAa;AACjC,MAAI,CAAC,SAAS,MAAM,wBAAwB,QAAQ,EAAE,SAAS,EAAG,QAAO;AACzE,MAAI;AACF,WAAO,MAAM,qBAAqB,UAAU,SAAS,IAAI,CAAC;AAAA,EAC5D,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAQO,SAAS,eAAkD;AAChE,EAAAQ,aAAY,YAAY;AACtB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,6BAA6B;AAC7E,aAAOC,UAAS,MAAM,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,UAAU,IAAK,IAAgC;AAAA,IAC9F,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAOD;AACT;AAGO,SAAS,wBAAwB,MAAgD;AACtF,EAAAA,UAAS,SAAS,UAAU,SAAY,QAAQ,QAAQ,IAAI;AAC9D;AAaO,SAAS,gBAAgB,UAAgC,KAAyB;AACvF,SAAO,EAAE,GAAI,YAAY,CAAC,GAAI,GAAG,IAAI;AACvC;AAGO,SAAS,kBAAkB,MAAgB,WAA8B,MAAqE;AACnJ,QAAM,MAAgB,gBAAgB,IAAI;AAC1C,aAAW,KAAK,WAAW;AACzB,UAAM,IAAI,gCAAgC,KAAK,CAAC;AAChD,QAAI,CAAC,EAAG,QAAO,EAAE,OAAO,sFAAsF,CAAC,IAAI;AACnH,UAAM,QAAQ,SAAS,IAAI,cAAc,IAAI,EAAE,GAAI,IAAI,eAA4B,IAAI,CAAC;AACxF,UAAM,EAAE,CAAC,CAAE,IAAI,EAAE,MAAM,EAAE,CAAC,GAAI,GAAI,EAAE,CAAC,IAAI,EAAE,QAAQ,OAAO,EAAE,CAAC,CAAC,EAAE,IAAI,CAAC,EAAG;AACxE,QAAI,iBAAiB;AAAA,EACvB;AACA,aAAW,KAAK,MAAM;AACpB,UAAM,IAAI,+BAA+B,KAAK,CAAC;AAC/C,QAAI,CAAC,EAAG,QAAO,EAAE,OAAO,uEAAuE,CAAC,IAAI;AACpG,QAAI,EAAE,CAAC,CAAE,IAAI,EAAE,CAAC;AAAA,EAClB;AACA,SAAO,EAAE,UAAU,IAAI;AACzB;AAGA,SAAS,QAAQ,MAAgB,MAAsE;AACrG,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,MAAM;AACpB,WAAK,KAAK,KAAK,CAAC,CAAE;AAClB;AAAA,IACF;AACA,UAAM,IAAI,KAAK,IAAI,CAAC;AACpB,QAAI,MAAM,UAAa,EAAE,WAAW,IAAI,EAAG,QAAO,EAAE,QAAQ,MAAM,MAAM,SAAS,KAAK;AACtF,WAAO,KAAK,CAAC;AACb;AAAA,EACF;AACA,SAAO,EAAE,QAAQ,MAAM,SAAS,MAAM;AACxC;AAEA,SAASE,cAAa,KAAa,MAAwB;AACzD,QAAM,MAAMH,WAAUL,eAAaG,OAAK,KAAK,IAAI,GAAG,MAAM,CAAC;AAC3D,MAAI,CAAC,SAAS,GAAG,EAAG,OAAM,IAAI,MAAM,GAAG,IAAI,oBAAoB;AAC/D,SAAO;AACT;AAGA,eAAsBL,SAAQ,MAAgB,MAAe,OAAkB,IAA8B;AAC3G,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,QAAM,OAAO,CAAC,QAAQ,OAAO,UAAU,QAAQ,UAAU,aAAa,UAAU;AAChF,MAAI,CAAC,OAAO,CAAC,KAAK,SAAS,GAAG,EAAG,QAAO,MAAM,wBAAwB,KAAK,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AAClG,QAAM,QAAQ,MAAM,aAAa;AACjC,MAAI,CAAC,MAAO,QAAO,MAAM,GAAG,mBAAmB,qGAAqG,OAAO,EAAE;AAC7J,QAAM,OAAO,CAAC,UAAmCW,WAA0B;AACzE,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,WAAW,GAAG,IAAI,GAAG,SAAS,CAAC,CAAC;AAAA,QACtE,YAAW,KAAKA,OAAO,IAAG,IAAI,CAAC;AAAA,EACtC;AACA,MAAI;AACF,YAAQ,KAAK;AAAA,MACX,KAAK;AACH,eAAO,MAAM,YAAY,OAAO,MAAM,MAAM,OAAO,EAAE;AAAA,MACvD,KAAK;AACH,eAAO,MAAM,gBAAgB,OAAO,MAAM,MAAM,OAAO,EAAE;AAAA,MAC3D,KAAK;AACH,eAAO,MAAM,iBAAiB,OAAO,MAAM,MAAM,OAAO,EAAE;AAAA,MAC5D;AACE,eAAO,MAAM,eAAe,OAAO,KAAK,MAAM,MAAM,OAAO,EAAE;AAAA,IACjE;AAAA,EACF,SAAS,GAAG;AACV,OAAG,IAAI,GAAG,OAAO,YAAY,GAAG,KAAM,EAAY,OAAO,EAAE;AAC3D,WAAO,MAAM;AAAA,EACf;AACF;AAKA,eAAe,qBAAqB,KAAa,OAA8H;AAC7K,QAAM,OAAO,4BAA4B,KAAK;AAC9C,MAAI;AACF,UAAMC,WAAU,cAAcP,OAAK,KAAK,cAAc,CAAC;AACvD,UAAM,IAA6B,MAAM,OAAO,cAAcO,SAAQ,QAAQ,IAAI,CAAC,EAAE;AACrF,WAAO,OAAO,EAAE,4BAA4B,aAAc,EAAE,0BAAoC;AAAA,EAClG,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEA,eAAe,YAAY,OAAqB,MAAgB,MAAY,OAAkB,IAA8B;AAC1H,QAAM,YAAY,SAAS,MAAM,SAAS;AAC1C,MAAI,UAAU,QAAS,QAAO,MAAM,2CAA2C,OAAO,EAAE;AACxF,QAAM,QAAQ,UAAU,KAAK,OAAO,CAAC,MAAM,MAAM,WAAW;AAC5D,MAAI,MAAM,OAAQ,QAAO,MAAM,8BAA8B,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACzF,QAAM,SAAS,UAAU,KAAK,SAAS,WAAW;AAClD,QAAM,QAAS,UAAU,SAAS;AAClC,MAAI,CAAE,OAA6B,SAAS,KAAK,EAAG,QAAO,MAAM,WAAW,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACjI,QAAM,WAAW,MAAM,qBAAqB,GAAG,KAAK,KAAK;AACzD,MAAI,CAAC,UAAU;AACb,WAAO,MAAM,iFAAiF,KAAK,4GAA4G,OAAO,EAAE;AAAA,EAC1N;AACA,QAAM,OAAO,SAAS,EAAE,OAAO,cAAc,CAAC;AAC9C,QAAM,OAAOP,OAAK,GAAG,KAAK,KAAK,IAAI;AACnC,QAAM,SAASJ,aAAW,IAAI,IAAIC,eAAa,MAAM,MAAM,IAAI;AAC/D,QAAM,SAAS,WAAW,KAAK,UAAU,cAAc;AACvD,MAAI,CAAC,UAAU,WAAW,WAAW;AACnC,UAAM,EAAE,WAAAW,WAAU,IAAI,MAAM,OAAO,SAAS;AAC5C,IAAAA,WAAUT,UAAQ,IAAI,GAAG,EAAE,WAAW,KAAK,CAAC;AAC5C,IAAAD,eAAc,MAAM,KAAK,OAAO;AAAA,EAClC;AACA,OAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,OAAO,MAAM,KAAK,MAAM,QAAQ,QAAQ,OAAO,KAAK,MAAM,GAAG;AAAA,IAClG,GAAG,OAAO,kBAAkB,KAAK,IAAI,IAAI,UAAU,WAAW,YAAY,qBAAqB,MAAM;AAAA,IACrG,GAAG,KAAK,MAAM,IAAI,CAAC,MAAM,YAAY,CAAC,EAAE;AAAA,EAC1C,CAAC;AACD,SAAO,MAAM;AACf;AAEA,eAAe,gBAAgB,OAAqB,MAAgB,MAAY,OAAkB,IAA8B;AAC9H,QAAM,UAAU,SAAS,MAAM,OAAO;AACtC,MAAI,QAAQ,WAAW,QAAQ,KAAK,OAAQ,QAAO,MAAM,8CAA8C,OAAO,EAAE;AAChH,QAAM,MAAM,QAAQ,SAAS,GAAG,IAAI,cAAc,GAAG,IAAI;AACzD,MAAI,CAAC,IAAK,QAAO,MAAM,oEAAoE,OAAO,EAAE;AACpG,QAAM,SAAS,MAAM,cAAc,OAAO,GAAG,GAAG;AAChD,MAAI,WAAW,OAAQ,QAAO,MAAM,OAAO,OAAO,OAAO,EAAE;AAC3D,QAAM,IAAI,MAAM,MAAM,gBAAgB,QAAQ,EAAE,QAAQ,OAAO,QAAQ,IAAI,OAAO,IAAI,IAAI,GAAG,EAAE,KAAK,GAAG,KAAK,OAAO,cAAc,CAAC;AAClI,OAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,OAAO,MAAM,QAAQ,OAAO,QAAQ,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,OAAO,GAAG;AAAA,IACvH,GAAG,OAAO,2BAA2B,OAAO,IAAI,SAAS,OAAO,MAAM,YAAY,IAAI,MAAM,GAAG,CAAC,CAAC,UAAU,EAAE,MAAM;AAAA,EACrH,CAAC;AACD,SAAO,MAAM;AACf;AAGA,eAAsB,cAAc,OAAqB,KAAkD;AACzG,QAAM,OAAO,WAAW,GAAG;AAC3B,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,qBAAqB,GAAG,eAAe;AAClE,QAAM,WAAW,UAAU,WAAW,IAAI,EAAE,GAAG;AAC/C,MAAI,CAAC,SAAU,QAAO,EAAE,OAAO,GAAG,IAAI,sBAAsB;AAC5D,QAAM,WAAW,MAAM,wBAAwB,QAAQ;AACvD,MAAI,SAAS,OAAQ,QAAO,EAAE,OAAO,SAAS,KAAK,IAAI,EAAE;AACzD,SAAO,MAAM,qBAAqB,UAAU,SAASC,UAAQ,IAAI,CAAC,CAAC;AACrE;AAEA,eAAe,eAAe,OAAqB,KAAa,MAAgB,MAAY,OAAkB,IAA8B;AAC1I,QAAM,OAAO,MAAM,iBAAiB,EAAE,KAAK,GAAG,IAAI,CAAC;AACnD,QAAM,SAAS,SAAS,MAAM,MAAM;AACpC,MAAI,OAAO,QAAS,QAAO,MAAM,qBAAqB,OAAO,EAAE;AAC/D,QAAM,SAAS,OAAO,KAAK,SAAS,WAAW;AAC/C,QAAM,OAAqB,EAAE,SAAS,SAAS,UAAU,yBAAyB,GAAI,OAAO,QAAQ,EAAE,IAAI,OAAO,MAAM,IAAI,CAAC,GAAI,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,EAAG;AAC/J,QAAM,WAAW,SAAS,CAAC,IAAI,CAAC,wEAAwE;AACxG,MAAI,OAAO,OAAO,KAAK,OAAO,CAAC,MAAM,MAAM,WAAW;AAEtD,MAAI,QAAQ,QAAQ;AAClB,QAAI,KAAK,OAAQ,QAAO,MAAM,8BAA8B,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACvF,UAAM,UAAU,MAAM,MAAM,mBAAmB,MAAM,EAAE,UAAU,wBAAwB,CAAC;AAC1F,SAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,QAAQ,GAAG,QAAQ,SAAS,QAAQ,IAAI,CAAC,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,WAAW,UAAU,KAAK,KAAK,UAAU,EAAE,QAAQ,CAAC,GAAG,EAAE,QAAQ,SAAS,aAAa,EAAE,QAAQ,KAAK,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,CAAC,iCAAiC,CAAC;AAC/P,WAAO,MAAM;AAAA,EACf;AACA,MAAI,QAAQ,UAAU;AACpB,QAAI,KAAK,WAAW,EAAG,QAAO,MAAM,4CAA4C,OAAO,EAAE;AACzF,UAAMU,KAAI,MAAM,MAAM,mBAAmB,MAAM,KAAK,CAAC,GAAI,IAAI;AAC7D,SAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,GAAGA,IAAG,OAAO,GAAG,CAAC,GAAG,OAAO,oBAAoB,KAAK,CAAC,CAAC,IAAIA,GAAE,MAAM,KAAKA,GAAE,EAAE,KAAK,GAAG,QAAQ,CAAC;AACnI,WAAO,MAAM;AAAA,EACf;AACA,MAAI,QAAQ,UAAU;AACpB,QAAI,KAAK,WAAW,EAAG,QAAO,MAAM,0DAA0D,OAAO,EAAE;AACvG,UAAM,MAAMJ,cAAa,GAAG,KAAK,KAAK,CAAC,CAAE;AACzC,UAAM,WAAW,SAAS,IAAI,QAAQ,IAAK,IAAI,WAAwC,CAAC;AACxF,UAAMK,WAAU,SAAS,IAAI,OAAO,IAAK,IAAI,UAAuC;AACpF,UAAM,UAAU,MAAM,MAAM,oBAAoB,MAAM,EAAE,GAAI,SAAS,IAAI,QAAQ,IAAI,EAAE,UAAU,IAAI,SAAS,IAAI,CAAC,GAAI,UAAU,GAAIA,WAAU,EAAE,SAAAA,SAAQ,IAAI,CAAC,EAAG,GAAG,IAAI;AACxK,SAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,SAAS,OAAO,GAAG,CAAC,GAAG,QAAQ,IAAI,CAACD,OAAM,GAAG,OAAO,oBAAoBA,GAAE,KAAK,IAAIA,GAAE,MAAM,KAAKA,GAAE,EAAE,GAAG,GAAG,GAAG,QAAQ,CAAC;AAC7J,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,OAAO,SAAS,MAAM,QAAQ;AACpC,QAAM,YAAY,QAAQ,KAAK,MAAM,YAAY;AACjD,QAAM,OAAO,QAAQ,UAAU,MAAM,OAAO;AAC5C,QAAM,UAAU,QAAQ,KAAK,MAAM,UAAU;AAC7C,MAAI,KAAK,WAAW,UAAU,WAAW,KAAK,WAAW,QAAQ,QAAS,QAAO,MAAM,4DAA4D,OAAO,EAAE;AAC5J,SAAO,YAAY,QAAQ,IAAI;AAC/B,MAAI,KAAK,WAAW,KAAK,QAAQ,KAAK,WAAW,EAAG,QAAO,MAAM,qEAAqE,OAAO,EAAE;AAC/I,QAAM,QAAQ,KAAK,CAAC;AACpB,QAAM,QAAQ,UAAU,aAAc,aAAwB;AAC9D,QAAM,WAAW,MAAM,MAAM,mBAAmB,MAAM,EAAE,SAAS,KAAK,CAAC,GAAG,KAAK,CAAC,MAAO,UAAU,aAAa,EAAE,UAAU,aAAa,EAAE,YAAY,KAAM;AAC3J,QAAM,WAAW,KAAK,QAAQJ,cAAa,GAAG,KAAK,KAAK,KAAK,IAAI,CAAC;AAClE,QAAM,OAAO,kBAAkB,EAAE,GAAI,SAAS,YAAY,CAAC,GAAI,GAAG,SAAS,GAAG,UAAU,QAAQ,KAAK,MAAM;AAC3G,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,EAAE,SAAS,IAAI;AACrB,QAAM,IAAI,MAAM,MAAM;AAAA,IACpB;AAAA,IACA,EAAE,OAAO,GAAI,UAAU,YAAY,EAAE,SAAS,MAAM,IAAI,CAAC,GAAI,UAAU,GAAI,QAAQ,OAAO,SAAS,EAAE,SAAS,QAAQ,OAAO,IAAI,CAAC,EAAG;AAAA,IACrI,EAAE,GAAG,MAAM,QAAQ,SAAS,UAAU,GAAG;AAAA,EAC3C;AACA,OAAK,EAAE,IAAI,MAAM,UAAU,MAAM,MAAM,GAAG,GAAG,UAAU,OAAO,GAAG,CAAC,GAAG,OAAO,iBAAiB,KAAK,IAAI,EAAE,MAAM,KAAK,EAAE,EAAE,KAAK,GAAI,EAAE,WAAW,cAAc,CAAC,IAAI,QAAS,CAAC;AAC1K,SAAO,MAAM;AACf;AAOO,SAAS,qBAAqB,UAA8B,UAAwC;AACzG,QAAM,MAAiB,WAAW,YAAY,QAAQ,EAAE,MAAM,CAAC;AAC/D,QAAM,UAAU,gBAAgB,KAAK,CAAC,MAAM,KAAK,YAAY,KAAK,UAAU,IAAI,CAAC,CAAC,MAAM,KAAK,UAAU,SAAS,CAAC,CAAC,CAAC;AACnH,MAAI,CAAC,WAAW,aAAa,OAAW,QAAO;AAC/C,QAAM,OAAkB,EAAE,GAAG,IAAI;AACjC,aAAW,KAAK,gBAAiB,KAAI,KAAK,SAAU,MAAK,CAAC,IAAI,SAAS,CAAC;AACxE,SACE,OAAO,QAAQ,IAAI,EAChB,OAAO,CAAC,CAAC,EAAE,CAAC,MAAM,MAAM,MAAS,EACjC,IAAI,CAAC,CAAC,GAAG,CAAC,MAAMJ,eAAc,GAAG,CAAU,CAAC,EAC5C,KAAK,IAAI,IAAI;AAEpB;AAGO,SAAS,iBAAiB,OAAkB,KAAyF;AAC1I,SAAO,OAAO,KAAK,WAAW;AAC5B,UAAM,OAAO,aAAa,KAAK,CAAC,MAAML,aAAWI,OAAK,KAAK,CAAC,CAAC,CAAC,KAAK;AACnE,UAAM,OAAOA,OAAK,KAAK,IAAI;AAC3B,UAAM,WAAWJ,aAAW,IAAI,IAAIC,eAAa,MAAM,MAAM,IAAI;AACjE,UAAM,OAAO,qBAAqB,UAAU,OAAO,QAAQ;AAC3D,UAAM,UAAwB,CAAC;AAC/B,QAAI,SAAS,QAAW;AACtB,cAAQ,KAAK,EAAE,MAAM,MAAM,QAAQ,aAAa,SAAY,YAAY,UAAU,CAAC;AACnF,UAAI,CAAC,OAAO,OAAQ,CAAAC,eAAc,MAAM,IAAI;AAAA,IAC9C;AACA,QAAI,OAAO,UAAU,SAAS,OAAW,QAAO;AAEhD,UAAM,EAAE,SAAAa,SAAQ,IAAI,MAAM;AAC1B,UAAM,IAAI,MAAMA,SAAQ,EAAE,KAAK,cAAc,aAAa,OAAO,QAAQ,OAAO,QAAQ,KAAK,KAAK,GAAG,OAAO,EAAE,KAAK,MAAM;AAAA,IAAC,GAAG,KAAK,MAAM;AAAA,IAAC,GAAG,KAAK,KAAK,IAAI,CAAC;AAC3J,eAAW,KAAK,EAAE,OAAO;AACvB,UAAI,EAAE,WAAW,aAAa,CAAC,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,EAAE,IAAI,EAAG,SAAQ,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQf,aAAWI,OAAK,KAAK,EAAE,IAAI,CAAC,IAAI,YAAY,UAAU,CAAC;AACnK,UAAI,EAAE,WAAW,SAAU,OAAM,IAAI,MAAM,mBAAmB,OAAO,GAAG,KAAK,EAAE,IAAI,IAAI,EAAE,QAAQ,QAAQ,EAAE;AAAA,IAC7G;AACA,QAAI,CAAC,EAAE,GAAI,OAAM,IAAI,MAAM,mBAAmB,OAAO,GAAG,KAAK,EAAE,MAAM,GAAG,EAAE,KAAK,QAAQ,EAAE;AACzF,WAAO;AAAA,EACT;AACF;AAEA,eAAe,iBAAiB,OAAqB,MAAgB,MAAY,OAAkB,IAA8B;AAC/H,QAAM,cAAc,SAAS,MAAM,WAAW;AAC9C,MAAI,YAAY,QAAS,QAAO,MAAM,mCAAmC,OAAO,EAAE;AAClF,QAAM,QAAQ,YAAY,KAAK,OAAO,CAAC,MAAM,MAAM,SAAS;AAC5D,MAAI,MAAM,OAAQ,QAAO,MAAM,mCAAmC,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AAC9F,QAAM,OAAO,YAAY,KAAK,SAAS,SAAS,IAAK,UAAqB;AAC1E,QAAM,UAAU,MAAM,MAAM,mBAAmB,MAAM,iBAAiB,EAAE,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,UAAU,wBAAwB,CAAC;AAC7H,QAAM,EAAE,UAAU,SAAS,IAAI,MAAM,cAAc,OAAO;AAC1D,QAAM,OAAO,OAAO,QAAQ,QAAQ,EAAE,IAAI,CAAC,CAAC,KAAK,GAAG,OAAO,EAAE,KAAK,UAAU,gBAAgB,UAAU,GAAG,EAAE,EAAE;AAC7G,QAAM,WAAW,MAAM,MAAM,kBAAkB,MAAM;AAAA,IACnD;AAAA,IACA,OAAO;AAAA,IACP,UAAU,iBAAiB,OAAO,GAAG,GAAG;AAAA,IACxC,KAAK,GAAG;AAAA,IACR,GAAI,YAAY,QAAQ,EAAE,SAAS,YAAY,MAAM,IAAI,CAAC;AAAA,EAC5D,CAAC;AACD,QAAM,SAAS,SAAS,KAAK,CAAC,MAAM,EAAE,WAAW,QAAQ;AACzD,QAAM,OAAO,SAAS,MAAM,SAAS,MAAM;AAC3C,OAAK,EAAE,IAAI,CAAC,QAAQ,UAAU,MAAM,MAAM,SAAS,GAAG,MAAM,kBAAkB,UAAU,IAAI,EAAE,MAAM,IAAI,CAAC;AACzG,SAAO;AACT;AAjeA,IAsDa,iBAGA,qBA0FP,oBA0CAI,WAEFD,SAsBS;AArNb,IAAAS,gBAAA;AAAA;AAAA;AA2CA;AACA;AACA;AACA;AAEA;AACA;AACA;AAIO,IAAM,kBAAkB,CAAC,QAAQ,YAAY,kBAAkB,UAAU,UAAU,OAAO;AAG1F,IAAM,sBACX;AAyFF,IAAM,qBAAqB,CAAC,QAAQ,MAAM,SAAS,UAAU,eAAe,mBAAmB,OAAO,SAAS;AA0C/G,IAAMR,YAAW,CAAC,0BAA0B,mBAAmB,mBAAmB;AAwB3E,IAAM,0BAAqC,CAAC,QAAQ,UAAU,aAAa;AAChF,YAAM,MAAgB,CAAC;AACvB,iBAAW,OAAO,OAAO,KAAK,QAAQ,GAAG;AACvC,YAAI,CAAE,gBAAsC,SAAS,GAAG,EAAG,KAAI,KAAK,GAAG,GAAG,8CAA8C,gBAAgB,KAAK,IAAI,CAAC,EAAE;AAAA,MACtJ;AACA,iBAAW,KAAK,YAAY,EAAE,KAAK,SAAS,CAAC,EAAG,KAAI,EAAE,aAAa,QAAS,KAAI,KAAK,GAAG,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC5G,aAAO;AAAA,IACT;AAAA;AAAA;;;ACxMA,SAAS,cAAAS,cAAY,gBAAAC,sBAAoB;AACzC,SAAS,QAAAC,cAAY;AAuCd,SAAS,SAAS,MAAgB,MAAoE;AAC3G,QAAM,KAAK,KAAK,QAAQ,IAAI;AAC5B,MAAI,KAAK,EAAG,QAAO,EAAE,MAAM,MAAM,SAAS,MAAM;AAChD,QAAM,QAAQ,KAAK,KAAK,CAAC;AACzB,MAAI,UAAU,UAAa,MAAM,WAAW,IAAI,EAAG,QAAO,EAAE,MAAM,MAAM,SAAS,KAAK;AACtF,SAAO,EAAE,OAAO,MAAM,CAAC,GAAG,KAAK,MAAM,GAAG,EAAE,GAAG,GAAG,KAAK,MAAM,KAAK,CAAC,CAAC,GAAG,SAAS,MAAM;AACtF;AAGO,SAAS,YAAY,MAA0B;AACpD,QAAM,MAAgB,CAAC;AACvB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,IAAI,KAAK,CAAC;AAChB,QAAI,EAAE,WAAW,GAAG,GAAG;AACrB,UAAI,OAAO,IAAI,CAAC,EAAG;AACnB;AAAA,IACF;AACA,QAAI,KAAK,CAAC;AAAA,EACZ;AACA,SAAO;AACT;AAEA,eAAsB,UAAU,MAAc,OAAkB,IAAa,KAAgE;AAC3I,QAAM,QAAQ,MAAM,aAAa;AACjC,MAAI,CAAC,OAAO;AACV,OAAG,IAAI,GAAG,OAAO,KAAK,kBAAkB,IAAI,CAAC,EAAE;AAC/C,WAAO,MAAM;AAAA,EACf;AACA,SAAO,IAAI,KAAK;AAClB;AAGO,SAAS,YAAY,MAAgB,OAAkB,IAA8B;AAC1F,SAAO,UAAU,GAAG,OAAO,IAAI,KAAK,CAAC,CAAC,IAAI,OAAO,IAAI,CAAC,UAAU,MAAM,kBAAkB,MAAM,aAAa,CAAC;AAC9G;AASA,eAAsB,MAAM,MAAgB,MAAe,OAAkB,IAA8B;AACzG,QAAM,OAAO,SAAS,MAAM,QAAQ;AACpC,MAAI,KAAK,QAAS,QAAO,MAAM,uBAAuB,OAAO,EAAE;AAC/D,QAAM,OAAO,SAAS,KAAK,MAAM,QAAQ;AACzC,MAAI,KAAK,QAAS,QAAO,MAAM,yBAAyB,OAAO,EAAE;AACjE,QAAM,IAAI,YAAY,GAAG,KAAK,KAAK,KAAK;AACxC,MAAI,CAAC,EAAE,IAAI;AACT,eAAW,QAAQ,EAAE,MAAO,IAAG,IAAI,IAAI;AACvC,WAAO,MAAM;AAAA,EACf;AACA,MAAI,CAAC,KAAM,YAAW,QAAQ,EAAE,MAAO,IAAG,IAAI,IAAI;AAClD,QAAM,KAAK,KAAK,SAAS,GAAG,IAAI;AAChC,MAAI,CAAC,GAAI,QAAO,MAAM,qJAAqJ,OAAO,EAAE;AACpL,QAAM,UAAU,YAAY,KAAK,IAAI;AACrC,QAAM,SAAS,SAAS,KAAK,MAAM,UAAU;AAC7C,QAAM,OAAO,CAAC,MAAM,SAAS,UAAU,IAAI,GAAG,SAAS,GAAI,OAAO,QAAQ,CAAC,YAAY,OAAO,KAAK,IAAI,CAAC,GAAI,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AACvI,SAAO,UAAU,GAAG,OAAO,kBAAkB,OAAO,IAAI,CAAC,UAAU,MAAM,kBAAkB,MAAM,aAAa,CAAC;AACjH;AAWA,eAAsB,QAAQ,MAAgB,MAAe,OAAkB,IAA8B;AAE3G,QAAM,WAAW,KAAK,SAAS,UAAU;AAEzC,QAAM,YAAY,CAAC,aAAa,qBAAqB,EAAE,OAAO,CAAC,MAAM,KAAK,SAAS,CAAC,CAAC;AACrF,MAAI,KAAK,SAAS,qBAAqB,KAAK,CAAC,SAAU,QAAO,MAAM,8GAA8G,OAAO,EAAE;AAC3L,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,QAAI,KAAK,CAAC,MAAM,eAAe,KAAK,IAAI,CAAC,MAAM,UAAa,KAAK,IAAI,CAAC,EAAG,WAAW,GAAG,GAAI,QAAO,MAAM,mCAAmC,OAAO,EAAE;AAAA,EACtJ;AACA,QAAM,YAAY,SAAS,MAAM,SAAS;AAC1C,MAAI,UAAU,QAAS,QAAO,MAAM,8BAA8B,OAAO,EAAE;AAC3E,QAAM,OAAO,SAAS,UAAU,MAAM,QAAQ;AAC9C,QAAM,KAAK,SAAS,KAAK,MAAM,MAAM;AACrC,MAAI,KAAK,WAAW,GAAG,QAAS,QAAO,MAAM,GAAG,KAAK,UAAU,WAAW,MAAM,kBAAkB,OAAO,EAAE;AAC3G,QAAM,QAAQ,YAAY,GAAG,IAAI;AACjC,MAAI,MAAM,SAAS,KAAM,MAAM,WAAW,KAAK,UAAU,MAAQ,QAAO,MAAM,2BAA2B,OAAO,EAAE;AAClH,QAAM,QAAQ,UAAU,SAAS,MAAM,CAAC;AACxC,QAAM,KAAK,KAAK,SAAS,GAAG,IAAI;AAChC,QAAM,SAAS,GAAG,SAAS,GAAG,IAAI;AAClC,MAAI,CAAC,GAAI,QAAO,MAAM,wEAAwE,OAAO,EAAE;AACvG,MAAI,CAAC,OAAQ,QAAO,MAAM,0FAA0F,OAAO,EAAE;AAE7H,QAAM,eAAe,IAAI,IAAI,GAAG,KAAK,OAAO,CAAC,GAAG,MAAM,GAAG,KAAK,IAAI,CAAC,MAAM,UAAU,CAAC;AACpF,QAAM,OAAO,GAAG,KAAK,OAAO,CAAC,MAAM,MAAM,SAAS,aAAa,IAAI,CAAC,CAAC;AACrE,QAAM,OAAO,KAAK,SAAS,QAAQ,IAAI,CAAC,IAAI,CAAC,UAAU,OAAO;AAC9D,QAAM,OAAO,CAAC,cAAc,WAAW,UAAU,IAAI,QAAQ,QAAQ,GAAG,MAAM,GAAI,QAAQ,CAAC,YAAY,KAAK,IAAI,CAAC,GAAI,GAAG,MAAM,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AACzJ,SAAO,UAAU,GAAG,OAAO,YAAY,OAAO,IAAI,OAAO,UAAU;AACjE,QAAI,YAAY,CAAC,aAAa,KAAK,EAAG,QAAO,MAAM,4BAA4B,OAAO,EAAE;AACxF,QAAI,UAAU,UAAU,EAAE,MAAM,UAAU,GAAG,UAAW,QAAO,MAAM,sBAAsB,SAAS,GAAG,OAAO,EAAE;AAChH,WAAO,MAAM,kBAAkB,MAAM,aAAa;AAAA,EACpD,CAAC;AACH;AAGO,SAAS,sBAAsB,OAAkC;AACtE,SAAO,GAAG,MAAM,KAAK,OAAO,CAAC,IAAI,MAAM,WAAW,IAAI,UAAU,MAAM,iCAAiC,MAAM,WAAW,IAAI,OAAO,MAAM;AAC3I;AAaO,SAAS,cAAc,KAAsB;AAClD,QAAM,OAAOA,OAAK,KAAK,mBAAmB,GAAG,OAAO,YAAY;AAChE,SAAOF,aAAW,IAAI,IAAI,KAAK,MAAMC,eAAa,MAAM,MAAM,CAAC,IAAI;AACrE;AAGO,SAAS,cAAc,KAAgB,OAAkB,OAAqG;AACnK,QAAM,mBAAmB,YAAY,GAAG,MAAM;AAE9C,QAAME,SAAQ,QAAQ,GAAG,EAAE,SAAS,aAAa,UAAU,WAAY,SAAmB;AAE1F,QAAM,UAAU,CAAC,oBAAoB,UAAU;AAC/C,QAAMC,QAAuB,CAAC,MAAM;AACpC,MAAI,oBAAoB,QAAS,CAAAA,MAAK,KAAK,OAAO;AAClD,MAAID,OAAO,CAAAC,MAAK,KAAK,QAAQ,QAAQ;AACrC,SAAO,EAAE,MAAAA,OAAM,kBAAkB,OAAO,SAAS,GAAID,SAAQ,EAAE,OAAAA,OAAM,IAAI,CAAC,EAAG;AAC/E;AAWA,eAAsB,GAAG,MAAgB,MAAe,OAAkB,IAA8B;AACtG,QAAM,YAAY,SAAS,MAAM,SAAS;AAC1C,QAAM,UAAU,SAAS,UAAU,MAAM,OAAO;AAChD,QAAM,UAAU,SAAS,QAAQ,MAAM,UAAU;AACjD,MAAI,UAAU,WAAW,QAAQ,WAAW,QAAQ,QAAS,QAAO,MAAM,iDAAiD,OAAO,EAAE;AACpI,QAAM,QAAQ,QAAQ,KAAK,OAAO,CAAC,MAAM,MAAM,WAAW;AAC1D,MAAI,MAAM,OAAQ,QAAO,MAAM,oBAAoB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AAC/E,QAAM,SAAS,QAAQ,KAAK,SAAS,WAAW;AAEhD,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,CAAC,KAAM,QAAO,MAAM,qBAAqB,GAAG,GAAG,sBAAsB,OAAO,gBAAgB,OAAO,EAAE;AACzG,QAAME,UAAS,WAAW,IAAI;AAC9B,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,WAAO,MAAM;AAAA,EACf;AACA,QAAM,aAAcA,QAAO,IAAI,OAAyC;AACxE,QAAM,QAAS,UAAU,SAAS,cAAc;AAChD,MAAI,CAAE,OAA6B,SAAS,KAAK,EAAG,QAAO,MAAM,WAAW,KAAK,kBAAkB,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,EAAE;AACjI,QAAM,MAAM,QAAQ,SAAS;AAC7B,QAAM,SAAS,QAAQ,SAAS,cAAc,KAAK;AAEnD,SAAO,UAAU,GAAG,OAAO,OAAO,OAAO,IAAI,OAAO,UAAU;AAC5D,UAAMC,gBAAe,MAAM,kBAAkB;AAC7C,QAAID,QAAO,IAAI,kBAAkB,UAAa,CAACC,cAAc,IAAG,IAAI,GAAG,OAAO,KAAK,wBAAwB,EAAE;AAC7G,QAAI,YAAYD,QAAO,GAAG,MAAM,gBAAgB;AAC9C,YAAM,OAAO,oBAAoB,OAAOA,QAAO,GAAG;AAClD,UAAI,KAAM,IAAG,IAAI,GAAG,OAAO,KAAK,IAAI,EAAE;AAAA,IACxC;AACA,QAAI;AACJ,QAAI;AACF,cAAQ,cAAc,GAAG,GAAG;AAAA,IAC9B,SAAS,GAAG;AACV,aAAO,MAAM,mBAAmB,OAAO,eAAgB,EAAY,OAAO,IAAI,OAAO,EAAE;AAAA,IACzF;AAEA,UAAM,WAAW,gBAAgBA,OAAM,EAAE;AACzC,UAAM,EAAE,WAAAE,YAAW,cAAAC,eAAc,iBAAAC,iBAAgB,IAAI,MAAM;AAC3D,UAAM,SAAS,MAAMF,WAAU,QAAQ;AACvC,eAAW,QAAQ,OAAO,MAAO,IAAG,IAAI,GAAG,OAAO,KAAK,IAAI,EAAE;AAC7D,QAAI,UAAU,UAAa,SAAS,MAAM;AACxC,UAAI;AACF,gBAAQE,iBAAgB,OAAkC,SAAS,MAAM,OAAO,EAAE,aAAa,MAAMD,cAAa,EAAE,CAAC;AAAA,MACvH,SAAS,GAAG;AACV,WAAG,IAAI,GAAG,OAAO,KAAM,EAAY,OAAO,EAAE;AAC5C,eAAO,MAAM;AAAA,MACf;AAAA,IACF;AAEA,UAAM,EAAE,mBAAAE,mBAAkB,IAAI,MAAM;AACpC,UAAM,cAAc,MAAMA,mBAAkBL,QAAO,KAAK,GAAG,GAAG;AAC9D,QAAI;AACJ,QAAI;AACF,aAAO,aAAa,OAAOA,QAAO,KAAK,OAAO,KAAK,OAAO,CAAC,GAAG,EAAE,cAAAC,eAAc,QAAQ,MAAM,MAAM,UAAU,GAAG,GAAI,cAAc,EAAE,SAAS,YAAY,IAAI,CAAC,EAAG,CAAC;AAAA,IACnK,SAAS,GAAG;AACV,SAAG,IAAI,GAAG,OAAO,KAAM,EAAY,OAAO,EAAE;AAC5C,aAAO,MAAM;AAAA,IACf;AACA,UAAM,EAAE,MAAAF,MAAK,IAAI;AACjB,eAAW,QAAQ,KAAK,MAAO,IAAG,IAAI,GAAG,OAAO,KAAK,IAAI,EAAE;AAG3D,UAAM,EAAE,cAAAO,cAAa,IAAI,MAAM;AAC/B,UAAMC,WAAUR,MAAK,QAAQ,MAAMO,cAAa,GAAG,GAAG,IAAK,EAAE,MAAM,KAAK;AACxE,QAAI,WAAWC,UAAS;AACtB,SAAG,IAAI,GAAG,OAAO,cAAcA,SAAQ,KAAK,EAAE;AAC9C,aAAO,MAAM;AAAA,IACf;AACA,UAAM,WAAWR,MAAK,SAAS,aAAaQ,WAAU,EAAE,GAAGR,MAAK,OAAO,MAAM,EAAE,GAAIA,MAAK,MAAM,MAAkC,SAASQ,SAAQ,QAAQ,EAAE,IAAIR,MAAK;AACpK,UAAM,UAAU;AAAA,MACd;AAAA,MACA;AAAA,MACA;AAAA,MACA,MAAMA,MAAK,KAAK;AAAA,MAChB,MAAMA,MAAK,KAAK;AAAA,MAChB,GAAIA,MAAK,SAAS,EAAE,QAAQA,MAAK,OAAO,QAAQ,IAAI,CAAC;AAAA,MACrD,GAAIA,MAAK,mBAAmB,EAAE,kBAAkBA,MAAK,iBAAiB,QAAQ,IAAI,CAAC;AAAA,MACnF,UAAUA,MAAK;AAAA,MACf,GAAIA,MAAK,QAAQ,EAAE,OAAO,EAAE,UAAUA,MAAK,MAAM,UAAU,MAAMA,MAAK,MAAM,KAAK,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,GAAG,CAAC,EAAE,EAAE,IAAI,CAAC;AAAA,MACxH,GAAI,aAAaQ,WAAU,EAAE,SAASA,SAAQ,KAAK,IAAI,CAAC;AAAA,IAC1D;AACA,QAAI,QAAQ,OAAQ,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,IAAI,MAAM,UAAU,MAAM,MAAM,QAAQ,GAAG,QAAQ,CAAC,CAAC;AAAA,aACvG,CAAC,MAAM;AACd,SAAG,IAAI,GAAG,OAAO,QAAQ,KAAK,gBAAgB,MAAM,SAAS,GAAG,EAAE;AAClE,SAAG,IAAI,eAAe,QAAQ,IAAI,EAAE;AACpC,SAAG,IAAI,eAAe,QAAQ,IAAI,EAAE;AACpC,UAAI,QAAQ,OAAQ,IAAG,IAAI,eAAe,QAAQ,MAAM,EAAE;AAC1D,UAAI,QAAQ,iBAAkB,IAAG,IAAI,eAAe,QAAQ,gBAAgB,EAAE;AAC9E,UAAI,KAAK,KAAK,KAAK,QAAS,IAAG,IAAI,+EAA+E;AAClH,iBAAW,CAAC,SAAS,IAAI,KAAK,OAAO,QAAQR,MAAK,QAAQ,EAAG,IAAG,IAAI,eAAe,IAAI,KAAK,OAAO,GAAG;AACtG,iBAAW,OAAO,QAAQ,OAAO,QAAQ,CAAC,EAAG,IAAG,IAAI,eAAe,GAAG,EAAE;AACxE,UAAIA,MAAK,MAAO,IAAG,IAAI,eAAeA,MAAK,MAAM,OAAO,sCAAsC;AAAA,IAChG;AACA,QAAI,CAAC,QAAQ,aAAaQ,SAAS,IAAG,IAAI,0CAA0CA,SAAQ,IAAI,sBAAsB;AAAA,aAC7G,CAAC,QAAQ,aAAaA,SAAS,IAAG,IAAI,qDAAqDA,SAAQ,OAAO,iDAAiD,OAAO,oBAAoB;AAC/L,QAAI,OAAQ,QAAO,MAAM;AAEzB,UAAM,UAAU,MAAM,cAAc,OAAO,EAAE,MAAM,GAAG,KAAK,OAAO,QAAQ,MAAM,KAAK,MAAM,OAAO,KAAK,SAAS,aAAa,KAAK,KAAK,KAAK,QAAQ,CAAC;AACrJ,QAAI,CAAC,QAAQ,QAAQ,KAAK,OAAQ,IAAG,IAAI,yBAAyB,QAAQ,KAAK,KAAK,IAAI,CAAC,EAAE;AAC3F,QAAI,QAAQ,SAAS,MAAM,KAAM,YAAW,QAAQ,aAAa,MAAM,QAAQ,IAAI,EAAG,IAAG,IAAI,GAAG,OAAO,KAAK,IAAI,EAAE;AAClH,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,IAAI,QAAQ,SAAS,GAAG,UAAU,QAAQ,MAAM,QAAQ,GAAG,SAAS,QAAQ,QAAQ,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAAC;AAClK,QAAI,QAAQ,SAAS,MAAM,MAAM;AAC/B,UAAI,CAAC,KAAM,IAAG,IAAI,GAAG,OAAO,iCAAiC,QAAQ,IAAI,iBAAiB,MAAM,2CAA2C;AAC3I,aAAO,QAAQ;AAAA,IACjB;AACA,UAAM,YAAY,WAAW,MAAM,cAAc,OAAO,OAAO,UAAU,KAAK,OAAO,OAAO,EAAE,IAAI,MAAM;AACxG,QAAI,cAAc,MAAM,KAAM,QAAO;AAErC,UAAM,YAAY,MAAM,eAAe,OAAO,OAAOP,QAAO,KAAK,KAAK,OAAO,OAAO,IAAI,GAAG;AAC3F,QAAI,cAAc,MAAM,KAAM,QAAO;AAErC,UAAM,aAAa,MAAM,gBAAgB,OAAO,OAAOA,QAAO,KAAK,KAAK,OAAO,OAAO,EAAE;AACxF,QAAI,eAAe,MAAM,KAAM,QAAO;AAEtC,WAAO,eAAe,OAAO,OAAO,KAAKA,QAAO,KAAK,KAAK,OAAO,OAAO,EAAE;AAAA,EAC5E,CAAC;AACH;AAqBO,SAAS,aAAa,MAAwC,MAAwB;AAC3F,MAAI,CAAC,KAAK,cAAc,CAACL,aAAW,IAAI,KAAKC,eAAa,MAAM,MAAM,EAAE,SAAS,mBAAmB,EAAG,QAAO,CAAC;AAC/G,SAAO,CAAC,+HAA+H,OAAO,eAAe,OAAO,kCAAkC;AACxM;AAQO,SAAS,aACd,OACA,KACA,OACA,KACA,OACA,QAAkB,CAAC,GACnB,OAAwI,CAAC,GAC3H;AACd,QAAM,QAAQ,cAAc,KAAK,OAAO,KAAK;AAC7C,QAAM,OAAO,KAAK;AAClB,QAAM,QAAkB,CAAC;AACzB,QAAM,WAAW,gBAAgB,EAAE,IAAI,CAAC,EAAE;AAE1C,QAAM,aAAa,MAAM,eAAe;AAExC,QAAM,UAAU,eAAe,OAAO,UAAU,MAAM,kBAAkB,KAAK;AAE7E,QAAM,aAAa,MAAM,oBAAoB,SAAS,aAAc,MAAM,aAAa,SAAS,cAAc,MAAM,KAAK,uBAAuB,GAAG,UAAc;AAGjK,MAAI,WAAW,GAAG,MAAM,eAAe,MAAM,SAAS,uBAAuB,KAAK,KAAK,CAAC,kCAAkC,KAAK,EAAG,OAAM,KAAK,oBAAoB;AACjK,QAAM,QAAQ,aAAa,MAAM,IAAI;AAErC,QAAM,WAAW,MAAM,mBAAmB,aAAa,OAAO,GAAG,IAAI,CAAC;AAEtE,QAAM,iBAAiB,aAAa,KAAK;AACzC,QAAMG,QAAO,MAAM,oBAAoB,OAAO,KAAK;AAAA,IACjD;AAAA,IACA,GAAI,MAAM,mBAAmB,EAAE,kBAAkB,KAAK,IAAI,CAAC;AAAA,IAC3D,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC5C,GAAI,MAAM,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,IAC/B,GAAI,SAAS,SAAS,EAAE,eAAe,SAAS,CAAC,EAAG,MAAM,GAAG,EAAE,IAAI,CAAC;AAAA,IACpE,GAAI,iBAAiB,EAAE,gBAAgB,KAAK,IAAI,CAAC;AAAA;AAAA,IAEjD,GAAI,KAAK,YAAY,SAAY,EAAE,SAAS,EAAE,QAAQ,KAAK,QAAQ,EAAE,IAAI,CAAC;AAAA;AAAA,IAE1E,GAAI,KAAK,QAAQ,WAAW,CAAC;AAAA,IAC7B,GAAI,aAAa,EAAE,YAAY,KAAK,IAAI,CAAC;AAAA,IACzC,GAAG,QAAQ;AAAA,IACX,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC;AAAA,EACrC,CAAC;AACD,QAAM,UAAU,MAAM,mBAAmB,QAAQ,aAAa,MAAM,KAAK,OAAO,CAAC,MAAM,MAAM,OAAO,CAAC;AACrG,QAAM,OAAO;AAAA,IACX;AAAA,IAAS;AAAA,IAAK;AAAA,IAAgB;AAAA,IAAc;AAAA,IAAO;AAAA,IAAa;AAAA,IAAS;AAAA,IAAK;AAAA,IAAUA,MAAK,MAAM;AAAA,IACnG,GAAI,MAAM,mBAAmB,CAAC,wBAAwB,GAAG,QAAQ,IAAI,CAAC;AAAA,IACtE,GAAI,aAAa,eAAe,UAAU,IAAI,CAAC;AAAA,IAC/C,GAAG,QAAQ;AAAA,IACX,GAAI,iBAAiB,CAAC,mBAAmB,IAAI,CAAC;AAAA,IAC9C,GAAI,aAAa,CAAC,eAAe,IAAI,CAAC;AAAA;AAAA,IAEtC,GAAI,IAAI,kBAAkB,UAAa,KAAK,eAAe,CAAC,UAAU,IAAI,CAAC;AAAA,IAC3E,GAAI,KAAK,QAAQ,SAAS,CAAC;AAAA,IAC3B,GAAG;AAAA,EACL;AACA,SAAO,EAAE,MAAAA,OAAM,OAAO,SAAS,MAAM,OAAO,GAAI,aAAa,EAAE,WAAW,IAAI,CAAC,EAAG;AACpF;AAUO,SAAS,eAAe,GAAoD;AACjF,SAAO,CAAC,WAAW,QAAQ,qBAAqB,EAAE,UAAU,GAAI,EAAE,SAAS,CAAC,kBAAkB,EAAE,MAAM,IAAI,CAAC,CAAE;AAC/G;AAmBO,SAAS,eACd,OACA,UACA,kBACA,OACgH;AAChH,QAAM,IAAI,SAAS;AACnB,MAAI,SAAS,UAAU,GAAG,gBAAgB,QAAS,OAAM,KAAK,eAAe;AAC7E,MAAI,CAAC,KAAK,OAAO,KAAK,CAAC,EAAE,WAAW,EAAG,QAAO,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AACtE,QAAM,OAAO,OAAO,KAAK,CAAC,EAAE,IAAI,CAAC,MAAM,EAAE,QAAQ,KAAK,GAAG,CAAC;AAC1D,MAAI,CAAC,gBAAgB,KAAK,GAAG;AAC3B,UAAM,KAAK,WAAW,KAAK,KAAK,YAAY,CAAC,IAAI,KAAK,WAAW,IAAI,UAAU,MAAM,mGAAmG;AACxL,WAAO,EAAE,SAAS,CAAC,GAAG,MAAM,CAAC,EAAE;AAAA,EACjC;AACA,QAAM,YAAY,EAAE,GAAG,EAAE;AACzB,QAAMS,SAAQ,UAAU,gBAAgB;AACxC,QAAM,SAASA,SAAQ,SAAS,SAAS;AACzC,MAAIA,UAAS,CAAC,QAAQ;AAEpB,WAAO,UAAU;AACjB,UAAM,KAAK,0GAA0G;AAAA,EACvH;AACA,QAAM,UAAU,EAAE,SAAS,WAAW,GAAI,SAAS,EAAE,QAAQ,EAAE,GAAG,OAAO,EAAE,IAAI,CAAC,EAAG;AACnF,MAAI,oBAAoB,KAAK,EAAG,QAAO,EAAE,SAAS,MAAM,YAAY,WAAW,MAAM,EAAE;AACvF,QAAM,SAAS;AAAA,IACb,GAAI,UAAU,gBAAgB,UAAU,CAAC,qBAAqB,IAAI,CAAC;AAAA,IACnE,GAAI,oBAAoB,UAAU,cAAc,MAAM,QAAQ,CAAC,sBAAsB,IAAI,CAAC;AAAA,IAC1F,GAAI,oBAAoB,UAAU,cAAc,MAAM,QAAQ,CAAC,sBAAsB,IAAI,CAAC;AAAA,EAC5F;AACA,MAAI,OAAO,OAAQ,OAAM,KAAK,GAAG,OAAO,KAAK,IAAI,CAAC,IAAI,OAAO,WAAW,IAAI,YAAY,OAAO,wMAAwM;AACvS,SAAO,EAAE,SAAS,MAAM,CAAC,EAAE;AAC7B;AAOO,SAAS,YAAY,WAA6C,QAAkE;AACzI,QAAM,OAAO,OAAO,KAAK,sBAAsB,EAC5C,OAAO,CAAC,MAAM,UAAU,CAAC,MAAM,UAAa,UAAU,CAAC,MAAM,uBAAuB,CAAC,CAAC,EACtF,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,UAAU,CAAC,CAAC,EAAE,EACjC,KAAK,GAAG;AACX,QAAMA,SAAQ,UAAU,gBAAgB,WAAW,WAAW;AAC9D,SAAO,CAAC,GAAI,OAAO,CAAC,aAAa,IAAI,IAAI,CAAC,GAAI,GAAIA,SAAQ,CAAC,oBAAoB,OAAO,SAAS,kBAAkB,OAAO,KAAK,IAAI,CAAC,CAAE;AACtI;AASO,SAAS,aAAa,OAAqB,KAA0B;AAC1E,QAAM,SAAS,gBAAgB,GAAG;AAClC,MAAI,OAAO,WAAW,eAAe,UAAU,CAAC,aAAa,KAAK,EAAG,QAAO,CAAC;AAC7E,QAAM,SAAS,MAAM,kBAAmB,MAAM;AAC9C,SAAO,YAAY,SAAS,CAAC,cAAc,OAAO,OAAO,KAAK,GAAG,CAAC,IAAI,CAAC;AACzE;AAGO,SAAS,oBAAoB,OAAqB,KAAoC;AAC3F,QAAM,SAAS,gBAAgB,GAAG;AAClC,MAAI,OAAO,WAAW,eAAe,UAAU,aAAa,KAAK,EAAG,QAAO;AAC3E,SAAO,wBAAwB,OAAO,KAAK,IAAI,CAAC,uHAAuH,eAAe,KAAK,IAAI,CAAC;AAClM;AAEO,SAAS,MAAM,SAAiB,OAAkB,IAAqB;AAE5E,KAAG,IAAI,GAAG,OAAO,KAAK,OAAO,EAAE;AAC/B,SAAO,MAAM;AACf;AAngBA,IAsDa,mBAGP,QAiHO,4BAGA,eAkPA,yBAGA,sBASA,wBAGA;AA9ab;AAAA;AAAA;AAsBA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA,IAAAC;AACA;AACA,IAAAC;AACA,IAAAC;AACA;AACA;AAgBO,IAAM,oBAAoB,CAAC,cAAc,OAAO,QAAQ,UAAU,SAAS,UAAU,WAAW;AAGvG,IAAM,SAAS,oBAAI,IAAI,CAAC,UAAU,QAAQ,WAAW,SAAS,YAAY,MAAM,WAAW,UAAU,UAAU,UAAU,YAAY,gBAAgB,UAAU,CAAC;AAiHzJ,IAAM,6BAA6B;AAGnC,IAAM,gBAAqD;AAAA,MAChE,QAAQ;AAAA,MACR,SAAS;AAAA,MACT,QAAQ;AAAA,IACV;AA8OO,IAAM,0BAA0B;AAGhC,IAAM,uBACX,oKAAoK,OAAO;AAQtK,IAAM,yBAA2D,OAAO,OAAO,EAAE,gBAAgB,QAAQ,gBAAgB,UAAU,aAAa,MAAM,CAAC;AAGvJ,IAAM,kBAAkB;AAAA;AAAA;;;AC9Z/B;;;ACiBO,IAAM,gBAA2B,OAAO,OAAO;AAAA,EACpD,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,OAAO;AAAA,EACP,SAAS;AAAA,EACT,OAAO;AAAA,EACP,MAAM;AAAA,EACN,YAAY;AAAA,EACZ,QAAQ;AAAA,EACR,UAAU;AAAA,EACV,WAAW;AACb,CAAC;AAGD,IAAM,QAAS,OAAO,KAAK,aAAa,EAAiB,OAAO,CAAC,MAAM,MAAM,WAAW;AAGjF,SAAS,YAAY,GAA4B;AACtD,MAAI,CAAC,KAAK,OAAO,MAAM,SAAU,QAAO;AACxC,QAAM,IAAI;AACV,SAAO,MAAM,MAAM,CAAC,MAAM,OAAO,UAAU,EAAE,CAAC,CAAC,CAAC,MAAM,EAAE,cAAc,UAAa,OAAO,UAAU,EAAE,SAAS;AACjH;AAGO,SAAS,cAAc,GAAyB;AACrD,SAAO,OAAO,UAAW,EAAyB,SAAS,IAAI,IAAI,OAAO,OAAO,EAAE,GAAG,GAAG,WAAW,cAAc,UAAU,CAAC;AAC/H;AAEA,IAAI;AAOG,SAAS,YAAyE;AACvF,cAAY,YAAY;AACtB,QAAI;AAEF,YAAM,IAAa,MAAM,OAAO,6BAA6B;AAC7D,YAAM,QAAS,EAA+B;AAC9C,UAAI,YAAY,KAAK,EAAG,QAAO,EAAE,OAAO,cAAc,KAAK,GAAG,QAAQ,QAAiB;AAAA,IACzF,QAAQ;AAAA,IAER;AACA,WAAO,EAAE,OAAO,eAAe,QAAQ,WAAoB;AAAA,EAC7D,GAAG;AACH,SAAO;AACT;;;AC1DA;AACA;AACA;AAGO,IAAM,eAAe,EAAE,WAAW,SAAS,SAAS,WAAW,MAAM,QAAQ,iBAAiB,UAAU;AACxG,IAAM,sBAAsB;AAG5B,SAAS,WAAW,MAAkC;AAC3D,QAAM,IAAI,QAAQ;AAClB,SAAQ,aAAwC,CAAC,KAAK;AACxD;AAGO,SAAS,YAAY,OAAmC;AAC7D,QAAM,CAAC,SAAS,IAAI,IAAI,MAAM,MAAM,GAAG;AAEvC,SAAO,WAAW,OAAO,KAAK,OAAO,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,OAAO,EAAE,IAAI;AAC3E;AAGO,SAAS,UAAU,MAAgB,MAA6C;AACrF,QAAM,QAAQ,SAAS,MAAM,SAAS;AACtC,QAAM,QAAQ,SAAS,MAAM,MAAM,SAAS;AAC5C,QAAM,KAAK,SAAS,MAAM,MAAM,MAAM;AACtC,aAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,WAAW,KAAK,GAAG,CAAC,WAAW,KAAK,GAAG,CAAC,QAAQ,EAAE,CAAC,EAAY,KAAI,EAAE,QAAS,QAAO,EAAE,OAAO,GAAG,IAAI,iBAAiB;AAChJ,QAAM,SAAmB,CAAC;AAC1B,QAAM,OAAiB,CAAC;AACxB,WAAS,IAAI,GAAG,IAAI,GAAG,KAAK,QAAQ,KAAK;AACvC,UAAM,IAAI,GAAG,KAAK,CAAC;AACnB,QAAI,MAAM,WAAW;AACnB,YAAM,IAAI,GAAG,KAAK,IAAI,CAAC;AACvB,UAAI,MAAM,UAAa,EAAE,WAAW,IAAI,EAAG,QAAO,EAAE,OAAO,wDAAwD;AACnH,aAAO,KAAK,WAAW,CAAC;AACxB;AAAA,IACF,MAAO,MAAK,KAAK,CAAC;AAAA,EACpB;AACA,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAClD,MAAI,MAAM,OAAQ,QAAO,EAAE,OAAO,uBAAuB,MAAM,KAAK,GAAG,CAAC,GAAG;AAC3E,MAAI,KAAK,SAAS,EAAG,QAAO,EAAE,OAAO,0BAA0B,OAAO,KAAK,YAAY,EAAE,KAAK,IAAI,CAAC,4BAA4B;AAC/H,MAAI;AACJ,MAAI,MAAM,UAAU,QAAW;AAC7B,aAAS,YAAY,MAAM,KAAK;AAChC,QAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,qCAAqC,MAAM,KAAK,IAAI;AAAA,EACnF;AACA,SAAO;AAAA,IACL;AAAA,IAAU,WAAW,KAAK,CAAC,CAAC;AAAA,IAC5B,GAAI,SAAS,CAAC,YAAY,MAAM,IAAI,CAAC;AAAA,IACrC,GAAI,MAAM,QAAQ,CAAC,WAAW,MAAM,KAAK,IAAI,CAAC;AAAA,IAC9C,GAAG;AAAA,IACH,GAAI,GAAG,QAAQ,CAAC,QAAQ,GAAG,KAAK,IAAI,CAAC;AAAA,IACrC,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC;AAAA,EAC3B;AACF;AAEA,eAAsBC,OAAM,MAAgB,MAAe,OAAkB,IAA8B;AACzG,QAAM,OAAO,UAAU,MAAM,IAAI;AACjC,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,SAAO,UAAU,GAAG,OAAO,UAAU,OAAO,IAAI,CAAC,UAAU,MAAM,kBAAkB,MAAM,aAAa,CAAC;AACzG;;;AFhEAC;AACAC;;;AGCA;AACA;AACA;AAEA;AACA;AANA,SAAS,WAAAC,iBAAe;AA8BxB,IAAI;AAGG,SAAS,cAAgD;AAC9D,oBAAkB,YAAY;AAC5B,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,4BAA4B;AAC5E,YAAM,IAA6B,MAAM,OAAO,gCAAgC;AAChF,UAAI,CAAC,CAAC,oBAAoB,qBAAqB,aAAa,EAAE,MAAM,CAAC,MAAM,OAAO,EAAE,CAAC,MAAM,UAAU,EAAG,QAAO;AAC/G,UAAI,OAAO,EAAE,mBAAmB,cAAc,OAAO,EAAE,cAAc,WAAY,QAAO;AACxF,aAAO,EAAE,GAAG,GAAG,gBAAgB,EAAE,gBAAgB,WAAW,EAAE,UAAU;AAAA,IAC1E,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AAQO,IAAM,qBACX,GAAG,OAAO,kHACF,OAAO;AAGV,SAAS,gBAAgBC,SAA4E;AAC1G,QAAMC,SAAQ,gBAAgBD,OAAM,EAAE,SAAS;AAC/C,QAAM,YAAYC,QAAO,UAAU,CAAC,GAAG,IAAI,WAAW;AACtD,QAAM,YAAYA,QAAO,WAAW,SAAS,IAAI,CAAC,QAAQ,EAAE,IAAI,MAAMA,OAAM,SAAU,EAAE,IAAI,CAAC;AAC7F,SAAO,EAAE,WAAW,SAAS;AAC/B;AAGA,eAAsB,OAAO,MAAgB,MAAe,OAAkB,IAA8B;AAC1G,QAAM,cAAc,KAAK,SAAS,gBAAgB;AAClD,MAAI,OAAO,KAAK,OAAO,CAAC,MAAM,MAAM,gBAAgB;AACpD,QAAM,QAA4C,CAAC;AACnD,aAAW,QAAQ,CAAC,UAAU,gBAAgB,UAAU,GAAG;AACzD,UAAM,IAAI,SAAS,MAAM,IAAI;AAC7B,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAC9D,UAAM,IAAI,IAAI,EAAE;AAChB,WAAO,EAAE;AAAA,EACX;AACA,MAAI,KAAK,OAAQ,QAAO,MAAM,wBAAwB,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACjF,QAAM,QAAQ,MAAM,YAAY;AAChC,MAAI,CAAC,OAAO;AACV,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,UAAU,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,mBAAmB,CAAC,CAAC;AAAA,QAC/G,IAAG,IAAI,GAAG,OAAO,KAAK,kBAAkB,EAAE;AAC/C,WAAO,MAAM;AAAA,EACf;AACA,QAAM,OAAO,MAAM,QAAQ,KAAK,WAAW,GAAG,GAAG;AACjD,MAAID;AACJ,MAAI,MAAM;AACR,QAAI;AACF,MAAAA,UAAS,WAAW,IAAI;AAAA,IAC1B,SAAS,GAAG;AACV,aAAO,MAAM,aAAa,cAAc,EAAE,UAAU,GAAG,IAAI,KAAM,EAAY,OAAO,IAAI,OAAO,EAAE;AAAA,IACnG;AACA,UAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,QAAI,OAAO,QAAQ;AACjB,iBAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,aAAO,MAAM;AAAA,IACf;AAAA,EACF;AACA,QAAM,EAAE,WAAW,SAAS,IAAIA,UAAS,gBAAgBA,OAAM,IAAI,EAAE,WAAW,CAAC,GAAG,UAAU,CAAC,EAAE;AAEjG,QAAM,UAAU,MAAM,aAAa;AACnC,QAAM,QAAQ,UAAU,QAAQ,mBAAmB,aAAa,IAAI;AACpE,QAAM,OAAO,OAAOE,UAAQ,IAAI,IAAI,GAAG;AACvC,QAAM,OAAO,MAAM,MAAM,iBAAiB,IAAI;AAC9C,QAAM,QAAQ,MAAM,kBAAkB,EAAE,MAAM,OAAO,WAAW,GAAI,SAAS,SAAS,EAAE,SAAS,IAAI,CAAC,EAAG,CAAC;AAE1G,QAAM,MAAM,MAAM,cAAc,MAAMF,UAAS,gBAAgBA,OAAM,EAAE,GAAG,YAAY;AACtF,MAAI;AACJ,MAAI,KAAK;AACP,UAAM,SAAS,MAAM,eAAe,KAAK,MAAM,cAAc,IAAI,iBAAiB,aAAa;AAC/F,QAAI,UAAU,OAAO,WAAW,YAAY,WAAW,OAAQ,QAAO,MAAM,OAAQ,OAA8B,KAAK,GAAG,OAAO,EAAE;AACnI,cAAU,MAAM,MAAM,YAAY,OAAO,EAAE,KAAK,MAAM,UAAU,MAAM,GAAG,OAAO,KAAK,GAAG,KAAK,GAAI,MAAM,UAAU,IAAI,EAAE,QAAQ,MAAM,UAAU,EAAE,IAAI,CAAC,EAAG,CAAC;AAAA,EAC5J;AAEA,QAAM,OAAO,eAAe,MAAM,QAAQ,SAAS,IAAI,MAAM,SAAS,MAAM;AAC5E,MAAI,MAAM;AACR,OAAG,IAAI,KAAK,UAAU,EAAE,SAAS,UAAU,IAAI,SAAS,MAAM,MAAM,UAAU,MAAM,QAAQ,MAAM,QAAQ,MAAM,MAAM,MAAM,SAAS,MAAM,SAAS,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC,EAAG,CAAC,CAAC;AACtL,WAAO;AAAA,EACT;AACA,QAAM,SAAS,MAAM,OAAO,UAAU,CAAC;AACvC,KAAG,IAAI,GAAG,OAAO,YAAY,OAAO,QAAQ,MAAM,EAAE,IAAI,CAAC,CAAC,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,IAAI,KAAK,2BAA2B,EAAE;AAC5H,aAAW,KAAK,MAAM,QAAS,IAAG,IAAI,KAAK,EAAE,OAAO,EAAE;AACtD,MAAI,QAAS,IAAG,IAAI,WAAW,QAAQ,KAAK,KAAK,IAAI,CAAC,UAAU,GAAG,EAAE;AAAA,MAChE,IAAG,IAAI,uEAAuE;AACnF,SAAO;AACT;;;AClIA;AACA;AAEO,IAAM,oBAAoB,GAAG,OAAO;AAE3C,eAAsB,OAAO,MAAgB,MAAe,OAAkB,IAA8B;AAC1G,MAAI,KAAK,CAAC,MAAM,QAAS,QAAO,MAAM,2BAA2B,KAAK,CAAC,KAAK,EAAE,WAAW,OAAO,mBAAmB,OAAO,EAAE;AAC5H,SAAO,UAAU,GAAG,OAAO,iBAAiB,OAAO,IAAI,CAAC,UAAU;AAChE,QAAI,OAAO,MAAM,qBAAqB,YAAY;AAChD,UAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,gBAAgB,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,kBAAkB,CAAC,CAAC;AAAA,UACpH,IAAG,IAAI,GAAG,OAAO,KAAK,iBAAiB,EAAE;AAC9C,aAAO,QAAQ,QAAQ,MAAM,MAAM;AAAA,IACrC;AACA,WAAO,MAAM,kBAAkB,CAAC,UAAU,GAAG,IAAI,GAAG,aAAa;AAAA,EACnE,CAAC;AACH;;;AJRA;;;AKMA;AACA;AAJA,SAAS,WAAW,cAAc,cAAAG,cAAY,aAAAC,YAAW,gBAAAC,gBAAc,iBAAAC,sBAAqB;AAC5F,SAAS,QAAAC,cAAY;AAMd,IAAM,UAAuD;AAAA,EAClE,QAAQ,CAAC,MAAM,UAAU,SAAS;AAAA,EAClC,QAAQ,CAAC,MAAM,UAAU,SAAS;AACpC;AAGA,IAAM,iBAAiB,oBAAI,IAAI,CAAC,MAAM,SAAS,MAAM,WAAW,WAAW,iBAAiB,aAAa,MAAM,aAAa,aAAa,eAAe,kBAAkB,CAAC;AAE3K,IAAM,YAAY,oBAAI,IAAI,CAAC,OAAO,OAAO,QAAQ,WAAW,QAAQ,SAAS,QAAQ,OAAO,CAAC;AAG7F,SAAS,SAAS,MAA0B;AAC1C,SAAO,KACJ,MAAM,yBAAyB,EAC/B,IAAI,CAAC,SAAS,IAAI,MAAM,sBAAsB,KAAK,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,QAAQ,gBAAgB,EAAE,CAAC,CAAC,EAChG,OAAO,CAAC,MAAM,EAAE,SAAS,CAAC;AAC/B;AAGO,SAAS,aAAa,MAAmF;AAC9G,aAAW,SAAS,SAAS,IAAI,GAAG;AAClC,QAAI,IAAI;AACR,WAAO,IAAI,MAAM,WAAW,UAAU,IAAI,MAAM,CAAC,CAAE,KAAK,2BAA2B,KAAK,MAAM,CAAC,CAAE,KAAM,MAAM,IAAI,CAAC,MAAM,SAAS,MAAM,CAAC,EAAG,WAAW,GAAG,GAAK;AAC9J,UAAM,OAAO,MAAM,CAAC,KAAK,IAAI,MAAM,GAAG,EAAE,IAAI;AAC5C,UAAM,UAAU,QAAQ,GAAG;AAC3B,QAAI,CAAC,QAAS;AACd,aAAS,IAAI,IAAI,GAAG,IAAI,MAAM,QAAQ,KAAK;AACzC,YAAM,IAAI,MAAM,CAAC;AACjB,UAAI,EAAE,WAAW,GAAG,GAAG;AACrB,YAAI,eAAe,IAAI,CAAC,EAAG;AAC3B;AAAA,MACF;AACA,UAAI,QAAQ,SAAS,CAAC,GAAG;AACvB,eAAO;AAAA,UACL,QAAQ;AAAA,UACR,YAAY;AAAA,UACZ,SAAS,GAAG,OAAO,0CAA0C,GAAG,IAAI,CAAC,2BAA2B,OAAO;AAAA,QACzG;AAAA,MACF;AACA;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAGO,IAAM,kBAAkB,IAAI,IAAI,6BAA6B,YAAY,GAAG;AAG5E,IAAM,eAAe;AAGrB,SAAS,cAAc,UAA4D;AACxF,QAAM,QAAS,OAAO,SAAS,UAAU,YAAY,SAAS,UAAU,OAAO,SAAS,QAAQ,CAAC;AACjG,QAAM,MAAM,MAAM,QAAQ,MAAM,UAAU,IAAI,CAAC,GAAI,MAAM,UAAwB,IAAI,CAAC;AACtF,QAAMC,OAAM,KAAK,UAAU,GAAG,EAAE,SAAS,mBAAmB;AAC5D,MAAI,CAACA,KAAK,KAAI,KAAK,EAAE,SAAS,QAAQ,OAAO,CAAC,EAAE,MAAM,WAAW,SAAS,aAAa,CAAC,EAAE,CAAC;AAC3F,SAAO,EAAE,GAAG,UAAU,OAAO,EAAE,GAAG,OAAO,YAAY,IAAI,EAAE;AAC7D;AAGA,eAAsB,MAAM,MAAgB,MAAe,OAAkB,IAA8B;AACzG,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,MAAI,QAAQ,SAAS;AACnB,UAAM,QAAQ,KAAK,CAAC,MAAM,OAAO,KAAK,MAAM,CAAC,IAAI,MAAM,KAAK,GAAG;AAC/D,QAAI,CAAC,KAAK,KAAK,EAAG,QAAO,MAAM,+CAA+C,OAAO,EAAE;AACvF,UAAM,IAAI,aAAa,IAAI;AAC3B,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,eAAe,IAAI,CAAC,GAAG,UAAU,IAAI,MAAM,SAAS,MAAM,MAAM,SAAS,KAAK,KAAK,CAAC,CAAC;AAAA,QAC3H,IAAG,IAAI,IAAI,EAAE,UAAU,GAAG,OAAO,YAAY,IAAI,QAAQ;AAC9D,WAAO,IAAI,MAAM,SAAS,MAAM;AAAA,EAClC;AACA,MAAI,QAAQ,WAAW;AACrB,UAAM,UAAU,SAAS,MAAM,OAAO;AACtC,QAAI,QAAQ,QAAS,QAAO,MAAM,2BAA2B,OAAO,EAAE;AACtE,QAAI,QAAQ,KAAK,OAAQ,QAAO,MAAM,+BAA+B,QAAQ,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACxG,UAAM,OAAO,QAAQ,QAAQD,OAAK,GAAG,KAAK,QAAQ,KAAK,IAAI,GAAG;AAC9D,UAAM,UAAoB,CAAC;AAC3B,UAAM,UAAUA,OAAK,MAAM,eAAe;AAC1C,IAAAH,WAAU,SAAS,EAAE,WAAW,KAAK,CAAC;AACtC,iBAAa,IAAI,IAAI,qBAAqB,eAAe,GAAGG,OAAK,SAAS,mBAAmB,CAAC;AAC9F,YAAQ,KAAK,iCAAiC;AAC9C,UAAM,eAAeA,OAAK,MAAM,uBAAuB;AACvD,QAAI,WAAoC,CAAC;AACzC,QAAIJ,aAAW,YAAY,GAAG;AAC5B,UAAI;AACF,mBAAW,KAAK,MAAME,eAAa,cAAc,MAAM,CAAC;AAAA,MAC1D,SAAS,GAAG;AACV,eAAO,MAAM,sCAAuC,EAAY,OAAO,kCAAkC,OAAO,EAAE;AAAA,MACpH;AAAA,IACF;AACA,IAAAC,eAAc,cAAc,KAAK,UAAU,cAAc,QAAQ,GAAG,MAAM,CAAC,IAAI,IAAI;AACnF,YAAQ,KAAK,uBAAuB;AACpC,UAAM,SAASC,OAAK,MAAM,oBAAoB;AAC9C,IAAAH,WAAU,QAAQ,EAAE,WAAW,KAAK,CAAC;AACrC,eAAW,QAAQ,OAAO,KAAK,OAAO,GAAG;AACvC,YAAM,KAAKG,OAAK,QAAQ,IAAI;AAC5B,mBAAa,IAAI,IAAI,OAAO,IAAI,IAAI,eAAe,GAAG,EAAE;AACxD,gBAAU,IAAI,GAAK;AACnB,cAAQ,KAAK,sBAAsB,IAAI,EAAE;AAAA,IAC3C;AACA,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,iBAAiB,IAAI,MAAM,UAAU,MAAM,MAAM,QAAQ,CAAC,CAAC;AAAA,SACjG;AACH,iBAAW,KAAK,QAAS,IAAG,IAAI,GAAG,OAAO,iBAAiB,CAAC,EAAE;AAC9D,SAAG,IAAI,GAAG,OAAO,6HAA6H;AAAA,IAChJ;AACA,WAAO,MAAM;AAAA,EACf;AACA,SAAO,MAAM,2DAA2D,OAAO,EAAE;AACnF;;;ACpHAE;AAIA;AACA;AACA;AACA;AAEA;AACA;AATA,SAAS,cAAAC,cAAY,gBAAAC,sBAAoB;AACzC,SAAS,WAAAC,WAAS,QAAAC,cAAY;AAC9B,SAAS,uBAAuB;AAmBzB,SAAS,aAAaC,SAAuB,KAAiC;AACnF,QAAM,MAAMA,QAAO;AACnB,QAAM,MAA0B,CAAC;AACjC,aAAW,SAAS,OAAO,KAAK,SAAS,GAAG,CAAC,GAAG;AAC9C,UAAM,MAAM,gBAAgB,KAAK,OAAO,KAAK,eAAe;AAC5D,eAAW,SAAS,iBAAiB;AACnC,YAAM,KAAK,IAAI,KAAK;AACpB,UAAI,GAAI,KAAI,KAAK,EAAE,OAAO,OAAO,SAAS,GAAG,SAAS,IAAI,GAAG,IAAI,MAAM,GAAG,KAAK,CAAC;AAAA,IAClF;AAAA,EACF;AACA,SAAO;AACT;AAGO,SAAS,cAAcA,SAAuB,KAAa,MAA6C;AAC7G,QAAM,MAAMA,QAAO;AACnB,QAAM,QAAQ,gBAAgB,GAAG;AACjC,MAAI,CAAC,MAAO,QAAO,CAAC,GAAGA,QAAO,QAAQ,aAAa,oCAAoC,WAAW,EAAE;AACpG,QAAMC,SAAQ,CAAC,GAAGD,QAAO,QAAQ,aAAa,+BAA+B,GAAG,EAAE;AAClF,QAAM,SAAS,OAAO,KAAK,MAAM,KAAK;AACtC,EAAAC,OAAM,KAAK,aAAa,OAAO,IAAI,CAAC,MAAM,YAAY,CAAC,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE;AACtE,MAAI,OAAO,SAAS,QAAQ,GAAG;AAC7B,UAAM,IAAI,cAAc,GAAG;AAC3B,IAAAA,OAAM,KAAK,mBAAmB,EAAE,GAAG,GAAG,EAAE,SAAS,OAAO,EAAE,MAAM,KAAK,EAAE,mDAAmD;AAAA,EAC5H;AACA,QAAMC,UAAS,OAAO,KAAK,SAAS,GAAG,CAAC;AACxC,MAAIA,QAAO,WAAW,EAAG,CAAAD,OAAM,KAAK,iFAAiF;AACrH,aAAW,SAASC,SAAQ;AAC1B,IAAAD,OAAM,KAAK,KAAK,KAAK,EAAE;AACvB,eAAW,SAAS,QAAQ;AAC1B,YAAM,IAAI,KAAK,KAAK,CAAC,MAAM,EAAE,UAAU,SAAS,EAAE,UAAU,KAAK;AACjE,MAAAA,OAAM,KAAK,IAAI,OAAO,YAAY,KAAK,EAAE,OAAO,EAAE,CAAC,YAAY,EAAE,OAAO,QAAQ,EAAE,EAAE,KAAK,EAAE,IAAI,MAAM,OAAO,YAAY,KAAK,EAAE,OAAO,EAAE,CAAC,IAAI,WAAW,EAAE;AAAA,IAC5J;AAAA,EACF;AACA,EAAAA,OAAM,KAAK,iGAAiG;AAC5G,SAAOA;AACT;AAGO,SAAS,iBAAiB,MAAgB,MAAe,OAAkB,IAAqB;AACrG,QAAM,OAAO,SAAS,MAAM,QAAQ;AACpC,QAAM,MAAM,SAAS,KAAK,MAAM,OAAO;AACvC,MAAI,KAAK,WAAW,IAAI,QAAS,QAAO,MAAM,GAAG,KAAK,UAAU,WAAW,OAAO,kBAAkB,OAAO,EAAE;AAC7G,MAAI,IAAI,KAAK,OAAQ,QAAO,MAAM,mCAAmC,IAAI,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACpG,QAAM,OAAO,KAAK,SAAS,WAAW,GAAG,GAAG;AAC5C,MAAI,CAAC,KAAM,QAAO,MAAM,qBAAqB,GAAG,GAAG,sBAAsB,OAAO,0BAA0B,OAAO,EAAE;AACnH,MAAID;AACJ,MAAI;AACF,IAAAA,UAAS,WAAW,IAAI;AAAA,EAC1B,SAAS,GAAG;AACV,WAAO,MAAM,aAAa,cAAc,EAAE,UAAU,GAAG,IAAI,KAAM,EAAY,OAAO,IAAI,OAAO,EAAE;AAAA,EACnG;AACA,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,qBAAqB,IAAI,OAAO,UAAU,MAAM,QAAQ,MAAM,MAAM,UAAU,OAAO,CAAC,CAAC;AAClI,WAAO,MAAM;AAAA,EACf;AACA,QAAM,cAAc,IAAI,SAAS;AACjC,QAAM,OAAO,aAAaA,SAAQ,WAAW;AAC7C,MAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,qBAAqB,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,MAAM,KAAK,aAAa,UAAU,gBAAgBA,OAAM,EAAE,GAAG,YAAY,MAAM,QAAQ,KAAK,CAAC,CAAC;AAAA,MAC/L,YAAW,QAAQ,cAAcA,SAAQ,aAAa,IAAI,EAAG,IAAG,IAAI,IAAI;AAC7E,SAAO,MAAM;AACf;AAGO,IAAM,sBACX,GAAG,OAAO,gRACgJ,OAAO;AAInK,IAAMG,UAA2B,CAAC,UAAU,UAAU,SAAS;AAmD/D,IAAM,wBAAwB,CAAC,cAAc,kBAAkB,sBAAsB,oBAAoB,kBAAkB;AAE3H,IAAI;AAGG,SAAS,kBAAwD;AACtE,wBAAsB,YAAY;AAChC,QAAI;AAEF,YAAM,KAA8B,MAAM,OAAO,8BAA8B;AAC/E,YAAM,KAA8B,MAAM,OAAO,8BAA8B;AAC/E,UAAI,CAAC,sBAAsB,MAAM,CAAC,MAAM,OAAO,GAAG,CAAC,MAAM,UAAU,KAAK,OAAO,GAAG,yBAAyB,WAAY,QAAO;AAC9H,aAAO,EAAE,GAAG,IAAI,sBAAsB,GAAG,qBAAqB;AAAA,IAChE,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AAQO,SAAS,iBAAiB,MAAwB;AACvD,QAAM,OAAOC,OAAK,MAAM,sBAAsB;AAC9C,MAAI,CAACC,aAAW,IAAI,EAAG,QAAO,CAAC;AAC/B,MAAI;AACF,UAAM,MAAM,KAAK,MAAMC,eAAa,MAAM,MAAM,CAAC;AACjD,YAAQ,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ;AAAA,EAChG,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACF;AAGO,SAAS,SAAS,QAAmF;AAC1G,MAAI,WAAW,OAAW,QAAO;AACjC,QAAM,SAAS,OAAO,WAAW,YAAY,CAAC,MAAM,QAAQ,MAAM,KAAK,EAAE,WAAW;AACpF,QAAM,OAAO,SAAW,OAAmC,MAAO,OAAmC,UAAW;AAChH,MAAI,SAAS,OAAW,QAAO;AAC/B,MAAI,OAAO,SAAS,SAAU,QAAO,EAAE,QAAQ,CAAC,IAAI,EAAE;AACtD,MAAI,MAAM,QAAQ,IAAI,EAAG,QAAO,EAAE,QAAQ,KAAK,OAAO,CAAC,MAAmB,OAAO,MAAM,QAAQ,EAAE;AACjG,QAAM,IAAI;AACV,SAAO,OAAO,EAAE,UAAU,WAAW,EAAE,QAAQ,MAAM,QAAQ,EAAE,MAAM,IAAK,EAAE,SAAsB,CAAC,GAAG,OAAO,EAAE,MAAM,IAAI;AAC3H;AAGO,SAAS,kBACd,IACA,OACA,KACA,SACA,QACAC,OACyB;AACzB,QAAM,cAAc,SAAS,MAAM;AACnC,QAAM,OAA+B,QAAQ,SAAS,CAAC,GAAG,OAAO,IAAI,CAAC,MAAS;AAC/E,SAAO,KAAK,QAAQ,CAAC,WAAW;AAC9B,UAAMC,YAAW,GAAG,qBAAqB,OAAO,KAAK,MAAM;AAC3D,UAAM,OAAO,SAAS,GAAG,MAAM,IAAI,GAAG,KAAK;AAE3C,UAAM,mBAAmBD,QAAO,eAAe,MAAMA,KAAI,GAAG,OAAO;AACnE,WAAOC,YAAW,CAAC,EAAE,MAAM,UAAAA,WAAU,GAAI,SAAS,EAAE,OAAO,IAAI,CAAC,GAAI,GAAI,cAAc,EAAE,YAAY,IAAI,CAAC,GAAI,GAAI,mBAAmB,EAAE,iBAAiB,IAAI,CAAC,EAAG,CAAC,IAAI,CAAC;AAAA,EACvK,CAAC;AACH;AASA,eAAsB,WAAW,MAAgB,MAAe,OAAkB,IAA8B;AAC9G,MAAI,KAAK,CAAC,MAAM,QAAS,QAAO,MAAM,0BAA0B,KAAK,CAAC,KAAK,EAAE,WAAW,OAAO,kBAAkB,OAAO,EAAE;AAC1H,QAAM,KAAK,MAAM,gBAAgB;AACjC,MAAI,CAAC,IAAI;AACP,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,eAAe,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,oBAAoB,CAAC,CAAC;AAAA,QACrH,IAAG,IAAI,GAAG,OAAO,KAAK,mBAAmB,EAAE;AAChD,WAAO,MAAM;AAAA,EACf;AACA,QAAM,gBAAgB,KAAK,SAAS,kBAAkB;AACtD,MAAI,OAAO,KAAK,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,kBAAkB;AAC/D,QAAM,QAA4C,CAAC;AACnD,aAAW,QAAQ,CAAC,UAAU,SAAS,WAAW,UAAU,UAAU,GAAG;AACvE,UAAM,IAAI,SAAS,MAAM,IAAI;AAC7B,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAC9D,UAAM,IAAI,IAAI,EAAE;AAChB,WAAO,EAAE;AAAA,EACX;AACA,MAAI,KAAK,OAAQ,QAAO,MAAM,6BAA6B,KAAK,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACtF,QAAM,YAAY,MAAM,SAAS;AACjC,MAAI,cAAc,UAAa,CAAEC,QAA6B,SAAS,SAAS,EAAG,QAAO,MAAM,cAAc,SAAS,oCAAoC,OAAO,EAAE;AACpK,QAAM,OAAO,MAAM,QAAQ,KAAK,WAAW,GAAG,GAAG;AACjD,MAAI,CAAC,KAAM,QAAO,MAAM,qBAAqB,GAAG,GAAG,sBAAsB,OAAO,0BAA0B,OAAO,EAAE;AACnH,MAAIC;AACJ,MAAI;AACF,IAAAA,UAAS,WAAW,IAAI;AAAA,EAC1B,SAAS,GAAG;AACV,WAAO,MAAM,aAAa,cAAc,EAAE,UAAU,GAAG,IAAI,KAAM,EAAY,OAAO,IAAI,OAAO,EAAE;AAAA,EACnG;AACA,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,QAAQ;AACjB,eAAW,KAAK,OAAQ,IAAG,IAAI,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE;AAC/D,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,eAAe,IAAI,OAAO,UAAU,MAAM,QAAQ,MAAM,MAAM,UAAU,OAAO,CAAC,CAAC;AAC5H,WAAO,MAAM;AAAA,EACf;AACA,QAAM,WAAW,gBAAgBA,OAAM;AACvC,QAAM,OAAQ,aAAa,SAAS,SAAS,OAAO;AACpD,MAAI;AACJ,MAAI;AACF,aAAS,GAAG,iBAAiB,GAAG,KAAK,EAAE,GAAI,QAASD,QAA6B,SAAS,IAAI,IAAI,EAAE,KAAK,IAAI,CAAC,GAAI,GAAI,MAAM,QAAQ,IAAI,EAAE,MAAM,MAAM,QAAQ,EAAE,IAAI,CAAC,EAAG,CAAC;AAAA,EAC3K,SAAS,GAAG;AACV,WAAO,MAAO,EAAY,SAAS,OAAO,EAAE;AAAA,EAC9C;AACA,QAAM,MAAM,MAAM,OAAO,KAAK;AAC9B,QAAM,QAAQ,SAAS,GAAG,UAAU;AACpC,QAAM,YAAY,kBAAkB,IAAI,OAAO,KAAK,iBAAiBE,UAAQ,IAAI,CAAC,GAAG,SAAS,SAAS,QAAQ,SAAS,SAAS,IAAI;AACrI,QAAM,SAAS,MAAM,GAAG;AAAA,IACtB;AAAA,MACE;AAAA,MACA,OAAO;AAAA,MACP,MAAM;AAAA,MACN,GAAI,gBAAgB,EAAE,eAAe,KAAK,IAAI,CAAC;AAAA,MAC/C,UAAU,CAAC,SACT,GAAG,iBAAiB;AAAA,QAClB,OAAO,OAAO;AAAA,QACd,YAAY;AAAA,UACV,MAAM,OAAO;AAAA,UACb,MAAM,KAAK,QAAQ,OAAO;AAAA,UAC1B,eAAe,MAAM,UAAU,KAAK,KAAK,iBAAiB;AAAA,UAC1D,GAAI,KAAK,UAAU,EAAE,SAAS,KAAK,QAAQ,IAAI,CAAC;AAAA,UAChD,GAAI,KAAK,SAAS,EAAE,QAAQ,KAAK,OAAO,IAAI,CAAC;AAAA,QAC/C;AAAA,QACA;AAAA,QACA,OAAO;AAAA,MACT,CAAC;AAAA,IACL;AAAA,IACA,EAAE,OAAO,WAAW,OAAO,KAAK,GAAG,IAAI;AAAA,EACzC;AACA,MAAI,KAAM,IAAG,IAAI,KAAK,UAAU,MAAM,CAAC;AAAA,MAClC,IAAG,IAAI,GAAG,mBAAmB,MAAM,CAAC;AACzC,MAAI,CAAC,MAAO,IAAG,IAAI,GAAG,OAAO,iBAAiB,IAAI,4CAA4C;AAAA,WACrF,UAAU,WAAW,EAAG,IAAG,IAAI,GAAG,OAAO,qDAAqD,GAAG,2BAA2B;AACrI,SAAO,GAAG,eAAe,MAAM;AACjC;;;ANpSAC;;;AOfA;AACA;AACA;AACA;AAGO,SAAS,aAAa,KAA8B,KAAgD;AACzG,QAAM,IAAI,YAAY,GAAG;AACzB,QAAM,MAA8B,CAAC;AACrC,QAAM,MAAM,CAAC,GAAW,MAAgC;AACtD,QAAI,MAAM,UAAa,MAAM,MAAM,IAAI,CAAC,MAAM,OAAW,KAAI,CAAC,IAAI;AAAA,EACpE;AACA,MAAI,CAAC,EAAE,QAAQ;AACb,QAAI,wBAAwB,MAAM;AAClC,WAAO;AAAA,EACT;AACA,MAAI,IAAI,uCAAuC,OAAW,KAAI,+BAA+B,EAAE,QAAQ;AACvG,MAAI,EAAE,WAAY,KAAI,8BAA8B,IAAI,EAAE,UAAU,CAAC;AACrE,MAAI,EAAE,aAAa,UAAa,IAAI,gCAAgC,UAAa,IAAI,uCAAuC,OAAW,KAAI,qBAAqB,EAAE,WAAW;AAC7K,SAAO;AACT;AAGA,eAAsB,eAAe,KAAa,MAAyB,QAAQ,KAAsC;AACvH,MAAI,QAAgC,CAAC;AACrC,MAAI;AACF,UAAM,OAAO,WAAW,GAAG;AAC3B,QAAI,KAAM,SAAQ,aAAa,WAAW,IAAI,EAAE,KAAK,GAAG;AAAA,EAC1D,QAAQ;AACN,WAAO,CAAC;AAAA,EACV;AACA,SAAO,OAAO,KAAK,KAAK;AACxB,QAAM,QAAS,MAAM,aAAa;AAClC,MAAI,SAAS,OAAO,MAAM,kBAAkB,WAAY,OAAM,cAAc,EAAE,QAAQ,SAAS,IAAI,CAAC;AACpG,SAAO;AACT;;;APlBA;AACA;AACA;AACA;AACA;;;AQLA;AAEA;AACA;AACA;AAPA,SAAS,gBAAgB;AACzB,SAAS,cAAAC,cAAY,gBAAAC,gBAAc,iBAAAC,sBAAqB;AACxD,SAAS,WAAAC,WAAS,QAAAC,QAAM,YAAAC,WAAU,WAAAC,gBAAe;AAO1C,IAAM,kBAAkB;AACxB,IAAM,gBAAgB;AAC7B,IAAM,eAAe;AACrB,IAAMC,WAAU;AAChB,IAAM,aAAa,CAAC,gBAAgB,mBAAmB,sBAAsB;AAsCtE,SAAS,iBAAiB,MAAoD;AACnF,QAAM,QAAQ,SAAS,MAAM,SAAS;AACtC,QAAM,QAAQ,SAAS,MAAM,MAAM,SAAS;AAC5C,QAAM,MAAM,SAAS,MAAM,MAAM,OAAO;AACxC,MAAI,MAAM,WAAW,MAAM,WAAW,IAAI,QAAS,QAAO,EAAE,OAAO,+CAA+C;AAClH,QAAM,QAAQ,oBAAI,IAAI,CAAC,gBAAgB,WAAW,CAAC;AACnD,QAAM,UAAU,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,CAAC,MAAM,IAAI,CAAC,CAAC;AACzE,MAAI,QAAQ,OAAQ,QAAO,EAAE,OAAO,yBAAyB,QAAQ,KAAK,GAAG,CAAC,GAAG;AACjF,QAAM,QAAQ,IAAI,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,CAAC;AACvD,MAAI,MAAM,SAAS,EAAG,QAAO,EAAE,OAAO,kCAAkC,MAAM,KAAK,GAAG,CAAC,GAAG;AAC1F,QAAMC,WAAU,MAAM,CAAC,GAAG,QAAQ,MAAM,EAAE;AAC1C,MAAIA,aAAY,UAAa,CAACD,SAAQ,KAAKC,QAAO,EAAG,QAAO,EAAE,OAAO,GAAG,MAAM,CAAC,CAAC,kDAAkD;AAClI,MAAI,MAAM,UAAU,UAAa,CAACD,SAAQ,KAAK,MAAM,KAAK,EAAG,QAAO,EAAE,OAAO,WAAW,MAAM,KAAK,kDAAkD;AACrJ,SAAO;AAAA,IACL,GAAIC,WAAU,EAAE,SAAAA,SAAQ,IAAI,CAAC;AAAA,IAC7B,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC5C,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,IAC5C,GAAI,IAAI,QAAQ,EAAE,KAAK,IAAI,MAAM,IAAI,CAAC;AAAA,IACtC,SAAS,CAAC,IAAI,KAAK,SAAS,cAAc;AAAA,IAC1C,QAAQ,IAAI,KAAK,SAAS,WAAW;AAAA,EACvC;AACF;AAGO,SAAS,mBAAmB,KAAiC;AAClE,MAAI,MAAMF,SAAQ,GAAG;AACrB,WAAS,QAAQ,GAAG,QAAQ,IAAI,SAAS;AACvC,UAAM,OAAOF,OAAK,KAAK,cAAc;AACrC,QAAIJ,aAAW,IAAI,GAAG;AACpB,UAAI;AACF,cAAM,MAAM,KAAK,MAAMC,eAAa,MAAM,MAAM,CAAC;AACjD,YAAI,WAAW,KAAK,CAAC,MAAMQ,UAAS,IAAI,CAAC,CAAC,KAAK,OAAQ,IAAI,CAAC,EAA8B,eAAe,MAAM,QAAQ,EAAG,QAAO;AAAA,MACnI,QAAQ;AAAA,MAER;AAAA,IACF;AACA,UAAMC,MAAKP,UAAQ,GAAG;AACtB,QAAIO,QAAO,IAAK,QAAO;AACvB,UAAMA;AAAA,EACR;AACA,SAAO;AACT;AAGO,SAAS,WAAW,OAAeF,UAAqC;AAC7E,QAAM,IAAI,+CAA+C,KAAK,MAAM,KAAK,CAAC;AAC1E,MAAI,CAAC,EAAG,QAAO;AACf,SAAO,GAAG,EAAE,CAAC,CAAC,GAAGA,QAAO;AAC1B;AAGO,SAAS,gBAAgB,MAAc,MAAc,SAAiB,OAAmE;AAC9I,QAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,QAAM,QAAmB,CAAC;AAC1B,QAAM,OAAiB,CAAC;AACxB,aAAW,SAAS,YAAY;AAC9B,UAAM,OAAO,IAAI,KAAK;AACtB,QAAI,CAACC,UAAS,IAAI,EAAG;AACrB,eAAW,CAAC,MAAM,KAAK,KAAK,OAAO,QAAQ,IAAI,GAAG;AAChD,UAAI,OAAO,UAAU,SAAU;AAC/B,YAAM,SAAS,SAAS,kBAAkB,UAAU,aAAa,KAAK,IAAI,IAAI,QAAQ;AACtF,UAAI,WAAW,OAAW;AAC1B,YAAM,OAAO,WAAW,OAAO,MAAM;AACrC,UAAI,SAAS,QAAW;AACtB,aAAK,KAAK,GAAG,KAAK,IAAI,IAAI,QAAQ,KAAK,iBAAiB,MAAM,UAAU;AACxE;AAAA,MACF;AACA,UAAI,SAAS,MAAO;AACpB,WAAK,IAAI,IAAI;AACb,YAAM,KAAK,EAAE,MAAM,MAAM,MAAM,OAAO,IAAI,KAAK,CAAC;AAAA,IAClD;AAAA,EACF;AACA,SAAO,EAAE,MAAM,MAAM,SAASE,UAAS,KAAK,IAAI,IAAI,MAAM,OAAO,KAAK;AACxE;AAGO,SAAS,oBAAoB,MAAc,MAAc,OAAmD;AACjH,QAAM,MAAM,KAAK,MAAM,IAAI;AAC3B,QAAM,QAAmB,CAAC;AAC1B,QAAM,OAAO,MAAM,QAAQ,IAAI,IAAI,IAAK,IAAI,OAA0C,CAAC;AACvF,aAAW,OAAO,MAAM;AACtB,QAAI,OAAO,IAAI,YAAY,YAAY,CAAC,aAAa,KAAK,IAAI,OAAO,KAAK,OAAO,IAAI,YAAY,SAAU;AAC3G,QAAI,IAAI,YAAY,MAAO;AAC3B,UAAM,KAAK,EAAE,MAAM,MAAM,IAAI,SAAS,MAAM,IAAI,SAAS,IAAI,MAAM,CAAC;AACpE,QAAI,UAAU;AAAA,EAChB;AACA,SAAO,EAAE,MAAM,MAAM,SAASA,UAAS,KAAK,IAAI,IAAI,MAAM,MAAM;AAClE;AAGO,SAAS,UAAU,KAA8BH,UAAqC;AAC3F,QAAM,QAAQ,IAAI;AAClB,QAAM,OAAO,OAAO,UAAU,WAAW,QAAQC,UAAS,KAAK,KAAK,OAAO,MAAM,SAAS,WAAW,MAAM,OAAO;AAClH,MAAI,SAAS,OAAW,QAAO;AAC/B,QAAM,IAAI,IAAI,OAAO,IAAI,SAAS,QAAQ,QAAQ,KAAK,CAAC,kCAAkC,EAAE,KAAK,IAAI;AACrG,MAAI,KAAK,EAAE,CAAC,EAAE,WAAW,GAAGD,QAAO,GAAG,EAAG,QAAO;AAChD,MAAI,EAAG,QAAO,oCAAoC,EAAE,CAAC,CAAC,aAAa,EAAE,CAAC,CAAC,cAAcA,QAAO,gCAAgCA,QAAO;AACnI,SAAO,oCAAoC,IAAI,gCAAgCA,QAAO;AACxF;AAGA,eAAsB,YAAY,MAAY,KAAa,KAAwBA,UAAgE;AACjJ,QAAM,OAAO,GAAG,eAAe,IAAIA,YAAW,QAAQ;AACtD,QAAM,IAAI,MAAM,KAAK,OAAO,CAAC,QAAQ,MAAM,WAAW,gBAAgB,QAAQ,GAAG,EAAE,KAAK,IAAI,CAAC;AAC7F,MAAI,EAAE,SAAS,GAAG;AAChB,UAAM,WAAW,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM;AAChD,WAAO,EAAE,OAAO,WAAW,cAAc,IAAI,KAAK,YAAY,IAAI,aAAa,EAAE,UAAU,EAAE,QAAQ,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,KAAK,EAAE,GAAG;AAAA,EACrI;AACA,MAAI;AACJ,MAAI;AACF,aAAS,KAAK,MAAM,EAAE,MAAM;AAAA,EAC9B,QAAQ;AACN,WAAO,EAAE,OAAO,YAAY,IAAI,mBAAmB;AAAA,EACrD;AACA,QAAM,MAAM,MAAM,QAAQ,MAAM,IAAI,OAAO,OAAO,SAAS,CAAC,IAAI;AAChE,MAAI,CAACC,UAAS,GAAG,KAAK,OAAO,IAAI,YAAY,SAAU,QAAO,EAAE,OAAO,YAAY,IAAI,oBAAoB;AAC3G,QAAM,OAAOA,UAAS,IAAI,YAAY,IAAI,IAAI,eAAe,CAAC;AAC9D,QAAM,QAAQ,KAAK,aAAa;AAChC,MAAI,OAAO,UAAU,YAAY,CAACF,SAAQ,KAAK,KAAK,EAAG,QAAO,EAAE,OAAO,GAAG,eAAe,IAAI,IAAI,OAAO,kBAAkB,aAAa,GAAG;AAC1I,SAAO,EAAE,SAAS,IAAI,SAAS,MAAM;AACvC;AAGA,eAAsB,QAAQ,MAAgB,MAAe,OAAkB,IAAgC;AAC7G,QAAM,OAAO,iBAAiB,IAAI;AAClC,QAAM,OAAO,CAAC,YAA4B;AACxC,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,WAAW,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,QAAQ,CAAC,CAAC;AAAA,QACrG,IAAG,IAAI,GAAG,OAAO,KAAK,OAAO,EAAE;AACpC,WAAO,MAAM;AAAA,EACf;AACA,MAAI,WAAW,KAAM,QAAO,KAAK,KAAK,KAAK;AAC3C,QAAM,OAAO,GAAG,QAAQ;AAExB,QAAM,UAAU,mBAAmB,GAAG,GAAG;AACzC,MAAI,CAAC,QAAS,QAAO,KAAK,sBAAsB,GAAG,GAAG,2BAA2B,eAAe,+BAA+B,eAAe,gBAAgB,OAAO,QAAQ;AAC7K,QAAM,SAASJ,UAAQ,OAAO;AAC9B,QAAM,aAAa,WAAW,GAAG,GAAG;AACpC,QAAM,YAAY,aAAaA,UAAQ,UAAU,IAAI;AACrD,QAAM,MAAM,CAAC,MAAsBE,UAAS,GAAG,KAAK,CAAC,KAAK;AAE1D,QAAMO,WAAU,MAAM,YAAY,MAAM,QAAQ,GAAG,KAAK,KAAK,OAAO;AACpE,MAAI,WAAWA,SAAS,QAAO,KAAKA,SAAQ,KAAK;AACjD,QAAM,QAAQ,KAAK,SAASA,SAAQ;AAEpC,QAAM,UAAUX,eAAa,SAAS,MAAM;AAC5C,QAAM,UAAU,gBAAgB,SAAS,IAAI,OAAO,GAAGW,SAAQ,SAAS,KAAK;AAC7E,QAAM,WAAWR,OAAK,WAAW,sBAAsB;AACvD,QAAM,WAAWJ,aAAW,QAAQ,IAAIC,eAAa,UAAU,MAAM,IAAI;AACzE,MAAI;AACJ,MAAI,aAAa,QAAW;AAC1B,QAAI;AACF,iBAAW,oBAAoB,UAAU,IAAI,QAAQ,GAAG,KAAK;AAAA,IAC/D,SAAS,GAAG;AACV,aAAO,KAAK,GAAG,IAAI,QAAQ,CAAC,0CAA2C,EAAY,OAAO,GAAG;AAAA,IAC/F;AAAA,EACF;AACA,QAAM,QAAQ,CAAC,GAAG,QAAQ,IAAI;AAC9B,MAAID,aAAWI,OAAK,WAAW,uBAAuB,CAAC,EAAG,OAAM,KAAK,sEAAsE,KAAK,UAAU;AAC1J,MAAI,YAAY;AACd,QAAI;AACF,YAAM,OAAO,UAAU,WAAW,UAAU,EAAE,KAAgCQ,SAAQ,OAAO;AAC7F,UAAI,KAAM,OAAM,KAAK,IAAI;AAAA,IAC3B,QAAQ;AAAA,IAER;AAAA,EACF,OAAO;AACL,UAAM,KAAK,gEAAgE,OAAO,0BAA0B;AAAA,EAC9G;AACA,QAAM,QAAQ,CAAC,GAAG,QAAQ,OAAO,GAAI,UAAU,SAAS,CAAC,CAAE;AAC3D,QAAM,SAAS,CAAC,gBAAgB,SAAS,MAAM,GAAI,KAAK,QAAQ,CAAC,WAAW,KAAK,KAAK,IAAI,CAAC,GAAI,GAAI,KAAK,MAAM,CAAC,SAAS,KAAK,GAAG,IAAI,CAAC,CAAE;AACvI,QAAM,QAAQ;AAAA,IACZ,SAAS,EAAE,KAAK,IAAI,MAAM,KAAK,KAAK,SAAS,mCAAmC;AAAA,IAChF,IAAI,EAAE,KAAK,IAAI,SAAS,KAAK,KAAK,SAAS,OAAO,OAAO,KAAK,GAAG,CAAC,GAAG;AAAA,EACvE;AACA,QAAM,WAAW,EAAE,SAAS,WAAW,SAASA,SAAQ,SAAS,OAAO,OAAO,OAAO,QAAQ,KAAK,OAAO;AAC1G,QAAM,MAAM,CAAC,SAAuB;AAClC,QAAI,CAAC,KAAM,IAAG,IAAI,IAAI;AAAA,EACxB;AAEA,MAAI,GAAG,OAAO,aAAa,eAAe,IAAIA,SAAQ,OAAO,KAAK,aAAa,IAAI,KAAK,EAAE;AAC1F,aAAW,KAAK,MAAO,KAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,KAAK,EAAE,IAAI,OAAO,EAAE,EAAE,EAAE;AACzE,MAAI,MAAM,WAAW,EAAG,KAAI,8BAA8B;AAE1D,MAAI,KAAK,QAAQ;AACf,QAAI,WAAW,MAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,GAAG,WAAW,MAAM,GAAG,OAAO,QAAQ,MAAM,GAAG,GAAG,GAAG;AAC/G,eAAW,KAAK,MAAO,KAAI,WAAW,CAAC,EAAE;AACzC,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,GAAG,UAAU,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,CAAC,CAAC;AACvF,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,QAAQ,SAAS,QAAS,CAAAV,eAAc,SAAS,QAAQ,IAAI;AACjE,MAAI,YAAY,aAAa,UAAa,SAAS,SAAS,SAAU,CAAAA,eAAc,UAAU,SAAS,IAAI;AAC3G,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAI,MAAM,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAEnD,MAAI,CAAC,KAAK,SAAS;AACjB,QAAI,kBAAkB,MAAM,QAAQ,OAAO,QAAQ,MAAM,QAAQ,GAAG,WAAW,MAAM,GAAG,OAAO,QAAQ,MAAM,GAAG,GAAG,GAAG;AACtH,eAAW,KAAK,MAAO,KAAI,WAAW,CAAC,EAAE;AACzC,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,GAAG,UAAU,IAAI,MAAM,UAAU,MAAM,MAAM,OAAO,MAAM,CAAC,CAAC;AAC9F,WAAO,MAAM;AAAA,EACf;AAEA,MAAI,OAAO,MAAM,QAAQ,OAAO,EAAE;AAClC,QAAM,YAAY,MAAM,KAAK,OAAO,CAAC,WAAW,cAAc,WAAW,GAAG,EAAE,KAAK,QAAQ,KAAK,GAAG,IAAI,CAAC;AACxG,MAAI,UAAU,SAAS,GAAG;AACxB,eAAW,KAAK,MAAO,KAAI,WAAW,CAAC,EAAE;AACzC,WAAO,KAAK,4BAA4B,UAAU,IAAI,yDAAyD,MAAM,GAAG,OAAO;AAAA,EAAM,UAAU,OAAO,KAAK,CAAC,EAAE;AAAA,EAChK;AAEA,QAAM,MAAM,iBAAiB,MAAM;AACnC,MAAI,QAAQ,UAAa,QAAQU,SAAQ,QAAS,OAAM,KAAK,sBAAsB,eAAe,IAAI,GAAG,SAASA,SAAQ,OAAO,qBAAqB;AACtJ,MAAIC;AACJ,MAAI,YAAY;AACd,QAAI,OAAO,MAAM,GAAG,OAAO,EAAE;AAC7B,IAAAA,MAAK,MAAM,KAAK,OAAO,QAAQ,EAAE,KAAK,WAAW,KAAK,GAAG,IAAI,CAAC;AAC9D,QAAI,CAAC,QAAQA,IAAG,OAAO,KAAK,EAAG,IAAG,IAAIA,IAAG,OAAO,QAAQ,CAAC;AAAA,EAC3D;AACA,aAAW,KAAK,MAAO,KAAI,WAAW,CAAC,EAAE;AACzC,QAAM,KAAKA,QAAO,UAAaA,IAAG,SAAS;AAC3C,QAAM,WAAWT,OAAK,QAAQ,mBAAmB;AACjD,QAAM,UAAU,CAAC,GAAG,OAAO,GAAIJ,aAAW,QAAQ,IAAI,CAAC,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAE;AAC3E,MAAI,GAAI,KAAI,gCAAgC,QAAQ,KAAK,IAAI,CAAC,kBAAkB,OAAO,YAAY;AAAA,MAC9F,KAAI,KAAK,OAAO,oBAAoBa,KAAI,IAAI,oEAAoE,MAAM,GAAG,OAAO,GAAG;AACxI,QAAM,OAAO,KAAK,MAAM,OAAQA,KAAI,QAAQ,MAAM;AAClD,MAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,GAAG,UAAU,IAAI,UAAU,MAAM,OAAO,SAAS,GAAIA,MAAK,EAAE,IAAI,EAAE,UAAUA,IAAG,KAAK,EAAE,IAAI,CAAC,EAAG,CAAC,CAAC;AAClI,SAAO;AACT;AAGA,SAAS,iBAAiB,KAAiC;AACzD,MAAI;AACF,UAAM,MAAM,KAAK,MAAMZ,eAAaG,OAAK,KAAK,gBAAgB,iBAAiB,cAAc,GAAG,MAAM,CAAC;AACvG,WAAO,OAAO,IAAI,YAAY,WAAW,IAAI,UAAU;AAAA,EACzD,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAGA,SAASO,UAAS,OAAgB,UAA0B;AAC1D,QAAM,SAAS,qBAAqB,KAAK,QAAQ,IAAI,CAAC,KAAK;AAC3D,SAAO,GAAG,KAAK,UAAU,OAAO,MAAM,MAAM,CAAC;AAAA;AAC/C;AAEA,SAASF,UAAS,GAA0C;AAC1D,SAAO,OAAO,MAAM,YAAY,MAAM,QAAQ,CAAC,MAAM,QAAQ,CAAC;AAChE;AAGA,IAAM,YAAkB,CAAC,KAAK,MAAM,SAClC,IAAI,QAAQ,CAAC,SAAS;AACpB,WAAS,KAAK,MAAM,EAAE,KAAK,KAAK,KAAK,KAAK,KAAK,KAAK,WAAW,KAAK,OAAO,MAAM,OAAO,QAAQ,aAAa,QAAQ,GAAG,CAACK,QAAO,QAAQ,WAAW;AACjJ,UAAM,OAAOA,SAAS,OAAQA,OAA6B,SAAS,WAAaA,OAA2B,OAAQ,IAAK;AACzH,SAAK,EAAE,MAAM,QAAQ,OAAO,MAAM,GAAG,QAAQ,OAAO,MAAM,EAAE,CAAC;AAAA,EAC/D,CAAC;AACH,CAAC;;;AChSH;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AAZA,SAAS,cAAAC,oBAAkB;AAC3B,SAAS,WAAAC,WAAS,cAAAC,aAAY,QAAAC,QAAM,WAAAC,gBAAe;AAc5C,IAAM,eAAe;AAsC5B,IAAMC,YAAW,CAAC,oBAAoB,oBAAoB,gBAAgB;AAK1E,IAAI;AAGG,SAAS,uBAAkE;AAChF,mBAAiB,YAAY;AAC3B,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,iCAAiC;AACjF,aAAO,OAAO,EAAE,uBAAuB,aAAc,EAAE,qBAA8C;AAAA,IACvG,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AAYA,eAAsB,aAAa,OAA2B,OAA0E,KAAyG;AAC/O,MAAI,MAAO,QAAO,EAAE,QAAQ,OAAO,MAAM,MAAM;AAC/C,QAAM,SAAS,MAAM,qBAAqB;AAC1C,MAAI,CAAC,OAAQ,QAAO,EAAE,OAAO,eAAe,UAAU;AACtD,MAAIC;AACJ,MAAI;AACF,IAAAA,SAAQ,MAAM,OAAO,EAAE,KAAK,MAAM,KAAK,OAAO,MAAM,OAAO,GAAI,MAAM,UAAU,EAAE,SAAS,MAAM,QAAQ,IAAI,CAAC,GAAI,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC,GAAI,IAAI,CAAC;AAAA,EAC3K,SAAS,GAAG;AACV,WAAO,EAAE,OAAO,GAAG,eAAe,SAAS,sCAAuC,EAAY,OAAO,GAAG;AAAA,EAC1G;AACA,MAAI,CAACA,OAAM,QAAS,QAAO,EAAE,OAAO,eAAe,cAAcA,OAAM,OAAO,EAAE;AAChF,MAAIA,OAAM,IAAI,WAAW,EAAG,QAAO,EAAE,OAAO,eAAe,OAAO,MAAM,KAAK,EAAE;AAC/E,MAAIA,OAAM,IAAI,SAAS,EAAG,QAAO,EAAE,OAAO,eAAe,UAAU,MAAM,OAAOA,OAAM,GAAG,EAAE;AAC3F,SAAO,EAAE,QAAQA,OAAM,IAAI,CAAC,GAAI,MAAM,KAAK;AAC7C;AAEA,IAAI;AACJ,IAAI;AAGG,SAAS,gBAAoD;AAClE,iBAAe,YAAY;AACzB,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,iCAAiC;AACjF,aAAOC,UAAS,MAAM,CAAC,SAAS,OAAO,EAAE,IAAI,MAAM,UAAU,IAAK,IAAiC;AAAA,IACrG,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AAOO,SAAS,qBAAuC;AACrD,sBAAoB,YAAY;AAC9B,QAAI;AAEF,YAAM,IAA6B,MAAM,OAAO,iCAAiC;AACjF,UAAI,OAAO,EAAE,wBAAwB,WAAY,QAAO;AAExD,YAAMC,QAAgC,MAAM,OAAO,8CAA8C;AACjG,aAAO,OAAOA,MAAK,uBAAuB;AAAA,IAC5C,QAAQ;AACN,aAAO;AAAA,IACT;AAAA,EACF,GAAG;AACH,SAAO;AACT;AASO,SAAS,qBAAqB,MAAc,SAAyB;AAC1E,SACE,GAAG,IAAI,uFAAuF,OAAO,uCAChE,WAAW;AAGpD;AAaO,SAAS,WAAW,KAA0E;AACnG,QAAM,OAAO,WAAW,GAAG;AAC3B,MAAI,CAAC,KAAM,QAAO,EAAE,OAAO,qBAAqB,GAAG,sBAAsB,OAAO,eAAe;AAC/F,QAAMC,UAAS,WAAW,IAAI;AAC9B,QAAM,SAAS,YAAYA,OAAM,EAAE,OAAO,CAAC,MAAM,EAAE,aAAa,OAAO;AACvE,MAAI,OAAO,OAAQ,QAAO,EAAE,OAAO,OAAO,IAAI,CAAC,MAAM,GAAG,IAAI,KAAK,EAAE,GAAG,IAAI,EAAE,OAAO,EAAE,EAAE,KAAK,IAAI,EAAE;AAClG,SAAO,EAAE,QAAAA,SAAQ,KAAK;AACxB;AAGO,SAAS,aAAaA,SAAuB,MAAc,KAAa,KAAiD;AAC9H,QAAM,CAAC,SAAS,OAAO,KAAK,IAAI,IAAI,MAAM,GAAG;AAC7C,MAAI,CAAC,WAAW,CAAC,SAAS,UAAU,OAAW,QAAO,EAAE,OAAO,2DAA2D,GAAG,IAAI;AACjI,QAAM,WAAW,gBAAgBA,OAAM;AACvC,QAAM,SAAS,SAASA,QAAO,GAAG;AAClC,QAAM,OAAOC,UAAQ,IAAI;AACzB,QAAM,SAAuC,SAAS,QAAQ,KAAK,CAAC,MAAM,EAAE,SAAS,GAAG,KAAK,SAAS;AACtG,MAAI,QAAQ,UAAa,OAAO,KAAK,MAAM,EAAE,SAAS,KAAK,EAAE,OAAO,SAAS;AAC3E,WAAO,EAAE,OAAO,GAAG,GAAG,2BAA2B,IAAI,oBAAoB,OAAO,KAAK,MAAM,EAAE,KAAK,IAAI,CAAC,sCAAsC;AAAA,EAC/I;AACA,QAAM,KAAK,OAAO,OAAO,GAAG,GAAG,OAAO;AACtC,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,KAAKC,YAAW,EAAE,IAAI,KAAKC,SAAQ,MAAM,EAAE;AAAA,IAC3C,GAAI,OAAO,SAAS,EAAE,QAAQ,OAAO,OAAO,IAAI,CAAC;AAAA,IACjD,GAAI,OAAO,UAAU,EAAE,SAAS,OAAO,QAAQ,IAAI,CAAC;AAAA,EACtD;AACF;AAGO,SAAS,aAAaH,SAA+C;AAC1E,QAAM,IAAI,gBAAgBA,OAAM,EAAE;AAClC,SAAO,EAAE,MAAM,EAAE,YAAY,UAAU,GAAI,EAAE,QAAQ,SAAS,EAAE,QAAQ,EAAE,OAAO,IAAI,CAAC,EAAG;AAC3F;AAGO,SAAS,YAAY,IAAwB,KAAgC;AAClF,SAAO,MAAM,IAAI,gBAAgB,IAAI,qBAAqB,IAAI,QAAQ;AACxE;AAOO,SAAS,cAAc,QAAuB,MAAqBA,SAA+B;AACvG,MAAI,KAAK,YAAY,OAAO,QAAS,QAAO,KAAK;AACjD,QAAM,QAAQ,CAAC,KAAK,WAAW,eAAe,KAAK,KAAK,OAAO;AAC/D,QAAM,MAAM,QAAQ,cAAcA,QAAO,GAAG,EAAE,MAAM;AACpD,SAAO,GAAG,OAAO,cAAc,IAAI,KAAK,OAAO,IAAI,KAAK,KAAK;AAC/D;AAGO,SAAS,mBAAmB,MAAc,QAAgB,MAAsB;AACrF,SAAO,GAAG,OAAO,YAAY,IAAI,SAAS,YAAY,WAAW,MAAM,GAAG,SAAS,WAAW,YAAY,EAAE;AAC9G;AAGA,SAAS,WAAWI,SAAyB,KAA4C;AACvF,QAAM,QAAQ,CAAC,GAAG,IAAI,IAAIA,QAAO,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,MAAmB,MAAM,MAAS,CAAC,CAAC;AACnG,MAAI,MAAM,SAAS,EAAG,QAAO,yCAAyC,MAAM,KAAK,IAAI,CAAC;AACtF,MAAI,MAAM,CAAC,KAAK,CAAC,IAAI,mBAAoB,KAAI,qBAAqB,MAAM,CAAC;AACzE,SAAO;AACT;AAKO,SAAS,cACd,MACA,SACA,MACA,OACA,MACA,MACA,OACA,IACQ;AACR,QAAM,cAAc,QAAQ,WAAW,aAAa,QAAQ,WAAW,YAAY,mBAAmB,MAAM,QAAQ,QAAQ,MAAM,IAAI,IAAI;AAC1I,MAAI;AACJ,MAAI;AACJ,UAAQ,QAAQ,QAAQ;AAAA,IACtB,KAAK;AACH,aAAO,MAAM;AACb,aAAO,eAAe,QAAQ,MAAM,WAAY;AAChD;AAAA,IACF,KAAK;AACH,aAAO,MAAM;AACb,aAAO,GAAG,QAAQ,MAAM,KAAK,eAAe,QAAQ,MAAM,WAAY,CAAC;AACvE;AAAA,IACF,KAAK;AACH,aAAO,MAAM;AACb,aAAO,eAAe,MAAM,IAAI;AAChC;AAAA,IACF,KAAK;AACH,aAAO,MAAM;AACb,aAAO,KAAK,QAAQ,MAAM;AAC1B;AAAA,IACF,KAAK;AACH,aAAO,MAAM;AACb,aAAO,GAAG,OAAO,IAAI,IAAI,KAAK,QAAQ,KAAK;AAC3C;AAAA,EACJ;AACA,MAAI,MAAM;AACR,OAAG,IAAI,KAAK,UAAU;AAAA,MACpB,SAAS;AAAA,MAAM,IAAI,SAAS,MAAM;AAAA,MAAM,UAAU;AAAA,MAAM,QAAQ,QAAQ;AAAA,MAAQ,IAAI;AAAA,MAAc;AAAA,MAAM,QAAQ,QAAQ;AAAA,MACxH,GAAI,cAAc,EAAE,SAAS,YAAY,IAAI,CAAC;AAAA,MAC9C,GAAI,QAAQ,WAAW,SAAS,EAAE,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MAC9D,GAAI,QAAQ,WAAW,WAAW,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,MAC9D,GAAI,QAAQ,WAAW,YAAY,EAAE,WAAW,QAAQ,IAAI,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,IAC1F,CAAC,CAAC;AAAA,EACJ,MAAO,EAAC,SAAS,MAAM,OAAO,GAAG,MAAM,GAAG,KAAK,IAAI;AACnD,SAAO;AACT;AAGA,eAAe,WAAW,MAAY,MAAe,OAAkB,IAAa,MAAgE;AAClJ,QAAM,MAAM,MAAM,cAAc;AAChC,MAAI,CAAC,KAAK;AACR,OAAG,IAAI,GAAG,OAAO,KAAK,qBAAqB,GAAG,OAAO,IAAI,IAAI,IAAI,yCAAyC,CAAC,EAAE;AAC7G,WAAO,MAAM;AAAA,EACf;AACA,MAAI;AACF,WAAO,MAAM,KAAK,GAAG;AAAA,EACvB,SAAS,GAAG;AACV,UAAM,UAAW,EAAY;AAC7B,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,EAAE,SAAS,MAAM,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,QAAQ,CAAC,CAAC;AAAA,QAChG,IAAG,IAAI,GAAG,OAAO,IAAI,IAAI,KAAK,OAAO,EAAE;AAC5C,WAAO,MAAM;AAAA,EACf;AACF;AAGA,SAAS,YAAY,MAAiF;AACpG,QAAM,KAAK,SAAS,MAAM,MAAM;AAChC,QAAM,MAAM,SAAS,GAAG,MAAM,OAAO;AACrC,MAAI,GAAG,QAAS,QAAO,EAAE,MAAM,MAAM,SAAS,OAAO;AACrD,MAAI,IAAI,QAAS,QAAO,EAAE,MAAM,MAAM,SAAS,QAAQ;AACvD,SAAO,EAAE,IAAI,GAAG,OAAO,KAAK,IAAI,OAAO,MAAM,IAAI,KAAK;AACxD;AAGA,eAAsB,YAAY,MAAgB,MAAe,OAAkB,IAA8B;AAC/G,QAAM,SAAS,YAAY,IAAI;AAC/B,MAAI,OAAO,QAAS,QAAO,MAAM,GAAG,OAAO,OAAO,kBAAkB,OAAO,EAAE;AAC7E,QAAM,MAAM,SAAS,OAAO,MAAM,OAAO;AACzC,MAAI,IAAI,QAAS,QAAO,MAAM,kDAAkD,OAAO,EAAE;AACzF,QAAM,QAAQ,IAAI,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AACtD,MAAI,MAAM,OAAQ,QAAO,MAAM,wBAAwB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACnF,QAAM,QAAQ,YAAY,IAAI,IAAI;AAClC,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,2BAA2B,eAAe,MAAM,MAAM,IAAI,OAAO,EAAE;AACxG,MAAI,CAAC,IAAI,MAAO,QAAO,MAAM,qFAAqF,eAAe,MAAM,MAAM,IAAI,OAAO,EAAE;AAC1J,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,QAAQ,aAAa,KAAK,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAI,OAAO,GAAG;AACxE,MAAI,WAAW,MAAO,QAAO,MAAM,MAAM,OAAO,OAAO,EAAE;AACzD,aAAW,CAAC,KAAK,GAAG,GAAG,GAAG;AAC1B,QAAM,QAAQ,aAAa,KAAK,MAAM;AACtC,QAAM,UAAUD,SAAQ,GAAG,KAAK,IAAI,KAAK;AACzC,SAAO,WAAW,UAAU,MAAM,OAAO,IAAI,OAAO,QAAQ;AAC1D,UAAM,UAAU,MAAM,IAAI,iBAAiB;AAAA,MACzC,IAAI,YAAY,OAAO,IAAI,GAAG,GAAG;AAAA,MAAG;AAAA,MAAO,IAAI;AAAA,MAAc,WAAW,GAAG;AAAA,MAAK,KAAK,GAAG;AAAA,MACxF,KAAK,MAAM;AAAA,MAAK,OAAO,MAAM;AAAA,MAAO,KAAK;AAAA,MAAS,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IACnG,CAAC;AACD,WAAO,cAAc,UAAU,SAAS,MAAM,OAAO,OAAO,CAAC,MAAM,eAAe,SAAS,MAAM,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE;AAAA,EAC3H,CAAC;AACH;AAGA,eAAsB,YAAY,MAAgB,MAAe,OAAkB,IAA8B;AAC/G,QAAM,SAAS,YAAY,IAAI;AAC/B,MAAI,OAAO,QAAS,QAAO,MAAM,GAAG,OAAO,OAAO,kBAAkB,OAAO,EAAE;AAC7E,QAAM,OAAO,SAAS,OAAO,MAAM,QAAQ;AAC3C,MAAI,KAAK,QAAS,QAAO,MAAM,4BAA4B,OAAO,EAAE;AACpE,QAAM,QAAQ,KAAK,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AACvD,MAAI,MAAM,OAAQ,QAAO,MAAM,wBAAwB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACnF,QAAM,QAAQ,YAAY,KAAK,IAAI;AACnC,MAAI,MAAM,WAAW,EAAG,QAAO,MAAM,2BAA2B,eAAe,MAAM,MAAM,IAAI,OAAO,EAAE;AACxG,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,QAAQ,aAAa,KAAK,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAI,OAAO,GAAG;AACxE,MAAI,WAAW,MAAO,QAAO,MAAM,MAAM,OAAO,OAAO,EAAE;AACzD,aAAW,CAAC,KAAK,GAAG,GAAG,GAAG;AAE1B,QAAM,SAAS,MAAM,aAAa,KAAK,OAAO,OAAO,GAAG,GAAG;AAC3D,MAAI,WAAW,OAAQ,QAAO,MAAM,OAAO,OAAO,OAAO,EAAE;AAC3D,MAAI,OAAO,QAAQ,CAAC,KAAM,IAAG,IAAI,GAAG,OAAO,YAAY,MAAM,GAAG,eAAe,OAAO,MAAM,EAAE;AAC9F,QAAM,QAAQ,aAAa,KAAK,MAAM;AACtC,SAAO,WAAW,UAAU,MAAM,OAAO,IAAI,OAAO,QAAQ;AAC1D,UAAM,UAAU,MAAM,IAAI,iBAAiB;AAAA,MACzC,IAAI,YAAY,OAAO,IAAI,GAAG,GAAG;AAAA,MAAG;AAAA,MAAO,IAAI;AAAA,MAAc,WAAW,GAAG;AAAA,MAAK,KAAK,GAAG;AAAA,MACxF,KAAK,MAAM;AAAA,MAAK,OAAO,MAAM;AAAA,MAAO,QAAQ,OAAO;AAAA,MAAQ,SAAS,MAAM;AAAA,MAAS,GAAI,MAAM,SAAS,EAAE,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,IACpI,CAAC;AACD,WAAO,cAAc,UAAU,SAAS,MAAM,OAAO,OAAO,CAAC,MAAM,eAAe,UAAU,MAAM,KAAK,OAAO,QAAQ,EAAE,WAAW,GAAG,MAAM,OAAO,EAAE;AAAA,EACvJ,CAAC;AACH;AAMA,eAAsB,UAAU,MAAgB,MAAe,OAAkB,IAA8B;AAC7G,QAAM,OAAO,SAAS,MAAM,QAAQ;AACpC,MAAI,KAAK,QAAS,QAAO,MAAM,uBAAuB,OAAO,EAAE;AAC/D,MAAI,KAAK,UAAU,OAAW,QAAO,eAAe,KAAK,OAAO,KAAK,MAAM,MAAM,OAAO,EAAE;AAE1F,QAAM,SAAS,YAAY,KAAK,IAAI;AACpC,MAAI,OAAO,QAAS,QAAO,MAAM,GAAG,OAAO,OAAO,kBAAkB,OAAO,EAAE;AAC7E,QAAM,OAAO,SAAS,OAAO,MAAM,QAAQ;AAC3C,QAAM,KAAK,SAAS,KAAK,MAAM,MAAM;AACrC,MAAI,KAAK,WAAW,GAAG,QAAS,QAAO,MAAM,GAAG,KAAK,UAAU,WAAW,MAAM,oCAAoC,OAAO,EAAE;AAC7H,QAAM,QAAQ,GAAG,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AACrD,MAAI,MAAM,OAAQ,QAAO,MAAM,sBAAsB,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACjF,MAAI,OAAO,QAAQ,OAAW,QAAO,MAAM,0FAA0F,OAAO,EAAE;AAC9I,QAAM,OAAO,YAAY,GAAG,IAAI;AAChC,MAAI,CAAC,KAAK,SAAS,CAAC,GAAG,MAAO,QAAO,MAAM,+BAA+B,eAAe,MAAM,IAAI,IAAI,OAAO,EAAE;AAChH,MAAI,KAAK,WAAW,EAAG,QAAO,MAAM,6CAA6C,eAAe,MAAM,IAAI,IAAI,OAAO,EAAE;AACvH,QAAM,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,EAAE,WAAW,aAAa,CAAC;AAC3D,MAAI,IAAI,OAAQ,QAAO,MAAM,yCAAyC,IAAI,KAAK,IAAI,CAAC,2CAA2C,OAAO,EAAE;AACxI,MAAI,KAAK,UAAU,GAAG,MAAO,QAAO,MAAM,4BAA4B,KAAK,KAAK,kCAAkC,OAAO,EAAE;AAE3H,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,SAAS,aAAa,KAAK,QAAQ,KAAK,MAAM,KAAK,OAAO,MAAS;AACzE,MAAI,WAAW,OAAQ,QAAO,MAAM,OAAO,OAAO,OAAO,EAAE;AAC3D,QAAM,OAAO,aAAa,KAAK,QAAQ,KAAK,MAAM,GAAG,OAAO,MAAS;AACrE,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,UAAU,WAAW,CAAC,QAAQ,IAAI,GAAG,GAAG,GAAG;AACjD,MAAI,QAAS,QAAO,MAAM,SAAS,OAAO,EAAE;AAC5C,QAAM,QAAQ,aAAa,KAAK,MAAM;AACtC,QAAM,WAAW,cAAc,QAAQ,MAAM,KAAK,MAAM;AACxD,QAAME,UAAS,OAAO,UAAU,KAAK;AACrC,SAAO,WAAW,QAAQ,MAAM,OAAO,IAAI,OAAO,QAAQ;AACxD,UAAM,UAAU,MAAM,IAAI,eAAe;AAAA,MACvC,IAAI,YAAY,OAAO,IAAI,GAAG,GAAG;AAAA,MAAG;AAAA,MAAO,IAAI;AAAA,MAAc,WAAW,GAAG;AAAA,MAAK,KAAK,GAAG;AAAA,MACxF,QAAQ,EAAE,QAAQ,OAAO,KAAK,KAAK,OAAO,KAAK,OAAO,OAAO,MAAM;AAAA,MACnE,MAAM,EAAE,QAAQ,KAAK,KAAK,KAAK,KAAK,KAAK,OAAO,SAAS;AAAA,MACzD;AAAA,MACA,GAAIA,UAAS,EAAE,QAAAA,QAAO,IAAI,CAAC;AAAA,IAC7B,CAAC;AACD,WAAO,cAAc,QAAQ,SAAS,QAAQ,OAAO,KAAK,IAAI,QAAQ,IAAI,OAAO,CAAC,MAAM,eAAe,MAAM,OAAO,KAAK,KAAK,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE;AAAA,EACxJ,CAAC;AACH;AAGA,eAAe,eAAeA,SAAgB,MAAgB,MAAe,OAAkB,IAA8B;AAC3H,MAAIA,YAAW,SAAU,QAAO,MAAM,6BAA6BA,OAAM,+DAA+D,OAAO,aAAa,OAAO,EAAE;AACrK,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAClD,MAAI,MAAM,OAAQ,QAAO,MAAM,6BAA6B,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACxF,QAAM,QAAQ,YAAY,IAAI;AAC9B,MAAI,MAAM,SAAS,EAAG,QAAO,MAAM,8CAA8C,OAAO,EAAE;AAC1F,QAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,MAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,QAAM,SAASC,OAAKL,UAAQ,KAAK,IAAI,GAAG,aAAa;AACrD,MAAI,CAACM,aAAW,MAAM,EAAG,QAAO,MAAM,eAAe,UAAU,MAAM,GAAG,OAAO,EAAE;AACjF,MAAI,MAAM,CAAC,GAAG;AACZ,UAAM,QAAQ,aAAa,KAAK,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAG,MAAS;AACtE,QAAI,WAAW,MAAO,QAAO,MAAM,MAAM,OAAO,OAAO,EAAE;AACzD,QAAI,CAAC,KAAM,IAAG,IAAI,eAAe,SAAS,MAAM,GAAG,CAAC;AAAA,EACtD;AACA,QAAM,OAAO,CAAC,OAAO,UAAU,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AAC1D,SAAO,UAAU,GAAG,OAAO,uBAAuB,OAAO,IAAI,OAAO,UAAU;AAC5E,UAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM,aAAa;AAC9D,QAAI,SAAS,MAAM,WAAW,CAAC,KAAM,IAAG,IAAI,eAAe,YAAY;AACvE,WAAO,SAAS,MAAM,UAAU,OAAO,eAAe,MAAM,OAAO,GAAG,GAAG;AAAA,EAC3E,CAAC;AACH;AAQA,eAAsB,cAAc,MAAgB,MAAe,OAAkB,IAA8B;AACjH,QAAMC,WAAU,SAAS,MAAM,WAAW;AAC1C,QAAM,MAAM,SAASA,SAAQ,MAAM,OAAO;AAC1C,QAAM,SAAS,SAAS,IAAI,MAAM,UAAU;AAC5C,QAAM,QAAQ,SAAS,OAAO,MAAM,SAAS;AAC7C,aAAW,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,aAAaA,QAAO,GAAG,CAAC,SAAS,GAAG,GAAG,CAAC,YAAY,MAAM,GAAG,CAAC,WAAW,KAAK,CAAC,GAAY;AACnH,QAAI,EAAE,QAAS,QAAO,MAAM,GAAG,IAAI,kBAAkB,OAAO,EAAE;AAAA,EAChE;AACA,QAAM,WAAqB,MAAM,KAAK,OAAO,CAAC,MAAM,MAAM,eAAe,MAAM,eAAe;AAC9F,QAAM,OAAO,MAAM,KAAK,OAAO,CAAC,MAAM,CAAC,SAAS,SAAS,CAAC,CAAC;AAC3D,QAAM,QAAQ,KAAK,OAAO,CAAC,MAAM,EAAE,WAAW,GAAG,CAAC;AAClD,MAAI,MAAM,OAAQ,QAAO,MAAM,0BAA0B,MAAM,KAAK,GAAG,CAAC,IAAI,OAAO,EAAE;AACrF,QAAM,QAAQ,YAAY,IAAI;AAC9B,MAAI,MAAM,SAAS,EAAG,QAAO,MAAM,6BAA6B,eAAe,MAAM,QAAQ,IAAI,OAAO,EAAE;AAE1G,MAAI;AACJ,MAAIA,SAAQ,UAAU,QAAW;AAC/B,QAAI,MAAM,OAAQ,QAAO,MAAM,eAAe,iBAAiB,MAAM,CAAC,GAAI,cAAc,MAAM,CAAC,CAAE,CAAC,GAAG,OAAO,EAAE;AAC9G,QAAI,OAAO,UAAU,OAAW,QAAO,MAAM,+EAA+E,OAAO,EAAE;AACrI,QAAI,CAAC,IAAI,MAAO,QAAO,MAAM,+EAA+E,eAAe,MAAM,QAAQ,IAAI,OAAO,EAAE;AACtJ,WAAO,CAAC,cAAc,YAAY,IAAI,OAAO,aAAaA,SAAQ,KAAK;AAAA,EACzE,OAAO;AACL,QAAI,MAAM,WAAW,EAAG,QAAO,MAAM,4DAA4D,eAAe,MAAM,QAAQ,IAAI,OAAO,EAAE;AAC3I,UAAM,OAAO,WAAW,GAAG,GAAG;AAC9B,QAAI,WAAW,KAAM,QAAO,MAAM,KAAK,OAAO,OAAO,EAAE;AACvD,UAAM,QAAQ,aAAa,KAAK,QAAQ,KAAK,MAAM,MAAM,CAAC,GAAI,MAAS;AACvE,QAAI,WAAW,MAAO,QAAO,MAAM,MAAM,OAAO,OAAO,EAAE;AAEzD,WAAO,CAAC,cAAc,YAAY,IAAI,SAAS,cAAc,MAAM,KAAK,GAAG,eAAe,KAAK,MAAM,GAAG,GAAG,GAAI,OAAO,QAAQ,CAAC,YAAY,OAAO,KAAK,IAAI,CAAC,CAAE;AAAA,EAChK;AACA,OAAK,KAAK,GAAI,MAAM,QAAQ,CAAC,WAAW,MAAM,KAAK,IAAI,CAAC,GAAI,GAAG,UAAU,GAAI,OAAO,CAAC,QAAQ,IAAI,CAAC,CAAE;AAEpG,MAAI,CAAE,MAAM,mBAAmB,GAAI;AACjC,OAAG,IAAI,GAAG,OAAO,KAAK,qBAAqB,GAAG,OAAO,aAAa,6CAA6C,CAAC,EAAE;AAClH,WAAO,MAAM;AAAA,EACf;AACA,SAAO,UAAU,GAAG,OAAO,aAAa,OAAO,IAAI,OAAO,UAAU;AAClE,UAAM,OAAO,MAAM,MAAM,kBAAkB,MAAM,aAAa;AAC9D,QAAI,SAAS,MAAM,WAAW,CAAC,KAAM,IAAG,IAAI,eAAe,eAAe;AAC1E,WAAO,SAAS,MAAM,UAAU,OAAO,eAAe,MAAM,OAAO,GAAG,GAAG;AAAA,EAC3E,CAAC;AACH;;;ATreA;AAKO,IAAMC,WAAU,OAA0C,UAAsB;AAOvF,IAAM,QAAY;AAAA,EAChB,KAAK,CAAC,MAAM,QAAQ,OAAO,MAAM,IAAI,IAAI;AAAA,EACzC,KAAK,CAAC,MAAM,QAAQ,OAAO,MAAM,IAAI,IAAI;AAC3C;AAEO,SAAS,WAAmB;AACjC,QAAM,QAAQ,KAAK,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,EAAE,KAAK,MAAM,CAAC;AACzD,SAAO;AAAA,IACL,GAAG,OAAO,KAAK,OAAO;AAAA,IACtB;AAAA,IACA,UAAU,OAAO;AAAA,IACjB;AAAA,IACA;AAAA,IACA,GAAG,MAAM,IAAI,CAAC,MAAM,KAAK,EAAE,KAAK,OAAO,KAAK,CAAC,KAAK,EAAE,OAAO,EAAE;AAAA,IAC7D;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACF;AAAA,IACA;AAAA,IACE;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,EAAE,KAAK,IAAI;AACb;AAGA,eAAsB,KAAK,MAAgB,KAAS,OAAwB;AAC1E,QAAM,EAAE,OAAO,OAAO,IAAI,MAAM,UAAU;AAC1C,QAAM,OAAO,KAAK,SAAS,QAAQ;AACnC,QAAM,OAAO,KAAK,OAAO,CAAC,MAAM,MAAM,QAAQ;AAC9C,QAAM,OAAO,KAAK,CAAC;AACnB,QAAM,OAAO,CAAC,UAAmC,MAAc,QAAQ,UAAgB;AACrF,QAAI,KAAM,IAAG,IAAI,KAAK,UAAU,QAAQ,CAAC;AAAA,QACpC,EAAC,QAAQ,GAAG,MAAM,GAAG,KAAK,IAAI;AAAA,EACrC;AAEA,MAAI,SAAS,UAAa,SAAS,YAAY,SAAS,QAAQ,SAAS,QAAQ;AAC/E,SAAK,EAAE,SAAS,QAAQ,IAAI,MAAM,UAAU,MAAM,MAAM,OAAO,MAAM,GAAG,SAAS,CAAC;AAClF,WAAO,MAAM;AAAA,EACf;AACA,MAAI,SAAS,eAAe,SAAS,MAAM;AACzC,SAAK,EAAE,SAAS,WAAW,IAAI,MAAM,UAAU,MAAM,MAAM,SAASA,UAAS,WAAW,OAAO,GAAGA,QAAO;AACzG,WAAO,MAAM;AAAA,EACf;AAEA,QAAM,qBAAqB;AAE3B,QAAM,qBAAqB;AAC3B,QAAM,UAAmB,EAAE,KAAK,GAAG,KAAK,KAAK,GAAG,KAAK,KAAK,QAAQ,IAAI,GAAG,KAAK,QAAQ,IAAI;AAE1F,MAAI,SAAS,YAAY,SAAS,UAAU,SAAS,UAAU,SAAS,UAAW,OAAM,eAAe,QAAQ,KAAK,QAAQ,GAAG;AAChI,MAAI,SAAS,QAAS,QAAOC,OAAM,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACtE,MAAI,SAAS,YAAY,KAAK,CAAC,MAAM,aAAc,QAAO,iBAAiB,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC9G,MAAI,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,CAAC,GAAG,OAAO,IAAI;AAC/D,MAAI,SAAS,QAAS,QAAO,WAAW,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC3E,MAAI,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACxE,MAAI,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACxE,MAAI,SAAS,UAAW,QAAOC,SAAQ,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC1E,MAAI,SAAS,QAAQ;AACnB,UAAM,cAAc,CAAC,QAAQ,CAAC,KAAK,SAAS,OAAO,KAAK,CAAC,KAAK,SAAS,IAAI,KAAK,QAAQ,MAAM,UAAU,QAAQ,QAAQ,OAAO,UAAU;AACzI,UAAM,SAAiB,cAAc,EAAE,GAAG,SAAS,KAAK,cAAc,IAAI;AAC1E,WAAO,KAAK,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,MAAM;AAAA,EAChD;AACA,MAAI,SAAS,UAAW,QAAO,QAAQ,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC1E,MAAI,SAAS,QAAS,QAAO,MAAM,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACtE,MAAI,SAAS,UAAW,QAAO,QAAQ,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC1E,MAAI,SAAS,KAAM,QAAO,GAAG,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAChE,MAAI,SAAS,SAAU,QAAO,OAAO,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACxE,MAAI,SAAS,UAAW,QAAO,QAAQ,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC1E,MAAI,SAAS,WAAY,QAAO,SAAS,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC5E,MAAI,SAAS,SAAU,QAAO,YAAY,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC7E,MAAI,SAAS,SAAU,QAAO,YAAY,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAC7E,MAAI,SAAS,OAAQ,QAAO,UAAU,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACzE,MAAI,SAAS,WAAY,QAAO,cAAc,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACjF,MAAI,SAAS,QAAS,QAAOC,OAAM,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AACtE,MAAI,SAAS,MAAO,QAAO,IAAI,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAClE,MAAI,SAAS,QAAS,QAAO,MAAM,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO;AAEtE,MAAI,SAAS,MAAM;AACjB,UAAM,MAAM,KAAK,CAAC;AAClB,WAAO,QAAQ,UAAa,IAAI,WAAW,GAAG,IAAI,GAAG,KAAK,MAAM,CAAC,GAAG,MAAM,OAAO,OAAO,IAAI,YAAY,MAAM,OAAO,OAAO;AAAA,EAC9H;AACA,MAAK,kBAAwC,SAAS,IAAI,EAAG,QAAO,YAAY,MAAM,OAAO,OAAO;AACpG,MAAI,SAAS,OAAQ,QAAO,KAAK,KAAK,CAAC,GAAG,OAAO,IAAI;AACrD,QAAM,QAAQ,MAAM,KAAK,CAAC,MAAM,EAAE,SAAS,IAAI;AAC/C,MAAI,CAAC,OAAO;AAEV,UAAM,UAAU,oBAAoB,IAAI,WAAW,OAAO;AAC1D,SAAK,EAAE,SAAS,MAAM,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,QAAQ,GAAG,GAAG,OAAO,KAAK,OAAO,IAAI,IAAI;AACzG,WAAO,MAAM;AAAA,EACf;AACA,SAAO,SAAS,MAAM,MAAM,MAAM,QAAQ,IAAI;AAChD;AAGA,eAAe,cAAc,UAAkB,SAA4B,UAAmC;AAC5G,QAAM,EAAE,gBAAgB,IAAI,MAAM,OAAO,wBAAwB;AACjE,QAAM,KAAK,gBAAgB,EAAE,OAAO,QAAQ,OAAO,QAAQ,QAAQ,OAAO,CAAC;AAC3E,MAAI;AACF,eAAS;AACP,YAAM,UAAU,MAAM,GAAG,SAAS,GAAG,QAAQ,KAAK,QAAQ,IAAI,CAAC,GAAG,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,EAAE,KAAK,IAAI,CAAC,MAAM,QAAQ,KAAK,GAAG,KAAK;AAC/H,UAAI,WAAW,GAAI,QAAO;AAC1B,YAAM,WAAW,QAAQ,OAAO,MAAM,IAAI,CAAC;AAC3C,UAAI,SAAU,QAAO;AACrB,UAAI,QAAQ,SAAS,MAAM,EAAG,QAAO;AAAA,IACvC;AAAA,EACF,UAAE;AACA,OAAG,MAAM;AAAA,EACX;AACF;AAEA,SAAS,SACP,MACA,MACA,MACQ;AACR,QAAM,UAAU,GAAG,OAAO,IAAI,IAAI;AAClC,OAAK,EAAE,SAAS,MAAM,IAAI,OAAO,UAAU,MAAM,OAAO,QAAQ,GAAG,GAAG,OAAO,KAAK,OAAO,IAAI,IAAI;AACjG,SAAO;AACT;AAGA,SAAS,KAAK,IAAwB,OAAkB,MAAoB;AAC1E,QAAM,SAAS,OAAO,SAAY,OAAO,CAAC,QAAQ,EAAE,CAAC,EAAE,OAAO,CAAC,MAAM,MAAM,MAAS;AACpF,MAAI,OAAO,WAAW,GAAG;AACvB,UAAM,UAAU,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC,MAAM,EAAE,EAAE,EAAE,KAAK,IAAI,CAAC;AAChF,SAAK,EAAE,SAAS,QAAQ,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,QAAQ,GAAG,GAAG,OAAO,KAAK,OAAO,IAAI,IAAI;AAC3G,WAAO,MAAM;AAAA,EACf;AACA,OAAK,EAAE,SAAS,QAAQ,IAAI,MAAM,UAAU,MAAM,MAAM,MAAM,OAAO,GAAG,SAAS,MAAM,EAAE,KAAK,IAAI,CAAC;AACnG,SAAO,MAAM;AACf;AAKA,SAAS,OAAO,MAAgB,OAAkB,MAAoB;AACpE,QAAM,CAAC,KAAK,GAAG,IAAI,IAAI;AACvB,QAAM,UAAU,UAAU,OAAO,EAAE,GAAG,KAAK;AAC3C,QAAM,SAAS,KAAK,QAAQ,QAAQ;AACpC,QAAM,OAAO,UAAU,IAAI,KAAK,SAAS,CAAC,IAAI;AAC9C,MAAI,QAAQ,WAAY,UAAU,KAAK,CAAC,MAAO;AAC7C,UAAM,UAAU,QAAQ,UAAU,2BAA2B,OAAO,EAAE,WAAW,OAAO,sBAAsB,OAAO,yBAAyB;AAC9I,SAAK,EAAE,SAAS,IAAI,OAAO,UAAU,MAAM,QAAQ,OAAO,QAAQ,GAAG,GAAG,OAAO,KAAK,OAAO,IAAI,IAAI;AACnG,WAAO,MAAM;AAAA,EACf;AACA,QAAM,IAAI,YAAY,QAAQ,IAAI,GAAG,IAAI;AACzC,QAAM,OAAO,EAAE,KAAK,MAAM,OAAO,MAAM;AACvC,OAAK,EAAE,SAAS,IAAI,EAAE,IAAI,UAAU,MAAM,GAAG,EAAE,SAAS,GAAG,EAAE,MAAM,KAAK,IAAI,GAAG,CAAC,EAAE,EAAE;AACpF,SAAO;AACT;;;AUlQA,QAAQ,WAAW,MAAM,KAAK,QAAQ,KAAK,MAAM,CAAC,CAAC;",
6
+ "names": ["VARIABLE", "jobs", "lines", "observedAt", "approve", "engine", "engine", "version", "lines", "engine", "init_images", "version", "init_images", "preview", "up", "VARIABLE", "init_images", "engine", "notify", "VARIABLE", "config", "init_images", "config", "config", "lines", "engine", "locks", "later", "existsSync", "readFileSync", "dirname", "join", "parseYAML", "stacksOf", "config", "REQUIRED", "cached", "lines", "indentOf", "lines", "at", "item", "existsSync", "readFileSync", "dirname", "join", "cached", "init_review_stacks", "existsSync", "readdirSync", "readFileSync", "writeFileSync", "mkdirSync", "dirname", "join", "lines", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "dirname", "join", "policy", "engine", "notify", "detected", "has", "init_jobs", "init_images", "existsSync", "readFileSync", "join", "ci", "up", "config", "init_review_stacks", "createHash", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "dirname", "join", "stacks", "drift", "config", "notify", "loaded", "audit", "lines", "engine", "jobs", "writeIfChanged", "OP_OUTPUT_DIR", "init_drift", "init_images", "init_jobs", "tips", "existsSync", "mkdirSync", "readdirSync", "readFileSync", "writeFileSync", "dirname", "join", "engine", "writeIfChanged", "OP_OUTPUT_DIR", "init_agents", "readFileSync", "cached", "cached", "stacks", "detected", "stacks", "init_engine", "readFileSync", "stacks", "lines", "ci", "join", "cached", "stacks", "reader", "existsSync", "readFileSync", "join", "posix", "parseYAML", "detected", "stacks", "init_types", "readdirSync", "basename", "dirname", "join", "detected", "init_types", "detected", "init_types", "up", "readdirSync", "join", "WORKFLOW_DIRS", "init_types", "detected", "version", "CARRIED", "init_types", "detected", "stacks", "images", "basename", "detected", "init_types", "WAVES_SPEC_FILE", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "emitYAMLEntry", "dirname", "join", "posix", "preset", "engine", "detected", "forgeFor", "forge", "config", "problems", "reviewStacks", "stacks", "noteControlTarget", "control", "check", "lines", "init_jobs", "init_engine", "init_review_stacks", "control", "existsSync", "readFileSync", "writeFileSync", "dirname", "join", "emitYAMLEntry", "parseYAML", "cached", "REQUIRED", "readYamlFile", "lines", "require", "mkdirSync", "r", "estates", "runInit", "init_control", "existsSync", "readFileSync", "join", "locks", "jobs", "config", "reviewStacks", "prJobsFor", "hasChant4625", "withJobSettings", "noteControlTarget", "wavesControl", "control", "check", "init_review_stacks", "init_drift", "init_agents", "audit", "init_agents", "init_drift", "dirname", "config", "drift", "dirname", "existsSync", "mkdirSync", "readFileSync", "writeFileSync", "join", "has", "init_jobs", "existsSync", "readFileSync", "dirname", "join", "config", "lines", "stacks", "FORGES", "join", "existsSync", "readFileSync", "jobs", "identity", "FORGES", "config", "dirname", "init_control", "existsSync", "readFileSync", "writeFileSync", "dirname", "join", "relative", "resolve", "VERSION", "version", "isObject", "up", "jsonText", "release", "ci", "error", "existsSync", "dirname", "isAbsolute", "join", "resolve", "REQUIRED", "locks", "REQUIRED", "copy", "config", "dirname", "isAbsolute", "resolve", "stacks", "engine", "join", "existsSync", "release", "VERSION", "audit", "control", "drift"]
7
+ }