@tapflowio/relay 0.9.0 → 0.9.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 (84) hide show
  1. package/dist/index.d.ts +1 -2
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +1 -2
  4. package/dist/index.js.map +1 -1
  5. package/dist/lib/config.d.ts +1 -0
  6. package/dist/lib/config.d.ts.map +1 -1
  7. package/dist/lib/config.js +12 -3
  8. package/dist/lib/config.js.map +1 -1
  9. package/dist/lib/loadEnvFile.d.ts.map +1 -1
  10. package/dist/lib/loadEnvFile.js +3 -1
  11. package/dist/lib/loadEnvFile.js.map +1 -1
  12. package/dist/server.js +4 -6
  13. package/dist/server.js.map +1 -1
  14. package/package.json +5 -5
  15. package/public/assets/AppCenter-CH3MXel8.js +16 -0
  16. package/public/assets/AppCenter-CH3MXel8.js.br +0 -0
  17. package/public/assets/{Default-DQiKj0NT.js → Default-CK_yhJO6.js} +1 -1
  18. package/public/assets/Default-CK_yhJO6.js.br +0 -0
  19. package/public/assets/{Invite-B4MMcQtw.js → Invite-9g1gI701.js} +1 -1
  20. package/public/assets/Invite-9g1gI701.js.br +0 -0
  21. package/public/assets/{MacResources-BfZAJ5BP.js → MacResources-41d3_9X2.js} +1 -1
  22. package/public/assets/MacResources-41d3_9X2.js.br +0 -0
  23. package/public/assets/{NotFound-D85RKzwv.js → NotFound-DsMP9eZN.js} +1 -1
  24. package/public/assets/NotFound-DsMP9eZN.js.br +2 -0
  25. package/public/assets/QASession-B02bILlB.js +130 -0
  26. package/public/assets/QASession-B02bILlB.js.br +0 -0
  27. package/public/assets/{ResetPassword-Degmb6sl.js → ResetPassword-DsXsNFTA.js} +1 -1
  28. package/public/assets/ResetPassword-DsXsNFTA.js.br +0 -0
  29. package/public/assets/{Setup-DKOFxDo2.js → Setup-CouJNq4v.js} +1 -1
  30. package/public/assets/Setup-CouJNq4v.js.br +0 -0
  31. package/public/assets/Team-DUG0YTtb.js +6 -0
  32. package/public/assets/Team-DUG0YTtb.js.br +0 -0
  33. package/public/assets/Tokens-BWBEl4ax.js +6 -0
  34. package/public/assets/Tokens-BWBEl4ax.js.br +0 -0
  35. package/public/assets/alert-dialog-qlHDtr4B.js +1 -0
  36. package/public/assets/alert-dialog-qlHDtr4B.js.br +0 -0
  37. package/public/assets/{badge-Cktrrdvf.js → badge-Cx2-XXcg.js} +1 -1
  38. package/public/assets/badge-Cx2-XXcg.js.br +0 -0
  39. package/public/assets/build-format-BvNznvYq.js +11 -0
  40. package/public/assets/build-format-BvNznvYq.js.br +0 -0
  41. package/public/assets/dialog-DzNUT3NF.js +11 -0
  42. package/public/assets/dialog-DzNUT3NF.js.br +0 -0
  43. package/public/assets/index-Dfs85Uiw.js +274 -0
  44. package/public/assets/index-Dfs85Uiw.js.br +0 -0
  45. package/public/assets/pencil-CrO7Me4O.js +6 -0
  46. package/public/assets/pencil-CrO7Me4O.js.br +0 -0
  47. package/public/assets/plus-DnAOz8DL.js +6 -0
  48. package/public/assets/plus-DnAOz8DL.js.br +0 -0
  49. package/public/assets/{table-NBRnBazr.js → table-BXnp_tRt.js} +1 -1
  50. package/public/assets/table-BXnp_tRt.js.br +0 -0
  51. package/public/assets/tabs-BTnhanO2.js +1 -0
  52. package/public/assets/tabs-BTnhanO2.js.br +0 -0
  53. package/public/index.html +1 -1
  54. package/public/index.html.br +0 -0
  55. package/public/assets/AppCenter-CaY73Tvf.js +0 -16
  56. package/public/assets/AppCenter-CaY73Tvf.js.br +0 -0
  57. package/public/assets/Default-DQiKj0NT.js.br +0 -0
  58. package/public/assets/Invite-B4MMcQtw.js.br +0 -0
  59. package/public/assets/MacResources-BfZAJ5BP.js.br +0 -0
  60. package/public/assets/NotFound-D85RKzwv.js.br +0 -0
  61. package/public/assets/QASession-B9FSUtZo.js +0 -130
  62. package/public/assets/QASession-B9FSUtZo.js.br +0 -0
  63. package/public/assets/ResetPassword-Degmb6sl.js.br +0 -0
  64. package/public/assets/Setup-DKOFxDo2.js.br +0 -0
  65. package/public/assets/Team-Bgspan2B.js +0 -6
  66. package/public/assets/Team-Bgspan2B.js.br +0 -0
  67. package/public/assets/Tokens-C3u48FUG.js +0 -6
  68. package/public/assets/Tokens-C3u48FUG.js.br +0 -0
  69. package/public/assets/alert-dialog-Ci_cWoVo.js +0 -7
  70. package/public/assets/alert-dialog-Ci_cWoVo.js.br +0 -0
  71. package/public/assets/badge-Cktrrdvf.js.br +0 -0
  72. package/public/assets/build-format-Blzidb1D.js +0 -11
  73. package/public/assets/build-format-Blzidb1D.js.br +0 -0
  74. package/public/assets/dialog-BuZjQWBQ.js +0 -11
  75. package/public/assets/dialog-BuZjQWBQ.js.br +0 -0
  76. package/public/assets/index-ClAB0eKw.js +0 -258
  77. package/public/assets/index-ClAB0eKw.js.br +0 -0
  78. package/public/assets/pencil-BoxokH2R.js +0 -6
  79. package/public/assets/pencil-BoxokH2R.js.br +0 -0
  80. package/public/assets/plus-C0Y4Yk9P.js +0 -6
  81. package/public/assets/plus-C0Y4Yk9P.js.br +0 -0
  82. package/public/assets/table-NBRnBazr.js.br +0 -0
  83. package/public/assets/tabs-CB9a8dpY.js +0 -1
  84. package/public/assets/tabs-CB9a8dpY.js.br +0 -0
@@ -0,0 +1,6 @@
1
+ import{Y as a}from"./index-Dfs85Uiw.js";/**
2
+ * @license lucide-react v0.577.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const e=[["path",{d:"M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z",key:"1a8usu"}],["path",{d:"m15 5 4 4",key:"1mk7zo"}]],c=a("pencil",e);export{c as P};
@@ -0,0 +1,6 @@
1
+ import{Y as e}from"./index-Dfs85Uiw.js";/**
2
+ * @license lucide-react v0.577.0 - ISC
3
+ *
4
+ * This source code is licensed under the ISC license.
5
+ * See the LICENSE file in the root directory of this source tree.
6
+ */const o=[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]],t=e("plus",o);export{t as P};
@@ -1 +1 @@
1
- import{a9 as o,a6 as t,J as l}from"./index-ClAB0eKw.js";const r=o.forwardRef(({className:a,...e},s)=>t.jsx("div",{className:"relative w-full overflow-auto",children:t.jsx("table",{ref:s,className:l("w-full caption-bottom text-sm",a),...e})}));r.displayName="Table";const d=o.forwardRef(({className:a,...e},s)=>t.jsx("thead",{ref:s,className:l("[&_tr]:border-b",a),...e}));d.displayName="TableHeader";const m=o.forwardRef(({className:a,...e},s)=>t.jsx("tbody",{ref:s,className:l("[&_tr:last-child]:border-0",a),...e}));m.displayName="TableBody";const b=o.forwardRef(({className:a,...e},s)=>t.jsx("tfoot",{ref:s,className:l("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",a),...e}));b.displayName="TableFooter";const c=o.forwardRef(({className:a,...e},s)=>t.jsx("tr",{ref:s,className:l("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",a),...e}));c.displayName="TableRow";const f=o.forwardRef(({className:a,...e},s)=>t.jsx("th",{ref:s,className:l("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",a),...e}));f.displayName="TableHead";const i=o.forwardRef(({className:a,...e},s)=>t.jsx("td",{ref:s,className:l("p-4 align-middle [&:has([role=checkbox])]:pr-0",a),...e}));i.displayName="TableCell";const n=o.forwardRef(({className:a,...e},s)=>t.jsx("caption",{ref:s,className:l("mt-4 text-sm text-muted-foreground",a),...e}));n.displayName="TableCaption";export{r as T,m as a,i as b,f as c,d,c as e};
1
+ import{a7 as o,a4 as t,K as l}from"./index-Dfs85Uiw.js";const r=o.forwardRef(({className:a,...e},s)=>t.jsx("div",{className:"relative w-full overflow-auto",children:t.jsx("table",{ref:s,className:l("w-full caption-bottom text-sm",a),...e})}));r.displayName="Table";const d=o.forwardRef(({className:a,...e},s)=>t.jsx("thead",{ref:s,className:l("[&_tr]:border-b",a),...e}));d.displayName="TableHeader";const m=o.forwardRef(({className:a,...e},s)=>t.jsx("tbody",{ref:s,className:l("[&_tr:last-child]:border-0",a),...e}));m.displayName="TableBody";const b=o.forwardRef(({className:a,...e},s)=>t.jsx("tfoot",{ref:s,className:l("border-t bg-muted/50 font-medium [&>tr]:last:border-b-0",a),...e}));b.displayName="TableFooter";const c=o.forwardRef(({className:a,...e},s)=>t.jsx("tr",{ref:s,className:l("border-b transition-colors hover:bg-muted/50 data-[state=selected]:bg-muted",a),...e}));c.displayName="TableRow";const f=o.forwardRef(({className:a,...e},s)=>t.jsx("th",{ref:s,className:l("h-12 px-4 text-left align-middle font-medium text-muted-foreground [&:has([role=checkbox])]:pr-0",a),...e}));f.displayName="TableHead";const i=o.forwardRef(({className:a,...e},s)=>t.jsx("td",{ref:s,className:l("p-4 align-middle [&:has([role=checkbox])]:pr-0",a),...e}));i.displayName="TableCell";const n=o.forwardRef(({className:a,...e},s)=>t.jsx("caption",{ref:s,className:l("mt-4 text-sm text-muted-foreground",a),...e}));n.displayName="TableCaption";export{r as T,m as a,i as b,f as c,d,c as e};
@@ -0,0 +1 @@
1
+ import{a7 as i,ag as k,af as M,a4 as f,u as g,aj as D,v as L,r as F,N as m,t as V,Q as G,$ as y,K as T}from"./index-Dfs85Uiw.js";const O=location.protocol==="https:"?"wss:":"ws:",K=`${O}//${location.host}`,J=2e3;function U(e,t){const a=i.useRef(null),[o,c]=i.useState(!1),u=i.useRef(e);u.current=e;const s=i.useRef(t);return s.current=t,i.useEffect(()=>{let l=!1;const d=()=>{if(l)return;const n=new WebSocket(K);n.binaryType="arraybuffer",a.current=n,n.onopen=()=>c(!0),n.onclose=()=>{c(!1),l||setTimeout(d,J)},n.onmessage=r=>{var v;if(r.data instanceof ArrayBuffer){(v=s.current)==null||v.call(s,r.data);return}try{u.current(JSON.parse(r.data))}catch{}}};return d(),()=>{var n;l=!0,(n=a.current)==null||n.close()}},[]),{send:i.useCallback(l=>{var d;((d=a.current)==null?void 0:d.readyState)===WebSocket.OPEN&&a.current.send(JSON.stringify(l))},[]),connected:o}}var p="Tabs",[W]=G(p,[y]),N=y(),[Y,x]=W(p),R=i.forwardRef((e,t)=>{const{__scopeTabs:a,value:o,onValueChange:c,defaultValue:u,orientation:s="horizontal",dir:b,activationMode:l="automatic",...d}=e,n=k(b),[r,v]=M({prop:o,onChange:c,defaultProp:u??"",caller:p});return f.jsx(Y,{scope:a,baseId:D(),value:r,onValueChange:v,orientation:s,dir:n,activationMode:l,children:f.jsx(g.div,{dir:n,"data-orientation":s,...d,ref:t})})});R.displayName=p;var h="TabsList",C=i.forwardRef((e,t)=>{const{__scopeTabs:a,loop:o=!0,...c}=e,u=x(h,a),s=N(a);return f.jsx(L,{asChild:!0,...s,orientation:u.orientation,dir:u.dir,loop:o,children:f.jsx(g.div,{role:"tablist","aria-orientation":u.orientation,...c,ref:t})})});C.displayName=h;var w="TabsTrigger",E=i.forwardRef((e,t)=>{const{__scopeTabs:a,value:o,disabled:c=!1,...u}=e,s=x(w,a),b=N(a),l=j(s.baseId,o),d=A(s.baseId,o),n=o===s.value;return f.jsx(F,{asChild:!0,...b,focusable:!c,active:n,children:f.jsx(g.button,{type:"button",role:"tab","aria-selected":n,"aria-controls":d,"data-state":n?"active":"inactive","data-disabled":c?"":void 0,disabled:c,id:l,...u,ref:t,onMouseDown:m(e.onMouseDown,r=>{!c&&r.button===0&&r.ctrlKey===!1?s.onValueChange(o):r.preventDefault()}),onKeyDown:m(e.onKeyDown,r=>{[" ","Enter"].includes(r.key)&&s.onValueChange(o)}),onFocus:m(e.onFocus,()=>{const r=s.activationMode!=="manual";!n&&!c&&r&&s.onValueChange(o)})})})});E.displayName=w;var I="TabsContent",S=i.forwardRef((e,t)=>{const{__scopeTabs:a,value:o,forceMount:c,children:u,...s}=e,b=x(I,a),l=j(b.baseId,o),d=A(b.baseId,o),n=o===b.value,r=i.useRef(n);return i.useEffect(()=>{const v=requestAnimationFrame(()=>r.current=!1);return()=>cancelAnimationFrame(v)},[]),f.jsx(V,{present:c||n,children:({present:v})=>f.jsx(g.div,{"data-state":n?"active":"inactive","data-orientation":b.orientation,role:"tabpanel","aria-labelledby":l,hidden:!v,id:d,tabIndex:0,...s,ref:t,style:{...e.style,animationDuration:r.current?"0s":void 0},children:v&&u})})});S.displayName=I;function j(e,t){return`${e}-trigger-${t}`}function A(e,t){return`${e}-content-${t}`}var q=R,_=C,P=E,$=S;const X=q,z=i.forwardRef(({className:e,...t},a)=>f.jsx(_,{ref:a,className:T("inline-flex h-9 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground",e),...t}));z.displayName=_.displayName;const B=i.forwardRef(({className:e,...t},a)=>f.jsx(P,{ref:a,className:T("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",e),...t}));B.displayName=P.displayName;const H=i.forwardRef(({className:e,...t},a)=>f.jsx($,{ref:a,className:T("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",e),...t}));H.displayName=$.displayName;export{X as T,H as a,z as b,B as c,U as u};
package/public/index.html CHANGED
@@ -5,7 +5,7 @@
5
5
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
6
6
  <link rel="icon" href="/favicon.svg" type="image/svg+xml" />
7
7
  <title>tapflow</title>
8
- <script type="module" crossorigin src="/assets/index-ClAB0eKw.js"></script>
8
+ <script type="module" crossorigin src="/assets/index-Dfs85Uiw.js"></script>
9
9
  <link rel="stylesheet" crossorigin href="/assets/index-BI7E3MD-.css">
10
10
  </head>
11
11
  <body>
