@epic-web/workshop-app 4.28.0 → 4.28.2

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 (90) hide show
  1. package/build/client/assets/{_-C82olNpL.js → _-D0Tgngwe.js} +2 -2
  2. package/build/client/assets/{_-C82olNpL.js.map → _-D0Tgngwe.js.map} +1 -1
  3. package/build/client/assets/{_exerciseNumber-DeMmiDU5.js → _exerciseNumber-DE_0qQH_.js} +2 -2
  4. package/build/client/assets/{_exerciseNumber-DeMmiDU5.js.map → _exerciseNumber-DE_0qQH_.js.map} +1 -1
  5. package/build/client/assets/{_exerciseNumber_._stepNumber-qCtEMlS2.js → _exerciseNumber_._stepNumber-7kSd_6hH.js} +2 -2
  6. package/build/client/assets/{_exerciseNumber_._stepNumber-qCtEMlS2.js.map → _exerciseNumber_._stepNumber-7kSd_6hH.js.map} +1 -1
  7. package/build/client/assets/{_exerciseNumber_.finished-DM5HZX6r.js → _exerciseNumber_.finished-CXSyM9gG.js} +2 -2
  8. package/build/client/assets/{_exerciseNumber_.finished-DM5HZX6r.js.map → _exerciseNumber_.finished-CXSyM9gG.js.map} +1 -1
  9. package/build/client/assets/_layout-BPwIOXxN.js +6 -0
  10. package/build/client/assets/_layout-BPwIOXxN.js.map +1 -0
  11. package/build/client/assets/{_layout-DATuycts.js → _layout-BwzhY4NI.js} +2 -2
  12. package/build/client/assets/{_layout-DATuycts.js.map → _layout-BwzhY4NI.js.map} +1 -1
  13. package/build/client/assets/{_layout-5idP3Bqx.js → _layout-CX6Ujslq.js} +2 -2
  14. package/build/client/assets/{_layout-5idP3Bqx.js.map → _layout-CX6Ujslq.js.map} +1 -1
  15. package/build/client/assets/{accordion-CKwXYK9L.js → accordion-OfO-5m5D.js} +2 -2
  16. package/build/client/assets/{accordion-CKwXYK9L.js.map → accordion-OfO-5m5D.js.map} +1 -1
  17. package/build/client/assets/{account-D1DCJCnR.js → account-BatJhmSV.js} +2 -2
  18. package/build/client/assets/{account-D1DCJCnR.js.map → account-BatJhmSV.js.map} +1 -1
  19. package/build/client/assets/app-88P7VaQm.js +2 -0
  20. package/build/client/assets/{app-C-oFaj2l.js.map → app-88P7VaQm.js.map} +1 -1
  21. package/build/client/assets/{button-CQ6cnotS.js → button-EE0aPg10.js} +2 -2
  22. package/build/client/assets/{button-CQ6cnotS.js.map → button-EE0aPg10.js.map} +1 -1
  23. package/build/client/assets/{diff-CU8At1c4.js → diff-aBqZBC2m.js} +2 -2
  24. package/build/client/assets/{diff-CU8At1c4.js.map → diff-aBqZBC2m.js.map} +1 -1
  25. package/build/client/assets/{diff-hoOood-9.js → diff-uBbcWjMl.js} +2 -2
  26. package/build/client/assets/{diff-hoOood-9.js.map → diff-uBbcWjMl.js.map} +1 -1
  27. package/build/client/assets/{discord-CgdmSzxV.js → discord-BRTW4Rnh.js} +2 -2
  28. package/build/client/assets/{discord-CgdmSzxV.js.map → discord-BRTW4Rnh.js.map} +1 -1
  29. package/build/client/assets/discord-BhzUjmbI.js +2 -0
  30. package/build/client/assets/discord-BhzUjmbI.js.map +1 -0
  31. package/build/client/assets/{epic-video-BFcdejfC.js → epic-video-CtC1lrmt.js} +2 -2
  32. package/build/client/assets/{epic-video-BFcdejfC.js.map → epic-video-CtC1lrmt.js.map} +1 -1
  33. package/build/client/assets/{error-boundary-CqgVAFiu.js → error-boundary-COkPRBOZ.js} +2 -2
  34. package/build/client/assets/{error-boundary-CqgVAFiu.js.map → error-boundary-COkPRBOZ.js.map} +1 -1
  35. package/build/client/assets/{finished-C_v7hO19.js → finished-B3ubB4CI.js} +2 -2
  36. package/build/client/assets/{finished-C_v7hO19.js.map → finished-B3ubB4CI.js.map} +1 -1
  37. package/build/client/assets/{icons-CnZJXICl.svg → icons-BtWYk6Ws.svg} +17 -0
  38. package/build/client/assets/{index-9dWszLxO.js → index-BwhlO_gF.js} +2 -2
  39. package/build/client/assets/{index-9dWszLxO.js.map → index-BwhlO_gF.js.map} +1 -1
  40. package/build/client/assets/{index-j_VpxCZh.js → index-CXyf3Reb.js} +2 -2
  41. package/build/client/assets/{index-j_VpxCZh.js.map → index-CXyf3Reb.js.map} +1 -1
  42. package/build/client/assets/{index-CsPok4Mn.js → index-RXedS5cU.js} +2 -2
  43. package/build/client/assets/{index-CsPok4Mn.js.map → index-RXedS5cU.js.map} +1 -1
  44. package/build/client/assets/{index-DlJAkutV.js → index-YNIH4TH8.js} +2 -2
  45. package/build/client/assets/{index-DlJAkutV.js.map → index-YNIH4TH8.js.map} +1 -1
  46. package/build/client/assets/{index-BHeB-0xq.js → index-ZRjyMQjt.js} +2 -2
  47. package/build/client/assets/{index-BHeB-0xq.js.map → index-ZRjyMQjt.js.map} +1 -1
  48. package/build/client/assets/{loading-CF7oQHQf.js → loading-DizTwLux.js} +2 -2
  49. package/build/client/assets/{loading-CF7oQHQf.js.map → loading-DizTwLux.js.map} +1 -1
  50. package/build/client/assets/{login-Ca9EDpZj.js → login-CbBI7xkR.js} +2 -2
  51. package/build/client/assets/{login-Ca9EDpZj.js.map → login-CbBI7xkR.js.map} +1 -1
  52. package/build/client/assets/{manifest-ade0c8c3.js → manifest-d831df81.js} +1 -1
  53. package/build/client/assets/{mdx-DvqHp8UI.js → mdx-C-xljcvl.js} +2 -2
  54. package/build/client/assets/{mdx-DvqHp8UI.js.map → mdx-C-xljcvl.js.map} +1 -1
  55. package/build/client/assets/{misc-Txs7O6JX.js → misc-CxCgA-_O.js} +2 -2
  56. package/build/client/assets/{misc-Txs7O6JX.js.map → misc-CxCgA-_O.js.map} +1 -1
  57. package/build/client/assets/{nav-chevrons-Cbc1bd_j.js → nav-chevrons-g-C0ilNz.js} +2 -2
  58. package/build/client/assets/{nav-chevrons-Cbc1bd_j.js.map → nav-chevrons-g-C0ilNz.js.map} +1 -1
  59. package/build/client/assets/{onboarding-Dc2TmI9y.js → onboarding-BIVf8oVW.js} +2 -2
  60. package/build/client/assets/onboarding-BIVf8oVW.js.map +1 -0
  61. package/build/client/assets/preview-DYe41EMN.js +2 -0
  62. package/build/client/assets/preview-DYe41EMN.js.map +1 -0
  63. package/build/client/assets/{product-f8Gd2MQ6.js → product-BAWG1Vut.js} +2 -2
  64. package/build/client/assets/{product-f8Gd2MQ6.js.map → product-BAWG1Vut.js.map} +1 -1
  65. package/build/client/assets/{progress-C7kc6YXZ.js → progress-BFm2U-l5.js} +2 -2
  66. package/build/client/assets/{progress-C7kc6YXZ.js.map → progress-BFm2U-l5.js.map} +1 -1
  67. package/build/client/assets/{progress-bar-bUuKn1Q8.js → progress-bar-D3kudPcr.js} +2 -2
  68. package/build/client/assets/{progress-bar-bUuKn1Q8.js.map → progress-bar-D3kudPcr.js.map} +1 -1
  69. package/build/client/assets/{root-CbC_P7jJ.js → root-Wg6CLPzr.js} +2 -2
  70. package/build/client/assets/{root-CbC_P7jJ.js.map → root-Wg6CLPzr.js.map} +1 -1
  71. package/build/client/assets/{set-playground-Cr0qL9N9.js → set-playground-DW0yVaNn.js} +2 -2
  72. package/build/client/assets/{set-playground-Cr0qL9N9.js.map → set-playground-DW0yVaNn.js.map} +1 -1
  73. package/build/client/assets/test-CSKfnJmn.js +2 -0
  74. package/build/client/assets/{test-Cy-fo6gv.js.map → test-CSKfnJmn.js.map} +1 -1
  75. package/build/client/assets/{tests-DmimqC1q.js → tests-AGbZcka3.js} +2 -2
  76. package/build/client/assets/{tests-DmimqC1q.js.map → tests-AGbZcka3.js.map} +1 -1
  77. package/build/client/assets/{tooltip-DTFU8ajx.js → tooltip-kD4kSf1i.js} +2 -2
  78. package/build/client/assets/{tooltip-DTFU8ajx.js.map → tooltip-kD4kSf1i.js.map} +1 -1
  79. package/build/server/index.js +249 -200
  80. package/build/server/index.js.map +1 -1
  81. package/package.json +3 -3
  82. package/build/client/assets/_layout-DkGEbcMk.js +0 -6
  83. package/build/client/assets/_layout-DkGEbcMk.js.map +0 -1
  84. package/build/client/assets/app-C-oFaj2l.js +0 -2
  85. package/build/client/assets/discord-BBRM_H3g.js +0 -2
  86. package/build/client/assets/discord-BBRM_H3g.js.map +0 -1
  87. package/build/client/assets/onboarding-Dc2TmI9y.js.map +0 -1
  88. package/build/client/assets/preview-WJ-QYhx8.js +0 -2
  89. package/build/client/assets/preview-WJ-QYhx8.js.map +0 -1
  90. package/build/client/assets/test-Cy-fo6gv.js +0 -2
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epic-web/workshop-app",
3
- "version": "4.28.0",
3
+ "version": "4.28.2",
4
4
  "sideEffects": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -44,8 +44,8 @@
44
44
  "@epic-web/invariant": "^1.0.0",
45
45
  "@epic-web/remember": "^1.0.2",
46
46
  "@epic-web/restore-scroll": "^1.1.1",
47
- "@epic-web/workshop-presence": "4.28.0",
48
- "@epic-web/workshop-utils": "4.28.0",
47
+ "@epic-web/workshop-presence": "4.28.2",
48
+ "@epic-web/workshop-utils": "4.28.2",
49
49
  "@mdx-js/mdx": "^3.0.1",
50
50
  "@mux/mux-player-react": "^2.6.0",
51
51
  "@nasa-gcn/remix-seo": "^2.0.1",
