buoy-ui 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +294 -2
- package/dist/buoy.global.js +2 -0
- package/dist/index.cjs +1705 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +239 -0
- package/dist/index.d.ts +239 -0
- package/dist/index.js +1679 -0
- package/dist/index.js.map +1 -0
- package/dist/styles.css +130 -0
- package/dist/vanilla.cjs +1642 -0
- package/dist/vanilla.cjs.map +1 -0
- package/dist/vanilla.d.cts +242 -0
- package/dist/vanilla.d.ts +242 -0
- package/dist/vanilla.js +1613 -0
- package/dist/vanilla.js.map +1 -0
- package/package.json +102 -4
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Michael Li
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
CHANGED
|
@@ -1,3 +1,295 @@
|
|
|
1
|
-
#
|
|
1
|
+
# Buoy
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
[](https://github.com/Michaell14/buoy/actions/workflows/ci.yml)
|
|
4
|
+
|
|
5
|
+
A morphing island for notifications, promises and background tasks.
|
|
6
|
+
|
|
7
|
+
**Try it live at [buoy-ui.vercel.app](https://buoy-ui.vercel.app).**
|
|
8
|
+
|
|
9
|
+
Messages, loading states and upload progress share one surface at the top of the screen. It queues, it splits in two when a message arrives during an upload, and it opens into a tray when you need the details. Works with React, or with no framework at all.
|
|
10
|
+
|
|
11
|
+
- **One surface.** Each state is the same element changing shape, so nothing stacks and nothing jumps.
|
|
12
|
+
- **Promises on the same shape.** Loading turns into success or error in place.
|
|
13
|
+
- **Real progress.** Track uploads or any long job: a live ring, then a tray with pause, resume, retry and cancel.
|
|
14
|
+
- **Four looks.** Ink, Frost, Paper, and Notch, which hangs from the top edge of the viewport.
|
|
15
|
+
- **Small and dependency-free.** About 16 KB gzipped including styles. Styles inject themselves.
|
|
16
|
+
- **Accessible.** Real buttons, a polite live region, Esc to close, and `prefers-reduced-motion` support.
|
|
17
|
+
|
|
18
|
+
## Install
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install buoy-ui
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Quick start (React)
|
|
25
|
+
|
|
26
|
+
Render `<Buoy />` once, near the root. Then call `buoy()` from anywhere: components, effects, plain functions.
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { Buoy, buoy } from 'buoy-ui';
|
|
30
|
+
|
|
31
|
+
export default function App() {
|
|
32
|
+
return (
|
|
33
|
+
<>
|
|
34
|
+
<Buoy />
|
|
35
|
+
<button onClick={() => buoy('Link copied', { icon: 'link' })}>Copy link</button>
|
|
36
|
+
</>
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
`<Buoy />` renders nothing inside your component tree. The island lives in its own element at the end of `<body>`.
|
|
42
|
+
|
|
43
|
+
**Next.js (App Router):** put `<Buoy />` in your root `layout.tsx`. The package is marked `'use client'`, so you can import it from a Server Component file. Calling `buoy()` during server rendering is harmless: nothing shows until the island mounts in the browser.
|
|
44
|
+
|
|
45
|
+
## Messages
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
buoy('Link copied', { icon: 'link' });
|
|
49
|
+
buoy.success('Saved to drafts');
|
|
50
|
+
buoy.info('Update available');
|
|
51
|
+
buoy.warn("You're offline", { persist: true });
|
|
52
|
+
buoy.error("Couldn't save", { action: { label: 'Retry', onClick: save } });
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
One message shows at a time. While others wait, a `+N` badge counts them and each one gets a short turn. Errors and `persist: true` messages stay until they are dismissed, but they step aside for newer messages and come back afterwards.
|
|
56
|
+
|
|
57
|
+
Messages with a description or several buttons open on hover or tap. Pass `expanded: true` to open them straight away:
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
buoy('Export ready', {
|
|
61
|
+
description: 'Q3-report.pdf · 4.2 MB',
|
|
62
|
+
icon: 'file',
|
|
63
|
+
tone: 'accent',
|
|
64
|
+
expanded: true,
|
|
65
|
+
actions: [
|
|
66
|
+
{ label: 'Open', primary: true, onClick: open },
|
|
67
|
+
{ label: 'Show in folder', onClick: reveal },
|
|
68
|
+
],
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Every call returns an id. Pass it back to update the message in place, or to dismiss it:
|
|
73
|
+
|
|
74
|
+
```ts
|
|
75
|
+
const id = buoy('Syncing…', { duration: Infinity });
|
|
76
|
+
buoy.success('Synced', { id });
|
|
77
|
+
buoy.dismiss(id);
|
|
78
|
+
buoy.dismiss(); // everything
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
| Option | Type | What it does |
|
|
82
|
+
| --- | --- | --- |
|
|
83
|
+
| `description` | `string` | Second line |
|
|
84
|
+
| `icon` | built-in name, trusted `<svg>` string, or `null` | Leading icon |
|
|
85
|
+
| `tone` | `'accent' \| 'success' \| 'error' \| 'warning' \| 'info'` | Icon tint for untyped messages |
|
|
86
|
+
| `action` | `{ label, onClick }` | One button on the compact pill |
|
|
87
|
+
| `actions` | `{ label, onClick, primary? }[]` | Up to two buttons in the expanded layout |
|
|
88
|
+
| `expanded` | `boolean` | Open the expanded layout straight away |
|
|
89
|
+
| `duration` | `number` (ms) | Defaults to 3000, or 6000 with buttons. `Infinity` keeps it |
|
|
90
|
+
| `persist` | `boolean` | Stay until dismissed. Errors persist by default |
|
|
91
|
+
| `id` | `string` | Update an existing message |
|
|
92
|
+
| `onDismiss` | `() => void` | Called when it leaves |
|
|
93
|
+
|
|
94
|
+
Built-in icons: `link`, `check`, `error`, `warning`, `info`, `upload`, `download`, `file`, `archive`, `image`, `send`, `folder`, `copy`, `stack`, `bell`, `timer`, `user`, `pause`, `play`, `retry`, `x`, `open`.
|
|
95
|
+
|
|
96
|
+
## Promises
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
buoy.promise(save(), {
|
|
100
|
+
loading: 'Saving…',
|
|
101
|
+
success: 'Saved to drafts',
|
|
102
|
+
error: (e) => (e instanceof Error ? e.message : "Couldn't save"),
|
|
103
|
+
retry: save,
|
|
104
|
+
});
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
It returns the promise you passed, so you can still `await` it.
|
|
108
|
+
|
|
109
|
+
## Background tasks
|
|
110
|
+
|
|
111
|
+
Give `buoy.track()` a function that does the work and reports progress. The island shows a live ring. Tapping it opens the tray, where each task can pause, resume, retry or cancel.
|
|
112
|
+
|
|
113
|
+
```ts
|
|
114
|
+
const job = buoy.track(
|
|
115
|
+
(task) =>
|
|
116
|
+
upload(file, {
|
|
117
|
+
onProgress: (e) => task.progress(e.loaded, e.total),
|
|
118
|
+
signal: task.signal,
|
|
119
|
+
}),
|
|
120
|
+
{ label: file.name, total: file.size, icon: 'image' },
|
|
121
|
+
);
|
|
122
|
+
|
|
123
|
+
job.pause();
|
|
124
|
+
job.resume();
|
|
125
|
+
job.cancel();
|
|
126
|
+
job.retry();
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The function receives a task context:
|
|
130
|
+
|
|
131
|
+
| Member | What it does |
|
|
132
|
+
| --- | --- |
|
|
133
|
+
| `task.progress(fraction)` or `task.progress(loaded, total)` | Report progress. Amounts are shown as bytes unless you pass `format` |
|
|
134
|
+
| `task.signal` | An `AbortSignal` that fires on cancel |
|
|
135
|
+
| `task.checkpoint()` | Resolves now, or when a paused task is resumed. Await it between chunks to support pausing |
|
|
136
|
+
| `task.attempt` | 1 on the first run, 2 after the first retry |
|
|
137
|
+
|
|
138
|
+
If the function throws or rejects, the task is marked failed with the error's message and can be retried. Two tasks run at a time by default (`concurrency`).
|
|
139
|
+
|
|
140
|
+
| Option | Type | What it does |
|
|
141
|
+
| --- | --- | --- |
|
|
142
|
+
| `label` | `string` | Name in the island and tray |
|
|
143
|
+
| `total` | `number` | Size of the work, so progress shows before the first report |
|
|
144
|
+
| `icon` | icon | Tile icon in the tray |
|
|
145
|
+
| `pausable` | `boolean` | Set to `false` for work that can't pause |
|
|
146
|
+
| `doneLabel` | `string` | Line under a finished task, like "Uploaded just now" |
|
|
147
|
+
| `format` | `(loaded, total) => string` | Amount line, e.g. `` (n, t) => `${n} of ${t} files` `` |
|
|
148
|
+
| `onOpen` | `(task) => void` | Adds an Open button to the finished task |
|
|
149
|
+
|
|
150
|
+
Show progress elsewhere in your React UI with the hook:
|
|
151
|
+
|
|
152
|
+
```tsx
|
|
153
|
+
import { useBuoyTasks } from 'buoy-ui';
|
|
154
|
+
|
|
155
|
+
function UploadBadge() {
|
|
156
|
+
const tasks = useBuoyTasks();
|
|
157
|
+
const running = tasks.filter((t) => t.status === 'running').length;
|
|
158
|
+
return running ? <span>{running} uploading</span> : null;
|
|
159
|
+
}
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
You can also open the tray yourself: `buoy.tray.open()`, `buoy.tray.close()`, `buoy.tray.toggle()`.
|
|
163
|
+
|
|
164
|
+
## Live activities
|
|
165
|
+
|
|
166
|
+
For something ongoing that you want to draw yourself, such as a timer, a call, a player or a recording, use `buoy.live()`. You supply the markup; the island still handles its size, motion, queue, the bubble for tasks, and screen reader announcements. A live activity stays until you close it, and steps aside for new messages before coming back.
|
|
167
|
+
|
|
168
|
+
```ts
|
|
169
|
+
let left = 25 * 60;
|
|
170
|
+
const timer = buoy.live({
|
|
171
|
+
label: 'Focus timer',
|
|
172
|
+
expandable: true, // a tap opens the details
|
|
173
|
+
render(el, { expanded }) {
|
|
174
|
+
const time = `${Math.floor(left / 60)}:${String(left % 60).padStart(2, '0')}`;
|
|
175
|
+
el.innerHTML = expanded
|
|
176
|
+
? `<div class="buoy-exp"><span class="buoy-exp-title">Focus</span><span class="buoy-exp-desc">${time} left</span></div>`
|
|
177
|
+
: `<span class="buoy-row no-icon"><span class="buoy-title">Focus</span><span class="buoy-pct">${time}</span></span>`;
|
|
178
|
+
},
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
const tick = setInterval(() => {
|
|
182
|
+
left--;
|
|
183
|
+
timer.refresh(); // draws again in place, without announcing
|
|
184
|
+
if (!left) {
|
|
185
|
+
clearInterval(tick);
|
|
186
|
+
timer.close();
|
|
187
|
+
}
|
|
188
|
+
}, 1000);
|
|
189
|
+
```
|
|
190
|
+
|
|
191
|
+
| Option | |
|
|
192
|
+
| --- | --- |
|
|
193
|
+
| `label` | What the activity is, for screen readers. Read out when it appears. |
|
|
194
|
+
| `render(el, { expanded })` | Fills the island. Called when it appears, when it opens or closes, and on every `refresh()`. |
|
|
195
|
+
| `expandable` | A tap opens the details, and `render` gets `expanded: true`. Esc or a click outside closes them. |
|
|
196
|
+
| `id` | Replaces the live activity with this id, and announces the new label. |
|
|
197
|
+
| `duration` | Leaves after this many milliseconds. Without it, the activity stays until `close()`. |
|
|
198
|
+
| `onClose` | Called when the activity leaves. |
|
|
199
|
+
|
|
200
|
+
The handle has `refresh()`, `expand(open?)` and `close()`. An expandable activity's compact view sits inside a button, so keep its markup non-interactive and put buttons in the expanded view.
|
|
201
|
+
|
|
202
|
+
To match every theme, reuse the island's own classes: `buoy-row`, `buoy-ic` (with `data-tone="accent|success|error|warn"`), `buoy-title`, `buoy-pct`, `buoy-act`, `buoy-ring`, `buoy-exp`, `buoy-exp-head`, `buoy-tile`, `buoy-exp-text`, `buoy-exp-title`, `buoy-exp-desc`, `buoy-x`, `buoy-bar`, `buoy-actions` and `buoy-btn` (with `is-primary` or `is-danger`). For anything else, these custom properties hold the current theme's colors: `--buoy-bg`, `--buoy-fg`, `--buoy-fg-2`, `--buoy-chip`, `--buoy-chip-2`, `--buoy-track`, `--buoy-tint`, `--buoy-success`, `--buoy-error` and `--buoy-warn`.
|
|
203
|
+
|
|
204
|
+
## Options
|
|
205
|
+
|
|
206
|
+
Pass these as props to `<Buoy />`, or to `mount()` and `buoy.configure()` without React.
|
|
207
|
+
|
|
208
|
+
| Prop | Type | Default | What it does |
|
|
209
|
+
| --- | --- | --- | --- |
|
|
210
|
+
| `theme` | `'ink' \| 'frost' \| 'paper' \| 'notch'` | `'ink'` | Surface style |
|
|
211
|
+
| `position` | `'top' \| 'bottom'` | `'top'` | Which edge the island sits on |
|
|
212
|
+
| `resting` | `'hidden' \| 'pill'` | `'hidden'` | What shows when nothing is happening |
|
|
213
|
+
| `richColors` | `boolean` | `false` | Tint the surface by message type |
|
|
214
|
+
| `colorScheme` | `'system' \| 'light' \| 'dark'` | `'system'` | Palette for Frost and Paper |
|
|
215
|
+
| `expandOnHover` | `boolean` | `true` | Open a message's details on hover |
|
|
216
|
+
| `duration` | `number` | `3000` | Default message duration in ms |
|
|
217
|
+
| `concurrency` | `number` | `2` | Tasks that run at the same time |
|
|
218
|
+
| `guard` | `boolean` | `true` | Ask before the tab closes while tasks run |
|
|
219
|
+
| `haptics` | `boolean` | `false` | Short vibration where the device supports it |
|
|
220
|
+
| `offset` | `number` | `12` | Distance from the screen edge in px |
|
|
221
|
+
| `taskIcon` | icon | `'upload'` | Icon on the live pill |
|
|
222
|
+
| `labels` | `{ noun, active, doneOne, doneMany }` | | Wording for tasks |
|
|
223
|
+
| `injectStyles` | `boolean` | `true` | Set to `false` if you import `buoy-ui/styles.css` yourself |
|
|
224
|
+
| `nonce` | `string` | | Nonce for the injected `<style>` under a strict CSP |
|
|
225
|
+
| `container` | `HTMLElement` | `document.body` | Where to render |
|
|
226
|
+
|
|
227
|
+
```tsx
|
|
228
|
+
<Buoy
|
|
229
|
+
theme="frost"
|
|
230
|
+
resting="pill"
|
|
231
|
+
labels={{
|
|
232
|
+
noun: 'upload',
|
|
233
|
+
active: (tasks) => (tasks.length === 1 ? `Uploading ${tasks[0].label}` : `Uploading ${tasks.length} files`),
|
|
234
|
+
}}
|
|
235
|
+
/>
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
## Theming
|
|
239
|
+
|
|
240
|
+
Set these custom properties anywhere above the island, `:root` included:
|
|
241
|
+
|
|
242
|
+
```css
|
|
243
|
+
:root {
|
|
244
|
+
--buoy-accent: #2dd4bf; /* progress on dark surfaces */
|
|
245
|
+
--buoy-accent-strong: #0f766e; /* progress on light surfaces */
|
|
246
|
+
--buoy-ink: #0b0b0c; /* Ink and Notch fill */
|
|
247
|
+
--buoy-font: 'Inter', system-ui, sans-serif;
|
|
248
|
+
--buoy-offset: 12px;
|
|
249
|
+
--buoy-z: 2147483000;
|
|
250
|
+
}
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
## Without React
|
|
254
|
+
|
|
255
|
+
```ts
|
|
256
|
+
import { buoy, mount } from 'buoy-ui/vanilla';
|
|
257
|
+
|
|
258
|
+
const island = mount({ theme: 'ink' });
|
|
259
|
+
buoy('Hello');
|
|
260
|
+
island.configure({ position: 'bottom' });
|
|
261
|
+
island.destroy();
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Or from a CDN:
|
|
265
|
+
|
|
266
|
+
```html
|
|
267
|
+
<script src="https://unpkg.com/buoy-ui/dist/buoy.global.js"></script>
|
|
268
|
+
<script>
|
|
269
|
+
const { buoy, mount } = window.Buoy;
|
|
270
|
+
mount();
|
|
271
|
+
buoy('Hello');
|
|
272
|
+
</script>
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
## Keyboard and screen readers
|
|
276
|
+
|
|
277
|
+
- New messages are announced through a polite live region.
|
|
278
|
+
- Every control is a real `<button>` with a visible focus ring.
|
|
279
|
+
- Esc closes the tray, and dismisses a message while it is focused or hovered.
|
|
280
|
+
- Swipe the island toward its edge to dismiss. Hovering pauses the timer, and so does a hidden tab.
|
|
281
|
+
- With `prefers-reduced-motion`, sizes change instantly and content only fades.
|
|
282
|
+
|
|
283
|
+
## Browser support
|
|
284
|
+
|
|
285
|
+
Current Chrome, Edge, Firefox and Safari. The gooey split between the pill and the bubble uses an SVG filter and falls back to a plain slide where that isn't supported. Frost needs `backdrop-filter`.
|
|
286
|
+
|
|
287
|
+
## Development
|
|
288
|
+
|
|
289
|
+
Use Node 24 (`nvm use` reads `.nvmrc`). `npm test` runs the tests and `npm run site` serves the website at http://localhost:4173.
|
|
290
|
+
|
|
291
|
+
To release, bump `version` in `package.json` and push it to `main`. CI stages the new version on npm through trusted publishing, and a maintainer approves it in the Staged Packages tab on npmjs.com.
|
|
292
|
+
|
|
293
|
+
## License
|
|
294
|
+
|
|
295
|
+
MIT
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var Buoy=(()=>{var Ue=Object.defineProperty;var Ot=Object.getOwnPropertyDescriptor;var At=Object.getOwnPropertyNames;var Lt=Object.prototype.hasOwnProperty;var Ft=(n,c)=>{for(var r in c)Ue(n,r,{get:c[r],enumerable:!0})},Ct=(n,c,r,g)=>{if(c&&typeof c=="object"||typeof c=="function")for(let y of At(c))!Lt.call(n,y)&&y!==r&&Ue(n,y,{get:()=>c[y],enumerable:!(g=Ot(c,y))||g.enumerable});return n};var Bt=n=>Ct(Ue({},"__esModule",{value:!0}),n);var en={};Ft(en,{buoy:()=>ft,mount:()=>$t,styles:()=>Ne});var xe=(n,c,r)=>Math.min(r,Math.max(c,n)),Pt={"&":"&","<":"<",">":">",'"':""","'":"'"},L=n=>String(n!=null?n:"").replace(/[&<>"']/g,c=>Pt[c]),J=n=>n.status==="done"?1:n.total>0?xe(n.loaded/n.total,0,1):n.fraction,Dt=[[1e9,"GB"],[1e6,"MB"],[1e3,"KB"]];function ut(n){for(let c of Dt)if(n>=c[0])return c;return[1,"B"]}var We=n=>n>=100?String(Math.round(n)):String(Math.round(n*10)/10);function Ht(n,c){let[r,g]=ut(c);return`${We(n/r)} of ${We(c/r)} ${g}`}function It(n){let[c,r]=ut(n);return`${We(n/c)} ${r}`}function Rt(n){if(!(n.rate>0)||!(n.total>0))return"";let c=Math.max(1,Math.round((n.total-n.loaded)/n.rate));return c<60?`${c} s left`:`${Math.round(c/60)} min left`}function Qe(n){switch(n.status){case"running":return`${Math.round(J(n)*100)}%`;case"queued":return"Queued";case"paused":return"Paused";case"failed":return"Failed";default:return n.total>0&&!n.format?It(n.total):"Done"}}function Xe(n){let c=n.total>0?n.format?n.format(n.loaded,n.total):Ht(n.loaded,n.total):`${Math.round(J(n)*100)}%`;switch(n.status){case"running":{let r=Rt(n);return r?`${c} \xB7 ${r}`:c}case"queued":return"Waiting to start";case"paused":return c;case"failed":return n.total>0?`${n.error} at ${c}`:n.error;default:return n.doneLabel||"Finished"}}var qt=1500,zt=900,Nt=200,Vt=6e3,Kt=2e3,jt=4e3,ct={theme:"ink",position:"top",resting:"hidden",richColors:!1,expandOnHover:!0,duration:3e3,concurrency:2,guard:!0,haptics:!1,colorScheme:"system",offset:null,taskIcon:"upload"};function dt(){let n={noun:"task",active:e=>e.length===1?e[0].label:`${e.length} ${c.labels.noun}s`,doneOne:e=>`${e.label} finished`,doneMany:e=>`${e} ${c.labels.noun}s finished`},c={...ct,labels:{...n}},r={current:null,queue:[],tasks:[],trayOpen:!1,attentionDismissed:!1,batch:0,batchAnnounced:!1,version:0},g=new Set,y=new Set(["detached"]),p=0,D=e=>`buoy-${e}${++p}`,T=()=>Date.now();function h(e="change",a){r.version++,g.forEach(i=>i(e,a))}function G(e){return g.add(e),()=>g.delete(e)}function Oe(e){typeof console!="undefined"&&console.error(e)}function Ae(){if(!(!c.haptics||typeof navigator=="undefined"||typeof navigator.vibrate!="function"))try{navigator.vibrate(8)}catch{}}function U(e={}){let{labels:a,...i}=e,d=c,m=!1;for(let[E,v]of Object.entries(i))v===void 0||d[E]===v||(d[E]=v,m=!0);if(a){let E=c.labels;for(let[v,M]of Object.entries(a))M===void 0||E[v]===M||(E[v]=M,m=!0)}m&&(i.concurrency!==void 0&&ne(),h("config"))}let k=()=>y.size>0||r.trayOpen;function F(e){e.timer||!Number.isFinite(e.remaining)||k()||e!==r.current||(e.deadline=T()+e.remaining,e.timer=setTimeout(()=>{e.timer=0,be(e.id)},e.remaining))}function W(e){e.timer&&(clearTimeout(e.timer),e.timer=0,e.remaining=Math.max(0,e.deadline-T()))}function H(){let e=r.current;e&&(k()?W(e):F(e))}function Ve(e,a){a!==y.has(e)&&(a?y.add(e):y.delete(e),H())}function Le(e,a){var v,M,C,me,B,ce,Pe,re,Ee;let i=(v=a.type)!=null?v:"default",d=(M=a.persist)!=null?M:i==="error",m=!!(a.action||a.actions&&a.actions.length),E=(C=a.duration)!=null?C:d?1/0:m?Math.max(c.duration,Vt):c.duration;return{id:(me=a.id)!=null?me:D("m"),type:i,title:String(e),description:(B=a.description)!=null?B:"",icon:a.icon,tone:(ce=a.tone)!=null?ce:"",action:(Pe=a.action)!=null?Pe:null,actions:a.actions&&a.actions.length?a.actions.slice(0,2):null,expanded:!!a.expanded,persist:d,duration:E,remaining:E,timer:0,deadline:0,shownAt:0,tapped:!1,onDismiss:(re=a.onDismiss)!=null?re:null,render:(Ee=a.render)!=null?Ee:null,expandable:!!a.expandable,open:!1,rev:0}}function I(e){var a;return r.current&&r.current.id===e?r.current:(a=r.queue.find(i=>i.id===e))!=null?a:null}function A(e){e.remaining=e.duration,r.queue.length&&Number.isFinite(e.remaining)&&(e.remaining=Math.min(e.remaining,qt)),e.timer=0,e.shownAt=T(),e.open=!1,F(e),h("show",e),Ae()}function Ke(e){if(!Number.isFinite(e.remaining))return;let a=Math.max(Nt,zt-(T()-e.shownAt));(e.timer?e.deadline-T():e.remaining)<=a||(W(e),e.remaining=a,F(e))}function ie(e,a={}){if(a.id){let m=I(a.id);if(m)return ve(m,e,a),m.id}let i=Le(e,a),d=r.current;return d?d.persist&&d.type!=="loading"?(W(d),r.queue.push(d),r.current=i,A(i)):(r.queue.push(i),Ke(d)):(r.current=i,A(i)),h(),i.id}function ve(e,a,i){let d=Le(a,{...i,id:e.id});d.rev=e.rev+1,W(e),Object.assign(e,d),e===r.current&&A(e),h()}function be(e){let a=r.current;if(e===void 0){for(let i of[a,...r.queue])i&&W(i);r.queue=[],r.current=null,a&&a.onDismiss&&Z(a.onDismiss),h();return}if(a&&a.id===e){W(a),r.current=null,a.onDismiss&&Z(a.onDismiss);let i=r.queue.shift();i&&(r.current=i,A(i))}else{let i=r.queue.findIndex(d=>d.id===e);if(i<0)return;r.queue.splice(i,1)}h()}function Z(e){try{e()}catch(a){Oe(a)}}function R(e){let a=e.duration!==void 0&&Number.isFinite(e.duration),i=ie(e.label,{id:e.id,type:"live",persist:!a,duration:a?e.duration:1/0,onDismiss:e.onClose,render:e.render,expandable:e.expandable});return{id:i,refresh:()=>Fe(i),expand:(d=!0)=>ee(i,d),close:()=>be(i)}}function Fe(e){let a=I(e);!a||!a.render||(a.rev++,h())}function ee(e,a){let i=I(e);!i||!i.expandable||i.open===a||(i.open=a,i.rev++,h())}function ke(e){let a=I(e);!a||a.tapped||(a.tapped=!0,h())}function je(e,a={}){var E;let i=ie((E=a.loading)!=null?E:"Loading\u2026",{type:"loading",duration:1/0,persist:!1}),d;try{d=Promise.resolve(typeof e=="function"?e():e)}catch(v){d=Promise.reject(v)}let m=(v,M)=>{let C=I(i);C?ve(C,v,M):ie(v,M)};return d.then(v=>{var M,C;return m(typeof a.success=="function"?a.success(v):(M=a.success)!=null?M:"Done",{type:"success",duration:(C=a.successDuration)!=null?C:Kt})},v=>{var M;return m(typeof a.error=="function"?a.error(v):(M=a.error)!=null?M:"Something went wrong",{type:"error",action:a.retry?{label:"Retry",onClick:a.retry}:void 0})}),d}let ye=e=>e.status==="running"||e.status==="queued"||e.status==="paused",j=()=>r.tasks.filter(ye),Q=()=>r.tasks.filter(e=>e.status==="failed"),te=e=>{var a;return(a=r.tasks.find(i=>i.id===e))!=null?a:null};function N(e){return{id:e.id,label:e.label,status:e.status==="canceled"?"failed":e.status,loaded:e.loaded,total:e.total,progress:J(e),error:e.error||void 0,attempt:e.attempt}}function ge(e){r.batch++,r.batchAnnounced=!1,r.attentionDismissed=!1,e&&(r.tasks=r.tasks.filter(a=>a.status!=="done"))}function X(e,a={}){var d,m,E,v,M,C;if(typeof e!="function")throw new TypeError("buoy.track() needs a function that does the work.");j().length||ge(!0);let i={id:D("t"),label:String((d=a.label)!=null?d:"Task"),icon:(m=a.icon)!=null?m:"file",run:e,pausable:a.pausable!==!1,onOpen:(E=a.onOpen)!=null?E:null,doneLabel:(v=a.doneLabel)!=null?v:"",format:(M=a.format)!=null?M:null,status:"queued",loaded:0,total:(C=a.total)!=null?C:0,fraction:0,rate:0,lastT:0,lastL:0,attempt:0,started:!1,paused:!1,resumers:[],ctrl:null,batch:r.batch,error:""};return r.tasks.push(i),ne(),h(),{id:i.id,pause:()=>we(i),resume:()=>Me(i),cancel:()=>Be(i),retry:()=>Te(i)}}function _e(e){let a=T(),i=(a-e.lastT)/1e3;if(i<.05)return;let d=(e.loaded-e.lastL)/i;e.rate=e.rate?e.rate*.75+d*.25:d,e.lastT=a,e.lastL=e.loaded}function Ce(e){let a=e.resumers;e.resumers=[],a.forEach(i=>i())}function Ye(e){e.status="running",e.started=!0,e.paused=!1,e.attempt+=1,e.error="",e.ctrl=new AbortController,e.lastT=T(),e.lastL=e.loaded,e.rate=0;let a=e.attempt,i={signal:e.ctrl.signal,attempt:a,progress:(d,m)=>{e.attempt!==a||e.status==="canceled"||(typeof m=="number"?(e.total=Math.max(0,m),e.loaded=xe(d,0,e.total||d)):(e.fraction=xe(d,0,1),e.total&&(e.loaded=e.fraction*e.total)),_e(e),h("progress"))},checkpoint:()=>e.paused?new Promise(d=>e.resumers.push(d)):Promise.resolve()};Promise.resolve().then(()=>e.run(i)).then(()=>{e.attempt!==a||e.status==="canceled"||(e.status="done",e.total&&(e.loaded=e.total),e.fraction=1,_())},d=>{e.attempt!==a||e.status==="canceled"||(e.status="failed",e.error=d instanceof Error&&d.message?d.message:typeof d=="string"?d:"Failed",_())})}function ne(){let e=r.tasks.filter(a=>a.status==="running").length;for(let a of r.tasks){if(e>=c.concurrency)break;a.status==="queued"&&(e++,a.started?(a.status="running",a.paused=!1,a.lastT=T(),a.lastL=a.loaded,a.rate=0,Ce(a)):Ye(a))}}function we(e){e.status!=="running"||!e.pausable||(e.status="paused",e.paused=!0,e.rate=0,ne(),h())}function Me(e){e.status==="paused"&&(e.status="queued",ne(),h())}function Be(e){ye(e)&&(e.status="canceled",e.paused=!1,e.ctrl&&e.ctrl.abort(),Ce(e),r.tasks=r.tasks.filter(a=>a!==e),_())}function Te(e){e.status==="failed"&&(j().length||ge(!1),Object.assign(e,{status:"queued",loaded:0,fraction:0,rate:0,started:!1,error:"",batch:r.batch}),r.attentionDismissed=!1,ne(),h())}function $(e){ye(e)||(r.tasks=r.tasks.filter(a=>a!==e),h())}function x(){r.tasks=r.tasks.filter(e=>e.status!=="done"),h()}function _(){if(ne(),!j().length){let e=Q(),a=r.tasks.filter(i=>i.status==="done"&&i.batch===r.batch);if(e.length)r.attentionDismissed=!1,Ae();else if(a.length&&!r.trayOpen&&!r.batchAnnounced){r.batchAnnounced=!0;let i=a.length===1?c.labels.doneOne(N(a[0])):c.labels.doneMany(a.length);ie(i,{type:"success",duration:jt,action:{label:"View",onClick:oe}})}}h()}function ae(){let e=0,a=0,i=0,d=0;for(let m of r.tasks)m.batch===r.batch&&(m.total>0?(e+=m.total,a+=J(m)*m.total):(i+=J(m),d++));return!e&&!d?0:d?xe(e?(a/e+i)/(1+d):i/d,0,1):xe(a/e,0,1)}function le(){let e={running:0,queued:0,paused:0,failed:0,done:0};for(let i of r.tasks)i.status!=="canceled"&&e[i.status]++;return{counts:e,text:["running","queued","paused","failed","done"].filter(i=>e[i]).map(i=>`${e[i]} ${i}`).join(" \xB7 ")}}function oe(){r.trayOpen||(r.trayOpen=!0,H(),h())}function $e(){r.trayOpen&&(r.trayOpen=!1,H(),h())}function he(){r.attentionDismissed||(r.attentionDismissed=!0,h())}let ue=e=>a=>{let i=te(a);i&&e(i)};return{cfg:c,state:r,defaults:{options:ct,labels:n},subscribe:G,configure:U,setPaused:Ve,push:ie,dismiss:be,tap:ke,live:R,refresh:Fe,setOpen:ee,promise:je,find:I,track:X,tasks:()=>r.tasks.map(N),info:N,active:j,failed:Q,aggregate:ae,summary:le,pauseTask:ue(we),resumeTask:ue(Me),cancelTask:ue(Be),retryTask:ue(Te),removeTask:ue($),retryFailed:()=>Q().forEach(Te),pauseAll:()=>r.tasks.filter(e=>e.status==="running").forEach(we),resumeAll:()=>r.tasks.filter(e=>e.status==="paused").forEach(Me),clearDone:x,openTray:oe,closeTray:$e,toggleTray:()=>r.trayOpen?$e():oe(),dismissAttention:he}}var pt=Symbol.for("buoy-ui");function qe(){let n=globalThis,c=n[pt];return c||(c={store:dt(),island:null,warned:!1},n[pt]=c),c}var P=()=>qe().store;function _t(n,c){return P().push(n,c)}var ft=Object.assign(_t,{success:(n,c)=>P().push(n,{...c,type:"success"}),error:(n,c)=>P().push(n,{...c,type:"error"}),warn:(n,c)=>P().push(n,{...c,type:"warning"}),info:(n,c)=>P().push(n,{...c,type:"info"}),promise:(n,c)=>P().promise(n,c),dismiss:n=>P().dismiss(n),track:(n,c)=>P().track(n,c),live:n=>P().live(n),tasks:()=>P().tasks(),tray:{open:()=>P().openTray(),close:()=>P().closeTray(),toggle:()=>P().toggleTray()},configure:n=>P().configure(n)});var bt="--a-edge:rgba(255,255,255,.14);--a-shadow:0 14px 30px -14px rgba(0,0,0,.9),0 2px 6px -2px rgba(0,0,0,.5);",Yt="--a-bg:rgba(255,255,255,.66);--a-fg:#0B0B0C;--a-fg2:#3F3F46;--a-edge:rgba(255,255,255,.7);--a-shadow:0 12px 30px -14px rgba(0,0,0,.4);--a-chip:rgba(11,11,12,.08);--a-chip-2:rgba(11,11,12,.14);--a-primary:#0B0B0C;--a-primary-fg:#fff;--a-track:rgba(11,11,12,.14);--a-row:rgba(11,11,12,.05);--a-row-2:rgba(11,11,12,.09);--a-accent:var(--buoy-accent-strong,#0F766E);--a-blur:blur(20px) saturate(1.6);--a-success:#047857;--a-error:#B91C1C;--a-warn:#B45309;--a-info:#1D4ED8;",yt="--a-bg:rgba(32,32,37,.62);--a-fg:#F4F4F5;--a-fg2:#C8C8CE;--a-edge:rgba(255,255,255,.12);--a-chip:rgba(255,255,255,.1);--a-chip-2:rgba(255,255,255,.16);--a-primary:#F4F4F5;--a-primary-fg:#0B0B0C;--a-track:rgba(255,255,255,.16);--a-row:rgba(255,255,255,.05);--a-row-2:rgba(255,255,255,.09);--a-accent:var(--buoy-accent,#2DD4BF);--a-success:#34D399;--a-error:#F87171;--a-warn:#FBBF24;--a-info:#60A5FA;",Gt="--a-bg:#fff;--a-fg:#111113;--a-fg2:#52525B;--a-edge:#E4E4E7;--a-shadow:0 12px 28px -16px rgba(0,0,0,.3),0 1px 2px rgba(0,0,0,.06);--a-chip:#F4F4F5;--a-chip-2:#EAEAEC;--a-primary:#0B0B0C;--a-primary-fg:#fff;--a-track:#E4E4E7;--a-row:#F7F7F8;--a-row-2:#F0F0F2;--a-accent:var(--buoy-accent-strong,#0F766E);--a-blur:none;--a-success:#047857;--a-error:#B91C1C;--a-warn:#B45309;--a-info:#1D4ED8;",gt="--a-bg:#18181B;--a-fg:#F4F4F5;--a-fg2:#A1A1AA;--a-edge:#2E2E34;--a-shadow:0 14px 30px -14px rgba(0,0,0,.9),0 2px 6px -2px rgba(0,0,0,.5);--a-chip:#232328;--a-chip-2:#2C2C32;--a-primary:#F4F4F5;--a-primary-fg:#0B0B0C;--a-track:#2E2E34;--a-row:#1F1F23;--a-row-2:#26262B;--a-accent:var(--buoy-accent,#2DD4BF);--a-success:#34D399;--a-error:#F87171;--a-warn:#FBBF24;--a-info:#60A5FA;",ht='.buoy:is([data-buoy-theme="ink"],[data-buoy-theme="notch"])',Je='.buoy[data-buoy-theme="frost"]',Ze='.buoy[data-buoy-theme="paper"]',se='.buoy[data-buoy-theme="notch"]',et='.buoy[data-position="bottom"]',ze=(n,c)=>`.buoy[data-rich="true"][data-type="${n}"]{--a-fill:color-mix(in srgb,var(${c}) 20%,var(--a-bg));--a-edge:color-mix(in srgb,var(${c}) 32%,transparent)}`,Ne=['.buoy{position:fixed;left:50%;top:calc(var(--buoy-offset,12px) + env(safe-area-inset-top,0px));width:0;height:0;z-index:var(--buoy-z,2147483000);font-family:var(--buoy-font,ui-sans-serif,system-ui,-apple-system,"Segoe UI",Roboto,"Helvetica Neue",Arial,sans-serif);font-size:14px;font-weight:400;line-height:1.25;letter-spacing:normal;text-align:left;text-transform:none;-webkit-font-smoothing:antialiased;-webkit-tap-highlight-color:transparent;--a-bg:var(--buoy-ink,#0B0B0C);--a-fg:#fff;--a-fg2:rgba(255,255,255,.62);--a-edge:rgba(255,255,255,.07);--a-shadow:0 14px 30px -14px rgba(0,0,0,.55),0 2px 6px -2px rgba(0,0,0,.25);--a-chip:rgba(255,255,255,.1);--a-chip-2:rgba(255,255,255,.16);--a-primary:#fff;--a-primary-fg:#0B0B0C;--a-track:rgba(255,255,255,.16);--a-row:rgba(255,255,255,.05);--a-row-2:rgba(255,255,255,.09);--a-accent:var(--buoy-accent,#2DD4BF);--a-blur:none;--a-success:#34D399;--a-error:#F87171;--a-warn:#FBBF24;--a-info:#60A5FA;--a-fill:var(--a-bg);--a-danger:#DC2626;--buoy-bg:var(--a-bg);--buoy-fg:var(--a-fg);--buoy-fg-2:var(--a-fg2);--buoy-chip:var(--a-chip);--buoy-chip-2:var(--a-chip-2);--buoy-track:var(--a-track);--buoy-tint:var(--a-accent);--buoy-success:var(--a-success);--buoy-error:var(--a-error);--buoy-warn:var(--a-warn)}',`${ht}[data-scheme="dark"]{${bt}}`,`@media (prefers-color-scheme:dark){${ht}[data-scheme="system"]{${bt}}}`,`${Je}{${Yt}}`,`${Je}[data-scheme="dark"]{${yt}}`,`@media (prefers-color-scheme:dark){${Je}[data-scheme="system"]{${yt}}}`,`${Ze}{${Gt}}`,`${Ze}[data-scheme="dark"]{${gt}}`,`@media (prefers-color-scheme:dark){${Ze}[data-scheme="system"]{${gt}}}`,ze("success","--a-success"),ze("error","--a-error"),ze("warning","--a-warn"),ze("info","--a-info"),":where(.buoy) *,:where(.buoy) *::before,:where(.buoy) *::after{box-sizing:border-box}",":where(.buoy) button{margin:0;font:inherit;color:inherit;letter-spacing:inherit;text-transform:none;-webkit-appearance:none;appearance:none}",".buoy [hidden]{display:none!important}",`${se}{top:env(safe-area-inset-top,0px)}`,`${et}{top:auto;bottom:calc(var(--buoy-offset,12px) + env(safe-area-inset-bottom,0px))}`,`${se}[data-position="bottom"]{top:auto;bottom:env(safe-area-inset-bottom,0px)}`,".buoy-sr{position:absolute;width:1px;height:1px;overflow:hidden;clip-path:inset(50%);white-space:nowrap}",".buoy-stage,.buoy-drag,.buoy-goo{position:absolute;left:0;top:0;width:0;height:0}",".buoy-shadow,.buoy-bshadow,.buoy-fill,.buoy-bfill,.buoy-shell,.buoy-bubble{position:absolute;left:0;top:0}",`${et} :is(.buoy-stage,.buoy-drag,.buoy-goo,.buoy-shadow,.buoy-bshadow,.buoy-fill,.buoy-bfill,.buoy-shell,.buoy-bubble){top:auto;bottom:0}`,".buoy-bshadow,.buoy-bfill,.buoy-bubble{width:44px;height:44px}",".buoy-shadow,.buoy-bshadow{box-shadow:var(--a-shadow);pointer-events:none}",".buoy-fill,.buoy-bfill{background-color:var(--a-fill);-webkit-backdrop-filter:var(--a-blur);backdrop-filter:var(--a-blur);pointer-events:none;transition:background-color .25s ease}",".buoy-goo.is-gooey{filter:url(#buoy-goo)}",".buoy-shell{overflow:hidden;color:var(--a-fg);box-shadow:inset 0 0 0 1px var(--a-edge);isolation:isolate;touch-action:none;transition:box-shadow .25s ease}",".buoy-bubble{padding:0;border:0;background:transparent;box-shadow:inset 0 0 0 1px var(--a-edge);color:var(--a-fg);display:grid;place-items:center;cursor:pointer}",".buoy-bub-ic{display:grid;color:var(--a-error)}",".buoy-bub-ic svg{width:20px;height:20px}",".buoy-layer{position:absolute;left:50%;top:0;translate:-50% 0;width:max-content}",`${et} .buoy-layer{top:auto;bottom:0}`,`${se} :is(.buoy-fill,.buoy-bfill)::before,${se} :is(.buoy-fill,.buoy-bfill)::after{content:"";position:absolute;top:0;width:16px;height:16px;pointer-events:none}`,`${se} :is(.buoy-fill,.buoy-bfill)::before{left:-16px;background:radial-gradient(circle at 0 100%,transparent 15.5px,var(--a-fill) 16px)}`,`${se} :is(.buoy-fill,.buoy-bfill)::after{right:-16px;background:radial-gradient(circle at 100% 100%,transparent 15.5px,var(--a-fill) 16px)}`,`${se}[data-position="bottom"] :is(.buoy-fill,.buoy-bfill)::before{top:auto;bottom:0;background:radial-gradient(circle at 0 0,transparent 15.5px,var(--a-fill) 16px)}`,`${se}[data-position="bottom"] :is(.buoy-fill,.buoy-bfill)::after{top:auto;bottom:0;background:radial-gradient(circle at 100% 0,transparent 15.5px,var(--a-fill) 16px)}`,'.buoy [data-tone="success"]{--tone:var(--a-success)}','.buoy [data-tone="error"]{--tone:var(--a-error)}','.buoy [data-tone="warn"]{--tone:var(--a-warn)}','.buoy [data-tone="info"]{--tone:var(--a-info)}','.buoy [data-tone="accent"]{--tone:var(--a-accent)}',".buoy-row{display:flex;align-items:center;gap:10px;height:44px;padding:0 18px 0 6px;white-space:nowrap;font-size:14px;font-weight:500;letter-spacing:-.005em;color:var(--a-fg)}",".buoy-row.no-icon{padding-left:18px}",".buoy-row.end-action{padding-right:4px}",".buoy-row.end-ring{padding-right:8px}",".buoy-row.end-badge{padding-right:10px}","button.buoy-row{border:0;background:none;cursor:pointer;text-align:left}",".buoy-ic{width:32px;height:32px;flex:none;border-radius:999px;background:var(--a-chip);color:var(--a-fg);display:grid;place-items:center}",".buoy-ic svg{width:18px;height:18px}",'.buoy-ic[data-tone]:not([data-tone=""]),.buoy-tile[data-tone]:not([data-tone=""]){background:color-mix(in srgb,var(--tone) 17%,transparent);color:var(--tone)}',".buoy-title{overflow:hidden;text-overflow:ellipsis;max-width:min(260px,calc(100vw - 170px))}",".buoy-pct{margin-left:2px;min-width:3.4ch;text-align:right;font-size:13px;color:var(--a-fg2);font-variant-numeric:tabular-nums}",".buoy-badge{height:24px;padding:0 8px;border-radius:999px;background:var(--a-chip-2);font-size:12px;font-weight:600;display:inline-flex;align-items:center;font-variant-numeric:tabular-nums}",".buoy-act{flex:none;height:44px;padding:0 0 0 4px;border:0;background:none;display:flex;align-items:center;cursor:pointer}",".buoy-act>span{height:32px;padding:0 14px;border-radius:999px;background:var(--a-chip);font-size:13px;font-weight:600;display:flex;align-items:center;transition:background-color .15s ease}",".buoy-act:hover>span{background:var(--a-chip-2)}",".buoy-link{padding:0;border:0;background:none;cursor:pointer}",".buoy-rest{display:block;width:104px;height:30px;padding:0;border:0;background:none}","button.buoy-rest{cursor:pointer}",".buoy-ring{width:28px;height:28px;flex:none;transform:rotate(-90deg)}",".buoy-ring circle{fill:none;stroke-width:3.5}",".buoy-ring .trk{stroke:var(--a-track)}",".buoy-ring .val{stroke:var(--a-accent);stroke-linecap:round;transition:stroke-dashoffset .35s ease,opacity .2s ease}",".buoy-ring.is-muted .val{stroke:var(--a-fg2)}",".buoy-spin{animation:buoy-spin .9s linear infinite}","@keyframes buoy-spin{to{transform:rotate(360deg)}}",".buoy-ic .draw{stroke-dasharray:20;stroke-dashoffset:20;animation:buoy-draw .36s .1s cubic-bezier(.2,.8,.2,1) forwards}","@keyframes buoy-draw{to{stroke-dashoffset:0}}",".buoy-exp{width:min(380px,calc(100vw - 24px));padding:14px;display:flex;flex-direction:column;gap:12px;white-space:normal;color:var(--a-fg)}",".buoy-exp-head{display:flex;align-items:center;gap:12px}",".buoy-tile{width:44px;height:44px;flex:none;border-radius:14px;background:var(--a-chip);color:var(--a-fg);display:grid;place-items:center}",".buoy-tile svg{width:22px;height:22px}",".buoy-exp-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:3px}",".buoy-exp-title{font-size:15px;font-weight:600;letter-spacing:-.01em}",".buoy-exp-desc{font-size:13px;color:var(--a-fg2)}",".buoy-x{width:44px;height:44px;flex:none;padding:0;border:0;border-radius:999px;background:transparent;color:var(--a-fg2);display:grid;place-items:center;cursor:pointer}",".buoy-x:hover{color:var(--a-fg)}",".buoy-x svg{width:16px;height:16px}",".buoy-actions{display:flex;gap:8px}",".buoy-btn.is-danger{background:var(--a-danger);color:#fff}",".buoy-btn.is-danger:hover{background:var(--a-danger);opacity:.9}",".buoy-custom{display:block;color:var(--a-fg)}","button.buoy-custom{margin:0;padding:0;border:0;background:none;font:inherit;letter-spacing:inherit;text-align:inherit;cursor:pointer}",".buoy-custom:focus{outline:none}","button.buoy-custom:focus-visible{outline:2px solid var(--a-accent);outline-offset:-3px;border-radius:999px}",".buoy-btn{flex:1;height:44px;border:0;border-radius:999px;background:var(--a-chip);color:var(--a-fg);font-size:14px;font-weight:600;line-height:1;cursor:pointer;transition:background-color .15s ease}",".buoy-btn:hover{background:var(--a-chip-2)}",".buoy-btn.is-primary{background:var(--a-primary);color:var(--a-primary-fg)}",".buoy-btn.is-primary:hover{background:var(--a-primary);opacity:.9}",".buoy-tray{width:min(420px,calc(100vw - 16px));padding:8px;display:flex;flex-direction:column;gap:4px;white-space:normal;color:var(--a-fg)}",".buoy-tray-head{display:flex;align-items:center;justify-content:space-between;gap:8px;padding:2px 2px 2px 14px}",".buoy-tray-titles{display:flex;flex-direction:column;gap:2px;min-width:0}",".buoy-tray-title{font-size:15px;font-weight:600;letter-spacing:-.01em}",".buoy-tray-sub{font-size:12px;color:var(--a-fg2)}",".buoy-tray-tools{display:flex;align-items:center;flex:none}",".buoy-list{list-style:none;margin:0;padding:0;display:flex;flex-direction:column;gap:4px;max-height:min(52vh,420px);overflow-y:auto;overscroll-behavior:contain;touch-action:pan-y}",".buoy-task{display:flex;align-items:center;gap:12px;padding:10px 2px 10px 10px;border-radius:22px;background:var(--a-row)}",".buoy-task:hover,.buoy-task:focus-within{background:var(--a-row-2)}",'.buoy-task[data-status="failed"]{background:color-mix(in srgb,var(--a-error) 9%,transparent)}',".buoy-tile.sm{width:40px;height:40px;border-radius:12px}",".buoy-tile.sm svg{width:20px;height:20px}",".buoy-task-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:6px}",".buoy-task-top{display:flex;justify-content:space-between;align-items:baseline;gap:8px}",".buoy-task-name{font-size:14px;font-weight:500;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",".buoy-task-state{flex:none;font-size:12px;font-weight:500;color:var(--a-fg2);font-variant-numeric:tabular-nums}",".buoy-task-state.is-error{color:var(--a-error);font-weight:600}",".buoy-bar{height:4px;border-radius:999px;background:var(--a-track);overflow:hidden}",".buoy-bar>i{display:block;height:100%;border-radius:inherit;background:var(--a-accent);transition:width .3s ease}",'.buoy-task[data-status="paused"] .buoy-bar>i{background:var(--a-fg2)}','.buoy-task[data-status="failed"] .buoy-bar>i{background:var(--a-error)}',".buoy-task-meta{font-size:12px;color:var(--a-fg2);font-variant-numeric:tabular-nums;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}",".buoy-task-actions{display:flex;flex:none}",".buoy-ib{width:44px;height:44px;padding:0;border:0;background:transparent;color:var(--a-fg);display:grid;place-items:center;cursor:pointer}",".buoy-ib>span{width:32px;height:32px;border-radius:999px;background:var(--a-chip);display:grid;place-items:center;transition:background-color .15s ease}",".buoy-ib:hover>span{background:var(--a-chip-2)}",".buoy-ib svg{width:14px;height:14px}",".buoy-task-actions .buoy-ib+.buoy-ib{margin-left:-8px}",".buoy-reveal{display:none}",".buoy-task:hover .buoy-reveal,.buoy-task:focus-within .buoy-reveal{display:grid}","@media (hover:none){.buoy-reveal{display:grid}}",".buoy-tray-foot{display:flex;align-items:center;gap:10px;padding:2px 2px 0 14px;font-size:12px;color:var(--a-fg2)}",".buoy-tray-foot>svg{width:16px;height:16px;flex:none}",".buoy-tray-foot>span{flex:1}",".buoy-empty{margin:0;padding:14px;font-size:13px;color:var(--a-fg2)}",".buoy button:focus-visible{outline:none}",".buoy button:focus-visible>span,.buoy .buoy-btn:focus-visible,.buoy .buoy-x:focus-visible,.buoy .buoy-link:focus-visible,.buoy .buoy-bubble:focus-visible,.buoy button.buoy-rest:focus-visible{outline:2px solid var(--a-accent);outline-offset:2px}",".buoy button.buoy-live:focus-visible{outline:2px solid var(--a-accent);outline-offset:-3px;border-radius:999px}","@media (prefers-reduced-motion:reduce){.buoy-spin{animation-duration:1.8s}.buoy-ic .draw{animation:none;stroke-dashoffset:0}.buoy-ring .val,.buoy-bar>i{transition:none}}"].join(`
|
|
2
|
+
`);function mt(n,c){if(n.querySelector("style[data-buoy]"))return;let r=n.createElement("style");r.setAttribute("data-buoy",""),c&&(r.nonce=c),r.textContent=Ne;let g=n.head||n.getElementsByTagName("head")[0]||n.documentElement;g.insertBefore(r,g.firstChild)}var xt={link:'<path d="M10 14a4.5 4.5 0 0 0 6.4 0l3-3a4.5 4.5 0 0 0-6.4-6.4l-1.1 1.1"/><path d="M14 10a4.5 4.5 0 0 0-6.4 0l-3 3a4.5 4.5 0 0 0 6.4 6.4l1.1-1.1"/>',check:'<path class="draw" d="M5.5 12.5l4 4L18.5 7.5"/>',error:'<circle cx="12" cy="12" r="8.5"/><path d="M12 8v4.5"/><path d="M12 16h.01"/>',warning:'<path d="M10.3 4.6 3 17.5a2 2 0 0 0 1.7 3h14.6a2 2 0 0 0 1.7-3L13.7 4.6a2 2 0 0 0-3.4 0z"/><path d="M12 9.5v4"/><path d="M12 17h.01"/>',info:'<circle cx="12" cy="12" r="8.5"/><path d="M12 11v5"/><path d="M12 7.8h.01"/>',upload:'<path d="M12 15V4.5"/><path d="M7.5 9 12 4.5 16.5 9"/><path d="M4.5 15v2.5a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V15"/>',download:'<path d="M12 4.5V15"/><path d="M7.5 10.5 12 15l4.5-4.5"/><path d="M4.5 15v2.5a2 2 0 0 0 2 2h11a2 2 0 0 0 2-2V15"/>',file:'<path d="M14 3.5H7.5a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V8z"/><path d="M14 3.5V8h4.5"/><path d="M9 13h6"/><path d="M9 16.5h4"/>',archive:'<path d="M14 3.5H7.5a2 2 0 0 0-2 2v13a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2V8z"/><path d="M14 3.5V8h4.5"/><path d="M11 9.5h2"/><path d="M11 12.5h2"/><path d="M11 15.5h2"/>',image:'<rect x="3.5" y="4.5" width="17" height="15" rx="2.5"/><circle cx="9" cy="10" r="1.75"/><path d="m20.5 15.5-4.5-4.5-8.5 8.5"/>',send:'<path d="M20.5 3.5 10 14"/><path d="m20.5 3.5-6.5 17-4-6.5-6.5-4z"/>',folder:'<path d="M3.5 7.5a2 2 0 0 1 2-2h3.6l2 2h7.4a2 2 0 0 1 2 2v8a2 2 0 0 1-2 2h-13a2 2 0 0 1-2-2z"/>',copy:'<rect x="8.5" y="8.5" width="11" height="11" rx="2.5"/><path d="M15.5 8.5v-2a2 2 0 0 0-2-2h-7a2 2 0 0 0-2 2v7a2 2 0 0 0 2 2h2"/>',stack:'<path d="m12 4 8 4.5-8 4.5-8-4.5z"/><path d="m4 13 8 4.5 8-4.5"/>',bell:'<path d="M6 16v-5a6 6 0 0 1 12 0v5l1.5 2h-15z"/><path d="M10 20.5a2 2 0 0 0 4 0"/>',timer:'<circle cx="12" cy="13.5" r="7.5"/><path d="M12 10v3.5l2.5 2"/><path d="M9.5 3h5"/>',user:'<circle cx="12" cy="8.5" r="3.5"/><path d="M5 19.5a7 7 0 0 1 14 0"/>',pause:'<path d="M9 6v12"/><path d="M15 6v12"/>',play:'<path d="M8.5 6v12l9.5-6z" fill="currentColor"/>',retry:'<path d="M4.5 12a7.5 7.5 0 1 0 2.2-5.3"/><path d="M4.5 4.5v4h4"/>',x:'<path d="m6.5 6.5 11 11"/><path d="m17.5 6.5-11 11"/>',open:'<path d="M7 17 17 7"/><path d="M9 7h8v8"/>',up:'<path d="M6.5 14.5 12 9l5.5 5.5"/>',down:'<path d="M6.5 9.5 12 15l5.5-5.5"/>'},Ut='<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true" focusable="false">';function V(n){return n?Object.prototype.hasOwnProperty.call(xt,n)?`${Ut}${xt[n]}</svg>`:/^\s*<svg[\s>]/i.test(n)?n:"":""}var vt='<svg class="buoy-spin" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" aria-hidden="true" focusable="false"><circle cx="12" cy="12" r="8.5" opacity=".22"/><path d="M12 3.5a8.5 8.5 0 0 1 8.5 8.5"/></svg>',kt=2*Math.PI*10.5,wt=n=>(kt*(1-Math.min(1,Math.max(0,n)))).toFixed(2);function tt(n,c){return`<svg class="buoy-ring${c?" is-muted":""}" viewBox="0 0 28 28" aria-hidden="true" focusable="false"><circle class="trk" cx="14" cy="14" r="10.5"/><circle class="val" cx="14" cy="14" r="10.5" style="stroke-dasharray:${kt.toFixed(2)};stroke-dashoffset:${wt(n)};opacity:${n>.004?1:0}"/></svg>`}function nt(n,c){let r=n&&n.querySelector(".val");r&&(r.style.strokeDashoffset=wt(c),r.style.opacity=c>.004?"1":"0")}var K={enter:[420,32],resize:[320,30],expand:[300,28],tray:[260,26],bubble:[380,22],drag:[420,34]},at=44,Mt=8,Wt={success:"check",error:"error",warning:"warning",info:"info"},Qt={success:"success",error:"error",warning:"warn",info:"info"},Xt={accent:"accent",success:"success",error:"error",warning:"warn",info:"info"},Jt='<div class="buoy-sr" role="status" aria-live="polite" aria-atomic="true"></div><div class="buoy-stage" hidden><div class="buoy-drag"><div class="buoy-shadow"></div><div class="buoy-bshadow"></div><div class="buoy-goo"><div class="buoy-fill"></div><div class="buoy-bfill"></div></div><div class="buoy-shell"></div><button class="buoy-bubble" type="button" data-act="bubble" tabindex="-1" aria-hidden="true"></button></div></div>',Zt='<svg data-buoy-goo aria-hidden="true" width="0" height="0" style="position:absolute;width:0;height:0;overflow:hidden"><defs><filter id="buoy-goo" filterUnits="userSpaceOnUse" x="-700" y="-700" width="1400" height="1400" color-interpolation-filters="sRGB"><feGaussianBlur in="SourceGraphic" stdDeviation="7" result="b"/><feColorMatrix in="b" mode="matrix" values="1 0 0 0 0 0 1 0 0 0 0 0 1 0 0 0 0 0 22 -9" result="g"/><feComposite in="SourceGraphic" in2="g" operator="atop"/></filter></defs></svg>';function Tt(n,c={}){let r=document,g=window,{cfg:y,state:p}=n,D=typeof g.matchMedia=="function"?g.matchMedia("(prefers-reduced-motion: reduce)"):null,T=()=>!!(D&&D.matches),h=()=>g.performance?g.performance.now():Date.now(),G=typeof g.requestAnimationFrame=="function"?t=>g.requestAnimationFrame(t):t=>g.setTimeout(()=>t(h()),16),Oe=typeof g.cancelAnimationFrame=="function"?t=>g.cancelAnimationFrame(t):t=>g.clearTimeout(t),Ae=typeof r.documentElement.animate=="function",U=(t,o,u)=>Ae?t.animate(o,u):null,k=r.createElement("div");k.className="buoy",k.innerHTML=Jt;let F=t=>k.querySelector(t),W=F(".buoy-sr"),H=F(".buoy-stage"),Ve=F(".buoy-drag"),Le=F(".buoy-goo"),I=F(".buoy-shell"),A=F(".buoy-bubble"),Ke=[F(".buoy-shadow"),F(".buoy-fill"),I],ie=[F(".buoy-bshadow"),F(".buoy-bfill"),A],ve=r.createElement("div");ve.innerHTML=Zt;let be=ve.firstElementChild,Z=t=>({x:t,v:0,t,k:320,c:30}),R={w:Z(44),h:Z(44),r:Z(22),p:Z(0),dy:Z(0)},Fe=Object.keys(R),ee=0,ke=0;function je(){ee||(ke=h(),ee=G(ye))}function ye(t){let o=Math.min(.05,Math.max(0,(t-ke)/1e3));ke=t;let u=Math.max(1,Math.ceil(o*240)),s=o/u,l=!1;for(let f of Fe){let b=R[f];if(b.x===b.t&&b.v===0)continue;for(let z=0;z<u;z++){let pe=-b.k*(b.x-b.t)-b.c*b.v;b.v+=pe*s,b.x+=b.v*s}let w=f==="p"?.002:.25;Math.abs(b.x-b.t)<w&&Math.abs(b.v)<w*4?(b.x=b.t,b.v=0):l=!0}te(),ee=l?G(ye):0}function j(t,o,u){let s=R[t];if(!(s.t===o&&s.k===u[0]&&s.c===u[1])){if(s.t=o,s.k=u[0],s.c=u[1],T()){s.x=o,s.v=0,te();return}je()}}function Q(t,o){let u=R[t];u.x=u.t=o,u.v=0}function te(){let t=Math.max(0,R.w.x),o=Math.max(0,R.h.x),u=Math.min(Math.max(0,R.r.x),Math.min(t,o)/2),s=R.p.x,l=-t/2-(at+Mt)/2*Math.min(Math.max(s,0),1.25),f=y.theme==="notch",b=y.position==="bottom",w=f?b?`${u}px ${u}px 0 0`:`0 0 ${u}px ${u}px`:`${u}px`;for(let S of Ke){let O=S.style;O.transform=`translateX(${l.toFixed(2)}px)`,O.width=`${t.toFixed(2)}px`,O.height=`${o.toFixed(2)}px`,O.borderRadius=w}let z=l+t-at+(at+Mt)*s,pe=.4+.6*Math.min(Math.max(s,0),1.2),fe=Math.min(Math.max(s*2.2,0),1),Se=f?b?"22px 22px 0 0":"0 0 22px 22px":"22px";for(let S of ie){let O=S.style;O.transform=`translateX(${z.toFixed(2)}px) scale(${pe.toFixed(3)})`,O.opacity=fe.toFixed(3),O.borderRadius=Se,O.visibility=fe<.01?"hidden":"visible"}Ve.style.transform=R.dy.x?`translateY(${R.dy.x.toFixed(2)}px)`:"",Le.classList.toggle("is-gooey",(y.theme==="ink"||f)&&s>.02&&s<.97&&!T())}let N=(t,o,u,s,l,f=!1)=>`<button type="button" class="buoy-ib${f?" buoy-reveal":""}" data-act="${o}" data-id="${t.id}" data-fk="${u}:${t.id}" aria-label="${s} ${L(t.label)}"><span>${V(l)}</span></button>`,ge=t=>!!(t.description||t.actions&&t.actions.length),X=!1;function _e(t){if(t.render)return Ce(t);let o=ge(t)&&(t.expanded||t.tapped||X&&y.expandOnHover),u=Qt[t.type]||Xt[t.tone]||"",s=t.type==="loading"?vt:V(t.icon===void 0?Wt[t.type]:t.icon),l;if(o){let f=(t.actions||[]).map((b,w)=>`<button type="button" class="buoy-btn${b.primary?" is-primary":""}" data-act="action" data-i="${w}" data-fk="a${w}">${L(b.label)}</button>`).join("");l=`<div class="buoy-exp"><div class="buoy-exp-head"><span class="buoy-tile" data-tone="${u}">${s||V("info")}</span><div class="buoy-exp-text"><span class="buoy-exp-title">${L(t.title)}</span>${t.description?`<span class="buoy-exp-desc">${L(t.description)}</span>`:""}</div><button type="button" class="buoy-x" data-act="dismiss" data-fk="x" aria-label="Dismiss">${V("x")}</button></div>${f?`<div class="buoy-actions">${f}</div>`:""}</div>`}else{let f=p.queue.length,b=t.action?`<button type="button" class="buoy-act" data-act="action" data-i="-1" data-fk="a-1"><span>${L(t.action.label)}</span></button>`:"",w=!b&&f?`<span class="buoy-badge" title="${f} waiting">+${f}</span>`:"";l=`<div class="${`buoy-row${s?"":" no-icon"}${b?" end-action":w?" end-badge":""}`}">${s?`<span class="buoy-ic" data-tone="${u}">${s}</span>`:""}<span class="buoy-title">${L(t.title)}</span>${w}${b}</div>`}return{kind:"msg",key:`m:${t.id}:${t.type}:${o?"x":"c"}`,sig:l,html:l,type:t.type,expanded:o,radius:o?28:null,spring:o?K.expand:K.resize}}function Ce(t){let o=t.expandable&&t.open,u=L(t.title),s=o?`<div class="buoy-custom is-expanded" role="group" aria-label="${u}" tabindex="-1" data-fk="live-x"></div>`:t.expandable?`<button type="button" class="buoy-custom" data-act="live-open" data-fk="live-c" aria-expanded="false" aria-label="${u}. Show details"></button>`:`<div class="buoy-custom" role="group" aria-label="${u}"></div>`;return{kind:"msg",key:`l:${t.id}:${o?"x":"c"}`,sig:s,html:s,type:"live",expanded:o,radius:o?28:null,spring:o?K.expand:K.resize,patch:l=>Ye(l,t,o)}}function Ye(t,o,u){let s=t.querySelector(".buoy-custom");if(!s||!o.render)return;let l=`${o.rev}:${u?1:0}`;if(s.getAttribute("data-rev")!==l){s.setAttribute("data-rev",l);try{o.render(s,{expanded:u})}catch(f){typeof console!="undefined"&&console.error(f),s.textContent=o.title}}}function ne(t){let o=n.aggregate(),u=t.every(w=>w.status==="paused"),s=y.labels.active(t.map(n.info)),l=u?`Paused \xB7 ${s}`:s,f=`<button type="button" class="buoy-row end-ring buoy-live" data-act="open-tray" data-fk="live" aria-label="${L(l)}. Show details"><span class="buoy-ic" data-tone="${u?"":"accent"}">${V(u?"pause":y.taskIcon)}</span><span class="buoy-title">${L(l)}</span><span class="buoy-pct">${Math.round(o*100)}%</span>${tt(o,u)}</button>`,b=w=>{let z=w.querySelector(".buoy-pct");z&&(z.textContent=`${Math.round(o*100)}%`),nt(w.querySelector(".buoy-ring"),o)};return{kind:"live",key:"live",sig:`live|${l}|${u}`,html:f,type:"",expanded:!1,radius:null,spring:K.resize,patch:b}}function we(t){let o=t.length,u=`${o} ${y.labels.noun}${o===1?"":"s"} failed`,s=`<div class="buoy-row end-action"><span class="buoy-ic" data-tone="error">${V("error")}</span><button type="button" class="buoy-link buoy-title" data-act="open-tray" data-fk="att">${L(u)}</button><button type="button" class="buoy-act" data-act="retry-failed" data-fk="att-retry"><span>Retry</span></button></div>`;return{kind:"attention",key:"attention",sig:s,html:s,type:"error",expanded:!1,radius:null,spring:K.resize}}function Me(){let t=p.tasks.length?'<button type="button" class="buoy-rest" data-act="open-tray" data-fk="rest" aria-label="Show activity"></button>':'<div class="buoy-rest"></div>';return{kind:"rest",key:"rest",sig:t,html:t,type:"",expanded:!1,radius:15,spring:K.resize}}function Be(t){let o=t.status,s=`<span class="buoy-tile sm" data-tone="${o==="failed"?"error":o==="done"?"success":""}">${V(o==="done"?"check":t.icon)||V("file")}</span>`,l=o==="done"||o==="queued"?"":`<div class="buoy-bar"><i style="width:${(J(t)*100).toFixed(1)}%"></i></div>`,f="";return o==="running"?f=N(t,"cancel","c","Cancel","x",!0)+(t.pausable?N(t,"pause","p","Pause","pause"):""):o==="queued"?f=N(t,"cancel","c","Cancel","x"):o==="paused"?f=N(t,"cancel","c","Cancel","x",!0)+N(t,"resume","p","Resume","play"):o==="failed"?f=N(t,"remove","c","Remove","x",!0)+N(t,"retry","p","Retry","retry"):o==="done"&&t.onOpen&&(f=N(t,"open","p","Open","open")),`<li class="buoy-task" data-id="${t.id}" data-status="${o}">${s}<div class="buoy-task-main"><div class="buoy-task-top"><span class="buoy-task-name">${L(t.label)}</span><span class="buoy-task-state${o==="failed"?" is-error":""}">${L(Qe(t))}</span></div>${l}<span class="buoy-task-meta">${L(Xe(t))}</span></div><div class="buoy-task-actions">${f}</div></li>`}function Te(){let{counts:t,text:o}=n.summary(),u=t.running+t.queued+t.paused,s=y.position==="bottom",l=S=>`${y.labels.noun}${S===1?"":"s"}`,f=t.done?'<button type="button" class="buoy-act" data-act="clear-done" data-fk="clear"><span>Clear done</span></button>':"",b=`<div class="buoy-tray-head"><div class="buoy-tray-titles"><span class="buoy-tray-title">Activity</span><span class="buoy-tray-sub">${L(o||"Nothing here yet")}</span></div><div class="buoy-tray-tools">${f}<button type="button" class="buoy-ib" data-act="close-tray" data-fk="close" aria-label="Close"><span>${V(s?"down":"up")}</span></button></div></div>`,w=p.tasks.length?`<ul class="buoy-list">${p.tasks.map(Be).join("")}</ul>`:'<p class="buoy-empty">Tasks you start show up here.</p>',z="";if(y.guard&&u){let S=t.running?'<button type="button" class="buoy-act" data-act="pause-all" data-fk="all"><span>Pause all</span></button>':t.paused?'<button type="button" class="buoy-act" data-act="resume-all" data-fk="all"><span>Resume all</span></button>':"";z=`<div class="buoy-tray-foot">${V("info")}<span>Closing this tab stops ${u} ${l(u)}.</span>${S}</div>`}let pe=`<div class="buoy-tray" role="dialog" aria-label="Activity">${b}${w}${z}</div>`,fe=["tray",s,y.guard,u,t.running>0,t.paused>0,t.done>0,p.tasks.map(S=>S.id+S.status).join(",")].join("|"),Se=S=>{for(let Y of p.tasks){let Re=S.querySelector(`.buoy-task[data-id="${Y.id}"]`);if(!Re)continue;let st=Re.querySelector(".buoy-task-state");st&&(st.textContent=Qe(Y));let it=Re.querySelector(".buoy-bar > i");it&&(it.style.width=`${(J(Y)*100).toFixed(1)}%`);let lt=Re.querySelector(".buoy-task-meta");lt&&(lt.textContent=Xe(Y))}let O=S.querySelector(".buoy-tray-sub");O&&(O.textContent=o||"Nothing here yet")};return{kind:"tray",key:"tray",sig:fe,html:pe,type:"",expanded:!1,radius:30,spring:K.tray,patch:Se}}let $=null,x=null,_=!1,ae=null,le=0,oe="",$e=null;function he(){le||(le=G(()=>{le=0,ue()}))}function ue(){let t=n.active(),o=n.failed(),u=o.length>0&&!p.attentionDismissed,s=p.current?p.current.id:null;s!==$e&&(X=!1,$e=s);let l,f=!1;if(p.trayOpen?l=Te():p.current?(l=_e(p.current),f=t.length>0||u):t.length?l=ne(t):u?l=we(o):l=Me(),k.dataset.kind=l.kind,k.dataset.type=l.type,l.kind==="rest"&&y.resting==="hidden"){E(!1,t),m();return}let b=!_;b&&i();let w=Y=>Y.slice(0,Y.lastIndexOf(":")),z=!!$&&$.type==="live"&&l.type==="live"&&$.expanded!==l.expanded&&w($.key)===w(l.key),pe=!!x&&x.contains(r.activeElement);if(!$||!x||$.key!==l.key?e(l):$.sig!==l.sig&&a(l),l.patch&&x&&l.patch(x),z&&pe&&x){let Y=x.querySelector('[data-fk="live-x"], [data-fk="live-c"]');Y&&Y.focus({preventScroll:!0})}$=l;let fe=x,Se=fe.offsetWidth,S=fe.offsetHeight,O=b?K.enter:l.spring;j("w",Se,O),j("h",S,O),j("r",l.radius==null?S/2:l.radius,O),E(f,t),I.style.cursor=l.kind==="msg"&&!l.expanded&&p.current&&p.current.type!=="loading"&&p.current.type!=="live"?"pointer":""}function e(t){let o=x,u=r.createElement("div");u.className="buoy-layer",u.innerHTML=t.html,I.appendChild(u),x=u;let s=T();if(o){o.inert=!0,o.setAttribute("aria-hidden","true");let l=U(o,s?[{opacity:1},{opacity:0}]:[{opacity:1,filter:"blur(0px)",transform:"scale(1)"},{opacity:0,filter:"blur(2px)",transform:"scale(.96)"}],{duration:s?80:120,easing:"ease-in",fill:"forwards"});l?l.onfinish=()=>o.remove():o.remove()}U(u,s?[{opacity:0},{opacity:1}]:[{opacity:0,filter:"blur(2px)",transform:"scale(.96)"},{opacity:1,filter:"blur(0px)",transform:"scale(1)"}],{duration:s?120:200,delay:o?60:40,easing:"cubic-bezier(.2,.8,.2,1)",fill:"backwards"})}function a(t){if(!x)return;let o=r.activeElement,u=o&&x.contains(o)?o.getAttribute("data-fk"):null,s=x.querySelector(".buoy-list"),l=s?s.scrollTop:0;x.innerHTML=t.html;let f=x.querySelector(".buoy-list");if(f&&l&&(f.scrollTop=l),u){let b=Array.from(x.querySelectorAll("[data-fk]")).find(w=>w.getAttribute("data-fk")===u);b&&b.focus({preventScroll:!0})}}function i(){if(_=!0,ae&&(ae.cancel(),ae=null),H.hidden=!1,T()){U(H,[{opacity:0},{opacity:1}],{duration:150});return}let t=y.theme==="notch",o=y.position==="bottom";U(H,t?[{transform:`translateY(${o?60:-60}px)`},{transform:"translateY(0px)"}]:[{opacity:0,transform:"scale(.6)"},{opacity:1,transform:"scale(1)"}],{duration:t?380:340,easing:"cubic-bezier(.2,.9,.25,1.12)"})}function d(){Q("w",44),Q("h",44),Q("r",22),Q("p",0),te()}function m(){if(!_)return;_=!1,Ge();let t=x;if(x=null,$=null,t){t.inert=!0,t.setAttribute("aria-hidden","true");let b=U(t,[{opacity:1},{opacity:0}],{duration:120,fill:"forwards"});b?b.onfinish=()=>t.remove():t.remove()}let o=y.theme==="notch",u=y.position==="bottom",s=T()?[{opacity:1},{opacity:0}]:o?[{transform:"translateY(0px)"},{transform:`translateY(${((u?1:-1)*(R.h.x+24)).toFixed(1)}px)`}]:[{opacity:1,transform:"scale(1)",filter:"blur(0px)"},{opacity:0,transform:"scale(.92)",filter:"blur(4px)"}],l=U(H,s,{duration:o?220:180,easing:"cubic-bezier(.4,0,1,1)",fill:"forwards"}),f=()=>{_||(H.hidden=!0,l&&l.cancel(),ae=null,d())};l?(ae=l,l.onfinish=()=>{ae===l&&f()}):f()}function E(t,o){if(t){if(o.length){let u=n.aggregate(),s=o.every(f=>f.status==="paused"),l=`ring|${s}`;oe!==l?(A.innerHTML=tt(u,s),oe=l):nt(A.querySelector(".buoy-ring"),u),A.setAttribute("aria-label",`${y.labels.active(o.map(n.info))}. Show details`)}else oe!=="attention"&&(A.innerHTML=`<span class="buoy-bub-ic">${V("error")}</span>`,oe="attention",A.setAttribute("aria-label",`A ${y.labels.noun} needs attention. Show details`));A.tabIndex=0,A.removeAttribute("aria-hidden")}else A.tabIndex=-1,A.setAttribute("aria-hidden","true");j("p",t?1:0,K.bubble)}function v(t){let o=[t.title,t.description].filter(Boolean).join(". ");W.textContent="",g.setTimeout(()=>{W.textContent=o},40)}let M=y.position;function C(){k.dataset.buoyTheme=y.theme,k.dataset.position=y.position,k.dataset.rich=y.richColors?"true":"false",k.dataset.scheme=y.colorScheme,y.offset!=null?k.style.setProperty("--buoy-offset",`${y.offset}px`):k.style.removeProperty("--buoy-offset"),te(),M!==y.position&&_&&!T()&&U(H,[{opacity:0},{opacity:1}],{duration:220}),M=y.position}let me=[];function B(t,o,u,s){let l=u;t.addEventListener(o,l,s),me.push(()=>t.removeEventListener(o,l,s))}let ce=null;function Pe(t){p.trayOpen||(ce=r.activeElement,X=!1,n.openTray(),t&&G(()=>G(()=>{let o=x&&x.querySelector('[data-fk="close"]');o&&o.focus({preventScroll:!0})})))}function re(){if(!p.trayOpen)return;let t=k.contains(r.activeElement);n.closeTray(),t&&G(()=>G(()=>{let u=x&&x.querySelector('[data-fk="live"], [data-fk="att"], [data-fk="rest"]')||(ce instanceof HTMLElement&&ce.isConnected?ce:null);u&&u.focus({preventScroll:!0})}))}function Ee(){p.trayOpen?re():p.current&&p.current.type==="live"?n.setOpen(p.current.id,!1):p.current?n.dismiss(p.current.id):$&&$.kind==="attention"&&n.dismissAttention()}function Et(t,o){let u=o.detail===0,s=t.getAttribute("data-id")||"",l=p.current;switch(t.getAttribute("data-act")){case"dismiss":l&&n.dismiss(l.id);break;case"action":{if(!l)break;let f=Number(t.getAttribute("data-i")),b=f<0?l.action:l.actions&&l.actions[f];n.dismiss(l.id),b&&b.onClick&&b.onClick();break}case"live-open":l&&n.setOpen(l.id,!0);break;case"open-tray":case"bubble":Pe(u);break;case"close-tray":re();break;case"retry-failed":n.retryFailed();break;case"pause":n.pauseTask(s);break;case"resume":n.resumeTask(s);break;case"cancel":n.cancelTask(s);break;case"retry":n.retryTask(s);break;case"remove":n.removeTask(s);break;case"open":{let f=p.tasks.find(b=>b.id===s);re(),f&&f.onOpen&&f.onOpen(n.info(f));break}case"clear-done":n.clearDone();break;case"pause-all":n.pauseAll();break;case"resume-all":n.resumeAll();break;default:break}}let De=!1;B(k,"click",t=>{if(De){De=!1,t.preventDefault(),t.stopPropagation();return}let o=t.target,u=o.closest("[data-act]");if(u&&k.contains(u)){Et(u,t);return}if(!$||$.kind!=="msg"||$.expanded||!I.contains(o)||o.closest(".buoy-custom"))return;let s=p.current;!s||s.type==="live"||!$.key.startsWith(`m:${s.id}:`)||(ge(s)?n.tap(s.id):s.type!=="loading"&&n.dismiss(s.id))});let de=!1,He=0,Ie=0;function Ge(){de&&(de=!1,n.setPaused("hover",!1),g.clearTimeout(He),X&&(g.clearTimeout(Ie),Ie=g.setTimeout(()=>{de||(X=!1,he())},300)))}B(H,"pointerenter",t=>{if(t.pointerType!=="mouse")return;de=!0,n.setPaused("hover",!0),g.clearTimeout(Ie);let o=p.current;o&&y.expandOnHover&&ge(o)&&!o.expanded&&!X&&(g.clearTimeout(He),He=g.setTimeout(()=>{de&&p.current===o&&(X=!0,he())},120))}),B(H,"pointerleave",t=>{t.pointerType==="mouse"&&Ge()});let q=null;B(I,"pointerdown",t=>{t.button!==0||t.target.closest(".buoy-list")||(q={id:t.pointerId,y:t.clientY,t:h(),dy:0,active:!1})}),B(g,"pointermove",t=>{if(de&&t.pointerType==="mouse"&&!H.contains(t.target)&&Ge(),!q||t.pointerId!==q.id)return;let o=t.clientY-q.y,u=y.position==="bottom"?1:-1;if(!q.active&&Math.abs(o)>6){q.active=!0;try{I.setPointerCapture(t.pointerId)}catch{}}if(!q.active)return;let s=o*u;q.dy=(s>0?s:s*.2)*u,Q("dy",q.dy),te()});let ot=t=>{if(!q||t.pointerId!==q.id)return;let o=q;if(q=null,!o.active)return;De=!0,g.setTimeout(()=>{De=!1},0);let u=y.position==="bottom"?1:-1,s=o.dy*u,l=s/Math.max(1,h()-o.t);(s>28||l>.45)&&Ee(),j("dy",0,K.drag)};if(B(g,"pointerup",ot),B(g,"pointercancel",ot),B(r,"keydown",t=>{t.key==="Escape"&&(p.trayOpen?(t.preventDefault(),re()):(k.contains(r.activeElement)||de)&&Ee())}),B(r,"pointerdown",t=>{k.contains(t.target)||(p.trayOpen?re():p.current&&p.current.open&&n.setOpen(p.current.id,!1))},{capture:!0}),B(r,"visibilitychange",()=>n.setPaused("hidden",r.hidden)),B(g,"beforeunload",t=>{y.guard&&n.active().length&&(t.preventDefault(),t.returnValue="")}),D&&typeof D.addEventListener=="function"){let t=()=>te();D.addEventListener("change",t),me.push(()=>D.removeEventListener("change",t))}let St=n.subscribe((t,o)=>{t==="show"&&o&&v(o),t==="config"&&C(),he()});(c.container||r.body).appendChild(k),r.body.appendChild(be),C(),n.setPaused("hidden",r.hidden),n.setPaused("detached",!1),p.current&&v(p.current),he();let rt=!1;return{element:k,destroy(){rt||(rt=!0,St(),me.forEach(t=>t()),ee&&Oe(ee),le&&Oe(le),g.clearTimeout(He),g.clearTimeout(Ie),n.setPaused("hover",!1),n.setPaused("hidden",!1),n.setPaused("detached",!0),k.remove(),be.remove())}}}function $t(n={}){let{container:c,injectStyles:r=!0,nonce:g,...y}=n,p=qe(),D=h=>p.store.configure(h);if(p.store.configure(y),typeof document=="undefined")return{configure:D,destroy(){}};if(p.island)return!p.warned&&typeof console!="undefined"&&(p.warned=!0,console.warn("[buoy] An island is already mounted. Only one is shown at a time, so this one was skipped.")),{configure:D,destroy(){}};r&&mt(document,g);let T=Tt(p.store,{container:c});return p.island=T,{configure:D,destroy(){p.island===T&&(p.island=null),T.destroy()}}}return Bt(en);})();
|