adjacent-cli 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/CHANGELOG.md +15 -0
  2. package/LICENSE +21 -0
  3. package/README.md +48 -0
  4. package/dist/arguments.d.ts +54 -0
  5. package/dist/arguments.d.ts.map +1 -0
  6. package/dist/arguments.js +68 -0
  7. package/dist/arguments.js.map +1 -0
  8. package/dist/bin.d.ts +3 -0
  9. package/dist/bin.d.ts.map +1 -0
  10. package/dist/bin.js +140 -0
  11. package/dist/bin.js.map +1 -0
  12. package/dist/checks.d.ts +35 -0
  13. package/dist/checks.d.ts.map +1 -0
  14. package/dist/checks.js +206 -0
  15. package/dist/checks.js.map +1 -0
  16. package/dist/create.d.ts +42 -0
  17. package/dist/create.d.ts.map +1 -0
  18. package/dist/create.js +82 -0
  19. package/dist/create.js.map +1 -0
  20. package/dist/dependencies.d.ts +59 -0
  21. package/dist/dependencies.d.ts.map +1 -0
  22. package/dist/dependencies.js +100 -0
  23. package/dist/dependencies.js.map +1 -0
  24. package/dist/destination.d.ts +16 -0
  25. package/dist/destination.d.ts.map +1 -0
  26. package/dist/destination.js +39 -0
  27. package/dist/destination.js.map +1 -0
  28. package/dist/dev-channel.d.ts +40 -0
  29. package/dist/dev-channel.d.ts.map +1 -0
  30. package/dist/dev-channel.js +192 -0
  31. package/dist/dev-channel.js.map +1 -0
  32. package/dist/dev.d.ts +3 -0
  33. package/dist/dev.d.ts.map +1 -0
  34. package/dist/dev.js +12 -0
  35. package/dist/dev.js.map +1 -0
  36. package/dist/doctor.d.ts +46 -0
  37. package/dist/doctor.d.ts.map +1 -0
  38. package/dist/doctor.js +52 -0
  39. package/dist/doctor.js.map +1 -0
  40. package/dist/edits.d.ts +26 -0
  41. package/dist/edits.d.ts.map +1 -0
  42. package/dist/edits.js +101 -0
  43. package/dist/edits.js.map +1 -0
  44. package/dist/index.d.ts +13 -0
  45. package/dist/index.d.ts.map +1 -0
  46. package/dist/index.js +18 -0
  47. package/dist/index.js.map +1 -0
  48. package/dist/init.d.ts +62 -0
  49. package/dist/init.d.ts.map +1 -0
  50. package/dist/init.js +275 -0
  51. package/dist/init.js.map +1 -0
  52. package/dist/keys.d.ts +14 -0
  53. package/dist/keys.d.ts.map +1 -0
  54. package/dist/keys.js +66 -0
  55. package/dist/keys.js.map +1 -0
  56. package/dist/package-manager.d.ts +40 -0
  57. package/dist/package-manager.d.ts.map +1 -0
  58. package/dist/package-manager.js +98 -0
  59. package/dist/package-manager.js.map +1 -0
  60. package/dist/process.d.ts +33 -0
  61. package/dist/process.d.ts.map +1 -0
  62. package/dist/process.js +95 -0
  63. package/dist/process.js.map +1 -0
  64. package/dist/project-name.d.ts +30 -0
  65. package/dist/project-name.d.ts.map +1 -0
  66. package/dist/project-name.js +73 -0
  67. package/dist/project-name.js.map +1 -0
  68. package/dist/reporter.d.ts +12 -0
  69. package/dist/reporter.d.ts.map +1 -0
  70. package/dist/reporter.js +11 -0
  71. package/dist/reporter.js.map +1 -0
  72. package/dist/rewrite.d.ts +54 -0
  73. package/dist/rewrite.d.ts.map +1 -0
  74. package/dist/rewrite.js +262 -0
  75. package/dist/rewrite.js.map +1 -0
  76. package/dist/shutdown.d.ts +24 -0
  77. package/dist/shutdown.d.ts.map +1 -0
  78. package/dist/shutdown.js +67 -0
  79. package/dist/shutdown.js.map +1 -0
  80. package/dist/survey.d.ts +33 -0
  81. package/dist/survey.d.ts.map +1 -0
  82. package/dist/survey.js +94 -0
  83. package/dist/survey.js.map +1 -0
  84. package/dist/template.d.ts +29 -0
  85. package/dist/template.d.ts.map +1 -0
  86. package/dist/template.js +77 -0
  87. package/dist/template.js.map +1 -0
  88. package/dist/ui.d.ts +14 -0
  89. package/dist/ui.d.ts.map +1 -0
  90. package/dist/ui.js +50 -0
  91. package/dist/ui.js.map +1 -0
  92. package/package.json +65 -0
  93. package/templates/adjacent/app/manifest.ts +5 -0
  94. package/templates/adjacent/app/sw.js/route.ts +5 -0
  95. package/templates/adjacent/app.config.ts +21 -0
  96. package/templates/adjacent/components/navigation.tsx +46 -0
  97. package/templates/adjacent/public/apple-touch-icon.png +0 -0
  98. package/templates/adjacent/public/favicon-96x96.png +0 -0
  99. package/templates/adjacent/public/favicon.ico +0 -0
  100. package/templates/adjacent/public/favicon.svg +4 -0
  101. package/templates/adjacent/public/web-app-manifest-192x192.png +0 -0
  102. package/templates/adjacent/public/web-app-manifest-512x512.png +0 -0
  103. package/templates/adjacent/public/web-app-manifest-maskable-192x192.png +0 -0
  104. package/templates/adjacent/public/web-app-manifest-maskable-512x512.png +0 -0
  105. package/templates/starter/app/(app)/layout.tsx +12 -0
  106. package/templates/starter/app/(app)/page.tsx +75 -0
  107. package/templates/starter/app/(app)/settings/page.tsx +24 -0
  108. package/templates/starter/app/(app)/settings/settings-panel.tsx +54 -0
