@salmexio/ui 0.4.0 → 1.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +52 -3
- package/dist/dialogs/ContextMenu/ContextMenu.svelte +97 -94
- package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts +3 -2
- package/dist/dialogs/ContextMenu/ContextMenu.svelte.d.ts.map +1 -1
- package/dist/dialogs/Modal/Modal.svelte +112 -116
- package/dist/dialogs/Modal/Modal.svelte.d.ts +1 -1
- package/dist/feedback/Alert/Alert.svelte +119 -220
- package/dist/feedback/Alert/Alert.svelte.d.ts +1 -1
- package/dist/feedback/ProgressBar/ProgressBar.svelte +265 -0
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts +40 -0
- package/dist/feedback/ProgressBar/ProgressBar.svelte.d.ts.map +1 -0
- package/dist/feedback/ProgressBar/index.d.ts +2 -0
- package/dist/feedback/ProgressBar/index.d.ts.map +1 -0
- package/dist/feedback/ProgressBar/index.js +1 -0
- package/dist/feedback/Skeleton/Skeleton.svelte +157 -0
- package/dist/feedback/Skeleton/Skeleton.svelte.d.ts +37 -0
- package/dist/feedback/Skeleton/Skeleton.svelte.d.ts.map +1 -0
- package/dist/feedback/Skeleton/index.d.ts +2 -0
- package/dist/feedback/Skeleton/index.d.ts.map +1 -0
- package/dist/feedback/Skeleton/index.js +1 -0
- package/dist/feedback/Spinner/Spinner.svelte +86 -151
- package/dist/feedback/Spinner/Spinner.svelte.d.ts +5 -3
- package/dist/feedback/Spinner/Spinner.svelte.d.ts.map +1 -1
- package/dist/feedback/Toast/Toaster.svelte +431 -0
- package/dist/feedback/Toast/Toaster.svelte.d.ts +22 -0
- package/dist/feedback/Toast/Toaster.svelte.d.ts.map +1 -0
- package/dist/feedback/Toast/index.d.ts +4 -0
- package/dist/feedback/Toast/index.d.ts.map +1 -0
- package/dist/feedback/Toast/index.js +2 -0
- package/dist/feedback/Toast/toastStore.d.ts +34 -0
- package/dist/feedback/Toast/toastStore.d.ts.map +1 -0
- package/dist/feedback/Toast/toastStore.js +43 -0
- package/dist/feedback/index.d.ts +4 -0
- package/dist/feedback/index.d.ts.map +1 -1
- package/dist/feedback/index.js +3 -0
- package/dist/forms/Checkbox/Checkbox.svelte +87 -104
- package/dist/forms/Checkbox/Checkbox.svelte.d.ts +1 -1
- package/dist/forms/Select/Select.svelte +137 -179
- package/dist/forms/Select/Select.svelte.d.ts +1 -1
- package/dist/forms/Slider/Slider.svelte +356 -0
- package/dist/forms/Slider/Slider.svelte.d.ts +50 -0
- package/dist/forms/Slider/Slider.svelte.d.ts.map +1 -0
- package/dist/forms/Slider/index.d.ts +2 -0
- package/dist/forms/Slider/index.d.ts.map +1 -0
- package/dist/forms/Slider/index.js +1 -0
- package/dist/forms/TextInput/TextInput.svelte +161 -167
- package/dist/forms/TextInput/TextInput.svelte.d.ts +1 -1
- package/dist/forms/Textarea/Textarea.svelte +615 -0
- package/dist/forms/Textarea/Textarea.svelte.d.ts +47 -0
- package/dist/forms/Textarea/Textarea.svelte.d.ts.map +1 -0
- package/dist/forms/Textarea/index.d.ts +2 -0
- package/dist/forms/Textarea/index.d.ts.map +1 -0
- package/dist/forms/Textarea/index.js +1 -0
- package/dist/forms/Toggle/Toggle.svelte +239 -0
- package/dist/forms/Toggle/Toggle.svelte.d.ts +39 -0
- package/dist/forms/Toggle/Toggle.svelte.d.ts.map +1 -0
- package/dist/forms/Toggle/index.d.ts +2 -0
- package/dist/forms/Toggle/index.d.ts.map +1 -0
- package/dist/forms/Toggle/index.js +1 -0
- package/dist/forms/index.d.ts +3 -0
- package/dist/forms/index.d.ts.map +1 -1
- package/dist/forms/index.js +3 -0
- package/dist/index.d.ts +0 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +0 -1
- package/dist/layout/Card/Card.svelte +66 -39
- package/dist/layout/Card/Card.svelte.d.ts +1 -1
- package/dist/layout/Card/Card.svelte.d.ts.map +1 -1
- package/dist/layout/Container/Container.svelte +71 -71
- package/dist/layout/Container/Container.svelte.d.ts +2 -2
- package/dist/layout/ThermalBackground/ThermalBackground.svelte +313 -0
- package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts +16 -0
- package/dist/layout/ThermalBackground/ThermalBackground.svelte.d.ts.map +1 -0
- package/dist/layout/ThermalBackground/index.d.ts +2 -0
- package/dist/layout/ThermalBackground/index.d.ts.map +1 -0
- package/dist/layout/ThermalBackground/index.js +1 -0
- package/dist/layout/index.d.ts +1 -0
- package/dist/layout/index.d.ts.map +1 -1
- package/dist/layout/index.js +1 -0
- package/dist/navigation/CommandPalette/CommandPalette.svelte +407 -189
- package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts +8 -3
- package/dist/navigation/CommandPalette/CommandPalette.svelte.d.ts.map +1 -1
- package/dist/navigation/Tabs/Tabs.svelte +139 -192
- package/dist/navigation/Tabs/Tabs.svelte.d.ts +2 -2
- package/dist/primitives/Badge/Badge.svelte +85 -220
- package/dist/primitives/Badge/Badge.svelte.d.ts +2 -2
- package/dist/primitives/Badge/Badge.svelte.d.ts.map +1 -1
- package/dist/primitives/Button/Button.svelte +214 -194
- package/dist/primitives/Button/Button.svelte.d.ts +3 -3
- package/dist/primitives/Button/Button.svelte.d.ts.map +1 -1
- package/dist/primitives/Tooltip/Tooltip.svelte +260 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts +36 -0
- package/dist/primitives/Tooltip/Tooltip.svelte.d.ts.map +1 -0
- package/dist/primitives/Tooltip/index.d.ts +2 -0
- package/dist/primitives/Tooltip/index.d.ts.map +1 -0
- package/dist/primitives/Tooltip/index.js +1 -0
- package/dist/primitives/index.d.ts +1 -0
- package/dist/primitives/index.d.ts.map +1 -1
- package/dist/primitives/index.js +1 -0
- package/dist/styles/tokens.css +329 -260
- package/package.json +5 -5
- package/dist/windowing/Window/Window.svelte +0 -637
- package/dist/windowing/Window/Window.svelte.d.ts +0 -65
- package/dist/windowing/Window/Window.svelte.d.ts.map +0 -1
- package/dist/windowing/Window/index.d.ts +0 -2
- package/dist/windowing/Window/index.d.ts.map +0 -1
- package/dist/windowing/Window/index.js +0 -1
- package/dist/windowing/WindowManager/WindowManager.svelte +0 -425
- package/dist/windowing/WindowManager/WindowManager.svelte.d.ts +0 -38
- package/dist/windowing/WindowManager/WindowManager.svelte.d.ts.map +0 -1
- package/dist/windowing/WindowManager/index.d.ts +0 -2
- package/dist/windowing/WindowManager/index.d.ts.map +0 -1
- package/dist/windowing/WindowManager/index.js +0 -1
- package/dist/windowing/index.d.ts +0 -5
- package/dist/windowing/index.d.ts.map +0 -1
- package/dist/windowing/index.js +0 -3
- package/dist/windowing/windowStore.svelte.d.ts +0 -49
- package/dist/windowing/windowStore.svelte.d.ts.map +0 -1
- package/dist/windowing/windowStore.svelte.js +0 -170
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
type WindowSize = 'sm' | 'md' | 'lg' | 'xl';
|
|
3
|
-
interface Props {
|
|
4
|
-
/** Unique window identifier. Auto-generated if omitted. */
|
|
5
|
-
id?: string;
|
|
6
|
-
/** Title displayed in the title bar. */
|
|
7
|
-
title?: string;
|
|
8
|
-
/** Initial width in pixels. */
|
|
9
|
-
width?: number;
|
|
10
|
-
/** Initial height in pixels. */
|
|
11
|
-
height?: number;
|
|
12
|
-
/** Initial X position (px from container left). */
|
|
13
|
-
x?: number;
|
|
14
|
-
/** Initial Y position (px from container top). */
|
|
15
|
-
y?: number;
|
|
16
|
-
/** Preset size (overrides width/height). */
|
|
17
|
-
size?: WindowSize;
|
|
18
|
-
/** Show minimize button. */
|
|
19
|
-
minimizable?: boolean;
|
|
20
|
-
/** Show maximize button. */
|
|
21
|
-
maximizable?: boolean;
|
|
22
|
-
/** Show close button. */
|
|
23
|
-
closable?: boolean;
|
|
24
|
-
/** Prevent the window from being dragged. */
|
|
25
|
-
disableDrag?: boolean;
|
|
26
|
-
/** Icon snippet rendered before the title. */
|
|
27
|
-
icon?: Snippet;
|
|
28
|
-
/** Custom title bar content (overrides title text). */
|
|
29
|
-
titleBar?: Snippet;
|
|
30
|
-
/** Status bar at bottom of window. */
|
|
31
|
-
statusBar?: Snippet;
|
|
32
|
-
/** Main body content. */
|
|
33
|
-
children?: Snippet;
|
|
34
|
-
/** Called when close button is clicked. */
|
|
35
|
-
onclose?: () => void;
|
|
36
|
-
/** Called when minimize button is clicked. */
|
|
37
|
-
onminimize?: () => void;
|
|
38
|
-
/** Called when maximize/restore button is clicked. */
|
|
39
|
-
onmaximize?: () => void;
|
|
40
|
-
/** Called when window gains focus. */
|
|
41
|
-
onfocus?: () => void;
|
|
42
|
-
/** Additional CSS class. */
|
|
43
|
-
class?: string;
|
|
44
|
-
/** Test ID for automated testing. */
|
|
45
|
-
testId?: string;
|
|
46
|
-
}
|
|
47
|
-
/**
|
|
48
|
-
* Window
|
|
49
|
-
*
|
|
50
|
-
* Win2K x Basquiat -- Draggable window with title bar chrome, minimize/maximize/close
|
|
51
|
-
* controls, 3D beveled borders, and flat shadow. Lives inside a WindowManager container.
|
|
52
|
-
* Non-modal dialog (role="dialog") -- windows do not trap focus.
|
|
53
|
-
* Title bar supports pointer-based dragging with container boundary clamping.
|
|
54
|
-
*
|
|
55
|
-
* @example
|
|
56
|
-
* <WindowManager>
|
|
57
|
-
* <Window id="notes" title="Notes">
|
|
58
|
-
* <p>Window body content.</p>
|
|
59
|
-
* </Window>
|
|
60
|
-
* </WindowManager>
|
|
61
|
-
*/
|
|
62
|
-
declare const Window: import("svelte").Component<Props, {}, "">;
|
|
63
|
-
type Window = ReturnType<typeof Window>;
|
|
64
|
-
export default Window;
|
|
65
|
-
//# sourceMappingURL=Window.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Window.svelte.d.ts","sourceRoot":"","sources":["../../../src/windowing/Window/Window.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,KAAK,UAAU,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,GAAG,IAAI,CAAC;AAE5C,UAAU,KAAK;IACd,2DAA2D;IAC3D,EAAE,CAAC,EAAE,MAAM,CAAC;IACZ,wCAAwC;IACxC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,+BAA+B;IAC/B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,gCAAgC;IAChC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,kDAAkD;IAClD,CAAC,CAAC,EAAE,MAAM,CAAC;IACX,4CAA4C;IAC5C,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,4BAA4B;IAC5B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,6CAA6C;IAC7C,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,sCAAsC;IACtC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,yBAAyB;IACzB,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,2CAA2C;IAC3C,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,8CAA8C;IAC9C,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,sDAAsD;IACtD,UAAU,CAAC,EAAE,MAAM,IAAI,CAAC;IACxB,sCAAsC;IACtC,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AA8OD;;;;;;;;;;;;;;GAcG;AACH,QAAA,MAAM,MAAM,2CAAwC,CAAC;AACrD,KAAK,MAAM,GAAG,UAAU,CAAC,OAAO,MAAM,CAAC,CAAC;AACxC,eAAe,MAAM,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/windowing/Window/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,MAAM,EAAE,MAAM,iBAAiB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as Window } from './Window.svelte';
|
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
<!--
|
|
2
|
-
@component WindowManager
|
|
3
|
-
|
|
4
|
-
Win2K x Basquiat -- Desktop-style container that manages Window components.
|
|
5
|
-
Provides a bounded area for windows to live in, with a taskbar at the bottom
|
|
6
|
-
showing all open windows (including minimized). Click-to-focus z-index stacking.
|
|
7
|
-
Keyboard: F6 cycles windows, Alt+Arrow Up maximizes, Alt+Arrow Down minimizes.
|
|
8
|
-
|
|
9
|
-
@example
|
|
10
|
-
<WindowManager height="500px">
|
|
11
|
-
<Window id="notes" title="Notes"><p>Content</p></Window>
|
|
12
|
-
<Window id="settings" title="Settings"><p>Content</p></Window>
|
|
13
|
-
</WindowManager>
|
|
14
|
-
-->
|
|
15
|
-
<script lang="ts">
|
|
16
|
-
import type { Snippet } from 'svelte';
|
|
17
|
-
import { setContext } from 'svelte';
|
|
18
|
-
import { cn } from '../../utils/cn.js';
|
|
19
|
-
import { generateId, Keys } from '../../utils/keyboard.js';
|
|
20
|
-
import { createWindowManager } from '../windowStore.svelte.js';
|
|
21
|
-
|
|
22
|
-
type TaskbarPosition = 'bottom' | 'top';
|
|
23
|
-
|
|
24
|
-
interface Props {
|
|
25
|
-
/** Height of the window manager area. */
|
|
26
|
-
height?: string;
|
|
27
|
-
/** Show the taskbar. */
|
|
28
|
-
showTaskbar?: boolean;
|
|
29
|
-
/** Taskbar position. */
|
|
30
|
-
taskbarPosition?: TaskbarPosition;
|
|
31
|
-
/** Show a desktop background pattern. */
|
|
32
|
-
showDesktopPattern?: boolean;
|
|
33
|
-
/** Desktop label in corner. */
|
|
34
|
-
desktopLabel?: string;
|
|
35
|
-
/** Window children (Window components). */
|
|
36
|
-
children?: Snippet;
|
|
37
|
-
/** Additional CSS class. */
|
|
38
|
-
class?: string;
|
|
39
|
-
/** Test ID for automated testing. */
|
|
40
|
-
testId?: string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
let {
|
|
44
|
-
height = '500px',
|
|
45
|
-
showTaskbar = true,
|
|
46
|
-
taskbarPosition = 'bottom',
|
|
47
|
-
showDesktopPattern = true,
|
|
48
|
-
desktopLabel = '',
|
|
49
|
-
children,
|
|
50
|
-
class: className = '',
|
|
51
|
-
testId
|
|
52
|
-
}: Props = $props();
|
|
53
|
-
|
|
54
|
-
const managerId = generateId('wm');
|
|
55
|
-
const manager = createWindowManager();
|
|
56
|
-
|
|
57
|
-
// Provide manager to child Window components
|
|
58
|
-
setContext('salmex-window-manager', manager);
|
|
59
|
-
|
|
60
|
-
let containerEl = $state<HTMLDivElement | null>(null);
|
|
61
|
-
|
|
62
|
-
function handleKeyDown(e: KeyboardEvent) {
|
|
63
|
-
// F6 / Shift+F6: cycle between windows
|
|
64
|
-
if (e.key === 'F6') {
|
|
65
|
-
e.preventDefault();
|
|
66
|
-
if (e.shiftKey) {
|
|
67
|
-
manager.focusPrevious();
|
|
68
|
-
} else {
|
|
69
|
-
manager.focusNext();
|
|
70
|
-
}
|
|
71
|
-
// Focus the window element
|
|
72
|
-
const focused = manager.getFocusedWindow();
|
|
73
|
-
if (focused && containerEl) {
|
|
74
|
-
const el = containerEl.querySelector<HTMLElement>(`[data-window-id="${focused.id}"]`);
|
|
75
|
-
el?.focus();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
const focusedWin = manager.getFocusedWindow();
|
|
80
|
-
if (!focusedWin) return;
|
|
81
|
-
|
|
82
|
-
// Alt+ArrowDown: minimize
|
|
83
|
-
if (e.altKey && e.key === Keys.ArrowDown) {
|
|
84
|
-
e.preventDefault();
|
|
85
|
-
manager.minimize(focusedWin.id);
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Alt+ArrowUp: maximize / restore
|
|
89
|
-
if (e.altKey && e.key === Keys.ArrowUp) {
|
|
90
|
-
e.preventDefault();
|
|
91
|
-
if (focusedWin.maximized) {
|
|
92
|
-
manager.restore(focusedWin.id);
|
|
93
|
-
} else if (containerEl) {
|
|
94
|
-
const rect = containerEl.getBoundingClientRect();
|
|
95
|
-
const taskbarH = showTaskbar ? 36 : 0;
|
|
96
|
-
manager.maximize(focusedWin.id, rect.width, rect.height - taskbarH);
|
|
97
|
-
}
|
|
98
|
-
}
|
|
99
|
-
}
|
|
100
|
-
|
|
101
|
-
function handleTaskbarClick(windowId: string) {
|
|
102
|
-
manager.toggleMinimize(windowId);
|
|
103
|
-
// Focus the window element if restored
|
|
104
|
-
const win = manager.getWindow(windowId);
|
|
105
|
-
if (win && !win.minimized && containerEl) {
|
|
106
|
-
setTimeout(() => {
|
|
107
|
-
const el = containerEl?.querySelector<HTMLElement>(`[data-window-id="${windowId}"]`);
|
|
108
|
-
el?.focus();
|
|
109
|
-
}, 0);
|
|
110
|
-
}
|
|
111
|
-
}
|
|
112
|
-
</script>
|
|
113
|
-
|
|
114
|
-
<!-- svelte-ignore a11y_no_noninteractive_element_interactions -->
|
|
115
|
-
<div
|
|
116
|
-
bind:this={containerEl}
|
|
117
|
-
id={managerId}
|
|
118
|
-
class={cn(
|
|
119
|
-
'salmex-wm',
|
|
120
|
-
showDesktopPattern && 'salmex-wm-pattern',
|
|
121
|
-
taskbarPosition === 'top' && 'salmex-wm-taskbar-top',
|
|
122
|
-
className
|
|
123
|
-
)}
|
|
124
|
-
style="height: {height};"
|
|
125
|
-
role="region"
|
|
126
|
-
aria-label="Window manager"
|
|
127
|
-
data-testid={testId}
|
|
128
|
-
onkeydown={handleKeyDown}
|
|
129
|
-
>
|
|
130
|
-
<!-- Window area -->
|
|
131
|
-
<div class="salmex-wm-desktop">
|
|
132
|
-
{#if desktopLabel}
|
|
133
|
-
<span class="salmex-wm-desktop-label" aria-hidden="true">{desktopLabel}</span>
|
|
134
|
-
{/if}
|
|
135
|
-
{#if children}
|
|
136
|
-
{@render children()}
|
|
137
|
-
{/if}
|
|
138
|
-
</div>
|
|
139
|
-
|
|
140
|
-
<!-- Taskbar -->
|
|
141
|
-
{#if showTaskbar}
|
|
142
|
-
<div class="salmex-wm-taskbar" role="toolbar" aria-label="Window taskbar">
|
|
143
|
-
<div class="salmex-wm-taskbar-start">
|
|
144
|
-
<span class="salmex-wm-start-label" aria-hidden="true">Salmex</span>
|
|
145
|
-
</div>
|
|
146
|
-
<div class="salmex-wm-taskbar-items">
|
|
147
|
-
{#each manager.windows as win (win.id)}
|
|
148
|
-
<button
|
|
149
|
-
type="button"
|
|
150
|
-
class={cn(
|
|
151
|
-
'salmex-wm-taskbar-btn',
|
|
152
|
-
win.focused && !win.minimized && 'salmex-wm-taskbar-btn-active',
|
|
153
|
-
win.minimized && 'salmex-wm-taskbar-btn-minimized'
|
|
154
|
-
)}
|
|
155
|
-
onclick={() => handleTaskbarClick(win.id)}
|
|
156
|
-
aria-pressed={win.focused && !win.minimized}
|
|
157
|
-
title={win.title}
|
|
158
|
-
>
|
|
159
|
-
<span class="salmex-wm-taskbar-btn-text">{win.title}</span>
|
|
160
|
-
</button>
|
|
161
|
-
{/each}
|
|
162
|
-
</div>
|
|
163
|
-
<div class="salmex-wm-taskbar-tray" aria-hidden="true">
|
|
164
|
-
<span class="salmex-wm-clock">{new Date().toLocaleTimeString([], { hour: '2-digit', minute: '2-digit' })}</span>
|
|
165
|
-
</div>
|
|
166
|
-
</div>
|
|
167
|
-
{/if}
|
|
168
|
-
</div>
|
|
169
|
-
|
|
170
|
-
<style>
|
|
171
|
-
/* ========================================
|
|
172
|
-
WINDOW MANAGER CONTAINER
|
|
173
|
-
======================================== */
|
|
174
|
-
|
|
175
|
-
.salmex-wm {
|
|
176
|
-
position: relative;
|
|
177
|
-
display: flex;
|
|
178
|
-
flex-direction: column;
|
|
179
|
-
border: 2px solid rgb(var(--salmex-button-dark-edge));
|
|
180
|
-
border-radius: var(--salmex-radius-md);
|
|
181
|
-
overflow: hidden;
|
|
182
|
-
background: rgb(var(--salmex-bg-tertiary));
|
|
183
|
-
box-shadow:
|
|
184
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
185
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
|
|
186
|
-
var(--salmex-shadow-lg);
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
.salmex-wm-taskbar-top {
|
|
190
|
-
flex-direction: column-reverse;
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/* Desktop background pattern -- Win2K teal with Basquiat texture */
|
|
194
|
-
.salmex-wm-pattern {
|
|
195
|
-
background:
|
|
196
|
-
/* Subtle cross-hatch */
|
|
197
|
-
repeating-linear-gradient(
|
|
198
|
-
45deg,
|
|
199
|
-
transparent,
|
|
200
|
-
transparent 8px,
|
|
201
|
-
rgb(0 0 0 / 0.03) 8px,
|
|
202
|
-
rgb(0 0 0 / 0.03) 9px
|
|
203
|
-
),
|
|
204
|
-
repeating-linear-gradient(
|
|
205
|
-
-45deg,
|
|
206
|
-
transparent,
|
|
207
|
-
transparent 8px,
|
|
208
|
-
rgb(0 0 0 / 0.03) 8px,
|
|
209
|
-
rgb(0 0 0 / 0.03) 9px
|
|
210
|
-
),
|
|
211
|
-
/* Win2K teal base with Basquiat flair */
|
|
212
|
-
linear-gradient(
|
|
213
|
-
135deg,
|
|
214
|
-
rgb(58 110 165),
|
|
215
|
-
rgb(40 90 140)
|
|
216
|
-
);
|
|
217
|
-
}
|
|
218
|
-
|
|
219
|
-
:global([data-theme='dark']) .salmex-wm-pattern {
|
|
220
|
-
background:
|
|
221
|
-
repeating-linear-gradient(
|
|
222
|
-
45deg,
|
|
223
|
-
transparent,
|
|
224
|
-
transparent 8px,
|
|
225
|
-
rgb(255 255 255 / 0.02) 8px,
|
|
226
|
-
rgb(255 255 255 / 0.02) 9px
|
|
227
|
-
),
|
|
228
|
-
repeating-linear-gradient(
|
|
229
|
-
-45deg,
|
|
230
|
-
transparent,
|
|
231
|
-
transparent 8px,
|
|
232
|
-
rgb(255 255 255 / 0.02) 8px,
|
|
233
|
-
rgb(255 255 255 / 0.02) 9px
|
|
234
|
-
),
|
|
235
|
-
linear-gradient(
|
|
236
|
-
135deg,
|
|
237
|
-
rgb(15 15 20),
|
|
238
|
-
rgb(20 18 28)
|
|
239
|
-
);
|
|
240
|
-
}
|
|
241
|
-
|
|
242
|
-
:global([data-theme='dark']) .salmex-wm {
|
|
243
|
-
box-shadow:
|
|
244
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
245
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
|
|
246
|
-
4px 4px 3px rgb(0 0 0 / 0.5);
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
/* ========================================
|
|
250
|
-
DESKTOP AREA
|
|
251
|
-
======================================== */
|
|
252
|
-
|
|
253
|
-
.salmex-wm-desktop {
|
|
254
|
-
position: relative;
|
|
255
|
-
flex: 1;
|
|
256
|
-
overflow: hidden;
|
|
257
|
-
}
|
|
258
|
-
|
|
259
|
-
.salmex-wm-desktop-label {
|
|
260
|
-
position: absolute;
|
|
261
|
-
bottom: var(--salmex-space-3);
|
|
262
|
-
right: var(--salmex-space-4);
|
|
263
|
-
font-family: var(--salmex-font-handwrite);
|
|
264
|
-
font-size: var(--salmex-font-size-lg);
|
|
265
|
-
color: rgb(255 255 255 / 0.25);
|
|
266
|
-
pointer-events: none;
|
|
267
|
-
user-select: none;
|
|
268
|
-
}
|
|
269
|
-
|
|
270
|
-
:global([data-theme='dark']) .salmex-wm-desktop-label {
|
|
271
|
-
color: rgb(255 255 255 / 0.1);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
/* ========================================
|
|
275
|
-
TASKBAR
|
|
276
|
-
======================================== */
|
|
277
|
-
|
|
278
|
-
.salmex-wm-taskbar {
|
|
279
|
-
display: flex;
|
|
280
|
-
align-items: center;
|
|
281
|
-
gap: 2px;
|
|
282
|
-
padding: 2px var(--salmex-space-1);
|
|
283
|
-
background: rgb(var(--salmex-window-surface));
|
|
284
|
-
border-top: 1px solid rgb(var(--salmex-button-highlight));
|
|
285
|
-
border-radius: 0 0 calc(var(--salmex-radius-md) - 2px) calc(var(--salmex-radius-md) - 2px);
|
|
286
|
-
min-height: 36px;
|
|
287
|
-
flex-shrink: 0;
|
|
288
|
-
/* 3D raised taskbar */
|
|
289
|
-
box-shadow:
|
|
290
|
-
inset 0 1px 0 rgb(var(--salmex-button-highlight)),
|
|
291
|
-
inset 0 -1px 0 rgb(var(--salmex-button-shadow));
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
.salmex-wm-taskbar-top .salmex-wm-taskbar {
|
|
295
|
-
border-top: none;
|
|
296
|
-
border-bottom: 1px solid rgb(var(--salmex-button-shadow));
|
|
297
|
-
border-radius: calc(var(--salmex-radius-md) - 2px) calc(var(--salmex-radius-md) - 2px) 0 0;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
/* Start button */
|
|
301
|
-
.salmex-wm-taskbar-start {
|
|
302
|
-
display: flex;
|
|
303
|
-
align-items: center;
|
|
304
|
-
padding: 0 var(--salmex-space-2);
|
|
305
|
-
border-right: 1px solid rgb(var(--salmex-button-shadow));
|
|
306
|
-
margin-right: var(--salmex-space-1);
|
|
307
|
-
}
|
|
308
|
-
|
|
309
|
-
.salmex-wm-start-label {
|
|
310
|
-
font-family: var(--salmex-font-display);
|
|
311
|
-
font-size: var(--salmex-font-size-xs);
|
|
312
|
-
font-weight: 900;
|
|
313
|
-
text-transform: uppercase;
|
|
314
|
-
letter-spacing: 0.5px;
|
|
315
|
-
color: rgb(var(--salmex-text-primary));
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
/* Taskbar items area */
|
|
319
|
-
.salmex-wm-taskbar-items {
|
|
320
|
-
display: flex;
|
|
321
|
-
flex: 1;
|
|
322
|
-
gap: 2px;
|
|
323
|
-
overflow-x: auto;
|
|
324
|
-
min-width: 0;
|
|
325
|
-
}
|
|
326
|
-
|
|
327
|
-
/* Taskbar button */
|
|
328
|
-
.salmex-wm-taskbar-btn {
|
|
329
|
-
display: flex;
|
|
330
|
-
align-items: center;
|
|
331
|
-
gap: var(--salmex-space-1);
|
|
332
|
-
padding: 2px var(--salmex-space-3);
|
|
333
|
-
min-width: 0;
|
|
334
|
-
max-width: 160px;
|
|
335
|
-
background: rgb(var(--salmex-button-face));
|
|
336
|
-
border: 1px solid rgb(var(--salmex-button-dark-edge));
|
|
337
|
-
border-radius: var(--salmex-radius-sm);
|
|
338
|
-
cursor: pointer;
|
|
339
|
-
font-family: var(--salmex-font-system);
|
|
340
|
-
font-size: var(--salmex-font-size-xs);
|
|
341
|
-
font-weight: 600;
|
|
342
|
-
color: rgb(var(--salmex-text-primary));
|
|
343
|
-
text-align: left;
|
|
344
|
-
/* Raised 3D */
|
|
345
|
-
box-shadow:
|
|
346
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
347
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow));
|
|
348
|
-
transition: all var(--salmex-transition-fast);
|
|
349
|
-
white-space: nowrap;
|
|
350
|
-
overflow: hidden;
|
|
351
|
-
height: 24px;
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
.salmex-wm-taskbar-btn:hover {
|
|
355
|
-
background: rgb(var(--salmex-button-light));
|
|
356
|
-
}
|
|
357
|
-
|
|
358
|
-
/* Active (focused) — pressed in */
|
|
359
|
-
.salmex-wm-taskbar-btn-active {
|
|
360
|
-
box-shadow:
|
|
361
|
-
inset -1px -1px 0 rgb(var(--salmex-button-highlight)),
|
|
362
|
-
inset 1px 1px 0 rgb(var(--salmex-button-shadow));
|
|
363
|
-
background: rgb(var(--salmex-bg-primary));
|
|
364
|
-
font-weight: 900;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/* Minimized — subtle difference */
|
|
368
|
-
.salmex-wm-taskbar-btn-minimized {
|
|
369
|
-
opacity: 0.75;
|
|
370
|
-
}
|
|
371
|
-
|
|
372
|
-
.salmex-wm-taskbar-btn:focus-visible {
|
|
373
|
-
outline: none;
|
|
374
|
-
box-shadow:
|
|
375
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
376
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
|
|
377
|
-
0 0 0 2px rgb(var(--salmex-midnight-black)),
|
|
378
|
-
0 0 2px 4px rgb(var(--salmex-crown-yellow));
|
|
379
|
-
}
|
|
380
|
-
|
|
381
|
-
:global([data-theme='dark']) .salmex-wm-taskbar-btn:focus-visible {
|
|
382
|
-
box-shadow:
|
|
383
|
-
inset 1px 1px 0 rgb(var(--salmex-button-highlight)),
|
|
384
|
-
inset -1px -1px 0 rgb(var(--salmex-button-shadow)),
|
|
385
|
-
0 0 2px 3px rgb(var(--salmex-crown-yellow));
|
|
386
|
-
}
|
|
387
|
-
|
|
388
|
-
.salmex-wm-taskbar-btn-text {
|
|
389
|
-
overflow: hidden;
|
|
390
|
-
text-overflow: ellipsis;
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
/* System tray */
|
|
394
|
-
.salmex-wm-taskbar-tray {
|
|
395
|
-
display: flex;
|
|
396
|
-
align-items: center;
|
|
397
|
-
gap: var(--salmex-space-2);
|
|
398
|
-
padding: 0 var(--salmex-space-2);
|
|
399
|
-
margin-left: auto;
|
|
400
|
-
border-left: 1px solid rgb(var(--salmex-button-shadow));
|
|
401
|
-
border-radius: var(--salmex-radius-sm);
|
|
402
|
-
/* Sunken inset */
|
|
403
|
-
box-shadow:
|
|
404
|
-
inset 1px 1px 0 rgb(var(--salmex-button-shadow)),
|
|
405
|
-
inset -1px -1px 0 rgb(var(--salmex-button-highlight));
|
|
406
|
-
height: 22px;
|
|
407
|
-
}
|
|
408
|
-
|
|
409
|
-
.salmex-wm-clock {
|
|
410
|
-
font-family: var(--salmex-font-mono);
|
|
411
|
-
font-size: var(--salmex-font-size-xs);
|
|
412
|
-
color: rgb(var(--salmex-text-primary));
|
|
413
|
-
white-space: nowrap;
|
|
414
|
-
}
|
|
415
|
-
|
|
416
|
-
/* ========================================
|
|
417
|
-
REDUCED MOTION
|
|
418
|
-
======================================== */
|
|
419
|
-
|
|
420
|
-
@media (prefers-reduced-motion: reduce) {
|
|
421
|
-
.salmex-wm-taskbar-btn {
|
|
422
|
-
transition: none;
|
|
423
|
-
}
|
|
424
|
-
}
|
|
425
|
-
</style>
|
|
@@ -1,38 +0,0 @@
|
|
|
1
|
-
import type { Snippet } from 'svelte';
|
|
2
|
-
type TaskbarPosition = 'bottom' | 'top';
|
|
3
|
-
interface Props {
|
|
4
|
-
/** Height of the window manager area. */
|
|
5
|
-
height?: string;
|
|
6
|
-
/** Show the taskbar. */
|
|
7
|
-
showTaskbar?: boolean;
|
|
8
|
-
/** Taskbar position. */
|
|
9
|
-
taskbarPosition?: TaskbarPosition;
|
|
10
|
-
/** Show a desktop background pattern. */
|
|
11
|
-
showDesktopPattern?: boolean;
|
|
12
|
-
/** Desktop label in corner. */
|
|
13
|
-
desktopLabel?: string;
|
|
14
|
-
/** Window children (Window components). */
|
|
15
|
-
children?: Snippet;
|
|
16
|
-
/** Additional CSS class. */
|
|
17
|
-
class?: string;
|
|
18
|
-
/** Test ID for automated testing. */
|
|
19
|
-
testId?: string;
|
|
20
|
-
}
|
|
21
|
-
/**
|
|
22
|
-
* WindowManager
|
|
23
|
-
*
|
|
24
|
-
* Win2K x Basquiat -- Desktop-style container that manages Window components.
|
|
25
|
-
* Provides a bounded area for windows to live in, with a taskbar at the bottom
|
|
26
|
-
* showing all open windows (including minimized). Click-to-focus z-index stacking.
|
|
27
|
-
* Keyboard: F6 cycles windows, Alt+Arrow Up maximizes, Alt+Arrow Down minimizes.
|
|
28
|
-
*
|
|
29
|
-
* @example
|
|
30
|
-
* <WindowManager height="500px">
|
|
31
|
-
* <Window id="notes" title="Notes"><p>Content</p></Window>
|
|
32
|
-
* <Window id="settings" title="Settings"><p>Content</p></Window>
|
|
33
|
-
* </WindowManager>
|
|
34
|
-
*/
|
|
35
|
-
declare const WindowManager: import("svelte").Component<Props, {}, "">;
|
|
36
|
-
type WindowManager = ReturnType<typeof WindowManager>;
|
|
37
|
-
export default WindowManager;
|
|
38
|
-
//# sourceMappingURL=WindowManager.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"WindowManager.svelte.d.ts","sourceRoot":"","sources":["../../../src/windowing/WindowManager/WindowManager.svelte.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AAOtC,KAAK,eAAe,GAAG,QAAQ,GAAG,KAAK,CAAC;AAExC,UAAU,KAAK;IACd,yCAAyC;IACzC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,wBAAwB;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,wBAAwB;IACxB,eAAe,CAAC,EAAE,eAAe,CAAC;IAClC,yCAAyC;IACzC,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,+BAA+B;IAC/B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,2CAA2C;IAC3C,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,4BAA4B;IAC5B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,qCAAqC;IACrC,MAAM,CAAC,EAAE,MAAM,CAAC;CAChB;AA+HD;;;;;;;;;;;;;GAaG;AACH,QAAA,MAAM,aAAa,2CAAwC,CAAC;AAC5D,KAAK,aAAa,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAAC;AACtD,eAAe,aAAa,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/windowing/WindowManager/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,IAAI,aAAa,EAAE,MAAM,wBAAwB,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { default as WindowManager } from './WindowManager.svelte';
|
|
@@ -1,5 +0,0 @@
|
|
|
1
|
-
export { Window } from './Window/index.js';
|
|
2
|
-
export { WindowManager } from './WindowManager/index.js';
|
|
3
|
-
export { createWindowManager } from './windowStore.svelte.js';
|
|
4
|
-
export type { WindowState, WindowManagerState } from './windowStore.svelte.js';
|
|
5
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/windowing/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,mBAAmB,CAAC;AAC3C,OAAO,EAAE,aAAa,EAAE,MAAM,0BAA0B,CAAC;AACzD,OAAO,EAAE,mBAAmB,EAAE,MAAM,yBAAyB,CAAC;AAC9D,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC"}
|
package/dist/windowing/index.js
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Window Manager state — Svelte 5 runes-based reactive store.
|
|
3
|
-
* Manages window lifecycle: open, focus, minimize, maximize, restore, close.
|
|
4
|
-
* Counter-based z-index stacking; taskbar-aware focus cycling.
|
|
5
|
-
*/
|
|
6
|
-
export interface WindowState {
|
|
7
|
-
id: string;
|
|
8
|
-
title: string;
|
|
9
|
-
minimized: boolean;
|
|
10
|
-
maximized: boolean;
|
|
11
|
-
focused: boolean;
|
|
12
|
-
zIndex: number;
|
|
13
|
-
/** Position before maximize (for restore) */
|
|
14
|
-
savedGeometry: {
|
|
15
|
-
x: number;
|
|
16
|
-
y: number;
|
|
17
|
-
width: number;
|
|
18
|
-
height: number;
|
|
19
|
-
} | null;
|
|
20
|
-
/** Current position */
|
|
21
|
-
x: number;
|
|
22
|
-
y: number;
|
|
23
|
-
width: number;
|
|
24
|
-
height: number;
|
|
25
|
-
}
|
|
26
|
-
export interface WindowManagerState {
|
|
27
|
-
readonly windows: WindowState[];
|
|
28
|
-
register(id: string, title: string, opts?: {
|
|
29
|
-
x?: number;
|
|
30
|
-
y?: number;
|
|
31
|
-
width?: number;
|
|
32
|
-
height?: number;
|
|
33
|
-
}): void;
|
|
34
|
-
unregister(id: string): void;
|
|
35
|
-
focus(id: string): void;
|
|
36
|
-
minimize(id: string): void;
|
|
37
|
-
maximize(id: string, containerWidth: number, containerHeight: number): void;
|
|
38
|
-
restore(id: string): void;
|
|
39
|
-
close(id: string): void;
|
|
40
|
-
toggleMinimize(id: string): void;
|
|
41
|
-
move(id: string, x: number, y: number): void;
|
|
42
|
-
resize(id: string, width: number, height: number): void;
|
|
43
|
-
focusNext(): void;
|
|
44
|
-
focusPrevious(): void;
|
|
45
|
-
getWindow(id: string): WindowState | undefined;
|
|
46
|
-
getFocusedWindow(): WindowState | undefined;
|
|
47
|
-
}
|
|
48
|
-
export declare function createWindowManager(): WindowManagerState;
|
|
49
|
-
//# sourceMappingURL=windowStore.svelte.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"windowStore.svelte.d.ts","sourceRoot":"","sources":["../../src/windowing/windowStore.svelte.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,WAAW;IAC3B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,OAAO,CAAC;IACnB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,6CAA6C;IAC7C,aAAa,EAAE;QAAE,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC;IAC9E,uBAAuB;IACvB,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,kBAAkB;IAClC,QAAQ,CAAC,OAAO,EAAE,WAAW,EAAE,CAAC;IAChC,QAAQ,CACP,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,MAAM,EACb,IAAI,CAAC,EAAE;QAAE,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,CAAC,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAChE,IAAI,CAAC;IACR,UAAU,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;IAC5E,OAAO,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAC1B,KAAK,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,cAAc,CAAC,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,IAAI,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAC7C,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACxD,SAAS,IAAI,IAAI,CAAC;IAClB,aAAa,IAAI,IAAI,CAAC;IACtB,SAAS,CAAC,EAAE,EAAE,MAAM,GAAG,WAAW,GAAG,SAAS,CAAC;IAC/C,gBAAgB,IAAI,WAAW,GAAG,SAAS,CAAC;CAC5C;AAED,wBAAgB,mBAAmB,IAAI,kBAAkB,CAqKxD"}
|