@scalebun-release/cli 2.5.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 (210) hide show
  1. package/bin/scalebun.js +2 -0
  2. package/lib/api/client.d.ts +52 -0
  3. package/lib/api/client.d.ts.map +1 -0
  4. package/lib/api/client.js +335 -0
  5. package/lib/api/client.js.map +1 -0
  6. package/lib/commands/ci-init.d.ts +3 -0
  7. package/lib/commands/ci-init.d.ts.map +1 -0
  8. package/lib/commands/ci-init.js +348 -0
  9. package/lib/commands/ci-init.js.map +1 -0
  10. package/lib/commands/doctor.d.ts +31 -0
  11. package/lib/commands/doctor.d.ts.map +1 -0
  12. package/lib/commands/doctor.js +559 -0
  13. package/lib/commands/doctor.js.map +1 -0
  14. package/lib/commands/launch.d.ts +3 -0
  15. package/lib/commands/launch.d.ts.map +1 -0
  16. package/lib/commands/launch.js +23 -0
  17. package/lib/commands/launch.js.map +1 -0
  18. package/lib/commands/link.d.ts +16 -0
  19. package/lib/commands/link.d.ts.map +1 -0
  20. package/lib/commands/link.js +164 -0
  21. package/lib/commands/link.js.map +1 -0
  22. package/lib/commands/login.d.ts +12 -0
  23. package/lib/commands/login.d.ts.map +1 -0
  24. package/lib/commands/login.js +124 -0
  25. package/lib/commands/login.js.map +1 -0
  26. package/lib/commands/migrate-codepush.d.ts +13 -0
  27. package/lib/commands/migrate-codepush.d.ts.map +1 -0
  28. package/lib/commands/migrate-codepush.js +98 -0
  29. package/lib/commands/migrate-codepush.js.map +1 -0
  30. package/lib/commands/ota-bundle.d.ts +22 -0
  31. package/lib/commands/ota-bundle.d.ts.map +1 -0
  32. package/lib/commands/ota-bundle.js +253 -0
  33. package/lib/commands/ota-bundle.js.map +1 -0
  34. package/lib/commands/ota-channels.d.ts +3 -0
  35. package/lib/commands/ota-channels.d.ts.map +1 -0
  36. package/lib/commands/ota-channels.js +231 -0
  37. package/lib/commands/ota-channels.js.map +1 -0
  38. package/lib/commands/ota-delete-bundle.d.ts +16 -0
  39. package/lib/commands/ota-delete-bundle.d.ts.map +1 -0
  40. package/lib/commands/ota-delete-bundle.js +96 -0
  41. package/lib/commands/ota-delete-bundle.js.map +1 -0
  42. package/lib/commands/ota-inspect.d.ts +3 -0
  43. package/lib/commands/ota-inspect.d.ts.map +1 -0
  44. package/lib/commands/ota-inspect.js +258 -0
  45. package/lib/commands/ota-inspect.js.map +1 -0
  46. package/lib/commands/ota-keys.d.ts +91 -0
  47. package/lib/commands/ota-keys.d.ts.map +1 -0
  48. package/lib/commands/ota-keys.js +765 -0
  49. package/lib/commands/ota-keys.js.map +1 -0
  50. package/lib/commands/ota-promote.d.ts +3 -0
  51. package/lib/commands/ota-promote.d.ts.map +1 -0
  52. package/lib/commands/ota-promote.js +194 -0
  53. package/lib/commands/ota-promote.js.map +1 -0
  54. package/lib/commands/ota-publish.d.ts +26 -0
  55. package/lib/commands/ota-publish.d.ts.map +1 -0
  56. package/lib/commands/ota-publish.js +892 -0
  57. package/lib/commands/ota-publish.js.map +1 -0
  58. package/lib/commands/ota-rollout.d.ts +3 -0
  59. package/lib/commands/ota-rollout.d.ts.map +1 -0
  60. package/lib/commands/ota-rollout.js +265 -0
  61. package/lib/commands/ota-rollout.js.map +1 -0
  62. package/lib/commands/ota-sign.d.ts +19 -0
  63. package/lib/commands/ota-sign.d.ts.map +1 -0
  64. package/lib/commands/ota-sign.js +245 -0
  65. package/lib/commands/ota-sign.js.map +1 -0
  66. package/lib/commands/push-apns.d.ts +3 -0
  67. package/lib/commands/push-apns.d.ts.map +1 -0
  68. package/lib/commands/push-apns.js +166 -0
  69. package/lib/commands/push-apns.js.map +1 -0
  70. package/lib/commands/quickstart.d.ts +4 -0
  71. package/lib/commands/quickstart.d.ts.map +1 -0
  72. package/lib/commands/quickstart.js +672 -0
  73. package/lib/commands/quickstart.js.map +1 -0
  74. package/lib/commands/shell.d.ts +28 -0
  75. package/lib/commands/shell.d.ts.map +1 -0
  76. package/lib/commands/shell.js +512 -0
  77. package/lib/commands/shell.js.map +1 -0
  78. package/lib/commands/tls-pins.d.ts +27 -0
  79. package/lib/commands/tls-pins.d.ts.map +1 -0
  80. package/lib/commands/tls-pins.js +209 -0
  81. package/lib/commands/tls-pins.js.map +1 -0
  82. package/lib/index.d.ts +2 -0
  83. package/lib/index.d.ts.map +1 -0
  84. package/lib/index.js +233 -0
  85. package/lib/index.js.map +1 -0
  86. package/lib/ui/banner.d.ts +23 -0
  87. package/lib/ui/banner.d.ts.map +1 -0
  88. package/lib/ui/banner.js +162 -0
  89. package/lib/ui/banner.js.map +1 -0
  90. package/lib/ui/graphics.d.ts +18 -0
  91. package/lib/ui/graphics.d.ts.map +1 -0
  92. package/lib/ui/graphics.js +134 -0
  93. package/lib/ui/graphics.js.map +1 -0
  94. package/lib/ui/mark.d.ts +4 -0
  95. package/lib/ui/mark.d.ts.map +1 -0
  96. package/lib/ui/mark.js +21 -0
  97. package/lib/ui/mark.js.map +1 -0
  98. package/lib/ui/menu.d.ts +109 -0
  99. package/lib/ui/menu.d.ts.map +1 -0
  100. package/lib/ui/menu.js +314 -0
  101. package/lib/ui/menu.js.map +1 -0
  102. package/lib/ui/sixel.d.ts +6 -0
  103. package/lib/ui/sixel.d.ts.map +1 -0
  104. package/lib/ui/sixel.js +9 -0
  105. package/lib/ui/sixel.js.map +1 -0
  106. package/lib/utils/apps.d.ts +29 -0
  107. package/lib/utils/apps.d.ts.map +1 -0
  108. package/lib/utils/apps.js +19 -0
  109. package/lib/utils/apps.js.map +1 -0
  110. package/lib/utils/browser.d.ts +9 -0
  111. package/lib/utils/browser.d.ts.map +1 -0
  112. package/lib/utils/browser.js +39 -0
  113. package/lib/utils/browser.js.map +1 -0
  114. package/lib/utils/bundle.d.ts +153 -0
  115. package/lib/utils/bundle.d.ts.map +1 -0
  116. package/lib/utils/bundle.js +459 -0
  117. package/lib/utils/bundle.js.map +1 -0
  118. package/lib/utils/bundleStore.d.ts +128 -0
  119. package/lib/utils/bundleStore.d.ts.map +1 -0
  120. package/lib/utils/bundleStore.js +250 -0
  121. package/lib/utils/bundleStore.js.map +1 -0
  122. package/lib/utils/context.d.ts +88 -0
  123. package/lib/utils/context.d.ts.map +1 -0
  124. package/lib/utils/context.js +247 -0
  125. package/lib/utils/context.js.map +1 -0
  126. package/lib/utils/credentials.d.ts +59 -0
  127. package/lib/utils/credentials.d.ts.map +1 -0
  128. package/lib/utils/credentials.js +147 -0
  129. package/lib/utils/credentials.js.map +1 -0
  130. package/lib/utils/guide.d.ts +63 -0
  131. package/lib/utils/guide.d.ts.map +1 -0
  132. package/lib/utils/guide.js +191 -0
  133. package/lib/utils/guide.js.map +1 -0
  134. package/lib/utils/hash.d.ts +3 -0
  135. package/lib/utils/hash.d.ts.map +1 -0
  136. package/lib/utils/hash.js +44 -0
  137. package/lib/utils/hash.js.map +1 -0
  138. package/lib/utils/native-id.d.ts +17 -0
  139. package/lib/utils/native-id.d.ts.map +1 -0
  140. package/lib/utils/native-id.js +105 -0
  141. package/lib/utils/native-id.js.map +1 -0
  142. package/lib/utils/output.d.ts +96 -0
  143. package/lib/utils/output.d.ts.map +1 -0
  144. package/lib/utils/output.js +135 -0
  145. package/lib/utils/output.js.map +1 -0
  146. package/lib/utils/prompt.d.ts +106 -0
  147. package/lib/utils/prompt.d.ts.map +1 -0
  148. package/lib/utils/prompt.js +457 -0
  149. package/lib/utils/prompt.js.map +1 -0
  150. package/lib/utils/provenance.d.ts +30 -0
  151. package/lib/utils/provenance.d.ts.map +1 -0
  152. package/lib/utils/provenance.js +157 -0
  153. package/lib/utils/provenance.js.map +1 -0
  154. package/lib/utils/resolve.d.ts +81 -0
  155. package/lib/utils/resolve.d.ts.map +1 -0
  156. package/lib/utils/resolve.js +139 -0
  157. package/lib/utils/resolve.js.map +1 -0
  158. package/lib/utils/sdkBin.d.ts +18 -0
  159. package/lib/utils/sdkBin.d.ts.map +1 -0
  160. package/lib/utils/sdkBin.js +76 -0
  161. package/lib/utils/sdkBin.js.map +1 -0
  162. package/lib/utils/signer.d.ts +94 -0
  163. package/lib/utils/signer.d.ts.map +1 -0
  164. package/lib/utils/signer.js +230 -0
  165. package/lib/utils/signer.js.map +1 -0
  166. package/lib/utils/signing.d.ts +102 -0
  167. package/lib/utils/signing.d.ts.map +1 -0
  168. package/lib/utils/signing.js +229 -0
  169. package/lib/utils/signing.js.map +1 -0
  170. package/lib/utils/transportSecurity.d.ts +36 -0
  171. package/lib/utils/transportSecurity.d.ts.map +1 -0
  172. package/lib/utils/transportSecurity.js +74 -0
  173. package/lib/utils/transportSecurity.js.map +1 -0
  174. package/lib/utils/trustAnchor.d.ts +109 -0
  175. package/lib/utils/trustAnchor.d.ts.map +1 -0
  176. package/lib/utils/trustAnchor.js +169 -0
  177. package/lib/utils/trustAnchor.js.map +1 -0
  178. package/lib/utils/ui.d.ts +12 -0
  179. package/lib/utils/ui.d.ts.map +1 -0
  180. package/lib/utils/ui.js +60 -0
  181. package/lib/utils/ui.js.map +1 -0
  182. package/lib/utils/validate.d.ts +62 -0
  183. package/lib/utils/validate.d.ts.map +1 -0
  184. package/lib/utils/validate.js +189 -0
  185. package/lib/utils/validate.js.map +1 -0
  186. package/lib/vendor/ota-protocol/base64.d.ts +11 -0
  187. package/lib/vendor/ota-protocol/base64.d.ts.map +1 -0
  188. package/lib/vendor/ota-protocol/base64.js +39 -0
  189. package/lib/vendor/ota-protocol/base64.js.map +1 -0
  190. package/lib/vendor/ota-protocol/codec.d.ts +26 -0
  191. package/lib/vendor/ota-protocol/codec.d.ts.map +1 -0
  192. package/lib/vendor/ota-protocol/codec.js +349 -0
  193. package/lib/vendor/ota-protocol/codec.js.map +1 -0
  194. package/lib/vendor/ota-protocol/hex.d.ts +8 -0
  195. package/lib/vendor/ota-protocol/hex.d.ts.map +1 -0
  196. package/lib/vendor/ota-protocol/hex.js +31 -0
  197. package/lib/vendor/ota-protocol/hex.js.map +1 -0
  198. package/lib/vendor/ota-protocol/index.d.ts +17 -0
  199. package/lib/vendor/ota-protocol/index.d.ts.map +1 -0
  200. package/lib/vendor/ota-protocol/index.js +41 -0
  201. package/lib/vendor/ota-protocol/index.js.map +1 -0
  202. package/lib/vendor/ota-protocol/limits.d.ts +39 -0
  203. package/lib/vendor/ota-protocol/limits.d.ts.map +1 -0
  204. package/lib/vendor/ota-protocol/limits.js +42 -0
  205. package/lib/vendor/ota-protocol/limits.js.map +1 -0
  206. package/lib/vendor/ota-protocol/types.d.ts +73 -0
  207. package/lib/vendor/ota-protocol/types.d.ts.map +1 -0
  208. package/lib/vendor/ota-protocol/types.js +24 -0
  209. package/lib/vendor/ota-protocol/types.js.map +1 -0
  210. package/package.json +37 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.d.ts","sourceRoot":"","sources":["../../src/utils/credentials.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,eAAO,MAAM,eAAe,oCAAoC,CAAC;AAEjE,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd;wDACoD;IACpD,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,eAAe,IAAI,WAAW,GAAG,IAAI,CAiBpD;AAED;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,WAAW,GAAG,IAAI,CAUzD;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,IAAI,CAuB7E;AAED,iCAAiC;AACjC,wBAAgB,gBAAgB,IAAI,IAAI,CAIvC"}
