orcasynth 1.2.1 → 1.3.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 (126) hide show
  1. package/dist/cli/install/index.js +113 -29
  2. package/dist/cli/install/systemdUnits.js +1 -1
  3. package/dist/cli/installInfo.js +15 -0
  4. package/dist/cli/menu.js +85 -1
  5. package/package.json +1 -1
  6. package/web-dist/.next/BUILD_ID +1 -1
  7. package/web-dist/.next/build-manifest.json +3 -3
  8. package/web-dist/.next/server/app/_global-error.html +1 -1
  9. package/web-dist/.next/server/app/_global-error.rsc +1 -1
  10. package/web-dist/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  11. package/web-dist/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  12. package/web-dist/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  13. package/web-dist/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  14. package/web-dist/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  15. package/web-dist/.next/server/app/_not-found.html +1 -1
  16. package/web-dist/.next/server/app/_not-found.rsc +1 -1
  17. package/web-dist/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  18. package/web-dist/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  19. package/web-dist/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  20. package/web-dist/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  21. package/web-dist/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  22. package/web-dist/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  23. package/web-dist/.next/server/app/account.html +1 -1
  24. package/web-dist/.next/server/app/account.rsc +1 -1
  25. package/web-dist/.next/server/app/account.segments/_full.segment.rsc +1 -1
  26. package/web-dist/.next/server/app/account.segments/_head.segment.rsc +1 -1
  27. package/web-dist/.next/server/app/account.segments/_index.segment.rsc +1 -1
  28. package/web-dist/.next/server/app/account.segments/_tree.segment.rsc +1 -1
  29. package/web-dist/.next/server/app/account.segments/account/__PAGE__.segment.rsc +1 -1
  30. package/web-dist/.next/server/app/account.segments/account.segment.rsc +1 -1
  31. package/web-dist/.next/server/app/dash.html +1 -1
  32. package/web-dist/.next/server/app/dash.rsc +1 -1
  33. package/web-dist/.next/server/app/dash.segments/_full.segment.rsc +1 -1
  34. package/web-dist/.next/server/app/dash.segments/_head.segment.rsc +1 -1
  35. package/web-dist/.next/server/app/dash.segments/_index.segment.rsc +1 -1
  36. package/web-dist/.next/server/app/dash.segments/_tree.segment.rsc +1 -1
  37. package/web-dist/.next/server/app/dash.segments/dash/__PAGE__.segment.rsc +1 -1
  38. package/web-dist/.next/server/app/dash.segments/dash.segment.rsc +1 -1
  39. package/web-dist/.next/server/app/escalations.html +1 -1
  40. package/web-dist/.next/server/app/escalations.rsc +1 -1
  41. package/web-dist/.next/server/app/escalations.segments/_full.segment.rsc +1 -1
  42. package/web-dist/.next/server/app/escalations.segments/_head.segment.rsc +1 -1
  43. package/web-dist/.next/server/app/escalations.segments/_index.segment.rsc +1 -1
  44. package/web-dist/.next/server/app/escalations.segments/_tree.segment.rsc +1 -1
  45. package/web-dist/.next/server/app/escalations.segments/escalations/__PAGE__.segment.rsc +1 -1
  46. package/web-dist/.next/server/app/escalations.segments/escalations.segment.rsc +1 -1
  47. package/web-dist/.next/server/app/index.html +1 -1
  48. package/web-dist/.next/server/app/index.rsc +1 -1
  49. package/web-dist/.next/server/app/index.segments/__PAGE__.segment.rsc +1 -1
  50. package/web-dist/.next/server/app/index.segments/_full.segment.rsc +1 -1
  51. package/web-dist/.next/server/app/index.segments/_head.segment.rsc +1 -1
  52. package/web-dist/.next/server/app/index.segments/_index.segment.rsc +1 -1
  53. package/web-dist/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  54. package/web-dist/.next/server/app/kanban.html +1 -1
  55. package/web-dist/.next/server/app/kanban.rsc +1 -1
  56. package/web-dist/.next/server/app/kanban.segments/_full.segment.rsc +1 -1
  57. package/web-dist/.next/server/app/kanban.segments/_head.segment.rsc +1 -1
  58. package/web-dist/.next/server/app/kanban.segments/_index.segment.rsc +1 -1
  59. package/web-dist/.next/server/app/kanban.segments/_tree.segment.rsc +1 -1
  60. package/web-dist/.next/server/app/kanban.segments/kanban/__PAGE__.segment.rsc +1 -1
  61. package/web-dist/.next/server/app/kanban.segments/kanban.segment.rsc +1 -1
  62. package/web-dist/.next/server/app/onboarding.html +1 -1
  63. package/web-dist/.next/server/app/onboarding.rsc +1 -1
  64. package/web-dist/.next/server/app/onboarding.segments/_full.segment.rsc +1 -1
  65. package/web-dist/.next/server/app/onboarding.segments/_head.segment.rsc +1 -1
  66. package/web-dist/.next/server/app/onboarding.segments/_index.segment.rsc +1 -1
  67. package/web-dist/.next/server/app/onboarding.segments/_tree.segment.rsc +1 -1
  68. package/web-dist/.next/server/app/onboarding.segments/onboarding/__PAGE__.segment.rsc +1 -1
  69. package/web-dist/.next/server/app/onboarding.segments/onboarding.segment.rsc +1 -1
  70. package/web-dist/.next/server/app/projects.html +1 -1
  71. package/web-dist/.next/server/app/projects.rsc +1 -1
  72. package/web-dist/.next/server/app/projects.segments/_full.segment.rsc +1 -1
  73. package/web-dist/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  74. package/web-dist/.next/server/app/projects.segments/_index.segment.rsc +1 -1
  75. package/web-dist/.next/server/app/projects.segments/_tree.segment.rsc +1 -1
  76. package/web-dist/.next/server/app/projects.segments/projects/__PAGE__.segment.rsc +1 -1
  77. package/web-dist/.next/server/app/projects.segments/projects.segment.rsc +1 -1
  78. package/web-dist/.next/server/app/sessions.html +1 -1
  79. package/web-dist/.next/server/app/sessions.rsc +1 -1
  80. package/web-dist/.next/server/app/sessions.segments/_full.segment.rsc +1 -1
  81. package/web-dist/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  82. package/web-dist/.next/server/app/sessions.segments/_index.segment.rsc +1 -1
  83. package/web-dist/.next/server/app/sessions.segments/_tree.segment.rsc +1 -1
  84. package/web-dist/.next/server/app/sessions.segments/sessions/__PAGE__.segment.rsc +1 -1
  85. package/web-dist/.next/server/app/sessions.segments/sessions.segment.rsc +1 -1
  86. package/web-dist/.next/server/app/settings.html +1 -1
  87. package/web-dist/.next/server/app/settings.rsc +1 -1
  88. package/web-dist/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  89. package/web-dist/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  90. package/web-dist/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  91. package/web-dist/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  92. package/web-dist/.next/server/app/settings.segments/settings/__PAGE__.segment.rsc +1 -1
  93. package/web-dist/.next/server/app/settings.segments/settings.segment.rsc +1 -1
  94. package/web-dist/.next/server/app/tasks.html +1 -1
  95. package/web-dist/.next/server/app/tasks.rsc +1 -1
  96. package/web-dist/.next/server/app/tasks.segments/_full.segment.rsc +1 -1
  97. package/web-dist/.next/server/app/tasks.segments/_head.segment.rsc +1 -1
  98. package/web-dist/.next/server/app/tasks.segments/_index.segment.rsc +1 -1
  99. package/web-dist/.next/server/app/tasks.segments/_tree.segment.rsc +1 -1
  100. package/web-dist/.next/server/app/tasks.segments/tasks/__PAGE__.segment.rsc +1 -1
  101. package/web-dist/.next/server/app/tasks.segments/tasks.segment.rsc +1 -1
  102. package/web-dist/.next/server/app/timeline.html +1 -1
  103. package/web-dist/.next/server/app/timeline.rsc +1 -1
  104. package/web-dist/.next/server/app/timeline.segments/_full.segment.rsc +1 -1
  105. package/web-dist/.next/server/app/timeline.segments/_head.segment.rsc +1 -1
  106. package/web-dist/.next/server/app/timeline.segments/_index.segment.rsc +1 -1
  107. package/web-dist/.next/server/app/timeline.segments/_tree.segment.rsc +1 -1
  108. package/web-dist/.next/server/app/timeline.segments/timeline/__PAGE__.segment.rsc +1 -1
  109. package/web-dist/.next/server/app/timeline.segments/timeline.segment.rsc +1 -1
  110. package/web-dist/.next/server/app/users.html +1 -1
  111. package/web-dist/.next/server/app/users.rsc +1 -1
  112. package/web-dist/.next/server/app/users.segments/_full.segment.rsc +1 -1
  113. package/web-dist/.next/server/app/users.segments/_head.segment.rsc +1 -1
  114. package/web-dist/.next/server/app/users.segments/_index.segment.rsc +1 -1
  115. package/web-dist/.next/server/app/users.segments/_tree.segment.rsc +1 -1
  116. package/web-dist/.next/server/app/users.segments/users/__PAGE__.segment.rsc +1 -1
  117. package/web-dist/.next/server/app/users.segments/users.segment.rsc +1 -1
  118. package/web-dist/.next/server/chunks/[root-of-the-server]__0bvp8h1._.js +1 -1
  119. package/web-dist/.next/server/chunks/[root-of-the-server]__1dgbigm._.js +1 -1
  120. package/web-dist/.next/server/chunks/[root-of-the-server]__1wxxtv8._.js +1 -1
  121. package/web-dist/.next/server/middleware-build-manifest.js +3 -3
  122. package/web-dist/.next/server/pages/404.html +1 -1
  123. package/web-dist/.next/server/pages/500.html +1 -1
  124. /package/web-dist/.next/static/{bvh5kJTXH2EYcTgp6Gxcw → hDw78YoaHr7BxL_Us9pPD}/_buildManifest.js +0 -0
  125. /package/web-dist/.next/static/{bvh5kJTXH2EYcTgp6Gxcw → hDw78YoaHr7BxL_Us9pPD}/_clientMiddlewareManifest.js +0 -0
  126. /package/web-dist/.next/static/{bvh5kJTXH2EYcTgp6Gxcw → hDw78YoaHr7BxL_Us9pPD}/_ssgManifest.js +0 -0
