@44-audio/components 0.1.0-dev.9 → 1.0.0-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,777 +1,1571 @@
1
- import { h as Cr, C as Dr, D as Tr, E as qr, F as $r, G as Rr, H as zr, I as Lr, J as Ar, T as Fr, K as _r, L as Or, M as Ur, N as W, O as Nr, P as Pr, d as nr, c as Y, p as Z, a as rr, b as P, l as O, Q as ar, y as wr, f as R, g as T, e as z, i as H, z as kr, q as U, j as _, k as er, s as I, n as t, m as B, r as M, B as or, R as lr, u as fr, S as Q, U as ir, v as X, V as vr, W as Br, o as J, w as ur, x as pr, X as xr, A as jr, Y as Hr } from "./AudioPlayer-bUgQMAfs.mjs";
2
- function Gr(e, r, i, n, o) {
3
- Cr && Dr();
4
- var s = r.$$slots?.[i], f = !1;
5
- s === !0 && (s = r.children, f = !0), s === void 0 || s(e, f ? () => n : n);
6
- }
7
- const Kr = () => performance.now(), j = {
8
- // don't access requestAnimationFrame eagerly outside method
9
- // this allows basic testing of user code without JSDOM
10
- // bunder will eval and remove ternary when the user's app is built
11
- tick: (
12
- /** @param {any} _ */
13
- (e) => requestAnimationFrame(e)
14
- ),
15
- now: () => Kr(),
16
- tasks: /* @__PURE__ */ new Set()
1
+ import { v as ge, x as Je, W as Er, y as E, O as w, Q as C, a5 as xe, S as I, H as o, I as Xe, M as D, ad as z, a3 as sr, Y as Ar, J as b, N as _, P as ar, $ as u, C as M, A as t, a0 as v, R as oe, F as U, G as k, a9 as Tr, aa as Or, L as V, a2 as Zr, ac as Lr, a6 as $r, V as et, X as Rr, a4 as R, ae as rr, af as rt, ab as tr, ag as br, ah as tt, ai as at, aj as Sr, ak as Cr, t as Pr, z as xr, D as Nr, K as st } from "./BarWaveform-BkBkQ8cb.js";
2
+ var it = w("<fortyfour-recorder></fortyfour-recorder>", 2);
3
+ const nt = {
4
+ hash: "svelte-8c87am",
5
+ code: ":host {display:block;}:host {--_bg-1: var(--fortyfour-recorder-bg-1, #393939);--_color-0: var(--fortyfour-recorder-color-0, #d3d0c8);}fortyfour-recorder.svelte-8c87am {--fortyfour-recorder-background: var(--fortyfour-recorder-bg, #2d2d2d);--fortyfour-recorder-text: var(--_color-0);--fortyfour-recorder-border: var(--_bg-1);--fortyfour-recorder-accent: var(--fortyfour-recorder-btn-primary-bg, hsla(210, 50%, 60%, 1));--fortyfour-recorder-muted: var(--_color-0);}"
17
6
  };
18
- function Ir() {
19
- const e = j.now();
20
- j.tasks.forEach((r) => {
21
- r.c(e) || (j.tasks.delete(r), r.f());
22
- }), j.tasks.size !== 0 && j.tick(Ir);
23
- }
24
- function Vr(e) {
25
- let r;
26
- return j.tasks.size === 0 && j.tick(Ir), {
27
- promise: new Promise((i) => {
28
- j.tasks.add(r = { c: e, f: i });
29
- }),
30
- abort() {
31
- j.tasks.delete(r);
32
- }
33
- };
34
- }
35
- function tr(e, r) {
36
- _r(() => {
37
- e.dispatchEvent(new CustomEvent(r));
38
- });
39
- }
40
- function Wr(e) {
41
- if (e === "float") return "cssFloat";
42
- if (e === "offset") return "cssOffset";
43
- if (e.startsWith("--")) return e;
44
- const r = e.split("-");
45
- return r.length === 1 ? r[0] : r[0] + r.slice(1).map(
46
- /** @param {any} word */
47
- (i) => i[0].toUpperCase() + i.slice(1)
48
- ).join("");
49
- }
50
- function br(e) {
51
- const r = {}, i = e.split(";");
52
- for (const n of i) {
53
- const [o, s] = n.split(":");
54
- if (!o || s === void 0) break;
55
- const f = Wr(o.trim());
56
- r[f] = s.trim();
57
- }
58
- return r;
59
- }
60
- const Jr = (e) => e;
61
- function gr(e, r, i, n) {
62
- var o = (e & Nr) !== 0, s = (e & Pr) !== 0, f = o && s, v = (e & Fr) !== 0, q = f ? "both" : o ? "in" : "out", C, w = r.inert, x = r.style.overflow, k, D;
63
- function E() {
64
- return _r(() => C ??= i()(r, n?.() ?? /** @type {P} */
65
- {}, {
66
- direction: q
7
+ function ot(d, e) {
8
+ Je(e, !0), Er(d, nt);
9
+ let r = E(e, "sessionId", 7), a = E(e, "labels", 7, "");
10
+ const i = e.$$host;
11
+ function n(c) {
12
+ i.dispatchEvent(new CustomEvent("recording-complete", {
13
+ bubbles: !0,
14
+ composed: !0,
15
+ detail: { recordingId: c.detail?.recordingId }
67
16
  }));
68
17
  }
69
- var a = {
70
- is_global: v,
71
- in() {
72
- if (r.inert = w, !o) {
73
- D?.abort(), D?.reset?.();
74
- return;
75
- }
76
- s || k?.abort(), tr(r, "introstart"), k = yr(r, E(), D, 1, () => {
77
- tr(r, "introend"), k?.abort(), k = C = void 0, r.style.overflow = x;
78
- });
79
- },
80
- out(c) {
81
- if (!s) {
82
- c?.(), C = void 0;
83
- return;
84
- }
85
- r.inert = !0, tr(r, "outrostart"), D = yr(r, E(), k, 0, () => {
86
- tr(r, "outroend"), c?.();
87
- });
88
- },
89
- stop: () => {
90
- k?.abort(), D?.abort();
91
- }
92
- }, d = (
93
- /** @type {Effect} */
94
- Tr
95
- );
96
- if ((d.transitions ??= []).push(a), o && qr) {
97
- var m = v;
98
- if (!m) {
99
- for (var l = (
100
- /** @type {Effect | null} */
101
- d.parent
102
- ); l && (l.f & $r) !== 0; )
103
- for (; (l = l.parent) && (l.f & Rr) === 0; )
104
- ;
105
- m = !l || (l.f & zr) !== 0;
106
- }
107
- m && Lr(() => {
108
- Ar(() => a.in());
109
- });
110
- }
111
- }
112
- function yr(e, r, i, n, o) {
113
- var s = n === 1;
114
- if (Or(r)) {
115
- var f, v = !1;
116
- return Ur(() => {
117
- if (!v) {
118
- var d = r({ direction: s ? "in" : "out" });
119
- f = yr(e, d, i, n, o);
120
- }
121
- }), {
122
- abort: () => {
123
- v = !0, f?.abort();
124
- },
125
- deactivate: () => f.deactivate(),
126
- reset: () => f.reset(),
127
- t: () => f.t()
128
- };
129
- }
130
- if (i?.deactivate(), !r?.duration)
131
- return o(), {
132
- abort: W,
133
- deactivate: W,
134
- reset: W,
135
- t: () => n
136
- };
137
- const { delay: q = 0, css: C, tick: w, easing: x = Jr } = r;
138
- var k = [];
139
- if (s && i === void 0 && (w && w(0, 1), C)) {
140
- var D = br(C(0, 1));
141
- k.push(D, D);
142
- }
143
- var E = () => 1 - n, a = e.animate(k, { duration: q, fill: "forwards" });
144
- return a.onfinish = () => {
145
- a.cancel();
146
- var d = i?.t() ?? 1 - n;
147
- i?.abort();
148
- var m = n - d, l = (
149
- /** @type {number} */
150
- r.duration * Math.abs(m)
151
- ), c = [];
152
- if (l > 0) {
153
- var p = !1;
154
- if (C)
155
- for (var b = Math.ceil(l / 16.666666666666668), g = 0; g <= b; g += 1) {
156
- var u = d + m * x(g / b), y = br(C(u, 1 - u));
157
- c.push(y), p ||= y.overflow === "hidden";
158
- }
159
- p && (e.style.overflow = "hidden"), E = () => {
160
- var h = (
161
- /** @type {number} */
162
- /** @type {globalThis.Animation} */
163
- a.currentTime
164
- );
165
- return d + m * x(h / l);
166
- }, w && Vr(() => {
167
- if (a.playState !== "running") return !1;
168
- var h = E();
169
- return w(h, 1 - h), !0;
170
- });
171
- }
172
- a = e.animate(c, { duration: l, fill: "forwards" }), a.onfinish = () => {
173
- E = () => n, w?.(n, 1 - n), o();
174
- };
175
- }, {
176
- abort: () => {
177
- a && (a.cancel(), a.effect = null, a.onfinish = W);
18
+ var s = {
19
+ get sessionId() {
20
+ return r();
178
21
  },
179
- deactivate: () => {
180
- o = W;
22
+ set sessionId(c) {
23
+ r(c), D();
181
24
  },
182
- reset: () => {
183
- n === 0 && w?.(1, 0);
25
+ get labels() {
26
+ return a();
184
27
  },
185
- t: () => E()
186
- };
187
- }
188
- const Qr = (e) => e;
189
- function Xr(e) {
190
- const r = e - 1;
191
- return r * r * r + 1;
192
- }
193
- function mr(e) {
194
- const r = typeof e == "string" && e.match(/^\s*(-?[\d.]+)([^\s]*)\s*$/);
195
- return r ? [parseFloat(r[1]), r[2] || "px"] : [
196
- /** @type {number} */
197
- e,
198
- "px"
199
- ];
200
- }
201
- function Yr(e, { delay: r = 0, duration: i = 400, easing: n = Qr } = {}) {
202
- const o = +getComputedStyle(e).opacity;
203
- return {
204
- delay: r,
205
- duration: i,
206
- easing: n,
207
- css: (s) => `opacity: ${s * o}`
208
- };
28
+ set labels(c = "") {
29
+ a(c), D();
30
+ }
31
+ }, h = it();
32
+ return C(() => z(h, "session-id", r())), C(() => z(h, "labels", a())), xe(h, 1, "svelte-8c87am"), I("recording-complete", h, n), o(d, h), Xe(s);
209
33
  }
210
- function hr(e, { delay: r = 0, duration: i = 400, easing: n = Xr, x: o = 0, y: s = 0, opacity: f = 0 } = {}) {
211
- const v = getComputedStyle(e), q = +v.opacity, C = v.transform === "none" ? "" : v.transform, w = q * (1 - f), [x, k] = mr(o), [D, E] = mr(s);
212
- return {
213
- delay: r,
214
- duration: i,
215
- easing: n,
216
- css: (a, d) => `
217
- transform: ${C} translate(${(1 - a) * x}${k}, ${(1 - a) * D}${E});
218
- opacity: ${q - w * d}`
219
- };
34
+ customElements.define("fortyfour-audio-recorder", ge(
35
+ ot,
36
+ {
37
+ sessionId: { attribute: "session-id" },
38
+ labels: { attribute: "labels" }
39
+ },
40
+ [],
41
+ [],
42
+ !0
43
+ ));
44
+ var ct = sr('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true"><path d="M232.7 69.9L224 96L128 96C110.3 96 96 110.3 96 128C96 145.7 110.3 160 128 160L512 160C529.7 160 544 145.7 544 128C544 110.3 529.7 96 512 96L416 96L407.3 69.9C402.9 56.8 390.7 48 376.9 48L263.1 48C249.3 48 237.1 56.8 232.7 69.9zM512 208L128 208L149.1 531.1C150.7 556.4 171.7 576 197 576L443 576C468.3 576 489.3 556.4 490.9 531.1L512 208z" fill="currentColor"></path></svg>');
45
+ function zr(d) {
46
+ var e = ct();
47
+ o(d, e);
220
48
  }
221
- async function Mr(e = !1) {
222
- e && (await navigator.mediaDevices.getUserMedia({ audio: !0 })).getTracks().forEach((o) => o.stop());
223
- const r = await navigator.mediaDevices.enumerateDevices(), i = r.filter((n) => n.deviceId).filter((n) => n.kind === "audioinput").map((n) => ({
224
- id: n.deviceId,
225
- label: n.label || `Microphone ${r.indexOf(n) + 1}`
226
- }));
227
- return i.length === 0 ? Mr(!0) : i;
49
+ ge(zr, {}, [], [], !0);
50
+ var lt = sr('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true"><path d="M448 288V128c0-70.7-57.3-128-128-128S192 57.3 192 128v42.4L425.2 384.6c14.5-27.2 22.8-58 22.8-90.6V288zM38.8 5.1C28.4-3.1 13.3-1.2 5.1 9.2s-6.3 25.5 4 33.7l592 464c10.4 8.2 25.5 6.3 33.7-4s6.3-25.5-4-33.7L417.8 297.3 38.8 5.1zM192 288v0l194.8 152.9C365.7 456.3 343.6 464 320 464c-79.5 0-144-64.5-144-144v-32zm-64 0c0-17.7-14.3-32-32-32s-32 14.3-32 32c0 97.4 72.4 178 166.2 190.3V544H160c-17.7 0-32 14.3-32 32s14.3 32 32 32h320c17.7 0 32-14.3 32-32s-14.3-32-32-32h-70.2V478.3C462.4 471.2 508 437.5 536 392.5" fill="currentColor"></path></svg>');
51
+ function Ur(d) {
52
+ var e = lt();
53
+ o(d, e);
228
54
  }
229
- async function Zr(e, r, i, n) {
230
- I(r, !t(r)), t(i).length || await n();
55
+ ge(Ur, {}, [], [], !0);
56
+ var dt = sr('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" aria-hidden="true"><path d="M580.6 137.4c12.5 12.5 12.5 32.8 0 45.3l-336 336c-12.5 12.5-32.8 12.5-45.3 0l-144-144c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0L222 450.7 535.4 137.4c12.5-12.5 32.8-12.5 45.3 0z" fill="currentColor"></path></svg>');
57
+ function _r(d) {
58
+ var e = dt();
59
+ o(d, e);
231
60
  }
232
- var re = R("<li><button> </button></li>"), ee = R('<li><button class="devices-select__option svelte-q87ygv" disabled>No microphones found</button></li>'), te = R('<li><button class="devices-select__option svelte-q87ygv" disabled>Loading Microphones...</button></li>'), oe = R('<ul role="listbox" aria-label="Select microphone"><!> <!> <!></ul>'), ae = R('<div class="container" role="group" aria-label="Audio recorder"><button class="devices-btn svelte-q87ygv" aria-haspopup="listbox"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 448 512" class="devices-btn__icon svelte-q87ygv"><path d="M201.4 406.6c12.5 12.5 32.8 12.5 45.3 0l192-192c12.5-12.5 12.5-32.8 0-45.3s-32.8-12.5-45.3 0L224 338.7 54.6 169.4c-12.5-12.5-32.8-12.5-45.3 0s-12.5 32.8 0 45.3l192 192z"></path></svg></button> <!></div>');
233
- const ie = {
234
- hash: "svelte-q87ygv",
235
- code: '.devices-btn.svelte-q87ygv {background:none;border:none;font-size:inherit;cursor:pointer;color:inherit;}.devices-btn__icon.svelte-q87ygv {width:0.75rem;height:0.75rem;fill:var(--fortyfour-recorder-btn-color);}.devices-select.svelte-q87ygv {display:none;flex-direction:column;list-style:none;margin:0;padding:0;border:var(--fortyfour-recorder-select-border);box-shadow:var(--fortyfour-recorder-select-shadow);border-radius:var(--fortyfour-recorder-select-radius);background:var(--fortyfour-recorder-select-bg);position:absolute;z-index:2147483647;overflow-y:auto;width:11rem;max-height:12rem;}.devices-select--is-open.svelte-q87ygv {display:flex;}.devices-select__option.svelte-q87ygv {padding:0.5rem 1rem;padding-left:0;background:none;border:none;text-align:left;cursor:pointer;width:100%;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;transition:background 0.1s;font:inherit;font-size:var(--fortyfour-recorder-select-font-size);color:var(--fortyfour-recorder-select-color);}.devices-select__option.svelte-q87ygv:hover {background:var(--fortyfour-recorder-select-bg-hover);}.devices-select__option.svelte-q87ygv::before {content:"";display:inline-block;width:2ch;text-align:center;padding:0 0.25rem;}.devices-select__option--is-selected.svelte-q87ygv::before {content:"✓";}.devices-select__option.svelte-q87ygv:disabled {opacity:0.5;cursor:inherit;}.devices-select__option.svelte-q87ygv:disabled:hover {background:inherit;}'
61
+ ge(_r, {}, [], [], !0);
62
+ var ut = sr("<rect></rect>"), vt = w('<div class="container svelte-ldbjcm" role="group" aria-label="audio player"><svg width="100%" xmlns="http://www.w3.org/2000/svg" aria-hidden="true" focusable="false" class="svelte-ldbjcm"><!></svg></div>');
63
+ const ht = {
64
+ hash: "svelte-ldbjcm",
65
+ code: `svg.svelte-ldbjcm {box-sizing:border-box;margin:0;padding:0;}.container.svelte-ldbjcm {flex:1;min-width:0;width:100%;box-sizing:border-box;margin:0;padding:0;display:flex;align-items:center;}.bar.svelte-ldbjcm {transition:fill 0.2s;}.played.svelte-ldbjcm {fill:var(--44-color-2, var(--fortyfour-recorder-bg-primary));}.unplayed.svelte-ldbjcm {fill:var(--44-color-1, var(--fortyfour-recorder-color-0));}.recording-pulse.svelte-ldbjcm {
66
+ animation: svelte-ldbjcm-pulse 0.5s ease-out;}
67
+
68
+ @keyframes svelte-ldbjcm-pulse {
69
+ 0% {
70
+ opacity: 0.5;
71
+ }
72
+ 100% {
73
+ opacity: 1;
74
+ }
75
+ }`
236
76
  };
237
- function Er(e, r) {
238
- Z(r, !0), rr(e, ie);
239
- let i = P(r, "deviceId", 15, ""), n = P(r, "disabled", 7, !1), o = O(ar([])), s = O(!1), f = O(!1), v;
240
- wr(() => {
241
- function a(d) {
242
- d.composedPath().includes(v) || t(s) && I(s, !1);
243
- }
244
- return document.addEventListener("pointerdown", a), () => {
245
- document.removeEventListener("pointerdown", a);
77
+ function jr(d, e) {
78
+ Je(e, !0), Er(d, ht);
79
+ let r = E(e, "data", 7), a = E(e, "timeMs", 7, null), i = E(e, "barWidth", 7, 3), n = E(e, "barGap", 7, 1), s = E(e, "barRadius", 7, 1), h = E(e, "minBarHeight", 7, 3), c = E(e, "height", 7, 56), l = E(e, "playedColor", 7, null), p = E(e, "unplayedColor", 7, null), L = M(0), m = M(!1), x = null;
80
+ Ar(() => {
81
+ const g = new ResizeObserver((G) => {
82
+ for (let Y of G)
83
+ Y.contentBoxSize ? b(L, Y.contentBoxSize[0]?.inlineSize ?? Y.contentBoxSize.inlineSize ?? 0, !0) : b(L, Y.contentRect.width, !0), b(m, !0);
84
+ });
85
+ return x && g.observe(x), () => {
86
+ g.disconnect();
246
87
  };
247
88
  });
248
- async function q() {
249
- try {
250
- I(f, !0), (await navigator.mediaDevices.getUserMedia({ audio: !0 })).getTracks().forEach((d) => d.stop()), I(o, await navigator.mediaDevices.enumerateDevices(), !0), I(
251
- o,
252
- t(o).filter((d) => d.deviceId).filter((d) => d.kind === "audioinput").map((d, m) => ({
253
- deviceId: d.deviceId,
254
- label: d.label || `Microphone ${m + 1}`
255
- })),
256
- !0
257
- ), !i() && t(o).length && i(t(o)[0].deviceId), t(o).sort((d, m) => d.label.localeCompare(m.label)), I(f, !1);
258
- } catch (a) {
259
- console.error("Error accessing microphones:", a);
260
- }
261
- }
262
- function C(a) {
263
- return () => {
264
- i(a), I(s, !1);
265
- };
266
- }
267
- var w = {
268
- get deviceId() {
89
+ const P = 100, fe = V(() => Math.floor(t(L) / (i() + n()))), ce = V(() => Zr(r(), t(fe))), le = V(() => t(ce).length ? r().length / t(ce).length : 1), ee = V(() => P * t(le)), pe = V(() => t(ce).map((g) => {
90
+ const G = Math.max(h(), Math.round(g / 100 * (c() - h()) + h()));
91
+ return G % 2 === 0 ? G + 1 : G;
92
+ }));
93
+ var me = {
94
+ get data() {
95
+ return r();
96
+ },
97
+ set data(g) {
98
+ r(g), D();
99
+ },
100
+ get timeMs() {
101
+ return a();
102
+ },
103
+ set timeMs(g = null) {
104
+ a(g), D();
105
+ },
106
+ get barWidth() {
269
107
  return i();
270
108
  },
271
- set deviceId(a = "") {
272
- i(a), B();
109
+ set barWidth(g = 3) {
110
+ i(g), D();
273
111
  },
274
- get disabled() {
112
+ get barGap() {
275
113
  return n();
276
114
  },
277
- set disabled(a = !1) {
278
- n(a), B();
115
+ set barGap(g = 1) {
116
+ n(g), D();
117
+ },
118
+ get barRadius() {
119
+ return s();
120
+ },
121
+ set barRadius(g = 1) {
122
+ s(g), D();
123
+ },
124
+ get minBarHeight() {
125
+ return h();
126
+ },
127
+ set minBarHeight(g = 3) {
128
+ h(g), D();
129
+ },
130
+ get height() {
131
+ return c();
132
+ },
133
+ set height(g = 56) {
134
+ c(g), D();
135
+ },
136
+ get playedColor() {
137
+ return l();
138
+ },
139
+ set playedColor(g = null) {
140
+ l(g), D();
141
+ },
142
+ get unplayedColor() {
143
+ return p();
144
+ },
145
+ set unplayedColor(g = null) {
146
+ p(g), D();
279
147
  }
280
- }, x = ae(), k = T(x);
281
- k.__click = [Zr, s, o, q];
282
- var D = z(k, 2);
148
+ }, W = vt(), q = u(W), _e = u(q);
283
149
  {
284
- var E = (a) => {
285
- var d = oe(), m = T(d);
286
- lr(m, 17, () => t(o), vr, (g, u) => {
287
- var y = re(), h = T(y), L = fr(() => C(t(u).deviceId));
288
- h.__click = function(...K) {
289
- t(L)?.apply(this, K);
290
- };
291
- var N = T(h, !0);
292
- M(h), M(y), U(() => {
293
- Q(
294
- h,
295
- 1,
296
- ir([
297
- "devices-select__option",
298
- t(u).deviceId === i() && "devices-select__option--is-selected"
299
- ]),
300
- "svelte-q87ygv"
301
- ), h.disabled = n(), X(N, t(u).label);
302
- }), _(g, y);
303
- });
304
- var l = z(m, 2);
305
- {
306
- var c = (g) => {
307
- var u = ee();
308
- _(g, u);
309
- };
310
- H(l, (g) => {
311
- !t(o).length && !t(f) && g(c);
312
- });
313
- }
314
- var p = z(l, 2);
315
- {
316
- var b = (g) => {
317
- var u = te();
318
- _(g, u);
319
- };
320
- H(p, (g) => {
321
- t(f) && g(b);
322
- });
323
- }
324
- M(d), U(() => Q(d, 1, `devices-select ${t(s) ? "devices-select--is-open" : ""}`, "svelte-q87ygv")), gr(3, d, () => Yr, () => ({ duration: 100 })), _(a, d);
150
+ var Fe = (g) => {
151
+ var G = U(), Y = k(G);
152
+ Tr(Y, 17, () => t(pe), Or, (y, A, de) => {
153
+ const Ke = V(() => de * t(ee) < a()), Qe = V(() => a() === null && de === t(pe).length - 1);
154
+ var J = ut();
155
+ C(
156
+ (Ge) => {
157
+ xe(
158
+ J,
159
+ 0,
160
+ Lr([
161
+ "bar",
162
+ t(Ke) ? "played" : "unplayed",
163
+ t(Qe) && "recording-pulse"
164
+ ]),
165
+ "svelte-ldbjcm"
166
+ ), oe(J, "rx", s()), oe(J, "x", de * (i() + n())), oe(J, "y", c() / 4 - t(A) / 2), oe(J, "width", Ge), oe(J, "height", t(A)), $r(J, t(Ke) ? l() ? `fill: ${l()}` : null : p() ? `fill: ${p()}` : null);
167
+ },
168
+ [() => Math.max(1, i() - 1)]
169
+ ), o(y, J);
170
+ }), o(g, G);
325
171
  };
326
- H(D, (a) => {
327
- t(s) && a(E);
172
+ _(_e, (g) => {
173
+ t(m) && g(Fe);
328
174
  });
329
175
  }
330
- return M(x), kr(x, (a) => v = a, () => v), U(() => or(k, "aria-expanded", t(s))), _(e, x), er(w);
176
+ return v(q), ar(q, (g) => x = g, () => x), v(W), C(() => {
177
+ oe(q, "height", c()), oe(q, "viewBox", `0 0 ${t(L)} ${c() / 2}`);
178
+ }), o(d, W), Xe(me);
331
179
  }
332
- nr(["click"]);
333
- Y(Er, { deviceId: {}, disabled: {} }, [], [], !0);
334
- var se = R("<button><!></button>");
335
- const ne = {
336
- hash: "svelte-f3ispq",
337
- code: ".btn.svelte-f3ispq {display:flex;align-items:center;gap:var(--fortyfour-recorder-btn-gap);font:inherit;border:none;padding:var(--fortyfour-recorder-btn-padding);border-radius:var(--fortyfour-recorder-btn-radius);background:var(--fortyfour-recorder-btn-bg);color:var(--fortyfour-recorder-btn-color);cursor:pointer;}.btn.svelte-f3ispq:hover {background:var(--fortyfour-recorder-btn-bg-hover);color:var(--fortyfour-recorder-btn-color-hover);}.btn.btn--recording.svelte-f3ispq {background:var(--fortyfour-recorder-red-bg);color:var(--fortyfour-recorder-red-color);}.btn.btn--primary.svelte-f3ispq {background:var(--fortyfour-recorder-btn-primary-bg);color:var(--fortyfour-recorder-btn-primary-color);}.btn.btn--primary.svelte-f3ispq:hover {background:var(--fortyfour-recorder-btn-primary-bg-hover);color:var(--fortyfour-recorder-btn-primary-color-hover);}"
338
- };
339
- function sr(e, r) {
340
- Z(r, !0), rr(e, ne);
341
- const i = P(r, "type", 7), n = P(r, "onclick", 7, () => {
342
- });
343
- var o = {
344
- get type() {
345
- return i();
346
- },
347
- set type(v) {
348
- i(v), B();
349
- },
350
- get onclick() {
351
- return n();
352
- },
353
- set onclick(v = () => {
354
- }) {
355
- n(v), B();
356
- }
357
- }, s = se();
358
- s.__click = function(...v) {
359
- n()?.apply(this, v);
360
- };
361
- var f = T(s);
362
- return Gr(f, r, "default", {}), M(s), U(() => Q(s, 1, ir(["btn", i() && `btn--${i()}`]), "svelte-f3ispq")), _(e, s), er(o);
180
+ ge(
181
+ jr,
182
+ {
183
+ data: {},
184
+ timeMs: {},
185
+ barWidth: {},
186
+ barGap: {},
187
+ barRadius: {},
188
+ minBarHeight: {},
189
+ height: {},
190
+ playedColor: {},
191
+ unplayedColor: {}
192
+ },
193
+ [],
194
+ [],
195
+ !0
196
+ );
197
+ function gt(d, e, r) {
198
+ t(e)?.setDevice(d.target.value), b(r, d.target.value, !0);
199
+ }
200
+ function Mr(d, e, r) {
201
+ t(e) === "needs-permission" ? t(r)?.requestPermission() : t(r)?.start();
202
+ }
203
+ function ft(d, e) {
204
+ t(e)?.stop();
205
+ }
206
+ function pt(d, e, r, a) {
207
+ t(e)?.save(r(), t(a));
208
+ }
209
+ function yr(d, e) {
210
+ t(e)?.reset();
363
211
  }
364
- nr(["click"]);
365
- Y(sr, { type: {}, onclick: {} }, ["default"], [], !0);
366
- var ce = R("<div></div> <!>", 1), de = R('<div class="time-elapsed svelte-11ls49v"> </div>'), le = R('<div role="group" aria-label="Audio recorder"><!> <!> <!></div>');
367
- const fe = {
368
- hash: "svelte-11ls49v",
369
- code: `.container.svelte-11ls49v {display:flex;align-items:center;gap:1rem;}.record-icon.svelte-11ls49v {width:1.25rem;height:1.25rem;background:var(--fortyfour-recorder-red-bg);border-radius:50%;}.record-icon--is-recording.svelte-11ls49v {background:var(--fortyfour-recorder-red-color);
370
- animation: svelte-11ls49v-pulse 2s infinite ease-out;}.time-elapsed.svelte-11ls49v {font-variant-numeric:tabular-nums;}
212
+ function mt(d, e) {
213
+ t(e)?.retry();
214
+ }
215
+ function bt(d, e) {
216
+ t(e)?.togglePlay();
217
+ }
218
+ var yt = w('<div class="row svelte-419ex5"><button class="record-btn round svelte-419ex5" part="button" disabled aria-label="Record"><span class="record-circle svelte-419ex5"></span></button></div>'), wt = w('<span class="svelte-419ex5">Record</span>'), xt = w('<div class="row svelte-419ex5"><button class="record-btn round svelte-419ex5" part="button" aria-label="Record"><span class="record-circle svelte-419ex5"></span> <!></button></div>'), _t = w('<div class="row svelte-419ex5"><span class="record-circle disabled svelte-419ex5"></span> <span class="message-text svelte-419ex5">Microphone Access Blocked</span></div>'), Et = w('<div class="row svelte-419ex5"><span class="icon-muted svelte-419ex5"><!></span> <span class="message-text svelte-419ex5">No microphone</span></div>'), Dt = w('<span class="svelte-419ex5">Record</span>'), Rt = w('<option class="svelte-419ex5"> </option>'), St = w('<div class="row svelte-419ex5"><button class="record-btn round svelte-419ex5" part="button" aria-label="Record"><span class="record-circle svelte-419ex5"></span> <!></button> <select class="mic-select svelte-419ex5" part="select" aria-label="Microphone"><option class="svelte-419ex5">Default Microphone</option><!></select></div>'), Ct = w('<div class="row svelte-419ex5"><div class="countdown svelte-419ex5"> </div></div>'), Pt = w('<span class="svelte-419ex5">Stop</span>'), Mt = w('<div class="live-waveform svelte-419ex5"><!></div>'), kt = w('<div class="row svelte-419ex5"><button class="record-btn svelte-419ex5" part="button" aria-label="Stop recording"><span class="stop-square svelte-419ex5"></span> <!></button> <span class="recording-indicator svelte-419ex5"></span> <span class="recording-label svelte-419ex5">Recording</span> <!> <span class="elapsed svelte-419ex5"> </span></div>'), It = w('<span class="svelte-419ex5">Discard</span>'), At = w('<span class="svelte-419ex5">Save</span>'), Tt = w('<fortyfour-preview-recording></fortyfour-preview-recording> <div class="row svelte-419ex5"><button class="record-btn svelte-419ex5" part="button"><!></button> <fortyfour-bar-waveform></fortyfour-bar-waveform> <fortyfour-duration></fortyfour-duration> <button class="record-btn svelte-419ex5" part="button" aria-label="Discard"><!> <!></button> <button class="record-btn svelte-419ex5" part="button" aria-label="Save"><!> <!></button></div>', 3), Ot = w('<div class="row svelte-419ex5"><span class="icon-accent svelte-419ex5"><!></span> <span class="muted-text svelte-419ex5">Uploading...</span></div>'), Lt = w('<div class="row svelte-419ex5"><span class="icon-accent svelte-419ex5"><!></span> <span class="muted-text svelte-419ex5">Processing...</span></div>'), Nt = w('<div class="row svelte-419ex5"><span class="icon-accent svelte-419ex5"><!></span> <span class="success-text svelte-419ex5">Saved</span></div>'), zt = w('<span class="svelte-419ex5">Try Again</span>'), Ut = w('<span class="svelte-419ex5">Start Over</span>'), jt = w('<div class="row svelte-419ex5"><span class="icon-accent svelte-419ex5"><!></span> <div class="error-container svelte-419ex5"><p class="error-message svelte-419ex5"> </p></div> <div class="btn-group svelte-419ex5"><button class="record-btn svelte-419ex5" part="button" aria-label="Try Again"><span class="btn-icon svelte-419ex5">&#x21bb;</span> <!></button> <button class="record-btn svelte-419ex5" part="button" aria-label="Start Over"><span class="btn-icon svelte-419ex5">&#x2715;</span> <!></button></div></div>'), Ft = w('<span class="svelte-419ex5">Start Over</span>'), Gt = w('<div class="row svelte-419ex5"><span class="icon-accent svelte-419ex5"><!></span> <p class="muted-text svelte-419ex5">Recording interrupted</p> <button class="record-btn svelte-419ex5" part="button" aria-label="Start Over"><span class="btn-icon svelte-419ex5">&#x2715;</span> <!></button></div>'), qt = w("<fortyfour-recording-session></fortyfour-recording-session> <div><!></div>", 3);
219
+ const Ht = {
220
+ hash: "svelte-419ex5",
221
+ code: `:host {--fortyfour-recorder-font-family: system-ui, sans-serif;--fortyfour-recorder-font-size: 14px;--fortyfour-recorder-accent: #c4956a;--fortyfour-recorder-background: #faf8f5;--fortyfour-recorder-text: #2c2620;--fortyfour-recorder-muted: #8c8279;--fortyfour-recorder-border: #d9d4cc;display:block;font-family:var(--fortyfour-recorder-font-family);font-size:var(--fortyfour-recorder-font-size);}.container.svelte-419ex5 {--recorder-btn-size: 36px;--recorder-row-gap: 0.5rem;--recorder-row-min-height: 40px;--recorder-container-radius: 12px;--recorder-btn-radius: 8px;--recorder-btn-padding: 8px;border:1px solid var(--fortyfour-recorder-border);background:var(--fortyfour-recorder-background);border-radius:var(--recorder-container-radius);box-shadow:0 1px 3px rgba(0, 0, 0, 0.04), 0 1px 2px rgba(0, 0, 0, 0.02);padding:0.5rem;overflow:hidden;width:100%;box-sizing:border-box;display:grid;}.row.svelte-419ex5 {display:flex;flex-direction:row;align-items:center;gap:var(--recorder-row-gap);min-height:var(--recorder-row-min-height);min-width:0;grid-area:1 / 1;}.mic-select.svelte-419ex5 {flex:1;min-width:0;max-width:240px;padding:0.5rem 0.625rem;border-radius:var(--recorder-btn-radius);border:1px solid var(--fortyfour-recorder-border);background:var(--fortyfour-recorder-background);color:var(--fortyfour-recorder-text);font-family:var(--fortyfour-recorder-font-family);font-size:1em;cursor:pointer;appearance:none;background-image:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' fill='none' stroke='%238c8279' stroke-width='1.5' stroke-linecap='round'/%3E%3C/svg%3E");background-repeat:no-repeat;background-position:right 0.5rem center;padding-right:1.75rem;transition:border-color 120ms ease;}.mic-select.svelte-419ex5:hover {border-color:var(--fortyfour-recorder-accent);}.mic-select.svelte-419ex5:disabled {opacity:0.6;cursor:default;}.mic-select.svelte-419ex5:focus-visible {outline:2px solid var(--fortyfour-recorder-accent);outline-offset:2px;}.record-circle.svelte-419ex5 {width:16px;height:16px;border-radius:50%;background:currentColor;flex-shrink:0;}.stop-square.svelte-419ex5 {width:12px;height:12px;border-radius:2px;background:currentColor;flex-shrink:0;}.record-circle.disabled.svelte-419ex5 {background:var(--fortyfour-recorder-muted);opacity:0.4;}.icon-muted.svelte-419ex5 {display:flex;width:20px;height:20px;color:var(--fortyfour-recorder-muted);flex-shrink:0;}.icon-accent.svelte-419ex5 {display:flex;width:20px;height:20px;color:var(--fortyfour-recorder-accent);flex-shrink:0;}.message-text.svelte-419ex5 {color:var(--fortyfour-recorder-muted);}.success-text.svelte-419ex5 {color:var(--fortyfour-recorder-accent);font-weight:500;}.record-btn.svelte-419ex5 {display:inline-flex;align-items:center;justify-content:center;gap:0.5rem;min-width:var(--recorder-btn-size);min-height:var(--recorder-btn-size);padding:var(--recorder-btn-padding);border:none;border-radius:var(--recorder-btn-radius);box-sizing:border-box;background:var(--fortyfour-recorder-accent);color:var(--fortyfour-recorder-background);font-family:var(--fortyfour-recorder-font-family);font-size:1em;cursor:pointer;flex-shrink:0;transition:filter 120ms ease, transform 120ms ease;}.has-labels.svelte-419ex5 .record-btn:where(.svelte-419ex5) {padding-left:1rem;padding-right:1rem;}.record-btn.round.svelte-419ex5 {border-radius:999px;}.record-btn.svelte-419ex5:disabled {opacity:0.4;cursor:default;}.record-btn.svelte-419ex5:not(:disabled):hover {filter:brightness(1.1);}.record-btn.svelte-419ex5:not(:disabled):active {transform:scale(0.95);filter:brightness(0.95);}.record-btn.svelte-419ex5:focus-visible {outline:2px solid var(--fortyfour-recorder-accent);outline-offset:2px;}.countdown.svelte-419ex5 {display:inline-flex;align-items:center;justify-content:center;width:var(--recorder-btn-size);height:var(--recorder-btn-size);border-radius:var(--recorder-btn-radius);background:var(--fortyfour-recorder-accent);color:var(--fortyfour-recorder-background);font-weight:700;font-variant-numeric:tabular-nums;flex-shrink:0;}.recording-indicator.svelte-419ex5 {width:10px;height:10px;border-radius:50%;background:var(--fortyfour-recorder-accent);
222
+ animation: svelte-419ex5-pulse 1s ease-in-out infinite;flex-shrink:0;}.recording-label.svelte-419ex5 {font-size:0.875em;font-weight:600;color:var(--fortyfour-recorder-accent);flex-shrink:0;}
371
223
 
372
- @keyframes svelte-11ls49v-pulse {
373
- 0% {
224
+ @keyframes svelte-419ex5-pulse {
225
+ 0%,
226
+ 100% {
227
+ opacity: 1;
374
228
  transform: scale(1);
375
- box-shadow: 0 0 0 0 hsla(0, 100%, 100%, 0.7);
376
229
  }
377
230
  50% {
378
- transform: scale(0.9);
231
+ opacity: 0.35;
232
+ transform: scale(0.85);
379
233
  }
380
- 100% {
381
- transform: scale(1);
382
- box-shadow: 0 0 0 8px hsla(0, 100%, 100%, 0);
383
- }
384
- }`
234
+ }.elapsed.svelte-419ex5 {font-variant-numeric:tabular-nums;font-size:1em;color:var(--fortyfour-recorder-text);flex-shrink:0;}.live-waveform.svelte-419ex5 {flex:1;min-width:0;display:flex;align-items:center;}.row.svelte-419ex5 fortyfour-bar-waveform {--waveform-progress-color: var(--fortyfour-recorder-waveform-progress, var(--fortyfour-recorder-accent));--waveform-track-color: var(--fortyfour-recorder-border);--waveform-focus-color: var(--fortyfour-recorder-accent);flex:1;min-width:0;}.row.svelte-419ex5 fortyfour-duration {--fortyfour-duration-font-family: var(--fortyfour-recorder-font-family);--fortyfour-duration-font-size: 1em;--fortyfour-duration-color: var(--fortyfour-recorder-text);flex-shrink:0;}.muted-text.svelte-419ex5 {color:var(--fortyfour-recorder-muted);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;min-width:0;}.error-container.svelte-419ex5 {flex:1;min-width:0;}.error-message.svelte-419ex5 {margin:0;color:var(--fortyfour-recorder-accent);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;}.btn-group.svelte-419ex5 {display:flex;gap:var(--recorder-row-gap);flex-shrink:0;}.record-btn.svelte-419ex5 svg {width:16px;height:16px;fill:currentColor;}.btn-icon.svelte-419ex5 {display:inline-flex;align-items:center;justify-content:center;width:16px;height:16px;font-size:1em;line-height:1;}.container.compact.svelte-419ex5 {--recorder-row-gap: 0.5rem;--recorder-row-min-height: 32px;padding:0.25rem;}.container.comfortable.svelte-419ex5 {--recorder-row-gap: 0.75rem;--recorder-row-min-height: 48px;padding:0.75rem;}.container.pill.svelte-419ex5 {--recorder-container-radius: 999px;--recorder-btn-radius: 999px;}.container.square.svelte-419ex5 {--recorder-container-radius: 0;--recorder-btn-radius: 0;}`
385
235
  };
386
- function Sr(e, r) {
387
- Z(r, !0), rr(e, fe);
388
- let i = P(r, "deviceId", 15, ""), n = P(r, "onDone", 7), o = O(ar({
389
- state: "ready",
390
- // "ready", "recording"
391
- timeElapsed: 0,
392
- error: null
393
- })), s;
394
- Br(() => {
395
- s?.stop();
396
- });
397
- function f() {
398
- t(o).state === "ready" ? v() : t(o).state === "recording" && q();
399
- }
400
- async function v() {
401
- const a = await navigator.mediaDevices.getUserMedia({
402
- audio: { deviceId: i() ? { exact: i() } : void 0 }
403
- }), d = [];
404
- s = new MediaRecorder(a), s.ondataavailable = (l) => d.push(l.data), s.onstop = () => {
405
- t(o).state === "recording" && (a.getTracks().forEach((l) => l.stop()), n()(URL.createObjectURL(new Blob(d, { type: s.mimeType }))), t(o).state = "ready");
406
- }, s.start();
407
- const m = () => {
408
- t(o).state === "recording" && (t(o).timeElapsed += 1, setTimeout(m, 1e3));
409
- };
410
- setTimeout(m, 1e3), t(o).state = "recording";
236
+ function Bt(d, e) {
237
+ Je(e, !0), Er(d, Ht);
238
+ const r = e.$$host;
239
+ let a = E(e, "sessionId", 7, null), i = E(e, "labels", 7, ""), n = E(e, "countdownMs", 7, 3e3), s = E(e, "maxDurationMs", 7, null), h = E(e, "shape", 7, "pill"), c = E(e, "buttonLabel", 7, "icon"), l = E(e, "visualization", 7, "waveform"), p = E(e, "spacing", 7, "default");
240
+ const L = `fortyfour-preview-${crypto.randomUUID().slice(0, 8)}`;
241
+ let m = M(null), x = M("initializing"), P = M(0), fe = M(0), ce = M(null), le = M(Rr([])), ee = M(null), pe = M(Rr([])), me = M(null), W = M(null), q = M(!1);
242
+ const _e = V(() => i() ? i().split(",").map((f) => f.trim()).filter(Boolean) : []), Fe = { compact: 28, comfortable: 40 }, g = V(() => Fe[p()] ?? 32), G = V(() => s() ? br(t(P)) + " / " + br(Number(s())) : br(t(P))), Y = {
243
+ "invalid-request": "Unable to save recording. Please try again.",
244
+ "rate-limited": "Too many requests. Please wait and try again.",
245
+ "server-error": "Server error. Please try again later.",
246
+ "upload-failed": "Upload failed. Please check your connection and try again.",
247
+ "processing-failed": "Processing failed. Please try again.",
248
+ "processing-timeout": "Processing is taking too long. Please try again.",
249
+ "recording-failed": "Unable to access microphone."
250
+ };
251
+ function y(f) {
252
+ return f && Y[f.code] || "Something went wrong.";
411
253
  }
412
- function q() {
413
- s?.stop();
254
+ function A() {
255
+ b(x, t(m)?.state ?? "initializing", !0), b(ce, t(m)?.audioUrl, !0), b(ee, t(m)?.error, !0), t(ee) && console.warn(`fortyfour-recorder: ${t(ee).code} — ${t(ee).message}`), r.setAttribute("data-state", t(x));
256
+ }
257
+ function de() {
258
+ b(pe, t(m)?.devices || [], !0), b(me, t(m)?.deviceId || null, !0);
259
+ }
260
+ function Ke() {
261
+ t(m)?.refreshDevices(), de();
262
+ }
263
+ function Qe() {
264
+ b(P, t(m)?.elapsedTime || 0, !0), b(fe, t(m)?.countdown || 0, !0), b(le, t(m)?.waveformSamples || [], !0);
265
+ }
266
+ function J(f) {
267
+ A(), r.dispatchEvent(new CustomEvent("recording-complete", {
268
+ bubbles: !0,
269
+ composed: !0,
270
+ detail: {
271
+ recordingId: t(m)?.recordingId,
272
+ recording: f.detail?.recording
273
+ }
274
+ }));
414
275
  }
415
- var C = {
416
- get deviceId() {
276
+ r._setApiFactory = (f) => {
277
+ t(m)?._setApiFactory(f);
278
+ };
279
+ function Ge() {
280
+ b(q, t(W)?.state === "playing");
281
+ }
282
+ var Fr = {
283
+ get sessionId() {
284
+ return a();
285
+ },
286
+ set sessionId(f = null) {
287
+ a(f), D();
288
+ },
289
+ get labels() {
417
290
  return i();
418
291
  },
419
- set deviceId(a = "") {
420
- i(a), B();
292
+ set labels(f = "") {
293
+ i(f), D();
421
294
  },
422
- get onDone() {
295
+ get countdownMs() {
423
296
  return n();
424
297
  },
425
- set onDone(a) {
426
- n(a), B();
298
+ set countdownMs(f = 3e3) {
299
+ n(f), D();
300
+ },
301
+ get maxDurationMs() {
302
+ return s();
303
+ },
304
+ set maxDurationMs(f = null) {
305
+ s(f), D();
306
+ },
307
+ get shape() {
308
+ return h();
309
+ },
310
+ set shape(f = "pill") {
311
+ h(f), D();
312
+ },
313
+ get buttonLabel() {
314
+ return c();
315
+ },
316
+ set buttonLabel(f = "icon") {
317
+ c(f), D();
318
+ },
319
+ get visualization() {
320
+ return l();
321
+ },
322
+ set visualization(f = "waveform") {
323
+ l(f), D();
324
+ },
325
+ get spacing() {
326
+ return p();
327
+ },
328
+ set spacing(f = "default") {
329
+ p(f), D();
427
330
  }
428
- }, w = le(), x = T(w);
429
- {
430
- let a = fr(() => t(o).state === "recording" && "recording");
431
- sr(x, {
432
- onclick: f,
433
- get type() {
434
- return t(a);
435
- },
436
- children: (d, m) => {
437
- var l = ce(), c = J(l), p = z(c, 2);
438
- {
439
- var b = (u) => {
440
- var y = ur("Record");
441
- _(u, y);
442
- }, g = (u) => {
443
- var y = pr(), h = J(y);
444
- {
445
- var L = (N) => {
446
- var K = ur("Recording");
447
- _(N, K);
448
- };
449
- H(
450
- h,
451
- (N) => {
452
- t(o).state === "recording" && N(L);
453
- },
454
- !0
455
- );
456
- }
457
- _(u, y);
458
- };
459
- H(p, (u) => {
460
- t(o).state === "ready" ? u(b) : u(g, !1);
461
- });
462
- }
463
- U(() => Q(
464
- c,
465
- 1,
466
- ir([
467
- "record-icon",
468
- t(o).state === "recording" && "record-icon--is-recording"
469
- ]),
470
- "svelte-11ls49v"
471
- )), _(d, l);
472
- },
473
- $$slots: { default: !0 }
474
- });
475
- }
476
- var k = z(x, 2);
331
+ }, Dr = qt(), j = k(Dr);
332
+ C(() => z(j, "countdown-ms", n())), C(() => z(j, "max-duration-ms", s())), xe(j, 1, "svelte-419ex5"), ar(j, (f) => b(m, f), () => t(m));
333
+ var ir = R(j, 2), Gr = u(ir);
477
334
  {
478
- let a = fr(() => t(o).state === "recording");
479
- Er(k, {
480
- get disabled() {
481
- return t(a);
482
- },
483
- get deviceId() {
484
- return i();
485
- },
486
- set deviceId(d) {
487
- i(d);
335
+ var qr = (f) => {
336
+ var Ze = yt();
337
+ o(f, Ze);
338
+ }, Hr = (f) => {
339
+ var Ze = U(), Br = k(Ze);
340
+ {
341
+ var Vr = (Ee) => {
342
+ var De = xt(), qe = u(De);
343
+ qe.__click = [Mr, x, m];
344
+ var nr = R(u(qe), 2);
345
+ {
346
+ var or = (X) => {
347
+ var Re = wt();
348
+ o(X, Re);
349
+ };
350
+ _(nr, (X) => {
351
+ c() === "label" && X(or);
352
+ });
353
+ }
354
+ v(qe), v(De), o(Ee, De);
355
+ }, Wr = (Ee) => {
356
+ var De = U(), qe = k(De);
357
+ {
358
+ var nr = (X) => {
359
+ var Re = _t();
360
+ o(X, Re);
361
+ }, or = (X) => {
362
+ var Re = U(), Yr = k(Re);
363
+ {
364
+ var Jr = (Se) => {
365
+ var Ce = Et(), $e = u(Ce), cr = u($e);
366
+ Ur(cr), v($e), rr(2), v(Ce), o(Se, Ce);
367
+ }, Xr = (Se) => {
368
+ var Ce = U(), $e = k(Ce);
369
+ {
370
+ var cr = (Pe) => {
371
+ var Me = St(), ke = u(Me);
372
+ ke.__click = [Mr, x, m];
373
+ var lr = R(u(ke), 2);
374
+ {
375
+ var dr = (re) => {
376
+ var Q = Dt();
377
+ o(re, Q);
378
+ };
379
+ _(lr, (re) => {
380
+ c() === "label" && re(dr);
381
+ });
382
+ }
383
+ v(ke);
384
+ var H = R(ke, 2);
385
+ H.__change = [gt, m, me];
386
+ var K = u(H);
387
+ K.value = K.__value = "";
388
+ var Ie = R(K);
389
+ Tr(Ie, 17, () => t(pe), Or, (re, Q) => {
390
+ var F = Rt(), ue = u(F, !0);
391
+ v(F);
392
+ var te = {};
393
+ C(() => {
394
+ rt(F, t(Q).deviceId === t(me)), tr(ue, t(Q).label || "Microphone"), te !== (te = t(Q).deviceId) && (F.value = (F.__value = t(Q).deviceId) ?? "");
395
+ }), o(re, F);
396
+ }), v(H), v(Me), I("focus", H, Ke), o(Pe, Me);
397
+ }, Kr = (Pe) => {
398
+ var Me = U(), ke = k(Me);
399
+ {
400
+ var lr = (H) => {
401
+ var K = Ct(), Ie = u(K), re = u(Ie, !0);
402
+ v(Ie), v(K), C((Q) => tr(re, Q), [() => Math.ceil(t(fe) / 1e3)]), o(H, K);
403
+ }, dr = (H) => {
404
+ var K = U(), Ie = k(K);
405
+ {
406
+ var re = (F) => {
407
+ var ue = kt(), te = u(ue);
408
+ te.__click = [ft, m];
409
+ var ur = R(u(te), 2);
410
+ {
411
+ var vr = (O) => {
412
+ var N = Pt();
413
+ o(O, N);
414
+ };
415
+ _(ur, (O) => {
416
+ c() === "label" && O(vr);
417
+ });
418
+ }
419
+ v(te);
420
+ var ae = R(te, 6);
421
+ {
422
+ var be = (O) => {
423
+ var N = Mt(), Z = u(N);
424
+ jr(Z, {
425
+ get data() {
426
+ return t(le);
427
+ },
428
+ barGap: 2,
429
+ get height() {
430
+ return t(g);
431
+ },
432
+ playedColor: "var(--fortyfour-recorder-accent)",
433
+ unplayedColor: "var(--fortyfour-recorder-border)"
434
+ }), v(N), o(O, N);
435
+ };
436
+ _(ae, (O) => {
437
+ l() === "waveform" && O(be);
438
+ });
439
+ }
440
+ var T = R(ae, 2), Ae = u(T, !0);
441
+ v(T), v(ue), C(() => tr(Ae, t(G))), o(F, ue);
442
+ }, Q = (F) => {
443
+ var ue = U(), te = k(ue);
444
+ {
445
+ var ur = (ae) => {
446
+ var be = Tt(), T = k(be);
447
+ C(() => z(T, "id", L)), C(() => z(T, "src", t(ce))), C(() => z(T, "waveform", JSON.stringify(t(le)))), C(() => z(T, "duration-ms", t(P))), xe(T, 1, "svelte-419ex5"), ar(T, (S) => b(W, S), () => t(W));
448
+ var Ae = R(T, 2), O = u(Ae);
449
+ O.__click = [bt, W];
450
+ var N = u(O);
451
+ {
452
+ var Z = (S) => {
453
+ tt(S);
454
+ }, Te = (S) => {
455
+ at(S);
456
+ };
457
+ _(N, (S) => {
458
+ t(q) ? S(Z) : S(Te, !1);
459
+ });
460
+ }
461
+ v(O);
462
+ var $ = R(O, 2);
463
+ C(() => z($, "for", L)), z($, "bar-width", "3"), z($, "bar-gap", "2"), C(() => z($, "height", t(g))), xe($, 1, "svelte-419ex5");
464
+ var Oe = R($, 2);
465
+ C(() => z(Oe, "for", L)), z(Oe, "format", "elapsed/total"), xe(Oe, 1, "svelte-419ex5");
466
+ var B = R(Oe, 2);
467
+ B.__click = [yr, m];
468
+ var se = u(B);
469
+ zr(se);
470
+ var Le = R(se, 2);
471
+ {
472
+ var He = (S) => {
473
+ var Ve = It();
474
+ o(S, Ve);
475
+ };
476
+ _(Le, (S) => {
477
+ c() === "label" && S(He);
478
+ });
479
+ }
480
+ v(B);
481
+ var Be = R(B, 2);
482
+ Be.__click = [pt, m, a, _e];
483
+ var ie = u(Be);
484
+ _r(ie);
485
+ var ve = R(ie, 2);
486
+ {
487
+ var Ne = (S) => {
488
+ var Ve = At();
489
+ o(S, Ve);
490
+ };
491
+ _(ve, (S) => {
492
+ c() === "label" && S(Ne);
493
+ });
494
+ }
495
+ v(Be), v(Ae), C(() => oe(O, "aria-label", t(q) ? "Pause" : "Play")), I("play", T, Ge), I("pause", T, Ge), I("ended", T, Ge), o(ae, be);
496
+ }, vr = (ae) => {
497
+ var be = U(), T = k(be);
498
+ {
499
+ var Ae = (N) => {
500
+ var Z = Ot(), Te = u(Z), $ = u(Te);
501
+ Sr($), v(Te), rr(2), v(Z), o(N, Z);
502
+ }, O = (N) => {
503
+ var Z = U(), Te = k(Z);
504
+ {
505
+ var $ = (B) => {
506
+ var se = Lt(), Le = u(se), He = u(Le);
507
+ Sr(He), v(Le), rr(2), v(se), o(B, se);
508
+ }, Oe = (B) => {
509
+ var se = U(), Le = k(se);
510
+ {
511
+ var He = (ie) => {
512
+ var ve = Nt(), Ne = u(ve), S = u(Ne);
513
+ _r(S), v(Ne), rr(2), v(ve), o(ie, ve);
514
+ }, Be = (ie) => {
515
+ var ve = U(), Ne = k(ve);
516
+ {
517
+ var S = (ze) => {
518
+ var Ue = jt(), We = u(Ue), hr = u(We);
519
+ Cr(hr), v(We);
520
+ var ye = R(We, 2), je = u(ye), Ye = u(je, !0);
521
+ v(je), v(ye);
522
+ var er = R(ye, 2), he = u(er);
523
+ he.__click = [mt, m];
524
+ var gr = R(u(he), 2);
525
+ {
526
+ var fr = (ne) => {
527
+ var mr = zt();
528
+ o(ne, mr);
529
+ };
530
+ _(gr, (ne) => {
531
+ c() === "label" && ne(fr);
532
+ });
533
+ }
534
+ v(he);
535
+ var we = R(he, 2);
536
+ we.__click = [yr, m];
537
+ var pr = R(u(we), 2);
538
+ {
539
+ var Qr = (ne) => {
540
+ var mr = Ut();
541
+ o(ne, mr);
542
+ };
543
+ _(pr, (ne) => {
544
+ c() === "label" && ne(Qr);
545
+ });
546
+ }
547
+ v(we), v(er), v(Ue), C((ne) => tr(Ye, ne), [() => y(t(ee))]), o(ze, Ue);
548
+ }, Ve = (ze) => {
549
+ var Ue = U(), We = k(Ue);
550
+ {
551
+ var hr = (ye) => {
552
+ var je = Gt(), Ye = u(je), er = u(Ye);
553
+ Cr(er), v(Ye);
554
+ var he = R(Ye, 4);
555
+ he.__click = [yr, m];
556
+ var gr = R(u(he), 2);
557
+ {
558
+ var fr = (we) => {
559
+ var pr = Ft();
560
+ o(we, pr);
561
+ };
562
+ _(gr, (we) => {
563
+ c() === "label" && we(fr);
564
+ });
565
+ }
566
+ v(he), v(je), o(ye, je);
567
+ };
568
+ _(
569
+ We,
570
+ (ye) => {
571
+ t(x) === "interrupted" && ye(hr);
572
+ },
573
+ !0
574
+ );
575
+ }
576
+ o(ze, Ue);
577
+ };
578
+ _(
579
+ Ne,
580
+ (ze) => {
581
+ t(x) === "error" ? ze(S) : ze(Ve, !1);
582
+ },
583
+ !0
584
+ );
585
+ }
586
+ o(ie, ve);
587
+ };
588
+ _(
589
+ Le,
590
+ (ie) => {
591
+ t(x) === "done" ? ie(He) : ie(Be, !1);
592
+ },
593
+ !0
594
+ );
595
+ }
596
+ o(B, se);
597
+ };
598
+ _(
599
+ Te,
600
+ (B) => {
601
+ t(x) === "processing" ? B($) : B(Oe, !1);
602
+ },
603
+ !0
604
+ );
605
+ }
606
+ o(N, Z);
607
+ };
608
+ _(
609
+ T,
610
+ (N) => {
611
+ t(x) === "uploading" ? N(Ae) : N(O, !1);
612
+ },
613
+ !0
614
+ );
615
+ }
616
+ o(ae, be);
617
+ };
618
+ _(
619
+ te,
620
+ (ae) => {
621
+ t(x) === "preview" ? ae(ur) : ae(vr, !1);
622
+ },
623
+ !0
624
+ );
625
+ }
626
+ o(F, ue);
627
+ };
628
+ _(
629
+ Ie,
630
+ (F) => {
631
+ t(x) === "recording" ? F(re) : F(Q, !1);
632
+ },
633
+ !0
634
+ );
635
+ }
636
+ o(H, K);
637
+ };
638
+ _(
639
+ ke,
640
+ (H) => {
641
+ t(x) === "counting-down" ? H(lr) : H(dr, !1);
642
+ },
643
+ !0
644
+ );
645
+ }
646
+ o(Pe, Me);
647
+ };
648
+ _(
649
+ $e,
650
+ (Pe) => {
651
+ t(x) === "idle" ? Pe(cr) : Pe(Kr, !1);
652
+ },
653
+ !0
654
+ );
655
+ }
656
+ o(Se, Ce);
657
+ };
658
+ _(
659
+ Yr,
660
+ (Se) => {
661
+ t(x) === "no-microphone" ? Se(Jr) : Se(Xr, !1);
662
+ },
663
+ !0
664
+ );
665
+ }
666
+ o(X, Re);
667
+ };
668
+ _(
669
+ qe,
670
+ (X) => {
671
+ t(x) === "permission-denied" ? X(nr) : X(or, !1);
672
+ },
673
+ !0
674
+ );
675
+ }
676
+ o(Ee, De);
677
+ };
678
+ _(
679
+ Br,
680
+ (Ee) => {
681
+ t(x) === "needs-permission" ? Ee(Vr) : Ee(Wr, !1);
682
+ },
683
+ !0
684
+ );
488
685
  }
489
- });
490
- }
491
- var D = z(k, 2);
492
- {
493
- var E = (a) => {
494
- var d = de(), m = T(d);
495
- M(d), U((l, c) => X(m, `${l ?? ""}:${c ?? ""}`), [
496
- () => Math.floor(t(o).timeElapsed / 60).toString(),
497
- () => (t(o).timeElapsed % 60).toString().padStart(2, "0")
498
- ]), _(a, d);
686
+ o(f, Ze);
499
687
  };
500
- H(D, (a) => {
501
- t(o).state === "recording" && a(E);
688
+ _(Gr, (f) => {
689
+ t(x) === "initializing" ? f(qr) : f(Hr, !1);
502
690
  });
503
691
  }
504
- return M(w), U(() => Q(
505
- w,
692
+ return v(ir), C(() => xe(
693
+ ir,
506
694
  1,
507
- ir([
695
+ Lr([
508
696
  "container",
509
- t(o).state === "recording" && "is-recording"
697
+ p() === "compact" && "compact",
698
+ p() === "comfortable" && "comfortable",
699
+ h() === "pill" && "pill",
700
+ h() === "square" && "square",
701
+ c() === "label" && "has-labels"
510
702
  ]),
511
- "svelte-11ls49v"
512
- )), _(e, w), er(C);
703
+ "svelte-419ex5"
704
+ )), I("statechange", j, A), I("countdowntick", j, Qe), I("recordingtick", j, Qe), I("recordingcomplete", j, A), I("uploadcomplete", j, A), I("savecomplete", j, J), I("error", j, A), I("deviceschange", j, de), o(d, Dr), Xe(Fr);
705
+ }
706
+ et(["click", "change"]);
707
+ customElements.define("fortyfour-recorder", ge(
708
+ Bt,
709
+ {
710
+ sessionId: { attribute: "session-id", reflect: !0 },
711
+ labels: { reflect: !0 },
712
+ countdownMs: { attribute: "countdown-ms", reflect: !0 },
713
+ maxDurationMs: { attribute: "max-duration-ms", reflect: !0 },
714
+ shape: { reflect: !0 },
715
+ buttonLabel: { attribute: "button-label", reflect: !0 },
716
+ visualization: { reflect: !0 },
717
+ spacing: { attribute: "spacing", reflect: !0 }
718
+ },
719
+ [],
720
+ [],
721
+ !0
722
+ ));
723
+ class Vt {
724
+ #e = null;
725
+ #r = null;
726
+ #a = [];
727
+ #t = null;
728
+ #s = null;
729
+ constructor({ onStop: e } = {}) {
730
+ this.#s = e;
731
+ }
732
+ async warmup(e = null) {
733
+ if (this.#e?.active)
734
+ return;
735
+ const r = {
736
+ autoGainControl: !0,
737
+ noiseSuppression: !0
738
+ };
739
+ e && (r.deviceId = { exact: e }), this.#e = await navigator.mediaDevices.getUserMedia({ audio: r });
740
+ }
741
+ async start(e = null) {
742
+ await this.warmup(e), this.#a = [], this.#r = new MediaRecorder(this.#e), this.#r.ondataavailable = (r) => this.#a.push(r.data), this.#r.onstop = this.#c, this.#r.start();
743
+ }
744
+ stop() {
745
+ this.#r?.stop();
746
+ }
747
+ destroy() {
748
+ this.#r && (this.#r.onstop = null, this.#r.state !== "inactive" && this.#r.stop()), this.#e?.getTracks().forEach((e) => e.stop()), this.#t && (URL.revokeObjectURL(this.#t), this.#t = null), this.#r = null, this.#e = null, this.#a = [];
749
+ }
750
+ reset() {
751
+ this.#t && (URL.revokeObjectURL(this.#t), this.#t = null);
752
+ }
753
+ #c = () => {
754
+ const e = this.#a, r = this.#e, a = e.length > 0 ? new Blob(e, { type: this.#r?.mimeType }) : null;
755
+ this.#e?.getTracks().forEach((i) => i.stop()), this.#r = null, this.#e = null, this.#a = [], a && (this.#t = URL.createObjectURL(a)), this.#s?.(r);
756
+ };
757
+ get audioUrl() {
758
+ return this.#t;
759
+ }
760
+ get stream() {
761
+ return this.#e;
762
+ }
763
+ }
764
+ class Wt {
765
+ #e = [];
766
+ #r = !1;
767
+ #a = null;
768
+ #t = null;
769
+ #s = null;
770
+ constructor({ onDeviceChange: e, onPermissionChange: r } = {}) {
771
+ this.#a = e, this.#t = r;
772
+ }
773
+ get devices() {
774
+ return this.#e;
775
+ }
776
+ async init() {
777
+ try {
778
+ this.#s = await navigator.permissions.query({ name: "microphone" }), this.#s.addEventListener("change", this.#g);
779
+ } catch {
780
+ }
781
+ navigator.mediaDevices.addEventListener("devicechange", this.#o);
782
+ }
783
+ async requestPermission(e = null) {
784
+ try {
785
+ (await navigator.mediaDevices.getUserMedia({
786
+ audio: e ? { deviceId: { exact: e } } : !0
787
+ })).getTracks().forEach((a) => a.stop()), this.#r = !1;
788
+ } catch (r) {
789
+ r.name === "NotAllowedError" && (this.#r = !0);
790
+ }
791
+ this.#t?.();
792
+ }
793
+ async refreshDevices() {
794
+ try {
795
+ const r = (await navigator.mediaDevices.enumerateDevices()).filter((a) => a.kind === "audioinput" && a.deviceId);
796
+ this.#e = r.map((a) => ({
797
+ deviceId: a.deviceId,
798
+ label: a.label || "Unknown Microphone"
799
+ }));
800
+ } catch {
801
+ this.#e = [];
802
+ }
803
+ }
804
+ destroy() {
805
+ this.#s && (this.#s.removeEventListener("change", this.#g), this.#s = null), navigator.mediaDevices.removeEventListener("devicechange", this.#o);
806
+ }
807
+ async noDevices() {
808
+ return (await this.#c()).length === 0;
809
+ }
810
+ async hasPermission() {
811
+ const e = await this.#c(), r = await this.#u(), a = e.some((i) => i.deviceId);
812
+ return r === "granted" && a;
813
+ }
814
+ async permissionDenied() {
815
+ return this.#r ? !0 : await this.#u() === "denied";
816
+ }
817
+ async #c() {
818
+ try {
819
+ return (await navigator.mediaDevices.enumerateDevices()).filter((r) => r.kind === "audioinput");
820
+ } catch {
821
+ return [];
822
+ }
823
+ }
824
+ async #u() {
825
+ try {
826
+ return (await navigator.permissions.query({ name: "microphone" })).state;
827
+ } catch {
828
+ return null;
829
+ }
830
+ }
831
+ #g = () => {
832
+ this.#t?.();
833
+ };
834
+ #o = () => {
835
+ this.#a?.();
836
+ };
837
+ }
838
+ const Yt = 2e3, Jt = 30, Xt = {
839
+ 400: "invalid-request",
840
+ 429: "rate-limited",
841
+ 500: "server-error"
842
+ };
843
+ class wr extends Error {
844
+ constructor(e, r) {
845
+ super(r), this.code = e;
846
+ }
513
847
  }
514
- Y(Sr, { deviceId: {}, onDone: {} }, [], [], !0);
515
- function ve(e, r, i) {
516
- I(r, e.target.value, !0), i()(e.target.value);
848
+ class kr {
849
+ async upload(e, r, a, i, n) {
850
+ const s = await this.#e(a, n), h = new FormData();
851
+ h.append("sessionId", e), r.forEach((p) => h.append("labels", p)), h.append("audioFile", s), i.length > 0 && h.append("waveform", JSON.stringify(i));
852
+ const c = await fetch(`https://${Pr.apiHost}/v1/recordings`, {
853
+ method: "POST",
854
+ body: h,
855
+ signal: n
856
+ });
857
+ if (!c.ok) {
858
+ let p = `Upload failed: ${c.status}`;
859
+ try {
860
+ const m = await c.json();
861
+ m.message && (p = m.message);
862
+ } catch {
863
+ }
864
+ const L = Xt[c.status] || "upload-failed";
865
+ throw new wr(L, p);
866
+ }
867
+ return (await c.json()).recordingId;
868
+ }
869
+ async waitForProcessing(e, r) {
870
+ for (let a = 0; a < Jt; a++) {
871
+ await new Promise((i, n) => {
872
+ const s = setTimeout(i, Yt);
873
+ r?.addEventListener("abort", () => {
874
+ clearTimeout(s), n(r.reason);
875
+ });
876
+ });
877
+ try {
878
+ const i = await fetch(
879
+ `https://${Pr.apiHost}/v1/recordings/${e}/status?include=recording`,
880
+ { signal: r }
881
+ );
882
+ if (i.ok) {
883
+ const n = await i.json();
884
+ if (n.status === "ready")
885
+ return n.recording;
886
+ if (n.status === "failed")
887
+ throw new wr("processing-failed", "Recording processing failed");
888
+ }
889
+ } catch (i) {
890
+ if (i.name === "AbortError" || i instanceof wr)
891
+ throw i;
892
+ }
893
+ }
894
+ return !1;
895
+ }
896
+ async #e(e, r) {
897
+ const a = await fetch(e, { signal: r });
898
+ if (!a.ok)
899
+ throw new Error("Failed to load audio data");
900
+ const i = await a.blob();
901
+ return new File([i], "recording.audio", { type: i.type });
902
+ }
517
903
  }
518
- var ue = R("<option> </option>"), pe = xr('<rect width="10" fill="#4A90E2"></rect>'), ge = R(`<div><label for="mic-select" class="svelte-zkiuts">Input Device</label> <select id="mic-select" class="svelte-zkiuts"></select> <div><div>Mic Test</div> <div>Having mic issues? Start a test and say something fun and see if it picks up your voice.</div> <div><button> </button> <audio></audio> <svg style="vertical-align: middle; margin-left: 1em; border: 1px solid #ccc; background:
519
- #f9f9f9;" fill="none" xmlns="http://www.w3.org/2000/svg"></svg></div></div></div>`);
520
- const ye = {
521
- hash: "svelte-zkiuts",
522
- code: "label.svelte-zkiuts {display:block;margin-bottom:0.5em;}select.svelte-zkiuts {display:block;font-size:inherit;}"
904
+ function Kt(d) {
905
+ const e = new AudioContext(), r = e.createAnalyser();
906
+ return r.fftSize = 256, e.createMediaStreamSource(d).connect(r), { audioCtx: e, analyser: r };
907
+ }
908
+ function Qt(d) {
909
+ const e = new Uint8Array(d.frequencyBinCount);
910
+ d.getByteTimeDomainData(e);
911
+ let r = 0;
912
+ for (let n = 0; n < e.length; n++) {
913
+ const s = (e[n] - 128) / 128;
914
+ r += s * s;
915
+ }
916
+ const a = Math.sqrt(r / e.length), i = Math.min(1, a * 4);
917
+ return Math.round(i * 100);
918
+ }
919
+ class Zt {
920
+ #e = 100;
921
+ #r = null;
922
+ #a = null;
923
+ #t = [];
924
+ #s = 0;
925
+ start(e) {
926
+ const r = Kt(e);
927
+ this.#r = r.audioCtx, this.#a = r.analyser, this.#t = [], this.#s = 0;
928
+ }
929
+ sample(e) {
930
+ return this.#a ? (e - this.#s >= this.#e && (this.#t.push(Qt(this.#a)), this.#s = e), this.#t) : this.#t;
931
+ }
932
+ reset() {
933
+ this.#t = [], this.#s = 0;
934
+ }
935
+ destroy() {
936
+ this.#r?.close(), this.#r = null, this.#a = null, this.reset();
937
+ }
938
+ get samples() {
939
+ return this.#t;
940
+ }
941
+ }
942
+ const Ir = {
943
+ initial: "initializing",
944
+ states: {
945
+ initializing: {
946
+ on: {
947
+ READY: [
948
+ { target: "no-microphone", guard: "noDevices" },
949
+ { target: "idle", guard: "hasPermission" },
950
+ { target: "permission-denied", guard: "permissionDenied" },
951
+ { target: "needs-permission" }
952
+ ]
953
+ }
954
+ },
955
+ "no-microphone": {
956
+ on: {
957
+ DEVICE_CHANGE: [
958
+ { target: "idle", guard: "hasPermission" },
959
+ { target: "permission-denied", guard: "permissionDenied" },
960
+ { target: "needs-permission", guard: "noPermission" }
961
+ ]
962
+ }
963
+ },
964
+ "needs-permission": {
965
+ on: {
966
+ PERMISSION_CHANGE: [
967
+ { target: "idle", guard: "hasPermission" },
968
+ { target: "permission-denied", guard: "permissionDenied" }
969
+ ],
970
+ DEVICE_CHANGE: [{ target: "no-microphone", guard: "noDevices" }]
971
+ }
972
+ },
973
+ "permission-denied": {
974
+ on: {
975
+ PERMISSION_CHANGE: [
976
+ { target: "idle", guard: "hasPermission" },
977
+ { target: "permission-denied", guard: "permissionDenied" },
978
+ { target: "needs-permission", guard: "noPermission" }
979
+ ],
980
+ DEVICE_CHANGE: [{ target: "no-microphone", guard: "noDevices" }]
981
+ }
982
+ },
983
+ idle: {
984
+ on: {
985
+ PERMISSION_CHANGE: [
986
+ { target: "permission-denied", guard: "permissionDenied" },
987
+ { target: "needs-permission", guard: "noPermission" }
988
+ ],
989
+ DEVICE_CHANGE: [{ target: "no-microphone", guard: "noDevices" }],
990
+ START: [
991
+ { target: "permission-denied", guard: "permissionDenied" },
992
+ { target: "needs-permission", guard: "noPermission" },
993
+ { target: "counting-down", guard: "hasCountdown", action: "startCountdown" },
994
+ { target: "recording", action: "startRecording" }
995
+ ],
996
+ RESET: [
997
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
998
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
999
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1000
+ { target: "needs-permission", action: "cleanup" }
1001
+ ]
1002
+ }
1003
+ },
1004
+ "counting-down": {
1005
+ on: {
1006
+ COUNTDOWN_COMPLETE: [{ target: "recording", action: "startRecording" }],
1007
+ INTERRUPT: [{ target: "interrupted", action: "cleanup" }],
1008
+ RESET: [
1009
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1010
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1011
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1012
+ { target: "needs-permission", action: "cleanup" }
1013
+ ]
1014
+ }
1015
+ },
1016
+ recording: {
1017
+ on: {
1018
+ PERMISSION_CHANGE: [
1019
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1020
+ { target: "needs-permission", guard: "noPermission", action: "cleanup" }
1021
+ ],
1022
+ STOP: [{ target: "preview", action: "stopRecording" }],
1023
+ MAX_DURATION: [{ target: "preview", action: "stopRecording" }],
1024
+ INTERRUPT: [{ target: "interrupted", action: "stopRecording" }],
1025
+ RESET: [
1026
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1027
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1028
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1029
+ { target: "needs-permission", action: "cleanup" }
1030
+ ]
1031
+ }
1032
+ },
1033
+ preview: {
1034
+ on: {
1035
+ SAVE: [{ target: "uploading" }],
1036
+ RESET: [
1037
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1038
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1039
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1040
+ { target: "needs-permission", action: "cleanup" }
1041
+ ],
1042
+ // Don't do anything when there are device or permission changes to avoid losing the
1043
+ // recording
1044
+ PERMISSION_CHANGE: [],
1045
+ DEVICE_CHANGE: []
1046
+ }
1047
+ },
1048
+ uploading: {
1049
+ on: {
1050
+ UPLOAD_SUCCESS: [{ target: "processing" }],
1051
+ UPLOAD_ERROR: [{ target: "error" }],
1052
+ RESET: [
1053
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1054
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1055
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1056
+ { target: "needs-permission", action: "cleanup" }
1057
+ ]
1058
+ }
1059
+ },
1060
+ processing: {
1061
+ on: {
1062
+ PROCESSING_COMPLETE: [{ target: "done" }],
1063
+ PROCESSING_ERROR: [{ target: "error" }],
1064
+ RESET: [
1065
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1066
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1067
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1068
+ { target: "needs-permission", action: "cleanup" }
1069
+ ]
1070
+ }
1071
+ },
1072
+ done: {
1073
+ on: {
1074
+ RESET: [
1075
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1076
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1077
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1078
+ { target: "needs-permission", action: "cleanup" }
1079
+ ]
1080
+ }
1081
+ },
1082
+ error: {
1083
+ on: {
1084
+ RETRY: [{ target: "processing", guard: "hasRecordingId" }, { target: "preview" }],
1085
+ RESET: [
1086
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1087
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1088
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1089
+ { target: "needs-permission", action: "cleanup" }
1090
+ ]
1091
+ }
1092
+ },
1093
+ interrupted: {
1094
+ on: {
1095
+ RESET: [
1096
+ { target: "no-microphone", guard: "noDevices", action: "cleanup" },
1097
+ { target: "idle", guard: "hasPermission", action: "cleanup" },
1098
+ { target: "permission-denied", guard: "permissionDenied", action: "cleanup" },
1099
+ { target: "needs-permission", action: "cleanup" }
1100
+ ]
1101
+ }
1102
+ }
1103
+ }
523
1104
  };
524
- function be(e, r) {
525
- Z(r, !0), rr(e, ye);
526
- const i = P(r, "onSelectMic", 7);
527
- let n = O(ar([])), o = O(null), s = null, f = O(!1), v = O(ar(Array(15).fill(1)));
528
- wr(() => {
529
- const l = async () => I(n, await Mr(), !0);
530
- navigator.mediaDevices.ondevicechange = l, l();
531
- });
532
- async function q() {
533
- if (s) {
534
- if (t(f)) {
535
- s.srcObject.getTracks().forEach((l) => l.stop()), I(f, !1);
1105
+ class $t {
1106
+ #e = Ir.initial;
1107
+ #r = 0;
1108
+ #a = 0;
1109
+ #t = null;
1110
+ #s = 3e3;
1111
+ #c = null;
1112
+ #u = null;
1113
+ #g = null;
1114
+ #o = null;
1115
+ #f = null;
1116
+ #d;
1117
+ #n;
1118
+ #v;
1119
+ #p = {
1120
+ countdownStart: null,
1121
+ recordingStart: null
1122
+ };
1123
+ #l = null;
1124
+ #h = null;
1125
+ #w = null;
1126
+ #b = null;
1127
+ #x = null;
1128
+ #_ = null;
1129
+ #E = null;
1130
+ #D = null;
1131
+ #m = null;
1132
+ #y = null;
1133
+ constructor({
1134
+ countdownMs: e = 3e3,
1135
+ maxDurationMs: r = null,
1136
+ _apiFactory: a = null,
1137
+ onStateChange: i,
1138
+ onCountdownTick: n,
1139
+ onRecordingTick: s,
1140
+ onRecordingComplete: h,
1141
+ onUploadComplete: c,
1142
+ onSaveComplete: l,
1143
+ onError: p,
1144
+ onDevicesChange: L
1145
+ } = {}) {
1146
+ this.#s = e, this.#c = r, this.#f = a, this.#w = i, this.#b = n, this.#x = s, this.#_ = h, this.#E = c, this.#D = l, this.#m = p, this.#y = L, this.#d = new Vt({
1147
+ onStop: this.#k
1148
+ }), this.#v = new Zt(), this.#n = new Wt({
1149
+ onDeviceChange: this.#I,
1150
+ onPermissionChange: this.#A
1151
+ });
1152
+ }
1153
+ async init() {
1154
+ await this.#n.init(), await this.#i("READY");
1155
+ }
1156
+ destroy() {
1157
+ cancelAnimationFrame(this.#l), this.#d.destroy(), this.#v.destroy(), this.#n.destroy();
1158
+ }
1159
+ get state() {
1160
+ return this.#e;
1161
+ }
1162
+ get elapsedTime() {
1163
+ return this.#r;
1164
+ }
1165
+ get remainingTime() {
1166
+ return this.#c ? Math.max(0, this.#c - this.#r) : null;
1167
+ }
1168
+ get countdown() {
1169
+ return this.#a;
1170
+ }
1171
+ get audioUrl() {
1172
+ return this.#d.audioUrl;
1173
+ }
1174
+ get waveformSamples() {
1175
+ return this.#v.samples;
1176
+ }
1177
+ get devices() {
1178
+ return this.#n.devices;
1179
+ }
1180
+ get deviceId() {
1181
+ return this.#t;
1182
+ }
1183
+ get recordingId() {
1184
+ return this.#u;
1185
+ }
1186
+ get recording() {
1187
+ return this.#g;
1188
+ }
1189
+ get error() {
1190
+ return this.#o;
1191
+ }
1192
+ set countdownMs(e) {
1193
+ this.#s = e;
1194
+ }
1195
+ set maxDurationMs(e) {
1196
+ this.#c = e;
1197
+ }
1198
+ set _apiFactory(e) {
1199
+ this.#f = e;
1200
+ }
1201
+ async requestPermission() {
1202
+ await this.#n.requestPermission(this.#t);
1203
+ }
1204
+ async setDevice(e) {
1205
+ this.#t = e, await this.#n.requestPermission(this.#t);
1206
+ }
1207
+ async start() {
1208
+ if (this.#e !== "idle") {
1209
+ console.warn(
1210
+ `fortyfour-recording-session: start() can only be called in the "idle" state. current state: "${this.#e}". hint: ensure microphone permission is granted first.`
1211
+ );
1212
+ return;
1213
+ }
1214
+ await this.#i("START");
1215
+ }
1216
+ stop() {
1217
+ if (this.#e !== "recording") {
1218
+ console.warn(
1219
+ `fortyfour-recording-session: stop() can only be called in the "recording" state. current state: "${this.#e}". hint: call start() first to begin recording.`
1220
+ );
1221
+ return;
1222
+ }
1223
+ this.#i("STOP");
1224
+ }
1225
+ async save(e, r = []) {
1226
+ if (this.#e !== "preview" || !this.#d.audioUrl) {
1227
+ console.warn(
1228
+ `fortyfour-recording-session: save() can only be called in the "preview" state. current state: "${this.#e}". hint: record and stop first to reach preview.`
1229
+ );
1230
+ return;
1231
+ }
1232
+ await this.#i("SAVE"), this.#h = new AbortController();
1233
+ const a = this.#h.signal;
1234
+ try {
1235
+ const i = this.#f ? this.#f() : new kr();
1236
+ this.#u = await i.upload(
1237
+ e,
1238
+ r,
1239
+ this.#d.audioUrl,
1240
+ this.#v.samples,
1241
+ a
1242
+ ), this.#E?.(), await this.#i("UPLOAD_SUCCESS"), await this.#R(i, a);
1243
+ } catch (i) {
1244
+ if (i.name === "AbortError")
536
1245
  return;
1246
+ const n = this.#e === "uploading", s = i.code || (n ? "upload-failed" : "processing-failed");
1247
+ this.#o = { code: s, message: i.message || "save recording" }, this.#m?.(this.#o), n ? await this.#i("UPLOAD_ERROR") : await this.#i("PROCESSING_ERROR");
1248
+ } finally {
1249
+ this.#h = null;
1250
+ }
1251
+ }
1252
+ async reset() {
1253
+ if ([
1254
+ "initializing",
1255
+ "no-microphone",
1256
+ "needs-permission",
1257
+ "permission-denied"
1258
+ ].includes(this.#e)) {
1259
+ console.warn(
1260
+ `fortyfour-recording-session: reset() has no effect in the "${this.#e}" state. hint: reset is available after recording has started.`
1261
+ );
1262
+ return;
1263
+ }
1264
+ await this.#i("RESET");
1265
+ }
1266
+ async retry() {
1267
+ if (this.#e !== "error") {
1268
+ console.warn(
1269
+ `fortyfour-recording-session: retry() can only be called in the "error" state. current state: "${this.#e}". hint: retry is available after a failed save.`
1270
+ );
1271
+ return;
1272
+ }
1273
+ this.#o = null;
1274
+ const e = !!this.#u;
1275
+ if (await this.#i("RETRY"), e && this.#e === "processing") {
1276
+ this.#h = new AbortController();
1277
+ const r = this.#h.signal;
1278
+ try {
1279
+ const a = this.#f ? this.#f() : new kr();
1280
+ await this.#R(a, r);
1281
+ } catch (a) {
1282
+ if (a.name === "AbortError")
1283
+ return;
1284
+ const i = a.code || "processing-failed";
1285
+ this.#o = { code: i, message: a.message || "Failed to save recording" }, this.#m?.(this.#o), await this.#i("PROCESSING_ERROR");
1286
+ } finally {
1287
+ this.#h = null;
537
1288
  }
538
- I(v, Array(15).fill(1), !0), I(f, !0);
1289
+ }
1290
+ }
1291
+ handleVisibilityChange(e) {
1292
+ e && (this.#e === "counting-down" || this.#e === "recording") && this.#i("INTERRUPT");
1293
+ }
1294
+ async refreshDevices() {
1295
+ if ([
1296
+ "initializing",
1297
+ "no-microphone",
1298
+ "needs-permission",
1299
+ "permission-denied"
1300
+ ].includes(this.#e)) {
1301
+ console.warn(
1302
+ `fortyfour-recording-session: refreshDevices() requires microphone permission. current state: "${this.#e}". hint: call requestPermission() first.`
1303
+ );
1304
+ return;
1305
+ }
1306
+ await this.#n.refreshDevices(), this.#y?.();
1307
+ }
1308
+ #P = {
1309
+ noDevices: () => this.#n.noDevices(),
1310
+ hasDevices: async () => !await this.#n.noDevices(),
1311
+ hasPermission: () => this.#n.hasPermission(),
1312
+ noPermission: async () => !await this.#n.hasPermission(),
1313
+ permissionDenied: () => this.#n.permissionDenied(),
1314
+ hasCountdown: () => this.#s > 0,
1315
+ hasRecordingId: () => !!this.#u
1316
+ };
1317
+ #M = {
1318
+ startCountdown: async () => {
1319
+ try {
1320
+ await this.#d.warmup(this.#t);
1321
+ } catch (e) {
1322
+ return this.#m?.({ code: "recording-failed", message: e.message }), !1;
1323
+ }
1324
+ this.#p.countdownStart = Date.now(), this.#a = this.#s, this.#b?.(), this.#l = requestAnimationFrame(this.#S);
1325
+ },
1326
+ startRecording: async () => {
539
1327
  try {
540
- let N = function($) {
541
- if (!t(f)) {
542
- g.close();
1328
+ return await this.#d.start(this.#t), this.#v.start(this.#d.stream), this.#p.recordingStart = Date.now(), this.#r = 0, this.#l = requestAnimationFrame(this.#C), !0;
1329
+ } catch (e) {
1330
+ return this.#m?.({ code: "recording-failed", message: e.message }), !1;
1331
+ }
1332
+ },
1333
+ stopRecording: () => {
1334
+ cancelAnimationFrame(this.#l), this.#l = null, this.#d.stop();
1335
+ },
1336
+ cleanup: () => {
1337
+ cancelAnimationFrame(this.#l), this.#l = null, this.#p.countdownStart = null, this.#p.recordingStart = null, this.#h?.abort(), this.#h = null, this.#u = null, this.#g = null, this.#o = null, this.#d.destroy(), this.#v.reset(), this.#r = 0, this.#a = 0;
1338
+ }
1339
+ };
1340
+ async #i(e) {
1341
+ const r = Ir.states[this.#e];
1342
+ if (!r?.on?.[e]) {
1343
+ console.warn(
1344
+ `fortyfour-recording-session: event "${e}" not handled in state "${this.#e}"`
1345
+ );
1346
+ return;
1347
+ }
1348
+ const a = r.on[e];
1349
+ for (const i of a) {
1350
+ const n = i.guard ? this.#P[i.guard] : null;
1351
+ if (!(n && !await n())) {
1352
+ if (i.action) {
1353
+ const s = this.#M[i.action];
1354
+ if (s && await s() === !1)
543
1355
  return;
544
- }
545
- const S = new Uint8Array(y.fftSize);
546
- y.getByteTimeDomainData(S);
547
- let A = 0;
548
- for (let G = 0; G < S.length; G++) {
549
- const V = (S[G] - 128) / 128;
550
- A += V * V;
551
- }
552
- const F = Math.sqrt(A / S.length);
553
- L.push(F), requestAnimationFrame(N);
554
- };
555
- const l = await navigator.mediaDevices.getUserMedia({
556
- audio: {
557
- deviceId: t(o) ? { exact: t(o) } : void 0
558
- }
559
- }), c = new MediaRecorder(l), p = [];
560
- let b;
561
- c.ondataavailable = ($) => $.data.size && p.push($.data), c.onstop = () => {
562
- const $ = new Blob(p, { type: c.mimeType }), S = URL.createObjectURL($);
563
- s.src = S, s.play(), l.getTracks().forEach((A) => A.stop()), I(f, !1), clearInterval(b);
564
- }, c.start(), setTimeout(() => c.stop(), 5e3);
565
- const g = new (window.AudioContext || window.webkitAudioContext)(), u = g.createMediaStreamSource(l), y = g.createAnalyser();
566
- u.connect(y), y.fftSize = 2048;
567
- const h = ($, S) => {
568
- if ($ <= 0) return 0;
569
- const A = 20 * Math.log10($), F = -50, G = -10, cr = (Math.min(G, Math.max(F, A)) - F) / (G - F);
570
- return Math.round(cr * S);
571
- };
572
- let L = [];
573
- N(0);
574
- let K = 0;
575
- b = setInterval(
576
- () => {
577
- const $ = L.reduce((A, F) => A + F, 0) / L.length, S = h($, 100);
578
- t(v)[K++] = S, L = [];
579
- },
580
- 300
581
- );
582
- } catch (l) {
583
- console.error("Error during mic check:", l);
1356
+ }
1357
+ if (this.#e === i.target)
1358
+ return;
1359
+ this.#e = i.target, this.#w?.();
1360
+ return;
584
1361
  }
585
1362
  }
586
1363
  }
587
- var C = {
588
- get onSelectMic() {
1364
+ async #R(e, r) {
1365
+ const a = await e.waitForProcessing(this.#u, r);
1366
+ if (!a) {
1367
+ this.#o = {
1368
+ code: "processing-timeout",
1369
+ message: "Recording processing timeout. Please try again."
1370
+ }, this.#m?.(this.#o), await this.#i("PROCESSING_ERROR");
1371
+ return;
1372
+ }
1373
+ this.#g = a, this.#D?.(a), await this.#i("PROCESSING_COMPLETE");
1374
+ }
1375
+ #k = () => {
1376
+ this.#v.destroy(), this.#_?.();
1377
+ };
1378
+ #S = () => {
1379
+ if (this.#e !== "counting-down") {
1380
+ this.#l = null;
1381
+ return;
1382
+ }
1383
+ const e = Date.now() - this.#p.countdownStart;
1384
+ if (this.#a = Math.max(0, this.#s - e), this.#b?.(), this.#a <= 0) {
1385
+ this.#i("COUNTDOWN_COMPLETE");
1386
+ return;
1387
+ }
1388
+ this.#l = requestAnimationFrame(this.#S);
1389
+ };
1390
+ #C = (e = 0) => {
1391
+ if (this.#e !== "recording") {
1392
+ this.#l = null;
1393
+ return;
1394
+ }
1395
+ if (this.#r = Date.now() - this.#p.recordingStart, this.#v.sample(e), this.#x?.(), this.#c && this.#r >= this.#c) {
1396
+ this.#i("MAX_DURATION");
1397
+ return;
1398
+ }
1399
+ this.#l = requestAnimationFrame(this.#C);
1400
+ };
1401
+ #I = async () => {
1402
+ await this.#n.refreshDevices(), await this.#i("DEVICE_CHANGE"), this.#y?.();
1403
+ };
1404
+ #A = async () => {
1405
+ await this.#i("PERMISSION_CHANGE");
1406
+ };
1407
+ }
1408
+ function ea(d, e) {
1409
+ Je(e, !0);
1410
+ const r = e.$$host;
1411
+ let a = E(e, "countdownMs", 7, 3e3), i = E(e, "maxDurationMs", 7, null);
1412
+ function n(l, p = {}) {
1413
+ r.dispatchEvent(new CustomEvent(l, { bubbles: !0, composed: !0, detail: p }));
1414
+ }
1415
+ const s = new $t({
1416
+ countdownMs: a(),
1417
+ maxDurationMs: i(),
1418
+ onStateChange: () => n("statechange"),
1419
+ onCountdownTick: () => n("countdowntick"),
1420
+ onRecordingTick: () => n("recordingtick"),
1421
+ onRecordingComplete: () => n("recordingcomplete"),
1422
+ onUploadComplete: () => n("uploadcomplete"),
1423
+ onSaveComplete: (l) => n("savecomplete", { recording: l }),
1424
+ onError: (l) => n("error", l),
1425
+ onDevicesChange: () => n("deviceschange")
1426
+ });
1427
+ xr(() => {
1428
+ s.countdownMs = a();
1429
+ }), xr(() => {
1430
+ s.maxDurationMs = i();
1431
+ }), r._setApiFactory = (l) => {
1432
+ s._apiFactory = l;
1433
+ }, s.init();
1434
+ function h() {
1435
+ s.handleVisibilityChange(document.hidden);
1436
+ }
1437
+ Ar(() => {
1438
+ document.addEventListener("visibilitychange", h);
1439
+ }), r.requestPermission = () => s.requestPermission(), r.setDevice = (l) => s.setDevice(l), r.start = () => s.start(), r.stop = () => s.stop(), r.save = (l, p) => s.save(l, p), r.reset = () => s.reset(), r.retry = () => s.retry(), r.refreshDevices = () => s.refreshDevices(), Object.defineProperty(r, "state", { configurable: !0, get: () => s.state }), Object.defineProperty(r, "elapsedTime", { configurable: !0, get: () => s.elapsedTime }), Object.defineProperty(r, "remainingTime", { configurable: !0, get: () => s.remainingTime }), Object.defineProperty(r, "countdown", { configurable: !0, get: () => s.countdown }), Object.defineProperty(r, "audioUrl", { configurable: !0, get: () => s.audioUrl }), Object.defineProperty(r, "waveformSamples", { configurable: !0, get: () => s.waveformSamples }), Object.defineProperty(r, "devices", { configurable: !0, get: () => s.devices }), Object.defineProperty(r, "deviceId", { configurable: !0, get: () => s.deviceId }), Object.defineProperty(r, "recordingId", { configurable: !0, get: () => s.recordingId }), Object.defineProperty(r, "recording", { configurable: !0, get: () => s.recording }), Object.defineProperty(r, "error", { configurable: !0, get: () => s.error }), Nr(() => {
1440
+ document.removeEventListener("visibilitychange", h), s.destroy();
1441
+ });
1442
+ var c = {
1443
+ get countdownMs() {
1444
+ return a();
1445
+ },
1446
+ set countdownMs(l = 3e3) {
1447
+ a(l), D();
1448
+ },
1449
+ get maxDurationMs() {
589
1450
  return i();
590
1451
  },
591
- set onSelectMic(l) {
592
- i(l), B();
593
- }
594
- }, w = ge(), x = z(T(w), 2);
595
- x.__change = [ve, o, i], lr(x, 21, () => t(n), vr, (l, c) => {
596
- var p = ue(), b = T(p, !0);
597
- M(p);
598
- var g = {};
599
- U(() => {
600
- X(b, t(c).label), g !== (g = t(c).id) && (p.value = (p.__value = t(c).id) ?? "");
601
- }), _(l, p);
602
- }), M(x);
603
- var k = z(x, 2), D = z(T(k), 4), E = T(D);
604
- E.__click = q;
605
- var a = T(E, !0);
606
- M(E);
607
- var d = z(E, 2);
608
- kr(d, (l) => s = l, () => s);
609
- var m = z(d, 2);
610
- return lr(m, 21, () => t(v), vr, (l, c, p) => {
611
- var b = pe();
612
- or(b, "x", p * 12), U(() => {
613
- or(b, "y", 100 - t(c)), or(b, "height", t(c));
614
- }), _(l, b);
615
- }), M(m), M(D), M(k), M(w), U(() => X(a, t(f) ? "Stop Testing" : "Let's Check")), _(e, w), er(C);
1452
+ set maxDurationMs(l = null) {
1453
+ i(l), D();
1454
+ }
1455
+ };
1456
+ return Xe(c);
616
1457
  }
617
- nr(["change", "click"]);
618
- Y(be, { onSelectMic: {} }, [], [], !0);
619
- var me = R('<div><p>Recording saved! ID:</p> <code><pre> </pre></code></div> <p><button class="primary">Record Again</button></p>', 1), he = R("<p>Processing your recording…</p>"), _e = xr('<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 640 640" style="fill: currentColor; width: 1em; height: 1em;"><path d="M232.7 69.9L224 96L128 96C110.3 96 96 110.3 96 128C96 145.7 110.3 160 128 160L512 160C529.7 160 544 145.7 544 128C544 110.3 529.7 96 512 96L416 96L407.3 69.9C402.9 56.8 390.7 48 376.9 48L263.1 48C249.3 48 237.1 56.8 232.7 69.9zM512 208L128 208L149.1 531.1C150.7 556.4 171.7 576 197 576L443 576C468.3 576 489.3 556.4 490.9 531.1L512 208z"></path></svg>'), we = R('<div class="confirm svelte-1i5eb1b"><!> <!> <!></div>'), ke = R('<div class="row"><!></div>'), xe = R('<div class="recorder svelte-1i5eb1b" role="group" aria-label="44 audio recorder"><!></div>');
620
- const Ie = {
621
- hash: "svelte-1i5eb1b",
622
- code: `:host {--fortyfour-recorder-bg-0: #2d2d2d;--fortyfour-recorder-bg-1: #393939;--fortyfour-recorder-bg-2: #515151;--fortyfour-recorder-bg-primary: hsla(210, 50%, 60%, 1);--fortyfour-recorder-bg-primary-light: hsla(210, 55%, 64%, 1);--fortyfour-recorder-color-0: #d3d0c8;--fortyfour-recorder-color-primary: hsla(0, 0%, 100%, 0.9);--fortyfour-recorder-red-bg: #f2777a;--fortyfour-recorder-red-color: #ffffff;--fortyfour-recorder-font-size-lg: 1.25rem;--fortyfour-recorder-font-size-md: 1rem;--fortyfour-recorder-font-size-sm: 0.875rem;--fortyfour-recorder-font-size-xs: 0.6825rem;--fortyfour-recorder-radius-xl: 3rem;--fortyfour-recorder-radius-lg: 1rem;--fortyfour-recorder-radius-md: 0.5rem;--fortyfour-recorder-spacing-md: 1rem;--fortyfour-recorder-spacing-sm-1: 0.85rem;--fortyfour-recorder-spacing-sm: 0.5rem;--fortyfour-recorder-radius: var(--fortyfour-recorder-radius-lg);--fortyfour-recorder-bg: var(--fortyfour-recorder-bg-0);--fortyfour-recorder-color: var(--fortyfour-recorder-color-0);--fortyfour-recorder-btn-radius: var(--fortyfour-recorder-radius-xl);--fortyfour-recorder-btn-padding: var(--fortyfour-recorder-spacing-sm)
623
- var(--fortyfour-recorder-spacing-sm-1);--fortyfour-recorder-btn-gap: var(--fortyfour-recorder-spacing-sm);--fortyfour-recorder-btn-bg: var(--fortyfour-recorder-bg-1);--fortyfour-recorder-btn-bg-hover: var(--fortyfour-recorder-bg-2);--fortyfour-recorder-btn-color: var(--fortyfour-recorder-color-0);--fortyfour-recorder-btn-color-hover: var(--fortyfour-recorder-color-0);--fortyfour-recorder-btn-primary-bg: var(--fortyfour-recorder-bg-primary);--fortyfour-recorder-btn-primary-bg-hover: var(--fortyfour-recorder-bg-primary-light);--fortyfour-recorder-btn-primary-color: var(--fortyfour-recorder-color-primary);--fortyfour-recorder-btn-primary-color-hover: var(--fortyfour-recorder-color-primary);--fortyfour-recorder-select-bg: var(--fortyfour-recorder-bg-0);--fortyfour-recorder-select-bg-hover: var(--fortyfour-recorder-bg-1);--fortyfour-recorder-select-border: 1px solid var(--fortyfour-recorder-bg-1);--fortyfour-recorder-select-radius: var(--fortyfour-recorder-radius-md);--fortyfour-recorder-select-shadow: 0 4px 8px hsla(0, 0%, 0%, 0.1);--fortyfour-recorder-select-color: var(--fortyfour-recorder-color-0);--fortyfour-recorder-select-font-size: var(--fortyfour-recorder-font-size-xs);}.recorder.svelte-1i5eb1b {padding:var(--fortyfour-recorder-spacing-md);border-radius:var(--fortyfour-recorder-radius);background:var(--fortyfour-recorder-bg);color:var(--fortyfour-recorder-color);}.confirm.svelte-1i5eb1b {display:flex;align-items:stretch;gap:var(--fortyfour-recorder-spacing-sm);}`
624
- };
625
- function Me(e, r) {
626
- Z(r, !0), rr(e, Ie);
627
- const i = r.$$host;
628
- let n = P(r, "sessionId", 7), o = P(r, "labels", 7, ""), s = P(r, "apiHost", 7, "api.44.audio"), f = O(
629
- "ready"
630
- // "ready", "recording", "confirm", "processing", "done"
631
- ), v = O(null), q = O(null), C = O("");
632
- async function w() {
633
- if (t(f) !== "confirm" || !t(q))
634
- return;
635
- const c = new FormData();
636
- c.append("sessionId", n()), o().split(",").map((u) => u.trim()).forEach((u) => c.append("labels", u));
637
- const b = await (await fetch(t(q))).blob(), g = new File([b], "recording.audio", { type: b.type });
638
- c.append("audioFile", g);
1458
+ customElements.define("fortyfour-recording-session", ge(
1459
+ ea,
1460
+ {
1461
+ countdownMs: { attribute: "countdown-ms", reflect: !0 },
1462
+ maxDurationMs: { attribute: "max-duration-ms", reflect: !0 }
1463
+ },
1464
+ [],
1465
+ [],
1466
+ !1
1467
+ ));
1468
+ var ra = w('<audio preload="auto" hidden></audio>');
1469
+ function ta(d, e) {
1470
+ Je(e, !0);
1471
+ const r = e.$$host;
1472
+ let a = E(e, "src", 7, null), i = E(e, "waveform", 7, "[]"), n = E(e, "durationMs", 7, null), s = M(null), h = M(0), c = M(0), l = M("idle"), p = null;
1473
+ const L = V(() => ({ waveform: m(i()) }));
1474
+ function m(y) {
639
1475
  try {
640
- const y = await (await fetch(`https://${s()}/api/v1/recordings`, { method: "POST", body: c })).json();
641
- I(v, y.recordingId, !0), I(f, "processing");
642
- let h = !1;
643
- for (; !h; )
644
- await new Promise((L) => setTimeout(L, 2e3)), h = await k(t(v));
645
- i.dispatchEvent(new CustomEvent("recording-complete", { detail: { recordingId: t(v) } })), I(f, "done");
646
- } catch (u) {
647
- console.error("Error saving recording:", u), I(f, "ready");
1476
+ return JSON.parse(y);
1477
+ } catch {
1478
+ return [];
648
1479
  }
649
1480
  }
650
1481
  function x() {
651
- I(q, null), I(f, "ready");
1482
+ r.duration = t(c), r.currentTime = t(h), r.state = t(l), r.metadata = t(L), r.setAttribute("data-state", t(l));
652
1483
  }
653
- async function k(c) {
654
- try {
655
- const p = await fetch(`https://${s()}/api/v1/recordings/${c}/status`);
656
- if (!p.ok)
657
- throw new Error("Failed to fetch data");
658
- return (await p.json()).status === "ready";
659
- } catch (p) {
660
- return console.error(p), !1;
1484
+ function P(y) {
1485
+ x(), r.dispatchEvent(new CustomEvent(y, { bubbles: !0, composed: !0 }));
1486
+ }
1487
+ function fe() {
1488
+ if (!t(s)) {
1489
+ p = null;
1490
+ return;
661
1491
  }
1492
+ b(h, Math.floor(t(s).currentTime * 1e3), !0), P("timeupdate"), p = requestAnimationFrame(fe);
662
1493
  }
663
- function D(c) {
664
- I(q, c, !0), I(f, "confirm");
1494
+ async function ce() {
1495
+ if (t(s))
1496
+ try {
1497
+ await t(s).play(), b(l, "playing"), P("play"), p || fe();
1498
+ } catch (y) {
1499
+ console.warn(`fortyfour-preview-recording: ${y.message}`), b(l, "error"), P("error");
1500
+ }
665
1501
  }
666
- var E = {
667
- get sessionId() {
668
- return n();
1502
+ function le() {
1503
+ t(s) && (t(s).pause(), b(l, "paused"), cancelAnimationFrame(p), p = null, P("pause"));
1504
+ }
1505
+ async function ee() {
1506
+ t(l) !== "error" && (t(l) === "playing" ? le() : await ce());
1507
+ }
1508
+ function pe(y) {
1509
+ t(s) && (typeof y != "number" || Number.isNaN(y) || y < 0 || y > t(c) || (t(s).currentTime = y / 1e3, b(h, Math.floor(y), !0), P("timeupdate")));
1510
+ }
1511
+ async function me() {
1512
+ cancelAnimationFrame(p), p = null, b(h, t(c), !0), P("timeupdate"), await st(), b(h, 0), t(s).currentTime = 0, P("timeupdate"), b(l, "ready"), P("ended");
1513
+ }
1514
+ function W(y) {
1515
+ console.warn("fortyfour-preview-recording: audio error", y.target.error), b(l, "error"), P("error");
1516
+ }
1517
+ function q() {
1518
+ b(
1519
+ c,
1520
+ n() ? Number(n()) : Math.floor(t(s).duration * 1e3),
1521
+ !0
1522
+ ), b(l, "ready"), P("loadedmetadata");
1523
+ }
1524
+ let _e = a();
1525
+ xr(() => {
1526
+ a() !== _e && (cancelAnimationFrame(p), p = null, t(s)?.pause(), b(h, 0), b(c, 0), b(l, "idle"), _e = a(), P("timeupdate"));
1527
+ }), r.togglePlay = ee, r.pause = le, r.seek = pe, x(), Nr(() => {
1528
+ t(s)?.pause(), cancelAnimationFrame(p);
1529
+ });
1530
+ var Fe = {
1531
+ get src() {
1532
+ return a();
669
1533
  },
670
- set sessionId(c) {
671
- n(c), B();
1534
+ set src(y = null) {
1535
+ a(y), D();
672
1536
  },
673
- get labels() {
674
- return o();
1537
+ get waveform() {
1538
+ return i();
675
1539
  },
676
- set labels(c = "") {
677
- o(c), B();
1540
+ set waveform(y = "[]") {
1541
+ i(y), D();
678
1542
  },
679
- get apiHost() {
680
- return s();
1543
+ get durationMs() {
1544
+ return n();
681
1545
  },
682
- set apiHost(c = "api.44.audio") {
683
- s(c), B();
1546
+ set durationMs(y = null) {
1547
+ n(y), D();
684
1548
  }
685
- }, a = xe(), d = T(a);
1549
+ }, g = U(), G = k(g);
686
1550
  {
687
- var m = (c) => {
688
- var p = me(), b = J(p), g = z(T(b), 2), u = T(g), y = T(u, !0);
689
- M(u), M(g), M(b);
690
- var h = z(b, 2), L = T(h);
691
- L.__click = x, M(h), U(() => X(y, t(v))), _(c, p);
692
- }, l = (c) => {
693
- var p = pr(), b = J(p);
694
- {
695
- var g = (y) => {
696
- var h = he();
697
- _(y, h);
698
- }, u = (y) => {
699
- var h = pr(), L = J(h);
700
- {
701
- var N = ($) => {
702
- var S = we(), A = T(S);
703
- jr(A, {
704
- get audioURL() {
705
- return t(q);
706
- }
707
- });
708
- var F = z(A, 2);
709
- sr(F, {
710
- onclick: x,
711
- children: (V, cr) => {
712
- var dr = _e();
713
- _(V, dr);
714
- },
715
- $$slots: { default: !0 }
716
- });
717
- var G = z(F, 2);
718
- sr(G, {
719
- type: "primary",
720
- onclick: w,
721
- children: (V, cr) => {
722
- Hr();
723
- var dr = ur("Save");
724
- _(V, dr);
725
- },
726
- $$slots: { default: !0 }
727
- }), M(S), gr(1, S, () => hr, () => ({ y: 20, duration: 700 })), _($, S);
728
- }, K = ($) => {
729
- var S = ke(), A = T(S);
730
- Sr(A, {
731
- onDone: D,
732
- get deviceId() {
733
- return t(C);
734
- },
735
- set deviceId(F) {
736
- I(C, F, !0);
737
- }
738
- }), M(S), gr(1, S, () => hr, () => ({ y: -20, duration: 700 })), _($, S);
739
- };
740
- H(
741
- L,
742
- ($) => {
743
- t(f) === "confirm" ? $(N) : $(K, !1);
744
- },
745
- !0
746
- );
747
- }
748
- _(y, h);
749
- };
750
- H(
751
- b,
752
- (y) => {
753
- t(f) === "processing" ? y(g) : y(u, !1);
754
- },
755
- !0
756
- );
757
- }
758
- _(c, p);
1551
+ var Y = (y) => {
1552
+ var A = ra();
1553
+ ar(A, (de) => b(s, de), () => t(s)), C(() => oe(A, "src", a())), I("ended", A, me), I("error", A, W), I("loadedmetadata", A, q), o(y, A);
759
1554
  };
760
- H(d, (c) => {
761
- t(f) === "done" && t(v) ? c(m) : c(l, !1);
1555
+ _(G, (y) => {
1556
+ a() && y(Y);
762
1557
  });
763
1558
  }
764
- return M(a), _(e, a), er(E);
1559
+ return o(d, g), Xe(Fe);
765
1560
  }
766
- nr(["click"]);
767
- customElements.define("fortyfour-audio-recorder", Y(
768
- Me,
1561
+ customElements.define("fortyfour-preview-recording", ge(
1562
+ ta,
769
1563
  {
770
- apiHost: { attribute: "api-host" },
771
- sessionId: { attribute: "session-id" },
772
- labels: { attribute: "labels" }
1564
+ src: { reflect: !0 },
1565
+ waveform: { reflect: !0 },
1566
+ durationMs: { attribute: "duration-ms", reflect: !0 }
773
1567
  },
774
1568
  [],
775
1569
  [],
776
- !0
1570
+ !1
777
1571
  ));