@limrun/ui 0.15.1 → 0.17.0-rc.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.
Files changed (66) hide show
  1. package/README.md +59 -0
  2. package/dist/GLTFLoader-BKnsBFsj.js +1 -0
  3. package/dist/GLTFLoader-DW6wpvyR.mjs +1679 -0
  4. package/dist/components/duo-button-hinge.d.ts +16 -0
  5. package/dist/components/duo-controls.d.ts +21 -0
  6. package/dist/components/duo-flat-frame.d.ts +7 -0
  7. package/dist/components/duo-flat-geometry.d.ts +52 -0
  8. package/dist/components/duo-fold-motion.d.ts +27 -0
  9. package/dist/components/duo-fold-renderer.d.ts +19 -0
  10. package/dist/components/duo-fold-timing.d.ts +1 -0
  11. package/dist/components/duo-frame.d.ts +16 -0
  12. package/dist/components/duo-hardware.d.ts +20 -0
  13. package/dist/components/duo-model.d.ts +19 -0
  14. package/dist/components/duo-screen-handoff.d.ts +4 -0
  15. package/dist/components/duo-view.d.ts +4 -0
  16. package/dist/components/remote-control-framed.d.ts +2 -0
  17. package/dist/components/remote-control.d.ts +24 -1
  18. package/dist/core/duo.d.ts +63 -0
  19. package/dist/duo-fold-renderer-BXejNHcY.mjs +257 -0
  20. package/dist/duo-fold-renderer-DdltAnF7.js +53 -0
  21. package/dist/duo-frame-BzyYljix.mjs +26767 -0
  22. package/dist/duo-frame-DjfA4gG-.js +4059 -0
  23. package/dist/duo-view-COZg8ieG.js +1 -0
  24. package/dist/duo-view-o1yxIzxu.mjs +654 -0
  25. package/dist/frame-assets.d.ts +2 -0
  26. package/dist/index.cjs +1 -1
  27. package/dist/index.css +1 -1
  28. package/dist/index.d.ts +3 -2
  29. package/dist/index.js +25 -2495
  30. package/dist/lite.cjs +1 -0
  31. package/dist/lite.d.ts +6 -0
  32. package/dist/lite.js +13 -0
  33. package/dist/remote-control-CQjSEVDF.mjs +2673 -0
  34. package/dist/remote-control-DVRXfCR2.js +1 -0
  35. package/package.json +13 -3
  36. package/src/components/duo-button-hinge.test.tsx +138 -0
  37. package/src/components/duo-button-hinge.ts +75 -0
  38. package/src/components/duo-controls.tsx +142 -0
  39. package/src/components/duo-flat-frame.tsx +145 -0
  40. package/src/components/duo-flat-geometry.test.ts +63 -0
  41. package/src/components/duo-flat-geometry.ts +97 -0
  42. package/src/components/duo-fold-motion.test.tsx +245 -0
  43. package/src/components/duo-fold-motion.tsx +192 -0
  44. package/src/components/duo-fold-renderer.test.ts +29 -0
  45. package/src/components/duo-fold-renderer.ts +397 -0
  46. package/src/components/duo-fold-timing.test.ts +44 -0
  47. package/src/components/duo-fold-timing.ts +9 -0
  48. package/src/components/duo-frame.tsx +579 -0
  49. package/src/components/duo-hardware.test.ts +61 -0
  50. package/src/components/duo-hardware.ts +61 -0
  51. package/src/components/duo-model.test.ts +243 -0
  52. package/src/components/duo-model.ts +607 -0
  53. package/src/components/duo-screen-handoff.ts +52 -0
  54. package/src/components/duo-view.test.tsx +104 -0
  55. package/src/components/duo-view.tsx +315 -0
  56. package/src/components/remote-control-framed.tsx +14 -0
  57. package/src/components/remote-control.css +310 -0
  58. package/src/components/remote-control.tsx +259 -59
  59. package/src/core/duo.test.ts +142 -0
  60. package/src/core/duo.ts +156 -0
  61. package/src/demo.tsx +16 -1
  62. package/src/frame-assets.ts +22 -0
  63. package/src/index.ts +5 -1
  64. package/src/lite.test.ts +30 -0
  65. package/src/lite.ts +30 -0
  66. package/vite.config.ts +5 -0
