@fairgarden/distribution 0.1.0-alpha.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 (58) hide show
  1. package/Readme.md +94 -0
  2. package/dist/add-module.d.ts +58 -0
  3. package/dist/add-module.d.ts.map +1 -0
  4. package/dist/add-module.js +250 -0
  5. package/dist/add-module.js.map +1 -0
  6. package/dist/canary.d.ts +58 -0
  7. package/dist/canary.d.ts.map +1 -0
  8. package/dist/canary.js +117 -0
  9. package/dist/canary.js.map +1 -0
  10. package/dist/cli.d.ts +3 -0
  11. package/dist/cli.d.ts.map +1 -0
  12. package/dist/cli.js +747 -0
  13. package/dist/cli.js.map +1 -0
  14. package/dist/config-edit.d.ts +18 -0
  15. package/dist/config-edit.d.ts.map +1 -0
  16. package/dist/config-edit.js +166 -0
  17. package/dist/config-edit.js.map +1 -0
  18. package/dist/extends.d.ts +59 -0
  19. package/dist/extends.d.ts.map +1 -0
  20. package/dist/extends.js +163 -0
  21. package/dist/extends.js.map +1 -0
  22. package/dist/extract.d.ts +31 -0
  23. package/dist/extract.d.ts.map +1 -0
  24. package/dist/extract.js +177 -0
  25. package/dist/extract.js.map +1 -0
  26. package/dist/git-url.d.ts +19 -0
  27. package/dist/git-url.d.ts.map +1 -0
  28. package/dist/git-url.js +55 -0
  29. package/dist/git-url.js.map +1 -0
  30. package/dist/index.d.ts +12 -0
  31. package/dist/index.d.ts.map +1 -0
  32. package/dist/index.js +7 -0
  33. package/dist/index.js.map +1 -0
  34. package/dist/overrides.d.ts +32 -0
  35. package/dist/overrides.d.ts.map +1 -0
  36. package/dist/overrides.js +81 -0
  37. package/dist/overrides.js.map +1 -0
  38. package/dist/readme.d.ts +58 -0
  39. package/dist/readme.d.ts.map +1 -0
  40. package/dist/readme.js +299 -0
  41. package/dist/readme.js.map +1 -0
  42. package/dist/release.d.ts +140 -0
  43. package/dist/release.d.ts.map +1 -0
  44. package/dist/release.js +409 -0
  45. package/dist/release.js.map +1 -0
  46. package/dist/scaffold.d.ts +46 -0
  47. package/dist/scaffold.d.ts.map +1 -0
  48. package/dist/scaffold.js +389 -0
  49. package/dist/scaffold.js.map +1 -0
  50. package/dist/submodules.d.ts +95 -0
  51. package/dist/submodules.d.ts.map +1 -0
  52. package/dist/submodules.js +225 -0
  53. package/dist/submodules.js.map +1 -0
  54. package/dist/workflows.d.ts +57 -0
  55. package/dist/workflows.d.ts.map +1 -0
  56. package/dist/workflows.js +358 -0
  57. package/dist/workflows.js.map +1 -0
  58. package/package.json +51 -0
