@epic-web/workshop-app 6.89.0 → 6.89.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,2 +1,2 @@
1
- import{w as T,a as k,b as A,d as $,L as l}from"./chunk-JZWAC4HX-BuixXc9D.js";import{j as r}from"./jsx-runtime-C5WNSv3b.js";import{E as B}from"./index-3PqfcnMA.js";import{g as L,R as M,P as H,C as n,a as O,D as U}from"./playground-BV2y1ifv.js";import{r as o}from"./index-Bi6L2ga8.js";import{U as V}from"./diff-C4LoXlDb.js";import{E as z}from"./epic-video-C9q0z-QM.js";import{G as X}from"./error-boundary-DCY9a5Cj.js";import{N as F}from"./nav-chevrons-DUMNZcNc.js";import{u as G}from"./revalidation-ws-JHvxsHsY.js";import{u as W}from"./workshop-config-v_LiyFvY.js";import{P as q}from"./preview-Dav9KrHN.js";import{E as Y}from"./launch-editor-C-8ah8qM.js";import{S as _}from"./set-playground-CvYErpku.js";import{c as Q,M as J}from"./mdx-C3Jl4O5D.js";import{g as K,u as Z,a as ee}from"./root-loader-DAxaiFMN.js";import{g as re}from"./seo-t5J-DRxw.js";import{s as v,a as te}from"./split-layout-DnRER1bP.js";import"./misc-D9k_mI0z.js";import"./loading-BjV0PtX2.js";import"./index-DSpM0ReJ.js";import"./tooltip-H74tOFSr.js";import"./index-B2VNpNxJ.js";import"./pe-D585gnmh.js";import"./schemas-siASSt6b.js";import"./discord-CVgNwZp4.js";import"./user-DhjrtSbZ.js";import"./online-x7UFobEJ.js";import"./index-BvE6USCZ.js";import"./index-DosQrH9F.js";import"./status-indicator-C6DiLYL5.js";import"./index-E_6kulJP.js";import"./playground-window-BM8PCQz7.js";import"./react-error-boundary-DFNLMQmr.js";import"./preload-helper-BXl3LOEh.js";import"./format-CZ5n8p10.js";import"./popover-Dh41LPal.js";import"./index-ywSltzcE.js";import"./button-B_EAwzD_.js";import"./progress-bar-BCbq1CuC.js";import"./onboarding-indicator-Csno1yMz.js";import"./dialog-DXBBGJQ6.js";const Ge=i=>{const e=i.data,s=K(i.matches);return!e||!s?[{title:"🦉 | Error"}]:re({title:`📚 | ${e.extra.title} | ${s.workshopTitle}`,description:`Extra: ${e.extra.title}`,ogTitle:e.extra.title,ogDescription:`Extra: ${e.extra.title}`,instructor:s.instructor,requestInfo:s.requestInfo})},We=T(function(){const e=A(),s=Z(),w=ee(),h=o.useRef(null),c=o.useRef(null),y=o.useRef(null),[P,d]=o.useState(e.splitPercent),[g]=$(),b=W(),N=o.useMemo(()=>Promise.resolve(s.userHasAccess??!1),[s.userHasAccess]),j=e.playground?.appName!==e.extra.name,E=j||e.playground?.isUpToDate===!1,p=["playground","extra","diff","chat"],m=g.get("preview"),u=e.previousExtra?{to:`/extra/${e.previousExtra.dirName}`,"aria-label":"Previous Extra"}:{to:"/extra","aria-label":"Extras"},x=e.nextExtra?{to:`/extra/${e.nextExtra.dirName}`,"aria-label":"Next Extra"}:{to:"/finished","aria-label":"Workshop finished"};function D(t){return!!(t&&p.includes(t))}function f(t){if(t==="playground")return ENV.EPICSHOP_DEPLOYED;if(t==="extra"&&ENV.EPICSHOP_DEPLOYED){const a=e.extra.dev.type;return a!=="browser"&&a!=="export"&&!e.extra.stackBlitzUrl}return t==="chat"?!b.product.discordChannelId:!1}const C=D(m)&&!f(m)?m:p.find(t=>!f(t))??"playground",I=p.map(t=>{const a=f(t);return{id:t,label:t,hidden:a,to:`?${L(g,t,"playground")}`}}),S=o.useMemo(()=>{const t=Q(()=>e.playground?{name:e.playground.name,fullPath:e.playground.fullPath}:null,()=>!e.playground||e.playground.appName!==e.extra.name?"Set the playground to this extra before opening a file.":null);return{h1:()=>null,InlineFile:t}},[e.playground,e.extra.name]),R=w.find(t=>t.name===e.playground?.appName)?.fullPath;return G({watchPaths:[e.extraReadme.file,R].filter(t=>!!t)}),r.jsx("div",{className:"flex max-w-full grow flex-col",children:r.jsxs("main",{ref:c,className:"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row",children:[r.jsxs("div",{className:"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)",style:{"--split-pct":`${P}%`},ref:y,children:[r.jsx("h1",{className:"@container h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium",children:r.jsxs("div",{className:"flex h-14 items-center justify-between gap-x-2 py-2 whitespace-nowrap",children:[r.jsxs("div",{className:"flex items-center justify-start gap-x-2 uppercase",children:[r.jsx(l,{to:"/extra",className:"hover:underline",children:r.jsx("span",{children:"Extras"})}),r.jsx("span",{children:"/"}),r.jsx(l,{to:".",className:"hover:underline",children:r.jsx("span",{children:e.extra.title})})]}),E?r.jsx(_,{appName:e.extra.name,isOutdated:e.playground?.isUpToDate===!1,hideTextOnNarrow:!0,showOnboardingIndicator:j}):null]})}),r.jsxs("article",{id:e.articleId,className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8",children:[e.extra.instructionsCode?r.jsx(z,{epicVideoInfosPromise:e.epicVideoInfosPromise,children:r.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:r.jsx(J,{code:e.extra.instructionsCode,components:S})})}):r.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:r.jsx("p",{children:"No instructions yet..."})}),r.jsxs("div",{className:"mt-auto flex justify-between",children:[r.jsxs(l,{to:u.to,"aria-label":u["aria-label"],prefetch:"intent",children:[r.jsx("span",{"aria-hidden":!0,children:"←"}),r.jsx("span",{className:"hidden xl:inline",children:" Previous"})]}),r.jsxs(l,{to:x.to,"aria-label":x["aria-label"],prefetch:"intent",children:[r.jsx("span",{className:"hidden xl:inline",children:"Next "}),r.jsx("span",{"aria-hidden":!0,children:"→"})]})]})]},e.articleId),r.jsx(B,{elementQuery:`#${e.articleId}`},`scroll-${e.articleId}`),r.jsxs("div",{className:"@container flex h-16 justify-between border-t border-b-4 lg:border-b-0",children:[r.jsx("div",{}),r.jsx(Y,{appName:e.extra.name,relativePath:e.extraReadme.relativePath}),r.jsx(F,{prev:u,next:x})]})]}),r.jsx("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",className:"bg-border hover:bg-muted hidden w-1 cursor-col-resize lg:block",onMouseDown:t=>v({container:c.current,initialClientX:t.clientX,setSplitPercent:d}),onDoubleClick:()=>{d(te(50))},onTouchStart:t=>{const a=t.touches?.[0];a&&v({container:c.current,initialClientX:a.clientX,setSplitPercent:d})}}),r.jsxs(M,{className:"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",value:C,children:[r.jsx(H,{tabs:I}),r.jsxs("div",{className:"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden",children:[r.jsx(n,{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:r.jsx(O,{appInfo:e.playground,problemAppName:e.extra.name,allApps:e.allApps??[],isUpToDate:e.playground?.isUpToDate??!1,inBrowserBrowserRef:h})}),r.jsx(n,{value:"extra",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:r.jsx(q,{appInfo:e.extra,inBrowserBrowserRef:h})}),r.jsx(n,{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:r.jsx(V,{diff:e.diff,allApps:e.allApps,userHasAccessPromise:N})}),r.jsx(n,{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:r.jsx(U,{discordPostsPromise:e.discordPostsPromise})})]})]})]})})}),qe=k(function(){return r.jsx(X,{})});export{qe as ErrorBoundary,We as default,Ge as meta};
2
- //# sourceMappingURL=_extra-Bd0-gThk.js.map
1
+ import{w as T,a as k,b as A,d as $,L as l}from"./chunk-JZWAC4HX-BuixXc9D.js";import{j as r}from"./jsx-runtime-C5WNSv3b.js";import{E as B}from"./index-3PqfcnMA.js";import{g as L,R as M,P as H,C as n,a as O,D as U}from"./playground-BV2y1ifv.js";import{r as o}from"./index-Bi6L2ga8.js";import{U as V}from"./diff-D18ACTzf.js";import{E as z}from"./epic-video-C9q0z-QM.js";import{G as X}from"./error-boundary-DCY9a5Cj.js";import{N as F}from"./nav-chevrons-DUMNZcNc.js";import{u as G}from"./revalidation-ws-JHvxsHsY.js";import{u as W}from"./workshop-config-v_LiyFvY.js";import{P as q}from"./preview-Dav9KrHN.js";import{E as Y}from"./launch-editor-C-8ah8qM.js";import{S as _}from"./set-playground-CvYErpku.js";import{c as Q,M as J}from"./mdx-C3Jl4O5D.js";import{g as K,u as Z,a as ee}from"./root-loader-DAxaiFMN.js";import{g as re}from"./seo-t5J-DRxw.js";import{s as v,a as te}from"./split-layout-DnRER1bP.js";import"./misc-D9k_mI0z.js";import"./loading-BjV0PtX2.js";import"./index-DSpM0ReJ.js";import"./tooltip-H74tOFSr.js";import"./index-B2VNpNxJ.js";import"./pe-D585gnmh.js";import"./schemas-siASSt6b.js";import"./discord-CVgNwZp4.js";import"./user-DhjrtSbZ.js";import"./online-x7UFobEJ.js";import"./index-BvE6USCZ.js";import"./index-DosQrH9F.js";import"./status-indicator-C6DiLYL5.js";import"./index-E_6kulJP.js";import"./playground-window-BM8PCQz7.js";import"./react-error-boundary-DFNLMQmr.js";import"./preload-helper-BXl3LOEh.js";import"./format-CZ5n8p10.js";import"./popover-Dh41LPal.js";import"./index-ywSltzcE.js";import"./button-B_EAwzD_.js";import"./progress-bar-BCbq1CuC.js";import"./onboarding-indicator-Csno1yMz.js";import"./dialog-DXBBGJQ6.js";const Ge=i=>{const e=i.data,s=K(i.matches);return!e||!s?[{title:"🦉 | Error"}]:re({title:`📚 | ${e.extra.title} | ${s.workshopTitle}`,description:`Extra: ${e.extra.title}`,ogTitle:e.extra.title,ogDescription:`Extra: ${e.extra.title}`,instructor:s.instructor,requestInfo:s.requestInfo})},We=T(function(){const e=A(),s=Z(),w=ee(),h=o.useRef(null),c=o.useRef(null),y=o.useRef(null),[P,d]=o.useState(e.splitPercent),[g]=$(),b=W(),N=o.useMemo(()=>Promise.resolve(s.userHasAccess??!1),[s.userHasAccess]),j=e.playground?.appName!==e.extra.name,E=j||e.playground?.isUpToDate===!1,p=["playground","extra","diff","chat"],m=g.get("preview"),u=e.previousExtra?{to:`/extra/${e.previousExtra.dirName}`,"aria-label":"Previous Extra"}:{to:"/extra","aria-label":"Extras"},x=e.nextExtra?{to:`/extra/${e.nextExtra.dirName}`,"aria-label":"Next Extra"}:{to:"/finished","aria-label":"Workshop finished"};function D(t){return!!(t&&p.includes(t))}function f(t){if(t==="playground")return ENV.EPICSHOP_DEPLOYED;if(t==="extra"&&ENV.EPICSHOP_DEPLOYED){const a=e.extra.dev.type;return a!=="browser"&&a!=="export"&&!e.extra.stackBlitzUrl}return t==="chat"?!b.product.discordChannelId:!1}const C=D(m)&&!f(m)?m:p.find(t=>!f(t))??"playground",I=p.map(t=>{const a=f(t);return{id:t,label:t,hidden:a,to:`?${L(g,t,"playground")}`}}),S=o.useMemo(()=>{const t=Q(()=>e.playground?{name:e.playground.name,fullPath:e.playground.fullPath}:null,()=>!e.playground||e.playground.appName!==e.extra.name?"Set the playground to this extra before opening a file.":null);return{h1:()=>null,InlineFile:t}},[e.playground,e.extra.name]),R=w.find(t=>t.name===e.playground?.appName)?.fullPath;return G({watchPaths:[e.extraReadme.file,R].filter(t=>!!t)}),r.jsx("div",{className:"flex max-w-full grow flex-col",children:r.jsxs("main",{ref:c,className:"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row",children:[r.jsxs("div",{className:"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)",style:{"--split-pct":`${P}%`},ref:y,children:[r.jsx("h1",{className:"@container h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium",children:r.jsxs("div",{className:"flex h-14 items-center justify-between gap-x-2 py-2 whitespace-nowrap",children:[r.jsxs("div",{className:"flex items-center justify-start gap-x-2 uppercase",children:[r.jsx(l,{to:"/extra",className:"hover:underline",children:r.jsx("span",{children:"Extras"})}),r.jsx("span",{children:"/"}),r.jsx(l,{to:".",className:"hover:underline",children:r.jsx("span",{children:e.extra.title})})]}),E?r.jsx(_,{appName:e.extra.name,isOutdated:e.playground?.isUpToDate===!1,hideTextOnNarrow:!0,showOnboardingIndicator:j}):null]})}),r.jsxs("article",{id:e.articleId,className:"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8",children:[e.extra.instructionsCode?r.jsx(z,{epicVideoInfosPromise:e.epicVideoInfosPromise,children:r.jsx("div",{className:"prose dark:prose-invert sm:prose-lg",children:r.jsx(J,{code:e.extra.instructionsCode,components:S})})}):r.jsx("div",{className:"flex h-full items-center justify-center text-lg",children:r.jsx("p",{children:"No instructions yet..."})}),r.jsxs("div",{className:"mt-auto flex justify-between",children:[r.jsxs(l,{to:u.to,"aria-label":u["aria-label"],prefetch:"intent",children:[r.jsx("span",{"aria-hidden":!0,children:"←"}),r.jsx("span",{className:"hidden xl:inline",children:" Previous"})]}),r.jsxs(l,{to:x.to,"aria-label":x["aria-label"],prefetch:"intent",children:[r.jsx("span",{className:"hidden xl:inline",children:"Next "}),r.jsx("span",{"aria-hidden":!0,children:"→"})]})]})]},e.articleId),r.jsx(B,{elementQuery:`#${e.articleId}`},`scroll-${e.articleId}`),r.jsxs("div",{className:"@container flex h-16 justify-between border-t border-b-4 lg:border-b-0",children:[r.jsx("div",{}),r.jsx(Y,{appName:e.extra.name,relativePath:e.extraReadme.relativePath}),r.jsx(F,{prev:u,next:x})]})]}),r.jsx("div",{role:"separator","aria-orientation":"vertical",title:"Drag to resize",className:"bg-border hover:bg-muted hidden w-1 cursor-col-resize lg:block",onMouseDown:t=>v({container:c.current,initialClientX:t.clientX,setSplitPercent:d}),onDoubleClick:()=>{d(te(50))},onTouchStart:t=>{const a=t.touches?.[0];a&&v({container:c.current,initialClientX:a.clientX,setSplitPercent:d})}}),r.jsxs(M,{className:"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden",value:C,children:[r.jsx(H,{tabs:I}),r.jsxs("div",{className:"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden",children:[r.jsx(n,{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:r.jsx(O,{appInfo:e.playground,problemAppName:e.extra.name,allApps:e.allApps??[],isUpToDate:e.playground?.isUpToDate??!1,inBrowserBrowserRef:h})}),r.jsx(n,{value:"extra",className:"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start",forceMount:!0,children:r.jsx(q,{appInfo:e.extra,inBrowserBrowserRef:h})}),r.jsx(n,{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:r.jsx(V,{diff:e.diff,allApps:e.allApps,userHasAccessPromise:N})}),r.jsx(n,{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:r.jsx(U,{discordPostsPromise:e.discordPostsPromise})})]})]})]})})}),qe=k(function(){return r.jsx(X,{})});export{qe as ErrorBoundary,We as default,Ge as meta};
2
+ //# sourceMappingURL=_extra-DI111cn8.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"_extra-Bd0-gThk.js","sources":["../../../app/routes/_app+/extra+/$extra.tsx"],"sourcesContent":["import { type Route } from './+types/$extra'\nimport path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppByName,\n\tgetAppDisplayName,\n\tgetApps,\n\tisExtraApp,\n\tisPlaygroundApp,\n\ttype ExtraApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getDiffPatch } from '@epic-web/workshop-utils/diff.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport * as Tabs from '@radix-ui/react-tabs'\nimport slugify from '@sindresorhus/slugify'\nimport { useMemo, useRef, useState } from 'react'\nimport {\n\tLink,\n\tdata,\n\ttype HeadersFunction,\n\tuseLoaderData,\n\tuseSearchParams,\n} from 'react-router'\nimport { Diff } from '#app/components/diff.tsx'\nimport { DiscordChat } from '#app/components/discord-chat.tsx'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport {\n\tgetPreviewSearchParams,\n\tPreviewTabsList,\n} from '#app/components/preview-tabs.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { useWorkshopConfig } from '#app/components/workshop-config.tsx'\nimport { Playground } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/playground.tsx'\nimport { Preview } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/preview.tsx'\nimport { getAppRunningState } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/utils.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { fetchDiscordPosts } from '#app/utils/discord.server.ts'\nimport { createInlineFileComponent, Mdx } from '#app/utils/mdx.tsx'\nimport {\n\tgetRootMatchLoaderData,\n\tuseApps,\n\tuseRootLoaderData,\n} from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport {\n\tgetSplitPercentFromRequest,\n\tsetSplitPercentCookie,\n\tstartSplitDrag,\n} from '#app/utils/split-layout.ts'\n\nfunction sortExtras(extras: ExtraApp[]) {\n\treturn extras.sort((a, b) =>\n\t\ta.title.localeCompare(b.title, undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base',\n\t\t}),\n\t)\n}\n\nexport const meta: Route.MetaFunction = (args) => {\n\tconst loaderData = args.data\n\tconst rootData = getRootMatchLoaderData(args.matches)\n\tif (!loaderData || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `📚 | ${loaderData.extra.title} | ${rootData.workshopTitle}`,\n\t\tdescription: `Extra: ${loaderData.extra.title}`,\n\t\togTitle: loaderData.extra.title,\n\t\togDescription: `Extra: ${loaderData.extra.title}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('extraLoader')\n\tinvariantResponse(params.extra, 'extra is required')\n\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\tconst cacheOptions = { request, timings }\n\tconst apps = await time(() => getApps(cacheOptions), {\n\t\ttimings,\n\t\ttype: 'getApps',\n\t\tdesc: 'getApps in extra loader',\n\t})\n\tconst extras = sortExtras(apps.filter(isExtraApp))\n\tconst playgroundApp = apps.find(isPlaygroundApp)\n\tconst extraIndex = extras.findIndex((extra) => extra.dirName === params.extra)\n\tconst extra = extras[extraIndex]\n\tif (!extra) {\n\t\tthrow new Response('Extra not found', { status: 404 })\n\t}\n\n\tconst readmeFilepath = path.join(extra.fullPath, 'README.mdx')\n\tconst previousExtra = extras[extraIndex - 1]\n\tconst nextExtra = extras[extraIndex + 1]\n\tconst reqUrl = new URL(request.url)\n\tconst app1Name = reqUrl.searchParams.get('app1')\n\tconst app2Name = reqUrl.searchParams.get('app2')\n\tconst app1 = app1Name\n\t\t? await getAppByName(app1Name)\n\t\t: (playgroundApp ?? extra)\n\tconst app2 = app2Name ? await getAppByName(app2Name) : extra\n\tconst splitPercent = getSplitPercentFromRequest(request, 50)\n\n\tconst { isRunning, portIsAvailable } = await getAppRunningState(extra)\n\n\tasync function getDiffProp() {\n\t\tif (!app1 || !app2) {\n\t\t\treturn { app1: app1?.name, app2: app2?.name, diffPatch: null }\n\t\t}\n\t\tconst diffPatch = await getDiffPatch(app1, app2, {\n\t\t\t...cacheOptions,\n\t\t\tforceFresh: reqUrl.searchParams.get('forceFresh') === 'diff',\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error)\n\t\t\treturn null\n\t\t})\n\t\treturn {\n\t\t\tapp1: app1.name,\n\t\t\tapp2: app2.name,\n\t\t\tdiffPatch,\n\t\t}\n\t}\n\n\tconst allApps = apps\n\t\t.filter(\n\t\t\t(app, index, list) =>\n\t\t\t\tlist.findIndex((item) => item.name === app.name) === index,\n\t\t)\n\t\t.map((app) => ({\n\t\t\tname: app.name,\n\t\t\tdisplayName: getAppDisplayName(app, apps),\n\t\t}))\n\t\t.sort((a, b) =>\n\t\t\ta.displayName.localeCompare(b.displayName, undefined, {\n\t\t\t\tnumeric: true,\n\t\t\t\tsensitivity: 'base',\n\t\t\t}),\n\t\t)\n\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(workshopTitle)}-${slugify(\n\t\t\t\textra.title,\n\t\t\t)}-extra`,\n\t\t\tsplitPercent,\n\t\t\textra: {\n\t\t\t\ttype: 'extra',\n\t\t\t\tname: extra.name,\n\t\t\t\ttitle: extra.title,\n\t\t\t\tdirName: extra.dirName,\n\t\t\t\tfullPath: extra.fullPath,\n\t\t\t\trelativePath: extra.relativePath,\n\t\t\t\tdev: extra.dev,\n\t\t\t\ttest: extra.test,\n\t\t\t\tstackBlitzUrl: extra.stackBlitzUrl,\n\t\t\t\tisRunning,\n\t\t\t\tportIsAvailable,\n\t\t\t\tepicVideoEmbeds: extra.epicVideoEmbeds,\n\t\t\t\tinstructionsCode: extra.instructionsCode,\n\t\t\t},\n\t\t\textraReadme: {\n\t\t\t\tfile: readmeFilepath,\n\t\t\t\trelativePath: path.join(extra.relativePath, 'README.mdx'),\n\t\t\t},\n\t\t\tplayground: playgroundApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'playground',\n\t\t\t\t\t\tappName: playgroundApp.appName,\n\t\t\t\t\t\tname: playgroundApp.name,\n\t\t\t\t\t\ttitle: playgroundApp.title,\n\t\t\t\t\t\tfullPath: playgroundApp.fullPath,\n\t\t\t\t\t\tdev: playgroundApp.dev,\n\t\t\t\t\t\ttest: playgroundApp.test,\n\t\t\t\t\t\tstackBlitzUrl: playgroundApp.stackBlitzUrl,\n\t\t\t\t\t\tisUpToDate: playgroundApp.isUpToDate,\n\t\t\t\t\t\t...(await getAppRunningState(playgroundApp)),\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tallApps,\n\t\t\tdiff: getDiffProp(),\n\t\t\tdiscordPostsPromise: fetchDiscordPosts({ request }),\n\t\t\tpreviousExtra: previousExtra\n\t\t\t\t? { dirName: previousExtra.dirName, title: previousExtra.title }\n\t\t\t\t: null,\n\t\t\tnextExtra: nextExtra\n\t\t\t\t? { dirName: nextExtra.dirName, title: nextExtra.title }\n\t\t\t\t: null,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(extra.epicVideoEmbeds, {\n\t\t\t\trequest,\n\t\t\t}),\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\nexport default function ExtraRoute() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst rootData = useRootLoaderData()\n\tconst apps = useApps()\n\tconst inBrowserBrowserRef = useRef<InBrowserBrowserRef>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst leftPaneRef = useRef<HTMLDivElement>(null)\n\tconst [splitPercent, setSplitPercent] = useState<number>(data.splitPercent)\n\tconst [searchParams] = useSearchParams()\n\tconst workshopConfig = useWorkshopConfig()\n\tconst userHasAccessPromise = useMemo(\n\t\t() => Promise.resolve(rootData.userHasAccess ?? false),\n\t\t[rootData.userHasAccess],\n\t)\n\tconst showPlaygroundIndicator = data.playground?.appName !== data.extra.name\n\tconst shouldShowSetPlayground =\n\t\tshowPlaygroundIndicator || data.playground?.isUpToDate === false\n\tconst tabs = ['playground', 'extra', 'diff', 'chat'] as const\n\tconst preview = searchParams.get('preview')\n\tconst previousExtraLink = data.previousExtra\n\t\t? {\n\t\t\t\tto: `/extra/${data.previousExtra.dirName}`,\n\t\t\t\t'aria-label': 'Previous Extra',\n\t\t\t}\n\t\t: {\n\t\t\t\tto: '/extra',\n\t\t\t\t'aria-label': 'Extras',\n\t\t\t}\n\tconst nextExtraLink = data.nextExtra\n\t\t? {\n\t\t\t\tto: `/extra/${data.nextExtra.dirName}`,\n\t\t\t\t'aria-label': 'Next Extra',\n\t\t\t}\n\t\t: {\n\t\t\t\tto: '/finished',\n\t\t\t\t'aria-label': 'Workshop finished',\n\t\t\t}\n\n\tfunction isValidPreview(\n\t\tvalue: string | null,\n\t): value is (typeof tabs)[number] {\n\t\treturn Boolean(value && tabs.includes(value as (typeof tabs)[number]))\n\t}\n\n\tfunction shouldHideTab(tab: (typeof tabs)[number]) {\n\t\tif (tab === 'playground') {\n\t\t\treturn ENV.EPICSHOP_DEPLOYED\n\t\t}\n\t\tif (tab === 'extra') {\n\t\t\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\t\t\tconst devType = data.extra.dev.type\n\t\t\t\treturn (\n\t\t\t\t\tdevType !== 'browser' &&\n\t\t\t\t\tdevType !== 'export' &&\n\t\t\t\t\t!data.extra.stackBlitzUrl\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (tab === 'chat') {\n\t\t\treturn !workshopConfig.product.discordChannelId\n\t\t}\n\t\treturn false\n\t}\n\n\tconst activeTab =\n\t\tisValidPreview(preview) && !shouldHideTab(preview)\n\t\t\t? preview\n\t\t\t: (tabs.find((tab) => !shouldHideTab(tab)) ?? 'playground')\n\n\tconst previewTabs = tabs.map((tab) => {\n\t\tconst hidden = shouldHideTab(tab)\n\t\treturn {\n\t\t\tid: tab,\n\t\t\tlabel: tab,\n\t\t\thidden,\n\t\t\tto: `?${getPreviewSearchParams(searchParams, tab, 'playground')}`,\n\t\t}\n\t})\n\n\t// Create MDX components with playground-specific InlineFile\n\tconst mdxComponents = useMemo(() => {\n\t\tconst InlineFile = createInlineFileComponent(\n\t\t\t() =>\n\t\t\t\tdata.playground\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tname: data.playground.name,\n\t\t\t\t\t\t\tfullPath: data.playground.fullPath,\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\t() =>\n\t\t\t\t!data.playground || data.playground.appName !== data.extra.name\n\t\t\t\t\t? 'Set the playground to this extra before opening a file.'\n\t\t\t\t\t: null,\n\t\t)\n\t\treturn {\n\t\t\t// we'll render the title ourselves thank you\n\t\t\th1: () => null,\n\t\t\tInlineFile,\n\t\t}\n\t}, [data.playground, data.extra.name])\n\n\tconst playgroundBasePath = apps.find(\n\t\t(app) => app.name === data.playground?.appName,\n\t)?.fullPath\n\n\tuseRevalidationWS({\n\t\twatchPaths: [data.extraReadme.file, playgroundBasePath].filter(\n\t\t\t(path): path is string => Boolean(path),\n\t\t),\n\t})\n\n\treturn (\n\t\t<div className=\"flex max-w-full grow flex-col\">\n\t\t\t<main\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)\"\n\t\t\t\t\tstyle={{ ['--split-pct' as any]: `${splitPercent}%` }}\n\t\t\t\t\tref={leftPaneRef}\n\t\t\t\t>\n\t\t\t\t\t<h1 className=\"@container h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium\">\n\t\t\t\t\t\t<div className=\"flex h-14 items-center justify-between gap-x-2 py-2 whitespace-nowrap\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2 uppercase\">\n\t\t\t\t\t\t\t\t<Link to=\"/extra\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t<span>Extras</span>\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<Link to=\".\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t<span>{data.extra.title}</span>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{shouldShowSetPlayground ? (\n\t\t\t\t\t\t\t\t<SetAppToPlayground\n\t\t\t\t\t\t\t\t\tappName={data.extra.name}\n\t\t\t\t\t\t\t\t\tisOutdated={data.playground?.isUpToDate === false}\n\t\t\t\t\t\t\t\t\thideTextOnNarrow\n\t\t\t\t\t\t\t\t\tshowOnboardingIndicator={showPlaygroundIndicator}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<article\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t\tkey={data.articleId}\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.extra.instructionsCode ? (\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\n\t\t\t\t\t\t\t\t\t\tcode={data.extra.instructionsCode}\n\t\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex h-full items-center justify-center text-lg\">\n\t\t\t\t\t\t\t\t<p>No instructions yet...</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"mt-auto flex justify-between\">\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={previousExtraLink.to}\n\t\t\t\t\t\t\t\taria-label={previousExtraLink['aria-label']}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span aria-hidden>←</span>\n\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\"> Previous</span>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExtraLink.to}\n\t\t\t\t\t\t\t\taria-label={nextExtraLink['aria-label']}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\">Next </span>\n\t\t\t\t\t\t\t\t<span aria-hidden>→</span>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration\n\t\t\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t\t\t/>\n\t\t\t\t\t<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<EditFileOnGitHub\n\t\t\t\t\t\t\tappName={data.extra.name}\n\t\t\t\t\t\t\trelativePath={data.extraReadme.relativePath}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons prev={previousExtraLink} next={nextExtraLink} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\trole=\"separator\"\n\t\t\t\t\taria-orientation=\"vertical\"\n\t\t\t\t\ttitle=\"Drag to resize\"\n\t\t\t\t\tclassName=\"bg-border hover:bg-muted hidden w-1 cursor-col-resize lg:block\"\n\t\t\t\t\tonMouseDown={(event) =>\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: event.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tonDoubleClick={() => {\n\t\t\t\t\t\tsetSplitPercent(setSplitPercentCookie(50))\n\t\t\t\t\t}}\n\t\t\t\t\tonTouchStart={(event) => {\n\t\t\t\t\t\tconst firstTouch = event.touches?.[0]\n\t\t\t\t\t\tif (!firstTouch) return\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: firstTouch.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<Tabs.Root\n\t\t\t\t\tclassName=\"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\"\n\t\t\t\t\tvalue={activeTab}\n\t\t\t\t>\n\t\t\t\t\t<PreviewTabsList tabs={previewTabs} />\n\t\t\t\t\t<div className=\"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden\">\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"playground\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t\tforceMount\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Playground\n\t\t\t\t\t\t\t\tappInfo={data.playground}\n\t\t\t\t\t\t\t\tproblemAppName={data.extra.name}\n\t\t\t\t\t\t\t\tallApps={data.allApps ?? []}\n\t\t\t\t\t\t\t\tisUpToDate={data.playground?.isUpToDate ?? false}\n\t\t\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"extra\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t\tforceMount\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Preview\n\t\t\t\t\t\t\t\tappInfo={data.extra}\n\t\t\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"diff\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Diff\n\t\t\t\t\t\t\t\tdiff={data.diff}\n\t\t\t\t\t\t\t\tallApps={data.allApps}\n\t\t\t\t\t\t\t\tuserHasAccessPromise={userHasAccessPromise}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"chat\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DiscordChat discordPostsPromise={data.discordPostsPromise} />\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t</div>\n\t\t\t\t</Tabs.Root>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn <GeneralErrorBoundary />\n}\n"],"names":["meta","args","loaderData","data","rootData","getRootMatchLoaderData","matches","title","getSeoMetaTags","extra","workshopTitle","description","ogTitle","ogDescription","instructor","requestInfo","$extra","_UNSAFE_withComponentProps","useLoaderData","useRootLoaderData","apps","useApps","inBrowserBrowserRef","useRef","containerRef","leftPaneRef","splitPercent","setSplitPercent","useState","searchParams","useSearchParams","workshopConfig","useWorkshopConfig","userHasAccessPromise","useMemo","Promise","resolve","userHasAccess","showPlaygroundIndicator","playground","appName","name","shouldShowSetPlayground","isUpToDate","tabs","preview","get","previousExtraLink","previousExtra","to","dirName","nextExtraLink","nextExtra","isValidPreview","value","Boolean","includes","shouldHideTab","tab","ENV","EPICSHOP_DEPLOYED","devType","dev","type","stackBlitzUrl","product","discordChannelId","activeTab","find","previewTabs","map","hidden","id","label","getPreviewSearchParams","mdxComponents","InlineFile","createInlineFileComponent","fullPath","h1","playgroundBasePath","app","useRevalidationWS","watchPaths","extraReadme","file","filter","path","jsx","className","children","jsxs","ref","style","Link","SetAppToPlayground","isOutdated","hideTextOnNarrow","showOnboardingIndicator","articleId","instructionsCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","prefetch","ElementScrollRestoration","elementQuery","EditFileOnGitHub","relativePath","NavChevrons","prev","next","role","onMouseDown","event","startSplitDrag","container","current","initialClientX","clientX","onDoubleClick","setSplitPercentCookie","onTouchStart","firstTouch","touches","Tabs","PreviewTabsList","forceMount","Playground","appInfo","problemAppName","allApps","Preview","Diff","diff","DiscordChat","discordPostsPromise","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary"],"mappings":"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"}
1
+ {"version":3,"file":"_extra-DI111cn8.js","sources":["../../../app/routes/_app+/extra+/$extra.tsx"],"sourcesContent":["import { type Route } from './+types/$extra'\nimport path from 'path'\nimport { invariantResponse } from '@epic-web/invariant'\nimport { ElementScrollRestoration } from '@epic-web/restore-scroll'\nimport {\n\tgetAppByName,\n\tgetAppDisplayName,\n\tgetApps,\n\tisExtraApp,\n\tisPlaygroundApp,\n\ttype ExtraApp,\n} from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getDiffPatch } from '@epic-web/workshop-utils/diff.server'\nimport { getEpicVideoInfos } from '@epic-web/workshop-utils/epic-api.server'\nimport {\n\tcombineServerTimings,\n\tgetServerTimeHeader,\n\tmakeTimings,\n\ttime,\n} from '@epic-web/workshop-utils/timing.server'\nimport * as Tabs from '@radix-ui/react-tabs'\nimport slugify from '@sindresorhus/slugify'\nimport { useMemo, useRef, useState } from 'react'\nimport {\n\tLink,\n\tdata,\n\ttype HeadersFunction,\n\tuseLoaderData,\n\tuseSearchParams,\n} from 'react-router'\nimport { Diff } from '#app/components/diff.tsx'\nimport { DiscordChat } from '#app/components/discord-chat.tsx'\nimport { EpicVideoInfoProvider } from '#app/components/epic-video.tsx'\nimport { GeneralErrorBoundary } from '#app/components/error-boundary.tsx'\nimport { type InBrowserBrowserRef } from '#app/components/in-browser-browser.tsx'\nimport { NavChevrons } from '#app/components/nav-chevrons.tsx'\nimport {\n\tgetPreviewSearchParams,\n\tPreviewTabsList,\n} from '#app/components/preview-tabs.tsx'\nimport { useRevalidationWS } from '#app/components/revalidation-ws.tsx'\nimport { useWorkshopConfig } from '#app/components/workshop-config.tsx'\nimport { Playground } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/playground.tsx'\nimport { Preview } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/preview.tsx'\nimport { getAppRunningState } from '#app/routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/__shared/utils.tsx'\nimport { EditFileOnGitHub } from '#app/routes/launch-editor.tsx'\nimport { SetAppToPlayground } from '#app/routes/set-playground.tsx'\nimport { fetchDiscordPosts } from '#app/utils/discord.server.ts'\nimport { createInlineFileComponent, Mdx } from '#app/utils/mdx.tsx'\nimport {\n\tgetRootMatchLoaderData,\n\tuseApps,\n\tuseRootLoaderData,\n} from '#app/utils/root-loader.ts'\nimport { getSeoMetaTags } from '#app/utils/seo.ts'\nimport {\n\tgetSplitPercentFromRequest,\n\tsetSplitPercentCookie,\n\tstartSplitDrag,\n} from '#app/utils/split-layout.ts'\n\nfunction sortExtras(extras: ExtraApp[]) {\n\treturn extras.sort((a, b) =>\n\t\ta.title.localeCompare(b.title, undefined, {\n\t\t\tnumeric: true,\n\t\t\tsensitivity: 'base',\n\t\t}),\n\t)\n}\n\nexport const meta: Route.MetaFunction = (args) => {\n\tconst loaderData = args.data\n\tconst rootData = getRootMatchLoaderData(args.matches)\n\tif (!loaderData || !rootData) return [{ title: '🦉 | Error' }]\n\n\treturn getSeoMetaTags({\n\t\ttitle: `📚 | ${loaderData.extra.title} | ${rootData.workshopTitle}`,\n\t\tdescription: `Extra: ${loaderData.extra.title}`,\n\t\togTitle: loaderData.extra.title,\n\t\togDescription: `Extra: ${loaderData.extra.title}`,\n\t\tinstructor: rootData.instructor,\n\t\trequestInfo: rootData.requestInfo,\n\t})\n}\n\nexport async function loader({ request, params }: Route.LoaderArgs) {\n\tconst timings = makeTimings('extraLoader')\n\tinvariantResponse(params.extra, 'extra is required')\n\n\tconst { title: workshopTitle } = getWorkshopConfig()\n\tconst cacheOptions = { request, timings }\n\tconst apps = await time(() => getApps(cacheOptions), {\n\t\ttimings,\n\t\ttype: 'getApps',\n\t\tdesc: 'getApps in extra loader',\n\t})\n\tconst extras = sortExtras(apps.filter(isExtraApp))\n\tconst playgroundApp = apps.find(isPlaygroundApp)\n\tconst extraIndex = extras.findIndex((extra) => extra.dirName === params.extra)\n\tconst extra = extras[extraIndex]\n\tif (!extra) {\n\t\tthrow new Response('Extra not found', { status: 404 })\n\t}\n\n\tconst readmeFilepath = path.join(extra.fullPath, 'README.mdx')\n\tconst previousExtra = extras[extraIndex - 1]\n\tconst nextExtra = extras[extraIndex + 1]\n\tconst reqUrl = new URL(request.url)\n\tconst app1Name = reqUrl.searchParams.get('app1')\n\tconst app2Name = reqUrl.searchParams.get('app2')\n\tconst app1 = app1Name\n\t\t? await getAppByName(app1Name)\n\t\t: (playgroundApp ?? extra)\n\tconst app2 = app2Name ? await getAppByName(app2Name) : extra\n\tconst splitPercent = getSplitPercentFromRequest(request, 50)\n\n\tconst { isRunning, portIsAvailable } = await getAppRunningState(extra)\n\n\tasync function getDiffProp() {\n\t\tif (!app1 || !app2) {\n\t\t\treturn { app1: app1?.name, app2: app2?.name, diffPatch: null }\n\t\t}\n\t\tconst diffPatch = await getDiffPatch(app1, app2, {\n\t\t\t...cacheOptions,\n\t\t\tforceFresh: reqUrl.searchParams.get('forceFresh') === 'diff',\n\t\t}).catch((error) => {\n\t\t\tconsole.error(error)\n\t\t\treturn null\n\t\t})\n\t\treturn {\n\t\t\tapp1: app1.name,\n\t\t\tapp2: app2.name,\n\t\t\tdiffPatch,\n\t\t}\n\t}\n\n\tconst allApps = apps\n\t\t.filter(\n\t\t\t(app, index, list) =>\n\t\t\t\tlist.findIndex((item) => item.name === app.name) === index,\n\t\t)\n\t\t.map((app) => ({\n\t\t\tname: app.name,\n\t\t\tdisplayName: getAppDisplayName(app, apps),\n\t\t}))\n\t\t.sort((a, b) =>\n\t\t\ta.displayName.localeCompare(b.displayName, undefined, {\n\t\t\t\tnumeric: true,\n\t\t\t\tsensitivity: 'base',\n\t\t\t}),\n\t\t)\n\n\treturn data(\n\t\t{\n\t\t\tarticleId: `workshop-${slugify(workshopTitle)}-${slugify(\n\t\t\t\textra.title,\n\t\t\t)}-extra`,\n\t\t\tsplitPercent,\n\t\t\textra: {\n\t\t\t\ttype: 'extra',\n\t\t\t\tname: extra.name,\n\t\t\t\ttitle: extra.title,\n\t\t\t\tdirName: extra.dirName,\n\t\t\t\tfullPath: extra.fullPath,\n\t\t\t\trelativePath: extra.relativePath,\n\t\t\t\tdev: extra.dev,\n\t\t\t\ttest: extra.test,\n\t\t\t\tstackBlitzUrl: extra.stackBlitzUrl,\n\t\t\t\tisRunning,\n\t\t\t\tportIsAvailable,\n\t\t\t\tepicVideoEmbeds: extra.epicVideoEmbeds,\n\t\t\t\tinstructionsCode: extra.instructionsCode,\n\t\t\t},\n\t\t\textraReadme: {\n\t\t\t\tfile: readmeFilepath,\n\t\t\t\trelativePath: path.join(extra.relativePath, 'README.mdx'),\n\t\t\t},\n\t\t\tplayground: playgroundApp\n\t\t\t\t? ({\n\t\t\t\t\t\ttype: 'playground',\n\t\t\t\t\t\tappName: playgroundApp.appName,\n\t\t\t\t\t\tname: playgroundApp.name,\n\t\t\t\t\t\ttitle: playgroundApp.title,\n\t\t\t\t\t\tfullPath: playgroundApp.fullPath,\n\t\t\t\t\t\tdev: playgroundApp.dev,\n\t\t\t\t\t\ttest: playgroundApp.test,\n\t\t\t\t\t\tstackBlitzUrl: playgroundApp.stackBlitzUrl,\n\t\t\t\t\t\tisUpToDate: playgroundApp.isUpToDate,\n\t\t\t\t\t\t...(await getAppRunningState(playgroundApp)),\n\t\t\t\t\t} as const)\n\t\t\t\t: null,\n\t\t\tallApps,\n\t\t\tdiff: getDiffProp(),\n\t\t\tdiscordPostsPromise: fetchDiscordPosts({ request }),\n\t\t\tpreviousExtra: previousExtra\n\t\t\t\t? { dirName: previousExtra.dirName, title: previousExtra.title }\n\t\t\t\t: null,\n\t\t\tnextExtra: nextExtra\n\t\t\t\t? { dirName: nextExtra.dirName, title: nextExtra.title }\n\t\t\t\t: null,\n\t\t\tepicVideoInfosPromise: getEpicVideoInfos(extra.epicVideoEmbeds, {\n\t\t\t\trequest,\n\t\t\t}),\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\nexport default function ExtraRoute() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst rootData = useRootLoaderData()\n\tconst apps = useApps()\n\tconst inBrowserBrowserRef = useRef<InBrowserBrowserRef>(null)\n\tconst containerRef = useRef<HTMLDivElement>(null)\n\tconst leftPaneRef = useRef<HTMLDivElement>(null)\n\tconst [splitPercent, setSplitPercent] = useState<number>(data.splitPercent)\n\tconst [searchParams] = useSearchParams()\n\tconst workshopConfig = useWorkshopConfig()\n\tconst userHasAccessPromise = useMemo(\n\t\t() => Promise.resolve(rootData.userHasAccess ?? false),\n\t\t[rootData.userHasAccess],\n\t)\n\tconst showPlaygroundIndicator = data.playground?.appName !== data.extra.name\n\tconst shouldShowSetPlayground =\n\t\tshowPlaygroundIndicator || data.playground?.isUpToDate === false\n\tconst tabs = ['playground', 'extra', 'diff', 'chat'] as const\n\tconst preview = searchParams.get('preview')\n\tconst previousExtraLink = data.previousExtra\n\t\t? {\n\t\t\t\tto: `/extra/${data.previousExtra.dirName}`,\n\t\t\t\t'aria-label': 'Previous Extra',\n\t\t\t}\n\t\t: {\n\t\t\t\tto: '/extra',\n\t\t\t\t'aria-label': 'Extras',\n\t\t\t}\n\tconst nextExtraLink = data.nextExtra\n\t\t? {\n\t\t\t\tto: `/extra/${data.nextExtra.dirName}`,\n\t\t\t\t'aria-label': 'Next Extra',\n\t\t\t}\n\t\t: {\n\t\t\t\tto: '/finished',\n\t\t\t\t'aria-label': 'Workshop finished',\n\t\t\t}\n\n\tfunction isValidPreview(\n\t\tvalue: string | null,\n\t): value is (typeof tabs)[number] {\n\t\treturn Boolean(value && tabs.includes(value as (typeof tabs)[number]))\n\t}\n\n\tfunction shouldHideTab(tab: (typeof tabs)[number]) {\n\t\tif (tab === 'playground') {\n\t\t\treturn ENV.EPICSHOP_DEPLOYED\n\t\t}\n\t\tif (tab === 'extra') {\n\t\t\tif (ENV.EPICSHOP_DEPLOYED) {\n\t\t\t\tconst devType = data.extra.dev.type\n\t\t\t\treturn (\n\t\t\t\t\tdevType !== 'browser' &&\n\t\t\t\t\tdevType !== 'export' &&\n\t\t\t\t\t!data.extra.stackBlitzUrl\n\t\t\t\t)\n\t\t\t}\n\t\t}\n\t\tif (tab === 'chat') {\n\t\t\treturn !workshopConfig.product.discordChannelId\n\t\t}\n\t\treturn false\n\t}\n\n\tconst activeTab =\n\t\tisValidPreview(preview) && !shouldHideTab(preview)\n\t\t\t? preview\n\t\t\t: (tabs.find((tab) => !shouldHideTab(tab)) ?? 'playground')\n\n\tconst previewTabs = tabs.map((tab) => {\n\t\tconst hidden = shouldHideTab(tab)\n\t\treturn {\n\t\t\tid: tab,\n\t\t\tlabel: tab,\n\t\t\thidden,\n\t\t\tto: `?${getPreviewSearchParams(searchParams, tab, 'playground')}`,\n\t\t}\n\t})\n\n\t// Create MDX components with playground-specific InlineFile\n\tconst mdxComponents = useMemo(() => {\n\t\tconst InlineFile = createInlineFileComponent(\n\t\t\t() =>\n\t\t\t\tdata.playground\n\t\t\t\t\t? {\n\t\t\t\t\t\t\tname: data.playground.name,\n\t\t\t\t\t\t\tfullPath: data.playground.fullPath,\n\t\t\t\t\t\t}\n\t\t\t\t\t: null,\n\t\t\t() =>\n\t\t\t\t!data.playground || data.playground.appName !== data.extra.name\n\t\t\t\t\t? 'Set the playground to this extra before opening a file.'\n\t\t\t\t\t: null,\n\t\t)\n\t\treturn {\n\t\t\t// we'll render the title ourselves thank you\n\t\t\th1: () => null,\n\t\t\tInlineFile,\n\t\t}\n\t}, [data.playground, data.extra.name])\n\n\tconst playgroundBasePath = apps.find(\n\t\t(app) => app.name === data.playground?.appName,\n\t)?.fullPath\n\n\tuseRevalidationWS({\n\t\twatchPaths: [data.extraReadme.file, playgroundBasePath].filter(\n\t\t\t(path): path is string => Boolean(path),\n\t\t),\n\t})\n\n\treturn (\n\t\t<div className=\"flex max-w-full grow flex-col\">\n\t\t\t<main\n\t\t\t\tref={containerRef}\n\t\t\t\tclassName=\"flex grow flex-col sm:h-full sm:min-h-[800px] md:min-h-[unset] lg:flex-row\"\n\t\t\t>\n\t\t\t\t<div\n\t\t\t\t\tclassName=\"relative flex min-w-0 flex-none basis-full flex-col sm:col-span-1 sm:row-span-1 sm:h-full lg:basis-(--split-pct)\"\n\t\t\t\t\tstyle={{ ['--split-pct' as any]: `${splitPercent}%` }}\n\t\t\t\t\tref={leftPaneRef}\n\t\t\t\t>\n\t\t\t\t\t<h1 className=\"@container h-14 border-b pr-5 pl-10 text-sm leading-tight font-medium\">\n\t\t\t\t\t\t<div className=\"flex h-14 items-center justify-between gap-x-2 py-2 whitespace-nowrap\">\n\t\t\t\t\t\t\t<div className=\"flex items-center justify-start gap-x-2 uppercase\">\n\t\t\t\t\t\t\t\t<Link to=\"/extra\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t<span>Extras</span>\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<Link to=\".\" className=\"hover:underline\">\n\t\t\t\t\t\t\t\t\t<span>{data.extra.title}</span>\n\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t{shouldShowSetPlayground ? (\n\t\t\t\t\t\t\t\t<SetAppToPlayground\n\t\t\t\t\t\t\t\t\tappName={data.extra.name}\n\t\t\t\t\t\t\t\t\tisOutdated={data.playground?.isUpToDate === false}\n\t\t\t\t\t\t\t\t\thideTextOnNarrow\n\t\t\t\t\t\t\t\t\tshowOnboardingIndicator={showPlaygroundIndicator}\n\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t) : null}\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</h1>\n\t\t\t\t\t<article\n\t\t\t\t\t\tid={data.articleId}\n\t\t\t\t\t\tkey={data.articleId}\n\t\t\t\t\t\tclassName=\"shadow-on-scrollbox scrollbar-thin scrollbar-thumb-scrollbar flex h-full w-full max-w-none flex-1 scroll-pt-6 flex-col justify-between space-y-6 overflow-y-auto p-2 sm:p-10 sm:pt-8\"\n\t\t\t\t\t>\n\t\t\t\t\t\t{data.extra.instructionsCode ? (\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\n\t\t\t\t\t\t\t\t\t\tcode={data.extra.instructionsCode}\n\t\t\t\t\t\t\t\t\t\tcomponents={mdxComponents}\n\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t\t</EpicVideoInfoProvider>\n\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t<div className=\"flex h-full items-center justify-center text-lg\">\n\t\t\t\t\t\t\t\t<p>No instructions yet...</p>\n\t\t\t\t\t\t\t</div>\n\t\t\t\t\t\t)}\n\t\t\t\t\t\t<div className=\"mt-auto flex justify-between\">\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={previousExtraLink.to}\n\t\t\t\t\t\t\t\taria-label={previousExtraLink['aria-label']}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span aria-hidden>←</span>\n\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\"> Previous</span>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t<Link\n\t\t\t\t\t\t\t\tto={nextExtraLink.to}\n\t\t\t\t\t\t\t\taria-label={nextExtraLink['aria-label']}\n\t\t\t\t\t\t\t\tprefetch=\"intent\"\n\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t<span className=\"hidden xl:inline\">Next </span>\n\t\t\t\t\t\t\t\t<span aria-hidden>→</span>\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</div>\n\t\t\t\t\t</article>\n\t\t\t\t\t<ElementScrollRestoration\n\t\t\t\t\t\telementQuery={`#${data.articleId}`}\n\t\t\t\t\t\tkey={`scroll-${data.articleId}`}\n\t\t\t\t\t/>\n\t\t\t\t\t<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<EditFileOnGitHub\n\t\t\t\t\t\t\tappName={data.extra.name}\n\t\t\t\t\t\t\trelativePath={data.extraReadme.relativePath}\n\t\t\t\t\t\t/>\n\t\t\t\t\t\t<NavChevrons prev={previousExtraLink} next={nextExtraLink} />\n\t\t\t\t\t</div>\n\t\t\t\t</div>\n\t\t\t\t<div\n\t\t\t\t\trole=\"separator\"\n\t\t\t\t\taria-orientation=\"vertical\"\n\t\t\t\t\ttitle=\"Drag to resize\"\n\t\t\t\t\tclassName=\"bg-border hover:bg-muted hidden w-1 cursor-col-resize lg:block\"\n\t\t\t\t\tonMouseDown={(event) =>\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: event.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}\n\t\t\t\t\tonDoubleClick={() => {\n\t\t\t\t\t\tsetSplitPercent(setSplitPercentCookie(50))\n\t\t\t\t\t}}\n\t\t\t\t\tonTouchStart={(event) => {\n\t\t\t\t\t\tconst firstTouch = event.touches?.[0]\n\t\t\t\t\t\tif (!firstTouch) return\n\t\t\t\t\t\tstartSplitDrag({\n\t\t\t\t\t\t\tcontainer: containerRef.current,\n\t\t\t\t\t\t\tinitialClientX: firstTouch.clientX,\n\t\t\t\t\t\t\tsetSplitPercent,\n\t\t\t\t\t\t})\n\t\t\t\t\t}}\n\t\t\t\t/>\n\t\t\t\t<Tabs.Root\n\t\t\t\t\tclassName=\"relative flex min-h-0 min-w-0 flex-1 flex-col overflow-hidden\"\n\t\t\t\t\tvalue={activeTab}\n\t\t\t\t>\n\t\t\t\t\t<PreviewTabsList tabs={previewTabs} />\n\t\t\t\t\t<div className=\"relative z-10 flex min-h-0 flex-1 flex-col overflow-hidden\">\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"playground\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t\tforceMount\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Playground\n\t\t\t\t\t\t\t\tappInfo={data.playground}\n\t\t\t\t\t\t\t\tproblemAppName={data.extra.name}\n\t\t\t\t\t\t\t\tallApps={data.allApps ?? []}\n\t\t\t\t\t\t\t\tisUpToDate={data.playground?.isUpToDate ?? false}\n\t\t\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"extra\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t\tforceMount\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Preview\n\t\t\t\t\t\t\t\tappInfo={data.extra}\n\t\t\t\t\t\t\t\tinBrowserBrowserRef={inBrowserBrowserRef}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"diff\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<Diff\n\t\t\t\t\t\t\t\tdiff={data.diff}\n\t\t\t\t\t\t\t\tallApps={data.allApps}\n\t\t\t\t\t\t\t\tuserHasAccessPromise={userHasAccessPromise}\n\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t\t<Tabs.Content\n\t\t\t\t\t\t\tvalue=\"chat\"\n\t\t\t\t\t\t\tclassName=\"radix-state-inactive:hidden flex h-full min-h-0 w-full grow basis-0 items-stretch justify-center self-start\"\n\t\t\t\t\t\t>\n\t\t\t\t\t\t\t<DiscordChat discordPostsPromise={data.discordPostsPromise} />\n\t\t\t\t\t\t</Tabs.Content>\n\t\t\t\t\t</div>\n\t\t\t\t</Tabs.Root>\n\t\t\t</main>\n\t\t</div>\n\t)\n}\n\nexport function ErrorBoundary() {\n\treturn <GeneralErrorBoundary />\n}\n"],"names":["meta","args","loaderData","data","rootData","getRootMatchLoaderData","matches","title","getSeoMetaTags","extra","workshopTitle","description","ogTitle","ogDescription","instructor","requestInfo","$extra","_UNSAFE_withComponentProps","useLoaderData","useRootLoaderData","apps","useApps","inBrowserBrowserRef","useRef","containerRef","leftPaneRef","splitPercent","setSplitPercent","useState","searchParams","useSearchParams","workshopConfig","useWorkshopConfig","userHasAccessPromise","useMemo","Promise","resolve","userHasAccess","showPlaygroundIndicator","playground","appName","name","shouldShowSetPlayground","isUpToDate","tabs","preview","get","previousExtraLink","previousExtra","to","dirName","nextExtraLink","nextExtra","isValidPreview","value","Boolean","includes","shouldHideTab","tab","ENV","EPICSHOP_DEPLOYED","devType","dev","type","stackBlitzUrl","product","discordChannelId","activeTab","find","previewTabs","map","hidden","id","label","getPreviewSearchParams","mdxComponents","InlineFile","createInlineFileComponent","fullPath","h1","playgroundBasePath","app","useRevalidationWS","watchPaths","extraReadme","file","filter","path","jsx","className","children","jsxs","ref","style","Link","SetAppToPlayground","isOutdated","hideTextOnNarrow","showOnboardingIndicator","articleId","instructionsCode","EpicVideoInfoProvider","epicVideoInfosPromise","Mdx","code","components","prefetch","ElementScrollRestoration","elementQuery","EditFileOnGitHub","relativePath","NavChevrons","prev","next","role","onMouseDown","event","startSplitDrag","container","current","initialClientX","clientX","onDoubleClick","setSplitPercentCookie","onTouchStart","firstTouch","touches","Tabs","PreviewTabsList","forceMount","Playground","appInfo","problemAppName","allApps","Preview","Diff","diff","DiscordChat","discordPostsPromise","ErrorBoundary","_UNSAFE_withErrorBoundaryProps","GeneralErrorBoundary"],"mappings":"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"}
@@ -1297,5 +1297,5 @@ XID_Start XIDS`.split(/\s/).map(t=>[Dt(t),t])),Du=new Map([["s",M(383)],[M(383),
1297
1297
  [data-line-type='context-expanded'] [data-column-content] *::selection {
1298
1298
  background: var(--diffs-bg-selection);
1299
1299
  }
1300
- `,Ao={foreground:"var(--base05)",background:"var(--base00)","token-link":"var(--base0D)","token-string":"var(--base0B)","token-comment":"var(--base03)","token-constant":"var(--base08)","token-keyword":"var(--base0A)","token-parameter":"var(--base08)","token-function":"var(--base0D)","token-string-expression":"var(--base0C)","token-punctuation":"var(--base0E)","token-inserted":"var(--diff-color-added)","token-deleted":"var(--diff-color-deleted)","token-changed":"var(--diff-color-modified)","ansi-green":"var(--diff-color-added)","ansi-red":"var(--diff-color-deleted)","ansi-blue":"var(--diff-color-modified)"};xo(So,Ao);xo(Lo,Ao);function Tf(t){return`${t.prevName??""}::${t.name}`}function If(t){return t.prevName&&t.prevName!==t.name?`${t.prevName} -> ${t.name}`:t.name}function Ro(t){switch(t.type){case"new":return"added";case"deleted":return"deleted";case"rename-pure":case"rename-changed":return"renamed";default:return"changed"}}function Pf(t){switch(Ro(t)){case"added":return"Added";case"deleted":return"Deleted";case"renamed":return"Renamed";default:return"Modified"}}function Df(t){switch(Ro(t)){case"added":return"text-[var(--diff-color-added)]";case"deleted":return"text-[var(--diff-color-deleted)]";case"renamed":return"text-[var(--diff-color-renamed)]";case"changed":default:return"text-[var(--diff-color-modified)]"}}function Nf(t){return t.hunks.reduce((e,n)=>({added:e.added+n.additionCount,deleted:e.deleted+n.deletionCount}),{added:0,deleted:0})}function ni(t){return!t||t==="/dev/null"?void 0:t.replace(/^["']|["']$/g,"").replace(/^[ab]\//,"")}function Of(t){return{app1Path:ni(t.prevName??t.name),app2Path:ni(t.name??t.prevName)}}function Mf(t){const e=t.hunks[0];return{app1Line:e?.deletionStart||e?.splitLineStart||1,app2Line:e?.additionStart||e?.splitLineStart||1}}function $f({fileDiff:t,app1Name:e,app2Name:n}){if(!e||!n)return null;const{app1Path:r,app2Path:i}=Of(t);if(!r||!i)return null;const{app1Line:o,app2Line:s}=Mf(t),a="bg-background/80 border-border/80 hover:bg-background inline-flex h-6 cursor-pointer items-center justify-center rounded border",l=ft(a,"w-11 px-1.5 font-mono text-[10px] leading-none uppercase"),c=ft(a,"text-foreground w-6");return E.jsxs("div",{className:"flex items-center gap-1",onClick:u=>u.stopPropagation(),onPointerDown:u=>u.stopPropagation(),children:[E.jsx(et,{appFile:`${r},${o},1`,appName:e,className:l,children:"App 1"}),E.jsxs("div",{className:"display-alt-down flex items-center gap-1",children:[E.jsx(et,{appFile:r,appName:e,syncTo:{appFile:i,appName:n},className:c,children:E.jsx(te,{name:"ArrowLeft",title:"Copy app 2 file to app 1 (Option+Command to sync without opening)"})}),E.jsx(et,{appFile:i,appName:n,syncTo:{appFile:r,appName:e},className:c,children:E.jsx(te,{name:"ArrowRight",title:"Copy app 1 file to app 2 (Option+Command to sync without opening)"})})]}),E.jsx(et,{appFile:`${i},${s},1`,appName:n,className:l,children:"App 2"})]})}function Vf({app1:t,app2:e}){const n=is(),r=n.find(o=>o.name===t),i=n.find(o=>o.name===e);return ss({watchPaths:[r?.fullPath,i?.fullPath].filter(Boolean)}),null}function ih({userHasAccessPromise:t,diff:e,allApps:n}){return E.jsx(To,{fallbackRender:()=>E.jsx("div",{className:"w-full p-12",children:E.jsxs("div",{className:"flex w-full flex-col gap-4 text-center",children:[E.jsx("p",{className:"text-2xl font-bold",children:"Error"}),E.jsx("p",{className:"text-lg",children:"There was an error loading the user access."})]})}),children:E.jsx(re.Suspense,{fallback:E.jsx("div",{className:"flex items-center justify-center p-8",children:E.jsx(dn,{content:"Loading user access",children:E.jsx(te,{name:"Refresh",className:"animate-spin"})})}),children:E.jsx(oi,{resolve:t,children:r=>r?E.jsx(jf,{diff:e,allApps:n}):E.jsxs("div",{className:"w-full p-12",children:[E.jsxs("div",{className:"flex w-full flex-col gap-4 text-center",children:[E.jsx("p",{className:"text-2xl font-bold",children:"Access Denied"}),E.jsx("p",{className:"text-lg",children:"You must login or register for the workshop to view the diff."})]}),E.jsx("div",{className:"h-16"}),E.jsx("p",{className:"pb-4",children:"Check out this video to see how the diff tab works."}),E.jsx(os,{url:"https://www.epicweb.dev/tips/epic-workshop-diff-tab-demo"})]})})})})}function jf({diff:t,allApps:e}){const n=Yo(),[r]=Zo(),i=new URLSearchParams(r);i.set("forceFresh","diff");const o=es(),s=Jo.useSpinDelay(o.state!=="idle",{delay:0,minDuration:1e3}),[a,l]=Mo.useState([]),c=rs(),u={theme:{light:So,dark:Lo},themeType:c,diffStyle:"unified",hunkSeparators:"line-info",overflow:"scroll",disableFileHeader:!0,unsafeCSS:Rf},d=[];for(const[h,p]of r.entries())h==="app1"||h==="app2"||d.push(E.jsx("input",{type:"hidden",name:h,value:p},h));return E.jsx(re.Suspense,{fallback:E.jsx("div",{className:"flex items-center justify-center p-8",children:E.jsx(dn,{content:"Loading diff",children:E.jsx(te,{name:"Refresh",className:"animate-spin"})})}),children:E.jsx(oi,{resolve:t,errorElement:E.jsx("p",{className:"text-foreground-destructive p-6",children:"There was an error calculating the diff. Sorry."}),children:h=>{let p=[],m=!1;if(h.diffPatch)try{p=Co(h.diffPatch).flatMap(v=>v.files)}catch{m=!0}return E.jsxs("div",{className:"flex h-full w-full flex-col",children:[E.jsxs("div",{className:"flex h-14 min-h-14 w-full overflow-x-hidden border-b",children:[E.jsx("div",{className:"border-r",children:E.jsx(dn,{content:"Reload diff",children:E.jsx(ts,{to:`.?${i}`,className:"flex h-full w-14 items-center justify-center",children:E.jsx(te,{name:"Refresh",className:ft({"animate-spin":s})})})})}),E.jsxs(ns,{onChange:v=>n(v.currentTarget),className:"scrollbar-thin scrollbar-thumb-scrollbar flex h-full flex-1 items-center overflow-x-auto",children:[d,E.jsx(ri,{name:"app1",label:"App 1",className:"border-r",allApps:e,defaultValue:h.app1}),E.jsx(ri,{name:"app2",label:"App 2",allApps:e,defaultValue:h.app2})]},`${h.app1}${h.app2}`)]}),E.jsx("div",{className:"scrollbar-thin scrollbar-thumb-scrollbar grow overflow-y-scroll",children:m?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"There was a problem rendering the diff"}):p.length?E.jsx(Io,{type:"multiple",value:a,onValueChange:l,className:"w-full",children:p.map((v,y)=>{const _=Tf(v),g=Nf(v);return E.jsxs(Po,{value:_,children:[E.jsxs(Do,{className:"bg-background/95 hover:bg-background/90 supports-[backdrop-filter]:bg-background/80 supports-[backdrop-filter]:hover:bg-background/70 border-border/70 relative sticky top-0 z-10 flex w-full items-center gap-3 border-b px-4 py-2 backdrop-blur",children:[E.jsxs(No,{className:"group flex min-w-0 flex-1 items-center justify-between gap-3 pr-38 text-left",children:[E.jsxs("span",{className:"flex min-w-0 items-center gap-2 font-mono text-sm",children:[E.jsx(te,{name:Pf(v),className:ft("shrink-0",Df(v))}),E.jsx("span",{className:"truncate",children:If(v)})]}),E.jsxs("span",{className:"text-muted-foreground flex shrink-0 items-center gap-2 font-mono text-xs",children:[E.jsxs("span",{className:"text-(--diff-color-deleted)",children:["-",g.deleted]}),E.jsxs("span",{className:"text-(--diff-color-added)",children:["+",g.added]}),E.jsx(te,{name:"TriangleDownSmall",className:"group-radix-state-open:rotate-180 transition","aria-hidden":!0})]})]}),E.jsx("div",{className:"absolute top-1/2 right-4 -translate-y-1/2",children:E.jsx($f,{fileDiff:v,app1Name:h.app1,app2Name:h.app2})})]}),E.jsx(Oo,{className:"radix-state-closed:hidden border-b",children:E.jsx(Af,{fileDiff:v,options:u})})]},`${_}:${y}`)})}):h.diffPatch===""?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"No changes"}):h.app1&&h.app2?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"There was a problem generating the diff"}):E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"Select two apps to compare"})}),E.jsx(Vf,{app1:h.app1,app2:h.app2})]})}})})}function ri({name:t,label:e,className:n,allApps:r,defaultValue:i}){return E.jsxs($o,{name:t,defaultValue:i,children:[E.jsxs(Vo,{className:ii("radix-placeholder:text-muted-foreground flex h-full w-full max-w-[50%] items-center justify-between px-3 text-left focus-visible:outline-none",n),"aria-label":`Select ${e} for git Diff`,children:[E.jsxs("span",{className:"truncate",children:[e,":"," ",E.jsx(jo,{placeholder:`Select ${e}`,className:"inline-block w-40 truncate"})]}),E.jsx(Fo,{className:"",children:E.jsx(te,{name:"TriangleDownSmall"})})]}),E.jsx(Go,{children:E.jsxs(Bo,{position:"popper",align:"start",className:"bg-popover text-popover-foreground z-20 max-h-[50vh] lg:max-h-[70vh]",children:[E.jsx(Ho,{className:"flex h-5 cursor-default items-center justify-center",children:E.jsx(te,{name:"ChevronUp"})}),E.jsx(Uo,{className:"p-3",children:E.jsxs(Wo,{children:[E.jsx(zo,{className:"px-5 pb-3 font-mono uppercase",children:e}),r.map(o=>E.jsx(Ff,{value:o.name,children:o.displayName},o.name))]})}),E.jsx(qo,{className:"flex h-5 cursor-default items-center justify-center",children:E.jsx(te,{name:"ChevronDown"})})]})})]})}const Ff=({ref:t,children:e,className:n,...r})=>E.jsxs(Xo,{className:ii("radix-disabled:text-muted-foreground radix-highlighted:opacity-100 radix-highlighted:outline-none radix-state-checked:opacity-100 relative flex cursor-pointer items-center rounded px-10 py-2 leading-none opacity-80 select-none",n),...r,ref:t,children:[E.jsx(Ko,{children:e}),E.jsx(Qo,{className:"absolute left-0 inline-flex w-[25px] items-center justify-center",children:E.jsx(te,{name:"CheckSmall"})})]});export{ih as U};
1301
- //# sourceMappingURL=diff-C4LoXlDb.js.map
1300
+ `,Ao={foreground:"var(--base05)",background:"var(--base00)","token-link":"var(--base0D)","token-string":"var(--base0B)","token-comment":"var(--base03)","token-constant":"var(--base08)","token-keyword":"var(--base0A)","token-parameter":"var(--base08)","token-function":"var(--base0D)","token-string-expression":"var(--base0C)","token-punctuation":"var(--base0E)","token-inserted":"var(--diff-color-added)","token-deleted":"var(--diff-color-deleted)","token-changed":"var(--diff-color-modified)","ansi-green":"var(--diff-color-added)","ansi-red":"var(--diff-color-deleted)","ansi-blue":"var(--diff-color-modified)"};xo(So,Ao);xo(Lo,Ao);function Tf(t){return`${t.prevName??""}::${t.name}`}function If(t){return t.prevName&&t.prevName!==t.name?`${t.prevName} -> ${t.name}`:t.name}function Ro(t){switch(t.type){case"new":return"added";case"deleted":return"deleted";case"rename-pure":case"rename-changed":return"renamed";default:return"changed"}}function Pf(t){switch(Ro(t)){case"added":return"Added";case"deleted":return"Deleted";case"renamed":return"Renamed";default:return"Modified"}}function Df(t){switch(Ro(t)){case"added":return"text-[var(--diff-color-added)]";case"deleted":return"text-[var(--diff-color-deleted)]";case"renamed":return"text-[var(--diff-color-renamed)]";case"changed":default:return"text-[var(--diff-color-modified)]"}}function Nf(t){return t.hunks.reduce((e,n)=>({added:e.added+n.additionCount,deleted:e.deleted+n.deletionCount}),{added:0,deleted:0})}function ni(t){return!t||t==="/dev/null"?void 0:t.replace(/^["']|["']$/g,"").replace(/^[ab]\//,"")}function Of(t){return{app1Path:ni(t.prevName??t.name),app2Path:ni(t.name??t.prevName)}}function Mf(t){const e=t.hunks[0];return{app1Line:e?.deletionStart||e?.splitLineStart||1,app2Line:e?.additionStart||e?.splitLineStart||1}}function $f({fileDiff:t,app1Name:e,app2Name:n}){if(!e||!n)return null;const{app1Path:r,app2Path:i}=Of(t);if(!r||!i)return null;const{app1Line:o,app2Line:s}=Mf(t),a="bg-background/80 border-border/80 hover:bg-background inline-flex h-6 cursor-pointer items-center justify-center rounded border",l=ft(a,"w-11 px-1.5 font-mono text-[10px] leading-none uppercase"),c=ft(a,"text-foreground w-6");return E.jsxs("div",{className:"flex items-center gap-1",onClick:u=>u.stopPropagation(),onPointerDown:u=>u.stopPropagation(),children:[E.jsx(et,{appFile:`${r},${o},1`,appName:e,className:l,children:"App 1"}),E.jsxs("div",{className:"display-alt-down flex items-center gap-1",children:[E.jsx(et,{appFile:r,appName:e,syncTo:{appFile:i,appName:n},className:c,children:E.jsx(te,{name:"ArrowLeft",title:"Copy app 2 file to app 1 (Option+Command to sync without opening)"})}),E.jsx(et,{appFile:i,appName:n,syncTo:{appFile:r,appName:e},className:c,children:E.jsx(te,{name:"ArrowRight",title:"Copy app 1 file to app 2 (Option+Command to sync without opening)"})})]}),E.jsx(et,{appFile:`${i},${s},1`,appName:n,className:l,children:"App 2"})]})}function Vf({app1:t,app2:e}){const n=is(),r=n.find(o=>o.name===t),i=n.find(o=>o.name===e);return ss({watchPaths:[r?.fullPath,i?.fullPath].filter(Boolean)}),null}function ih({userHasAccessPromise:t,diff:e,allApps:n}){return E.jsx(To,{fallbackRender:()=>E.jsx("div",{className:"w-full p-12",children:E.jsxs("div",{className:"flex w-full flex-col gap-4 text-center",children:[E.jsx("p",{className:"text-2xl font-bold",children:"Error"}),E.jsx("p",{className:"text-lg",children:"There was an error loading the user access."})]})}),children:E.jsx(re.Suspense,{fallback:E.jsx("div",{className:"flex items-center justify-center p-8",children:E.jsx(dn,{content:"Loading user access",children:E.jsx(te,{name:"Refresh",className:"animate-spin"})})}),children:E.jsx(oi,{resolve:t,children:r=>r?E.jsx(jf,{diff:e,allApps:n}):E.jsxs("div",{className:"w-full p-12",children:[E.jsxs("div",{className:"flex w-full flex-col gap-4 text-center",children:[E.jsx("p",{className:"text-2xl font-bold",children:"Access Denied"}),E.jsx("p",{className:"text-lg",children:"You must login or register for the workshop to view the diff."})]}),E.jsx("div",{className:"h-16"}),E.jsx("p",{className:"pb-4",children:"Check out this video to see how the diff tab works."}),E.jsx(os,{url:"https://www.epicweb.dev/tips/epic-workshop-diff-tab-demo"})]})})})})}function jf({diff:t,allApps:e}){const n=Yo(),[r]=Zo(),i=new URLSearchParams(r);i.set("forceFresh","diff");const o=es(),s=Jo.useSpinDelay(o.state!=="idle",{delay:0,minDuration:1e3}),[a,l]=Mo.useState([]),c=rs(),u={theme:{light:So,dark:Lo},themeType:c,diffStyle:"unified",hunkSeparators:"line-info",overflow:"scroll",disableFileHeader:!0,unsafeCSS:Rf},d=[];for(const[h,p]of r.entries())h==="app1"||h==="app2"||d.push(E.jsx("input",{type:"hidden",name:h,value:p},h));return E.jsx(re.Suspense,{fallback:E.jsx("div",{className:"flex items-center justify-center p-8",children:E.jsx(dn,{content:"Loading diff",children:E.jsx(te,{name:"Refresh",className:"animate-spin"})})}),children:E.jsx(oi,{resolve:t,errorElement:E.jsx("p",{className:"text-foreground-destructive p-6",children:"There was an error calculating the diff. Sorry."}),children:h=>{let p=[],m=!1;if(h.diffPatch)try{p=Co(h.diffPatch).flatMap(v=>v.files)}catch{m=!0}return E.jsxs("div",{className:"flex h-full w-full flex-col",children:[E.jsxs("div",{className:"flex h-14 min-h-14 w-full overflow-x-hidden border-b",children:[E.jsx("div",{className:"border-r",children:E.jsx(dn,{content:"Reload diff",children:E.jsx(ts,{to:`.?${i}`,className:"flex h-full w-14 items-center justify-center",children:E.jsx(te,{name:"Refresh",className:ft({"animate-spin":s})})})})}),E.jsxs(ns,{onChange:v=>n(v.currentTarget),className:"scrollbar-thin scrollbar-thumb-scrollbar flex h-full flex-1 items-center overflow-x-auto",children:[d,E.jsx(ri,{name:"app1",label:"App 1",className:"border-r",allApps:e,defaultValue:h.app1}),E.jsx(ri,{name:"app2",label:"App 2",allApps:e,defaultValue:h.app2})]},`${h.app1}${h.app2}`)]}),E.jsx("div",{className:"scrollbar-thin scrollbar-thumb-scrollbar grow overflow-y-scroll",children:m?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"There was a problem rendering the diff"}):p.length?E.jsx(Io,{type:"multiple",value:a,onValueChange:l,className:"w-full",children:p.map((v,y)=>{const _=Tf(v),g=Nf(v);return E.jsxs(Po,{value:_,children:[E.jsxs(Do,{className:"bg-background/95 hover:bg-background/90 supports-[backdrop-filter]:bg-background/80 supports-[backdrop-filter]:hover:bg-background/70 border-border/70 sticky top-0 z-10 flex w-full items-center gap-3 border-b backdrop-blur",children:[E.jsxs(No,{className:"group flex min-w-0 flex-1 items-center justify-between gap-3 px-4 py-2 pr-38 text-left",children:[E.jsxs("span",{className:"flex min-w-0 items-center gap-2 font-mono text-sm",children:[E.jsx(te,{name:Pf(v),className:ft("shrink-0",Df(v))}),E.jsx("span",{className:"truncate",children:If(v)})]}),E.jsxs("span",{className:"text-muted-foreground flex shrink-0 items-center gap-2 font-mono text-xs",children:[E.jsxs("span",{className:"text-(--diff-color-deleted)",children:["-",g.deleted]}),E.jsxs("span",{className:"text-(--diff-color-added)",children:["+",g.added]}),E.jsx(te,{name:"TriangleDownSmall",className:"group-radix-state-open:rotate-180 transition","aria-hidden":!0})]})]}),E.jsx("div",{className:"absolute top-1/2 right-4 -translate-y-1/2",children:E.jsx($f,{fileDiff:v,app1Name:h.app1,app2Name:h.app2})})]}),E.jsx(Oo,{className:"radix-state-closed:hidden border-b",children:E.jsx(Af,{fileDiff:v,options:u})})]},`${_}:${y}`)})}):h.diffPatch===""?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"No changes"}):h.app1&&h.app2?E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"There was a problem generating the diff"}):E.jsx("p",{className:"bg-foreground text-background m-5 inline-flex items-center justify-center px-1 py-0.5 font-mono text-sm uppercase",children:"Select two apps to compare"})}),E.jsx(Vf,{app1:h.app1,app2:h.app2})]})}})})}function ri({name:t,label:e,className:n,allApps:r,defaultValue:i}){return E.jsxs($o,{name:t,defaultValue:i,children:[E.jsxs(Vo,{className:ii("radix-placeholder:text-muted-foreground flex h-full w-full max-w-[50%] items-center justify-between px-3 text-left focus-visible:outline-none",n),"aria-label":`Select ${e} for git Diff`,children:[E.jsxs("span",{className:"truncate",children:[e,":"," ",E.jsx(jo,{placeholder:`Select ${e}`,className:"inline-block w-40 truncate"})]}),E.jsx(Fo,{className:"",children:E.jsx(te,{name:"TriangleDownSmall"})})]}),E.jsx(Go,{children:E.jsxs(Bo,{position:"popper",align:"start",className:"bg-popover text-popover-foreground z-20 max-h-[50vh] lg:max-h-[70vh]",children:[E.jsx(Ho,{className:"flex h-5 cursor-default items-center justify-center",children:E.jsx(te,{name:"ChevronUp"})}),E.jsx(Uo,{className:"p-3",children:E.jsxs(Wo,{children:[E.jsx(zo,{className:"px-5 pb-3 font-mono uppercase",children:e}),r.map(o=>E.jsx(Ff,{value:o.name,children:o.displayName},o.name))]})}),E.jsx(qo,{className:"flex h-5 cursor-default items-center justify-center",children:E.jsx(te,{name:"ChevronDown"})})]})})]})}const Ff=({ref:t,children:e,className:n,...r})=>E.jsxs(Xo,{className:ii("radix-disabled:text-muted-foreground radix-highlighted:opacity-100 radix-highlighted:outline-none radix-state-checked:opacity-100 relative flex cursor-pointer items-center rounded px-10 py-2 leading-none opacity-80 select-none",n),...r,ref:t,children:[E.jsx(Ko,{children:e}),E.jsx(Qo,{className:"absolute left-0 inline-flex w-[25px] items-center justify-center",children:E.jsx(te,{name:"CheckSmall"})})]});export{ih as U};
1301
+ //# sourceMappingURL=diff-D18ACTzf.js.map