@@ -9,8 +9,19 @@ import { daemonUnit, webUnit } from './systemdUnits.js';
9
9
  import { detectProxy, nginxVhost, apacheVhost, certbotCommand } from './proxy.js';
10
10
  import { applySetup, buildSetupPlan, isFirstRun } from '../setup.js';
11
11
  import { runSetupWizard } from '../setupWizard.js';
12
+ import { INSTALL_INFO_PATH, serializeInstallInfo } from '../installInfo.js';
12
13
  const DAEMON_PORT = Number(process.env.ORCA_PORT ?? 4400);
13
14
  const WEB_PORT = Number(process.env.ORCA_WEB_PORT ?? 4500);
15
+ /** Canonical public URL for a deployment, given whether TLS actually came up. */
16
+ function publicUrl(d, tlsOk) {
17
+ if (d.mode === 'domain')
18
+ return `${tlsOk ? 'https' : 'http'}://${d.host}`;
19
+ if (d.mode === 'ip')
20
+ return `http://${d.host}:${WEB_PORT}`;
21
+ return `http://localhost:${WEB_PORT}`;
22
+ }
23
+ const localhostDeploy = () => ({ mode: 'localhost', host: 'localhost', domain: null, proxyPreference: 'nginx', tls: false, email: null, webHost: '127.0.0.1' });
24
+ const ipDeploy = (host) => ({ mode: 'ip', host, domain: null, proxyPreference: 'nginx', tls: false, email: null, webHost: '0.0.0.0' });
14
25
  // ── package + npm path resolution ────────────────────────────────────────────
15
26
  /** Absolute paths into the globally-installed package — this file lives at
16
27
  * <pkgRoot>/dist/cli/install/index.js, so the daemon entry and web bundle resolve relative to it. */
@@ -31,6 +42,11 @@ function bail(v) {
31
42
  process.exit(1);
32
43
  }
33
44
  }