@@ -0,0 +1,389 @@
1
+ import { mkdir, writeFile, readFile, readdir } from 'node:fs/promises';
2
+ import path from 'node:path';
3
+ import { publishWorkflow, releaseScripts } from "./workflows.js";
4
+ const json = (value) => `${JSON.stringify(value, null, 2)}\n`;
5
+ /** Versions the generated projects pin, kept beside the ones this package uses. */
6
+ export const VERSIONS = {
7
+ monolith: '^0.1.0-alpha.0',
8
+ // Provides `fg-dist`, which the release scripts and the publish workflow call.
9
+ distribution: '^0.1.0-alpha.0',
10
+ next: '^16.3.5',
11
+ react: '^19.3.0',
12
+ types: {
13
+ node: '^26.6.2',
14
+ react: '^19.3.0',
15
+ reactDom: '^19.3.0',
16
+ },
17
+ eslint: '^9.39.5',
18
+ eslintConfigNext: '^16.3.5',
19
+ portless: '^0.15.6',
20
+ typescript: '^6.0.3',
21
+ // Exact, because this is what `packageManager` means. The publish workflow's
22
+ // pnpm comes from it, so a module without one cannot build in CI.
23
+ pnpm: 'pnpm@10.28.0',
24
+ };
25
+ const GITIGNORE = `node_modules
26
+ .next
27
+ .turbo
28
+ out
29
+ build
30
+ next-env.d.ts
31
+ *.tsbuildinfo
32
+
33
+ # derived mount points; the symlinks under src/ are what is committed
34
+ /app/
35
+ /pages/
36
+
37
+ # generated by next dev
38
+ AGENTS.md
39
+ CLAUDE.md
40
+ `;
41
+ const TSCONFIG = {
42
+ compilerOptions: {
43
+ target: 'ES2017',
44
+ lib: ['dom', 'dom.iterable', 'esnext'],
45
+ allowJs: true,
46
+ skipLibCheck: true,
47
+ strict: true,
48
+ noEmit: true,
49
+ esModuleInterop: true,
50
+ module: 'esnext',
51
+ moduleResolution: 'bundler',
52
+ resolveJsonModule: true,
53
+ isolatedModules: true,
54
+ jsx: 'preserve',
55
+ incremental: true,
56
+ plugins: [{ name: 'next' }],
57
+ },
58
+ include: ['next-env.d.ts', '**/*.ts', '**/*.tsx', '.next/types/**/*.ts'],
59
+ exclude: ['node_modules'],
60
+ };
61
+ /**
62
+ * A repository that composes modules.
63
+ *
64
+ * The monolith app lives at `apps/monolith` so modules can be added beside it
65
+ * as `apps/<name>`, which is where `add-module` puts them.
66
+ */
67
+ export const monolithRepo = (name, origin) => ({
68
+ '.gitignore': `node_modules\n.turbo\n`,
69
+ // Modules are linked through the workspace, so nothing here carries a
70
+ // version: the submodule commit is the pin and its package.json is the
71
+ // version. Keeping the workspace protocol stops pnpm writing one back in.
72
+ '.npmrc': `link-workspace-packages=true\nsave-workspace-protocol=true\n`,
73
+ 'pnpm-workspace.yaml': `packages:\n - "apps/*"\n - "packages/*"\n - "packages/*/docs"\n`,
74
+ 'package.json': json({
75
+ name,
76
+ version: '0.1.0-alpha.0',
77
+ private: true,
78
+ ...(origin ? { repository: { type: 'git', url: origin } } : {}),
79
+ scripts: {
80
+ build: 'turbo run build',
81
+ // The monolith already serves every mounted app, so running their dev
82
+ // servers as well would be the same routes twice.
83
+ dev: "turbo run dev --filter=./apps/monolith --filter='./packages/*'",
84
+ // Each app on its own instead, for working on one in isolation or on
85
+ // anything the monolith cannot serve from one deployment.
86
+ 'dev-services': 'turbo run dev:service',
87
+ lint: 'turbo run lint',
88
+ },
89
+ devDependencies: { turbo: '^2.11.2' },
90
+ }),
91
+ 'turbo.json': json({
92
+ $schema: 'https://turbo.build/schema.json',
93
+ tasks: {
94
+ build: { dependsOn: ['^build'], outputs: ['.next/**', '!.next/cache/**'] },
95
+ lint: { dependsOn: ['^lint'] },
96
+ dev: { persistent: true, cache: false },
97
+ 'dev:service': { persistent: true, cache: false },
98
+ },
99
+ }),
100
+ 'apps/monolith/package.json': json({
101
+ name: `${name}-monolith`,
102
+ version: '0.1.0-alpha.0',
103
+ private: true,
104
+ scripts: {
105
+ dev: 'next dev',
106
+ build: 'next build',
107
+ start: 'next start',
108
+ lint: 'eslint',
109
+ },
110
+ dependencies: {
111
+ '@fairgarden/monolith': VERSIONS.monolith,
112
+ next: VERSIONS.next,
113
+ react: VERSIONS.react,
114
+ 'react-dom': VERSIONS.react,
115
+ },
116
+ devDependencies: {
117
+ '@types/node': VERSIONS.types.node,
118
+ '@types/react': VERSIONS.types.react,
119
+ '@types/react-dom': VERSIONS.types.reactDom,
120
+ eslint: VERSIONS.eslint,
121
+ 'eslint-config-next': VERSIONS.eslintConfigNext,
122
+ typescript: VERSIONS.typescript,
123
+ },
124
+ }),
125
+ 'apps/monolith/next.config.ts': `import { withMonolith } from '@fairgarden/monolith'
126
+
127
+ export default withMonolith(
128
+ {
129
+ // the monolith's own Next config
130
+ },
131
+ {
132
+ // mount name -> module, added by \`fg-dist add-module\`
133
+ }
134
+ )
135
+ `,
136
+ 'apps/monolith/tsconfig.json': json(TSCONFIG),
137
+ 'apps/monolith/eslint.config.mjs': `import next from 'eslint-config-next/core-web-vitals'
138
+
139
+ /** @type {import('eslint').Linter.Config[]} */
140
+ const config = [{ ignores: ['node_modules/**', '.next/**', 'app/**', 'pages/**'] }, ...next]
141
+
142
+ export default config
143
+ `,
144
+ 'apps/monolith/.gitignore': GITIGNORE,
145
+ 'apps/monolith/src/app/layout.tsx': `export default function RootLayout({
146
+ children,
147
+ }: Readonly<{ children: React.ReactNode }>) {
148
+ return (
149
+ <html lang="en">
150
+ <body>{children}</body>
151
+ </html>
152
+ )
153
+ }
154
+ `,
155
+ 'apps/monolith/src/app/page.tsx': `export default function Home() {
156
+ return <main>Nothing mounted yet. Add a module with \`fg-dist add-module\`.</main>
157
+ }
158
+ `,
159
+ });
160
+ /**
161
+ * A repository that can be mounted into a monolith.
162
+ *
163
+ * It is an ordinary Next app; the only additions are the portability check and
164
+ * the lint rules that keep it mountable.
165
+ */
166
+ /** `@acme/widget` -> `widget`, which is what a hostname wants. */
167
+ const unscoped = (packageName) => packageName.replace(/^@[^/]+\//, '');
168
+ export const moduleRepo = (packageName, origin) => ({
169
+ // A module releases on its own schedule, so it carries its own workflow.
170
+ ...publishWorkflow(packageName),
171
+ '.gitignore': `node_modules\n.next\n.turbo\nnext-env.d.ts\n*.tsbuildinfo\n\n# generated by next dev\nAGENTS.md\nCLAUDE.md\n`,
172
+ 'package.json': json({
173
+ name: packageName,
174
+ version: '0.1.0-alpha.0',
175
+ // Not private: a module publishes itself, so that a monolith which cannot
176
+ // reach it as a submodule can install it as a package instead. Scoped
177
+ // packages publish restricted by default; say so rather than leave it to
178
+ // whoever reads this to remember.
179
+ publishConfig: { access: 'restricted' },
180
+ // What CI installs with — see .github/actions/publish-prepare.
181
+ packageManager: VERSIONS.pnpm,
182
+ // A module is consumed as source — its routes are read out of the package —
183
+ // so the tarball carries the source rather than a build.
184
+ files: ['app', 'lib', 'pages', 'public', 'next.config.ts'],
185
+ // A monolith adds this repository as a submodule, so record where it lives.
186
+ ...(origin ? { repository: { type: 'git', url: origin } } : {}),
187
+ scripts: {
188
+ dev: 'next dev',
189
+ // Served at a stable hostname instead of a port, so several apps can run
190
+ // at once without colliding: https://${unscoped(packageName)}.localhost
191
+ 'dev:service': `portless ${unscoped(packageName)} next dev`,
192
+ build: 'next build',
193
+ start: 'next start',
194
+ lint: 'eslint',
195
+ // Called by .github/workflows/publish.yml, and by you — see the readme.
196
+ ...releaseScripts(packageName),
197
+ },
198
+ dependencies: {
199
+ next: VERSIONS.next,
200
+ react: VERSIONS.react,
201
+ 'react-dom': VERSIONS.react,
202
+ },
203
+ devDependencies: {
204
+ '@fairgarden/distribution': VERSIONS.distribution,
205
+ '@fairgarden/monolith': VERSIONS.monolith,
206
+ '@types/node': VERSIONS.types.node,
207
+ '@types/react': VERSIONS.types.react,
208
+ '@types/react-dom': VERSIONS.types.reactDom,
209
+ eslint: VERSIONS.eslint,
210
+ 'eslint-config-next': VERSIONS.eslintConfigNext,
211
+ // `dev:service` serves this at a stable hostname instead of a port.
212
+ portless: VERSIONS.portless,
213
+ typescript: VERSIONS.typescript,
214
+ },
215
+ }),
216
+ 'next.config.ts': `import type { NextConfig } from 'next'
217
+ import { withMonolithicPortability } from '@fairgarden/monolith'
218
+
219
+ const nextConfig: NextConfig = {}
220
+
221
+ // Reports anything that would not survive being mounted in a monolith.
222
+ export default withMonolithicPortability(nextConfig)
223
+ `,
224
+ 'tsconfig.json': json({
225
+ ...TSCONFIG,
226
+ compilerOptions: {
227
+ ...TSCONFIG.compilerOptions,
228
+ // So this module's own files can import each other by package name,
229
+ // which is what keeps them resolvable once mounted.
230
+ paths: { [`${packageName}/*`]: ['./*'] },
231
+ },
232
+ }),
233
+ 'eslint.config.mjs': `import next from 'eslint-config-next/core-web-vitals'
234
+ import monolith from '@fairgarden/monolith/eslint'
235
+
236
+ /** @type {import('eslint').Linter.Config[]} */
237
+ const config = [
238
+ { ignores: ['node_modules/**', '.next/**'] },
239
+ ...next,
240
+ ...monolith.configs.recommended,
241
+ ]
242
+
243
+ export default config
244
+ `,
245
+ 'lib/link.ts': `import { createHref, createLink } from '@fairgarden/monolith/link'
246
+
247
+ // Use these instead of next/link so hrefs carry the mount point when this
248
+ // module is served inside a monolith.
249
+ export const Link = createLink('${packageName}')
250
+ export const href = createHref('${packageName}')
251
+ `,
252
+ 'app/layout.tsx': `export default function RootLayout({
253
+ children,
254
+ }: Readonly<{ children: React.ReactNode }>) {
255
+ return (
256
+ <html lang="en">
257
+ <body>{children}</body>
258
+ </html>
259
+ )
260
+ }
261
+ `,
262
+ 'app/page.tsx': `import { Link } from '${packageName}/lib/link'
263
+
264
+ export default function Home() {
265
+ return (
266
+ <main>
267
+ <h1>${packageName}</h1>
268
+ <Link href="/">Home</Link>
269
+ </main>
270
+ )
271
+ }
272
+ `,
273
+ });
274
+ /** Write a file map, creating directories as needed. */
275
+ export const write = async (root, files) => {
276
+ const written = [];
277
+ for (const [relative, contents] of Object.entries(files)) {
278
+ const full = path.join(root, relative);
279
+ await mkdir(path.dirname(full), { recursive: true });
280
+ await writeFile(full, contents);
281
+ written.push(relative);
282
+ }
283
+ return written.sort();
284
+ };
285
+ /** Whether a directory has anything in it, so `init` never writes over work. */
286
+ export const isEmpty = async (dir) => {
287
+ const entries = await readdir(dir).catch(() => undefined);
288
+ if (!entries)
289
+ return true;
290
+ return entries.filter((entry) => entry !== '.git').length === 0;
291
+ };
292
+ export const readPackageName = async (root) => {
293
+ try {
294
+ const pkg = JSON.parse(await readFile(path.join(root, 'package.json'), 'utf8'));
295
+ return typeof pkg.name === 'string' ? pkg.name : undefined;
296
+ }
297
+ catch {
298
+ return undefined;
299
+ }
300
+ };
301
+ /** `2024.01.15` — the date-based version a distribution is released under. */
302
+ export const calendarVersion = (on = new Date()) => [
303
+ on.getUTCFullYear(),
304
+ String(on.getUTCMonth() + 1).padStart(2, '0'),
305
+ String(on.getUTCDate()).padStart(2, '0'),
306
+ ].join('.');
307
+ /**
308
+ * A repository that ships a set of modules to end users.
309
+ *
310
+ * The root package.json is the distribution manifest: its version is the date
311
+ * it was released, and its dependencies are the modules it ships, each at a
312
+ * semver version. `extends` names another distribution whose modules this one
313
+ * inherits and may move ahead of, but never behind.
314
+ */
315
+ export const distributionRepo = (name, origin, parent, { monolith = true } = {}) => {
316
+ // A distribution of only Next apps can deploy as one. A complex one cannot,
317
+ // and then each app under apps/ is deployed on its own — which is fine for
318
+ // an audience that already has deployment infrastructure.
319
+ const files = monolith
320
+ ? monolithRepo(name, origin)
321
+ : {
322
+ '.gitignore': `node_modules\n.turbo\n`,
323
+ '.npmrc': `link-workspace-packages=true\nsave-workspace-protocol=true\n`,
324
+ 'pnpm-workspace.yaml': `packages:\n - "apps/*"\n - "packages/*"\n - "packages/*/docs"\n`,
325
+ 'turbo.json': json({
326
+ $schema: 'https://turbo.build/schema.json',
327
+ tasks: {
328
+ build: {
329
+ dependsOn: ['^build'],
330
+ outputs: ['.next/**', '!.next/cache/**'],
331
+ },
332
+ lint: { dependsOn: ['^lint'] },
333
+ dev: { persistent: true, cache: false },
334
+ },
335
+ }),
336
+ };
337
+ files['package.json'] = json({
338
+ name,
339
+ // End users read a date, not a semver range: it says how old their copy is.
340
+ version: calendarVersion(),
341
+ private: true,
342
+ ...(origin ? { repository: { type: 'git', url: origin } } : {}),
343
+ ...(parent ? { distribution: { extends: parent } } : {}),
344
+ scripts: {
345
+ build: 'turbo run build',
346
+ // With a monolith, running the mounted apps as well would serve the same
347
+ // routes twice. Without one, every app is its own deployment and there
348
+ // is nothing else to run them.
349
+ dev: monolith
350
+ ? "turbo run dev --filter=./apps/monolith --filter='./packages/*'"
351
+ : 'turbo run dev:service',
352
+ 'dev-services': 'turbo run dev:service',
353
+ lint: 'turbo run lint',
354
+ },
355
+ // Modules go here, each pinned to the semver version this ships.
356
+ dependencies: parent ? { [parent]: 'latest' } : {},
357
+ devDependencies: { turbo: '^2.11.2' },
358
+ });
359
+ files['Readme.md'] = `# ${name}
360
+
361
+ A distribution: the set of modules shipped together, released under a date-based
362
+ version so it is obvious how old a copy is.
363
+
364
+ Modules are listed in \`dependencies\`, each pinned to a semver version, and
365
+ checked out as submodules. Add one with \`fg-dist add-module <url>\`, and see
366
+ what has moved with \`fg-dist sync\`.
367
+
368
+ ## Deploying
369
+ ${monolith
370
+ ? `
371
+ Every module is mounted into \`apps/monolith\`, which deploys as one Next app.
372
+ `
373
+ : `
374
+ Each app under \`apps/\` is deployed on its own. There is no monolith app,
375
+ which is the right shape once the distribution is too complex to serve from one
376
+ deployment — and fine for an audience that already runs deployment
377
+ infrastructure.
378
+ `}${parent
379
+ ? `
380
+ ## Extends
381
+
382
+ This distribution extends \`${parent}\`. It ships that distribution's modules
383
+ and may move ahead of them, but can never ship anything older. \`fg-dist check\`
384
+ fails when it does${monolith ? ', and so does the monolith build' : ''}.
385
+ `
386
+ : ''}`;
387
+ return files;
388
+ };
389
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Whether this repository ships modules, as opposed to being one.
3
+ *
4
+ * Read from `.gitmodules`, which is committed, rather than from
5
+ * {@link submodules}, which only reports checkouts that are actually there. A
6
+ * clone made without `--recurse-submodules` has the file and none of the
7
+ * checkouts, and treating that as a module would write a module's readme over
8
+ * the distribution's and let it be released as if it were one.
9
+ */
10
+ export declare const isDistribution: (root: string) => boolean;
11
+ /**
12
+ * Submodules that are missing their checkout.
13
+ *
14
+ * Anything that reads a module's own package.json needs to say so rather than
15
+ * quietly leave it out.
16
+ */
17
+ export declare const uninitialised: (root: string) => string[];
18
+ /** The repository holding the submodules, which is not the monolith directory. */
19
+ export declare const repositoryRoot: (from: string) => string | undefined;
20
+ export interface Submodule {
21
+ /** Last path segment, which is what you name on the command line. */
22
+ name: string;
23
+ /** The section name in .gitmodules, which is what config reads and writes. */
24
+ configName: string;
25
+ /** Path as recorded in .gitmodules, relative to the repository. */
26
+ relativePath: string;
27
+ path: string;
28
+ url: string;
29
+ /** The commit the repository has pinned. */
30
+ pinned: string;
31
+ }
32
+ /**
33
+ * Submodules as `.gitmodules` records them, with the commit each is pinned to.
34
+ *
35
+ * Uninitialised submodules are left out — there is nothing to inspect until
36
+ * they are checked out.
37
+ */
38
+ export declare const submodules: (root: string) => Submodule[];
39
+ export type ReleaseKind = 'major' | 'minor' | 'patch';
40
+ export interface SubmoduleState {
41
+ submodule: Submodule;
42
+ /** The commit checked out right now, which a bump changes. */
43
+ head: string;
44
+ /** Version pinned right now, when a tag names it. */
45
+ current: string | undefined;
46
+ /** Whether that tag is the pinned commit rather than an ancestor of it. */
47
+ exact: boolean;
48
+ /** Newer version tags, newest first. */
49
+ available: string[];
50
+ /** The newest upgrade of each kind that is available. */
51
+ upgrades: Partial<Record<ReleaseKind, string>>;
52
+ /** Commits on the tracked branch that no version tag covers yet. */
53
+ untagged: number;
54
+ /** Uncommitted changes, which make moving the pin unsafe. */
55
+ dirty: boolean;
56
+ /** Whether the remote was reachable, when a fetch was attempted. */
57
+ fetched: boolean | undefined;
58
+ }
59
+ /**
60
+ * Compare a submodule's pinned commit against the versions its repository has.
61
+ *
62
+ * Only tags that name a version are considered an upgrade. Commits past the
63
+ * newest tag are counted and reported, but never bumped to — a commit carries
64
+ * no statement about what changed, which is the whole point of the version.
65
+ */
66
+ export declare const inspect: (submodule: Submodule, { fetch }?: {
67
+ fetch?: boolean;
68
+ }) => SubmoduleState;
69
+ /**
70
+ * The version a bump should move to, or undefined when there is nothing to do.
71
+ *
72
+ * Major upgrades are held back unless asked for: they are the ones that need a
73
+ * person to read a changelog first.
74
+ */
75
+ export declare const target: (state: SubmoduleState, { major }?: {
76
+ major?: boolean;
77
+ }) => string | undefined;
78
+ /**
79
+ * Record a different URL for a submodule.
80
+ *
81
+ * `.gitmodules` is what gets committed, and `submodule sync` copies it into the
82
+ * local config so the existing checkout uses it too. The caller commits.
83
+ */
84
+ export declare const setUrl: (root: string, submodule: Submodule, url: string) => void;
85
+ /**
86
+ * Whether a remote can be read with no credentials at all.
87
+ *
88
+ * This is the question a build host asks. Prompting is disabled so a private
89
+ * repository fails immediately instead of waiting for a password nobody is
90
+ * there to type.
91
+ */
92
+ export declare const isPublic: (url: string, timeout?: number) => boolean;
93
+ /** Move a submodule's checkout to a tag. The caller commits the new pointer. */
94
+ export declare const moveTo: (submodule: Submodule, tag: string) => void;
95
+ //# sourceMappingURL=submodules.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"submodules.d.ts","sourceRoot":"","sources":["../src/submodules.ts"],"names":[],"mappings":"AAqBA;;;;;;;;GAQG;AACH,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,OAEyC,CAAA;AAEvF;;;;;GAKG;AACH,eAAO,MAAM,aAAa,GAAI,MAAM,MAAM,KAAG,MAAM,EAOlD,CAAA;AAED,kFAAkF;AAClF,eAAO,MAAM,cAAc,GAAI,MAAM,MAAM,KAAG,MAAM,GAAG,SACV,CAAA;AAE7C,MAAM,WAAW,SAAS;IACxB,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,UAAU,EAAE,MAAM,CAAA;IAClB,mEAAmE;IACnE,YAAY,EAAE,MAAM,CAAA;IACpB,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,MAAM,CAAA;IACX,4CAA4C;IAC5C,MAAM,EAAE,MAAM,CAAA;CACf;AAED;;;;;GAKG;AACH,eAAO,MAAM,UAAU,GAAI,MAAM,MAAM,KAAG,SAAS,EAgClD,CAAA;AAgBD,MAAM,MAAM,WAAW,GAAG,OAAO,GAAG,OAAO,GAAG,OAAO,CAAA;AAErD,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,SAAS,CAAA;IACpB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,qDAAqD;IACrD,OAAO,EAAE,MAAM,GAAG,SAAS,CAAA;IAC3B,2EAA2E;IAC3E,KAAK,EAAE,OAAO,CAAA;IACd,wCAAwC;IACxC,SAAS,EAAE,MAAM,EAAE,CAAA;IACnB,yDAAyD;IACzD,QAAQ,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;IAC9C,oEAAoE;IACpE,QAAQ,EAAE,MAAM,CAAA;IAChB,6DAA6D;IAC7D,KAAK,EAAE,OAAO,CAAA;IACd,oEAAoE;IACpE,OAAO,EAAE,OAAO,GAAG,SAAS,CAAA;CAC7B;AAED;;;;;;GAMG;AACH,eAAO,MAAM,OAAO,GAClB,WAAW,SAAS,EACpB,YAAkB;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KACzC,cA6DF,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GACjB,OAAO,cAAc,EACrB,YAAmB;IAAE,KAAK,CAAC,EAAE,OAAO,CAAA;CAAO,KAC1C,MAAM,GAAG,SASX,CAAA;AAED;;;;;GAKG;AACH,eAAO,MAAM,MAAM,GAAI,MAAM,MAAM,EAAE,WAAW,SAAS,EAAE,KAAK,MAAM,KAAG,IAYxE,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,QAAQ,GAAI,KAAK,MAAM,EAAE,gBAAgB,KAAG,OAoBxD,CAAA;AAED,gFAAgF;AAChF,eAAO,MAAM,MAAM,GAAI,WAAW,SAAS,EAAE,KAAK,MAAM,KAAG,IAa1D,CAAA"}