@ai-ecoverse/slicc-spectrum 1.109.1 → 1.111.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/slicc-ui.js CHANGED
@@ -17944,14 +17944,14 @@ var resolver = {
17944
17944
  };
17945
17945
  var string = initializeFactory("string");
17946
17946
  var text = initializeFactory("text");
17947
- function initializeFactory(field) {
17947
+ function initializeFactory(field3) {
17948
17948
  return {
17949
- resolveAll: createResolver(field === "text" ? resolveAllLineSuffixes : void 0),
17949
+ resolveAll: createResolver(field3 === "text" ? resolveAllLineSuffixes : void 0),
17950
17950
  tokenize: initializeText
17951
17951
  };
17952
17952
  function initializeText(effects) {
17953
17953
  const self2 = this;
17954
- const constructs2 = this.parser.constructs[field];
17954
+ const constructs2 = this.parser.constructs[field3];
17955
17955
  const text4 = effects.attempt(constructs2, start2, notText);
17956
17956
  return start2;
17957
17957
  function start2(code3) {
@@ -25063,7 +25063,7 @@ var File = class {
25063
25063
  const sessionAnnotationsCurrent = editSessionAnnotations?.current;
25064
25064
  let acceptedFile;
25065
25065
  let failed2 = false;
25066
- let failure2;
25066
+ let failure3;
25067
25067
  if (editor == null) throw new Error("File.__completeEditSession: editor is required for completion");
25068
25068
  const completedFile = { ...editSessionFile };
25069
25069
  const event2 = {
@@ -25082,7 +25082,7 @@ var File = class {
25082
25082
  }
25083
25083
  } catch (error) {
25084
25084
  failed2 = true;
25085
- failure2 = error;
25085
+ failure3 = error;
25086
25086
  }
25087
25087
  const settledFile = installResult && acceptedFile != null ? acceptedFile : inputFile;
25088
25088
  const settledAnnotations = installResult && acceptedFile != null ? sessionAnnotationsCurrent ?? inputAnnotations : inputAnnotations;
@@ -25095,7 +25095,7 @@ var File = class {
25095
25095
  this.fileRenderer.endEditSession(settledFile);
25096
25096
  if (areFileTargetsEqual(this.getRenderedFile(), settledFile)) this.adoptRenderData(settledFile);
25097
25097
  if (installResult && this.fileContainer != null) this.rerender();
25098
- if (failed2) throw failure2;
25098
+ if (failed2) throw failure3;
25099
25099
  }
25100
25100
  applyDocumentChange(textDocument, newLineAnnotations) {
25101
25101
  const editSessionFile = this.editSession?.file;
@@ -31513,7 +31513,7 @@ var FileDiff = class {
31513
31513
  let acceptedOldFile = null;
31514
31514
  let acceptedNewFile = null;
31515
31515
  let failed2 = false;
31516
- let failure2;
31516
+ let failure3;
31517
31517
  if (editor == null) throw new Error("FileDiff.__completeEditSession: editor is required for completion");
31518
31518
  const completedDiff = cloneFileDiffMetadata(editSessionDiff);
31519
31519
  const newFile = {
@@ -31544,7 +31544,7 @@ var FileDiff = class {
31544
31544
  }
31545
31545
  } catch (error) {
31546
31546
  failed2 = true;
31547
- failure2 = error;
31547
+ failure3 = error;
31548
31548
  }
31549
31549
  if (installResult && acceptedDiff != null) {
31550
31550
  if (this.additionFile != null) {
@@ -31559,7 +31559,7 @@ var FileDiff = class {
31559
31559
  lineAnnotations: installResult && acceptedDiff != null ? sessionAnnotationsCurrent ?? inputAnnotations : inputAnnotations
31560
31560
  };
31561
31561
  if (installResult && this.fileContainer != null) this.rerender();
31562
- if (failed2) throw failure2;
31562
+ if (failed2) throw failure3;
31563
31563
  }
31564
31564
  /**
31565
31565
  * Run the session-end recompute: restore recompute-shaped hunks (a
@@ -33411,14 +33411,14 @@ function errorCard(item2, handlers) {
33411
33411
  const signing = login?.state === "signing-in" && login.window;
33412
33412
  const text4 = resolved ? signedIn : signing ? signInText(login.waited) : item2.text;
33413
33413
  const title2 = resolved && login.provider ? `Signed in to ${login.provider} again.` : item2.title;
33414
- const failure2 = login?.state === "idle" ? login.error : void 0;
33414
+ const failure3 = login?.state === "idle" ? login.error : void 0;
33415
33415
  return b`<div class="error-card" role=${resolved ? A : "alert"} aria-atomic=${resolved ? A : "false"} data-id=${id || A} data-login=${login?.state ?? A}>
33416
33416
  ${resolved ? b`<swc-icon-info-circle class="icon" size="s" aria-hidden="true"></swc-icon-info-circle>` : b`<swc-icon-alert-diamond class="icon" size="s" aria-hidden="true"></swc-icon-alert-diamond>`}
33417
33417
  ${resolved ? A : b`<span class="sr">Error: </span>`}<span class="lead">${title2}</span>
33418
33418
  ${text4 ? b`<span class="detail" role=${login ? "status" : A}>${text4}</span>` : A}
33419
33419
  ${fix ? b`<div class="fix" aria-live="off">${fixButton(fix, item2, handlers, login)}</div>` : A}
33420
33420
  ${signing ? signInDetails(item2.account, login.signIn, login.copied, (code3) => handlers.copySignIn?.(item2.account, id, code3), "s") : A}
33421
- ${failure2 ? b`<div class="help" data-error="login"><sp-help-text size="s" variant="negative" icon>${failure2}</sp-help-text><swc-action-button size="s" quiet data-action="settings" @click=${() => handlers.action("settings", item2.id, item2.account)}>Open settings</swc-action-button></div>` : A}
33421
+ ${failure3 ? b`<div class="help" data-error="login"><sp-help-text size="s" variant="negative" icon>${failure3}</sp-help-text><swc-action-button size="s" quiet data-action="settings" @click=${() => handlers.action("settings", item2.id, item2.account)}>Open settings</swc-action-button></div>` : A}
33422
33422
  </div>`;
33423
33423
  }
33424
33424
  function time(at) {
@@ -33620,8 +33620,8 @@ function question(item2, handlers) {
33620
33620
  } else {
33621
33621
  const submit = (event2) => {
33622
33622
  event2.preventDefault();
33623
- const field = event2.currentTarget.querySelector("input");
33624
- if (field.value.trim()) answer(field.value.trim());
33623
+ const field3 = event2.currentTarget.querySelector("input");
33624
+ if (field3.value.trim()) answer(field3.value.trim());
33625
33625
  };
33626
33626
  body2 = b`<form class="options" @submit=${submit}>
33627
33627
  <input class="input" type=${item2.kind === "email" ? "email" : item2.kind === "number" ? "number" : item2.kind === "date" ? "date" : "text"} aria-label=${item2.question} ?disabled=${handlers.readOnly} />
@@ -34891,8 +34891,8 @@ function failureText(error) {
34891
34891
  const text4 = isVaultFailure(error) ? codeTexts[error.code] : void 0;
34892
34892
  return text4 ?? (error instanceof Error ? error.message : "The vault did not answer");
34893
34893
  }
34894
- function fieldOf(error, field) {
34895
- return isVaultFailure(error) && error.code === "EINVAL" ? field : null;
34894
+ function fieldOf(error, field3) {
34895
+ return isVaultFailure(error) && error.code === "EINVAL" ? field3 : null;
34896
34896
  }
34897
34897
  function away(vault) {
34898
34898
  const state2 = vault.availability?.() ?? (vault.status() ? "ready" : "waiting");
@@ -35814,12 +35814,12 @@ var SliccComposer = class extends ThemedElement {
35814
35814
  this.renderRoot.querySelector('.item[aria-selected="true"]')?.scrollIntoView({ block: "nearest" });
35815
35815
  }
35816
35816
  #wire() {
35817
- const field = this.#field;
35818
- void field.updateComplete.then(() => {
35817
+ const field3 = this.#field;
35818
+ void field3.updateComplete.then(() => {
35819
35819
  const popover = this.renderRoot.querySelector("swc-popover");
35820
35820
  if (popover) {
35821
35821
  popover.triggerElement = null;
35822
- popover.triggerElement = field.shadowRoot.querySelector(
35822
+ popover.triggerElement = field3.shadowRoot.querySelector(
35823
35823
  ".swc-PromptField-upload"
35824
35824
  );
35825
35825
  }
@@ -36030,16 +36030,16 @@ ${this.value}` : text4;
36030
36030
  text4 === null || text4 === void 0 ? { ...base, kind: "file", size: 0, error: "Could not read the file" } : { ...base, kind: "text", size: text4.length, text: text4 }
36031
36031
  ];
36032
36032
  }
36033
- async shareSecret(name, field = null) {
36033
+ async shareSecret(name, field3 = null) {
36034
36034
  const clean = name.trim().toUpperCase().replace(/[^A-Z0-9_]/g, "_");
36035
36035
  if (this.sharing) return;
36036
36036
  if (!clean) {
36037
- if (field) this.#refuse("Enter a name", "name", true);
36037
+ if (field3) this.#refuse("Enter a name", "name", true);
36038
36038
  return;
36039
36039
  }
36040
- const value = field ? take(field) : "";
36040
+ const value = field3 ? take(field3) : "";
36041
36041
  const vault = this.model?.vault;
36042
- if (field && vault?.put && !await this.#store(vault, clean, value)) return;
36042
+ if (field3 && vault?.put && !await this.#store(vault, clean, value)) return;
36043
36043
  this.#refuse(null);
36044
36044
  this.attachments = [
36045
36045
  ...this.attachments,
@@ -36053,12 +36053,12 @@ ${this.value}` : text4;
36053
36053
  ];
36054
36054
  this.popup = null;
36055
36055
  }
36056
- #refuse(text4, field = null, focus = false) {
36056
+ #refuse(text4, field3 = null, focus = false) {
36057
36057
  this.secretError = text4;
36058
- this.secretField = text4 ? field : null;
36059
- if (focus && text4 && field)
36058
+ this.secretField = text4 ? field3 : null;
36059
+ if (focus && text4 && field3)
36060
36060
  void this.updateComplete.then(
36061
- () => this.renderRoot.querySelector(`form.secret input[name=${field}]`)?.focus()
36061
+ () => this.renderRoot.querySelector(`form.secret input[name=${field3}]`)?.focus()
36062
36062
  );
36063
36063
  }
36064
36064
  async #store(vault, clean, value) {
@@ -36655,6 +36655,93 @@ function dipsOf(node2) {
36655
36655
  return null;
36656
36656
  }
36657
36657
 
36658
+ // src/app/model-picker.ts
36659
+ var searchable = 5;
36660
+ var field = "sp-search[data-action=filter-models]";
36661
+ var modelFilterCss = i`
36662
+ sp-search[data-action='filter-models'] {
36663
+ position: sticky;
36664
+ inset-block-start: 0;
36665
+ z-index: 1;
36666
+ box-sizing: border-box;
36667
+ width: 100%;
36668
+ padding: var(--swc-spacing-75) var(--swc-spacing-100);
36669
+ background: var(--mod-popover-background-color, var(--spectrum-popover-background-color));
36670
+ }
36671
+ `;
36672
+ function matchesModel(option, query) {
36673
+ const text4 = `${option.label} ${option.provider} ${option.id}`.toLowerCase();
36674
+ return query.toLowerCase().split(/\s+/).every((word2) => text4.includes(word2));
36675
+ }
36676
+ function visible(picker) {
36677
+ return [...picker.querySelectorAll("sp-menu-item[value]")].find(
36678
+ (item2) => !item2.hidden
36679
+ );
36680
+ }
36681
+ var ModelFilter = class {
36682
+ #host;
36683
+ #query = "";
36684
+ constructor(host4) {
36685
+ this.#host = host4;
36686
+ }
36687
+ #set(query) {
36688
+ if (query === this.#query) return;
36689
+ this.#query = query;
36690
+ this.#host.requestUpdate();
36691
+ }
36692
+ items(options2) {
36693
+ if (options2.length <= searchable)
36694
+ return b`${options2.map((option) => this.#item(option, false))}`;
36695
+ const shown4 = options2.filter((option) => matchesModel(option, this.#query));
36696
+ return b`<sp-search
36697
+ size="s"
36698
+ data-action="filter-models"
36699
+ label="Filter models"
36700
+ placeholder="Filter models"
36701
+ .value=${this.#query}
36702
+ @input=${(event2) => this.#set(event2.target.value)}
36703
+ @change=${(event2) => event2.stopPropagation()}
36704
+ @submit=${(event2) => event2.preventDefault()}
36705
+ @keydown=${this.#key}
36706
+ ></sp-search>
36707
+ ${options2.map((option) => this.#item(option, !shown4.includes(option)))}
36708
+ ${shown4.length ? A : b`<sp-menu-item disabled data-empty>No matching models</sp-menu-item>`}`;
36709
+ }
36710
+ #item(option, hidden) {
36711
+ return b`<sp-menu-item value=${option.id} ?hidden=${hidden}>${option.label}<span slot="description">${option.provider}</span></sp-menu-item>`;
36712
+ }
36713
+ opened = (event2) => {
36714
+ const search3 = event2.currentTarget.querySelector(field);
36715
+ if (search3) queueMicrotask(() => search3.focus());
36716
+ };
36717
+ closed = () => this.#set("");
36718
+ keys = {
36719
+ capture: true,
36720
+ handleEvent: (event2) => {
36721
+ const picker = event2.currentTarget;
36722
+ const search3 = picker.querySelector(field);
36723
+ if (!search3 || !picker.open) return;
36724
+ if (event2.target === search3) {
36725
+ if (event2.key === "Escape" && this.#query) event2.preventDefault();
36726
+ return;
36727
+ }
36728
+ if (event2.key.trim().length !== 1 || event2.ctrlKey || event2.metaKey || event2.altKey) return;
36729
+ search3.focus();
36730
+ const end = search3.focusElement.value.length;
36731
+ search3.focusElement.setSelectionRange(end, end);
36732
+ }
36733
+ };
36734
+ #key = (event2) => {
36735
+ if (event2.key === "Tab" || event2.key === "Escape" && !event2.defaultPrevented) return;
36736
+ event2.stopPropagation();
36737
+ if (event2.key !== "ArrowDown" && event2.key !== "Enter") return;
36738
+ event2.preventDefault();
36739
+ const first2 = visible(event2.currentTarget.parentElement);
36740
+ if (event2.key === "Enter") first2?.click();
36741
+ else first2?.focus();
36742
+ };
36743
+ };
36744
+
36658
36745
  // src/app/models.ts
36659
36746
  var asked = /* @__PURE__ */ new WeakMap();
36660
36747
  var switched = /* @__PURE__ */ new WeakMap();
@@ -37110,6 +37197,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
37110
37197
  };
37111
37198
  static styles = [
37112
37199
  shared,
37200
+ modelFilterCss,
37113
37201
  fade,
37114
37202
  markdownCss,
37115
37203
  messageCss,
@@ -37352,6 +37440,7 @@ var SliccChat = class _SliccChat extends ThemedElement {
37352
37440
  }
37353
37441
  `
37354
37442
  ];
37443
+ #modelFilter = new ModelFilter(this);
37355
37444
  #licks = new ViewSet(this, "chat:licks");
37356
37445
  #runs = new ViewSet(this, "chat:runs");
37357
37446
  #details = /* @__PURE__ */ new Set();
@@ -37885,8 +37974,8 @@ var SliccChat = class _SliccChat extends ThemedElement {
37885
37974
  }
37886
37975
  const offered = chatModels(model.settings.models());
37887
37976
  return b`${statusLight(agent.status)}
37888
- ${offered.length ? b`<sp-picker size="s" quiet label="Model" value=${agent.model} @change=${(event2) => model.agent.setModel(agent.id, event2.target.value)}>
37889
- ${offered.map((option) => b`<sp-menu-item value=${option.id}>${option.label}<span slot="description">${option.provider}</span></sp-menu-item>`)}
37977
+ ${offered.length ? b`<sp-picker size="s" quiet label="Model" value=${agent.model} @change=${(event2) => model.agent.setModel(agent.id, event2.target.value)} @sp-opened=${this.#modelFilter.opened} @sp-closed=${this.#modelFilter.closed} @keydown=${this.#modelFilter.keys}>
37978
+ ${this.#modelFilter.items(offered)}
37890
37979
  </sp-picker>` : b`<swc-action-button size="s" quiet data-action="set-up-model" @click=${() => this.#action("settings")}>Set up a model</swc-action-button>`}
37891
37980
  <sp-picker size="s" quiet label="Thinking" value=${model.settings.get().thinking} @change=${(event2) => model.settings.update({ thinking: event2.target.value })}>
37892
37981
  <sp-menu-item value="off">No thinking</sp-menu-item>
@@ -41015,9 +41104,9 @@ var defaultGates = {
41015
41104
  messages: ["user", "agent", "cone", "scoop:*", "off"],
41016
41105
  tools: ["user", "agent", "scoop:*"]
41017
41106
  };
41018
- function gateChoice(field, cone, gate) {
41107
+ function gateChoice(field3, cone, gate) {
41019
41108
  if (gate === "scoop:*")
41020
- return cone.scoops.flatMap((name) => gateChoice(field, cone, `scoop:${name}`));
41109
+ return cone.scoops.flatMap((name) => gateChoice(field3, cone, `scoop:${name}`));
41021
41110
  if (gate.startsWith("scoop:")) {
41022
41111
  const name = gate.slice(6);
41023
41112
  return cone.scoops.includes(name) ? [{ value: gate, label: `${name} decides`, description: `The scoop ${name} decides.` }] : [];
@@ -41037,14 +41126,14 @@ function gateChoice(field, cone, gate) {
41037
41126
  off: {
41038
41127
  value: "off",
41039
41128
  label: "No review",
41040
- description: field === "messages" ? "Messages go straight in as follow-ups." : "Tool calls run without review."
41129
+ description: field3 === "messages" ? "Messages go straight in as follow-ups." : "Tool calls run without review."
41041
41130
  }
41042
41131
  };
41043
41132
  return choices[gate] ? [choices[gate]] : [];
41044
41133
  }
41045
- function gateOptions(field, cone, allowed = defaultGates[field]) {
41046
- const options2 = allowed.flatMap((gate) => gateChoice(field, cone, gate)).filter((option, index2, all2) => all2.findIndex(({ value }) => value === option.value) === index2);
41047
- return options2.length ? options2 : gateChoice(field, cone, "user");
41134
+ function gateOptions(field3, cone, allowed = defaultGates[field3]) {
41135
+ const options2 = allowed.flatMap((gate) => gateChoice(field3, cone, gate)).filter((option, index2, all2) => all2.findIndex(({ value }) => value === option.value) === index2);
41136
+ return options2.length ? options2 : gateChoice(field3, cone, "user");
41048
41137
  }
41049
41138
  function defaultGate(options2) {
41050
41139
  return options2.some(({ value }) => value === "user") ? "user" : options2[0].value;
@@ -41189,11 +41278,11 @@ var SliccGuestInvite = class extends i2 {
41189
41278
  get #current() {
41190
41279
  return this.cones.find((cone) => cone.id === this.cone) ?? this.cones[0];
41191
41280
  }
41192
- #options(field, cone) {
41193
- return gateOptions(field, cone, this.port?.gates?.()[field]);
41281
+ #options(field3, cone) {
41282
+ return gateOptions(field3, cone, this.port?.gates?.()[field3]);
41194
41283
  }
41195
- #keep(gate, field, cone) {
41196
- const options2 = this.#options(field, cone);
41284
+ #keep(gate, field3, cone) {
41285
+ const options2 = this.#options(field3, cone);
41197
41286
  return options2.some((option) => option.value === gate) ? gate : defaultGate(options2);
41198
41287
  }
41199
41288
  #settle() {
@@ -41265,18 +41354,18 @@ var SliccGuestInvite = class extends i2 {
41265
41354
  this.remove();
41266
41355
  if (this.trigger?.isConnected) this.trigger.focus();
41267
41356
  }
41268
- #gate(field, title2, value) {
41269
- const options2 = this.#options(field, this.#current);
41357
+ #gate(field3, title2, value) {
41358
+ const options2 = this.#options(field3, this.#current);
41270
41359
  const chosen = options2.find((option) => option.value === value);
41271
- const id = `guest-${field}`;
41360
+ const id = `guest-${field3}`;
41272
41361
  return b`<div class="field">
41273
41362
  <sp-field-label for=${id} size="m">${title2}</sp-field-label>
41274
- <sp-picker id=${id} size="m" label=${title2} data-action=${`guest-${field}`} .value=${l(value)} ?disabled=${this.pending} @change=${(event2) => {
41275
- this[field] = this.#pick(event2);
41363
+ <sp-picker id=${id} size="m" label=${title2} data-action=${`guest-${field3}`} .value=${l(value)} ?disabled=${this.pending} @change=${(event2) => {
41364
+ this[field3] = this.#pick(event2);
41276
41365
  }}>
41277
41366
  ${options2.map((option) => b`<sp-menu-item value=${option.value}>${option.label}<span slot="description">${option.description}</span></sp-menu-item>`)}
41278
41367
  </sp-picker>
41279
- <sp-help-text size="m" data-help=${field}>${chosen.description}</sp-help-text>
41368
+ <sp-help-text size="m" data-help=${field3}>${chosen.description}</sp-help-text>
41280
41369
  </div>`;
41281
41370
  }
41282
41371
  #form() {
@@ -42862,11 +42951,11 @@ var SliccNetwork = class extends ModelElement {
42862
42951
  }
42863
42952
  async #submitPair(event2, port) {
42864
42953
  event2.preventDefault();
42865
- const field = this.renderRoot.querySelector("#pair-url");
42866
- const url = field.value.trim();
42954
+ const field3 = this.renderRoot.querySelector("#pair-url");
42955
+ const url = field3.value.trim();
42867
42956
  if (!url || this.pairBusy || !port.pairComputer) return;
42868
42957
  if (await this.#pairAct("pair", () => port.pairComputer?.(url))) {
42869
- field.value = "";
42958
+ field3.value = "";
42870
42959
  this.pairFilled = false;
42871
42960
  }
42872
42961
  }
@@ -42935,11 +43024,11 @@ var SliccNetwork = class extends ModelElement {
42935
43024
  #submitKey(event2, port) {
42936
43025
  event2.preventDefault();
42937
43026
  if (this.busy) return;
42938
- const field = event2.currentTarget.querySelector(
43027
+ const field3 = event2.currentTarget.querySelector(
42939
43028
  "sp-textfield"
42940
43029
  );
42941
- const key = field.value.trim();
42942
- field.value = "";
43030
+ const key = field3.value.trim();
43031
+ field3.value = "";
42943
43032
  if (key) void this.#tailnet("key", () => port.submitAuthKey?.(key));
42944
43033
  }
42945
43034
  #sendKey(event2) {
@@ -49363,9 +49452,9 @@ var SliccApp = class extends ThemedElement {
49363
49452
  #railButton(item2, side) {
49364
49453
  const changes2 = item2.id === "changes" ? this.#changes() : 0;
49365
49454
  const driven = item2.id === "browser" && !!this.model?.browser.list().some((tab) => tab.controlled);
49366
- const visible2 = shown2(this.dock, item2.id);
49367
- const label = `${visible2 ? `${item2.title}, shown` : `Open ${item2.title}`}${changes2 ? `, ${changeCount(changes2)}` : driven ? ", a tab is in use" : ""}`;
49368
- const button = u21`<swc-action-button id=${`rail-${item2.id}`} class=${visible2 ? "selected" : ""} quiet size="m" accessible-label=${label} data-surface=${item2.id} data-cone=${o2(item2.cone)} ?data-visible=${visible2} @click=${(event2) => this.#railClick(event2, item2.id)}>${railIcon(item2.icon)}</swc-action-button>`;
49455
+ const visible3 = shown2(this.dock, item2.id);
49456
+ const label = `${visible3 ? `${item2.title}, shown` : `Open ${item2.title}`}${changes2 ? `, ${changeCount(changes2)}` : driven ? ", a tab is in use" : ""}`;
49457
+ const button = u21`<swc-action-button id=${`rail-${item2.id}`} class=${visible3 ? "selected" : ""} quiet size="m" accessible-label=${label} data-surface=${item2.id} data-cone=${o2(item2.cone)} ?data-visible=${visible3} @click=${(event2) => this.#railClick(event2, item2.id)}>${railIcon(item2.icon)}</swc-action-button>`;
49369
49458
  const tooltip = b`<swc-tooltip for=${`rail-${item2.id}`} placement=${{ left: "end", right: "start", bottom: "top" }[side]}>${item2.title}</swc-tooltip>`;
49370
49459
  return changes2 ? b`<span class="badged">${button}<swc-badge size="s" variant="neutral" aria-hidden="true">${changes2}</swc-badge></span>${tooltip}` : driven ? b`<span class="badged">${button}<span class="dot" data-driven aria-hidden="true"></span></span>${tooltip}` : b`${button}${tooltip}`;
49371
49460
  }
@@ -50348,7 +50437,7 @@ var SliccApprovals = class extends ModelElement {
50348
50437
  const list6 = this.#current();
50349
50438
  const [approval, ...rest] = held2 ? [held2, ...list6.filter(({ id }) => id !== held2.id)] : list6;
50350
50439
  if (!approval) return A;
50351
- const failure2 = this.failure?.id === approval.id ? this.failure.message : "";
50440
+ const failure3 = this.failure?.id === approval.id ? this.failure.message : "";
50352
50441
  const verdict = rulesOf(approval);
50353
50442
  const rules = verdict.certain ?? verdict.maybe;
50354
50443
  const always = approval.kind !== "tray" && approval.always && !deniedSudo(approval) && !rules;
@@ -50364,10 +50453,10 @@ var SliccApprovals = class extends ModelElement {
50364
50453
  ${this.#verdict(approval)}
50365
50454
  ${rules ? b`<div class="rules" data-secret-rules=${rules}><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><p>${verdict.certain ? b`<strong>This changes secret rules.</strong> It names <code>${commandText(rules, false)}</code>, where SLICC keeps which secrets programs may use and where they may be sent.` : b`<strong>This may change secret rules.</strong> SLICC can't tell where <code>${commandText(rules, false)}</code> leads, and it could reach the files where SLICC keeps which secrets programs may use and where they may be sent.`} Allow it only if you asked for this change.</p></div>` : A}
50366
50455
  ${hint2 ? b`<p class="hint">${hint2}</p>` : A}
50367
- ${!failure2 && gate ? b`<p class="hint" data-allow-hint>${gate}</p>` : A}
50368
- ${failure2 ? b`<p class="problem" role="alert" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${failure2}</span></p>` : b`<p class="timer" data-timer>Denied automatically in ${countdown(approval.expiresAt - this.now)}.</p>`}
50456
+ ${!failure3 && gate ? b`<p class="hint" data-allow-hint>${gate}</p>` : A}
50457
+ ${failure3 ? b`<p class="problem" role="alert" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${failure3}</span></p>` : b`<p class="timer" data-timer>Denied automatically in ${countdown(approval.expiresAt - this.now)}.</p>`}
50369
50458
  ${rest.length ? b`<p class="more" data-more>${rest.length === 1 ? "1 more request is waiting." : `${rest.length} more requests are waiting.`}</p>` : A}
50370
- ${this.#actions(approval, !!failure2, always)}
50459
+ ${this.#actions(approval, !!failure3, always)}
50371
50460
  </sp-alert-dialog>`
50372
50461
  );
50373
50462
  }
@@ -51258,11 +51347,11 @@ var SliccBrowser = class extends ModelElement {
51258
51347
  }
51259
51348
  updated() {
51260
51349
  const tab = this.#focused();
51261
- const visible2 = this.#visible();
51262
- this.#settle(visible2 && tab?.controlled && this.model?.browser.watch ? tab.id : null);
51263
- if (visible2 && tab && !this.#ticker)
51350
+ const visible3 = this.#visible();
51351
+ this.#settle(visible3 && tab?.controlled && this.model?.browser.watch ? tab.id : null);
51352
+ if (visible3 && tab && !this.#ticker)
51264
51353
  this.#ticker = setInterval(() => this.requestUpdate(), 1e3);
51265
- if (!(visible2 && tab)) this.#still();
51354
+ if (!(visible3 && tab)) this.#still();
51266
51355
  const list6 = this.renderRoot.querySelector(".actions:not(.last)");
51267
51356
  const last = list6?.lastElementChild?.getAttribute("data-action-id") ?? null;
51268
51357
  if (list6 && this.#anchor !== null) list6.scrollTop = list6.scrollHeight - this.#anchor;
@@ -52277,7 +52366,7 @@ e26("swc-icon-user-settings", o90);
52277
52366
 
52278
52367
  // src/app/memory.ts
52279
52368
  var everyone = "*";
52280
- function visible(memories, scope, tag3, query) {
52369
+ function visible2(memories, scope, tag3, query) {
52281
52370
  const needle = query.trim().toLowerCase();
52282
52371
  return memories.filter(
52283
52372
  (memory) => (scope === everyone || memory.scope === scope) && (tag3 === "all" || (tag3 === "untagged" ? memory.tag === null : memory.tag === tag3)) && (!needle || `${memory.title} ${memory.body} ${memory.section}`.toLowerCase().includes(needle))
@@ -52594,15 +52683,15 @@ var SliccMemory = class extends ModelElement {
52594
52683
  }
52595
52684
  #save(memory) {
52596
52685
  const form = this.renderRoot.querySelector(".editor");
52597
- const field = (name) => form.querySelector(`[name=${name}]`).value.trim();
52598
- if (!field("title")) return;
52599
- const tag3 = field("tag");
52686
+ const field3 = (name) => form.querySelector(`[name=${name}]`).value.trim();
52687
+ if (!field3("title")) return;
52688
+ const tag3 = field3("tag");
52600
52689
  const saved = this.model?.memory.save({
52601
52690
  ...memory.id ? { id: memory.id } : {},
52602
52691
  scope: memory.scope,
52603
- section: field("section") || "Notes",
52604
- title: field("title"),
52605
- body: field("body"),
52692
+ section: field3("section") || "Notes",
52693
+ title: field3("title"),
52694
+ body: field3("body"),
52606
52695
  tag: tag3 !== "none" ? tag3 : null
52607
52696
  });
52608
52697
  this.editing = null;
@@ -52710,7 +52799,7 @@ var SliccMemory = class extends ModelElement {
52710
52799
  const scopes = this.#scopes;
52711
52800
  const scope = this.scope;
52712
52801
  const option = (item2) => b`<sp-menu-item value=${item2.id}>${item2.label}</sp-menu-item>`;
52713
- const shown4 = visible(all2, scope, this.tag, this.query);
52802
+ const shown4 = visible2(all2, scope, this.tag, this.query);
52714
52803
  const total = inScope(all2, scope);
52715
52804
  const filtered = this.tag !== "all" || this.query.trim() !== "";
52716
52805
  const current = scopes.find((item2) => item2.id === scope) ?? null;
@@ -52879,13 +52968,13 @@ var SliccNotices = class extends ModelElement {
52879
52968
  }
52880
52969
  #notice(notice) {
52881
52970
  const pending = this.pending.get(notice.id);
52882
- const failure2 = this.failures.get(notice.id);
52971
+ const failure3 = this.failures.get(notice.id);
52883
52972
  return b`<div class="notice" role="status" data-notice=${notice.id} data-tone=${notice.tone}>
52884
52973
  ${notice.tone === "warning" ? b`<swc-icon-alert-triangle></swc-icon-alert-triangle>` : b`<swc-icon-info-circle></swc-icon-info-circle>`}
52885
52974
  <div class="text">
52886
52975
  <span class="title">${notice.title}</span>
52887
52976
  <p>${notice.body}</p>
52888
- ${failure2 ? b`<p class="problem" data-error><swc-icon-alert-triangle></swc-icon-alert-triangle><span>${failure2}</span></p>` : A}
52977
+ ${failure3 ? b`<p class="problem" data-error><swc-icon-alert-triangle></swc-icon-alert-triangle><span>${failure3}</span></p>` : A}
52889
52978
  ${notice.actions.length ? b`<div class="actions">${notice.actions.map(
52890
52979
  (action) => b`<swc-button size="s" variant="secondary" fill-style="outline" data-action=${action.id} ?pending=${pending === action.id} ?disabled=${!!pending && pending !== action.id} @click=${() => void this.act(notice.id, action.id)}>${action.label}</swc-button>`
52891
52980
  )}</div>` : A}
@@ -53585,19 +53674,19 @@ var SliccSecrets = class extends ThemedElement {
53585
53674
  if (form?.kind === "import") this.importKind = "bundle";
53586
53675
  if (form) void this.updateComplete.then(() => this.#focus());
53587
53676
  }
53588
- #refuse(text4, field = null, focus = false) {
53677
+ #refuse(text4, field3 = null, focus = false) {
53589
53678
  this.problem = text4;
53590
- this.invalid = text4 ? field : null;
53591
- if (focus && text4 && field) void this.updateComplete.then(() => this.#field(field)?.focus());
53679
+ this.invalid = text4 ? field3 : null;
53680
+ if (focus && text4 && field3) void this.updateComplete.then(() => this.#field(field3)?.focus());
53592
53681
  }
53593
53682
  #typed() {
53594
53683
  this.invalid = null;
53595
53684
  }
53596
- #bad(field) {
53597
- return this.invalid === field ? "true" : A;
53685
+ #bad(field3) {
53686
+ return this.invalid === field3 ? "true" : A;
53598
53687
  }
53599
- #described(field) {
53600
- return this.invalid === field ? "error-form" : A;
53688
+ #described(field3) {
53689
+ return this.invalid === field3 ? "error-form" : A;
53601
53690
  }
53602
53691
  #focus() {
53603
53692
  this.renderRoot.querySelector("[data-form] input, [data-form] sp-picker")?.focus();
@@ -53835,8 +53924,8 @@ var SliccSecrets = class extends ThemedElement {
53835
53924
  event2.preventDefault();
53836
53925
  if (!locked && !this.busy) void run();
53837
53926
  }
53838
- #value(label, field = "value") {
53839
- return b`<label class="field"><span>${label}</span><input type="password" autocomplete="off" spellcheck="false" data-field=${field} aria-invalid=${this.#bad(field)} aria-describedby=${this.#described(field)} /></label>`;
53927
+ #value(label, field3 = "value") {
53928
+ return b`<label class="field"><span>${label}</span><input type="password" autocomplete="off" spellcheck="false" data-field=${field3} aria-invalid=${this.#bad(field3)} aria-describedby=${this.#described(field3)} /></label>`;
53840
53929
  }
53841
53930
  #actions(locked, label, action, run) {
53842
53931
  return b`<div class="buttons">
@@ -54325,6 +54414,7 @@ var SliccSettings = class extends ThemedElement {
54325
54414
  };
54326
54415
  #waits = new SignInWaits(() => this.requestUpdate());
54327
54416
  #copies = new SignInCopies(() => this.requestUpdate());
54417
+ #modelFilter = new ModelFilter(this);
54328
54418
  #landing = null;
54329
54419
  #away = false;
54330
54420
  #bases = /* @__PURE__ */ new Map();
@@ -54357,6 +54447,7 @@ var SliccSettings = class extends ThemedElement {
54357
54447
  fieldStyles,
54358
54448
  dialogFrame,
54359
54449
  searchCss,
54450
+ modelFilterCss,
54360
54451
  r(link_default),
54361
54452
  signInCss,
54362
54453
  i`
@@ -54888,13 +54979,13 @@ var SliccSettings = class extends ThemedElement {
54888
54979
  });
54889
54980
  }
54890
54981
  #settingsOf(account, fields) {
54891
- const settable = (account.fields ?? []).filter((field) => field.vaultSetting);
54982
+ const settable = (account.fields ?? []).filter((field3) => field3.vaultSetting);
54892
54983
  if (account.group === "mcp" || !settable.length) return void 0;
54893
54984
  return Object.fromEntries(
54894
- settable.flatMap((field) => {
54895
- const value = fields?.[field.name];
54896
- if (!value || field.customBase && this.#baseOf(value)) return [];
54897
- return [[field.vaultSetting, value]];
54985
+ settable.flatMap((field3) => {
54986
+ const value = fields?.[field3.name];
54987
+ if (!value || field3.customBase && this.#baseOf(value)) return [];
54988
+ return [[field3.vaultSetting, value]];
54898
54989
  })
54899
54990
  );
54900
54991
  }
@@ -54907,17 +54998,17 @@ var SliccSettings = class extends ThemedElement {
54907
54998
  #keyOptional(account) {
54908
54999
  const vault = this.#vault(account);
54909
55000
  const fields = account.fields ?? [];
54910
- if (!vault || !fields.some((field) => field.vaultSetting || field.customBase)) return false;
54911
- if (fields.some((field) => field.vaultSetting) && !vault.settings) return false;
55001
+ if (!vault || !fields.some((field3) => field3.vaultSetting || field3.customBase)) return false;
55002
+ if (fields.some((field3) => field3.vaultSetting) && !vault.settings) return false;
54912
55003
  return !!this.#record(account);
54913
55004
  }
54914
55005
  #refused(account, message, keyed2) {
54915
- const field = (account.fields ?? []).find(
55006
+ const field3 = (account.fields ?? []).find(
54916
55007
  (candidate) => [candidate.vaultSetting, candidate.name, candidate.label].some(
54917
55008
  (word2) => word2 && words(message, word2)
54918
55009
  )
54919
55010
  );
54920
- if (field) this.#refuse(account.id, field.name, message);
55011
+ if (field3) this.#refuse(account.id, field3.name, message);
54921
55012
  else if (keyed2) this.#refuse(account.id, "value", message);
54922
55013
  else this.failure = { id: account.id, message };
54923
55014
  }
@@ -54929,14 +55020,14 @@ var SliccSettings = class extends ThemedElement {
54929
55020
  return void 0;
54930
55021
  }
54931
55022
  }
54932
- #oldBase(account, field) {
54933
- return this.#baseOf(field.value) ?? this.#bases.get(`${account.id} ${field.name}`);
55023
+ #oldBase(account, field3) {
55024
+ return this.#baseOf(field3.value) ?? this.#bases.get(`${account.id} ${field3.name}`);
54934
55025
  }
54935
55026
  #baseChanges(account, fields) {
54936
- return (account.fields ?? []).filter((field) => field.customBase).map((field) => ({
54937
- field: field.name,
54938
- url: this.#baseOf(fields?.[field.name]),
54939
- old: this.#oldBase(account, field)
55027
+ return (account.fields ?? []).filter((field3) => field3.customBase).map((field3) => ({
55028
+ field: field3.name,
55029
+ url: this.#baseOf(fields?.[field3.name]),
55030
+ old: this.#oldBase(account, field3)
54940
55031
  })).filter((change) => change.url !== change.old);
54941
55032
  }
54942
55033
  #modelChange(name, changes2, from, to) {
@@ -54962,8 +55053,8 @@ var SliccSettings = class extends ThemedElement {
54962
55053
  await live?.endpoints?.(forward);
54963
55054
  } catch (error) {
54964
55055
  this.#busy(id, false);
54965
- const field = changes2.find((change) => change.url) ?? changes2[0];
54966
- if (this.model === model) this.#refuse(id, field.field, failureText(error));
55056
+ const field3 = changes2.find((change) => change.url) ?? changes2[0];
55057
+ if (this.model === model) this.#refuse(id, field3.field, failureText(error));
54967
55058
  return;
54968
55059
  }
54969
55060
  if (this.model !== model) {
@@ -54987,35 +55078,35 @@ var SliccSettings = class extends ThemedElement {
54987
55078
  }
54988
55079
  #placeFailure(account, fields) {
54989
55080
  const message = this.failure.message;
54990
- const field = (account.fields ?? []).find(
55081
+ const field3 = (account.fields ?? []).find(
54991
55082
  (candidate) => candidate.customBase && !!fields?.[candidate.name] && [candidate.name, candidate.label, "https", "url", "port", "userinfo"].some(
54992
55083
  (word2) => words(message, word2)
54993
55084
  )
54994
55085
  );
54995
- if (!field) return;
55086
+ if (!field3) return;
54996
55087
  this.failure = null;
54997
- this.#refuse(account.id, field.name, message);
55088
+ this.#refuse(account.id, field3.name, message);
54998
55089
  }
54999
- #refuse(id, field, message) {
55000
- this.problem = { id, field, message };
55090
+ #refuse(id, field3, message) {
55091
+ this.problem = { id, field: field3, message };
55001
55092
  void this.updateComplete.then(
55002
55093
  () => this.renderRoot.querySelector(
55003
- field === "value" ? ".key input[data-field=value]" : `.key [data-account-field="${field}"]`
55094
+ field3 === "value" ? ".key input[data-field=value]" : `.key [data-account-field="${field3}"]`
55004
55095
  )?.focus()
55005
55096
  );
55006
55097
  }
55007
55098
  #fields(form, account) {
55008
55099
  if (!account.fields?.length) return void 0;
55009
55100
  const values = {};
55010
- for (const field of account.fields) {
55011
- const input = form.querySelector(`[data-account-field="${field.name}"]`);
55101
+ for (const field3 of account.fields) {
55102
+ const input = form.querySelector(`[data-account-field="${field3.name}"]`);
55012
55103
  const value = input.value.trim();
55013
- if (value) values[field.name] = value;
55014
- else if (field.required && field.options?.length !== 0) {
55104
+ if (value) values[field3.name] = value;
55105
+ else if (field3.required && field3.options?.length !== 0) {
55015
55106
  this.#refuse(
55016
55107
  account.id,
55017
- field.name,
55018
- field.options ? `Select a ${field.label.toLowerCase()}.` : `${field.label} can\u2019t be empty`
55108
+ field3.name,
55109
+ field3.options ? `Select a ${field3.label.toLowerCase()}.` : `${field3.label} can\u2019t be empty`
55019
55110
  );
55020
55111
  return null;
55021
55112
  }
@@ -55058,7 +55149,7 @@ var SliccSettings = class extends ThemedElement {
55058
55149
  this.failure = null;
55059
55150
  this.problem = null;
55060
55151
  this.filled = new Set(
55061
- (account.fields ?? []).filter((field) => field.options || field.value?.trim()).map((field) => field.name)
55152
+ (account.fields ?? []).filter((field3) => field3.options || field3.value?.trim()).map((field3) => field3.name)
55062
55153
  );
55063
55154
  this.entering = account.id;
55064
55155
  void this.updateComplete.then(() => this.focusOn(".key sp-textfield", ".key input"));
@@ -55080,9 +55171,9 @@ var SliccSettings = class extends ThemedElement {
55080
55171
  if (fields2 !== null && !this.pending.has(account.id)) void this.keep(account, value, fields2);
55081
55172
  return;
55082
55173
  }
55083
- const field = form.querySelector("sp-textfield");
55084
- const secret = field.value.trim();
55085
- field.value = "";
55174
+ const field3 = form.querySelector("sp-textfield");
55175
+ const secret = field3.value.trim();
55176
+ field3.value = "";
55086
55177
  const fields = this.#fields(form, account);
55087
55178
  if (secret && fields !== null) void this.#connectBases(account, secret, fields);
55088
55179
  }
@@ -55165,67 +55256,67 @@ var SliccSettings = class extends ThemedElement {
55165
55256
  this.failure = null;
55166
55257
  this.problem = null;
55167
55258
  }
55168
- #problem(account, field, icon = true) {
55259
+ #problem(account, field3, icon = true) {
55169
55260
  const problem = this.problem;
55170
- if (problem?.id !== account.id || problem.field !== field) return A;
55261
+ if (problem?.id !== account.id || problem.field !== field3) return A;
55171
55262
  return b`<div class="problem" id="key-problem" role="alert">
55172
55263
  ${icon ? b`<swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>` : A}
55173
55264
  <span>${problem.message}</span>
55174
55265
  </div>`;
55175
55266
  }
55176
- #described(account, field) {
55177
- return this.problem?.id === account.id && this.problem.field === field ? "key-problem" : A;
55267
+ #described(account, field3) {
55268
+ return this.problem?.id === account.id && this.problem.field === field3 ? "key-problem" : A;
55178
55269
  }
55179
- #invalid(account, field) {
55180
- return this.#described(account, field) === A ? A : "true";
55270
+ #invalid(account, field3) {
55271
+ return this.#described(account, field3) === A ? A : "true";
55181
55272
  }
55182
55273
  #extra(account) {
55183
55274
  return (account.fields ?? []).map(
55184
- (field) => field.options ? b`<div class="field">
55185
- <sp-field-label for=${`field-${field.name}`} size="m">${field.label}</sp-field-label>${this.#control(account, field)}
55186
- ${field.options.length ? A : b`<p class="hint" data-empty=${field.name}>${nothingToChoose}</p>`}
55187
- ${field.help ? b`<p class="hint" id=${`help-${field.name}`}>${field.help}</p>` : A}
55188
- ${this.#problem(account, field.name, false)}
55275
+ (field3) => field3.options ? b`<div class="field">
55276
+ <sp-field-label for=${`field-${field3.name}`} size="m">${field3.label}</sp-field-label>${this.#control(account, field3)}
55277
+ ${field3.options.length ? A : b`<p class="hint" data-empty=${field3.name}>${nothingToChoose}</p>`}
55278
+ ${field3.help ? b`<p class="hint" id=${`help-${field3.name}`}>${field3.help}</p>` : A}
55279
+ ${this.#problem(account, field3.name, false)}
55189
55280
  </div>` : b`<label class="field">
55190
- <span>${field.label}</span>${this.#control(account, field)}
55281
+ <span>${field3.label}</span>${this.#control(account, field3)}
55191
55282
  </label>
55192
- ${field.help ? b`<p class="hint" id=${`help-${field.name}`}>${field.help}</p>` : A}
55193
- ${this.#problem(account, field.name)}`
55283
+ ${field3.help ? b`<p class="hint" id=${`help-${field3.name}`}>${field3.help}</p>` : A}
55284
+ ${this.#problem(account, field3.name)}`
55194
55285
  );
55195
55286
  }
55196
- #describedBy(account, field) {
55197
- const problem = this.#described(account, field.name);
55198
- const ids = [problem === A ? "" : problem, field.help ? `help-${field.name}` : ""];
55287
+ #describedBy(account, field3) {
55288
+ const problem = this.#described(account, field3.name);
55289
+ const ids = [problem === A ? "" : problem, field3.help ? `help-${field3.name}` : ""];
55199
55290
  return ids.filter(Boolean).join(" ") || A;
55200
55291
  }
55201
- #control(account, field) {
55202
- if (field.options) {
55203
- const empty4 = !field.options.length;
55204
- const described2 = this.problem?.id === account.id && this.problem.field === field.name;
55292
+ #control(account, field3) {
55293
+ if (field3.options) {
55294
+ const empty4 = !field3.options.length;
55295
+ const described2 = this.problem?.id === account.id && this.problem.field === field3.name;
55205
55296
  return b`<sp-picker
55206
55297
  size="m"
55207
- data-account-field=${field.name}
55208
- label=${empty4 ? "None available" : field.label}
55209
- id=${`field-${field.name}`}
55210
- value=${start(field.options, field.value)}
55298
+ data-account-field=${field3.name}
55299
+ label=${empty4 ? "None available" : field3.label}
55300
+ id=${`field-${field3.name}`}
55301
+ value=${start(field3.options, field3.value)}
55211
55302
  ?disabled=${empty4}
55212
55303
  ?invalid=${described2}
55213
- aria-required=${field.required ? "true" : A}
55304
+ aria-required=${field3.required ? "true" : A}
55214
55305
  >
55215
- ${field.options.map((option) => b`<sp-menu-item value=${option.value}>${option.label}</sp-menu-item>`)}
55216
- ${described2 || empty4 || field.help ? b`<span slot="description" class="sr">${described2 ? this.problem?.message : empty4 ? nothingToChoose : field.help}</span>` : A}
55306
+ ${field3.options.map((option) => b`<sp-menu-item value=${option.value}>${option.label}</sp-menu-item>`)}
55307
+ ${described2 || empty4 || field3.help ? b`<span slot="description" class="sr">${described2 ? this.problem?.message : empty4 ? nothingToChoose : field3.help}</span>` : A}
55217
55308
  </sp-picker>`;
55218
55309
  }
55219
55310
  return b`<input
55220
55311
  type="text"
55221
55312
  autocomplete="off"
55222
55313
  spellcheck="false"
55223
- data-account-field=${field.name}
55224
- value=${field.value ?? A}
55225
- placeholder=${field.placeholder ?? A}
55226
- aria-required=${field.required ? "true" : A}
55227
- aria-invalid=${this.#invalid(account, field.name)}
55228
- aria-describedby=${this.#describedBy(account, field)}
55314
+ data-account-field=${field3.name}
55315
+ value=${field3.value ?? A}
55316
+ placeholder=${field3.placeholder ?? A}
55317
+ aria-required=${field3.required ? "true" : A}
55318
+ aria-invalid=${this.#invalid(account, field3.name)}
55319
+ aria-describedby=${this.#describedBy(account, field3)}
55229
55320
  />`;
55230
55321
  }
55231
55322
  #getKey(account) {
@@ -55243,9 +55334,9 @@ var SliccSettings = class extends ThemedElement {
55243
55334
  #ready(account) {
55244
55335
  if (account.blocked) return false;
55245
55336
  if (!this.#offered()) return true;
55246
- const required = (account.fields ?? []).filter((field) => field.required && !field.options);
55337
+ const required = (account.fields ?? []).filter((field3) => field3.required && !field3.options);
55247
55338
  const key = this.#keyOptional(account) ? [] : ["value"];
55248
- return [...key, ...required.map((field) => field.name)].every((name) => this.filled.has(name));
55339
+ return [...key, ...required.map((field3) => field3.name)].every((name) => this.filled.has(name));
55249
55340
  }
55250
55341
  #fill(event2) {
55251
55342
  const input = event2.target;
@@ -55439,7 +55530,7 @@ var SliccSettings = class extends ThemedElement {
55439
55530
  const status2 = this.#status(account);
55440
55531
  const [variant, generic] = accountStatus[status2];
55441
55532
  const label = status2 === "rejected" ? rejectedNames[account.secret ?? "api-key"] : generic;
55442
- const failure2 = this.failure?.id === account.id ? b`<div class="failure" role="alert">
55533
+ const failure3 = this.failure?.id === account.id ? b`<div class="failure" role="alert">
55443
55534
  <swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>
55444
55535
  <span>${this.failure.message}</span>
55445
55536
  </div>` : A;
@@ -55451,7 +55542,7 @@ var SliccSettings = class extends ThemedElement {
55451
55542
  </div>
55452
55543
  ${this.#rowNotes(account)}
55453
55544
  ${this.#movedNote(account)}
55454
- ${this.adding?.id === account.id ? A : b`${this.#key(account)}${this.#otherKey(account)}${failure2}`}`;
55545
+ ${this.adding?.id === account.id ? A : b`${this.#key(account)}${this.#otherKey(account)}${failure3}`}`;
55455
55546
  }
55456
55547
  #refusedNote(account) {
55457
55548
  if (account.state !== "refused") return A;
@@ -55533,7 +55624,7 @@ var SliccSettings = class extends ThemedElement {
55533
55624
  this.#busy(account.id, false);
55534
55625
  }
55535
55626
  this.focusOn("[data-action=add-provider]");
55536
- for (const field of account.fields ?? []) this.#bases.delete(`${account.id} ${field.name}`);
55627
+ for (const field3 of account.fields ?? []) this.#bases.delete(`${account.id} ${field3.name}`);
55537
55628
  }
55538
55629
  #heldRecords(account, vault) {
55539
55630
  const server = serverOf(account);
@@ -55644,7 +55735,7 @@ var SliccSettings = class extends ThemedElement {
55644
55735
  event2.preventDefault();
55645
55736
  if (this.serverBusy) return;
55646
55737
  const form = event2.currentTarget;
55647
- const text4 = (field) => form.querySelector(`[data-server-field=${field}]`)?.value.trim();
55738
+ const text4 = (field3) => form.querySelector(`[data-server-field=${field3}]`)?.value.trim();
55648
55739
  const name = text4("name");
55649
55740
  const url = text4("url");
55650
55741
  const problem = this.#checkServer(name, url);
@@ -55673,21 +55764,21 @@ var SliccSettings = class extends ThemedElement {
55673
55764
  this.serverProblem = problem;
55674
55765
  if (problem.field !== "form") this.focusOn(`[data-server-field=${problem.field}]`);
55675
55766
  }
55676
- #serverNote(field) {
55677
- if (this.serverProblem?.field !== field) return A;
55678
- return b`<div class="problem" id=${`server-${field}-problem`} role="alert" data-problem=${field}>
55767
+ #serverNote(field3) {
55768
+ if (this.serverProblem?.field !== field3) return A;
55769
+ return b`<div class="problem" id=${`server-${field3}-problem`} role="alert" data-problem=${field3}>
55679
55770
  <swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle>
55680
55771
  <span>${this.serverProblem.message}</span>
55681
55772
  </div>`;
55682
55773
  }
55683
- #serverInput(field, type, help2) {
55684
- const invalid = this.serverProblem?.field === field;
55685
- const problem = invalid ? `server-${field}-problem ` : "";
55774
+ #serverInput(field3, type, help2) {
55775
+ const invalid = this.serverProblem?.field === field3;
55776
+ const problem = invalid ? `server-${field3}-problem ` : "";
55686
55777
  return b`<input
55687
55778
  type=${type}
55688
55779
  autocomplete="off"
55689
55780
  spellcheck="false"
55690
- data-server-field=${field}
55781
+ data-server-field=${field3}
55691
55782
  aria-required="true"
55692
55783
  aria-invalid=${invalid ? "true" : A}
55693
55784
  aria-describedby=${`${problem}${help2}`}
@@ -55784,8 +55875,8 @@ var SliccSettings = class extends ThemedElement {
55784
55875
  const dialog = this.#dialog;
55785
55876
  if (!changed2.has("picking") || !dialog || dialog.open) return;
55786
55877
  dialog.showModal();
55787
- const field = this.renderRoot.querySelector("sp-search");
55788
- void field.updateComplete.then(() => field.focus());
55878
+ const field3 = this.renderRoot.querySelector("sp-search");
55879
+ void field3.updateComplete.then(() => field3.focus());
55789
55880
  }
55790
55881
  get #dialog() {
55791
55882
  return this.renderRoot.querySelector("dialog.picker");
@@ -56001,8 +56092,8 @@ var SliccSettings = class extends ThemedElement {
56001
56092
  <div class="rows">
56002
56093
  <div class="row">
56003
56094
  <span class="label" id="model">Model for new cones</span>
56004
- <sp-picker size="m" label="Model" aria-labelledby="model" value=${value.model} @change=${(e128) => this.#pickModel(e128)}>
56005
- ${chatModels(settings.models()).map((option) => b`<sp-menu-item value=${option.id}>${option.label}<span slot="description">${option.provider}</span></sp-menu-item>`)}
56095
+ <sp-picker size="m" label="Model" aria-labelledby="model" value=${value.model} @change=${(e128) => this.#pickModel(e128)} @sp-opened=${this.#modelFilter.opened} @sp-closed=${this.#modelFilter.closed} @keydown=${this.#modelFilter.keys}>
56096
+ ${this.#modelFilter.items(chatModels(settings.models()))}
56006
56097
  </sp-picker>
56007
56098
  ${this.#switched(value.model)}
56008
56099
  </div>
@@ -56142,13 +56233,197 @@ var bridge = `(() => {
56142
56233
  face.load().then(size, () => {});
56143
56234
  }
56144
56235
  };
56236
+ const runs = new Map();
56145
56237
  addEventListener('message', (event) => {
56146
56238
  if (event.source !== parent) return;
56147
56239
  const message = event.data || {};
56148
56240
  if (message.type === 'slicc-icons') swap(message.icons);
56149
56241
  if (message.type === 'slicc-fonts') fonts(message.fonts);
56150
56242
  if (message.type === 'slicc-theme') document.documentElement.classList.toggle('theme-light', message.color === 'light');
56243
+ const run = runs.get(message.id);
56244
+ if (run && message.type === 'slicc-cgi-head') run.head(message);
56245
+ if (run && message.type === 'slicc-cgi-chunk') run.chunk(message);
56246
+ });
56247
+ const native = window.fetch;
56248
+ const tag = Math.random().toString(36).slice(2);
56249
+ let count = 0;
56250
+ const empty = new Set([101, 103, 204, 205, 304]);
56251
+ const moved = new Set([301, 302, 303, 307, 308]);
56252
+ const decode = (text) => Uint8Array.from(atob(text || ''), (char) => char.charCodeAt(0));
56253
+ const encode = (bytes) => {
56254
+ let text = '';
56255
+ for (let at = 0; at < bytes.length; at += 32768) text += String.fromCharCode(...bytes.subarray(at, at + 32768));
56256
+ return btoa(text);
56257
+ };
56258
+ const scope = (input) => {
56259
+ try {
56260
+ const href = input instanceof Request ? input.url : new URL(input, document.baseURI).href;
56261
+ const base = new URL('cgi-bin/', document.baseURI);
56262
+ return href.startsWith(base.href) ? base : null;
56263
+ } catch {
56264
+ return null;
56265
+ }
56266
+ };
56267
+ const send = (input, init, hops) => {
56268
+ const base = scope(input);
56269
+ if (!base) return native.call(window, input, init);
56270
+ let request;
56271
+ try {
56272
+ request = new Request(input, init);
56273
+ } catch (error) {
56274
+ return Promise.reject(error);
56275
+ }
56276
+ const payload = request.body ? request.arrayBuffer() : Promise.resolve(null);
56277
+ return payload.then((bytes) => exchange(request, base, bytes, hops));
56278
+ };
56279
+ const redirect = (request, payload, status, location, hops) => {
56280
+ if (request.redirect === 'error') throw new TypeError('fetch: the response redirects and redirect is error');
56281
+ if (hops >= 20) throw new TypeError('fetch: more than 20 redirects');
56282
+ const get = (status === 303 && request.method !== 'GET' && request.method !== 'HEAD') || ((status === 301 || status === 302) && request.method === 'POST');
56283
+ const headers = new Headers(request.headers);
56284
+ if (get) for (const name of ['content-encoding', 'content-language', 'content-location', 'content-type']) headers.delete(name);
56285
+ const init = { method: get ? 'GET' : request.method, headers, body: get ? null : payload, signal: request.signal, redirect: request.redirect };
56286
+ return send(new URL(location, request.url).href, init, hops + 1).then((response) => Object.defineProperty(response, 'redirected', { value: true }));
56287
+ };
56288
+ const exchange = (request, base, payload, hops) => new Promise((resolve, reject) => {
56289
+ const { signal } = request;
56290
+ if (signal.aborted) return reject(signal.reason);
56291
+ const id = tag + ':' + ++count;
56292
+ const url = new URL(request.url);
56293
+ const headers = new Headers(request.headers);
56294
+ if (!headers.has('accept')) headers.set('accept', '*/*');
56295
+ const language = navigator.languages.join(',') || navigator.language;
56296
+ if (language && !headers.has('accept-language')) headers.set('accept-language', language);
56297
+ let stream = null;
56298
+ const finish = () => {
56299
+ runs.delete(id);
56300
+ signal.removeEventListener('abort', abort);
56301
+ };
56302
+ const close = () => {
56303
+ finish();
56304
+ post({ type: 'slicc-cgi-close', id });
56305
+ };
56306
+ const abort = () => {
56307
+ close();
56308
+ reject(signal.reason);
56309
+ if (stream) stream.error(signal.reason);
56310
+ };
56311
+ signal.addEventListener('abort', abort);
56312
+ runs.set(id, {
56313
+ head(message) {
56314
+ if (typeof message.error === 'string') {
56315
+ finish();
56316
+ return reject(new TypeError(message.error));
56317
+ }
56318
+ const head = message.head;
56319
+ let response;
56320
+ let follow = false;
56321
+ try {
56322
+ const fields = new Headers(head.headers);
56323
+ follow = moved.has(head.status) && fields.has('location') && request.redirect !== 'manual';
56324
+ const drop = follow || request.method === 'HEAD' || empty.has(head.status);
56325
+ const body = drop ? null : new ReadableStream({
56326
+ start(controller) {
56327
+ const first = decode(head.body);
56328
+ if (first.length) controller.enqueue(first);
56329
+ if (head.done) controller.close();
56330
+ else stream = controller;
56331
+ },
56332
+ cancel() {
56333
+ if (runs.has(id)) close();
56334
+ },
56335
+ });
56336
+ response = new Response(body, { status: head.status, statusText: head.statusText, headers: fields });
56337
+ } catch (error) {
56338
+ close();
56339
+ return reject(new TypeError(error.message));
56340
+ }
56341
+ if (head.done) finish();
56342
+ url.hash = '';
56343
+ Object.defineProperty(response, 'url', { value: url.href });
56344
+ if (!follow) return resolve(response);
56345
+ try {
56346
+ resolve(redirect(request, payload, head.status, response.headers.get('location'), hops));
56347
+ } catch (error) {
56348
+ reject(error);
56349
+ }
56350
+ },
56351
+ chunk(message) {
56352
+ if (typeof message.error === 'string') {
56353
+ finish();
56354
+ if (stream) stream.error(new TypeError(message.error));
56355
+ return;
56356
+ }
56357
+ const bytes = decode(message.body);
56358
+ if (stream && bytes.length) stream.enqueue(bytes);
56359
+ if (!message.done) return;
56360
+ finish();
56361
+ if (stream) stream.close();
56362
+ },
56363
+ });
56364
+ post({
56365
+ type: 'slicc-cgi',
56366
+ id,
56367
+ request: {
56368
+ method: request.method,
56369
+ path: url.pathname.slice(base.pathname.length),
56370
+ query: url.search.slice(1),
56371
+ headers: [...headers],
56372
+ body: payload && payload.byteLength ? encode(new Uint8Array(payload)) : null,
56373
+ },
56374
+ });
56151
56375
  });
56376
+ window.fetch = function fetch(input, init) {
56377
+ return send(input, init, 0);
56378
+ };
56379
+ const formOf = (form, submitter) => {
56380
+ const own = (name) => !!submitter && submitter.hasAttribute('form' + name);
56381
+ return {
56382
+ action: (own('action') ? submitter.getAttribute('formaction') : form.getAttribute('action')) || '',
56383
+ method: own('method') ? submitter.formMethod : form.method,
56384
+ enctype: own('enctype') ? submitter.formEnctype : form.enctype,
56385
+ };
56386
+ };
56387
+ const submitted = (form, submitter) => {
56388
+ const { action, method, enctype } = formOf(form, submitter);
56389
+ if (!action || !scope(action)) return;
56390
+ const url = new URL(action, document.baseURI);
56391
+ const data = new FormData(form, submitter || null);
56392
+ const entries = [...data].map(([name, value]) => [name, typeof value === 'string' ? value : value.name]);
56393
+ const init = { method: method === 'post' ? 'POST' : 'GET', redirect: 'manual', headers: {} };
56394
+ if (init.method === 'GET') url.search = new URLSearchParams(entries).toString();
56395
+ else if (enctype === 'multipart/form-data') init.body = data;
56396
+ else if (enctype === 'text/plain') {
56397
+ init.body = entries.map(([name, value]) => name + '=' + value + '\\r\\n').join('');
56398
+ init.headers['content-type'] = 'text/plain';
56399
+ } else {
56400
+ init.body = new URLSearchParams(entries).toString();
56401
+ init.headers['content-type'] = 'application/x-www-form-urlencoded';
56402
+ }
56403
+ const tell = (detail) => form.dispatchEvent(new CustomEvent('slicc-cgi', { bubbles: true, cancelable: true, detail }));
56404
+ send(url.href, init, 0).then(
56405
+ (response) => {
56406
+ if (tell({ response }) && response.headers.has('location')) post({ type: 'slicc-reload' });
56407
+ },
56408
+ (error) => tell({ error }),
56409
+ );
56410
+ };
56411
+ const copies = new WeakSet();
56412
+ addEventListener('submit', (event) => {
56413
+ if (copies.has(event)) return;
56414
+ const form = event.composedPath()[0];
56415
+ if (!(form instanceof HTMLFormElement) || formOf(form, event.submitter).method === 'dialog') return;
56416
+ event.preventDefault();
56417
+ event.stopImmediatePropagation();
56418
+ const copy = new SubmitEvent('submit', { bubbles: true, cancelable: true, submitter: event.submitter });
56419
+ copies.add(copy);
56420
+ if (form.dispatchEvent(copy)) submitted(form, event.submitter);
56421
+ }, true);
56422
+ const submit = HTMLFormElement.prototype.submit;
56423
+ HTMLFormElement.prototype.submit = function () {
56424
+ if (formOf(this, null).method === 'dialog') return submit.call(this);
56425
+ submitted(this, null);
56426
+ };
56152
56427
  const size = () => {
56153
56428
  const style = getComputedStyle(document.body);
56154
56429
  post({ type: 'slicc-size', height: Math.ceil(document.body.offsetHeight + parseFloat(style.marginTop) + parseFloat(style.marginBottom)) });
@@ -56241,12 +56516,47 @@ async function frameFonts(files, base) {
56241
56516
  (font) => Boolean(font.data)
56242
56517
  );
56243
56518
  }
56519
+ var cgiMethods = /* @__PURE__ */ new Set([
56520
+ "cgi",
56521
+ "cgiRead",
56522
+ "cgiClose"
56523
+ ]);
56244
56524
  var sprinkleMethods = /* @__PURE__ */ new Set([
56245
56525
  "readFile",
56246
56526
  "exists",
56247
56527
  "getState",
56248
- "setState"
56528
+ "setState",
56529
+ ...cgiMethods
56249
56530
  ]);
56531
+ var field2 = (value) => typeof value === "string" ? value : "";
56532
+ function cgiRequest(value) {
56533
+ const given = value ?? {};
56534
+ const headers = (Array.isArray(given.headers) ? given.headers : []).filter(
56535
+ (pair) => Array.isArray(pair) && typeof pair[0] === "string" && typeof pair[1] === "string"
56536
+ ).map(([name, text4]) => [name, text4]);
56537
+ return {
56538
+ method: field2(given.method) || "GET",
56539
+ path: field2(given.path),
56540
+ query: field2(given.query),
56541
+ headers,
56542
+ body: field2(given.body) || null
56543
+ };
56544
+ }
56545
+ function cgiRefusal(status2, text4) {
56546
+ return {
56547
+ status: status2,
56548
+ statusText: status2 === 403 ? "Forbidden" : "Not Found",
56549
+ headers: [["Content-Type", "text/plain; charset=utf-8"]],
56550
+ body: btoa(`${text4}
56551
+ `),
56552
+ done: true,
56553
+ stream: null
56554
+ };
56555
+ }
56556
+ var cgiGuest = "A guest seat has no cgi-bin/.";
56557
+ var cgiReadOnly = "This sprinkle is read-only here, so its cgi-bin/ only answers GET and HEAD.";
56558
+ var cgiMissing = "This sprinkle has no cgi-bin/ here.";
56559
+ var failure2 = (error) => error instanceof Error ? error.message : String(error);
56250
56560
  var grip = w`<svg class="grip" viewBox="0 0 8 14" width="8" height="14" aria-hidden="true">${[2, 7, 12].flatMap((y8) => [2, 6].map((x5) => w`<circle cx=${x5} cy=${y8} r="1.25"></circle>`))}</svg>`;
56251
56561
  var plainId = (id) => id.replace(/^cone:/, "");
56252
56562
  var SliccSprinkle = class extends ThemedElement {
@@ -56386,8 +56696,75 @@ var SliccSprinkle = class extends ThemedElement {
56386
56696
  this.height = data.height;
56387
56697
  } else if (data.type === "slicc-call") {
56388
56698
  await this.#call(source, data);
56699
+ } else if (data.type === "slicc-cgi") {
56700
+ await this.#cgi(source, data);
56701
+ } else if (data.type === "slicc-cgi-close") {
56702
+ this.#close(data.id);
56703
+ } else if (data.type === "slicc-reload") {
56704
+ this.#reload();
56389
56705
  }
56390
56706
  };
56707
+ #runs = /* @__PURE__ */ new Map();
56708
+ #refusal(method) {
56709
+ if (this.model?.seat) return cgiRefusal(403, cgiGuest);
56710
+ const reading = ["GET", "HEAD"].includes(method.toUpperCase());
56711
+ if (!reading && this.#readOnly()) return cgiRefusal(403, cgiReadOnly);
56712
+ return void 0;
56713
+ }
56714
+ async #cgi(source, data) {
56715
+ if (typeof data.id !== "string") return;
56716
+ const id = data.id;
56717
+ const post2 = (message) => source.postMessage({ ...message, id }, "*");
56718
+ const request2 = cgiRequest(data.request);
56719
+ const port = this.model?.sprinkles;
56720
+ const call = port?.call?.bind(port);
56721
+ const refused3 = this.#refusal(request2.method);
56722
+ if (refused3 || !call)
56723
+ return post2({ type: "slicc-cgi-head", head: refused3 ?? cgiRefusal(404, cgiMissing) });
56724
+ const run = { call, sprinkle: this.sprinkle, stream: null, closed: false };
56725
+ this.#runs.set(id, run);
56726
+ let headed = false;
56727
+ try {
56728
+ const head = await call(run.sprinkle, "cgi", [request2]);
56729
+ let done2 = head.done || !head.stream;
56730
+ run.stream = done2 ? null : head.stream;
56731
+ if (run.closed) return this.#shut(run);
56732
+ headed = true;
56733
+ const { status: status2, statusText, headers, body: body2 } = head;
56734
+ post2({ type: "slicc-cgi-head", head: { status: status2, statusText, headers, body: body2, done: done2 } });
56735
+ while (!done2) {
56736
+ const chunk = await call(run.sprinkle, "cgiRead", [run.stream]);
56737
+ if (run.closed) return;
56738
+ done2 = chunk.done;
56739
+ post2({ type: "slicc-cgi-chunk", body: chunk.body, done: done2 });
56740
+ }
56741
+ } catch (error) {
56742
+ if (!run.closed)
56743
+ post2({ type: headed ? "slicc-cgi-chunk" : "slicc-cgi-head", error: failure2(error) });
56744
+ } finally {
56745
+ if (this.#runs.get(id) === run) this.#runs.delete(id);
56746
+ }
56747
+ }
56748
+ #close(id) {
56749
+ const run = typeof id === "string" ? this.#runs.get(id) : void 0;
56750
+ if (!run) return;
56751
+ this.#runs.delete(id);
56752
+ this.#shut(run);
56753
+ }
56754
+ #shut(run) {
56755
+ run.closed = true;
56756
+ if (run.stream) run.call(run.sprinkle, "cgiClose", [run.stream]).catch(() => void 0);
56757
+ }
56758
+ #closeAll() {
56759
+ for (const run of this.#runs.values()) this.#shut(run);
56760
+ this.#runs.clear();
56761
+ }
56762
+ #reload() {
56763
+ this.#closeAll();
56764
+ this.#frame = { key: "", doc: "" };
56765
+ this.#mounts++;
56766
+ this.requestUpdate();
56767
+ }
56391
56768
  #readOnly() {
56392
56769
  return this.readonly || !!this.model?.seat || this.#frozen() || !!watchOnly(this.model);
56393
56770
  }
@@ -56409,6 +56786,7 @@ var SliccSprinkle = class extends ThemedElement {
56409
56786
  async #call(source, data) {
56410
56787
  const port = this.model?.sprinkles;
56411
56788
  if (!port?.call || typeof data.method !== "string" || !sprinkleMethods.has(data.method)) return;
56789
+ if (cgiMethods.has(data.method)) return;
56412
56790
  const method = data.method;
56413
56791
  if (method === "setState" && this.#readOnly()) {
56414
56792
  source.postMessage({ type: "slicc-result", id: data.id, error: "read-only" }, "*");
@@ -56465,6 +56843,7 @@ var SliccSprinkle = class extends ThemedElement {
56465
56843
  return [
56466
56844
  ...super.subscribe(model),
56467
56845
  () => globalThis.removeEventListener("message", this.#message),
56846
+ () => this.#closeAll(),
56468
56847
  model.sprinkles.on("sprinkles", () => this.requestUpdate()),
56469
56848
  this.#dips.on("change", () => this.requestUpdate()),
56470
56849
  ...onWatch(model, () => this.requestUpdate())
@@ -56518,7 +56897,7 @@ ${data.html}`;
56518
56897
  const style2 = `color-scheme:${this.color};${this.inline ? `height:${this.height}px;` : ""}`;
56519
56898
  const frame = b`${i23(
56520
56899
  this.#mounts,
56521
- b`<iframe title=${data.title} sandbox="allow-scripts" ?inert=${watch2} style=${style2} .srcdoc=${this.#document(data, state2)}></iframe>`
56900
+ b`<iframe title=${data.title} sandbox="allow-scripts allow-forms" ?inert=${watch2} style=${style2} .srcdoc=${this.#document(data, state2)}></iframe>`
56522
56901
  )}`;
56523
56902
  if (!this.inline)
56524
56903
  return watch2 ? b`<div class="panel"><div class="bar">${caption2}</div>${frame}</div>` : frame;
@@ -56801,10 +57180,10 @@ var SliccValueRequest = class extends ThemedElement {
56801
57180
  const bad = nameProblem(name);
56802
57181
  const value = bad ? "" : take(this.#field("value"));
56803
57182
  const text4 = bad ?? valueProblem(value);
56804
- const field = bad ? "name" : "value";
56805
- this.problem = text4 ? { id: request2.id, text: text4, field } : null;
57183
+ const field3 = bad ? "name" : "value";
57184
+ this.problem = text4 ? { id: request2.id, text: text4, field: field3 } : null;
56806
57185
  if (text4) {
56807
- void this.updateComplete.then(() => this.#field(field)?.focus());
57186
+ void this.updateComplete.then(() => this.#field(field3)?.focus());
56808
57187
  return;
56809
57188
  }
56810
57189
  this.busy = true;
@@ -56814,8 +57193,8 @@ var SliccValueRequest = class extends ThemedElement {
56814
57193
  this.#done.add(request2.id);
56815
57194
  } catch (error) {
56816
57195
  if (this.#mine(vault)) {
56817
- const field2 = fieldOf(error, "value");
56818
- this.problem = { id: request2.id, text: failureText(error), ...field2 ? { field: field2 } : {} };
57196
+ const field4 = fieldOf(error, "value");
57197
+ this.problem = { id: request2.id, text: failureText(error), ...field4 ? { field: field4 } : {} };
56819
57198
  }
56820
57199
  } finally {
56821
57200
  if (this.model?.vault === vault) this.busy = false;
@@ -56824,8 +57203,8 @@ var SliccValueRequest = class extends ThemedElement {
56824
57203
  #typed() {
56825
57204
  if (this.problem?.field) this.problem = { id: this.problem.id, text: this.problem.text };
56826
57205
  }
56827
- #aria(field, problem) {
56828
- const bad = problem?.field === field;
57206
+ #aria(field3, problem) {
57207
+ const bad = problem?.field === field3;
56829
57208
  return { invalid: bad ? "true" : A, described: bad ? "error-request" : A };
56830
57209
  }
56831
57210
  async cancelRequest(request2) {
@@ -56896,7 +57275,7 @@ var SliccValueRequest = class extends ThemedElement {
56896
57275
  const shown4 = this.problem?.id === request2.id ? this.problem : null;
56897
57276
  const problem = shown4?.text ?? "";
56898
57277
  const name = this.#aria("name", shown4);
56899
- const field = this.#aria("value", shown4);
57278
+ const field3 = this.#aria("value", shown4);
56900
57279
  return i23(
56901
57280
  request2.id,
56902
57281
  b`<dialog role="alertdialog" aria-labelledby="title" aria-describedby="asked" data-request=${request2.id} @cancel=${(event2) => {
@@ -56912,7 +57291,7 @@ var SliccValueRequest = class extends ThemedElement {
56912
57291
  const input = event2.currentTarget;
56913
57292
  input.value = input.value.toUpperCase();
56914
57293
  }} /></label>`}
56915
- <label class="field"><span>Value</span><input type="password" autocomplete="off" spellcheck="false" data-field="value" aria-invalid=${field.invalid} aria-describedby=${field.described} /></label>
57294
+ <label class="field"><span>Value</span><input type="password" autocomplete="off" spellcheck="false" data-field="value" aria-invalid=${field3.invalid} aria-describedby=${field3.described} /></label>
56916
57295
  </div>` : A}
56917
57296
  ${locked ? this.#unlock(vault) : A}
56918
57297
  ${problem ? b`<p class="problem" role="alert" id="error-request" data-error><swc-icon-alert-triangle size="s" aria-hidden="true"></swc-icon-alert-triangle><span>${problem}</span></p>` : A}
@@ -58015,9 +58394,9 @@ var ViewItem = class {
58015
58394
  this._cachedVisibleSize = size4.cachedVisibleSize;
58016
58395
  }
58017
58396
  }
58018
- setVisible(visible2, size4) {
58019
- if (visible2 === this.visible) return;
58020
- if (visible2) {
58397
+ setVisible(visible3, size4) {
58398
+ if (visible3 === this.visible) return;
58399
+ if (visible3) {
58021
58400
  var _this$_cachedVisibleS;
58022
58401
  const cachedVisibleSize = (_this$_cachedVisibleS = this._cachedVisibleSize) !== null && _this$_cachedVisibleS !== void 0 ? _this$_cachedVisibleS : 0;
58023
58402
  this._cachedVisibleSize = void 0;
@@ -58026,8 +58405,8 @@ var ViewItem = class {
58026
58405
  this._cachedVisibleSize = typeof size4 === "number" ? size4 : this.size;
58027
58406
  this.size = 0;
58028
58407
  }
58029
- this.container.classList.toggle("visible", visible2);
58030
- if (this.view.setVisible) this.view.setVisible(visible2);
58408
+ this.container.classList.toggle("visible", visible3);
58409
+ if (this.view.setVisible) this.view.setVisible(visible3);
58031
58410
  }
58032
58411
  dispose() {
58033
58412
  this.disposable.dispose();
@@ -58189,15 +58568,15 @@ var Splitview = class {
58189
58568
  let snapped = false;
58190
58569
  if (snapBefore) {
58191
58570
  const snapView = this.viewItems[snapBefore.index];
58192
- const visible2 = delta >= snapBefore.limitDelta;
58193
- snapped = visible2 !== snapView.visible;
58194
- snapView.setVisible(visible2, snapBefore.size);
58571
+ const visible3 = delta >= snapBefore.limitDelta;
58572
+ snapped = visible3 !== snapView.visible;
58573
+ snapView.setVisible(visible3, snapBefore.size);
58195
58574
  }
58196
58575
  if (!snapped && snapAfter) {
58197
58576
  const snapView = this.viewItems[snapAfter.index];
58198
- const visible2 = delta < snapAfter.limitDelta;
58199
- snapped = visible2 !== snapView.visible;
58200
- snapView.setVisible(visible2, snapAfter.size);
58577
+ const visible3 = delta < snapAfter.limitDelta;
58578
+ snapped = visible3 !== snapView.visible;
58579
+ snapView.setVisible(visible3, snapAfter.size);
58201
58580
  }
58202
58581
  if (snapped) return this.resize(index2, delta, sizes, lowPriorityIndexes, highPriorityIndexes, overloadMinDelta, overloadMaxDelta);
58203
58582
  const tentativeDelta = clamp(delta, minDelta, maxDelta);
@@ -58260,10 +58639,10 @@ var Splitview = class {
58260
58639
  if (index2 < 0 || index2 >= this.viewItems.length) throw new Error("Index out of bounds");
58261
58640
  return this.viewItems[index2].visible;
58262
58641
  }
58263
- setViewVisible(index2, visible2) {
58642
+ setViewVisible(index2, visible3) {
58264
58643
  if (index2 < 0 || index2 >= this.viewItems.length) throw new Error("Index out of bounds");
58265
58644
  const viewItem = this.viewItems[index2];
58266
- viewItem.setVisible(visible2, viewItem.size);
58645
+ viewItem.setVisible(visible3, viewItem.size);
58267
58646
  this.distributeEmptySpace(index2);
58268
58647
  this.layoutViews();
58269
58648
  this.saveProportions();
@@ -58706,8 +59085,8 @@ var LeafNode = class {
58706
59085
  else this._onDidChange.fire({});
58707
59086
  });
58708
59087
  }
58709
- setVisible(visible2) {
58710
- if (this.view.setVisible) this.view.setVisible(visible2);
59088
+ setVisible(visible3) {
59089
+ if (this.view.setVisible) this.view.setVisible(visible3);
58711
59090
  }
58712
59091
  layout(size4, orthogonalSize) {
58713
59092
  this._size = size4;
@@ -58869,14 +59248,14 @@ var BranchNode = class BranchNode2 extends CompositeDisposable {
58869
59248
  if (index2 < 0 || index2 >= this.children.length) throw new Error("Invalid index");
58870
59249
  return this.splitview.isViewVisible(index2);
58871
59250
  }
58872
- setChildVisible(index2, visible2) {
59251
+ setChildVisible(index2, visible3) {
58873
59252
  if (index2 < 0 || index2 >= this.children.length) throw new Error("Invalid index");
58874
- if (this.splitview.isViewVisible(index2) === visible2) return;
59253
+ if (this.splitview.isViewVisible(index2) === visible3) return;
58875
59254
  const wereAllChildrenHidden = this.splitview.contentSize === 0;
58876
- this.splitview.setViewVisible(index2, visible2);
59255
+ this.splitview.setViewVisible(index2, visible3);
58877
59256
  this.invalidateCachedSizes();
58878
59257
  const areAllChildrenHidden = this.splitview.contentSize === 0;
58879
- if (visible2 && wereAllChildrenHidden || !visible2 && areAllChildrenHidden) this._onDidVisibilityChange.fire({ visible: visible2 });
59258
+ if (visible3 && wereAllChildrenHidden || !visible3 && areAllChildrenHidden) this._onDidVisibilityChange.fire({ visible: visible3 });
58880
59259
  }
58881
59260
  moveChild(from, to) {
58882
59261
  if (from === to) return;
@@ -58929,8 +59308,8 @@ var BranchNode = class BranchNode2 extends CompositeDisposable {
58929
59308
  this.invalidateCachedSizes();
58930
59309
  this._onDidChange.fire({ size: e128.orthogonalSize });
58931
59310
  }), ...this.children.map((c29, i26) => {
58932
- if (c29 instanceof BranchNode2) return c29.onDidVisibilityChange(({ visible: visible2 }) => {
58933
- this.setChildVisible(i26, visible2);
59311
+ if (c29 instanceof BranchNode2) return c29.onDidVisibilityChange(({ visible: visible3 }) => {
59312
+ this.setChildVisible(i26, visible3);
58934
59313
  });
58935
59314
  return Disposable.NONE;
58936
59315
  }));
@@ -59356,13 +59735,13 @@ var Gridview = class {
59356
59735
  if (!(parent instanceof BranchNode)) throw new TypeError("Invalid from location");
59357
59736
  return parent.isChildVisible(index2);
59358
59737
  }
59359
- setViewVisible(location2, visible2) {
59738
+ setViewVisible(location2, visible3) {
59360
59739
  if (this.hasMaximizedView()) this.exitMaximizedView();
59361
59740
  const [rest, index2] = tail(location2);
59362
59741
  const [, parent] = this.getNode(rest);
59363
59742
  if (!(parent instanceof BranchNode)) throw new TypeError("Invalid from location");
59364
59743
  this._onDidViewVisibilityChange.fire();
59365
- parent.setChildVisible(index2, visible2);
59744
+ parent.setChildVisible(index2, visible3);
59366
59745
  }
59367
59746
  moveView(parentLocation, from, to) {
59368
59747
  if (this.hasMaximizedView()) this.exitMaximizedView();
@@ -59608,8 +59987,8 @@ var BaseGrid = class extends Resizable {
59608
59987
  this._bufferOnDidLayoutChange.fire();
59609
59988
  }), this._onDidMaximizedChange, this._onDidViewVisibilityChangeMicroTaskQueue, this._bufferOnDidLayoutChange);
59610
59989
  }
59611
- setVisible(panel, visible2) {
59612
- this.gridview.setViewVisible(getGridLocation(panel.element), visible2);
59990
+ setVisible(panel, visible3) {
59991
+ this.gridview.setViewVisible(getGridLocation(panel.element), visible3);
59613
59992
  this._bufferOnDidLayoutChange.fire();
59614
59993
  }
59615
59994
  isVisible(panel) {
@@ -60368,8 +60747,8 @@ var DockviewApi = class {
60368
60747
  /**
60369
60748
  * Set the visibility of an edge group.
60370
60749
  */
60371
- setEdgeGroupVisible(position2, visible2) {
60372
- this.component.setEdgeGroupVisible(position2, visible2);
60750
+ setEdgeGroupVisible(position2, visible3) {
60751
+ this.component.setEdgeGroupVisible(position2, visible3);
60373
60752
  }
60374
60753
  /**
60375
60754
  * Check whether an edge group is currently visible.
@@ -70493,8 +70872,8 @@ var EdgeGroupView = class {
70493
70872
  this._isCollapsed = collapsed;
70494
70873
  this._group.element.classList.toggle("dv-edge-collapsed", collapsed);
70495
70874
  }
70496
- setVisible(visible2) {
70497
- this._isVisible = visible2;
70875
+ setVisible(visible3) {
70876
+ this._isVisible = visible3;
70498
70877
  }
70499
70878
  /**
70500
70879
  * Set the expanded size without triggering a layout: from serialized
@@ -70588,9 +70967,9 @@ var MiddleColumnView = class {
70588
70967
  }
70589
70968
  setVisible(_visible) {
70590
70969
  }
70591
- setViewVisible(position2, visible2) {
70970
+ setViewVisible(position2, visible3) {
70592
70971
  const index2 = position2 === "top" ? this._topIndex : this._bottomIndex;
70593
- if (index2 !== void 0) this._splitview.setViewVisible(index2, visible2);
70972
+ if (index2 !== void 0) this._splitview.setViewVisible(index2, visible3);
70594
70973
  }
70595
70974
  isViewVisible(position2) {
70596
70975
  const index2 = position2 === "top" ? this._topIndex : this._bottomIndex;
@@ -70837,22 +71216,22 @@ var ShellManager = class {
70837
71216
  return this._rightView !== void 0;
70838
71217
  }
70839
71218
  }
70840
- setEdgeGroupVisible(position2, visible2) {
70841
- const changes2 = this._getView(position2) !== void 0 && visible2 !== this.isEdgeGroupVisible(position2);
71219
+ setEdgeGroupVisible(position2, visible3) {
71220
+ const changes2 = this._getView(position2) !== void 0 && visible3 !== this.isEdgeGroupVisible(position2);
70842
71221
  switch (position2) {
70843
71222
  case "left":
70844
- if (this._leftIndex !== void 0) this._outerSplitview.setViewVisible(this._leftIndex, visible2);
71223
+ if (this._leftIndex !== void 0) this._outerSplitview.setViewVisible(this._leftIndex, visible3);
70845
71224
  break;
70846
71225
  case "right":
70847
- if (this._rightIndex !== void 0) this._outerSplitview.setViewVisible(this._rightIndex, visible2);
71226
+ if (this._rightIndex !== void 0) this._outerSplitview.setViewVisible(this._rightIndex, visible3);
70848
71227
  break;
70849
71228
  case "top":
70850
71229
  case "bottom":
70851
- this._middleColumn.setViewVisible(position2, visible2);
71230
+ this._middleColumn.setViewVisible(position2, visible3);
70852
71231
  break;
70853
71232
  }
70854
71233
  if (changes2 && this._gap > 0 && this._hasSiblingOn(position2)) this._relayout();
70855
- if (visible2) this._flushPendingSizes();
71234
+ if (visible3) this._flushPendingSizes();
70856
71235
  }
70857
71236
  isEdgeGroupVisible(position2) {
70858
71237
  switch (position2) {
@@ -70954,10 +71333,10 @@ var ShellManager = class {
70954
71333
  for (const position2 of EDGE_POSITIONS) {
70955
71334
  const view = this._getView(position2);
70956
71335
  if (!view) continue;
70957
- const visible2 = this.isEdgeGroupVisible(position2);
71336
+ const visible3 = this.isEdgeGroupVisible(position2);
70958
71337
  edgeGroups[position2] = {
70959
- size: this._expandedSize(view, position2, visible2),
70960
- visible: visible2,
71338
+ size: this._expandedSize(view, position2, visible3),
71339
+ visible: visible3,
70961
71340
  collapsed: view.isCollapsed || void 0,
70962
71341
  minimumSize: view.configuredMinimumSize,
70963
71342
  maximumSize: Number.isFinite(view.configuredMaximumSize) ? view.configuredMaximumSize : void 0,
@@ -70969,11 +71348,11 @@ var ShellManager = class {
70969
71348
  /** The size to restore the group to. An expanded-but-hidden group has a
70970
71349
  * slot of 0, so fall back to its cached visible size (then
70971
71350
  * lastExpandedSize); otherwise re-showing snaps to minimumSize. */
70972
- _expandedSize(view, position2, visible2) {
71351
+ _expandedSize(view, position2, visible3) {
70973
71352
  if (view.isCollapsed) return view.lastExpandedSize;
70974
71353
  const pending = this._pendingSizes.get(position2);
70975
71354
  if (pending !== void 0) return pending;
70976
- if (!visible2) {
71355
+ if (!visible3) {
70977
71356
  var _this$_cachedVisibleS;
70978
71357
  return (_this$_cachedVisibleS = this._cachedVisibleSize(position2)) !== null && _this$_cachedVisibleS !== void 0 ? _this$_cachedVisibleS : view.lastExpandedSize;
70979
71358
  }
@@ -71011,10 +71390,10 @@ var ShellManager = class {
71011
71390
  this._shellElement.remove();
71012
71391
  }
71013
71392
  };
71014
- function logFailedPopout(failure2) {
71015
- if (failure2.error) console.error("dockview: failed to create popout.", failure2.error);
71016
- else if (failure2.reason === "blocked") console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
71017
- else console.error(`dockview: failed to create popout (${failure2.reason}).`);
71393
+ function logFailedPopout(failure3) {
71394
+ if (failure3.error) console.error("dockview: failed to create popout.", failure3.error);
71395
+ else if (failure3.reason === "blocked") console.error("dockview: failed to create popout. perhaps you need to allow pop-ups for this website");
71396
+ else console.error(`dockview: failed to create popout (${failure3.reason}).`);
71018
71397
  }
71019
71398
  function buildTabGroupColorPalette(options2) {
71020
71399
  var _options$tabGroupColo;
@@ -71747,16 +72126,16 @@ var DockviewComponent = class extends BaseGrid {
71747
72126
  this._moduleRegistry.postConstruct(this);
71748
72127
  this._shellManager.layoutFromElement();
71749
72128
  }
71750
- setVisible(panel, visible2) {
72129
+ setVisible(panel, visible3) {
71751
72130
  switch (panel.api.location.type) {
71752
72131
  case "grid":
71753
- super.setVisible(panel, visible2);
72132
+ super.setVisible(panel, visible3);
71754
72133
  break;
71755
72134
  case "floating": {
71756
72135
  const item2 = this.floatingGroups.find((floatingGroup) => floatingGroup.group === panel);
71757
72136
  if (item2) {
71758
- item2.overlay.setVisible(visible2);
71759
- panel.api._onDidVisibilityChange.fire({ isVisible: visible2 });
72137
+ item2.overlay.setVisible(visible3);
72138
+ panel.api._onDidVisibilityChange.fire({ isVisible: visible3 });
71760
72139
  }
71761
72140
  break;
71762
72141
  }
@@ -71845,10 +72224,10 @@ var DockviewComponent = class extends BaseGrid {
71845
72224
  return false;
71846
72225
  }
71847
72226
  if (_window.isDisposed) {
71848
- const failure2 = _window.failure;
71849
- if (failure2 && !this.isDisposed) {
71850
- logFailedPopout(failure2);
71851
- this._onDidOpenPopoutWindowFail.fire(failure2);
72227
+ const failure3 = _window.failure;
72228
+ if (failure3 && !this.isDisposed) {
72229
+ logFailedPopout(failure3);
72230
+ this._onDidOpenPopoutWindowFail.fire(failure3);
71852
72231
  }
71853
72232
  return false;
71854
72233
  }
@@ -72041,10 +72420,10 @@ var DockviewComponent = class extends BaseGrid {
72041
72420
  * render nothing and later crash clear()/remove().
72042
72421
  */
72043
72422
  handleBlockedPopout(params) {
72044
- const { group, referenceGroup, options: options2, popoutWindowDisposable, failure: failure2 } = params;
72045
- logFailedPopout(failure2);
72423
+ const { group, referenceGroup, options: options2, popoutWindowDisposable, failure: failure3 } = params;
72424
+ logFailedPopout(failure3);
72046
72425
  popoutWindowDisposable.dispose();
72047
- this._onDidOpenPopoutWindowFail.fire(failure2);
72426
+ this._onDidOpenPopoutWindowFail.fire(failure3);
72048
72427
  if (options2 === null || options2 === void 0 ? void 0 : options2.overridePopoutGridview) {
72049
72428
  const blockedGridview = options2.overridePopoutGridview;
72050
72429
  const members = this.groups.filter((candidate) => blockedGridview.element.contains(candidate.element));
@@ -72563,8 +72942,8 @@ var DockviewComponent = class extends BaseGrid {
72563
72942
  repositionPanelOverlay(panel, forceVisible, clip) {
72564
72943
  this.overlayRenderContainer.repositionPanelOverlay(panel.api.id, forceVisible, clip);
72565
72944
  }
72566
- setEdgeGroupVisible(position2, visible2) {
72567
- this._shellManager.setEdgeGroupVisible(position2, visible2);
72945
+ setEdgeGroupVisible(position2, visible3) {
72946
+ this._shellManager.setEdgeGroupVisible(position2, visible3);
72568
72947
  }
72569
72948
  isEdgeGroupVisible(position2) {
72570
72949
  return this._shellManager.isEdgeGroupVisible(position2);
@@ -80781,9 +81160,9 @@ function computeFileTreeLayout(rows2, metrics) {
80781
81160
  const firstOccludedIndex = stickyHeight <= 0 || firstVisiblePhysicalIndex < 0 || firstVisiblePhysicalIndex >= totalRowCount ? -1 : firstVisiblePhysicalIndex;
80782
81161
  const lastOccludedIndex = firstOccludedIndex === -1 ? -1 : Math.min(totalRowCount - 1, firstProjectedIndex - 1);
80783
81162
  const occludedCount = firstOccludedIndex === -1 || lastOccludedIndex < firstOccludedIndex ? 0 : lastOccludedIndex - firstOccludedIndex + 1;
80784
- const visible2 = paneHeight <= 0 || firstProjectedIndex >= totalRowCount ? EMPTY_FILE_TREE_LAYOUT_RANGE : createRange(firstProjectedIndex, getLastIntersectingIndex(paneTop + paneHeight, totalRowCount, metrics.itemHeight));
81163
+ const visible3 = paneHeight <= 0 || firstProjectedIndex >= totalRowCount ? EMPTY_FILE_TREE_LAYOUT_RANGE : createRange(firstProjectedIndex, getLastIntersectingIndex(paneTop + paneHeight, totalRowCount, metrics.itemHeight));
80785
81164
  const minimumWindowStart = lastOccludedIndex + 1;
80786
- const windowRange = isEmptyRange(visible2) ? EMPTY_FILE_TREE_LAYOUT_RANGE : createRange(Math.max(minimumWindowStart, visible2.startIndex - overscan), Math.min(totalRowCount - 1, visible2.endIndex + overscan));
81165
+ const windowRange = isEmptyRange(visible3) ? EMPTY_FILE_TREE_LAYOUT_RANGE : createRange(Math.max(minimumWindowStart, visible3.startIndex - overscan), Math.min(totalRowCount - 1, visible3.endIndex + overscan));
80787
81166
  const windowHeight = getRangeHeight(windowRange, metrics.itemHeight);
80788
81167
  return {
80789
81168
  occlusion: {
@@ -80809,7 +81188,7 @@ function computeFileTreeLayout(rows2, metrics) {
80809
81188
  height: stickyHeight,
80810
81189
  rows: stickyRows
80811
81190
  },
80812
- visible: visible2,
81191
+ visible: visible3,
80813
81192
  window: {
80814
81193
  endIndex: windowRange.endIndex,
80815
81194
  height: windowHeight,