local-operator-ui 0.34.45 → 0.34.47

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 (88) hide show
  1. package/out/main/index.js +3707 -97
  2. package/out/preload/index.js +73 -0
  3. package/out/renderer/assets/{_basePickBy-AOIZJtmP.js → _basePickBy-B2JiaFKi.js} +1 -1
  4. package/out/renderer/assets/{_baseUniq-6rYoQPQm.js → _baseUniq-CfpDxOYw.js} +1 -1
  5. package/out/renderer/assets/{agent-details-page-B9MNIwUW.js → agent-details-page-C0GdJMfq.js} +1 -1
  6. package/out/renderer/assets/{agent-hub-page-Bj3VsEfD.js → agent-hub-page-C6ze_xjQ.js} +1 -1
  7. package/out/renderer/assets/{agents-page-y_fPy8cB.js → agents-page-DSNLtN_J.js} +3 -3
  8. package/out/renderer/assets/{arc-DEIVtaqP.js → arc-K65ZzfoN.js} +1 -1
  9. package/out/renderer/assets/{architectureDiagram-IEHRJDOE-C6lgf3ft.js → architectureDiagram-IEHRJDOE-CLJdV8y-.js} +1 -1
  10. package/out/renderer/assets/{blockDiagram-JOT3LUYC-rUXOYgBS.js → blockDiagram-JOT3LUYC-DpImr7tl.js} +1 -1
  11. package/out/renderer/assets/{book-open-BWUyDXVa.js → book-open-BEOtYKZe.js} +1 -1
  12. package/out/renderer/assets/browser-page-Hj-3V4SP.js +1 -0
  13. package/out/renderer/assets/{browser-webauthn-prompt-BlawzvV4.js → browser-webauthn-prompt-4jHz_1RY.js} +1 -1
  14. package/out/renderer/assets/{c4Diagram-VJAJSXHY-B5DZCCX3.js → c4Diagram-VJAJSXHY-CD9xVR0f.js} +1 -1
  15. package/out/renderer/assets/channel-CjH9_X6K.js +1 -0
  16. package/out/renderer/assets/{chunk-4BMEZGHF-LYO-H6gm.js → chunk-4BMEZGHF-CTvc3b4C.js} +1 -1
  17. package/out/renderer/assets/{chunk-A2AXSNBT-C-eXpCGB.js → chunk-A2AXSNBT-ByqThlbf.js} +1 -1
  18. package/out/renderer/assets/{chunk-AEK57VVT-CkjgDW9B.js → chunk-AEK57VVT-DD6OqDr0.js} +1 -1
  19. package/out/renderer/assets/{chunk-D6G4REZN-hAERljt9.js → chunk-D6G4REZN-DyRn0cWl.js} +1 -1
  20. package/out/renderer/assets/{chunk-RZ5BOZE2-D1aP9fPZ.js → chunk-RZ5BOZE2-CnZV3WTJ.js} +1 -1
  21. package/out/renderer/assets/{chunk-XZIHB7SX-Chv37Bqx.js → chunk-XZIHB7SX-DolFB-S0.js} +1 -1
  22. package/out/renderer/assets/classDiagram-GIVACNV2-DNFX9Bxc.js +1 -0
  23. package/out/renderer/assets/classDiagram-v2-COTLJTTW-DNFX9Bxc.js +1 -0
  24. package/out/renderer/assets/clone-Dh-7KwYI.js +1 -0
  25. package/out/renderer/assets/{console-mirror-DF_IQ1r-.js → console-mirror-DpL-JwpC.js} +1 -1
  26. package/out/renderer/assets/{consoleCapture-CAbvxCQS.js → consoleCapture-DD1Sq_ph.js} +1 -1
  27. package/out/renderer/assets/{conversation-input-sync-BdhFw-JY.js → conversation-input-sync-BX8IVirL.js} +5 -5
  28. package/out/renderer/assets/{dagre-OKDRZEBW-ClDfyejg.js → dagre-OKDRZEBW-CDaLTqSD.js} +1 -1
  29. package/out/renderer/assets/{diagram-SSKATNLV-BECmfn9C.js → diagram-SSKATNLV-CT01eufZ.js} +1 -1
  30. package/out/renderer/assets/{diagram-VNBRO52H-82BMsx_Z.js → diagram-VNBRO52H-Dm95zJ6Z.js} +1 -1
  31. package/out/renderer/assets/{erDiagram-Q7BY3M3F-BiCriqsZ.js → erDiagram-Q7BY3M3F-CKncNCh2.js} +1 -1
  32. package/out/renderer/assets/{error-boundary-B4K6A3dS.js → error-boundary-BDLNfQKz.js} +1 -1
  33. package/out/renderer/assets/{flowDiagram-4HSFHLVR-D4PQMO6X.js → flowDiagram-4HSFHLVR-DxgK_2s-.js} +1 -1
  34. package/out/renderer/assets/{ganttDiagram-APWFNJXF-Rts_QpVD.js → ganttDiagram-APWFNJXF-C26kU1-9.js} +1 -1
  35. package/out/renderer/assets/{gitGraphDiagram-7IBYFJ6S-B1rxvfyh.js → gitGraphDiagram-7IBYFJ6S-B22ejsPk.js} +1 -1
  36. package/out/renderer/assets/{graph-DxQCKx-L.js → graph-CnXCW8BP.js} +1 -1
  37. package/out/renderer/assets/{index-XFXAg7sM.js → index-Be9pTy7F.js} +1 -1
  38. package/out/renderer/assets/index-CnQsclLj.js +809 -0
  39. package/out/renderer/assets/index-Dk4-Px6P.css +1 -0
  40. package/out/renderer/assets/{index-BhsV-ipc.js → index-UE_QEAqr.js} +1 -1
  41. package/out/renderer/assets/{infoDiagram-PH2N3AL5-CDvWuX2O.js → infoDiagram-PH2N3AL5-DJZU3P7J.js} +1 -1
  42. package/out/renderer/assets/{installer-B4Bd2pBF.js → installer-CIu909RT.js} +1 -1
  43. package/out/renderer/assets/{journeyDiagram-U35MCT3I-CnefKX-i.js → journeyDiagram-U35MCT3I-C-Aue1NR.js} +1 -1
  44. package/out/renderer/assets/{kanban-definition-NDS4AKOZ-Kd7aNO4_.js → kanban-definition-NDS4AKOZ-DhgXwdEM.js} +1 -1
  45. package/out/renderer/assets/{layout-CMQ0zdhs.js → layout-Dw8q0WZh.js} +1 -1
  46. package/out/renderer/assets/{legacy-agents-page-PBvD5xd9.js → legacy-agents-page-u84wTmRV.js} +1 -1
  47. package/out/renderer/assets/{mermaid.core-x5Fva3t5.js → mermaid.core-CLdsX7Rp.js} +5 -5
  48. package/out/renderer/assets/{mesh-page-IOGN512j.js → mesh-page-Dys9-2sY.js} +1 -1
  49. package/out/renderer/assets/messages-Yrm2FT2V.js +3 -0
  50. package/out/renderer/assets/{mindmap-definition-ALO5MXBD-DJwQ3wYh.js → mindmap-definition-ALO5MXBD-BjBiqabY.js} +1 -1
  51. package/out/renderer/assets/{mini-DHQCkYmb.js → mini-BXXRy4rW.js} +1 -1
  52. package/out/renderer/assets/{notebook-pen-CKFoYavJ.js → notebook-pen-B5Stfimb.js} +1 -1
  53. package/out/renderer/assets/{org-access-_jPzS_wW.js → org-access-CyjYN726.js} +1 -1
  54. package/out/renderer/assets/{org-surface-gate-D29XdDTt.js → org-surface-gate-i_SGPHN5.js} +1 -1
  55. package/out/renderer/assets/{page-header-D90TvAM5.js → page-header-BR-fmx4f.js} +1 -1
  56. package/out/renderer/assets/{pieDiagram-IB7DONF6-CW-ezwOn.js → pieDiagram-IB7DONF6-DjDH1mVr.js} +1 -1
  57. package/out/renderer/assets/{projects-page-DGLblpIY.js → projects-page-CGRUr8ls.js} +1 -1
  58. package/out/renderer/assets/{publication-validation-ZquLmMLD.js → publication-validation-B4k6VAFZ.js} +1 -1
  59. package/out/renderer/assets/{quadrantDiagram-7GDLP6J5-cgwnEsXh.js → quadrantDiagram-7GDLP6J5-Ba5XUz4h.js} +1 -1
  60. package/out/renderer/assets/{radar-MK3ICKWK-DvOkOeQ6.js → radar-MK3ICKWK-eQRm6qEE.js} +1 -1
  61. package/out/renderer/assets/{radient-auth-buttons-y3JK-yD8.js → radient-auth-buttons-BW_zi2lF.js} +1 -1
  62. package/out/renderer/assets/{requirementDiagram-KVF5MWMF-DOMWjtoO.js → requirementDiagram-KVF5MWMF-BSpyCNos.js} +1 -1
  63. package/out/renderer/assets/{sankeyDiagram-QLVOVGJD-CE3E7VO5.js → sankeyDiagram-QLVOVGJD-C-fzkOnd.js} +1 -1
  64. package/out/renderer/assets/{schedules-page-ETT8R0wn.js → schedules-page-CiSL5P8q.js} +1 -1
  65. package/out/renderer/assets/{sequenceDiagram-X6HHIX6F-C4EGcl7U.js → sequenceDiagram-X6HHIX6F-DdHVib_S.js} +1 -1
  66. package/out/renderer/assets/{settings-page-BZDF6UIV.js → settings-page-C11l7qyA.js} +60 -60
  67. package/out/renderer/assets/{stateDiagram-DGXRK772-wBbKaUQh.js → stateDiagram-DGXRK772-DEwuWkNd.js} +1 -1
  68. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-DRPVtafh.js +1 -0
  69. package/out/renderer/assets/{timeline-definition-BDJGKUSR-CgTCOxCY.js → timeline-definition-BDJGKUSR-5dsF-6I0.js} +1 -1
  70. package/out/renderer/assets/{use-download-agent-mutation-DkI3E5yA.js → use-download-agent-mutation-DGGt-uXR.js} +1 -1
  71. package/out/renderer/assets/{use-memberships-query-Hv-eprVl.js → use-memberships-query-BMGVy3RO.js} +1 -1
  72. package/out/renderer/assets/{use-session-snapshot-CfEF5TPK.js → use-session-snapshot-D3QghcPD.js} +1 -1
  73. package/out/renderer/assets/{xychartDiagram-VJFVF3MP-G2SxM5sQ.js → xychartDiagram-VJFVF3MP-DmEwPPnE.js} +1 -1
  74. package/out/renderer/console-capture.html +5 -5
  75. package/out/renderer/index.html +7 -7
  76. package/out/renderer/installer.html +4 -4
  77. package/out/renderer/mini.html +7 -7
  78. package/package.json +2 -2
  79. package/out/renderer/assets/browser-page-BENwHsVf.js +0 -1
  80. package/out/renderer/assets/channel-vM9rusk9.js +0 -1
  81. package/out/renderer/assets/classDiagram-GIVACNV2-BCqIuRq4.js +0 -1
  82. package/out/renderer/assets/classDiagram-v2-COTLJTTW-BCqIuRq4.js +0 -1
  83. package/out/renderer/assets/clone-Bj8HwBLn.js +0 -1
  84. package/out/renderer/assets/index-BJ-AJLyd.js +0 -804
  85. package/out/renderer/assets/index-C7mMgpwT.css +0 -1
  86. package/out/renderer/assets/messages-D3mGACg6.js +0 -3
  87. package/out/renderer/assets/stateDiagram-v2-YXO3MK2T-Bh0k2Dz3.js +0 -1
  88. /package/out/renderer/assets/{index-B-uibf5k.js → index-DF_hRerL.js} +0 -0
package/out/main/index.js CHANGED
@@ -50,8 +50,8 @@ const DAEMON_UNPAIRED = {
50
50
  };
51
51
  const BACKEND_STATUS_EVENT = "backend-status-changed";
52
52
  const BACKEND_RECONNECT_CHANNEL = "backend-reconnect";
