@epic-web/workshop-app 6.57.0 → 6.58.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (30) hide show
  1. package/build/client/assets/{_exerciseNumber-D8mJvwwf.js → _exerciseNumber-COUjBGBi.js} +2 -2
  2. package/build/client/assets/{_exerciseNumber-D8mJvwwf.js.map → _exerciseNumber-COUjBGBi.js.map} +1 -1
  3. package/build/client/assets/{_exerciseNumber_.finished-ifOd5NuD.js → _exerciseNumber_.finished-BjiSuKGH.js} +2 -2
  4. package/build/client/assets/{_exerciseNumber_.finished-ifOd5NuD.js.map → _exerciseNumber_.finished-BjiSuKGH.js.map} +1 -1
  5. package/build/client/assets/{_layout-DDytBxiZ.js → _layout-DgA_wW0k.js} +2 -2
  6. package/build/client/assets/{_layout-DDytBxiZ.js.map → _layout-DgA_wW0k.js.map} +1 -1
  7. package/build/client/assets/{diff-CUbXRIeq.js → diff-BVJpb91n.js} +2 -2
  8. package/build/client/assets/{diff-CUbXRIeq.js.map → diff-BVJpb91n.js.map} +1 -1
  9. package/build/client/assets/{diff-GhgVnDeo.js → diff-BkCOoQXe.js} +2 -2
  10. package/build/client/assets/{diff-GhgVnDeo.js.map → diff-BkCOoQXe.js.map} +1 -1
  11. package/build/client/assets/{epic-video-DdaxOz-5.js → epic-video-DSeT-uKN.js} +123 -123
  12. package/build/client/assets/{epic-video-DdaxOz-5.js.map → epic-video-DSeT-uKN.js.map} +1 -1
  13. package/build/client/assets/{epic-video-BUuA-tBw.js → epic-video-ITsM_wbc.js} +2 -2
  14. package/build/client/assets/{epic-video-BUuA-tBw.js.map → epic-video-ITsM_wbc.js.map} +1 -1
  15. package/build/client/assets/{finished-Dug_uwjv.js → finished-CBJx9qcb.js} +2 -2
  16. package/build/client/assets/{finished-Dug_uwjv.js.map → finished-CBJx9qcb.js.map} +1 -1
  17. package/build/client/assets/{index-UPAFB0f0.js → index-Cr0r3TYc.js} +2 -2
  18. package/build/client/assets/{index-UPAFB0f0.js.map → index-Cr0r3TYc.js.map} +1 -1
  19. package/build/client/assets/{index-C2aC4iSz.js → index-DOotQobj.js} +2 -2
  20. package/build/client/assets/{index-C2aC4iSz.js.map → index-DOotQobj.js.map} +1 -1
  21. package/build/client/assets/{manifest-ade4e0c4.js → manifest-212b6ac9.js} +1 -1
  22. package/build/client/assets/{mdx-CTC7HBz7.js → mdx-Bez0LKTa.js} +2 -2
  23. package/build/client/assets/{mdx-CTC7HBz7.js.map → mdx-Bez0LKTa.js.map} +1 -1
  24. package/build/client/assets/{test-BDSMF-Kf.js → test-BjW5Fz1e.js} +2 -2
  25. package/build/client/assets/{test-BDSMF-Kf.js.map → test-BjW5Fz1e.js.map} +1 -1
  26. package/build/client/assets/{tests-CHg0zMRl.js → tests-ihMcV-RO.js} +2 -2
  27. package/build/client/assets/{tests-CHg0zMRl.js.map → tests-ihMcV-RO.js.map} +1 -1
  28. package/build/server/index.js +12 -2
  29. package/build/server/index.js.map +1 -1
  30. package/package.json +3 -3
