pith-ui 0.1.0 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (124) hide show
  1. package/AI.md +20 -1
  2. package/API.md +834 -272
  3. package/README.md +3 -1
  4. package/dist/composer.d.ts.map +1 -1
  5. package/dist/composer.js +48 -29
  6. package/dist/composer.js.map +1 -1
  7. package/dist/content/conversation-reader.d.ts.map +1 -1
  8. package/dist/content/conversation-reader.js +8 -1
  9. package/dist/content/conversation-reader.js.map +1 -1
  10. package/dist/content/conversation-view.d.ts +21 -4
  11. package/dist/content/conversation-view.d.ts.map +1 -1
  12. package/dist/content/conversation-view.js +72 -13
  13. package/dist/content/conversation-view.js.map +1 -1
  14. package/dist/content/image-viewer.d.ts +4 -2
  15. package/dist/content/image-viewer.d.ts.map +1 -1
  16. package/dist/content/image-viewer.js +36 -15
  17. package/dist/content/image-viewer.js.map +1 -1
  18. package/dist/content/paged-preview.d.ts +1 -1
  19. package/dist/content/paged-preview.d.ts.map +1 -1
  20. package/dist/content/paged-preview.js +10 -5
  21. package/dist/content/paged-preview.js.map +1 -1
  22. package/dist/content/views.d.ts +3 -0
  23. package/dist/content/views.d.ts.map +1 -1
  24. package/dist/content/views.js +110 -41
  25. package/dist/content/views.js.map +1 -1
  26. package/dist/content/welcome.d.ts.map +1 -1
  27. package/dist/content/welcome.js +19 -7
  28. package/dist/content/welcome.js.map +1 -1
  29. package/dist/dom.js +1 -1
  30. package/dist/dom.js.map +1 -1
  31. package/dist/files/panels.d.ts +8 -1
  32. package/dist/files/panels.d.ts.map +1 -1
  33. package/dist/files/panels.js +235 -120
  34. package/dist/files/panels.js.map +1 -1
  35. package/dist/files/systems.d.ts.map +1 -1
  36. package/dist/files/systems.js +81 -91
  37. package/dist/files/systems.js.map +1 -1
  38. package/dist/forms/actions.d.ts +28 -7
  39. package/dist/forms/actions.d.ts.map +1 -1
  40. package/dist/forms/actions.js +59 -11
  41. package/dist/forms/actions.js.map +1 -1
  42. package/dist/forms/custom-connection.d.ts +2 -1
  43. package/dist/forms/custom-connection.d.ts.map +1 -1
  44. package/dist/forms/custom-connection.js +36 -28
  45. package/dist/forms/custom-connection.js.map +1 -1
  46. package/dist/forms/dialog-frame.d.ts +2 -0
  47. package/dist/forms/dialog-frame.d.ts.map +1 -1
  48. package/dist/forms/dialog-frame.js +46 -26
  49. package/dist/forms/dialog-frame.js.map +1 -1
  50. package/dist/forms/history.d.ts +1 -1
  51. package/dist/forms/history.d.ts.map +1 -1
  52. package/dist/forms/history.js +78 -15
  53. package/dist/forms/history.js.map +1 -1
  54. package/dist/forms/identity.d.ts +12 -0
  55. package/dist/forms/identity.d.ts.map +1 -1
  56. package/dist/forms/identity.js +16 -0
  57. package/dist/forms/identity.js.map +1 -1
  58. package/dist/forms/model-editor.d.ts +8 -3
  59. package/dist/forms/model-editor.d.ts.map +1 -1
  60. package/dist/forms/model-editor.js +73 -62
  61. package/dist/forms/model-editor.js.map +1 -1
  62. package/dist/forms/panels.d.ts +103 -7
  63. package/dist/forms/panels.d.ts.map +1 -1
  64. package/dist/forms/panels.js +183 -77
  65. package/dist/forms/panels.js.map +1 -1
  66. package/dist/forms/provider-login.d.ts.map +1 -1
  67. package/dist/forms/provider-login.js +25 -39
  68. package/dist/forms/provider-login.js.map +1 -1
  69. package/dist/forms/resource-editor.d.ts +9 -5
  70. package/dist/forms/resource-editor.d.ts.map +1 -1
  71. package/dist/forms/resource-editor.js +20 -9
  72. package/dist/forms/resource-editor.js.map +1 -1
  73. package/dist/foundations.d.ts +95 -0
  74. package/dist/foundations.d.ts.map +1 -0
  75. package/dist/foundations.js +299 -0
  76. package/dist/foundations.js.map +1 -0
  77. package/dist/navigation/context-menu.d.ts +8 -1
  78. package/dist/navigation/context-menu.d.ts.map +1 -1
  79. package/dist/navigation/context-menu.js +67 -50
  80. package/dist/navigation/context-menu.js.map +1 -1
  81. package/dist/navigation/navigation.d.ts +55 -7
  82. package/dist/navigation/navigation.d.ts.map +1 -1
  83. package/dist/navigation/navigation.js +167 -18
  84. package/dist/navigation/navigation.js.map +1 -1
  85. package/dist/operation.d.ts +12 -0
  86. package/dist/operation.d.ts.map +1 -0
  87. package/dist/operation.js +49 -0
  88. package/dist/operation.js.map +1 -0
  89. package/dist/primitives.d.ts +11 -1
  90. package/dist/primitives.d.ts.map +1 -1
  91. package/dist/primitives.js +164 -301
  92. package/dist/primitives.js.map +1 -1
  93. package/dist/reconcile.d.ts +11 -0
  94. package/dist/reconcile.d.ts.map +1 -0
  95. package/dist/reconcile.js +36 -0
  96. package/dist/reconcile.js.map +1 -0
  97. package/dist/select.d.ts +14 -0
  98. package/dist/select.d.ts.map +1 -0
  99. package/dist/select.js +304 -0
  100. package/dist/select.js.map +1 -0
  101. package/dist/styles.css +452 -382
  102. package/dist/surface.d.ts +60 -0
  103. package/dist/surface.d.ts.map +1 -0
  104. package/dist/surface.js +344 -0
  105. package/dist/surface.js.map +1 -0
  106. package/dist/tasks/approval.d.ts.map +1 -1
  107. package/dist/tasks/approval.js +86 -45
  108. package/dist/tasks/approval.js.map +1 -1
  109. package/dist/tasks/permission-element.d.ts +3 -0
  110. package/dist/tasks/permission-element.d.ts.map +1 -0
  111. package/dist/tasks/permission-element.js +10 -0
  112. package/dist/tasks/permission-element.js.map +1 -0
  113. package/dist/tasks/permission.d.ts +5 -3
  114. package/dist/tasks/permission.d.ts.map +1 -1
  115. package/dist/tasks/permission.js +47 -22
  116. package/dist/tasks/permission.js.map +1 -1
  117. package/dist/tasks/runtime.d.ts.map +1 -1
  118. package/dist/tasks/runtime.js +30 -13
  119. package/dist/tasks/runtime.js.map +1 -1
  120. package/dist/workspace.d.ts +58 -4
  121. package/dist/workspace.d.ts.map +1 -1
  122. package/dist/workspace.js +202 -44
  123. package/dist/workspace.js.map +1 -1
  124. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../../src/navigation/context-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UIBlock } from '../core.js';\nexport interface ContextMenuItem {\n label: string; action?: string; sdkAction?: string; danger?: boolean; disabled?: boolean;\n idle?: {conversationId?: string; workspaceId?: string};\n}\nexport interface ContextMenuState {label: string; items: readonly ContextMenuItem[]}\nexport function createContextMenu(options: {element?: HTMLElement; onDismiss?: (restoreFocus: boolean) => void; onAction?: (item: ContextMenuItem) => void} = {}): UIBlock<ContextMenuState> & {open(trigger: HTMLElement, state: ContextMenuState): void; close(restoreFocus?: boolean): void} {\n const element = options.element || document.createElement('div');\n if (!options.element) {element.className = 'pui-sidebar-conversation-menu pui-context-menu'; element.setAttribute('role', 'menu'); element.hidden = true;}\n const abort = new AbortController(); let trigger: HTMLElement | null = null; let destroyed = false;\n const close = (restoreFocus = false) => {element.hidden = true; trigger?.setAttribute('aria-expanded', 'false'); if (restoreFocus) trigger?.focus(); trigger = null;};\n const update = (state: Readonly<ContextMenuState>) => {\n if (destroyed) return; element.setAttribute('aria-label', state.label); element.replaceChildren();\n for (const item of state.items) {\n const button = document.createElement('button'); button.type = 'button'; button.setAttribute('role', 'menuitem'); button.textContent = item.label; button.disabled = !!item.disabled;\n if (item.danger) button.className = 'pui-destructive-menu-item';\n if (item.action) button.dataset.action = item.action;\n if (item.sdkAction) button.dataset.sdk = item.sdkAction;\n if (item.idle) {button.dataset.idleAction = ''; if (item.idle.conversationId) button.dataset.idleConversation = item.idle.conversationId; if (item.idle.workspaceId) button.dataset.idleWorkspace = item.idle.workspaceId;}\n if (options.onAction) button.addEventListener('click', () => options.onAction!(item), {signal:abort.signal});\n element.append(button);\n }\n };\n element.addEventListener('keydown', (event) => {\n if (event.key === 'Escape') {event.preventDefault(); event.stopPropagation(); options.onDismiss ? options.onDismiss(true) : close(true); return;}\n if (event.key === 'Tab') {options.onDismiss ? options.onDismiss(false) : close(false); return;}\n const buttons = [...element.querySelectorAll<HTMLButtonElement>('button:not(:disabled)')];\n if (['ArrowDown', 'ArrowUp', 'Home', 'End'].includes(event.key)) {\n event.preventDefault(); event.stopPropagation(); const index = buttons.indexOf(document.activeElement as HTMLButtonElement);\n const next = event.key === 'Home' ? 0 : event.key === 'End' ? buttons.length - 1 : (index + (event.key === 'ArrowDown' ? 1 : -1) + buttons.length) % buttons.length;\n buttons[next]?.focus();\n }\n }, {signal:abort.signal});\n return {element, update, close, open(source, state) {if (destroyed) return; close(); trigger = source; trigger.setAttribute('aria-expanded', 'true'); update(state); element.hidden = false; const rect = source.getBoundingClientRect(); element.style.left = `${Math.max(8, Math.min(rect.right, window.innerWidth - element.offsetWidth - 8))}px`; element.style.top = `${Math.max(8, Math.min(rect.bottom + 4, window.innerHeight - element.offsetHeight - 8))}px`; element.querySelector<HTMLButtonElement>('button:not(:disabled)')?.focus();}, destroy() {if (destroyed) return; destroyed = true; close(); abort.abort(); if (!options.element) element.remove();}};\n}\n"]}
