negotium 0.1.26 → 0.1.28

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.
package/dist/main.js CHANGED
@@ -3728,7 +3728,7 @@ var init_claude_provider = __esm(async () => {
3728
3728
  });
3729
3729
 
3730
3730
  // ../../packages/core/src/version.ts
3731
- var NEGOTIUM_VERSION = "0.1.26";
3731
+ var NEGOTIUM_VERSION = "0.1.28";
3732
3732
 
3733
3733
  // ../../packages/core/src/agents/codex-native-multi-agent.ts
3734
3734
  import { spawn as spawn3 } from "child_process";
@@ -20904,7 +20904,9 @@ __export(exports_src3, {
20904
20904
  startDefaultNode: () => startDefaultNode,
20905
20905
  runNodeDaemon: () => runNodeDaemon,
20906
20906
  readNodeDaemonInfo: () => readNodeDaemonInfo,
20907
+ nodeFileStore: () => nodeFileStore,
20907
20908
  inspectNodeDaemon: () => inspectNodeDaemon,
20909
+ NodeFileStore: () => NodeFileStore,
20908
20910
  NODE_RUNTIME_CONTRACT_VERSION: () => NODE_RUNTIME_CONTRACT_VERSION,
20909
20911
  NODE_RUNTIME_CONTRACT_BASE_PATH: () => NODE_RUNTIME_CONTRACT_BASE_PATH,
20910
20912
  NODE_DAEMON_INFO_PATH: () => NODE_DAEMON_INFO_PATH,
@@ -21129,6 +21131,7 @@ var init_src5 = __esm(async () => {
21129
21131
  await init_control();
21130
21132
  await init_files();
21131
21133
  await init_control();
21134
+ await init_files();
21132
21135
  });
21133
21136
 
21134
21137
  // ../../packages/adapter-sdk/src/index.ts
@@ -21796,8 +21799,8 @@ var init_commands = __esm(() => {
21796
21799
  { name: "copy", usage: "/copy [all]", description: "copy answer or transcript" },
21797
21800
  {
21798
21801
  name: "vault",
21799
- usage: "/vault",
21800
- description: "manage encrypted secrets"
21802
+ usage: "/vault [list|set|del]",
21803
+ description: "open the Vault editor or run a compact Vault command"
21801
21804
  },
21802
21805
  { name: "abort", usage: "/abort", description: "stop the active turn" },
21803
21806
  { name: "help", usage: "/help", description: "show keyboard help" },
@@ -22843,22 +22846,25 @@ function vaultOverlayLines(state, width, height) {
22843
22846
  ].slice(0, height);
22844
22847
  }
22845
22848
  const entries = state.vaultEntries;
22846
- const visibleCount = Math.max(1, height - 7);
22847
- const start = Math.min(Math.max(0, entries.length - visibleCount), Math.max(0, state.vaultPickerIndex - visibleCount + 1));
22849
+ const visibleCount = Math.max(1, height - 13);
22848
22850
  return [
22849
22851
  ...header,
22850
22852
  ...entries.length === 0 ? [
22851
22853
  line(" No secrets stored", { bold: true }),
22852
- line(" Press N to add your first key.", { fg: theme.muted })
22853
- ] : entries.slice(start, start + visibleCount).map((entry, visibleIndex) => {
22854
- const selected = start + visibleIndex === state.vaultPickerIndex;
22855
- const description = entry.description || "No description";
22856
- return line(` ${selected ? "\u203A" : " "} ${entry.key} ${description}`, {
22857
- fg: selected ? theme.text : theme.muted,
22858
- bg: selected ? theme.selected : theme.canvas,
22859
- bold: selected
22860
- });
22854
+ line(" Add one with the command below.", { fg: theme.muted })
22855
+ ] : entries.slice(0, visibleCount).map((entry) => line(` \u2022 ${entry.key} ${entry.description || "No description"}`, {
22856
+ fg: theme.muted
22857
+ })),
22858
+ line(""),
22859
+ line(" Add or update", { fg: theme.cyan, bold: true }),
22860
+ line(" /vault set KEY VALUE | optional description", { fg: theme.text }),
22861
+ line(" Example: /vault set GITHUB_TOKEN your-secret-value | GitHub access", {
22862
+ fg: theme.muted
22861
22863
  }),
22864
+ line(" Delete", { fg: theme.cyan, bold: true }),
22865
+ line(" /vault del KEY", { fg: theme.text }),
22866
+ line(" Example: /vault del GITHUB_TOKEN", { fg: theme.muted }),
22867
+ line(" Vault commands are never saved to input history.", { fg: theme.muted }),
22862
22868
  ...state.vaultNotice ? [line(""), line(` ${state.vaultNotice}`, { fg: theme.green })] : []
22863
22869
  ].slice(0, height);
22864
22870
  }
@@ -22996,7 +23002,7 @@ function inputVisualLines(state, width) {
22996
23002
  `).map((row) => "*".repeat(Array.from(row).length)).join(`
22997
23003
  `) : state.input;
22998
23004
  if (!displayInput) {
22999
- const placeholder = state.overlay === "vault" ? state.vaultMode === "key" ? "Type a key name\u2026" : state.vaultMode === "value" ? "Type the secret value\u2026" : "Optional description\u2026" : state.creatingTopic ? "Type a topic name\u2026" : "Type a message or /command\u2026";
23005
+ const placeholder = state.overlay === "vault" ? state.vaultMode === "list" ? "Type /vault set \u2026 or /vault del \u2026" : state.vaultMode === "key" ? "Type a key name\u2026" : state.vaultMode === "value" ? "Type the secret value\u2026" : "Optional description\u2026" : state.creatingTopic ? "Type a topic name\u2026" : "Type a message or /command\u2026";
23000
23006
  return {
23001
23007
  lines: [line(` \u203A ${placeholder}`, { fg: theme.subtle, bg: theme.surfaceRaised })],
23002
23008
  cursorLine: 0,
@@ -23024,7 +23030,7 @@ function inputVisualLines(state, width) {
23024
23030
  return { lines: result, cursorLine, cursorColumn };
23025
23031
  }
23026
23032
  function composerPane(state, width) {
23027
- const title = state.creatingTopic ? "new topic \xB7 type a name \xB7 Enter create" : state.overlay === "vault" ? `${state.vaultMode === "key" ? "key" : state.vaultMode === "value" ? "secret value" : "description"} \xB7 Enter continue \xB7 Esc cancel` : "Ctrl-O topics";
23033
+ const title = state.creatingTopic ? "new topic \xB7 type a name \xB7 Enter create" : state.overlay === "vault" ? state.vaultMode === "list" ? "Vault command \xB7 Enter run \xB7 Esc close" : `${state.vaultMode === "key" ? "key" : state.vaultMode === "value" ? "secret value" : "description"} \xB7 Enter continue \xB7 Esc cancel` : "Ctrl-O topics";
23028
23034
  const visual = inputVisualLines(state, width);
23029
23035
  let inputStart = Math.max(0, visual.lines.length - 5);
23030
23036
  if (visual.cursorLine < inputStart)
@@ -23104,7 +23110,7 @@ function footerLines(state, width) {
23104
23110
  bg: theme.surfaceRaised,
23105
23111
  bold: true
23106
23112
  }),
23107
- paint(joinSides("", state.notice ? `! ${state.notice} ` : state.overlay === "topics" ? state.topicPickerRoot ? "Esc/Ctrl-C exit " : "Esc close \xB7 Ctrl-C exit; work continues " : state.overlay === "background-session" ? "Esc back \xB7 read-only " : state.overlay === "vault" ? state.vaultMode === "list" ? state.vaultEntries.length > 0 ? "\u2191\u2193 select \xB7 Enter edit \xB7 N add \xB7 D delete \xB7 Esc close " : "N add \xB7 Esc close " : state.vaultMode === "confirm-delete" ? "Y delete \xB7 N cancel " : "Enter continue \xB7 Esc cancel " : running ? "Esc/Ctrl-C stop " : "Ctrl-C twice to quit ", width), {
23113
+ paint(joinSides("", state.notice ? `! ${state.notice} ` : state.overlay === "topics" ? state.topicPickerRoot ? "Esc/Ctrl-C exit " : "Esc close \xB7 Ctrl-C exit; work continues " : state.overlay === "background-session" ? "Esc back \xB7 read-only " : state.overlay === "vault" ? state.vaultMode === "list" ? "Enter run \xB7 Esc close " : state.vaultMode === "confirm-delete" ? "Y delete \xB7 N cancel " : "Enter continue \xB7 Esc cancel " : running ? "Esc/Ctrl-C stop " : "Ctrl-C twice to quit ", width), {
23108
23114
  fg: state.notice ? theme.amber : theme.muted,
23109
23115
  bg: theme.canvas
23110
23116
  })
@@ -23129,7 +23135,7 @@ function renderAppFrame(state, columns, rows, animationFrame = 0, nowMs = termin
23129
23135
  const height = Math.max(14, rows);
23130
23136
  const footer = footerLines(state, width);
23131
23137
  const decision = decisionPane(state, width);
23132
- const hideComposer = state.overlay === "background-session" || state.overlay === "topics" || state.overlay === "vault" && (state.vaultMode === "list" || state.vaultMode === "confirm-delete");
23138
+ const hideComposer = state.overlay === "background-session" || state.overlay === "topics" || state.overlay === "vault" && state.vaultMode === "confirm-delete";
23133
23139
  const composer = hideComposer ? { lines: [], cursor: null } : composerPane(state, width);
23134
23140
  const bodyHeight = Math.max(3, height - footer.length - decision.length - composer.lines.length);
23135
23141
  const body = renderBody(conversationLines(state, width, bodyHeight, animationFrame, nowMs), width, bodyHeight);
@@ -23192,18 +23198,27 @@ class TerminalScreenRenderer {
23192
23198
  this.#previousLines = [];
23193
23199
  this.#invalidated = true;
23194
23200
  }
23195
- update(frame) {
23201
+ update(frame, terminalRows) {
23196
23202
  const lines = frame.split(`
23197
23203
  `);
23198
23204
  const previous = this.#previousLines;
23199
23205
  const redrawAll = this.#invalidated;
23200
- const rowCount = Math.max(lines.length, previous.length);
23206
+ const storedRowCount = Math.max(lines.length, previous.length);
23207
+ const physicalRowCount = Math.max(1, Math.trunc(terminalRows ?? storedRowCount));
23208
+ const rowCount = Math.min(storedRowCount, physicalRowCount);
23201
23209
  let output = "";
23202
23210
  for (let index = 0;index < rowCount; index += 1) {
23203
23211
  const current3 = lines[index];
23204
23212
  if (!redrawAll && current3 === previous[index])
23205
23213
  continue;
23206
- output += `${ESC2}${index + 1};1H${ESC2}2K${current3 ?? ""}`;
23214
+ const row = index + 1;
23215
+ const content = current3 ?? "";
23216
+ output += `${ESC2}${row};1H${ESC2}2K`;
23217
+ if (row === physicalRowCount) {
23218
+ output += `${DISABLE_AUTOWRAP}${content}${ENABLE_AUTOWRAP}`;
23219
+ } else {
23220
+ output += content;
23221
+ }
23207
23222
  }
23208
23223
  if (output)
23209
23224
  output += `${ESC2}H`;
@@ -23212,7 +23227,11 @@ class TerminalScreenRenderer {
23212
23227
  return output;
23213
23228
  }
23214
23229
  }
23215
- var ESC2 = "\x1B[";
23230
+ var ESC2 = "\x1B[", DISABLE_AUTOWRAP, ENABLE_AUTOWRAP;
23231
+ var init_screen_renderer = __esm(() => {
23232
+ DISABLE_AUTOWRAP = `${ESC2}?7l`;
23233
+ ENABLE_AUTOWRAP = `${ESC2}?7h`;
23234
+ });
23216
23235
 
23217
23236
  // ../../adapters/terminal/src/selection.ts
23218
23237
  function ordered(selection) {
@@ -23591,6 +23610,27 @@ function selectableEfforts(topic) {
23591
23610
  function vaultFormBlocksOverlaySwitch(state) {
23592
23611
  return state.overlay === "vault" && (state.vaultMode === "value" || state.vaultMode === "description");
23593
23612
  }
23613
+ async function runTerminalVaultCommand(client, commandLine) {
23614
+ const match = commandLine.trim().match(/^\/vault(?:@\w+)?(?:\s+([^\s]+))?/i);
23615
+ const subcommand = match?.[1]?.toLowerCase();
23616
+ if (!subcommand)
23617
+ return { kind: "open-manager" };
23618
+ if (subcommand !== "list" && subcommand !== "set" && subcommand !== "del") {
23619
+ return { kind: "notice", notice: TERMINAL_VAULT_USAGE };
23620
+ }
23621
+ if (!client.runVaultCommand) {
23622
+ return { kind: "notice", notice: "Vault commands are unavailable for this client." };
23623
+ }
23624
+ try {
23625
+ const output = await client.runVaultCommand(commandLine);
23626
+ return {
23627
+ kind: "notice",
23628
+ notice: output?.replace(/\s+/g, " ").trim() || "Vault command completed."
23629
+ };
23630
+ } catch {
23631
+ return { kind: "notice", notice: "Vault command failed. Check the node connection." };
23632
+ }
23633
+ }
23594
23634
  function runtimeEventWaitsForMessageLoad(event) {
23595
23635
  if (event.type === "message" || event.type === "message-updated")
23596
23636
  return true;
@@ -23911,7 +23951,7 @@ class TerminalApp {
23911
23951
  this.#plainFrameLines = stripAnsi(baseFrame).split(`
23912
23952
  `);
23913
23953
  const frame = this.#selection ? highlightScreenSelection(baseFrame, this.#selection) : baseFrame;
23914
- const patch = this.#screen.update(frame);
23954
+ const patch = this.#screen.update(frame, rows);
23915
23955
  const cursor = rendered.cursor ? placeTerminalCursor(rendered.cursor) : "";
23916
23956
  if (patch || cursor)
23917
23957
  process.stdout.write(`${patch}${cursor}`);
@@ -24141,7 +24181,7 @@ class TerminalApp {
24141
24181
  return;
24142
24182
  }
24143
24183
  if (this.#state.overlay === "vault") {
24144
- if (this.#state.vaultMode === "list" || this.#state.vaultMode === "confirm-delete") {
24184
+ if (this.#state.vaultMode === "confirm-delete") {
24145
24185
  this.#handleVaultListInput(chunk);
24146
24186
  return;
24147
24187
  }
@@ -24259,6 +24299,17 @@ class TerminalApp {
24259
24299
  const text2 = this.#input.text.trim();
24260
24300
  if (!text2)
24261
24301
  return;
24302
+ const inVaultCommandScreen = this.#state.overlay === "vault" && this.#state.vaultMode === "list";
24303
+ if (inVaultCommandScreen && !isVaultCommandLine(text2)) {
24304
+ this.#input.setText("");
24305
+ this.#syncInput();
24306
+ this.#state = {
24307
+ ...this.#state,
24308
+ vaultNotice: "Use /vault set KEY VALUE or /vault del KEY."
24309
+ };
24310
+ this.#queueRender();
24311
+ return;
24312
+ }
24262
24313
  if (this.#state.creatingTopic) {
24263
24314
  this.#input.setText("");
24264
24315
  this.#syncInput();
@@ -24272,9 +24323,10 @@ class TerminalApp {
24272
24323
  }
24273
24324
  this.#input.setText("");
24274
24325
  this.#syncInput();
24326
+ const keepVaultOpen = this.#state.overlay === "vault";
24275
24327
  this.#state = {
24276
24328
  ...this.#state,
24277
- overlay: null,
24329
+ overlay: keepVaultOpen ? "vault" : null,
24278
24330
  notice: undefined
24279
24331
  };
24280
24332
  if (text2.startsWith("/")) {
@@ -24318,12 +24370,15 @@ class TerminalApp {
24318
24370
  }
24319
24371
  async#runCommand(commandLine) {
24320
24372
  if (isVaultCommandLine(commandLine)) {
24321
- if (commandLine.trim().toLowerCase() !== "/vault") {
24322
- this.#state = { ...this.#state, notice: "Use /vault to open the Vault manager." };
24373
+ const outcome = await runTerminalVaultCommand(this.#client, commandLine);
24374
+ if (outcome.kind === "open-manager")
24375
+ await this.#openVault();
24376
+ else if (this.#state.overlay === "vault")
24377
+ await this.#openVault(outcome.notice);
24378
+ else {
24379
+ this.#state = { ...this.#state, notice: outcome.notice };
24323
24380
  this.#queueRender();
24324
- return;
24325
24381
  }
24326
- await this.#openVault();
24327
24382
  return;
24328
24383
  }
24329
24384
  const [command = "", ...args] = commandLine.slice(1).trim().split(/\s+/);
@@ -24623,8 +24678,8 @@ class TerminalApp {
24623
24678
  };
24624
24679
  this.#queueRender();
24625
24680
  }
24626
- async#openVault() {
24627
- if (!this.#client.listVaultEntries || !this.#client.saveVaultEntry || !this.#client.deleteVaultEntry) {
24681
+ async#openVault(vaultNotice) {
24682
+ if (!this.#client.listVaultEntries || !this.#client.runVaultCommand) {
24628
24683
  this.#state = { ...this.#state, notice: "Vault management is unavailable for this client." };
24629
24684
  this.#queueRender();
24630
24685
  return;
@@ -24642,7 +24697,7 @@ class TerminalApp {
24642
24697
  vaultDraftKey: undefined,
24643
24698
  vaultDraftDescription: "",
24644
24699
  vaultEditing: false,
24645
- vaultNotice: undefined
24700
+ vaultNotice
24646
24701
  };
24647
24702
  } catch (error) {
24648
24703
  this.#state = {
@@ -24654,78 +24709,21 @@ class TerminalApp {
24654
24709
  }
24655
24710
  #handleVaultListInput(chunk) {
24656
24711
  if (this.#state.vaultMode === "confirm-delete") {
24657
- const key2 = chunk.toLowerCase();
24658
- if (CONFIRM_KEYS.has(key2))
24712
+ const key = chunk.toLowerCase();
24713
+ if (CONFIRM_KEYS.has(key))
24659
24714
  this.#deleteSelectedVaultEntry();
24660
- else if (CANCEL_KEYS.has(key2) || chunk === "\x1B") {
24715
+ else if (CANCEL_KEYS.has(key) || chunk === "\x1B") {
24661
24716
  this.#state = { ...this.#state, vaultMode: "list", vaultNotice: undefined };
24662
24717
  this.#queueRender();
24663
24718
  }
24664
24719
  return;
24665
24720
  }
24666
- const key = chunk.toLowerCase();
24667
- if (chunk === "\x1B[A")
24668
- this.#moveVaultPicker(-1);
24669
- else if (chunk === "\x1B[B")
24670
- this.#moveVaultPicker(1);
24671
- else if (key === "n" || key === "a")
24672
- this.#beginVaultAdd();
24673
- else if (chunk === "\r" || key === "e")
24674
- this.#beginVaultEdit();
24675
- else if (key === "d" || chunk === "\x1B[3~")
24676
- this.#requestVaultDelete();
24677
- else if (chunk === "\x1B") {
24721
+ if (chunk === "\x1B") {
24678
24722
  this.#vaultDraftValue = "";
24679
24723
  this.#state = { ...this.#state, overlay: null, vaultNotice: undefined };
24680
24724
  this.#queueRender();
24681
24725
  }
24682
24726
  }
24683
- #moveVaultPicker(delta) {
24684
- const count = this.#state.vaultEntries.length;
24685
- if (count === 0)
24686
- return;
24687
- this.#state = {
24688
- ...this.#state,
24689
- vaultPickerIndex: (this.#state.vaultPickerIndex + delta + count) % count,
24690
- vaultNotice: undefined
24691
- };
24692
- this.#queueRender();
24693
- }
24694
- #beginVaultAdd() {
24695
- this.#vaultDraftValue = "";
24696
- this.#state = {
24697
- ...this.#state,
24698
- vaultMode: "key",
24699
- vaultDraftKey: undefined,
24700
- vaultDraftDescription: "",
24701
- vaultEditing: false,
24702
- vaultNotice: undefined
24703
- };
24704
- this.#replaceInput("");
24705
- }
24706
- #beginVaultEdit() {
24707
- const selected = this.#state.vaultEntries[this.#state.vaultPickerIndex];
24708
- if (!selected) {
24709
- this.#beginVaultAdd();
24710
- return;
24711
- }
24712
- this.#vaultDraftValue = "";
24713
- this.#state = {
24714
- ...this.#state,
24715
- vaultMode: "value",
24716
- vaultDraftKey: selected.key,
24717
- vaultDraftDescription: selected.description,
24718
- vaultEditing: true,
24719
- vaultNotice: undefined
24720
- };
24721
- this.#replaceInput("");
24722
- }
24723
- #requestVaultDelete() {
24724
- if (!this.#state.vaultEntries[this.#state.vaultPickerIndex])
24725
- return;
24726
- this.#state = { ...this.#state, vaultMode: "confirm-delete", vaultNotice: undefined };
24727
- this.#queueRender();
24728
- }
24729
24727
  #cancelVaultForm() {
24730
24728
  this.#vaultDraftValue = "";
24731
24729
  this.#input.setText("");
@@ -25177,13 +25175,14 @@ class TerminalApp {
25177
25175
  await this.#client.stop();
25178
25176
  }
25179
25177
  }
25180
- var ENTER_ALT_SCREEN = "\x1B]11;#0a0b0f\x07\x1B[?1049h\x1B[48;2;10;11;15m\x1B[2J\x1B[H\x1B[?25l\x1B[?2004h\x1B[?1002h\x1B[?1006h", EXIT_ALT_SCREEN = "\x1B[0m\x1B[?1006l\x1B[?1002l\x1B[?2004l\x1B[?25h\x1B[?1049l\x1B]111\x07", NEW_TOPIC_KEYS, DELETE_TOPIC_KEYS, CONFIRM_KEYS, CANCEL_KEYS, MESSAGE_MUTATING_AI_STATUS_KINDS, SGR_MOUSE_PATTERN;
25178
+ var ENTER_ALT_SCREEN = "\x1B]11;#0a0b0f\x07\x1B[?1049h\x1B[48;2;10;11;15m\x1B[2J\x1B[H\x1B[?25l\x1B[?2004h\x1B[?1002h\x1B[?1006h", EXIT_ALT_SCREEN = "\x1B[0m\x1B[?7h\x1B[?1006l\x1B[?1002l\x1B[?2004l\x1B[?25h\x1B[?1049l\x1B]111\x07", NEW_TOPIC_KEYS, DELETE_TOPIC_KEYS, CONFIRM_KEYS, CANCEL_KEYS, MESSAGE_MUTATING_AI_STATUS_KINDS, SGR_MOUSE_PATTERN, TERMINAL_VAULT_USAGE = "Usage: /vault, /vault list, /vault set KEY VALUE [description], or /vault del KEY";
25181
25179
  var init_app = __esm(async () => {
25182
25180
  await init_src();
25183
25181
  await init_client();
25184
25182
  init_commands();
25185
25183
  init_path_suggest();
25186
25184
  await init_render();
25185
+ init_screen_renderer();
25187
25186
  await init_selection();
25188
25187
  await init_state2();
25189
25188
  NEW_TOPIC_KEYS = new Set(["n", "\u315C"]);
@@ -27435,9 +27434,13 @@ var init_src7 = __esm(async () => {
27435
27434
  var exports_cli2 = {};
27436
27435
  __export(exports_cli2, {
27437
27436
  startTelegramFromEnv: () => startTelegramFromEnv,
27438
- runTelegramCli: () => runTelegramCli
27437
+ runTelegramCli: () => runTelegramCli,
27438
+ installTelegramNodeFileHooks: () => installTelegramNodeFileHooks
27439
27439
  });
27440
27440
  import TelegramBot from "node-telegram-bot-api";
27441
+ function installTelegramNodeFileHooks() {
27442
+ setFileHooks(nodeFileStore.hooks);
27443
+ }
27441
27444
  function startTelegramFromEnv(options = {}) {
27442
27445
  const token = process.env.TELEGRAM_BOT_TOKEN?.trim();
27443
27446
  if (!token)
@@ -27500,6 +27503,7 @@ async function runTelegramCli(args = process.argv.slice(2)) {
27500
27503
  throw new Error("TELEGRAM_BOT_TOKEN is required");
27501
27504
  }
27502
27505
  const initialNode = await ensureCanonicalNode();
27506
+ installTelegramNodeFileHooks();
27503
27507
  const singleton = await waitForRequiredRuntimeProcessLease("adapter:telegram", {
27504
27508
  workloadName: "Telegram adapter",
27505
27509
  onLost: () => {
@@ -33091,4 +33095,4 @@ switch (command) {
33091
33095
  }
33092
33096
  }
33093
33097
 
33094
- //# debugId=4312707E3B05EF9564756E2164756E21
33098
+ //# debugId=CFBE3BB53C71112664756E2164756E21