@epic-web/workshop-app 4.28.6 → 5.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/build/client/assets/{_exerciseNumber-j9COGU-R.js → _exerciseNumber-1JworToC.js} +2 -2
  2. package/build/client/assets/{_exerciseNumber-j9COGU-R.js.map → _exerciseNumber-1JworToC.js.map} +1 -1
  3. package/build/client/assets/{_exerciseNumber_.finished-DDNPeo8x.js → _exerciseNumber_.finished-B4D2ZAmj.js} +2 -2
  4. package/build/client/assets/{_exerciseNumber_.finished-DDNPeo8x.js.map → _exerciseNumber_.finished-B4D2ZAmj.js.map} +1 -1
  5. package/build/client/assets/_layout-CKnDy_9Z.js +2 -0
  6. package/build/client/assets/_layout-CKnDy_9Z.js.map +1 -0
  7. package/build/client/assets/{diff-BEEJhGiC.js → diff-Cvtc-qzL.js} +2 -2
  8. package/build/client/assets/{diff-BEEJhGiC.js.map → diff-Cvtc-qzL.js.map} +1 -1
  9. package/build/client/assets/{diff-BXHLJqTK.js → diff-jgZ_RGra.js} +2 -2
  10. package/build/client/assets/{diff-BXHLJqTK.js.map → diff-jgZ_RGra.js.map} +1 -1
  11. package/build/client/assets/{epic-video-DZzPuXR8.js → epic-video-yrWoJVFy.js} +122 -122
  12. package/build/client/assets/{epic-video-DZzPuXR8.js.map → epic-video-yrWoJVFy.js.map} +1 -1
  13. package/build/client/assets/{finished-Dop_5v80.js → finished-Ct6I1SZV.js} +2 -2
  14. package/build/client/assets/{finished-Dop_5v80.js.map → finished-Ct6I1SZV.js.map} +1 -1
  15. package/build/client/assets/{index-ZZCxObNp.js → index-Ccssehd9.js} +2 -2
  16. package/build/client/assets/{index-ZZCxObNp.js.map → index-Ccssehd9.js.map} +1 -1
  17. package/build/client/assets/{index-D-l_qaLC.js → index-R-sUGQfT.js} +2 -2
  18. package/build/client/assets/{index-D-l_qaLC.js.map → index-R-sUGQfT.js.map} +1 -1
  19. package/build/client/assets/{manifest-1d60a768.js → manifest-f5f44d87.js} +1 -1
  20. package/build/client/assets/{mdx-DwC5Oacq.js → mdx-CpyquP9i.js} +2 -2
  21. package/build/client/assets/{mdx-DwC5Oacq.js.map → mdx-CpyquP9i.js.map} +1 -1
  22. package/build/client/assets/misc-CxCgA-_O.js.map +1 -1
  23. package/build/client/assets/{onboarding-DE9gclYS.js → onboarding-B7TLVi2l.js} +2 -2
  24. package/build/client/assets/{onboarding-DE9gclYS.js.map → onboarding-B7TLVi2l.js.map} +1 -1
  25. package/build/client/assets/{root-BOrI36ez.js → root-9wVBEzOq.js} +2 -2
  26. package/build/client/assets/{root-BOrI36ez.js.map → root-9wVBEzOq.js.map} +1 -1
  27. package/build/client/assets/set-playground-DW0yVaNn.js.map +1 -1
  28. package/build/client/assets/tailwind-B9pSujyx.css +1 -0
  29. package/build/client/assets/{test-N2HloCnX.js → test-DbZkv25C.js} +2 -2
  30. package/build/client/assets/{test-N2HloCnX.js.map → test-DbZkv25C.js.map} +1 -1
  31. package/build/client/assets/{tests-DUg6VXec.js → tests-BR7RFlr5.js} +3 -3
  32. package/build/client/assets/tests-BR7RFlr5.js.map +1 -0
  33. package/build/server/index.js +790 -1280
  34. package/build/server/index.js.map +1 -1
  35. package/package.json +4 -4
  36. package/build/client/assets/_layout-DZWGV4Uf.js +0 -2
  37. package/build/client/assets/_layout-DZWGV4Uf.js.map +0 -1
  38. package/build/client/assets/tailwind-CFrdHbaR.css +0 -1
  39. package/build/client/assets/tests-DUg6VXec.js.map +0 -1
  40. package/build/client/assets/update-mdx-cache-l0sNRNKZ.js +0 -2
  41. package/build/client/assets/update-mdx-cache-l0sNRNKZ.js.map +0 -1
@@ -9,13 +9,12 @@ import path$1 from "node:path";
9
9
  import os from "os";
10
10
  import path from "path";
11
11
  import * as C from "@epic-web/cachified";
12
- import { verboseReporter, cachified as cachified$1 } from "@epic-web/cachified";
12
+ import { verboseReporter } from "@epic-web/cachified";
13
13
  import { remember } from "@epic-web/remember";
14
14
  import fsExtra from "fs-extra";
15
15
  import { LRUCache } from "lru-cache";
16
16
  import md5 from "md5-hex";
17
- import * as z from "zod";
18
- import { z as z$1 } from "zod";
17
+ import { z } from "zod";
19
18
  import fs from "node:fs";
20
19
  import "@total-typescript/ts-reset";
21
20
  import { execa } from "execa";
@@ -31,8 +30,6 @@ import remarkAutolinkHeadings from "remark-autolink-headings";
31
30
  import emoji from "remark-emoji";
32
31
  import gfm from "remark-gfm";
33
32
  import { visit } from "unist-util-visit";
34
- import { createProcessor } from "@mdx-js/mdx";
35
- import { removePosition } from "unist-util-remove-position";
36
33
  import child_process, { spawn } from "child_process";
37
34
  import net from "node:net";
38
35
  import chalk from "chalk";
@@ -219,40 +216,16 @@ const diffFilesCache = makeSingletonCache("DiffFilesCache");
219
216
  const compiledMarkdownCache = makeSingletonCache(
220
217
  "CompiledMarkdownCache"
221
218
  );
222
- const embeddedFilesCache = makeSingletonCache("EmbeddedFilesCache");
223
219
  const compiledCodeCache = makeSingletonCache("CompiledCodeCache");
224
220
  const ogCache = makeSingletonCache("OgCache");