package/dist/init.js ADDED
@@ -0,0 +1,275 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { dirname, join, relative, resolve, sep } from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { ADJACENT_PACKAGES, matchesWorkspaceGlob, resolveAdjacentDependencies, } from "./dependencies.js";
5
+ import { createProjectEdits } from "./edits.js";
6
+ import { resolvePackageManager, } from "./package-manager.js";
7
+ import { runInheritedCommand } from "./process.js";
8
+ import { TERMINAL_REPORTER } from "./reporter.js";
9
+ import { createNextConfig, injectAdjacentStyles, wrapNextConfig, wrapRootLayout, } from "./rewrite.js";
10
+ import { renderTemplateTree } from "./template.js";
11
+ import { surveyProject } from "./survey.js";
12
+ function moduleDirectory() {
13
+ return dirname(fileURLToPath(import.meta.url));
14
+ }
15
+ export function defaultTemplatesRoot(from = moduleDirectory()) {
16
+ return resolve(from, "..", "templates");
17
+ }
18
+ /**
19
+ * Finds the framework's `packages/` directory when this CLI runs from a
20
+ * checkout, so a generated application can depend on the local sources. Returns
21
+ * nothing once the CLI is installed from a registry.
22
+ */
23
+ export async function findWorkspacePackagesRoot(from = moduleDirectory()) {
24
+ let current = resolve(from);
25
+ while (true) {
26
+ // A directory name alone is not distinctive, so the manifest inside it
27
+ // has to be the one this CLI expects before the checkout counts as ours.
28
+ const candidate = join(current, "packages", "adjacent-core", "package.json");
29
+ const manifest = await readFile(candidate, "utf8").catch(() => undefined);
30
+ if (manifest !== undefined) {
31
+ const parsed = JSON.parse(manifest);
32
+ if (parsed.name === "adjacent-core")
33
+ return join(current, "packages");
34
+ }
35
+ const parent = dirname(current);
36
+ if (parent === current)
37
+ return undefined;
38
+ current = parent;
39
+ }
40
+ }
41
+ /**
42
+ * Whether a project sits inside the framework's own Bun workspace. A member is
43
+ * linked with `workspace:*`, which is the only form that survives a clean
44
+ * checkout: Bun resolves it, so the framework's packages find each other
45
+ * wherever they are installed from.
46
+ */
47
+ export async function isWorkspaceMember(workspaceRoot, projectRoot) {
48
+ const raw = await readFile(join(workspaceRoot, "package.json"), "utf8").catch(() => undefined);
49
+ if (raw === undefined)
50
+ return false;
51
+ let globs = [];
52
+ try {
53
+ const manifest = JSON.parse(raw);
54
+ if (Array.isArray(manifest.workspaces)) {
55
+ globs = manifest.workspaces.filter((glob) => typeof glob === "string");
56
+ }
57
+ }
58
+ catch {
59
+ return false;
60
+ }
61
+ const location = relative(workspaceRoot, projectRoot).split(sep).join("/");
62
+ if (location === "" || location.startsWith(".."))
63
+ return false;
64
+ return globs.some((glob) => matchesWorkspaceGlob(location, glob));
65
+ }
66
+ /**
67
+ * Adds the Adjacent packages to an existing manifest, leaving every other field
68
+ * alone. A `typecheck` script is added only when the project has none.
69
+ */
70
+ export function addAdjacentDependencies(manifest, dependencies) {
71
+ const existing = typeof manifest.dependencies === "object" && manifest.dependencies !== null
72
+ ? manifest.dependencies
73
+ : {};
74
+ const scripts = typeof manifest.scripts === "object" && manifest.scripts !== null
75
+ ? manifest.scripts
76
+ : {};
77
+ const merged = {
78
+ ...manifest,
79
+ dependencies: Object.fromEntries(Object.entries({ ...existing, ...dependencies.dependencies }).sort(([a], [b]) => a.localeCompare(b))),
80
+ // `next typegen` first, because Next.js generates the route types the App
81
+ // Router relies on (LayoutProps and friends) and tsc cannot see them until
82
+ // it has run at least once.
83
+ scripts: {
84
+ ...scripts,
85
+ ...(scripts.typecheck ? null : { typecheck: "next typegen && tsc --noEmit" }),
86
+ },
87
+ };
88
+ if (dependencies.overrides) {
89
+ const configured = typeof manifest.overrides === "object" && manifest.overrides !== null
90
+ ? manifest.overrides
91
+ : {};
92
+ merged.overrides = { ...configured, ...dependencies.overrides };
93
+ }
94
+ return merged;
95
+ }
96
+ async function installDependencies(root, options = {}) {
97
+ const manager = await resolvePackageManager({ projectRoot: root });
98
+ const { args, command } = manager.install(options);
99
+ await runInheritedCommand(command, args, { cwd: root }).catch((error) => {
100
+ const detail = error instanceof Error ? error.message : String(error);
101
+ throw new Error(`Could not install dependencies in ${root}: ${detail}\n` +
102
+ `Adjacent was added to the project. Install by hand with: ${command} ${args.join(" ")}`);
103
+ });
104
+ }
105
+ async function applyRewrite({ edits, file, manual, outcome, }) {
106
+ if (outcome.kind === "rewritten") {
107
+ await edits.rewriteFile(file, outcome.contents);
108
+ return;
109
+ }
110
+ if (outcome.kind === "manual") {
111
+ manual.push({ file, instruction: outcome.instruction });
112
+ }
113
+ }
114
+ /**
115
+ * Adds Adjacent to an existing Next.js App Router application: the files it
116
+ * needs, the wrapping of the two files the application owns, and the packages
117
+ * it depends on. Anything that cannot be rewritten safely is reported instead.
118
+ */
119
+ export async function runInit(options, ports = {}) {
120
+ const report = ports.reporter ?? TERMINAL_REPORTER;
121
+ const root = resolve(options.projectRoot);
122
+ const survey = await surveyProject(root);
123
+ const templatesRoot = ports.templatesRoot ?? defaultTemplatesRoot();
124
+ const manager = await resolvePackageManager({ projectRoot: root });
125
+ const packagesRoot = await findWorkspacePackagesRoot();
126
+ const dependencies = ports.dependencies ??
127
+ resolveAdjacentDependencies({
128
+ ...(packagesRoot === undefined ? null : { packagesRoot }),
129
+ projectRoot: root,
130
+ workspaceMember: packagesRoot !== undefined &&
131
+ (await isWorkspaceMember(dirname(packagesRoot), root)),
132
+ });
133
+ const installOptions = { isolated: dependencies.pathLinked };
134
+ const edits = createProjectEdits(root);
135
+ const manual = [];
136
+ // `src/app` means the project keeps its sources under `src/`, so anything
137
+ // Adjacent adds beside the app directory belongs there too.
138
+ const sourceRoot = dirname(survey.appDirectory);
139
+ const relocate = (path) => sourceRoot === "." ? path : join(sourceRoot, path);
140
+ try {
141
+ // app.config.ts stays at the project root while everything else follows the
142
+ // app directory, so a project keeping its sources under src/ needs one more
143
+ // level than one that does not.
144
+ const configFromApp = sourceRoot === "." ? "../app.config" : "../../app.config";
145
+ const values = {
146
+ appName: survey.identity.appName,
147
+ configFromApp,
148
+ configFromRoute: `../${configFromApp}`,
149
+ packageName: survey.identity.packageName,
150
+ shortName: survey.identity.shortName,
151
+ slug: survey.identity.slug,
152
+ };
153
+ const injected = await renderTemplateTree({
154
+ relocate: (path) =>
155
+ // app.config.ts and public/ stay at the project root; the rest follows
156
+ // the app directory.
157
+ path === "app.config.ts" || path.startsWith("public/")
158
+ ? path
159
+ : relocate(path),
160
+ sink: (path, contents) => edits.addFile(path, contents),
161
+ templateRoot: join(templatesRoot, "adjacent"),
162
+ values,
163
+ });
164
+ // Nothing Adjacent injects overwrites a file that is already there, so an
165
+ // application with its own components/navigation.tsx keeps it and never
166
+ // receives Adjacent's. Silently importing the wrong component from the
167
+ // layout is the one outcome worth refusing, so say so instead.
168
+ const navigationFile = relocate("components/navigation.tsx");
169
+ if (!injected.includes(navigationFile)) {
170
+ manual.push({
171
+ file: navigationFile,
172
+ instruction: "A file of this name already exists, so Adjacent's navigation was " +
173
+ "not written and nothing here imports it yet.\n\n" +
174
+ "Either rename the existing file and run `adj init` again, or build " +
175
+ "the navigation yourself with `Tabs` and `Tab` from `adjacent-ui`, " +
176
+ "and render it through the `navigation` prop of `NavigationShell`.",
177
+ });
178
+ }
179
+ if (options.scaffold) {
180
+ await renderTemplateTree({
181
+ relocate,
182
+ sink: (path, contents) => edits.addFile(path, contents),
183
+ templateRoot: join(templatesRoot, "starter"),
184
+ values,
185
+ });
186
+ // The starter route group owns the index route, so the placeholder page
187
+ // create-next-app wrote is removed rather than left to conflict with it.
188
+ await edits.removeFile(join(survey.appDirectory, "page.tsx"));
189
+ }
190
+ const nextConfigFile = survey.nextConfigFile ?? "next.config.ts";
191
+ const nextConfigSource = await edits.readFile(nextConfigFile);
192
+ if (nextConfigSource === undefined) {
193
+ await edits.addFile(nextConfigFile, createNextConfig());
194
+ }
195
+ else {
196
+ await applyRewrite({
197
+ edits,
198
+ file: nextConfigFile,
199
+ manual,
200
+ outcome: wrapNextConfig(nextConfigSource),
201
+ });
202
+ }
203
+ const layoutSource = await edits.readFile(survey.layoutFile);
204
+ if (layoutSource !== undefined) {
205
+ await applyRewrite({
206
+ edits,
207
+ file: survey.layoutFile,
208
+ manual,
209
+ outcome: wrapRootLayout(layoutSource, {
210
+ configImportPath: sourceRoot === "." ? "../app.config" : "../../app.config",
211
+ scaffolded: options.scaffold === true,
212
+ }),
213
+ });
214
+ }
215
+ if (survey.globalsCss) {
216
+ const styles = await edits.readFile(survey.globalsCss);
217
+ if (styles !== undefined) {
218
+ await applyRewrite({
219
+ edits,
220
+ file: survey.globalsCss,
221
+ manual,
222
+ outcome: injectAdjacentStyles(styles, { tailwind: survey.hasTailwind }),
223
+ });
224
+ }
225
+ }
226
+ await edits.rewriteFile("package.json", `${JSON.stringify(addAdjacentDependencies(survey.packageJson, dependencies), null, 2)}\n`);
227
+ }
228
+ catch (error) {
229
+ await edits.rollback();
230
+ const detail = error instanceof Error ? error.message : String(error);
231
+ throw new Error(`Could not add Adjacent to ${root}: ${detail}`);
232
+ }
233
+ const summary = edits.summary();
234
+ report.success(`Added ${summary.added.length} file${summary.added.length === 1 ? "" : "s"} and updated ${summary.rewritten.length}`);
235
+ let installed = false;
236
+ if (options.install) {
237
+ report.step("Installing dependencies with Bun");
238
+ await (ports.install ?? installDependencies)(root, installOptions);
239
+ installed = true;
240
+ report.success("Installed dependencies");
241
+ }
242
+ for (const step of manual) {
243
+ report.step(`${step.file} needs one edit by hand:\n\n${step.instruction}\n`);
244
+ }
245
+ return {
246
+ added: summary.added,
247
+ installed,
248
+ installOptions,
249
+ manual,
250
+ packageManager: manager,
251
+ rewritten: summary.rewritten,
252
+ root,
253
+ survey,
254
+ };
255
+ }
256
+ /** `adj init` as a command: the injection, framed with progress and next steps. */
257
+ export async function runInitCommand(options, ports = {}) {
258
+ const report = ports.reporter ?? TERMINAL_REPORTER;
259
+ report.intro("Adjacent");
260
+ const result = await runInit(options, { ...ports, reporter: report });
261
+ const install = result.packageManager.install(result.installOptions);
262
+ const dev = result.packageManager.run("dev");
263
+ const steps = [
264
+ ...(result.installed ? [] : [`${install.command} ${install.args.join(" ")}`]),
265
+ `${dev.command} ${dev.args.join(" ")}`,
266
+ "adj dev --android",
267
+ ];
268
+ report.step(`Next steps:\n${steps.map((command) => ` ${command}`).join("\n")}`);
269
+ report.outro(result.manual.length === 0
270
+ ? `${result.survey.identity.appName} is an Adjacent app.`
271
+ : `${result.survey.identity.appName} needs the ${result.manual.length} edit${result.manual.length === 1 ? "" : "s"} above.`);
272
+ return result;
273
+ }
274
+ export { ADJACENT_PACKAGES };
275
+ //# sourceMappingURL=init.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../src/init.ts"],"names":[],"mappings":"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"}
package/dist/keys.d.ts ADDED
@@ -0,0 +1,14 @@
1
+ import { type DevCommand } from "./dev-channel.js";
2
+ export type KeyAction = "clear-cache" | "help" | "interrupt" | "open" | "quit" | "reload";
3
+ export declare function resolveKeyAction(key: string): KeyAction | undefined;
4
+ export declare function commandForAction(action: KeyAction): DevCommand | undefined;
5
+ export declare const KEY_HELP = "Press r to reload, c to clear caches and reload, o to reopen on the device, q to quit.";
6
+ export interface KeyHandlers {
7
+ readonly onInterrupt: () => void;
8
+ readonly onOpen: () => Promise<void>;
9
+ readonly onQuit: () => void;
10
+ readonly onSend: (command: DevCommand) => Promise<void>;
11
+ readonly onShowHelp: () => void;
12
+ }
13
+ export declare function watchKeys(handlers: KeyHandlers): () => void;
14
+ //# sourceMappingURL=keys.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.d.ts","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAe,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEhE,MAAM,MAAM,SAAS,GACjB,aAAa,GACb,MAAM,GACN,WAAW,GACX,MAAM,GACN,MAAM,GACN,QAAQ,CAAC;AAKb,wBAAgB,gBAAgB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,SAAS,CAQnE;AAED,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,SAAS,GAAG,UAAU,GAAG,SAAS,CAI1E;AAED,eAAO,MAAM,QAAQ,2FACqE,CAAC;AAE3F,MAAM,WAAW,WAAW;IAC1B,QAAQ,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;IACjC,QAAQ,CAAC,MAAM,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,QAAQ,CAAC,MAAM,EAAE,MAAM,IAAI,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,UAAU,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACxD,QAAQ,CAAC,UAAU,EAAE,MAAM,IAAI,CAAC;CACjC;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,IAAI,CAsC3D"}
package/dist/keys.js ADDED
@@ -0,0 +1,66 @@
1
+ import { DEV_COMMAND } from "./dev-channel.js";
2
+ const END_OF_TEXT = "\u0003";
3
+ const END_OF_TRANSMISSION = "\u0004";
4
+ export function resolveKeyAction(key) {
5
+ if (key === END_OF_TEXT)
6
+ return "interrupt";
7
+ if (key === END_OF_TRANSMISSION || key === "q")
8
+ return "quit";
9
+ if (key === "r")
10
+ return "reload";
11
+ if (key === "c")
12
+ return "clear-cache";
13
+ if (key === "o")
14
+ return "open";
15
+ if (key === "?" || key === "h")
16
+ return "help";
17
+ return undefined;
18
+ }
19
+ export function commandForAction(action) {
20
+ if (action === "reload")
21
+ return { type: DEV_COMMAND.reload };
22
+ if (action === "clear-cache")
23
+ return { type: DEV_COMMAND.clearCache };
24
+ return undefined;
25
+ }
26
+ export const KEY_HELP = "Press r to reload, c to clear caches and reload, o to reopen on the device, q to quit.";
27
+ export function watchKeys(handlers) {
28
+ const input = process.stdin;
29
+ if (!input.isTTY)
30
+ return () => undefined;
31
+ input.setRawMode(true);
32
+ input.resume();
33
+ input.setEncoding("utf8");
34
+ const onData = (key) => {
35
+ const action = resolveKeyAction(key);
36
+ if (action === undefined)
37
+ return;
38
+ if (action === "interrupt") {
39
+ handlers.onInterrupt();
40
+ return;
41
+ }
42
+ if (action === "quit") {
43
+ handlers.onQuit();
44
+ return;
45
+ }
46
+ if (action === "help") {
47
+ handlers.onShowHelp();
48
+ return;
49
+ }
50
+ if (action === "open") {
51
+ void handlers.onOpen();
52
+ return;
53
+ }
54
+ const command = commandForAction(action);
55
+ if (command)
56
+ void handlers.onSend(command);
57
+ };
58
+ input.on("data", onData);
59
+ return () => {
60
+ input.off("data", onData);
61
+ if (input.isTTY)
62
+ input.setRawMode(false);
63
+ input.pause();
64
+ };
65
+ }
66
+ //# sourceMappingURL=keys.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"keys.js","sourceRoot":"","sources":["../src/keys.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAmB,MAAM,kBAAkB,CAAC;AAUhE,MAAM,WAAW,GAAG,QAAQ,CAAC;AAC7B,MAAM,mBAAmB,GAAG,QAAQ,CAAC;AAErC,MAAM,UAAU,gBAAgB,CAAC,GAAW;IAC1C,IAAI,GAAG,KAAK,WAAW;QAAE,OAAO,WAAW,CAAC;IAC5C,IAAI,GAAG,KAAK,mBAAmB,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IAC9D,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,QAAQ,CAAC;IACjC,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,aAAa,CAAC;IACtC,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IAC/B,IAAI,GAAG,KAAK,GAAG,IAAI,GAAG,KAAK,GAAG;QAAE,OAAO,MAAM,CAAC;IAC9C,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,MAAiB;IAChD,IAAI,MAAM,KAAK,QAAQ;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,MAAM,EAAE,CAAC;IAC7D,IAAI,MAAM,KAAK,aAAa;QAAE,OAAO,EAAE,IAAI,EAAE,WAAW,CAAC,UAAU,EAAE,CAAC;IACtE,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,CAAC,MAAM,QAAQ,GACnB,wFAAwF,CAAC;AAU3F,MAAM,UAAU,SAAS,CAAC,QAAqB;IAC7C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IAC5B,IAAI,CAAC,KAAK,CAAC,KAAK;QAAE,OAAO,GAAG,EAAE,CAAC,SAAS,CAAC;IAEzC,KAAK,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;IACvB,KAAK,CAAC,MAAM,EAAE,CAAC;IACf,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC,CAAC;IAE1B,MAAM,MAAM,GAAG,CAAC,GAAW,EAAQ,EAAE;QACnC,MAAM,MAAM,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;QACrC,IAAI,MAAM,KAAK,SAAS;YAAE,OAAO;QACjC,IAAI,MAAM,KAAK,WAAW,EAAE,CAAC;YAC3B,QAAQ,CAAC,WAAW,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,QAAQ,CAAC,MAAM,EAAE,CAAC;YAClB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,QAAQ,CAAC,UAAU,EAAE,CAAC;YACtB,OAAO;QACT,CAAC;QACD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;YACvB,OAAO;QACT,CAAC;QACD,MAAM,OAAO,GAAG,gBAAgB,CAAC,MAAM,CAAC,CAAC;QACzC,IAAI,OAAO;YAAE,KAAK,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAC7C,CAAC,CAAC;IAEF,KAAK,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAEzB,OAAO,GAAG,EAAE;QACV,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC1B,IAAI,KAAK,CAAC,KAAK;YAAE,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;QACzC,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,40 @@
1
+ export type PackageManagerName = "bun" | "npm" | "pnpm" | "yarn";
2
+ export interface Invocation {
3
+ readonly args: readonly string[];
4
+ readonly command: string;
5
+ }
6
+ export interface InstallOptions {
7
+ /**
8
+ * True when the project depends on Adjacent through `file:` paths. Bun's
9
+ * default hoisted linker copies those into `node_modules`, and Turbopack
10
+ * fails to resolve the copy; the isolated linker symlinks them, which is
11
+ * what Bun did before 1.4 and what every other manager still does.
12
+ */
13
+ readonly isolated?: boolean;
14
+ }
15
+ export interface PackageManager {
16
+ /** Runs a one-off package, the way `npx` and `bunx` do. */
17
+ readonly exec: (specifier: string, args: readonly string[]) => Invocation;
18
+ readonly install: (options?: InstallOptions) => Invocation;
19
+ readonly name: PackageManagerName;
20
+ /** The flag `create-next-app` takes to scaffold with this manager. */
21
+ readonly scaffoldFlag: string;
22
+ readonly run: (script: string, args?: readonly string[]) => Invocation;
23
+ }
24
+ export declare function packageManager(name: PackageManagerName): PackageManager;
25
+ /** Reads the manager out of the `npm_config_user_agent` every manager sets. */
26
+ export declare function parseUserAgent(userAgent: string | undefined): PackageManagerName | undefined;
27
+ /** The manager a project is already using, judged by the lockfile it committed. */
28
+ export declare function detectFromLockfile(projectRoot: string): Promise<PackageManagerName | undefined>;
29
+ export interface ResolvePackageManagerOptions {
30
+ /** Looked at first, so an existing project keeps the manager it already uses. */
31
+ readonly projectRoot?: string;
32
+ readonly userAgent?: string;
33
+ }
34
+ /**
35
+ * Picks the manager to shell out to. A project's own lockfile wins, then
36
+ * whichever manager invoked this command, then bun, then npm. npm is the last
37
+ * resort rather than an error because it ships with Node.
38
+ */
39
+ export declare function resolvePackageManager(options?: ResolvePackageManagerOptions): Promise<PackageManager>;
40
+ //# sourceMappingURL=package-manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../src/package-manager.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,kBAAkB,GAAG,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,QAAQ,CAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,cAAc;IAC7B;;;;;OAKG;IACH,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;CAC7B;AAED,MAAM,WAAW,cAAc;IAC7B,2DAA2D;IAC3D,QAAQ,CAAC,IAAI,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,SAAS,MAAM,EAAE,KAAK,UAAU,CAAC;IAC1E,QAAQ,CAAC,OAAO,EAAE,CAAC,OAAO,CAAC,EAAE,cAAc,KAAK,UAAU,CAAC;IAC3D,QAAQ,CAAC,IAAI,EAAE,kBAAkB,CAAC;IAClC,sEAAsE;IACtE,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,SAAS,MAAM,EAAE,KAAK,UAAU,CAAC;CACxE;AAyDD,wBAAgB,cAAc,CAAC,IAAI,EAAE,kBAAkB,GAAG,cAAc,CAEvE;AAED,+EAA+E;AAC/E,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,GAAG,SAAS,CAM5F;AAED,mFAAmF;AACnF,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,kBAAkB,GAAG,SAAS,CAAC,CAMzC;AASD,MAAM,WAAW,4BAA4B;IAC3C,iFAAiF;IACjF,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED;;;;GAIG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,GAAE,4BAAiC,GACzC,OAAO,CAAC,cAAc,CAAC,CAWzB"}
@@ -0,0 +1,98 @@
1
+ import { stat } from "node:fs/promises";
2
+ import { join } from "node:path";
3
+ import { runCommand } from "./process.js";
4
+ /** The lockfile each manager leaves behind, in the order they are checked. */
5
+ const LOCKFILES = [
6
+ ["bun", "bun.lock"],
7
+ ["bun", "bun.lockb"],
8
+ ["pnpm", "pnpm-lock.yaml"],
9
+ ["yarn", "yarn.lock"],
10
+ ["npm", "package-lock.json"],
11
+ ];
12
+ /**
13
+ * npm, pnpm and yarn need `--` before a script's own arguments; bun and pnpm
14
+ * forward them as they are. Getting this wrong sends `--port` to the manager
15
+ * rather than to the script, which fails in a way that reads like a bug in the
16
+ * script.
17
+ */
18
+ const MANAGERS = {
19
+ bun: {
20
+ exec: (specifier, args) => ({ args: [specifier, ...args], command: "bunx" }),
21
+ install: ({ isolated = false } = {}) => ({
22
+ args: isolated ? ["install", "--linker=isolated"] : ["install"],
23
+ command: "bun",
24
+ }),
25
+ name: "bun",
26
+ run: (script, args = []) => ({ args: ["run", script, ...args], command: "bun" }),
27
+ scaffoldFlag: "--use-bun",
28
+ },
29
+ npm: {
30
+ exec: (specifier, args) => ({
31
+ args: ["--yes", specifier, ...args],
32
+ command: "npx",
33
+ }),
34
+ install: () => ({ args: ["install"], command: "npm" }),
35
+ name: "npm",
36
+ run: (script, args = []) => ({
37
+ args: ["run", script, ...(args.length > 0 ? ["--", ...args] : [])],
38
+ command: "npm",
39
+ }),
40
+ scaffoldFlag: "--use-npm",
41
+ },
42
+ pnpm: {
43
+ exec: (specifier, args) => ({ args: ["dlx", specifier, ...args], command: "pnpm" }),
44
+ install: () => ({ args: ["install"], command: "pnpm" }),
45
+ name: "pnpm",
46
+ run: (script, args = []) => ({ args: ["run", script, ...args], command: "pnpm" }),
47
+ scaffoldFlag: "--use-pnpm",
48
+ },
49
+ yarn: {
50
+ exec: (specifier, args) => ({ args: ["dlx", specifier, ...args], command: "yarn" }),
51
+ install: () => ({ args: ["install"], command: "yarn" }),
52
+ name: "yarn",
53
+ run: (script, args = []) => ({ args: [script, ...args], command: "yarn" }),
54
+ scaffoldFlag: "--use-yarn",
55
+ },
56
+ };
57
+ export function packageManager(name) {
58
+ return MANAGERS[name];
59
+ }
60
+ /** Reads the manager out of the `npm_config_user_agent` every manager sets. */
61
+ export function parseUserAgent(userAgent) {
62
+ if (!userAgent)
63
+ return undefined;
64
+ const [first] = userAgent.split("/");
65
+ return first !== undefined && first in MANAGERS
66
+ ? first
67
+ : undefined;
68
+ }
69
+ /** The manager a project is already using, judged by the lockfile it committed. */
70
+ export async function detectFromLockfile(projectRoot) {
71
+ for (const [name, lockfile] of LOCKFILES) {
72
+ const found = await stat(join(projectRoot, lockfile)).catch(() => undefined);
73
+ if (found?.isFile())
74
+ return name;
75
+ }
76
+ return undefined;
77
+ }
78
+ async function isInstalled(command) {
79
+ return runCommand(command, ["--version"]).then(() => true, () => false);
80
+ }
81
+ /**
82
+ * Picks the manager to shell out to. A project's own lockfile wins, then
83
+ * whichever manager invoked this command, then bun, then npm. npm is the last
84
+ * resort rather than an error because it ships with Node.
85
+ */
86
+ export async function resolvePackageManager(options = {}) {
87
+ const { projectRoot, userAgent = process.env.npm_config_user_agent } = options;
88
+ const fromLockfile = projectRoot ? await detectFromLockfile(projectRoot) : undefined;
89
+ if (fromLockfile)
90
+ return MANAGERS[fromLockfile];
91
+ const fromAgent = parseUserAgent(userAgent);
92
+ if (fromAgent)
93
+ return MANAGERS[fromAgent];
94
+ if (await isInstalled("bun"))
95
+ return MANAGERS.bun;
96
+ return MANAGERS.npm;
97
+ }
98
+ //# sourceMappingURL=package-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"package-manager.js","sourceRoot":"","sources":["../src/package-manager.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,MAAM,kBAAkB,CAAC;AACxC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,UAAU,EAAE,MAAM,cAAc,CAAC;AA6B1C,8EAA8E;AAC9E,MAAM,SAAS,GAAuD;IACpE,CAAC,KAAK,EAAE,UAAU,CAAC;IACnB,CAAC,KAAK,EAAE,WAAW,CAAC;IACpB,CAAC,MAAM,EAAE,gBAAgB,CAAC;IAC1B,CAAC,MAAM,EAAE,WAAW,CAAC;IACrB,CAAC,KAAK,EAAE,mBAAmB,CAAC;CAC7B,CAAC;AAEF;;;;;GAKG;AACH,MAAM,QAAQ,GAAyD;IACrE,GAAG,EAAE;QACH,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC5E,OAAO,EAAE,CAAC,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YACvC,IAAI,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,SAAS,EAAE,mBAAmB,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;YAC/D,OAAO,EAAE,KAAK;SACf,CAAC;QACF,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QAChF,YAAY,EAAE,WAAW;KAC1B;IACD,GAAG,EAAE;QACH,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;YAC1B,IAAI,EAAE,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC;YACnC,OAAO,EAAE,KAAK;SACf,CAAC;QACF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;QACtD,IAAI,EAAE,KAAK;QACX,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC;YAC3B,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;YAClE,OAAO,EAAE,KAAK;SACf,CAAC;QACF,YAAY,EAAE,WAAW;KAC1B;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACnF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACvD,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACjF,YAAY,EAAE,YAAY;KAC3B;IACD,IAAI,EAAE;QACJ,IAAI,EAAE,CAAC,SAAS,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,SAAS,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACnF,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,SAAS,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QACvD,IAAI,EAAE,MAAM;QACZ,GAAG,EAAE,CAAC,MAAM,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,GAAG,IAAI,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC;QAC1E,YAAY,EAAE,YAAY;KAC3B;CACF,CAAC;AAEF,MAAM,UAAU,cAAc,CAAC,IAAwB;IACrD,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC;AACxB,CAAC;AAED,+EAA+E;AAC/E,MAAM,UAAU,cAAc,CAAC,SAA6B;IAC1D,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACrC,OAAO,KAAK,KAAK,SAAS,IAAI,KAAK,IAAI,QAAQ;QAC7C,CAAC,CAAE,KAA4B;QAC/B,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED,mFAAmF;AACnF,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,WAAmB;IAEnB,KAAK,MAAM,CAAC,IAAI,EAAE,QAAQ,CAAC,IAAI,SAAS,EAAE,CAAC;QACzC,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;QAC7E,IAAI,KAAK,EAAE,MAAM,EAAE;YAAE,OAAO,IAAI,CAAC;IACnC,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,OAAe;IACxC,OAAO,UAAU,CAAC,OAAO,EAAE,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,CAC5C,GAAG,EAAE,CAAC,IAAI,EACV,GAAG,EAAE,CAAC,KAAK,CACZ,CAAC;AACJ,CAAC;AAQD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,qBAAqB,CACzC,UAAwC,EAAE;IAE1C,MAAM,EAAE,WAAW,EAAE,SAAS,GAAG,OAAO,CAAC,GAAG,CAAC,qBAAqB,EAAE,GAAG,OAAO,CAAC;IAE/E,MAAM,YAAY,GAAG,WAAW,CAAC,CAAC,CAAC,MAAM,kBAAkB,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;IACrF,IAAI,YAAY;QAAE,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC;IAEhD,MAAM,SAAS,GAAG,cAAc,CAAC,SAAS,CAAC,CAAC;IAC5C,IAAI,SAAS;QAAE,OAAO,QAAQ,CAAC,SAAS,CAAC,CAAC;IAE1C,IAAI,MAAM,WAAW,CAAC,KAAK,CAAC;QAAE,OAAO,QAAQ,CAAC,GAAG,CAAC;IAClD,OAAO,QAAQ,CAAC,GAAG,CAAC;AACtB,CAAC"}
@@ -0,0 +1,33 @@
1
+ import { type ChildProcess, type StdioOptions } from "node:child_process";
2
+ export interface CommandResult {
3
+ readonly stderr: string;
4
+ readonly stdout: string;
5
+ }
6
+ export interface CommandOptions {
7
+ readonly cwd?: string;
8
+ readonly env?: NodeJS.ProcessEnv;
9
+ }
10
+ export interface StartCommandOptions {
11
+ readonly cwd: string;
12
+ /** Makes the child a process group leader so its own children can be signalled. */
13
+ readonly detached?: boolean;
14
+ readonly env?: NodeJS.ProcessEnv;
15
+ readonly stdio?: StdioOptions;
16
+ }
17
+ export declare function runCommand(command: string, args: readonly string[], options?: CommandOptions): Promise<CommandResult>;
18
+ /**
19
+ * Runs a command with its output streamed straight to this terminal, for the
20
+ * long operations where watching progress is the point. `runCommand` captures
21
+ * output instead, which is right for commands whose result is parsed.
22
+ */
23
+ export declare function runInheritedCommand(command: string, args: readonly string[], options?: CommandOptions): Promise<void>;
24
+ export declare function startCommand(command: string, args: readonly string[], options: StartCommandOptions): ChildProcess;
25
+ export declare function hasExited(child: ChildProcess): boolean;
26
+ /**
27
+ * `bun run dev` spawns Next.js, which spawns its own workers. Signalling only
28
+ * the direct child leaves that subtree holding the port, so the whole process
29
+ * group is signalled instead.
30
+ */
31
+ export declare function killProcessTree(child: ChildProcess, signal: NodeJS.Signals): void;
32
+ export declare function terminateProcessTree(child: ChildProcess, graceMilliseconds?: number): Promise<void>;
33
+ //# sourceMappingURL=process.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"process.d.ts","sourceRoot":"","sources":["../src/process.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,KAAK,YAAY,EAAE,KAAK,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEjF,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;IACxB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;CAClC;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;IACrB,mFAAmF;IACnF,QAAQ,CAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAC5B,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACjC,QAAQ,CAAC,KAAK,CAAC,EAAE,YAAY,CAAC;CAC/B;AAED,wBAAsB,UAAU,CAC9B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,aAAa,CAAC,CA6BxB;AAED;;;;GAIG;AACH,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,GAAE,cAAmB,GAC3B,OAAO,CAAC,IAAI,CAAC,CAcf;AAED,wBAAgB,YAAY,CAC1B,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,SAAS,MAAM,EAAE,EACvB,OAAO,EAAE,mBAAmB,GAC3B,YAAY,CAOd;AAED,wBAAgB,SAAS,CAAC,KAAK,EAAE,YAAY,GAAG,OAAO,CAEtD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,MAAM,CAAC,OAAO,GACrB,IAAI,CAcN;AAED,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,YAAY,EACnB,iBAAiB,SAAQ,GACxB,OAAO,CAAC,IAAI,CAAC,CAiBf"}