45
+ /** True for a bare IPv4/IPv6 host. Let's Encrypt only issues for registered domain names, so we never
46
+ * offer (or attempt) HTTPS for an IP — certbot would fail every time. */
47
+ export function isIpAddress(host) {
48
+ return /^\d{1,3}(\.\d{1,3}){3}$/.test(host) || host.includes(':');
49
+ }
34
50
  async function step(label, fn) {
35
51
  // Off a TTY (unattended / CI / piped logs) a spinner just spams frames — emit one line per step.
36
52
  if (!process.stdout.isTTY) {
@@ -93,11 +109,11 @@ async function aptInstall(r, ...pkgs) {
93
109
  await must(r, 'apt-get', ['install', '-y', ...pkgs]);
94
110
  }
95
111
  /** Write + enable the two systemd units and verify they came active. */
96
- async function provisionSystemd(r, user, home) {
112
+ async function provisionSystemd(r, user, home, webHost) {
97
113
  const { daemonEntry, webServer } = packagePaths();
98
114
  const params = {
99
115
  user, home, nodePath: process.execPath, daemonEntry, webServer,
100
- npmGlobalBin: await npmGlobalBin(r), daemonPort: DAEMON_PORT, webPort: WEB_PORT,
116
+ npmGlobalBin: await npmGlobalBin(r), daemonPort: DAEMON_PORT, webPort: WEB_PORT, webHost,
101
117
  };
102
118
  // Ensure the data tree exists and is owned by the service user before first boot.
103
119
  await must(r, 'mkdir', ['-p', join(home, '.config', 'orca', 'logs')]);
@@ -154,7 +170,8 @@ async function provisionAdmin(answers) {
154
170
  await loginSmokeTest(answers.username, answers.password);
155
171
  }
156
172
  /** Provision a box from a fully-resolved plan. Used directly by the unattended path; the interactive
157
- * path drives the same executors with spinners and inline prompts. */
173
+ * path drives the same executors with spinners and inline prompts. Returns whether TLS was obtained,
174
+ * so the caller can build the final URL (a non-fatal certbot failure leaves the site on HTTP). */
158
175
  async function execute(r, plan) {
159
176
  if (plan.installTmux)
160
177
  await step('Installing tmux', () => aptInstall(r, 'tmux'));
@@ -163,21 +180,38 @@ async function execute(r, plan) {
163
180
  const { cmd, args } = installCommand({ id, bin: id, pkg: agentPkg(id) });
164
181
  await step(`Installing ${id}`, () => must(r, cmd, args));
165
182
  }
166
- await step('Configuring systemd services', () => provisionSystemd(r, plan.user.username, home));
183
+ await step('Configuring systemd services', () => provisionSystemd(r, plan.user.username, home, plan.deploy.webHost));
167
184
  const ready = await step('Waiting for the daemon', () => waitForDaemon());
168
185
  if (!ready)
169
186
  throw new Error('daemon did not become reachable — check: journalctl -u orca-daemon');
170
- if (plan.domain) {
187
+ const d = plan.deploy;
188
+ let tlsOk = false;
189
+ if (d.mode === 'domain' && d.domain) {
171
190
  const kind = await step('Configuring reverse proxy', async () => {
172
- const k = await resolveProxy(r, plan.proxyPreference);
173
- await configureVhost(r, k, plan.domain);
191
+ const k = await resolveProxy(r, d.proxyPreference);
192
+ await configureVhost(r, k, d.domain);
174
193
  return k;
175
194
  });
176
- if (plan.tls)
177
- await step('Requesting HTTPS certificate', () => obtainTls(r, kind, plan.domain, plan.email));
195
+ // TLS is the last, optional, most failure-prone step (DNS not pointed yet, rate limits, IPs). A
196
+ // failure here must NOT abort the install the site already serves over HTTP and the admin still
197
+ // needs creating — so we warn and carry on rather than throwing.
198
+ if (d.tls) {
199
+ try {
200
+ await step('Requesting HTTPS certificate', () => obtainTls(r, kind, d.domain, d.email));
201
+ tlsOk = true;
202
+ }
203
+ catch (e) {
204
+ p.log.warn(`HTTPS setup failed: ${e.message}\nThe site is up over HTTP — re-run certbot once the domain's DNS points here.`);
205
+ }
206
+ }
178
207
  }
179
208
  if (plan.admin)
180
209
  await step('Creating admin + verifying login', () => provisionAdmin(plan.admin));
210
+ // Record the deployment so the launcher menu shows the right URL and drives systemd (not a 2nd daemon).
211
+ const info = { publicUrl: publicUrl(d, tlsOk), mode: d.mode, serviceUser: plan.user.username, daemonPort: DAEMON_PORT, webPort: WEB_PORT };
212
+ await must(r, 'mkdir', ['-p', '/etc/orca']);
213
+ await r.writeFile(INSTALL_INFO_PATH, serializeInstallInfo(info));
214
+ return { tls: tlsOk };
181
215
  }
182
216
  /** npm package for an agent CLI id (so the executor needn't carry the full AgentCli around). */
183
217
  function agentPkg(id) {
@@ -201,7 +235,6 @@ async function planFromArgs(r, args) {
201
235
  const agents = !agentsRaw || agentsRaw === 'none' ? []
202
236
  : agentsRaw === 'all' ? ['claude', 'opencode', 'codex']
203
237
  : agentsRaw.split(',').map((s) => s.trim()).filter(Boolean);
204
- const domain = flag(args, '--domain') ?? null;
205
238
  const adminUser = flag(args, '--admin-user');
206
239
  const adminPass = flag(args, '--admin-pass');
207
240
  const admin = adminUser && adminPass
@@ -211,13 +244,33 @@ async function planFromArgs(r, args) {
211
244
  installTmux: !args.includes('--no-tmux'),
212
245
  user: { mode: exists ? 'existing' : 'create', username },
213
246
  agents,
214
- domain,
215
- proxyPreference: flag(args, '--proxy') === 'apache' ? 'apache' : 'nginx',
216
- tls: domain !== null && !args.includes('--no-tls'),
217
- email: flag(args, '--email') ?? null,
247
+ deploy: deploymentFromArgs(args),
218
248
  admin,
219
249
  };
220
250
  }
251
+ /** Resolve the deployment from flags. `--host <ip>` (or `--ip`) ⇒ direct port mode; a real `--domain`
252
+ * ⇒ domain+HTTPS; a `--domain` that is actually an IP is treated as direct port mode (Let's Encrypt
253
+ * can't certify an IP); nothing ⇒ localhost. */
254
+ function deploymentFromArgs(args) {
255
+ const host = flag(args, '--host');
256
+ const domain = flag(args, '--domain');
257
+ if (args.includes('--localhost'))
258
+ return localhostDeploy();
259
+ if (host)
260
+ return ipDeploy(host);
261
+ if (domain && isIpAddress(domain))
262
+ return ipDeploy(domain);
263
+ if (domain) {
264
+ return {
265
+ mode: 'domain', host: domain, domain,
266
+ proxyPreference: flag(args, '--proxy') === 'apache' ? 'apache' : 'nginx',
267
+ tls: !args.includes('--no-tls'),
268
+ email: flag(args, '--email') ?? null,
269
+ webHost: '127.0.0.1',
270
+ };
271
+ }
272
+ return localhostDeploy();
273
+ }
221
274
  // ── interactive front-end ────────────────────────────────────────────────────
222
275
  async function chooseServiceUser() {
223
276
  const mode = await p.select({
@@ -253,14 +306,42 @@ async function chooseAgents(r, user) {
253
306
  return [];
254
307
  return pick;
255
308
  }
256
- async function chooseProxy(r) {
257
- const domain = await p.text({
258
- message: 'Domain for the web UI (blank to skip the reverse proxy and serve on localhost only)',
259
- placeholder: 'orca.example.com',
309
+ /** Best-effort public IPv4 of this box, used as the default for the direct-port mode. Prefers the
310
+ * first global address from `hostname -I`; empty string when none can be determined. */
311
+ async function detectPublicIp(r) {
312
+ const res = await r.exec('hostname', ['-I']);
313
+ const first = res.stdout.trim().split(/\s+/).find((ip) => /^\d{1,3}(\.\d{1,3}){3}$/.test(ip) && !ip.startsWith('127.'));
314
+ return first ?? '';
315
+ }
316
+ async function chooseDeployment(r) {
317
+ const mode = await p.select({
318
+ message: 'How will you reach the ORCA web UI?',
319
+ options: [
320
+ { value: 'domain', label: 'A domain name', hint: 'nginx + free HTTPS (Let’s Encrypt)' },
321
+ { value: 'ip', label: 'This server’s IP, on a port', hint: `http://<ip>:${WEB_PORT} — no reverse proxy` },
322
+ { value: 'localhost', label: 'Localhost only', hint: `http://localhost:${WEB_PORT}` },
323
+ ],
260
324
  });
325
+ bail(mode);
326
+ if (mode === 'localhost')
327
+ return localhostDeploy();
328
+ if (mode === 'ip') {
329
+ const guess = await detectPublicIp(r);
330
+ const host = await p.text({ message: 'Public IP / hostname to advertise', initialValue: guess, validate: (v) => ((v ?? '').trim() ? undefined : 'Required') });
331
+ bail(host);
332
+ p.log.info(`The web UI will listen on 0.0.0.0:${WEB_PORT} — make sure port ${WEB_PORT} is open in any firewall.`);
333
+ return ipDeploy(host.trim());
334
+ }
335
+ // domain
336
+ const domain = await p.text({ message: 'Domain name', placeholder: 'orca.example.com', validate: (v) => {
337
+ const t = (v ?? '').trim();
338
+ if (!t)
339
+ return 'Required';
340
+ if (isIpAddress(t))
341
+ return 'That’s an IP — pick the IP option instead (Let’s Encrypt needs a domain name)';
342
+ return undefined;
343
+ } });
261
344
  bail(domain);
262
- if (!domain.trim())
263
- return { domain: null, proxyPreference: 'nginx', tls: false, email: null };
264
345
  let proxyPreference = 'nginx';
265
346
  if (!(await detectProxy(r))) {
266
347
  const which = await p.select({
@@ -272,18 +353,21 @@ async function chooseProxy(r) {
272
353
  }
273
354
  const wantTls = await p.confirm({ message: `Obtain a free HTTPS certificate for ${domain.trim()} via Let's Encrypt?` });
274
355
  if (p.isCancel(wantTls) || !wantTls)
275
- return { domain: domain.trim(), proxyPreference, tls: false, email: null };
356
+ return { mode: 'domain', host: domain.trim(), domain: domain.trim(), proxyPreference, tls: false, email: null, webHost: '127.0.0.1' };
276
357
  const email = await p.text({ message: 'Email for renewal notices (blank to register without email)', placeholder: 'you@example.com' });
277
358
  bail(email);
278
- return { domain: domain.trim(), proxyPreference, tls: true, email: email.trim() || null };
359
+ return { mode: 'domain', host: domain.trim(), domain: domain.trim(), proxyPreference, tls: true, email: email.trim() || null, webHost: '127.0.0.1' };
279
360
  }
280
361
  // ── entry point ──────────────────────────────────────────────────────────────
281
362
  /** Human recap of what the wizard is about to do — shown for confirmation before anything is touched. */
282
363
  function planSummary(plan) {
283
364
  const pad = (s) => s.padEnd(9);
284
- const web = plan.domain
285
- ? `${plan.proxyPreference} ${plan.domain}${plan.tls ? ' + HTTPS (Let’s Encrypt)' : ' (HTTP only)'}`
286
- : `localhost only — http://127.0.0.1:${WEB_PORT} (no reverse proxy)`;
365
+ const d = plan.deploy;
366
+ const web = d.mode === 'domain'
367
+ ? `${d.proxyPreference} ${d.domain}${d.tls ? ' + HTTPS (Let’s Encrypt)' : ' (HTTP only)'}`
368
+ : d.mode === 'ip'
369
+ ? `http://${d.host}:${WEB_PORT} — direct, no reverse proxy`
370
+ : `localhost only — http://localhost:${WEB_PORT}`;
287
371
  return [
288
372
  `${pad('User')}${plan.user.mode === 'create' ? `create system user "${plan.user.username}"` : `existing user "${plan.user.username}"`}`,
289
373
  `${pad('Agents')}${plan.agents.length ? plan.agents.join(', ') : 'none (install later)'}`,
@@ -321,9 +405,9 @@ export async function install(args = []) {
321
405
  }
322
406
  const user = await chooseServiceUser();
323
407
  const agents = await chooseAgents(r, user.username);
324
- const proxy = await chooseProxy(r);
408
+ const deploy = await chooseDeployment(r);
325
409
  // Admin is created via the shared wizard AFTER the daemon is up, so collect it there instead.
326
- plan = { installTmux, user, agents, ...proxy, admin: null };
410
+ plan = { installTmux, user, agents, deploy, admin: null };
327
411
  }
328
412
  // Recap everything before touching the system — last chance to back out.
329
413
  p.note(planSummary(plan), 'Install plan');
@@ -334,7 +418,7 @@ export async function install(args = []) {
334
418
  process.exit(0);
335
419
  }
336
420
  }
337
- await execute(r, plan);
421
+ const { tls } = await execute(r, plan);
338
422
  // Interactive: now that the daemon is live, run the shared first-run wizard for the admin + LLM.
339
423
  let adminUser = plan.admin?.username ?? null;
340
424
  if (!unattended) {
@@ -345,7 +429,7 @@ export async function install(args = []) {
345
429
  await step('Verifying login', () => loginSmokeTest(creds.username, creds.password));
346
430
  }
347
431
  }
348
- const url = plan.domain ? (plan.tls ? `https://${plan.domain}` : `http://${plan.domain}`) : `http://127.0.0.1:${WEB_PORT}`;
432
+ const url = publicUrl(plan.deploy, tls);
349
433
  const summary = [
350
434
  `Open ${url}`,
351
435
  adminUser ? `Sign in ${adminUser}` : 'Sign in create an admin in the web UI',
@@ -33,7 +33,7 @@ Wants=orca-daemon.service
33
33
  Type=simple
34
34
  User=${p.user}
35
35
  Environment=PORT=${p.webPort}
36
- Environment=HOSTNAME=127.0.0.1
36
+ Environment=HOSTNAME=${p.webHost}
37
37
  Environment=ORCA_DAEMON_URL=http://127.0.0.1:${p.daemonPort}
38
38
  Environment=ORCA_LOG_DIR=${p.home}/.config/orca/logs
39
39
  Environment=PATH=${p.npmGlobalBin}:${BASE_PATH}
@@ -0,0 +1,15 @@
1
+ import { readFileSync } from 'node:fs';
2
+ /** System-wide so any user invoking `orca` (typically root) can read it, regardless of which user the
3
+ * services run as. */
4
+ export const INSTALL_INFO_PATH = '/etc/orca/install.json';
5
+ export function readInstallInfo(path = INSTALL_INFO_PATH) {
6
+ try {
7
+ return JSON.parse(readFileSync(path, 'utf8'));
8
+ }
9
+ catch {
10
+ return null;
11
+ }
12
+ }
13
+ export function serializeInstallInfo(info) {
14
+ return JSON.stringify(info, null, 2);
15
+ }
package/dist/cli/menu.js CHANGED
@@ -1,10 +1,12 @@
1
- import { spawn } from 'node:child_process';
1
+ import { spawn, execFile } from 'node:child_process';
2
2
  import * as p from '@clack/prompts';
3
3
  import { status } from './launcher.js';
4
4
  import { defaultLifecycleDeps, formatStatus, runLifecycle } from './commands.js';
5
5
  import { isFirstRun } from './setup.js';
6
6
  import { runSetupWizard } from './setupWizard.js';
7
+ import { readInstallInfo } from './installInfo.js';
7
8
  const BASE = process.env.ORCA_URL ?? 'http://localhost:4400';
9
+ const SERVICES = ['orca-daemon', 'orca-web'];
8
10
  /** Open a URL in the user's default browser, cross-platform, fire-and-forget. */
9
11
  function openUrl(url) {
10
12
  const cmd = process.platform === 'darwin' ? 'open' : process.platform === 'win32' ? 'cmd' : 'xdg-open';
@@ -14,8 +16,90 @@ function openUrl(url) {
14
16
  }
15
17
  catch { /* headless box — ignore */ }
16
18
  }
19
+ /** Run a command, resolving its stdout/exit code (never rejects). */
20
+ function run(cmd, args) {
21
+ return new Promise((resolve) => {
22
+ execFile(cmd, args, (err, stdout) => {
23
+ const code = err && typeof err.code === 'number' ? err.code : err ? 1 : 0;
24
+ resolve({ code, stdout: stdout?.toString() ?? '' });
25
+ });
26
+ });
27
+ }
28
+ /** systemctl, transparently via sudo when we aren't root (so a non-root operator still works). */
29
+ async function systemctl(...args) {
30
+ const asRoot = typeof process.getuid === 'function' && process.getuid() === 0;
31
+ return asRoot ? run('systemctl', args) : run('sudo', ['systemctl', ...args]);
32
+ }
33
+ /** Whether both ORCA units report active. */
34
+ async function servicesActive() {
35
+ const r = await systemctl('is-active', ...SERVICES);
36
+ const states = r.stdout.trim().split('\n');
37
+ return states.length > 0 && states.every((s) => s.trim() === 'active');
38
+ }
39
+ /** Launcher menu for a systemd-provisioned box (`orca install`): drives the units via systemctl and
40
+ * shows the real public URL the operator chose — never spawns a second, port-conflicting daemon. */
41
+ async function systemdMenu(info, version) {
42
+ p.intro(`🐋 orcasynth v${version} · systemd`);
43
+ for (;;) {
44
+ const active = await servicesActive();
45
+ const state = active ? `● orca is running · ${info.publicUrl}` : '○ orca is stopped';
46
+ const action = await p.select({
47
+ message: state,
48
+ options: [
49
+ active ? { value: 'restart', label: 'Restart', hint: 'daemon + web' } : { value: 'start', label: 'Start', hint: 'daemon + web' },
50
+ ...(active ? [{ value: 'stop', label: 'Stop' }] : []),
51
+ { value: 'status', label: 'Status', hint: 'systemctl status' },
52
+ { value: 'open', label: 'Open web UI', hint: info.publicUrl },
53
+ { value: 'logs', label: 'Recent daemon logs' },
54
+ { value: 'update', label: 'Update', hint: 'npm + restart services' },
55
+ { value: 'exit', label: 'Exit' },
56
+ ],
57
+ });
58
+ if (p.isCancel(action) || action === 'exit')
59
+ break;
60
+ if (action === 'open') {
61
+ openUrl(info.publicUrl);
62
+ p.log.success(`Opening ${info.publicUrl}`);
63
+ continue;
64
+ }
65
+ if (action === 'status') {
66
+ const r = await systemctl('status', '--no-pager', '-n', '0', ...SERVICES);
67
+ p.note(r.stdout.trim() || '(no output)', 'Status');
68
+ continue;
69
+ }
70
+ if (action === 'logs') {
71
+ const r = await run('journalctl', ['-u', 'orca-daemon', '-n', '20', '--no-pager']);
72
+ p.note(r.stdout.trim() || '(no logs — try: journalctl -u orca-daemon)', 'orca-daemon');
73
+ continue;
74
+ }
75
+ if (action === 'update') {
76
+ const s = p.spinner();
77
+ s.start('Updating orcasynth…');
78
+ const upd = await run('npm', ['install', '-g', 'orcasynth@latest']);
79
+ if (upd.code !== 0) {
80
+ s.stop('Update failed — see npm output above.');
81
+ continue;
82
+ }
83
+ await systemctl('restart', ...SERVICES);
84
+ s.stop('Updated and restarted.');
85
+ continue;
86
+ }
87
+ // start | stop | restart
88
+ const s = p.spinner();
89
+ s.start(`${action}…`);
90
+ const r = await systemctl(action, ...SERVICES);
91
+ s.stop(r.code === 0 ? `${action} ✓` : `${action} failed (code ${r.code})`);
92
+ }
93
+ p.outro('See you 🐋');
94
+ }
17
95
  /** The interactive launcher menu shown when `orca` is run with no arguments in a terminal. */
18
96
  export async function menu(env, version) {
97
+ // A box provisioned by `orca install` is systemd-managed — drive those units, don't spawn our own.
98
+ const info = readInstallInfo();
99
+ if (info) {
100
+ await systemdMenu(info, version);
101
+ return;
102
+ }
19
103
  const deps = defaultLifecycleDeps(version);
20
104
  p.intro(`🐋 orcasynth v${version}`);
21
105
  for (;;) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "orcasynth",
3
- "version": "1.2.1",
3
+ "version": "1.3.0",
4
4
  "description": "ORCA — an autonomous coding-agent orchestrator with an autopilot overseer, daemon API and web UI. Install globally and run `orca`.",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -1 +1 @@
1
- bvh5kJTXH2EYcTgp6Gxcw
1
+ hDw78YoaHr7BxL_Us9pPD
@@ -7,9 +7,9 @@
7
7
  "static/chunks/0cz1d0mv5g_q7.js"
8
8
  ],
9
9
  "lowPriorityFiles": [
10
- "static/bvh5kJTXH2EYcTgp6Gxcw/_buildManifest.js",
11
- "static/bvh5kJTXH2EYcTgp6Gxcw/_ssgManifest.js",
12
- "static/bvh5kJTXH2EYcTgp6Gxcw/_clientMiddlewareManifest.js"
10
+ "static/hDw78YoaHr7BxL_Us9pPD/_buildManifest.js",
11
+ "static/hDw78YoaHr7BxL_Us9pPD/_ssgManifest.js",
12
+ "static/hDw78YoaHr7BxL_Us9pPD/_clientMiddlewareManifest.js"
13
13
  ],
14
14
  "rootMainFiles": [
15
15
  "static/chunks/310vm2bl3xxpt.js",
@@ -1 +1 @@
1
- <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/310vm2bl3xxpt.js"/><script src="/_next/static/chunks/17tpdgx22zl4v.js" async=""></script><script src="/_next/static/chunks/2nykiepra7i1k.js" async=""></script><script src="/_next/static/chunks/0n-zjr76qg7uq.js" async=""></script><script src="/_next/static/chunks/0paxexg6-m0de.js" async=""></script><script src="/_next/static/chunks/turbopack-2put530kkhy0n.js" async=""></script><script src="/_next/static/chunks/05-c3ty_6dwfk.js" async=""></script><script src="/_next/static/chunks/0c179dg4znere.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/0cz1d0mv5g_q7.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/310vm2bl3xxpt.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"bvh5kJTXH2EYcTgp6Gxcw\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
1
+ <!DOCTYPE html><html id="__next_error__"><head><meta charSet="utf-8"/><meta name="viewport" content="width=device-width, initial-scale=1"/><link rel="preload" as="script" fetchPriority="low" href="/_next/static/chunks/310vm2bl3xxpt.js"/><script src="/_next/static/chunks/17tpdgx22zl4v.js" async=""></script><script src="/_next/static/chunks/2nykiepra7i1k.js" async=""></script><script src="/_next/static/chunks/0n-zjr76qg7uq.js" async=""></script><script src="/_next/static/chunks/0paxexg6-m0de.js" async=""></script><script src="/_next/static/chunks/turbopack-2put530kkhy0n.js" async=""></script><script src="/_next/static/chunks/05-c3ty_6dwfk.js" async=""></script><script src="/_next/static/chunks/0c179dg4znere.js" async=""></script><title>500: This page couldn’t load</title><style>:root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }</style><script src="/_next/static/chunks/0cz1d0mv5g_q7.js" noModule=""></script></head><body><div hidden=""><!--$--><!--/$--></div><div style="font-family:system-ui,&quot;Segoe UI&quot;,Roboto,Helvetica,Arial,sans-serif,&quot;Apple Color Emoji&quot;,&quot;Segoe UI Emoji&quot;;height:100vh;display:flex;align-items:center;justify-content:center"><div style="margin-top:-32px;max-width:325px;padding:32px 28px;text-align:left"><svg width="32" height="32" viewBox="-0.2 -1.5 32 32" fill="none" style="margin-bottom:24px"><path d="M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z" fill="var(--next-error-title)"></path></svg><h1 style="font-size:24px;font-weight:500;letter-spacing:-0.02em;line-height:32px;margin:0 0 12px 0;color:var(--next-error-title)">This page couldn’t load</h1><p style="font-size:14px;font-weight:400;line-height:21px;margin:0 0 20px 0;color:var(--next-error-message)">A server error occurred. Reload to try again.</p><form style="margin:0"><button type="submit" style="display:inline-flex;align-items:center;justify-content:center;height:32px;padding:0 12px;font-size:14px;font-weight:500;line-height:20px;border-radius:6px;cursor:pointer;color:var(--next-error-btn-text);background:var(--next-error-btn-bg);border:var(--next-error-btn-border)">Reload</button></form></div></div><!--$--><!--/$--><script src="/_next/static/chunks/310vm2bl3xxpt.js" id="_R_" async=""></script><script>(self.__next_f=self.__next_f||[]).push([0])</script><script>self.__next_f.push([1,"1:\"$Sreact.fragment\"\n2:I[39756,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\"]\n3:I[37457,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\"]\n4:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"OutletBoundary\"]\n5:\"$Sreact.suspense\"\n8:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"ViewportBoundary\"]\na:I[97367,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"MetadataBoundary\"]\nc:I[68027,[\"/_next/static/chunks/05-c3ty_6dwfk.js\",\"/_next/static/chunks/0c179dg4znere.js\"],\"default\",1]\n"])</script><script>self.__next_f.push([1,"0:{\"P\":null,\"c\":[\"\",\"_global-error\"],\"q\":\"\",\"i\":false,\"f\":[[[\"\",{\"children\":[\"__PAGE__\",{}]}],[[\"$\",\"$1\",\"c\",{\"children\":[null,[\"$\",\"$L2\",null,{\"parallelRouterKey\":\"children\",\"error\":\"$undefined\",\"errorStyles\":\"$undefined\",\"errorScripts\":\"$undefined\",\"template\":[\"$\",\"$L3\",null,{}],\"templateStyles\":\"$undefined\",\"templateScripts\":\"$undefined\",\"notFound\":\"$undefined\",\"forbidden\":\"$undefined\",\"unauthorized\":\"$undefined\"}]]}],{\"children\":[[\"$\",\"$1\",\"c\",{\"children\":[[\"$\",\"html\",null,{\"id\":\"__next_error__\",\"children\":[[\"$\",\"head\",null,{\"children\":[[\"$\",\"title\",null,{\"children\":\"500: This page couldn’t load\"}],[\"$\",\"style\",null,{\"dangerouslySetInnerHTML\":{\"__html\":\":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }\"}}]]}],[\"$\",\"body\",null,{\"children\":[\"$\",\"div\",null,{\"style\":{\"fontFamily\":\"system-ui,\\\"Segoe UI\\\",Roboto,Helvetica,Arial,sans-serif,\\\"Apple Color Emoji\\\",\\\"Segoe UI Emoji\\\"\",\"height\":\"100vh\",\"display\":\"flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\"},\"children\":[\"$\",\"div\",null,{\"style\":{\"marginTop\":\"-32px\",\"maxWidth\":\"325px\",\"padding\":\"32px 28px\",\"textAlign\":\"left\"},\"children\":[[\"$\",\"svg\",null,{\"width\":\"32\",\"height\":\"32\",\"viewBox\":\"-0.2 -1.5 32 32\",\"fill\":\"none\",\"style\":{\"marginBottom\":\"24px\"},\"children\":[\"$\",\"path\",null,{\"d\":\"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z\",\"fill\":\"var(--next-error-title)\"}]}],[\"$\",\"h1\",null,{\"style\":{\"fontSize\":\"24px\",\"fontWeight\":500,\"letterSpacing\":\"-0.02em\",\"lineHeight\":\"32px\",\"margin\":\"0 0 12px 0\",\"color\":\"var(--next-error-title)\"},\"children\":\"This page couldn’t load\"}],[\"$\",\"p\",null,{\"style\":{\"fontSize\":\"14px\",\"fontWeight\":400,\"lineHeight\":\"21px\",\"margin\":\"0 0 20px 0\",\"color\":\"var(--next-error-message)\"},\"children\":\"A server error occurred. Reload to try again.\"}],[\"$\",\"form\",null,{\"style\":{\"margin\":0},\"children\":[\"$\",\"button\",null,{\"type\":\"submit\",\"style\":{\"display\":\"inline-flex\",\"alignItems\":\"center\",\"justifyContent\":\"center\",\"height\":\"32px\",\"padding\":\"0 12px\",\"fontSize\":\"14px\",\"fontWeight\":500,\"lineHeight\":\"20px\",\"borderRadius\":\"6px\",\"cursor\":\"pointer\",\"color\":\"var(--next-error-btn-text)\",\"background\":\"var(--next-error-btn-bg)\",\"border\":\"var(--next-error-btn-border)\"},\"children\":\"Reload\"}]}]]}]}]}]]}],null,[\"$\",\"$L4\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.MetadataOutlet\",\"children\":\"$@6\"}]}]]}],{},null,false,null]},null,false,\"$@7\"],[\"$\",\"$1\",\"h\",{\"children\":[null,[\"$\",\"$L8\",null,{\"children\":\"$L9\"}],[\"$\",\"div\",null,{\"hidden\":true,\"children\":[\"$\",\"$La\",null,{\"children\":[\"$\",\"$5\",null,{\"name\":\"Next.Metadata\",\"children\":\"$Lb\"}]}]}],null]}],false]],\"m\":\"$undefined\",\"G\":[\"$c\",[]],\"S\":true,\"h\":null,\"s\":\"$undefined\",\"l\":\"$undefined\",\"p\":\"$undefined\",\"d\":\"$undefined\",\"b\":\"hDw78YoaHr7BxL_Us9pPD\"}\n"])</script><script>self.__next_f.push([1,"d:[]\n7:\"$Wd\"\n"])</script><script>self.__next_f.push([1,"9:[[\"$\",\"meta\",\"0\",{\"charSet\":\"utf-8\"}],[\"$\",\"meta\",\"1\",{\"name\":\"viewport\",\"content\":\"width=device-width, initial-scale=1\"}]]\n"])</script><script>self.__next_f.push([1,"6:null\nb:[]\n"])</script></body></html>
@@ -6,7 +6,7 @@
6
6
  8:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"ViewportBoundary"]
7
7
  a:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"MetadataBoundary"]
8
8
  c:I[68027,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"default",1]
9
- 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"bvh5kJTXH2EYcTgp6Gxcw"}
9
+ 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"hDw78YoaHr7BxL_Us9pPD"}
10
10
  d:[]
11
11
  7:"$Wd"
12
12
  9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
@@ -1,5 +1,5 @@
1
1
  1:"$Sreact.fragment"
2
2
  2:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"OutletBoundary"]
3
3
  3:"$Sreact.suspense"
4
- 0:{"rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"bvh5kJTXH2EYcTgp6Gxcw"}
4
+ 0:{"rsc":["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L2",null,{"children":["$","$3",null,{"name":"Next.MetadataOutlet","children":"$@4"}]}]]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"hDw78YoaHr7BxL_Us9pPD"}
5
5
  4:null
@@ -6,7 +6,7 @@
6
6
  8:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"ViewportBoundary"]
7
7
  a:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"MetadataBoundary"]
8
8
  c:I[68027,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"default",1]
9
- 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"bvh5kJTXH2EYcTgp6Gxcw"}
9
+ 0:{"P":null,"c":["","_global-error"],"q":"","i":false,"f":[[["",{"children":["__PAGE__",{}]}],[["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","error":"$undefined","errorStyles":"$undefined","errorScripts":"$undefined","template":["$","$L3",null,{}],"templateStyles":"$undefined","templateScripts":"$undefined","notFound":"$undefined","forbidden":"$undefined","unauthorized":"$undefined"}]]}],{"children":[["$","$1","c",{"children":[["$","html",null,{"id":"__next_error__","children":[["$","head",null,{"children":[["$","title",null,{"children":"500: This page couldn’t load"}],["$","style",null,{"dangerouslySetInnerHTML":{"__html":":root {--next-error-bg: #fff;--next-error-text: #171717;--next-error-title: #171717;--next-error-message: #171717;--next-error-digest: #666666;--next-error-btn-text: #fff;--next-error-btn-bg: #171717;--next-error-btn-border: none;--next-error-btn-secondary-text: #171717;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(0,0,0,0.08);}@media (prefers-color-scheme: dark) {:root {--next-error-bg: #0a0a0a;--next-error-text: #ededed;--next-error-title: #ededed;--next-error-message: #ededed;--next-error-digest: #a0a0a0;--next-error-btn-text: #0a0a0a;--next-error-btn-bg: #ededed;--next-error-btn-border: none;--next-error-btn-secondary-text: #ededed;--next-error-btn-secondary-bg: transparent;--next-error-btn-secondary-border: 1px solid rgba(255,255,255,0.14);}}body { margin: 0; color: var(--next-error-text); background: var(--next-error-bg); }"}}]]}],["$","body",null,{"children":["$","div",null,{"style":{"fontFamily":"system-ui,\"Segoe UI\",Roboto,Helvetica,Arial,sans-serif,\"Apple Color Emoji\",\"Segoe UI Emoji\"","height":"100vh","display":"flex","alignItems":"center","justifyContent":"center"},"children":["$","div",null,{"style":{"marginTop":"-32px","maxWidth":"325px","padding":"32px 28px","textAlign":"left"},"children":[["$","svg",null,{"width":"32","height":"32","viewBox":"-0.2 -1.5 32 32","fill":"none","style":{"marginBottom":"24px"},"children":["$","path",null,{"d":"M16.9328 0C18.0839 0.000116771 19.1334 0.658832 19.634 1.69531L31.4299 26.1309C32.0708 27.4588 31.1036 28.9999 29.6291 29H2.00215C0.527541 29 -0.439628 27.4588 0.201371 26.1309L11.9973 1.69531C12.4979 0.658823 13.5474 7.75066e-05 14.6984 0H16.9328ZM3.59493 26H28.0363L16.9328 3H14.6984L3.59493 26ZM15.8156 19C16.9202 19.0001 17.8156 19.8955 17.8156 21C17.8156 22.1045 16.9202 22.9999 15.8156 23C14.7111 23 13.8156 22.1046 13.8156 21C13.8156 19.8954 14.7111 19 15.8156 19ZM17.3156 16.5H14.3156V8.5H17.3156V16.5Z","fill":"var(--next-error-title)"}]}],["$","h1",null,{"style":{"fontSize":"24px","fontWeight":500,"letterSpacing":"-0.02em","lineHeight":"32px","margin":"0 0 12px 0","color":"var(--next-error-title)"},"children":"This page couldn’t load"}],["$","p",null,{"style":{"fontSize":"14px","fontWeight":400,"lineHeight":"21px","margin":"0 0 20px 0","color":"var(--next-error-message)"},"children":"A server error occurred. Reload to try again."}],["$","form",null,{"style":{"margin":0},"children":["$","button",null,{"type":"submit","style":{"display":"inline-flex","alignItems":"center","justifyContent":"center","height":"32px","padding":"0 12px","fontSize":"14px","fontWeight":500,"lineHeight":"20px","borderRadius":"6px","cursor":"pointer","color":"var(--next-error-btn-text)","background":"var(--next-error-btn-bg)","border":"var(--next-error-btn-border)"},"children":"Reload"}]}]]}]}]}]]}],null,["$","$L4",null,{"children":["$","$5",null,{"name":"Next.MetadataOutlet","children":"$@6"}]}]]}],{},null,false,null]},null,false,"$@7"],["$","$1","h",{"children":[null,["$","$L8",null,{"children":"$L9"}],["$","div",null,{"hidden":true,"children":["$","$La",null,{"children":["$","$5",null,{"name":"Next.Metadata","children":"$Lb"}]}]}],null]}],false]],"m":"$undefined","G":["$c",[]],"S":true,"h":null,"s":"$undefined","l":"$undefined","p":"$undefined","d":"$undefined","b":"hDw78YoaHr7BxL_Us9pPD"}
10
10
  d:[]
11
11
  7:"$Wd"
12
12
  9:[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]
@@ -2,4 +2,4 @@
2
2
  2:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"ViewportBoundary"]
3
3
  3:I[97367,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"MetadataBoundary"]
4
4
  4:"$Sreact.suspense"
5
- 0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],null]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"bvh5kJTXH2EYcTgp6Gxcw"}
5
+ 0:{"rsc":["$","$1","h",{"children":[null,["$","$L2",null,{"children":[["$","meta","0",{"charSet":"utf-8"}],["$","meta","1",{"name":"viewport","content":"width=device-width, initial-scale=1"}]]}],["$","div",null,{"hidden":true,"children":["$","$L3",null,{"children":["$","$4",null,{"name":"Next.Metadata","children":[]}]}]}],null]}],"isPartial":false,"staleTime":300,"varyParams":null,"buildId":"hDw78YoaHr7BxL_Us9pPD"}
@@ -2,4 +2,4 @@
2
2
  2:I[39756,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"default"]
3
3
  3:I[37457,["/_next/static/chunks/05-c3ty_6dwfk.js","/_next/static/chunks/0c179dg4znere.js"],"default"]
4
4
  4:[]
5
- 0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"bvh5kJTXH2EYcTgp6Gxcw"}
5
+ 0:{"rsc":["$","$1","c",{"children":[null,["$","$L2",null,{"parallelRouterKey":"children","template":["$","$L3",null,{}]}]]}],"isPartial":false,"staleTime":300,"varyParams":"$W4","buildId":"hDw78YoaHr7BxL_Us9pPD"}
@@ -1 +1 @@
1
- 0:{"tree":{"name":"","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"bvh5kJTXH2EYcTgp6Gxcw"}
1
+ 0:{"tree":{"name":"","param":null,"prefetchHints":0,"slots":{"children":{"name":"__PAGE__","param":null,"prefetchHints":0,"slots":null}}},"staleTime":300,"buildId":"hDw78YoaHr7BxL_Us9pPD"}