@epic-web/workshop-app 4.23.2 → 4.24.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epic-web/workshop-app",
3
- "version": "4.23.2",
3
+ "version": "4.24.0",
4
4
  "sideEffects": false,
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -44,8 +44,8 @@
44
44
  "@epic-web/invariant": "^1.0.0",
45
45
  "@epic-web/remember": "^1.0.2",
46
46
  "@epic-web/restore-scroll": "^1.1.1",
47
- "@epic-web/workshop-presence": "4.23.2",
48
- "@epic-web/workshop-utils": "4.23.2",
47
+ "@epic-web/workshop-presence": "4.24.0",
48
+ "@epic-web/workshop-utils": "4.24.0",
49
49
  "@mdx-js/mdx": "^3.0.1",
50
50
  "@mux/mux-player-react": "^2.6.0",
51
51
  "@nasa-gcn/remix-seo": "^2.0.1",
@@ -1,2 +0,0 @@
1
- import{c as b,j as e}from"./index-1cKOJFpX.js";import{I as m}from"./misc-BvHlNnqL.js";import{S as f}from"./tooltip-fa2eC7LQ.js";import{a as g}from"./progress-Dn5gs-vs.js";import{u as N,L as i,F as c}from"./components-CME-nGId.js";import"./pe-CUZaIcdt.js";const L={getSitemapEntries:()=>null},T=({matches:n})=>{var r;const l=(r=n.find(o=>o.id==="root"))==null?void 0:r.data;return[{title:`👷 | ${l==null?void 0:l.workshopTitle}`}]};function S(n,l){return n.type==="unknown"&&l.type==="unknown"?0:n.type==="unknown"?-1:l.type==="unknown"?1:0}function w(n){switch(n.type){case"workshop-instructions":return"/";case"workshop-finished":return"/finished";case"instructions":return`/${n.exerciseNumber.toString().padStart(2,"0")}`;case"step":return`/${n.exerciseNumber.toString().padStart(2,"0")}/${n.stepNumber.toString().padStart(2,"0")}`;case"finished":return`/${n.exerciseNumber.toString().padStart(2,"0")}/finished`;default:return""}}function A(){var a,d;const n=N(),l=b(),r=g(),o=((a=l.formData)==null?void 0:a.get("intent"))==="inspect",u=((d=l.formData)==null?void 0:d.get("intent"))==="stop-inspect",j={completed:"bg-blue-500",incomplete:"bg-yellow-500"};return e.jsxs("main",{className:"container mx-auto mt-8",children:[e.jsx("h1",{className:"text-4xl font-bold",children:"Admin"}),e.jsxs("div",{className:"flex flex-col gap-4",children:[e.jsx("nav",{children:e.jsxs("ul",{className:"flex gap-3",children:[e.jsx("li",{children:e.jsx(i,{className:"underline",to:"/",children:"Home"})}),e.jsx("li",{children:e.jsx(i,{className:"underline",to:"/diff",children:"Diff Viewer"})})]})}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Progress"}),r?e.jsx("ul",{className:"flex max-h-72 flex-col gap-2 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:r.sort(S).map(s=>{const t=`https://www.epicweb.dev/workshops/${n.workshopSlug}/${s.epicSectionSlug}/${s.epicLessonSlug}`,p=s.epicCompletedAt?"completed":"incomplete",h=[`${s.epicSectionSlug}/${s.epicLessonSlug}`,s.epicCompletedAt?`(${s.epicCompletedAt})`:null].filter(Boolean).join(" ");return e.jsxs("li",{className:"flex items-center gap-2",children:[e.jsx("span",{className:`h-3 w-3 rounded-full ${j[p]}`,title:p}),s.type==="unknown"?e.jsxs("span",{className:"flex items-center gap-1",children:[h,e.jsx("span",{className:"text-red-500",children:e.jsx(f,{content:"This video is in the workshop on EpicWeb.dev, but not in the local workshop.",children:e.jsx(m,{name:"Close"})})})]}):e.jsx(i,{to:w(s),children:h}),e.jsx(i,{to:t,children:e.jsx(m,{name:"ExternalLink"})})]},s.epicLessonSlug)})}):e.jsx("p",{children:"No progress data"})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Commands"}),e.jsxs("ul",{className:"max-h-48 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:[e.jsx("li",{children:e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"clear-caches",children:"Clear local caches"})})}),e.jsx("li",{children:e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"clear-data",children:"Clear all local data (including auth data)"})})}),e.jsx("li",{children:n.inspectorRunning?e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"stop-inspect",children:o?"Stopping inspector...":"Stop inspector"})}):e.jsx(c,{method:"POST",children:e.jsx("button",{name:"intent",value:"inspect",children:u?"Starting inspector...":"Start inspector"})})})]})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Apps"}),e.jsx("ul",{className:"max-h-48 list-none overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:n.apps.map(s=>e.jsxs("li",{className:"flex items-center gap-2 py-1",children:[n.processes[s.name]?e.jsx(x,{status:"running"}):e.jsx(x,{status:"stopped"}),s.name]},s.name))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Processes"}),e.jsx("ul",{className:"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:Object.entries(n.processes).map(([s,t])=>e.jsx("li",{children:e.jsxs("span",{children:[s," - Port: ",t.port," - PID ",t.pid," -"," ",t.color]})},s))})]}),e.jsxs("div",{children:[e.jsx("h2",{className:"text-lg font-bold",children:"Test Processes"}),e.jsx("ul",{className:"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar",children:Object.entries(n.testProcesses).map(([s,t])=>e.jsx("li",{children:e.jsxs("span",{children:[s," - PID ",t.pid," - Exit code: ",t.exitCode]})},s))})]})]})]})}function x({status:n}){const l={running:{pinger:"bg-green-400",circle:"bg-green-500"},starting:{pinger:"bg-sky-400",circle:"bg-sky-500"},stopped:{circle:"bg-gray-500"},taken:{pinger:"bg-red-400",circle:"bg-red-500"}}[n];return e.jsxs("span",{className:"relative flex h-3 w-3",children:[l.pinger?e.jsx("span",{className:`absolute inline-flex h-full w-full animate-ping rounded-full ${l.pinger} opacity-75`}):null,e.jsx("span",{className:`relative inline-flex h-3 w-3 rounded-full ${l.circle}`})]})}export{A as default,L as handle,T as meta};
2
- //# sourceMappingURL=_layout-D2SdN9lJ.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"_layout-D2SdN9lJ.js","sources":["../../../app/routes/admin+/_layout.tsx"],"sourcesContent":["import { getApps } from '@epic-web/workshop-utils/apps.server'\nimport { getWorkshopConfig } from '@epic-web/workshop-utils/config.server'\nimport { getProcesses } from '@epic-web/workshop-utils/process-manager.server'\nimport {\n\tgetServerTimeHeader,\n\tmakeTimings,\n} from '@epic-web/workshop-utils/timing.server'\nimport { type SEOHandle } from '@nasa-gcn/remix-seo'\nimport {\n\tjson,\n\ttype ActionFunctionArgs,\n\ttype LoaderFunctionArgs,\n\ttype MetaFunction,\n} from '@remix-run/node'\nimport { Form, Link, useLoaderData, useNavigation } from '@remix-run/react'\nimport { Icon } from '#app/components/icons.tsx'\nimport { SimpleTooltip } from '#app/components/ui/tooltip.tsx'\nimport { type loader as rootLoader } from '#app/root.tsx'\nimport {\n\tuseEpicProgress,\n\ttype SerializedProgress,\n} from '#app/routes/progress.tsx'\nimport { ensureUndeployed } from '#app/utils/misc.tsx'\nimport {\n\tclearCaches,\n\tclearData,\n\tstartInspector,\n\tstopInspector,\n} from './admin-utils.server.tsx'\n\ndeclare global {\n\tvar __inspector_open__: boolean | undefined\n}\n\nexport const handle: SEOHandle = {\n\tgetSitemapEntries: () => null,\n}\n\nexport const meta: MetaFunction<typeof loader, { root: typeof rootLoader }> = ({\n\tmatches,\n}) => {\n\tconst rootData = matches.find((m) => m.id === 'root')?.data\n\treturn [{ title: `👷 | ${rootData?.workshopTitle}` }]\n}\n\nexport async function loader({ request }: LoaderFunctionArgs) {\n\tensureUndeployed()\n\tconst timings = makeTimings('adminLoader')\n\tconst workshopSlug = getWorkshopConfig().epicWorkshopSlug ?? 'Unkown'\n\tconst apps = (await getApps({ request, timings })).filter(\n\t\t(a, i, ar) => ar.findIndex((b) => a.name === b.name) === i,\n\t)\n\tconst processes: Record<\n\t\tstring,\n\t\t{ port: number; pid?: number; color: string }\n\t> = {}\n\tconst testProcesses: Record<\n\t\tstring,\n\t\t{ pid?: number; exitCode?: number | null }\n\t> = {}\n\tfor (const [\n\t\tname,\n\t\t{ port, process, color },\n\t] of getProcesses().devProcesses.entries()) {\n\t\tprocesses[name] = { port, pid: process.pid, color }\n\t}\n\n\tfor (const [\n\t\tname,\n\t\t{ process, exitCode },\n\t] of getProcesses().testProcesses.entries()) {\n\t\ttestProcesses[name] = { pid: process?.pid, exitCode }\n\t}\n\treturn json(\n\t\t{\n\t\t\tapps,\n\t\t\tprocesses,\n\t\t\tworkshopSlug,\n\t\t\ttestProcesses,\n\t\t\tinspectorRunning: global.__inspector_open__,\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 async function action({ request }: ActionFunctionArgs) {\n\tensureUndeployed()\n\tconst formData = await request.formData()\n\tconst intent = formData.get('intent')\n\tswitch (intent) {\n\t\tcase 'clear-data': {\n\t\t\tawait clearData()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'clear-caches': {\n\t\t\tawait clearCaches()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'inspect': {\n\t\t\tawait startInspector()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tcase 'stop-inspect': {\n\t\t\tawait stopInspector()\n\t\t\treturn json({ success: true })\n\t\t}\n\t\tdefault: {\n\t\t\tthrow new Error(`Unknown intent: ${intent}`)\n\t\t}\n\t}\n}\n\nfunction sortProgress(a: SerializedProgress, b: SerializedProgress) {\n\treturn a.type === 'unknown' && b.type === 'unknown'\n\t\t? 0\n\t\t: a.type === 'unknown'\n\t\t\t? -1\n\t\t\t: b.type === 'unknown'\n\t\t\t\t? 1\n\t\t\t\t: 0\n}\n\nfunction linkProgress(progress: SerializedProgress) {\n\tswitch (progress.type) {\n\t\tcase 'workshop-instructions':\n\t\t\treturn '/'\n\t\tcase 'workshop-finished':\n\t\t\treturn '/finished'\n\t\tcase 'instructions':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}`\n\t\tcase 'step':\n\t\t\treturn `/${progress.exerciseNumber\n\t\t\t\t.toString()\n\t\t\t\t.padStart(2, '0')}/${progress.stepNumber.toString().padStart(2, '0')}`\n\t\tcase 'finished':\n\t\t\treturn `/${progress.exerciseNumber.toString().padStart(2, '0')}/finished`\n\t\tdefault:\n\t\t\treturn ''\n\t}\n}\n\nexport default function AdminLayout() {\n\tconst data = useLoaderData<typeof loader>()\n\tconst navigation = useNavigation()\n\tconst epicProgress = useEpicProgress()\n\n\tconst isStartingInspector = navigation.formData?.get('intent') === 'inspect'\n\tconst isStoppingInspector =\n\t\tnavigation.formData?.get('intent') === 'stop-inspect'\n\n\tconst progressStatus = {\n\t\tcompleted: 'bg-blue-500',\n\t\tincomplete: 'bg-yellow-500',\n\t}\n\n\treturn (\n\t\t<main className=\"container mx-auto mt-8\">\n\t\t\t<h1 className=\"text-4xl font-bold\">Admin</h1>\n\t\t\t<div className=\"flex flex-col gap-4\">\n\t\t\t\t<nav>\n\t\t\t\t\t<ul className=\"flex gap-3\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Link className=\"underline\" to=\"/\">\n\t\t\t\t\t\t\t\tHome\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Link className=\"underline\" to=\"/diff\">\n\t\t\t\t\t\t\t\tDiff Viewer\n\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</nav>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Progress</h2>\n\t\t\t\t\t{epicProgress ? (\n\t\t\t\t\t\t<ul className=\"flex max-h-72 flex-col gap-2 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t\t{epicProgress.sort(sortProgress).map((progress) => {\n\t\t\t\t\t\t\t\tconst epicUrl = `https://www.epicweb.dev/workshops/${data.workshopSlug}/${progress.epicSectionSlug}/${progress.epicLessonSlug}`\n\t\t\t\t\t\t\t\tconst status = progress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t? 'completed'\n\t\t\t\t\t\t\t\t\t: 'incomplete'\n\t\t\t\t\t\t\t\tconst label = [\n\t\t\t\t\t\t\t\t\t`${progress.epicSectionSlug}/${progress.epicLessonSlug}`,\n\t\t\t\t\t\t\t\t\tprogress.epicCompletedAt\n\t\t\t\t\t\t\t\t\t\t? `(${progress.epicCompletedAt})`\n\t\t\t\t\t\t\t\t\t\t: null,\n\t\t\t\t\t\t\t\t]\n\t\t\t\t\t\t\t\t\t.filter(Boolean)\n\t\t\t\t\t\t\t\t\t.join(' ')\n\t\t\t\t\t\t\t\treturn (\n\t\t\t\t\t\t\t\t\t<li\n\t\t\t\t\t\t\t\t\t\tkey={progress.epicLessonSlug}\n\t\t\t\t\t\t\t\t\t\tclassName=\"flex items-center gap-2\"\n\t\t\t\t\t\t\t\t\t>\n\t\t\t\t\t\t\t\t\t\t<span\n\t\t\t\t\t\t\t\t\t\t\tclassName={`h-3 w-3 rounded-full ${progressStatus[status]}`}\n\t\t\t\t\t\t\t\t\t\t\ttitle={status}\n\t\t\t\t\t\t\t\t\t\t/>\n\t\t\t\t\t\t\t\t\t\t{progress.type === 'unknown' ? (\n\t\t\t\t\t\t\t\t\t\t\t<span className=\"flex items-center gap-1\">\n\t\t\t\t\t\t\t\t\t\t\t\t{label}\n\t\t\t\t\t\t\t\t\t\t\t\t<span className=\"text-red-500\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t<SimpleTooltip content=\"This video is in the workshop on EpicWeb.dev, but not in the local workshop.\">\n\t\t\t\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"Close\" />\n\t\t\t\t\t\t\t\t\t\t\t\t\t</SimpleTooltip>\n\t\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t\t\t<Link to={linkProgress(progress)}>{label}</Link>\n\t\t\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t\t\t<Link to={epicUrl}>\n\t\t\t\t\t\t\t\t\t\t\t<Icon name=\"ExternalLink\"></Icon>\n\t\t\t\t\t\t\t\t\t\t</Link>\n\t\t\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t\t\t)\n\t\t\t\t\t\t\t})}\n\t\t\t\t\t\t</ul>\n\t\t\t\t\t) : (\n\t\t\t\t\t\t<p>No progress data</p>\n\t\t\t\t\t)}\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Commands</h2>\n\t\t\t\t\t<ul className=\"max-h-48 overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"clear-caches\">\n\t\t\t\t\t\t\t\t\tClear local caches\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"clear-data\">\n\t\t\t\t\t\t\t\t\tClear all local data (including auth data)\n\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t</li>\n\t\t\t\t\t\t<li>\n\t\t\t\t\t\t\t{data.inspectorRunning ? (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"stop-inspect\">\n\t\t\t\t\t\t\t\t\t\t{isStartingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Stopping inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Stop inspector'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t<Form method=\"POST\">\n\t\t\t\t\t\t\t\t\t<button name=\"intent\" value=\"inspect\">\n\t\t\t\t\t\t\t\t\t\t{isStoppingInspector\n\t\t\t\t\t\t\t\t\t\t\t? 'Starting inspector...'\n\t\t\t\t\t\t\t\t\t\t\t: 'Start inspector'}\n\t\t\t\t\t\t\t\t\t</button>\n\t\t\t\t\t\t\t\t</Form>\n\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t</li>\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Apps</h2>\n\t\t\t\t\t<ul className=\"max-h-48 list-none overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{data.apps.map((app) => (\n\t\t\t\t\t\t\t<li key={app.name} className=\"flex items-center gap-2 py-1\">\n\t\t\t\t\t\t\t\t{data.processes[app.name] ? (\n\t\t\t\t\t\t\t\t\t<Pinger status=\"running\" />\n\t\t\t\t\t\t\t\t) : (\n\t\t\t\t\t\t\t\t\t<Pinger status=\"stopped\" />\n\t\t\t\t\t\t\t\t)}\n\t\t\t\t\t\t\t\t{app.name}\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Processes</h2>\n\t\t\t\t\t<ul className=\"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{Object.entries(data.processes).map(([key, process]) => (\n\t\t\t\t\t\t\t<li key={key}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{key} - Port: {process.port} - PID {process.pid} -{' '}\n\t\t\t\t\t\t\t\t\t{process.color}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t\t<div>\n\t\t\t\t\t<h2 className=\"text-lg font-bold\">Test Processes</h2>\n\t\t\t\t\t<ul className=\"overflow-y-scroll border-2 p-8 scrollbar-thin scrollbar-thumb-scrollbar\">\n\t\t\t\t\t\t{Object.entries(data.testProcesses).map(([key, process]) => (\n\t\t\t\t\t\t\t<li key={key}>\n\t\t\t\t\t\t\t\t<span>\n\t\t\t\t\t\t\t\t\t{key} - PID {process.pid} - Exit code: {process.exitCode}\n\t\t\t\t\t\t\t\t</span>\n\t\t\t\t\t\t\t</li>\n\t\t\t\t\t\t))}\n\t\t\t\t\t</ul>\n\t\t\t\t</div>\n\t\t\t</div>\n\t\t</main>\n\t)\n}\n\nfunction Pinger({\n\tstatus,\n}: {\n\tstatus: 'running' | 'starting' | 'stopped' | 'taken'\n}) {\n\tconst colors = {\n\t\trunning: {\n\t\t\tpinger: 'bg-green-400',\n\t\t\tcircle: 'bg-green-500',\n\t\t},\n\t\tstarting: {\n\t\t\tpinger: 'bg-sky-400',\n\t\t\tcircle: 'bg-sky-500',\n\t\t},\n\t\tstopped: {\n\t\t\tcircle: 'bg-gray-500',\n\t\t},\n\t\ttaken: {\n\t\t\tpinger: 'bg-red-400',\n\t\t\tcircle: 'bg-red-500',\n\t\t},\n\t}[status]\n\treturn (\n\t\t<span className=\"relative flex h-3 w-3\">\n\t\t\t{colors.pinger ? (\n\t\t\t\t<span\n\t\t\t\t\tclassName={`absolute inline-flex h-full w-full animate-ping rounded-full ${colors.pinger} opacity-75`}\n\t\t\t\t/>\n\t\t\t) : null}\n\t\t\t<span\n\t\t\t\tclassName={`relative inline-flex h-3 w-3 rounded-full ${colors.circle}`}\n\t\t\t/>\n\t\t</span>\n\t)\n}\n"],"names":["handle","getSitemapEntries","meta","matches","rootData","find","m","id","data","title","workshopTitle","sortProgress","a","b","type","linkProgress","progress","exerciseNumber","toString","padStart","stepNumber","AdminLayout","useLoaderData","navigation","useNavigation","epicProgress","useEpicProgress","isStartingInspector","formData","get","isStoppingInspector","progressStatus","completed","incomplete","jsxs","className","children","jsx","Link","to","sort","map","epicUrl","workshopSlug","epicSectionSlug","epicLessonSlug","status","epicCompletedAt","label","filter","Boolean","join","SimpleTooltip","content","Icon","name","Form","method","value","inspectorRunning","apps","app","processes","Pinger","Object","entries","key","process","port","pid","color","testProcesses","exitCode","colors","running","pinger","circle","starting","stopped","taken"],"mappings":"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"}