@homeflare/alchemy 0.19.0 → 0.19.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/linux/index.js +107 -86
- package/dist/linux/index.js.map +6 -5
- package/dist/linux/unit-lifecycle.d.ts +1 -5
- package/dist/linux/unit-lifecycle.d.ts.map +1 -1
- package/dist/linux/unit-preflight.d.ts +41 -0
- package/dist/linux/unit-preflight.d.ts.map +1 -0
- package/docs/linux-host.md +7 -1
- package/package.json +1 -1
- package/src/linux/unit-lifecycle.ts +12 -30
- package/src/linux/unit-preflight.test.ts +128 -0
- package/src/linux/unit-preflight.ts +100 -0
- package/src/proxmox/constraints-forms.test.ts +14 -6
- package/src/proxmox/constraints-node-forms.test.ts +12 -3
package/dist/linux/index.js
CHANGED
|
@@ -914,6 +914,80 @@ import { Unowned as Unowned4 } from "alchemy/AdoptPolicy";
|
|
|
914
914
|
import { isResolved as isResolved3 } from "alchemy/Diff";
|
|
915
915
|
import * as Effect8 from "effect/Effect";
|
|
916
916
|
|
|
917
|
+
// src/linux/systemctl.ts
|
|
918
|
+
var SYSTEMCTL = "systemctl";
|
|
919
|
+
var SHOW_PROPERTIES = [
|
|
920
|
+
"Id",
|
|
921
|
+
"LoadState",
|
|
922
|
+
"ActiveState",
|
|
923
|
+
"SubState",
|
|
924
|
+
"UnitFileState",
|
|
925
|
+
"FragmentPath",
|
|
926
|
+
"NeedDaemonReload"
|
|
927
|
+
];
|
|
928
|
+
|
|
929
|
+
class SystemctlError extends Error {
|
|
930
|
+
constructor(command, exitCode, stderr) {
|
|
931
|
+
super(`systemctl ${command} -> ${String(exitCode)}: ${stderr.trim().slice(0, 300)}`);
|
|
932
|
+
this.name = "SystemctlError";
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
var parseShow = (stdout) => {
|
|
936
|
+
const fields = new Map;
|
|
937
|
+
for (const line of stdout.split(`
|
|
938
|
+
`)) {
|
|
939
|
+
const at = line.indexOf("=");
|
|
940
|
+
if (at <= 0)
|
|
941
|
+
continue;
|
|
942
|
+
const key = line.slice(0, at);
|
|
943
|
+
if (!fields.has(key))
|
|
944
|
+
fields.set(key, line.slice(at + 1));
|
|
945
|
+
}
|
|
946
|
+
return fields;
|
|
947
|
+
};
|
|
948
|
+
var statusOf = (stdout) => {
|
|
949
|
+
const fields = parseShow(stdout);
|
|
950
|
+
const loadState = fields.get("LoadState") ?? "not-found";
|
|
951
|
+
const unitFileState = fields.get("UnitFileState") ?? "";
|
|
952
|
+
const fragmentPath = fields.get("FragmentPath") ?? "";
|
|
953
|
+
const subState = fields.get("SubState") ?? "";
|
|
954
|
+
return {
|
|
955
|
+
activeState: fields.get("ActiveState") ?? "inactive",
|
|
956
|
+
known: loadState !== "not-found" || unitFileState !== "",
|
|
957
|
+
loadState,
|
|
958
|
+
needDaemonReload: fields.get("NeedDaemonReload") === "yes",
|
|
959
|
+
...subState === "" ? {} : { subState },
|
|
960
|
+
...unitFileState === "" ? {} : { unitFileState },
|
|
961
|
+
...fragmentPath === "" ? {} : { fragmentPath }
|
|
962
|
+
};
|
|
963
|
+
};
|
|
964
|
+
var showUnit = async (runner, name) => {
|
|
965
|
+
const result = await runner.exec([
|
|
966
|
+
SYSTEMCTL,
|
|
967
|
+
"show",
|
|
968
|
+
"--no-pager",
|
|
969
|
+
"-p",
|
|
970
|
+
SHOW_PROPERTIES.join(","),
|
|
971
|
+
"--",
|
|
972
|
+
name
|
|
973
|
+
]);
|
|
974
|
+
if (result.exitCode !== 0)
|
|
975
|
+
throw new SystemctlError(`show ${name}`, result.exitCode, result.stderr);
|
|
976
|
+
return statusOf(result.stdout);
|
|
977
|
+
};
|
|
978
|
+
var run = async (runner, args) => {
|
|
979
|
+
const result = await runner.exec([SYSTEMCTL, ...args]);
|
|
980
|
+
if (result.exitCode !== 0) {
|
|
981
|
+
throw new SystemctlError(args.join(" "), result.exitCode, result.stderr);
|
|
982
|
+
}
|
|
983
|
+
};
|
|
984
|
+
var daemonReload = (runner) => run(runner, ["daemon-reload"]);
|
|
985
|
+
var enableUnit = (runner, name) => run(runner, ["enable", "--", name]);
|
|
986
|
+
var disableUnit = (runner, name) => run(runner, ["disable", "--", name]);
|
|
987
|
+
var startUnit = (runner, name) => run(runner, ["start", "--", name]);
|
|
988
|
+
var stopUnit = (runner, name) => run(runner, ["stop", "--", name]);
|
|
989
|
+
var restartUnit = (runner, name) => run(runner, ["restart", "--", name]);
|
|
990
|
+
|
|
917
991
|
// src/linux/unit-form.ts
|
|
918
992
|
var DEFAULT_UNIT_DIRECTORY = "/etc/systemd/system";
|
|
919
993
|
var UNIT_SEARCH_DIRECTORIES = [
|
|
@@ -994,80 +1068,6 @@ var textProblems = (text) => {
|
|
|
994
1068
|
return found;
|
|
995
1069
|
};
|
|
996
1070
|
|
|
997
|
-
// src/linux/systemctl.ts
|
|
998
|
-
var SYSTEMCTL = "systemctl";
|
|
999
|
-
var SHOW_PROPERTIES = [
|
|
1000
|
-
"Id",
|
|
1001
|
-
"LoadState",
|
|
1002
|
-
"ActiveState",
|
|
1003
|
-
"SubState",
|
|
1004
|
-
"UnitFileState",
|
|
1005
|
-
"FragmentPath",
|
|
1006
|
-
"NeedDaemonReload"
|
|
1007
|
-
];
|
|
1008
|
-
|
|
1009
|
-
class SystemctlError extends Error {
|
|
1010
|
-
constructor(command, exitCode, stderr) {
|
|
1011
|
-
super(`systemctl ${command} -> ${String(exitCode)}: ${stderr.trim().slice(0, 300)}`);
|
|
1012
|
-
this.name = "SystemctlError";
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
var parseShow = (stdout) => {
|
|
1016
|
-
const fields = new Map;
|
|
1017
|
-
for (const line of stdout.split(`
|
|
1018
|
-
`)) {
|
|
1019
|
-
const at = line.indexOf("=");
|
|
1020
|
-
if (at <= 0)
|
|
1021
|
-
continue;
|
|
1022
|
-
const key = line.slice(0, at);
|
|
1023
|
-
if (!fields.has(key))
|
|
1024
|
-
fields.set(key, line.slice(at + 1));
|
|
1025
|
-
}
|
|
1026
|
-
return fields;
|
|
1027
|
-
};
|
|
1028
|
-
var statusOf = (stdout) => {
|
|
1029
|
-
const fields = parseShow(stdout);
|
|
1030
|
-
const loadState = fields.get("LoadState") ?? "not-found";
|
|
1031
|
-
const unitFileState = fields.get("UnitFileState") ?? "";
|
|
1032
|
-
const fragmentPath = fields.get("FragmentPath") ?? "";
|
|
1033
|
-
const subState = fields.get("SubState") ?? "";
|
|
1034
|
-
return {
|
|
1035
|
-
activeState: fields.get("ActiveState") ?? "inactive",
|
|
1036
|
-
known: loadState !== "not-found" || unitFileState !== "",
|
|
1037
|
-
loadState,
|
|
1038
|
-
needDaemonReload: fields.get("NeedDaemonReload") === "yes",
|
|
1039
|
-
...subState === "" ? {} : { subState },
|
|
1040
|
-
...unitFileState === "" ? {} : { unitFileState },
|
|
1041
|
-
...fragmentPath === "" ? {} : { fragmentPath }
|
|
1042
|
-
};
|
|
1043
|
-
};
|
|
1044
|
-
var showUnit = async (runner, name) => {
|
|
1045
|
-
const result = await runner.exec([
|
|
1046
|
-
SYSTEMCTL,
|
|
1047
|
-
"show",
|
|
1048
|
-
"--no-pager",
|
|
1049
|
-
"-p",
|
|
1050
|
-
SHOW_PROPERTIES.join(","),
|
|
1051
|
-
"--",
|
|
1052
|
-
name
|
|
1053
|
-
]);
|
|
1054
|
-
if (result.exitCode !== 0)
|
|
1055
|
-
throw new SystemctlError(`show ${name}`, result.exitCode, result.stderr);
|
|
1056
|
-
return statusOf(result.stdout);
|
|
1057
|
-
};
|
|
1058
|
-
var run = async (runner, args) => {
|
|
1059
|
-
const result = await runner.exec([SYSTEMCTL, ...args]);
|
|
1060
|
-
if (result.exitCode !== 0) {
|
|
1061
|
-
throw new SystemctlError(args.join(" "), result.exitCode, result.stderr);
|
|
1062
|
-
}
|
|
1063
|
-
};
|
|
1064
|
-
var daemonReload = (runner) => run(runner, ["daemon-reload"]);
|
|
1065
|
-
var enableUnit = (runner, name) => run(runner, ["enable", "--", name]);
|
|
1066
|
-
var disableUnit = (runner, name) => run(runner, ["disable", "--", name]);
|
|
1067
|
-
var startUnit = (runner, name) => run(runner, ["start", "--", name]);
|
|
1068
|
-
var stopUnit = (runner, name) => run(runner, ["stop", "--", name]);
|
|
1069
|
-
var restartUnit = (runner, name) => run(runner, ["restart", "--", name]);
|
|
1070
|
-
|
|
1071
1071
|
// src/linux/unit-settle.ts
|
|
1072
1072
|
var refuse4 = (name, message) => new Error(`Systemd.Unit ${name}: ${message}`);
|
|
1073
1073
|
var attributesOf = (props, unitSha256, status) => ({
|
|
@@ -1123,21 +1123,13 @@ var settle = async (runner, props, step) => {
|
|
|
1123
1123
|
return settled;
|
|
1124
1124
|
};
|
|
1125
1125
|
|
|
1126
|
-
// src/linux/unit-
|
|
1127
|
-
var encoder2 = new TextEncoder;
|
|
1126
|
+
// src/linux/unit-preflight.ts
|
|
1128
1127
|
var decoder2 = new TextDecoder;
|
|
1129
1128
|
var assertValid = (props, expect) => {
|
|
1130
1129
|
const found = unitProblems(props, expect);
|
|
1131
1130
|
if (found.length > 0)
|
|
1132
1131
|
throw refuse4(props.name, found.join("; "));
|
|
1133
1132
|
};
|
|
1134
|
-
var readUnit = async (runner, props) => {
|
|
1135
|
-
const bytes = await runner.readFile(unitPathFor(props));
|
|
1136
|
-
const status = await showUnit(runner, props.name);
|
|
1137
|
-
if (bytes === undefined && !status.known)
|
|
1138
|
-
return;
|
|
1139
|
-
return attributesOf(props, bytes === undefined ? "" : digestOf2(decoder2.decode(bytes)), status);
|
|
1140
|
-
};
|
|
1141
1133
|
var assertMayWrite = (runner, name) => {
|
|
1142
1134
|
if (canActAsRoot(runner))
|
|
1143
1135
|
return;
|
|
@@ -1148,10 +1140,37 @@ var assertUsable = (props, status) => {
|
|
|
1148
1140
|
throw refuse4(props.name, "is masked. If that is stale, `systemctl unmask` it deliberately, then redeploy. Nothing " + "was written.");
|
|
1149
1141
|
}
|
|
1150
1142
|
};
|
|
1143
|
+
var assertUnclaimed = async (runner, props) => {
|
|
1144
|
+
const path = unitPathFor(props);
|
|
1145
|
+
const bytes = await runner.readFile(path);
|
|
1146
|
+
const live = bytes === undefined ? undefined : digestOf2(decoder2.decode(bytes));
|
|
1147
|
+
if (live !== undefined && live !== digestOf2(unitText(props))) {
|
|
1148
|
+
throw refuse4(props.name, `${path} is already on this host and is not this resource. Remove it, or declare it as a ` + "new resource and deploy with --adopt.");
|
|
1149
|
+
}
|
|
1150
|
+
};
|
|
1151
|
+
var assertReplaceable = async (runner, next, old, expect) => {
|
|
1152
|
+
assertValid(next, expect);
|
|
1153
|
+
assertMayWrite(runner, old.name);
|
|
1154
|
+
assertMayWrite(runner, next.name);
|
|
1155
|
+
assertUsable(next, await showUnit(runner, next.name));
|
|
1156
|
+
await assertUnclaimed(runner, next);
|
|
1157
|
+
await runner.checkWrite?.(unitPathFor(next), UNIT_WRITE);
|
|
1158
|
+
};
|
|
1159
|
+
|
|
1160
|
+
// src/linux/unit-lifecycle.ts
|
|
1161
|
+
var encoder2 = new TextEncoder;
|
|
1162
|
+
var decoder3 = new TextDecoder;
|
|
1163
|
+
var readUnit = async (runner, props) => {
|
|
1164
|
+
const bytes = await runner.readFile(unitPathFor(props));
|
|
1165
|
+
const status = await showUnit(runner, props.name);
|
|
1166
|
+
if (bytes === undefined && !status.known)
|
|
1167
|
+
return;
|
|
1168
|
+
return attributesOf(props, bytes === undefined ? "" : digestOf2(decoder3.decode(bytes)), status);
|
|
1169
|
+
};
|
|
1151
1170
|
var diffUnit = async (runner, news, output, expect) => {
|
|
1152
1171
|
assertValid(news, expect);
|
|
1153
1172
|
if (news.name !== output.name || unitPathFor(news) !== output.unitPath) {
|
|
1154
|
-
|
|
1173
|
+
await assertReplaceable(runner, news, output, expect);
|
|
1155
1174
|
return { action: "replace", deleteFirst: true };
|
|
1156
1175
|
}
|
|
1157
1176
|
const desired2 = digestOf2(unitText(news));
|
|
@@ -1183,8 +1202,10 @@ var reconcileUnit = async (runner, props, output, adopt = false, expect) => {
|
|
|
1183
1202
|
const text = unitText(props);
|
|
1184
1203
|
const desired2 = digestOf2(text);
|
|
1185
1204
|
const before = await runner.readFile(path);
|
|
1186
|
-
const liveSha = before === undefined ? undefined : digestOf2(
|
|
1205
|
+
const liveSha = before === undefined ? undefined : digestOf2(decoder3.decode(before));
|
|
1187
1206
|
const moved = output !== undefined && (output.name !== props.name || output.unitPath !== path);
|
|
1207
|
+
if (moved && output !== undefined)
|
|
1208
|
+
await assertReplaceable(runner, props, output, expect);
|
|
1188
1209
|
const prior = moved ? undefined : output;
|
|
1189
1210
|
if (prior === undefined && !(adopt && output === undefined) && liveSha !== undefined && liveSha !== desired2) {
|
|
1190
1211
|
throw refuse4(props.name, `${path} is already on this host and is not this resource. Remove it, or declare it as a ` + "new resource and deploy with --adopt.");
|
|
@@ -1550,5 +1571,5 @@ export {
|
|
|
1550
1571
|
sshRunner
|
|
1551
1572
|
};
|
|
1552
1573
|
|
|
1553
|
-
//# debugId=
|
|
1574
|
+
//# debugId=6BC8BE5DBFF285E364756E2164756E21
|
|
1554
1575
|
//# sourceMappingURL=index.js.map
|
package/dist/linux/index.js.map
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
|
-
"sources": ["../src/linux/directory.ts", "../src/launchd/host-effect.ts", "../src/launchd/runner.ts", "../src/ownership/adopt.ts", "../src/ownership/resume.ts", "../src/ownership/rows.ts", "../src/ownership/whole.ts", "../src/launchd/secret-tripwire.ts", "../src/launchd/host-file-form.ts", "../src/linux/directory-lifecycle.ts", "../src/linux/providers.ts", "../src/linux/remote-file.ts", "../src/launchd/job-form.ts", "../src/launchd/plist.ts", "../src/linux/region.ts", "../src/linux/remote-file-form.ts", "../src/linux/remote-file-plan.ts", "../src/linux/remote-file-lifecycle.ts", "../src/linux/unit.ts", "../src/linux/unit-handlers.ts", "../src/linux/unit-form.ts", "../src/linux/
|
|
3
|
+
"sources": ["../src/linux/directory.ts", "../src/launchd/host-effect.ts", "../src/launchd/runner.ts", "../src/ownership/adopt.ts", "../src/ownership/resume.ts", "../src/ownership/rows.ts", "../src/ownership/whole.ts", "../src/launchd/secret-tripwire.ts", "../src/launchd/host-file-form.ts", "../src/linux/directory-lifecycle.ts", "../src/linux/providers.ts", "../src/linux/remote-file.ts", "../src/launchd/job-form.ts", "../src/launchd/plist.ts", "../src/linux/region.ts", "../src/linux/remote-file-form.ts", "../src/linux/remote-file-plan.ts", "../src/linux/remote-file-lifecycle.ts", "../src/linux/unit.ts", "../src/linux/unit-handlers.ts", "../src/linux/systemctl.ts", "../src/linux/unit-form.ts", "../src/linux/unit-settle.ts", "../src/linux/unit-preflight.ts", "../src/linux/unit-lifecycle.ts", "../src/linux/ssh-runner.ts", "../src/launchd/host-lookup.ts", "../src/linux/ssh-command.ts", "../src/linux/ssh-scripts.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
5
|
"/**\n * `Host.Directory` — one directory on the host, declared: path, mode, owner, group.\n *\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt`: a directory already at the path reads as `Unowned`, and\n * where the plan never asked, reconcile honours the same flag (docs/ownership.md).\n * ★ IT IS NOT LINUX-ONLY. `mkdir`, `chmod`, `chown` and `rmdir` are the same argv on macOS, so this\n * resource works through any HostRunner; it lives in the linux subpath because the gap it closes\n * was found there (a first deploy into a new tree, which every file resource refuses to create).\n */\nimport { Resource } from 'alchemy';\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport { isResolved } from 'alchemy/Diff';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { HostDirectoryAttributes, HostDirectoryProps } from './directory-lifecycle.ts';\nimport {\n deleteDirectory,\n diffDirectory,\n readDirectory,\n reconcileDirectory,\n} from './directory-lifecycle.ts';\n\nexport type { HostDirectoryAttributes, HostDirectoryProps } from './directory-lifecycle.ts';\n\nexport interface HostDirectory extends Resource<\n 'Host.Directory',\n HostDirectoryProps,\n HostDirectoryAttributes\n> {}\n\nexport const HostDirectory = Resource<HostDirectory>('Host.Directory');\n\nexport const HostDirectoryProvider = () =>\n Provider.effect(\n HostDirectory,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return HostDirectory.Provider.of({\n list: () => Effect.succeed([]),\n\n read: ({ olds, output }) =>\n lift(async () => {\n const found = await readDirectory(runner, olds.path);\n if (found === undefined) return undefined;\n return output === undefined ? Unowned(found) : found;\n }),\n\n diff: ({ instanceId, news, output }) => {\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffDirectory(runner, news, output));\n // ⛔ A new path is a replace even while the rest is unresolved: the engine's default\n // update would create the new directory and leave the old one behind forever.\n const path = resolvedString(news, 'path');\n return Effect.succeed(\n path !== undefined && path !== output.path ? { action: 'replace' as const } : undefined,\n );\n },\n\n reconcile: ({ fqn, instanceId, news, output }) =>\n Effect.flatMap(adoptsAtApply({ fqn, instanceId, output }), (adopt) =>\n lift(() => reconcileDirectory(runner, news, output, adopt)),\n ),\n\n delete: ({ output }) => lift(() => deleteDirectory(runner, output)),\n });\n }),\n );\n",
|
|
6
6
|
"/**\n * The one place a HostRunner's promises become Effects — plus the one probe of an unresolved\n * `news` both providers' diffs share. (The engine's adopt setting lives in ownership/adopt.ts.)\n *\n * ★ The lifecycle files are plain async functions over a HostRunner (see runner.ts for why the\n * runner is promise-based), so each provider handler is a single `lift(() => step(runner, …))`.\n * ⚠️ A thrown Error stays that Error — its message is the refusal a deploy prints. Anything else\n * thrown is wrapped, so the failure channel is always an Error with a readable message.\n */\nimport * as Effect from 'effect/Effect';\n\nexport const lift = <A>(step: () => Promise<A>): Effect.Effect<A, Error> =>\n Effect.tryPromise({\n catch: (cause) => (cause instanceof Error ? cause : new Error(String(cause))),\n try: step,\n });\n\n/**\n * A string prop of a diff's `news`, when that one prop is already resolved; `undefined` while it\n * is still an Output (a function-typed proxy), an Effect or a Config.\n * ★ For the identity props a diff must see even when the rest of `news` is unresolved — a plain\n * string is resolved by definition, so `typeof` is the whole test.\n */\nexport const resolvedString = (news: unknown, key: string): string | undefined => {\n if (typeof news !== 'object' || news === null) return undefined;\n const value = (news as Record<string, unknown>)[key];\n return typeof value === 'string' ? value : undefined;\n};\n",
|
|
@@ -22,16 +22,17 @@
|
|
|
22
22
|
"/**\n * RemoteFile's diff / reconcile / delete over a HostRunner, so the whole lifecycle runs against a\n * fake host in tests with no ssh and no real write. What it would write is worked out next door\n * (remote-file-plan.ts); this file is the part that decides to act.\n *\n * ⛔ IN REGION MODE, DRIFT MEANS THE REGION AND NOTHING ELSE. Every byte outside the markers belongs\n * to another owner, so a change there must never plan an update — otherwise the two owners fight\n * on every deploy and this resource loses the right to be in that file at all.\n * ⚠️ THE WRITE REPLACES THE INODE, in both modes. A process holding the old file keeps reading it\n * until it reopens, and a hard link to the path stops tracking. That is the price of never\n * leaving a torn file, and it is the trade the launchd family already makes.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport { sha256Hex } from '../launchd/job-form.ts';\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\nimport { removeRegion } from './region.ts';\nimport {\n DEFAULT_MODE,\n type RemoteFileAttributes,\n type RemoteFileProps,\n} from './remote-file-form.ts';\nimport {\n decoder,\n digestOf,\n encoder,\n identity,\n ownedDigest,\n planWrite,\n readFileAttributes,\n refuse,\n} from './remote-file-plan.ts';\n\nexport { readFileAttributes } from './remote-file-plan.ts';\n\n/**\n * ★ A PLAN THAT WILL WRITE ASKS THE RUNNER FIRST (`checkWrite`, when it has one), so a runner's own\n * refusals fail the plan instead of arriving halfway through the apply.\n */\nexport const diffFile = async (\n runner: HostRunner,\n news: RemoteFileProps,\n output: RemoteFileAttributes,\n): Promise<Diff> => {\n const want = await identity(runner, news);\n if (news.path !== output.path) {\n // ★ Create-before-delete: two paths hold two files at once, so nothing forces deleteFirst.\n await runner.checkWrite?.(news.path, { mode: news.mode ?? DEFAULT_MODE, ...want });\n return { action: 'replace' };\n }\n const planned = await planWrite(runner, news, want);\n // ⛔ BOTH digests: the live one catches a hand edit, the STORED one catches a write that landed\n // and whose deploy then died before committing. Either alone reports `noop` over a wrong file.\n if (planned.converged && output.contentSha256 === digestOf(news.content)) {\n return { action: 'noop' };\n }\n await runner.checkWrite?.(news.path, planned.write);\n return { action: 'update' };\n};\n\n/**\n * `adopt` is whether adoption is on AND this apply is a create or an unfinished generation of our\n * own (ownership/adopt.ts). It lets such a generation take over what is already at the path — the\n * takeover the plan's probe would have allowed, had it run.\n * ★ IN REGION MODE THE FILE BEING THERE IS NOT A TAKEOVER: it belongs to someone else by\n * definition. What this resource claims is the block, so only a block already present with other\n * content is the thing adoption is asked about.\n */\nexport const reconcileFile = async (\n runner: HostRunner,\n props: RemoteFileProps,\n output?: RemoteFileAttributes,\n adopt = false,\n): Promise<RemoteFileAttributes> => {\n const want = await identity(runner, props);\n // ⛔ NO SILENT SUDO: handing a file to another user is root's call (chown(2)), so say so up front.\n if (want.uid !== undefined && want.uid !== runner.effectiveUid() && !canActAsRoot(runner)) {\n throw refuse(\n props.path,\n `owner ${String(props.owner)} is not the deploying user; only root may chown. Deploy through ` +\n 'a root destination or a privileged HostRunner. This provider never calls sudo itself.',\n );\n }\n const moved = output !== undefined && output.path !== props.path;\n const prior = moved ? undefined : output;\n const planned = await planWrite(runner, props, want);\n const live = ownedDigest(planned.before, props.region);\n const declared = digestOf(props.content);\n /**\n * ⛔ SOMETHING WE DO NOT OWN IS NEVER OVERWRITTEN. With no prior state the engine's probe has\n * already refused whatever it found — except where it never looked: a replace's new path, and a\n * create whose props still held an Output at plan time. A path typo there would otherwise\n * overwrite a system file. ★ With adoption on, a create takes it over, as the probe would have.\n */\n if (\n prior === undefined &&\n live !== undefined &&\n live !== declared &&\n !(adopt && output === undefined)\n ) {\n throw refuse(\n props.path,\n `${props.region === undefined ? 'already exists' : 'already carries that managed region'}` +\n ' and is not this resource. Remove it, or declare it as a new resource and deploy --adopt.',\n );\n }\n if (!planned.converged) await runner.writeFileAtomic(props.path, planned.bytes, planned.write);\n /**\n * ⚠️ READ BACK, never echo the declaration: a umask, an ACL or a runner that ignored `uid` shows\n * up here as a refusal instead of as a forever-`update`.\n */\n const after = await readFileAttributes(runner, props.path, props.region);\n if (\n after === undefined ||\n after.sha256 !== sha256Hex(planned.bytes) ||\n after.contentSha256 !== declared\n ) {\n /**\n * ⚠️ Roll back a CREATE only: left behind, the next plan's recovery read finds a file with no\n * state, reports it Unowned, and every later deploy demands --adopt for our own file.\n * ⛔ NEVER IN REGION MODE — the file was someone else's before this deploy and must survive it.\n */\n if (planned.before === undefined && props.region === undefined) {\n await runner.removeFile(props.path).catch(() => undefined);\n }\n throw refuse(\n props.path,\n 'the write returned but the file on disk does not match the declaration',\n );\n }\n // ★ Create-before-delete, as the replace would have been: the old path goes once the new one is\n // written and verified.\n if (moved && output !== undefined) await deleteFile(runner, output);\n return after;\n};\n\n/**\n * Whole-file mode removes the file. ⛔ REGION MODE REMOVES ONLY THE BLOCK, leaving every other byte\n * identical — removing the file would delete another owner's configuration. Idempotent both ways.\n */\nexport const deleteFile = async (\n runner: HostRunner,\n output: RemoteFileAttributes,\n): Promise<void> => {\n const stat = await runner.stat(output.path);\n if (stat === undefined) return;\n if (stat.kind !== 'file') throw refuse(output.path, `is now a ${stat.kind}; not touching it`);\n if (output.region === undefined) {\n await runner.removeFile(output.path);\n return;\n }\n const bytes = await runner.readFile(output.path);\n if (bytes === undefined) return;\n const before = decoder.decode(bytes);\n const next = removeRegion(before, output.region);\n if (next === before) return;\n await runner.writeFileAtomic(output.path, encoder.encode(next), {\n gid: stat.gid,\n mode: stat.mode,\n uid: stat.uid,\n });\n};\n",
|
|
23
23
|
"/**\n * `Systemd.Unit` and `Systemd.Timer` — one systemd unit file and systemd's view of it, declared.\n *\n * - create / update — write the unit file atomically, `daemon-reload`, enable or disable, then\n * start, stop, or RESTART ONLY when something actually changed (unit-lifecycle.ts settle).\n * - read — the unit file's SHA-256 plus `systemctl show` (load state, active state, enablement).\n * - diff — the rendered digest against the stored AND the on-disk one, the declared enablement and\n * running state against systemd's, and systemd's own `NeedDaemonReload`.\n * - replace — only when the unit's name or directory changes, and DELETE FIRST: two unit files for\n * one name cannot both be the one systemd reads.\n * - delete — stop, disable, remove the file, reload.\n *\n * ⛔ A DEPLOY NEVER MASS-RESTARTS — see the ⛔ at the top of unit-lifecycle.ts. It is the property\n * that lets this family reach a host holding a vault, a clock or a UPS handler.\n * ⛔ THE UNIT FILE IS NEVER A SECRET (unit-form.ts): it is 0644 and its props sit in state.\n * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt`. A unit already on the host reads as `Unowned`; adopting\n * one that already matches the declaration does not restart it.\n * ★ TWO RESOURCES, ONE LIFECYCLE. A timer is a unit whose file ends `.timer` and carries a\n * `[Timer]` section; splitting the TYPE rather than the code means a plan says which of the two\n * a row is, and a `.service` declared as a timer is a refusal instead of a puzzle.\n */\nimport { Resource } from 'alchemy';\nimport * as Provider from 'alchemy/Provider';\nimport * as Effect from 'effect/Effect';\nimport { HostRunnerService } from '../launchd/runner.ts';\nimport type { SystemdUnitAttributes, SystemdUnitProps } from './unit-form.ts';\nimport { deleteHandler, diffHandler, readHandler, reconcileHandler } from './unit-handlers.ts';\n\nexport type { SystemdUnitAttributes, SystemdUnitProps, UnitSection } from './unit-form.ts';\n\nexport interface SystemdUnit extends Resource<\n 'Systemd.Unit',\n SystemdUnitProps,\n SystemdUnitAttributes\n> {}\n\nexport interface SystemdTimer extends Resource<\n 'Systemd.Timer',\n SystemdUnitProps,\n SystemdUnitAttributes\n> {}\n\nexport const SystemdUnit = Resource<SystemdUnit>('Systemd.Unit');\nexport const SystemdTimer = Resource<SystemdTimer>('Systemd.Timer');\n\nexport const SystemdUnitProvider = () =>\n Provider.effect(\n SystemdUnit,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return SystemdUnit.Provider.of({\n /**\n * ⛔ systemd's unit list is not a list of things this stack owns — it is every vendor,\n * package and hand-written unit on the host. Returning them would invite a nuke to stop\n * services nothing here declared.\n */\n list: () => Effect.succeed([]),\n read: ({ olds, output }) => readHandler(runner, olds, output),\n diff: ({ instanceId, news, output }) => diffHandler(runner, instanceId, news, output),\n reconcile: (args) => reconcileHandler(runner, args),\n delete: ({ output }) => deleteHandler(runner, output),\n });\n }),\n );\n\nexport const SystemdTimerProvider = () =>\n Provider.effect(\n SystemdTimer,\n Effect.gen(function* () {\n const runner = yield* HostRunnerService;\n return SystemdTimer.Provider.of({\n list: () => Effect.succeed([]),\n read: ({ olds, output }) => readHandler(runner, olds, output),\n // ★ `'timer'` is the whole difference: the same lifecycle, refusing a name that is not one.\n diff: ({ instanceId, news, output }) =>\n diffHandler(runner, instanceId, news, output, 'timer'),\n reconcile: (args) => reconcileHandler(runner, args, 'timer'),\n delete: ({ output }) => deleteHandler(runner, output),\n });\n }),\n );\n",
|
|
24
24
|
"/**\n * The four provider handlers `Systemd.Unit` and `Systemd.Timer` share, as plain functions over a\n * HostRunner — so the two Resources differ only in their TYPE and the unit suffix they insist on.\n *\n * ★ WHY NOT ONE SHARED HANDLER OBJECT. `Provider.of` is typed per Resource, so an object built once\n * and passed to both would have to be widened or cast; functions with their arguments spelled out\n * keep both call sites fully checked and still say each rule once.\n */\nimport { Unowned } from 'alchemy/AdoptPolicy';\nimport type { Diff } from 'alchemy/Diff';\nimport { isResolved } from 'alchemy/Diff';\nimport type { Input } from 'alchemy/Input';\nimport * as Effect from 'effect/Effect';\nimport { lift, resolvedString } from '../launchd/host-effect.ts';\nimport type { HostRunner } from '../launchd/runner.ts';\nimport { adoptsAtApply } from '../ownership/adopt.ts';\nimport { noteUnfinished } from '../ownership/resume.ts';\nimport type { SystemdUnitAttributes, SystemdUnitProps } from './unit-form.ts';\nimport { deleteUnit, diffUnit, readUnit, reconcileUnit } from './unit-lifecycle.ts';\n\nexport const readHandler = (\n runner: HostRunner,\n olds: SystemdUnitProps,\n output: SystemdUnitAttributes | undefined,\n): Effect.Effect<SystemdUnitAttributes | undefined, Error> =>\n lift(async () => {\n const found = await readUnit(runner, olds);\n if (found === undefined) return undefined;\n return output === undefined ? Unowned(found) : found;\n });\n\nexport const diffHandler = (\n runner: HostRunner,\n instanceId: string,\n news: Input<SystemdUnitProps>,\n output: SystemdUnitAttributes | undefined,\n expect?: string,\n): Effect.Effect<Diff | undefined, Error> => {\n // ★ An unfinished generation of our own: `--adopt` may resume it (ownership/resume.ts).\n if (output === undefined) return noteUnfinished(instanceId);\n if (isResolved(news)) return lift(() => diffUnit(runner, news, output, expect));\n /**\n * ⛔ A RENAME MUST BE SEEN EVEN WHILE OTHER PROPS ARE UNRESOLVED. The engine's default for a prop\n * change is `update`, and an update under a new name writes the new unit file and leaves the old\n * unit running with nothing in state to ever remove it. `content` is exactly what is unresolved\n * when a rendered config file's digest is templated into the same deploy.\n */\n const name = resolvedString(news, 'name');\n return Effect.succeed(\n name !== undefined && name !== output.name\n ? { action: 'replace' as const, deleteFirst: true }\n : undefined,\n );\n};\n\nexport const reconcileHandler = (\n runner: HostRunner,\n args: {\n fqn: string;\n instanceId: string;\n news: SystemdUnitProps;\n output: SystemdUnitAttributes | undefined;\n },\n expect?: string,\n): Effect.Effect<SystemdUnitAttributes, Error> =>\n Effect.flatMap(adoptsAtApply(args), (adopt) =>\n lift(() => reconcileUnit(runner, args.news, args.output, adopt, expect)),\n );\n\nexport const deleteHandler = (\n runner: HostRunner,\n output: SystemdUnitAttributes,\n): Effect.Effect<void, Error> => lift(() => deleteUnit(runner, output));\n",
|
|
25
|
-
"/**\n * Systemd.Unit / Systemd.Timer props, attributes, the unit-file renderer and the validation — the\n * pure half of the family.\n *\n * ⛔ THE DIRECTIVE SET IS SYSTEMD'S, NOT THIS FILE'S. There is no machine-readable schema of\n * `systemd.unit(5)` / `systemd.service(5)` directives to generate from, so this renders SECTIONS\n * AND LINES VERBATIM and claims to know nothing about what the keys mean. What it validates is\n * only what an INI file must be true of — a section name, a key shape, no embedded newline —\n * plus the two structural rules systemd's own output proves (see `unitProblems`). ★ That is the\n * honest boundary: invent no vendor shapes, and let `systemd-analyze verify` be the deep check a\n * host stack runs on the host.\n * ⛔ `content` IS NEVER A SECRET. Props sit unencrypted in Alchemy state and the unit file is\n * world-readable at 0644; a unit that needs a secret takes `EnvironmentFile=` pointing at a file\n * a secret renderer maintains.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\n\nexport type UnitSection = {\n /** `Unit`, `Service`, `Timer`, `Install`, … — verbatim, including its capitalisation. */\n readonly name: string;\n /**\n * The section's lines, in order. A repeated key is allowed and meaningful in systemd\n * (`ExecStartPre=` twice runs twice), so this is a list of pairs, never an object.\n */\n readonly lines: readonly (readonly [key: string, value: string])[];\n};\n\nexport type SystemdUnitProps = {\n /** Unit name WITH its suffix, e.g. `thing.service`. The unit file's name on disk. */\n name: string;\n /** The whole unit file, verbatim. Mutually exclusive with `sections`. */\n content?: string;\n /** The unit file as sections, rendered in the order given. Mutually exclusive with `content`. */\n sections?: readonly UnitSection[];\n /** Directory the unit file goes in. @default '/etc/systemd/system' */\n directory?: string;\n /** `systemctl enable` / `disable`. @default true */\n enabled?: boolean;\n /** `systemctl start` / `stop`. @default true */\n started?: boolean;\n /**\n * Digests of things this unit READS that live outside its unit file — a rendered config file's\n * `sha256` attribute, most often. A change here restarts the unit; nothing else does.\n * ⚠️ A hand edit of that file is NOT noticed: the digest in state still matches what the stack\n * declared, so the unit reads converged. That limit is the same one the Mac side records.\n */\n restartOn?: readonly string[];\n};\n\nexport type SystemdUnitAttributes = {\n name: string;\n unitPath: string;\n /** SHA-256 of the unit file this resource wrote. */\n unitSha256: string;\n /** SHA-256 of `restartOn`, so a config change is a diff. */\n configSha256: string;\n loadState: string;\n activeState: string;\n unitFileState?: string;\n enabled: boolean;\n active: boolean;\n};\n\n/** ★ systemd's admin drop-in directory, ahead of the vendor's in its search order (measured). */\nexport const DEFAULT_UNIT_DIRECTORY = '/etc/systemd/system';\n\n/**\n * Directories systemd looks in for a unit file it can enable.\n * ★ MEASURED 2026-09-22 with `systemd-analyze unit-paths` on Debian 13 / systemd 257, minus the\n * per-user and generator directories, which are not places a stack writes. `/lib/systemd/system`\n * is the same directory before the /usr merge, where the measured host has only the merged name.\n * ⛔ WHY IT IS ENFORCED. `systemctl enable <name>` looks the unit up BY NAME; a unit file outside\n * these directories is invisible to that lookup, so an enabled unit declared into, say, `/opt`\n * writes its file, reloads, and then fails at `enable` with the file already on disk.\n */\nexport const UNIT_SEARCH_DIRECTORIES = [\n '/etc/systemd/system',\n '/run/systemd/system',\n '/usr/local/lib/systemd/system',\n '/usr/lib/systemd/system',\n '/lib/systemd/system',\n] as const;\n\n/** ⛔ The unit file's mode and owner are systemd's rule, not a choice: readable, never writable. */\nexport const UNIT_WRITE = { gid: 0, mode: 0o644, uid: 0 } as const;\n\nexport const digestOf = (text: string): string => sha256Hex(new TextEncoder().encode(text));\n\n/** The digests of everything outside the unit file that should restart it, as one value. */\nexport const configDigest = (restartOn: readonly string[] | undefined): string =>\n digestOf((restartOn ?? []).join('\\n'));\n\n/** Sections → an INI unit file. ★ Keys and values pass through untouched; see the file header. */\nexport const renderUnit = (sections: readonly UnitSection[]): string =>\n `${sections\n .map((section) =>\n [`[${section.name}]`, ...section.lines.map(([key, value]) => `${key}=${value}`)].join('\\n'),\n )\n .join('\\n\\n')}\\n`;\n\nexport const unitText = (props: SystemdUnitProps): string =>\n props.content ?? renderUnit(props.sections ?? []);\n\nexport const unitPathFor = (props: SystemdUnitProps): string =>\n `${props.directory ?? DEFAULT_UNIT_DIRECTORY}/${props.name}`;\n\nconst NAME = /^[A-Za-z0-9][A-Za-z0-9_.@:-]*\\.([a-z]+)$/;\n/** systemd's own unit types. ★ Fixed vocabulary from `systemd.unit(5)`, not a guess at directives. */\nconst TYPES = new Set([\n 'automount',\n 'device',\n 'mount',\n 'path',\n 'scope',\n 'service',\n 'slice',\n 'socket',\n 'swap',\n 'target',\n 'timer',\n]);\n\nconst INSTALL_KEYS = new Set(['WantedBy', 'RequiredBy', 'UpsertedBy', 'Also', 'Alias']);\n\n/**\n * Every refusal at once, so one plan shows the whole list.\n * ⛔ THE TWO STRUCTURAL RULES, both proven by systemd's own output rather than assumed:\n * - `enabled: true` needs an `[Install]` section. `systemctl enable` has nothing to link without\n * one, and systemd's name for a unit file that has none is `UnitFileState=static` — measured on\n * a live host, where the journal daemon reads `static` and the ssh daemon reads `enabled`.\n * - A `.timer` needs a `[Timer]` section, and a timer's `[Install]` is what arms it at boot.\n */\nexport const unitProblems = (props: SystemdUnitProps, expect?: string): string[] => {\n const found: string[] = [];\n const type = NAME.exec(props.name)?.[1];\n if (type === undefined || !TYPES.has(type)) {\n found.push(\n `name must be <unit>.<type> with a systemd unit type, got ${JSON.stringify(props.name)}`,\n );\n } else if (expect !== undefined && type !== expect) {\n found.push(`this resource declares a .${expect} unit; ${props.name} is a .${type}`);\n }\n if ((props.content === undefined) === (props.sections === undefined)) {\n found.push('declare exactly one of content or sections');\n }\n const directory = props.directory ?? DEFAULT_UNIT_DIRECTORY;\n if (!directory.startsWith('/') || directory.endsWith('/') || directory.includes('/..')) {\n found.push('directory must be an absolute, normalised path with no trailing slash');\n }\n found.push(...textProblems(unitText(props)));\n if (props.enabled !== false && !UNIT_SEARCH_DIRECTORIES.includes(directory as never)) {\n found.push(\n `an enabled unit must live where systemd looks for it by name (${UNIT_SEARCH_DIRECTORIES.join(', ')}); ` +\n `${directory} is not one of them. Move it, or declare enabled: false.`,\n );\n }\n if (props.enabled !== false && !hasInstall(props)) {\n found.push(\n 'enabled units need an [Install] section with WantedBy/RequiredBy/Also/Alias; without one ' +\n 'systemd calls the unit \"static\" and `systemctl enable` has nothing to link. Add one, or ' +\n 'declare enabled: false and let something else pull it in.',\n );\n }\n if (type === 'timer' && !unitText(props).includes('[Timer]')) {\n found.push('a .timer needs a [Timer] section');\n }\n return found;\n};\n\nconst hasInstall = (props: SystemdUnitProps): boolean => {\n const text = unitText(props);\n if (!text.includes('[Install]')) return false;\n const after = text.slice(text.indexOf('[Install]'));\n return [...INSTALL_KEYS].some((key) => new RegExp(`^${key}=`, 'm').test(after));\n};\n\nconst textProblems = (text: string): string[] => {\n const found: string[] = [];\n if (text.trim() === '') found.push('the unit file is empty');\n if (text.includes('\\u0000')) found.push('the unit file contains NUL');\n if (!/^\\s*\\[[A-Za-z]+]/.test(text)) found.push('a unit file must begin with a [Section]');\n return found;\n};\n",
|
|
26
25
|
"/**\n * The `systemctl` subcommands the systemd family uses, over a HostRunner, plus the parser for the\n * one that returns data.\n *\n * ★ MEASURED 2026-09-22 on Debian 13, systemd 257 (257.13-1~deb13u1), read-only — nothing was\n * enabled, started or reloaded to write this:\n *\n * - `systemctl show -p <list> <unit>` EXITS 0 FOR A UNIT THAT DOES NOT EXIST, and answers with\n * the properties it would have had:\n * Id=hf-nonexistent-xyz.service LoadState=not-found\n * ActiveState=inactive SubState=dead\n * FragmentPath= UnitFileState=\n * ⛔ SO THE EXIT CODE IS NOT THE ANSWER — `LoadState` is. A provider that read exit 0 as \"the\n * unit is there\" would adopt a unit that does not exist and then never write its file.\n * - The properties come back in systemd's own order, not the order asked for, so the output is a\n * map and never positional.\n * - `systemctl is-enabled <unknown>` exits **4** and prints `not-found`; `is-active <unknown>`\n * exits **4** and prints `inactive`. Both are answers, not errors.\n * - `UnitFileState=static` is exactly systemd's name for a unit file with no `[Install]` section\n * (measured: the journal daemon is `static`, the ssh daemon is `enabled`).\n * - `/etc/systemd/system` is `root:root 0755` — the admin drop-in directory, ahead of the\n * vendor's `/usr/lib/systemd/system` in systemd's own search order.\n * ⚠️ REASONED, NOT MEASURED: the write subcommands. `daemon-reload`, `enable`, `disable`, `start`,\n * `stop` and `restart` were never run for this file, because running them would change a live\n * host. Each is therefore checked the same way: exit 0 or an Error carrying systemd's stderr, and\n * the state is read back with `show` afterwards rather than assumed.\n * ⛔ NEVER PUT `show` STDOUT WITH NO PROPERTY FILTER IN AN ERROR: the unfiltered property set\n * carries the unit's whole environment block.\n */\nimport type { HostRunner } from '../launchd/runner.ts';\n\nexport const SYSTEMCTL = 'systemctl';\n\n/** The properties every read asks for. ⛔ Never `Environment` — see the header. */\nexport const SHOW_PROPERTIES = [\n 'Id',\n 'LoadState',\n 'ActiveState',\n 'SubState',\n 'UnitFileState',\n 'FragmentPath',\n 'NeedDaemonReload',\n] as const;\n\nexport class SystemctlError extends Error {\n constructor(command: string, exitCode: number, stderr: string) {\n super(`systemctl ${command} -> ${String(exitCode)}: ${stderr.trim().slice(0, 300)}`);\n this.name = 'SystemctlError';\n }\n}\n\nexport type UnitStatus = {\n /** `loaded`, `not-found`, `masked`, `error`, `bad-setting`. ⛔ The authority on existence. */\n readonly loadState: string;\n /** systemd knows this unit: it has a unit file or is loaded. */\n readonly known: boolean;\n readonly activeState: string;\n readonly subState?: string;\n /** `enabled`, `disabled`, `static`, `masked`, … Empty for a unit with no unit file. */\n readonly unitFileState?: string;\n /** The unit file systemd would read. Empty when there is none. */\n readonly fragmentPath?: string;\n /** systemd's own view that its on-disk unit files are newer than what it has loaded. */\n readonly needDaemonReload: boolean;\n};\n\n/** `key=value` lines into a map. ⚠️ First wins: systemd never repeats a key, a truncated read might. */\nexport const parseShow = (stdout: string): Map<string, string> => {\n const fields = new Map<string, string>();\n for (const line of stdout.split('\\n')) {\n const at = line.indexOf('=');\n if (at <= 0) continue;\n const key = line.slice(0, at);\n if (!fields.has(key)) fields.set(key, line.slice(at + 1));\n }\n return fields;\n};\n\nexport const statusOf = (stdout: string): UnitStatus => {\n const fields = parseShow(stdout);\n const loadState = fields.get('LoadState') ?? 'not-found';\n const unitFileState = fields.get('UnitFileState') ?? '';\n const fragmentPath = fields.get('FragmentPath') ?? '';\n const subState = fields.get('SubState') ?? '';\n return {\n activeState: fields.get('ActiveState') ?? 'inactive',\n // ⛔ MEASURED: `show` answers for a unit that does not exist, so \"known\" is LoadState plus\n // whether systemd found a unit file at all — never the exit code.\n known: loadState !== 'not-found' || unitFileState !== '',\n loadState,\n needDaemonReload: fields.get('NeedDaemonReload') === 'yes',\n ...(subState === '' ? {} : { subState }),\n ...(unitFileState === '' ? {} : { unitFileState }),\n ...(fragmentPath === '' ? {} : { fragmentPath }),\n };\n};\n\nexport const showUnit = async (runner: HostRunner, name: string): Promise<UnitStatus> => {\n const result = await runner.exec([\n SYSTEMCTL,\n 'show',\n '--no-pager',\n '-p',\n SHOW_PROPERTIES.join(','),\n '--',\n name,\n ]);\n // ⚠️ A non-zero `show` means systemctl itself failed (no bus, a malformed name) — not a missing\n // unit, which exits 0. Failing closed here is what keeps a broken connection from reading as\n // \"the unit is gone\", which would make the next deploy write its file and restart it.\n if (result.exitCode !== 0)\n throw new SystemctlError(`show ${name}`, result.exitCode, result.stderr);\n return statusOf(result.stdout);\n};\n\n/** One write subcommand, checked. ⚠️ stderr only; `show` output never reaches an error. */\nconst run = async (runner: HostRunner, args: readonly string[]): Promise<void> => {\n const result = await runner.exec([SYSTEMCTL, ...args]);\n if (result.exitCode !== 0) {\n throw new SystemctlError(args.join(' '), result.exitCode, result.stderr);\n }\n};\n\n/** ⛔ After every unit-file write or removal, and before enable/start reads it. */\nexport const daemonReload = (runner: HostRunner): Promise<void> => run(runner, ['daemon-reload']);\n\nexport const enableUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['enable', '--', name]);\n\nexport const disableUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['disable', '--', name]);\n\nexport const startUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['start', '--', name]);\n\nexport const stopUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['stop', '--', name]);\n\n/**\n * ⛔ `restart`, NOT `reload-or-restart`. The reloading form asks the unit to re-read its config in\n * place when it declares `ExecReload=`, which means \"did the change take effect?\" has two\n * different answers depending on the unit — and a deploy cannot report a half-applied change.\n */\nexport const restartUnit = (runner: HostRunner, name: string): Promise<void> =>\n run(runner, ['restart', '--', name]);\n",
|
|
26
|
+
"/**\n * Systemd.Unit / Systemd.Timer props, attributes, the unit-file renderer and the validation — the\n * pure half of the family.\n *\n * ⛔ THE DIRECTIVE SET IS SYSTEMD'S, NOT THIS FILE'S. There is no machine-readable schema of\n * `systemd.unit(5)` / `systemd.service(5)` directives to generate from, so this renders SECTIONS\n * AND LINES VERBATIM and claims to know nothing about what the keys mean. What it validates is\n * only what an INI file must be true of — a section name, a key shape, no embedded newline —\n * plus the two structural rules systemd's own output proves (see `unitProblems`). ★ That is the\n * honest boundary: invent no vendor shapes, and let `systemd-analyze verify` be the deep check a\n * host stack runs on the host.\n * ⛔ `content` IS NEVER A SECRET. Props sit unencrypted in Alchemy state and the unit file is\n * world-readable at 0644; a unit that needs a secret takes `EnvironmentFile=` pointing at a file\n * a secret renderer maintains.\n */\nimport { sha256Hex } from '../launchd/job-form.ts';\n\nexport type UnitSection = {\n /** `Unit`, `Service`, `Timer`, `Install`, … — verbatim, including its capitalisation. */\n readonly name: string;\n /**\n * The section's lines, in order. A repeated key is allowed and meaningful in systemd\n * (`ExecStartPre=` twice runs twice), so this is a list of pairs, never an object.\n */\n readonly lines: readonly (readonly [key: string, value: string])[];\n};\n\nexport type SystemdUnitProps = {\n /** Unit name WITH its suffix, e.g. `thing.service`. The unit file's name on disk. */\n name: string;\n /** The whole unit file, verbatim. Mutually exclusive with `sections`. */\n content?: string;\n /** The unit file as sections, rendered in the order given. Mutually exclusive with `content`. */\n sections?: readonly UnitSection[];\n /** Directory the unit file goes in. @default '/etc/systemd/system' */\n directory?: string;\n /** `systemctl enable` / `disable`. @default true */\n enabled?: boolean;\n /** `systemctl start` / `stop`. @default true */\n started?: boolean;\n /**\n * Digests of things this unit READS that live outside its unit file — a rendered config file's\n * `sha256` attribute, most often. A change here restarts the unit; nothing else does.\n * ⚠️ A hand edit of that file is NOT noticed: the digest in state still matches what the stack\n * declared, so the unit reads converged. That limit is the same one the Mac side records.\n */\n restartOn?: readonly string[];\n};\n\nexport type SystemdUnitAttributes = {\n name: string;\n unitPath: string;\n /** SHA-256 of the unit file this resource wrote. */\n unitSha256: string;\n /** SHA-256 of `restartOn`, so a config change is a diff. */\n configSha256: string;\n loadState: string;\n activeState: string;\n unitFileState?: string;\n enabled: boolean;\n active: boolean;\n};\n\n/** ★ systemd's admin drop-in directory, ahead of the vendor's in its search order (measured). */\nexport const DEFAULT_UNIT_DIRECTORY = '/etc/systemd/system';\n\n/**\n * Directories systemd looks in for a unit file it can enable.\n * ★ MEASURED 2026-09-22 with `systemd-analyze unit-paths` on Debian 13 / systemd 257, minus the\n * per-user and generator directories, which are not places a stack writes. `/lib/systemd/system`\n * is the same directory before the /usr merge, where the measured host has only the merged name.\n * ⛔ WHY IT IS ENFORCED. `systemctl enable <name>` looks the unit up BY NAME; a unit file outside\n * these directories is invisible to that lookup, so an enabled unit declared into, say, `/opt`\n * writes its file, reloads, and then fails at `enable` with the file already on disk.\n */\nexport const UNIT_SEARCH_DIRECTORIES = [\n '/etc/systemd/system',\n '/run/systemd/system',\n '/usr/local/lib/systemd/system',\n '/usr/lib/systemd/system',\n '/lib/systemd/system',\n] as const;\n\n/** ⛔ The unit file's mode and owner are systemd's rule, not a choice: readable, never writable. */\nexport const UNIT_WRITE = { gid: 0, mode: 0o644, uid: 0 } as const;\n\nexport const digestOf = (text: string): string => sha256Hex(new TextEncoder().encode(text));\n\n/** The digests of everything outside the unit file that should restart it, as one value. */\nexport const configDigest = (restartOn: readonly string[] | undefined): string =>\n digestOf((restartOn ?? []).join('\\n'));\n\n/** Sections → an INI unit file. ★ Keys and values pass through untouched; see the file header. */\nexport const renderUnit = (sections: readonly UnitSection[]): string =>\n `${sections\n .map((section) =>\n [`[${section.name}]`, ...section.lines.map(([key, value]) => `${key}=${value}`)].join('\\n'),\n )\n .join('\\n\\n')}\\n`;\n\nexport const unitText = (props: SystemdUnitProps): string =>\n props.content ?? renderUnit(props.sections ?? []);\n\nexport const unitPathFor = (props: SystemdUnitProps): string =>\n `${props.directory ?? DEFAULT_UNIT_DIRECTORY}/${props.name}`;\n\nconst NAME = /^[A-Za-z0-9][A-Za-z0-9_.@:-]*\\.([a-z]+)$/;\n/** systemd's own unit types. ★ Fixed vocabulary from `systemd.unit(5)`, not a guess at directives. */\nconst TYPES = new Set([\n 'automount',\n 'device',\n 'mount',\n 'path',\n 'scope',\n 'service',\n 'slice',\n 'socket',\n 'swap',\n 'target',\n 'timer',\n]);\n\nconst INSTALL_KEYS = new Set(['WantedBy', 'RequiredBy', 'UpsertedBy', 'Also', 'Alias']);\n\n/**\n * Every refusal at once, so one plan shows the whole list.\n * ⛔ THE TWO STRUCTURAL RULES, both proven by systemd's own output rather than assumed:\n * - `enabled: true` needs an `[Install]` section. `systemctl enable` has nothing to link without\n * one, and systemd's name for a unit file that has none is `UnitFileState=static` — measured on\n * a live host, where the journal daemon reads `static` and the ssh daemon reads `enabled`.\n * - A `.timer` needs a `[Timer]` section, and a timer's `[Install]` is what arms it at boot.\n */\nexport const unitProblems = (props: SystemdUnitProps, expect?: string): string[] => {\n const found: string[] = [];\n const type = NAME.exec(props.name)?.[1];\n if (type === undefined || !TYPES.has(type)) {\n found.push(\n `name must be <unit>.<type> with a systemd unit type, got ${JSON.stringify(props.name)}`,\n );\n } else if (expect !== undefined && type !== expect) {\n found.push(`this resource declares a .${expect} unit; ${props.name} is a .${type}`);\n }\n if ((props.content === undefined) === (props.sections === undefined)) {\n found.push('declare exactly one of content or sections');\n }\n const directory = props.directory ?? DEFAULT_UNIT_DIRECTORY;\n if (!directory.startsWith('/') || directory.endsWith('/') || directory.includes('/..')) {\n found.push('directory must be an absolute, normalised path with no trailing slash');\n }\n found.push(...textProblems(unitText(props)));\n if (props.enabled !== false && !UNIT_SEARCH_DIRECTORIES.includes(directory as never)) {\n found.push(\n `an enabled unit must live where systemd looks for it by name (${UNIT_SEARCH_DIRECTORIES.join(', ')}); ` +\n `${directory} is not one of them. Move it, or declare enabled: false.`,\n );\n }\n if (props.enabled !== false && !hasInstall(props)) {\n found.push(\n 'enabled units need an [Install] section with WantedBy/RequiredBy/Also/Alias; without one ' +\n 'systemd calls the unit \"static\" and `systemctl enable` has nothing to link. Add one, or ' +\n 'declare enabled: false and let something else pull it in.',\n );\n }\n if (type === 'timer' && !unitText(props).includes('[Timer]')) {\n found.push('a .timer needs a [Timer] section');\n }\n return found;\n};\n\nconst hasInstall = (props: SystemdUnitProps): boolean => {\n const text = unitText(props);\n if (!text.includes('[Install]')) return false;\n const after = text.slice(text.indexOf('[Install]'));\n return [...INSTALL_KEYS].some((key) => new RegExp(`^${key}=`, 'm').test(after));\n};\n\nconst textProblems = (text: string): string[] => {\n const found: string[] = [];\n if (text.trim() === '') found.push('the unit file is empty');\n if (text.includes('\\u0000')) found.push('the unit file contains NUL');\n if (!/^\\s*\\[[A-Za-z]+]/.test(text)) found.push('a unit file must begin with a [Section]');\n return found;\n};\n",
|
|
27
27
|
"/**\n * The step that decides whether anything on the host actually moves: enablement, running state and\n * — only for a real change — a restart. Split from unit-lifecycle.ts because it is the rule the\n * whole family exists to keep, and it should be readable on its own.\n *\n * ⛔ THE RESTART CONDITION IS THE WHOLE CONTRACT. `changed` is set by the caller from the four\n * things that earn one (unit-lifecycle.ts reconcileUnit); `configChanged` is a digest the\n * DECLARATION itself listed. Nothing else restarts a unit — not a re-run, not an unrelated\n * resource in the same deploy, not `--adopt`.\n */\nimport type { HostRunner } from '../launchd/runner.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n configDigest,\n unitPathFor,\n} from './unit-form.ts';\nimport {\n type UnitStatus,\n daemonReload,\n disableUnit,\n enableUnit,\n restartUnit,\n showUnit,\n startUnit,\n stopUnit,\n} from './systemctl.ts';\n\nexport const refuse = (name: string, message: string): Error =>\n new Error(`Systemd.Unit ${name}: ${message}`);\n\nexport const attributesOf = (\n props: SystemdUnitProps,\n unitSha256: string,\n status: UnitStatus,\n): SystemdUnitAttributes => ({\n active: status.activeState === 'active' || status.activeState === 'activating',\n activeState: status.activeState,\n configSha256: configDigest(props.restartOn),\n enabled: status.unitFileState === 'enabled' || status.unitFileState === 'enabled-runtime',\n loadState: status.loadState,\n name: props.name,\n unitPath: unitPathFor(props),\n unitSha256,\n ...(status.unitFileState === undefined ? {} : { unitFileState: status.unitFileState }),\n});\n\nexport type Settle = {\n readonly before: Uint8Array | undefined;\n /** The unit file or systemd's view of it changed in a way that earns a restart. */\n readonly changed: boolean;\n readonly configChanged: boolean;\n readonly desired: string;\n readonly path: string;\n readonly status: UnitStatus;\n};\n\n/**\n * Bring enablement and running state to the declaration, restarting ONLY for a real change.\n * ⛔ THE RESTART CONDITION IS THE WHOLE CONTRACT: the unit file changed, or a digest the caller\n * listed changed. Nothing else — not a re-run, not an unrelated resource, not `--adopt`.\n */\nexport const settle = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n step: Settle,\n): Promise<SystemdUnitAttributes> => {\n const wantEnabled = props.enabled !== false;\n const wantStarted = props.started !== false;\n const isEnabled =\n step.status.unitFileState === 'enabled' || step.status.unitFileState === 'enabled-runtime';\n const undo = async (detail: string): Promise<never> => {\n // ⚠️ A create that never came up leaves nothing behind; an update keeps the new file and the\n // old stored digest, so the next deploy retries.\n if (step.before === undefined) {\n await runner.removeFile(step.path).catch(() => undefined);\n await daemonReload(runner).catch(() => undefined);\n }\n throw refuse(props.name, `${detail} The unit is NOT running.`);\n };\n try {\n if (wantEnabled && (!isEnabled || step.changed)) await enableUnit(runner, props.name);\n if (!wantEnabled && isEnabled) await disableUnit(runner, props.name);\n const active = step.status.activeState === 'active' || step.status.activeState === 'activating';\n if (!wantStarted) {\n if (active) await stopUnit(runner, props.name);\n } else if (!active) await startUnit(runner, props.name);\n else if (step.changed || step.configChanged) await restartUnit(runner, props.name);\n } catch (cause) {\n return undo(cause instanceof Error ? cause.message : String(cause));\n }\n /**\n * ⚠️ READ BACK, never echo the declaration. Returning `enabled: wantEnabled` because we called\n * `enable` would put a CLAIM in state instead of a reading, and the next plan would compare\n * the declaration against itself — so a link systemd did not actually make would never show up\n * as drift, in either direction.\n */\n const after = await showUnit(runner, props.name);\n if (wantStarted && after.activeState !== 'active' && after.activeState !== 'activating') {\n return undo(`systemctl reported success but the unit is ${after.activeState}.`);\n }\n const settled = attributesOf(props, step.desired, after);\n if (wantEnabled && !settled.enabled) {\n return undo(\n `systemctl enable reported success but systemd calls the unit ` +\n `${JSON.stringify(after.unitFileState ?? '')}, not enabled.`,\n );\n }\n return settled;\n};\n",
|
|
28
|
-
"/**\n * Systemd.Unit
|
|
28
|
+
"/**\n * Everything Systemd.Unit checks before it touches the host — split from unit-lifecycle.ts so that\n * a reconcile and a plan-time REPLACE run the very same checks.\n *\n * ★ WHY A REPLACE IS CHECKED AT PLAN TIME. A name or directory change is a delete-first replace,\n * and Alchemy runs `delete` on the old unit BEFORE `reconcile` on the new one (Apply.ts,\n * deleteOldGenerations under `node.deleteFirst`). A refusal that fired only in reconcile would\n * therefore arrive after the old unit was already stopped and its file removed: nothing running,\n * and a plan that had promised a clean swap.\n * ★ EVERY CHECK HERE IS READ-ONLY. systemd has no `print-disabled` equivalent in this family —\n * masking is `systemctl show`'s LoadState / UnitFileState, which `showUnit` already returns.\n * Validation, that show, a file read and `HostRunner.checkWrite` write nothing. `systemctl\n * enable` itself stays an apply step; the ways it is known to fail (no `[Install]`, a directory\n * systemd does not search) are `unitProblems`, checked here before the plan may promise a swap.\n */\nimport { type HostRunner, canActAsRoot } from '../launchd/runner.ts';\nimport { type UnitStatus, showUnit } from './systemctl.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n UNIT_WRITE,\n digestOf,\n unitPathFor,\n unitProblems,\n unitText,\n} from './unit-form.ts';\nimport { refuse } from './unit-settle.ts';\n\nconst decoder = new TextDecoder();\n\n/** Throw every refusal at once, so one plan shows the whole list. */\nexport const assertValid = (props: SystemdUnitProps, expect?: string): void => {\n const found = unitProblems(props, expect);\n if (found.length > 0) throw refuse(props.name, found.join('; '));\n};\n\n/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */\nexport const assertMayWrite = (runner: HostRunner, name: string): void => {\n if (canActAsRoot(runner)) return;\n throw refuse(\n name,\n 'a systemd unit is root-owned and systemctl needs root. Point the runner at a destination ' +\n 'whose ssh user is root, or provide a privileged HostRunner. This provider never calls sudo.',\n );\n};\n\n/**\n * ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes\n * start fail; unmasking here would silently overrule whoever masked it.\n */\nexport const assertUsable = (props: SystemdUnitProps, status: UnitStatus): void => {\n if (status.loadState === 'masked' || status.unitFileState === 'masked') {\n throw refuse(\n props.name,\n 'is masked. If that is stale, `systemctl unmask` it deliberately, then redeploy. Nothing ' +\n 'was written.',\n );\n }\n};\n\n/**\n * ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Alchemy's adoption probe guards a\n * create, but NOT the new name of a replace — the engine reads nothing there — so a rename onto\n * a unit file someone else already has would stop the old unit and write ours over theirs.\n * ★ A file byte-identical to our render is exempt: it is this declaration's own leftover (a deploy\n * that died between write and reload), and rewriting it changes nothing.\n */\nexport const assertUnclaimed = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n): Promise<void> => {\n const path = unitPathFor(props);\n const bytes = await runner.readFile(path);\n const live = bytes === undefined ? undefined : digestOf(decoder.decode(bytes));\n if (live !== undefined && live !== digestOf(unitText(props))) {\n throw refuse(\n props.name,\n `${path} is already on this host and is not this resource. Remove it, or declare it as a ` +\n 'new resource and deploy with --adopt.',\n );\n }\n};\n\n/**\n * A rename, checked at plan time: the new identity must be valid, writable, not masked and free,\n * and the old one deletable — before the plan may promise a delete-first replace.\n */\nexport const assertReplaceable = async (\n runner: HostRunner,\n next: SystemdUnitProps,\n old: SystemdUnitAttributes,\n expect?: string,\n): Promise<void> => {\n assertValid(next, expect);\n assertMayWrite(runner, old.name);\n assertMayWrite(runner, next.name);\n assertUsable(next, await showUnit(runner, next.name));\n await assertUnclaimed(runner, next);\n await runner.checkWrite?.(unitPathFor(next), UNIT_WRITE);\n};\n",
|
|
29
|
+
"/**\n * Systemd.Unit's read / diff / reconcile / delete as plain async functions over a HostRunner, so\n * the whole lifecycle runs against a fake host with no real systemd.\n *\n * ⛔ WHAT A DEPLOY DOES NOT DO — the rule this family was built around. It NEVER mass-restarts.\n * A unit is restarted only when THIS resource's unit file changed, or when a digest the\n * declaration itself listed in `restartOn` changed. A unit that is already running the content\n * we declare is left strictly alone: no restart, no reload, not even a `start`. An estate rebuild\n * must be able to reach a host that holds a vault, a UPS handler or a clock without bouncing\n * them, and \"the deploy ran\" must never be a reason anything went down.\n * ★ THE ORDER IS WRITE, RELOAD, ENABLE, THEN START OR RESTART. systemd reads the unit file at\n * `daemon-reload`, so writing it while the old unit runs changes nothing yet, and a write that\n * fails leaves the old unit running rather than leaving nothing running.\n * ⚠️ A FAILED START LEAVES THE UNIT DOWN. On an update the new unit file stays and state keeps the\n * previous digest, so the next deploy retries. On a CREATE the file this deploy wrote is removed\n * and systemd reloaded again: left behind, the next plan's recovery read finds a unit with no\n * state, reports it `Unowned`, and every later deploy demands `--adopt` for our own file.\n * ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes\n * start fail; unmasking here would silently overrule whoever masked it.\n */\nimport type { Diff } from 'alchemy/Diff';\nimport type { HostRunner } from '../launchd/runner.ts';\nimport { daemonReload, disableUnit, showUnit, stopUnit } from './systemctl.ts';\nimport {\n type SystemdUnitAttributes,\n type SystemdUnitProps,\n UNIT_WRITE,\n configDigest,\n digestOf,\n unitPathFor,\n unitText,\n} from './unit-form.ts';\nimport { assertMayWrite, assertReplaceable, assertUsable, assertValid } from './unit-preflight.ts';\nimport { attributesOf, refuse, settle } from './unit-settle.ts';\n\nconst encoder = new TextEncoder();\nconst decoder = new TextDecoder();\n\n/** What is on the host now: the unit file's digest and systemd's view. `undefined` when neither. */\nexport const readUnit = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n): Promise<SystemdUnitAttributes | undefined> => {\n const bytes = await runner.readFile(unitPathFor(props));\n const status = await showUnit(runner, props.name);\n if (bytes === undefined && !status.known) return undefined;\n return attributesOf(props, bytes === undefined ? '' : digestOf(decoder.decode(bytes)), status);\n};\n\nexport const diffUnit = async (\n runner: HostRunner,\n news: SystemdUnitProps,\n output: SystemdUnitAttributes,\n expect?: string,\n): Promise<Diff> => {\n assertValid(news, expect);\n // ★ The unit's name or its directory is its identity on the host: a change is a replace, and\n // delete-first, because two unit files for one name cannot both be the one systemd reads.\n // ⛔ Which is why everything the new unit's reconcile would refuse is refused HERE, at plan\n // time (unit-preflight.ts): after the delete it would be too late.\n if (news.name !== output.name || unitPathFor(news) !== output.unitPath) {\n await assertReplaceable(runner, news, output, expect);\n return { action: 'replace', deleteFirst: true };\n }\n const desired = digestOf(unitText(news));\n const update = async (): Promise<Diff> => {\n assertMayWrite(runner, news.name);\n await runner.checkWrite?.(unitPathFor(news), UNIT_WRITE);\n return { action: 'update' };\n };\n // ⛔ BOTH digests: the stored one catches a start that failed after the write landed, the live\n // one catches a hand edit. Either alone reports `noop` over a unit that is not what we say.\n if (desired !== output.unitSha256) return update();\n if (configDigest(news.restartOn) !== output.configSha256) return update();\n const live = await readUnit(runner, news);\n if (live === undefined || live.unitSha256 !== desired) return update();\n if (live.enabled !== (news.enabled !== false)) return update();\n if (live.active !== (news.started !== false)) return update();\n // ⚠️ systemd's own word for \"the file on disk is newer than what I loaded\" — a write that landed\n // without its reload. It is drift that neither digest can see.\n const status = await showUnit(runner, news.name);\n return status.needDaemonReload ? update() : { action: 'noop' };\n};\n\n/**\n * `adopt` is whether adoption is on AND this apply is a create or an unfinished generation of our\n * own (ownership/adopt.ts): it lets such a generation take over a unit already on the host.\n * ★ AN ADOPTED UNIT THAT ALREADY MATCHES IS NOT RESTARTED. That is the whole point of adopting one:\n * the estate's live services come under declaration without a single bounce.\n */\nexport const reconcileUnit = async (\n runner: HostRunner,\n props: SystemdUnitProps,\n output: SystemdUnitAttributes | undefined,\n adopt = false,\n expect?: string,\n): Promise<SystemdUnitAttributes> => {\n assertValid(props, expect);\n assertMayWrite(runner, props.name);\n const path = unitPathFor(props);\n const status = await showUnit(runner, props.name);\n assertUsable(props, status);\n const text = unitText(props);\n const desired = digestOf(text);\n const before = await runner.readFile(path);\n const liveSha = before === undefined ? undefined : digestOf(decoder.decode(before));\n const moved = output !== undefined && (output.name !== props.name || output.unitPath !== path);\n /**\n * ★ A rename the diff could not see — a name that was still an unresolved Output at plan time\n * (unit-handlers.ts diffHandler) — arrives here as an update. Run the same read-only checks a\n * plan-time replace runs, BEFORE deleteUnit, or the old unit is already gone when we refuse.\n */\n if (moved && output !== undefined) await assertReplaceable(runner, props, output, expect);\n const prior = moved ? undefined : output;\n /**\n * ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Where the engine's probe never\n * looked — a replace's new name, a create whose props were still an Output at plan time — a\n * unit file already there with other content belongs to someone else, and writing ours over it\n * would take their service. ★ A byte-identical file is this declaration's own leftover.\n */\n if (\n prior === undefined &&\n !(adopt && output === undefined) &&\n liveSha !== undefined &&\n liveSha !== desired\n ) {\n throw refuse(\n props.name,\n `${path} is already on this host and is not this resource. Remove it, or declare it as a ` +\n 'new resource and deploy with --adopt.',\n );\n }\n if (moved && output !== undefined) await deleteUnit(runner, output);\n const wrote = liveSha !== desired;\n /**\n * ⛔ THE THREE THINGS THAT EARN A RESTART, and nothing else:\n * - the unit file's bytes changed (`wrote`);\n * - state holds an older digest than the file does — a previous deploy's write landed and its\n * reload or restart never ran, so systemd is still running the old content;\n * - systemd itself says its loaded unit is older than the file (`NeedDaemonReload`, measured);\n * - a digest the declaration listed in `restartOn` changed.\n * ★ An adopted, converged unit hits none of them, which is why adoption never bounces a service.\n */\n const stale = prior !== undefined && prior.unitSha256 !== desired;\n const configChanged = prior !== undefined && prior.configSha256 !== configDigest(props.restartOn);\n if (wrote) await runner.writeFileAtomic(path, encoder.encode(text), UNIT_WRITE);\n if (wrote || status.needDaemonReload) await daemonReload(runner);\n const changed = wrote || stale || status.needDaemonReload;\n return settle(runner, props, { before, changed, configChanged, desired, path, status });\n};\n\n/**\n * Stop, disable, remove the unit file, reload. Idempotent.\n * ⛔ DELETING THE DECLARATION STOPS THE SERVICE. That is what removing it from the stack means, and\n * it is why a unit that must outlive its declaration is adopted rather than deleted.\n */\nexport const deleteUnit = async (\n runner: HostRunner,\n output: SystemdUnitAttributes,\n): Promise<void> => {\n assertMayWrite(runner, output.name);\n const status = await showUnit(runner, output.name);\n if (status.activeState === 'active' || status.activeState === 'activating') {\n await stopUnit(runner, output.name);\n }\n if (status.unitFileState === 'enabled' || status.unitFileState === 'enabled-runtime') {\n await disableUnit(runner, output.name);\n }\n const stat = await runner.stat(output.unitPath);\n if (stat !== undefined) {\n if (stat.kind !== 'file') throw refuse(output.name, `${output.unitPath} is a ${stat.kind}`);\n await runner.removeFile(output.unitPath);\n }\n await daemonReload(runner);\n};\n",
|
|
29
30
|
"/**\n * `sshRunner()` — the estate's Linux hosts behind the SAME HostRunner seam the launchd family\n * already drives a Mac through (launchd/runner.ts). Every provider in this directory reaches its\n * host only through it, so the whole Linux lifecycle runs against a fake in tests.\n *\n * ★ WHY THE SAME SEAM AND NOT A SECOND ONE. HostRunner is nine promise-returning methods with no\n * macOS in them; what was Mac-specific was launchctl and the plist, not the seam. Reusing it\n * means HostFile, the ownership rules and `checkWrite` already work on Linux, and a stack can\n * hand the same runner to a file, a directory and a unit.\n * ⛔ NO PASSWORDS AND NO SILENT SUDO. Every connection is `BatchMode=yes` (ssh-command.ts), and\n * `privileged` is false: this runner never calls sudo. A root-owned path therefore needs a\n * destination whose ssh user IS root — which is how the estate already reaches its hypervisors —\n * or a privileged runner of the caller's own. See docs/linux-host.md; the Linux twin of\n * sudoRunner is deliberately a later, separate change with its own allowlist.\n * ⛔ FAIL CLOSED. A connection that drops, a host key that changed, a shell that cannot parse the\n * script: none of them produces a \"not found\". Without the framing marker the result is an\n * Error, never data (ssh-command.ts parseFramed).\n * ★ EXERCISED READ-ONLY AGAINST A LIVE HOST, 2026-09-22 (Debian 13, systemd 257, ssh user uid\n * 1001): `stat` of a file, of a missing path and of a symlink (reported `symlink`, so the lstat\n * contract holds over the wire); `readFile` of a file and of a missing path; `getent` user and\n * group; a failing `exec`; and an argument of `a b '$HOME` + backtick + ` ;rm` arriving verbatim,\n * which is the quoting proven rather than argued. Nothing was written.\n * ⚠️ ONE CONNECTION PER CALL. No multiplexing is configured here: a deploy over a slow link pays a\n * handshake per read. Pass `sshArgs: ['-o', 'ControlMaster=auto', …]` to opt into your own\n * ControlPersist socket — the kit does not create one behind your back, because a stale socket\n * outliving the deploy is a surprise nobody declared.\n */\nimport { spawn } from 'node:child_process';\nimport { randomBytes } from 'node:crypto';\nimport { groupQuery, parseGroup, parseUser, userQuery } from '../launchd/host-lookup.ts';\nimport type { ExecResult, HostRunner } from '../launchd/runner.ts';\nimport { ABSENT, frameScript, parseFramed, sshArgv } from './ssh-command.ts';\nimport {\n execScript,\n parseStat,\n readScript,\n removeScript,\n statScript,\n writeScript,\n} from './ssh-scripts.ts';\n\nexport type SshRunnerOptions = {\n /** The destination exactly as the operator's own ssh config names it (`Host` block or user@host). */\n readonly host: string;\n /** Extra ssh options, after the fixed safety set and before the destination. */\n readonly sshArgs?: readonly string[];\n /** Kill a connection after this long. @default 120_000 */\n readonly execTimeoutMs?: number;\n /** ssh's own `ConnectTimeout`. @default 10 */\n readonly connectTimeoutSec?: number;\n};\n\ntype Raw = { exitCode: number; stdout: string; stderr: string; signal: string | null };\n\nconst spawnSsh = (argv: readonly string[], timeoutMs: number, stdin?: Uint8Array): Promise<Raw> =>\n new Promise((resolve, reject) => {\n const [program, ...args] = argv as [string, ...string[]];\n const child = spawn(program, args, {\n shell: false,\n stdio: [stdin === undefined ? 'ignore' : 'pipe', 'pipe', 'pipe'],\n timeout: timeoutMs,\n });\n const out: Buffer[] = [];\n const err: Buffer[] = [];\n child.stdout?.on('data', (chunk: Buffer) => out.push(chunk));\n child.stderr?.on('data', (chunk: Buffer) => err.push(chunk));\n child.on('error', (cause) => {\n reject(new Error(`ssh: ${cause.message}`));\n });\n if (stdin !== undefined && child.stdin !== null) {\n // ⚠️ EPIPE is normal here: the remote `cat` can die before we finish writing, and the real\n // failure is the exit code we are about to read — not a crash in this process.\n child.stdin.on('error', () => undefined);\n child.stdin.end(stdin);\n }\n child.on('close', (exitCode, signal) => {\n resolve({\n exitCode: exitCode ?? -1,\n signal,\n stderr: Buffer.concat(err).toString('utf8'),\n stdout: Buffer.concat(out).toString('utf8'),\n });\n });\n });\n\n/** What the process on the far end did — or an Error, when we cannot say that it ran at all. */\nexport const runRemote = async (\n options: Required<Pick<SshRunnerOptions, 'host' | 'connectTimeoutSec' | 'execTimeoutMs'>> &\n Pick<SshRunnerOptions, 'sshArgs'>,\n nonce: string,\n script: string,\n stdin?: Uint8Array,\n): Promise<ExecResult> => {\n const argv = sshArgv(options.host, frameScript(script, nonce), {\n connectTimeoutSec: options.connectTimeoutSec,\n ...(options.sshArgs === undefined ? {} : { sshArgs: options.sshArgs }),\n });\n const raw = await spawnSsh(argv, options.execTimeoutMs, stdin);\n const framed = parseFramed(raw.stderr, nonce);\n if (framed === undefined) {\n // ⛔ The command may or may not have run. Saying \"absent\" here is how a dropped link becomes a\n // deleted config, so it is an error with ssh's own words (truncated, never the stdout).\n throw new Error(\n `ssh ${options.host}: the remote command did not report a status (ssh exit ` +\n `${String(raw.exitCode)}${raw.signal === null ? '' : `, killed by ${raw.signal}`}): ` +\n `${raw.stderr.trim().slice(0, 300)}`,\n );\n }\n return { exitCode: framed.exitCode, stderr: framed.stderr, stdout: raw.stdout };\n};\n\nconst decodeBase64 = (text: string): Uint8Array =>\n new Uint8Array(Buffer.from(text.replaceAll('\\n', ''), 'base64'));\n\nconst failed = (host: string, what: string, result: ExecResult): Error =>\n new Error(\n `ssh ${host}: ${what} -> ${String(result.exitCode)}: ${result.stderr.trim().slice(0, 300)}`,\n );\n\n/**\n * Connect once to learn who we are, then hand back the runner.\n * ⛔ THE PROBE IS THE FAIL-CLOSED GATE. `effectiveUid()` is synchronous on HostRunner, so the uid\n * must be known before the first provider call; and `uname -s` refuses a host whose `stat -c`,\n * `base64` and `mv -f` are not the Linux spellings this runner sends. A host that cannot answer\n * both is a thrown Error at construction, not a stack that half-deploys.\n */\nexport const sshRunner = async (options: SshRunnerOptions): Promise<HostRunner> => {\n const settings = {\n connectTimeoutSec: options.connectTimeoutSec ?? 10,\n execTimeoutMs: options.execTimeoutMs ?? 120_000,\n host: options.host,\n ...(options.sshArgs === undefined ? {} : { sshArgs: options.sshArgs }),\n };\n const nonce = randomBytes(8).toString('hex');\n const run = (script: string, stdin?: Uint8Array) => runRemote(settings, nonce, script, stdin);\n const probe = await run('uname -s; id -u');\n if (probe.exitCode !== 0) throw failed(options.host, 'uname -s; id -u', probe);\n const [system, uid] = probe.stdout.trim().split('\\n');\n if (system !== 'Linux' || uid === undefined || !/^\\d+$/.test(uid)) {\n throw new Error(\n `ssh ${options.host}: expected a Linux host, got ${JSON.stringify(probe.stdout.trim())}. ` +\n 'sshRunner() sends GNU/BusyBox argv (stat -c, base64, mv -f); for a Mac use localRunner().',\n );\n }\n const euid = Number(uid);\n return {\n effectiveUid: () => euid,\n exec: (argv) => run(execScript(argv)),\n lookupGroup: async (nameOrId) => {\n const result = await run(execScript(groupQuery('linux', nameOrId)));\n return result.exitCode === 0 ? parseGroup('linux', result.stdout) : undefined;\n },\n lookupUser: async (nameOrId) => {\n const result = await run(execScript(userQuery('linux', nameOrId)));\n return result.exitCode === 0 ? parseUser('linux', result.stdout) : undefined;\n },\n privileged: false,\n readFile: async (path) => {\n const result = await run(readScript(path));\n if (result.exitCode === ABSENT) return undefined;\n if (result.exitCode !== 0) throw failed(options.host, `read ${path}`, result);\n return decodeBase64(result.stdout);\n },\n removeFile: async (path) => {\n const result = await run(removeScript(path));\n if (result.exitCode !== 0) throw failed(options.host, `remove ${path}`, result);\n },\n sleep: (ms) => new Promise((resolve) => setTimeout(resolve, ms)),\n stat: async (path) => {\n const result = await run(statScript(path));\n if (result.exitCode === ABSENT) return undefined;\n if (result.exitCode !== 0) throw failed(options.host, `stat ${path}`, result);\n const parsed = parseStat(result.stdout);\n // ⛔ Unparseable is an error, not \"nothing there\": a `stat` that printed something we do not\n // understand is a host this runner does not know, and guessing would write over a file.\n if (parsed === undefined) {\n throw new Error(`ssh ${options.host}: stat ${path} printed an unexpected shape`);\n }\n return parsed;\n },\n writeFileAtomic: async (path, bytes, write) => {\n const at = path.lastIndexOf('/');\n const temp = `${path.slice(0, at)}/.${path.slice(at + 1)}.${randomBytes(6).toString('hex')}.tmp`;\n const result = await run(writeScript(path, temp, write), bytes);\n if (result.exitCode !== 0) throw failed(options.host, `write ${path}`, result);\n },\n };\n};\n",
|
|
30
31
|
"/**\n * User and group lookups, as argv plus a parser — split out so the parsing is tested against the\n * real output shapes without running anything.\n *\n * ★ macOS FIRST, getent ELSEWHERE. macOS has no `getent`; its directory service answers through\n * `dscacheutil`. Shape MEASURED 2026-09-21 on macOS 27.2 (read-only query):\n *\n * name: someone\n * password: ********\n * uid: 501\n * gid: 20\n * dir: /Users/someone\n * shell: /bin/zsh\n *\n * An unknown uid printed NOTHING and exited 0 — so \"no record\" is an empty parse, never an\n * exit code. `getent` exits 2 for an unknown key; that also parses as no record.\n * ⛔ NEVER PARSE OR KEEP THE `password:` LINE. It is a placeholder on macOS, but a parser that\n * copies every field would carry a hash from any host where it is not.\n */\nimport type { HostUser } from './runner.ts';\n\nconst NUMERIC = /^\\d+$/;\n\n/** argv for looking up a user, by name or numeric id. */\nexport const userQuery = (platform: string, nameOrId: string): readonly string[] =>\n platform === 'darwin'\n ? [\n '/usr/bin/dscacheutil',\n '-q',\n 'user',\n '-a',\n NUMERIC.test(nameOrId) ? 'uid' : 'name',\n nameOrId,\n ]\n : ['getent', 'passwd', nameOrId];\n\n/** argv for looking up a group, by name or numeric id. */\nexport const groupQuery = (platform: string, nameOrId: string): readonly string[] =>\n platform === 'darwin'\n ? [\n '/usr/bin/dscacheutil',\n '-q',\n 'group',\n '-a',\n NUMERIC.test(nameOrId) ? 'gid' : 'name',\n nameOrId,\n ]\n : ['getent', 'group', nameOrId];\n\n/** The first `key: value` record in dscacheutil output, minus any password field. */\nconst firstRecord = (stdout: string): Map<string, string> => {\n const fields = new Map<string, string>();\n for (const line of stdout.split('\\n')) {\n if (line.trim() === '') {\n if (fields.size > 0) break; // ⚠️ records are blank-line separated; keep the first only\n continue;\n }\n const at = line.indexOf(': ');\n if (at <= 0) continue;\n const key = line.slice(0, at);\n if (key === 'password') continue;\n fields.set(key, line.slice(at + 2).trim());\n }\n return fields;\n};\n\nconst toId = (text: string | undefined): number | undefined =>\n text !== undefined && NUMERIC.test(text) ? Number(text) : undefined;\n\nexport const parseUser = (platform: string, stdout: string): HostUser | undefined => {\n if (platform === 'darwin') {\n const record = firstRecord(stdout);\n const uid = toId(record.get('uid'));\n const gid = toId(record.get('gid'));\n const home = record.get('dir');\n return uid === undefined || gid === undefined || home === undefined\n ? undefined\n : { gid, home, uid };\n }\n // getent passwd: name:x:uid:gid:gecos:home:shell\n const fields = (stdout.split('\\n')[0] ?? '').split(':');\n const uid = toId(fields[2]);\n const gid = toId(fields[3]);\n const home = fields[5];\n return uid === undefined || gid === undefined || home === undefined || home === ''\n ? undefined\n : { gid, home, uid };\n};\n\nexport const parseGroup = (platform: string, stdout: string): number | undefined => {\n if (platform === 'darwin') return toId(firstRecord(stdout).get('gid'));\n // getent group: name:x:gid:members\n return toId((stdout.split('\\n')[0] ?? '').split(':')[2]);\n};\n",
|
|
31
32
|
"/**\n * The wire format the ssh runner speaks: how an argv becomes one remote `sh` script, and how that\n * script's real exit code comes back. Pure functions, so every quoting and framing rule is tested\n * without opening a connection.\n *\n * ⛔ `ssh host <words>` IS NOT AN EXECVE. ssh joins its trailing arguments with spaces and the\n * REMOTE LOGIN SHELL parses the result, so an unquoted path with a space, a `$`, a backtick or a\n * `;` is re-parsed as shell syntax on the other side. Everything therefore goes through\n * `shellQuote`, and the remote command is always `/bin/sh -c '<script>'` — a POSIX shell named\n * explicitly, so a csh or fish login shell only ever execs it.\n * ⛔ AN EXIT CODE FROM ssh IS AMBIGUOUS. ssh exits 255 for its own failures (connection refused,\n * host key changed, auth) and otherwise passes the remote exit code through — and a remote\n * command may itself exit 255. A runner that read the code alone would report \"the file is not\n * there\" for a dropped connection, which is the exact \"never infer success from an empty result\"\n * failure. So every script ends by printing its own status on stderr behind a PER-RUNNER NONCE,\n * and a result without that line is a transport failure, never data.\n * ⚠️ THE NONCE IS NOT DECORATION. Without it a remote program that happens to print the marker on\n * stderr could claim any exit code it liked; with a fresh random nonce per runner, the only thing\n * that can produce the line is the script we sent.\n */\n\n/** A script whose work found nothing at the path. ★ Chosen from the 64–113 range sh leaves free. */\nexport const ABSENT = 66;\n\n/**\n * One argument, safe for a POSIX shell. ⛔ Single quotes, because they quote EVERYTHING; the\n * `'\\''` dance is how a literal quote gets through.\n */\nexport const shellQuote = (arg: string): string => {\n if (arg.includes('\\x00')) throw new Error('ssh: an argument contains NUL');\n return `'${arg.replaceAll(\"'\", `'\\\\''`)}'`;\n};\n\n/** An argv as one shell command line. */\nexport const quoteArgv = (argv: readonly string[]): string => argv.map(shellQuote).join(' ');\n\nconst marker = (nonce: string) => `__HF_RC_${nonce}=`;\n\n/**\n * Wrap a script so its status comes back unambiguously.\n *\n * ⛔ THE SCRIPT RUNS IN A SUBSHELL, AND THAT IS NOT COSMETIC. Several of the scripts end a branch\n * with `exit <code>` to say \"nothing was there\"; at the top level that exit leaves the shell\n * immediately and the marker line NEVER PRINTS — so the caller sees a framed result missing its\n * frame and, correctly, calls it a transport failure. 🔴 MEASURED 2026-09-22 against a live\n * Debian 13 host: `stat` of a missing path came back as \"the remote command did not report a\n * status (ssh exit 66)\" instead of \"nothing is at this path\". Inside `( … )` the exit leaves only\n * the subshell, `$?` carries the code out, and the frame always runs.\n * ⚠️ The leading `\\n` matters too: a program whose last stderr line has no newline would otherwise\n * glue itself to the marker and the marker would not be found.\n */\nexport const frameScript = (script: string, nonce: string): string =>\n `(\\n${script}\\n)\\n__hf=$?\\nprintf '\\\\n${marker(nonce)}%s\\\\n' \"$__hf\" >&2\\nexit \"$__hf\"`;\n\nexport type Framed = { readonly exitCode: number; readonly stderr: string };\n\n/**\n * The remote exit code and the stderr that belongs to the command, or `undefined` when the marker\n * is absent — which means the script never ran to its end: ssh failed, the connection dropped, or\n * the remote shell could not parse what we sent. ⛔ The caller must treat `undefined` as an error,\n * never as an answer.\n */\nexport const parseFramed = (stderr: string, nonce: string): Framed | undefined => {\n const at = stderr.lastIndexOf(`\\n${marker(nonce)}`);\n if (at < 0) return undefined;\n const digits = /^(\\d+)\\s*$/.exec(stderr.slice(at + marker(nonce).length + 1));\n if (digits?.[1] === undefined) return undefined;\n return { exitCode: Number(digits[1]), stderr: stderr.slice(0, at) };\n};\n\n/**\n * The fixed ssh options, in front of anything a caller adds.\n * ⛔ `BatchMode=yes` — a deploy that stops to ask for a passphrase is the failure \"no password\n * prompts\" names, and with BatchMode ssh fails at once instead.\n * ⛔ NOTHING HERE WEAKENS HOST VERIFICATION. No `StrictHostKeyChecking`, no `UserKnownHostsFile`:\n * the operator's own ssh config and known_hosts decide who the host is, and a changed key stays\n * a refusal. A runner that turned that off would make a man-in-the-middle a deploy target.\n * ★ `-T`: no pseudo-terminal, so the remote shell's stdout stays the bytes the program wrote.\n */\nexport const sshArgv = (\n host: string,\n script: string,\n options: { readonly connectTimeoutSec: number; readonly sshArgs?: readonly string[] },\n): readonly string[] => {\n if (host === '' || host.startsWith('-')) {\n throw new Error(`ssh: ${JSON.stringify(host)} is not a usable destination`);\n }\n return [\n 'ssh',\n '-T',\n '-o',\n 'BatchMode=yes',\n '-o',\n `ConnectTimeout=${String(options.connectTimeoutSec)}`,\n ...(options.sshArgs ?? []),\n host,\n `/bin/sh -c ${shellQuote(script)}`,\n ];\n};\n",
|
|
32
33
|
"/**\n * The four remote scripts a HostRunner needs, and the parser for the one that returns data.\n * Pure: every shape here is asserted in ssh-scripts.test.ts without a connection.\n *\n * ★ MEASURED 2026-09-22 on Debian 13 (systemd 257, kernel 7.0.14-pve), read-only over ssh:\n * $ stat -c '%f %a %u %g %s' /etc/hostname → 81a4 644 0 0 4 (exit 0)\n * $ stat -c '%f %a %u %g %s' /nonexistent → \"cannot statx\" (exit 1)\n * `%f` is the RAW mode in hex, so the file type is in it (0x8000 regular, 0x4000 directory,\n * 0xa000 symlink) and `%a` is the permission bits alone. ⛔ GNU `stat` does NOT follow symlinks\n * without `-L`, which is what makes this an lstat — the FileStat contract (runner.ts) requires it,\n * because writing through a symlink changes a file the resource never named.\n * ⚠️ COREUTILS, NOT POSIX. `stat -c`, `base64` and `mv -f` are GNU/BusyBox spellings, not POSIX\n * ones; this runner is for Linux hosts and refuses anything else at the probe (ssh-runner.ts).\n */\nimport { ABSENT, quoteArgv, shellQuote } from './ssh-command.ts';\nimport type { FileStat, WriteOptions } from '../launchd/runner.ts';\n\n/** ★ `-e` is false for a dangling symlink and `-L` is true for it, so both tests together mean\n * \"something is at this path\" — the question stat(2) answers and `-e` alone does not. */\nconst IF_PRESENT = (path: string) => `if [ -e ${path} ] || [ -L ${path} ]; then`;\n\nexport const statScript = (path: string): string => {\n const quoted = shellQuote(path);\n return `${IF_PRESENT(quoted)} stat -c '%f %a %u %g %s' -- ${quoted}; else exit ${String(ABSENT)}; fi`;\n};\n\n/** ★ base64 on the wire: stdout then carries no byte that a shell, a pty or a locale can alter. */\nexport const readScript = (path: string): string => {\n const quoted = shellQuote(path);\n return `${IF_PRESENT(quoted)} base64 -- ${quoted}; else exit ${String(ABSENT)}; fi`;\n};\n\n/** ⛔ `rm -f` is idempotent for an absent path and still FAILS for a directory, which is what keeps\n * HostRunner.removeFile from quietly removing something that is not a file. */\nexport const removeScript = (path: string): string => `rm -f -- ${shellQuote(path)}`;\n\nexport const execScript = (argv: readonly string[]): string => quoteArgv(argv);\n\n/**\n * Write bytes (fed on stdin) so `path` holds the old file or the new one and never a torn mix.\n *\n * ⛔ NOT `install`. GNU coreutils `install` opens the destination and writes THROUGH it — unlike\n * macOS's, which stages and renames — so a deploy interrupted mid-write would leave a truncated\n * config where a whole one used to be. Staging beside the target and `mv` (rename(2), same\n * directory so never EXDEV) is the only atomic spelling available over a shell.\n * ⛔ `set -C` and `umask 077`: the staged file is created O_EXCL, so a symlink or a file planted at\n * the temp name is a refusal rather than a write through it, and it is unreadable by anyone else\n * in the moment before its mode is set.\n * ⚠️ chown BEFORE chmod: chown by root clears setuid/setgid, so the other order silently drops a\n * declared 4755 — the same ordering localRunner keeps for the same reason.\n * ⚠️ Each step removes the staged file before it fails, so a failed write leaves no litter beside\n * a file someone else owns.\n */\nexport const writeScript = (path: string, temp: string, options: WriteOptions): string => {\n const target = shellQuote(path);\n const staged = shellQuote(temp);\n const bail = `{ rm -f -- ${staged}; exit`;\n /**\n * ⛔ NEVER `chown <uid>:` — GNU chown reads a trailing colon as \"and that user's LOGIN GROUP\",\n * which is a gid nobody declared. Each half is spelled only when it was asked for.\n */\n const owner =\n options.uid === undefined\n ? options.gid === undefined\n ? undefined\n : `:${String(options.gid)}`\n : options.gid === undefined\n ? String(options.uid)\n : `${String(options.uid)}:${String(options.gid)}`;\n const chown = owner === undefined ? [] : [`chown ${owner} -- ${staged} || ${bail} 72; }`];\n return [\n 'set -C',\n 'umask 077',\n `cat > ${staged} || ${bail} 71; }`,\n ...chown,\n `chmod ${options.mode.toString(8).padStart(3, '0')} -- ${staged} || ${bail} 73; }`,\n `mv -f -- ${staged} ${target} || ${bail} 74; }`,\n ].join('\\n');\n};\n\nconst TYPE_BITS = 0xf000;\nconst KINDS = new Map<number, FileStat['kind']>([\n [0x8000, 'file'],\n [0x4000, 'directory'],\n [0xa000, 'symlink'],\n]);\n\n/** `stat -c '%f %a %u %g %s'` output → a FileStat, or `undefined` when it is not that shape. */\nexport const parseStat = (stdout: string): FileStat | undefined => {\n const fields = stdout.trim().split(/\\s+/);\n if (fields.length !== 5) return undefined;\n const [rawMode, perms, uid, gid, size] = fields as [string, string, string, string, string];\n const raw = Number.parseInt(rawMode, 16);\n const mode = Number.parseInt(perms, 8);\n const numbers = [raw, mode, Number(uid), Number(gid), Number(size)];\n if (numbers.some((value) => !Number.isSafeInteger(value) || value < 0)) return undefined;\n return {\n gid: Number(gid),\n kind: KINDS.get(raw & TYPE_BITS) ?? 'other',\n // ⚠️ `%a` alone, never `%f & 0o7777`: they agree, and the permission field is the documented one.\n mode,\n size: Number(size),\n uid: Number(uid),\n };\n};\n"
|
|
33
34
|
],
|
|
34
|
-
"mappings": ";AASA;AACA,oBAAS;AACT;AACA;AACA;;;ACJA;AAEO,IAAM,OAAO,CAAI,SACf,kBAAW;AAAA,EAChB,OAAO,CAAC,UAAW,iBAAiB,QAAQ,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;AAAA,EAC3E,KAAK;AACP,CAAC;AAQI,IAAM,iBAAiB,CAAC,MAAe,QAAoC;AAAA,EAChF,IAAI,OAAO,SAAS,YAAY,SAAS;AAAA,IAAM;AAAA,EAC/C,MAAM,QAAS,KAAiC;AAAA,EAChD,OAAO,OAAO,UAAU,WAAW,QAAQ;AAAA;;;ACZ7C;AACA;AAAA;AA8EO,MAAM,0BAAkC,gBAAuC,EACpF,8BACF,EAAE;AAAC;AAGI,IAAM,kBAAkB,CAAC,WACxB,cAAQ,mBAAmB,MAAM;AAGlC,IAAM,eAAe,CAAC,WAC3B,OAAO,cAAc,OAAO,aAAa,MAAM;;;AC9FjD;AACA;AACA,kBAAS;AACT;AACA;;;ACiBA;AACA;AACA;AACA;AAEA,IAAM,SAAS;AACf,IAAM,aAAa;AAEnB,IAAM,OAAO,CAAC,KAAa,eAClB,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,MAAM,OAAc,sBAAc,SAAS;AAAA,EACjD,IAAW,cAAO,GAAG;AAAA,IAAG,OAAO,IAAI,MAAM,IAAI,KAAK,UAAU;AAAA,CAC7D;AAEH,IAAM,QAAQ,CAAC,KAAa,eACnB,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,MAAM,OAAc,sBAAc,SAAS;AAAA,EACjD,IAAW,cAAO,GAAG;AAAA,IAAG,OAAO;AAAA,EAC/B,QAAQ,OAAO,IAAI,MAAM,IAAY,GAAG,OAAO;AAAA,CAChD;AAOI,IAAM,iBAAiB,CAAC,eACtB,WAAG,KAAK,YAAY,UAAU,GAAG,SAAS;AAQ5C,IAAM,aAAa,CACxB,YACA,cAEO,YAAI,UAAU,GAAG;AAAA,EACtB,OAAO,eAAe,UAAU;AAAA,EAChC,MAAM,WAAW,MAAa,gBAAQ,SAAS;AAAA,EAC/C,MAAM,QAAQ,OAAO,UAAU,KAAY,cAAM,QAAQ,GAAU,oBAAY,QAAQ,CAAC;AAAA,EACxF,IAAI,UAAU,aAAa,UAAU,QAAQ,QAAQ,GAAG,KAAK;AAAA,IAAG;AAAA,EAChE,OAAO,KAAK,QAAQ,UAAU;AAAA,CAC/B;AAGI,IAAM,UAAU,CAAC,eAA+C,MAAM,QAAQ,UAAU;AAGxF,IAAM,aAAa,CAAC,eACzB,MAAM,YAAY,UAAU;AAuBvB,IAAM,iBAAiB,CAAsB,YAAkB;AAAA,EACpE,QAAQ,MAAM,SAAS;AAAA,EACvB,IAAI,SAAS,aAAa,SAAS;AAAA,IAAW,OAAO;AAAA,EACrD,MAAM,UAA6B,CAAC,UAC3B,YAAI,UAAU,GAAG;AAAA,IACtB,IAAI,MAAM,WAAW,WAAW;AAAA,MAC9B,OAAO,WAAW,MAAM,YAAY,KAAK,KAAK,OAAO,QAAQ,UAAU,CAAC,CAAC;AAAA,IAC3E;AAAA,IACA,OAAO,OAAO,KAAK,KAAK;AAAA,GACzB;AAAA,EAEH,OAAO,KAAK,SAAS,MAAM,QAAQ;AAAA;;;ACxGrC,kBAAS;AACT;AACA;AACA;;;ACIA;AACA;AACA;AAEA,IAAM,SAAS,CAAC,UAA4B,UAAU,aAAa,UAAU;AAE7E,IAAM,gBAAgB,CAAC,UAAqD;AAAA,EAC1E,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,MAAM,QAAQ,KAAK;AAAA,IAAG,OAAO;AAAA,EAChF,MAAM,QAAiB,OAAO,eAAe,KAAK;AAAA,EAClD,OAAO,UAAU,OAAO,aAAa,UAAU;AAAA;AAO1C,IAAM,UAAU,CAAC,UAAmB,aAA+B;AAAA,EACxE,IAAI,OAAO,QAAQ;AAAA,IAAG,OAAO;AAAA,EAC7B,IAAI,OAAO,QAAQ;AAAA,IAAG,OAAO;AAAA,EAC7B,IAAI,MAAM,QAAQ,QAAQ,GAAG;AAAA,IAC3B,IAAI,CAAC,MAAM,QAAQ,QAAQ;AAAA,MAAG,OAAO;AAAA,IACrC,OAAO,SAAS,MAAM,CAAC,MAAM,UAAU,QAAQ,MAAM,SAAS,MAAM,CAAC;AAAA,EACvE;AAAA,EACA,IAAI,cAAc,QAAQ,GAAG;AAAA,IAC3B,IAAI,CAAC,cAAc,QAAQ;AAAA,MAAG,OAAO;AAAA,IACrC,OAAO,OAAO,QAAQ,QAAQ,EAAE,MAAM,EAAE,KAAK,UAAU,QAAQ,MAAM,SAAS,IAAI,CAAC;AAAA,EACrF;AAAA,EACA,OAAO;AAAA;AASF,IAAM,mBAAmB,CAAC,KAAa,UACrC,YAAW,sBAAc,KAAK,GAAG,CAAC,UAAU;AAAA,EACjD,MAAM,WAAkB,eAAO,KAAK,IAAI,MAAM,MAAM,UAAU,OAAO;AAAA,EACrE,OAAO,aAAa,aAAa,QAAQ,SAAS,OAAO,KAAK;AAAA,CAC/D;;;ADtCH,IAAM,UAAiB,YAAI,UAAU,GAAG;AAAA,EACtC,MAAM,QAAQ,OAAc,sBAAc,MAAK;AAAA,EAC/C,MAAM,QAAQ,OAAc,sBAAc,KAAK;AAAA,EAC/C,IAAW,eAAO,KAAK,KAAY,eAAO,KAAK;AAAA,IAAG;AAAA,EAClD,MAAM,QAAsB,OAAO,MAAM;AAAA,EACzC,MAAM,QAAe,EAAE,OAAO,MAAM,MAAM,MAAM,OAAO,MAAM,MAAM,MAAM;AAAA,EACzE,OAAO,EAAE,WAAW,MAAM,MAAM,WAAW,OAAO,MAAM;AAAA,CACzD;AAED,IAAM,QAAQ,CAAC,OAAqB,OAAc,QAChD,MAAM,IAAI,KAAK,OAAO,IAAI,CAAC,EAAE,KAAY,sBAAc,MAAG;AAAA,EAAG;AAAA,CAAS,CAAC;AAczE,IAAM,eAAe,CAAC,KAAc,eAA+C;AAAA,EACjF,IAAI,KAAK;AAAA,EACT,OAAO,OAAO,OAAO,YAAY,OAAO,QAAQ,CAAC,cAAc,EAAW,GAAG;AAAA,IAC3E,MAAM,aAAa;AAAA,IACnB,IAAI,WAAW,eAAe;AAAA,MAAY,OAAO;AAAA,IACjD,KAAK,WAAW;AAAA,EAClB;AAAA,EACA;AAAA;AAIK,IAAM,qBAAqB,CAChC,KACA,eAEO,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,WAAW,MAAM,CAAC,KAAK,GAAI,MAAM,UAAU,MAAM,cAAc,CAAC,CAAE,GAAG;AAAA,IACnE,MAAM,aAAa,aAAa,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,EAAE,GAAG,UAAU;AAAA,IACtF,IAAI,eAAe;AAAA,MAAW,OAAO;AAAA,EACvC;AAAA,EACA;AAAA,CACD;AAcI,IAAM,mBAAmB,CAAC,KAAa,eACrC,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,aAAa,OAAO,mBAAmB,KAAK,UAAU;AAAA,EAC5D,IAAI,eAAe;AAAA,IAAW,OAAO;AAAA,EACrC,QAAQ,OAAO,iBAAiB,KAAK,WAAW,KAAK,KAAK,UAAU;AAAA,CACrE;AAQI,IAAM,WAAW,CAAC,KAAa,eAC7B,YACL,mBAAmB,KAAK,UAAU,GAClC,CAAC,eAAe,YAAY,WAAW,UACzC;AAaK,IAAM,sBAAsB,CAAC,KAAa,eACxC,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,QAAQ,OAAO;AAAA,EACrB,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,MAAM,MAAM,OAAO,MAAM,MAAM,OAAO,MAAM,OAAO,GAAG;AAAA,EACtD,MAAM,OAAO;AAAA,EACb,IAAI,MAAM,WAAW,cAAc,KAAK,eAAe,cAAc,KAAK,SAAS,WAAW;AAAA,IAC5F;AAAA,EACF;AAAA,EACA,OAAO,MAAM,MAAM,OAAO,KAAK,MAAM,OAAO,IAAI,CAAC,EAAE,KAAY,cAAM;AAAA,CACtE;;;AFxFI,IAAM,eAAe,CAAC,QACpB,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,QAAQ,OAAc,sBAAc,MAAK;AAAA,EAC/C,MAAM,SAAgB,eAAO,KAAK,IAAI,MAAM,MAAM,UAAU,MAAM,QAAQ;AAAA,EAC1E,IAAI,WAAW;AAAA,IAAW,OAAO;AAAA,EACjC,MAAM,SAAS,OAAc,sBAAc,WAAW;AAAA,EACtD,IAAW,eAAO,MAAM;AAAA,IAAG,OAAO,OAAO;AAAA,EACzC,MAAM,UAAU,OAAc,sBAAc,cAAc;AAAA,EAC1D,OAAc,eAAO,OAAO,IAAI,QAAQ,MAAM,QAAQ;AAAA,CACvD;AAqBH,IAAM,YAAY,CAAC,UACV,YAAI,UAAU,GAAG;AAAA,EACtB,IAAI,OAAO,SAAS,MAAM,KAAK,MAAM,UAAU;AAAA,IAAG,OAAO;AAAA,EACzD,OAAO,OAAO,WAAW,MAAM,UAAU;AAAA,CAC1C;AAGI,IAAM,gBAAgB,CAAC,UACrB,YAAI,UAAU,GAAG;AAAA,EACtB,IAAI,EAAE,OAAO,aAAa,MAAM,GAAG;AAAA,IAAI,OAAO;AAAA,EAC9C,OAAO,OAAO,UAAU,KAAK;AAAA,CAC9B;AAuBI,IAAM,iBAAiB,CAAC,OAAc,SACpC,YAAI,UAAU,GAAG;AAAA,EACtB,IAAI,MAAM,WAAW;AAAA,IAAW;AAAA,EAChC,IAAI,OAAO,QAAQ,MAAM,UAAU;AAAA,IAAG;AAAA,EACtC,MAAM,MAAM,OAAO,UAAU,KAAK;AAAA,EAClC,IAAI,QAAQ,OAAO,aAAa,MAAM,GAAG;AAAA,IAAI;AAAA,EAC7C,OAAO,oBAAoB,MAAM,KAAK,MAAM,UAAU;AAAA,EACtD,MAAM,SAAS,MACX,mGACA;AAAA,EACJ,OAAO,OAAc,YACnB,IAAI,MACF,GAAG,yFACD,0FACA,+BAA+B,QACnC,CACF;AAAA,CACD;AAGI,IAAM,WACX,CAAC,UACD,CAAC,SACC,eAAe,OAAO,IAAI;;;AIzG9B,IAAM,cACJ,gGACA;AAGF,IAAM,cACJ;AAGF,IAAM,cAAc;AAGpB,IAAM,YAAY;AAEX,IAAM,cAAc;AAG3B,IAAM,YAAY,CAAC,OAAmB,SAA2B;AAAA,EAC/D,IAAI,OAAO,UAAU;AAAA,IAAU,OAAO,YAAY,KAAK,KAAK,IAAI,CAAC,IAAI,IAAI,CAAC;AAAA,EAC1E,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxB,OAAQ,MAAgC,QAAQ,CAAC,MAAM,UACrD,UAAU,MAAM,GAAG,QAAQ,OAAO,KAAK,IAAI,CAC7C;AAAA,EACF;AAAA,EACA,IAAI,OAAO,UAAU,YAAY,UAAU,MAAM;AAAA,IAC/C,OAAO,OAAO,QAAQ,KAAK,EAAE,QAAQ,EAAE,KAAK,UAAU,UAAU,MAAM,GAAG,QAAQ,KAAK,CAAC;AAAA,EACzF;AAAA,EACA,OAAO,CAAC;AAAA;AAOH,IAAM,oBAAoB,CAC/B,aACA,MACA,cACa;AAAA,EACb,MAAM,QAAkB,CAAC;AAAA,EACzB,YAAY,MAAM,UAAU,OAAO,QAAQ,eAAe,CAAC,CAAC,GAAG;AAAA,IAC7D,IAAI,YAAY,KAAK,IAAI;AAAA,MACvB,MAAM,KAAK,eAAe,6BAA6B,aAAa;AAAA,IACjE,SAAI,YAAY,KAAK,KAAK;AAAA,MAC7B,MAAM,KAAK,eAAe,6BAA6B,aAAa;AAAA,EACxE;AAAA,EACA,YAAY,OAAO,QAAQ,KAAK,QAAQ,GAAG;AAAA,IAEzC,IAAI,YAAY,KAAK,GAAG,GAAG;AAAA,MACzB,MAAM,KAAK,oBAAoB,OAAO,KAAK,8BAA8B,aAAa;AAAA,IACxF,EAAO,SAAI,UAAU,KAAK,GAAG,KAAK,QAAQ,IAAI,KAAK,QAAQ;AAAA,MACzD,MAAM,KAAK,oBAAoB,OAAO,QAAQ,CAAC,6BAA6B,aAAa;AAAA,IAC3F,EAAO,SAAI,YAAY,KAAK,GAAG,GAAG;AAAA,MAChC,MAAM,KAAK,oBAAoB,OAAO,KAAK,2BAA2B,aAAa;AAAA,IACrF;AAAA,EACF;AAAA,EACA,WAAW,QAAQ,UAAU,aAAa,CAAC,GAAG,WAAW,GAAG;AAAA,IAC1D,MAAM,KAAK,GAAG,6BAA6B,aAAa;AAAA,EAC1D;AAAA,EACA,OAAO;AAAA;AAIF,IAAM,qBAAqB,CAAC,YACjC,YAAY,KAAK,OAAO,IAAI,CAAC,gCAAgC,aAAa,IAAI,CAAC;;;AC9C1E,IAAM,eAAe;AAE5B,IAAM,mBAAmB,CAAC,MAAc,UAAiD;AAAA,EACvF,IAAI,UAAU;AAAA,IAAW,OAAO,CAAC;AAAA,EACjC,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,OAAO,OAAO,cAAc,KAAK,KAAK,SAAS,IAC3C,CAAC,IACD,CAAC,GAAG,wCAAwC;AAAA,EAClD;AAAA,EACA,OAAO,6BAA6B,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,IACjE,CAAC,IACD,CAAC,GAAG,QAAQ,KAAK,UAAU,KAAK,qCAAqC;AAAA;AAOpE,IAAM,eAAe,CAAC,SAA2B;AAAA,EACtD,MAAM,QAAkB,CAAC;AAAA,EACzB,IAAI,CAAC,KAAK,WAAW,GAAG;AAAA,IAAG,MAAM,KAAK,uBAAuB;AAAA,EAG7D,IACE,KAAK,SAAS,GAAG,KACjB,KACG,MAAM,GAAG,EACT,MAAM,CAAC,EACP,KAAK,CAAC,SAAS,SAAS,MAAM,SAAS,OAAO,SAAS,IAAI,GAC9D;AAAA,IACA,MAAM,KAAK,6EAA6E;AAAA,EAC1F;AAAA,EACA,IAAI,KAAK,SAAS,MAAM;AAAA,IAAG,MAAM,KAAK,mBAAmB;AAAA,EACzD,OAAO;AAAA;AAGF,IAAM,eAAe,CAAC,UAAmC;AAAA,EAC9D,MAAM,QAAQ,aAAa,MAAM,IAAI;AAAA,EACrC,MAAM,OAAO,MAAM,QAAQ;AAAA,EAC3B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO;AAAA,IAAQ,MAAM,KAAK,uBAAuB;AAAA,EAChG,MAAM,KAAK,GAAG,iBAAiB,SAAS,MAAM,KAAK,CAAC;AAAA,EACpD,MAAM,KAAK,GAAG,iBAAiB,SAAS,MAAM,KAAK,CAAC;AAAA,EACpD,MAAM,KAAK,GAAG,mBAAmB,MAAM,OAAO,CAAC;AAAA,EAC/C,OAAO;AAAA;;;AC1CF,IAAM,mBAAmB;AAEzB,IAAM,SAAS,CAAC,MAAc,YACnC,IAAI,MAAM,kBAAkB,SAAS,SAAS;AAEhD,IAAM,aAAa,CAAC,MAAc,UAAiD;AAAA,EACjF,IAAI,UAAU;AAAA,IAAW,OAAO,CAAC;AAAA,EACjC,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,OAAO,OAAO,cAAc,KAAK,KAAK,SAAS,IAAI,CAAC,IAAI,CAAC,GAAG,gCAAgC;AAAA,EAC9F;AAAA,EACA,OAAO,6BAA6B,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,IACjE,CAAC,IACD,CAAC,GAAG,QAAQ,KAAK,UAAU,KAAK,qCAAqC;AAAA;AAGpE,IAAM,oBAAoB,CAAC,UAAwC;AAAA,EACxE,MAAM,QAAQ,aAAa,MAAM,IAAI;AAAA,EACrC,MAAM,OAAO,MAAM,QAAQ;AAAA,EAC3B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO;AAAA,IAAQ,MAAM,KAAK,uBAAuB;AAAA,EAChG,MAAM,KAAK,GAAG,WAAW,SAAS,MAAM,KAAK,GAAG,GAAG,WAAW,SAAS,MAAM,KAAK,CAAC;AAAA,EACnF,OAAO;AAAA;AAGT,IAAM,YAAY,CAAC,UACjB,OAAO,UAAU,WAAW,QAAQ,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI;AAI5E,IAAM,UAAU,OAAO,QAAoB,UAAgD;AAAA,EACzF,MAAM,QAAQ,kBAAkB,KAAK;AAAA,EACrC,IAAI,MAAM,SAAS;AAAA,IAAG,MAAM,OAAO,MAAM,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAC/D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,MAAM,UAAU,MAAM,KAAK,MAAM,MAAM,OAAO,WAAW,OAAO,MAAM,KAAK,CAAC,IAAI;AAAA,IAChF,IAAI,QAAQ;AAAA,MAAW,MAAM,OAAO,MAAM,MAAM,WAAW,OAAO,MAAM,KAAK,gBAAgB;AAAA,EAC/F;AAAA,EACA,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,MAAM,UAAU,MAAM,KAAK,KAAM,MAAM,OAAO,YAAY,OAAO,MAAM,KAAK,CAAC;AAAA,IAC7E,IAAI,QAAQ;AAAA,MAAW,MAAM,OAAO,MAAM,MAAM,YAAY,OAAO,MAAM,KAAK,gBAAgB;AAAA,EAChG;AAAA,EACA,OAAO;AAAA,IACL,MAAM,MAAM,QAAQ;AAAA,OAChB,QAAQ,YAAY,CAAC,IAAI,EAAE,IAAI;AAAA,OAC/B,QAAQ,YAAY,CAAC,IAAI,EAAE,IAAI;AAAA,EACrC;AAAA;AAGK,IAAM,gBAAgB,OAC3B,QACA,SACiD;AAAA,EACjD,MAAM,OAAO,MAAM,OAAO,KAAK,IAAI;AAAA,EACnC,IAAI,SAAS,aAAa,KAAK,SAAS;AAAA,IAAa;AAAA,EACrD,OAAO,EAAE,KAAK,KAAK,KAAK,MAAM,KAAK,MAAM,MAAM,KAAK,KAAK,IAAI;AAAA;AAG/D,IAAM,QAAQ,CAAC,SAAiB,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG;AAGhE,IAAM,OAAO,OAAO,QAAoB,MAAc,SAA2C;AAAA,EAC/F,MAAM,SAAS,MAAM,OAAO,KAAK,IAAI;AAAA,EACrC,IAAI,OAAO,aAAa,GAAG;AAAA,IACzB,MAAM,OACJ,MACA,GAAG,KAAK,KAAK,GAAG,QAAQ,OAAO,OAAO,QAAQ,MAAM,OAAO,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,GACvF;AAAA,EACF;AAAA;AAQK,IAAM,qBAAqB,OAChC,QACA,OACA,QACA,QAAQ,UAC6B;AAAA,EACrC,MAAM,OAAO,MAAM,QAAQ,QAAQ,KAAK;AAAA,EACxC,IAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,OAAO,aAAa,KAAK,CAAC,aAAa,MAAM,GAAG;AAAA,IACzF,MAAM,OACJ,MAAM,MACN,SAAS,OAAO,MAAM,KAAK,sEACzB,uFACJ;AAAA,EACF;AAAA,EACA,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA,EACzC,IAAI,SAAS,aAAa,KAAK,SAAS,aAAa;AAAA,IACnD,MAAM,OAAO,MAAM,MAAM,QAAQ,KAAK,uBAAuB;AAAA,EAC/D;AAAA,EAMA,IAAI,WAAW,aAAa,SAAS,aAAa,CAAC,OAAO;AAAA,IACxD,MAAM,UAAU,KAAK,SAAS,KAAK,QAAS,KAAK,QAAQ,aAAa,KAAK,QAAQ,KAAK;AAAA,IACxF,IAAI,SAAS;AAAA,MACX,MAAM,OACJ,MAAM,MACN,uFACE,uDACJ;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,SAAS,WAAW;AAAA,IACtB,MAAM,SAAS,MAAM,KAAK,MAAM,GAAG,MAAM,KAAK,YAAY,GAAG,CAAC,KAAK;AAAA,IACnE,MAAM,QAAQ,MAAM,OAAO,KAAK,MAAM;AAAA,IACtC,IAAI,UAAU,aAAa,MAAM,SAAS,aAAa;AAAA,MACrD,MAAM,OAAO,MAAM,MAAM,cAAc,mDAAmD;AAAA,IAC5F;AAAA,IACA,MAAM,KAAK,QAAQ,MAAM,MAAM,CAAC,SAAS,MAAM,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM,IAAI,CAAC;AAAA,EACpF,EAAO,SAAI,KAAK,SAAS,KAAK,MAAM;AAAA,IAClC,MAAM,KAAK,QAAQ,MAAM,MAAM,CAAC,SAAS,MAAM,KAAK,IAAI,GAAG,MAAM,MAAM,IAAI,CAAC;AAAA,EAC9E;AAAA,EAMA,MAAM,QAAQ,aACZ,EAAE,KAAK,MAAM,OAAO,IAAI,MAAM,GAAG,MAAM,MAAM,MAAM,KAAK,MAAM,OAAO,GAAG,GACxE,IACF,IACI,YACA,SAAS,IAAI;AAAA,EACjB,IAAI,UAAU;AAAA,IAAW,MAAM,KAAK,QAAQ,MAAM,MAAM,CAAC,SAAS,OAAO,MAAM,MAAM,IAAI,CAAC;AAAA,EAC1F,MAAM,QAAQ,MAAM,cAAc,QAAQ,MAAM,IAAI;AAAA,EAEpD,IAAI,UAAU,aAAa,MAAM,SAAS,KAAK,QAAQ,CAAC,aAAa,OAAO,IAAI,GAAG;AAAA,IACjF,MAAM,OAAO,MAAM,MAAM,0DAA0D;AAAA,EACrF;AAAA,EACA,OAAO;AAAA;AAIT,IAAM,WAAW,CAAC,SAAsC;AAAA,EACtD,IAAI,KAAK,QAAQ;AAAA,IAAW,OAAO,KAAK,QAAQ,YAAY,YAAY,IAAI,OAAO,KAAK,GAAG;AAAA,EAC3F,OAAO,KAAK,QAAQ,YAAY,OAAO,KAAK,GAAG,IAAI,GAAG,OAAO,KAAK,GAAG,KAAK,OAAO,KAAK,GAAG;AAAA;AAG3F,IAAM,eAAe,CAAC,MAA+B,UAClD,KAAK,QAAQ,aAAa,KAAK,QAAQ,KAAK,SAC5C,KAAK,QAAQ,aAAa,KAAK,QAAQ,KAAK;AAOxC,IAAM,gBAAgB,OAC3B,QACA,MACA,WACkB;AAAA,EAClB,MAAM,OAAO,MAAM,QAAQ,QAAQ,IAAI;AAAA,EACvC,IAAI,KAAK,SAAS,OAAO;AAAA,IAAM,OAAO,EAAE,QAAQ,UAAU;AAAA,EAC1D,MAAM,OAAO,MAAM,cAAc,QAAQ,KAAK,IAAI;AAAA,EAGlD,MAAM,YACJ,SAAS,aACT,KAAK,SAAS,KAAK,QACnB,aAAa,MAAM,IAAI,KACvB,OAAO,SAAS,KAAK,QACrB,aAAa,QAAQ,IAAI;AAAA,EAC3B,IAAI;AAAA,IAAW,OAAO,EAAE,QAAQ,OAAO;AAAA,EACvC,MAAM,OAAO,aAAa,KAAK,MAAM,IAAI;AAAA,EACzC,OAAO,EAAE,QAAQ,SAAS;AAAA;AAIrB,IAAM,kBAAkB,OAC7B,QACA,WACkB;AAAA,EAClB,MAAM,OAAO,MAAM,OAAO,KAAK,OAAO,IAAI;AAAA,EAC1C,IAAI,SAAS;AAAA,IAAW;AAAA,EACxB,IAAI,KAAK,SAAS;AAAA,IAChB,MAAM,OAAO,OAAO,MAAM,YAAY,KAAK,uBAAuB;AAAA,EACpE,MAAM,KAAK,QAAQ,OAAO,MAAM,CAAC,SAAS,MAAM,OAAO,IAAI,CAAC;AAAA;;;ATxLvD,IAAM,gBAAgB,SAAwB,gBAAgB;AAE9D,IAAM,wBAAwB,MAC1B,gBACP,eACO,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,SAAS,OAAO;AAAA,EACtB,OAAO,cAAc,SAAS,GAAG;AAAA,IAC/B,MAAM,MAAa,gBAAQ,CAAC,CAAC;AAAA,IAE7B,MAAM,GAAG,MAAM,aACb,KAAK,YAAY;AAAA,MACf,MAAM,QAAQ,MAAM,cAAc,QAAQ,KAAK,IAAI;AAAA,MACnD,IAAI,UAAU;AAAA,QAAW;AAAA,MACzB,OAAO,WAAW,YAAY,SAAQ,KAAK,IAAI;AAAA,KAChD;AAAA,IAEH,MAAM,GAAG,YAAY,MAAM,aAAa;AAAA,MACtC,IAAI,WAAW;AAAA,QAAW,OAAO,eAAe,UAAU;AAAA,MAC1D,IAAI,WAAW,IAAI;AAAA,QAAG,OAAO,KAAK,MAAM,cAAc,QAAQ,MAAM,MAAM,CAAC;AAAA,MAG3E,MAAM,OAAO,eAAe,MAAM,MAAM;AAAA,MACxC,OAAc,gBACZ,SAAS,aAAa,SAAS,OAAO,OAAO,EAAE,QAAQ,UAAmB,IAAI,SAChF;AAAA;AAAA,IAGF,WAAW,GAAG,KAAK,YAAY,MAAM,aAC5B,gBAAQ,cAAc,EAAE,KAAK,YAAY,OAAO,CAAC,GAAG,CAAC,UAC1D,KAAK,MAAM,mBAAmB,QAAQ,MAAM,QAAQ,KAAK,CAAC,CAC5D;AAAA,IAEF,QAAQ,GAAG,aAAa,KAAK,MAAM,gBAAgB,QAAQ,MAAM,CAAC;AAAA,EACpE,CAAC;AAAA,CACF,CACH;;AUzDF;;;ACKA,qBAAS;AACT,oBAAS;AACT,uBAAS;AACT;AACA;;;ACZA;;;ACqBO,MAAM,mBAAmB,MAAM;AAAA,EAEzB;AAAA,EADX,WAAW,CACA,MACT,QACA;AAAA,IACA,MAAM,SAAS,SAAS,KAAK,WAAW,SAAS,QAAQ;AAAA,IAHhD;AAAA,IAIT,KAAK,OAAO;AAAA;AAEhB;AAEA,IAAM,SACJ;AAAA,IACA,0DACA;AAAA,IACA;AAAA;AAGF,IAAM,YAAY;AASlB,IAAM,YAAY;AAQX,IAAM,aAAa,CAAC,MAAc,SAAyB;AAAA,EAChE,MAAM,MAAM,UAAU,KAAK,IAAI;AAAA,EAC/B,IAAI,QAAQ,MAAM;AAAA,IAChB,MAAM,OAAO,IAAI,GAAG,YAAY,CAAC,KAAK;AAAA,IACtC,MAAM,IAAI,WACR,MACA,KAAK,KAAK,SAAS,EAAE,EAAE,YAAY,EAAE,SAAS,GAAG,GAAG,4BACtD;AAAA,EACF;AAAA,EACA,OAAO,KACJ,WAAW,KAAK,OAAO,EACvB,WAAW,KAAK,MAAM,EACtB,WAAW,KAAK,MAAM,EACtB,WAAW,MAAM,OAAO;AAAA;AAG7B,IAAM,iBAAgB,CAAC,UAA2B;AAAA,EAChD,MAAM,QAAQ,OAAO,eAAe,KAAK;AAAA,EACzC,OAAO,UAAU,OAAO,aAAa,UAAU;AAAA;AAGjD,IAAM,cAAc,CAAC,OAAgB,MAAc,OAAe,QAAwB;AAAA,EACxF,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,EAC7B,IAAI,QAAQ;AAAA,IAAW,MAAM,IAAI,WAAW,MAAM,sBAAsB,OAAO,SAAS,GAAG;AAAA,EAC3F,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,IAAI,KAAK,GAAG,cAAc,WAAW,OAAO,IAAI,YAAY;AAAA,IAC5D;AAAA,EACF;AAAA,EACA,IAAI,OAAO,UAAU,WAAW;AAAA,IAC9B,IAAI,KAAK,GAAG,OAAO,QAAQ,SAAS,WAAW;AAAA,IAC/C;AAAA,EACF;AAAA,EACA,IAAI,OAAO,UAAU,UAAU;AAAA,IAE7B,IAAI,CAAC,OAAO,cAAc,KAAK,GAAG;AAAA,MAChC,MAAM,IAAI,WAAW,MAAM,GAAG,OAAO,KAAK,6CAA6C;AAAA,IACzF;AAAA,IACA,IAAI,KAAK,GAAG,eAAe,OAAO,UAAU,IAAI,IAAI,KAAK,aAAa;AAAA,IACtE;AAAA,EACF;AAAA,EACA,IAAI,MAAM,QAAQ,KAAK,GAAG;AAAA,IACxB,IAAI,MAAM,WAAW,GAAG;AAAA,MACtB,IAAI,KAAK,GAAG,aAAa;AAAA,MACzB;AAAA,IACF;AAAA,IACA,IAAI,KAAK,GAAG,YAAY;AAAA,IACxB,YAAY,OAAO,SAAU,MAA6B,QAAQ,GAAG;AAAA,MACnE,YAAY,MAAM,GAAG,QAAQ,OAAO,KAAK,MAAM,QAAQ,GAAG,GAAG;AAAA,IAC/D;AAAA,IACA,IAAI,KAAK,GAAG,aAAa;AAAA,IACzB;AAAA,EACF;AAAA,EACA,IAAI,OAAO,UAAU,YAAY,UAAU,QAAQ,eAAc,KAAK,GAAG;AAAA,IACvE,WAAW,OAAkC,MAAM,OAAO,GAAG;AAAA,IAC7D;AAAA,EACF;AAAA,EACA,MAAM,OAAO,UAAU,OAAO,SAAS,OAAO;AAAA,EAC9C,MAAM,IAAI,WAAW,MAAM,GAAG,+CAA+C;AAAA;AAG/E,IAAM,aAAa,CACjB,MACA,MACA,OACA,QACS;AAAA,EACT,MAAM,MAAM,KAAK,OAAO,KAAK;AAAA,EAE7B,MAAM,OAAO,OAAO,KAAK,IAAI,EAAE,KAAK;AAAA,EACpC,IAAI,KAAK,WAAW,GAAG;AAAA,IACrB,IAAI,KAAK,GAAG,YAAY;AAAA,IACxB;AAAA,EACF;AAAA,EACA,IAAI,KAAK,GAAG,WAAW;AAAA,EACvB,WAAW,OAAO,MAAM;AAAA,IACtB,MAAM,QAAQ,SAAS,KAAK,MAAM,GAAG,QAAQ;AAAA,IAC7C,IAAI,KAAK,GAAG,YAAa,WAAW,KAAK,KAAK,SAAS;AAAA,IACvD,YAAY,KAAK,MAAM,OAAO,QAAQ,GAAG,GAAG;AAAA,EAC9C;AAAA,EACA,IAAI,KAAK,GAAG,YAAY;AAAA;AAInB,IAAM,cAAc,CAAC,SAA4B;AAAA,EACtD,IAAI,OAAO,SAAS,YAAY,SAAS,QAAQ,MAAM,QAAQ,IAAI,KAAK,CAAC,eAAc,IAAI,GAAG;AAAA,IAC5F,MAAM,IAAI,WAAW,IAAI,iDAAiD;AAAA,EAC5E;AAAA,EACA,MAAM,MAAgB,CAAC;AAAA,EACvB,WAAW,MAAiC,IAAI,GAAG,GAAG;AAAA,EACtD,OAAO,GAAG,SAAS,IAAI,KAAK;AAAA,CAAI;AAAA;AAAA;AAAA;;;ADxE3B,IAAM,cAAc,CAAC,WAA6C;AAAA,EACvE,IAAI,WAAW;AAAA,IAAU,OAAO,EAAE,MAAM,SAAS;AAAA,EACjD,MAAM,QAAQ,eAAe,KAAK,MAAM;AAAA,EACxC,OAAO,QAAQ,OAAO,YAAY,YAAY,EAAE,MAAM,OAAO,KAAK,OAAO,MAAM,EAAE,EAAE;AAAA;AAG9E,IAAM,gBAAgB,CAAC,OAAe,WAAkC,GAAG,UAAU;AAOrF,IAAM,eAAe,CAC1B,OACA,QACA,SACW;AAAA,EACX,IAAI,OAAO,SAAS;AAAA,IAAU,OAAO,0BAA0B;AAAA,EAE/D,IAAI,SAAS,aAAa,CAAC,KAAK,WAAW,GAAG,GAAG;AAAA,IAC/C,MAAM,IAAI,MAAM,OAAO,OAAO,OAAO,GAAG,gDAAgD;AAAA,EAC1F;AAAA,EACA,OAAO,GAAG,6BAA6B;AAAA;AAIlC,IAAM,aAAgC;AAAA,EAC3C;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,eAAe,CAAC,UAAuC;AAAA,EAC3D,MAAM,OAAmC,CAAC;AAAA,EAC1C,IAAI,MAAM,WAAW;AAAA,IAAW,KAAK,YAAY,MAAM;AAAA,EACvD,IAAI,MAAM,SAAS;AAAA,IAAW,KAAK,UAAU,MAAM;AAAA,EACnD,IAAI,MAAM,QAAQ;AAAA,IAAW,KAAK,SAAS,MAAM;AAAA,EACjD,IAAI,MAAM,YAAY;AAAA,IAAW,KAAK,aAAa,MAAM;AAAA,EACzD,IAAI,MAAM,UAAU;AAAA,IAAW,KAAK,WAAW,MAAM;AAAA,EACrD,OAAO;AAAA;AAGT,IAAM,iBAAiB,CAAC,cAAqC;AAAA,EAC3D,IAAI,OAAO,cAAc;AAAA,IAAW,OAAO;AAAA,EAC3C,MAAM,OAAmC,CAAC;AAAA,EAC1C,IAAI,UAAU,mBAAmB;AAAA,IAAW,KAAK,oBAAoB,UAAU;AAAA,EAC/E,IAAI,UAAU,YAAY;AAAA,IAAW,KAAK,aAAa,UAAU;AAAA,EACjE,OAAO;AAAA;AAIF,IAAM,eAAe,CAAC,UAAsC;AAAA,EACjE,MAAM,OAAmC,KAAK,MAAM,UAAU;AAAA,EAC9D,KAAK,WAAW,MAAM;AAAA,EACtB,KAAK,sBAAsB,CAAC,GAAG,MAAM,gBAAgB;AAAA,EACrD,MAAM,MAAM,MAAM,eAAe,CAAC;AAAA,EAClC,IAAI,OAAO,KAAK,GAAG,EAAE,SAAS;AAAA,IAAG,KAAK,0BAA0B,KAAK,IAAI;AAAA,EACzE,IAAI,MAAM,cAAc;AAAA,IAAW,KAAK,eAAe,MAAM;AAAA,EAC7D,IAAI,MAAM,cAAc;AAAA,IAAW,KAAK,eAAe,eAAe,MAAM,SAAS;AAAA,EACrF,IAAI,MAAM,kBAAkB;AAAA,IAAW,KAAK,mBAAmB,MAAM;AAAA,EACrE,MAAM,WAAW,MAAM;AAAA,EACvB,IAAI,aAAa,WAAW;AAAA,IAC1B,KAAK,2BAA2B,MAAM,QAAQ,QAAQ,IACjD,SAAyC,IAAI,YAAY,IAC1D,aAAa,QAA4B;AAAA,EAC/C;AAAA,EACA,IAAI,MAAM,qBAAqB;AAAA,IAAW,KAAK,sBAAsB,MAAM;AAAA,EAC3E,IAAI,MAAM,oBAAoB;AAAA,IAAW,KAAK,qBAAqB,MAAM;AAAA,EACzE,IAAI,MAAM,sBAAsB;AAAA,IAAW,KAAK,uBAAuB,MAAM;AAAA,EAC7E,IAAI,MAAM,qBAAqB;AAAA,IAAW,KAAK,sBAAsB,MAAM;AAAA,EAC3E,IAAI,MAAM,aAAa;AAAA,IAAW,KAAK,cAAc,MAAM;AAAA,EAC3D,IAAI,MAAM,cAAc;AAAA,IAAW,KAAK,eAAe,MAAM;AAAA,EAC7D,OAAO;AAAA;AAGF,IAAM,YAAY,CAAC,UACxB,WAAW,QAAQ,EAAE,OAAO,KAAK,EAAE,OAAO,KAAK;AAG1C,IAAM,YAAY,CACvB,UACwD;AAAA,EACxD,MAAM,OAAO,YAAY,aAAa,KAAK,CAAC;AAAA,EAC5C,MAAM,QAAQ,IAAI,YAAY,EAAE,OAAO,IAAI;AAAA,EAC3C,OAAO,EAAE,OAAO,QAAQ,UAAU,KAAK,GAAG,KAAK;AAAA;;;AExJ1C,IAAM,kBAAkB;AAE/B,IAAM,SAAS,CAAC,SAAqB;AAAA,EACnC,MAAM,UAAU,KAAK,WAAW;AAAA,EAChC,OAAO;AAAA,IACL,OAAO,GAAG,iBAAiB,KAAK;AAAA,IAChC,KAAK,GAAG,eAAe,KAAK;AAAA,EAC9B;AAAA;AAGK,IAAM,iBAAiB,CAAC,SAA+B;AAAA,EAC5D,MAAM,QAAkB,CAAC;AAAA,EACzB,MAAM,UAAU,KAAK,WAAW;AAAA,EAChC,IAAI,CAAC,YAAY,KAAK,OAAO,KAAK,QAAQ,SAAS,MAAQ,GAAG;AAAA,IAC5D,MAAM,KAAK,iDAAiD;AAAA,EAC9D;AAAA,EAGA,IAAI,CAAC,wCAAwC,KAAK,KAAK,IAAI,GAAG;AAAA,IAC5D,MAAM,KAAK,sEAAsE;AAAA,EACnF;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,UAAS,CAAC,YAA2B,IAAI,MAAM,mBAAmB,SAAS;AAEjF,IAAM,YAAY,CAAC,MAAc,IAAuB,SACtD,QACE,GAAG,YAAY,KAAK,UAAU,IAAI,YAAY,GAAG,IAAI,CAAC,UAAU,QAAQ,CAAC,EAAE,KAAK,IAAI,SAClF,mEACJ;AAGF,IAAM,SAAS,CAAC,OAA0B,SAAqB;AAAA,EAC7D,QAAQ,OAAO,QAAQ,OAAO,IAAI;AAAA,EAClC,MAAM,SAAS,MAAM,QAAQ,CAAC,MAAM,UAAW,SAAS,QAAQ,CAAC,KAAK,IAAI,CAAC,CAAE;AAAA,EAC7E,MAAM,OAAO,MAAM,QAAQ,CAAC,MAAM,UAAW,SAAS,MAAM,CAAC,KAAK,IAAI,CAAC,CAAE;AAAA,EACzE,IAAI,OAAO,SAAS;AAAA,IAAG,MAAM,UAAU,qBAAqB,QAAQ,KAAK;AAAA,EACzE,IAAI,KAAK,SAAS;AAAA,IAAG,MAAM,UAAU,mBAAmB,MAAM,GAAG;AAAA,EACjE,OAAO,QAAQ;AAAA,EACf,OAAO,MAAM;AAAA,EACb,IAAI,SAAS,aAAa,OAAO;AAAA,IAAW;AAAA,EAC5C,IAAI,SAAS,aAAa,OAAO,WAAW;AAAA,IAC1C,MAAM,QACJ,GAAG,KAAK,UAAU,KAAK,IAAI,WAAW,SAAS,YAAY,QAAQ,2BACjE,+EACJ;AAAA,EACF;AAAA,EACA,IAAI,KAAK;AAAA,IAAM,MAAM,QAAO,GAAG,KAAK,UAAU,KAAK,IAAI,uCAAuC;AAAA,EAC9F,OAAO,EAAE,MAAM,GAAG;AAAA;AASb,IAAM,eAAe,CAAC,MAAc,MAAkB,SAAyB;AAAA,EACpF,QAAQ,OAAO,QAAQ,OAAO,IAAI;AAAA,EAElC,MAAM,QAAQ,CAAC,OAAO,GAAI,SAAS,KAAK,CAAC,IAAI,KAAK,QAAQ,OAAO,EAAE,EAAE,MAAM;AAAA,CAAI,GAAI,GAAG;AAAA,EACtF,MAAM,QAAQ,KAAK,MAAM;AAAA,CAAI;AAAA,EAC7B,MAAM,QAAQ,OAAO,OAAO,IAAI;AAAA,EAChC,IAAI,UAAU,WAAW;AAAA,IACvB,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG,GAAG,OAAO,GAAG,MAAM,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,KAAK;AAAA,CAAI;AAAA,EAC1F;AAAA,EACA,MAAM,SAAS,SAAS,MAAM,KAAK,SAAS;AAAA,CAAI,IAAI,OAAO,GAAG;AAAA;AAAA,EAC9D,OAAO,GAAG,SAAS,MAAM,KAAK;AAAA,CAAI;AAAA;AAAA;AAI7B,IAAM,aAAa,CAAC,MAAc,SAAyC;AAAA,EAChF,MAAM,QAAQ,KAAK,MAAM;AAAA,CAAI;AAAA,EAC7B,MAAM,QAAQ,OAAO,OAAO,IAAI;AAAA,EAChC,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,MAAM,OAAO,MAAM,MAAM,MAAM,OAAO,GAAG,MAAM,EAAE;AAAA,EACjD,OAAO,KAAK,WAAW,IAAI,KAAK,GAAG,KAAK,KAAK;AAAA,CAAI;AAAA;AAAA;AAS5C,IAAM,eAAe,CAAC,MAAc,SAA6B;AAAA,EACtE,MAAM,QAAQ,KAAK,MAAM;AAAA,CAAI;AAAA,EAC7B,MAAM,QAAQ,OAAO,OAAO,IAAI;AAAA,EAChC,IAAI,UAAU;AAAA,IAAW,OAAO;AAAA,EAChC,OAAO,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,IAAI,GAAG,GAAG,MAAM,MAAM,MAAM,KAAK,CAAC,CAAC,EAAE,KAAK;AAAA,CAAI;AAAA;;;ACvDzE,IAAM,gBAAe;AAE5B,IAAM,oBAAmB,CAAC,MAAc,UAAiD;AAAA,EACvF,IAAI,UAAU;AAAA,IAAW,OAAO,CAAC;AAAA,EACjC,IAAI,OAAO,UAAU,UAAU;AAAA,IAC7B,OAAO,OAAO,cAAc,KAAK,KAAK,SAAS,IAC3C,CAAC,IACD,CAAC,GAAG,wCAAwC;AAAA,EAClD;AAAA,EACA,OAAO,6BAA6B,KAAK,KAAK,KAAK,QAAQ,KAAK,KAAK,IACjE,CAAC,IACD,CAAC,GAAG,QAAQ,KAAK,UAAU,KAAK,qCAAqC;AAAA;AAGpE,IAAM,gBAAe,CAAC,UAAqC;AAAA,EAChE,MAAM,QAAQ,aAAa,MAAM,IAAI;AAAA,EACrC,MAAM,OAAO,MAAM,QAAQ;AAAA,EAC3B,IAAI,CAAC,OAAO,cAAc,IAAI,KAAK,OAAO,KAAK,OAAO;AAAA,IAAQ,MAAM,KAAK,uBAAuB;AAAA,EAChG,MAAM,KAAK,GAAG,kBAAiB,SAAS,MAAM,KAAK,CAAC;AAAA,EACpD,MAAM,KAAK,GAAG,kBAAiB,SAAS,MAAM,KAAK,CAAC;AAAA,EACpD,MAAM,KAAK,GAAG,mBAAmB,MAAM,OAAO,CAAC;AAAA,EAC/C,IAAI,MAAM,WAAW,WAAW;AAAA,IAC9B,MAAM,KAAK,GAAG,eAAe,MAAM,MAAM,CAAC;AAAA,IAG1C,IAAI,MAAM,WAAW,SAAS,MAAM,SAAS,aAAa,MAAM,UAAU,YAAY;AAAA,MACpF,MAAM,KACJ,2FACF;AAAA,IACF;AAAA,EACF,EAAO,SAAI,MAAM,WAAW,MAAM;AAAA,IAChC,MAAM,KAAK,kFAAkF;AAAA,EAC/F;AAAA,EACA,OAAO;AAAA;;;AC5EF,IAAM,UAAU,IAAI;AACpB,IAAM,UAAU,IAAI;AAEpB,IAAM,UAAS,CAAC,MAAc,YACnC,IAAI,MAAM,eAAe,SAAS,SAAS;AAE7C,IAAM,aAAY,CAAC,UACjB,OAAO,UAAU,WAAW,QAAQ,QAAQ,KAAK,KAAK,IAAI,OAAO,KAAK,IAAI;AAKrE,IAAM,WAAW,OAAO,QAAoB,UAA8C;AAAA,EAC/F,MAAM,QAAQ,cAAa,KAAK;AAAA,EAChC,IAAI,MAAM,SAAS;AAAA,IAAG,MAAM,QAAO,MAAM,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA,EAC/D,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,MAAM,WAAU,MAAM,KAAK,MAAM,MAAM,OAAO,WAAW,OAAO,MAAM,KAAK,CAAC,IAAI;AAAA,IAChF,IAAI,QAAQ;AAAA,MAAW,MAAM,QAAO,MAAM,MAAM,WAAW,OAAO,MAAM,KAAK,gBAAgB;AAAA,EAC/F;AAAA,EACA,IAAI,MAAM,UAAU,WAAW;AAAA,IAC7B,MAAM,WAAU,MAAM,KAAK,KAAM,MAAM,OAAO,YAAY,OAAO,MAAM,KAAK,CAAC;AAAA,IAC7E,IAAI,QAAQ;AAAA,MAAW,MAAM,QAAO,MAAM,MAAM,YAAY,OAAO,MAAM,KAAK,gBAAgB;AAAA,EAChG;AAAA,EACA,OAAO,KAAM,QAAQ,YAAY,CAAC,IAAI,EAAE,IAAI,MAAQ,QAAQ,YAAY,CAAC,IAAI,EAAE,IAAI,EAAG;AAAA;AAGjF,IAAM,WAAW,CAAC,SAAyB,UAAU,QAAQ,OAAO,IAAI,CAAC;AAGzE,IAAM,cAAc,CACzB,MACA,WACuB;AAAA,EACvB,IAAI,SAAS;AAAA,IAAW;AAAA,EACxB,IAAI,WAAW;AAAA,IAAW,OAAO,SAAS,IAAI;AAAA,EAC9C,MAAM,OAAO,WAAW,MAAM,MAAM;AAAA,EACpC,OAAO,SAAS,YAAY,YAAY,SAAS,IAAI;AAAA;AAIhD,IAAM,qBAAqB,OAChC,QACA,MACA,WAC8C;AAAA,EAC9C,MAAM,OAAO,MAAM,OAAO,KAAK,IAAI;AAAA,EACnC,IAAI,SAAS;AAAA,IAAW;AAAA,EACxB,MAAM,QAAQ,KAAK,SAAS,SAAS,MAAM,OAAO,SAAS,IAAI,IAAI;AAAA,EACnE,MAAM,OAAO,UAAU,YAAY,YAAY,QAAQ,OAAO,KAAK;AAAA,EACnE,OAAO;AAAA,IACL,eAAe,YAAY,MAAM,MAAM,KAAK;AAAA,IAC5C,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,IACX;AAAA,OACI,WAAW,YAAY,CAAC,IAAI,EAAE,OAAO;AAAA,IACzC,QAAQ,UAAU,YAAY,KAAK,UAAU,KAAK;AAAA,IAClD,MAAM,KAAK;AAAA,IACX,KAAK,KAAK;AAAA,EACZ;AAAA;AAGF,IAAM,UAAU,CAAC,MAA4B,UAC3C,SAAS,aACT,KAAK,SAAS,MAAM,SACnB,MAAM,QAAQ,aAAa,KAAK,QAAQ,MAAM,SAC9C,MAAM,QAAQ,aAAa,KAAK,QAAQ,MAAM;AAiB1C,IAAM,YAAY,OACvB,QACA,OACA,SACkB;AAAA,EAClB,MAAM,OAAO,MAAM,OAAO,KAAK,MAAM,IAAI;AAAA,EACzC,IAAI,SAAS,aAAa,KAAK,SAAS,QAAQ;AAAA,IAC9C,MAAM,QACJ,MAAM,MACN,QAAQ,KAAK,gEACf;AAAA,EACF;AAAA,EACA,MAAM,UAAU,SAAS,YAAY,YAAY,MAAM,OAAO,SAAS,MAAM,IAAI;AAAA,EACjF,MAAM,SAAS,YAAY,YAAY,YAAY,QAAQ,OAAO,OAAO;AAAA,EACzE,MAAM,eAAe,MAAM,QAAQ;AAAA,EACnC,IAAI,MAAM,WAAW,WAAW;AAAA,IAC9B,MAAM,QAAsB,EAAE,MAAM,iBAAiB,KAAK;AAAA,IAC1D,OAAO;AAAA,MACL;AAAA,MACA,OAAO,QAAQ,OAAO,MAAM,OAAO;AAAA,MACnC,WAAW,WAAW,MAAM,WAAW,QAAQ,MAAM,KAAK;AAAA,MAC1D;AAAA,IACF;AAAA,EACF;AAAA,EACA,IAAI,WAAW,WAAW;AAAA,IACxB,IAAI,MAAM,WAAW,MAAM;AAAA,MACzB,MAAM,QACJ,MAAM,MACN,0FACE,sDACJ;AAAA,IACF;AAAA,IACA,OAAO;AAAA,MACL;AAAA,MACA,OAAO,QAAQ,OAAO,aAAa,IAAI,MAAM,QAAQ,MAAM,OAAO,CAAC;AAAA,MACnE,WAAW;AAAA,MACX,OAAO,EAAE,MAAM,iBAAiB,KAAK;AAAA,IACvC;AAAA,EACF;AAAA,EACA,MAAM,OAAO,aAAa,QAAQ,MAAM,QAAQ,MAAM,OAAO;AAAA,EAM7D,OAAO;AAAA,IACL;AAAA,IACA,OAAO,QAAQ,OAAO,IAAI;AAAA,IAC1B,WAAW,SAAS;AAAA,IACpB,OAAO,EAAE,KAAK,MAAM,OAAO,GAAG,MAAM,MAAM,QAAQ,cAAc,KAAK,MAAM,OAAO,EAAE;AAAA,EACtF;AAAA;;;AClHK,IAAM,WAAW,OACtB,QACA,MACA,WACkB;AAAA,EAClB,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI;AAAA,EACxC,IAAI,KAAK,SAAS,OAAO,MAAM;AAAA,IAE7B,MAAM,OAAO,aAAa,KAAK,MAAM,EAAE,MAAM,KAAK,QAAQ,kBAAiB,KAAK,CAAC;AAAA,IACjF,OAAO,EAAE,QAAQ,UAAU;AAAA,EAC7B;AAAA,EACA,MAAM,UAAU,MAAM,UAAU,QAAQ,MAAM,IAAI;AAAA,EAGlD,IAAI,QAAQ,aAAa,OAAO,kBAAkB,SAAS,KAAK,OAAO,GAAG;AAAA,IACxE,OAAO,EAAE,QAAQ,OAAO;AAAA,EAC1B;AAAA,EACA,MAAM,OAAO,aAAa,KAAK,MAAM,QAAQ,KAAK;AAAA,EAClD,OAAO,EAAE,QAAQ,SAAS;AAAA;AAWrB,IAAM,gBAAgB,OAC3B,QACA,OACA,QACA,QAAQ,UAC0B;AAAA,EAClC,MAAM,OAAO,MAAM,SAAS,QAAQ,KAAK;AAAA,EAEzC,IAAI,KAAK,QAAQ,aAAa,KAAK,QAAQ,OAAO,aAAa,KAAK,CAAC,aAAa,MAAM,GAAG;AAAA,IACzF,MAAM,QACJ,MAAM,MACN,SAAS,OAAO,MAAM,KAAK,sEACzB,uFACJ;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,WAAW,aAAa,OAAO,SAAS,MAAM;AAAA,EAC5D,MAAM,QAAQ,QAAQ,YAAY;AAAA,EAClC,MAAM,UAAU,MAAM,UAAU,QAAQ,OAAO,IAAI;AAAA,EACnD,MAAM,OAAO,YAAY,QAAQ,QAAQ,MAAM,MAAM;AAAA,EACrD,MAAM,WAAW,SAAS,MAAM,OAAO;AAAA,EAOvC,IACE,UAAU,aACV,SAAS,aACT,SAAS,YACT,EAAE,SAAS,WAAW,YACtB;AAAA,IACA,MAAM,QACJ,MAAM,MACN,GAAG,MAAM,WAAW,YAAY,mBAAmB,0CACjD,2FACJ;AAAA,EACF;AAAA,EACA,IAAI,CAAC,QAAQ;AAAA,IAAW,MAAM,OAAO,gBAAgB,MAAM,MAAM,QAAQ,OAAO,QAAQ,KAAK;AAAA,EAK7F,MAAM,QAAQ,MAAM,mBAAmB,QAAQ,MAAM,MAAM,MAAM,MAAM;AAAA,EACvE,IACE,UAAU,aACV,MAAM,WAAW,UAAU,QAAQ,KAAK,KACxC,MAAM,kBAAkB,UACxB;AAAA,IAMA,IAAI,QAAQ,WAAW,aAAa,MAAM,WAAW,WAAW;AAAA,MAC9D,MAAM,OAAO,WAAW,MAAM,IAAI,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,IAC3D;AAAA,IACA,MAAM,QACJ,MAAM,MACN,wEACF;AAAA,EACF;AAAA,EAGA,IAAI,SAAS,WAAW;AAAA,IAAW,MAAM,WAAW,QAAQ,MAAM;AAAA,EAClE,OAAO;AAAA;AAOF,IAAM,aAAa,OACxB,QACA,WACkB;AAAA,EAClB,MAAM,OAAO,MAAM,OAAO,KAAK,OAAO,IAAI;AAAA,EAC1C,IAAI,SAAS;AAAA,IAAW;AAAA,EACxB,IAAI,KAAK,SAAS;AAAA,IAAQ,MAAM,QAAO,OAAO,MAAM,YAAY,KAAK,uBAAuB;AAAA,EAC5F,IAAI,OAAO,WAAW,WAAW;AAAA,IAC/B,MAAM,OAAO,WAAW,OAAO,IAAI;AAAA,IACnC;AAAA,EACF;AAAA,EACA,MAAM,QAAQ,MAAM,OAAO,SAAS,OAAO,IAAI;AAAA,EAC/C,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,MAAM,SAAS,QAAQ,OAAO,KAAK;AAAA,EACnC,MAAM,OAAO,aAAa,QAAQ,OAAO,MAAM;AAAA,EAC/C,IAAI,SAAS;AAAA,IAAQ;AAAA,EACrB,MAAM,OAAO,gBAAgB,OAAO,MAAM,QAAQ,OAAO,IAAI,GAAG;AAAA,IAC9D,KAAK,KAAK;AAAA,IACV,MAAM,KAAK;AAAA,IACX,KAAK,KAAK;AAAA,EACZ,CAAC;AAAA;;;ANpHI,IAAM,aAAa,UAAqB,aAAa;AAErD,IAAM,qBAAqB,MACvB,iBACP,YACO,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,SAAS,OAAO;AAAA,EACtB,OAAO,WAAW,SAAS,GAAG;AAAA,IAE5B,MAAM,MAAa,gBAAQ,CAAC,CAAC;AAAA,IAE7B,MAAM,GAAG,MAAM,aACb,KAAK,YAAY;AAAA,MACf,MAAM,QAAQ,MAAM,mBAAmB,QAAQ,KAAK,MAAM,KAAK,MAAM;AAAA,MACrE,IAAI,UAAU;AAAA,QAAW;AAAA,MAIzB,IAAI,KAAK,WAAW,aAAa,MAAM,kBAAkB;AAAA,QAAI;AAAA,MAC7D,OAAO,WAAW,YAAY,SAAQ,KAAK,IAAI;AAAA,KAChD;AAAA,IAEH,MAAM,GAAG,YAAY,MAAM,aAAa;AAAA,MAEtC,IAAI,WAAW;AAAA,QAAW,OAAO,eAAe,UAAU;AAAA,MAC1D,IAAI,YAAW,IAAI;AAAA,QAAG,OAAO,KAAK,MAAM,SAAS,QAAQ,MAAM,MAAM,CAAC;AAAA,MAItE,MAAM,OAAO,eAAe,MAAM,MAAM;AAAA,MACxC,OAAc,gBACZ,SAAS,aAAa,SAAS,OAAO,OAAO,EAAE,QAAQ,UAAmB,IAAI,SAChF;AAAA;AAAA,IAIF,WAAW,GAAG,KAAK,YAAY,MAAM,aAC5B,gBAAQ,cAAc,EAAE,KAAK,YAAY,OAAO,CAAC,GAAG,CAAC,UAC1D,KAAK,MAAM,cAAc,QAAQ,MAAM,QAAQ,KAAK,CAAC,CACvD;AAAA,IAEF,QAAQ,GAAG,aAAa,KAAK,MAAM,WAAW,QAAQ,MAAM,CAAC;AAAA,EAC/D,CAAC;AAAA,CACF,CACH;;;AOlEF,qBAAS;AACT;AACA;;;ACfA,oBAAS;AAET,uBAAS;AAET;;;ACoDO,IAAM,yBAAyB;AAW/B,IAAM,0BAA0B;AAAA,EACrC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAGO,IAAM,aAAa,EAAE,KAAK,GAAG,MAAM,KAAO,KAAK,EAAE;AAEjD,IAAM,YAAW,CAAC,SAAyB,UAAU,IAAI,YAAY,EAAE,OAAO,IAAI,CAAC;AAGnF,IAAM,eAAe,CAAC,cAC3B,WAAU,aAAa,CAAC,GAAG,KAAK;AAAA,CAAI,CAAC;AAGhC,IAAM,aAAa,CAAC,aACzB,GAAG,SACA,IAAI,CAAC,YACJ,CAAC,IAAI,QAAQ,SAAS,GAAG,QAAQ,MAAM,IAAI,EAAE,KAAK,WAAW,GAAG,OAAO,OAAO,CAAC,EAAE,KAAK;AAAA,CAAI,CAC5F,EACC,KAAK;AAAA;AAAA,CAAM;AAAA;AAET,IAAM,WAAW,CAAC,UACvB,MAAM,WAAW,WAAW,MAAM,YAAY,CAAC,CAAC;AAE3C,IAAM,cAAc,CAAC,UAC1B,GAAG,MAAM,aAAa,0BAA0B,MAAM;AAExD,IAAM,OAAO;AAEb,IAAM,QAAQ,IAAI,IAAI;AAAA,EACpB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAED,IAAM,eAAe,IAAI,IAAI,CAAC,YAAY,cAAc,cAAc,QAAQ,OAAO,CAAC;AAU/E,IAAM,eAAe,CAAC,OAAyB,WAA8B;AAAA,EAClF,MAAM,QAAkB,CAAC;AAAA,EACzB,MAAM,OAAO,KAAK,KAAK,MAAM,IAAI,IAAI;AAAA,EACrC,IAAI,SAAS,aAAa,CAAC,MAAM,IAAI,IAAI,GAAG;AAAA,IAC1C,MAAM,KACJ,4DAA4D,KAAK,UAAU,MAAM,IAAI,GACvF;AAAA,EACF,EAAO,SAAI,WAAW,aAAa,SAAS,QAAQ;AAAA,IAClD,MAAM,KAAK,6BAA6B,gBAAgB,MAAM,cAAc,MAAM;AAAA,EACpF;AAAA,EACA,IAAK,MAAM,YAAY,eAAgB,MAAM,aAAa,YAAY;AAAA,IACpE,MAAM,KAAK,4CAA4C;AAAA,EACzD;AAAA,EACA,MAAM,YAAY,MAAM,aAAa;AAAA,EACrC,IAAI,CAAC,UAAU,WAAW,GAAG,KAAK,UAAU,SAAS,GAAG,KAAK,UAAU,SAAS,KAAK,GAAG;AAAA,IACtF,MAAM,KAAK,uEAAuE;AAAA,EACpF;AAAA,EACA,MAAM,KAAK,GAAG,aAAa,SAAS,KAAK,CAAC,CAAC;AAAA,EAC3C,IAAI,MAAM,YAAY,SAAS,CAAC,wBAAwB,SAAS,SAAkB,GAAG;AAAA,IACpF,MAAM,KACJ,iEAAiE,wBAAwB,KAAK,IAAI,SAChG,GAAG,mEACP;AAAA,EACF;AAAA,EACA,IAAI,MAAM,YAAY,SAAS,CAAC,WAAW,KAAK,GAAG;AAAA,IACjD,MAAM,KACJ,8FACE,6FACA,2DACJ;AAAA,EACF;AAAA,EACA,IAAI,SAAS,WAAW,CAAC,SAAS,KAAK,EAAE,SAAS,SAAS,GAAG;AAAA,IAC5D,MAAM,KAAK,kCAAkC;AAAA,EAC/C;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,aAAa,CAAC,UAAqC;AAAA,EACvD,MAAM,OAAO,SAAS,KAAK;AAAA,EAC3B,IAAI,CAAC,KAAK,SAAS,WAAW;AAAA,IAAG,OAAO;AAAA,EACxC,MAAM,QAAQ,KAAK,MAAM,KAAK,QAAQ,WAAW,CAAC;AAAA,EAClD,OAAO,CAAC,GAAG,YAAY,EAAE,KAAK,CAAC,QAAQ,IAAI,OAAO,IAAI,QAAQ,GAAG,EAAE,KAAK,KAAK,CAAC;AAAA;AAGhF,IAAM,eAAe,CAAC,SAA2B;AAAA,EAC/C,MAAM,QAAkB,CAAC;AAAA,EACzB,IAAI,KAAK,KAAK,MAAM;AAAA,IAAI,MAAM,KAAK,wBAAwB;AAAA,EAC3D,IAAI,KAAK,SAAS,MAAQ;AAAA,IAAG,MAAM,KAAK,4BAA4B;AAAA,EACpE,IAAI,CAAC,mBAAmB,KAAK,IAAI;AAAA,IAAG,MAAM,KAAK,yCAAyC;AAAA,EACxF,OAAO;AAAA;;;ACtJF,IAAM,YAAY;AAGlB,IAAM,kBAAkB;AAAA,EAC7B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAAA;AAEO,MAAM,uBAAuB,MAAM;AAAA,EACxC,WAAW,CAAC,SAAiB,UAAkB,QAAgB;AAAA,IAC7D,MAAM,aAAa,cAAc,OAAO,QAAQ,MAAM,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,GAAG;AAAA,IACnF,KAAK,OAAO;AAAA;AAEhB;AAkBO,IAAM,YAAY,CAAC,WAAwC;AAAA,EAChE,MAAM,SAAS,IAAI;AAAA,EACnB,WAAW,QAAQ,OAAO,MAAM;AAAA,CAAI,GAAG;AAAA,IACrC,MAAM,KAAK,KAAK,QAAQ,GAAG;AAAA,IAC3B,IAAI,MAAM;AAAA,MAAG;AAAA,IACb,MAAM,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,IAC5B,IAAI,CAAC,OAAO,IAAI,GAAG;AAAA,MAAG,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC,CAAC;AAAA,EAC1D;AAAA,EACA,OAAO;AAAA;AAGF,IAAM,WAAW,CAAC,WAA+B;AAAA,EACtD,MAAM,SAAS,UAAU,MAAM;AAAA,EAC/B,MAAM,YAAY,OAAO,IAAI,WAAW,KAAK;AAAA,EAC7C,MAAM,gBAAgB,OAAO,IAAI,eAAe,KAAK;AAAA,EACrD,MAAM,eAAe,OAAO,IAAI,cAAc,KAAK;AAAA,EACnD,MAAM,WAAW,OAAO,IAAI,UAAU,KAAK;AAAA,EAC3C,OAAO;AAAA,IACL,aAAa,OAAO,IAAI,aAAa,KAAK;AAAA,IAG1C,OAAO,cAAc,eAAe,kBAAkB;AAAA,IACtD;AAAA,IACA,kBAAkB,OAAO,IAAI,kBAAkB,MAAM;AAAA,OACjD,aAAa,KAAK,CAAC,IAAI,EAAE,SAAS;AAAA,OAClC,kBAAkB,KAAK,CAAC,IAAI,EAAE,cAAc;AAAA,OAC5C,iBAAiB,KAAK,CAAC,IAAI,EAAE,aAAa;AAAA,EAChD;AAAA;AAGK,IAAM,WAAW,OAAO,QAAoB,SAAsC;AAAA,EACvF,MAAM,SAAS,MAAM,OAAO,KAAK;AAAA,IAC/B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,gBAAgB,KAAK,GAAG;AAAA,IACxB;AAAA,IACA;AAAA,EACF,CAAC;AAAA,EAID,IAAI,OAAO,aAAa;AAAA,IACtB,MAAM,IAAI,eAAe,QAAQ,QAAQ,OAAO,UAAU,OAAO,MAAM;AAAA,EACzE,OAAO,SAAS,OAAO,MAAM;AAAA;AAI/B,IAAM,MAAM,OAAO,QAAoB,SAA2C;AAAA,EAChF,MAAM,SAAS,MAAM,OAAO,KAAK,CAAC,WAAW,GAAG,IAAI,CAAC;AAAA,EACrD,IAAI,OAAO,aAAa,GAAG;AAAA,IACzB,MAAM,IAAI,eAAe,KAAK,KAAK,GAAG,GAAG,OAAO,UAAU,OAAO,MAAM;AAAA,EACzE;AAAA;AAIK,IAAM,eAAe,CAAC,WAAsC,IAAI,QAAQ,CAAC,eAAe,CAAC;AAEzF,IAAM,aAAa,CAAC,QAAoB,SAC7C,IAAI,QAAQ,CAAC,UAAU,MAAM,IAAI,CAAC;AAE7B,IAAM,cAAc,CAAC,QAAoB,SAC9C,IAAI,QAAQ,CAAC,WAAW,MAAM,IAAI,CAAC;AAE9B,IAAM,YAAY,CAAC,QAAoB,SAC5C,IAAI,QAAQ,CAAC,SAAS,MAAM,IAAI,CAAC;AAE5B,IAAM,WAAW,CAAC,QAAoB,SAC3C,IAAI,QAAQ,CAAC,QAAQ,MAAM,IAAI,CAAC;AAO3B,IAAM,cAAc,CAAC,QAAoB,SAC9C,IAAI,QAAQ,CAAC,WAAW,MAAM,IAAI,CAAC;;;ACpH9B,IAAM,UAAS,CAAC,MAAc,YACnC,IAAI,MAAM,gBAAgB,SAAS,SAAS;AAEvC,IAAM,eAAe,CAC1B,OACA,YACA,YAC2B;AAAA,EAC3B,QAAQ,OAAO,gBAAgB,YAAY,OAAO,gBAAgB;AAAA,EAClE,aAAa,OAAO;AAAA,EACpB,cAAc,aAAa,MAAM,SAAS;AAAA,EAC1C,SAAS,OAAO,kBAAkB,aAAa,OAAO,kBAAkB;AAAA,EACxE,WAAW,OAAO;AAAA,EAClB,MAAM,MAAM;AAAA,EACZ,UAAU,YAAY,KAAK;AAAA,EAC3B;AAAA,KACI,OAAO,kBAAkB,YAAY,CAAC,IAAI,EAAE,eAAe,OAAO,cAAc;AACtF;AAiBO,IAAM,SAAS,OACpB,QACA,OACA,SACmC;AAAA,EACnC,MAAM,cAAc,MAAM,YAAY;AAAA,EACtC,MAAM,cAAc,MAAM,YAAY;AAAA,EACtC,MAAM,YACJ,KAAK,OAAO,kBAAkB,aAAa,KAAK,OAAO,kBAAkB;AAAA,EAC3E,MAAM,OAAO,OAAO,WAAmC;AAAA,IAGrD,IAAI,KAAK,WAAW,WAAW;AAAA,MAC7B,MAAM,OAAO,WAAW,KAAK,IAAI,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,MACxD,MAAM,aAAa,MAAM,EAAE,MAAM,MAAG;AAAA,QAAG;AAAA,OAAS;AAAA,IAClD;AAAA,IACA,MAAM,QAAO,MAAM,MAAM,GAAG,iCAAiC;AAAA;AAAA,EAE/D,IAAI;AAAA,IACF,IAAI,gBAAgB,CAAC,aAAa,KAAK;AAAA,MAAU,MAAM,WAAW,QAAQ,MAAM,IAAI;AAAA,IACpF,IAAI,CAAC,eAAe;AAAA,MAAW,MAAM,YAAY,QAAQ,MAAM,IAAI;AAAA,IACnE,MAAM,SAAS,KAAK,OAAO,gBAAgB,YAAY,KAAK,OAAO,gBAAgB;AAAA,IACnF,IAAI,CAAC,aAAa;AAAA,MAChB,IAAI;AAAA,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI;AAAA,IAC/C,EAAO,SAAI,CAAC;AAAA,MAAQ,MAAM,UAAU,QAAQ,MAAM,IAAI;AAAA,IACjD,SAAI,KAAK,WAAW,KAAK;AAAA,MAAe,MAAM,YAAY,QAAQ,MAAM,IAAI;AAAA,IACjF,OAAO,OAAO;AAAA,IACd,OAAO,KAAK,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK,CAAC;AAAA;AAAA,EAQpE,MAAM,QAAQ,MAAM,SAAS,QAAQ,MAAM,IAAI;AAAA,EAC/C,IAAI,eAAe,MAAM,gBAAgB,YAAY,MAAM,gBAAgB,cAAc;AAAA,IACvF,OAAO,KAAK,8CAA8C,MAAM,cAAc;AAAA,EAChF;AAAA,EACA,MAAM,UAAU,aAAa,OAAO,KAAK,SAAS,KAAK;AAAA,EACvD,IAAI,eAAe,CAAC,QAAQ,SAAS;AAAA,IACnC,OAAO,KACL,kEACE,GAAG,KAAK,UAAU,MAAM,iBAAiB,EAAE,iBAC/C;AAAA,EACF;AAAA,EACA,OAAO;AAAA;;;ACzET,IAAM,WAAU,IAAI;AACpB,IAAM,WAAU,IAAI;AAGb,IAAM,cAAc,CAAC,OAAyB,WAA0B;AAAA,EAC7E,MAAM,QAAQ,aAAa,OAAO,MAAM;AAAA,EACxC,IAAI,MAAM,SAAS;AAAA,IAAG,MAAM,QAAO,MAAM,MAAM,MAAM,KAAK,IAAI,CAAC;AAAA;AAI1D,IAAM,WAAW,OACtB,QACA,UAC+C;AAAA,EAC/C,MAAM,QAAQ,MAAM,OAAO,SAAS,YAAY,KAAK,CAAC;AAAA,EACtD,MAAM,SAAS,MAAM,SAAS,QAAQ,MAAM,IAAI;AAAA,EAChD,IAAI,UAAU,aAAa,CAAC,OAAO;AAAA,IAAO;AAAA,EAC1C,OAAO,aAAa,OAAO,UAAU,YAAY,KAAK,UAAS,SAAQ,OAAO,KAAK,CAAC,GAAG,MAAM;AAAA;AAIxF,IAAM,iBAAiB,CAAC,QAAoB,SAAuB;AAAA,EACxE,IAAI,aAAa,MAAM;AAAA,IAAG;AAAA,EAC1B,MAAM,QACJ,MACA,8FACE,6FACJ;AAAA;AAGF,IAAM,eAAe,CAAC,OAAyB,WAA6B;AAAA,EAC1E,IAAI,OAAO,cAAc,YAAY,OAAO,kBAAkB,UAAU;AAAA,IACtE,MAAM,QACJ,MAAM,MACN,6FACE,cACJ;AAAA,EACF;AAAA;AAGK,IAAM,WAAW,OACtB,QACA,MACA,QACA,WACkB;AAAA,EAClB,YAAY,MAAM,MAAM;AAAA,EAGxB,IAAI,KAAK,SAAS,OAAO,QAAQ,YAAY,IAAI,MAAM,OAAO,UAAU;AAAA,IACtE,eAAe,QAAQ,KAAK,IAAI;AAAA,IAChC,OAAO,EAAE,QAAQ,WAAW,aAAa,KAAK;AAAA,EAChD;AAAA,EACA,MAAM,WAAU,UAAS,SAAS,IAAI,CAAC;AAAA,EACvC,MAAM,SAAS,YAA2B;AAAA,IACxC,eAAe,QAAQ,KAAK,IAAI;AAAA,IAChC,MAAM,OAAO,aAAa,YAAY,IAAI,GAAG,UAAU;AAAA,IACvD,OAAO,EAAE,QAAQ,SAAS;AAAA;AAAA,EAI5B,IAAI,aAAY,OAAO;AAAA,IAAY,OAAO,OAAO;AAAA,EACjD,IAAI,aAAa,KAAK,SAAS,MAAM,OAAO;AAAA,IAAc,OAAO,OAAO;AAAA,EACxE,MAAM,OAAO,MAAM,SAAS,QAAQ,IAAI;AAAA,EACxC,IAAI,SAAS,aAAa,KAAK,eAAe;AAAA,IAAS,OAAO,OAAO;AAAA,EACrE,IAAI,KAAK,aAAa,KAAK,YAAY;AAAA,IAAQ,OAAO,OAAO;AAAA,EAC7D,IAAI,KAAK,YAAY,KAAK,YAAY;AAAA,IAAQ,OAAO,OAAO;AAAA,EAG5D,MAAM,SAAS,MAAM,SAAS,QAAQ,KAAK,IAAI;AAAA,EAC/C,OAAO,OAAO,mBAAmB,OAAO,IAAI,EAAE,QAAQ,OAAO;AAAA;AASxD,IAAM,gBAAgB,OAC3B,QACA,OACA,QACA,QAAQ,OACR,WACmC;AAAA,EACnC,YAAY,OAAO,MAAM;AAAA,EACzB,eAAe,QAAQ,MAAM,IAAI;AAAA,EACjC,MAAM,OAAO,YAAY,KAAK;AAAA,EAC9B,MAAM,SAAS,MAAM,SAAS,QAAQ,MAAM,IAAI;AAAA,EAChD,aAAa,OAAO,MAAM;AAAA,EAC1B,MAAM,OAAO,SAAS,KAAK;AAAA,EAC3B,MAAM,WAAU,UAAS,IAAI;AAAA,EAC7B,MAAM,SAAS,MAAM,OAAO,SAAS,IAAI;AAAA,EACzC,MAAM,UAAU,WAAW,YAAY,YAAY,UAAS,SAAQ,OAAO,MAAM,CAAC;AAAA,EAClF,MAAM,QAAQ,WAAW,cAAc,OAAO,SAAS,MAAM,QAAQ,OAAO,aAAa;AAAA,EACzF,MAAM,QAAQ,QAAQ,YAAY;AAAA,EAOlC,IACE,UAAU,aACV,EAAE,SAAS,WAAW,cACtB,YAAY,aACZ,YAAY,UACZ;AAAA,IACA,MAAM,QACJ,MAAM,MACN,GAAG,0FACD,uCACJ;AAAA,EACF;AAAA,EACA,IAAI,SAAS,WAAW;AAAA,IAAW,MAAM,WAAW,QAAQ,MAAM;AAAA,EAClE,MAAM,QAAQ,YAAY;AAAA,EAU1B,MAAM,QAAQ,UAAU,aAAa,MAAM,eAAe;AAAA,EAC1D,MAAM,gBAAgB,UAAU,aAAa,MAAM,iBAAiB,aAAa,MAAM,SAAS;AAAA,EAChG,IAAI;AAAA,IAAO,MAAM,OAAO,gBAAgB,MAAM,SAAQ,OAAO,IAAI,GAAG,UAAU;AAAA,EAC9E,IAAI,SAAS,OAAO;AAAA,IAAkB,MAAM,aAAa,MAAM;AAAA,EAC/D,MAAM,UAAU,SAAS,SAAS,OAAO;AAAA,EACzC,OAAO,OAAO,QAAQ,OAAO,EAAE,QAAQ,SAAS,eAAe,mBAAS,MAAM,OAAO,CAAC;AAAA;AAQjF,IAAM,aAAa,OACxB,QACA,WACkB;AAAA,EAClB,eAAe,QAAQ,OAAO,IAAI;AAAA,EAClC,MAAM,SAAS,MAAM,SAAS,QAAQ,OAAO,IAAI;AAAA,EACjD,IAAI,OAAO,gBAAgB,YAAY,OAAO,gBAAgB,cAAc;AAAA,IAC1E,MAAM,SAAS,QAAQ,OAAO,IAAI;AAAA,EACpC;AAAA,EACA,IAAI,OAAO,kBAAkB,aAAa,OAAO,kBAAkB,mBAAmB;AAAA,IACpF,MAAM,YAAY,QAAQ,OAAO,IAAI;AAAA,EACvC;AAAA,EACA,MAAM,OAAO,MAAM,OAAO,KAAK,OAAO,QAAQ;AAAA,EAC9C,IAAI,SAAS,WAAW;AAAA,IACtB,IAAI,KAAK,SAAS;AAAA,MAAQ,MAAM,QAAO,OAAO,MAAM,GAAG,OAAO,iBAAiB,KAAK,MAAM;AAAA,IAC1F,MAAM,OAAO,WAAW,OAAO,QAAQ;AAAA,EACzC;AAAA,EACA,MAAM,aAAa,MAAM;AAAA;;;AJ3KpB,IAAM,cAAc,CACzB,QACA,MACA,WAEA,KAAK,YAAY;AAAA,EACf,MAAM,QAAQ,MAAM,SAAS,QAAQ,IAAI;AAAA,EACzC,IAAI,UAAU;AAAA,IAAW;AAAA,EACzB,OAAO,WAAW,YAAY,SAAQ,KAAK,IAAI;AAAA,CAChD;AAEI,IAAM,cAAc,CACzB,QACA,YACA,MACA,QACA,WAC2C;AAAA,EAE3C,IAAI,WAAW;AAAA,IAAW,OAAO,eAAe,UAAU;AAAA,EAC1D,IAAI,YAAW,IAAI;AAAA,IAAG,OAAO,KAAK,MAAM,SAAS,QAAQ,MAAM,QAAQ,MAAM,CAAC;AAAA,EAO9E,MAAM,OAAO,eAAe,MAAM,MAAM;AAAA,EACxC,OAAc,gBACZ,SAAS,aAAa,SAAS,OAAO,OAClC,EAAE,QAAQ,WAAoB,aAAa,KAAK,IAChD,SACN;AAAA;AAGK,IAAM,mBAAmB,CAC9B,QACA,MAMA,WAEO,gBAAQ,cAAc,IAAI,GAAG,CAAC,UACnC,KAAK,MAAM,cAAc,QAAQ,KAAK,MAAM,KAAK,QAAQ,OAAO,MAAM,CAAC,CACzE;AAEK,IAAM,gBAAgB,CAC3B,QACA,WAC+B,KAAK,MAAM,WAAW,QAAQ,MAAM,CAAC;;;AD9B/D,IAAM,cAAc,UAAsB,cAAc;AACxD,IAAM,eAAe,UAAuB,eAAe;AAE3D,IAAM,sBAAsB,MACxB,iBACP,aACO,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,SAAS,OAAO;AAAA,EACtB,OAAO,YAAY,SAAS,GAAG;AAAA,IAM7B,MAAM,MAAa,gBAAQ,CAAC,CAAC;AAAA,IAC7B,MAAM,GAAG,MAAM,aAAa,YAAY,QAAQ,MAAM,MAAM;AAAA,IAC5D,MAAM,GAAG,YAAY,MAAM,aAAa,YAAY,QAAQ,YAAY,MAAM,MAAM;AAAA,IACpF,WAAW,CAAC,SAAS,iBAAiB,QAAQ,IAAI;AAAA,IAClD,QAAQ,GAAG,aAAa,cAAc,QAAQ,MAAM;AAAA,EACtD,CAAC;AAAA,CACF,CACH;AAEK,IAAM,uBAAuB,MACzB,iBACP,cACO,YAAI,UAAU,GAAG;AAAA,EACtB,MAAM,SAAS,OAAO;AAAA,EACtB,OAAO,aAAa,SAAS,GAAG;AAAA,IAC9B,MAAM,MAAa,gBAAQ,CAAC,CAAC;AAAA,IAC7B,MAAM,GAAG,MAAM,aAAa,YAAY,QAAQ,MAAM,MAAM;AAAA,IAE5D,MAAM,GAAG,YAAY,MAAM,aACzB,YAAY,QAAQ,YAAY,MAAM,QAAQ,OAAO;AAAA,IACvD,WAAW,CAAC,SAAS,iBAAiB,QAAQ,MAAM,OAAO;AAAA,IAC3D,QAAQ,GAAG,aAAa,cAAc,QAAQ,MAAM;AAAA,EACtD,CAAC;AAAA,CACF,CACH;;;AR7DK,IAAM,iBAAiB,CAAC,WACvB,gBACJ,sBAAsB,GACtB,mBAAmB,GACnB,qBAAqB,GACrB,oBAAoB,CACtB,EAAE,KAAW,eAAQ,gBAAgB,MAAM,CAAC,CAAC;;AcE/C;AACA;;;ACPA,IAAM,UAAU;AAGT,IAAM,YAAY,CAAC,UAAkB,aAC1C,aAAa,WACT;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,KAAK,QAAQ,IAAI,QAAQ;AAAA,EACjC;AACF,IACA,CAAC,UAAU,UAAU,QAAQ;AAG5B,IAAM,aAAa,CAAC,UAAkB,aAC3C,aAAa,WACT;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA,QAAQ,KAAK,QAAQ,IAAI,QAAQ;AAAA,EACjC;AACF,IACA,CAAC,UAAU,SAAS,QAAQ;AAGlC,IAAM,cAAc,CAAC,WAAwC;AAAA,EAC3D,MAAM,SAAS,IAAI;AAAA,EACnB,WAAW,QAAQ,OAAO,MAAM;AAAA,CAAI,GAAG;AAAA,IACrC,IAAI,KAAK,KAAK,MAAM,IAAI;AAAA,MACtB,IAAI,OAAO,OAAO;AAAA,QAAG;AAAA,MACrB;AAAA,IACF;AAAA,IACA,MAAM,KAAK,KAAK,QAAQ,IAAI;AAAA,IAC5B,IAAI,MAAM;AAAA,MAAG;AAAA,IACb,MAAM,MAAM,KAAK,MAAM,GAAG,EAAE;AAAA,IAC5B,IAAI,QAAQ;AAAA,MAAY;AAAA,IACxB,OAAO,IAAI,KAAK,KAAK,MAAM,KAAK,CAAC,EAAE,KAAK,CAAC;AAAA,EAC3C;AAAA,EACA,OAAO;AAAA;AAGT,IAAM,OAAO,CAAC,SACZ,SAAS,aAAa,QAAQ,KAAK,IAAI,IAAI,OAAO,IAAI,IAAI;AAErD,IAAM,YAAY,CAAC,UAAkB,WAAyC;AAAA,EACnF,IAAI,aAAa,UAAU;AAAA,IACzB,MAAM,SAAS,YAAY,MAAM;AAAA,IACjC,MAAM,OAAM,KAAK,OAAO,IAAI,KAAK,CAAC;AAAA,IAClC,MAAM,OAAM,KAAK,OAAO,IAAI,KAAK,CAAC;AAAA,IAClC,MAAM,QAAO,OAAO,IAAI,KAAK;AAAA,IAC7B,OAAO,SAAQ,aAAa,SAAQ,aAAa,UAAS,YACtD,YACA,EAAE,WAAK,aAAM,UAAI;AAAA,EACvB;AAAA,EAEA,MAAM,UAAU,OAAO,MAAM;AAAA,CAAI,EAAE,MAAM,IAAI,MAAM,GAAG;AAAA,EACtD,MAAM,MAAM,KAAK,OAAO,EAAE;AAAA,EAC1B,MAAM,MAAM,KAAK,OAAO,EAAE;AAAA,EAC1B,MAAM,OAAO,OAAO;AAAA,EACpB,OAAO,QAAQ,aAAa,QAAQ,aAAa,SAAS,aAAa,SAAS,KAC5E,YACA,EAAE,KAAK,MAAM,IAAI;AAAA;AAGhB,IAAM,aAAa,CAAC,UAAkB,WAAuC;AAAA,EAClF,IAAI,aAAa;AAAA,IAAU,OAAO,KAAK,YAAY,MAAM,EAAE,IAAI,KAAK,CAAC;AAAA,EAErE,OAAO,MAAM,OAAO,MAAM;AAAA,CAAI,EAAE,MAAM,IAAI,MAAM,GAAG,EAAE,EAAE;AAAA;;;ACtElD,IAAM,SAAS;AAMf,IAAM,aAAa,CAAC,QAAwB;AAAA,EACjD,IAAI,IAAI,SAAS,MAAM;AAAA,IAAG,MAAM,IAAI,MAAM,+BAA+B;AAAA,EACzE,OAAO,IAAI,IAAI,WAAW,KAAK,OAAO;AAAA;AAIjC,IAAM,YAAY,CAAC,SAAoC,KAAK,IAAI,UAAU,EAAE,KAAK,GAAG;AAE3F,IAAM,SAAS,CAAC,UAAkB,WAAW;AAetC,IAAM,cAAc,CAAC,QAAgB,UAC1C;AAAA,EAAM;AAAA;AAAA;AAAA,aAAkC,OAAO,KAAK;AAAA;AAU/C,IAAM,cAAc,CAAC,QAAgB,UAAsC;AAAA,EAChF,MAAM,KAAK,OAAO,YAAY;AAAA,EAAK,OAAO,KAAK,GAAG;AAAA,EAClD,IAAI,KAAK;AAAA,IAAG;AAAA,EACZ,MAAM,SAAS,aAAa,KAAK,OAAO,MAAM,KAAK,OAAO,KAAK,EAAE,SAAS,CAAC,CAAC;AAAA,EAC5E,IAAI,SAAS,OAAO;AAAA,IAAW;AAAA,EAC/B,OAAO,EAAE,UAAU,OAAO,OAAO,EAAE,GAAG,QAAQ,OAAO,MAAM,GAAG,EAAE,EAAE;AAAA;AAY7D,IAAM,UAAU,CACrB,MACA,QACA,YACsB;AAAA,EACtB,IAAI,SAAS,MAAM,KAAK,WAAW,GAAG,GAAG;AAAA,IACvC,MAAM,IAAI,MAAM,QAAQ,KAAK,UAAU,IAAI,+BAA+B;AAAA,EAC5E;AAAA,EACA,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA,kBAAkB,OAAO,QAAQ,iBAAiB;AAAA,IAClD,GAAI,QAAQ,WAAW,CAAC;AAAA,IACxB;AAAA,IACA,cAAc,WAAW,MAAM;AAAA,EACjC;AAAA;;;AC9EF,IAAM,aAAa,CAAC,SAAiB,WAAW,kBAAkB;AAE3D,IAAM,aAAa,CAAC,SAAyB;AAAA,EAClD,MAAM,SAAS,WAAW,IAAI;AAAA,EAC9B,OAAO,GAAG,WAAW,MAAM,iCAAiC,qBAAqB,OAAO,MAAM;AAAA;AAIzF,IAAM,aAAa,CAAC,SAAyB;AAAA,EAClD,MAAM,SAAS,WAAW,IAAI;AAAA,EAC9B,OAAO,GAAG,WAAW,MAAM,eAAe,qBAAqB,OAAO,MAAM;AAAA;AAKvE,IAAM,eAAe,CAAC,SAAyB,YAAY,WAAW,IAAI;AAE1E,IAAM,aAAa,CAAC,SAAoC,UAAU,IAAI;AAiBtE,IAAM,cAAc,CAAC,MAAc,MAAc,YAAkC;AAAA,EACxF,MAAM,SAAS,WAAW,IAAI;AAAA,EAC9B,MAAM,SAAS,WAAW,IAAI;AAAA,EAC9B,MAAM,OAAO,cAAc;AAAA,EAK3B,MAAM,QACJ,QAAQ,QAAQ,YACZ,QAAQ,QAAQ,YACd,YACA,IAAI,OAAO,QAAQ,GAAG,MACxB,QAAQ,QAAQ,YACd,OAAO,QAAQ,GAAG,IAClB,GAAG,OAAO,QAAQ,GAAG,KAAK,OAAO,QAAQ,GAAG;AAAA,EACpD,MAAM,QAAQ,UAAU,YAAY,CAAC,IAAI,CAAC,SAAS,YAAY,aAAa,YAAY;AAAA,EACxF,OAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,SAAS,aAAa;AAAA,IACtB,GAAG;AAAA,IACH,SAAS,QAAQ,KAAK,SAAS,CAAC,EAAE,SAAS,GAAG,GAAG,QAAQ,aAAa;AAAA,IACtE,YAAY,UAAU,aAAa;AAAA,EACrC,EAAE,KAAK;AAAA,CAAI;AAAA;AAGb,IAAM,YAAY;AAClB,IAAM,QAAQ,IAAI,IAA8B;AAAA,EAC9C,CAAC,OAAQ,MAAM;AAAA,EACf,CAAC,OAAQ,WAAW;AAAA,EACpB,CAAC,OAAQ,SAAS;AACpB,CAAC;AAGM,IAAM,YAAY,CAAC,WAAyC;AAAA,EACjE,MAAM,SAAS,OAAO,KAAK,EAAE,MAAM,KAAK;AAAA,EACxC,IAAI,OAAO,WAAW;AAAA,IAAG;AAAA,EACzB,OAAO,SAAS,OAAO,KAAK,KAAK,QAAQ;AAAA,EACzC,MAAM,MAAM,OAAO,SAAS,SAAS,EAAE;AAAA,EACvC,MAAM,OAAO,OAAO,SAAS,OAAO,CAAC;AAAA,EACrC,MAAM,UAAU,CAAC,KAAK,MAAM,OAAO,GAAG,GAAG,OAAO,GAAG,GAAG,OAAO,IAAI,CAAC;AAAA,EAClE,IAAI,QAAQ,KAAK,CAAC,UAAU,CAAC,OAAO,cAAc,KAAK,KAAK,QAAQ,CAAC;AAAA,IAAG;AAAA,EACxE,OAAO;AAAA,IACL,KAAK,OAAO,GAAG;AAAA,IACf,MAAM,MAAM,IAAI,MAAM,SAAS,KAAK;AAAA,IAEpC;AAAA,IACA,MAAM,OAAO,IAAI;AAAA,IACjB,KAAK,OAAO,GAAG;AAAA,EACjB;AAAA;;;AHjDF,IAAM,WAAW,CAAC,MAAyB,WAAmB,UAC5D,IAAI,QAAQ,CAAC,SAAS,WAAW;AAAA,EAC/B,OAAO,YAAY,QAAQ;AAAA,EAC3B,MAAM,QAAQ,MAAM,SAAS,MAAM;AAAA,IACjC,OAAO;AAAA,IACP,OAAO,CAAC,UAAU,YAAY,WAAW,QAAQ,QAAQ,MAAM;AAAA,IAC/D,SAAS;AAAA,EACX,CAAC;AAAA,EACD,MAAM,MAAgB,CAAC;AAAA,EACvB,MAAM,MAAgB,CAAC;AAAA,EACvB,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB,IAAI,KAAK,KAAK,CAAC;AAAA,EAC3D,MAAM,QAAQ,GAAG,QAAQ,CAAC,UAAkB,IAAI,KAAK,KAAK,CAAC;AAAA,EAC3D,MAAM,GAAG,SAAS,CAAC,UAAU;AAAA,IAC3B,OAAO,IAAI,MAAM,QAAQ,MAAM,SAAS,CAAC;AAAA,GAC1C;AAAA,EACD,IAAI,UAAU,aAAa,MAAM,UAAU,MAAM;AAAA,IAG/C,MAAM,MAAM,GAAG,SAAS,MAAG;AAAA,MAAG;AAAA,KAAS;AAAA,IACvC,MAAM,MAAM,IAAI,KAAK;AAAA,EACvB;AAAA,EACA,MAAM,GAAG,SAAS,CAAC,UAAU,WAAW;AAAA,IACtC,QAAQ;AAAA,MACN,UAAU,YAAY;AAAA,MACtB;AAAA,MACA,QAAQ,OAAO,OAAO,GAAG,EAAE,SAAS,MAAM;AAAA,MAC1C,QAAQ,OAAO,OAAO,GAAG,EAAE,SAAS,MAAM;AAAA,IAC5C,CAAC;AAAA,GACF;AAAA,CACF;AAGI,IAAM,YAAY,OACvB,SAEA,OACA,QACA,UACwB;AAAA,EACxB,MAAM,OAAO,QAAQ,QAAQ,MAAM,YAAY,QAAQ,KAAK,GAAG;AAAA,IAC7D,mBAAmB,QAAQ;AAAA,OACvB,QAAQ,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACtE,CAAC;AAAA,EACD,MAAM,MAAM,MAAM,SAAS,MAAM,QAAQ,eAAe,KAAK;AAAA,EAC7D,MAAM,SAAS,YAAY,IAAI,QAAQ,KAAK;AAAA,EAC5C,IAAI,WAAW,WAAW;AAAA,IAGxB,MAAM,IAAI,MACR,OAAO,QAAQ,gEACb,GAAG,OAAO,IAAI,QAAQ,IAAI,IAAI,WAAW,OAAO,KAAK,eAAe,IAAI,gBACxE,GAAG,IAAI,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,GACrC;AAAA,EACF;AAAA,EACA,OAAO,EAAE,UAAU,OAAO,UAAU,QAAQ,OAAO,QAAQ,QAAQ,IAAI,OAAO;AAAA;AAGhF,IAAM,eAAe,CAAC,SACpB,IAAI,WAAW,OAAO,KAAK,KAAK,WAAW;AAAA,GAAM,EAAE,GAAG,QAAQ,CAAC;AAEjE,IAAM,SAAS,CAAC,MAAc,MAAc,WAC1C,IAAI,MACF,OAAO,SAAS,WAAW,OAAO,OAAO,QAAQ,MAAM,OAAO,OAAO,KAAK,EAAE,MAAM,GAAG,GAAG,GAC1F;AASK,IAAM,YAAY,OAAO,YAAmD;AAAA,EACjF,MAAM,WAAW;AAAA,IACf,mBAAmB,QAAQ,qBAAqB;AAAA,IAChD,eAAe,QAAQ,iBAAiB;AAAA,IACxC,MAAM,QAAQ;AAAA,OACV,QAAQ,YAAY,YAAY,CAAC,IAAI,EAAE,SAAS,QAAQ,QAAQ;AAAA,EACtE;AAAA,EACA,MAAM,QAAQ,YAAY,CAAC,EAAE,SAAS,KAAK;AAAA,EAC3C,MAAM,OAAM,CAAC,QAAgB,UAAuB,UAAU,UAAU,OAAO,QAAQ,KAAK;AAAA,EAC5F,MAAM,QAAQ,MAAM,KAAI,iBAAiB;AAAA,EACzC,IAAI,MAAM,aAAa;AAAA,IAAG,MAAM,OAAO,QAAQ,MAAM,mBAAmB,KAAK;AAAA,EAC7E,OAAO,QAAQ,OAAO,MAAM,OAAO,KAAK,EAAE,MAAM;AAAA,CAAI;AAAA,EACpD,IAAI,WAAW,WAAW,QAAQ,aAAa,CAAC,QAAQ,KAAK,GAAG,GAAG;AAAA,IACjE,MAAM,IAAI,MACR,OAAO,QAAQ,oCAAoC,KAAK,UAAU,MAAM,OAAO,KAAK,CAAC,QACnF,2FACJ;AAAA,EACF;AAAA,EACA,MAAM,OAAO,OAAO,GAAG;AAAA,EACvB,OAAO;AAAA,IACL,cAAc,MAAM;AAAA,IACpB,MAAM,CAAC,SAAS,KAAI,WAAW,IAAI,CAAC;AAAA,IACpC,aAAa,OAAO,aAAa;AAAA,MAC/B,MAAM,SAAS,MAAM,KAAI,WAAW,WAAW,SAAS,QAAQ,CAAC,CAAC;AAAA,MAClE,OAAO,OAAO,aAAa,IAAI,WAAW,SAAS,OAAO,MAAM,IAAI;AAAA;AAAA,IAEtE,YAAY,OAAO,aAAa;AAAA,MAC9B,MAAM,SAAS,MAAM,KAAI,WAAW,UAAU,SAAS,QAAQ,CAAC,CAAC;AAAA,MACjE,OAAO,OAAO,aAAa,IAAI,UAAU,SAAS,OAAO,MAAM,IAAI;AAAA;AAAA,IAErE,YAAY;AAAA,IACZ,UAAU,OAAO,SAAS;AAAA,MACxB,MAAM,SAAS,MAAM,KAAI,WAAW,IAAI,CAAC;AAAA,MACzC,IAAI,OAAO,aAAa;AAAA,QAAQ;AAAA,MAChC,IAAI,OAAO,aAAa;AAAA,QAAG,MAAM,OAAO,QAAQ,MAAM,QAAQ,QAAQ,MAAM;AAAA,MAC5E,OAAO,aAAa,OAAO,MAAM;AAAA;AAAA,IAEnC,YAAY,OAAO,SAAS;AAAA,MAC1B,MAAM,SAAS,MAAM,KAAI,aAAa,IAAI,CAAC;AAAA,MAC3C,IAAI,OAAO,aAAa;AAAA,QAAG,MAAM,OAAO,QAAQ,MAAM,UAAU,QAAQ,MAAM;AAAA;AAAA,IAEhF,OAAO,CAAC,OAAO,IAAI,QAAQ,CAAC,YAAY,WAAW,SAAS,EAAE,CAAC;AAAA,IAC/D,MAAM,OAAO,SAAS;AAAA,MACpB,MAAM,SAAS,MAAM,KAAI,WAAW,IAAI,CAAC;AAAA,MACzC,IAAI,OAAO,aAAa;AAAA,QAAQ;AAAA,MAChC,IAAI,OAAO,aAAa;AAAA,QAAG,MAAM,OAAO,QAAQ,MAAM,QAAQ,QAAQ,MAAM;AAAA,MAC5E,MAAM,SAAS,UAAU,OAAO,MAAM;AAAA,MAGtC,IAAI,WAAW,WAAW;AAAA,QACxB,MAAM,IAAI,MAAM,OAAO,QAAQ,cAAc,kCAAkC;AAAA,MACjF;AAAA,MACA,OAAO;AAAA;AAAA,IAET,iBAAiB,OAAO,MAAM,OAAO,UAAU;AAAA,MAC7C,MAAM,KAAK,KAAK,YAAY,GAAG;AAAA,MAC/B,MAAM,OAAO,GAAG,KAAK,MAAM,GAAG,EAAE,MAAM,KAAK,MAAM,KAAK,CAAC,KAAK,YAAY,CAAC,EAAE,SAAS,KAAK;AAAA,MACzF,MAAM,SAAS,MAAM,KAAI,YAAY,MAAM,MAAM,KAAK,GAAG,KAAK;AAAA,MAC9D,IAAI,OAAO,aAAa;AAAA,QAAG,MAAM,OAAO,QAAQ,MAAM,SAAS,QAAQ,MAAM;AAAA;AAAA,EAEjF;AAAA;",
|
|
35
|
-
"debugId": "
|
|
35
|
+
"mappings": "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",
|
|
36
|
+
"debugId": "6BC8BE5DBFF285E364756E2164756E21",
|
|
36
37
|
"names": []
|
|
37
38
|
}
|
|
@@ -19,14 +19,10 @@
|
|
|
19
19
|
* start fail; unmasking here would silently overrule whoever masked it.
|
|
20
20
|
*/
|
|
21
21
|
import type { Diff } from 'alchemy/Diff';
|
|
22
|
-
import {
|
|
22
|
+
import type { HostRunner } from '../launchd/runner.ts';
|
|
23
23
|
import { type SystemdUnitAttributes, type SystemdUnitProps } from './unit-form.ts';
|
|
24
|
-
/** Throw every refusal at once, so one plan shows the whole list. */
|
|
25
|
-
export declare const assertValid: (props: SystemdUnitProps, expect?: string) => void;
|
|
26
24
|
/** What is on the host now: the unit file's digest and systemd's view. `undefined` when neither. */
|
|
27
25
|
export declare const readUnit: (runner: HostRunner, props: SystemdUnitProps) => Promise<SystemdUnitAttributes | undefined>;
|
|
28
|
-
/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */
|
|
29
|
-
export declare const assertMayWrite: (runner: HostRunner, name: string) => void;
|
|
30
26
|
export declare const diffUnit: (runner: HostRunner, news: SystemdUnitProps, output: SystemdUnitAttributes, expect?: string) => Promise<Diff>;
|
|
31
27
|
/**
|
|
32
28
|
* `adopt` is whether adoption is on AND this apply is a create or an unfinished generation of our
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"unit-lifecycle.d.ts","sourceRoot":"","sources":["../../src/linux/unit-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,EAAE,
|
|
1
|
+
{"version":3,"file":"unit-lifecycle.d.ts","sourceRoot":"","sources":["../../src/linux/unit-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AACzC,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAEvD,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAMtB,MAAM,gBAAgB,CAAC;AAOxB,oGAAoG;AACpG,eAAO,MAAM,QAAQ,WACX,UAAU,SACX,gBAAgB,KACtB,OAAO,CAAC,qBAAqB,GAAG,SAAS,CAK3C,CAAC;AAEF,eAAO,MAAM,QAAQ,WACX,UAAU,QACZ,gBAAgB,UACd,qBAAqB,WACpB,MAAM,KACd,OAAO,CAAC,IAAI,CA4Bd,CAAC;AAEF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,WAChB,UAAU,SACX,gBAAgB,UACf,qBAAqB,GAAG,SAAS,4BAEhC,MAAM,KACd,OAAO,CAAC,qBAAqB,CAqD/B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,UAAU,WACb,UAAU,UACV,qBAAqB,KAC5B,OAAO,CAAC,IAAI,CAed,CAAC"}
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything Systemd.Unit checks before it touches the host — split from unit-lifecycle.ts so that
|
|
3
|
+
* a reconcile and a plan-time REPLACE run the very same checks.
|
|
4
|
+
*
|
|
5
|
+
* ★ WHY A REPLACE IS CHECKED AT PLAN TIME. A name or directory change is a delete-first replace,
|
|
6
|
+
* and Alchemy runs `delete` on the old unit BEFORE `reconcile` on the new one (Apply.ts,
|
|
7
|
+
* deleteOldGenerations under `node.deleteFirst`). A refusal that fired only in reconcile would
|
|
8
|
+
* therefore arrive after the old unit was already stopped and its file removed: nothing running,
|
|
9
|
+
* and a plan that had promised a clean swap.
|
|
10
|
+
* ★ EVERY CHECK HERE IS READ-ONLY. systemd has no `print-disabled` equivalent in this family —
|
|
11
|
+
* masking is `systemctl show`'s LoadState / UnitFileState, which `showUnit` already returns.
|
|
12
|
+
* Validation, that show, a file read and `HostRunner.checkWrite` write nothing. `systemctl
|
|
13
|
+
* enable` itself stays an apply step; the ways it is known to fail (no `[Install]`, a directory
|
|
14
|
+
* systemd does not search) are `unitProblems`, checked here before the plan may promise a swap.
|
|
15
|
+
*/
|
|
16
|
+
import { type HostRunner } from '../launchd/runner.ts';
|
|
17
|
+
import { type UnitStatus } from './systemctl.ts';
|
|
18
|
+
import { type SystemdUnitAttributes, type SystemdUnitProps } from './unit-form.ts';
|
|
19
|
+
/** Throw every refusal at once, so one plan shows the whole list. */
|
|
20
|
+
export declare const assertValid: (props: SystemdUnitProps, expect?: string) => void;
|
|
21
|
+
/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */
|
|
22
|
+
export declare const assertMayWrite: (runner: HostRunner, name: string) => void;
|
|
23
|
+
/**
|
|
24
|
+
* ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes
|
|
25
|
+
* start fail; unmasking here would silently overrule whoever masked it.
|
|
26
|
+
*/
|
|
27
|
+
export declare const assertUsable: (props: SystemdUnitProps, status: UnitStatus) => void;
|
|
28
|
+
/**
|
|
29
|
+
* ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Alchemy's adoption probe guards a
|
|
30
|
+
* create, but NOT the new name of a replace — the engine reads nothing there — so a rename onto
|
|
31
|
+
* a unit file someone else already has would stop the old unit and write ours over theirs.
|
|
32
|
+
* ★ A file byte-identical to our render is exempt: it is this declaration's own leftover (a deploy
|
|
33
|
+
* that died between write and reload), and rewriting it changes nothing.
|
|
34
|
+
*/
|
|
35
|
+
export declare const assertUnclaimed: (runner: HostRunner, props: SystemdUnitProps) => Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* A rename, checked at plan time: the new identity must be valid, writable, not masked and free,
|
|
38
|
+
* and the old one deletable — before the plan may promise a delete-first replace.
|
|
39
|
+
*/
|
|
40
|
+
export declare const assertReplaceable: (runner: HostRunner, next: SystemdUnitProps, old: SystemdUnitAttributes, expect?: string) => Promise<void>;
|
|
41
|
+
//# sourceMappingURL=unit-preflight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"unit-preflight.d.ts","sourceRoot":"","sources":["../../src/linux/unit-preflight.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AACH,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AACrE,OAAO,EAAE,KAAK,UAAU,EAAY,MAAM,gBAAgB,CAAC;AAC3D,OAAO,EACL,KAAK,qBAAqB,EAC1B,KAAK,gBAAgB,EAMtB,MAAM,gBAAgB,CAAC;AAKxB,qEAAqE;AACrE,eAAO,MAAM,WAAW,UAAW,gBAAgB,WAAW,MAAM,KAAG,IAGtE,CAAC;AAEF,sGAAsG;AACtG,eAAO,MAAM,cAAc,WAAY,UAAU,QAAQ,MAAM,KAAG,IAOjE,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,YAAY,UAAW,gBAAgB,UAAU,UAAU,KAAG,IAQ1E,CAAC;AAEF;;;;;;GAMG;AACH,eAAO,MAAM,eAAe,WAClB,UAAU,SACX,gBAAgB,KACtB,OAAO,CAAC,IAAI,CAWd,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,iBAAiB,WACpB,UAAU,QACZ,gBAAgB,OACjB,qBAAqB,WACjB,MAAM,KACd,OAAO,CAAC,IAAI,CAOd,CAAC"}
|
package/docs/linux-host.md
CHANGED
|
@@ -158,7 +158,13 @@ unit reads converged — the same limit the Mac side records.
|
|
|
158
158
|
- ⛔ Deleting the declaration **stops the service** — stop, disable, remove the
|
|
159
159
|
file, reload. A unit that must outlive its declaration is adopted, not deleted.
|
|
160
160
|
- A name or directory change is a **delete-first replace**: two unit files for
|
|
161
|
-
one name cannot both be the one systemd reads.
|
|
161
|
+
one name cannot both be the one systemd reads. The new identity is checked
|
|
162
|
+
at plan time, read-only — valid, writable, not masked, unclaimed, and the
|
|
163
|
+
runner's own check on the new path — and the old unit must be deletable,
|
|
164
|
+
before that swap is promised. A file byte-identical to this render is the
|
|
165
|
+
declaration's own leftover, not someone else's unit. A rename the plan could
|
|
166
|
+
not see (a name still an Output) gets the same checks at apply, before the
|
|
167
|
+
old unit is stopped.
|
|
162
168
|
|
|
163
169
|
### The directive set is systemd's, not the kit's
|
|
164
170
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@homeflare/alchemy",
|
|
3
|
-
"version": "0.19.
|
|
3
|
+
"version": "0.19.1",
|
|
4
4
|
"description": "Custom Alchemy providers for Cloudflare, Proxmox, OpenBao, Forgejo, Talos, launchd and Caddy, and a verifier that proves adoptions are no-ops.",
|
|
5
5
|
"homepage": "https://github.com/taslabs-net/homeflare-kit/tree/main/packages/alchemy#readme",
|
|
6
6
|
"bugs": "https://github.com/taslabs-net/homeflare-kit/issues",
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
* start fail; unmasking here would silently overrule whoever masked it.
|
|
20
20
|
*/
|
|
21
21
|
import type { Diff } from 'alchemy/Diff';
|
|
22
|
-
import {
|
|
22
|
+
import type { HostRunner } from '../launchd/runner.ts';
|
|
23
|
+
import { daemonReload, disableUnit, showUnit, stopUnit } from './systemctl.ts';
|
|
23
24
|
import {
|
|
24
25
|
type SystemdUnitAttributes,
|
|
25
26
|
type SystemdUnitProps,
|
|
@@ -27,21 +28,14 @@ import {
|
|
|
27
28
|
configDigest,
|
|
28
29
|
digestOf,
|
|
29
30
|
unitPathFor,
|
|
30
|
-
unitProblems,
|
|
31
31
|
unitText,
|
|
32
32
|
} from './unit-form.ts';
|
|
33
|
-
import {
|
|
33
|
+
import { assertMayWrite, assertReplaceable, assertUsable, assertValid } from './unit-preflight.ts';
|
|
34
34
|
import { attributesOf, refuse, settle } from './unit-settle.ts';
|
|
35
35
|
|
|
36
36
|
const encoder = new TextEncoder();
|
|
37
37
|
const decoder = new TextDecoder();
|
|
38
38
|
|
|
39
|
-
/** Throw every refusal at once, so one plan shows the whole list. */
|
|
40
|
-
export const assertValid = (props: SystemdUnitProps, expect?: string): void => {
|
|
41
|
-
const found = unitProblems(props, expect);
|
|
42
|
-
if (found.length > 0) throw refuse(props.name, found.join('; '));
|
|
43
|
-
};
|
|
44
|
-
|
|
45
39
|
/** What is on the host now: the unit file's digest and systemd's view. `undefined` when neither. */
|
|
46
40
|
export const readUnit = async (
|
|
47
41
|
runner: HostRunner,
|
|
@@ -53,26 +47,6 @@ export const readUnit = async (
|
|
|
53
47
|
return attributesOf(props, bytes === undefined ? '' : digestOf(decoder.decode(bytes)), status);
|
|
54
48
|
};
|
|
55
49
|
|
|
56
|
-
/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */
|
|
57
|
-
export const assertMayWrite = (runner: HostRunner, name: string): void => {
|
|
58
|
-
if (canActAsRoot(runner)) return;
|
|
59
|
-
throw refuse(
|
|
60
|
-
name,
|
|
61
|
-
'a systemd unit is root-owned and systemctl needs root. Point the runner at a destination ' +
|
|
62
|
-
'whose ssh user is root, or provide a privileged HostRunner. This provider never calls sudo.',
|
|
63
|
-
);
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const assertUsable = (props: SystemdUnitProps, status: UnitStatus): void => {
|
|
67
|
-
if (status.loadState === 'masked' || status.unitFileState === 'masked') {
|
|
68
|
-
throw refuse(
|
|
69
|
-
props.name,
|
|
70
|
-
'is masked. If that is stale, `systemctl unmask` it deliberately, then redeploy. Nothing ' +
|
|
71
|
-
'was written.',
|
|
72
|
-
);
|
|
73
|
-
}
|
|
74
|
-
};
|
|
75
|
-
|
|
76
50
|
export const diffUnit = async (
|
|
77
51
|
runner: HostRunner,
|
|
78
52
|
news: SystemdUnitProps,
|
|
@@ -82,8 +56,10 @@ export const diffUnit = async (
|
|
|
82
56
|
assertValid(news, expect);
|
|
83
57
|
// ★ The unit's name or its directory is its identity on the host: a change is a replace, and
|
|
84
58
|
// delete-first, because two unit files for one name cannot both be the one systemd reads.
|
|
59
|
+
// ⛔ Which is why everything the new unit's reconcile would refuse is refused HERE, at plan
|
|
60
|
+
// time (unit-preflight.ts): after the delete it would be too late.
|
|
85
61
|
if (news.name !== output.name || unitPathFor(news) !== output.unitPath) {
|
|
86
|
-
|
|
62
|
+
await assertReplaceable(runner, news, output, expect);
|
|
87
63
|
return { action: 'replace', deleteFirst: true };
|
|
88
64
|
}
|
|
89
65
|
const desired = digestOf(unitText(news));
|
|
@@ -129,6 +105,12 @@ export const reconcileUnit = async (
|
|
|
129
105
|
const before = await runner.readFile(path);
|
|
130
106
|
const liveSha = before === undefined ? undefined : digestOf(decoder.decode(before));
|
|
131
107
|
const moved = output !== undefined && (output.name !== props.name || output.unitPath !== path);
|
|
108
|
+
/**
|
|
109
|
+
* ★ A rename the diff could not see — a name that was still an unresolved Output at plan time
|
|
110
|
+
* (unit-handlers.ts diffHandler) — arrives here as an update. Run the same read-only checks a
|
|
111
|
+
* plan-time replace runs, BEFORE deleteUnit, or the old unit is already gone when we refuse.
|
|
112
|
+
*/
|
|
113
|
+
if (moved && output !== undefined) await assertReplaceable(runner, props, output, expect);
|
|
132
114
|
const prior = moved ? undefined : output;
|
|
133
115
|
/**
|
|
134
116
|
* ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Where the engine's probe never
|
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A systemd rename is a delete-first replace, so every refusal has to fire at PLAN time. Caught
|
|
3
|
+
* only in reconcile, Alchemy has already stopped and removed the old unit (Apply.ts,
|
|
4
|
+
* deleteOldGenerations under `node.deleteFirst`).
|
|
5
|
+
*
|
|
6
|
+
* ★ The last case is the one the diff cannot see: a name that was still an Output at plan time
|
|
7
|
+
* arrives at reconcile as an update (unit-handlers.ts). The same refusals have to fire there,
|
|
8
|
+
* before deleteUnit.
|
|
9
|
+
*/
|
|
10
|
+
import { describe, expect, test } from 'bun:test';
|
|
11
|
+
import { fakeLinuxHost } from './fake-linux-host.ts';
|
|
12
|
+
import { renderUnit } from './unit-form.ts';
|
|
13
|
+
import { deleteUnit, diffUnit, reconcileUnit } from './unit-lifecycle.ts';
|
|
14
|
+
|
|
15
|
+
const NAME = 'hf-example.service';
|
|
16
|
+
const PATH = `/etc/systemd/system/${NAME}`;
|
|
17
|
+
const RENAMED = 'hf-renamed.service';
|
|
18
|
+
const RENAMED_PATH = `/etc/systemd/system/${RENAMED}`;
|
|
19
|
+
|
|
20
|
+
const body = (exec: string) =>
|
|
21
|
+
renderUnit([
|
|
22
|
+
{ lines: [['Description', 'an example']], name: 'Unit' },
|
|
23
|
+
{
|
|
24
|
+
lines: [
|
|
25
|
+
['ExecStart', exec],
|
|
26
|
+
['Restart', 'on-failure'],
|
|
27
|
+
],
|
|
28
|
+
name: 'Service',
|
|
29
|
+
},
|
|
30
|
+
{ lines: [['WantedBy', 'multi-user.target']], name: 'Install' },
|
|
31
|
+
]);
|
|
32
|
+
|
|
33
|
+
const props = { content: body('/usr/bin/example'), name: NAME };
|
|
34
|
+
const renamed = { ...props, name: RENAMED };
|
|
35
|
+
const host = () => fakeLinuxHost({ dirs: { '/etc/systemd/system': 0 } });
|
|
36
|
+
|
|
37
|
+
const running = async () => {
|
|
38
|
+
const fake = host();
|
|
39
|
+
const output = await reconcileUnit(fake.runner, props, undefined);
|
|
40
|
+
return { fake, output };
|
|
41
|
+
};
|
|
42
|
+
|
|
43
|
+
describe('a rename is refused at plan time, and the old unit is still running', () => {
|
|
44
|
+
test('a masked new name', async () => {
|
|
45
|
+
const { fake, output } = await running();
|
|
46
|
+
fake.placeUnit(RENAMED_PATH, body('/usr/bin/other'), { masked: true });
|
|
47
|
+
await expect(diffUnit(fake.runner, renamed, output)).rejects.toThrow(/is masked/);
|
|
48
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
49
|
+
expect(fake.files.has(PATH)).toBe(true);
|
|
50
|
+
});
|
|
51
|
+
|
|
52
|
+
test('a new name whose file belongs to someone else', async () => {
|
|
53
|
+
const { fake, output } = await running();
|
|
54
|
+
fake.placeUnit(RENAMED_PATH, body('/usr/bin/other'), { active: true, enabled: true });
|
|
55
|
+
await expect(diffUnit(fake.runner, renamed, output)).rejects.toThrow(/not this resource/);
|
|
56
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
57
|
+
expect(fake.units.get(RENAMED)?.active).toBe(true);
|
|
58
|
+
});
|
|
59
|
+
|
|
60
|
+
test('a file byte-identical to our render is our own leftover, not a claim', async () => {
|
|
61
|
+
const { fake, output } = await running();
|
|
62
|
+
fake.placeUnit(RENAMED_PATH, props.content);
|
|
63
|
+
expect(await diffUnit(fake.runner, renamed, output)).toEqual({
|
|
64
|
+
action: 'replace',
|
|
65
|
+
deleteFirst: true,
|
|
66
|
+
});
|
|
67
|
+
});
|
|
68
|
+
|
|
69
|
+
test('a runner that will not write the new path', async () => {
|
|
70
|
+
const { fake, output } = await running();
|
|
71
|
+
const refusing = {
|
|
72
|
+
...fake.runner,
|
|
73
|
+
checkWrite: async () => {
|
|
74
|
+
throw new Error('HostRunner.checkWrite refused');
|
|
75
|
+
},
|
|
76
|
+
};
|
|
77
|
+
await expect(diffUnit(refusing, renamed, output)).rejects.toThrow(/checkWrite/);
|
|
78
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
79
|
+
});
|
|
80
|
+
|
|
81
|
+
test('the old unit must be deletable before a delete-first replace is promised', async () => {
|
|
82
|
+
const { fake, output } = await running();
|
|
83
|
+
const unprivileged = { ...fake.runner, effectiveUid: () => 1001, privileged: false };
|
|
84
|
+
await expect(diffUnit(unprivileged, renamed, output)).rejects.toThrow(/never calls sudo/);
|
|
85
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
86
|
+
expect(fake.files.has(PATH)).toBe(true);
|
|
87
|
+
});
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
describe('a free name', () => {
|
|
91
|
+
test('plans a delete-first replace, and delete-then-reconcile leaves only the new unit', async () => {
|
|
92
|
+
const { fake, output } = await running();
|
|
93
|
+
expect(await diffUnit(fake.runner, renamed, output)).toEqual({
|
|
94
|
+
action: 'replace',
|
|
95
|
+
deleteFirst: true,
|
|
96
|
+
});
|
|
97
|
+
await deleteUnit(fake.runner, output);
|
|
98
|
+
const next = await reconcileUnit(fake.runner, renamed, output);
|
|
99
|
+
expect(next).toMatchObject({
|
|
100
|
+
active: true,
|
|
101
|
+
enabled: true,
|
|
102
|
+
name: RENAMED,
|
|
103
|
+
unitPath: RENAMED_PATH,
|
|
104
|
+
});
|
|
105
|
+
expect(fake.files.has(PATH)).toBe(false);
|
|
106
|
+
expect(fake.files.has(RENAMED_PATH)).toBe(true);
|
|
107
|
+
expect(fake.units.get(NAME)?.active ?? false).toBe(false);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
describe('a rename the diff could not see is refused at apply, before the old unit stops', () => {
|
|
112
|
+
test('a masked new name', async () => {
|
|
113
|
+
const { fake, output } = await running();
|
|
114
|
+
fake.placeUnit(RENAMED_PATH, body('/usr/bin/other'), { masked: true });
|
|
115
|
+
await expect(reconcileUnit(fake.runner, renamed, output)).rejects.toThrow(/is masked/);
|
|
116
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
117
|
+
expect(fake.files.has(PATH)).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
test('a new name whose file belongs to someone else', async () => {
|
|
121
|
+
const { fake, output } = await running();
|
|
122
|
+
fake.placeUnit(RENAMED_PATH, body('/usr/bin/other'), { active: true, enabled: true });
|
|
123
|
+
await expect(reconcileUnit(fake.runner, renamed, output)).rejects.toThrow(/not this resource/);
|
|
124
|
+
expect(fake.units.get(NAME)?.active).toBe(true);
|
|
125
|
+
expect(fake.files.has(PATH)).toBe(true);
|
|
126
|
+
expect(fake.units.get(RENAMED)?.active).toBe(true);
|
|
127
|
+
});
|
|
128
|
+
});
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Everything Systemd.Unit checks before it touches the host — split from unit-lifecycle.ts so that
|
|
3
|
+
* a reconcile and a plan-time REPLACE run the very same checks.
|
|
4
|
+
*
|
|
5
|
+
* ★ WHY A REPLACE IS CHECKED AT PLAN TIME. A name or directory change is a delete-first replace,
|
|
6
|
+
* and Alchemy runs `delete` on the old unit BEFORE `reconcile` on the new one (Apply.ts,
|
|
7
|
+
* deleteOldGenerations under `node.deleteFirst`). A refusal that fired only in reconcile would
|
|
8
|
+
* therefore arrive after the old unit was already stopped and its file removed: nothing running,
|
|
9
|
+
* and a plan that had promised a clean swap.
|
|
10
|
+
* ★ EVERY CHECK HERE IS READ-ONLY. systemd has no `print-disabled` equivalent in this family —
|
|
11
|
+
* masking is `systemctl show`'s LoadState / UnitFileState, which `showUnit` already returns.
|
|
12
|
+
* Validation, that show, a file read and `HostRunner.checkWrite` write nothing. `systemctl
|
|
13
|
+
* enable` itself stays an apply step; the ways it is known to fail (no `[Install]`, a directory
|
|
14
|
+
* systemd does not search) are `unitProblems`, checked here before the plan may promise a swap.
|
|
15
|
+
*/
|
|
16
|
+
import { type HostRunner, canActAsRoot } from '../launchd/runner.ts';
|
|
17
|
+
import { type UnitStatus, showUnit } from './systemctl.ts';
|
|
18
|
+
import {
|
|
19
|
+
type SystemdUnitAttributes,
|
|
20
|
+
type SystemdUnitProps,
|
|
21
|
+
UNIT_WRITE,
|
|
22
|
+
digestOf,
|
|
23
|
+
unitPathFor,
|
|
24
|
+
unitProblems,
|
|
25
|
+
unitText,
|
|
26
|
+
} from './unit-form.ts';
|
|
27
|
+
import { refuse } from './unit-settle.ts';
|
|
28
|
+
|
|
29
|
+
const decoder = new TextDecoder();
|
|
30
|
+
|
|
31
|
+
/** Throw every refusal at once, so one plan shows the whole list. */
|
|
32
|
+
export const assertValid = (props: SystemdUnitProps, expect?: string): void => {
|
|
33
|
+
const found = unitProblems(props, expect);
|
|
34
|
+
if (found.length > 0) throw refuse(props.name, found.join('; '));
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/** ⛔ Writing a unit file and driving systemd are root's, so refuse up front rather than mid-apply. */
|
|
38
|
+
export const assertMayWrite = (runner: HostRunner, name: string): void => {
|
|
39
|
+
if (canActAsRoot(runner)) return;
|
|
40
|
+
throw refuse(
|
|
41
|
+
name,
|
|
42
|
+
'a systemd unit is root-owned and systemctl needs root. Point the runner at a destination ' +
|
|
43
|
+
'whose ssh user is root, or provide a privileged HostRunner. This provider never calls sudo.',
|
|
44
|
+
);
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
/**
|
|
48
|
+
* ⛔ A MASKED UNIT IS SOMEONE'S DECISION, NOT DRIFT. `systemctl mask` survives reboots and makes
|
|
49
|
+
* start fail; unmasking here would silently overrule whoever masked it.
|
|
50
|
+
*/
|
|
51
|
+
export const assertUsable = (props: SystemdUnitProps, status: UnitStatus): void => {
|
|
52
|
+
if (status.loadState === 'masked' || status.unitFileState === 'masked') {
|
|
53
|
+
throw refuse(
|
|
54
|
+
props.name,
|
|
55
|
+
'is masked. If that is stale, `systemctl unmask` it deliberately, then redeploy. Nothing ' +
|
|
56
|
+
'was written.',
|
|
57
|
+
);
|
|
58
|
+
}
|
|
59
|
+
};
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* ⛔ A UNIT THIS RESOURCE DOES NOT OWN IS NEVER OVERWRITTEN. Alchemy's adoption probe guards a
|
|
63
|
+
* create, but NOT the new name of a replace — the engine reads nothing there — so a rename onto
|
|
64
|
+
* a unit file someone else already has would stop the old unit and write ours over theirs.
|
|
65
|
+
* ★ A file byte-identical to our render is exempt: it is this declaration's own leftover (a deploy
|
|
66
|
+
* that died between write and reload), and rewriting it changes nothing.
|
|
67
|
+
*/
|
|
68
|
+
export const assertUnclaimed = async (
|
|
69
|
+
runner: HostRunner,
|
|
70
|
+
props: SystemdUnitProps,
|
|
71
|
+
): Promise<void> => {
|
|
72
|
+
const path = unitPathFor(props);
|
|
73
|
+
const bytes = await runner.readFile(path);
|
|
74
|
+
const live = bytes === undefined ? undefined : digestOf(decoder.decode(bytes));
|
|
75
|
+
if (live !== undefined && live !== digestOf(unitText(props))) {
|
|
76
|
+
throw refuse(
|
|
77
|
+
props.name,
|
|
78
|
+
`${path} is already on this host and is not this resource. Remove it, or declare it as a ` +
|
|
79
|
+
'new resource and deploy with --adopt.',
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* A rename, checked at plan time: the new identity must be valid, writable, not masked and free,
|
|
86
|
+
* and the old one deletable — before the plan may promise a delete-first replace.
|
|
87
|
+
*/
|
|
88
|
+
export const assertReplaceable = async (
|
|
89
|
+
runner: HostRunner,
|
|
90
|
+
next: SystemdUnitProps,
|
|
91
|
+
old: SystemdUnitAttributes,
|
|
92
|
+
expect?: string,
|
|
93
|
+
): Promise<void> => {
|
|
94
|
+
assertValid(next, expect);
|
|
95
|
+
assertMayWrite(runner, old.name);
|
|
96
|
+
assertMayWrite(runner, next.name);
|
|
97
|
+
assertUsable(next, await showUnit(runner, next.name));
|
|
98
|
+
await assertUnclaimed(runner, next);
|
|
99
|
+
await runner.checkWrite?.(unitPathFor(next), UNIT_WRITE);
|
|
100
|
+
};
|
|
@@ -58,17 +58,25 @@ describe('Proxmox.ApiToken plans clean against POST /access/users/{userid}/token
|
|
|
58
58
|
});
|
|
59
59
|
|
|
60
60
|
describe('Proxmox.MetricServer plans clean against POST /cluster/metrics/server/{id}', () => {
|
|
61
|
-
/**
|
|
61
|
+
/**
|
|
62
|
+
* The estate's own row, SHAPED: InfluxDB v2 over https with an api-path-prefix, an
|
|
63
|
+
* organization and a bucket, every value a placeholder.
|
|
64
|
+
*
|
|
65
|
+
* ⛔ SHAPE ONLY, FOR THE REASON lxc-harness.ts GIVES. `src` ships in the npm tarball and this
|
|
66
|
+
* repository is public, so a real metrics host, cluster name or organization here would be
|
|
67
|
+
* estate topology published forever in the git history. The proof is about which KEYS the
|
|
68
|
+
* create form sends and which bounds they face; the strings carry none of it.
|
|
69
|
+
*/
|
|
62
70
|
const declared = {
|
|
63
|
-
'api-path-prefix': '/
|
|
71
|
+
'api-path-prefix': '/cluster-a/',
|
|
64
72
|
bucket: 'pve',
|
|
65
73
|
disable: false,
|
|
66
|
-
id: '
|
|
74
|
+
id: 'metrics-example',
|
|
67
75
|
influxdbproto: 'https',
|
|
68
76
|
'max-body-size': 10_000_000,
|
|
69
|
-
organization: '
|
|
77
|
+
organization: 'example',
|
|
70
78
|
port: 443,
|
|
71
|
-
server: 'metrics.
|
|
79
|
+
server: 'metrics.example.invalid',
|
|
72
80
|
target: TARGET,
|
|
73
81
|
type: 'influxdb',
|
|
74
82
|
'verify-certificate': true,
|
|
@@ -102,7 +110,7 @@ describe('Proxmox.MetricServer plans clean against POST /cluster/metrics/server/
|
|
|
102
110
|
});
|
|
103
111
|
|
|
104
112
|
describe('Proxmox.NotificationTarget plans clean per family', () => {
|
|
105
|
-
/** The
|
|
113
|
+
/** The shipped `mail-to-root`, edited — the shape every estate has. sendmail needs only a name. */
|
|
106
114
|
test('the live sendmail declaration has no violations', () => {
|
|
107
115
|
expect(
|
|
108
116
|
onCreate(
|
|
@@ -50,7 +50,12 @@ describe('the Ceph families plan clean against their own creates', () => {
|
|
|
50
50
|
expect(
|
|
51
51
|
onCreate(
|
|
52
52
|
'pve:POST /nodes/{node}/ceph/fs/{name}',
|
|
53
|
-
cephFsCreateForm({
|
|
53
|
+
cephFsCreateForm({
|
|
54
|
+
'add-storage': true,
|
|
55
|
+
name: 'cephfs-example',
|
|
56
|
+
node: 'n2',
|
|
57
|
+
target: TARGET,
|
|
58
|
+
}),
|
|
54
59
|
),
|
|
55
60
|
).toEqual([]);
|
|
56
61
|
expect(constraintsFor('pve:POST /nodes/{node}/ceph/fs/{name}')['pg_num']).toMatchObject({
|
|
@@ -69,9 +74,13 @@ describe('the Ceph families plan clean against their own creates', () => {
|
|
|
69
74
|
expect(constraintsFor('pve:POST /nodes/{node}/ceph/osd')['dev']?.required).toBe(true);
|
|
70
75
|
});
|
|
71
76
|
|
|
72
|
-
/**
|
|
77
|
+
/**
|
|
78
|
+
* The estate's own pool set, SHAPED: an RBD pool and a CephFS data/metadata pair, size 3 and
|
|
79
|
+
* min_size 2, names replaced. ⛔ `src` ships in the npm tarball and this repository is public —
|
|
80
|
+
* lxc-harness.ts has the rule. The proof is the keys and the bounds, never the strings.
|
|
81
|
+
*/
|
|
73
82
|
test('the live CephPool declarations have no violations', () => {
|
|
74
|
-
for (const name of ['
|
|
83
|
+
for (const name of ['rbd-example', 'cephfs-example_data', 'cephfs-example_metadata']) {
|
|
75
84
|
expect(
|
|
76
85
|
onCreate(
|
|
77
86
|
'pve:POST /nodes/{node}/ceph/pool',
|