Binary file
@@ -1,16 +0,0 @@
1
- import{Z as T,a9 as n,a6 as e,B as b,L as y,ab as _,J as G,I as L,S as E,g as J,an as Q,ao as Z}from"./index-ClAB0eKw.js";import{d as K,S as W,P as X,g as ee,f as se,h as ae,b as te,u as le}from"./build-format-Blzidb1D.js";import{D as U,f as z,a as M,d as V,e as q,S as k,i as D,j as A,g as C,h as c,C as ne}from"./dialog-BuZjQWBQ.js";import{P as re}from"./plus-C0Y4Yk9P.js";import{B as O}from"./badge-Cktrrdvf.js";import{A as ie,c as ce,f as de,g as oe,d as xe,e as ue,b as pe,a as he}from"./alert-dialog-Ci_cWoVo.js";/**
2
- * @license lucide-react v0.468.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const me=T("Layers",[["path",{d:"M12.83 2.18a2 2 0 0 0-1.66 0L2.6 6.08a1 1 0 0 0 0 1.83l8.58 3.91a2 2 0 0 0 1.66 0l8.58-3.9a1 1 0 0 0 0-1.83z",key:"zw3jo"}],["path",{d:"M2 12a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 12",key:"1wduqc"}],["path",{d:"M2 17a1 1 0 0 0 .58.91l8.6 3.91a2 2 0 0 0 1.65 0l8.58-3.9A1 1 0 0 0 22 17",key:"kqbvx6"}]]);/**
7
- * @license lucide-react v0.468.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const fe=T("Package",[["path",{d:"M11 21.73a2 2 0 0 0 2 0l7-4A2 2 0 0 0 21 16V8a2 2 0 0 0-1-1.73l-7-4a2 2 0 0 0-2 0l-7 4A2 2 0 0 0 3 8v8a2 2 0 0 0 1 1.73z",key:"1a0edw"}],["path",{d:"M12 22V12",key:"d0xqtd"}],["path",{d:"m3.3 7 7.703 4.734a2 2 0 0 0 1.994 0L20.7 7",key:"yx3hmr"}],["path",{d:"m7.5 4.27 9 5.15",key:"1c824w"}]]);/**
12
- * @license lucide-react v0.468.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const ge=T("Upload",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"17 8 12 3 7 8",key:"t8dd8p"}],["line",{x1:"12",x2:"12",y1:"3",y2:"15",key:"widbto"}]]);function je({onSuccess:s,appId:l}){const[u,r]=n.useState(!1),[a,h]=n.useState(null),[d,p]=n.useState("none"),g=n.useRef(null);function f(i){if(i.preventDefault(),!a)return;const o=new FormData;o.append("file",a),d!=="none"&&o.append("status",d),l&&o.append("app_id",String(l));const N=fetch("/api/v1/builds",{method:"POST",credentials:"include",body:o}).then(async x=>{if(!x.ok){const m=await x.json().catch(()=>({}));throw new Error(m.error??"Upload failed. Check the file format.")}s()});_.promise(N,{loading:"Uploading build…",success:"Build uploaded",error:x=>x instanceof Error?x.message:"Failed to upload build"}),r(!1),h(null),p("none")}function v(i){r(i),i||(h(null),p("none"))}return e.jsxs(U,{open:u,onOpenChange:v,children:[e.jsx(z,{asChild:!0,children:e.jsxs(b,{size:"sm",children:[e.jsx(ge,{className:"mr-2 h-4 w-4"}),"Upload build"]})}),e.jsxs(M,{className:"sm:max-w-md",children:[e.jsx(V,{children:e.jsx(q,{children:"Upload build"})}),e.jsxs("form",{onSubmit:f,className:"flex flex-col gap-4 pt-2",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(y,{children:"File"}),e.jsx("div",{className:"flex h-24 cursor-pointer items-center justify-center rounded-md border-2 border-dashed text-sm text-muted-foreground hover:border-primary",onClick:()=>{var i;return(i=g.current)==null?void 0:i.click()},onDragOver:i=>i.preventDefault(),onDrop:i=>{i.preventDefault();const o=i.dataTransfer.files[0];o&&h(o)},children:a?a.name:"Click or drag to upload"}),e.jsx("input",{ref:g,type:"file",accept:".zip,.apk",className:"hidden",onChange:i=>{var o;return h(((o=i.target.files)==null?void 0:o[0])??null)}}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["iOS: ",e.jsx("code",{children:".app.zip"})," (zip the ",e.jsx("code",{children:".app"})," folder after ",e.jsx("code",{children:"xcodebuild -sdk iphonesimulator"}),")  · Android: ",e.jsx("code",{children:".apk"})]})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsxs(y,{children:["Status ",e.jsx("span",{className:"text-muted-foreground",children:"(optional)"})]}),e.jsxs(k,{value:d,onValueChange:p,children:[e.jsx(D,{children:e.jsx(A,{})}),e.jsxs(C,{children:[e.jsx(c,{value:"none",children:"None"}),e.jsx(c,{value:"Backlog",children:"Backlog"}),e.jsx(c,{value:"In Progress",children:"In Progress"}),e.jsx(c,{value:"Done",children:"Done"}),e.jsx(c,{value:"Rejected",children:"Rejected"})]})]})]}),e.jsxs("div",{className:"flex justify-end gap-2",children:[e.jsx(b,{type:"button",variant:"outline",className:"w-24",onClick:()=>r(!1),children:"Cancel"}),e.jsx(b,{type:"submit",className:"w-24",disabled:!a,children:"Upload"})]})]})]})]})}function w({className:s,...l}){return e.jsx("span",{className:G("font-mono text-xs tabular-nums tracking-tight",s),...l})}function ve({onSuccess:s}){const[l,u]=n.useState(!1),[r,a]=n.useState(""),[h,d]=n.useState(""),[p,g]=n.useState("ios"),[f,v]=n.useState(""),[i,o]=n.useState(!1);async function N(x){x.preventDefault(),v(""),o(!0);try{const m=await K({name:r.trim(),bundle_id_key:h.trim(),platform:p});if(!m){v("Failed to create app");return}if("error"in m){v(m.error);return}u(!1),a(""),d(""),g("ios"),_.success("App created"),s()}catch{_.error("Failed to create app — check your network")}finally{o(!1)}}return e.jsxs(U,{open:l,onOpenChange:u,children:[e.jsx(z,{asChild:!0,children:e.jsxs("button",{className:"flex w-full items-center gap-1.5 rounded-md px-2 py-1.5 text-left text-sm text-muted-foreground hover:bg-accent hover:text-foreground transition-colors",children:[e.jsx(re,{className:"size-3.5 shrink-0"}),e.jsx("span",{children:"Add App"})]})}),e.jsxs(M,{className:"sm:max-w-sm",children:[e.jsx(V,{children:e.jsx(q,{children:"Add App"})}),e.jsxs("form",{onSubmit:N,className:"flex flex-col gap-4 pt-2",children:[e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(y,{htmlFor:"app-name",children:"Name"}),e.jsx(L,{id:"app-name",value:r,onChange:x=>a(x.target.value),placeholder:"My App",required:!0})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(y,{htmlFor:"bundle-id",children:"Bundle ID"}),e.jsx(L,{id:"bundle-id",value:h,onChange:x=>d(x.target.value),placeholder:"com.example.myapp",required:!0})]}),e.jsxs("div",{className:"flex flex-col gap-1.5",children:[e.jsx(y,{htmlFor:"platform",children:"Platform"}),e.jsxs(k,{value:p,onValueChange:x=>g(x),children:[e.jsx(D,{id:"platform",children:e.jsx(A,{})}),e.jsxs(C,{children:[e.jsx(c,{value:"ios",children:"iOS"}),e.jsx(c,{value:"android",children:"Android"}),e.jsx(c,{value:"both",children:"Both"})]})]})]}),f&&e.jsx("p",{className:"text-sm text-destructive",children:f}),e.jsx(b,{type:"submit",disabled:i,className:"w-full",children:i?"Creating…":"Create App"})]})]})]})}function Ne({apps:s,selectedAppId:l,onSelect:u,onAdd:r}){return e.jsxs("aside",{className:"w-64 shrink-0 border-r flex flex-col gap-1 p-3 overflow-y-auto",children:[e.jsx("span",{className:"px-2 pb-1 font-mono text-xs font-medium text-muted-foreground uppercase tracking-wider",children:"Apps"}),s.length===0&&e.jsx("span",{className:"px-2 text-sm text-muted-foreground",children:"No apps yet"}),s.map(a=>e.jsxs("button",{onClick:()=>u(a.id),className:["flex flex-col gap-0.5 rounded-md px-2 py-2 text-left text-sm hover:bg-accent overflow-hidden",a.id===l?"bg-accent font-medium":""].join(" "),children:[e.jsx("span",{className:"truncate",children:a.name}),e.jsx(w,{className:"text-muted-foreground truncate",children:a.bundle_id_key})]},a.id)),e.jsx("div",{className:"mt-1 border-t pt-1",children:e.jsx(ve,{onSuccess:r})})]})}function Se(s){const r=new Date(s).getTime()+6048e5-Date.now();if(r<=0)return{label:"Expired",urgent:!0};const a=Math.floor(r/36e5);return a<1?{label:"< 1 hour left",urgent:!0}:a<24?{label:`Expires in ${a}h`,urgent:a<6}:{label:`Expires in ${Math.floor(a/24)}d`,urgent:!1}}function be({build:s,isLast:l,onNavigate:u,onStatusChange:r}){const[a,h]=n.useState(!1),d=s.status_label==="Done",p=d&&s.completed_at?Se(s.completed_at):null;function g(f){if(f==="Done"){h(!0);return}r(s.id,f==="none"?null:f)}return e.jsxs(e.Fragment,{children:[e.jsx(ie,{open:a,onOpenChange:h,children:e.jsxs(ce,{children:[e.jsxs(de,{children:[e.jsx(oe,{children:"Mark as Done?"}),e.jsx(xe,{children:"Build files will be automatically deleted after 7 days. Reverting the status will cancel the scheduled deletion."})]}),e.jsxs(ue,{children:[e.jsx(pe,{children:"Cancel"}),e.jsx(he,{onClick:()=>{r(s.id,"Done"),h(!1)},children:"Confirm"})]})]})}),e.jsxs("div",{className:["flex items-center gap-3 px-4 py-3",l?"":"border-b"].join(" "),children:[e.jsxs("div",{className:"flex-1 min-w-0",children:[e.jsxs("div",{className:"flex items-center gap-2 flex-wrap",children:[e.jsxs("span",{className:"text-sm font-medium",children:["build ",e.jsx(w,{children:s.build_number??"—"})]}),e.jsx(O,{tone:s.platform==="ios"?"ios":"android",className:"text-xs capitalize",children:s.platform}),s.status_label&&e.jsx(O,{tone:W[s.status_label],className:"text-xs",children:s.status_label})]}),e.jsxs("div",{style:{display:"flex",flexDirection:"row",gap:"14px",marginTop:"0.7rem",alignItems:"center"},className:"text-xs text-muted-foreground",children:[s.uploader&&e.jsxs(e.Fragment,{children:[e.jsx("span",{children:s.uploader}),e.jsx(E,{orientation:"vertical",className:"h-3"})]}),e.jsx(w,{children:new Date(s.uploaded_at).toLocaleDateString()}),p&&e.jsxs(e.Fragment,{children:[e.jsx(E,{orientation:"vertical",className:"h-3"}),e.jsx("span",{className:p.urgent?"text-destructive":"",children:p.label})]})]})]}),e.jsxs(k,{value:s.status_label??"none",onValueChange:g,children:[e.jsx(D,{className:"h-9 w-32 text-xs",children:e.jsx(A,{})}),e.jsxs(C,{children:[e.jsx(c,{value:"none",children:e.jsx("span",{className:"text-muted-foreground",children:"—"})}),e.jsx(c,{value:"Backlog",children:"Backlog"}),e.jsx(c,{value:"In Progress",children:"In Progress"}),e.jsx(c,{value:"Done",children:"Done"}),e.jsx(c,{value:"Rejected",children:"Rejected"})]})]}),e.jsxs(b,{size:"sm",onClick:()=>u(s.id),disabled:d,children:[e.jsx(X,{className:"mr-1.5 h-3.5 w-3.5"}),"Start QA"]})]})]})}function ye({versionName:s,builds:l,isOpen:u,onToggle:r,onNavigate:a,onStatusChange:h}){return e.jsxs("div",{className:"rounded-lg shadow-card-2 overflow-hidden",children:[e.jsxs("button",{className:"flex w-full items-center gap-2 px-4 py-3 text-left hover:bg-accent/50 bg-card",onClick:r,children:[u?e.jsx(ne,{className:"h-4 w-4 shrink-0 text-muted-foreground"}):e.jsx(J,{className:"h-4 w-4 shrink-0 text-muted-foreground"}),e.jsx(w,{className:"font-medium text-sm text-foreground",children:s}),e.jsxs("span",{className:"text-xs text-muted-foreground",children:["(",l.length," build",l.length>1?"s":"",")"]})]}),u&&e.jsx("div",{className:"border-t bg-card",children:l.map((d,p)=>e.jsx(be,{build:d,isLast:p===l.length-1,onNavigate:a,onStatusChange:h},d.id))})]})}function Ie(){const s=Q(),[l,u]=Z(),[r,a]=n.useState([]),[h,d]=n.useState([]),[p,g]=n.useState(""),[f,v]=n.useState("all"),[i,o]=n.useState(!0),[N,x]=n.useState(new Set),m=l.get("appId")?Number(l.get("appId")):null,R=r.find(t=>t.id===m)??null,B=n.useCallback(async()=>{const t=await ee();a(t),!l.get("appId")&&t.length>0&&u({appId:String(t[0].id)},{replace:!0})},[l,u]),I=n.useCallback(async()=>{if(!m){d([]),o(!1);return}o(!0);try{const t=await se({appId:m,search:p,statusFilter:f});d(t),t.length>0&&N.size===0&&x(new Set([t[0].version_name??"Unversioned"]))}finally{o(!1)}},[m,p,f]);n.useEffect(()=>{B()},[]),n.useEffect(()=>{I()},[I]);function H(t){t!==m&&(d([]),x(new Set)),u({appId:String(t)})}function $(t){x(S=>{const j=new Set(S);return j.has(t)?j.delete(t):j.add(t),j})}async function Y(t,S){await le(t,S),d(j=>j.map(P=>P.id===t?{...P,status_label:S}:P))}const F=ae(h);return e.jsxs("div",{className:"flex h-full gap-0",children:[e.jsx(Ne,{apps:r,selectedAppId:m,onSelect:H,onAdd:B}),e.jsxs("main",{className:"flex-1 flex flex-col gap-4 p-4 overflow-y-auto min-w-0",children:[e.jsxs("div",{className:"flex items-center justify-between flex-wrap gap-2",children:[e.jsx("h1",{className:"text-xl font-semibold tracking-display-sm",children:R?R.name:"App Center"}),e.jsx(je,{onSuccess:()=>{B(),I()},appId:m})]}),m?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-wrap gap-2",children:[e.jsx(te,{placeholder:"Search version…",value:p,onChange:g}),e.jsxs(k,{value:f,onValueChange:v,children:[e.jsx(D,{className:"h-8 w-36",children:e.jsx(A,{placeholder:"Status"})}),e.jsxs(C,{children:[e.jsx(c,{value:"all",children:"All statuses"}),e.jsx(c,{value:"Backlog",children:"Backlog"}),e.jsx(c,{value:"In Progress",children:"In Progress"}),e.jsx(c,{value:"Done",children:"Done"}),e.jsx(c,{value:"Rejected",children:"Rejected"})]})]})]}),i?e.jsx("p",{className:"text-sm text-muted-foreground",children:"Loading…"}):F.length===0?e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-2 text-center",children:[e.jsx(fe,{className:"w-8 h-8 text-muted-foreground/40"}),e.jsx("p",{className:"text-sm font-medium",children:"No builds yet"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Upload the first build to get started."})]}):e.jsx("div",{className:"flex flex-col gap-2",children:F.map(({versionName:t,builds:S})=>e.jsx(ye,{versionName:t,builds:S,isOpen:N.has(t),onToggle:()=>$(t),onNavigate:j=>s(`/app-center/build?id=${j}`),onStatusChange:Y},t))})]}):e.jsxs("div",{className:"flex-1 flex flex-col items-center justify-center gap-2 text-center",children:[e.jsx(me,{className:"w-8 h-8 text-muted-foreground/40"}),e.jsx("p",{className:"text-sm font-medium",children:"No app selected"}),e.jsx("p",{className:"text-sm text-muted-foreground",children:"Choose an app from the sidebar to view its builds."})]})]})]})}export{Ie as AppCenter};
Binary file
@@ -1,130 +0,0 @@
1
- import{Z as G,a9 as o,ao as Gt,a6 as n,J as Y,x as kt,v as we,y as Se,B as ee,w as Re,S as qt,n as On,ab as at,ag as Fe,ai as $n,q as qe,p as bt,Q as Jt,K as Ue,af as Ge,am as Wn,U as Vn,u as Xn,g as Kn,ah as Yn,ap as Gn,an as qn,ae as Jn,L as Zn}from"./index-ClAB0eKw.js";import{e as Qn,a as er,P as Zt,c as Ht,S as tr,b as nr}from"./build-format-Blzidb1D.js";import{u as Qt,T as rr,b as sr,c as Ut,a as Ft}from"./tabs-CB9a8dpY.js";import{D as en,a as tn,d as or,e as nn,b as ar,c as ir,k as cr,u as lr,S as dr,i as ur,j as hr,g as fr,h as zt}from"./dialog-BuZjQWBQ.js";import{B as pr}from"./badge-Cktrrdvf.js";/**
2
- * @license lucide-react v0.468.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const mr=G("ArrowLeft",[["path",{d:"m12 19-7-7 7-7",key:"1l729n"}],["path",{d:"M19 12H5",key:"x3x0zl"}]]);/**
7
- * @license lucide-react v0.468.0 - ISC
8
- *
9
- * This source code is licensed under the ISC license.
10
- * See the LICENSE file in the root directory of this source tree.
11
- */const gr=G("ArrowUp",[["path",{d:"m5 12 7-7 7 7",key:"hav0vg"}],["path",{d:"M12 19V5",key:"x0mq9r"}]]);/**
12
- * @license lucide-react v0.468.0 - ISC
13
- *
14
- * This source code is licensed under the ISC license.
15
- * See the LICENSE file in the root directory of this source tree.
16
- */const xr=G("Camera",[["path",{d:"M14.5 4h-5L7 7H4a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2V9a2 2 0 0 0-2-2h-3l-2.5-3z",key:"1tc9qg"}],["circle",{cx:"12",cy:"13",r:"3",key:"1vg3eu"}]]);/**
17
- * @license lucide-react v0.468.0 - ISC
18
- *
19
- * This source code is licensed under the ISC license.
20
- * See the LICENSE file in the root directory of this source tree.
21
- */const br=G("Download",[["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["polyline",{points:"7 10 12 15 17 10",key:"2ggqvy"}],["line",{x1:"12",x2:"12",y1:"15",y2:"3",key:"1vk2je"}]]);/**
22
- * @license lucide-react v0.468.0 - ISC
23
- *
24
- * This source code is licensed under the ISC license.
25
- * See the LICENSE file in the root directory of this source tree.
26
- */const yr=G("Film",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M7 3v18",key:"bbkbws"}],["path",{d:"M3 7.5h4",key:"zfgn84"}],["path",{d:"M3 12h18",key:"1i2n21"}],["path",{d:"M3 16.5h4",key:"1230mu"}],["path",{d:"M17 3v18",key:"in4fa5"}],["path",{d:"M17 7.5h4",key:"myr1c1"}],["path",{d:"M17 16.5h4",key:"go4c1d"}]]);/**
27
- * @license lucide-react v0.468.0 - ISC
28
- *
29
- * This source code is licensed under the ISC license.
30
- * See the LICENSE file in the root directory of this source tree.
31
- */const rn=G("House",[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-5.999a2 2 0 0 1 2.582 0l7 5.999A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"1d0kgt"}]]);/**
32
- * @license lucide-react v0.468.0 - ISC
33
- *
34
- * This source code is licensed under the ISC license.
35
- * See the LICENSE file in the root directory of this source tree.
36
- */const vr=G("ImagePlus",[["path",{d:"M16 5h6",key:"1vod17"}],["path",{d:"M19 2v6",key:"4bpg5p"}],["path",{d:"M21 11.5V19a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h7.5",key:"1ue2ih"}],["path",{d:"m21 15-3.086-3.086a2 2 0 0 0-2.828 0L6 21",key:"1xmnt7"}],["circle",{cx:"9",cy:"9",r:"2",key:"af1f0g"}]]);/**
37
- * @license lucide-react v0.468.0 - ISC
38
- *
39
- * This source code is licensed under the ISC license.
40
- * See the LICENSE file in the root directory of this source tree.
41
- */const wr=G("Info",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 16v-4",key:"1dtifu"}],["path",{d:"M12 8h.01",key:"e9boi3"}]]);/**
42
- * @license lucide-react v0.468.0 - ISC
43
- *
44
- * This source code is licensed under the ISC license.
45
- * See the LICENSE file in the root directory of this source tree.
46
- */const Sr=G("Keyboard",[["path",{d:"M10 8h.01",key:"1r9ogq"}],["path",{d:"M12 12h.01",key:"1mp3jc"}],["path",{d:"M14 8h.01",key:"1primd"}],["path",{d:"M16 12h.01",key:"1l6xoz"}],["path",{d:"M18 8h.01",key:"emo2bl"}],["path",{d:"M6 8h.01",key:"x9i8wu"}],["path",{d:"M7 16h10",key:"wp8him"}],["path",{d:"M8 12h.01",key:"czm47f"}],["rect",{width:"20",height:"16",x:"2",y:"4",rx:"2",key:"18n3k1"}]]);/**
47
- * @license lucide-react v0.468.0 - ISC
48
- *
49
- * This source code is licensed under the ISC license.
50
- * See the LICENSE file in the root directory of this source tree.
51
- */const sn=G("Link2",[["path",{d:"M9 17H7A5 5 0 0 1 7 7h2",key:"8i5ue5"}],["path",{d:"M15 7h2a5 5 0 1 1 0 10h-2",key:"1b9ql8"}],["line",{x1:"8",x2:"16",y1:"12",y2:"12",key:"1jonct"}]]);/**
52
- * @license lucide-react v0.468.0 - ISC
53
- *
54
- * This source code is licensed under the ISC license.
55
- * See the LICENSE file in the root directory of this source tree.
56
- */const pt=G("LoaderCircle",[["path",{d:"M21 12a9 9 0 1 1-6.219-8.56",key:"13zald"}]]);/**
57
- * @license lucide-react v0.468.0 - ISC
58
- *
59
- * This source code is licensed under the ISC license.
60
- * See the LICENSE file in the root directory of this source tree.
61
- */const Rr=G("MessageSquare",[["path",{d:"M21 15a2 2 0 0 1-2 2H7l-4 4V5a2 2 0 0 1 2-2h14a2 2 0 0 1 2 2z",key:"1lielz"}]]);/**
62
- * @license lucide-react v0.468.0 - ISC
63
- *
64
- * This source code is licensed under the ISC license.
65
- * See the LICENSE file in the root directory of this source tree.
66
- */const jr=G("Power",[["path",{d:"M12 2v10",key:"mnfbl"}],["path",{d:"M18.4 6.6a9 9 0 1 1-12.77.04",key:"obofu9"}]]);/**
67
- * @license lucide-react v0.468.0 - ISC
68
- *
69
- * This source code is licensed under the ISC license.
70
- * See the LICENSE file in the root directory of this source tree.
71
- */const kr=G("RotateCw",[["path",{d:"M21 12a9 9 0 1 1-9-9c2.52 0 4.93 1 6.74 2.74L21 8",key:"1p45f6"}],["path",{d:"M21 3v5h-5",key:"1q7to0"}]]);/**
72
- * @license lucide-react v0.468.0 - ISC
73
- *
74
- * This source code is licensed under the ISC license.
75
- * See the LICENSE file in the root directory of this source tree.
76
- */const Cr=G("ScanLine",[["path",{d:"M3 7V5a2 2 0 0 1 2-2h2",key:"aa7l1z"}],["path",{d:"M17 3h2a2 2 0 0 1 2 2v2",key:"4qcy5o"}],["path",{d:"M21 17v2a2 2 0 0 1-2 2h-2",key:"6vwrx8"}],["path",{d:"M7 21H5a2 2 0 0 1-2-2v-2",key:"ioqczr"}],["path",{d:"M7 12h10",key:"b7w52i"}]]);/**
77
- * @license lucide-react v0.468.0 - ISC
78
- *
79
- * This source code is licensed under the ISC license.
80
- * See the LICENSE file in the root directory of this source tree.
81
- */const Er=G("Square",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}]]);/**
82
- * @license lucide-react v0.468.0 - ISC
83
- *
84
- * This source code is licensed under the ISC license.
85
- * See the LICENSE file in the root directory of this source tree.
86
- */const Nr=G("Video",[["path",{d:"m16 13 5.223 3.482a.5.5 0 0 0 .777-.416V7.87a.5.5 0 0 0-.752-.432L16 10.5",key:"ftymec"}],["rect",{x:"2",y:"6",width:"14",height:"12",rx:"2",key:"158x01"}]]);/**
87
- * @license lucide-react v0.468.0 - ISC
88
- *
89
- * This source code is licensed under the ISC license.
90
- * See the LICENSE file in the root directory of this source tree.
91
- */const Tr=G("Volume1",[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}]]);/**
92
- * @license lucide-react v0.468.0 - ISC
93
- *
94
- * This source code is licensed under the ISC license.
95
- * See the LICENSE file in the root directory of this source tree.
96
- */const Pr=G("Volume2",[["path",{d:"M11 4.702a.705.705 0 0 0-1.203-.498L6.413 7.587A1.4 1.4 0 0 1 5.416 8H3a1 1 0 0 0-1 1v6a1 1 0 0 0 1 1h2.416a1.4 1.4 0 0 1 .997.413l3.383 3.384A.705.705 0 0 0 11 19.298z",key:"uqj9uw"}],["path",{d:"M16 9a5 5 0 0 1 0 6",key:"1q6k2b"}],["path",{d:"M19.364 18.364a9 9 0 0 0 0-12.728",key:"ijwkga"}]]);function Ar(e){const[t,r]=o.useState(null);return o.useEffect(()=>{e&&Qn(e).then(r)},[e]),{build:t}}function _r(e){const[t,r]=o.useState([]),[s,a]=o.useState(null),[i,l]=o.useState(null),[f,h]=o.useState(""),[m,p]=o.useState(!1),[x,d]=o.useState(""),v=o.useCallback(D=>{D.type==="agents:listed"&&r(D.sessions),D.type==="session:joined"&&(p(!1),d("Connected")),D.type==="error"&&(p(!1),d(`Error: ${D.message}`))},[]),{send:R,connected:U}=Qt(v);o.useEffect(()=>{if(!U)return;R({type:"agents:list"});const D=setInterval(()=>R({type:"agents:list"}),5e3);return()=>clearInterval(D)},[U,R]);const k=o.useRef({sessionId:i,deviceId:f});o.useEffect(()=>{k.current={sessionId:i,deviceId:f}},[i,f]),o.useEffect(()=>()=>{const{sessionId:D,deviceId:I}=k.current;D&&I&&R({type:"device:shutdown",sessionId:D,payload:{deviceId:I}})},[R]);const _=t.filter(D=>D.devices.some(I=>I.platform===e)),A=o.useCallback(D=>{h(D.id),p(!0),d("Booting…"),l(D.sessionId)},[]),C=o.useCallback(()=>h(""),[]),P=o.useCallback(()=>{const{sessionId:D,deviceId:I}=k.current;D&&I&&R({type:"device:shutdown",sessionId:D,payload:{deviceId:I}}),l(null),p(!1),d("")},[R]),F=o.useCallback(()=>{const{sessionId:D,deviceId:I}=k.current;D&&I&&R({type:"device:shutdown",sessionId:D,payload:{deviceId:I}}),l(null),a(null),p(!1),d("")},[R]);return{sessions:t,selectedAgent:s,setSelectedAgent:a,activeSessionId:i,deviceId:f,booting:m,status:x,send:R,connected:U,agentGroups:_,startDevice:A,resetDevice:C,handleBack:P,handleBackToMacs:F}}function Dr(e,t){const[r,s]=o.useState(""),[a,i]=o.useState(""),[l,f]=o.useState("app-only"),h=(e==null?void 0:e.devices.filter(x=>x.platform===t))??[],m=[...new Set(h.map(x=>x.osVersion).filter(Boolean))].sort((x,d)=>{const v=k=>k.replace(/^[^\d]*/,"").split(".").map(Number),[R,U]=[v(x),v(d)];for(let k=0;k<Math.max(R.length,U.length);k++){const _=(U[k]??0)-(R[k]??0);if(_!==0)return _}return 0}),p=(r?h.filter(x=>x.osVersion===r):h).filter(x=>!a||x.name.toLowerCase().includes(a.toLowerCase()));return{filteredDevices:h,osVersions:m,osVersion:r,setOsVersion:s,deviceSearch:a,setDeviceSearch:i,versionedDevices:p,resetMode:l,setResetMode:f}}function Lr(){const[e]=Gt(),t=e.get("perf")==="1",[r,s]=o.useState(t);return o.useEffect(()=>{if(!t){s(!1);return}s(!0);const a=i=>{i.ctrlKey&&i.shiftKey&&i.key==="P"&&s(l=>!l)};return window.addEventListener("keydown",a),()=>window.removeEventListener("keydown",a)},[t]),{perfMode:t,visible:r}}const Mr=["video/mp4;codecs=avc1","video/webm;codecs=vp9","video/webm;codecs=vp8","video/webm"];function on({sessionId:e,buildId:t,onRecordingUploaded:r}){const[s,a]=o.useState("idle"),i=o.useRef(null),l=o.useRef(r);o.useEffect(()=>{l.current=r},[r]);const f=o.useRef(!1),h=o.useRef(null),m=o.useRef([]),p=o.useRef(""),x=o.useRef(0),d=o.useRef(null),v=o.useCallback(()=>{var k;f.current&&((k=d.current)==null||k.call(d),x.current=requestAnimationFrame(v))},[]),R=o.useCallback(k=>{const _=i.current;if(!_)return;const A=_.getContext("2d");A&&(A.fillStyle="#000",A.fillRect(0,0,_.width,_.height));const C=Mr.find(F=>MediaRecorder.isTypeSupported(F))??"";if(!C)return;p.current=C,m.current=[];const P=new MediaRecorder(_.captureStream(30),{mimeType:C});P.ondataavailable=F=>{F.data.size>0&&m.current.push(F.data)},h.current=P,P.start(1e3),d.current=k,f.current=!0,x.current=requestAnimationFrame(v),a("recording")},[v]),U=o.useCallback(async()=>{var F;a("uploading"),f.current=!1,cancelAnimationFrame(x.current);const k=h.current;if(!k){a("idle");return}await new Promise(D=>{const I=setTimeout(D,5e3);k.onstop=()=>{clearTimeout(I),D()};try{k.stop()}catch{clearTimeout(I),D()}}),h.current=null;const _=p.current,A=_.includes("mp4")?".mp4":".webm",C=new Blob(m.current,{type:_});m.current=[];const P=new FormData;P.append("file",C,`tapflow-${Date.now()}${A}`);try{const D=new URLSearchParams({sessionId:e});t&&D.set("buildId",String(t));const I=await fetch(`/api/v1/recordings/upload?${D}`,{method:"POST",credentials:"include",body:P}),X=await I.json();if(I.ok&&X.url){const z=document.createElement("a");z.href=X.url,z.download="",z.click(),(F=l.current)==null||F.call(l),a("done"),setTimeout(()=>a("idle"),2e3)}else a("idle")}catch{a("idle")}},[e,t]);return o.useEffect(()=>{if(s!=="recording")return;const k=()=>{document.visibilityState==="hidden"&&U()};return document.addEventListener("visibilitychange",k),()=>{var _;document.removeEventListener("visibilitychange",k),f.current&&(f.current=!1,cancelAnimationFrame(x.current),(_=h.current)==null||_.stop(),h.current=null)}},[s,U]),{recordState:s,recordCanvasRef:i,startClientRecording:R,stopClientRecording:U}}function an(){const e=o.useRef(0),[t,r]=o.useState(0);return o.useEffect(()=>{const s=setInterval(()=>{r(e.current),e.current=0},1e3);return()=>clearInterval(s)},[]),{fps:t,frameCount:e}}function Ye({className:e,...t}){return n.jsx("kbd",{"data-slot":"kbd",className:Y("bg-muted text-muted-foreground pointer-events-none inline-flex h-5 w-fit min-w-5 select-none items-center justify-center gap-1 rounded-sm px-1 font-sans text-xs font-medium","[&_svg:not([class*='size-'])]:size-3","[[data-slot=tooltip-content]_&]:bg-background/20 [[data-slot=tooltip-content]_&]:text-background dark:[[data-slot=tooltip-content]_&]:bg-background/10",e),...t})}function Ct({className:e,...t}){return n.jsx("kbd",{"data-slot":"kbd-group",className:Y("inline-flex items-center gap-1",e),...t})}function rt({label:e,keys:t}){return n.jsxs("span",{className:"flex items-center gap-3",children:[e,n.jsx(Ct,{children:t.map(r=>n.jsx(Ye,{children:r},r))})]})}function cn({joined:e,onScreenshot:t,onRecordToggle:r,recordState:s,onRotate:a,onDeepLink:i,platformSlot:l,launchSlot:f}){return e?n.jsx(kt,{delayDuration:400,children:n.jsxs("div",{className:"flex flex-col items-center gap-0.5 rounded-2xl border bg-background/90 backdrop-blur-sm px-1.5 py-2.5 shrink-0 mt-3",children:[f,l,n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:i,children:n.jsx(sn,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:n.jsx(rt,{label:"Deeplink",keys:["⌘","K"]})})]}),n.jsx("div",{className:"w-4 h-px bg-border my-1"}),n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:t,children:n.jsx(xr,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:n.jsx(rt,{label:"Screenshot",keys:["⌘","S"]})})]}),n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:Y("h-8 w-8",s==="recording"&&"text-red-500 hover:text-red-500"),disabled:s==="uploading"||s==="done",onClick:r,children:s==="uploading"?n.jsx(pt,{className:"h-4 w-4 animate-spin"}):s==="recording"?n.jsx(Er,{className:"h-4 w-4 fill-current"}):n.jsx(Nr,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:s==="idle"?n.jsx(rt,{label:"Start recording",keys:["⌘","⇧","Y"]}):s==="recording"?n.jsx(rt,{label:"Stop recording",keys:["⌘","⇧","Y"]}):"Processing…"})]}),n.jsx("div",{className:"w-4 h-px bg-border my-1"}),n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:a,children:n.jsx(kr,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:n.jsx(rt,{label:"Rotate",keys:["⌘","⇧","O"]})})]})]})}):null}class Et{constructor(t){this.bytes=t,this.bitPos=0}get position(){return this.bitPos}bit(){const t=this.bitPos>>3,r=7-(this.bitPos&7);return this.bitPos++,t>=this.bytes.length?0:this.bytes[t]>>r&1}bits(t){let r=0;for(let s=0;s<t;s++)r=r<<1|this.bit();return r>>>0}flag(){return this.bit()===1}ue(){let t=0;for(;this.bit()===0&&t<32;)t++;return t===0?0:(1<<t)-1+this.bits(t)}se(){const t=this.ue();return t&1?Math.ceil(t/2):-Math.ceil(t/2)}}class Hr{constructor(){this.bitsArr=[]}bit(t){this.bitsArr.push(t&1)}ue(t){const r=t+1,s=Math.floor(Math.log2(r));for(let a=0;a<s;a++)this.bit(0);for(let a=s;a>=0;a--)this.bit(r>>a&1)}toBytes(){const t=[];for(let r=0;r<this.bitsArr.length;r+=8){let s=0;for(let a=0;a<8;a++)s=s<<1|(this.bitsArr[r+a]??0);t.push(s)}return new Uint8Array(t)}}function ln(e){const t=[];let r=0;for(let s=1;s<e.length;s++){const a=e[s];if(r>=2&&a===3){r=0;continue}t.push(a),r=a===0?r+1:0}return new Uint8Array(t)}function Ur(e){const t=[];let r=0;for(const s of e)r>=2&&s<=3&&(t.push(3),r=0),t.push(s),r=s===0?r+1:0;return new Uint8Array(t)}const Fr=new Set([100,110,122,244,44,83,86,118,128,138,139,134,135]);function Bt(e){const t=e.ue()+1;e.bits(4),e.bits(4);for(let r=0;r<t;r++)e.ue(),e.ue(),e.flag();e.bits(5),e.bits(5),e.bits(5),e.bits(5)}function dn(e){const t=e.bits(8);e.bits(8);const r=e.bits(8);if(e.ue(),Fr.has(t)){const x=e.ue();if(x===3&&e.flag(),e.ue(),e.ue(),e.flag(),e.flag()){const d=x!==3?8:12;for(let v=0;v<d;v++)if(e.flag()){const R=v<6?16:64;let U=8,k=8;for(let _=0;_<R;_++)k!==0&&(k=(U+e.se()+256)%256),U=k===0?U:k}}}e.ue();const s=e.ue();if(s===0)e.ue();else if(s===1){e.flag(),e.se(),e.se();const x=e.ue();for(let d=0;d<x;d++)e.se()}const a=e.ue();e.flag(),e.ue(),e.ue(),e.flag()||e.flag(),e.flag(),e.flag()&&(e.ue(),e.ue(),e.ue(),e.ue());const i={profileIdc:t,levelIdc:r,numRefFrames:a,bitstreamRestriction:!1,maxNumReorderFrames:null,maxDecFrameBuffering:null};if(!e.flag())return{...i,vuiPresent:!1,restrictionFlagPos:-1};e.flag()&&e.bits(8)===255&&(e.bits(16),e.bits(16)),e.flag()&&e.flag(),e.flag()&&(e.bits(3),e.flag(),e.flag()&&(e.bits(8),e.bits(8),e.bits(8))),e.flag()&&(e.ue(),e.ue()),e.flag()&&(e.bits(32),e.bits(32),e.flag());const f=e.flag();f&&Bt(e);const h=e.flag();h&&Bt(e),(f||h)&&e.flag(),e.flag();const m=e.position;return e.flag()?(e.flag(),e.ue(),e.ue(),e.ue(),e.ue(),{...i,vuiPresent:!0,bitstreamRestriction:!0,maxNumReorderFrames:e.ue(),maxDecFrameBuffering:e.ue(),restrictionFlagPos:m}):{...i,vuiPresent:!0,restrictionFlagPos:m}}function zr(e){const t=dn(new Et(ln(e)));return{profileIdc:t.profileIdc,levelIdc:t.levelIdc,vuiPresent:t.vuiPresent,bitstreamRestriction:t.bitstreamRestriction,maxNumReorderFrames:t.maxNumReorderFrames,maxDecFrameBuffering:t.maxDecFrameBuffering}}function Br(e){const t=ln(e),r=dn(new Et(t));if(!r.vuiPresent||r.restrictionFlagPos<0||r.bitstreamRestriction)return null;const s=new Hr,a=new Et(t);for(let i=0;i<r.restrictionFlagPos;i++)s.bit(a.bit());return s.bit(1),s.bit(1),s.ue(0),s.ue(0),s.ue(0),s.ue(0),s.ue(0),s.ue(r.numRefFrames),s.bit(1),Uint8Array.from([e[0],...Ur(s.toBytes())])}function Ir(e){const t=[],r=e.length;let s=-1,a=0;for(;a+2<r;){const i=a+3<r&&e[a]===0&&e[a+1]===0&&e[a+2]===0&&e[a+3]===1,l=e[a]===0&&e[a+1]===0&&e[a+2]===1;i||l?(s>=0&&t.push(e.subarray(s,a)),a+=i?4:3,s=a):a++}return s>=0&&t.push(e.subarray(s,r)),t}class Or{constructor(t){this.onFrame=t,this.decoder=null,this.sps=null,this.pps=null,this.frameCount=0,this.submitAt=new Map,this.spsLogged=!1}setDecodeSampler(t){this.decodeSampler=t}decode(t){const r=[];let s=!1;for(const m of Ir(new Uint8Array(t))){const p=m[0]&31;if(p===7){const x=!this.sps||m.length!==this.sps.length||m.some((d,v)=>d!==this.sps[v]);this.sps=m,x&&this.decoder&&(this.decoder.close(),this.decoder=null)}else p===8?this.pps=m:p>=1&&p<=5&&(p===5&&(s=!0),r.push(m))}if(s&&this.sps&&this.pps&&!this.decoder&&this.initDecoder(this.sps,this.pps),!this.decoder||r.length===0)return;let a=0;for(const m of r)a+=4+m.length;const i=new Uint8Array(a),l=new DataView(i.buffer);let f=0;for(const m of r)l.setUint32(f,m.length,!1),f+=4,i.set(m,f),f+=m.length;const h=Math.round(this.frameCount++*(1e6/30));if(this.decodeSampler&&(this.submitAt.set(h,performance.now()),this.submitAt.size>120)){const m=this.submitAt.keys().next().value;m!==void 0&&this.submitAt.delete(m)}try{this.decoder.decode(new EncodedVideoChunk({type:s?"key":"delta",timestamp:h,data:i}))}catch{}}sampleDecode(t){var s;if(!this.decodeSampler)return;const r=this.submitAt.get(t.timestamp);r!==void 0&&(this.submitAt.delete(t.timestamp),this.decodeSampler({decodeMs:performance.now()-r,queueSize:((s=this.decoder)==null?void 0:s.decodeQueueSize)??0}))}close(){var t;(t=this.decoder)==null||t.close(),this.decoder=null}logSpsVui(t){if(!(this.spsLogged||!this.decodeSampler)){this.spsLogged=!0;try{console.log("[sps-vui]",JSON.stringify(zr(t)))}catch(r){console.warn("[sps-vui] parse failed",r)}}}initDecoder(t,r){this.logSpsVui(t);const s=Br(t)??t,a=s[0]===0?s.subarray(4):s,i=`avc1.${a[1].toString(16).padStart(2,"0")}${a[2].toString(16).padStart(2,"0")}${a[3].toString(16).padStart(2,"0")}`,l=this.buildAVCC(s,r);this.decoder=new VideoDecoder({output:f=>{this.sampleDecode(f),this.onFrame(f)},error:f=>console.error("[WebCodecsCore]",f)}),this.decoder.configure({codec:i,description:l,optimizeForLatency:!0})}buildAVCC(t,r){const s=t[0]===0?t.subarray(4):t,a=r[0]===0?r.subarray(4):r,i=new Uint8Array(8+s.length+1+2+a.length);let l=0;return i[l++]=1,i[l++]=s[1],i[l++]=s[2],i[l++]=s[3],i[l++]=255,i[l++]=225,i[l++]=s.length>>8&255,i[l++]=s.length&255,i.set(s,l),l+=s.length,i[l++]=1,i[l++]=a.length>>8&255,i[l++]=a.length&255,i.set(a,l),i}}const $r=`#version 300 es
97
- in vec2 a_pos;
98
- out vec2 v_uv;
99
- void main() {
100
- v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
101
- gl_Position = vec4(a_pos, 0.0, 1.0);
102
- }`,Wr=`#version 300 es
103
- precision mediump float;
104
- in vec2 v_uv;
105
- uniform sampler2D u_tex;
106
- out vec4 out_color;
107
- void main() {
108
- out_color = texture(u_tex, v_uv);
109
- }`;function Vr(e){const t=e.getContext("webgl2",{alpha:!1,antialias:!1,powerPreference:"high-performance",preserveDrawingBuffer:!0});if(!t)return null;const r=(p,x)=>{const d=t.createShader(p);return t.shaderSource(d,x),t.compileShader(d),d},s=t.createProgram(),a=r(t.VERTEX_SHADER,$r),i=r(t.FRAGMENT_SHADER,Wr);t.attachShader(s,a),t.attachShader(s,i),t.linkProgram(s),t.deleteShader(a),t.deleteShader(i),t.useProgram(s);const l=t.createVertexArray();t.bindVertexArray(l);const f=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,f),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),t.STATIC_DRAW);const h=t.getAttribLocation(s,"a_pos");t.enableVertexAttribArray(h),t.vertexAttribPointer(h,2,t.FLOAT,!1,0,0),t.bindVertexArray(null);const m=t.createTexture();return t.activeTexture(t.TEXTURE0),t.bindTexture(t.TEXTURE_2D,m),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MIN_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_MAG_FILTER,t.LINEAR),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_S,t.CLAMP_TO_EDGE),t.texParameteri(t.TEXTURE_2D,t.TEXTURE_WRAP_T,t.CLAMP_TO_EDGE),t.uniform1i(t.getUniformLocation(s,"u_tex"),0),{gl:t,program:s,tex:m,vao:l}}class Xr{constructor(t){this.canvas=t,this.state=null}init(){return this.state=Vr(this.canvas),this.state!==null}drawFrame(t){const r=this.state;if(!r)return t.close(),null;const s=t.displayWidth,a=t.displayHeight;try{return(this.canvas.width!==s||this.canvas.height!==a)&&(this.canvas.width=s,this.canvas.height=a,r.gl.viewport(0,0,s,a)),r.gl.activeTexture(r.gl.TEXTURE0),r.gl.bindTexture(r.gl.TEXTURE_2D,r.tex),r.gl.texImage2D(r.gl.TEXTURE_2D,0,r.gl.RGBA,r.gl.RGBA,r.gl.UNSIGNED_BYTE,t),r.gl.bindVertexArray(r.vao),r.gl.drawArrays(r.gl.TRIANGLES,0,6),r.gl.bindVertexArray(null),r.gl.bindTexture(r.gl.TEXTURE_2D,null),{width:s,height:a}}finally{t.close()}}dispose(){const t=this.state;t&&(t.gl.deleteTexture(t.tex),t.gl.deleteVertexArray(t.vao),t.gl.deleteProgram(t.program),this.state=null)}}function Kr(e){const t=new Xr(e);return t.init(),t}class Yr{constructor(t=Kr){this._size=null,this.canvas=document.createElement("canvas"),this.renderer=t(this.canvas),this.core=new Or(r=>this.render(r))}get surface(){return this.canvas}get size(){return this._size}onResize(t){this.resizeCb=t}onDecodedFrame(t){this.decodedCb=t,this.core.setDecodeSampler(r=>{this.lastSample=r})}decode(t){this.core.decode(t)}close(){this.core.close(),this.renderer.dispose()}render(t){var s,a;const r=this.renderer.drawFrame(t);r&&((s=this.decodedCb)==null||s.call(this,performance.now(),this.lastSample),this.lastSample=void 0,(!this._size||this._size.width!==r.width||this._size.height!==r.height)&&(this._size=r,(a=this.resizeCb)==null||a.call(this,r)))}}const Gr=`#version 300 es
110
- in vec2 a_pos;
111
- out vec2 v_uv;
112
- void main() {
113
- v_uv = vec2(a_pos.x * 0.5 + 0.5, 0.5 - a_pos.y * 0.5);
114
- gl_Position = vec4(a_pos, 0.0, 1.0);
115
- }`,qr=`#version 300 es
116
- precision mediump float;
117
- in vec2 v_uv;
118
- uniform sampler2D u_texY;
119
- uniform sampler2D u_texU;
120
- uniform sampler2D u_texV;
121
- out vec4 out_color;
122
- void main() {
123
- float Y = (texture(u_texY, v_uv).r - 0.0627451) * 1.1643836; // (y-16/255)*255/219
124
- float U = (texture(u_texU, v_uv).r - 0.5019608) * 1.1383929; // (u-128/255)*255/224
125
- float V = (texture(u_texV, v_uv).r - 0.5019608) * 1.1383929;
126
- float r = Y + 1.5748 * V;
127
- float g = Y - 0.1873 * U - 0.4681 * V;
128
- float b = Y + 1.8556 * U;
129
- out_color = vec4(r, g, b, 1.0);
130
- }`;function Rt(e,t,r,s){const a=e.createTexture();return e.activeTexture(e.TEXTURE0+t),e.bindTexture(e.TEXTURE_2D,a),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MIN_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_MAG_FILTER,e.LINEAR),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_S,e.CLAMP_TO_EDGE),e.texParameteri(e.TEXTURE_2D,e.TEXTURE_WRAP_T,e.CLAMP_TO_EDGE),e.uniform1i(e.getUniformLocation(s,r),t),a}function Jr(e){const t=e.getContext("webgl2",{alpha:!1,antialias:!1,powerPreference:"high-performance",preserveDrawingBuffer:!0});if(!t)return null;const r=(d,v)=>{const R=t.createShader(d);return t.shaderSource(R,v),t.compileShader(R),R},s=t.createProgram(),a=r(t.VERTEX_SHADER,Gr),i=r(t.FRAGMENT_SHADER,qr);t.attachShader(s,a),t.attachShader(s,i),t.linkProgram(s),t.deleteShader(a),t.deleteShader(i),t.useProgram(s);const l=t.createVertexArray();t.bindVertexArray(l);const f=t.createBuffer();t.bindBuffer(t.ARRAY_BUFFER,f),t.bufferData(t.ARRAY_BUFFER,new Float32Array([-1,-1,1,-1,-1,1,-1,1,1,-1,1,1]),t.STATIC_DRAW);const h=t.getAttribLocation(s,"a_pos");t.enableVertexAttribArray(h),t.vertexAttribPointer(h,2,t.FLOAT,!1,0,0),t.bindVertexArray(null),t.pixelStorei(t.UNPACK_ALIGNMENT,1);const m=Rt(t,0,"u_texY",s),p=Rt(t,1,"u_texU",s),x=Rt(t,2,"u_texV",s);return{gl:t,program:s,texY:m,texU:p,texV:x,vao:l}}class Zr{constructor(t){this.canvas=t,this.state=null}init(){return this.state=Jr(this.canvas),this.state!==null}drawI420(t,r,s){const a=this.state;if(!a)return null;const{gl:i}=a,l=r+1>>1,f=s+1>>1,h=r*s,m=l*f,p=t.subarray(0,h),x=t.subarray(h,h+m),d=t.subarray(h+m,h+2*m);(this.canvas.width!==r||this.canvas.height!==s)&&(this.canvas.width=r,this.canvas.height=s,i.viewport(0,0,r,s));const v=(R,U,k,_,A)=>{i.activeTexture(i.TEXTURE0+R),i.bindTexture(i.TEXTURE_2D,U),i.texImage2D(i.TEXTURE_2D,0,i.R8,k,_,0,i.RED,i.UNSIGNED_BYTE,A)};return v(0,a.texY,r,s,p),v(1,a.texU,l,f,x),v(2,a.texV,l,f,d),i.bindVertexArray(a.vao),i.drawArrays(i.TRIANGLES,0,6),i.bindVertexArray(null),{width:r,height:s}}dispose(){const t=this.state;t&&(t.gl.deleteTexture(t.texY),t.gl.deleteTexture(t.texU),t.gl.deleteTexture(t.texV),t.gl.deleteVertexArray(t.vao),t.gl.deleteProgram(t.program),this.state=null)}}const Qr=0;function es(e){const t=new Zr(e);return t.init(),t}function ts(){return new Worker(new URL("/assets/tinyh264.worker-DiJ50Hai.js",import.meta.url),{type:"module"})}class ns{constructor(t=es,r=ts){this.ready=!1,this.pending=[],this._size=null,this.canvas=document.createElement("canvas"),this.renderer=t(this.canvas),this.worker=r(),this.worker.onmessage=s=>this.onMessage(s.data)}get surface(){return this.canvas}get size(){return this._size}onResize(t){this.resizeCb=t}onDecodedFrame(t){this.decodedCb=t}decode(t){if(!this.ready){this.pending.push(t);return}this.post(t)}close(){this.worker.terminate(),this.renderer.dispose()}post(t){this.worker.postMessage({type:"decode",data:t,offset:0,length:t.byteLength,renderStateId:Qr},[t])}onMessage(t){var s,a;if(t.type==="decoderReady"){this.ready=!0;for(const i of this.pending)this.post(i);this.pending.length=0;return}const r=this.renderer.drawI420(new Uint8Array(t.data),t.width,t.height);r&&((s=this.decodedCb)==null||s.call(this,performance.now()),(!this._size||this._size.width!==r.width||this._size.height!==r.height)&&(this._size=r,(a=this.resizeCb)==null||a.call(this,r)))}}function Nt(){const e=typeof window<"u";let t=!1;try{t=!!document.createElement("canvas").getContext("webgl2")}catch{t=!1}return{secureContext:e&&window.isSecureContext===!0,webCodecs:e&&"VideoDecoder"in window,webgl2:t,wasm:typeof WebAssembly<"u"&&typeof Worker<"u"}}function rs(e=Nt()){return e.secureContext&&e.webCodecs&&e.webgl2?new Yr:e.wasm&&e.webgl2?new ns:null}function ss(e=Nt()){return e.secureContext&&e.webCodecs&&e.webgl2||e.wasm&&e.webgl2}function os(e=Nt()){return e.secureContext&&e.webCodecs&&e.webgl2?"high":e.wasm&&e.webgl2?"standard":"unsupported"}const It="tapflow.perfModeNoticeDismissed",as="https://www.tapflow.dev/reference/configuration#https-secure-context";function is(e,t){return e==="standard"&&!t}function cs({open:e,onOpenChange:t}){return n.jsx(en,{open:e,onOpenChange:t,children:n.jsxs(tn,{className:"sm:max-w-[440px]",children:[n.jsxs(or,{children:[n.jsx(nn,{children:"Streaming in Standard mode"}),n.jsxs(ar,{className:"space-y-3 pt-1",children:[n.jsx("span",{className:"block",children:"This screen is running in Standard mode. For a faster, smoother picture, switch to High performance."}),n.jsx("span",{className:"block",children:"High performance needs the relay served over HTTPS. If you didn't set up tapflow, ask whoever did."})]})]}),n.jsxs(ir,{children:[n.jsx(ee,{variant:"outline",onClick:()=>window.open(as,"_blank","noopener,noreferrer"),children:"How to enable"}),n.jsx(ee,{onClick:()=>t(!1),children:"Got it"})]})]})})}const ls={high:"High performance",standard:"Standard",unsupported:null};function ds(e){const{connected:t,joined:r,bootError:s,deviceReady:a,installing:i,installError:l}=e;return t?r?s?`Boot failed: ${s.length>40?s.slice(0,40)+"…":s}`:a?i?"Installing app…":l?`Install failed: ${l}`:null:"Starting device…":"Joining session…":"Connecting…"}function Tt(e){const{joined:t,fps:r,keyboardActive:s}=e,a=ds(e),i=r>15,l=r>0&&r<=15,f=i?"#10b981":l?"#94a3b8":"transparent",h=i?"Active":l?"Idle":null,m=o.useMemo(()=>os(),[]),p=ls[m],[x,d]=o.useState(!1);o.useEffect(()=>{let R=!1;try{R=localStorage.getItem(It)==="1"}catch{}is(m,R)&&d(!0)},[m]);const v=R=>{if(d(R),!R)try{localStorage.setItem(It,"1")}catch{}};return n.jsxs("div",{className:"w-[300px] shrink-0 mt-3 rounded-xl border bg-background px-4 py-4 flex flex-col gap-3",children:[n.jsxs("div",{className:Y("flex items-center",s?"text-emerald-500":"text-muted-foreground"),style:{gap:6},children:[n.jsx(Cr,{className:"h-3.5 w-3.5 shrink-0"}),n.jsx("span",{className:"text-[12px] font-medium",children:"Focus"})]}),t&&n.jsxs("div",{className:"flex items-center gap-[12px]",children:[n.jsxs("div",{className:"flex items-center gap-[4px]",children:[n.jsx("span",{className:"h-2 w-2 rounded-full shrink-0 mr-1",style:{background:f}}),n.jsx("span",{className:"text-[12px] font-mono text-foreground/75",children:r}),n.jsx("span",{className:"text-[12px] text-muted-foreground",children:"fps"}),h&&n.jsx("span",{className:"text-[11px] text-muted-foreground/60",children:"·"}),h&&n.jsx("span",{className:Y("text-[11px]",i?"text-emerald-500":"text-muted-foreground/60"),children:h})]}),p&&n.jsxs(n.Fragment,{children:[n.jsx(qt,{orientation:"vertical",className:"h-3"}),m==="standard"?n.jsx("button",{type:"button",onClick:()=>d(!0),className:"text-[11px] text-foreground/70 hover:text-foreground underline-offset-2 hover:underline",children:p}):n.jsx("span",{className:"text-[11px] text-muted-foreground",children:p})]})]}),a&&n.jsx("p",{className:"text-[12px] text-muted-foreground leading-relaxed break-all",children:a}),n.jsx(cs,{open:x,onOpenChange:v})]})}function un({open:e,onOpenChange:t,sessionId:r,send:s}){const[a,i]=o.useState(""),l=o.useRef(null);o.useEffect(()=>{e?setTimeout(()=>{var h;return(h=l.current)==null?void 0:h.focus()},0):i("")},[e]);const f=()=>{a.trim()&&(s({type:"open-url",sessionId:r,payload:{url:a.trim()}}),t(!1))};return n.jsx(en,{open:e,onOpenChange:t,children:n.jsxs(tn,{className:"w-[500px] max-w-[500px] h-[52px] !rounded-[18px] p-[10px] border border-border bg-background shadow-lg overflow-hidden [&>button]:hidden","aria-describedby":void 0,children:[n.jsx(nn,{className:"sr-only",children:"Open Deeplink"}),n.jsxs("div",{className:"flex items-center gap-3",children:[n.jsxs("div",{className:"flex-1 h-[32px] flex items-center gap-2 pl-[4px] pb-[1px]",children:[n.jsx(er,{className:"h-4 w-4 text-muted-foreground shrink-0"}),n.jsx("input",{ref:l,className:"flex-1 bg-transparent text-sm outline-none placeholder:text-muted-foreground min-w-0",placeholder:"myapp://home...",value:a,onChange:h=>i(h.target.value),onKeyDown:h=>{h.key==="Enter"&&f()}})]}),n.jsx(ee,{size:"sm",disabled:!a.trim(),onClick:f,className:"shrink-0 rounded-xl h-8 px-4",children:"Open"})]})]})})}function us(e,t,r,s,a,i){const{x:l,y:f,width:h,height:m}=a;let p,x;if(i){const d=(e.x-t.left)/t.width;p=(1-(e.y-t.top)/t.height)*r,x=d*s}else p=(e.x-t.left)*(r/t.width),x=(e.y-t.top)*(s/t.height);return p<l||p>l+h||x<f||x>f+m?null:{x:(p-l)/h,y:(x-f)/m}}function hs(e,t,r){const s=(e.x-t.left)/t.width,a=(e.y-t.top)/t.height;return s<0||s>1||a<0||a>1?null:r?{x:a,y:1-s}:{x:s,y:a}}function hn(e){return{f0:{x:1-e.x,y:1-e.y},f1:e}}function fs(e,t){return e>0?Math.min(1,t/e):1}const fn=22,Ot=[84,70,70,69],ps=1,ms=0,mt=1,gs=1,xs=2;function bs(e){if(e.byteLength<fn)return null;const t=new DataView(e);for(let a=0;a<Ot.length;a++)if(t.getUint8(a)!==Ot[a])return null;if(t.getUint8(4)!==ps)return null;const r=t.getUint8(5),s=r&gs?mt:ms;return{capturedAt:Number(t.getBigUint64(6)),relayedAt:Number(t.getBigUint64(14)),codec:s,keyframe:s===mt&&(r&xs)!==0}}function pn(e){const{binaryFrameHandlerRef:t,perfHookRef:r,frameCount:s}=e,a=o.useRef(e);a.current=e,o.useEffect(()=>{let i=null,l=!1,f=!1,h;const m=()=>{if(i)return i;if(l)return null;const p=rs();return p?(i=p,p.onResize(x=>a.current.onResize(x)),h=a.current.onDecoderReady(p),p):(l=!0,a.current.onUnsupported(),console.warn("[decoder] none available — set up HTTPS or use a supported browser"),null)};return t.current=(p,x)=>{const d=a.current.onJpegFrame;if(d&&(x==null?void 0:x.codec)!==mt){d(p,x);return}const v=m();if(v){if(!f){if(!(x!=null&&x.keyframe))return;f=!0}v.decode(p),s.current+=1}},()=>{t.current=void 0,typeof h=="function"&&h(),i==null||i.close(),i==null||i.surface.remove(),i=null}},[t,r,s])}const Ne=13,Xe=8,$t=16,ys=.02,vs=100;function ws({sessionId:e,buildId:t,send:r,connected:s,joined:a,deviceReady:i,installing:l,installed:f,installError:h,bootError:m,launching:p,setLaunching:x,chrome:d,binaryFrameHandlerRef:v,onRecordingUploaded:R,swKeyboardVisible:U,swKeyboardPending:k,onKbdToggle:_,perfHookRef:A}){const C=o.useRef(null),P=o.useRef(null),F=o.useRef(null),{fps:D,frameCount:I}=an(),X=o.useRef(0),{recordState:z,recordCanvasRef:O,startClientRecording:q,stopClientRecording:je}=on({sessionId:e,buildId:t,onRecordingUploaded:R}),he=o.useRef(0),[ae,ke]=o.useState(!1),[fe,ie]=o.useState(!1),[E,$]=o.useState(!1),[Z,te]=o.useState(!1),[Ce,L]=o.useState(null),[W,Q]=o.useState(null),[ce,J]=o.useState(!1),[re,ye]=o.useState(null),pe=o.useRef(re);o.useEffect(()=>{pe.current=re},[re]);const le=o.useRef(null),de=o.useRef(null),se=o.useRef(!1),oe=o.useRef(!1),me=o.useRef(0),ne=o.useRef(null),ge=o.useRef(null),Ee=o.useRef("idle"),Pe=o.useRef(null),ze=o.useRef(null),Le=o.useRef(null);o.useEffect(()=>{Le.current=d},[d]),o.useEffect(()=>{const c=new Image;c.onload=()=>{ze.current=c},c.src=`data:image/png;base64,${d.framePng}`},[d.framePng]),pn({binaryFrameHandlerRef:v,perfHookRef:A,frameCount:I,onUnsupported:()=>{},onResize:c=>{const g=C.current;if(g&&(g.width!==c.width||g.height!==c.height)&&(g.width=c.width,g.height=c.height,!Le.current)){const u=O.current;u&&(u.width=c.width,u.height=c.height)}ie(!0)},onDecoderReady:c=>{var y;const g=c.surface,u=C.current;g.style.position="absolute",u&&(g.style.left=u.style.left,g.style.top=u.style.top,g.style.width=u.style.width,g.style.height=u.style.height,g.style.borderRadius=u.style.borderRadius),g.style.objectFit="fill",g.style.zIndex="3",g.style.pointerEvents="none",(y=P.current)==null||y.appendChild(g);let S=null;const j=()=>{const T=C.current,H=T==null?void 0:T.getContext("2d");if(T&&H&&c.size)try{H.drawImage(c.surface,0,0,T.width,T.height)}catch{}S=requestAnimationFrame(j)};return S=requestAnimationFrame(j),()=>{S!==null&&cancelAnimationFrame(S)}},onJpegFrame:c=>{const g=performance.now();X.current&&g-X.current,X.current=g;const u=he.current;createImageBitmap(new Blob([c],{type:"image/jpeg"})).then(S=>{if(performance.now()-g,he.current!==u){S.close();return}const j=C.current,y=j==null?void 0:j.getContext("2d");if(!j||!y){S.close();return}if((j.width!==S.width||j.height!==S.height)&&(j.width=S.width,j.height=S.height,!Le.current)){const H=O.current;H&&(H.width=S.width,H.height=S.height)}const T=performance.now();y.drawImage(S,0,0),performance.now()-T,S.close(),ie(!0),I.current+=1}).catch(()=>{})}}),o.useEffect(()=>{const c=O.current,g=P.current;c&&g&&(c.width=g.clientWidth,c.height=g.clientHeight)},[d]);const tt=o.useCallback(()=>{const c=O.current,g=C.current;if(!c||!g)return;const u=c.getContext("2d");if(!u)return;const S=Le.current;if(u.clearRect(0,0,c.width,c.height),S){ze.current&&u.drawImage(ze.current,0,0,c.width,c.height);const T=Math.round(S.screenCornerRadius/2*(c.height/(S.compositeHeight/2)));u.save(),u.beginPath(),T>0?u.roundRect(g.offsetLeft,g.offsetTop,g.clientWidth,g.clientHeight,T):u.rect(g.offsetLeft,g.offsetTop,g.clientWidth,g.clientHeight),u.clip(),u.drawImage(g,g.offsetLeft,g.offsetTop,g.clientWidth,g.clientHeight),u.restore()}else u.drawImage(g,0,0,c.width,c.height);const j=pe.current;if(j)for(const T of[j.f0,j.f1]){const H=S?g.offsetLeft+T.x*g.clientWidth:T.x*c.width,V=S?g.offsetTop+T.y*g.clientHeight:T.y*c.height;se.current?(u.beginPath(),u.arc(H,V,Xe,0,Math.PI*2),u.fillStyle="rgba(255,255,255,0.92)",u.fill(),u.strokeStyle="rgba(0,0,0,0.2)",u.lineWidth=1,u.stroke()):(u.beginPath(),u.arc(H,V,Ne,0,Math.PI*2),u.strokeStyle="rgba(0,0,0,0.3)",u.lineWidth=3,u.stroke(),u.beginPath(),u.arc(H,V,Ne,0,Math.PI*2),u.strokeStyle="rgba(255,255,255,0.65)",u.lineWidth=1.5,u.stroke())}const y=ge.current;if(y){const T=Ee.current,H=Pe.current;if(u.save(),T==="down")u.beginPath(),u.arc(y.x,y.y,Xe,0,Math.PI*2),u.fillStyle="rgba(255,255,255,0.92)",u.fill(),u.strokeStyle="rgba(0,0,0,0.2)",u.lineWidth=1,u.stroke();else if(T==="release"&&H){const V=Math.min((performance.now()-H.startTime)/350,1);u.beginPath(),u.arc(y.x,y.y,Xe+26*V,0,Math.PI*2),u.strokeStyle=`rgba(255,255,255,${(1-V)*.55})`,u.lineWidth=1.5,u.stroke(),V>=1&&(Ee.current="idle",Pe.current=null)}else u.beginPath(),u.arc(y.x,y.y,Ne,0,Math.PI*2),u.strokeStyle="rgba(0,0,0,0.3)",u.lineWidth=3,u.stroke(),u.beginPath(),u.arc(y.x,y.y,Ne,0,Math.PI*2),u.strokeStyle="rgba(255,255,255,0.65)",u.lineWidth=1.5,u.stroke();u.restore()}},[]),Be=o.useCallback(()=>{const c=C.current;if(!c)return;const g=document.createElement("canvas"),u=g.getContext("2d");u&&(g.width=c.width,g.height=c.height,u.drawImage(c,0,0),g.toBlob(S=>{if(!S)return;const j=URL.createObjectURL(S),y=document.createElement("a");y.href=j,y.download=`tapflow-${Date.now()}.png`,y.click(),URL.revokeObjectURL(j)},"image/png"))},[]),ve=o.useCallback(()=>{if(z==="idle"){const c=O.current;if(!c)return;const g=P.current;if(g&&g.clientWidth>0)c.width=g.clientWidth,c.height=g.clientHeight;else{const u=C.current;if(u&&u.width>0)c.width=u.width,c.height=u.height;else return}q(tt)}else z==="recording"&&je()},[z,q,je,tt]),Ae=o.useCallback(()=>{r({type:"input:rotate",sessionId:e}),$(c=>!c)},[r,e]),it=o.useRef(E);o.useEffect(()=>{it.current=E},[E]),o.useEffect(()=>()=>{it.current&&r({type:"input:rotate",sessionId:e})},[]),o.useEffect(()=>{const c=new Set(["ShiftLeft","ShiftRight","ControlLeft","ControlRight","MetaLeft","MetaRight"]),g=y=>{if(y.code==="AltLeft"||y.code==="AltRight"){oe.current=!0;return}if(y.metaKey){const H=document.activeElement;if(!H||H.tagName!=="INPUT"&&H.tagName!=="TEXTAREA"){if(!y.shiftKey&&y.code==="KeyK"){y.preventDefault(),ke(!0);return}if(!y.shiftKey&&y.code==="KeyS"){y.preventDefault(),Be();return}if(y.shiftKey&&y.code==="KeyY"){y.preventDefault(),ve();return}if(y.shiftKey&&y.code==="KeyO"){y.preventDefault(),Ae();return}if(y.shiftKey&&y.code==="KeyU"){y.preventDefault(),r({type:"input:button",sessionId:e,payload:{name:"home"}});return}if(y.shiftKey&&y.code==="KeyK"){y.preventDefault(),k||_();return}}}if(!Z||c.has(y.code))return;y.preventDefault();const T=(y.shiftKey?2:0)|(y.ctrlKey?1:0)|(y.metaKey?8:0);r({type:"input:key",sessionId:e,payload:{code:y.code,modifiers:T}})},u=()=>{se.current&&(se.current=!1,J(!1),r({type:"input:pinch:end",sessionId:e})),oe.current=!1,ye(null)},S=y=>{(y.code==="AltLeft"||y.code==="AltRight")&&u()},j=()=>{oe.current&&u()};return window.addEventListener("keydown",g),window.addEventListener("keyup",S),window.addEventListener("blur",j),()=>{window.removeEventListener("keydown",g),window.removeEventListener("keyup",S),window.removeEventListener("blur",j)}},[Z,r,e,Be,ve,Ae,_,k]),o.useEffect(()=>{if(!Z)return;const c=g=>{const u=P.current??C.current;u&&!u.contains(g.target)&&te(!1)};return document.addEventListener("pointerdown",c),()=>document.removeEventListener("pointerdown",c)},[Z]);const _e=o.useCallback(c=>{const g=(E?F.current:null)??P.current;if(!g)return null;const u=g.getBoundingClientRect(),S=d.compositeWidth/2,j=d.compositeHeight/2,y=d.screenRect.x/2,T=d.screenRect.y/2,H=d.screenRect.width/2,V=d.screenRect.height/2;return us({x:c.clientX,y:c.clientY},u,S,j,{x:y,y:T,width:H,height:V},E)},[d,E]),Ie=o.useCallback(c=>{const g=_e(c);return g?hn(g):null},[_e]),Je=o.useCallback(c=>{const g=E?F.current:P.current;if(!g)return null;const u=g.getBoundingClientRect();let S,j;if(E){const y=u.height-(c.clientY-u.top),T=c.clientX-u.left;S=y*(d.compositeWidth/u.height),j=T*(d.compositeHeight/u.width)}else S=(c.clientX-u.left)*(d.compositeWidth/u.width),j=(c.clientY-u.top)*(d.compositeHeight/u.height);for(const y of d.buttons){const T=S-y.normalOffset.x,H=j-y.normalOffset.y;if(T*T+H*H<vs**2)return y.name}return null},[d,E]),Oe=o.useCallback(c=>{const g=C.current,u=O.current;return g&&g.clientWidth>0?{x:g.offsetLeft+c.x*g.clientWidth,y:g.offsetTop+c.y*g.clientHeight}:{x:c.x*((u==null?void 0:u.width)??1),y:c.y*((u==null?void 0:u.height)??1)}},[]),xe=o.useCallback(c=>{if(te(!0),oe.current){const y=Ie(c);if(!y)return;se.current=!0,J(!0),c.target.setPointerCapture(c.pointerId),ye(y),r({type:"input:pinch:start",sessionId:e,payload:y});return}const g=Je(c);if(g){le.current=g,L(g);return}const u=_e(c);if(!u)return;de.current=u,c.target.setPointerCapture(c.pointerId),ge.current=Oe(u),Ee.current="down",Pe.current=null;const S=c.currentTarget.getBoundingClientRect(),j=ne.current;j&&(j.style.display="block",j.style.left=`${c.clientX-S.left}px`,j.style.top=`${c.clientY-S.top}px`,j.style.width=`${Xe*2}px`,j.style.height=`${Xe*2}px`,j.style.background="rgba(255,255,255,0.92)",j.style.border="1.5px solid rgba(0,0,0,0.2)",j.style.boxShadow="0 0 0 1px rgba(0,0,0,0.15), 0 0 8px rgba(255,255,255,0.25)"),r({type:"input:touch:start",sessionId:e,payload:u})},[Je,_e,Ie,Oe,r,e]),ct=o.useCallback(c=>{if(c.buttons===0){if(Q(Je(c)),oe.current){ye(Ie(c)),ge.current=null;const T=ne.current;T&&(T.style.display="none")}else{ye(null);const T=_e(c);ge.current=T?Oe(T):null,Ee.current!=="down"&&(Ee.current="idle");const H=ne.current;if(H)if(T){const V=c.currentTarget.getBoundingClientRect();H.style.display="block",H.style.left=`${c.clientX-V.left}px`,H.style.top=`${c.clientY-V.top}px`,H.style.width=`${Ne*2}px`,H.style.height=`${Ne*2}px`,H.style.background="transparent",H.style.border="1.5px solid rgba(255,255,255,0.6)",H.style.boxShadow="0 0 0 1px rgba(0,0,0,0.3)"}else H.style.display="none"}return}if(se.current){const T=Ie(c);if(!T)return;const H=performance.now();if(H-me.current<$t)return;me.current=H,ye(T),r({type:"input:pinch:move",sessionId:e,payload:T});return}if(le.current||!de.current)return;const g=_e(c);if(!g)return;const u=g.x-de.current.x,S=g.y-de.current.y;if(Math.sqrt(u*u+S*S)<ys)return;const j=performance.now();if(j-me.current<$t)return;me.current=j,ge.current=Oe(g);const y=ne.current;if(y&&y.style.display!=="none"){const T=c.currentTarget.getBoundingClientRect();y.style.left=`${c.clientX-T.left}px`,y.style.top=`${c.clientY-T.top}px`}r({type:"input:touch:move",sessionId:e,payload:g})},[Je,_e,Ie,Oe,r,e]),Me=o.useCallback(()=>{if(se.current){se.current=!1,J(!1),ye(null),r({type:"input:pinch:end",sessionId:e});return}if(de.current=null,le.current){r({type:"input:button",sessionId:e,payload:{name:le.current}}),le.current=null,setTimeout(()=>L(null),100);return}Ee.current="release",Pe.current={startTime:performance.now()};const c=ne.current;c&&(c.style.width=`${Ne*2}px`,c.style.height=`${Ne*2}px`,c.style.background="transparent",c.style.border="1.5px solid rgba(255,255,255,0.6)",c.style.boxShadow="0 0 0 1px rgba(0,0,0,0.3)"),r({type:"input:touch:end",sessionId:e})},[r,e]),$e=o.useCallback(()=>{if(se.current){se.current=!1,J(!1),ye(null),r({type:"input:pinch:end",sessionId:e});return}if(de.current=null,le.current){le.current=null,L(null);return}Ee.current="release",Pe.current={startTime:performance.now()},r({type:"input:touch:end",sessionId:e})},[r,e]),St=o.useCallback(()=>{Q(null),ye(null),ge.current=null;const c=ne.current;c&&(c.style.display="none")},[]),He=d.compositeWidth/2,lt=d.compositeHeight/2,Ze=fs(lt,750),We=Math.round(He*Ze),Ve=Math.round(lt*Ze),Qe=d.screenRect.x/d.compositeWidth*100,b=d.screenRect.y/d.compositeHeight*100,N=d.screenRect.width/d.compositeWidth*100,B=d.screenRect.height/d.compositeHeight*100,w=Math.round(d.screenCornerRadius/2*Ze),K=n.jsxs(n.Fragment,{children:[n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>r({type:"input:button",sessionId:e,payload:{name:"home"}}),children:n.jsx(rn,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:n.jsxs("span",{className:"flex items-center gap-3",children:["Home ",n.jsxs(Ct,{children:[n.jsx(Ye,{children:"⌘"}),n.jsx(Ye,{children:"⇧"}),n.jsx(Ye,{children:"U"})]})]})})]}),n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",disabled:k,onClick:_,"data-active":U,children:k?n.jsx(pt,{className:"h-4 w-4 animate-spin"}):n.jsx(Sr,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:n.jsxs("span",{className:"flex items-center gap-3",children:["Software keyboard ",n.jsxs(Ct,{children:[n.jsx(Ye,{children:"⌘"}),n.jsx(Ye,{children:"⇧"}),n.jsx(Ye,{children:"K"})]})]})})]})]}),M=f&&t?n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",disabled:p,onClick:()=>{x(!0),r({type:"app:launch",sessionId:e,buildId:t})},children:p?n.jsx(pt,{className:"h-4 w-4 animate-spin"}):n.jsx(Zt,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:p?"Launching…":"Launch app"})]}):null;return n.jsxs("div",{className:"flex items-start justify-center gap-16",children:[n.jsx("canvas",{ref:O,style:{display:"none"}}),n.jsx(un,{open:ae,onOpenChange:ke,sessionId:e,send:r}),n.jsx(cn,{joined:a,onDeepLink:()=>ke(!0),onScreenshot:Be,onRecordToggle:ve,recordState:z,onRotate:Ae,platformSlot:K,launchSlot:M}),n.jsxs("div",{className:"flex items-start gap-8",children:[n.jsxs("div",{ref:F,style:{width:E?Ve:We,height:E?We:Ve,position:"relative",flexShrink:0},children:[n.jsxs("div",{ref:P,className:`relative ${W?"cursor-pointer":"cursor-default"}`,style:{width:We,height:Ve,...E?{position:"absolute",top:(We-Ve)/2,left:(Ve-We)/2,transform:"rotate(-90deg)",transformOrigin:"center center"}:{}},onPointerDown:xe,onPointerMove:ct,onPointerUp:Me,onPointerCancel:$e,onPointerLeave:St,children:[n.jsx("img",{src:`data:image/png;base64,${d.framePng}`,style:{position:"absolute",top:0,left:0,zIndex:2,width:"100%",height:"100%",display:"block",pointerEvents:"none",userSelect:"none"},draggable:!1,alt:""}),n.jsx("canvas",{ref:C,style:{position:"absolute",zIndex:3,left:`${Qe}%`,top:`${b}%`,width:`${N}%`,height:`${B}%`,borderRadius:w>0?`${w}px`:void 0,backgroundColor:"#010101",cursor:"none",visibility:fe?"visible":"hidden"}}),!fe&&n.jsx("div",{className:"absolute animate-pulse bg-zinc-700",style:{zIndex:3,left:`${Qe}%`,top:`${b}%`,width:`${N}%`,height:`${B}%`,borderRadius:w>0?`${w}px`:void 0}}),re&&(()=>{const c=Qe/100,g=b/100,u=N/100,S=B/100,j=(y,T)=>({left:`${(c+y*u)*100}%`,top:`${(g+T*S)*100}%`});return n.jsx(n.Fragment,{children:[re.f0,re.f1].map((y,T)=>n.jsx("div",{style:{position:"absolute",zIndex:10,borderRadius:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none",transition:"width 0.1s ease, height 0.1s ease, background 0.1s ease",...ce?{width:Xe*2,height:Xe*2,background:"rgba(255,255,255,0.92)",border:"1.5px solid rgba(0,0,0,0.2)",boxShadow:"0 0 0 1px rgba(0,0,0,0.15), 0 0 8px rgba(255,255,255,0.25)"}:{width:Ne*2,height:Ne*2,background:"transparent",border:"1.5px solid rgba(255,255,255,0.6)",boxShadow:"0 0 0 1px rgba(0,0,0,0.3)"},...j(y.x,y.y)}},T))})})(),a&&D===0&&n.jsx("div",{style:{position:"absolute",zIndex:8,left:`${Qe}%`,top:`${b}%`,width:`${N}%`,height:`${B}%`,display:"flex",alignItems:"center",justifyContent:"center",pointerEvents:"none"},children:n.jsx("span",{style:{color:"white",fontSize:"0.875rem"},children:"Waiting for first frame..."})}),d.buttons.map(c=>{const g=Ce===c.name,u=W===c.name,S=c.anchor==="bottom",j=c.anchor==="top",y=S?(c.normalOffset.y-c.buttonH/2)/d.compositeHeight*100:j?c.rolloverOffset.y/d.compositeHeight*100:(c.normalOffset.y-c.buttonH/2)/d.compositeHeight*100,T=c.buttonH/d.compositeHeight*100,H=c.buttonW/d.compositeWidth*100,V=c.buttonW/2,ue=(c.rolloverOffset.x-V)/d.compositeWidth*100,De=(2*c.rolloverOffset.x-c.normalOffset.x-V)/d.compositeWidth*100,dt=c.rolloverOffset.x/d.compositeWidth*100,nt=S?(c.normalOffset.y-c.buttonH/2)/d.compositeHeight*100:j?c.rolloverOffset.y/d.compositeHeight*100:(c.normalOffset.y-c.buttonH/2)/d.compositeHeight*100,Mt=j?(2*c.rolloverOffset.y-c.normalOffset.y)/d.compositeHeight*100:0,In=c.onTop?4:1;return n.jsxs(o.Fragment,{children:[c.buttonPng&&n.jsx("img",{src:`data:image/png;base64,${c.buttonPng}`,style:{position:"absolute",zIndex:In,top:`${j&&u?Mt:y}%`,left:`${j?ue:u?De:ue}%`,width:`${H}%`,height:`${T}%`,transition:j?"top 0.15s ease":"left 0.15s ease",pointerEvents:"none",userSelect:"none"},draggable:!1,alt:""}),g&&c.pressedPng&&c.pressedRect&&n.jsx("img",{src:`data:image/png;base64,${c.pressedPng}`,style:{position:"absolute",zIndex:c.onTop?3:1,left:`${j?ue:u?De:ue}%`,top:`${j&&u?Mt:y}%`,width:`${c.pressedRect.width/d.compositeWidth*100}%`,height:`${c.pressedRect.height/d.compositeHeight*100}%`,pointerEvents:"none",userSelect:"none"},draggable:!1,alt:""}),u&&n.jsx("div",{className:"bg-foreground/85 text-background text-[11px] px-[7px] py-1.5 rounded-lg whitespace-nowrap pointer-events-none",style:{position:"absolute",zIndex:5,left:`${dt}%`,top:`${nt}%`,transform:"translate(-50%, calc(-100% - 8px))"},children:c.accessibilityTitle})]},c.name)})]}),n.jsx("div",{ref:ne,style:{display:"none",position:"absolute",zIndex:20,borderRadius:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none",transition:"width 0.1s ease, height 0.1s ease, background 0.1s ease, box-shadow 0.1s ease"}})]}),n.jsx(Tt,{joined:a,fps:D,connected:s,deviceReady:i,bootError:m,installing:l,installError:h,keyboardActive:Z})]})]})}const Ke=13,st=8,Wt=16,Ss=.02,jt=720;function Rs({sessionId:e,buildId:t,send:r,connected:s,joined:a,deviceReady:i,installing:l,installed:f,installError:h,bootError:m,launching:p,setLaunching:x,androidButtons:d,binaryFrameHandlerRef:v,onRecordingUploaded:R,screenWidth:U,screenHeight:k,cornerRadius:_,perfHookRef:A}){const C=o.useRef(null),P=o.useRef(null),F=o.useRef(null),{fps:D,frameCount:I}=an(),{recordState:X,recordCanvasRef:z,startClientRecording:O,stopClientRecording:q}=on({sessionId:e,buildId:t,onRecordingUploaded:R}),[je,he]=o.useState(!1),[ae,ke]=o.useState(!1),[fe,ie]=o.useState(!1),E=o.useRef(null),[$,Z]=o.useState(null),[te,Ce]=o.useState(!1),[L,W]=o.useState(!1),[Q,ce]=o.useState(!1),[J,re]=o.useState(null),ye=o.useRef(J);o.useEffect(()=>{ye.current=J},[J]);const pe=o.useRef(!1),le=o.useRef(!1),de=o.useRef(null),se=o.useRef(0),oe=o.useRef(null),me=o.useRef(null),ne=o.useRef("idle"),ge=o.useRef(null);pn({binaryFrameHandlerRef:v,perfHookRef:A,frameCount:I,onUnsupported:()=>ie(!0),onResize:b=>{ke(!0);const N=E.current;(!N||N.width!==b.width||N.height!==b.height)&&(E.current=b,Z(b))},onDecoderReady:b=>{var B;F.current=b;const N=b.surface;N.style.display="block",N.style.width="100%",N.style.height="100%",N.style.objectFit="fill",(B=C.current)==null||B.appendChild(N)}});const Ee=o.useCallback(()=>{var H;const b=z.current,N=(H=F.current)==null?void 0:H.surface,B=E.current;if(!b||!N||!B)return;const w=b.getContext("2d");if(!w)return;const K=B.width,M=B.height,c=b.width>b.height!=K>M;w.save(),c&&(w.translate(b.width,0),w.rotate(Math.PI/2)),w.drawImage(N,0,0,K,M);const g=Math.max(K,M),u=g>jt?g/jt:1,S=Ke*u,j=st*u,y=ye.current;if(y)for(const V of[y.f0,y.f1]){const ue=V.x*K,De=V.y*M;pe.current?(w.beginPath(),w.arc(ue,De,j,0,Math.PI*2),w.fillStyle="rgba(255,255,255,0.92)",w.fill(),w.strokeStyle="rgba(0,0,0,0.2)",w.lineWidth=u,w.stroke()):(w.beginPath(),w.arc(ue,De,S,0,Math.PI*2),w.strokeStyle="rgba(0,0,0,0.3)",w.lineWidth=3*u,w.stroke(),w.beginPath(),w.arc(ue,De,S,0,Math.PI*2),w.strokeStyle="rgba(255,255,255,0.65)",w.lineWidth=1.5*u,w.stroke())}const T=me.current;if(T){const V=T.x*K,ue=T.y*M,De=ne.current,dt=ge.current;if(De==="down")w.beginPath(),w.arc(V,ue,j,0,Math.PI*2),w.fillStyle="rgba(255,255,255,0.92)",w.fill(),w.strokeStyle="rgba(0,0,0,0.2)",w.lineWidth=u,w.stroke();else if(De==="release"&&dt){const nt=Math.min((performance.now()-dt.startTime)/350,1);w.beginPath(),w.arc(V,ue,j+26*u*nt,0,Math.PI*2),w.strokeStyle=`rgba(255,255,255,${(1-nt)*.55})`,w.lineWidth=1.5*u,w.stroke(),nt>=1&&(ne.current="idle",ge.current=null)}else w.beginPath(),w.arc(V,ue,S,0,Math.PI*2),w.strokeStyle="rgba(0,0,0,0.3)",w.lineWidth=3*u,w.stroke(),w.beginPath(),w.arc(V,ue,S,0,Math.PI*2),w.strokeStyle="rgba(255,255,255,0.65)",w.lineWidth=1.5*u,w.stroke()}w.restore()},[]),Pe=o.useCallback(()=>{var K;const b=(K=F.current)==null?void 0:K.surface,N=E.current;if(!b||!N)return;const B=document.createElement("canvas"),w=B.getContext("2d");w&&(B.width=N.width,B.height=N.height,w.drawImage(b,0,0,N.width,N.height),B.toBlob(M=>{if(!M)return;const c=URL.createObjectURL(M),g=document.createElement("a");g.href=c,g.download=`tapflow-${Date.now()}.png`,g.click(),URL.revokeObjectURL(c)},"image/png"))},[]),ze=o.useCallback(()=>{if(X==="idle"){const b=z.current;if(!b)return;const N=E.current;if(!N)return;const B=Be.current;b.width=B?N.height:N.width,b.height=B?N.width:N.height,O(Ee)}else X==="recording"&&q()},[X,O,q,Ee]),Le=o.useCallback(()=>{r({type:"input:rotate",sessionId:e}),Ce(b=>!b)},[r,e]),tt=o.useRef(te);o.useEffect(()=>{tt.current=te},[te]),o.useEffect(()=>()=>{tt.current&&r({type:"input:rotate",sessionId:e})},[]),o.useEffect(()=>{const b=new Set(["ShiftLeft","ShiftRight","ControlLeft","ControlRight","MetaLeft","MetaRight"]),N=M=>{if(M.code==="AltLeft"||M.code==="AltRight"){le.current=!0;return}if(M.metaKey){const g=document.activeElement;if(!g||g.tagName!=="INPUT"&&g.tagName!=="TEXTAREA"){if(!M.shiftKey&&M.code==="KeyK"){M.preventDefault(),he(!0);return}if(!M.shiftKey&&M.code==="KeyS"){M.preventDefault(),Pe();return}if(M.shiftKey&&M.code==="KeyY"){M.preventDefault(),ze();return}if(M.shiftKey&&M.code==="KeyO"){M.preventDefault(),Le();return}}}if(!L||b.has(M.code))return;M.preventDefault();const c=(M.shiftKey?2:0)|(M.ctrlKey?1:0)|(M.metaKey?8:0);r({type:"input:key",sessionId:e,payload:{code:M.code,modifiers:c}})},B=()=>{pe.current&&(pe.current=!1,ce(!1),r({type:"input:pinch:end",sessionId:e})),le.current=!1,re(null)},w=M=>{(M.code==="AltLeft"||M.code==="AltRight")&&B()},K=()=>{le.current&&B()};return window.addEventListener("keydown",N),window.addEventListener("keyup",w),window.addEventListener("blur",K),()=>{window.removeEventListener("keydown",N),window.removeEventListener("keyup",w),window.removeEventListener("blur",K)}},[L,r,e,Pe,ze,Le]),o.useEffect(()=>{if(!L)return;const b=N=>{const B=P.current??C.current;B&&!B.contains(N.target)&&W(!1)};return document.addEventListener("pointerdown",b),()=>document.removeEventListener("pointerdown",b)},[L]);const Be=o.useRef(!1),ve=o.useCallback(b=>{const N=C.current;if(!N)return null;const B=N.getBoundingClientRect();return hs({x:b.clientX,y:b.clientY},B,Be.current)},[]),Ae=o.useCallback(b=>{const N=ve(b);return N?hn(N):null},[ve]),it=o.useCallback(b=>{if(le.current){const K=Ae(b);if(!K)return;pe.current=!0,ce(!0),b.target.setPointerCapture(b.pointerId);const M=oe.current;M&&(M.style.display="none"),re(K),r({type:"input:pinch:start",sessionId:e,payload:K});return}const N=ve(b);if(!N)return;W(!0),de.current=N,b.target.setPointerCapture(b.pointerId);const B=b.currentTarget.getBoundingClientRect();me.current=N,ne.current="down",ge.current=null;const w=oe.current;w&&(w.style.display="block",w.style.left=`${b.clientX-B.left}px`,w.style.top=`${b.clientY-B.top}px`,w.style.width=`${st*2}px`,w.style.height=`${st*2}px`,w.style.background="rgba(255,255,255,0.92)",w.style.border="1.5px solid rgba(0,0,0,0.2)",w.style.boxShadow="0 0 0 1px rgba(0,0,0,0.15), 0 0 8px rgba(255,255,255,0.25)"),r({type:"input:touch:start",sessionId:e,payload:N})},[ve,Ae,r,e]),_e=o.useCallback(b=>{if(b.buttons===0){if(le.current){re(Ae(b)),me.current=null;const j=oe.current;j&&(j.style.display="none");return}const g=ve(b),u=b.currentTarget.getBoundingClientRect(),S=oe.current;g?(me.current=g,ne.current!=="down"&&(ne.current="idle"),S&&(S.style.display="block",S.style.left=`${b.clientX-u.left}px`,S.style.top=`${b.clientY-u.top}px`,S.style.width=`${Ke*2}px`,S.style.height=`${Ke*2}px`,S.style.background="transparent",S.style.border="1.5px solid rgba(255,255,255,0.6)",S.style.boxShadow="0 0 0 1px rgba(0,0,0,0.3)")):(me.current=null,S&&(S.style.display="none"));return}if(pe.current){const g=Ae(b);if(!g)return;const u=performance.now();if(u-se.current<Wt)return;se.current=u,re(g),r({type:"input:pinch:move",sessionId:e,payload:g});return}if(!de.current)return;const N=ve(b);if(!N)return;const B=N.x-de.current.x,w=N.y-de.current.y;if(Math.sqrt(B*B+w*w)<Ss)return;const K=performance.now();if(K-se.current<Wt)return;se.current=K;const M=b.currentTarget.getBoundingClientRect();me.current=N;const c=oe.current;c&&c.style.display!=="none"&&(c.style.left=`${b.clientX-M.left}px`,c.style.top=`${b.clientY-M.top}px`),r({type:"input:touch:move",sessionId:e,payload:N})},[ve,Ae,r,e]),Ie=o.useCallback(()=>{if(pe.current){pe.current=!1,ce(!1),re(null),r({type:"input:pinch:end",sessionId:e});return}de.current=null,ne.current="release",ge.current={startTime:performance.now()};const b=oe.current;b&&(b.style.width=`${Ke*2}px`,b.style.height=`${Ke*2}px`,b.style.background="transparent",b.style.border="1.5px solid rgba(255,255,255,0.6)",b.style.boxShadow="0 0 0 1px rgba(0,0,0,0.3)"),r({type:"input:touch:end",sessionId:e})},[r,e]),Je=o.useCallback(()=>{if(pe.current){pe.current=!1,ce(!1),re(null),r({type:"input:pinch:end",sessionId:e});return}de.current=null,ne.current="release",ge.current={startTime:performance.now()},r({type:"input:touch:end",sessionId:e})},[r,e]),Oe=o.useCallback(()=>{re(null),me.current=null;const b=oe.current;b&&(b.style.display="none")},[]),xe=$??(U&&k?{width:U,height:k}:null),ct=xe?Math.min(1,jt/Math.max(xe.width,xe.height)):.3,Me=xe?Math.round(xe.width*ct):324,$e=xe?Math.round(xe.height*ct):720,St=xe?xe.width>xe.height:!1,He=te&&!St;o.useLayoutEffect(()=>{Be.current=He},[He]);const lt=He?$e:Me,Lt=He?Me:$e,Ze=_!=null?Math.round(_*Me):22,We=He?{position:"absolute",width:Me,height:$e,top:(Me-$e)/2,left:($e-Me)/2,transform:"rotate(90deg)",transformOrigin:"center center",visibility:ae?"visible":"hidden",cursor:"none"}:{visibility:ae?"visible":"hidden",cursor:"none"},Ve=n.jsx(n.Fragment,{children:d==null?void 0:d.map(b=>n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",onClick:()=>r({type:"input:button",sessionId:e,payload:{name:b.name}}),children:b.name==="back"?n.jsx(mr,{className:"h-4 w-4"}):b.name==="recent_apps"?n.jsx(On,{className:"h-4 w-4"}):b.name==="volume_up"?n.jsx(Pr,{className:"h-4 w-4"}):b.name==="volume_down"?n.jsx(Tr,{className:"h-4 w-4"}):b.name==="power"?n.jsx(jr,{className:"h-4 w-4"}):n.jsx(rn,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:b.accessibilityTitle})]},b.name))}),Qe=f&&t?n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx(ee,{variant:"ghost",size:"icon",className:"h-8 w-8",disabled:p||l,onClick:()=>{x(!0),r({type:"app:launch",sessionId:e,buildId:t})},children:p?n.jsx(pt,{className:"h-4 w-4 animate-spin"}):n.jsx(Zt,{className:"h-4 w-4"})})}),n.jsx(Re,{side:"left",children:p?"Launching…":l?"Installing…":"Launch app"})]}):null;return n.jsxs("div",{className:"flex items-start justify-center gap-16",children:[n.jsx("canvas",{ref:z,style:{display:"none"}}),n.jsx(un,{open:je,onOpenChange:he,sessionId:e,send:r}),n.jsx(cn,{joined:a,onDeepLink:()=>he(!0),onScreenshot:Pe,onRecordToggle:ze,recordState:X,onRotate:Le,platformSlot:Ve,launchSlot:Qe}),n.jsxs("div",{className:"flex items-start gap-8",children:[n.jsx("div",{style:{background:"#1c1c1e",borderRadius:`${Ze+12}px`,padding:"12px",flexShrink:0,boxShadow:"0 8px 32px rgba(0,0,0,0.45), inset 0 1px 0 rgba(255,255,255,0.06)"},children:n.jsx("div",{ref:P,className:"relative",style:{width:lt,height:Lt,backgroundColor:"#010101",borderRadius:`${Ze}px`,overflow:"hidden"},children:fe?n.jsx("div",{className:"absolute inset-0 flex items-center justify-center p-4 text-center",children:n.jsxs("span",{style:{color:"rgba(255,255,255,0.6)",fontSize:"0.875rem"},children:["이 환경에서는 스트리밍을 표시할 수 없습니다.",n.jsx("br",{}),"Chrome/Edge 또는 HTTPS 환경에서 다시 시도해 주세요."]})}):n.jsxs(n.Fragment,{children:[n.jsx("div",{ref:C,className:He?void 0:"block w-full h-full",style:We,onPointerDown:it,onPointerMove:_e,onPointerUp:Ie,onPointerCancel:Je,onPointerLeave:Oe}),!ae&&n.jsx("div",{className:"absolute inset-0 animate-pulse bg-zinc-700"}),!ae&&i&&n.jsx("div",{className:"absolute inset-0 flex items-center justify-center pointer-events-none",children:n.jsx("span",{style:{color:"rgba(255,255,255,0.6)",fontSize:"0.875rem"},children:"Waiting for stream…"})}),n.jsx("div",{ref:oe,style:{display:"none",position:"absolute",zIndex:20,borderRadius:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none",transition:"width 0.1s ease, height 0.1s ease, background 0.1s ease, box-shadow 0.1s ease"}}),J&&n.jsx(n.Fragment,{children:[J.f0,J.f1].map((b,N)=>n.jsx("div",{style:{position:"absolute",zIndex:10,borderRadius:"50%",transform:"translate(-50%, -50%)",pointerEvents:"none",transition:"width 0.1s ease, height 0.1s ease, background 0.1s ease",left:`${b.x*100}%`,top:`${b.y*100}%`,...Q?{width:st*2,height:st*2,background:"rgba(255,255,255,0.92)",border:"1.5px solid rgba(0,0,0,0.2)",boxShadow:"0 0 0 1px rgba(0,0,0,0.15), 0 0 8px rgba(255,255,255,0.25)"}:{width:Ke*2,height:Ke*2,background:"transparent",border:"1.5px solid rgba(255,255,255,0.6)",boxShadow:"0 0 0 1px rgba(0,0,0,0.3)"}}},N))})]})})}),n.jsx(Tt,{joined:a,fps:D,connected:s,deviceReady:i,bootError:m,installing:l,installError:h,keyboardActive:L})]})]})}function js({sessionId:e,deviceId:t,buildId:r,resetMode:s,onRecordingUploaded:a}){const i=o.useRef(()=>{});Lr();const l=o.useRef(null),f=o.useRef(null),h=o.useRef([]);o.useRef({onFrameBegin:()=>{var L;return(L=l.current)==null?void 0:L.onFrameBegin()},onFrameEnd:L=>{var ce,J;const W=h.current.shift()??null,Q=W?{...L,capturedAt:W.capturedAt,relayedAt:W.relayedAt}:L;(ce=l.current)==null||ce.onFrameEnd(Q),(J=f.current)==null||J.call(f,Q)}});const[m,p]=o.useState(!1),[x,d]=o.useState(!1),[v,R]=o.useState(null),[U,k]=o.useState(!1),[_,A]=o.useState(!1),[C,P]=o.useState(null),[F,D]=o.useState(null),[I,X]=o.useState(!1),[z,O]=o.useState(!1),[q,je]=o.useState(!1),he=o.useRef(void 0),ae=o.useCallback(L=>{if(L.type==="session:joined"&&(p(!0),i.current({type:"device:boot",sessionId:e,payload:{deviceId:t,resetMode:s,acceptH264:ss(),secureContext:window.isSecureContext}})),L.type==="device:boot-error"&&D(L.message),L.type==="device:booting"&&(d(!1),k(!1),A(!1),P(null),D(null),R(null)),L.type==="device:ready"&&(d(!0),r&&(k(!0),i.current({type:"app:install",sessionId:e,buildId:r}))),L.type==="app:install-done"&&(k(!1),A(!0)),L.type==="app:install-error"&&(k(!1),P(L.message)),L.type==="app:launch-done"&&X(!1),L.type==="app:launch-error"&&X(!1),L.type==="session:chrome"&&R(L.payload),L.type==="keyboard:toggled"){const{visible:W}=L.payload;O(W),je(!1)}L.type==="open-url:done"&&at.success("Deeplink opened"),L.type==="open-url:error"&&at.error(L.message),L.type==="error"&&L.message==="Agent resources exhausted"&&at.error("Could not start session — this Mac is currently overloaded.",{description:"Go back and select a different Mac."})},[e,t,r]),ke=o.useCallback(L=>{var J;const W=bs(L);W&&W.codec===mt||h.current.push(W);const Q=W?L.slice(fn):L,ce=W?{codec:W.codec,keyframe:W.keyframe,capturedAt:W.capturedAt,relayedAt:W.relayedAt}:void 0;(J=he.current)==null||J.call(he,Q,ce)},[]),{send:fe,connected:ie}=Qt(ae,ke);o.useLayoutEffect(()=>{i.current=fe}),o.useEffect(()=>{ie&&fe({type:"session:start",sessionId:e})},[ie,fe,e]);const E=v!==null&&"framePng"in v?v:null,$=v!==null&&!("framePng"in v)?v:null,te={sessionId:e,buildId:r,send:fe,connected:ie,joined:m,deviceReady:x,installing:U,installed:_,installError:C,bootError:F,launching:I,setLaunching:X,binaryFrameHandlerRef:he,onRecordingUploaded:a,swKeyboardVisible:z,swKeyboardPending:q,onKbdToggle:()=>{je(!0),fe({type:"input:keyboard:toggle",sessionId:e})}};if(!E&&!$)return n.jsxs("div",{className:"flex items-start justify-center gap-16",children:[n.jsx("div",{className:"flex flex-col items-center gap-0.5 rounded-2xl border bg-background/90 px-1.5 py-2.5 shrink-0 mt-3 opacity-40",children:Array.from({length:5}).map((L,W)=>n.jsx("div",{className:"h-8 w-8 rounded-md bg-muted animate-pulse"},W))}),n.jsxs("div",{className:"flex items-start gap-8",children:[n.jsx("div",{style:{background:"#1c1c1e",borderRadius:"34px",padding:"12px",flexShrink:0},children:n.jsx("div",{className:"animate-pulse bg-zinc-700",style:{width:324,height:720,borderRadius:"22px"}})}),n.jsx(Tt,{joined:m,fps:0,connected:ie,deviceReady:x,bootError:F,installing:U,installError:C,keyboardActive:!1})]})]});const Ce=void 0;return n.jsxs(n.Fragment,{children:[E&&n.jsx(ws,{...te,chrome:E,perfHookRef:Ce}),$&&n.jsx(Rs,{...te,androidButtons:$.buttons,screenWidth:$.screenWidth,screenHeight:$.screenHeight,cornerRadius:$.cornerRadius,perfHookRef:Ce}),!1]})}const mn=o.forwardRef(({className:e,...t},r)=>n.jsx("textarea",{className:Y("flex min-h-[80px] w-full rounded-md border border-input bg-background px-3 py-2 text-base ring-offset-background placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 md:text-sm",e),ref:r,...t}));mn.displayName="Textarea";function ks(e,t){return o.useReducer((r,s)=>t[r][s]??r,e)}var Pt="ScrollArea",[gn]=Jt(Pt),[Cs,be]=gn(Pt),xn=o.forwardRef((e,t)=>{const{__scopeScrollArea:r,type:s="hover",dir:a,scrollHideDelay:i=600,...l}=e,[f,h]=o.useState(null),[m,p]=o.useState(null),[x,d]=o.useState(null),[v,R]=o.useState(null),[U,k]=o.useState(null),[_,A]=o.useState(0),[C,P]=o.useState(0),[F,D]=o.useState(!1),[I,X]=o.useState(!1),z=Fe(t,q=>h(q)),O=$n(a);return n.jsx(Cs,{scope:r,type:s,dir:O,scrollHideDelay:i,scrollArea:f,viewport:m,onViewportChange:p,content:x,onContentChange:d,scrollbarX:v,onScrollbarXChange:R,scrollbarXEnabled:F,onScrollbarXEnabledChange:D,scrollbarY:U,onScrollbarYChange:k,scrollbarYEnabled:I,onScrollbarYEnabledChange:X,onCornerWidthChange:A,onCornerHeightChange:P,children:n.jsx(qe.div,{dir:O,...l,ref:z,style:{position:"relative","--radix-scroll-area-corner-width":_+"px","--radix-scroll-area-corner-height":C+"px",...e.style}})})});xn.displayName=Pt;var bn="ScrollAreaViewport",yn=o.forwardRef((e,t)=>{const{__scopeScrollArea:r,children:s,nonce:a,...i}=e,l=be(bn,r),f=o.useRef(null),h=Fe(t,f,l.onViewportChange);return n.jsxs(n.Fragment,{children:[n.jsx("style",{dangerouslySetInnerHTML:{__html:"[data-radix-scroll-area-viewport]{scrollbar-width:none;-ms-overflow-style:none;-webkit-overflow-scrolling:touch;}[data-radix-scroll-area-viewport]::-webkit-scrollbar{display:none}"},nonce:a}),n.jsx(qe.div,{"data-radix-scroll-area-viewport":"",...i,ref:h,style:{overflowX:l.scrollbarXEnabled?"scroll":"hidden",overflowY:l.scrollbarYEnabled?"scroll":"hidden",...e.style},children:n.jsx("div",{ref:l.onContentChange,style:{minWidth:"100%",display:"table"},children:s})})]})});yn.displayName=bn;var Te="ScrollAreaScrollbar",At=o.forwardRef((e,t)=>{const{forceMount:r,...s}=e,a=be(Te,e.__scopeScrollArea),{onScrollbarXEnabledChange:i,onScrollbarYEnabledChange:l}=a,f=e.orientation==="horizontal";return o.useEffect(()=>(f?i(!0):l(!0),()=>{f?i(!1):l(!1)}),[f,i,l]),a.type==="hover"?n.jsx(Es,{...s,ref:t,forceMount:r}):a.type==="scroll"?n.jsx(Ns,{...s,ref:t,forceMount:r}):a.type==="auto"?n.jsx(vn,{...s,ref:t,forceMount:r}):a.type==="always"?n.jsx(_t,{...s,ref:t}):null});At.displayName=Te;var Es=o.forwardRef((e,t)=>{const{forceMount:r,...s}=e,a=be(Te,e.__scopeScrollArea),[i,l]=o.useState(!1);return o.useEffect(()=>{const f=a.scrollArea;let h=0;if(f){const m=()=>{window.clearTimeout(h),l(!0)},p=()=>{h=window.setTimeout(()=>l(!1),a.scrollHideDelay)};return f.addEventListener("pointerenter",m),f.addEventListener("pointerleave",p),()=>{window.clearTimeout(h),f.removeEventListener("pointerenter",m),f.removeEventListener("pointerleave",p)}}},[a.scrollArea,a.scrollHideDelay]),n.jsx(bt,{present:r||i,children:n.jsx(vn,{"data-state":i?"visible":"hidden",...s,ref:t})})}),Ns=o.forwardRef((e,t)=>{const{forceMount:r,...s}=e,a=be(Te,e.__scopeScrollArea),i=e.orientation==="horizontal",l=vt(()=>h("SCROLL_END"),100),[f,h]=ks("hidden",{hidden:{SCROLL:"scrolling"},scrolling:{SCROLL_END:"idle",POINTER_ENTER:"interacting"},interacting:{SCROLL:"interacting",POINTER_LEAVE:"idle"},idle:{HIDE:"hidden",SCROLL:"scrolling",POINTER_ENTER:"interacting"}});return o.useEffect(()=>{if(f==="idle"){const m=window.setTimeout(()=>h("HIDE"),a.scrollHideDelay);return()=>window.clearTimeout(m)}},[f,a.scrollHideDelay,h]),o.useEffect(()=>{const m=a.viewport,p=i?"scrollLeft":"scrollTop";if(m){let x=m[p];const d=()=>{const v=m[p];x!==v&&(h("SCROLL"),l()),x=v};return m.addEventListener("scroll",d),()=>m.removeEventListener("scroll",d)}},[a.viewport,i,h,l]),n.jsx(bt,{present:r||f!=="hidden",children:n.jsx(_t,{"data-state":f==="hidden"?"hidden":"visible",...s,ref:t,onPointerEnter:Ue(e.onPointerEnter,()=>h("POINTER_ENTER")),onPointerLeave:Ue(e.onPointerLeave,()=>h("POINTER_LEAVE"))})})}),vn=o.forwardRef((e,t)=>{const r=be(Te,e.__scopeScrollArea),{forceMount:s,...a}=e,[i,l]=o.useState(!1),f=e.orientation==="horizontal",h=vt(()=>{if(r.viewport){const m=r.viewport.offsetWidth<r.viewport.scrollWidth,p=r.viewport.offsetHeight<r.viewport.scrollHeight;l(f?m:p)}},10);return et(r.viewport,h),et(r.content,h),n.jsx(bt,{present:s||i,children:n.jsx(_t,{"data-state":i?"visible":"hidden",...a,ref:t})})}),_t=o.forwardRef((e,t)=>{const{orientation:r="vertical",...s}=e,a=be(Te,e.__scopeScrollArea),i=o.useRef(null),l=o.useRef(0),[f,h]=o.useState({content:0,viewport:0,scrollbar:{size:0,paddingStart:0,paddingEnd:0}}),m=kn(f.viewport,f.content),p={...s,sizes:f,onSizesChange:h,hasThumb:m>0&&m<1,onThumbChange:d=>i.current=d,onThumbPointerUp:()=>l.current=0,onThumbPointerDown:d=>l.current=d};function x(d,v){return Ls(d,l.current,f,v)}return r==="horizontal"?n.jsx(Ts,{...p,ref:t,onThumbPositionChange:()=>{if(a.viewport&&i.current){const d=a.viewport.scrollLeft,v=Vt(d,f,a.dir);i.current.style.transform=`translate3d(${v}px, 0, 0)`}},onWheelScroll:d=>{a.viewport&&(a.viewport.scrollLeft=d)},onDragScroll:d=>{a.viewport&&(a.viewport.scrollLeft=x(d,a.dir))}}):r==="vertical"?n.jsx(Ps,{...p,ref:t,onThumbPositionChange:()=>{if(a.viewport&&i.current){const d=a.viewport.scrollTop,v=Vt(d,f);i.current.style.transform=`translate3d(0, ${v}px, 0)`}},onWheelScroll:d=>{a.viewport&&(a.viewport.scrollTop=d)},onDragScroll:d=>{a.viewport&&(a.viewport.scrollTop=x(d))}}):null}),Ts=o.forwardRef((e,t)=>{const{sizes:r,onSizesChange:s,...a}=e,i=be(Te,e.__scopeScrollArea),[l,f]=o.useState(),h=o.useRef(null),m=Fe(t,h,i.onScrollbarXChange);return o.useEffect(()=>{h.current&&f(getComputedStyle(h.current))},[h]),n.jsx(Sn,{"data-orientation":"horizontal",...a,ref:m,sizes:r,style:{bottom:0,left:i.dir==="rtl"?"var(--radix-scroll-area-corner-width)":0,right:i.dir==="ltr"?"var(--radix-scroll-area-corner-width)":0,"--radix-scroll-area-thumb-width":yt(r)+"px",...e.style},onThumbPointerDown:p=>e.onThumbPointerDown(p.x),onDragScroll:p=>e.onDragScroll(p.x),onWheelScroll:(p,x)=>{if(i.viewport){const d=i.viewport.scrollLeft+p.deltaX;e.onWheelScroll(d),En(d,x)&&p.preventDefault()}},onResize:()=>{h.current&&i.viewport&&l&&s({content:i.viewport.scrollWidth,viewport:i.viewport.offsetWidth,scrollbar:{size:h.current.clientWidth,paddingStart:xt(l.paddingLeft),paddingEnd:xt(l.paddingRight)}})}})}),Ps=o.forwardRef((e,t)=>{const{sizes:r,onSizesChange:s,...a}=e,i=be(Te,e.__scopeScrollArea),[l,f]=o.useState(),h=o.useRef(null),m=Fe(t,h,i.onScrollbarYChange);return o.useEffect(()=>{h.current&&f(getComputedStyle(h.current))},[h]),n.jsx(Sn,{"data-orientation":"vertical",...a,ref:m,sizes:r,style:{top:0,right:i.dir==="ltr"?0:void 0,left:i.dir==="rtl"?0:void 0,bottom:"var(--radix-scroll-area-corner-height)","--radix-scroll-area-thumb-height":yt(r)+"px",...e.style},onThumbPointerDown:p=>e.onThumbPointerDown(p.y),onDragScroll:p=>e.onDragScroll(p.y),onWheelScroll:(p,x)=>{if(i.viewport){const d=i.viewport.scrollTop+p.deltaY;e.onWheelScroll(d),En(d,x)&&p.preventDefault()}},onResize:()=>{h.current&&i.viewport&&l&&s({content:i.viewport.scrollHeight,viewport:i.viewport.offsetHeight,scrollbar:{size:h.current.clientHeight,paddingStart:xt(l.paddingTop),paddingEnd:xt(l.paddingBottom)}})}})}),[As,wn]=gn(Te),Sn=o.forwardRef((e,t)=>{const{__scopeScrollArea:r,sizes:s,hasThumb:a,onThumbChange:i,onThumbPointerUp:l,onThumbPointerDown:f,onThumbPositionChange:h,onDragScroll:m,onWheelScroll:p,onResize:x,...d}=e,v=be(Te,r),[R,U]=o.useState(null),k=Fe(t,z=>U(z)),_=o.useRef(null),A=o.useRef(""),C=v.viewport,P=s.content-s.viewport,F=Ge(p),D=Ge(h),I=vt(x,10);function X(z){if(_.current){const O=z.clientX-_.current.left,q=z.clientY-_.current.top;m({x:O,y:q})}}return o.useEffect(()=>{const z=O=>{const q=O.target;(R==null?void 0:R.contains(q))&&F(O,P)};return document.addEventListener("wheel",z,{passive:!1}),()=>document.removeEventListener("wheel",z,{passive:!1})},[C,R,P,F]),o.useEffect(D,[s,D]),et(R,I),et(v.content,I),n.jsx(As,{scope:r,scrollbar:R,hasThumb:a,onThumbChange:Ge(i),onThumbPointerUp:Ge(l),onThumbPositionChange:D,onThumbPointerDown:Ge(f),children:n.jsx(qe.div,{...d,ref:k,style:{position:"absolute",...d.style},onPointerDown:Ue(e.onPointerDown,z=>{z.button===0&&(z.target.setPointerCapture(z.pointerId),_.current=R.getBoundingClientRect(),A.current=document.body.style.webkitUserSelect,document.body.style.webkitUserSelect="none",v.viewport&&(v.viewport.style.scrollBehavior="auto"),X(z))}),onPointerMove:Ue(e.onPointerMove,X),onPointerUp:Ue(e.onPointerUp,z=>{const O=z.target;O.hasPointerCapture(z.pointerId)&&O.releasePointerCapture(z.pointerId),document.body.style.webkitUserSelect=A.current,v.viewport&&(v.viewport.style.scrollBehavior=""),_.current=null})})})}),gt="ScrollAreaThumb",Rn=o.forwardRef((e,t)=>{const{forceMount:r,...s}=e,a=wn(gt,e.__scopeScrollArea);return n.jsx(bt,{present:r||a.hasThumb,children:n.jsx(_s,{ref:t,...s})})}),_s=o.forwardRef((e,t)=>{const{__scopeScrollArea:r,style:s,...a}=e,i=be(gt,r),l=wn(gt,r),{onThumbPositionChange:f}=l,h=Fe(t,x=>l.onThumbChange(x)),m=o.useRef(void 0),p=vt(()=>{m.current&&(m.current(),m.current=void 0)},100);return o.useEffect(()=>{const x=i.viewport;if(x){const d=()=>{if(p(),!m.current){const v=Ms(x,f);m.current=v,f()}};return f(),x.addEventListener("scroll",d),()=>x.removeEventListener("scroll",d)}},[i.viewport,p,f]),n.jsx(qe.div,{"data-state":l.hasThumb?"visible":"hidden",...a,ref:h,style:{width:"var(--radix-scroll-area-thumb-width)",height:"var(--radix-scroll-area-thumb-height)",...s},onPointerDownCapture:Ue(e.onPointerDownCapture,x=>{const v=x.target.getBoundingClientRect(),R=x.clientX-v.left,U=x.clientY-v.top;l.onThumbPointerDown({x:R,y:U})}),onPointerUp:Ue(e.onPointerUp,l.onThumbPointerUp)})});Rn.displayName=gt;var Dt="ScrollAreaCorner",jn=o.forwardRef((e,t)=>{const r=be(Dt,e.__scopeScrollArea),s=!!(r.scrollbarX&&r.scrollbarY);return r.type!=="scroll"&&s?n.jsx(Ds,{...e,ref:t}):null});jn.displayName=Dt;var Ds=o.forwardRef((e,t)=>{const{__scopeScrollArea:r,...s}=e,a=be(Dt,r),[i,l]=o.useState(0),[f,h]=o.useState(0),m=!!(i&&f);return et(a.scrollbarX,()=>{var x;const p=((x=a.scrollbarX)==null?void 0:x.offsetHeight)||0;a.onCornerHeightChange(p),h(p)}),et(a.scrollbarY,()=>{var x;const p=((x=a.scrollbarY)==null?void 0:x.offsetWidth)||0;a.onCornerWidthChange(p),l(p)}),m?n.jsx(qe.div,{...s,ref:t,style:{width:i,height:f,position:"absolute",right:a.dir==="ltr"?0:void 0,left:a.dir==="rtl"?0:void 0,bottom:0,...e.style}}):null});function xt(e){return e?parseInt(e,10):0}function kn(e,t){const r=e/t;return isNaN(r)?0:r}function yt(e){const t=kn(e.viewport,e.content),r=e.scrollbar.paddingStart+e.scrollbar.paddingEnd,s=(e.scrollbar.size-r)*t;return Math.max(s,18)}function Ls(e,t,r,s="ltr"){const a=yt(r),i=a/2,l=t||i,f=a-l,h=r.scrollbar.paddingStart+l,m=r.scrollbar.size-r.scrollbar.paddingEnd-f,p=r.content-r.viewport,x=s==="ltr"?[0,p]:[p*-1,0];return Cn([h,m],x)(e)}function Vt(e,t,r="ltr"){const s=yt(t),a=t.scrollbar.paddingStart+t.scrollbar.paddingEnd,i=t.scrollbar.size-a,l=t.content-t.viewport,f=i-s,h=r==="ltr"?[0,l]:[l*-1,0],m=cr(e,h);return Cn([0,l],[0,f])(m)}function Cn(e,t){return r=>{if(e[0]===e[1]||t[0]===t[1])return t[0];const s=(t[1]-t[0])/(e[1]-e[0]);return t[0]+s*(r-e[0])}}function En(e,t){return e>0&&e<t}var Ms=(e,t=()=>{})=>{let r={left:e.scrollLeft,top:e.scrollTop},s=0;return(function a(){const i={left:e.scrollLeft,top:e.scrollTop},l=r.left!==i.left,f=r.top!==i.top;(l||f)&&t(),r=i,s=window.requestAnimationFrame(a)})(),()=>window.cancelAnimationFrame(s)};function vt(e,t){const r=Ge(e),s=o.useRef(0);return o.useEffect(()=>()=>window.clearTimeout(s.current),[]),o.useCallback(()=>{window.clearTimeout(s.current),s.current=window.setTimeout(r,t)},[r,t])}function et(e,t){const r=Ge(t);Wn(()=>{let s=0;if(e){const a=new ResizeObserver(()=>{cancelAnimationFrame(s),s=window.requestAnimationFrame(r)});return a.observe(e),()=>{window.cancelAnimationFrame(s),a.unobserve(e)}}},[e,r])}var Nn=xn,Hs=yn,Us=jn;const Tn=o.forwardRef(({className:e,children:t,...r},s)=>n.jsxs(Nn,{ref:s,className:Y("relative overflow-hidden",e),...r,children:[n.jsx(Hs,{className:"h-full w-full rounded-[inherit]",children:t}),n.jsx(Pn,{}),n.jsx(Us,{})]}));Tn.displayName=Nn.displayName;const Pn=o.forwardRef(({className:e,orientation:t="vertical",...r},s)=>n.jsx(At,{ref:s,orientation:t,className:Y("flex touch-none select-none transition-colors",t==="vertical"&&"h-full w-2.5 border-l border-l-transparent p-[1px]",t==="horizontal"&&"h-2.5 flex-col border-t border-t-transparent p-[1px]",e),...r,children:n.jsx(Rn,{className:"relative flex-1 rounded-full bg-border"})}));Pn.displayName=At.displayName;function An(e){return/[Zz]|[+-]\d{2}/.test(e)?new Date(e):new Date(e.replace(" ","T")+"Z")}function Fs(e){const t=new Map;for(const a of e){const i=An(a.created_at).toDateString();t.has(i)||t.set(i,[]),t.get(i).push(a)}const r=new Date().toDateString(),s=new Date(Date.now()-864e5).toDateString();return Array.from(t.entries()).map(([a,i])=>{let l;if(a===r)l="Today";else if(a===s)l="Yesterday";else{const f=new Date(a);l=f.toLocaleDateString(void 0,{month:"short",day:"numeric",...f.getFullYear()!==new Date().getFullYear()?{year:"numeric"}:{}})}return{label:l,items:i}})}function zs(e){return An(e).toLocaleTimeString(void 0,{hour:"numeric",minute:"2-digit"})}const Bs=5*1024*1024,Is=["image/png","image/jpeg","image/webp"];function Os({buildId:e}){const[t,r]=o.useState([]),[s,a]=o.useState(""),[i,l]=o.useState(null),[f,h]=o.useState(!1),[m,p]=o.useState(""),x=o.useRef(null),d=o.useRef({});function v(){fetch(`/api/v1/comments?build_id=${e}`,{credentials:"include"}).then(A=>A.ok?A.json():[]).then(r)}o.useEffect(()=>{v()},[e]),o.useEffect(()=>{const A=window.location.hash;if(!A.startsWith("#comment-"))return;const C=Number(A.replace("#comment-","")),P=d.current[C];if(!P)return;P.scrollIntoView({behavior:"smooth"});const F=document.documentElement.classList.contains("dark");P.style.backgroundColor=F?"rgb(0 112 243 / 0.18)":"#d3e5ff",setTimeout(()=>{P.style.backgroundColor=""},2e3)},[t]);function R(A){const C=`${location.origin}${location.pathname}${location.search}#comment-${A}`;navigator.clipboard.writeText(C).then(()=>at.success("Link copied")).catch(()=>at.error("Could not copy link"))}function U(A){if(p(""),!Is.includes(A.type)){p("Only png, jpg, webp allowed");return}if(A.size>Bs){p("Max 5MB");return}l(A)}async function k(A){if(A.preventDefault(),!s.trim()&&!i)return;h(!0);const C=new FormData;C.append("build_id",String(e)),C.append("body",s),i&&C.append("attachment",i),(await fetch("/api/v1/comments",{method:"POST",credentials:"include",body:C})).ok&&(a(""),l(null),v()),h(!1)}const _=Fs(t);return n.jsxs("div",{className:"flex h-full flex-col gap-3 px-1",children:[n.jsx(Tn,{className:"flex-1 rounded-md border",children:n.jsx("div",{className:"p-3",children:t.length===0?n.jsx("p",{className:"text-sm text-muted-foreground text-center py-8",children:"No comments yet."}):n.jsx("div",{className:"flex flex-col",children:_.map(({label:A,items:C})=>n.jsxs("div",{children:[n.jsxs("div",{className:"flex items-center gap-2 py-3",children:[n.jsx("div",{className:"h-px flex-1 bg-border"}),n.jsx("span",{className:"text-[11px] font-medium text-muted-foreground px-1 select-none",children:A}),n.jsx("div",{className:"h-px flex-1 bg-border"})]}),n.jsx("div",{className:"flex flex-col gap-4",children:C.map(P=>n.jsxs("div",{id:`comment-${P.id}`,ref:F=>{d.current[P.id]=F},className:"group flex gap-2.5 rounded-md px-2 py-1.5 transition-all",children:[n.jsx("div",{className:"mt-0.5 shrink-0",children:n.jsx(Vn,{name:P.author,avatarUrl:P.authorAvatarUrl,size:28})}),n.jsxs("div",{className:"flex-1 min-w-0",children:[n.jsxs("div",{className:"flex items-center gap-1.5",children:[n.jsx("span",{className:"text-sm font-semibold leading-none",children:P.author}),n.jsx("span",{className:"text-[11px] text-muted-foreground leading-none",children:zs(P.created_at)}),n.jsx(ee,{variant:"ghost",size:"icon",className:"h-4 w-4 ml-0.5 opacity-0 group-hover:opacity-50 hover:!opacity-100 transition-opacity",onClick:()=>R(P.id),children:n.jsx(sn,{className:"h-3 w-3"})})]}),n.jsx("p",{className:"text-sm leading-relaxed whitespace-pre-wrap mt-1",children:P.body}),P.attachments.map(F=>n.jsx("a",{href:F.file_path,target:"_blank",rel:"noreferrer",className:"mt-1.5 block",children:n.jsx("img",{src:F.file_path,alt:"attachment",className:"max-h-48 rounded border object-contain"})},F.id))]})]},P.id))})]},A))})})}),n.jsx("div",{className:"pb-1",children:n.jsx("form",{onSubmit:k,children:n.jsxs("div",{className:"rounded-xl border border-input bg-background ring-offset-background transition-shadow focus-within:outline-none focus-within:ring-2 focus-within:ring-ring focus-within:ring-offset-2",children:[n.jsx(mn,{placeholder:"Leave a comment…",value:s,onChange:A=>a(A.target.value),className:"min-h-16 resize-none border-0 bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0 text-sm"}),(i||m)&&n.jsxs("div",{className:"px-3 -mt-1 pb-1",children:[i&&n.jsx("p",{className:"text-xs text-muted-foreground",children:i.name}),m&&n.jsx("p",{className:"text-xs text-destructive",children:m})]}),n.jsxs("div",{className:"flex items-center gap-2 px-2 py-2",children:[n.jsx(ee,{type:"button",variant:"ghost",size:"icon",className:"h-7 w-7 text-muted-foreground",onClick:()=>{var A;return(A=x.current)==null?void 0:A.click()},children:n.jsx(vr,{className:"h-4 w-4"})}),n.jsx("input",{ref:x,type:"file",accept:"image/png,image/jpeg,image/webp",className:"hidden",onChange:A=>{var P;const C=(P=A.target.files)==null?void 0:P[0];C&&U(C)}}),n.jsx("div",{className:"flex-1"}),n.jsx(ee,{type:"submit",size:"icon",className:"h-7 w-7 rounded-full",disabled:f||!s.trim()&&!i,children:n.jsx(gr,{className:"h-3.5 w-3.5"})})]})]})})})]})}function $s(e){return e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/1024/1024).toFixed(1)} MB`}function Ws(e){return new Date(e).toLocaleString(void 0,{month:"short",day:"numeric",hour:"2-digit",minute:"2-digit"})}function Vs(e){const t=new Date(e).getTime()-Date.now();if(t<=0)return{label:"Expired",urgent:!0};const r=Math.floor(t/36e5);return r<1?{label:"< 1 hour left",urgent:!0}:r<24?{label:`Expires in ${r}h`,urgent:r<6}:{label:`Expires in ${Math.floor(r/24)}d`,urgent:!1}}function Xs({buildId:e,refreshKey:t}){const[r,s]=o.useState([]),[a,i]=o.useState(!0),[l,f]=o.useState(!1);return o.useEffect(()=>{i(!0),f(!1);const h=setTimeout(()=>f(!0),250);return fetch(`/api/v1/recordings?buildId=${e}`,{credentials:"include"}).then(m=>m.ok?m.json():[]).then(m=>s(m)).catch(()=>s([])).finally(()=>{clearTimeout(h),i(!1)}),()=>clearTimeout(h)},[e,t]),a?l?n.jsx("p",{className:"text-xs text-muted-foreground",children:"Loading recordings…"}):null:r.length===0?n.jsx("p",{className:"py-8 text-center text-sm text-muted-foreground",children:"No recordings yet."}):n.jsx("div",{className:"flex flex-col gap-2",children:r.map(h=>{const m=Vs(h.expiresAt);return n.jsxs("div",{className:"flex items-center justify-between rounded-md border border-border px-3 py-2 text-sm",children:[n.jsxs("div",{className:"flex flex-col gap-0.5 min-w-0",children:[n.jsx("span",{className:"text-xs font-medium truncate",children:Ws(h.createdAt)}),n.jsxs("span",{className:`text-xs ${m.urgent?"text-destructive":"text-muted-foreground"}`,children:[m.label," · ",$s(h.fileSize)]})]}),n.jsx(ee,{variant:"ghost",size:"icon",className:"h-7 w-7 shrink-0 ml-2",title:"Download",onClick:()=>{const p=document.createElement("a");p.href=h.url,p.download="",p.click()},children:n.jsx(br,{className:"h-3.5 w-3.5"})})]},h.id)})})}function Ks({buildId:e,recordingsRefreshKey:t=0}){return n.jsxs(rr,{defaultValue:"comments",className:"flex h-full flex-col",children:[n.jsx("div",{className:"shrink-0 px-1",children:n.jsxs(sr,{className:"w-full",children:[n.jsxs(Ut,{value:"comments",className:"flex-1 gap-1.5",children:[n.jsx(Rr,{className:"h-3.5 w-3.5"}),"Comments"]}),n.jsxs(Ut,{value:"recordings",className:"flex-1 gap-1.5",children:[n.jsx(yr,{className:"h-3.5 w-3.5"}),"Recordings"]})]})}),n.jsx(Ft,{value:"comments",className:"mt-3 min-h-0 flex-1 overflow-hidden",children:n.jsx(Os,{buildId:e})}),n.jsx(Ft,{value:"recordings",className:"mt-3 min-h-0 flex-1 overflow-y-auto",children:n.jsx(Xs,{buildId:e,refreshKey:t})})]})}const _n=o.forwardRef(({...e},t)=>n.jsx("nav",{ref:t,"aria-label":"breadcrumb",...e}));_n.displayName="Breadcrumb";const Dn=o.forwardRef(({className:e,...t},r)=>n.jsx("ol",{ref:r,className:Y("flex flex-wrap items-center gap-1.5 break-words text-sm text-muted-foreground sm:gap-2.5",e),...t}));Dn.displayName="BreadcrumbList";const ot=o.forwardRef(({className:e,...t},r)=>n.jsx("li",{ref:r,className:Y("inline-flex items-center gap-1.5",e),...t}));ot.displayName="BreadcrumbItem";const ut=o.forwardRef(({asChild:e,className:t,...r},s)=>{const a=e?Xn:"a";return n.jsx(a,{ref:s,className:Y("transition-colors hover:text-foreground cursor-pointer",t),...r})});ut.displayName="BreadcrumbLink";const ht=o.forwardRef(({className:e,...t},r)=>n.jsx("span",{ref:r,role:"link","aria-disabled":"true","aria-current":"page",className:Y("font-medium text-foreground",e),...t}));ht.displayName="BreadcrumbPage";const ft=({children:e,className:t,...r})=>n.jsx("li",{role:"presentation","aria-hidden":"true",className:Y("[&>svg]:h-3.5 [&>svg]:w-3.5",t),...r,children:e??n.jsx(Kn,{})});ft.displayName="BreadcrumbSeparator";var wt="Switch",[Ys]=Jt(wt),[Gs,qs]=Ys(wt),Ln=o.forwardRef((e,t)=>{const{__scopeSwitch:r,name:s,checked:a,defaultChecked:i,required:l,disabled:f,value:h="on",onCheckedChange:m,form:p,...x}=e,[d,v]=o.useState(null),R=Fe(t,C=>v(C)),U=o.useRef(!1),k=d?p||!!d.closest("form"):!0,[_,A]=Yn({prop:a,defaultProp:i??!1,onChange:m,caller:wt});return n.jsxs(Gs,{scope:r,checked:_,disabled:f,children:[n.jsx(qe.button,{type:"button",role:"switch","aria-checked":_,"aria-required":l,"data-state":Fn(_),"data-disabled":f?"":void 0,disabled:f,value:h,...x,ref:R,onClick:Ue(e.onClick,C=>{A(P=>!P),k&&(U.current=C.isPropagationStopped(),U.current||C.stopPropagation())})}),k&&n.jsx(Un,{control:d,bubbles:!U.current,name:s,value:h,checked:_,required:l,disabled:f,form:p,style:{transform:"translateX(-100%)"}})]})});Ln.displayName=wt;var Mn="SwitchThumb",Hn=o.forwardRef((e,t)=>{const{__scopeSwitch:r,...s}=e,a=qs(Mn,r);return n.jsx(qe.span,{"data-state":Fn(a.checked),"data-disabled":a.disabled?"":void 0,...s,ref:t})});Hn.displayName=Mn;var Js="SwitchBubbleInput",Un=o.forwardRef(({__scopeSwitch:e,control:t,checked:r,bubbles:s=!0,...a},i)=>{const l=o.useRef(null),f=Fe(l,i),h=lr(r),m=Gn(t);return o.useEffect(()=>{const p=l.current;if(!p)return;const x=window.HTMLInputElement.prototype,v=Object.getOwnPropertyDescriptor(x,"checked").set;if(h!==r&&v){const R=new Event("click",{bubbles:s});v.call(p,r),p.dispatchEvent(R)}},[h,r,s]),n.jsx("input",{type:"checkbox","aria-hidden":!0,defaultChecked:r,...a,tabIndex:-1,ref:f,style:{...a.style,...m,position:"absolute",pointerEvents:"none",opacity:0,margin:0}})});Un.displayName=Js;function Fn(e){return e?"checked":"unchecked"}var zn=Ln,Zs=Hn;const Bn=o.forwardRef(({className:e,...t},r)=>n.jsx(zn,{className:Y("peer inline-flex h-6 w-11 shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50 data-[state=checked]:bg-primary data-[state=unchecked]:bg-input",e),...t,ref:r,children:n.jsx(Zs,{className:Y("pointer-events-none block h-5 w-5 rounded-full bg-background shadow-lg ring-0 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0")})}));Bn.displayName=zn.displayName;const Xt=70,Kt=80;function Qs(e,t){if(!e||t)return"unknown";const r=e.memUsedMB/e.memTotalMB*100;return e.cpuPercent>Kt||r>Kt?"overloaded":e.cpuPercent>=Xt||r>=Xt?"warning":"healthy"}function ao(){const[e]=Gt(),t=qn(),r=e.get("id"),{build:s}=Ar(r),[a,i]=o.useState(0),l=(s==null?void 0:s.platform)??"ios",{sessions:f,selectedAgent:h,setSelectedAgent:m,activeSessionId:p,deviceId:x,booting:d,status:v,connected:R,agentGroups:U,startDevice:k,resetDevice:_,handleBack:A,handleBackToMacs:C}=_r(l),P=U.find(E=>E.agentName===h),{osVersions:F,osVersion:D,setOsVersion:I,deviceSearch:X,setDeviceSearch:z,versionedDevices:O,resetMode:q,setResetMode:je}=Dr(P,l),ae=f.flatMap(E=>E.devices).find(E=>E.id===x),ke=ae?`${ae.name}${ae.osVersion?` · ${ae.osVersion}`:""}`:"",fe=o.useCallback(()=>i(E=>E+1),[]),{setNode:ie}=Jn();return o.useEffect(()=>{if(s)return ie(n.jsxs("div",{className:"flex items-center gap-3",children:[n.jsx(_n,{children:n.jsxs(Dn,{children:[n.jsx(ot,{children:n.jsx(ut,{asChild:!0,children:n.jsx("button",{onClick:()=>t(`/app-center?appId=${s.app_id}`),children:s.name})})}),n.jsx(ft,{}),n.jsx(ot,{children:h?n.jsx(ut,{asChild:!0,children:n.jsx("button",{onClick:C,children:Ht(s)})}):n.jsx(ht,{children:Ht(s)})}),h&&n.jsxs(n.Fragment,{children:[n.jsx(ft,{}),n.jsx(ot,{children:p?n.jsx(ut,{asChild:!0,children:n.jsx("button",{onClick:A,children:h})}):n.jsx(ht,{children:h})})]}),p&&n.jsxs(n.Fragment,{children:[n.jsx(ft,{}),n.jsx(ot,{children:n.jsx(ht,{children:ke})})]})]})}),!h&&s.status_label&&n.jsx(pr,{tone:tr[s.status_label],children:s.status_label})]})),()=>ie(null)},[s,h,p,ke,t,A,C,ie]),n.jsxs("div",{className:"flex h-full min-h-0 gap-6 p-6",children:[n.jsx("div",{className:"flex flex-col gap-3 flex-1 min-w-0 min-h-0",children:n.jsx("div",{className:"flex-1 min-h-0 overflow-auto -ml-1 pl-1 -mr-4 pr-4",children:p?n.jsx("div",{className:"min-h-full flex items-center justify-center py-6 px-8 min-w-max",children:n.jsx(js,{sessionId:p,deviceId:x,buildId:s==null?void 0:s.id,resetMode:q,onRecordingUploaded:fe})}):h?n.jsxs("div",{className:"flex flex-col gap-5",children:[n.jsxs("div",{className:"flex items-center gap-3",children:[n.jsx("button",{onClick:C,className:"text-sm text-muted-foreground hover:text-foreground transition-colors",children:"← All Macs"}),n.jsx("h1",{className:"text-xl font-semibold tracking-tight",children:"Select device"})]}),n.jsxs("div",{className:"flex items-center gap-2",children:[n.jsx(nr,{placeholder:"Search device…",value:X,onChange:z}),F.length>0&&n.jsxs(dr,{value:D||"__all__",onValueChange:E=>{I(E==="__all__"?"":E),_()},children:[n.jsx(ur,{className:"h-8 w-36 shrink-0",children:n.jsx(hr,{})}),n.jsxs(fr,{children:[n.jsx(zt,{value:"__all__",children:"Any version"}),F.map(E=>n.jsx(zt,{value:E,children:E},E))]})]}),n.jsx(kt,{children:n.jsxs(we,{children:[n.jsxs("div",{className:"ml-auto flex items-center gap-2 shrink-0",children:[n.jsx(Se,{asChild:!0,children:n.jsxs(Zn,{htmlFor:"reset-mode",className:"flex items-center gap-1 text-sm cursor-pointer whitespace-nowrap",children:[n.jsx(wr,{className:"h-3.5 w-3.5 text-muted-foreground"}),"Full reset"]})}),n.jsx(Bn,{id:"reset-mode",checked:q==="full-erase",onCheckedChange:E=>je(E?"full-erase":"app-only")})]}),n.jsx(Re,{children:q==="full-erase"?"Erase all data before booting":"Keep existing data"})]})})]}),O.length===0?n.jsx("p",{className:"text-sm text-muted-foreground",children:R?"No devices available for this OS.":"Connecting to relay…"}):n.jsx("div",{className:"grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 gap-2",children:O.map(E=>{const $=E.status==="booted",Z=E.busy,te=Z?"In use":$?"Booted":"Available",Ce=Z?"bg-amber-400":$?"bg-emerald-400":"bg-muted-foreground/40";return n.jsxs("button",{disabled:Z||d||!R,onClick:()=>k(E),className:Y("flex flex-col gap-3 rounded-lg border p-3 text-left transition-colors min-h-[100px]","hover:bg-accent disabled:cursor-not-allowed disabled:opacity-50"),children:[n.jsx("span",{className:"text-sm font-medium leading-tight",children:E.name}),E.osVersion&&n.jsx("span",{className:"font-mono text-xs text-muted-foreground",children:E.osVersion}),n.jsxs("span",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[n.jsx("span",{className:Y("inline-block h-1.5 w-1.5 rounded-full",Ce)}),te]})]},E.id)})}),v&&n.jsx("p",{className:"text-sm text-muted-foreground",children:v})]}):n.jsxs("div",{className:"flex flex-col gap-5",children:[n.jsx("h1",{className:"text-xl font-semibold tracking-tight",children:"Select Mac"}),U.length===0?n.jsx("p",{className:"text-sm text-muted-foreground",children:R?`No agents available for ${l}.`:"Connecting to relay…"}):n.jsx("div",{className:"grid grid-cols-1 lg:grid-cols-2 2xl:grid-cols-3 gap-2",children:U.map(E=>{const $=E.resources,Z=$?Date.now()-$.reportedAt>3e4:!1,te=E.devices.filter(ce=>ce.platform===l).length,Ce=($==null?void 0:$.cpuPercent)??0,L=$?$.memUsedMB/$.memTotalMB*100:0,W=Qs($,Z),Q=W==="overloaded";return n.jsx(kt,{children:n.jsxs(we,{children:[n.jsx(Se,{asChild:!0,children:n.jsx("span",{tabIndex:Q?0:void 0,className:Q?"cursor-not-allowed":void 0,children:n.jsxs("button",{disabled:Q,"aria-disabled":Q,onClick:()=>m(E.agentName??null),className:Y("flex flex-col gap-3 rounded-lg border p-3 text-left transition-colors min-h-[100px] w-full",Q?"pointer-events-none":"hover:bg-accent"),children:[n.jsxs("div",{className:"flex items-start justify-between gap-2",children:[n.jsxs("div",{className:"flex items-center gap-2 min-w-0",children:[n.jsx(eo,{health:W}),n.jsx("span",{className:"text-sm font-medium leading-tight truncate",children:E.agentName??"Unknown"})]}),Z&&n.jsx("span",{className:"shrink-0 text-[10px] font-medium text-amber-500",children:"Stale"})]}),n.jsxs("div",{className:"flex items-center gap-1.5 text-xs text-muted-foreground",children:[n.jsxs("span",{children:[te," device",te!==1?"s":""]}),$&&n.jsxs(n.Fragment,{children:[n.jsx("span",{children:"·"}),n.jsxs("span",{children:[$.slotsAvailable,"/",$.slotsTotal," slots"]})]})]}),$&&!Z&&n.jsxs("div",{className:"flex flex-col gap-1.5 w-full",children:[n.jsx(Yt,{label:"CPU",percent:Ce,colorClass:"bg-blue-400"}),n.jsx(Yt,{label:"RAM",percent:L,colorClass:"bg-violet-400"})]})]})})}),Q&&n.jsx(Re,{children:"This Mac is currently overloaded. Try again later."})]})},E.agentName)})})]})})}),r&&n.jsxs(n.Fragment,{children:[n.jsx(qt,{orientation:"vertical",className:"h-auto"}),n.jsx("div",{className:"w-80 shrink-0 h-full",children:n.jsx(Ks,{buildId:Number(r),recordingsRefreshKey:a})})]})]})}function eo({health:e}){const t={unknown:"bg-muted-foreground/40",healthy:"bg-emerald-400",warning:"bg-amber-400",overloaded:"bg-red-500"}[e];return n.jsx("span",{"data-testid":"resource-health-dot",className:Y("inline-block h-2 w-2 shrink-0 rounded-full",t)})}function Yt({label:e,percent:t,colorClass:r}){return n.jsxs("div",{className:"flex flex-col gap-0.5",children:[n.jsxs("div",{className:"flex justify-between text-[10px] text-muted-foreground",children:[n.jsx("span",{children:e}),n.jsxs("span",{children:[t.toFixed(0),"%"]})]}),n.jsx("div",{className:"h-1 w-full rounded-full bg-muted overflow-hidden",children:n.jsx("div",{className:Y("h-full rounded-full transition-all",r),style:{width:`${Math.min(100,t)}%`}})})]})}export{ao as QASession};
Binary file
@@ -1,6 +0,0 @@
1
- import{Z as z,a9 as i,ak as J,ac as G,a6 as e,B as t,L as D,I as U,k as _,C as q,d as Z,e as K,b as W,ab as j,a7 as I,aa as u,G as X}from"./index-ClAB0eKw.js";import{D as Y,f as ee,a as se,d as ae,e as ne,S as k,i as w,j as N,g as T,h as n}from"./dialog-BuZjQWBQ.js";import{A as ie,c as te,f as le,g as re,d as ce,e as oe,b as de,a as me}from"./alert-dialog-Ci_cWoVo.js";import{T as he,d as xe,e as A,c as l,a as je,b as r}from"./table-NBRnBazr.js";/**
2
- * @license lucide-react v0.468.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const ue=z("UserPlus",[["path",{d:"M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2",key:"1yyitq"}],["circle",{cx:"9",cy:"7",r:"4",key:"nufk8"}],["line",{x1:"19",x2:"19",y1:"8",y2:"14",key:"1bvyxn"}],["line",{x1:"22",x2:"16",y1:"11",y2:"11",key:"1shjgl"}]]),ve=I({email:u().email(),role:u().min(1)}),pe=I({token:u(),emailSent:X()});function ye(){const[v,R]=i.useState([]),[E,p]=i.useState({}),[g,f]=i.useState(""),[O,b]=i.useState(!1),[o,d]=i.useState(null),{register:P,handleSubmit:V,control:H,reset:L,formState:{errors:S,isSubmitting:y}}=J({resolver:G(ve),mode:"onBlur",defaultValues:{email:"",role:"QA"}});function m(){fetch("/api/v1/team/members",{credentials:"include"}).then(s=>s.json()).then(R)}i.useEffect(()=>{m()},[]);async function $(s){try{const a=await fetch("/api/v1/team/invite",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({email:s.email,role:s.role})});if(!a.ok)throw new Error(`Server error: ${a.status}`);const h=pe.parse(await a.json()),c=`${location.origin}/invite?token=${h.token}`;f(c),navigator.clipboard.writeText(c).catch(()=>{}),h.emailSent?j.success(`Invite email sent to ${s.email}`):j.warning("Invite link copied — email could not be sent. Check your SMTP settings.")}catch{j.error("Failed to create invite link")}}function M(s){b(s),s||(f(""),L())}async function Q(s,a){await fetch(`/api/v1/team/members/${s}`,{method:"PATCH",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({role:a})}),m()}async function B(s){const c=(await(await fetch(`/api/v1/team/members/${s}/send-reset`,{method:"POST",credentials:"include"})).json()).emailSent?"Sent":"No SMTP";p(x=>({...x,[s]:c})),setTimeout(()=>p(x=>{const C={...x};return delete C[s],C}),3e3)}async function F(s){await fetch(`/api/v1/team/members/${s}`,{method:"DELETE",credentials:"include"}),d(null),m()}return e.jsxs("div",{className:"flex flex-col gap-6 max-w-[900px] mx-auto w-full p-6",children:[e.jsx(ie,{open:o!==null,onOpenChange:s=>{s||d(null)},children:e.jsxs(te,{children:[e.jsxs(le,{children:[e.jsx(re,{children:"Remove this member?"}),e.jsx(ce,{children:"This member will lose access to the team immediately."})]}),e.jsxs(oe,{children:[e.jsx(de,{children:"Cancel"}),e.jsx(me,{className:"bg-destructive/10 text-destructive hover:bg-destructive/20 border-0",onClick:()=>o!==null&&F(o),children:"Remove"})]})]})}),e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h1",{className:"text-xl font-semibold",children:"Team"}),e.jsxs(Y,{open:O,onOpenChange:M,children:[e.jsx(ee,{asChild:!0,children:e.jsxs(t,{size:"sm",children:[e.jsx(ue,{className:"mr-2 h-4 w-4"}),"Invite member"]})}),e.jsxs(se,{className:"sm:max-w-md",children:[e.jsx(ae,{children:e.jsx(ne,{children:"Invite team member"})}),g?e.jsxs("div",{className:"flex flex-col gap-3 pt-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Invite link copied to clipboard:"}),e.jsx("code",{className:"rounded bg-muted px-3 py-2 text-xs break-all",children:g}),e.jsx(t,{onClick:()=>b(!1),children:"Done"})]}):e.jsxs("form",{onSubmit:V($),className:"flex flex-col gap-4 pt-2",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(D,{htmlFor:"invite-email",children:"Email"}),e.jsx(U,{id:"invite-email",type:"email",...P("email")}),S.email&&e.jsx("p",{className:"text-sm text-destructive",children:S.email.message})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(D,{children:"Role"}),e.jsx(_,{name:"role",control:H,render:({field:s})=>e.jsxs(k,{value:s.value,onValueChange:s.onChange,children:[e.jsx(w,{children:e.jsx(N,{})}),e.jsxs(T,{children:[e.jsx(n,{value:"Admin",children:"Admin"}),e.jsx(n,{value:"Developer",children:"Developer"}),e.jsx(n,{value:"QA",children:"QA"}),e.jsx(n,{value:"Viewer",children:"Viewer"})]})]})})]}),e.jsx(t,{type:"submit",disabled:y,children:y?"Creating link…":"Generate invite link"})]})]})]})]}),e.jsxs(q,{children:[e.jsx(Z,{children:e.jsxs(K,{children:["Members (",v.length,")"]})}),e.jsx(W,{className:"px-4 pt-0 pb-2",children:e.jsxs(he,{children:[e.jsx(xe,{children:e.jsxs(A,{children:[e.jsx(l,{children:"Nickname"}),e.jsx(l,{children:"Email"}),e.jsx(l,{children:"Role"}),e.jsx(l,{children:"Joined"}),e.jsx(l,{className:"w-10"})]})}),e.jsx(je,{children:v.map(s=>e.jsxs(A,{className:"hover:bg-transparent",children:[e.jsx(r,{className:"font-medium",children:s.display_name||"—"}),e.jsx(r,{className:"text-muted-foreground text-sm",children:s.email}),e.jsx(r,{children:e.jsxs(k,{value:s.role,onValueChange:a=>Q(s.id,a),children:[e.jsx(w,{className:"h-7 w-28",children:e.jsx(N,{})}),e.jsxs(T,{children:[e.jsx(n,{value:"Admin",children:"Admin"}),e.jsx(n,{value:"Developer",children:"Developer"}),e.jsx(n,{value:"QA",children:"QA"}),e.jsx(n,{value:"Viewer",children:"Viewer"})]})]})}),e.jsx(r,{className:"text-muted-foreground text-sm",children:new Date(s.joined_at).toLocaleDateString()}),e.jsx(r,{children:e.jsxs("div",{className:"flex items-center gap-2",children:[e.jsx(t,{variant:"secondary",size:"nav",onClick:()=>B(s.id),children:E[s.id]??"Reset pwd"}),e.jsx(t,{variant:"destructive",size:"nav",onClick:()=>d(s.id),children:"Remove"})]})})]},s.id))})]})})]})]})}export{ye as TeamSettings};
Binary file
@@ -1,6 +0,0 @@
1
- import{Z as $,a9 as n,ak as H,ac as M,a6 as e,B as d,ab as a,L as k,I as S,C as O,d as V,e as z,c as W,b as J,a7 as U,aa as A}from"./index-ClAB0eKw.js";import{B as I}from"./badge-Cktrrdvf.js";import{A as Z,c as q,f as G,g as K,d as Q,e as X,b as Y}from"./alert-dialog-Ci_cWoVo.js";import{D as ee,f as se,a as ae,d as te,e as ne,S as re,i as oe,j as ie,g as le,h as B}from"./dialog-BuZjQWBQ.js";import{T as ce,d as de,e as y,c as x,a as xe,b as i}from"./table-NBRnBazr.js";import{P as he}from"./plus-C0Y4Yk9P.js";/**
2
- * @license lucide-react v0.468.0 - ISC
3
- *
4
- * This source code is licensed under the ISC license.
5
- * See the LICENSE file in the root directory of this source tree.
6
- */const me=$("Trash2",[["path",{d:"M3 6h18",key:"d0wm0j"}],["path",{d:"M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6",key:"4alrt4"}],["path",{d:"M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2",key:"v07s0e"}],["line",{x1:"10",x2:"10",y1:"11",y2:"17",key:"1uufr5"}],["line",{x1:"14",x2:"14",y1:"11",y2:"17",key:"xtxkd"}]]);async function pe(){const t=window.location.protocol==="https:"?"wss":"ws";if(["localhost","127.0.0.1","[::1]"].includes(window.location.hostname))try{const h=await fetch("/api/v1/relay/host",{credentials:"include"});if(h.ok){const{lanHost:l,port:o}=await h.json();if(l)return`${t}://${l}:${o}`}}catch{}return`${t}://${window.location.host}`}const ue=U({name:A().min(1),expiresDays:A().refine(t=>{const r=parseInt(t,10);return!isNaN(r)&&r>=1&&r<=365},{message:"Must be between 1 and 365"})});function ve(){const[t,r]=n.useState([]),[h,l]=n.useState(!1),[o,w]=n.useState(""),[c,v]=n.useState("api"),[N,b]=n.useState(""),[u,j]=n.useState(null),{register:T,handleSubmit:E,reset:_,formState:{errors:m,isSubmitting:C}}=H({resolver:M(ue),mode:"onBlur",defaultValues:{name:"",expiresDays:"30"}});function g(){fetch("/api/v1/tokens",{credentials:"include"}).then(s=>s.json()).then(r)}n.useEffect(()=>{g()},[]);async function L(s){try{const p=await fetch("/api/v1/tokens",{method:"POST",credentials:"include",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:s.name,expires_in_days:parseInt(s.expiresDays,10),...c==="agent"?{scope:"agent"}:{}})});if(!p.ok){const f=await p.json().catch(()=>null);a.error((f==null?void 0:f.error)??"Failed to create token");return}const P=await p.json();c==="agent"&&b(await pe()),a.success("Token created"),w(P.token),g()}catch{a.error("Network error")}}function R(s){l(s),s||(w(""),v("api"),b(""),_())}async function F(s){try{return(await fetch(`/api/v1/tokens/${s}`,{method:"DELETE",credentials:"include"})).ok?(a.success("Token revoked"),g(),!0):(a.error("Failed to revoke token"),!1)}catch{return a.error("Network error"),!1}}function D(s){return s.expires_at&&new Date(s.expires_at)<new Date}return e.jsxs("div",{className:"flex flex-col gap-6 max-w-[900px] mx-auto w-full p-6",children:[e.jsxs("div",{className:"flex items-center justify-between",children:[e.jsx("h1",{className:"text-xl font-semibold",children:"Personal Access Tokens"}),e.jsxs(ee,{open:h,onOpenChange:R,children:[e.jsx(se,{asChild:!0,children:e.jsxs(d,{size:"sm",children:[e.jsx(he,{className:"mr-2 h-4 w-4"}),"New token"]})}),e.jsxs(ae,{className:"sm:max-w-md",children:[e.jsx(te,{children:e.jsx(ne,{children:"Create token"})}),o?e.jsxs("div",{className:"flex flex-col gap-3 pt-2",children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Copy this token now — it won't be shown again."}),e.jsx("code",{className:"rounded bg-muted px-3 py-2 text-xs break-all font-mono",children:o}),c==="agent"&&N&&e.jsxs(e.Fragment,{children:[e.jsx("p",{className:"text-sm text-muted-foreground",children:"Run this on the agent Mac to connect it to this relay:"}),e.jsx("code",{className:"rounded bg-muted px-3 py-2 text-xs break-all font-mono",children:`tapflow agent start --relay ${N} --token ${o}`})]}),e.jsx(d,{onClick:()=>{navigator.clipboard.writeText(o).then(()=>{a.success("Token copied to clipboard"),l(!1)}).catch(()=>a.error("Failed to copy — copy manually"))},children:"Copy & close"})]}):e.jsxs("form",{onSubmit:E(L),className:"flex flex-col gap-4 pt-2",children:[e.jsxs("div",{className:"grid gap-2",children:[e.jsx(k,{htmlFor:"token-name",children:"Name"}),e.jsx(S,{id:"token-name",placeholder:"e.g. ci-deploy",...T("name")}),m.name&&e.jsx("p",{className:"text-sm text-destructive",children:m.name.message})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(k,{htmlFor:"expires",children:"Expires in (days)"}),e.jsx(S,{id:"expires",type:"number",...T("expiresDays")}),m.expiresDays&&e.jsx("p",{className:"text-sm text-destructive",children:m.expiresDays.message})]}),e.jsxs("div",{className:"grid gap-2",children:[e.jsx(k,{children:"Type"}),e.jsxs(re,{value:c,onValueChange:s=>v(s),children:[e.jsx(oe,{children:e.jsx(ie,{})}),e.jsxs(le,{children:[e.jsx(B,{value:"api",children:"API — CI uploads & API access"}),e.jsx(B,{value:"agent",children:"Agent — connect remote device agents (Admin only)"})]})]})]}),e.jsxs("p",{className:"text-xs text-muted-foreground",children:["Scope: ",e.jsx(I,{variant:"secondary",children:c==="agent"?"agent":"view, builds:write"})]}),e.jsx(d,{type:"submit",disabled:C,children:C?"Creating…":"Create token"})]})]})]})]}),e.jsxs(O,{children:[e.jsxs(V,{children:[e.jsx(z,{children:"Active tokens"}),e.jsxs(W,{children:["Use these tokens with ",e.jsx("code",{className:"text-xs",children:"Authorization: Bearer <token>"})," for API deployments."]})]}),e.jsx(J,{className:"px-4 pt-0 pb-2",children:e.jsxs(ce,{children:[e.jsx(de,{children:e.jsxs(y,{children:[e.jsx(x,{children:"Name"}),e.jsx(x,{children:"Scope"}),e.jsx(x,{children:"Last used"}),e.jsx(x,{children:"Expires"}),e.jsx(x,{className:"w-10"})]})}),e.jsx(xe,{children:t.length===0?e.jsx(y,{children:e.jsx(i,{colSpan:5,className:"h-20 text-center text-muted-foreground",children:"No tokens yet."})}):t.map(s=>e.jsxs(y,{className:"hover:bg-transparent",children:[e.jsx(i,{className:"font-medium",children:s.name}),e.jsx(i,{children:e.jsx(I,{variant:"secondary",children:s.scope})}),e.jsx(i,{className:"text-muted-foreground text-sm",children:s.last_used_at?new Date(s.last_used_at).toLocaleDateString():"Never"}),e.jsx(i,{children:s.expires_at?e.jsx("span",{className:D(s)?"text-destructive text-sm":"text-muted-foreground text-sm",children:D(s)?"Expired":new Date(s.expires_at).toLocaleDateString()}):e.jsx("span",{className:"text-muted-foreground text-sm",children:"Never"})}),e.jsx(i,{children:e.jsx(d,{variant:"destructive",size:"icon",className:"h-7 w-7","aria-label":"Revoke token",onClick:()=>j(s.id),children:e.jsx(me,{className:"h-4 w-4"})})})]},s.id))})]})})]}),e.jsx(Z,{open:u!==null,onOpenChange:s=>{s||j(null)},children:e.jsxs(q,{children:[e.jsxs(G,{children:[e.jsx(K,{children:"Revoke token?"}),e.jsx(Q,{children:"Any active API calls using this token will immediately fail."})]}),e.jsxs(X,{children:[e.jsx(Y,{children:"Cancel"}),e.jsx(d,{variant:"destructive",onClick:async()=>{if(u===null)return;await F(u)&&j(null)},children:"Revoke"})]})]})})]})}export{ve as TokenSettings};
Binary file
@@ -1,7 +0,0 @@
1
- import{a6 as o,s as L,a9 as s,z as G,Y as u,o as W,ag as A,W as Y,j as k,K as V,T as q,D as B,h as D,O as J,a2 as K,Q,J as n,H as v}from"./index-ClAB0eKw.js";var x="AlertDialog",[U]=Q(x,[u]),i=u(),N=e=>{const{__scopeAlertDialog:a,...t}=e,r=i(a);return o.jsx(L,{...r,...t,modal:!0})};N.displayName=x;var X="AlertDialogTrigger",y=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,l=i(t);return o.jsx(G,{...l,...r,ref:a})});y.displayName=X;var Z="AlertDialogPortal",R=e=>{const{__scopeAlertDialog:a,...t}=e,r=i(a);return o.jsx(W,{...r,...t})};R.displayName=Z;var ee="AlertDialogOverlay",_=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,l=i(t);return o.jsx(J,{...l,...r,ref:a})});_.displayName=ee;var c="AlertDialogContent",[ae,te]=U(c),oe=K("AlertDialogContent"),j=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,children:r,...l}=e,g=i(t),p=s.useRef(null),H=A(a,p),f=s.useRef(null);return o.jsx(Y,{contentName:c,titleName:h,docsSlug:"alert-dialog",children:o.jsx(ae,{scope:t,cancelRef:f,children:o.jsxs(k,{role:"alertdialog",...g,...l,ref:H,onOpenAutoFocus:V(l.onOpenAutoFocus,d=>{var m;d.preventDefault(),(m=f.current)==null||m.focus({preventScroll:!0})}),onPointerDownOutside:d=>d.preventDefault(),onInteractOutside:d=>d.preventDefault(),children:[o.jsx(oe,{children:r}),o.jsx(se,{contentRef:p})]})})})});j.displayName=c;var h="AlertDialogTitle",b=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,l=i(t);return o.jsx(q,{...l,...r,ref:a})});b.displayName=h;var w="AlertDialogDescription",C=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,l=i(t);return o.jsx(B,{...l,...r,ref:a})});C.displayName=w;var re="AlertDialogAction",E=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,l=i(t);return o.jsx(D,{...l,...r,ref:a})});E.displayName=re;var T="AlertDialogCancel",P=s.forwardRef((e,a)=>{const{__scopeAlertDialog:t,...r}=e,{cancelRef:l}=te(T,t),g=i(t),p=A(a,l);return o.jsx(D,{...g,...r,ref:p})});P.displayName=T;var se=({contentRef:e})=>{const a=`\`${c}\` requires a description for the component to be accessible for screen reader users.
2
-
3
- You can add a description to the \`${c}\` by passing a \`${w}\` component as a child, which also benefits sighted users by adding visible context to the dialog.
4
-
5
- Alternatively, you can use your own component as a description by assigning it an \`id\` and passing the same value to the \`aria-describedby\` prop in \`${c}\`. If the description is confusing or duplicative for sighted users, you can use the \`@radix-ui/react-visually-hidden\` primitive as a wrapper around your description component.
6
-
7
- For more information, see https://radix-ui.com/primitives/docs/components/alert-dialog`;return s.useEffect(()=>{var r;document.getElementById((r=e.current)==null?void 0:r.getAttribute("aria-describedby"))||console.warn(a)},[a,e]),null},le=N,ie=y,ne=R,S=_,O=j,$=E,M=P,I=b,z=C;const ve=le,xe=ie,ce=ne,F=s.forwardRef(({className:e,...a},t)=>o.jsx(S,{className:n("fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",e),...a,ref:t}));F.displayName=S.displayName;const de=s.forwardRef(({className:e,...a},t)=>o.jsxs(ce,{children:[o.jsx(F,{}),o.jsx(O,{ref:t,className:n("fixed left-[50%] top-[50%] z-50 grid w-full max-w-lg translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",e),...a})]}));de.displayName=O.displayName;const pe=({className:e,...a})=>o.jsx("div",{className:n("flex flex-col space-y-2 text-center sm:text-left",e),...a});pe.displayName="AlertDialogHeader";const ge=({className:e,...a})=>o.jsx("div",{className:n("flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",e),...a});ge.displayName="AlertDialogFooter";const fe=s.forwardRef(({className:e,...a},t)=>o.jsx(I,{ref:t,className:n("text-lg font-semibold",e),...a}));fe.displayName=I.displayName;const me=s.forwardRef(({className:e,...a},t)=>o.jsx(z,{ref:t,className:n("text-sm text-muted-foreground",e),...a}));me.displayName=z.displayName;const ue=s.forwardRef(({className:e,...a},t)=>o.jsx($,{ref:t,className:n(v(),e),...a}));ue.displayName=$.displayName;const Ae=s.forwardRef(({className:e,...a},t)=>o.jsx(M,{ref:t,className:n(v({variant:"outline"}),"mt-2 sm:mt-0",e),...a}));Ae.displayName=M.displayName;export{ve as A,ue as a,Ae as b,de as c,me as d,ge as e,pe as f,fe as g,xe as h};
Binary file