azcodr 2.0.0 → 2.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 (71) hide show
  1. package/.agents/hooks.json +3 -3
  2. package/.github/workflows/publish.yml +0 -4
  3. package/bin/azcodr.js +9 -4
  4. package/lib/cli-parse.d.ts +32 -0
  5. package/lib/cli-parse.d.ts.map +1 -0
  6. package/lib/cli-parse.js +45 -41
  7. package/lib/cli-parse.js.map +1 -0
  8. package/lib/cli-target.d.ts +66 -0
  9. package/lib/cli-target.d.ts.map +1 -0
  10. package/lib/cli-target.js +89 -96
  11. package/lib/cli-target.js.map +1 -0
  12. package/lib/cli.d.ts +40 -0
  13. package/lib/cli.d.ts.map +1 -0
  14. package/lib/cli.js +122 -136
  15. package/lib/cli.js.map +1 -0
  16. package/lib/errors.d.ts +39 -0
  17. package/lib/errors.d.ts.map +1 -0
  18. package/lib/errors.js +16 -18
  19. package/lib/errors.js.map +1 -0
  20. package/lib/git.d.ts +15 -0
  21. package/lib/git.d.ts.map +1 -0
  22. package/lib/git.js +25 -22
  23. package/lib/git.js.map +1 -0
  24. package/lib/guards.d.ts +35 -0
  25. package/lib/guards.d.ts.map +1 -0
  26. package/lib/guards.js +62 -63
  27. package/lib/guards.js.map +1 -0
  28. package/lib/index.d.ts +6 -199
  29. package/lib/index.d.ts.map +1 -0
  30. package/lib/index.js +4 -5
  31. package/lib/index.js.map +1 -0
  32. package/lib/links.d.ts +28 -0
  33. package/lib/links.d.ts.map +1 -0
  34. package/lib/links.js +105 -99
  35. package/lib/links.js.map +1 -0
  36. package/lib/permissions.d.ts +9 -0
  37. package/lib/permissions.d.ts.map +1 -0
  38. package/lib/permissions.js +36 -36
  39. package/lib/permissions.js.map +1 -0
  40. package/lib/repo.d.ts +20 -0
  41. package/lib/repo.d.ts.map +1 -0
  42. package/lib/repo.js +73 -71
  43. package/lib/repo.js.map +1 -0
  44. package/lib/scaffold.d.ts +80 -0
  45. package/lib/scaffold.d.ts.map +1 -0
  46. package/lib/scaffold.js +159 -196
  47. package/lib/scaffold.js.map +1 -0
  48. package/memory.md +16 -0
  49. package/package.json +13 -3
  50. package/scripts/test_coverage.js +2 -2
  51. package/scripts/validate/adr.js +11 -7
  52. package/scripts/validate/io.js +7 -9
  53. package/scripts/validate/links.js +6 -7
  54. package/scripts/validate/parity.js +5 -7
  55. package/scripts/validate/root.js +6 -7
  56. package/scripts/validate/rules.js +7 -9
  57. package/scripts/validate/skills.js +8 -10
  58. package/scripts/validate/text.js +3 -5
  59. package/scripts/validate-cli.js +1 -2
  60. package/scripts/validate.js +37 -19
  61. package/src/cli-parse.ts +77 -0
  62. package/src/cli-target.ts +167 -0
  63. package/src/cli.ts +240 -0
  64. package/src/errors.ts +35 -0
  65. package/src/git.ts +34 -0
  66. package/src/guards.ts +101 -0
  67. package/src/index.ts +39 -0
  68. package/src/links.ts +139 -0
  69. package/src/permissions.ts +42 -0
  70. package/src/repo.ts +94 -0
  71. package/src/scaffold.ts +273 -0
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Ensures all bash scripts in agent and skill directories have executable permissions (0o755).
3
+ */
4
+ export declare function makeScriptsExecutable(targetDir: string, dryRun?: boolean): string[];
5
+ declare const _default: {
6
+ makeScriptsExecutable: typeof makeScriptsExecutable;
7
+ };
8
+ export default _default;
9
+ //# sourceMappingURL=permissions.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.d.ts","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAyBA;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,UAAQ,GAAG,MAAM,EAAE,CAWjF;;;;AAED,wBAAyC"}
@@ -1,44 +1,44 @@
1
- 'use strict';
2
-
3
- const fs = require('node:fs');
4
- const path = require('node:path');
5
-
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
6
3
  function chmodShFile(filePath, dryRun) {
7
- if (dryRun) return;
8
- try {
9
- fs.chmodSync(filePath, 0o755);
10
- } catch {
11
- // Non-critical if filesystem does not support POSIX permissions
12
- }
4
+ if (dryRun)
5
+ return;
6
+ try {
7
+ fs.chmodSync(filePath, 0o755);
8
+ }
9
+ catch {
10
+ // Non-critical if filesystem does not support POSIX permissions
11
+ }
13
12
  }