@@ -1,2 +1,2 @@
1
- import{w}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as m}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{E as g,D as h}from"./epic-video-DdaxOz-5.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./index-Dvg33-i0.js";import"./misc-GmfBFNKU.js";import"./tooltip-DOPvLR3d.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./online-DlPkOHh3.js";import"./loading-TTjdHw_c.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";function l(p,r,i={}){const{schema:s}=i,e=crypto.randomUUID();return new Promise((t,o)=>{if(!window.parent||window.parent===window){console.log("[MCP] No parent frame available. Would have sent message:",{type:p,messageId:e,payload:r}),o(new Error("No parent frame available"));return}window.parent.postMessage({type:p,messageId:e,payload:r},"*");function n(a){if(a.data.type!=="ui-message-response"||a.data.messageId!==e)return;window.removeEventListener("message",n);const{response:d,error:f}=a.data.payload;if(f)return o(f);if(!s)return t(d);const c=s.safeParse(d);return c.success?t(c.data):o(c.error)}window.addEventListener("message",n)})}const D=w(function({loaderData:r}){const i=u.useRef(null);u.useEffect(()=>{r.videoInfos?.finally(()=>{if(window.parent.postMessage({type:"ui-lifecycle-iframe-ready"},"*"),!i.current)return;const e=i.current.clientHeight,t=i.current.clientWidth;window.parent.postMessage({type:"ui-size-change",payload:{height:e,width:t}},"*")})},[r.videoInfos]);async function s(e){const t=e.target;if(!(t instanceof HTMLAnchorElement))return;const o=t.href;if(!o)return;e.preventDefault(),e.stopPropagation();const n=o.startsWith("http")?new URL(o):new URL(o,window.location.origin);n.host===window.location.host&&n.pathname==="/login"&&await l("tool",{toolName:"login",params:{workshopDirectory:ENV.EPICSHOP_CONTEXT_CWD}}),await l("link",{url:n.toString()})}return m.jsx("div",{ref:i,onClickCapture:s,children:m.jsx(g,{epicVideoInfosPromise:r.videoInfos,children:m.jsx(h,{url:r.videoUrl})})})});export{D as default};
2
- //# sourceMappingURL=epic-video-BUuA-tBw.js.map
1
+ import{w}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as m}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{E as g,D as h}from"./epic-video-DSeT-uKN.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./index-Dvg33-i0.js";import"./misc-GmfBFNKU.js";import"./tooltip-DOPvLR3d.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./online-DlPkOHh3.js";import"./loading-TTjdHw_c.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";function l(p,r,i={}){const{schema:s}=i,e=crypto.randomUUID();return new Promise((t,o)=>{if(!window.parent||window.parent===window){console.log("[MCP] No parent frame available. Would have sent message:",{type:p,messageId:e,payload:r}),o(new Error("No parent frame available"));return}window.parent.postMessage({type:p,messageId:e,payload:r},"*");function n(a){if(a.data.type!=="ui-message-response"||a.data.messageId!==e)return;window.removeEventListener("message",n);const{response:d,error:f}=a.data.payload;if(f)return o(f);if(!s)return t(d);const c=s.safeParse(d);return c.success?t(c.data):o(c.error)}window.addEventListener("message",n)})}const D=w(function({loaderData:r}){const i=u.useRef(null);u.useEffect(()=>{r.videoInfos?.finally(()=>{if(window.parent.postMessage({type:"ui-lifecycle-iframe-ready"},"*"),!i.current)return;const e=i.current.clientHeight,t=i.current.clientWidth;window.parent.postMessage({type:"ui-size-change",payload:{height:e,width:t}},"*")})},[r.videoInfos]);async function s(e){const t=e.target;if(!(t instanceof HTMLAnchorElement))return;const o=t.href;if(!o)return;e.preventDefault(),e.stopPropagation();const n=o.startsWith("http")?new URL(o):new URL(o,window.location.origin);n.host===window.location.host&&n.pathname==="/login"&&await l("tool",{toolName:"login",params:{workshopDirectory:ENV.EPICSHOP_CONTEXT_CWD}}),await l("link",{url:n.toString()})}return m.jsx("div",{ref:i,onClickCapture:s,children:m.jsx(g,{epicVideoInfosPromise:r.videoInfos,children:m.jsx(h,{url:r.videoUrl})})})});export{D as default};
2
+ //# sourceMappingURL=epic-video-ITsM_wbc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"epic-video-BUuA-tBw.js","sources":["../../../app/routes/mcp-ui+/__utils.ts","../../../app/routes/mcp-ui+/epic-video.tsx"],"sourcesContent":["import { useEffect } from 'react'\nimport { type z } from 'zod'\n\nexport function useMcpUiInit(rootRef: React.RefObject<HTMLDivElement | null>) {\n\tuseEffect(() => {\n\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\t\tif (!rootRef.current) return\n\n\t\tconst height = rootRef.current.clientHeight\n\t\tconst width = rootRef.current.clientWidth\n\n\t\twindow.parent.postMessage(\n\t\t\t{ type: 'ui-size-change', payload: { height, width } },\n\t\t\t'*',\n\t\t)\n\t}, [rootRef])\n}\n\ntype MessageOptions = { schema?: z.ZodSchema }\n\ntype McpMessageReturnType<Options> = Promise<\n\tOptions extends { schema: z.ZodSchema } ? z.infer<Options['schema']> : unknown\n>\n\ntype McpMessageTypes = {\n\ttool: { toolName: string; params: Record<string, unknown> }\n\tprompt: { prompt: string }\n\tlink: { url: string }\n}\n\ntype McpMessageType = keyof McpMessageTypes\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'tool',\n\tpayload: McpMessageTypes['tool'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'prompt',\n\tpayload: McpMessageTypes['prompt'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'link',\n\tpayload: McpMessageTypes['link'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'link',\n\tpayload: McpMessageTypes['link'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage(\n\ttype: McpMessageType,\n\tpayload: McpMessageTypes[McpMessageType],\n\toptions: MessageOptions = {},\n): McpMessageReturnType<typeof options> {\n\tconst { schema } = options\n\tconst messageId = crypto.randomUUID()\n\n\treturn new Promise((resolve, reject) => {\n\t\tif (!window.parent || window.parent === window) {\n\t\t\tconsole.log(`[MCP] No parent frame available. Would have sent message:`, {\n\t\t\t\ttype,\n\t\t\t\tmessageId,\n\t\t\t\tpayload,\n\t\t\t})\n\t\t\treject(new Error('No parent frame available'))\n\t\t\treturn\n\t\t}\n\n\t\twindow.parent.postMessage({ type, messageId, payload }, '*')\n\n\t\tfunction handleMessage(event: MessageEvent) {\n\t\t\tif (event.data.type !== 'ui-message-response') return\n\t\t\tif (event.data.messageId !== messageId) return\n\t\t\twindow.removeEventListener('message', handleMessage)\n\n\t\t\tconst { response, error } = event.data.payload\n\n\t\t\tif (error) return reject(error)\n\t\t\tif (!schema) return resolve(response)\n\n\t\t\tconst parseResult = schema.safeParse(response)\n\t\t\tif (!parseResult.success) return reject(parseResult.error)\n\n\t\t\treturn resolve(parseResult.data)\n\t\t}\n\n\t\twindow.addEventListener('message', handleMessage)\n\t})\n}\n\nexport { sendMcpMessage }\n\nexport function waitForRenderData<RenderData>(\n\tschema: z.ZodSchema<RenderData>,\n): Promise<RenderData> {\n\treturn new Promise((resolve, reject) => {\n\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\n\t\tfunction handleMessage(event: MessageEvent) {\n\t\t\tif (event.data?.type !== 'ui-lifecycle-iframe-render-data') return\n\t\t\twindow.removeEventListener('message', handleMessage)\n\n\t\t\tconst { renderData, error } = event.data.payload\n\n\t\t\tif (error) return reject(error)\n\t\t\tif (!schema) return resolve(renderData)\n\n\t\t\tconst parseResult = schema.safeParse(renderData)\n\t\t\tif (!parseResult.success) return reject(parseResult.error)\n\n\t\t\treturn resolve(parseResult.data)\n\t\t}\n\n\t\twindow.addEventListener('message', handleMessage)\n\t})\n}\n","import { invariantResponse } from '@epic-web/invariant'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport { makeTimings } from '@epic-web/workshop-utils/timing.server'\nimport { useEffect, useRef } from 'react'\nimport { data } from 'react-router'\nimport {\n\tDeferredEpicVideo,\n\tEpicVideoInfoProvider,\n} from '#app/components/epic-video.tsx'\nimport { type Route } from './+types/epic-video.tsx'\nimport { sendMcpMessage } from './__utils.ts'\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('epicVideoLoader')\n\tconst videoUrl = new URL(request.url).searchParams.get('url')\n\tinvariantResponse(videoUrl, 'url param is required')\n\tconst videoInfos = getEpicVideoInfos([videoUrl], {\n\t\trequest,\n\t\ttimings,\n\t})\n\treturn data(\n\t\t{ videoInfos, videoUrl },\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 default function EpicVideoEmbedRoute({\n\tloaderData,\n}: Route.ComponentProps) {\n\tconst rootRef = useRef<HTMLDivElement>(null)\n\tuseEffect(() => {\n\t\tvoid loaderData.videoInfos?.finally(() => {\n\t\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\t\t\tif (!rootRef.current) return\n\n\t\t\tconst height = rootRef.current.clientHeight\n\t\t\tconst width = rootRef.current.clientWidth\n\n\t\t\twindow.parent.postMessage(\n\t\t\t\t{ type: 'ui-size-change', payload: { height, width } },\n\t\t\t\t'*',\n\t\t\t)\n\t\t})\n\t}, [loaderData.videoInfos])\n\n\tasync function handleLinksClick(event: React.MouseEvent<HTMLElement>) {\n\t\tconst target = event.target\n\t\tif (!(target instanceof HTMLAnchorElement)) return\n\n\t\tconst href = target.href\n\t\tif (!href) return\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\n\t\tconst url = href.startsWith('http')\n\t\t\t? new URL(href)\n\t\t\t: new URL(href, window.location.origin)\n\t\tconst isLocal = url.host === window.location.host\n\n\t\tif (isLocal && url.pathname === '/login') {\n\t\t\tawait sendMcpMessage('tool', {\n\t\t\t\ttoolName: 'login',\n\t\t\t\tparams: { workshopDirectory: ENV.EPICSHOP_CONTEXT_CWD },\n\t\t\t})\n\t\t}\n\n\t\tawait sendMcpMessage('link', { url: url.toString() })\n\t}\n\n\treturn (\n\t\t<div ref={rootRef} onClickCapture={handleLinksClick}>\n\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={loaderData.videoInfos}>\n\t\t\t\t<DeferredEpicVideo url={loaderData.videoUrl} />\n\t\t\t</EpicVideoInfoProvider>\n\t\t</div>\n\t)\n}\n"],"names":["sendMcpMessage","type","payload","options","schema","messageId","resolve","reject","handleMessage","event","response","error","parseResult","epicVideo","_UNSAFE_withComponentProps","loaderData","rootRef","useRef","useEffect","videoInfos","finally","window","parent","postMessage","current","height","clientHeight","width","clientWidth","handleLinksClick","target","HTMLAnchorElement","href","preventDefault","stopPropagation","url","startsWith","URL","location","origin","host","pathname","toolName","params","workshopDirectory","ENV","EPICSHOP_CONTEXT_CWD","toString","ref","onClickCapture","children","jsx","EpicVideoInfoProvider","epicVideoInfosPromise","DeferredEpicVideo","videoUrl"],"mappings":"6jBAwDA,SAASA,EACRC,EACAC,EACAC,EAA0B,CAAA,EACa,CACvC,KAAM,CAAE,OAAAC,GAAWD,EACbE,EAAY,OAAO,WAAA,EAEzB,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACvC,GAAI,CAAC,OAAO,QAAU,OAAO,SAAW,OAAQ,CAC/C,QAAQ,IAAI,4DAA6D,CACxE,KAAAN,EACA,UAAAI,EACA,QAAAH,CAAA,CACA,EACDK,EAAO,IAAI,MAAM,2BAA2B,CAAC,EAC7C,MACD,CAEA,OAAO,OAAO,YAAY,CAAE,KAAAN,EAAM,UAAAI,EAAW,QAAAH,CAAA,EAAW,GAAG,EAE3D,SAASM,EAAcC,EAAqB,CAE3C,GADIA,EAAM,KAAK,OAAS,uBACpBA,EAAM,KAAK,YAAcJ,EAAW,OACxC,OAAO,oBAAoB,UAAWG,CAAa,EAEnD,KAAM,CAAE,SAAAE,EAAU,MAAAC,CAAA,EAAUF,EAAM,KAAK,QAEvC,GAAIE,EAAO,OAAOJ,EAAOI,CAAK,EAC9B,GAAI,CAACP,EAAQ,OAAOE,EAAQI,CAAQ,EAEpC,MAAME,EAAcR,EAAO,UAAUM,CAAQ,EAC7C,OAAKE,EAAY,QAEVN,EAAQM,EAAY,IAAI,EAFEL,EAAOK,EAAY,KAAK,CAG1D,CAEA,OAAO,iBAAiB,UAAWJ,CAAa,CACjD,CAAC,CACF,CCjEA,MAAAK,EAAAC,EAAA,SAA4C,CAC3CC,WAAAA,CACD,EAAyB,CACxB,MAAMC,EAAUC,EAAAA,OAAuB,IAAI,EAC3CC,EAAAA,UAAU,IAAM,CACVH,EAAWI,YAAYC,QAAQ,IAAM,CAEzC,GADAC,OAAOC,OAAOC,YAAY,CAAEtB,KAAM,6BAA+B,GAAG,EAChE,CAACe,EAAQQ,QAAS,OAEtB,MAAMC,EAAST,EAAQQ,QAAQE,aACzBC,EAAQX,EAAQQ,QAAQI,YAE9BP,OAAOC,OAAOC,YACb,CAAEtB,KAAM,iBAAkBC,QAAS,CAAEuB,OAAAA,EAAQE,MAAAA,CAAM,GACnD,GACD,CACD,CAAC,CACF,EAAG,CAACZ,EAAWI,UAAU,CAAC,EAE1B,eAAeU,EAAiBpB,EAAsC,CACrE,MAAMqB,EAASrB,EAAMqB,OACrB,GAAI,EAAEA,aAAkBC,mBAAoB,OAE5C,MAAMC,EAAOF,EAAOE,KACpB,GAAI,CAACA,EAAM,OAEXvB,EAAMwB,eAAA,EACNxB,EAAMyB,gBAAA,EAEN,MAAMC,EAAMH,EAAKI,WAAW,MAAM,EAC/B,IAAIC,IAAIL,CAAI,EACZ,IAAIK,IAAIL,EAAMX,OAAOiB,SAASC,MAAM,EACvBJ,EAAIK,OAASnB,OAAOiB,SAASE,MAE9BL,EAAIM,WAAa,UAC/B,MAAMzC,EAAe,OAAQ,CAC5B0C,SAAU,QACVC,OAAQ,CAAEC,kBAAmBC,IAAIC,oBAAqB,CACvD,CAAC,EAGF,MAAM9C,EAAe,OAAQ,CAAEmC,IAAKA,EAAIY,SAAA,CAAW,CAAC,CACrD,CAEA,aACE,MAAA,CAAIC,IAAKhC,EAASiC,eAAgBpB,EAClCqB,SAAAC,EAAAA,IAACC,EAAA,CAAsBC,sBAAuBtC,EAAWI,WACxD+B,SAAAC,EAAAA,IAACG,EAAA,CAAkBnB,IAAKpB,EAAWwC,SAAU,EAC9C,CAAA,CACD,CAEF,CAAA"}
1
+ {"version":3,"file":"epic-video-ITsM_wbc.js","sources":["../../../app/routes/mcp-ui+/__utils.ts","../../../app/routes/mcp-ui+/epic-video.tsx"],"sourcesContent":["import { useEffect } from 'react'\nimport { type z } from 'zod'\n\nexport function useMcpUiInit(rootRef: React.RefObject<HTMLDivElement | null>) {\n\tuseEffect(() => {\n\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\t\tif (!rootRef.current) return\n\n\t\tconst height = rootRef.current.clientHeight\n\t\tconst width = rootRef.current.clientWidth\n\n\t\twindow.parent.postMessage(\n\t\t\t{ type: 'ui-size-change', payload: { height, width } },\n\t\t\t'*',\n\t\t)\n\t}, [rootRef])\n}\n\ntype MessageOptions = { schema?: z.ZodSchema }\n\ntype McpMessageReturnType<Options> = Promise<\n\tOptions extends { schema: z.ZodSchema } ? z.infer<Options['schema']> : unknown\n>\n\ntype McpMessageTypes = {\n\ttool: { toolName: string; params: Record<string, unknown> }\n\tprompt: { prompt: string }\n\tlink: { url: string }\n}\n\ntype McpMessageType = keyof McpMessageTypes\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'tool',\n\tpayload: McpMessageTypes['tool'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'prompt',\n\tpayload: McpMessageTypes['prompt'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'link',\n\tpayload: McpMessageTypes['link'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage<Options extends MessageOptions>(\n\ttype: 'link',\n\tpayload: McpMessageTypes['link'],\n\toptions?: Options,\n): McpMessageReturnType<Options>\n\nfunction sendMcpMessage(\n\ttype: McpMessageType,\n\tpayload: McpMessageTypes[McpMessageType],\n\toptions: MessageOptions = {},\n): McpMessageReturnType<typeof options> {\n\tconst { schema } = options\n\tconst messageId = crypto.randomUUID()\n\n\treturn new Promise((resolve, reject) => {\n\t\tif (!window.parent || window.parent === window) {\n\t\t\tconsole.log(`[MCP] No parent frame available. Would have sent message:`, {\n\t\t\t\ttype,\n\t\t\t\tmessageId,\n\t\t\t\tpayload,\n\t\t\t})\n\t\t\treject(new Error('No parent frame available'))\n\t\t\treturn\n\t\t}\n\n\t\twindow.parent.postMessage({ type, messageId, payload }, '*')\n\n\t\tfunction handleMessage(event: MessageEvent) {\n\t\t\tif (event.data.type !== 'ui-message-response') return\n\t\t\tif (event.data.messageId !== messageId) return\n\t\t\twindow.removeEventListener('message', handleMessage)\n\n\t\t\tconst { response, error } = event.data.payload\n\n\t\t\tif (error) return reject(error)\n\t\t\tif (!schema) return resolve(response)\n\n\t\t\tconst parseResult = schema.safeParse(response)\n\t\t\tif (!parseResult.success) return reject(parseResult.error)\n\n\t\t\treturn resolve(parseResult.data)\n\t\t}\n\n\t\twindow.addEventListener('message', handleMessage)\n\t})\n}\n\nexport { sendMcpMessage }\n\nexport function waitForRenderData<RenderData>(\n\tschema: z.ZodSchema<RenderData>,\n): Promise<RenderData> {\n\treturn new Promise((resolve, reject) => {\n\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\n\t\tfunction handleMessage(event: MessageEvent) {\n\t\t\tif (event.data?.type !== 'ui-lifecycle-iframe-render-data') return\n\t\t\twindow.removeEventListener('message', handleMessage)\n\n\t\t\tconst { renderData, error } = event.data.payload\n\n\t\t\tif (error) return reject(error)\n\t\t\tif (!schema) return resolve(renderData)\n\n\t\t\tconst parseResult = schema.safeParse(renderData)\n\t\t\tif (!parseResult.success) return reject(parseResult.error)\n\n\t\t\treturn resolve(parseResult.data)\n\t\t}\n\n\t\twindow.addEventListener('message', handleMessage)\n\t})\n}\n","import { invariantResponse } from '@epic-web/invariant'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport { makeTimings } from '@epic-web/workshop-utils/timing.server'\nimport { useEffect, useRef } from 'react'\nimport { data } from 'react-router'\nimport {\n\tDeferredEpicVideo,\n\tEpicVideoInfoProvider,\n} from '#app/components/epic-video.tsx'\nimport { type Route } from './+types/epic-video.tsx'\nimport { sendMcpMessage } from './__utils.ts'\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('epicVideoLoader')\n\tconst videoUrl = new URL(request.url).searchParams.get('url')\n\tinvariantResponse(videoUrl, 'url param is required')\n\tconst videoInfos = getEpicVideoInfos([videoUrl], {\n\t\trequest,\n\t\ttimings,\n\t})\n\treturn data(\n\t\t{ videoInfos, videoUrl },\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 default function EpicVideoEmbedRoute({\n\tloaderData,\n}: Route.ComponentProps) {\n\tconst rootRef = useRef<HTMLDivElement>(null)\n\tuseEffect(() => {\n\t\tvoid loaderData.videoInfos?.finally(() => {\n\t\t\twindow.parent.postMessage({ type: 'ui-lifecycle-iframe-ready' }, '*')\n\t\t\tif (!rootRef.current) return\n\n\t\t\tconst height = rootRef.current.clientHeight\n\t\t\tconst width = rootRef.current.clientWidth\n\n\t\t\twindow.parent.postMessage(\n\t\t\t\t{ type: 'ui-size-change', payload: { height, width } },\n\t\t\t\t'*',\n\t\t\t)\n\t\t})\n\t}, [loaderData.videoInfos])\n\n\tasync function handleLinksClick(event: React.MouseEvent<HTMLElement>) {\n\t\tconst target = event.target\n\t\tif (!(target instanceof HTMLAnchorElement)) return\n\n\t\tconst href = target.href\n\t\tif (!href) return\n\n\t\tevent.preventDefault()\n\t\tevent.stopPropagation()\n\n\t\tconst url = href.startsWith('http')\n\t\t\t? new URL(href)\n\t\t\t: new URL(href, window.location.origin)\n\t\tconst isLocal = url.host === window.location.host\n\n\t\tif (isLocal && url.pathname === '/login') {\n\t\t\tawait sendMcpMessage('tool', {\n\t\t\t\ttoolName: 'login',\n\t\t\t\tparams: { workshopDirectory: ENV.EPICSHOP_CONTEXT_CWD },\n\t\t\t})\n\t\t}\n\n\t\tawait sendMcpMessage('link', { url: url.toString() })\n\t}\n\n\treturn (\n\t\t<div ref={rootRef} onClickCapture={handleLinksClick}>\n\t\t\t<EpicVideoInfoProvider epicVideoInfosPromise={loaderData.videoInfos}>\n\t\t\t\t<DeferredEpicVideo url={loaderData.videoUrl} />\n\t\t\t</EpicVideoInfoProvider>\n\t\t</div>\n\t)\n}\n"],"names":["sendMcpMessage","type","payload","options","schema","messageId","resolve","reject","handleMessage","event","response","error","parseResult","epicVideo","_UNSAFE_withComponentProps","loaderData","rootRef","useRef","useEffect","videoInfos","finally","window","parent","postMessage","current","height","clientHeight","width","clientWidth","handleLinksClick","target","HTMLAnchorElement","href","preventDefault","stopPropagation","url","startsWith","URL","location","origin","host","pathname","toolName","params","workshopDirectory","ENV","EPICSHOP_CONTEXT_CWD","toString","ref","onClickCapture","children","jsx","EpicVideoInfoProvider","epicVideoInfosPromise","DeferredEpicVideo","videoUrl"],"mappings":"6jBAwDA,SAASA,EACRC,EACAC,EACAC,EAA0B,CAAA,EACa,CACvC,KAAM,CAAE,OAAAC,GAAWD,EACbE,EAAY,OAAO,WAAA,EAEzB,OAAO,IAAI,QAAQ,CAACC,EAASC,IAAW,CACvC,GAAI,CAAC,OAAO,QAAU,OAAO,SAAW,OAAQ,CAC/C,QAAQ,IAAI,4DAA6D,CACxE,KAAAN,EACA,UAAAI,EACA,QAAAH,CAAA,CACA,EACDK,EAAO,IAAI,MAAM,2BAA2B,CAAC,EAC7C,MACD,CAEA,OAAO,OAAO,YAAY,CAAE,KAAAN,EAAM,UAAAI,EAAW,QAAAH,CAAA,EAAW,GAAG,EAE3D,SAASM,EAAcC,EAAqB,CAE3C,GADIA,EAAM,KAAK,OAAS,uBACpBA,EAAM,KAAK,YAAcJ,EAAW,OACxC,OAAO,oBAAoB,UAAWG,CAAa,EAEnD,KAAM,CAAE,SAAAE,EAAU,MAAAC,CAAA,EAAUF,EAAM,KAAK,QAEvC,GAAIE,EAAO,OAAOJ,EAAOI,CAAK,EAC9B,GAAI,CAACP,EAAQ,OAAOE,EAAQI,CAAQ,EAEpC,MAAME,EAAcR,EAAO,UAAUM,CAAQ,EAC7C,OAAKE,EAAY,QAEVN,EAAQM,EAAY,IAAI,EAFEL,EAAOK,EAAY,KAAK,CAG1D,CAEA,OAAO,iBAAiB,UAAWJ,CAAa,CACjD,CAAC,CACF,CCjEA,MAAAK,EAAAC,EAAA,SAA4C,CAC3CC,WAAAA,CACD,EAAyB,CACxB,MAAMC,EAAUC,EAAAA,OAAuB,IAAI,EAC3CC,EAAAA,UAAU,IAAM,CACVH,EAAWI,YAAYC,QAAQ,IAAM,CAEzC,GADAC,OAAOC,OAAOC,YAAY,CAAEtB,KAAM,6BAA+B,GAAG,EAChE,CAACe,EAAQQ,QAAS,OAEtB,MAAMC,EAAST,EAAQQ,QAAQE,aACzBC,EAAQX,EAAQQ,QAAQI,YAE9BP,OAAOC,OAAOC,YACb,CAAEtB,KAAM,iBAAkBC,QAAS,CAAEuB,OAAAA,EAAQE,MAAAA,CAAM,GACnD,GACD,CACD,CAAC,CACF,EAAG,CAACZ,EAAWI,UAAU,CAAC,EAE1B,eAAeU,EAAiBpB,EAAsC,CACrE,MAAMqB,EAASrB,EAAMqB,OACrB,GAAI,EAAEA,aAAkBC,mBAAoB,OAE5C,MAAMC,EAAOF,EAAOE,KACpB,GAAI,CAACA,EAAM,OAEXvB,EAAMwB,eAAA,EACNxB,EAAMyB,gBAAA,EAEN,MAAMC,EAAMH,EAAKI,WAAW,MAAM,EAC/B,IAAIC,IAAIL,CAAI,EACZ,IAAIK,IAAIL,EAAMX,OAAOiB,SAASC,MAAM,EACvBJ,EAAIK,OAASnB,OAAOiB,SAASE,MAE9BL,EAAIM,WAAa,UAC/B,MAAMzC,EAAe,OAAQ,CAC5B0C,SAAU,QACVC,OAAQ,CAAEC,kBAAmBC,IAAIC,oBAAqB,CACvD,CAAC,EAGF,MAAM9C,EAAe,OAAQ,CAAEmC,IAAKA,EAAIY,SAAA,CAAW,CAAC,CACrD,CAEA,aACE,MAAA,CAAIC,IAAKhC,EAASiC,eAAgBpB,EAClCqB,SAAAC,EAAAA,IAACC,EAAA,CAAsBC,sBAAuBtC,EAAWI,WACxD+B,SAAAC,EAAAA,IAACG,EAAA,CAAkBnB,IAAKpB,EAAWwC,SAAU,EAC9C,CAAA,CACD,CAEF,CAAA"}
@@ -1,2 +1,2 @@
1
- import{w as n,L as l}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{E as a}from"./index-C5c6Cdgw.js";import{r as c}from"./index-Az39ZADK.js";import{E as m}from"./epic-video-DdaxOz-5.js";import{I as d,c as p}from"./misc-GmfBFNKU.js";import{L as f}from"./loading-TTjdHw_c.js";import{N as h}from"./nav-chevrons-C1okk63A.js";import{u as x}from"./revalidation-ws-BdlKZ8s_.js";import{M as u}from"./mdx-CTC7HBz7.js";import{u as j}from"./online-DlPkOHh3.js";import{g as b}from"./root-loader-CcoJXu7H.js";import{g}from"./seo-t5J-DRxw.js";import{E as v}from"./launch-editor-B4NVrR9O.js";import{P as w}from"./progress-1Egr2Ysk.js";import{u as N}from"./index-Dvg33-i0.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./types-Cl2NuNg4.js";import"./tooltip-DOPvLR3d.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-CXiAexcc.js";import"./pe-BgHP_H47.js";const Z={getSitemapEntries:()=>[{route:"/finished"}]},_=({matches:r})=>{const s=b(r);return s?g({title:`🎉 ${s?.workshopTitle}`,description:`Elaboration for ${s?.workshopTitle}`,ogTitle:`Finished ${s?.workshopTitle}`,ogDescription:"You finished! Time to submit feedback.",instructor:s.instructor,requestInfo:s.requestInfo}):[]},k={h1:()=>null},ee=n(function({loaderData:s}){return x({watchPaths:["./exercises/FINISHED.mdx"]}),e.jsx("div",{className:"flex h-full grow flex-col",children:e.jsxs("main",{className:"grid h-full grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1",children:[e.jsxs("div",{className:"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r",children:[e.jsx("h1",{className:"h-14 border-b pr-5 pl-10 text-sm leading-none font-medium uppercase",children:e.jsx("div",{className:"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2",children:e.jsxs("div",{className:"flex items-center justify-start gap-x-2",children:[e.jsx(l,{to:"/",className:"hover:underline",children:s.workshopTitle}),e.jsx("span",{children:"/"}),e.jsx("span",{children:"Elaboration"})]})})}),e.jsx("article",{className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8",id:s.articleId,children:s.finishedCode?e.jsx(m,{epicVideoInfosPromise:s.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(u,{code:s.finishedCode,components:k})})}):"No finished instructions yet..."}),e.jsx(a,{elementQuery:`#${s.articleId}`}),e.jsx(w,{type:"workshop-finished",className:"h-14 border-t px-6"}),e.jsxs("div",{className:"@container flex h-16 justify-between border-t border-b-4 lg:border-b-0",children:[e.jsx("div",{}),s.workshopFinished.status==="success"?e.jsx(v,{file:s.workshopFinished.file,relativePath:s.workshopFinished.relativePath}):null,e.jsx(h,{prev:s.prevStepLink,next:{to:"/"}})]})]}),e.jsx(E,{workshopTitle:s.workshopTitle,workshopFormEmbedUrl:s.workshopFormEmbedUrl})]})})});function E({workshopTitle:r,workshopFormEmbedUrl:s}){const t=N(),[o,i]=c.useState(!1);return j()?e.jsxs("div",{className:"relative shrink-0",children:[o?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(f,{children:e.jsxs("span",{children:["Loading ",r," Elaboration form"]})})}),e.jsx("iframe",{onLoad:()=>i(!0),onError:()=>i(!0),title:"Elaboration",src:s,className:p("absolute inset-0 flex h-full w-full transition-opacity duration-300",o?"opacity-100":"opacity-0"),style:{colorScheme:t}})]}):e.jsx("div",{className:"relative shrink-0",children:e.jsx("div",{className:"text-foreground-destructive absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(d,{name:"WifiNoConnection",size:"xl",children:e.jsxs("span",{children:["Unable to load the ",e.jsx("a",{href:s,className:"underline",children:`${r} feedback form`})," when offline"]})})})})}export{ee as default,Z as handle,_ as meta};
2
- //# sourceMappingURL=finished-Dug_uwjv.js.map
1
+ import{w as n,L as l}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{E as a}from"./index-C5c6Cdgw.js";import{r as c}from"./index-Az39ZADK.js";import{E as m}from"./epic-video-DSeT-uKN.js";import{I as d,c as p}from"./misc-GmfBFNKU.js";import{L as f}from"./loading-TTjdHw_c.js";import{N as h}from"./nav-chevrons-C1okk63A.js";import{u as x}from"./revalidation-ws-BdlKZ8s_.js";import{M as u}from"./mdx-Bez0LKTa.js";import{u as j}from"./online-DlPkOHh3.js";import{g as b}from"./root-loader-CcoJXu7H.js";import{g}from"./seo-t5J-DRxw.js";import{E as v}from"./launch-editor-B4NVrR9O.js";import{P as w}from"./progress-1Egr2Ysk.js";import{u as N}from"./index-Dvg33-i0.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./types-Cl2NuNg4.js";import"./tooltip-DOPvLR3d.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-CXiAexcc.js";import"./pe-BgHP_H47.js";const Z={getSitemapEntries:()=>[{route:"/finished"}]},_=({matches:r})=>{const s=b(r);return s?g({title:`🎉 ${s?.workshopTitle}`,description:`Elaboration for ${s?.workshopTitle}`,ogTitle:`Finished ${s?.workshopTitle}`,ogDescription:"You finished! Time to submit feedback.",instructor:s.instructor,requestInfo:s.requestInfo}):[]},k={h1:()=>null},ee=n(function({loaderData:s}){return x({watchPaths:["./exercises/FINISHED.mdx"]}),e.jsx("div",{className:"flex h-full grow flex-col",children:e.jsxs("main",{className:"grid h-full grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1",children:[e.jsxs("div",{className:"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r",children:[e.jsx("h1",{className:"h-14 border-b pr-5 pl-10 text-sm leading-none font-medium uppercase",children:e.jsx("div",{className:"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2",children:e.jsxs("div",{className:"flex items-center justify-start gap-x-2",children:[e.jsx(l,{to:"/",className:"hover:underline",children:s.workshopTitle}),e.jsx("span",{children:"/"}),e.jsx("span",{children:"Elaboration"})]})})}),e.jsx("article",{className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8",id:s.articleId,children:s.finishedCode?e.jsx(m,{epicVideoInfosPromise:s.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(u,{code:s.finishedCode,components:k})})}):"No finished instructions yet..."}),e.jsx(a,{elementQuery:`#${s.articleId}`}),e.jsx(w,{type:"workshop-finished",className:"h-14 border-t px-6"}),e.jsxs("div",{className:"@container flex h-16 justify-between border-t border-b-4 lg:border-b-0",children:[e.jsx("div",{}),s.workshopFinished.status==="success"?e.jsx(v,{file:s.workshopFinished.file,relativePath:s.workshopFinished.relativePath}):null,e.jsx(h,{prev:s.prevStepLink,next:{to:"/"}})]})]}),e.jsx(E,{workshopTitle:s.workshopTitle,workshopFormEmbedUrl:s.workshopFormEmbedUrl})]})})});function E({workshopTitle:r,workshopFormEmbedUrl:s}){const t=N(),[o,i]=c.useState(!1);return j()?e.jsxs("div",{className:"relative shrink-0",children:[o?null:e.jsx("div",{className:"absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(f,{children:e.jsxs("span",{children:["Loading ",r," Elaboration form"]})})}),e.jsx("iframe",{onLoad:()=>i(!0),onError:()=>i(!0),title:"Elaboration",src:s,className:p("absolute inset-0 flex h-full w-full transition-opacity duration-300",o?"opacity-100":"opacity-0"),style:{colorScheme:t}})]}):e.jsx("div",{className:"relative shrink-0",children:e.jsx("div",{className:"text-foreground-destructive absolute inset-0 z-10 flex items-center justify-center",children:e.jsx(d,{name:"WifiNoConnection",size:"xl",children:e.jsxs("span",{children:["Unable to load the ",e.jsx("a",{href:s,className:"underline",children:`${r} feedback form`})," when offline"]})})})})}export{ee as default,Z as handle,_ as meta};
2
+ //# sourceMappingURL=finished-CBJx9qcb.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"finished-Dug_uwjv.js","sources":["../../../app/routes/_app+/finished.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopFinished,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport slugify from '@sindresorhus/slugify'\nimport * as React from 'react'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { useIsOnline } from '#app/utils/online.ts'\nimport { getRootMatchLoaderData } from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport { EditFileOnGitHub } from '../launch-editor.tsx'\nimport { ProgressToggle } from '../progress.tsx'\nimport { useTheme } from '../theme/index.tsx'\nimport { type Route } from './+types/finished.tsx'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => [{ route: '/finished' }],\n}\n\nexport const meta: Route.MetaFunction = ({ matches }) => {\n\tconst rootData = getRootMatchLoaderData(matches)\n\tif (!rootData) return []\n\n\treturn getSeoMetaTags({\n\t\ttitle: `🎉 ${rootData?.workshopTitle}`,\n\t\tdescription: `Elaboration for ${rootData?.workshopTitle}`,\n\t\togTitle: `Finished ${rootData?.workshopTitle}`,\n\t\togDescription: `You finished! Time to submit feedback.`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('finishedLoader')\n\tconst exercises = await getExercises({ request, timings })\n\tconst compiledFinished = await time(() => getWorkshopFinished({ request }), {\n\t\ttimings,\n\t\ttype: 'compileMdx',\n\t\tdesc: 'compileMdx in finished',\n\t})\n\n\tconst lastExercises = exercises[exercises.length - 1]\n\tconst workshopConfig = getWorkshopConfig()\n\tconst workshopTitle = workshopConfig.title\n\tconst workshopFormTemplate = workshopConfig.forms.workshop\n\tconst workshopFormEmbedUrl = workshopFormTemplate.replace(\n\t\t'{workshopTitle}',\n\t\tencodeURIComponent(workshopTitle),\n\t)\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(workshopTitle)}-finished`,\n\t\t\tworkshopTitle,\n\t\t\tworkshopFormEmbedUrl,\n\t\t\tfinishedCode:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? compiledFinished.compiled.code\n\t\t\t\t\t: null,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(compiledFinished.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\n\t\t\tworkshopFinished: {\n\t\t\t\tstatus: compiledFinished.compiled.status,\n\t\t\t\tfile: compiledFinished.file,\n\t\t\t\trelativePath: compiledFinished.relativePath,\n\t\t\t},\n\t\t\tprevStepLink: lastExercises\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/${lastExercises.exerciseNumber}/finished`,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t},\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'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst mdxComponents = { h1: () => null }\n\nexport default function ExerciseFinished({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tuseRevalidationWS({ watchPaths: ['./exercises/FINISHED.mdx'] })\n\treturn (\n\t\t<div className=\"flex h-full grow flex-col\">\n\t\t\t<main className=\"grid h-full grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1\">\n\t\t\t\t<div className=\"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r\">\n\t\t\t\t\t<h1 className=\"h-14 border-b pr-5 pl-10 text-sm leading-none font-medium uppercase\">\n\t\t\t\t\t\t<div className=\"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2\">\n\t\t\t\t\t\t\t\t<Link to=\"/\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{data.workshopTitle}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t<span>/</span>\n\t\t\t\t\t\t\t\t<span>Elaboration</span>\n\t\t\t\t\t\t\t</div>\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\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8\"\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.finishedCode ? (\n\t\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t\t<Mdx code={data.finishedCode} components={mdxComponents} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t// TODO: render a random dad joke...\n\t\t\t\t\t\t\t'No finished instructions yet...'\n\t\t\t\t\t\t)}\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\ttype=\"workshop-finished\"\n\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"@container 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{data.workshopFinished.status === 'success' ? (\n\t\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\t\tfile={data.workshopFinished.file}\n\t\t\t\t\t\t\t\trelativePath={data.workshopFinished.relativePath}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<NavChevrons prev={data.prevStepLink} next={{ to: '/' }} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<Survey\n\t\t\t\t\tworkshopTitle={data.workshopTitle}\n\t\t\t\t\tworkshopFormEmbedUrl={data.workshopFormEmbedUrl}\n\t\t\t\t/>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nfunction Survey({\n\tworkshopTitle,\n\tworkshopFormEmbedUrl,\n}: {\n\tworkshopTitle: string\n\tworkshopFormEmbedUrl: string\n}) {\n\tconst theme = useTheme()\n\tconst [iframeLoaded, setIframeLoaded] = React.useState(false)\n\tconst isOnline = useIsOnline()\n\tif (!isOnline) {\n\t\treturn (\n\t\t\t<div className=\"relative shrink-0\">\n\t\t\t\t<div className=\"text-foreground-destructive absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Icon name=\"WifiNoConnection\" size=\"xl\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{'Unable to load the '}\n\t\t\t\t\t\t\t<a href={workshopFormEmbedUrl} className=\"underline\">\n\t\t\t\t\t\t\t\t{`${workshopTitle} feedback form`}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t{' when offline'}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Icon>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t)\n\t}\n\treturn (\n\t\t<div className=\"relative shrink-0\">\n\t\t\t{!iframeLoaded ? (\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Loading>\n\t\t\t\t\t\t<span>Loading {workshopTitle} Elaboration form</span>\n\t\t\t\t\t</Loading>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<iframe\n\t\t\t\tonLoad={() => setIframeLoaded(true)}\n\t\t\t\t// show what would have shown if there is an error\n\t\t\t\tonError={() => setIframeLoaded(true)}\n\t\t\t\ttitle=\"Elaboration\"\n\t\t\t\tsrc={workshopFormEmbedUrl}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'absolute inset-0 flex h-full w-full transition-opacity duration-300',\n\t\t\t\t\tiframeLoaded ? 'opacity-100' : 'opacity-0',\n\t\t\t\t)}\n\t\t\t\tstyle={{ colorScheme: theme }}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["handle","getSitemapEntries","route","meta","matches","rootData","getRootMatchLoaderData","getSeoMetaTags","title","workshopTitle","description","ogTitle","ogDescription","instructor","requestInfo","mdxComponents","h1","finished","_UNSAFE_withComponentProps","loaderData","data","useRevalidationWS","watchPaths","className","children","jsxs","jsx","Link","to","id","articleId","finishedCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","workshopFinished","status","EditFileOnGitHub","file","relativePath","NavChevrons","prev","prevStepLink","next","Survey","workshopFormEmbedUrl","theme","useTheme","iframeLoaded","setIframeLoaded","React","useIsOnline","Loading","onLoad","onError","src","cn","style","colorScheme","Icon","name","size","href"],"mappings":"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"}
1
+ {"version":3,"file":"finished-CBJx9qcb.js","sources":["../../../app/routes/_app+/finished.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopFinished,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport slugify from '@sindresorhus/slugify'\nimport * as React from 'react'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { Icon } from '#app/components/icons.tsx'\nimport { Loading } from '#app/components/loading.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { useIsOnline } from '#app/utils/online.ts'\nimport { getRootMatchLoaderData } from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport { EditFileOnGitHub } from '../launch-editor.tsx'\nimport { ProgressToggle } from '../progress.tsx'\nimport { useTheme } from '../theme/index.tsx'\nimport { type Route } from './+types/finished.tsx'\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => [{ route: '/finished' }],\n}\n\nexport const meta: Route.MetaFunction = ({ matches }) => {\n\tconst rootData = getRootMatchLoaderData(matches)\n\tif (!rootData) return []\n\n\treturn getSeoMetaTags({\n\t\ttitle: `🎉 ${rootData?.workshopTitle}`,\n\t\tdescription: `Elaboration for ${rootData?.workshopTitle}`,\n\t\togTitle: `Finished ${rootData?.workshopTitle}`,\n\t\togDescription: `You finished! Time to submit feedback.`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('finishedLoader')\n\tconst exercises = await getExercises({ request, timings })\n\tconst compiledFinished = await time(() => getWorkshopFinished({ request }), {\n\t\ttimings,\n\t\ttype: 'compileMdx',\n\t\tdesc: 'compileMdx in finished',\n\t})\n\n\tconst lastExercises = exercises[exercises.length - 1]\n\tconst workshopConfig = getWorkshopConfig()\n\tconst workshopTitle = workshopConfig.title\n\tconst workshopFormTemplate = workshopConfig.forms.workshop\n\tconst workshopFormEmbedUrl = workshopFormTemplate.replace(\n\t\t'{workshopTitle}',\n\t\tencodeURIComponent(workshopTitle),\n\t)\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(workshopTitle)}-finished`,\n\t\t\tworkshopTitle,\n\t\t\tworkshopFormEmbedUrl,\n\t\t\tfinishedCode:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? compiledFinished.compiled.code\n\t\t\t\t\t: null,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tcompiledFinished.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(compiledFinished.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\n\t\t\tworkshopFinished: {\n\t\t\t\tstatus: compiledFinished.compiled.status,\n\t\t\t\tfile: compiledFinished.file,\n\t\t\t\trelativePath: compiledFinished.relativePath,\n\t\t\t},\n\t\t\tprevStepLink: lastExercises\n\t\t\t\t? {\n\t\t\t\t\t\tto: `/${lastExercises.exerciseNumber}/finished`,\n\t\t\t\t\t}\n\t\t\t\t: null,\n\t\t},\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'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nconst mdxComponents = { h1: () => null }\n\nexport default function ExerciseFinished({\n\tloaderData: data,\n}: Route.ComponentProps) {\n\tuseRevalidationWS({ watchPaths: ['./exercises/FINISHED.mdx'] })\n\treturn (\n\t\t<div className=\"flex h-full grow flex-col\">\n\t\t\t<main className=\"grid h-full grow grid-cols-1 grid-rows-2 lg:grid-cols-2 lg:grid-rows-1\">\n\t\t\t\t<div className=\"relative col-span-1 row-span-1 flex h-full flex-col lg:border-r\">\n\t\t\t\t\t<h1 className=\"h-14 border-b pr-5 pl-10 text-sm leading-none font-medium uppercase\">\n\t\t\t\t\t\t<div className=\"flex h-14 flex-wrap items-center justify-between gap-x-2 py-2\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2\">\n\t\t\t\t\t\t\t\t<Link to=\"/\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t{data.workshopTitle}\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t<span>/</span>\n\t\t\t\t\t\t\t\t<span>Elaboration</span>\n\t\t\t\t\t\t\t</div>\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\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar h-full w-full max-w-none flex-1 scroll-pt-6 space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8\"\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.finishedCode ? (\n\t\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t\t<Mdx code={data.finishedCode} components={mdxComponents} />\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t// TODO: render a random dad joke...\n\t\t\t\t\t\t\t'No finished instructions yet...'\n\t\t\t\t\t\t)}\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t\t\t<ProgressToggle\n\t\t\t\t\t\ttype=\"workshop-finished\"\n\t\t\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t\t\t/>\n\t\t\t\t\t<div className=\"@container 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{data.workshopFinished.status === 'success' ? (\n\t\t\t\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\t\t\t\tfile={data.workshopFinished.file}\n\t\t\t\t\t\t\t\trelativePath={data.workshopFinished.relativePath}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t<NavChevrons prev={data.prevStepLink} next={{ to: '/' }} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<Survey\n\t\t\t\t\tworkshopTitle={data.workshopTitle}\n\t\t\t\t\tworkshopFormEmbedUrl={data.workshopFormEmbedUrl}\n\t\t\t\t/>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nfunction Survey({\n\tworkshopTitle,\n\tworkshopFormEmbedUrl,\n}: {\n\tworkshopTitle: string\n\tworkshopFormEmbedUrl: string\n}) {\n\tconst theme = useTheme()\n\tconst [iframeLoaded, setIframeLoaded] = React.useState(false)\n\tconst isOnline = useIsOnline()\n\tif (!isOnline) {\n\t\treturn (\n\t\t\t<div className=\"relative shrink-0\">\n\t\t\t\t<div className=\"text-foreground-destructive absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Icon name=\"WifiNoConnection\" size=\"xl\">\n\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t{'Unable to load the '}\n\t\t\t\t\t\t\t<a href={workshopFormEmbedUrl} className=\"underline\">\n\t\t\t\t\t\t\t\t{`${workshopTitle} feedback form`}\n\t\t\t\t\t\t\t</a>\n\t\t\t\t\t\t\t{' when offline'}\n\t\t\t\t\t\t</span>\n\t\t\t\t\t</Icon>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t)\n\t}\n\treturn (\n\t\t<div className=\"relative shrink-0\">\n\t\t\t{!iframeLoaded ? (\n\t\t\t\t<div className=\"absolute inset-0 z-10 flex items-center justify-center\">\n\t\t\t\t\t<Loading>\n\t\t\t\t\t\t<span>Loading {workshopTitle} Elaboration form</span>\n\t\t\t\t\t</Loading>\n\t\t\t\t</div>\n\t\t\t) : null}\n\t\t\t<iframe\n\t\t\t\tonLoad={() => setIframeLoaded(true)}\n\t\t\t\t// show what would have shown if there is an error\n\t\t\t\tonError={() => setIframeLoaded(true)}\n\t\t\t\ttitle=\"Elaboration\"\n\t\t\t\tsrc={workshopFormEmbedUrl}\n\t\t\t\tclassName={cn(\n\t\t\t\t\t'absolute inset-0 flex h-full w-full transition-opacity duration-300',\n\t\t\t\t\tiframeLoaded ? 'opacity-100' : 'opacity-0',\n\t\t\t\t)}\n\t\t\t\tstyle={{ colorScheme: theme }}\n\t\t\t/>\n\t\t</div>\n\t)\n}\n"],"names":["handle","getSitemapEntries","route","meta","matches","rootData","getRootMatchLoaderData","getSeoMetaTags","title","workshopTitle","description","ogTitle","ogDescription","instructor","requestInfo","mdxComponents","h1","finished","_UNSAFE_withComponentProps","loaderData","data","useRevalidationWS","watchPaths","className","children","jsxs","jsx","Link","to","id","articleId","finishedCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","ElementScrollRestoration","elementQuery","ProgressToggle","type","workshopFinished","status","EditFileOnGitHub","file","relativePath","NavChevrons","prev","prevStepLink","next","Survey","workshopFormEmbedUrl","theme","useTheme","iframeLoaded","setIframeLoaded","React","useIsOnline","Loading","onLoad","onError","src","cn","style","colorScheme","Icon","name","size","href"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import{w as l,a as m,L as n}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{E as a}from"./index-C5c6Cdgw.js";import{E as c}from"./epic-video-DdaxOz-5.js";import{G as p}from"./error-boundary-AXWwBxFl.js";import{E as d}from"./launch-editor-B4NVrR9O.js";import{M as x}from"./mdx-CTC7HBz7.js";import{c as h}from"./misc-GmfBFNKU.js";import{P as f,u}from"./progress-1Egr2Ysk.js";import"./index-Az39ZADK.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./index-Dvg33-i0.js";import"./tooltip-DOPvLR3d.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./online-DlPkOHh3.js";import"./loading-TTjdHw_c.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-CXiAexcc.js";function b({index:o,exercise:r}){const s=u(r.exerciseNumber);return e.jsx("li",{children:e.jsxs(n,{className:h("relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5",s),to:`${r.exerciseNumber.toString().padStart(2,"0")}`,"data-keyboard-action":o===0?"g+n":void 0,children:[e.jsx("span",{className:"text-xs font-normal tabular-nums opacity-50",children:r.exerciseNumber}),e.jsx("span",{children:r.title})]})},r.exerciseNumber)}const j={h1:()=>null},q=l(function({loaderData:r}){const s=e.jsxs("ul",{className:"divide-border dark:divide-border/50 flex flex-col divide-y",children:[e.jsx("strong",{className:"px-10 pb-3 font-mono text-xs uppercase",children:"Exercises"}),r.exercises.map((t,i)=>e.jsx(b,{index:i,exercise:t},t.exerciseNumber))]});return e.jsxs("main",{className:"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3",children:[e.jsxs("article",{id:r.articleId,className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 md:px-10 md:py-12 md:pt-16",children:[e.jsx("div",{children:e.jsx("h1",{className:"px-10 text-[clamp(3rem,6vw,7.5rem)] leading-none font-extrabold",children:r.title})}),e.jsxs("div",{className:"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8",children:[e.jsx("h2",{className:"pb-5 font-mono text-xs font-semibold uppercase",children:"Intro"}),r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code?e.jsx(c,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(x,{code:r.workshopReadme.compiled.code,components:j})})}):r.workshopReadme.compiled.status==="error"?e.jsxs("div",{className:"text-red-500",children:["There was an error:",e.jsx("pre",{children:r.workshopReadme.compiled.error})]}):"No instructions yet..."]}),e.jsx("div",{className:"pt-10 pb-5",children:r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code&&r.workshopReadme.compiled.code.length>500?s:null})]}),e.jsx(a,{elementQuery:`#${r.articleId}`}),e.jsx(f,{type:"workshop-instructions",className:"h-14 border-t px-6"}),e.jsx("div",{className:"@container flex h-16 justify-center border-t",children:e.jsx(d,{file:r.workshopReadme.file,relativePath:r.workshopReadme.relativePath})})]})}),z=m(function(){return e.jsx(p,{})});export{z as ErrorBoundary,q as default};
2
- //# sourceMappingURL=index-UPAFB0f0.js.map
1
+ import{w as l,a as m,L as n}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{E as a}from"./index-C5c6Cdgw.js";import{E as c}from"./epic-video-DSeT-uKN.js";import{G as p}from"./error-boundary-AXWwBxFl.js";import{E as d}from"./launch-editor-B4NVrR9O.js";import{M as x}from"./mdx-Bez0LKTa.js";import{c as h}from"./misc-GmfBFNKU.js";import{P as f,u}from"./progress-1Egr2Ysk.js";import"./index-Az39ZADK.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dd9cSrtE.js";import"./index-CjiomtK6.js";import"./index-Dvg33-i0.js";import"./tooltip-DOPvLR3d.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./online-DlPkOHh3.js";import"./loading-TTjdHw_c.js";import"./user-BGmCaKzN.js";import"./workshop-config-CJJU91bU.js";import"./preload-helper-BXl3LOEh.js";import"./progress-bar-CXiAexcc.js";function b({index:o,exercise:r}){const s=u(r.exerciseNumber);return e.jsx("li",{children:e.jsxs(n,{className:h("relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5",s),to:`${r.exerciseNumber.toString().padStart(2,"0")}`,"data-keyboard-action":o===0?"g+n":void 0,children:[e.jsx("span",{className:"text-xs font-normal tabular-nums opacity-50",children:r.exerciseNumber}),e.jsx("span",{children:r.title})]})},r.exerciseNumber)}const j={h1:()=>null},q=l(function({loaderData:r}){const s=e.jsxs("ul",{className:"divide-border dark:divide-border/50 flex flex-col divide-y",children:[e.jsx("strong",{className:"px-10 pb-3 font-mono text-xs uppercase",children:"Exercises"}),r.exercises.map((t,i)=>e.jsx(b,{index:i,exercise:t},t.exerciseNumber))]});return e.jsxs("main",{className:"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3",children:[e.jsxs("article",{id:r.articleId,className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 md:px-10 md:py-12 md:pt-16",children:[e.jsx("div",{children:e.jsx("h1",{className:"px-10 text-[clamp(3rem,6vw,7.5rem)] leading-none font-extrabold",children:r.title})}),e.jsxs("div",{className:"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8",children:[e.jsx("h2",{className:"pb-5 font-mono text-xs font-semibold uppercase",children:"Intro"}),r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code?e.jsx(c,{epicVideoInfosPromise:r.epicVideoInfosPromise,children:e.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:e.jsx(x,{code:r.workshopReadme.compiled.code,components:j})})}):r.workshopReadme.compiled.status==="error"?e.jsxs("div",{className:"text-red-500",children:["There was an error:",e.jsx("pre",{children:r.workshopReadme.compiled.error})]}):"No instructions yet..."]}),e.jsx("div",{className:"pt-10 pb-5",children:r.workshopReadme.compiled.status==="success"&&r.workshopReadme.compiled.code&&r.workshopReadme.compiled.code.length>500?s:null})]}),e.jsx(a,{elementQuery:`#${r.articleId}`}),e.jsx(f,{type:"workshop-instructions",className:"h-14 border-t px-6"}),e.jsx("div",{className:"@container flex h-16 justify-center border-t",children:e.jsx(d,{file:r.workshopReadme.file,relativePath:r.workshopReadme.relativePath})})]})}),z=m(function(){return e.jsx(p,{})});export{z as ErrorBoundary,q as default};
2
+ //# sourceMappingURL=index-Cr0r3TYc.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index-UPAFB0f0.js","sources":["../../../app/routes/_app+/index.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopInstructions,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { ProgressToggle, useExerciseProgressClassName } from '../progress.tsx'\nimport { type Route } from './+types/index.tsx'\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('indexLoader')\n\tconst { title } = getWorkshopConfig()\n\tconst [exercises, workshopReadme] = await Promise.all([\n\t\ttime(() => getExercises({ request, timings }), {\n\t\t\ttimings,\n\t\t\ttype: 'getExercises',\n\t\t\tdesc: 'getExercises in index',\n\t\t}),\n\t\ttime(() => getWorkshopInstructions({ request }), {\n\t\t\ttimings,\n\t\t\ttype: 'compileMdx',\n\t\t\tdesc: 'compileMdx in index',\n\t\t}),\n\t])\n\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(title)}-instructions`,\n\t\t\ttitle:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? workshopReadme.compiled.title\n\t\t\t\t\t: title,\n\t\t\texercises: exercises.map((e) => ({\n\t\t\t\texerciseNumber: e.exerciseNumber,\n\t\t\t\ttitle: e.title,\n\t\t\t})),\n\t\t\tworkshopReadme,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(workshopReadme.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\n\t\t},\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'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nfunction ExerciseListItem({\n\tindex,\n\texercise,\n}: {\n\tindex: number\n\texercise: Awaited<Route.ComponentProps['loaderData']>['exercises'][number]\n}) {\n\tconst progressClassName = useExerciseProgressClassName(\n\t\texercise.exerciseNumber,\n\t)\n\treturn (\n\t\t<li key={exercise.exerciseNumber}>\n\t\t\t<Link\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5\",\n\t\t\t\t\tprogressClassName,\n\t\t\t\t)}\n\t\t\t\tto={`${exercise.exerciseNumber.toString().padStart(2, '0')}`}\n\t\t\t\tdata-keyboard-action={index === 0 ? 'g+n' : undefined}\n\t\t\t>\n\t\t\t\t<span className=\"text-xs font-normal tabular-nums opacity-50\">\n\t\t\t\t\t{exercise.exerciseNumber}\n\t\t\t\t</span>\n\t\t\t\t<span>{exercise.title}</span>\n\t\t\t</Link>\n\t\t</li>\n\t)\n}\n\nconst mdxComponents = { h1: () => null }\n\nexport default function Index({ loaderData: data }: Route.ComponentProps) {\n\tconst exerciseLinks = (\n\t\t<ul className=\"divide-border dark:divide-border/50 flex flex-col divide-y\">\n\t\t\t<strong className=\"px-10 pb-3 font-mono text-xs uppercase\">\n\t\t\t\tExercises\n\t\t\t</strong>\n\t\t\t{data.exercises.map((exercise, index) => (\n\t\t\t\t<ExerciseListItem\n\t\t\t\t\tkey={exercise.exerciseNumber}\n\t\t\t\t\tindex={index}\n\t\t\t\t\texercise={exercise}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</ul>\n\t)\n\treturn (\n\t\t<main className=\"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3\">\n\t\t\t<article\n\t\t\t\tid={data.articleId}\n\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 md:px-10 md:py-12 md:pt-16\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<h1 className=\"px-10 text-[clamp(3rem,6vw,7.5rem)] leading-none font-extrabold\">\n\t\t\t\t\t\t{data.title}\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8\">\n\t\t\t\t\t<h2 className=\"pb-5 font-mono text-xs font-semibold uppercase\">\n\t\t\t\t\t\tIntro\n\t\t\t\t\t</h2>\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code ? (\n\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\tcode={data.workshopReadme.compiled.code}\n\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\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</EpicVideoInfoProvider>\n\t\t\t\t\t) : data.workshopReadme.compiled.status === 'error' ? (\n\t\t\t\t\t\t<div className=\"text-red-500\">\n\t\t\t\t\t\t\tThere was an error:\n\t\t\t\t\t\t\t<pre>{data.workshopReadme.compiled.error}</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t'No instructions yet...'\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"pt-10 pb-5\">\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code &&\n\t\t\t\t\tdata.workshopReadme.compiled.code.length > 500\n\t\t\t\t\t\t? exerciseLinks\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t</article>\n\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t<ProgressToggle\n\t\t\t\ttype=\"workshop-instructions\"\n\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t/>\n\t\t\t<div className=\"@container flex h-16 justify-center border-t\">\n\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\tfile={data.workshopReadme.file}\n\t\t\t\t\trelativePath={data.workshopReadme.relativePath}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn <GeneralErrorBoundary />\n}\n"],"names":["ExerciseListItem","index","exercise","progressClassName","useExerciseProgressClassName","exerciseNumber","children","jsxs","Link","className","cn","to","toString","padStart","jsx","title","mdxComponents","h1","_UNSAFE_withComponentProps","loaderData","data","exerciseLinks","exercises","map","id","articleId","workshopReadme","compiled","status","code","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","components","error","length","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","file","relativePath","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary"],"mappings":"62BA0EA,SAASA,EAAiB,CACzBC,MAAAA,EACAC,SAAAA,CACD,EAGG,CACF,MAAMC,EAAoBC,EACzBF,EAASG,cACV,EACA,aACE,KAAA,CACAC,SAAAC,EAAAA,KAACC,EAAA,CACAC,UAAWC,EACV,+QACAP,CACD,EACAQ,GAAI,GAAGT,EAASG,eAAeO,WAAWC,SAAS,EAAG,GAAG,CAAC,GAC1D,uBAAsBZ,IAAU,EAAI,MAAQ,OAE5CK,SAAA,CAAAQ,EAAAA,IAAC,OAAA,CAAKL,UAAU,8CACdH,SAAAJ,EAASG,cAAA,CACX,EACAS,EAAAA,IAAC,OAAA,CAAMR,SAAAJ,EAASa,KAAA,CAAM,CAAA,EACvB,CAAA,EAbQb,EAASG,cAclB,CAEF,CAEA,MAAMW,EAAgB,CAAEC,GAAIA,IAAM,IAAK,EAEvChB,EAAAiB,EAAA,SAA8B,CAAEC,WAAYC,CAAK,EAAyB,CACzE,MAAMC,EACLd,EAAAA,KAAC,KAAA,CAAGE,UAAU,6DACbH,SAAA,CAAAQ,EAAAA,IAAC,SAAA,CAAOL,UAAU,yCAAyCH,SAAA,WAAA,CAE3D,EACCc,EAAKE,UAAUC,IAAI,CAACrB,EAAUD,IAC9Ba,EAAAA,IAACd,EAAA,CAEAC,MAAAA,EACAC,SAAAA,CAAA,EAFKA,EAASG,cAGf,CACA,CAAA,CAAA,CACF,EAED,OACCE,EAAAA,KAAC,OAAA,CAAKE,UAAU,4FACfH,SAAA,CAAAC,EAAAA,KAAC,UAAA,CACAiB,GAAIJ,EAAKK,UACThB,UAAU,8JAEVH,SAAA,CAAAQ,EAAAA,IAAC,MAAA,CACAR,eAAC,KAAA,CAAGG,UAAU,kEACZH,SAAAc,EAAKL,MACP,CAAA,CACD,EACAR,EAAAA,KAAC,MAAA,CAAIE,UAAU,oEACdH,SAAA,CAAAQ,EAAAA,IAAC,KAAA,CAAGL,UAAU,iDAAiDH,SAAA,QAE/D,EACCc,EAAKM,eAAeC,SAASC,SAAW,WACzCR,EAAKM,eAAeC,SAASE,KAC5Bf,EAAAA,IAACgB,EAAA,CACAC,sBAAuBX,EAAKW,sBAE5BzB,SAAAQ,EAAAA,IAAC,MAAA,CAAIL,UAAU,sCACdH,SAAAQ,EAAAA,IAACkB,EAAA,CACAH,KAAMT,EAAKM,eAAeC,SAASE,KACnCI,WAAYjB,EACb,EACD,CAAA,CACD,EACGI,EAAKM,eAAeC,SAASC,SAAW,QAC3CrB,EAAAA,KAAC,MAAA,CAAIE,UAAU,eAAeH,SAAA,CAAA,4BAE5B,MAAA,CAAKA,SAAAc,EAAKM,eAAeC,SAASO,KAAA,CAAM,CAAA,EAC1C,EAEA,wBAAA,CAAA,CAEF,EACApB,EAAAA,IAAC,OAAIL,UAAU,aACbH,SAAAc,EAAKM,eAAeC,SAASC,SAAW,WACzCR,EAAKM,eAAeC,SAASE,MAC7BT,EAAKM,eAAeC,SAASE,KAAKM,OAAS,IACxCd,EACA,IAAA,CACJ,CAAA,CAAA,CACD,QACCe,EAAA,CAAyBC,aAAc,IAAIjB,EAAKK,SAAS,EAAA,CAAI,EAC9DX,EAAAA,IAACwB,EAAA,CACAC,KAAK,wBACL9B,UAAU,oBAAA,CACX,EACAK,EAAAA,IAAC,MAAA,CAAIL,UAAU,+CACdH,SAAAQ,EAAAA,IAAC0B,EAAA,CACAC,KAAMrB,EAAKM,eAAee,KAC1BC,aAActB,EAAKM,eAAegB,aACnC,CAAA,CACD,CAAA,CAAA,CACD,CAEF,CAAA,EAEOC,EAAAC,EAAA,UAAyB,CAC/B,aAAQC,EAAA,EAAqB,CAC9B,CAAA"}
1
+ {"version":3,"file":"index-Cr0r3TYc.js","sources":["../../../app/routes/_app+/index.tsx"],"sourcesContent":["import { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetExercises,\n\tgetWorkshopInstructions,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport slugify from '@sindresorhus/slugify'\nimport { data, type HeadersFunction, Link } from 'react-router'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { Mdx } from '#app/utils/mdx.tsx'\nimport { cn } from '#app/utils/misc.tsx'\nimport { ProgressToggle, useExerciseProgressClassName } from '../progress.tsx'\nimport { type Route } from './+types/index.tsx'\n\nexport async function loader({ request }: Route.LoaderArgs) {\n\tconst timings = makeTimings('indexLoader')\n\tconst { title } = getWorkshopConfig()\n\tconst [exercises, workshopReadme] = await Promise.all([\n\t\ttime(() => getExercises({ request, timings }), {\n\t\t\ttimings,\n\t\t\ttype: 'getExercises',\n\t\t\tdesc: 'getExercises in index',\n\t\t}),\n\t\ttime(() => getWorkshopInstructions({ request }), {\n\t\t\ttimings,\n\t\t\ttype: 'compileMdx',\n\t\t\tdesc: 'compileMdx in index',\n\t\t}),\n\t])\n\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(title)}-instructions`,\n\t\t\ttitle:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? workshopReadme.compiled.title\n\t\t\t\t\t: title,\n\t\t\texercises: exercises.map((e) => ({\n\t\t\t\texerciseNumber: e.exerciseNumber,\n\t\t\t\ttitle: e.title,\n\t\t\t})),\n\t\t\tworkshopReadme,\n\t\t\tepicVideoInfosPromise:\n\t\t\t\tworkshopReadme.compiled.status === 'success'\n\t\t\t\t\t? getEpicVideoInfos(workshopReadme.compiled.epicVideoEmbeds, {\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t})\n\t\t\t\t\t: null,\n\t\t},\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'Cache-Control': loaderHeaders.get('Cache-Control') ?? '',\n\t\t'Server-Timing': combineServerTimings(loaderHeaders, parentHeaders),\n\t}\n\treturn headers\n}\n\nfunction ExerciseListItem({\n\tindex,\n\texercise,\n}: {\n\tindex: number\n\texercise: Awaited<Route.ComponentProps['loaderData']>['exercises'][number]\n}) {\n\tconst progressClassName = useExerciseProgressClassName(\n\t\texercise.exerciseNumber,\n\t)\n\treturn (\n\t\t<li key={exercise.exerciseNumber}>\n\t\t\t<Link\n\t\t\t\tclassName={cn(\n\t\t\t\t\t\"relative flex items-center gap-4 px-4 py-3 text-lg font-semibold transition after:absolute after:right-10 after:-translate-x-2 after:opacity-0 after:transition after:content-['→'] hover:bg-gray-50 hover:after:translate-x-0 hover:after:opacity-100 dark:hover:bg-white/5\",\n\t\t\t\t\tprogressClassName,\n\t\t\t\t)}\n\t\t\t\tto={`${exercise.exerciseNumber.toString().padStart(2, '0')}`}\n\t\t\t\tdata-keyboard-action={index === 0 ? 'g+n' : undefined}\n\t\t\t>\n\t\t\t\t<span className=\"text-xs font-normal tabular-nums opacity-50\">\n\t\t\t\t\t{exercise.exerciseNumber}\n\t\t\t\t</span>\n\t\t\t\t<span>{exercise.title}</span>\n\t\t\t</Link>\n\t\t</li>\n\t)\n}\n\nconst mdxComponents = { h1: () => null }\n\nexport default function Index({ loaderData: data }: Route.ComponentProps) {\n\tconst exerciseLinks = (\n\t\t<ul className=\"divide-border dark:divide-border/50 flex flex-col divide-y\">\n\t\t\t<strong className=\"px-10 pb-3 font-mono text-xs uppercase\">\n\t\t\t\tExercises\n\t\t\t</strong>\n\t\t\t{data.exercises.map((exercise, index) => (\n\t\t\t\t<ExerciseListItem\n\t\t\t\t\tkey={exercise.exerciseNumber}\n\t\t\t\t\tindex={index}\n\t\t\t\t\texercise={exercise}\n\t\t\t\t/>\n\t\t\t))}\n\t\t</ul>\n\t)\n\treturn (\n\t\t<main className=\"relative flex h-full w-full max-w-5xl flex-col justify-between border-r md:w-3/4 xl:w-2/3\">\n\t\t\t<article\n\t\t\t\tid={data.articleId}\n\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex w-full flex-1 flex-col gap-12 overflow-y-scroll px-3 py-4 pt-6 md:px-10 md:py-12 md:pt-16\"\n\t\t\t>\n\t\t\t\t<div>\n\t\t\t\t\t<h1 className=\"px-10 text-[clamp(3rem,6vw,7.5rem)] leading-none font-extrabold\">\n\t\t\t\t\t\t{data.title}\n\t\t\t\t\t</h1>\n\t\t\t\t</div>\n\t\t\t\t<div className=\"w-full max-w-none scroll-pt-6 border-t px-3 pt-3 md:px-10 md:pt-8\">\n\t\t\t\t\t<h2 className=\"pb-5 font-mono text-xs font-semibold uppercase\">\n\t\t\t\t\t\tIntro\n\t\t\t\t\t</h2>\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code ? (\n\t\t\t\t\t\t<EpicVideoInfoProvider\n\t\t\t\t\t\t\tepicVideoInfosPromise={data.epicVideoInfosPromise}\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<div className=\"prose dark:prose-invert sm:prose-lg\">\n\t\t\t\t\t\t\t\t<Mdx\n\t\t\t\t\t\t\t\t\tcode={data.workshopReadme.compiled.code}\n\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\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</EpicVideoInfoProvider>\n\t\t\t\t\t) : data.workshopReadme.compiled.status === 'error' ? (\n\t\t\t\t\t\t<div className=\"text-red-500\">\n\t\t\t\t\t\t\tThere was an error:\n\t\t\t\t\t\t\t<pre>{data.workshopReadme.compiled.error}</pre>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t'No instructions yet...'\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div className=\"pt-10 pb-5\">\n\t\t\t\t\t{data.workshopReadme.compiled.status === 'success' &&\n\t\t\t\t\tdata.workshopReadme.compiled.code &&\n\t\t\t\t\tdata.workshopReadme.compiled.code.length > 500\n\t\t\t\t\t\t? exerciseLinks\n\t\t\t\t\t\t: null}\n\t\t\t\t</div>\n\t\t\t</article>\n\t\t\t<ElementScrollRestoration elementQuery={`#${data.articleId}`} />\n\t\t\t<ProgressToggle\n\t\t\t\ttype=\"workshop-instructions\"\n\t\t\t\tclassName=\"h-14 border-t px-6\"\n\t\t\t/>\n\t\t\t<div className=\"@container flex h-16 justify-center border-t\">\n\t\t\t\t<EditFileOnGitHub\n\t\t\t\t\tfile={data.workshopReadme.file}\n\t\t\t\t\trelativePath={data.workshopReadme.relativePath}\n\t\t\t\t/>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn <GeneralErrorBoundary />\n}\n"],"names":["ExerciseListItem","index","exercise","progressClassName","useExerciseProgressClassName","exerciseNumber","children","jsxs","Link","className","cn","to","toString","padStart","jsx","title","mdxComponents","h1","_UNSAFE_withComponentProps","loaderData","data","exerciseLinks","exercises","map","id","articleId","workshopReadme","compiled","status","code","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","components","error","length","ElementScrollRestoration","elementQuery","ProgressToggle","type","EditFileOnGitHub","file","relativePath","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary"],"mappings":"62BA0EA,SAASA,EAAiB,CACzBC,MAAAA,EACAC,SAAAA,CACD,EAGG,CACF,MAAMC,EAAoBC,EACzBF,EAASG,cACV,EACA,aACE,KAAA,CACAC,SAAAC,EAAAA,KAACC,EAAA,CACAC,UAAWC,EACV,+QACAP,CACD,EACAQ,GAAI,GAAGT,EAASG,eAAeO,WAAWC,SAAS,EAAG,GAAG,CAAC,GAC1D,uBAAsBZ,IAAU,EAAI,MAAQ,OAE5CK,SAAA,CAAAQ,EAAAA,IAAC,OAAA,CAAKL,UAAU,8CACdH,SAAAJ,EAASG,cAAA,CACX,EACAS,EAAAA,IAAC,OAAA,CAAMR,SAAAJ,EAASa,KAAA,CAAM,CAAA,EACvB,CAAA,EAbQb,EAASG,cAclB,CAEF,CAEA,MAAMW,EAAgB,CAAEC,GAAIA,IAAM,IAAK,EAEvChB,EAAAiB,EAAA,SAA8B,CAAEC,WAAYC,CAAK,EAAyB,CACzE,MAAMC,EACLd,EAAAA,KAAC,KAAA,CAAGE,UAAU,6DACbH,SAAA,CAAAQ,EAAAA,IAAC,SAAA,CAAOL,UAAU,yCAAyCH,SAAA,WAAA,CAE3D,EACCc,EAAKE,UAAUC,IAAI,CAACrB,EAAUD,IAC9Ba,EAAAA,IAACd,EAAA,CAEAC,MAAAA,EACAC,SAAAA,CAAA,EAFKA,EAASG,cAGf,CACA,CAAA,CAAA,CACF,EAED,OACCE,EAAAA,KAAC,OAAA,CAAKE,UAAU,4FACfH,SAAA,CAAAC,EAAAA,KAAC,UAAA,CACAiB,GAAIJ,EAAKK,UACThB,UAAU,8JAEVH,SAAA,CAAAQ,EAAAA,IAAC,MAAA,CACAR,eAAC,KAAA,CAAGG,UAAU,kEACZH,SAAAc,EAAKL,MACP,CAAA,CACD,EACAR,EAAAA,KAAC,MAAA,CAAIE,UAAU,oEACdH,SAAA,CAAAQ,EAAAA,IAAC,KAAA,CAAGL,UAAU,iDAAiDH,SAAA,QAE/D,EACCc,EAAKM,eAAeC,SAASC,SAAW,WACzCR,EAAKM,eAAeC,SAASE,KAC5Bf,EAAAA,IAACgB,EAAA,CACAC,sBAAuBX,EAAKW,sBAE5BzB,SAAAQ,EAAAA,IAAC,MAAA,CAAIL,UAAU,sCACdH,SAAAQ,EAAAA,IAACkB,EAAA,CACAH,KAAMT,EAAKM,eAAeC,SAASE,KACnCI,WAAYjB,EACb,EACD,CAAA,CACD,EACGI,EAAKM,eAAeC,SAASC,SAAW,QAC3CrB,EAAAA,KAAC,MAAA,CAAIE,UAAU,eAAeH,SAAA,CAAA,4BAE5B,MAAA,CAAKA,SAAAc,EAAKM,eAAeC,SAASO,KAAA,CAAM,CAAA,EAC1C,EAEA,wBAAA,CAAA,CAEF,EACApB,EAAAA,IAAC,OAAIL,UAAU,aACbH,SAAAc,EAAKM,eAAeC,SAASC,SAAW,WACzCR,EAAKM,eAAeC,SAASE,MAC7BT,EAAKM,eAAeC,SAASE,KAAKM,OAAS,IACxCd,EACA,IAAA,CACJ,CAAA,CAAA,CACD,QACCe,EAAA,CAAyBC,aAAc,IAAIjB,EAAKK,SAAS,EAAA,CAAI,EAC9DX,EAAAA,IAACwB,EAAA,CACAC,KAAK,wBACL9B,UAAU,oBAAA,CACX,EACAK,EAAAA,IAAC,MAAA,CAAIL,UAAU,+CACdH,SAAAQ,EAAAA,IAAC0B,EAAA,CACAC,KAAMrB,EAAKM,eAAee,KAC1BC,aAActB,EAAKM,eAAegB,aACnC,CAAA,CACD,CAAA,CAAA,CACD,CAEF,CAAA,EAEOC,EAAAC,EAAA,UAAyB,CAC/B,aAAQC,EAAA,EAAqB,CAC9B,CAAA"}
@@ -1,2 +1,2 @@
1
- import{b as me,A as xe,L as K,w as he,a as ve,p as ge,h as je,m as be}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{c as B,d as H,P,f as w,e as we,u as V,o as ye,g as Ne,S as Te}from"./tooltip-DOPvLR3d.js";import{f as Ie,u as $}from"./index-wbZv2KL3.js";import{k as z,I as C,a as Ce}from"./misc-GmfBFNKU.js";import{U as Pe}from"./diff-GhgVnDeo.js";import{G as Ee}from"./error-boundary-AXWwBxFl.js";import{u as Re}from"./workshop-config-CJJU91bU.js";import{L as Se}from"./loading-TTjdHw_c.js";import{D as Ae,u as Fe}from"./discord-gAs3sIeG.js";import{u as _e}from"./online-DlPkOHh3.js";import{t as ke}from"./index-Dd9cSrtE.js";import{S as Ue}from"./set-playground-CqWopo_p.js";import{P as De,a as Le}from"./tests-CHg0zMRl.js";import{P as k}from"./preview-BBLFAsCx.js";import"./index-CjiomtK6.js";import"./index-DhJTQh61.js";import"./accordion-CMwNXwpE.js";import"./mdx-CTC7HBz7.js";import"./epic-video-DdaxOz-5.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dvg33-i0.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./user-BGmCaKzN.js";import"./preload-helper-BXl3LOEh.js";import"./launch-editor-B4NVrR9O.js";import"./progress-bar-CXiAexcc.js";import"./revalidation-ws-BdlKZ8s_.js";import"./button-Bhee0nJ5.js";import"./onboarding-indicator-BtHxYHrp.js";import"./dialog-D9Rz0D0m.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),h=$(d),[j,f]=V({prop:l,defaultProp:p??null,onChange:g,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 v=x.current;if(v)return v.addEventListener(_,b),()=>v.removeEventListener(_,b)},[b]),e.jsx(Ke,{scope:r,orientation:n,dir:h,loop:i,currentTabStopId:j,onItemFocus:u.useCallback(v=>f(v),[f]),onItemShiftTab:u.useCallback(()=>S(!0),[]),onFocusableItemAdd:u.useCallback(()=>O(v=>v+1),[]),onFocusableItemRemove:u.useCallback(()=>O(v=>v-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,v=>{const ue=!A.current;if(v.target===v.currentTarget&&ue&&!y){const M=new CustomEvent(_,Oe);if(v.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,g=H(),m=d||g,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: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-yellow-400",circle:"bg-yellow-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 Hs=he(function({loaderData:t}){const{inBrowserBrowserRef:r}=ge(),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){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=>!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 h=g(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:o==="diff"?x:void 0,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,{})})]})]})}),Vs=ve(function(){return e.jsx(Ee,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."})}})});export{Vs as ErrorBoundary,Hs as default};
2
- //# sourceMappingURL=index-C2aC4iSz.js.map
1
+ import{b as me,A as xe,L as K,w as he,a as ve,p as ge,h as je,m as be}from"./chunk-UIGDSWPH-D7TrB36R.js";import{j as e}from"./jsx-runtime-C5WNSv3b.js";import{r as u}from"./index-Az39ZADK.js";import{c as B,d as H,P,f as w,e as we,u as V,o as ye,g as Ne,S as Te}from"./tooltip-DOPvLR3d.js";import{f as Ie,u as $}from"./index-wbZv2KL3.js";import{k as z,I as C,a as Ce}from"./misc-GmfBFNKU.js";import{U as Pe}from"./diff-BkCOoQXe.js";import{G as Ee}from"./error-boundary-AXWwBxFl.js";import{u as Re}from"./workshop-config-CJJU91bU.js";import{L as Se}from"./loading-TTjdHw_c.js";import{D as Ae,u as Fe}from"./discord-gAs3sIeG.js";import{u as _e}from"./online-DlPkOHh3.js";import{t as ke}from"./index-Dd9cSrtE.js";import{S as Ue}from"./set-playground-CqWopo_p.js";import{P as De,a as Le}from"./tests-ihMcV-RO.js";import{P as k}from"./preview-BBLFAsCx.js";import"./index-CjiomtK6.js";import"./index-DhJTQh61.js";import"./accordion-CMwNXwpE.js";import"./mdx-Bez0LKTa.js";import"./epic-video-DSeT-uKN.js";import"./use-event-source-CrGUTTzj.js";import"./index-Dvg33-i0.js";import"./root-loader-CcoJXu7H.js";import"./pe-BgHP_H47.js";import"./types-Cl2NuNg4.js";import"./user-BGmCaKzN.js";import"./preload-helper-BXl3LOEh.js";import"./launch-editor-B4NVrR9O.js";import"./progress-bar-CXiAexcc.js";import"./revalidation-ws-BdlKZ8s_.js";import"./button-Bhee0nJ5.js";import"./onboarding-indicator-BtHxYHrp.js";import"./dialog-D9Rz0D0m.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),h=$(d),[j,f]=V({prop:l,defaultProp:p??null,onChange:g,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 v=x.current;if(v)return v.addEventListener(_,b),()=>v.removeEventListener(_,b)},[b]),e.jsx(Ke,{scope:r,orientation:n,dir:h,loop:i,currentTabStopId:j,onItemFocus:u.useCallback(v=>f(v),[f]),onItemShiftTab:u.useCallback(()=>S(!0),[]),onFocusableItemAdd:u.useCallback(()=>O(v=>v+1),[]),onFocusableItemRemove:u.useCallback(()=>O(v=>v-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,v=>{const ue=!A.current;if(v.target===v.currentTarget&&ue&&!y){const M=new CustomEvent(_,Oe);if(v.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,g=H(),m=d||g,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: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-yellow-400",circle:"bg-yellow-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 Hs=he(function({loaderData:t}){const{inBrowserBrowserRef:r}=ge(),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){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=>!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 h=g(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:o==="diff"?x:void 0,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,{})})]})]})}),Vs=ve(function(){return e.jsx(Ee,{statusHandlers:{404:()=>e.jsx("p",{children:"Sorry, we couldn't find an app here."})}})});export{Vs as ErrorBoundary,Hs as default};
2
+ //# sourceMappingURL=index-DOotQobj.js.map