53
- function isServerReachable(state) {
54
- return state !== "detached" && state !== "wedged";
53
+ function isServerReachable(state2) {
54
+ return state2 !== "detached" && state2 !== "wedged";
55
55
  }
56
56
  function relayNeedsRebuild(current, next) {
57
57
  return current.url !== next.url || current.token !== next.token;
@@ -1993,6 +1993,39 @@ const desktopRequestUnion = zod.z.discriminatedUnion("op", [
1993
1993
  accountId: zod.z.number().int().positive(),
1994
1994
  confirmed: zod.z.literal(true)
1995
1995
  }).strict(),
1996
+ /*
1997
+ * PHONE ACCESS SETUP (`features.tunnel_setup`, local-operator
1998
+ * `docs/DESKTOP_API.md` "Explicit phone setup"). Three ops over ONE route,
1999
+ * split by authority so a caller cannot mutate by accident:
2000
+ *
2001
+ * - `tunnel.setup.read`: GET, local metadata only. No upstream read, no token
2002
+ * refresh, never `verified` and never a quote - the cheap poll that rebuilds
2003
+ * the block after a window close or a lost response.
2004
+ * - `tunnel.setup.plan`: POST `{action:"plan"}`, a FRESH account/quote/
2005
+ * preparation observation that changes nothing.
2006
+ * - `tunnel.setup.run`: POST `{action:"run"}`, the only op that can write. The
2007
+ * backend REFUSES it without an explicit owner (422), so `credentialId` is
2008
+ * required here rather than defaulted: an account is never picked for the
2009
+ * user. `acceptMonthlyPrice` is a STRING, the exact fresh amount the user
2010
+ * saw, because the backend compares it to a fresh quote and a number would
2011
+ * round-trip through float formatting.
2012
+ *
2013
+ * ONLY the capability gates these. An older backend 404s the route, so the
2014
+ * renderer asks `features.tunnel_setup` first and sends nothing without it.
2015
+ */
2016
+ zod.z.object({
2017
+ op: zod.z.literal("tunnel.setup.read"),
2018
+ credentialId: zod.z.number().int().positive().optional()
2019
+ }).strict(),
2020
+ zod.z.object({
2021
+ op: zod.z.literal("tunnel.setup.plan"),
2022
+ credentialId: zod.z.number().int().positive().optional()
2023
+ }).strict(),
2024
+ zod.z.object({
2025
+ op: zod.z.literal("tunnel.setup.run"),
2026
+ credentialId: zod.z.number().int().positive(),
2027
+ acceptMonthlyPrice: zod.z.string().min(1).max(64).optional()
2028
+ }).strict(),
1996
2029
  zod.z.object({ op: zod.z.literal("auth.start"), provider: id$1 }).strict(),
1997
2030
  zod.z.object({ op: zod.z.literal("auth.status"), id: id$1 }).strict(),
1998
2031
  zod.z.object({ op: zod.z.literal("auth.input"), id: id$1, promptId: id$1, value: secret }).strict(),
@@ -2573,6 +2606,44 @@ function desktopRefusalCodeForStatus(path2, status2) {
2573
2606
  if (status2 === 503) return DESKTOP_REFUSAL_CODE.planeClosed;
2574
2607
  return void 0;
2575
2608
  }
2609
+ zod.z.object({
2610
+ step: zod.z.string(),
2611
+ blocked_on: zod.z.string(),
2612
+ configured: zod.z.boolean(),
2613
+ ready: zod.z.boolean(),
2614
+ verified: zod.z.boolean(),
2615
+ url: zod.z.string().nullable(),
2616
+ credential_id: zod.z.number().int().positive().nullable(),
2617
+ identity_label: zod.z.string().nullable(),
2618
+ credential_choices: zod.z.array(
2619
+ zod.z.object({
2620
+ id: zod.z.number().int().positive(),
2621
+ identity_label: zod.z.string().nullable().optional()
2622
+ }).passthrough()
2623
+ ).default([]),
2624
+ quote: zod.z.object({
2625
+ monthly_price_usd: zod.z.string().nullable(),
2626
+ positive_balance: zod.z.boolean(),
2627
+ eligible: zod.z.boolean(),
2628
+ account_valid: zod.z.boolean()
2629
+ }).passthrough().nullable(),
2630
+ receipts: zod.z.array(zod.z.object({ step: zod.z.string(), ok: zod.z.boolean(), text: zod.z.string() })).default([]),
2631
+ remedy: zod.z.object({
2632
+ kind: zod.z.string(),
2633
+ text: zod.z.string(),
2634
+ command: zod.z.string().nullable().optional(),
2635
+ url: zod.z.string().nullable().optional()
2636
+ }).nullable(),
2637
+ source: zod.z.string(),
2638
+ in_progress: zod.z.boolean().default(false),
2639
+ progress: zod.z.array(zod.z.string()).default([]),
2640
+ active_credential_id: zod.z.number().int().positive().nullable().default(null),
2641
+ // Backend facts, separate from receipts: an emitted receipt does not prove
2642
+ // an ambiguous activation succeeded or was rolled back.
2643
+ billing_outcome: zod.z.string().optional(),
2644
+ reservation_outcome: zod.z.string().optional(),
2645
+ failure_stage: zod.z.string().optional()
2646
+ }).passthrough();
2576
2647
  const DESKTOP_MESSAGE_BYTE_BUDGET = 88e4;
2577
2648
  const DESKTOP_CONTROL_BYTE_BUDGET = 262144;
2578
2649
  const DESKTOP_SYSTEM_PROMPT_BYTE_BUDGET = 11e5;
@@ -2630,6 +2701,8 @@ function moveClientBoundMs(shape) {
2630
2701
  const PRESENCE_GESTURE_DEADLINE_MS = 18e4;
2631
2702
  const APPROVAL_APPROVE_DEADLINE_MS = PRESENCE_GESTURE_DEADLINE_MS + 15e3;
2632
2703
  const HUB_ITEM_MERGE_S = 120;
2704
+ const PHONE_SETUP_PLAN_DEADLINE_MS = 135e3;
2705
+ const PHONE_SETUP_RUN_DEADLINE_MS = 93e4;
2633
2706
  const HUB_ITEM_WRITE_DEADLINE_MS = (HUB_ITEM_MERGE_S + 30 + MOVE_CLIENT_MARGIN_S) * 1e3;
2634
2707
  const HUB_CHECK_DEADLINE_MS = 6e4;
2635
2708
  const HUB_APPLY_ALL_DEADLINE_MS = 5 * HUB_ITEM_WRITE_DEADLINE_MS;
@@ -2664,6 +2737,8 @@ function desktopRequestDeadlineMs(request) {
2664
2737
  }
2665
2738
  const op = typeof request === "string" ? request : request.op;
2666
2739
  if (op === "approvals.approve") return APPROVAL_APPROVE_DEADLINE_MS;
2740
+ if (op === "tunnel.setup.run") return PHONE_SETUP_RUN_DEADLINE_MS;
2741
+ if (op === "tunnel.setup.plan") return PHONE_SETUP_PLAN_DEADLINE_MS;
2667
2742
  const hub = hubWriteDeadlineMs(op);
2668
2743
  if (hub !== null) return hub;
2669
2744
  return LONG_READ_OPS.has(op) ? DESKTOP_LONG_READ_DEADLINE_MS : DESKTOP_CONTROL_DEADLINE_MS;
@@ -2728,6 +2803,10 @@ const READ_ONLY_OPS = /* @__PURE__ */ new Set([
2728
2803
  "subagents.transcript",
2729
2804
  "teams.get",
2730
2805
  "teams.list",
2806
+ // The two phone-setup observations change nothing on the server; `tunnel.setup.run`
2807
+ // is deliberately absent so a run that ran out of time gets the cautious sentence.
2808
+ "tunnel.setup.plan",
2809
+ "tunnel.setup.read",
2731
2810
  "usage.get"
2732
2811
  ]);
2733
2812
  const PANEL_READ_OPS = /* @__PURE__ */ new Set([
@@ -4023,6 +4102,30 @@ function desktopEndpoint(request) {
4023
4102
  path: `/v1/auth/accounts/${request.accountId}`,
4024
4103
  method: "DELETE"
4025
4104
  };
4105
+ case "tunnel.setup.read":
4106
+ return {
4107
+ path: request.credentialId === void 0 ? "/v1/desktop/tunnel/setup" : `/v1/desktop/tunnel/setup?credential_id=${request.credentialId}`,
4108
+ method: "GET"
4109
+ };
4110
+ case "tunnel.setup.plan":
4111
+ return {
4112
+ path: "/v1/desktop/tunnel/setup",
4113
+ method: "POST",
4114
+ body: {
4115
+ action: "plan",
4116
+ ...request.credentialId !== void 0 ? { credential_id: request.credentialId } : {}
4117
+ }
4118
+ };
4119
+ case "tunnel.setup.run":
4120
+ return {
4121
+ path: "/v1/desktop/tunnel/setup",
4122
+ method: "POST",
4123
+ body: {
4124
+ action: "run",
4125
+ credential_id: request.credentialId,
4126
+ ...request.acceptMonthlyPrice !== void 0 ? { accept_monthly_price: request.acceptMonthlyPrice } : {}
4127
+ }
4128
+ };
4026
4129
  case "auth.start":
4027
4130
  return {
4028
4131
  path: "/v1/auth/login",
@@ -4556,11 +4659,11 @@ function isZombie(pid) {
4556
4659
  const stat = fs.readFileSync(`/proc/${pid}/stat`, "utf8");
4557
4660
  return stat.slice(stat.lastIndexOf(")") + 1).trimStart().startsWith("Z");
4558
4661
  }
4559
- const state = node_child_process.execFileSync("/bin/ps", ["-o", "state=", "-p", String(pid)], {
4662
+ const state2 = node_child_process.execFileSync("/bin/ps", ["-o", "state=", "-p", String(pid)], {
4560
4663
  encoding: "utf8",
4561
4664
  timeout: 1e3
4562
4665
  });
4563
- return state.trim().toUpperCase().startsWith("Z");
4666
+ return state2.trim().toUpperCase().startsWith("Z");
4564
4667
  } catch {
4565
4668
  return false;
4566
4669
  }
@@ -4672,9 +4775,9 @@ async function probeIdentity(address, expectedInstanceId, options = {}) {
4672
4775
  }
4673
4776
  const VERSION_SEPARATOR = /[.+-]/;
4674
4777
  function compareVersions$1(a, b) {
4675
- const parse = (value) => value.split(VERSION_SEPARATOR).slice(0, 3).map((part) => Number.parseInt(part, 10) || 0);
4676
- const left = parse(a);
4677
- const right = parse(b);
4778
+ const parse2 = (value) => value.split(VERSION_SEPARATOR).slice(0, 3).map((part) => Number.parseInt(part, 10) || 0);
4779
+ const left = parse2(a);
4780
+ const right = parse2(b);
4678
4781
  for (let i = 0; i < 3; i++) {
4679
4782
  if (left[i] !== right[i]) return left[i] - right[i];
4680
4783
  }
@@ -5858,13 +5961,13 @@ function clearLastInstallAttempt(dir) {
5858
5961
  }
5859
5962
  const VERSION_TRIPLE_REGEX = /^v?(\d+)\.(\d+)\.(\d+)/;
5860
5963
  function compareVersions(a, b) {
5861
- const parse = (value) => {
5964
+ const parse2 = (value) => {
5862
5965
  const match = VERSION_TRIPLE_REGEX.exec(value.trim());
5863
5966
  if (!match) return null;
5864
5967
  return [Number(match[1]), Number(match[2]), Number(match[3])];
5865
5968
  };
5866
- const left = parse(a);
5867
- const right = parse(b);
5969
+ const left = parse2(a);
5970
+ const right = parse2(b);
5868
5971
  if (!left || !right) return null;
5869
5972
  for (let index = 0; index < 3; index++) {
5870
5973
  if (left[index] !== right[index])
@@ -9436,8 +9539,8 @@ function inspectManagedSelection(options) {
9436
9539
  return { kind: "ready", selection };
9437
9540
  }
9438
9541
  function readManagedSelection(options) {
9439
- const state = inspectManagedSelection(options);
9440
- return state.kind === "ready" ? state.selection : null;
9542
+ const state2 = inspectManagedSelection(options);
9543
+ return state2.kind === "ready" ? state2.selection : null;
9441
9544
  }
9442
9545
  async function managedSelectionReady(options) {
9443
9546
  return inspectManagedSelection(options).kind === "ready";
@@ -9648,10 +9751,10 @@ async function smokeEnvironment(venv, env) {
9648
9751
  }
9649
9752
  async function prepareManagedPython(options, install) {
9650
9753
  return locked(managedPythonRoot(options), async (held) => {
9651
- const state = inspectManagedSelection(options);
9652
- if (state.kind === "ready") return state.selection;
9653
- const superseded = state.kind === "missing" ? state.detail : null;
9654
- const published = state.kind === "missing" ? state.published : null;
9754
+ const state2 = inspectManagedSelection(options);
9755
+ if (state2.kind === "ready") return state2.selection;
9756
+ const superseded = state2.kind === "missing" ? state2.detail : null;
9757
+ const published = state2.kind === "missing" ? state2.published : null;
9655
9758
  return publishGeneration(
9656
9759
  options,
9657
9760
  install,
@@ -9725,16 +9828,16 @@ function managedSelectionSatisfies(options, target2, isNewer) {
9725
9828
  }
9726
9829
  async function updateManagedPython(options, install, decision) {
9727
9830
  return locked(managedPythonRoot(options), async (held) => {
9728
- const state = inspectManagedSelection(options);
9729
- const published = state.kind === "ready" ? state.selection : null;
9831
+ const state2 = inspectManagedSelection(options);
9832
+ const published = state2.kind === "ready" ? state2.selection : null;
9730
9833
  if (published && managedSelectionSatisfies(options, decision.target, decision.isNewer))
9731
9834
  return { selection: published, replaced: false, previous: null };
9732
- const previous = published ?? (state.kind === "missing" ? state.published : null);
9835
+ const previous = published ?? (state2.kind === "missing" ? state2.published : null);
9733
9836
  const selection = await publishGeneration(
9734
9837
  options,
9735
9838
  install,
9736
9839
  previous,
9737
- state.kind === "missing" ? state.detail : null,
9840
+ state2.kind === "missing" ? state2.detail : null,
9738
9841
  true,
9739
9842
  held
9740
9843
  );
@@ -14532,10 +14635,10 @@ ${error instanceof Error ? error.message : String(error ?? "")}`;
14532
14635
  if (ok) this.settleInstalled();
14533
14636
  return ok;
14534
14637
  }
14535
- const state = inspectManagedSelection(this.managedOptions());
14536
- if (state.kind === "missing")
14638
+ const state2 = inspectManagedSelection(this.managedOptions());
14639
+ if (state2.kind === "missing")
14537
14640
  logger.warn(
14538
- `Published backend environment is not usable and will be rebuilt: ${state.detail}`,
14641
+ `Published backend environment is not usable and will be rebuilt: ${state2.detail}`,
14539
14642
  LogFileType.INSTALLER
14540
14643
  );
14541
14644
  this.ensurePreparationWindow(show);
@@ -15348,7 +15451,7 @@ class BrowserStateWriter {
15348
15451
  write() {
15349
15452
  try {
15350
15453
  const facts = this.facts();
15351
- const state = {
15454
+ const state2 = {
15352
15455
  pid: process.pid,
15353
15456
  port: this.port,
15354
15457
  session_key: this.sessionKey,
@@ -15389,7 +15492,7 @@ class BrowserStateWriter {
15389
15492
  mode: STATE_DIR_MODE
15390
15493
  });
15391
15494
  const staged = `${this.path}.${process.pid}.tmp`;
15392
- fs.writeFileSync(staged, `${JSON.stringify(state, null, 2)}
15495
+ fs.writeFileSync(staged, `${JSON.stringify(state2, null, 2)}
15393
15496
  `, {
15394
15497
  mode: STATE_FILE_MODE
15395
15498
  });
@@ -16148,13 +16251,13 @@ function requireCreateNode() {
16148
16251
  const defaultTagPrefix = "tag:yaml.org,2002:";
16149
16252
  function findTagObject(value, tagName, tags2) {
16150
16253
  if (tagName) {
16151
- const match = tags2.filter((t) => t.tag === tagName);
16152
- const tagObj = match.find((t) => !t.format) ?? match[0];
16254
+ const match = tags2.filter((t2) => t2.tag === tagName);
16255
+ const tagObj = match.find((t2) => !t2.format) ?? match[0];
16153
16256
  if (!tagObj)
16154
16257
  throw new Error(`Tag ${tagName} not found`);
16155
16258
  return tagObj;
16156
16259
  }
16157
- return tags2.find((t) => t.identify?.(value) && !t.format);
16260
+ return tags2.find((t2) => t2.identify?.(value) && !t2.format);
16158
16261
  }
16159
16262
  function createNode$1(value, tagName, ctx) {
16160
16263
  if (identity2.isDocument(value))
@@ -16784,10 +16887,10 @@ ${indent}`);
16784
16887
  let res = _stringify(type2);
16785
16888
  if (res === null) {
16786
16889
  const { defaultKeyType, defaultStringType } = ctx.options;
16787
- const t = implicitKey && defaultKeyType || defaultStringType;
16788
- res = _stringify(t);
16890
+ const t2 = implicitKey && defaultKeyType || defaultStringType;
16891
+ res = _stringify(t2);
16789
16892
  if (res === null)
16790
- throw new Error(`Unsupported default string type ${t}`);
16893
+ throw new Error(`Unsupported default string type ${t2}`);
16791
16894
  }
16792
16895
  return res;
16793
16896
  }
@@ -16845,24 +16948,24 @@ function requireStringify() {
16845
16948
  }
16846
16949
  function getTagObject(tags2, item) {
16847
16950
  if (item.tag) {
16848
- const match = tags2.filter((t) => t.tag === item.tag);
16951
+ const match = tags2.filter((t2) => t2.tag === item.tag);
16849
16952
  if (match.length > 0)
16850
- return match.find((t) => t.format === item.format) ?? match[0];
16953
+ return match.find((t2) => t2.format === item.format) ?? match[0];
16851
16954
  }
16852
16955
  let tagObj = void 0;
16853
16956
  let obj;
16854
16957
  if (identity2.isScalar(item)) {
16855
16958
  obj = item.value;
16856
- let match = tags2.filter((t) => t.identify?.(obj));
16959
+ let match = tags2.filter((t2) => t2.identify?.(obj));
16857
16960
  if (match.length > 1) {
16858
- const testMatch = match.filter((t) => t.test);
16961
+ const testMatch = match.filter((t2) => t2.test);
16859
16962
  if (testMatch.length > 0)
16860
16963
  match = testMatch;
16861
16964
  }
16862
- tagObj = match.find((t) => t.format === item.format) ?? match.find((t) => !t.format);
16965
+ tagObj = match.find((t2) => t2.format === item.format) ?? match.find((t2) => !t2.format);
16863
16966
  } else {
16864
16967
  obj = item;
16865
- tagObj = tags2.find((t) => t.nodeClass && obj instanceof t.nodeClass);
16968
+ tagObj = tags2.find((t2) => t2.nodeClass && obj instanceof t2.nodeClass);
16866
16969
  }
16867
16970
  if (!tagObj) {
16868
16971
  const name = obj?.constructor?.name ?? typeof obj;
@@ -19104,9 +19207,9 @@ function requireErrors() {
19104
19207
  let ci = col - 1;
19105
19208
  let lineStr = src.substring(lc.lineStarts[line - 1], lc.lineStarts[line]).replace(/[\n\r]+$/, "");
19106
19209
  if (ci >= 60 && lineStr.length > 80) {
19107
- const trimStart = Math.min(ci - 39, lineStr.length - 79);
19108
- lineStr = "…" + lineStr.substring(trimStart);
19109
- ci -= trimStart - 1;
19210
+ const trimStart4 = Math.min(ci - 39, lineStr.length - 79);
19211
+ lineStr = "…" + lineStr.substring(trimStart4);
19212
+ ci -= trimStart4 - 1;
19110
19213
  }
19111
19214
  if (lineStr.length > 80)
19112
19215
  lineStr = lineStr.substring(0, 79) + "…";
@@ -19784,7 +19887,7 @@ function requireComposeCollection() {
19784
19887
  if (!tagToken || !tagName || tagName === "!" || tagName === YAMLMap2.YAMLMap.tagName && expType === "map" || tagName === YAMLSeq2.YAMLSeq.tagName && expType === "seq") {
19785
19888
  return resolveCollection(CN, ctx, token, onError, tagName);
19786
19889
  }
19787
- let tag = ctx.schema.tags.find((t) => t.tag === tagName && t.collection === expType);
19890
+ let tag = ctx.schema.tags.find((t2) => t2.tag === tagName && t2.collection === expType);
19788
19891
  if (!tag) {
19789
19892
  const kt = ctx.schema.knownTags[tagName];
19790
19893
  if (kt && kt.collection === expType) {
@@ -21186,11 +21289,11 @@ function requireLexer() {
21186
21289
  hasChars(n) {
21187
21290
  return this.pos + n <= this.buffer.length;
21188
21291
  }
21189
- setNext(state) {
21292
+ setNext(state2) {
21190
21293
  this.buffer = this.buffer.substring(this.pos);
21191
21294
  this.pos = 0;
21192
21295
  this.lineEndPos = null;
21193
- this.next = state;
21296
+ this.next = state2;
21194
21297
  return null;
21195
21298
  }
21196
21299
  peek(n) {
@@ -21783,7 +21886,7 @@ function requireParser() {
21783
21886
  }
21784
21887
  }
21785
21888
  }
21786
- class Parser {
21889
+ class Parser2 {
21787
21890
  /**
21788
21891
  * @param onNewLine - If defined, called separately with the start position of
21789
21892
  * each new line (in `parse()`, including the start of input).
@@ -22556,7 +22659,7 @@ function requireParser() {
22556
22659
  }
22557
22660
  }
22558
22661
  }
22559
- parser.Parser = Parser;
22662
+ parser.Parser = Parser2;
22560
22663
  return parser;
22561
22664
  }
22562
22665
  var publicApi = {};
@@ -22609,7 +22712,7 @@ function requirePublicApi() {
22609
22712
  }
22610
22713
  return doc;
22611
22714
  }
22612
- function parse(src, reviver, options) {
22715
+ function parse2(src, reviver, options) {
22613
22716
  let _reviver = void 0;
22614
22717
  if (typeof reviver === "function") {
22615
22718
  _reviver = reviver;
@@ -22650,7 +22753,7 @@ function requirePublicApi() {
22650
22753
  return value.toString(options);
22651
22754
  return new Document2.Document(value, _replacer, options).toString(options);
22652
22755
  }
22653
- publicApi.parse = parse;
22756
+ publicApi.parse = parse2;
22654
22757
  publicApi.parseAllDocuments = parseAllDocuments;
22655
22758
  publicApi.parseDocument = parseDocument;
22656
22759
  publicApi.stringify = stringify2;
@@ -23331,8 +23434,8 @@ function consoleCompletionHooks(deps) {
23331
23434
  };
23332
23435
  };
23333
23436
  const displayed = (surface) => {
23334
- const state = deps.host()?.state();
23335
- return state?.displayed_surface === surface;
23437
+ const state2 = deps.host()?.state();
23438
+ return state2?.displayed_surface === surface;
23336
23439
  };
23337
23440
  const completionFor = (surface, exitCode, key) => {
23338
23441
  const described = describe2(surface);
@@ -23906,8 +24009,8 @@ class ConsoleRegistry {
23906
24009
  restored: { user: 0, agent: 0 }
23907
24010
  };
23908
24011
  for (const entry of this.entries.values()) {
23909
- const state = !entry.record.live ? "restored" : !entry.record.running ? "exited" : entry.runtime === null ? "starting" : "running";
23910
- states[state][entry.record.origin] += 1;
24012
+ const state2 = !entry.record.live ? "restored" : !entry.record.running ? "exited" : entry.runtime === null ? "starting" : "running";
24013
+ states[state2][entry.record.origin] += 1;
23911
24014
  }
23912
24015
  return {
23913
24016
  generation: this.generation,
@@ -27540,12 +27643,12 @@ function newEntry(origin, displayAuthority2, requester, kind, now, sequence, com
27540
27643
  ...broad ? { broad } : {}
27541
27644
  };
27542
27645
  }
27543
- function receiptFor(entry, state, now) {
27646
+ function receiptFor(entry, state2, now) {
27544
27647
  return {
27545
27648
  entryId: entry.entryId,
27546
27649
  origin: entry.origin,
27547
27650
  requester: entry.requester,
27548
- state,
27651
+ state: state2,
27549
27652
  decidedAt: now,
27550
27653
  expiresAt: now + ACCESS_RESULT_TTL_MS
27551
27654
  };
@@ -27827,10 +27930,10 @@ class ApprovalStore {
27827
27930
  );
27828
27931
  return this.entryResponse(entry, "pending");
27829
27932
  }
27830
- entryResponse(entry, state) {
27933
+ entryResponse(entry, state2) {
27831
27934
  return {
27832
27935
  origin: entry.origin,
27833
- state,
27936
+ state: state2,
27834
27937
  entry_id: entry.entryId,
27835
27938
  authority: entry.displayAuthority,
27836
27939
  expires_at: entry.expiresAt,
@@ -27849,7 +27952,7 @@ class ApprovalStore {
27849
27952
  void 0,
27850
27953
  now
27851
27954
  );
27852
- const state = accessState(
27955
+ const state2 = accessState(
27853
27956
  entry ? {
27854
27957
  origin: entry.origin,
27855
27958
  hostname: entry.displayAuthority,
@@ -27879,12 +27982,12 @@ class ApprovalStore {
27879
27982
  requester,
27880
27983
  now
27881
27984
  );
27882
- if (state === "none" && this.refusalReason(url) === "denied") {
27985
+ if (state2 === "none" && this.refusalReason(url) === "denied") {
27883
27986
  return { origin: url.origin, state: "denied" };
27884
27987
  }
27885
27988
  return {
27886
27989
  origin: url.origin,
27887
- state,
27990
+ state: state2,
27888
27991
  ...entry ? { entry_id: entry.entryId } : {}
27889
27992
  };
27890
27993
  }
@@ -28798,6 +28901,3401 @@ class CdpPool {
28798
28901
  for (const id2 of [...this.attachments.keys()]) await this.detach(id2);
28799
28902
  }
28800
28903
  }
28904
+ function memoize(fn, options) {
28905
+ const cache = options && options.cache ? options.cache : cacheDefault;
28906
+ const serializer = options && options.serializer ? options.serializer : serializerDefault;
28907
+ return (options && options.strategy ? options.strategy : strategyDefault)(fn, {
28908
+ cache,
28909
+ serializer
28910
+ });
28911
+ }
28912
+ function isPrimitive(value) {
28913
+ return value == null || typeof value === "number" || typeof value === "boolean";
28914
+ }
28915
+ function monadic(fn, cache, serializer, arg) {
28916
+ const cacheKey = isPrimitive(arg) ? arg : serializer(arg);
28917
+ let computedValue = cache.get(cacheKey);
28918
+ if (typeof computedValue === "undefined") {
28919
+ computedValue = fn.call(this, arg);
28920
+ cache.set(cacheKey, computedValue);
28921
+ }
28922
+ return computedValue;
28923
+ }
28924
+ function variadic(fn, cache, serializer) {
28925
+ const args = Array.prototype.slice.call(arguments, 3);
28926
+ const cacheKey = serializer(args);
28927
+ let computedValue = cache.get(cacheKey);
28928
+ if (typeof computedValue === "undefined") {
28929
+ computedValue = fn.apply(this, args);
28930
+ cache.set(cacheKey, computedValue);
28931
+ }
28932
+ return computedValue;
28933
+ }
28934
+ function assemble(fn, context, strategy, cache, serialize) {
28935
+ return strategy.bind(context, fn, cache, serialize);
28936
+ }
28937
+ function strategyDefault(fn, options) {
28938
+ const strategy = fn.length === 1 ? monadic : variadic;
28939
+ return assemble(fn, this, strategy, options.cache.create(), options.serializer);
28940
+ }
28941
+ function strategyVariadic(fn, options) {
28942
+ return assemble(fn, this, variadic, options.cache.create(), options.serializer);
28943
+ }
28944
+ const serializerDefault = function() {
28945
+ return JSON.stringify(arguments);
28946
+ };
28947
+ var ObjectWithoutPrototypeCache = class {
28948
+ constructor() {
28949
+ this.cache = /* @__PURE__ */ Object.create(null);
28950
+ }
28951
+ get(key) {
28952
+ return this.cache[key];
28953
+ }
28954
+ set(key, value) {
28955
+ this.cache[key] = value;
28956
+ }
28957
+ };
28958
+ const cacheDefault = { create: function create() {
28959
+ return new ObjectWithoutPrototypeCache();
28960
+ } };
28961
+ const strategies = {
28962
+ variadic: strategyVariadic
28963
+ };
28964
+ const DATE_TIME_REGEX = /(?:[Eec]{1,6}|G{1,5}|[Qq]{1,5}|(?:[yYur]+|U{1,5})|[ML]{1,5}|d{1,2}|D{1,3}|F{1}|[abB]{1,5}|[hkHK]{1,2}|w{1,2}|W{1}|m{1,2}|s{1,2}|[zZOvVxX]{1,4})(?=([^']*'[^']*')*[^']*$)/g;
28965
+ function parseDateTimeSkeleton(skeleton) {
28966
+ const result = {};
28967
+ skeleton.replace(DATE_TIME_REGEX, (match) => {
28968
+ const len = match.length;
28969
+ switch (match[0]) {
28970
+ case "G":
28971
+ result.era = len === 4 ? "long" : len === 5 ? "narrow" : "short";
28972
+ break;
28973
+ case "y":
28974
+ result.year = len === 2 ? "2-digit" : "numeric";
28975
+ break;
28976
+ case "Y":
28977
+ case "u":
28978
+ case "U":
28979
+ case "r":
28980
+ throw new RangeError("`Y/u/U/r` (year) patterns are not supported, use `y` instead");
28981
+ case "q":
28982
+ case "Q":
28983
+ throw new RangeError("`q/Q` (quarter) patterns are not supported");
28984
+ case "M":
28985
+ case "L":
28986
+ result.month = [
28987
+ "numeric",
28988
+ "2-digit",
28989
+ "short",
28990
+ "long",
28991
+ "narrow"
28992
+ ][len - 1];
28993
+ break;
28994
+ case "w":
28995
+ case "W":
28996
+ throw new RangeError("`w/W` (week) patterns are not supported");
28997
+ case "d":
28998
+ result.day = ["numeric", "2-digit"][len - 1];
28999
+ break;
29000
+ case "D":
29001
+ case "F":
29002
+ case "g":
29003
+ throw new RangeError("`D/F/g` (day) patterns are not supported, use `d` instead");
29004
+ case "E":
29005
+ result.weekday = len === 4 ? "long" : len === 5 ? "narrow" : "short";
29006
+ break;
29007
+ case "e":
29008
+ if (len < 4) throw new RangeError("`e..eee` (weekday) patterns are not supported");
29009
+ result.weekday = [
29010
+ "short",
29011
+ "long",
29012
+ "narrow",
29013
+ "short"
29014
+ ][len - 3];
29015
+ break;
29016
+ case "c":
29017
+ if (len < 4) throw new RangeError("`c..ccc` (weekday) patterns are not supported");
29018
+ result.weekday = [
29019
+ "short",
29020
+ "long",
29021
+ "narrow",
29022
+ "short"
29023
+ ][len - 3];
29024
+ break;
29025
+ case "a":
29026
+ result.hour12 = true;
29027
+ break;
29028
+ case "b":
29029
+ case "B":
29030
+ throw new RangeError("`b/B` (period) patterns are not supported, use `a` instead");
29031
+ case "h":
29032
+ result.hourCycle = "h12";
29033
+ result.hour = ["numeric", "2-digit"][len - 1];
29034
+ break;
29035
+ case "H":
29036
+ result.hourCycle = "h23";
29037
+ result.hour = ["numeric", "2-digit"][len - 1];
29038
+ break;
29039
+ case "K":
29040
+ result.hourCycle = "h11";
29041
+ result.hour = ["numeric", "2-digit"][len - 1];
29042
+ break;
29043
+ case "k":
29044
+ result.hourCycle = "h24";
29045
+ result.hour = ["numeric", "2-digit"][len - 1];
29046
+ break;
29047
+ case "j":
29048
+ case "J":
29049
+ case "C":
29050
+ throw new RangeError("`j/J/C` (hour) patterns are not supported, use `h/H/K/k` instead");
29051
+ case "m":
29052
+ result.minute = ["numeric", "2-digit"][len - 1];
29053
+ break;
29054
+ case "s":
29055
+ result.second = ["numeric", "2-digit"][len - 1];
29056
+ break;
29057
+ case "S":
29058
+ case "A":
29059
+ throw new RangeError("`S/A` (second) patterns are not supported, use `s` instead");
29060
+ case "z":
29061
+ result.timeZoneName = len < 4 ? "short" : "long";
29062
+ break;
29063
+ case "Z":
29064
+ case "O":
29065
+ case "v":
29066
+ case "V":
29067
+ case "X":
29068
+ case "x":
29069
+ throw new RangeError("`Z/O/v/V/X/x` (timeZone) patterns are not supported, use `z` instead");
29070
+ }
29071
+ return "";
29072
+ });
29073
+ return result;
29074
+ }
29075
+ const WHITE_SPACE_REGEX = /[\t-\r \x85\u200E\u200F\u2028\u2029]/i;
29076
+ function parseNumberSkeletonFromString(skeleton) {
29077
+ if (skeleton.length === 0) throw new Error("Number skeleton cannot be empty");
29078
+ const stringTokens = skeleton.split(WHITE_SPACE_REGEX).filter((x) => x.length > 0);
29079
+ const tokens = [];
29080
+ for (const stringToken of stringTokens) {
29081
+ let stemAndOptions = stringToken.split("/");
29082
+ if (stemAndOptions.length === 0) throw new Error("Invalid number skeleton");
29083
+ const [stem, ...options] = stemAndOptions;
29084
+ for (const option of options) if (option.length === 0) throw new Error("Invalid number skeleton");
29085
+ tokens.push({
29086
+ stem,
29087
+ options
29088
+ });
29089
+ }
29090
+ return tokens;
29091
+ }
29092
+ function icuUnitToEcma(unit) {
29093
+ return unit.replace(/^(.*?)-/, "");
29094
+ }
29095
+ const FRACTION_PRECISION_REGEX = /^\.(?:(0+)(\*)?|(#+)|(0+)(#+))$/g;
29096
+ const SIGNIFICANT_PRECISION_REGEX = /^(@+)?(\+|#+)?[rs]?$/g;
29097
+ const INTEGER_WIDTH_REGEX = /(\*)(0+)|(#+)(0+)|(0+)/g;
29098
+ const CONCISE_INTEGER_WIDTH_REGEX = /^(0+)$/;
29099
+ function parseSignificantPrecision(str) {
29100
+ const result = {};
29101
+ if (str[str.length - 1] === "r") result.roundingPriority = "morePrecision";
29102
+ else if (str[str.length - 1] === "s") result.roundingPriority = "lessPrecision";
29103
+ str.replace(SIGNIFICANT_PRECISION_REGEX, function(_, g1, g2) {
29104
+ if (typeof g2 !== "string") {
29105
+ result.minimumSignificantDigits = g1.length;
29106
+ result.maximumSignificantDigits = g1.length;
29107
+ } else if (g2 === "+") result.minimumSignificantDigits = g1.length;
29108
+ else if (g1[0] === "#") result.maximumSignificantDigits = g1.length;
29109
+ else {
29110
+ result.minimumSignificantDigits = g1.length;
29111
+ result.maximumSignificantDigits = g1.length + (typeof g2 === "string" ? g2.length : 0);
29112
+ }
29113
+ return "";
29114
+ });
29115
+ return result;
29116
+ }
29117
+ function parseSign(str) {
29118
+ switch (str) {
29119
+ case "sign-auto":
29120
+ return { signDisplay: "auto" };
29121
+ case "sign-accounting":
29122
+ case "()":
29123
+ return { currencySign: "accounting" };
29124
+ case "sign-always":
29125
+ case "+!":
29126
+ return { signDisplay: "always" };
29127
+ case "sign-accounting-always":
29128
+ case "()!":
29129
+ return {
29130
+ signDisplay: "always",
29131
+ currencySign: "accounting"
29132
+ };
29133
+ case "sign-except-zero":
29134
+ case "+?":
29135
+ return { signDisplay: "exceptZero" };
29136
+ case "sign-accounting-except-zero":
29137
+ case "()?":
29138
+ return {
29139
+ signDisplay: "exceptZero",
29140
+ currencySign: "accounting"
29141
+ };
29142
+ case "sign-never":
29143
+ case "+_":
29144
+ return { signDisplay: "never" };
29145
+ }
29146
+ }
29147
+ function parseConciseScientificAndEngineeringStem(stem) {
29148
+ let result;
29149
+ if (stem[0] === "E" && stem[1] === "E") {
29150
+ result = { notation: "engineering" };
29151
+ stem = stem.slice(2);
29152
+ } else if (stem[0] === "E") {
29153
+ result = { notation: "scientific" };
29154
+ stem = stem.slice(1);
29155
+ }
29156
+ if (result) {
29157
+ const signDisplay = stem.slice(0, 2);
29158
+ if (signDisplay === "+!") {
29159
+ result.signDisplay = "always";
29160
+ stem = stem.slice(2);
29161
+ } else if (signDisplay === "+?") {
29162
+ result.signDisplay = "exceptZero";
29163
+ stem = stem.slice(2);
29164
+ }
29165
+ if (!CONCISE_INTEGER_WIDTH_REGEX.test(stem)) throw new Error("Malformed concise eng/scientific notation");
29166
+ result.minimumIntegerDigits = stem.length;
29167
+ }
29168
+ return result;
29169
+ }
29170
+ function parseNotationOptions(opt) {
29171
+ const result = {};
29172
+ const signOpts = parseSign(opt);
29173
+ if (signOpts) return signOpts;
29174
+ return result;
29175
+ }
29176
+ function parseNumberSkeleton(tokens) {
29177
+ let result = {};
29178
+ for (const token of tokens) {
29179
+ switch (token.stem) {
29180
+ case "percent":
29181
+ case "%":
29182
+ result.style = "percent";
29183
+ continue;
29184
+ case "%x100":
29185
+ result.style = "percent";
29186
+ result.scale = 100;
29187
+ continue;
29188
+ case "currency":
29189
+ result.style = "currency";
29190
+ result.currency = token.options[0];
29191
+ continue;
29192
+ case "group-off":
29193
+ case ",_":
29194
+ result.useGrouping = false;
29195
+ continue;
29196
+ case "precision-integer":
29197
+ case ".":
29198
+ result.maximumFractionDigits = 0;
29199
+ continue;
29200
+ case "measure-unit":
29201
+ case "unit":
29202
+ result.style = "unit";
29203
+ result.unit = icuUnitToEcma(token.options[0]);
29204
+ continue;
29205
+ case "compact-short":
29206
+ case "K":
29207
+ result.notation = "compact";
29208
+ result.compactDisplay = "short";
29209
+ continue;
29210
+ case "compact-long":
29211
+ case "KK":
29212
+ result.notation = "compact";
29213
+ result.compactDisplay = "long";
29214
+ continue;
29215
+ case "scientific":
29216
+ result = {
29217
+ ...result,
29218
+ notation: "scientific",
29219
+ ...token.options.reduce((all, opt) => ({
29220
+ ...all,
29221
+ ...parseNotationOptions(opt)
29222
+ }), {})
29223
+ };
29224
+ continue;
29225
+ case "engineering":
29226
+ result = {
29227
+ ...result,
29228
+ notation: "engineering",
29229
+ ...token.options.reduce((all, opt) => ({
29230
+ ...all,
29231
+ ...parseNotationOptions(opt)
29232
+ }), {})
29233
+ };
29234
+ continue;
29235
+ case "notation-simple":
29236
+ result.notation = "standard";
29237
+ continue;
29238
+ case "unit-width-narrow":
29239
+ result.currencyDisplay = "narrowSymbol";
29240
+ result.unitDisplay = "narrow";
29241
+ continue;
29242
+ case "unit-width-short":
29243
+ result.currencyDisplay = "code";
29244
+ result.unitDisplay = "short";
29245
+ continue;
29246
+ case "unit-width-full-name":
29247
+ result.currencyDisplay = "name";
29248
+ result.unitDisplay = "long";
29249
+ continue;
29250
+ case "unit-width-iso-code":
29251
+ result.currencyDisplay = "symbol";
29252
+ continue;
29253
+ case "scale":
29254
+ result.scale = parseFloat(token.options[0]);
29255
+ continue;
29256
+ case "rounding-mode-floor":
29257
+ result.roundingMode = "floor";
29258
+ continue;
29259
+ case "rounding-mode-ceiling":
29260
+ result.roundingMode = "ceil";
29261
+ continue;
29262
+ case "rounding-mode-down":
29263
+ result.roundingMode = "trunc";
29264
+ continue;
29265
+ case "rounding-mode-up":
29266
+ result.roundingMode = "expand";
29267
+ continue;
29268
+ case "rounding-mode-half-even":
29269
+ result.roundingMode = "halfEven";
29270
+ continue;
29271
+ case "rounding-mode-half-down":
29272
+ result.roundingMode = "halfTrunc";
29273
+ continue;
29274
+ case "rounding-mode-half-up":
29275
+ result.roundingMode = "halfExpand";
29276
+ continue;
29277
+ case "integer-width":
29278
+ if (token.options.length > 1) throw new RangeError("integer-width stems only accept a single optional option");
29279
+ token.options[0].replace(INTEGER_WIDTH_REGEX, function(_, g1, g2, g3, g4, g5) {
29280
+ if (g1) result.minimumIntegerDigits = g2.length;
29281
+ else if (g3 && g4) throw new Error("We currently do not support maximum integer digits");
29282
+ else if (g5) throw new Error("We currently do not support exact integer digits");
29283
+ return "";
29284
+ });
29285
+ continue;
29286
+ }
29287
+ if (CONCISE_INTEGER_WIDTH_REGEX.test(token.stem)) {
29288
+ result.minimumIntegerDigits = token.stem.length;
29289
+ continue;
29290
+ }
29291
+ if (FRACTION_PRECISION_REGEX.test(token.stem)) {
29292
+ if (token.options.length > 1) throw new RangeError("Fraction-precision stems only accept a single optional option");
29293
+ token.stem.replace(FRACTION_PRECISION_REGEX, function(_, g1, g2, g3, g4, g5) {
29294
+ if (g2 === "*") result.minimumFractionDigits = g1.length;
29295
+ else if (g3 && g3[0] === "#") result.maximumFractionDigits = g3.length;
29296
+ else if (g4 && g5) {
29297
+ result.minimumFractionDigits = g4.length;
29298
+ result.maximumFractionDigits = g4.length + g5.length;
29299
+ } else {
29300
+ result.minimumFractionDigits = g1.length;
29301
+ result.maximumFractionDigits = g1.length;
29302
+ }
29303
+ return "";
29304
+ });
29305
+ const opt = token.options[0];
29306
+ if (opt === "w") result = {
29307
+ ...result,
29308
+ trailingZeroDisplay: "stripIfInteger"
29309
+ };
29310
+ else if (opt) result = {
29311
+ ...result,
29312
+ ...parseSignificantPrecision(opt)
29313
+ };
29314
+ continue;
29315
+ }
29316
+ if (SIGNIFICANT_PRECISION_REGEX.test(token.stem)) {
29317
+ result = {
29318
+ ...result,
29319
+ ...parseSignificantPrecision(token.stem)
29320
+ };
29321
+ continue;
29322
+ }
29323
+ const signOpts = parseSign(token.stem);
29324
+ if (signOpts) result = {
29325
+ ...result,
29326
+ ...signOpts
29327
+ };
29328
+ const conciseScientificAndEngineeringOpts = parseConciseScientificAndEngineeringStem(token.stem);
29329
+ if (conciseScientificAndEngineeringOpts) result = {
29330
+ ...result,
29331
+ ...conciseScientificAndEngineeringOpts
29332
+ };
29333
+ }
29334
+ return result;
29335
+ }
29336
+ let ErrorKind = /* @__PURE__ */ function(ErrorKind2) {
29337
+ ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_CLOSING_BRACE"] = 1] = "EXPECT_ARGUMENT_CLOSING_BRACE";
29338
+ ErrorKind2[ErrorKind2["EMPTY_ARGUMENT"] = 2] = "EMPTY_ARGUMENT";
29339
+ ErrorKind2[ErrorKind2["MALFORMED_ARGUMENT"] = 3] = "MALFORMED_ARGUMENT";
29340
+ ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_TYPE"] = 4] = "EXPECT_ARGUMENT_TYPE";
29341
+ ErrorKind2[ErrorKind2["INVALID_ARGUMENT_TYPE"] = 5] = "INVALID_ARGUMENT_TYPE";
29342
+ ErrorKind2[ErrorKind2["EXPECT_ARGUMENT_STYLE"] = 6] = "EXPECT_ARGUMENT_STYLE";
29343
+ ErrorKind2[ErrorKind2["INVALID_NUMBER_SKELETON"] = 7] = "INVALID_NUMBER_SKELETON";
29344
+ ErrorKind2[ErrorKind2["INVALID_DATE_TIME_SKELETON"] = 8] = "INVALID_DATE_TIME_SKELETON";
29345
+ ErrorKind2[ErrorKind2["EXPECT_NUMBER_SKELETON"] = 9] = "EXPECT_NUMBER_SKELETON";
29346
+ ErrorKind2[ErrorKind2["EXPECT_DATE_TIME_SKELETON"] = 10] = "EXPECT_DATE_TIME_SKELETON";
29347
+ ErrorKind2[ErrorKind2["UNCLOSED_QUOTE_IN_ARGUMENT_STYLE"] = 11] = "UNCLOSED_QUOTE_IN_ARGUMENT_STYLE";
29348
+ ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_OPTIONS"] = 12] = "EXPECT_SELECT_ARGUMENT_OPTIONS";
29349
+ ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE"] = 13] = "EXPECT_PLURAL_ARGUMENT_OFFSET_VALUE";
29350
+ ErrorKind2[ErrorKind2["INVALID_PLURAL_ARGUMENT_OFFSET_VALUE"] = 14] = "INVALID_PLURAL_ARGUMENT_OFFSET_VALUE";
29351
+ ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_SELECTOR"] = 15] = "EXPECT_SELECT_ARGUMENT_SELECTOR";
29352
+ ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_SELECTOR"] = 16] = "EXPECT_PLURAL_ARGUMENT_SELECTOR";
29353
+ ErrorKind2[ErrorKind2["EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT"] = 17] = "EXPECT_SELECT_ARGUMENT_SELECTOR_FRAGMENT";
29354
+ ErrorKind2[ErrorKind2["EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT"] = 18] = "EXPECT_PLURAL_ARGUMENT_SELECTOR_FRAGMENT";
29355
+ ErrorKind2[ErrorKind2["INVALID_PLURAL_ARGUMENT_SELECTOR"] = 19] = "INVALID_PLURAL_ARGUMENT_SELECTOR";
29356
+ ErrorKind2[ErrorKind2["DUPLICATE_PLURAL_ARGUMENT_SELECTOR"] = 20] = "DUPLICATE_PLURAL_ARGUMENT_SELECTOR";
29357
+ ErrorKind2[ErrorKind2["DUPLICATE_SELECT_ARGUMENT_SELECTOR"] = 21] = "DUPLICATE_SELECT_ARGUMENT_SELECTOR";
29358
+ ErrorKind2[ErrorKind2["MISSING_OTHER_CLAUSE"] = 22] = "MISSING_OTHER_CLAUSE";
29359
+ ErrorKind2[ErrorKind2["INVALID_TAG"] = 23] = "INVALID_TAG";
29360
+ ErrorKind2[ErrorKind2["INVALID_TAG_NAME"] = 25] = "INVALID_TAG_NAME";
29361
+ ErrorKind2[ErrorKind2["UNMATCHED_CLOSING_TAG"] = 26] = "UNMATCHED_CLOSING_TAG";
29362
+ ErrorKind2[ErrorKind2["UNCLOSED_TAG"] = 27] = "UNCLOSED_TAG";
29363
+ return ErrorKind2;
29364
+ }({});
29365
+ function isLiteralElement(el) {
29366
+ return el.type === 0;
29367
+ }
29368
+ function isArgumentElement(el) {
29369
+ return el.type === 1;
29370
+ }
29371
+ function isNumberElement(el) {
29372
+ return el.type === 2;
29373
+ }
29374
+ function isDateElement(el) {
29375
+ return el.type === 3;
29376
+ }
29377
+ function isTimeElement(el) {
29378
+ return el.type === 4;
29379
+ }
29380
+ function isSelectElement(el) {
29381
+ return el.type === 5;
29382
+ }
29383
+ function isPluralElement(el) {
29384
+ return el.type === 6;
29385
+ }
29386
+ function isPoundElement(el) {
29387
+ return el.type === 7;
29388
+ }
29389
+ function isTagElement(el) {
29390
+ return el.type === 8;
29391
+ }
29392
+ function isNumberSkeleton(el) {
29393
+ return !!(el && typeof el === "object" && el.type === 0);
29394
+ }
29395
+ function isDateTimeSkeleton(el) {
29396
+ return !!(el && typeof el === "object" && el.type === 1);
29397
+ }
29398
+ const SPACE_SEPARATOR_REGEX = /[ \xA0\u1680\u2000-\u200A\u202F\u205F\u3000]/;
29399
+ const IDENTIFIER_PREFIX_REGEX = /([^\t-\r -\/:-@\[-\^`\{-~\x85\xA0-\xA7\xA9\xAB\xAC\xAE\xB0\xB1\xB6\xBB\xBF\xD7\xF7\u1680\u2000-\u200A\u2010-\u2029\u202F-\u203E\u2041-\u2053\u2055-\u205F\u2190-\u245F\u2500-\u2775\u2794-\u2BFF\u2E00-\u2E7F\u3000-\u3003\u3008-\u3020\u3030\uFD3E\uFD3F\uFE45\uFE46]*)/g;
29400
+ const timeData = {
29401
+ "001": ["H", "h"],
29402
+ "419": [
29403
+ "h",
29404
+ "H",
29405
+ "hB",
29406
+ "hb"
29407
+ ],
29408
+ "AC": [
29409
+ "H",
29410
+ "h",
29411
+ "hb",
29412
+ "hB"
29413
+ ],
29414
+ "AD": ["H", "hB"],
29415
+ "AE": [
29416
+ "h",
29417
+ "hB",
29418
+ "hb",
29419
+ "H"
29420
+ ],
29421
+ "AF": [
29422
+ "H",
29423
+ "hb",
29424
+ "hB",
29425
+ "h"
29426
+ ],
29427
+ "AG": [
29428
+ "h",
29429
+ "hb",
29430
+ "H",
29431
+ "hB"
29432
+ ],
29433
+ "AI": [
29434
+ "H",
29435
+ "h",
29436
+ "hb",
29437
+ "hB"
29438
+ ],
29439
+ "AL": [
29440
+ "h",
29441
+ "H",
29442
+ "hB"
29443
+ ],
29444
+ "AM": ["H", "hB"],
29445
+ "AO": ["H", "hB"],
29446
+ "AR": [
29447
+ "h",
29448
+ "H",
29449
+ "hB",
29450
+ "hb"
29451
+ ],
29452
+ "AS": ["h", "H"],
29453
+ "AT": ["H", "hB"],
29454
+ "AU": [
29455
+ "h",
29456
+ "hb",
29457
+ "H",
29458
+ "hB"
29459
+ ],
29460
+ "AW": ["H", "hB"],
29461
+ "AX": ["H"],
29462
+ "AZ": [
29463
+ "H",
29464
+ "hB",
29465
+ "h"
29466
+ ],
29467
+ "BA": [
29468
+ "H",
29469
+ "hB",
29470
+ "h"
29471
+ ],
29472
+ "BB": [
29473
+ "h",
29474
+ "hb",
29475
+ "H",
29476
+ "hB"
29477
+ ],
29478
+ "BD": [
29479
+ "h",
29480
+ "hB",
29481
+ "H"
29482
+ ],
29483
+ "BE": ["H", "hB"],
29484
+ "BF": ["H", "hB"],
29485
+ "BG": [
29486
+ "H",
29487
+ "hB",
29488
+ "h"
29489
+ ],
29490
+ "BH": [
29491
+ "h",
29492
+ "hB",
29493
+ "hb",
29494
+ "H"
29495
+ ],
29496
+ "BI": ["H", "h"],
29497
+ "BJ": ["H", "hB"],
29498
+ "BL": ["H", "hB"],
29499
+ "BM": [
29500
+ "h",
29501
+ "hb",
29502
+ "H",
29503
+ "hB"
29504
+ ],
29505
+ "BN": [
29506
+ "hb",
29507
+ "hB",
29508
+ "h",
29509
+ "H"
29510
+ ],
29511
+ "BO": [
29512
+ "h",
29513
+ "H",
29514
+ "hB",
29515
+ "hb"
29516
+ ],
29517
+ "BQ": ["H"],
29518
+ "BR": ["H", "hB"],
29519
+ "BS": [
29520
+ "h",
29521
+ "hb",
29522
+ "H",
29523
+ "hB"
29524
+ ],
29525
+ "BT": ["h", "H"],
29526
+ "BW": [
29527
+ "H",
29528
+ "h",
29529
+ "hb",
29530
+ "hB"
29531
+ ],
29532
+ "BY": ["H", "h"],
29533
+ "BZ": [
29534
+ "H",
29535
+ "h",
29536
+ "hb",
29537
+ "hB"
29538
+ ],
29539
+ "CA": [
29540
+ "h",
29541
+ "hb",
29542
+ "H",
29543
+ "hB"
29544
+ ],
29545
+ "CC": [
29546
+ "H",
29547
+ "h",
29548
+ "hb",
29549
+ "hB"
29550
+ ],
29551
+ "CD": ["hB", "H"],
29552
+ "CF": [
29553
+ "H",
29554
+ "h",
29555
+ "hB"
29556
+ ],
29557
+ "CG": ["H", "hB"],
29558
+ "CH": [
29559
+ "H",
29560
+ "hB",
29561
+ "h"
29562
+ ],
29563
+ "CI": ["H", "hB"],
29564
+ "CK": [
29565
+ "H",
29566
+ "h",
29567
+ "hb",
29568
+ "hB"
29569
+ ],
29570
+ "CL": [
29571
+ "h",
29572
+ "H",
29573
+ "hB",
29574
+ "hb"
29575
+ ],
29576
+ "CM": [
29577
+ "H",
29578
+ "h",
29579
+ "hB"
29580
+ ],
29581
+ "CN": [
29582
+ "H",
29583
+ "hB",
29584
+ "hb",
29585
+ "h"
29586
+ ],
29587
+ "CO": [
29588
+ "h",
29589
+ "H",
29590
+ "hB",
29591
+ "hb"
29592
+ ],
29593
+ "CP": ["H"],
29594
+ "CR": [
29595
+ "h",
29596
+ "H",
29597
+ "hB",
29598
+ "hb"
29599
+ ],
29600
+ "CU": [
29601
+ "h",
29602
+ "H",
29603
+ "hB",
29604
+ "hb"
29605
+ ],
29606
+ "CV": ["H", "hB"],
29607
+ "CW": ["H", "hB"],
29608
+ "CX": [
29609
+ "H",
29610
+ "h",
29611
+ "hb",
29612
+ "hB"
29613
+ ],
29614
+ "CY": [
29615
+ "h",
29616
+ "H",
29617
+ "hb",
29618
+ "hB"
29619
+ ],
29620
+ "CZ": ["H"],
29621
+ "DE": ["H", "hB"],
29622
+ "DG": [
29623
+ "H",
29624
+ "h",
29625
+ "hb",
29626
+ "hB"
29627
+ ],
29628
+ "DJ": ["h", "H"],
29629
+ "DK": ["H"],
29630
+ "DM": [
29631
+ "h",
29632
+ "hb",
29633
+ "H",
29634
+ "hB"
29635
+ ],
29636
+ "DO": [
29637
+ "h",
29638
+ "H",
29639
+ "hB",
29640
+ "hb"
29641
+ ],
29642
+ "DZ": [
29643
+ "h",
29644
+ "hB",
29645
+ "hb",
29646
+ "H"
29647
+ ],
29648
+ "EA": [
29649
+ "H",
29650
+ "h",
29651
+ "hB",
29652
+ "hb"
29653
+ ],
29654
+ "EC": [
29655
+ "h",
29656
+ "H",
29657
+ "hB",
29658
+ "hb"
29659
+ ],
29660
+ "EE": ["H", "hB"],
29661
+ "EG": [
29662
+ "h",
29663
+ "hB",
29664
+ "hb",
29665
+ "H"
29666
+ ],
29667
+ "EH": [
29668
+ "h",
29669
+ "hB",
29670
+ "hb",
29671
+ "H"
29672
+ ],
29673
+ "ER": ["h", "H"],
29674
+ "ES": [
29675
+ "H",
29676
+ "hB",
29677
+ "h",
29678
+ "hb"
29679
+ ],
29680
+ "ET": [
29681
+ "hB",
29682
+ "hb",
29683
+ "h",
29684
+ "H"
29685
+ ],
29686
+ "FI": ["H"],
29687
+ "FJ": [
29688
+ "h",
29689
+ "hb",
29690
+ "H",
29691
+ "hB"
29692
+ ],
29693
+ "FK": [
29694
+ "H",
29695
+ "h",
29696
+ "hb",
29697
+ "hB"
29698
+ ],
29699
+ "FM": [
29700
+ "h",
29701
+ "hb",
29702
+ "H",
29703
+ "hB"
29704
+ ],
29705
+ "FO": ["H", "h"],
29706
+ "FR": ["H", "hB"],
29707
+ "GA": ["H", "hB"],
29708
+ "GB": [
29709
+ "H",
29710
+ "h",
29711
+ "hb",
29712
+ "hB"
29713
+ ],
29714
+ "GD": [
29715
+ "h",
29716
+ "hb",
29717
+ "H",
29718
+ "hB"
29719
+ ],
29720
+ "GE": [
29721
+ "H",
29722
+ "hB",
29723
+ "h"
29724
+ ],
29725
+ "GF": ["H", "hB"],
29726
+ "GG": [
29727
+ "H",
29728
+ "h",
29729
+ "hb",
29730
+ "hB"
29731
+ ],
29732
+ "GH": ["h", "H"],
29733
+ "GI": [
29734
+ "H",
29735
+ "h",
29736
+ "hb",
29737
+ "hB"
29738
+ ],
29739
+ "GL": ["H", "h"],
29740
+ "GM": [
29741
+ "h",
29742
+ "hb",
29743
+ "H",
29744
+ "hB"
29745
+ ],
29746
+ "GN": ["H", "hB"],
29747
+ "GP": ["H", "hB"],
29748
+ "GQ": [
29749
+ "H",
29750
+ "hB",
29751
+ "h",
29752
+ "hb"
29753
+ ],
29754
+ "GR": [
29755
+ "h",
29756
+ "H",
29757
+ "hb",
29758
+ "hB"
29759
+ ],
29760
+ "GS": [
29761
+ "H",
29762
+ "h",
29763
+ "hb",
29764
+ "hB"
29765
+ ],
29766
+ "GT": [
29767
+ "h",
29768
+ "H",
29769
+ "hB",
29770
+ "hb"
29771
+ ],
29772
+ "GU": [
29773
+ "h",
29774
+ "hb",
29775
+ "H",
29776
+ "hB"
29777
+ ],
29778
+ "GW": ["H", "hB"],
29779
+ "GY": [
29780
+ "h",
29781
+ "hb",
29782
+ "H",
29783
+ "hB"
29784
+ ],
29785
+ "HK": [
29786
+ "h",
29787
+ "hB",
29788
+ "hb",
29789
+ "H"
29790
+ ],
29791
+ "HN": [
29792
+ "h",
29793
+ "H",
29794
+ "hB",
29795
+ "hb"
29796
+ ],
29797
+ "HR": ["H", "hB"],
29798
+ "HU": ["H", "h"],
29799
+ "IC": [
29800
+ "H",
29801
+ "h",
29802
+ "hB",
29803
+ "hb"
29804
+ ],
29805
+ "ID": ["H"],
29806
+ "IE": [
29807
+ "H",
29808
+ "h",
29809
+ "hb",
29810
+ "hB"
29811
+ ],
29812
+ "IL": ["H", "hB"],
29813
+ "IM": [
29814
+ "H",
29815
+ "h",
29816
+ "hb",
29817
+ "hB"
29818
+ ],
29819
+ "IN": ["h", "H"],
29820
+ "IO": [
29821
+ "H",
29822
+ "h",
29823
+ "hb",
29824
+ "hB"
29825
+ ],
29826
+ "IQ": [
29827
+ "h",
29828
+ "hB",
29829
+ "hb",
29830
+ "H"
29831
+ ],
29832
+ "IR": ["hB", "H"],
29833
+ "IS": ["H"],
29834
+ "IT": ["H", "hB"],
29835
+ "JE": [
29836
+ "H",
29837
+ "h",
29838
+ "hb",
29839
+ "hB"
29840
+ ],
29841
+ "JM": [
29842
+ "h",
29843
+ "hb",
29844
+ "H",
29845
+ "hB"
29846
+ ],
29847
+ "JO": [
29848
+ "h",
29849
+ "hB",
29850
+ "hb",
29851
+ "H"
29852
+ ],
29853
+ "JP": [
29854
+ "H",
29855
+ "K",
29856
+ "h"
29857
+ ],
29858
+ "KE": [
29859
+ "hB",
29860
+ "hb",
29861
+ "H",
29862
+ "h"
29863
+ ],
29864
+ "KG": [
29865
+ "H",
29866
+ "h",
29867
+ "hB",
29868
+ "hb"
29869
+ ],
29870
+ "KH": [
29871
+ "hB",
29872
+ "h",
29873
+ "H",
29874
+ "hb"
29875
+ ],
29876
+ "KI": [
29877
+ "h",
29878
+ "hb",
29879
+ "H",
29880
+ "hB"
29881
+ ],
29882
+ "KM": [
29883
+ "H",
29884
+ "h",
29885
+ "hB",
29886
+ "hb"
29887
+ ],
29888
+ "KN": [
29889
+ "h",
29890
+ "hb",
29891
+ "H",
29892
+ "hB"
29893
+ ],
29894
+ "KP": [
29895
+ "h",
29896
+ "H",
29897
+ "hB",
29898
+ "hb"
29899
+ ],
29900
+ "KR": [
29901
+ "h",
29902
+ "H",
29903
+ "hB",
29904
+ "hb"
29905
+ ],
29906
+ "KW": [
29907
+ "h",
29908
+ "hB",
29909
+ "hb",
29910
+ "H"
29911
+ ],
29912
+ "KY": [
29913
+ "h",
29914
+ "hb",
29915
+ "H",
29916
+ "hB"
29917
+ ],
29918
+ "KZ": ["H", "hB"],
29919
+ "LA": [
29920
+ "H",
29921
+ "hb",
29922
+ "hB",
29923
+ "h"
29924
+ ],
29925
+ "LB": [
29926
+ "h",
29927
+ "hB",
29928
+ "hb",
29929
+ "H"
29930
+ ],
29931
+ "LC": [
29932
+ "h",
29933
+ "hb",
29934
+ "H",
29935
+ "hB"
29936
+ ],
29937
+ "LI": [
29938
+ "H",
29939
+ "hB",
29940
+ "h"
29941
+ ],
29942
+ "LK": [
29943
+ "H",
29944
+ "h",
29945
+ "hB",
29946
+ "hb"
29947
+ ],
29948
+ "LR": [
29949
+ "h",
29950
+ "hb",
29951
+ "H",
29952
+ "hB"
29953
+ ],
29954
+ "LS": ["h", "H"],
29955
+ "LT": [
29956
+ "H",
29957
+ "h",
29958
+ "hb",
29959
+ "hB"
29960
+ ],
29961
+ "LU": [
29962
+ "H",
29963
+ "h",
29964
+ "hB"
29965
+ ],
29966
+ "LV": [
29967
+ "H",
29968
+ "hB",
29969
+ "hb",
29970
+ "h"
29971
+ ],
29972
+ "LY": [
29973
+ "h",
29974
+ "hB",
29975
+ "hb",
29976
+ "H"
29977
+ ],
29978
+ "MA": [
29979
+ "H",
29980
+ "h",
29981
+ "hB",
29982
+ "hb"
29983
+ ],
29984
+ "MC": ["H", "hB"],
29985
+ "MD": ["H", "hB"],
29986
+ "ME": [
29987
+ "H",
29988
+ "hB",
29989
+ "h"
29990
+ ],
29991
+ "MF": ["H", "hB"],
29992
+ "MG": ["H", "h"],
29993
+ "MH": [
29994
+ "h",
29995
+ "hb",
29996
+ "H",
29997
+ "hB"
29998
+ ],
29999
+ "MK": [
30000
+ "H",
30001
+ "h",
30002
+ "hb",
30003
+ "hB"
30004
+ ],
30005
+ "ML": ["H"],
30006
+ "MM": [
30007
+ "hB",
30008
+ "hb",
30009
+ "H",
30010
+ "h"
30011
+ ],
30012
+ "MN": [
30013
+ "H",
30014
+ "h",
30015
+ "hb",
30016
+ "hB"
30017
+ ],
30018
+ "MO": [
30019
+ "h",
30020
+ "hB",
30021
+ "hb",
30022
+ "H"
30023
+ ],
30024
+ "MP": [
30025
+ "h",
30026
+ "hb",
30027
+ "H",
30028
+ "hB"
30029
+ ],
30030
+ "MQ": ["H", "hB"],
30031
+ "MR": [
30032
+ "h",
30033
+ "hB",
30034
+ "hb",
30035
+ "H"
30036
+ ],
30037
+ "MS": [
30038
+ "H",
30039
+ "h",
30040
+ "hb",
30041
+ "hB"
30042
+ ],
30043
+ "MT": ["H", "h"],
30044
+ "MU": ["H", "h"],
30045
+ "MV": ["H", "h"],
30046
+ "MW": [
30047
+ "h",
30048
+ "hb",
30049
+ "H",
30050
+ "hB"
30051
+ ],
30052
+ "MX": [
30053
+ "h",
30054
+ "H",
30055
+ "hB",
30056
+ "hb"
30057
+ ],
30058
+ "MY": [
30059
+ "hb",
30060
+ "hB",
30061
+ "h",
30062
+ "H"
30063
+ ],
30064
+ "MZ": ["H", "hB"],
30065
+ "NA": [
30066
+ "h",
30067
+ "H",
30068
+ "hB",
30069
+ "hb"
30070
+ ],
30071
+ "NC": ["H", "hB"],
30072
+ "NE": ["H"],
30073
+ "NF": [
30074
+ "H",
30075
+ "h",
30076
+ "hb",
30077
+ "hB"
30078
+ ],
30079
+ "NG": [
30080
+ "H",
30081
+ "h",
30082
+ "hb",
30083
+ "hB"
30084
+ ],
30085
+ "NI": [
30086
+ "h",
30087
+ "H",
30088
+ "hB",
30089
+ "hb"
30090
+ ],
30091
+ "NL": ["H", "hB"],
30092
+ "NO": ["H", "h"],
30093
+ "NP": [
30094
+ "H",
30095
+ "h",
30096
+ "hB"
30097
+ ],
30098
+ "NR": [
30099
+ "H",
30100
+ "h",
30101
+ "hb",
30102
+ "hB"
30103
+ ],
30104
+ "NU": [
30105
+ "H",
30106
+ "h",
30107
+ "hb",
30108
+ "hB"
30109
+ ],
30110
+ "NZ": [
30111
+ "h",
30112
+ "hb",
30113
+ "H",
30114
+ "hB"
30115
+ ],
30116
+ "OM": [
30117
+ "h",
30118
+ "hB",
30119
+ "hb",
30120
+ "H"
30121
+ ],
30122
+ "PA": [
30123
+ "h",
30124
+ "H",
30125
+ "hB",
30126
+ "hb"
30127
+ ],
30128
+ "PE": [
30129
+ "h",
30130
+ "H",
30131
+ "hB",
30132
+ "hb"
30133
+ ],
30134
+ "PF": [
30135
+ "H",
30136
+ "h",
30137
+ "hB"
30138
+ ],
30139
+ "PG": ["h", "H"],
30140
+ "PH": [
30141
+ "h",
30142
+ "hB",
30143
+ "hb",
30144
+ "H"
30145
+ ],
30146
+ "PK": [
30147
+ "h",
30148
+ "hB",
30149
+ "H"
30150
+ ],
30151
+ "PL": ["H", "h"],
30152
+ "PM": ["H", "hB"],
30153
+ "PN": [
30154
+ "H",
30155
+ "h",
30156
+ "hb",
30157
+ "hB"
30158
+ ],
30159
+ "PR": [
30160
+ "h",
30161
+ "H",
30162
+ "hB",
30163
+ "hb"
30164
+ ],
30165
+ "PS": [
30166
+ "h",
30167
+ "hB",
30168
+ "hb",
30169
+ "H"
30170
+ ],
30171
+ "PT": ["H", "hB"],
30172
+ "PW": ["h", "H"],
30173
+ "PY": [
30174
+ "h",
30175
+ "H",
30176
+ "hB",
30177
+ "hb"
30178
+ ],
30179
+ "QA": [
30180
+ "h",
30181
+ "hB",
30182
+ "hb",
30183
+ "H"
30184
+ ],
30185
+ "RE": ["H", "hB"],
30186
+ "RO": ["H", "hB"],
30187
+ "RS": [
30188
+ "H",
30189
+ "hB",
30190
+ "h"
30191
+ ],
30192
+ "RU": ["H"],
30193
+ "RW": ["H", "h"],
30194
+ "SA": [
30195
+ "h",
30196
+ "hB",
30197
+ "hb",
30198
+ "H"
30199
+ ],
30200
+ "SB": [
30201
+ "h",
30202
+ "hb",
30203
+ "H",
30204
+ "hB"
30205
+ ],
30206
+ "SC": [
30207
+ "H",
30208
+ "h",
30209
+ "hB"
30210
+ ],
30211
+ "SD": [
30212
+ "h",
30213
+ "hB",
30214
+ "hb",
30215
+ "H"
30216
+ ],
30217
+ "SE": ["H"],
30218
+ "SG": [
30219
+ "h",
30220
+ "hb",
30221
+ "H",
30222
+ "hB"
30223
+ ],
30224
+ "SH": [
30225
+ "H",
30226
+ "h",
30227
+ "hb",
30228
+ "hB"
30229
+ ],
30230
+ "SI": ["H", "hB"],
30231
+ "SJ": ["H"],
30232
+ "SK": ["H"],
30233
+ "SL": [
30234
+ "h",
30235
+ "hb",
30236
+ "H",
30237
+ "hB"
30238
+ ],
30239
+ "SM": [
30240
+ "H",
30241
+ "h",
30242
+ "hB"
30243
+ ],
30244
+ "SN": [
30245
+ "H",
30246
+ "h",
30247
+ "hB"
30248
+ ],
30249
+ "SO": ["h", "H"],
30250
+ "SR": ["H", "hB"],
30251
+ "SS": [
30252
+ "h",
30253
+ "hb",
30254
+ "H",
30255
+ "hB"
30256
+ ],
30257
+ "ST": ["H", "hB"],
30258
+ "SV": [
30259
+ "h",
30260
+ "H",
30261
+ "hB",
30262
+ "hb"
30263
+ ],
30264
+ "SX": [
30265
+ "H",
30266
+ "h",
30267
+ "hb",
30268
+ "hB"
30269
+ ],
30270
+ "SY": [
30271
+ "h",
30272
+ "hB",
30273
+ "hb",
30274
+ "H"
30275
+ ],
30276
+ "SZ": [
30277
+ "h",
30278
+ "hb",
30279
+ "H",
30280
+ "hB"
30281
+ ],
30282
+ "TA": [
30283
+ "H",
30284
+ "h",
30285
+ "hb",
30286
+ "hB"
30287
+ ],
30288
+ "TC": [
30289
+ "h",
30290
+ "hb",
30291
+ "H",
30292
+ "hB"
30293
+ ],
30294
+ "TD": [
30295
+ "h",
30296
+ "H",
30297
+ "hB"
30298
+ ],
30299
+ "TF": [
30300
+ "H",
30301
+ "h",
30302
+ "hB"
30303
+ ],
30304
+ "TG": ["H", "hB"],
30305
+ "TH": ["H", "h"],
30306
+ "TJ": ["H", "h"],
30307
+ "TL": [
30308
+ "H",
30309
+ "hB",
30310
+ "hb",
30311
+ "h"
30312
+ ],
30313
+ "TM": ["H", "h"],
30314
+ "TN": [
30315
+ "h",
30316
+ "hB",
30317
+ "hb",
30318
+ "H"
30319
+ ],
30320
+ "TO": ["h", "H"],
30321
+ "TR": ["H", "hB"],
30322
+ "TT": [
30323
+ "h",
30324
+ "hb",
30325
+ "H",
30326
+ "hB"
30327
+ ],
30328
+ "TW": [
30329
+ "hB",
30330
+ "hb",
30331
+ "h",
30332
+ "H"
30333
+ ],
30334
+ "TZ": [
30335
+ "hB",
30336
+ "hb",
30337
+ "H",
30338
+ "h"
30339
+ ],
30340
+ "UA": [
30341
+ "H",
30342
+ "hB",
30343
+ "h"
30344
+ ],
30345
+ "UG": [
30346
+ "hB",
30347
+ "hb",
30348
+ "H",
30349
+ "h"
30350
+ ],
30351
+ "UM": [
30352
+ "h",
30353
+ "hb",
30354
+ "H",
30355
+ "hB"
30356
+ ],
30357
+ "US": [
30358
+ "h",
30359
+ "hb",
30360
+ "H",
30361
+ "hB"
30362
+ ],
30363
+ "UY": [
30364
+ "h",
30365
+ "H",
30366
+ "hB",
30367
+ "hb"
30368
+ ],
30369
+ "UZ": [
30370
+ "H",
30371
+ "hB",
30372
+ "h"
30373
+ ],
30374
+ "VA": [
30375
+ "H",
30376
+ "h",
30377
+ "hB"
30378
+ ],
30379
+ "VC": [
30380
+ "h",
30381
+ "hb",
30382
+ "H",
30383
+ "hB"
30384
+ ],
30385
+ "VE": [
30386
+ "h",
30387
+ "H",
30388
+ "hB",
30389
+ "hb"
30390
+ ],
30391
+ "VG": [
30392
+ "h",
30393
+ "hb",
30394
+ "H",
30395
+ "hB"
30396
+ ],
30397
+ "VI": [
30398
+ "h",
30399
+ "hb",
30400
+ "H",
30401
+ "hB"
30402
+ ],
30403
+ "VN": ["H", "h"],
30404
+ "VU": ["h", "H"],
30405
+ "WF": ["H", "hB"],
30406
+ "WS": ["h", "H"],
30407
+ "XK": [
30408
+ "H",
30409
+ "hB",
30410
+ "h"
30411
+ ],
30412
+ "YE": [
30413
+ "h",
30414
+ "hB",
30415
+ "hb",
30416
+ "H"
30417
+ ],
30418
+ "YT": ["H", "hB"],
30419
+ "ZA": [
30420
+ "H",
30421
+ "h",
30422
+ "hb",
30423
+ "hB"
30424
+ ],
30425
+ "ZM": [
30426
+ "h",
30427
+ "hb",
30428
+ "H",
30429
+ "hB"
30430
+ ],
30431
+ "ZW": ["H", "h"],
30432
+ "af-ZA": [
30433
+ "H",
30434
+ "h",
30435
+ "hB",
30436
+ "hb"
30437
+ ],
30438
+ "ar-001": [
30439
+ "h",
30440
+ "hB",
30441
+ "hb",
30442
+ "H"
30443
+ ],
30444
+ "ca-ES": [
30445
+ "H",
30446
+ "h",
30447
+ "hB"
30448
+ ],
30449
+ "en-001": [
30450
+ "h",
30451
+ "hb",
30452
+ "H",
30453
+ "hB"
30454
+ ],
30455
+ "en-HK": [
30456
+ "h",
30457
+ "hb",
30458
+ "H",
30459
+ "hB"
30460
+ ],
30461
+ "en-IL": [
30462
+ "H",
30463
+ "h",
30464
+ "hb",
30465
+ "hB"
30466
+ ],
30467
+ "en-MY": [
30468
+ "h",
30469
+ "hb",
30470
+ "H",
30471
+ "hB"
30472
+ ],
30473
+ "es-BR": [
30474
+ "H",
30475
+ "h",
30476
+ "hB",
30477
+ "hb"
30478
+ ],
30479
+ "es-ES": [
30480
+ "H",
30481
+ "h",
30482
+ "hB",
30483
+ "hb"
30484
+ ],
30485
+ "es-GQ": [
30486
+ "H",
30487
+ "h",
30488
+ "hB",
30489
+ "hb"
30490
+ ],
30491
+ "fr-CA": [
30492
+ "H",
30493
+ "h",
30494
+ "hB"
30495
+ ],
30496
+ "gl-ES": [
30497
+ "H",
30498
+ "h",
30499
+ "hB"
30500
+ ],
30501
+ "gu-IN": [
30502
+ "hB",
30503
+ "hb",
30504
+ "h",
30505
+ "H"
30506
+ ],
30507
+ "hi-IN": [
30508
+ "hB",
30509
+ "h",
30510
+ "H"
30511
+ ],
30512
+ "it-CH": [
30513
+ "H",
30514
+ "h",
30515
+ "hB"
30516
+ ],
30517
+ "it-IT": [
30518
+ "H",
30519
+ "h",
30520
+ "hB"
30521
+ ],
30522
+ "kn-IN": [
30523
+ "hB",
30524
+ "h",
30525
+ "H"
30526
+ ],
30527
+ "ku-SY": ["H", "hB"],
30528
+ "ml-IN": [
30529
+ "hB",
30530
+ "h",
30531
+ "H"
30532
+ ],
30533
+ "mr-IN": [
30534
+ "hB",
30535
+ "hb",
30536
+ "h",
30537
+ "H"
30538
+ ],
30539
+ "pa-IN": [
30540
+ "hB",
30541
+ "hb",
30542
+ "h",
30543
+ "H"
30544
+ ],
30545
+ "ta-IN": [
30546
+ "hB",
30547
+ "h",
30548
+ "hb",
30549
+ "H"
30550
+ ],
30551
+ "te-IN": [
30552
+ "hB",
30553
+ "h",
30554
+ "H"
30555
+ ],
30556
+ "zu-ZA": [
30557
+ "H",
30558
+ "hB",
30559
+ "hb",
30560
+ "h"
30561
+ ]
30562
+ };
30563
+ function getBestPattern(skeleton, locale) {
30564
+ let skeletonCopy = "";
30565
+ for (let patternPos = 0; patternPos < skeleton.length; patternPos++) {
30566
+ const patternChar = skeleton.charAt(patternPos);
30567
+ if (patternChar === "j") {
30568
+ let extraLength = 0;
30569
+ while (patternPos + 1 < skeleton.length && skeleton.charAt(patternPos + 1) === patternChar) {
30570
+ extraLength++;
30571
+ patternPos++;
30572
+ }
30573
+ let hourLen = 1 + (extraLength & 1);
30574
+ let dayPeriodLen = extraLength < 2 ? 1 : 3 + (extraLength >> 1);
30575
+ let dayPeriodChar = "a";
30576
+ let hourChar = getDefaultHourSymbolFromLocale(locale);
30577
+ if (hourChar == "H" || hourChar == "k") dayPeriodLen = 0;
30578
+ while (dayPeriodLen-- > 0) skeletonCopy += dayPeriodChar;
30579
+ while (hourLen-- > 0) skeletonCopy = hourChar + skeletonCopy;
30580
+ } else if (patternChar === "J") skeletonCopy += "H";
30581
+ else skeletonCopy += patternChar;
30582
+ }
30583
+ return skeletonCopy;
30584
+ }
30585
+ function getDefaultHourSymbolFromLocale(locale) {
30586
+ let hourCycle = locale.hourCycle;
30587
+ if (hourCycle === void 0) {
30588
+ const localeWithHourCycles = locale;
30589
+ hourCycle = localeWithHourCycles.getHourCycles?.()[0] ?? localeWithHourCycles.hourCycles?.[0];
30590
+ }
30591
+ if (hourCycle) switch (hourCycle) {
30592
+ case "h24":
30593
+ return "k";
30594
+ case "h23":
30595
+ return "H";
30596
+ case "h12":
30597
+ return "h";
30598
+ case "h11":
30599
+ return "K";
30600
+ default:
30601
+ throw new Error("Invalid hourCycle");
30602
+ }
30603
+ const languageTag = locale.language;
30604
+ let regionTag;
30605
+ if (languageTag !== "root") regionTag = locale.maximize().region;
30606
+ return (timeData[`${languageTag}-${regionTag}`] || timeData[regionTag || ""] || timeData[languageTag || ""] || timeData[`${languageTag}-001`] || timeData["001"])[0].charAt(0);
30607
+ }
30608
+ const SPACE_SEPARATOR_START_REGEX = new RegExp(`^${SPACE_SEPARATOR_REGEX.source}*`);
30609
+ const SPACE_SEPARATOR_END_REGEX = new RegExp(`${SPACE_SEPARATOR_REGEX.source}*$`);
30610
+ function createLocation(start, end) {
30611
+ return {
30612
+ start,
30613
+ end
30614
+ };
30615
+ }
30616
+ const hasNativeFromEntries = !!Object.fromEntries;
30617
+ const hasTrimStart = !!String.prototype.trimStart;
30618
+ const hasTrimEnd = !!String.prototype.trimEnd;
30619
+ const fromEntries = hasNativeFromEntries ? Object.fromEntries : function fromEntries2(entries) {
30620
+ const obj = {};
30621
+ for (const [k, v] of entries) obj[k] = v;
30622
+ return obj;
30623
+ };
30624
+ const trimStart = hasTrimStart ? function trimStart2(s) {
30625
+ return s.trimStart();
30626
+ } : function trimStart3(s) {
30627
+ return s.replace(SPACE_SEPARATOR_START_REGEX, "");
30628
+ };
30629
+ const trimEnd = hasTrimEnd ? function trimEnd2(s) {
30630
+ return s.trimEnd();
30631
+ } : function trimEnd3(s) {
30632
+ return s.replace(SPACE_SEPARATOR_END_REGEX, "");
30633
+ };
30634
+ let IDENTIFIER_PREFIX_RE = createIdentifierPrefixRegex();
30635
+ function createIdentifierPrefixRegex() {
30636
+ try {
30637
+ const regex = new RegExp("([^\\p{White_Space}\\p{Pattern_Syntax}]*)", "yu");
30638
+ if (regex.exec("a ")?.[1] === "a") return regex;
30639
+ } catch {
30640
+ }
30641
+ return IDENTIFIER_PREFIX_REGEX;
30642
+ }
30643
+ function matchIdentifierAtIndex(s, index) {
30644
+ IDENTIFIER_PREFIX_RE.lastIndex = index;
30645
+ return IDENTIFIER_PREFIX_RE.exec(s)[1] ?? "";
30646
+ }
30647
+ function plainTopLevelEndPosition(message) {
30648
+ if (message.length === 0) return null;
30649
+ let line = 1;
30650
+ let column = 1;
30651
+ for (let offset = 0; offset < message.length; ) {
30652
+ const code = message.charCodeAt(offset);
30653
+ switch (code) {
30654
+ case 35:
30655
+ case 39:
30656
+ case 60:
30657
+ case 123:
30658
+ case 125:
30659
+ return null;
30660
+ }
30661
+ if (code === 10) {
30662
+ line++;
30663
+ column = 1;
30664
+ offset++;
30665
+ } else {
30666
+ column++;
30667
+ if (code >= 55296 && code <= 56319 && offset + 1 < message.length) {
30668
+ const next = message.charCodeAt(offset + 1);
30669
+ offset += next >= 56320 && next <= 57343 ? 2 : 1;
30670
+ } else offset++;
30671
+ }
30672
+ }
30673
+ return {
30674
+ offset: message.length,
30675
+ line,
30676
+ column
30677
+ };
30678
+ }
30679
+ var Parser = class {
30680
+ constructor(message, options = {}) {
30681
+ this.message = message;
30682
+ this.position = {
30683
+ offset: 0,
30684
+ line: 1,
30685
+ column: 1
30686
+ };
30687
+ this.ignoreTag = !!options.ignoreTag;
30688
+ this.locale = options.locale;
30689
+ this.requiresOtherClause = !!options.requiresOtherClause;
30690
+ this.shouldParseSkeletons = !!options.shouldParseSkeletons;
30691
+ }
30692
+ parse() {
30693
+ if (this.offset() !== 0) throw Error("parser can only be used once");
30694
+ if (this.message.length > 0) {
30695
+ const firstCode = this.message.charCodeAt(0);
30696
+ if (firstCode !== 35 && firstCode !== 39 && firstCode !== 60 && firstCode !== 123 && firstCode !== 125) {
30697
+ const plainEndPosition = plainTopLevelEndPosition(this.message);
30698
+ if (plainEndPosition) {
30699
+ const start = this.clonePosition();
30700
+ this.position = plainEndPosition;
30701
+ return {
30702
+ val: [{
30703
+ type: 0,
30704
+ value: this.message,
30705
+ location: createLocation(start, this.clonePosition())
30706
+ }],
30707
+ err: null
30708
+ };
30709
+ }
30710
+ }
30711
+ }
30712
+ return this.parseMessage(0, "", false);
30713
+ }
30714
+ parseMessage(nestingLevel, parentArgType, expectingCloseTag) {
30715
+ let elements = [];
30716
+ while (!this.isEOF()) {
30717
+ const char = this.char();
30718
+ if (char === 123) {
30719
+ const result = this.parseArgument(nestingLevel, expectingCloseTag);
30720
+ if (result.err) return result;
30721
+ elements.push(result.val);
30722
+ } else if (char === 125 && nestingLevel > 0) break;
30723
+ else if (char === 35 && (parentArgType === "plural" || parentArgType === "selectordinal")) {
30724
+ const position = this.clonePosition();
30725
+ this.bump();
30726
+ elements.push({
30727
+ type: 7,
30728
+ location: createLocation(position, this.clonePosition())
30729
+ });
30730
+ } else if (char === 60 && !this.ignoreTag && this.peek() === 47) {
30731
+ if (expectingCloseTag) break;
30732
+ else return this.error(26, createLocation(this.clonePosition(), this.clonePosition()));
30733
+ } else if (char === 60 && !this.ignoreTag && _isAlpha(this.peek() || 0)) {
30734
+ const result = this.parseTag(nestingLevel, parentArgType);
30735
+ if (result.err) return result;
30736
+ elements.push(result.val);
30737
+ } else {
30738
+ const result = this.parseLiteral(nestingLevel, parentArgType);
30739
+ if (result.err) return result;
30740
+ elements.push(result.val);
30741
+ }
30742
+ }
30743
+ return {
30744
+ val: elements,
30745
+ err: null
30746
+ };
30747
+ }
30748
+ /**
30749
+ * A tag name must start with an ASCII lower/upper case letter. The grammar is based on the
30750
+ * [custom element name][] except that a dash is NOT always mandatory and uppercase letters
30751
+ * are accepted:
30752
+ *
30753
+ * ```
30754
+ * tag ::= "<" tagName (whitespace)* "/>" | "<" tagName (whitespace)* ">" message "</" tagName (whitespace)* ">"
30755
+ * tagName ::= [a-z] (PENChar)*
30756
+ * PENChar ::=
30757
+ * "-" | "." | [0-9] | "_" | [a-z] | [A-Z] | #xB7 | [#xC0-#xD6] | [#xD8-#xF6] | [#xF8-#x37D] |
30758
+ * [#x37F-#x1FFF] | [#x200C-#x200D] | [#x203F-#x2040] | [#x2070-#x218F] | [#x2C00-#x2FEF] |
30759
+ * [#x3001-#xD7FF] | [#xF900-#xFDCF] | [#xFDF0-#xFFFD] | [#x10000-#xEFFFF]
30760
+ * ```
30761
+ *
30762
+ * [custom element name]: https://html.spec.whatwg.org/multipage/custom-elements.html#valid-custom-element-name
30763
+ * NOTE: We're a bit more lax here since HTML technically does not allow uppercase HTML element but we do
30764
+ * since other tag-based engines like React allow it
30765
+ */
30766
+ parseTag(nestingLevel, parentArgType) {
30767
+ const startPosition = this.clonePosition();
30768
+ this.bump();
30769
+ const tagName = this.parseTagName();
30770
+ this.bumpSpace();
30771
+ if (this.bumpIf("/>")) return {
30772
+ val: {
30773
+ type: 0,
30774
+ value: `<${tagName}/>`,
30775
+ location: createLocation(startPosition, this.clonePosition())
30776
+ },
30777
+ err: null
30778
+ };
30779
+ else if (this.bumpIf(">")) {
30780
+ const childrenResult = this.parseMessage(nestingLevel + 1, parentArgType, true);
30781
+ if (childrenResult.err) return childrenResult;
30782
+ const children = childrenResult.val;
30783
+ const endTagStartPosition = this.clonePosition();
30784
+ if (this.bumpIf("</")) {
30785
+ if (this.isEOF() || !_isAlpha(this.char())) return this.error(23, createLocation(endTagStartPosition, this.clonePosition()));
30786
+ const closingTagNameStartPosition = this.clonePosition();
30787
+ if (tagName !== this.parseTagName()) return this.error(26, createLocation(closingTagNameStartPosition, this.clonePosition()));
30788
+ this.bumpSpace();
30789
+ if (!this.bumpIf(">")) return this.error(23, createLocation(endTagStartPosition, this.clonePosition()));
30790
+ return {
30791
+ val: {
30792
+ type: 8,
30793
+ value: tagName,
30794
+ children,
30795
+ location: createLocation(startPosition, this.clonePosition())
30796
+ },
30797
+ err: null
30798
+ };
30799
+ } else return this.error(27, createLocation(startPosition, this.clonePosition()));
30800
+ } else return this.error(23, createLocation(startPosition, this.clonePosition()));
30801
+ }
30802
+ /**
30803
+ * This method assumes that the caller has peeked ahead for the first tag character.
30804
+ */
30805
+ parseTagName() {
30806
+ const startOffset = this.offset();
30807
+ this.bump();
30808
+ while (!this.isEOF() && _isPotentialElementNameChar(this.char())) this.bump();
30809
+ return this.message.slice(startOffset, this.offset());
30810
+ }
30811
+ parseLiteral(nestingLevel, parentArgType) {
30812
+ const start = this.clonePosition();
30813
+ let value = "";
30814
+ while (true) {
30815
+ const parseQuoteResult = this.tryParseQuote(parentArgType);
30816
+ if (parseQuoteResult) {
30817
+ value += parseQuoteResult;
30818
+ continue;
30819
+ }
30820
+ const parseUnquotedResult = this.tryParseUnquoted(nestingLevel, parentArgType);
30821
+ if (parseUnquotedResult) {
30822
+ value += parseUnquotedResult;
30823
+ continue;
30824
+ }
30825
+ const parseLeftAngleResult = this.tryParseLeftAngleBracket();
30826
+ if (parseLeftAngleResult) {
30827
+ value += parseLeftAngleResult;
30828
+ continue;
30829
+ }
30830
+ break;
30831
+ }
30832
+ const location = createLocation(start, this.clonePosition());
30833
+ return {
30834
+ val: {
30835
+ type: 0,
30836
+ value,
30837
+ location
30838
+ },
30839
+ err: null
30840
+ };
30841
+ }
30842
+ tryParseLeftAngleBracket() {
30843
+ if (!this.isEOF() && this.char() === 60 && (this.ignoreTag || !_isAlphaOrSlash(this.peek() || 0))) {
30844
+ this.bump();
30845
+ return "<";
30846
+ }
30847
+ return null;
30848
+ }
30849
+ /**
30850
+ * Starting with ICU 4.8, an ASCII apostrophe only starts quoted text if it immediately precedes
30851
+ * a character that requires quoting (that is, "only where needed"), and works the same in
30852
+ * nested messages as on the top level of the pattern. The new behavior is otherwise compatible.
30853
+ */
30854
+ tryParseQuote(parentArgType) {
30855
+ if (this.isEOF() || this.char() !== 39) return null;
30856
+ switch (this.peek()) {
30857
+ case 39:
30858
+ this.bump();
30859
+ this.bump();
30860
+ return "'";
30861
+ case 123:
30862
+ case 60:
30863
+ case 62:
30864
+ case 125:
30865
+ break;
30866
+ case 35:
30867
+ if (parentArgType === "plural" || parentArgType === "selectordinal") break;
30868
+ return null;
30869
+ default:
30870
+ return null;
30871
+ }
30872
+ this.bump();
30873
+ const codePoints = [this.char()];
30874
+ this.bump();
30875
+ while (!this.isEOF()) {
30876
+ const ch = this.char();
30877
+ if (ch === 39) {
30878
+ if (this.peek() === 39) {
30879
+ codePoints.push(39);
30880
+ this.bump();
30881
+ } else {
30882
+ this.bump();
30883
+ break;
30884
+ }
30885
+ } else codePoints.push(ch);
30886
+ this.bump();
30887
+ }
30888
+ return String.fromCodePoint(...codePoints);
30889
+ }
30890
+ tryParseUnquoted(nestingLevel, parentArgType) {
30891
+ if (this.isEOF()) return null;
30892
+ const ch = this.char();
30893
+ if (ch === 60 || ch === 123 || ch === 35 && (parentArgType === "plural" || parentArgType === "selectordinal") || ch === 125 && nestingLevel > 0) return null;
30894
+ else {
30895
+ this.bump();
30896
+ return String.fromCodePoint(ch);
30897
+ }
30898
+ }
30899
+ parseArgument(nestingLevel, expectingCloseTag) {
30900
+ const openingBracePosition = this.clonePosition();
30901
+ this.bump();
30902
+ this.bumpSpace();
30903
+ if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
30904
+ if (this.char() === 125) {
30905
+ this.bump();
30906
+ return this.error(2, createLocation(openingBracePosition, this.clonePosition()));
30907
+ }
30908
+ let value = this.parseIdentifierIfPossible().value;
30909
+ if (!value) return this.error(3, createLocation(openingBracePosition, this.clonePosition()));
30910
+ this.bumpSpace();
30911
+ if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
30912
+ switch (this.char()) {
30913
+ case 125:
30914
+ this.bump();
30915
+ return {
30916
+ val: {
30917
+ type: 1,
30918
+ value,
30919
+ location: createLocation(openingBracePosition, this.clonePosition())
30920
+ },
30921
+ err: null
30922
+ };
30923
+ case 44:
30924
+ this.bump();
30925
+ this.bumpSpace();
30926
+ if (this.isEOF()) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
30927
+ return this.parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition);
30928
+ default:
30929
+ return this.error(3, createLocation(openingBracePosition, this.clonePosition()));
30930
+ }
30931
+ }
30932
+ /**
30933
+ * Advance the parser until the end of the identifier, if it is currently on
30934
+ * an identifier character. Return an empty string otherwise.
30935
+ */
30936
+ parseIdentifierIfPossible() {
30937
+ const startingPosition = this.clonePosition();
30938
+ const startOffset = this.offset();
30939
+ const value = matchIdentifierAtIndex(this.message, startOffset);
30940
+ const endOffset = startOffset + value.length;
30941
+ this.bumpTo(endOffset);
30942
+ return {
30943
+ value,
30944
+ location: createLocation(startingPosition, this.clonePosition())
30945
+ };
30946
+ }
30947
+ parseArgumentOptions(nestingLevel, expectingCloseTag, value, openingBracePosition) {
30948
+ let typeStartPosition = this.clonePosition();
30949
+ let argType = this.parseIdentifierIfPossible().value;
30950
+ let typeEndPosition = this.clonePosition();
30951
+ switch (argType) {
30952
+ case "":
30953
+ return this.error(4, createLocation(typeStartPosition, typeEndPosition));
30954
+ case "number":
30955
+ case "date":
30956
+ case "time": {
30957
+ this.bumpSpace();
30958
+ let styleAndLocation = null;
30959
+ if (this.bumpIf(",")) {
30960
+ this.bumpSpace();
30961
+ const styleStartPosition = this.clonePosition();
30962
+ const result = this.parseSimpleArgStyleIfPossible();
30963
+ if (result.err) return result;
30964
+ const style = trimEnd(result.val);
30965
+ if (style.length === 0) return this.error(6, createLocation(this.clonePosition(), this.clonePosition()));
30966
+ styleAndLocation = {
30967
+ style,
30968
+ styleLocation: createLocation(styleStartPosition, this.clonePosition())
30969
+ };
30970
+ }
30971
+ const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
30972
+ if (argCloseResult.err) return argCloseResult;
30973
+ const location = createLocation(openingBracePosition, this.clonePosition());
30974
+ if (styleAndLocation && styleAndLocation.style.startsWith("::")) {
30975
+ let skeleton = trimStart(styleAndLocation.style.slice(2));
30976
+ if (argType === "number") {
30977
+ const result = this.parseNumberSkeletonFromString(skeleton, styleAndLocation.styleLocation);
30978
+ if (result.err) return result;
30979
+ return {
30980
+ val: {
30981
+ type: 2,
30982
+ value,
30983
+ location,
30984
+ style: result.val
30985
+ },
30986
+ err: null
30987
+ };
30988
+ } else {
30989
+ if (skeleton.length === 0) return this.error(10, location);
30990
+ let dateTimePattern = skeleton;
30991
+ if (this.locale) dateTimePattern = getBestPattern(skeleton, this.locale);
30992
+ const style = {
30993
+ type: 1,
30994
+ pattern: dateTimePattern,
30995
+ location: styleAndLocation.styleLocation,
30996
+ parsedOptions: this.shouldParseSkeletons ? parseDateTimeSkeleton(dateTimePattern) : {}
30997
+ };
30998
+ return {
30999
+ val: {
31000
+ type: argType === "date" ? 3 : 4,
31001
+ value,
31002
+ location,
31003
+ style
31004
+ },
31005
+ err: null
31006
+ };
31007
+ }
31008
+ }
31009
+ return {
31010
+ val: {
31011
+ type: argType === "number" ? 2 : argType === "date" ? 3 : 4,
31012
+ value,
31013
+ location,
31014
+ style: styleAndLocation?.style ?? null
31015
+ },
31016
+ err: null
31017
+ };
31018
+ }
31019
+ case "plural":
31020
+ case "selectordinal":
31021
+ case "select": {
31022
+ const typeEndPosition2 = this.clonePosition();
31023
+ this.bumpSpace();
31024
+ if (!this.bumpIf(",")) return this.error(12, createLocation(typeEndPosition2, { ...typeEndPosition2 }));
31025
+ this.bumpSpace();
31026
+ let identifierAndLocation = this.parseIdentifierIfPossible();
31027
+ let pluralOffset = 0;
31028
+ if (argType !== "select" && identifierAndLocation.value === "offset") {
31029
+ if (!this.bumpIf(":")) return this.error(13, createLocation(this.clonePosition(), this.clonePosition()));
31030
+ this.bumpSpace();
31031
+ const result = this.tryParseDecimalInteger(13, 14);
31032
+ if (result.err) return result;
31033
+ this.bumpSpace();
31034
+ identifierAndLocation = this.parseIdentifierIfPossible();
31035
+ pluralOffset = result.val;
31036
+ }
31037
+ const optionsResult = this.tryParsePluralOrSelectOptions(nestingLevel, argType, expectingCloseTag, identifierAndLocation);
31038
+ if (optionsResult.err) return optionsResult;
31039
+ const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
31040
+ if (argCloseResult.err) return argCloseResult;
31041
+ const location = createLocation(openingBracePosition, this.clonePosition());
31042
+ if (argType === "select") return {
31043
+ val: {
31044
+ type: 5,
31045
+ value,
31046
+ options: fromEntries(optionsResult.val),
31047
+ location
31048
+ },
31049
+ err: null
31050
+ };
31051
+ else return {
31052
+ val: {
31053
+ type: 6,
31054
+ value,
31055
+ options: fromEntries(optionsResult.val),
31056
+ offset: pluralOffset,
31057
+ pluralType: argType === "plural" ? "cardinal" : "ordinal",
31058
+ location
31059
+ },
31060
+ err: null
31061
+ };
31062
+ }
31063
+ default:
31064
+ return this.error(5, createLocation(typeStartPosition, typeEndPosition));
31065
+ }
31066
+ }
31067
+ tryParseArgumentClose(openingBracePosition) {
31068
+ if (this.isEOF() || this.char() !== 125) return this.error(1, createLocation(openingBracePosition, this.clonePosition()));
31069
+ this.bump();
31070
+ return {
31071
+ val: true,
31072
+ err: null
31073
+ };
31074
+ }
31075
+ /**
31076
+ * See: https://github.com/unicode-org/icu/blob/af7ed1f6d2298013dc303628438ec4abe1f16479/icu4c/source/common/messagepattern.cpp#L659
31077
+ */
31078
+ parseSimpleArgStyleIfPossible() {
31079
+ let nestedBraces = 0;
31080
+ const startPosition = this.clonePosition();
31081
+ while (!this.isEOF()) switch (this.char()) {
31082
+ case 39: {
31083
+ this.bump();
31084
+ let apostrophePosition = this.clonePosition();
31085
+ if (!this.bumpUntil("'")) return this.error(11, createLocation(apostrophePosition, this.clonePosition()));
31086
+ this.bump();
31087
+ break;
31088
+ }
31089
+ case 123:
31090
+ nestedBraces += 1;
31091
+ this.bump();
31092
+ break;
31093
+ case 125:
31094
+ if (nestedBraces > 0) nestedBraces -= 1;
31095
+ else return {
31096
+ val: this.message.slice(startPosition.offset, this.offset()),
31097
+ err: null
31098
+ };
31099
+ break;
31100
+ default:
31101
+ this.bump();
31102
+ }
31103
+ return {
31104
+ val: this.message.slice(startPosition.offset, this.offset()),
31105
+ err: null
31106
+ };
31107
+ }
31108
+ parseNumberSkeletonFromString(skeleton, location) {
31109
+ let tokens = [];
31110
+ try {
31111
+ tokens = parseNumberSkeletonFromString(skeleton);
31112
+ } catch {
31113
+ return this.error(7, location);
31114
+ }
31115
+ return {
31116
+ val: {
31117
+ type: 0,
31118
+ tokens,
31119
+ location,
31120
+ parsedOptions: this.shouldParseSkeletons ? parseNumberSkeleton(tokens) : {}
31121
+ },
31122
+ err: null
31123
+ };
31124
+ }
31125
+ /**
31126
+ * @param nesting_level The current nesting level of messages.
31127
+ * This can be positive when parsing message fragment in select or plural argument options.
31128
+ * @param parent_arg_type The parent argument's type.
31129
+ * @param parsed_first_identifier If provided, this is the first identifier-like selector of
31130
+ * the argument. It is a by-product of a previous parsing attempt.
31131
+ * @param expecting_close_tag If true, this message is directly or indirectly nested inside
31132
+ * between a pair of opening and closing tags. The nested message will not parse beyond
31133
+ * the closing tag boundary.
31134
+ */
31135
+ tryParsePluralOrSelectOptions(nestingLevel, parentArgType, expectCloseTag, parsedFirstIdentifier) {
31136
+ let hasOtherClause = false;
31137
+ const options = [];
31138
+ const parsedSelectors = /* @__PURE__ */ new Set();
31139
+ let { value: selector, location: selectorLocation } = parsedFirstIdentifier;
31140
+ while (true) {
31141
+ if (selector.length === 0) {
31142
+ const startPosition = this.clonePosition();
31143
+ if (parentArgType !== "select" && this.bumpIf("=")) {
31144
+ const result = this.tryParseDecimalInteger(16, 19);
31145
+ if (result.err) return result;
31146
+ selectorLocation = createLocation(startPosition, this.clonePosition());
31147
+ selector = this.message.slice(startPosition.offset, this.offset());
31148
+ } else break;
31149
+ }
31150
+ if (parsedSelectors.has(selector)) return this.error(parentArgType === "select" ? 21 : 20, selectorLocation);
31151
+ if (selector === "other") hasOtherClause = true;
31152
+ this.bumpSpace();
31153
+ const openingBracePosition = this.clonePosition();
31154
+ if (!this.bumpIf("{")) return this.error(parentArgType === "select" ? 17 : 18, createLocation(this.clonePosition(), this.clonePosition()));
31155
+ const fragmentResult = this.parseMessage(nestingLevel + 1, parentArgType, expectCloseTag);
31156
+ if (fragmentResult.err) return fragmentResult;
31157
+ const argCloseResult = this.tryParseArgumentClose(openingBracePosition);
31158
+ if (argCloseResult.err) return argCloseResult;
31159
+ options.push([selector, {
31160
+ value: fragmentResult.val,
31161
+ location: createLocation(openingBracePosition, this.clonePosition())
31162
+ }]);
31163
+ parsedSelectors.add(selector);
31164
+ this.bumpSpace();
31165
+ ({ value: selector, location: selectorLocation } = this.parseIdentifierIfPossible());
31166
+ }
31167
+ if (options.length === 0) return this.error(parentArgType === "select" ? 15 : 16, createLocation(this.clonePosition(), this.clonePosition()));
31168
+ if (this.requiresOtherClause && !hasOtherClause) return this.error(22, createLocation(this.clonePosition(), this.clonePosition()));
31169
+ return {
31170
+ val: options,
31171
+ err: null
31172
+ };
31173
+ }
31174
+ tryParseDecimalInteger(expectNumberError, invalidNumberError) {
31175
+ let sign = 1;
31176
+ const startingPosition = this.clonePosition();
31177
+ if (this.bumpIf("+")) ;
31178
+ else if (this.bumpIf("-")) sign = -1;
31179
+ let hasDigits = false;
31180
+ let decimal = 0;
31181
+ while (!this.isEOF()) {
31182
+ const ch = this.char();
31183
+ if (ch >= 48 && ch <= 57) {
31184
+ hasDigits = true;
31185
+ decimal = decimal * 10 + (ch - 48);
31186
+ this.bump();
31187
+ } else break;
31188
+ }
31189
+ const location = createLocation(startingPosition, this.clonePosition());
31190
+ if (!hasDigits) return this.error(expectNumberError, location);
31191
+ decimal *= sign;
31192
+ if (!Number.isSafeInteger(decimal)) return this.error(invalidNumberError, location);
31193
+ return {
31194
+ val: decimal,
31195
+ err: null
31196
+ };
31197
+ }
31198
+ offset() {
31199
+ return this.position.offset;
31200
+ }
31201
+ isEOF() {
31202
+ return this.offset() === this.message.length;
31203
+ }
31204
+ clonePosition() {
31205
+ return {
31206
+ offset: this.position.offset,
31207
+ line: this.position.line,
31208
+ column: this.position.column
31209
+ };
31210
+ }
31211
+ /**
31212
+ * Return the code point at the current position of the parser.
31213
+ * Throws if the index is out of bound.
31214
+ */
31215
+ char() {
31216
+ const offset = this.position.offset;
31217
+ if (offset >= this.message.length) throw Error("out of bound");
31218
+ const code = this.message.codePointAt(offset);
31219
+ if (code === void 0) throw Error(`Offset ${offset} is at invalid UTF-16 code unit boundary`);
31220
+ return code;
31221
+ }
31222
+ error(kind, location) {
31223
+ return {
31224
+ val: null,
31225
+ err: {
31226
+ kind,
31227
+ message: this.message,
31228
+ location
31229
+ }
31230
+ };
31231
+ }
31232
+ /** Bump the parser to the next UTF-16 code unit. */
31233
+ bump() {
31234
+ if (this.isEOF()) return;
31235
+ const code = this.char();
31236
+ if (code === 10) {
31237
+ this.position.line += 1;
31238
+ this.position.column = 1;
31239
+ this.position.offset += 1;
31240
+ } else {
31241
+ this.position.column += 1;
31242
+ this.position.offset += code < 65536 ? 1 : 2;
31243
+ }
31244
+ }
31245
+ /**
31246
+ * If the substring starting at the current position of the parser has
31247
+ * the given prefix, then bump the parser to the character immediately
31248
+ * following the prefix and return true. Otherwise, don't bump the parser
31249
+ * and return false.
31250
+ */
31251
+ bumpIf(prefix) {
31252
+ const offset = this.offset();
31253
+ if (this.message.slice(offset, offset + prefix.length) === prefix) {
31254
+ for (let i = 0; i < prefix.length; i++) this.bump();
31255
+ return true;
31256
+ }
31257
+ return false;
31258
+ }
31259
+ /**
31260
+ * Bump the parser until the pattern character is found and return `true`.
31261
+ * Otherwise bump to the end of the file and return `false`.
31262
+ */
31263
+ bumpUntil(pattern) {
31264
+ const currentOffset = this.offset();
31265
+ const index = this.message.indexOf(pattern, currentOffset);
31266
+ if (index >= 0) {
31267
+ this.bumpTo(index);
31268
+ return true;
31269
+ } else {
31270
+ this.bumpTo(this.message.length);
31271
+ return false;
31272
+ }
31273
+ }
31274
+ /**
31275
+ * Bump the parser to the target offset.
31276
+ * If target offset is beyond the end of the input, bump the parser to the end of the input.
31277
+ */
31278
+ bumpTo(targetOffset) {
31279
+ if (this.offset() > targetOffset) throw Error(`targetOffset ${targetOffset} must be greater than or equal to the current offset ${this.offset()}`);
31280
+ targetOffset = Math.min(targetOffset, this.message.length);
31281
+ while (true) {
31282
+ const offset = this.offset();
31283
+ if (offset === targetOffset) break;
31284
+ if (offset > targetOffset) throw Error(`targetOffset ${targetOffset} is at invalid UTF-16 code unit boundary`);
31285
+ this.bump();
31286
+ if (this.isEOF()) break;
31287
+ }
31288
+ }
31289
+ /** advance the parser through all whitespace to the next non-whitespace code unit. */
31290
+ bumpSpace() {
31291
+ while (!this.isEOF() && _isWhiteSpace(this.char())) this.bump();
31292
+ }
31293
+ /**
31294
+ * Peek at the *next* Unicode codepoint in the input without advancing the parser.
31295
+ * If the input has been exhausted, then this returns null.
31296
+ */
31297
+ peek() {
31298
+ if (this.isEOF()) return null;
31299
+ const code = this.char();
31300
+ const offset = this.offset();
31301
+ return this.message.charCodeAt(offset + (code >= 65536 ? 2 : 1)) ?? null;
31302
+ }
31303
+ };
31304
+ function _isAlpha(codepoint) {
31305
+ return codepoint >= 97 && codepoint <= 122 || codepoint >= 65 && codepoint <= 90;
31306
+ }
31307
+ function _isAlphaOrSlash(codepoint) {
31308
+ return _isAlpha(codepoint) || codepoint === 47;
31309
+ }
31310
+ function _isPotentialElementNameChar(c) {
31311
+ return c === 45 || c === 46 || c >= 48 && c <= 57 || c === 95 || c >= 97 && c <= 122 || c >= 65 && c <= 90 || c == 183 || c >= 192 && c <= 214 || c >= 216 && c <= 246 || c >= 248 && c <= 893 || c >= 895 && c <= 8191 || c >= 8204 && c <= 8205 || c >= 8255 && c <= 8256 || c >= 8304 && c <= 8591 || c >= 11264 && c <= 12271 || c >= 12289 && c <= 55295 || c >= 63744 && c <= 64975 || c >= 65008 && c <= 65533 || c >= 65536 && c <= 983039;
31312
+ }
31313
+ function _isWhiteSpace(c) {
31314
+ return c >= 9 && c <= 13 || c === 32 || c === 133 || c >= 8206 && c <= 8207 || c === 8232 || c === 8233;
31315
+ }
31316
+ function pruneLocation(els) {
31317
+ els.forEach((el) => {
31318
+ delete el.location;
31319
+ if (isSelectElement(el) || isPluralElement(el)) for (const k in el.options) {
31320
+ delete el.options[k].location;
31321
+ pruneLocation(el.options[k].value);
31322
+ }
31323
+ else if (isNumberElement(el) && isNumberSkeleton(el.style)) delete el.style.location;
31324
+ else if ((isDateElement(el) || isTimeElement(el)) && isDateTimeSkeleton(el.style)) delete el.style.location;
31325
+ else if (isTagElement(el)) pruneLocation(el.children);
31326
+ });
31327
+ }
31328
+ function parse(message, opts = {}) {
31329
+ opts = {
31330
+ shouldParseSkeletons: true,
31331
+ requiresOtherClause: true,
31332
+ ...opts
31333
+ };
31334
+ const result = new Parser(message, opts).parse();
31335
+ if (result.err) {
31336
+ const error = SyntaxError(ErrorKind[result.err.kind]);
31337
+ error.location = result.err.location;
31338
+ error.originalMessage = result.err.message;
31339
+ throw error;
31340
+ }
31341
+ if (!opts?.captureLocation) pruneLocation(result.val);
31342
+ return result.val;
31343
+ }
31344
+ var FormatError = class extends Error {
31345
+ constructor(msg, code, originalMessage) {
31346
+ super(msg);
31347
+ this.code = code;
31348
+ this.originalMessage = originalMessage;
31349
+ }
31350
+ toString() {
31351
+ return `[formatjs Error: ${this.code}] ${this.message}`;
31352
+ }
31353
+ };
31354
+ var InvalidValueError = class extends FormatError {
31355
+ constructor(variableId, value, options, originalMessage) {
31356
+ super(`Invalid values for "${variableId}": "${value}". Options are "${Object.keys(options).join('", "')}"`, "INVALID_VALUE", originalMessage);
31357
+ }
31358
+ };
31359
+ var InvalidValueTypeError = class extends FormatError {
31360
+ constructor(value, type2, originalMessage) {
31361
+ super(`Value for "${value}" must be of type ${type2}`, "INVALID_VALUE", originalMessage);
31362
+ }
31363
+ };
31364
+ var MissingValueError = class extends FormatError {
31365
+ constructor(variableId, originalMessage) {
31366
+ super(`The intl string context variable "${variableId}" was not provided to the string "${originalMessage}"`, "MISSING_VALUE", originalMessage);
31367
+ }
31368
+ };
31369
+ function mergeLiteral(parts) {
31370
+ if (parts.length < 2) return parts;
31371
+ return parts.reduce((all, part) => {
31372
+ const lastPart = all[all.length - 1];
31373
+ if (!lastPart || lastPart.type !== 0 || part.type !== 0) all.push(part);
31374
+ else lastPart.value += part.value;
31375
+ return all;
31376
+ }, []);
31377
+ }
31378
+ function isFormatXMLElementFn(el) {
31379
+ return typeof el === "function";
31380
+ }
31381
+ function formatToParts(els, locales, formatters, formats2, values, currentPluralValue, originalMessage) {
31382
+ if (els.length === 1 && isLiteralElement(els[0])) return [{
31383
+ type: 0,
31384
+ value: els[0].value
31385
+ }];
31386
+ const result = [];
31387
+ for (const el of els) {
31388
+ if (isLiteralElement(el)) {
31389
+ result.push({
31390
+ type: 0,
31391
+ value: el.value
31392
+ });
31393
+ continue;
31394
+ }
31395
+ if (isPoundElement(el)) {
31396
+ if (typeof currentPluralValue === "number") result.push({
31397
+ type: 0,
31398
+ value: formatters.getNumberFormat(locales).format(currentPluralValue)
31399
+ });
31400
+ continue;
31401
+ }
31402
+ const { value: varName } = el;
31403
+ if (!(values && varName in values)) throw new MissingValueError(varName, originalMessage);
31404
+ let value = values[varName];
31405
+ if (isArgumentElement(el)) {
31406
+ if (!value || typeof value === "string" || typeof value === "number" || typeof value === "bigint") value = typeof value === "string" || typeof value === "number" || typeof value === "bigint" ? String(value) : "";
31407
+ result.push({
31408
+ type: typeof value === "string" ? 0 : 1,
31409
+ value
31410
+ });
31411
+ continue;
31412
+ }
31413
+ if (isDateElement(el)) {
31414
+ const style = typeof el.style === "string" ? formats2.date[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : void 0;
31415
+ result.push({
31416
+ type: 0,
31417
+ value: formatters.getDateTimeFormat(locales, style).format(value)
31418
+ });
31419
+ continue;
31420
+ }
31421
+ if (isTimeElement(el)) {
31422
+ const style = typeof el.style === "string" ? formats2.time[el.style] : isDateTimeSkeleton(el.style) ? el.style.parsedOptions : formats2.time.medium;
31423
+ result.push({
31424
+ type: 0,
31425
+ value: formatters.getDateTimeFormat(locales, style).format(value)
31426
+ });
31427
+ continue;
31428
+ }
31429
+ if (isNumberElement(el)) {
31430
+ const style = typeof el.style === "string" ? formats2.number[el.style] : isNumberSkeleton(el.style) ? el.style.parsedOptions : void 0;
31431
+ if (style && style.scale) {
31432
+ const scale = style.scale || 1;
31433
+ if (typeof value === "bigint") {
31434
+ if (!Number.isInteger(scale)) throw new TypeError(`Cannot apply fractional scale ${scale} to bigint value. Scale must be an integer when formatting bigint.`);
31435
+ value = value * BigInt(scale);
31436
+ } else value = value * scale;
31437
+ }
31438
+ result.push({
31439
+ type: 0,
31440
+ value: formatters.getNumberFormat(locales, style).format(value)
31441
+ });
31442
+ continue;
31443
+ }
31444
+ if (isTagElement(el)) {
31445
+ const { children, value: value2 } = el;
31446
+ const formatFn = values[value2];
31447
+ if (!isFormatXMLElementFn(formatFn)) throw new InvalidValueTypeError(value2, "function", originalMessage);
31448
+ let chunks = formatFn(formatToParts(children, locales, formatters, formats2, values, currentPluralValue).map((p) => p.value));
31449
+ if (!Array.isArray(chunks)) chunks = [chunks];
31450
+ result.push(...chunks.map((c) => {
31451
+ return {
31452
+ type: typeof c === "string" ? 0 : 1,
31453
+ value: c
31454
+ };
31455
+ }));
31456
+ }
31457
+ if (isSelectElement(el)) {
31458
+ const key = value;
31459
+ const opt = (Object.prototype.hasOwnProperty.call(el.options, key) ? el.options[key] : void 0) || el.options.other;
31460
+ if (!opt) throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);
31461
+ result.push(...formatToParts(opt.value, locales, formatters, formats2, values));
31462
+ continue;
31463
+ }
31464
+ if (isPluralElement(el)) {
31465
+ const exactKey = `=${value}`;
31466
+ let opt = Object.prototype.hasOwnProperty.call(el.options, exactKey) ? el.options[exactKey] : void 0;
31467
+ if (!opt) {
31468
+ if (!Intl.PluralRules) throw new FormatError(`Intl.PluralRules is not available in this environment.
31469
+ Try polyfilling it using "@formatjs/intl-pluralrules"
31470
+ `, "MISSING_INTL_API", originalMessage);
31471
+ const numericValue2 = typeof value === "bigint" ? Number(value) : value;
31472
+ const rule = formatters.getPluralRules(locales, { type: el.pluralType }).select(numericValue2 - (el.offset || 0));
31473
+ opt = (Object.prototype.hasOwnProperty.call(el.options, rule) ? el.options[rule] : void 0) || el.options.other;
31474
+ }
31475
+ if (!opt) throw new InvalidValueError(el.value, value, Object.keys(el.options), originalMessage);
31476
+ const numericValue = typeof value === "bigint" ? Number(value) : value;
31477
+ result.push(...formatToParts(opt.value, locales, formatters, formats2, values, numericValue - (el.offset || 0)));
31478
+ continue;
31479
+ }
31480
+ }
31481
+ return mergeLiteral(result);
31482
+ }
31483
+ function mergeConfig(c1, c2) {
31484
+ if (!c2) return c1;
31485
+ return {
31486
+ ...c1,
31487
+ ...c2,
31488
+ ...Object.keys(c1).reduce((all, k) => {
31489
+ all[k] = {
31490
+ ...c1[k],
31491
+ ...c2[k]
31492
+ };
31493
+ return all;
31494
+ }, {})
31495
+ };
31496
+ }
31497
+ function mergeConfigs(defaultConfig, configs) {
31498
+ if (!configs) return defaultConfig;
31499
+ return Object.keys(defaultConfig).reduce((all, k) => {
31500
+ all[k] = mergeConfig(defaultConfig[k], configs[k]);
31501
+ return all;
31502
+ }, { ...defaultConfig });
31503
+ }
31504
+ function createFastMemoizeCache(store) {
31505
+ return { create() {
31506
+ return {
31507
+ get(key) {
31508
+ return store[key];
31509
+ },
31510
+ set(key, value) {
31511
+ store[key] = value;
31512
+ }
31513
+ };
31514
+ } };
31515
+ }
31516
+ function createDefaultFormatters(cache = {
31517
+ number: {},
31518
+ dateTime: {},
31519
+ pluralRules: {}
31520
+ }) {
31521
+ return {
31522
+ getNumberFormat: memoize((...args) => new Intl.NumberFormat(...args), {
31523
+ cache: createFastMemoizeCache(cache.number),
31524
+ strategy: strategies.variadic
31525
+ }),
31526
+ getDateTimeFormat: memoize((...args) => new Intl.DateTimeFormat(...args), {
31527
+ cache: createFastMemoizeCache(cache.dateTime),
31528
+ strategy: strategies.variadic
31529
+ }),
31530
+ getPluralRules: memoize((...args) => new Intl.PluralRules(...args), {
31531
+ cache: createFastMemoizeCache(cache.pluralRules),
31532
+ strategy: strategies.variadic
31533
+ })
31534
+ };
31535
+ }
31536
+ var IntlMessageFormat = class IntlMessageFormat2 {
31537
+ constructor(message, locales = IntlMessageFormat2.defaultLocale, overrideFormats, opts) {
31538
+ this.formatterCache = {
31539
+ number: {},
31540
+ dateTime: {},
31541
+ pluralRules: {}
31542
+ };
31543
+ this.format = (values) => {
31544
+ const parts = this.formatToParts(values);
31545
+ if (parts.length === 1) return parts[0].value;
31546
+ const result = parts.reduce((all, part) => {
31547
+ if (!all.length || part.type !== 0 || typeof all[all.length - 1] !== "string") all.push(part.value);
31548
+ else all[all.length - 1] += part.value;
31549
+ return all;
31550
+ }, []);
31551
+ if (result.length <= 1) return result[0] || "";
31552
+ return result;
31553
+ };
31554
+ this.formatToParts = (values) => formatToParts(this.ast, this.locales, this.formatters, this.formats, values, void 0, this.message);
31555
+ this.resolvedOptions = () => ({ locale: this.resolvedLocale?.toString() || Intl.NumberFormat.supportedLocalesOf(this.locales)[0] });
31556
+ this.getAst = () => this.ast;
31557
+ this.locales = locales;
31558
+ this.resolvedLocale = IntlMessageFormat2.resolveLocale(locales);
31559
+ if (typeof message === "string") {
31560
+ this.message = message;
31561
+ if (!IntlMessageFormat2.__parse) throw new TypeError("IntlMessageFormat.__parse must be set to process `message` of type `string`");
31562
+ const { ...parseOpts } = opts || {};
31563
+ this.ast = IntlMessageFormat2.__parse(message, {
31564
+ ...parseOpts,
31565
+ locale: this.resolvedLocale
31566
+ });
31567
+ } else this.ast = message;
31568
+ if (!Array.isArray(this.ast)) throw new TypeError("A message must be provided as a String or AST.");
31569
+ this.formats = mergeConfigs(IntlMessageFormat2.formats, overrideFormats);
31570
+ this.formatters = opts && opts.formatters || createDefaultFormatters(this.formatterCache);
31571
+ }
31572
+ static {
31573
+ this.memoizedDefaultLocale = null;
31574
+ }
31575
+ static get defaultLocale() {
31576
+ if (!IntlMessageFormat2.memoizedDefaultLocale) IntlMessageFormat2.memoizedDefaultLocale = new Intl.NumberFormat().resolvedOptions().locale;
31577
+ return IntlMessageFormat2.memoizedDefaultLocale;
31578
+ }
31579
+ static {
31580
+ this.resolveLocale = (locales) => {
31581
+ if (typeof Intl.Locale === "undefined") return;
31582
+ const supportedLocales = Intl.NumberFormat.supportedLocalesOf(locales);
31583
+ if (supportedLocales.length > 0) return new Intl.Locale(supportedLocales[0]);
31584
+ return new Intl.Locale(typeof locales === "string" ? locales : locales[0]);
31585
+ };
31586
+ }
31587
+ static {
31588
+ this.__parse = parse;
31589
+ }
31590
+ static {
31591
+ this.formats = {
31592
+ number: {
31593
+ integer: { maximumFractionDigits: 0 },
31594
+ currency: { style: "currency" },
31595
+ percent: { style: "percent" }
31596
+ },
31597
+ date: {
31598
+ short: {
31599
+ month: "numeric",
31600
+ day: "numeric",
31601
+ year: "2-digit"
31602
+ },
31603
+ medium: {
31604
+ month: "short",
31605
+ day: "numeric",
31606
+ year: "numeric"
31607
+ },
31608
+ long: {
31609
+ month: "long",
31610
+ day: "numeric",
31611
+ year: "numeric"
31612
+ },
31613
+ full: {
31614
+ weekday: "long",
31615
+ month: "long",
31616
+ day: "numeric",
31617
+ year: "numeric"
31618
+ }
31619
+ },
31620
+ time: {
31621
+ short: {
31622
+ hour: "numeric",
31623
+ minute: "numeric"
31624
+ },
31625
+ medium: {
31626
+ hour: "numeric",
31627
+ minute: "numeric",
31628
+ second: "numeric"
31629
+ },
31630
+ long: {
31631
+ hour: "numeric",
31632
+ minute: "numeric",
31633
+ second: "numeric",
31634
+ timeZoneName: "short"
31635
+ },
31636
+ full: {
31637
+ hour: "numeric",
31638
+ minute: "numeric",
31639
+ second: "numeric",
31640
+ timeZoneName: "short"
31641
+ }
31642
+ }
31643
+ };
31644
+ }
31645
+ };
31646
+ const enUiAgents = {};
31647
+ const enUiBrowserChrome = {
31648
+ "ui.browser.chrome.approvals": "Approvals and site access",
31649
+ "ui.browser.chrome.error_title": "Page failed to load",
31650
+ "ui.browser.chrome.move_left": "Move tab left",
31651
+ "ui.browser.chrome.move_right": "Move tab right",
31652
+ "ui.browser.chrome.duplicate": "Duplicate tab",
31653
+ "ui.browser.chrome.reload": "Reload tab",
31654
+ "ui.browser.chrome.scroll_left": "Scroll tabs left",
31655
+ "ui.browser.chrome.scroll_right": "Scroll tabs right",
31656
+ "ui.browser.chrome.accessible_tab": "{title}{loading, select, yes{, loading} other{}}{failed, select, yes{, failed to load} other{}}{owner, select, agent{, agent-owned} shared{, shared with an agent} other{}}{waiting, select, none{} other{, request {waiting} waiting}}{restored, select, yes{, restored} other{}}",
31657
+ "ui.browser.chrome.invalid_order": "Invalid browser tab order.",
31658
+ "ui.browser.chrome.duplicate_refused": "Only web pages can be duplicated.",
31659
+ "ui.browser.chrome.invalid_action": "Invalid browser tab action.",
31660
+ "ui.browser.chrome.tab_gone": "That browser tab is no longer open.",
31661
+ "ui.browser.chrome.operation_failed": "{action, select, duplicate{The tab could not be duplicated. You can retry from its menu.} other{The tab could not be reloaded. You can retry from its menu.}}"
31662
+ };
31663
+ const enUiBrowser = {};
31664
+ const enUiCanvas = {
31665
+ "ui.canvas.files.highlights": "Highlights",
31666
+ "ui.canvas.files.working": "Working files",
31667
+ "ui.canvas.files.images": "Images",
31668
+ "ui.canvas.files.videos": "Videos",
31669
+ "ui.canvas.files.documents": "Documents",
31670
+ "ui.canvas.files.spreadsheets": "Spreadsheets",
31671
+ "ui.canvas.files.other": "Other",
31672
+ "ui.canvas.files.audio": "Audio",
31673
+ "ui.canvas.files.code": "Code",
31674
+ "ui.canvas.files.presentations": "Presentations",
31675
+ "ui.canvas.files.archives": "Archives",
31676
+ "ui.canvas.files.files": "Files",
31677
+ "ui.canvas.files.search": "Search files by name or folder",
31678
+ "ui.canvas.files.searchPlaceholder": "Search files",
31679
+ "ui.canvas.files.sort": "Sort by",
31680
+ "ui.canvas.files.order": "Order",
31681
+ "ui.canvas.files.group": "Group by kind",
31682
+ "ui.canvas.files.recent": "Mentioned",
31683
+ "ui.canvas.files.name": "Name",
31684
+ "ui.canvas.files.kind": "Kind",
31685
+ "ui.canvas.files.modified": "Modified",
31686
+ "ui.canvas.files.created": "Created",
31687
+ "ui.canvas.files.size": "Size",
31688
+ "ui.canvas.files.filter": "Filter",
31689
+ "ui.canvas.files.reset": "Reset filter",
31690
+ "ui.canvas.files.folder": "Open folder",
31691
+ "ui.canvas.files.loading": "Loading session files…",
31692
+ "ui.canvas.files.progress": "{loaded} of {total} loaded",
31693
+ "ui.canvas.files.building": "Building the file index…",
31694
+ "ui.canvas.files.retry": "Retry",
31695
+ "ui.canvas.files.continue": "Continue loading",
31696
+ "ui.canvas.files.empty": "No files yet",
31697
+ "ui.canvas.files.emptyDetail": "Files the agent creates or highlights appear here.",
31698
+ "ui.canvas.files.noMatch": "No files match this search and filter",
31699
+ "ui.canvas.files.clear": "Clear search and filter",
31700
+ "ui.canvas.files.sessionOnly": "In conversation only",
31701
+ "ui.canvas.files.missing": "No longer on disk",
31702
+ "ui.canvas.files.tooLarge": "Too large to preview",
31703
+ "ui.canvas.files.unreadable": "Could not be read",
31704
+ "ui.canvas.files.expand": "Expand image",
31705
+ "ui.canvas.files.play": "Open to play",
31706
+ "ui.canvas.files.asc": "Ascending",
31707
+ "ui.canvas.files.desc": "Descending",
31708
+ "ui.canvas.files.region": "Session files",
31709
+ "ui.canvas.files.readingStats": "Reading file details…",
31710
+ "ui.canvas.files.error": "Could not load session files",
31711
+ "ui.canvas.files.remote": "Remote files are unavailable here",
31712
+ "ui.canvas.files.inSession": "In session",
31713
+ "ui.canvas.files.count": "{count, plural, one {# file} other {# files}}",
31714
+ "ui.canvas.files.narrowCount": "{shown} of {total} files",
31715
+ "ui.canvas.files.gone": "No longer in the session",
31716
+ "ui.canvas.files.earlier": "Search earlier messages",
31717
+ "ui.canvas.files.imageActions": "Image actions",
31718
+ "ui.canvas.files.fileActions": "File actions",
31719
+ "ui.canvas.files.saveError": "Could not save the file",
31720
+ "ui.canvas.files.prepareError": "Could not prepare a local copy for this action",
31721
+ "ui.canvas.files.pathCopyNote": "Open, folder and path actions create a local copy in this conversation's scratchpad."
31722
+ };
31723
+ const enUiChat = {
31724
+ "ui.chat.usage.continue": "Included quota used; credits will continue.",
31725
+ "ui.chat.usage.family_caps": "Model-family caps still apply.",
31726
+ "ui.chat.usage.blocked": "Spend unavailable",
31727
+ "ui.chat.usage.eligibility_unknown": "Spend eligibility unknown",
31728
+ "ui.chat.usage.unlimited": "Unlimited paid allowance",
31729
+ "ui.chat.highlights.file_resolution_failed": "Couldn't resolve this file in the session working directory. Use Copy file path to check its location against this session's workspace before trying again."
31730
+ };
31731
+ const enUiConsole = {
31732
+ "ui.console.capacity.summary": "{live, number} live of {limit, number} in the app",
31733
+ "ui.console.capacity.summary_compact": "{live, number}/{limit, number} · {archived, number} kept",
31734
+ "ui.console.capacity.summary_compact_bare": "{live, number}/{limit, number}",
31735
+ "ui.console.capacity.archived": " · {archived, number} kept",
31736
+ "ui.console.capacity.full": " · full",
31737
+ "ui.console.capacity.help": "App-wide counts, across every conversation. Kept history does not use a process slot.",
31738
+ "ui.console.capacity.resources": "Modeled managed storage: {memory, number} MiB. Logs: {logs, number} MiB. Pending output: {pending, number} MiB. Terminal cells: {cells, number}. Protected terminals: {protected, number}. This excludes child-process memory.",
31739
+ "ui.console.cleanup.label": "Clear finished agent terminals",
31740
+ "ui.console.cleanup.help": "Clears finished agent terminals in this conversation. Finished ones the agent asked to keep stay on disk; the rest are closed and their output is not kept. Terminals you opened, and any in use, are left alone.",
31741
+ "ui.console.cleanup.result": "Cleared {released, plural, one {# finished agent terminal} other {# finished agent terminals}}. {protected, plural, =0 {} one {# is still in use and was left open.} other {# are still in use and were left open.}}",
31742
+ "ui.console.cleanup.result_none": "Nothing to clear — no finished agent terminals in this conversation.",
31743
+ "ui.console.dismiss_history": "Clear terminal and delete retained output",
31744
+ "ui.console.dismiss.body": "Clearing this terminal deletes its retained output from disk, so a relaunch cannot restore it.",
31745
+ "ui.console.dismiss.title": "Clear this terminal?",
31746
+ "ui.console.dismiss.confirm": "Clear terminal",
31747
+ "ui.console.close.body": "This ends the program running here and removes its tab.",
31748
+ "ui.console.close.busy": "Closing…",
31749
+ "ui.console.close.confirm": "Close terminal",
31750
+ "ui.console.close.kept": "Its output is kept.",
31751
+ "ui.console.close.title": "Close this terminal?",
31752
+ "ui.console.create_failed.detail": "The console host is running, and refused to start a program for this conversation — so this is one attempt failing rather than the console being switched off. Trying again is the first thing to do; if it keeps failing, the line below is the host's own reason.",
31753
+ "ui.console.create_failed.retry": "Try again",
31754
+ "ui.console.create_failed.title": "The console could not start in this session",
31755
+ "ui.console.empty.detail": "A console runs a program in this conversation's directory and keeps its output, whether or not this pane is open.",
31756
+ "ui.console.empty.title": "No console in this session",
31757
+ "ui.console.ended.exit_code": "exit code {code}",
31758
+ "ui.console.ended.exit_unknown": "exit code not observed",
31759
+ "ui.console.ended.live": "This terminal has ended",
31760
+ "ui.console.ended.restored": "This terminal has ended and its history was restored",
31761
+ "ui.console.loading.create": "Starting a console",
31762
+ "ui.console.loading.read": "Reading this session's console",
31763
+ "ui.console.new": "New console",
31764
+ "ui.console.pane.blip": "Finished since you last looked",
31765
+ "ui.console.pane.close": "Close console",
31766
+ "ui.console.pane.close_refusal": "The terminal could not be closed.",
31767
+ "ui.console.pane.label": "Console",
31768
+ "ui.console.pane.needs_conversation.detail": "A console runs in a conversation's working directory, so there is nowhere to put one yet.",
31769
+ "ui.console.pane.needs_conversation.title": "A console needs a conversation",
31770
+ "ui.console.pane.surfaces": "Console surfaces",
31771
+ "ui.console.secure": "Secure input is on: what you type here is not recorded.",
31772
+ "ui.console.unavailable.disabled.detail": "LOCAL_OPERATOR_UI_CONSOLE_HOST is set to 0 in this app's environment, so no terminal is started and no surface can be created. Removing that setting turns the console back on.",
31773
+ "ui.console.unavailable.disabled.title": "The console is switched off for this run",
31774
+ "ui.console.unavailable.pty.detail": "Terminal support did not load for this run. Updating Local Operator restores it, and the app's log names the reason.",
31775
+ "ui.console.unavailable.title": "The console is not available in this app",
31776
+ "ui.console.unavailable.unknown.detail": "This window could not reach the console, and did not say why. The app's log carries the reason.",
31777
+ "ui.console.tab.ended": "ended",
31778
+ "ui.console.tab.agent_opened": "An agent opened this console",
31779
+ "ui.console.tab.agent_typed": "An agent has typed into this console",
31780
+ "ui.console.tab.close_label": "Close {title}, tab {index, number} of {total, number}",
31781
+ "ui.console.tab.clear_label": "Clear {title}, tab {index, number} of {total, number}",
31782
+ "ui.console.tab.clear_label_retained": "Clear {title}, tab {index, number} of {total, number} — deletes retained output",
31783
+ "ui.console.secure_toggle.stop": "Stop secure input",
31784
+ "ui.console.secure_toggle.start": "Secure input",
31785
+ "ui.console.secure_toggle.start_tooltip": "Secure input: stop recording this terminal",
31786
+ "ui.console.close.cancel": "Cancel",
31787
+ "ui.console.terminal.prompt_label": "Terminal input",
31788
+ "ui.console.terminal.too_much_output": "Too much output to announce, navigate to rows manually to read"
31789
+ };
31790
+ const enUiHub = {
31791
+ "ui.hub.links.title": "Hub links",
31792
+ "ui.hub.links.loading": "Loading hub links…",
31793
+ "ui.hub.links.empty": "Not linked to the hub.",
31794
+ "ui.hub.links.load_failed": "Hub links could not be loaded. Retry.",
31795
+ "ui.hub.links.retry": "Retry",
31796
+ "ui.hub.links.source_public": "Public",
31797
+ "ui.hub.links.source_private": "{organization} · Private",
31798
+ "ui.hub.links.source_unavailable": "Source unavailable",
31799
+ "ui.hub.links.source_address": "Hub source: {address}",
31800
+ "ui.hub.subscriptions.subscribe": "Subscribe",
31801
+ "ui.hub.subscriptions.subscribe_description": "Receive updates from {source}. Manual pull stays available.",
31802
+ "ui.hub.subscriptions.auto_push": "Auto-push",
31803
+ "ui.hub.subscriptions.auto_push_description": "Publish local changes to {source} automatically when safe.",
31804
+ "ui.hub.subscriptions.configured_on": "On",
31805
+ "ui.hub.subscriptions.configured_off": "Off",
31806
+ "ui.hub.subscriptions.effective_paused": "Paused — {reason}",
31807
+ "ui.hub.subscriptions.effective_ready": "Ready when there are safe changes.",
31808
+ "ui.hub.subscriptions.saving": "Saving {setting} for {source}…",
31809
+ "ui.hub.subscriptions.save_failed": "Couldn’t save {setting} for {source}. Try again.",
31810
+ "ui.hub.subscriptions.policy_changed": "This policy changed elsewhere. Review the latest values before trying again.",
31811
+ "ui.hub.subscriptions.check": "Check now",
31812
+ "ui.hub.subscriptions.pull": "Pull now",
31813
+ "ui.hub.subscriptions.preview_publish": "Preview publish",
31814
+ "ui.hub.subscriptions.enable_title": "Enable auto-push to {source}?",
31815
+ "ui.hub.subscriptions.enable_public": "Future changes to {item} may be published publicly without asking each time. Changes from private sources are paused for review. Turning auto-push off later stops future publishing, but it does not take back anything that is already public.",
31816
+ "ui.hub.subscriptions.enable_private": "Future changes to {item} may be published to {organization} without asking each time. Only people allowed to access that organization can receive them.",
31817
+ "ui.hub.subscriptions.enable_safety": "Concurrent changes on the hub are merged or paused for review, never overwritten silently.",
31818
+ "ui.hub.subscriptions.cancel": "Cancel",
31819
+ "ui.hub.subscriptions.enable": "Enable auto-push",
31820
+ "ui.hub.subscriptions.unsupported": "The destination has not verified safe automatic publication.",
31821
+ "ui.hub.subscriptions.manual_available": "Incoming updates are off. Manual check and pull remain available.",
31822
+ "ui.hub.subscriptions.subscribe_description_blocked": "Receive updates from {source}.",
31823
+ "ui.hub.subscriptions.incoming_paused": "Incoming updates paused.",
31824
+ "ui.hub.subscriptions.outgoing_paused": "Outgoing changes may still be published to {source}.",
31825
+ "ui.hub.links.last_success": "Last successful action: {time}",
31826
+ "ui.hub.links.actual_model": "Model used: {model}",
31827
+ "ui.hub.links.healthy": "{item} from {source}; Subscribe {subscribe}; Auto-push {autoPush}. Open link policies.",
31828
+ "ui.hub.links.available": "Update {item} from {source}",
31829
+ "ui.hub.links.failed": "Retry {direction} for {item} at {source}",
31830
+ "ui.hub.links.busy": "{direction} in progress for {item} at {source}",
31831
+ "ui.hub.links.updated": "Updated {item} from {source}",
31832
+ "ui.hub.links.published": "Published {item} to {source}",
31833
+ "ui.hub.subscriptions.policy_menu": "Link policies for {item} at {source}",
31834
+ "ui.hub.subscriptions.copy_needed": "Separate copy needed for subscription.",
31835
+ "ui.hub.subscriptions.open_copy": "Open copy",
31836
+ "ui.hub.subscriptions.create_copy": "Create linked copy",
31837
+ "ui.hub.subscriptions.alias": "Local alias",
31838
+ "ui.hub.subscriptions.source_separation": "This copy is linked to {currentSource}. Updates from {newSource} will use a separate local copy.",
31839
+ "ui.hub.skills.title": "Skills",
31840
+ "ui.hub.skills.empty": "No skills installed.",
31841
+ "ui.hub.skills.search_empty": "No skills match this search.",
31842
+ "ui.hub.skills.loading": "Loading skills…",
31843
+ "ui.hub.skills.unavailable": "This server does not support the hub skills catalogue.",
31844
+ "ui.hub.links.confirm_publish": "Publish reviewed changes",
31845
+ "ui.hub.links.preview_changed": "The hub, this copy, or its policy changed. Review a new preview before publishing.",
31846
+ "ui.hub.links.preview_expired": "This preview expired. Review a new preview before publishing.",
31847
+ "ui.hub.links.preview_payload": "Reviewed publication to {source}",
31848
+ "ui.hub.links.direction_pull": "Incoming update",
31849
+ "ui.hub.links.direction_push": "Outgoing publication",
31850
+ "ui.hub.links.action_failed": "The {direction} for {item} at {source} did not complete. Review its status before trying again.",
31851
+ "ui.hub.links.preview_warnings": "Review notes",
31852
+ "ui.hub.links.action_result": "{direction} for {item} at {source}: {outcome}",
31853
+ "ui.hub.links.preview_pull": "Preview incoming changes",
31854
+ "ui.hub.links.prefer_local": "Keep mine",
31855
+ "ui.hub.links.prefer_remote": "Use the hub’s",
31856
+ "ui.hub.links.unknown_baseline": "This copy has no verified common baseline. Review both versions before applying changes.",
31857
+ "ui.hub.links.acknowledge_baseline": "I reviewed both versions and understand that the previous baseline is unknown.",
31858
+ "ui.hub.skills.remote_empty": "No skills have been published here yet.",
31859
+ "ui.hub.skills.scope": "Skills from {source}",
31860
+ "ui.hub.skills.pull_title": "Pull {item} from {source}",
31861
+ "ui.hub.skills.pull_help": "Create a separate local copy with its own source and policy. Existing copies are not overwritten.",
31862
+ "ui.hub.skills.pull_failed": "The pull was not confirmed. Check linked items before trying again.",
31863
+ "ui.hub.skills.policy_pending": "Publication succeeded, but this machine has not confirmed the link policies. Reconcile this publication before another write.",
31864
+ "ui.hub.skills.publish_title": "Publish a skill",
31865
+ "ui.hub.skills.select_authored": "Authored skill",
31866
+ "ui.hub.skills.revision": "Remote revision: {revision}",
31867
+ "ui.hub.skills.file_count": "{count, plural, one {# file included} other {# files included}}",
31868
+ "ui.hub.skills.files": "Files included",
31869
+ "ui.hub.skills.text_limits": "Skills support up to 64 UTF-8 text files, 200 KiB per file and 1 MiB in total. Scripts are never run when publishing or pulling.",
31870
+ "ui.hub.skills.local_exists": "That local alias is already used. Choose another.",
31871
+ "ui.hub.skills.initial_policy_description": "New links subscribe to incoming updates. Auto-push stays off until enabled for this destination.",
31872
+ "ui.hub.status.not_checked": "Not checked yet.",
31873
+ "ui.hub.status.idle": "No changes waiting.",
31874
+ "ui.hub.status.checking": "Checking for changes…",
31875
+ "ui.hub.status.available": "Changes are available.",
31876
+ "ui.hub.status.merging": "Merging changes…",
31877
+ "ui.hub.status.applying": "Applying incoming changes…",
31878
+ "ui.hub.status.pushing": "Publishing outgoing changes…",
31879
+ "ui.hub.status.retry_wait": "A retry is scheduled.",
31880
+ "ui.hub.status.needs_review": "Review is needed before changes can be applied.",
31881
+ "ui.hub.status.failed": "The last action did not complete.",
31882
+ "ui.hub.status.missing": "The source is missing or access is no longer available.",
31883
+ "ui.hub.status.unknown": "Status unavailable.",
31884
+ "ui.hub.status.next_retry": "Next retry: {time}",
31885
+ "ui.hub.status.last_checked": "Last checked: {time}",
31886
+ "ui.hub.status.attempts": "{count, plural, one {# attempt} other {# attempts}}",
31887
+ "ui.hub.status.receipt": "Operation receipt: {operation}",
31888
+ "ui.hub.status.core_update_required": "Update the Local Operator backend to a published release {minimum} or newer to change Hub settings. Browsing is still available.",
31889
+ "ui.hub.status.backend_checking": "Checking the Local Operator backend before allowing Hub changes. Browsing is still available.",
31890
+ "ui.hub.status.backend_disconnected": "Reconnect the Local Operator backend to change Hub settings. Backend {minimum} or newer is required; browsing is still available.",
31891
+ "ui.hub.status.unsupported": "This destination has not verified revision-safe publication.",
31892
+ "ui.hub.status.baseline_unknown": "The common baseline could not be verified. Review both versions first.",
31893
+ "ui.hub.status.mixed_lineage": "This copy includes changes from another source. Automatic publication is paused.",
31894
+ "ui.hub.status.no_credential": "Sign in to the hub before trying this action.",
31895
+ "ui.hub.status.access_lost": "Access to this private source is no longer available.",
31896
+ "ui.hub.status.provider_error": "The current default model could not be reached. A retry can use the latest state.",
31897
+ "ui.hub.status.model_unavailable": "The current default model is unavailable. Check its configuration.",
31898
+ "ui.hub.status.conflict": "Concurrent changes need review. Your copy has not been replaced.",
31899
+ "ui.hub.status.too_large": "These changes exceed the safe processing limit. Your copy has been preserved.",
31900
+ "ui.hub.status.skill_validation": "The skill does not meet the required file and metadata rules.",
31901
+ "ui.hub.status.unsafe_publication": "This destination cannot safely receive the current content. Review the destination-specific copy.",
31902
+ "ui.hub.status.other_error": "This action is paused.",
31903
+ "ui.hub.skills.search": "Search skills",
31904
+ "ui.hub.skills.search_loaded": "Search covers this loaded page.",
31905
+ "ui.hub.skills.open_detail": "View {item}",
31906
+ "ui.hub.skills.catalogue_failed": "Skills from {source} could not be loaded. Retry.",
31907
+ "ui.hub.skills.installed_alias": "Pulled {item} from {source}",
31908
+ "ui.hub.skills.session_selection": "Skill files are available on their next read. Newly selected skill descriptions are included in the next session.",
31909
+ "ui.hub.links.publication_pending": "The publication outcome is not yet confirmed. Retry this same operation to reconcile it.",
31910
+ "ui.hub.links.resolve_title": "Confirm this link’s source",
31911
+ "ui.hub.links.resolve_description": "Only confirm if you know {item} came from here.",
31912
+ "ui.hub.links.resolve_action": "Confirm source",
31913
+ "ui.hub.links.resolve_conflict": "That source conflicts with the stored origin. Nothing was changed.",
31914
+ "ui.hub.links.scope_label": "Publish scope",
31915
+ "ui.hub.links.scope_public": "Public",
31916
+ "ui.hub.links.scope_private": "{organization} · Private",
31917
+ "ui.hub.links.sign_in_to_publish": "Sign in to choose a publish scope",
31918
+ "ui.hub.links.resolve_action_confirm": "Confirm this source",
31919
+ "ui.hub.links.resolve_action_confirming": "Confirming…",
31920
+ "ui.hub.links.resolve_action_done": "Source confirmed",
31921
+ "ui.hub.links.resolve_failed_generic": "The source could not be confirmed.",
31922
+ "ui.hub.links.source_not_confirmed": "Source not confirmed",
31923
+ "ui.hub.links.resolve_irreversible": "Confirmation is permanent. A wrong source cannot be changed later; it needs a separate local copy.",
31924
+ "ui.hub.conflict.title": "This changed while you were editing",
31925
+ "ui.hub.conflict.body": "Something else — a configuration run, or another window — wrote to this team after you opened it. Your edits are kept; saving would only ever write the fields you changed, and only from the version you saw. Reload to start from the current one.",
31926
+ "ui.hub.conflict.reload": "Reload the saved version",
31927
+ "ui.hub.status.transport_error": "Couldn't reach the hub. A retry is scheduled.",
31928
+ "ui.hub.links.scope_placeholder": "Choose a scope…",
31929
+ "ui.hub.links.scope_required": "Choose a scope to continue",
31930
+ "ui.hub.links.sources_count": "{count, plural, one {# source} other {# sources}}",
31931
+ "ui.hub.links.links_count": "{count, plural, one {# link} other {# links}}",
31932
+ "ui.hub.links.unresolved_mark": "{item}: source not confirmed. Confirm the source.",
31933
+ "ui.hub.links.mixed": "Mixed",
31934
+ "ui.hub.links.aggregate_mark": "{count, plural, one {# link} other {# links}}; {state}",
31935
+ "ui.hub.links.mark_healthy": "up to date",
31936
+ "ui.hub.links.mark_review": "needs review",
31937
+ "ui.hub.links.mark_failed": "failed",
31938
+ "ui.hub.links.mark_available": "update available",
31939
+ "ui.hub.links.mark_busy": "working",
31940
+ "ui.hub.links.mark_applied": "applied"
31941
+ };
31942
+ const enUiMesh = {};
31943
+ const enUiOnboarding = {
31944
+ "ui.onboarding.connect.intro": "Local Operator needs an AI account to work. Radient is the easiest: one browser sign-in and nothing to paste. Already pay for ChatGPT or Claude? Sign in with that instead. Anything else is under More providers.",
31945
+ "ui.onboarding.default_model.block.loading_models": "Loading the model list…",
31946
+ "ui.onboarding.default_model.block.pick_a_model": "Pick a model to continue.",
31947
+ "ui.onboarding.default_model.change": "Change",
31948
+ "ui.onboarding.default_model.connected_pick": "{brand} is connected. Pick the model new chats should use.",
31949
+ "ui.onboarding.default_model.empty_helper": "No providers are connected yet. Go back a step to connect one.",
31950
+ "ui.onboarding.default_model.fallback_name": "{brand}'s default model",
31951
+ "ui.onboarding.default_model.intro": "New chats use this model. Every agent can pick a different one later.",
31952
+ "ui.onboarding.default_model.loading": "Loading your models",
31953
+ "ui.onboarding.default_model.none_connected": "No provider is connected yet. Go back to connect one, or skip setup and connect one later from the chat.",
31954
+ "ui.onboarding.default_model.nothing_saved": "Nothing will be saved: your Local Operator can't list {brand} models yet, so setup finishes without a default model. Pick one in Settings before your first message.",
31955
+ "ui.onboarding.default_model.provider_fallback": "this provider's",
31956
+ "ui.onboarding.default_model.tag.applied": "your default",
31957
+ "ui.onboarding.default_model.tag.suggested": "suggested for your account",
31958
+ "ui.onboarding.dialog.setup": "Setup",
31959
+ "ui.onboarding.extras.greeting_done": "{name} is your chief of staff. Her conversation is where you pick up with her, and it is one keystroke away in the sidebar. You can also skip straight to a new chat.",
31960
+ "ui.onboarding.extras.greeting_owed": "{name} is your chief of staff. She will say hello first, ask what to call you and what you would like help with, and show you around. You can also skip straight to a new chat.",
31961
+ "ui.onboarding.extras.next_meet": "Next: meet {name}",
31962
+ "ui.onboarding.modal.action.back": "Back",
31963
+ "ui.onboarding.modal.action.continue": "Continue",
31964
+ "ui.onboarding.modal.action.finish": "Finish",
31965
+ "ui.onboarding.modal.action.meet": "Meet {name}",
31966
+ "ui.onboarding.modal.action.skip": "Skip",
31967
+ "ui.onboarding.modal.action.skip_for_now": "Skip for now",
31968
+ "ui.onboarding.modal.action.skip_to_chat": "Skip to chat",
31969
+ "ui.onboarding.modal.error.aida_open_failed": "{name}'s conversation could not be opened, so you are in a new chat instead.",
31970
+ "ui.onboarding.modal.title.connect_provider": "Connect an AI account",
31971
+ "ui.onboarding.modal.title.default_model": "Your default model",
31972
+ "ui.onboarding.modal.title.extras": "Web search (optional)",
31973
+ "ui.onboarding.modal.title.extras_with_name": "Web search, then meet {name}",
31974
+ "ui.onboarding.modal.title.fallback": "First-time setup",
31975
+ "ui.onboarding.search.each_key_saved": "Each key is saved on your device as soon as you leave its field.",
31976
+ "ui.onboarding.search.intro": "Agents can look things up while they work — today's prices, this week's news — instead of relying on what the model already knows.",
31977
+ "ui.onboarding.search.mode.free": "Free",
31978
+ "ui.onboarding.search.mode.free_detail": "Uses a rotating pool of free providers — DuckDuckGo, Tavily's free tier, Exa and Parallel. No key needed; the pool is shared, so searches can be slower at busy times.",
31979
+ "ui.onboarding.search.mode.keys": "Add API keys",
31980
+ "ui.onboarding.search.mode.keys_detail": "Bring your own keys for the search providers you use.",
31981
+ "ui.onboarding.search.mode.label": "Search setup",
31982
+ "ui.onboarding.search.recommended": "Recommended",
31983
+ "ui.onboarding.search.row.get_your": "Get your {name}",
31984
+ "ui.onboarding.search.row.not_saved": "Not saved — {message}",
31985
+ "ui.onboarding.search.row.placeholder": "Paste your API key",
31986
+ "ui.onboarding.search.row.save_failed": "The key could not be saved.",
31987
+ "ui.onboarding.search.row.saved": "Saved",
31988
+ "ui.onboarding.search.row.saving": "Saving {name}",
31989
+ "ui.onboarding.modal.step_of": "Step {current, number} of {total, number}",
31990
+ "ui.onboarding.modal.steps_total": "{total, plural, one {# step} other {# steps}}"
31991
+ };
31992
+ const enUiProjects = {};
31993
+ const enUiProviders = {
31994
+ "ui.providers.phone.account": "Account: {identity}, credential {id}",
31995
+ "ui.providers.phone.account_unlabeled": "Account: credential {id}",
31996
+ "ui.providers.phone.action.activate": "Activate for USD {amount} a month",
31997
+ "ui.providers.phone.action.cancel": "Cancel",
31998
+ "ui.providers.phone.action.check_again": "Check again",
31999
+ "ui.providers.phone.action.choose": "{identity}, credential {id}",
32000
+ "ui.providers.phone.action.choose_unlabeled": "Credential {id}",
32001
+ "ui.providers.phone.action.copy_address": "Copy address",
32002
+ "ui.providers.phone.action.set_up": "Set up phone access",
32003
+ "ui.providers.phone.action.sign_in": "Continue in browser",
32004
+ "ui.providers.phone.address_label": "Phone address",
32005
+ "ui.providers.phone.choose_heading": "Choose an account",
32006
+ "ui.providers.phone.consent": "Activating sets up this Radient account’s tunnel subscription at USD {amount} a month, reserves your phone address and starts the background connector. It does not purchase credit.",
32007
+ "ui.providers.phone.failure.check": "Phone access could not be checked, and nothing was changed.",
32008
+ "ui.providers.phone.failure.run": "Phone access setup could not finish. Steps already completed are not undone. Check again before retrying.",
32009
+ "ui.providers.phone.heading": "Phone access",
32010
+ "ui.providers.phone.outcome.billing_activated_status": "Billing: subscription activation completed; this has not been undone.",
32011
+ "ui.providers.phone.outcome.billing_already_active": "Billing: the subscription was already active.",
32012
+ "ui.providers.phone.outcome.billing_not_activated": "Billing: the current subscription still needs activation.",
32013
+ "ui.providers.phone.outcome.billing_unconfirmed": "Billing: activation was requested but its outcome is unconfirmed. Check the account before retrying; do not assume rollback.",
32014
+ "ui.providers.phone.outcome.failure_stage": "Did not finish: {stage}.",
32015
+ "ui.providers.phone.outcome.reservation_existing": "Phone address: existing reservation retained.",
32016
+ "ui.providers.phone.outcome.reservation_saved": "Phone address: reservation saved on this computer; retry reuses it.",
32017
+ "ui.providers.phone.outcome.reservation_unconfirmed": "Phone address: reservation outcome unconfirmed; retry uses the saved request key.",
32018
+ "ui.providers.phone.outcome.stage_billing": "subscription activation",
32019
+ "ui.providers.phone.outcome.stage_configuration": "existing-route configuration",
32020
+ "ui.providers.phone.outcome.stage_installation": "background connector installation",
32021
+ "ui.providers.phone.outcome.stage_prerequisites": "prerequisite checks",
32022
+ "ui.providers.phone.outcome.stage_reservation": "phone-address reservation",
32023
+ "ui.providers.phone.outcome.stage_verification": "connection verification",
32024
+ "ui.providers.phone.progress_heading": "Setup progress",
32025
+ "ui.providers.phone.receipts_heading": "Completed so far",
32026
+ "ui.providers.phone.signing_in": "Finish signing in in your browser. This updates on its own when you are done.",
32027
+ "ui.providers.phone.status.applying": "Setting up",
32028
+ "ui.providers.phone.status.checking": "Checking",
32029
+ "ui.providers.phone.status.connected": "Connected",
32030
+ "ui.providers.phone.use_address": "Open the URL above and sign in with the same Radient account."
32031
+ };
32032
+ const enUiSchedules = {};
32033
+ const enUiSettings = {
32034
+ "ui.settings.language.dialog.description": "Applies across the app and the terminal — the same setting the settings page edits.",
32035
+ "ui.settings.language.dialog.loading": "Loading the current setting...",
32036
+ "ui.settings.language.dialog.retry": "Retry",
32037
+ "ui.settings.language.dialog.retrying": "Retrying",
32038
+ "ui.settings.language.dialog.save": "Save",
32039
+ "ui.settings.language.dialog.saved": "Saved",
32040
+ "ui.settings.language.dialog.title": "Interface language",
32041
+ "ui.settings.language.dialog.unavailable": "The connected service does not serve the settings this dialog edits.",
32042
+ "ui.settings.language.effective": "In effect: {locale}",
32043
+ "ui.settings.language.external_notice": "Interface language changed elsewhere — now {language}.",
32044
+ "ui.settings.language.general.description": "Choose the language shared by the app and terminal. Changes save immediately; existing conversations are not rewritten.",
32045
+ "ui.settings.language.general.effective": "App language in effect: {locale}",
32046
+ "ui.settings.language.general.last_known": "Last synced app language: {locale}",
32047
+ "ui.settings.language.general.no_resolution": "The app language has not been set yet.",
32048
+ "ui.settings.language.general.pending": "Saving language…",
32049
+ "ui.settings.language.general.readback_error": "The write was confirmed, but the current setting could not be checked. Reconnect or retry before changing it again.",
32050
+ "ui.settings.language.general.saved": "Language saved.",
32051
+ "ui.settings.language.general.system": "Use system",
32052
+ "ui.settings.language.general.unavailable_choice": "Not available",
32053
+ "ui.settings.language.general.write_error": "The language was not saved. Your previous setting is unchanged. {message}",
32054
+ "ui.settings.language.palette_action": "Change interface language",
32055
+ "ui.settings.page.title": "Settings",
32056
+ "ui.settings.profile.description_anonymous": "Your user profile information displayed in the application. This information is not provided to the agents.",
32057
+ "ui.settings.profile.description_authenticated": "Your user profile information displayed in the application. This information is not provided to the agents. These details are provided through your Radient account.",
32058
+ "ui.settings.profile.display_name.label": "Display name",
32059
+ "ui.settings.profile.display_name.placeholder": "Enter your name...",
32060
+ "ui.settings.profile.email.label": "Email address",
32061
+ "ui.settings.profile.email.placeholder": "Enter your email...",
32062
+ "ui.settings.profile.title": "User profile",
32063
+ "ui.settings.section.interface_language.help": "Interface language, one setting shared with the terminal. auto follows your operating system, falling back to English.",
32064
+ "ui.settings.section.interface_language.label": "Interface language",
32065
+ "ui.settings.tour.action": "Take the tour",
32066
+ "ui.settings.tour.description": "Missed the application onboarding tour or want a refresher? Start it again here.",
32067
+ "ui.settings.tour.title": "Application tour",
32068
+ "ui.settings.profile.account_checking": "Checking your Radient account…",
32069
+ "ui.settings.profile.account_read_failed_retry": "Your Radient account could not be read, so the name and email below are placeholders rather than your account details. Retry.",
32070
+ "ui.settings.profile.account_read_failed_refused": "Your Radient account could not be read, so the name and email below are placeholders rather than your account details. Retry, or sign in to Radient again.",
32071
+ "ui.settings.profile.retry": "Retry",
32072
+ "ui.settings.profile.retrying": "Retrying"
32073
+ };
32074
+ const enUiShell = {};
32075
+ const frUiConsole = {
32076
+ "ui.console.close.body": "Le programme en cours sera arrêté et son onglet supprimé.",
32077
+ "ui.console.close.busy": "Fermeture…",
32078
+ "ui.console.close.confirm": "Fermer le terminal",
32079
+ "ui.console.close.kept": "Sa sortie est conservée.",
32080
+ "ui.console.close.title": "Fermer ce terminal ?",
32081
+ "ui.console.create_failed.detail": "Le service de console fonctionne, mais a refusé de lancer un programme pour cette conversation — c’est donc cet essai qui a échoué, la console n’est pas désactivée. Réessayez d’abord ; si l’échec persiste, la ligne ci-dessous indique le motif fourni par le service.",
32082
+ "ui.console.create_failed.retry": "Réessayer",
32083
+ "ui.console.create_failed.title": "Impossible de démarrer la console dans cette session",
32084
+ "ui.console.empty.detail": "Une console exécute un programme dans le dossier de cette conversation et conserve sa sortie, même si ce volet est fermé.",
32085
+ "ui.console.empty.title": "Aucune console dans cette session",
32086
+ "ui.console.ended.exit_code": "code de sortie {code}",
32087
+ "ui.console.ended.exit_unknown": "code de sortie non observé",
32088
+ "ui.console.ended.live": "Ce terminal est terminé",
32089
+ "ui.console.ended.restored": "Ce terminal est terminé, historique restauré",
32090
+ "ui.console.loading.create": "Démarrage d’une console",
32091
+ "ui.console.loading.read": "Lecture de la console de cette session",
32092
+ "ui.console.new": "Nouvelle console",
32093
+ "ui.console.pane.blip": "Terminé depuis votre dernière visite",
32094
+ "ui.console.pane.close": "Fermer la console",
32095
+ "ui.console.pane.close_refusal": "Le terminal n’a pas pu être fermé.",
32096
+ "ui.console.pane.label": "Console",
32097
+ "ui.console.pane.needs_conversation.detail": "Une console utilise le dossier de travail d’une conversation : sans conversation, elle ne peut pas être créée.",
32098
+ "ui.console.pane.needs_conversation.title": "La console nécessite une conversation",
32099
+ "ui.console.pane.surfaces": "Terminaux de la console",
32100
+ "ui.console.secure": "Saisie sécurisée activée : ce que vous tapez ici n’est pas enregistré.",
32101
+ "ui.console.unavailable.disabled.detail": "LOCAL_OPERATOR_UI_CONSOLE_HOST vaut 0 dans l’environnement de l’application : aucun terminal n’est lancé et aucune surface ne peut être créée. Supprimez cette variable pour réactiver la console.",
32102
+ "ui.console.unavailable.disabled.title": "La console est désactivée pour cette exécution",
32103
+ "ui.console.unavailable.pty.detail": "La prise en charge des terminaux n’a pas été chargée pour cette exécution. Une mise à jour de Local Operator la rétablit ; le journal de l’application indique la cause.",
32104
+ "ui.console.unavailable.title": "La console est indisponible dans cette application",
32105
+ "ui.console.unavailable.unknown.detail": "Cette fenêtre n’a pas pu accéder à la console et n’a pas indiqué pourquoi. Le journal de l’application précise la cause.",
32106
+ "ui.console.capacity.summary": "{live, number} sur {limit, number} actifs dans l’app",
32107
+ "ui.console.capacity.summary_compact": "{live, number}/{limit, number} · {archived, plural, one {# gardé} many {# de gardés} other {# gardés}}",
32108
+ "ui.console.capacity.summary_compact_bare": "{live, number}/{limit, number}",
32109
+ "ui.console.capacity.archived": " · {archived, plural, one {# gardé} many {# de gardés} other {# gardés}}",
32110
+ "ui.console.capacity.full": " · plein",
32111
+ "ui.console.capacity.help": "Compteurs pour toute l’application, toutes conversations confondues. L’historique conservé n’occupe pas d’emplacement de processus.",
32112
+ "ui.console.capacity.resources": "Stockage géré estimé : {memory, number} MiB. Journaux : {logs, number} MiB. Sortie en attente : {pending, number} MiB. Cellules de terminal : {cells, number}. Terminaux protégés : {protected, number}. La mémoire des processus enfants n’est pas incluse.",
32113
+ "ui.console.cleanup.label": "Effacer les terminaux d’agent terminés",
32114
+ "ui.console.cleanup.help": "Efface les terminaux d’agent terminés de cette conversation. Ceux que l’agent a demandé de conserver restent sur le disque ; les autres sont fermés et leur sortie n’est pas conservée. Les terminaux que vous avez ouverts, ainsi que ceux en cours d’utilisation, ne sont pas touchés.",
32115
+ "ui.console.cleanup.result": "Effacé : {released, plural, one {# terminal d’agent terminé} many {# de terminaux d’agent terminés} other {# terminaux d’agent terminés}}. {protected, plural, =0 {} one {# terminal est encore utilisé et a été laissé ouvert.} many {# de terminaux sont encore utilisés et ont été laissés ouverts.} other {# terminaux sont encore utilisés et ont été laissés ouverts.}}",
32116
+ "ui.console.cleanup.result_none": "Rien à effacer — aucun terminal d’agent terminé dans cette conversation.",
32117
+ "ui.console.dismiss_history": "Effacer le terminal et supprimer la sortie conservée",
32118
+ "ui.console.dismiss.body": "Effacer ce terminal supprime sa sortie conservée sur le disque ; une relance ne pourra pas la restaurer.",
32119
+ "ui.console.dismiss.title": "Effacer ce terminal ?",
32120
+ "ui.console.dismiss.confirm": "Effacer le terminal",
32121
+ "ui.console.tab.ended": "terminé",
32122
+ "ui.console.tab.agent_opened": "Un agent a ouvert cette console",
32123
+ "ui.console.tab.agent_typed": "Un agent a saisi du texte dans cette console",
32124
+ "ui.console.tab.close_label": "Fermer {title}, onglet {index, number} sur {total, number}",
32125
+ "ui.console.tab.clear_label": "Effacer {title}, onglet {index, number} sur {total, number}",
32126
+ "ui.console.tab.clear_label_retained": "Effacer {title}, onglet {index, number} sur {total, number} — supprime la sortie conservée",
32127
+ "ui.console.secure_toggle.stop": "Arrêter la saisie sécurisée",
32128
+ "ui.console.secure_toggle.start": "Saisie sécurisée",
32129
+ "ui.console.secure_toggle.start_tooltip": "Saisie sécurisée : arrêter l’enregistrement de ce terminal",
32130
+ "ui.console.close.cancel": "Annuler",
32131
+ "ui.console.terminal.prompt_label": "Saisie du terminal",
32132
+ "ui.console.terminal.too_much_output": "Trop de sortie à annoncer, parcourez les lignes manuellement pour les lire"
32133
+ };
32134
+ const frUiOnboarding = {
32135
+ "ui.onboarding.connect.intro": "Local Operator a besoin d’un compte IA pour fonctionner. Radient est le plus simple : une connexion dans le navigateur, rien à coller. Vous payez déjà pour ChatGPT ou Claude ? Connectez-vous avec ce compte. Les autres options sont regroupées plus bas.",
32136
+ "ui.onboarding.default_model.block.loading_models": "Chargement des modèles…",
32137
+ "ui.onboarding.default_model.block.pick_a_model": "Choisissez un modèle pour continuer.",
32138
+ "ui.onboarding.default_model.change": "Modifier",
32139
+ "ui.onboarding.default_model.connected_pick": "{brand} est connecté. Choisissez le modèle des nouvelles conversations.",
32140
+ "ui.onboarding.default_model.empty_helper": "Aucun fournisseur connecté. Revenez à l’étape précédente pour en connecter un.",
32141
+ "ui.onboarding.default_model.fallback_name": "Modèle par défaut — {brand}",
32142
+ "ui.onboarding.default_model.intro": "Ce modèle servira aux nouvelles conversations. Chaque agent pourra en changer.",
32143
+ "ui.onboarding.default_model.loading": "Chargement de vos modèles",
32144
+ "ui.onboarding.default_model.none_connected": "Aucun fournisseur n’est encore connecté. Revenez en arrière pour en connecter un, ou passez la configuration et connectez-en un plus tard depuis la conversation.",
32145
+ "ui.onboarding.default_model.nothing_saved": "Rien ne sera enregistré : Local Operator ne peut pas encore lister les modèles proposés par {brand}. La configuration se termine donc sans modèle par défaut. Choisissez-en un dans Paramètres avant votre premier message.",
32146
+ "ui.onboarding.default_model.provider_fallback": "ce fournisseur",
32147
+ "ui.onboarding.default_model.tag.applied": "votre modèle par défaut",
32148
+ "ui.onboarding.default_model.tag.suggested": "suggéré pour votre compte",
32149
+ "ui.onboarding.dialog.setup": "Configuration",
32150
+ "ui.onboarding.extras.greeting_done": "{name} est votre cheffe de cabinet. Retrouvez-la dans sa conversation, accessible en une touche depuis la barre latérale. Vous pouvez aussi passer directement à une nouvelle conversation.",
32151
+ "ui.onboarding.extras.greeting_owed": "{name} est votre cheffe de cabinet. Elle vous accueillera, vous demandera comment vous appeler et en quoi vous aider, puis vous fera une visite guidée. Vous pouvez aussi passer directement à une nouvelle conversation.",
32152
+ "ui.onboarding.extras.next_meet": "Ensuite : rencontrer {name}",
32153
+ "ui.onboarding.modal.action.back": "Retour",
32154
+ "ui.onboarding.modal.action.continue": "Continuer",
32155
+ "ui.onboarding.modal.action.finish": "Terminer",
32156
+ "ui.onboarding.modal.action.meet": "Rencontrer {name}",
32157
+ "ui.onboarding.modal.action.skip": "Passer",
32158
+ "ui.onboarding.modal.action.skip_for_now": "Plus tard",
32159
+ "ui.onboarding.modal.action.skip_to_chat": "Passer à la conversation",
32160
+ "ui.onboarding.modal.error.aida_open_failed": "Impossible d’ouvrir la conversation avec {name} ; une nouvelle conversation a été ouverte à la place.",
32161
+ "ui.onboarding.modal.title.connect_provider": "Connecter un compte IA",
32162
+ "ui.onboarding.modal.title.default_model": "Votre modèle par défaut",
32163
+ "ui.onboarding.modal.title.extras": "Recherche web (facultative)",
32164
+ "ui.onboarding.modal.title.extras_with_name": "Recherche web, puis rencontre avec {name}",
32165
+ "ui.onboarding.modal.title.fallback": "Configuration initiale",
32166
+ "ui.onboarding.search.each_key_saved": "Chaque clé est enregistrée sur votre appareil dès que vous quittez son champ.",
32167
+ "ui.onboarding.search.intro": "Les agents peuvent chercher des informations pendant leur travail — prix du jour, actualités de la semaine — plutôt que de se limiter aux connaissances du modèle.",
32168
+ "ui.onboarding.search.mode.free": "Gratuit",
32169
+ "ui.onboarding.search.mode.free_detail": "Utilise à tour de rôle des fournisseurs gratuits — DuckDuckGo, l’offre gratuite de Tavily, Exa et Parallel. Aucune clé nécessaire ; l’accès est partagé, les recherches peuvent donc ralentir aux heures de pointe.",
32170
+ "ui.onboarding.search.mode.keys": "Ajouter des clés API",
32171
+ "ui.onboarding.search.mode.keys_detail": "Utilisez vos propres clés pour vos fournisseurs de recherche.",
32172
+ "ui.onboarding.search.mode.label": "Mode de recherche",
32173
+ "ui.onboarding.search.recommended": "Recommandé",
32174
+ "ui.onboarding.search.row.get_your": "Obtenir {name}",
32175
+ "ui.onboarding.search.row.not_saved": "Non enregistré — {message}",
32176
+ "ui.onboarding.search.row.placeholder": "Collez votre clé API",
32177
+ "ui.onboarding.search.row.save_failed": "La clé n’a pas pu être enregistrée.",
32178
+ "ui.onboarding.search.row.saved": "Enregistré",
32179
+ "ui.onboarding.search.row.saving": "Enregistrement : {name}",
32180
+ "ui.onboarding.modal.step_of": "Étape {current, number} sur {total, number}",
32181
+ "ui.onboarding.modal.steps_total": "{total, plural, one {# étape} many {# d’étapes} other {# étapes}}"
32182
+ };
32183
+ const frUiSettings = {
32184
+ "ui.settings.language.dialog.description": "S’applique à l’application et au terminal — le même réglage que dans les paramètres.",
32185
+ "ui.settings.language.dialog.loading": "Chargement du réglage actuel…",
32186
+ "ui.settings.language.dialog.retry": "Réessayer",
32187
+ "ui.settings.language.dialog.retrying": "Nouvel essai",
32188
+ "ui.settings.language.dialog.save": "Enregistrer",
32189
+ "ui.settings.language.dialog.saved": "Enregistré",
32190
+ "ui.settings.language.dialog.title": "Langue de l’interface",
32191
+ "ui.settings.language.dialog.unavailable": "Le service connecté ne fournit pas les paramètres modifiés dans cette fenêtre.",
32192
+ "ui.settings.language.effective": "Langue utilisée : {locale}",
32193
+ "ui.settings.language.external_notice": "Langue de l’interface modifiée ailleurs — désormais {language}.",
32194
+ "ui.settings.language.general.description": "Choisissez la langue de l’application et du terminal. Enregistrement immédiat ; les conversations existantes restent inchangées.",
32195
+ "ui.settings.language.general.effective": "Langue de l’application utilisée : {locale}",
32196
+ "ui.settings.language.general.last_known": "Dernière langue de l’application synchronisée : {locale}",
32197
+ "ui.settings.language.general.no_resolution": "La langue de l’application n’est pas encore définie.",
32198
+ "ui.settings.language.general.pending": "Enregistrement de la langue…",
32199
+ "ui.settings.language.general.readback_error": "L’enregistrement est confirmé, mais le réglage actuel n’a pas pu être vérifié. Rétablissez la connexion ou réessayez avant de le modifier.",
32200
+ "ui.settings.language.general.saved": "Langue enregistrée.",
32201
+ "ui.settings.language.general.system": "Langue du système",
32202
+ "ui.settings.language.general.unavailable_choice": "Indisponible",
32203
+ "ui.settings.language.general.write_error": "La langue n’a pas été enregistrée. Le réglage précédent reste inchangé. {message}",
32204
+ "ui.settings.language.palette_action": "Changer la langue de l’interface",
32205
+ "ui.settings.page.title": "Paramètres",
32206
+ "ui.settings.profile.description_anonymous": "Les informations de votre profil affichées dans l’application ne sont pas transmises aux agents.",
32207
+ "ui.settings.profile.description_authenticated": "Les informations de votre profil affichées dans l’application ne sont pas transmises aux agents. Elles proviennent de votre compte Radient.",
32208
+ "ui.settings.profile.display_name.label": "Nom affiché",
32209
+ "ui.settings.profile.display_name.placeholder": "Saisissez votre nom…",
32210
+ "ui.settings.profile.email.label": "Adresse e-mail",
32211
+ "ui.settings.profile.email.placeholder": "Saisissez votre e-mail…",
32212
+ "ui.settings.profile.title": "Profil utilisateur",
32213
+ "ui.settings.section.interface_language.help": "Langue de l’interface, partagée avec le terminal. auto suit la langue du système ou utilise l’anglais à défaut.",
32214
+ "ui.settings.section.interface_language.label": "Langue de l’interface",
32215
+ "ui.settings.tour.action": "Lancer la visite",
32216
+ "ui.settings.tour.description": "Vous avez manqué la visite guidée ou souhaitez la revoir ? Relancez-la ici.",
32217
+ "ui.settings.tour.title": "Visite guidée",
32218
+ "ui.settings.profile.account_checking": "Vérification de votre compte Radient…",
32219
+ "ui.settings.profile.account_read_failed_retry": "Votre compte Radient n’a pas pu être lu ; le nom et l’adresse e-mail ci-dessous sont donc des valeurs par défaut, et non les informations de votre compte. Réessayez.",
32220
+ "ui.settings.profile.account_read_failed_refused": "Votre compte Radient n’a pas pu être lu ; le nom et l’adresse e-mail ci-dessous sont donc des valeurs par défaut, et non les informations de votre compte. Réessayez, ou reconnectez-vous à Radient.",
32221
+ "ui.settings.profile.retry": "Réessayer",
32222
+ "ui.settings.profile.retrying": "Nouvel essai"
32223
+ };
32224
+ const bundledEnglish = {
32225
+ ...enUiAgents,
32226
+ ...enUiBrowserChrome,
32227
+ ...enUiBrowser,
32228
+ ...enUiCanvas,
32229
+ ...enUiChat,
32230
+ ...enUiConsole,
32231
+ ...enUiHub,
32232
+ ...enUiMesh,
32233
+ ...enUiOnboarding,
32234
+ ...enUiProjects,
32235
+ ...enUiProviders,
32236
+ ...enUiSchedules,
32237
+ ...enUiSettings,
32238
+ ...enUiShell
32239
+ };
32240
+ const bundledCatalogues = {
32241
+ en: bundledEnglish,
32242
+ fr: {
32243
+ ...frUiConsole,
32244
+ ...frUiOnboarding,
32245
+ ...frUiSettings
32246
+ }
32247
+ };
32248
+ const DEFAULT_LOCALE = "en";
32249
+ function deviceLanguage() {
32250
+ const navigatorLike = globalThis.navigator;
32251
+ const language = navigatorLike?.language;
32252
+ return typeof language === "string" && language.trim() !== "" ? language : void 0;
32253
+ }
32254
+ function resolveLocale(capabilities) {
32255
+ const device = deviceLanguage();
32256
+ return device ? { locale: device, source: "device" } : { locale: DEFAULT_LOCALE, source: "default" };
32257
+ }
32258
+ let state = resolveLocale();
32259
+ function currentLocale() {
32260
+ return state.locale;
32261
+ }
32262
+ const registered = /* @__PURE__ */ new Map();
32263
+ function messageFor(key, locale) {
32264
+ const served = registered.get(locale)?.[key];
32265
+ if (served !== void 0) return served;
32266
+ const bundled = bundledCatalogues[locale]?.[key];
32267
+ if (bundled !== void 0) return bundled;
32268
+ return bundledEnglish[key];
32269
+ }
32270
+ function sourceTagFor(key, locale) {
32271
+ if (registered.get(locale)?.[key] !== void 0) return locale;
32272
+ if (bundledCatalogues[locale]?.[key] !== void 0) return locale;
32273
+ return DEFAULT_LOCALE;
32274
+ }
32275
+ const formats = /* @__PURE__ */ new Map();
32276
+ function formatterFor(locale, message) {
32277
+ const cacheKey = `${locale}\0${message}`;
32278
+ let format = formats.get(cacheKey);
32279
+ if (format === void 0) {
32280
+ format = new IntlMessageFormat(message, locale);
32281
+ formats.set(cacheKey, format);
32282
+ }
32283
+ return format;
32284
+ }
32285
+ function translate(key, params = {}, locale = currentLocale()) {
32286
+ const message = messageFor(key, locale);
32287
+ if (message === void 0) return key;
32288
+ const tag = sourceTagFor(key, locale);
32289
+ try {
32290
+ const rendered = formatterFor(tag, message).format(params);
32291
+ return typeof rendered === "string" ? rendered : String(rendered);
32292
+ } catch {
32293
+ return key;
32294
+ }
32295
+ }
32296
+ function t(key, params) {
32297
+ return translate(key, params ?? {});
32298
+ }
28801
32299
  function requesterOf(params, requestId2) {
28802
32300
  const supplied = typeof params.requester === "string" ? params.requester.trim() : "";
28803
32301
  return supplied.startsWith("session:") ? supplied : requestId2;
@@ -31328,6 +34826,35 @@ function factOf(path2) {
31328
34826
  sha256: ""
31329
34827
  };
31330
34828
  }
34829
+ class ChromeTabOrder {
34830
+ ids = [];
34831
+ customized = false;
34832
+ get hasCustomOrder() {
34833
+ return this.customized;
34834
+ }
34835
+ project(records) {
34836
+ if (!this.customized) this.ids = records.map((record) => record.tabId);
34837
+ const byId = new Map(records.map((record) => [record.tabId, record]));
34838
+ this.ids = this.ids.filter((id2) => byId.has(id2));
34839
+ const known = new Set(this.ids);
34840
+ this.ids.push(
34841
+ ...records.filter((r) => !known.has(r.tabId)).map((r) => r.tabId)
34842
+ );
34843
+ return this.ids.map((id2) => byId.get(id2)).filter((record) => record !== void 0);
34844
+ }
34845
+ reorder(records, permutation) {
34846
+ this.project(records);
34847
+ const selected = new Set(permutation);
34848
+ if (selected.size !== permutation.length || [...permutation].some((id2) => !this.ids.includes(id2)))
34849
+ return false;
34850
+ this.customized = true;
34851
+ let index = 0;
34852
+ this.ids = this.ids.map(
34853
+ (id2) => selected.has(id2) ? permutation[index++] : id2
34854
+ );
34855
+ return true;
34856
+ }
34857
+ }
31331
34858
  const PAGE_ZOOM_STEPS = [
31332
34859
  0.25,
31333
34860
  0.33,
@@ -31490,6 +35017,7 @@ class PageControls {
31490
35017
  if (changed) this.changed();
31491
35018
  }
31492
35019
  }
35020
+ const DUPLICATABLE_WEB_URL = /^https?:\/\//i;
31493
35021
  const DOCUMENT_SCOPED = /* @__PURE__ */ new Set([
31494
35022
  "read",
31495
35023
  // The structured reads (`styles`, `hit_test`, `ancestors`) describe the
@@ -31575,6 +35103,7 @@ function sessionRequesterOf(requester) {
31575
35103
  return id2 || null;
31576
35104
  }
31577
35105
  class BrowserHost {
35106
+ chromeTabOrder = new ChromeTabOrder();
31578
35107
  registry;
31579
35108
  pageControls;
31580
35109
  cdp;
@@ -31888,7 +35417,8 @@ class BrowserHost {
31888
35417
  const navigation = active?.view.webContents.navigationHistory;
31889
35418
  return {
31890
35419
  pageControls: this.pageControls.state(active),
31891
- tabs: this.registry.snapshot().map((entry) => ({
35420
+ tabs: this.chromeTabOrder.project(this.registry.snapshot()).map((entry, displayOrder) => ({
35421
+ ...this.chromeTabOrder.hasCustomOrder ? { displayOrder } : {},
31892
35422
  tabId: entry.tabId,
31893
35423
  title: this.titleForChrome(entry.title) || "New tab",
31894
35424
  url: entry.url,
@@ -32008,14 +35538,75 @@ class BrowserHost {
32008
35538
  await this.createUserTab(sessionId2 ?? null);
32009
35539
  return this.chromeState();
32010
35540
  }
35541
+ /** Human duplicates copy URL ONLY. Session attribution is not a capability,
35542
+ * but copying it would still put an agent's duplicate inside its conversation.
35543
+ * User records have no nonce/handover; an explicit later handover is the only
35544
+ * way they can become agent-drivable. Failure retains that plain user tab. */
35545
+ async actOnChromeTab(tabId, action) {
35546
+ const record = this.registry.get(tabId);
35547
+ if (!record || record.view.webContents.isDestroyed())
35548
+ return {
35549
+ status: "failed",
35550
+ action,
35551
+ tabId: null,
35552
+ error: { code: "tab_closed", message: t("ui.browser.chrome.tab_gone") }
35553
+ };
35554
+ let url = "";
35555
+ let destinationId = action === "reload" ? tabId : null;
35556
+ try {
35557
+ url = record.view.webContents.getURL();
35558
+ if (action === "duplicate" && url !== "about:blank" && !DUPLICATABLE_WEB_URL.test(url))
35559
+ return {
35560
+ status: "failed",
35561
+ action,
35562
+ tabId: null,
35563
+ error: {
35564
+ code: "unsupported_page",
35565
+ message: t("ui.browser.chrome.duplicate_refused")
35566
+ }
35567
+ };
35568
+ if (action === "reload") record.view.webContents.reload();
35569
+ else {
35570
+ const copy = await this.createUserTab(null, url, (created) => {
35571
+ destinationId = created.tabId;
35572
+ });
35573
+ destinationId = copy.tabId;
35574
+ }
35575
+ this.onChanged();
35576
+ return { status: "completed", action, tabId: destinationId };
35577
+ } catch {
35578
+ if (destinationId !== null && action === "duplicate")
35579
+ this.recordLoadFailure(destinationId, {
35580
+ code: -2,
35581
+ description: "DUPLICATE_NAVIGATION_FAILED",
35582
+ url
35583
+ });
35584
+ return {
35585
+ status: "failed",
35586
+ action,
35587
+ tabId: destinationId,
35588
+ error: {
35589
+ code: "navigation_failed",
35590
+ message: t("ui.browser.chrome.operation_failed", { action })
35591
+ }
35592
+ };
35593
+ }
35594
+ }
35595
+ reorderChromeTabs(ids) {
35596
+ if (!this.chromeTabOrder.reorder(this.registry.snapshot(), ids))
35597
+ throw new Error(t("ui.browser.chrome.invalid_order"));
35598
+ this.onChanged();
35599
+ return this.chromeState();
35600
+ }
32011
35601
  /** `newTab`'s body, returning the record so `reopenClosed` can navigate the tab
32012
35602
  * it created rather than whichever tab is active by the time the await ends. */
32013
- async createUserTab(sessionId2) {
35603
+ async createUserTab(sessionId2, initialUrl = "about:blank", onCreated) {
32014
35604
  const record = this.registry.create({
32015
35605
  owner: "user",
32016
35606
  sessionId: sessionId2
32017
35607
  });
32018
- await record.view.webContents.loadURL("about:blank");
35608
+ onCreated?.(record);
35609
+ await record.view.webContents.loadURL(initialUrl);
32019
35610
  await this.cdp.attach(record.view.webContents);
32020
35611
  this.onChanged();
32021
35612
  return record;
@@ -32610,12 +36201,12 @@ class ConsentNotifier {
32610
36201
  this.announced = count;
32611
36202
  if (!increased) return;
32612
36203
  if (this.options.show !== "focus") return;
32613
- const create = this.options.createNotification;
32614
- if (!create && !electron.Notification.isSupported()) return;
36204
+ const create2 = this.options.createNotification;
36205
+ if (!create2 && !electron.Notification.isSupported()) return;
32615
36206
  const oldest = pending[0];
32616
36207
  if (!oldest) return;
32617
36208
  try {
32618
- const notification = (create ?? ((options) => new electron.Notification(options)))(
36209
+ const notification = (create2 ?? ((options) => new electron.Notification(options)))(
32619
36210
  {
32620
36211
  title: CONSENT_TITLE,
32621
36212
  body: consentBody(count, oldest.origin),
@@ -32967,19 +36558,19 @@ class DownloadArmer {
32967
36558
  }
32968
36559
  this.showProgress(capture, entry);
32969
36560
  });
32970
- item.once("done", (_event, state) => {
36561
+ item.once("done", (_event, state2) => {
32971
36562
  capture.pending -= 1;
32972
36563
  capture.live = capture.live.filter((live) => live !== entry);
32973
36564
  const name = path$1.basename(savePath);
32974
36565
  this.release(capture, savePath);
32975
36566
  if (entry.weCancelled) {
32976
- if (state !== "completed") discardPartial(savePath, this.options.log);
32977
- } else if (state === "completed") {
36567
+ if (state2 !== "completed") discardPartial(savePath, this.options.log);
36568
+ } else if (state2 === "completed") {
32978
36569
  restrictMode(savePath, this.options.log);
32979
36570
  capture.files.push(fileFact(item, savePath));
32980
36571
  this.note(capture, name, "saved", 1, "", null);
32981
36572
  } else {
32982
- const reason = capture.settled ? `refused: \`${name}\` did not finish (${state}) after this call's answer; the partial file was discarded` : `refused: \`${name}\` did not finish (${state}); the partial file was discarded`;
36573
+ const reason = capture.settled ? `refused: \`${name}\` did not finish (${state2}) after this call's answer; the partial file was discarded` : `refused: \`${name}\` did not finish (${state2}); the partial file was discarded`;
32983
36574
  discardPartial(savePath, this.options.log);
32984
36575
  if (!capture.settled) capture.refusals.push(reason);
32985
36576
  this.note(capture, name, "refused", 1, reason, {
@@ -33329,6 +36920,8 @@ const BROWSER_IPC_CHANNELS = [
33329
36920
  "browser-reopen-tab",
33330
36921
  "browser-focus-page",
33331
36922
  "browser-new-tab",
36923
+ "browser-reorder-tabs",
36924
+ "browser-tab-action",
33332
36925
  "browser-close-tab",
33333
36926
  "browser-close-tabs",
33334
36927
  "browser-activate-tab",
@@ -33398,6 +36991,23 @@ function registerBrowserIpc(options) {
33398
36991
  const host = authorize(event);
33399
36992
  return host.newTab(optionalConversationOrThrow(sessionId2));
33400
36993
  });
36994
+ electron.ipcMain.handle("browser-reorder-tabs", (event, ids) => {
36995
+ const host = authorize(event);
36996
+ if (!Array.isArray(ids) || ids.length > 512 || Array.from(ids).some(
36997
+ (id2) => typeof id2 !== "number" || !Number.isSafeInteger(id2) || id2 < 0
36998
+ ))
36999
+ throw new Error(t("ui.browser.chrome.invalid_order"));
37000
+ return host.reorderChromeTabs(ids);
37001
+ });
37002
+ electron.ipcMain.handle(
37003
+ "browser-tab-action",
37004
+ (event, tabId, action) => {
37005
+ const host = authorize(event);
37006
+ if (action !== "duplicate" && action !== "reload")
37007
+ throw new Error(t("ui.browser.chrome.invalid_action"));
37008
+ return host.actOnChromeTab(numberOrThrow(tabId, "tabId"), action);
37009
+ }
37010
+ );
33401
37011
  electron.ipcMain.handle("browser-close-tab", (event, tabId) => {
33402
37012
  const host = authorize(event);
33403
37013
  return host.closeTab(numberOrThrow(tabId, "tabId"));
@@ -33654,10 +37264,10 @@ class OwnershipLedger {
33654
37264
  }
33655
37265
  /** The scope a proof names, after the session and generation checks. Creation
33656
37266
  * is opt-in per method, matching the extension's `create` flag. */
33657
- mutate(params, fn, create = false) {
37267
+ mutate(params, fn, create2 = false) {
33658
37268
  const [proof, session, generation] = this.identity(params);
33659
37269
  let scope = this.scopes.get(proof);
33660
- if (!scope && create) {
37270
+ if (!scope && create2) {
33661
37271
  scope = {
33662
37272
  session,
33663
37273
  generation,
@@ -33675,7 +37285,7 @@ class OwnershipLedger {
33675
37285
  return fn(scope);
33676
37286
  }
33677
37287
  /** Record (or clear) the tab an allocation owns. */
33678
- recordAllocation(params, tab, state) {
37288
+ recordAllocation(params, tab, state2) {
33679
37289
  if (!params.owner_proof) return;
33680
37290
  this.mutate(params, (scope) => {
33681
37291
  const allocation = String(params.allocation_id ?? "");
@@ -33685,7 +37295,7 @@ class OwnershipLedger {
33685
37295
  if (scope.terminal) {
33686
37296
  throw new BridgeCommandError("owner_refused", "browser scope ended");
33687
37297
  }
33688
- scope.allocations[allocation] = { tab: tab || void 0, state };
37298
+ scope.allocations[allocation] = { tab: tab || void 0, state: state2 };
33689
37299
  });
33690
37300
  }
33691
37301
  /**
@@ -36645,10 +40255,10 @@ class DesktopNotifier {
36645
40255
  * being left.
36646
40256
  */
36647
40257
  releaseWatch(windowId, sessionId2) {
36648
- const state = this.windows.get(windowId);
36649
- if (!state) return;
36650
- if (!sessionId2 || state.session !== sessionId2) return;
36651
- this.windows.set(windowId, { ...state, session: "" });
40258
+ const state2 = this.windows.get(windowId);
40259
+ if (!state2) return;
40260
+ if (!sessionId2 || state2.session !== sessionId2) return;
40261
+ this.windows.set(windowId, { ...state2, session: "" });
36652
40262
  }
36653
40263
  /**
36654
40264
  * Called by the stream relay for every parsed frame it forwards, and by the
@@ -36844,11 +40454,11 @@ class DesktopNotifier {
36844
40454
  * suppresses every completion for the life of the process.
36845
40455
  */
36846
40456
  anyDisplayingFocused(sessionId2) {
36847
- for (const [id2, state] of this.windows) {
36848
- if (!state.visible || !state.focused) continue;
36849
- if (state.session !== sessionId2) continue;
40457
+ for (const [id2, state2] of this.windows) {
40458
+ if (!state2.visible || !state2.focused) continue;
40459
+ if (state2.session !== sessionId2) continue;
36850
40460
  if (!this.host.windowAlive(id2)) continue;
36851
- if (Date.now() - state.seenAt > RENDERER_REPORT_TTL_MS) continue;
40461
+ if (Date.now() - state2.seenAt > RENDERER_REPORT_TTL_MS) continue;
36852
40462
  return true;
36853
40463
  }
36854
40464
  return false;
@@ -45441,7 +49051,7 @@ class ViewerEndpoint {
45441
49051
  }
45442
49052
  });
45443
49053
  }
45444
- async onLine(line, socket, state) {
49054
+ async onLine(line, socket, state2) {
45445
49055
  let frame;
45446
49056
  try {
45447
49057
  frame = JSON.parse(line);
@@ -45450,13 +49060,13 @@ class ViewerEndpoint {
45450
49060
  }
45451
49061
  if (typeof frame !== "object" || frame === null) return;
45452
49062
  const record = frame;
45453
- if (!state.isAuthenticated()) {
49063
+ if (!state2.isAuthenticated()) {
45454
49064
  const key = typeof record.key === "string" ? record.key : "";
45455
49065
  if (!constantTimeEqual(key, this.key)) {
45456
- state.finish();
49066
+ state2.finish();
45457
49067
  return;
45458
49068
  }
45459
- state.markAuthenticated();
49069
+ state2.markAuthenticated();
45460
49070
  return;
45461
49071
  }
45462
49072
  const op = typeof record.op === "string" ? record.op : "";
@@ -45475,7 +49085,7 @@ class ViewerEndpoint {
45475
49085
  socket.write(`${JSON.stringify(reply)}
45476
49086
  `);
45477
49087
  } catch {
45478
- state.finish();
49088
+ state2.finish();
45479
49089
  }
45480
49090
  }
45481
49091
  async apply(op, frame) {
@@ -46021,8 +49631,8 @@ function frameNavigationVerdict(input, trustedRendererUrls) {
46021
49631
  }
46022
49632
  const own = trustedRendererUrls.some((trusted) => {
46023
49633
  try {
46024
- const t = new URL(trusted);
46025
- return t.protocol === "file:" ? minted.protocol === "file:" : minted.origin === t.origin;
49634
+ const t2 = new URL(trusted);
49635
+ return t2.protocol === "file:" ? minted.protocol === "file:" : minted.origin === t2.origin;
46026
49636
  } catch {
46027
49637
  return false;
46028
49638
  }
@@ -47170,10 +50780,10 @@ electron.app.whenReady().then(async () => {
47170
50780
  if (!window || window.isDestroyed()) return;
47171
50781
  window.webContents.send("desktop-feed-frame", frame);
47172
50782
  },
47173
- (state) => {
50783
+ (state2) => {
47174
50784
  const window = mainWindow;
47175
50785
  if (!window || window.isDestroyed()) return;
47176
- window.webContents.send("desktop-feed-state", state);
50786
+ window.webContents.send("desktop-feed-state", state2);
47177
50787
  }
47178
50788
  );
47179
50789
  backendService.providePresenceContext(() => desktopNotifier.presence());
@@ -47299,10 +50909,10 @@ electron.app.whenReady().then(async () => {
47299
50909
  */
47300
50910
  env: launchEnv,
47301
50911
  onTrigger: () => miniView?.toggle(),
47302
- onState: (state) => {
50912
+ onState: (state2) => {
47303
50913
  for (const window of electron.BrowserWindow.getAllWindows()) {
47304
50914
  if (window.isDestroyed()) continue;
47305
- window.webContents.send(MINI_VIEW_REGISTRATION, state);
50915
+ window.webContents.send(MINI_VIEW_REGISTRATION, state2);
47306
50916
  }
47307
50917
  }
47308
50918
  });
@@ -47318,10 +50928,10 @@ electron.app.whenReady().then(async () => {
47318
50928
  );
47319
50929
  quickSendWatcher = watchQuickSend({
47320
50930
  onValue: (value) => {
47321
- const state = miniViewRegistrar?.apply(value);
47322
- if (state)
50931
+ const state2 = miniViewRegistrar?.apply(value);
50932
+ if (state2)
47323
50933
  logger.info(
47324
- `mini-view: config changed, registration is ${state.status}`,
50934
+ `mini-view: config changed, registration is ${state2.status}`,
47325
50935
  LogFileType.BACKEND
47326
50936
  );
47327
50937
  },
@@ -47344,9 +50954,9 @@ electron.app.whenReady().then(async () => {
47344
50954
  if (!owner || owner.isDestroyed() || event.sender !== owner.webContents || event.senderFrame !== owner.webContents.mainFrame) {
47345
50955
  throw new Error("This window cannot read the hotkey registration.");
47346
50956
  }
47347
- const state = miniViewRegistrar?.getState() ?? null;
47348
- if (state) {
47349
- return state;
50957
+ const state2 = miniViewRegistrar?.getState() ?? null;
50958
+ if (state2) {
50959
+ return state2;
47350
50960
  }
47351
50961
  return {
47352
50962
  value: "",