@epic-web/workshop-app 6.50.2 → 6.50.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/client/assets/_layout-COy4UuFj.js +2 -0
- package/build/client/assets/_layout-COy4UuFj.js.map +1 -0
- package/build/client/assets/{app-Wqtaq0if.js → app-B-WYurXM.js} +2 -2
- package/build/client/assets/{app-Wqtaq0if.js.map → app-B-WYurXM.js.map} +1 -1
- package/build/client/assets/{index-auYYjXx0.js → index-CDG5ZZjr.js} +2 -2
- package/build/client/assets/{index-auYYjXx0.js.map → index-CDG5ZZjr.js.map} +1 -1
- package/build/client/assets/{manifest-2ee52cac.js → manifest-940d9817.js} +1 -1
- package/build/client/assets/{preview-CuS2jg4z.js → preview-CqV1y1NY.js} +2 -2
- package/build/client/assets/{preview-CuS2jg4z.js.map → preview-CqV1y1NY.js.map} +1 -1
- package/build/client/export-app.css +558 -0
- package/build/server/index.js +391 -16
- package/build/server/index.js.map +1 -1
- package/package.json +3 -3
- package/build/client/assets/_layout-Bm8WMscw.js +0 -2
- package/build/client/assets/_layout-Bm8WMscw.js.map +0 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{b as w,g as ae,L as j,A as le,w as ce,a as pe,O as ue}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{E as de}from"./index-BwZqB-mh.js";import{r as l}from"./index-Az39ZADK.js";import{G as me}from"./error-boundary-C8da5z08.js";import{N as fe}from"./nav-chevrons-Q_xwzgQq.js";import{u as xe}from"./revalidation-ws-BahUMYqf.js";import{L as C,E as he}from"./launch-editor-FcTaA5kv.js";import{P as ve}from"./progress-DJ4oeyzx.js";import{S as H}from"./set-playground-kIjHv9mG.js";import{l as ge,c as F,I as D,o as Pe,m as je}from"./misc-BapXpylh.js";import{a as be,g as Ne}from"./root-loader-C5P2c7MU.js";import{g as Ee}from"./seo-t5J-DRxw.js";import{E as we}from"./error-boundary-ChRytjv2.js";import{E as ye}from"./epic-video-DQNGJhVF.js";import{S as k,d as U,u as Se,R as Ce,e as Re,f as Oe,g as B,P as V,h as E,A as Y,i as G,j as Ae,D as De,C as ke,k as Le}from"./tooltip-C2AQeNhD.js";import{M as _e}from"./mdx-C_z6TweY.js";import{P as Ie,h as Te,R as $e,u as Fe,F as Me}from"./index-Cod-PQ6D.js";import"./preload-helper-BXl3LOEh.js";import"./types-Cl2NuNg4.js";import"./progress-bar-D66irkpP.js";import"./pe-Bs-DFNma.js";import"./index--z_DgN94.js";import"./index-CjiomtK6.js";import"./chunk-JG3XND5A-pL43G3x8.js";import"./index-_LzGTKVC.js";import"./online-Dw7HU4wM.js";import"./loading-DyvhEH4Q.js";import"./user-DtZkTMil.js";import"./workshop-config-DCYN9tG7.js";import"./index-Dd9cSrtE.js";const q=l.createContext(null);function He(){const t=l.useContext(q);if(!t)throw new Error("useStepContext must be used within a StepContextProvider");return t}function Ue({children:t,inBrowserBrowserRef:r}){return e.jsx(q,{value:{inBrowserBrowserRef:r},children:t})}const Be={DiffLink:L,PrevDiffLink:Ge,NextDiffLink:Ye,InlineFile:qe,LinkToApp:ze};function Ve({inBrowserBrowserRef:t}){const r=w();return r.exerciseStepApp.instructionsCode?e.jsx(Ue,{inBrowserBrowserRef:t,children:e.jsx(ye,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(_e,{code:r.exerciseStepApp.instructionsCode,components:Be})})})}):null}function X(t,r,o){const i=new URLSearchParams(t);return o===null?i.delete(r):i.set(r,o),i}function Ye({app:t=0,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function Ge({app:t=-1,fullPage:r=!1,children:o}){return e.jsx(L,{app1:t,app2:t+1,fullPage:r,children:o})}function L({app1:t=0,app2:r=1,children:o,fullPage:i=!1,to:n}){const s=w();if(!n&&!t&&!r)return e.jsx("callout-danger",{className:"notification",children:e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"})});function a(u){if(typeof u=="number"){const m=s.exerciseIndex+u;return s.allApps[m]?.name}if(!u)return null;for(const{name:m,stepName:d}of s.allApps)if(u===m||u===d)return m;return null}if(n){const u=new URLSearchParams(n);t=u.get("app1"),r=u.get("app2")}const c=a(t),p=a(r);if(!c||!p)return e.jsxs("callout-danger",{className:"notification",children:[e.jsx("div",{className:"title",children:"DiffLink Error: invalid input"}),!c&&e.jsxs("div",{children:['app1: "',t,'" is not a valid app name']}),!p&&e.jsxs("div",{children:['app2: "',r,'" is not a valid app name']})]});n||(n=`app1=${c}&app2=${p}`);const f=i?`/diff?${n}`:`?${decodeURIComponent(X(new URLSearchParams,"preview",`diff&${n}`).toString())}`;return o||(o=e.jsxs("span",{children:["Go to Diff ",i?"":"Preview"," from: ",e.jsx("code",{children:c})," to:"," ",e.jsx("code",{children:p})]})),e.jsx(j,{to:f,children:o})}function qe({file:t,type:r="playground",children:o=e.jsx("code",{children:t}),...i}){const n=w(),s=n[r]||n[n.type],a=e.jsxs("div",{className:"launch-editor-button-wrapper flex underline underline-offset-4",children:[o," ",e.jsx("svg",{height:24,width:24,children:e.jsx("use",{href:`${Pe}#Keyboard`})})]});return ENV.EPICSHOP_DEPLOYED&&s?e.jsx("div",{className:"inline-block grow",children:e.jsx(C,{appFile:t,appName:s.name,...i,children:a})}):s?e.jsx("div",{className:"inline-block grow",children:e.jsx(C,{appFile:t,appName:s.name,...i,children:a})}):r==="playground"?e.jsx(k,{content:"You must 'Set to Playground' before opening a file",children:e.jsx("div",{className:"inline-block grow cursor-not-allowed",children:a})}):e.jsx(e.Fragment,{children:"children"})}function Xe(t){return t==="problem"?"problem":t==="solution"?"solution":"playground"}function ze({to:t,children:r=e.jsx("code",{children:t.toString()}),...o}){const[i]=ae(),n=`?${X(i,"pathname",t.toString()).toString()}`,s=w(),a=Xe(i.get("preview")),c=be(),p=s[a],f=p?.dev.type==="script"?ge({domain:c.domain,port:p.dev.portNumber}):s.playground?.dev.type==="browser"||s.playground?.dev.type==="export"?s.playground.dev.pathname:null,{inBrowserBrowserRef:u}=He(),m=f?f.slice(0,-1)+t.toString():null;return e.jsxs("div",{className:"inline-flex items-center justify-between gap-1",children:[e.jsx(j,{to:n,...o,className:F(o.className,{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":void 0,onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault(),o.onClick?.(d),u.current?.handleExtrnalNavigation(t.toString())},children:r}),m?e.jsx(k,{content:"Open in new tab",children:e.jsx("a",{href:m,target:"_blank",rel:"noreferrer",className:F("flex aspect-square items-center justify-center",{"cursor-not-allowed":ENV.EPICSHOP_DEPLOYED}),title:ENV.EPICSHOP_DEPLOYED?"Cannot link to app in deployed version":"Open in new tab",onClick:d=>{ENV.EPICSHOP_DEPLOYED&&d.preventDefault()},children:e.jsx(D,{name:"ExternalLink"})})}):null]})}var R="Popover",[z]=Re(R,[U]),y=U(),[We,v]=z(R),W=t=>{const{__scopePopover:r,children:o,open:i,defaultOpen:n,onOpenChange:s,modal:a=!1}=t,c=y(r),p=l.useRef(null),[f,u]=l.useState(!1),[m,d]=Se({prop:i,defaultProp:n??!1,onChange:s,caller:R});return e.jsx(Ce,{...c,children:e.jsx(We,{scope:r,contentId:Oe(),triggerRef:p,open:m,onOpenChange:d,onOpenToggle:l.useCallback(()=>d(x=>!x),[d]),hasCustomAnchor:f,onCustomAnchorAdd:l.useCallback(()=>u(!0),[]),onCustomAnchorRemove:l.useCallback(()=>u(!1),[]),modal:a,children:o})})};W.displayName=R;var K="PopoverAnchor",Ke=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(K,o),s=y(o),{onCustomAnchorAdd:a,onCustomAnchorRemove:c}=n;return l.useEffect(()=>(a(),()=>c()),[a,c]),e.jsx(Y,{...s,...i,ref:r})});Ke.displayName=K;var Q="PopoverTrigger",Z=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(Q,o),s=y(o),a=B(r,n.triggerRef),c=e.jsx(V.button,{type:"button","aria-haspopup":"dialog","aria-expanded":n.open,"aria-controls":n.contentId,"data-state":oe(n.open),...i,ref:a,onClick:E(t.onClick,n.onOpenToggle)});return n.hasCustomAnchor?c:e.jsx(Y,{asChild:!0,...s,children:c})});Z.displayName=Q;var _="PopoverPortal",[Qe,Ze]=z(_,{forceMount:void 0}),J=t=>{const{__scopePopover:r,forceMount:o,children:i,container:n}=t,s=v(_,r);return e.jsx(Qe,{scope:r,forceMount:o,children:e.jsx(G,{present:o||s.open,children:e.jsx(Ie,{asChild:!0,container:n,children:i})})})};J.displayName=_;var b="PopoverContent",ee=l.forwardRef((t,r)=>{const o=Ze(b,t.__scopePopover),{forceMount:i=o.forceMount,...n}=t,s=v(b,t.__scopePopover);return e.jsx(G,{present:i||s.open,children:s.modal?e.jsx(et,{...n,ref:r}):e.jsx(tt,{...n,ref:r})})});ee.displayName=b;var Je=Ae("PopoverContent.RemoveScroll"),et=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(null),n=B(r,i),s=l.useRef(!1);return l.useEffect(()=>{const a=i.current;if(a)return Te(a)},[]),e.jsx($e,{as:Je,allowPinchZoom:!0,children:e.jsx(te,{...t,ref:n,trapFocus:o.open,disableOutsidePointerEvents:!0,onCloseAutoFocus:E(t.onCloseAutoFocus,a=>{a.preventDefault(),s.current||o.triggerRef.current?.focus()}),onPointerDownOutside:E(t.onPointerDownOutside,a=>{const c=a.detail.originalEvent,p=c.button===0&&c.ctrlKey===!0,f=c.button===2||p;s.current=f},{checkForDefaultPrevented:!1}),onFocusOutside:E(t.onFocusOutside,a=>a.preventDefault(),{checkForDefaultPrevented:!1})})})}),tt=l.forwardRef((t,r)=>{const o=v(b,t.__scopePopover),i=l.useRef(!1),n=l.useRef(!1);return e.jsx(te,{...t,ref:r,trapFocus:!1,disableOutsidePointerEvents:!1,onCloseAutoFocus:s=>{t.onCloseAutoFocus?.(s),s.defaultPrevented||(i.current||o.triggerRef.current?.focus(),s.preventDefault()),i.current=!1,n.current=!1},onInteractOutside:s=>{t.onInteractOutside?.(s),s.defaultPrevented||(i.current=!0,s.detail.originalEvent.type==="pointerdown"&&(n.current=!0));const a=s.target;o.triggerRef.current?.contains(a)&&s.preventDefault(),s.detail.originalEvent.type==="focusin"&&n.current&&s.preventDefault()}})}),te=l.forwardRef((t,r)=>{const{__scopePopover:o,trapFocus:i,onOpenAutoFocus:n,onCloseAutoFocus:s,disableOutsidePointerEvents:a,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:f,onInteractOutside:u,...m}=t,d=v(b,o),x=y(o);return Fe(),e.jsx(Me,{asChild:!0,loop:!0,trapped:i,onMountAutoFocus:n,onUnmountAutoFocus:s,children:e.jsx(De,{asChild:!0,disableOutsidePointerEvents:a,onInteractOutside:u,onEscapeKeyDown:c,onPointerDownOutside:p,onFocusOutside:f,onDismiss:()=>d.onOpenChange(!1),children:e.jsx(ke,{"data-state":oe(d.open),role:"dialog",id:d.contentId,...x,...m,ref:r,style:{...m.style,"--radix-popover-content-transform-origin":"var(--radix-popper-transform-origin)","--radix-popover-content-available-width":"var(--radix-popper-available-width)","--radix-popover-content-available-height":"var(--radix-popper-available-height)","--radix-popover-trigger-width":"var(--radix-popper-anchor-width)","--radix-popover-trigger-height":"var(--radix-popper-anchor-height)"}})})})}),re="PopoverClose",rt=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=v(re,o);return e.jsx(V.button,{type:"button",...i,ref:r,onClick:E(t.onClick,()=>n.onOpenChange(!1))})});rt.displayName=re;var ot="PopoverArrow",nt=l.forwardRef((t,r)=>{const{__scopePopover:o,...i}=t,n=y(o);return e.jsx(Le,{...n,...i,ref:r})});nt.displayName=ot;function oe(t){return t?"open":"closed"}var st=W,it=Z,at=J,lt=ee;function ct({diffFilesPromise:t,compact:r=!1}){const o=w(),[i,n]=l.useState(!1),s=l.useRef(null);function a(){n(!1)}const c=o.playground?.appName;return e.jsx(e.Fragment,{children:e.jsxs(st,{open:i,onOpenChange:n,children:[e.jsx(it,{asChild:!0,children:e.jsxs("button",{className:"flex h-full items-center gap-1 border-r px-6 py-3 font-mono text-sm uppercase","aria-label":"Relevant Files",children:[e.jsx(D,{name:"Files"}),r?null:e.jsx("span",{className:"hidden xl:inline",children:"Files"})]})}),e.jsx(at,{children:e.jsx(lt,{ref:s,className:"slideRightContent lg:slideUpContent invert-theme bg-background text-foreground z-10 rounded px-9 py-8 select-none",align:"start",sideOffset:5,children:e.jsxs("div",{className:"launch-editor-wrapper",children:[e.jsx("strong",{className:"inline-block px-2 pb-4 font-semibold uppercase",children:"Relevant Files"}),o.problem&&o.playground?.appName!==o.problem.name?e.jsx("div",{className:"mb-2 rounded p-1 font-mono font-medium",children:e.jsx(H,{appName:o.problem.name})}):null,e.jsx("div",{id:"files",children:e.jsx(l.Suspense,{fallback:e.jsx(k,{content:"Loading diff",children:e.jsx("div",{className:"flex justify-center",children:e.jsx(D,{name:"Refresh",className:"h-8 w-8 animate-spin"})})}),children:e.jsx(le,{resolve:t,errorElement:e.jsx("div",{className:"text-foreground-destructive",children:"Something went wrong."}),children:p=>{if(!p)return e.jsx("p",{className:"text-foreground-destructive",children:"Unable to determine diff"});if(typeof p=="string")return e.jsx("p",{className:"text-foreground-destructive",children:p});if(!p.length)return e.jsx("p",{children:"No files changed"});const f=c||ENV.EPICSHOP_GITHUB_ROOT?{}:{title:"You must 'Set to Playground' before opening a file",className:"not-allowed"};return e.jsxs("ul",{...f,children:[p.length>1&&!ENV.EPICSHOP_DEPLOYED?e.jsx("div",{className:"border-opacity-50 mb-2 border-b border-b-gray-50 pb-2 font-sans",children:e.jsx(C,{appFile:p.map(u=>`${u.path},${u.line},1`),appName:"playground",onUpdate:a,children:e.jsx("p",{children:"Open All Files"})})}):null,p.map(u=>e.jsx("li",{"data-state":u.status,children:e.jsx(C,{appFile:`${u.path},${u.line},1`,appName:ENV.EPICSHOP_DEPLOYED?o.problem?.name??"playground":"playground",onUpdate:a,children:e.jsx("code",{children:u.path})})},u.path))]})}})})})]})})})]})})}const pt="es_split_pct";function M(t,r=50){const o=typeof t=="number"?t:Number(t);return Number.isFinite(o)?Math.min(80,Math.max(20,Math.round(o*100)/100)):r}function ne(t,r){const o=t?.exerciseStepApp.exerciseNumber.toString().padStart(2,"0")??"00",i=t?.exerciseStepApp.stepNumber.toString().padStart(2,"0")??"00",n={problem:"💪",solution:"🏁"}[t?.type??"problem"],s=t?.[t.type]?.title??"N/A";return{emoji:n,stepNumber:i,title:s,exerciseNumber:o,exerciseTitle:t?.exerciseTitle??"Unknown exercise",workshopTitle:r,type:t?.type??"problem"}}const Bt=({loaderData:t,matches:r,params:o})=>{const i=Ne(r);if(!t||!i)return[{title:"🦉 | Error"}];const{emoji:n,stepNumber:s,title:a,exerciseNumber:c,exerciseTitle:p}=ne(t);return Ee({title:`${n} | ${s}. ${a} | ${c}. ${p} | ${i.workshopTitle}`,description:`${o.type} step for exercise ${c}. ${p}`,ogTitle:a,ogDescription:`${p} step ${Number(s)} ${o.type}`,instructor:i.instructor,requestInfo:i.requestInfo})},Vt=ce(function({loaderData:r}){const o=l.useRef(null),i=l.useRef(null),n=l.useRef(null),[s,a]=l.useState(r.splitPercent),[c,p]=l.useState(0);l.useEffect(()=>{const d=n.current;if(!d)return;const x=new ResizeObserver(S=>{for(const g of S)p(g.contentRect.width)});return x.observe(d),p(d.getBoundingClientRect().width),()=>x.disconnect()},[]);function f(d){const x=M(d);document.cookie=`${pt}=${x}; path=/; SameSite=Lax;`}function u(d){const x=i.current;if(!x)return;const S=x.getBoundingClientRect();let g=!0;const O=Array.from(document.querySelectorAll("iframe")),se=O.map(h=>h.style.pointerEvents);O.forEach(h=>h.style.pointerEvents="none");function A(h){if(!g){P();return}const ie=(h-S.left)/S.width*100,$=M(ie);a($),f($)}function I(h){if(!g||h.buttons===0){P();return}A(h.clientX)}function T(h){const N=h.touches?.[0];if(!g||!N){P();return}A(N.clientX)}function P(){g&&(g=!1,O.forEach((h,N)=>h.style.pointerEvents=se[N]??""),window.removeEventListener("mousemove",I),window.removeEventListener("mouseup",P),window.removeEventListener("touchmove",T),window.removeEventListener("touchend",P),document.body.style.cursor="",document.body.style.userSelect="")}window.addEventListener("mousemove",I),window.addEventListener("mouseup",P),window.addEventListener("touchmove",T),window.addEventListener("touchend",P),document.body.style.cursor="col-resize",document.body.style.userSelect="none",A(d)}const m=ne(r);return xe({watchPaths:[`${r.exerciseStepApp.relativePath}/README.mdx`]}),e.jsx("div",{className:"flex max-w-full grow flex-col",children:e.jsxs("main",{ref:i,className:"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row",children:[e.jsxs("div",{className:"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)",style:{"--split-pct":`${s}%`},ref:n,children:[e.jsx("h1",{className:"h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium",children:e.jsxs("div",{className:"flex h-14 items-center justify-between gap-x-2 overflow-x-auto py-2 whitespace-nowrap",children:[e.jsxs("div",{className:"flex items-center justify-start gap-x-2 uppercase",children:[e.jsxs(j,{to:je(r.exerciseStepApp.exerciseNumber),className:"hover:underline",children:[m.exerciseNumber,". ",m.exerciseTitle]}),"/",e.jsxs(j,{to:".",className:"hover:underline",children:[m.stepNumber,". ",m.title," (",m.emoji," ",m.type,")"]})]}),r.problem&&(r.playground?.appName!==r.problem.name||!r.playground?.isUpToDate)?e.jsx("div",{className:"hidden md:block",children:e.jsx(H,{appName:r.problem.name,isOutdated:r.playground?.isUpToDate===!1})}):null]})}),e.jsxs("article",{id:r.articleId,className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8",children:[r.exerciseStepApp.instructionsCode?e.jsx(Ve,{inBrowserBrowserRef:o}):e.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:e.jsx("p",{children:"No instructions yet..."})}),e.jsxs("div",{className:"mt-auto flex justify-between",children:[r.prevStepLink?e.jsxs(j,{to:r.prevStepLink.to,"aria-label":"Previous Step","data-keyboard-action":"g+p",prefetch:"intent",children:[e.jsx("span",{"aria-hidden":!0,children:"←"}),e.jsx("span",{className:"hidden xl:inline",children:" Previous"})]}):e.jsx("span",{}),r.nextStepLink?e.jsxs(j,{to:r.nextStepLink.to,"aria-label":"Next Step","data-keyboard-action":"g+n",prefetch:"intent",children:[e.jsx("span",{className:"hidden xl:inline",children:"Next "}),e.jsx("span",{"aria-hidden":!0,children:"→"})]}):e.jsx("span",{})]})]},r.articleId),e.jsx(de,{elementQuery:`#${r.articleId}`},`scroll-${r.articleId}`),r.type==="solution"?e.jsx(ve,{type:"step",exerciseNumber:r.exerciseStepApp.exerciseNumber,stepNumber:r.exerciseStepApp.stepNumber,className:"h-14 border-t px-6"}):null,e.jsxs("div",{className:"flex h-16 justify-between border-t border-b-4 lg:border-b-0",children:[e.jsx("div",{children:e.jsx("div",{className:"h-full",children:e.jsx(ct,{diffFilesPromise:r.diffFiles,compact:c<640})})}),e.jsx(he,{appName:r.exerciseStepApp.name,relativePath:`${r.exerciseStepApp.relativePath}/README.mdx`,compact:c<720}),e.jsx(fe,{prev:r.prevStepLink?{to:r.prevStepLink.to,"aria-label":"Previous Step"}:null,next:r.nextStepLink?{to:r.nextStepLink.to,"aria-label":"Next Step"}:null})]})]}),e.jsx("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",className:"bg-border hover:bg-accent hidden w-1 cursor-col-resize lg:block",onMouseDown:d=>u(d.clientX),onDoubleClick:()=>{a(50),f(50)},onTouchStart:d=>{const x=d.touches?.[0];x&&u(x.clientX)}}),e.jsx("div",{className:"flex min-w-0 flex-1",children:e.jsx(ue,{context:{inBrowserBrowserRef:o}})})]})})}),Yt=pe(function(){return e.jsx(me,{className:"container flex items-center justify-center",statusHandlers:{404:we}})});export{Yt as ErrorBoundary,Vt as default,Bt as meta};
|
|
2
|
+
//# sourceMappingURL=_layout-COy4UuFj.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"_layout-COy4UuFj.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/step-mdx.tsx","../../../../../node_modules/@radix-ui/react-popover/dist/index.mjs","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/touched-files.tsx","../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout.tsx"],"sourcesContent":["import * as React from 'react'\nimport { type PropsWithChildren } from 'react'\nimport {\n\tLink,\n\tuseLoaderData,\n\tuseSearchParams,\n\ttype LinkProps,\n} from 'react-router'\nimport iconsSvg from '#app/assets/icons.svg'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { LaunchEditor } from '#app/routes/launch-editor.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn, getBaseUrl } from '#app/utils/misc.tsx'\nimport { useRequestInfo } from '#app/utils/root-loader.ts'\nimport { type loader } from '../_layout.tsx'\n\ntype StepContextType = {\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}\nconst StepContext = React.createContext<StepContextType | null>(null)\n\nfunction useStepContext() {\n\tconst context = React.useContext(StepContext)\n\tif (!context) {\n\t\tthrow new Error('useStepContext must be used within a StepContextProvider')\n\t}\n\treturn context\n}\n\nfunction StepContextProvider({\n\tchildren,\n\tinBrowserBrowserRef,\n}: {\n\tchildren: React.ReactNode\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}) {\n\treturn <StepContext value={{ inBrowserBrowserRef }}>{children}</StepContext>\n}\n\nconst stepMdxComponents = {\n\tDiffLink,\n\tPrevDiffLink,\n\tNextDiffLink,\n\tInlineFile,\n\tLinkToApp,\n}\n\nexport function StepMdx({\n\tinBrowserBrowserRef,\n}: {\n\tinBrowserBrowserRef: React.RefObject<InBrowserBrowserRef | null>\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tif (!data.exerciseStepApp.instructionsCode) return null\n\treturn (\n\t\t<StepContextProvider inBrowserBrowserRef={inBrowserBrowserRef}>\n\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={data.epicVideoInfosPromise}>\n\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t<Mdx\n\t\t\t\t\t\tcode={data.exerciseStepApp.instructionsCode}\n\t\t\t\t\t\tcomponents={stepMdxComponents}\n\t\t\t\t\t/>\n\t\t\t\t</div>\n\t\t\t</EpicVideoInfoProvider>\n\t\t</StepContextProvider>\n\t)\n}\n\nfunction withParam(\n\tsearchParams: URLSearchParams,\n\tkey: string,\n\tvalue: string | null,\n) {\n\tconst newSearchParams = new URLSearchParams(searchParams)\n\tif (value === null) {\n\t\tnewSearchParams.delete(key)\n\t} else {\n\t\tnewSearchParams.set(key, value)\n\t}\n\treturn newSearchParams\n}\n\nfunction NextDiffLink({\n\tapp = 0,\n\tfullPage = false,\n\tchildren,\n}: {\n\tapp: number\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\treturn (\n\t\t<DiffLink app1={app} app2={app + 1} fullPage={fullPage}>\n\t\t\t{children}\n\t\t</DiffLink>\n\t)\n}\n\nfunction PrevDiffLink({\n\tapp = -1,\n\tfullPage = false,\n\tchildren,\n}: {\n\tapp: number\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\treturn (\n\t\t<DiffLink app1={app} app2={app + 1} fullPage={fullPage}>\n\t\t\t{children}\n\t\t</DiffLink>\n\t)\n}\n\nfunction DiffLink({\n\tapp1 = 0,\n\tapp2 = 1,\n\tchildren,\n\tfullPage = false,\n\tto,\n}: {\n\tapp1?: string | number | null\n\tapp2?: string | number | null\n\tto?: string\n\tfullPage?: boolean\n\tchildren?: React.ReactNode\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tif (!to && !app1 && !app2) {\n\t\treturn (\n\t\t\t<callout-danger className=\"notification\">\n\t\t\t\t<div className=\"title\">DiffLink Error: invalid input</div>\n\t\t\t</callout-danger>\n\t\t)\n\t}\n\n\tfunction getAppName(input: typeof app1) {\n\t\tif (typeof input === 'number') {\n\t\t\tconst stepIndex = data.exerciseIndex + input\n\t\t\treturn data.allApps[stepIndex]?.name\n\t\t}\n\t\tif (!input) return null\n\t\tfor (const { name, stepName } of data.allApps) {\n\t\t\tif (input === name || input === stepName) {\n\t\t\t\treturn name\n\t\t\t}\n\t\t}\n\t\treturn null\n\t}\n\n\tif (to) {\n\t\tconst params = new URLSearchParams(to)\n\t\tapp1 = params.get('app1')\n\t\tapp2 = params.get('app2')\n\t}\n\tconst app1Name = getAppName(app1)\n\tconst app2Name = getAppName(app2)\n\tif (!app1Name || !app2Name) {\n\t\treturn (\n\t\t\t<callout-danger className=\"notification\">\n\t\t\t\t<div className=\"title\">DiffLink Error: invalid input</div>\n\t\t\t\t{!app1Name && <div>app1: \"{app1}\" is not a valid app name</div>}\n\t\t\t\t{!app2Name && <div>app2: \"{app2}\" is not a valid app name</div>}\n\t\t\t</callout-danger>\n\t\t)\n\t}\n\n\tif (!to) {\n\t\tto = `app1=${app1Name}&app2=${app2Name}`\n\t}\n\tconst pathToDiff = fullPage\n\t\t? `/diff?${to}`\n\t\t: `?${decodeURIComponent(\n\t\t\t\twithParam(new URLSearchParams(), 'preview', `diff&${to}`).toString(),\n\t\t\t)}`\n\n\tif (!children) {\n\t\tchildren = (\n\t\t\t<span>\n\t\t\t\tGo to Diff {fullPage ? '' : 'Preview'} from: <code>{app1Name}</code> to:{' '}\n\t\t\t\t<code>{app2Name}</code>\n\t\t\t</span>\n\t\t)\n\t}\n\n\treturn <Link to={pathToDiff}>{children}</Link>\n}\n\nfunction InlineFile({\n\tfile,\n\ttype = 'playground',\n\tchildren = <code>{file}</code>,\n\t...props\n}: Omit<PropsWithChildren<typeof LaunchEditor>, 'appName'> & {\n\tfile: string\n\ttype?: 'playground' | 'solution' | 'problem'\n}) {\n\tconst data = useLoaderData<typeof loader>()\n\tconst app = data[type] || data[data.type]\n\n\tconst info = (\n\t\t<div className=\"launch-editor-button-wrapper flex underline underline-offset-4\">\n\t\t\t{children}{' '}\n\t\t\t<svg height={24} width={24}>\n\t\t\t\t<use href={`${iconsSvg}#Keyboard`} />\n\t\t\t</svg>\n\t\t</div>\n\t)\n\n\treturn ENV.EPICSHOP_DEPLOYED && app ? (\n\t\t<div className=\"inline-block grow\">\n\t\t\t<LaunchEditor appFile={file} appName={app.name} {...props}>\n\t\t\t\t{info}\n\t\t\t</LaunchEditor>\n\t\t</div>\n\t) : app ? (\n\t\t<div className=\"inline-block grow\">\n\t\t\t<LaunchEditor appFile={file} appName={app.name} {...props}>\n\t\t\t\t{info}\n\t\t\t</LaunchEditor>\n\t\t</div>\n\t) : type === 'playground' ? (\n\t\t// playground does not exist yet\n\t\t<SimpleTooltip content=\"You must 'Set to Playground' before opening a file\">\n\t\t\t<div className=\"inline-block grow cursor-not-allowed\">{info}</div>\n\t\t</SimpleTooltip>\n\t) : (\n\t\t<>children</>\n\t)\n}\n\nfunction getPreviewType(\n\tpreview: string | null,\n): 'playground' | 'problem' | 'solution' {\n\tif (preview === 'problem') return 'problem'\n\tif (preview === 'solution') return 'solution'\n\treturn 'playground'\n}\n\nfunction LinkToApp({\n\tto: appTo,\n\tchildren = <code>{appTo.toString()}</code>,\n\t...props\n}: LinkProps) {\n\tconst [searchParams] = useSearchParams()\n\tconst to = `?${withParam(\n\t\tsearchParams,\n\t\t'pathname',\n\t\tappTo.toString(),\n\t).toString()}`\n\tconst data = useLoaderData<typeof loader>()\n\tconst type = getPreviewType(searchParams.get('preview'))\n\tconst requestInfo = useRequestInfo()\n\tconst app = data[type]\n\tconst previewAppUrl =\n\t\tapp?.dev.type === 'script'\n\t\t\t? getBaseUrl({\n\t\t\t\t\tdomain: requestInfo.domain,\n\t\t\t\t\tport: app.dev.portNumber,\n\t\t\t\t})\n\t\t\t: data.playground?.dev.type === 'browser' ||\n\t\t\t\t data.playground?.dev.type === 'export'\n\t\t\t\t? data.playground.dev.pathname\n\t\t\t\t: null\n\tconst { inBrowserBrowserRef } = useStepContext()\n\tconst href = previewAppUrl\n\t\t? previewAppUrl.slice(0, -1) + appTo.toString()\n\t\t: null\n\treturn (\n\t\t<div className=\"inline-flex items-center justify-between gap-1\">\n\t\t\t<Link\n\t\t\t\tto={to}\n\t\t\t\t{...props}\n\t\t\t\tclassName={cn(props.className, {\n\t\t\t\t\t'cursor-not-allowed': ENV.EPICSHOP_DEPLOYED,\n\t\t\t\t})}\n\t\t\t\ttitle={\n\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t? 'Cannot link to app in deployed version'\n\t\t\t\t\t\t: undefined\n\t\t\t\t}\n\t\t\t\tonClick={(event) => {\n\t\t\t\t\tif (ENV.EPICSHOP_DEPLOYED) event.preventDefault()\n\n\t\t\t\t\tprops.onClick?.(event)\n\t\t\t\t\tinBrowserBrowserRef.current?.handleExtrnalNavigation(appTo.toString())\n\t\t\t\t}}\n\t\t\t>\n\t\t\t\t{children}\n\t\t\t</Link>\n\t\t\t{href ? (\n\t\t\t\t<SimpleTooltip content=\"Open in new tab\">\n\t\t\t\t\t<a\n\t\t\t\t\t\thref={href}\n\t\t\t\t\t\ttarget=\"_blank\"\n\t\t\t\t\t\trel=\"noreferrer\"\n\t\t\t\t\t\tclassName={cn('flex aspect-square items-center justify-center', {\n\t\t\t\t\t\t\t'cursor-not-allowed': ENV.EPICSHOP_DEPLOYED,\n\t\t\t\t\t\t})}\n\t\t\t\t\t\ttitle={\n\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t? 'Cannot link to app in deployed version'\n\t\t\t\t\t\t\t\t: 'Open in new tab'\n\t\t\t\t\t\t}\n\t\t\t\t\t\tonClick={(event) => {\n\t\t\t\t\t\t\tif (ENV.EPICSHOP_DEPLOYED) event.preventDefault()\n\t\t\t\t\t\t}}\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon name=\"ExternalLink\" />\n\t\t\t\t\t</a>\n\t\t\t\t</SimpleTooltip>\n\t\t\t) : null}\n\t\t</div>\n\t)\n}\n","\"use client\";\n\n// src/popover.tsx\nimport * as React from \"react\";\nimport { composeEventHandlers } from \"@radix-ui/primitive\";\nimport { useComposedRefs } from \"@radix-ui/react-compose-refs\";\nimport { createContextScope } from \"@radix-ui/react-context\";\nimport { DismissableLayer } from \"@radix-ui/react-dismissable-layer\";\nimport { useFocusGuards } from \"@radix-ui/react-focus-guards\";\nimport { FocusScope } from \"@radix-ui/react-focus-scope\";\nimport { useId } from \"@radix-ui/react-id\";\nimport * as PopperPrimitive from \"@radix-ui/react-popper\";\nimport { createPopperScope } from \"@radix-ui/react-popper\";\nimport { Portal as PortalPrimitive } from \"@radix-ui/react-portal\";\nimport { Presence } from \"@radix-ui/react-presence\";\nimport { Primitive } from \"@radix-ui/react-primitive\";\nimport { createSlot } from \"@radix-ui/react-slot\";\nimport { useControllableState } from \"@radix-ui/react-use-controllable-state\";\nimport { hideOthers } from \"aria-hidden\";\nimport { RemoveScroll } from \"react-remove-scroll\";\nimport { jsx } from \"react/jsx-runtime\";\nvar POPOVER_NAME = \"Popover\";\nvar [createPopoverContext, createPopoverScope] = createContextScope(POPOVER_NAME, [\n createPopperScope\n]);\nvar usePopperScope = createPopperScope();\nvar [PopoverProvider, usePopoverContext] = createPopoverContext(POPOVER_NAME);\nvar Popover = (props) => {\n const {\n __scopePopover,\n children,\n open: openProp,\n defaultOpen,\n onOpenChange,\n modal = false\n } = props;\n const popperScope = usePopperScope(__scopePopover);\n const triggerRef = React.useRef(null);\n const [hasCustomAnchor, setHasCustomAnchor] = React.useState(false);\n const [open, setOpen] = useControllableState({\n prop: openProp,\n defaultProp: defaultOpen ?? false,\n onChange: onOpenChange,\n caller: POPOVER_NAME\n });\n return /* @__PURE__ */ jsx(PopperPrimitive.Root, { ...popperScope, children: /* @__PURE__ */ jsx(\n PopoverProvider,\n {\n scope: __scopePopover,\n contentId: useId(),\n triggerRef,\n open,\n onOpenChange: setOpen,\n onOpenToggle: React.useCallback(() => setOpen((prevOpen) => !prevOpen), [setOpen]),\n hasCustomAnchor,\n onCustomAnchorAdd: React.useCallback(() => setHasCustomAnchor(true), []),\n onCustomAnchorRemove: React.useCallback(() => setHasCustomAnchor(false), []),\n modal,\n children\n }\n ) });\n};\nPopover.displayName = POPOVER_NAME;\nvar ANCHOR_NAME = \"PopoverAnchor\";\nvar PopoverAnchor = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...anchorProps } = props;\n const context = usePopoverContext(ANCHOR_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n const { onCustomAnchorAdd, onCustomAnchorRemove } = context;\n React.useEffect(() => {\n onCustomAnchorAdd();\n return () => onCustomAnchorRemove();\n }, [onCustomAnchorAdd, onCustomAnchorRemove]);\n return /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { ...popperScope, ...anchorProps, ref: forwardedRef });\n }\n);\nPopoverAnchor.displayName = ANCHOR_NAME;\nvar TRIGGER_NAME = \"PopoverTrigger\";\nvar PopoverTrigger = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...triggerProps } = props;\n const context = usePopoverContext(TRIGGER_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n const composedTriggerRef = useComposedRefs(forwardedRef, context.triggerRef);\n const trigger = /* @__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 return context.hasCustomAnchor ? trigger : /* @__PURE__ */ jsx(PopperPrimitive.Anchor, { asChild: true, ...popperScope, children: trigger });\n }\n);\nPopoverTrigger.displayName = TRIGGER_NAME;\nvar PORTAL_NAME = \"PopoverPortal\";\nvar [PortalProvider, usePortalContext] = createPopoverContext(PORTAL_NAME, {\n forceMount: void 0\n});\nvar PopoverPortal = (props) => {\n const { __scopePopover, forceMount, children, container } = props;\n const context = usePopoverContext(PORTAL_NAME, __scopePopover);\n return /* @__PURE__ */ jsx(PortalProvider, { scope: __scopePopover, forceMount, children: /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: /* @__PURE__ */ jsx(PortalPrimitive, { asChild: true, container, children }) }) });\n};\nPopoverPortal.displayName = PORTAL_NAME;\nvar CONTENT_NAME = \"PopoverContent\";\nvar PopoverContent = React.forwardRef(\n (props, forwardedRef) => {\n const portalContext = usePortalContext(CONTENT_NAME, props.__scopePopover);\n const { forceMount = portalContext.forceMount, ...contentProps } = props;\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n return /* @__PURE__ */ jsx(Presence, { present: forceMount || context.open, children: context.modal ? /* @__PURE__ */ jsx(PopoverContentModal, { ...contentProps, ref: forwardedRef }) : /* @__PURE__ */ jsx(PopoverContentNonModal, { ...contentProps, ref: forwardedRef }) });\n }\n);\nPopoverContent.displayName = CONTENT_NAME;\nvar Slot = createSlot(\"PopoverContent.RemoveScroll\");\nvar PopoverContentModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n const contentRef = React.useRef(null);\n const composedRefs = useComposedRefs(forwardedRef, contentRef);\n const isRightClickOutsideRef = React.useRef(false);\n React.useEffect(() => {\n const content = contentRef.current;\n if (content) return hideOthers(content);\n }, []);\n return /* @__PURE__ */ jsx(RemoveScroll, { as: Slot, allowPinchZoom: true, children: /* @__PURE__ */ jsx(\n PopoverContentImpl,\n {\n ...props,\n ref: composedRefs,\n trapFocus: context.open,\n disableOutsidePointerEvents: true,\n onCloseAutoFocus: composeEventHandlers(props.onCloseAutoFocus, (event) => {\n event.preventDefault();\n if (!isRightClickOutsideRef.current) context.triggerRef.current?.focus();\n }),\n onPointerDownOutside: composeEventHandlers(\n props.onPointerDownOutside,\n (event) => {\n const originalEvent = event.detail.originalEvent;\n const ctrlLeftClick = originalEvent.button === 0 && originalEvent.ctrlKey === true;\n const isRightClick = originalEvent.button === 2 || ctrlLeftClick;\n isRightClickOutsideRef.current = isRightClick;\n },\n { checkForDefaultPrevented: false }\n ),\n onFocusOutside: composeEventHandlers(\n props.onFocusOutside,\n (event) => event.preventDefault(),\n { checkForDefaultPrevented: false }\n )\n }\n ) });\n }\n);\nvar PopoverContentNonModal = React.forwardRef(\n (props, forwardedRef) => {\n const context = usePopoverContext(CONTENT_NAME, props.__scopePopover);\n const hasInteractedOutsideRef = React.useRef(false);\n const hasPointerDownOutsideRef = React.useRef(false);\n return /* @__PURE__ */ jsx(\n PopoverContentImpl,\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 PopoverContentImpl = React.forwardRef(\n (props, forwardedRef) => {\n const {\n __scopePopover,\n trapFocus,\n onOpenAutoFocus,\n onCloseAutoFocus,\n disableOutsidePointerEvents,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onInteractOutside,\n ...contentProps\n } = props;\n const context = usePopoverContext(CONTENT_NAME, __scopePopover);\n const popperScope = usePopperScope(__scopePopover);\n useFocusGuards();\n return /* @__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 asChild: true,\n disableOutsidePointerEvents,\n onInteractOutside,\n onEscapeKeyDown,\n onPointerDownOutside,\n onFocusOutside,\n onDismiss: () => context.onOpenChange(false),\n children: /* @__PURE__ */ jsx(\n PopperPrimitive.Content,\n {\n \"data-state\": getState(context.open),\n role: \"dialog\",\n id: context.contentId,\n ...popperScope,\n ...contentProps,\n ref: forwardedRef,\n style: {\n ...contentProps.style,\n // re-namespace exposed content custom properties\n ...{\n \"--radix-popover-content-transform-origin\": \"var(--radix-popper-transform-origin)\",\n \"--radix-popover-content-available-width\": \"var(--radix-popper-available-width)\",\n \"--radix-popover-content-available-height\": \"var(--radix-popper-available-height)\",\n \"--radix-popover-trigger-width\": \"var(--radix-popper-anchor-width)\",\n \"--radix-popover-trigger-height\": \"var(--radix-popper-anchor-height)\"\n }\n }\n }\n )\n }\n )\n }\n );\n }\n);\nvar CLOSE_NAME = \"PopoverClose\";\nvar PopoverClose = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...closeProps } = props;\n const context = usePopoverContext(CLOSE_NAME, __scopePopover);\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);\nPopoverClose.displayName = CLOSE_NAME;\nvar ARROW_NAME = \"PopoverArrow\";\nvar PopoverArrow = React.forwardRef(\n (props, forwardedRef) => {\n const { __scopePopover, ...arrowProps } = props;\n const popperScope = usePopperScope(__scopePopover);\n return /* @__PURE__ */ jsx(PopperPrimitive.Arrow, { ...popperScope, ...arrowProps, ref: forwardedRef });\n }\n);\nPopoverArrow.displayName = ARROW_NAME;\nfunction getState(open) {\n return open ? \"open\" : \"closed\";\n}\nvar Root2 = Popover;\nvar Anchor2 = PopoverAnchor;\nvar Trigger = PopoverTrigger;\nvar Portal = PopoverPortal;\nvar Content2 = PopoverContent;\nvar Close = PopoverClose;\nvar Arrow2 = PopoverArrow;\nexport {\n Anchor2 as Anchor,\n Arrow2 as Arrow,\n Close,\n Content2 as Content,\n Popover,\n PopoverAnchor,\n PopoverArrow,\n PopoverClose,\n PopoverContent,\n PopoverPortal,\n PopoverTrigger,\n Portal,\n Root2 as Root,\n Trigger,\n createPopoverScope\n};\n//# sourceMappingURL=index.mjs.map\n","import * as Popover from '@radix-ui/react-popover'\nimport * as React from 'react'\nimport { Await, useLoaderData } from 'react-router'\nimport { Icon } from '#app/components/icons.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { LaunchEditor } from '#app/routes/launch-editor.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { type Route as LayoutRoute } from '../+types/_layout.tsx'\n\nfunction TouchedFiles({\n\tdiffFilesPromise,\n\tcompact = false,\n}: {\n\tdiffFilesPromise: LayoutRoute.ComponentProps['loaderData']['diffFiles']\n\tcompact?: boolean\n}) {\n\tconst data = useLoaderData<LayoutRoute.ComponentProps['loaderData']>()\n\n\tconst [open, setOpen] = React.useState(false)\n\tconst contentRef = React.useRef<HTMLDivElement>(null)\n\n\tfunction handleLaunchUpdate() {\n\t\tsetOpen(false)\n\t}\n\n\tconst appName = data.playground?.appName\n\n\treturn (\n\t\t<>\n\t\t\t<Popover.Root open={open} onOpenChange={setOpen}>\n\t\t\t\t<Popover.Trigger asChild>\n\t\t\t\t\t<button\n\t\t\t\t\t\tclassName=\"flex h-full items-center gap-1 border-r px-6 py-3 font-mono text-sm uppercase\"\n\t\t\t\t\t\taria-label=\"Relevant Files\"\n\t\t\t\t\t>\n\t\t\t\t\t\t<Icon name=\"Files\" />\n\t\t\t\t\t\t{compact ? null : <span className=\"hidden xl:inline\">Files</span>}\n\t\t\t\t\t</button>\n\t\t\t\t</Popover.Trigger>\n\t\t\t\t<Popover.Portal>\n\t\t\t\t\t<Popover.Content\n\t\t\t\t\t\tref={contentRef}\n\t\t\t\t\t\tclassName=\"slideRightContent lg:slideUpContent invert-theme bg-background text-foreground z-10 rounded px-9 py-8 select-none\"\n\t\t\t\t\t\talign=\"start\"\n\t\t\t\t\t\tsideOffset={5}\n\t\t\t\t\t>\n\t\t\t\t\t\t<div className=\"launch-editor-wrapper\">\n\t\t\t\t\t\t\t<strong className=\"inline-block px-2 pb-4 font-semibold uppercase\">\n\t\t\t\t\t\t\t\tRelevant Files\n\t\t\t\t\t\t\t</strong>\n\t\t\t\t\t\t\t{data.problem &&\n\t\t\t\t\t\t\tdata.playground?.appName !== data.problem.name ? (\n\t\t\t\t\t\t\t\t<div className=\"mb-2 rounded p-1 font-mono font-medium\">\n\t\t\t\t\t\t\t\t\t<SetAppToPlayground appName={data.problem.name} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t<div id=\"files\">\n\t\t\t\t\t\t\t\t<React.Suspense\n\t\t\t\t\t\t\t\t\tfallback={\n\t\t\t\t\t\t\t\t\t\t<SimpleTooltip content=\"Loading diff\">\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"flex justify-center\">\n\t\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"Refresh\" className=\"h-8 w-8 animate-spin\" />\n\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t</SimpleTooltip>\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<Await\n\t\t\t\t\t\t\t\t\t\tresolve={diffFilesPromise}\n\t\t\t\t\t\t\t\t\t\terrorElement={\n\t\t\t\t\t\t\t\t\t\t\t<div className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\tSomething went wrong.\n\t\t\t\t\t\t\t\t\t\t\t</div>\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{(diffFiles) => {\n\t\t\t\t\t\t\t\t\t\t\tif (!diffFiles) {\n\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<p className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\tUnable to determine diff\n\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\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\tif (typeof diffFiles === 'string') {\n\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<p className=\"text-foreground-destructive\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles}\n\t\t\t\t\t\t\t\t\t\t\t\t\t</p>\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\tif (!diffFiles.length) {\n\t\t\t\t\t\t\t\t\t\t\t\treturn <p>No files changed</p>\n\t\t\t\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t\t\t\t\tconst props =\n\t\t\t\t\t\t\t\t\t\t\t\tappName || ENV.EPICSHOP_GITHUB_ROOT\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: {\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\ttitle:\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\"You must 'Set to Playground' before opening a file\",\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tclassName: 'not-allowed',\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\treturn (\n\t\t\t\t\t\t\t\t\t\t\t\t<ul {...props}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles.length > 1 && !ENV.EPICSHOP_DEPLOYED ? (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<div className=\"border-opacity-50 mb-2 border-b border-b-gray-50 pb-2 font-sans\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<LaunchEditor\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappFile={diffFiles.map(\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t(file) => `${file.path},${file.line},1`,\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\tappName=\"playground\"\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tonUpdate={handleLaunchUpdate}\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\t\t<p>Open All Files</p>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</LaunchEditor>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t\t\t\t\t\t\t\t{diffFiles.map((file) => (\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<li key={file.path} data-state={file.status}>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t<LaunchEditor\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappFile={`${file.path},${file.line},1`}\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tappName={\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\tENV.EPICSHOP_DEPLOYED\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t? (data.problem?.name ?? 'playground')\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t: 'playground'\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\tonUpdate={handleLaunchUpdate}\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\t\t<code>{file.path}</code>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t\t</LaunchEditor>\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t</li>\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</ul>\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</Await>\n\t\t\t\t\t\t\t\t</React.Suspense>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</Popover.Content>\n\t\t\t\t</Popover.Portal>\n\t\t\t</Popover.Root>\n\t\t</>\n\t)\n}\n\nexport default TouchedFiles\n","import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppDisplayName,\n\tgetAppPageRoute,\n\tgetApps,\n\tgetExerciseApp,\n\tgetNextExerciseApp,\n\tgetPrevExerciseApp,\n\tisExerciseStepApp,\n\tisPlaygroundApp,\n\trequireExercise,\n\trequireExerciseApp,\n\ttype App,\n\ttype ExerciseStepApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getDiffFiles } from '@epic-web/workshop-utils/diff.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport * as cookie from 'cookie'\nimport { useEffect, useRef, useState } from 'react'\nimport {\n\tLink,\n\tOutlet,\n\tdata,\n\tredirect,\n\ttype HeadersFunction,\n} from 'react-router'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { ProgressToggle } from '#app/routes/progress.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { getExercisePath } from '#app/utils/misc.tsx'\nimport { getRootMatchLoaderData } from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport { getStep404Data } from '../__shared/error-boundary.server.ts'\nimport { Exercise404ErrorBoundary } from '../__shared/error-boundary.tsx'\nimport { type Route } from './+types/_layout.tsx'\nimport { StepMdx } from './__shared/step-mdx.tsx'\nimport TouchedFiles from './__shared/touched-files.tsx'\n\n// shared split state helpers\nconst splitCookieName = 'es_split_pct'\n\nfunction computeSplitPercent(input: unknown, defaultValue = 50): number {\n\tconst value = typeof input === 'number' ? input : Number(input)\n\tif (Number.isFinite(value)) {\n\t\treturn Math.min(80, Math.max(20, Math.round(value * 100) / 100))\n\t}\n\treturn defaultValue\n}\n\nfunction pageTitle(\n\tdata: Awaited<Route.ComponentProps['loaderData']> | undefined,\n\tworkshopTitle?: string,\n) {\n\tconst exerciseNumber =\n\t\tdata?.exerciseStepApp.exerciseNumber.toString().padStart(2, '0') ?? '00'\n\tconst stepNumber =\n\t\tdata?.exerciseStepApp.stepNumber.toString().padStart(2, '0') ?? '00'\n\tconst emoji = (\n\t\t{\n\t\t\tproblem: '💪',\n\t\t\tsolution: '🏁',\n\t\t} as const\n\t)[data?.type ?? 'problem']\n\tconst title = data?.[data.type]?.title ?? 'N/A'\n\treturn {\n\t\temoji,\n\t\tstepNumber,\n\t\ttitle,\n\t\texerciseNumber,\n\t\texerciseTitle: data?.exerciseTitle ?? 'Unknown exercise',\n\t\tworkshopTitle,\n\t\ttype: data?.type ?? 'problem',\n\t}\n}\n\nexport const meta: Route.MetaFunction = ({ loaderData, matches, params }) => {\n\tconst rootData = getRootMatchLoaderData(matches)\n\tif (!loaderData || !rootData) return [{ title: '🦉 | Error' }]\n\tconst { emoji, stepNumber, title, exerciseNumber, exerciseTitle } =\n\t\tpageTitle(loaderData)\n\n\treturn getSeoMetaTags({\n\t\ttitle: `${emoji} | ${stepNumber}. ${title} | ${exerciseNumber}. ${exerciseTitle} | ${rootData.workshopTitle}`,\n\t\tdescription: `${params.type} step for exercise ${exerciseNumber}. ${exerciseTitle}`,\n\t\togTitle: title,\n\t\togDescription: `${exerciseTitle} step ${Number(stepNumber)} ${params.type}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('exerciseStepTypeLayoutLoader')\n\tconst url = new URL(request.url)\n\tconst { type } = params\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\n\tconst cacheOptions = { request, timings }\n\n\tconst [allAppsFull, problemApp, solutionApp] = await Promise.all([\n\t\tgetApps(cacheOptions),\n\t\tgetExerciseApp({ ...params, type: 'problem' }, cacheOptions),\n\t\tgetExerciseApp({ ...params, type: 'solution' }, cacheOptions),\n\t])\n\n\tconst reqUrl = new URL(request.url)\n\tconst pathnameParam = reqUrl.searchParams.get('pathname')\n\tif (pathnameParam === '' || pathnameParam === '/') {\n\t\treqUrl.searchParams.delete('pathname')\n\t\tthrow redirect(reqUrl.toString())\n\t}\n\n\tif (\n\t\t(type === 'problem' && !problemApp) ||\n\t\t(type === 'solution' && !solutionApp)\n\t) {\n\t\tconst errorData = await getStep404Data({\n\t\t\texerciseNumber: params.exerciseNumber,\n\t\t})\n\t\tthrow Response.json(errorData, { status: 404 })\n\t}\n\n\tconst exerciseStepApp = await requireExerciseApp(params, cacheOptions)\n\n\tconst playgroundApp = allAppsFull.find(isPlaygroundApp)\n\n\tfunction getStepId(a: ExerciseStepApp) {\n\t\treturn (\n\t\t\ta.exerciseNumber * 1000 +\n\t\t\ta.stepNumber * 10 +\n\t\t\t(a.type === 'problem' ? 0 : 1)\n\t\t)\n\t}\n\n\tfunction getStepNameAndId(a: App) {\n\t\tif (isExerciseStepApp(a)) {\n\t\t\tconst exerciseNumberStr = String(a.exerciseNumber).padStart(2, '0')\n\t\t\tconst stepNumberStr = String(a.stepNumber).padStart(2, '0')\n\n\t\t\treturn {\n\t\t\t\tstepName: `${exerciseNumberStr}/${stepNumberStr}.${a.type}`,\n\t\t\t\tstepId: getStepId(a),\n\t\t\t}\n\t\t}\n\t\treturn { stepName: '', stepId: -1 }\n\t}\n\n\tconst allApps = allAppsFull\n\t\t.filter((a, i, ar) => ar.findIndex((b) => a.name === b.name) === i)\n\t\t.map((a) => ({\n\t\t\tdisplayName: getAppDisplayName(a, allAppsFull),\n\t\t\tname: a.name,\n\t\t\ttitle: a.title,\n\t\t\ttype: a.type,\n\t\t\t...getStepNameAndId(a),\n\t\t}))\n\n\tallApps.sort((a, b) => {\n\t\t// order them by their stepId\n\t\tif (a.stepId > 0 && b.stepId > 0) return a.stepId - b.stepId\n\n\t\t// non-step apps should come after step apps\n\t\tif (a.stepId > 0) return -1\n\t\tif (b.stepId > 0) return 1\n\n\t\treturn 0\n\t})\n\tconst exerciseId = getStepId(exerciseStepApp)\n\tconst exerciseIndex = allApps.findIndex((step) => step.stepId === exerciseId)\n\n\t// These depend on exerciseStepApp\n\tconst [exercise, nextApp, prevApp] = await Promise.all([\n\t\trequireExercise(exerciseStepApp.exerciseNumber, cacheOptions),\n\t\tgetNextExerciseApp(exerciseStepApp, cacheOptions),\n\t\tgetPrevExerciseApp(exerciseStepApp, cacheOptions),\n\t])\n\n\tconst exerciseApps = allAppsFull\n\t\t.filter(isExerciseStepApp)\n\t\t.filter((app) => app.exerciseNumber === exerciseStepApp.exerciseNumber)\n\tconst isLastStep =\n\t\texerciseApps[exerciseApps.length - 1]?.name === exerciseStepApp.name\n\tconst isFirstStep = exerciseApps[0]?.name === exerciseStepApp.name\n\n\tconst articleId = `workshop-${slugify(workshopTitle)}-${\n\t\texercise.exerciseNumber\n\t}-${exerciseStepApp.stepNumber}-${exerciseStepApp.type}`\n\n\tconst subroute = url.pathname.split(\n\t\t`/exercise/${params.exerciseNumber}/${params.stepNumber}/${params.type}/`,\n\t)[1]\n\n\t// read persisted split percentage from cookie (10-90, default 50)\n\tconst cookieHeader = request.headers.get('cookie')\n\tconst rawSplit = cookieHeader\n\t\t? cookie.parse(cookieHeader)[splitCookieName]\n\t\t: null\n\tconst splitPercent = computeSplitPercent(rawSplit, 50)\n\n\treturn data(\n\t\t{\n\t\t\tarticleId,\n\t\t\ttype: params.type as 'problem' | 'solution',\n\t\t\texerciseStepApp,\n\t\t\texerciseTitle: exercise.title,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(exerciseStepApp.epicVideoEmbeds),\n\t\t\texerciseIndex,\n\t\t\tallApps,\n\t\t\tsplitPercent,\n\t\t\tprevStepLink: isFirstStep\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${exerciseStepApp.exerciseNumber\n\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t.padStart(2, '0')}`,\n\t\t\t\t\t}\n\t\t\t\t: prevApp\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tto: getAppPageRoute(prevApp, {\n\t\t\t\t\t\t\t\tsubroute,\n\t\t\t\t\t\t\t\tsearchParams: url.searchParams,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\tnextStepLink: isLastStep\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/exercise/${exerciseStepApp.exerciseNumber\n\t\t\t\t\t\t\t.toString()\n\t\t\t\t\t\t\t.padStart(2, '0')}/finished`,\n\t\t\t\t\t}\n\t\t\t\t: nextApp\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tto: getAppPageRoute(nextApp, {\n\t\t\t\t\t\t\t\tsubroute,\n\t\t\t\t\t\t\t\tsearchParams: url.searchParams,\n\t\t\t\t\t\t\t}),\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\tplayground: playgroundApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'playground',\n\t\t\t\t\t\tappName: playgroundApp.appName,\n\t\t\t\t\t\tname: playgroundApp.name,\n\t\t\t\t\t\tfullPath: playgroundApp.fullPath,\n\t\t\t\t\t\tdev: playgroundApp.dev,\n\t\t\t\t\t\tisUpToDate: playgroundApp.isUpToDate,\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tproblem: problemApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'problem',\n\t\t\t\t\t\ttitle: problemApp.title,\n\t\t\t\t\t\tname: problemApp.name,\n\t\t\t\t\t\tfullPath: problemApp.fullPath,\n\t\t\t\t\t\tdev: problemApp.dev,\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tsolution: solutionApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'solution',\n\t\t\t\t\t\ttitle: solutionApp.title,\n\t\t\t\t\t\tname: solutionApp.name,\n\t\t\t\t\t\tfullPath: solutionApp.fullPath,\n\t\t\t\t\t\tdev: solutionApp.dev,\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tdiffFiles:\n\t\t\t\tproblemApp && solutionApp\n\t\t\t\t\t? getDiffFiles(problemApp, solutionApp, {\n\t\t\t\t\t\t\t...cacheOptions,\n\t\t\t\t\t\t\tforceFresh: url.searchParams.get('forceFresh') === 'diff',\n\t\t\t\t\t\t}).catch((e) => {\n\t\t\t\t\t\t\tconsole.error(e)\n\t\t\t\t\t\t\treturn 'There was a problem generating the diff (check the terminal output)'\n\t\t\t\t\t\t})\n\t\t\t\t\t: 'No diff available',\n\t\t} as const,\n\t\t{\n\t\t\theaders: {\n\t\t\t\t'Server-Timing': getServerTimeHeader(timings),\n\t\t\t},\n\t\t},\n\t)\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nexport default function ExercisePartRoute({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tconst inBrowserBrowserRef = useRef<InBrowserBrowserRef>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst leftPaneRef = useRef<HTMLDivElement>(null)\n\tconst [splitPercent, setSplitPercent] = useState<number>(data.splitPercent)\n\tconst [leftWidthPx, setLeftWidthPx] = useState<number>(0)\n\n\tuseEffect(() => {\n\t\tconst left = leftPaneRef.current\n\t\tif (!left) return\n\t\tconst ro = new ResizeObserver((entries) => {\n\t\t\tfor (const entry of entries) {\n\t\t\t\tsetLeftWidthPx(entry.contentRect.width)\n\t\t\t}\n\t\t})\n\t\tro.observe(left)\n\t\tsetLeftWidthPx(left.getBoundingClientRect().width)\n\t\treturn () => ro.disconnect()\n\t}, [])\n\n\tfunction setCookie(percent: number) {\n\t\tconst clamped = computeSplitPercent(percent)\n\t\tdocument.cookie = `${splitCookieName}=${clamped}; path=/; SameSite=Lax;`\n\t}\n\n\tfunction startDrag(initialClientX: number) {\n\t\tconst container = containerRef.current\n\t\tif (!container) return\n\t\tconst rect = container.getBoundingClientRect()\n\t\tlet dragging = true\n\n\t\t// Disable pointer events on iframes so the drag keeps receiving events\n\t\tconst iframes = Array.from(\n\t\t\tdocument.querySelectorAll('iframe'),\n\t\t) as HTMLIFrameElement[]\n\t\tconst originalPointerEvents = iframes.map((el) => el.style.pointerEvents)\n\t\tiframes.forEach((el) => (el.style.pointerEvents = 'none'))\n\n\t\tfunction handleMove(clientX: number) {\n\t\t\t// Safety check: ensure user is still dragging\n\t\t\tif (!dragging) {\n\t\t\t\tcleanup()\n\t\t\t\treturn\n\t\t\t}\n\n\t\t\tconst relativeX = clientX - rect.left\n\t\t\tconst percent = (relativeX / rect.width) * 100\n\t\t\tconst clamped = computeSplitPercent(percent)\n\t\t\tsetSplitPercent(clamped)\n\t\t\tsetCookie(clamped)\n\t\t}\n\n\t\tfunction onMouseMove(e: MouseEvent) {\n\t\t\tif (!dragging || e.buttons === 0) {\n\t\t\t\tcleanup()\n\t\t\t\treturn\n\t\t\t}\n\t\t\thandleMove(e.clientX)\n\t\t}\n\t\tfunction onTouchMove(e: TouchEvent) {\n\t\t\tconst firstTouch = e.touches?.[0]\n\t\t\tif (!dragging || !firstTouch) {\n\t\t\t\tcleanup()\n\t\t\t\treturn\n\t\t\t}\n\t\t\thandleMove(firstTouch.clientX)\n\t\t}\n\t\tfunction cleanup() {\n\t\t\tif (!dragging) return\n\t\t\tdragging = false\n\t\t\tiframes.forEach(\n\t\t\t\t(el, i) => (el.style.pointerEvents = originalPointerEvents[i] ?? ''),\n\t\t\t)\n\t\t\twindow.removeEventListener('mousemove', onMouseMove)\n\t\t\twindow.removeEventListener('mouseup', cleanup)\n\t\t\twindow.removeEventListener('touchmove', onTouchMove)\n\t\t\twindow.removeEventListener('touchend', cleanup)\n\t\t\tdocument.body.style.cursor = ''\n\t\t\tdocument.body.style.userSelect = ''\n\t\t}\n\n\t\twindow.addEventListener('mousemove', onMouseMove)\n\t\twindow.addEventListener('mouseup', cleanup)\n\t\twindow.addEventListener('touchmove', onTouchMove)\n\t\twindow.addEventListener('touchend', cleanup)\n\t\tdocument.body.style.cursor = 'col-resize'\n\t\tdocument.body.style.userSelect = 'none'\n\t\thandleMove(initialClientX)\n\t}\n\n\tconst titleBits = pageTitle(data)\n\n\tuseRevalidationWS({\n\t\twatchPaths: [`${data.exerciseStepApp.relativePath}/README.mdx`],\n\t})\n\n\treturn (\n\t\t<div className=\"flex max-w-full grow flex-col\">\n\t\t\t<main\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)\"\n\t\t\t\t\tstyle={{ ['--split-pct' as any]: `${splitPercent}%` }}\n\t\t\t\t\tref={leftPaneRef}\n\t\t\t\t>\n\t\t\t\t\t<h1 className=\"h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium\">\n\t\t\t\t\t\t<div className=\"flex h-14 items-center justify-between gap-x-2 overflow-x-auto py-2 whitespace-nowrap\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2 uppercase\">\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={getExercisePath(data.exerciseStepApp.exerciseNumber)}\n\t\t\t\t\t\t\t\t\tclassName=\"hover:underline\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t{titleBits.exerciseNumber}. {titleBits.exerciseTitle}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t{'/'}\n\t\t\t\t\t\t\t\t<Link to=\".\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{titleBits.stepNumber}. {titleBits.title}\n\t\t\t\t\t\t\t\t\t{' ('}\n\t\t\t\t\t\t\t\t\t{titleBits.emoji} {titleBits.type}\n\t\t\t\t\t\t\t\t\t{')'}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{data.problem &&\n\t\t\t\t\t\t\t(data.playground?.appName !== data.problem.name ||\n\t\t\t\t\t\t\t\t!data.playground?.isUpToDate) ? (\n\t\t\t\t\t\t\t\t<div className=\"hidden md:block\">\n\t\t\t\t\t\t\t\t\t<SetAppToPlayground\n\t\t\t\t\t\t\t\t\t\tappName={data.problem.name}\n\t\t\t\t\t\t\t\t\t\tisOutdated={data.playground?.isUpToDate === false}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<article\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t\tkey={data.articleId}\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.exerciseStepApp.instructionsCode ? (\n\t\t\t\t\t\t\t<StepMdx inBrowserBrowserRef={inBrowserBrowserRef} />\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex h-full items-center justify-center text-lg\">\n\t\t\t\t\t\t\t\t<p>No instructions yet...</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"mt-auto flex justify-between\">\n\t\t\t\t\t\t\t{data.prevStepLink ? (\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={data.prevStepLink.to}\n\t\t\t\t\t\t\t\t\taria-label=\"Previous Step\"\n\t\t\t\t\t\t\t\t\tdata-keyboard-action=\"g+p\"\n\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span aria-hidden>←</span>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\"> Previous</span>\n\t\t\t\t\t\t\t\t</Link>\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)}\n\t\t\t\t\t\t\t{data.nextStepLink ? (\n\t\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\t\tto={data.nextStepLink.to}\n\t\t\t\t\t\t\t\t\taria-label=\"Next Step\"\n\t\t\t\t\t\t\t\t\tdata-keyboard-action=\"g+n\"\n\t\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\">Next </span>\n\t\t\t\t\t\t\t\t\t<span aria-hidden>→</span>\n\t\t\t\t\t\t\t\t</Link>\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)}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration\n\t\t\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t\t\t/>\n\t\t\t\t\t{data.type === 'solution' ? (\n\t\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\t\ttype=\"step\"\n\t\t\t\t\t\t\texerciseNumber={data.exerciseStepApp.exerciseNumber}\n\t\t\t\t\t\t\tstepNumber={data.exerciseStepApp.stepNumber}\n\t\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t\t/>\n\t\t\t\t\t) : null}\n\t\t\t\t\t<div className=\"flex h-16 justify-between border-t border-b-4 lg:border-b-0\">\n\t\t\t\t\t\t<div>\n\t\t\t\t\t\t\t<div className=\"h-full\">\n\t\t\t\t\t\t\t\t<TouchedFiles\n\t\t\t\t\t\t\t\t\tdiffFilesPromise={data.diffFiles}\n\t\t\t\t\t\t\t\t\tcompact={leftWidthPx < 640}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\tappName={data.exerciseStepApp.name}\n\t\t\t\t\t\t\trelativePath={`${data.exerciseStepApp.relativePath}/README.mdx`}\n\t\t\t\t\t\t\tcompact={leftWidthPx < 720}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons\n\t\t\t\t\t\t\tprev={\n\t\t\t\t\t\t\t\tdata.prevStepLink\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tto: data.prevStepLink.to,\n\t\t\t\t\t\t\t\t\t\t\t'aria-label': 'Previous Step',\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: null\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\tnext={\n\t\t\t\t\t\t\t\tdata.nextStepLink\n\t\t\t\t\t\t\t\t\t? {\n\t\t\t\t\t\t\t\t\t\t\tto: data.nextStepLink.to,\n\t\t\t\t\t\t\t\t\t\t\t'aria-label': 'Next Step',\n\t\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t\t: null\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t/>\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\trole=\"separator\"\n\t\t\t\t\taria-orientation=\"vertical\"\n\t\t\t\t\ttitle=\"Drag to resize\"\n\t\t\t\t\tclassName=\"bg-border hover:bg-accent hidden w-1 cursor-col-resize lg:block\"\n\t\t\t\t\tonMouseDown={(e) => startDrag(e.clientX)}\n\t\t\t\t\tonDoubleClick={() => {\n\t\t\t\t\t\tsetSplitPercent(50)\n\t\t\t\t\t\tsetCookie(50)\n\t\t\t\t\t}}\n\t\t\t\t\tonTouchStart={(e) => {\n\t\t\t\t\t\tconst firstTouch = e.touches?.[0]\n\t\t\t\t\t\tif (firstTouch) startDrag(firstTouch.clientX)\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<div className=\"flex min-w-0 flex-1\">\n\t\t\t\t\t<Outlet context={{ inBrowserBrowserRef }} />\n\t\t\t\t</div>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn (\n\t\t<GeneralErrorBoundary\n\t\t\tclassName=\"container flex items-center justify-center\"\n\t\t\tstatusHandlers={{\n\t\t\t\t404: Exercise404ErrorBoundary,\n\t\t\t}}\n\t\t/>\n\t)\n}\n"],"names":["StepContext","React.createContext","useStepContext","context","React.useContext","StepContextProvider","children","inBrowserBrowserRef","stepMdxComponents","DiffLink","PrevDiffLink","NextDiffLink","InlineFile","LinkToApp","StepMdx","data","useLoaderData","jsx","EpicVideoInfoProvider","Mdx","withParam","searchParams","key","value","newSearchParams","app","fullPage","app1","app2","to","getAppName","input","stepIndex","name","stepName","params","app1Name","app2Name","jsxs","pathToDiff","Link","file","type","props","info","iconsSvg","LaunchEditor","SimpleTooltip","getPreviewType","preview","appTo","useSearchParams","requestInfo","useRequestInfo","previewAppUrl","getBaseUrl","href","cn","event","Icon","POPOVER_NAME","createPopoverContext","createContextScope","createPopperScope","usePopperScope","PopoverProvider","usePopoverContext","Popover","__scopePopover","openProp","defaultOpen","onOpenChange","modal","popperScope","triggerRef","React.useRef","hasCustomAnchor","setHasCustomAnchor","React.useState","open","setOpen","useControllableState","PopperPrimitive.Root","useId","React.useCallback","prevOpen","ANCHOR_NAME","PopoverAnchor","React.forwardRef","forwardedRef","anchorProps","onCustomAnchorAdd","onCustomAnchorRemove","React.useEffect","PopperPrimitive.Anchor","TRIGGER_NAME","PopoverTrigger","triggerProps","composedTriggerRef","useComposedRefs","trigger","Primitive","getState","composeEventHandlers","PORTAL_NAME","PortalProvider","usePortalContext","PopoverPortal","forceMount","container","Presence","PortalPrimitive","CONTENT_NAME","PopoverContent","portalContext","contentProps","PopoverContentModal","PopoverContentNonModal","Slot","createSlot","contentRef","composedRefs","isRightClickOutsideRef","content","hideOthers","RemoveScroll","PopoverContentImpl","originalEvent","ctrlLeftClick","isRightClick","hasInteractedOutsideRef","hasPointerDownOutsideRef","target","trapFocus","onOpenAutoFocus","onCloseAutoFocus","disableOutsidePointerEvents","onEscapeKeyDown","onPointerDownOutside","onFocusOutside","onInteractOutside","useFocusGuards","FocusScope","DismissableLayer","PopperPrimitive.Content","CLOSE_NAME","PopoverClose","closeProps","ARROW_NAME","PopoverArrow","arrowProps","PopperPrimitive.Arrow","Root2","Trigger","Portal","Content2","TouchedFiles","diffFilesPromise","compact","handleLaunchUpdate","appName","Popover.Root","Popover.Trigger","Popover.Portal","Popover.Content","SetAppToPlayground","React.Suspense","Await","diffFiles","splitCookieName","computeSplitPercent","defaultValue","Number","isFinite","Math","min","max","round","pageTitle","workshopTitle","exerciseNumber","exerciseStepApp","toString","padStart","stepNumber","emoji","problem","solution","title","exerciseTitle","meta","loaderData","matches","rootData","getRootMatchLoaderData","getSeoMetaTags","description","ogTitle","ogDescription","instructor","_layout","_UNSAFE_withComponentProps","useRef","containerRef","leftPaneRef","splitPercent","setSplitPercent","useState","leftWidthPx","setLeftWidthPx","useEffect","left","current","ro","ResizeObserver","entries","entry","contentRect","width","observe","getBoundingClientRect","disconnect","setCookie","percent","clamped","document","cookie","startDrag","initialClientX","rect","dragging","iframes","Array","from","querySelectorAll","originalPointerEvents","map","el","style","pointerEvents","forEach","handleMove","clientX","cleanup","onMouseMove","e","buttons","onTouchMove","firstTouch","touches","i","window","removeEventListener","body","cursor","userSelect","addEventListener","titleBits","useRevalidationWS","watchPaths","relativePath","className","ref","getExercisePath","playground","isUpToDate","isOutdated","id","articleId","instructionsCode","prevStepLink","prefetch","nextStepLink","ElementScrollRestoration","elementQuery","ProgressToggle","EditFileOnGitHub","NavChevrons","prev","next","role","onMouseDown","onDoubleClick","onTouchStart","Outlet","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary","statusHandlers","Exercise404ErrorBoundary"],"mappings":"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","x_google_ignoreList":[1]}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{w as t,b as p}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as s}from"./jsx-runtime-C5WNSv3b.js";import{r as i}from"./index-Az39ZADK.js";import{P as m}from"./preview-
|
|
2
|
-
//# sourceMappingURL=app-
|
|
1
|
+
import{w as t,b as p}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as s}from"./jsx-runtime-C5WNSv3b.js";import{r as i}from"./index-Az39ZADK.js";import{P as m}from"./preview-CqV1y1NY.js";import"./misc-BapXpylh.js";import"./button-Ds94YjAg.js";import"./loading-DyvhEH4Q.js";import"./index-_LzGTKVC.js";import"./tooltip-C2AQeNhD.js";import"./index-CjiomtK6.js";import"./root-loader-C5P2c7MU.js";import"./pe-Bs-DFNma.js";import"./types-Cl2NuNg4.js";import"./progress-bar-D66irkpP.js";const L=t(function(){const{appInfo:r}=p(),o=i.useRef(null);return s.jsx(m,{appInfo:r,inBrowserBrowserRef:o})});export{L as default};
|
|
2
|
+
//# sourceMappingURL=app-B-WYurXM.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"app-
|
|
1
|
+
{"version":3,"file":"app-B-WYurXM.js","sources":["../../../app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app.tsx"],"sourcesContent":["import { requireExerciseApp } from '@epic-web/workshop-utils/apps.server'\nimport {\n\tcombineServerTimings,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport { useRef } from 'react'\nimport {\n\tdata,\n\ttype HeadersFunction,\n\ttype LoaderFunctionArgs,\n\tuseLoaderData,\n} from 'react-router'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.ts'\nimport { Preview } from './__shared/preview.tsx'\nimport { getAppRunningState } from './__shared/utils.tsx'\n\nexport async function loader({ request, params }: LoaderFunctionArgs) {\n\tconst timings = makeTimings('exercise-step-test')\n\tconst exerciseStepApp = await requireExerciseApp(params, { request, timings })\n\tconst { isRunning, portIsAvailable } =\n\t\tawait getAppRunningState(exerciseStepApp)\n\n\treturn data(\n\t\t{\n\t\t\tappInfo: {\n\t\t\t\tisRunning,\n\t\t\t\tname: exerciseStepApp.name,\n\t\t\t\ttitle: exerciseStepApp.title,\n\t\t\t\tportIsAvailable,\n\t\t\t\ttype: exerciseStepApp.type,\n\t\t\t\tfullPath: exerciseStepApp.fullPath,\n\t\t\t\tdev: exerciseStepApp.dev,\n\t\t\t\ttest: exerciseStepApp.test,\n\t\t\t\tstackBlitzUrl: exerciseStepApp.stackBlitzUrl,\n\t\t\t},\n\t\t},\n\t\t{\n\t\t\theaders: {\n\t\t\t\t'Server-Timing': timings.toString(),\n\t\t\t},\n\t\t},\n\t)\n}\n\nexport const headers: HeadersFunction = ({ loaderHeaders, parentHeaders }) => {\n\tconst headers = {\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nexport default function TestsList() {\n\tconst { appInfo } = useLoaderData<typeof loader>()\n\tconst ref = useRef<InBrowserBrowserRef>(null)\n\n\treturn <Preview appInfo={appInfo} inBrowserBrowserRef={ref} />\n}\n"],"names":["app","_UNSAFE_withComponentProps","appInfo","useLoaderData","ref","useRef","jsx","Preview","inBrowserBrowserRef"],"mappings":"8dAmDA,MAAAA,EAAAC,EAAA,UAAoC,CACnC,KAAM,CAAEC,QAAAA,GAAYC,EAAA,EACdC,EAAMC,EAAAA,OAA4B,IAAI,EAE5C,OAAOC,EAAAA,IAACC,EAAA,CAAQL,QAAAA,EAAkBM,oBAAqBJ,CAAA,CAAK,CAC7D,CAAA"}
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{b as me,A as xe,L as K,w as he,a as ge,p as ve,g as je,m as be}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{e as B,f as H,P,h as w,g as we,u as V,m as ye,i as Ne,S as Te}from"./tooltip-C2AQeNhD.js";import{f as Ie,u as $}from"./index--z_DgN94.js";import{k as z,I as C,a as Ce}from"./misc-BapXpylh.js";import{U as Pe}from"./diff-CSBF170R.js";import{G as Ee}from"./error-boundary-C8da5z08.js";import{u as Re}from"./workshop-config-DCYN9tG7.js";import{L as Se}from"./loading-DyvhEH4Q.js";import{D as Ae,u as Fe}from"./discord-CRlZTq2g.js";import{u as _e}from"./online-Dw7HU4wM.js";import{t as ke}from"./index-Dd9cSrtE.js";import{S as Ue}from"./set-playground-kIjHv9mG.js";import{P as De,a as Le}from"./tests-CA21WazO.js";import{P as k}from"./preview-CuS2jg4z.js";import"./index-CjiomtK6.js";import"./index-Cod-PQ6D.js";import"./accordion-APJveXWr.js";import"./mdx-C_z6TweY.js";import"./epic-video-DQNGJhVF.js";import"./index-_LzGTKVC.js";import"./root-loader-C5P2c7MU.js";import"./pe-Bs-DFNma.js";import"./types-Cl2NuNg4.js";import"./user-DtZkTMil.js";import"./preload-helper-BXl3LOEh.js";import"./launch-editor-FcTaA5kv.js";import"./progress-bar-D66irkpP.js";import"./revalidation-ws-BahUMYqf.js";import"./use-event-source-CrGUTTzj.js";import"./button-Ds94YjAg.js";var _="rovingFocusGroup.onEntryFocus",Oe={bubbles:!1,cancelable:!0},E="RovingFocusGroup",[U,Y,Me]=Ie(E),[Ge,W]=B(E,[Me]),[Ke,Be]=Ge(E),q=u.forwardRef((s,t)=>e.jsx(U.Provider,{scope:s.__scopeRovingFocusGroup,children:e.jsx(U.Slot,{scope:s.__scopeRovingFocusGroup,children:e.jsx(He,{...s,ref:t})})}));q.displayName=E;var He=u.forwardRef((s,t)=>{const{__scopeRovingFocusGroup:r,orientation:n,loop:i=!1,dir:d,currentTabStopId:l,defaultCurrentTabStopId:p,onCurrentTabStopIdChange:g,onEntryFocus:m,preventScrollOnEntryFocus:a=!1,...c}=s,x=u.useRef(null),o=we(t,x),b=$(d),[v,f]=V({prop:l,defaultProp:p??null,onChange:g,caller:E}),[y,S]=u.useState(!1),j=ye(m),N=Y(r),A=u.useRef(!1),[ce,O]=u.useState(0);return u.useEffect(()=>{const h=x.current;if(h)return h.addEventListener(_,j),()=>h.removeEventListener(_,j)},[j]),e.jsx(Ke,{scope:r,orientation:n,dir:b,loop:i,currentTabStopId:v,onItemFocus:u.useCallback(h=>f(h),[f]),onItemShiftTab:u.useCallback(()=>S(!0),[]),onFocusableItemAdd:u.useCallback(()=>O(h=>h+1),[]),onFocusableItemRemove:u.useCallback(()=>O(h=>h-1),[]),children:e.jsx(P.div,{tabIndex:y||ce===0?-1:0,"data-orientation":n,...c,ref:o,style:{outline:"none",...s.style},onMouseDown:w(s.onMouseDown,()=>{A.current=!0}),onFocus:w(s.onFocus,h=>{const ue=!A.current;if(h.target===h.currentTarget&&ue&&!y){const M=new CustomEvent(_,Oe);if(h.currentTarget.dispatchEvent(M),!M.defaultPrevented){const F=N().filter(T=>T.focusable),de=F.find(T=>T.active),fe=F.find(T=>T.id===v),pe=[de,fe,...F].filter(Boolean).map(T=>T.ref.current);X(pe,a)}}A.current=!1}),onBlur:w(s.onBlur,()=>S(!1))})})}),J="RovingFocusGroupItem",Q=u.forwardRef((s,t)=>{const{__scopeRovingFocusGroup:r,focusable:n=!0,active:i=!1,tabStopId:d,children:l,...p}=s,g=H(),m=d||g,a=Be(J,r),c=a.currentTabStopId===m,x=Y(r),{onFocusableItemAdd:o,onFocusableItemRemove:b,currentTabStopId:v}=a;return u.useEffect(()=>{if(n)return o(),()=>b()},[n,o,b]),e.jsx(U.ItemSlot,{scope:r,id:m,focusable:n,active:i,children:e.jsx(P.span,{tabIndex:c?0:-1,"data-orientation":a.orientation,...p,ref:t,onMouseDown:w(s.onMouseDown,f=>{n?a.onItemFocus(m):f.preventDefault()}),onFocus:w(s.onFocus,()=>a.onItemFocus(m)),onKeyDown:w(s.onKeyDown,f=>{if(f.key==="Tab"&&f.shiftKey){a.onItemShiftTab();return}if(f.target!==f.currentTarget)return;const y=ze(f,a.orientation,a.dir);if(y!==void 0){if(f.metaKey||f.ctrlKey||f.altKey||f.shiftKey)return;f.preventDefault();let j=x().filter(N=>N.focusable).map(N=>N.ref.current);if(y==="last")j.reverse();else if(y==="prev"||y==="next"){y==="prev"&&j.reverse();const N=j.indexOf(f.currentTarget);j=a.loop?Ye(j,N+1):j.slice(N+1)}setTimeout(()=>X(j))}}),children:typeof l=="function"?l({isCurrentTabStop:c,hasTabStop:v!=null}):l})})});Q.displayName=J;var Ve={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function $e(s,t){return t!=="rtl"?s:s==="ArrowLeft"?"ArrowRight":s==="ArrowRight"?"ArrowLeft":s}function ze(s,t,r){const n=$e(s.key,r);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(n))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(n)))return Ve[n]}function X(s,t=!1){const r=document.activeElement;for(const n of s)if(n===r||(n.focus({preventScroll:t}),document.activeElement!==r))return}function Ye(s,t){return s.map((r,n)=>s[(t+n)%s.length])}var We=q,qe=Q,R="Tabs",[Je]=B(R,[W]),Z=W(),[Qe,L]=Je(R),ee=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,onValueChange:i,defaultValue:d,orientation:l="horizontal",dir:p,activationMode:g="automatic",...m}=s,a=$(p),[c,x]=V({prop:n,onChange:i,defaultProp:d??"",caller:R});return e.jsx(Qe,{scope:r,baseId:H(),value:c,onValueChange:x,orientation:l,dir:a,activationMode:g,children:e.jsx(P.div,{dir:a,"data-orientation":l,...m,ref:t})})});ee.displayName=R;var se="TabsList",te=u.forwardRef((s,t)=>{const{__scopeTabs:r,loop:n=!0,...i}=s,d=L(se,r),l=Z(r);return e.jsx(We,{asChild:!0,...l,orientation:d.orientation,dir:d.dir,loop:n,children:e.jsx(P.div,{role:"tablist","aria-orientation":d.orientation,...i,ref:t})})});te.displayName=se;var re="TabsTrigger",ne=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,disabled:i=!1,...d}=s,l=L(re,r),p=Z(r),g=ae(l.baseId,n),m=le(l.baseId,n),a=n===l.value;return e.jsx(qe,{asChild:!0,...p,focusable:!i,active:a,children:e.jsx(P.button,{type:"button",role:"tab","aria-selected":a,"aria-controls":m,"data-state":a?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:g,...d,ref:t,onMouseDown:w(s.onMouseDown,c=>{!i&&c.button===0&&c.ctrlKey===!1?l.onValueChange(n):c.preventDefault()}),onKeyDown:w(s.onKeyDown,c=>{[" ","Enter"].includes(c.key)&&l.onValueChange(n)}),onFocus:w(s.onFocus,()=>{const c=l.activationMode!=="manual";!a&&!i&&c&&l.onValueChange(n)})})})});ne.displayName=re;var oe="TabsContent",ie=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,forceMount:i,children:d,...l}=s,p=L(oe,r),g=ae(p.baseId,n),m=le(p.baseId,n),a=n===p.value,c=u.useRef(a);return u.useEffect(()=>{const x=requestAnimationFrame(()=>c.current=!1);return()=>cancelAnimationFrame(x)},[]),e.jsx(Ne,{present:i||a,children:({present:x})=>e.jsx(P.div,{"data-state":a?"active":"inactive","data-orientation":p.orientation,role:"tabpanel","aria-labelledby":g,hidden:!x,id:m,tabIndex:0,...l,ref:t,style:{...s.style,animationDuration:c.current?"0s":void 0},children:x&&d})})});ie.displayName=oe;function ae(s,t){return`${s}-trigger-${t}`}function le(s,t){return`${s}-content-${t}`}var Xe=ee,Ze=te,es=ne,I=ie;function ss({status:s}){const t={running:{pinger:"bg-green-400",circle:"bg-green-500"},passed:{circle:"bg-green-500"},failed:{circle:"bg-red-500"},stopped:{circle:"bg-gray-500"}}[s];return e.jsxs("span",{className:"relative flex h-3 w-3",children:[t.pinger?e.jsx("span",{className:`absolute inline-flex h-full w-full animate-ping rounded-full ${t.pinger} opacity-75`}):null,e.jsx("span",{className:`relative inline-flex h-3 w-3 rounded-full ${t.circle}`})]})}function ts(){return e.jsxs("div",{className:"flex h-full w-full flex-col gap-4 pt-4",children:[e.jsx("div",{className:"text-center",children:e.jsx(Ae,{})}),e.jsx("div",{className:"bg-accent scrollbar-thin scrollbar-thumb-scrollbar flex-1 overflow-y-scroll pb-4",children:e.jsx(rs,{})})]})}function rs(){const s=me(),t=Fe(),r=z();return _e()?e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx(u.Suspense,{fallback:e.jsx("div",{className:"flex h-full w-full flex-col items-center justify-center",children:e.jsx(Se,{children:"Loading Discord Posts"})}),children:e.jsx(xe,{resolve:s.discordPostsPromise,errorElement:e.jsx("div",{className:"text-red-500",children:"There was a problem loading the discord posts"}),children:i=>e.jsx("ul",{className:"flex w-full flex-col gap-4 p-3 xl:p-12",children:i.map(d=>e.jsx("li",{className:"bg-background rounded-xl border transition-all duration-200 focus-within:-translate-y-1 focus-within:shadow-lg hover:-translate-y-1 hover:shadow-lg",children:e.jsx(ns,{thread:d})},d.id))})})}),e.jsx("div",{children:e.jsxs(K,{to:r&&!t.includes("oauth")?t.replace(/^https/,"discord"):t,target:t.includes("oauth")?void 0:"_blank",rel:"noreferrer noopener",onClick:r?i=>{i.preventDefault(),window.open(i.currentTarget.href,"_blank","noreferrer noopener")}:void 0,className:"flex items-center gap-2 p-2 text-xl hover:underline",children:["Create Post ",e.jsx(C,{name:"ExternalLink"})]})})]}):e.jsx("div",{className:"flex h-full flex-col items-center justify-between",children:e.jsx("div",{className:"text-foreground-destructive flex h-full w-full flex-col items-center justify-center",children:e.jsx(C,{name:"WifiNoConnection",size:"xl",children:"Unable to load discord messages when offline"})})})}function ns({thread:s}){const t=s.reactions.filter(r=>r.count);return e.jsx("div",{children:e.jsxs("div",{className:"flex flex-col gap-2 p-4",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[s.tags.length?e.jsx("div",{className:"flex gap-2",children:s.tags.map(r=>e.jsxs("div",{className:"bg-accent flex items-center justify-center gap-1 rounded-full px-2 py-1 text-sm",children:[e.jsx("span",{className:"h-3 w-3 leading-3",children:e.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),e.jsx("span",{children:r.name})]},r.name))}):null,e.jsx("strong",{className:"text-xl font-bold",children:s.name}),e.jsxs("div",{className:"flex items-start gap-1",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[s.authorAvatarUrl?e.jsx("img",{src:s.authorAvatarUrl,alt:"",className:"h-6 w-6 rounded-full"}):null,e.jsxs("span",{children:[e.jsx("span",{className:"font-bold",style:s.authorHexAccentColor?{color:s.authorHexAccentColor}:{},children:s.authorDisplayName}),":"," "]})]}),e.jsx("span",{className:"text-muted-foreground flex-1 overflow-ellipsis",children:s.messagePreview})]})]}),s.previewImageUrl?e.jsx("img",{src:s.previewImageUrl,alt:"",className:"h-28 w-28 rounded-lg object-cover"}):null]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{children:t.length?e.jsx("ul",{className:"flex items-center gap-2",children:t.map((r,n)=>e.jsxs("li",{className:"flex items-center gap-1 rounded-md border border-blue-600 bg-blue-500/20 px-[5px] py-[0.5px] text-sm",children:[e.jsx("span",{className:"h-3 w-3 leading-3",children:e.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),e.jsx("span",{children:r.count})]},n))}):null}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(C,{name:"Chat"})," ",s.messageCount]}),` · ${s.lastUpdatedDisplay}`]})]}),e.jsxs("span",{className:"flex items-center gap-4",children:[e.jsx("a",{href:s.link.replace(/^https/,"discord"),children:e.jsx(C,{name:"Discord"})}),e.jsx("a",{href:s.link,target:"_blank",rel:"noreferrer noopener",children:e.jsx(C,{name:"ExternalLink"})})]})]})]})})}function G({name:s,url:t}){return t?e.jsx("img",{src:t,alt:s,className:"h-full w-full"}):s||null}function os({appInfo:s,inBrowserBrowserRef:t,problemAppName:r,allApps:n,isUpToDate:i}){return e.jsx(De,{playgroundAppName:s?.appName,problemAppName:r,allApps:n,isUpToDate:i,children:s?.dev.type==="none"?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-4",children:[e.jsx("div",{className:"text-secondary-foreground text-2xl",children:"Non-UI exercise"}),e.jsxs("div",{className:"text-secondary-foreground max-w-md text-center text-balance",children:["This exercise has no application or other UI associated with it."," ",e.jsx("br",{}),"Navigate to"," ",e.jsx(Te,{content:s.fullPath,children:e.jsxs("span",{className:"inline-flex cursor-pointer items-center gap-1.5 underline",onClick:()=>{navigator.clipboard.writeText(s.fullPath),ke.success("Copied playground path to clipboard")},children:["the playground directory",e.jsx(C,{name:"Copy",size:"sm"})]})})," ","in your editor and follow the exercise instructions to complete it."]})]}):s?e.jsx(k,{id:s.appName,appInfo:s,inBrowserBrowserRef:t}):e.jsxs("div",{className:"flex flex-col justify-center gap-2",children:[e.jsx("p",{children:"Please set the playground first"}),r?e.jsx(Ue,{appName:r}):null]})})}const D=["playground","problem","solution","tests","diff","chat"],is=s=>!!(s&&D.includes(s));function as(s,t,r){const n=new URLSearchParams(s);return r===null?n.delete(t):n.set(t,r),n}const Ks=he(function({loaderData:t}){const{inBrowserBrowserRef:r}=ve(),n=Re(),[i]=je(),d=i.get("preview"),l=z(),p=be();function g(o){if(o==="tests")return ENV.EPICSHOP_DEPLOYED||!t.playground||t.playground.test.type==="none";if(o==="problem"||o==="solution"){if(t[o]?.dev.type==="none")return!0;if(ENV.EPICSHOP_DEPLOYED)return t[o]?.dev.type!=="browser"&&!t[o]?.stackBlitzUrl}return o==="playground"&&ENV.EPICSHOP_DEPLOYED?!0:o==="chat"?!n.product.discordChannelId:!1}function m(o){if(o==="tests"){if(!t.playground)return null;const{isTestRunning:b,testExitCode:v}=t.playground;return b?"running":v===0?"passed":v!==null&&v!==0?"failed":null}return(o==="problem"||o==="solution"||o==="playground")&&(o==="playground"?t.playground:t[o])?.isRunning?"running":null}const a=is(d)?d:D.find(o=>!g(o)),c=`/diff?${new URLSearchParams({app1:t.problem?.name??"",app2:t.solution?.name??""})}`;function x(o){o.altKey&&!o.ctrlKey&&!o.shiftKey&&!o.metaKey&&(o.preventDefault(),p(c))}return e.jsxs(Xe,{className:"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden sm:col-span-1 sm:row-span-1",value:a,children:[e.jsx(Ze,{className:"scrollbar-thin scrollbar-thumb-scrollbar h-14 min-h-14 overflow-x-auto border-b whitespace-nowrap",children:D.map(o=>{const b=g(o),v=m(o);return e.jsx(es,{value:o,hidden:b,asChild:!0,children:e.jsx(K,{id:`${o}-tab`,className:Ce("clip-path-button radix-state-active:z-10 radix-state-active:bg-foreground radix-state-active:text-background radix-state-active:hover:bg-foreground/80 radix-state-active:hover:text-background/80 radix-state-inactive:hover:bg-foreground/20 radix-state-inactive:hover:text-foreground/80 focus:bg-foreground/80 focus:text-background/80 relative h-full px-6 py-4 font-mono text-sm uppercase outline-none",b?"hidden":"inline-block"),preventScrollReset:!0,prefetch:"intent",onClick:x,to:o==="diff"&&l?c:`?${as(i,"preview",o==="playground"?null:o)}`,children:e.jsxs("span",{className:"flex items-center gap-2",children:[v&&e.jsx(ss,{status:v}),e.jsx("span",{children:o})]})})},o)})}),e.jsxs("div",{className:"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden",children:[e.jsx(I,{value:"playground",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(os,{appInfo:t.playground,problemAppName:t.problem?.name,inBrowserBrowserRef:r,allApps:t.allApps,isUpToDate:t.playground?.isUpToDate??!1})}),e.jsx(I,{value:"problem",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(k,{appInfo:t.problem,inBrowserBrowserRef:r})}),e.jsx(I,{value:"solution",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(k,{appInfo:t.solution,inBrowserBrowserRef:r})}),e.jsx(I,{value:"tests",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start overflow-hidden",children:e.jsx(Le,{appInfo:t.playground,problemAppName:t.problem?.name,allApps:t.allApps,isUpToDate:t.playground?.isUpToDate??!1,userHasAccessPromise:t.userHasAccessPromise})}),e.jsx(I,{value:"diff",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:e.jsx(Pe,{diff:t.diff,allApps:t.allApps,userHasAccessPromise:t.userHasAccessPromise})}),e.jsx(I,{value:"chat",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:e.jsx(ts,{})})]})]})}),Bs=ge(function(){return e.jsx(Ee,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."})}})});export{Bs as ErrorBoundary,Ks as default};
|
|
2
|
-
//# sourceMappingURL=index-
|
|
1
|
+
import{b as me,A as xe,L as K,w as he,a as ge,p as ve,g as je,m as be}from"./chunk-UIGDSWPH-BWkP6tD5.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{e as B,f as H,P,h as w,g as we,u as V,m as ye,i as Ne,S as Te}from"./tooltip-C2AQeNhD.js";import{f as Ie,u as $}from"./index--z_DgN94.js";import{k as z,I as C,a as Ce}from"./misc-BapXpylh.js";import{U as Pe}from"./diff-CSBF170R.js";import{G as Ee}from"./error-boundary-C8da5z08.js";import{u as Re}from"./workshop-config-DCYN9tG7.js";import{L as Se}from"./loading-DyvhEH4Q.js";import{D as Ae,u as Fe}from"./discord-CRlZTq2g.js";import{u as _e}from"./online-Dw7HU4wM.js";import{t as ke}from"./index-Dd9cSrtE.js";import{S as Ue}from"./set-playground-kIjHv9mG.js";import{P as De,a as Le}from"./tests-CA21WazO.js";import{P as k}from"./preview-CqV1y1NY.js";import"./index-CjiomtK6.js";import"./index-Cod-PQ6D.js";import"./accordion-APJveXWr.js";import"./mdx-C_z6TweY.js";import"./epic-video-DQNGJhVF.js";import"./index-_LzGTKVC.js";import"./root-loader-C5P2c7MU.js";import"./pe-Bs-DFNma.js";import"./types-Cl2NuNg4.js";import"./user-DtZkTMil.js";import"./preload-helper-BXl3LOEh.js";import"./launch-editor-FcTaA5kv.js";import"./progress-bar-D66irkpP.js";import"./revalidation-ws-BahUMYqf.js";import"./use-event-source-CrGUTTzj.js";import"./button-Ds94YjAg.js";var _="rovingFocusGroup.onEntryFocus",Oe={bubbles:!1,cancelable:!0},E="RovingFocusGroup",[U,Y,Me]=Ie(E),[Ge,W]=B(E,[Me]),[Ke,Be]=Ge(E),q=u.forwardRef((s,t)=>e.jsx(U.Provider,{scope:s.__scopeRovingFocusGroup,children:e.jsx(U.Slot,{scope:s.__scopeRovingFocusGroup,children:e.jsx(He,{...s,ref:t})})}));q.displayName=E;var He=u.forwardRef((s,t)=>{const{__scopeRovingFocusGroup:r,orientation:n,loop:i=!1,dir:d,currentTabStopId:l,defaultCurrentTabStopId:p,onCurrentTabStopIdChange:v,onEntryFocus:m,preventScrollOnEntryFocus:a=!1,...c}=s,x=u.useRef(null),o=we(t,x),h=$(d),[j,f]=V({prop:l,defaultProp:p??null,onChange:v,caller:E}),[y,S]=u.useState(!1),b=ye(m),N=Y(r),A=u.useRef(!1),[ce,O]=u.useState(0);return u.useEffect(()=>{const g=x.current;if(g)return g.addEventListener(_,b),()=>g.removeEventListener(_,b)},[b]),e.jsx(Ke,{scope:r,orientation:n,dir:h,loop:i,currentTabStopId:j,onItemFocus:u.useCallback(g=>f(g),[f]),onItemShiftTab:u.useCallback(()=>S(!0),[]),onFocusableItemAdd:u.useCallback(()=>O(g=>g+1),[]),onFocusableItemRemove:u.useCallback(()=>O(g=>g-1),[]),children:e.jsx(P.div,{tabIndex:y||ce===0?-1:0,"data-orientation":n,...c,ref:o,style:{outline:"none",...s.style},onMouseDown:w(s.onMouseDown,()=>{A.current=!0}),onFocus:w(s.onFocus,g=>{const ue=!A.current;if(g.target===g.currentTarget&&ue&&!y){const M=new CustomEvent(_,Oe);if(g.currentTarget.dispatchEvent(M),!M.defaultPrevented){const F=N().filter(T=>T.focusable),de=F.find(T=>T.active),fe=F.find(T=>T.id===j),pe=[de,fe,...F].filter(Boolean).map(T=>T.ref.current);X(pe,a)}}A.current=!1}),onBlur:w(s.onBlur,()=>S(!1))})})}),J="RovingFocusGroupItem",Q=u.forwardRef((s,t)=>{const{__scopeRovingFocusGroup:r,focusable:n=!0,active:i=!1,tabStopId:d,children:l,...p}=s,v=H(),m=d||v,a=Be(J,r),c=a.currentTabStopId===m,x=Y(r),{onFocusableItemAdd:o,onFocusableItemRemove:h,currentTabStopId:j}=a;return u.useEffect(()=>{if(n)return o(),()=>h()},[n,o,h]),e.jsx(U.ItemSlot,{scope:r,id:m,focusable:n,active:i,children:e.jsx(P.span,{tabIndex:c?0:-1,"data-orientation":a.orientation,...p,ref:t,onMouseDown:w(s.onMouseDown,f=>{n?a.onItemFocus(m):f.preventDefault()}),onFocus:w(s.onFocus,()=>a.onItemFocus(m)),onKeyDown:w(s.onKeyDown,f=>{if(f.key==="Tab"&&f.shiftKey){a.onItemShiftTab();return}if(f.target!==f.currentTarget)return;const y=ze(f,a.orientation,a.dir);if(y!==void 0){if(f.metaKey||f.ctrlKey||f.altKey||f.shiftKey)return;f.preventDefault();let b=x().filter(N=>N.focusable).map(N=>N.ref.current);if(y==="last")b.reverse();else if(y==="prev"||y==="next"){y==="prev"&&b.reverse();const N=b.indexOf(f.currentTarget);b=a.loop?Ye(b,N+1):b.slice(N+1)}setTimeout(()=>X(b))}}),children:typeof l=="function"?l({isCurrentTabStop:c,hasTabStop:j!=null}):l})})});Q.displayName=J;var Ve={ArrowLeft:"prev",ArrowUp:"prev",ArrowRight:"next",ArrowDown:"next",PageUp:"first",Home:"first",PageDown:"last",End:"last"};function $e(s,t){return t!=="rtl"?s:s==="ArrowLeft"?"ArrowRight":s==="ArrowRight"?"ArrowLeft":s}function ze(s,t,r){const n=$e(s.key,r);if(!(t==="vertical"&&["ArrowLeft","ArrowRight"].includes(n))&&!(t==="horizontal"&&["ArrowUp","ArrowDown"].includes(n)))return Ve[n]}function X(s,t=!1){const r=document.activeElement;for(const n of s)if(n===r||(n.focus({preventScroll:t}),document.activeElement!==r))return}function Ye(s,t){return s.map((r,n)=>s[(t+n)%s.length])}var We=q,qe=Q,R="Tabs",[Je]=B(R,[W]),Z=W(),[Qe,L]=Je(R),ee=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,onValueChange:i,defaultValue:d,orientation:l="horizontal",dir:p,activationMode:v="automatic",...m}=s,a=$(p),[c,x]=V({prop:n,onChange:i,defaultProp:d??"",caller:R});return e.jsx(Qe,{scope:r,baseId:H(),value:c,onValueChange:x,orientation:l,dir:a,activationMode:v,children:e.jsx(P.div,{dir:a,"data-orientation":l,...m,ref:t})})});ee.displayName=R;var se="TabsList",te=u.forwardRef((s,t)=>{const{__scopeTabs:r,loop:n=!0,...i}=s,d=L(se,r),l=Z(r);return e.jsx(We,{asChild:!0,...l,orientation:d.orientation,dir:d.dir,loop:n,children:e.jsx(P.div,{role:"tablist","aria-orientation":d.orientation,...i,ref:t})})});te.displayName=se;var re="TabsTrigger",ne=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,disabled:i=!1,...d}=s,l=L(re,r),p=Z(r),v=ae(l.baseId,n),m=le(l.baseId,n),a=n===l.value;return e.jsx(qe,{asChild:!0,...p,focusable:!i,active:a,children:e.jsx(P.button,{type:"button",role:"tab","aria-selected":a,"aria-controls":m,"data-state":a?"active":"inactive","data-disabled":i?"":void 0,disabled:i,id:v,...d,ref:t,onMouseDown:w(s.onMouseDown,c=>{!i&&c.button===0&&c.ctrlKey===!1?l.onValueChange(n):c.preventDefault()}),onKeyDown:w(s.onKeyDown,c=>{[" ","Enter"].includes(c.key)&&l.onValueChange(n)}),onFocus:w(s.onFocus,()=>{const c=l.activationMode!=="manual";!a&&!i&&c&&l.onValueChange(n)})})})});ne.displayName=re;var oe="TabsContent",ie=u.forwardRef((s,t)=>{const{__scopeTabs:r,value:n,forceMount:i,children:d,...l}=s,p=L(oe,r),v=ae(p.baseId,n),m=le(p.baseId,n),a=n===p.value,c=u.useRef(a);return u.useEffect(()=>{const x=requestAnimationFrame(()=>c.current=!1);return()=>cancelAnimationFrame(x)},[]),e.jsx(Ne,{present:i||a,children:({present:x})=>e.jsx(P.div,{"data-state":a?"active":"inactive","data-orientation":p.orientation,role:"tabpanel","aria-labelledby":v,hidden:!x,id:m,tabIndex:0,...l,ref:t,style:{...s.style,animationDuration:c.current?"0s":void 0},children:x&&d})})});ie.displayName=oe;function ae(s,t){return`${s}-trigger-${t}`}function le(s,t){return`${s}-content-${t}`}var Xe=ee,Ze=te,es=ne,I=ie;function ss({status:s}){const t={running:{pinger:"bg-green-400",circle:"bg-green-500"},passed:{circle:"bg-green-500"},failed:{circle:"bg-red-500"},stopped:{circle:"bg-gray-500"}}[s];return e.jsxs("span",{className:"relative flex h-3 w-3",children:[t.pinger?e.jsx("span",{className:`absolute inline-flex h-full w-full animate-ping rounded-full ${t.pinger} opacity-75`}):null,e.jsx("span",{className:`relative inline-flex h-3 w-3 rounded-full ${t.circle}`})]})}function ts(){return e.jsxs("div",{className:"flex h-full w-full flex-col gap-4 pt-4",children:[e.jsx("div",{className:"text-center",children:e.jsx(Ae,{})}),e.jsx("div",{className:"bg-accent scrollbar-thin scrollbar-thumb-scrollbar flex-1 overflow-y-scroll pb-4",children:e.jsx(rs,{})})]})}function rs(){const s=me(),t=Fe(),r=z();return _e()?e.jsxs("div",{className:"flex h-full flex-col items-center justify-between",children:[e.jsx(u.Suspense,{fallback:e.jsx("div",{className:"flex h-full w-full flex-col items-center justify-center",children:e.jsx(Se,{children:"Loading Discord Posts"})}),children:e.jsx(xe,{resolve:s.discordPostsPromise,errorElement:e.jsx("div",{className:"text-red-500",children:"There was a problem loading the discord posts"}),children:i=>e.jsx("ul",{className:"flex w-full flex-col gap-4 p-3 xl:p-12",children:i.map(d=>e.jsx("li",{className:"bg-background rounded-xl border transition-all duration-200 focus-within:-translate-y-1 focus-within:shadow-lg hover:-translate-y-1 hover:shadow-lg",children:e.jsx(ns,{thread:d})},d.id))})})}),e.jsx("div",{children:e.jsxs(K,{to:r&&!t.includes("oauth")?t.replace(/^https/,"discord"):t,target:t.includes("oauth")?void 0:"_blank",rel:"noreferrer noopener",onClick:r?i=>{i.preventDefault(),window.open(i.currentTarget.href,"_blank","noreferrer noopener")}:void 0,className:"flex items-center gap-2 p-2 text-xl hover:underline",children:["Create Post ",e.jsx(C,{name:"ExternalLink"})]})})]}):e.jsx("div",{className:"flex h-full flex-col items-center justify-between",children:e.jsx("div",{className:"text-foreground-destructive flex h-full w-full flex-col items-center justify-center",children:e.jsx(C,{name:"WifiNoConnection",size:"xl",children:"Unable to load discord messages when offline"})})})}function ns({thread:s}){const t=s.reactions.filter(r=>r.count);return e.jsx("div",{children:e.jsxs("div",{className:"flex flex-col gap-2 p-4",children:[e.jsxs("div",{className:"flex gap-4",children:[e.jsxs("div",{className:"flex flex-col gap-1",children:[s.tags.length?e.jsx("div",{className:"flex gap-2",children:s.tags.map(r=>e.jsxs("div",{className:"bg-accent flex items-center justify-center gap-1 rounded-full px-2 py-1 text-sm",children:[e.jsx("span",{className:"h-3 w-3 leading-3",children:e.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),e.jsx("span",{children:r.name})]},r.name))}):null,e.jsx("strong",{className:"text-xl font-bold",children:s.name}),e.jsxs("div",{className:"flex items-start gap-1",children:[e.jsxs("div",{className:"flex items-center gap-1",children:[s.authorAvatarUrl?e.jsx("img",{src:s.authorAvatarUrl,alt:"",className:"h-6 w-6 rounded-full"}):null,e.jsxs("span",{children:[e.jsx("span",{className:"font-bold",style:s.authorHexAccentColor?{color:s.authorHexAccentColor}:{},children:s.authorDisplayName}),":"," "]})]}),e.jsx("span",{className:"text-muted-foreground flex-1 overflow-ellipsis",children:s.messagePreview})]})]}),s.previewImageUrl?e.jsx("img",{src:s.previewImageUrl,alt:"",className:"h-28 w-28 rounded-lg object-cover"}):null]}),e.jsxs("div",{className:"flex justify-between",children:[e.jsxs("div",{className:"flex items-center gap-3",children:[e.jsx("span",{children:t.length?e.jsx("ul",{className:"flex items-center gap-2",children:t.map((r,n)=>e.jsxs("li",{className:"flex items-center gap-1 rounded-md border border-blue-600 bg-blue-500/20 px-[5px] py-[0.5px] text-sm",children:[e.jsx("span",{className:"h-3 w-3 leading-3",children:e.jsx(G,{name:r.emojiName,url:r.emojiUrl})}),e.jsx("span",{children:r.count})]},n))}):null}),e.jsxs("span",{className:"flex items-center gap-1",children:[e.jsxs("span",{className:"inline-flex items-center gap-1",children:[e.jsx(C,{name:"Chat"})," ",s.messageCount]}),` · ${s.lastUpdatedDisplay}`]})]}),e.jsxs("span",{className:"flex items-center gap-4",children:[e.jsx("a",{href:s.link.replace(/^https/,"discord"),children:e.jsx(C,{name:"Discord"})}),e.jsx("a",{href:s.link,target:"_blank",rel:"noreferrer noopener",children:e.jsx(C,{name:"ExternalLink"})})]})]})]})})}function G({name:s,url:t}){return t?e.jsx("img",{src:t,alt:s,className:"h-full w-full"}):s||null}function os({appInfo:s,inBrowserBrowserRef:t,problemAppName:r,allApps:n,isUpToDate:i}){return e.jsx(De,{playgroundAppName:s?.appName,problemAppName:r,allApps:n,isUpToDate:i,children:s?.dev.type==="none"?e.jsxs("div",{className:"flex h-full flex-col items-center justify-center gap-4",children:[e.jsx("div",{className:"text-secondary-foreground text-2xl",children:"Non-UI exercise"}),e.jsxs("div",{className:"text-secondary-foreground max-w-md text-center text-balance",children:["This exercise has no application or other UI associated with it."," ",e.jsx("br",{}),"Navigate to"," ",e.jsx(Te,{content:s.fullPath,children:e.jsxs("span",{className:"inline-flex cursor-pointer items-center gap-1.5 underline",onClick:()=>{navigator.clipboard.writeText(s.fullPath),ke.success("Copied playground path to clipboard")},children:["the playground directory",e.jsx(C,{name:"Copy",size:"sm"})]})})," ","in your editor and follow the exercise instructions to complete it."]})]}):s?e.jsx(k,{id:s.appName,appInfo:s,inBrowserBrowserRef:t}):e.jsxs("div",{className:"flex flex-col justify-center gap-2",children:[e.jsx("p",{children:"Please set the playground first"}),r?e.jsx(Ue,{appName:r}):null]})})}const D=["playground","problem","solution","tests","diff","chat"],is=s=>!!(s&&D.includes(s));function as(s,t,r){const n=new URLSearchParams(s);return r===null?n.delete(t):n.set(t,r),n}const Ks=he(function({loaderData:t}){const{inBrowserBrowserRef:r}=ve(),n=Re(),[i]=je(),d=i.get("preview"),l=z(),p=be();function v(o){if(o==="tests")return ENV.EPICSHOP_DEPLOYED||!t.playground||t.playground.test.type==="none";if(o==="problem"||o==="solution"){if(t[o]?.dev.type==="none")return!0;if(ENV.EPICSHOP_DEPLOYED){const h=t[o]?.dev.type;return h!=="browser"&&h!=="export"&&!t[o]?.stackBlitzUrl}}return o==="playground"&&ENV.EPICSHOP_DEPLOYED?!0:o==="chat"?!n.product.discordChannelId:!1}function m(o){if(o==="tests"){if(!t.playground)return null;const{isTestRunning:h,testExitCode:j}=t.playground;return h?"running":j===0?"passed":j!==null&&j!==0?"failed":null}return(o==="problem"||o==="solution"||o==="playground")&&(o==="playground"?t.playground:t[o])?.isRunning?"running":null}const a=is(d)?d:D.find(o=>!v(o)),c=`/diff?${new URLSearchParams({app1:t.problem?.name??"",app2:t.solution?.name??""})}`;function x(o){o.altKey&&!o.ctrlKey&&!o.shiftKey&&!o.metaKey&&(o.preventDefault(),p(c))}return e.jsxs(Xe,{className:"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden sm:col-span-1 sm:row-span-1",value:a,children:[e.jsx(Ze,{className:"scrollbar-thin scrollbar-thumb-scrollbar h-14 min-h-14 overflow-x-auto border-b whitespace-nowrap",children:D.map(o=>{const h=v(o),j=m(o);return e.jsx(es,{value:o,hidden:h,asChild:!0,children:e.jsx(K,{id:`${o}-tab`,className:Ce("clip-path-button radix-state-active:z-10 radix-state-active:bg-foreground radix-state-active:text-background radix-state-active:hover:bg-foreground/80 radix-state-active:hover:text-background/80 radix-state-inactive:hover:bg-foreground/20 radix-state-inactive:hover:text-foreground/80 focus:bg-foreground/80 focus:text-background/80 relative h-full px-6 py-4 font-mono text-sm uppercase outline-none",h?"hidden":"inline-block"),preventScrollReset:!0,prefetch:"intent",onClick:x,to:o==="diff"&&l?c:`?${as(i,"preview",o==="playground"?null:o)}`,children:e.jsxs("span",{className:"flex items-center gap-2",children:[j&&e.jsx(ss,{status:j}),e.jsx("span",{children:o})]})})},o)})}),e.jsxs("div",{className:"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden",children:[e.jsx(I,{value:"playground",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(os,{appInfo:t.playground,problemAppName:t.problem?.name,inBrowserBrowserRef:r,allApps:t.allApps,isUpToDate:t.playground?.isUpToDate??!1})}),e.jsx(I,{value:"problem",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(k,{appInfo:t.problem,inBrowserBrowserRef:r})}),e.jsx(I,{value:"solution",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:e.jsx(k,{appInfo:t.solution,inBrowserBrowserRef:r})}),e.jsx(I,{value:"tests",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start overflow-hidden",children:e.jsx(Le,{appInfo:t.playground,problemAppName:t.problem?.name,allApps:t.allApps,isUpToDate:t.playground?.isUpToDate??!1,userHasAccessPromise:t.userHasAccessPromise})}),e.jsx(I,{value:"diff",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:e.jsx(Pe,{diff:t.diff,allApps:t.allApps,userHasAccessPromise:t.userHasAccessPromise})}),e.jsx(I,{value:"chat",className:"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start",children:e.jsx(ts,{})})]})]})}),Bs=ge(function(){return e.jsx(Ee,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."})}})});export{Bs as ErrorBoundary,Ks as default};
|
|
2
|
+
//# sourceMappingURL=index-CDG5ZZjr.js.map
|