1
+ {"version":3,"file":"context-menu.js","sourceRoot":"","sources":["../../src/navigation/context-menu.ts"],"names":[],"mappings":"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","sourcesContent":["import type { UIBlock } from '../core.js';\nimport { installAnchoredSurface, installMenuNavigation } from '../surface.js';\nimport { adoptProductParts } from '../foundations.js';\nimport { reconcileKeyed } from '../reconcile.js';\nexport interface ContextMenuItem {\n id?: string; label: string; action?: string; sdkAction?: string; danger?: boolean; disabled?: boolean;\n idle?: {conversationId?: string; workspaceId?: string};\n}\nexport interface ContextMenuState {label: string; items: readonly ContextMenuItem[]}\nexport interface ContextMenuOpenOptions {point?: {x: number; y: number}}\nexport function createContextMenu(options: {element?: HTMLElement; onDismiss?: (restoreFocus: boolean) => void; onAction?: (item: ContextMenuItem) => void} = {}): UIBlock<ContextMenuState> & {open(trigger: HTMLElement, state: ContextMenuState, options?: ContextMenuOpenOptions): void; close(restoreFocus?: boolean): void} {\n const element = options.element || document.createElement('div');\n if (!options.element) {element.className = 'pui-sidebar-conversation-menu pui-context-menu'; element.setAttribute('role', 'menu'); element.hidden = true;}\n element.setAttribute('role', 'menu'); element.tabIndex = -1;\n const abort = new AbortController(); let destroyed = false, programmaticClose = false;\n let surface: ReturnType<typeof installAnchoredSurface> | undefined;\n const parts = adoptProductParts(element);\n const rows = new Map<string, HTMLButtonElement>();\n const actions = new Map<HTMLButtonElement, ContextMenuItem>();\n const close = (restoreFocus = false) => {\n programmaticClose = true;\n surface?.close(restoreFocus); surface?.destroy(); surface = undefined;\n element.hidden = true; programmaticClose = false;\n };\n const dismiss = (restoreFocus: boolean) => {close(restoreFocus); options.onDismiss?.(restoreFocus);};\n const navigation = installMenuNavigation(element, {onDismiss: dismiss, isOpen: () => surface?.isOpen() ?? false});\n const update = (state: Readonly<ContextMenuState>) => {\n if (destroyed) return; element.setAttribute('aria-label', state.label);\n const entries = state.items.map((item, index) => ({item, key: item.id ?? `${item.action || ''}/${item.sdkAction || ''}/${index}`}));\n reconcileKeyed(element, rows, entries, {key: entry => entry.key, element: button => button,\n create() {const button = document.createElement('button'); button.type = 'button'; button.setAttribute('role', 'menuitem'); return button;},\n update(button, {item}) {\n parts.action(button).update({label: item.label, disabled: !!item.disabled});\n button.classList.toggle('pui-destructive-menu-item', !!item.danger);\n if (item.action) button.dataset.action = item.action; else delete button.dataset.action;\n if (item.sdkAction) button.dataset.sdk = item.sdkAction; else delete button.dataset.sdk;\n for (const name of ['idleAction', 'idleConversation', 'idleWorkspace']) delete button.dataset[name];\n if (item.idle) {button.dataset.idleAction = ''; if (item.idle.conversationId) button.dataset.idleConversation = item.idle.conversationId; if (item.idle.workspaceId) button.dataset.idleWorkspace = item.idle.workspaceId;}\n actions.set(button, item);\n }, destroy(button) {actions.delete(button);},\n });\n parts.update();\n };\n if (options.onAction) element.addEventListener('click', event => {const button = (event.target as Element).closest<HTMLButtonElement>('button'); const item = button ? actions.get(button) : undefined; if (item && !button!.disabled) {event.stopPropagation();options.onAction!(item);}}, {signal: abort.signal});\n return {element, update, close, open(source, state, anchor = {}) {\n if (destroyed) return;\n close(); update(state); source.focus({preventScroll: true});\n surface = installAnchoredSurface({trigger: source, panel: element, dismissOnMove: true,\n ...(anchor.point ? {getAnchor: () => ({left: anchor.point!.x, right: anchor.point!.x, top: anchor.point!.y, bottom: anchor.point!.y, width: 0, height: 0})} : {}),\n onToggle(open, restoreFocus) {if (!open && !programmaticClose) options.onDismiss?.(!!restoreFocus);},\n });\n surface.open(); navigation.focus();\n if (surface.isOpen() && !element.contains(document.activeElement)) element.focus({preventScroll: true});\n }, destroy() {if (destroyed) return; destroyed = true; close(); navigation.destroy(); abort.abort(); parts.destroy(); rows.clear(); actions.clear(); if (!options.element) element.remove();}};\n}\n"]}
@@ -1,4 +1,4 @@
1
- import type { UIBlock } from '../core.js';
1
+ import { type ActionResult, type UIBlock } from '../core.js';
2
2
  export interface NavigationConversation {
3
3
  id: string;
4
4
  title?: string;
@@ -20,11 +20,24 @@ export interface WorkspaceNavigationState {
20
20
  empty: 'workspaces' | 'search' | null;
21
21
  disabled?: boolean;
22
22
  }
23
+ export type WorkspaceNavigationAction = {
24
+ action: 'add-workspace';
25
+ trigger: HTMLButtonElement;
26
+ } | {
27
+ action: 'new-conversation' | 'workspace-menu';
28
+ workspaceId: string;
29
+ trigger: HTMLButtonElement;
30
+ } | {
31
+ action: 'conversation-menu';
32
+ conversationId: string;
33
+ trigger: HTMLButtonElement;
34
+ };
23
35
  export declare function createWorkspaceNavigation(initial: WorkspaceNavigationState, options?: {
24
36
  element?: HTMLElement;
25
37
  idPrefix?: string;
26
38
  onToggle?: (id: string) => void;
27
39
  onSelect?: (id: string) => void;
40
+ onAction?: (action: WorkspaceNavigationAction) => void;
28
41
  }): UIBlock<WorkspaceNavigationState>;
29
42
  export interface RenameConversationState {
30
43
  id: string;
@@ -32,12 +45,28 @@ export interface RenameConversationState {
32
45
  error?: string;
33
46
  disabled?: boolean;
34
47
  }
35
- export declare function createRenameConversation(initial: RenameConversationState, options?: {
48
+ export interface RenameConversationDraft {
49
+ id: string;
50
+ title: string;
51
+ }
52
+ export interface RenameConversationOptions {
36
53
  idPrefix?: string;
37
- }): UIBlock<RenameConversationState> & {
54
+ dialog?: HTMLDialogElement;
55
+ unavailable?: () => boolean;
56
+ onSubmit?: (draft: RenameConversationDraft) => Promise<ActionResult> | ActionResult;
57
+ onSubmitted?: () => void;
58
+ onCancel?: () => void;
59
+ }
60
+ export interface RenameConversationBlock extends UIBlock<RenameConversationState> {
38
61
  readonly input: HTMLInputElement;
39
62
  readonly form: HTMLFormElement;
40
- };
63
+ read(): RenameConversationDraft;
64
+ reset(state: RenameConversationState): void;
65
+ open(state?: RenameConversationState): void;
66
+ close(): void;
67
+ focus(): void;
68
+ }
69
+ export declare function createRenameConversation(initial: RenameConversationState, options?: RenameConversationOptions): RenameConversationBlock;
41
70
  export interface WorkspacePickerState {
42
71
  workspaces: readonly {
43
72
  id: string;
@@ -47,11 +76,30 @@ export interface WorkspacePickerState {
47
76
  error?: string;
48
77
  disabled?: boolean;
49
78
  }
50
- export declare function createWorkspacePicker(initial: WorkspacePickerState, options?: {
79
+ export interface WorkspacePickerOptions {
51
80
  idPrefix?: string;
52
- }): UIBlock<WorkspacePickerState> & {
81
+ dialog?: HTMLDialogElement;
82
+ unavailable?: () => boolean;
83
+ onSubmit?: (path: string) => Promise<ActionResult> | ActionResult;
84
+ onPick?: () => Promise<{
85
+ path?: string;
86
+ error?: string;
87
+ }>;
88
+ onSelect?: (id: string) => void;
89
+ onSubmitted?: () => void;
90
+ onCancel?: () => void;
91
+ }
92
+ export interface WorkspacePickerBlock extends UIBlock<WorkspacePickerState> {
53
93
  readonly input: HTMLInputElement;
54
94
  readonly form: HTMLFormElement;
55
95
  readonly pickButton: HTMLButtonElement;
56
- };
96
+ read(): {
97
+ path: string;
98
+ };
99
+ reset(path?: string): void;
100
+ open(): void;
101
+ close(): void;
102
+ focus(): void;
103
+ }
104
+ export declare function createWorkspacePicker(initial: WorkspacePickerState, options?: WorkspacePickerOptions): WorkspacePickerBlock;
57
105
  //# sourceMappingURL=navigation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/navigation/navigation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,MAAM,WAAW,sBAAsB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,IAAI,GAAG,IAAI,CAAA;CAAC;AAC/H,MAAM,WAAW,mBAAmB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,SAAS,sBAAsB,EAAE,CAAA;CAAC;AACpL,MAAM,WAAW,wBAAwB;IAAE,MAAM,EAAE,SAAS,mBAAmB,EAAE,CAAC;IAAC,KAAK,EAAE,YAAY,GAAG,QAAQ,GAAG,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AAG7I,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,wBAAwB,EAAE,OAAO,GAAE;IAAC,OAAO,CAAC,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAC;IAAC,QAAQ,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,IAAI,CAAA;CAAM,GAAG,OAAO,CAAC,wBAAwB,CAAC,CAoD1O;AACD,MAAM,WAAW,uBAAuB;IAAE,EAAE,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AACxG,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,uBAAuB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,OAAO,CAAC,uBAAuB,CAAC,GAAG;IAAC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAA;CAAC,CAKnN;AACD,MAAM,WAAW,oBAAoB;IAAE,UAAU,EAAE,SAAS;QAAC,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAC,EAAE,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,CAAA;CAAC;AAC3I,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,oBAAoB,EAAE,OAAO,GAAE;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAM,GAAG,OAAO,CAAC,oBAAoB,CAAC,GAAG;IAAC,QAAQ,CAAC,KAAK,EAAE,gBAAgB,CAAC;IAAC,QAAQ,CAAC,IAAI,EAAE,eAAe,CAAC;IAAC,QAAQ,CAAC,UAAU,EAAE,iBAAiB,CAAA;CAAC,CAKlP"}
1
+ {"version":3,"file":"navigation.d.ts","sourceRoot":"","sources":["../../src/navigation/navigation.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,10 @@
1
1
  import { scopeIds } from '../forms/identity.js';
2
+ import { Lifetime } from '../core.js';
2
3
  import { dialogHeading, escape, icon, uniqueId } from '../dom.js';
4
+ import { adoptProductParts } from '../foundations.js';
5
+ import { installDialogLifecycle } from '../surface.js';
6
+ import { createOperation } from '../operation.js';
7
+ import { reconcileKeyed } from '../reconcile.js';
3
8
  export function createWorkspaceNavigation(initial, options = {}) {
4
9
  const element = options.element || document.createElement('nav');
5
10
  if (!options.element) {
@@ -9,6 +14,7 @@ export function createWorkspaceNavigation(initial, options = {}) {
9
14
  const prefix = options.idPrefix ?? uniqueId('pui-nav') + '-';
10
15
  const abort = new AbortController();
11
16
  let destroyed = false;
17
+ const parts = adoptProductParts(element);
12
18
  const workspaces = new Map();
13
19
  const conversations = new Map();
14
20
  const emptyWorkspace = document.createElement('button');
@@ -68,10 +74,10 @@ export function createWorkspaceNavigation(initial, options = {}) {
68
74
  group.more.dataset.workspaceMenu = workspace.id;
69
75
  group.more.setAttribute('aria-label', 'Actions for workspace ' + workspace.name);
70
76
  group.more.setAttribute('aria-expanded', String(!!workspace.menuOpen));
71
- group.more.disabled = !!state.disabled;
77
+ parts.action(group.more).update({ disabled: !!state.disabled });
72
78
  group.create.dataset.newWorkspace = workspace.id;
73
79
  group.create.setAttribute('aria-label', 'New conversation in ' + workspace.name);
74
- group.create.disabled = !!state.disabled;
80
+ parts.action(group.create).update({ disabled: !!state.disabled });
75
81
  group.children.id = prefix + 'workspace-children-' + workspace.id;
76
82
  group.children.hidden = !workspace.expanded;
77
83
  let rowCursor = group.children.firstElementChild;
@@ -85,8 +91,7 @@ export function createWorkspaceNavigation(initial, options = {}) {
85
91
  const title = entry.title || 'Untitled conversation';
86
92
  row.element.classList.toggle('pui-active', entry.active);
87
93
  row.button.dataset.conversation = entry.id;
88
- row.button.title = title;
89
- row.button.disabled = !!state.disabled;
94
+ parts.action(row.button).update({ title, disabled: !!state.disabled });
90
95
  if (entry.active)
91
96
  row.button.setAttribute('aria-current', 'page');
92
97
  else
@@ -97,7 +102,7 @@ export function createWorkspaceNavigation(initial, options = {}) {
97
102
  row.more.dataset.conversationMenu = entry.id;
98
103
  row.more.setAttribute('aria-label', 'Actions for ' + title);
99
104
  row.more.setAttribute('aria-expanded', String(!!entry.menuOpen));
100
- row.more.disabled = !!state.disabled;
105
+ parts.action(row.more).update({ disabled: !!state.disabled });
101
106
  const signature = entry.status === row.statusSource && entry.status instanceof DocumentFragment && entry.status.childNodes.length === 0 ? row.statusSignature : statusSignature(entry.status);
102
107
  row.statusSource = entry.status;
103
108
  if (signature !== row.statusSignature) {
@@ -137,20 +142,41 @@ export function createWorkspaceNavigation(initial, options = {}) {
137
142
  }
138
143
  else
139
144
  emptyWorkspace.remove();
145
+ parts.action(emptyWorkspace).update({ disabled: !!state.disabled });
140
146
  if (state.empty === 'search') {
141
147
  if (emptySearch.parentElement !== element)
142
148
  element.append(emptySearch);
143
149
  }
144
150
  else
145
151
  emptySearch.remove();
152
+ parts.update();
146
153
  };
147
- element.addEventListener('click', event => { const target = event.target.closest('button'); if (target?.disabled)
148
- return; if (target?.dataset.toggleWorkspace)
149
- options.onToggle?.(target.dataset.toggleWorkspace); if (target?.dataset.conversation)
150
- options.onSelect?.(target.dataset.conversation); }, { signal: abort.signal });
154
+ element.addEventListener('click', event => {
155
+ const target = event.target.closest('button');
156
+ if (!target || target.disabled)
157
+ return;
158
+ if (target.dataset.toggleWorkspace && options.onToggle) {
159
+ event.stopPropagation();
160
+ options.onToggle(target.dataset.toggleWorkspace);
161
+ return;
162
+ }
163
+ if (target.dataset.conversation && options.onSelect) {
164
+ event.stopPropagation();
165
+ options.onSelect(target.dataset.conversation);
166
+ return;
167
+ }
168
+ const action = target === emptyWorkspace ? { action: 'add-workspace', trigger: target }
169
+ : target.dataset.newWorkspace ? { action: 'new-conversation', workspaceId: target.dataset.newWorkspace, trigger: target }
170
+ : target.dataset.workspaceMenu ? { action: 'workspace-menu', workspaceId: target.dataset.workspaceMenu, trigger: target }
171
+ : target.dataset.conversationMenu ? { action: 'conversation-menu', conversationId: target.dataset.conversationMenu, trigger: target } : undefined;
172
+ if (action && options.onAction) {
173
+ event.stopPropagation();
174
+ options.onAction(action);
175
+ }
176
+ }, { signal: abort.signal });
151
177
  update(initial);
152
178
  return { element, update, destroy() { if (destroyed)
153
- return; destroyed = true; abort.abort(); workspaces.clear(); conversations.clear(); if (!options.element)
179
+ return; destroyed = true; abort.abort(); parts.destroy(); workspaces.clear(); conversations.clear(); if (!options.element)
154
180
  element.remove(); } };
155
181
  }
156
182
  export function createRenameConversation(initial, options = {}) {
@@ -161,11 +187,51 @@ export function createRenameConversation(initial, options = {}) {
161
187
  const input = element.querySelector('#conversation-title');
162
188
  const form = element.querySelector('#rename-form');
163
189
  const error = element.querySelector('#rename-error');
164
- const update = (state) => { if (state.error !== undefined)
165
- error.textContent = state.error; const button = form.querySelector('button[type="submit"]'); button.disabled = !!state.disabled; };
166
- update(initial);
167
190
  scopeIds(element, options.idPrefix ?? uniqueId('pui-rename') + '-');
168
- return { element, input, form, update, destroy() { element.remove(); } };
191
+ const parts = adoptProductParts(element);
192
+ const control = parts.control(input);
193
+ const feedback = parts.feedback(error);
194
+ const button = form.querySelector('button[type="submit"]');
195
+ const action = parts.action(button);
196
+ const life = new Lifetime();
197
+ let current = initial;
198
+ let targetId = initial.id;
199
+ let destroyed = false;
200
+ const sync = () => { action.update({ disabled: !!current.disabled || !!options.unavailable?.(), pending: operation.pending }); feedback.update({ message: current.error || '', tone: 'error' }); };
201
+ const operation = createOperation({ unavailable: () => destroyed || !!current.disabled || !!options.unavailable?.(), onPending: sync, onError(message) { current = { ...current, error: message }; sync(); } });
202
+ const lifecycle = options.dialog ? installDialogLifecycle(options.dialog, { onOpen() { operation.invalidate(); }, onClose() { operation.invalidate(); } }) : undefined;
203
+ const update = (next) => { if (destroyed)
204
+ return; current = { ...next, error: next.error ?? current.error }; sync(); };
205
+ const reset = (next) => { if (destroyed)
206
+ return; operation.invalidate(); targetId = next.id; current = next; control.reset(next.title); button.dataset.idleConversation = next.id; sync(); };
207
+ const close = () => { operation.invalidate(); lifecycle?.close(); };
208
+ if (options.onSubmit)
209
+ life.listen(form, 'submit', (event => {
210
+ event.preventDefault();
211
+ const title = control.getValue().trim();
212
+ if (!title)
213
+ return;
214
+ operation.run(() => { current = { ...current, error: '' }; sync(); return options.onSubmit({ id: targetId, title }); }, result => {
215
+ if (options.dialog && !options.dialog.open)
216
+ return;
217
+ if (result.ok) {
218
+ lifecycle?.close();
219
+ options.onSubmitted?.();
220
+ }
221
+ else
222
+ current = { ...current, error: result.error };
223
+ sync();
224
+ });
225
+ }));
226
+ life.listen(element, 'click', (event => { if (event.target.closest('[data-close]')) {
227
+ operation.invalidate();
228
+ options.onCancel?.();
229
+ lifecycle?.close();
230
+ } }));
231
+ update(initial);
232
+ return { element, input, form, update, read: () => ({ id: targetId, title: control.getValue() }), reset, open(next) { if (next)
233
+ reset(next); lifecycle?.open(); input.select(); }, close, focus() { input.select(); }, destroy() { if (destroyed)
234
+ return; destroyed = true; operation.destroy(); life.destroy(); lifecycle?.close(); lifecycle?.destroy(); parts.destroy(); element.remove(); } };
169
235
  }
170
236
  export function createWorkspacePicker(initial, options = {}) {
171
237
  const state = initial;
@@ -176,10 +242,93 @@ export function createWorkspacePicker(initial, options = {}) {
176
242
  const form = element.querySelector('#workspace-form');
177
243
  const pickButton = element.querySelector('#pick-folder');
178
244
  const error = element.querySelector('#workspace-error');
179
- const update = (state) => { if (state.error !== undefined)
180
- error.textContent = state.error; const button = form.querySelector('button[type="submit"]'); button.disabled = !!state.disabled; };
181
- update(initial);
182
245
  scopeIds(element, options.idPrefix ?? uniqueId('pui-workspace') + '-');
183
- return { element, input, form, pickButton, update, destroy() { element.remove(); } };
246
+ const list = element.querySelector('.pui-modal-workspaces');
247
+ const rows = new Map([...list.querySelectorAll('[data-modal-workspace]')].map(row => [row.dataset.modalWorkspace, row]));
248
+ const parts = adoptProductParts(element);
249
+ const control = parts.control(input);
250
+ const feedback = parts.feedback(error);
251
+ const submitButton = form.querySelector('button[type="submit"]');
252
+ const life = new Lifetime();
253
+ let current = initial;
254
+ let destroyed = false;
255
+ const unavailable = () => destroyed || !!current.disabled || !!options.unavailable?.();
256
+ const sync = () => { const disabled = unavailable(), pending = pickOperation.pending || submitOperation.pending; parts.action(submitButton).update({ disabled, pending }); parts.action(pickButton).update({ disabled, pending }); for (const row of rows.values())
257
+ parts.action(row).update({ disabled: disabled || pending }); feedback.update({ message: current.error || '', tone: 'error' }); };
258
+ const fail = (message) => { current = { ...current, error: message }; sync(); };
259
+ const pickOperation = createOperation({ unavailable: () => unavailable() || submitOperation.pending, onPending: sync, onError(message) { fail(`${message} You can enter the path below.`); control.focus(); } });
260
+ const submitOperation = createOperation({ unavailable: () => unavailable() || pickOperation.pending, onPending: sync, onError: fail });
261
+ const invalidate = () => { pickOperation.invalidate(); submitOperation.invalidate(); };
262
+ const lifecycle = options.dialog ? installDialogLifecycle(options.dialog, { onOpen: invalidate, onClose: invalidate }) : undefined;
263
+ const update = (next) => {
264
+ if (destroyed)
265
+ return;
266
+ current = { ...next, error: next.error ?? current.error };
267
+ reconcileKeyed(list, rows, next.workspaces, { key: entry => entry.id, element: row => row,
268
+ create(entry) { const row = document.createElement('button'); row.type = 'button'; row.className = 'pui-modal-workspace'; row.dataset.modalWorkspace = entry.id; row.innerHTML = `${icon('folder')}<span><strong></strong><small></small></span>${icon('chevron')}`; return row; },
269
+ update(row, entry) {
270
+ const name = row.querySelector('strong');
271
+ const path = row.querySelector('small');
272
+ if (name.textContent !== entry.name)
273
+ name.textContent = entry.name;
274
+ if (path.textContent !== entry.path)
275
+ path.textContent = entry.path;
276
+ }, destroy() { }, });
277
+ parts.update();
278
+ sync();
279
+ };
280
+ const submit = (path) => {
281
+ if (!options.onSubmit || !path.trim())
282
+ return;
283
+ submitOperation.run(() => { current = { ...current, error: '' }; sync(); return options.onSubmit(path.trim()); }, result => {
284
+ if (options.dialog && !options.dialog.open)
285
+ return;
286
+ if (result.ok) {
287
+ lifecycle?.close();
288
+ options.onSubmitted?.();
289
+ }
290
+ else
291
+ current = { ...current, error: result.error };
292
+ sync();
293
+ });
294
+ };
295
+ if (options.onSubmit)
296
+ life.listen(form, 'submit', (event => { event.preventDefault(); void submit(control.getValue()); }));
297
+ if (options.onPick)
298
+ life.listen(pickButton, 'click', (() => {
299
+ pickOperation.run(() => { current = { ...current, error: '' }; sync(); return options.onPick(); }, result => {
300
+ // End the picker ownership before handing a valid path to submission.
301
+ // A newly disabled target can refuse the write without retaining pending.
302
+ pickOperation.invalidate();
303
+ if (options.dialog && !options.dialog.open)
304
+ return;
305
+ if (result.error) {
306
+ fail(result.error);
307
+ control.focus();
308
+ }
309
+ else if (result.path) {
310
+ control.reset(result.path);
311
+ submit(result.path);
312
+ }
313
+ });
314
+ }));
315
+ life.listen(element, 'click', (event => {
316
+ const target = event.target;
317
+ const selection = target.closest('[data-modal-workspace]');
318
+ if (selection && options.onSelect) {
319
+ event.stopPropagation();
320
+ if (!pickOperation.pending && !submitOperation.pending && !unavailable())
321
+ options.onSelect(selection.dataset.modalWorkspace);
322
+ }
323
+ if (target.closest('[data-close]')) {
324
+ invalidate();
325
+ options.onCancel?.();
326
+ lifecycle?.close();
327
+ }
328
+ }));
329
+ update(initial);
330
+ return { element, input, form, pickButton, update, read: () => ({ path: control.getValue() }), reset(path = '') { if (destroyed)
331
+ return; invalidate(); current = { ...current, error: '' }; control.reset(path); sync(); }, open() { lifecycle?.open(); }, close() { invalidate(); lifecycle?.close(); }, focus: control.focus, destroy() { if (destroyed)
332
+ return; destroyed = true; pickOperation.destroy(); submitOperation.destroy(); life.destroy(); lifecycle?.close(); lifecycle?.destroy(); parts.destroy(); element.remove(); } };
184
333
  }
185
334
  //# sourceMappingURL=navigation.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/navigation/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds} from '../forms/identity.js';\nimport type { UIBlock } from '../core.js';\nimport {dialogHeading, escape, icon, uniqueId} from '../dom.js';\nexport interface NavigationConversation {id: string; title?: string; active: boolean; menuOpen?: boolean; status?: Node | null}\nexport interface NavigationWorkspace {id: string; name: string; path: string; expanded: boolean; selected: boolean; menuOpen?: boolean; children: readonly NavigationConversation[]}\nexport interface WorkspaceNavigationState {groups: readonly NavigationWorkspace[]; empty: 'workspaces' | 'search' | null; disabled?: boolean}\ntype ConversationDOM = {element: HTMLElement; button: HTMLButtonElement; title: HTMLElement; more: HTMLButtonElement; status: Node[]; statusSignature: string; statusSource?: Node | null};\ntype WorkspaceDOM = {element: HTMLElement; heading: HTMLElement; toggle: HTMLButtonElement; title: HTMLElement; more: HTMLButtonElement; create: HTMLButtonElement; children: HTMLElement; empty: HTMLElement};\nexport function createWorkspaceNavigation(initial: WorkspaceNavigationState, options: {element?: HTMLElement; idPrefix?: string; onToggle?: (id: string) => void; onSelect?: (id: string) => void} = {}): UIBlock<WorkspaceNavigationState> {\n const element = options.element || document.createElement('nav');\n if (!options.element) {element.className = 'pui-history-list pui-workspace-navigation'; element.setAttribute('aria-label', 'Workspaces and conversations');}\n const prefix = options.idPrefix ?? uniqueId('pui-nav') + '-';\n const abort = new AbortController(); let destroyed = false;\n const workspaces = new Map<string, WorkspaceDOM>(); const conversations = new Map<string, ConversationDOM>();\n const emptyWorkspace = document.createElement('button'); emptyWorkspace.type = 'button'; emptyWorkspace.className = 'pui-workspace-item pui-empty-workspace'; emptyWorkspace.dataset.action = 'workspace'; emptyWorkspace.innerHTML = `${icon('folder')}<span>Add a workspace</span>`;\n const emptySearch = document.createElement('p'); emptySearch.className = 'pui-history-empty'; emptySearch.textContent = 'No matching conversations.';\n function createWorkspace(): WorkspaceDOM {\n const root = document.createElement('section'); root.className = 'pui-workspace-group';\n root.innerHTML = `<div class=\"pui-workspace-heading\"><button class=\"pui-workspace-toggle\">${icon('chevron', 'pui-workspace-chevron')}${icon('folder')}<span></span></button><button class=\"pui-quiet-icon pui-workspace-more\" aria-haspopup=\"menu\">${icon('more')}</button><button class=\"pui-quiet-icon pui-workspace-new\" title=\"New conversation\">${icon('compose')}</button></div><div class=\"pui-workspace-children\"></div>`;\n const buttons = root.querySelectorAll<HTMLButtonElement>('button'); const empty = document.createElement('p'); empty.className = 'pui-workspace-empty'; empty.textContent = 'No conversations yet';\n return {element:root,heading:root.firstElementChild as HTMLElement,toggle:buttons[0],title:buttons[0].querySelector('span')!,more:buttons[1],create:buttons[2],children:root.lastElementChild as HTMLElement,empty};\n }\n function createConversation(): ConversationDOM {\n const root = document.createElement('div'); root.className = 'pui-history-row';\n root.innerHTML = `<button class=\"pui-history-item\"><span></span></button><button class=\"pui-quiet-icon pui-history-more\" aria-haspopup=\"menu\">${icon('more')}</button>`;\n const buttons = root.querySelectorAll<HTMLButtonElement>('button'); return {element:root,button:buttons[0],title:buttons[0].querySelector('span')!,more:buttons[1],status:[],statusSignature:''};\n }\n function statusSignature(node?: Node | null): string {\n if (!node) return ''; const holder = document.createElement('div'); holder.append(node.cloneNode(true)); return holder.innerHTML;\n }\n const update = (state: Readonly<WorkspaceNavigationState>) => {\n if (destroyed) return; const currentWorkspaces = new Set<string>(); const currentConversations = new Set<string>(); let groupCursor: Element | null = element.firstElementChild;\n for (const workspace of state.groups) {\n currentWorkspaces.add(workspace.id); let group = workspaces.get(workspace.id); if (!group) {group = createWorkspace(); workspaces.set(workspace.id,group);}\n group.element.setAttribute('aria-label',workspace.name); group.heading.classList.toggle('pui-selected',workspace.selected);\n group.toggle.dataset.toggleWorkspace = workspace.id; group.toggle.setAttribute('aria-expanded',String(workspace.expanded)); group.toggle.setAttribute('aria-controls',prefix+'workspace-children-'+workspace.id); group.toggle.title = workspace.path;\n if (group.title.textContent !== workspace.name) group.title.textContent = workspace.name;\n group.more.id = prefix+'workspace-actions-'+workspace.id; group.more.dataset.workspaceMenu = workspace.id; group.more.setAttribute('aria-label','Actions for workspace '+workspace.name); group.more.setAttribute('aria-expanded',String(!!workspace.menuOpen)); group.more.disabled = !!state.disabled;\n group.create.dataset.newWorkspace = workspace.id; group.create.setAttribute('aria-label','New conversation in '+workspace.name); group.create.disabled = !!state.disabled;\n group.children.id = prefix+'workspace-children-'+workspace.id; group.children.hidden = !workspace.expanded; let rowCursor: Element | null = group.children.firstElementChild;\n for (const entry of workspace.children) {\n currentConversations.add(entry.id); let row = conversations.get(entry.id); if (!row) {row = createConversation(); conversations.set(entry.id,row);}\n const title = entry.title || 'Untitled conversation'; row.element.classList.toggle('pui-active',entry.active); row.button.dataset.conversation = entry.id; row.button.title = title; row.button.disabled = !!state.disabled;\n if (entry.active) row.button.setAttribute('aria-current','page'); else row.button.removeAttribute('aria-current'); if (row.title.textContent !== title) row.title.textContent = title;\n row.more.id = prefix+'conversation-actions-'+entry.id; row.more.dataset.conversationMenu = entry.id; row.more.setAttribute('aria-label','Actions for '+title); row.more.setAttribute('aria-expanded',String(!!entry.menuOpen)); row.more.disabled = !!state.disabled;\n const signature = entry.status === row.statusSource && entry.status instanceof DocumentFragment && entry.status.childNodes.length === 0 ? row.statusSignature : statusSignature(entry.status);\n row.statusSource = entry.status;\n if (signature !== row.statusSignature) {for (const node of row.status) node.parentNode?.removeChild(node); row.status = entry.status ? entry.status instanceof DocumentFragment ? [...entry.status.childNodes] : [entry.status] : []; row.button.append(...row.status); row.statusSignature = signature;}\n if (row.element !== rowCursor) group.children.insertBefore(row.element,rowCursor); rowCursor = row.element.nextElementSibling;\n }\n if (!workspace.children.length) {if (group.empty.parentElement !== group.children) group.children.append(group.empty);} else group.empty.remove();\n if (group.element !== groupCursor) element.insertBefore(group.element,groupCursor); groupCursor = group.element.nextElementSibling;\n }\n for (const [id,row] of conversations) if (!currentConversations.has(id)) {row.element.remove(); conversations.delete(id);}\n for (const [id,group] of workspaces) if (!currentWorkspaces.has(id)) {group.element.remove(); workspaces.delete(id);}\n if (state.empty === 'workspaces') {if (emptyWorkspace.parentElement !== element) element.append(emptyWorkspace);} else emptyWorkspace.remove();\n if (state.empty === 'search') {if (emptySearch.parentElement !== element) element.append(emptySearch);} else emptySearch.remove();\n };\n element.addEventListener('click',event => {const target = (event.target as HTMLElement).closest<HTMLButtonElement>('button'); if (target?.disabled) return; if (target?.dataset.toggleWorkspace) options.onToggle?.(target.dataset.toggleWorkspace); if (target?.dataset.conversation) options.onSelect?.(target.dataset.conversation);},{signal:abort.signal});\n update(initial); return {element,update,destroy() {if (destroyed) return; destroyed = true; abort.abort(); workspaces.clear(); conversations.clear(); if (!options.element) element.remove();}};\n}\nexport interface RenameConversationState {id: string; title: string; error?: string; disabled?: boolean}\nexport function createRenameConversation(initial: RenameConversationState, options: {idPrefix?: string} = {}): UIBlock<RenameConversationState> & {readonly input: HTMLInputElement; readonly form: HTMLFormElement} {\n const state = initial; const element = document.createElement('div'); element.className = 'pui-rename-conversation'; element.innerHTML = `${dialogHeading('Rename conversation', 'rename-title', 'rename-dialog', 'CONVERSATION')}<form id=\"rename-form\"><label class=\"pui-field-label\" for=\"conversation-title\">Title</label><input id=\"conversation-title\" name=\"title\" value=\"${escape(state.title)}\" required autocomplete=\"off\" /><div id=\"rename-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-close=\"rename-dialog\">Cancel</button><button type=\"submit\" class=\"pui-primary-button\" data-idle-action data-idle-conversation=\"${escape(state.id)}\">Save title</button></div></form>`;\n const input = element.querySelector<HTMLInputElement>('#conversation-title')!; const form = element.querySelector<HTMLFormElement>('#rename-form')!; const error = element.querySelector<HTMLElement>('#rename-error')!;\n const update = (state: Readonly<RenameConversationState>) => {if (state.error !== undefined) error.textContent = state.error; const button = form.querySelector<HTMLButtonElement>('button[type=\"submit\"]')!; button.disabled = !!state.disabled;}; update(initial); scopeIds(element, options.idPrefix ?? uniqueId('pui-rename') + '-');\n return {element, input, form, update, destroy() {element.remove();}};\n}\nexport interface WorkspacePickerState {workspaces: readonly {id: string; name: string; path: string}[]; error?: string; disabled?: boolean}\nexport function createWorkspacePicker(initial: WorkspacePickerState, options: {idPrefix?: string} = {}): UIBlock<WorkspacePickerState> & {readonly input: HTMLInputElement; readonly form: HTMLFormElement; readonly pickButton: HTMLButtonElement} {\n const state = initial; const element = document.createElement('div'); element.className = 'pui-workspace-picker'; element.innerHTML = `${dialogHeading('Workspaces', 'workspace-title', 'workspace-dialog', 'A PLACE TO WORK')}<p class=\"pui-modal-description\">Choose a local folder. Conversations belong to a workspace, so Pith knows where to read and create files.</p><div class=\"pui-modal-workspaces\">${state.workspaces.map((entry) => `<button class=\"pui-modal-workspace\" data-modal-workspace=\"${escape(entry.id)}\">${icon('folder')}<span><strong>${escape(entry.name)}</strong><small>${escape(entry.path)}</small></span>${icon('chevron')}</button>`).join('')}</div><div class=\"pui-workspace-add\"><button class=\"pui-picker-button\" id=\"pick-folder\" type=\"button\">${icon('folder')}Choose a folder…</button><div class=\"pui-path-divider\"><span>or enter a folder path</span></div><form id=\"workspace-form\"><label class=\"pui-sr-only\" for=\"workspace-path\">Absolute folder path</label><input id=\"workspace-path\" name=\"path\" placeholder=\"/Users/you/Documents/my-work\" required autocomplete=\"off\" spellcheck=\"false\" /><p class=\"pui-field-hint\">Use an existing folder on this computer. Pith will work inside it.</p><div id=\"workspace-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-close=\"workspace-dialog\">Cancel</button><button class=\"pui-primary-button\" id=\"add-workspace\" type=\"submit\">Add workspace</button></div></form></div>`;\n const input = element.querySelector<HTMLInputElement>('#workspace-path')!; const form = element.querySelector<HTMLFormElement>('#workspace-form')!; const pickButton = element.querySelector<HTMLButtonElement>('#pick-folder')!; const error = element.querySelector<HTMLElement>('#workspace-error')!;\n const update = (state: Readonly<WorkspacePickerState>) => {if (state.error !== undefined) error.textContent = state.error; const button = form.querySelector<HTMLButtonElement>('button[type=\"submit\"]')!; button.disabled = !!state.disabled;}; update(initial); scopeIds(element, options.idPrefix ?? uniqueId('pui-workspace') + '-');\n return {element, input, form, pickButton, update, destroy() {element.remove();}};\n}\n"]}
1
+ {"version":3,"file":"navigation.js","sourceRoot":"","sources":["../../src/navigation/navigation.ts"],"names":[],"mappings":"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","sourcesContent":["import {scopeIds} from '../forms/identity.js';\nimport { Lifetime, type ActionResult, type UIBlock } from '../core.js';\nimport {dialogHeading, escape, icon, uniqueId} from '../dom.js';\nimport { adoptProductParts } from '../foundations.js';\nimport { installDialogLifecycle } from '../surface.js';\nimport { createOperation } from '../operation.js';\nimport { reconcileKeyed } from '../reconcile.js';\nexport interface NavigationConversation {id: string; title?: string; active: boolean; menuOpen?: boolean; status?: Node | null}\nexport interface NavigationWorkspace {id: string; name: string; path: string; expanded: boolean; selected: boolean; menuOpen?: boolean; children: readonly NavigationConversation[]}\nexport interface WorkspaceNavigationState {groups: readonly NavigationWorkspace[]; empty: 'workspaces' | 'search' | null; disabled?: boolean}\nexport type WorkspaceNavigationAction =\n | {action: 'add-workspace'; trigger: HTMLButtonElement}\n | {action: 'new-conversation' | 'workspace-menu'; workspaceId: string; trigger: HTMLButtonElement}\n | {action: 'conversation-menu'; conversationId: string; trigger: HTMLButtonElement};\ntype ConversationDOM = {element: HTMLElement; button: HTMLButtonElement; title: HTMLElement; more: HTMLButtonElement; status: Node[]; statusSignature: string; statusSource?: Node | null};\ntype WorkspaceDOM = {element: HTMLElement; heading: HTMLElement; toggle: HTMLButtonElement; title: HTMLElement; more: HTMLButtonElement; create: HTMLButtonElement; children: HTMLElement; empty: HTMLElement};\nexport function createWorkspaceNavigation(initial: WorkspaceNavigationState, options: {element?: HTMLElement; idPrefix?: string; onToggle?: (id: string) => void; onSelect?: (id: string) => void; onAction?: (action: WorkspaceNavigationAction) => void} = {}): UIBlock<WorkspaceNavigationState> {\n const element = options.element || document.createElement('nav');\n if (!options.element) {element.className = 'pui-history-list pui-workspace-navigation'; element.setAttribute('aria-label', 'Workspaces and conversations');}\n const prefix = options.idPrefix ?? uniqueId('pui-nav') + '-';\n const abort = new AbortController(); let destroyed = false;\n const parts = adoptProductParts(element);\n const workspaces = new Map<string, WorkspaceDOM>(); const conversations = new Map<string, ConversationDOM>();\n const emptyWorkspace = document.createElement('button'); emptyWorkspace.type = 'button'; emptyWorkspace.className = 'pui-workspace-item pui-empty-workspace'; emptyWorkspace.dataset.action = 'workspace'; emptyWorkspace.innerHTML = `${icon('folder')}<span>Add a workspace</span>`;\n const emptySearch = document.createElement('p'); emptySearch.className = 'pui-history-empty'; emptySearch.textContent = 'No matching conversations.';\n function createWorkspace(): WorkspaceDOM {\n const root = document.createElement('section'); root.className = 'pui-workspace-group';\n root.innerHTML = `<div class=\"pui-workspace-heading\"><button class=\"pui-workspace-toggle\">${icon('chevron', 'pui-workspace-chevron')}${icon('folder')}<span></span></button><button class=\"pui-quiet-icon pui-workspace-more\" aria-haspopup=\"menu\">${icon('more')}</button><button class=\"pui-quiet-icon pui-workspace-new\" title=\"New conversation\">${icon('compose')}</button></div><div class=\"pui-workspace-children\"></div>`;\n const buttons = root.querySelectorAll<HTMLButtonElement>('button'); const empty = document.createElement('p'); empty.className = 'pui-workspace-empty'; empty.textContent = 'No conversations yet';\n return {element:root,heading:root.firstElementChild as HTMLElement,toggle:buttons[0],title:buttons[0].querySelector('span')!,more:buttons[1],create:buttons[2],children:root.lastElementChild as HTMLElement,empty};\n }\n function createConversation(): ConversationDOM {\n const root = document.createElement('div'); root.className = 'pui-history-row';\n root.innerHTML = `<button class=\"pui-history-item\"><span></span></button><button class=\"pui-quiet-icon pui-history-more\" aria-haspopup=\"menu\">${icon('more')}</button>`;\n const buttons = root.querySelectorAll<HTMLButtonElement>('button'); return {element:root,button:buttons[0],title:buttons[0].querySelector('span')!,more:buttons[1],status:[],statusSignature:''};\n }\n function statusSignature(node?: Node | null): string {\n if (!node) return ''; const holder = document.createElement('div'); holder.append(node.cloneNode(true)); return holder.innerHTML;\n }\n const update = (state: Readonly<WorkspaceNavigationState>) => {\n if (destroyed) return; const currentWorkspaces = new Set<string>(); const currentConversations = new Set<string>(); let groupCursor: Element | null = element.firstElementChild;\n for (const workspace of state.groups) {\n currentWorkspaces.add(workspace.id); let group = workspaces.get(workspace.id); if (!group) {group = createWorkspace(); workspaces.set(workspace.id,group);}\n group.element.setAttribute('aria-label',workspace.name); group.heading.classList.toggle('pui-selected',workspace.selected);\n group.toggle.dataset.toggleWorkspace = workspace.id; group.toggle.setAttribute('aria-expanded',String(workspace.expanded)); group.toggle.setAttribute('aria-controls',prefix+'workspace-children-'+workspace.id); group.toggle.title = workspace.path;\n if (group.title.textContent !== workspace.name) group.title.textContent = workspace.name;\n group.more.id = prefix+'workspace-actions-'+workspace.id; group.more.dataset.workspaceMenu = workspace.id; group.more.setAttribute('aria-label','Actions for workspace '+workspace.name); group.more.setAttribute('aria-expanded',String(!!workspace.menuOpen)); parts.action(group.more).update({disabled: !!state.disabled});\n group.create.dataset.newWorkspace = workspace.id; group.create.setAttribute('aria-label','New conversation in '+workspace.name); parts.action(group.create).update({disabled: !!state.disabled});\n group.children.id = prefix+'workspace-children-'+workspace.id; group.children.hidden = !workspace.expanded; let rowCursor: Element | null = group.children.firstElementChild;\n for (const entry of workspace.children) {\n currentConversations.add(entry.id); let row = conversations.get(entry.id); if (!row) {row = createConversation(); conversations.set(entry.id,row);}\n const title = entry.title || 'Untitled conversation'; row.element.classList.toggle('pui-active',entry.active); row.button.dataset.conversation = entry.id; parts.action(row.button).update({title, disabled: !!state.disabled});\n if (entry.active) row.button.setAttribute('aria-current','page'); else row.button.removeAttribute('aria-current'); if (row.title.textContent !== title) row.title.textContent = title;\n row.more.id = prefix+'conversation-actions-'+entry.id; row.more.dataset.conversationMenu = entry.id; row.more.setAttribute('aria-label','Actions for '+title); row.more.setAttribute('aria-expanded',String(!!entry.menuOpen)); parts.action(row.more).update({disabled: !!state.disabled});\n const signature = entry.status === row.statusSource && entry.status instanceof DocumentFragment && entry.status.childNodes.length === 0 ? row.statusSignature : statusSignature(entry.status);\n row.statusSource = entry.status;\n if (signature !== row.statusSignature) {for (const node of row.status) node.parentNode?.removeChild(node); row.status = entry.status ? entry.status instanceof DocumentFragment ? [...entry.status.childNodes] : [entry.status] : []; row.button.append(...row.status); row.statusSignature = signature;}\n if (row.element !== rowCursor) group.children.insertBefore(row.element,rowCursor); rowCursor = row.element.nextElementSibling;\n }\n if (!workspace.children.length) {if (group.empty.parentElement !== group.children) group.children.append(group.empty);} else group.empty.remove();\n if (group.element !== groupCursor) element.insertBefore(group.element,groupCursor); groupCursor = group.element.nextElementSibling;\n }\n for (const [id,row] of conversations) if (!currentConversations.has(id)) {row.element.remove(); conversations.delete(id);}\n for (const [id,group] of workspaces) if (!currentWorkspaces.has(id)) {group.element.remove(); workspaces.delete(id);}\n if (state.empty === 'workspaces') {if (emptyWorkspace.parentElement !== element) element.append(emptyWorkspace);} else emptyWorkspace.remove();\n parts.action(emptyWorkspace).update({disabled: !!state.disabled});\n if (state.empty === 'search') {if (emptySearch.parentElement !== element) element.append(emptySearch);} else emptySearch.remove();\n parts.update();\n };\n element.addEventListener('click',event => {\n const target = (event.target as Element).closest<HTMLButtonElement>('button'); if (!target || target.disabled) return;\n if (target.dataset.toggleWorkspace && options.onToggle) {event.stopPropagation(); options.onToggle(target.dataset.toggleWorkspace); return;}\n if (target.dataset.conversation && options.onSelect) {event.stopPropagation(); options.onSelect(target.dataset.conversation); return;}\n const action: WorkspaceNavigationAction | undefined = target === emptyWorkspace ? {action:'add-workspace',trigger:target}\n : target.dataset.newWorkspace ? {action:'new-conversation',workspaceId:target.dataset.newWorkspace,trigger:target}\n : target.dataset.workspaceMenu ? {action:'workspace-menu',workspaceId:target.dataset.workspaceMenu,trigger:target}\n : target.dataset.conversationMenu ? {action:'conversation-menu',conversationId:target.dataset.conversationMenu,trigger:target} : undefined;\n if (action && options.onAction) {event.stopPropagation(); options.onAction(action);}\n },{signal:abort.signal});\n update(initial); return {element,update,destroy() {if (destroyed) return; destroyed = true; abort.abort(); parts.destroy(); workspaces.clear(); conversations.clear(); if (!options.element) element.remove();}};\n}\nexport interface RenameConversationState {id: string; title: string; error?: string; disabled?: boolean}\nexport interface RenameConversationDraft {id: string; title: string}\nexport interface RenameConversationOptions {\n idPrefix?: string;\n dialog?: HTMLDialogElement;\n unavailable?: () => boolean;\n onSubmit?: (draft: RenameConversationDraft) => Promise<ActionResult> | ActionResult;\n onSubmitted?: () => void;\n onCancel?: () => void;\n}\nexport interface RenameConversationBlock extends UIBlock<RenameConversationState> {\n readonly input: HTMLInputElement;\n readonly form: HTMLFormElement;\n read(): RenameConversationDraft;\n reset(state: RenameConversationState): void;\n open(state?: RenameConversationState): void;\n close(): void;\n focus(): void;\n}\nexport function createRenameConversation(initial: RenameConversationState, options: RenameConversationOptions = {}): RenameConversationBlock {\n const state = initial; const element = document.createElement('div'); element.className = 'pui-rename-conversation'; element.innerHTML = `${dialogHeading('Rename conversation', 'rename-title', 'rename-dialog', 'CONVERSATION')}<form id=\"rename-form\"><label class=\"pui-field-label\" for=\"conversation-title\">Title</label><input id=\"conversation-title\" name=\"title\" value=\"${escape(state.title)}\" required autocomplete=\"off\" /><div id=\"rename-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button type=\"button\" class=\"pui-secondary-button\" data-close=\"rename-dialog\">Cancel</button><button type=\"submit\" class=\"pui-primary-button\" data-idle-action data-idle-conversation=\"${escape(state.id)}\">Save title</button></div></form>`;\n const input = element.querySelector<HTMLInputElement>('#conversation-title')!; const form = element.querySelector<HTMLFormElement>('#rename-form')!; const error = element.querySelector<HTMLElement>('#rename-error')!;\n scopeIds(element, options.idPrefix ?? uniqueId('pui-rename') + '-');\n const parts = adoptProductParts(element); const control = parts.control(input); const feedback = parts.feedback(error);\n const button = form.querySelector<HTMLButtonElement>('button[type=\"submit\"]')!; const action = parts.action(button);\n const life = new Lifetime();\n let current = initial; let targetId = initial.id; let destroyed = false;\n const sync = () => {action.update({disabled: !!current.disabled || !!options.unavailable?.(), pending:operation.pending}); feedback.update({message: current.error || '', tone: 'error'});};\n const operation = createOperation({unavailable:()=>destroyed || !!current.disabled || !!options.unavailable?.(),onPending:sync,onError(message) {current={...current,error:message};sync();}});\n const lifecycle = options.dialog ? installDialogLifecycle(options.dialog, {onOpen() {operation.invalidate();}, onClose() {operation.invalidate();}}) : undefined;\n const update = (next: Readonly<RenameConversationState>) => {if (destroyed) return; current = {...next, error: next.error ?? current.error}; sync();};\n const reset = (next: RenameConversationState) => {if (destroyed) return; operation.invalidate(); targetId = next.id; current = next; control.reset(next.title); button.dataset.idleConversation = next.id; sync();};\n const close = () => {operation.invalidate(); lifecycle?.close();};\n if (options.onSubmit) life.listen(form, 'submit', (event => {\n event.preventDefault();\n const title = control.getValue().trim();\n if (!title) return;\n operation.run(()=>{current = {...current, error: ''}; sync(); return options.onSubmit!({id: targetId, title});},result=>{\n if (options.dialog && !options.dialog.open) return;\n if (result.ok) {lifecycle?.close(); options.onSubmitted?.();}\n else current = {...current, error: result.error};\n sync();\n });\n }) as EventListener);\n life.listen(element, 'click', (event => {if ((event.target as Element).closest('[data-close]')) {operation.invalidate(); options.onCancel?.(); lifecycle?.close();}}) as EventListener);\n update(initial);\n return {element, input, form, update, read: () => ({id: targetId, title: control.getValue()}), reset, open(next) {if (next) reset(next); lifecycle?.open(); input.select();}, close, focus() {input.select();}, destroy() {if (destroyed) return; destroyed = true; operation.destroy(); life.destroy(); lifecycle?.close(); lifecycle?.destroy(); parts.destroy(); element.remove();}};\n}\nexport interface WorkspacePickerState {workspaces: readonly {id: string; name: string; path: string}[]; error?: string; disabled?: boolean}\nexport interface WorkspacePickerOptions {\n idPrefix?: string;\n dialog?: HTMLDialogElement;\n unavailable?: () => boolean;\n onSubmit?: (path: string) => Promise<ActionResult> | ActionResult;\n onPick?: () => Promise<{path?: string; error?: string}>;\n onSelect?: (id: string) => void;\n onSubmitted?: () => void;\n onCancel?: () => void;\n}\nexport interface WorkspacePickerBlock extends UIBlock<WorkspacePickerState> {\n readonly input: HTMLInputElement;\n readonly form: HTMLFormElement;\n readonly pickButton: HTMLButtonElement;\n read(): {path: string};\n reset(path?: string): void;\n open(): void;\n close(): void;\n focus(): void;\n}\nexport function createWorkspacePicker(initial: WorkspacePickerState, options: WorkspacePickerOptions = {}): WorkspacePickerBlock {\n const state = initial; const element = document.createElement('div'); element.className = 'pui-workspace-picker'; element.innerHTML = `${dialogHeading('Workspaces', 'workspace-title', 'workspace-dialog', 'A PLACE TO WORK')}<p class=\"pui-modal-description\">Choose a local folder. Conversations belong to a workspace, so Pith knows where to read and create files.</p><div class=\"pui-modal-workspaces\">${state.workspaces.map((entry) => `<button class=\"pui-modal-workspace\" data-modal-workspace=\"${escape(entry.id)}\">${icon('folder')}<span><strong>${escape(entry.name)}</strong><small>${escape(entry.path)}</small></span>${icon('chevron')}</button>`).join('')}</div><div class=\"pui-workspace-add\"><button class=\"pui-picker-button\" id=\"pick-folder\" type=\"button\">${icon('folder')}Choose a folder…</button><div class=\"pui-path-divider\"><span>or enter a folder path</span></div><form id=\"workspace-form\"><label class=\"pui-sr-only\" for=\"workspace-path\">Absolute folder path</label><input id=\"workspace-path\" name=\"path\" placeholder=\"/Users/you/Documents/my-work\" required autocomplete=\"off\" spellcheck=\"false\" /><p class=\"pui-field-hint\">Use an existing folder on this computer. Pith will work inside it.</p><div id=\"workspace-error\" class=\"pui-form-error\" role=\"alert\"></div><div class=\"pui-modal-footer\"><button class=\"pui-secondary-button\" type=\"button\" data-close=\"workspace-dialog\">Cancel</button><button class=\"pui-primary-button\" id=\"add-workspace\" type=\"submit\">Add workspace</button></div></form></div>`;\n const input = element.querySelector<HTMLInputElement>('#workspace-path')!; const form = element.querySelector<HTMLFormElement>('#workspace-form')!; const pickButton = element.querySelector<HTMLButtonElement>('#pick-folder')!; const error = element.querySelector<HTMLElement>('#workspace-error')!;\n scopeIds(element, options.idPrefix ?? uniqueId('pui-workspace') + '-');\n const list = element.querySelector<HTMLElement>('.pui-modal-workspaces')!;\n const rows = new Map([...list.querySelectorAll<HTMLButtonElement>('[data-modal-workspace]')].map(row => [row.dataset.modalWorkspace!, row]));\n const parts = adoptProductParts(element); const control = parts.control(input); const feedback = parts.feedback(error);\n const submitButton = form.querySelector<HTMLButtonElement>('button[type=\"submit\"]')!;\n const life = new Lifetime();\n let current = initial; let destroyed = false;\n const unavailable = () => destroyed || !!current.disabled || !!options.unavailable?.();\n const sync = () => {const disabled = unavailable(), pending = pickOperation.pending || submitOperation.pending; parts.action(submitButton).update({disabled, pending}); parts.action(pickButton).update({disabled, pending}); for (const row of rows.values()) parts.action(row).update({disabled: disabled || pending}); feedback.update({message: current.error || '', tone: 'error'});};\n const fail = (message: string) => {current={...current,error:message};sync();};\n const pickOperation = createOperation({unavailable:()=>unavailable() || submitOperation.pending,onPending:sync,onError(message) {fail(`${message} You can enter the path below.`);control.focus();}});\n const submitOperation = createOperation({unavailable:()=>unavailable() || pickOperation.pending,onPending:sync,onError:fail});\n const invalidate = () => {pickOperation.invalidate();submitOperation.invalidate();};\n const lifecycle = options.dialog ? installDialogLifecycle(options.dialog, {onOpen:invalidate,onClose:invalidate}) : undefined;\n const update = (next: Readonly<WorkspacePickerState>) => {\n if (destroyed) return; current = {...next, error: next.error ?? current.error};\n reconcileKeyed(list,rows,next.workspaces,{key:entry=>entry.id,element:row=>row,\n create(entry) {const row=document.createElement('button'); row.type = 'button'; row.className = 'pui-modal-workspace'; row.dataset.modalWorkspace = entry.id; row.innerHTML = `${icon('folder')}<span><strong></strong><small></small></span>${icon('chevron')}`;return row;},\n update(row,entry) {\n const name = row.querySelector('strong')!; const path = row.querySelector('small')!;\n if (name.textContent !== entry.name) name.textContent = entry.name;\n if (path.textContent !== entry.path) path.textContent = entry.path;\n },destroy() {},\n });\n parts.update(); sync();\n };\n const submit = (path: string): void => {\n if (!options.onSubmit || !path.trim()) return;\n submitOperation.run(()=>{current = {...current, error: ''}; sync(); return options.onSubmit!(path.trim());},result=>{\n if (options.dialog && !options.dialog.open) return;\n if (result.ok) {lifecycle?.close(); options.onSubmitted?.();}\n else current = {...current, error: result.error};\n sync();\n });\n };\n if (options.onSubmit) life.listen(form, 'submit', (event => {event.preventDefault(); void submit(control.getValue());}) as EventListener);\n if (options.onPick) life.listen(pickButton, 'click', (() => {\n pickOperation.run(()=>{current = {...current, error: ''}; sync(); return options.onPick!();},result=>{\n // End the picker ownership before handing a valid path to submission.\n // A newly disabled target can refuse the write without retaining pending.\n pickOperation.invalidate();\n if (options.dialog && !options.dialog.open) return;\n if (result.error) {fail(result.error);control.focus();}\n else if (result.path) {control.reset(result.path);submit(result.path);}\n });\n }) as EventListener);\n life.listen(element, 'click', (event => {\n const target = event.target as Element;\n const selection = target.closest<HTMLButtonElement>('[data-modal-workspace]');\n if (selection && options.onSelect) {event.stopPropagation(); if (!pickOperation.pending && !submitOperation.pending && !unavailable()) options.onSelect(selection.dataset.modalWorkspace!);}\n if (target.closest('[data-close]')) {invalidate(); options.onCancel?.(); lifecycle?.close();}\n }) as EventListener);\n update(initial);\n return {element, input, form, pickButton, update, read: () => ({path: control.getValue()}), reset(path = '') {if (destroyed) return; invalidate(); current = {...current, error: ''}; control.reset(path); sync();}, open() {lifecycle?.open();}, close() {invalidate(); lifecycle?.close();}, focus: control.focus, destroy() {if (destroyed) return; destroyed = true; pickOperation.destroy(); submitOperation.destroy(); life.destroy(); lifecycle?.close(); lifecycle?.destroy(); parts.destroy(); element.remove();}};\n}\n"]}
@@ -0,0 +1,12 @@
1
+ /** One owned operation. Invalidating UI never retries or cancels a business write. */
2
+ export declare function createOperation(options?: {
3
+ unavailable?: () => boolean;
4
+ onPending?: (pending: boolean) => void;
5
+ onError?: (message: string) => void;
6
+ }): {
7
+ readonly pending: boolean;
8
+ run<Value>(task: () => Value | PromiseLike<Value>, onResult?: (value: Value) => void): boolean;
9
+ invalidate(): void;
10
+ destroy(): void;
11
+ };
12
+ //# sourceMappingURL=operation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"operation.d.ts","sourceRoot":"","sources":["../src/operation.ts"],"names":[],"mappings":"AAEA,sFAAsF;AACtF,wBAAgB,eAAe,CAAC,OAAO,GAAE;IACvC,WAAW,CAAC,EAAE,MAAM,OAAO,CAAC;IAC5B,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACvC,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAChC;sBAKa,OAAO;QAClB,KAAK,QAAQ,MAAM,KAAK,GAAG,WAAW,CAAC,KAAK,CAAC,aAAa,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,GAAG,OAAO;kBAchF,IAAI;eACP,IAAI;EAElB"}