@@ -1,6 +0,0 @@
1
- import{r as u,j as e,O as We,b as se}from"./index-1cKOJFpX.js";import{a as m,I as N,c as v}from"./misc-Txs7O6JX.js";import{a as Ve}from"./pe-CUZaIcdt.js";import{L as O}from"./product-f8Gd2MQ6.js";import{d as He,h as U,P as I,f as k,g as Y,k as ze,D as Ue,n as Ye,u as Be,e as W,S as $,T as Ge,a as q,b as Z,c as X}from"./tooltip-DTFU8ajx.js";import{R as Me,h as Qe,u as Je,F as Ke,P as qe}from"./index-j_VpxCZh.js";import{c as L}from"./user-DvujSs-t.js";import{u as ae}from"./workshop-config-CL4F08kr.js";import{a as B}from"./presence-Cr--lRCr.js";import{b as Ze,s as re,c as Xe,d as et,e as oe,m as p,u as tt,f as nt}from"./progress-C7kc6YXZ.js";import{T as le}from"./index-DlJAkutV.js";import{L as h,u as ie,N as S}from"./components-CME-nGId.js";import"./request-info-CEhUGODY.js";function st(t){t.values.forEach(n=>n.stop())}function H(t,n){[...n].reverse().forEach(a=>{const o=t.getVariant(a);o&&re(t,o),t.variantChildren&&t.variantChildren.forEach(r=>{H(r,n)})})}function at(t,n){if(Array.isArray(n))return H(t,n);if(typeof n=="string")return H(t,[n]);re(t,n)}function rt(){const t=new Set,n={subscribe(s){return t.add(s),()=>void t.delete(s)},start(s,a){const o=[];return t.forEach(r=>{o.push(Ze(r,s,{transitionOverride:a}))}),Promise.all(o)},set(s){return t.forEach(a=>{at(a,s)})},stop(){t.forEach(s=>{st(s)})},mount(){return()=>{n.stop()}}};return n}function z(){const t=Xe(rt);return et(t.mount,[]),t}function ot(t,n){function s(){return window.matchMedia(t).matches}function a(o){const r=window.matchMedia(t);return r.addEventListener("change",o),()=>{r.removeEventListener("change",o)}}return function(){return u.useSyncExternalStore(a,s,()=>n)}}var G="Dialog",[ce,Vt]=He(G),[lt,j]=ce(G),de=t=>{const{__scopeDialog:n,children:s,open:a,defaultOpen:o,onOpenChange:r,modal:c=!0}=t,l=u.useRef(null),i=u.useRef(null),[f=!1,g]=Be({prop:a,defaultProp:o,onChange:r});return e.jsx(lt,{scope:n,triggerRef:l,contentRef:i,contentId:W(),titleId:W(),descriptionId:W(),open:f,onOpenChange:g,onOpenToggle:u.useCallback(()=>g(b=>!b),[g]),modal:c,children:s})};de.displayName=G;var ue="DialogTrigger",fe=u.forwardRef((t,n)=>{const{__scopeDialog:s,...a}=t,o=j(ue,s),r=U(n,o.triggerRef);return e.jsx(I.button,{type:"button","aria-haspopup":"dialog","aria-expanded":o.open,"aria-controls":o.contentId,"data-state":J(o.open),...a,ref:r,onClick:k(t.onClick,o.onOpenToggle)})});fe.displayName=ue;var M="DialogPortal",[it,he]=ce(M,{forceMount:void 0}),me=t=>{const{__scopeDialog:n,forceMount:s,children:a,container:o}=t,r=j(M,n);return e.jsx(it,{scope:n,forceMount:s,children:u.Children.map(a,c=>e.jsx(Y,{present:s||r.open,children:e.jsx(qe,{asChild:!0,container:o,children:c})}))})};me.displayName=M;var T="DialogOverlay",xe=u.forwardRef((t,n)=>{const s=he(T,t.__scopeDialog),{forceMount:a=s.forceMount,...o}=t,r=j(T,t.__scopeDialog);return r.modal?e.jsx(Y,{present:a||r.open,children:e.jsx(ct,{...o,ref:n})}):null});xe.displayName=T;var ct=u.forwardRef((t,n)=>{const{__scopeDialog:s,...a}=t,o=j(T,s);return e.jsx(Me,{as:ze,allowPinchZoom:!0,shards:[o.contentRef],children:e.jsx(I.div,{"data-state":J(o.open),...a,ref:n,style:{pointerEvents:"auto",...a.style}})})}),D="DialogContent",pe=u.forwardRef((t,n)=>{const s=he(D,t.__scopeDialog),{forceMount:a=s.forceMount,...o}=t,r=j(D,t.__scopeDialog);return e.jsx(Y,{present:a||r.open,children:r.modal?e.jsx(dt,{...o,ref:n}):e.jsx(ut,{...o,ref:n})})});pe.displayName=D;var dt=u.forwardRef((t,n)=>{const s=j(D,t.__scopeDialog),a=u.useRef(null),o=U(n,s.contentRef,a);return u.useEffect(()=>{const r=a.current;if(r)return Qe(r)},[]),e.jsx(ge,{...t,ref:o,trapFocus:s.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:k(t.onCloseAutoFocus,r=>{var c;r.preventDefault(),(c=s.triggerRef.current)==null||c.focus()}),onPointerDownOutside:k(t.onPointerDownOutside,r=>{const c=r.detail.originalEvent,l=c.button===0&&c.ctrlKey===!0;(c.button===2||l)&&r.preventDefault()}),onFocusOutside:k(t.onFocusOutside,r=>r.preventDefault())})}),ut=u.forwardRef((t,n)=>{const s=j(D,t.__scopeDialog),a=u.useRef(!1),o=u.useRef(!1);return e.jsx(ge,{...t,ref:n,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:r=>{var c,l;(c=t.onCloseAutoFocus)==null||c.call(t,r),r.defaultPrevented||(a.current||(l=s.triggerRef.current)==null||l.focus(),r.preventDefault()),a.current=!1,o.current=!1},onInteractOutside:r=>{var i,f;(i=t.onInteractOutside)==null||i.call(t,r),r.defaultPrevented||(a.current=!0,r.detail.originalEvent.type==="pointerdown"&&(o.current=!0));const c=r.target;((f=s.triggerRef.current)==null?void 0:f.contains(c))&&r.preventDefault(),r.detail.originalEvent.type==="focusin"&&o.current&&r.preventDefault()}})}),ge=u.forwardRef((t,n)=>{const{__scopeDialog:s,trapFocus:a,onOpenAutoFocus:o,onCloseAutoFocus:r,...c}=t,l=j(D,s),i=u.useRef(null),f=U(n,i);return Je(),e.jsxs(e.Fragment,{children:[e.jsx(Ke,{asChild:!0,loop:!0,trapped:a,onMountAutoFocus:o,onUnmountAutoFocus:r,children:e.jsx(Ue,{role:"dialog",id:l.contentId,"aria-describedby":l.descriptionId,"aria-labelledby":l.titleId,"data-state":J(l.open),...c,ref:f,onDismiss:()=>l.onOpenChange(!1)})}),e.jsxs(e.Fragment,{children:[e.jsx(ft,{titleId:l.titleId}),e.jsx(mt,{contentRef:i,descriptionId:l.descriptionId})]})]})}),Q="DialogTitle",be=u.forwardRef((t,n)=>{const{__scopeDialog:s,...a}=t,o=j(Q,s);return e.jsx(I.h2,{id:o.titleId,...a,ref:n})});be.displayName=Q;var ve="DialogDescription",je=u.forwardRef((t,n)=>{const{__scopeDialog:s,...a}=t,o=j(ve,s);return e.jsx(I.p,{id:o.descriptionId,...a,ref:n})});je.displayName=ve;var Ne="DialogClose",we=u.forwardRef((t,n)=>{const{__scopeDialog:s,...a}=t,o=j(Ne,s);return e.jsx(I.button,{type:"button",...a,ref:n,onClick:k(t.onClick,()=>o.onOpenChange(!1))})});we.displayName=Ne;function J(t){return t?"open":"closed"}var ye="DialogTitleWarning",[Ht,De]=Ye(ye,{contentName:D,titleName:Q,docsSlug:"dialog"}),ft=({titleId:t})=>{const n=De(ye),s=`\`${n.contentName}\` requires a \`${n.titleName}\` for the component to be accessible for screen reader users.
2
-
3
- If you want to hide the \`${n.titleName}\`, you can wrap it with our VisuallyHidden component.
4
-
5
- For more information, see https://radix-ui.com/primitives/docs/components/${n.docsSlug}`;return u.useEffect(()=>{t&&(document.getElementById(t)||console.error(s))},[s,t]),null},ht="DialogDescriptionWarning",mt=({contentRef:t,descriptionId:n})=>{const a=`Warning: Missing \`Description\` or \`aria-describedby={undefined}\` for {${De(ht).contentName}}.`;return u.useEffect(()=>{var r;const o=(r=t.current)==null?void 0:r.getAttribute("aria-describedby");n&&o&&(document.getElementById(n)||console.warn(a))},[a,t,n]),null},xt=de,pt=fe,gt=me,Ce=xe,Ee=pe,bt=be,Pe=je,vt=we;const jt=xt,Nt=pt,wt=gt;function _e({className:t,ref:n,...s}){return e.jsx(Ce,{ref:n,className:m("fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",t),...s})}_e.displayName=Ce.displayName;function ke({className:t,children:n,ref:s,...a}){return e.jsxs(wt,{children:[e.jsx(_e,{}),e.jsxs(Ee,{ref:s,className:m("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 md:w-full",t),...a,children:[n,e.jsxs(vt,{className:"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none",children:[e.jsx(N,{name:"Close"}),e.jsx("span",{className:"sr-only",children:"Close"})]})]})]})}ke.displayName=Ee.displayName;function Ie({className:t,...n}){return e.jsx("div",{className:m("flex flex-col space-y-1.5 text-center sm:text-left",t),...n})}Ie.displayName="DialogHeader";bt.displayName;function Re({className:t,ref:n,...s}){return e.jsx(Pe,{ref:n,className:m("text-sm text-muted-foreground",t),...s})}Re.displayName=Pe.displayName;const ee=["opacity-70","opacity-80","opacity-90","opacity-100"],te=["shadow-[0_0_2px_0_rgba(0,0,0,0.3)]","shadow-[0_0_4px_0_rgba(0,0,0,0.3)]","shadow-[0_0_7px_0_rgba(0,0,0,0.3)]","shadow-[0_0_10px_0_rgba(0,0,0,0.3)]"];function ne(t){const n=Math.round(t*ee.length-1),s=Math.round(t*te.length-1);return m("shadow-purple-700 hover:opacity-100 focus:opacity-100 dark:shadow-purple-200",ee[n]??"opacity-60",te[s]??"shadow-none",t===1?"animate-pulse hover:animate-none focus:animate-none":null)}function $e({isMenuOpened:t}){const n=L(),{users:s}=B(),{product:{displayNameShort:a}}=ae(),o=t?17:0,r=s.length-o,c=r>(t?1:0);if(!s.length)return null;const l=t&&s.length===1?e.jsx(h,{target:"_blank",rel:"noopener noreferrer",to:"https://www.youtube.com/watch?v=w6Q3mHyzn78",children:e.jsx("img",{alt:"Tiffany Tunes",className:m("h-8 w-8 rounded-full border object-cover",ne(1)),src:"/img/tiffany.png"})}):null,i=`${r}${t?" more ":" "}${a} Dev${r===1?"":"s"} working now`;return e.jsx("div",{className:"flex flex-wrap items-center gap-2",children:e.jsxs(Ge,{children:[(c?s.slice(0,o):s).map(({user:f,score:g})=>{var d,w;const b=ne(g),x=yt(f.location);return e.jsxs(q,{children:[e.jsx(Z,{asChild:!0,children:f.avatarUrl?e.jsx("img",{tabIndex:0,alt:f.name||a,className:m("h-8 w-8 rounded-full border object-cover",b),src:f.avatarUrl}):e.jsx("div",{tabIndex:0,"aria-label":f.name||`${a} Dev`,className:m("flex h-8 w-8 items-center justify-center rounded-full border",b),children:e.jsx(N,{name:"User"})})}),e.jsx(X,{children:e.jsxs("span",{className:"flex flex-col items-center justify-center gap-1",children:[e.jsxs("span",{children:[f.name||`${a} Dev`," ",x?` is ${(w=(d=f.location)==null?void 0:d.origin)!=null&&w.includes("localhost")?"working":"learning"} ${g===1&&(n==null?void 0:n.id)!==f.id?"with you":""} on`:null]}),x!=null&&x.line1?e.jsx("span",{children:x.line1}):null,x!=null&&x.line2?e.jsx("span",{children:x.line2}):null]})})]},f.id)}),l,c?e.jsxs(q,{children:[e.jsx(Z,{asChild:!0,children:e.jsx("div",{tabIndex:0,"aria-label":i,className:m("flex items-center justify-center rounded-full border bg-accent text-xs text-accent-foreground",t?"h-8 w-8":"h-6 w-6"),children:e.jsx("span",{className:m("pointer-events-none overflow-hidden text-ellipsis whitespace-nowrap text-center",t?"w-8":"w-6"),children:t?`+${r}`:r})})}),e.jsx(X,{children:i})]}):null]})})}const Se=ot("(min-width: 640px)",!0);function zt(){const t=L(),n=Se(),s=Ve(),[a,o]=u.useState(!1);return e.jsxs("div",{className:"flex flex-col",children:[t?null:e.jsx(Dt,{}),s&&n?null:e.jsx(Ct,{isMenuOpened:a,onMenuOpenChange:o}),e.jsxs("div",{className:m("flex flex-grow flex-col sm:flex-row",{"h-[calc(100vh-128px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":!t,"h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))]":t,"h-[unset]":!n&&a}),children:[n?e.jsx(Et,{isMenuOpened:a,onMenuOpenChange:o}):null,e.jsx("div",{className:m("h-full w-full max-w-full sm:max-w-[calc(100%-56px)]",a?"hidden md:block":""),children:e.jsx(We,{})})]})]})}function yt(t){if(!t)return null;const{exercise:n}=t,s=[n?[n.exerciseNumber,n.stepNumber].filter(Boolean).map(a=>a.toString().padStart(2,"0")).join("/"):null,n==null?void 0:n.type].filter(Boolean).join(" - ");return{line1:t.workshopTitle,line2:s}}function Dt(){const t=Se(),{product:{host:n,displayName:s}}=ae(),a=e.jsx("div",{children:ENV.EPICSHOP_DEPLOYED?e.jsxs("div",{children:["This is the deployed version. ",e.jsxs(e.Fragment,{children:[e.jsx(h,{className:"underline",target:"_blank",rel:"noopener noreferrer",to:ENV.EPICSHOP_GITHUB_REPO,children:"Run locally"})," for full experience."]})," "]}):e.jsxs("div",{children:[e.jsx(h,{to:"/login",className:"underline",children:"Login"})," ","or"," ",e.jsx("a",{href:`https://${n}/login`,className:"underline",children:"join for free"})," ","for the full experience."]})});return e.jsx("div",{className:"z-10 flex h-16 items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white",children:t?e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"hidden flex-1 flex-wrap items-center gap-4 sm:flex",children:[e.jsx(O,{size:"lg",style:"monochrome"}),e.jsxs("div",{className:"flex flex-1 flex-wrap items-center",children:[e.jsxs("p",{className:"mr-2",children:["Welcome to the"," ",e.jsx(h,{to:`https://${n}`,className:"underline",target:"_blank",children:s})," ","Workshop app!"]}),a]})]}),e.jsxs("div",{className:"hidden h-full flex-col items-center sm:flex md:flex-row",children:[e.jsxs(h,{to:`https://${n}`,target:"_blank",className:"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold",children:[e.jsxs("span",{className:"drop-shadow-sm",children:["Join ",s]}),e.jsx("span",{children:"↗︎"})]}),e.jsxs(h,{to:ENV.EPICSHOP_DEPLOYED?`https://${n}/login`:"/login",className:"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30",children:[e.jsx(N,{name:"User",size:"lg"}),e.jsx("span",{className:"drop-shadow-sm",children:"Login"})]})]})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"flex flex-1 flex-wrap items-center gap-4 sm:hidden",children:[e.jsx("a",{href:`https://${n}`,children:e.jsx(O,{size:"lg",style:"monochrome"})}),e.jsxs(jt,{children:[e.jsx(Nt,{children:e.jsx(N,{name:"Question",size:"lg",className:"animate-pulse"})}),e.jsxs(ke,{children:[e.jsxs(Ie,{children:[e.jsx(O,{size:"lg",style:"monochrome"}),e.jsx("span",{className:"text-lg font-semibold",children:s})]}),e.jsxs(Re,{children:["Welcome to the"," ",e.jsx(h,{to:`https://${n}`,className:"underline",children:s})," ","Workshop app!"]}),a]})]})]}),e.jsxs("div",{className:"flex h-full items-center",children:[e.jsxs(h,{to:`https://${n}`,target:"_blank",className:"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold",children:[e.jsx("span",{className:"drop-shadow-sm",children:"Join"}),e.jsx("span",{children:"↗︎"})]}),e.jsxs(h,{to:ENV.EPICSHOP_DEPLOYED?`https://${n}/login`:"/login",className:"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30",children:[e.jsx(N,{name:"User",size:"lg"}),e.jsx("span",{className:"drop-shadow-sm",children:"Login"})]})]})]})})}const Te={hidden:{opacity:0,x:-20},visible:{opacity:1,x:0}};function Le({exerciseNumber:t,children:n}){const s=tt(t);return e.jsx(p.li,{variants:Te,className:m("py-[6px] first:pt-3 last:pb-3",s?`${s} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:n})})}function P({children:t,...n}){const s=nt(n);return e.jsx(p.li,{variants:Te,className:m("py-[6px] first:pt-3 last:pb-3",s?`${s} before:border-t`:null),children:e.jsx("span",{className:"ml-2",children:t})})}function Ct({isMenuOpened:t,onMenuOpenChange:n}){const s=ie(),a=L(),o=oe(),r=se(),{users:c}=B(),l={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}};return e.jsx("nav",{className:"flex w-full border-b sm:hidden",children:e.jsx("div",{className:"w-full",children:e.jsxs("div",{className:m("flex items-center",{"flex-col":t,"h-14":!t}),children:[e.jsx(Ae,{title:s.workshopTitle,isMenuOpened:t,setMenuOpened:n}),t&&e.jsxs(p.div,{className:"flex w-full flex-grow flex-col justify-between overflow-x-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar",initial:{opacity:0},animate:{opacity:1},children:[e.jsx(p.ul,{variants:l,initial:"hidden",animate:"visible",className:"flex flex-col",children:s.exercises.map(({exerciseNumber:i,title:f,steps:g})=>{const b=Number(r.exerciseNumber)===i,x=!b&&s.playground.exerciseNumber===i,d=i.toString().padStart(2,"0");return e.jsxs(Le,{exerciseNumber:i,children:[e.jsxs(h,{prefetch:"intent",to:`/${d}`,className:v("relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline",'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":b}),children:[f,x?" 🛝":null]}),b?e.jsxs(p.ul,{variants:l,initial:"hidden",animate:"visible",className:"ml-4 mt-4 flex flex-col",children:[e.jsx(P,{type:"instructions",exerciseNumber:i,children:e.jsx(h,{to:`/${d}`,prefetch:"intent",className:v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":!r.stepNumber}),children:"Intro"})},i),g.filter(Boolean).map(({name:w,stepNumber:C,title:E})=>{const A=Number(r.stepNumber)===C,y=C.toString().padStart(2,"0"),_=w===s.playground.appName;return e.jsx(P,{type:"step",stepNumber:C,exerciseNumber:i,children:e.jsx(h,{to:`/${d}/${y}`,prefetch:"intent",className:v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":A}),children:_?`${y}. ${E} 🛝`:`${y}. ${E}`})},C)}),e.jsx(P,{type:"finished",exerciseNumber:i,children:e.jsx(S,{to:`/${d}/finished`,prefetch:"intent",className:({isActive:w})=>v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":w}),children:"📝 Elaboration"})})]}):null]},i)})}),e.jsx("div",{className:"mt-6",children:e.jsx(S,{to:"/finished",className:({isActive:i})=>v("relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline",{'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""]':i}),children:"📝 Workshop Feedback"})})]}),e.jsx("div",{className:"flex-grow"}),e.jsx("div",{className:m("flex items-center justify-start p-4",t&&c.length>4?"min-h-14":"h-14",{"w-full border-t":t}),children:e.jsx($e,{isMenuOpened:t})}),ENV.EPICSHOP_DEPLOYED?null:a?e.jsx($,{content:t?null:"Your account",children:e.jsxs(h,{className:m("flex h-14 flex-shrink-0 items-center justify-start space-x-3 px-4 py-4 text-center no-underline hover:underline",{"border-l":!t,"w-full border-t":t}),to:"/account",children:[a.avatarUrl?e.jsx("img",{alt:a.name??a.email,src:a.avatarUrl,className:"h-full rounded-full"}):e.jsx(N,{name:"User",className:"flex-shrink-0",size:"lg"}),t?e.jsx(p.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Your Account"}):e.jsx("span",{className:"sr-only",children:"Your account"})]})}):null,ENV.EPICSHOP_DEPLOYED?null:a&&o?e.jsx($,{content:t?null:"Continue to next lesson",children:e.jsxs(h,{to:o,prefetch:"intent",className:v("flex h-14 w-full items-center space-x-3 border-l px-4 py-4 pl-[18px] no-underline hover:underline"),state:{from:"continue next lesson button"},children:[e.jsx(N,{name:"FastForward",className:"flex-shrink-0",size:"md"}),t?e.jsx(p.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Continue to next lesson"}):e.jsx("span",{className:"sr-only",children:"Continue to next lesson"})]})}):null,e.jsx("div",{className:m("flex h-14 w-14 items-center justify-center self-start p-4 sm:mb-4 sm:w-full",{"w-full border-t":t,"border-l":!t}),children:e.jsx(le,{})})]})})})}const V=400;function Et({isMenuOpened:t,onMenuOpenChange:n}){const s=ie(),a=L(),o=oe(),r=se(),{users:c}=B(),l=s.exercises.find(d=>d.exerciseNumber===Number(r.exerciseNumber)),i=r.type==="solution"?l==null?void 0:l.solutions.find(d=>d.stepNumber===Number(r.stepNumber)):r.type==="problem"?l==null?void 0:l.problems.find(d=>d.stepNumber===Number(r.stepNumber)):null,f=z(),g={close:{width:56},open:{width:V}},b={visible:{opacity:1,transition:{duration:.05,when:"beforeChildren",staggerChildren:.03}},hidden:{opacity:0}},x=Number(r.exerciseNumber).toString().padStart(2,"0");return e.jsx("nav",{className:"hidden border-r sm:flex",children:e.jsx(p.div,{initial:t?"open":"close",variants:g,animate:f,children:e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx(Ae,{title:s.workshopTitle,menuControls:f,isMenuOpened:t,setMenuOpened:n}),t&&e.jsxs(p.div,{style:{width:V},className:"flex flex-grow flex-col justify-between overflow-y-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar",initial:{opacity:0},animate:{opacity:1},children:[e.jsx(p.ul,{variants:b,initial:"hidden",animate:"visible",className:"flex flex-col",children:s.exercises.map(({exerciseNumber:d,title:w,steps:C})=>{const E=Number(r.exerciseNumber)===d,A=!E&&s.playground.exerciseNumber===d,y=d.toString().padStart(2,"0");return e.jsxs(Le,{exerciseNumber:d,children:[e.jsxs(h,{prefetch:"intent",to:`/${y}`,className:v("relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline",'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":E}),children:[w,A?" 🛝":null]}),E?e.jsxs(p.ul,{variants:b,initial:"hidden",animate:"visible",className:"ml-4 mt-4 flex flex-col",children:[e.jsx(P,{type:"instructions",exerciseNumber:d,children:e.jsx(h,{to:`/${y}`,prefetch:"intent",className:v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":!r.stepNumber}),children:"Intro"})},d),C.filter(Boolean).map(({name:_,stepNumber:R,title:K})=>{const Fe=Number(r.stepNumber)===R,F=R.toString().padStart(2,"0"),Oe=_===s.playground.appName;return e.jsx(P,{type:"step",stepNumber:R,exerciseNumber:d,children:e.jsx(h,{to:`/${y}/${F}`,prefetch:"intent",className:v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":Fe}),children:Oe?`${F}. ${K} 🛝`:`${F}. ${K}`})},R)}),e.jsx(P,{type:"finished",exerciseNumber:d,children:e.jsx(S,{to:`/${y}/finished`,prefetch:"intent",className:({isActive:_})=>v('relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""] hover:underline focus:underline',{"bg-foreground text-background":_}),children:"📝 Elaboration"})})]}):null]},d)})}),e.jsx("div",{className:"mt-6",children:e.jsx(S,{to:"/finished",className:({isActive:d})=>v("relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline",{'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[""]':d}),children:"📝 Workshop Feedback"})})]}),!t&&e.jsx("div",{className:"flex flex-grow flex-col justify-center",children:e.jsxs("div",{className:"orientation-sideways w-full font-mono text-sm font-medium uppercase leading-none",children:[l!=null&&l.title?e.jsx(h,{to:`/${x}`,children:l.title}):null,l!=null&&l.title&&(i!=null&&i.title)?" — ":null,i!=null&&i.title?e.jsx(h,{to:`/${x}/${i.stepNumber.toString().padStart(2,"0")}`,children:i.title}):null]})}),e.jsx("div",{className:m("flex w-full items-center justify-start border-t p-4 transition-[height]",t&&c.length>4?"h-28":"h-14"),style:t?{width:V}:{},children:e.jsx($e,{isMenuOpened:t})}),ENV.EPICSHOP_DEPLOYED?null:a?e.jsx($,{content:t?null:"Your account",children:e.jsxs(h,{className:"flex h-14 w-full flex-shrink-0 items-center justify-start space-x-3 border-t px-4 py-4 text-center no-underline hover:underline",to:"/account",children:[a.avatarUrl?e.jsx("img",{alt:a.name??a.email,src:a.avatarUrl,className:"h-full rounded-full"}):e.jsx(N,{name:"User",className:"flex-shrink-0",size:"lg"}),t?e.jsx(p.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Your Account"}):e.jsx("span",{className:"sr-only",children:"Your account"})]})}):null,ENV.EPICSHOP_DEPLOYED?null:a&&o?e.jsx($,{content:t?null:"Continue to next lesson",children:e.jsxs(h,{to:o,prefetch:"intent",className:v("flex h-14 w-full items-center space-x-3 border-t px-4 py-4 pl-[18px] no-underline hover:underline"),state:{from:"continue next lesson button"},children:[e.jsx(N,{name:"FastForward",className:"flex-shrink-0",size:"md"}),t?e.jsx(p.div,{className:"flex items-center whitespace-nowrap",initial:{opacity:0},animate:{opacity:1},children:"Continue to next lesson"}):e.jsx("span",{className:"sr-only",children:"Continue to next lesson"})]})}):null,e.jsx("div",{className:"mb-4 w-full self-start border-t pl-3 pt-[15px]",children:e.jsx(le,{})})]})})})}function Ae({title:t,isMenuOpened:n,setMenuOpened:s,menuControls:a}){const o=u.useRef(null),r={open:{d:"M3.06061 2.99999L21.0606 21"},closed:{d:"M0 9.5L24 9.5"}},c={open:{d:"M3.00006 21.0607L21 3.06064"},moving:{d:"M0 14.5L24 14.5"},closed:{d:"M0 14.5L15 14.5"}},l=z(),i=z();async function f(){a==null||a.start(n?"close":"open"),s(!n),n?(l.start(r.closed),await i.start(c.moving),i.start(c.closed)):(await i.start(c.moving),l.start(r.open),i.start(c.open))}return u.useEffect(()=>{if(!n)return;function g(b){var x;b.key==="Escape"&&((x=o.current)==null||x.click())}return document.addEventListener("keyup",g),()=>document.removeEventListener("keyup",g)},[n]),e.jsxs("div",{className:m("relative inline-flex h-14 flex-shrink-0 items-center justify-between overflow-hidden border-r sm:w-full sm:border-b sm:border-r-0",{"w-full":n}),children:[e.jsx("button",{ref:o,className:"flex h-14 w-14 items-center justify-center","aria-label":"Open Navigation menu",onClick:f,children:e.jsxs("svg",{width:"24",height:"24",viewBox:"0 0 24 24",children:[e.jsx(p.path,{...r.closed,animate:l,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5}),e.jsx(p.path,{...c.closed,animate:i,transition:{duration:.2},stroke:"currentColor",strokeWidth:1.5})]})}),n&&e.jsx(p.p,{transition:{delay:.2},initial:{opacity:0,y:5},animate:{opacity:1,y:0},className:"absolute right-5 whitespace-nowrap font-mono text-sm uppercase",children:e.jsx(h,{to:"/",children:t})})]})}export{zt as default};
6
- //# sourceMappingURL=_layout-DkGEbcMk.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_layout-DkGEbcMk.js","sources":["../../../../../node_modules/framer-motion/dist/es/animation/hooks/animation-controls.mjs","../../../../../node_modules/framer-motion/dist/es/animation/hooks/use-animation.mjs","../../../app/components/media-query.ts","../../../../../node_modules/@radix-ui/react-dialog/dist/index.mjs","../../../app/components/ui/dialog.tsx","../../../app/routes/_app+/_layout.tsx"],"sourcesContent":["import { invariant } from '../../utils/errors.mjs';\nimport { setTarget } from '../../render/utils/setters.mjs';\nimport { animateVisualElement } from '../interfaces/visual-element.mjs';\n\nfunction stopAnimation(visualElement) {\n visualElement.values.forEach((value) => value.stop());\n}\nfunction setVariants(visualElement, variantLabels) {\n const reversedLabels = [...variantLabels].reverse();\n reversedLabels.forEach((key) => {\n const variant = visualElement.getVariant(key);\n variant && setTarget(visualElement, variant);\n if (visualElement.variantChildren) {\n visualElement.variantChildren.forEach((child) => {\n setVariants(child, variantLabels);\n });\n }\n });\n}\nfunction setValues(visualElement, definition) {\n if (Array.isArray(definition)) {\n return setVariants(visualElement, definition);\n }\n else if (typeof definition === \"string\") {\n return setVariants(visualElement, [definition]);\n }\n else {\n setTarget(visualElement, definition);\n }\n}\n/**\n * @public\n */\nfunction animationControls() {\n /**\n * Track whether the host component has mounted.\n */\n let hasMounted = false;\n /**\n * A collection of linked component animation controls.\n */\n const subscribers = new Set();\n const controls = {\n subscribe(visualElement) {\n subscribers.add(visualElement);\n return () => void subscribers.delete(visualElement);\n },\n start(definition, transitionOverride) {\n invariant(hasMounted, \"controls.start() should only be called after a component has mounted. Consider calling within a useEffect hook.\");\n const animations = [];\n subscribers.forEach((visualElement) => {\n animations.push(animateVisualElement(visualElement, definition, {\n transitionOverride,\n }));\n });\n return Promise.all(animations);\n },\n set(definition) {\n invariant(hasMounted, \"controls.set() should only be called after a component has mounted. Consider calling within a useEffect hook.\");\n return subscribers.forEach((visualElement) => {\n setValues(visualElement, definition);\n });\n },\n stop() {\n subscribers.forEach((visualElement) => {\n stopAnimation(visualElement);\n });\n },\n mount() {\n hasMounted = true;\n return () => {\n hasMounted = false;\n controls.stop();\n };\n },\n };\n return controls;\n}\n\nexport { animationControls, setValues };\n","import { animationControls } from './animation-controls.mjs';\nimport { useConstant } from '../../utils/use-constant.mjs';\nimport { useIsomorphicLayoutEffect } from '../../utils/use-isomorphic-effect.mjs';\n\n/**\n * Creates `AnimationControls`, which can be used to manually start, stop\n * and sequence animations on one or more components.\n *\n * The returned `AnimationControls` should be passed to the `animate` property\n * of the components you want to animate.\n *\n * These components can then be animated with the `start` method.\n *\n * ```jsx\n * import * as React from 'react'\n * import { motion, useAnimation } from 'framer-motion'\n *\n * export function MyComponent(props) {\n * const controls = useAnimation()\n *\n * controls.start({\n * x: 100,\n * transition: { duration: 0.5 },\n * })\n *\n * return <motion.div animate={controls} />\n * }\n * ```\n *\n * @returns Animation controller with `start` and `stop` methods\n *\n * @public\n */\nfunction useAnimationControls() {\n const controls = useConstant(animationControls);\n useIsomorphicLayoutEffect(controls.mount, []);\n return controls;\n}\nconst useAnimation = useAnimationControls;\n\nexport { useAnimation, useAnimationControls };\n","import { useSyncExternalStore } from 'react'\n\nexport function makeMediaQueryStore(\n\tmediaQuery: string,\n\tserverSnapshot: boolean,\n) {\n\tfunction getSnapshot() {\n\t\treturn window.matchMedia(mediaQuery).matches\n\t}\n\n\tfunction subscribe(callback: () => void) {\n\t\tconst mediaQueryList = window.matchMedia(mediaQuery)\n\t\tmediaQueryList.addEventListener('change', callback)\n\t\treturn () => {\n\t\t\tmediaQueryList.removeEventListener('change', callback)\n\t\t}\n\t}\n\n\treturn function useMediaQuery() {\n\t\treturn useSyncExternalStore(subscribe, getSnapshot, () => serverSnapshot)\n\t}\n}\n","\"use client\";\n\n// packages/react/dialog/src/Dialog.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContext, createContextScope } from \"@radix-ui/react-context\";\nimport { useId } from \"@radix-ui/react-id\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { hideOthers } from \"aria-hidden\";\nimport { Slot } from \"@radix-ui/react-slot\";\nimport { Fragment, jsx, jsxs } from \"react/jsx-runtime\";\nvar DIALOG_NAME = \"Dialog\";\nvar [createDialogContext, createDialogScope] = createContextScope(DIALOG_NAME);\nvar [DialogProvider, useDialogContext] = createDialogContext(DIALOG_NAME);\nvar Dialog = (props) => {\n const {\n __scopeDialog,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = true\n } = props;\n const triggerRef = React.useRef(null);\n const contentRef = React.useRef(null);\n const [open = false, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen,\n onChange: onOpenChange\n });\n return /* @__PURE__ */ jsx(\n DialogProvider,\n {\n scope: __scopeDialog,\n triggerRef,\n contentRef,\n contentId: useId(),\n titleId: useId(),\n descriptionId: useId(),\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n modal,\n children\n }\n );\n};\nDialog.displayName = DIALOG_NAME;\nvar TRIGGER_NAME = \"DialogTrigger\";\nvar DialogTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...triggerProps } = props;\n const context = useDialogContext(TRIGGER_NAME, __scopeDialog);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n \"aria-haspopup\": \"dialog\",\n \"aria-expanded\": context.open,\n \"aria-controls\": context.contentId,\n \"data-state\": getState(context.open),\n ...triggerProps,\n ref: composedTriggerRef,\n onClick: composeEventHandlers(props.onClick, context.onOpenToggle)\n }\n );\n }\n);\nDialogTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"DialogPortal\";\nvar [PortalProvider, usePortalContext] = createDialogContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar DialogPortal = (props) => {\n const { __scopeDialog, forceMount, children, container } = props;\n const context = useDialogContext(PORTAL_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopeDialog, forceMount, children: React.Children.map(children, (child) => /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children: child }) })) });\n};\nDialogPortal.displayName = PORTAL_NAME;\nvar OVERLAY_NAME = \"DialogOverlay\";\nvar DialogOverlay = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(OVERLAY_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, props.__scopeDialog);\n return context.modal ? /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(DialogOverlayImpl, { ...overlayProps, ref: forwardedRef }) }) : null;\n }\n);\nDialogOverlay.displayName = OVERLAY_NAME;\nvar DialogOverlayImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...overlayProps } = props;\n const context = useDialogContext(OVERLAY_NAME, __scopeDialog);\n return (\n // Make sure `Content` is scrollable even when it doesn't live inside `RemoveScroll`\n // ie. when `Overlay` and `Content` are siblings\n /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, shards: [context.contentRef], children: /* @__PURE__ */ jsx(\n Primitive.div,\n {\n \"data-state\": getState(context.open),\n ...overlayProps,\n ref: forwardedRef,\n style: { pointerEvents: \"auto\", ...overlayProps.style }\n }\n ) })\n );\n }\n);\nvar CONTENT_NAME = \"DialogContent\";\nvar DialogContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopeDialog);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(DialogContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(DialogContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nDialogContent.displayName = CONTENT_NAME;\nvar DialogContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, context.contentRef, contentRef);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: true,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(props.onPointerDownOutside, (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n if (isRightClick) event.preventDefault();\n }),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault()\n )\n }\n );\n }\n);\nvar DialogContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = useDialogContext(CONTENT_NAME, props.__scopeDialog);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n DialogContentImpl,\n {\n ...props,\n ref: forwardedRef,\n trapFocus: false,\n disableOutsidePointerEvents: false,\n onCloseAutoFocus: (event) => {\n props.onCloseAutoFocus?.(event);\n if (!event.defaultPrevented) {\n if (!hasInteractedOutsideRef.current) context.triggerRef.current?.focus();\n event.preventDefault();\n }\n hasInteractedOutsideRef.current = false;\n hasPointerDownOutsideRef.current = false;\n },\n onInteractOutside: (event) => {\n props.onInteractOutside?.(event);\n if (!event.defaultPrevented) {\n hasInteractedOutsideRef.current = true;\n if (event.detail.originalEvent.type === \"pointerdown\") {\n hasPointerDownOutsideRef.current = true;\n }\n }\n const target = event.target;\n const targetIsTrigger = context.triggerRef.current?.contains(target);\n if (targetIsTrigger) event.preventDefault();\n if (event.detail.originalEvent.type === \"focusin\" && hasPointerDownOutsideRef.current) {\n event.preventDefault();\n }\n }\n }\n );\n }\n);\nvar DialogContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, trapFocus, onOpenAutoFocus, onCloseAutoFocus, ...contentProps } = props;\n const context = useDialogContext(CONTENT_NAME, __scopeDialog);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n useFocusGuards();\n return /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(\n FocusScope,\n {\n asChild: true,\n loop: true,\n trapped: trapFocus,\n onMountAutoFocus: onOpenAutoFocus,\n onUnmountAutoFocus: onCloseAutoFocus,\n children: /* @__PURE__ */ jsx(\n DismissableLayer,\n {\n role: \"dialog\",\n id: context.contentId,\n \"aria-describedby\": context.descriptionId,\n \"aria-labelledby\": context.titleId,\n \"data-state\": getState(context.open),\n ...contentProps,\n ref: composedRefs,\n onDismiss: () => context.onOpenChange(false)\n }\n )\n }\n ),\n /* @__PURE__ */ jsxs(Fragment, { children: [\n /* @__PURE__ */ jsx(TitleWarning, { titleId: context.titleId }),\n /* @__PURE__ */ jsx(DescriptionWarning, { contentRef, descriptionId: context.descriptionId })\n ] })\n ] });\n }\n);\nvar TITLE_NAME = \"DialogTitle\";\nvar DialogTitle = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...titleProps } = props;\n const context = useDialogContext(TITLE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.h2, { id: context.titleId, ...titleProps, ref: forwardedRef });\n }\n);\nDialogTitle.displayName = TITLE_NAME;\nvar DESCRIPTION_NAME = \"DialogDescription\";\nvar DialogDescription = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...descriptionProps } = props;\n const context = useDialogContext(DESCRIPTION_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(Primitive.p, { id: context.descriptionId, ...descriptionProps, ref: forwardedRef });\n }\n);\nDialogDescription.displayName = DESCRIPTION_NAME;\nvar CLOSE_NAME = \"DialogClose\";\nvar DialogClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopeDialog, ...closeProps } = props;\n const context = useDialogContext(CLOSE_NAME, __scopeDialog);\n return /* @__PURE__ */ jsx(\n Primitive.button,\n {\n type: \"button\",\n ...closeProps,\n ref: forwardedRef,\n onClick: composeEventHandlers(props.onClick, () => context.onOpenChange(false))\n }\n );\n }\n);\nDialogClose.displayName = CLOSE_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar TITLE_WARNING_NAME = \"DialogTitleWarning\";\nvar [WarningProvider, useWarningContext] = createContext(TITLE_WARNING_NAME, {\n contentName: CONTENT_NAME,\n titleName: TITLE_NAME,\n docsSlug: \"dialog\"\n});\nvar TitleWarning = ({ titleId }) => {\n const titleWarningContext = useWarningContext(TITLE_WARNING_NAME);\n const MESSAGE = `\\`${titleWarningContext.contentName}\\` requires a \\`${titleWarningContext.titleName}\\` for the component to be accessible for screen reader users.\n\nIf you want to hide the \\`${titleWarningContext.titleName}\\`, you can wrap it with our VisuallyHidden component.\n\nFor more information, see https://radix-ui.com/primitives/docs/components/${titleWarningContext.docsSlug}`;\n React.useEffect(() => {\n if (titleId) {\n const hasTitle = document.getElementById(titleId);\n if (!hasTitle) console.error(MESSAGE);\n }\n }, [MESSAGE, titleId]);\n return null;\n};\nvar DESCRIPTION_WARNING_NAME = \"DialogDescriptionWarning\";\nvar DescriptionWarning = ({ contentRef, descriptionId }) => {\n const descriptionWarningContext = useWarningContext(DESCRIPTION_WARNING_NAME);\n const MESSAGE = `Warning: Missing \\`Description\\` or \\`aria-describedby={undefined}\\` for {${descriptionWarningContext.contentName}}.`;\n React.useEffect(() => {\n const describedById = contentRef.current?.getAttribute(\"aria-describedby\");\n if (descriptionId && describedById) {\n const hasDescription = document.getElementById(descriptionId);\n if (!hasDescription) console.warn(MESSAGE);\n }\n }, [MESSAGE, contentRef, descriptionId]);\n return null;\n};\nvar Root = Dialog;\nvar Trigger = DialogTrigger;\nvar Portal = DialogPortal;\nvar Overlay = DialogOverlay;\nvar Content = DialogContent;\nvar Title = DialogTitle;\nvar Description = DialogDescription;\nvar Close = DialogClose;\nexport {\n Close,\n Content,\n Description,\n Dialog,\n DialogClose,\n DialogContent,\n DialogDescription,\n DialogOverlay,\n DialogPortal,\n DialogTitle,\n DialogTrigger,\n Overlay,\n Portal,\n Root,\n Title,\n Trigger,\n WarningProvider,\n createDialogScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as DialogPrimitive from '@radix-ui/react-dialog'\nimport * as React from 'react'\nimport { cn } from '#app/utils/misc.tsx'\nimport { Icon } from '../icons'\n\nconst Dialog = DialogPrimitive.Root\n\nconst DialogTrigger = DialogPrimitive.Trigger\n\nconst DialogPortal = DialogPrimitive.Portal\n\nconst DialogClose = DialogPrimitive.Close\n\nfunction DialogOverlay({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Overlay>) {\n\treturn (\n\t\t<DialogPrimitive.Overlay\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'fixed inset-0 z-50 bg-background/80 backdrop-blur-sm data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogOverlay.displayName = DialogPrimitive.Overlay.displayName\n\nfunction DialogContent({\n\tclassName,\n\tchildren,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Content>) {\n\treturn (\n\t\t<DialogPortal>\n\t\t\t<DialogOverlay />\n\t\t\t<DialogPrimitive.Content\n\t\t\t\tref={ref}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'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 md:w-full',\n\t\t\t\t\tclassName,\n\t\t\t\t)}\n\t\t\t\t{...props}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t\t<DialogPrimitive.Close className=\"absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity data-[state=open]:bg-accent data-[state=open]:text-muted-foreground hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none\">\n\t\t\t\t\t<Icon name=\"Close\" />\n\t\t\t\t\t<span className=\"sr-only\">Close</span>\n\t\t\t\t</DialogPrimitive.Close>\n\t\t\t</DialogPrimitive.Content>\n\t\t</DialogPortal>\n\t)\n}\nDialogContent.displayName = DialogPrimitive.Content.displayName\n\nfunction DialogHeader({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col space-y-1.5 text-center sm:text-left',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogHeader.displayName = 'DialogHeader'\n\nfunction DialogFooter({\n\tclassName,\n\t...props\n}: React.HTMLAttributes<HTMLDivElement>) {\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogFooter.displayName = 'DialogFooter'\n\nfunction DialogTitle({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Title>) {\n\treturn (\n\t\t<DialogPrimitive.Title\n\t\t\tref={ref}\n\t\t\tclassName={cn(\n\t\t\t\t'text-lg font-semibold leading-none tracking-tight',\n\t\t\t\tclassName,\n\t\t\t)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogTitle.displayName = DialogPrimitive.Title.displayName\n\nfunction DialogDescription({\n\tclassName,\n\tref,\n\t...props\n}: React.ComponentProps<typeof DialogPrimitive.Description>) {\n\treturn (\n\t\t<DialogPrimitive.Description\n\t\t\tref={ref}\n\t\t\tclassName={cn('text-sm text-muted-foreground', className)}\n\t\t\t{...props}\n\t\t/>\n\t)\n}\nDialogDescription.displayName = DialogPrimitive.Description.displayName\n\nexport {\n\tDialog,\n\tDialogClose,\n\tDialogContent,\n\tDialogDescription,\n\tDialogFooter,\n\tDialogHeader,\n\tDialogOverlay,\n\tDialogPortal,\n\tDialogTitle,\n\tDialogTrigger,\n}\n","import {\n\textractNumbersAndTypeFromAppNameOrPath,\n\tgetExercises,\n\tgetPlaygroundAppName,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport {\n\tjson,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n} from '@remix-run/node'\nimport {\n\tLink,\n\tNavLink,\n\tOutlet,\n\tuseLoaderData,\n\tuseParams,\n} from '@remix-run/react'\nimport { clsx } from 'clsx'\nimport {\n\tmotion,\n\tuseAnimationControls,\n\ttype AnimationControls,\n} from 'framer-motion'\nimport * as React from 'react'\nimport { useHydrated } from 'remix-utils/use-hydrated'\nimport { Icon } from '#app/components/icons.tsx'\nimport { makeMediaQueryStore } from '#app/components/media-query.ts'\nimport { Logo } from '#app/components/product.tsx'\nimport {\n\tDialog,\n\tDialogContent,\n\tDialogDescription,\n\tDialogHeader,\n\tDialogTrigger,\n} from '#app/components/ui/dialog.js'\nimport {\n\tSimpleTooltip,\n\tTooltip,\n\tTooltipContent,\n\tTooltipProvider,\n\tTooltipTrigger,\n} from '#app/components/ui/tooltip.tsx'\nimport { useOptionalUser } from '#app/components/user.tsx'\nimport { useWorkshopConfig } from '#app/components/workshop-config.js'\nimport { cn } from '#app/utils/misc.tsx'\nimport { usePresence, type User } from '#app/utils/presence.tsx'\nimport {\n\tuseExerciseProgressClassName,\n\tuseNextExerciseRoute,\n\tuseProgressItemClassName,\n\ttype ProgressItemSearch,\n} from '../progress.tsx'\nimport { ThemeSwitch } from '../theme/index.tsx'\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('appLayoutLoader')\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\tconst [exercises, playgroundAppName] = await Promise.all([\n\t\tgetExercises({ request, timings }),\n\t\tgetPlaygroundAppName(),\n\t])\n\n\tconst playground = {\n\t\tappName: playgroundAppName,\n\t\texerciseNumber: Number(\n\t\t\textractNumbersAndTypeFromAppNameOrPath(playgroundAppName ?? '')\n\t\t\t\t?.exerciseNumber,\n\t\t),\n\t}\n\n\tconst result = json(\n\t\t{\n\t\t\tworkshopTitle,\n\t\t\texercises: exercises.map((e) => ({\n\t\t\t\texerciseNumber: e.exerciseNumber,\n\t\t\t\ttitle: e.title,\n\t\t\t\tsolutions: e.solutions.map(({ stepNumber, title, name }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle,\n\t\t\t\t\tname,\n\t\t\t\t})),\n\t\t\t\tproblems: e.problems.map(({ stepNumber, title, name }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle,\n\t\t\t\t\tname,\n\t\t\t\t})),\n\t\t\t\tsteps: e.steps.map(({ stepNumber, problem, solution }) => ({\n\t\t\t\t\tstepNumber,\n\t\t\t\t\ttitle: problem?.title ?? solution?.title ?? 'Unknown',\n\t\t\t\t\tname: problem?.name ?? solution?.name ?? 'Unknown',\n\t\t\t\t})),\n\t\t\t})),\n\t\t\tplayground,\n\t\t},\n\t\t{\n\t\t\theaders: {\n\t\t\t\tVary: 'Cookie',\n\t\t\t\t'Server-Timing': getServerTimeHeader(timings),\n\t\t\t},\n\t\t},\n\t)\n\treturn result\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\tVary: 'Cookie',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst opacities = ['opacity-70', 'opacity-80', 'opacity-90', 'opacity-100']\nconst shadows = [\n\t'shadow-[0_0_2px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_4px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_7px_0_rgba(0,0,0,0.3)]',\n\t'shadow-[0_0_10px_0_rgba(0,0,0,0.3)]',\n]\nfunction getScoreClassNames(score: number) {\n\tconst opacityNumber = Math.round(score * opacities.length - 1)\n\tconst shadowNumber = Math.round(score * shadows.length - 1)\n\treturn cn(\n\t\t'shadow-purple-700 hover:opacity-100 focus:opacity-100 dark:shadow-purple-200',\n\t\topacities[opacityNumber] ?? 'opacity-60',\n\t\tshadows[shadowNumber] ?? 'shadow-none',\n\t\tscore === 1 ? 'animate-pulse hover:animate-none focus:animate-none' : null,\n\t)\n}\n\nfunction FacePile({ isMenuOpened }: { isMenuOpened: boolean }) {\n\tconst loggedInUser = useOptionalUser()\n\tconst { users } = usePresence()\n\tconst {\n\t\tproduct: { displayNameShort },\n\t} = useWorkshopConfig()\n\tconst limit = isMenuOpened ? 17 : 0\n\tconst numberOverLimit = users.length - limit\n\tconst shouldShowNumberOverLimit = numberOverLimit > (isMenuOpened ? 1 : 0)\n\n\tif (!users.length) return null\n\n\tconst tiffany =\n\t\tisMenuOpened && users.length === 1 ? (\n\t\t\t<Link\n\t\t\t\ttarget=\"_blank\"\n\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\tto=\"https://www.youtube.com/watch?v=w6Q3mHyzn78\"\n\t\t\t>\n\t\t\t\t<img\n\t\t\t\t\talt=\"Tiffany Tunes\"\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'h-8 w-8 rounded-full border object-cover',\n\t\t\t\t\t\tgetScoreClassNames(1),\n\t\t\t\t\t)}\n\t\t\t\t\tsrc=\"/img/tiffany.png\"\n\t\t\t\t/>\n\t\t\t</Link>\n\t\t) : null\n\tconst overLimitLabel = `${numberOverLimit}${\n\t\tisMenuOpened ? ' more ' : ' '\n\t}${displayNameShort} Dev${numberOverLimit === 1 ? '' : 's'} working now`\n\treturn (\n\t\t<div className=\"flex flex-wrap items-center gap-2\">\n\t\t\t<TooltipProvider>\n\t\t\t\t{(shouldShowNumberOverLimit ? users.slice(0, limit) : users).map(\n\t\t\t\t\t({ user, score }) => {\n\t\t\t\t\t\tconst scoreClassNames = getScoreClassNames(score)\n\t\t\t\t\t\tconst locationLabel = getLocationLabel(user.location)\n\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t<Tooltip key={user.id}>\n\t\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\t\t\t\talt={user.name || displayNameShort}\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t'h-8 w-8 rounded-full border object-cover',\n\t\t\t\t\t\t\t\t\t\t\t\tscoreClassNames,\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\t\t\t\taria-label={user.name || `${displayNameShort} Dev`}\n\t\t\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t\t\t'flex h-8 w-8 items-center justify-center rounded-full border',\n\t\t\t\t\t\t\t\t\t\t\t\tscoreClassNames,\n\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"User\" />\n\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t\t<TooltipContent>\n\t\t\t\t\t\t\t\t\t<span className=\"flex flex-col items-center justify-center gap-1\">\n\t\t\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t\t\t{user.name || `${displayNameShort} Dev`}{' '}\n\t\t\t\t\t\t\t\t\t\t\t{locationLabel\n\t\t\t\t\t\t\t\t\t\t\t\t? ` is ${user.location?.origin?.includes('localhost') ? 'working' : 'learning'} ${\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tscore === 1 && loggedInUser?.id !== user.id\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? 'with you'\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: ''\n\t\t\t\t\t\t\t\t\t\t\t\t\t} on`\n\t\t\t\t\t\t\t\t\t\t\t\t: null}\n\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t{locationLabel?.line1 ? (\n\t\t\t\t\t\t\t\t\t\t\t<span>{locationLabel.line1}</span>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t{locationLabel?.line2 ? (\n\t\t\t\t\t\t\t\t\t\t\t<span>{locationLabel.line2}</span>\n\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t</TooltipContent>\n\t\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t)\n\t\t\t\t\t},\n\t\t\t\t)}\n\t\t\t\t{tiffany}\n\t\t\t\t{shouldShowNumberOverLimit ? (\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<div\n\t\t\t\t\t\t\t\ttabIndex={0}\n\t\t\t\t\t\t\t\taria-label={overLimitLabel}\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'flex items-center justify-center rounded-full border bg-accent text-xs text-accent-foreground',\n\t\t\t\t\t\t\t\t\tisMenuOpened ? 'h-8 w-8' : 'h-6 w-6',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t\t'pointer-events-none overflow-hidden text-ellipsis whitespace-nowrap text-center',\n\t\t\t\t\t\t\t\t\t\tisMenuOpened ? 'w-8' : 'w-6',\n\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{isMenuOpened ? `+${numberOverLimit}` : numberOverLimit}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>{overLimitLabel}</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t) : null}\n\t\t\t</TooltipProvider>\n\t\t</div>\n\t)\n}\n\nconst useIsWide = makeMediaQueryStore('(min-width: 640px)', true)\n\nexport default function App() {\n\tconst user = useOptionalUser()\n\tconst isWide = useIsWide()\n\tconst isHydrated = useHydrated()\n\n\tconst [isMenuOpened, setMenuOpened] = React.useState(false)\n\n\treturn (\n\t\t<div className=\"flex flex-col\">\n\t\t\t{user ? null : <NoUserBanner />}\n\t\t\t{/*\n\t\t\t\tthis isn't placed in a conditional with isWide because the server render\n\t\t\t\tdoesn't know whether it should be around or not so we just use CSS to hide it\n\t\t\t\tif it's not supposed to show up.\n\n\t\t\t\tWe don't just use media queries for the wider screen nav because we want\n\t\t\t\tto avoid running all the logic in there unnecessarily.\n\t\t\t*/}\n\t\t\t{isHydrated && isWide ? null : (\n\t\t\t\t<MobileNavigation\n\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\tonMenuOpenChange={setMenuOpened}\n\t\t\t\t/>\n\t\t\t)}\n\t\t\t<div\n\t\t\t\t// this nonsense is here because we want the panels to be scrollable rather\n\t\t\t\t// than having the entire page be scrollable (at least on wider screens)\n\t\t\t\tclassName={cn('flex flex-grow flex-col sm:flex-row', {\n\t\t\t\t\t'h-[calc(100vh-128px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))]':\n\t\t\t\t\t\t!user,\n\t\t\t\t\t'h-[calc(100vh-64px-env(safe-area-inset-top)-env(safe-area-inset-bottom))] sm:h-[calc(100vh-env(safe-area-inset-top)-env(safe-area-inset-bottom))]':\n\t\t\t\t\t\tuser,\n\t\t\t\t\t'h-[unset]': !isWide && isMenuOpened,\n\t\t\t\t})}\n\t\t\t>\n\t\t\t\t{isWide ? (\n\t\t\t\t\t<Navigation\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tonMenuOpenChange={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t) : null}\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'h-full w-full max-w-full sm:max-w-[calc(100%-56px)]',\n\t\t\t\t\t\tisMenuOpened ? 'hidden md:block' : '',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<Outlet />\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</div>\n\t)\n}\n\nfunction getLocationLabel(location: User['location']) {\n\tif (!location) return null\n\n\tconst { exercise } = location\n\n\tconst exercisePortion = [\n\t\texercise\n\t\t\t? [exercise.exerciseNumber, exercise.stepNumber]\n\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t.map((s) => s.toString().padStart(2, '0'))\n\t\t\t\t\t.join('/')\n\t\t\t: null,\n\t\texercise?.type,\n\t]\n\t\t.filter(Boolean)\n\t\t.join(' - ')\n\treturn { line1: location.workshopTitle, line2: exercisePortion }\n}\n\nfunction NoUserBanner() {\n\tconst isWide = useIsWide()\n\tconst {\n\t\tproduct: { host, displayName },\n\t} = useWorkshopConfig()\n\tconst details = (\n\t\t<div>\n\t\t\t{ENV.EPICSHOP_DEPLOYED ? (\n\t\t\t\t<div>\n\t\t\t\t\t{`This is the deployed version. `}\n\t\t\t\t\t<>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\trel=\"noopener noreferrer\"\n\t\t\t\t\t\t\tto={ENV.EPICSHOP_GITHUB_REPO}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\tRun locally\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t{` for full experience.`}\n\t\t\t\t\t</>{' '}\n\t\t\t\t</div>\n\t\t\t) : (\n\t\t\t\t<div>\n\t\t\t\t\t<Link to=\"/login\" className=\"underline\">\n\t\t\t\t\t\tLogin\n\t\t\t\t\t</Link>{' '}\n\t\t\t\t\tor{' '}\n\t\t\t\t\t<a href={`https://${host}/login`} className=\"underline\">\n\t\t\t\t\t\tjoin for free\n\t\t\t\t\t</a>{' '}\n\t\t\t\t\tfor the full experience.\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</div>\n\t)\n\treturn (\n\t\t<div className=\"z-10 flex h-16 items-center justify-between border-b bg-gradient-to-tr from-blue-500 to-indigo-500 pl-4 text-white\">\n\t\t\t{isWide ? (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"hidden flex-1 flex-wrap items-center gap-4 sm:flex\">\n\t\t\t\t\t\t<Logo size=\"lg\" style=\"monochrome\" />\n\t\t\t\t\t\t<div className=\"flex flex-1 flex-wrap items-center\">\n\t\t\t\t\t\t\t<p className=\"mr-2\">\n\t\t\t\t\t\t\t\tWelcome to the{' '}\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={`https://${host}`}\n\t\t\t\t\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{displayName}\n\t\t\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\t\t\tWorkshop app!\n\t\t\t\t\t\t\t</p>\n\t\t\t\t\t\t\t{details}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"hidden h-full flex-col items-center sm:flex md:flex-row\">\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={`https://${host}`}\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Join {displayName}</span>\n\t\t\t\t\t\t\t<span>↗︎</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={ENV.EPICSHOP_DEPLOYED ? `https://${host}/login` : '/login'}\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon name=\"User\" size=\"lg\" />\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Login</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t) : (\n\t\t\t\t<>\n\t\t\t\t\t<div className=\"flex flex-1 flex-wrap items-center gap-4 sm:hidden\">\n\t\t\t\t\t\t<a href={`https://${host}`}>\n\t\t\t\t\t\t\t<Logo size=\"lg\" style=\"monochrome\" />\n\t\t\t\t\t\t</a>\n\t\t\t\t\t\t<Dialog>\n\t\t\t\t\t\t\t<DialogTrigger>\n\t\t\t\t\t\t\t\t<Icon name=\"Question\" size=\"lg\" className=\"animate-pulse\" />\n\t\t\t\t\t\t\t</DialogTrigger>\n\t\t\t\t\t\t\t<DialogContent>\n\t\t\t\t\t\t\t\t<DialogHeader>\n\t\t\t\t\t\t\t\t\t<Logo size=\"lg\" style=\"monochrome\" />\n\t\t\t\t\t\t\t\t\t<span className=\"text-lg font-semibold\">{displayName}</span>\n\t\t\t\t\t\t\t\t</DialogHeader>\n\t\t\t\t\t\t\t\t<DialogDescription>\n\t\t\t\t\t\t\t\t\tWelcome to the{' '}\n\t\t\t\t\t\t\t\t\t<Link to={`https://${host}`} className=\"underline\">\n\t\t\t\t\t\t\t\t\t\t{displayName}\n\t\t\t\t\t\t\t\t\t</Link>{' '}\n\t\t\t\t\t\t\t\t\tWorkshop app!\n\t\t\t\t\t\t\t\t</DialogDescription>\n\t\t\t\t\t\t\t\t{details}\n\t\t\t\t\t\t\t</DialogContent>\n\t\t\t\t\t\t</Dialog>\n\t\t\t\t\t</div>\n\t\t\t\t\t<div className=\"flex h-full items-center\">\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={`https://${host}`}\n\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 px-5 text-sm font-semibold\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Join</span>\n\t\t\t\t\t\t\t<span>↗︎</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\tto={ENV.EPICSHOP_DEPLOYED ? `https://${host}/login` : '/login'}\n\t\t\t\t\t\t\tclassName=\"flex h-full items-center justify-center space-x-1.5 bg-white/20 px-5 text-sm font-semibold shadow-md transition hover:bg-white/30\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Icon name=\"User\" size=\"lg\" />\n\t\t\t\t\t\t\t<span className=\"drop-shadow-sm\">Login</span>\n\t\t\t\t\t\t</Link>\n\t\t\t\t\t</div>\n\t\t\t\t</>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n\nconst itemVariants = {\n\thidden: { opacity: 0, x: -20 },\n\tvisible: { opacity: 1, x: 0 },\n}\nfunction NavigationExerciseListItem({\n\texerciseNumber,\n\tchildren,\n}: {\n\texerciseNumber: number\n\tchildren: React.ReactNode\n}) {\n\tconst progressClassName = useExerciseProgressClassName(exerciseNumber)\n\treturn (\n\t\t<motion.li\n\t\t\tvariants={itemVariants}\n\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\tclassName={cn(\n\t\t\t\t// add gap of 3 to children, but using padding so the progress extends through the whole height\n\t\t\t\t'py-[6px] first:pt-3 last:pb-3',\n\t\t\t\tprogressClassName ? `${progressClassName} before:border-t` : null,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"ml-2\">{children}</span>\n\t\t</motion.li>\n\t)\n}\n\nfunction NavigationExerciseStepListItem({\n\tchildren,\n\t...progressItemSearch\n}: {\n\tchildren: React.ReactNode\n} & ProgressItemSearch) {\n\tconst progressClassName = useProgressItemClassName(progressItemSearch)\n\treturn (\n\t\t<motion.li\n\t\t\tvariants={itemVariants}\n\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\tclassName={cn(\n\t\t\t\t// add gap of 3 to children, but using padding so the progress extends through the whole height\n\t\t\t\t'py-[6px] first:pt-3 last:pb-3',\n\t\t\t\tprogressClassName ? `${progressClassName} before:border-t` : null,\n\t\t\t)}\n\t\t>\n\t\t\t<span className=\"ml-2\">{children}</span>\n\t\t</motion.li>\n\t)\n}\n\nfunction MobileNavigation({\n\tisMenuOpened,\n\tonMenuOpenChange: setMenuOpened,\n}: {\n\tisMenuOpened: boolean\n\tonMenuOpenChange: (change: boolean) => void\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst user = useOptionalUser()\n\tconst nextExerciseRoute = useNextExerciseRoute()\n\tconst params = useParams()\n\tconst { users } = usePresence()\n\n\t// items\n\tconst listVariants = {\n\t\tvisible: {\n\t\t\topacity: 1,\n\t\t\ttransition: {\n\t\t\t\tduration: 0.05,\n\t\t\t\twhen: 'beforeChildren',\n\t\t\t\tstaggerChildren: 0.03,\n\t\t\t},\n\t\t},\n\t\thidden: {\n\t\t\topacity: 0,\n\t\t},\n\t}\n\n\treturn (\n\t\t<nav className=\"flex w-full border-b sm:hidden\">\n\t\t\t<div className=\"w-full\">\n\t\t\t\t<div\n\t\t\t\t\tclassName={cn('flex items-center', {\n\t\t\t\t\t\t'flex-col': isMenuOpened,\n\t\t\t\t\t\t'h-14': !isMenuOpened,\n\t\t\t\t\t})}\n\t\t\t\t>\n\t\t\t\t\t<NavToggle\n\t\t\t\t\t\ttitle={data.workshopTitle}\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tsetMenuOpened={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t\t{isMenuOpened && (\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\tclassName=\"flex w-full flex-grow flex-col justify-between overflow-x-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar\"\n\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\tclassName=\"flex flex-col\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.exercises.map(({ exerciseNumber, title, steps }) => {\n\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\tNumber(params.exerciseNumber) === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst showPlayground =\n\t\t\t\t\t\t\t\t\t\t!isActive &&\n\t\t\t\t\t\t\t\t\t\tdata.playground.exerciseNumber === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst exerciseNum = exerciseNumber.toString().padStart(2, '0')\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<NavigationExerciseListItem\n\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ 'bg-foreground text-background': isActive },\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t\t\t\t\t\t{showPlayground ? ' 🛝' : null}\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t{isActive ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"ml-4 mt-4 flex flex-col\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"instructions\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t!params.stepNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIntro\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{steps\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.map(({ name, stepNumber, title }) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNumber(params.stepNumber) === stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst step = stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isPlayground =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname === data.playground.appName\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstepNumber={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/${step}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isPlayground\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${step}. ${title} 🛝`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: `${step}. ${title}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/finished`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background': isActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t📝 Elaboration\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</NavigationExerciseListItem>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t<div className=\"mt-6\">\n\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\tto=\"/finished\"\n\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"]':\n\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t📝 Workshop Feedback\n\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t)}\n\t\t\t\t\t<div className=\"flex-grow\" />\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex items-center justify-start p-4',\n\t\t\t\t\t\t\tisMenuOpened && users.length > 4 ? 'min-h-14' : 'h-14',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t// left border is covered by the menu\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<FacePile isMenuOpened={isMenuOpened} />\n\t\t\t\t\t</div>\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user ? (\n\t\t\t\t\t\t<SimpleTooltip content={isMenuOpened ? null : 'Your account'}>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t\t\t'flex h-14 flex-shrink-0 items-center justify-start space-x-3 px-4 py-4 text-center no-underline hover:underline',\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t'border-l': !isMenuOpened,\n\t\t\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tto=\"/account\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={user.name ?? user.email}\n\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-full rounded-full\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Icon name=\"User\" className=\"flex-shrink-0\" size=\"lg\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tYour Account\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Your account</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user && nextExerciseRoute ? (\n\t\t\t\t\t\t<SimpleTooltip\n\t\t\t\t\t\t\tcontent={isMenuOpened ? null : 'Continue to next lesson'}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExerciseRoute}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'flex h-14 w-full items-center space-x-3 border-l px-4 py-4 pl-[18px] no-underline hover:underline',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstate={{ from: 'continue next lesson button' }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon name=\"FastForward\" className=\"flex-shrink-0\" size=\"md\" />\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue to next lesson\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Continue to next lesson</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex h-14 w-14 items-center justify-center self-start p-4 sm:mb-4 sm:w-full',\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t'w-full border-t': isMenuOpened,\n\t\t\t\t\t\t\t\t'border-l': !isMenuOpened,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t)}\n\t\t\t\t\t>\n\t\t\t\t\t\t<ThemeSwitch />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</nav>\n\t)\n}\n\nconst OPENED_MENU_WIDTH = 400\n\nfunction Navigation({\n\tisMenuOpened,\n\tonMenuOpenChange: setMenuOpened,\n}: {\n\tisMenuOpened: boolean\n\tonMenuOpenChange: (change: boolean) => void\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst user = useOptionalUser()\n\tconst nextExerciseRoute = useNextExerciseRoute()\n\tconst params = useParams()\n\tconst { users } = usePresence()\n\n\tconst exercise = data.exercises.find(\n\t\t(e) => e.exerciseNumber === Number(params.exerciseNumber),\n\t)\n\tconst app =\n\t\tparams.type === 'solution'\n\t\t\t? exercise?.solutions.find(\n\t\t\t\t\t(s) => s.stepNumber === Number(params.stepNumber),\n\t\t\t\t)\n\t\t\t: params.type === 'problem'\n\t\t\t\t? exercise?.problems.find(\n\t\t\t\t\t\t(p) => p.stepNumber === Number(params.stepNumber),\n\t\t\t\t\t)\n\t\t\t\t: null\n\n\t// container\n\tconst menuControls = useAnimationControls()\n\tconst menuVariants = {\n\t\tclose: { width: 56 },\n\t\topen: { width: OPENED_MENU_WIDTH },\n\t}\n\n\t// items\n\tconst listVariants = {\n\t\tvisible: {\n\t\t\topacity: 1,\n\t\t\ttransition: {\n\t\t\t\tduration: 0.05,\n\t\t\t\twhen: 'beforeChildren',\n\t\t\t\tstaggerChildren: 0.03,\n\t\t\t},\n\t\t},\n\t\thidden: {\n\t\t\topacity: 0,\n\t\t},\n\t}\n\tconst exNum = Number(params.exerciseNumber).toString().padStart(2, '0')\n\n\treturn (\n\t\t<nav className=\"hidden border-r sm:flex\">\n\t\t\t<motion.div\n\t\t\t\tinitial={isMenuOpened ? 'open' : 'close'}\n\t\t\t\tvariants={menuVariants}\n\t\t\t\tanimate={menuControls}\n\t\t\t>\n\t\t\t\t<div className=\"flex h-full flex-col items-center justify-between\">\n\t\t\t\t\t<NavToggle\n\t\t\t\t\t\ttitle={data.workshopTitle}\n\t\t\t\t\t\tmenuControls={menuControls}\n\t\t\t\t\t\tisMenuOpened={isMenuOpened}\n\t\t\t\t\t\tsetMenuOpened={setMenuOpened}\n\t\t\t\t\t/>\n\t\t\t\t\t{isMenuOpened && (\n\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\tstyle={{ width: OPENED_MENU_WIDTH }}\n\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\tclassName=\"flex flex-grow flex-col justify-between overflow-y-auto p-6 scrollbar-thin scrollbar-thumb-scrollbar\"\n\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\tclassName=\"flex flex-col\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{data.exercises.map(({ exerciseNumber, title, steps }) => {\n\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\tNumber(params.exerciseNumber) === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst showPlayground =\n\t\t\t\t\t\t\t\t\t\t!isActive &&\n\t\t\t\t\t\t\t\t\t\tdata.playground.exerciseNumber === exerciseNumber\n\t\t\t\t\t\t\t\t\tconst exerciseNum = exerciseNumber.toString().padStart(2, '0')\n\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t<NavigationExerciseListItem\n\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-2xl font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t'after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t{ 'bg-foreground text-background': isActive },\n\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t{title}\n\t\t\t\t\t\t\t\t\t\t\t\t{showPlayground ? ' 🛝' : null}\n\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t{isActive ? (\n\t\t\t\t\t\t\t\t\t\t\t\t<motion.ul\n\t\t\t\t\t\t\t\t\t\t\t\t\tvariants={listVariants}\n\t\t\t\t\t\t\t\t\t\t\t\t\tinitial=\"hidden\"\n\t\t\t\t\t\t\t\t\t\t\t\t\tanimate=\"visible\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\t\t\t\tclassName=\"ml-4 mt-4 flex flex-col\"\n\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"instructions\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t!params.stepNumber,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tIntro\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{steps\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t.map(({ name, stepNumber, title }) => {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isActive =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tNumber(params.stepNumber) === stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst step = stepNumber\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tconst isPlayground =\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tname === data.playground.appName\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tkey={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tstepNumber={stepNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/${step}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-xl font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background':\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{isPlayground\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? `${step}. ${title} 🛝`\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: `${step}. ${title}`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t\t\t\t\t\t\t<NavigationExerciseStepListItem\n\t\t\t\t\t\t\t\t\t\t\t\t\t\ttype=\"finished\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\texerciseNumber={exerciseNumber}\n\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tto={`/${exerciseNum}/finished`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap px-2 py-0.5 pr-3 text-base font-medium outline-none after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"] hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t'bg-foreground text-background': isActive,\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t📝 Elaboration\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t\t\t\t\t\t\t</NavigationExerciseStepListItem>\n\t\t\t\t\t\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t</NavigationExerciseListItem>\n\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t\t</motion.ul>\n\t\t\t\t\t\t\t<div className=\"mt-6\">\n\t\t\t\t\t\t\t\t<NavLink\n\t\t\t\t\t\t\t\t\tto=\"/finished\"\n\t\t\t\t\t\t\t\t\tclassName={({ isActive }) =>\n\t\t\t\t\t\t\t\t\t\tclsx(\n\t\t\t\t\t\t\t\t\t\t\t'relative whitespace-nowrap text-lg font-bold outline-none hover:underline focus:underline',\n\t\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\t\t'bg-black text-white after:absolute after:-bottom-2.5 after:-right-2.5 after:h-5 after:w-5 after:rotate-45 after:scale-75 after:bg-background after:content-[\"\"]':\n\t\t\t\t\t\t\t\t\t\t\t\t\tisActive,\n\t\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t📝 Workshop Feedback\n\t\t\t\t\t\t\t\t</NavLink>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t)}\n\t\t\t\t\t{!isMenuOpened && (\n\t\t\t\t\t\t<div className=\"flex flex-grow flex-col justify-center\">\n\t\t\t\t\t\t\t<div className=\"orientation-sideways w-full font-mono text-sm font-medium uppercase leading-none\">\n\t\t\t\t\t\t\t\t{exercise?.title ? (\n\t\t\t\t\t\t\t\t\t<Link to={`/${exNum}`}>{exercise.title}</Link>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t{exercise?.title && app?.title ? ' — ' : null}\n\t\t\t\t\t\t\t\t{app?.title ? (\n\t\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\t\tto={`/${exNum}/${app.stepNumber\n\t\t\t\t\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t\t\t\t\t.padStart(2, '0')}`}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t{app.title}\n\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t)}\n\t\t\t\t\t<div\n\t\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t\t'flex w-full items-center justify-start border-t p-4 transition-[height]',\n\t\t\t\t\t\t\tisMenuOpened && users.length > 4 ? 'h-28' : 'h-14',\n\t\t\t\t\t\t)}\n\t\t\t\t\t\tstyle={isMenuOpened ? { width: OPENED_MENU_WIDTH } : {}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<FacePile isMenuOpened={isMenuOpened} />\n\t\t\t\t\t</div>\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user ? (\n\t\t\t\t\t\t<SimpleTooltip content={isMenuOpened ? null : 'Your account'}>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tclassName=\"flex h-14 w-full flex-shrink-0 items-center justify-start space-x-3 border-t px-4 py-4 text-center no-underline hover:underline\"\n\t\t\t\t\t\t\t\tto=\"/account\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t{user.avatarUrl ? (\n\t\t\t\t\t\t\t\t\t<img\n\t\t\t\t\t\t\t\t\t\talt={user.name ?? user.email}\n\t\t\t\t\t\t\t\t\t\tsrc={user.avatarUrl}\n\t\t\t\t\t\t\t\t\t\tclassName=\"h-full rounded-full\"\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Icon name=\"User\" className=\"flex-shrink-0\" size=\"lg\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tYour Account\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Your account</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t{ENV.EPICSHOP_DEPLOYED ? null : user && nextExerciseRoute ? (\n\t\t\t\t\t\t<SimpleTooltip\n\t\t\t\t\t\t\tcontent={isMenuOpened ? null : 'Continue to next lesson'}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExerciseRoute}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'flex h-14 w-full items-center space-x-3 border-t px-4 py-4 pl-[18px] no-underline hover:underline',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\tstate={{ from: 'continue next lesson button' }}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon name=\"FastForward\" className=\"flex-shrink-0\" size=\"md\" />\n\t\t\t\t\t\t\t\t{isMenuOpened ? (\n\t\t\t\t\t\t\t\t\t<motion.div\n\t\t\t\t\t\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center whitespace-nowrap\"\n\t\t\t\t\t\t\t\t\t\tinitial={{ opacity: 0 }}\n\t\t\t\t\t\t\t\t\t\tanimate={{ opacity: 1 }}\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\tContinue to next lesson\n\t\t\t\t\t\t\t\t\t</motion.div>\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<span className=\"sr-only\">Continue to next lesson</span>\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"mb-4 w-full self-start border-t pl-3 pt-[15px]\">\n\t\t\t\t\t\t<ThemeSwitch />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t</motion.div>\n\t\t</nav>\n\t)\n}\n\nfunction NavToggle({\n\ttitle,\n\tisMenuOpened,\n\tsetMenuOpened,\n\tmenuControls,\n}: {\n\ttitle: string\n\tisMenuOpened: boolean\n\tsetMenuOpened: (value: boolean) => void\n\tmenuControls?: AnimationControls\n}) {\n\tconst menuButtonRef = React.useRef<HTMLButtonElement>(null)\n\tconst path01Variants = {\n\t\topen: { d: 'M3.06061 2.99999L21.0606 21' },\n\t\tclosed: { d: 'M0 9.5L24 9.5' },\n\t}\n\tconst path02Variants = {\n\t\topen: { d: 'M3.00006 21.0607L21 3.06064' },\n\t\tmoving: { d: 'M0 14.5L24 14.5' },\n\t\tclosed: { d: 'M0 14.5L15 14.5' },\n\t}\n\tconst path01Controls = useAnimationControls()\n\tconst path02Controls = useAnimationControls()\n\n\tasync function toggleMenu() {\n\t\tvoid menuControls?.start(isMenuOpened ? 'close' : 'open')\n\t\tsetMenuOpened(!isMenuOpened)\n\t\tif (isMenuOpened) {\n\t\t\tvoid path01Controls.start(path01Variants.closed)\n\t\t\tawait path02Controls.start(path02Variants.moving)\n\t\t\tvoid path02Controls.start(path02Variants.closed)\n\t\t} else {\n\t\t\tawait path02Controls.start(path02Variants.moving)\n\t\t\tvoid path01Controls.start(path01Variants.open)\n\t\t\tvoid path02Controls.start(path02Variants.open)\n\t\t}\n\t}\n\n\tReact.useEffect(() => {\n\t\tif (!isMenuOpened) return\n\n\t\tfunction handleKeyUp(event: KeyboardEvent) {\n\t\t\tif (event.key === 'Escape') {\n\t\t\t\tmenuButtonRef.current?.click()\n\t\t\t}\n\t\t}\n\t\tdocument.addEventListener('keyup', handleKeyUp)\n\t\treturn () => document.removeEventListener('keyup', handleKeyUp)\n\t}, [isMenuOpened])\n\n\treturn (\n\t\t<div\n\t\t\tclassName={cn(\n\t\t\t\t'relative inline-flex h-14 flex-shrink-0 items-center justify-between overflow-hidden border-r sm:w-full sm:border-b sm:border-r-0',\n\t\t\t\t{\n\t\t\t\t\t'w-full': isMenuOpened,\n\t\t\t\t},\n\t\t\t)}\n\t\t>\n\t\t\t<button\n\t\t\t\tref={menuButtonRef}\n\t\t\t\tclassName=\"flex h-14 w-14 items-center justify-center\"\n\t\t\t\taria-label=\"Open Navigation menu\"\n\t\t\t\tonClick={toggleMenu}\n\t\t\t>\n\t\t\t\t<svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\">\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\t{...path01Variants.closed}\n\t\t\t\t\t\tanimate={path01Controls}\n\t\t\t\t\t\ttransition={{ duration: 0.2 }}\n\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t\t<motion.path\n\t\t\t\t\t\t{...path02Variants.closed}\n\t\t\t\t\t\tanimate={path02Controls}\n\t\t\t\t\t\ttransition={{ duration: 0.2 }}\n\t\t\t\t\t\tstroke=\"currentColor\"\n\t\t\t\t\t\tstrokeWidth={1.5}\n\t\t\t\t\t/>\n\t\t\t\t</svg>\n\t\t\t</button>\n\t\t\t{isMenuOpened && (\n\t\t\t\t<motion.p\n\t\t\t\t\ttransition={{ delay: 0.2 }}\n\t\t\t\t\tinitial={{ opacity: 0, y: 5 }}\n\t\t\t\t\tanimate={{ opacity: 1, y: 0 }}\n\t\t\t\t\t// @ts-expect-error framer-motion + latest typescript types has issues\n\t\t\t\t\tclassName=\"absolute right-5 whitespace-nowrap font-mono text-sm uppercase\"\n\t\t\t\t>\n\t\t\t\t\t<Link to=\"/\">{title}</Link>\n\t\t\t\t</motion.p>\n\t\t\t)}\n\t\t</div>\n\t)\n}\n"],"names":["stopAnimation","visualElement","value","setVariants","variantLabels","key","variant","setTarget","child","setValues","definition","animationControls","subscribers","controls","transitionOverride","animations","animateVisualElement","useAnimationControls","useConstant","useIsomorphicLayoutEffect","makeMediaQueryStore","mediaQuery","serverSnapshot","getSnapshot","subscribe","callback","mediaQueryList","useSyncExternalStore","DIALOG_NAME","createDialogContext","createDialogScope","createContextScope","DialogProvider","useDialogContext","Dialog","props","__scopeDialog","children","openProp","defaultOpen","onOpenChange","modal","triggerRef","React.useRef","contentRef","open","setOpen","useControllableState","jsx","useId","React.useCallback","prevOpen","TRIGGER_NAME","DialogTrigger","React.forwardRef","forwardedRef","triggerProps","context","composedTriggerRef","useComposedRefs","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","DialogPortal","forceMount","container","React.Children","Presence","PortalPrimitive","OVERLAY_NAME","DialogOverlay","portalContext","overlayProps","DialogOverlayImpl","RemoveScroll","Slot","CONTENT_NAME","DialogContent","contentProps","DialogContentModal","DialogContentNonModal","composedRefs","React.useEffect","content","hideOthers","DialogContentImpl","event","_a","originalEvent","ctrlLeftClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","_b","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","useFocusGuards","jsxs","Fragment","FocusScope","DismissableLayer","TitleWarning","DescriptionWarning","TITLE_NAME","DialogTitle","titleProps","DESCRIPTION_NAME","DialogDescription","descriptionProps","CLOSE_NAME","DialogClose","closeProps","TITLE_WARNING_NAME","WarningProvider","useWarningContext","createContext","titleId","titleWarningContext","MESSAGE","DESCRIPTION_WARNING_NAME","descriptionId","describedById","Root","Trigger","Portal","Overlay","Content","Title","Description","Close","DialogPrimitive.Root","DialogPrimitive.Trigger","DialogPrimitive.Portal","className","ref","DialogPrimitive.Overlay","cn","DialogPrimitive.Content","DialogPrimitive.Close","Icon","DialogHeader","DialogPrimitive.Title","DialogPrimitive.Description","opacities","shadows","getScoreClassNames","score","opacityNumber","Math","round","length","shadowNumber","FacePile","isMenuOpened","loggedInUser","useOptionalUser","users","usePresence","product","displayNameShort","useWorkshopConfig","limit","numberOverLimit","shouldShowNumberOverLimit","tiffany","Link","rel","to","alt","src","overLimitLabel","TooltipProvider","slice","map","user","scoreClassNames","locationLabel","getLocationLabel","location","Tooltip","TooltipTrigger","asChild","avatarUrl","tabIndex","name","TooltipContent","origin","includes","id","line1","line2","useIsWide","App","isWide","isHydrated","useHydrated","setMenuOpened","React","NoUserBanner","MobileNavigation","onMenuOpenChange","Navigation","Outlet","exercise","exercisePortion","exerciseNumber","stepNumber","filter","Boolean","s","toString","padStart","join","type","workshopTitle","host","displayName","details","ENV","EPICSHOP_DEPLOYED","EPICSHOP_GITHUB_REPO","href","Logo","size","style","itemVariants","hidden","opacity","x","visible","NavigationExerciseListItem","progressClassName","useExerciseProgressClassName","motion","li","variants","NavigationExerciseStepListItem","progressItemSearch","useProgressItemClassName","data","useLoaderData","nextExerciseRoute","useNextExerciseRoute","params","useParams","listVariants","transition","duration","when","staggerChildren","NavToggle","title","div","initial","animate","ul","exercises","steps","isActive","Number","showPlayground","playground","exerciseNum","prefetch","clsx","step","isPlayground","appName","NavLink","SimpleTooltip","email","state","from","ThemeSwitch","OPENED_MENU_WIDTH","find","e","app","solutions","problems","p","menuControls","menuVariants","close","width","exNum","menuButtonRef","path01Variants","d","closed","path02Variants","moving","path01Controls","path02Controls","toggleMenu","start","handleKeyUp","current","click","document","addEventListener","removeEventListener","onClick","height","viewBox","path","stroke","strokeWidth","delay","y"],"mappings":"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","x_google_ignoreList":[0,1,3]}
@@ -1,2 +0,0 @@
1
- import{r as t,j as s}from"./index-1cKOJFpX.js";import{P as e}from"./preview-WJ-QYhx8.js";import{u as i}from"./components-CME-nGId.js";import"./misc-Txs7O6JX.js";import"./request-info-CEhUGODY.js";import"./button-CQ6cnotS.js";import"./loading-CF7oQHQf.js";import"./index-DlJAkutV.js";import"./tooltip-DTFU8ajx.js";import"./pe-CUZaIcdt.js";import"./progress-bar-bUuKn1Q8.js";function R(){const{appInfo:r}=i(),o=t.useRef(null);return s.jsx(e,{appInfo:r,inBrowserBrowserRef:o})}export{R as default};
2
- //# sourceMappingURL=app-C-oFaj2l.js.map
@@ -1,2 +0,0 @@
1
- import{a as i,h as e}from"./discord-CgdmSzxV.js";import"./index-1cKOJFpX.js";import"./misc-Txs7O6JX.js";import"./components-CME-nGId.js";import"./user-DvujSs-t.js";export{i as default,e as handle};
2
- //# sourceMappingURL=discord-BBRM_H3g.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"discord-BBRM_H3g.js","sources":[],"sourcesContent":[],"names":[],"mappings":""}
@@ -1 +0,0 @@
1
- {"version":3,"file":"onboarding-Dc2TmI9y.js","sources":["../../../app/routes/onboarding.tsx"],"sourcesContent":["import { invariantResponse } from '@epic-web/invariant'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { markOnboardingVideoWatched } from '@epic-web/workshop-utils/db.server'\nimport { makeTimings } from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport {\n\tdefer,\n\tredirect,\n\ttype ActionFunctionArgs,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n} from '@remix-run/node'\nimport { Form, useLoaderData } from '@remix-run/react'\nimport { Button } from '#app/components/button.tsx'\nimport {\n\tDeferredEpicVideo,\n\tEpicVideoInfoProvider,\n} from '#app/components/epic-video.tsx'\nimport { getEpicVideoInfos } from '#app/utils/epic-api.ts'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => null,\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('onboarding')\n\n\tconst { onboardingVideo } = getWorkshopConfig()\n\tconst videoInfos = getEpicVideoInfos([onboardingVideo], { request, timings })\n\treturn defer(\n\t\t{ onboardingVideo, videoInfos },\n\t\t{ headers: { 'Server-Timing': timings.toString() } },\n\t)\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders }) => {\n\tconst headers = {\n\t\t'Server-Timing': loaderHeaders.get('Server-Timing') ?? '',\n\t}\n\treturn headers\n}\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tconst data = await request.formData()\n\tconst intent = data.get('intent')\n\tinvariantResponse(intent === 'complete', 'Invalid intent')\n\tconst { onboardingVideo } = getWorkshopConfig()\n\tawait markOnboardingVideoWatched(onboardingVideo)\n\tthrow redirect('/account')\n}\n\nexport default function Onboarding() {\n\tconst data = useLoaderData<typeof loader>()\n\treturn (\n\t\t<main className=\"flex h-full w-full flex-col items-center justify-between gap-4\">\n\t\t\t<div className=\"container flex h-full w-full max-w-5xl flex-1 flex-col items-center gap-4 overflow-y-scroll py-12 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t<h1 className=\"text-5xl\">Onboarding</h1>\n\t\t\t\t<p className=\"text-xl\">Welcome to EpicWeb.dev!</p>\n\t\t\t\t<p className=\"text-lg\">\n\t\t\t\t\tBefore you get started, <strong>you must watch the tour video</strong>\n\t\t\t\t\t! You're going to be spending a lot of time in here, so it's important\n\t\t\t\t\tyou understand how to work effectively in this workshop\n\t\t\t\t</p>\n\t\t\t\t<div className=\"w-[780px] max-w-full\">\n\t\t\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={data.videoInfos}>\n\t\t\t\t\t\t<DeferredEpicVideo url={data.onboardingVideo} />\n\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t\t<Form method=\"post\" className=\"pb-4\">\n\t\t\t\t<Button name=\"intent\" value=\"complete\" varient=\"primary\">\n\t\t\t\t\tI've watched it. Let's go!\n\t\t\t\t</Button>\n\t\t\t</Form>\n\t\t</main>\n\t)\n}\n"],"names":["handle","getSitemapEntries","Onboarding","data","useLoaderData","jsxs","className","children","jsx","EpicVideoInfoProvider","epicVideoInfosPromise","videoInfos","DeferredEpicVideo","url","onboardingVideo","Form","method","Button","name","value","varient"],"mappings":"yaAoBO,MAAMA,EAAoB,CAChCC,kBAAmBA,IAAM,IAC1B,EA6BA,SAAwBC,GAAa,CACpC,MAAMC,EAAOC,IAEZ,OAAAC,EAAAA,KAAC,OAAK,CAAAC,UAAU,iEACfC,SAAA,CAACF,EAAA,KAAA,MAAA,CAAIC,UAAU,6IACdC,SAAA,CAACC,EAAA,IAAA,KAAA,CAAGF,UAAU,WAAWC,SAAU,YAAA,CAAA,EAClCC,EAAA,IAAA,IAAA,CAAEF,UAAU,UAAUC,SAAuB,yBAAA,CAAA,EAC9CF,EAAA,KAAC,IAAE,CAAAC,UAAU,UAAUC,SAAA,CAAA,2BACEC,EAAA,IAAC,UAAOD,SAA6B,+BAAA,CAAA,EAAS,gIAAA,CAGvE,CAAA,EACCC,EAAA,IAAA,MAAA,CAAIF,UAAU,uBACdC,eAACE,EAAsB,CAAAC,sBAAuBP,EAAKQ,WAClDJ,eAACK,EAAkB,CAAAC,IAAKV,EAAKW,gBAAiB,EAC/C,CACD,CAAA,CAAA,CACD,CAAA,EACCN,EAAA,IAAAO,EAAA,CAAKC,OAAO,OAAOV,UAAU,OAC7BC,SAAAC,EAAA,IAACS,EAAO,CAAAC,KAAK,SAASC,MAAM,WAAWC,QAAQ,UAAUb,sCAEzD,CACD,CAAA,CAAA,CACD,CAAA,CAEF"}
@@ -1,2 +0,0 @@
1
- import{j as e,r as a}from"./index-1cKOJFpX.js";import{u as ne,b as J,I,c as ae,a as Q}from"./misc-Txs7O6JX.js";import{z as t,u as X}from"./request-info-CEhUGODY.js";import{B as Z}from"./button-CQ6cnotS.js";import{L as C}from"./loading-CF7oQHQf.js";import{s as O}from"./progress-bar-bUuKn1Q8.js";import{u as z}from"./pe-CUZaIcdt.js";import{a as q,b as ie,F as oe}from"./components-CME-nGId.js";import{T as le,a as v,b as E,c as B}from"./tooltip-DTFU8ajx.js";import{u as ce}from"./index-DlJAkutV.js";function ue({name:o}){var i;const r=q(),l=z(),c=(i=r.formData)==null?void 0:i.get("intent"),u=c==="stop"?"Stopping App":c==="restart"?"Restarting App":null,f=ne();return e.jsxs(r.Form,{method:"POST",action:"/start",children:[l,O,e.jsx("input",{type:"hidden",name:"name",value:o}),e.jsx("button",{type:"submit",name:"intent",value:f?"restart":"stop",className:"h-full border-r px-3 py-4 font-mono text-xs uppercase leading-none",children:u||(f?"Restart App":"Stop App")})]})}function ee({port:o}){const r=q(),l=z();return e.jsxs(r.Form,{method:"POST",action:"/start",children:[l,O,e.jsx("input",{type:"hidden",name:"port",value:o}),e.jsx(Z,{varient:"mono",type:"submit",name:"intent",value:"stop-port",children:r.state==="idle"?"Stop Port":"Stopping Port"})]})}function de({name:o}){var c;const r=q(),l=z();return((c=r.data)==null?void 0:c.status)==="app-not-started"?r.data.error==="port-unavailable"?e.jsxs("div",{children:["The port is unavailable. Would you like to stop whatever is running on that port and try again?",e.jsx(ee,{port:r.data.port})]}):e.jsx("div",{children:"An unknown error has happened."}):e.jsxs(r.Form,{method:"POST",action:"/start",children:[l,O,e.jsx("input",{type:"hidden",name:"name",value:o}),r.state==="idle"?e.jsx(Z,{type:"submit",name:"intent",value:"start",varient:"mono",children:"Start App"}):e.jsx("div",{children:e.jsx(C,{children:"Starting App"})})]})}const he=t.intersection(t.object({type:t.literal("epicshop:history-call")}),t.union([t.object({method:t.literal("pushState"),args:t.union([t.tuple([t.object({}).passthrough(),t.unknown()]),t.tuple([t.object({}).passthrough(),t.unknown(),t.string()])])}),t.object({method:t.literal("replaceState"),args:t.union([t.tuple([t.object({}).passthrough(),t.unknown()]),t.tuple([t.object({}).passthrough(),t.unknown(),t.string()])])}),t.object({method:t.literal("go"),args:t.tuple([t.number().optional()])}),t.object({method:t.literal("forward"),args:t.tuple([])}),t.object({method:t.literal("back"),args:t.tuple([])}),t.object({method:t.literal("popstate"),pathname:t.string(),delta:t.number()})])),me=t.object({type:t.literal("epicshop:loaded"),url:t.string()}),fe=t.union([he,me]);function $(o,r,l){return Math.min(Math.max(o+r,0),l)}const pe=a.forwardRef(xe);function xe({name:o,port:r,portIsAvailable:l,isRunning:c,baseUrl:u,id:f,initialRoute:i},p){const b=X();return c?e.jsx(ge,{baseUrl:u,id:f,name:o,ref:p,initialRoute:i}):l===!1?e.jsxs("div",{className:"flex flex-col items-center justify-center",children:[e.jsxs("p",{className:"max-w-xs pb-5 text-center",role:"status",children:["The port for this app is unavailable. It could be that you're running it ",e.jsx("a",{href:J({domain:b.domain,port:r}),className:"underline",children:"elsewhere"}),"?"]}),e.jsx(ee,{port:r})]}):e.jsx(de,{name:o})}const ge=a.forwardRef(je);function je({baseUrl:o,id:r,name:l,initialRoute:c},u){const[f,i]=ie(),p=f.get("pathname")??c,[b,N]=a.useState(0),x=r+b,y=a.useRef("new"),L=a.useRef(null),[g,T]=a.useState({history:[p],index:0}),[H,A]=a.useState(p),U=a.useRef(null),j=new URL(p,o),M=a.useRef(j);a.useEffect(()=>{M.current=j});const[W,_]=a.useState(j),F=a.useRef(r);F.current!==r&&(F.current=r,_(M.current)),a.useEffect(()=>{F.current=r}),a.useEffect(()=>{function n(d){var Y;if(d.source!==((Y=U.current)==null?void 0:Y.contentWindow))return;const P=fe.safeParse(d.data,{path:["messageEvent","data"]});if(!P.success)return;const{data:h}=P;if(h.type==="epicshop:loaded"){T(s=>{const w=S=>$(s.index,S,s.history.length-1);if(y.current==="back")return{...s,index:w(-1)};if(y.current==="forward")return{...s,index:w(1)};if(y.current==="new"){const S=s.history[s.index],m=new URL(h.url).pathname;if(S===m)return s;const k=[...s.history.slice(0,s.index+1),m];return{history:k,index:k.length-1}}else throw new Error("Unexpected lastDirectionRef value")});return}const{method:se}=h;T(s=>{const w=m=>$(s.index,m,s.history.length-1),S=s.history[s.index];switch(se){case"popstate":return{...s,index:w(h.delta)};case"forward":return{...s,index:w(1)};case"back":return{...s,index:w(-1)};case"pushState":{const m=h.args[2]??S,k=[...s.history.slice(0,s.index+1),m].filter(Boolean);return{...s,history:k,index:k.length-1}}case"replaceState":{const m=h.args[2]??S;return{...s,history:[...s.history.slice(0,s.index),m,...s.history.slice(s.index+1)].filter(Boolean)}}case"go":{const[m=0]=h.args;return{...s,index:w(m)}}}})}return window.addEventListener("message",n),()=>{window.removeEventListener("message",n)}},[]);const K=a.useRef(i);a.useEffect(()=>{K.current=i},[i]);const R=g.history[g.index];a.useEffect(()=>{if(!R)return;A(R);const n=new URLSearchParams(window.location.search);R==="/"?n.delete("pathname"):n.set("pathname",R),`?${n.toString()}`!==window.location.search&&K.current(n,{replace:!0})},[R]);const D=(...n)=>{var P,h;const d=n[0];typeof d=="number"?y.current=d>0?"forward":"back":y.current="new",L.current&&clearTimeout(L.current),L.current=setTimeout(()=>{y.current="new"},100),(h=(P=U.current)==null?void 0:P.contentWindow)==null||h.postMessage({type:"epicshop:navigate-call",params:n},"*")};function G(n=H){A(n);const d=g.history[g.index];D(n,{replace:d===n})}a.useImperativeHandle(u,()=>({handleExtrnalNavigation:G}));const te=g.index===g.history.length-1,re=g.index<=0,V=[];for(const[n,d]of f.entries())n!=="pathname"&&V.push(e.jsx("input",{type:"hidden",name:n,value:d},n));return e.jsx(le,{children:e.jsxs("div",{className:"flex h-full flex-grow flex-col",children:[e.jsxs("div",{className:"flex items-center justify-between border-b pl-1.5",children:[e.jsxs("div",{className:"mr-2 flex items-center justify-center gap-2 px-1",children:[e.jsxs(v,{children:[e.jsx(E,{asChild:!0,children:e.jsx("button",{type:"button",className:"hidden aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40 sm:flex",disabled:re,onClick:()=>D(-1),children:e.jsx(I,{name:"ArrowLeft","aria-hidden":"true"})})}),e.jsx(B,{children:"Go back"})]}),e.jsxs(v,{children:[e.jsx(E,{asChild:!0,children:e.jsx("button",{type:"button",className:"hidden aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40 sm:flex",disabled:te,onClick:()=>D(1),children:e.jsx(I,{name:"ArrowRight","aria-hidden":"true"})})}),e.jsx(B,{children:"Go forward"})]}),e.jsxs(v,{children:[e.jsx(E,{asChild:!0,children:e.jsx("button",{type:"button",className:"flex aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40",onClick:()=>{_(j),N(b+1),T({history:[j.pathname],index:0})},children:e.jsx(I,{name:"Refresh","aria-hidden":"true"})})}),e.jsx(B,{children:"Refresh"})]})]}),e.jsxs(oe,{method:"get",replace:!0,className:"flex flex-1 gap-2",onSubmit:()=>G(),children:[V,e.jsxs("div",{className:"flex flex-1 items-center border-x bg-background p-3 leading-none text-foreground",children:[e.jsx("a",{href:j.toString(),target:"_blank",rel:"noreferrer",children:W.host}),e.jsx("input",{"aria-label":"pathname",className:"w-full flex-1 bg-background focus-visible:outline-none",value:H,name:"pathname",onChange:n=>A(n.currentTarget.value)})]})]}),e.jsx(ue,{name:l}),e.jsxs(v,{children:[e.jsx(E,{asChild:!0,children:e.jsx("a",{href:j.toString(),target:"_blank",rel:"noreferrer",className:ae("flex aspect-square items-center justify-center px-3.5"),children:e.jsx(I,{name:"ExternalLink"})})}),e.jsx(B,{children:"Open in new tab"})]})]}),e.jsx("div",{className:"flex h-full w-full flex-grow dark:bg-white",children:e.jsx("iframe",{title:l,ref:U,src:W.toString(),className:"h-full w-full flex-grow bg-white"},x)})]})})}function Be({id:o,appInfo:r,inBrowserBrowserRef:l}){const c=X(),u=ce();if(!r)return e.jsx("p",{children:"No app here. Sorry."});const{isRunning:f,dev:i,name:p,portIsAvailable:b,title:N}=r;if(ENV.EPICSHOP_DEPLOYED&&r.stackBlitzUrl){const x=new URL(r.stackBlitzUrl);return x.searchParams.set("embed","1"),x.searchParams.set("theme",u),e.jsx(we,{title:N,url:x.toString(),loadingContent:e.jsx(C,{children:e.jsxs("span",{children:["Loading"," ",e.jsxs("a",{className:"underline",href:r.stackBlitzUrl,children:['"',N,'"']})]})})})}if(i.type==="script"){const x=J({domain:c.domain,port:i.portNumber});return e.jsx(pe,{ref:l,isRunning:f,id:o??p,name:p,portIsAvailable:b,port:i.portNumber,baseUrl:x,initialRoute:i.initialRoute})}else return i.type==="browser"?e.jsxs("div",{className:"relative h-full flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-scrollbar",children:[e.jsxs("a",{href:i.pathname,target:"_blank",rel:"noreferrer",className:Q("absolute bottom-5 right-5 flex items-center justify-center rounded-full bg-gray-100 p-2.5 transition hover:bg-gray-200 dark:bg-gray-800 hover:dark:bg-gray-600"),children:[e.jsx(I,{name:"ExternalLink","aria-hidden":"true"}),e.jsx("span",{className:"sr-only",children:"Open in New Window"})]}),e.jsx("iframe",{title:N,src:i.pathname,className:"h-full w-full flex-grow bg-white"})]}):e.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:e.jsxs("p",{children:["Preview for dev type of ",e.jsx("code",{children:i.type})," not supported."]})})}function we({url:o,title:r,loadingContent:l}){const[c,u]=a.useState(!1);return e.jsxs("div",{className:"h-full w-full flex-grow",children:[c?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:l}),e.jsx("iframe",{onLoad:()=>u(!0),onError:()=>u(!0),src:o,className:Q("h-full w-full flex-grow transition-opacity duration-300",c?"opacity-100":"opacity-0"),title:r,sandbox:"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox"})]})}export{Be as P};
2
- //# sourceMappingURL=preview-WJ-QYhx8.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"preview-WJ-QYhx8.js","sources":["../../../app/routes/start.tsx","../../../app/components/in-browser-browser.tsx","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/preview.tsx"],"sourcesContent":["import { invariant, invariantResponse } from '@epic-web/invariant'\nimport { getAppByName } from '@epic-web/workshop-utils/apps.server'\nimport {\n\tcloseProcess,\n\trunAppDev,\n\tstopPort,\n\twaitOnApp,\n} from '@epic-web/workshop-utils/process-manager.server'\nimport { json, type ActionFunctionArgs } from '@remix-run/node'\nimport { useFetcher } from '@remix-run/react'\nimport { Button } from '#app/components/button.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { showProgressBarField } from '#app/components/progress-bar.tsx'\nimport { ensureUndeployed, useAltDown } from '#app/utils/misc.tsx'\nimport { jsonWithPE, usePERedirectInput } from '#app/utils/pe.js'\nimport { createToastHeaders } from '#app/utils/toast.server'\n\nexport async function action({ request }: ActionFunctionArgs) {\n\tensureUndeployed()\n\tconst formData = await request.formData()\n\tconst intent = formData.get('intent')\n\tinvariantResponse(typeof intent === 'string', 'intent is required')\n\n\tif (intent === 'start' || intent === 'stop' || intent === 'restart') {\n\t\tconst name = formData.get('name')\n\t\tinvariantResponse(typeof name === 'string', 'name is required')\n\t\tconst app = await getAppByName(name)\n\t\tif (!app) {\n\t\t\tthrow new Response('Not found', { status: 404 })\n\t\t}\n\t\tif (app.dev.type !== 'script') {\n\t\t\tthrow new Response(`App \"${name}\" does not have a server`, {\n\t\t\t\tstatus: 400,\n\t\t\t})\n\t\t}\n\n\t\tasync function startApp() {\n\t\t\tinvariant(app, 'app must be defined')\n\t\t\tconst result = await runAppDev(app)\n\t\t\tif (result.running) {\n\t\t\t\tconst appRunningResult = await waitOnApp(app)\n\t\t\t\tif (appRunningResult?.status === 'success') {\n\t\t\t\t\t// wait another 200ms just in case the build output for assets isn't finished\n\t\t\t\t\tawait new Promise((resolve) => setTimeout(resolve, 200))\n\t\t\t\t\treturn jsonWithPE(formData, { status: 'app-started' } as const)\n\t\t\t\t} else if (app.dev.type === 'script') {\n\t\t\t\t\tconst errorMessage = appRunningResult\n\t\t\t\t\t\t? appRunningResult.error\n\t\t\t\t\t\t: 'Unknown error'\n\t\t\t\t\treturn json(\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 'app-not-started',\n\t\t\t\t\t\t\terror: errorMessage,\n\t\t\t\t\t\t\tport: app.dev.portNumber,\n\t\t\t\t\t\t} as const,\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\tstatusText: 'App did not start',\n\t\t\t\t\t\t\theaders: await createToastHeaders({\n\t\t\t\t\t\t\t\tdescription: errorMessage,\n\t\t\t\t\t\t\t\ttitle: 'App did not start',\n\t\t\t\t\t\t\t\ttype: 'error',\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t},\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t} else if (result.portNumber) {\n\t\t\t\treturn jsonWithPE(formData, {\n\t\t\t\t\tstatus: 'app-not-started',\n\t\t\t\t\terror: result.status,\n\t\t\t\t\tport: result.portNumber,\n\t\t\t\t} as const)\n\t\t\t} else {\n\t\t\t\tthrow new Response(\n\t\t\t\t\t'Tried starting a server for an app that does not have one',\n\t\t\t\t\t{ status: 400 },\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\n\t\tasync function stopApp() {\n\t\t\tinvariant(app, 'app must be defined')\n\t\t\tawait closeProcess(app.name)\n\t\t\treturn jsonWithPE(formData, { status: 'app-stopped' } as const)\n\t\t}\n\n\t\tswitch (intent) {\n\t\t\tcase 'start': {\n\t\t\t\treturn startApp()\n\t\t\t}\n\t\t\tcase 'stop': {\n\t\t\t\treturn stopApp()\n\t\t\t}\n\t\t\tcase 'restart': {\n\t\t\t\tawait stopApp()\n\t\t\t\treturn startApp()\n\t\t\t}\n\t\t}\n\t}\n\n\tif (intent === 'stop-port') {\n\t\tconst port = formData.get('port')\n\t\tinvariantResponse(typeof port === 'string', 'port is required')\n\t\tawait stopPort(port)\n\t\treturn jsonWithPE(formData, { status: 'port-stopped' } as const)\n\t}\n\tthrow new Error(`Unknown intent: ${intent}`)\n}\n\nexport function AppStopper({ name }: { name: string }) {\n\tconst fetcher = useFetcher<typeof action>()\n\tconst peRedirectInput = usePERedirectInput()\n\tconst inFlightIntent = fetcher.formData?.get('intent')\n\tconst inFlightState =\n\t\tinFlightIntent === 'stop'\n\t\t\t? 'Stopping App'\n\t\t\t: inFlightIntent === 'restart'\n\t\t\t\t? 'Restarting App'\n\t\t\t\t: null\n\tconst altDown = useAltDown()\n\treturn (\n\t\t<fetcher.Form method=\"POST\" action=\"/start\">\n\t\t\t{peRedirectInput}\n\t\t\t{showProgressBarField}\n\t\t\t<input type=\"hidden\" name=\"name\" value={name} />\n\t\t\t<button\n\t\t\t\ttype=\"submit\"\n\t\t\t\tname=\"intent\"\n\t\t\t\tvalue={altDown ? 'restart' : 'stop'}\n\t\t\t\tclassName=\"h-full border-r px-3 py-4 font-mono text-xs uppercase leading-none\"\n\t\t\t>\n\t\t\t\t{inFlightState ? inFlightState : altDown ? 'Restart App' : 'Stop App'}\n\t\t\t</button>\n\t\t</fetcher.Form>\n\t)\n}\n\nexport function PortStopper({ port }: { port: number | string }) {\n\tconst fetcher = useFetcher<typeof action>()\n\tconst peRedirectInput = usePERedirectInput()\n\treturn (\n\t\t<fetcher.Form method=\"POST\" action=\"/start\">\n\t\t\t{peRedirectInput}\n\t\t\t{showProgressBarField}\n\t\t\t<input type=\"hidden\" name=\"port\" value={port} />\n\t\t\t<Button varient=\"mono\" type=\"submit\" name=\"intent\" value=\"stop-port\">\n\t\t\t\t{fetcher.state === 'idle' ? 'Stop Port' : 'Stopping Port'}\n\t\t\t</Button>\n\t\t</fetcher.Form>\n\t)\n}\n\nexport function AppStarter({ name }: { name: string }) {\n\tconst fetcher = useFetcher<typeof action>()\n\tconst peRedirectInput = usePERedirectInput()\n\tif (fetcher.data?.status === 'app-not-started') {\n\t\tif (fetcher.data.error === 'port-unavailable') {\n\t\t\treturn (\n\t\t\t\t<div>\n\t\t\t\t\tThe port is unavailable. Would you like to stop whatever is running on\n\t\t\t\t\tthat port and try again?\n\t\t\t\t\t<PortStopper port={fetcher.data.port} />\n\t\t\t\t</div>\n\t\t\t)\n\t\t} else {\n\t\t\treturn <div>An unknown error has happened.</div>\n\t\t}\n\t}\n\treturn (\n\t\t<fetcher.Form method=\"POST\" action=\"/start\">\n\t\t\t{peRedirectInput}\n\t\t\t{showProgressBarField}\n\t\t\t<input type=\"hidden\" name=\"name\" value={name} />\n\t\t\t{fetcher.state === 'idle' ? (\n\t\t\t\t<Button type=\"submit\" name=\"intent\" value=\"start\" varient=\"mono\">\n\t\t\t\t\tStart App\n\t\t\t\t</Button>\n\t\t\t) : (\n\t\t\t\t<div>\n\t\t\t\t\t<Loading>Starting App</Loading>\n\t\t\t\t</div>\n\t\t\t)}\n\t\t</fetcher.Form>\n\t)\n}\n","import { Form, useSearchParams, type NavigateFunction } from '@remix-run/react'\nimport { clsx } from 'clsx'\nimport {\n\tforwardRef,\n\tuseEffect,\n\tuseImperativeHandle,\n\tuseRef,\n\tuseState,\n\ttype ForwardedRef,\n} from 'react'\nimport { z } from 'zod'\nimport { Icon } from '#app/components/icons.tsx'\nimport { AppStarter, AppStopper, PortStopper } from '#app/routes/start.tsx'\nimport { getBaseUrl } from '#app/utils/misc.tsx'\nimport { useRequestInfo } from '#app/utils/request-info.ts'\nimport {\n\tTooltip,\n\tTooltipContent,\n\tTooltipProvider,\n\tTooltipTrigger,\n} from './ui/tooltip.tsx'\n\nconst historyCallDataSchema = z.intersection(\n\tz.object({\n\t\ttype: z.literal('epicshop:history-call'),\n\t}),\n\tz.union([\n\t\tz.object({\n\t\t\tmethod: z.literal('pushState'),\n\t\t\targs: z.union([\n\t\t\t\tz.tuple([z.object({}).passthrough(), z.unknown()]),\n\t\t\t\tz.tuple([z.object({}).passthrough(), z.unknown(), z.string()]),\n\t\t\t]),\n\t\t}),\n\t\tz.object({\n\t\t\tmethod: z.literal('replaceState'),\n\t\t\targs: z.union([\n\t\t\t\tz.tuple([z.object({}).passthrough(), z.unknown()]),\n\t\t\t\tz.tuple([z.object({}).passthrough(), z.unknown(), z.string()]),\n\t\t\t]),\n\t\t}),\n\t\tz.object({\n\t\t\tmethod: z.literal('go'),\n\t\t\targs: z.tuple([z.number().optional()]),\n\t\t}),\n\t\tz.object({ method: z.literal('forward'), args: z.tuple([]) }),\n\t\tz.object({ method: z.literal('back'), args: z.tuple([]) }),\n\t\tz.object({\n\t\t\tmethod: z.literal('popstate'),\n\t\t\tpathname: z.string(),\n\t\t\tdelta: z.number(),\n\t\t}),\n\t]),\n)\n\nconst loadedSchema = z.object({\n\ttype: z.literal('epicshop:loaded'),\n\turl: z.string(),\n})\n\nconst messageSchema = z.union([historyCallDataSchema, loadedSchema])\n\nfunction getNewIndex(prevIndex: number, delta: number, max: number) {\n\t// keep the index bound between 0 and the history length\n\treturn Math.min(Math.max(prevIndex + delta, 0), max)\n}\n\ntype Props = {\n\tid: string\n\tname: string\n\tport: number\n\tportIsAvailable: boolean | null\n\tisRunning: boolean\n\tbaseUrl: string\n\tinitialRoute: string\n}\n\nexport type InBrowserBrowserRef = {\n\thandleExtrnalNavigation: (pathname?: string) => void\n}\n\nexport const InBrowserBrowser = forwardRef<InBrowserBrowserRef, Props>(\n\tInBrowserBrowserImpl,\n)\n\nfunction InBrowserBrowserImpl(\n\t{ name, port, portIsAvailable, isRunning, baseUrl, id, initialRoute }: Props,\n\tref: ForwardedRef<InBrowserBrowserRef>,\n) {\n\tconst requestInfo = useRequestInfo()\n\treturn isRunning ? (\n\t\t<InBrowserBrowserForRealz\n\t\t\tbaseUrl={baseUrl}\n\t\t\tid={id}\n\t\t\tname={name}\n\t\t\tref={ref}\n\t\t\tinitialRoute={initialRoute}\n\t\t/>\n\t) : portIsAvailable === false ? (\n\t\t<div className=\"flex flex-col items-center justify-center\">\n\t\t\t<p className=\"max-w-xs pb-5 text-center\" role=\"status\">\n\t\t\t\t{`The port for this app is unavailable. It could be that you're running it `}\n\t\t\t\t<a\n\t\t\t\t\thref={getBaseUrl({ domain: requestInfo.domain, port })}\n\t\t\t\t\tclassName=\"underline\"\n\t\t\t\t>\n\t\t\t\t\telsewhere\n\t\t\t\t</a>\n\t\t\t\t?\n\t\t\t</p>\n\t\t\t<PortStopper port={port} />\n\t\t</div>\n\t) : (\n\t\t<AppStarter name={name} />\n\t)\n}\ntype RealBrowserProps = {\n\tbaseUrl: string\n\tid: string\n\tname: string\n\tinitialRoute: string\n}\n\nconst InBrowserBrowserForRealz = forwardRef<\n\tInBrowserBrowserRef,\n\tRealBrowserProps\n>(InBrowserBrowserForRealzImpl)\n\n// we're doing this to ensure all of this complex stuff doesn't happen unless\n// the iframe is actually rendered.\nfunction InBrowserBrowserForRealzImpl(\n\t{ baseUrl, id, name, initialRoute }: RealBrowserProps,\n\tref: ForwardedRef<InBrowserBrowserRef>,\n) {\n\tconst [searchParams, setSearchParams] = useSearchParams()\n\tconst searchParamsPathname = searchParams.get('pathname') ?? initialRoute\n\tconst [iframeKeyNumber, setIframeKeyNumber] = useState(0)\n\tconst iframeKey = id + iframeKeyNumber\n\tconst lastDirectionRef = useRef<'forward' | 'back' | 'new'>('new')\n\tconst lastDirectionTimeout = useRef<ReturnType<typeof setTimeout> | null>(\n\t\tnull,\n\t)\n\tconst [iframeContext, setIFrameContext] = useState({\n\t\thistory: [searchParamsPathname],\n\t\tindex: 0,\n\t})\n\tconst [pathnameInputValue, setPathnameInputValue] =\n\t\tuseState(searchParamsPathname)\n\tconst iframeRef = useRef<HTMLIFrameElement>(null)\n\n\tconst appUrl = new URL(searchParamsPathname, baseUrl)\n\tconst currentAppUrl = useRef(appUrl)\n\tuseEffect(() => {\n\t\tcurrentAppUrl.current = appUrl\n\t})\n\n\t/** changing the iframeSrcUrl will trigger a reload of the iframe */\n\tconst [iframeSrcUrl, setIframeSrcUrl] = useState(appUrl)\n\n\tconst currentId = useRef(id)\n\t// if the id changes, then we're going to reload the iframe, but we want to\n\t// make sure to preserve the pathname so we set the src to the current pathname\n\t// this is one of the few side-effects in render that are \"ok\"\n\tif (currentId.current !== id) {\n\t\tcurrentId.current = id\n\t\tsetIframeSrcUrl(currentAppUrl.current)\n\t}\n\tuseEffect(() => {\n\t\tcurrentId.current = id\n\t})\n\n\tuseEffect(() => {\n\t\tfunction handleMessage(messageEvent: MessageEvent) {\n\t\t\tif (messageEvent.source !== iframeRef.current?.contentWindow) return\n\n\t\t\tconst result = messageSchema.safeParse(messageEvent.data, {\n\t\t\t\tpath: ['messageEvent', 'data'],\n\t\t\t})\n\t\t\tif (!result.success) return\n\t\t\tconst { data } = result\n\n\t\t\tif (data.type === 'epicshop:loaded') {\n\t\t\t\tsetIFrameContext((prevContext) => {\n\t\t\t\t\tconst newIndex = (i: number) =>\n\t\t\t\t\t\tgetNewIndex(prevContext.index, i, prevContext.history.length - 1)\n\t\t\t\t\tif (lastDirectionRef.current === 'back') {\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(-1) }\n\t\t\t\t\t} else if (lastDirectionRef.current === 'forward') {\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(1) }\n\t\t\t\t\t} else if (lastDirectionRef.current === 'new') {\n\t\t\t\t\t\tconst currentPathname = prevContext.history[prevContext.index]\n\t\t\t\t\t\tconst newPathname = new URL(data.url).pathname\n\t\t\t\t\t\tif (currentPathname === newPathname) return prevContext\n\n\t\t\t\t\t\tconst newHistory = [\n\t\t\t\t\t\t\t...prevContext.history.slice(0, prevContext.index + 1),\n\t\t\t\t\t\t\tnewPathname,\n\t\t\t\t\t\t]\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\thistory: newHistory,\n\t\t\t\t\t\t\tindex: newHistory.length - 1,\n\t\t\t\t\t\t}\n\t\t\t\t\t} else {\n\t\t\t\t\t\tthrow new Error('Unexpected lastDirectionRef value')\n\t\t\t\t\t}\n\t\t\t\t})\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst { method } = data\n\t\t\tsetIFrameContext((prevContext) => {\n\t\t\t\tconst newIndex = (i: number) =>\n\t\t\t\t\tgetNewIndex(prevContext.index, i, prevContext.history.length - 1)\n\t\t\t\tconst currentPathname = prevContext.history[prevContext.index]\n\t\t\t\tswitch (method) {\n\t\t\t\t\tcase 'popstate': {\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(data.delta) }\n\t\t\t\t\t}\n\t\t\t\t\tcase 'forward': {\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(1) }\n\t\t\t\t\t}\n\t\t\t\t\tcase 'back': {\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(-1) }\n\t\t\t\t\t}\n\t\t\t\t\tcase 'pushState': {\n\t\t\t\t\t\tconst pathname = data.args[2] ?? currentPathname\n\t\t\t\t\t\tconst newHistory = [\n\t\t\t\t\t\t\t...prevContext.history.slice(0, prevContext.index + 1),\n\t\t\t\t\t\t\tpathname,\n\t\t\t\t\t\t].filter(Boolean)\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...prevContext,\n\t\t\t\t\t\t\thistory: newHistory,\n\t\t\t\t\t\t\tindex: newHistory.length - 1,\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'replaceState': {\n\t\t\t\t\t\tconst pathname = data.args[2] ?? currentPathname\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t...prevContext,\n\t\t\t\t\t\t\thistory: [\n\t\t\t\t\t\t\t\t...prevContext.history.slice(0, prevContext.index),\n\t\t\t\t\t\t\t\tpathname,\n\t\t\t\t\t\t\t\t...prevContext.history.slice(prevContext.index + 1),\n\t\t\t\t\t\t\t].filter(Boolean),\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t\tcase 'go': {\n\t\t\t\t\t\tconst [delta = 0] = data.args\n\t\t\t\t\t\treturn { ...prevContext, index: newIndex(delta) }\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t})\n\t\t}\n\t\twindow.addEventListener('message', handleMessage)\n\t\treturn () => {\n\t\t\twindow.removeEventListener('message', handleMessage)\n\t\t}\n\t}, [])\n\n\t// setSearchParams is unstable\n\t// https://github.com/remix-run/react-router/issues/9991\n\tconst setSearchParamsLatestRef = useRef(setSearchParams)\n\tuseEffect(() => {\n\t\tsetSearchParamsLatestRef.current = setSearchParams\n\t}, [setSearchParams])\n\n\tconst iframePathname = iframeContext.history[iframeContext.index]\n\tuseEffect(() => {\n\t\tif (!iframePathname) return\n\n\t\tsetPathnameInputValue(iframePathname)\n\n\t\tconst newSearchParams = new URLSearchParams(window.location.search)\n\t\tif (iframePathname === '/') {\n\t\t\tnewSearchParams.delete('pathname')\n\t\t} else {\n\t\t\tnewSearchParams.set('pathname', iframePathname)\n\t\t}\n\t\tconst newSearch = newSearchParams.toString()\n\t\tif (`?${newSearch}` !== window.location.search) {\n\t\t\tsetSearchParamsLatestRef.current(newSearchParams, { replace: true })\n\t\t}\n\t}, [iframePathname])\n\n\tconst navigateChild: NavigateFunction = (...params) => {\n\t\tconst to = params[0]\n\t\tif (typeof to === 'number') {\n\t\t\t// this part feels very brittle to me...\n\t\t\tlastDirectionRef.current = to > 0 ? 'forward' : 'back'\n\t\t} else {\n\t\t\tlastDirectionRef.current = 'new'\n\t\t}\n\t\tif (lastDirectionTimeout.current) {\n\t\t\tclearTimeout(lastDirectionTimeout.current)\n\t\t}\n\t\tlastDirectionTimeout.current = setTimeout(() => {\n\t\t\tlastDirectionRef.current = 'new'\n\t\t}, 100)\n\t\tiframeRef.current?.contentWindow?.postMessage(\n\t\t\t{ type: 'epicshop:navigate-call', params },\n\t\t\t'*',\n\t\t)\n\t}\n\n\tfunction handleExtrnalNavigation(\n\t\tnewPathnameInputValue: string = pathnameInputValue,\n\t) {\n\t\tsetPathnameInputValue(newPathnameInputValue)\n\n\t\tconst currentPathname = iframeContext.history[iframeContext.index]\n\t\tnavigateChild(newPathnameInputValue, {\n\t\t\treplace: currentPathname === newPathnameInputValue,\n\t\t})\n\t}\n\n\tuseImperativeHandle(ref, () => ({ handleExtrnalNavigation }))\n\n\tconst atEndOfHistory =\n\t\tiframeContext.index === iframeContext.history.length - 1\n\tconst atStartOfHistory = iframeContext.index <= 0\n\tconst existingSearchParamHiddenInputs: Array<React.ReactElement> = []\n\tfor (const [key, value] of searchParams.entries()) {\n\t\tif (key === 'pathname') continue\n\n\t\texistingSearchParamHiddenInputs.push(\n\t\t\t<input key={key} type=\"hidden\" name={key} value={value} />,\n\t\t)\n\t}\n\n\treturn (\n\t\t<TooltipProvider>\n\t\t\t<div className=\"flex h-full flex-grow flex-col\">\n\t\t\t\t<div className=\"flex items-center justify-between border-b pl-1.5\">\n\t\t\t\t\t<div className=\"mr-2 flex items-center justify-center gap-2 px-1\">\n\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"hidden aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40 sm:flex\"\n\t\t\t\t\t\t\t\t\tdisabled={atStartOfHistory}\n\t\t\t\t\t\t\t\t\tonClick={() => navigateChild(-1)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon name=\"ArrowLeft\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>Go back</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"hidden aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40 sm:flex\"\n\t\t\t\t\t\t\t\t\tdisabled={atEndOfHistory}\n\t\t\t\t\t\t\t\t\tonClick={() => navigateChild(1)}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon name=\"ArrowRight\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>Go forward</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t\t<button\n\t\t\t\t\t\t\t\t\ttype=\"button\"\n\t\t\t\t\t\t\t\t\tclassName=\"flex aspect-square h-full w-full items-center justify-center p-1 transition disabled:opacity-40\"\n\t\t\t\t\t\t\t\t\tonClick={() => {\n\t\t\t\t\t\t\t\t\t\tsetIframeSrcUrl(appUrl)\n\t\t\t\t\t\t\t\t\t\tsetIframeKeyNumber(iframeKeyNumber + 1)\n\t\t\t\t\t\t\t\t\t\t// TODO: figure out how we can avoid having to do this...\n\t\t\t\t\t\t\t\t\t\t// I stayed up for hours one night trying and couldn't work out\n\t\t\t\t\t\t\t\t\t\t// why react router wouldn't update the UI when using back/forward\n\t\t\t\t\t\t\t\t\t\t// after a refresh.\n\t\t\t\t\t\t\t\t\t\tsetIFrameContext({\n\t\t\t\t\t\t\t\t\t\t\thistory: [appUrl.pathname],\n\t\t\t\t\t\t\t\t\t\t\tindex: 0,\n\t\t\t\t\t\t\t\t\t\t})\n\t\t\t\t\t\t\t\t\t}}\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<Icon name=\"Refresh\" aria-hidden=\"true\" />\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t\t<TooltipContent>Refresh</TooltipContent>\n\t\t\t\t\t\t</Tooltip>\n\t\t\t\t\t</div>\n\t\t\t\t\t<Form\n\t\t\t\t\t\tmethod=\"get\"\n\t\t\t\t\t\treplace\n\t\t\t\t\t\tclassName=\"flex flex-1 gap-2\"\n\t\t\t\t\t\tonSubmit={() => handleExtrnalNavigation()}\n\t\t\t\t\t>\n\t\t\t\t\t\t{existingSearchParamHiddenInputs}\n\t\t\t\t\t\t<div className=\"flex flex-1 items-center border-x bg-background p-3 leading-none text-foreground\">\n\t\t\t\t\t\t\t<a href={appUrl.toString()} target=\"_blank\" rel=\"noreferrer\">\n\t\t\t\t\t\t\t\t{iframeSrcUrl.host}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t<input\n\t\t\t\t\t\t\t\taria-label=\"pathname\"\n\t\t\t\t\t\t\t\tclassName=\"w-full flex-1 bg-background focus-visible:outline-none\"\n\t\t\t\t\t\t\t\tvalue={pathnameInputValue}\n\t\t\t\t\t\t\t\tname=\"pathname\"\n\t\t\t\t\t\t\t\tonChange={(e) => setPathnameInputValue(e.currentTarget.value)}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t{/* TODO: Reconsider if this is needed as browsers don't usually have a submit button in address bar */}\n\t\t\t\t\t\t{/* <button type=\"submit\">Go</button> */}\n\t\t\t\t\t</Form>\n\t\t\t\t\t<AppStopper name={name} />\n\t\t\t\t\t<Tooltip>\n\t\t\t\t\t\t<TooltipTrigger asChild>\n\t\t\t\t\t\t\t<a\n\t\t\t\t\t\t\t\thref={appUrl.toString()}\n\t\t\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\t\t\tclassName={clsx(\n\t\t\t\t\t\t\t\t\t'flex aspect-square items-center justify-center px-3.5',\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<Icon name=\"ExternalLink\" />\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</TooltipTrigger>\n\t\t\t\t\t\t<TooltipContent>Open in new tab</TooltipContent>\n\t\t\t\t\t</Tooltip>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"flex h-full w-full flex-grow dark:bg-white\">\n\t\t\t\t\t<iframe\n\t\t\t\t\t\ttitle={name}\n\t\t\t\t\t\tkey={iframeKey}\n\t\t\t\t\t\tref={iframeRef}\n\t\t\t\t\t\tsrc={iframeSrcUrl.toString()}\n\t\t\t\t\t\tclassName=\"h-full w-full flex-grow bg-white\"\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</TooltipProvider>\n\t)\n}\n","import { type BaseExerciseStepApp } from '@epic-web/workshop-utils/apps.server'\nimport { useState } from 'react'\nimport { Icon } from '#app/components/icons'\nimport {\n\tInBrowserBrowser,\n\ttype InBrowserBrowserRef,\n} from '#app/components/in-browser-browser'\nimport { Loading } from '#app/components/loading.js'\nimport { useTheme } from '#app/routes/theme/index.js'\nimport { cn, getBaseUrl } from '#app/utils/misc'\nimport { useRequestInfo } from '#app/utils/request-info'\n\nexport function Preview({\n\tid,\n\tappInfo,\n\tinBrowserBrowserRef,\n}: {\n\tid?: string\n\tappInfo: {\n\t\tisRunning: boolean\n\t\tappName?: string\n\t\tname: string\n\t\ttitle: string\n\t\tportIsAvailable: boolean | null\n\t\ttype: string\n\t\tfullPath: string\n\t\tdev: BaseExerciseStepApp['dev']\n\t\ttest: BaseExerciseStepApp['test']\n\t\tstackBlitzUrl: BaseExerciseStepApp['stackBlitzUrl']\n\t} | null\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}) {\n\tconst requestInfo = useRequestInfo()\n\tconst theme = useTheme()\n\tif (!appInfo) return <p>No app here. Sorry.</p>\n\tconst { isRunning, dev, name, portIsAvailable, title } = appInfo\n\n\tif (ENV.EPICSHOP_DEPLOYED && appInfo.stackBlitzUrl) {\n\t\tconst url = new URL(appInfo.stackBlitzUrl)\n\t\turl.searchParams.set('embed', '1')\n\t\turl.searchParams.set('theme', theme)\n\n\t\treturn (\n\t\t\t<StackBlitzEmbed\n\t\t\t\ttitle={title}\n\t\t\t\turl={url.toString()}\n\t\t\t\tloadingContent={\n\t\t\t\t\t<Loading>\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\tLoading{' '}\n\t\t\t\t\t\t\t<a className=\"underline\" href={appInfo.stackBlitzUrl}>\n\t\t\t\t\t\t\t\t\"{title}\"\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Loading>\n\t\t\t\t}\n\t\t\t/>\n\t\t)\n\t}\n\n\tif (dev.type === 'script') {\n\t\tconst baseUrl = getBaseUrl({\n\t\t\tdomain: requestInfo.domain,\n\t\t\tport: dev.portNumber,\n\t\t})\n\t\treturn (\n\t\t\t<InBrowserBrowser\n\t\t\t\tref={inBrowserBrowserRef}\n\t\t\t\tisRunning={isRunning}\n\t\t\t\tid={id ?? name}\n\t\t\t\tname={name}\n\t\t\t\tportIsAvailable={portIsAvailable}\n\t\t\t\tport={dev.portNumber}\n\t\t\t\tbaseUrl={baseUrl}\n\t\t\t\tinitialRoute={dev.initialRoute}\n\t\t\t/>\n\t\t)\n\t} else if (dev.type === 'browser') {\n\t\treturn (\n\t\t\t<div className=\"relative h-full flex-grow overflow-y-auto scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t<a\n\t\t\t\t\thref={dev.pathname}\n\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\tclassName={cn(\n\t\t\t\t\t\t'absolute bottom-5 right-5 flex items-center justify-center rounded-full bg-gray-100 p-2.5 transition hover:bg-gray-200 dark:bg-gray-800 hover:dark:bg-gray-600',\n\t\t\t\t\t)}\n\t\t\t\t>\n\t\t\t\t\t<Icon name=\"ExternalLink\" aria-hidden=\"true\" />\n\t\t\t\t\t<span className=\"sr-only\">Open in New Window</span>\n\t\t\t\t</a>\n\t\t\t\t<iframe\n\t\t\t\t\ttitle={title}\n\t\t\t\t\tsrc={dev.pathname}\n\t\t\t\t\tclassName=\"h-full w-full flex-grow bg-white\"\n\t\t\t\t/>\n\t\t\t</div>\n\t\t)\n\t} else {\n\t\treturn (\n\t\t\t<div className=\"flex h-full items-center justify-center text-lg\">\n\t\t\t\t<p>\n\t\t\t\t\tPreview for dev type of <code>{dev.type}</code> not supported.\n\t\t\t\t</p>\n\t\t\t</div>\n\t\t)\n\t}\n}\n\nexport function StackBlitzEmbed({\n\turl,\n\ttitle,\n\tloadingContent,\n}: {\n\turl: string\n\ttitle?: string\n\tloadingContent: React.ReactNode\n}) {\n\tconst [iframeLoaded, setIframeLoaded] = useState(false)\n\n\treturn (\n\t\t<div className=\"h-full w-full flex-grow\">\n\t\t\t{iframeLoaded ? null : (\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t{loadingContent}\n\t\t\t\t</div>\n\t\t\t)}\n\t\t\t<iframe\n\t\t\t\tonLoad={() => setIframeLoaded(true)}\n\t\t\t\t// show what would have shown if there is an error\n\t\t\t\tonError={() => setIframeLoaded(true)}\n\t\t\t\tsrc={url}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'h-full w-full flex-grow transition-opacity duration-300',\n\t\t\t\t\tiframeLoaded ? 'opacity-100' : 'opacity-0',\n\t\t\t\t)}\n\t\t\t\ttitle={title}\n\t\t\t\tsandbox=\"allow-forms allow-scripts allow-same-origin allow-popups allow-popups-to-escape-sandbox\"\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["AppStopper","name","fetcher","useFetcher","peRedirectInput","usePERedirectInput","inFlightIntent","formData","get","inFlightState","altDown","useAltDown","Form","method","action","children","showProgressBarField","type","value","jsx","className","PortStopper","port","Button","varient","state","AppStarter","data","status","error","Loading","historyCallDataSchema","z","loadedSchema","messageSchema","getNewIndex","prevIndex","delta","max","InBrowserBrowser","forwardRef","InBrowserBrowserImpl","portIsAvailable","isRunning","baseUrl","id","initialRoute","ref","requestInfo","useRequestInfo","InBrowserBrowserForRealz","jsxs","getBaseUrl","InBrowserBrowserForRealzImpl","searchParams","setSearchParams","useSearchParams","searchParamsPathname","iframeKeyNumber","setIframeKeyNumber","useState","iframeKey","lastDirectionRef","useRef","lastDirectionTimeout","iframeContext","setIFrameContext","pathnameInputValue","setPathnameInputValue","iframeRef","appUrl","currentAppUrl","useEffect","iframeSrcUrl","setIframeSrcUrl","currentId","handleMessage","messageEvent","_a","result","prevContext","newIndex","i","currentPathname","newPathname","newHistory","pathname","setSearchParamsLatestRef","iframePathname","newSearchParams","navigateChild","params","to","_b","handleExtrnalNavigation","newPathnameInputValue","useImperativeHandle","atEndOfHistory","atStartOfHistory","existingSearchParamHiddenInputs","key","TooltipProvider","Tooltip","TooltipTrigger","Icon","TooltipContent","e","clsx","Preview","appInfo","inBrowserBrowserRef","theme","useTheme","dev","title","url","StackBlitzEmbed","cn","loadingContent","iframeLoaded","setIframeLoaded"],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- import{j as t}from"./index-1cKOJFpX.js";import{T as r}from"./tests-DmimqC1q.js";import{u as p}from"./components-CME-nGId.js";import"./epic-video-BFcdejfC.js";import"./index-DlJAkutV.js";import"./request-info-CEhUGODY.js";import"./misc-Txs7O6JX.js";import"./tooltip-DTFU8ajx.js";import"./pe-CUZaIcdt.js";import"./loading-CF7oQHQf.js";import"./user-DvujSs-t.js";import"./workshop-config-CL4F08kr.js";import"./accordion-CKwXYK9L.js";import"./index-9dWszLxO.js";import"./index-j_VpxCZh.js";import"./use-event-source-A_0lEOPX.js";import"./set-playground-Cr0qL9N9.js";import"./progress-bar-bUuKn1Q8.js";function A(){const{appInfo:o}=p();return t.jsx(r,{playgroundAppInfo:o})}export{A as default};
2
- //# sourceMappingURL=test-Cy-fo6gv.js.map