@flxgde/gigamenu 0.5.0 → 0.6.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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, Injectable, inject, TemplateRef, Directive, PLATFORM_ID, Inject, viewChild, contentChild, effect, HostListener, Component } from '@angular/core';
2
+ import { signal, computed, Injectable, inject, TemplateRef, Directive, PLATFORM_ID, Inject, viewChild, contentChild, effect, untracked, HostListener, Component } from '@angular/core';
3
3
  import { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';
4
4
 
5
5
  /** Colors for parameter highlighting */
@@ -1143,7 +1143,7 @@ class GigamenuComponent {
1143
1143
  // Dynamic provider state
1144
1144
  providerResults = signal(new Map(), ...(ngDevMode ? [{ debugName: "providerResults" }] : []));
1145
1145
  providerTimers = new Map();
1146
- providerGeneration = new Map();
1146
+ providerInvocation = 0;
1147
1147
  // Query parsing (simplified - only used for filtering)
1148
1148
  queryParser = computed(() => {
1149
1149
  const separator = this.service.config().argSeparator ?? ' ';
@@ -1229,6 +1229,22 @@ class GigamenuComponent {
1229
1229
  setTimeout(() => this.searchInput()?.nativeElement.focus(), 0);
1230
1230
  }
1231
1231
  });
1232
+ // Scroll lock: prevent page scrolling while the menu is open
1233
+ effect(() => {
1234
+ if (!this.isBrowser)
1235
+ return;
1236
+ const open = this.service.isOpen();
1237
+ const body = document.body;
1238
+ if (open) {
1239
+ const previous = body.style.overflow;
1240
+ body.dataset['gigamenuPrevOverflow'] = previous;
1241
+ body.style.overflow = 'hidden';
1242
+ }
1243
+ else if ('gigamenuPrevOverflow' in body.dataset) {
1244
+ body.style.overflow = body.dataset['gigamenuPrevOverflow'] ?? '';
1245
+ delete body.dataset['gigamenuPrevOverflow'];
1246
+ }
1247
+ });
1232
1248
  // Frecency auto-select effect (only in ActionSelection mode)
1233
1249
  effect(() => {
1234
1250
  const state = this.currentState();
@@ -1248,71 +1264,59 @@ class GigamenuComponent {
1248
1264
  }
1249
1265
  this.selectedIndex.set(0);
1250
1266
  });
1251
- // Dynamic provider effect (only in ActionSelection mode)
1267
+ // Dynamic provider effect (only in ActionSelection mode).
1268
+ // IMPORTANT: this effect must not read providerResults — it writes it, and
1269
+ // doing both would create a write-triggers-itself feedback loop that
1270
+ // re-fires every registered provider on every write.
1252
1271
  effect(() => {
1253
1272
  const state = this.currentState();
1254
1273
  const providers = this.service.providers();
1255
- const query = this.query();
1274
+ const query = this.query().trim();
1275
+ // Cancel anything currently pending / in-flight.
1276
+ for (const t of this.providerTimers.values())
1277
+ clearTimeout(t);
1278
+ this.providerTimers.clear();
1279
+ const invocation = ++this.providerInvocation;
1256
1280
  if (state !== InputState.ActionSelection) {
1257
- this.clearProviderResults();
1281
+ untracked(() => {
1282
+ if (this.providerResults().size > 0)
1283
+ this.providerResults.set(new Map());
1284
+ });
1258
1285
  return;
1259
1286
  }
1260
- // Cancel timers for providers that no longer exist
1261
- for (const id of this.providerTimers.keys()) {
1262
- if (!providers.has(id)) {
1263
- clearTimeout(this.providerTimers.get(id));
1264
- this.providerTimers.delete(id);
1265
- }
1266
- }
1267
- // Drop results from removed providers
1268
- const currentResults = this.providerResults();
1269
- if (currentResults.size > 0) {
1287
+ // Drop stored results that no longer apply (provider removed or query below threshold).
1288
+ untracked(() => {
1289
+ const current = this.providerResults();
1290
+ if (current.size === 0)
1291
+ return;
1292
+ const next = new Map(current);
1270
1293
  let changed = false;
1271
- const next = new Map(currentResults);
1272
- for (const id of next.keys()) {
1273
- if (!providers.has(id)) {
1294
+ for (const id of [...next.keys()]) {
1295
+ const reg = providers.get(id);
1296
+ if (!reg || query.length < reg.options.minQueryLength) {
1274
1297
  next.delete(id);
1275
1298
  changed = true;
1276
1299
  }
1277
1300
  }
1278
1301
  if (changed)
1279
1302
  this.providerResults.set(next);
1280
- }
1281
- // Schedule each provider
1303
+ });
1282
1304
  providers.forEach((registered, id) => {
1283
- const trimmed = query.trim();
1284
- if (trimmed.length < registered.options.minQueryLength) {
1285
- // Clear any previous results for this provider when below threshold
1286
- if (this.providerResults().has(id)) {
1287
- this.providerResults.update((map) => {
1288
- const next = new Map(map);
1289
- next.delete(id);
1290
- return next;
1291
- });
1292
- }
1293
- const existing = this.providerTimers.get(id);
1294
- if (existing) {
1295
- clearTimeout(existing);
1296
- this.providerTimers.delete(id);
1297
- }
1305
+ if (query.length < registered.options.minQueryLength)
1298
1306
  return;
1299
- }
1300
- const existing = this.providerTimers.get(id);
1301
- if (existing)
1302
- clearTimeout(existing);
1303
- const generation = (this.providerGeneration.get(id) ?? 0) + 1;
1304
- this.providerGeneration.set(id, generation);
1305
1307
  const timer = setTimeout(async () => {
1306
1308
  this.providerTimers.delete(id);
1307
1309
  try {
1308
- const raw = await registered.provider(trimmed);
1309
- if (this.providerGeneration.get(id) !== generation)
1310
+ const raw = await registered.provider(query);
1311
+ if (invocation !== this.providerInvocation)
1310
1312
  return;
1311
1313
  const items = this.normalizeProviderItems(raw, id, registered.options.group);
1312
- this.providerResults.update((map) => {
1313
- const next = new Map(map);
1314
- next.set(id, items);
1315
- return next;
1314
+ untracked(() => {
1315
+ this.providerResults.update((map) => {
1316
+ const next = new Map(map);
1317
+ next.set(id, items);
1318
+ return next;
1319
+ });
1316
1320
  });
1317
1321
  }
1318
1322
  catch (err) {
@@ -1618,13 +1622,11 @@ class GigamenuComponent {
1618
1622
  for (const timer of this.providerTimers.values())
1619
1623
  clearTimeout(timer);
1620
1624
  this.providerTimers.clear();
1621
- // Bump all generations to invalidate any in-flight responses
1622
- for (const id of this.providerGeneration.keys()) {
1623
- this.providerGeneration.set(id, (this.providerGeneration.get(id) ?? 0) + 1);
1624
- }
1625
- if (this.providerResults().size > 0) {
1626
- this.providerResults.set(new Map());
1627
- }
1625
+ this.providerInvocation++; // invalidates in-flight responses
1626
+ untracked(() => {
1627
+ if (this.providerResults().size > 0)
1628
+ this.providerResults.set(new Map());
1629
+ });
1628
1630
  }
1629
1631
  normalizeProviderItems(raw, providerId, group) {
1630
1632
  return raw.map((item) => ({
@@ -1650,11 +1652,11 @@ class GigamenuComponent {
1650
1652
  }
1651
1653
  }
1652
1654
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GigamenuComponent, deps: [{ token: GigamenuService }, { token: FrecencyService }, { token: PLATFORM_ID }], target: i0.ɵɵFactoryTarget.Component });
1653
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: GigamenuComponent, isStandalone: true, selector: "gm-gigamenu", host: { listeners: { "document:keydown": "onGlobalKeydown($event)" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: GigamenuItemTemplate, descendants: true, isSignal: true }, { propertyName: "emptyTemplate", first: true, predicate: GigamenuEmptyTemplate, descendants: true, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: GigamenuHeaderTemplate, descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: GigamenuFooterTemplate, descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: GigamenuPanelTemplate, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "listContainer", first: true, predicate: ["listContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-start justify-center pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full max-w-xl min-h-50 overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">\u203A</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">\u203A</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"max-h-80 overflow-y-auto p-2\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2191</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2193</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u21B5</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1655
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.6", type: GigamenuComponent, isStandalone: true, selector: "gm-gigamenu", host: { listeners: { "document:keydown": "onGlobalKeydown($event)" } }, queries: [{ propertyName: "itemTemplate", first: true, predicate: GigamenuItemTemplate, descendants: true, isSignal: true }, { propertyName: "emptyTemplate", first: true, predicate: GigamenuEmptyTemplate, descendants: true, isSignal: true }, { propertyName: "headerTemplate", first: true, predicate: GigamenuHeaderTemplate, descendants: true, isSignal: true }, { propertyName: "footerTemplate", first: true, predicate: GigamenuFooterTemplate, descendants: true, isSignal: true }, { propertyName: "panelTemplate", first: true, predicate: GigamenuPanelTemplate, descendants: true, isSignal: true }], viewQueries: [{ propertyName: "searchInput", first: true, predicate: ["searchInput"], descendants: true, isSignal: true }, { propertyName: "listContainer", first: true, predicate: ["listContainer"], descendants: true, isSignal: true }], ngImport: i0, template: "@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-stretch justify-center sm:items-start sm:pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full flex flex-col overflow-hidden border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900 sm:max-w-xl sm:min-h-50 sm:flex-none sm:rounded-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">\u203A</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">\u203A</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"flex-1 overflow-y-auto p-2 sm:flex-none sm:max-h-80\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2191</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2193</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u21B5</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [":host{display:contents}\n"], dependencies: [{ kind: "directive", type: NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }] });
1654
1656
  }
1655
1657
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.6", ngImport: i0, type: GigamenuComponent, decorators: [{
1656
1658
  type: Component,
1657
- args: [{ selector: 'gm-gigamenu', standalone: true, imports: [NgTemplateOutlet], template: "@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-start justify-center pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full max-w-xl min-h-50 overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">\u203A</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">\u203A</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"max-h-80 overflow-y-auto p-2\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2191</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2193</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u21B5</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [":host{display:contents}\n"] }]
1659
+ args: [{ selector: 'gm-gigamenu', standalone: true, imports: [NgTemplateOutlet], template: "@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-stretch justify-center sm:items-start sm:pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full flex flex-col overflow-hidden border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900 sm:max-w-xl sm:min-h-50 sm:flex-none sm:rounded-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">\u203A</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">\u203A</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"flex-1 overflow-y-auto p-2 sm:flex-none sm:max-h-80\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2191</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u2193</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">\u21B5</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n", styles: [":host{display:contents}\n"] }]
1658
1660
  }], ctorParameters: () => [{ type: GigamenuService }, { type: FrecencyService }, { type: undefined, decorators: [{
1659
1661
  type: Inject,
1660
1662
  args: [PLATFORM_ID]
@@ -1 +1 @@
1
- {"version":3,"file":"flxgde-gigamenu.mjs","sources":["../../../src/lib/types.ts","../../../src/lib/gigamenu.service.ts","../../../src/lib/gigamenu-templates.directive.ts","../../../src/lib/query-parser.ts","../../../src/lib/input-state.ts","../../../src/lib/core/scroll-utils.ts","../../../src/lib/core/search.ts","../../../src/lib/core/parameter-state.ts","../../../src/lib/core/template-contexts.ts","../../../src/lib/core/menu-lifecycle.ts","../../../src/lib/core/autocomplete.ts","../../../src/lib/core/keyboard-handlers.ts","../../../src/lib/core/index.ts","../../../src/lib/frecency.service.ts","../../../src/lib/gigamenu.component.ts","../../../src/lib/gigamenu.component.html","../../../src/flxgde-gigamenu.ts"],"sourcesContent":["export type GigamenuItemCategory = 'page' | 'command';\n\n/**\n * Autocomplete option for parameter suggestions.\n * label: Display text shown in the autocomplete dropdown\n * value: Actual value that gets passed to the action\n */\nexport interface AutocompleteOption {\n label: string;\n value: string;\n}\n\n/**\n * Provider for autocomplete suggestions.\n * Can be either a static array of options or an async function that returns options.\n */\nexport type ParamProvider =\n | AutocompleteOption[]\n | ((query: string) => Promise<AutocompleteOption[]> | AutocompleteOption[]);\n\nexport interface GigamenuItem {\n id: string;\n label: string;\n description?: string;\n /** Emoji or text icon */\n icon?: string;\n /** CSS class for icon libraries (e.g., 'pi pi-home', 'fa fa-home') */\n iconClass?: string;\n keywords?: string[];\n category: GigamenuItemCategory;\n /** Action to execute. Receives args string if user typed text after the separator. */\n action: (args?: string) => void;\n /** Required parameter names for this item (e.g., ['id', 'commentId']) */\n params?: string[];\n /**\n * Autocomplete providers for parameters.\n * Key: parameter name (must match a name in params array)\n * Value: ParamProvider (static array or async function)\n */\n paramProviders?: Record<string, ParamProvider>;\n /**\n * Optional section/group label. Items supplied by dynamic providers typically\n * set this so the UI can render them under a heading (e.g. \"Recipes\").\n */\n group?: string;\n /** Provider id when produced by a dynamic provider. Set automatically. */\n providerId?: string;\n}\n\n/**\n * A dynamic provider returns items that depend on the current query, e.g. results\n * fetched from a server. Returned items skip the built-in fuzzy filter.\n */\nexport type GigamenuProvider = (\n query: string\n) => Promise<GigamenuProviderItem[]> | GigamenuProviderItem[];\n\n/**\n * Items returned from a provider. Same shape as GigamenuItem but `category` is\n * optional — it defaults to 'command'. Providers typically omit it.\n */\nexport type GigamenuProviderItem = Omit<GigamenuItem, 'category'> & {\n category?: GigamenuItemCategory;\n};\n\nexport interface GigamenuProviderOptions {\n /** Minimum query length before the provider is invoked. Default: 2. */\n minQueryLength?: number;\n /** Debounce window in ms before invoking the provider. Default: 200. */\n debounceMs?: number;\n /** Optional group label applied to all items from this provider. */\n group?: string;\n}\n\n/** Colors for parameter highlighting */\nexport const PARAM_COLORS = [\n 'text-blue-500 dark:text-blue-400',\n 'text-green-500 dark:text-green-400',\n 'text-orange-500 dark:text-orange-400',\n 'text-pink-500 dark:text-pink-400',\n 'text-cyan-500 dark:text-cyan-400',\n] as const;\n\nexport interface GigamenuPage extends Omit<GigamenuItem, 'category' | 'action'> {\n path: string;\n}\n\nexport interface GigamenuCommand extends Omit<GigamenuItem, 'category'> {\n shortcut?: string;\n}\n\nexport interface GigamenuConfig {\n placeholder?: string;\n maxResults?: number;\n autoDiscoverRoutes?: boolean;\n /** Separator between search query and arguments (default: ' ') */\n argSeparator?: string;\n /** CSS class name for dark mode (default: 'dark') */\n darkModeClass?: string;\n /** Tab behavior for autocomplete: 'cycle' always cycles, 'accept-first' accepts on first tab (default: 'cycle') */\n autocompleteTabBehavior?: 'cycle' | 'accept-first';\n /** When to dismiss autocomplete overlay: 'on-type' hides on any keystroke, 'manual' only on Escape/selection (default: 'on-type') */\n autocompleteDismiss?: 'on-type' | 'manual';\n}\n\nexport const DEFAULT_CONFIG: GigamenuConfig = {\n placeholder: 'Search pages and commands...',\n maxResults: 10,\n autoDiscoverRoutes: true,\n argSeparator: ' ',\n darkModeClass: 'dark',\n autocompleteTabBehavior: 'cycle',\n autocompleteDismiss: 'on-type',\n};\n\n/**\n * Base interface for defining a command in a separate file.\n * Each command file should export a constant implementing this interface.\n */\nexport interface CommandDefinition {\n readonly id: string;\n readonly label: string;\n readonly description?: string;\n readonly icon?: string;\n readonly iconClass?: string;\n readonly keywords?: string[];\n readonly shortcut?: string;\n execute(): void;\n}\n\n/**\n * Helper function to define a command with type safety.\n */\nexport function defineCommand(command: CommandDefinition): CommandDefinition {\n return command;\n}\n\n/**\n * Information about a route passed to the filter function.\n */\nexport interface RouteInfo {\n path: string;\n fullPath: string;\n data?: Record<string, unknown>;\n title?: string;\n}\n\n/**\n * Filter function to include/exclude routes from discovery.\n * Return true to include the route, false to exclude it.\n */\nexport type RouteFilter = (route: RouteInfo) => boolean;\n\n/**\n * Mapped page data returned from the map function.\n */\nexport interface MappedPage {\n label?: string;\n description?: string;\n icon?: string;\n iconClass?: string;\n keywords?: string[];\n}\n\n/**\n * Map function to customize page data for discovered routes.\n * Return partial page data to override defaults, or null to skip the route.\n */\nexport type RouteMapper = (route: RouteInfo) => MappedPage | null;\n\n/**\n * Options for route discovery.\n */\nexport interface DiscoverRoutesOptions {\n filter?: RouteFilter;\n map?: RouteMapper;\n}\n","import { Injectable, signal, computed } from '@angular/core';\nimport { Router, Routes } from '@angular/router';\nimport {\n GigamenuItem,\n GigamenuCommand,\n GigamenuPage,\n GigamenuConfig,\n DEFAULT_CONFIG,\n DiscoverRoutesOptions,\n RouteInfo,\n GigamenuProvider,\n GigamenuProviderOptions,\n} from './types';\n\ninterface RegisteredProvider {\n provider: GigamenuProvider;\n options: Required<GigamenuProviderOptions>;\n}\n\nconst DEFAULT_PROVIDER_OPTIONS: Required<GigamenuProviderOptions> = {\n minQueryLength: 2,\n debounceMs: 200,\n group: '',\n};\n\n@Injectable({ providedIn: 'root' })\nexport class GigamenuService {\n private _router?: Router;\n\n private readonly _items = signal<Map<string, GigamenuItem>>(new Map());\n private readonly _providers = signal<Map<string, RegisteredProvider>>(new Map());\n private readonly _isOpen = signal(false);\n private readonly _config = signal<GigamenuConfig>(DEFAULT_CONFIG);\n\n readonly items = computed(() => Array.from(this._items().values()));\n readonly providers = this._providers.asReadonly();\n readonly isOpen = this._isOpen.asReadonly();\n readonly config = this._config.asReadonly();\n\n /**\n * Set the router instance. Must be called before using navigation features.\n */\n setRouter(router: Router): void {\n this._router = router;\n }\n\n private get router(): Router {\n if (!this._router) {\n throw new Error(\n 'GigamenuService: Router not set. Call setRouter() in your app initialization.'\n );\n }\n return this._router;\n }\n\n configure(config: Partial<GigamenuConfig>): void {\n this._config.update((current) => ({ ...current, ...config }));\n }\n\n open(): void {\n this._isOpen.set(true);\n }\n\n close(): void {\n this._isOpen.set(false);\n }\n\n toggle(): void {\n this._isOpen.update((v) => !v);\n }\n\n toggleDarkMode(): void {\n const darkModeClass = this._config().darkModeClass ?? 'dark';\n document.documentElement.classList.toggle(darkModeClass);\n }\n\n registerItem(item: GigamenuItem): void {\n this._items.update((items) => {\n const newItems = new Map(items);\n newItems.set(item.id, item);\n return newItems;\n });\n }\n\n unregisterItem(id: string): void {\n this._items.update((items) => {\n const newItems = new Map(items);\n newItems.delete(id);\n return newItems;\n });\n }\n\n /**\n * Register a dynamic item provider. The provider is invoked when the user\n * types in the menu (in action-selection mode) and its results are merged\n * into the displayed items alongside statically registered items.\n */\n registerProvider(\n id: string,\n provider: GigamenuProvider,\n options: GigamenuProviderOptions = {}\n ): void {\n const resolved: Required<GigamenuProviderOptions> = {\n ...DEFAULT_PROVIDER_OPTIONS,\n ...options,\n };\n this._providers.update((providers) => {\n const next = new Map(providers);\n next.set(id, { provider, options: resolved });\n return next;\n });\n }\n\n unregisterProvider(id: string): void {\n this._providers.update((providers) => {\n if (!providers.has(id)) return providers;\n const next = new Map(providers);\n next.delete(id);\n return next;\n });\n }\n\n registerCommand(command: GigamenuCommand): void {\n this.registerItem({\n ...command,\n category: 'command',\n });\n }\n\n registerPage(page: GigamenuPage): void {\n // Extract parameter names from path (e.g., /users/:id -> ['id'])\n const paramNames = this.extractParamNames(page.path);\n\n // Use manually specified params if provided, otherwise use extracted ones\n const finalParams = page.params ?? (paramNames.length > 0 ? paramNames : undefined);\n\n this.registerItem({\n ...page,\n category: 'page',\n params: finalParams,\n // Preserve paramProviders if specified\n paramProviders: page.paramProviders,\n action: (args?: string) => {\n let path = page.path;\n const paramsToReplace = finalParams ?? [];\n if (paramsToReplace.length > 0 && args) {\n // Split args by whitespace to get parameter values\n const argValues = args.trim().split(/\\s+/);\n // Replace each parameter with corresponding arg value\n paramsToReplace.forEach((param, index) => {\n if (argValues[index]) {\n path = path.replace(`:${param}`, argValues[index]);\n }\n });\n }\n this.router.navigate([path]);\n },\n });\n }\n\n private extractParamNames(path: string): string[] {\n const paramRegex = /:([^/]+)/g;\n const params: string[] = [];\n let match;\n while ((match = paramRegex.exec(path)) !== null) {\n params.push(match[1]);\n }\n return params;\n }\n\n discoverRoutes(options?: DiscoverRoutesOptions): void;\n discoverRoutes(routes?: Routes, options?: DiscoverRoutesOptions): void;\n discoverRoutes(\n routesOrOptions?: Routes | DiscoverRoutesOptions,\n maybeOptions?: DiscoverRoutesOptions\n ): void {\n let routes: Routes;\n let options: DiscoverRoutesOptions | undefined;\n\n if (Array.isArray(routesOrOptions)) {\n routes = routesOrOptions;\n options = maybeOptions;\n } else {\n routes = this.router.config;\n options = routesOrOptions;\n }\n\n this.extractPagesFromRoutes(routes, '', options?.filter);\n }\n\n private extractPagesFromRoutes(\n routes: Routes,\n parentPath: string,\n filter?: (route: RouteInfo) => boolean\n ): void {\n for (const route of routes) {\n if (route.redirectTo !== undefined) continue;\n\n const fullPath = parentPath\n ? `${parentPath}/${route.path ?? ''}`\n : route.path ?? '';\n\n if (route.path !== undefined && route.path !== '**') {\n const routeInfo: RouteInfo = {\n path: route.path,\n fullPath: `/${fullPath}`,\n data: route.data as Record<string, unknown> | undefined,\n title: typeof route.title === 'string' ? route.title : undefined,\n };\n\n // Apply filter if provided\n if (filter && !filter(routeInfo)) {\n // Still process children even if this route is filtered\n if (route.children) {\n this.extractPagesFromRoutes(route.children, fullPath, filter);\n }\n continue;\n }\n\n const label = routeInfo.title || this.pathToLabel(route.path || 'Home');\n const paramNames = this.extractParamNames(`/${fullPath}`);\n const hasParams = paramNames.length > 0;\n\n this.registerPage({\n id: `page:${fullPath || '/'}`,\n label, // Params will be rendered separately with colors\n path: `/${fullPath}`,\n description: hasParams\n ? `Navigate to ${label} (requires: ${paramNames.join(', ')})`\n : `Navigate to ${label}`,\n });\n }\n\n if (route.children) {\n this.extractPagesFromRoutes(route.children, fullPath, filter);\n }\n }\n }\n\n private pathToLabel(path: string): string {\n return path\n .split('/')\n .pop()!\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\nimport { GigamenuItem } from './types';\n\n/**\n * Context provided to the item template.\n */\nexport interface GigamenuItemContext {\n /** The menu item being rendered */\n $implicit: GigamenuItem;\n /** The index of the item in the filtered list */\n index: number;\n /** Whether this item is currently selected */\n selected: boolean;\n}\n\n/**\n * Context provided to the empty template.\n */\nexport interface GigamenuEmptyContext {\n /** The current search query */\n $implicit: string;\n}\n\n/**\n * Context provided to the header template.\n */\nexport interface GigamenuHeaderContext {\n /** The current query value */\n $implicit: string;\n /** The current query value */\n query: string;\n /** The locked action (if in parameter mode) */\n lockedAction: GigamenuItem | null;\n /** Array of filled parameter values */\n paramValues: string[];\n /** Name of the current parameter being edited */\n currentParamName: string | null;\n /** Placeholder text */\n placeholder: string;\n /** Callback to update the query */\n onQueryChange: (value: string) => void;\n /** Callback for keydown events */\n onKeydown: (event: KeyboardEvent) => void;\n /** Callback to unlock the action (go back to action selection) */\n onUnlockAction: () => void;\n /** Callback to go back to a specific parameter */\n onGoToParam: (index: number) => void;\n}\n\n/**\n * Context provided to the footer template.\n */\nexport interface GigamenuFooterContext {\n /** Number of filtered items */\n $implicit: number;\n /** Total number of items */\n total: number;\n}\n\n/**\n * Template directive for customizing menu item rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmItem let-item let-selected=\"selected\" let-index=\"index\">\n * <div [class.active]=\"selected\">\n * {{ item.label }}\n * </div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmItem]',\n standalone: true,\n})\nexport class GigamenuItemTemplate {\n readonly template = inject<TemplateRef<GigamenuItemContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing empty state rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmEmpty let-query>\n * <div>No results for \"{{ query }}\"</div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmEmpty]',\n standalone: true,\n})\nexport class GigamenuEmptyTemplate {\n readonly template = inject<TemplateRef<GigamenuEmptyContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing header/search input rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmHeader let-query let-onQueryChange=\"onQueryChange\" let-onKeydown=\"onKeydown\">\n * <input [value]=\"query\" (input)=\"onQueryChange($event.target.value)\" (keydown)=\"onKeydown($event)\" />\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmHeader]',\n standalone: true,\n})\nexport class GigamenuHeaderTemplate {\n readonly template = inject<TemplateRef<GigamenuHeaderContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing footer rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmFooter let-count let-total=\"total\">\n * <div>Showing {{ count }} of {{ total }} items</div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmFooter]',\n standalone: true,\n})\nexport class GigamenuFooterTemplate {\n readonly template = inject<TemplateRef<GigamenuFooterContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing the entire panel/dialog container.\n * When provided, replaces the entire default panel structure.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmPanel let-items let-query=\"query\" let-selectedIndex=\"selectedIndex\">\n * <div class=\"my-custom-panel\">\n * <!-- Custom implementation -->\n * </div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\nexport interface GigamenuPanelContext {\n /** Items to display (actions or autocomplete suggestions) */\n $implicit: GigamenuItem[];\n /** Items to display (actions or autocomplete suggestions) */\n items: GigamenuItem[];\n /** Current query value */\n query: string;\n /** The locked action (if in parameter mode) */\n lockedAction: GigamenuItem | null;\n /** Array of filled parameter values */\n paramValues: string[];\n /** Currently selected index */\n selectedIndex: number;\n /** Placeholder text from config */\n placeholder: string;\n /** Callback when item is clicked */\n onItemClick: (item: GigamenuItem, index: number) => void;\n /** Callback to update selection */\n onSelectIndex: (index: number) => void;\n /** Callback to update query */\n onQueryChange: (query: string) => void;\n /** Callback to close the menu */\n onClose: () => void;\n}\n\n@Directive({\n selector: '[gmPanel]',\n standalone: true,\n})\nexport class GigamenuPanelTemplate {\n readonly template = inject<TemplateRef<GigamenuPanelContext>>(TemplateRef);\n}\n","/**\n * Parsed query result containing search term and arguments.\n */\nexport interface ParsedQuery {\n /** The search term (may include quotes if label contains spaces) */\n searchTerm: string;\n /** The raw arguments string after the search term */\n args: string;\n /** Whether the query contains a separator after the search term */\n hasSeparator: boolean;\n}\n\n/**\n * Parsed arguments result containing both values and display strings.\n */\nexport interface ParsedArgs {\n /** Unquoted argument values */\n values: string[];\n /** Display strings (preserves quotes for visual alignment) */\n display: string[];\n}\n\n/**\n * Handles parsing of gigamenu query input.\n * Supports quoted strings for labels/values containing spaces.\n */\nexport class QueryParser {\n constructor(private readonly separator: string = ' ') {}\n\n /**\n * Parse a query string into search term and arguments.\n * Simple split on first separator - no quote handling.\n */\n parseQuery(query: string): ParsedQuery {\n const sepIndex = query.indexOf(this.separator);\n if (sepIndex === -1) {\n return { searchTerm: query, args: '', hasSeparator: false };\n }\n return {\n searchTerm: query.substring(0, sepIndex),\n args: query.substring(sepIndex + this.separator.length),\n hasSeparator: true,\n };\n }\n\n /**\n * Parse an arguments string into an array.\n * Simple space-based splitting - quotes are ignored.\n */\n parseArgs(args: string): ParsedArgs {\n if (!args) {\n return { values: [], display: [] };\n }\n\n // Simple split on spaces, filter out empty strings\n const parts = args.split(' ').filter(part => part.length > 0);\n return { values: parts, display: parts };\n }\n\n /**\n * Strip quotes from a string if it's quoted (legacy, kept for compatibility).\n */\n stripQuotes(str: string): string {\n if ((str.startsWith(\"'\") && str.endsWith(\"'\")) ||\n (str.startsWith('\"') && str.endsWith('\"'))) {\n return str.slice(1, -1);\n }\n return str;\n }\n\n /**\n * Return the string as-is (no escaping needed).\n */\n escapeIfNeeded(str: string): string {\n return str;\n }\n\n /**\n * Check if a search term matches a label (case-insensitive).\n */\n matchesLabel(searchTerm: string, label: string): boolean {\n const trimmed = searchTerm.trim().toLowerCase();\n return trimmed === label.toLowerCase();\n }\n\n /**\n * Build a query string from search term and args.\n */\n buildQuery(searchTerm: string, args: string[]): string {\n if (args.length === 0) {\n return searchTerm;\n }\n return searchTerm + this.separator + args.join(' ');\n }\n}\n","/**\n * Represents the different states of the gigamenu input.\n * New paradigm: input handles ONE thing at a time.\n */\nexport enum InputState {\n /** Menu is closed */\n Closed = 'closed',\n\n /** User is searching/selecting an action (page or command) */\n ActionSelection = 'actionSelection',\n\n /** User is inputting a parameter value */\n ParameterInput = 'parameterInput',\n}\n\n/**\n * Result of handling a keyboard event.\n */\nexport interface KeyboardHandlerResult {\n /** Whether the event was handled (should prevent default) */\n handled: boolean;\n\n /** Optional new state to transition to */\n newState?: InputState;\n}\n\n/**\n * Context provided to keyboard handlers.\n */\nexport interface KeyboardHandlerContext {\n /** The keyboard event */\n event: KeyboardEvent;\n\n /** Current query string */\n query: string;\n\n /** Parsed search term */\n searchTerm: string;\n\n /** Whether there's a separator in the query */\n hasSeparator: boolean;\n\n /** Currently selected menu item */\n selectedItem: { label: string; params?: string[]; paramProviders?: Record<string, unknown> } | null;\n\n /** Number of filtered items */\n itemCount: number;\n\n /** Current selected index in the menu */\n selectedIndex: number;\n\n /** Autocomplete suggestions */\n suggestions: { label: string; value: string }[];\n\n /** Currently selected suggestion index */\n suggestionIndex: number;\n\n /** Whether typeahead ghost text is available */\n hasTypeahead: boolean;\n\n /** Tab behavior config */\n tabBehavior: 'cycle' | 'accept-first';\n\n /** Separator character */\n separator: string;\n}\n\n/**\n * Actions that can be dispatched from keyboard handlers.\n */\nexport type KeyboardAction =\n | { type: 'navigate'; direction: 'up' | 'down' }\n | { type: 'navigateSuggestion'; direction: 'up' | 'down' }\n | { type: 'selectItem' }\n | { type: 'selectSuggestion' }\n | { type: 'completeItemLabel' }\n | { type: 'showAutocomplete' }\n | { type: 'hideAutocomplete' }\n | { type: 'close' }\n | { type: 'setQuery'; query: string };\n\n/**\n * Context for computing the current input state.\n */\nexport interface InputStateContext {\n isOpen: boolean;\n /** Whether an action has been locked/selected for parameter input */\n hasLockedAction: boolean;\n}\n\n/**\n * Compute the current input state based on menu status.\n */\nexport function computeInputState(ctx: InputStateContext): InputState {\n if (!ctx.isOpen) {\n return InputState.Closed;\n }\n\n if (ctx.hasLockedAction) {\n return InputState.ParameterInput;\n }\n\n return InputState.ActionSelection;\n}\n","/**\n * Scroll the selected menu item into view.\n */\nexport function scrollSelectedIntoView(\n container: HTMLElement | null,\n selectedIndex: number\n): void {\n if (!container) return;\n\n const selectedButton = container.querySelector(\n `[data-index=\"${selectedIndex}\"]`\n ) as HTMLElement | null;\n\n if (selectedButton) {\n selectedButton.scrollIntoView({ block: 'nearest' });\n }\n}\n\n/**\n * Scroll the selected autocomplete suggestion into view.\n */\nexport function scrollAutocompleteIntoView(\n container: HTMLElement | null,\n selectedIndex: number\n): void {\n if (!container) return;\n\n const selectedButton = container.querySelector(\n `[data-autocomplete-index=\"${selectedIndex}\"]`\n ) as HTMLElement | null;\n\n if (selectedButton) {\n selectedButton.scrollIntoView({ block: 'nearest' });\n }\n}\n","import { GigamenuItem } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Filter items based on search query.\n */\nexport function filterItems(\n items: GigamenuItem[],\n searchTerm: string,\n queryParser: QueryParser\n): GigamenuItem[] {\n const normalizedTerm = searchTerm.toLowerCase().trim();\n if (!normalizedTerm) {\n return items;\n }\n\n return items.filter((item) => matchesQuery(item, normalizedTerm, queryParser));\n}\n\n/**\n * Check if an item matches the search query.\n * Uses word-based matching across label, description, and keywords.\n */\nexport function matchesQuery(\n item: GigamenuItem,\n query: string,\n _queryParser: QueryParser\n): boolean {\n const searchableText = [\n item.label,\n item.description,\n ...(item.keywords ?? []),\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n const words = query.split(/\\s+/);\n return words.every((word) => searchableText.includes(word));\n}\n\n/**\n * Sort items by frecency scores (frequency + recency).\n */\nexport function sortByFrecency(\n items: GigamenuItem[],\n scores: Map<string, number>\n): GigamenuItem[] {\n if (scores.size === 0) return items;\n\n return [...items].sort((a, b) => {\n const scoreA = scores.get(a.id) ?? 0;\n const scoreB = scores.get(b.id) ?? 0;\n return scoreB - scoreA;\n });\n}\n\n/**\n * Build searchable text from an item for matching.\n */\nexport function buildSearchableText(item: GigamenuItem): string {\n return [item.label, item.description, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\n\n/**\n * Compute the current parameter index being edited.\n * Returns null if no parameter is being edited.\n */\nexport function computeCurrentParamIndex(\n item: GigamenuItem | null,\n args: string,\n argsCount: number\n): number | null {\n if (!item || !item.params || item.params.length === 0) return null;\n\n const endsWithSpace = args.endsWith(' ');\n\n // If user is still typing a param (no trailing space) and has typed at least one arg\n if (!endsWithSpace && argsCount > 0 && argsCount <= item.params.length) {\n return argsCount - 1; // Currently editing the last typed arg\n }\n\n // If we have fewer args than params, we're about to type the next param\n if (argsCount < item.params.length) return argsCount;\n\n // All params complete (with trailing space confirming completion)\n return null;\n}\n\n/**\n * Get the name of the current parameter being edited.\n */\nexport function computeCurrentParamName(\n item: GigamenuItem | null,\n paramIndex: number | null\n): string | null {\n if (paramIndex === null || !item || !item.params) return null;\n return item.params[paramIndex] ?? null;\n}\n\n/**\n * Compute the current partial value of the parameter being edited.\n */\nexport function computeCurrentParamValue(\n args: string,\n argsArray: string[],\n paramIndex: number | null\n): string {\n const trimmedArgs = args.trim();\n if (!trimmedArgs) return '';\n if (paramIndex === null) return '';\n\n const endsWithSpace = args.endsWith(' ');\n\n // If we're on the last arg and still typing\n if (!endsWithSpace && argsArray.length === paramIndex + 1) {\n return argsArray[paramIndex] ?? '';\n }\n\n // If we're starting a new arg (after a space)\n if (endsWithSpace || argsArray.length === paramIndex) {\n return '';\n }\n\n return '';\n}\n\n/**\n * Check if the selected item can be executed (has all required params).\n */\nexport function computeCanExecute(\n item: GigamenuItem | null,\n argsCount: number\n): boolean {\n if (!item) return false;\n if (!item.params || item.params.length === 0) return true;\n return argsCount >= item.params.length;\n}\n\n/**\n * Get completed arguments for display (excludes the incomplete arg being typed).\n */\nexport function computeCompletedArgsDisplay(\n display: string[],\n args: string\n): string[] {\n const endsWithSpace = args.endsWith(' ');\n\n // If args ends with space, all args are complete\n if (endsWithSpace || !args) return display;\n\n // Otherwise, exclude the last incomplete arg (shown in currentParamValue)\n return display.slice(0, -1);\n}\n\n/**\n * Get actual values for args (substituting labels with values from selected options).\n */\nexport function computeArgsValues(\n argsArray: string[],\n selectedOptions: Map<number, AutocompleteOption>\n): string[] {\n return argsArray.map((arg, index) => {\n const option = selectedOptions.get(index);\n // If we have a selected option for this param and the current arg matches its label, use the value\n if (option && arg === option.label) {\n return option.value;\n }\n return arg;\n });\n}\n\n/**\n * Check if the selected item has autocomplete available for the current param.\n */\nexport function computeHasAutocomplete(\n item: GigamenuItem | null,\n paramName: string | null\n): boolean {\n if (!item || !paramName) return false;\n return !!(item.paramProviders?.[paramName]);\n}\n","import { GigamenuItem, PARAM_COLORS } from '../types';\nimport {\n GigamenuItemContext,\n GigamenuEmptyContext,\n GigamenuFooterContext,\n} from '../gigamenu-templates.directive';\n\n/**\n * Get color class for a parameter index.\n */\nexport function getParamColor(index: number): string {\n return PARAM_COLORS[index % PARAM_COLORS.length];\n}\n\n/**\n * Create context for item template.\n */\nexport function createItemContext(\n item: GigamenuItem,\n index: number,\n selectedIndex: number\n): GigamenuItemContext {\n return {\n $implicit: item,\n index,\n selected: selectedIndex === index,\n };\n}\n\n/**\n * Create context for empty state template.\n */\nexport function createEmptyContext(query: string): GigamenuEmptyContext {\n return {\n $implicit: query,\n };\n}\n\n/**\n * Create context for footer template.\n */\nexport function createFooterContext(\n filteredCount: number,\n totalCount: number\n): GigamenuFooterContext {\n return {\n $implicit: filteredCount,\n total: totalCount,\n };\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Initial state for menu reset.\n */\nexport interface MenuResetState {\n query: string;\n selectedIndex: number;\n showAutocomplete: boolean;\n autocompleteSelectedIndex: number;\n selectedParamOptions: Map<number, AutocompleteOption>;\n}\n\n/**\n * Get the initial/reset state for the menu.\n */\nexport function getInitialMenuState(): MenuResetState {\n return {\n query: '',\n selectedIndex: 0,\n showAutocomplete: false,\n autocompleteSelectedIndex: 0,\n selectedParamOptions: new Map(),\n };\n}\n\n/**\n * Check if an input element is currently focused.\n */\nexport function isInputFocused(): boolean {\n const activeElement = document.activeElement;\n if (!activeElement) return false;\n\n const tagName = activeElement.tagName.toLowerCase();\n return (\n tagName === 'input' ||\n tagName === 'textarea' ||\n (activeElement as HTMLElement).isContentEditable\n );\n}\n\n/**\n * Check if the current search term matches the selected item's label.\n */\nexport function isSearchTermMatchingItem(\n searchTerm: string,\n itemLabel: string,\n queryParser: QueryParser\n): boolean {\n return queryParser.matchesLabel(searchTerm, itemLabel);\n}\n\n/**\n * Complete the selected item's label in the search input.\n * Returns the new query string.\n */\nexport function completeItemLabel(\n item: GigamenuItem,\n separator: string,\n queryParser: QueryParser\n): string {\n const escapedLabel = queryParser.escapeIfNeeded(item.label);\n const hasParams = item.params && item.params.length > 0;\n return hasParams ? escapedLabel + separator : escapedLabel;\n}\n","import { AutocompleteOption, ParamProvider } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Result from fetching autocomplete suggestions.\n */\nexport interface FetchResult {\n options: AutocompleteOption[];\n isAsync: boolean;\n}\n\n/**\n * Fetch autocomplete suggestions from a provider.\n */\nexport async function fetchAutocompleteSuggestions(\n provider: ParamProvider,\n query: string,\n cache: Map<string, AutocompleteOption[]>\n): Promise<FetchResult> {\n // Handle static array provider\n if (Array.isArray(provider)) {\n const cacheKey = `${JSON.stringify(provider)}-${query}`;\n if (cache.has(cacheKey)) {\n return { options: cache.get(cacheKey)!, isAsync: false };\n }\n cache.set(cacheKey, provider);\n return { options: provider, isAsync: false };\n }\n\n // Handle async function provider (server-side filtering)\n const result = await Promise.resolve(provider(query));\n return { options: result, isAsync: true };\n}\n\n/**\n * Filter suggestions client-side based on query.\n */\nexport function filterSuggestionsClientSide(\n options: AutocompleteOption[],\n query: string\n): AutocompleteOption[] {\n const lowerQuery = query.toLowerCase().trim();\n if (!lowerQuery) return options;\n return options.filter((opt) => opt.label.toLowerCase().includes(lowerQuery));\n}\n\n/**\n * Compute typeahead ghost text suggestion.\n * Returns the portion of the label that extends beyond the typed text.\n */\nexport function computeTypeaheadSuggestion(\n suggestions: AutocompleteOption[],\n selectedIndex: number,\n paramValue: string\n): string | null {\n if (suggestions.length === 0) return null;\n\n const suggestion = suggestions[selectedIndex] ?? suggestions[0];\n if (!suggestion) return null;\n\n // Return portion of label that extends beyond typed text (case-insensitive prefix match)\n const suggestionLabel = suggestion.label;\n if (suggestionLabel.toLowerCase().startsWith(paramValue.toLowerCase())) {\n return suggestionLabel.slice(paramValue.length);\n }\n return null;\n}\n\n/**\n * Context for building a query with a selected autocomplete option.\n */\nexport interface SelectionContext {\n searchTerm: string;\n separator: string;\n argsArray: string[];\n paramIndex: number | null;\n queryParser: QueryParser;\n}\n\n/**\n * Build the new query string after selecting an autocomplete option.\n */\nexport function buildQueryWithSelection(\n ctx: SelectionContext,\n option: AutocompleteOption,\n addTrailingSpace: boolean\n): string {\n if (ctx.paramIndex === null) return ctx.searchTerm;\n\n // Quote labels that contain spaces\n const escapedLabel = ctx.queryParser.escapeIfNeeded(option.label);\n\n // Replace current param with the selected option's label\n const newArgs = [...ctx.argsArray];\n newArgs[ctx.paramIndex] = escapedLabel;\n\n // Build new query with or without trailing space\n const baseQuery = ctx.searchTerm + ctx.separator + newArgs.join(' ');\n return addTrailingSpace ? baseQuery + ' ' : baseQuery;\n}\n\n/**\n * Result from selecting an autocomplete suggestion.\n */\nexport interface SelectionResult {\n newQuery: string;\n selectedOption: AutocompleteOption;\n paramIndex: number;\n}\n\n/**\n * Process autocomplete suggestion selection.\n * Returns the new query and the selected option for tracking.\n */\nexport function processAutocompleteSuggestionSelection(\n suggestions: AutocompleteOption[],\n selectedIdx: number,\n ctx: SelectionContext,\n addTrailingSpace: boolean\n): SelectionResult | null {\n const option = suggestions[selectedIdx];\n if (!option || ctx.paramIndex === null) return null;\n\n const newQuery = buildQueryWithSelection(ctx, option, addTrailingSpace);\n\n return {\n newQuery,\n selectedOption: option,\n paramIndex: ctx.paramIndex,\n };\n}\n\n/**\n * Result from selecting and cycling to next suggestion.\n */\nexport interface CycleResult extends SelectionResult {\n nextIndex: number;\n}\n\n/**\n * Process autocomplete suggestion selection with cycling to next.\n * zsh-style: select current and prepare for next Tab press.\n */\nexport function processAutocompleteSuggestionAndCycle(\n suggestions: AutocompleteOption[],\n currentIdx: number,\n ctx: SelectionContext\n): CycleResult | null {\n if (suggestions.length === 0) return null;\n\n const option = suggestions[currentIdx];\n if (!option || ctx.paramIndex === null) return null;\n\n // Don't add trailing space - keep cursor position for cycling\n const newQuery = buildQueryWithSelection(ctx, option, false);\n\n // Cycle to next suggestion\n const nextIdx = (currentIdx + 1) % suggestions.length;\n\n return {\n newQuery,\n selectedOption: option,\n paramIndex: ctx.paramIndex,\n nextIndex: nextIdx,\n };\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\n\n/**\n * Actions that can be dispatched from keyboard handlers.\n */\nexport type MenuAction =\n | { type: 'setSelectedIndex'; value: number }\n | { type: 'setQuery'; value: string }\n | { type: 'executeAction'; item: GigamenuItem }\n | { type: 'executeLockedAction' }\n | { type: 'close' }\n | { type: 'toggle' }\n | { type: 'open' }\n | { type: 'scrollIntoView' }\n | { type: 'lockAction'; item: GigamenuItem }\n | { type: 'unlockAction' }\n | { type: 'nextParameter' }\n | { type: 'previousParameter' }\n | { type: 'selectSuggestion'; option: AutocompleteOption };\n\n/**\n * Context for global keyboard handling.\n */\nexport interface GlobalKeydownContext {\n isOpen: boolean;\n isInputFocused: boolean;\n}\n\n/**\n * Handle global keydown events (Ctrl+K, /, Escape).\n * Returns action if handled, null otherwise.\n */\nexport function handleGlobalKeydown(\n event: KeyboardEvent,\n ctx: GlobalKeydownContext\n): MenuAction | null {\n // Ctrl/Cmd + K: Toggle menu\n if ((event.metaKey || event.ctrlKey) && event.key === 'k') {\n return { type: 'toggle' };\n }\n\n // /: Open menu (only when no input is focused)\n if (event.key === '/' && !ctx.isInputFocused) {\n return { type: 'open' };\n }\n\n // Escape: Close menu (only when input is NOT focused - let input handler deal with it)\n if (event.key === 'Escape' && ctx.isOpen && !ctx.isInputFocused) {\n return { type: 'close' };\n }\n\n return null;\n}\n\n/**\n * Context for action selection state.\n */\nexport interface ActionSelectionContext {\n items: GigamenuItem[];\n selectedIndex: number;\n selectedItem: GigamenuItem | null;\n}\n\n/**\n * Handle keyboard events in ActionSelection state.\n */\nexport function handleActionSelectionKeydown(\n event: KeyboardEvent,\n ctx: ActionSelectionContext\n): MenuAction[] {\n const actions: MenuAction[] = [];\n const item = ctx.selectedItem;\n\n switch (event.key) {\n case 'ArrowDown':\n actions.push({\n type: 'setSelectedIndex',\n value: Math.min(ctx.selectedIndex + 1, ctx.items.length - 1),\n });\n actions.push({ type: 'scrollIntoView' });\n break;\n\n case 'ArrowUp':\n actions.push({\n type: 'setSelectedIndex',\n value: Math.max(ctx.selectedIndex - 1, 0),\n });\n actions.push({ type: 'scrollIntoView' });\n break;\n\n case 'Tab':\n if (item) {\n // Tab: always tries to go to params first, or execute if no params\n if (item.params && item.params.length > 0) {\n actions.push({ type: 'lockAction', item });\n } else {\n actions.push({ type: 'executeAction', item });\n }\n }\n break;\n\n case 'Enter':\n if (item) {\n const hasRequiredParams = item.params && item.params.length > 0 && !hasOnlyOptionalParams(item);\n if (hasRequiredParams) {\n // Has required params - go to parameter input\n actions.push({ type: 'lockAction', item });\n } else {\n // No params or only optional - execute immediately\n actions.push({ type: 'executeAction', item });\n }\n }\n break;\n\n case 'Escape':\n actions.push({ type: 'close' });\n break;\n }\n\n return actions;\n}\n\n/**\n * Context for parameter input state.\n */\nexport interface ParameterInputContext {\n lockedItem: GigamenuItem;\n currentParamIndex: number;\n paramValues: string[];\n query: string;\n suggestions: AutocompleteOption[];\n selectedSuggestionIndex: number;\n}\n\n/**\n * Handle keyboard events in ParameterInput state.\n */\nexport function handleParameterInputKeydown(\n event: KeyboardEvent,\n ctx: ParameterInputContext\n): MenuAction[] {\n const actions: MenuAction[] = [];\n const item = ctx.lockedItem;\n const params = item.params ?? [];\n const currentParam = params[ctx.currentParamIndex];\n const isLastParam = ctx.currentParamIndex >= params.length - 1;\n const hasSuggestions = ctx.suggestions.length > 0;\n\n switch (event.key) {\n case 'ArrowDown':\n if (hasSuggestions) {\n actions.push({\n type: 'setSelectedIndex',\n value: Math.min(ctx.selectedSuggestionIndex + 1, ctx.suggestions.length - 1),\n });\n actions.push({ type: 'scrollIntoView' });\n }\n break;\n\n case 'ArrowUp':\n if (hasSuggestions) {\n actions.push({\n type: 'setSelectedIndex',\n value: Math.max(ctx.selectedSuggestionIndex - 1, 0),\n });\n actions.push({ type: 'scrollIntoView' });\n }\n break;\n\n case 'Tab':\n // Tab: select suggestion (if any), then go to next param or execute\n if (hasSuggestions) {\n actions.push({ type: 'selectSuggestion', option: ctx.suggestions[ctx.selectedSuggestionIndex] });\n }\n if (isLastParam) {\n // Execute - args will be built at dispatch time from current state\n actions.push({ type: 'executeLockedAction' });\n } else {\n actions.push({ type: 'nextParameter' });\n }\n break;\n\n case 'Enter':\n // Enter: select suggestion if any\n if (hasSuggestions && ctx.selectedSuggestionIndex >= 0) {\n actions.push({ type: 'selectSuggestion', option: ctx.suggestions[ctx.selectedSuggestionIndex] });\n }\n\n if (isLastParam) {\n // Execute - args will be built at dispatch time from current state\n actions.push({ type: 'executeLockedAction' });\n } else {\n // More params - go to next (Enter acts like Tab when more required params)\n actions.push({ type: 'nextParameter' });\n }\n break;\n\n case 'Escape':\n // Escape: go back one step (like Backspace on empty)\n if (ctx.currentParamIndex > 0) {\n // Go to previous parameter\n actions.push({ type: 'previousParameter' });\n } else {\n // At first param, go back to action selection\n actions.push({ type: 'unlockAction' });\n }\n break;\n\n case 'Backspace':\n // Backspace when query is empty: go back\n if (ctx.query === '') {\n if (ctx.currentParamIndex > 0) {\n // Go to previous parameter\n actions.push({ type: 'previousParameter' });\n } else {\n // At first param, go back to action selection\n actions.push({ type: 'unlockAction' });\n }\n }\n break;\n }\n\n return actions;\n}\n\n/**\n * Check if item has only optional parameters (none required).\n * For now, we treat all params as required. Can be extended later.\n */\nfunction hasOnlyOptionalParams(_item: GigamenuItem): boolean {\n // TODO: Add optional param support to GigamenuItem type\n return false;\n}\n\n/**\n * Handle zsh-like keyboard shortcuts (Ctrl+W, Ctrl+U).\n * Returns the new query if handled, null otherwise.\n */\nexport function handleZshShortcuts(\n event: KeyboardEvent,\n query: string\n): string | null {\n // Ctrl+W or Alt+Backspace or Ctrl+Backspace: Delete last word\n if (\n (event.ctrlKey && event.key === 'w') ||\n (event.altKey && event.key === 'Backspace') ||\n (event.ctrlKey && event.key === 'Backspace')\n ) {\n return deleteLastWord(query);\n }\n\n // Ctrl+U: Clear line\n if (event.ctrlKey && event.key === 'u') {\n return '';\n }\n\n return null;\n}\n\n/**\n * Delete the last word from the query.\n */\nexport function deleteLastWord(query: string): string {\n if (!query) return '';\n\n let newQuery = query.replace(/\\s+$/, '');\n const lastSpaceIndex = newQuery.lastIndexOf(' ');\n if (lastSpaceIndex !== -1) {\n newQuery = newQuery.substring(0, lastSpaceIndex);\n } else {\n newQuery = '';\n }\n\n return newQuery;\n}\n\n/**\n * Check if any actions were generated.\n */\nexport function hasActions(actions: MenuAction[]): boolean {\n return actions.length > 0;\n}\n","// Scroll utilities\nexport { scrollSelectedIntoView, scrollAutocompleteIntoView } from './scroll-utils';\n\n// Search functions\nexport { filterItems, matchesQuery, sortByFrecency, buildSearchableText } from './search';\n\n// Parameter state functions\nexport {\n computeCurrentParamIndex,\n computeCurrentParamName,\n computeCurrentParamValue,\n computeCanExecute,\n computeCompletedArgsDisplay,\n computeArgsValues,\n computeHasAutocomplete,\n} from './parameter-state';\n\n// Template context functions\nexport {\n getParamColor,\n createItemContext,\n createEmptyContext,\n createFooterContext,\n} from './template-contexts';\n\n// Menu lifecycle functions\nexport {\n getInitialMenuState,\n isInputFocused,\n isSearchTermMatchingItem,\n completeItemLabel,\n} from './menu-lifecycle';\nexport type { MenuResetState } from './menu-lifecycle';\n\n// Autocomplete functions\nexport {\n fetchAutocompleteSuggestions,\n filterSuggestionsClientSide,\n computeTypeaheadSuggestion,\n buildQueryWithSelection,\n processAutocompleteSuggestionSelection,\n processAutocompleteSuggestionAndCycle,\n} from './autocomplete';\nexport type { FetchResult, SelectionContext, SelectionResult, CycleResult } from './autocomplete';\n\n// Keyboard handler functions\nexport {\n handleGlobalKeydown,\n handleZshShortcuts,\n deleteLastWord,\n handleActionSelectionKeydown,\n handleParameterInputKeydown,\n hasActions,\n} from './keyboard-handlers';\nexport type {\n MenuAction,\n GlobalKeydownContext,\n ActionSelectionContext,\n ParameterInputContext,\n} from './keyboard-handlers';\n","import { Injectable, PLATFORM_ID, Inject } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\ninterface FrecencyEntry {\n itemId: string;\n count: number;\n lastUsed: number;\n}\n\ninterface FrecencyData {\n [searchTerm: string]: FrecencyEntry[];\n}\n\nconst STORAGE_KEY = 'gigamenu_frecency';\nconst GLOBAL_KEY = '__global__';\nconst MAX_ENTRIES_PER_TERM = 10;\nconst MAX_TERMS = 100;\nconst DECAY_FACTOR = 0.9;\n\n@Injectable({ providedIn: 'root' })\nexport class FrecencyService {\n private data: FrecencyData = {};\n private readonly isBrowser: boolean;\n\n constructor(@Inject(PLATFORM_ID) platformId: object) {\n this.isBrowser = isPlatformBrowser(platformId);\n this.load();\n }\n\n /**\n * Record that an item was selected for a given search term.\n */\n recordSelection(searchTerm: string, itemId: string): void {\n // Always record to global for overall frecency\n this.recordToKey(GLOBAL_KEY, itemId);\n\n // Also record to specific search term if provided\n const normalizedTerm = this.normalizeTerm(searchTerm);\n if (normalizedTerm) {\n this.recordToKey(normalizedTerm, itemId);\n }\n\n this.pruneAndSave();\n }\n\n private recordToKey(key: string, itemId: string): void {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n const entries = this.data[key];\n const existing = entries.find((e) => e.itemId === itemId);\n\n if (existing) {\n existing.count++;\n existing.lastUsed = Date.now();\n } else {\n entries.push({\n itemId,\n count: 1,\n lastUsed: Date.now(),\n });\n }\n\n // Keep only top entries\n this.data[key] = entries\n .sort((a, b) => this.calculateScore(b) - this.calculateScore(a))\n .slice(0, MAX_ENTRIES_PER_TERM);\n }\n\n /**\n * Get frecency scores for items matching a search term.\n * Returns a map of itemId -> score (higher is better).\n */\n getScores(searchTerm: string): Map<string, number> {\n const scores = new Map<string, number>();\n const normalizedTerm = this.normalizeTerm(searchTerm);\n\n // If no search term, return global scores\n if (!normalizedTerm) {\n const globalEntries = this.data[GLOBAL_KEY];\n if (globalEntries) {\n for (const entry of globalEntries) {\n scores.set(entry.itemId, this.calculateScore(entry));\n }\n }\n return scores;\n }\n\n // Exact match for search term\n const exactEntries = this.data[normalizedTerm];\n if (exactEntries) {\n for (const entry of exactEntries) {\n const score = this.calculateScore(entry);\n scores.set(entry.itemId, score);\n }\n }\n\n // Prefix matches (for partial typing)\n for (const [term, entries] of Object.entries(this.data)) {\n if (term !== GLOBAL_KEY && term !== normalizedTerm && term.startsWith(normalizedTerm)) {\n for (const entry of entries) {\n const currentScore = scores.get(entry.itemId) ?? 0;\n // Prefix matches get reduced weight\n const prefixScore = this.calculateScore(entry) * 0.5;\n scores.set(entry.itemId, Math.max(currentScore, prefixScore));\n }\n }\n }\n\n return scores;\n }\n\n /**\n * Get the most likely item for a search term (for auto-selection).\n * Returns itemId if there's a strong match, null otherwise.\n */\n getTopMatch(searchTerm: string): string | null {\n const normalizedTerm = this.normalizeTerm(searchTerm);\n if (!normalizedTerm) return null;\n\n const entries = this.data[normalizedTerm];\n if (!entries || entries.length === 0) return null;\n\n const topEntry = entries[0];\n const score = this.calculateScore(topEntry);\n\n // Only auto-select if strong confidence (used multiple times recently)\n if (topEntry.count >= 2 && score > 5) {\n return topEntry.itemId;\n }\n\n return null;\n }\n\n private calculateScore(entry: FrecencyEntry): number {\n const ageInHours = (Date.now() - entry.lastUsed) / (60 * 60 * 24);\n const recencyScore = Math.pow(DECAY_FACTOR, ageInHours);\n return entry.count * recencyScore;\n }\n\n private normalizeTerm(term: string): string {\n return term.toLowerCase().trim();\n }\n\n private load(): void {\n if (!this.isBrowser) return;\n\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n this.data = JSON.parse(stored);\n }\n } catch {\n this.data = {};\n }\n }\n\n private pruneAndSave(): void {\n if (!this.isBrowser) return;\n\n // Prune old terms if we have too many\n const terms = Object.keys(this.data);\n if (terms.length > MAX_TERMS) {\n const termScores = terms.map((term) => ({\n term,\n maxScore: Math.max(...this.data[term].map((e) => this.calculateScore(e))),\n }));\n termScores.sort((a, b) => b.maxScore - a.maxScore);\n\n const keepTerms = new Set(termScores.slice(0, MAX_TERMS).map((t) => t.term));\n for (const term of terms) {\n if (!keepTerms.has(term)) {\n delete this.data[term];\n }\n }\n }\n\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(this.data));\n } catch {\n // Storage full or unavailable\n }\n }\n}\n","import {\n Component,\n signal,\n computed,\n effect,\n ElementRef,\n viewChild,\n contentChild,\n HostListener,\n PLATFORM_ID,\n Inject,\n} from '@angular/core';\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport { GigamenuService } from './gigamenu.service';\nimport { FrecencyService } from './frecency.service';\nimport { GigamenuItem, AutocompleteOption, GigamenuProviderItem } from './types';\nimport {\n GigamenuItemTemplate,\n GigamenuEmptyTemplate,\n GigamenuHeaderTemplate,\n GigamenuFooterTemplate,\n GigamenuPanelTemplate,\n} from './gigamenu-templates.directive';\nimport { QueryParser } from './query-parser';\nimport { InputState, computeInputState } from './input-state';\nimport {\n // Scroll utilities\n scrollSelectedIntoView,\n // Search functions\n filterItems,\n sortByFrecency,\n // Parameter state functions\n computeHasAutocomplete,\n // Template context functions\n getParamColor,\n createItemContext,\n createEmptyContext,\n createFooterContext,\n // Menu lifecycle functions\n isInputFocused,\n // Autocomplete functions\n fetchAutocompleteSuggestions,\n filterSuggestionsClientSide,\n // Keyboard handler functions\n handleGlobalKeydown,\n handleZshShortcuts,\n handleActionSelectionKeydown,\n handleParameterInputKeydown,\n hasActions,\n // Types\n type MenuAction,\n type ActionSelectionContext,\n type ParameterInputContext,\n} from './core';\n\n@Component({\n selector: 'gm-gigamenu',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: 'gigamenu.component.html',\n styles: `\n :host {\n display: contents;\n }\n `,\n})\nexport class GigamenuComponent {\n private readonly searchInput = viewChild<ElementRef<HTMLInputElement>>('searchInput');\n private readonly listContainer = viewChild<ElementRef<HTMLDivElement>>('listContainer');\n private readonly isBrowser: boolean;\n\n // Template queries\n protected readonly itemTemplate = contentChild(GigamenuItemTemplate);\n protected readonly emptyTemplate = contentChild(GigamenuEmptyTemplate);\n protected readonly headerTemplate = contentChild(GigamenuHeaderTemplate);\n protected readonly footerTemplate = contentChild(GigamenuFooterTemplate);\n protected readonly panelTemplate = contentChild(GigamenuPanelTemplate);\n\n // Core state signals\n protected readonly query = signal('');\n protected readonly selectedIndex = signal(0);\n\n // Step-by-step input state\n protected readonly lockedAction = signal<GigamenuItem | null>(null);\n protected readonly paramValues = signal<string[]>([]);\n\n // Autocomplete state signals\n protected readonly autocompleteSuggestions = signal<AutocompleteOption[]>([]);\n private autocompleteCache = new Map<string, AutocompleteOption[]>();\n private readonly selectedParamOptions = signal<Map<number, AutocompleteOption>>(new Map());\n\n // Dynamic provider state\n private readonly providerResults = signal<Map<string, GigamenuItem[]>>(new Map());\n private providerTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private providerGeneration = new Map<string, number>();\n\n // Query parsing (simplified - only used for filtering)\n private readonly queryParser = computed(() => {\n const separator = this.service.config().argSeparator ?? ' ';\n return new QueryParser(separator);\n });\n\n // Selected item from display list\n protected readonly selectedItem = computed(() => {\n const items = this.displayItems();\n const index = this.selectedIndex();\n return items[index] ?? null;\n });\n\n protected readonly currentParamIndex = computed(() => {\n const action = this.lockedAction();\n if (!action || !action.params) return null;\n const filled = this.paramValues().length;\n if (filled >= action.params.length) return null;\n return filled;\n });\n\n protected readonly currentParamName = computed(() => {\n const action = this.lockedAction();\n const idx = this.currentParamIndex();\n if (!action || idx === null || !action.params) return null;\n return action.params[idx] ?? null;\n });\n\n protected readonly hasAutocomplete = computed(() => {\n const action = this.lockedAction();\n const paramName = this.currentParamName();\n if (!action || !paramName) return false;\n return computeHasAutocomplete(action, paramName);\n });\n\n protected readonly currentState = computed((): InputState => {\n return computeInputState({\n isOpen: this.service.isOpen(),\n hasLockedAction: this.lockedAction() !== null,\n });\n });\n\n protected readonly filteredItems = computed(() => {\n const searchTerm = this.query().toLowerCase().trim();\n const items = this.service.items();\n const maxResults = this.service.config().maxResults ?? 10;\n\n if (!searchTerm) {\n const scores = this.frecency.getScores('');\n return sortByFrecency(items, scores).slice(0, maxResults);\n }\n\n const matched = filterItems(items, searchTerm, this.queryParser());\n const scores = this.frecency.getScores(searchTerm);\n return sortByFrecency(matched, scores).slice(0, maxResults);\n });\n\n // Display items: actions in ActionSelection, suggestions in ParameterInput\n protected readonly displayItems = computed((): GigamenuItem[] => {\n const state = this.currentState();\n if (state === InputState.ParameterInput) {\n // In parameter mode, show autocomplete suggestions as items\n return this.autocompleteSuggestions().map((opt) => ({\n id: `suggestion-${opt.value}`,\n label: opt.label,\n description: opt.value !== opt.label ? opt.value : undefined,\n category: 'command' as const,\n action: () => {}, // Handled via selectSuggestion action\n }));\n }\n\n // Action selection: static items + dynamic provider results\n const staticItems = this.filteredItems();\n const dynamic: GigamenuItem[] = [];\n for (const items of this.providerResults().values()) {\n dynamic.push(...items);\n }\n return [...staticItems, ...dynamic];\n });\n\n // Template helper\n protected getParamColor = getParamColor;\n\n constructor(\n protected readonly service: GigamenuService,\n private readonly frecency: FrecencyService,\n @Inject(PLATFORM_ID) platformId: object\n ) {\n this.isBrowser = isPlatformBrowser(platformId);\n\n // Focus effect\n effect(() => {\n if (this.service.isOpen() && this.isBrowser) {\n setTimeout(() => this.searchInput()?.nativeElement.focus(), 0);\n }\n });\n\n // Frecency auto-select effect (only in ActionSelection mode)\n effect(() => {\n const state = this.currentState();\n if (state !== InputState.ActionSelection) return;\n\n const items = this.filteredItems();\n const query = this.query();\n\n if (query && items.length > 0) {\n const topMatch = this.frecency.getTopMatch(query);\n if (topMatch) {\n const idx = items.findIndex((item) => item.id === topMatch);\n if (idx !== -1) {\n this.selectedIndex.set(idx);\n return;\n }\n }\n }\n this.selectedIndex.set(0);\n });\n\n // Dynamic provider effect (only in ActionSelection mode)\n effect(() => {\n const state = this.currentState();\n const providers = this.service.providers();\n const query = this.query();\n\n if (state !== InputState.ActionSelection) {\n this.clearProviderResults();\n return;\n }\n\n // Cancel timers for providers that no longer exist\n for (const id of this.providerTimers.keys()) {\n if (!providers.has(id)) {\n clearTimeout(this.providerTimers.get(id)!);\n this.providerTimers.delete(id);\n }\n }\n // Drop results from removed providers\n const currentResults = this.providerResults();\n if (currentResults.size > 0) {\n let changed = false;\n const next = new Map(currentResults);\n for (const id of next.keys()) {\n if (!providers.has(id)) {\n next.delete(id);\n changed = true;\n }\n }\n if (changed) this.providerResults.set(next);\n }\n\n // Schedule each provider\n providers.forEach((registered, id) => {\n const trimmed = query.trim();\n if (trimmed.length < registered.options.minQueryLength) {\n // Clear any previous results for this provider when below threshold\n if (this.providerResults().has(id)) {\n this.providerResults.update((map) => {\n const next = new Map(map);\n next.delete(id);\n return next;\n });\n }\n const existing = this.providerTimers.get(id);\n if (existing) {\n clearTimeout(existing);\n this.providerTimers.delete(id);\n }\n return;\n }\n\n const existing = this.providerTimers.get(id);\n if (existing) clearTimeout(existing);\n\n const generation = (this.providerGeneration.get(id) ?? 0) + 1;\n this.providerGeneration.set(id, generation);\n\n const timer = setTimeout(async () => {\n this.providerTimers.delete(id);\n try {\n const raw = await registered.provider(trimmed);\n if (this.providerGeneration.get(id) !== generation) return;\n const items = this.normalizeProviderItems(raw, id, registered.options.group);\n this.providerResults.update((map) => {\n const next = new Map(map);\n next.set(id, items);\n return next;\n });\n } catch (err) {\n console.error(`gigamenu provider \"${id}\" failed:`, err);\n }\n }, registered.options.debounceMs);\n\n this.providerTimers.set(id, timer);\n });\n });\n\n // Autocomplete effect (only in ParameterInput mode)\n effect(() => {\n const action = this.lockedAction();\n const paramIndex = this.currentParamIndex();\n const paramName = this.currentParamName();\n const paramValue = this.query(); // In ParameterInput, query is the param value\n\n if (!action || paramIndex === null || !paramName) {\n this.autocompleteSuggestions.set([]);\n return;\n }\n\n const provider = action.paramProviders?.[paramName];\n if (!provider) {\n this.autocompleteSuggestions.set([]);\n return;\n }\n\n this.fetchSuggestions(provider, paramValue);\n });\n }\n\n @HostListener('document:keydown', ['$event'])\n onGlobalKeydown(event: KeyboardEvent): void {\n if (!this.isBrowser) return;\n\n const action = handleGlobalKeydown(event, {\n isOpen: this.service.isOpen(),\n isInputFocused: isInputFocused(),\n });\n\n if (action) {\n event.preventDefault();\n this.dispatchAction(action);\n }\n }\n\n protected onInputKeydown(event: KeyboardEvent): void {\n const state = this.currentState();\n\n // Handle zsh-like shortcuts first\n const newQuery = handleZshShortcuts(event, this.query());\n if (newQuery !== null) {\n event.preventDefault();\n this.query.set(newQuery);\n return;\n }\n\n // Get actions from state-specific handler\n const actions = this.getActionsForState(state, event);\n\n if (hasActions(actions)) {\n event.preventDefault();\n actions.forEach((action) => this.dispatchAction(action));\n }\n }\n\n private getActionsForState(state: InputState, event: KeyboardEvent): MenuAction[] {\n switch (state) {\n case InputState.ActionSelection: {\n const ctx: ActionSelectionContext = {\n items: this.displayItems(),\n selectedIndex: this.selectedIndex(),\n selectedItem: this.selectedItem(),\n };\n return handleActionSelectionKeydown(event, ctx);\n }\n case InputState.ParameterInput: {\n const action = this.lockedAction();\n if (!action) return [];\n const ctx: ParameterInputContext = {\n lockedItem: action,\n currentParamIndex: this.currentParamIndex() ?? 0,\n paramValues: this.paramValues(),\n query: this.query(),\n suggestions: this.autocompleteSuggestions(),\n selectedSuggestionIndex: this.selectedIndex(),\n };\n return handleParameterInputKeydown(event, ctx);\n }\n default:\n return [];\n }\n }\n\n private dispatchAction(action: MenuAction): void {\n switch (action.type) {\n case 'setSelectedIndex':\n this.selectedIndex.set(action.value);\n break;\n case 'setQuery':\n this.query.set(action.value);\n break;\n case 'executeAction':\n // Execute an action directly (no params)\n this.executeItemWithArgs(action.item, []);\n break;\n case 'executeLockedAction':\n // Build args from current state (includes any changes from selectSuggestion)\n const lockedItem = this.lockedAction();\n if (lockedItem) {\n const args = this.buildArgsWithValues();\n this.executeItemWithArgs(lockedItem, args);\n }\n break;\n case 'close':\n this.close();\n break;\n case 'toggle':\n this.service.toggle();\n break;\n case 'open':\n this.service.open();\n break;\n case 'scrollIntoView':\n scrollSelectedIntoView(this.listContainer()?.nativeElement ?? null, this.selectedIndex());\n break;\n case 'lockAction':\n this.lockedAction.set(action.item);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'unlockAction':\n this.lockedAction.set(null);\n this.paramValues.set([]);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'nextParameter':\n // Push current query value to paramValues, clear query\n this.paramValues.update((values) => [...values, this.query()]);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'previousParameter':\n // Pop last param value back to query\n const values = this.paramValues();\n if (values.length > 0) {\n const lastValue = values[values.length - 1];\n this.paramValues.update((v) => v.slice(0, -1));\n this.query.set(lastValue);\n this.selectedIndex.set(0);\n }\n break;\n case 'selectSuggestion':\n this.selectSuggestion(action.option);\n break;\n }\n }\n\n protected onQueryChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.query.set(value);\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) {\n this.close();\n }\n }\n\n protected onItemClick(item: GigamenuItem, index: number): void {\n // Only proceed if this is the selected item\n if (this.selectedIndex() !== index) {\n this.selectedIndex.set(index);\n return;\n }\n\n const state = this.currentState();\n if (state === InputState.ParameterInput) {\n // In parameter mode, clicking selects the suggestion\n const suggestions = this.autocompleteSuggestions();\n const option = suggestions[index];\n if (option) {\n this.selectSuggestion(option);\n }\n } else {\n // In action selection mode, trigger the action selection\n const actions = handleActionSelectionKeydown(\n new KeyboardEvent('keydown', { key: 'Enter' }),\n {\n items: this.displayItems(),\n selectedIndex: index,\n selectedItem: item,\n }\n );\n actions.forEach((action) => this.dispatchAction(action));\n }\n }\n\n private executeItemWithArgs(item: GigamenuItem, args: string[]): void {\n // Record frecency for the action\n this.frecency.recordSelection(this.query(), item.id);\n\n // Build args string from array\n const argsStr = args.length > 0 ? args.join(' ') : undefined;\n\n this.close();\n item.action(argsStr);\n }\n\n private selectSuggestion(option: AutocompleteOption): void {\n // Set the query to the selected option's label (for display)\n this.query.set(option.label);\n\n // Track the selected option for value substitution when executing\n const paramIndex = this.currentParamIndex();\n if (paramIndex !== null) {\n this.selectedParamOptions.update((map) => {\n const newMap = new Map(map);\n newMap.set(paramIndex, option);\n return newMap;\n });\n }\n }\n\n /**\n * Build args array using values from selectedParamOptions when available.\n * For each param, if a suggestion was selected, use its value; otherwise use the typed text.\n */\n private buildArgsWithValues(): string[] {\n const paramValues = this.paramValues();\n const currentQuery = this.query();\n const selectedOptions = this.selectedParamOptions();\n\n const args: string[] = [];\n\n // Add completed param values (use selected option's value if available)\n for (let i = 0; i < paramValues.length; i++) {\n const selectedOption = selectedOptions.get(i);\n if (selectedOption) {\n args.push(selectedOption.value);\n } else {\n args.push(paramValues[i]);\n }\n }\n\n // Add current param value (use selected option's value if available)\n if (currentQuery) {\n const currentParamIdx = this.currentParamIndex();\n if (currentParamIdx !== null) {\n const selectedOption = selectedOptions.get(currentParamIdx);\n if (selectedOption) {\n args.push(selectedOption.value);\n } else {\n args.push(currentQuery);\n }\n } else {\n args.push(currentQuery);\n }\n }\n\n return args.filter(Boolean);\n }\n\n // Template context methods\n protected getItemContext(item: GigamenuItem, index: number) {\n return createItemContext(item, index, this.selectedIndex());\n }\n\n protected getEmptyContext() {\n return createEmptyContext(this.query());\n }\n\n protected getFooterContext() {\n return createFooterContext(this.displayItems().length, this.service.items().length);\n }\n\n protected getHeaderContext() {\n return {\n $implicit: this.query(),\n query: this.query(),\n lockedAction: this.lockedAction(),\n paramValues: this.paramValues(),\n currentParamName: this.currentParamName(),\n placeholder: this.service.config().placeholder ?? '',\n onQueryChange: (value: string) => this.query.set(value),\n onKeydown: (event: KeyboardEvent) => this.onInputKeydown(event),\n onUnlockAction: () => this.unlockActionFromUI(),\n onGoToParam: (index: number) => this.goToParam(index),\n };\n }\n\n protected getPanelContext() {\n return {\n $implicit: this.displayItems(),\n items: this.displayItems(),\n query: this.query(),\n lockedAction: this.lockedAction(),\n paramValues: this.paramValues(),\n selectedIndex: this.selectedIndex(),\n placeholder: this.service.config().placeholder ?? '',\n onItemClick: (item: GigamenuItem, index: number) => this.onItemClick(item, index),\n onSelectIndex: (index: number) => this.selectedIndex.set(index),\n onQueryChange: (query: string) => this.query.set(query),\n onClose: () => this.close(),\n };\n }\n\n // Autocomplete methods\n private async fetchSuggestions(provider: NonNullable<GigamenuItem['paramProviders']>[string], query: string): Promise<void> {\n try {\n const { options, isAsync } = await fetchAutocompleteSuggestions(provider, query, this.autocompleteCache);\n const filtered = isAsync ? options : filterSuggestionsClientSide(options, query);\n this.autocompleteSuggestions.set(filtered);\n this.selectedIndex.set(0);\n } catch (error) {\n console.error('Error fetching autocomplete suggestions:', error);\n this.autocompleteSuggestions.set([]);\n }\n }\n\n private close(): void {\n this.service.close();\n this.query.set('');\n this.selectedIndex.set(0);\n this.lockedAction.set(null);\n this.paramValues.set([]);\n this.autocompleteCache.clear();\n this.selectedParamOptions.set(new Map());\n this.clearProviderResults();\n }\n\n private clearProviderResults(): void {\n for (const timer of this.providerTimers.values()) clearTimeout(timer);\n this.providerTimers.clear();\n // Bump all generations to invalidate any in-flight responses\n for (const id of this.providerGeneration.keys()) {\n this.providerGeneration.set(id, (this.providerGeneration.get(id) ?? 0) + 1);\n }\n if (this.providerResults().size > 0) {\n this.providerResults.set(new Map());\n }\n }\n\n private normalizeProviderItems(\n raw: GigamenuProviderItem[],\n providerId: string,\n group: string\n ): GigamenuItem[] {\n return raw.map((item) => ({\n ...item,\n category: item.category ?? 'command',\n providerId,\n group: item.group ?? (group || undefined),\n }));\n }\n\n // Template helper for going back from breadcrumb\n protected unlockActionFromUI(): void {\n this.dispatchAction({ type: 'unlockAction' });\n }\n\n protected goToParam(index: number): void {\n // Go back to a specific parameter\n const values = this.paramValues();\n if (index < values.length) {\n // Set query to the value at that index\n this.query.set(values[index]);\n // Keep only values before that index\n this.paramValues.set(values.slice(0, index));\n this.selectedIndex.set(0);\n }\n }\n}\n","@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-start justify-center pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full max-w-xl min-h-50 overflow-hidden rounded-xl border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">›</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">›</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"max-h-80 overflow-y-auto p-2\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↑</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↓</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↵</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"flxgde-gigamenu.mjs","sources":["../../../src/lib/types.ts","../../../src/lib/gigamenu.service.ts","../../../src/lib/gigamenu-templates.directive.ts","../../../src/lib/query-parser.ts","../../../src/lib/input-state.ts","../../../src/lib/core/scroll-utils.ts","../../../src/lib/core/search.ts","../../../src/lib/core/parameter-state.ts","../../../src/lib/core/template-contexts.ts","../../../src/lib/core/menu-lifecycle.ts","../../../src/lib/core/autocomplete.ts","../../../src/lib/core/keyboard-handlers.ts","../../../src/lib/core/index.ts","../../../src/lib/frecency.service.ts","../../../src/lib/gigamenu.component.ts","../../../src/lib/gigamenu.component.html","../../../src/flxgde-gigamenu.ts"],"sourcesContent":["export type GigamenuItemCategory = 'page' | 'command';\n\n/**\n * Autocomplete option for parameter suggestions.\n * label: Display text shown in the autocomplete dropdown\n * value: Actual value that gets passed to the action\n */\nexport interface AutocompleteOption {\n label: string;\n value: string;\n}\n\n/**\n * Provider for autocomplete suggestions.\n * Can be either a static array of options or an async function that returns options.\n */\nexport type ParamProvider =\n | AutocompleteOption[]\n | ((query: string) => Promise<AutocompleteOption[]> | AutocompleteOption[]);\n\nexport interface GigamenuItem {\n id: string;\n label: string;\n description?: string;\n /** Emoji or text icon */\n icon?: string;\n /** CSS class for icon libraries (e.g., 'pi pi-home', 'fa fa-home') */\n iconClass?: string;\n keywords?: string[];\n category: GigamenuItemCategory;\n /** Action to execute. Receives args string if user typed text after the separator. */\n action: (args?: string) => void;\n /** Required parameter names for this item (e.g., ['id', 'commentId']) */\n params?: string[];\n /**\n * Autocomplete providers for parameters.\n * Key: parameter name (must match a name in params array)\n * Value: ParamProvider (static array or async function)\n */\n paramProviders?: Record<string, ParamProvider>;\n /**\n * Optional section/group label. Items supplied by dynamic providers typically\n * set this so the UI can render them under a heading (e.g. \"Recipes\").\n */\n group?: string;\n /** Provider id when produced by a dynamic provider. Set automatically. */\n providerId?: string;\n}\n\n/**\n * A dynamic provider returns items that depend on the current query, e.g. results\n * fetched from a server. Returned items skip the built-in fuzzy filter.\n */\nexport type GigamenuProvider = (\n query: string\n) => Promise<GigamenuProviderItem[]> | GigamenuProviderItem[];\n\n/**\n * Items returned from a provider. Same shape as GigamenuItem but `category` is\n * optional — it defaults to 'command'. Providers typically omit it.\n */\nexport type GigamenuProviderItem = Omit<GigamenuItem, 'category'> & {\n category?: GigamenuItemCategory;\n};\n\nexport interface GigamenuProviderOptions {\n /** Minimum query length before the provider is invoked. Default: 2. */\n minQueryLength?: number;\n /** Debounce window in ms before invoking the provider. Default: 200. */\n debounceMs?: number;\n /** Optional group label applied to all items from this provider. */\n group?: string;\n}\n\n/** Colors for parameter highlighting */\nexport const PARAM_COLORS = [\n 'text-blue-500 dark:text-blue-400',\n 'text-green-500 dark:text-green-400',\n 'text-orange-500 dark:text-orange-400',\n 'text-pink-500 dark:text-pink-400',\n 'text-cyan-500 dark:text-cyan-400',\n] as const;\n\nexport interface GigamenuPage extends Omit<GigamenuItem, 'category' | 'action'> {\n path: string;\n}\n\nexport interface GigamenuCommand extends Omit<GigamenuItem, 'category'> {\n shortcut?: string;\n}\n\nexport interface GigamenuConfig {\n placeholder?: string;\n maxResults?: number;\n autoDiscoverRoutes?: boolean;\n /** Separator between search query and arguments (default: ' ') */\n argSeparator?: string;\n /** CSS class name for dark mode (default: 'dark') */\n darkModeClass?: string;\n /** Tab behavior for autocomplete: 'cycle' always cycles, 'accept-first' accepts on first tab (default: 'cycle') */\n autocompleteTabBehavior?: 'cycle' | 'accept-first';\n /** When to dismiss autocomplete overlay: 'on-type' hides on any keystroke, 'manual' only on Escape/selection (default: 'on-type') */\n autocompleteDismiss?: 'on-type' | 'manual';\n}\n\nexport const DEFAULT_CONFIG: GigamenuConfig = {\n placeholder: 'Search pages and commands...',\n maxResults: 10,\n autoDiscoverRoutes: true,\n argSeparator: ' ',\n darkModeClass: 'dark',\n autocompleteTabBehavior: 'cycle',\n autocompleteDismiss: 'on-type',\n};\n\n/**\n * Base interface for defining a command in a separate file.\n * Each command file should export a constant implementing this interface.\n */\nexport interface CommandDefinition {\n readonly id: string;\n readonly label: string;\n readonly description?: string;\n readonly icon?: string;\n readonly iconClass?: string;\n readonly keywords?: string[];\n readonly shortcut?: string;\n execute(): void;\n}\n\n/**\n * Helper function to define a command with type safety.\n */\nexport function defineCommand(command: CommandDefinition): CommandDefinition {\n return command;\n}\n\n/**\n * Information about a route passed to the filter function.\n */\nexport interface RouteInfo {\n path: string;\n fullPath: string;\n data?: Record<string, unknown>;\n title?: string;\n}\n\n/**\n * Filter function to include/exclude routes from discovery.\n * Return true to include the route, false to exclude it.\n */\nexport type RouteFilter = (route: RouteInfo) => boolean;\n\n/**\n * Mapped page data returned from the map function.\n */\nexport interface MappedPage {\n label?: string;\n description?: string;\n icon?: string;\n iconClass?: string;\n keywords?: string[];\n}\n\n/**\n * Map function to customize page data for discovered routes.\n * Return partial page data to override defaults, or null to skip the route.\n */\nexport type RouteMapper = (route: RouteInfo) => MappedPage | null;\n\n/**\n * Options for route discovery.\n */\nexport interface DiscoverRoutesOptions {\n filter?: RouteFilter;\n map?: RouteMapper;\n}\n","import { Injectable, signal, computed } from '@angular/core';\nimport { Router, Routes } from '@angular/router';\nimport {\n GigamenuItem,\n GigamenuCommand,\n GigamenuPage,\n GigamenuConfig,\n DEFAULT_CONFIG,\n DiscoverRoutesOptions,\n RouteInfo,\n GigamenuProvider,\n GigamenuProviderOptions,\n} from './types';\n\ninterface RegisteredProvider {\n provider: GigamenuProvider;\n options: Required<GigamenuProviderOptions>;\n}\n\nconst DEFAULT_PROVIDER_OPTIONS: Required<GigamenuProviderOptions> = {\n minQueryLength: 2,\n debounceMs: 200,\n group: '',\n};\n\n@Injectable({ providedIn: 'root' })\nexport class GigamenuService {\n private _router?: Router;\n\n private readonly _items = signal<Map<string, GigamenuItem>>(new Map());\n private readonly _providers = signal<Map<string, RegisteredProvider>>(new Map());\n private readonly _isOpen = signal(false);\n private readonly _config = signal<GigamenuConfig>(DEFAULT_CONFIG);\n\n readonly items = computed(() => Array.from(this._items().values()));\n readonly providers = this._providers.asReadonly();\n readonly isOpen = this._isOpen.asReadonly();\n readonly config = this._config.asReadonly();\n\n /**\n * Set the router instance. Must be called before using navigation features.\n */\n setRouter(router: Router): void {\n this._router = router;\n }\n\n private get router(): Router {\n if (!this._router) {\n throw new Error(\n 'GigamenuService: Router not set. Call setRouter() in your app initialization.'\n );\n }\n return this._router;\n }\n\n configure(config: Partial<GigamenuConfig>): void {\n this._config.update((current) => ({ ...current, ...config }));\n }\n\n open(): void {\n this._isOpen.set(true);\n }\n\n close(): void {\n this._isOpen.set(false);\n }\n\n toggle(): void {\n this._isOpen.update((v) => !v);\n }\n\n toggleDarkMode(): void {\n const darkModeClass = this._config().darkModeClass ?? 'dark';\n document.documentElement.classList.toggle(darkModeClass);\n }\n\n registerItem(item: GigamenuItem): void {\n this._items.update((items) => {\n const newItems = new Map(items);\n newItems.set(item.id, item);\n return newItems;\n });\n }\n\n unregisterItem(id: string): void {\n this._items.update((items) => {\n const newItems = new Map(items);\n newItems.delete(id);\n return newItems;\n });\n }\n\n /**\n * Register a dynamic item provider. The provider is invoked when the user\n * types in the menu (in action-selection mode) and its results are merged\n * into the displayed items alongside statically registered items.\n */\n registerProvider(\n id: string,\n provider: GigamenuProvider,\n options: GigamenuProviderOptions = {}\n ): void {\n const resolved: Required<GigamenuProviderOptions> = {\n ...DEFAULT_PROVIDER_OPTIONS,\n ...options,\n };\n this._providers.update((providers) => {\n const next = new Map(providers);\n next.set(id, { provider, options: resolved });\n return next;\n });\n }\n\n unregisterProvider(id: string): void {\n this._providers.update((providers) => {\n if (!providers.has(id)) return providers;\n const next = new Map(providers);\n next.delete(id);\n return next;\n });\n }\n\n registerCommand(command: GigamenuCommand): void {\n this.registerItem({\n ...command,\n category: 'command',\n });\n }\n\n registerPage(page: GigamenuPage): void {\n // Extract parameter names from path (e.g., /users/:id -> ['id'])\n const paramNames = this.extractParamNames(page.path);\n\n // Use manually specified params if provided, otherwise use extracted ones\n const finalParams = page.params ?? (paramNames.length > 0 ? paramNames : undefined);\n\n this.registerItem({\n ...page,\n category: 'page',\n params: finalParams,\n // Preserve paramProviders if specified\n paramProviders: page.paramProviders,\n action: (args?: string) => {\n let path = page.path;\n const paramsToReplace = finalParams ?? [];\n if (paramsToReplace.length > 0 && args) {\n // Split args by whitespace to get parameter values\n const argValues = args.trim().split(/\\s+/);\n // Replace each parameter with corresponding arg value\n paramsToReplace.forEach((param, index) => {\n if (argValues[index]) {\n path = path.replace(`:${param}`, argValues[index]);\n }\n });\n }\n this.router.navigate([path]);\n },\n });\n }\n\n private extractParamNames(path: string): string[] {\n const paramRegex = /:([^/]+)/g;\n const params: string[] = [];\n let match;\n while ((match = paramRegex.exec(path)) !== null) {\n params.push(match[1]);\n }\n return params;\n }\n\n discoverRoutes(options?: DiscoverRoutesOptions): void;\n discoverRoutes(routes?: Routes, options?: DiscoverRoutesOptions): void;\n discoverRoutes(\n routesOrOptions?: Routes | DiscoverRoutesOptions,\n maybeOptions?: DiscoverRoutesOptions\n ): void {\n let routes: Routes;\n let options: DiscoverRoutesOptions | undefined;\n\n if (Array.isArray(routesOrOptions)) {\n routes = routesOrOptions;\n options = maybeOptions;\n } else {\n routes = this.router.config;\n options = routesOrOptions;\n }\n\n this.extractPagesFromRoutes(routes, '', options?.filter);\n }\n\n private extractPagesFromRoutes(\n routes: Routes,\n parentPath: string,\n filter?: (route: RouteInfo) => boolean\n ): void {\n for (const route of routes) {\n if (route.redirectTo !== undefined) continue;\n\n const fullPath = parentPath\n ? `${parentPath}/${route.path ?? ''}`\n : route.path ?? '';\n\n if (route.path !== undefined && route.path !== '**') {\n const routeInfo: RouteInfo = {\n path: route.path,\n fullPath: `/${fullPath}`,\n data: route.data as Record<string, unknown> | undefined,\n title: typeof route.title === 'string' ? route.title : undefined,\n };\n\n // Apply filter if provided\n if (filter && !filter(routeInfo)) {\n // Still process children even if this route is filtered\n if (route.children) {\n this.extractPagesFromRoutes(route.children, fullPath, filter);\n }\n continue;\n }\n\n const label = routeInfo.title || this.pathToLabel(route.path || 'Home');\n const paramNames = this.extractParamNames(`/${fullPath}`);\n const hasParams = paramNames.length > 0;\n\n this.registerPage({\n id: `page:${fullPath || '/'}`,\n label, // Params will be rendered separately with colors\n path: `/${fullPath}`,\n description: hasParams\n ? `Navigate to ${label} (requires: ${paramNames.join(', ')})`\n : `Navigate to ${label}`,\n });\n }\n\n if (route.children) {\n this.extractPagesFromRoutes(route.children, fullPath, filter);\n }\n }\n }\n\n private pathToLabel(path: string): string {\n return path\n .split('/')\n .pop()!\n .replace(/[-_]/g, ' ')\n .replace(/\\b\\w/g, (c) => c.toUpperCase());\n }\n}\n","import { Directive, TemplateRef, inject } from '@angular/core';\nimport { GigamenuItem } from './types';\n\n/**\n * Context provided to the item template.\n */\nexport interface GigamenuItemContext {\n /** The menu item being rendered */\n $implicit: GigamenuItem;\n /** The index of the item in the filtered list */\n index: number;\n /** Whether this item is currently selected */\n selected: boolean;\n}\n\n/**\n * Context provided to the empty template.\n */\nexport interface GigamenuEmptyContext {\n /** The current search query */\n $implicit: string;\n}\n\n/**\n * Context provided to the header template.\n */\nexport interface GigamenuHeaderContext {\n /** The current query value */\n $implicit: string;\n /** The current query value */\n query: string;\n /** The locked action (if in parameter mode) */\n lockedAction: GigamenuItem | null;\n /** Array of filled parameter values */\n paramValues: string[];\n /** Name of the current parameter being edited */\n currentParamName: string | null;\n /** Placeholder text */\n placeholder: string;\n /** Callback to update the query */\n onQueryChange: (value: string) => void;\n /** Callback for keydown events */\n onKeydown: (event: KeyboardEvent) => void;\n /** Callback to unlock the action (go back to action selection) */\n onUnlockAction: () => void;\n /** Callback to go back to a specific parameter */\n onGoToParam: (index: number) => void;\n}\n\n/**\n * Context provided to the footer template.\n */\nexport interface GigamenuFooterContext {\n /** Number of filtered items */\n $implicit: number;\n /** Total number of items */\n total: number;\n}\n\n/**\n * Template directive for customizing menu item rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmItem let-item let-selected=\"selected\" let-index=\"index\">\n * <div [class.active]=\"selected\">\n * {{ item.label }}\n * </div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmItem]',\n standalone: true,\n})\nexport class GigamenuItemTemplate {\n readonly template = inject<TemplateRef<GigamenuItemContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing empty state rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmEmpty let-query>\n * <div>No results for \"{{ query }}\"</div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmEmpty]',\n standalone: true,\n})\nexport class GigamenuEmptyTemplate {\n readonly template = inject<TemplateRef<GigamenuEmptyContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing header/search input rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmHeader let-query let-onQueryChange=\"onQueryChange\" let-onKeydown=\"onKeydown\">\n * <input [value]=\"query\" (input)=\"onQueryChange($event.target.value)\" (keydown)=\"onKeydown($event)\" />\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmHeader]',\n standalone: true,\n})\nexport class GigamenuHeaderTemplate {\n readonly template = inject<TemplateRef<GigamenuHeaderContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing footer rendering.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmFooter let-count let-total=\"total\">\n * <div>Showing {{ count }} of {{ total }} items</div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\n@Directive({\n selector: '[gmFooter]',\n standalone: true,\n})\nexport class GigamenuFooterTemplate {\n readonly template = inject<TemplateRef<GigamenuFooterContext>>(TemplateRef);\n}\n\n/**\n * Template directive for customizing the entire panel/dialog container.\n * When provided, replaces the entire default panel structure.\n *\n * @example\n * ```html\n * <gm-gigamenu>\n * <ng-template gmPanel let-items let-query=\"query\" let-selectedIndex=\"selectedIndex\">\n * <div class=\"my-custom-panel\">\n * <!-- Custom implementation -->\n * </div>\n * </ng-template>\n * </gm-gigamenu>\n * ```\n */\nexport interface GigamenuPanelContext {\n /** Items to display (actions or autocomplete suggestions) */\n $implicit: GigamenuItem[];\n /** Items to display (actions or autocomplete suggestions) */\n items: GigamenuItem[];\n /** Current query value */\n query: string;\n /** The locked action (if in parameter mode) */\n lockedAction: GigamenuItem | null;\n /** Array of filled parameter values */\n paramValues: string[];\n /** Currently selected index */\n selectedIndex: number;\n /** Placeholder text from config */\n placeholder: string;\n /** Callback when item is clicked */\n onItemClick: (item: GigamenuItem, index: number) => void;\n /** Callback to update selection */\n onSelectIndex: (index: number) => void;\n /** Callback to update query */\n onQueryChange: (query: string) => void;\n /** Callback to close the menu */\n onClose: () => void;\n}\n\n@Directive({\n selector: '[gmPanel]',\n standalone: true,\n})\nexport class GigamenuPanelTemplate {\n readonly template = inject<TemplateRef<GigamenuPanelContext>>(TemplateRef);\n}\n","/**\n * Parsed query result containing search term and arguments.\n */\nexport interface ParsedQuery {\n /** The search term (may include quotes if label contains spaces) */\n searchTerm: string;\n /** The raw arguments string after the search term */\n args: string;\n /** Whether the query contains a separator after the search term */\n hasSeparator: boolean;\n}\n\n/**\n * Parsed arguments result containing both values and display strings.\n */\nexport interface ParsedArgs {\n /** Unquoted argument values */\n values: string[];\n /** Display strings (preserves quotes for visual alignment) */\n display: string[];\n}\n\n/**\n * Handles parsing of gigamenu query input.\n * Supports quoted strings for labels/values containing spaces.\n */\nexport class QueryParser {\n constructor(private readonly separator: string = ' ') {}\n\n /**\n * Parse a query string into search term and arguments.\n * Simple split on first separator - no quote handling.\n */\n parseQuery(query: string): ParsedQuery {\n const sepIndex = query.indexOf(this.separator);\n if (sepIndex === -1) {\n return { searchTerm: query, args: '', hasSeparator: false };\n }\n return {\n searchTerm: query.substring(0, sepIndex),\n args: query.substring(sepIndex + this.separator.length),\n hasSeparator: true,\n };\n }\n\n /**\n * Parse an arguments string into an array.\n * Simple space-based splitting - quotes are ignored.\n */\n parseArgs(args: string): ParsedArgs {\n if (!args) {\n return { values: [], display: [] };\n }\n\n // Simple split on spaces, filter out empty strings\n const parts = args.split(' ').filter(part => part.length > 0);\n return { values: parts, display: parts };\n }\n\n /**\n * Strip quotes from a string if it's quoted (legacy, kept for compatibility).\n */\n stripQuotes(str: string): string {\n if ((str.startsWith(\"'\") && str.endsWith(\"'\")) ||\n (str.startsWith('\"') && str.endsWith('\"'))) {\n return str.slice(1, -1);\n }\n return str;\n }\n\n /**\n * Return the string as-is (no escaping needed).\n */\n escapeIfNeeded(str: string): string {\n return str;\n }\n\n /**\n * Check if a search term matches a label (case-insensitive).\n */\n matchesLabel(searchTerm: string, label: string): boolean {\n const trimmed = searchTerm.trim().toLowerCase();\n return trimmed === label.toLowerCase();\n }\n\n /**\n * Build a query string from search term and args.\n */\n buildQuery(searchTerm: string, args: string[]): string {\n if (args.length === 0) {\n return searchTerm;\n }\n return searchTerm + this.separator + args.join(' ');\n }\n}\n","/**\n * Represents the different states of the gigamenu input.\n * New paradigm: input handles ONE thing at a time.\n */\nexport enum InputState {\n /** Menu is closed */\n Closed = 'closed',\n\n /** User is searching/selecting an action (page or command) */\n ActionSelection = 'actionSelection',\n\n /** User is inputting a parameter value */\n ParameterInput = 'parameterInput',\n}\n\n/**\n * Result of handling a keyboard event.\n */\nexport interface KeyboardHandlerResult {\n /** Whether the event was handled (should prevent default) */\n handled: boolean;\n\n /** Optional new state to transition to */\n newState?: InputState;\n}\n\n/**\n * Context provided to keyboard handlers.\n */\nexport interface KeyboardHandlerContext {\n /** The keyboard event */\n event: KeyboardEvent;\n\n /** Current query string */\n query: string;\n\n /** Parsed search term */\n searchTerm: string;\n\n /** Whether there's a separator in the query */\n hasSeparator: boolean;\n\n /** Currently selected menu item */\n selectedItem: { label: string; params?: string[]; paramProviders?: Record<string, unknown> } | null;\n\n /** Number of filtered items */\n itemCount: number;\n\n /** Current selected index in the menu */\n selectedIndex: number;\n\n /** Autocomplete suggestions */\n suggestions: { label: string; value: string }[];\n\n /** Currently selected suggestion index */\n suggestionIndex: number;\n\n /** Whether typeahead ghost text is available */\n hasTypeahead: boolean;\n\n /** Tab behavior config */\n tabBehavior: 'cycle' | 'accept-first';\n\n /** Separator character */\n separator: string;\n}\n\n/**\n * Actions that can be dispatched from keyboard handlers.\n */\nexport type KeyboardAction =\n | { type: 'navigate'; direction: 'up' | 'down' }\n | { type: 'navigateSuggestion'; direction: 'up' | 'down' }\n | { type: 'selectItem' }\n | { type: 'selectSuggestion' }\n | { type: 'completeItemLabel' }\n | { type: 'showAutocomplete' }\n | { type: 'hideAutocomplete' }\n | { type: 'close' }\n | { type: 'setQuery'; query: string };\n\n/**\n * Context for computing the current input state.\n */\nexport interface InputStateContext {\n isOpen: boolean;\n /** Whether an action has been locked/selected for parameter input */\n hasLockedAction: boolean;\n}\n\n/**\n * Compute the current input state based on menu status.\n */\nexport function computeInputState(ctx: InputStateContext): InputState {\n if (!ctx.isOpen) {\n return InputState.Closed;\n }\n\n if (ctx.hasLockedAction) {\n return InputState.ParameterInput;\n }\n\n return InputState.ActionSelection;\n}\n","/**\n * Scroll the selected menu item into view.\n */\nexport function scrollSelectedIntoView(\n container: HTMLElement | null,\n selectedIndex: number\n): void {\n if (!container) return;\n\n const selectedButton = container.querySelector(\n `[data-index=\"${selectedIndex}\"]`\n ) as HTMLElement | null;\n\n if (selectedButton) {\n selectedButton.scrollIntoView({ block: 'nearest' });\n }\n}\n\n/**\n * Scroll the selected autocomplete suggestion into view.\n */\nexport function scrollAutocompleteIntoView(\n container: HTMLElement | null,\n selectedIndex: number\n): void {\n if (!container) return;\n\n const selectedButton = container.querySelector(\n `[data-autocomplete-index=\"${selectedIndex}\"]`\n ) as HTMLElement | null;\n\n if (selectedButton) {\n selectedButton.scrollIntoView({ block: 'nearest' });\n }\n}\n","import { GigamenuItem } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Filter items based on search query.\n */\nexport function filterItems(\n items: GigamenuItem[],\n searchTerm: string,\n queryParser: QueryParser\n): GigamenuItem[] {\n const normalizedTerm = searchTerm.toLowerCase().trim();\n if (!normalizedTerm) {\n return items;\n }\n\n return items.filter((item) => matchesQuery(item, normalizedTerm, queryParser));\n}\n\n/**\n * Check if an item matches the search query.\n * Uses word-based matching across label, description, and keywords.\n */\nexport function matchesQuery(\n item: GigamenuItem,\n query: string,\n _queryParser: QueryParser\n): boolean {\n const searchableText = [\n item.label,\n item.description,\n ...(item.keywords ?? []),\n ]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n\n const words = query.split(/\\s+/);\n return words.every((word) => searchableText.includes(word));\n}\n\n/**\n * Sort items by frecency scores (frequency + recency).\n */\nexport function sortByFrecency(\n items: GigamenuItem[],\n scores: Map<string, number>\n): GigamenuItem[] {\n if (scores.size === 0) return items;\n\n return [...items].sort((a, b) => {\n const scoreA = scores.get(a.id) ?? 0;\n const scoreB = scores.get(b.id) ?? 0;\n return scoreB - scoreA;\n });\n}\n\n/**\n * Build searchable text from an item for matching.\n */\nexport function buildSearchableText(item: GigamenuItem): string {\n return [item.label, item.description, ...(item.keywords ?? [])]\n .filter(Boolean)\n .join(' ')\n .toLowerCase();\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\n\n/**\n * Compute the current parameter index being edited.\n * Returns null if no parameter is being edited.\n */\nexport function computeCurrentParamIndex(\n item: GigamenuItem | null,\n args: string,\n argsCount: number\n): number | null {\n if (!item || !item.params || item.params.length === 0) return null;\n\n const endsWithSpace = args.endsWith(' ');\n\n // If user is still typing a param (no trailing space) and has typed at least one arg\n if (!endsWithSpace && argsCount > 0 && argsCount <= item.params.length) {\n return argsCount - 1; // Currently editing the last typed arg\n }\n\n // If we have fewer args than params, we're about to type the next param\n if (argsCount < item.params.length) return argsCount;\n\n // All params complete (with trailing space confirming completion)\n return null;\n}\n\n/**\n * Get the name of the current parameter being edited.\n */\nexport function computeCurrentParamName(\n item: GigamenuItem | null,\n paramIndex: number | null\n): string | null {\n if (paramIndex === null || !item || !item.params) return null;\n return item.params[paramIndex] ?? null;\n}\n\n/**\n * Compute the current partial value of the parameter being edited.\n */\nexport function computeCurrentParamValue(\n args: string,\n argsArray: string[],\n paramIndex: number | null\n): string {\n const trimmedArgs = args.trim();\n if (!trimmedArgs) return '';\n if (paramIndex === null) return '';\n\n const endsWithSpace = args.endsWith(' ');\n\n // If we're on the last arg and still typing\n if (!endsWithSpace && argsArray.length === paramIndex + 1) {\n return argsArray[paramIndex] ?? '';\n }\n\n // If we're starting a new arg (after a space)\n if (endsWithSpace || argsArray.length === paramIndex) {\n return '';\n }\n\n return '';\n}\n\n/**\n * Check if the selected item can be executed (has all required params).\n */\nexport function computeCanExecute(\n item: GigamenuItem | null,\n argsCount: number\n): boolean {\n if (!item) return false;\n if (!item.params || item.params.length === 0) return true;\n return argsCount >= item.params.length;\n}\n\n/**\n * Get completed arguments for display (excludes the incomplete arg being typed).\n */\nexport function computeCompletedArgsDisplay(\n display: string[],\n args: string\n): string[] {\n const endsWithSpace = args.endsWith(' ');\n\n // If args ends with space, all args are complete\n if (endsWithSpace || !args) return display;\n\n // Otherwise, exclude the last incomplete arg (shown in currentParamValue)\n return display.slice(0, -1);\n}\n\n/**\n * Get actual values for args (substituting labels with values from selected options).\n */\nexport function computeArgsValues(\n argsArray: string[],\n selectedOptions: Map<number, AutocompleteOption>\n): string[] {\n return argsArray.map((arg, index) => {\n const option = selectedOptions.get(index);\n // If we have a selected option for this param and the current arg matches its label, use the value\n if (option && arg === option.label) {\n return option.value;\n }\n return arg;\n });\n}\n\n/**\n * Check if the selected item has autocomplete available for the current param.\n */\nexport function computeHasAutocomplete(\n item: GigamenuItem | null,\n paramName: string | null\n): boolean {\n if (!item || !paramName) return false;\n return !!(item.paramProviders?.[paramName]);\n}\n","import { GigamenuItem, PARAM_COLORS } from '../types';\nimport {\n GigamenuItemContext,\n GigamenuEmptyContext,\n GigamenuFooterContext,\n} from '../gigamenu-templates.directive';\n\n/**\n * Get color class for a parameter index.\n */\nexport function getParamColor(index: number): string {\n return PARAM_COLORS[index % PARAM_COLORS.length];\n}\n\n/**\n * Create context for item template.\n */\nexport function createItemContext(\n item: GigamenuItem,\n index: number,\n selectedIndex: number\n): GigamenuItemContext {\n return {\n $implicit: item,\n index,\n selected: selectedIndex === index,\n };\n}\n\n/**\n * Create context for empty state template.\n */\nexport function createEmptyContext(query: string): GigamenuEmptyContext {\n return {\n $implicit: query,\n };\n}\n\n/**\n * Create context for footer template.\n */\nexport function createFooterContext(\n filteredCount: number,\n totalCount: number\n): GigamenuFooterContext {\n return {\n $implicit: filteredCount,\n total: totalCount,\n };\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Initial state for menu reset.\n */\nexport interface MenuResetState {\n query: string;\n selectedIndex: number;\n showAutocomplete: boolean;\n autocompleteSelectedIndex: number;\n selectedParamOptions: Map<number, AutocompleteOption>;\n}\n\n/**\n * Get the initial/reset state for the menu.\n */\nexport function getInitialMenuState(): MenuResetState {\n return {\n query: '',\n selectedIndex: 0,\n showAutocomplete: false,\n autocompleteSelectedIndex: 0,\n selectedParamOptions: new Map(),\n };\n}\n\n/**\n * Check if an input element is currently focused.\n */\nexport function isInputFocused(): boolean {\n const activeElement = document.activeElement;\n if (!activeElement) return false;\n\n const tagName = activeElement.tagName.toLowerCase();\n return (\n tagName === 'input' ||\n tagName === 'textarea' ||\n (activeElement as HTMLElement).isContentEditable\n );\n}\n\n/**\n * Check if the current search term matches the selected item's label.\n */\nexport function isSearchTermMatchingItem(\n searchTerm: string,\n itemLabel: string,\n queryParser: QueryParser\n): boolean {\n return queryParser.matchesLabel(searchTerm, itemLabel);\n}\n\n/**\n * Complete the selected item's label in the search input.\n * Returns the new query string.\n */\nexport function completeItemLabel(\n item: GigamenuItem,\n separator: string,\n queryParser: QueryParser\n): string {\n const escapedLabel = queryParser.escapeIfNeeded(item.label);\n const hasParams = item.params && item.params.length > 0;\n return hasParams ? escapedLabel + separator : escapedLabel;\n}\n","import { AutocompleteOption, ParamProvider } from '../types';\nimport { QueryParser } from '../query-parser';\n\n/**\n * Result from fetching autocomplete suggestions.\n */\nexport interface FetchResult {\n options: AutocompleteOption[];\n isAsync: boolean;\n}\n\n/**\n * Fetch autocomplete suggestions from a provider.\n */\nexport async function fetchAutocompleteSuggestions(\n provider: ParamProvider,\n query: string,\n cache: Map<string, AutocompleteOption[]>\n): Promise<FetchResult> {\n // Handle static array provider\n if (Array.isArray(provider)) {\n const cacheKey = `${JSON.stringify(provider)}-${query}`;\n if (cache.has(cacheKey)) {\n return { options: cache.get(cacheKey)!, isAsync: false };\n }\n cache.set(cacheKey, provider);\n return { options: provider, isAsync: false };\n }\n\n // Handle async function provider (server-side filtering)\n const result = await Promise.resolve(provider(query));\n return { options: result, isAsync: true };\n}\n\n/**\n * Filter suggestions client-side based on query.\n */\nexport function filterSuggestionsClientSide(\n options: AutocompleteOption[],\n query: string\n): AutocompleteOption[] {\n const lowerQuery = query.toLowerCase().trim();\n if (!lowerQuery) return options;\n return options.filter((opt) => opt.label.toLowerCase().includes(lowerQuery));\n}\n\n/**\n * Compute typeahead ghost text suggestion.\n * Returns the portion of the label that extends beyond the typed text.\n */\nexport function computeTypeaheadSuggestion(\n suggestions: AutocompleteOption[],\n selectedIndex: number,\n paramValue: string\n): string | null {\n if (suggestions.length === 0) return null;\n\n const suggestion = suggestions[selectedIndex] ?? suggestions[0];\n if (!suggestion) return null;\n\n // Return portion of label that extends beyond typed text (case-insensitive prefix match)\n const suggestionLabel = suggestion.label;\n if (suggestionLabel.toLowerCase().startsWith(paramValue.toLowerCase())) {\n return suggestionLabel.slice(paramValue.length);\n }\n return null;\n}\n\n/**\n * Context for building a query with a selected autocomplete option.\n */\nexport interface SelectionContext {\n searchTerm: string;\n separator: string;\n argsArray: string[];\n paramIndex: number | null;\n queryParser: QueryParser;\n}\n\n/**\n * Build the new query string after selecting an autocomplete option.\n */\nexport function buildQueryWithSelection(\n ctx: SelectionContext,\n option: AutocompleteOption,\n addTrailingSpace: boolean\n): string {\n if (ctx.paramIndex === null) return ctx.searchTerm;\n\n // Quote labels that contain spaces\n const escapedLabel = ctx.queryParser.escapeIfNeeded(option.label);\n\n // Replace current param with the selected option's label\n const newArgs = [...ctx.argsArray];\n newArgs[ctx.paramIndex] = escapedLabel;\n\n // Build new query with or without trailing space\n const baseQuery = ctx.searchTerm + ctx.separator + newArgs.join(' ');\n return addTrailingSpace ? baseQuery + ' ' : baseQuery;\n}\n\n/**\n * Result from selecting an autocomplete suggestion.\n */\nexport interface SelectionResult {\n newQuery: string;\n selectedOption: AutocompleteOption;\n paramIndex: number;\n}\n\n/**\n * Process autocomplete suggestion selection.\n * Returns the new query and the selected option for tracking.\n */\nexport function processAutocompleteSuggestionSelection(\n suggestions: AutocompleteOption[],\n selectedIdx: number,\n ctx: SelectionContext,\n addTrailingSpace: boolean\n): SelectionResult | null {\n const option = suggestions[selectedIdx];\n if (!option || ctx.paramIndex === null) return null;\n\n const newQuery = buildQueryWithSelection(ctx, option, addTrailingSpace);\n\n return {\n newQuery,\n selectedOption: option,\n paramIndex: ctx.paramIndex,\n };\n}\n\n/**\n * Result from selecting and cycling to next suggestion.\n */\nexport interface CycleResult extends SelectionResult {\n nextIndex: number;\n}\n\n/**\n * Process autocomplete suggestion selection with cycling to next.\n * zsh-style: select current and prepare for next Tab press.\n */\nexport function processAutocompleteSuggestionAndCycle(\n suggestions: AutocompleteOption[],\n currentIdx: number,\n ctx: SelectionContext\n): CycleResult | null {\n if (suggestions.length === 0) return null;\n\n const option = suggestions[currentIdx];\n if (!option || ctx.paramIndex === null) return null;\n\n // Don't add trailing space - keep cursor position for cycling\n const newQuery = buildQueryWithSelection(ctx, option, false);\n\n // Cycle to next suggestion\n const nextIdx = (currentIdx + 1) % suggestions.length;\n\n return {\n newQuery,\n selectedOption: option,\n paramIndex: ctx.paramIndex,\n nextIndex: nextIdx,\n };\n}\n","import { GigamenuItem, AutocompleteOption } from '../types';\n\n/**\n * Actions that can be dispatched from keyboard handlers.\n */\nexport type MenuAction =\n | { type: 'setSelectedIndex'; value: number }\n | { type: 'setQuery'; value: string }\n | { type: 'executeAction'; item: GigamenuItem }\n | { type: 'executeLockedAction' }\n | { type: 'close' }\n | { type: 'toggle' }\n | { type: 'open' }\n | { type: 'scrollIntoView' }\n | { type: 'lockAction'; item: GigamenuItem }\n | { type: 'unlockAction' }\n | { type: 'nextParameter' }\n | { type: 'previousParameter' }\n | { type: 'selectSuggestion'; option: AutocompleteOption };\n\n/**\n * Context for global keyboard handling.\n */\nexport interface GlobalKeydownContext {\n isOpen: boolean;\n isInputFocused: boolean;\n}\n\n/**\n * Handle global keydown events (Ctrl+K, /, Escape).\n * Returns action if handled, null otherwise.\n */\nexport function handleGlobalKeydown(\n event: KeyboardEvent,\n ctx: GlobalKeydownContext\n): MenuAction | null {\n // Ctrl/Cmd + K: Toggle menu\n if ((event.metaKey || event.ctrlKey) && event.key === 'k') {\n return { type: 'toggle' };\n }\n\n // /: Open menu (only when no input is focused)\n if (event.key === '/' && !ctx.isInputFocused) {\n return { type: 'open' };\n }\n\n // Escape: Close menu (only when input is NOT focused - let input handler deal with it)\n if (event.key === 'Escape' && ctx.isOpen && !ctx.isInputFocused) {\n return { type: 'close' };\n }\n\n return null;\n}\n\n/**\n * Context for action selection state.\n */\nexport interface ActionSelectionContext {\n items: GigamenuItem[];\n selectedIndex: number;\n selectedItem: GigamenuItem | null;\n}\n\n/**\n * Handle keyboard events in ActionSelection state.\n */\nexport function handleActionSelectionKeydown(\n event: KeyboardEvent,\n ctx: ActionSelectionContext\n): MenuAction[] {\n const actions: MenuAction[] = [];\n const item = ctx.selectedItem;\n\n switch (event.key) {\n case 'ArrowDown':\n actions.push({\n type: 'setSelectedIndex',\n value: Math.min(ctx.selectedIndex + 1, ctx.items.length - 1),\n });\n actions.push({ type: 'scrollIntoView' });\n break;\n\n case 'ArrowUp':\n actions.push({\n type: 'setSelectedIndex',\n value: Math.max(ctx.selectedIndex - 1, 0),\n });\n actions.push({ type: 'scrollIntoView' });\n break;\n\n case 'Tab':\n if (item) {\n // Tab: always tries to go to params first, or execute if no params\n if (item.params && item.params.length > 0) {\n actions.push({ type: 'lockAction', item });\n } else {\n actions.push({ type: 'executeAction', item });\n }\n }\n break;\n\n case 'Enter':\n if (item) {\n const hasRequiredParams = item.params && item.params.length > 0 && !hasOnlyOptionalParams(item);\n if (hasRequiredParams) {\n // Has required params - go to parameter input\n actions.push({ type: 'lockAction', item });\n } else {\n // No params or only optional - execute immediately\n actions.push({ type: 'executeAction', item });\n }\n }\n break;\n\n case 'Escape':\n actions.push({ type: 'close' });\n break;\n }\n\n return actions;\n}\n\n/**\n * Context for parameter input state.\n */\nexport interface ParameterInputContext {\n lockedItem: GigamenuItem;\n currentParamIndex: number;\n paramValues: string[];\n query: string;\n suggestions: AutocompleteOption[];\n selectedSuggestionIndex: number;\n}\n\n/**\n * Handle keyboard events in ParameterInput state.\n */\nexport function handleParameterInputKeydown(\n event: KeyboardEvent,\n ctx: ParameterInputContext\n): MenuAction[] {\n const actions: MenuAction[] = [];\n const item = ctx.lockedItem;\n const params = item.params ?? [];\n const currentParam = params[ctx.currentParamIndex];\n const isLastParam = ctx.currentParamIndex >= params.length - 1;\n const hasSuggestions = ctx.suggestions.length > 0;\n\n switch (event.key) {\n case 'ArrowDown':\n if (hasSuggestions) {\n actions.push({\n type: 'setSelectedIndex',\n value: Math.min(ctx.selectedSuggestionIndex + 1, ctx.suggestions.length - 1),\n });\n actions.push({ type: 'scrollIntoView' });\n }\n break;\n\n case 'ArrowUp':\n if (hasSuggestions) {\n actions.push({\n type: 'setSelectedIndex',\n value: Math.max(ctx.selectedSuggestionIndex - 1, 0),\n });\n actions.push({ type: 'scrollIntoView' });\n }\n break;\n\n case 'Tab':\n // Tab: select suggestion (if any), then go to next param or execute\n if (hasSuggestions) {\n actions.push({ type: 'selectSuggestion', option: ctx.suggestions[ctx.selectedSuggestionIndex] });\n }\n if (isLastParam) {\n // Execute - args will be built at dispatch time from current state\n actions.push({ type: 'executeLockedAction' });\n } else {\n actions.push({ type: 'nextParameter' });\n }\n break;\n\n case 'Enter':\n // Enter: select suggestion if any\n if (hasSuggestions && ctx.selectedSuggestionIndex >= 0) {\n actions.push({ type: 'selectSuggestion', option: ctx.suggestions[ctx.selectedSuggestionIndex] });\n }\n\n if (isLastParam) {\n // Execute - args will be built at dispatch time from current state\n actions.push({ type: 'executeLockedAction' });\n } else {\n // More params - go to next (Enter acts like Tab when more required params)\n actions.push({ type: 'nextParameter' });\n }\n break;\n\n case 'Escape':\n // Escape: go back one step (like Backspace on empty)\n if (ctx.currentParamIndex > 0) {\n // Go to previous parameter\n actions.push({ type: 'previousParameter' });\n } else {\n // At first param, go back to action selection\n actions.push({ type: 'unlockAction' });\n }\n break;\n\n case 'Backspace':\n // Backspace when query is empty: go back\n if (ctx.query === '') {\n if (ctx.currentParamIndex > 0) {\n // Go to previous parameter\n actions.push({ type: 'previousParameter' });\n } else {\n // At first param, go back to action selection\n actions.push({ type: 'unlockAction' });\n }\n }\n break;\n }\n\n return actions;\n}\n\n/**\n * Check if item has only optional parameters (none required).\n * For now, we treat all params as required. Can be extended later.\n */\nfunction hasOnlyOptionalParams(_item: GigamenuItem): boolean {\n // TODO: Add optional param support to GigamenuItem type\n return false;\n}\n\n/**\n * Handle zsh-like keyboard shortcuts (Ctrl+W, Ctrl+U).\n * Returns the new query if handled, null otherwise.\n */\nexport function handleZshShortcuts(\n event: KeyboardEvent,\n query: string\n): string | null {\n // Ctrl+W or Alt+Backspace or Ctrl+Backspace: Delete last word\n if (\n (event.ctrlKey && event.key === 'w') ||\n (event.altKey && event.key === 'Backspace') ||\n (event.ctrlKey && event.key === 'Backspace')\n ) {\n return deleteLastWord(query);\n }\n\n // Ctrl+U: Clear line\n if (event.ctrlKey && event.key === 'u') {\n return '';\n }\n\n return null;\n}\n\n/**\n * Delete the last word from the query.\n */\nexport function deleteLastWord(query: string): string {\n if (!query) return '';\n\n let newQuery = query.replace(/\\s+$/, '');\n const lastSpaceIndex = newQuery.lastIndexOf(' ');\n if (lastSpaceIndex !== -1) {\n newQuery = newQuery.substring(0, lastSpaceIndex);\n } else {\n newQuery = '';\n }\n\n return newQuery;\n}\n\n/**\n * Check if any actions were generated.\n */\nexport function hasActions(actions: MenuAction[]): boolean {\n return actions.length > 0;\n}\n","// Scroll utilities\nexport { scrollSelectedIntoView, scrollAutocompleteIntoView } from './scroll-utils';\n\n// Search functions\nexport { filterItems, matchesQuery, sortByFrecency, buildSearchableText } from './search';\n\n// Parameter state functions\nexport {\n computeCurrentParamIndex,\n computeCurrentParamName,\n computeCurrentParamValue,\n computeCanExecute,\n computeCompletedArgsDisplay,\n computeArgsValues,\n computeHasAutocomplete,\n} from './parameter-state';\n\n// Template context functions\nexport {\n getParamColor,\n createItemContext,\n createEmptyContext,\n createFooterContext,\n} from './template-contexts';\n\n// Menu lifecycle functions\nexport {\n getInitialMenuState,\n isInputFocused,\n isSearchTermMatchingItem,\n completeItemLabel,\n} from './menu-lifecycle';\nexport type { MenuResetState } from './menu-lifecycle';\n\n// Autocomplete functions\nexport {\n fetchAutocompleteSuggestions,\n filterSuggestionsClientSide,\n computeTypeaheadSuggestion,\n buildQueryWithSelection,\n processAutocompleteSuggestionSelection,\n processAutocompleteSuggestionAndCycle,\n} from './autocomplete';\nexport type { FetchResult, SelectionContext, SelectionResult, CycleResult } from './autocomplete';\n\n// Keyboard handler functions\nexport {\n handleGlobalKeydown,\n handleZshShortcuts,\n deleteLastWord,\n handleActionSelectionKeydown,\n handleParameterInputKeydown,\n hasActions,\n} from './keyboard-handlers';\nexport type {\n MenuAction,\n GlobalKeydownContext,\n ActionSelectionContext,\n ParameterInputContext,\n} from './keyboard-handlers';\n","import { Injectable, PLATFORM_ID, Inject } from '@angular/core';\nimport { isPlatformBrowser } from '@angular/common';\n\ninterface FrecencyEntry {\n itemId: string;\n count: number;\n lastUsed: number;\n}\n\ninterface FrecencyData {\n [searchTerm: string]: FrecencyEntry[];\n}\n\nconst STORAGE_KEY = 'gigamenu_frecency';\nconst GLOBAL_KEY = '__global__';\nconst MAX_ENTRIES_PER_TERM = 10;\nconst MAX_TERMS = 100;\nconst DECAY_FACTOR = 0.9;\n\n@Injectable({ providedIn: 'root' })\nexport class FrecencyService {\n private data: FrecencyData = {};\n private readonly isBrowser: boolean;\n\n constructor(@Inject(PLATFORM_ID) platformId: object) {\n this.isBrowser = isPlatformBrowser(platformId);\n this.load();\n }\n\n /**\n * Record that an item was selected for a given search term.\n */\n recordSelection(searchTerm: string, itemId: string): void {\n // Always record to global for overall frecency\n this.recordToKey(GLOBAL_KEY, itemId);\n\n // Also record to specific search term if provided\n const normalizedTerm = this.normalizeTerm(searchTerm);\n if (normalizedTerm) {\n this.recordToKey(normalizedTerm, itemId);\n }\n\n this.pruneAndSave();\n }\n\n private recordToKey(key: string, itemId: string): void {\n if (!this.data[key]) {\n this.data[key] = [];\n }\n\n const entries = this.data[key];\n const existing = entries.find((e) => e.itemId === itemId);\n\n if (existing) {\n existing.count++;\n existing.lastUsed = Date.now();\n } else {\n entries.push({\n itemId,\n count: 1,\n lastUsed: Date.now(),\n });\n }\n\n // Keep only top entries\n this.data[key] = entries\n .sort((a, b) => this.calculateScore(b) - this.calculateScore(a))\n .slice(0, MAX_ENTRIES_PER_TERM);\n }\n\n /**\n * Get frecency scores for items matching a search term.\n * Returns a map of itemId -> score (higher is better).\n */\n getScores(searchTerm: string): Map<string, number> {\n const scores = new Map<string, number>();\n const normalizedTerm = this.normalizeTerm(searchTerm);\n\n // If no search term, return global scores\n if (!normalizedTerm) {\n const globalEntries = this.data[GLOBAL_KEY];\n if (globalEntries) {\n for (const entry of globalEntries) {\n scores.set(entry.itemId, this.calculateScore(entry));\n }\n }\n return scores;\n }\n\n // Exact match for search term\n const exactEntries = this.data[normalizedTerm];\n if (exactEntries) {\n for (const entry of exactEntries) {\n const score = this.calculateScore(entry);\n scores.set(entry.itemId, score);\n }\n }\n\n // Prefix matches (for partial typing)\n for (const [term, entries] of Object.entries(this.data)) {\n if (term !== GLOBAL_KEY && term !== normalizedTerm && term.startsWith(normalizedTerm)) {\n for (const entry of entries) {\n const currentScore = scores.get(entry.itemId) ?? 0;\n // Prefix matches get reduced weight\n const prefixScore = this.calculateScore(entry) * 0.5;\n scores.set(entry.itemId, Math.max(currentScore, prefixScore));\n }\n }\n }\n\n return scores;\n }\n\n /**\n * Get the most likely item for a search term (for auto-selection).\n * Returns itemId if there's a strong match, null otherwise.\n */\n getTopMatch(searchTerm: string): string | null {\n const normalizedTerm = this.normalizeTerm(searchTerm);\n if (!normalizedTerm) return null;\n\n const entries = this.data[normalizedTerm];\n if (!entries || entries.length === 0) return null;\n\n const topEntry = entries[0];\n const score = this.calculateScore(topEntry);\n\n // Only auto-select if strong confidence (used multiple times recently)\n if (topEntry.count >= 2 && score > 5) {\n return topEntry.itemId;\n }\n\n return null;\n }\n\n private calculateScore(entry: FrecencyEntry): number {\n const ageInHours = (Date.now() - entry.lastUsed) / (60 * 60 * 24);\n const recencyScore = Math.pow(DECAY_FACTOR, ageInHours);\n return entry.count * recencyScore;\n }\n\n private normalizeTerm(term: string): string {\n return term.toLowerCase().trim();\n }\n\n private load(): void {\n if (!this.isBrowser) return;\n\n try {\n const stored = localStorage.getItem(STORAGE_KEY);\n if (stored) {\n this.data = JSON.parse(stored);\n }\n } catch {\n this.data = {};\n }\n }\n\n private pruneAndSave(): void {\n if (!this.isBrowser) return;\n\n // Prune old terms if we have too many\n const terms = Object.keys(this.data);\n if (terms.length > MAX_TERMS) {\n const termScores = terms.map((term) => ({\n term,\n maxScore: Math.max(...this.data[term].map((e) => this.calculateScore(e))),\n }));\n termScores.sort((a, b) => b.maxScore - a.maxScore);\n\n const keepTerms = new Set(termScores.slice(0, MAX_TERMS).map((t) => t.term));\n for (const term of terms) {\n if (!keepTerms.has(term)) {\n delete this.data[term];\n }\n }\n }\n\n try {\n localStorage.setItem(STORAGE_KEY, JSON.stringify(this.data));\n } catch {\n // Storage full or unavailable\n }\n }\n}\n","import {\n Component,\n signal,\n computed,\n effect,\n untracked,\n ElementRef,\n viewChild,\n contentChild,\n HostListener,\n PLATFORM_ID,\n Inject,\n} from '@angular/core';\nimport { isPlatformBrowser, NgTemplateOutlet } from '@angular/common';\nimport { GigamenuService } from './gigamenu.service';\nimport { FrecencyService } from './frecency.service';\nimport { GigamenuItem, AutocompleteOption, GigamenuProviderItem } from './types';\nimport {\n GigamenuItemTemplate,\n GigamenuEmptyTemplate,\n GigamenuHeaderTemplate,\n GigamenuFooterTemplate,\n GigamenuPanelTemplate,\n} from './gigamenu-templates.directive';\nimport { QueryParser } from './query-parser';\nimport { InputState, computeInputState } from './input-state';\nimport {\n // Scroll utilities\n scrollSelectedIntoView,\n // Search functions\n filterItems,\n sortByFrecency,\n // Parameter state functions\n computeHasAutocomplete,\n // Template context functions\n getParamColor,\n createItemContext,\n createEmptyContext,\n createFooterContext,\n // Menu lifecycle functions\n isInputFocused,\n // Autocomplete functions\n fetchAutocompleteSuggestions,\n filterSuggestionsClientSide,\n // Keyboard handler functions\n handleGlobalKeydown,\n handleZshShortcuts,\n handleActionSelectionKeydown,\n handleParameterInputKeydown,\n hasActions,\n // Types\n type MenuAction,\n type ActionSelectionContext,\n type ParameterInputContext,\n} from './core';\n\n@Component({\n selector: 'gm-gigamenu',\n standalone: true,\n imports: [NgTemplateOutlet],\n templateUrl: 'gigamenu.component.html',\n styles: `\n :host {\n display: contents;\n }\n `,\n})\nexport class GigamenuComponent {\n private readonly searchInput = viewChild<ElementRef<HTMLInputElement>>('searchInput');\n private readonly listContainer = viewChild<ElementRef<HTMLDivElement>>('listContainer');\n private readonly isBrowser: boolean;\n\n // Template queries\n protected readonly itemTemplate = contentChild(GigamenuItemTemplate);\n protected readonly emptyTemplate = contentChild(GigamenuEmptyTemplate);\n protected readonly headerTemplate = contentChild(GigamenuHeaderTemplate);\n protected readonly footerTemplate = contentChild(GigamenuFooterTemplate);\n protected readonly panelTemplate = contentChild(GigamenuPanelTemplate);\n\n // Core state signals\n protected readonly query = signal('');\n protected readonly selectedIndex = signal(0);\n\n // Step-by-step input state\n protected readonly lockedAction = signal<GigamenuItem | null>(null);\n protected readonly paramValues = signal<string[]>([]);\n\n // Autocomplete state signals\n protected readonly autocompleteSuggestions = signal<AutocompleteOption[]>([]);\n private autocompleteCache = new Map<string, AutocompleteOption[]>();\n private readonly selectedParamOptions = signal<Map<number, AutocompleteOption>>(new Map());\n\n // Dynamic provider state\n private readonly providerResults = signal<Map<string, GigamenuItem[]>>(new Map());\n private providerTimers = new Map<string, ReturnType<typeof setTimeout>>();\n private providerInvocation = 0;\n\n // Query parsing (simplified - only used for filtering)\n private readonly queryParser = computed(() => {\n const separator = this.service.config().argSeparator ?? ' ';\n return new QueryParser(separator);\n });\n\n // Selected item from display list\n protected readonly selectedItem = computed(() => {\n const items = this.displayItems();\n const index = this.selectedIndex();\n return items[index] ?? null;\n });\n\n protected readonly currentParamIndex = computed(() => {\n const action = this.lockedAction();\n if (!action || !action.params) return null;\n const filled = this.paramValues().length;\n if (filled >= action.params.length) return null;\n return filled;\n });\n\n protected readonly currentParamName = computed(() => {\n const action = this.lockedAction();\n const idx = this.currentParamIndex();\n if (!action || idx === null || !action.params) return null;\n return action.params[idx] ?? null;\n });\n\n protected readonly hasAutocomplete = computed(() => {\n const action = this.lockedAction();\n const paramName = this.currentParamName();\n if (!action || !paramName) return false;\n return computeHasAutocomplete(action, paramName);\n });\n\n protected readonly currentState = computed((): InputState => {\n return computeInputState({\n isOpen: this.service.isOpen(),\n hasLockedAction: this.lockedAction() !== null,\n });\n });\n\n protected readonly filteredItems = computed(() => {\n const searchTerm = this.query().toLowerCase().trim();\n const items = this.service.items();\n const maxResults = this.service.config().maxResults ?? 10;\n\n if (!searchTerm) {\n const scores = this.frecency.getScores('');\n return sortByFrecency(items, scores).slice(0, maxResults);\n }\n\n const matched = filterItems(items, searchTerm, this.queryParser());\n const scores = this.frecency.getScores(searchTerm);\n return sortByFrecency(matched, scores).slice(0, maxResults);\n });\n\n // Display items: actions in ActionSelection, suggestions in ParameterInput\n protected readonly displayItems = computed((): GigamenuItem[] => {\n const state = this.currentState();\n if (state === InputState.ParameterInput) {\n // In parameter mode, show autocomplete suggestions as items\n return this.autocompleteSuggestions().map((opt) => ({\n id: `suggestion-${opt.value}`,\n label: opt.label,\n description: opt.value !== opt.label ? opt.value : undefined,\n category: 'command' as const,\n action: () => {}, // Handled via selectSuggestion action\n }));\n }\n\n // Action selection: static items + dynamic provider results\n const staticItems = this.filteredItems();\n const dynamic: GigamenuItem[] = [];\n for (const items of this.providerResults().values()) {\n dynamic.push(...items);\n }\n return [...staticItems, ...dynamic];\n });\n\n // Template helper\n protected getParamColor = getParamColor;\n\n constructor(\n protected readonly service: GigamenuService,\n private readonly frecency: FrecencyService,\n @Inject(PLATFORM_ID) platformId: object\n ) {\n this.isBrowser = isPlatformBrowser(platformId);\n\n // Focus effect\n effect(() => {\n if (this.service.isOpen() && this.isBrowser) {\n setTimeout(() => this.searchInput()?.nativeElement.focus(), 0);\n }\n });\n\n // Scroll lock: prevent page scrolling while the menu is open\n effect(() => {\n if (!this.isBrowser) return;\n const open = this.service.isOpen();\n const body = document.body;\n if (open) {\n const previous = body.style.overflow;\n body.dataset['gigamenuPrevOverflow'] = previous;\n body.style.overflow = 'hidden';\n } else if ('gigamenuPrevOverflow' in body.dataset) {\n body.style.overflow = body.dataset['gigamenuPrevOverflow'] ?? '';\n delete body.dataset['gigamenuPrevOverflow'];\n }\n });\n\n // Frecency auto-select effect (only in ActionSelection mode)\n effect(() => {\n const state = this.currentState();\n if (state !== InputState.ActionSelection) return;\n\n const items = this.filteredItems();\n const query = this.query();\n\n if (query && items.length > 0) {\n const topMatch = this.frecency.getTopMatch(query);\n if (topMatch) {\n const idx = items.findIndex((item) => item.id === topMatch);\n if (idx !== -1) {\n this.selectedIndex.set(idx);\n return;\n }\n }\n }\n this.selectedIndex.set(0);\n });\n\n // Dynamic provider effect (only in ActionSelection mode).\n // IMPORTANT: this effect must not read providerResults — it writes it, and\n // doing both would create a write-triggers-itself feedback loop that\n // re-fires every registered provider on every write.\n effect(() => {\n const state = this.currentState();\n const providers = this.service.providers();\n const query = this.query().trim();\n\n // Cancel anything currently pending / in-flight.\n for (const t of this.providerTimers.values()) clearTimeout(t);\n this.providerTimers.clear();\n const invocation = ++this.providerInvocation;\n\n if (state !== InputState.ActionSelection) {\n untracked(() => {\n if (this.providerResults().size > 0) this.providerResults.set(new Map());\n });\n return;\n }\n\n // Drop stored results that no longer apply (provider removed or query below threshold).\n untracked(() => {\n const current = this.providerResults();\n if (current.size === 0) return;\n const next = new Map(current);\n let changed = false;\n for (const id of [...next.keys()]) {\n const reg = providers.get(id);\n if (!reg || query.length < reg.options.minQueryLength) {\n next.delete(id);\n changed = true;\n }\n }\n if (changed) this.providerResults.set(next);\n });\n\n providers.forEach((registered, id) => {\n if (query.length < registered.options.minQueryLength) return;\n\n const timer = setTimeout(async () => {\n this.providerTimers.delete(id);\n try {\n const raw = await registered.provider(query);\n if (invocation !== this.providerInvocation) return;\n const items = this.normalizeProviderItems(raw, id, registered.options.group);\n untracked(() => {\n this.providerResults.update((map) => {\n const next = new Map(map);\n next.set(id, items);\n return next;\n });\n });\n } catch (err) {\n console.error(`gigamenu provider \"${id}\" failed:`, err);\n }\n }, registered.options.debounceMs);\n\n this.providerTimers.set(id, timer);\n });\n });\n\n // Autocomplete effect (only in ParameterInput mode)\n effect(() => {\n const action = this.lockedAction();\n const paramIndex = this.currentParamIndex();\n const paramName = this.currentParamName();\n const paramValue = this.query(); // In ParameterInput, query is the param value\n\n if (!action || paramIndex === null || !paramName) {\n this.autocompleteSuggestions.set([]);\n return;\n }\n\n const provider = action.paramProviders?.[paramName];\n if (!provider) {\n this.autocompleteSuggestions.set([]);\n return;\n }\n\n this.fetchSuggestions(provider, paramValue);\n });\n }\n\n @HostListener('document:keydown', ['$event'])\n onGlobalKeydown(event: KeyboardEvent): void {\n if (!this.isBrowser) return;\n\n const action = handleGlobalKeydown(event, {\n isOpen: this.service.isOpen(),\n isInputFocused: isInputFocused(),\n });\n\n if (action) {\n event.preventDefault();\n this.dispatchAction(action);\n }\n }\n\n protected onInputKeydown(event: KeyboardEvent): void {\n const state = this.currentState();\n\n // Handle zsh-like shortcuts first\n const newQuery = handleZshShortcuts(event, this.query());\n if (newQuery !== null) {\n event.preventDefault();\n this.query.set(newQuery);\n return;\n }\n\n // Get actions from state-specific handler\n const actions = this.getActionsForState(state, event);\n\n if (hasActions(actions)) {\n event.preventDefault();\n actions.forEach((action) => this.dispatchAction(action));\n }\n }\n\n private getActionsForState(state: InputState, event: KeyboardEvent): MenuAction[] {\n switch (state) {\n case InputState.ActionSelection: {\n const ctx: ActionSelectionContext = {\n items: this.displayItems(),\n selectedIndex: this.selectedIndex(),\n selectedItem: this.selectedItem(),\n };\n return handleActionSelectionKeydown(event, ctx);\n }\n case InputState.ParameterInput: {\n const action = this.lockedAction();\n if (!action) return [];\n const ctx: ParameterInputContext = {\n lockedItem: action,\n currentParamIndex: this.currentParamIndex() ?? 0,\n paramValues: this.paramValues(),\n query: this.query(),\n suggestions: this.autocompleteSuggestions(),\n selectedSuggestionIndex: this.selectedIndex(),\n };\n return handleParameterInputKeydown(event, ctx);\n }\n default:\n return [];\n }\n }\n\n private dispatchAction(action: MenuAction): void {\n switch (action.type) {\n case 'setSelectedIndex':\n this.selectedIndex.set(action.value);\n break;\n case 'setQuery':\n this.query.set(action.value);\n break;\n case 'executeAction':\n // Execute an action directly (no params)\n this.executeItemWithArgs(action.item, []);\n break;\n case 'executeLockedAction':\n // Build args from current state (includes any changes from selectSuggestion)\n const lockedItem = this.lockedAction();\n if (lockedItem) {\n const args = this.buildArgsWithValues();\n this.executeItemWithArgs(lockedItem, args);\n }\n break;\n case 'close':\n this.close();\n break;\n case 'toggle':\n this.service.toggle();\n break;\n case 'open':\n this.service.open();\n break;\n case 'scrollIntoView':\n scrollSelectedIntoView(this.listContainer()?.nativeElement ?? null, this.selectedIndex());\n break;\n case 'lockAction':\n this.lockedAction.set(action.item);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'unlockAction':\n this.lockedAction.set(null);\n this.paramValues.set([]);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'nextParameter':\n // Push current query value to paramValues, clear query\n this.paramValues.update((values) => [...values, this.query()]);\n this.query.set('');\n this.selectedIndex.set(0);\n break;\n case 'previousParameter':\n // Pop last param value back to query\n const values = this.paramValues();\n if (values.length > 0) {\n const lastValue = values[values.length - 1];\n this.paramValues.update((v) => v.slice(0, -1));\n this.query.set(lastValue);\n this.selectedIndex.set(0);\n }\n break;\n case 'selectSuggestion':\n this.selectSuggestion(action.option);\n break;\n }\n }\n\n protected onQueryChange(event: Event): void {\n const value = (event.target as HTMLInputElement).value;\n this.query.set(value);\n }\n\n protected onBackdropClick(event: MouseEvent): void {\n if (event.target === event.currentTarget) {\n this.close();\n }\n }\n\n protected onItemClick(item: GigamenuItem, index: number): void {\n // Only proceed if this is the selected item\n if (this.selectedIndex() !== index) {\n this.selectedIndex.set(index);\n return;\n }\n\n const state = this.currentState();\n if (state === InputState.ParameterInput) {\n // In parameter mode, clicking selects the suggestion\n const suggestions = this.autocompleteSuggestions();\n const option = suggestions[index];\n if (option) {\n this.selectSuggestion(option);\n }\n } else {\n // In action selection mode, trigger the action selection\n const actions = handleActionSelectionKeydown(\n new KeyboardEvent('keydown', { key: 'Enter' }),\n {\n items: this.displayItems(),\n selectedIndex: index,\n selectedItem: item,\n }\n );\n actions.forEach((action) => this.dispatchAction(action));\n }\n }\n\n private executeItemWithArgs(item: GigamenuItem, args: string[]): void {\n // Record frecency for the action\n this.frecency.recordSelection(this.query(), item.id);\n\n // Build args string from array\n const argsStr = args.length > 0 ? args.join(' ') : undefined;\n\n this.close();\n item.action(argsStr);\n }\n\n private selectSuggestion(option: AutocompleteOption): void {\n // Set the query to the selected option's label (for display)\n this.query.set(option.label);\n\n // Track the selected option for value substitution when executing\n const paramIndex = this.currentParamIndex();\n if (paramIndex !== null) {\n this.selectedParamOptions.update((map) => {\n const newMap = new Map(map);\n newMap.set(paramIndex, option);\n return newMap;\n });\n }\n }\n\n /**\n * Build args array using values from selectedParamOptions when available.\n * For each param, if a suggestion was selected, use its value; otherwise use the typed text.\n */\n private buildArgsWithValues(): string[] {\n const paramValues = this.paramValues();\n const currentQuery = this.query();\n const selectedOptions = this.selectedParamOptions();\n\n const args: string[] = [];\n\n // Add completed param values (use selected option's value if available)\n for (let i = 0; i < paramValues.length; i++) {\n const selectedOption = selectedOptions.get(i);\n if (selectedOption) {\n args.push(selectedOption.value);\n } else {\n args.push(paramValues[i]);\n }\n }\n\n // Add current param value (use selected option's value if available)\n if (currentQuery) {\n const currentParamIdx = this.currentParamIndex();\n if (currentParamIdx !== null) {\n const selectedOption = selectedOptions.get(currentParamIdx);\n if (selectedOption) {\n args.push(selectedOption.value);\n } else {\n args.push(currentQuery);\n }\n } else {\n args.push(currentQuery);\n }\n }\n\n return args.filter(Boolean);\n }\n\n // Template context methods\n protected getItemContext(item: GigamenuItem, index: number) {\n return createItemContext(item, index, this.selectedIndex());\n }\n\n protected getEmptyContext() {\n return createEmptyContext(this.query());\n }\n\n protected getFooterContext() {\n return createFooterContext(this.displayItems().length, this.service.items().length);\n }\n\n protected getHeaderContext() {\n return {\n $implicit: this.query(),\n query: this.query(),\n lockedAction: this.lockedAction(),\n paramValues: this.paramValues(),\n currentParamName: this.currentParamName(),\n placeholder: this.service.config().placeholder ?? '',\n onQueryChange: (value: string) => this.query.set(value),\n onKeydown: (event: KeyboardEvent) => this.onInputKeydown(event),\n onUnlockAction: () => this.unlockActionFromUI(),\n onGoToParam: (index: number) => this.goToParam(index),\n };\n }\n\n protected getPanelContext() {\n return {\n $implicit: this.displayItems(),\n items: this.displayItems(),\n query: this.query(),\n lockedAction: this.lockedAction(),\n paramValues: this.paramValues(),\n selectedIndex: this.selectedIndex(),\n placeholder: this.service.config().placeholder ?? '',\n onItemClick: (item: GigamenuItem, index: number) => this.onItemClick(item, index),\n onSelectIndex: (index: number) => this.selectedIndex.set(index),\n onQueryChange: (query: string) => this.query.set(query),\n onClose: () => this.close(),\n };\n }\n\n // Autocomplete methods\n private async fetchSuggestions(provider: NonNullable<GigamenuItem['paramProviders']>[string], query: string): Promise<void> {\n try {\n const { options, isAsync } = await fetchAutocompleteSuggestions(provider, query, this.autocompleteCache);\n const filtered = isAsync ? options : filterSuggestionsClientSide(options, query);\n this.autocompleteSuggestions.set(filtered);\n this.selectedIndex.set(0);\n } catch (error) {\n console.error('Error fetching autocomplete suggestions:', error);\n this.autocompleteSuggestions.set([]);\n }\n }\n\n private close(): void {\n this.service.close();\n this.query.set('');\n this.selectedIndex.set(0);\n this.lockedAction.set(null);\n this.paramValues.set([]);\n this.autocompleteCache.clear();\n this.selectedParamOptions.set(new Map());\n this.clearProviderResults();\n }\n\n private clearProviderResults(): void {\n for (const timer of this.providerTimers.values()) clearTimeout(timer);\n this.providerTimers.clear();\n this.providerInvocation++; // invalidates in-flight responses\n untracked(() => {\n if (this.providerResults().size > 0) this.providerResults.set(new Map());\n });\n }\n\n private normalizeProviderItems(\n raw: GigamenuProviderItem[],\n providerId: string,\n group: string\n ): GigamenuItem[] {\n return raw.map((item) => ({\n ...item,\n category: item.category ?? 'command',\n providerId,\n group: item.group ?? (group || undefined),\n }));\n }\n\n // Template helper for going back from breadcrumb\n protected unlockActionFromUI(): void {\n this.dispatchAction({ type: 'unlockAction' });\n }\n\n protected goToParam(index: number): void {\n // Go back to a specific parameter\n const values = this.paramValues();\n if (index < values.length) {\n // Set query to the value at that index\n this.query.set(values[index]);\n // Keep only values before that index\n this.paramValues.set(values.slice(0, index));\n this.selectedIndex.set(0);\n }\n }\n}\n","@if (service.isOpen()) {\n<div\n class=\"fixed inset-0 z-50 flex items-stretch justify-center sm:items-start sm:pt-[15vh]\"\n (click)=\"onBackdropClick($event)\"\n>\n <div class=\"fixed inset-0 bg-black/50 backdrop-blur-sm\"></div>\n\n <!-- Custom panel template -->\n @if (panelTemplate(); as pt) {\n <ng-container\n [ngTemplateOutlet]=\"pt.template\"\n [ngTemplateOutletContext]=\"getPanelContext()\"\n ></ng-container>\n } @else {\n <!-- Default panel -->\n <div\n class=\"relative z-10 w-full flex flex-col overflow-hidden border border-neutral-200 bg-white shadow-2xl dark:border-neutral-700 dark:bg-neutral-900 sm:max-w-xl sm:min-h-50 sm:flex-none sm:rounded-xl\"\n role=\"dialog\"\n aria-modal=\"true\"\n aria-label=\"Command menu\"\n >\n <!-- Header -->\n @if (headerTemplate(); as ht) {\n <ng-container\n [ngTemplateOutlet]=\"ht.template\"\n [ngTemplateOutletContext]=\"getHeaderContext()\"\n ></ng-container>\n } @else {\n <div class=\"border-b border-neutral-200 dark:border-neutral-700\">\n <!-- Breadcrumb (when action is locked) -->\n @if (lockedAction(); as action) {\n <div class=\"flex flex-wrap items-center gap-1 px-4 py-2 text-sm\">\n <button\n type=\"button\"\n (click)=\"unlockActionFromUI()\"\n class=\"inline-flex items-center gap-1.5 rounded-md bg-blue-100 px-2 py-1 font-medium text-blue-800 hover:bg-blue-200 dark:bg-blue-900/40 dark:text-blue-300 dark:hover:bg-blue-900/60\"\n >\n @if (action.icon) {\n <span>{{ action.icon }}</span>\n }\n {{ action.label }}\n </button>\n @for (value of paramValues(); track $index) {\n <span class=\"text-neutral-400\">›</span>\n <button\n type=\"button\"\n (click)=\"goToParam($index)\"\n [class]=\"'rounded-md px-2 py-1 font-medium hover:opacity-80 ' + getParamColor($index)\"\n >\n <span class=\"text-xs opacity-60\">{{ action.params?.[$index] }}:</span>\n {{ value }}\n </button>\n }\n @if (currentParamName(); as paramName) {\n <span class=\"text-neutral-400\">›</span>\n <span class=\"text-neutral-500 dark:text-neutral-400 italic\">{{ paramName }}:</span>\n }\n </div>\n }\n\n <!-- Search input row -->\n <div class=\"flex items-center px-4\">\n <svg\n class=\"h-5 w-5 text-neutral-400\"\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path\n stroke-linecap=\"round\"\n stroke-linejoin=\"round\"\n stroke-width=\"2\"\n d=\"M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z\"\n />\n </svg>\n <input\n #searchInput\n type=\"text\"\n [placeholder]=\"lockedAction() ? (currentParamName() ?? 'Enter value...') : service.config().placeholder\"\n [value]=\"query()\"\n (input)=\"onQueryChange($event)\"\n (keydown)=\"onInputKeydown($event)\"\n class=\"w-full px-3 py-4 text-base text-neutral-900 placeholder-neutral-400 outline-none dark:text-neutral-100 bg-transparent\"\n />\n <kbd\n class=\"rounded border border-neutral-200 bg-neutral-100 px-1.5 py-0.5 text-xs text-neutral-500 dark:border-neutral-600 dark:bg-neutral-800 dark:text-neutral-400\"\n >\n ESC\n </kbd>\n </div>\n </div>\n }\n\n <!-- Items list -->\n <div #listContainer class=\"flex-1 overflow-y-auto p-2 sm:flex-none sm:max-h-80\">\n @if (displayItems().length === 0) {\n <!-- Empty state -->\n @if (emptyTemplate(); as et) {\n <ng-container\n [ngTemplateOutlet]=\"et.template\"\n [ngTemplateOutletContext]=\"getEmptyContext()\"\n ></ng-container>\n } @else {\n <div class=\"px-3 py-8 text-center text-neutral-500\">\n @if (lockedAction()) {\n @if (hasAutocomplete()) {\n Type to search...\n } @else {\n Enter a value and press Tab or Enter\n }\n } @else {\n No results found\n }\n </div>\n }\n } @else {\n @for (item of displayItems(); track item.id; let i = $index) {\n <!-- Custom item template -->\n @if (itemTemplate(); as it) {\n <ng-container\n [ngTemplateOutlet]=\"it.template\"\n [ngTemplateOutletContext]=\"getItemContext(item, i)\"\n ></ng-container>\n } @else {\n <!-- Default item -->\n <button\n type=\"button\"\n (click)=\"onItemClick(item, i)\"\n (mouseenter)=\"selectedIndex.set(i)\"\n [attr.data-index]=\"i\"\n [class]=\"\n 'flex w-full items-center gap-3 rounded-lg px-3 py-2.5 text-left transition-colors ' +\n (selectedIndex() === i\n ? 'bg-neutral-100 dark:bg-neutral-800'\n : 'hover:bg-neutral-50 dark:hover:bg-neutral-800/50')\n \"\n >\n @if (!lockedAction()) {\n <!-- Action mode: show icon -->\n @if (item.iconClass) {\n <i [class]=\"item.iconClass + ' text-lg text-neutral-600 dark:text-neutral-300'\"></i>\n } @else if (item.icon) {\n <span class=\"text-lg\">{{ item.icon }}</span>\n } @else {\n <span\n class=\"flex h-6 w-6 items-center justify-center rounded bg-neutral-200 text-xs font-medium text-neutral-600 dark:bg-neutral-700 dark:text-neutral-300\"\n >\n {{ item.category === 'page' ? 'P' : 'C' }}\n </span>\n }\n }\n <div class=\"flex-1 min-w-0\">\n <div class=\"truncate font-medium text-neutral-900 dark:text-neutral-100\">\n {{ item.label }}@if (!lockedAction() && item.params) { @for (param of item.params; track $index) {<span class=\"whitespace-pre\"> </span><span [class]=\"getParamColor($index)\">&lt;{{ param }}&gt;</span>}@if (item.paramProviders) {<span class=\"ml-2 inline-flex items-center rounded border border-neutral-300 bg-neutral-100 px-1 py-0.5 text-[10px] font-normal text-neutral-500 dark:border-neutral-600 dark:bg-neutral-700 dark:text-neutral-400\">Tab</span>}}\n </div>\n @if (item.description) {\n <div class=\"truncate text-sm text-neutral-500 dark:text-neutral-400\">\n {{ item.description }}\n </div>\n }\n </div>\n @if (!lockedAction()) {\n <span\n class=\"rounded-full px-2 py-0.5 text-xs\"\n [class]=\"\n item.category === 'page'\n ? 'bg-blue-100 text-blue-700 dark:bg-blue-900/30 dark:text-blue-400'\n : 'bg-purple-100 text-purple-700 dark:bg-purple-900/30 dark:text-purple-400'\n \"\n >\n {{ item.category }}\n </span>\n }\n </button>\n }\n }\n }\n </div>\n\n <!-- Footer -->\n @if (footerTemplate(); as ft) {\n <ng-container\n [ngTemplateOutlet]=\"ft.template\"\n [ngTemplateOutletContext]=\"getFooterContext()\"\n ></ng-container>\n } @else {\n <div\n class=\"flex items-center justify-between border-t border-neutral-200 px-4 py-2 text-xs text-neutral-500 dark:border-neutral-700\"\n >\n <div class=\"flex items-center gap-3\">\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↑</kbd>\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↓</kbd>\n navigate\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">Tab</kbd>\n @if (lockedAction()) {\n next\n } @else {\n params\n }\n </span>\n <span class=\"flex items-center gap-1\">\n <kbd class=\"rounded border border-neutral-300 bg-neutral-100 px-1 dark:border-neutral-600 dark:bg-neutral-800\">↵</kbd>\n @if (lockedAction()) {\n execute\n } @else {\n select\n }\n </span>\n </div>\n <span>gigamenu</span>\n </div>\n }\n </div>\n }\n</div>\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@flxgde/gigamenu",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "A keyboard-driven command palette menu for Angular applications",
5
5
  "keywords": [
6
6
  "angular",
package/styles.css CHANGED
@@ -1,2 +1,2 @@
1
1
  /*! tailwindcss v4.2.2 | MIT License | https://tailwindcss.com */
2
- @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-900:oklch(38.1% .176 304.987);--color-pink-400:oklch(71.8% .202 349.761);--color-pink-500:oklch(65.6% .241 354.308);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-neutral-950:oklch(14.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.inline-flex{display:inline-flex}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.max-h-80{max-height:calc(var(--spacing) * 80)}.min-h-50{min-height:calc(var(--spacing) * 50)}.min-h-screen{min-height:100vh}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-full{width:100%}.max-w-xl{max-width:var(--container-xl)}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-start{align-items:flex-start}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.rounded-xl{border-radius:var(--radius-xl)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-300{border-color:var(--color-neutral-300)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-neutral-200{background-color:var(--color-neutral-200)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-8{padding-block:calc(var(--spacing) * 8)}.pt-\[15vh\]{padding-top:15vh}.text-center{text-align:center}.text-left{text-align:left}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre{white-space:pre}.text-blue-500{color:var(--color-blue-500)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-cyan-500{color:var(--color-cyan-500)}.text-green-500{color:var(--color-green-500)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-900{color:var(--color-neutral-900)}.text-orange-500{color:var(--color-orange-500)}.text-pink-500{color:var(--color-pink-500)}.text-purple-700{color:var(--color-purple-700)}.italic{font-style:italic}.placeholder-neutral-400::placeholder{color:var(--color-neutral-400)}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:bg-blue-200:hover{background-color:var(--color-blue-200)}.hover\:bg-neutral-50:hover{background-color:var(--color-neutral-50)}.hover\:opacity-80:hover{opacity:.8}}@media (prefers-color-scheme:dark){.dark\:border-neutral-600{border-color:var(--color-neutral-600)}.dark\:border-neutral-700{border-color:var(--color-neutral-700)}.dark\:bg-blue-900\/30{background-color:#1c398e4d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-900\/30{background-color:color-mix(in oklab, var(--color-blue-900) 30%, transparent)}}.dark\:bg-blue-900\/40{background-color:#1c398e66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-900\/40{background-color:color-mix(in oklab, var(--color-blue-900) 40%, transparent)}}.dark\:bg-neutral-700{background-color:var(--color-neutral-700)}.dark\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\:bg-neutral-900{background-color:var(--color-neutral-900)}.dark\:bg-neutral-950{background-color:var(--color-neutral-950)}.dark\:bg-purple-900\/30{background-color:#59168b4d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-purple-900\/30{background-color:color-mix(in oklab, var(--color-purple-900) 30%, transparent)}}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-cyan-400{color:var(--color-cyan-400)}.dark\:text-green-400{color:var(--color-green-400)}.dark\:text-neutral-100{color:var(--color-neutral-100)}.dark\:text-neutral-300{color:var(--color-neutral-300)}.dark\:text-neutral-400{color:var(--color-neutral-400)}.dark\:text-orange-400{color:var(--color-orange-400)}.dark\:text-pink-400{color:var(--color-pink-400)}.dark\:text-purple-400{color:var(--color-purple-400)}@media (hover:hover){.dark\:hover\:bg-blue-900\/60:hover{background-color:#1c398e99}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-blue-900\/60:hover{background-color:color-mix(in oklab, var(--color-blue-900) 60%, transparent)}}.dark\:hover\:bg-neutral-800\/50:hover{background-color:#26262680}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-neutral-800\/50:hover{background-color:color-mix(in oklab, var(--color-neutral-800) 50%, transparent)}}}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}
2
+ @layer properties{@supports (((-webkit-hyphens:none)) and (not (margin-trim:inline))) or ((-moz-orient:inline) and (not (color:rgb(from red r g b)))){*,:before,:after,::backdrop{--tw-space-y-reverse:0;--tw-border-style:solid;--tw-font-weight:initial;--tw-shadow:0 0 #0000;--tw-shadow-color:initial;--tw-shadow-alpha:100%;--tw-inset-shadow:0 0 #0000;--tw-inset-shadow-color:initial;--tw-inset-shadow-alpha:100%;--tw-ring-color:initial;--tw-ring-shadow:0 0 #0000;--tw-inset-ring-color:initial;--tw-inset-ring-shadow:0 0 #0000;--tw-ring-inset:initial;--tw-ring-offset-width:0px;--tw-ring-offset-color:#fff;--tw-ring-offset-shadow:0 0 #0000;--tw-blur:initial;--tw-brightness:initial;--tw-contrast:initial;--tw-grayscale:initial;--tw-hue-rotate:initial;--tw-invert:initial;--tw-opacity:initial;--tw-saturate:initial;--tw-sepia:initial;--tw-drop-shadow:initial;--tw-drop-shadow-color:initial;--tw-drop-shadow-alpha:100%;--tw-drop-shadow-size:initial;--tw-backdrop-blur:initial;--tw-backdrop-brightness:initial;--tw-backdrop-contrast:initial;--tw-backdrop-grayscale:initial;--tw-backdrop-hue-rotate:initial;--tw-backdrop-invert:initial;--tw-backdrop-opacity:initial;--tw-backdrop-saturate:initial;--tw-backdrop-sepia:initial}}}@layer theme{:root,:host{--font-sans:ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";--font-mono:ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace;--color-orange-400:oklch(75% .183 55.934);--color-orange-500:oklch(70.5% .213 47.604);--color-green-400:oklch(79.2% .209 151.711);--color-green-500:oklch(72.3% .219 149.579);--color-cyan-400:oklch(78.9% .154 211.53);--color-cyan-500:oklch(71.5% .143 215.221);--color-blue-100:oklch(93.2% .032 255.585);--color-blue-200:oklch(88.2% .059 254.128);--color-blue-300:oklch(80.9% .105 251.813);--color-blue-400:oklch(70.7% .165 254.624);--color-blue-500:oklch(62.3% .214 259.815);--color-blue-700:oklch(48.8% .243 264.376);--color-blue-800:oklch(42.4% .199 265.638);--color-blue-900:oklch(37.9% .146 265.522);--color-purple-100:oklch(94.6% .033 307.174);--color-purple-400:oklch(71.4% .203 305.504);--color-purple-700:oklch(49.6% .265 301.924);--color-purple-900:oklch(38.1% .176 304.987);--color-pink-400:oklch(71.8% .202 349.761);--color-pink-500:oklch(65.6% .241 354.308);--color-neutral-50:oklch(98.5% 0 0);--color-neutral-100:oklch(97% 0 0);--color-neutral-200:oklch(92.2% 0 0);--color-neutral-300:oklch(87% 0 0);--color-neutral-400:oklch(70.8% 0 0);--color-neutral-500:oklch(55.6% 0 0);--color-neutral-600:oklch(43.9% 0 0);--color-neutral-700:oklch(37.1% 0 0);--color-neutral-800:oklch(26.9% 0 0);--color-neutral-900:oklch(20.5% 0 0);--color-neutral-950:oklch(14.5% 0 0);--color-black:#000;--color-white:#fff;--spacing:.25rem;--container-xl:36rem;--text-xs:.75rem;--text-xs--line-height:calc(1 / .75);--text-sm:.875rem;--text-sm--line-height:calc(1.25 / .875);--text-base:1rem;--text-base--line-height:calc(1.5 / 1);--text-lg:1.125rem;--text-lg--line-height:calc(1.75 / 1.125);--text-xl:1.25rem;--text-xl--line-height:calc(1.75 / 1.25);--text-2xl:1.5rem;--text-2xl--line-height:calc(2 / 1.5);--font-weight-normal:400;--font-weight-medium:500;--font-weight-semibold:600;--font-weight-bold:700;--radius-md:.375rem;--radius-lg:.5rem;--radius-xl:.75rem;--blur-sm:8px;--default-transition-duration:.15s;--default-transition-timing-function:cubic-bezier(.4, 0, .2, 1);--default-font-family:var(--font-sans);--default-mono-font-family:var(--font-mono)}}@layer base{*,:after,:before,::backdrop{box-sizing:border-box;border:0 solid;margin:0;padding:0}::file-selector-button{box-sizing:border-box;border:0 solid;margin:0;padding:0}html,:host{-webkit-text-size-adjust:100%;tab-size:4;line-height:1.5;font-family:var(--default-font-family,ui-sans-serif, system-ui, sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji");font-feature-settings:var(--default-font-feature-settings,normal);font-variation-settings:var(--default-font-variation-settings,normal);-webkit-tap-highlight-color:transparent}hr{height:0;color:inherit;border-top-width:1px}abbr:where([title]){-webkit-text-decoration:underline dotted;text-decoration:underline dotted}h1,h2,h3,h4,h5,h6{font-size:inherit;font-weight:inherit}a{color:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;-webkit-text-decoration:inherit;text-decoration:inherit}b,strong{font-weight:bolder}code,kbd,samp,pre{font-family:var(--default-mono-font-family,ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace);font-feature-settings:var(--default-mono-font-feature-settings,normal);font-variation-settings:var(--default-mono-font-variation-settings,normal);font-size:1em}small{font-size:80%}sub,sup{vertical-align:baseline;font-size:75%;line-height:0;position:relative}sub{bottom:-.25em}sup{top:-.5em}table{text-indent:0;border-color:inherit;border-collapse:collapse}:-moz-focusring{outline:auto}progress{vertical-align:baseline}summary{display:list-item}ol,ul,menu{list-style:none}img,svg,video,canvas,audio,iframe,embed,object{vertical-align:middle;display:block}img,video{max-width:100%;height:auto}button,input,select,optgroup,textarea{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}::file-selector-button{font:inherit;font-feature-settings:inherit;font-variation-settings:inherit;letter-spacing:inherit;color:inherit;opacity:1;background-color:#0000;border-radius:0}:where(select:is([multiple],[size])) optgroup{font-weight:bolder}:where(select:is([multiple],[size])) optgroup option{padding-inline-start:20px}::file-selector-button{margin-inline-end:4px}::placeholder{opacity:1}@supports (not ((-webkit-appearance:-apple-pay-button))) or (contain-intrinsic-size:1px){::placeholder{color:currentColor}@supports (color:color-mix(in lab, red, red)){::placeholder{color:color-mix(in oklab, currentcolor 50%, transparent)}}}textarea{resize:vertical}::-webkit-search-decoration{-webkit-appearance:none}::-webkit-date-and-time-value{min-height:1lh;text-align:inherit}::-webkit-datetime-edit{display:inline-flex}::-webkit-datetime-edit-fields-wrapper{padding:0}::-webkit-datetime-edit{padding-block:0}::-webkit-datetime-edit-year-field{padding-block:0}::-webkit-datetime-edit-month-field{padding-block:0}::-webkit-datetime-edit-day-field{padding-block:0}::-webkit-datetime-edit-hour-field{padding-block:0}::-webkit-datetime-edit-minute-field{padding-block:0}::-webkit-datetime-edit-second-field{padding-block:0}::-webkit-datetime-edit-millisecond-field{padding-block:0}::-webkit-datetime-edit-meridiem-field{padding-block:0}::-webkit-calendar-picker-indicator{line-height:1}:-moz-ui-invalid{box-shadow:none}button,input:where([type=button],[type=reset],[type=submit]){appearance:button}::file-selector-button{appearance:button}::-webkit-inner-spin-button{height:auto}::-webkit-outer-spin-button{height:auto}[hidden]:where(:not([hidden=until-found])){display:none!important}}@layer components;@layer utilities{.fixed{position:fixed}.relative{position:relative}.static{position:static}.inset-0{inset:calc(var(--spacing) * 0)}.start{inset-inline-start:var(--spacing)}.z-10{z-index:10}.z-50{z-index:50}.container{width:100%}@media (min-width:40rem){.container{max-width:40rem}}@media (min-width:48rem){.container{max-width:48rem}}@media (min-width:64rem){.container{max-width:64rem}}@media (min-width:80rem){.container{max-width:80rem}}@media (min-width:96rem){.container{max-width:96rem}}.mb-2{margin-bottom:calc(var(--spacing) * 2)}.mb-8{margin-bottom:calc(var(--spacing) * 8)}.ml-2{margin-left:calc(var(--spacing) * 2)}.block{display:block}.contents{display:contents}.flex{display:flex}.hidden{display:none}.inline-flex{display:inline-flex}.h-5{height:calc(var(--spacing) * 5)}.h-6{height:calc(var(--spacing) * 6)}.min-h-screen{min-height:100vh}.w-5{width:calc(var(--spacing) * 5)}.w-6{width:calc(var(--spacing) * 6)}.w-full{width:100%}.min-w-0{min-width:calc(var(--spacing) * 0)}.flex-1{flex:1}.list-inside{list-style-position:inside}.list-disc{list-style-type:disc}.flex-col{flex-direction:column}.flex-wrap{flex-wrap:wrap}.items-center{align-items:center}.items-stretch{align-items:stretch}.justify-between{justify-content:space-between}.justify-center{justify-content:center}.gap-1{gap:calc(var(--spacing) * 1)}.gap-1\.5{gap:calc(var(--spacing) * 1.5)}.gap-3{gap:calc(var(--spacing) * 3)}:where(.space-y-1>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 1) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 1) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-2>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 2) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 2) * calc(1 - var(--tw-space-y-reverse)))}:where(.space-y-4>:not(:last-child)){--tw-space-y-reverse:0;margin-block-start:calc(calc(var(--spacing) * 4) * var(--tw-space-y-reverse));margin-block-end:calc(calc(var(--spacing) * 4) * calc(1 - var(--tw-space-y-reverse)))}.truncate{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.overflow-hidden{overflow:hidden}.overflow-y-auto{overflow-y:auto}.rounded{border-radius:.25rem}.rounded-full{border-radius:3.40282e38px}.rounded-lg{border-radius:var(--radius-lg)}.rounded-md{border-radius:var(--radius-md)}.border{border-style:var(--tw-border-style);border-width:1px}.border-t{border-top-style:var(--tw-border-style);border-top-width:1px}.border-b{border-bottom-style:var(--tw-border-style);border-bottom-width:1px}.border-neutral-200{border-color:var(--color-neutral-200)}.border-neutral-300{border-color:var(--color-neutral-300)}.bg-black\/50{background-color:#00000080}@supports (color:color-mix(in lab, red, red)){.bg-black\/50{background-color:color-mix(in oklab, var(--color-black) 50%, transparent)}}.bg-blue-100{background-color:var(--color-blue-100)}.bg-neutral-100{background-color:var(--color-neutral-100)}.bg-neutral-200{background-color:var(--color-neutral-200)}.bg-purple-100{background-color:var(--color-purple-100)}.bg-transparent{background-color:#0000}.bg-white{background-color:var(--color-white)}.p-2{padding:calc(var(--spacing) * 2)}.p-4{padding:calc(var(--spacing) * 4)}.p-8{padding:calc(var(--spacing) * 8)}.px-1{padding-inline:calc(var(--spacing) * 1)}.px-1\.5{padding-inline:calc(var(--spacing) * 1.5)}.px-2{padding-inline:calc(var(--spacing) * 2)}.px-3{padding-inline:calc(var(--spacing) * 3)}.px-4{padding-inline:calc(var(--spacing) * 4)}.py-0\.5{padding-block:calc(var(--spacing) * .5)}.py-1{padding-block:calc(var(--spacing) * 1)}.py-2{padding-block:calc(var(--spacing) * 2)}.py-2\.5{padding-block:calc(var(--spacing) * 2.5)}.py-4{padding-block:calc(var(--spacing) * 4)}.py-8{padding-block:calc(var(--spacing) * 8)}.text-center{text-align:center}.text-left{text-align:left}.text-2xl{font-size:var(--text-2xl);line-height:var(--tw-leading,var(--text-2xl--line-height))}.text-base{font-size:var(--text-base);line-height:var(--tw-leading,var(--text-base--line-height))}.text-lg{font-size:var(--text-lg);line-height:var(--tw-leading,var(--text-lg--line-height))}.text-sm{font-size:var(--text-sm);line-height:var(--tw-leading,var(--text-sm--line-height))}.text-xl{font-size:var(--text-xl);line-height:var(--tw-leading,var(--text-xl--line-height))}.text-xs{font-size:var(--text-xs);line-height:var(--tw-leading,var(--text-xs--line-height))}.text-\[10px\]{font-size:10px}.font-bold{--tw-font-weight:var(--font-weight-bold);font-weight:var(--font-weight-bold)}.font-medium{--tw-font-weight:var(--font-weight-medium);font-weight:var(--font-weight-medium)}.font-normal{--tw-font-weight:var(--font-weight-normal);font-weight:var(--font-weight-normal)}.font-semibold{--tw-font-weight:var(--font-weight-semibold);font-weight:var(--font-weight-semibold)}.whitespace-pre{white-space:pre}.text-blue-500{color:var(--color-blue-500)}.text-blue-700{color:var(--color-blue-700)}.text-blue-800{color:var(--color-blue-800)}.text-cyan-500{color:var(--color-cyan-500)}.text-green-500{color:var(--color-green-500)}.text-neutral-400{color:var(--color-neutral-400)}.text-neutral-500{color:var(--color-neutral-500)}.text-neutral-600{color:var(--color-neutral-600)}.text-neutral-900{color:var(--color-neutral-900)}.text-orange-500{color:var(--color-orange-500)}.text-pink-500{color:var(--color-pink-500)}.text-purple-700{color:var(--color-purple-700)}.italic{font-style:italic}.placeholder-neutral-400::placeholder{color:var(--color-neutral-400)}.opacity-60{opacity:.6}.shadow-2xl{--tw-shadow:0 25px 50px -12px var(--tw-shadow-color,#00000040);box-shadow:var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow)}.filter{filter:var(--tw-blur,) var(--tw-brightness,) var(--tw-contrast,) var(--tw-grayscale,) var(--tw-hue-rotate,) var(--tw-invert,) var(--tw-saturate,) var(--tw-sepia,) var(--tw-drop-shadow,)}.backdrop-blur-sm{--tw-backdrop-blur:blur(var(--blur-sm));-webkit-backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,);backdrop-filter:var(--tw-backdrop-blur,) var(--tw-backdrop-brightness,) var(--tw-backdrop-contrast,) var(--tw-backdrop-grayscale,) var(--tw-backdrop-hue-rotate,) var(--tw-backdrop-invert,) var(--tw-backdrop-opacity,) var(--tw-backdrop-saturate,) var(--tw-backdrop-sepia,)}.transition{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to,opacity,box-shadow,transform,translate,scale,rotate,filter,-webkit-backdrop-filter,backdrop-filter,display,content-visibility,overlay,pointer-events;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.transition-colors{transition-property:color,background-color,border-color,outline-color,text-decoration-color,fill,stroke,--tw-gradient-from,--tw-gradient-via,--tw-gradient-to;transition-timing-function:var(--tw-ease,var(--default-transition-timing-function));transition-duration:var(--tw-duration,var(--default-transition-duration))}.outline-none{--tw-outline-style:none;outline-style:none}@media (hover:hover){.hover\:bg-blue-200:hover{background-color:var(--color-blue-200)}.hover\:bg-neutral-50:hover{background-color:var(--color-neutral-50)}.hover\:opacity-80:hover{opacity:.8}}@media (min-width:40rem){.sm\:max-h-80{max-height:calc(var(--spacing) * 80)}.sm\:min-h-50{min-height:calc(var(--spacing) * 50)}.sm\:max-w-xl{max-width:var(--container-xl)}.sm\:flex-none{flex:none}.sm\:items-start{align-items:flex-start}.sm\:rounded-xl{border-radius:var(--radius-xl)}.sm\:pt-\[15vh\]{padding-top:15vh}}@media (prefers-color-scheme:dark){.dark\:border-neutral-600{border-color:var(--color-neutral-600)}.dark\:border-neutral-700{border-color:var(--color-neutral-700)}.dark\:bg-blue-900\/30{background-color:#1c398e4d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-900\/30{background-color:color-mix(in oklab, var(--color-blue-900) 30%, transparent)}}.dark\:bg-blue-900\/40{background-color:#1c398e66}@supports (color:color-mix(in lab, red, red)){.dark\:bg-blue-900\/40{background-color:color-mix(in oklab, var(--color-blue-900) 40%, transparent)}}.dark\:bg-neutral-700{background-color:var(--color-neutral-700)}.dark\:bg-neutral-800{background-color:var(--color-neutral-800)}.dark\:bg-neutral-900{background-color:var(--color-neutral-900)}.dark\:bg-neutral-950{background-color:var(--color-neutral-950)}.dark\:bg-purple-900\/30{background-color:#59168b4d}@supports (color:color-mix(in lab, red, red)){.dark\:bg-purple-900\/30{background-color:color-mix(in oklab, var(--color-purple-900) 30%, transparent)}}.dark\:text-blue-300{color:var(--color-blue-300)}.dark\:text-blue-400{color:var(--color-blue-400)}.dark\:text-cyan-400{color:var(--color-cyan-400)}.dark\:text-green-400{color:var(--color-green-400)}.dark\:text-neutral-100{color:var(--color-neutral-100)}.dark\:text-neutral-300{color:var(--color-neutral-300)}.dark\:text-neutral-400{color:var(--color-neutral-400)}.dark\:text-orange-400{color:var(--color-orange-400)}.dark\:text-pink-400{color:var(--color-pink-400)}.dark\:text-purple-400{color:var(--color-purple-400)}@media (hover:hover){.dark\:hover\:bg-blue-900\/60:hover{background-color:#1c398e99}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-blue-900\/60:hover{background-color:color-mix(in oklab, var(--color-blue-900) 60%, transparent)}}.dark\:hover\:bg-neutral-800\/50:hover{background-color:#26262680}@supports (color:color-mix(in lab, red, red)){.dark\:hover\:bg-neutral-800\/50:hover{background-color:color-mix(in oklab, var(--color-neutral-800) 50%, transparent)}}}}}@property --tw-space-y-reverse{syntax:"*";inherits:false;initial-value:0}@property --tw-border-style{syntax:"*";inherits:false;initial-value:solid}@property --tw-font-weight{syntax:"*";inherits:false}@property --tw-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-shadow-color{syntax:"*";inherits:false}@property --tw-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-inset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-shadow-color{syntax:"*";inherits:false}@property --tw-inset-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-ring-color{syntax:"*";inherits:false}@property --tw-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-inset-ring-color{syntax:"*";inherits:false}@property --tw-inset-ring-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-ring-inset{syntax:"*";inherits:false}@property --tw-ring-offset-width{syntax:"<length>";inherits:false;initial-value:0}@property --tw-ring-offset-color{syntax:"*";inherits:false;initial-value:#fff}@property --tw-ring-offset-shadow{syntax:"*";inherits:false;initial-value:0 0 #0000}@property --tw-blur{syntax:"*";inherits:false}@property --tw-brightness{syntax:"*";inherits:false}@property --tw-contrast{syntax:"*";inherits:false}@property --tw-grayscale{syntax:"*";inherits:false}@property --tw-hue-rotate{syntax:"*";inherits:false}@property --tw-invert{syntax:"*";inherits:false}@property --tw-opacity{syntax:"*";inherits:false}@property --tw-saturate{syntax:"*";inherits:false}@property --tw-sepia{syntax:"*";inherits:false}@property --tw-drop-shadow{syntax:"*";inherits:false}@property --tw-drop-shadow-color{syntax:"*";inherits:false}@property --tw-drop-shadow-alpha{syntax:"<percentage>";inherits:false;initial-value:100%}@property --tw-drop-shadow-size{syntax:"*";inherits:false}@property --tw-backdrop-blur{syntax:"*";inherits:false}@property --tw-backdrop-brightness{syntax:"*";inherits:false}@property --tw-backdrop-contrast{syntax:"*";inherits:false}@property --tw-backdrop-grayscale{syntax:"*";inherits:false}@property --tw-backdrop-hue-rotate{syntax:"*";inherits:false}@property --tw-backdrop-invert{syntax:"*";inherits:false}@property --tw-backdrop-opacity{syntax:"*";inherits:false}@property --tw-backdrop-saturate{syntax:"*";inherits:false}@property --tw-backdrop-sepia{syntax:"*";inherits:false}
@@ -419,7 +419,7 @@ declare class GigamenuComponent {
419
419
  private readonly selectedParamOptions;
420
420
  private readonly providerResults;
421
421
  private providerTimers;
422
- private providerGeneration;
422
+ private providerInvocation;
423
423
  private readonly queryParser;
424
424
  protected readonly selectedItem: _angular_core.Signal<GigamenuItem>;
425
425
  protected readonly currentParamIndex: _angular_core.Signal<number>;