@@ -0,0 +1,147 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEFAULT_API_URL = void 0;
37
+ exports.readCredentials = readCredentials;
38
+ exports.writeCredentials = writeCredentials;
39
+ exports.restrictToCurrentUser = restrictToCurrentUser;
40
+ exports.clearCredentials = clearCredentials;
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const os = __importStar(require("os"));
44
+ const childProcess = __importStar(require("child_process"));
45
+ const CREDENTIALS_DIR = path.join(os.homedir(), '.scalebun');
46
+ const CREDENTIALS_FILE = path.join(CREDENTIALS_DIR, 'credentials.json');
47
+ /**
48
+ * The hosted ScaleBun backend. Used whenever no API URL is supplied — so login
49
+ * and CI need only a token. Override with --api-url or SCALEBUN_API_URL (e.g.
50
+ * self-hosted, staging, or http://localhost:3000/api/v1 for local dev). The
51
+ * /api/v1 suffix is required — without it every ingestion route 404s.
52
+ */
53
+ exports.DEFAULT_API_URL = 'https://api.scalebun.com/api/v1';
54
+ /**
55
+ * Read credentials. Priority:
56
+ * 1. SCALEBUN_TOKEN / SCALEBUN_API_TOKEN (+ optional SCALEBUN_API_URL) env vars (for CI)
57
+ * 2. ~/.scalebun/credentials.json (from `scalebun login`)
58
+ *
59
+ * `SCALEBUN_API_TOKEN` is the name the dashboard's CI/CD setup page issues and
60
+ * documents; `SCALEBUN_TOKEN` is the original CLI name. Both are accepted —
61
+ * `SCALEBUN_TOKEN` wins when both are set, so nothing that worked before breaks.
62
+ *
63
+ * The API URL is optional in both paths and defaults to DEFAULT_API_URL, so a
64
+ * bare token is enough to authenticate against the hosted backend.
65
+ */
66
+ function readCredentials() {
67
+ // CI path: a token env var is enough; the URL is optional.
68
+ const envToken = process.env.SCALEBUN_TOKEN || process.env.SCALEBUN_API_TOKEN;
69
+ if (envToken) {
70
+ return { apiUrl: process.env.SCALEBUN_API_URL || exports.DEFAULT_API_URL, token: envToken };
71
+ }
72
+ // Interactive path: credentials file
73
+ if (!fs.existsSync(CREDENTIALS_FILE))
74
+ return null;
75
+ try {
76
+ const raw = fs.readFileSync(CREDENTIALS_FILE, 'utf-8');
77
+ const parsed = JSON.parse(raw);
78
+ if (!parsed.token)
79
+ return null;
80
+ return { apiUrl: parsed.apiUrl || exports.DEFAULT_API_URL, token: parsed.token, email: parsed.email };
81
+ }
82
+ catch {
83
+ return null;
84
+ }
85
+ }
86
+ /**
87
+ * Store credentials to ~/.scalebun/credentials.json.
88
+ *
89
+ * The `mode: 0o600` below is real on macOS and Linux and a NO-OP ON WINDOWS —
90
+ * Node cannot express a Windows ACL through a Unix mode, so it silently drops
91
+ * it and the file lands with whatever the parent directory grants. That is how
92
+ * a token ends up readable by every other account on a shared machine while
93
+ * the code looks like it locked the file down. So on Windows the ACL is set
94
+ * explicitly afterwards, and a failure to do so is reported rather than
95
+ * swallowed: the user is entitled to know their token is sitting in a
96
+ * world-readable file.
97
+ */
98
+ function writeCredentials(creds) {
99
+ if (!fs.existsSync(CREDENTIALS_DIR)) {
100
+ fs.mkdirSync(CREDENTIALS_DIR, { recursive: true, mode: 0o700 });
101
+ }
102
+ fs.writeFileSync(CREDENTIALS_FILE, JSON.stringify(creds, null, 2) + '\n', { mode: 0o600 });
103
+ restrictToCurrentUser(CREDENTIALS_FILE, 'an access token');
104
+ }
105
+ /**
106
+ * Windows-only ACL tightening: drop inherited ACEs and grant the current user
107
+ * alone full control. On POSIX the file mode already did this and this is a
108
+ * no-op.
109
+ *
110
+ * Exported because the credentials file is not the only secret this CLI writes:
111
+ * `ota generate-key-pair` puts an RSA PRIVATE SIGNING KEY on disk, and for
112
+ * a while that file got only the POSIX `mode: 0o600` — which Node silently
113
+ * drops on Windows — while the (less valuable) access token got this full
114
+ * treatment. Every secret the CLI writes must go through here.
115
+ *
116
+ * @param file absolute path of the just-written secret file
117
+ * @param whatItHolds short description used in the failure warning, e.g.
118
+ * "an access token" / "your OTA signing private key"
119
+ */
120
+ function restrictToCurrentUser(file, whatItHolds) {
121
+ if (process.platform !== 'win32')
122
+ return;
123
+ const user = process.env.USERNAME
124
+ ? `${process.env.USERDOMAIN ? `${process.env.USERDOMAIN}\\` : ''}${process.env.USERNAME}`
125
+ : null;
126
+ if (!user)
127
+ return;
128
+ try {
129
+ // /inheritance:r removes inherited permissions — without it the grant is
130
+ // added ON TOP of whatever the profile directory already allows, which is
131
+ // usually the point being missed.
132
+ childProcess.execFileSync('icacls', [file, '/inheritance:r', '/grant:r', `${user}:F`], { stdio: 'ignore', timeout: 10000 });
133
+ }
134
+ catch {
135
+ console.warn(`⚠️ Could not restrict permissions on ${file}.\n` +
136
+ ` It contains ${whatItHolds} in plaintext and may be readable by other\n` +
137
+ ' accounts on this machine. Fix it with:\n' +
138
+ ` icacls "${file}" /inheritance:r /grant:r "%USERNAME%:F"`);
139
+ }
140
+ }
141
+ /** Delete stored credentials. */
142
+ function clearCredentials() {
143
+ if (fs.existsSync(CREDENTIALS_FILE)) {
144
+ fs.unlinkSync(CREDENTIALS_FILE);
145
+ }
146
+ }
147
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../../src/utils/credentials.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,63 @@
1
+ import { Context } from './context';
2
+ /**
3
+ * The command surface — one definition, three consumers.
4
+ *
5
+ * ── The problem ─────────────────────────────────────────────────────────────
6
+ *
7
+ * The old splash printed all 31 commands to everyone, every time. A first-time
8
+ * user could not tell which of thirty lines mattered, and `quickstart` — the
9
+ * one command that matters most — was line 14 of a wall of cyan.
10
+ *
11
+ * ── The fix ─────────────────────────────────────────────────────────────────
12
+ *
13
+ * Meet people where they are. Stage 0 shows ONE command; the grouped surface
14
+ * appears from stage 2, once a project is linked and the commands have
15
+ * something to act on. `scalebun help --all` always prints everything, so
16
+ * nobody is ever trapped in a tutorial.
17
+ *
18
+ * The stage is DERIVED (see context.ts) — never stored. A veteran opening a
19
+ * fresh repo is at stage 2 there, which is correct: they need the wiring steps
20
+ * in that checkout regardless of how many releases they have shipped elsewhere.
21
+ *
22
+ * ── Why GROUPS is data ──────────────────────────────────────────────────────
23
+ *
24
+ * The printed splash, `help --all`, and the interactive menu all describe the
25
+ * same commands. Written three times they drift — the menu offers a command
26
+ * the splash never mentions, or the splash advertises one the menu cannot
27
+ * reach, and nobody notices because each surface looks internally consistent.
28
+ * `argv` is the runnable form, so a menu entry cannot describe a command it is
29
+ * unable to launch.
30
+ */
31
+ export interface CommandEntry {
32
+ /** Argv to run, e.g. ['ota', 'publish'] — the runnable truth. */
33
+ argv: string[];
34
+ desc: string;
35
+ }
36
+ export interface CommandGroup {
37
+ title: string;
38
+ /** One line for the group menu: what this group is for. */
39
+ summary: string;
40
+ commands: CommandEntry[];
41
+ }
42
+ export declare const GROUPS: CommandGroup[];
43
+ /** How a command is written in prose and on the splash. */
44
+ export declare function commandLabel(entry: CommandEntry): string;
45
+ /**
46
+ * The stage hint as ONE line, for the interactive menu.
47
+ *
48
+ * The printed splash can afford a four-line NEXT block; a menu frame competing
49
+ * with the logo, the status box and five groups cannot. Losing it entirely
50
+ * would be worse — the ladder is what stops a newcomer from picking a command
51
+ * that cannot work yet — so it compresses rather than disappears.
52
+ */
53
+ export declare function nextStepHint(ctx: Context): string | null;
54
+ /** The one thing to do next, given the stage. */
55
+ export declare function renderNextStep(ctx: Context): void;
56
+ /** Every command, grouped by task. Printed at stage 2+ and by `help --all`. */
57
+ export declare function renderAllCommands(): void;
58
+ /** The stage-appropriate body of the splash. */
59
+ export declare function renderGuide(ctx: Context): void;
60
+ /** Context line for the splash and the session header. */
61
+ export declare function contextLineText(ctx: Context): string | null;
62
+ export declare function renderContextLine(ctx: Context): void;
63
+ //# sourceMappingURL=guide.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.d.ts","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAgB,MAAM,WAAW,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,MAAM,WAAW,YAAY;IAC3B,iEAAiE;IACjE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,CAAC;IACd,2DAA2D;IAC3D,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,YAAY,EAAE,CAAC;CAC1B;AAED,eAAO,MAAM,MAAM,EAAE,YAAY,EA0DhC,CAAC;AAEF,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,KAAK,EAAE,YAAY,GAAG,MAAM,CAExD;AAKD;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAkBxD;AAED,iDAAiD;AACjD,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CA4CjD;AAED,+EAA+E;AAC/E,wBAAgB,iBAAiB,IAAI,IAAI,CASxC;AAED,gDAAgD;AAChD,wBAAgB,WAAW,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAiB9C;AAED,0DAA0D;AAC1D,wBAAgB,eAAe,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAO3D;AAED,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,IAAI,CAGpD"}
@@ -0,0 +1,191 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.GROUPS = void 0;
7
+ exports.commandLabel = commandLabel;
8
+ exports.nextStepHint = nextStepHint;
9
+ exports.renderNextStep = renderNextStep;
10
+ exports.renderAllCommands = renderAllCommands;
11
+ exports.renderGuide = renderGuide;
12
+ exports.contextLineText = contextLineText;
13
+ exports.renderContextLine = renderContextLine;
14
+ const chalk_1 = __importDefault(require("chalk"));
15
+ const context_1 = require("./context");
16
+ exports.GROUPS = [
17
+ {
18
+ title: 'SHIP',
19
+ summary: 'get a new bundle in front of devices',
20
+ commands: [
21
+ { argv: ['ota', 'publish'], desc: 'bundle, upload and publish a release' },
22
+ { argv: ['ota', 'promote'], desc: 'promote an uploaded bundle to a channel' },
23
+ { argv: ['ota', 'bundles'], desc: 'list uploaded bundles, newest first' },
24
+ { argv: ['ota', 'bundle', 'build'], desc: 'build a bundle file for manual upload' },
25
+ { argv: ['ota', 'sign'], desc: 'sign a built bundle so it can be uploaded from the dashboard' },
26
+ ],
27
+ },
28
+ {
29
+ title: 'CONTROL',
30
+ summary: 'change or stop what is already shipping',
31
+ commands: [
32
+ { argv: ['ota', 'rollout'], desc: 'set the rollout percentage' },
33
+ { argv: ['ota', 'pause'], desc: 'stop new devices receiving a release' },
34
+ { argv: ['ota', 'resume'], desc: 'resume a paused release' },
35
+ { argv: ['ota', 'rollback'], desc: 'revert a release for every device' },
36
+ ],
37
+ },
38
+ {
39
+ title: 'INSPECT',
40
+ summary: 'see what is live and what needs a decision',
41
+ commands: [
42
+ { argv: ['ota', 'status'], desc: 'what is live, and what needs a decision' },
43
+ { argv: ['ota', 'releases'], desc: 'list releases and their rollout state' },
44
+ { argv: ['apps'], desc: 'list your apps and their ids' },
45
+ ],
46
+ },
47
+ {
48
+ title: 'CONFIGURE',
49
+ summary: 'channels, signing keys, and deletions',
50
+ commands: [
51
+ { argv: ['ota', 'channels'], desc: 'list, create, rename or remove channels' },
52
+ { argv: ['ota', 'keys'], desc: 'list, register or revoke signing keys' },
53
+ { argv: ['ota', 'generate-key-pair'], desc: 'create an RSA-3072 signing key' },
54
+ { argv: ['ota', 'keys', 'verify'], desc: 'prove you hold the private half (activate a pending key)' },
55
+ { argv: ['ota', 'delete-bundle'], desc: 'delete a bundle permanently' },
56
+ ],
57
+ },
58
+ {
59
+ title: 'SETUP',
60
+ summary: 'sign in, bind the project, wire the native app',
61
+ commands: [
62
+ { argv: ['quickstart'], desc: 'guided first-release walkthrough' },
63
+ { argv: ['login'], desc: 'authenticate with an access token' },
64
+ { argv: ['logout'], desc: 'clear stored credentials' },
65
+ { argv: ['link'], desc: 'bind this project to an app' },
66
+ { argv: ['unlink'], desc: 'remove the app binding' },
67
+ { argv: ['init', 'android'], desc: 'wire the Android app for OTA' },
68
+ { argv: ['init', 'ios'], desc: 'wire the iOS app for OTA' },
69
+ { argv: ['doctor'], desc: 'check the project is OTA-ready' },
70
+ { argv: ['ci', 'init'], desc: 'generate a CI pipeline for publishing' },
71
+ { argv: ['migrate', 'codepush'], desc: 'migrate from Microsoft CodePush' },
72
+ ],
73
+ },
74
+ ];
75
+ /** How a command is written in prose and on the splash. */
76
+ function commandLabel(entry) {
77
+ return `scalebun ${entry.argv.join(' ')}`;
78
+ }
79
+ const cmd = (name, desc, pad = 32) => console.log(` ${chalk_1.default.cyan(name.padEnd(pad))} ${chalk_1.default.dim(desc)}`);
80
+ /**
81
+ * The stage hint as ONE line, for the interactive menu.
82
+ *
83
+ * The printed splash can afford a four-line NEXT block; a menu frame competing
84
+ * with the logo, the status box and five groups cannot. Losing it entirely
85
+ * would be worse — the ladder is what stops a newcomer from picking a command
86
+ * that cannot work yet — so it compresses rather than disappears.
87
+ */
88
+ function nextStepHint(ctx) {
89
+ const line = (lead, command, why) => chalk_1.default.dim(` ${lead} `) + chalk_1.default.green(command) + chalk_1.default.dim(` ${why}`);
90
+ switch (ctx.stage) {
91
+ case 0:
92
+ return line('start here', 'scalebun quickstart', 'sign in, pick an app, wire it, ship an update');
93
+ case 1:
94
+ return line('next', 'scalebun link', 'bind this project to an app');
95
+ case 2: {
96
+ const p = ctx.platforms.find((x) => ctx.wired[x] === false) ?? ctx.platforms[0] ?? 'android';
97
+ return line('next', `scalebun init ${p}`, 'updates install but never load until this is done');
98
+ }
99
+ case 3:
100
+ return line('next', 'scalebun ota publish', 'bundle, upload and ship your first update');
101
+ default:
102
+ return null;
103
+ }
104
+ }
105
+ /** The one thing to do next, given the stage. */
106
+ function renderNextStep(ctx) {
107
+ console.log('');
108
+ switch (ctx.stage) {
109
+ case 0:
110
+ console.log(` ${chalk_1.default.bold.white('START HERE')}`);
111
+ console.log(` ${chalk_1.default.green('scalebun quickstart')} ${chalk_1.default.dim('sign in, pick an app, wire it, ship an update')}`);
112
+ console.log('');
113
+ console.log(chalk_1.default.dim(' One guided flow. Everything else becomes relevant once it finishes.'));
114
+ break;
115
+ case 1:
116
+ console.log(` ${chalk_1.default.bold.white('NEXT')}`);
117
+ console.log(` ${chalk_1.default.green('scalebun link')} ${chalk_1.default.dim('bind this project to an app — then --app-id is never needed')}`);
118
+ console.log('');
119
+ cmd('scalebun quickstart', 'or continue the guided flow', 22);
120
+ cmd('scalebun apps', 'list the apps you can publish to', 22);
121
+ break;
122
+ case 2: {
123
+ const p = ctx.platforms.find((x) => ctx.wired[x] === false) ?? ctx.platforms[0] ?? 'android';
124
+ console.log(` ${chalk_1.default.bold.white('NEXT')}`);
125
+ console.log(` ${chalk_1.default.green('scalebun init ' + p)} ${chalk_1.default.dim('wire the native app for OTA, then rebuild')}`);
126
+ console.log('');
127
+ console.log(chalk_1.default.dim(' Updates install but never load until this is done.'));
128
+ cmd('scalebun doctor', 'check what else this project needs', 22);
129
+ break;
130
+ }
131
+ case 3:
132
+ console.log(` ${chalk_1.default.bold.white('NEXT')}`);
133
+ console.log(` ${chalk_1.default.green('scalebun ota publish')} ${chalk_1.default.dim('bundle, upload and ship your first update')}`);
134
+ console.log('');
135
+ // Pad to 32 — the same column renderAllCommands uses, because the
136
+ // grouped surface now prints directly beneath this block.
137
+ if (!ctx.hasSigningKey) {
138
+ cmd('scalebun ota generate-key-pair', 'sign your bundles (recommended)');
139
+ }
140
+ cmd('scalebun doctor', 'verify the project once more');
141
+ break;
142
+ case 4:
143
+ // No hand-holding at stage 4 — the full surface follows.
144
+ break;
145
+ }
146
+ }
147
+ /** Every command, grouped by task. Printed at stage 2+ and by `help --all`. */
148
+ function renderAllCommands() {
149
+ for (const g of exports.GROUPS) {
150
+ console.log('');
151
+ console.log(` ${chalk_1.default.bold.white(g.title)}`);
152
+ for (const c of g.commands)
153
+ cmd(commandLabel(c), c.desc);
154
+ }
155
+ console.log('');
156
+ console.log(chalk_1.default.dim(` Every flag: ${chalk_1.default.cyan('scalebun <command> --help')}`));
157
+ console.log('');
158
+ }
159
+ /** The stage-appropriate body of the splash. */
160
+ function renderGuide(ctx) {
161
+ renderNextStep(ctx);
162
+ // Stage 2 — linked — is where the map earns its space. Gating the grouped
163
+ // surface on stage 4 (a release already shipped) was too strict: it withheld
164
+ // the command list from exactly the person walking the setup path, who has
165
+ // committed to the tool and now wants to see what it does. Before stage 2
166
+ // there is no app bound, so most of the surface has nothing to act on and
167
+ // printing it buries the one step that does.
168
+ if (ctx.stage >= 2) {
169
+ renderAllCommands();
170
+ return;
171
+ }
172
+ console.log('');
173
+ console.log(chalk_1.default.dim(` All commands: ${chalk_1.default.cyan('scalebun help --all')}`));
174
+ console.log('');
175
+ }
176
+ /** Context line for the splash and the session header. */
177
+ function contextLineText(ctx) {
178
+ const label = (0, context_1.contextLabel)(ctx);
179
+ if (!label)
180
+ return null;
181
+ const wired = ctx.platforms
182
+ .map((p) => `${p} ${ctx.wired[p] ? chalk_1.default.green('wired') : chalk_1.default.yellow('not wired')}`)
183
+ .join(chalk_1.default.dim(' · '));
184
+ return chalk_1.default.dim(' project ') + chalk_1.default.bold(label) + (wired ? chalk_1.default.dim(' · ') + wired : '');
185
+ }
186
+ function renderContextLine(ctx) {
187
+ const line = contextLineText(ctx);
188
+ if (line)
189
+ console.log(line);
190
+ }
191
+ //# sourceMappingURL=guide.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guide.js","sourceRoot":"","sources":["../../src/utils/guide.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ /** Compute SHA-256 hex digest of a file. */
2
+ export declare function sha256File(filePath: string): string;
3
+ //# sourceMappingURL=hash.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.d.ts","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":"AAGA,4CAA4C;AAC5C,wBAAgB,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGnD"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.sha256File = sha256File;
37
+ const crypto = __importStar(require("crypto"));
38
+ const fs = __importStar(require("fs"));
39
+ /** Compute SHA-256 hex digest of a file. */
40
+ function sha256File(filePath) {
41
+ const content = fs.readFileSync(filePath);
42
+ return crypto.createHash('sha256').update(content).digest('hex');
43
+ }
44
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/utils/hash.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAIA,gCAGC;AAPD,+CAAiC;AACjC,uCAAyB;AAEzB,4CAA4C;AAC5C,SAAgB,UAAU,CAAC,QAAgB;IACzC,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC1C,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AACnE,CAAC"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Best-effort detection of the binary's native application id — the Android
3
+ * `applicationId` or the iOS bundle identifier.
4
+ *
5
+ * Why the CLI cares: a signed OTA release (SB-OTA-RSA-SHA256-V1) is identified by
6
+ * this value, and the device's native verifier rejects any release whose
7
+ * `applicationId` does not equal its own package name. The server stores it as
8
+ * `apps.bundleId`, but that column is optional at app creation, so most apps have
9
+ * it null. By reading the real id out of the project and sending it at presign,
10
+ * the backend can self-heal the app record on the first publish — no manual data
11
+ * entry, and no confusing "backend did not return release identity" failure.
12
+ *
13
+ * Returns `undefined` when it cannot be determined (a monorepo layout, a
14
+ * non-standard project, etc.); the caller simply omits the field.
15
+ */
16
+ export declare function detectNativeApplicationId(platform: string, cwd?: string): string | undefined;
17
+ //# sourceMappingURL=native-id.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-id.d.ts","sourceRoot":"","sources":["../../src/utils/native-id.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,yBAAyB,CACvC,QAAQ,EAAE,MAAM,EAChB,GAAG,GAAE,MAAsB,GAC1B,MAAM,GAAG,SAAS,CAQpB"}
@@ -0,0 +1,105 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.detectNativeApplicationId = detectNativeApplicationId;
37
+ const fs = __importStar(require("fs"));
38
+ const path = __importStar(require("path"));
39
+ /**
40
+ * Best-effort detection of the binary's native application id — the Android
41
+ * `applicationId` or the iOS bundle identifier.
42
+ *
43
+ * Why the CLI cares: a signed OTA release (SB-OTA-RSA-SHA256-V1) is identified by
44
+ * this value, and the device's native verifier rejects any release whose
45
+ * `applicationId` does not equal its own package name. The server stores it as
46
+ * `apps.bundleId`, but that column is optional at app creation, so most apps have
47
+ * it null. By reading the real id out of the project and sending it at presign,
48
+ * the backend can self-heal the app record on the first publish — no manual data
49
+ * entry, and no confusing "backend did not return release identity" failure.
50
+ *
51
+ * Returns `undefined` when it cannot be determined (a monorepo layout, a
52
+ * non-standard project, etc.); the caller simply omits the field.
53
+ */
54
+ function detectNativeApplicationId(platform, cwd = process.cwd()) {
55
+ try {
56
+ if (platform === 'android')
57
+ return detectAndroidApplicationId(cwd);
58
+ if (platform === 'ios')
59
+ return detectIosBundleId(cwd);
60
+ }
61
+ catch {
62
+ // Detection is a convenience, never a hard dependency — never throw.
63
+ }
64
+ return undefined;
65
+ }
66
+ function detectAndroidApplicationId(cwd) {
67
+ const gradlePath = path.join(cwd, 'android', 'app', 'build.gradle');
68
+ if (!fs.existsSync(gradlePath))
69
+ return undefined;
70
+ const gradle = fs.readFileSync(gradlePath, 'utf8');
71
+ // `applicationId "com.example.app"` (or single quotes). Prefer applicationId;
72
+ // fall back to `namespace` which RN's defaultConfig derives the id from when
73
+ // applicationId is omitted.
74
+ const appId = matchQuoted(gradle, /applicationId\s+["']([^"']+)["']/) ??
75
+ matchQuoted(gradle, /namespace\s+["']([^"']+)["']/);
76
+ return appId;
77
+ }
78
+ function detectIosBundleId(cwd) {
79
+ const iosDir = path.join(cwd, 'ios');
80
+ if (!fs.existsSync(iosDir))
81
+ return undefined;
82
+ // Find the app's project.pbxproj (…/<App>.xcodeproj/project.pbxproj).
83
+ const xcodeproj = fs
84
+ .readdirSync(iosDir)
85
+ .find((name) => name.endsWith('.xcodeproj'));
86
+ if (!xcodeproj)
87
+ return undefined;
88
+ const pbxPath = path.join(iosDir, xcodeproj, 'project.pbxproj');
89
+ if (!fs.existsSync(pbxPath))
90
+ return undefined;
91
+ const pbx = fs.readFileSync(pbxPath, 'utf8');
92
+ // Collect every PRODUCT_BUNDLE_IDENTIFIER, drop test/extension targets, and
93
+ // prefer a literal id over an unresolved `$(...)` variable.
94
+ const ids = Array.from(pbx.matchAll(/PRODUCT_BUNDLE_IDENTIFIER\s*=\s*"?([^";]+)"?;/g))
95
+ .map((m) => m[1].trim())
96
+ .filter((id) => id.length > 0 &&
97
+ !/\.(Tests|UITests|test|ShareExtension|watchkit)/i.test(id));
98
+ const literal = ids.find((id) => !id.includes('$('));
99
+ return literal ?? ids[0];
100
+ }
101
+ function matchQuoted(src, re) {
102
+ const m = src.match(re);
103
+ return m ? m[1].trim() : undefined;
104
+ }
105
+ //# sourceMappingURL=native-id.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"native-id.js","sourceRoot":"","sources":["../../src/utils/native-id.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkBA,8DAWC;AA7BD,uCAAyB;AACzB,2CAA6B;AAE7B;;;;;;;;;;;;;;GAcG;AACH,SAAgB,yBAAyB,CACvC,QAAgB,EAChB,MAAc,OAAO,CAAC,GAAG,EAAE;IAE3B,IAAI,CAAC;QACH,IAAI,QAAQ,KAAK,SAAS;YAAE,OAAO,0BAA0B,CAAC,GAAG,CAAC,CAAC;QACnE,IAAI,QAAQ,KAAK,KAAK;YAAE,OAAO,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACxD,CAAC;IAAC,MAAM,CAAC;QACP,qEAAqE;IACvE,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,SAAS,0BAA0B,CAAC,GAAW;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,SAAS,EAAE,KAAK,EAAE,cAAc,CAAC,CAAC;IACpE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,UAAU,CAAC;QAAE,OAAO,SAAS,CAAC;IACjD,MAAM,MAAM,GAAG,EAAE,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAEnD,8EAA8E;IAC9E,6EAA6E;IAC7E,4BAA4B;IAC5B,MAAM,KAAK,GACT,WAAW,CAAC,MAAM,EAAE,kCAAkC,CAAC;QACvD,WAAW,CAAC,MAAM,EAAE,8BAA8B,CAAC,CAAC;IACtD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,iBAAiB,CAAC,GAAW;IACpC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IACrC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,SAAS,CAAC;IAE7C,sEAAsE;IACtE,MAAM,SAAS,GAAG,EAAE;SACjB,WAAW,CAAC,MAAM,CAAC;SACnB,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC;IAC/C,IAAI,CAAC,SAAS;QAAE,OAAO,SAAS,CAAC;IACjC,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,iBAAiB,CAAC,CAAC;IAChE,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,OAAO,CAAC;QAAE,OAAO,SAAS,CAAC;IAC9C,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC;IAE7C,4EAA4E;IAC5E,4DAA4D;IAC5D,MAAM,GAAG,GAAG,KAAK,CAAC,IAAI,CACpB,GAAG,CAAC,QAAQ,CAAC,gDAAgD,CAAC,CAC/D;SACE,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;SACvB,MAAM,CACL,CAAC,EAAE,EAAE,EAAE,CACL,EAAE,CAAC,MAAM,GAAG,CAAC;QACb,CAAC,iDAAiD,CAAC,IAAI,CAAC,EAAE,CAAC,CAC9D,CAAC;IACJ,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC;IACrD,OAAO,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC;AAC3B,CAAC;AAED,SAAS,WAAW,CAAC,GAAW,EAAE,EAAU;IAC1C,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACxB,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC;AACrC,CAAC"}