14
-
15
13
  function chmodShFilesIn(scriptsDir, dryRun) {
16
- const modified = [];
17
- if (!fs.existsSync(scriptsDir) || !fs.statSync(scriptsDir).isDirectory()) return modified;
18
- const files = fs.readdirSync(scriptsDir);
19
- for (const file of files) {
20
- if (!file.endsWith('.sh')) continue;
21
- const filePath = path.join(scriptsDir, file);
22
- modified.push(filePath);
23
- chmodShFile(filePath, dryRun);
24
- }
25
- return modified;
14
+ const modified = [];
15
+ if (!fs.existsSync(scriptsDir) || !fs.statSync(scriptsDir).isDirectory())
16
+ return modified;
17
+ const files = fs.readdirSync(scriptsDir);
18
+ for (const file of files) {
19
+ if (!file.endsWith('.sh'))
20
+ continue;
21
+ const filePath = path.join(scriptsDir, file);
22
+ modified.push(filePath);
23
+ chmodShFile(filePath, dryRun);
24
+ }
25
+ return modified;
26
26
  }
27
-
28
27
  /**
29
28
  * Ensures all bash scripts in agent and skill directories have executable permissions (0o755).
30
29
  */
31
- function makeScriptsExecutable(targetDir, dryRun = false) {
32
- const agentScriptsDir = path.join(targetDir, '.agents', 'scripts');
33
- const modified = chmodShFilesIn(agentScriptsDir, dryRun);
34
- const skillsDir = path.join(targetDir, '.agents', 'skills');
35
- if (!fs.existsSync(skillsDir)) return modified;
36
- const skills = fs.readdirSync(skillsDir);
37
- for (const skill of skills) {
38
- const scriptsDir = path.join(skillsDir, skill, 'scripts');
39
- modified.push(...chmodShFilesIn(scriptsDir, dryRun));
40
- }
41
- return modified;
30
+ export function makeScriptsExecutable(targetDir, dryRun = false) {
31
+ const agentScriptsDir = path.join(targetDir, '.agents', 'scripts');
32
+ const modified = chmodShFilesIn(agentScriptsDir, dryRun);
33
+ const skillsDir = path.join(targetDir, '.agents', 'skills');
34
+ if (!fs.existsSync(skillsDir))
35
+ return modified;
36
+ const skills = fs.readdirSync(skillsDir);
37
+ for (const skill of skills) {
38
+ const scriptsDir = path.join(skillsDir, skill, 'scripts');
39
+ modified.push(...chmodShFilesIn(scriptsDir, dryRun));
40
+ }
41
+ return modified;
42
42
  }
43
-
44
- module.exports = { makeScriptsExecutable };
43
+ export default { makeScriptsExecutable };
44
+ //# sourceMappingURL=permissions.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"permissions.js","sourceRoot":"","sources":["../src/permissions.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,SAAS,WAAW,CAAC,QAAgB,EAAE,MAAe;IACpD,IAAI,MAAM;QAAE,OAAO;IACnB,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAChC,CAAC;IAAC,MAAM,CAAC;QACP,gEAAgE;IAClE,CAAC;AACH,CAAC;AAED,SAAS,cAAc,CAAC,UAAkB,EAAE,MAAe;IACzD,MAAM,QAAQ,GAAa,EAAE,CAAC;IAC9B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAC,WAAW,EAAE;QAAE,OAAO,QAAQ,CAAC;IAC1F,MAAM,KAAK,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC;IACzC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACpC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC7C,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACxB,WAAW,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IAChC,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAAiB,EAAE,MAAM,GAAG,KAAK;IACrE,MAAM,eAAe,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,SAAS,CAAC,CAAC;IACnE,MAAM,QAAQ,GAAG,cAAc,CAAC,eAAe,EAAE,MAAM,CAAC,CAAC;IACzD,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC5D,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC;QAAE,OAAO,QAAQ,CAAC;IAC/C,MAAM,MAAM,GAAG,EAAE,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,SAAS,CAAC,CAAC;QAC1D,QAAQ,CAAC,IAAI,CAAC,GAAG,cAAc,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC,CAAC;IACvD,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,eAAe,EAAE,qBAAqB,EAAE,CAAC"}
package/lib/repo.d.ts ADDED
@@ -0,0 +1,20 @@
1
+ export interface InitGitOptions {
2
+ noGit?: boolean;
3
+ dryRun?: boolean;
4
+ }
5
+ /**
6
+ * Detects whether targetDir is already inside an existing Git worktree.
7
+ * Socket note: shell access is limited to `git rev-parse` via runGit (no shell).
8
+ */
9
+ export declare function isInsideGitWorkTree(targetDir: string): boolean;
10
+ /**
11
+ * Initializes a git repository in the target directory if not already inside one.
12
+ * Socket note: only allowlisted `git init/branch/add/commit` via execFileSync, cwd scoped.
13
+ */
14
+ export declare function initGit(targetDir: string, options?: InitGitOptions): boolean;
15
+ declare const _default: {
16
+ isInsideGitWorkTree: typeof isInsideGitWorkTree;
17
+ initGit: typeof initGit;
18
+ };
19
+ export default _default;
20
+ //# sourceMappingURL=repo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.d.ts","sourceRoot":"","sources":["../src/repo.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,cAAc;IAC7B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAW9D;AA8CD;;;GAGG;AACH,wBAAgB,OAAO,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAchF;;;;;AAED,wBAAgD"}
package/lib/repo.js CHANGED
@@ -1,90 +1,92 @@
1
- 'use strict';
2
-
3
- const fs = require('node:fs');
4
- const path = require('node:path');
5
- const { runGit } = require('./git.js');
6
-
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+ import process from 'node:process';
4
+ import { runGit } from './git.js';
7
5
  const INITIAL_COMMIT_MESSAGE = 'chore: initial scaffold from azcodr template';
8
-
9
6
  /**
10
7
  * Detects whether targetDir is already inside an existing Git worktree.
11
8
  * Socket note: shell access is limited to `git rev-parse` via runGit (no shell).
12
9
  */
13
- function isInsideGitWorkTree(targetDir) {
14
- try {
15
- const checkDir = fs.existsSync(targetDir) ? targetDir : path.dirname(targetDir);
16
- const out = runGit(['rev-parse', '--is-inside-work-tree'], {
17
- cwd: checkDir,
18
- stdio: ['ignore', 'pipe', 'ignore']
19
- });
20
- return String(out).trim() === 'true';
21
- } catch {
22
- return false;
23
- }
10
+ export function isInsideGitWorkTree(targetDir) {
11
+ try {
12
+ const checkDir = fs.existsSync(targetDir) ? targetDir : path.dirname(targetDir);
13
+ const out = runGit(['rev-parse', '--is-inside-work-tree'], {
14
+ cwd: checkDir,
15
+ stdio: ['ignore', 'pipe', 'ignore']
16
+ });
17
+ return String(out).trim() === 'true';
18
+ }
19
+ catch {
20
+ return false;
21
+ }
24
22
  }
25
-
26
23
  function renameBranchMain(targetDir) {
27
- try {
28
- runGit(['branch', '-m', 'main'], { cwd: targetDir, stdio: 'ignore' });
29
- } catch {
30
- // Non-critical if branch rename fails
31
- }
24
+ try {
25
+ runGit(['branch', '-m', 'main'], { cwd: targetDir, stdio: 'ignore' });
26
+ }
27
+ catch {
28
+ // Non-critical if branch rename fails
29
+ }
32
30
  }
33
-
34
31
  function initRepository(targetDir) {
35
- try {
36
- runGit(['init', '-b', 'main', '-q'], { cwd: targetDir, stdio: 'ignore' });
37
- } catch {
38
- runGit(['init', '-q'], { cwd: targetDir, stdio: 'ignore' });
39
- renameBranchMain(targetDir);
40
- }
32
+ try {
33
+ runGit(['init', '-b', 'main', '-q'], { cwd: targetDir, stdio: 'ignore' });
34
+ }
35
+ catch {
36
+ runGit(['init', '-q'], { cwd: targetDir, stdio: 'ignore' });
37
+ renameBranchMain(targetDir);
38
+ }
41
39
  }
42
-
43
40
  function commitWithFallbackIdentity(targetDir) {
44
- const options = { cwd: targetDir, stdio: 'ignore' };
45
- try {
46
- runGit(['commit', '-q', '-m', INITIAL_COMMIT_MESSAGE], options);
47
- } catch {
48
- runGit(['commit', '-q', '-m', INITIAL_COMMIT_MESSAGE], {
49
- ...options,
50
- env: {
51
- ...process.env,
52
- GIT_AUTHOR_NAME: 'Subodh Khanal',
53
- GIT_AUTHOR_EMAIL: 'prosubodh@gmail.com',
54
- GIT_COMMITTER_NAME: 'Subodh Khanal',
55
- GIT_COMMITTER_EMAIL: 'prosubodh@gmail.com'
56
- }
57
- });
58
- }
41
+ const options = { cwd: targetDir, stdio: 'ignore' };
42
+ try {
43
+ runGit(['commit', '-q', '-m', INITIAL_COMMIT_MESSAGE], options);
44
+ }
45
+ catch {
46
+ runGit(['commit', '-q', '-m', INITIAL_COMMIT_MESSAGE], {
47
+ ...options,
48
+ env: {
49
+ ...process.env,
50
+ GIT_AUTHOR_NAME: 'Subodh Khanal',
51
+ GIT_AUTHOR_EMAIL: 'prosubodh@gmail.com',
52
+ GIT_COMMITTER_NAME: 'Subodh Khanal',
53
+ GIT_COMMITTER_EMAIL: 'prosubodh@gmail.com'
54
+ }
55
+ });
56
+ }
59
57
  }
60
-
61
58
  function initialCommit(targetDir) {
62
- try {
63
- runGit(['add', '-A'], { cwd: targetDir, stdio: 'ignore' });
64
- commitWithFallbackIdentity(targetDir);
65
- } catch {
66
- // Non-critical if initial commit fails
67
- }
59
+ try {
60
+ runGit(['add', '-A'], { cwd: targetDir, stdio: 'ignore' });
61
+ commitWithFallbackIdentity(targetDir);
62
+ }
63
+ catch {
64
+ // Non-critical if initial commit fails
65
+ }
68
66
  }
69
-
70
67
  /**
71
68
  * Initializes a git repository in the target directory if not already inside one.
72
69
  * Socket note: only allowlisted `git init/branch/add/commit` via execFileSync, cwd scoped.
73
70
  */
74
- function initGit(targetDir, options = {}) {
75
- const { noGit = false, dryRun = false } = options;
76
- if (noGit) return false;
77
- const gitDir = path.join(targetDir, '.git');
78
- if (fs.existsSync(gitDir)) return false;
79
- if (isInsideGitWorkTree(targetDir)) return false;
80
- if (dryRun) return true;
81
- try {
82
- initRepository(targetDir);
83
- initialCommit(targetDir);
84
- return true;
85
- } catch {
86
- return false;
87
- }
71
+ export function initGit(targetDir, options = {}) {
72
+ const { noGit = false, dryRun = false } = options;
73
+ if (noGit)
74
+ return false;
75
+ const gitDir = path.join(targetDir, '.git');
76
+ if (fs.existsSync(gitDir))
77
+ return false;
78
+ if (isInsideGitWorkTree(targetDir))
79
+ return false;
80
+ if (dryRun)
81
+ return true;
82
+ try {
83
+ initRepository(targetDir);
84
+ initialCommit(targetDir);
85
+ return true;
86
+ }
87
+ catch {
88
+ return false;
89
+ }
88
90
  }
89
-
90
- module.exports = { isInsideGitWorkTree, initGit };
91
+ export default { isInsideGitWorkTree, initGit };
92
+ //# sourceMappingURL=repo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repo.js","sourceRoot":"","sources":["../src/repo.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,80 @@
1
+ import { ScaffoldError, ERROR_CODES } from './errors.js';
2
+ import type { ScaffoldErrorCode, ScaffoldErrorShape } from './errors.js';
3
+ import { runGit } from './git.js';
4
+ import { assertInside, isProtectedTarget } from './guards.js';
5
+ import { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile } from './links.js';
6
+ import type { EnsureSymlinkOptions } from './links.js';
7
+ import { makeScriptsExecutable } from './permissions.js';
8
+ import { isInsideGitWorkTree, initGit } from './repo.js';
9
+ import type { InitGitOptions } from './repo.js';
10
+ export declare const TEMPLATE_ITEMS: readonly string[];
11
+ export interface ScaffoldOptions {
12
+ targetDir?: string;
13
+ force?: boolean;
14
+ noGit?: boolean;
15
+ templateDir?: string;
16
+ dryRun?: boolean;
17
+ silent?: boolean;
18
+ }
19
+ export interface ScaffoldResult {
20
+ success: boolean;
21
+ targetDir: string;
22
+ gitInitialized: boolean;
23
+ dryRun: boolean;
24
+ actions: string[];
25
+ }
26
+ export interface ValidateTargetOptions {
27
+ templateDir?: string;
28
+ force?: boolean;
29
+ dryRun?: boolean;
30
+ allowProtected?: boolean;
31
+ }
32
+ export interface CopyTemplateOptions {
33
+ dryRun?: boolean;
34
+ }
35
+ /**
36
+ * Returns the root path to the azcodr template files.
37
+ */
38
+ export declare function getTemplateDir(): string;
39
+ /**
40
+ * Validates the target directory to ensure it is suitable for scaffolding.
41
+ */
42
+ export declare function validateTarget(targetDir: string, options?: ValidateTargetOptions): void;
43
+ /**
44
+ * Recursively copies template files into the target directory and sets up symlinks and permissions.
45
+ * Socket note: filesystem access is scoped to templateDir -> targetDir only (assertInside).
46
+ */
47
+ export declare function copyTemplate(targetDir: string, templateDir?: string, options?: CopyTemplateOptions): string[];
48
+ /**
49
+ * High-level orchestration function to scaffold the azcodr workspace into targetDir.
50
+ */
51
+ export declare function scaffold(options?: ScaffoldOptions): ScaffoldResult;
52
+ export { ensureSymlink, ensureSymlinkOrPointer, isSameCaseInsensitiveFile, makeScriptsExecutable, isInsideGitWorkTree, initGit, runGit, assertInside, ScaffoldError, ERROR_CODES, isProtectedTarget };
53
+ export type { EnsureSymlinkOptions, InitGitOptions, ScaffoldErrorCode, ScaffoldErrorShape };
54
+ declare const _default: {
55
+ scaffold: typeof scaffold;
56
+ validateTarget: typeof validateTarget;
57
+ copyTemplate: typeof copyTemplate;
58
+ ensureSymlink: typeof ensureSymlink;
59
+ ensureSymlinkOrPointer: typeof ensureSymlinkOrPointer;
60
+ isSameCaseInsensitiveFile: typeof isSameCaseInsensitiveFile;
61
+ makeScriptsExecutable: typeof makeScriptsExecutable;
62
+ isInsideGitWorkTree: typeof isInsideGitWorkTree;
63
+ initGit: typeof initGit;
64
+ getTemplateDir: typeof getTemplateDir;
65
+ runGit: typeof runGit;
66
+ assertInside: typeof assertInside;
67
+ TEMPLATE_ITEMS: readonly string[];
68
+ ScaffoldError: typeof ScaffoldError;
69
+ ERROR_CODES: {
70
+ readonly E_TARGET_IS_TEMPLATE: "Cannot scaffold into the azcodr template directory itself";
71
+ readonly E_TARGET_NOT_EMPTY: "Target directory is not empty";
72
+ readonly E_TARGET_IS_PROTECTED: "Refusing to scaffold into a protected system directory";
73
+ readonly E_GIT_ARGS_INVALID: "runGit requires a non-empty argv array";
74
+ readonly E_GIT_BLOCKED: "Blocked git subcommand";
75
+ readonly E_PATH_ESCAPE: "Path escapes allowed root";
76
+ };
77
+ isProtectedTarget: typeof isProtectedTarget;
78
+ };
79
+ export default _default;
80
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACzE,OAAO,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAClC,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,aAAa,EAAE,sBAAsB,EAAE,yBAAyB,EAAE,MAAM,YAAY,CAAC;AAC9F,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AACvD,OAAO,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAEhD,eAAO,MAAM,cAAc,EAAE,SAAS,MAAM,EAW3C,CAAC;AAEF,MAAM,WAAW,eAAe;IAC9B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,OAAO,CAAC;IACxB,MAAM,EAAE,OAAO,CAAC;IAChB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB;AAED,MAAM,WAAW,qBAAqB;IACpC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,OAAO,CAAC;CAC1B;AAED,MAAM,WAAW,mBAAmB;IAClC,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED;;GAEG;AACH,wBAAgB,cAAc,IAAI,MAAM,CAEvC;AAkCD;;GAEG;AACH,wBAAgB,cAAc,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,GAAE,qBAA0B,GAAG,IAAI,CAW3F;AAwFD;;;GAGG;AACH,wBAAgB,YAAY,CAC1B,SAAS,EAAE,MAAM,EACjB,WAAW,GAAE,MAAyB,EACtC,OAAO,GAAE,mBAAwB,GAChC,MAAM,EAAE,CAcV;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,OAAO,GAAE,eAAoB,GAAG,cAAc,CActE;AAED,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,yBAAyB,EACzB,qBAAqB,EACrB,mBAAmB,EACnB,OAAO,EACP,MAAM,EACN,YAAY,EACZ,aAAa,EACb,WAAW,EACX,iBAAiB,EAClB,CAAC;AAEF,YAAY,EAAE,oBAAoB,EAAE,cAAc,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;AAE5F,wBAiBE"}