@@ -0,0 +1,654 @@
1
+ import { jsx as n, jsxs as b, Fragment as L } from "react/jsx-runtime";
2
+ import et, { useId as q, useState as I, useRef as M, useEffect as H, useCallback as rt, useLayoutEffect as nt, Suspense as ot, lazy as it } from "react";
3
+ import { H as at, D as _, h as st, i as O, j as ct } from "./remote-control-CQjSEVDF.mjs";
4
+ function dt(t, o, e) {
5
+ const [c, i] = I(t), a = M({ nativeAngle: t, send: o, failed: e });
6
+ a.current = { nativeAngle: t, send: o, failed: e };
7
+ const l = M(void 0), f = M(!1), u = M(null);
8
+ return H(() => (u.current = new at(
9
+ async (x) => {
10
+ await a.current.send(x), l.current === x && (l.current = void 0);
11
+ },
12
+ (x) => {
13
+ l.current = void 0, a.current.failed(String(x)), i(a.current.nativeAngle);
14
+ }
15
+ ), () => u.current?.stop()), []), H(() => {
16
+ !f.current && l.current === void 0 && i(t);
17
+ }, [t]), { angle: c, changeAngle: (x) => {
18
+ a.current.failed(void 0), l.current = x, i(x), u.current?.set(x);
19
+ }, interacting: f };
20
+ }
21
+ function ut({
22
+ angle: t,
23
+ changeAngle: o,
24
+ interacting: e,
25
+ rotate: c,
26
+ onFold: i,
27
+ foldTarget: a,
28
+ onHingeDrag: l,
29
+ children: f
30
+ }) {
31
+ const u = q();
32
+ return /* @__PURE__ */ b("div", { className: "rc-duo-controls", onPointerDown: (d) => d.stopPropagation(), children: [
33
+ /* @__PURE__ */ b("div", { className: "rc-duo-hinge", children: [
34
+ /* @__PURE__ */ n("button", { className: "rc-duo-fold", onClick: i ?? (() => o(t < 90 ? 180 : 0)), children: (a ?? t) < 90 ? "Unfold" : "Fold" }),
35
+ /* @__PURE__ */ n("label", { htmlFor: u, children: "Hinge" }),
36
+ /* @__PURE__ */ n(
37
+ "input",
38
+ {
39
+ id: u,
40
+ type: "range",
41
+ min: 0,
42
+ max: 180,
43
+ step: 1,
44
+ value: t,
45
+ onPointerDown: (d) => {
46
+ l?.(), e.current = !0, d.currentTarget.setPointerCapture(d.pointerId);
47
+ },
48
+ onPointerUp: () => {
49
+ e.current = !1;
50
+ },
51
+ onPointerCancel: () => {
52
+ e.current = !1;
53
+ },
54
+ onLostPointerCapture: () => {
55
+ e.current = !1;
56
+ },
57
+ onChange: (d) => o(Number(d.target.value))
58
+ }
59
+ ),
60
+ /* @__PURE__ */ b("output", { children: [
61
+ Math.round(t),
62
+ "°"
63
+ ] }),
64
+ /* @__PURE__ */ n("button", { className: "rc-duo-rotate", "aria-label": "Rotate device", title: "Rotate device", onClick: c, children: /* @__PURE__ */ b(
65
+ "svg",
66
+ {
67
+ viewBox: "0 0 24 24",
68
+ width: "18",
69
+ height: "18",
70
+ fill: "none",
71
+ stroke: "currentColor",
72
+ strokeWidth: "1.6",
73
+ "aria-hidden": "true",
74
+ children: [
75
+ /* @__PURE__ */ n("rect", { x: "7", y: "3", width: "10", height: "18", rx: "2" }),
76
+ /* @__PURE__ */ n("path", { d: "M3 9a9 9 0 0 1 3-5M3 4v5h5M21 15a9 9 0 0 1-3 5m3 0v-5h-5" })
77
+ ]
78
+ }
79
+ ) })
80
+ ] }),
81
+ f && /* @__PURE__ */ n("div", { className: "rc-duo-views", "aria-label": "Device view", children: f })
82
+ ] });
83
+ }
84
+ function lt({ button: t }) {
85
+ return /* @__PURE__ */ n(
86
+ "svg",
87
+ {
88
+ viewBox: "0 0 24 24",
89
+ width: "24",
90
+ height: "24",
91
+ fill: "none",
92
+ stroke: "currentColor",
93
+ strokeWidth: "1.7",
94
+ strokeLinecap: "round",
95
+ strokeLinejoin: "round",
96
+ "aria-hidden": "true",
97
+ children: t === "side" ? /* @__PURE__ */ b(L, { children: [
98
+ /* @__PURE__ */ n("rect", { x: "6", y: "10", width: "12", height: "11", rx: "2" }),
99
+ /* @__PURE__ */ n("path", { d: "M8 10V7a4 4 0 0 1 8 0v3" })
100
+ ] }) : /* @__PURE__ */ b(L, { children: [
101
+ /* @__PURE__ */ n("path", { d: "M3 9h4l5-5v16l-5-5H3zM17 12h5" }),
102
+ t === "volumeUp" && /* @__PURE__ */ n("path", { d: "M19.5 9.5v5" })
103
+ ] })
104
+ }
105
+ );
106
+ }
107
+ function R(t, o, e, c, i, a) {
108
+ return "M" + (t + i) + "," + o + "H" + (t + e - a) + "a" + a + "," + a + " 0 0 1 " + a + "," + a + "V" + (o + c - a) + "a" + a + "," + a + " 0 0 1 " + -a + "," + a + "H" + (t + i) + "a" + i + "," + i + " 0 0 1 " + -i + "," + -i + "V" + (o + i) + "a" + i + "," + i + " 0 0 1 " + i + "," + -i + "Z";
109
+ }
110
+ function G({ inner: t, width: o, height: e }) {
111
+ const c = q().replace(/:/g, ""), i = t ? 8.4 : 1.25, a = 8.4;
112
+ return /* @__PURE__ */ b("svg", { className: "rc-duo-flat-frame", viewBox: "0 0 " + o + " " + e, "aria-hidden": "true", children: [
113
+ /* @__PURE__ */ b("defs", { children: [
114
+ /* @__PURE__ */ b("linearGradient", { id: c + "-silver", x1: "0", y1: "0", x2: "1", y2: "1", children: [
115
+ /* @__PURE__ */ n("stop", { offset: "0", stopColor: "#62676b" }),
116
+ /* @__PURE__ */ n("stop", { offset: "0.035", stopColor: "#f9faf9" }),
117
+ /* @__PURE__ */ n("stop", { offset: "0.11", stopColor: "#b0b4b6" }),
118
+ /* @__PURE__ */ n("stop", { offset: "0.31", stopColor: "#fdfefd" }),
119
+ /* @__PURE__ */ n("stop", { offset: "0.43", stopColor: "#797f84" }),
120
+ /* @__PURE__ */ n("stop", { offset: "0.51", stopColor: "#e8eaea" }),
121
+ /* @__PURE__ */ n("stop", { offset: "0.7", stopColor: "#979da1" }),
122
+ /* @__PURE__ */ n("stop", { offset: "0.87", stopColor: "#fafbf9" }),
123
+ /* @__PURE__ */ n("stop", { offset: "1", stopColor: "#5f676c" })
124
+ ] }),
125
+ /* @__PURE__ */ b("linearGradient", { id: c + "-spine", children: [
126
+ /* @__PURE__ */ n("stop", { stopColor: "#4a5154" }),
127
+ /* @__PURE__ */ n("stop", { offset: "0.16", stopColor: "#d6d9d9" }),
128
+ /* @__PURE__ */ n("stop", { offset: "0.4", stopColor: "#f8f9f7" }),
129
+ /* @__PURE__ */ n("stop", { offset: "0.62", stopColor: "#a2a8ab" }),
130
+ /* @__PURE__ */ n("stop", { offset: "0.83", stopColor: "#e4e7e5" }),
131
+ /* @__PURE__ */ n("stop", { offset: "1", stopColor: "#666e72" })
132
+ ] })
133
+ ] }),
134
+ !t && /* @__PURE__ */ b(L, { children: [
135
+ /* @__PURE__ */ n(
136
+ "rect",
137
+ {
138
+ x: "-2.3",
139
+ y: "0.7",
140
+ width: "3.3",
141
+ height: e - 1.4,
142
+ rx: "0.85",
143
+ fill: "url(#" + c + "-spine)",
144
+ stroke: "#8b9296",
145
+ strokeWidth: "0.15"
146
+ }
147
+ ),
148
+ /* @__PURE__ */ n("path", { d: "M-.6 2V" + (e - 2), stroke: "#f5f6f4", strokeWidth: "0.22" })
149
+ ] }),
150
+ /* @__PURE__ */ n(
151
+ "path",
152
+ {
153
+ d: R(0, 0, o, e, i, a),
154
+ fill: "url(#" + c + "-silver)",
155
+ stroke: "#696f72",
156
+ strokeWidth: "0.24"
157
+ }
158
+ ),
159
+ /* @__PURE__ */ n(
160
+ "path",
161
+ {
162
+ d: R(0.48, 0.48, o - 0.96, e - 0.96, Math.max(0.5, i - 0.48), a - 0.48),
163
+ fill: "none",
164
+ stroke: "#ffffff",
165
+ strokeOpacity: "0.85",
166
+ strokeWidth: "0.2"
167
+ }
168
+ ),
169
+ /* @__PURE__ */ n(
170
+ "path",
171
+ {
172
+ d: R(1.12, 1.12, o - 2.24, e - 2.24, t ? 7.15 : 0.65, 7.15),
173
+ fill: "#090b0d",
174
+ stroke: "#34393c",
175
+ strokeWidth: "0.2"
176
+ }
177
+ ),
178
+ [o - 16, t ? 19 : 16].map((l) => /* @__PURE__ */ n(et.Fragment, { children: /* @__PURE__ */ n(
179
+ "path",
180
+ {
181
+ d: "M" + l + ",0.17v0.82M" + l + "," + (e - 1) + "v0.82",
182
+ stroke: "#b1b2ac",
183
+ strokeWidth: "1.1"
184
+ }
185
+ ) }, l)),
186
+ t && [0, e - 0.6].map((l) => /* @__PURE__ */ n(
187
+ "rect",
188
+ {
189
+ x: o / 2 - 2.2,
190
+ y: l,
191
+ width: "4.4",
192
+ height: "0.6",
193
+ rx: "0.18",
194
+ fill: "url(#" + c + "-spine)",
195
+ stroke: "#697074",
196
+ strokeWidth: "0.14"
197
+ },
198
+ l
199
+ )),
200
+ /* @__PURE__ */ n(
201
+ "path",
202
+ {
203
+ d: "M" + (o - 0.1) + ",20h-.9m.9," + (e - 40) + "h-.9",
204
+ stroke: "#b1b2ac",
205
+ strokeWidth: "1.05"
206
+ }
207
+ )
208
+ ] });
209
+ }
210
+ function A(t, o, e, c) {
211
+ const i = _.width / (t ? 1 : 2), a = _.height, l = t ? 157.5 : 77.1, f = t ? 110.8 : 112.2, u = (o + (t ? 3 : 0)) % 4, d = Math.max(
212
+ 0,
213
+ Math.min(
214
+ (e - 120) / (u % 2 ? a : i),
215
+ (c - 120) / (u % 2 ? i : a)
216
+ )
217
+ ), x = (h, y) => {
218
+ h = (h - i / 2) * d, y = (y - a / 2) * d;
219
+ const C = u === 1 ? { x: -y, y: h } : u === 2 ? { x: -h, y: -y } : u === 3 ? { x: y, y: -h } : { x: h, y };
220
+ return { x: C.x + e / 2, y: C.y + c / 2 };
221
+ }, P = (u % 2 ? a : i) * d, W = (u % 2 ? i : a) * d, m = {
222
+ min: { x: (e - P) / 2, y: (c - W) / 2 },
223
+ max: { x: (e + P) / 2, y: (c + W) / 2 }
224
+ }, p = [
225
+ { button: "volumeDown", x: i - 37, y: -0.32, width: 9.5, height: 0.65, edge: "top" },
226
+ { button: "volumeUp", x: i - 25, y: -0.32, width: 9.5, height: 0.65, edge: "top" },
227
+ { button: "side", x: i + 0.35, y: a / 2 - 21, width: 0.7, height: 13, edge: "right" }
228
+ ], v = ["top", "right", "bottom", "left"], w = p.map((h) => {
229
+ const y = v[(v.indexOf(h.edge) + u) % 4], C = x(h.x, h.y);
230
+ return y === "top" && (C.y = m.min.y - 28), y === "bottom" && (C.y = m.max.y + 28), y === "left" && (C.x = m.min.x - 28), y === "right" && (C.x = m.max.x + 28), { button: h.button, edge: y, ...C, targetX: C.x, targetY: C.y };
231
+ }), g = w.filter((h) => h.button !== "side"), D = u % 2 ? "y" : "x";
232
+ g.sort((h, y) => h[D] - y[D]);
233
+ const N = u % 2 ? "targetY" : "targetX";
234
+ if (g[1][D] - g[0][D] < 44) {
235
+ const h = (g[0][D] + g[1][D]) / 2;
236
+ g[0][N] = h - 22, g[1][N] = h + 22;
237
+ }
238
+ return {
239
+ bodyWidth: i,
240
+ bodyHeight: a,
241
+ screenWidth: l,
242
+ screenHeight: f,
243
+ scale: d,
244
+ turns: u,
245
+ buttons: p,
246
+ guides: w,
247
+ rect: m,
248
+ iconSize: Math.min(ht(m), 12 * d)
249
+ };
250
+ }
251
+ function ht(t) {
252
+ return Math.max(12, Math.min(24, Math.max(t.max.x - t.min.x, t.max.y - t.min.y) / 24));
253
+ }
254
+ function ft(t, o, e) {
255
+ return [
256
+ ["top", e.min.y - o, t, e.min.x, e.max.x],
257
+ ["bottom", o - e.max.y, t, e.min.x, e.max.x],
258
+ ["left", e.min.x - t, o, e.min.y, e.max.y],
259
+ ["right", t - e.max.x, o, e.min.y, e.max.y]
260
+ ].filter(
261
+ ([, i, a, l, f]) => i >= -7 && i <= 52 && a >= l - 12 && a <= f + 12
262
+ ).sort((i, a) => Math.abs(i[1]) - Math.abs(a[1]))[0]?.[0];
263
+ }
264
+ function U(t) {
265
+ if (!t || t.readyState < 2 || !t.videoWidth || !t.videoHeight) return;
266
+ const o = Math.min(1, 1024 / Math.max(t.videoWidth, t.videoHeight)), e = document.createElement("canvas");
267
+ try {
268
+ const c = e.getContext("2d");
269
+ return c ? (e.width = Math.round(t.videoWidth * o), e.height = Math.round(t.videoHeight * o), c.drawImage(t, 0, 0, e.width, e.height), e) : void 0;
270
+ } catch {
271
+ return;
272
+ }
273
+ }
274
+ function mt(t, o) {
275
+ let e = !1, c;
276
+ const i = (d) => {
277
+ e || (u(), o(d));
278
+ }, a = () => {
279
+ if (e) return;
280
+ const d = U(t);
281
+ d && i(d);
282
+ }, l = () => {
283
+ c = void 0, a(), e || (c = t?.requestVideoFrameCallback?.(l));
284
+ }, f = setTimeout(() => i(void 0), 2500);
285
+ c = t?.requestVideoFrameCallback?.(l), t?.addEventListener("loadeddata", a), !t?.requestVideoFrameCallback && t && t.readyState >= 2 && a();
286
+ function u() {
287
+ e = !0, clearTimeout(f), c !== void 0 && t?.cancelVideoFrameCallback(c), t?.removeEventListener("loadeddata", a);
288
+ }
289
+ return u;
290
+ }
291
+ function pt(t, o, e, c) {
292
+ const i = M(void 0), a = M(c), l = M({ inner: o, frame: e });
293
+ l.current = { inner: o, frame: e };
294
+ const [f, u] = I(), d = M(void 0), x = M(void 0), P = rt(() => {
295
+ clearTimeout(x.current), d.current = void 0, u(void 0);
296
+ }, []), W = (m) => {
297
+ if (m === o) {
298
+ P();
299
+ return;
300
+ }
301
+ if (window.matchMedia?.("(prefers-reduced-motion: reduce)").matches || d.current) return;
302
+ const p = U(t.current);
303
+ if (!p) return;
304
+ const v = l.current;
305
+ d.current = { from: v, to: v, before: p, ready: !1 }, u(d.current), x.current = setTimeout(P, 5e3);
306
+ };
307
+ return H(() => () => clearTimeout(x.current), []), nt(() => {
308
+ const m = i.current, p = { inner: o, frame: e };
309
+ i.current = p;
310
+ const v = a.current !== c;
311
+ if (a.current = c, !m) return;
312
+ if (Math.abs(m.frame.rect.min.x + m.frame.rect.max.x - e.rect.min.x - e.rect.max.x) > 0.5 || Math.abs(m.frame.rect.min.y + m.frame.rect.max.y - e.rect.min.y - e.rect.max.y) > 0.5 || v) {
313
+ P();
314
+ return;
315
+ }
316
+ if (m.inner === o || (u(void 0), !m.frame.scale || !e.scale) || window.matchMedia?.("(prefers-reduced-motion: reduce)").matches) return;
317
+ const g = d.current?.before ?? U(t.current), D = d.current?.from ?? m;
318
+ clearTimeout(x.current), d.current = void 0, g && (p.frame = A(
319
+ o,
320
+ (D.frame.turns + (o ? 1 : 0)) % 4,
321
+ e.rect.min.x + e.rect.max.x,
322
+ e.rect.min.y + e.rect.max.y
323
+ ), u({ from: D, to: p, before: g, ready: !1 }));
324
+ }, [o, e.scale, e.turns, e.rect.min.x, e.rect.min.y, c]), H(() => {
325
+ if (!f || f.from.inner === o) return;
326
+ const m = mt(t.current, (w) => {
327
+ w ? u((g) => g && { ...g, after: w, ready: !0 }) : P();
328
+ }), p = window.matchMedia?.("(prefers-reduced-motion: reduce)"), v = () => {
329
+ p?.matches && u(void 0);
330
+ };
331
+ return p?.addEventListener("change", v), () => {
332
+ m(), p?.removeEventListener("change", v);
333
+ };
334
+ }, [f?.from, o]), { motion: f, finish: P, prepare: W };
335
+ }
336
+ function gt({ pose: t, image: o, scale: e }) {
337
+ const { bodyWidth: c, bodyHeight: i, screenWidth: a, screenHeight: l } = t.frame, f = a * e, u = l * e;
338
+ return /* @__PURE__ */ b("div", { className: "rc-duo-fold-still", style: { width: c * e, height: i * e }, children: [
339
+ /* @__PURE__ */ n(G, { inner: t.inner, width: c, height: i }),
340
+ /* @__PURE__ */ n(
341
+ "div",
342
+ {
343
+ className: "rc-duo-flat-screen",
344
+ style: {
345
+ width: f,
346
+ height: u,
347
+ left: (c - a) * e / 2,
348
+ top: (i - l) * e / 2,
349
+ borderRadius: t.inner ? 5.3 * e : [0.8, 6.6, 6.6, 0.8].map((d) => d * e + "px").join(" ")
350
+ },
351
+ children: o && /* @__PURE__ */ n(
352
+ "canvas",
353
+ {
354
+ ref: (d) => {
355
+ d && (d.width = o.width, d.height = o.height, d.getContext("2d")?.drawImage(o, 0, 0));
356
+ },
357
+ style: {
358
+ width: t.inner ? u : f,
359
+ height: t.inner ? f : u,
360
+ transform: `translate(-50%, -50%) rotate(${t.inner ? 90 : 0}deg)`
361
+ }
362
+ }
363
+ )
364
+ }
365
+ )
366
+ ] });
367
+ }
368
+ function yt({ motion: t, onFinish: o }) {
369
+ const e = M(null), [c, i] = I(!1);
370
+ return H(() => {
371
+ if (i(!1), !t.ready) return;
372
+ let a = !1, l;
373
+ return import("./duo-fold-renderer-BXejNHcY.mjs").then(({ renderFold: f }) => {
374
+ a || !e.current || (l = f(e.current, t, o), i(!0));
375
+ }).catch(() => {
376
+ a || o();
377
+ }), () => {
378
+ a = !0, l?.();
379
+ };
380
+ }, [t.ready, t.from, o]), /* @__PURE__ */ b(L, { children: [
381
+ !c && /* @__PURE__ */ n(
382
+ "div",
383
+ {
384
+ className: "rc-duo-fold-hold",
385
+ "aria-hidden": "true",
386
+ style: {
387
+ width: t.from.frame.bodyWidth * t.from.frame.scale,
388
+ height: t.from.frame.bodyHeight * t.from.frame.scale,
389
+ transform: `translate(-50%, -50%) rotate(${t.from.frame.turns * 90}deg)`
390
+ },
391
+ children: /* @__PURE__ */ n(gt, { pose: t.from, image: t.before, scale: t.from.frame.scale })
392
+ }
393
+ ),
394
+ /* @__PURE__ */ n(
395
+ "canvas",
396
+ {
397
+ ref: e,
398
+ className: "rc-duo-fold-canvas",
399
+ "aria-hidden": "true",
400
+ style: { visibility: c ? "visible" : "hidden" }
401
+ }
402
+ )
403
+ ] });
404
+ }
405
+ const bt = it(() => import("./duo-frame-BzyYljix.mjs").then((t) => t.ac));
406
+ function xt(t) {
407
+ const [o, e] = I("2d");
408
+ return /* @__PURE__ */ b("div", { className: "rc-duo-view", children: [
409
+ o === "3d" ? /* @__PURE__ */ n(ot, { fallback: /* @__PURE__ */ n($, { ...t }), children: /* @__PURE__ */ n(bt, { ...t }) }) : /* @__PURE__ */ n($, { ...t }),
410
+ /* @__PURE__ */ b("div", { className: "rc-duo-mode", role: "group", "aria-label": "Device rendering", children: [
411
+ /* @__PURE__ */ n("button", { type: "button", "aria-pressed": o === "2d", onClick: () => e("2d"), children: "2D" }),
412
+ /* @__PURE__ */ n("button", { type: "button", "aria-pressed": o === "3d", onClick: () => e("3d"), children: "3D" })
413
+ ] })
414
+ ] });
415
+ }
416
+ function $(t) {
417
+ const o = M(null), e = M(null), c = M(t);
418
+ c.current = t;
419
+ const [i, a] = I({ width: 0, height: 0 }), [l, f] = I(), [u, d] = I(), [x, P] = I(), [W, m] = I(), p = M(void 0), v = M(null), w = t.state.displays.find(
420
+ (r) => r.id === (t.state.angleDegrees < 90 ? "outer" : "inner")
421
+ ), g = w?.id === "inner" ? t.inner : t.outer, D = w?.orientation === 2 ? 2 : w?.orientation === 3 ? 1 : w?.orientation === 4 ? 3 : 0, N = w?.id === "inner", h = A(N, D, i.width, i.height), { bodyWidth: y, bodyHeight: C, screenWidth: V, screenHeight: B, scale: k } = h, j = V * k, z = B * k;
422
+ H(() => {
423
+ const r = new ResizeObserver(([s]) => {
424
+ s && a({ width: s.contentRect.width, height: s.contentRect.height });
425
+ });
426
+ return o.current && r.observe(o.current), () => r.disconnect();
427
+ }, []), H(() => {
428
+ const r = e.current;
429
+ if (!r || !g) return;
430
+ const s = () => {
431
+ r.srcObject !== g.srcObject && (r.srcObject = g.srcObject), r.play().catch(() => {
432
+ }), t.outer?.pause(), t.inner?.pause();
433
+ };
434
+ return s(), g.addEventListener("loadedmetadata", s), () => {
435
+ g.removeEventListener("loadedmetadata", s), r.pause(), r.srcObject = null;
436
+ for (const T of [t.outer, t.inner]) T?.play().catch(() => {
437
+ });
438
+ };
439
+ }, [g, t.outer, t.inner]);
440
+ const {
441
+ motion: S,
442
+ finish: K,
443
+ prepare: Z
444
+ } = pt(e, N, h, t.state.orientation), { angle: J, changeAngle: Q, interacting: tt } = dt(
445
+ t.state.angleDegrees,
446
+ async (r) => {
447
+ Z(r >= 90);
448
+ try {
449
+ await t.setAngle(r);
450
+ } catch (s) {
451
+ throw K(), s;
452
+ }
453
+ },
454
+ f
455
+ ), E = () => {
456
+ if (!p.current) return;
457
+ const { screenId: r, x: s, y: T } = p.current;
458
+ c.current.touch(1, r, s, T), p.current = void 0;
459
+ };
460
+ H(() => {
461
+ v.current = new st(
462
+ (s, T) => c.current.button(s, T),
463
+ (s) => f(String(s))
464
+ );
465
+ const r = () => {
466
+ E(), v.current?.release(), m(void 0);
467
+ };
468
+ return window.addEventListener("blur", r), () => {
469
+ r(), window.removeEventListener("blur", r);
470
+ };
471
+ }, []), H(() => {
472
+ E();
473
+ }, [w?.screenId, D]);
474
+ const F = () => {
475
+ v.current?.release(), m(void 0);
476
+ }, X = (r) => ({
477
+ onPointerDown: (s) => {
478
+ S || s.button !== 0 || (s.currentTarget.setPointerCapture(s.pointerId), v.current?.press(r), m(r));
479
+ },
480
+ onPointerUp: F,
481
+ onPointerCancel: F,
482
+ onLostPointerCapture: F,
483
+ onBlur: F,
484
+ onPointerEnter: () => P(r),
485
+ onPointerLeave: () => P(void 0),
486
+ onFocus: () => d(h.guides.find((s) => s.button === r)?.edge),
487
+ onKeyDown: (s) => {
488
+ S || (s.key === "Enter" || s.key === " ") && (s.preventDefault(), s.repeat || (v.current?.press(r), m(r)));
489
+ },
490
+ onKeyUp: (s) => {
491
+ (s.key === "Enter" || s.key === " ") && (s.preventDefault(), F());
492
+ }
493
+ }), Y = (r) => {
494
+ const s = r.currentTarget.getBoundingClientRect();
495
+ return ct(
496
+ (r.clientX - s.left) / s.width,
497
+ (r.clientY - s.top) / s.height,
498
+ D
499
+ );
500
+ };
501
+ return /* @__PURE__ */ b("div", { className: "rc-duo", children: [
502
+ /* @__PURE__ */ b(
503
+ "div",
504
+ {
505
+ ref: o,
506
+ className: "rc-duo-flat-stage",
507
+ "data-folding": !!S,
508
+ "aria-busy": !!S,
509
+ onPointerMove: (r) => {
510
+ const s = r.currentTarget.getBoundingClientRect();
511
+ d(ft(r.clientX - s.left, r.clientY - s.top, h.rect));
512
+ },
513
+ onPointerLeave: () => {
514
+ d(void 0), P(void 0);
515
+ },
516
+ children: [
517
+ /* @__PURE__ */ b(
518
+ "div",
519
+ {
520
+ className: "rc-duo-flat-device",
521
+ "data-display": N ? "inner" : "outer",
522
+ style: {
523
+ width: y * k,
524
+ height: C * k,
525
+ transform: "translate(-50%, -50%) rotate(" + h.turns * 90 + "deg)"
526
+ },
527
+ children: [
528
+ /* @__PURE__ */ n(G, { inner: N, width: y, height: C }),
529
+ /* @__PURE__ */ n(
530
+ "div",
531
+ {
532
+ className: "rc-duo-flat-screen",
533
+ role: "application",
534
+ "aria-label": "iPhone Duo 2D simulator",
535
+ tabIndex: 0,
536
+ style: {
537
+ width: j,
538
+ height: z,
539
+ left: (y - V) / 2 * k,
540
+ top: (C - B) / 2 * k,
541
+ borderRadius: N ? 5.3 * k : [0.8, 6.6, 6.6, 0.8].map((r) => r * k + "px").join(" ")
542
+ },
543
+ onKeyDown: S ? void 0 : t.onKeyDown,
544
+ onKeyUp: t.onKeyUp,
545
+ onPointerDown: (r) => {
546
+ if (S || p.current || r.button !== 0 || !w) return;
547
+ r.currentTarget.focus({ preventScroll: !0 }), r.currentTarget.setPointerCapture(r.pointerId);
548
+ const s = Y(r);
549
+ p.current = { pointer: r.pointerId, screenId: w.screenId, ...s }, t.touch(0, w.screenId, s.x, s.y);
550
+ },
551
+ onPointerMove: (r) => {
552
+ if (p.current?.pointer !== r.pointerId) return;
553
+ const s = Y(r);
554
+ Object.assign(p.current, s), t.touch(2, p.current.screenId, s.x, s.y);
555
+ },
556
+ onPointerUp: (r) => {
557
+ p.current?.pointer === r.pointerId && E();
558
+ },
559
+ onPointerCancel: E,
560
+ onLostPointerCapture: E,
561
+ children: /* @__PURE__ */ n(
562
+ "video",
563
+ {
564
+ ref: e,
565
+ autoPlay: !0,
566
+ muted: !0,
567
+ playsInline: !0,
568
+ style: {
569
+ width: N ? z : j,
570
+ height: N ? j : z,
571
+ transform: "translate(-50%, -50%) rotate(" + (N ? 90 : 0) + "deg)"
572
+ }
573
+ }
574
+ )
575
+ }
576
+ ),
577
+ h.buttons.map((r) => /* @__PURE__ */ n(
578
+ "button",
579
+ {
580
+ type: "button",
581
+ className: "rc-duo-physical",
582
+ "data-duo-button": r.button,
583
+ "data-edge": r.edge,
584
+ "data-highlighted": x === r.button,
585
+ "data-pressed": W === r.button,
586
+ "aria-label": O[r.button] + " physical button",
587
+ title: O[r.button],
588
+ style: {
589
+ left: r.x * k,
590
+ top: r.y * k,
591
+ width: r.edge === "top" ? Math.max(28, r.width * k) : 28,
592
+ height: r.edge === "top" ? 28 : Math.max(28, r.height * k)
593
+ },
594
+ ...X(r.button),
595
+ children: /* @__PURE__ */ n("span", { style: { width: Math.max(2, r.width * k), height: Math.max(2, r.height * k) } })
596
+ },
597
+ r.button
598
+ ))
599
+ ]
600
+ }
601
+ ),
602
+ h.guides.map((r) => /* @__PURE__ */ n(
603
+ "button",
604
+ {
605
+ type: "button",
606
+ className: "rc-duo-hardware",
607
+ "data-duo-button": r.button,
608
+ "data-visible": u === r.edge,
609
+ "data-pressed": W === r.button,
610
+ "aria-label": O[r.button],
611
+ title: O[r.button],
612
+ style: {
613
+ left: r.targetX,
614
+ top: r.targetY,
615
+ "--duo-hardware-icon-size": `${h.iconSize}px`,
616
+ "--duo-hardware-icon-x": `${r.x - r.targetX}px`,
617
+ "--duo-hardware-icon-y": `${r.y - r.targetY}px`
618
+ },
619
+ ...X(r.button),
620
+ children: /* @__PURE__ */ n(lt, { button: r.button })
621
+ },
622
+ r.button
623
+ )),
624
+ S && /* @__PURE__ */ n(yt, { motion: S, onFinish: K })
625
+ ]
626
+ }
627
+ ),
628
+ /* @__PURE__ */ n(
629
+ ut,
630
+ {
631
+ angle: J,
632
+ changeAngle: Q,
633
+ interacting: tt,
634
+ rotate: () => {
635
+ t.setOrientation(t.state.orientation === "portrait" ? "landscape-left" : "portrait").catch((r) => f(String(r)));
636
+ },
637
+ children: /* @__PURE__ */ n("span", { className: "rc-duo-view-label", children: "Front view" })
638
+ }
639
+ ),
640
+ l && /* @__PURE__ */ n("div", { role: "alert", className: "rc-duo-error", children: l })
641
+ ] });
642
+ }
643
+ const Ct = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
644
+ __proto__: null,
645
+ default: xt
646
+ }, Symbol.toStringTag, { value: "Module" }));
647
+ export {
648
+ lt as D,
649
+ ut as a,
650
+ Ct as d,
651
+ ft as f,
652
+ ht as h,
653
+ dt as u
654
+ };
@@ -0,0 +1,2 @@
1
+ import { RemoteControlAssets } from './components/remote-control';
2
+ export declare const defaultRemoteControlAssets: RemoteControlAssets;