225
- const cacheDir$1 = path.join(os.homedir(), ".epicshop", "cache");
226
- const fsCache = {
227
- name: "Filesystem cache",
228
- async get(key) {
229
- try {
230
- const filePath = path.join(cacheDir$1, md5(key));
231
- const data = await fsExtra.readJSON(filePath);
232
- if (data.entry) return data.entry;
233
- return null;
234
- } catch (error) {
235
- if (error instanceof Error && "code" in error && error.code === "ENOENT") {
236
- return null;
237
- }
238
- throw error;
239
- }
240
- },
241
- async set(key, entry2) {
242
- const filePath = path.join(cacheDir$1, md5(key));
243
- await fsExtra.ensureDir(path.dirname(filePath));
244
- await fsExtra.writeJSON(filePath, { key, entry: entry2 });
245
- },
246
- async delete(key) {
247
- const filePath = path.join(cacheDir$1, md5(key));
248
- await fsExtra.remove(filePath);
249
- }
250
- };
221
+ const compiledInstructionMarkdownCache = makeSingletonFsCache("CompiledInstructionMarkdownCache");
222
+ const cacheDir = path.join(os.homedir(), ".epicshop", "cache");
223
+ const fsCache = makeSingletonFsCache("FsCache");
251
224
  async function getAllFileCacheEntries() {
252
- const files = await fsExtra.readdir(cacheDir$1);
225
+ const files = await fsExtra.readdir(cacheDir);
253
226
  const entries = await Promise.all(
254
227
  files.map(async (file) => {
255
- const filePath = path.join(cacheDir$1, file);
228
+ const filePath = path.join(cacheDir, file);
256
229
  const data = await fsExtra.readJSON(filePath);
257
230
  return data;
258
231
  }).filter(Boolean)
@@ -262,11 +235,11 @@ async function getAllFileCacheEntries() {
262
235
  async function deleteCache() {
263
236
  if (process.env.EPICSHOP_DEPLOYED) return null;
264
237
  try {
265
- if (await fsExtra.exists(cacheDir$1)) {
266
- await fsExtra.remove(cacheDir$1);
238
+ if (await fsExtra.exists(cacheDir)) {
239
+ await fsExtra.remove(cacheDir);
267
240
  }
268
241
  } catch (error) {
269
- console.error(`Error deleting the cache in ${cacheDir$1}`, error);
242
+ console.error(`Error deleting the cache in ${cacheDir}`, error);
270
243
  }
271
244
  }
272
245
  function makeSingletonCache(name) {
@@ -290,6 +263,37 @@ function makeSingletonCache(name) {
290
263
  return lru;
291
264
  });
292
265
  }
266
+ function makeSingletonFsCache(name) {
267
+ return remember(name, () => {
268
+ const cacheDir2 = path.join(os.homedir(), ".epicshop", "cache", name);
269
+ const fsCache2 = {
270
+ name: `Filesystem cache (${name})`,
271
+ async get(key) {
272
+ try {
273
+ const filePath = path.join(cacheDir2, md5(key));
274
+ const data = await fsExtra.readJSON(filePath);
275
+ if (data.entry) return data.entry;
276
+ return null;
277
+ } catch (error) {
278
+ if (error instanceof Error && "code" in error && error.code === "ENOENT") {
279
+ return null;
280
+ }
281
+ throw error;
282
+ }
283
+ },
284
+ async set(key, entry2) {
285
+ const filePath = path.join(cacheDir2, md5(key));
286
+ await fsExtra.ensureDir(path.dirname(filePath));
287
+ await fsExtra.writeJSON(filePath, { key, entry: entry2 });
288
+ },
289
+ async delete(key) {
290
+ const filePath = path.join(cacheDir2, md5(key));
291
+ await fsExtra.remove(filePath);
292
+ }
293
+ };
294
+ return fsCache2;
295
+ });
296
+ }
293
297
  async function cachified({
294
298
  request,
295
299
  timings,
@@ -330,42 +334,42 @@ async function shouldForceFresh({
330
334
  if (!key) return false;
331
335
  return fresh.split(",").includes(key);
332
336
  }
333
- const DiscordMemberSchema = z$1.object({
334
- avatarURL: z$1.string().nullable().optional(),
335
- displayName: z$1.string(),
336
- id: z$1.string()
337
+ const DiscordMemberSchema = z.object({
338
+ avatarURL: z.string().nullable().optional(),
339
+ displayName: z.string(),
340
+ id: z.string()
337
341
  });
338
- const TokenSetSchema = z$1.object({
339
- access_token: z$1.string(),
340
- token_type: z$1.string(),
341
- scope: z$1.string()
342
+ const TokenSetSchema = z.object({
343
+ access_token: z.string(),
344
+ token_type: z.string(),
345
+ scope: z.string()
342
346
  });
343
- const PlayerPreferencesSchema = z$1.object({
344
- volumeRate: z$1.number().optional(),
345
- playbackRate: z$1.number().optional(),
346
- autoplay: z$1.boolean().optional(),
347
- subtitle: z$1.object({
348
- id: z$1.string().nullable().default(null),
349
- mode: z$1.literal("disabled").or(z$1.literal("hidden")).or(z$1.literal("showing")).nullable().default("disabled")
347
+ const PlayerPreferencesSchema = z.object({
348
+ volumeRate: z.number().optional(),
349
+ playbackRate: z.number().optional(),
350
+ autoplay: z.boolean().optional(),
351
+ subtitle: z.object({
352
+ id: z.string().nullable().default(null),
353
+ mode: z.literal("disabled").or(z.literal("hidden")).or(z.literal("showing")).nullable().default("disabled")
350
354
  }).optional().default({}),
351
- muted: z$1.boolean().optional(),
352
- theater: z$1.boolean().optional(),
353
- defaultView: z$1.string().optional(),
354
- activeSidebarTab: z$1.number().optional()
355
+ muted: z.boolean().optional(),
356
+ theater: z.boolean().optional(),
357
+ defaultView: z.string().optional(),
358
+ activeSidebarTab: z.number().optional()
355
359
  }).optional().default({});
356
- const PresencePreferencesSchema = z$1.object({
357
- optOut: z$1.boolean()
360
+ const PresencePreferencesSchema = z.object({
361
+ optOut: z.boolean()
358
362
  }).optional().default({ optOut: false });
359
- const AuthInfoSchema = z$1.object({
363
+ const AuthInfoSchema = z.object({
360
364
  tokenSet: TokenSetSchema,
361
- email: z$1.string(),
362
- name: z$1.string().nullable().optional()
365
+ email: z.string(),
366
+ name: z.string().nullable().optional()
363
367
  }).transform((d) => ({ ...d, id: md5(d.email) }));
364
- const DataSchema = z$1.object({
365
- onboarding: z$1.object({
366
- tourVideosWatched: z$1.array(z$1.string()).default([])
368
+ const DataSchema = z.object({
369
+ onboarding: z.object({
370
+ tourVideosWatched: z.array(z.string()).default([])
367
371
  }).passthrough().optional().default({ tourVideosWatched: [] }),
368
- preferences: z$1.object({
372
+ preferences: z.object({
369
373
  player: PlayerPreferencesSchema,
370
374
  presence: PresencePreferencesSchema
371
375
  }).optional().default({}),
@@ -517,30 +521,30 @@ async function markOnboardingVideoWatched(videoUrl) {
517
521
  }
518
522
  const partykitRoom = "epic-web-presence";
519
523
  const partykitBaseUrl = `https://epic-web-presence.kentcdodds.partykit.dev/parties/main/${partykitRoom}`;
520
- const UserSchema = z$1.object({
521
- id: z$1.string(),
522
- avatarUrl: z$1.string().nullable().optional(),
523
- name: z$1.string().nullable().optional(),
524
- location: z$1.object({
525
- workshopTitle: z$1.string().nullable().optional(),
526
- origin: z$1.string().nullable().optional(),
527
- exercise: z$1.object({
528
- type: z$1.union([z$1.literal("problem"), z$1.literal("solution")]).nullable().optional(),
529
- exerciseNumber: z$1.number().nullable().optional(),
530
- stepNumber: z$1.number().nullable().optional()
524
+ const UserSchema = z.object({
525
+ id: z.string(),
526
+ avatarUrl: z.string().nullable().optional(),
527
+ name: z.string().nullable().optional(),
528
+ location: z.object({
529
+ workshopTitle: z.string().nullable().optional(),
530
+ origin: z.string().nullable().optional(),
531
+ exercise: z.object({
532
+ type: z.union([z.literal("problem"), z.literal("solution")]).nullable().optional(),
533
+ exerciseNumber: z.number().nullable().optional(),
534
+ stepNumber: z.number().nullable().optional()
531
535
  }).nullable().optional()
532
536
  }).nullable().optional()
533
537
  });
534
- const MessageSchema = z$1.object({
535
- type: z$1.literal("remove-user"),
536
- payload: z$1.object({ id: z$1.string() })
537
- }).or(z$1.object({ type: z$1.literal("add-user"), payload: UserSchema })).or(
538
- z$1.object({
539
- type: z$1.literal("presence"),
540
- payload: z$1.object({ users: z$1.array(UserSchema) })
538
+ const MessageSchema = z.object({
539
+ type: z.literal("remove-user"),
540
+ payload: z.object({ id: z.string() })
541
+ }).or(z.object({ type: z.literal("add-user"), payload: UserSchema })).or(
542
+ z.object({
543
+ type: z.literal("presence"),
544
+ payload: z.object({ users: z.array(UserSchema) })
541
545
  })
542
546
  );
543
- const PresenceSchema = z$1.object({ users: z$1.array(UserSchema) });
547
+ const PresenceSchema = z.object({ users: z.array(UserSchema) });
544
548
  const presenceCache = makeSingletonCache("PresenceCache");
545
549
  async function getPresentUsers(user, { timings, request } = {}) {
546
550
  return cachified({
@@ -550,7 +554,7 @@ async function getPresentUsers(user, { timings, request } = {}) {
550
554
  request,
551
555
  ttl: 1e3 * 60 * 5,
552
556
  swr: 1e3 * 60 * 60 * 24,
553
- checkValue: z$1.array(UserSchema),
557
+ checkValue: z.array(UserSchema),
554
558
  async getFreshValue(context) {
555
559
  try {
556
560
  const response = await Promise.race([
@@ -594,638 +598,59 @@ function uniqueUsers(users) {
594
598
  return true;
595
599
  });
596
600
  }
597
- let watcher = global.__change_tracker_watcher__;
598
- function getWatcher() {
599
- if (process.env.EPICSHOP_DEPLOYED ?? process.env.EPICSHOP_ENABLE_WATCHER !== "true") {
600
- return null;
601
- }
602
- if (watcher) return watcher;
603
- const workshopRoot2 = process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd();
604
- watcher = chokidar.watch(workshopRoot2, {
605
- ignoreInitial: true,
606
- ignored: [
607
- "**/.git/**",
608
- "**/node_modules/**",
609
- "**/build/**",
610
- "**/public/build/**",
611
- "**/playwright-report/**",
612
- "**/dist/**",
613
- "**/.cache/**"
614
- ]
615
- });
616
- global.__change_tracker_watcher__ = watcher;
617
- return watcher;
618
- }
619
- function getOptionalWatcher() {
620
- return watcher;
621
- }
622
- (_a = global.__change_tracker_close_with_grace_return__) == null ? void 0 : _a.uninstall();
623
- global.__change_tracker_close_with_grace_return__ = closeWithGrace(
624
- () => watcher == null ? void 0 : watcher.close()
625
- );
626
- const APP_TYPES = ["problem", "solution", "playground"];
627
- const safePath$1 = (s) => s.replace(/\\/g, "/");
628
- const REG_EXP = /^(?:\d+(?:-\d+)?,)*\d+(?:-\d+)?$/;
629
- const isValidRangeFormat = (value) => value ? REG_EXP.test(value) : true;
630
- const transformRange = (value) => value == null ? void 0 : value.split(",").map((range) => {
631
- const [start, end] = range.split("-").map(Number);
632
- return [start, end ?? start];
633
- });
634
- const isRangeBounded = (range, ctx, lines) => {
635
- if (!lines || !Array.isArray(range)) return;
636
- if (range.flat().some((r) => r < 1 || r > lines)) {
637
- ctx.addIssue({
638
- code: z.ZodIssueCode.custom,
639
- message: `Range must be between 1 and ${lines}`
640
- });
641
- }
642
- };
643
- const isRangeInOrder = (range) => Array.isArray(range) ? range.every(([a, b]) => !isNaN(Number(a)) && !isNaN(Number(b)) && b >= a) : true;
644
- const isRangesNonOverlapping = (range) => {
645
- if (!Array.isArray(range)) return true;
646
- return range.every(([a], i) => {
647
- var _a2;
648
- return i === 0 || (((_a2 = range[i - 1]) == null ? void 0 : _a2[1]) ?? 0) < a;
649
- });
650
- };
651
- let fileContentCache = /* @__PURE__ */ new Map();
652
- async function getFileContent(filePath) {
653
- if (fileContentCache.has(filePath)) {
654
- return fileContentCache.get(filePath);
655
- }
656
- try {
657
- const content = await fs.promises.readFile(filePath, "utf-8");
658
- const fileContent = content.split("\n");
659
- fileContentCache.set(filePath, fileContent);
660
- return fileContent;
661
- } catch {
662
- console.warn(
663
- `@epic-web/workshop-app - invalid CodeFile.
664
- Could not read file: ${filePath}
665
- `
666
- );
667
- }
668
- }
669
- async function validateProps(props, appDir2) {
670
- let validRange;
671
- let linesCount = 0;
672
- const BooleanSchema = z.nullable(z.string()).optional().refine(
673
- (v) => ["true", "false", null, void 0].includes(v),
674
- 'optional boolean key can be "true", "false", null or undefined'
675
- ).transform((v) => v === null || Boolean(v));
676
- const RangeSchema = z.string().optional().refine(isValidRangeFormat, "Invalid range format").transform(transformRange).superRefine((val, ctx) => isRangeBounded(val, ctx, linesCount)).refine(isRangeInOrder, "Range must be in order low-high");
677
- const inputSchema = z.object({
678
- file: z.string().nonempty().transform(async (file, ctx) => {
679
- const fullPath = path$1.join(appDir2, file);
680
- const content = await getFileContent(fullPath);
681
- if (!content) {
682
- ctx.addIssue({
683
- code: z.ZodIssueCode.custom,
684
- message: `Could not read file`,
685
- fatal: true
686
- });
687
- return z.NEVER;
688
- }
689
- linesCount = content.length;
690
- return {
691
- fullPath: safePath$1(fullPath),
692
- filePath: safePath$1(file),
693
- content
694
- };
695
- }),
696
- range: RangeSchema.refine((range) => {
697
- const isValid = isRangesNonOverlapping(range);
698
- validRange = isValid ? range : void 0;
699
- return isValid;
700
- }, "Ranges must not overlap"),
701
- highlight: RangeSchema.refine((highlight) => {
702
- if (!Array.isArray(highlight) || !Array.isArray(validRange)) {
703
- return z.NEVER;
704
- }
705
- return highlight.every(
706
- ([hStart, hEnd]) => validRange == null ? void 0 : validRange.some(
707
- ([rStart, rEnd]) => hStart >= rStart && hEnd <= rEnd
708
- )
709
- );
710
- }, "Highlight range must be within defined range").transform(() => props.highlight).optional(),
711
- nonumber: BooleanSchema,
712
- nocopy: BooleanSchema,
713
- buttons: z.string().optional().transform(
714
- (str) => str ? str.split(",") : []
715
- ).refine((arr) => arr.every((item) => APP_TYPES.includes(item)), {
716
- message: `Buttons can only be any of ${APP_TYPES.join(",")}`
717
- })
718
- }).strict();
719
- return inputSchema.safeParseAsync(props);
720
- }
721
- async function createErrorNotification(node, errors, mdxFile, appType) {
722
- var _a2, _b;
723
- const filename = path$1.basename(mdxFile);
724
- const startLine = (_a2 = node.position) == null ? void 0 : _a2.start.line;
725
- const endLine = (_b = node.position) == null ? void 0 : _b.end.line;
726
- const codeFence = async () => {
727
- if (startLine && endLine) {
728
- const contentStr = await getFileContent(mdxFile);
729
- const content = contentStr == null ? void 0 : contentStr.slice(startLine - 1, endLine).join("\n");
730
- if (content) {
731
- return `
732
- \`\`\`tsx filename=${filename} start=${startLine} nocopy
733
- ${content}
734
- \`\`\``.trim();
735
- }
736
- }
737
- return "";
738
- };
739
- const mdxSource = `
740
- <CodeFileNotification variant="error" file="${filename}" line="${startLine}" type="${appType}">
741
- <callout-danger class="notification">
742
- <div className="title">CodeFile Error: invalid input</div>
743
- ${errors.map((error) => `<div>${error}</div>`).join("")}
744
- ${await codeFence()}
745
- </callout-danger>
746
- </CodeFileNotification>`;
747
- return mdxToMdast(mdxSource);
748
- }
749
- function stripIndent(string) {
750
- const match = string.match(/^[ \t]*(?=\S)/gm);
751
- const indent = (match == null ? void 0 : match.reduce((r, a) => Math.min(r, a.length), Infinity)) ?? 0;
752
- if (indent === 0) {
753
- return string;
754
- }
755
- const regex = new RegExp(`^[ \\t]{${indent}}`, "gm");
756
- return string.replace(regex, "");
757
- }
758
- function mdxToMdast(mdx) {
759
- const processor = createProcessor();
760
- const mdast = processor.parse(mdx.trim());
761
- removePosition(mdast, { force: true });
762
- return mdast.type === "root" ? mdast.children : [mdast];
763
- }
764
- function remarkCodeFile(data) {
765
- fileContentCache = /* @__PURE__ */ new Map();
766
- const mdxFile = data.mdxFile;
767
- const appDir2 = path$1.dirname(mdxFile);
768
- const appType = mdxFile.includes("problem") ? "problem" : mdxFile.includes("solution") ? "solution" : "other";
769
- async function replaceCodeFileNode({
770
- node,
771
- parent
772
- }) {
773
- var _a2, _b;
774
- if (!parent) {
775
- console.warn(
776
- "Unexpected error: replaceCodeFileNode called without a Parent"
777
- );
778
- return;
779
- }
780
- const index = parent.children.indexOf(node);
781
- if (index === -1) {
782
- console.warn(
783
- "Unexpected error: replaceCodeFileNode could not find node index in Parent"
784
- );
785
- return;
786
- }
787
- const attributes = node.attributes;
788
- const props = {};
789
- for (const { name, value } of attributes) {
790
- props[name] = value;
791
- }
792
- const result = await validateProps(props, appDir2);
793
- if (!result.success) {
794
- const errors = result.error.issues.map(
795
- ({ message, path: path2 }) => path2[0] ? `${message}: ${path2[0]}="${props[path2[0]]}"` : message
796
- );
797
- const notification = await createErrorNotification(
798
- node,
799
- errors,
800
- mdxFile,
801
- appType
802
- );
803
- parent.children.splice(index, 1, ...notification);
804
- data.embeddedFiles.set("invalid input", {
805
- error: true,
806
- file: props.file,
807
- hash: "",
808
- line: ((_a2 = node.position) == null ? void 0 : _a2.start.line) ?? 1
809
- });
810
- return;
811
- }
812
- const {
813
- file: { content, filePath, fullPath },
814
- highlight,
815
- range
816
- } = result.data;
817
- const language = path$1.extname(filePath).substring(1);
818
- const meta2 = [`filename=${filePath}`];
819
- Object.entries(result.data).forEach(
820
- ([key, val]) => typeof val === "boolean" && val && meta2.push(`${key}=true`)
821
- );
822
- if (result.data.buttons) {
823
- meta2.push(`buttons=${result.data.buttons.join(",")}`);
824
- meta2.push(`type=${appType}`);
825
- meta2.push(`fullpath=${fullPath}`);
826
- meta2.push(`sep=${path$1.sep}`);
827
- }
828
- if (highlight == null ? void 0 : highlight.length) {
829
- meta2.push(`lines=${highlight}`);
830
- }
831
- const fileSections = (range == null ? void 0 : range.length) ? range : [[1, content.length]];
832
- const rangesContent = [];
833
- const preNodes = [];
834
- for (const [start, end] of fileSections) {
835
- const rangeContent = stripIndent(
836
- content.slice(start ? start - 1 : 0, end).join("\n")
837
- );
838
- rangesContent.push(rangeContent);
839
- const mdxSource = `
840
- \`\`\`${language} ${meta2.concat(`start=${start}`).join(" ")}
841
- ${rangeContent}
842
- \`\`\``;
843
- preNodes.push(...mdxToMdast(mdxSource));
844
- }
845
- const embeddedKey = md5(fullPath + JSON.stringify(range));
846
- const contentHash = md5(rangesContent.join(","));
847
- const newData = {
848
- file: fullPath,
849
- hash: contentHash
850
- };
851
- const cachedData = data.cachedEmbeddedFiles.get(embeddedKey);
852
- if (cachedData && // If a warning existed previously and its hash matched the current hash,
853
- // then the changes were reverted and the warning will be remove
854
- ((cachedData.warning && cachedData.warning !== contentHash) ?? (!cachedData.warning && cachedData.hash !== contentHash))) {
855
- newData.warning = cachedData.warning ?? cachedData.hash;
856
- const startLine = ((_b = node.position) == null ? void 0 : _b.start.line) ?? 1;
857
- newData.line = startLine;
858
- const mdxFilename = path$1.basename(mdxFile);
859
- const filename = path$1.basename(filePath);
860
- const warning = `
861
- <CodeFileNotification variant="warning" file="${mdxFilename}" line="${startLine}" type="${appType}"
862
- cacheLocation="${data.cacheLocation}" embeddedKey="${embeddedKey}">
863
- <callout-warning class="notification">
864
- <div className="title">CodeFile Warning:</div>
865
- <div>file ${filename} content was changed, review 'range' and 'highlight' inputs</div>
866
- </callout-warning>
867
- </CodeFileNotification>`;
868
- preNodes.unshift(...mdxToMdast(warning));
869
- }
870
- data.embeddedFiles.set(embeddedKey, newData);
871
- parent.children.splice(index, 1, ...preNodes);
872
- }
873
- return async function codeFileTransformer(tree) {
874
- const codeFiles = [];
875
- const filter = { type: "mdxJsxFlowElement", name: "CodeFile" };
876
- visit(tree, filter, (node, _index, parent) => {
877
- codeFiles.push({ node, parent });
878
- });
879
- for (const props of codeFiles) {
880
- await replaceCodeFileNode(props);
881
- }
882
- fileContentCache = /* @__PURE__ */ new Map();
883
- };
884
- }
885
- const cacheDir = path.join(
886
- process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd(),
887
- "./node_modules/.cache/compile-mdx"
888
- );
889
- function trimCodeBlocks() {
890
- return async function transformer(tree) {
891
- visit(tree, "element", (preNode) => {
892
- if (preNode.tagName !== "pre" || !preNode.children.length) {
893
- return;
894
- }
895
- const codeNode = preNode.children[0];
896
- if (!codeNode || codeNode.type !== "element" || codeNode.tagName !== "code") {
897
- return;
898
- }
899
- const [codeStringNode] = codeNode.children;
900
- if (!codeStringNode) return;
901
- if (codeStringNode.type !== "text") {
902
- console.warn(
903
- `trimCodeBlocks: Unexpected: codeStringNode type is not "text": ${codeStringNode.type}`
904
- );
905
- return;
906
- }
907
- codeStringNode.value = codeStringNode.value.trimEnd();
908
- });
909
- };
910
- }
911
- function removePreContainerDivs() {
912
- return async function preContainerDivsTransformer(tree) {
913
- visit(
914
- tree,
915
- { type: "element", tagName: "pre" },
916
- function visitor(node, index, parent) {
917
- if ((parent == null ? void 0 : parent.type) !== "element") return;
918
- if (parent.tagName !== "div") return;
919
- if (parent.children.length !== 1 && index === 0) return;
920
- Object.assign(parent, node);
921
- }
922
- );
923
- };
924
- }
925
- const rehypePlugins = [
926
- trimCodeBlocks,
927
- remarkCodeBlocksShiki,
928
- removePreContainerDivs
929
- ];
930
- function checkFileExists$1(file) {
931
- return fs$1.promises.access(file, fs$1.constants.F_OK).then(
932
- () => true,
933
- () => false
934
- );
935
- }
936
- const verboseLog = process.env.EPICSHOP_VERBOSE_LOG === "true" ? console.log : () => {
937
- };
938
- function validateEmbeddedFiles(embeddedFiles, lastCompiledTime) {
939
- if (process.env.NODE_ENV !== "development") return Promise.resolve(true);
940
- return Promise.all(
941
- Array.from(embeddedFiles).map(async ({ file }) => {
942
- const stat = await fs$1.promises.stat(file).catch(() => ({ mtimeMs: 0 }));
943
- return lastCompiledTime > stat.mtimeMs || Promise.reject();
944
- })
945
- ).then(
946
- () => true,
947
- () => false
948
- );
949
- }
950
- async function compileMdx(file, { request, forceFresh } = {}) {
951
- var _a2;
952
- if (!await checkFileExists$1(file)) {
953
- throw new Error(`File does not exist: ${file}`);
954
- }
955
- let cachedEmbeddedFiles = /* @__PURE__ */ new Map();
956
- const stat = await fs$1.promises.stat(file);
957
- const cacheLocation = path.join(cacheDir, `${md5(file)}.json`);
958
- const requireFresh = await shouldForceFresh({
959
- forceFresh,
960
- request,
961
- key: cacheLocation
962
- });
963
- if (!requireFresh && await checkFileExists$1(cacheLocation)) {
964
- try {
965
- const cached = JSON.parse(
966
- await fs$1.promises.readFile(cacheLocation, "utf-8")
967
- );
968
- cachedEmbeddedFiles = new Map(
969
- Object.entries(cached.value.embeddedFiles ?? {})
970
- );
971
- const compiledTime = cached.value.compiledTime ?? 0;
972
- const warningCancled = process.env.NODE_ENV === "development" ? ((_a2 = cached == null ? void 0 : cached.value) == null ? void 0 : _a2.warningCancled) ?? false : false;
973
- if (compiledTime > stat.mtimeMs && !warningCancled && await validateEmbeddedFiles(
974
- cachedEmbeddedFiles.values(),
975
- compiledTime
976
- )) {
977
- return cached.value;
978
- }
979
- } catch (error) {
980
- console.error(`Error reading cached file: ${cacheLocation}`, error);
981
- void fs$1.promises.unlink(cacheLocation);
982
- }
983
- }
984
- let title = null;
985
- const epicVideoEmbeds = [];
986
- const codeFileData = {
987
- mdxFile: file,
988
- cacheLocation,
989
- cachedEmbeddedFiles,
990
- embeddedFiles: /* @__PURE__ */ new Map()
991
- };
992
- try {
993
- verboseLog(`Compiling ${file}`);
994
- const bundleResult = await queuedBundleMDX({
995
- file,
996
- cwd: path.dirname(file),
997
- mdxOptions(options) {
998
- options.remarkPlugins = [
999
- ...options.remarkPlugins ?? [],
1000
- [remarkAutolinkHeadings, { behavior: "wrap" }],
1001
- gfm,
1002
- () => (tree) => {
1003
- visit(tree, "heading", (node) => {
1004
- if (title) return;
1005
- if (node.depth === 1) {
1006
- visit(node, "text", (textNode) => {
1007
- title = textNode.value.trim();
1008
- });
1009
- }
1010
- });
1011
- title = title ? title.replace(/^\d+\. /, "").trim() : null;
1012
- },
1013
- () => (tree) => {
1014
- visit(tree, "mdxJsxFlowElement", (jsxEl) => {
1015
- if (jsxEl.name !== "EpicVideo") return;
1016
- const urlAttr = jsxEl.attributes.find(
1017
- (a) => a.type === "mdxJsxAttribute" && a.name === "url"
1018
- );
1019
- if (!urlAttr) return;
1020
- let url = urlAttr.value;
1021
- if (typeof url !== "string") return;
1022
- if (url.endsWith("/")) url = url.slice(0, -1);
1023
- epicVideoEmbeds.push(url);
1024
- });
1025
- },
1026
- () => remarkCodeFile(codeFileData),
1027
- emoji
1028
- ];
1029
- options.rehypePlugins = [
1030
- ...options.rehypePlugins ?? [],
1031
- ...rehypePlugins
1032
- ];
1033
- options.mdxExtensions = [".mdx", ".md"];
1034
- options.format = "mdx";
1035
- options.development = false;
1036
- return options;
1037
- }
1038
- });
1039
- if (!bundleResult) throw new Error(`Timeout for file: ${file}`);
1040
- const result = { code: bundleResult.code, title, epicVideoEmbeds };
1041
- await fsExtra.ensureDir(cacheDir);
1042
- await fs$1.promises.writeFile(
1043
- cacheLocation,
1044
- JSON.stringify({
1045
- value: {
1046
- ...result,
1047
- compiledTime: Date.now(),
1048
- embeddedFiles: codeFileData.embeddedFiles.size ? Object.fromEntries(codeFileData.embeddedFiles) : void 0
1049
- }
1050
- })
1051
- );
1052
- await updateEmbeddedFilesCache(codeFileData);
1053
- return result;
1054
- } catch (error) {
1055
- console.error(`Compilation error for file: `, file, error);
1056
- throw error;
1057
- } finally {
1058
- verboseLog(`Successfully compiled ${file}`);
1059
- }
1060
- }
1061
- async function compileMarkdownString(markdownString) {
1062
- return cachified$1({
1063
- key: markdownString,
1064
- cache: compiledMarkdownCache,
1065
- ttl: 1e3 * 60 * 60 * 24,
1066
- getFreshValue: async () => {
1067
- try {
1068
- verboseLog(`Compiling string`, markdownString);
1069
- const result = await queuedBundleMDX({
1070
- source: markdownString,
1071
- mdxOptions(options) {
1072
- options.rehypePlugins = [
1073
- ...options.rehypePlugins ?? [],
1074
- ...rehypePlugins
1075
- ];
1076
- options.development = false;
1077
- return options;
1078
- }
1079
- });
1080
- if (!result) throw new Error(`Timed out compiling markdown string`);
1081
- return result.code;
1082
- } catch (error) {
1083
- console.error(`Compilation error for code: `, markdownString, error);
1084
- throw error;
1085
- } finally {
1086
- verboseLog(`Successfully compiled string`, markdownString);
1087
- }
1088
- }
1089
- });
1090
- }
1091
- const modifiedEmbeddedFilesTime = remember(
1092
- "modified_embedded_files_time",
1093
- () => /* @__PURE__ */ new Map()
1094
- );
1095
- const EMBEDDED_FILES_CACHE_KEY = "embeddedFilesCache";
1096
- async function updateEmbeddedFilesCache({
1097
- mdxFile,
1098
- embeddedFiles
1099
- }) {
1100
- var _a2;
1101
- if (mdxFile.includes("playground")) return;
1102
- let cachedList = await getEmbeddedFilesCache();
1103
- const hash = cachedList ? md5(JSON.stringify(cachedList)) : null;
1104
- if (cachedList) {
1105
- for (const [key, value] of Object.entries(cachedList)) {
1106
- cachedList[key] = value.filter((item) => item !== mdxFile);
1107
- if (((_a2 = cachedList[key]) == null ? void 0 : _a2.length) === 0) {
1108
- delete cachedList[key];
1109
- }
1110
- }
1111
- }
1112
- if (embeddedFiles.size) {
1113
- if (!cachedList) {
1114
- cachedList = {};
1115
- }
1116
- const files = Array.from(
1117
- new Set(Array.from(embeddedFiles.values()).map(({ file }) => file))
1118
- ).sort();
1119
- for (const file of files) {
1120
- cachedList[file] = [...cachedList[file] ?? [], mdxFile];
1121
- }
1122
- }
1123
- if (cachedList && hash !== md5(JSON.stringify(cachedList))) {
1124
- await fsExtra.ensureDir(cacheDir);
1125
- const embeddedFilesLocation = path.join(cacheDir, "embeddedFiles.json");
1126
- modifiedEmbeddedFilesTime.set(EMBEDDED_FILES_CACHE_KEY, Date.now());
1127
- await fs$1.promises.writeFile(
1128
- embeddedFilesLocation,
1129
- JSON.stringify({ ...cachedList })
1130
- );
1131
- }
1132
- }
1133
- async function getEmbeddedFilesCache() {
1134
- const key = EMBEDDED_FILES_CACHE_KEY;
1135
- function getForceFresh2(cacheEntry) {
1136
- if (!cacheEntry) return true;
1137
- const latestModifiedTime = modifiedEmbeddedFilesTime.get(key);
1138
- if (!latestModifiedTime) return void 0;
1139
- return latestModifiedTime > cacheEntry.metadata.createdTime ? true : void 0;
1140
- }
1141
- return cachified$1({
1142
- key,
1143
- cache: embeddedFilesCache,
1144
- ttl: 1e3 * 60 * 60 * 24,
1145
- forceFresh: getForceFresh2(embeddedFilesCache.get(key)),
1146
- getFreshValue: async () => {
1147
- try {
1148
- const embeddedFilesLocation = path.join(cacheDir, "embeddedFiles.json");
1149
- if (await checkFileExists$1(embeddedFilesLocation)) {
1150
- return JSON.parse(
1151
- await fs$1.promises.readFile(embeddedFilesLocation, "utf-8")
1152
- );
1153
- }
1154
- } catch {
1155
- console.error(`Unable to read 'embeddedFiles.json' from: `, cacheDir);
1156
- }
1157
- return void 0;
1158
- }
1159
- });
1160
- }
1161
- let _queue = null;
1162
- async function getQueue() {
1163
- if (_queue) return _queue;
1164
- _queue = new PQueue({
1165
- concurrency: 1,
1166
- throwOnTimeout: true,
1167
- timeout: 1e3 * 60
1168
- });
1169
- return _queue;
1170
- }
1171
- async function queuedBundleMDX(...args) {
1172
- const queue = await getQueue();
1173
- const result = await queue.add(() => bundleMDX(...args));
1174
- return result;
1175
- }
1176
601
  const workshopRoot$1 = process.env.EPICSHOP_CONTEXT_CWD ?? process.cwd();
1177
- const StackBlitzConfigSchema = z$1.object({
602
+ const StackBlitzConfigSchema = z.object({
1178
603
  // we default this to `${exerciseTitle} (${type})`
1179
- title: z$1.string().optional(),
604
+ title: z.string().optional(),
1180
605
  // stackblitz defaults this to dev automatically
1181
- startScript: z$1.string().optional(),
606
+ startScript: z.string().optional(),
1182
607
  // if no value is provided, then stackblitz defaults this to whatever
1183
608
  // looks best based on the width of the screen
1184
- view: z$1.union([z$1.literal("editor"), z$1.literal("preview"), z$1.literal("both")]).optional(),
1185
- file: z$1.string().optional()
609
+ view: z.union([z.literal("editor"), z.literal("preview"), z.literal("both")]).optional(),
610
+ file: z.string().optional()
1186
611
  });
1187
- const InstructorSchema = z$1.object({
1188
- name: z$1.string().optional(),
1189
- avatar: z$1.string().optional(),
1190
- "𝕏": z$1.string().optional(),
1191
- xHandle: z$1.string().optional()
612
+ const InstructorSchema = z.object({
613
+ name: z.string().optional(),
614
+ avatar: z.string().optional(),
615
+ "𝕏": z.string().optional(),
616
+ xHandle: z.string().optional()
1192
617
  });
1193
- const WorkshopConfigSchema = z$1.object({
1194
- title: z$1.string(),
1195
- subtitle: z$1.string().optional(),
618
+ const WorkshopConfigSchema = z.object({
619
+ title: z.string(),
620
+ subtitle: z.string().optional(),
1196
621
  instructor: InstructorSchema.optional(),
1197
- epicWorkshopHost: z$1.string().optional(),
1198
- epicWorkshopSlug: z$1.string().optional(),
1199
- product: z$1.object({
1200
- host: z$1.string().default("www.epicweb.dev"),
1201
- displayName: z$1.string().default("EpicWeb.dev"),
1202
- displayNameShort: z$1.string().default("Epic Web"),
1203
- logo: z$1.string().default("/logo.svg"),
1204
- slug: z$1.string().optional(),
1205
- discordChannelId: z$1.string().default("1161045224907341972"),
1206
- discordTags: z$1.array(z$1.string()).optional()
622
+ epicWorkshopHost: z.string().optional(),
623
+ epicWorkshopSlug: z.string().optional(),
624
+ product: z.object({
625
+ host: z.string().default("www.epicweb.dev"),
626
+ displayName: z.string().default("EpicWeb.dev"),
627
+ displayNameShort: z.string().default("Epic Web"),
628
+ logo: z.string().default("/logo.svg"),
629
+ slug: z.string().optional(),
630
+ discordChannelId: z.string().default("1161045224907341972"),
631
+ discordTags: z.array(z.string()).optional()
1207
632
  }).default({}),
1208
- onboardingVideo: z$1.string().default(
633
+ onboardingVideo: z.string().default(
1209
634
  "https://www.epicweb.dev/tips/get-started-with-the-epic-workshop-app"
1210
635
  ),
1211
- githubRepo: z$1.string(),
1212
- githubRoot: z$1.string(),
636
+ githubRepo: z.string(),
637
+ githubRoot: z.string(),
1213
638
  stackBlitzConfig: StackBlitzConfigSchema.optional(),
1214
- forms: z$1.object({
1215
- workshop: z$1.string().default(
639
+ forms: z.object({
640
+ workshop: z.string().default(
1216
641
  "https://docs.google.com/forms/d/e/1FAIpQLSdRmj9p8-5zyoqRzxp3UpqSbC3aFkweXvvJIKes0a5s894gzg/viewform?hl=en&embedded=true&entry.2123647600={workshopTitle}"
1217
642
  ),
1218
- exercise: z$1.string().default(
643
+ exercise: z.string().default(
1219
644
  "https://docs.google.com/forms/d/e/1FAIpQLSf3o9xyjQepTlOTH5Z7ZwkeSTdXh6YWI_RGc9KiyD3oUN0p6w/viewform?hl=en&embedded=true&entry.1836176234={workshopTitle}&entry.428900931={exerciseTitle}"
1220
645
  )
1221
646
  }).default({}),
1222
- testTab: z$1.object({
1223
- enabled: z$1.boolean().default(true)
647
+ testTab: z.object({
648
+ enabled: z.boolean().default(true)
1224
649
  }).default({}),
1225
- scripts: z$1.object({
1226
- postupdate: z$1.string().optional()
650
+ scripts: z.object({
651
+ postupdate: z.string().optional()
1227
652
  }).optional(),
1228
- initialRoute: z$1.string().optional().default("/")
653
+ initialRoute: z.string().optional().default("/")
1229
654
  }).transform((data) => {
1230
655
  return {
1231
656
  ...data,
@@ -1283,7 +708,7 @@ function getWorkshopConfig() {
1283
708
  cachedConfig = parsedConfig;
1284
709
  return parsedConfig;
1285
710
  } catch (error) {
1286
- if (error instanceof z$1.ZodError) {
711
+ if (error instanceof z.ZodError) {
1287
712
  const flattenedErrors = error.flatten();
1288
713
  const errorMessages = Object.entries(flattenedErrors.fieldErrors).map(([field, errors]) => `${field}: ${errors == null ? void 0 : errors.join(", ")}`).concat(flattenedErrors.formErrors);
1289
714
  throw new Error(
@@ -1334,7 +759,7 @@ async function getAppConfig(fullPath) {
1334
759
  epicshopConfig = pkg.epicshop ?? {};
1335
760
  scripts = pkg.scripts ?? {};
1336
761
  }
1337
- const AppConfigSchema = z$1.object({
762
+ const AppConfigSchema = z.object({
1338
763
  stackBlitzConfig: StackBlitzConfigSchema.nullable().optional().transform((appStackBlitzConfig) => {
1339
764
  if (appStackBlitzConfig === null) return null;
1340
765
  return {
@@ -1342,14 +767,14 @@ async function getAppConfig(fullPath) {
1342
767
  ...appStackBlitzConfig
1343
768
  };
1344
769
  }),
1345
- testTab: z$1.object({
1346
- enabled: z$1.boolean().optional().default(((_a2 = workshopConfig.testTab) == null ? void 0 : _a2.enabled) ?? true)
770
+ testTab: z.object({
771
+ enabled: z.boolean().optional().default(((_a2 = workshopConfig.testTab) == null ? void 0 : _a2.enabled) ?? true)
1347
772
  }).default({}),
1348
- scripts: z$1.object({
1349
- test: z$1.string().optional(),
1350
- dev: z$1.string().optional()
773
+ scripts: z.object({
774
+ test: z.string().optional(),
775
+ dev: z.string().optional()
1351
776
  }).default({}),
1352
- initialRoute: z$1.string().optional().default(workshopConfig.initialRoute)
777
+ initialRoute: z.string().optional().default(workshopConfig.initialRoute)
1353
778
  });
1354
779
  const appConfig = {
1355
780
  stackBlitzConfig: epicshopConfig.stackBlitzConfig,
@@ -1365,22 +790,257 @@ async function getAppConfig(fullPath) {
1365
790
  try {
1366
791
  return AppConfigSchema.parse(appConfig);
1367
792
  } catch (error) {
1368
- if (error instanceof z$1.ZodError) {
1369
- const flattenedErrors = error.flatten();
1370
- const errorMessages = Object.entries(flattenedErrors.fieldErrors).map(([field, errors]) => `${field}: ${errors == null ? void 0 : errors.join(", ")}`).concat(flattenedErrors.formErrors);
1371
- throw new Error(
1372
- `Invalid app configuration for ${fullPath}:
1373
- ${errorMessages.join("\n")}`
1374
- );
1375
- }
793
+ if (error instanceof z.ZodError) {
794
+ const flattenedErrors = error.flatten();
795
+ const errorMessages = Object.entries(flattenedErrors.fieldErrors).map(([field, errors]) => `${field}: ${errors == null ? void 0 : errors.join(", ")}`).concat(flattenedErrors.formErrors);
796
+ throw new Error(
797
+ `Invalid app configuration for ${fullPath}:
798
+ ${errorMessages.join("\n")}`
799
+ );
800
+ }
801
+ throw error;
802
+ }
803
+ }
804
+ let watcher = global.__change_tracker_watcher__;
805
+ const dirsToWatch = [
806
+ path.join(workshopRoot$1, "playground"),
807
+ path.join(workshopRoot$1, "exercises"),
808
+ path.join(workshopRoot$1, "examples")
809
+ ];
810
+ const ignoredDirs = [
811
+ "/.git",
812
+ "/node_modules",
813
+ "/build",
814
+ "/server-build",
815
+ "/public/build",
816
+ "/playwright-report",
817
+ "/dist",
818
+ "/.cache"
819
+ ];
820
+ function getWatcher() {
821
+ if (process.env.EPICSHOP_DEPLOYED ?? process.env.EPICSHOP_ENABLE_WATCHER !== "true") {
822
+ return void 0;
823
+ }
824
+ if (watcher) return watcher;
825
+ watcher = chokidar.watch(dirsToWatch, {
826
+ ignoreInitial: true,
827
+ ignored(path2, stat) {
828
+ return (stat == null ? void 0 : stat.isDirectory()) ? ignoredDirs.some((dir) => path2.endsWith(dir)) : false;
829
+ }
830
+ });
831
+ global.__change_tracker_watcher__ = watcher;
832
+ return watcher;
833
+ }
834
+ let currentWithoutWatcher = null;
835
+ async function withoutWatcher(fn) {
836
+ if (!watcher) return fn();
837
+ let thisWithoutWatcher = currentWithoutWatcher = Symbol("withoutWatcher");
838
+ const eventNames = watcher.eventNames();
839
+ const eventNamesToListenersMap = {};
840
+ for (const eventName of eventNames) {
841
+ if (typeof eventName === "string") {
842
+ eventNamesToListenersMap[eventName] = watcher.listeners(eventName);
843
+ }
844
+ }
845
+ watcher.removeAllListeners();
846
+ try {
847
+ const result = await fn();
848
+ return result;
849
+ } finally {
850
+ if (currentWithoutWatcher === thisWithoutWatcher) {
851
+ await new Promise((r) => setTimeout(r, 100));
852
+ for (const eventName of eventNames) {
853
+ if (typeof eventName === "string") {
854
+ const listeners = eventNamesToListenersMap[eventName] || [];
855
+ for (const listener of listeners) {
856
+ watcher.on(eventName, listener);
857
+ }
858
+ }
859
+ }
860
+ }
861
+ }
862
+ }
863
+ (_a = global.__change_tracker_close_with_grace_return__) == null ? void 0 : _a.uninstall();
864
+ global.__change_tracker_close_with_grace_return__ = closeWithGrace(
865
+ () => watcher == null ? void 0 : watcher.close()
866
+ );
867
+ function trimCodeBlocks() {
868
+ return async function transformer(tree) {
869
+ visit(tree, "element", (preNode) => {
870
+ if (preNode.tagName !== "pre" || !preNode.children.length) {
871
+ return;
872
+ }
873
+ const codeNode = preNode.children[0];
874
+ if (!codeNode || codeNode.type !== "element" || codeNode.tagName !== "code") {
875
+ return;
876
+ }
877
+ const [codeStringNode] = codeNode.children;
878
+ if (!codeStringNode) return;
879
+ if (codeStringNode.type !== "text") {
880
+ console.warn(
881
+ `trimCodeBlocks: Unexpected: codeStringNode type is not "text": ${codeStringNode.type}`
882
+ );
883
+ return;
884
+ }
885
+ codeStringNode.value = codeStringNode.value.trimEnd();
886
+ });
887
+ };
888
+ }
889
+ function removePreContainerDivs() {
890
+ return async function preContainerDivsTransformer(tree) {
891
+ visit(
892
+ tree,
893
+ { type: "element", tagName: "pre" },
894
+ function visitor(node, index, parent) {
895
+ if ((parent == null ? void 0 : parent.type) !== "element") return;
896
+ if (parent.tagName !== "div") return;
897
+ if (parent.children.length !== 1 && index === 0) return;
898
+ Object.assign(parent, node);
899
+ }
900
+ );
901
+ };
902
+ }
903
+ const rehypePlugins = [
904
+ trimCodeBlocks,
905
+ remarkCodeBlocksShiki,
906
+ removePreContainerDivs
907
+ ];
908
+ const verboseLog = process.env.EPICSHOP_VERBOSE_LOG === "true" ? console.log : () => {
909
+ };
910
+ async function compileMdx(file, {
911
+ request,
912
+ timings,
913
+ forceFresh
914
+ } = {}) {
915
+ const stat = await fs$1.promises.stat(file).catch((error) => ({ error }));
916
+ if ("error" in stat) {
917
+ throw new Error(`File stat cannot be read: ${stat.error}`);
918
+ }
919
+ const key = `file:${file}`;
920
+ forceFresh = await shouldForceFresh({ forceFresh, request, key });
921
+ const existingCacheEntry = await compiledInstructionMarkdownCache.get(key);
922
+ if (!forceFresh && existingCacheEntry) {
923
+ forceFresh = stat.mtimeMs > existingCacheEntry.metadata.createdTime;
924
+ }
925
+ return cachified({
926
+ key,
927
+ cache: compiledInstructionMarkdownCache,
928
+ request,
929
+ timings,
930
+ forceFresh,
931
+ getFreshValue: () => compileMdxImpl(file)
932
+ });
933
+ }
934
+ async function compileMdxImpl(file) {
935
+ let title = null;
936
+ const epicVideoEmbeds = [];
937
+ try {
938
+ verboseLog(`Compiling ${file}`);
939
+ const bundleResult = await queuedBundleMDX({
940
+ file,
941
+ cwd: path.dirname(file),
942
+ mdxOptions(options) {
943
+ options.remarkPlugins = [
944
+ ...options.remarkPlugins ?? [],
945
+ [remarkAutolinkHeadings, { behavior: "wrap" }],
946
+ gfm,
947
+ () => (tree) => {
948
+ visit(tree, "heading", (node) => {
949
+ if (title) return;
950
+ if (node.depth === 1) {
951
+ visit(node, "text", (textNode) => {
952
+ title = textNode.value.trim();
953
+ });
954
+ }
955
+ });
956
+ title = title ? title.replace(/^\d+\. /, "").trim() : null;
957
+ },
958
+ () => (tree) => {
959
+ visit(tree, "mdxJsxFlowElement", (jsxEl) => {
960
+ if (jsxEl.name !== "EpicVideo") return;
961
+ const urlAttr = jsxEl.attributes.find(
962
+ // @ts-expect-error no idea why this started being an issue suddenly 🤷‍♂️
963
+ (a) => a.type === "mdxJsxAttribute" && a.name === "url"
964
+ );
965
+ if (!urlAttr) return;
966
+ let url = urlAttr.value;
967
+ if (typeof url !== "string") return;
968
+ if (url.endsWith("/")) url = url.slice(0, -1);
969
+ epicVideoEmbeds.push(url);
970
+ });
971
+ },
972
+ emoji
973
+ ];
974
+ options.rehypePlugins = [
975
+ ...options.rehypePlugins ?? [],
976
+ ...rehypePlugins
977
+ ];
978
+ options.mdxExtensions = [".mdx", ".md"];
979
+ options.format = "mdx";
980
+ options.development = false;
981
+ return options;
982
+ }
983
+ });
984
+ if (!bundleResult) throw new Error(`Timeout for file: ${file}`);
985
+ const result = { code: bundleResult.code, title, epicVideoEmbeds };
986
+ return result;
987
+ } catch (error) {
988
+ console.error(`Compilation error for file: `, file, error);
1376
989
  throw error;
990
+ } finally {
991
+ verboseLog(`Successfully compiled ${file}`);
1377
992
  }
1378
993
  }
1379
- const schema = z$1.object({
1380
- NODE_ENV: z$1.enum(["production", "development", "test"]).default("development"),
1381
- EPICSHOP_GITHUB_REPO: z$1.string(),
1382
- EPICSHOP_GITHUB_ROOT: z$1.string(),
1383
- EPICSHOP_CONTEXT_CWD: z$1.string()
994
+ async function compileMarkdownString(markdownString) {
995
+ return cachified({
996
+ key: markdownString,
997
+ cache: compiledMarkdownCache,
998
+ ttl: 1e3 * 60 * 60 * 24,
999
+ getFreshValue: async () => {
1000
+ try {
1001
+ verboseLog(`Compiling string`, markdownString);
1002
+ const result = await queuedBundleMDX({
1003
+ source: markdownString,
1004
+ mdxOptions(options) {
1005
+ options.rehypePlugins = [
1006
+ ...options.rehypePlugins ?? [],
1007
+ ...rehypePlugins
1008
+ ];
1009
+ options.development = false;
1010
+ return options;
1011
+ }
1012
+ });
1013
+ if (!result) throw new Error(`Timed out compiling markdown string`);
1014
+ return result.code;
1015
+ } catch (error) {
1016
+ console.error(`Compilation error for code: `, markdownString, error);
1017
+ throw error;
1018
+ } finally {
1019
+ verboseLog(`Successfully compiled string`, markdownString);
1020
+ }
1021
+ }
1022
+ });
1023
+ }
1024
+ let _queue = null;
1025
+ async function getQueue() {
1026
+ if (_queue) return _queue;
1027
+ _queue = new PQueue({
1028
+ concurrency: 1,
1029
+ throwOnTimeout: true,
1030
+ timeout: 1e3 * 60
1031
+ });
1032
+ return _queue;
1033
+ }
1034
+ async function queuedBundleMDX(...args) {
1035
+ const queue = await getQueue();
1036
+ const result = await queue.add(() => bundleMDX(...args));
1037
+ return result;
1038
+ }
1039
+ const schema = z.object({
1040
+ NODE_ENV: z.enum(["production", "development", "test"]).default("development"),
1041
+ EPICSHOP_GITHUB_REPO: z.string(),
1042
+ EPICSHOP_GITHUB_ROOT: z.string(),
1043
+ EPICSHOP_CONTEXT_CWD: z.string()
1384
1044
  });
1385
1045
  function init$1() {
1386
1046
  const parsed = schema.safeParse(process.env);
@@ -1665,92 +1325,92 @@ const playgroundAppNameInfoPath = path$1.join(
1665
1325
  "epicshop",
1666
1326
  "playground.json"
1667
1327
  );
1668
- const BaseAppSchema = z$1.object({
1328
+ const BaseAppSchema = z.object({
1669
1329
  /** a unique identifier for the app */
1670
- name: z$1.string(),
1330
+ name: z.string(),
1671
1331
  /** the title of the app used for display (comes from the package.json title prop) */
1672
- title: z$1.string(),
1332
+ title: z.string(),
1673
1333
  /** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */
1674
- dirName: z$1.string(),
1675
- fullPath: z$1.string(),
1676
- relativePath: z$1.string(),
1677
- instructionsCode: z$1.string().optional(),
1678
- epicVideoEmbeds: z$1.array(z$1.string()).optional(),
1679
- test: z$1.union([
1680
- z$1.object({
1681
- type: z$1.literal("browser"),
1682
- pathname: z$1.string(),
1683
- testFiles: z$1.array(z$1.string())
1334
+ dirName: z.string(),
1335
+ fullPath: z.string(),
1336
+ relativePath: z.string(),
1337
+ instructionsCode: z.string().optional(),
1338
+ epicVideoEmbeds: z.array(z.string()).optional(),
1339
+ test: z.union([
1340
+ z.object({
1341
+ type: z.literal("browser"),
1342
+ pathname: z.string(),
1343
+ testFiles: z.array(z.string())
1684
1344
  }),
1685
- z$1.object({ type: z$1.literal("script"), script: z$1.string() }),
1686
- z$1.object({ type: z$1.literal("none") })
1345
+ z.object({ type: z.literal("script"), script: z.string() }),
1346
+ z.object({ type: z.literal("none") })
1687
1347
  ]),
1688
- dev: z$1.union([
1689
- z$1.object({ type: z$1.literal("browser"), pathname: z$1.string() }),
1690
- z$1.object({
1691
- type: z$1.literal("script"),
1692
- portNumber: z$1.number(),
1693
- initialRoute: z$1.string()
1348
+ dev: z.union([
1349
+ z.object({ type: z.literal("browser"), pathname: z.string() }),
1350
+ z.object({
1351
+ type: z.literal("script"),
1352
+ portNumber: z.number(),
1353
+ initialRoute: z.string()
1694
1354
  }),
1695
- z$1.object({ type: z$1.literal("none") })
1355
+ z.object({ type: z.literal("none") })
1696
1356
  ]),
1697
- stackBlitzUrl: z$1.string().nullable()
1357
+ stackBlitzUrl: z.string().nullable()
1698
1358
  });
1699
1359
  const BaseExerciseStepAppSchema = BaseAppSchema.extend({
1700
- exerciseNumber: z$1.number(),
1701
- stepNumber: z$1.number()
1360
+ exerciseNumber: z.number(),
1361
+ stepNumber: z.number()
1702
1362
  });
1703
1363
  const ProblemAppSchema = BaseExerciseStepAppSchema.extend({
1704
- type: z$1.literal("problem"),
1705
- solutionName: z$1.string().nullable()
1364
+ type: z.literal("problem"),
1365
+ solutionName: z.string().nullable()
1706
1366
  });
1707
1367
  const SolutionAppSchema = BaseExerciseStepAppSchema.extend({
1708
- type: z$1.literal("solution"),
1709
- problemName: z$1.string().nullable()
1368
+ type: z.literal("solution"),
1369
+ problemName: z.string().nullable()
1710
1370
  });
1711
1371
  const ExampleAppSchema = BaseAppSchema.extend({
1712
- type: z$1.literal("example")
1372
+ type: z.literal("example")
1713
1373
  });
1714
1374
  const PlaygroundAppSchema = BaseAppSchema.extend({
1715
- type: z$1.literal("playground"),
1716
- appName: z$1.string(),
1717
- isUpToDate: z$1.boolean()
1375
+ type: z.literal("playground"),
1376
+ appName: z.string(),
1377
+ isUpToDate: z.boolean()
1718
1378
  });
1719
- z$1.object({
1379
+ z.object({
1720
1380
  /** a unique identifier for the exercise */
1721
- exerciseNumber: z$1.number(),
1381
+ exerciseNumber: z.number(),
1722
1382
  /** used when displaying the list of files to match the list of apps in the file system (comes the name of the directory of the app) */
1723
- dirName: z$1.string(),
1383
+ dirName: z.string(),
1724
1384
  /** the title of the app used for display (comes from the first h1 in the README) */
1725
- title: z$1.string(),
1726
- instructionsCode: z$1.string().optional(),
1727
- finishedCode: z$1.string().optional(),
1728
- instructionsEpicVideoEmbeds: z$1.array(z$1.string()).optional(),
1729
- finishedEpicVideoEmbeds: z$1.array(z$1.string()).optional(),
1730
- steps: z$1.array(
1731
- z$1.union([
1732
- z$1.object({
1733
- stepNumber: z$1.number(),
1385
+ title: z.string(),
1386
+ instructionsCode: z.string().optional(),
1387
+ finishedCode: z.string().optional(),
1388
+ instructionsEpicVideoEmbeds: z.array(z.string()).optional(),
1389
+ finishedEpicVideoEmbeds: z.array(z.string()).optional(),
1390
+ steps: z.array(
1391
+ z.union([
1392
+ z.object({
1393
+ stepNumber: z.number(),
1734
1394
  problem: ProblemAppSchema,
1735
1395
  solution: SolutionAppSchema
1736
1396
  }),
1737
- z$1.object({
1738
- stepNumber: z$1.number(),
1397
+ z.object({
1398
+ stepNumber: z.number(),
1739
1399
  problem: ProblemAppSchema,
1740
- solution: z$1.never().optional()
1400
+ solution: z.never().optional()
1741
1401
  }),
1742
- z$1.object({
1743
- stepNumber: z$1.number(),
1744
- problem: z$1.never().optional(),
1402
+ z.object({
1403
+ stepNumber: z.number(),
1404
+ problem: z.never().optional(),
1745
1405
  solution: SolutionAppSchema
1746
1406
  })
1747
1407
  ])
1748
1408
  ),
1749
- problems: z$1.array(ProblemAppSchema),
1750
- solutions: z$1.array(SolutionAppSchema)
1409
+ problems: z.array(ProblemAppSchema),
1410
+ solutions: z.array(SolutionAppSchema)
1751
1411
  });
1752
- const ExerciseStepAppSchema = z$1.union([ProblemAppSchema, SolutionAppSchema]);
1753
- const AppSchema = z$1.union([
1412
+ const ExerciseStepAppSchema = z.union([ProblemAppSchema, SolutionAppSchema]);
1413
+ const AppSchema = z.union([
1754
1414
  ExerciseStepAppSchema,
1755
1415
  PlaygroundAppSchema,
1756
1416
  ExampleAppSchema
@@ -1797,19 +1457,19 @@ function init() {
1797
1457
  process.env.EPICSHOP_GITHUB_ROOT = config.githubRoot;
1798
1458
  init$1();
1799
1459
  global.ENV = getEnv();
1800
- async function handleFileChanges(event, filePath) {
1801
- if (filePath === path$1.join(workshopRoot, "package.json")) {
1802
- bustWorkshopConfigCache();
1803
- }
1804
- const apps = await getApps();
1805
- for (const app of apps) {
1806
- if (filePath.startsWith(app.fullPath)) {
1807
- modifiedTimes.set(app.fullPath, Date.now());
1808
- break;
1809
- }
1460
+ (_a2 = getWatcher()) == null ? void 0 : _a2.on("all", handleFileChanges);
1461
+ }
1462
+ async function handleFileChanges(event, filePath) {
1463
+ if (filePath === path$1.join(workshopRoot, "package.json")) {
1464
+ bustWorkshopConfigCache();
1465
+ }
1466
+ const apps = await getApps();
1467
+ for (const app of apps) {
1468
+ if (filePath.startsWith(app.fullPath)) {
1469
+ modifiedTimes.set(app.fullPath, Date.now());
1470
+ break;
1810
1471
  }
1811
1472
  }
1812
- (_a2 = getWatcher()) == null ? void 0 : _a2.on("all", handleFileChanges);
1813
1473
  }
1814
1474
  function getForceFresh$1(cacheEntry) {
1815
1475
  if (!cacheEntry) return true;
@@ -1817,9 +1477,6 @@ function getForceFresh$1(cacheEntry) {
1817
1477
  if (!latestModifiedTime) return void 0;
1818
1478
  return latestModifiedTime > cacheEntry.metadata.createdTime ? true : void 0;
1819
1479
  }
1820
- function setModifiedTimesForDir(dir) {
1821
- modifiedTimes.set(dir, Date.now());
1822
- }
1823
1480
  function getForceFreshForDir(cacheEntry, ...dirs) {
1824
1481
  const truthyDirs = dirs.filter(Boolean);
1825
1482
  for (const d of truthyDirs) {
@@ -1991,10 +1648,10 @@ async function getApps({
1991
1648
  });
1992
1649
  return apps;
1993
1650
  }
1994
- const AppIdInfoSchema = z$1.object({
1995
- exerciseNumber: z$1.string(),
1996
- stepNumber: z$1.string(),
1997
- type: z$1.union([z$1.literal("problem"), z$1.literal("solution")])
1651
+ const AppIdInfoSchema = z.object({
1652
+ exerciseNumber: z.string(),
1653
+ stepNumber: z.string(),
1654
+ type: z.union([z.literal("problem"), z.literal("solution")])
1998
1655
  });
1999
1656
  function extractNumbersAndTypeFromAppNameOrPath(fullPathOrAppName) {
2000
1657
  var _a2;
@@ -2460,10 +2117,10 @@ async function requireExerciseApp(params, { request, timings } = {}) {
2460
2117
  }
2461
2118
  return app;
2462
2119
  }
2463
- const ExerciseAppParamsSchema$1 = z$1.object({
2464
- type: z$1.union([z$1.literal("problem"), z$1.literal("solution")]),
2465
- exerciseNumber: z$1.coerce.number().finite(),
2466
- stepNumber: z$1.coerce.number().finite()
2120
+ const ExerciseAppParamsSchema$1 = z.object({
2121
+ type: z.union([z.literal("problem"), z.literal("solution")]),
2122
+ exerciseNumber: z.coerce.number().finite(),
2123
+ stepNumber: z.coerce.number().finite()
2467
2124
  });
2468
2125
  async function getExerciseApp(params, { request, timings } = {}) {
2469
2126
  const result = ExerciseAppParamsSchema$1.safeParse(params);
@@ -2523,104 +2180,104 @@ async function getAppFromFile(filePath) {
2523
2180
  return apps.find((app) => filePath.startsWith(app.fullPath));
2524
2181
  }
2525
2182
  async function setPlayground(srcDir, { reset } = {}) {
2526
- var _a2, _b;
2527
- const isIgnored = await isGitIgnored({ cwd: srcDir });
2183
+ var _a2;
2528
2184
  const destDir = path$1.join(workshopRoot, "playground");
2529
- const playgroundFiles = path$1.join(destDir, "**");
2530
- (_a2 = getOptionalWatcher()) == null ? void 0 : _a2.unwatch(playgroundFiles);
2531
- const playgroundApp = await getAppByName("playground");
2532
- const playgroundWasRunning = playgroundApp ? isAppRunning(playgroundApp) : false;
2533
- if (playgroundApp && reset) {
2534
- await closeProcess(playgroundApp.name);
2535
- await fsExtra.remove(destDir);
2536
- }
2537
- const setPlaygroundTimestamp = Date.now();
2538
- const preSetPlaygroundPath = await firstToExist(
2539
- path$1.join(srcDir, "epicshop", "pre-set-playground.js"),
2540
- path$1.join(workshopRoot, "epicshop", "pre-set-playground.js")
2541
- );
2542
- if (preSetPlaygroundPath) {
2543
- await execa("node", [preSetPlaygroundPath], {
2544
- cwd: workshopRoot,
2545
- stdio: "inherit",
2546
- env: {
2547
- EPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),
2548
- EPICSHOP_PLAYGROUND_DEST_DIR: destDir,
2549
- EPICSHOP_PLAYGROUND_SRC_DIR: srcDir,
2550
- EPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString()
2185
+ await withoutWatcher(async () => {
2186
+ const isIgnored = await isGitIgnored({ cwd: srcDir });
2187
+ const playgroundApp = await getAppByName("playground");
2188
+ const playgroundWasRunning = playgroundApp ? isAppRunning(playgroundApp) : false;
2189
+ if (playgroundApp && reset) {
2190
+ await closeProcess(playgroundApp.name);
2191
+ await fsExtra.remove(destDir);
2192
+ }
2193
+ const setPlaygroundTimestamp = Date.now();
2194
+ const preSetPlaygroundPath = await firstToExist(
2195
+ path$1.join(srcDir, "epicshop", "pre-set-playground.js"),
2196
+ path$1.join(workshopRoot, "epicshop", "pre-set-playground.js")
2197
+ );
2198
+ if (preSetPlaygroundPath) {
2199
+ await execa("node", [preSetPlaygroundPath], {
2200
+ cwd: workshopRoot,
2201
+ stdio: "inherit",
2202
+ env: {
2203
+ EPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),
2204
+ EPICSHOP_PLAYGROUND_DEST_DIR: destDir,
2205
+ EPICSHOP_PLAYGROUND_SRC_DIR: srcDir,
2206
+ EPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString()
2207
+ }
2208
+ });
2209
+ }
2210
+ const basename2 = path$1.basename(srcDir);
2211
+ await fsExtra.remove(path$1.join(destDir, "node_modules"));
2212
+ await fsExtra.copy(srcDir, destDir, {
2213
+ filter: async (srcFile, destFile) => {
2214
+ if (srcFile.includes(`${basename2}${path$1.sep}build`) || srcFile.includes(`${basename2}${path$1.sep}public${path$1.sep}build`)) {
2215
+ return false;
2216
+ }
2217
+ if (srcFile === srcDir) return true;
2218
+ if (srcFile.includes("node_modules")) return true;
2219
+ if (srcFile.endsWith(".env")) return true;
2220
+ if (isIgnored(srcFile)) return false;
2221
+ try {
2222
+ const isDir = (await fsExtra.stat(srcFile)).isDirectory();
2223
+ if (isDir) return true;
2224
+ const destIsDir = (await fsExtra.stat(destFile)).isDirectory();
2225
+ if (destIsDir) return true;
2226
+ const currentContents = await fsExtra.readFile(destFile);
2227
+ const newContents = await fsExtra.readFile(srcFile);
2228
+ if (currentContents.equals(newContents)) return false;
2229
+ return true;
2230
+ } catch {
2231
+ return true;
2232
+ }
2551
2233
  }
2552
2234
  });
2553
- }
2554
- const basename2 = path$1.basename(srcDir);
2555
- await fsExtra.remove(path$1.join(destDir, "node_modules"));
2556
- await fsExtra.copy(srcDir, destDir, {
2557
- filter: async (srcFile, destFile) => {
2558
- if (srcFile.includes(`${basename2}${path$1.sep}build`) || srcFile.includes(`${basename2}${path$1.sep}public${path$1.sep}build`)) {
2559
- return false;
2560
- }
2561
- if (srcFile === srcDir) return true;
2562
- if (srcFile.includes("node_modules")) return true;
2563
- if (srcFile.endsWith(".env")) return true;
2564
- if (isIgnored(srcFile)) return false;
2565
- try {
2566
- const isDir = (await fsExtra.stat(srcFile)).isDirectory();
2567
- if (isDir) return true;
2568
- const destIsDir = (await fsExtra.stat(destFile)).isDirectory();
2569
- if (destIsDir) return true;
2570
- const currentContents = await fsExtra.readFile(destFile);
2571
- const newContents = await fsExtra.readFile(srcFile);
2572
- if (currentContents.equals(newContents)) return false;
2573
- return true;
2574
- } catch {
2575
- return true;
2576
- }
2235
+ async function getFiles(dir) {
2236
+ const dirPath = dir.replace(/\\/g, "/");
2237
+ const files = await globby([`${dirPath}/**/*`, "!**/build/**/*"], {
2238
+ onlyFiles: false,
2239
+ dot: true
2240
+ });
2241
+ return files.map((f) => f.replace(dirPath, ""));
2242
+ }
2243
+ const srcFiles = await getFiles(srcDir);
2244
+ const destFiles = await getFiles(destDir);
2245
+ const filesToDelete = destFiles.filter(
2246
+ (fileName) => !srcFiles.includes(fileName)
2247
+ );
2248
+ for (const fileToDelete of filesToDelete) {
2249
+ await fsExtra.remove(path$1.join(destDir, fileToDelete));
2250
+ }
2251
+ const appName = getAppName(srcDir);
2252
+ await fsExtra.ensureDir(path$1.dirname(playgroundAppNameInfoPath));
2253
+ await fsExtra.writeJSON(playgroundAppNameInfoPath, { appName });
2254
+ const playgroundIsStillRunning = playgroundApp ? isAppRunning(playgroundApp) : false;
2255
+ const restartPlayground = playgroundWasRunning && !playgroundIsStillRunning;
2256
+ const postSetPlaygroundPath = await firstToExist(
2257
+ path$1.join(srcDir, "epicshop", "post-set-playground.js"),
2258
+ path$1.join(workshopRoot, "epicshop", "post-set-playground.js")
2259
+ );
2260
+ if (postSetPlaygroundPath) {
2261
+ await execa("node", [postSetPlaygroundPath], {
2262
+ cwd: workshopRoot,
2263
+ stdio: "inherit",
2264
+ env: {
2265
+ EPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),
2266
+ EPICSHOP_PLAYGROUND_SRC_DIR: srcDir,
2267
+ EPICSHOP_PLAYGROUND_DEST_DIR: destDir,
2268
+ EPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),
2269
+ EPICSHOP_PLAYGROUND_IS_STILL_RUNNING: playgroundIsStillRunning.toString(),
2270
+ EPICSHOP_PLAYGROUND_RESTART_PLAYGROUND: restartPlayground.toString()
2271
+ }
2272
+ });
2273
+ }
2274
+ modifiedTimes.set(destDir, Date.now());
2275
+ if (playgroundApp && restartPlayground) {
2276
+ await runAppDev(playgroundApp);
2277
+ await waitOnApp(playgroundApp);
2577
2278
  }
2578
2279
  });
2579
- async function getFiles(dir) {
2580
- const dirPath = dir.replace(/\\/g, "/");
2581
- const files = await globby([`${dirPath}/**/*`, "!**/build/**/*"], {
2582
- onlyFiles: false,
2583
- dot: true
2584
- });
2585
- return files.map((f) => f.replace(dirPath, ""));
2586
- }
2587
- const srcFiles = await getFiles(srcDir);
2588
- const destFiles = await getFiles(destDir);
2589
- const filesToDelete = destFiles.filter(
2590
- (fileName) => !srcFiles.includes(fileName)
2591
- );
2592
- for (const fileToDelete of filesToDelete) {
2593
- await fsExtra.remove(path$1.join(destDir, fileToDelete));
2594
- }
2595
- const appName = getAppName(srcDir);
2596
- await fsExtra.ensureDir(path$1.dirname(playgroundAppNameInfoPath));
2597
- await fsExtra.writeJSON(playgroundAppNameInfoPath, { appName });
2598
- const playgroundIsStillRunning = playgroundApp ? isAppRunning(playgroundApp) : false;
2599
- const restartPlayground = playgroundWasRunning && !playgroundIsStillRunning;
2600
- const postSetPlaygroundPath = await firstToExist(
2601
- path$1.join(srcDir, "epicshop", "post-set-playground.js"),
2602
- path$1.join(workshopRoot, "epicshop", "post-set-playground.js")
2603
- );
2604
- if (postSetPlaygroundPath) {
2605
- await execa("node", [postSetPlaygroundPath], {
2606
- cwd: workshopRoot,
2607
- stdio: "inherit",
2608
- env: {
2609
- EPICSHOP_PLAYGROUND_TIMESTAMP: setPlaygroundTimestamp.toString(),
2610
- EPICSHOP_PLAYGROUND_SRC_DIR: srcDir,
2611
- EPICSHOP_PLAYGROUND_DEST_DIR: destDir,
2612
- EPICSHOP_PLAYGROUND_WAS_RUNNING: playgroundWasRunning.toString(),
2613
- EPICSHOP_PLAYGROUND_IS_STILL_RUNNING: playgroundIsStillRunning.toString(),
2614
- EPICSHOP_PLAYGROUND_RESTART_PLAYGROUND: restartPlayground.toString()
2615
- }
2616
- });
2617
- }
2618
- if (playgroundApp && restartPlayground) {
2619
- await runAppDev(playgroundApp);
2620
- await waitOnApp(playgroundApp);
2621
- }
2622
- (_b = getOptionalWatcher()) == null ? void 0 : _b.add(playgroundFiles);
2623
- modifiedTimes.set(destDir, Date.now());
2280
+ (_a2 = getWatcher()) == null ? void 0 : _a2.emit("all", "playground", destDir);
2624
2281
  }
2625
2282
  async function getPlaygroundAppName() {
2626
2283
  if (!await exists(playgroundAppNameInfoPath)) {
@@ -3327,10 +2984,10 @@ function setTheme(theme) {
3327
2984
  });
3328
2985
  }
3329
2986
  const ROUTE_PATH = "/theme";
3330
- const ThemeFormSchema = z$1.object({
3331
- theme: z$1.enum(["system", "light", "dark"])
2987
+ const ThemeFormSchema = z.object({
2988
+ theme: z.enum(["system", "light", "dark"])
3332
2989
  });
3333
- async function action$c({ request }) {
2990
+ async function action$b({ request }) {
3334
2991
  const formData = await request.formData();
3335
2992
  const submission = parseWithZod(formData, {
3336
2993
  schema: ThemeFormSchema
@@ -3403,11 +3060,11 @@ function useTheme() {
3403
3060
  const route42 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
3404
3061
  __proto__: null,
3405
3062
  ThemeSwitch,
3406
- action: action$c,
3063
+ action: action$b,
3407
3064
  useTheme
3408
3065
  }, Symbol.toStringTag, { value: "Module" }));
3409
3066
  const appStylesheetUrl = "/assets/app-b7uXHF5m.css";
3410
- const tailwindStylesheetUrl = "/assets/tailwind-CFrdHbaR.css";
3067
+ const tailwindStylesheetUrl = "/assets/tailwind-B9pSujyx.css";
3411
3068
  const cookieName = "EpicShop_confetti";
3412
3069
  function getConfetti(request) {
3413
3070
  const cookieHeader = request.headers.get("cookie");
@@ -3425,39 +3082,39 @@ function createConfettiHeaders(value = String(Date.now())) {
3425
3082
  })
3426
3083
  });
3427
3084
  }
3428
- const Transcript = z$1.string().nullable().optional().transform((s) => s ?? "Transcripts not available");
3429
- const EpicVideoInfoSchema = z$1.object({
3085
+ const Transcript = z.string().nullable().optional().transform((s) => s ?? "Transcripts not available");
3086
+ const EpicVideoInfoSchema = z.object({
3430
3087
  transcript: Transcript,
3431
- muxPlaybackId: z$1.string()
3088
+ muxPlaybackId: z.string()
3432
3089
  });
3433
- const EpicVideoRegionRestrictedErrorSchema = z$1.object({
3434
- requestCountry: z$1.string(),
3435
- restrictedCountry: z$1.string(),
3436
- isRegionRestricted: z$1.literal(true)
3090
+ const EpicVideoRegionRestrictedErrorSchema = z.object({
3091
+ requestCountry: z.string(),
3092
+ restrictedCountry: z.string(),
3093
+ isRegionRestricted: z.literal(true)
3437
3094
  });
3438
- const CachedEpicVideoInfoSchema = z$1.object({
3095
+ const CachedEpicVideoInfoSchema = z.object({
3439
3096
  transcript: Transcript,
3440
- muxPlaybackId: z$1.string(),
3441
- status: z$1.literal("success"),
3442
- statusCode: z$1.number(),
3443
- statusText: z$1.string()
3097
+ muxPlaybackId: z.string(),
3098
+ status: z.literal("success"),
3099
+ statusCode: z.number(),
3100
+ statusText: z.string()
3444
3101
  }).or(
3445
- z$1.object({
3446
- status: z$1.literal("error"),
3447
- statusCode: z$1.number(),
3448
- statusText: z$1.string(),
3449
- type: z$1.literal("unknown")
3102
+ z.object({
3103
+ status: z.literal("error"),
3104
+ statusCode: z.number(),
3105
+ statusText: z.string(),
3106
+ type: z.literal("unknown")
3450
3107
  })
3451
3108
  ).or(
3452
- z$1.object({
3453
- status: z$1.literal("error"),
3454
- statusCode: z$1.number(),
3455
- statusText: z$1.string(),
3456
- type: z$1.literal("region-restricted"),
3457
- requestCountry: z$1.string(),
3458
- restrictedCountry: z$1.string()
3109
+ z.object({
3110
+ status: z.literal("error"),
3111
+ statusCode: z.number(),
3112
+ statusText: z.string(),
3113
+ type: z.literal("region-restricted"),
3114
+ requestCountry: z.string(),
3115
+ restrictedCountry: z.string()
3459
3116
  })
3460
- ).or(z$1.null());
3117
+ ).or(z.null());
3461
3118
  async function getEpicVideoInfos(epicWebUrls, { request, timings } = {}) {
3462
3119
  if (!epicWebUrls) return {};
3463
3120
  const authInfo = await getAuthInfo();
@@ -3571,10 +3228,10 @@ async function getEpicProgress({
3571
3228
  } = getWorkshopConfig();
3572
3229
  if (!authInfo) return [];
3573
3230
  const tokenPart = md5(authInfo.tokenSet.access_token);
3574
- const EpicProgressSchema = z$1.array(
3575
- z$1.object({
3576
- lessonId: z$1.string(),
3577
- completedAt: z$1.string().nullable()
3231
+ const EpicProgressSchema = z.array(
3232
+ z.object({
3233
+ lessonId: z.string(),
3234
+ completedAt: z.string().nullable()
3578
3235
  })
3579
3236
  );
3580
3237
  return cachified({
@@ -3735,17 +3392,17 @@ async function updateProgress({ lessonSlug, complete }, {
3735
3392
  }
3736
3393
  return { status: "success" };
3737
3394
  }
3738
- const ModuleSchema = z$1.object({
3739
- resources: z$1.array(
3740
- z$1.union([
3741
- z$1.object({
3742
- _type: z$1.literal("lesson"),
3743
- _id: z$1.string(),
3744
- slug: z$1.string()
3395
+ const ModuleSchema = z.object({
3396
+ resources: z.array(
3397
+ z.union([
3398
+ z.object({
3399
+ _type: z.literal("lesson"),
3400
+ _id: z.string(),
3401
+ slug: z.string()
3745
3402
  }),
3746
- z$1.object({
3747
- _type: z$1.literal("section"),
3748
- lessons: z$1.array(z$1.object({ _id: z$1.string(), slug: z$1.string() }))
3403
+ z.object({
3404
+ _type: z.literal("section"),
3405
+ lessons: z.array(z.object({ _id: z.string(), slug: z.string() }))
3749
3406
  })
3750
3407
  ])
3751
3408
  )
@@ -3808,7 +3465,7 @@ async function userHasAccessToWorkshop({
3808
3465
  forceFresh,
3809
3466
  timings,
3810
3467
  ttl: 1e3 * 5,
3811
- checkValue: z$1.boolean(),
3468
+ checkValue: z.boolean(),
3812
3469
  async getFreshValue(context) {
3813
3470
  const response = await fetch(
3814
3471
  `https://${host}/api/workshops/${encodeURIComponent(slug)}/access`,
@@ -3837,10 +3494,10 @@ function useOptionalWorkshopTitle() {
3837
3494
  const data = useRouteLoaderData("root");
3838
3495
  return (data == null ? void 0 : data.workshopTitle) ?? null;
3839
3496
  }
3840
- const ExerciseAppParamsSchema = z$1.object({
3841
- type: z$1.union([z$1.literal("problem"), z$1.literal("solution")]).optional(),
3842
- exerciseNumber: z$1.coerce.number().finite(),
3843
- stepNumber: z$1.coerce.number().finite().optional()
3497
+ const ExerciseAppParamsSchema = z.object({
3498
+ type: z.union([z.literal("problem"), z.literal("solution")]).optional(),
3499
+ exerciseNumber: z.coerce.number().finite(),
3500
+ stepNumber: z.coerce.number().finite().optional()
3844
3501
  });
3845
3502
  function usePresenceSocket(user) {
3846
3503
  const workshopTitle = useOptionalWorkshopTitle();
@@ -3980,11 +3637,11 @@ function getSeoMetaTags({
3980
3637
  ].filter(Boolean);
3981
3638
  }
3982
3639
  const toastKey = "toast";
3983
- const TypeSchema = z$1.enum(["message", "success", "error"]);
3984
- const ToastSchema = z$1.object({
3985
- description: z$1.string(),
3986
- id: z$1.string().default(() => createId()),
3987
- title: z$1.string().optional(),
3640
+ const TypeSchema = z.enum(["message", "success", "error"]);
3641
+ const ToastSchema = z.object({
3642
+ description: z.string(),
3643
+ id: z.string().default(() => createId()),
3644
+ title: z.string().optional(),
3988
3645
  type: TypeSchema.default("message")
3989
3646
  });
3990
3647
  const toastSessionStorage = createCookieSessionStorage({
@@ -4613,7 +4270,7 @@ function useProgressItem({
4613
4270
  }
4614
4271
  return null;
4615
4272
  }
4616
- async function action$b({ request }) {
4273
+ async function action$a({ request }) {
4617
4274
  ensureUndeployed();
4618
4275
  await requireAuthInfo({ request });
4619
4276
  const formData = await request.formData();
@@ -4784,7 +4441,7 @@ function ProgressToggle({
4784
4441
  const route36 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
4785
4442
  __proto__: null,
4786
4443
  ProgressToggle,
4787
- action: action$b,
4444
+ action: action$a,
4788
4445
  useEpicProgress,
4789
4446
  useExerciseProgressClassName,
4790
4447
  useNextExerciseRoute,
@@ -5940,12 +5597,12 @@ function ButtonLink({
5940
5597
  }
5941
5598
  const port = process.env.PORT || "5639";
5942
5599
  const scope = "guilds.join identify messages.read";
5943
- const DiscordApiResponseSchema = z$1.object({
5944
- status: z$1.literal("error"),
5945
- error: z$1.string()
5600
+ const DiscordApiResponseSchema = z.object({
5601
+ status: z.literal("error"),
5602
+ error: z.string()
5946
5603
  }).or(
5947
- z$1.object({
5948
- status: z$1.literal("success"),
5604
+ z.object({
5605
+ status: z.literal("success"),
5949
5606
  member: DiscordMemberSchema
5950
5607
  })
5951
5608
  );
@@ -6026,7 +5683,7 @@ async function loader$u({ request }) {
6026
5683
  await requireAuthInfo({ request });
6027
5684
  return json$1({ discordAuthUrl: getDiscordAuthURL() });
6028
5685
  }
6029
- async function action$a({ request }) {
5686
+ async function action$9({ request }) {
6030
5687
  ensureUndeployed();
6031
5688
  const formData = await request.formData();
6032
5689
  const intent = formData.get("intent");
@@ -6150,7 +5807,7 @@ function Account() {
6150
5807
  }
6151
5808
  const route3 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6152
5809
  __proto__: null,
6153
- action: action$a,
5810
+ action: action$9,
6154
5811
  default: Account,
6155
5812
  handle: handle$7,
6156
5813
  loader: loader$u
@@ -6312,7 +5969,7 @@ async function loader$s(args) {
6312
5969
  api.cleanupError(error);
6313
5970
  }
6314
5971
  }
6315
- async function action$9(args) {
5972
+ async function action$8(args) {
6316
5973
  const api = await getApiModule(args);
6317
5974
  invariantResponse(
6318
5975
  api.mod.action,
@@ -6326,9 +5983,9 @@ async function action$9(args) {
6326
5983
  api.cleanupError(error);
6327
5984
  }
6328
5985
  }
6329
- const ApiModuleSchema = z$1.object({
6330
- loader: z$1.function().optional(),
6331
- action: z$1.function().optional()
5986
+ const ApiModuleSchema = z.object({
5987
+ loader: z.function().optional(),
5988
+ action: z.function().optional()
6332
5989
  });
6333
5990
  async function getApiModule({ request, params }) {
6334
5991
  const timings = makeTimings("app-api");
@@ -6400,7 +6057,7 @@ async function getApiModule({ request, params }) {
6400
6057
  }
6401
6058
  const route5 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6402
6059
  __proto__: null,
6403
- action: action$9,
6060
+ action: action$8,
6404
6061
  loader: loader$s
6405
6062
  }, Symbol.toStringTag, { value: "Module" }));
6406
6063
  async function loader$r({ request, params }) {
@@ -6837,9 +6494,9 @@ const route11 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
6837
6494
  default: ExercisesLayout,
6838
6495
  handle: handle$5
6839
6496
  }, Symbol.toStringTag, { value: "Module" }));
6840
- const PlaybackTimeSchema = z$1.object({
6841
- time: z$1.number(),
6842
- expiresAt: z$1.string()
6497
+ const PlaybackTimeSchema = z.object({
6498
+ time: z.number(),
6499
+ expiresAt: z.string()
6843
6500
  }).transform((data) => {
6844
6501
  return { time: Number(data.time), expiresAt: new Date(data.expiresAt) };
6845
6502
  });
@@ -6849,14 +6506,25 @@ function usePlayerPreferences() {
6849
6506
  return ((_a2 = data == null ? void 0 : data.preferences) == null ? void 0 : _a2.player) ?? null;
6850
6507
  }
6851
6508
  const ignoredInputs = [
6852
- "input",
6853
- "select",
6854
- "button",
6855
- "textarea",
6856
- "mux-player",
6857
- "summary"
6509
+ "INPUT",
6510
+ "SELECT",
6511
+ "BUTTON",
6512
+ "TEXTAREA",
6513
+ "MUX-PLAYER",
6514
+ "SUMMARY"
6858
6515
  ];
6859
- async function action$8({ request }) {
6516
+ const ignoredRoles = ["button", "option", "combobox", "tab", "tablist"];
6517
+ function shouldIgnoreHotkey(el) {
6518
+ let current = el;
6519
+ while (current) {
6520
+ if (!(current instanceof HTMLElement)) return false;
6521
+ const isIgnored = ignoredInputs.includes(current.tagName) || ignoredRoles.includes(current.getAttribute("role") || "") || current.isContentEditable;
6522
+ if (isIgnored) return true;
6523
+ current = current.parentElement;
6524
+ }
6525
+ return false;
6526
+ }
6527
+ async function action$7({ request }) {
6860
6528
  const result = PlayerPreferencesSchema.safeParse(await request.json());
6861
6529
  if (!result.success) {
6862
6530
  return json$1({ status: "error", error: result.error.flatten() }, {
@@ -6900,24 +6568,23 @@ function MuxPlayer({
6900
6568
  function handleUserKeyPress(e) {
6901
6569
  if (!muxPlayerRef.current) return;
6902
6570
  const activeElement = document.activeElement;
6903
- const isContentEditable = activeElement instanceof HTMLElement ? activeElement.contentEditable === "true" : false;
6904
- if (activeElement && !ignoredInputs.includes(activeElement.tagName.toLowerCase()) && !isContentEditable) {
6905
- if (e.key === " ") {
6906
- e.preventDefault();
6907
- void (muxPlayerRef.current.paused ? muxPlayerRef.current.play() : muxPlayerRef.current.pause());
6908
- }
6909
- if (e.key === "ArrowRight") {
6910
- e.preventDefault();
6911
- muxPlayerRef.current.currentTime = muxPlayerRef.current.currentTime + (muxPlayerRef.current.forwardSeekOffset || 10);
6912
- }
6913
- if (e.key === "ArrowLeft") {
6914
- e.preventDefault();
6915
- muxPlayerRef.current.currentTime = muxPlayerRef.current.currentTime - (muxPlayerRef.current.forwardSeekOffset || 10);
6916
- }
6917
- if (e.key === "f" && !e.metaKey && !e.ctrlKey) {
6918
- e.preventDefault();
6919
- void (document.fullscreenElement ? document.exitFullscreen() : muxPlayerRef.current.requestFullscreen());
6920
- }
6571
+ if (shouldIgnoreHotkey(activeElement)) return;
6572
+ if (shouldIgnoreHotkey(e.target)) return;
6573
+ if (e.key === " ") {
6574
+ e.preventDefault();
6575
+ void (muxPlayerRef.current.paused ? muxPlayerRef.current.play() : muxPlayerRef.current.pause());
6576
+ }
6577
+ if (e.key === "ArrowRight") {
6578
+ e.preventDefault();
6579
+ muxPlayerRef.current.currentTime = muxPlayerRef.current.currentTime + (muxPlayerRef.current.forwardSeekOffset || 10);
6580
+ }
6581
+ if (e.key === "ArrowLeft") {
6582
+ e.preventDefault();
6583
+ muxPlayerRef.current.currentTime = muxPlayerRef.current.currentTime - (muxPlayerRef.current.forwardSeekOffset || 10);
6584
+ }
6585
+ if (e.key === "f" && !e.metaKey && !e.ctrlKey) {
6586
+ e.preventDefault();
6587
+ void (document.fullscreenElement ? document.exitFullscreen() : muxPlayerRef.current.requestFullscreen());
6921
6588
  }
6922
6589
  }
6923
6590
  window.document.addEventListener("keydown", handleUserKeyPress);
@@ -7025,10 +6692,10 @@ function isDeepEqual(obj1, obj2) {
7025
6692
  }
7026
6693
  return true;
7027
6694
  }
7028
- const route44 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
6695
+ const route43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
7029
6696
  __proto__: null,
7030
6697
  MuxPlayer,
7031
- action: action$8,
6698
+ action: action$7,
7032
6699
  usePlayerPreferences
7033
6700
  }, Symbol.toStringTag, { value: "Module" }));
7034
6701
  function Loading({
@@ -7854,27 +7521,27 @@ The editor process exited with an error code (${errorCode}).`
7854
7521
  });
7855
7522
  }
7856
7523
  function getFileDescriptorSchema(appFile) {
7857
- return z$1.union([
7858
- z$1.object({
7859
- type: z$1.literal("file"),
7860
- file: z$1.string()
7524
+ return z.union([
7525
+ z.object({
7526
+ type: z.literal("file"),
7527
+ file: z.string()
7861
7528
  }),
7862
- z$1.object({
7863
- type: z$1.literal("appFile"),
7529
+ z.object({
7530
+ type: z.literal("appFile"),
7864
7531
  appFile,
7865
- appName: z$1.string()
7532
+ appName: z.string()
7866
7533
  })
7867
7534
  ]);
7868
7535
  }
7869
- const LaunchSchema = z$1.intersection(
7870
- z$1.object({
7871
- line: z$1.coerce.number().optional(),
7872
- column: z$1.coerce.number().optional(),
7873
- syncTo: getFileDescriptorSchema(z$1.string()).optional()
7536
+ const LaunchSchema = z.intersection(
7537
+ z.object({
7538
+ line: z.coerce.number().optional(),
7539
+ column: z.coerce.number().optional(),
7540
+ syncTo: getFileDescriptorSchema(z.string()).optional()
7874
7541
  }),
7875
- getFileDescriptorSchema(z$1.array(z$1.string()))
7542
+ getFileDescriptorSchema(z.array(z.string()))
7876
7543
  );
7877
- async function action$7({ request }) {
7544
+ async function action$6({ request }) {
7878
7545
  ensureUndeployed();
7879
7546
  const formData = await request.formData();
7880
7547
  const syncTo = {
@@ -8125,7 +7792,7 @@ const route31 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
8125
7792
  __proto__: null,
8126
7793
  EditFileOnGitHub,
8127
7794
  LaunchEditor,
8128
- action: action$7
7795
+ action: action$6
8129
7796
  }, Symbol.toStringTag, { value: "Module" }));
8130
7797
  const safePath = (s) => s.replace(/\\/g, "/");
8131
7798
  function getRelativePath(file, separator, type) {
@@ -8959,11 +8626,11 @@ ${getFileCodeblocks(file, filePathApp1, filePathApp2, file.type).join("\n")}
8959
8626
  const code = await compileMarkdownString(markdownLines.join("\n"));
8960
8627
  return code;
8961
8628
  }
8962
- const SetPlaygroundSchema = z$1.object({
8963
- appName: z$1.string(),
8964
- reset: z$1.string().nullable().optional().transform((v) => v === "true")
8629
+ const SetPlaygroundSchema = z.object({
8630
+ appName: z.string(),
8631
+ reset: z.string().nullable().optional().transform((v) => v === "true")
8965
8632
  });
8966
- async function action$6({ request }) {
8633
+ async function action$5({ request }) {
8967
8634
  ensureUndeployed();
8968
8635
  const formData = await request.formData();
8969
8636
  const rawData = {
@@ -9005,7 +8672,7 @@ async function action$6({ request }) {
9005
8672
  const apps = await getApps({ forceFresh: true });
9006
8673
  const playground = apps.find(isPlaygroundApp);
9007
8674
  if (playground && converseApp) {
9008
- await getDiffCode(playground, converseApp, { forceFresh: true });
8675
+ void getDiffCode(playground, converseApp, { forceFresh: true });
9009
8676
  }
9010
8677
  return jsonWithPE(formData, { status: "success" });
9011
8678
  }
@@ -9143,86 +8810,6 @@ const route38 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
9143
8810
  PlaygroundChooser,
9144
8811
  SetAppToPlayground,
9145
8812
  SetPlayground,
9146
- action: action$6
9147
- }, Symbol.toStringTag, { value: "Module" }));
9148
- const cacheSchema = z$1.object({
9149
- cacheLocation: z$1.string(),
9150
- embeddedKey: z$1.string(),
9151
- appFullPath: z$1.string()
9152
- });
9153
- function checkFileExists(file) {
9154
- return fs.promises.access(file, fs.constants.F_OK).then(
9155
- () => true,
9156
- () => false
9157
- );
9158
- }
9159
- async function action$5({ request }) {
9160
- var _a2, _b;
9161
- ensureUndeployed();
9162
- const formData = await request.formData();
9163
- const rawData = {
9164
- cacheLocation: formData.get("cacheLocation"),
9165
- embeddedKey: formData.get("embeddedKey"),
9166
- appFullPath: formData.get("appFullPath")
9167
- };
9168
- const { cacheLocation, embeddedKey, appFullPath } = cacheSchema.parse(rawData);
9169
- if (!await checkFileExists(cacheLocation)) {
9170
- console.log(`file ${cacheLocation} not found`);
9171
- return json$1({ success: true });
9172
- }
9173
- const cached = JSON.parse(
9174
- await fs.promises.readFile(cacheLocation, "utf-8")
9175
- );
9176
- const cachedEmbeddedFiles = new Map(
9177
- Object.entries(((_a2 = cached == null ? void 0 : cached.value) == null ? void 0 : _a2.embeddedFiles) ?? {})
9178
- );
9179
- if (cachedEmbeddedFiles.has(embeddedKey)) {
9180
- (_b = cachedEmbeddedFiles.get(embeddedKey)) == null ? true : delete _b.warning;
9181
- cached.value.embeddedFiles = Object.fromEntries(cachedEmbeddedFiles);
9182
- }
9183
- try {
9184
- cached.value.warningCancled = true;
9185
- await fs.promises.writeFile(cacheLocation, JSON.stringify(cached));
9186
- } catch (error) {
9187
- console.log(
9188
- `Error when trying to write cache file at ${cacheLocation}`,
9189
- error
9190
- );
9191
- }
9192
- setModifiedTimesForDir(appFullPath);
9193
- return jsonWithPE(formData, { success: true });
9194
- }
9195
- function UpdateMdxCache({
9196
- handleClick,
9197
- cacheLocation,
9198
- embeddedKey,
9199
- appFullPath
9200
- }) {
9201
- const fetcher = useFetcher();
9202
- const peRedirectInput = usePERedirectInput();
9203
- return /* @__PURE__ */ jsxs(fetcher.Form, { action: "/update-mdx-cache", method: "POST", children: [
9204
- peRedirectInput,
9205
- showProgressBarField,
9206
- /* @__PURE__ */ jsx("input", { type: "hidden", name: "cacheLocation", value: cacheLocation }),
9207
- /* @__PURE__ */ jsx("input", { type: "hidden", name: "embeddedKey", value: embeddedKey }),
9208
- /* @__PURE__ */ jsx("input", { type: "hidden", name: "appFullPath", value: appFullPath }),
9209
- /* @__PURE__ */ jsx(
9210
- "button",
9211
- {
9212
- type: "submit",
9213
- onClick: handleClick,
9214
- className: clsx(
9215
- "launch_button",
9216
- fetcher.state === "idle" ? null : "cursor-progress"
9217
- ),
9218
- children: "Cancel Warning"
9219
- }
9220
- )
9221
- ] });
9222
- }
9223
- const route43 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.defineProperty({
9224
- __proto__: null,
9225
- UpdateMdxCache,
9226
8813
  action: action$5
9227
8814
  }, Symbol.toStringTag, { value: "Module" }));
9228
8815
  const StepContext = React.createContext(null);
@@ -9240,8 +8827,6 @@ function StepContextProvider({
9240
8827
  return /* @__PURE__ */ jsx(StepContext.Provider, { value: { inBrowserBrowserRef }, children });
9241
8828
  }
9242
8829
  const stepMdxComponents = {
9243
- CodeFile,
9244
- CodeFileNotification,
9245
8830
  DiffLink,
9246
8831
  PrevDiffLink,
9247
8832
  NextDiffLink,
@@ -9356,73 +8941,6 @@ function DiffLink({
9356
8941
  }
9357
8942
  return /* @__PURE__ */ jsx(Link, { to: pathToDiff, children });
9358
8943
  }
9359
- function CodeFile({ file }) {
9360
- return /* @__PURE__ */ jsxs("div", { className: "border-4 border-[#ff4545] bg-[#ff454519] p-4 text-lg", children: [
9361
- "Something went wrong compiling ",
9362
- /* @__PURE__ */ jsx("b", { children: "CodeFile" }),
9363
- " for file: ",
9364
- /* @__PURE__ */ jsx("u", { children: file }),
9365
- " to markdown"
9366
- ] });
9367
- }
9368
- function CodeFileNotification({
9369
- file,
9370
- type = "problem",
9371
- children,
9372
- variant,
9373
- cacheLocation,
9374
- embeddedKey,
9375
- ...props
9376
- }) {
9377
- const [visibility, setVisibility] = useState("visible");
9378
- const data = useLoaderData();
9379
- const app = data[type];
9380
- const handleClick = () => {
9381
- if (visibility !== "visible") return;
9382
- setVisibility("collapse");
9383
- setTimeout(() => {
9384
- setVisibility("none");
9385
- }, 400);
9386
- };
9387
- const className = clsx(
9388
- "rounded px-4 py-1 font-mono text-sm font-semibold outline-none transition duration-300 ease-in-out",
9389
- {
9390
- "bg-amber-300/70 hover:bg-amber-300/40 active:bg-amber-300/50": variant === "warning",
9391
- "bg-red-300/70 hover:bg-red-300/40 active:bg-red-300/50": variant === "error"
9392
- }
9393
- );
9394
- return /* @__PURE__ */ jsxs(
9395
- "div",
9396
- {
9397
- className: clsx("notification important h-15 relative", {
9398
- "duration-400 !my-0 !h-0 !py-0 !opacity-0 transition-all ease-out": visibility !== "visible",
9399
- hidden: visibility === "none"
9400
- }),
9401
- children: [
9402
- /* @__PURE__ */ jsxs("div", { className: "absolute right-3 top-3 z-50 flex gap-4", children: [
9403
- app ? /* @__PURE__ */ jsx("div", { className, title: `Edit ${file}`, children: /* @__PURE__ */ jsx(LaunchEditor, { appFile: file, appName: app.name, ...props, children: "Edit this File" }) }) : null,
9404
- app && variant === "warning" ? /* @__PURE__ */ jsx(
9405
- "div",
9406
- {
9407
- className,
9408
- title: `Remove the warning from here and from ${file} cache file`,
9409
- children: /* @__PURE__ */ jsx(
9410
- UpdateMdxCache,
9411
- {
9412
- handleClick,
9413
- cacheLocation,
9414
- embeddedKey,
9415
- appFullPath: app.fullPath
9416
- }
9417
- )
9418
- }
9419
- ) : null
9420
- ] }),
9421
- children
9422
- ]
9423
- }
9424
- );
9425
- }
9426
8944
  function InlineFile({
9427
8945
  file,
9428
8946
  type = "playground",
@@ -10039,43 +9557,43 @@ const route40 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
10039
9557
  PortStopper,
10040
9558
  action: action$4
10041
9559
  }, Symbol.toStringTag, { value: "Module" }));
10042
- const historyCallDataSchema = z$1.intersection(
10043
- z$1.object({
10044
- type: z$1.literal("epicshop:history-call")
9560
+ const historyCallDataSchema = z.intersection(
9561
+ z.object({
9562
+ type: z.literal("epicshop:history-call")
10045
9563
  }),
10046
- z$1.union([
10047
- z$1.object({
10048
- method: z$1.literal("pushState"),
10049
- args: z$1.union([
10050
- z$1.tuple([z$1.object({}).passthrough(), z$1.unknown()]),
10051
- z$1.tuple([z$1.object({}).passthrough(), z$1.unknown(), z$1.string()])
9564
+ z.union([
9565
+ z.object({
9566
+ method: z.literal("pushState"),
9567
+ args: z.union([
9568
+ z.tuple([z.object({}).passthrough(), z.unknown()]),
9569
+ z.tuple([z.object({}).passthrough(), z.unknown(), z.string()])
10052
9570
  ])
10053
9571
  }),
10054
- z$1.object({
10055
- method: z$1.literal("replaceState"),
10056
- args: z$1.union([
10057
- z$1.tuple([z$1.object({}).passthrough(), z$1.unknown()]),
10058
- z$1.tuple([z$1.object({}).passthrough(), z$1.unknown(), z$1.string()])
9572
+ z.object({
9573
+ method: z.literal("replaceState"),
9574
+ args: z.union([
9575
+ z.tuple([z.object({}).passthrough(), z.unknown()]),
9576
+ z.tuple([z.object({}).passthrough(), z.unknown(), z.string()])
10059
9577
  ])
10060
9578
  }),
10061
- z$1.object({
10062
- method: z$1.literal("go"),
10063
- args: z$1.tuple([z$1.number().optional()])
9579
+ z.object({
9580
+ method: z.literal("go"),
9581
+ args: z.tuple([z.number().optional()])
10064
9582
  }),
10065
- z$1.object({ method: z$1.literal("forward"), args: z$1.tuple([]) }),
10066
- z$1.object({ method: z$1.literal("back"), args: z$1.tuple([]) }),
10067
- z$1.object({
10068
- method: z$1.literal("popstate"),
10069
- pathname: z$1.string(),
10070
- delta: z$1.number()
9583
+ z.object({ method: z.literal("forward"), args: z.tuple([]) }),
9584
+ z.object({ method: z.literal("back"), args: z.tuple([]) }),
9585
+ z.object({
9586
+ method: z.literal("popstate"),
9587
+ pathname: z.string(),
9588
+ delta: z.number()
10071
9589
  })
10072
9590
  ])
10073
9591
  );
10074
- const loadedSchema = z$1.object({
10075
- type: z$1.literal("epicshop:loaded"),
10076
- url: z$1.string()
9592
+ const loadedSchema = z.object({
9593
+ type: z.literal("epicshop:loaded"),
9594
+ url: z.string()
10077
9595
  });
10078
- const messageSchema = z$1.union([historyCallDataSchema, loadedSchema]);
9596
+ const messageSchema = z.union([historyCallDataSchema, loadedSchema]);
10079
9597
  function getNewIndex(prevIndex, delta, max) {
10080
9598
  return Math.min(Math.max(prevIndex + delta, 0), max);
10081
9599
  }
@@ -10835,49 +10353,49 @@ function getDayjs() {
10835
10353
  initialized = true;
10836
10354
  return dayjs;
10837
10355
  }
10838
- const EmojiDataSchema = z$1.union([
10839
- z$1.object({
10840
- emojiName: z$1.never().optional(),
10841
- emojiUrl: z$1.string()
10356
+ const EmojiDataSchema = z.union([
10357
+ z.object({
10358
+ emojiName: z.never().optional(),
10359
+ emojiUrl: z.string()
10842
10360
  }),
10843
- z$1.object({
10844
- emojiName: z$1.string(),
10845
- emojiUrl: z$1.never().optional()
10361
+ z.object({
10362
+ emojiName: z.string(),
10363
+ emojiUrl: z.never().optional()
10846
10364
  }),
10847
- z$1.object({
10848
- emojiName: z$1.never().optional(),
10849
- emojiUrl: z$1.never().optional()
10365
+ z.object({
10366
+ emojiName: z.never().optional(),
10367
+ emojiUrl: z.never().optional()
10850
10368
  })
10851
10369
  ]);
10852
- const ThreadItemSchema = z$1.object({
10853
- id: z$1.string(),
10854
- tags: z$1.array(
10855
- z$1.object({
10856
- name: z$1.string()
10370
+ const ThreadItemSchema = z.object({
10371
+ id: z.string(),
10372
+ tags: z.array(
10373
+ z.object({
10374
+ name: z.string()
10857
10375
  }).and(EmojiDataSchema)
10858
10376
  ),
10859
- name: z$1.string(),
10860
- link: z$1.string(),
10861
- authorDisplayName: z$1.string(),
10862
- authorHexAccentColor: z$1.string().nullable().optional(),
10863
- authorAvatarUrl: z$1.string().nullable(),
10864
- messagePreview: z$1.string(),
10865
- messageCount: z$1.number(),
10866
- lastUpdated: z$1.string(),
10867
- previewImageUrl: z$1.string().nullable(),
10868
- reactions: z$1.array(
10869
- z$1.object({
10870
- count: z$1.number()
10377
+ name: z.string(),
10378
+ link: z.string(),
10379
+ authorDisplayName: z.string(),
10380
+ authorHexAccentColor: z.string().nullable().optional(),
10381
+ authorAvatarUrl: z.string().nullable(),
10382
+ messagePreview: z.string(),
10383
+ messageCount: z.number(),
10384
+ lastUpdated: z.string(),
10385
+ previewImageUrl: z.string().nullable(),
10386
+ reactions: z.array(
10387
+ z.object({
10388
+ count: z.number()
10871
10389
  }).and(EmojiDataSchema)
10872
10390
  )
10873
10391
  });
10874
- const ThreadDataSchema = z$1.array(ThreadItemSchema);
10875
- const EpicForumResponseSchema = z$1.object({
10876
- status: z$1.literal("error"),
10877
- error: z$1.string()
10392
+ const ThreadDataSchema = z.array(ThreadItemSchema);
10393
+ const EpicForumResponseSchema = z.object({
10394
+ status: z.literal("error"),
10395
+ error: z.string()
10878
10396
  }).or(
10879
- z$1.object({
10880
- status: z$1.literal("success"),
10397
+ z.object({
10398
+ status: z.literal("success"),
10881
10399
  threadData: ThreadDataSchema
10882
10400
  })
10883
10401
  );
@@ -11195,24 +10713,24 @@ function useAnsiToHtml() {
11195
10713
  function stripCursorMovements(data) {
11196
10714
  return data.replace(/\u001b\[\d+A/g, "").replace(/\u001b\[\d+K/g, "");
11197
10715
  }
11198
- const testRunnerStatusDataSchema = z$1.intersection(
11199
- z$1.object({
11200
- type: z$1.literal("epicshop:test-status-update"),
11201
- timestamp: z$1.number()
10716
+ const testRunnerStatusDataSchema = z.intersection(
10717
+ z.object({
10718
+ type: z.literal("epicshop:test-status-update"),
10719
+ timestamp: z.number()
11202
10720
  }),
11203
- z$1.union([
11204
- z$1.object({ status: z$1.literal("pending") }),
11205
- z$1.object({ status: z$1.literal("pass") }),
11206
- z$1.object({ status: z$1.literal("fail"), error: z$1.string() })
10721
+ z.union([
10722
+ z.object({ status: z.literal("pending") }),
10723
+ z.object({ status: z.literal("pass") }),
10724
+ z.object({ status: z.literal("fail"), error: z.string() })
11207
10725
  ])
11208
10726
  );
11209
- const testRunnerTestStepDataSchema = z$1.object({
11210
- type: z$1.literal("epicshop:test-step-update"),
11211
- status: z$1.literal("pass"),
11212
- title: z$1.string(),
11213
- timestamp: z$1.number()
10727
+ const testRunnerTestStepDataSchema = z.object({
10728
+ type: z.literal("epicshop:test-step-update"),
10729
+ status: z.literal("pass"),
10730
+ title: z.string(),
10731
+ timestamp: z.number()
11214
10732
  });
11215
- const testRunnerDataSchema = z$1.union([
10733
+ const testRunnerDataSchema = z.union([
11216
10734
  testRunnerTestStepDataSchema,
11217
10735
  testRunnerStatusDataSchema
11218
10736
  ]);
@@ -11257,7 +10775,7 @@ function InBrowserTestRunner({
11257
10775
  };
11258
10776
  }, []);
11259
10777
  const statusEmoji = {
11260
- pending: /* @__PURE__ */ jsx(AnimatedBars, { "aria-label": "Pending" }),
10778
+ pending: /* @__PURE__ */ jsx(AnimatedBars, { size: 14, "aria-label": "Pending" }),
11261
10779
  pass: /* @__PURE__ */ jsx(
11262
10780
  Icon,
11263
10781
  {
@@ -11354,45 +10872,45 @@ function InBrowserTestRunner({
11354
10872
  }
11355
10873
  ) }) });
11356
10874
  }
11357
- const testActionSchema = z$1.union([
11358
- z$1.object({
11359
- intent: z$1.literal("run"),
11360
- name: z$1.string()
10875
+ const testActionSchema = z.union([
10876
+ z.object({
10877
+ intent: z.literal("run"),
10878
+ name: z.string()
11361
10879
  }),
11362
- z$1.object({
11363
- intent: z$1.literal("stop"),
11364
- name: z$1.string()
10880
+ z.object({
10881
+ intent: z.literal("stop"),
10882
+ name: z.string()
11365
10883
  }),
11366
- z$1.object({
11367
- intent: z$1.literal("clear"),
11368
- name: z$1.string()
10884
+ z.object({
10885
+ intent: z.literal("clear"),
10886
+ name: z.string()
11369
10887
  })
11370
10888
  ]);
11371
- const testEventSchema = z$1.union([
11372
- z$1.object({
11373
- type: z$1.literal("init"),
11374
- exitCode: z$1.number().nullable().optional(),
11375
- isRunning: z$1.boolean(),
11376
- output: z$1.array(
11377
- z$1.object({
11378
- type: z$1.union([z$1.literal("stdout"), z$1.literal("stderr")]),
11379
- content: z$1.string(),
11380
- timestamp: z$1.number()
10889
+ const testEventSchema = z.union([
10890
+ z.object({
10891
+ type: z.literal("init"),
10892
+ exitCode: z.number().nullable().optional(),
10893
+ isRunning: z.boolean(),
10894
+ output: z.array(
10895
+ z.object({
10896
+ type: z.union([z.literal("stdout"), z.literal("stderr")]),
10897
+ content: z.string(),
10898
+ timestamp: z.number()
11381
10899
  })
11382
10900
  )
11383
10901
  }),
11384
- z$1.object({
11385
- type: z$1.union([z$1.literal("stdout"), z$1.literal("stderr")]),
11386
- data: z$1.string(),
11387
- timestamp: z$1.number()
10902
+ z.object({
10903
+ type: z.union([z.literal("stdout"), z.literal("stderr")]),
10904
+ data: z.string(),
10905
+ timestamp: z.number()
11388
10906
  }),
11389
- z$1.object({
11390
- type: z$1.literal("exit"),
11391
- isRunning: z$1.literal(false),
11392
- code: z$1.number().nullable()
10907
+ z.object({
10908
+ type: z.literal("exit"),
10909
+ isRunning: z.literal(false),
10910
+ code: z.number().nullable()
11393
10911
  })
11394
10912
  ]);
11395
- const testEventQueueSchema = z$1.array(testEventSchema);
10913
+ const testEventQueueSchema = z.array(testEventSchema);
11396
10914
  async function loader$j({ request }) {
11397
10915
  ensureUndeployed();
11398
10916
  const url = new URL(request.url);
@@ -12701,19 +12219,19 @@ async function registerDevice() {
12701
12219
  });
12702
12220
  }
12703
12221
  }
12704
- const CodeReceivedEventSchema = z$1.object({
12705
- type: z$1.literal(EVENTS.USER_CODE_RECEIVED),
12706
- code: z$1.string(),
12707
- url: z$1.string()
12222
+ const CodeReceivedEventSchema = z.object({
12223
+ type: z.literal(EVENTS.USER_CODE_RECEIVED),
12224
+ code: z.string(),
12225
+ url: z.string()
12708
12226
  });
12709
- const AuthResolvedEventSchema = z$1.object({
12710
- type: z$1.literal(EVENTS.AUTH_RESOLVED)
12227
+ const AuthResolvedEventSchema = z.object({
12228
+ type: z.literal(EVENTS.AUTH_RESOLVED)
12711
12229
  });
12712
- const AuthRejectedEventSchema = z$1.object({
12713
- type: z$1.literal(EVENTS.AUTH_REJECTED),
12714
- error: z$1.string().optional().default("Unknown error")
12230
+ const AuthRejectedEventSchema = z.object({
12231
+ type: z.literal(EVENTS.AUTH_REJECTED),
12232
+ error: z.string().optional().default("Unknown error")
12715
12233
  });
12716
- const EventSchema = z$1.union([
12234
+ const EventSchema = z.union([
12717
12235
  CodeReceivedEventSchema,
12718
12236
  AuthResolvedEventSchema,
12719
12237
  AuthRejectedEventSchema
@@ -13749,7 +13267,7 @@ const route39 = /* @__PURE__ */ Object.freeze(/* @__PURE__ */ Object.definePrope
13749
13267
  __proto__: null,
13750
13268
  loader
13751
13269
  }, Symbol.toStringTag, { value: "Module" }));
13752
- const serverManifest = { "entry": { "module": "/assets/entry.client-3M2p-8I3.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/root-BOrI36ez.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-B-hHvmeV.js", "/assets/index-YNIH4TH8.js", "/assets/presence-Cr--lRCr.js", "/assets/seo-pBpFCWsy.js"], "css": [] }, "routes/$": { "id": "routes/$", "parentId": "root", "path": "*", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_-D0Tgngwe.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/error-boundary-COkPRBOZ.js"], "css": [] }, "routes/_app+/_layout": { "id": "routes/_app+/_layout", "parentId": "root", "path": void 0, "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BPwIOXxN.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/workshop-config-CL4F08kr.js", "/assets/product-BAWG1Vut.js", "/assets/index-CXyf3Reb.js", "/assets/user-DvujSs-t.js", "/assets/presence-Cr--lRCr.js", "/assets/progress-BFm2U-l5.js"], "css": [] }, "routes/_app+/account": { "id": "routes/_app+/account", "parentId": "routes/_app+/_layout", "path": "account", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/account-BatJhmSV.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/button-EE0aPg10.js", "/assets/tooltip-kD4kSf1i.js", "/assets/user-DvujSs-t.js", "/assets/presence-Cr--lRCr.js"], "css": [] }, "routes/_app+/app.$appName+/$": { "id": "routes/_app+/app.$appName+/$", "parentId": "routes/_app+/_layout", "path": "app/:appName/*", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/api.$": { "id": "routes/_app+/app.$appName+/api.$", "parentId": "routes/_app+/_layout", "path": "app/:appName/api/*", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/api._-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/epic_ws[.js]": { "id": "routes/_app+/app.$appName+/epic_ws[.js]", "parentId": "routes/_app+/_layout", "path": "app/:appName/epic_ws.js", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/epic_ws_.js_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/index": { "id": "routes/_app+/app.$appName+/index", "parentId": "routes/_app+/_layout", "path": "app/:appName/", "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/test.$testName": { "id": "routes/_app+/app.$appName+/test.$testName", "parentId": "routes/_app+/_layout", "path": "app/:appName/test/:testName", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test._testName-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/test.epic_ws[.js]": { "id": "routes/_app+/app.$appName+/test.epic_ws[.js]", "parentId": "routes/_app+/_layout", "path": "app/:appName/test/epic_ws.js", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test.epic_ws_.js_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/discord": { "id": "routes/_app+/discord", "parentId": "routes/_app+/_layout", "path": "discord", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/discord-BhzUjmbI.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/user-DvujSs-t.js", "/assets/discord-BRTW4Rnh.js"], "css": [] }, "routes/_app+/exercise+/_layout": { "id": "routes/_app+/exercise+/_layout", "parentId": "routes/_app+/_layout", "path": "exercise", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BUs3av-e.js", "imports": ["/assets/index-1cKOJFpX.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber": { "id": "routes/_app+/exercise+/$exerciseNumber", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_exerciseNumber-j9COGU-R.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/mdx-DwC5Oacq.js", "/assets/progress-BFm2U-l5.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber/:stepNumber", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_exerciseNumber_._stepNumber-7kSd_6hH.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "path": ":type", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_layout-DZWGV4Uf.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/index-Dx5GmdYq.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-DwC5Oacq.js", "/assets/progress-BFm2U-l5.js", "/assets/set-playground-DW0yVaNn.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": "app", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/app-CJ9ElQg6.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/button-EE0aPg10.js", "/assets/loading-sXkYDMsx.js", "/assets/progress-bar-D3kudPcr.js", "/assets/preview-C7dtR2VR.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/index-ZZCxObNp.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/tooltip-kD4kSf1i.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/request-info-CEhUGODY.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/accordion-OfO-5m5D.js", "/assets/mdx-DwC5Oacq.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/set-playground-DW0yVaNn.js", "/assets/button-EE0aPg10.js", "/assets/diff-BXHLJqTK.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/discord-BRTW4Rnh.js", "/assets/index-B-hHvmeV.js", "/assets/tests-DUg6VXec.js", "/assets/preview-C7dtR2VR.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": "test", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test-N2HloCnX.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/progress-bar-D3kudPcr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/accordion-OfO-5m5D.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/set-playground-DW0yVaNn.js", "/assets/tests-DUg6VXec.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_exerciseNumber_._stepNumber.index-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.finished": { "id": "routes/_app+/exercise+/$exerciseNumber_.finished", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber/finished", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_exerciseNumber_.finished-DDNPeo8x.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-DwC5Oacq.js", "/assets/progress-BFm2U-l5.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/finished": { "id": "routes/_app+/finished", "parentId": "routes/_app+/_layout", "path": "finished", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/finished-Dop_5v80.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-DwC5Oacq.js", "/assets/seo-pBpFCWsy.js", "/assets/progress-BFm2U-l5.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/index": { "id": "routes/_app+/index", "parentId": "routes/_app+/_layout", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/index-D-l_qaLC.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/mdx-DwC5Oacq.js", "/assets/progress-BFm2U-l5.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/login": { "id": "routes/_app+/login", "parentId": "routes/_app+/_layout", "path": "login", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/login-Cc73KLYm.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/workshop-config-CL4F08kr.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/button-EE0aPg10.js", "/assets/loading-sXkYDMsx.js", "/assets/product-BAWG1Vut.js"], "css": [] }, "routes/_app+/support": { "id": "routes/_app+/support", "parentId": "routes/_app+/_layout", "path": "support", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/support-hcqGIpir.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js"], "css": [] }, "routes/admin+/_layout": { "id": "routes/admin+/_layout", "parentId": "root", "path": "admin", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BwzhY4NI.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/pe-CUZaIcdt.js", "/assets/tooltip-kD4kSf1i.js", "/assets/progress-BFm2U-l5.js"], "css": [] }, "routes/admin+/apps": { "id": "routes/admin+/apps", "parentId": "routes/admin+/_layout", "path": "apps", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/apps-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/admin+/cache": { "id": "routes/admin+/cache", "parentId": "routes/admin+/_layout", "path": "cache", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/cache-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/apps": { "id": "routes/apps", "parentId": "root", "path": "apps", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/apps-DP2rzg_V.js", "imports": [], "css": [] }, "routes/diff": { "id": "routes/diff", "parentId": "root", "path": "diff", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/diff-BEEJhGiC.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/tooltip-kD4kSf1i.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/request-info-CEhUGODY.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-DZzPuXR8.js", "/assets/progress-bar-D3kudPcr.js", "/assets/accordion-OfO-5m5D.js", "/assets/mdx-DwC5Oacq.js", "/assets/diff-BXHLJqTK.js", "/assets/nav-chevrons-g-C0ilNz.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/discord.callback": { "id": "routes/discord.callback", "parentId": "root", "path": "discord/callback", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/discord.callback-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/exercises": { "id": "routes/exercises", "parentId": "root", "path": "exercises", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/exercises-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/launch-editor": { "id": "routes/launch-editor", "parentId": "root", "path": "launch-editor", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/launch-editor-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/login-sse": { "id": "routes/login-sse", "parentId": "root", "path": "login-sse", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/login-sse-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/og": { "id": "routes/og", "parentId": "root", "path": "og", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/og-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/onboarding": { "id": "routes/onboarding", "parentId": "root", "path": "onboarding", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/onboarding-DE9gclYS.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/button-EE0aPg10.js", "/assets/epic-video-DZzPuXR8.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/processes": { "id": "routes/processes", "parentId": "root", "path": "processes", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/processes-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/progress": { "id": "routes/progress", "parentId": "root", "path": "progress", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/progress-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/robots[.]txt": { "id": "routes/robots[.]txt", "parentId": "root", "path": "robots.txt", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/robots_._txt-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/set-playground": { "id": "routes/set-playground", "parentId": "root", "path": "set-playground", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/set-playground-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/sitemap[.]xml": { "id": "routes/sitemap[.]xml", "parentId": "root", "path": "sitemap.xml", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/sitemap_._xml-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/start": { "id": "routes/start", "parentId": "root", "path": "start", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/start-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/test": { "id": "routes/test", "parentId": "root", "path": "test", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/theme/index": { "id": "routes/theme/index", "parentId": "root", "path": "theme", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-DP2rzg_V.js", "imports": [], "css": [] }, "routes/update-mdx-cache": { "id": "routes/update-mdx-cache", "parentId": "root", "path": "update-mdx-cache", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/update-mdx-cache-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/video-player/index": { "id": "routes/video-player/index", "parentId": "root", "path": "video-player", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-K6Dvbx-E.js", "imports": [], "css": [] } }, "url": "/assets/manifest-1d60a768.js", "version": "1d60a768" };
13270
+ const serverManifest = { "entry": { "module": "/assets/entry.client-3M2p-8I3.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js"], "css": [] }, "routes": { "root": { "id": "root", "parentId": void 0, "path": "", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/root-9wVBEzOq.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-B-hHvmeV.js", "/assets/index-YNIH4TH8.js", "/assets/presence-Cr--lRCr.js", "/assets/seo-pBpFCWsy.js"], "css": [] }, "routes/$": { "id": "routes/$", "parentId": "root", "path": "*", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_-D0Tgngwe.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/error-boundary-COkPRBOZ.js"], "css": [] }, "routes/_app+/_layout": { "id": "routes/_app+/_layout", "parentId": "root", "path": void 0, "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BPwIOXxN.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/workshop-config-CL4F08kr.js", "/assets/product-BAWG1Vut.js", "/assets/index-CXyf3Reb.js", "/assets/user-DvujSs-t.js", "/assets/presence-Cr--lRCr.js", "/assets/progress-BFm2U-l5.js"], "css": [] }, "routes/_app+/account": { "id": "routes/_app+/account", "parentId": "routes/_app+/_layout", "path": "account", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/account-BatJhmSV.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/button-EE0aPg10.js", "/assets/tooltip-kD4kSf1i.js", "/assets/user-DvujSs-t.js", "/assets/presence-Cr--lRCr.js"], "css": [] }, "routes/_app+/app.$appName+/$": { "id": "routes/_app+/app.$appName+/$", "parentId": "routes/_app+/_layout", "path": "app/:appName/*", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/api.$": { "id": "routes/_app+/app.$appName+/api.$", "parentId": "routes/_app+/_layout", "path": "app/:appName/api/*", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/api._-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/epic_ws[.js]": { "id": "routes/_app+/app.$appName+/epic_ws[.js]", "parentId": "routes/_app+/_layout", "path": "app/:appName/epic_ws.js", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/epic_ws_.js_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/index": { "id": "routes/_app+/app.$appName+/index", "parentId": "routes/_app+/_layout", "path": "app/:appName/", "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-K6Dvbx-E.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/test.$testName": { "id": "routes/_app+/app.$appName+/test.$testName", "parentId": "routes/_app+/_layout", "path": "app/:appName/test/:testName", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test._testName-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/app.$appName+/test.epic_ws[.js]": { "id": "routes/_app+/app.$appName+/test.epic_ws[.js]", "parentId": "routes/_app+/_layout", "path": "app/:appName/test/epic_ws.js", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test.epic_ws_.js_-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/discord": { "id": "routes/_app+/discord", "parentId": "routes/_app+/_layout", "path": "discord", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/discord-BhzUjmbI.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/user-DvujSs-t.js", "/assets/discord-BRTW4Rnh.js"], "css": [] }, "routes/_app+/exercise+/_layout": { "id": "routes/_app+/exercise+/_layout", "parentId": "routes/_app+/_layout", "path": "exercise", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BUs3av-e.js", "imports": ["/assets/index-1cKOJFpX.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber": { "id": "routes/_app+/exercise+/$exerciseNumber", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_exerciseNumber-1JworToC.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/mdx-CpyquP9i.js", "/assets/progress-BFm2U-l5.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber/:stepNumber", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_exerciseNumber_._stepNumber-7kSd_6hH.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "path": ":type", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/_layout-CKnDy_9Z.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/index-Dx5GmdYq.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-CpyquP9i.js", "/assets/progress-BFm2U-l5.js", "/assets/set-playground-DW0yVaNn.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/app", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": "app", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/app-CJ9ElQg6.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/button-EE0aPg10.js", "/assets/loading-sXkYDMsx.js", "/assets/progress-bar-D3kudPcr.js", "/assets/preview-C7dtR2VR.js"], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/index", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/index-Ccssehd9.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/tooltip-kD4kSf1i.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/request-info-CEhUGODY.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/accordion-OfO-5m5D.js", "/assets/mdx-CpyquP9i.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/set-playground-DW0yVaNn.js", "/assets/button-EE0aPg10.js", "/assets/diff-jgZ_RGra.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/discord-BRTW4Rnh.js", "/assets/index-B-hHvmeV.js", "/assets/tests-BR7RFlr5.js", "/assets/preview-C7dtR2VR.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/test", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.$type+/_layout", "path": "test", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test-DbZkv25C.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/progress-bar-D3kudPcr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/accordion-OfO-5m5D.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/set-playground-DW0yVaNn.js", "/assets/tests-BR7RFlr5.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index": { "id": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber.index", "parentId": "routes/_app+/exercise+/$exerciseNumber_.$stepNumber", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_exerciseNumber_._stepNumber.index-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/_app+/exercise+/$exerciseNumber_.finished": { "id": "routes/_app+/exercise+/$exerciseNumber_.finished", "parentId": "routes/_app+/exercise+/_layout", "path": ":exerciseNumber/finished", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_exerciseNumber_.finished-B4D2ZAmj.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-CpyquP9i.js", "/assets/progress-BFm2U-l5.js", "/assets/seo-pBpFCWsy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/finished": { "id": "routes/_app+/finished", "parentId": "routes/_app+/_layout", "path": "finished", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/finished-Ct6I1SZV.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/nav-chevrons-g-C0ilNz.js", "/assets/mdx-CpyquP9i.js", "/assets/seo-pBpFCWsy.js", "/assets/progress-BFm2U-l5.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/index": { "id": "routes/_app+/index", "parentId": "routes/_app+/_layout", "path": void 0, "index": true, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": true, "module": "/assets/index-R-sUGQfT.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/index-Dx5GmdYq.js", "/assets/error-boundary-COkPRBOZ.js", "/assets/mdx-CpyquP9i.js", "/assets/progress-BFm2U-l5.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/_app+/login": { "id": "routes/_app+/login", "parentId": "routes/_app+/_layout", "path": "login", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/login-Cc73KLYm.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/workshop-config-CL4F08kr.js", "/assets/use-event-source-A_0lEOPX.js", "/assets/button-EE0aPg10.js", "/assets/loading-sXkYDMsx.js", "/assets/product-BAWG1Vut.js"], "css": [] }, "routes/_app+/support": { "id": "routes/_app+/support", "parentId": "routes/_app+/_layout", "path": "support", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/support-hcqGIpir.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js"], "css": [] }, "routes/admin+/_layout": { "id": "routes/admin+/_layout", "parentId": "root", "path": "admin", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/_layout-BwzhY4NI.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/pe-CUZaIcdt.js", "/assets/tooltip-kD4kSf1i.js", "/assets/progress-BFm2U-l5.js"], "css": [] }, "routes/admin+/apps": { "id": "routes/admin+/apps", "parentId": "routes/admin+/_layout", "path": "apps", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/apps-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/admin+/cache": { "id": "routes/admin+/cache", "parentId": "routes/admin+/_layout", "path": "cache", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/cache-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/apps": { "id": "routes/apps", "parentId": "root", "path": "apps", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/apps-DP2rzg_V.js", "imports": [], "css": [] }, "routes/diff": { "id": "routes/diff", "parentId": "root", "path": "diff", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/diff-Cvtc-qzL.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/tooltip-kD4kSf1i.js", "/assets/index-CXyf3Reb.js", "/assets/index-BwhlO_gF.js", "/assets/request-info-CEhUGODY.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/epic-video-yrWoJVFy.js", "/assets/progress-bar-D3kudPcr.js", "/assets/accordion-OfO-5m5D.js", "/assets/mdx-CpyquP9i.js", "/assets/diff-jgZ_RGra.js", "/assets/nav-chevrons-g-C0ilNz.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/discord.callback": { "id": "routes/discord.callback", "parentId": "root", "path": "discord/callback", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/discord.callback-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/exercises": { "id": "routes/exercises", "parentId": "root", "path": "exercises", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/exercises-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/launch-editor": { "id": "routes/launch-editor", "parentId": "root", "path": "launch-editor", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/launch-editor-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/login-sse": { "id": "routes/login-sse", "parentId": "root", "path": "login-sse", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/login-sse-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/og": { "id": "routes/og", "parentId": "root", "path": "og", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/og-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/onboarding": { "id": "routes/onboarding", "parentId": "root", "path": "onboarding", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/onboarding-B7TLVi2l.js", "imports": ["/assets/index-1cKOJFpX.js", "/assets/components-CME-nGId.js", "/assets/misc-CxCgA-_O.js", "/assets/request-info-CEhUGODY.js", "/assets/tooltip-kD4kSf1i.js", "/assets/pe-CUZaIcdt.js", "/assets/index-YNIH4TH8.js", "/assets/loading-sXkYDMsx.js", "/assets/user-DvujSs-t.js", "/assets/workshop-config-CL4F08kr.js", "/assets/button-EE0aPg10.js", "/assets/epic-video-yrWoJVFy.js"], "css": ["/assets/epic-video-DUnRvy1A.css"] }, "routes/processes": { "id": "routes/processes", "parentId": "root", "path": "processes", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/processes-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/progress": { "id": "routes/progress", "parentId": "root", "path": "progress", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/progress-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/robots[.]txt": { "id": "routes/robots[.]txt", "parentId": "root", "path": "robots.txt", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/robots_._txt-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/set-playground": { "id": "routes/set-playground", "parentId": "root", "path": "set-playground", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/set-playground-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/sitemap[.]xml": { "id": "routes/sitemap[.]xml", "parentId": "root", "path": "sitemap.xml", "index": void 0, "caseSensitive": void 0, "hasAction": false, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/sitemap_._xml-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/start": { "id": "routes/start", "parentId": "root", "path": "start", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/start-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/test": { "id": "routes/test", "parentId": "root", "path": "test", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": true, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/test-l0sNRNKZ.js", "imports": [], "css": [] }, "routes/theme/index": { "id": "routes/theme/index", "parentId": "root", "path": "theme", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-DP2rzg_V.js", "imports": [], "css": [] }, "routes/video-player/index": { "id": "routes/video-player/index", "parentId": "root", "path": "video-player", "index": void 0, "caseSensitive": void 0, "hasAction": true, "hasLoader": false, "hasClientAction": false, "hasClientLoader": false, "hasErrorBoundary": false, "module": "/assets/index-l0sNRNKZ.js", "imports": [], "css": [] } }, "url": "/assets/manifest-f5f44d87.js", "version": "f5f44d87" };
13753
13271
  const mode = "production";
13754
13272
  const assetsBuildDirectory = "build/client";
13755
13273
  const basename = "/";
@@ -14102,21 +13620,13 @@ const routes = {
14102
13620
  caseSensitive: void 0,
14103
13621
  module: route42
14104
13622
  },
14105
- "routes/update-mdx-cache": {
14106
- id: "routes/update-mdx-cache",
14107
- parentId: "root",
14108
- path: "update-mdx-cache",
14109
- index: void 0,
14110
- caseSensitive: void 0,
14111
- module: route43
14112
- },
14113
13623
  "routes/video-player/index": {
14114
13624
  id: "routes/video-player/index",
14115
13625
  parentId: "root",
14116
13626
  path: "video-player",
14117
13627
  index: void 0,
14118
13628
  caseSensitive: void 0,
14119
- module: route44
13629
+ module: route43
14120
13630
  }
14121
13631
  };
14122
13632
  export {