@hasna/machines 0.0.20 → 0.0.22
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -0
- package/dist/cli/index.js +417 -15
- package/dist/commands/workspace.d.ts +37 -0
- package/dist/commands/workspace.d.ts.map +1 -0
- package/dist/consumer.d.ts +1 -1
- package/dist/consumer.d.ts.map +1 -1
- package/dist/consumer.js +201 -10
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +354 -14
- package/dist/mcp/index.js +205 -14
- package/dist/topology.d.ts +21 -0
- package/dist/topology.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/consumer.js
CHANGED
|
@@ -4317,7 +4317,8 @@ var MACHINES_CONSUMER_CAPABILITIES = {
|
|
|
4317
4317
|
compatibility: true,
|
|
4318
4318
|
route_resolution: true,
|
|
4319
4319
|
cli_json_fallback: true,
|
|
4320
|
-
workspace_path_mapping: true
|
|
4320
|
+
workspace_path_mapping: true,
|
|
4321
|
+
workspace_diagnostics: true
|
|
4321
4322
|
};
|
|
4322
4323
|
var MACHINES_CONSUMER_CONTRACT = {
|
|
4323
4324
|
schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
|
|
@@ -4731,6 +4732,170 @@ function inferRepoRoot(workspaceRoot, repoName) {
|
|
|
4731
4732
|
}
|
|
4732
4733
|
return joinPath(root, repoName);
|
|
4733
4734
|
}
|
|
4735
|
+
function shellQuote(value) {
|
|
4736
|
+
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
4737
|
+
}
|
|
4738
|
+
function shellCommand(command) {
|
|
4739
|
+
return command.map(shellQuote).join(" ");
|
|
4740
|
+
}
|
|
4741
|
+
function canCheckPathForMachine(machine, localMachineId) {
|
|
4742
|
+
if (!machine)
|
|
4743
|
+
return false;
|
|
4744
|
+
if (machine.machine_id === localMachineId)
|
|
4745
|
+
return true;
|
|
4746
|
+
return machine.route_hints.some((hint) => hint.kind === "local");
|
|
4747
|
+
}
|
|
4748
|
+
function checkedPathExists(path, check) {
|
|
4749
|
+
if (!path || !check)
|
|
4750
|
+
return null;
|
|
4751
|
+
return existsSync4(path);
|
|
4752
|
+
}
|
|
4753
|
+
function repairHint(input) {
|
|
4754
|
+
const command = [
|
|
4755
|
+
"machines",
|
|
4756
|
+
"workspace",
|
|
4757
|
+
"repair",
|
|
4758
|
+
"--machine",
|
|
4759
|
+
input.machineId,
|
|
4760
|
+
"--project",
|
|
4761
|
+
input.projectId
|
|
4762
|
+
];
|
|
4763
|
+
if (input.repoName)
|
|
4764
|
+
command.push("--repo", input.repoName);
|
|
4765
|
+
if (input.openFilesRepoName)
|
|
4766
|
+
command.push("--open-files-repo", input.openFilesRepoName);
|
|
4767
|
+
command.push("--json");
|
|
4768
|
+
const applyCommand = [...command.slice(0, -1), "--apply", "--json"];
|
|
4769
|
+
return {
|
|
4770
|
+
id: `repair:${input.machineId}:${input.projectId}`,
|
|
4771
|
+
reason: input.reason,
|
|
4772
|
+
command,
|
|
4773
|
+
shell_command: shellCommand(command),
|
|
4774
|
+
apply_command: applyCommand,
|
|
4775
|
+
apply_shell_command: shellCommand(applyCommand)
|
|
4776
|
+
};
|
|
4777
|
+
}
|
|
4778
|
+
function pathDiagnostic(input) {
|
|
4779
|
+
if (!input.path.path) {
|
|
4780
|
+
return {
|
|
4781
|
+
id: input.id,
|
|
4782
|
+
status: "missing",
|
|
4783
|
+
severity: input.required ? "fail" : "warn",
|
|
4784
|
+
message: `${input.label} is unresolved.`,
|
|
4785
|
+
path: null,
|
|
4786
|
+
source: input.path.source,
|
|
4787
|
+
path_exists: null
|
|
4788
|
+
};
|
|
4789
|
+
}
|
|
4790
|
+
if (input.pathExists === false) {
|
|
4791
|
+
return {
|
|
4792
|
+
id: input.id,
|
|
4793
|
+
status: "stale",
|
|
4794
|
+
severity: "fail",
|
|
4795
|
+
message: `${input.label} points to a path that does not exist on this machine.`,
|
|
4796
|
+
path: input.path.path,
|
|
4797
|
+
source: input.path.source,
|
|
4798
|
+
path_exists: false
|
|
4799
|
+
};
|
|
4800
|
+
}
|
|
4801
|
+
if (input.path.source === "inferred") {
|
|
4802
|
+
return {
|
|
4803
|
+
id: input.id,
|
|
4804
|
+
status: "inferred",
|
|
4805
|
+
severity: "warn",
|
|
4806
|
+
message: `${input.label} was inferred from the workspace root; write an explicit manifest mapping for repeatable downstream sync.`,
|
|
4807
|
+
path: input.path.path,
|
|
4808
|
+
source: input.path.source,
|
|
4809
|
+
path_exists: input.pathExists
|
|
4810
|
+
};
|
|
4811
|
+
}
|
|
4812
|
+
return {
|
|
4813
|
+
id: input.id,
|
|
4814
|
+
status: "ok",
|
|
4815
|
+
severity: "ok",
|
|
4816
|
+
message: `${input.label} is explicit enough for downstream sync.`,
|
|
4817
|
+
path: input.path.path,
|
|
4818
|
+
source: input.path.source,
|
|
4819
|
+
path_exists: input.pathExists
|
|
4820
|
+
};
|
|
4821
|
+
}
|
|
4822
|
+
function workspaceDiagnostics(input) {
|
|
4823
|
+
const checkPaths = canCheckPathForMachine(input.machine, input.localMachineId);
|
|
4824
|
+
const diagnostics = [];
|
|
4825
|
+
if (!input.machine) {
|
|
4826
|
+
diagnostics.push({
|
|
4827
|
+
id: "manifest",
|
|
4828
|
+
status: "missing_manifest",
|
|
4829
|
+
severity: "fail",
|
|
4830
|
+
message: "Machine is not present in topology or manifest.",
|
|
4831
|
+
path: null,
|
|
4832
|
+
source: "manifest",
|
|
4833
|
+
path_exists: null
|
|
4834
|
+
});
|
|
4835
|
+
} else if (!input.resolution.evidence.manifest_declared) {
|
|
4836
|
+
diagnostics.push({
|
|
4837
|
+
id: "manifest",
|
|
4838
|
+
status: "missing_manifest",
|
|
4839
|
+
severity: "warn",
|
|
4840
|
+
message: "Machine came from live topology but is not declared in the manifest.",
|
|
4841
|
+
path: null,
|
|
4842
|
+
source: "manifest",
|
|
4843
|
+
path_exists: null
|
|
4844
|
+
});
|
|
4845
|
+
}
|
|
4846
|
+
diagnostics.push(pathDiagnostic({
|
|
4847
|
+
id: "workspace_root",
|
|
4848
|
+
label: "Workspace root",
|
|
4849
|
+
path: input.resolution.paths.workspace_root,
|
|
4850
|
+
pathExists: checkedPathExists(input.resolution.paths.workspace_root.path, checkPaths),
|
|
4851
|
+
required: false
|
|
4852
|
+
}));
|
|
4853
|
+
diagnostics.push(pathDiagnostic({
|
|
4854
|
+
id: "project_root",
|
|
4855
|
+
label: "Project root",
|
|
4856
|
+
path: input.resolution.paths.project_root,
|
|
4857
|
+
pathExists: checkedPathExists(input.resolution.paths.project_root.path, checkPaths),
|
|
4858
|
+
required: true
|
|
4859
|
+
}));
|
|
4860
|
+
diagnostics.push(pathDiagnostic({
|
|
4861
|
+
id: "open_files_root",
|
|
4862
|
+
label: "Open-files root",
|
|
4863
|
+
path: input.resolution.paths.open_files_root,
|
|
4864
|
+
pathExists: checkedPathExists(input.resolution.paths.open_files_root.path, checkPaths),
|
|
4865
|
+
required: false
|
|
4866
|
+
}));
|
|
4867
|
+
if (input.resolution.machine.trust_status !== "trusted") {
|
|
4868
|
+
diagnostics.push({
|
|
4869
|
+
id: "trust",
|
|
4870
|
+
status: "untrusted",
|
|
4871
|
+
severity: "warn",
|
|
4872
|
+
message: `Machine trust status is ${input.resolution.machine.trust_status}; manifest repair apply requires trust or --allow-untrusted.`,
|
|
4873
|
+
path: null,
|
|
4874
|
+
source: "trust",
|
|
4875
|
+
path_exists: null
|
|
4876
|
+
});
|
|
4877
|
+
}
|
|
4878
|
+
if (input.resolution.machine.auth_status !== "authenticated") {
|
|
4879
|
+
diagnostics.push({
|
|
4880
|
+
id: "auth",
|
|
4881
|
+
status: "unknown_auth",
|
|
4882
|
+
severity: "warn",
|
|
4883
|
+
message: `Machine auth status is ${input.resolution.machine.auth_status}; remote sync may still fail if SSH is unavailable.`,
|
|
4884
|
+
path: null,
|
|
4885
|
+
source: "auth",
|
|
4886
|
+
path_exists: null
|
|
4887
|
+
});
|
|
4888
|
+
}
|
|
4889
|
+
const needsRepair = diagnostics.some((entry) => (entry.id === "project_root" || entry.id === "open_files_root") && (entry.status === "missing" || entry.status === "inferred" || entry.status === "stale"));
|
|
4890
|
+
const repairHints = needsRepair ? [repairHint({
|
|
4891
|
+
machineId: input.resolution.machine_id ?? input.resolution.requested_machine_id,
|
|
4892
|
+
projectId: input.resolution.project.project_id,
|
|
4893
|
+
repoName: input.resolution.project.repo_name,
|
|
4894
|
+
openFilesRepoName: input.openFilesRepoName,
|
|
4895
|
+
reason: "Write explicit workspace_paths and open_files_roots manifest metadata."
|
|
4896
|
+
})] : [];
|
|
4897
|
+
return { diagnostics, repairHints };
|
|
4898
|
+
}
|
|
4734
4899
|
function projectPathFromMetadata(metadata, projectId, repoName) {
|
|
4735
4900
|
const keys = [projectId, repoName].filter((value) => Boolean(value));
|
|
4736
4901
|
return readMappedPath({
|
|
@@ -4806,7 +4971,7 @@ function resolveMachineWorkspace(options) {
|
|
|
4806
4971
|
const openFilesRepoName = options.openFilesRepoName ?? "open-files";
|
|
4807
4972
|
if (!machine) {
|
|
4808
4973
|
warnings.push(`machine_not_found:${options.machineId}`);
|
|
4809
|
-
|
|
4974
|
+
const resolution2 = {
|
|
4810
4975
|
schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
|
|
4811
4976
|
package: topology.package,
|
|
4812
4977
|
ok: false,
|
|
@@ -4820,6 +4985,8 @@ function resolveMachineWorkspace(options) {
|
|
|
4820
4985
|
project_root: { path: null, source: "unresolved" },
|
|
4821
4986
|
open_files_root: { path: null, source: "unresolved" }
|
|
4822
4987
|
},
|
|
4988
|
+
diagnostics: [],
|
|
4989
|
+
repair_hints: [],
|
|
4823
4990
|
evidence: {
|
|
4824
4991
|
topology: true,
|
|
4825
4992
|
matched_by: matchedBy,
|
|
@@ -4828,6 +4995,17 @@ function resolveMachineWorkspace(options) {
|
|
|
4828
4995
|
},
|
|
4829
4996
|
warnings
|
|
4830
4997
|
};
|
|
4998
|
+
const diagnostics2 = workspaceDiagnostics({
|
|
4999
|
+
machine,
|
|
5000
|
+
localMachineId: topology.local_machine_id,
|
|
5001
|
+
resolution: resolution2,
|
|
5002
|
+
openFilesRepoName
|
|
5003
|
+
});
|
|
5004
|
+
return {
|
|
5005
|
+
...resolution2,
|
|
5006
|
+
diagnostics: diagnostics2.diagnostics,
|
|
5007
|
+
repair_hints: diagnostics2.repairHints
|
|
5008
|
+
};
|
|
4831
5009
|
}
|
|
4832
5010
|
const metadata = machine.metadata;
|
|
4833
5011
|
const workspaceRootPath = options.workspaceRoot ?? machine.workspace_path;
|
|
@@ -4846,7 +5024,7 @@ function resolveMachineWorkspace(options) {
|
|
|
4846
5024
|
warnings.push(`open_files_root_inferred:${options.projectId}`);
|
|
4847
5025
|
if (!projectRootPath)
|
|
4848
5026
|
warnings.push(`project_root_unresolved:${options.projectId}`);
|
|
4849
|
-
|
|
5027
|
+
const resolution = {
|
|
4850
5028
|
schema_version: MACHINES_CONSUMER_CONTRACT_VERSION,
|
|
4851
5029
|
package: topology.package,
|
|
4852
5030
|
ok: Boolean(projectRootPath),
|
|
@@ -4869,6 +5047,8 @@ function resolveMachineWorkspace(options) {
|
|
|
4869
5047
|
project_root: { path: projectRootPath, source: projectRootSource },
|
|
4870
5048
|
open_files_root: { path: openFilesRootPath, source: openFilesRootSource }
|
|
4871
5049
|
},
|
|
5050
|
+
diagnostics: [],
|
|
5051
|
+
repair_hints: [],
|
|
4872
5052
|
evidence: {
|
|
4873
5053
|
topology: true,
|
|
4874
5054
|
matched_by: matchedBy,
|
|
@@ -4877,6 +5057,17 @@ function resolveMachineWorkspace(options) {
|
|
|
4877
5057
|
},
|
|
4878
5058
|
warnings
|
|
4879
5059
|
};
|
|
5060
|
+
const diagnostics = workspaceDiagnostics({
|
|
5061
|
+
machine,
|
|
5062
|
+
localMachineId: topology.local_machine_id,
|
|
5063
|
+
resolution,
|
|
5064
|
+
openFilesRepoName
|
|
5065
|
+
});
|
|
5066
|
+
return {
|
|
5067
|
+
...resolution,
|
|
5068
|
+
diagnostics: diagnostics.diagnostics,
|
|
5069
|
+
repair_hints: diagnostics.repairHints
|
|
5070
|
+
};
|
|
4880
5071
|
}
|
|
4881
5072
|
function getLocalMachineTopology(options = {}) {
|
|
4882
5073
|
const topology = discoverMachineTopology(options);
|
|
@@ -4902,7 +5093,7 @@ import { spawnSync as spawnSync2 } from "child_process";
|
|
|
4902
5093
|
import { hostname as hostname4 } from "os";
|
|
4903
5094
|
|
|
4904
5095
|
// src/commands/ssh.ts
|
|
4905
|
-
function
|
|
5096
|
+
function shellQuote2(value) {
|
|
4906
5097
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
4907
5098
|
}
|
|
4908
5099
|
function resolveSshTarget(machineId, options = {}) {
|
|
@@ -4923,11 +5114,11 @@ function resolveSshTarget(machineId, options = {}) {
|
|
|
4923
5114
|
}
|
|
4924
5115
|
function buildSshCommand(machineId, remoteCommand, options = {}) {
|
|
4925
5116
|
const resolved = resolveSshTarget(machineId, options);
|
|
4926
|
-
return remoteCommand ? `ssh ${resolved.target} ${
|
|
5117
|
+
return remoteCommand ? `ssh ${resolved.target} ${shellQuote2(remoteCommand)}` : `ssh ${resolved.target}`;
|
|
4927
5118
|
}
|
|
4928
5119
|
|
|
4929
5120
|
// src/remote.ts
|
|
4930
|
-
function
|
|
5121
|
+
function shellQuote3(value) {
|
|
4931
5122
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
4932
5123
|
}
|
|
4933
5124
|
function machineIsLocal(machineId, localMachineId) {
|
|
@@ -4945,7 +5136,7 @@ function resolveMachineCommand(machineId, command, localMachineId = getLocalMach
|
|
|
4945
5136
|
} catch (error) {
|
|
4946
5137
|
const message = String(error.message ?? error);
|
|
4947
5138
|
if (message.includes("Machine route not found") || message.includes("Machine not found in manifest")) {
|
|
4948
|
-
return { source: "ssh", shellCommand: `ssh ${
|
|
5139
|
+
return { source: "ssh", shellCommand: `ssh ${shellQuote3(machineId)} ${shellQuote3(command)}` };
|
|
4949
5140
|
}
|
|
4950
5141
|
throw error;
|
|
4951
5142
|
}
|
|
@@ -4973,7 +5164,7 @@ var DEFAULT_COMMANDS = [
|
|
|
4973
5164
|
function defaultPackages() {
|
|
4974
5165
|
return [{ name: "@hasna/machines", command: "machines", expectedVersion: getPackageVersion(), required: true }];
|
|
4975
5166
|
}
|
|
4976
|
-
function
|
|
5167
|
+
function shellQuote4(value) {
|
|
4977
5168
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
4978
5169
|
}
|
|
4979
5170
|
function commandId(value) {
|
|
@@ -5024,7 +5215,7 @@ function defaultRunner2(machineId, command) {
|
|
|
5024
5215
|
return runMachineCommand(machineId, command);
|
|
5025
5216
|
}
|
|
5026
5217
|
function inspectCommand(machineId, spec, runner) {
|
|
5027
|
-
const command =
|
|
5218
|
+
const command = shellQuote4(spec.command);
|
|
5028
5219
|
const versionArgs = spec.versionArgs ?? "--version";
|
|
5029
5220
|
const script = [
|
|
5030
5221
|
`cmd=${command}`,
|
|
@@ -5053,7 +5244,7 @@ function fieldCommand(field) {
|
|
|
5053
5244
|
}
|
|
5054
5245
|
function inspectWorkspace(machineId, spec, runner) {
|
|
5055
5246
|
const script = [
|
|
5056
|
-
`path=${
|
|
5247
|
+
`path=${shellQuote4(spec.path)}`,
|
|
5057
5248
|
'printf "exists=%s\\n" "$(test -d "$path" && printf yes || printf no)"',
|
|
5058
5249
|
'pkg="$path/package.json"',
|
|
5059
5250
|
'printf "package_json=%s\\n" "$(test -f "$pkg" && printf yes || printf no)"',
|
package/dist/index.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export * from "./commands/setup.js";
|
|
|
23
23
|
export * from "./commands/ssh.js";
|
|
24
24
|
export * from "./commands/sync.js";
|
|
25
25
|
export * from "./commands/status.js";
|
|
26
|
+
export * from "./commands/workspace.js";
|
|
26
27
|
export * from "./mcp/server.js";
|
|
27
28
|
export { MACHINES_STORAGE_ENV, MACHINES_STORAGE_FALLBACK_ENV, MACHINES_STORAGE_MODE_ENV, MACHINES_STORAGE_MODE_FALLBACK_ENV, MACHINES_STORAGE_TABLES, STORAGE_DATABASE_ENV, STORAGE_MODE_ENV, STORAGE_TABLES, getStorageDatabaseEnv, getStorageDatabaseEnvName, getStorageDatabaseUrl, getStorageMode, getStoragePg, getStorageStatus, getSyncMetaAll, parseStorageTables, resolveTables, runStorageMigrations, storagePull, storagePush, storageSync, } from "./storage.js";
|
|
28
29
|
export type { StorageEnv, StorageMode, StorageStatus, SyncMeta, SyncResult as StorageSyncResult } from "./storage.js";
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,yBAAyB,EACzB,kCAAkC,EAClC,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtH,cAAc,cAAc,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,YAAY,CAAC;AAC3B,cAAc,0BAA0B,CAAC;AACzC,cAAc,YAAY,CAAC;AAC3B,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,oBAAoB,CAAC;AACnC,cAAc,oBAAoB,CAAC;AACnC,cAAc,mBAAmB,CAAC;AAClC,cAAc,sBAAsB,CAAC;AACrC,cAAc,wBAAwB,CAAC;AACvC,cAAc,oBAAoB,CAAC;AACnC,cAAc,8BAA8B,CAAC;AAC7C,cAAc,iCAAiC,CAAC;AAChD,cAAc,6BAA6B,CAAC;AAC5C,cAAc,qBAAqB,CAAC;AACpC,cAAc,yBAAyB,CAAC;AACxC,cAAc,qBAAqB,CAAC;AACpC,cAAc,qBAAqB,CAAC;AACpC,cAAc,mBAAmB,CAAC;AAClC,cAAc,oBAAoB,CAAC;AACnC,cAAc,sBAAsB,CAAC;AACrC,cAAc,yBAAyB,CAAC;AACxC,cAAc,iBAAiB,CAAC;AAChC,OAAO,EACL,oBAAoB,EACpB,6BAA6B,EAC7B,yBAAyB,EACzB,kCAAkC,EAClC,uBAAuB,EACvB,oBAAoB,EACpB,gBAAgB,EAChB,cAAc,EACd,qBAAqB,EACrB,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,YAAY,EACZ,gBAAgB,EAChB,cAAc,EACd,kBAAkB,EAClB,aAAa,EACb,oBAAoB,EACpB,WAAW,EACX,WAAW,EACX,WAAW,GACZ,MAAM,cAAc,CAAC;AACtB,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,IAAI,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACtH,cAAc,cAAc,CAAC"}
|